喜欢0次
队伍编号:CICC1413
在进行浮点扩展的过程中,由于浮点指令执行可能需要多周期,因此这就会导致一些数据冲突,例如RAW或WAW,这时候蜂鸟处理器就采用了OITF作为数据冲突处理模块,下面我们简要介绍一下该模块。
在OITF中主要通过队列存储当前所有的长周期的指令。
wire alc_ptr_flg_r;
wire alc_ptr_flg_nxt = ~alc_ptr_flg_r;
wire alc_ptr_flg_ena = (alc_ptr_r == ($unsigned(`E203_OITF_DEPTH-1))) & alc_ptr_ena;
sirv_gnrl_dfflr #(1) alc_ptr_flg_dfflrs(alc_ptr_flg_ena, alc_ptr_flg_nxt, alc_ptr_flg_r, clk, rst_n);
wire [`E203_ITAG_WIDTH-1:0] alc_ptr_nxt;
assign alc_ptr_nxt = alc_ptr_flg_ena ? `E203_ITAG_WIDTH'b0 : (alc_ptr_r + 1'b1);
sirv_gnrl_dfflr #(`E203_ITAG_WIDTH) alc_ptr_dfflrs(alc_ptr_ena, alc_ptr_nxt, alc_ptr_r, clk, rst_n);
例如在这段代码中,alc_ptr_r便代表着当前分配的指令,alc_ptr_flg_ena则是判断是否当前队列已满,如果满了,下一个分配指令就为0,否则就为队列中的下一个。
OITF也提供了冲突检验,主要是通过输出以下四个信号:
output oitfrd_match_disprs1,
output oitfrd_match_disprs2,
output oitfrd_match_disprs3,
output oitfrd_match_disprd,
这四个信号主要是用来匹配是否发生冲突,主要实现:
assign rd_match_rs1idx[i] = vld_r[i] & disp_i_rs1fpu & (rdfpu_r[i] == disp_i_rs1fpu) & (rdidx_r[i] == disp_i_rs1idx);
assign rd_match_rs2idx[i] = vld_r[i] & disp_i_rs2fpu & (rdfpu_r[i] == disp_i_rs2fpu) & (rdidx_r[i] == disp_i_rs2idx);
assign rd_match_rs3idx[i] = vld_r[i] & disp_i_rs3fpu & (rdfpu_r[i] == disp_i_rs3fpu) & (rdidx_r[i] == disp_i_rs3idx);
assign rd_match_rdidx [i] = vld_r[i] & disp_i_rdfpu & (rdfpu_r[i] == disp_i_rdfpu ) & (rdidx_r[i] == disp_i_rdidx );
可以看到这里匹配在OITF中有效的指令是否有目的寄存器与当前指令的寄存器匹配的,如果匹配,毫无疑问则会产生冲突。这四个信号最终也是传给了DISP模块,可以看到DISP中对四个信号的使用:
wire raw_dep = ((oitfrd_match_disprs1) |
(oitfrd_match_disprs2) |
(oitfrd_match_disprs3));
wire waw_dep = (oitfrd_match_disprd);
wire dep = raw_dep | waw_dep;