OpenCores
URL https://opencores.org/ocsvn/s1_core/s1_core/trunk

Subversion Repositories s1_core

[/] [s1_core/] [trunk/] [hdl/] [rtl/] [sparc_core/] [sparc_exu_ecl_wb.v] - Diff between revs 105 and 113

Show entire file | Details | Blame | View Log

Rev 105 Rev 113
Line 16... Line 16...
// You should have received a copy of the GNU General Public
// You should have received a copy of the GNU General Public
// License along with this work; if not, write to the Free Software
// License along with this work; if not, write to the Free Software
// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
// 
// 
// ========== Copyright Header End ============================================
// ========== Copyright Header End ============================================
 
`ifdef SIMPLY_RISC_TWEAKS
 
`define SIMPLY_RISC_SCANIN .si(0)
 
`else
 
`define SIMPLY_RISC_SCANIN .si()
 
`endif
////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
/*
/*
//  Module Name: sparc_exu_ecl_wb
//  Module Name: sparc_exu_ecl_wb
//      Description:  Implements the writeback logic for the exu.
//      Description:  Implements the writeback logic for the exu.
//              This includes the control signals for the w1 and w2 input
//              This includes the control signals for the w1 and w2 input
Line 222... Line 227...
 
 
   ////////////////////////////////////////////
   ////////////////////////////////////////////
   // Pass along result of load for one cycle
   // Pass along result of load for one cycle
   ////////////////////////////////////////////
   ////////////////////////////////////////////
   assign     ld_g = lsu_exu_dfill_vld_g | ecl_byp_ldxa_g;
   assign     ld_g = lsu_exu_dfill_vld_g | ecl_byp_ldxa_g;
   dff dfill_vld_dff (.din(ld_g), .clk(clk), .q(ld_g2),
   dff_s dfill_vld_dff (.din(ld_g), .clk(clk), .q(ld_g2),
                      .se(se), .si(), .so());
                      .se(se), `SIMPLY_RISC_SCANIN, .so());
   assign     kill_ld_g2 = flush_w1 & (dfill_tid_g2[1:0] == tid_w1[1:0]);
   assign     kill_ld_g2 = flush_w1 & (dfill_tid_g2[1:0] == tid_w1[1:0]);
   assign     dfill_vld_g2 = ld_g2 & ~kill_ld_g2 & ~lsu_exu_ldst_miss_g2;
   assign     dfill_vld_g2 = ld_g2 & ~kill_ld_g2 & ~lsu_exu_ldst_miss_g2;
   dff #(2) dfill_tid_dff(.din(ld_tid_g[1:0]), .clk(clk), .q(dfill_tid_g2[1:0]),
   dff_s #(2) dfill_tid_dff(.din(ld_tid_g[1:0]), .clk(clk), .q(dfill_tid_g2[1:0]),
                          .se(se), .si(), .so());
                          .se(se), `SIMPLY_RISC_SCANIN, .so());
   dff #(5) dfill_rd_dff(.din(ld_rd_g[4:0]), .clk(clk), .q(dfill_rd_g2[4:0]),
   dff_s #(5) dfill_rd_dff(.din(ld_rd_g[4:0]), .clk(clk), .q(dfill_rd_g2[4:0]),
                         .se(se), .si(), .so());
                         .se(se), `SIMPLY_RISC_SCANIN, .so());
 
 
   ///////////////////////////////////////////
   ///////////////////////////////////////////
   // Help with bypassing of long latency ops
   // Help with bypassing of long latency ops
   ///////////////////////////////////////////
   ///////////////////////////////////////////
   assign       wb_byplog_rd_w2[4:0] = rd_w2[4:0];
   assign       wb_byplog_rd_w2[4:0] = rd_w2[4:0];
