0

我正在用 Verilog 创建一个模拟。

我有一个内存模块,加载了像这样的 MIPS 指令......

20082000
200d2030
8dad0000
240a0001
ad0a0000
..
..
..

内存模块将指令输出到“控制”模块的输入端,该模块有以下信号:

RegDst、跳转、分支、MemRead、MemtoReg、ALUOp、MemWrite、ALUSrc、RegWrite

将为加载内存模块的受支持指令列表生成信号值。add,addi等指令

我如何知道给定指令的信号是真还是假?

4

1 回答 1

3

您必须分解每条指令的作用。

例如,使用MIPS 绿卡

所有 R-Type 指令共享某些控制信号,这些控制信号遵循它们的基本指令格式——例如它们的源/读取rs&rt和目标/写入到rd,这意味着:

  • RegDest是真的(rd是写的,不是rt
  • RegWrite是真的(写了一些 reg)
  • ALUSrc为真(第二个 alu 输入来自寄存器,而不是立即数)

I-Type 指令都有一定的共享控制信号模式:

  • RegDest为假(rt已写,rdI-Types 没有)
  • RegWrite是真的(写了一些 reg)
  • ALUSrc为假(第二个 alu 输入来自立即数,而不是来自寄存器)

除了加载和存储之外,没有指令触及内存,因此MemRead对于MemWrite所有其他指令都是错误的。  MemRead仅适用于加载,仅MemWrite适用于商店。

MemtoReg对于加载结果为真,因为结果来自内存,但对于大多数其他指令为假,因为结果(如果有)来自 ALU。


对于许多指令,其中一些控制信号无关紧要,因此可以归类为“不关心”而不是真或假(硬件都可以)。例如,由于存储指令将数据发送到内存,因此它不会更新 CPU 寄存器 - 因此,MemToReg对于那个无关紧要,因为无论如何都不会写入 reg (对于分支也是如此,因为它们也不写入 /更新寄存器)。

何时RegWrite为假,则MemtoReg无关紧要(不在乎)。


与其他大多数不同,ALUOp 是一个大于单个布尔值的控制信号。所以 ALU 需要知道要执行什么操作,对于 R-Type 指令,这来自funct指令字段,而对于 I-Type 指令,这来自操作码字段本身。

对于加载和存储,ALU(在单周期 MIPS CPU 中)用于执行寻址模式计算,因此应该告诉 ALU 添加。

对于分支(在单周期 MIPS CPU 中),应该告诉 ALU 进行减法(即比较)。


高级:硬件是所有指令所需的所有组件的结合。控制信号用于为正在执行的任何单个指令“激活”适当的硬件组件——但是,诀窍是这些信号实际上并没有激活组件,而是选择在之后是接受还是忽略它们的输出给定正在执行的指令,它们分别计算出有用或无用的东西。

这有点麻烦,但是所有需要的硬件组件(对于每条可能的指令)的结合一直坐在那里做某事(除非使用非常先进的节能电路)。因此,控制信号所做的——而不是关闭对当前指令没有贡献的组件——只是简单地忽略它们的计算结果,而偏向于相关的东西。

例如,有效地,立即数硬件在每个指令的每个周期上对I-Type 16 位立即数进行符号扩展,但该计算值仅在指令实际上是 I-Type 时使用,否则由于控制而被忽略信号(ALUSrc)。

虽然我们可能认为这是低效的,但有一个值得赞赏的并行性能,即提前计算不必要的东西,以防万一需要它们,只有在以后知道更多时才抑制它们。

于 2020-04-14T00:48:34.140 回答