Skip to content

Commit

Permalink
hw: Add native bootrom (#168)
Browse files Browse the repository at this point in the history
---------

Co-authored-by: Thierry Dubochet <[email protected]>
Co-authored-by: Milos Hirsl <[email protected]>
Co-authored-by: Luca Colagrande <[email protected]>
  • Loading branch information
4 people authored Jan 28, 2025
1 parent 1b9da15 commit c7eb9c2
Show file tree
Hide file tree
Showing 39 changed files with 781 additions and 280 deletions.
2 changes: 2 additions & 0 deletions Bender.yml
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,7 @@ sources:
- hw/snitch_cluster/src/snitch_fpu.sv
- hw/snitch_cluster/src/snitch_sequencer.sv
- hw/snitch_cluster/src/snitch_tcdm_interconnect.sv
- target/snitch_cluster/test/snitch_bootrom.sv
# Level 1
- hw/snitch_cluster/src/snitch_barrier.sv
- hw/snitch_cluster/src/snitch_fp_ss.sv
Expand Down Expand Up @@ -189,4 +190,5 @@ sources:
- target/snitch_cluster/generated/snitch_cluster_wrapper.sv
- target: all(snitch_cluster, any(simulation, verilator))
files:
- target/snitch_cluster/test/vip_snitch_cluster.sv
- target/snitch_cluster/test/testharness.sv
3 changes: 2 additions & 1 deletion hw/snitch/src/snitch_pkg.sv
Original file line number Diff line number Diff line change
Expand Up @@ -139,7 +139,8 @@ package snitch_pkg;
typedef enum int unsigned {
TCDMDMA = 0,
SoCDMAOut = 1,
ZeroMemory = 2
ZeroMemory = 2,
BootRom = 3
} cluster_slave_dma_e;

typedef enum int unsigned {
Expand Down
131 changes: 94 additions & 37 deletions hw/snitch_cluster/src/snitch_cluster.sv
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,8 @@ module snitch_cluster
parameter int unsigned NarrowUserWidth = 1,
/// AXI: dma user width.
parameter int unsigned WideUserWidth = 1,
/// Address from which to fetch the first instructions.
/// Boot Address from which to fetch the first instructions.
/// Used if `AliasRegionEnable` or `IntBootromEnable` is not set.
parameter logic [31:0] BootAddr = 32'h0,
/// Number of Hives. Each Hive can hold 1-many cores.
parameter int unsigned NrHives = 1,
Expand All @@ -47,6 +48,8 @@ module snitch_cluster
parameter int unsigned TCDMDepth = 1024,
/// Zero memory address region size (in kB).
parameter int unsigned ZeroMemorySize = 64,
/// Bootrom memory address region size (in kB).
parameter int unsigned BootRomSize = 4,
/// Cluster peripheral address region size (in kB).
parameter int unsigned ClusterPeriphSize = 64,
/// Number of TCDM Banks. It is recommended to have twice the number of banks
Expand Down Expand Up @@ -195,7 +198,9 @@ module snitch_cluster
parameter bit DebugSupport = 1,
/// Optional fixed cluster alias region.
parameter bit AliasRegionEnable = 1'b0,
parameter logic [PhysicalAddrWidth-1:0] AliasRegionBase = '0
parameter logic [PhysicalAddrWidth-1:0] AliasRegionBase = '0,
/// Instantiate internal bootrom.
parameter bit IntBootromEnable = 1'b1
) (
/// System clock. If `IsoCrossing` is enabled this port is the _fast_ clock.
/// The slower, half-frequency clock, is derived internally.
Expand Down Expand Up @@ -276,11 +281,12 @@ module snitch_cluster
localparam int unsigned NrRuleIdcs = NrSlaves - 1;
localparam int unsigned NrRules = (1 + AliasRegionEnable) * NrRuleIdcs;

// SoC Request, DMA Channels, `n` instruction caches.
// DMA X-BAR configuration
// SoC in Request, DMA Channels, `n` instruction caches.
localparam int unsigned NrWideMasters = 1 + DMANumChannels + NrHives;
localparam int unsigned WideIdWidthOut = $clog2(NrWideMasters) + WideIdWidthIn;
// DMA X-BAR configuration
localparam int unsigned NrWideSlaves = 3;
// TCDM, SoC out, ZeroMemory, (Bootrom)
localparam int unsigned NrWideSlaves = 3 + IntBootromEnable;
localparam int unsigned NrWideRuleIdcs = NrWideSlaves - 1;
localparam int unsigned NrWideRules = (1 + AliasRegionEnable) * NrWideRuleIdcs;

Expand Down Expand Up @@ -459,9 +465,13 @@ module snitch_cluster
assign tcdm_start_address = (cluster_base_addr_i & TCDMMask);
assign tcdm_end_address = (tcdm_start_address + TCDMSize) & TCDMMask;

addr_t bootrom_start_address, bootrom_end_address;
assign bootrom_start_address = tcdm_end_address;
assign bootrom_end_address = tcdm_end_address + BootRomSize * 1024;

addr_t cluster_periph_start_address, cluster_periph_end_address;
assign cluster_periph_start_address = tcdm_end_address;
assign cluster_periph_end_address = tcdm_end_address + ClusterPeriphSize * 1024;
assign cluster_periph_start_address = IntBootromEnable ? bootrom_end_address : tcdm_end_address;
assign cluster_periph_end_address = cluster_periph_start_address + ClusterPeriphSize * 1024;

addr_t zero_mem_start_address, zero_mem_end_address;
assign zero_mem_start_address = cluster_periph_end_address;
Expand All @@ -470,8 +480,11 @@ module snitch_cluster
localparam addr_t TCDMAliasStart = AliasRegionBase & TCDMMask;
localparam addr_t TCDMAliasEnd = (TCDMAliasStart + TCDMSize) & TCDMMask;

localparam addr_t PeriphAliasStart = TCDMAliasEnd;
localparam addr_t PeriphAliasEnd = TCDMAliasEnd + ClusterPeriphSize * 1024;
localparam addr_t BootRomAliasStart = TCDMAliasEnd;
localparam addr_t BootRomAliasEnd = BootRomAliasStart + BootRomSize * 1024;

localparam addr_t PeriphAliasStart = IntBootromEnable ? BootRomAliasEnd : TCDMAliasEnd;
localparam addr_t PeriphAliasEnd = PeriphAliasStart + ClusterPeriphSize * 1024;

localparam addr_t ZeroMemAliasStart = PeriphAliasEnd;
localparam addr_t ZeroMemAliasEnd = PeriphAliasEnd + ZeroMemorySize * 1024;
Expand Down Expand Up @@ -572,34 +585,30 @@ module snitch_cluster
);

logic [DmaXbarCfg.NoSlvPorts-1:0][$clog2(DmaXbarCfg.NoMstPorts)-1:0] dma_xbar_default_port;
xbar_rule_t [DmaXbarCfg.NoAddrRules-1:0] dma_xbar_rule;

assign dma_xbar_default_port = '{default: SoCDMAOut};
assign dma_xbar_rule[NrWideRuleIdcs-1:0] = '{
'{
idx: TCDMDMA,
start_addr: tcdm_start_address,
end_addr: tcdm_end_address
},
'{
idx: ZeroMemory,
start_addr: zero_mem_start_address,
end_addr: zero_mem_end_address
}

