<dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><s id="yhprb"><strike id="yhprb"></strike></s></dfn><small id="yhprb"></small><dfn id="yhprb"></dfn><small id="yhprb"><delect id="yhprb"></delect></small><small id="yhprb"></small><small id="yhprb"></small> <delect id="yhprb"><strike id="yhprb"></strike></delect><dfn id="yhprb"></dfn><dfn id="yhprb"></dfn><s id="yhprb"><noframes id="yhprb"><small id="yhprb"><dfn id="yhprb"></dfn></small><dfn id="yhprb"><delect id="yhprb"></delect></dfn><small id="yhprb"></small><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn> <small id="yhprb"></small><delect id="yhprb"><strike id="yhprb"></strike></delect><dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"><s id="yhprb"><strike id="yhprb"></strike></s></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn>

新聞中心

EEPW首頁(yè) > 嵌入式系統 > 設計應用 > Spoc CPU軟核 Part 3-軟件(即程序員)模型

Spoc CPU軟核 Part 3-軟件(即程序員)模型

作者: 時(shí)間:2024-01-22 來(lái)源:EEPW編譯 收藏

有一個(gè)小指令集和一些尋址模式。
這使得 程序員的模型易于學(xué)習。

本文引用地址:http://dyxdggzs.com/article/202401/454998.htm
指令集

目前支持 8 條指令:

1705888178193292.png

例子:

 inc RA2      // increments register RA2 
 dec A       // decrements accumulator 
 sel WA10     // selects WA10 
 do #0xBA00 + WA22 > A // adds value 0xBA00 to register WA22, and writes the result to the accumulator 
 do A and #0x5555 -> @ // logical AND between accumulator and value goes to memory 
 do A xnor #0x5555 > RA0     // logical XNOR between accumulator and value goes to register RA0, selects RA0 
 not RA1     // inverts all the bits in register RA1, selects RA1 
 jsr A+RA10   // calculates A+RA10, and jumps to this address (subroutine, returns with RET)
 jmp #loop   // jmp to label "loop"
尋址模式

Spoc 支持 3 種尋址模式:

1705888324903172.png

例子:

 do #1234 -> A    // Immediate addressing: moves value 1234 to accumulator 
 do A -> RA4    // Direct addressing: writes accumulator value to register RA4 
 do @ -> A    // Indirect addressing: reads memory to accumulator 
 do A -> @    // Indirect addressing: writes accumulator to memory

可以對源操作數和目標操作數使用間接尋址。

 do @ -> @ 
 do @ + #0x22 -> @ 
 do A or @ -> @

間接尋址與“選定的寄存器”有關(guān)(參見(jiàn)下面的“存儲器和寄存器文件”段落)。

DO指令

DO 指令是最強大的,因為它可以使用多達 2 個(gè)源執行操作,并將結果寫(xiě)入多達 2 個(gè)目的地。

要寫(xiě)入 2 個(gè)目標,請用逗號分隔它們。
示例:寫(xiě)入 2 個(gè)目標時(shí),一個(gè)始終是累加器,另一個(gè)是寄存器 (RAxx/WAxx) 或存儲器 (@)。

 do #22 -> A, RA0 
 do A + #22 -> A, WA1 
 do A - @ -> A, WA1 
 do A or RA3 -> WA4, A 
 do @ and #22 -> A, @ 
 do WA6 xor #22 -> A, @
累加器和數據大小

每個(gè) spoc 指令都從可能的大小列表中指定一個(gè)數據大小。
Spoc0 具有 4 種有效數據大?。?、8、16 和 32 位。 默認值為 16 位(未指定數據大小時(shí))。
數據大小是通過(guò)后綴指令(.bit、.byte、.word 和 .dw)來(lái)指定的。

Spoc 還為每個(gè)有效數據大小提供了一個(gè)累加器。使用 Spoc0,這為我們提供了 4 個(gè)累加器。
累加器是獨立的(寫(xiě)入一個(gè)不會(huì )影響其他累加器)。

