hdk/common/verif/models/fpga/fpga_ddr.svh (296 lines of code) (raw):

// ============================================================================ // Amazon FPGA Hardware Development Kit // // Copyright 2024 Amazon.com, Inc. or its affiliates. All Rights Reserved. // // Licensed under the Amazon Software License (the "License"). You may not use // this file except in compliance with the License. A copy of the License is // located at // // http://aws.amazon.com/asl/ // // or in the "license" file accompanying this file. This file is distributed on // an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, express or // implied. See the License for the specific language governing permissions and // limitations under the License. // ============================================================================ //--------------------------------------------------------------------------- // DIMM Interface from CL //--------------------------------------------------------------------------- wire CLK_DIMM_DP; wire CLK_DIMM_DN; wire M_ACT_N; wire [17:0] M_MA; wire [1:0] M_BA; wire [1:0] M_BG; wire [1:0] M_CKE; wire [1:0] M_ODT; wire [1:0] M_CS_N; wire [1:0] M_CLK_DN; wire [1:0] M_CLK_DP; wire M_PAR; wire [63:0] M_DQ; wire [7:0] M_ECC; wire [17:0] M_DQS_DP; wire [17:0] M_DQS_DN; wire RST_DIMM_N; wire PCIE_EP_PERSTN; wire PCIE_EP_REF_CLK_P; wire PCIE_EP_REF_CLK_N; wire [7:0] PCIE_EP_TXP; wire [7:0] PCIE_EP_TXN; wire [7:0] PCIE_EP_RXP; wire [7:0] PCIE_EP_RXN; wire PCIE_RP_PERSTN; wire PCIE_RP_REF_CLK_P; wire PCIE_RP_REF_CLK_N; wire [7:0] PCIE_RP_TXP; wire [7:0] PCIE_RP_TXN; wire [7:0] PCIE_RP_RXP; wire [7:0] PCIE_RP_RXN; `ifndef NO_DDR int fp[17:0]; string ddr_name[17:0]; //--------------------------------------------------------------------------- // DDR Clocks source clock to the CL_DDR4 controller. // CL_DDR4 generates the actual DDR clocks (M_CLK_DP, M_CLK_DN) based on // this source clock //--------------------------------------------------------------------------- logic ddr_clk; initial begin ddr_clk = 0; forever #5ns ddr_clk = ~ddr_clk; end assign CLK_DIMM_DP = ddr_clk; assign CLK_DIMM_DN = ~ddr_clk; `define EOF -1 //=========================================================================== // Memory Model instantiation //=========================================================================== ddr4_rdimm_wrapper #( .MC_DQ_WIDTH (72), .MC_DQS_BITS (18), .MC_DM_WIDTH (18), .MC_CKE_NUM (2), .MC_ODT_WIDTH (2), .MC_ABITS (18), .MC_BANK_WIDTH (2), .MC_BANK_GROUP (2), .MC_CS_NUM (2), .MC_RANKS_NUM (2), .NUM_PHYSICAL_PARTS (18), .CALIB_EN ("NO"), .tCK (938), .tPDM (), .MIN_TOTAL_R2R_DELAY (), .MAX_TOTAL_R2R_DELAY (), .TOTAL_FBT_DELAY (), .MEM_PART_WIDTH ("x4"), .MC_CA_MIRROR ("ON"), // .SDRAM ("DDR4"), `ifdef SAMSUNG .DDR_SIM_MODEL ("SAMSUNG"), `else .DDR_SIM_MODEL ("MICRON"), `endif .DM_DBI ("NONE"), .MC_REG_CTRL ("ON"), .DIMM_MODEL ("RDIMM"), .RDIMM_SLOTS (1) ) u_ddr4_rdimm ( .ddr4_act_n (M_ACT_N), .ddr4_addr (M_MA), .ddr4_ba (M_BA), .ddr4_bg (M_BG), .ddr4_par (M_PAR), .ddr4_cke (M_CKE), .ddr4_odt (M_ODT), .ddr4_cs_n (M_CS_N), .ddr4_ck_t (M_CLK_DP), .ddr4_ck_c (M_CLK_DN), .ddr4_reset_n (RST_DIMM_N), .ddr4_dm_dbi_n (), .ddr4_dq ({M_ECC,M_DQ}), .ddr4_dqs_t (M_DQS_DP), .ddr4_dqs_c (M_DQS_DN), .ddr4_alert_n (), .initDone (), .scl (), .sa0 (), .sa1 (), .sa2 (), .sda (), .bfunc (), .vddspd ()); `define ddr4_rdimm_inst(N)\ u_ddr4_rdimm.rcd_enabled.NOT_LRDIMM.u_ddr4_dimm.rank_instances[0].\ even_ranks.u_ddr4_rank.Micron_model.instance_of_sdram_devices[N].\ micron_mem_model.u_ddr4_model `ifndef QUESTA_SIM `ifndef IES_SIM //------------------------------------------------------ // Turn off warnings from DDR models //------------------------------------------------------ initial begin `ddr4_rdimm_inst( 0).set_memory_warnings(0, 0); `ddr4_rdimm_inst( 1).set_memory_warnings(0, 0); `ddr4_rdimm_inst( 2).set_memory_warnings(0, 0); `ddr4_rdimm_inst( 3).set_memory_warnings(0, 0); `ddr4_rdimm_inst( 4).set_memory_warnings(0, 0); `ddr4_rdimm_inst( 5).set_memory_warnings(0, 0); `ddr4_rdimm_inst( 6).set_memory_warnings(0, 0); `ddr4_rdimm_inst( 7).set_memory_warnings(0, 0); `ddr4_rdimm_inst( 8).set_memory_warnings(0, 0); `ddr4_rdimm_inst( 9).set_memory_warnings(0, 0); `ddr4_rdimm_inst(10).set_memory_warnings(0, 0); `ddr4_rdimm_inst(11).set_memory_warnings(0, 0); `ddr4_rdimm_inst(12).set_memory_warnings(0, 0); `ddr4_rdimm_inst(13).set_memory_warnings(0, 0); `ddr4_rdimm_inst(14).set_memory_warnings(0, 0); `ddr4_rdimm_inst(15).set_memory_warnings(0, 0); `ddr4_rdimm_inst(16).set_memory_warnings(0, 0); `ddr4_rdimm_inst(17).set_memory_warnings(0, 0); end // initial begin `endif//IES_SIM `endif//QUESTA_SIM task write_cfg_info_to_file(int ddr_fp); $display("File pointer is %d", ddr_fp); $fdisplay(ddr_fp, "config 4 16"); endtask task write_bdr_ld_data_to_file(logic [63:0] axi_addr, logic [511:0] data); logic [17:0] row_a, row_b; logic [1:0] bank_a, bank_b; logic [9:0] col_a, col_b; logic [1:0] bank_group_a, bank_group_b; logic [63:0] data_fp[17:0]; logic [511:0] data_t; row_a = axi_addr[34:17]; col_a = {axi_addr[16:11], axi_addr[8], axi_addr[5:3]}; bank_a = {axi_addr[10:9]}; bank_group_a = {axi_addr[7:6]}; row_b = {row_a[17:14], ~row_a[13], row_a[12], ~row_a[11], row_a[10], ~row_a[9:3], row_a[2:0]}; col_b = {~col_a[9:3], col_a[2:0]}; bank_b = ~bank_a; bank_group_b = ~bank_group_a; for (int i=0; i<8; i=i+2) begin data_t = data; //Each device is 32-bits wide. 64-bit data is loaded as below. for (int j=0; j<8; j++) begin data_fp[i][(j*4+3) -: 4] = data_t[3:0]; //3-0 data_t = data >> 4; data_fp[i+1][(j*4+3) -: 4] = data_t[3:0];//7-4 data_t = data >> 8; data = data_t; end // for (int j=0; j<8; j++) $fdisplay(fp[i], "%0h %0h %0h %0h %h", bank_group_a, bank_a, row_a, col_a, data_fp[i] [31:0]); $fdisplay(fp[i+1], "%0h %0h %0h %0h %h", bank_group_a, bank_a, row_a, col_a, data_fp[i+1][31:0]); $fdisplay(fp[i], "%0h %0h %0h %0h %h", bank_group_b, bank_b, row_b, col_b, data_fp[i] [31:0]); $fdisplay(fp[i+1], "%0h %0h %0h %0h %h", bank_group_b, bank_b, row_b, col_b, data_fp[i+1][31:0]); end //ECC $fdisplay(fp[14], "%0h %0h %0h %0h %h", bank_group_a, bank_a, row_a, col_a, 'h0); $fdisplay(fp[15], "%0h %0h %0h %0h %h", bank_group_a, bank_a, row_a, col_a, 'h0); //ECC $fdisplay(fp[14], "%0h %0h %0h %0h %h", bank_group_b, bank_b, row_b, col_b, 'h0); $fdisplay(fp[15], "%0h %0h %0h %0h %h", bank_group_b, bank_b, row_b, col_b, 'h0); for (int i=16; i<18; i=i+2) begin data_t = data; //Each device is 32-bits wide. 64-bit data is loaded as below. for (int j=0; j<8; j++) begin data_fp[i][(j*4+3) -: 4] = data_t[3:0]; data_t = data >> 4; data_fp[i+1][(j*4+3) -: 4] = data_t[3:0]; data_t = data >> 8; data = data_t; end // for (int j=0; j<8; j++) $fdisplay(fp[i], "%0h %0h %0h %0h %h", bank_group_a, bank_a, row_a, col_a, data_fp[i] [31:0]); $fdisplay(fp[i+1], "%0h %0h %0h %0h %h", bank_group_a, bank_a, row_a, col_a, data_fp[i+1][31:0]); $fdisplay(fp[i], "%0h %0h %0h %0h %h", bank_group_b, bank_b, row_b, col_b, data_fp[i] [31:0]); $fdisplay(fp[i+1], "%0h %0h %0h %0h %h", bank_group_b, bank_b, row_b, col_b, data_fp[i+1][31:0]); end // for (int i=16; i<18; i=i+2) for (int i=8; i<13; i=i+2) begin data_t = data; //Each device is 32-bits wide. 64-bit data is loaded as below. for (int j=0; j<8; j++) begin data_fp[i][(j*4+3) -: 4] = data_t[3:0]; data_t = data >> 4; data_fp[i+1][(j*4+3) -: 4] = data_t[3:0]; data_t = data >> 8; data = data_t; end // for (int j=0; j<8; j++) $fdisplay(fp[i], "%0h %0h %0h %0h %h", bank_group_a, bank_a, row_a, col_a, data_fp[i] [31:0]); $fdisplay(fp[i+1], "%0h %0h %0h %0h %h", bank_group_a, bank_a, row_a, col_a, data_fp[i+1][31:0]); $fdisplay(fp[i], "%0h %0h %0h %0h %h", bank_group_b, bank_b, row_b, col_b, data_fp[i] [31:0]); $fdisplay(fp[i+1], "%0h %0h %0h %0h %h", bank_group_b, bank_b, row_b, col_b, data_fp[i+1][31:0]); end // for (int i=8; i<13; i=i+2) endtask // write_bdr_ld_data_to_file task write_bdr_ld_raw_data_to_file(int ddr_file, logic [16:0] row_a, logic [1:0] bank_a, logic [9:0] col_a, logic [1:0] bank_group_a, logic [31:0] data); $fdisplay(ddr_file, "%0d %0d %0d %0d %h", bank_group_a, bank_a, row_a, col_a, data); endtask // write_bdr_ld_raw_data_to_file task ddr_bdr_ld(string file_name); logic [63:0] addr; logic [511:0] data; int axi_fp; int eof_s; int status; // Line buffer reg [12*100:1] line; int c; axi_fp = $fopen(file_name, "r"); for (int i=0; i<18; i++) begin ddr_name[i] = $sformatf("ddr4_ddr_%0d.mem", i); $display("ddr_name is %0s \n", ddr_name[i]); fp[i] = $fopen(ddr_name[i], "w"); if (!fp[i]) begin $display("Could not open file %s", ddr_name[i]); end end //Config information for memory. for (int i=0; i<18; i++) begin write_cfg_info_to_file(fp[i]); end // Check the first character c = $fgetc(axi_fp); while (c != `EOF) begin status = $ungetc(c, axi_fp); //status = $fscanf(axi_fp,"%0h %0h", addr, data); status = $fgets(line, axi_fp); status = $sscanf(line, "%x %x", addr, data); $display("eof_s is %d status is %d \n", eof_s, status); $display("addr is %h data is %h \n", addr, data); write_bdr_ld_data_to_file(.axi_addr(addr), .data(data)); c = $fgetc(axi_fp); end for (int i=0; i<18; i++) begin $fclose(fp[i]); end device_bdr_ld(); endtask // ddr_bdr_ld task device_bdr_ld(); for (int i=0; i<18; i++) begin ddr_name[i] = $sformatf("ddr4_ddr_%0d.mem", i); $display("ddr_name is %s \n", ddr_name[i]); end `ifndef DDR_ABSENT `ddr4_rdimm_inst( 0).initialize_memory_with_file(ddr_name[0]); `ddr4_rdimm_inst( 1).initialize_memory_with_file(ddr_name[1]); `ddr4_rdimm_inst( 2).initialize_memory_with_file(ddr_name[2]); `ddr4_rdimm_inst( 3).initialize_memory_with_file(ddr_name[3]); `ddr4_rdimm_inst( 4).initialize_memory_with_file(ddr_name[4]); `ddr4_rdimm_inst( 5).initialize_memory_with_file(ddr_name[5]); `ddr4_rdimm_inst( 6).initialize_memory_with_file(ddr_name[6]); `ddr4_rdimm_inst( 7).initialize_memory_with_file(ddr_name[7]); `ddr4_rdimm_inst( 8).initialize_memory_with_file(ddr_name[16]); `ddr4_rdimm_inst( 9).initialize_memory_with_file(ddr_name[17]); `ddr4_rdimm_inst(10).initialize_memory_with_file(ddr_name[8]); `ddr4_rdimm_inst(11).initialize_memory_with_file(ddr_name[9]); `ddr4_rdimm_inst(12).initialize_memory_with_file(ddr_name[10]); `ddr4_rdimm_inst(13).initialize_memory_with_file(ddr_name[11]); `ddr4_rdimm_inst(14).initialize_memory_with_file(ddr_name[12]); `ddr4_rdimm_inst(15).initialize_memory_with_file(ddr_name[13]); `ddr4_rdimm_inst(16).initialize_memory_with_file(ddr_name[14]); `ddr4_rdimm_inst(17).initialize_memory_with_file(ddr_name[15]); `endif//DDR_ABSENT endtask // device_bdr_ld `endif//NO_DDR