xbar_rule_t [5:0] dma_xbar_rules;
xbar_rule_t [DmaXbarCfg.NoAddrRules-1:0] enabled_dma_xbar_rule;

assign dma_xbar_rules = '{
'{idx: TCDMDMA, start_addr: tcdm_start_address, end_addr: tcdm_end_address},
'{idx: ZeroMemory, start_addr: zero_mem_start_address, end_addr: zero_mem_end_address},
'{idx: BootRom, start_addr: bootrom_start_address, end_addr: bootrom_end_address},
'{idx: TCDMDMA, start_addr: TCDMAliasStart, end_addr: TCDMAliasEnd},
'{idx: ZeroMemory, start_addr: ZeroMemAliasStart, end_addr: ZeroMemAliasEnd},
'{idx: BootRom, start_addr: BootRomAliasStart, end_addr: BootRomAliasEnd}
};
if (AliasRegionEnable) begin : gen_dma_xbar_alias
assign dma_xbar_rule [NrWideRules-1:NrWideRuleIdcs] = '{
'{
idx: TCDMDMA,
start_addr: TCDMAliasStart,
end_addr: TCDMAliasEnd
},
'{
idx: ZeroMemory,
start_addr: ZeroMemAliasStart,
end_addr: ZeroMemAliasEnd
}
};

