CPU 速通系列 2-3:ID-EX 模块
代码
Path src/cpu/id_ex.sv
1`include "defines.svh"
2
3module id_ex (
4
5 input logic clk,
6 input logic rst,
7
8 //来自控制模块的信息
9 input logic [5:0] stall,
10
11 //从译码阶段传递的信息
12 input logic [ `AluOpBus] id_aluop,
13 input logic [ `AluSelBus] id_alusel,
14 input logic [ `RegBus] id_reg1,
15 input logic [ `RegBus] id_reg2,
16 input logic [`RegAddrBus] id_wd,
17 input logic id_wreg,
18 input logic [ `RegBus] id_link_address,
19 input logic id_is_in_delayslot,
20 input logic next_inst_in_delayslot_i,
21
22 //传递到执行阶段的信息
23 output logic [ `AluOpBus] ex_aluop,
24 output logic [ `AluSelBus] ex_alusel,
25 output logic [ `RegBus] ex_reg1,
26 output logic [ `RegBus] ex_reg2,
27 output logic [`RegAddrBus] ex_wd,
28 output logic ex_wreg,
29 output logic [ `RegBus] ex_link_address,
30 output logic ex_is_in_delayslot,
31 output logic is_in_delayslot_o
32
33);
34
35 always_ff @(posedge clk) begin
36 if (rst == `RstEnable) begin
37 ex_aluop <= `EXE_NOP_OP;
38 ex_alusel <= `EXE_RES_NOP;
39 ex_reg1 <= `ZeroWord;
40 ex_reg2 <= `ZeroWord;
41 ex_wd <= `NOPRegAddr;
42 ex_wreg <= `WriteDisable;
43 ex_link_address <= `ZeroWord;
44 ex_is_in_delayslot <= `NotInDelaySlot;
45 is_in_delayslot_o <= `NotInDelaySlot;
46 end else if (stall[2] == `Stop && stall[3] == `NoStop) begin
47 ex_aluop <= `EXE_NOP_OP;
48 ex_alusel <= `EXE_RES_NOP;
49 ex_reg1 <= `ZeroWord;
50 ex_reg2 <= `ZeroWord;
51 ex_wd <= `NOPRegAddr;
52 ex_wreg <= `WriteDisable;
53 ex_link_address <= `ZeroWord;
54 ex_is_in_delayslot <= `NotInDelaySlot;
55 end else if (stall[2] == `NoStop) begin
56 ex_aluop <= id_aluop;
57 ex_alusel <= id_alusel;
58 ex_reg1 <= id_reg1;
59 ex_reg2 <= id_reg2;
60 ex_wd <= id_wd;
61 ex_wreg <= id_wreg;
62 ex_link_address <= id_link_address;
63 ex_is_in_delayslot <= id_is_in_delayslot;
64 is_in_delayslot_o <= next_inst_in_delayslot_i;
65 end
66 end
67
68endmodule
解读
实现了数据通路中的 ID-EX(译码-执行)模块。
设计意图
简要而言,ID-EX 模块的设计旨在传递来自译码阶段的信息到执行阶段,同时处理流水线暂停和复位的情况。
具体而言,ID-EX 模块需要完成以下任务:
-
接收来自控制模块的暂停信号(stall)
-
传递译码阶段的 ALU 操作码(id_aluop)、ALU 选择信号(id_alusel)、寄存器 1(id_reg1)、寄存器 2(id_reg2)、写入目标寄存器地址(id_wd)、写入目标寄存器使能信号(id_wreg)、链接地址(id_link_address)、是否处于延迟槽指令(id_is_in_delayslot)等信息到执行阶段
-
根据流水线暂停情况和复位信号,确定执行阶段的 ALU 操作码(ex_aluop)、ALU 选择信号(ex_alusel)、寄存器 1(ex_reg1)、寄存器 2(ex_reg2)、写入目标寄存器地址(ex_wd)、写入目标寄存器使能信号(ex_wreg)、链接地址(ex_link_address)、是否处于延迟槽指令(ex_is_in_delayslot)等信息
-
传递当前是否处于延迟槽指令的状态(is_in_delayslot_o)到下一个阶段
端口
-
clk
:输入时钟信号 -
rst
:输入复位信号 -
stall
:来自控制模块的暂停信号 -
id_aluop
:从译码阶段传递的 ALU 操作码 -
id_alusel
:从译码阶段传递的 ALU 选择信号 -
id_reg1
:从译码阶段传递的寄存器 1 -
id_reg2
:从译码阶段传递的寄存器 2 -
id_wd
:从译码阶段传递的写入目标寄存器地址 -
id_wreg
:从译码阶段传递的写入目标寄存器使能信号 -
id_link_address
:从译码阶段传递的链接地址 -
id_is_in_delayslot
:从译码阶段传递的是否处于延迟槽指令 -
next_inst_in_delayslot_i
:下一条指令是否处于延迟槽指令
伪代码
实现思路
在时钟上升沿触发的 always_ff 块内,根据复位信号 rst 和流水线暂停信号 stall 的状态,以及输入端口的值,确定输出端口的值。
具体实现如下:
-
如果复位信号 rst 为有效状态,则将执行阶段的输出端口(ex_*)和 is_in_delayslot_o 置为初始值。
-
如果 stall[2] 为 Stop 且 stall[3] 为 NoStop,则将执行阶段的输出端口(ex_*)和 is_in_delayslot_o 置为初始值。
-
如果 stall[2] 为 NoStop,则将执行阶段的输出端口(ex_*)和 is_in_delayslot_o 设为对应的输入端口的值。
根据代码注释和信号命名,该模块主要是根据输入信号的状态和控制信号的指示,决定执行阶段需要传递给下一阶段的信息,以及当前是否处于延迟槽指令的状态。
参考资料
本文与 AI 合作完成。