aboutsummaryrefslogtreecommitdiffstats
path: root/sources/hdl
diff options
context:
space:
mode:
Diffstat (limited to 'sources/hdl')
-rw-r--r--sources/hdl/header_verilog/encoding.vh10
-rw-r--r--sources/hdl/header_verilog/parameters.vh3
-rw-r--r--sources/hdl/verilog/ddr_pipeline.v83
-rw-r--r--sources/hdl/verilog/decode_stage.v18
-rw-r--r--sources/hdl/verilog/dll_toggler.v34
-rw-r--r--sources/hdl/verilog/execute_stage.v38
-rw-r--r--sources/hdl/verilog/frontend.v24
-rw-r--r--sources/hdl/verilog/maintenance_controller.v12
-rw-r--r--sources/hdl/verilog/readback_engine.v31
-rw-r--r--sources/hdl/verilog/softmc_pipeline.v38
10 files changed, 198 insertions, 93 deletions
diff --git a/sources/hdl/header_verilog/encoding.vh b/sources/hdl/header_verilog/encoding.vh
index f5d5697..c0265d6 100644
--- a/sources/hdl/header_verilog/encoding.vh
+++ b/sources/hdl/header_verilog/encoding.vh
@@ -20,13 +20,15 @@
`define DDR_CODE_OFFSET 12
`define DEC_CAR 4
`define DEC_BAR 0
+`define DEC_SEL_CH 0
`define DEC_RAR 4
`define DEC_INC_BAR 10
`define DEC_PRE_ALL 11
`define DEC_INC_RAR 11
`define DEC_INC_CAR 11
`define DEC_AP 9
-`define DEC_BL4 8
+`define DEC_BL4 8 // deprecated
+`define DEC_RANK 8
// function codes - exe
`define ADD 0
`define ADDI 1
@@ -54,6 +56,7 @@
`define PRE 2
`define ACT 3
`define ZQ 4
+`define SEL_CH 4
`define REF 5
`define NOP 7
@@ -63,6 +66,7 @@
`define IS_PRE 2
`define IS_ACT 3
`define IS_ZQ 4
+`define IS_SEL_CH 4
`define IS_REF 5
`define CAR 6 // column address register identifier
`define RAR 10 // row address register identifier
@@ -72,10 +76,12 @@
`define INC_RAR 20
`define INC_BAR 21
`define IS_NOP 22
-`define IS_BL4 23
+`define IS_BL4 23 // deprecated
+`define IS_RANK 23
`define DO_AP 24
`define IS_SRE 25
`define IS_SRX 26
+`define HBM_CHANNEL 27 // HBM channel identifier
// SoftMC exe uops
`define IS_ADD 0
`define IS_SUB 1
diff --git a/sources/hdl/header_verilog/parameters.vh b/sources/hdl/header_verilog/parameters.vh
index 916c973..f60c2ad 100644
--- a/sources/hdl/header_verilog/parameters.vh
+++ b/sources/hdl/header_verilog/parameters.vh
@@ -3,12 +3,13 @@
`define IMEM_ADDR_WIDTH 11
// Decode - Execute
-`define DDR_UOP_WIDTH 27
+`define DDR_UOP_WIDTH 31
`define EXE_UOP_WIDTH 62
`define BG_WIDTH 2
`define BANK_WIDTH 2
`define COL_WIDTH 10
`define ROW_WIDTH 17
+`define HBM_CH_WIDTH 4
//Frontend
`define XDMA_AXI_DATA_WIDTH 256
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),