aboutsummaryrefslogtreecommitdiffstats
path: root/projects/U50-HBM/verilog/softmc_top.v
diff options
context:
space:
mode:
Diffstat (limited to 'projects/U50-HBM/verilog/softmc_top.v')
-rw-r--r--projects/U50-HBM/verilog/softmc_top.v398
1 files changed, 398 insertions, 0 deletions
diff --git a/projects/U50-HBM/verilog/softmc_top.v b/projects/U50-HBM/verilog/softmc_top.v
new file mode 100644
index 0000000..f826a5f
--- /dev/null
+++ b/projects/U50-HBM/verilog/softmc_top.v
@@ -0,0 +1,398 @@
+`include "parameters.vh"
+`include "project.vh"
+
+module softmc_top #(parameter tCK = 1500, SIM = "false")
+(
+ // common signals
+ input c0_sys_clk_p,
+ input c0_sys_clk_n,
+ input sys_rst_l,
+
+ // xdma signals
+ input clk_ref_p,
+ input clk_ref_n,
+ input pcie_rst,
+ output [7:0] pci_exp_txp,
+ output [7:0] pci_exp_txn,
+ input [7:0] pci_exp_rxp,
+ input [7:0] pci_exp_rxn,
+
+ output icc
+);
+
+ // clock signals
+ wire fab_clk;
+ wire dfi_clk;
+ wire main_clk;
+
+ // Frontend control signals
+ wire softmc_fin;
+ wire user_rst;
+
+ // Frontend <-> Fetch signals
+ wire [`IMEM_ADDR_WIDTH-1:0] fr_addr_in;
+ wire fr_valid_in;
+ wire [`INSTR_WIDTH-1:0] fr_data_out;
+ wire fr_valid_out;
+ wire [`IMEM_ADDR_WIDTH-1:0] fr_addr_out;
+ wire fr_ready_out;
+
+ // Frontend <-> misc. control signals
+ wire per_rd_init;
+ wire per_zq_init;
+ wire per_ref_init;
+ wire rbe_switch_mode;
+ wire toggle_dll;
+
+ // AXI streaming ports
+ wire [`XDMA_AXI_DATA_WIDTH-1:0] m_axis_h2c_tdata_0,xdma_h2c_tdata_0;
+ wire m_axis_h2c_tlast_0, xdma_h2c_tlast_0;
+ wire m_axis_h2c_tvalid_0, xdma_h2c_tvalid_0;
+ wire m_axis_h2c_tready_0, xdma_h2c_tready_0;
+ wire [`XDMA_AXI_DATA_WIDTH/8-1:0] m_axis_h2c_tkeep_0, xdma_h2c_tkeep_0;
+ wire [`XDMA_AXI_DATA_WIDTH-1:0] s_axis_c2h_tdata_0, xdma_c2h_tdata_0;
+ wire s_axis_c2h_tlast_0, xdma_c2h_tlast_0;
+ wire s_axis_c2h_tvalid_0, xdma_c2h_tvalid_0;
+ wire s_axis_c2h_tready_0, xdma_c2h_tready_0;
+ wire [`XDMA_AXI_DATA_WIDTH/8-1:0] s_axis_c2h_tkeep_0, xdma_c2h_tkeep_0;
+
+ // ddr_pipeline <-> outer module if
+ wire [3:0] ddr_write;
+ wire [3:0] ddr_read;
+ wire [3:0] ddr_pre;
+ wire [3:0] ddr_act;
+ wire [3:0] ddr_ref;
+ wire [3:0] hbm_sel_ch;
+ wire [3:0] ddr_nop;
+ wire [3:0] ddr_ap;
+ wire [3:0] ddr_pall;
+ wire [3:0] ddr_rank;
+ wire [3:0] ddr_half_bl;
+ wire [4*`HBM_CH_WIDTH-1:0] hbm_ch;
+ wire [4*`BG_WIDTH-1:0] ddr_bg;
+ wire [4*`BANK_WIDTH-1:0] ddr_bank;
+ wire [4*`COL_WIDTH-1:0] ddr_col;
+ wire [4*`ROW_WIDTH-1:0] ddr_row;
+ wire [511:0] ddr_wdata;
+
+ // periodic maintenance signals
+ wire ddr_maint_read;
+
+ wire read_seq_incoming; // next few instructions will read from DRAM
+ wire [11:0] incoming_reads; // how many reads next few instructions will issue
+ wire [11:0] buffer_space; // remaining buffer size
+
+ wire sys_rst = ~sys_rst_l; // low active signal
+
+ // HBM PHY signals
+ wire dfi_0_init_complete;
+ wire HBM_ready;
+ wire dfi_0_dw_rddata_valid;
+ wire [255:0] dfi_0_dw_rddata_p0;
+ wire [255:0] dfi_0_dw_rddata_p1;
+ wire hbm_ref_clk_buf;
+
+ // There is a possibility that these signals are on
+ // the critical path as observed in
+ // the previous iteration of SoftMC
+ reg dfi_0_init_complete_r, sys_rst_r;
+ wire iq_full, processing_iseq, rdback_fifo_empty;
+
+ wire [6:0] hbm0_temp;
+ wire [6:0] hbm1_temp;
+
+ IBUFDS hbm_ref_clk_ibuf (.O(hbm_ref_clk_buf), .I(c0_sys_clk_p), .IB((c0_sys_clk_n)));
+
+ // clock generation
+ clk_wiz_0 clk_gen (
+ .clk_150MHz(fab_clk),
+ .clk_300MHz(dfi_clk),
+ .clk_in1(hbm_ref_clk_buf)
+ );
+
+
+ always @(posedge fab_clk) begin
+ dfi_0_init_complete_r <= dfi_0_init_complete;
+ sys_rst_r <= sys_rst;
+ end
+
+ reg dllt_active = 1'b0;
+
+ `ifdef ENABLE_DLL_TOGGLER
+ always @(posedge fab_clk) begin
+ if(toggle_dll) begin
+ dllt_active <= ~dllt_active;
+ end
+ if(dllt_done) begin
+ dllt_active <= ~dllt_active;
+ end
+ end
+ `endif
+
+
+ softmc_pipeline pipeline(
+ .clk(fab_clk),
+ .rst(~HBM_ready || user_rst),
+
+ .softmc_end(softmc_fin),
+ .read_size(incoming_reads),
+ .read_seq_incoming(read_seq_incoming),
+ .buffer_space(buffer_space),
+
+ .addr_out(fr_addr_in),
+ .valid_out(fr_valid_in),
+ .data_in(fr_data_out),
+ .valid_in(fr_valid_out),
+ .addr_in(fr_addr_out),
+ .ready_out(fr_ready_out),
+
+ .ddr_write(ddr_write),
+ .ddr_read(ddr_read),
+ .ddr_pre(ddr_pre),
+ .ddr_act(ddr_act),
+ .ddr_rank(ddr_rank),
+ .ddr_ref(ddr_ref),
+ .ddr_zq(hbm_sel_ch),
+ .ddr_nop(ddr_nop),
+ .ddr_ap(ddr_ap),
+ .ddr_pall(ddr_pall),
+ //.ddr_half_bl(ddr_half_bl),
+ .hbm_ch(hbm_ch),
+ .ddr_bg(ddr_bg),
+ .ddr_bank(ddr_bank),
+ .ddr_col(ddr_col),
+ .ddr_row(ddr_row),
+ .ddr_wdata(ddr_wdata)
+ );
+
+
+ assign icc = dfi_0_init_complete_r;
+
+ wire frontend_ready;
+
+ wire hbm_temp_rd;
+
+ frontend #(.SIM_MEM(SIM)) frontend(
+ .clk(fab_clk),
+ .rst(~HBM_ready),
+
+ .init_calib_complete(dfi_0_init_complete_r),
+ .softmc_fin(softmc_fin),
+ .user_rst(user_rst),
+
+ .dllt_begin(toggle_dll),
+
+ // indicates read_back unit is ready for the next iseq
+ .frontend_ready(frontend_ready),
+
+ // frontend <-> fetch stage if
+ .addr_in(fr_addr_in),
+ .valid_in(fr_valid_in),
+ .data_out(fr_data_out),
+ .valid_out(fr_valid_out),
+ .addr_out(fr_addr_out),
+ .ready_in(fr_ready_out),
+
+ .hbm_temp_rd(hbm_temp_rd),
+
+ // frontend <-> xdma interface
+ .h2c_tdata_0(m_axis_h2c_tdata_0),
+ .h2c_tlast_0(m_axis_h2c_tlast_0),
+ .h2c_tvalid_0(m_axis_h2c_tvalid_0),
+ .h2c_tready_0(m_axis_h2c_tready_0),
+ .h2c_tkeep_0(m_axis_h2c_tkeep_0),
+
+ .per_rd_init(per_rd_init),
+ .per_zq_init(per_zq_init),
+ .per_ref_init(per_ref_init),
+ .rbe_switch_mode(rbe_switch_mode)
+ );
+
+ wire sys_clk, sys_clk_gt;
+ wire [2:0] msi_vector_width;
+ wire msi_enable;
+ wire user_lnk_up, usr_irq_req, usr_irq_ack;
+ `ifdef XUPVVH_HBM
+ IBUFDS_GTE4 refclk_ibuf (.O(sys_clk_gt), .ODIV2(sys_clk), .I(clk_ref_p), .CEB(1'b0), .IB(clk_ref_n));
+ `else
+ IBUFDS_GTE3 # (.REFCLK_HROW_CK_SEL(2'b01)) refclk_ibuf (.O(sys_clk_gt), .ODIV2(sys_clk), .I(clk_ref_p), .CEB(1'b0), .IB(clk_ref_n));
+ `endif
+ wire axi_clk, axi_rst;
+
+
+ xdma xdma_i
+ (
+ //---------------------------------------------------------------------------------------//
+ // PCI Express (pci_exp) Interface //
+ //---------------------------------------------------------------------------------------//
+ .sys_rst_n ( pcie_rst ),
+ .sys_clk ( sys_clk ),
+ .sys_clk_gt ( sys_clk_gt),
+
+ // Tx
+ .pci_exp_txn ( pci_exp_txn ),
+ .pci_exp_txp ( pci_exp_txp ),
+
+ // Rx
+ .pci_exp_rxn ( pci_exp_rxn ),
+ .pci_exp_rxp ( pci_exp_rxp ),
+
+ // AXI streaming ports
+ .s_axis_c2h_tdata_0(xdma_c2h_tdata_0),
+ .s_axis_c2h_tlast_0(xdma_c2h_tlast_0),
+ .s_axis_c2h_tvalid_0(xdma_c2h_tvalid_0),
+ .s_axis_c2h_tready_0(xdma_c2h_tready_0),
+ .s_axis_c2h_tkeep_0(xdma_c2h_tkeep_0),
+ .m_axis_h2c_tdata_0(xdma_h2c_tdata_0),
+ .m_axis_h2c_tlast_0(xdma_h2c_tlast_0),
+ .m_axis_h2c_tvalid_0(xdma_h2c_tvalid_0),
+ .m_axis_h2c_tready_0(xdma_h2c_tready_0),
+ .m_axis_h2c_tkeep_0(xdma_h2c_tkeep_0),
+
+ .usr_irq_req (1'b0),
+ .usr_irq_ack (usr_irq_ack),
+ .msi_enable (msi_enable),
+ .msi_vector_width (msi_vector_width),
+
+
+ // Config managemnet interface
+ .cfg_mgmt_addr ( 19'b0 ),
+ .cfg_mgmt_write ( 1'b0 ),
+ .cfg_mgmt_write_data ( 32'b0 ),
+ .cfg_mgmt_byte_enable ( 4'b0 ),
+ .cfg_mgmt_read ( 1'b0 ),
+ .cfg_mgmt_read_data (),
+ .cfg_mgmt_read_write_done (),
+ `ifndef XUPVVH_HBM
+ .cfg_mgmt_type1_cfg_reg_access ( 1'b0 ),
+ //---------- Shared Logic Internal -------------------------
+ .int_qpll1lock_out ( ),
+ .int_qpll1outrefclk_out ( ),
+ .int_qpll1outclk_out ( ),
+ `endif
+
+ //-- AXI Global
+ .axi_aclk (axi_clk), // AXI i-face clock driven from pcie clk
+ .axi_aresetn (axi_rst), // reset synchronous to axi_clk
+
+ .user_lnk_up ( user_lnk_up )
+ );
+
+ // Clock converter for the c2h interface
+ axis_clock_converter axis_clk_conv_i0
+ (
+ .s_axis_tvalid(s_axis_c2h_tvalid_0),
+ .s_axis_tlast(s_axis_c2h_tlast_0),
+ .s_axis_tdata(s_axis_c2h_tdata_0),
+ .s_axis_tkeep(s_axis_c2h_tkeep_0),
+ .s_axis_tready(s_axis_c2h_tready_0),
+ .m_axis_tvalid(xdma_c2h_tvalid_0),
+ .m_axis_tlast(xdma_c2h_tlast_0),
+ .m_axis_tdata(xdma_c2h_tdata_0),
+ .m_axis_tkeep(xdma_c2h_tkeep_0),
+ .m_axis_tready(xdma_c2h_tready_0),
+ .s_axis_aresetn(HBM_ready),
+ .s_axis_aclk(fab_clk),
+ .m_axis_aresetn(axi_rst),
+ .m_axis_aclk(axi_clk)
+ );
+
+ // Clock converter for the h2c interface
+ axis_clock_converter axis_clk_conv_i1
+ (
+ .m_axis_tvalid(m_axis_h2c_tvalid_0),
+ .m_axis_tlast(m_axis_h2c_tlast_0),
+ .m_axis_tdata(m_axis_h2c_tdata_0),
+ .m_axis_tkeep(m_axis_h2c_tkeep_0),
+ .m_axis_tready(m_axis_h2c_tready_0),
+ .s_axis_tvalid(xdma_h2c_tvalid_0),
+ .s_axis_tlast(xdma_h2c_tlast_0),
+ .s_axis_tdata(xdma_h2c_tdata_0),
+ .s_axis_tkeep(xdma_h2c_tkeep_0),
+ .s_axis_tready(xdma_h2c_tready_0),
+ .m_axis_aresetn(HBM_ready),
+ .m_axis_aclk(fab_clk),
+ .s_axis_aresetn(axi_rst),
+ .s_axis_aclk(axi_clk)
+ );
+
+
+ readback_engine rbe(
+ // common signals
+ .clk(fab_clk),
+ .rst(~HBM_ready || user_rst),
+
+ // other ctrl signals
+ .flush(frontend_ready),
+ .switch_mode(rbe_switch_mode),
+ .read_seq_incoming(read_seq_incoming), // next few instructions will read from DRAM
+ .incoming_reads(incoming_reads), // how many reads next few instructions will issue
+ .buffer_space(buffer_space), // remaining buffer size
+ // DRAM <-> engine if
+
+ // We make sure to retrieve the data following our convention
+ // wr/rddata[255:0] corresponds to PC0, and wr/rddata[511:256] corresponds to PC1
+ .rd_data({dfi_0_dw_rddata_p1, dfi_0_dw_rddata_p0}),
+
+ // Data is valid when dfi_0_dw_rddata_valid = 0011 (else 1100 or 0000), for now we can just use dfi_0_dw_rddata_valid[0]
+ .rd_valid(dfi_0_dw_rddata_valid),
+
+ // rbe <-> rf interface
+ .ddr_wdata(ddr_wdata),
+
+ .per_rd_init(per_rd_init),
+ .per_zq_init(per_zq_init),
+ .per_ref_init(per_ref_init),
+
+ `ifdef HBM_BENDER
+ .hbm_temp_rd(hbm_temp_rd),
+ .hbm0_temp(hbm0_temp),
+ .hbm1_temp(hbm1_temp),
+ `endif
+
+ // rbe <-> xdma if
+ .c2h_tdata_0(s_axis_c2h_tdata_0),
+ .c2h_tlast_0(s_axis_c2h_tlast_0),
+ .c2h_tvalid_0(s_axis_c2h_tvalid_0),
+ .c2h_tready_0(s_axis_c2h_tready_0), // use this when not simulating: s_axis_c2h_tready_0
+ .c2h_tkeep_0(s_axis_c2h_tkeep_0)
+ );
+
+ HBM_adapter HBM_adapter (
+ .c0_sys_clk_p(hbm_ref_clk_buf),
+ .sys_rst(~sys_rst),
+ .fab_clk(fab_clk),
+ .dfi_clk(dfi_clk),
+ .dfi_rst_n(~sys_rst),
+
+ .ddr_write(ddr_write),
+ .ddr_read(ddr_read),
+ .ddr_pre(ddr_pre),
+ .ddr_act(ddr_act),
+ .ddr_ref(ddr_ref),
+ .ddr_rank(ddr_rank),
+ .hbm_sel_ch(hbm_sel_ch),
+ .hbm_ch(hbm_ch),
+ .ddr_nop(ddr_nop),
+ .ddr_ap(ddr_ap),
+ .ddr_pall(ddr_pall),
+ .ddr_bg(ddr_bg),
+ .ddr_bank(ddr_bank),
+ .ddr_col(ddr_col),
+ .ddr_row(ddr_row),
+ .ddr_wdata(ddr_wdata),
+
+ .o_dfi_0_init_complete(dfi_0_init_complete),
+ .o_HBM_ready(HBM_ready),
+
+ // Received by readback engine
+ .o_dfi_0_dw_rddata_p0(dfi_0_dw_rddata_p0),
+ .o_dfi_0_dw_rddata_p1(dfi_0_dw_rddata_p1),
+ .o_dfi_0_dw_rddata_valid(dfi_0_dw_rddata_valid),
+
+ .hbm0_temp(hbm0_temp),
+ .hbm1_temp(hbm1_temp)
+ );
+
+
+endmodule