diff --git a/hw/chimera_clu_domain.sv b/hw/chimera_clu_domain.sv index 6fae9b0..75226f1 100644 --- a/hw/chimera_clu_domain.sv +++ b/hw/chimera_clu_domain.sv @@ -25,7 +25,7 @@ module chimera_clu_domain ) ( input logic soc_clk_i, input logic [ ExtClusters-1:0] clu_clk_i, - input logic rst_ni, + input logic [ ExtClusters-1:0] rst_sync_ni, input logic [ ExtClusters-1:0] widemem_bypass_i, //----------------------------- // Interrupt ports @@ -45,11 +45,133 @@ module chimera_clu_domain // Wide AXI ports //----------------------------- output wide_out_req_t [ iomsb(Cfg.AxiExtNumWideMst):0] wide_out_req_o, - input wide_out_resp_t [ iomsb(Cfg.AxiExtNumWideMst):0] wide_out_resp_i + input wide_out_resp_t [ iomsb(Cfg.AxiExtNumWideMst):0] wide_out_resp_i, + //----------------------------- + // Isolation control ports + //----------------------------- + input logic [ ExtClusters-1:0] isolate_i, + output logic [ ExtClusters-1:0] isolate_o ); + // Axi parameters + localparam int unsigned AxiWideDataWidth = Cfg.AxiDataWidth * Cfg.MemIslNarrowToWideFactor; + localparam int unsigned AxiWideSlvIdWidth = Cfg.MemIslAxiMstIdWidth + $clog2(Cfg.MemIslWidePorts); + localparam int unsigned AxiSlvIdWidth = Cfg.AxiMstIdWidth + $clog2( + cheshire_pkg::gen_axi_in(Cfg).num_in + ); + + // Isolated AXI signals + narrow_in_req_t [ iomsb(Cfg.AxiExtNumSlv):0] narrow_in_isolated_req; + narrow_in_resp_t [ iomsb(Cfg.AxiExtNumSlv):0] narrow_in_isolated_resp; + narrow_out_req_t [ iomsb(Cfg.AxiExtNumMst):0] narrow_out_isolated_req; + narrow_out_resp_t [ iomsb(Cfg.AxiExtNumMst):0] narrow_out_isolated_resp; + wide_out_req_t [iomsb(Cfg.AxiExtNumWideMst):0] wide_out_isolated_req; + wide_out_resp_t [iomsb(Cfg.AxiExtNumWideMst):0] wide_out_isolated_resp; + + logic [ iomsb(Cfg.AxiExtNumSlv):0] isolated_narrow_in; + logic [ iomsb(Cfg.AxiExtNumMst):0] isolated_narrow_out; + logic [iomsb(Cfg.AxiExtNumWideMst):0] isolated_wide_out; + + + for (genvar extClusterIdx = 0; extClusterIdx < ExtClusters; extClusterIdx++) begin : gen_clusters + if (Pasim == 1) begin : gen_cluster_iso + // Add AXI isolation at the Narrow Input Interface + axi_isolate #( + .NumPending (Cfg.AxiMaxSlvTrans), + .TerminateTransaction(0), + .AtopSupport (1), + .AxiAddrWidth (Cfg.AddrWidth), + .AxiDataWidth (Cfg.AxiDataWidth), + .AxiIdWidth (AxiSlvIdWidth), + .AxiUserWidth (Cfg.AxiUserWidth), + .axi_req_t (narrow_in_req_t), + .axi_resp_t (narrow_in_resp_t) + ) i_iso_narrow_in_cluster ( + .clk_i (soc_clk_i), + .rst_ni (rst_sync_ni[extClusterIdx]), + .slv_req_i (narrow_in_req_i[extClusterIdx]), + .slv_resp_o(narrow_in_resp_o[extClusterIdx]), + .mst_req_o (narrow_in_isolated_req[extClusterIdx]), + .mst_resp_i(narrow_in_isolated_resp[extClusterIdx]), + .isolate_i (isolate_i[extClusterIdx]), + .isolated_o(isolated_narrow_in[extClusterIdx]) + ); + + // Add AXI isolation at the Narrow Output Interface. + // Two ports for each cluster: one to convert stray wides, one for the original narrow + for ( + genvar narrowOutIdx = 2 * extClusterIdx; + narrowOutIdx < 2 * extClusterIdx + 2; + narrowOutIdx++ + ) begin : gen_iso_narrow_out + axi_isolate #( + .NumPending (Cfg.AxiMaxSlvTrans), + .TerminateTransaction(0), + .AtopSupport (1), + .AxiAddrWidth (Cfg.AddrWidth), + .AxiDataWidth (Cfg.AxiDataWidth), + .AxiIdWidth (Cfg.AxiMstIdWidth), + .AxiUserWidth (Cfg.AxiUserWidth), + .axi_req_t (narrow_out_req_t), + .axi_resp_t (narrow_out_resp_t) + ) i_iso_narrow_out_cluster ( + .clk_i (soc_clk_i), + .rst_ni (rst_sync_ni[extClusterIdx]), + .slv_req_i (narrow_out_isolated_req[narrowOutIdx]), + .slv_resp_o(narrow_out_isolated_resp[narrowOutIdx]), + .mst_req_o (narrow_out_req_o[narrowOutIdx]), + .mst_resp_i(narrow_out_resp_i[narrowOutIdx]), + .isolate_i (isolate_i[extClusterIdx]), + .isolated_o(isolated_narrow_out[narrowOutIdx]) + ); + end : gen_iso_narrow_out + + // Add AXI isolation at the Wide Interface + axi_isolate #( + .NumPending (Cfg.AxiMaxSlvTrans), + .TerminateTransaction(0), + .AtopSupport (1), + .AxiAddrWidth (Cfg.AddrWidth), + .AxiDataWidth (AxiWideDataWidth), + .AxiIdWidth (Cfg.MemIslAxiMstIdWidth), // To Check + .AxiUserWidth (Cfg.AxiUserWidth), + .axi_req_t (wide_out_req_t), + .axi_resp_t (wide_out_resp_t) + ) i_iso_wide_cluster ( + .clk_i (soc_clk_i), + .rst_ni (rst_sync_ni[extClusterIdx]), + .slv_req_i (wide_out_isolated_req[extClusterIdx]), + .slv_resp_o(wide_out_isolated_resp[extClusterIdx]), + .mst_req_o (wide_out_req_o[extClusterIdx]), + .mst_resp_i(wide_out_resp_i[extClusterIdx]), + .isolate_i (isolate_i[extClusterIdx]), + .isolated_o(isolated_wide_out[extClusterIdx]) + ); + + assign isolate_o[extClusterIdx] = isolated_narrow_in[extClusterIdx] & + isolated_narrow_out[2*extClusterIdx+:2] & + isolated_wide_out[extClusterIdx]; + + end else begin : gen_no_cluster_iso // bypass isolate if not required + + assign narrow_in_isolated_req[extClusterIdx] = narrow_in_req_i[extClusterIdx]; + assign narrow_in_resp_o[extClusterIdx] = narrow_in_isolated_resp[extClusterIdx]; + + assign narrow_out_req_o[2*extClusterIdx] = narrow_out_isolated_req[2*extClusterIdx]; + assign narrow_out_isolated_resp[2*extClusterIdx] = narrow_out_resp_i[2*extClusterIdx]; + + assign narrow_out_req_o[2*extClusterIdx+1] = narrow_out_isolated_req[2*extClusterIdx+1]; + assign narrow_out_isolated_resp[2*extClusterIdx+1] = narrow_out_resp_i[2*extClusterIdx+1]; + + assign wide_out_req_o[extClusterIdx] = wide_out_isolated_req[extClusterIdx]; + assign wide_out_isolated_resp[extClusterIdx] = wide_out_resp_i[extClusterIdx]; + + assign isolate_o[extClusterIdx] = '0; + + end : gen_no_cluster_iso + chimera_cluster #( .Cfg (Cfg), .NrCores (`NRCORES(extClusterIdx)), @@ -62,7 +184,7 @@ module chimera_clu_domain ) i_chimera_cluster ( .soc_clk_i (soc_clk_i), .clu_clk_i (clu_clk_i[extClusterIdx]), - .rst_ni, + .rst_ni (rst_sync_ni[extClusterIdx]), .widemem_bypass_i (widemem_bypass_i[extClusterIdx]), .debug_req_i (debug_req_i[`PREVNRCORES(extClusterIdx)+:`NRCORES(extClusterIdx)]), .meip_i (xeip_i[`PREVNRCORES(extClusterIdx)+:`NRCORES(extClusterIdx)]), @@ -72,12 +194,13 @@ module chimera_clu_domain .cluster_base_addr_i(Cfg.AxiExtRegionStart[extClusterIdx][Cfg.AddrWidth-1:0]), .boot_addr_i (SnitchBootROMRegionStart[31:0]), - .narrow_in_req_i (narrow_in_req_i[extClusterIdx]), - .narrow_in_resp_flat_o(narrow_in_resp_o[extClusterIdx]), - .narrow_out_req_flat_o(narrow_out_req_o[2*extClusterIdx+:2]), - .narrow_out_resp_i (narrow_out_resp_i[2*extClusterIdx+:2]), - .wide_out_req_flat_o (wide_out_req_o[extClusterIdx]), - .wide_out_resp_i (wide_out_resp_i[extClusterIdx]) + .narrow_in_req_i (narrow_in_isolated_req[extClusterIdx]), + .narrow_in_resp_o (narrow_in_isolated_resp[extClusterIdx]), + .narrow_out_req_o (narrow_out_isolated_req[2*extClusterIdx+:2]), + .narrow_out_resp_i(narrow_out_isolated_resp[2*extClusterIdx+:2]), + + .wide_out_req_o (wide_out_isolated_req[extClusterIdx]), + .wide_out_resp_i(wide_out_isolated_resp[extClusterIdx]) ); end : gen_clusters diff --git a/hw/chimera_cluster.sv b/hw/chimera_cluster.sv index d47717f..25283a4 100644 --- a/hw/chimera_cluster.sv +++ b/hw/chimera_cluster.sv @@ -3,6 +3,7 @@ // SPDX-License-Identifier: SHL-0.51 // // Moritz Scherer +// Lorenzo Leone module chimera_cluster import chimera_pkg::*; @@ -16,76 +17,49 @@ module chimera_cluster parameter type narrow_out_req_t = logic, parameter type narrow_out_resp_t = logic, parameter type wide_out_req_t = logic, - parameter type wide_out_resp_t = logic, - - // !! DO NOT OVERWRITE THESE PARAMETERS - // These parameters are used to provide a flattened interface for the AXI ports (see comments below). - parameter type narrow_in_resp_flat_t = logic [$bits(narrow_in_resp_t)-1:0], - parameter type narrow_out_req_flat_t = logic [$bits(narrow_out_req_t)-1:0], - parameter type wide_out_req_flat_t = logic [ $bits(wide_out_req_t)-1:0] + parameter type wide_out_resp_t = logic ) ( - input logic soc_clk_i, - input logic clu_clk_i, - input logic rst_ni, - input logic widemem_bypass_i, + input logic soc_clk_i, + input logic clu_clk_i, + input logic rst_ni, + input logic widemem_bypass_i, //----------------------------- // Interrupt ports //----------------------------- - input logic [ NrCores-1:0] debug_req_i, - input logic [ NrCores-1:0] meip_i, - input logic [ NrCores-1:0] mtip_i, - input logic [ NrCores-1:0] msip_i, + input logic [ NrCores-1:0] debug_req_i, + input logic [ NrCores-1:0] meip_i, + input logic [ NrCores-1:0] mtip_i, + input logic [ NrCores-1:0] msip_i, //----------------------------- // Cluster base addressing //----------------------------- - input logic [ 9:0] hart_base_id_i, - input logic [Cfg.AddrWidth-1:0] cluster_base_addr_i, - input logic [ 31:0] boot_addr_i, + input logic [ 9:0] hart_base_id_i, + input logic [Cfg.AddrWidth-1:0] cluster_base_addr_i, + input logic [ 31:0] boot_addr_i, //----------------------------- // Narrow AXI ports //----------------------------- - input narrow_in_req_t narrow_in_req_i, - output narrow_in_resp_flat_t narrow_in_resp_flat_o, - output narrow_out_req_flat_t [ 1:0] narrow_out_req_flat_o, - input narrow_out_resp_t [ 1:0] narrow_out_resp_i, + input narrow_in_req_t narrow_in_req_i, + output narrow_in_resp_t narrow_in_resp_o, + output narrow_out_req_t [ 1:0] narrow_out_req_o, + input narrow_out_resp_t [ 1:0] narrow_out_resp_i, //----------------------------- //Wide AXI ports //----------------------------- - output wide_out_req_flat_t wide_out_req_flat_o, - input wide_out_resp_t wide_out_resp_i + output wide_out_req_t wide_out_req_o, + input wide_out_resp_t wide_out_resp_i ); `include "axi/typedef.svh" - /* ------------------------------------------------------------------------------- */ - /* Flattened interface signals for UPF structure workaround */ - /* ------------------------------------------------------------------------------- */ - // - // The UPF standard supported by QuestaSim cannot apply isolation strategies to - // ports with "complex" types, such as AXI ports, which are structures. - // To address this issue, at the interface of each power domain, signals are flattened - // (e.g., narrow_in_resp_flat_o) and then internally reassigned to new structured signals - // (e.g., narrow_in_resp_s), which can be propagated to downstream modules. - // - narrow_out_req_t [1:0] narrow_out_req_s; - narrow_in_resp_t narrow_in_resp_s; - wide_out_req_t wide_out_req_s; - - assign narrow_out_req_flat_o = narrow_out_req_s; - assign narrow_in_resp_flat_o = narrow_in_resp_s; - assign wide_out_req_flat_o = wide_out_req_s; - - /* ------------------------------------------------------------------------------- */ - /* ------------------------------------------------------------------------------- */ - - localparam int WideDataWidth = $bits(wide_out_req_s.w.data); - - localparam int WideMasterIdWidth = $bits(wide_out_req_s.aw.id); + localparam int WideDataWidth = $bits(wide_out_req_o.w.data); + + localparam int WideMasterIdWidth = $bits(wide_out_req_o.aw.id); localparam int WideSlaveIdWidth = WideMasterIdWidth + $clog2(Cfg.AxiExtNumWideMst) - 1; localparam int NarrowSlaveIdWidth = $bits(narrow_in_req_i.aw.id); - localparam int NarrowMasterIdWidth = $bits(narrow_out_req_s[0].aw.id); + localparam int NarrowMasterIdWidth = $bits(narrow_out_req_o[0].aw.id); typedef logic [Cfg.AddrWidth-1:0] axi_addr_t; typedef logic [Cfg.AxiUserWidth-1:0] axi_user_t; @@ -167,8 +141,8 @@ module chimera_cluster // SoC side narrow. .narrow_in_req_i (narrow_in_req_i), - .narrow_in_resp_o (narrow_in_resp_s), - .narrow_out_req_o (narrow_out_req_s), + .narrow_in_resp_o (narrow_in_resp_o), + .narrow_out_req_o (narrow_out_req_o), .narrow_out_resp_i(narrow_out_resp_i), // Cluster side narrow @@ -182,8 +156,8 @@ module chimera_cluster end else begin : gen_skip_narrow_adapter // if (ClusterDataWidth != Cfg.AxiDataWidth) assign clu_axi_narrow_slv_req = narrow_in_req_i; - assign narrow_in_resp_s = clu_axi_narrow_slv_rsp; - assign narrow_out_req_s = clu_axi_narrow_mst_req; + assign narrow_in_resp_o = clu_axi_narrow_slv_rsp; + assign narrow_out_req_o = clu_axi_narrow_mst_req; assign clu_axi_narrow_mst_rsp = narrow_out_resp_i; end @@ -223,7 +197,7 @@ module chimera_cluster .clu_narrow_out_req_i (clu_axi_adapter_mst_req), .clu_narrow_out_resp_o(clu_axi_adapter_mst_resp), - .wide_out_req_o (wide_out_req_s), + .wide_out_req_o (wide_out_req_o), .wide_out_resp_i (wide_out_resp_i), .clu_wide_out_req_i (clu_axi_wide_mst_req), .clu_wide_out_resp_o(clu_axi_wide_mst_resp), diff --git a/hw/chimera_pkg.sv b/hw/chimera_pkg.sv index 1db0044..20c563d 100644 --- a/hw/chimera_pkg.sv +++ b/hw/chimera_pkg.sv @@ -59,6 +59,9 @@ package chimera_pkg; localparam aw_bt ClusterNarrowAxiMstIdWidth = 1; + // Power Aware Simulation Configuration Enable + localparam int unsigned Pasim = 0; + function automatic cheshire_cfg_t gen_chimera_cfg(); localparam int AddrWidth = DefaultCfg.AddrWidth; diff --git a/hw/chimera_top_wrapper.sv b/hw/chimera_top_wrapper.sv index d3ac121..cb66857 100644 --- a/hw/chimera_top_wrapper.sv +++ b/hw/chimera_top_wrapper.sv @@ -11,51 +11,56 @@ 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, // 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 ); @@ -316,7 +321,7 @@ module chimera_top_wrapper ) i_cluster_domain ( .soc_clk_i (soc_clk_i), .clu_clk_i (clu_clk_gated), - .rst_ni, + .rst_sync_ni (pmu_rst_clusters_ni), .widemem_bypass_i (wide_mem_bypass_mode), .debug_req_i (dbg_ext_req), .xeip_i (xeip_ext), @@ -327,8 +332,9 @@ module chimera_top_wrapper .narrow_out_req_o (axi_mst_req), .narrow_out_resp_i(axi_mst_rsp), .wide_out_req_o (axi_wide_mst_req), - .wide_out_resp_i (axi_wide_mst_rsp) - + .wide_out_resp_i (axi_wide_mst_rsp), + .isolate_i (pmu_iso_en_clusters_i), + .isolate_o (pmu_iso_ack_clusters_o) ); endmodule diff --git a/target/sim/src/fixture_chimera_soc.sv b/target/sim/src/fixture_chimera_soc.sv index 7f50aaf..ab4676a 100644 --- a/target/sim/src/fixture_chimera_soc.sv +++ b/target/sim/src/fixture_chimera_soc.sv @@ -61,42 +61,46 @@ module fixture_chimera_soc #( chimera_top_wrapper #( .SelectedCfg(SelectedCfg) ) dut ( - .soc_clk_i (soc_clk), - .clu_clk_i (clu_clk), - .rst_ni (rst_n), - .test_mode_i (test_mode), - .boot_mode_i (boot_mode), - .rtc_i (rtc), - .jtag_tck_i (jtag_tck), - .jtag_trst_ni (jtag_trst_n), - .jtag_tms_i (jtag_tms), - .jtag_tdi_i (jtag_tdi), - .jtag_tdo_o (jtag_tdo), - .jtag_tdo_oe_o(), - .uart_tx_o (uart_tx), - .uart_rx_i (uart_rx), - .uart_rts_no (), - .uart_dtr_no (), - .uart_cts_ni (1'b0), - .uart_dsr_ni (1'b0), - .uart_dcd_ni (1'b0), - .uart_rin_ni (1'b0), - .i2c_sda_o (i2c_sda_o), - .i2c_sda_i (i2c_sda_i), - .i2c_sda_en_o (i2c_sda_en), - .i2c_scl_o (i2c_scl_o), - .i2c_scl_i (i2c_scl_i), - .i2c_scl_en_o (i2c_scl_en), - .spih_sck_o (spih_sck_o), - .spih_sck_en_o(spih_sck_en), - .spih_csb_o (spih_csb_o), - .spih_csb_en_o(spih_csb_en), - .spih_sd_o (spih_sd_o), - .spih_sd_en_o (spih_sd_en), - .spih_sd_i (spih_sd_i), - .gpio_i ('0), - .gpio_o (), - .gpio_en_o () + .soc_clk_i (soc_clk), + .clu_clk_i (clu_clk), + .rst_ni (rst_n), + .test_mode_i (test_mode), + .boot_mode_i (boot_mode), + .rtc_i (rtc), + .jtag_tck_i (jtag_tck), + .jtag_trst_ni (jtag_trst_n), + .jtag_tms_i (jtag_tms), + .jtag_tdi_i (jtag_tdi), + .jtag_tdo_o (jtag_tdo), + .jtag_tdo_oe_o (), + .uart_tx_o (uart_tx), + .uart_rx_i (uart_rx), + .uart_rts_no (), + .uart_dtr_no (), + .uart_cts_ni (1'b0), + .uart_dsr_ni (1'b0), + .uart_dcd_ni (1'b0), + .uart_rin_ni (1'b0), + .i2c_sda_o (i2c_sda_o), + .i2c_sda_i (i2c_sda_i), + .i2c_sda_en_o (i2c_sda_en), + .i2c_scl_o (i2c_scl_o), + .i2c_scl_i (i2c_scl_i), + .i2c_scl_en_o (i2c_scl_en), + .spih_sck_o (spih_sck_o), + .spih_sck_en_o (spih_sck_en), + .spih_csb_o (spih_csb_o), + .spih_csb_en_o (spih_csb_en), + .spih_sd_o (spih_sd_o), + .spih_sd_en_o (spih_sd_en), + .spih_sd_i (spih_sd_i), + .gpio_i ('0), + .gpio_o (), + .gpio_en_o (), + .pmu_rst_clusters_ni ({ExtClusters{rst_n}}), + .pmu_clkgate_en_clusters_i(), + .pmu_iso_en_clusters_i ('0), // Never Isolate + .pmu_iso_ack_clusters_o () ); ////////////////////////