Skip to content

Commit c7eb9c2

Browse files
fischetiThierry DubochetMilosHirslcolluca
authored
hw: Add native bootrom (#168)
--------- Co-authored-by: Thierry Dubochet <tdubochet@student.ethz.ch> Co-authored-by: Milos Hirsl <mhirsl@student.ethz.ch> Co-authored-by: Luca Colagrande <luca.colagrande3@gmail.com>
1 parent 1b9da15 commit c7eb9c2

39 files changed

+781
-280
lines changed

Bender.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -159,6 +159,7 @@ sources:
159159
- hw/snitch_cluster/src/snitch_fpu.sv
160160
- hw/snitch_cluster/src/snitch_sequencer.sv
161161
- hw/snitch_cluster/src/snitch_tcdm_interconnect.sv
162+
- target/snitch_cluster/test/snitch_bootrom.sv
162163
# Level 1
163164
- hw/snitch_cluster/src/snitch_barrier.sv
164165
- hw/snitch_cluster/src/snitch_fp_ss.sv
@@ -189,4 +190,5 @@ sources:
189190
- target/snitch_cluster/generated/snitch_cluster_wrapper.sv
190191
- target: all(snitch_cluster, any(simulation, verilator))
191192
files:
193+
- target/snitch_cluster/test/vip_snitch_cluster.sv
192194
- target/snitch_cluster/test/testharness.sv

hw/snitch/src/snitch_pkg.sv

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -139,7 +139,8 @@ package snitch_pkg;
139139
typedef enum int unsigned {
140140
TCDMDMA = 0,
141141
SoCDMAOut = 1,
142-
ZeroMemory = 2
142+
ZeroMemory = 2,
143+
BootRom = 3
143144
} cluster_slave_dma_e;
144145

145146
typedef enum int unsigned {

hw/snitch_cluster/src/snitch_cluster.sv

Lines changed: 94 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,8 @@ module snitch_cluster
3737
parameter int unsigned NarrowUserWidth = 1,
3838
/// AXI: dma user width.
3939
parameter int unsigned WideUserWidth = 1,
40-
/// Address from which to fetch the first instructions.
40+
/// Boot Address from which to fetch the first instructions.
41+
/// Used if `AliasRegionEnable` or `IntBootromEnable` is not set.
4142
parameter logic [31:0] BootAddr = 32'h0,
4243
/// Number of Hives. Each Hive can hold 1-many cores.
4344
parameter int unsigned NrHives = 1,
@@ -47,6 +48,8 @@ module snitch_cluster
4748
parameter int unsigned TCDMDepth = 1024,
4849
/// Zero memory address region size (in kB).
4950
parameter int unsigned ZeroMemorySize = 64,
51+
/// Bootrom memory address region size (in kB).
52+
parameter int unsigned BootRomSize = 4,
5053
/// Cluster peripheral address region size (in kB).
5154
parameter int unsigned ClusterPeriphSize = 64,
5255
/// Number of TCDM Banks. It is recommended to have twice the number of banks
@@ -195,7 +198,9 @@ module snitch_cluster
195198
parameter bit DebugSupport = 1,
196199
/// Optional fixed cluster alias region.
197200
parameter bit AliasRegionEnable = 1'b0,
198-
parameter logic [PhysicalAddrWidth-1:0] AliasRegionBase = '0
201+
parameter logic [PhysicalAddrWidth-1:0] AliasRegionBase = '0,
202+
/// Instantiate internal bootrom.
203+
parameter bit IntBootromEnable = 1'b1
199204
) (
200205
/// System clock. If `IsoCrossing` is enabled this port is the _fast_ clock.
201206
/// The slower, half-frequency clock, is derived internally.
@@ -276,11 +281,12 @@ module snitch_cluster
276281
localparam int unsigned NrRuleIdcs = NrSlaves - 1;
277282
localparam int unsigned NrRules = (1 + AliasRegionEnable) * NrRuleIdcs;
278283

279-
// SoC Request, DMA Channels, `n` instruction caches.
284+
// DMA X-BAR configuration
285+
// SoC in Request, DMA Channels, `n` instruction caches.
280286
localparam int unsigned NrWideMasters = 1 + DMANumChannels + NrHives;
281287
localparam int unsigned WideIdWidthOut = $clog2(NrWideMasters) + WideIdWidthIn;
282-
// DMA X-BAR configuration
283-
localparam int unsigned NrWideSlaves = 3;
288+
// TCDM, SoC out, ZeroMemory, (Bootrom)
289+
localparam int unsigned NrWideSlaves = 3 + IntBootromEnable;
284290
localparam int unsigned NrWideRuleIdcs = NrWideSlaves - 1;
285291
localparam int unsigned NrWideRules = (1 + AliasRegionEnable) * NrWideRuleIdcs;
286292

@@ -459,9 +465,13 @@ module snitch_cluster
459465
assign tcdm_start_address = (cluster_base_addr_i & TCDMMask);
460466
assign tcdm_end_address = (tcdm_start_address + TCDMSize) & TCDMMask;
461467

468+
addr_t bootrom_start_address, bootrom_end_address;
469+
assign bootrom_start_address = tcdm_end_address;
470+
assign bootrom_end_address = tcdm_end_address + BootRomSize * 1024;
471+
462472
addr_t cluster_periph_start_address, cluster_periph_end_address;
463-
assign cluster_periph_start_address = tcdm_end_address;
464-
assign cluster_periph_end_address = tcdm_end_address + ClusterPeriphSize * 1024;
473+
assign cluster_periph_start_address = IntBootromEnable ? bootrom_end_address : tcdm_end_address;
474+
assign cluster_periph_end_address = cluster_periph_start_address + ClusterPeriphSize * 1024;
465475

466476
addr_t zero_mem_start_address, zero_mem_end_address;
467477
assign zero_mem_start_address = cluster_periph_end_address;
@@ -470,8 +480,11 @@ module snitch_cluster
470480
localparam addr_t TCDMAliasStart = AliasRegionBase & TCDMMask;
471481
localparam addr_t TCDMAliasEnd = (TCDMAliasStart + TCDMSize) & TCDMMask;
472482

473-
localparam addr_t PeriphAliasStart = TCDMAliasEnd;
474-
localparam addr_t PeriphAliasEnd = TCDMAliasEnd + ClusterPeriphSize * 1024;
483+
localparam addr_t BootRomAliasStart = TCDMAliasEnd;
484+
localparam addr_t BootRomAliasEnd = BootRomAliasStart + BootRomSize * 1024;
485+
486+
localparam addr_t PeriphAliasStart = IntBootromEnable ? BootRomAliasEnd : TCDMAliasEnd;
487+
localparam addr_t PeriphAliasEnd = PeriphAliasStart + ClusterPeriphSize * 1024;
475488

476489
localparam addr_t ZeroMemAliasStart = PeriphAliasEnd;
477490
localparam addr_t ZeroMemAliasEnd = PeriphAliasEnd + ZeroMemorySize * 1024;
@@ -572,34 +585,30 @@ module snitch_cluster
572585
);
573586

574587
logic [DmaXbarCfg.NoSlvPorts-1:0][$clog2(DmaXbarCfg.NoMstPorts)-1:0] dma_xbar_default_port;
575-
xbar_rule_t [DmaXbarCfg.NoAddrRules-1:0] dma_xbar_rule;
576-
577588
assign dma_xbar_default_port = '{default: SoCDMAOut};
578-
assign dma_xbar_rule[NrWideRuleIdcs-1:0] = '{
579-
'{
580-
idx: TCDMDMA,
581-
start_addr: tcdm_start_address,
582-
end_addr: tcdm_end_address
583-
},
584-
'{
585-
idx: ZeroMemory,
586-
start_addr: zero_mem_start_address,
587-
end_addr: zero_mem_end_address
588-
}
589+
590+
xbar_rule_t [5:0] dma_xbar_rules;
591+
xbar_rule_t [DmaXbarCfg.NoAddrRules-1:0] enabled_dma_xbar_rule;
592+
593+
assign dma_xbar_rules = '{
594+
'{idx: TCDMDMA, start_addr: tcdm_start_address, end_addr: tcdm_end_address},
595+
'{idx: ZeroMemory, start_addr: zero_mem_start_address, end_addr: zero_mem_end_address},
596+
'{idx: BootRom, start_addr: bootrom_start_address, end_addr: bootrom_end_address},
597+
'{idx: TCDMDMA, start_addr: TCDMAliasStart, end_addr: TCDMAliasEnd},
598+
'{idx: ZeroMemory, start_addr: ZeroMemAliasStart, end_addr: ZeroMemAliasEnd},
599+
'{idx: BootRom, start_addr: BootRomAliasStart, end_addr: BootRomAliasEnd}
589600
};
590-
if (AliasRegionEnable) begin : gen_dma_xbar_alias
591-
assign dma_xbar_rule [NrWideRules-1:NrWideRuleIdcs] = '{
592-
'{
593-
idx: TCDMDMA,
594-
start_addr: TCDMAliasStart,
595-
end_addr: TCDMAliasEnd
596-
},
597-
'{
598-
idx: ZeroMemory,
599-
start_addr: ZeroMemAliasStart,
600-
end_addr: ZeroMemAliasEnd
601-
}
602-
};
601+
602+
always_comb begin
603+
automatic int unsigned i = 0;
604+
enabled_dma_xbar_rule[i] = dma_xbar_rules[0]; i++; // TCDM
605+
enabled_dma_xbar_rule[i] = dma_xbar_rules[1]; i++; // ZeroMemory
606+
if (IntBootromEnable) enabled_dma_xbar_rule[i] = dma_xbar_rules[2]; i++; // Bootrom
607+
if (AliasRegionEnable) begin
608+
enabled_dma_xbar_rule[i] = dma_xbar_rules[3]; i++; // TCDM Alias
609+
enabled_dma_xbar_rule[i] = dma_xbar_rules[4]; i++; // ZeroMemory Alias
610+
if (IntBootromEnable) enabled_dma_xbar_rule[i] = dma_xbar_rules[5]; // Bootrom Alias
611+
end
603612
end
604613

