diff --git a/.gitignore b/.gitignore index 9eef0bc..551bbc3 100644 --- a/.gitignore +++ b/.gitignore @@ -4,6 +4,7 @@ transcript .venv cheshire idma +hyperbus # EMACS @@ -30,6 +31,7 @@ utils/verible-verilog # SIM +target/sim/models target/sim/vsim/work target/sim/vsim/transcript target/sim/vsim/trace* diff --git a/.gitlab/gitlab-ci.yml b/.gitlab/gitlab-ci.yml index a420aff..cf68cb8 100644 --- a/.gitlab/gitlab-ci.yml +++ b/.gitlab/gitlab-ci.yml @@ -7,7 +7,7 @@ # We initialize the nonfree repo, then spawn a sub-pipeline from it variables: - VSIM_TESTS: '["testCluster", "testClusterOffload", "testMemBypass", "testPeripheralsGating"]' + VSIM_TESTS: '["testCluster", "testClusterOffload", "testMemBypass", "testPeripheralsGating", "testHyperbusAddr"]' stages: - nonfree diff --git a/Bender.lock b/Bender.lock index 0178d60..662995a 100644 --- a/Bender.lock +++ b/Bender.lock @@ -164,6 +164,16 @@ packages: Git: https://github.com/pulp-platform/fpu_div_sqrt_mvp.git dependencies: - common_cells + hyperbus: + revision: f039e601c8b6590181734e6d26ff8b77aa380412 + version: null + source: + Git: https://github.com/pulp-platform/hyperbus.git + dependencies: + - axi + - common_cells + - register_interface + - tech_cells_generic idma: revision: 9edf489f57389dce5e71252c79e337f527d3aded version: null diff --git a/Bender.yml b/Bender.yml index 3f15ea3..e8fc290 100644 --- a/Bender.yml +++ b/Bender.yml @@ -17,6 +17,8 @@ dependencies: idma: { git: "https://github.com/pulp-platform/iDMA.git", rev: 9edf489f57389dce5e71252c79e337f527d3aded} memory_island: { git: "https://github.com/pulp-platform/memory_island.git", rev: 64828cb7a9ccc1f1656ec92d06129072f445c319 } # main branch apb: { git: "https://github.com/pulp-platform/apb.git", version: 0.2.4 } + hyperbus: { git: "https://github.com/pulp-platform/hyperbus.git", rev: f039e601c8b6590181734e6d26ff8b77aa380412 } # branch: chi/add_fsm_with_Tcsh + tech_cells_generic: { git: "https://github.com/pulp-platform/tech_cells_generic.git", version: 0.2.12 } export_include_dirs: - hw/include @@ -25,6 +27,7 @@ workspace: package_links: cheshire: cheshire idma: idma + hyperbus: hyperbus sources: - hw/chimera_pkg.sv @@ -36,14 +39,16 @@ sources: - hw/chimera_cluster.sv - hw/chimera_clu_domain.sv - hw/chimera_memisland_domain.sv + - hw/hyperbus_wrap.sv - hw/chimera_top_wrapper.sv - target: any(simulation, test) files: + - target/sim/models/s27ks0641/s27ks0641.v + - target/sim/src/tb_chimera_pkg.sv - target/sim/src/vip_chimera_soc.sv - target/sim/src/fixture_chimera_soc.sv - target/sim/src/tb_chimera_soc.sv - - target/sim/src/tb_chimera_pkg.sv vendor_package: - name: reggen diff --git a/Makefile b/Makefile index c38ccb3..05db9e1 100644 --- a/Makefile +++ b/Makefile @@ -14,6 +14,7 @@ VERIBLE_VERILOG_FORMAT ?= $(CHIM_UTILS_DIR)/verible-verilog/verible-verilog-form CHS_ROOT ?= $(shell $(BENDER) path cheshire) SNITCH_ROOT ?= $(shell $(BENDER) path snitch_cluster) IDMA_ROOT ?= $(shell $(BENDER) path idma) +HYPERB_ROOT ?= $(shell $(BENDER) path hyperbus) CHS_XLEN ?= 32 diff --git a/bender.mk b/bender.mk index 5984911..2039e68 100644 --- a/bender.mk +++ b/bender.mk @@ -8,4 +8,4 @@ COMMON_TARGS ?= COMMON_TARGS += -t snitch_cluster -t cv32a6_convolve -t cva6 -t rtl -SIM_TARGS = -t test -t sim +SIM_TARGS = $(COMMON_TARGS) -t test -t sim diff --git a/hw/chimera_pkg.sv b/hw/chimera_pkg.sv index 34b8bdb..ae90115 100644 --- a/hw/chimera_pkg.sv +++ b/hw/chimera_pkg.sv @@ -65,13 +65,14 @@ package chimera_pkg; localparam bit SnitchBootROM = 1; localparam bit TopLevelCfgRegs = 1; localparam bit ExtCfgRegs = 1; + localparam bit HyperCfgRegs = 1; // ------------------------------- // | External Register Interface | // ------------------------------- // SCHEREMO: Shared Snitch bootrom, one clock gate per cluster, External regs (PADs, FLLs etc...) - localparam int ExtRegNum = SnitchBootROM + TopLevelCfgRegs + ExtCfgRegs; + localparam int ExtRegNum = SnitchBootROM + TopLevelCfgRegs + ExtCfgRegs + HyperCfgRegs; localparam int ClusterDataWidth = 64; localparam byte_bt SnitchBootROMIdx = 8'h0; @@ -87,6 +88,11 @@ package chimera_pkg; localparam doub_bt ExtCfgRegsRegionStart = 64'h3000_2000; localparam doub_bt ExtCfgRegsRegionEnd = 64'h3000_5000; + // Hyperbus configuration registers: HyperBus + localparam byte_bt HyperCfgRegsIdx = 8'h3; + localparam doub_bt HyperCfgRegsRegionStart = 64'h3000_5000; + localparam doub_bt HyperCfgRegsRegionEnd = 64'h3000_6000; + // -------------------------- // | External AXI ports | // -------------------------- @@ -106,8 +112,8 @@ ExtClusters localparam aw_bt ClusterNarrowAxiMstIdWidth = 1; - // Parameters for Memory Island - localparam int MemIslandIdx = ClusterIdx[ExtClusters-1] + 1; + // Memory Island + localparam byte_bt MemIslandIdx = ClusterIdx[ExtClusters-1] + 1; localparam doub_bt MemIslRegionStart = 64'h4800_0000; localparam doub_bt MemIslRegionEnd = 64'h4804_0000; @@ -118,6 +124,18 @@ ExtClusters localparam byte_bt MemIslNumWideBanks = 2; localparam shrt_bt MemIslWordsPerBank = 1024; + // Hyperbus + localparam byte_bt HyperbusIdx = MemIslandIdx + 1; + localparam doub_bt HyperbusRegionStart = 64'h5000_0000; + //TODO(smazzola): Correct size of HyperRAM? + localparam doub_bt HyperbusRegionEnd = HyperbusRegionStart + 64'h1000_0000; + + localparam int unsigned HypNumPhys = 1; + localparam int unsigned HypNumChips = 2; + + localparam int unsigned LogDepth = 3; + localparam int unsigned SyncStages = 3; + // ------------------- // | Generate Cfg | // -------------------- @@ -125,6 +143,7 @@ ExtClusters function automatic chimera_cfg_t gen_chimera_cfg(); localparam int AddrWidth = DefaultCfg.AddrWidth; localparam int MemoryIsland = 1; + localparam int Hyperbus = 1; chimera_cfg_t chimera_cfg; cheshire_cfg_t cfg = DefaultCfg; @@ -133,6 +152,7 @@ ExtClusters // Set all Chimera addresses as uncached cfg.Cva6ExtCieLength = 'h0; + cfg.Cva6ExtCieOnTop = 1; cfg.Vga = 0; cfg.SerialLink = 0; @@ -150,21 +170,26 @@ ExtClusters // SCHEREMO: Two ports for each cluster: one to convert stray wides, one for the original narrow cfg.AxiExtNumMst = ExtClusters + $countones(ChimeraClusterCfg.hasWideMasterPort); - cfg.AxiExtNumSlv = ExtClusters + MemoryIsland; - cfg.AxiExtNumRules = ExtClusters + MemoryIsland; + cfg.AxiExtNumSlv = ExtClusters + MemoryIsland + Hyperbus; + cfg.AxiExtNumRules = ExtClusters + MemoryIsland + Hyperbus; - cfg.AxiExtRegionIdx = {MemIslandIdx, ClusterIdx}; - cfg.AxiExtRegionStart = {MemIslRegionStart, ClusterRegionStart}; - cfg.AxiExtRegionEnd = {MemIslRegionEnd, ClusterRegionEnd}; + cfg.AxiExtRegionIdx = {HyperbusIdx, MemIslandIdx, ClusterIdx}; + cfg.AxiExtRegionStart = {HyperbusRegionStart, MemIslRegionStart, ClusterRegionStart}; + cfg.AxiExtRegionEnd = {HyperbusRegionEnd, MemIslRegionEnd, ClusterRegionEnd}; // REG CFG cfg.RegExtNumSlv = ExtRegNum; cfg.RegExtNumRules = ExtRegNum; - cfg.RegExtRegionIdx = {ExtCfgRegsIdx, TopLevelCfgRegsIdx, SnitchBootROMIdx}; + cfg.RegExtRegionIdx = {HyperCfgRegsIdx, ExtCfgRegsIdx, TopLevelCfgRegsIdx, SnitchBootROMIdx}; cfg.RegExtRegionStart = { - ExtCfgRegsRegionStart, TopLevelCfgRegsRegionStart, SnitchBootROMRegionStart + HyperCfgRegsRegionStart, + ExtCfgRegsRegionStart, + TopLevelCfgRegsRegionStart, + SnitchBootROMRegionStart + }; + cfg.RegExtRegionEnd = { + HyperCfgRegsRegionEnd, ExtCfgRegsRegionEnd, TopLevelCfgRegsRegionEnd, SnitchBootROMRegionEnd }; - cfg.RegExtRegionEnd = {ExtCfgRegsRegionEnd, TopLevelCfgRegsRegionEnd, SnitchBootROMRegionEnd}; // ACCEL HART/IRQ CFG cfg.NumExtIrqHarts = ExtCores; diff --git a/hw/chimera_top_wrapper.sv b/hw/chimera_top_wrapper.sv index d060e68..3f7325e 100644 --- a/hw/chimera_top_wrapper.sv +++ b/hw/chimera_top_wrapper.sv @@ -4,7 +4,7 @@ // // Moritz Scherer // Lorenzo Leone - +// Arpan Prasad module chimera_top_wrapper import cheshire_pkg::*; @@ -13,56 +13,67 @@ module chimera_top_wrapper #( parameter int unsigned SelectedCfg = 0 ) ( - input logic soc_clk_i, - input logic clu_clk_i, - input logic rst_ni, - input logic test_mode_i, - input logic [ 1:0] boot_mode_i, - input logic rtc_i, + input logic soc_clk_i, + input logic clu_clk_i, + input logic rst_ni, + input logic test_mode_i, + input logic [ 1:0] boot_mode_i, + input logic rtc_i, // JTAG interface - input logic jtag_tck_i, - input logic jtag_trst_ni, - input logic jtag_tms_i, - input logic jtag_tdi_i, - output logic jtag_tdo_o, - output logic jtag_tdo_oe_o, + input logic jtag_tck_i, + input logic jtag_trst_ni, + input logic jtag_tms_i, + input logic jtag_tdi_i, + output logic jtag_tdo_o, + output logic jtag_tdo_oe_o, // UART interface - output logic uart_tx_o, - input logic uart_rx_i, + output logic uart_tx_o, + input logic uart_rx_i, // UART modem flow control - output logic uart_rts_no, - output logic uart_dtr_no, - input logic uart_cts_ni, - input logic uart_dsr_ni, - input logic uart_dcd_ni, - input logic uart_rin_ni, + output logic uart_rts_no, + output logic uart_dtr_no, + input logic uart_cts_ni, + input logic uart_dsr_ni, + input logic uart_dcd_ni, + input logic uart_rin_ni, // I2C interface - output logic i2c_sda_o, - input logic i2c_sda_i, - output logic i2c_sda_en_o, - output logic i2c_scl_o, - input logic i2c_scl_i, - output logic i2c_scl_en_o, + output logic i2c_sda_o, + input logic i2c_sda_i, + output logic i2c_sda_en_o, + output logic i2c_scl_o, + input logic i2c_scl_i, + output logic i2c_scl_en_o, // SPI host interface - output logic spih_sck_o, - output logic spih_sck_en_o, - output logic [ SpihNumCs-1:0] spih_csb_o, - output logic [ SpihNumCs-1:0] spih_csb_en_o, - output logic [ 3:0] spih_sd_o, - output logic [ 3:0] spih_sd_en_o, - input logic [ 3:0] spih_sd_i, + output logic spih_sck_o, + output logic spih_sck_en_o, + output logic [ SpihNumCs-1:0] spih_csb_o, + output logic [ SpihNumCs-1:0] spih_csb_en_o, + output logic [ 3:0] spih_sd_o, + output logic [ 3:0] spih_sd_en_o, + input logic [ 3:0] spih_sd_i, // GPIO interface - input logic [ 31:0] gpio_i, - output logic [ 31:0] gpio_o, - output logic [ 31:0] gpio_en_o, + input logic [ 31:0] gpio_i, + output logic [ 31:0] gpio_o, + output logic [ 31:0] gpio_en_o, + // Hyperbus interface + output logic [ HypNumPhys-1:0][HypNumChips-1:0] hyper_cs_no, + output logic [ HypNumPhys-1:0] hyper_ck_o, + output logic [ HypNumPhys-1:0] hyper_ck_no, + output logic [ HypNumPhys-1:0] hyper_rwds_o, + input logic [ HypNumPhys-1:0] hyper_rwds_i, + output logic [ HypNumPhys-1:0] hyper_rwds_oe_o, + input logic [ HypNumPhys-1:0][ 7:0] hyper_dq_i, + output logic [ HypNumPhys-1:0][ 7:0] hyper_dq_o, + output logic [ HypNumPhys-1:0] hyper_dq_oe_o, + output logic [ HypNumPhys-1:0] hyper_reset_no, // APB interface - input apb_resp_t apb_rsp_i, - output apb_req_t apb_req_o, + input apb_resp_t apb_rsp_i, + output apb_req_t apb_req_o, // PMU Clusters control signals - input logic [ExtClusters-1:0] pmu_rst_clusters_ni, - input logic [ExtClusters-1:0] pmu_clkgate_en_clusters_i, // TODO: lleone - input logic [ExtClusters-1:0] pmu_iso_en_clusters_i, - output logic [ExtClusters-1:0] pmu_iso_ack_clusters_o + input logic [ExtClusters-1:0] pmu_rst_clusters_ni, + input logic [ExtClusters-1:0] pmu_clkgate_en_clusters_i, // TODO: lleone + input logic [ExtClusters-1:0] pmu_iso_en_clusters_i, + output logic [ExtClusters-1:0] pmu_iso_ack_clusters_o ); @@ -352,13 +363,17 @@ module chimera_top_wrapper .isolate_o (pmu_iso_ack_clusters_o) ); + // Generate indices and get maps for all ports + localparam axi_in_t AxiIn = gen_axi_in(ChsCfg); + localparam axi_out_t AxiOut = gen_axi_out(ChsCfg); + // --------------------------------------- // | Memory Island | // --------------------------------------- chimera_memisland_domain #( .Cfg (Cfg), - .NumWideMst (Cfg.ChsCfg.AxiExtNumWideMst), + .NumWideMst (ChsCfg.AxiExtNumWideMst), .axi_narrow_req_t(axi_slv_req_t), .axi_narrow_rsp_t(axi_slv_rsp_t), .axi_wide_req_t (axi_wide_mst_req_t), @@ -372,4 +387,160 @@ module chimera_top_wrapper .axi_wide_rsp_o (axi_wide_mst_rsp) ); + localparam int unsigned AxiSlvIdWidth = ChsCfg.AxiMstIdWidth + $clog2(AxiIn.num_in); + + // Slave CDC parameters + localparam int unsigned ChimeraAxiSlvAwWidth = (2 ** LogDepth) * axi_pkg::aw_width( + ChsCfg.AddrWidth, AxiSlvIdWidth, ChsCfg.AxiUserWidth + ); + localparam int unsigned ChimeraAxiSlvWWidth = (2 ** LogDepth) * axi_pkg::w_width( + ChsCfg.AxiDataWidth, ChsCfg.AxiUserWidth + ); + localparam int unsigned ChimeraAxiSlvBWidth = (2 ** LogDepth) * axi_pkg::b_width( + AxiSlvIdWidth, ChsCfg.AxiUserWidth + ); + localparam int unsigned ChimeraAxiSlvArWidth = (2 ** LogDepth) * axi_pkg::ar_width( + ChsCfg.AddrWidth, AxiSlvIdWidth, ChsCfg.AxiUserWidth + ); + localparam int unsigned ChimeraAxiSlvRWidth = (2 ** LogDepth) * axi_pkg::r_width( + ChsCfg.AxiDataWidth, AxiSlvIdWidth, ChsCfg.AxiUserWidth + ); + + // Master CDC parameters + localparam int unsigned ChimeraAxiMstAwWidth = (2 ** LogDepth) * axi_pkg::aw_width( + ChsCfg.AddrWidth, ChsCfg.AxiMstIdWidth, ChsCfg.AxiUserWidth + ); + localparam int unsigned ChimeraAxiMstWWidth = (2 ** LogDepth) * axi_pkg::w_width( + ChsCfg.AxiDataWidth, ChsCfg.AxiUserWidth + ); + localparam int unsigned ChimeraAxiMstBWidth = (2 ** LogDepth) * axi_pkg::b_width( + ChsCfg.AxiMstIdWidth, ChsCfg.AxiUserWidth + ); + localparam int unsigned ChimeraAxiMstArWidth = (2 ** LogDepth) * axi_pkg::ar_width( + ChsCfg.AddrWidth, ChsCfg.AxiMstIdWidth, ChsCfg.AxiUserWidth + ); + localparam int unsigned ChimeraAxiMstRWidth = (2 ** LogDepth) * axi_pkg::r_width( + ChsCfg.AxiDataWidth, ChsCfg.AxiMstIdWidth, ChsCfg.AxiUserWidth + ); + + logic [ChimeraAxiSlvArWidth-1:0] hyper_ar_data; + logic [ LogDepth:0] hyper_ar_wptr; + logic [ LogDepth:0] hyper_ar_rptr; + logic [ChimeraAxiSlvAwWidth-1:0] hyper_aw_data; + logic [ LogDepth:0] hyper_aw_wptr; + logic [ LogDepth:0] hyper_aw_rptr; + logic [ ChimeraAxiSlvBWidth-1:0] hyper_b_data; + logic [ LogDepth:0] hyper_b_wptr; + logic [ LogDepth:0] hyper_b_rptr; + logic [ ChimeraAxiSlvRWidth-1:0] hyper_r_data; + logic [ LogDepth:0] hyper_r_wptr; + logic [ LogDepth:0] hyper_r_rptr; + logic [ ChimeraAxiSlvWWidth-1:0] hyper_w_data; + logic [ LogDepth:0] hyper_w_wptr; + logic [ LogDepth:0] hyper_w_rptr; + + axi_cdc_src #( + .LogDepth (LogDepth), + .SyncStages(SyncStages), + .aw_chan_t (axi_slv_aw_chan_t), + .w_chan_t (axi_slv_w_chan_t), + .b_chan_t (axi_slv_b_chan_t), + .ar_chan_t (axi_slv_ar_chan_t), + .r_chan_t (axi_slv_r_chan_t), + .axi_req_t (axi_slv_req_t), + .axi_resp_t(axi_slv_rsp_t) + ) hyperbus_slv_cdc_src ( + // synchronous slave port + .src_clk_i (soc_clk_i), + .src_rst_ni (rst_ni), + .src_req_i (axi_slv_req[HyperbusIdx]), + .src_resp_o (axi_slv_rsp[HyperbusIdx]), + // asynchronous master port + .async_data_master_aw_data_o(hyper_aw_data), + .async_data_master_aw_wptr_o(hyper_aw_wptr), + .async_data_master_aw_rptr_i(hyper_aw_rptr), + .async_data_master_w_data_o (hyper_w_data), + .async_data_master_w_wptr_o (hyper_w_wptr), + .async_data_master_w_rptr_i (hyper_w_rptr), + .async_data_master_b_data_i (hyper_b_data), + .async_data_master_b_wptr_i (hyper_b_wptr), + .async_data_master_b_rptr_o (hyper_b_rptr), + .async_data_master_ar_data_o(hyper_ar_data), + .async_data_master_ar_wptr_o(hyper_ar_wptr), + .async_data_master_ar_rptr_i(hyper_ar_rptr), + .async_data_master_r_data_i (hyper_r_data), + .async_data_master_r_wptr_i (hyper_r_wptr), + .async_data_master_r_rptr_o (hyper_r_rptr) + ); + + hyperbus_wrap #( + .NumChips (HypNumChips), + .NumPhys (HypNumPhys), + .IsClockODelayed (1'b0), + .AxiAddrWidth (ChsCfg.AddrWidth), + .AxiDataWidth (ChsCfg.AxiDataWidth), + .AxiIdWidth (AxiSlvIdWidth), + .AxiUserWidth (ChsCfg.AxiUserWidth), + .axi_req_t (axi_slv_req_t), + .axi_rsp_t (axi_slv_rsp_t), + .axi_w_chan_t (axi_slv_w_chan_t), + .axi_b_chan_t (axi_slv_b_chan_t), + .axi_ar_chan_t (axi_slv_ar_chan_t), + .axi_r_chan_t (axi_slv_r_chan_t), + .axi_aw_chan_t (axi_slv_aw_chan_t), + .RegAddrWidth (ChsCfg.AddrWidth), + .RegDataWidth (ChsCfg.AxiDataWidth), + .reg_req_t (reg_req_t), + .reg_rsp_t (reg_rsp_t), + .RxFifoLogDepth (32'd2), + .TxFifoLogDepth (32'd2), + .RstChipBase (ChsCfg.LlcOutRegionStart), + .RstChipSpace (HyperbusRegionEnd - HyperbusRegionStart), + .PhyStartupCycles(300 * 200), + .AxiLogDepth (LogDepth), + .AxiSlaveArWidth (ChimeraAxiSlvArWidth), + .AxiSlaveAwWidth (ChimeraAxiSlvAwWidth), + .AxiSlaveBWidth (ChimeraAxiSlvBWidth), + .AxiSlaveRWidth (ChimeraAxiSlvRWidth), + .AxiSlaveWWidth (ChimeraAxiSlvWWidth), + .AxiMaxTrans (ChsCfg.AxiMaxSlvTrans), + .CdcSyncStages (SyncStages) + ) i_hyperbus_wrap ( + .clk_i (soc_clk_i), + .rst_ni (rst_ni), + .test_mode_i (test_mode_i), + .axi_slave_ar_data_i(hyper_ar_data), + .axi_slave_ar_wptr_i(hyper_ar_wptr), + .axi_slave_ar_rptr_o(hyper_ar_rptr), + .axi_slave_aw_data_i(hyper_aw_data), + .axi_slave_aw_wptr_i(hyper_aw_wptr), + .axi_slave_aw_rptr_o(hyper_aw_rptr), + .axi_slave_b_data_o (hyper_b_data), + .axi_slave_b_wptr_o (hyper_b_wptr), + .axi_slave_b_rptr_i (hyper_b_rptr), + .axi_slave_r_data_o (hyper_r_data), + .axi_slave_r_wptr_o (hyper_r_wptr), + .axi_slave_r_rptr_i (hyper_r_rptr), + .axi_slave_w_data_i (hyper_w_data), + .axi_slave_w_wptr_i (hyper_w_wptr), + .axi_slave_w_rptr_o (hyper_w_rptr), + .rbus_req_addr_i (reg_slv_req[HyperCfgRegsIdx].addr), + .rbus_req_write_i (reg_slv_req[HyperCfgRegsIdx].write), + .rbus_req_wdata_i (reg_slv_req[HyperCfgRegsIdx].wdata), + .rbus_req_wstrb_i (reg_slv_req[HyperCfgRegsIdx].wstrb), + .rbus_req_valid_i (reg_slv_req[HyperCfgRegsIdx].valid), + .rbus_rsp_rdata_o (reg_slv_rsp[HyperCfgRegsIdx].rdata), + .rbus_rsp_ready_o (reg_slv_rsp[HyperCfgRegsIdx].ready), + .rbus_rsp_error_o (reg_slv_rsp[HyperCfgRegsIdx].error), + .hyper_cs_no, + .hyper_ck_o, + .hyper_ck_no, + .hyper_rwds_o, + .hyper_rwds_i, + .hyper_rwds_oe_o, + .hyper_dq_i, + .hyper_dq_o, + .hyper_dq_oe_o, + .hyper_reset_no + ); endmodule diff --git a/hw/hyperbus_wrap.sv b/hw/hyperbus_wrap.sv new file mode 100644 index 0000000..86b43c7 --- /dev/null +++ b/hw/hyperbus_wrap.sv @@ -0,0 +1,189 @@ +// Copyright 2023 ETH Zurich and University of Bologna. +// Solderpad Hardware License, Version 0.51, see LICENSE for details. +// SPDX-License-Identifier: SHL-0.51 +// +// Yvan Tortorella + +`include "register_interface/typedef.svh" + +module hyperbus_wrap #( + parameter int unsigned NumChips = -1, + parameter int unsigned NumPhys = 2, + parameter int unsigned IsClockODelayed = 0, + parameter int unsigned AxiAddrWidth = -1, + parameter int unsigned AxiDataWidth = -1, + parameter int unsigned AxiIdWidth = -1, + parameter int unsigned AxiUserWidth = -1, + parameter int unsigned AxiMaxTrans = 0, + parameter type axi_req_t = logic, + parameter type axi_rsp_t = logic, + parameter type axi_w_chan_t = logic, + parameter type axi_b_chan_t = logic, + parameter type axi_ar_chan_t = logic, + parameter type axi_r_chan_t = logic, + parameter type axi_aw_chan_t = logic, + parameter int unsigned RegAddrWidth = -1, + parameter int unsigned RegDataWidth = -1, + parameter type reg_req_t = logic, + parameter type reg_rsp_t = logic, + parameter type reg_addr_t = logic [RegAddrWidth-1:0], + parameter type reg_data_t = logic [RegDataWidth-1:0], + parameter type reg_strb_t = logic [RegDataWidth/8-1:0], + // The below have sensible defaults, but should be set on integration! + parameter int unsigned RxFifoLogDepth = 2, + parameter int unsigned TxFifoLogDepth = 2, + parameter logic [RegDataWidth-1:0] RstChipBase = 'h0, // Base address for all chips + parameter logic [RegDataWidth-1:0] RstChipSpace = 'h1_0000, // 64 KiB: Current maximum H + // yperBus device size + parameter int unsigned PhyStartupCycles = 300 * 200, /* us*MHz */ + // Conservative maximum + // frequency estimate + parameter int unsigned AxiLogDepth = 3, + parameter int unsigned AxiSlaveArWidth = 0, + parameter int unsigned AxiSlaveAwWidth = 0, + parameter int unsigned AxiSlaveBWidth = 0, + parameter int unsigned AxiSlaveRWidth = 0, + parameter int unsigned AxiSlaveWWidth = 0, + parameter int unsigned CdcSyncStages = 0 +) ( + input logic clk_i, + input logic rst_ni, + input logic test_mode_i, + // AXI bus + input logic [AxiSlaveArWidth-1:0] axi_slave_ar_data_i, + input logic [ AxiLogDepth:0] axi_slave_ar_wptr_i, + output logic [ AxiLogDepth:0] axi_slave_ar_rptr_o, + input logic [AxiSlaveAwWidth-1:0] axi_slave_aw_data_i, + input logic [ AxiLogDepth:0] axi_slave_aw_wptr_i, + output logic [ AxiLogDepth:0] axi_slave_aw_rptr_o, + output logic [ AxiSlaveBWidth-1:0] axi_slave_b_data_o, + output logic [ AxiLogDepth:0] axi_slave_b_wptr_o, + input logic [ AxiLogDepth:0] axi_slave_b_rptr_i, + output logic [ AxiSlaveRWidth-1:0] axi_slave_r_data_o, + output logic [ AxiLogDepth:0] axi_slave_r_wptr_o, + input logic [ AxiLogDepth:0] axi_slave_r_rptr_i, + input logic [ AxiSlaveWWidth-1:0] axi_slave_w_data_i, + input logic [ AxiLogDepth:0] axi_slave_w_wptr_i, + output logic [ AxiLogDepth:0] axi_slave_w_rptr_o, + // Reg bus + input reg_addr_t rbus_req_addr_i, + input logic rbus_req_write_i, + input reg_data_t rbus_req_wdata_i, + input reg_strb_t rbus_req_wstrb_i, + input logic rbus_req_valid_i, + output reg_data_t rbus_rsp_rdata_o, + output logic rbus_rsp_ready_o, + output logic rbus_rsp_error_o, + // Physical interace: HyperBus PADs + output logic [ NumPhys-1:0][NumChips-1:0] hyper_cs_no, + output logic [ NumPhys-1:0] hyper_ck_o, + output logic [ NumPhys-1:0] hyper_ck_no, + output logic [ NumPhys-1:0] hyper_rwds_o, + input logic [ NumPhys-1:0] hyper_rwds_i, + output logic [ NumPhys-1:0] hyper_rwds_oe_o, + input logic [ NumPhys-1:0][ 7:0] hyper_dq_i, + output logic [ NumPhys-1:0][ 7:0] hyper_dq_o, + output logic [ NumPhys-1:0] hyper_dq_oe_o, + output logic [ NumPhys-1:0] hyper_reset_no +); + + reg_req_t reg_req; + reg_rsp_t reg_rsp; + + typedef struct packed { + logic [31:0] idx; + logic [AxiAddrWidth-1:0] start_addr; + logic [AxiAddrWidth-1:0] end_addr; + } addr_rule_t; + + axi_req_t hyper_req; + axi_rsp_t hyper_rsp; + + axi_cdc_dst #( + .LogDepth (AxiLogDepth), + .SyncStages(CdcSyncStages), + .aw_chan_t (axi_aw_chan_t), + .w_chan_t (axi_w_chan_t), + .b_chan_t (axi_b_chan_t), + .ar_chan_t (axi_ar_chan_t), + .r_chan_t (axi_r_chan_t), + .axi_req_t (axi_req_t), + .axi_resp_t(axi_rsp_t) + ) i_hyper_cdc_dst ( + // asynchronous slave port + .async_data_slave_aw_data_i(axi_slave_aw_data_i), + .async_data_slave_aw_wptr_i(axi_slave_aw_wptr_i), + .async_data_slave_aw_rptr_o(axi_slave_aw_rptr_o), + .async_data_slave_w_data_i (axi_slave_w_data_i), + .async_data_slave_w_wptr_i (axi_slave_w_wptr_i), + .async_data_slave_w_rptr_o (axi_slave_w_rptr_o), + .async_data_slave_b_data_o (axi_slave_b_data_o), + .async_data_slave_b_wptr_o (axi_slave_b_wptr_o), + .async_data_slave_b_rptr_i (axi_slave_b_rptr_i), + .async_data_slave_ar_data_i(axi_slave_ar_data_i), + .async_data_slave_ar_wptr_i(axi_slave_ar_wptr_i), + .async_data_slave_ar_rptr_o(axi_slave_ar_rptr_o), + .async_data_slave_r_data_o (axi_slave_r_data_o), + .async_data_slave_r_wptr_o (axi_slave_r_wptr_o), + .async_data_slave_r_rptr_i (axi_slave_r_rptr_i), + // synchronous master port + .dst_clk_i (clk_i), + .dst_rst_ni (rst_ni), + .dst_req_o (hyper_req), + .dst_resp_i (hyper_rsp) + ); + + assign reg_req.addr = rbus_req_addr_i; + assign reg_req.write = rbus_req_write_i; + assign reg_req.wdata = rbus_req_wdata_i; + assign reg_req.wstrb = rbus_req_wstrb_i; + assign reg_req.valid = rbus_req_valid_i; + assign rbus_rsp_rdata_o = reg_rsp.rdata; + assign rbus_rsp_ready_o = reg_rsp.ready; + assign rbus_rsp_error_o = reg_rsp.error; + + hyperbus #( + .NumChips (NumChips), + .NumPhys (NumPhys), + .IsClockODelayed (IsClockODelayed), + .AxiAddrWidth (AxiAddrWidth), + .AxiDataWidth (AxiDataWidth), + .AxiIdWidth (AxiIdWidth), + .AxiUserWidth (AxiUserWidth), + .axi_req_t (axi_req_t), + .axi_rsp_t (axi_rsp_t), + .RegAddrWidth (RegAddrWidth), + .RegDataWidth (RegDataWidth), + .reg_req_t (reg_req_t), + .reg_rsp_t (reg_rsp_t), + .axi_rule_t (addr_rule_t), + .RxFifoLogDepth (RxFifoLogDepth), + .TxFifoLogDepth (TxFifoLogDepth), + .RstChipBase (RstChipBase), + .RstChipSpace (RstChipSpace), + .PhyStartupCycles(PhyStartupCycles), + .AxiLogDepth (AxiLogDepth), + .SyncStages (CdcSyncStages) + ) i_hyperbus ( + .clk_phy_i (clk_i), + .rst_phy_ni (rst_ni), + .clk_sys_i (clk_i), + .rst_sys_ni (rst_ni), + .test_mode_i(test_mode_i), + .axi_req_i (hyper_req), + .axi_rsp_o (hyper_rsp), + .reg_req_i (reg_req), + .reg_rsp_o (reg_rsp), + .hyper_cs_no, + .hyper_ck_o, + .hyper_ck_no, + .hyper_rwds_o, + .hyper_rwds_i, + .hyper_rwds_oe_o, + .hyper_dq_i, + .hyper_dq_o, + .hyper_dq_oe_o, + .hyper_reset_no + ); + +endmodule : hyperbus_wrap diff --git a/sw/include/soc_addr_map.h b/sw/include/soc_addr_map.h index 8141c6f..6445608 100644 --- a/sw/include/soc_addr_map.h +++ b/sw/include/soc_addr_map.h @@ -3,6 +3,7 @@ // SPDX-License-Identifier: Apache-2.0 // // Moritz Scherer +// Sergio Mazzola #ifndef _SOC_ADDR_MAP_INCLUDE_GUARD_ #define _SOC_ADDR_MAP_INCLUDE_GUARD_ @@ -32,4 +33,7 @@ static uint8_t _chimera_numCores[] = {CLUSTER_0_NUMCORES, CLUSTER_1_NUMCORES, CL #define CHIMERA_PADFRAME_BASE_ADDRESS 0x30002000 #define FLL_BASE_ADDR 0x30003000 +#define HYPERBUS_CFG_BASE 0x30005000 +#define HYPERRAM_BASE 0x50000000 + #endif diff --git a/sw/tests/testHyperbusAddr.c b/sw/tests/testHyperbusAddr.c new file mode 100644 index 0000000..89b2ae3 --- /dev/null +++ b/sw/tests/testHyperbusAddr.c @@ -0,0 +1,30 @@ +// Copyright 2024 ETH Zurich and University of Bologna. +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 +// +// Sergio Mazzola + +// Test HyperRAM addressability through the Hyperbus peripheral + +#include +#include + +#define HYPER_BASE HYPERRAM_BASE +#define TESTVAL (uint32_t)0x1234ABCD + +int main() { + volatile uint32_t *hyperMemPtr = (volatile uint32_t *)HYPER_BASE; + volatile uint32_t result; + + // write + *(hyperMemPtr) = TESTVAL; + // read + result = *(hyperMemPtr); + + // verify + if (result == TESTVAL) { + return 0; + } else { + return 1; + } +} diff --git a/target/sim/sim.mk b/target/sim/sim.mk index fa5ba1d..d1d83fd 100644 --- a/target/sim/sim.mk +++ b/target/sim/sim.mk @@ -3,23 +3,44 @@ # SPDX-License-Identifier: Apache-2.0 # # Moritz Scherer +# Sergio Mazzola ifndef chim_sim_mk chim_sim_mk=1 CHIM_SIM_DIR ?= $(CHIM_ROOT)/target/sim -.PHONY: sim sim-clean +# Init vsim compilation +.PHONY: chim-sim +chim-sim: chim-hyperram-model $(CHIM_SIM_DIR)/vsim/compile.tcl -chim-sim-clean: - @rm -rf $(CHIM_SIM_DIR)/vsim/work - @rm -rf $(CHIM_SIM_DIR)/vsim/transcript - @rm -f $(CHIM_SIM_DIR)/vsim/compile.tcl +# Get HyperRAM verification IP (VIP) for simulation +.PHONY: chim-hyperram-model +chim-hyperram-model: $(CHIM_SIM_DIR)/models/s27ks0641/s27ks0641.sv +$(CHIM_SIM_DIR)/models/s27ks0641/s27ks0641.sv: + make -C $(HYPERB_ROOT) models/s27ks0641 + mkdir -p $(dir $@) + cp -r $(HYPERB_ROOT)/models/s27ks0641 $(CHIM_SIM_DIR)/models +# Defines for hyperram model preload at time 0 +HYP_USER_PRELOAD ?= 0 +HYP0_PRELOAD_MEM_FILE ?= "" -chim-sim: $(CHIM_SIM_DIR)/vsim/compile.tcl +CHIM_VLOG_ARGS += +define+HYP_USER_PRELOAD="$(HYP_USER_PRELOAD)" +CHIM_VLOG_ARGS += +define+HYP0_PRELOAD_MEM_FILE=\"$(HYP0_PRELOAD_MEM_FILE)\" +# this path should be kept relative to the vsim directory to avoid CI issues: +# an absolute path produce inter-CI-runner file accesses +CHIM_VLOG_ARGS += +define+PATH_TO_HYP_SDF=\"../models/s27ks0641/s27ks0641.sdf\" +# Generate vsim compilation script $(CHIM_SIM_DIR)/vsim/compile.tcl: chs-hw-init snitch-hw-init - @bender script vsim $(COMMON_TARGS) $(SIM_TARGS) --vlog-arg="$(VLOG_ARGS)"> $@ + @bender script vsim $(SIM_TARGS) --vlog-arg="$(CHIM_VLOG_ARGS)" > $@ echo 'vlog "$(realpath $(CHS_ROOT))/target/sim/src/elfloader.cpp" -ccflags "-std=c++11"' >> $@ +# Clean +.PHONY: chim-sim-clean +chim-sim-clean: + @rm -rf $(CHIM_SIM_DIR)/vsim/work + @rm -rf $(CHIM_SIM_DIR)/vsim/transcript + @rm -f $(CHIM_SIM_DIR)/vsim/compile.tcl + endif # chim_sim_mk diff --git a/target/sim/src/fixture_chimera_soc.sv b/target/sim/src/fixture_chimera_soc.sv index e2ec0d1..533499d 100644 --- a/target/sim/src/fixture_chimera_soc.sv +++ b/target/sim/src/fixture_chimera_soc.sv @@ -18,6 +18,7 @@ module fixture_chimera_soc #( import cheshire_pkg::*; import tb_cheshire_pkg::*; import chimera_pkg::*; + import tb_chimera_pkg::*; localparam chimera_cfg_t DutCfg = ChimeraCfg[SelectedCfg]; localparam cheshire_cfg_t ChsCfg = DutCfg.ChsCfg; @@ -29,36 +30,56 @@ module fixture_chimera_soc #( // DUT // /////////// - logic soc_clk; - logic clu_clk; - logic rst_n; - logic test_mode; - logic [ 1:0] boot_mode; - logic rtc; - - logic jtag_tck; - logic jtag_trst_n; - logic jtag_tms; - logic jtag_tdi; - logic jtag_tdo; - - logic uart_tx; - logic uart_rx; - - logic i2c_sda_o; - logic i2c_sda_i; - logic i2c_sda_en; - logic i2c_scl_o; - logic i2c_scl_i; - logic i2c_scl_en; - - logic spih_sck_o; - logic spih_sck_en; - logic [SpihNumCs-1:0] spih_csb_o; - logic [SpihNumCs-1:0] spih_csb_en; - logic [ 3:0] spih_sd_o; - logic [ 3:0] spih_sd_i; - logic [ 3:0] spih_sd_en; + logic soc_clk; + logic clu_clk; + logic rst_n; + logic test_mode; + logic [ 1:0] boot_mode; + logic rtc; + + logic jtag_tck; + logic jtag_trst_n; + logic jtag_tms; + logic jtag_tdi; + logic jtag_tdo; + + logic uart_tx; + logic uart_rx; + + logic i2c_sda_o; + logic i2c_sda_i; + logic i2c_sda_en; + logic i2c_scl_o; + logic i2c_scl_i; + logic i2c_scl_en; + + logic spih_sck_o; + logic spih_sck_en; + logic [ SpihNumCs-1:0] spih_csb_o; + logic [ SpihNumCs-1:0] spih_csb_en; + logic [ 3:0] spih_sd_o; + logic [ 3:0] spih_sd_i; + logic [ 3:0] spih_sd_en; + + logic [HypNumPhys-1:0][HypNumChips-1:0] hyper_cs_no; + logic [HypNumPhys-1:0] hyper_ck_i; + logic [HypNumPhys-1:0] hyper_ck_o; + logic [HypNumPhys-1:0] hyper_ck_ni; + logic [HypNumPhys-1:0] hyper_ck_no; + logic [HypNumPhys-1:0] hyper_rwds_o; + logic [HypNumPhys-1:0] hyper_rwds_i; + logic [HypNumPhys-1:0] hyper_rwds_oe_o; + logic [HypNumPhys-1:0][ 7:0] hyper_dq_i; + logic [HypNumPhys-1:0][ 7:0] hyper_dq_o; + logic [HypNumPhys-1:0] hyper_dq_oe_o; + logic [HypNumPhys-1:0] hyper_reset_no; + + wire [HypNumPhys-1:0][HypNumChips-1:0] pad_hyper_csn; + wire [HypNumPhys-1:0] pad_hyper_ck; + wire [HypNumPhys-1:0] pad_hyper_ckn; + wire [HypNumPhys-1:0] pad_hyper_rwds; + wire [HypNumPhys-1:0] pad_hyper_resetn; + wire [HypNumPhys-1:0][ 7:0] pad_hyper_dq; chimera_top_wrapper #( .SelectedCfg(SelectedCfg) @@ -99,6 +120,16 @@ module fixture_chimera_soc #( .gpio_i ('0), .gpio_o (), .gpio_en_o (), + .hyper_cs_no (hyper_cs_no), + .hyper_ck_o (hyper_ck_o), + .hyper_ck_no (hyper_ck_no), + .hyper_rwds_o (hyper_rwds_o), + .hyper_rwds_i (hyper_rwds_i), + .hyper_rwds_oe_o (hyper_rwds_oe_o), + .hyper_dq_i (hyper_dq_i), + .hyper_dq_o (hyper_dq_o), + .hyper_dq_oe_o (hyper_dq_oe_o), + .hyper_reset_no (hyper_reset_no), .pmu_rst_clusters_ni ({ExtClusters{rst_n}}), .pmu_clkgate_en_clusters_i(), .pmu_iso_en_clusters_i ('0), // Never Isolate @@ -123,9 +154,15 @@ module fixture_chimera_soc #( /////////// vip_chimera_soc #( - .DutCfg (ChsCfg), - .axi_ext_mst_req_t(axi_mst_req_t), - .axi_ext_mst_rsp_t(axi_mst_rsp_t) + .DutCfg (ChsCfg), + // Determine whether we preload the hyperram model or not User preload. If 0, the memory model + // is not preloaded at time 0. + .HypUserPreload (`HYP_USER_PRELOAD), + // Mem files for hyperram model. The argument is considered only if HypUserPreload==1 in the + // memory model. + .Hyp0UserPreloadMemFile(`HYP0_PRELOAD_MEM_FILE), + .axi_ext_mst_req_t (axi_mst_req_t), + .axi_ext_mst_rsp_t (axi_mst_rsp_t) ) vip ( .* ); diff --git a/target/sim/src/vip_chimera_soc.sv b/target/sim/src/vip_chimera_soc.sv index 28b5d25..d08d4ca 100644 --- a/target/sim/src/vip_chimera_soc.sv +++ b/target/sim/src/vip_chimera_soc.sv @@ -11,59 +11,71 @@ module vip_chimera_soc import cheshire_pkg::*; + import chimera_pkg::HypNumPhys; + import chimera_pkg::HypNumChips; #( // DUT (must be set) - parameter cheshire_cfg_t DutCfg = '0, + parameter cheshire_cfg_t DutCfg = '0, + + parameter type axi_ext_mst_req_t = logic, + parameter type axi_ext_mst_rsp_t = logic, // Timing - parameter type axi_ext_mst_req_t = logic, - parameter type axi_ext_mst_rsp_t = logic, - - parameter time ClkPeriodClu = 2ns, - parameter time ClkPeriodSys = 5ns, - parameter time ClkPeriodJtag = 20ns, - parameter time ClkPeriodRtc = 30518ns, - parameter int unsigned RstCycles = 5, - parameter real TAppl = 0.1, - parameter real TTest = 0.9, + parameter time ClkPeriodClu = 2ns, + parameter time ClkPeriodSys = 5ns, + parameter time ClkPeriodJtag = 20ns, + parameter time ClkPeriodRtc = 30518ns, + parameter int unsigned RstCycles = 5, + parameter real TAppl = 0.1, + parameter real TTest = 0.9, // UART - parameter int unsigned UartBaudRate = 115200, - parameter int unsigned UartParityEna = 0, - parameter int unsigned UartBurstBytes = 256, - parameter int unsigned UartWaitCycles = 60, + parameter int unsigned UartBaudRate = 115200, + parameter int unsigned UartParityEna = 0, + parameter int unsigned UartBurstBytes = 256, + parameter int unsigned UartWaitCycles = 60, // Serial Link - parameter int unsigned SlinkMaxWaitAx = 100, - parameter int unsigned SlinkMaxWaitR = 5, - parameter int unsigned SlinkMaxWaitResp = 20, - parameter int unsigned SlinkBurstBytes = 1024, - parameter int unsigned SlinkMaxTxns = 32, - parameter int unsigned SlinkMaxTxnsPerId = 16, - parameter bit SlinkAxiDebug = 0, + parameter int unsigned SlinkMaxWaitAx = 100, + parameter int unsigned SlinkMaxWaitR = 5, + parameter int unsigned SlinkMaxWaitResp = 20, + parameter int unsigned SlinkBurstBytes = 1024, + parameter int unsigned SlinkMaxTxns = 32, + parameter int unsigned SlinkMaxTxnsPerId = 16, + parameter bit SlinkAxiDebug = 0, + // HyperRAM (hardcoded to HypNumPhys = 2) + parameter int unsigned HypUserPreload = 0, + parameter string Hyp0UserPreloadMemFile = "", // Derived Parameters; *do not override* - parameter int unsigned AxiStrbWidth = DutCfg.AxiDataWidth / 8, - parameter int unsigned AxiStrbBits = $clog2(DutCfg.AxiDataWidth / 8) + parameter int unsigned AxiStrbWidth = DutCfg.AxiDataWidth / 8, + parameter int unsigned AxiStrbBits = $clog2(DutCfg.AxiDataWidth / 8) ) ( - output logic soc_clk, - output logic clu_clk, - output logic rst_n, - output logic test_mode, - output logic [ 1:0] boot_mode, - output logic rtc, + output logic soc_clk, + output logic clu_clk, + output logic rst_n, + output logic test_mode, + output logic [ 1:0] boot_mode, + output logic rtc, // JTAG interface - output logic jtag_tck, - output logic jtag_trst_n, - output logic jtag_tms, - output logic jtag_tdi, - input logic jtag_tdo, + output logic jtag_tck, + output logic jtag_trst_n, + output logic jtag_tms, + output logic jtag_tdi, + input logic jtag_tdo, // UART interface - input logic uart_tx, - output logic uart_rx, + input logic uart_tx, + output logic uart_rx, // I2C interface - inout wire i2c_sda, - inout wire i2c_scl, + inout wire i2c_sda, + inout wire i2c_scl, // SPI host interface - inout wire spih_sck, - inout wire [SpihNumCs-1:0] spih_csb, - inout wire [ 3:0] spih_sd + inout wire spih_sck, + inout wire [ SpihNumCs-1:0] spih_csb, + inout wire [ 3:0] spih_sd, + // Hyperbus interface + wire [HypNumPhys-1:0][HypNumChips-1:0] pad_hyper_csn, + wire [HypNumPhys-1:0] pad_hyper_ck, + wire [HypNumPhys-1:0] pad_hyper_ckn, + wire [HypNumPhys-1:0] pad_hyper_rwds, + wire [HypNumPhys-1:0] pad_hyper_resetn, + wire [HypNumPhys-1:0][ 7:0] pad_hyper_dq ); `include "cheshire/typedef.svh" @@ -554,35 +566,102 @@ module vip_chimera_soc if (image != "") $readmemh(image, i_spi_norflash.Mem); endtask + ////////////// + // Hyperbus // + ////////////// + + localparam string HypUserPreloadMemFiles[HypNumPhys] = '{Hyp0UserPreloadMemFile}; + + for (genvar i = 0; i < HypNumPhys; i++) begin : hyperrams + for (genvar j = 0; j < HypNumChips; j++) begin : chips + s27ks0641 #( + .UserPreload (HypUserPreload), + .mem_file_name(HypUserPreloadMemFiles[i]), + .TimingModel ("S27KS0641DPBHI020") + ) dut ( + .DQ7 (pad_hyper_dq[i][7]), + .DQ6 (pad_hyper_dq[i][6]), + .DQ5 (pad_hyper_dq[i][5]), + .DQ4 (pad_hyper_dq[i][4]), + .DQ3 (pad_hyper_dq[i][3]), + .DQ2 (pad_hyper_dq[i][2]), + .DQ1 (pad_hyper_dq[i][1]), + .DQ0 (pad_hyper_dq[i][0]), + .RWDS (pad_hyper_rwds[i]), + .CSNeg (pad_hyper_csn[i][j]), + .CK (pad_hyper_ck[i]), + .CKNeg (pad_hyper_ckn[i]), + .RESETNeg(pad_hyper_resetn[i]) + ); + end + end + + for (genvar p = 0; p < HypNumPhys; p++) begin : sdf_annotation + for (genvar l = 0; l < HypNumChips; l++) begin : sdf_annotation + initial begin +`ifndef PATH_TO_HYP_SDF + automatic string sdf_file_path = "../models/s27ks0641/s27ks0641.sdf"; +`else + automatic string sdf_file_path = `PATH_TO_HYP_SDF; +`endif + $sdf_annotate(sdf_file_path, hyperrams[p].chips[l].dut); + $display("Mem (%d,%d)", p, l); + end + end + end + endmodule // Map pad IO to tristate wires to adapt from SoC IO (not needed for chip instances). module vip_cheshire_soc_tristate import cheshire_pkg::*; -( +#( + parameter int unsigned HypNumPhys = 1, + parameter int unsigned HypNumChips = 2 +) ( // I2C pad IO - output logic i2c_sda_i, - input logic i2c_sda_o, - input logic i2c_sda_en, - output logic i2c_scl_i, - input logic i2c_scl_o, - input logic i2c_scl_en, + output logic i2c_sda_i, + input logic i2c_sda_o, + input logic i2c_sda_en, + output logic i2c_scl_i, + input logic i2c_scl_o, + input logic i2c_scl_en, // SPI host pad IO - input logic spih_sck_o, - input logic spih_sck_en, - input logic [SpihNumCs-1:0] spih_csb_o, - input logic [SpihNumCs-1:0] spih_csb_en, - output logic [ 3:0] spih_sd_i, - input logic [ 3:0] spih_sd_o, - input logic [ 3:0] spih_sd_en, + input logic spih_sck_o, + input logic spih_sck_en, + input logic [ SpihNumCs-1:0] spih_csb_o, + input logic [ SpihNumCs-1:0] spih_csb_en, + output logic [ 3:0] spih_sd_i, + input logic [ 3:0] spih_sd_o, + input logic [ 3:0] spih_sd_en, // I2C wires - inout wire i2c_sda, - inout wire i2c_scl, + inout wire i2c_sda, + inout wire i2c_scl, // SPI host wires - inout wire spih_sck, - inout wire [SpihNumCs-1:0] spih_csb, - inout wire [ 3:0] spih_sd + inout wire spih_sck, + inout wire [ SpihNumCs-1:0] spih_csb, + inout wire [ 3:0] spih_sd, + // Hyperbus pad IO + input logic [HypNumPhys-1:0][HypNumChips-1:0] hyper_cs_no, + output logic [HypNumPhys-1:0] hyper_ck_i, + input logic [HypNumPhys-1:0] hyper_ck_o, + output logic [HypNumPhys-1:0] hyper_ck_ni, + input logic [HypNumPhys-1:0] hyper_ck_no, + input logic [HypNumPhys-1:0] hyper_rwds_o, + output logic [HypNumPhys-1:0] hyper_rwds_i, + input logic [HypNumPhys-1:0] hyper_rwds_oe_o, + output logic [HypNumPhys-1:0][ 7:0] hyper_dq_i, + input logic [HypNumPhys-1:0][ 7:0] hyper_dq_o, + input logic [HypNumPhys-1:0] hyper_dq_oe_o, + input logic [HypNumPhys-1:0] hyper_reset_no, + // Hyperbus wires + wire [HypNumPhys-1:0][HypNumChips-1:0] pad_hyper_csn, + wire [HypNumPhys-1:0] pad_hyper_ck, + wire [HypNumPhys-1:0] pad_hyper_ckn, + wire [HypNumPhys-1:0] pad_hyper_rwds, + wire [HypNumPhys-1:0] pad_hyper_resetn, + wire [HypNumPhys-1:0][ 7:0] pad_hyper_dq ); // I2C @@ -608,4 +687,53 @@ module vip_cheshire_soc_tristate pullup (spih_csb[i]); end + for (genvar i = 0; i < HypNumPhys; i++) begin : gen_hyper_phy + for (genvar j = 0; j < HypNumChips; j++) begin : gen_hyper_cs + pad_functional_pd padinst_hyper_csno ( + .OEN(1'b0), + .I (hyper_cs_no[i][j]), + .O (), + .PEN(), + .PAD(pad_hyper_csn[i][j]) + ); + end + pad_functional_pd padinst_hyper_ck ( + .OEN(1'b0), + .I (hyper_ck_o[i]), + .O (), + .PEN(), + .PAD(pad_hyper_ck[i]) + ); + pad_functional_pd padinst_hyper_ckno ( + .OEN(1'b0), + .I (hyper_ck_no[i]), + .O (), + .PEN(), + .PAD(pad_hyper_ckn[i]) + ); + pad_functional_pd padinst_hyper_rwds0 ( + .OEN(~hyper_rwds_oe_o[i]), + .I (hyper_rwds_o[i]), + .O (hyper_rwds_i[i]), + .PEN(), + .PAD(pad_hyper_rwds[i]) + ); + pad_functional_pd padinst_hyper_resetn ( + .OEN(1'b0), + .I (hyper_reset_no[i]), + .O (), + .PEN(), + .PAD(pad_hyper_resetn[i]) + ); + for (genvar j = 0; j < 8; j++) begin : gen_hyper_dq + pad_functional_pd padinst_hyper_dqio0 ( + .OEN(~hyper_dq_oe_o[i]), + .I (hyper_dq_o[i][j]), + .O (hyper_dq_i[i][j]), + .PEN(), + .PAD(pad_hyper_dq[i][j]) + ); + end + end : gen_hyper_phy + endmodule