Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Lleone/pmu #40

Merged
merged 1 commit into from
Sep 26, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
141 changes: 132 additions & 9 deletions hw/chimera_clu_domain.sv
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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 (IsolateClusters == 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)),
Expand All @@ -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)]),
Expand All @@ -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
Expand Down
82 changes: 28 additions & 54 deletions hw/chimera_cluster.sv
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
// SPDX-License-Identifier: SHL-0.51
//
// Moritz Scherer <scheremo@iis.ee.ethz.ch>
// Lorenzo Leone <lleone@iis.ee.ethz.ch>

module chimera_cluster
import chimera_pkg::*;
Expand All @@ -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;
Expand Down Expand Up @@ -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
Expand All @@ -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
Expand Down Expand Up @@ -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),
Expand Down
3 changes: 3 additions & 0 deletions hw/chimera_pkg.sv
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,9 @@ package chimera_pkg;

localparam aw_bt ClusterNarrowAxiMstIdWidth = 1;

// Isolate Clusters from SoC
localparam int unsigned IsolateClusters = 0;

function automatic cheshire_cfg_t gen_chimera_cfg();
localparam int AddrWidth = DefaultCfg.AddrWidth;

Expand Down
Loading
Loading