例子:

 do.bit #1 -> A      // writes 1 to the 1-bit accumulator inc.byte A      // increments the 8-bits accumulator 
 do.word A + #0x1000-> A      // adds 0x1000 to the 16-bits accumulator 
 do.dw #0x12DECF80 -> A      // writes 0x12DECF80 to the 32-bits accumulator
分支

指令 JMP 用于分支到新的程序位置。
指令 JSR 用于分支到新的程序位置,最終使用指令 RET 從該位置返回。
這些指令可以有條件地執行(借助 C 和 Z 標志,請參閱下一段)。

例子:

 jmp #gothere      // jumps unconditionally 
 jsr #gotosubroutine    // jumps unconditionally to subroutine 
 jmp.Z=0 #gothere    // jumps conditionally (if flag Z is 0)

分支指令可以使用計算地址進(jìn)行分支。 例如,可以有子例程表。
注意:在任何分支指令之后,將取消選擇當前寄存器(有關(guān)“選定”寄存器的討論,請參閱后面的內容)。

在使用 JSR 指令之前,請確保初始化 SP(堆棧指針)寄存器。

例:

  do #0x0C00 > SP // stack from 0x0C00 to 0x0FFF,enough for a depth of 64 subroutine calls
  jsr #mysubroutine

堆棧用于存儲子例程返回地址。 堆棧使用內存并向上增長(cháng)(在 Spoc0 中,SP 指針對于每個(gè) JSR 指令遞增 16,對于每個(gè) RET 遞減 16)。

標志和條件執行

標志用于有條件地執行其他指令。
Spoc0 使用 2 個(gè)標志:

  • Z(零)標志。用于檢測零值或“相等”比較。

  • C(攜帶)標志。對于無(wú)符號數字的“大于”比較很有用(還可以檢測無(wú)符號添加/子操作的溢出)。

