MAXQ內核是一個功能強大的單周期、傳輸觸發CPU。本文通過展示整個指令集如何圍繞簡單的 MOVE 操作構建來演示這種功能。
MAXQ處理器系列是功能強大的8位、16位和32位單周期微控制器,在一個時鐘周期內執行多個操作。本文將探討MAXQ20內核的內部工作原理,并展示其強大的功能。
程序員模型
MAXQ20內核為16位CPU,這意味著所有累加器和大多數工作寄存器(堆棧、數據指針、計數器)的長度均為16位。MAXQ20可以尋址64k字的代碼空間(即64kB指令)和64k字(128kB)的數據空間(圖1)。
注意,對于基于MAXQ20內核的處理器,大部分內存空間將處于空置狀態。此外,由于實用程序ROM和數據RAM位于代碼空間的上部32kB,因此訪問此區域中的用戶代碼需要內核中的特殊功能,這些功能超出了本文的范圍。
圖1.MAXQ20內核的編程模型由16個通用累加器、兩個環路計數器和一組數據指針組成。
蓄電池
16個寄存器稱為“累加器”,形成一個通用寄存器陣列。累加器指針寄存器 (AP) 指向的寄存器被指定為“活動累加器”,它是算術和邏輯運算的目標。因此,通過更改AP寄存器中的值,可以將2個累加器中的任何一個指定為算術邏輯單元(ALU)操作的目標。累加器指針控制寄存器 (APC) 使 AP 在訪問活動累加器時自動遞增或遞減,從而使多精度算術變得簡單。在圖 0 中,A[1] 是有源累加器,但任何累加器訪問都可以使 A[15] 或 A[<>] 成為有源累加器,具體取決于 APC 寄存器的值。
圖2.活動累加器由AP寄存器指定,AP寄存器本身可以通過累加器訪問指令進行修改。
遺傳資源注冊
通用寄存器(GR)有助于從16位字中提取單個字節。程序員可以使用GR將字節組裝成一個字:將低字節加載到GRL(通用寄存器-低字節)中,將高字節加載到GRH(通用寄存器-高字節)中,并在GR中讀取組裝好的字。加載到 GR 中的單詞可以在 GRS(通用寄存器-交換)中以字節交換格式讀取。最后,加載到GRL寄存器的字節可以通過讀取GRXL(通用寄存器低字節)來符號擴展為一個字。參見圖 3。
圖3.GR 寄存器支持字節提取、字節交換和 16 位符號擴展。
循環計數器
有兩個環路計數器:環路計數器 0 (LC[0]) 和環路計數器 1 (LC[1])。這些寄存器可用作通用寄存器,但如果計數器為非零 (DJNZ) 指令,則用作遞減和跳轉的循環計數器。
疊
MAXQ20內核具有專用的16電平內部堆棧。堆棧指針指示要使用的下一個堆棧位置,或指示 PUSH 或 CALL 操作。
數據存儲指針
MAXQ微控制器具有三個用于訪問數據存儲器的指針。兩個,DP[0] 和 DP[1],是簡單的 16 位指針。第三個指針是通過將基址指針 (BP) 添加到 8 位無符號偏移量 (OFFS) 來形成的。
請注意,由三個數據指針之一尋址的數據存儲器與由指令指針尋址的代碼存儲器不同。雖然所有MAXQ處理器都包含一個存儲器管理單元(MMU),允許將任何存儲器段視為代碼或數據,但代碼和數據總線是分開的。代碼和數據獲取操作的總線分離是MAXQ20技術的基本要素,允許在單個時鐘周期內同時訪問代碼和數據。
傳輸觸發架構
通過檢查程序員的模型,可以得出結論,有一個傳統的指令獲取-解碼單元,它加載指令,解碼它,然后激活CPU的某些元素。然而,這將是一種誤解。MAXQ架構與其他傳統CPU的不同之處在于MAXQ內核的傳輸觸發特性。
傳輸觸發是一種允許簡單的 MOVE 指令執行 CPU 中可用的每個功能的技術。雖然MAXQ匯編器支持30多種指令操作碼,但MAXQ指令集中的每條指令都可以編碼為:
move Ma[b], Mc[d] or move Ma[b], #immediate_value
其中名稱 Ma[b] 描述寄存器模塊 a 和寄存器子解碼 b。簡單地說:每條指令——ADD、位操作、對外部存儲器的引用——都被編碼為兩個寄存器之間的移動或將即時值移動到寄存器中。
當執行MAXQ指令時,目標寄存器加載源寄存器的內容或即時值。此外,這種數據傳輸可以觸發其他事件,例如遞增或遞減指針、設置某些狀態位或其他函數。因此,該架構是傳輸觸發的。為了支持這種架構,需要一個大的寄存器補充。在MAXQ20內核中,共有512個寄存器地址,分為兩大部分:外設寄存器空間和系統寄存器空間(圖4)。
前六個寄存器模塊(模塊 0 到 5)專用于外設寄存器;最后九個模塊(模塊7至F)被分配為系統寄存器。(模塊 6 是保留的。當外設寄存器模塊從一種類型的MAXQ處理器變為另一種類型的MAXQ處理器時,所有MAXQ處理器的系統寄存器保持不變(圖5)。
圖4.MAXQ20內核中的寄存器分配分為兩個區域:寄存器組0至5為外設寄存器,可以從MAXQ器件切換到另一個MAXQ器件;組7至15是系統寄存器,在所有MAXQ部件上保持相對固定。
圖5.MAXQ系統寄存器映射由所有基于MAXQ20的處理器中的寄存器和用于實現指令集的附加解碼組成。
解碼MAXQ指令
因為每條MAXQ指令實際上都是一個MOVE,所以每條指令可以分解為三個字段:一個SOURCE字段,它指定數據從哪里移動;指定數據移動到何處的“目標”字段;以及一個格式位,指示源是即時值(FORMAT == 0)還是寄存器指示符(FORMAT == 1)(圖6)。
圖6.MAXQ指令由三部分組成:源指示符、目標指示符和源格式位,用于確定源是直接操作數還是寄存器操作數。
以指令操作碼0x0923為例。在此指令中,FORMAT位是明確的,指示源指示符(23)應被視為8位即時值。目標模塊是模塊 9,即累加器陣列。該數組中的寄存器 0 是累加器 A[0]。因此,指令的作用是將0x0023的值加載到寄存器 A[0] 中。在這種情況下,沒有與源或目標指示符相關的副作用。
對于第二個示例,請考慮0xBF09。在此指令中,設置了FORMAT位,這意味著源指示符應解釋為寄存器。模塊 9 寄存器 0 已在上面介紹:它是累加器 A[0]。在目標端,模塊 F 是數據指針模塊,寄存器 3(指令中的位 14:12)表示數據指針 DP[0]。因此,此指令將 A[0] 的內容移動到 DP[0]。
請注意,在某些情況下,寄存器模塊內的各個位置可能引用實際寄存器,也可能不引用實際寄存器。或者,它們可以引用實際的寄存器,但在訪問該寄存器子解碼時會導致一些副作用。例如,讓我們用0xAF09稍微修改前面的示例。只有目標子解碼已更改。現在,指令不是加載寄存器 DP[0],而是遞減 DP[0],然后開始對 DP[0] 指向的新內存位置進行存儲操作。也就是說,指令在遞減指針上執行間接存儲。在MAXQ匯編器中,它被編碼為移動@DP[0],A[0],但它可以像移動M15[2],M9[0]一樣容易編碼。
前綴寄存器
每個模塊有 32 個寄存器,但只有 11 位用于選擇源寄存器,只有 <> 位用于指定目標寄存器。乍一看,這意味著無法讀取一半的寄存器子解碼,并且無法寫入整整四分之三的寄存器子解碼。幸運的是,MAXQ架構設計可以解決這個問題。每個MAXQ處理器提供一個前綴寄存器,以提供這些額外的寄存器地址位,并提供字范圍移動的高字節。有關詳細信息,請參閱模塊 <> - 前綴部分。
一次創建一個模塊的MAXQ指令集
以下各節詳細介紹了系統寄存器模塊以及它們如何交互以創建所有記錄和未記錄的指令。我們首先研究MAXQ20內核的核心:累加器陣列。
模塊 9 - 蓄能器
MAXQ架構最多支持32個累加器,盡管大多數型號只支持16個。累加器可通過模塊 9 直接訪問。此模塊中的每個子解碼代表一個累加器。模塊 9 在概念上是最簡單的模塊,但還有兩個模塊會影響累加器陣列。
模塊 8 - 系統控制
該模塊包含許多寄存器,用于管理系統操作的各個方面,例如中斷控制和程序狀態標志。其中許多寄存器超出了本文的范圍,因此有關詳細信息,請參閱器件規格。表1列出了其中一些寄存器模塊。
表 1.模塊 8 函數
子 | 功能 | S/D | 描述 |
0 | 累加器指針寄存器 | S/D | 指定活動累加器,即用作 ALU 操作目標的累加器。 |
1 | 累加器指針控制寄存器 | S/D | 告訴 AP 如何表現。對于此討論,它是一個通用的8位寄存器。 |
4 | 程序狀態標志寄存器 | S/D | 包含用戶可能希望在主程序中監視的標志(攜帶、零、等于)。寄存器通常用作源,但也可以用作目標。請注意,某些位是只讀的(例如,Z 標志是活動累加器中所有位的邏輯 NOR)。 |
5 | 中斷控制寄存器 | S/D | 管理中斷子系統。 |
6 | 中斷掩碼寄存器 | S/D | 通常包含在模塊級別屏蔽中斷的位。 |
7 | 比較器寄存器 | DO | 只寫子解碼。不是真正的寄存器,因為它后面沒有實際的內存。寫入此子解碼時,如果源操作數與當前累加器的內容匹配,則在 PSF 中設置等于位;否則,將清除等于位。 |
8 | 系統控制寄存器 | S/D | 包含控制系統操作(讀/寫)方面的位。 |
11 | 中斷識別寄存器 | SO | 包含標識中斷源的位集合。 |
14 | 時鐘控制寄存器 | S/D | 包含與系統時鐘相關的位。特別是,控制主時鐘分頻比,以及時鐘源(如果特定微控制器中存在多個源)。 |
15 | 看門狗控制寄存器 | S/D | 控制看門狗定時器的操作。大多數MAXQ器件都包含一個看門狗定時器,如果處理器卡在程序循環中,該定時器可以復位。 |
AP和APC登記冊值得特別注意。AP 寄存器確定哪個累加器寄存器是活動累加器;也就是說,它指定算術、邏輯和按位運算的目標。它可以指向數組中的任何累加器。
APC 寄存器包含一組位,用于定義在任何累加器操作后如何修改 AP 寄存器。因此,AP寄存器可以遞增或遞減,計數在可選擇的2次冪模數上滾動,使多精度運算變得簡單。
模塊 10 - 累加器功能
模塊 10 是完成累加器大部分實際工作的地方。它提供對傳統 ALU 函數的訪問和對有源累加器的位級訪問。模塊 10 是唯一的;它的行為有所不同,具體取決于它是用作源、目標還是同時用作源和目標(表 2)。
表 2.模塊 10 作為源
子 | 功能 | 描述 |
0 | 有源蓄能器 | 活動累加器的內容將移動到目標,并且 AP 將根據 APC 進行更改。 |
1 | 有源蓄能器 | 活動累加器的內容將移動到目標,并且 AP 保持不變。 |
如果源是模塊 10,并且目標是模塊 10 以外的任何模塊,則累加器的內容將移動到目標。如果子解碼為零,則根據APC寄存器中的位修改AP寄存器。如果子解碼為 1,則不會修改 AP 寄存器。
請注意,當前版本的宏匯編器不支持子解碼 1。這是因為沒有助記符或修飾符來指定子解碼 1。因此,指令移動 A[1],ACC 將始終0x990A生成操作碼,并且永遠不會0x991A(表 3)。
表 3.模塊 10 作為目的地
子 | 功能 | 描述 |
0 | MOVE | 源將移動到累加器。 |
1 | AND | 源的內容在邏輯上與累加器一起進行。 |
2 | OR | 源的內容與累加器進行邏輯 OR 運算。 |
3 | XOR | 源的內容在邏輯上與累加器進行 OR。 |
4 | ADD | 源的內容以算術方式添加到累加器中。從 MSB 溢出設置進位。 |
5 | SUB | 源的內容從累加器算術上減去。底流設置進位。 |
6 | ADDC | 源和進位的內容被添加到累加器中。 |
7 | SUBB | 源和進位的內容從累加器中減去。 |
當模塊 10 被指定為目標并且源是即時值或模塊 10 以外的任何模塊時,源通過 ALU 路由;目標取自 ALU 的輸出,而不是直接取自源。這就是算術和邏輯指令的實現方式。
請注意,對可用作源寄存器的內容沒有限制。它可以是即時值、間接存儲器位置,甚至是堆棧或外設寄存器上的值(表 4)。
表 4.模塊 10 同時作為源和目標
德斯特亞 | SRC 子 | 功能 | 描述 |
0 | 0 | MOVE | 累加器的內容被移動到累加器;從邏輯上講,一個NOP。但是,可以更改 AP 寄存器。 |
1 | .CPL | 累加器按位補充。 | |
2 | SLA | 累加器向左移動一位;低階位設置為零。高階位被復制到進位。 | |
3 | SLA2 | 累加器向左移動兩位;低階兩位設置為零。位 14 被復制到攜帶。 | |
4 | RL | 蓄能器向左旋轉一位,將位 15 復制到位 0。位 15 也被復制到攜帶。 | |
5 | RLC | 蓄能器向左旋轉一位,將位 15 復制到進位,進位復制到位 0。 | |
6 | SLA4 | 蓄能器向左移動四位;低階四位設置為零。位 12 被復制到攜帶。 | |
7 | XCHN | 累加器每個字節中的半字節被顛倒;0x1234變得0x2143。 | |
8 | XCH | 累加器的字節是相反的;0x1234變得0x3412。 | |
9 | NEG | 累加器在算術上被否定。 | |
10 | SR | 累加器向右移動一位。位 15 加載零。位 0 被移動到攜帶。 | |
11 | SRA4 | 累加器向右移動四位;高階四位設置為零。位 3 被復制到攜帶。 | |
12 | RR | 蓄能器向右旋轉一位,位 0 復制到位 15。位 0 也被復制到攜帶。 | |
13 | RRC | 蓄能器向右旋轉一位,位 0 復制到進位,進位復制到位 15。 | |
14 | SRA2 | 累加器向右移動兩位;高階兩位設置為零。位 1 復制到攜帶。 | |
15 | SRA | 累加器向右移動一位;高階位設置為零。低階位復制到進位。 | |
1 | 位 | 和 C | 進位與累加器中的指定位在邏輯上與 AND 運算。 |
2 | 位 | 或 C | 進位與累加器中的指定位在邏輯上是 OR 運算的。 |
3 | 位 | 異或 C | 進位與累加器中的指定位進行邏輯異或運算。 |
5 | 0 | C ← 0 | 進位設置為零。 |
1 | C ← 1 | 進位設置為 1。 | |
2 | C ← C | 進位是補充的。 | |
3 | NOP | 保證無價 | |
6 | 位 | C ← ACC | 蓄能器中的指定位被加載到進位中。 |
7 | 位 | ACC ← C | 進位被加載到累加器中的指定位中。 |
當源和目標指定都是模塊 10 時,它要么是僅累加器指令,要么是涉及進位的位操作。在所有情況下,源子解碼和目標子解碼都用于指定操作。
目標子解碼 0 是僅累加器指令的主頁,包括補碼、否定和所有移位、旋轉和交換指令。目標子解碼 1、2、3、6 和 7 涉及按位加載和使用進位的操作。最后,目標子解碼 5 具有僅進位操作:加載 0 和 1 以及補碼。
請注意,目標子解碼 5 的一個源子解碼是指定的 NOP 指令。雖然任何既沒有副作用又解決空寄存器位置的操作都可以作為NOP,但MOVE M10[5]、M10[3]特別保證在當前或未來的MAXQ器件中不執行任何操作。這是在 NOP 助記符的所有當前匯編程序中生成的操作代碼 (0xDA3A)。
模塊 12 — 指令指針
模塊 12 是唯一的,因為它包含許多條件加載操作。如果將模塊 12 用作源模塊,則只需將 IP 復制到目標指示符。但是,如果模塊 12 是目標,則除非滿足指定的條件,否則不會執行任何操作(表 5)。
表 5.模塊 12 子解碼
子 | 描述 |
0 | 如果源,則從 IP 加載目標。如果是目標,請從源加載 IP。 |
1 | 如果源,則從 IP 加載目標。如果是目標,則僅在 ACC == 0 時從源加載 IP。 |
2 | 如果源,則從 IP 加載目標。如果是目標,則僅在 C == 1 時從源加載 IP。 |
3 | 如果源,則從 IP 加載目標。如果是目標,則僅當最新的 CMP 指令設置 EQ 標志時,才從源加載 IP。 |
4 | 如果源,則從 IP 加載目標。如果是目標,則僅在設置了累加器的高階位時從源加載 IP。 |
5 | 如果源,則從 IP 加載目標。如果是目標,則僅在 ACC == 0 時從源加載 IP。 |
6 | 如果源,則從 IP 加載目標。如果是目標,則僅在 C == 0 時從源加載 IP。 |
7 | 如果源,則從 IP 加載目標。如果是目標,則僅當最新的 CMP 指令清除了 EQ 標志時,才從源加載 IP。 |
模塊 12 也是唯一的,因為當從 8 位即時源加載時,源值被解釋為有符號整數,并添加到指令指針的先前預遞增內容中。這種添加有助于相對短的跳躍,從而顯著節省代碼大小。這也意味著任何短跳或跳遠指令都可以是有條件的。
請注意,此模塊僅支持指令指針寄存器 (IP) 的簡單加載和存儲。CALL 指令被視為也加載 IP 的堆棧指令,而不是推送到堆棧的 IP 指令。因此,CALL 指令的傳輸在堆棧指針模塊(模塊 13)中。此外,沒有明確的 RET 指令;這被強制轉換為 POP IP。
模塊 13 — 堆棧指針
模塊 13 不僅包含與堆棧指針相關的寄存器,還包含循環計數器和中斷向量。請注意,多個子解碼僅作為目標有效,一個(子解碼 8)僅作為源有效(表 6)。
表 6.模塊 13 子解碼
子 | 功能 | S/D | 描述 |
0 | 推/爆 | S/D | 如果是目標,則遞增堆棧指針并將源操作數存儲在堆棧上。如果是源,則將堆棧上的值加載到目標并遞減堆棧指針。 |
1 | 堆棧指針 | S/D | 指向內部專用堆棧上最近使用的位置。 |
2 | 中斷向量 | S/D | 指向程序內存中中斷服務例程所在的位置。 |
3 | CALL | DO | 將當前 IP 推送到堆棧,然后從源操作數加載 IP。如果用作源操作數,將導致不可預知的結果。 |
4 | DJNZ LC[0] | DO | 遞減 LC[0] 并使用源 IF LC[0] != 0 加載 IP。如果用作源操作數,將導致不可預知的結果。 |
5 | DJNZ LC[1] | DO | 遞減 LC[1] 并使用源 IF LC[1] != 0 加載 IP。如果用作源操作數,將導致不可預知的結果。 |
6 | LC[0] | S/D | 數據移入/移出循環計數器 0。 |
7 | LC[1] | S/D | 數據移入/移出循環計數器 1。 |
8 | SO | 堆棧上的值將復制到目標,堆棧點遞減,并清除 IN SERVICE 位。主要用于實現 RETI 操作。 |
子解碼 3、4 和 5 用作 IP 寄存器的代理。Subdecode 3在遞增的指令指針被推送到堆棧后加載指令指針,從而實現傳統的CALL指令。子解碼 4 和 5 將指定循環計數器的前置版本加載回循環計數器,如果前遞減循環計數器不為零,則還會使用源操作數加載指令指針。要加載到此目標子解碼中的源可以是任何內容;指令 DJNZ LC[0], A[1] 是完全有效的。在這種情況下,如果遞減操作的結果不為零,則指令將遞減 LC[0] 并跳轉到 A[1] 中的地址。
模塊 14 - GR、BP 和 DPC
模塊14包含DPC寄存器、GR寄存器以及與基極指針和偏移寄存器相關的所有寄存器(表7)。
表 7.模塊 14 子解碼
子 | 功能 | S/D | 描述 | |
0 | @BP[offs] | S/D | 讀取或寫入 BP+off 指向的數據存儲器位置 | |
1 |
|
S/D | 如果為 source,則讀取 BP+off 指向的數據存儲器位置,然后遞增 off。如果為 target,則遞增,然后將源數據存儲在 BP+offs 處。 | |
2 | @BP[offs--] | S/D | 如果為 source,則讀取 BP+off 指向的數據存儲器位置,然后遞減。如果是目標,則遞減,然后將源數據存儲在 BP+offs。 | |
3 | offs | S/D | 8位失調寄存器 | |
4 | DPC | S/D | 數據指針控制寄存器定義哪個數據指針是當前源指針以及每個數據指針的字/字節狀態。 | |
5 | GR | S/D | 16位通用寄存器 | |
6 | GRL | S/D | 16位通用寄存器的低階字節 | |
7 | BP | S/D | 16 位基本內存指針 | |
8 | GRS | 所以 | 遺傳資源的字節交換版本 | |
9 | GRH | S/D | 16位通用寄存器的高階字節 | |
10 | GRXL | 所以 | GR 的符號擴展低字節 | |
11 | BP[offs] | 所以 | 基指針和偏移量的總和 |
數據指針控制寄存器 (DPC) 描述數據指針的行為方式。特別是,它包含每個數據指針的位,用于定義該指針是在字模式還是字節模式下運行。它還包含一個字段,用于定義哪個指針是當前源指針。這是必需的,因為在加載源指針時訪問源,并且只有一條總線用于操作數數據。
當 16 位數據需要字節訪問時,GR 寄存器很方便。一旦GR加載了16位數據,就可以分別通過GRL和GRH寄存器檢索低階和高階字節。GRS 寄存器包含 GR 的字節交換版本;GRXL 寄存器與 GRL 寄存器相同,不同之處在于高字節是低位字節的符號擴展。
基極指針寄存器(BP)是MAXQ架構中三個數據存儲器指針寄存器之一,也是唯一支持失調寄存器的寄存器。BP 通常指向數據結構的基底,8 位無符號偏移寄存器指向結構內的數據元素。請注意,此寄存器的遞增和遞減版本僅修改偏移寄存器,而不會修改基寄存器。
模塊 15 - 數據指針
模塊15包含MAXQ架構中三個數據指針中的兩個。根據子解碼,對此模塊的訪問將執行直接或間接加載或存儲,并可能在間接訪問后增加或減少數據指針。這些寄存器子解碼可用作源寄存器或目標寄存器(表8)。
表 8.模塊 15 子解碼
子 | 功能 | 描述 |
0 | @DP[0] | 讀取或寫入 DP[0] 指向的數據存儲器位置。 |
1 | @DP[0]++ | 如果是 source,則讀取 DP[0] 指向的數據存儲器位置,然后遞增 DP[0]。如果為 target,則遞增 DP[0],然后將源數據存儲在 DP[0]。 |
2 | @DP[0]-- | 如果為 source,則讀取 DP[0] 指向的數據存儲器位置,然后遞減 DP[0]。如果為 target,則遞減 DP[0],然后將源數據存儲在 DP[0]。 |
3 | DP[0] | 數據指針 0 |
4 | @DP[1] | 讀取或寫入 DP[1] 指向的數據存儲器位置 |
5 | @DP[1]++ | 如果是 source,則讀取 DP[1] 指向的數據存儲器位置,然后遞增 DP[1]。如果為 target,則遞增 DP[1],然后將源數據存儲在 DP[1]。 |
6 | @DP[1]-- | 如果是 source,則讀取 DP[1] 指向的數據存儲器位置,然后遞減 DP[1]。如果為目的地,則遞減 DP[1]。然后將源數據存儲在DP[1]。 |
7 | DP[1] | 數據指針 1 |
模塊 7 - 布爾變量操作
布爾變量操作(BVM)模塊(模塊7)允許在典型的MAXQ處理器中對許多寄存器進行位提取和位設置/清除(圖7)。請注意,并非所有模塊都連接到 BVM 計算機。通常,只有外圍模塊連接到 BVM;系統寄存器沒有。因此,在BVM和系統寄存器之間移動數據可能會導致不可預測的后果。
圖7.模塊7的子解碼指定要提取或替換的位,如果是源指示符,則指定即時位值。
作為目的地指示符,BVM 充當進位的代理。提取源的一個位并將其復制到進位。如果 BVM 是源指示符,則子解碼的第 3 位(完整源指示符的第 7 位)中給出的值將復制到目標的指定位。
請注意,BVM 僅適用于外設寄存器的 0 到 7 位。這對于大多數外設寄存器來說是可以接受的,因為許多寄存器(特別是I/O端口)的長度僅為8位。但是,當訪問16位外設寄存器時,只有低階8位可用。
模塊 11 - 前綴
前綴模塊是MAXQ架構的一個獨特特性,解決了所有16位微控制器的限制。對于 16 位寄存器,即時加載指令需要 16 位操作數,這意味著有效的即時加載指令需要 16 位以上。
針對這一限制有幾種解決方案,包括可變長度指令和寄存器,允許獨立訪問低字節和高字節(MAXQ GR寄存器就是一個例子)。沒有一種解決方案是理想的,因為它們會使解碼邏輯復雜化或涉及新的寄存器(圖 8)。
圖8.當前綴寄存器是目標時,8 位即時源為 16 位即時操作數提供高位字節;目標子解碼提供額外的位,以允許對每個模塊中源和目標操作數的所有 32 個寄存器進行尋址。
前綴機制以兩種方式改進了此過程。首先,通過僅為那些特別需要額外位的指令添加前綴,該機制可以節省代碼空間和執行時間。其次,通過不僅為直接操作數提供額外的位,而且為寄存器指示符提供額外的位,該機制保留了整體架構,同時擴展了寄存器空間的大小。
請記住,雖然每個寄存器模塊有 32 個寄存器,但只有 <> 位指定源寄存器,只有 <> 位指定目標寄存器。前綴機制提供這些附加位。
前綴機制在幾個方面是唯一的。首先,指令目標部分的某些位用作直接源位,用于訪問寄存器子解碼,源地址高于15,目標地址高于<>。這樣,單個前綴指令可以提供從任何寄存器或即時值到任何寄存器子解碼的訪問。
其次,前綴寄存器是唯一的,因為加載到其中的任何值只能存活一個時鐘周期。之后,寄存器自動清零。這意味著任何移動到前綴寄存器的指令都必須是前綴寄存器要修改的指令之前的指令。這也意味著前綴指令是不可中斷的。如果在前綴操作之后發生中斷,則當中斷返回到主函數時,前綴信息將丟失。
如圖9所示,前綴寄存器中的位進入源指示符、目標指示符和即時值。因此,雖然大多數指令在單個周期內執行,但以下指令需要兩個周期:地址目標寄存器子解碼大于 7;地址源寄存器子解碼大于 15;或加載大于 255 的即時值。
圖9.前綴寄存器提供 16 位即時操作數所需的額外位,并將每個模塊中的所有 32 個寄存器尋址為源和目標。
為了說明此過程,請考慮指令移動 A[0],#010h。由于這會將即時值移動到模塊 9 寄存器 0,匯編程序將創建以下操作代碼:0910。但是,如果指令是移動 A[10],#0320h,匯編程序必須自動插入前綴指令:2B03 2920。
如果沒有前綴指令,操作代碼 2920 將轉換為移動 A[2],#020h。但是前綴會向目標說明符添加位,為即時值添加額外的位,允許處理器將任何值加載到任何寄存器子解碼,并且永遠不會花費超過兩個周期。
幾個例子
獨特的MAXQ20內核架構允許一些在其他處理器中根本無法實現的操作。
向量中斷
MAXQ20內核只有一個中斷矢量寄存器,有些人可能認為這是一個限制因素。但請考慮具有兩個外部中斷的系統,其中設備 A 連接到端口 0 位 0,設備 B 連接到端口 0 位 1。現在,中斷選擇可以像跳轉PI0一樣簡單。在地址 0 處,代碼為:
0000: IRET 0001: jump SERVICE_DEVICE_A 0002: jump SERVICE_DEVICE_B 0003: jump SERVICE_DEVICE_A
在此示例中,設備 A 在中斷服務中具有優先級。也就是說,如果兩個中斷請求行都處于活動狀態(端口 0 具有位 0 和 1 個活動狀態),則為 A 提供服務。在中斷服務例程結束時,設備A可能不再處于活動狀態,并且可以為設備B提供服務。
任務管理器
在許多應用程序中,需要循環瀏覽任務列表以創建粗略類型的多任務環境。當不需要搶占(或由于實時原因而不希望)時,這很有用。MAXQ架構使這種過程變得簡單:
task_wheel_init: move dp[0], #task_list task_wheel: move dp[0], dp[0] jump @dp[0]++ . . . task_list: dw task_01 dw task_02 dw task_03 dw task_wheel_init
指向任務列表。在task_wheel例程中,選擇 DP[0] 作為源指針,然后從任務列表中加載指令指針。當每個任務完成時,它不會執行 RET,而是簡單地跳轉到task_wheel例程。
執行表向量中的最后一個條目以重新初始化指針,任務輪將再次開始掃描表。
遍歷列表
通常,快速搜索大小不規則的對象列表以查找標記的條目很有用。這在某些處理器架構中很困難,因為內存訪問功能已從 ALU 中刪除。在MAXQ中,這是一項簡單的任務。
標記 | 基 | 數據 | |||||||||||||
3樓 | 09 | 00 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 08 | |||||
17 | 0E | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 1一 | 1乙 | 1C | 1D |
35 | 07 | 20 | 21 | 21 | 22 | 23 | 24 | 25 |
對于此示例,假定列表包含由標記、長度和數據字符串組成的數據對象。遍歷此列表的例程可能如下所示:在八條指令中,此例程遍歷列表,查找終止列表的匹配項或零條目。在8MHz MAXQ20內核上,該例程每秒遍歷<>萬個條目。
item_seek: move acc, @dp[0]++ ;Get tag jump z, item_not_found ;Tag==0 means end of list cmp a[1] ;A[1] has target tag jump e, item_found ;If item==target, exit move acc, @dp[0]++ ;If no match, get data len add dp[0] ;Add to pointer move dp[0], acc ;Store pointer back jump item_seek ;...and seek next item.
結論
盡管MAXQ內核體積小,看似簡單,但其傳輸觸發架構使其在速度和靈活性方面具有顯著優勢。由于外設直接通過寄存器接口尋址,因此通過嵌入式外設的數據傳輸速度令人印象深刻。總之,任何形式的MAXQ內核都是各種微控制器應用的絕佳選擇。
審核編輯:郭婷
POPI |
-
微控制器
+關注
關注
48文章
7649瀏覽量
152111 -
處理器
+關注
關注
68文章
19408瀏覽量
231186 -
嵌入式
+關注
關注
5092文章
19177瀏覽量
307680
發布評論請先 登錄
相關推薦
評論