-
流水线划分的问题,很多个cycle的长周期指令应该怎么分流水线
以前是用sram,读写都可以1 cycle完成,所以可以很好的放在fetch MEM里, 现在的这个cache操作,不管是inst_valid还是data_addr_ok data_data_ok都要很多个cycle。 LSU里发地址过去是在ex里,但data_addr_ok给回来要5个cycle。而等到data_data_ok又需要5个cycle。 所以现在要搞清楚发地址或者写dcache需要几个cycle,是不是要把计算地址放在EX,把发地址,等读回数据都算做MEM? 之前提到的bug,pc_x流水线寄存器一直走,IFU被stall了应该停下来准确表示当前指令的问题。 在pc_f2d_reg里加了en,如果IFU stall,pc_d就不更新。再加上之前改的,valid也不进到_d,pippeline里的数据是无效的。 cpu7/IP/myCPU/cpu7_ifu_fdp.v 130 wire pc_f2d_en = ~exu_ifu_stall_req; 131 132 dffe_s #(`GRLEN) pc_f2d_reg ( 133 .din (pc_f), 134 .clk (clock), 135 .q (pc_d), 136 .en (pc_f2d_en), 137 .se(), .si(), .so()); 红框的地方pc_f被exu_ifu_stall_req stall住了,一直没有传到pc_d,直到这个信号消失。这里将来还有其它的控制信号,比如mul div指令的。 蓝线的是addi指令的,这个没问题,每一步都是1个cycle,也没有IFU stall。 黄线是ld.w指令,这个有问题,因为在EX MEM都花了5个cycle,但pc_e pc_m没有反映出来。 不过这部分要先把上面说的LSU的情况搞清楚以后再改。 下面是测试程序fun_uty2_ld_2,和以前的一样。 obj/main.elf: file...
-
LSU OP decode 搞错地方了
应该放在_d。现在是放在_e了。 LSU BRU要是想stall IFU,最好在_d就判断好指令,这样stall IFU的时候就不需要再处理_d流水线寄存器里的指令了,要不_d也得stall。 ALU也是把alu_op送进去的,里面也有解码的部分。 感觉应该把lsu_op在_d送进去,decode的verilog代码也是在lsu里,把结果送到_e的流水线寄存器里。 不过看到在OpenSPARC里也是部分解码出op,具体详细的还是在各个功能模块里。 ifu/rtl/sparc_ifu_dec.v //---------------------------------------------------------------------- // Code Begins Here //---------------------------------------------------------------------- assign clk = rclk; assign op = dtu_inst_d[31:30]; assign op2 = dtu_inst_d[24:22]; assign op3 = dtu_inst_d[24:19]; assign opf = dtu_inst_d[13:5]; // decode op assign brsethi_inst = ~op[1] & ~op[0]; assign call_inst = ~op[1] & op[0];...
-
遇到LSU指令时stall IFU,处理流水线中的指令
可以在_d阶段判断出是不是LSU指令,也可以知道是不是load指令。 现在store指令还没有试,不知道写成功回不回data_data_ok,要是回的话需要几个周期。 _d阶段,可以控制IFU仍然选择old pc,但当前的指令会进到_d的流水线寄存器。 可以刷_d流水线寄存器 可以用exu_ifu_stall_req来清除进到_d流水线寄存器的valid信号。这也相当于刷掉了这条指令,卡在_bf和_f的oldpc这条指令是最终送进流水线执行的。 问题是,exu_ifu_stall_req信号从lsu_op decode给出,只有1个cycle有效,怎样让它持续到LSU指令完成。 要看下openSPACR里,stall_req后是怎么恢复的。 ifu/rtl/sparc_ifu_fcl.v dff_s #(2) stlreq_reg(.din ({lsu_ifu_stallreq, ffu_ifu_stallreq}), .q ({lsu_stallreq_d1, ffu_stallreq_d1}), .clk (clk), .se(se), .si(), .so()); assign all_stallreq = ifq_fcl_stallreq | lsu_stallreq_d1 | ffu_stallreq_d1 | itlb_starv_alert; // leave out stall from ifq which goes directly to swl assign fcl_dtu_stall_bf = lsu_stallreq_d1 | ffu_stallreq_d1...