引言
“善妖善老,善始善终”,说的是无论什么事情要从有头有尾,别三分钟热度。
对于or1200的流水线来说,MA阶段是最后一个阶段,也是整条流水线的收尾阶段,负责战场的清扫工作。比如,把运算指令的运算结果要写到寄存器里,把从内存读来的数据写到寄存器里,如果在前面的流水阶段出现了异常,WB阶段还要负责把异常指令的地址存到寄存器里。总之呢,就是写回寄存器。
本小节,我们就分析一下or1200五级流水线最后一级,也就是WB(write back)。
1,整体结构
or1200的WB模块,主要包括的rtl文件是or1200_wbmux.v和or1200_rf.v。上面,我们介绍了WB阶段的功能和任务,那么这个模块的整体结构是什么样子的呢?如下所示。
WB模块负责将其他流水阶段的结果写回寄存器堆,而寄存器堆只有一个,所以就需要一个多路选择器(wb_mux)。
wb_mux是一个5选1的多路选择器,指令解码的结果和ex_freeze信号作为多路选择器的选择信号。
需要选择的5路信号分别是:
a,来自运算单元的alu的运算结果和fpu的运算结果(fpu模块,并没有实现)。
b,load指令的处理结果(从内存读来的数据)。
c,异常指令的地址。这个需要说明的是,在采用流水线的cpu结构时,各个流水阶段都可能产生异常,但并不是一旦产生异常后就马上处理,而是把所有流水阶段的异常统一处理,这样才能保证精确异常。
d,来自特殊功能寄存器的数据。
多路选择器的输出:
wb_mux模块的输出,
a,oprandmuxes模块。这个是用作forword的。流水线的forword技术,之前我们曾经介绍过,这里不再赘述。
b,rf模块。这个是显然的,写回阶段,肯定要将数据写回到reg_file里面。
c,调试模块。将输出数据给上述模块的同时,也会送给debug模块,这个是调试单元的需要。
2,wb_mux模块
上面介绍了wb_mux的整体功能,下面我们就是其对应的rtl代码。
module or1200_wbmux(
// Clock and reset
clk, rst,
// Internal i/f
wb_freeze, rfwb_op,
muxin_a, muxin_b, muxin_c, muxin_d, muxin_e,
muxout, muxreg, muxreg_valid
);
parameter width = 32;
//
// Internal wires and regs
//
reg [width-1:0] muxout;
reg [width-1:0] muxreg;
reg muxreg_valid;
//
// Registered output from the write-back multiplexer
//
always @(posedge clk or `OR1200_RST_EVENT rst) be