u@home:~$

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的值。

screenshot0

在时序图里,会有一个时刻,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 this mux as close to the top (itlb) as possible
   dp_mux3ds #(48) pcbf_mux(.dout  (pc_bf[47:0]),
                          .in0   (swpc_bf[47:0]),
                          .in1   (nextpc_nosw_bf[47:0]),
                          .in2   (exu_ifu_brpc_e[47:0]),
                          .sel0_l (fcl_fdp_pcbf_sel_swpc_bf_l),
                          .sel1_l (fcl_fdp_pcbf_sel_nosw_bf_l),
                          .sel2_l (fcl_fdp_pcbf_sel_br_bf_l));

   dff_s #(48)  pcf_reg(.din  (pc_bf),
                    .clk  (clk),
                    .q    (pc_f),
                    .se   (se), .si(), .so());

   assign fdp_erb_pc_f = pc_f[47:0];

如果fdp_icd_vaddr_bf是去cache里取值的,如果cache miss,无论怎样,下一个周期里pc_f都会等于pc_bf。

以后还要看看cache miss怎样stall pc_bf的。上面这个pcbf_mux,如果不选switch pc,也不选branch pc的话nextpc_nosw_bf应该要stall。

   // can reduce this to a 2:1 mux since reset pc is not used any more and
   // pc_f is not needed.
   dp_mux3ds #(49) pcp4_mux(.dout  (nextpc_nosw_bf),
                          .in0   (pcinc_f),
                          .in1   (thr_trappc_bf),
                          .in2   ({fcl_fdp_pcoor_f, pc_f[47:0]}),
                          .sel0_l (fcl_fdp_noswpc_sel_inc_l_bf),
                          .sel1_l (fcl_fdp_noswpc_sel_tnpc_l_bf),
                          .sel2_l (fcl_fdp_noswpc_sel_old_l_bf));

看样也是sel_old。


ifu/rtl/sparc_ifu_fdp.v


   // Thread instruction muxes
   dp_mux4ds #(33)  t0inst_mux(.dout (t0inst_s1),
                             .in0 (ifq_fdp_fill_inst),
                             .in1 (inst_s1_bf1),
                             .in2 (t0inst_s2),
                             .in3 (rb_inst0_s),
                             .sel0_l (fcl_fdp_tinst_sel_ifq_s_l[0]),
                             .sel1_l (fcl_fdp_tinst_sel_curr_s_l[0]),
                             .sel2_l (fcl_fdp_tinst_sel_old_s_l[0]),
                             .sel3_l (fcl_fdp_tinst_sel_rb_s_l[0]));


ifu/rtl/sparc_ifu_fcl.v

   // thread IR input muxes
   assign fcl_fdp_tinst_sel_rb_s_l   = ~rb_w2;
   assign fcl_fdp_tinst_sel_ifq_s_l  = rb_w2 | ~ifq_fcl_fill_thr;
   assign fcl_fdp_tinst_sel_curr_s_l = ~val_thr_s1 | rb_w2 | ifq_fcl_fill_thr;
   assign fcl_fdp_tinst_sel_old_s_l  = val_thr_s1 | rb_w2 | ifq_fcl_fill_thr;

还没搞清楚。