605614
localparam bit [DmaXbarCfg.NoSlvPorts-1:0] DMAEnableDefaultMstPort = '1;
@@ -628,7 +637,7 @@ module snitch_cluster
628637
.slv_ports_resp_o (wide_axi_mst_rsp),
629638
.mst_ports_req_o (wide_axi_slv_req),
630639
.mst_ports_resp_i (wide_axi_slv_rsp),
631-
.addr_map_i (dma_xbar_rule),
640+
.addr_map_i (enabled_dma_xbar_rule),
632641
.en_default_mst_port_i (DMAEnableDefaultMstPort),
633642
.default_mst_port_i (dma_xbar_default_port)
634643
);
@@ -857,6 +866,9 @@ module snitch_cluster
857866

858867
tcdm_req_t [TcdmPorts-1:0] tcdm_req_wo_user;
859868

869+
parameter logic [31:0] BootAddrInternal = (AliasRegionEnable & IntBootromEnable) ?
870+
BootRomAliasStart : BootAddr;
871+
860872
snitch_cc #(
861873
.AddrWidth (PhysicalAddrWidth),
862874
.DataWidth (NarrowDataWidth),
@@ -881,7 +893,7 @@ module snitch_cluster
881893
.acc_req_t (acc_req_t),
882894
.acc_resp_t (acc_resp_t),
883895
.dma_events_t (dma_events_t),
884-
.BootAddr (BootAddr),
896+
.BootAddr (BootAddrInternal),
885897
.RVE (RVE[i]),
886898
.RVF (RVF[i]),
887899
.RVD (RVD[i]),
@@ -1236,6 +1248,51 @@ module snitch_cluster
12361248
.reg_rsp_i (reg_rsp)
12371249
);
12381250