always_comb begin
automatic int unsigned i = 0;
enabled_dma_xbar_rule[i] = dma_xbar_rules[0]; i++; // TCDM
enabled_dma_xbar_rule[i] = dma_xbar_rules[1]; i++; // ZeroMemory
if (IntBootromEnable) enabled_dma_xbar_rule[i] = dma_xbar_rules[2]; i++; // Bootrom
if (AliasRegionEnable) begin
enabled_dma_xbar_rule[i] = dma_xbar_rules[3]; i++; // TCDM Alias
enabled_dma_xbar_rule[i] = dma_xbar_rules[4]; i++; // ZeroMemory Alias
if (IntBootromEnable) enabled_dma_xbar_rule[i] = dma_xbar_rules[5]; // Bootrom Alias
end
end

localparam bit [DmaXbarCfg.NoSlvPorts-1:0] DMAEnableDefaultMstPort = '1;
Expand Down Expand Up @@ -628,7 +637,7 @@ module snitch_cluster
.slv_ports_resp_o (wide_axi_mst_rsp),
.mst_ports_req_o (wide_axi_slv_req),
.mst_ports_resp_i (wide_axi_slv_rsp),
.addr_map_i (dma_xbar_rule),
.addr_map_i (enabled_dma_xbar_rule),
.en_default_mst_port_i (DMAEnableDefaultMstPort),
.default_mst_port_i (dma_xbar_default_port)
);
Expand Down Expand Up @@ -857,6 +866,9 @@ module snitch_cluster

tcdm_req_t [TcdmPorts-1:0] tcdm_req_wo_user;

parameter logic [31:0] BootAddrInternal = (AliasRegionEnable & IntBootromEnable) ?
BootRomAliasStart : BootAddr;

snitch_cc #(
.AddrWidth (PhysicalAddrWidth),
.DataWidth (NarrowDataWidth),
Expand All @@ -881,7 +893,7 @@ module snitch_cluster
.acc_req_t (acc_req_t),
.acc_resp_t (acc_resp_t),
.dma_events_t (dma_events_t),
.BootAddr (BootAddr),
.BootAddr (BootAddrInternal),
.RVE (RVE[i]),
.RVF (RVF[i]),
.RVD (RVD[i]),
Expand Down Expand Up @@ -1236,6 +1248,51 @@ module snitch_cluster
.reg_rsp_i (reg_rsp)
);

if (IntBootromEnable) begin : gen_bootrom

addr_t bootrom_addr;
data_dma_t bootrom_data, bootrom_data_q;
logic bootrom_req, bootrom_req_q;

`FF(bootrom_data_q, bootrom_data, '0, clk_i, rst_ni)
`FF(bootrom_req_q, bootrom_req, '0, clk_i, rst_ni)

axi_to_mem #(
.axi_req_t (axi_slv_dma_req_t),
.axi_resp_t (axi_slv_dma_resp_t),
.AddrWidth (PhysicalAddrWidth),
.DataWidth (WideDataWidth),
.IdWidth (WideIdWidthOut),
.NumBanks (1)
) i_axi_to_mem (
.clk_i (clk_i),
.rst_ni (rst_ni),
.busy_o (),
.axi_req_i (wide_axi_slv_req[BootRom]),
.axi_resp_o (wide_axi_slv_rsp[BootRom]),
.mem_req_o (bootrom_req),
.mem_gnt_i (bootrom_req),
.mem_addr_o (bootrom_addr),
.mem_wdata_o (),
.mem_strb_o (),
.mem_atop_o (),
.mem_we_o (),
.mem_rvalid_i (bootrom_req_q),
.mem_rdata_i (bootrom_data_q)
);

