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 合作完成。