Spoc CPU软核 Part 3-软件(即程序员)模型

发布时间:2024-01-22  

有一个小指令集和一些寻址模式。
这使得 程序员的模型易于学习。

本文引用地址:
指令集

目前支持 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 @ -> @

间接寻址与“选定的寄存器”有关(参见下面的“存储器和寄存器文件”段落)。

DO指令

DO 指令是最强大的,因为它可以使用多达 2 个源执行操作,并将结果写入多达 2 个目的地。

要写入 2 个目标,请用逗号分隔它们。
示例:写入 2 个目标时,一个始终是累加器,另一个是寄存器 (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, @
累加器和数据大小

每个 spoc 指令都从可能的大小列表中指定一个数据大小。
Spoc0 具有 4 种有效数据大小:1、8、16 和 32 位。 默认值为 16 位(未指定数据大小时)。
数据大小是通过后缀指令(.bit、.byte、.word 和 .dw)来指定的。

Spoc 还为每个有效数据大小提供了一个累加器。使用 Spoc0,这为我们提供了 4 个累加器。
累加器是独立的(写入一个不会影响其他累加器)。

例子:

 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)

分支指令可以使用计算地址进行分支。 例如,可以有子例程表。
注意:在任何分支指令之后,将取消选择当前寄存器(有关“选定”寄存器的讨论,请参阅后面的内容)。

在使用 JSR 指令之前,请确保初始化 SP(堆栈指针)寄存器。

例:

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

堆栈用于存储子例程返回地址。 堆栈使用内存并向上增长(在 Spoc0 中,SP 指针对于每个 JSR 指令递增 16,对于每个 RET 递减 16)。

标志和条件执行

标志用于有条件地执行其他指令。
Spoc0 使用 2 个标志:

  • Z(零)标志。用于检测零值或“相等”比较。

  • C(携带)标志。对于无符号数字的“大于”比较很有用(还可以检测无符号添加/子操作的溢出)。

如果上一个操作的结果为 0,则 Z 标志为 0。
如果上一个操作的结果不是 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

您可以执行没有目标的 DO 操作。 在这种情况下,将执行操作,结果将丢失,但标志仍会更新。

例子:

 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

最后,如果未执行条件指令,则标志也不会更新。

例:

 do #1 > A    // A is 0x0001, C is 0, Z is 1 
 dec.z=0 A      // not executed, and flags not changed
将标志作为操作数

进位标志也可以在源操作数中使用(在源操作数中,进位标志可以命名为“C”或“CY”或“carry”)。

例:

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

对于算术运算,进位标志值不是有符号扩展的,但对于逻辑运算,它是有符号扩展的(换句话说,对于算术运算,进位值为 0 或 1,对于逻辑运算,进位值为 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
存储器和寄存器文件

符号“@”用于表示内存访问。
它与名为“RAxx”和“WAxx”的寄存器结合使用。

内存读取示例(从地址0x200读取):

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

内存写入(写入地址0x200)示例:

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

读取存储器访问的地址由“RAxx”寄存器给出。
写存储器访问的地址由“WAxx”寄存器给出。
寄存器是寄存器文件的一部分,因此您可以使用其中的许多寄存器。
Spoc0 有 32 个 RA 寄存器,命名为 RA0 到 RA31,以及 32 个 WA 寄存器,命名为 WA0 到 WA31。
每个文件的一个寄存器在给定的执行时间被“选择”。 要选择寄存器,您可以使用“sel”指令,也可以写入寄存器。
当指令进行内存访问时,所选寄存器的值用作内存地址。
在每次内存访问期间,寄存器都会自动递增。

例:

 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 还可用于存储器访问以外的其他目的。 它们具有与累加器几乎相同的功能,因此可以递增、添加、异或编辑......
它们还可用于子例程参数传递。

内存空间

使用 Spoc0 时,每个寄存器 WAxx 和 RAxx 的宽度为 16 位 (.word),因此它可以寻址 64K。
数据空间是“位可寻址”的。 因此,您可以在没有任何对齐限制的情况下访问它的任何部分。 例如,可以将一个 32 位值写入寻址0xABCD,然后在地址0xABC3写入另一个值,最后从地址0xABC7读取(读取两个值的一部分)。
代码空间通常无法直接访问。 它用于保存要执行的指令。 但是有一个钩子可以访问代码空间,这样你就可以存储表、数据、字符串......
Spoc0 使用寄存器 CS 访问代码空间。

例:

  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

另一个保留值是“$”。 它代表实际的PC(程序代码位置,当前执行指令的位置)。 这是一个只读值。

例:

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

当您使用 blockram 时(如在 Spoc0 中),代码空间是位可寻址的,如果使用串行闪存,则代码空间是字节可寻址的。 这为 Spoc64 提供了 0Kbits 的空间,而使用串行闪存时则为 64KB 的空间。

预留空间

Spoc0 使用一个块 (4Kbits) 作为数据空间,它填充0x0000到0x0FFF的地址。
在此之上,0x1000 0xFFFF的空间是“外部存储器”。它应该用于连接外部外围设备。

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


保留寄存器

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

例如,在 Spoc0 中,寄存器 WA31 用作 PC...所以如果你要使用 WA31,你实际上会跳到某个地方......

持久寄存器

当一个寄存器被取消选择,然后在以后重新选择时,它的值可以是“持久的”(它在最后一次自动递增之后恢复该值),也可以是“非持久的”(它恢复最初受影响的值,即在任何内存访问/自动递增之前)。

您可以选择是否希望在选择寄存器时将其持久化(通过使用或不使用“.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

上一篇:

下一篇:

文章来源于:电子产品世界    原文链接
本站所有转载文章系出于传递更多信息之目的,且明确注明来源,不希望被转载的媒体或个人可与我们联系,我们将立即进行删除处理。

我们与500+贴片厂合作,完美满足客户的定制需求。为品牌提供定制化的推广方案、专属产品特色页,多渠道推广,SEM/SEO精准营销以及与公众号的联合推广...详细>>

利用葫芦芯平台的卓越技术服务和新产品推广能力,原厂代理能轻松打入消费物联网(IOT)、信息与通信(ICT)、汽车及新能源汽车、工业自动化及工业物联网、装备及功率电子...详细>>

充分利用其强大的电子元器件采购流量,创新性地为这些物料提供了一个全新的窗口。我们的高效数字营销技术,不仅可以助你轻松识别与连接到需求方,更能够极大地提高“闲置物料”的处理能力,通过葫芦芯平台...详细>>

我们的目标很明确:构建一个全方位的半导体产业生态系统。成为一家全球领先的半导体互联网生态公司。目前,我们已成功打造了智能汽车、智能家居、大健康医疗、机器人和材料等五大生态领域。更为重要的是...详细>>

我们深知加工与定制类服务商的价值和重要性,因此,我们倾力为您提供最顶尖的营销资源。在我们的平台上,您可以直接接触到100万的研发工程师和采购工程师,以及10万的活跃客户群体...详细>>

凭借我们强大的专业流量和尖端的互联网数字营销技术,我们承诺为原厂提供免费的产品资料推广服务。无论是最新的资讯、技术动态还是创新产品,都可以通过我们的平台迅速传达给目标客户...详细>>

我们不止于将线索转化为潜在客户。葫芦芯平台致力于形成业务闭环,从引流、宣传到最终销售,全程跟进,确保每一个potential lead都得到妥善处理,从而大幅提高转化率。不仅如此...详细>>