From 5f796b830d6e8a79069485a125b62dd4cbe81554 Mon Sep 17 00:00:00 2001 From: Lorenzo Leone Date: Sat, 5 Jul 2025 18:46:51 +0200 Subject: [PATCH 1/3] hw: Initial systemRDL setup --- Bender.yml | 4 +- Makefile | 1 + chimera.mk | 11 +- hw/chimera_top_wrapper.sv | 72 +++--- hw/rdl/chimera_reg_pkg.sv | 86 ++++++++ hw/rdl/chimera_reg_top.sv | 452 ++++++++++++++++++++++++++++++++++++++ hw/rdl/chimera_regs.rdl | 134 +++++++++++ requirements.txt | 1 + 8 files changed, 720 insertions(+), 41 deletions(-) create mode 100644 hw/rdl/chimera_reg_pkg.sv create mode 100644 hw/rdl/chimera_reg_top.sv create mode 100644 hw/rdl/chimera_regs.rdl diff --git a/Bender.yml b/Bender.yml index 4e80b56..c02c90a 100644 --- a/Bender.yml +++ b/Bender.yml @@ -31,8 +31,8 @@ workspace: sources: # Level 0 - hw/chimera_pkg.sv - - hw/regs/chimera_reg_pkg.sv - - hw/regs/chimera_reg_top.sv + - hw/rdl/chimera_reg_pkg.sv + - hw/rdl/chimera_reg_top.sv - hw/bootrom/snitch/snitch_bootrom.sv - hw/narrow_adapter.sv - hw/chimera_cluster_adapter.sv diff --git a/Makefile b/Makefile index 3370934..ea72c90 100644 --- a/Makefile +++ b/Makefile @@ -9,6 +9,7 @@ CHIM_ROOT ?= $(shell pwd) # Tooling BENDER ?= bender -d $(CHIM_ROOT) VERIBLE_VERILOG_FORMAT ?= $(CHIM_UTILS_DIR)/verible-verilog/verible-verilog-format +PEAKRDL ?= peakrdl # Set dependency paths only if dependencies have already been cloned # This avoids running `bender checkout` at every make command diff --git a/chimera.mk b/chimera.mk index 065f8ce..cce5758 100644 --- a/chimera.mk +++ b/chimera.mk @@ -5,7 +5,7 @@ # Moritz Scherer # Lorenzo Leone - +NUMCLUSTERS ?= 5 CLINTCORES = 46 PLICCORES = 92 PLIC_NUM_INTRS = 92 @@ -57,11 +57,10 @@ $(CHIM_ROOT)/hw/bootrom/snitch/snitch_bootrom.sv: $(CHIM_ROOT)/hw/bootrom/snitch $(CHS_ROOT)/util/gen_bootrom.py --sv-module snitch_bootrom $< > $@ .PHONY: regenerate_soc_regs -regenerate_soc_regs: $(CHIM_ROOT)/hw/regs/chimera_reg_pkg.sv $(CHIM_ROOT)/hw/regs/chimera_reg_top.sv $(CHIM_SW_DIR)/include/regs/soc_ctrl.h $(CHIM_HW_DIR)/regs/pcr.md - -.PHONY: $(CHIM_ROOT)/hw/regs/chimera_reg_pkg.sv hw/regs/chimera_reg_top.sv -$(CHIM_ROOT)/hw/regs/chimera_reg_pkg.sv $(CHIM_ROOT)/hw/regs/chimera_reg_top.sv: $(CHIM_ROOT)/hw/regs/chimera_regs.hjson - python $(CHIM_ROOT)/utils/reggen/regtool.py -r $< --outdir $(dir $@) +regenerate_soc_regs: $(CHIM_ROOT)/hw/rdl/chimera_reg_top.sv $(CHIM_ROOT)/hw/rdl/chimera_reg_pkg.sv +$(CHIM_ROOT)/hw/rdl/chimera_reg_top.sv $(CHIM_ROOT)/hw/rdl/chimera_reg_pkg.sv: $(CHIM_ROOT)/hw/rdl/chimera_regs.rdl + $(PEAKRDL) regblock $< -o $(CHIM_ROOT)/hw/rdl --cpuif apb4-flat --default-reset arst_n --module-name chimera_reg_top --package-name chimera_reg_pkg -P NumClusters=$(NUMCLUSTERS) + @sed -i '1i// Copyright 2025 ETH Zurich and University of Bologna.\n// Licensed under the Apache License, Version 2 0, see LICENSE for details.\n// SPDX-License-Identifier: Apache-2.0\n' $(CHIM_ROOT)/hw/rdl/chimera_reg*.sv # Nonfree components diff --git a/hw/chimera_top_wrapper.sv b/hw/chimera_top_wrapper.sv index a534bdb..be7f978 100644 --- a/hw/chimera_top_wrapper.sv +++ b/hw/chimera_top_wrapper.sv @@ -94,7 +94,9 @@ module chimera_top_wrapper localparam type axi_wide_slv_req_t = mem_isl_wide_axi_slv_req_t; localparam type axi_wide_slv_rsp_t = mem_isl_wide_axi_slv_rsp_t; - chimera_reg2hw_t reg2hw; + chimera_regs__out_t reg2hw; + apb_resp_t apb_reg_soc_rsp; + apb_req_t apb_reg_soc_req; // External AXI crossbar ports axi_mst_req_t [iomsb(ChsCfg.AxiExtNumMst):0] axi_mst_req; @@ -235,7 +237,7 @@ module chimera_top_wrapper .reg_rsp_t(reg_rsp_t), .apb_req_t(apb_req_t), .apb_rsp_t(apb_resp_t) - ) i_ext_reg_to_apb ( + ) i_soc_reg_to_apb ( .clk_i (soc_clk_i), .rst_ni (rst_ni), .reg_req_i(reg_slv_req[ExtCfgRegsIdx]), @@ -244,19 +246,35 @@ module chimera_top_wrapper .apb_rsp_i(apb_rsp_i) ); - // TOP-LEVEL REG - - chimera_reg_top #( + reg_to_apb #( .reg_req_t(reg_req_t), - .reg_rsp_t(reg_rsp_t) - ) i_reg_top ( + .reg_rsp_t(reg_rsp_t), + .apb_req_t(apb_req_t), + .apb_rsp_t(apb_resp_t) + ) i_ext_reg_to_apb ( .clk_i (soc_clk_i), - .rst_ni, + .rst_ni (rst_ni), .reg_req_i(reg_slv_req[TopLevelCfgRegsIdx]), .reg_rsp_o(reg_slv_rsp[TopLevelCfgRegsIdx]), - .reg2hw (reg2hw), - .devmode_i('1) + .apb_req_o(apb_reg_soc_req), + .apb_rsp_i(apb_reg_soc_rsp) + ); + + chimera_reg_top i_reg_top ( + .clk (soc_clk_i), + .arst_n (rst_ni), + .s_apb_psel (apb_reg_soc_req.psel), + .s_apb_penable(apb_reg_soc_req.penable), + .s_apb_pwrite (apb_reg_soc_req.pwrite), + .s_apb_pprot (apb_reg_soc_req.pprot), + .s_apb_paddr (apb_reg_soc_req.paddr[CHIMERA_REG_TOP_MIN_ADDR_WIDTH-1:0]), + .s_apb_pwdata (apb_reg_soc_req.pwdata), + .s_apb_pstrb (apb_reg_soc_req.pstrb), + .s_apb_pready (apb_reg_soc_rsp.pready), + .s_apb_prdata (apb_reg_soc_rsp.prdata), + .s_apb_pslverr(apb_reg_soc_rsp.pslverr), + .hwif_out (reg2hw) ); @@ -306,25 +324,17 @@ module chimera_top_wrapper ); logic [ExtClusters-1:0] wide_mem_bypass_mode; - assign wide_mem_bypass_mode = { - reg2hw.wide_mem_cluster_4_bypass.q, - reg2hw.wide_mem_cluster_3_bypass.q, - reg2hw.wide_mem_cluster_2_bypass.q, - reg2hw.wide_mem_cluster_1_bypass.q, - reg2hw.wide_mem_cluster_0_bypass.q - }; + for ( + genvar extClusterIdx = 0; extClusterIdx < ExtClusters; extClusterIdx++ + ) begin : gen_wide_mem_bypass + assign wide_mem_bypass_mode[extClusterIdx] = reg2hw.wide_mem_cluster_bypass[extClusterIdx].WIDE_MEM_CLUSTER_BYPASS.value; + end logic [ExtClusters-1:0] cluster_clock_gate_en; logic [ExtClusters-1:0] clu_clk_gated; - assign cluster_clock_gate_en = { - reg2hw.cluster_4_clk_gate_en, - reg2hw.cluster_3_clk_gate_en, - reg2hw.cluster_2_clk_gate_en, - reg2hw.cluster_1_clk_gate_en, - reg2hw.cluster_0_clk_gate_en - }; - for (genvar extClusterIdx = 0; extClusterIdx < ExtClusters; extClusterIdx++) begin : gen_clk_gates + assign cluster_clock_gate_en[extClusterIdx] = reg2hw.cluster_clk_gate_en[extClusterIdx].CLUSTER_CLK_GATE_EN.value; + tc_clk_gating i_cluster_clk_gate ( .clk_i (clu_clk_i), .en_i (~cluster_clock_gate_en[extClusterIdx]), @@ -335,13 +345,9 @@ module chimera_top_wrapper logic [ExtClusters-1:0] cluster_rst_n; logic [ExtClusters-1:0] cluster_soft_rst_n; - assign cluster_soft_rst_n = { - ~reg2hw.reset_cluster_4.q, - ~reg2hw.reset_cluster_3.q, - ~reg2hw.reset_cluster_2.q, - ~reg2hw.reset_cluster_1.q, - ~reg2hw.reset_cluster_0.q - }; + for (genvar extClusterIdx = 0; extClusterIdx < ExtClusters; extClusterIdx++) begin : gen_soft_rst + assign cluster_soft_rst_n[extClusterIdx] = ~reg2hw.reset_cluster[extClusterIdx].RESET_CLUSTER.value; + end // The Rst used for each cluster is the AND gate among all different source of rst in the system that are: // - rst_ni: Global asynchronous reset coming from the PAD @@ -366,7 +372,7 @@ module chimera_top_wrapper .clu_clk_i (clu_clk_gated), .rst_ni (cluster_rst_n), .widemem_bypass_i (wide_mem_bypass_mode), - .boot_addr_i (reg2hw.snitch_configurable_boot_addr.q), + .boot_addr_i (reg2hw.snitch_configurable_boot_addr.SNITCH_CONFIGURABLE_BOOT_ADDR.value), .debug_req_i (dbg_ext_req), .xeip_i (xeip_ext), .mtip_i (mtip_ext), diff --git a/hw/rdl/chimera_reg_pkg.sv b/hw/rdl/chimera_reg_pkg.sv new file mode 100644 index 0000000..f3e66fa --- /dev/null +++ b/hw/rdl/chimera_reg_pkg.sv @@ -0,0 +1,86 @@ +// Copyright 2025 ETH Zurich and University of Bologna. +// Licensed under the Apache License, Version 2 0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 + +// Generated by PeakRDL-regblock - A free and open-source SystemVerilog generator +// https://github.com/SystemRDL/PeakRDL-regblock + +package chimera_reg_pkg; + + localparam CHIMERA_REG_TOP_DATA_WIDTH = 32; + localparam CHIMERA_REG_TOP_MIN_ADDR_WIDTH = 7; + localparam CHIMERA_REG_TOP_SIZE = 'h70; + + localparam NumClusters = 'h5; + + typedef struct { + logic [31:0] value; + } chimera_regs_NumClusters_5__snitch_boot_addr__SNITCH_BOOT_ADDR__out_t; + + typedef struct { + chimera_regs_NumClusters_5__snitch_boot_addr__SNITCH_BOOT_ADDR__out_t SNITCH_BOOT_ADDR; + } chimera_regs_NumClusters_5__snitch_boot_addr__out_t; + + typedef struct { + logic [31:0] value; + } chimera_regs_NumClusters_5__snitch_configurable_boot_addr__SNITCH_CONFIGURABLE_BOOT_ADDR__out_t; + + typedef struct { + chimera_regs_NumClusters_5__snitch_configurable_boot_addr__SNITCH_CONFIGURABLE_BOOT_ADDR__out_t SNITCH_CONFIGURABLE_BOOT_ADDR; + } chimera_regs_NumClusters_5__snitch_configurable_boot_addr__out_t; + + typedef struct { + logic [31:0] value; + } chimera_regs_NumClusters_5__snitch_intr_handler_addr__SNITCH_INTR_HANDLER_ADDR__out_t; + + typedef struct { + chimera_regs_NumClusters_5__snitch_intr_handler_addr__SNITCH_INTR_HANDLER_ADDR__out_t SNITCH_INTR_HANDLER_ADDR; + } chimera_regs_NumClusters_5__snitch_intr_handler_addr__out_t; + + typedef struct { + logic [31:0] value; + } chimera_regs_NumClusters_5__snitch_cluster_return__SNITCH_CLUSTER_RETURN__out_t; + + typedef struct { + chimera_regs_NumClusters_5__snitch_cluster_return__SNITCH_CLUSTER_RETURN__out_t SNITCH_CLUSTER_RETURN; + } chimera_regs_NumClusters_5__snitch_cluster_return__out_t; + + typedef struct {logic value;} chimera_regs_NumClusters_5__reset_cluster__RESET_CLUSTER__out_t; + + typedef struct { + chimera_regs_NumClusters_5__reset_cluster__RESET_CLUSTER__out_t RESET_CLUSTER; + } chimera_regs_NumClusters_5__reset_cluster__out_t; + + typedef struct { + logic value; + } chimera_regs_NumClusters_5__cluster_clk_gate_en__CLUSTER_CLK_GATE_EN__out_t; + + typedef struct { + chimera_regs_NumClusters_5__cluster_clk_gate_en__CLUSTER_CLK_GATE_EN__out_t CLUSTER_CLK_GATE_EN; + } chimera_regs_NumClusters_5__cluster_clk_gate_en__out_t; + + typedef struct { + logic value; + } chimera_regs_NumClusters_5__wide_mem_cluster_bypass__WIDE_MEM_CLUSTER_BYPASS__out_t; + + typedef struct { + chimera_regs_NumClusters_5__wide_mem_cluster_bypass__WIDE_MEM_CLUSTER_BYPASS__out_t WIDE_MEM_CLUSTER_BYPASS; + } chimera_regs_NumClusters_5__wide_mem_cluster_bypass__out_t; + + typedef struct {logic value;} chimera_regs_NumClusters_5__cluster_busy__CLUSTER_BUSY__out_t; + + typedef struct { + chimera_regs_NumClusters_5__cluster_busy__CLUSTER_BUSY__out_t CLUSTER_BUSY; + } chimera_regs_NumClusters_5__cluster_busy__out_t; + + typedef struct { + chimera_regs_NumClusters_5__snitch_boot_addr__out_t snitch_boot_addr; + chimera_regs_NumClusters_5__snitch_configurable_boot_addr__out_t snitch_configurable_boot_addr; + chimera_regs_NumClusters_5__snitch_intr_handler_addr__out_t snitch_intr_handler_addr; + chimera_regs_NumClusters_5__snitch_cluster_return__out_t snitch_cluster_return[5]; + chimera_regs_NumClusters_5__reset_cluster__out_t reset_cluster[5]; + chimera_regs_NumClusters_5__cluster_clk_gate_en__out_t cluster_clk_gate_en[5]; + chimera_regs_NumClusters_5__wide_mem_cluster_bypass__out_t wide_mem_cluster_bypass[5]; + chimera_regs_NumClusters_5__cluster_busy__out_t cluster_busy[5]; + } chimera_regs__out_t; +endpackage diff --git a/hw/rdl/chimera_reg_top.sv b/hw/rdl/chimera_reg_top.sv new file mode 100644 index 0000000..f39c4aa --- /dev/null +++ b/hw/rdl/chimera_reg_top.sv @@ -0,0 +1,452 @@ +// Copyright 2025 ETH Zurich and University of Bologna. +// Licensed under the Apache License, Version 2 0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 + +// Generated by PeakRDL-regblock - A free and open-source SystemVerilog generator +// https://github.com/SystemRDL/PeakRDL-regblock + +module chimera_reg_top ( + input wire clk, + input wire arst_n, + + input wire s_apb_psel, + input wire s_apb_penable, + input wire s_apb_pwrite, + input wire [ 2:0] s_apb_pprot, + input wire [ 6:0] s_apb_paddr, + input wire [31:0] s_apb_pwdata, + input wire [ 3:0] s_apb_pstrb, + output logic s_apb_pready, + output logic [31:0] s_apb_prdata, + output logic s_apb_pslverr, + + output chimera_reg_pkg::chimera_regs__out_t hwif_out +); + + //-------------------------------------------------------------------------- + // CPU Bus interface logic + //-------------------------------------------------------------------------- + logic cpuif_req; + logic cpuif_req_is_wr; + logic [ 6:0] cpuif_addr; + logic [31:0] cpuif_wr_data; + logic [31:0] cpuif_wr_biten; + logic cpuif_req_stall_wr; + logic cpuif_req_stall_rd; + + logic cpuif_rd_ack; + logic cpuif_rd_err; + logic [31:0] cpuif_rd_data; + + logic cpuif_wr_ack; + logic cpuif_wr_err; + + // Request + logic is_active; + always_ff @(posedge clk or negedge arst_n) begin + if (~arst_n) begin + is_active <= '0; + cpuif_req <= '0; + cpuif_req_is_wr <= '0; + cpuif_addr <= '0; + cpuif_wr_data <= '0; + cpuif_wr_biten <= '0; + end else begin + if (~is_active) begin + if (s_apb_psel) begin + is_active <= '1; + cpuif_req <= '1; + cpuif_req_is_wr <= s_apb_pwrite; + cpuif_addr <= {s_apb_paddr[6:2], 2'b0}; + cpuif_wr_data <= s_apb_pwdata; + for (int i = 0; i < 4; i++) begin + cpuif_wr_biten[i*8+:8] <= {8{s_apb_pstrb[i]}}; + end + end + end else begin + cpuif_req <= '0; + if (cpuif_rd_ack || cpuif_wr_ack) begin + is_active <= '0; + end + end + end + end + + // Response + assign s_apb_pready = cpuif_rd_ack | cpuif_wr_ack; + assign s_apb_prdata = cpuif_rd_data; + assign s_apb_pslverr = cpuif_rd_err | cpuif_wr_err; + + logic cpuif_req_masked; + + // Read & write latencies are balanced. Stalls not required + assign cpuif_req_stall_rd = '0; + assign cpuif_req_stall_wr = '0; + assign cpuif_req_masked = cpuif_req + & !(!cpuif_req_is_wr & cpuif_req_stall_rd) + & !(cpuif_req_is_wr & cpuif_req_stall_wr); + + //-------------------------------------------------------------------------- + // Address Decode + //-------------------------------------------------------------------------- + typedef struct { + logic snitch_boot_addr; + logic snitch_configurable_boot_addr; + logic snitch_intr_handler_addr; + logic snitch_cluster_return[5]; + logic reset_cluster[5]; + logic cluster_clk_gate_en[5]; + logic wide_mem_cluster_bypass[5]; + logic cluster_busy[5]; + } decoded_reg_strb_t; + decoded_reg_strb_t decoded_reg_strb; + logic decoded_req; + logic decoded_req_is_wr; + logic [31:0] decoded_wr_data; + logic [31:0] decoded_wr_biten; + + always_comb begin + decoded_reg_strb.snitch_boot_addr = cpuif_req_masked & (cpuif_addr == 7'h0); + decoded_reg_strb.snitch_configurable_boot_addr = cpuif_req_masked & (cpuif_addr == 7'h4); + decoded_reg_strb.snitch_intr_handler_addr = cpuif_req_masked & (cpuif_addr == 7'h8); + for (int i0 = 0; i0 < 5; i0++) begin + decoded_reg_strb.snitch_cluster_return[i0] = cpuif_req_masked & (cpuif_addr == 7'hc + (7)'(i0) * 7'h4); + end + for (int i0 = 0; i0 < 5; i0++) begin + decoded_reg_strb.reset_cluster[i0] = cpuif_req_masked & (cpuif_addr == 7'h20 + (7)'(i0) * 7'h4); + end + for (int i0 = 0; i0 < 5; i0++) begin + decoded_reg_strb.cluster_clk_gate_en[i0] = cpuif_req_masked & (cpuif_addr == 7'h34 + (7)'(i0) * 7'h4); + end + for (int i0 = 0; i0 < 5; i0++) begin + decoded_reg_strb.wide_mem_cluster_bypass[i0] = cpuif_req_masked & (cpuif_addr == 7'h48 + (7)'(i0) * 7'h4); + end + for (int i0 = 0; i0 < 5; i0++) begin + decoded_reg_strb.cluster_busy[i0] = cpuif_req_masked & (cpuif_addr == 7'h5c + (7)'(i0) * 7'h4); + end + end + + // Pass down signals to next stage + assign decoded_req = cpuif_req_masked; + assign decoded_req_is_wr = cpuif_req_is_wr; + assign decoded_wr_data = cpuif_wr_data; + assign decoded_wr_biten = cpuif_wr_biten; + + //-------------------------------------------------------------------------- + // Field logic + //-------------------------------------------------------------------------- + typedef struct { + struct { + struct { + logic [31:0] next; + logic load_next; + } SNITCH_BOOT_ADDR; + } snitch_boot_addr; + struct { + struct { + logic [31:0] next; + logic load_next; + } SNITCH_CONFIGURABLE_BOOT_ADDR; + } snitch_configurable_boot_addr; + struct { + struct { + logic [31:0] next; + logic load_next; + } SNITCH_INTR_HANDLER_ADDR; + } snitch_intr_handler_addr; + struct { + struct { + logic [31:0] next; + logic load_next; + } SNITCH_CLUSTER_RETURN; + } snitch_cluster_return[5]; + struct { + struct { + logic next; + logic load_next; + } RESET_CLUSTER; + } reset_cluster[5]; + struct { + struct { + logic next; + logic load_next; + } CLUSTER_CLK_GATE_EN; + } cluster_clk_gate_en[5]; + struct { + struct { + logic next; + logic load_next; + } WIDE_MEM_CLUSTER_BYPASS; + } wide_mem_cluster_bypass[5]; + struct { + struct { + logic next; + logic load_next; + } CLUSTER_BUSY; + } cluster_busy[5]; + } field_combo_t; + field_combo_t field_combo; + + typedef struct { + struct {struct {logic [31:0] value;} SNITCH_BOOT_ADDR;} snitch_boot_addr; + struct { + struct {logic [31:0] value;} SNITCH_CONFIGURABLE_BOOT_ADDR; + } snitch_configurable_boot_addr; + struct {struct {logic [31:0] value;} SNITCH_INTR_HANDLER_ADDR;} snitch_intr_handler_addr; + struct {struct {logic [31:0] value;} SNITCH_CLUSTER_RETURN;} snitch_cluster_return[5]; + struct {struct {logic value;} RESET_CLUSTER;} reset_cluster[5]; + struct {struct {logic value;} CLUSTER_CLK_GATE_EN;} cluster_clk_gate_en[5]; + struct {struct {logic value;} WIDE_MEM_CLUSTER_BYPASS;} wide_mem_cluster_bypass[5]; + struct {struct {logic value;} CLUSTER_BUSY;} cluster_busy[5]; + } field_storage_t; + field_storage_t field_storage; + + // Field: chimera_regs.snitch_boot_addr.SNITCH_BOOT_ADDR + always_comb begin + automatic logic [31:0] next_c; + automatic logic load_next_c; + next_c = field_storage.snitch_boot_addr.SNITCH_BOOT_ADDR.value; + load_next_c = '0; + if (decoded_reg_strb.snitch_boot_addr && decoded_req_is_wr) begin // SW write + next_c = (field_storage.snitch_boot_addr.SNITCH_BOOT_ADDR.value & ~decoded_wr_biten[31:0]) | (decoded_wr_data[31:0] & decoded_wr_biten[31:0]); + load_next_c = '1; + end + field_combo.snitch_boot_addr.SNITCH_BOOT_ADDR.next = next_c; + field_combo.snitch_boot_addr.SNITCH_BOOT_ADDR.load_next = load_next_c; + end + always_ff @(posedge clk or negedge arst_n) begin + if (~arst_n) begin + field_storage.snitch_boot_addr.SNITCH_BOOT_ADDR.value <= 32'hbadcab1e; + end else begin + if (field_combo.snitch_boot_addr.SNITCH_BOOT_ADDR.load_next) begin + field_storage.snitch_boot_addr.SNITCH_BOOT_ADDR.value <= field_combo.snitch_boot_addr.SNITCH_BOOT_ADDR.next; + end + end + end + assign hwif_out.snitch_boot_addr.SNITCH_BOOT_ADDR.value = field_storage.snitch_boot_addr.SNITCH_BOOT_ADDR.value; + // Field: chimera_regs.snitch_configurable_boot_addr.SNITCH_CONFIGURABLE_BOOT_ADDR + always_comb begin + automatic logic [31:0] next_c; + automatic logic load_next_c; + next_c = field_storage.snitch_configurable_boot_addr.SNITCH_CONFIGURABLE_BOOT_ADDR.value; + load_next_c = '0; + if (decoded_reg_strb.snitch_configurable_boot_addr && decoded_req_is_wr) begin // SW write + next_c = (field_storage.snitch_configurable_boot_addr.SNITCH_CONFIGURABLE_BOOT_ADDR.value & ~decoded_wr_biten[31:0]) | (decoded_wr_data[31:0] & decoded_wr_biten[31:0]); + load_next_c = '1; + end + field_combo.snitch_configurable_boot_addr.SNITCH_CONFIGURABLE_BOOT_ADDR.next = next_c; + field_combo.snitch_configurable_boot_addr.SNITCH_CONFIGURABLE_BOOT_ADDR.load_next = load_next_c; + end + always_ff @(posedge clk or negedge arst_n) begin + if (~arst_n) begin + field_storage.snitch_configurable_boot_addr.SNITCH_CONFIGURABLE_BOOT_ADDR.value <= 32'h30000000; + end else begin + if (field_combo.snitch_configurable_boot_addr.SNITCH_CONFIGURABLE_BOOT_ADDR.load_next) begin + field_storage.snitch_configurable_boot_addr.SNITCH_CONFIGURABLE_BOOT_ADDR.value <= field_combo.snitch_configurable_boot_addr.SNITCH_CONFIGURABLE_BOOT_ADDR.next; + end + end + end + assign hwif_out.snitch_configurable_boot_addr.SNITCH_CONFIGURABLE_BOOT_ADDR.value = field_storage.snitch_configurable_boot_addr.SNITCH_CONFIGURABLE_BOOT_ADDR.value; + // Field: chimera_regs.snitch_intr_handler_addr.SNITCH_INTR_HANDLER_ADDR + always_comb begin + automatic logic [31:0] next_c; + automatic logic load_next_c; + next_c = field_storage.snitch_intr_handler_addr.SNITCH_INTR_HANDLER_ADDR.value; + load_next_c = '0; + if (decoded_reg_strb.snitch_intr_handler_addr && decoded_req_is_wr) begin // SW write + next_c = (field_storage.snitch_intr_handler_addr.SNITCH_INTR_HANDLER_ADDR.value & ~decoded_wr_biten[31:0]) | (decoded_wr_data[31:0] & decoded_wr_biten[31:0]); + load_next_c = '1; + end + field_combo.snitch_intr_handler_addr.SNITCH_INTR_HANDLER_ADDR.next = next_c; + field_combo.snitch_intr_handler_addr.SNITCH_INTR_HANDLER_ADDR.load_next = load_next_c; + end + always_ff @(posedge clk or negedge arst_n) begin + if (~arst_n) begin + field_storage.snitch_intr_handler_addr.SNITCH_INTR_HANDLER_ADDR.value <= 32'hbadcab1e; + end else begin + if (field_combo.snitch_intr_handler_addr.SNITCH_INTR_HANDLER_ADDR.load_next) begin + field_storage.snitch_intr_handler_addr.SNITCH_INTR_HANDLER_ADDR.value <= field_combo.snitch_intr_handler_addr.SNITCH_INTR_HANDLER_ADDR.next; + end + end + end + assign hwif_out.snitch_intr_handler_addr.SNITCH_INTR_HANDLER_ADDR.value = field_storage.snitch_intr_handler_addr.SNITCH_INTR_HANDLER_ADDR.value; + for (genvar i0 = 0; i0 < 5; i0++) begin + // Field: chimera_regs.snitch_cluster_return[].SNITCH_CLUSTER_RETURN + always_comb begin + automatic logic [31:0] next_c; + automatic logic load_next_c; + next_c = field_storage.snitch_cluster_return[i0].SNITCH_CLUSTER_RETURN.value; + load_next_c = '0; + if (decoded_reg_strb.snitch_cluster_return[i0] && decoded_req_is_wr) begin // SW write + next_c = (field_storage.snitch_cluster_return[i0].SNITCH_CLUSTER_RETURN.value & ~decoded_wr_biten[31:0]) | (decoded_wr_data[31:0] & decoded_wr_biten[31:0]); + load_next_c = '1; + end + field_combo.snitch_cluster_return[i0].SNITCH_CLUSTER_RETURN.next = next_c; + field_combo.snitch_cluster_return[i0].SNITCH_CLUSTER_RETURN.load_next = load_next_c; + end + always_ff @(posedge clk or negedge arst_n) begin + if (~arst_n) begin + field_storage.snitch_cluster_return[i0].SNITCH_CLUSTER_RETURN.value <= 32'h0; + end else begin + if (field_combo.snitch_cluster_return[i0].SNITCH_CLUSTER_RETURN.load_next) begin + field_storage.snitch_cluster_return[i0].SNITCH_CLUSTER_RETURN.value <= field_combo.snitch_cluster_return[i0].SNITCH_CLUSTER_RETURN.next; + end + end + end + assign hwif_out.snitch_cluster_return[i0].SNITCH_CLUSTER_RETURN.value = field_storage.snitch_cluster_return[i0].SNITCH_CLUSTER_RETURN.value; + end + for (genvar i0 = 0; i0 < 5; i0++) begin + // Field: chimera_regs.reset_cluster[].RESET_CLUSTER + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.reset_cluster[i0].RESET_CLUSTER.value; + load_next_c = '0; + if (decoded_reg_strb.reset_cluster[i0] && decoded_req_is_wr) begin // SW write + next_c = (field_storage.reset_cluster[i0].RESET_CLUSTER.value & ~decoded_wr_biten[0:0]) | (decoded_wr_data[0:0] & decoded_wr_biten[0:0]); + load_next_c = '1; + end + field_combo.reset_cluster[i0].RESET_CLUSTER.next = next_c; + field_combo.reset_cluster[i0].RESET_CLUSTER.load_next = load_next_c; + end + always_ff @(posedge clk or negedge arst_n) begin + if (~arst_n) begin + field_storage.reset_cluster[i0].RESET_CLUSTER.value <= 1'h1; + end else begin + if (field_combo.reset_cluster[i0].RESET_CLUSTER.load_next) begin + field_storage.reset_cluster[i0].RESET_CLUSTER.value <= field_combo.reset_cluster[i0].RESET_CLUSTER.next; + end + end + end + assign hwif_out.reset_cluster[i0].RESET_CLUSTER.value = field_storage.reset_cluster[i0].RESET_CLUSTER.value; + end + for (genvar i0 = 0; i0 < 5; i0++) begin + // Field: chimera_regs.cluster_clk_gate_en[].CLUSTER_CLK_GATE_EN + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.cluster_clk_gate_en[i0].CLUSTER_CLK_GATE_EN.value; + load_next_c = '0; + if (decoded_reg_strb.cluster_clk_gate_en[i0] && decoded_req_is_wr) begin // SW write + next_c = (field_storage.cluster_clk_gate_en[i0].CLUSTER_CLK_GATE_EN.value & ~decoded_wr_biten[0:0]) | (decoded_wr_data[0:0] & decoded_wr_biten[0:0]); + load_next_c = '1; + end + field_combo.cluster_clk_gate_en[i0].CLUSTER_CLK_GATE_EN.next = next_c; + field_combo.cluster_clk_gate_en[i0].CLUSTER_CLK_GATE_EN.load_next = load_next_c; + end + always_ff @(posedge clk or negedge arst_n) begin + if (~arst_n) begin + field_storage.cluster_clk_gate_en[i0].CLUSTER_CLK_GATE_EN.value <= 1'h1; + end else begin + if (field_combo.cluster_clk_gate_en[i0].CLUSTER_CLK_GATE_EN.load_next) begin + field_storage.cluster_clk_gate_en[i0].CLUSTER_CLK_GATE_EN.value <= field_combo.cluster_clk_gate_en[i0].CLUSTER_CLK_GATE_EN.next; + end + end + end + assign hwif_out.cluster_clk_gate_en[i0].CLUSTER_CLK_GATE_EN.value = field_storage.cluster_clk_gate_en[i0].CLUSTER_CLK_GATE_EN.value; + end + for (genvar i0 = 0; i0 < 5; i0++) begin + // Field: chimera_regs.wide_mem_cluster_bypass[].WIDE_MEM_CLUSTER_BYPASS + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.wide_mem_cluster_bypass[i0].WIDE_MEM_CLUSTER_BYPASS.value; + load_next_c = '0; + if (decoded_reg_strb.wide_mem_cluster_bypass[i0] && decoded_req_is_wr) begin // SW write + next_c = (field_storage.wide_mem_cluster_bypass[i0].WIDE_MEM_CLUSTER_BYPASS.value & ~decoded_wr_biten[0:0]) | (decoded_wr_data[0:0] & decoded_wr_biten[0:0]); + load_next_c = '1; + end + field_combo.wide_mem_cluster_bypass[i0].WIDE_MEM_CLUSTER_BYPASS.next = next_c; + field_combo.wide_mem_cluster_bypass[i0].WIDE_MEM_CLUSTER_BYPASS.load_next = load_next_c; + end + always_ff @(posedge clk or negedge arst_n) begin + if (~arst_n) begin + field_storage.wide_mem_cluster_bypass[i0].WIDE_MEM_CLUSTER_BYPASS.value <= 1'h0; + end else begin + if (field_combo.wide_mem_cluster_bypass[i0].WIDE_MEM_CLUSTER_BYPASS.load_next) begin + field_storage.wide_mem_cluster_bypass[i0].WIDE_MEM_CLUSTER_BYPASS.value <= field_combo.wide_mem_cluster_bypass[i0].WIDE_MEM_CLUSTER_BYPASS.next; + end + end + end + assign hwif_out.wide_mem_cluster_bypass[i0].WIDE_MEM_CLUSTER_BYPASS.value = field_storage.wide_mem_cluster_bypass[i0].WIDE_MEM_CLUSTER_BYPASS.value; + end + for (genvar i0 = 0; i0 < 5; i0++) begin + // Field: chimera_regs.cluster_busy[].CLUSTER_BUSY + always_comb begin + automatic logic [0:0] next_c; + automatic logic load_next_c; + next_c = field_storage.cluster_busy[i0].CLUSTER_BUSY.value; + load_next_c = '0; + if (decoded_reg_strb.cluster_busy[i0] && decoded_req_is_wr) begin // SW write + next_c = (field_storage.cluster_busy[i0].CLUSTER_BUSY.value & ~decoded_wr_biten[0:0]) | (decoded_wr_data[0:0] & decoded_wr_biten[0:0]); + load_next_c = '1; + end + field_combo.cluster_busy[i0].CLUSTER_BUSY.next = next_c; + field_combo.cluster_busy[i0].CLUSTER_BUSY.load_next = load_next_c; + end + always_ff @(posedge clk or negedge arst_n) begin + if (~arst_n) begin + field_storage.cluster_busy[i0].CLUSTER_BUSY.value <= 1'h0; + end else begin + if (field_combo.cluster_busy[i0].CLUSTER_BUSY.load_next) begin + field_storage.cluster_busy[i0].CLUSTER_BUSY.value <= field_combo.cluster_busy[i0].CLUSTER_BUSY.next; + end + end + end + assign hwif_out.cluster_busy[i0].CLUSTER_BUSY.value = field_storage.cluster_busy[i0].CLUSTER_BUSY.value; + end + + //-------------------------------------------------------------------------- + // Write response + //-------------------------------------------------------------------------- + assign cpuif_wr_ack = decoded_req & decoded_req_is_wr; + // Writes are always granted with no error response + assign cpuif_wr_err = '0; + + //-------------------------------------------------------------------------- + // Readback + //-------------------------------------------------------------------------- + + logic readback_err; + logic readback_done; + logic [31:0] readback_data; + + // Assign readback values to a flattened array + logic [31:0] readback_array[28]; + assign readback_array[0][31:0] = (decoded_reg_strb.snitch_boot_addr && !decoded_req_is_wr) ? field_storage.snitch_boot_addr.SNITCH_BOOT_ADDR.value : '0; + assign readback_array[1][31:0] = (decoded_reg_strb.snitch_configurable_boot_addr && !decoded_req_is_wr) ? field_storage.snitch_configurable_boot_addr.SNITCH_CONFIGURABLE_BOOT_ADDR.value : '0; + assign readback_array[2][31:0] = (decoded_reg_strb.snitch_intr_handler_addr && !decoded_req_is_wr) ? field_storage.snitch_intr_handler_addr.SNITCH_INTR_HANDLER_ADDR.value : '0; + for (genvar i0 = 0; i0 < 5; i0++) begin + assign readback_array[i0 * 1 + 3][31:0] = (decoded_reg_strb.snitch_cluster_return[i0] && !decoded_req_is_wr) ? field_storage.snitch_cluster_return[i0].SNITCH_CLUSTER_RETURN.value : '0; + end + for (genvar i0 = 0; i0 < 5; i0++) begin + assign readback_array[i0 * 1 + 8][0:0] = (decoded_reg_strb.reset_cluster[i0] && !decoded_req_is_wr) ? field_storage.reset_cluster[i0].RESET_CLUSTER.value : '0; + assign readback_array[i0*1+8][31:1] = '0; + end + for (genvar i0 = 0; i0 < 5; i0++) begin + assign readback_array[i0 * 1 + 13][0:0] = (decoded_reg_strb.cluster_clk_gate_en[i0] && !decoded_req_is_wr) ? field_storage.cluster_clk_gate_en[i0].CLUSTER_CLK_GATE_EN.value : '0; + assign readback_array[i0*1+13][31:1] = '0; + end + for (genvar i0 = 0; i0 < 5; i0++) begin + assign readback_array[i0 * 1 + 18][0:0] = (decoded_reg_strb.wide_mem_cluster_bypass[i0] && !decoded_req_is_wr) ? field_storage.wide_mem_cluster_bypass[i0].WIDE_MEM_CLUSTER_BYPASS.value : '0; + assign readback_array[i0*1+18][31:1] = '0; + end + for (genvar i0 = 0; i0 < 5; i0++) begin + assign readback_array[i0 * 1 + 23][0:0] = (decoded_reg_strb.cluster_busy[i0] && !decoded_req_is_wr) ? field_storage.cluster_busy[i0].CLUSTER_BUSY.value : '0; + assign readback_array[i0*1+23][31:1] = '0; + end + + // Reduce the array + always_comb begin + automatic logic [31:0] readback_data_var; + readback_done = decoded_req & ~decoded_req_is_wr; + readback_err = '0; + readback_data_var = '0; + for (int i = 0; i < 28; i++) readback_data_var |= readback_array[i]; + readback_data = readback_data_var; + end + + assign cpuif_rd_ack = readback_done; + assign cpuif_rd_data = readback_data; + assign cpuif_rd_err = readback_err; +endmodule diff --git a/hw/rdl/chimera_regs.rdl b/hw/rdl/chimera_regs.rdl new file mode 100644 index 0000000..c22ffa6 --- /dev/null +++ b/hw/rdl/chimera_regs.rdl @@ -0,0 +1,134 @@ +// Copyright 2025 ETH Zurich and University of Bologna. +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 + +// Author: Moritz Scherer +// Author: Lorenzo Leone + +`ifndef CHIMERA_RDL +`define CHIMERA_RDL + +addrmap chimera_regs #( + longint unsigned NumClusters = 1 // Number of cores +) { + name = "chimera_regs"; + desc = "Chimera SoC control registers"; + + reg snitch_boot_addr { + name = "SNITCH_BOOT_ADDR"; + desc = "Set boot address for all snitch cores"; + field { + name = "SNITCH_BOOT_ADDR"; + desc = "Boot address for all snitch cores"; + reset = 0xBADCAB1E; + hw = r; + sw = rw; + } SNITCH_BOOT_ADDR[31:0]; + }; + + reg snitch_configurable_boot_addr { + name = "SNITCH_CONFIGURABLE_BOOT_ADDR"; + desc = "Define the address of the Boot executed by each Snitch core"; + field { + name = "SNITCH_CONFIGURABLE_BOOT_ADDR"; + desc = "Configurable Boot Address for Snitch cores"; + reset = 0x30000000; + sw = rw; + hw = r; + } SNITCH_CONFIGURABLE_BOOT_ADDR[31:0]; + }; + + reg snitch_intr_handler_addr { + name = "SNITCH_INTR_HANDLER_ADDR"; + desc = "Set the address of the interrupt handler for all snitch cores"; + field { + name = "SNITCH_INTR_HANDLER_ADDR"; + desc = "Snitch core interrupt handler address"; + reset = 0xBADCAB1E; + sw = rw; + hw = r; + } SNITCH_INTR_HANDLER_ADDR[31:0]; + }; + + reg snitch_cluster_return { + name = "SNITCH_CLUSTER_RETURN"; + desc = "Register to store Snitch cluster return value"; + field { + name = "SNITCH_CLUSTER_RETURN"; + desc = "Snitch cluster return register"; + reset = 0x0; + sw = rw; + hw = r; + } SNITCH_CLUSTER_RETURN[31:0]; + }; + + + reg reset_cluster { + name = "RESET_CLUSTER"; + desc = "Soft reset for cluster 0. Active High"; + regwidth = 32; + field { + name = "RESET_CLUSTER"; + desc = "Soft reset for cluster 0. Active High"; + reset = 0x1; + sw = rw; + hw = r; + } RESET_CLUSTER[0:0]; + }; + + reg cluster_clk_gate_en { + name = "CLUSTER_CLK_GATE_EN"; + desc = "Enable clock gate for cluster"; + regwidth = 32; + field { + name = "CLUSTER_CLK_GATE_EN"; + desc = "Enable clock gate for cluster"; + reset = 0x1; + sw = rw; + hw = r; + } CLUSTER_CLK_GATE_EN[0:0]; + }; + + + reg wide_mem_cluster_bypass { + name = "WIDE_MEM_CLUSTER_BYPASS"; + desc = "Bypass cluster to mem wide access. If enabled, wide transactions from clusters to memory island, will be serialized through the narrow interconnect."; + regwidth = 32; + field { + name = "WIDE_MEM_CLUSTER_BYPASS"; + desc = "Bypass cluster to mem wide"; + reset = 0x0; + sw = rw; + hw = r; + } WIDE_MEM_CLUSTER_BYPASS[0:0]; + }; + + reg cluster_busy { + name = "CLUSTER_BUSY"; + desc = "Flag register to identify when the cluster is busy. Read value to knwo when the host can offload."; + regwidth = 32; + field { + name = "CLUSTER_BUSY"; + desc = "Clustr busy status register"; + reset = 0x0; + sw = rw; + hw = r; + } CLUSTER_BUSY[0:0]; + }; + + // Instantiate control registers + // TODO (lleone): Check the correctness of addresses and offsets + snitch_boot_addr snitch_boot_addr @0x0; + snitch_configurable_boot_addr snitch_configurable_boot_addr; + snitch_intr_handler_addr snitch_intr_handler_addr; + + // Snitch clusters registers + snitch_cluster_return snitch_cluster_return[NumClusters]; + reset_cluster reset_cluster [NumClusters]; + cluster_clk_gate_en cluster_clk_gate_en[NumClusters]; + wide_mem_cluster_bypass wide_mem_cluster_bypass [NumClusters]; + cluster_busy cluster_busy [NumClusters]; +}; + + +`endif // CHIMERA_RDL diff --git a/requirements.txt b/requirements.txt index 297ba62..04c9f40 100644 --- a/requirements.txt +++ b/requirements.txt @@ -5,3 +5,4 @@ mako jsonref jsonschema flatdict +peakrdl \ No newline at end of file From 56e7ba460602aa24f7f9204d6835b46e5143c315 Mon Sep 17 00:00:00 2001 From: Lorenzo Leone Date: Mon, 7 Jul 2025 14:00:37 +0200 Subject: [PATCH 2/3] lint: Avoid linting of generetade systemRDL fiels --- .github/workflows/lint.yml | 9 +- hw/chimera_top_wrapper.sv | 9 +- hw/regs/chimera_reg_pkg.sv | 199 ------ hw/regs/chimera_reg_top.sv | 1249 ------------------------------------ hw/regs/chimera_regs.hjson | 333 ---------- 5 files changed, 11 insertions(+), 1788 deletions(-) delete mode 100644 hw/regs/chimera_reg_pkg.sv delete mode 100644 hw/regs/chimera_reg_top.sv delete mode 100644 hw/regs/chimera_regs.hjson diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index fb5dc15..56b2a80 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -15,7 +15,7 @@ jobs: steps: - name: Checkout - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: Check license uses: pulp-platform/pulp-actions/lint-license@v2 @@ -35,7 +35,7 @@ jobs: steps: - name: Checkout - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: Run Verible uses: chipsalliance/verible-linter-action@main @@ -45,11 +45,12 @@ jobs: github_token: ${{ secrets.GITHUB_TOKEN }} fail_on_error: true reviewdog_reporter: github-check + exclude_paths: hw/rdl lint-sv-format: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 with: ref: ${{ github.event.pull_request.head.sha }} - name: Run Verible formatter action @@ -68,7 +69,7 @@ jobs: steps: - name: Checkout - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: Run Clang-format uses: DoozyX/clang-format-lint-action@v0.14 diff --git a/hw/chimera_top_wrapper.sv b/hw/chimera_top_wrapper.sv index be7f978..9f9a9cc 100644 --- a/hw/chimera_top_wrapper.sv +++ b/hw/chimera_top_wrapper.sv @@ -327,13 +327,15 @@ module chimera_top_wrapper for ( genvar extClusterIdx = 0; extClusterIdx < ExtClusters; extClusterIdx++ ) begin : gen_wide_mem_bypass - assign wide_mem_bypass_mode[extClusterIdx] = reg2hw.wide_mem_cluster_bypass[extClusterIdx].WIDE_MEM_CLUSTER_BYPASS.value; + assign wide_mem_bypass_mode[extClusterIdx] = + reg2hw.wide_mem_cluster_bypass[extClusterIdx].WIDE_MEM_CLUSTER_BYPASS.value; end logic [ExtClusters-1:0] cluster_clock_gate_en; logic [ExtClusters-1:0] clu_clk_gated; for (genvar extClusterIdx = 0; extClusterIdx < ExtClusters; extClusterIdx++) begin : gen_clk_gates - assign cluster_clock_gate_en[extClusterIdx] = reg2hw.cluster_clk_gate_en[extClusterIdx].CLUSTER_CLK_GATE_EN.value; + assign cluster_clock_gate_en[extClusterIdx] = + reg2hw.cluster_clk_gate_en[extClusterIdx].CLUSTER_CLK_GATE_EN.value; tc_clk_gating i_cluster_clk_gate ( .clk_i (clu_clk_i), @@ -346,7 +348,8 @@ module chimera_top_wrapper logic [ExtClusters-1:0] cluster_rst_n; logic [ExtClusters-1:0] cluster_soft_rst_n; for (genvar extClusterIdx = 0; extClusterIdx < ExtClusters; extClusterIdx++) begin : gen_soft_rst - assign cluster_soft_rst_n[extClusterIdx] = ~reg2hw.reset_cluster[extClusterIdx].RESET_CLUSTER.value; + assign cluster_soft_rst_n[extClusterIdx] = + ~reg2hw.reset_cluster[extClusterIdx].RESET_CLUSTER.value; end // The Rst used for each cluster is the AND gate among all different source of rst in the system that are: diff --git a/hw/regs/chimera_reg_pkg.sv b/hw/regs/chimera_reg_pkg.sv deleted file mode 100644 index 13c3349..0000000 --- a/hw/regs/chimera_reg_pkg.sv +++ /dev/null @@ -1,199 +0,0 @@ -// Copyright lowRISC contributors. -// Licensed under the Apache License, Version 2.0, see LICENSE for details. -// SPDX-License-Identifier: Apache-2.0 -// -// Register Package auto-generated by `reggen` containing data structure - -package chimera_reg_pkg; - - // Address widths within the block - parameter int BlockAw = 7; - - //////////////////////////// - // Typedefs for registers // - //////////////////////////// - - typedef struct packed {logic [31:0] q;} chimera_reg2hw_snitch_boot_addr_reg_t; - - typedef struct packed {logic [31:0] q;} chimera_reg2hw_snitch_configurable_boot_addr_reg_t; - - typedef struct packed {logic [31:0] q;} chimera_reg2hw_snitch_intr_handler_addr_reg_t; - - typedef struct packed {logic [31:0] q;} chimera_reg2hw_snitch_cluster_0_return_reg_t; - - typedef struct packed {logic [31:0] q;} chimera_reg2hw_snitch_cluster_1_return_reg_t; - - typedef struct packed {logic [31:0] q;} chimera_reg2hw_snitch_cluster_2_return_reg_t; - - typedef struct packed {logic [31:0] q;} chimera_reg2hw_snitch_cluster_3_return_reg_t; - - typedef struct packed {logic [31:0] q;} chimera_reg2hw_snitch_cluster_4_return_reg_t; - - typedef struct packed {logic q;} chimera_reg2hw_reset_cluster_0_reg_t; - - typedef struct packed {logic q;} chimera_reg2hw_reset_cluster_1_reg_t; - - typedef struct packed {logic q;} chimera_reg2hw_reset_cluster_2_reg_t; - - typedef struct packed {logic q;} chimera_reg2hw_reset_cluster_3_reg_t; - - typedef struct packed {logic q;} chimera_reg2hw_reset_cluster_4_reg_t; - - typedef struct packed {logic q;} chimera_reg2hw_cluster_0_clk_gate_en_reg_t; - - typedef struct packed {logic q;} chimera_reg2hw_cluster_1_clk_gate_en_reg_t; - - typedef struct packed {logic q;} chimera_reg2hw_cluster_2_clk_gate_en_reg_t; - - typedef struct packed {logic q;} chimera_reg2hw_cluster_3_clk_gate_en_reg_t; - - typedef struct packed {logic q;} chimera_reg2hw_cluster_4_clk_gate_en_reg_t; - - typedef struct packed {logic q;} chimera_reg2hw_wide_mem_cluster_0_bypass_reg_t; - - typedef struct packed {logic q;} chimera_reg2hw_wide_mem_cluster_1_bypass_reg_t; - - typedef struct packed {logic q;} chimera_reg2hw_wide_mem_cluster_2_bypass_reg_t; - - typedef struct packed {logic q;} chimera_reg2hw_wide_mem_cluster_3_bypass_reg_t; - - typedef struct packed {logic q;} chimera_reg2hw_wide_mem_cluster_4_bypass_reg_t; - - typedef struct packed {logic q;} chimera_reg2hw_cluster_0_busy_reg_t; - - typedef struct packed {logic q;} chimera_reg2hw_cluster_1_busy_reg_t; - - typedef struct packed {logic q;} chimera_reg2hw_cluster_2_busy_reg_t; - - typedef struct packed {logic q;} chimera_reg2hw_cluster_3_busy_reg_t; - - typedef struct packed {logic q;} chimera_reg2hw_cluster_4_busy_reg_t; - - // Register -> HW type - typedef struct packed { - chimera_reg2hw_snitch_boot_addr_reg_t snitch_boot_addr; // [275:244] - chimera_reg2hw_snitch_configurable_boot_addr_reg_t snitch_configurable_boot_addr; // [243:212] - chimera_reg2hw_snitch_intr_handler_addr_reg_t snitch_intr_handler_addr; // [211:180] - chimera_reg2hw_snitch_cluster_0_return_reg_t snitch_cluster_0_return; // [179:148] - chimera_reg2hw_snitch_cluster_1_return_reg_t snitch_cluster_1_return; // [147:116] - chimera_reg2hw_snitch_cluster_2_return_reg_t snitch_cluster_2_return; // [115:84] - chimera_reg2hw_snitch_cluster_3_return_reg_t snitch_cluster_3_return; // [83:52] - chimera_reg2hw_snitch_cluster_4_return_reg_t snitch_cluster_4_return; // [51:20] - chimera_reg2hw_reset_cluster_0_reg_t reset_cluster_0; // [19:19] - chimera_reg2hw_reset_cluster_1_reg_t reset_cluster_1; // [18:18] - chimera_reg2hw_reset_cluster_2_reg_t reset_cluster_2; // [17:17] - chimera_reg2hw_reset_cluster_3_reg_t reset_cluster_3; // [16:16] - chimera_reg2hw_reset_cluster_4_reg_t reset_cluster_4; // [15:15] - chimera_reg2hw_cluster_0_clk_gate_en_reg_t cluster_0_clk_gate_en; // [14:14] - chimera_reg2hw_cluster_1_clk_gate_en_reg_t cluster_1_clk_gate_en; // [13:13] - chimera_reg2hw_cluster_2_clk_gate_en_reg_t cluster_2_clk_gate_en; // [12:12] - chimera_reg2hw_cluster_3_clk_gate_en_reg_t cluster_3_clk_gate_en; // [11:11] - chimera_reg2hw_cluster_4_clk_gate_en_reg_t cluster_4_clk_gate_en; // [10:10] - chimera_reg2hw_wide_mem_cluster_0_bypass_reg_t wide_mem_cluster_0_bypass; // [9:9] - chimera_reg2hw_wide_mem_cluster_1_bypass_reg_t wide_mem_cluster_1_bypass; // [8:8] - chimera_reg2hw_wide_mem_cluster_2_bypass_reg_t wide_mem_cluster_2_bypass; // [7:7] - chimera_reg2hw_wide_mem_cluster_3_bypass_reg_t wide_mem_cluster_3_bypass; // [6:6] - chimera_reg2hw_wide_mem_cluster_4_bypass_reg_t wide_mem_cluster_4_bypass; // [5:5] - chimera_reg2hw_cluster_0_busy_reg_t cluster_0_busy; // [4:4] - chimera_reg2hw_cluster_1_busy_reg_t cluster_1_busy; // [3:3] - chimera_reg2hw_cluster_2_busy_reg_t cluster_2_busy; // [2:2] - chimera_reg2hw_cluster_3_busy_reg_t cluster_3_busy; // [1:1] - chimera_reg2hw_cluster_4_busy_reg_t cluster_4_busy; // [0:0] - } chimera_reg2hw_t; - - // Register offsets - parameter logic [BlockAw-1:0] CHIMERA_SNITCH_BOOT_ADDR_OFFSET = 7'h0; - parameter logic [BlockAw-1:0] CHIMERA_SNITCH_CONFIGURABLE_BOOT_ADDR_OFFSET = 7'h4; - parameter logic [BlockAw-1:0] CHIMERA_SNITCH_INTR_HANDLER_ADDR_OFFSET = 7'h8; - parameter logic [BlockAw-1:0] CHIMERA_SNITCH_CLUSTER_0_RETURN_OFFSET = 7'hc; - parameter logic [BlockAw-1:0] CHIMERA_SNITCH_CLUSTER_1_RETURN_OFFSET = 7'h10; - parameter logic [BlockAw-1:0] CHIMERA_SNITCH_CLUSTER_2_RETURN_OFFSET = 7'h14; - parameter logic [BlockAw-1:0] CHIMERA_SNITCH_CLUSTER_3_RETURN_OFFSET = 7'h18; - parameter logic [BlockAw-1:0] CHIMERA_SNITCH_CLUSTER_4_RETURN_OFFSET = 7'h1c; - parameter logic [BlockAw-1:0] CHIMERA_RESET_CLUSTER_0_OFFSET = 7'h20; - parameter logic [BlockAw-1:0] CHIMERA_RESET_CLUSTER_1_OFFSET = 7'h24; - parameter logic [BlockAw-1:0] CHIMERA_RESET_CLUSTER_2_OFFSET = 7'h28; - parameter logic [BlockAw-1:0] CHIMERA_RESET_CLUSTER_3_OFFSET = 7'h2c; - parameter logic [BlockAw-1:0] CHIMERA_RESET_CLUSTER_4_OFFSET = 7'h30; - parameter logic [BlockAw-1:0] CHIMERA_CLUSTER_0_CLK_GATE_EN_OFFSET = 7'h34; - parameter logic [BlockAw-1:0] CHIMERA_CLUSTER_1_CLK_GATE_EN_OFFSET = 7'h38; - parameter logic [BlockAw-1:0] CHIMERA_CLUSTER_2_CLK_GATE_EN_OFFSET = 7'h3c; - parameter logic [BlockAw-1:0] CHIMERA_CLUSTER_3_CLK_GATE_EN_OFFSET = 7'h40; - parameter logic [BlockAw-1:0] CHIMERA_CLUSTER_4_CLK_GATE_EN_OFFSET = 7'h44; - parameter logic [BlockAw-1:0] CHIMERA_WIDE_MEM_CLUSTER_0_BYPASS_OFFSET = 7'h48; - parameter logic [BlockAw-1:0] CHIMERA_WIDE_MEM_CLUSTER_1_BYPASS_OFFSET = 7'h4c; - parameter logic [BlockAw-1:0] CHIMERA_WIDE_MEM_CLUSTER_2_BYPASS_OFFSET = 7'h50; - parameter logic [BlockAw-1:0] CHIMERA_WIDE_MEM_CLUSTER_3_BYPASS_OFFSET = 7'h54; - parameter logic [BlockAw-1:0] CHIMERA_WIDE_MEM_CLUSTER_4_BYPASS_OFFSET = 7'h58; - parameter logic [BlockAw-1:0] CHIMERA_CLUSTER_0_BUSY_OFFSET = 7'h5c; - parameter logic [BlockAw-1:0] CHIMERA_CLUSTER_1_BUSY_OFFSET = 7'h60; - parameter logic [BlockAw-1:0] CHIMERA_CLUSTER_2_BUSY_OFFSET = 7'h64; - parameter logic [BlockAw-1:0] CHIMERA_CLUSTER_3_BUSY_OFFSET = 7'h68; - parameter logic [BlockAw-1:0] CHIMERA_CLUSTER_4_BUSY_OFFSET = 7'h6c; - - // Register index - typedef enum int { - CHIMERA_SNITCH_BOOT_ADDR, - CHIMERA_SNITCH_CONFIGURABLE_BOOT_ADDR, - CHIMERA_SNITCH_INTR_HANDLER_ADDR, - CHIMERA_SNITCH_CLUSTER_0_RETURN, - CHIMERA_SNITCH_CLUSTER_1_RETURN, - CHIMERA_SNITCH_CLUSTER_2_RETURN, - CHIMERA_SNITCH_CLUSTER_3_RETURN, - CHIMERA_SNITCH_CLUSTER_4_RETURN, - CHIMERA_RESET_CLUSTER_0, - CHIMERA_RESET_CLUSTER_1, - CHIMERA_RESET_CLUSTER_2, - CHIMERA_RESET_CLUSTER_3, - CHIMERA_RESET_CLUSTER_4, - CHIMERA_CLUSTER_0_CLK_GATE_EN, - CHIMERA_CLUSTER_1_CLK_GATE_EN, - CHIMERA_CLUSTER_2_CLK_GATE_EN, - CHIMERA_CLUSTER_3_CLK_GATE_EN, - CHIMERA_CLUSTER_4_CLK_GATE_EN, - CHIMERA_WIDE_MEM_CLUSTER_0_BYPASS, - CHIMERA_WIDE_MEM_CLUSTER_1_BYPASS, - CHIMERA_WIDE_MEM_CLUSTER_2_BYPASS, - CHIMERA_WIDE_MEM_CLUSTER_3_BYPASS, - CHIMERA_WIDE_MEM_CLUSTER_4_BYPASS, - CHIMERA_CLUSTER_0_BUSY, - CHIMERA_CLUSTER_1_BUSY, - CHIMERA_CLUSTER_2_BUSY, - CHIMERA_CLUSTER_3_BUSY, - CHIMERA_CLUSTER_4_BUSY - } chimera_id_e; - - // Register width information to check illegal writes - parameter logic [3:0] CHIMERA_PERMIT[28] = '{ - 4'b1111, // index[ 0] CHIMERA_SNITCH_BOOT_ADDR - 4'b1111, // index[ 1] CHIMERA_SNITCH_CONFIGURABLE_BOOT_ADDR - 4'b1111, // index[ 2] CHIMERA_SNITCH_INTR_HANDLER_ADDR - 4'b1111, // index[ 3] CHIMERA_SNITCH_CLUSTER_0_RETURN - 4'b1111, // index[ 4] CHIMERA_SNITCH_CLUSTER_1_RETURN - 4'b1111, // index[ 5] CHIMERA_SNITCH_CLUSTER_2_RETURN - 4'b1111, // index[ 6] CHIMERA_SNITCH_CLUSTER_3_RETURN - 4'b1111, // index[ 7] CHIMERA_SNITCH_CLUSTER_4_RETURN - 4'b0001, // index[ 8] CHIMERA_RESET_CLUSTER_0 - 4'b0001, // index[ 9] CHIMERA_RESET_CLUSTER_1 - 4'b0001, // index[10] CHIMERA_RESET_CLUSTER_2 - 4'b0001, // index[11] CHIMERA_RESET_CLUSTER_3 - 4'b0001, // index[12] CHIMERA_RESET_CLUSTER_4 - 4'b0001, // index[13] CHIMERA_CLUSTER_0_CLK_GATE_EN - 4'b0001, // index[14] CHIMERA_CLUSTER_1_CLK_GATE_EN - 4'b0001, // index[15] CHIMERA_CLUSTER_2_CLK_GATE_EN - 4'b0001, // index[16] CHIMERA_CLUSTER_3_CLK_GATE_EN - 4'b0001, // index[17] CHIMERA_CLUSTER_4_CLK_GATE_EN - 4'b0001, // index[18] CHIMERA_WIDE_MEM_CLUSTER_0_BYPASS - 4'b0001, // index[19] CHIMERA_WIDE_MEM_CLUSTER_1_BYPASS - 4'b0001, // index[20] CHIMERA_WIDE_MEM_CLUSTER_2_BYPASS - 4'b0001, // index[21] CHIMERA_WIDE_MEM_CLUSTER_3_BYPASS - 4'b0001, // index[22] CHIMERA_WIDE_MEM_CLUSTER_4_BYPASS - 4'b0001, // index[23] CHIMERA_CLUSTER_0_BUSY - 4'b0001, // index[24] CHIMERA_CLUSTER_1_BUSY - 4'b0001, // index[25] CHIMERA_CLUSTER_2_BUSY - 4'b0001, // index[26] CHIMERA_CLUSTER_3_BUSY - 4'b0001 // index[27] CHIMERA_CLUSTER_4_BUSY - }; - -endpackage - diff --git a/hw/regs/chimera_reg_top.sv b/hw/regs/chimera_reg_top.sv deleted file mode 100644 index d6d5033..0000000 --- a/hw/regs/chimera_reg_top.sv +++ /dev/null @@ -1,1249 +0,0 @@ -// Copyright lowRISC contributors. -// Licensed under the Apache License, Version 2.0, see LICENSE for details. -// SPDX-License-Identifier: Apache-2.0 -// -// Register Top module auto-generated by `reggen` - - -`include "common_cells/assertions.svh" - -module chimera_reg_top #( - parameter type reg_req_t = logic, - parameter type reg_rsp_t = logic, - parameter int AW = 7 -) ( - input logic clk_i, - input logic rst_ni, - input reg_req_t reg_req_i, - output reg_rsp_t reg_rsp_o, - // To HW - output chimera_reg_pkg::chimera_reg2hw_t reg2hw, // Write - - - // Config - input devmode_i // If 1, explicit error return for unmapped register access -); - - import chimera_reg_pkg::*; - - localparam int DW = 32; - localparam int DBW = DW / 8; // Byte Width - - // register signals - logic reg_we; - logic reg_re; - logic [BlockAw-1:0] reg_addr; - logic [ DW-1:0] reg_wdata; - logic [ DBW-1:0] reg_be; - logic [ DW-1:0] reg_rdata; - logic reg_error; - - logic addrmiss, wr_err; - - logic [DW-1:0] reg_rdata_next; - - // Below register interface can be changed - reg_req_t reg_intf_req; - reg_rsp_t reg_intf_rsp; - - - assign reg_intf_req = reg_req_i; - assign reg_rsp_o = reg_intf_rsp; - - - assign reg_we = reg_intf_req.valid & reg_intf_req.write; - assign reg_re = reg_intf_req.valid & ~reg_intf_req.write; - assign reg_addr = reg_intf_req.addr[BlockAw-1:0]; - assign reg_wdata = reg_intf_req.wdata; - assign reg_be = reg_intf_req.wstrb; - assign reg_intf_rsp.rdata = reg_rdata; - assign reg_intf_rsp.error = reg_error; - assign reg_intf_rsp.ready = 1'b1; - - assign reg_rdata = reg_rdata_next; - assign reg_error = (devmode_i & addrmiss) | wr_err; - - - // Define SW related signals - // Format: __{wd|we|qs} - // or _{wd|we|qs} if field == 1 or 0 - logic [31:0] snitch_boot_addr_qs; - logic [31:0] snitch_boot_addr_wd; - logic snitch_boot_addr_we; - logic [31:0] snitch_configurable_boot_addr_qs; - logic [31:0] snitch_configurable_boot_addr_wd; - logic snitch_configurable_boot_addr_we; - logic [31:0] snitch_intr_handler_addr_qs; - logic [31:0] snitch_intr_handler_addr_wd; - logic snitch_intr_handler_addr_we; - logic [31:0] snitch_cluster_0_return_qs; - logic [31:0] snitch_cluster_0_return_wd; - logic snitch_cluster_0_return_we; - logic [31:0] snitch_cluster_1_return_qs; - logic [31:0] snitch_cluster_1_return_wd; - logic snitch_cluster_1_return_we; - logic [31:0] snitch_cluster_2_return_qs; - logic [31:0] snitch_cluster_2_return_wd; - logic snitch_cluster_2_return_we; - logic [31:0] snitch_cluster_3_return_qs; - logic [31:0] snitch_cluster_3_return_wd; - logic snitch_cluster_3_return_we; - logic [31:0] snitch_cluster_4_return_qs; - logic [31:0] snitch_cluster_4_return_wd; - logic snitch_cluster_4_return_we; - logic reset_cluster_0_qs; - logic reset_cluster_0_wd; - logic reset_cluster_0_we; - logic reset_cluster_1_qs; - logic reset_cluster_1_wd; - logic reset_cluster_1_we; - logic reset_cluster_2_qs; - logic reset_cluster_2_wd; - logic reset_cluster_2_we; - logic reset_cluster_3_qs; - logic reset_cluster_3_wd; - logic reset_cluster_3_we; - logic reset_cluster_4_qs; - logic reset_cluster_4_wd; - logic reset_cluster_4_we; - logic cluster_0_clk_gate_en_qs; - logic cluster_0_clk_gate_en_wd; - logic cluster_0_clk_gate_en_we; - logic cluster_1_clk_gate_en_qs; - logic cluster_1_clk_gate_en_wd; - logic cluster_1_clk_gate_en_we; - logic cluster_2_clk_gate_en_qs; - logic cluster_2_clk_gate_en_wd; - logic cluster_2_clk_gate_en_we; - logic cluster_3_clk_gate_en_qs; - logic cluster_3_clk_gate_en_wd; - logic cluster_3_clk_gate_en_we; - logic cluster_4_clk_gate_en_qs; - logic cluster_4_clk_gate_en_wd; - logic cluster_4_clk_gate_en_we; - logic wide_mem_cluster_0_bypass_qs; - logic wide_mem_cluster_0_bypass_wd; - logic wide_mem_cluster_0_bypass_we; - logic wide_mem_cluster_1_bypass_qs; - logic wide_mem_cluster_1_bypass_wd; - logic wide_mem_cluster_1_bypass_we; - logic wide_mem_cluster_2_bypass_qs; - logic wide_mem_cluster_2_bypass_wd; - logic wide_mem_cluster_2_bypass_we; - logic wide_mem_cluster_3_bypass_qs; - logic wide_mem_cluster_3_bypass_wd; - logic wide_mem_cluster_3_bypass_we; - logic wide_mem_cluster_4_bypass_qs; - logic wide_mem_cluster_4_bypass_wd; - logic wide_mem_cluster_4_bypass_we; - logic cluster_0_busy_qs; - logic cluster_0_busy_wd; - logic cluster_0_busy_we; - logic cluster_1_busy_qs; - logic cluster_1_busy_wd; - logic cluster_1_busy_we; - logic cluster_2_busy_qs; - logic cluster_2_busy_wd; - logic cluster_2_busy_we; - logic cluster_3_busy_qs; - logic cluster_3_busy_wd; - logic cluster_3_busy_we; - logic cluster_4_busy_qs; - logic cluster_4_busy_wd; - logic cluster_4_busy_we; - - // Register instances - // R[snitch_boot_addr]: V(False) - - prim_subreg #( - .DW (32), - .SWACCESS("RW"), - .RESVAL (32'hbadcab1e) - ) u_snitch_boot_addr ( - .clk_i (clk_i), - .rst_ni(rst_ni), - - // from register interface - .we(snitch_boot_addr_we), - .wd(snitch_boot_addr_wd), - - // from internal hardware - .de(1'b0), - .d ('0), - - // to internal hardware - .qe(), - .q (reg2hw.snitch_boot_addr.q), - - // to register interface (read) - .qs(snitch_boot_addr_qs) - ); - - - // R[snitch_configurable_boot_addr]: V(False) - - prim_subreg #( - .DW (32), - .SWACCESS("RW"), - .RESVAL (32'h30000000) - ) u_snitch_configurable_boot_addr ( - .clk_i (clk_i), - .rst_ni(rst_ni), - - // from register interface - .we(snitch_configurable_boot_addr_we), - .wd(snitch_configurable_boot_addr_wd), - - // from internal hardware - .de(1'b0), - .d ('0), - - // to internal hardware - .qe(), - .q (reg2hw.snitch_configurable_boot_addr.q), - - // to register interface (read) - .qs(snitch_configurable_boot_addr_qs) - ); - - - // R[snitch_intr_handler_addr]: V(False) - - prim_subreg #( - .DW (32), - .SWACCESS("RW"), - .RESVAL (32'hbadcab1e) - ) u_snitch_intr_handler_addr ( - .clk_i (clk_i), - .rst_ni(rst_ni), - - // from register interface - .we(snitch_intr_handler_addr_we), - .wd(snitch_intr_handler_addr_wd), - - // from internal hardware - .de(1'b0), - .d ('0), - - // to internal hardware - .qe(), - .q (reg2hw.snitch_intr_handler_addr.q), - - // to register interface (read) - .qs(snitch_intr_handler_addr_qs) - ); - - - // R[snitch_cluster_0_return]: V(False) - - prim_subreg #( - .DW (32), - .SWACCESS("RW"), - .RESVAL (32'h0) - ) u_snitch_cluster_0_return ( - .clk_i (clk_i), - .rst_ni(rst_ni), - - // from register interface - .we(snitch_cluster_0_return_we), - .wd(snitch_cluster_0_return_wd), - - // from internal hardware - .de(1'b0), - .d ('0), - - // to internal hardware - .qe(), - .q (reg2hw.snitch_cluster_0_return.q), - - // to register interface (read) - .qs(snitch_cluster_0_return_qs) - ); - - - // R[snitch_cluster_1_return]: V(False) - - prim_subreg #( - .DW (32), - .SWACCESS("RW"), - .RESVAL (32'h0) - ) u_snitch_cluster_1_return ( - .clk_i (clk_i), - .rst_ni(rst_ni), - - // from register interface - .we(snitch_cluster_1_return_we), - .wd(snitch_cluster_1_return_wd), - - // from internal hardware - .de(1'b0), - .d ('0), - - // to internal hardware - .qe(), - .q (reg2hw.snitch_cluster_1_return.q), - - // to register interface (read) - .qs(snitch_cluster_1_return_qs) - ); - - - // R[snitch_cluster_2_return]: V(False) - - prim_subreg #( - .DW (32), - .SWACCESS("RW"), - .RESVAL (32'h0) - ) u_snitch_cluster_2_return ( - .clk_i (clk_i), - .rst_ni(rst_ni), - - // from register interface - .we(snitch_cluster_2_return_we), - .wd(snitch_cluster_2_return_wd), - - // from internal hardware - .de(1'b0), - .d ('0), - - // to internal hardware - .qe(), - .q (reg2hw.snitch_cluster_2_return.q), - - // to register interface (read) - .qs(snitch_cluster_2_return_qs) - ); - - - // R[snitch_cluster_3_return]: V(False) - - prim_subreg #( - .DW (32), - .SWACCESS("RW"), - .RESVAL (32'h0) - ) u_snitch_cluster_3_return ( - .clk_i (clk_i), - .rst_ni(rst_ni), - - // from register interface - .we(snitch_cluster_3_return_we), - .wd(snitch_cluster_3_return_wd), - - // from internal hardware - .de(1'b0), - .d ('0), - - // to internal hardware - .qe(), - .q (reg2hw.snitch_cluster_3_return.q), - - // to register interface (read) - .qs(snitch_cluster_3_return_qs) - ); - - - // R[snitch_cluster_4_return]: V(False) - - prim_subreg #( - .DW (32), - .SWACCESS("RW"), - .RESVAL (32'h0) - ) u_snitch_cluster_4_return ( - .clk_i (clk_i), - .rst_ni(rst_ni), - - // from register interface - .we(snitch_cluster_4_return_we), - .wd(snitch_cluster_4_return_wd), - - // from internal hardware - .de(1'b0), - .d ('0), - - // to internal hardware - .qe(), - .q (reg2hw.snitch_cluster_4_return.q), - - // to register interface (read) - .qs(snitch_cluster_4_return_qs) - ); - - - // R[reset_cluster_0]: V(False) - - prim_subreg #( - .DW (1), - .SWACCESS("RW"), - .RESVAL (1'h1) - ) u_reset_cluster_0 ( - .clk_i (clk_i), - .rst_ni(rst_ni), - - // from register interface - .we(reset_cluster_0_we), - .wd(reset_cluster_0_wd), - - // from internal hardware - .de(1'b0), - .d ('0), - - // to internal hardware - .qe(), - .q (reg2hw.reset_cluster_0.q), - - // to register interface (read) - .qs(reset_cluster_0_qs) - ); - - - // R[reset_cluster_1]: V(False) - - prim_subreg #( - .DW (1), - .SWACCESS("RW"), - .RESVAL (1'h1) - ) u_reset_cluster_1 ( - .clk_i (clk_i), - .rst_ni(rst_ni), - - // from register interface - .we(reset_cluster_1_we), - .wd(reset_cluster_1_wd), - - // from internal hardware - .de(1'b0), - .d ('0), - - // to internal hardware - .qe(), - .q (reg2hw.reset_cluster_1.q), - - // to register interface (read) - .qs(reset_cluster_1_qs) - ); - - - // R[reset_cluster_2]: V(False) - - prim_subreg #( - .DW (1), - .SWACCESS("RW"), - .RESVAL (1'h1) - ) u_reset_cluster_2 ( - .clk_i (clk_i), - .rst_ni(rst_ni), - - // from register interface - .we(reset_cluster_2_we), - .wd(reset_cluster_2_wd), - - // from internal hardware - .de(1'b0), - .d ('0), - - // to internal hardware - .qe(), - .q (reg2hw.reset_cluster_2.q), - - // to register interface (read) - .qs(reset_cluster_2_qs) - ); - - - // R[reset_cluster_3]: V(False) - - prim_subreg #( - .DW (1), - .SWACCESS("RW"), - .RESVAL (1'h1) - ) u_reset_cluster_3 ( - .clk_i (clk_i), - .rst_ni(rst_ni), - - // from register interface - .we(reset_cluster_3_we), - .wd(reset_cluster_3_wd), - - // from internal hardware - .de(1'b0), - .d ('0), - - // to internal hardware - .qe(), - .q (reg2hw.reset_cluster_3.q), - - // to register interface (read) - .qs(reset_cluster_3_qs) - ); - - - // R[reset_cluster_4]: V(False) - - prim_subreg #( - .DW (1), - .SWACCESS("RW"), - .RESVAL (1'h1) - ) u_reset_cluster_4 ( - .clk_i (clk_i), - .rst_ni(rst_ni), - - // from register interface - .we(reset_cluster_4_we), - .wd(reset_cluster_4_wd), - - // from internal hardware - .de(1'b0), - .d ('0), - - // to internal hardware - .qe(), - .q (reg2hw.reset_cluster_4.q), - - // to register interface (read) - .qs(reset_cluster_4_qs) - ); - - - // R[cluster_0_clk_gate_en]: V(False) - - prim_subreg #( - .DW (1), - .SWACCESS("RW"), - .RESVAL (1'h1) - ) u_cluster_0_clk_gate_en ( - .clk_i (clk_i), - .rst_ni(rst_ni), - - // from register interface - .we(cluster_0_clk_gate_en_we), - .wd(cluster_0_clk_gate_en_wd), - - // from internal hardware - .de(1'b0), - .d ('0), - - // to internal hardware - .qe(), - .q (reg2hw.cluster_0_clk_gate_en.q), - - // to register interface (read) - .qs(cluster_0_clk_gate_en_qs) - ); - - - // R[cluster_1_clk_gate_en]: V(False) - - prim_subreg #( - .DW (1), - .SWACCESS("RW"), - .RESVAL (1'h1) - ) u_cluster_1_clk_gate_en ( - .clk_i (clk_i), - .rst_ni(rst_ni), - - // from register interface - .we(cluster_1_clk_gate_en_we), - .wd(cluster_1_clk_gate_en_wd), - - // from internal hardware - .de(1'b0), - .d ('0), - - // to internal hardware - .qe(), - .q (reg2hw.cluster_1_clk_gate_en.q), - - // to register interface (read) - .qs(cluster_1_clk_gate_en_qs) - ); - - - // R[cluster_2_clk_gate_en]: V(False) - - prim_subreg #( - .DW (1), - .SWACCESS("RW"), - .RESVAL (1'h1) - ) u_cluster_2_clk_gate_en ( - .clk_i (clk_i), - .rst_ni(rst_ni), - - // from register interface - .we(cluster_2_clk_gate_en_we), - .wd(cluster_2_clk_gate_en_wd), - - // from internal hardware - .de(1'b0), - .d ('0), - - // to internal hardware - .qe(), - .q (reg2hw.cluster_2_clk_gate_en.q), - - // to register interface (read) - .qs(cluster_2_clk_gate_en_qs) - ); - - - // R[cluster_3_clk_gate_en]: V(False) - - prim_subreg #( - .DW (1), - .SWACCESS("RW"), - .RESVAL (1'h1) - ) u_cluster_3_clk_gate_en ( - .clk_i (clk_i), - .rst_ni(rst_ni), - - // from register interface - .we(cluster_3_clk_gate_en_we), - .wd(cluster_3_clk_gate_en_wd), - - // from internal hardware - .de(1'b0), - .d ('0), - - // to internal hardware - .qe(), - .q (reg2hw.cluster_3_clk_gate_en.q), - - // to register interface (read) - .qs(cluster_3_clk_gate_en_qs) - ); - - - // R[cluster_4_clk_gate_en]: V(False) - - prim_subreg #( - .DW (1), - .SWACCESS("RW"), - .RESVAL (1'h1) - ) u_cluster_4_clk_gate_en ( - .clk_i (clk_i), - .rst_ni(rst_ni), - - // from register interface - .we(cluster_4_clk_gate_en_we), - .wd(cluster_4_clk_gate_en_wd), - - // from internal hardware - .de(1'b0), - .d ('0), - - // to internal hardware - .qe(), - .q (reg2hw.cluster_4_clk_gate_en.q), - - // to register interface (read) - .qs(cluster_4_clk_gate_en_qs) - ); - - - // R[wide_mem_cluster_0_bypass]: V(False) - - prim_subreg #( - .DW (1), - .SWACCESS("RW"), - .RESVAL (1'h0) - ) u_wide_mem_cluster_0_bypass ( - .clk_i (clk_i), - .rst_ni(rst_ni), - - // from register interface - .we(wide_mem_cluster_0_bypass_we), - .wd(wide_mem_cluster_0_bypass_wd), - - // from internal hardware - .de(1'b0), - .d ('0), - - // to internal hardware - .qe(), - .q (reg2hw.wide_mem_cluster_0_bypass.q), - - // to register interface (read) - .qs(wide_mem_cluster_0_bypass_qs) - ); - - - // R[wide_mem_cluster_1_bypass]: V(False) - - prim_subreg #( - .DW (1), - .SWACCESS("RW"), - .RESVAL (1'h0) - ) u_wide_mem_cluster_1_bypass ( - .clk_i (clk_i), - .rst_ni(rst_ni), - - // from register interface - .we(wide_mem_cluster_1_bypass_we), - .wd(wide_mem_cluster_1_bypass_wd), - - // from internal hardware - .de(1'b0), - .d ('0), - - // to internal hardware - .qe(), - .q (reg2hw.wide_mem_cluster_1_bypass.q), - - // to register interface (read) - .qs(wide_mem_cluster_1_bypass_qs) - ); - - - // R[wide_mem_cluster_2_bypass]: V(False) - - prim_subreg #( - .DW (1), - .SWACCESS("RW"), - .RESVAL (1'h0) - ) u_wide_mem_cluster_2_bypass ( - .clk_i (clk_i), - .rst_ni(rst_ni), - - // from register interface - .we(wide_mem_cluster_2_bypass_we), - .wd(wide_mem_cluster_2_bypass_wd), - - // from internal hardware - .de(1'b0), - .d ('0), - - // to internal hardware - .qe(), - .q (reg2hw.wide_mem_cluster_2_bypass.q), - - // to register interface (read) - .qs(wide_mem_cluster_2_bypass_qs) - ); - - - // R[wide_mem_cluster_3_bypass]: V(False) - - prim_subreg #( - .DW (1), - .SWACCESS("RW"), - .RESVAL (1'h0) - ) u_wide_mem_cluster_3_bypass ( - .clk_i (clk_i), - .rst_ni(rst_ni), - - // from register interface - .we(wide_mem_cluster_3_bypass_we), - .wd(wide_mem_cluster_3_bypass_wd), - - // from internal hardware - .de(1'b0), - .d ('0), - - // to internal hardware - .qe(), - .q (reg2hw.wide_mem_cluster_3_bypass.q), - - // to register interface (read) - .qs(wide_mem_cluster_3_bypass_qs) - ); - - - // R[wide_mem_cluster_4_bypass]: V(False) - - prim_subreg #( - .DW (1), - .SWACCESS("RW"), - .RESVAL (1'h0) - ) u_wide_mem_cluster_4_bypass ( - .clk_i (clk_i), - .rst_ni(rst_ni), - - // from register interface - .we(wide_mem_cluster_4_bypass_we), - .wd(wide_mem_cluster_4_bypass_wd), - - // from internal hardware - .de(1'b0), - .d ('0), - - // to internal hardware - .qe(), - .q (reg2hw.wide_mem_cluster_4_bypass.q), - - // to register interface (read) - .qs(wide_mem_cluster_4_bypass_qs) - ); - - - // R[cluster_0_busy]: V(False) - - prim_subreg #( - .DW (1), - .SWACCESS("RW"), - .RESVAL (1'h1) - ) u_cluster_0_busy ( - .clk_i (clk_i), - .rst_ni(rst_ni), - - // from register interface - .we(cluster_0_busy_we), - .wd(cluster_0_busy_wd), - - // from internal hardware - .de(1'b0), - .d ('0), - - // to internal hardware - .qe(), - .q (reg2hw.cluster_0_busy.q), - - // to register interface (read) - .qs(cluster_0_busy_qs) - ); - - - // R[cluster_1_busy]: V(False) - - prim_subreg #( - .DW (1), - .SWACCESS("RW"), - .RESVAL (1'h1) - ) u_cluster_1_busy ( - .clk_i (clk_i), - .rst_ni(rst_ni), - - // from register interface - .we(cluster_1_busy_we), - .wd(cluster_1_busy_wd), - - // from internal hardware - .de(1'b0), - .d ('0), - - // to internal hardware - .qe(), - .q (reg2hw.cluster_1_busy.q), - - // to register interface (read) - .qs(cluster_1_busy_qs) - ); - - - // R[cluster_2_busy]: V(False) - - prim_subreg #( - .DW (1), - .SWACCESS("RW"), - .RESVAL (1'h1) - ) u_cluster_2_busy ( - .clk_i (clk_i), - .rst_ni(rst_ni), - - // from register interface - .we(cluster_2_busy_we), - .wd(cluster_2_busy_wd), - - // from internal hardware - .de(1'b0), - .d ('0), - - // to internal hardware - .qe(), - .q (reg2hw.cluster_2_busy.q), - - // to register interface (read) - .qs(cluster_2_busy_qs) - ); - - - // R[cluster_3_busy]: V(False) - - prim_subreg #( - .DW (1), - .SWACCESS("RW"), - .RESVAL (1'h1) - ) u_cluster_3_busy ( - .clk_i (clk_i), - .rst_ni(rst_ni), - - // from register interface - .we(cluster_3_busy_we), - .wd(cluster_3_busy_wd), - - // from internal hardware - .de(1'b0), - .d ('0), - - // to internal hardware - .qe(), - .q (reg2hw.cluster_3_busy.q), - - // to register interface (read) - .qs(cluster_3_busy_qs) - ); - - - // R[cluster_4_busy]: V(False) - - prim_subreg #( - .DW (1), - .SWACCESS("RW"), - .RESVAL (1'h1) - ) u_cluster_4_busy ( - .clk_i (clk_i), - .rst_ni(rst_ni), - - // from register interface - .we(cluster_4_busy_we), - .wd(cluster_4_busy_wd), - - // from internal hardware - .de(1'b0), - .d ('0), - - // to internal hardware - .qe(), - .q (reg2hw.cluster_4_busy.q), - - // to register interface (read) - .qs(cluster_4_busy_qs) - ); - - - - - logic [27:0] addr_hit; - always_comb begin - addr_hit = '0; - addr_hit[0] = (reg_addr == CHIMERA_SNITCH_BOOT_ADDR_OFFSET); - addr_hit[1] = (reg_addr == CHIMERA_SNITCH_CONFIGURABLE_BOOT_ADDR_OFFSET); - addr_hit[2] = (reg_addr == CHIMERA_SNITCH_INTR_HANDLER_ADDR_OFFSET); - addr_hit[3] = (reg_addr == CHIMERA_SNITCH_CLUSTER_0_RETURN_OFFSET); - addr_hit[4] = (reg_addr == CHIMERA_SNITCH_CLUSTER_1_RETURN_OFFSET); - addr_hit[5] = (reg_addr == CHIMERA_SNITCH_CLUSTER_2_RETURN_OFFSET); - addr_hit[6] = (reg_addr == CHIMERA_SNITCH_CLUSTER_3_RETURN_OFFSET); - addr_hit[7] = (reg_addr == CHIMERA_SNITCH_CLUSTER_4_RETURN_OFFSET); - addr_hit[8] = (reg_addr == CHIMERA_RESET_CLUSTER_0_OFFSET); - addr_hit[9] = (reg_addr == CHIMERA_RESET_CLUSTER_1_OFFSET); - addr_hit[10] = (reg_addr == CHIMERA_RESET_CLUSTER_2_OFFSET); - addr_hit[11] = (reg_addr == CHIMERA_RESET_CLUSTER_3_OFFSET); - addr_hit[12] = (reg_addr == CHIMERA_RESET_CLUSTER_4_OFFSET); - addr_hit[13] = (reg_addr == CHIMERA_CLUSTER_0_CLK_GATE_EN_OFFSET); - addr_hit[14] = (reg_addr == CHIMERA_CLUSTER_1_CLK_GATE_EN_OFFSET); - addr_hit[15] = (reg_addr == CHIMERA_CLUSTER_2_CLK_GATE_EN_OFFSET); - addr_hit[16] = (reg_addr == CHIMERA_CLUSTER_3_CLK_GATE_EN_OFFSET); - addr_hit[17] = (reg_addr == CHIMERA_CLUSTER_4_CLK_GATE_EN_OFFSET); - addr_hit[18] = (reg_addr == CHIMERA_WIDE_MEM_CLUSTER_0_BYPASS_OFFSET); - addr_hit[19] = (reg_addr == CHIMERA_WIDE_MEM_CLUSTER_1_BYPASS_OFFSET); - addr_hit[20] = (reg_addr == CHIMERA_WIDE_MEM_CLUSTER_2_BYPASS_OFFSET); - addr_hit[21] = (reg_addr == CHIMERA_WIDE_MEM_CLUSTER_3_BYPASS_OFFSET); - addr_hit[22] = (reg_addr == CHIMERA_WIDE_MEM_CLUSTER_4_BYPASS_OFFSET); - addr_hit[23] = (reg_addr == CHIMERA_CLUSTER_0_BUSY_OFFSET); - addr_hit[24] = (reg_addr == CHIMERA_CLUSTER_1_BUSY_OFFSET); - addr_hit[25] = (reg_addr == CHIMERA_CLUSTER_2_BUSY_OFFSET); - addr_hit[26] = (reg_addr == CHIMERA_CLUSTER_3_BUSY_OFFSET); - addr_hit[27] = (reg_addr == CHIMERA_CLUSTER_4_BUSY_OFFSET); - end - - assign addrmiss = (reg_re || reg_we) ? ~|addr_hit : 1'b0; - - // Check sub-word write is permitted - always_comb begin - wr_err = (reg_we & - ((addr_hit[ 0] & (|(CHIMERA_PERMIT[ 0] & ~reg_be))) | - (addr_hit[ 1] & (|(CHIMERA_PERMIT[ 1] & ~reg_be))) | - (addr_hit[ 2] & (|(CHIMERA_PERMIT[ 2] & ~reg_be))) | - (addr_hit[ 3] & (|(CHIMERA_PERMIT[ 3] & ~reg_be))) | - (addr_hit[ 4] & (|(CHIMERA_PERMIT[ 4] & ~reg_be))) | - (addr_hit[ 5] & (|(CHIMERA_PERMIT[ 5] & ~reg_be))) | - (addr_hit[ 6] & (|(CHIMERA_PERMIT[ 6] & ~reg_be))) | - (addr_hit[ 7] & (|(CHIMERA_PERMIT[ 7] & ~reg_be))) | - (addr_hit[ 8] & (|(CHIMERA_PERMIT[ 8] & ~reg_be))) | - (addr_hit[ 9] & (|(CHIMERA_PERMIT[ 9] & ~reg_be))) | - (addr_hit[10] & (|(CHIMERA_PERMIT[10] & ~reg_be))) | - (addr_hit[11] & (|(CHIMERA_PERMIT[11] & ~reg_be))) | - (addr_hit[12] & (|(CHIMERA_PERMIT[12] & ~reg_be))) | - (addr_hit[13] & (|(CHIMERA_PERMIT[13] & ~reg_be))) | - (addr_hit[14] & (|(CHIMERA_PERMIT[14] & ~reg_be))) | - (addr_hit[15] & (|(CHIMERA_PERMIT[15] & ~reg_be))) | - (addr_hit[16] & (|(CHIMERA_PERMIT[16] & ~reg_be))) | - (addr_hit[17] & (|(CHIMERA_PERMIT[17] & ~reg_be))) | - (addr_hit[18] & (|(CHIMERA_PERMIT[18] & ~reg_be))) | - (addr_hit[19] & (|(CHIMERA_PERMIT[19] & ~reg_be))) | - (addr_hit[20] & (|(CHIMERA_PERMIT[20] & ~reg_be))) | - (addr_hit[21] & (|(CHIMERA_PERMIT[21] & ~reg_be))) | - (addr_hit[22] & (|(CHIMERA_PERMIT[22] & ~reg_be))) | - (addr_hit[23] & (|(CHIMERA_PERMIT[23] & ~reg_be))) | - (addr_hit[24] & (|(CHIMERA_PERMIT[24] & ~reg_be))) | - (addr_hit[25] & (|(CHIMERA_PERMIT[25] & ~reg_be))) | - (addr_hit[26] & (|(CHIMERA_PERMIT[26] & ~reg_be))) | - (addr_hit[27] & (|(CHIMERA_PERMIT[27] & ~reg_be))))); - end - - assign snitch_boot_addr_we = addr_hit[0] & reg_we & !reg_error; - assign snitch_boot_addr_wd = reg_wdata[31:0]; - - assign snitch_configurable_boot_addr_we = addr_hit[1] & reg_we & !reg_error; - assign snitch_configurable_boot_addr_wd = reg_wdata[31:0]; - - assign snitch_intr_handler_addr_we = addr_hit[2] & reg_we & !reg_error; - assign snitch_intr_handler_addr_wd = reg_wdata[31:0]; - - assign snitch_cluster_0_return_we = addr_hit[3] & reg_we & !reg_error; - assign snitch_cluster_0_return_wd = reg_wdata[31:0]; - - assign snitch_cluster_1_return_we = addr_hit[4] & reg_we & !reg_error; - assign snitch_cluster_1_return_wd = reg_wdata[31:0]; - - assign snitch_cluster_2_return_we = addr_hit[5] & reg_we & !reg_error; - assign snitch_cluster_2_return_wd = reg_wdata[31:0]; - - assign snitch_cluster_3_return_we = addr_hit[6] & reg_we & !reg_error; - assign snitch_cluster_3_return_wd = reg_wdata[31:0]; - - assign snitch_cluster_4_return_we = addr_hit[7] & reg_we & !reg_error; - assign snitch_cluster_4_return_wd = reg_wdata[31:0]; - - assign reset_cluster_0_we = addr_hit[8] & reg_we & !reg_error; - assign reset_cluster_0_wd = reg_wdata[0]; - - assign reset_cluster_1_we = addr_hit[9] & reg_we & !reg_error; - assign reset_cluster_1_wd = reg_wdata[0]; - - assign reset_cluster_2_we = addr_hit[10] & reg_we & !reg_error; - assign reset_cluster_2_wd = reg_wdata[0]; - - assign reset_cluster_3_we = addr_hit[11] & reg_we & !reg_error; - assign reset_cluster_3_wd = reg_wdata[0]; - - assign reset_cluster_4_we = addr_hit[12] & reg_we & !reg_error; - assign reset_cluster_4_wd = reg_wdata[0]; - - assign cluster_0_clk_gate_en_we = addr_hit[13] & reg_we & !reg_error; - assign cluster_0_clk_gate_en_wd = reg_wdata[0]; - - assign cluster_1_clk_gate_en_we = addr_hit[14] & reg_we & !reg_error; - assign cluster_1_clk_gate_en_wd = reg_wdata[0]; - - assign cluster_2_clk_gate_en_we = addr_hit[15] & reg_we & !reg_error; - assign cluster_2_clk_gate_en_wd = reg_wdata[0]; - - assign cluster_3_clk_gate_en_we = addr_hit[16] & reg_we & !reg_error; - assign cluster_3_clk_gate_en_wd = reg_wdata[0]; - - assign cluster_4_clk_gate_en_we = addr_hit[17] & reg_we & !reg_error; - assign cluster_4_clk_gate_en_wd = reg_wdata[0]; - - assign wide_mem_cluster_0_bypass_we = addr_hit[18] & reg_we & !reg_error; - assign wide_mem_cluster_0_bypass_wd = reg_wdata[0]; - - assign wide_mem_cluster_1_bypass_we = addr_hit[19] & reg_we & !reg_error; - assign wide_mem_cluster_1_bypass_wd = reg_wdata[0]; - - assign wide_mem_cluster_2_bypass_we = addr_hit[20] & reg_we & !reg_error; - assign wide_mem_cluster_2_bypass_wd = reg_wdata[0]; - - assign wide_mem_cluster_3_bypass_we = addr_hit[21] & reg_we & !reg_error; - assign wide_mem_cluster_3_bypass_wd = reg_wdata[0]; - - assign wide_mem_cluster_4_bypass_we = addr_hit[22] & reg_we & !reg_error; - assign wide_mem_cluster_4_bypass_wd = reg_wdata[0]; - - assign cluster_0_busy_we = addr_hit[23] & reg_we & !reg_error; - assign cluster_0_busy_wd = reg_wdata[0]; - - assign cluster_1_busy_we = addr_hit[24] & reg_we & !reg_error; - assign cluster_1_busy_wd = reg_wdata[0]; - - assign cluster_2_busy_we = addr_hit[25] & reg_we & !reg_error; - assign cluster_2_busy_wd = reg_wdata[0]; - - assign cluster_3_busy_we = addr_hit[26] & reg_we & !reg_error; - assign cluster_3_busy_wd = reg_wdata[0]; - - assign cluster_4_busy_we = addr_hit[27] & reg_we & !reg_error; - assign cluster_4_busy_wd = reg_wdata[0]; - - // Read data return - always_comb begin - reg_rdata_next = '0; - unique case (1'b1) - addr_hit[0]: begin - reg_rdata_next[31:0] = snitch_boot_addr_qs; - end - - addr_hit[1]: begin - reg_rdata_next[31:0] = snitch_configurable_boot_addr_qs; - end - - addr_hit[2]: begin - reg_rdata_next[31:0] = snitch_intr_handler_addr_qs; - end - - addr_hit[3]: begin - reg_rdata_next[31:0] = snitch_cluster_0_return_qs; - end - - addr_hit[4]: begin - reg_rdata_next[31:0] = snitch_cluster_1_return_qs; - end - - addr_hit[5]: begin - reg_rdata_next[31:0] = snitch_cluster_2_return_qs; - end - - addr_hit[6]: begin - reg_rdata_next[31:0] = snitch_cluster_3_return_qs; - end - - addr_hit[7]: begin - reg_rdata_next[31:0] = snitch_cluster_4_return_qs; - end - - addr_hit[8]: begin - reg_rdata_next[0] = reset_cluster_0_qs; - end - - addr_hit[9]: begin - reg_rdata_next[0] = reset_cluster_1_qs; - end - - addr_hit[10]: begin - reg_rdata_next[0] = reset_cluster_2_qs; - end - - addr_hit[11]: begin - reg_rdata_next[0] = reset_cluster_3_qs; - end - - addr_hit[12]: begin - reg_rdata_next[0] = reset_cluster_4_qs; - end - - addr_hit[13]: begin - reg_rdata_next[0] = cluster_0_clk_gate_en_qs; - end - - addr_hit[14]: begin - reg_rdata_next[0] = cluster_1_clk_gate_en_qs; - end - - addr_hit[15]: begin - reg_rdata_next[0] = cluster_2_clk_gate_en_qs; - end - - addr_hit[16]: begin - reg_rdata_next[0] = cluster_3_clk_gate_en_qs; - end - - addr_hit[17]: begin - reg_rdata_next[0] = cluster_4_clk_gate_en_qs; - end - - addr_hit[18]: begin - reg_rdata_next[0] = wide_mem_cluster_0_bypass_qs; - end - - addr_hit[19]: begin - reg_rdata_next[0] = wide_mem_cluster_1_bypass_qs; - end - - addr_hit[20]: begin - reg_rdata_next[0] = wide_mem_cluster_2_bypass_qs; - end - - addr_hit[21]: begin - reg_rdata_next[0] = wide_mem_cluster_3_bypass_qs; - end - - addr_hit[22]: begin - reg_rdata_next[0] = wide_mem_cluster_4_bypass_qs; - end - - addr_hit[23]: begin - reg_rdata_next[0] = cluster_0_busy_qs; - end - - addr_hit[24]: begin - reg_rdata_next[0] = cluster_1_busy_qs; - end - - addr_hit[25]: begin - reg_rdata_next[0] = cluster_2_busy_qs; - end - - addr_hit[26]: begin - reg_rdata_next[0] = cluster_3_busy_qs; - end - - addr_hit[27]: begin - reg_rdata_next[0] = cluster_4_busy_qs; - end - - default: begin - reg_rdata_next = '1; - end - endcase - end - - // Unused signal tieoff - - // wdata / byte enable are not always fully used - // add a blanket unused statement to handle lint waivers - logic unused_wdata; - logic unused_be; - assign unused_wdata = ^reg_wdata; - assign unused_be = ^reg_be; - - // Assertions for Register Interface - `ASSERT(en2addrHit, (reg_we || reg_re) |-> $onehot0(addr_hit)) - -endmodule - -module chimera_reg_top_intf #( - parameter int AW = 7, - localparam int DW = 32 -) ( - input logic clk_i, - input logic rst_ni, - REG_BUS.in regbus_slave, - // To HW - output chimera_reg_pkg::chimera_reg2hw_t reg2hw, // Write - // Config - input devmode_i // If 1, explicit error return for unmapped register access -); - localparam int unsigned STRB_WIDTH = DW / 8; - - `include "register_interface/typedef.svh" - `include "register_interface/assign.svh" - - // Define structs for reg_bus - typedef logic [AW-1:0] addr_t; - typedef logic [DW-1:0] data_t; - typedef logic [STRB_WIDTH-1:0] strb_t; - `REG_BUS_TYPEDEF_ALL(reg_bus, addr_t, data_t, strb_t) - - reg_bus_req_t s_reg_req; - reg_bus_rsp_t s_reg_rsp; - - // Assign SV interface to structs - `REG_BUS_ASSIGN_TO_REQ(s_reg_req, regbus_slave) - `REG_BUS_ASSIGN_FROM_RSP(regbus_slave, s_reg_rsp) - - - - chimera_reg_top #( - .reg_req_t(reg_bus_req_t), - .reg_rsp_t(reg_bus_rsp_t), - .AW (AW) - ) i_regs ( - .clk_i, - .rst_ni, - .reg_req_i(s_reg_req), - .reg_rsp_o(s_reg_rsp), - .reg2hw, // Write - .devmode_i - ); - -endmodule - - diff --git a/hw/regs/chimera_regs.hjson b/hw/regs/chimera_regs.hjson deleted file mode 100644 index 2bdc93c..0000000 --- a/hw/regs/chimera_regs.hjson +++ /dev/null @@ -1,333 +0,0 @@ -// Copyright 2024 ETH Zurich and University of Bologna. -// Solderpad Hardware License, Version 0.51, see LICENSE for details. -// SPDX-License-Identifier: SHL-0.51 -// Moritz Scherer - -{ - name: "chimera", - clock_primary: "clk_i", - bus_interfaces: [ - { protocol: "reg_iface", direction: "device" } - ], - regwidth: "32", - registers :[ - { - name: "SNITCH_BOOT_ADDR", - desc: "Set boot address for all snitch cores", - swaccess: "rw", - hwaccess: "hro", - resval: "0xBADCAB1E", - hwqe: "0", - fields: [ - { bits: "31:0" } - ], - } - { - name: "SNITCH_CONFIGURABLE_BOOT_ADDR", - desc: "Define the address of the Boot executed by each Snitch core", - swaccess: "rw", - hwaccess: "hro", - resval: "0x30000000", - hwqe: "0", - fields: [ - { bits: "31:0" } - ], - } - { - name: "SNITCH_INTR_HANDLER_ADDR", - desc: "Set interrupt handler address for all snitch cores", - swaccess: "rw", - hwaccess: "hro", - resval: "0xBADCAB1E", - hwqe: "0", - fields: [ - { bits: "31:0" } - ], - } - { - name: "SNITCH_CLUSTER_0_RETURN", - desc: "Register to store return value of Snitch cluster 0", - swaccess: "rw", - hwaccess: "hro", - resval: "0", - hwqe: "0", - fields: [ - { bits: "31:0" } - ], - } - - { - name: "SNITCH_CLUSTER_1_RETURN", - desc: "Register to store return value of Snitch cluster 1", - swaccess: "rw", - hwaccess: "hro", - resval: "0", - hwqe: "0", - fields: [ - { bits: "31:0" } - ], - } - - { - name: "SNITCH_CLUSTER_2_RETURN", - desc: "Register to store return value of Snitch cluster 2", - swaccess: "rw", - hwaccess: "hro", - resval: "0", - hwqe: "0", - fields: [ - { bits: "31:0" } - ], - } - - { - name: "SNITCH_CLUSTER_3_RETURN", - desc: "Register to store return value of Snitch cluster 3", - swaccess: "rw", - hwaccess: "hro", - resval: "0", - hwqe: "0", - fields: [ - { bits: "31:0" } - ], - } - - { - name: "SNITCH_CLUSTER_4_RETURN", - desc: "Register to store return value of Snitch cluster 4", - swaccess: "rw", - hwaccess: "hro", - resval: "0", - hwqe: "0", - fields: [ - { bits: "31:0" } - ], - } - - { - name: "RESET_CLUSTER_0", - desc: "Soft reset for cluster 0. Active High", - swaccess: "rw", - hwaccess: "hro", - resval: "1", - hwqe: "0", - fields: [ - { bits: "0:0" } - ], - } - - { - name: "RESET_CLUSTER_1", - desc: "Soft reset for cluster 1. Active High", - swaccess: "rw", - hwaccess: "hro", - resval: "1", - hwqe: "0", - fields: [ - { bits: "0:0" } - ], - } - - { - name: "RESET_CLUSTER_2", - desc: "Soft reset for cluster 2. Active High", - swaccess: "rw", - hwaccess: "hro", - resval: "1", - hwqe: "0", - fields: [ - { bits: "0:0" } - ], - } - - { - name: "RESET_CLUSTER_3", - desc: "Soft reset for cluster 3. Active High", - swaccess: "rw", - hwaccess: "hro", - resval: "1", - hwqe: "0", - fields: [ - { bits: "0:0" } - ], - } - - { - name: "RESET_CLUSTER_4", - desc: "Soft reset for cluster 4. Active High", - swaccess: "rw", - hwaccess: "hro", - resval: "1", - hwqe: "0", - fields: [ - { bits: "0:0" } - ], - } - - { - name: "CLUSTER_0_CLK_GATE_EN", - desc: "Enable clock gate for cluster 0 (disable clock)", - swaccess: "rw", - hwaccess: "hro", - resval: "1", - hwqe: "0", - fields: [ - { bits: "0:0" } - ], - } - - { - name: "CLUSTER_1_CLK_GATE_EN", - desc: "Enable clock gate for cluster 1 (disable clock)", - swaccess: "rw", - hwaccess: "hro", - resval: "1", - hwqe: "0", - fields: [ - { bits: "0:0" } - ], - } - - { - name: "CLUSTER_2_CLK_GATE_EN", - desc: "Enable clock gate for cluster 2 (disable clock)", - swaccess: "rw", - hwaccess: "hro", - resval: "1", - hwqe: "0", - fields: [ - { bits: "0:0" } - ], - } - - { - name: "CLUSTER_3_CLK_GATE_EN", - desc: "Enable clock gate for cluster 3 (disable clock)", - swaccess: "rw", - hwaccess: "hro", - resval: "1", - hwqe: "0", - fields: [ - { bits: "0:0" } - ], - } - - { - name: "CLUSTER_4_CLK_GATE_EN", - desc: "Enable clock gate for cluster 4 (disable clock)", - swaccess: "rw", - hwaccess: "hro", - resval: "1", - hwqe: "0", - fields: [ - { bits: "0:0" } - ], - } - - { - name: "WIDE_MEM_CLUSTER_0_BYPASS", - desc: "Bypass cluster to mem wide connection for cluster 0", - swaccess: "rw", - hwaccess: "hro", - resval: "0", - fields: [ - { bits: "0:0" } - ], - } - - - { - name: "WIDE_MEM_CLUSTER_1_BYPASS", - desc: "Bypass cluster to mem wide connection for cluster 1", - swaccess: "rw", - hwaccess: "hro", - resval: "0", - fields: [ - { bits: "0:0" } - ], - } - { - name: "WIDE_MEM_CLUSTER_2_BYPASS", - desc: "Bypass cluster to mem wide connection for cluster 2", - swaccess: "rw", - hwaccess: "hro", - resval: "0", - fields: [ - { bits: "0:0" } - ], - } - { - name: "WIDE_MEM_CLUSTER_3_BYPASS", - desc: "Bypass cluster to mem wide connection for cluster 3", - swaccess: "rw", - hwaccess: "hro", - resval: "0", - fields: [ - { bits: "0:0" } - ], - } - { - name: "WIDE_MEM_CLUSTER_4_BYPASS", - desc: "Bypass cluster to mem wide connection for cluster 4", - swaccess: "rw", - hwaccess: "hro", - resval: "0", - fields: [ - { bits: "0:0" } - ], - } - - { - name: "CLUSTER_0_BUSY", - desc: "Register to identify when cluster 0 is busy", - swaccess: "rw", - hwaccess: "hro", - resval: "1", - fields: [ - { bits: "0:0" } - ], - } - - { - name: "CLUSTER_1_BUSY", - desc: "Register to identify when cluster 1 is busy", - swaccess: "rw", - hwaccess: "hro", - resval: "1", - fields: [ - { bits: "0:0" } - ], - } - { - name: "CLUSTER_2_BUSY", - desc: "Register to identify when cluster 2 is busy", - swaccess: "rw", - hwaccess: "hro", - resval: "1", - fields: [ - { bits: "0:0" } - ], - } - { - name: "CLUSTER_3_BUSY", - desc: "Register to identify when cluster 3 is busy", - swaccess: "rw", - hwaccess: "hro", - resval: "1", - fields: [ - { bits: "0:0" } - ], - } - { - name: "CLUSTER_4_BUSY", - desc: "Register to identify when cluster 4 is busy", - swaccess: "rw", - hwaccess: "hro", - resval: "1", - fields: [ - { bits: "0:0" } - ], - } - - ] -} From d9905178d9041cd0f5e7f5c5da7f12f8b029a62d Mon Sep 17 00:00:00 2001 From: Lorenzo Leone Date: Mon, 7 Jul 2025 21:11:06 +0200 Subject: [PATCH 3/3] sw: Adapt software to new systemRDL c-header `chimera_addrmap.h` --- Makefile | 3 +- chimera.mk | 8 ++ hw/rdl/cheshire_host.rdl | 21 ++++ hw/rdl/chimera.rdl | 16 +++ hw/rdl/chimera_regs.rdl | 2 +- hw/rdl/snitch_cluster.rdl | 21 ++++ sw/include/chimera_addrmap.h | 176 +++++++++++++++++++++++++++++++ sw/include/offload.h | 9 +- sw/include/regs/soc_ctrl.h | 127 ---------------------- sw/lib/offload.c | 109 +++++++------------ sw/sw.mk | 10 ++ sw/tests/testCfgBootAddr.c | 22 ++-- sw/tests/testCluster.c | 8 +- sw/tests/testClusterGating.c | 14 +-- sw/tests/testClusterOffload.c | 12 +-- sw/tests/testHyperbusAddr.c | 9 +- sw/tests/testMemBypass.c | 32 ++---- sw/tests/testPeripheralsGating.c | 8 +- 18 files changed, 348 insertions(+), 259 deletions(-) create mode 100644 hw/rdl/cheshire_host.rdl create mode 100644 hw/rdl/chimera.rdl create mode 100644 hw/rdl/snitch_cluster.rdl create mode 100644 sw/include/chimera_addrmap.h delete mode 100644 sw/include/regs/soc_ctrl.h diff --git a/Makefile b/Makefile index ea72c90..fa653b2 100644 --- a/Makefile +++ b/Makefile @@ -9,7 +9,7 @@ CHIM_ROOT ?= $(shell pwd) # Tooling BENDER ?= bender -d $(CHIM_ROOT) VERIBLE_VERILOG_FORMAT ?= $(CHIM_UTILS_DIR)/verible-verilog/verible-verilog-format -PEAKRDL ?= peakrdl +PEAKRDL ?= peakrdl # Set dependency paths only if dependencies have already been cloned # This avoids running `bender checkout` at every make command @@ -63,4 +63,5 @@ help: @echo -e "" @echo -e "Software:" @echo -e "${Green}chim-sw ${Black}Compile all software tests" + @echo -e "${Green}chimera-addrmap ${Black}Regenerate c-header for SoC address map" @echo -e "" diff --git a/chimera.mk b/chimera.mk index cce5758..17d5733 100644 --- a/chimera.mk +++ b/chimera.mk @@ -56,6 +56,14 @@ $(CHIM_ROOT)/hw/bootrom/snitch/snitch_bootrom.bin: $(CHIM_ROOT)/hw/bootrom/snitc $(CHIM_ROOT)/hw/bootrom/snitch/snitch_bootrom.sv: $(CHIM_ROOT)/hw/bootrom/snitch/snitch_bootrom.bin $(CHS_ROOT)/util/gen_bootrom.py $(CHS_ROOT)/util/gen_bootrom.py --sv-module snitch_bootrom $< > $@ +############# +# SystemRDL # +############# +CHIM_RDL_ALL += $(CHIM_ROOT)/hw/rdl/chimera.rdl +CHIM_RDL_ALL += $(CHIM_ROOT)/hw/rdl/snitch_cluster.rdl +CHIM_RDL_ALL += $(CHIM_ROOT)/hw/rdl/cheshire_host.rdl +CHIM_RDL_ALL += $(CHIM_ROOT)/hw/rdl/chimera_regs.rdl + .PHONY: regenerate_soc_regs regenerate_soc_regs: $(CHIM_ROOT)/hw/rdl/chimera_reg_top.sv $(CHIM_ROOT)/hw/rdl/chimera_reg_pkg.sv $(CHIM_ROOT)/hw/rdl/chimera_reg_top.sv $(CHIM_ROOT)/hw/rdl/chimera_reg_pkg.sv: $(CHIM_ROOT)/hw/rdl/chimera_regs.rdl diff --git a/hw/rdl/cheshire_host.rdl b/hw/rdl/cheshire_host.rdl new file mode 100644 index 0000000..e3893c3 --- /dev/null +++ b/hw/rdl/cheshire_host.rdl @@ -0,0 +1,21 @@ +// Copyright 2025 ETH Zurich and University of Bologna. +// Solderpad Hardware License, Version 0.51, see LICENSE for details. +// SPDX-License-Identifier: SHL-0.51 + +`ifndef __CHESHIRE_HOST_RDL__ +`define __CHESHIRE_HOST_RDL__ + +`include "chimera_regs.rdl" + +addrmap cheshire_host #( + longint unsigned NumClusters = 1 // Number of Clusters +) { + + chimera_regs #(.NumClusters (NumClusters)) chimera_regs @0x1000; + + // TODO: Map the Hyperbus + // TODO: Map external reg for chip levelk (FLL, etc...) + +}; + +`endif // __CHESHIRE_HOST_RDL__ diff --git a/hw/rdl/chimera.rdl b/hw/rdl/chimera.rdl new file mode 100644 index 0000000..da535cc --- /dev/null +++ b/hw/rdl/chimera.rdl @@ -0,0 +1,16 @@ +// Copyright 2025 ETH Zurich and University of Bologna. +// Solderpad Hardware License, Version 0.51, see LICENSE for details. +// SPDX-License-Identifier: SHL-0.51 + +`include "cheshire_host.rdl" +`include "snitch_cluster.rdl" + +addrmap chimera_addrmap #( + longint unsigned NumClusters = 1 // Number of Clusters +){ + + cheshire_host #(.NumClusters (NumClusters)) host @0x30000000; + snitch_cluster snitch_cluster[NumClusters] @0x40000000 += 0x200000; + external mem { mementries = 0x40000; memwidth = 8; } l2_mem_island @0x48000000; + +}; diff --git a/hw/rdl/chimera_regs.rdl b/hw/rdl/chimera_regs.rdl index c22ffa6..440cb0d 100644 --- a/hw/rdl/chimera_regs.rdl +++ b/hw/rdl/chimera_regs.rdl @@ -9,7 +9,7 @@ `define CHIMERA_RDL addrmap chimera_regs #( - longint unsigned NumClusters = 1 // Number of cores + longint unsigned NumClusters = 1 // Number of clusters ) { name = "chimera_regs"; desc = "Chimera SoC control registers"; diff --git a/hw/rdl/snitch_cluster.rdl b/hw/rdl/snitch_cluster.rdl new file mode 100644 index 0000000..babcd00 --- /dev/null +++ b/hw/rdl/snitch_cluster.rdl @@ -0,0 +1,21 @@ +// Copyright 2025 ETH Zurich and University of Bologna. +// Solderpad Hardware License, Version 0.51, see LICENSE for details. +// SPDX-License-Identifier: SHL-0.51 + +`ifndef __SNITCH_CLUSTER_RDL__ +`define __SNITCH_CLUSTER_RDL__ + +// `include "snitch_cluster_wrapper.rdl" + +addrmap snitch_cluster { + + external mem { + mementries = 1; + memwidth = 64; + } dummy; + + // snitch_cluster_wrapper #(.BASE_ADDR(0)) snitch_cluster_wrapper; + +}; + +`endif // __SNITCH_CLUSTER_RDL__ diff --git a/sw/include/chimera_addrmap.h b/sw/include/chimera_addrmap.h new file mode 100644 index 0000000..c691fe8 --- /dev/null +++ b/sw/include/chimera_addrmap.h @@ -0,0 +1,176 @@ +// Copyright 2025 ETH Zurich and University of Bologna. +// Licensed under the Apache License, Version 2 0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 + +// Generated by PeakRDL-cheader - A free and open-source header generator +// https://github.com/SystemRDL/PeakRDL-cheader + +#ifndef CHIMERA_ADDRMAP_H +#define CHIMERA_ADDRMAP_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include + +// Reg - chimera_regs_NumClusters_5::snitch_boot_addr +#define CHIMERA_REGS_NUMCLUSTERS_5__SNITCH_BOOT_ADDR__SNITCH_BOOT_ADDR_bm 0xffffffff +#define CHIMERA_REGS_NUMCLUSTERS_5__SNITCH_BOOT_ADDR__SNITCH_BOOT_ADDR_bp 0 +#define CHIMERA_REGS_NUMCLUSTERS_5__SNITCH_BOOT_ADDR__SNITCH_BOOT_ADDR_bw 32 +#define CHIMERA_REGS_NUMCLUSTERS_5__SNITCH_BOOT_ADDR__SNITCH_BOOT_ADDR_reset 0xbadcab1e +typedef union { + struct __attribute__((__packed__)) { + uint32_t SNITCH_BOOT_ADDR : 32; + } f; + uint32_t w; +} chimera_regs_NumClusters_5__snitch_boot_addr_t; + +// Reg - chimera_regs_NumClusters_5::snitch_configurable_boot_addr +#define CHIMERA_REGS_NUMCLUSTERS_5__SNITCH_CONFIGURABLE_BOOT_ADDR__SNITCH_CONFIGURABLE_BOOT_ADDR_bm \ + 0xffffffff +#define CHIMERA_REGS_NUMCLUSTERS_5__SNITCH_CONFIGURABLE_BOOT_ADDR__SNITCH_CONFIGURABLE_BOOT_ADDR_bp \ + 0 +#define CHIMERA_REGS_NUMCLUSTERS_5__SNITCH_CONFIGURABLE_BOOT_ADDR__SNITCH_CONFIGURABLE_BOOT_ADDR_bw \ + 32 +#define CHIMERA_REGS_NUMCLUSTERS_5__SNITCH_CONFIGURABLE_BOOT_ADDR__SNITCH_CONFIGURABLE_BOOT_ADDR_reset \ + 0x30000000 +typedef union { + struct __attribute__((__packed__)) { + uint32_t SNITCH_CONFIGURABLE_BOOT_ADDR : 32; + } f; + uint32_t w; +} chimera_regs_NumClusters_5__snitch_configurable_boot_addr_t; + +// Reg - chimera_regs_NumClusters_5::snitch_intr_handler_addr +#define CHIMERA_REGS_NUMCLUSTERS_5__SNITCH_INTR_HANDLER_ADDR__SNITCH_INTR_HANDLER_ADDR_bm 0xffffffff +#define CHIMERA_REGS_NUMCLUSTERS_5__SNITCH_INTR_HANDLER_ADDR__SNITCH_INTR_HANDLER_ADDR_bp 0 +#define CHIMERA_REGS_NUMCLUSTERS_5__SNITCH_INTR_HANDLER_ADDR__SNITCH_INTR_HANDLER_ADDR_bw 32 +#define CHIMERA_REGS_NUMCLUSTERS_5__SNITCH_INTR_HANDLER_ADDR__SNITCH_INTR_HANDLER_ADDR_reset \ + 0xbadcab1e +typedef union { + struct __attribute__((__packed__)) { + uint32_t SNITCH_INTR_HANDLER_ADDR : 32; + } f; + uint32_t w; +} chimera_regs_NumClusters_5__snitch_intr_handler_addr_t; + +// Reg - chimera_regs_NumClusters_5::snitch_cluster_return +#define CHIMERA_REGS_NUMCLUSTERS_5__SNITCH_CLUSTER_RETURN__SNITCH_CLUSTER_RETURN_bm 0xffffffff +#define CHIMERA_REGS_NUMCLUSTERS_5__SNITCH_CLUSTER_RETURN__SNITCH_CLUSTER_RETURN_bp 0 +#define CHIMERA_REGS_NUMCLUSTERS_5__SNITCH_CLUSTER_RETURN__SNITCH_CLUSTER_RETURN_bw 32 +#define CHIMERA_REGS_NUMCLUSTERS_5__SNITCH_CLUSTER_RETURN__SNITCH_CLUSTER_RETURN_reset 0x0 +typedef union { + struct __attribute__((__packed__)) { + uint32_t SNITCH_CLUSTER_RETURN : 32; + } f; + uint32_t w; +} chimera_regs_NumClusters_5__snitch_cluster_return_t; + +// Reg - chimera_regs_NumClusters_5::reset_cluster +#define CHIMERA_REGS_NUMCLUSTERS_5__RESET_CLUSTER__RESET_CLUSTER_bm 0x1 +#define CHIMERA_REGS_NUMCLUSTERS_5__RESET_CLUSTER__RESET_CLUSTER_bp 0 +#define CHIMERA_REGS_NUMCLUSTERS_5__RESET_CLUSTER__RESET_CLUSTER_bw 1 +#define CHIMERA_REGS_NUMCLUSTERS_5__RESET_CLUSTER__RESET_CLUSTER_reset 0x1 +typedef union { + struct __attribute__((__packed__)) { + uint32_t RESET_CLUSTER : 1; + uint32_t : 31; + } f; + uint32_t w; +} chimera_regs_NumClusters_5__reset_cluster_t; + +// Reg - chimera_regs_NumClusters_5::cluster_clk_gate_en +#define CHIMERA_REGS_NUMCLUSTERS_5__CLUSTER_CLK_GATE_EN__CLUSTER_CLK_GATE_EN_bm 0x1 +#define CHIMERA_REGS_NUMCLUSTERS_5__CLUSTER_CLK_GATE_EN__CLUSTER_CLK_GATE_EN_bp 0 +#define CHIMERA_REGS_NUMCLUSTERS_5__CLUSTER_CLK_GATE_EN__CLUSTER_CLK_GATE_EN_bw 1 +#define CHIMERA_REGS_NUMCLUSTERS_5__CLUSTER_CLK_GATE_EN__CLUSTER_CLK_GATE_EN_reset 0x1 +typedef union { + struct __attribute__((__packed__)) { + uint32_t CLUSTER_CLK_GATE_EN : 1; + uint32_t : 31; + } f; + uint32_t w; +} chimera_regs_NumClusters_5__cluster_clk_gate_en_t; + +// Reg - chimera_regs_NumClusters_5::wide_mem_cluster_bypass +#define CHIMERA_REGS_NUMCLUSTERS_5__WIDE_MEM_CLUSTER_BYPASS__WIDE_MEM_CLUSTER_BYPASS_bm 0x1 +#define CHIMERA_REGS_NUMCLUSTERS_5__WIDE_MEM_CLUSTER_BYPASS__WIDE_MEM_CLUSTER_BYPASS_bp 0 +#define CHIMERA_REGS_NUMCLUSTERS_5__WIDE_MEM_CLUSTER_BYPASS__WIDE_MEM_CLUSTER_BYPASS_bw 1 +#define CHIMERA_REGS_NUMCLUSTERS_5__WIDE_MEM_CLUSTER_BYPASS__WIDE_MEM_CLUSTER_BYPASS_reset 0x0 +typedef union { + struct __attribute__((__packed__)) { + uint32_t WIDE_MEM_CLUSTER_BYPASS : 1; + uint32_t : 31; + } f; + uint32_t w; +} chimera_regs_NumClusters_5__wide_mem_cluster_bypass_t; + +// Reg - chimera_regs_NumClusters_5::cluster_busy +#define CHIMERA_REGS_NUMCLUSTERS_5__CLUSTER_BUSY__CLUSTER_BUSY_bm 0x1 +#define CHIMERA_REGS_NUMCLUSTERS_5__CLUSTER_BUSY__CLUSTER_BUSY_bp 0 +#define CHIMERA_REGS_NUMCLUSTERS_5__CLUSTER_BUSY__CLUSTER_BUSY_bw 1 +#define CHIMERA_REGS_NUMCLUSTERS_5__CLUSTER_BUSY__CLUSTER_BUSY_reset 0x0 +typedef union { + struct __attribute__((__packed__)) { + uint32_t CLUSTER_BUSY : 1; + uint32_t : 31; + } f; + uint32_t w; +} chimera_regs_NumClusters_5__cluster_busy_t; + +// Addrmap - chimera_regs_NumClusters_5 +typedef struct __attribute__((__packed__)) { + chimera_regs_NumClusters_5__snitch_boot_addr_t snitch_boot_addr; + chimera_regs_NumClusters_5__snitch_configurable_boot_addr_t snitch_configurable_boot_addr; + chimera_regs_NumClusters_5__snitch_intr_handler_addr_t snitch_intr_handler_addr; + chimera_regs_NumClusters_5__snitch_cluster_return_t snitch_cluster_return[5]; + chimera_regs_NumClusters_5__reset_cluster_t reset_cluster[5]; + chimera_regs_NumClusters_5__cluster_clk_gate_en_t cluster_clk_gate_en[5]; + chimera_regs_NumClusters_5__wide_mem_cluster_bypass_t wide_mem_cluster_bypass[5]; + chimera_regs_NumClusters_5__cluster_busy_t cluster_busy[5]; +} chimera_regs_NumClusters_5_t; + +// Addrmap - cheshire_host_NumClusters_5 +typedef struct __attribute__((__packed__)) { + uint8_t RESERVED_0_fff[0x1000]; + chimera_regs_NumClusters_5_t chimera_regs; +} cheshire_host_NumClusters_5_t; + +// Mem - snitch_cluster::dummy +typedef struct __attribute__((__packed__)) { + uint64_t mem[1]; +} snitch_cluster__dummy_t; + +// Addrmap - snitch_cluster +typedef struct __attribute__((__packed__)) { + snitch_cluster__dummy_t dummy; + uint8_t RESERVED_8_1fffff[0x1ffff8]; +} snitch_cluster__stride200000_t; + +// Mem - chimera_addrmap_NumClusters_5::l2_mem_island +typedef struct __attribute__((__packed__)) { + uint8_t mem[262144]; +} chimera_addrmap_NumClusters_5__l2_mem_island_t; + +// Addrmap - chimera_addrmap_NumClusters_5 +typedef struct __attribute__((__packed__)) { + uint8_t RESERVED_0_2fffffff[0x30000000]; + cheshire_host_NumClusters_5_t host; + uint8_t RESERVED_30001070_3fffffff[0xfffef90]; + snitch_cluster__stride200000_t snitch_cluster[5]; + uint8_t RESERVED_40a00000_47ffffff[0x7600000]; + chimera_addrmap_NumClusters_5__l2_mem_island_t l2_mem_island; +} chimera_addrmap_NumClusters_5_t; + +// Instances +#define chimera_addrmap (*(volatile chimera_addrmap_NumClusters_5_t *)0x0UL) + +static_assert(sizeof(chimera_addrmap_NumClusters_5_t) == 0x48040000, "Packing error"); + +#ifdef __cplusplus +} +#endif + +#endif /* CHIMERA_ADDRMAP_H */ diff --git a/sw/include/offload.h b/sw/include/offload.h index 7d03439..a569454 100644 --- a/sw/include/offload.h +++ b/sw/include/offload.h @@ -13,10 +13,11 @@ #include void setupInterruptHandler(void *handler); -void setClusterClockGating(uint8_t *regPtr, uint8_t clusterId, bool enable); -void setAllClusterClockGating(uint8_t *regPtr, bool enable); -void setClusterReset(uint8_t *regPtr, uint8_t clusterId, bool enable); -void setAllClusterReset(uint8_t *regPtr, bool enable); +void setClusterClockGating(uint8_t clusterId, bool enable); +void setAllClusterClockGating(volatile uint8_t numRegs, bool enable); +void setClusterReset(uint8_t clusterId, bool enable); +void setAllClusterReset(volatile uint8_t numRegs, bool enable); +void setAllRegs(volatile uint32_t *regPtr, uint8_t numRegs, bool enable); void offloadToCluster(void *function, uint8_t hartId); void waitClusterBusy(uint8_t clusterId); uint32_t waitForCluster(uint8_t clusterId); diff --git a/sw/include/regs/soc_ctrl.h b/sw/include/regs/soc_ctrl.h deleted file mode 100644 index a63244b..0000000 --- a/sw/include/regs/soc_ctrl.h +++ /dev/null @@ -1,127 +0,0 @@ -// Generated register defines for chimera - -// Copyright information found in source file: -// Copyright 2024 ETH Zurich and University of Bologna. - -// Licensing information found in source file: -// -// SPDX-License-Identifier: SHL-0.51 - -#ifndef _CHIMERA_REG_DEFS_ -#define _CHIMERA_REG_DEFS_ - -#ifdef __cplusplus -extern "C" { -#endif -// Register width -#define CHIMERA_PARAM_REG_WIDTH 32 - -// Set boot address for all snitch cores -#define CHIMERA_SNITCH_BOOT_ADDR_REG_OFFSET 0x0 - -// Define the address of the Boot executed by each Snitch core -#define CHIMERA_SNITCH_CONFIGURABLE_BOOT_ADDR_REG_OFFSET 0x4 - -// Set interrupt handler address for all snitch cores -#define CHIMERA_SNITCH_INTR_HANDLER_ADDR_REG_OFFSET 0x8 - -// Register to store return value of Snitch cluster 0 -#define CHIMERA_SNITCH_CLUSTER_0_RETURN_REG_OFFSET 0xc - -// Register to store return value of Snitch cluster 1 -#define CHIMERA_SNITCH_CLUSTER_1_RETURN_REG_OFFSET 0x10 - -// Register to store return value of Snitch cluster 2 -#define CHIMERA_SNITCH_CLUSTER_2_RETURN_REG_OFFSET 0x14 - -// Register to store return value of Snitch cluster 3 -#define CHIMERA_SNITCH_CLUSTER_3_RETURN_REG_OFFSET 0x18 - -// Register to store return value of Snitch cluster 4 -#define CHIMERA_SNITCH_CLUSTER_4_RETURN_REG_OFFSET 0x1c - -// Soft reset for cluster 0. Active High -#define CHIMERA_RESET_CLUSTER_0_REG_OFFSET 0x20 -#define CHIMERA_RESET_CLUSTER_0_RESET_CLUSTER_0_BIT 0 - -// Soft reset for cluster 1. Active High -#define CHIMERA_RESET_CLUSTER_1_REG_OFFSET 0x24 -#define CHIMERA_RESET_CLUSTER_1_RESET_CLUSTER_1_BIT 0 - -// Soft reset for cluster 2. Active High -#define CHIMERA_RESET_CLUSTER_2_REG_OFFSET 0x28 -#define CHIMERA_RESET_CLUSTER_2_RESET_CLUSTER_2_BIT 0 - -// Soft reset for cluster 3. Active High -#define CHIMERA_RESET_CLUSTER_3_REG_OFFSET 0x2c -#define CHIMERA_RESET_CLUSTER_3_RESET_CLUSTER_3_BIT 0 - -// Soft reset for cluster 4. Active High -#define CHIMERA_RESET_CLUSTER_4_REG_OFFSET 0x30 -#define CHIMERA_RESET_CLUSTER_4_RESET_CLUSTER_4_BIT 0 - -// Enable clock gate for cluster 0 (disable clock) -#define CHIMERA_CLUSTER_0_CLK_GATE_EN_REG_OFFSET 0x34 -#define CHIMERA_CLUSTER_0_CLK_GATE_EN_CLUSTER_0_CLK_GATE_EN_BIT 0 - -// Enable clock gate for cluster 1 (disable clock) -#define CHIMERA_CLUSTER_1_CLK_GATE_EN_REG_OFFSET 0x38 -#define CHIMERA_CLUSTER_1_CLK_GATE_EN_CLUSTER_1_CLK_GATE_EN_BIT 0 - -// Enable clock gate for cluster 2 (disable clock) -#define CHIMERA_CLUSTER_2_CLK_GATE_EN_REG_OFFSET 0x3c -#define CHIMERA_CLUSTER_2_CLK_GATE_EN_CLUSTER_2_CLK_GATE_EN_BIT 0 - -// Enable clock gate for cluster 3 (disable clock) -#define CHIMERA_CLUSTER_3_CLK_GATE_EN_REG_OFFSET 0x40 -#define CHIMERA_CLUSTER_3_CLK_GATE_EN_CLUSTER_3_CLK_GATE_EN_BIT 0 - -// Enable clock gate for cluster 4 (disable clock) -#define CHIMERA_CLUSTER_4_CLK_GATE_EN_REG_OFFSET 0x44 -#define CHIMERA_CLUSTER_4_CLK_GATE_EN_CLUSTER_4_CLK_GATE_EN_BIT 0 - -// Bypass cluster to mem wide connection for cluster 0 -#define CHIMERA_WIDE_MEM_CLUSTER_0_BYPASS_REG_OFFSET 0x48 -#define CHIMERA_WIDE_MEM_CLUSTER_0_BYPASS_WIDE_MEM_CLUSTER_0_BYPASS_BIT 0 - -// Bypass cluster to mem wide connection for cluster 1 -#define CHIMERA_WIDE_MEM_CLUSTER_1_BYPASS_REG_OFFSET 0x4c -#define CHIMERA_WIDE_MEM_CLUSTER_1_BYPASS_WIDE_MEM_CLUSTER_1_BYPASS_BIT 0 - -// Bypass cluster to mem wide connection for cluster 2 -#define CHIMERA_WIDE_MEM_CLUSTER_2_BYPASS_REG_OFFSET 0x50 -#define CHIMERA_WIDE_MEM_CLUSTER_2_BYPASS_WIDE_MEM_CLUSTER_2_BYPASS_BIT 0 - -// Bypass cluster to mem wide connection for cluster 3 -#define CHIMERA_WIDE_MEM_CLUSTER_3_BYPASS_REG_OFFSET 0x54 -#define CHIMERA_WIDE_MEM_CLUSTER_3_BYPASS_WIDE_MEM_CLUSTER_3_BYPASS_BIT 0 - -// Bypass cluster to mem wide connection for cluster 4 -#define CHIMERA_WIDE_MEM_CLUSTER_4_BYPASS_REG_OFFSET 0x58 -#define CHIMERA_WIDE_MEM_CLUSTER_4_BYPASS_WIDE_MEM_CLUSTER_4_BYPASS_BIT 0 - -// Register to identify when cluster 0 is busy -#define CHIMERA_CLUSTER_0_BUSY_REG_OFFSET 0x5c -#define CHIMERA_CLUSTER_0_BUSY_CLUSTER_0_BUSY_BIT 0 - -// Register to identify when cluster 1 is busy -#define CHIMERA_CLUSTER_1_BUSY_REG_OFFSET 0x60 -#define CHIMERA_CLUSTER_1_BUSY_CLUSTER_1_BUSY_BIT 0 - -// Register to identify when cluster 2 is busy -#define CHIMERA_CLUSTER_2_BUSY_REG_OFFSET 0x64 -#define CHIMERA_CLUSTER_2_BUSY_CLUSTER_2_BUSY_BIT 0 - -// Register to identify when cluster 3 is busy -#define CHIMERA_CLUSTER_3_BUSY_REG_OFFSET 0x68 -#define CHIMERA_CLUSTER_3_BUSY_CLUSTER_3_BUSY_BIT 0 - -// Register to identify when cluster 4 is busy -#define CHIMERA_CLUSTER_4_BUSY_REG_OFFSET 0x6c -#define CHIMERA_CLUSTER_4_BUSY_CLUSTER_4_BUSY_BIT 0 - -#ifdef __cplusplus -} // extern "C" -#endif -#endif // _CHIMERA_REG_DEFS_ - // End generated register defines for chimera \ No newline at end of file diff --git a/sw/lib/offload.c b/sw/lib/offload.c index d31d0ff..79b399b 100644 --- a/sw/lib/offload.c +++ b/sw/lib/offload.c @@ -6,33 +6,22 @@ // Viviane Potocnik // Lorenzo Leone -#include "regs/soc_ctrl.h" #include "soc_addr_map.h" +#include #include #include #include void setupInterruptHandler(void *handler) { volatile void **snitchTrapHandlerAddr = - (volatile void **)(SOC_CTRL_BASE + CHIMERA_SNITCH_INTR_HANDLER_ADDR_REG_OFFSET); + (volatile void **)(&chimera_addrmap.host.chimera_regs.snitch_intr_handler_addr); *snitchTrapHandlerAddr = handler; } void waitClusterBusy(uint8_t clusterId) { volatile int32_t *busy_ptr; - - if (clusterId == 0) { - busy_ptr = (volatile int32_t *)(SOC_CTRL_BASE + CHIMERA_CLUSTER_0_BUSY_REG_OFFSET); - } else if (clusterId == 1) { - busy_ptr = (volatile int32_t *)(SOC_CTRL_BASE + CHIMERA_CLUSTER_1_BUSY_REG_OFFSET); - } else if (clusterId == 2) { - busy_ptr = (volatile int32_t *)(SOC_CTRL_BASE + CHIMERA_CLUSTER_2_BUSY_REG_OFFSET); - } else if (clusterId == 3) { - busy_ptr = (volatile int32_t *)(SOC_CTRL_BASE + CHIMERA_CLUSTER_3_BUSY_REG_OFFSET); - } else if (clusterId == 4) { - busy_ptr = (volatile int32_t *)(SOC_CTRL_BASE + CHIMERA_CLUSTER_4_BUSY_REG_OFFSET); - } + busy_ptr = (volatile int32_t *)(&chimera_addrmap.host.chimera_regs.cluster_busy[clusterId]); while (*busy_ptr == 1) { } @@ -46,70 +35,60 @@ void waitClusterBusy(uint8_t clusterId) { } /* Set Clock Gating on specified cluster */ -void setClusterClockGating(volatile uint8_t *regPtr, uint8_t clusterId, bool enable) { +void setClusterClockGating(uint8_t clusterId, bool enable) { + volatile uint32_t *regPtr = + (volatile uint32_t *)chimera_addrmap.host.chimera_regs.cluster_clk_gate_en; - if (regPtr == NULL) return; - - if (clusterId == 0) { - *(regPtr + CHIMERA_CLUSTER_0_CLK_GATE_EN_REG_OFFSET) = enable; - } else if (clusterId == 1) { - *(regPtr + CHIMERA_CLUSTER_1_CLK_GATE_EN_REG_OFFSET) = enable; - } else if (clusterId == 2) { - *(regPtr + CHIMERA_CLUSTER_2_CLK_GATE_EN_REG_OFFSET) = enable; - } else if (clusterId == 3) { - *(regPtr + CHIMERA_CLUSTER_3_CLK_GATE_EN_REG_OFFSET) = enable; - } else if (clusterId == 4) { - *(regPtr + CHIMERA_CLUSTER_4_CLK_GATE_EN_REG_OFFSET) = enable; - } + setReg(regPtr, clusterId, enable); } /* Set Clock Gating on all clusters */ -void setAllClusterClockGating(volatile uint8_t *regPtr, bool enable) { +void setAllClusterClockGating(volatile uint8_t numRegs, bool enable) { + volatile uint32_t *regPtr = + (volatile uint32_t *)chimera_addrmap.host.chimera_regs.cluster_clk_gate_en; - if (regPtr == NULL) return; - - *(regPtr + CHIMERA_CLUSTER_0_CLK_GATE_EN_REG_OFFSET) = enable; - *(regPtr + CHIMERA_CLUSTER_1_CLK_GATE_EN_REG_OFFSET) = enable; - *(regPtr + CHIMERA_CLUSTER_2_CLK_GATE_EN_REG_OFFSET) = enable; - *(regPtr + CHIMERA_CLUSTER_3_CLK_GATE_EN_REG_OFFSET) = enable; - *(regPtr + CHIMERA_CLUSTER_4_CLK_GATE_EN_REG_OFFSET) = enable; + setAllRegs(regPtr, numRegs, enable); } /* Set Soft Reset on specified cluster */ -void setClusterReset(volatile uint8_t *regPtr, uint8_t clusterId, bool enable) { +void setClusterReset(uint8_t clusterId, bool enable) { + volatile uint32_t *regPtr = + (volatile uint32_t *)chimera_addrmap.host.chimera_regs.reset_cluster; + + setReg(regPtr, clusterId, enable); +} + +/* Set Soft Reset on all clusters */ +void setAllClusterReset(volatile uint8_t numRegs, bool enable) { + volatile uint32_t *regPtr = + (volatile uint32_t *)chimera_addrmap.host.chimera_regs.reset_cluster; + + setAllRegs(regPtr, numRegs, enable); +} + +/* Set Bit on specified register */ +void setReg(volatile uint32_t *regPtr, uint8_t regIdx, bool enable) { if (regPtr == NULL) return; - if (clusterId == 0) { - *(regPtr + CHIMERA_RESET_CLUSTER_0_REG_OFFSET) = enable; - } else if (clusterId == 1) { - *(regPtr + CHIMERA_RESET_CLUSTER_1_REG_OFFSET) = enable; - } else if (clusterId == 2) { - *(regPtr + CHIMERA_RESET_CLUSTER_2_REG_OFFSET) = enable; - } else if (clusterId == 3) { - *(regPtr + CHIMERA_RESET_CLUSTER_3_REG_OFFSET) = enable; - } else if (clusterId == 4) { - *(regPtr + CHIMERA_RESET_CLUSTER_4_REG_OFFSET) = enable; - } + regPtr[regIdx] = enable; } -/* Set Soft Reset on all clusters */ -void setAllClusterReset(volatile uint8_t *regPtr, bool enable) { +/* Set Bit on all registers */ +void setAllRegs(volatile uint32_t *regPtr, uint8_t numRegs, bool enable) { if (regPtr == NULL) return; - *(regPtr + CHIMERA_RESET_CLUSTER_0_REG_OFFSET) = enable; - *(regPtr + CHIMERA_RESET_CLUSTER_1_REG_OFFSET) = enable; - *(regPtr + CHIMERA_RESET_CLUSTER_2_REG_OFFSET) = enable; - *(regPtr + CHIMERA_RESET_CLUSTER_3_REG_OFFSET) = enable; - *(regPtr + CHIMERA_RESET_CLUSTER_4_REG_OFFSET) = enable; + for (int i = 0; i < numRegs; i++) { + regPtr[i] = enable; + } } /* Offloads a void function pointer to the specified cluster's core 0 */ void offloadToCluster(void *function, uint8_t clusterId) { volatile void **snitchBootAddr = - (volatile void **)(SOC_CTRL_BASE + CHIMERA_SNITCH_BOOT_ADDR_REG_OFFSET); + (volatile void **)(&chimera_addrmap.host.chimera_regs.snitch_boot_addr); *snitchBootAddr = function; @@ -127,22 +106,8 @@ void offloadToCluster(void *function, uint8_t clusterId) { * returns the return value */ uint32_t waitForCluster(uint8_t clusterId) { volatile int32_t *snitchReturnAddr; - if (clusterId == 0) { - snitchReturnAddr = - (volatile int32_t *)(SOC_CTRL_BASE + CHIMERA_SNITCH_CLUSTER_0_RETURN_REG_OFFSET); - } else if (clusterId == 1) { - snitchReturnAddr = - (volatile int32_t *)(SOC_CTRL_BASE + CHIMERA_SNITCH_CLUSTER_1_RETURN_REG_OFFSET); - } else if (clusterId == 2) { - snitchReturnAddr = - (volatile int32_t *)(SOC_CTRL_BASE + CHIMERA_SNITCH_CLUSTER_2_RETURN_REG_OFFSET); - } else if (clusterId == 3) { - snitchReturnAddr = - (volatile int32_t *)(SOC_CTRL_BASE + CHIMERA_SNITCH_CLUSTER_3_RETURN_REG_OFFSET); - } else if (clusterId == 4) { - snitchReturnAddr = - (volatile int32_t *)(SOC_CTRL_BASE + CHIMERA_SNITCH_CLUSTER_4_RETURN_REG_OFFSET); - } + snitchReturnAddr = + (volatile int32_t *)(&chimera_addrmap.host.chimera_regs.snitch_cluster_return[clusterId]); while (*snitchReturnAddr == 0) { } diff --git a/sw/sw.mk b/sw/sw.mk index 0c55342..1db1706 100644 --- a/sw/sw.mk +++ b/sw/sw.mk @@ -11,6 +11,16 @@ chim_sw_mk=1 CHS_SW_INCLUDES += -I$(CHIM_SW_DIR)/include +############# +# SystemRDL # +############# + +$(CHIM_SW_DIR)/include/chimera_addrmap.h: $(CHIM_RDL_ALL) + $(PEAKRDL) c-header $< $(PEAKRDL_INCLUDES) $(PEAKRDL_DEFINES) -o $@ -i -b ltoh -P NumClusters=$(NUMCLUSTERS) + @sed -i '1i// Copyright 2025 ETH Zurich and University of Bologna.\n// Licensed under the Apache License, Version 2 0, see LICENSE for details.\n// SPDX-License-Identifier: Apache-2.0\n' $@ + +.PHONY: chimera-addrmap +chimera-addrmap: $(CHIM_SW_DIR)/include/chimera_addrmap.h # SCHEREMO: use im for platform-level SW, as the smallest common denominator between CVA6 and the Snitch cluster. # CVA6's bootrom however needs imc, so override that for this specific case. diff --git a/sw/tests/testCfgBootAddr.c b/sw/tests/testCfgBootAddr.c index 8f6ff52..d3e5e34 100644 --- a/sw/tests/testCfgBootAddr.c +++ b/sw/tests/testCfgBootAddr.c @@ -5,36 +5,38 @@ // Lorenzo Leone #include -#include "regs/soc_ctrl.h" +#include +#include "offload.h" #include #include -#define TESTVAL 0x00E0D0C0 +#define TESTVAL 0x00E0D0FF #define RSTVAL 0x30000000 +#define NUMCLUSTERS 5 int main() { - volatile uint32_t *regPtr = (volatile uint32_t *)SOC_CTRL_BASE; uint32_t regVal = 0; - uint32_t regOffset = CHIMERA_SNITCH_CONFIGURABLE_BOOT_ADDR_REG_OFFSET / 4; + volatile uint32_t *cfgBootAddr = + (volatile uint32_t *)&chimera_addrmap.host.chimera_regs.snitch_configurable_boot_addr; // Check if configurable boot address reset value is the expected one: 0x30000000 - regVal = *(regPtr + regOffset); + regVal = *(cfgBootAddr); if (regVal != RSTVAL) { return 1; } // Write a TESTVAL and check the write was succesfull - *(regPtr + regOffset) = TESTVAL; - regVal = *(regPtr + regOffset); + *(cfgBootAddr) = TESTVAL; + regVal = *(cfgBootAddr); if (regVal != TESTVAL) { return 2; } // Write the original value again and disable cluster clock gating to check correct boot // wait 100 cycles to see boot access from, the waveforms. - *(regPtr + regOffset) = RSTVAL; - setAllClusterReset(regPtr, 0); - setAllClusterClockGating(regPtr, 0); + *(cfgBootAddr) = RSTVAL; + setAllClusterReset(NUMCLUSTERS, 0); + setAllClusterClockGating(NUMCLUSTERS, 0); for (int i = 0; i < 100; i++) { // NOP diff --git a/sw/tests/testCluster.c b/sw/tests/testCluster.c index 761e62b..8509878 100644 --- a/sw/tests/testCluster.c +++ b/sw/tests/testCluster.c @@ -3,8 +3,11 @@ // SPDX-License-Identifier: Apache-2.0 // // Moritz Scherer +// Lorenzo Leone // Viviane Potocnik +#include +#include "offload.h" #include #include @@ -15,10 +18,9 @@ #define TESTVAL 0x00E0D0C0 int main() { - volatile uint8_t *regPtr = (volatile uint8_t *)SOC_CTRL_BASE; - setAllClusterReset(regPtr, 0); - setAllClusterClockGating(regPtr, 0); + setAllClusterReset(NUMCLUSTERS, 0); + setAllClusterClockGating(NUMCLUSTERS, 0); volatile int32_t *clusterMemPtr = (volatile int32_t *)CLUSTERMEMORYSTART; volatile int32_t result; diff --git a/sw/tests/testClusterGating.c b/sw/tests/testClusterGating.c index bea0820..390cfd6 100644 --- a/sw/tests/testClusterGating.c +++ b/sw/tests/testClusterGating.c @@ -5,18 +5,20 @@ // Moritz Scherer // Viviane Potocnik -#include "regs/soc_ctrl.h" #include "soc_addr_map.h" #include "offload.h" #include +#define NUMCLUSTERS 5 + int main() { - volatile uint8_t *regPtr = (volatile uint8_t *)SOC_CTRL_BASE; - setAllClusterReset(regPtr, 0); - setClusterClockGating(regPtr, 0, 1); - setClusterClockGating(regPtr, 3, 1); - setClusterClockGating(regPtr, 4, 1); + setAllClusterReset(NUMCLUSTERS, 0); + setAllClusterClockGating(NUMCLUSTERS, 0); + + setClusterClockGating(0, 1); + setClusterClockGating(3, 1); + setClusterClockGating(4, 1); while (1) { } diff --git a/sw/tests/testClusterOffload.c b/sw/tests/testClusterOffload.c index df444bb..b7cd62e 100644 --- a/sw/tests/testClusterOffload.c +++ b/sw/tests/testClusterOffload.c @@ -3,6 +3,7 @@ // SPDX-License-Identifier: Apache-2.0 // // Moritz Scherer +// Lorenzo Leone // Viviane Potocnik // Simple offload test. Set the trap handler first, offload a function, retrieve @@ -11,7 +12,6 @@ #include "offload.h" #include "soc_addr_map.h" -#include #include #define TESTVAL 0x050CCE55 @@ -32,17 +32,17 @@ int32_t testReturn() { } int main() { - volatile uint8_t *regPtr = (volatile uint8_t *)SOC_CTRL_BASE; + setupInterruptHandler(clusterTrapHandler); uint32_t retVal = 0; for (int i = 0; i < _chimera_numClusters; i++) { - setClusterReset(regPtr, i, 0); - setClusterClockGating(regPtr, i, 0); + setClusterReset(i, 0); + setClusterClockGating(i, 0); offloadToCluster(testReturn, i); retVal |= waitForCluster(i); - setClusterClockGating(regPtr, i, 1); - setClusterReset(regPtr, i, 0); + setClusterClockGating(i, 1); + setClusterReset(i, 0); } return (retVal != (TESTVAL | 0x000000001)); diff --git a/sw/tests/testHyperbusAddr.c b/sw/tests/testHyperbusAddr.c index d1bef52..a6f9c99 100644 --- a/sw/tests/testHyperbusAddr.c +++ b/sw/tests/testHyperbusAddr.c @@ -3,20 +3,23 @@ // SPDX-License-Identifier: Apache-2.0 // // Sergio Mazzola +// Lorenzo Leone // Viviane Potocnik // Test HyperRAM addressability through the Hyperbus peripheral #include +#include "offload.h" #include #define HYPER_BASE HYPERRAM_BASE #define TESTVAL (uint32_t)0x1234ABCD +#define NUMCLUSTERS 5 int main() { - volatile uint8_t *regPtr = (volatile uint8_t *)SOC_CTRL_BASE; - setAllClusterReset(regPtr, 0); - setAllClusterClockGating(regPtr, 0); + + setAllClusterReset(NUMCLUSTERS, 0); + setAllClusterClockGating(NUMCLUSTERS, 0); volatile uint32_t *hyperMemPtr = (volatile uint32_t *)HYPER_BASE; volatile uint32_t result; diff --git a/sw/tests/testMemBypass.c b/sw/tests/testMemBypass.c index f690739..81b2cd3 100644 --- a/sw/tests/testMemBypass.c +++ b/sw/tests/testMemBypass.c @@ -12,11 +12,10 @@ // - Access the memory island both settin/disabling the bypass mode #include -#include "regs/soc_ctrl.h" #include "offload.h" +#include #include "soc_addr_map.h" -// #define TOPLEVELREGION 0x30001000 #define NUMCLUSTERS 5 #define TESTNARROW 0x050CCE55 #define TESTWIDE 0x060CCE55 @@ -32,20 +31,10 @@ void clusterTrapHandler() { return; } -int32_t returnPtr(uint32_t ClstIdx) { - int32_t regPtr; - - if (ClstIdx == 0) { - regPtr = (SOC_CTRL_BASE + CHIMERA_WIDE_MEM_CLUSTER_0_BYPASS_REG_OFFSET); - } else if (ClstIdx == 1) { - regPtr = (SOC_CTRL_BASE + CHIMERA_WIDE_MEM_CLUSTER_1_BYPASS_REG_OFFSET); - } else if (ClstIdx == 2) { - regPtr = (SOC_CTRL_BASE + CHIMERA_WIDE_MEM_CLUSTER_2_BYPASS_REG_OFFSET); - } else if (ClstIdx == 3) { - regPtr = (SOC_CTRL_BASE + CHIMERA_WIDE_MEM_CLUSTER_3_BYPASS_REG_OFFSET); - } else if (ClstIdx == 4) { - regPtr = (SOC_CTRL_BASE + CHIMERA_WIDE_MEM_CLUSTER_4_BYPASS_REG_OFFSET); - } +int32_t *returnPtr(uint32_t clusterIdx) { + int32_t *regPtr; + regPtr = (int32_t *)&chimera_addrmap.host.chimera_regs.wide_mem_cluster_bypass[clusterIdx]; + return regPtr; } @@ -59,19 +48,18 @@ int32_t __attribute__((aligned(32))) testMemWide() { } int main() { - volatile uint8_t *clockGatingRegPtr = (volatile uint8_t *)SOC_CTRL_BASE; - volatile uint8_t *resetRegPtr = (volatile uint8_t *)SOC_CTRL_BASE; - setAllClusterReset(resetRegPtr, 0); - setAllClusterClockGating(clockGatingRegPtr, 0); + + setAllClusterReset(NUMCLUSTERS, 0); + setAllClusterClockGating(NUMCLUSTERS, 0); volatile int32_t *regPtr = 0; uint32_t retVal = 0; // Tes for each cluster - for (int ClstIdx = 0; ClstIdx < NUMCLUSTERS; ClstIdx++) { + for (int clusterIdx = 0; clusterIdx < NUMCLUSTERS; clusterIdx++) { - regPtr = (volatile int32_t *)returnPtr(ClstIdx); + regPtr = (volatile int32_t *)returnPtr(clusterIdx); /* TEST RESET VALUE */ if (*regPtr != 0) { diff --git a/sw/tests/testPeripheralsGating.c b/sw/tests/testPeripheralsGating.c index 49858a4..390b437 100644 --- a/sw/tests/testPeripheralsGating.c +++ b/sw/tests/testPeripheralsGating.c @@ -16,12 +16,12 @@ #include "soc_addr_map.h" #define CHESHIRE_REGS_BASE 0x03000000 +#define NUMCLUSTERS 5 int main() { - volatile uint8_t *clockGatingRegPtr = (volatile uint8_t *)SOC_CTRL_BASE; - volatile uint8_t *resetRegPtr = (volatile uint8_t *)SOC_CTRL_BASE; - setAllClusterReset(resetRegPtr, 0); - setAllClusterClockGating(clockGatingRegPtr, 0); + + setAllClusterReset(NUMCLUSTERS, 0); + setAllClusterClockGating(NUMCLUSTERS, 0); volatile uint32_t *regPtr = 0; uint8_t expVal;