aboutsummaryrefslogtreecommitdiffstats
path: root/sources/hdl/verilog/ddr_pipeline.v
diff options
context:
space:
mode:
authorAtaberk <olgunataberk@gmail.com>2022-09-25 17:22:03 +0200
committerAtaberk <olgunataberk@gmail.com>2022-09-25 17:22:03 +0200
commitdc0b3db1b4f1895a07e5fe280ee3790e87f97b9f (patch)
treeb47203aa281bdd959def4451c84d310cd9cf2e12 /sources/hdl/verilog/ddr_pipeline.v
downloaddram-bender-dc0b3db1b4f1895a07e5fe280ee3790e87f97b9f.tar.gz
Initial commit
Diffstat (limited to 'sources/hdl/verilog/ddr_pipeline.v')
-rw-r--r--sources/hdl/verilog/ddr_pipeline.v206
1 files changed, 206 insertions, 0 deletions
diff --git a/sources/hdl/verilog/ddr_pipeline.v b/sources/hdl/verilog/ddr_pipeline.v
new file mode 100644
index 0000000..f8ae5aa
--- /dev/null
+++ b/sources/hdl/verilog/ddr_pipeline.v
@@ -0,0 +1,206 @@
+`include "parameters.vh"
+`include "encoding.vh"
+
+module ddr_pipeline(
+
+ // common signals
+ input clk,
+ input rst,
+
+ // execute_stage <-> ddr_pipeline if
+ input ddr_valid,
+ 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,
+
+ // ddr_pipeline <-> regfile interface
+ input [511:0] wide_reg,
+ output [7:0] update_en,
+ output [4*8-1:0] update_ids,
+ output [32*8-1:0] update_vals,
+ input [`COL_WIDTH-1:0] casr,
+ input [`BANK_WIDTH+`BG_WIDTH-1:0] basr,
+ input [`ROW_WIDTH-1:0] rasr,
+ output [4*8-1:0] reg_ids, // registers we need to read
+ input [32*8-1:0] reg_vals // register values
+ );
+
+ //Split input uop into four ways
+ wire [`DDR_UOP_WIDTH-1:0] uop [3:0];
+ genvar uops;
+ generate
+ for(uops = 0 ; uops < 4 ; uops = uops + 1) begin: split_uops
+ assign uop[uops] = ddr_uop[`DDR_UOP_WIDTH*uops +: `DDR_UOP_WIDTH];
+ end
+ endgenerate
+
+ // Figure out reg ids in the bubble cycle
+ reg [4*8-1:0] reg_ids_ns, reg_ids_r;
+
+ reg s2_valid;
+ reg [`DDR_UOP_WIDTH-1:0] s2_uop [3:0];
+ 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;
+
+ assign update_vals = s2_update_val;
+ assign update_en = s2_update_en;
+ assign update_ids = reg_ids_r;
+ assign reg_ids = reg_ids_r;
+ // these values are registered before
+ // being offloaded to the outer module
+ assign ddr_write = ddr_write_r;
+ assign ddr_read = ddr_read_r;
+ assign ddr_pre = ddr_pre_r;
+ assign ddr_act = ddr_act_r;
+ assign ddr_ref = ddr_ref_r;
+ assign ddr_sre = ddr_sre_r;
+ assign ddr_srx = ddr_srx_r;
+ assign ddr_zq = ddr_zq_r;
+ assign ddr_nop = ddr_nop_r;
+ assign ddr_ap = ddr_ap_r;
+ assign ddr_pall = ddr_pall_r;
+ assign ddr_half_bl = ddr_half_bl_r;
+ assign ddr_bg = ddr_bg_r;
+ assign ddr_bank = ddr_bank_r;
+ assign ddr_col = ddr_col_r;
+ assign ddr_row = ddr_row_r;
+ assign ddr_wdata = ddr_data_r;
+
+ integer i;
+ always @* begin
+ ddr_nop_ns = {4{`HIGH}};
+ s2_update_en = {4{`LOW}};
+ reg_ids_ns = reg_ids_r;
+ s2_update_val = 8*32'bX;
+ for(i = 0 ; i < 4 ; i = i + 1) begin: gen_ddrx_sigs
+ // Decide which registers to read in stage 1
+ if(uop[i][`IS_WRITE] || uop[i][`IS_READ]) begin
+ reg_ids_ns[i*8 +: 4] = uop[i][`BAR +: 4];
+ reg_ids_ns[i*8+4 +: 4] = uop[i][`CAR +: 4];
+ end
+ if(uop[i][`IS_PRE]) begin
+ reg_ids_ns[i*8 +: 4] = uop[i][`BAR +: 4];
+ end
+ if(uop[i][`IS_ACT]) begin
+ reg_ids_ns[i*8 +: 4] = uop[i][`BAR +: 4];
+ reg_ids_ns[i*8+4 +: 4] = uop[i][`RAR +: 4];
+ end
+ // stage 2 control sigs
+ ddr_pall_ns[i] = s2_uop[i][`PRE_ALL] & s2_uop[i][`IS_PRE];
+ ddr_write_ns[i] = s2_uop[i][`IS_WRITE];
+ ddr_read_ns[i] = s2_uop[i][`IS_READ];
+ ddr_pre_ns[i] = s2_uop[i][`IS_PRE];
+ ddr_act_ns[i] = s2_uop[i][`IS_ACT];
+ ddr_zq_ns[i] = s2_uop[i][`IS_ZQ];
+ ddr_ref_ns[i] = s2_uop[i][`IS_REF];
+ 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_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}};
+ // stage 2 address calculation
+ ddr_row_ns[i*`ROW_WIDTH +: `ROW_WIDTH]
+ = reg_vals[i*64+32 +: `ROW_WIDTH];
+ ddr_bank_ns[i*`BANK_WIDTH +: `BANK_WIDTH]
+ = reg_vals[i*64 +: `BANK_WIDTH];
+ ddr_bg_ns[i*`BG_WIDTH +: `BG_WIDTH]
+ = reg_vals[i*64+`BANK_WIDTH +: `BG_WIDTH];
+ ddr_col_ns[i*`COL_WIDTH +: `COL_WIDTH]
+ = reg_vals[i*64+32 +: `COL_WIDTH];
+ // stage 2 reg update
+ if(s2_uop[i][`INC_CAR] & (s2_uop[i][`IS_WRITE] | s2_uop[i][`IS_READ])) begin
+ s2_update_en[i*2+1] = `HIGH;
+ s2_update_val[i*64+32 +: 32] = reg_vals[i*64+32 +: `COL_WIDTH]
+ + casr;
+ end
+ else if(s2_uop[i][`INC_RAR] & (s2_uop[i][`IS_ACT])) begin
+ s2_update_en[i*2+1] = `HIGH;
+ s2_update_val[i*64+32 +: 32] = reg_vals[i*64+32 +: `ROW_WIDTH]
+ + rasr;
+ end
+ if(s2_uop[i][`INC_BAR]) begin
+ s2_update_en[i*2] = `HIGH;
+ s2_update_val[i*64 +: 32] = reg_vals[i*64 +: `BANK_WIDTH+`BG_WIDTH]
+ + basr;
+ end
+ end // for
+ end
+
+ always @(posedge clk) begin
+ if(rst) begin
+ s2_valid <= `LOW;
+ for(i = 0 ; i < 4 ; i = i + 1)
+ s2_uop[i] <= {`DDR_UOP_WIDTH{`LOW}};
+ ddr_write_r <= {4{`LOW}};
+ ddr_read_r <= {4{`LOW}};
+ ddr_pre_r <= {4{`LOW}};
+ ddr_act_r <= {4{`LOW}};
+ ddr_ref_r <= {4{`LOW}};
+ ddr_sre_r <= {4{`LOW}};
+ ddr_srx_r <= {4{`LOW}};
+ ddr_zq_r <= {4{`LOW}};
+ ddr_nop_r <= {4{`HIGH}};
+ ddr_ap_r <= {4{`LOW}};
+ ddr_half_bl_r <= {4{`LOW}};
+ end
+ else begin
+ reg_ids_r <= reg_ids_ns;
+ s2_valid <= ddr_valid;
+ for(i = 0 ; i < 4 ; i = i + 1)
+ s2_uop[i] <= uop[i];
+ ddr_write_r <= ddr_write_ns;
+ ddr_read_r <= ddr_read_ns;
+ ddr_pre_r <= ddr_pre_ns;
+ ddr_act_r <= ddr_act_ns;
+ ddr_ref_r <= ddr_ref_ns;
+ ddr_sre_r <= ddr_sre_ns;
+ ddr_srx_r <= ddr_srx_ns;
+ ddr_zq_r <= ddr_zq_ns;
+ 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_bg_r <= ddr_bg_ns;
+ ddr_bank_r <= ddr_bank_ns;
+ ddr_col_r <= ddr_col_ns;
+ ddr_row_r <= ddr_row_ns;
+ ddr_data_r <= wide_reg;
+ end
+ end
+
+endmodule