Line 267... Line 272...
   assign ecl_irf_wen_g = (sehold)? ecl_irf_wen_w2:
   assign ecl_irf_wen_g = (sehold)? ecl_irf_wen_w2:
                                   (ecl_byp_sel_load_g & dfill_vld_g2 |
                                   (ecl_byp_sel_load_g & dfill_vld_g2 |
                                    (ecl_byp_sel_restore_g & restore_wen) |
                                    (ecl_byp_sel_restore_g & restore_wen) |
                                    (ecl_byp_sel_muldiv_g & divcntl_wb_req_g));
                                    (ecl_byp_sel_muldiv_g & divcntl_wb_req_g));
 
 
   dff wen_w2_dff(.din(ecl_irf_wen_g), .clk(clk), .q(ecl_irf_wen_w2),
   dff_s wen_w2_dff(.din(ecl_irf_wen_g), .clk(clk), .q(ecl_irf_wen_w2),
                  .se(se), .si(), .so());
                  .se(se), `SIMPLY_RISC_SCANIN, .so());
   mux4ds #(5) rd_g_mux(.dout(ecl_irf_rd_g[4:0]), .in0(dfill_rd_g2[4:0]),
   mux4ds #(5) rd_g_mux(.dout(ecl_irf_rd_g[4:0]), .in0(dfill_rd_g2[4:0]),
                       .in1(mdqctl_wb_divrd_g[4:0]),
                       .in1(mdqctl_wb_divrd_g[4:0]),
                       .in2(mdqctl_wb_mulrd_g[4:0]),
                       .in2(mdqctl_wb_mulrd_g[4:0]),
                        .in3(restore_rd[4:0]),
                        .in3(restore_rd[4:0]),
                       .sel0(ecl_byp_sel_load_g),
                       .sel0(ecl_byp_sel_load_g),
Line 290... Line 295...
   mux2ds setcc_g_mux(.dout(setcc_g),
   mux2ds setcc_g_mux(.dout(setcc_g),
                         .in0(mdqctl_wb_mulsetcc_g),
                         .in0(mdqctl_wb_mulsetcc_g),
                         .in1(mdqctl_wb_divsetcc_g),
                         .in1(mdqctl_wb_divsetcc_g),
                         .sel0(~ecl_div_sel_div),
                         .sel0(~ecl_div_sel_div),
                         .sel1(ecl_div_sel_div));
                         .sel1(ecl_div_sel_div));
   dff #(2) dff_thr_g2w2(.din(ecl_irf_tid_g[1:0]), .clk(clk), .q(tid_w2[1:0]), .se(se),
   dff_s #(2) dff_thr_g2w2(.din(ecl_irf_tid_g[1:0]), .clk(clk), .q(tid_w2[1:0]), .se(se),
                      .si(), .so());
                      `SIMPLY_RISC_SCANIN, .so());
   dff #(5) dff_rd_g2w2(.din(ecl_irf_rd_g[4:0]), .clk(clk), .q(rd_w2[4:0]), .se(se),
   dff_s #(5) dff_rd_g2w2(.din(ecl_irf_rd_g[4:0]), .clk(clk), .q(rd_w2[4:0]), .se(se),
                     .si(), .so());
                     `SIMPLY_RISC_SCANIN, .so());
   // needs wen to setcc
   // needs wen to setcc
   assign wb_ccr_setcc_g = wb_divcntl_ack_g & divcntl_wb_req_g & setcc_g;
   assign wb_ccr_setcc_g = wb_divcntl_ack_g & divcntl_wb_req_g & setcc_g;
 
 
 
 
   ///////////////////
   ///////////////////
Line 310... Line 315...
   assign      ecl_byp_sel_pipe_m = (wb_m | wrsr_m) & ~ecl_byp_sel_ecc_m;
   assign      ecl_byp_sel_pipe_m = (wb_m | wrsr_m) & ~ecl_byp_sel_ecc_m;
   assign      ecl_byp_sel_restore_m = ~(wb_m | wrsr_m | ld_g2 | ecl_byp_sel_ecc_m);
   assign      ecl_byp_sel_restore_m = ~(wb_m | wrsr_m | ld_g2 | ecl_byp_sel_ecc_m);
   assign      wen_no_inst_vld_m = (sehold)? ecl_irf_wen_w:
   assign      wen_no_inst_vld_m = (sehold)? ecl_irf_wen_w:
                                             ((dfill_vld_g2 & ecl_byp_sel_load_m) |
                                             ((dfill_vld_g2 & ecl_byp_sel_load_m) |
                                              (ecl_byp_sel_restore_m & restore_wen));
                                              (ecl_byp_sel_restore_m & restore_wen));
   dff dff_lsu_wen_m2w(.din(wen_no_inst_vld_m), .clk(clk), .q(wen_no_inst_vld_w), .se(se), .si(),
   dff_s dff_lsu_wen_m2w(.din(wen_no_inst_vld_m), .clk(clk), .q(wen_no_inst_vld_w), .se(se), `SIMPLY_RISC_SCANIN,
                       .so());
                       .so());
   // ecc_wen must be kept separate because it needs to check inst_vld but not flush
   // ecc_wen must be kept separate because it needs to check inst_vld but not flush
   assign      inst_vld_noflush_wen_m = ecl_byp_sel_ecc_m & ~sehold;
   assign      inst_vld_noflush_wen_m = ecl_byp_sel_ecc_m & ~sehold;
   dff ecc_wen_m2w(.din(inst_vld_noflush_wen_m), .clk(clk), .q(inst_vld_noflush_wen_w), .se(se), .si(), .so());
   dff_s ecc_wen_m2w(.din(inst_vld_noflush_wen_m), .clk(clk), .q(inst_vld_noflush_wen_w), .se(se), `SIMPLY_RISC_SCANIN, .so());
 
 
   assign ecl_irf_tid_m[1:0] = ((ecl_byp_sel_load_m)? dfill_tid_g2[1:0]:
   assign ecl_irf_tid_m[1:0] = ((ecl_byp_sel_load_m)? dfill_tid_g2[1:0]:
                                (ecl_byp_sel_restore_m)? restore_tid[1:0]:
                                (ecl_byp_sel_restore_m)? restore_tid[1:0]:
                                tid_m[1:0]);
                                tid_m[1:0]);
 
 
Line 333... Line 338...
                      .sel3(ecl_byp_sel_restore_m));
                      .sel3(ecl_byp_sel_restore_m));
   assign wen_w_inst_vld = valid_w | inst_vld_noflush_wen_w;
   assign wen_w_inst_vld = valid_w | inst_vld_noflush_wen_w;
   assign ecl_irf_wen_w = ifu_exu_inst_vld_w & wen_w_inst_vld | wen_no_inst_vld_w;
   assign ecl_irf_wen_w = ifu_exu_inst_vld_w & wen_w_inst_vld | wen_no_inst_vld_w;
 
 
   // bypass valid logic and flops
   // bypass valid logic and flops
   dff dff_wb_d2e(.din(ifu_exu_wen_d), .clk(clk), .q(wb_e), .se(se),
   dff_s dff_wb_d2e(.din(ifu_exu_wen_d), .clk(clk), .q(wb_e), .se(se),
                  .si(), .so());
                  `SIMPLY_RISC_SCANIN, .so());
   dff dff_wb_e2m(.din(valid_e), .clk(clk), .q(wb_m), .se(se),
   dff_s dff_wb_e2m(.din(valid_e), .clk(clk), .q(wb_m), .se(se),
                  .si(), .so());
                  `SIMPLY_RISC_SCANIN, .so());
   dffr dff_wb_m2w(.din(valid_m), .clk(clk), .q(wb_w), .se(se),
   dffr_s dff_wb_m2w(.din(valid_m), .clk(clk), .q(wb_w), .se(se),
                  .si(), .so(), .rst(reset));
                  `SIMPLY_RISC_SCANIN, .so(), .rst(reset));
   assign  valid_e = wb_e & ~ifu_exu_kill_e & ~restore_e & ~wrsr_e;// restore doesn't finish on time
   assign  valid_e = wb_e & ~ifu_exu_kill_e & ~restore_e & ~wrsr_e;// restore doesn't finish on time
   assign  bypass_m = wb_m;// bypass doesn't need to check for traps or sehold
   assign  bypass_m = wb_m;// bypass doesn't need to check for traps or sehold
   assign  valid_m = bypass_m & ~rml_ecl_kill_m & ~sehold;// sehold turns off writes from this path
   assign  valid_m = bypass_m & ~rml_ecl_kill_m & ~sehold;// sehold turns off writes from this path
   assign  valid_w = (wb_w & ~early_flush_w & ~ifu_tlu_flush_w);// check inst_vld later
   assign  valid_w = (wb_w & ~early_flush_w & ~ifu_tlu_flush_w);// check inst_vld later
   // don't check flush for bypass
   // don't check flush for bypass
Line 397... Line 402...
   assign  ecl_rml_cleanwin_wen_w = sraddr_cleanwin_w & wrsr_w;
   assign  ecl_rml_cleanwin_wen_w = sraddr_cleanwin_w & wrsr_w;
   assign  ecl_rml_otherwin_wen_w = sraddr_otherwin_w & wrsr_w;
   assign  ecl_rml_otherwin_wen_w = sraddr_otherwin_w & wrsr_w;
   assign  ecl_rml_wstate_wen_w = sraddr_wstate_w & wrsr_w;
   assign  ecl_rml_wstate_wen_w = sraddr_wstate_w & wrsr_w;
 
 
 
 
   dff dff_wrsr_d2e(.din(ifu_tlu_wsr_inst_d), .clk(clk), .q(wrsr_e), .se(se),
   dff_s dff_wrsr_d2e(.din(ifu_tlu_wsr_inst_d), .clk(clk), .q(wrsr_e), .se(se),
                   .si(), .so());
                   `SIMPLY_RISC_SCANIN, .so());
   assign  exu_ffu_wsr_inst_e = wrsr_e;
   assign  exu_ffu_wsr_inst_e = wrsr_e;
   dff dff_wrsr_e2m(.din(wrsr_e), .clk(clk), .q(wrsr_m), .se(se),
   dff_s dff_wrsr_e2m(.din(wrsr_e), .clk(clk), .q(wrsr_m), .se(se),
                   .si(), .so());
                   `SIMPLY_RISC_SCANIN, .so());
   dff dff_wrsr_m2w(.din(wrsr_m), .clk(clk), .q(wrsr_w), .se(se),
   dff_s dff_wrsr_m2w(.din(wrsr_m), .clk(clk), .q(wrsr_w), .se(se),
                   .si(), .so());
                   `SIMPLY_RISC_SCANIN, .so());
   dff #(7) dff_sraddr_d2e(.din(ifu_tlu_sraddr_d[6:0]), .clk(clk), .q(sraddr_e[6:0]), .se(se),
   dff_s #(7) dff_sraddr_d2e(.din(ifu_tlu_sraddr_d[6:0]), .clk(clk), .q(sraddr_e[6:0]), .se(se),
                       .si(), .so());
                       `SIMPLY_RISC_SCANIN, .so());
   dff #(7) dff_sraddr_e2m(.din(sraddr_e[6:0]), .clk(clk), .q(sraddr_m[6:0]), .se(se),
   dff_s #(7) dff_sraddr_e2m(.din(sraddr_e[6:0]), .clk(clk), .q(sraddr_m[6:0]), .se(se),
                       .si(), .so());
                       `SIMPLY_RISC_SCANIN, .so());
   dff #(7) dff_sraddr_m2w(.din(sraddr_m[6:0]), .clk(clk), .q(sraddr_w[6:0]), .se(se),
   dff_s #(7) dff_sraddr_m2w(.din(sraddr_m[6:0]), .clk(clk), .q(sraddr_w[6:0]), .se(se),
                       .si(), .so());
                       `SIMPLY_RISC_SCANIN, .so());
   dff dff_yreg_wen_w2w1(.din(yreg_wen_w), .clk(clk), .q(yreg_wen_w1), .se(se), .si(), .so());
   dff_s dff_yreg_wen_w2w1(.din(yreg_wen_w), .clk(clk), .q(yreg_wen_w1), .se(se), `SIMPLY_RISC_SCANIN, .so());
 
 
   // Logic for rdpr/rdsr
   // Logic for rdpr/rdsr
   // This mux takes advantage of the fact that these 4 encodings don't overlap
   // This mux takes advantage of the fact that these 4 encodings don't overlap
   assign sel_cleanwin_d = ~ifu_tlu_sraddr_d[1] & ~ifu_tlu_sraddr_d[0];
   assign sel_cleanwin_d = ~ifu_tlu_sraddr_d[1] & ~ifu_tlu_sraddr_d[0];
   assign sel_otherwin_d = ~ifu_tlu_sraddr_d[1] & ifu_tlu_sraddr_d[0];
   assign sel_otherwin_d = ~ifu_tlu_sraddr_d[1] & ifu_tlu_sraddr_d[0];
Line 442... Line 447...
                       .sel1(sel_cwp_d),
                       .sel1(sel_cwp_d),
                       .sel2(sel_wstate_d),
                       .sel2(sel_wstate_d),
                       .sel3(sel_rdpr_mux1_d));
                       .sel3(sel_rdpr_mux1_d));
 
 
   assign read_yreg_e = ~(sraddr_e[3] | sraddr_e[1]);
   assign read_yreg_e = ~(sraddr_e[3] | sraddr_e[1]);
   dff #(8) rdpr_dff(.din(rdpr_mux2_out[7:0]), .clk(clk), .q(ecl_byp_eclpr_e[7:0]),
   dff_s #(8) rdpr_dff(.din(rdpr_mux2_out[7:0]), .clk(clk), .q(ecl_byp_eclpr_e[7:0]),
                   .se(se), .si(), .so());
                   .se(se), `SIMPLY_RISC_SCANIN, .so());
 
 
 
 
   ///////////////////////////////
   ///////////////////////////////
   // YREG write enable logic
   // YREG write enable logic
   ///////////////////////////////
   ///////////////////////////////
Line 518... Line 523...
   assign restore_done[3:0] = restore_thr[3:0] & {4{restore_picked & restore_request}};
   assign restore_done[3:0] = restore_thr[3:0] & {4{restore_picked & restore_request}};
   // restore request waits for kills in the w stage.  they
   // restore request waits for kills in the w stage.  they
   // won't start until after the flop
   // won't start until after the flop
   assign restore_ready_next = (vld_restore_w  | restore_ready) & ~restore_picked;
   assign restore_ready_next = (vld_restore_w  | restore_ready) & ~restore_picked;
 
 
   dffe #(2) restore_tid_dff(.din(tid_m[1:0]), .clk(clk), .q(restore_tid[1:0]),
   dffe_s #(2) restore_tid_dff(.din(tid_m[1:0]), .clk(clk), .q(restore_tid[1:0]),
                             .se(se), .si(), .so(), .en(restore_m));
                             .se(se), `SIMPLY_RISC_SCANIN, .so(), .en(restore_m));
   dffe #(5) restore_rd_dff(.din(rd_m[4:0]), .clk(clk), .q(restore_rd[4:0]),
   dffe_s #(5) restore_rd_dff(.din(rd_m[4:0]), .clk(clk), .q(restore_rd[4:0]),
                            .se(se), .si(), .so(), .en(restore_m));
                            .se(se), `SIMPLY_RISC_SCANIN, .so(), .en(restore_m));
   dff return_d2e(.din(ifu_exu_return_d), .clk(clk), .q(return_e),
   dff_s return_d2e(.din(ifu_exu_return_d), .clk(clk), .q(return_e),
                   .se(se), .si(), .so());
                   .se(se), `SIMPLY_RISC_SCANIN, .so());
   dff restore_e2m(.din(vld_restore_e), .clk(clk), .q(restore_m),
   dff_s restore_e2m(.din(vld_restore_e), .clk(clk), .q(restore_m),
                   .se(se), .si(), .so());
                   .se(se), `SIMPLY_RISC_SCANIN, .so());
   dff restore_m2w(.din(restore_m), .clk(clk), .q(restore_w),
   dff_s restore_m2w(.din(restore_m), .clk(clk), .q(restore_w),
                   .se(se), .si(), .so());
                   .se(se), `SIMPLY_RISC_SCANIN, .so());
   dff restore_ready_dff(.din(restore_ready_next), .q(restore_ready),
   dff_s restore_ready_dff(.din(restore_ready_next), .q(restore_ready),
                         .clk(clk), .se(se), .so(), .si());
                         .clk(clk), .se(se), .so(), `SIMPLY_RISC_SCANIN);
 
 
   //////////////////////////////////////////////////////////
   //////////////////////////////////////////////////////////
   // Completion logic for non integer-pipeline operations
   // Completion logic for non integer-pipeline operations
   //////////////////////////////////////////////////////////
   //////////////////////////////////////////////////////////
   // short_longops must check inst_vld_e to protect against invalid completion signal
   // short_longops must check inst_vld_e to protect against invalid completion signal
   assign short_longop_done_e = (rml_ecl_rmlop_done_e | (restore_e & ~wb_e & ~return_e)) &
   assign short_longop_done_e = (rml_ecl_rmlop_done_e | (restore_e & ~wb_e & ~return_e)) &
                                  ifu_exu_inst_vld_e & ~ifu_exu_kill_e;
                                  ifu_exu_inst_vld_e & ~ifu_exu_kill_e;
   dff longop_done_e2m (.din(short_longop_done_e), .clk(clk), .q(short_longop_done_m), .se(se), .si(), .so());
   dff_s longop_done_e2m (.din(short_longop_done_e), .clk(clk), .q(short_longop_done_m), .se(se), `SIMPLY_RISC_SCANIN, .so());
   assign short_longop_done[3:0] = thr_m[3:0] & {4{short_longop_done_m}};
   assign short_longop_done[3:0] = thr_m[3:0] & {4{short_longop_done_m}};
 
 
   assign ecl_longop_done_nokill_m[3:0] = (muldiv_done_g[3:0] | restore_done[3:0] | short_longop_done[3:0] |
   assign ecl_longop_done_nokill_m[3:0] = (muldiv_done_g[3:0] | restore_done[3:0] | short_longop_done[3:0] |
                                           rml_ecl_swap_done[3:0]);
                                           rml_ecl_swap_done[3:0]);
   assign ecl_longop_done_kill_m[3:0] = (muldiv_done_g[3:0] | restore_done[3:0] | rml_ecl_swap_done[3:0]);
   assign ecl_longop_done_kill_m[3:0] = (muldiv_done_g[3:0] | restore_done[3:0] | rml_ecl_swap_done[3:0]);

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.