1251+
if (IntBootromEnable) begin : gen_bootrom
1252+
1253+
addr_t bootrom_addr;
1254+
data_dma_t bootrom_data, bootrom_data_q;
1255+
logic bootrom_req, bootrom_req_q;
1256+
1257+
`FF(bootrom_data_q, bootrom_data, '0, clk_i, rst_ni)
1258+
`FF(bootrom_req_q, bootrom_req, '0, clk_i, rst_ni)
1259+
1260+
axi_to_mem #(
1261+
.axi_req_t (axi_slv_dma_req_t),
1262+
.axi_resp_t (axi_slv_dma_resp_t),
1263+
.AddrWidth (PhysicalAddrWidth),
1264+
.DataWidth (WideDataWidth),
1265+
.IdWidth (WideIdWidthOut),
1266+
.NumBanks (1)
1267+
) i_axi_to_mem (
1268+
.clk_i (clk_i),
1269+
.rst_ni (rst_ni),
1270+
.busy_o (),
1271+
.axi_req_i (wide_axi_slv_req[BootRom]),
1272+
.axi_resp_o (wide_axi_slv_rsp[BootRom]),
1273+
.mem_req_o (bootrom_req),
1274+
.mem_gnt_i (bootrom_req),
1275+
.mem_addr_o (bootrom_addr),
1276+
.mem_wdata_o (),
1277+
.mem_strb_o (),
1278+
.mem_atop_o (),
1279+
.mem_we_o (),
1280+
.mem_rvalid_i (bootrom_req_q),
1281+
.mem_rdata_i (bootrom_data_q)
1282+
);
1283+
1284+
snitch_bootrom #(
1285+
.AddrWidth (PhysicalAddrWidth),
1286+
.DataWidth (WideDataWidth),
1287+
.BootromSize (BootRomSize * 1024)
1288+
) i_bootrom (
1289+
.clk_i (clk_i),
1290+
.rst_ni (rst_ni),
1291+
.addr_i (bootrom_addr),
1292+
.data_o (bootrom_data)
1293+
);
1294+
end
1295+
12391296
snitch_cluster_peripheral #(
12401297
.reg_req_t (reg_req_t),
12411298
.reg_rsp_t (reg_rsp_t),

