-
LSU data_recv, 又用了回逻辑开关
data_recv的逻辑就是在data_addr_ok以后为1,表示等待接收数据和data_data_ok信号。 data_recv应该是这个意思。 data_addr_ok __--______________ data_data_ok ______________--__ data_recv ____------------__ 这个还是个开关一样的逻辑,data_addr_ok data_data_ok都是只给1个cycle。 402 wire lsu_recv_next; 403 404 assign lsu_recv_next = (lsu_recv | data_addr_ok) & (~data_data_ok); 405 406 dff_s #(1) lsu_recv_reg ( 407 .din (lsu_recv_next), 408 .clk (clk), 409 .q (lsu_recv), 410 .se(), .si(), .so());
-
BUG FIX pc_f到pc_d,在指令还没fetch回来的时候就把pc_f传给pc_d了。
这部分传递受到exu_ifu_stall_req控制,同时也受inst_valid控制。 就算是ALU指令也不应该是阶梯一样,每个cycle都向下传,因为这里fetch指令的时候要5个周期。 应该是下面蓝线这样,pc_bf和pc_f以后就停住了,直到新的pc_bf处的指令读回来了,这个时候pc_bf+4,pc_f再次获得pc_bf的值。 在时序图里,会有一个时刻,pc_f和pc_bf值一样,指向下一条指令,而且inst为0,这时候_f阶段的valid信号也是0。 当时在想,这个时候要不要不让pc_f等于pc_bf,因为如果这个时候要用pc_f的值并不正确,等指令fetch到了pc_f再更新才好。 我看了OpenSPARC,也是这样。 ifu/rtl/sparc_ifu_fdp.v // assign fdp_icd_vaddr_bf = icaddr_bf[47:0]; // this goes to the itlb, icd and ict on top of fdp // this is !!very critical!! assign fdp_icd_vaddr_bf = pc_bf[47:2]; // create separate output for the icv to the left assign fdp_icv_index_bf = pc_bf[11:5]; // Place...
-
流水线划分的问题,很多个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...