req和ack
比如ifu向biu发读内存请求ifu_biu_req,一旦仲裁后得到axi总线,biu发回biu_lsu_ack。
但是ack不能参与到req的逻辑里去,会出现combinational loop,通过dff存一次也不行,loop的warning虽然没有了,但实际在fpga上运行的时候会发现能跑到的频率低很多,比如能跑到75mhz的只能跑50mhz。当时没看综合后工具给出的fmax。
现在c7bbiu实现的方式是biu自己记录当前自己是不是busy,如果busy就不接受新请求,而对req要求不是很严。
比如ifu_biu_req可以是----_
,一直给high,直到要求的数据接收到rdata_valid。
这样很不好的一个问题就是,如果数据很久不到,ifu_biu_req就一直是high。现在是lsu的priority更高,如果lsu_biu_req一直是high。现在是单发射,所以问题不明显。
见到的req ack的用法是,requestor自己记录biu是不是busy,比如刚发出了ifu_biu_req,并且通过rd_arbitrator后得到ar channel,发回了biu_ifu_ack。这时ifu自己标记biu_busy。
也就是ifu_biu_req的请求不应该有连续两个high的cycle。
这个还要试试才行。
// instruction fetch in progress
wire if_in_prog_in;
wire if_in_prog_q;
wire biu_busy;
assign biu_busy = if_in_prog_q; // | others
// if inst_cancel, inst_valid_f will not coming, so let if_in_prog_in finish
wire if_fin;
assign if_fin = inst_valid_f | inst_cancel;
assign if_in_prog_in = (if_in_prog_q & ~if_fin) | inst_ack;
dffrl_s #(1) lf_in_prog_reg (
.din (if_in_prog_in),
.clk (clk),
.rst_l (~reset),
.q (if_in_prog_q),
.se(), .si(), .so());
assign inst_req = ~reset &
~exu_ifu_stall_req &
~biu_busy;
可以看到inst_req只high一个cycle,以inst_ack开始下一个cycle,inst_valid_f结束,biu_busy是high。一但biu_busy结束,立即开始下一个inst_req。
现在ifu和lsu不存在同时rd arbitration的情况,如果lsu和ifu或者以后多个模块同时请求,比如lsu抢到了,那inst_req在没有得到inst_ack以前,应该会一直high。
如果需要inst_cancel,biu里的逻辑会取消下一个inst_valid_f,所以lf_in_prog_reg就收不到结束信号,所以要用inst_cancel替代,让biu_busy结束。