如何有效地为CPU设计操作码?


12

我正在Logisim中构建一个简单的16位CPU,并准备好ALU和想要的操作码。现在,我发现很难为命令找到正确的编码,以使不同的子电路(例如,逻辑,算术)不需要所有(构成编码的)控制线作为输入,而是尽可能少地输入。是否有任何策略或方法有助于有效的操作码设计?

提前


1
首先构建您的ALU,并查看所需的控制线。然后将它们直接连接到“当前指令”寄存器。内存访问控制逻辑和任何其他主要的操作码类别相同。然后使用剩余的任何位选择激活哪个子电路。
user253751

1
Ken Chapman还提供了他的8位可编程状态机KCPSM或PicoBlaze的原始论文。它描述了他如何选择说明和设计ISA。dc.uba.ar/materias/disfpga/2010/c2/descargas/…– Paebbels
2015年

Answers:


9

我认为这是学习其他一些指令集的好方法。

TI的MSP430就是其中的一小部分,它是一个具有约22条指令的16位处理器。

http://www.physics.mcmaster.ca/phys3b06/MSP430/MSP430_Instruction_Set_Summary.pdf

您还可以研究Atmel AVR,它们也有非常小的指令集。

在我的一个小项目中,我尝试用一​​个小的指令集(14条指令)在VHDL中开发一个简单的32位处理器:

http://www.blog-tm.de/?p=80

由于我目前的空闲时间,它还没有完全结束。该指令已实现,但其中两个未经过测试,并且可能缺少某些状态标志。


但是我没有找到可以看到实际编码以及为什么选择这种编码的东西。
Benjoyo

您可以在回购中找到实际的编码:github.com/TM90/MISC_Processor/raw/master/Documentation/…。我之所以选择这些编码,是因为指令解码器中的逻辑变得最小。
TM90 2015年

7

研究(但不要复制)ARM方法进行指令编码。它是严格面向前缀的(例如Dzarda建议的Huffman树方法),并且在指令的寄存器选择部分所在的位置上非常统一。

一种没有想象力但可靠的方法是枚举您拥有的所有控制信号(可能会超过16位),然后尝试对它们进行卡诺图映射样式的逻辑最小化。


我并没有真正理解控制信号的含义。
Benjoyo

我发现并喜欢ARM的是条件字段,我将包括它。
Benjoyo

控制信号是各个多路复用器的输入,并使该信号可以在CPU的各个部分之间定向数据。
pjc50

对于16位体系结构,我认为ARM的指令编码不合适。Mayby thumb2更好。但是我喜欢MIPS的编码方式,简单易懂,尽管有点浪费
phuclv 2015年

4

有一次我尝试在Logisim中使用具有8位指令长度内核的4位CPU。最终得到了一个简单的状态机,不仅仅是一个CPU。

随机寻找的东西

  • 霍夫曼树
  • 定长还是可变编码?
  • 它是具有单个地址空间的冯·诺依曼设计,还是具有独立数据/程序的哈佛风格?

关于Computeruffe的关于霍夫曼树的精彩视频:

https://www.youtube.com/watch?v=umTbivyJoiI


霍夫曼编码不能用于固定长度的编码,对吗?
Benjoyo 2015年

@Benjoyo我可以想象一个场景,其中的备用位用于更改最常用的指令,从而提供更多功能。
Dzarda 2015年

但是我不知道会带来什么样的优化。它对电路设计没有帮助。将霍夫曼编码用于操作码的目的是什么?
Benjoyo

4

我为课程编写的ISA曾经有一个4位操作码,如下所示: 1XXX ALU instructions 01XX jump, jump register, call etc 001X branch not equal, branch equal zero 000X 0 - load, 1 - store

这不是构造最优化的门,而是构造/设计门的更容易的样式之一,因为单个位的输入信号可以完全控制采用哪种逻辑路径。另外,您可以对最常用的符号进行霍夫曼编码,然后对它们进行零填充以获得固定长度的操作码。


我目前正在寻找这种优化。但是我有一个5位操作码,因此我很难将命令分组在一起,以便在电路中有意义。
Benjoyo

@Benjoyo,您可以将高位设置成一堆更多的ALU指令。另外,我的跳转条件覆盖范围很弱,大多数普通分支都需要两条指令。通常,我认为类别为:数学/控制/内存

3

您需要考虑的一件事是是否允许任何形式的多字指令,或者允许像多字指令那样“起作用”的任何东西;如果这样做,则可能需要考虑是在主指令之后使用其他指令字,还是在其前面加上前缀字。允许使用前缀和后继字会增加中断处理的复杂性,但可以避免将很少使用的指令与常用的指令放在同一操作码空间中的需要。

如果在执行之前在周期上取指令,则可能会有一条“条件分支”指令,该指令要么导致下一个指令字被跳过,要么直接将其内容传送到程序计数器中;这样的设计可能会给中断排序增加一些额外的复杂性,但是它可以减轻对“分支”,“跳转”和“调用”指令使用大部分操作码空间的需要,同时允许范围更大的分支条件比原本可能的 由于采用分支的指令通常会在执行指令本身之后需要一个死循环,而不管该地址来自何处,因此使地址来自已取回但不会被执行的以下字不会带来任何额外费用时间。

即使将目标地址移出分支指令将减少它们占用的操作码空间,但16位操作码格式仍然非常紧凑。使用前缀说明可以帮助您。例如,如果要拥有32个寄存器,则允许将任意一个寄存器分别指定为source1,source2和destination,这将需要操作码中的15位,从而允许总共两个指令。不是很有用。另一方面,能够对这三个操作数中的每一个使用32个寄存器中的任何一个都很好。可以通过使任何不带前缀的ALU操作使用8位来进行两个十六分之一的寄存器选择来平衡两个目标,但是让ALU操作紧随前缀之后使用前缀中的某些位来进行两个选择以下指令中的八个 这样就可以从32个完整的寄存器集中独立选择源和目的地。使用高位寄存器的指令将占用两个字/周期,而不是一个字/周期,但是在某些情况下,这种折衷是值得的。使用前缀的最大困难是,要么必须防止在前缀和下一条指令之间发生中断,要么必须确保如果确实发生了中断,则前缀之后的指令仍将使用正确的寄存器(例如,通过使程序运行)。 -counter保存逻辑存储执行的最后一个非前缀指令的地址]。但在某些情况下,这样的权衡可能是值得的。使用前缀的最大困难是,要么必须防止在前缀和下一条指令之间发生中断,要么必须确保如果确实发生了中断,则前缀之后的指令仍将使用正确的寄存器(例如,通过使程序运行)。 -counter保存逻辑存储执行的最后一个非前缀指令的地址]。但在某些情况下,这样的权衡可能是值得的。使用前缀的最大困难是,要么必须防止在前缀和下一条指令之间发生中断,要么必须确保如果确实发生了中断,则前缀之后的指令仍将使用正确的寄存器(例如,通过使程序运行)。 -counter保存逻辑存储执行的最后一个非前缀指令的地址]。

使用多字指令将使设计的某些方面更加困难,但是可以减少做出其他困难决定的需要。


By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.