L1 有 50788,这是当前正在执行的分支指令的地址——它是被送入指令内存的地址,导致获取beq x3, x14, 80。
您可以遵循在 L1 之后,有一个 ADDer,它将向 PC 值加 4(将该值提供给后续电路),加 4 以跳过此 4 字节指令,从而引用下一个连续的内存地址,它保存下一条顺序指令。
L2 是“不关心”,这意味着它是 0 还是 1 无关紧要,因此相同基本设计的不同实现可以使用任一值。为什么这个信号是 0 还是 1 都没有关系?因为这条指令是条件分支,因此不会更新寄存器,所以RegWrite 将为0,因此WriteData 的值不重要并被忽略。
硬件是执行指令集中任何指令的所有必要组件的联合体,因此,在执行不同指令期间,这里或那里的某些电路未使用。允许执行任何给定指令的未使用电路,而不是关闭未使用的电路(这是一种需要设计和实现工作的先进技术,此处未采用) - 但是(无论是关闭还是允许执行)控制信号根据当前指令,进一步设置数据路径以忽略这些未使用电路的结果。
L3 是分支条件信号,它动态地通知 PC 更新电路是否采用分支。在这里,该条件在 ALU 中从表达式 x3 == x14 有效地生成,并确定该控制信号的值:如果它们相等,则该控制信号需要为 1 才能使其采用分支(根据条件的定义分支指令),该控制信号需要为 0 以使其不采取分支,而是继续顺序执行。
希望您可以看到,对于条件分支指令,Branch 控制信号被断言 (1/true) — 此信号与 Zero 结合进入与门,从而导致 1 获取分支与0,通过在与门之后控制多路复用器,不要采用分支。因此,可以采用分支的唯一条件 [pc := pc + sxt(imm)*2] 是 Branch 和 Zero 都为真。如果Branch为假,则不是分支指令,所以Zero无所谓,如果Zero为假,则分支条件为假,所以Branch被覆盖[pc := pc + 4 ].
更明确地说,PC 更新电路说:
PC := (Branch & Zero) ? PC + sxt(imm)*2 : PC + 4;
使用 C 三元运算符(也可以使用 if-then-else 编写)。
Zero 是这个动态控制信号名称的一个相当糟糕的选择。我会选择Take 或Taken。我相信 Zero 这个名字是旧 RISC 架构的历史。
该电路遵循 RISC V 标准,将分支目标立即数字段乘以 2(而不是 MIPS 中的 4),并且该标准使得常规 4 字节指令在压缩指令存在时相同(不变) — 因此,在支持压缩指令的硬件上,不需要模式切换,并且压缩指令可以与未压缩指令交错(与 MIPS16 或 ARM Thumb 不同)。但是,此框图不提供执行压缩指令所需的其他功能(一方面,在此 PC 更新电路中没有增量 2 选项,另一方面,没有压缩指令扩展器,它将进入指令之间内存输出和解码逻辑)。