hw/snitch_cluster/src/snitch_cluster_peripheral/snitch_cluster_peripheral_reg.hjson

Lines changed: 27 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,17 @@
44
// Licensed under Solderpad Hardware License, Version 0.51, see LICENSE for details.
55
{
66
param_list: [
7-
{ name: "NumPerfCounters",
8-
desc: "Number of performance counters",
9-
type: "int",
10-
default: "16"
7+
{
8+
name: "NumPerfCounters",
9+
desc: "Number of performance counters",
10+
type: "int",
11+
default: "16"
12+
},
13+
{
14+
name: "NumCtrlScratch",
15+
desc: "Number of scratch registers",
16+
type: "int",
17+
default: "4"
1118
},
1219
],
1320
name: "snitch_cluster_peripheral",
@@ -303,6 +310,22 @@
303310
}]
304311
}
305312
},
313+
{
314+
multireg: {
315+
name: "SCRATCH",
316+
desc: '''Scratch registers. Used in the bootrom for various purposes.'''
317+
swaccess: "rw",
318+
hwaccess: "none",
319+
count: "NumCtrlScratch",
320+
cname: "ctrl_scratch",
321+
compact: "false",
322+
fields: [{
323+
bits: "31:0",
324+
name: "SCRATCH",
325+
desc: "Scratch register"
326+
}]
327+
}
328+
},
306329
{
307330
name: "CL_CLINT_SET",
308331
desc: '''

hw/snitch_cluster/src/snitch_cluster_peripheral/snitch_cluster_peripheral_reg_pkg.sv

Lines changed: 20 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ package snitch_cluster_peripheral_reg_pkg;
88

99
// Param list
1010
parameter int NumPerfCounters = 16;
11+
parameter int NumCtrlScratch = 4;
1112

1213
// Address widths within the block
1314
parameter int BlockAw = 9;
@@ -128,9 +129,13 @@ package snitch_cluster_peripheral_reg_pkg;
128129
parameter logic [BlockAw-1:0] SNITCH_CLUSTER_PERIPHERAL_PERF_CNT_13_OFFSET = 9'h 168;
129130
parameter logic [BlockAw-1:0] SNITCH_CLUSTER_PERIPHERAL_PERF_CNT_14_OFFSET = 9'h 170;
130131
parameter logic [BlockAw-1:0] SNITCH_CLUSTER_PERIPHERAL_PERF_CNT_15_OFFSET = 9'h 178;
131-
parameter logic [BlockAw-1:0] SNITCH_CLUSTER_PERIPHERAL_CL_CLINT_SET_OFFSET = 9'h 180;
132-
parameter logic [BlockAw-1:0] SNITCH_CLUSTER_PERIPHERAL_CL_CLINT_CLEAR_OFFSET = 9'h 188;
133-
parameter logic [BlockAw-1:0] SNITCH_CLUSTER_PERIPHERAL_ICACHE_PREFETCH_ENABLE_OFFSET = 9'h 190;
132+
parameter logic [BlockAw-1:0] SNITCH_CLUSTER_PERIPHERAL_SCRATCH_0_OFFSET = 9'h 180;
133+
parameter logic [BlockAw-1:0] SNITCH_CLUSTER_PERIPHERAL_SCRATCH_1_OFFSET = 9'h 188;
134+
parameter logic [BlockAw-1:0] SNITCH_CLUSTER_PERIPHERAL_SCRATCH_2_OFFSET = 9'h 190;
135+
parameter logic [BlockAw-1:0] SNITCH_CLUSTER_PERIPHERAL_SCRATCH_3_OFFSET = 9'h 198;
136+
parameter logic [BlockAw-1:0] SNITCH_CLUSTER_PERIPHERAL_CL_CLINT_SET_OFFSET = 9'h 1a0;
137+
parameter logic [BlockAw-1:0] SNITCH_CLUSTER_PERIPHERAL_CL_CLINT_CLEAR_OFFSET = 9'h 1a8;
138+
parameter logic [BlockAw-1:0] SNITCH_CLUSTER_PERIPHERAL_ICACHE_PREFETCH_ENABLE_OFFSET = 9'h 1b0;
134139

135140
// Reset values for hwext registers and their fields
136141
parameter logic [31:0] SNITCH_CLUSTER_PERIPHERAL_PERF_CNT_SEL_0_RESVAL = 32'h 0;
@@ -218,13 +223,17 @@ package snitch_cluster_peripheral_reg_pkg;
218223
SNITCH_CLUSTER_PERIPHERAL_PERF_CNT_13,
219224
SNITCH_CLUSTER_PERIPHERAL_PERF_CNT_14,
220225
SNITCH_CLUSTER_PERIPHERAL_PERF_CNT_15,
226+
SNITCH_CLUSTER_PERIPHERAL_SCRATCH_0,
227+
SNITCH_CLUSTER_PERIPHERAL_SCRATCH_1,
228+
SNITCH_CLUSTER_PERIPHERAL_SCRATCH_2,
229+
SNITCH_CLUSTER_PERIPHERAL_SCRATCH_3,
221230
SNITCH_CLUSTER_PERIPHERAL_CL_CLINT_SET,
222231
SNITCH_CLUSTER_PERIPHERAL_CL_CLINT_CLEAR,
223232
SNITCH_CLUSTER_PERIPHERAL_ICACHE_PREFETCH_ENABLE
224233
} snitch_cluster_peripheral_id_e;
225234

226235
// Register width information to check illegal writes
227-
parameter logic [3:0] SNITCH_CLUSTER_PERIPHERAL_PERMIT [51] = '{
236+
parameter logic [3:0] SNITCH_CLUSTER_PERIPHERAL_PERMIT [55] = '{
228237
4'b 0001, // index[ 0] SNITCH_CLUSTER_PERIPHERAL_PERF_CNT_EN_0
229238
4'b 0001, // index[ 1] SNITCH_CLUSTER_PERIPHERAL_PERF_CNT_EN_1
230239
4'b 0001, // index[ 2] SNITCH_CLUSTER_PERIPHERAL_PERF_CNT_EN_2
@@ -273,9 +282,13 @@ package snitch_cluster_peripheral_reg_pkg;
273282
4'b 1111, // index[45] SNITCH_CLUSTER_PERIPHERAL_PERF_CNT_13
274283
4'b 1111, // index[46] SNITCH_CLUSTER_PERIPHERAL_PERF_CNT_14
275284
4'b 1111, // index[47] SNITCH_CLUSTER_PERIPHERAL_PERF_CNT_15
276-
4'b 1111, // index[48] SNITCH_CLUSTER_PERIPHERAL_CL_CLINT_SET
277-
4'b 1111, // index[49] SNITCH_CLUSTER_PERIPHERAL_CL_CLINT_CLEAR
278-
4'b 0001 // index[50] SNITCH_CLUSTER_PERIPHERAL_ICACHE_PREFETCH_ENABLE
285+
4'b 1111, // index[48] SNITCH_CLUSTER_PERIPHERAL_SCRATCH_0
286+
4'b 1111, // index[49] SNITCH_CLUSTER_PERIPHERAL_SCRATCH_1
287+
4'b 1111, // index[50] SNITCH_CLUSTER_PERIPHERAL_SCRATCH_2
288+
4'b 1111, // index[51] SNITCH_CLUSTER_PERIPHERAL_SCRATCH_3
289+
4'b 1111, // index[52] SNITCH_CLUSTER_PERIPHERAL_CL_CLINT_SET
290+
4'b 1111, // index[53] SNITCH_CLUSTER_PERIPHERAL_CL_CLINT_CLEAR
291+
4'b 0001 // index[54] SNITCH_CLUSTER_PERIPHERAL_ICACHE_PREFETCH_ENABLE
279292
};
280293

281294
endpackage

0 commit comments

Comments
 (0)