snitch_bootrom #(
.AddrWidth (PhysicalAddrWidth),
.DataWidth (WideDataWidth),
.BootromSize (BootRomSize * 1024)
) i_bootrom (
.clk_i (clk_i),
.rst_ni (rst_ni),
.addr_i (bootrom_addr),
.data_o (bootrom_data)
);
end

snitch_cluster_peripheral #(
.reg_req_t (reg_req_t),
.reg_rsp_t (reg_rsp_t),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,17 @@
// Licensed under Solderpad Hardware License, Version 0.51, see LICENSE for details.
{
param_list: [
{ name: "NumPerfCounters",
desc: "Number of performance counters",
type: "int",
default: "16"
{
name: "NumPerfCounters",
desc: "Number of performance counters",
type: "int",
default: "16"
},
{
name: "NumCtrlScratch",
desc: "Number of scratch registers",
type: "int",
default: "4"
},
],
name: "snitch_cluster_peripheral",
Expand Down Expand Up @@ -303,6 +310,22 @@
}]
}
},
{
multireg: {
name: "SCRATCH",
desc: '''Scratch registers. Used in the bootrom for various purposes.'''
swaccess: "rw",
hwaccess: "none",
count: "NumCtrlScratch",
cname: "ctrl_scratch",
compact: "false",
fields: [{
bits: "31:0",
name: "SCRATCH",
desc: "Scratch register"
}]
}
},
{
name: "CL_CLINT_SET",
desc: '''
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ package snitch_cluster_peripheral_reg_pkg;

// Param list
parameter int NumPerfCounters = 16;
parameter int NumCtrlScratch = 4;

// Address widths within the block
parameter int BlockAw = 9;
Expand Down Expand Up @@ -128,9 +129,13 @@ package snitch_cluster_peripheral_reg_pkg;
parameter logic [BlockAw-1:0] SNITCH_CLUSTER_PERIPHERAL_PERF_CNT_13_OFFSET = 9'h 168;
parameter logic [BlockAw-1:0] SNITCH_CLUSTER_PERIPHERAL_PERF_CNT_14_OFFSET = 9'h 170;
parameter logic [BlockAw-1:0] SNITCH_CLUSTER_PERIPHERAL_PERF_CNT_15_OFFSET = 9'h 178;
parameter logic [BlockAw-1:0] SNITCH_CLUSTER_PERIPHERAL_CL_CLINT_SET_OFFSET = 9'h 180;
parameter logic [BlockAw-1:0] SNITCH_CLUSTER_PERIPHERAL_CL_CLINT_CLEAR_OFFSET = 9'h 188;
parameter logic [BlockAw-1:0] SNITCH_CLUSTER_PERIPHERAL_ICACHE_PREFETCH_ENABLE_OFFSET = 9'h 190;
parameter logic [BlockAw-1:0] SNITCH_CLUSTER_PERIPHERAL_SCRATCH_0_OFFSET = 9'h 180;
parameter logic [BlockAw-1:0] SNITCH_CLUSTER_PERIPHERAL_SCRATCH_1_OFFSET = 9'h 188;
parameter logic [BlockAw-1:0] SNITCH_CLUSTER_PERIPHERAL_SCRATCH_2_OFFSET = 9'h 190;
parameter logic [BlockAw-1:0] SNITCH_CLUSTER_PERIPHERAL_SCRATCH_3_OFFSET = 9'h 198;
parameter logic [BlockAw-1:0] SNITCH_CLUSTER_PERIPHERAL_CL_CLINT_SET_OFFSET = 9'h 1a0;
parameter logic [BlockAw-1:0] SNITCH_CLUSTER_PERIPHERAL_CL_CLINT_CLEAR_OFFSET = 9'h 1a8;
parameter logic [BlockAw-1:0] SNITCH_CLUSTER_PERIPHERAL_ICACHE_PREFETCH_ENABLE_OFFSET = 9'h 1b0;

// Reset values for hwext registers and their fields
parameter logic [31:0] SNITCH_CLUSTER_PERIPHERAL_PERF_CNT_SEL_0_RESVAL = 32'h 0;
Expand Down Expand Up @@ -218,13 +223,17 @@ package snitch_cluster_peripheral_reg_pkg;
SNITCH_CLUSTER_PERIPHERAL_PERF_CNT_13,
SNITCH_CLUSTER_PERIPHERAL_PERF_CNT_14,
SNITCH_CLUSTER_PERIPHERAL_PERF_CNT_15,
SNITCH_CLUSTER_PERIPHERAL_SCRATCH_0,
SNITCH_CLUSTER_PERIPHERAL_SCRATCH_1,
SNITCH_CLUSTER_PERIPHERAL_SCRATCH_2,
SNITCH_CLUSTER_PERIPHERAL_SCRATCH_3,
SNITCH_CLUSTER_PERIPHERAL_CL_CLINT_SET,
SNITCH_CLUSTER_PERIPHERAL_CL_CLINT_CLEAR,
SNITCH_CLUSTER_PERIPHERAL_ICACHE_PREFETCH_ENABLE
} snitch_cluster_peripheral_id_e;

// Register width information to check illegal writes
parameter logic [3:0] SNITCH_CLUSTER_PERIPHERAL_PERMIT [51] = '{
parameter logic [3:0] SNITCH_CLUSTER_PERIPHERAL_PERMIT [55] = '{
4'b 0001, // index[ 0] SNITCH_CLUSTER_PERIPHERAL_PERF_CNT_EN_0
4'b 0001, // index[ 1] SNITCH_CLUSTER_PERIPHERAL_PERF_CNT_EN_1
4'b 0001, // index[ 2] SNITCH_CLUSTER_PERIPHERAL_PERF_CNT_EN_2
Expand Down Expand Up @@ -273,9 +282,13 @@ package snitch_cluster_peripheral_reg_pkg;
4'b 1111, // index[45] SNITCH_CLUSTER_PERIPHERAL_PERF_CNT_13
4'b 1111, // index[46] SNITCH_CLUSTER_PERIPHERAL_PERF_CNT_14
4'b 1111, // index[47] SNITCH_CLUSTER_PERIPHERAL_PERF_CNT_15
4'b 1111, // index[48] SNITCH_CLUSTER_PERIPHERAL_CL_CLINT_SET
4'b 1111, // index[49] SNITCH_CLUSTER_PERIPHERAL_CL_CLINT_CLEAR
4'b 0001 // index[50] SNITCH_CLUSTER_PERIPHERAL_ICACHE_PREFETCH_ENABLE
4'b 1111, // index[48] SNITCH_CLUSTER_PERIPHERAL_SCRATCH_0
4'b 1111, // index[49] SNITCH_CLUSTER_PERIPHERAL_SCRATCH_1
4'b 1111, // index[50] SNITCH_CLUSTER_PERIPHERAL_SCRATCH_2
4'b 1111, // index[51] SNITCH_CLUSTER_PERIPHERAL_SCRATCH_3
4'b 1111, // index[52] SNITCH_CLUSTER_PERIPHERAL_CL_CLINT_SET
4'b 1111, // index[53] SNITCH_CLUSTER_PERIPHERAL_CL_CLINT_CLEAR
4'b 0001 // index[54] SNITCH_CLUSTER_PERIPHERAL_ICACHE_PREFETCH_ENABLE
};

endpackage
Expand Down
Loading

0 comments on commit c7eb9c2

Please sign in to comment.