如果上一個(gè)操作的結果為 0,則 Z 標志為 0。
如果上一個(gè)操作的結果不是 1,則 Z 標志為 0(注意:許多 CPU 采用相反的約定......
標志由所有執行的指令設置。

例子:

 do #3 > A dec A   // A becomes 0x0002, C is 0, Z is 1 
 dec A   // A becomes 0x0001, C is 0, Z is 1 
 dec A   // A becomes 0x0000, C is 0, Z is 0 
 dec A   // A becomes 0xFFFF, C is 1, Z is 1 
 dec A   // A becomes 0xFFFE, C is 0, Z is 1 
 dec A   // A becomes 0xFFFD, C is 0, Z is 1

您可以執行沒(méi)有目標的 DO 操作。 在這種情況下,將執行操作,結果將丟失,但標志仍會(huì )更新。

例子:

 do #3 -> WA0     // writes 3 to register WA0

 // now we are going to do 3 subtractions, without saving the results. But the flags are still updated. 
 do WA0-#2    // WA0>2, so we get C=0, Z=1 
 do WA0-#3    // WA0=3, so we get C=0, Z=0 
 do WA0-#4    // WA0<4, so we get C=1, Z=1

 // now run some conditional instructions 
 jmp.c=0 #mylabel1     // conditional jump, not executed since C=1 
 add.z=0 WA0 + A > RA2       // conditional addition, not executed since Z=1 
 jmp.z=1 #mylabel2     // conditional jump, executed since Z=1

最后,如果未執行條件指令,則標志也不會(huì )更新。

例:

 do #1 > A    // A is 0x0001, C is 0, Z is 1 
 dec.z=0 A      // not executed, and flags not changed
將標志作為操作數

進(jìn)位標志也可以在源操作數中使用(在源操作數中,進(jìn)位標志可以命名為“C”或“CY”或“carry”)。

例:

 do CY -> A 
 do A + #22 + C -> A 
 do A xor CARRY -> RA0

對于算術(shù)運算,進(jìn)位標志值不是有符號擴展的,但對于邏輯運算,它是有符號擴展的(換句話(huà)說(shuō),對于算術(shù)運算,進(jìn)位值為 0 或 1,對于邏輯運算,進(jìn)位值為 0 和 0xFFFF)。

例:

 do #0 -> A dec A        // A=0xFFFF, C=1 
 do CY + #22 -> A       // arithmetic operation, so A=23 
 do #0 -> A dec A        // A=0xFFFF, C=1 
 do CY xor #0x1111 -> A       // logical operation, so A=0xEEEE
存儲器和寄存器文件

符號“@”用于表示內存訪(fǎng)問(wèn)。
它與名為“RAxx”和“WAxx”的寄存器結合使用。

內存讀取示例(從地址0x200讀?。?/p>

 do #0x0200 -> RA0 do @ -> A      
 // reads memory 0x200, and puts the value in accumulator

內存寫(xiě)入(寫(xiě)入地址0x200)示例:

 do #0x0200 -> WA17 
 do RA3 -> @       // writes content of RA3 to memory 0x200

讀取存儲器訪(fǎng)問(wèn)的地址由“RAxx”寄存器給出。
寫(xiě)存儲器訪(fǎng)問(wèn)的地址由“WAxx”寄存器給出。
寄存器是寄存器文件的一部分,因此您可以使用其中的許多寄存器。
Spoc0 有 32 個(gè) RA 寄存器,命名為 RA0 到 RA31,以及 32 個(gè) WA 寄存器,命名為 WA0 到 WA31。
每個(gè)文件的一個(gè)寄存器在給定的執行時(shí)間被“選擇”。 要選擇寄存器,您可以使用“sel”指令,也可以寫(xiě)入寄存器。
當指令進(jìn)行內存訪(fǎng)問(wèn)時(shí),所選寄存器的值用作內存地址。
在每次內存訪(fǎng)問(wèn)期間,寄存器都會(huì )自動(dòng)遞增。

例:

 do #0x0200 -> RA5    // writes 0x200 to RA5, and selects it 
 do #0x0300 -> WA7    // writes 0x300 to WA7, and selects it

 // RA5 and WA7 are both selected 
 do @ -> @    // copies the value from memory location 0x200 to memory location 0x300

 // now RA5=0x210 and WA7=0x310 
 do WA7 + #0x20 -> RA6     // RA6 is now selected with the value 0x330 
 do @ -> A       
 // memory location 0x330 is read and copied to the accumulator 
 sel RA5    
 // re-select RA5. Since it was non-persistent, its value is back to 0x0200 (see later for explanation on persistent registers)

寄存器 RAxx/WAxx 還可用于存儲器訪(fǎng)問(wèn)以外的其他目的。 它們具有與累加器幾乎相同的功能,因此可以遞增、添加、異或編輯......
它們還可用于子例程參數傳遞。

內存空間

使用 Spoc0 時(shí),每個(gè)寄存器 WAxx 和 RAxx 的寬度為 16 位 (.word),因此它可以尋址 64K。
數據空間是“位可尋址”的。 因此,您可以在沒(méi)有任何對齊限制的情況下訪(fǎng)問(wèn)它的任何部分。 例如,可以將一個(gè) 32 位值寫(xiě)入尋址0xABCD,然后在地址0xABC3寫(xiě)入另一個(gè)值,最后從地址0xABC7讀?。ㄗx取兩個(gè)值的一部分)。
代碼空間通常無(wú)法直接訪(fǎng)問(wèn)。 它用于保存要執行的指令。 但是有一個(gè)鉤子可以訪(fǎng)問(wèn)代碼空間,這樣你就可以存儲表、數據、字符串......
Spoc0 使用寄存器 CS 訪(fǎng)問(wèn)代碼空間。

例:

  do #GreetingString -> CS      // CS points to a string, and selects CS  do.byte @ -> A     // read the "H" into the accumulator
  ...

GreetingString:  data.byte "Hello world!", 13

另一個(gè)保留值是“$”。 它代表實(shí)際的PC(程序代碼位置,當前執行指令的位置)。 這是一個(gè)只讀值。

例:

  jmp $     // forever loop (if you want spoc to "die")

當您使用 blockram 時(shí)(如在 Spoc0 中),代碼空間是位可尋址的,如果使用串行閃存,則代碼空間是字節可尋址的。 這為 Spoc64 提供了 0Kbits 的空間,而使用串行閃存時(shí)則為 64KB 的空間。

預留空間

Spoc0 使用一個(gè)塊 (4Kbits) 作為數據空間,它填充0x0000到0x0FFF的地址。
在此之上,0x1000 0xFFFF的空間是“外部存儲器”。它應該用于連接外部外圍設備。

此外,保留 blockram 數據空間的前 1Kbit(地址 0x0000 到 0x03FF)來(lái)保存寄存器 RAxx/WAxx 的值。 如果你知道自己在做什么,你仍然可以使用它......


保留寄存器

寄存器 WA30/31 和 RA30/31 是保留的。 不要使用它們。

例如,在 Spoc0 中,寄存器 WA31 用作 PC...所以如果你要使用 WA31,你實(shí)際上會(huì )跳到某個(gè)地方......

持久寄存器

當一個(gè)寄存器被取消選擇,然后在以后重新選擇時(shí),它的值可以是“持久的”(它在最后一次自動(dòng)遞增之后恢復該值),也可以是“非持久的”(它恢復最初受影響的值,即在任何內存訪(fǎng)問(wèn)/自動(dòng)遞增之前)。

您可以選擇是否希望在選擇寄存器時(shí)將其持久化(通過(guò)使用或不使用“.p”后綴)。

例:

do #0x0200 -> RA5    // RA5 is selected (not persistent) 
do @ -> A    // copies the value from memory location 0x200 to accumulator
                  // RA5 value is now 0x210 do #0x0300 -> RA6.p    // RA6 is selected (persistent) 
do @ -> A    // copies the value from memory location 0x300 to accumulator
                  // RA6 value is now 0x310 
sel RA5.p    // re-selects RA5. Since it was non-persistent, its value is back to 0x0200
                   // note that it is now persistent! 
do @ -> A    // copies the value from memory location 0x200 to accumulator
                  // RA5 value is now 0x210 
sel RA6    // re-selects RA6. Since it was persistent, its value is 0x0310 
do @ -> A    // copies the value from memory location 0x310 to accumulator
                  // RA6 value is now 0x320 
sel RA5    // re-selects RA5 (not persistent). But since it was persistent, its value is 0x0210 
do @ -> A    // copies the value from memory location 0x210 to accumulator
                  // RA5 value is now 0x220

上一篇:Spoc CPU軟核 Part 2-主要特征

下一篇:Spoc CPU軟核 Part 4-硬件接口



關(guān)鍵詞: FPGA Spoc

評論


相關(guān)推薦

技術(shù)專(zhuān)區

關(guān)閉
国产精品自在自线亚洲|国产精品无圣光一区二区|国产日产欧洲无码视频|久久久一本精品99久久K精品66|欧美人与动牲交片免费播放
<dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><s id="yhprb"><strike id="yhprb"></strike></s></dfn><small id="yhprb"></small><dfn id="yhprb"></dfn><small id="yhprb"><delect id="yhprb"></delect></small><small id="yhprb"></small><small id="yhprb"></small> <delect id="yhprb"><strike id="yhprb"></strike></delect><dfn id="yhprb"></dfn><dfn id="yhprb"></dfn><s id="yhprb"><noframes id="yhprb"><small id="yhprb"><dfn id="yhprb"></dfn></small><dfn id="yhprb"><delect id="yhprb"></delect></dfn><small id="yhprb"></small><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn> <small id="yhprb"></small><delect id="yhprb"><strike id="yhprb"></strike></delect><dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"><s id="yhprb"><strike id="yhprb"></strike></s></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn>