diff options
Diffstat (limited to 'sources/hdl/verilog')
| -rw-r--r-- | sources/hdl/verilog/ddr_pipeline.v | 83 | ||||
| -rw-r--r-- | sources/hdl/verilog/decode_stage.v | 18 | ||||
| -rw-r--r-- | sources/hdl/verilog/dll_toggler.v | 34 | ||||
| -rw-r--r-- | sources/hdl/verilog/execute_stage.v | 38 | ||||
| -rw-r--r-- | sources/hdl/verilog/frontend.v | 24 | ||||
| -rw-r--r-- | sources/hdl/verilog/maintenance_controller.v | 12 | ||||
| -rw-r--r-- | sources/hdl/verilog/readback_engine.v | 31 | ||||
| -rw-r--r-- | sources/hdl/verilog/softmc_pipeline.v | 38 |
8 files changed, 188 insertions, 90 deletions
diff --git a/sources/hdl/verilog/ddr_pipeline.v b/sources/hdl/verilog/ddr_pipeline.v index f8ae5aa..3fea5bc 100644 --- a/sources/hdl/verilog/ddr_pipeline.v +++ b/sources/hdl/verilog/ddr_pipeline.v @@ -12,23 +12,25 @@ module ddr_pipeline( input [`DDR_UOP_WIDTH*4-1:0] ddr_uop, // ddr_pipeline <-> outer DDRX IP interface - output [3:0] ddr_write, - output [3:0] ddr_read, - output [3:0] ddr_pre, - output [3:0] ddr_act, - output [3:0] ddr_ref, - output [3:0] ddr_zq, - output [3:0] ddr_nop, - output [3:0] ddr_sre, - output [3:0] ddr_srx, - output [3:0] ddr_ap, - output [3:0] ddr_pall, - output [3:0] ddr_half_bl, - output [4*`BG_WIDTH-1:0] ddr_bg, - output [4*`BANK_WIDTH-1:0] ddr_bank, - output [4*`COL_WIDTH-1:0] ddr_col, - output [4*`ROW_WIDTH-1:0] ddr_row, - output [511:0] ddr_wdata, + output [3:0] ddr_write, + output [3:0] ddr_read, + output [3:0] ddr_pre, + output [3:0] ddr_act, + output [3:0] ddr_ref, + output [3:0] ddr_zq, + output [3:0] ddr_nop, + output [3:0] ddr_sre, + output [3:0] ddr_srx, + output [3:0] ddr_ap, + output [3:0] ddr_pall, + output [3:0] ddr_half_bl, + output [3:0] ddr_rank, + output [4*`HBM_CH_WIDTH-1:0] hbm_ch, + output [4*`BG_WIDTH-1:0] ddr_bg, + output [4*`BANK_WIDTH-1:0] ddr_bank, + output [4*`COL_WIDTH-1:0] ddr_col, + output [4*`ROW_WIDTH-1:0] ddr_row, + output [511:0] ddr_wdata, // ddr_pipeline <-> regfile interface input [511:0] wide_reg, @@ -59,23 +61,25 @@ module ddr_pipeline( reg [7:0] s2_update_en; // which registers will we update reg [8*32-1:0] s2_update_val; - reg [3:0] ddr_write_ns, ddr_write_r; - reg [3:0] ddr_read_ns, ddr_read_r; - reg [3:0] ddr_pre_ns, ddr_pre_r; - reg [3:0] ddr_act_ns, ddr_act_r; - reg [3:0] ddr_ref_ns, ddr_ref_r; - reg [3:0] ddr_sre_ns, ddr_sre_r; - reg [3:0] ddr_srx_ns, ddr_srx_r; - reg [3:0] ddr_zq_ns, ddr_zq_r; - reg [3:0] ddr_nop_ns, ddr_nop_r; - reg [3:0] ddr_ap_ns, ddr_ap_r; - reg [3:0] ddr_pall_ns, ddr_pall_r; - reg [3:0] ddr_half_bl_ns, ddr_half_bl_r; - reg [4*`BG_WIDTH-1:0] ddr_bg_ns, ddr_bg_r; - reg [4*`BANK_WIDTH-1:0] ddr_bank_ns, ddr_bank_r; - reg [4*`COL_WIDTH-1:0] ddr_col_ns, ddr_col_r; - reg [4*`ROW_WIDTH-1:0] ddr_row_ns, ddr_row_r; - reg [511:0] ddr_data_r; + reg [3:0] ddr_write_ns, ddr_write_r; + reg [3:0] ddr_read_ns, ddr_read_r; + reg [3:0] ddr_pre_ns, ddr_pre_r; + reg [3:0] ddr_act_ns, ddr_act_r; + reg [3:0] ddr_ref_ns, ddr_ref_r; + reg [3:0] ddr_sre_ns, ddr_sre_r; + reg [3:0] ddr_srx_ns, ddr_srx_r; + reg [3:0] ddr_zq_ns, ddr_zq_r; + reg [3:0] ddr_nop_ns, ddr_nop_r; + reg [3:0] ddr_ap_ns, ddr_ap_r; + reg [3:0] ddr_pall_ns, ddr_pall_r; + reg [3:0] ddr_half_bl_ns, ddr_half_bl_r; + reg [4*`HBM_CH_WIDTH-1:0] hbm_ch_ns, hbm_ch_r; + reg [3:0] ddr_rank_ns, ddr_rank_r; + reg [4*`BG_WIDTH-1:0] ddr_bg_ns, ddr_bg_r; + reg [4*`BANK_WIDTH-1:0] ddr_bank_ns, ddr_bank_r; + reg [4*`COL_WIDTH-1:0] ddr_col_ns, ddr_col_r; + reg [4*`ROW_WIDTH-1:0] ddr_row_ns, ddr_row_r; + reg [511:0] ddr_data_r; assign update_vals = s2_update_val; assign update_en = s2_update_en; @@ -95,6 +99,8 @@ module ddr_pipeline( assign ddr_ap = ddr_ap_r; assign ddr_pall = ddr_pall_r; assign ddr_half_bl = ddr_half_bl_r; + assign ddr_rank = ddr_rank_r; + assign hbm_ch = hbm_ch_r; assign ddr_bg = ddr_bg_r; assign ddr_bank = ddr_bank_r; assign ddr_col = ddr_col_r; @@ -131,8 +137,11 @@ module ddr_pipeline( ddr_sre_ns[i] = s2_uop[i][`IS_SRE]; ddr_srx_ns[i] = s2_uop[i][`IS_SRX]; ddr_ap_ns[i] = s2_uop[i][`DO_AP] & (s2_uop[i][`IS_WRITE] | s2_uop[i][`IS_READ]); + ddr_rank_ns[i] = s2_uop[i][`IS_RANK]; ddr_half_bl_ns[i] = s2_uop[i][`IS_BL4] & (s2_uop[i][`IS_WRITE] | s2_uop[i][`IS_READ]); ddr_nop_ns[i] = s2_valid ? s2_uop[i][`IS_NOP] : {4{`HIGH}}; + hbm_ch_ns[i*`HBM_CH_WIDTH +: `HBM_CH_WIDTH] + = s2_uop[i][`HBM_CHANNEL +: `HBM_CH_WIDTH]; // stage 2 address calculation ddr_row_ns[i*`ROW_WIDTH +: `ROW_WIDTH] = reg_vals[i*64+32 +: `ROW_WIDTH]; @@ -177,6 +186,8 @@ module ddr_pipeline( ddr_nop_r <= {4{`HIGH}}; ddr_ap_r <= {4{`LOW}}; ddr_half_bl_r <= {4{`LOW}}; + ddr_rank_r <= {4{`LOW}}; + hbm_ch_r <= {4*`HBM_CH_WIDTH{`LOW}}; end else begin reg_ids_r <= reg_ids_ns; @@ -194,7 +205,9 @@ module ddr_pipeline( ddr_nop_r <= ddr_nop_ns; ddr_ap_r <= ddr_ap_ns; ddr_pall_r <= ddr_pall_ns; - ddr_half_bl_r <= ddr_half_bl_ns; + ddr_half_bl_r <= {4{`LOW}}; // deprecated + ddr_rank_r <= ddr_rank_ns; + hbm_ch_r <= hbm_ch_ns; ddr_bg_r <= ddr_bg_ns; ddr_bank_r <= ddr_bank_ns; ddr_col_r <= ddr_col_ns; diff --git a/sources/hdl/verilog/decode_stage.v b/sources/hdl/verilog/decode_stage.v index 7f40cba..754a2d9 100644 --- a/sources/hdl/verilog/decode_stage.v +++ b/sources/hdl/verilog/decode_stage.v @@ -77,6 +77,7 @@ module decode_stage( ddr_uop_ns[i][`BAR+:4] = ddr_insts[i][`DEC_BAR+:4]; ddr_uop_ns[i][`DO_AP] = ddr_insts[i][`DEC_AP]; ddr_uop_ns[i][`IS_BL4] = ddr_insts[i][`DEC_BL4]; + ddr_uop_ns[i][`IS_RANK] = ddr_insts[i][`DEC_RANK]; end `READ: begin ddr_uop_ns[i][`IS_READ] = `HIGH; @@ -86,12 +87,14 @@ module decode_stage( ddr_uop_ns[i][`BAR+:4] = ddr_insts[i][`DEC_BAR+:4]; ddr_uop_ns[i][`DO_AP] = ddr_insts[i][`DEC_AP]; ddr_uop_ns[i][`IS_BL4] = ddr_insts[i][`DEC_BL4]; + ddr_uop_ns[i][`IS_RANK] = ddr_insts[i][`DEC_RANK]; end `PRE: begin ddr_uop_ns[i][`IS_PRE] = `HIGH; ddr_uop_ns[i][`PRE_ALL] = ddr_insts[i][`DEC_PRE_ALL]; ddr_uop_ns[i][`INC_BAR] = ddr_insts[i][`DEC_INC_BAR]; ddr_uop_ns[i][`BAR+:4] = ddr_insts[i][`DEC_BAR+:4]; + ddr_uop_ns[i][`IS_RANK] = ddr_insts[i][`DEC_RANK]; end `ACT: begin ddr_uop_ns[i][`IS_ACT] = `HIGH; @@ -99,15 +102,30 @@ module decode_stage( ddr_uop_ns[i][`INC_BAR] = ddr_insts[i][`DEC_INC_BAR]; ddr_uop_ns[i][`RAR+:4] = ddr_insts[i][`DEC_RAR+:4]; ddr_uop_ns[i][`BAR+:4] = ddr_insts[i][`DEC_BAR+:4]; + ddr_uop_ns[i][`IS_RANK] = ddr_insts[i][`DEC_RANK]; end +`ifndef HBM_BENDER `ZQ: begin ddr_uop_ns[i][`IS_ZQ] = `HIGH; + ddr_uop_ns[i][`IS_RANK] = ddr_insts[i][`DEC_RANK]; end +`else + `SEL_CH: begin + // this is redundant and needs fixing + // we use ZQ to select channels in the HBM version + ddr_uop_ns[i][`IS_ZQ] = `HIGH; + ddr_uop_ns[i][`IS_RANK] = ddr_insts[i][`DEC_RANK]; + ddr_uop_ns[i][`HBM_CHANNEL +: `HBM_CH_WIDTH] = ddr_insts[i][`DEC_SEL_CH +: `HBM_CH_WIDTH]; + ddr_uop_ns[i][`IS_SEL_CH] = `HIGH; + end +`endif `REF: begin ddr_uop_ns[i][`IS_REF] = `HIGH; + ddr_uop_ns[i][`IS_RANK] = ddr_insts[i][`DEC_RANK]; end `NOP: begin ddr_uop_ns[i][`IS_NOP] = `HIGH; + ddr_uop_ns[i][`IS_RANK] = ddr_insts[i][`DEC_RANK]; end endcase end diff --git a/sources/hdl/verilog/dll_toggler.v b/sources/hdl/verilog/dll_toggler.v index a6cb5bf..9d51679 100644 --- a/sources/hdl/verilog/dll_toggler.v +++ b/sources/hdl/verilog/dll_toggler.v @@ -1,5 +1,5 @@ `include "parameters.vh" - +`define CKE_WIDTH 2 module dll_toggler #(parameter CKE_WIDTH = 1, RANK_WIDTH = 1, DQ_WIDTH = 64, DRAM_CMD_SLOTS = 4, DATA_BUF_ADDR_WIDTH = 5, DBUF_WIDTH = 4, DQ_BURST = 8) @@ -12,7 +12,7 @@ module dll_toggler #(parameter CKE_WIDTH = 1, RANK_WIDTH = 1, DQ_WIDTH = 64, DRA // ---------- DDR4 Signals ---------- output [7:0] mc_ACT_n, // DRAM ACT_n command signal for four DRAM clock cycles. - output [`ADDR_WIDTH*8-1:0] mc_ADR, // DRAM address. There are 8 bits in the fabric interface for each address bit on the DRAM bus. + output [17*8-1:0] mc_ADR, // DRAM address. There are 8 bits in the fabric interface for each address bit on the DRAM bus. output [`BANK_WIDTH*8-1:0] mc_BA, // DRAM bank address. 8 bits for each DRAM bank address. output [`BG_WIDTH*8-1:0] mc_BG, // DRAM bank group address. output [`CS_WIDTH*8-1:0] mc_CS_n, // DRAM CS_n @@ -25,7 +25,7 @@ module dll_toggler #(parameter CKE_WIDTH = 1, RANK_WIDTH = 1, DQ_WIDTH = 64, DRA wire [13:0] MR1_CONF = 14'b00001100000000; - reg [`ADDR_WIDTH*8-1:0] ADR_ns, ADR_r; + reg [17*8-1:0] ADR_ns, ADR_r; reg [`BANK_WIDTH*8-1:0] BA_ns, BA_r; reg [`BG_WIDTH*8-1:0] BG_ns, BG_r; reg [`CS_WIDTH*8-1:0] CS_n_ns, CS_n_r; @@ -83,7 +83,7 @@ module dll_toggler #(parameter CKE_WIDTH = 1, RANK_WIDTH = 1, DQ_WIDTH = 64, DRA always @* begin // Set bank and bank group signals dllt_done = `LOW; - ADR_ns = {`ADDR_WIDTH*8{`HIGH}}; + ADR_ns = {17*8{`HIGH}}; BG_ns = {`BG_WIDTH*8{`LOW}}; BA_ns = {`BANK_WIDTH*8{`LOW}}; CS_n_ns = {`CS_WIDTH*8{`HIGH}}; // by default we don't issue any commands @@ -95,9 +95,9 @@ module dll_toggler #(parameter CKE_WIDTH = 1, RANK_WIDTH = 1, DQ_WIDTH = 64, DRA IDLE_S: begin if(toggle_valid) begin CS_n_ns[1:0] = {2*`CS_WIDTH{`LOW}}; - ADR_ns[`ADDR_WIDTH*8-3*8 +: 2] = {2{`LOW}}; // WE - ADR_ns[`ADDR_WIDTH*8-2*8 +: 2] = {2{`HIGH}}; // ~CAS - ADR_ns[`ADDR_WIDTH*8-8 +: 2] = {2{`LOW}}; // RAS + ADR_ns[17*8-3*8 +: 2] = {2{`LOW}}; // WE + ADR_ns[17*8-2*8 +: 2] = {2{`HIGH}}; // ~CAS + ADR_ns[17*8-8 +: 2] = {2{`LOW}}; // RAS ADR_ns[10*8 +: 2] = {2{`HIGH}}; // Pre ALL wait_ns = T_PRECHARGE; state_ns = IDLE_WAIT_S; @@ -111,9 +111,9 @@ module dll_toggler #(parameter CKE_WIDTH = 1, RANK_WIDTH = 1, DQ_WIDTH = 64, DRA end SET_MR_1_S: begin CS_n_ns[1:0] = {2*`CS_WIDTH{`LOW}}; - ADR_ns[`ADDR_WIDTH*8-3*8 +: 2] = {2{`LOW}}; // WE - ADR_ns[`ADDR_WIDTH*8-2*8 +: 2] = {2{`LOW}}; // CAS - ADR_ns[`ADDR_WIDTH*8-8 +: 2] = {2{`LOW}}; // RAS + ADR_ns[17*8-3*8 +: 2] = {2{`LOW}}; // WE + ADR_ns[17*8-2*8 +: 2] = {2{`LOW}}; // CAS + ADR_ns[17*8-8 +: 2] = {2{`LOW}}; // RAS for(adr_bit_i = 0 ; adr_bit_i < 14 ; adr_bit_i = adr_bit_i + 1) begin ADR_ns[adr_bit_i*8 +: 2] = {2{MR1_CONF[adr_bit_i]}}; @@ -133,9 +133,9 @@ module dll_toggler #(parameter CKE_WIDTH = 1, RANK_WIDTH = 1, DQ_WIDTH = 64, DRA ENTER_SELF_REF_S: begin CKE_ns = `LOW; CS_n_ns[1:0] = {2*`CS_WIDTH{`LOW}}; - ADR_ns[`ADDR_WIDTH*8-3*8 +: 2] = {2{`HIGH}}; // ~WE - ADR_ns[`ADDR_WIDTH*8-2*8 +: 2] = {2{`LOW}}; // CAS - ADR_ns[`ADDR_WIDTH*8-8 +: 2] = {2{`LOW}}; // RAS + ADR_ns[17*8-3*8 +: 2] = {2{`HIGH}}; // ~WE + ADR_ns[17*8-2*8 +: 2] = {2{`LOW}}; // CAS + ADR_ns[17*8-8 +: 2] = {2{`LOW}}; // RAS state_ns = WAIT_ENTER_SELF_REF_S; wait_ns = T_CKSRE; end @@ -161,9 +161,9 @@ module dll_toggler #(parameter CKE_WIDTH = 1, RANK_WIDTH = 1, DQ_WIDTH = 64, DRA EXIT_SELF_REF_S: begin CKE_ns = {`CKE_WIDTH*8{`HIGH}}; CS_n_ns[7:0] = {8*`CS_WIDTH{`HIGH}}; - ADR_ns[`ADDR_WIDTH*8-3*8 +: 2] = {2{`HIGH}}; // ~WE - ADR_ns[`ADDR_WIDTH*8-2*8 +: 2] = {2{`HIGH}}; // CAS - ADR_ns[`ADDR_WIDTH*8-8 +: 2] = {2{`HIGH}}; // RAS + ADR_ns[17*8-3*8 +: 2] = {2{`HIGH}}; // ~WE + ADR_ns[17*8-2*8 +: 2] = {2{`HIGH}}; // CAS + ADR_ns[17*8-8 +: 2] = {2{`HIGH}}; // RAS state_ns = WAIT_EXIT_SELF_REF_S; wait_ns = T_XS; end @@ -186,7 +186,7 @@ module dll_toggler #(parameter CKE_WIDTH = 1, RANK_WIDTH = 1, DQ_WIDTH = 64, DRA wait_r <= `LOW; clk_sel_r <= `LOW; CKE_r <= {`CKE_WIDTH*8{`HIGH}}; - ADR_r = {`ADDR_WIDTH*8{`LOW}}; + ADR_r = {17*8{`LOW}}; BG_r = {`BG_WIDTH*8{`LOW}}; BA_r = {`BANK_WIDTH*8{`LOW}}; CS_n_r = {`CS_WIDTH*8{`HIGH}}; diff --git a/sources/hdl/verilog/execute_stage.v b/sources/hdl/verilog/execute_stage.v index 0b690f8..5ca8d38 100644 --- a/sources/hdl/verilog/execute_stage.v +++ b/sources/hdl/verilog/execute_stage.v @@ -18,23 +18,25 @@ module execute_stage( output [`IMEM_ADDR_WIDTH-1:0] br_target, // execute <-> outer DDRX IP interface - output [3:0] ddr_write, - output [3:0] ddr_read, - output [3:0] ddr_pre, - output [3:0] ddr_act, - output [3:0] ddr_ref, - output [3:0] ddr_sre, - output [3:0] ddr_srx, - output [3:0] ddr_zq, - output [3:0] ddr_nop, - output [3:0] ddr_ap, - output [3:0] ddr_pall, - output [3:0] ddr_half_bl, - output [4*`BG_WIDTH-1:0] ddr_bg, - output [4*`BANK_WIDTH-1:0] ddr_bank, - output [4*`COL_WIDTH-1:0] ddr_col, - output [4*`ROW_WIDTH-1:0] ddr_row, - output [511:0] ddr_wdata, + output [3:0] ddr_write, + output [3:0] ddr_read, + output [3:0] ddr_pre, + output [3:0] ddr_act, + output [3:0] ddr_ref, + output [3:0] ddr_sre, + output [3:0] ddr_srx, + output [3:0] ddr_zq, + output [3:0] ddr_nop, + output [3:0] ddr_ap, + output [3:0] ddr_pall, + output [3:0] ddr_half_bl, + output [3:0] ddr_rank, + output [4*`HBM_CH_WIDTH-1:0] hbm_ch, + output [4*`BG_WIDTH-1:0] ddr_bg, + output [4*`BANK_WIDTH-1:0] ddr_bank, + output [4*`COL_WIDTH-1:0] ddr_col, + output [4*`ROW_WIDTH-1:0] ddr_row, + output [511:0] ddr_wdata, // execute <-> reg file if output rf_wide_wen, @@ -86,6 +88,8 @@ module execute_stage( .ddr_ap(ddr_ap), .ddr_pall(ddr_pall), .ddr_half_bl(ddr_half_bl), + .hbm_ch(hbm_ch), + .ddr_rank(ddr_rank), .ddr_bg(ddr_bg), .ddr_bank(ddr_bank), .ddr_col(ddr_col), diff --git a/sources/hdl/verilog/frontend.v b/sources/hdl/verilog/frontend.v index 9225bd9..c1ce196 100644 --- a/sources/hdl/verilog/frontend.v +++ b/sources/hdl/verilog/frontend.v @@ -25,6 +25,10 @@ module frontend#(parameter SIM_MEM = "false")( output valid_out, output [`IMEM_ADDR_WIDTH-1:0] addr_out, output ready_in, + + `ifdef HBM_BENDER + output hbm_temp_rd, + `endif // frontend <-> xdma interface input [`XDMA_AXI_DATA_WIDTH-1:0] h2c_tdata_0, @@ -37,6 +41,7 @@ module frontend#(parameter SIM_MEM = "false")( output per_rd_init, output per_zq_init, output per_ref_init + ); reg[31:0] delay_fin; @@ -125,6 +130,10 @@ module frontend#(parameter SIM_MEM = "false")( reg [`IMEM_RD_LATENCY-1:0] valid_out_sr; reg [(`IMEM_RD_LATENCY * `IMEM_ADDR_WIDTH)-1:0] addr_out_sr; + reg hbm_temp_rd_ns, hbm_temp_rd_r; + + assign hbm_temp_rd = hbm_temp_rd_r; + assign user_rst = (|rst_ctr_r); // imem <-> xdma interface @@ -150,6 +159,9 @@ module frontend#(parameter SIM_MEM = "false")( always @* begin aref_en_valid = `LOW; aref_en = `LOW; + `ifdef HBM_BENDER + hbm_temp_rd_ns = `LOW; + `endif state_ns = state_r; xfer_ctr_ns = xfer_ctr_r; rst_ctr_ns = {5{`LOW}}; @@ -182,6 +194,12 @@ module frontend#(parameter SIM_MEM = "false")( aref_en = h2c_tdata_0[0]; state_ns = IDLE_S; end + `ifdef HBM_BENDER + else if(h2c_tdata_0[`INSTR_WIDTH+4]) begin // read HBM temp + hbm_temp_rd_ns = `HIGH; + state_ns = IDLE_S; + end + `endif else begin xfer_ctr_ns = xfer_ctr_r + 1; if(h2c_tlast_0) begin @@ -216,6 +234,9 @@ module frontend#(parameter SIM_MEM = "false")( rst_ctr_r <= rst_ctr_r - 1; else rst_ctr_r <= 0; + `ifdef HBM_BENDER + hbm_temp_rd_r <= 0; + `endif end else begin state_r <= state_ns; @@ -230,6 +251,9 @@ module frontend#(parameter SIM_MEM = "false")( valid_out_sr[`IMEM_RD_LATENCY-1:0] <= valid_out_sr >> 1; addr_out_sr[(`IMEM_RD_LATENCY-1)*`IMEM_ADDR_WIDTH-1:0] <= addr_out_sr >> `IMEM_ADDR_WIDTH; + `endif + `ifdef HBM_BENDER + hbm_temp_rd_r <= hbm_temp_rd_ns; `endif end end diff --git a/sources/hdl/verilog/maintenance_controller.v b/sources/hdl/verilog/maintenance_controller.v index 9354d17..169833a 100644 --- a/sources/hdl/verilog/maintenance_controller.v +++ b/sources/hdl/verilog/maintenance_controller.v @@ -172,8 +172,12 @@ module maintenance_controller#(parameter tCK = 1500)( wire periodic_rd_timer_one = maint_prescaler_tick_r_lcl && (periodic_rd_timer_r == ONE[0+:PERIODIC_RD_TIMER_WIDTH]); + `ifndef HBM_BENDER wire periodic_rd_request = ~rst && (/*((PERIODIC_RD_TIMER_DIV != 0) && ~dfi_init_complete) ||*/ (~per_rd_ack && (per_rd_request || periodic_rd_timer_one))); + `else + wire periodic_rd_request = 1'b0; + `endif always @(posedge clk) begin if(~init_calib_complete) @@ -221,8 +225,12 @@ module maintenance_controller#(parameter tCK = 1500)( always @(posedge clk) zq_request_r <= zq_request_ns; - always @(/*AS*/init_calib_complete or zq_request_r) - zq_request = init_calib_complete && zq_request_r; + always @(/*AS*/init_calib_complete or zq_request_r) + `ifndef HBM_BENDER + zq_request = init_calib_complete && zq_request_r; + `else + zq_request = 1'b0; + `endif end // zq_request_logic end endgenerate diff --git a/sources/hdl/verilog/readback_engine.v b/sources/hdl/verilog/readback_engine.v index 496d83e..b5313af 100644 --- a/sources/hdl/verilog/readback_engine.v +++ b/sources/hdl/verilog/readback_engine.v @@ -25,6 +25,12 @@ module readback_engine( // engine <-> regfile if input [511:0] ddr_wdata, // to compare read data against + `ifdef HBM_BENDER + input hbm_temp_rd, + input [6:0] hbm0_temp, + input [6:0] hbm1_temp, + `endif + // readback <-> XDMA if output [`XDMA_AXI_DATA_WIDTH-1:0] c2h_tdata_0, output c2h_tlast_0, @@ -39,6 +45,9 @@ module readback_engine( localparam DIFF_MODE = 1; reg mode_r, mode_ns; // Switch between diff count and read modes + // used to ignore the reads from both ranks after a periodic read + reg rd_flag_r, rd_flag_ns; + reg rd_valid_r; reg ignore_read_r, ignore_read_ns; reg ignore_flush_r, ignore_flush_ns; @@ -134,13 +143,21 @@ module readback_engine( wire rbf_empty, rbf_rd_valid, fifo_almost_full, fifo_valid; (*KEEP = "TRUE"*) wire rbf_full; (*KEEP = "TRUE"*) reg [19:0] dbg_rd_ctr; + + `ifdef HBM_BENDER + wire [15:0] hbm_temp_all = {1'b0, hbm1_temp, 1'b0, hbm0_temp}; + wire [511:0] rdback_din = mode_r == READ_MODE ? hbm_temp_rd ? hbm_temp_all : {rd_data[0+:128], rd_data[128+:128], rd_data[256+:128], rd_data[384+:128]} : {dsr_out[255:0],dsr_out[511:256]}; + `else + wire [511:0] rdback_din = mode_r == READ_MODE ? {rd_data[255:0],rd_data[511:256]} : {dsr_out[255:0],dsr_out[511:256]}; + `endif + rdback_fifo rbf( .full(rbf_full), .prog_full(fifo_almost_full), .empty(rbf_empty), - .wr_en(mode_r == READ_MODE ? rd_valid && ~ignore_read_r: dsr_valid), + .wr_en(mode_r == READ_MODE ? (rd_valid | hbm_temp_rd) && ~ignore_read_r: dsr_valid), // shuffle data because fifo outputs them on wrong order - .din(mode_r == READ_MODE ? {rd_data[255:0],rd_data[511:256]} : {dsr_out[255:0],dsr_out[511:256]}), + .din(rdback_din), .rd_en(c2h_tready_0), .dout(c2h_tdata_0), .valid(fifo_valid), @@ -159,12 +176,22 @@ module readback_engine( ignore_read_ns = ignore_read_r; ignore_flush_ns = ignore_flush_r; buffer_space_ns = buffer_space_r; + rd_flag_ns = rd_flag_r; if(per_rd_init || per_zq_init || per_ref_init) begin ignore_read_ns = per_rd_init; ignore_flush_ns = `HIGH; end + `ifdef DUAL_RANK_SELECT + if(rd_valid_r) begin + rd_flag_ns = ~rd_flag_ns; + if (~rd_flag_ns) begin + ignore_read_ns = `LOW; + end + end + `else if(rd_valid_r) ignore_read_ns = `LOW; + `endif proc_flush_ns = proc_flush_r; if(flush) begin if(ignore_flush_r) diff --git a/sources/hdl/verilog/softmc_pipeline.v b/sources/hdl/verilog/softmc_pipeline.v index 07c106e..43849f6 100644 --- a/sources/hdl/verilog/softmc_pipeline.v +++ b/sources/hdl/verilog/softmc_pipeline.v @@ -22,23 +22,25 @@ module softmc_pipeline( input ready_out, // ddr_pipeline <-> outer DDR module - output [3:0] ddr_write, - output [3:0] ddr_read, - output [3:0] ddr_pre, - output [3:0] ddr_act, - output [3:0] ddr_ref, - output [3:0] ddr_sre, - output [3:0] ddr_srx, - output [3:0] ddr_zq, - output [3:0] ddr_nop, - output [3:0] ddr_ap, - output [3:0] ddr_pall, - output [3:0] ddr_half_bl, - output [4*`BG_WIDTH-1:0] ddr_bg, - output [4*`BANK_WIDTH-1:0] ddr_bank, - output [4*`COL_WIDTH-1:0] ddr_col, - output [4*`ROW_WIDTH-1:0] ddr_row, - output [511:0] ddr_wdata + output [3:0] ddr_write, + output [3:0] ddr_read, + output [3:0] ddr_pre, + output [3:0] ddr_act, + output [3:0] ddr_ref, + output [3:0] ddr_sre, + output [3:0] ddr_srx, + output [3:0] ddr_zq, + output [3:0] ddr_nop, + output [3:0] ddr_ap, + output [3:0] ddr_pall, + output [3:0] ddr_half_bl, + output [3:0] ddr_rank, + output [4*`HBM_CH_WIDTH-1:0] hbm_ch, + output [4*`BG_WIDTH-1:0] ddr_bg, + output [4*`BANK_WIDTH-1:0] ddr_bank, + output [4*`COL_WIDTH-1:0] ddr_col, + output [4*`ROW_WIDTH-1:0] ddr_row, + output [511:0] ddr_wdata ); wire br_resolve; @@ -149,6 +151,8 @@ module softmc_pipeline( .ddr_ap(ddr_ap), .ddr_pall(ddr_pall), .ddr_half_bl(ddr_half_bl), + .hbm_ch(hbm_ch), + .ddr_rank(ddr_rank), .ddr_bg(ddr_bg), .ddr_bank(ddr_bank), .ddr_col(ddr_col), |
