From d4137f416bb8de129902291489695a3045ad245e Mon Sep 17 00:00:00 2001 From: Luca Balboni Date: Thu, 30 Jul 2026 15:27:34 +0200 Subject: [PATCH 1/3] Removed RI5CY and re-enabled CV32E40X in memory-mapped mode --- .gitignore | 3 + Bender.lock | 2 +- Bender.yml | 37 +- Makefile | 46 +- README.md | 4 +- bender_common.mk | 1 - hw/tile/converters/cv32e40p_data2obi.sv | 49 ++ hw/tile/converters/cv32e40p_obi2data.sv | 38 ++ .../{data2obi.sv => cv32e40x_data2obi.sv} | 28 +- .../{obi2data.sv => cv32e40x_obi2data.sv} | 22 +- hw/tile/fractal_sync_xif_inst_decoder.sv | 332 ------------ hw/tile/idma_ctrl.sv | 292 ---------- hw/tile/idma_xif_inst_decoder.sv | 445 ---------------- hw/tile/magia_tile.sv | 501 +++--------------- hw/tile/magia_tile_pkg.sv | 177 ++----- hw/tile/xif_inst_dispatcher.sv | 204 ------- setup_env.sh | 12 +- sw/kernel_pulp/Makefile | 38 +- sw/tests/cluster_tests/hello_pulp/main.c | 13 +- .../hello_pulp/pulp_task/hello_pulp_task.c | 13 +- sw/tests/fpu_test.c | 16 +- sw/tests/xif_tests/fsync_extended_test.c | 131 ----- sw/tests/xif_tests/fsync_test.c | 286 ---------- sw/tests/xif_tests/idma_test.c | 213 -------- sw/tests/xif_tests/mesh_test.c | 265 --------- sw/tests/xif_tests/redmule_test.c | 113 ---- sw/tests/xif_tests/tile_test.c | 255 --------- sw/utils/event_unit_utils.h | 11 +- sw/utils/magia_utils.h | 14 +- 29 files changed, 272 insertions(+), 3289 deletions(-) create mode 100644 hw/tile/converters/cv32e40p_data2obi.sv create mode 100644 hw/tile/converters/cv32e40p_obi2data.sv rename hw/tile/converters/{data2obi.sv => cv32e40x_data2obi.sv} (74%) rename hw/tile/converters/{obi2data.sv => cv32e40x_obi2data.sv} (68%) delete mode 100644 hw/tile/fractal_sync_xif_inst_decoder.sv delete mode 100644 hw/tile/idma_ctrl.sv delete mode 100644 hw/tile/idma_xif_inst_decoder.sv delete mode 100644 hw/tile/xif_inst_dispatcher.sv delete mode 100644 sw/tests/xif_tests/fsync_extended_test.c delete mode 100644 sw/tests/xif_tests/fsync_test.c delete mode 100644 sw/tests/xif_tests/idma_test.c delete mode 100644 sw/tests/xif_tests/mesh_test.c delete mode 100644 sw/tests/xif_tests/redmule_test.c delete mode 100644 sw/tests/xif_tests/tile_test.c diff --git a/.gitignore b/.gitignore index d03f86be..958b0821 100644 --- a/.gitignore +++ b/.gitignore @@ -6,6 +6,7 @@ update-ips.log synth-ips.log build-hw.log profile-ips.log +vsim-scripts.log magia_venv/ modelsim.ini regression_logs/ @@ -23,6 +24,8 @@ sw/tests/*/*/work/ sw/tests/*/*/work sw/tests/*/*/transcript sw/tests/*/*/*.log +sw/tests/*/traces/*/ +sw/tests/*/*/traces/*/ spatz/bootrom/*.elf spatz/bootrom/*.bin diff --git a/Bender.lock b/Bender.lock index ec2ea9c6..62c99f31 100644 --- a/Bender.lock +++ b/Bender.lock @@ -72,7 +72,7 @@ packages: Git: https://github.com/pulp-platform/common_verification.git dependencies: [] cv32e40p: - revision: a8206ab02759f110c40dd907369816ea656381bc + revision: 65c6961d8acf9698e09c976228c43692d700e697 version: null source: Git: https://github.com/FondazioneChipsIT/cv32e40p.git diff --git a/Bender.yml b/Bender.yml index 44eca32c..d334c5e4 100644 --- a/Bender.yml +++ b/Bender.yml @@ -26,11 +26,11 @@ package: dependencies: redmule : { git: "https://github.com/pulp-platform/redmule.git" , version: 2.1.0 } cv32e40x : { git: "https://github.com/pulp-platform/cv32e40x.git" , rev: a90101211048ba1a16cedbe4db963ab6e12569d7 } # branch: vi/redmule_scaleup - cv32e40p : { git: "https://github.com/FondazioneChipsIT/cv32e40p.git" , rev: a8206ab02759f110c40dd907369816ea656381bc } # branch: ng/pulp_cluster + cv32e40p : { git: "https://github.com/FondazioneChipsIT/cv32e40p.git" , rev: 65c6961d8acf9698e09c976228c43692d700e697 } # branch: ng/pulp_cluster spatz : { git: "https://github.com/pulp-platform/spatz.git" , rev: 9380883fd36a4794d7f31e2c22e3fed3202aeb81 } # branch: lb/magia-spatz_cc idma : { git: "https://github.com/pulp-platform/iDMA.git" , rev: ff5d56fffb3767814db88d6bf8f381974ea33aa5 } # version: 0.6.4 hwpe-stream : { git: "https://github.com/pulp-platform/hwpe-stream.git" , version: 1.6 } - hwpe-ctrl : { git: "https://github.com/pulp-platform/hwpe-ctrl.git" , version: 3.1.0 } + hwpe-ctrl : { git: "https://github.com/pulp-platform/hwpe-ctrl.git" , version: 3.1.0 } hci : { git: "https://github.com/pulp-platform/hci.git" , version: 2.3.0 } cluster_icache : { git: "https://github.com/pulp-platform/cluster_icache.git" , version: 0.2.0 } fpnew : { git: "https://github.com/pulp-platform/cvfpu.git" , rev: "pulp-v0.1.3" } @@ -60,8 +60,10 @@ sources: - hw/mesh/magia_pkg.sv - hw/tile/magia_tile_pkg.sv # MAGIA Tile - - hw/tile/converters/data2obi.sv - - hw/tile/converters/obi2data.sv + - hw/tile/converters/cv32e40p_data2obi.sv + - hw/tile/converters/cv32e40x_data2obi.sv + - hw/tile/converters/cv32e40p_obi2data.sv + - hw/tile/converters/cv32e40x_obi2data.sv - hw/tile/converters/instr2obi.sv - hw/tile/converters/obi2instr.sv - hw/tile/converters/instr2cache.sv @@ -84,14 +86,9 @@ sources: - hw/tile/obi_demux_addr.sv - hw/tile/l1_spm.sv - hw/tile/local_interconnect.sv - - hw/tile/idma_xif_inst_decoder.sv - - hw/tile/xif_inst_dispatcher.sv - - hw/tile/idma_xif_inst_decoder.sv - - hw/tile/idma_ctrl.sv - hw/tile/idma_axi_obi_transfer_ch.sv - hw/tile/idma_obi_ctrl_decoder.sv - hw/tile/idma_ctrl_mm.sv - - hw/tile/fractal_sync_xif_inst_decoder.sv - hw/tile/obi_slave_fsync.sv - hw/tile/obi_slave_ctrl_spatz.sv - hw/tile/obi_slave_ctrl_cluster.sv @@ -127,8 +124,10 @@ sources: - hw/tile/magia_tile_pkg.sv - hw/mesh/noc/magia_noc_pkg.sv # MAGIA Tile - - hw/tile/converters/data2obi.sv - - hw/tile/converters/obi2data.sv + - hw/tile/converters/cv32e40p_data2obi.sv + - hw/tile/converters/cv32e40x_data2obi.sv + - hw/tile/converters/cv32e40p_obi2data.sv + - hw/tile/converters/cv32e40x_obi2data.sv - hw/tile/converters/instr2obi.sv - hw/tile/converters/obi2instr.sv - hw/tile/converters/instr2cache.sv @@ -151,14 +150,9 @@ sources: - hw/tile/obi_demux_addr.sv - hw/tile/l1_spm.sv - hw/tile/local_interconnect.sv - - hw/tile/idma_xif_inst_decoder.sv - - hw/tile/xif_inst_dispatcher.sv - - hw/tile/idma_xif_inst_decoder.sv - - hw/tile/idma_ctrl.sv - hw/tile/idma_axi_obi_transfer_ch.sv - hw/tile/idma_obi_ctrl_decoder.sv - hw/tile/idma_ctrl_mm.sv - - hw/tile/fractal_sync_xif_inst_decoder.sv - hw/tile/obi_slave_fsync.sv - hw/tile/obi_slave_ctrl_spatz.sv - hw/tile/obi_slave_ctrl_cluster.sv @@ -209,8 +203,10 @@ sources: - hw/tile/magia_tile_pkg.sv - hw/mesh/noc/magia_noc_pkg.sv # MAGIA Tile - - hw/tile/converters/data2obi.sv - - hw/tile/converters/obi2data.sv + - hw/tile/converters/cv32e40p_data2obi.sv + - hw/tile/converters/cv32e40x_data2obi.sv + - hw/tile/converters/cv32e40p_obi2data.sv + - hw/tile/converters/cv32e40x_obi2data.sv - hw/tile/converters/instr2obi.sv - hw/tile/converters/obi2instr.sv - hw/tile/converters/instr2cache.sv @@ -233,14 +229,9 @@ sources: - hw/tile/obi_demux_addr.sv - hw/tile/l1_spm.sv - hw/tile/local_interconnect.sv - - hw/tile/idma_xif_inst_decoder.sv - - hw/tile/xif_inst_dispatcher.sv - - hw/tile/idma_xif_inst_decoder.sv - - hw/tile/idma_ctrl.sv - hw/tile/idma_axi_obi_transfer_ch.sv - hw/tile/idma_obi_ctrl_decoder.sv - hw/tile/idma_ctrl_mm.sv - - hw/tile/fractal_sync_xif_inst_decoder.sv - hw/tile/obi_slave_fsync.sv - hw/tile/obi_slave_ctrl_spatz.sv - hw/tile/obi_slave_ctrl_cluster.sv diff --git a/Makefile b/Makefile index dce40399..83418b07 100644 --- a/Makefile +++ b/Makefile @@ -46,16 +46,7 @@ ifeq ($(core), CV32E40X) ISA = riscv ABI ?= ilp XABI ?= f -else ifeq ($(core), RI5CY) - XTEN = imcxgap9 - ISA = riscv - ABI ?= ilp - XABI ?= else - # CV32E40P configured with ZFINX=1 in RTL: FP ops use the GPRs (no F register - # file). Toolchain must therefore use Zfinx (and Zhinxmin for FP16) and the - # plain ilp32 ABI; using `f` in march or ilp32f ABI would emit instructions - # that target the (non-existent) F regs. XTEN = imc_xcvalu_xcvbi_xcvbitmanip_xcvhwlp_xcvmac_xcvmem_xcvsimd_xcvelw_zfinx_zhinxmin ISA = cv32e40p ABI ?= ilp @@ -124,9 +115,6 @@ ifeq ($(core), CV32E40P) FLAGS += -DCV32E40P endif -ifeq ($(core), RI5CY) - FLAGS += -DRI5CY -endif # Include directories INC += -Isw @@ -226,11 +214,14 @@ spatz-header: # Build PULP cluster binary (magia-sdk style): produces # sw/kernel_pulp/headers_bin/_pulp_task_bin.h # embedding the position-independent flat binary in section .pulp_binary. +# PULP cluster cores are always CV32E40P (see magia_tile.sv), independent of +# which core is selected for the control core via $(core) — so core=CV32E40P +# is hardcoded here rather than forwarding $(core). .PHONY: pulp-header pulp-header: @if [ -n "$(PULP_TASKS)" ]; then \ echo "[PULP] Auto-detected tasks: $(PULP_TASKS)"; \ - $(MAKE) -C $(PULP_SW_DIR) TEST_NAME=$(test) task="$(PULP_TASKS)" PULP_TASK_DIR=$(ROOT_DIR)/$(PULP_TASK_DIR_PATH) core=$(core) all; \ + $(MAKE) -C $(PULP_SW_DIR) TEST_NAME=$(test) task="$(PULP_TASKS)" PULP_TASK_DIR=$(ROOT_DIR)/$(PULP_TASK_DIR_PATH) core=CV32E40P all; \ else \ echo "[PULP] No pulp_task/ directory — skipping PULP cluster compilation"; \ fi @@ -354,18 +345,13 @@ ifeq ($(core), CV32E40X) bender_defs += -D CV32E40X else ifeq ($(core), CV32E40P) bender_defs += -D CV32E40P -else ifeq ($(core), RI5CY) - bender_defs += -D RI5CY else - $(error Detected unsupported core, must choose among CV32E40X, CV32E40P and RI5CY) + $(error Detected unsupported core, must choose among CV32E40X or CV32E40P ) endif bender_targs += -t rtl bender_targs += -t test -ifeq ($(core), CV32E40P) bender_targs += -t cv32e40p_include_tracer -endif -# RI5CY: riscv_*.sv compiled unconditionally by the PULP cv32e40p package, no extra bender target needed # Targets needed to avoid error even though the module is not used @@ -411,19 +397,9 @@ bender_defs += -D SPATZ_XDMA=$(SPATZ_XDMA) bender_defs += -D SPATZ_RVF=$(SPATZ_RVF) bender_defs += -D SPATZ_RVV=$(SPATZ_RVV) -# RI5CY_CV32E40P_GIT / RI5CY_CV32E40P_REV: PULP repo override for core=RI5CY -RI5CY_CV32E40P_GIT := https://github.com/pulp-platform/cv32e40p.git -RI5CY_CV32E40P_REV := f5241403d5d65dbe1fffacd7035dd7ae1359c8ef -CV32E40P_GIT := https://github.com/FondazioneChipsIT/cv32e40p.git -CV32E40P_REV := a8206ab02759f110c40dd907369816ea656381bc update-ips: -ifeq ($(core), RI5CY) - @sed -i '/^ cv32e40p:$$/,/^ cv32e40x:/ { s|^ revision: .*| revision: $(RI5CY_CV32E40P_REV)|; s|^ Git: .*| Git: $(RI5CY_CV32E40P_GIT)|; }' Bender.lock -else - @sed -i '/^ cv32e40p:$$/,/^ cv32e40x:/ { s|^ revision: .*| revision: $(CV32E40P_REV)|; s|^ Git: .*| Git: $(CV32E40P_GIT)|; }' Bender.lock -endif - $(BENDER) checkout + $(BENDER) update $(BENDER) script vsim \ --vlog-arg="$(compile_flag)" \ --vcom-arg="-pedanticerrors" \ @@ -432,11 +408,6 @@ endif > ${compile_script} vsim-scripts: -ifeq ($(core), RI5CY) - @sed -i '/^ cv32e40p:$$/,/^ cv32e40x:/ { s|^ revision: .*| revision: $(RI5CY_CV32E40P_REV)|; s|^ Git: .*| Git: $(RI5CY_CV32E40P_GIT)|; }' Bender.lock -else - @sed -i '/^ cv32e40p:$$/,/^ cv32e40x:/ { s|^ revision: .*| revision: $(CV32E40P_REV)|; s|^ Git: .*| Git: $(CV32E40P_GIT)|; }' Bender.lock -endif $(BENDER) script vsim \ --vlog-arg="$(compile_flag)" \ --vcom-arg="-pedanticerrors" \ @@ -445,11 +416,6 @@ endif > ${compile_script} synth-ips: -ifeq ($(core), RI5CY) - @sed -i '/^ cv32e40p:$$/,/^ cv32e40x:/ { s|^ revision: .*| revision: $(RI5CY_CV32E40P_REV)|; s|^ Git: .*| Git: $(RI5CY_CV32E40P_GIT)|; }' Bender.lock -else - @sed -i '/^ cv32e40p:$$/,/^ cv32e40x:/ { s|^ revision: .*| revision: $(CV32E40P_REV)|; s|^ Git: .*| Git: $(CV32E40P_GIT)|; }' Bender.lock -endif $(MAKE) -C $(IDMA_ROOT) idma_hw_all IDMA_ADD_IDS=$(IDMA_ADD_IDS) $(BENDER) script synopsys \ $(common_targs) $(common_defs) \ diff --git a/README.md b/README.md index 645071ba..1b056ead 100644 --- a/README.md +++ b/README.md @@ -31,7 +31,7 @@ The following *optional* parameters can be specified: `gui`: **0**|**1** (**Default**: 0). 0 simulation without GUI; 1 simulation with GUI. -`core`: **CV32E40P**|**RI5CY**|**CV32E40X** (**Default**: CV32E40P). Control and cluster cores type. +`core`: **CV32E40P**|**CV32E40X** (**Default**: CV32E40P). Control and cluster cores type. **Instructions to build HW/SW and run simulations**: @@ -182,7 +182,7 @@ The central piece of the architecture is the MAGIA tile containing a GeMM accele Each tile is controlled by a [CV32E40P](https://github.com/pulp-platform/cv32e40p) main core. Control of iDMA, RedMulE, FractalSync, Spatz CC, and the PULP cluster follows a memory-mapped model, with the Event Unit handling event aggregation for system control. #### PULP Cluster -Each tile embeds a cluster of 8 [CV32E40P](https://github.com/pulp-platform/cv32e40p) (or RI5CY) cores. Cluster cores share a Snitch instruction cache with an AXI refill path to L2, and each core has its own OBI master port into the tile crossbar for data accesses (L1, accelerator registers, PULP_CTRL). Cluster cores receive interrupts exclusively from the tile CSR (`PULP_CTRL`) — they are not connected to the Event Unit. The main core dispatches tasks to the cluster via the `PULP_CTRL` register block (`0x1740`), which provides: binary entry point (`PULP_BINARY`), per-core MEI dispatch (`PULP_START`), task function pointer (`PULP_TASKBIN`), data pointer (`PULP_DATA`), completion quorum (`PULP_NB_CORES_TO_WAIT`), and readiness/done handshake registers (`PULP_READY`, `PULP_DONE`). When the done quorum is reached, the tile CSR raises EU bit 12 on the main core's Event Unit, allowing the main core to sleep in WFE until the cluster finishes. +Each tile embeds a cluster of 8 [CV32E40P](https://github.com/pulp-platform/cv32e40p) cores. Cluster cores share a Snitch instruction cache with an AXI refill path to L2, and each core has its own OBI master port into the tile crossbar for data accesses (L1, accelerator registers, PULP_CTRL). Cluster cores receive interrupts exclusively from the tile CSR (`PULP_CTRL`) — they are not connected to the Event Unit. The main core dispatches tasks to the cluster via the `PULP_CTRL` register block (`0x1740`), which provides: binary entry point (`PULP_BINARY`), per-core MEI dispatch (`PULP_START`), task function pointer (`PULP_TASKBIN`), data pointer (`PULP_DATA`), completion quorum (`PULP_NB_CORES_TO_WAIT`), and readiness/done handshake registers (`PULP_READY`, `PULP_DONE`). When the done quorum is reached, the tile CSR raises EU bit 12 on the main core's Event Unit, allowing the main core to sleep in WFE until the cluster finishes. ### Mesh Replicating the MAGIA tile, we scale up to a homogeneous two-dimensional (2D) mesh of compute tiles. The NoC allows access to the global west-side L2 through row-side interfaces, while tiles exchange traffic through FlooNoC router. The mesh uses XY routing and carries both AXI narrow channels (32-bit) and AXI wide channels (256-bit), with protocol conversion handled by per-tile Network Interfaces (NIs). diff --git a/bender_common.mk b/bender_common.mk index 3c0c4f0d..cff75149 100644 --- a/bender_common.mk +++ b/bender_common.mk @@ -26,7 +26,6 @@ ifeq ($(core), CV32E40X) sim_targs += -t cv32e40x else ifeq ($(core), CV32E40P) sim_targs += -t cv32e40p -# RI5CY: no bender target needed — riscv_*.sv compiled unconditionally by the PULP cv32e40p package endif common_targs += -t magia_tile diff --git a/hw/tile/converters/cv32e40p_data2obi.sv b/hw/tile/converters/cv32e40p_data2obi.sv new file mode 100644 index 00000000..1e1d030a --- /dev/null +++ b/hw/tile/converters/cv32e40p_data2obi.sv @@ -0,0 +1,49 @@ +/* + * Copyright (C) 2023-2024 ETH Zurich and University of Bologna + * + * Licensed under the Solderpad Hardware License, Version 0.51 + * (the "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * SPDX-License-Identifier: SHL-0.51 + * + * Authors: Victor Isachi + * Luca Balboni + * + * CV32E40P Core Data - OBI REQ Converter + * + * CV32E40P has no atop/memtype/prot/dbg on its data channel, so those OBI + * optional fields are tied to their inactive defaults. Used by the PULP + * cluster cores (always CV32E40P) and by the control core when it is CV32E40P. + */ + +module cv32e40p_data2obi_req + import magia_tile_pkg::*; +( + input magia_tile_pkg::cv32e40p_core_data_req_t data_req_i, + output magia_tile_pkg::core_obi_data_req_t obi_req_o +); + + assign obi_req_o.req = data_req_i.req; + assign obi_req_o.a.addr = data_req_i.addr; + assign obi_req_o.a.we = data_req_i.we; + assign obi_req_o.a.be = data_req_i.be; + assign obi_req_o.a.wdata = data_req_i.wdata; + assign obi_req_o.a.aid = 'b0; + assign obi_req_o.a.a_optional.auser = 'b0; + assign obi_req_o.a.a_optional.wuser = 'b0; + assign obi_req_o.a.a_optional.mid = 'b0; + assign obi_req_o.a.a_optional.achk = 'b0; + assign obi_req_o.a.a_optional.atop = 'b0; + assign obi_req_o.a.a_optional.memtype = 'b0; + assign obi_req_o.a.a_optional.prot = 'b0; + assign obi_req_o.a.a_optional.dbg = 'b0; + +endmodule: cv32e40p_data2obi_req diff --git a/hw/tile/converters/cv32e40p_obi2data.sv b/hw/tile/converters/cv32e40p_obi2data.sv new file mode 100644 index 00000000..5bb9ebf6 --- /dev/null +++ b/hw/tile/converters/cv32e40p_obi2data.sv @@ -0,0 +1,38 @@ +/* + * Copyright (C) 2023-2024 ETH Zurich and University of Bologna + * + * Licensed under the Solderpad Hardware License, Version 0.51 + * (the "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * SPDX-License-Identifier: SHL-0.51 + * + * Authors: Victor Isachi + * Luca Balboni + * + * OBI - CV32E40P Core Data RSP Converter + * + * CV32E40P has no exokay on its data response. Used by the PULP cluster cores + * (always CV32E40P) and by the control core when it is CV32E40P. + */ + +module cv32e40p_obi2data_rsp + import magia_tile_pkg::*; +( + input magia_tile_pkg::core_obi_data_rsp_t obi_rsp_i, + output magia_tile_pkg::cv32e40p_core_data_rsp_t data_rsp_o +); + + assign data_rsp_o.gnt = obi_rsp_i.gnt; + assign data_rsp_o.rvalid = obi_rsp_i.rvalid; + assign data_rsp_o.rdata = obi_rsp_i.r.rdata; + assign data_rsp_o.err = obi_rsp_i.r.err; + +endmodule: cv32e40p_obi2data_rsp diff --git a/hw/tile/converters/data2obi.sv b/hw/tile/converters/cv32e40x_data2obi.sv similarity index 74% rename from hw/tile/converters/data2obi.sv rename to hw/tile/converters/cv32e40x_data2obi.sv index e6146ee7..f09e68db 100644 --- a/hw/tile/converters/data2obi.sv +++ b/hw/tile/converters/cv32e40x_data2obi.sv @@ -1,8 +1,8 @@ /* * Copyright (C) 2023-2024 ETH Zurich and University of Bologna * - * Licensed under the Solderpad Hardware License, Version 0.51 - * (the "License"); you may not use this file except in compliance + * Licensed under the Solderpad Hardware License, Version 0.51 + * (the "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 @@ -15,15 +15,19 @@ * SPDX-License-Identifier: SHL-0.51 * * Authors: Victor Isachi - * - * Core Data - OBI REQ/RSP Converter + * Luca Balboni + * + * CV32E40X Core Data - OBI REQ Converter + * + * CV32E40X drives atop/memtype/prot/dbg on its data channel, which are mapped + * onto the OBI optional fields. Used by the control core when it is CV32E40X. */ -module data2obi_req +module cv32e40x_data2obi_req import magia_tile_pkg::*; ( - input magia_tile_pkg::core_data_req_t data_req_i, - output magia_tile_pkg::core_obi_data_req_t obi_req_o + input magia_tile_pkg::cv32e40x_core_data_req_t data_req_i, + output magia_tile_pkg::core_obi_data_req_t obi_req_o ); assign obi_req_o.req = data_req_i.req; @@ -34,19 +38,11 @@ module data2obi_req assign obi_req_o.a.aid = 'b0; assign obi_req_o.a.a_optional.auser = 'b0; assign obi_req_o.a.a_optional.wuser = 'b0; - assign obi_req_o.a.a_optional.mid = 'b0; assign obi_req_o.a.a_optional.achk = 'b0; -`ifdef CV32E40X assign obi_req_o.a.a_optional.atop = data_req_i.atop; assign obi_req_o.a.a_optional.memtype = data_req_i.memtype; assign obi_req_o.a.a_optional.prot = data_req_i.prot; assign obi_req_o.a.a_optional.dbg = data_req_i.dbg; -`else - assign obi_req_o.a.a_optional.atop = 'b0; - assign obi_req_o.a.a_optional.memtype = 'b0; - assign obi_req_o.a.a_optional.prot = 'b0; - assign obi_req_o.a.a_optional.dbg = 'b0; -`endif -endmodule: data2obi_req +endmodule: cv32e40x_data2obi_req diff --git a/hw/tile/converters/obi2data.sv b/hw/tile/converters/cv32e40x_obi2data.sv similarity index 68% rename from hw/tile/converters/obi2data.sv rename to hw/tile/converters/cv32e40x_obi2data.sv index 70fa64e3..b1c88e34 100644 --- a/hw/tile/converters/obi2data.sv +++ b/hw/tile/converters/cv32e40x_obi2data.sv @@ -1,8 +1,8 @@ /* * Copyright (C) 2023-2024 ETH Zurich and University of Bologna * - * Licensed under the Solderpad Hardware License, Version 0.51 - * (the "License"); you may not use this file except in compliance + * Licensed under the Solderpad Hardware License, Version 0.51 + * (the "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 @@ -15,23 +15,25 @@ * SPDX-License-Identifier: SHL-0.51 * * Authors: Victor Isachi - * - * OBI - Core Data REQ/RSP Converter + * Luca Balboni + * + * OBI - CV32E40X Core Data RSP Converter + * + * CV32E40X consumes the exokay response bit. Used by the control core when it + * is CV32E40X. */ -module obi2data_rsp +module cv32e40x_obi2data_rsp import magia_tile_pkg::*; ( - input magia_tile_pkg::core_obi_data_rsp_t obi_rsp_i, - output magia_tile_pkg::core_data_rsp_t data_rsp_o + input magia_tile_pkg::core_obi_data_rsp_t obi_rsp_i, + output magia_tile_pkg::cv32e40x_core_data_rsp_t data_rsp_o ); assign data_rsp_o.gnt = obi_rsp_i.gnt; assign data_rsp_o.rvalid = obi_rsp_i.rvalid; assign data_rsp_o.rdata = obi_rsp_i.r.rdata; assign data_rsp_o.err = obi_rsp_i.r.err; -`ifdef CV32E40X assign data_rsp_o.exokay = obi_rsp_i.r.r_optional.exokay; -`endif -endmodule: obi2data_rsp \ No newline at end of file +endmodule: cv32e40x_obi2data_rsp diff --git a/hw/tile/fractal_sync_xif_inst_decoder.sv b/hw/tile/fractal_sync_xif_inst_decoder.sv deleted file mode 100644 index a31292ea..00000000 --- a/hw/tile/fractal_sync_xif_inst_decoder.sv +++ /dev/null @@ -1,332 +0,0 @@ -/* - * Copyright (C) 2023-2024 ETH Zurich and University of Bologna - * - * Licensed under the Solderpad Hardware License, Version 0.51 - * (the "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * SPDX-License-Identifier: SHL-0.51 - * - * Authors: Victor Isachi - * - * Fractal Sync Xif Instruction Decoder - */ - -module fractal_sync_xif_inst_decoder - import magia_tile_pkg::*; - import cv32e40x_pkg::*; -#( - parameter int unsigned INSTR_W = magia_tile_pkg::FSYNC_INSTR_W, - parameter int unsigned DATA_W = magia_tile_pkg::FSYNC_DATA_W, - parameter int unsigned ADDR_W = magia_tile_pkg::FSYNC_ADDR_W, - parameter int unsigned N_RF_PORTS = magia_tile_pkg::FSYNC_N_RF_PORTS, - parameter int unsigned OPCODE_W = magia_tile_pkg::FSYNC_OPCODE_W, - parameter int unsigned FUNC3_W = magia_tile_pkg::FSYNC_FUNC3_W, - parameter int unsigned OPCODE_OFF = magia_tile_pkg::FSYNC_OPCODE_OFF, - parameter int unsigned FUNC3_OFF = magia_tile_pkg::FSYNC_FUNC3_OFF, - parameter int unsigned N_CFG_REG = magia_tile_pkg::FSYNC_N_CFG_REG, - parameter int unsigned AGGR_W = magia_tile_pkg::FSYNC_AGGR_W, - parameter int unsigned ID_W = magia_tile_pkg::FSYNC_ID_W, - parameter int unsigned NBR_AGGR_W = magia_tile_pkg::FSYNC_NBR_AGGR_W, - parameter int unsigned NBR_ID_W = magia_tile_pkg::FSYNC_NBR_ID_W, - parameter bit STALL = magia_tile_pkg::FSYNC_STALL -)( - input logic clk_i, - input logic rst_ni, - input logic clear_i, - - cv32e40x_if_xif.coproc_issue xif_issue_if_i, - - fractal_sync_if.mst_port ht_fsync_if_o, - fractal_sync_if.mst_port hn_fsync_if_o, - fractal_sync_if.mst_port vt_fsync_if_o, - fractal_sync_if.mst_port vn_fsync_if_o, - - output logic done_o, - output logic error_o -); - -/*******************************************************/ -/** Internal Signal Definitions Beginning **/ -/*******************************************************/ - - logic clk_dec_en, clk_sync_en; - logic clk_dec_g, clk_sync_g; - - logic[OPCODE_W-1:0] opcode; - logic[ FUNC3_W-1:0] func3; - - logic sync; - logic done; - - logic[N_CFG_REG-1:0][DATA_W-1:0] cfg_reg_d, cfg_reg_q; - - typedef enum logic[1:0] { - IDLE, - SYNC, - WAIT, - DONE - } sync_state_e; - - sync_state_e c_sync_state, n_sync_state; - -/*******************************************************/ -/** Internal Signal Definitions End **/ -/*******************************************************/ -/** Hardwired Signals Beginning **/ -/*******************************************************/ - - assign opcode = xif_issue_if_i.issue_req.instr[OPCODE_OFF+:OPCODE_W]; - assign func3 = xif_issue_if_i.issue_req.instr[ FUNC3_OFF+: FUNC3_W]; - - assign done_o = done; - assign error_o = ht_fsync_if_o.error | hn_fsync_if_o.error | vt_fsync_if_o.error | vn_fsync_if_o.error; - -/*******************************************************/ -/** Hardwired Signals End **/ -/*******************************************************/ -/** Clock gating Beginning **/ -/*******************************************************/ - - tc_clk_gating i_dec_clock_gating ( - .clk_i , - .en_i ( clk_dec_en ), - .test_en_i ( '0 ), - .clk_o ( clk_dec_g ) - ); - - tc_clk_gating i_sync_clock_gating ( - .clk_i , - .en_i ( clk_sync_en ), - .test_en_i ( '0 ), - .clk_o ( clk_sync_g ) - ); - -/*******************************************************/ -/** Clock gating End **/ -/*******************************************************/ -/** Decoder FSM Beginning **/ -/*******************************************************/ - - generate if (STALL) begin: gen_stalling_decoder - always_comb begin: instruction_decoder - clk_dec_en = 1'b0; - cfg_reg_d = cfg_reg_q; - sync = 1'b0; - - if (xif_issue_if_i.issue_valid) begin - case (opcode) - FSYNC_OPCODE: begin - clk_dec_en = 1'b1; - if ((func3 == FSYNC_FUNC3) && (xif_issue_if_i.issue_req.rs_valid)) begin - cfg_reg_d[magia_tile_pkg::FSYNC_AGGR_IDX] = xif_issue_if_i.issue_req.rs[0]; - cfg_reg_d[magia_tile_pkg::FSYNC_ID_IDX] = xif_issue_if_i.issue_req.rs[1]; - sync = 1'b1; - end - end - endcase - end - end - end else begin: gen_non_stalling_decoder - always_comb begin: instruction_decoder - clk_dec_en = 1'b0; - cfg_reg_d = cfg_reg_q; - sync = 1'b0; - xif_issue_if_i.issue_ready = 1'b0; - xif_issue_if_i.issue_resp = '0; - - if (xif_issue_if_i.issue_valid) begin - case (opcode) - FSYNC_OPCODE: begin - xif_issue_if_i.issue_ready = 1'b1; - xif_issue_if_i.issue_resp.accept = 1'b1; - clk_dec_en = 1'b1; - if ((func3 == FSYNC_FUNC3) && (xif_issue_if_i.issue_req.rs_valid)) begin - cfg_reg_d[magia_tile_pkg::FSYNC_AGGR_IDX] = xif_issue_if_i.issue_req.rs[0]; - cfg_reg_d[magia_tile_pkg::FSYNC_ID_IDX] = xif_issue_if_i.issue_req.rs[1]; - sync = 1'b1; - end - end - endcase - end - end - end endgenerate - - always_ff @(posedge clk_dec_g, negedge rst_ni) begin: configuration_register - if (~rst_ni) cfg_reg_q <= '0; - else begin - if (clear_i) cfg_reg_q <= '0; - else cfg_reg_q <= cfg_reg_d; - end - end - -/*******************************************************/ -/** Decoder FSM End **/ -/*******************************************************/ -/** Synchronization FSM Beginning **/ -/*******************************************************/ - - generate if (STALL) begin: gen_stalling_sync - always_comb begin: sync_logic - n_sync_state = c_sync_state; - clk_sync_en = 1'b1; - done = 1'b0; - ht_fsync_if_o.sync = 1'b0; - ht_fsync_if_o.aggr = '0; - ht_fsync_if_o.id_req = '0; - hn_fsync_if_o.sync = 1'b0; - hn_fsync_if_o.aggr = '0; - hn_fsync_if_o.id_req = '0; - vt_fsync_if_o.sync = 1'b0; - vt_fsync_if_o.aggr = '0; - vt_fsync_if_o.id_req = '0; - vn_fsync_if_o.sync = 1'b0; - vn_fsync_if_o.aggr = '0; - vn_fsync_if_o.id_req = '0; - xif_issue_if_i.issue_ready = 1'b0; - xif_issue_if_i.issue_resp = '0; - - case (c_sync_state) - IDLE: if (sync) n_sync_state = SYNC; else clk_sync_en = 1'b0; - SYNC: begin - n_sync_state = WAIT; - if (cfg_reg_q[magia_tile_pkg::FSYNC_AGGR_IDX] != 1) begin // Tree (level > 1) request - case (cfg_reg_q[magia_tile_pkg::FSYNC_ID_IDX][0]) - 1'b0: begin // Horizontal tree node request - ht_fsync_if_o.sync = 1'b1; - ht_fsync_if_o.aggr = cfg_reg_q[magia_tile_pkg::FSYNC_AGGR_IDX][AGGR_W-1:0]; - ht_fsync_if_o.id_req = cfg_reg_q[magia_tile_pkg::FSYNC_ID_IDX][ ID_W-1:0]; - end - 1'b1: begin // Vertical tree node request - vt_fsync_if_o.sync = 1'b1; - vt_fsync_if_o.aggr = cfg_reg_q[magia_tile_pkg::FSYNC_AGGR_IDX][AGGR_W-1:0]; - vt_fsync_if_o.id_req = cfg_reg_q[magia_tile_pkg::FSYNC_ID_IDX][ ID_W-1:0]; - end - endcase - end else begin // Neighbor (level = 1) request - case (cfg_reg_q[magia_tile_pkg::FSYNC_ID_IDX][1:0]) - 2'b00: begin // Horizontal tree node request - ht_fsync_if_o.sync = 1'b1; - ht_fsync_if_o.aggr = cfg_reg_q[magia_tile_pkg::FSYNC_AGGR_IDX][AGGR_W-1:0]; - ht_fsync_if_o.id_req = cfg_reg_q[magia_tile_pkg::FSYNC_ID_IDX][ ID_W-1:0]; - end - 2'b01: begin // Vertical tree node request - vt_fsync_if_o.sync = 1'b1; - vt_fsync_if_o.aggr = cfg_reg_q[magia_tile_pkg::FSYNC_AGGR_IDX][AGGR_W-1:0]; - vt_fsync_if_o.id_req = cfg_reg_q[magia_tile_pkg::FSYNC_ID_IDX][ ID_W-1:0]; - end - 2'b10: begin // Horizontal neighbor node request - hn_fsync_if_o.sync = 1'b1; - hn_fsync_if_o.aggr = cfg_reg_q[magia_tile_pkg::FSYNC_AGGR_IDX][NBR_AGGR_W-1:0]; - hn_fsync_if_o.id_req = cfg_reg_q[magia_tile_pkg::FSYNC_ID_IDX][ NBR_ID_W-1:0]; - end - 2'b11: begin // Vertical neighbor node request - vn_fsync_if_o.sync = 1'b1; - vn_fsync_if_o.aggr = cfg_reg_q[magia_tile_pkg::FSYNC_AGGR_IDX][NBR_AGGR_W-1:0]; - vn_fsync_if_o.id_req = cfg_reg_q[magia_tile_pkg::FSYNC_ID_IDX][ NBR_ID_W-1:0]; - end - endcase - end - end - WAIT: begin - n_sync_state = (ht_fsync_if_o.wake | hn_fsync_if_o.wake | vt_fsync_if_o.wake | vn_fsync_if_o.wake) ? DONE : WAIT; - end - DONE: begin - n_sync_state = IDLE; - done = 1'b1; - xif_issue_if_i.issue_ready = 1'b1; - xif_issue_if_i.issue_resp.accept = 1'b1; - end - endcase - end - end else begin: gen_non_stalling_sync - always_comb begin: sync_logic - n_sync_state = c_sync_state; - clk_sync_en = 1'b1; - done = 1'b0; - ht_fsync_if_o.sync = 1'b0; - ht_fsync_if_o.aggr = '0; - ht_fsync_if_o.id_req = '0; - hn_fsync_if_o.sync = 1'b0; - hn_fsync_if_o.aggr = '0; - hn_fsync_if_o.id_req = '0; - vt_fsync_if_o.sync = 1'b0; - vt_fsync_if_o.aggr = '0; - vt_fsync_if_o.id_req = '0; - vn_fsync_if_o.sync = 1'b0; - vn_fsync_if_o.aggr = '0; - vn_fsync_if_o.id_req = '0; - - case (c_sync_state) - IDLE: if (sync) n_sync_state = SYNC; else clk_sync_en = 1'b0; - SYNC: begin - n_sync_state = WAIT; - if (cfg_reg_q[magia_tile_pkg::FSYNC_AGGR_IDX] != 1) begin // Tree (level > 1) request - case (cfg_reg_q[magia_tile_pkg::FSYNC_ID_IDX][0]) - 1'b0: begin // Horizontal tree node request - ht_fsync_if_o.sync = 1'b1; - ht_fsync_if_o.aggr = cfg_reg_q[magia_tile_pkg::FSYNC_AGGR_IDX][AGGR_W-1:0]; - ht_fsync_if_o.id_req = cfg_reg_q[magia_tile_pkg::FSYNC_ID_IDX][ ID_W-1:0]; - end - 1'b1: begin // Vertical tree node request - vt_fsync_if_o.sync = 1'b1; - vt_fsync_if_o.aggr = cfg_reg_q[magia_tile_pkg::FSYNC_AGGR_IDX][AGGR_W-1:0]; - vt_fsync_if_o.id_req = cfg_reg_q[magia_tile_pkg::FSYNC_ID_IDX][ ID_W-1:0]; - end - endcase - end else begin // Neighbor (level = 1) request - case (cfg_reg_q[magia_tile_pkg::FSYNC_ID_IDX][1:0]) - 2'b00: begin // Horizontal tree node request - ht_fsync_if_o.sync = 1'b1; - ht_fsync_if_o.aggr = cfg_reg_q[magia_tile_pkg::FSYNC_AGGR_IDX][AGGR_W-1:0]; - ht_fsync_if_o.id_req = cfg_reg_q[magia_tile_pkg::FSYNC_ID_IDX][ ID_W-1:0]; - end - 2'b01: begin // Vertical tree node request - vt_fsync_if_o.sync = 1'b1; - vt_fsync_if_o.aggr = cfg_reg_q[magia_tile_pkg::FSYNC_AGGR_IDX][AGGR_W-1:0]; - vt_fsync_if_o.id_req = cfg_reg_q[magia_tile_pkg::FSYNC_ID_IDX][ ID_W-1:0]; - end - 2'b10: begin // Horizontal neighbor node request - hn_fsync_if_o.sync = 1'b1; - hn_fsync_if_o.aggr = cfg_reg_q[magia_tile_pkg::FSYNC_AGGR_IDX][NBR_AGGR_W-1:0]; - hn_fsync_if_o.id_req = cfg_reg_q[magia_tile_pkg::FSYNC_ID_IDX][ NBR_ID_W-1:0]; - end - 2'b11: begin // Vertical neighbor node request - vn_fsync_if_o.sync = 1'b1; - vn_fsync_if_o.aggr = cfg_reg_q[magia_tile_pkg::FSYNC_AGGR_IDX][NBR_AGGR_W-1:0]; - vn_fsync_if_o.id_req = cfg_reg_q[magia_tile_pkg::FSYNC_ID_IDX][ NBR_ID_W-1:0]; - end - endcase - end - end - WAIT: begin - n_sync_state = (ht_fsync_if_o.wake | hn_fsync_if_o.wake | vt_fsync_if_o.wake | vn_fsync_if_o.wake) ? DONE : WAIT; - end - DONE: begin - n_sync_state = IDLE; - done = 1'b1; - end - endcase - end - end endgenerate - - always_ff @(posedge clk_sync_g, negedge rst_ni) begin: sync_state - if (~rst_ni) c_sync_state <= IDLE; - else begin - if (clear_i) c_sync_state <= IDLE; - else c_sync_state <= n_sync_state; - end - end - -/*******************************************************/ -/** Synchronization FSM End **/ -/*******************************************************/ - -endmodule: fractal_sync_xif_inst_decoder \ No newline at end of file diff --git a/hw/tile/idma_ctrl.sv b/hw/tile/idma_ctrl.sv deleted file mode 100644 index 58e2e3c2..00000000 --- a/hw/tile/idma_ctrl.sv +++ /dev/null @@ -1,292 +0,0 @@ -/* - * Copyright (C) 2023-2024 ETH Zurich and University of Bologna - * - * Licensed under the Solderpad Hardware License, Version 0.51 - * (the "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * SPDX-License-Identifier: SHL-0.51 - * - * Authors: Victor Isachi - * - * iDMA Controller - */ - -module idma_ctrl - import magia_tile_pkg::*; - import cv32e40x_pkg::*; - import idma_pkg::*; -#( - parameter idma_pkg::error_cap_e ERROR_CAP = idma_pkg::NO_ERROR_HANDLING, - localparam int unsigned DIRECTION_W = magia_tile_pkg::DMA_DIRECTION_W, - localparam int unsigned DIRECTION_OFF = magia_tile_pkg::DMA_DIRECTION_OFF, - localparam type idma_fe_reg_req_t = magia_tile_pkg::idma_fe_reg_req_t, - localparam type idma_fe_reg_rsp_t = magia_tile_pkg::idma_fe_reg_rsp_t, - parameter type axi_req_t = magia_tile_pkg::idma_axi_req_t, - parameter type axi_rsp_t = magia_tile_pkg::idma_axi_rsp_t, - parameter type obi_req_t = magia_tile_pkg::idma_obi_req_t, - parameter type obi_rsp_t = magia_tile_pkg::idma_obi_rsp_t -)( - input logic clk_i, - input logic rst_ni, - input logic testmode_i, - input logic clear_i, - - cv32e40x_if_xif.coproc_issue xif_issue_if_i, - - output axi_req_t axi_read_req_o, - input axi_rsp_t axi_read_rsp_i, - - output axi_req_t axi_write_req_o, - input axi_rsp_t axi_write_rsp_i, - - output obi_req_t obi_read_req_o, - input obi_rsp_t obi_read_rsp_i, - - output obi_req_t obi_write_req_o, - input obi_rsp_t obi_write_rsp_i, - - output logic axi2obi_start_o, // Started L2 to L1 iDMA transfer - output logic axi2obi_busy_o, // Performing L2 to L1 iDMA transfer - output logic axi2obi_done_o, // Finished L2 to L1 iDMA transfer - output logic axi2obi_error_o, // Detected L2 to L1 transfer error - - output logic obi2axi_start_o, // Started L1 to L2 iDMA transfer - output logic obi2axi_busy_o, // Performing L1 to L2 iDMA transfer - output logic obi2axi_done_o, // Finished L1 to L2 iDMA transfer - output logic obi2axi_error_o // Detected L1 to L2 transfer error -); - -/*******************************************************/ -/** Internal Signal Definitions Beginning **/ -/*******************************************************/ - - logic direction; // Direction of the iDMA transfer: 0 -> AXI2OBI; 1 -> OBI2AXI - - idma_fe_reg_req_t idma_fe_reg_axi2obi_req; - idma_fe_reg_rsp_t idma_fe_reg_axi2obi_rsp; - idma_fe_reg_req_t idma_fe_reg_obi2axi_req; - idma_fe_reg_rsp_t idma_fe_reg_obi2axi_rsp; - -/*******************************************************/ -/** Internal Signal Definitions End **/ -/*******************************************************/ -/** Interface Definitions Beginning **/ -/*******************************************************/ - - cv32e40x_if_xif #( - .X_NUM_RS ( magia_tile_pkg::X_NUM_RS ), - .X_ID_WIDTH ( magia_tile_pkg::X_ID_W ), - .X_MEM_WIDTH ( magia_tile_pkg::X_MEM_W ), - .X_RFR_WIDTH ( magia_tile_pkg::X_RFR_W ), - .X_RFW_WIDTH ( magia_tile_pkg::X_RFW_W ), - .X_MISA ( magia_tile_pkg::X_MISA ), - .X_ECS_XS ( magia_tile_pkg::X_ECS_XS ) - ) xif_axi2obi_issue_if (); - - cv32e40x_if_xif #( - .X_NUM_RS ( magia_tile_pkg::X_NUM_RS ), - .X_ID_WIDTH ( magia_tile_pkg::X_ID_W ), - .X_MEM_WIDTH ( magia_tile_pkg::X_MEM_W ), - .X_RFR_WIDTH ( magia_tile_pkg::X_RFR_W ), - .X_RFW_WIDTH ( magia_tile_pkg::X_RFW_W ), - .X_MISA ( magia_tile_pkg::X_MISA ), - .X_ECS_XS ( magia_tile_pkg::X_ECS_XS ) - ) xif_obi2axi_issue_if (); - -/*******************************************************/ -/** Interface Definitions End **/ -/*******************************************************/ -/** Hardwired Signals Beginning **/ -/*******************************************************/ - - assign direction = xif_issue_if_i.issue_req.instr[DIRECTION_OFF+:DIRECTION_W]; - -/*******************************************************/ -/** Hardwired Signals End **/ -/*******************************************************/ -/** Xif Issue DEMUX Beginning **/ -/*******************************************************/ - - always_comb begin: xif_issue_demux - if (direction) begin // OBI2AXI - xif_obi2axi_issue_if.issue_valid = xif_issue_if_i.issue_valid; - xif_obi2axi_issue_if.issue_req = xif_issue_if_i.issue_req; - xif_issue_if_i.issue_ready = xif_obi2axi_issue_if.issue_ready; - xif_issue_if_i.issue_resp = xif_obi2axi_issue_if.issue_resp; - - xif_axi2obi_issue_if.issue_valid = 1'b0; - xif_axi2obi_issue_if.issue_req = '0; - end else begin // AXI2OBI - xif_axi2obi_issue_if.issue_valid = xif_issue_if_i.issue_valid; - xif_axi2obi_issue_if.issue_req = xif_issue_if_i.issue_req; - xif_issue_if_i.issue_ready = xif_axi2obi_issue_if.issue_ready; - xif_issue_if_i.issue_resp = xif_axi2obi_issue_if.issue_resp; - - xif_obi2axi_issue_if.issue_valid = 1'b0; - xif_obi2axi_issue_if.issue_req = '0; - end - end - -/*******************************************************/ -/** Xif Issue DEMUX End **/ -/*******************************************************/ -/** AXI2OBI Xif Instruction Decoder Beginning **/ -/*******************************************************/ - - idma_xif_inst_decoder #( - .INSTR_W ( magia_tile_pkg::DMA_INSTR_W ), - .DATA_W ( magia_tile_pkg::DMA_DATA_W ), - .N_RF_PORTS ( magia_tile_pkg::DMA_N_RF_PORTS ), - .OPCODE_W ( magia_tile_pkg::DMA_OPCODE_W ), - .FUNC3_W ( magia_tile_pkg::DMA_FUNC3_W ), - .ND_EN_W ( magia_tile_pkg::DMA_ND_EN_W ), - .DST_MAX_LOG_LEN_W ( magia_tile_pkg::DMA_DST_MAX_LOG_LEN_W ), - .SRC_MAX_LOG_LEN_W ( magia_tile_pkg::DMA_SRC_MAX_LOG_LEN_W ), - .DST_REDUCE_LEN_W ( magia_tile_pkg::DMA_DST_REDUCE_LEN_W ), - .SRC_REDUCE_LEN_W ( magia_tile_pkg::DMA_SRC_REDUCE_LEN_W ), - .DECOUPLE_R_W_W ( magia_tile_pkg::DMA_DECOUPLE_R_W_W ), - .DECOUPLE_R_AW_W ( magia_tile_pkg::DMA_DECOUPLE_R_AW_W ), - .OPCODE_OFF ( magia_tile_pkg::DMA_OPCODE_OFF ), - .FUNC3_OFF ( magia_tile_pkg::DMA_FUNC3_OFF ), - .ND_EN_OFF ( magia_tile_pkg::DMA_ND_EN_OFF ), - .DST_MAX_LOG_LEN_OFF ( magia_tile_pkg::DMA_DST_MAX_LOG_LEN_OFF ), - .SRC_MAX_LOG_LEN_OFF ( magia_tile_pkg::DMA_SRC_MAX_LOG_LEN_OFF ), - .DST_REDUCE_LEN_OFF ( magia_tile_pkg::DMA_DST_REDUCE_LEN_OFF ), - .SRC_REDUCE_LEN_OFF ( magia_tile_pkg::DMA_SRC_REDUCE_LEN_OFF ), - .DECOUPLE_R_W_OFF ( magia_tile_pkg::DMA_DECOUPLE_R_W_OFF ), - .DECOUPLE_R_AW_OFF ( magia_tile_pkg::DMA_DECOUPLE_R_AW_OFF ), - .N_CFG_REG ( magia_tile_pkg::DMA_N_CFG_REG ), - .idma_fe_req_t ( idma_fe_reg_req_t ), - .idma_fe_rsp_t ( idma_fe_reg_rsp_t ) - ) i_idma_axi2obi_inst_decoder ( - .clk_i , - .rst_ni , - .clear_i , - - .xif_issue_if_i ( xif_axi2obi_issue_if.coproc_issue ), - - .cfg_req_o ( idma_fe_reg_axi2obi_req ), - .cfg_rsp_i ( idma_fe_reg_axi2obi_rsp ), - - .start_o ( axi2obi_start_o ), - .busy_o ( axi2obi_busy_o ), - .done_o ( axi2obi_done_o ), - .error_o ( axi2obi_error_o ) - ); - -/*******************************************************/ -/** AXI2OBI Xif Instruction Decoder End **/ -/*******************************************************/ -/** OBI2AXI Xif Instruction Decoder Beginning **/ -/*******************************************************/ - - idma_xif_inst_decoder #( - .INSTR_W ( magia_tile_pkg::DMA_INSTR_W ), - .DATA_W ( magia_tile_pkg::DMA_DATA_W ), - .N_RF_PORTS ( magia_tile_pkg::DMA_N_RF_PORTS ), - .OPCODE_W ( magia_tile_pkg::DMA_OPCODE_W ), - .FUNC3_W ( magia_tile_pkg::DMA_FUNC3_W ), - .ND_EN_W ( magia_tile_pkg::DMA_ND_EN_W ), - .DST_MAX_LOG_LEN_W ( magia_tile_pkg::DMA_DST_MAX_LOG_LEN_W ), - .SRC_MAX_LOG_LEN_W ( magia_tile_pkg::DMA_SRC_MAX_LOG_LEN_W ), - .DST_REDUCE_LEN_W ( magia_tile_pkg::DMA_DST_REDUCE_LEN_W ), - .SRC_REDUCE_LEN_W ( magia_tile_pkg::DMA_SRC_REDUCE_LEN_W ), - .DECOUPLE_R_W_W ( magia_tile_pkg::DMA_DECOUPLE_R_W_W ), - .DECOUPLE_R_AW_W ( magia_tile_pkg::DMA_DECOUPLE_R_AW_W ), - .OPCODE_OFF ( magia_tile_pkg::DMA_OPCODE_OFF ), - .FUNC3_OFF ( magia_tile_pkg::DMA_FUNC3_OFF ), - .ND_EN_OFF ( magia_tile_pkg::DMA_ND_EN_OFF ), - .DST_MAX_LOG_LEN_OFF ( magia_tile_pkg::DMA_DST_MAX_LOG_LEN_OFF ), - .SRC_MAX_LOG_LEN_OFF ( magia_tile_pkg::DMA_SRC_MAX_LOG_LEN_OFF ), - .DST_REDUCE_LEN_OFF ( magia_tile_pkg::DMA_DST_REDUCE_LEN_OFF ), - .SRC_REDUCE_LEN_OFF ( magia_tile_pkg::DMA_SRC_REDUCE_LEN_OFF ), - .DECOUPLE_R_W_OFF ( magia_tile_pkg::DMA_DECOUPLE_R_W_OFF ), - .DECOUPLE_R_AW_OFF ( magia_tile_pkg::DMA_DECOUPLE_R_AW_OFF ), - .N_CFG_REG ( magia_tile_pkg::DMA_N_CFG_REG ), - .idma_fe_req_t ( idma_fe_reg_req_t ), - .idma_fe_rsp_t ( idma_fe_reg_rsp_t ) - ) i_idma_obi2axi_inst_decoder ( - .clk_i , - .rst_ni , - .clear_i , - - .xif_issue_if_i ( xif_obi2axi_issue_if.coproc_issue ), - - .cfg_req_o ( idma_fe_reg_obi2axi_req ), - .cfg_rsp_i ( idma_fe_reg_obi2axi_rsp ), - - .start_o ( obi2axi_start_o ), - .busy_o ( obi2axi_busy_o ), - .done_o ( obi2axi_done_o ), - .error_o ( obi2axi_error_o ) - ); - -/*******************************************************/ -/** OBI2AXI Xif Instruction Decoder End **/ -/*******************************************************/ -/** AXI2OBI (L2 to L1) Transfer Channel Beginning **/ -/*******************************************************/ - - idma_axi_obi_transfer_ch #( - .CHANNEL_T ( magia_tile_pkg::AXI2OBI ), - .ERROR_CAP ( ERROR_CAP ), - .idma_fe_reg_req_t ( idma_fe_reg_req_t ), - .idma_fe_reg_rsp_t ( idma_fe_reg_rsp_t ), - .axi_req_t ( axi_req_t ), - .axi_rsp_t ( axi_rsp_t ), - .obi_req_t ( obi_req_t ), - .obi_rsp_t ( obi_rsp_t ) - ) i_l2_to_l1_ch ( - .clk_i , - .rst_ni , - .testmode_i , - .clear_i , - .cfg_req_i ( idma_fe_reg_axi2obi_req ), - .cfg_rsp_o ( idma_fe_reg_axi2obi_rsp ), - .axi_req_o ( axi_read_req_o ), - .axi_rsp_i ( axi_read_rsp_i ), - .obi_req_o ( obi_write_req_o ), - .obi_rsp_i ( obi_write_rsp_i ) - ); - -/*******************************************************/ -/** AXI2OBI (L2 to L1) Transfer Channel End **/ -/*******************************************************/ -/** OBI2AXI (L1 to L2) Transfer Channel Beginning **/ -/*******************************************************/ - - idma_axi_obi_transfer_ch #( - .CHANNEL_T ( magia_tile_pkg::OBI2AXI ), - .ERROR_CAP ( ERROR_CAP ), - .idma_fe_reg_req_t ( idma_fe_reg_req_t ), - .idma_fe_reg_rsp_t ( idma_fe_reg_rsp_t ), - .axi_req_t ( axi_req_t ), - .axi_rsp_t ( axi_rsp_t ), - .obi_req_t ( obi_req_t ), - .obi_rsp_t ( obi_rsp_t ) - ) i_l1_to_l2_ch ( - .clk_i , - .rst_ni , - .testmode_i , - .clear_i , - .cfg_req_i ( idma_fe_reg_obi2axi_req ), - .cfg_rsp_o ( idma_fe_reg_obi2axi_rsp ), - .axi_req_o ( axi_write_req_o ), - .axi_rsp_i ( axi_write_rsp_i ), - .obi_req_o ( obi_read_req_o ), - .obi_rsp_i ( obi_read_rsp_i ) - ); - -/*******************************************************/ -/** OBI2AXI (L1 to L2) Transfer Channel End **/ -/*******************************************************/ - -endmodule: idma_ctrl \ No newline at end of file diff --git a/hw/tile/idma_xif_inst_decoder.sv b/hw/tile/idma_xif_inst_decoder.sv deleted file mode 100644 index d37cf580..00000000 --- a/hw/tile/idma_xif_inst_decoder.sv +++ /dev/null @@ -1,445 +0,0 @@ -/* - * Copyright (C) 2023-2024 ETH Zurich and University of Bologna - * - * Licensed under the Solderpad Hardware License, Version 0.51 - * (the "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * SPDX-License-Identifier: SHL-0.51 - * - * Authors: Victor Isachi - * - * iDMA Xif Instruction Decoder - */ - -module idma_xif_inst_decoder - import magia_tile_pkg::*; - import cv32e40x_pkg::*; - import idma_pkg::*; -#( - parameter int unsigned INSTR_W = magia_tile_pkg::DMA_INSTR_W, - parameter int unsigned DATA_W = magia_tile_pkg::DMA_DATA_W, - parameter int unsigned ADDR_W = magia_tile_pkg::DMA_ADDR_W, - parameter int unsigned N_RF_PORTS = magia_tile_pkg::DMA_N_RF_PORTS, - parameter int unsigned OPCODE_W = magia_tile_pkg::DMA_OPCODE_W, - parameter int unsigned FUNC3_W = magia_tile_pkg::DMA_FUNC3_W, - parameter int unsigned ND_EN_W = magia_tile_pkg::DMA_ND_EN_W, - parameter int unsigned DST_MAX_LOG_LEN_W = magia_tile_pkg::DMA_DST_MAX_LOG_LEN_W, - parameter int unsigned SRC_MAX_LOG_LEN_W = magia_tile_pkg::DMA_SRC_MAX_LOG_LEN_W, - parameter int unsigned DST_REDUCE_LEN_W = magia_tile_pkg::DMA_DST_REDUCE_LEN_W, - parameter int unsigned SRC_REDUCE_LEN_W = magia_tile_pkg::DMA_SRC_REDUCE_LEN_W, - parameter int unsigned DECOUPLE_R_W_W = magia_tile_pkg::DMA_DECOUPLE_R_W_W, - parameter int unsigned DECOUPLE_R_AW_W = magia_tile_pkg::DMA_DECOUPLE_R_AW_W, - localparam int unsigned CONF_W = ND_EN_W + - DST_MAX_LOG_LEN_W + - SRC_MAX_LOG_LEN_W + - DST_REDUCE_LEN_W + - SRC_REDUCE_LEN_W + - DECOUPLE_R_W_W + - DECOUPLE_R_AW_W, - parameter int unsigned OPCODE_OFF = magia_tile_pkg::DMA_OPCODE_OFF, - parameter int unsigned FUNC3_OFF = magia_tile_pkg::DMA_FUNC3_OFF, - parameter int unsigned ND_EN_OFF = magia_tile_pkg::DMA_ND_EN_OFF, - parameter int unsigned DST_MAX_LOG_LEN_OFF = magia_tile_pkg::DMA_DST_MAX_LOG_LEN_OFF, - parameter int unsigned SRC_MAX_LOG_LEN_OFF = magia_tile_pkg::DMA_SRC_MAX_LOG_LEN_OFF, - parameter int unsigned DST_REDUCE_LEN_OFF = magia_tile_pkg::DMA_DST_REDUCE_LEN_OFF, - parameter int unsigned SRC_REDUCE_LEN_OFF = magia_tile_pkg::DMA_SRC_REDUCE_LEN_OFF, - parameter int unsigned DECOUPLE_R_W_OFF = magia_tile_pkg::DMA_DECOUPLE_R_W_OFF, - parameter int unsigned DECOUPLE_R_AW_OFF = magia_tile_pkg::DMA_DECOUPLE_R_AW_OFF, - parameter int unsigned N_CFG_REG = magia_tile_pkg::DMA_N_CFG_REG, - parameter type idma_fe_req_t = magia_tile_pkg::idma_fe_reg_req_t, - parameter type idma_fe_rsp_t = magia_tile_pkg::idma_fe_reg_rsp_t -)( - input logic clk_i, - input logic rst_ni, - input logic clear_i, - - cv32e40x_if_xif.coproc_issue xif_issue_if_i, - - output idma_fe_req_t cfg_req_o, - input idma_fe_rsp_t cfg_rsp_i, - - output logic start_o, // Started iDMA transfer - output logic busy_o, // Performing iDMA transfer - output logic done_o, // Finished iDMA transfer - output logic error_o // Detected error -); - -/*******************************************************/ -/** Internal Signal Definitions Beginning **/ -/*******************************************************/ - - logic dec_clk_req; - logic cfg_clk_req; - logic clk_dc_en, clk_tfr_en; - logic clk_dc_g, clk_tfr_g; - - logic[ OPCODE_W-1:0] opcode; - logic[ FUNC3_W-1:0] func3; - logic[ ND_EN_W-1:0] nd_en; - logic[DST_MAX_LOG_LEN_W-1:0] dst_max_log_len; - logic[SRC_MAX_LOG_LEN_W-1:0] src_max_log_len; - logic[ DST_REDUCE_LEN_W-1:0] dst_reduce_len; - logic[ SRC_REDUCE_LEN_W-1:0] src_reduce_len; - logic[ DECOUPLE_R_W_W-1:0] decouple_r_w; - logic[ DECOUPLE_R_AW_W-1:0] decouple_r_aw; - - logic[N_CFG_REG-1:0][DATA_W-1:0] cfg_reg_d, cfg_reg_q; - logic[N_CFG_REG-1:0] cfg_reg_update_d, cfg_reg_update_q; - logic[N_CFG_REG-1:0] cfg_reg_update_clr; - - idma_fe_req_t cfg_configurer_req; - idma_fe_rsp_t cfg_configurer_rsp; - idma_fe_req_t cfg_transferer_req; - idma_fe_rsp_t cfg_transferer_rsp; - - logic free_cfg; - logic free_tfr; - - logic start_transfer; - - logic start_dma; - logic busy_dma; - logic done_dma; - - logic transfer_not_set_properly; - logic reg_error_cfg, reg_error_tfr; - - logic rw_valid_cfg, rw_valid_tfr; - - logic[DATA_W-1:0] next_id_d, next_id_q; - logic[DATA_W-1:0] done_id; - - typedef enum logic[1:0] { - IDLE, - START, - BUSY, - DONE - } idma_state_e; - - idma_state_e c_idma_state, n_idma_state; - -/*******************************************************/ -/** Internal Signal Definitions End **/ -/*******************************************************/ -/** Function Definitions Beginning **/ -/*******************************************************/ - - /* Function that writes the data argument to the addr argument of the iDMA FE register - * OUTPUT: - * req - iDMA FE register request channel - * reg_error - indicates that the req/rsp of the iDMA FE asserted the error signal - * INPUT: - * rsp - iDMA FE register response channel - * addr - iDMA FE register address - * data - iDMA FE register data - * RETURN: - * 1'b1 if the write was acknowledged, 1'b0 otherwise - */ - function automatic logic write_idma_reg(output idma_fe_req_t req, input idma_fe_rsp_t rsp, - input logic[ADDR_W-1:0] addr, input logic[DATA_W-1:0] data, - output logic reg_error); - req.addr = addr; - req.write = 1'b1; - req.wdata = data; - req.wstrb = '1; - req.valid = 1'b1; - - reg_error = rsp.error ? 1'b1 : 1'b0; - write_idma_reg = cfg_rsp_i.ready ? 1'b1 : 1'b0; - endfunction: write_idma_reg - - /* - * Function that reads the data argument of the iDMA FE register - * OUTPUT: - * req - iDMA FE register request channel - * reg_error - indicates that the req/rsp of the iDMA FE asserted the error signal - * data - iDMA FE register read data - * INPUT: - * rsp - iDMA FE register response channel - * addr - iDMA FE register address - * RETURN: - * 1'b1 if the read data is valid, 1'b0 otherwise - */ - function automatic logic read_idma_reg(output idma_fe_req_t req, input idma_fe_rsp_t rsp, - input logic[ADDR_W-1:0] addr, output logic[DATA_W-1:0] data, - output logic reg_error); - req.addr = addr; - req.write = 1'b0; - req.wdata = '0; - req.wstrb = '0; - req.valid = 1'b1; - - data = cfg_rsp_i.rdata; - - reg_error = rsp.error ? 1'b1 : 1'b0; - read_idma_reg = cfg_rsp_i.ready ? 1'b1 : 1'b0; - endfunction: read_idma_reg - -/*******************************************************/ -/** Function Definitions End **/ -/*******************************************************/ -/** Hardwired Signals Beginning **/ -/*******************************************************/ - - assign clk_dc_en = dec_clk_req | cfg_clk_req; - - assign opcode = xif_issue_if_i.issue_req.instr[ OPCODE_OFF+: OPCODE_W]; - assign func3 = xif_issue_if_i.issue_req.instr[ FUNC3_OFF+: FUNC3_W]; - assign nd_en = xif_issue_if_i.issue_req.instr[ ND_EN_OFF+: ND_EN_W]; - assign dst_max_log_len = xif_issue_if_i.issue_req.instr[DST_MAX_LOG_LEN_OFF+:DST_MAX_LOG_LEN_W]; - assign src_max_log_len = xif_issue_if_i.issue_req.instr[SRC_MAX_LOG_LEN_OFF+:SRC_MAX_LOG_LEN_W]; - assign dst_reduce_len = xif_issue_if_i.issue_req.instr[ DST_REDUCE_LEN_OFF+: DST_REDUCE_LEN_W]; - assign src_reduce_len = xif_issue_if_i.issue_req.instr[ SRC_REDUCE_LEN_OFF+: SRC_REDUCE_LEN_W]; - assign decouple_r_w = xif_issue_if_i.issue_req.instr[ DECOUPLE_R_W_OFF+: DECOUPLE_R_W_W]; - assign decouple_r_aw = xif_issue_if_i.issue_req.instr[ DECOUPLE_R_AW_OFF+: DECOUPLE_R_AW_W]; - - assign free_cfg = ~(|cfg_reg_update_q); - assign free_tfr = ~(start_dma | busy_dma); - - assign cfg_req_o = ~free_tfr ? cfg_transferer_req : - ~free_cfg ? cfg_configurer_req : '0; - assign cfg_transferer_rsp = ~free_tfr ? cfg_rsp_i : '0; - assign cfg_configurer_rsp = ~free_tfr ? '0 : - ~free_cfg ? cfg_rsp_i : '0; - - assign error_o = transfer_not_set_properly | reg_error_cfg | reg_error_tfr; - - assign start_o = start_dma; - assign busy_o = busy_dma; - assign done_o = done_dma; - -/*******************************************************/ -/** Hardwired Signals End **/ -/*******************************************************/ -/** Clock gating Beginning **/ -/*******************************************************/ - - tc_clk_gating dc_clock_gating ( - .clk_i , - .en_i ( clk_dc_en ), - .test_en_i ( '0 ), - .clk_o ( clk_dc_g ) - ); - - tc_clk_gating tfr_clock_gating ( - .clk_i , - .en_i ( clk_tfr_en ), - .test_en_i ( '0 ), - .clk_o ( clk_tfr_g ) - ); - -/*******************************************************/ -/** Clock gating End **/ -/*******************************************************/ -/** Decoder FSM Beginning **/ -/*******************************************************/ - - always_comb begin: instr_decoder - dec_clk_req = 1'b0; - start_transfer = 1'b0; - cfg_reg_d = cfg_reg_q; - cfg_reg_update_d = cfg_reg_update_q; - xif_issue_if_i.issue_ready = 1'b0; - xif_issue_if_i.issue_resp = '0; - - if (xif_issue_if_i.issue_valid) begin - case (opcode) - CONF_OPCODE: if (func3 == CONF_FUNC3) begin - xif_issue_if_i.issue_ready = 1'b1; - xif_issue_if_i.issue_resp.accept = 1'b1; - dec_clk_req = 1'b1; - cfg_reg_d [magia_tile_pkg::DMA_CONF_IDX] = {nd_en, dst_max_log_len, src_max_log_len, dst_reduce_len, src_reduce_len, decouple_r_w, decouple_r_aw}; - cfg_reg_update_d[magia_tile_pkg::DMA_CONF_IDX] = 1'b1; - end - SET_OPCODE: begin - xif_issue_if_i.issue_ready = 1'b1; - xif_issue_if_i.issue_resp.accept = 1'b1; - dec_clk_req = 1'b1; - case (func3) - SET_AL_FUNC3: if (xif_issue_if_i.issue_req.rs_valid) begin - cfg_reg_d [magia_tile_pkg::DMA_LENGTH_IDX] = xif_issue_if_i.issue_req.rs[0]; - cfg_reg_d [magia_tile_pkg::DMA_SRC_ADDR_IDX] = xif_issue_if_i.issue_req.rs[1]; - cfg_reg_d [magia_tile_pkg::DMA_DST_ADDR_IDX] = xif_issue_if_i.issue_req.rs[2]; - cfg_reg_update_d[magia_tile_pkg::DMA_LENGTH_IDX] = 1'b1; - cfg_reg_update_d[magia_tile_pkg::DMA_SRC_ADDR_IDX] = 1'b1; - cfg_reg_update_d[magia_tile_pkg::DMA_DST_ADDR_IDX] = 1'b1; - end - SET_SR2_FUNC3: if (xif_issue_if_i.issue_req.rs_valid) begin - cfg_reg_d [magia_tile_pkg::DMA_REPS_2_IDX] = xif_issue_if_i.issue_req.rs[0]; - cfg_reg_d [magia_tile_pkg::DMA_SRC_STRIDE_2_IDX] = xif_issue_if_i.issue_req.rs[1]; - cfg_reg_d [magia_tile_pkg::DMA_DST_STRIDE_2_IDX] = xif_issue_if_i.issue_req.rs[2]; - cfg_reg_update_d[magia_tile_pkg::DMA_REPS_2_IDX] = 1'b1; - cfg_reg_update_d[magia_tile_pkg::DMA_SRC_STRIDE_2_IDX] = 1'b1; - cfg_reg_update_d[magia_tile_pkg::DMA_DST_STRIDE_2_IDX] = 1'b1; - end - SET_SR3_FUNC3: if (xif_issue_if_i.issue_req.rs_valid) begin - cfg_reg_d [magia_tile_pkg::DMA_REPS_3_IDX] = xif_issue_if_i.issue_req.rs[0]; - cfg_reg_d [magia_tile_pkg::DMA_SRC_STRIDE_3_IDX] = xif_issue_if_i.issue_req.rs[1]; - cfg_reg_d [magia_tile_pkg::DMA_DST_STRIDE_3_IDX] = xif_issue_if_i.issue_req.rs[2]; - cfg_reg_update_d[magia_tile_pkg::DMA_REPS_3_IDX] = 1'b1; - cfg_reg_update_d[magia_tile_pkg::DMA_SRC_STRIDE_3_IDX] = 1'b1; - cfg_reg_update_d[magia_tile_pkg::DMA_DST_STRIDE_3_IDX] = 1'b1; - end - SET_S_FUNC3: start_transfer = 1'b1; - endcase - end - endcase - end - end - - always_ff @(posedge clk_dc_g, negedge rst_ni) begin: configuration_register - if (~rst_ni) cfg_reg_q <= '0; - else begin - if (clear_i) cfg_reg_q <= '0; - else cfg_reg_q <= cfg_reg_d; - end - end - -/*******************************************************/ -/** Decoder FSM End **/ -/*******************************************************/ -/** iDMA FE Configuration FSM Beginning **/ -/*******************************************************/ - - always_comb begin: idma_configurerer_next_state_output_logic - cfg_clk_req = 1'b0; - reg_error_cfg = 1'b0; - rw_valid_cfg = 1'b0; - cfg_reg_update_clr = '0; - cfg_configurer_req.addr = '0; - cfg_configurer_req.write = 1'b0; - cfg_configurer_req.wdata = '0; - cfg_configurer_req.wstrb = '0; - cfg_configurer_req.valid = 1'b0; - - if (free_tfr) begin - if (~free_cfg) begin - cfg_clk_req = 1'b1; - case (1'b1) - cfg_reg_update_q[magia_tile_pkg::DMA_CONF_IDX]: begin - rw_valid_cfg = write_idma_reg(.req(cfg_configurer_req), .rsp(cfg_configurer_rsp), .addr(idma_reg32_3d_reg_pkg::IDMA_REG32_3D_CONF_OFFSET), .data(cfg_reg_d[magia_tile_pkg::DMA_CONF_IDX][CONF_W-1:0]), .reg_error(reg_error_cfg)); - cfg_reg_update_clr[magia_tile_pkg::DMA_CONF_IDX] = reg_error_cfg ? 1'b0 : (rw_valid_cfg ? 1'b1 : 1'b0); - end - cfg_reg_update_q[magia_tile_pkg::DMA_DST_ADDR_IDX]: begin - rw_valid_cfg = write_idma_reg(.req(cfg_configurer_req), .rsp(cfg_configurer_rsp), .addr(idma_reg32_3d_reg_pkg::IDMA_REG32_3D_DST_ADDR_LOW_OFFSET), .data(cfg_reg_d[magia_tile_pkg::DMA_DST_ADDR_IDX]), .reg_error(reg_error_cfg)); - cfg_reg_update_clr[magia_tile_pkg::DMA_DST_ADDR_IDX] = reg_error_cfg ? 1'b0 : (rw_valid_cfg ? 1'b1 : 1'b0); - end - cfg_reg_update_q[magia_tile_pkg::DMA_SRC_ADDR_IDX]: begin - rw_valid_cfg = write_idma_reg(.req(cfg_configurer_req), .rsp(cfg_configurer_rsp), .addr(idma_reg32_3d_reg_pkg::IDMA_REG32_3D_SRC_ADDR_LOW_OFFSET), .data(cfg_reg_d[magia_tile_pkg::DMA_SRC_ADDR_IDX]), .reg_error(reg_error_cfg)); - cfg_reg_update_clr[magia_tile_pkg::DMA_SRC_ADDR_IDX] = reg_error_cfg ? 1'b0 : (rw_valid_cfg ? 1'b1 : 1'b0); - end - cfg_reg_update_q[magia_tile_pkg::DMA_LENGTH_IDX]: begin - rw_valid_cfg = write_idma_reg(.req(cfg_configurer_req), .rsp(cfg_configurer_rsp), .addr(idma_reg32_3d_reg_pkg::IDMA_REG32_3D_LENGTH_LOW_OFFSET), .data(cfg_reg_d[magia_tile_pkg::DMA_LENGTH_IDX]), .reg_error(reg_error_cfg)); - cfg_reg_update_clr[magia_tile_pkg::DMA_LENGTH_IDX] = reg_error_cfg ? 1'b0 : (rw_valid_cfg ? 1'b1 : 1'b0); - end - cfg_reg_update_q[magia_tile_pkg::DMA_DST_STRIDE_2_IDX]: begin - rw_valid_cfg = write_idma_reg(.req(cfg_configurer_req), .rsp(cfg_configurer_rsp), .addr(idma_reg32_3d_reg_pkg::IDMA_REG32_3D_DST_STRIDE_2_LOW_OFFSET), .data(cfg_reg_d[magia_tile_pkg::DMA_DST_STRIDE_2_IDX]), .reg_error(reg_error_cfg)); - cfg_reg_update_clr[magia_tile_pkg::DMA_DST_STRIDE_2_IDX] = reg_error_cfg ? 1'b0 : (rw_valid_cfg ? 1'b1 : 1'b0); - end - cfg_reg_update_q[magia_tile_pkg::DMA_SRC_STRIDE_2_IDX]: begin - rw_valid_cfg = write_idma_reg(.req(cfg_configurer_req), .rsp(cfg_configurer_rsp), .addr(idma_reg32_3d_reg_pkg::IDMA_REG32_3D_SRC_STRIDE_2_LOW_OFFSET), .data(cfg_reg_d[magia_tile_pkg::DMA_SRC_STRIDE_2_IDX]), .reg_error(reg_error_cfg)); - cfg_reg_update_clr[magia_tile_pkg::DMA_SRC_STRIDE_2_IDX] = reg_error_cfg ? 1'b0 : (rw_valid_cfg ? 1'b1 : 1'b0); - end - cfg_reg_update_q[magia_tile_pkg::DMA_REPS_2_IDX]: begin - rw_valid_cfg = write_idma_reg(.req(cfg_configurer_req), .rsp(cfg_configurer_rsp), .addr(idma_reg32_3d_reg_pkg::IDMA_REG32_3D_REPS_2_LOW_OFFSET), .data(cfg_reg_d[magia_tile_pkg::DMA_REPS_2_IDX]), .reg_error(reg_error_cfg)); - cfg_reg_update_clr[magia_tile_pkg::DMA_REPS_2_IDX] = reg_error_cfg ? 1'b0 : (rw_valid_cfg ? 1'b1 : 1'b0); - end - cfg_reg_update_q[magia_tile_pkg::DMA_DST_STRIDE_3_IDX]: begin - rw_valid_cfg = write_idma_reg(.req(cfg_configurer_req), .rsp(cfg_configurer_rsp), .addr(idma_reg32_3d_reg_pkg::IDMA_REG32_3D_DST_STRIDE_3_LOW_OFFSET), .data(cfg_reg_d[magia_tile_pkg::DMA_DST_STRIDE_3_IDX]), .reg_error(reg_error_cfg)); - cfg_reg_update_clr[magia_tile_pkg::DMA_DST_STRIDE_3_IDX] = reg_error_cfg ? 1'b0 : (rw_valid_cfg ? 1'b1 : 1'b0); - end - cfg_reg_update_q[magia_tile_pkg::DMA_SRC_STRIDE_3_IDX]: begin - rw_valid_cfg = write_idma_reg(.req(cfg_configurer_req), .rsp(cfg_configurer_rsp), .addr(idma_reg32_3d_reg_pkg::IDMA_REG32_3D_SRC_STRIDE_3_LOW_OFFSET), .data(cfg_reg_d[magia_tile_pkg::DMA_SRC_STRIDE_3_IDX]), .reg_error(reg_error_cfg)); - cfg_reg_update_clr[magia_tile_pkg::DMA_SRC_STRIDE_3_IDX] = reg_error_cfg ? 1'b0 : (rw_valid_cfg ? 1'b1 : 1'b0); - end - cfg_reg_update_q[magia_tile_pkg::DMA_REPS_3_IDX]: begin - rw_valid_cfg = write_idma_reg(.req(cfg_configurer_req), .rsp(cfg_configurer_rsp), .addr(idma_reg32_3d_reg_pkg::IDMA_REG32_3D_REPS_3_LOW_OFFSET), .data(cfg_reg_d[magia_tile_pkg::DMA_REPS_3_IDX]), .reg_error(reg_error_cfg)); - cfg_reg_update_clr[magia_tile_pkg::DMA_REPS_3_IDX] = reg_error_cfg ? 1'b0 : (rw_valid_cfg ? 1'b1 : 1'b0); - end - endcase - end - end - end - - for (genvar i = 0; i < N_CFG_REG; i++) begin: gen_configuration_update_register - always_ff @(posedge clk_dc_g, negedge rst_ni) begin: configuration_update_register - if (~rst_ni) cfg_reg_update_q[i] <= 1'b0; - else begin - if (clear_i | cfg_reg_update_clr[i]) cfg_reg_update_q[i] <= 1'b0; - else cfg_reg_update_q[i] <= cfg_reg_update_d[i]; - end - end - end - -/*******************************************************/ -/** iDMA FE Configuration FSM End **/ -/*******************************************************/ -/** iDMA Transfer FSM Beginning **/ -/*******************************************************/ - - always_comb begin: idma_transferer_next_state_output_logic - clk_tfr_en = 1'b1; - n_idma_state = c_idma_state; - start_dma = 1'b0; - busy_dma = 1'b0; - done_dma = 1'b0; - transfer_not_set_properly = 1'b0; - reg_error_tfr = 1'b0; - rw_valid_tfr = 1'b0; - next_id_d = next_id_q; - done_id = '0; - cfg_transferer_req.addr = '0; - cfg_transferer_req.write = 1'b0; - cfg_transferer_req.wdata = '0; - cfg_transferer_req.wstrb = '0; - cfg_transferer_req.valid = 1'b0; - - case (c_idma_state) - IDLE: if (start_transfer) n_idma_state = START; else clk_tfr_en = 1'b0; - START: begin - start_dma = 1'b1; - rw_valid_tfr = read_idma_reg(.req(cfg_transferer_req), .rsp(cfg_transferer_rsp), .addr(idma_reg32_3d_reg_pkg::IDMA_REG32_3D_NEXT_ID_0_OFFSET), .data(next_id_d), .reg_error(reg_error_tfr)); - transfer_not_set_properly = (rw_valid_tfr & (next_id_d == 0)) ? 1'b1 : 1'b0; - n_idma_state = (reg_error_tfr | transfer_not_set_properly) ? IDLE : (~rw_valid_tfr ? c_idma_state: BUSY); - end - BUSY: begin - busy_dma = 1'b1; - rw_valid_tfr = read_idma_reg(.req(cfg_transferer_req), .rsp(cfg_transferer_rsp), .addr(idma_reg32_3d_reg_pkg::IDMA_REG32_3D_DONE_ID_0_OFFSET), .data(done_id), .reg_error(reg_error_tfr)); - n_idma_state = reg_error_tfr ? IDLE : (~rw_valid_tfr ? c_idma_state : (done_id != next_id_q ? c_idma_state : DONE)); - end - DONE: begin - done_dma = 1'b1; - n_idma_state = IDLE; - end - endcase - end - - always_ff @(posedge clk_tfr_g, negedge rst_ni) begin: idma_state_register - if (~rst_ni) c_idma_state <= IDLE; - else begin - if (clear_i) c_idma_state <= IDLE; - else c_idma_state <= n_idma_state; - end - end - - always_ff @(posedge clk_tfr_g, negedge rst_ni) begin: next_id_register - if (~rst_ni) next_id_q <= 1; - else begin - if (clear_i) next_id_q <= 1; - else next_id_q <= next_id_d; - end - end - -/*******************************************************/ -/** iDMA Transfer FSM End **/ -/*******************************************************/ - -endmodule: idma_xif_inst_decoder \ No newline at end of file diff --git a/hw/tile/magia_tile.sv b/hw/tile/magia_tile.sv index 161ff914..353995af 100644 --- a/hw/tile/magia_tile.sv +++ b/hw/tile/magia_tile.sv @@ -316,7 +316,6 @@ module magia_tile logic idma_obi2axi_done; logic idma_obi2axi_error; - magia_tile_pkg::xif_inst_rule_t[magia_tile_pkg::N_RULES-1:0] xif_coproc_rules; logic sys_clk; logic sys_clk_en; @@ -403,9 +402,13 @@ module magia_tile magia_tile_pkg::eu_direct_req_t eu_direct_req; magia_tile_pkg::eu_direct_rsp_t eu_direct_rsp; - // Cluster core data interface (converted directly to OBI xbar) - magia_tile_pkg::core_data_req_t [magia_tile_pkg::N_CLUSTER_CORES-1:0] cluster_data_req; - magia_tile_pkg::core_data_rsp_t [magia_tile_pkg::N_CLUSTER_CORES-1:0] cluster_data_rsp; + // Cluster core data interface (converted directly to OBI xbar). + // Cluster cores are always CV32E40P, so these are typed on the CV32E40P + // flavour and not on core_data_req_t, which follows the control core: with + // core=CV32E40X the extra atop/memtype/prot/dbg fields would never be driven + // and would propagate X into the OBI crossbar. + magia_tile_pkg::cv32e40p_core_data_req_t [magia_tile_pkg::N_CLUSTER_CORES-1:0] cluster_data_req; + magia_tile_pkg::cv32e40p_core_data_rsp_t [magia_tile_pkg::N_CLUSTER_CORES-1:0] cluster_data_rsp; // Cluster core OBI data interface (output from demux data2obi) magia_tile_pkg::core_obi_data_req_t [magia_tile_pkg::N_CLUSTER_CORES-1:0] cluster_obi_data_req; @@ -466,9 +469,6 @@ module magia_tile magia_tile_pkg::core_instr_rsp_t [magia_tile_pkg::N_CLUSTER_CORES-1:0] cluster_instr_rsp; logic [magia_tile_pkg::N_CLUSTER_CORES-1:0] cluster_fetch_enable; logic [magia_tile_pkg::N_CLUSTER_CORES-1:0] cluster_core_sleep; -`ifdef RI5CY - logic [magia_tile_pkg::N_CLUSTER_CORES-1:0] cluster_core_busy; // RI5CY cluster: core_busy_o intermediate -`endif logic cluster_done; // Per-core dispatch IRQ pulse from tile_csr. CV32E40P IRQ inputs are level // sensitive, so the pulse is stretched until the worker acknowledges MEI. @@ -476,7 +476,7 @@ module magia_tile logic [magia_tile_pkg::N_CLUSTER_CORES-1:0] cluster_start_irq; logic [magia_tile_pkg::N_CLUSTER_CORES-1:0] cluster_start_irq_pending; logic [magia_tile_pkg::N_CLUSTER_CORES-1:0] cluster_irq_ack; - logic [magia_tile_pkg::N_CLUSTER_CORES-1:0][magia_tile_pkg::CLIC_ID_W-1:0] cluster_irq_id; + logic [magia_tile_pkg::N_CLUSTER_CORES-1:0][magia_tile_pkg::CLIC_ID_W_CLUSTER-1:0] cluster_irq_id; logic [magia_tile_pkg::N_CLUSTER_CORES-1:0][31:0] cluster_irq_vec; @@ -524,13 +524,11 @@ module magia_tile assign obi_xbar_rule[magia_tile_pkg::OBI_XBAR_L1SPM_IDX] = '{idx: 32'd1, start_addr: tile_l1_start_addr, end_addr: tile_l1_end_addr }; assign obi_xbar_rule[magia_tile_pkg::OBI_XBAR_RESERVED_IDX] = '{idx: 32'd1, start_addr: tile_reserved_start_addr, end_addr: tile_reserved_end_addr }; assign obi_xbar_rule[magia_tile_pkg::OBI_XBAR_STACK_IDX] = '{idx: 32'd1, start_addr: magia_tile_pkg::STACK_ADDR_START, end_addr: magia_tile_pkg::STACK_ADDR_END }; - assign obi_xbar_rule[magia_tile_pkg::OBI_XBAR_EVENT_UNIT_IDX] = '{idx: 32'd5, start_addr: tile_event_unit_start_addr, end_addr: tile_event_unit_end_addr }; - assign obi_xbar_rule[magia_tile_pkg::OBI_XBAR_TILE_CSR_IDX] = '{idx: 32'd6, start_addr: tile_csr_start_addr, end_addr: tile_csr_end_addr }; -`ifndef CV32E40X - assign obi_xbar_rule[magia_tile_pkg::OBI_XBAR_REDMULE_CTRL_IDX] = '{idx: 32'd2, start_addr: tile_redmule_ctrl_start_addr, end_addr: tile_redmule_ctrl_end_addr }; - assign obi_xbar_rule[magia_tile_pkg::OBI_XBAR_IDMA_IDX] = '{idx: 32'd3, start_addr: tile_idma_ctrl_start_addr, end_addr: tile_idma_ctrl_end_addr }; - assign obi_xbar_rule[magia_tile_pkg::OBI_XBAR_FSYNC_CTRL_IDX] = '{idx: 32'd4, start_addr: tile_fsync_ctrl_start_addr, end_addr: tile_fsync_ctrl_end_addr }; -`endif + assign obi_xbar_rule[magia_tile_pkg::OBI_XBAR_REDMULE_CTRL_IDX] = '{idx: 32'd2, start_addr: tile_redmule_ctrl_start_addr, end_addr: tile_redmule_ctrl_end_addr }; + assign obi_xbar_rule[magia_tile_pkg::OBI_XBAR_IDMA_IDX] = '{idx: 32'd3, start_addr: tile_idma_ctrl_start_addr, end_addr: tile_idma_ctrl_end_addr }; + assign obi_xbar_rule[magia_tile_pkg::OBI_XBAR_FSYNC_CTRL_IDX] = '{idx: 32'd4, start_addr: tile_fsync_ctrl_start_addr, end_addr: tile_fsync_ctrl_end_addr }; + assign obi_xbar_rule[magia_tile_pkg::OBI_XBAR_EVENT_UNIT_IDX] = '{idx: 32'd5, start_addr: tile_event_unit_start_addr, end_addr: tile_event_unit_end_addr }; + assign obi_xbar_rule[magia_tile_pkg::OBI_XBAR_TILE_CSR_IDX] = '{idx: 32'd6, start_addr: tile_csr_start_addr, end_addr: tile_csr_end_addr }; assign axi_xbar_rule[magia_tile_pkg::AXI_XBAR_L2_IDX] = '{idx: 32'd0, start_addr: magia_tile_pkg::L2_ADDR_START, end_addr: magia_tile_pkg::L2_ADDR_END }; assign axi_xbar_rule[magia_tile_pkg::AXI_XBAR_L1SPM_IDX] = '{idx: 32'd1, start_addr: tile_l1_start_addr, end_addr: tile_l1_end_addr }; @@ -587,74 +585,37 @@ module magia_tile assign hci_clear = 1'b0; assign hci_ctrl = '0; -`ifdef CV32E40X - assign redmule_ctrl_req = '0; -`endif - assign idma_clear = 1'b0; assign fsync_clear = 1'b0; - assign xif_coproc_rules[magia_tile_pkg::XIF_REDMULE_IDX] = '0; // current version of XIF-RedMulE not (yet) supported - assign xif_coproc_rules[magia_tile_pkg::XIF_IDMA_IDX] = '{sign_list: '{ {{magia_tile_pkg::CONF_OPCODE, magia_tile_pkg::CONF_FUNC3}}, - {{magia_tile_pkg::SET_OPCODE, magia_tile_pkg::SET_AL_FUNC3}}, - {{magia_tile_pkg::SET_OPCODE, magia_tile_pkg::SET_SR2_FUNC3}}, - {{magia_tile_pkg::SET_OPCODE, magia_tile_pkg::SET_SR3_FUNC3}}, - {{magia_tile_pkg::SET_OPCODE, magia_tile_pkg::SET_S_FUNC3}}, - {{magia_tile_pkg::SET_OPCODE, magia_tile_pkg::SET_S_FUNC3}}, - {{magia_tile_pkg::SET_OPCODE, magia_tile_pkg::SET_S_FUNC3}}, - {{magia_tile_pkg::SET_OPCODE, magia_tile_pkg::SET_S_FUNC3}}, - {{magia_tile_pkg::SET_OPCODE, magia_tile_pkg::SET_S_FUNC3}} }}; - assign xif_coproc_rules[magia_tile_pkg::XIF_FSYNC_IDX] = '{sign_list: '{ default: {magia_tile_pkg::FSYNC_OPCODE, magia_tile_pkg::FSYNC_FUNC3} }}; assign redmule_evt[0][1] = 1'b0; `ifdef CV32E40X - assign irq[magia_tile_pkg::IRQ_IDX_REDMULE_EVT_0] = 1'b0; /* redmule_evt[0][0]; */ // Event Unit manages these interrupts // Only 1 core supported - assign irq[magia_tile_pkg::IRQ_IDX_REDMULE_EVT_1] = 1'b0; /* redmule_evt[0][1]; */ // Event Unit manages these interrupts // Only 1 core supported - assign irq[magia_tile_pkg::IRQ_IDX_A2O_ERROR] = 1'b0; /* idma_axi2obi_error; */ // Event Unit manages these interrupts - assign irq[magia_tile_pkg::IRQ_IDX_O2A_ERROR] = 1'b0; /* idma_obi2axi_error; */ // Event Unit manages these interrupts - assign irq[magia_tile_pkg::IRQ_IDX_A2O_DONE] = 1'b0; /* idma_axi2obi_done; */ // Event Unit manages these interrupts - assign irq[magia_tile_pkg::IRQ_IDX_O2A_DONE] = 1'b0; /* idma_obi2axi_done; */ // Event Unit manages these interrupts - assign irq[magia_tile_pkg::IRQ_IDX_A2O_START] = 1'b0; /* idma_axi2obi_start; */ // Event Unit manages these interrupts - assign irq[magia_tile_pkg::IRQ_IDX_O2A_START] = 1'b0; /* idma_obi2axi_start; */ // Event Unit manages these interrupts - assign irq[magia_tile_pkg::IRQ_IDX_A2O_BUSY] = 1'b0; /* idma_axi2obi_busy; */ // Event Unit manages these interrupts - assign irq[magia_tile_pkg::IRQ_IDX_O2A_BUSY] = 1'b0; /* idma_obi2axi_busy; */ // Event Unit manages these interrupts - assign irq[magia_tile_pkg::IRQ_IDX_REDMULE_BUSY] = 1'b0; /* redmule_busy; */ // Event Unit manages these interrupts - assign irq[magia_tile_pkg::IRQ_IDX_FSYNC_DONE] = 1'b0; /* fsync_done; */ // Event Unit manages these interrupts - assign irq[magia_tile_pkg::IRQ_IDX_FSYNC_ERROR] = 1'b0; /* fsync_error; */ // Event Unit manages these interrupts - assign irq[magia_pkg::N_IRQ-magia_tile_pkg::IRQ_USED-1:16] - = irq_i[magia_pkg::N_IRQ-magia_tile_pkg::IRQ_USED-1:16]; + assign enable_prefetching = 1'b0; + assign flush_valid[0] = fencei_flush_req; // Single port i$ + assign fencei_flush_ack = flush_ready[0]; // Signle port i$ + + assign irq[N_IRQ-1:19] = '0; + assign irq[18:16] = irq_i[18:16]; assign irq[15:12] = '0; - assign irq[11] = eu_core_irq_req[0]; // Event Unit IRQ mapped to external interrupt (bit 11) /* irq_i[11]; */ + assign irq[11] = eu_core_irq_req[0]; // Event Unit IRQ mapped to external interrupt (bit 11) assign irq[10:8] = '0; assign irq[7] = irq_i[7]; assign irq[6:4] = '0; assign irq[3] = irq_i[3]; assign irq[2:0] = '0; - // CLIC unused assign clic_irq = 1'b0; assign clic_irq_id = '0; assign clic_irq_level = '0; assign clic_irq_priv = '0; assign clic_irq_shv = 1'b0; - - assign enable_prefetching = 1'b0; - assign flush_valid[0] = fencei_flush_req; // Single port i$ - assign fencei_flush_ack = flush_ready[0]; // Signle port i$ - - assign xif_redmule_if.result_ready = 1'b0; - assign xif_redmule_if.compressed_valid = 1'b0; - assign xif_redmule_if.compressed_req = '0; - assign xif_redmule_if.mem_ready = 1'b0; - assign xif_redmule_if.mem_resp = '0; `else // Icache control signals assign enable_prefetching = 1'b0; assign flush_valid = '0; - // Event Unit provides unified interrupt management - // External interrupts must be mapped to bit 11 (MEIE - Machine External Interrupt Enable) assign irq[magia_pkg::N_IRQ-1:12] = '0; // Clear all high IRQs assign irq[11] = eu_core_irq_req[0]; // Event Unit IRQ mapped to external interrupt (bit 11) assign irq[10:8] = '0; // Clear IRQs 8-10 @@ -670,16 +631,28 @@ module magia_tile /** Type Conversions Beginning **/ /*******************************************************/ - // Convert core data interface to OBI for crossbar - data2obi_req i_core_data2obi_req ( + // Convert control core data interface to OBI for crossbar +`ifdef CV32E40X + cv32e40x_data2obi_req i_core_data2obi_req ( + .data_req_i ( core_data_req_to_xbar ), + .obi_req_o ( core_obi_data_req ) + ); + + cv32e40x_obi2data_rsp i_core_obi2data_rsp ( + .obi_rsp_i ( core_obi_data_rsp ), + .data_rsp_o ( core_data_rsp_from_xbar ) + ); +`else + cv32e40p_data2obi_req i_core_data2obi_req ( .data_req_i ( core_data_req_to_xbar ), .obi_req_o ( core_obi_data_req ) ); - obi2data_rsp i_core_obi2data_rsp ( + cv32e40p_obi2data_rsp i_core_obi2data_rsp ( .obi_rsp_i ( core_obi_data_rsp ), .data_rsp_o ( core_data_rsp_from_xbar ) ); +`endif obi2hci_req #( .obi_req_t ( magia_tile_pkg::core_obi_data_req_t ), @@ -935,7 +908,6 @@ module magia_tile .rsp_r_user_i ( '0 ) ); -`ifndef CV32E40X // RedMule controller OBI-to-HWPE control interface obi2hwpe_ctrl obi2hwpe_ctrl_inst ( .obi_req_i ( core_mem_data_req[magia_tile_pkg::OBI_XBAR_REDMULE_CTRL_IDX] ), @@ -943,7 +915,6 @@ module magia_tile .ctrl_req_o ( redmule_ctrl_req ), .ctrl_rsp_i ( redmule_ctrl_rsp ) ); -`endif /*********************** Cluster **********************************/ @@ -1133,18 +1104,7 @@ module magia_tile end endgenerate - cv32e40x_if_xif xif_redmule_if (); - - cv32e40x_if_xif #( - .X_NUM_RS ( magia_tile_pkg::X_NUM_RS ), - .X_ID_WIDTH ( magia_tile_pkg::X_ID_W ), - .X_MEM_WIDTH ( magia_tile_pkg::X_MEM_W ), - .X_RFR_WIDTH ( magia_tile_pkg::X_RFR_W ), - .X_RFW_WIDTH ( magia_tile_pkg::X_RFW_W ), - .X_MISA ( magia_tile_pkg::X_MISA ), - .X_ECS_XS ( magia_tile_pkg::X_ECS_XS ) - ) xif_fpu_if (); - + // Single Xif interface shared between core (cpu_*) and FPU (coproc_*) cv32e40x_if_xif #( .X_NUM_RS ( magia_tile_pkg::X_NUM_RS ), .X_ID_WIDTH ( magia_tile_pkg::X_ID_W ), @@ -1153,17 +1113,9 @@ module magia_tile .X_RFW_WIDTH ( magia_tile_pkg::X_RFW_W ), .X_MISA ( magia_tile_pkg::X_MISA ), .X_ECS_XS ( magia_tile_pkg::X_ECS_XS ) - ) xif_if (); + ) xif_if (); + - cv32e40x_if_xif #( - .X_NUM_RS ( magia_tile_pkg::X_NUM_RS ), - .X_ID_WIDTH ( magia_tile_pkg::X_ID_W ), - .X_MEM_WIDTH ( magia_tile_pkg::X_MEM_W ), - .X_RFR_WIDTH ( magia_tile_pkg::X_RFR_W ), - .X_RFW_WIDTH ( magia_tile_pkg::X_RFW_W ), - .X_MISA ( magia_tile_pkg::X_MISA ), - .X_ECS_XS ( magia_tile_pkg::X_ECS_XS ) - ) xif_coproc_if[magia_tile_pkg::N_COPROC] (); // Index 0 -> RedMulE, Index 1 -> iDMA, Index 2 -> Fractal Sync, Index 3 -> FPU /*******************************************************/ /** Interface Definitions End **/ @@ -1190,14 +1142,9 @@ module magia_tile /*******************************************************/ magia_redmule_wrap #( -`ifdef CV32E40X - .CtrlIntfConfig ( redmule_pkg::XIF ), - .XifIdWidth ( magia_tile_pkg::X_ID_W ), -`else - .CtrlIntfConfig ( redmule_pkg::HWPE_TARGET ), -`endif - .Height ( magia_tile_pkg::REDMULE_HEIGHT ), - .Width ( magia_tile_pkg::REDMULE_WIDTH ), + .CtrlIntfConfig ( redmule_pkg::HWPE_TARGET ), + .Height ( magia_tile_pkg::REDMULE_HEIGHT ), + .Width ( magia_tile_pkg::REDMULE_WIDTH ), .NumPipeRegs ( magia_tile_pkg::REDMULE_NUM_PIPE_REGS ) ) i_redmule_wrap ( .clk_i ( sys_clk ), @@ -1206,21 +1153,6 @@ module magia_tile .busy_o ( redmule_busy ), .evt_o ( redmule_evt[0][0] ), - -`ifdef CV32E40X - .x_issue_req_i ( xif_coproc_if.coproc_issue[magia_tile_pkg::XIF_REDMULE_IDX].issue_req ), - .x_issue_resp_o ( xif_coproc_if.coproc_issue[magia_tile_pkg::XIF_REDMULE_IDX].issue_resp ), - .x_issue_valid_i ( xif_coproc_if.coproc_issue[magia_tile_pkg::XIF_REDMULE_IDX].issue_valid ), - .x_issue_ready_o ( xif_coproc_if.coproc_issue[magia_tile_pkg::XIF_REDMULE_IDX].issue_ready ), - .x_register_i ( xif_coproc_if.coproc_issue[magia_tile_pkg::XIF_REDMULE_IDX].register ), - .x_register_valid_i ( xif_coproc_if.coproc_issue[magia_tile_pkg::XIF_REDMULE_IDX].register_valid ), - .x_register_ready_o ( xif_coproc_if.coproc_issue[magia_tile_pkg::XIF_REDMULE_IDX].register_ready ), - .x_commit_i ( xif_coproc_if.coproc_commit[magia_tile_pkg::XIF_REDMULE_IDX].commit ), - .x_commit_valid_i ( xif_coproc_if.coproc_commit[magia_tile_pkg::XIF_REDMULE_IDX].commit_valid ), - .x_result_o ( xif_redmule_if.coproc_result.result ), - .x_result_valid_o ( xif_redmule_if.coproc_result.result_valid ), - .x_result_ready_i ( xif_redmule_if.coproc_result.result_ready ), -`else .x_issue_req_i ( ), // Not used in HWPE mode .x_issue_resp_o ( ), // Not used in HWPE mode .x_issue_valid_i ( 1'b0 ), // Not used in HWPE mode @@ -1233,7 +1165,6 @@ module magia_tile .x_result_o ( ), // Not used in HWPE mode .x_result_valid_o ( ), // Not used in HWPE mode .x_result_ready_i ( 1'b0 ), // Not used in HWPE mode -`endif .data_req_o ( redmule_data_req ), .data_rsp_i ( redmule_data_rsp ), @@ -1280,7 +1211,7 @@ module magia_tile .CLIC_ID_WIDTH ( magia_tile_pkg::CLIC_ID_W ) // Width of clic_irq_id_i and clic_irq_id_o ) i_cv32e40x_ctrl_core ( // Clock and reset - .clk_i ( sys_clk ), + .clk_i ( core_clk ), .rst_ni ( rst_ni ), .scan_cg_en_i , @@ -1355,102 +1286,8 @@ module magia_tile // Special control signals .fetch_enable_i , .core_sleep_o , - .wu_wfe_i - ); -`elsif RI5CY - riscv_core #( - .N_EXT_PERF_COUNTERS ( magia_tile_pkg::N_EXT_PERF_COUNTERS ), - .INSTR_RDATA_WIDTH ( magia_tile_pkg::INSTR_RDATA_WIDTH ), - .PULP_SECURE ( magia_tile_pkg::PULP_SECURE ), - .N_PMP_ENTRIES ( magia_tile_pkg::N_PMP_ENTRIES ), - .USE_PMP ( magia_tile_pkg::USE_PMP ), - .PULP_CLUSTER ( magia_tile_pkg::PULP_CLUSTER ), - .FPU ( magia_tile_pkg::FPU ), - .Zfinx ( magia_tile_pkg::ZFINX ), - .FP_DIVSQRT ( magia_tile_pkg::FP_DIVSQRT ), - .SHARED_FP ( magia_tile_pkg::SHARED_FP ), - .SHARED_DSP_MULT ( magia_tile_pkg::SHARED_DSP_MULT ), - .SHARED_INT_MULT ( magia_tile_pkg::SHARED_INT_MULT ), - .SHARED_INT_DIV ( magia_tile_pkg::SHARED_INT_DIV ), - .SHARED_FP_DIVSQRT ( magia_tile_pkg::SHARED_FP_DIVSQRT ), - .WAPUTYPE ( magia_tile_pkg::WAPUTYPE ), - .APU_NARGS_CPU ( magia_tile_pkg::APU_NARGS_CPU ), - .APU_WOP_CPU ( magia_tile_pkg::APU_WOP_CPU ), - .APU_NDSFLAGS_CPU ( magia_tile_pkg::APU_NDSFLAGS_CPU ), - .APU_NUSFLAGS_CPU ( magia_tile_pkg::APU_NUSFLAGS_CPU ), - .DM_HaltAddress ( magia_tile_pkg::DM_HALT_ADDR ) - ) i_ri5cy_ctrl_core ( - // Clock and Reset - .clk_i ( core_clk ), // Use gated clock for core - .rst_ni ( rst_ni ), - - // Clock enable and test mode - .clock_en_i ( sys_clk_en ), - .test_en_i ( test_mode_i ), - - // Floating-point register file disable (for Zfinx) - .fregfile_disable_i ( 1'b0 ), // FPU enabled, use dedicated FP regfile - - // Boot configuration - .boot_addr_i ( boot_addr_i ), - - // Cluster/Core IDs - .cluster_id_i ( '0 ), - .core_id_i ( mhartid_i[3:0] ), - - // Instruction memory interface - .instr_req_o ( core_instr_req.req ), - .instr_gnt_i ( core_instr_rsp.gnt ), - .instr_rvalid_i ( core_instr_rsp.rvalid ), - .instr_addr_o ( core_instr_req.addr ), - .instr_rdata_i ( core_instr_rsp.rdata ), - - // Data memory interface - .data_req_o ( core_data_req.req ), - .data_gnt_i ( core_data_rsp.gnt ), - .data_rvalid_i ( core_data_rsp.rvalid ), - .data_addr_o ( core_data_req.addr ), - .data_be_o ( core_data_req.be ), - .data_wdata_o ( core_data_req.wdata ), - .data_we_o ( core_data_req.we ), - .data_rdata_i ( core_data_rsp.rdata ), - - // APU interface (disabled - not connected) - .apu_master_req_o ( ), - .apu_master_ready_o ( ), - .apu_master_gnt_i ( '0 ), - - .apu_master_operands_o ( ), - .apu_master_op_o ( ), - .apu_master_type_o ( ), - .apu_master_flags_o ( ), - - .apu_master_valid_i ( '0 ), - .apu_master_result_i ( '0 ), - .apu_master_flags_i ( '0 ), - - // Interrupts - .irq_i ( eu_core_irq_req[0] ), - .irq_id_i ( '0 ), - .irq_ack_o ( eu_core_irq_ack[0] ), - .irq_id_o ( eu_core_irq_ack_id[0] ), - .irq_sec_i ( '0 ), - - // Security level (unused) - .sec_lvl_o ( ), - - // Debug interface - .debug_req_i ( debug_req_i[0] ), - - // CPU control - .fetch_enable_i ( fetch_enable_i ), - .core_busy_o ( core_busy_o ), - - - // Performance counters - .ext_perf_counters_i ( '0 ) + .wu_wfe_i ); - `else `ifndef CORE_TRACES cv32e40p_top #( @@ -1460,7 +1297,7 @@ module magia_tile .COREV_PULP ( 1 ), // For now this is a no .COREV_CLUSTER ( 1 ), .FPU ( FPU ), - .ZFINX ( magia_tile_pkg::ZFINX ), + .ZFINX ( magia_tile_pkg::ZFINX_CV32E40P ), .FPU_ADDMUL_LAT ( 1 ), // Match C_LAT_FP32=1 in fpnew wrapper .FPU_OTHERS_LAT ( 1 ), // Match C_LAT_NONCOMP=1 in fpnew wrapper .NUM_MHPMCOUNTERS ( 29 ) @@ -1497,7 +1334,10 @@ module magia_tile .irq_ack_o ( eu_core_irq_ack[0] ), .irq_id_o ( eu_core_irq_ack_id[0] ), // Debug interface - .debug_req_i ( debug_req_i[0] ), + .debug_req_i ( debug_req_i[0] ), + .debug_havereset_o ( debug_havereset_o ), + .debug_running_o ( debug_running_o ), + .debug_halted_o ( debug_halted_o ), // CPU control .fetch_enable_i ( fetch_enable_i ), .core_sleep_o ( core_sleep_o ) @@ -1510,9 +1350,6 @@ module magia_tile assign core_instr_req.dbg = 1'b0; assign mcycle_o = 64'h0; - assign debug_havereset_o = 1'b0; - assign debug_running_o = 1'b0; - assign debug_halted_o = 1'b0; assign debug_pc_valid_o = 1'b0; assign debug_pc_o = 32'h0; `endif @@ -1676,70 +1513,9 @@ module magia_tile /*******************************************************/ /** L1 SPM (TCDM) End **/ /*******************************************************/ -/** Xif Dispatcher Beginning **/ -/*******************************************************/ - - xif_inst_dispatcher #( - .N_COPROC ( magia_tile_pkg::N_COPROC ), - .N_RULES ( magia_tile_pkg::N_RULES ), - .DEFAULT_IDX ( magia_tile_pkg::DEFAULT_IDX ), - .OPCODE_OFF ( magia_tile_pkg::OPCODE_OFF ), - .OPCODE_W ( magia_tile_pkg::OPCODE_W ), - .xif_inst_rule_t ( magia_tile_pkg::xif_inst_rule_t ) - ) i_xif_inst_dispatcher ( - .clk_i ( sys_clk ), - .rst_ni ( rst_ni ), - .xif_issue_if_i ( xif_if.coproc_issue ), - .xif_issue_if_o ( xif_coproc_if.cpu_issue ), - .xif_result_if_o ( xif_if.coproc_result ), - .xif_result_if_i ( xif_fpu_if.cpu_result ), - .rules_i ( xif_coproc_rules ) - ); - -/*******************************************************/ -/** Xif Dispatcher End **/ -/*******************************************************/ /** iDMA Beginning **/ /*******************************************************/ -`ifdef CV32E40X - idma_ctrl #( - .ERROR_CAP ( ERROR_CAP ), - .axi_req_t ( magia_tile_pkg::idma_axi_req_t ), - .axi_rsp_t ( magia_tile_pkg::idma_axi_rsp_t ), - .obi_req_t ( magia_tile_pkg::idma_obi_req_t ), - .obi_rsp_t ( magia_tile_pkg::idma_obi_rsp_t ) - ) i_idma_ctrl ( - .clk_i ( sys_clk ), - .rst_ni ( rst_ni ), - .testmode_i ( test_mode_i ), - .clear_i ( idma_clear ), - - .xif_issue_if_i ( xif_coproc_if.coproc_issue[magia_tile_pkg::XIF_IDMA_IDX] ), - - .axi_read_req_o ( idma_axi_read_req_out ), - .axi_read_rsp_i ( idma_axi_read_rsp_out ), - - .axi_write_req_o ( idma_axi_write_req_out ), - .axi_write_rsp_i ( idma_axi_write_rsp_out ), - - .obi_read_req_o ( idma_obi_read_req_out ), - .obi_read_rsp_i ( idma_obi_read_rsp_out ), - - .obi_write_req_o ( idma_obi_write_req_out ), - .obi_write_rsp_i ( idma_obi_write_rsp_out ), - - .axi2obi_start_o ( idma_axi2obi_start ), - .axi2obi_busy_o ( idma_axi2obi_busy ), - .axi2obi_done_o ( idma_axi2obi_done ), - .axi2obi_error_o ( idma_axi2obi_error ), - - .obi2axi_start_o ( idma_obi2axi_start ), - .obi2axi_busy_o ( idma_obi2axi_busy ), - .obi2axi_done_o ( idma_obi2axi_done ), - .obi2axi_error_o ( idma_obi2axi_error ) - ); -`else idma_ctrl_mm #( .ERROR_CAP ( ERROR_CAP ), .obi_req_t ( magia_tile_pkg::core_obi_data_req_t ), @@ -1782,7 +1558,6 @@ module magia_tile .irq_o2a_done_o ( idma_obi2axi_done ), .irq_o2a_error_o ( idma_obi2axi_error ) ); -`endif axi_rw_join #( .axi_req_t ( magia_tile_pkg::idma_axi_req_t ), @@ -2011,37 +1786,8 @@ module magia_tile /*******************************************************/ /** Fractal Sync Out Beginning **/ /*******************************************************/ - -`ifdef CV32E40X - fractal_sync_xif_inst_decoder #( - .INSTR_W ( magia_tile_pkg::FSYNC_INSTR_W ), - .DATA_W ( magia_tile_pkg::FSYNC_DATA_W ), - .ADDR_W ( magia_tile_pkg::FSYNC_ADDR_W ), - .N_RF_PORTS ( magia_tile_pkg::FSYNC_N_RF_PORTS ), - .OPCODE_W ( magia_tile_pkg::FSYNC_OPCODE_W ), - .FUNC3_W ( magia_tile_pkg::FSYNC_FUNC3_W ), - .OPCODE_OFF ( magia_tile_pkg::FSYNC_OPCODE_OFF ), - .FUNC3_OFF ( magia_tile_pkg::FSYNC_FUNC3_OFF ), - .N_CFG_REG ( magia_tile_pkg::FSYNC_N_CFG_REG ), - .AGGR_W ( magia_tile_pkg::FSYNC_AGGR_W ), - .ID_W ( magia_tile_pkg::FSYNC_ID_W ), - .NBR_AGGR_W ( magia_tile_pkg::FSYNC_NBR_AGGR_W ), - .NBR_ID_W ( magia_tile_pkg::FSYNC_NBR_ID_W ), - .STALL ( magia_tile_pkg::FSYNC_STALL ) - ) i_fsync_dec ( - .clk_i ( sys_clk ), - .rst_ni ( rst_ni ), - .clear_i ( fsync_clear ), - .xif_issue_if_i ( xif_coproc_if.coproc_issue[magia_tile_pkg::XIF_FSYNC_IDX] ), - .ht_fsync_if_o ( ht_fsync_if_o ), - .hn_fsync_if_o ( hn_fsync_if_o ), - .vt_fsync_if_o ( vt_fsync_if_o ), - .vn_fsync_if_o ( vn_fsync_if_o ), - .done_o ( fsync_done ), - .error_o ( fsync_error ) - ); -`else - // Fractal Sync OBI Memory-Mapped Slave (replaces XIF interface) + + // Fractal Sync OBI Memory-Mapped Slave obi_slave_fsync #( .BASE_ADDR ( magia_tile_pkg::FSYNC_CTRL_ADDR_START ), .AGGR_W ( magia_tile_pkg::FSYNC_AGGR_W ), @@ -2061,7 +1807,6 @@ module magia_tile .done_o ( fsync_done ), .error_o ( fsync_error ) ); -`endif /*******************************************************/ /** Fractal Sync Out End **/ @@ -2071,7 +1816,7 @@ module magia_tile `ifdef CV32E40X fpu_ss #( - .PULP_ZFINX ( magia_tile_pkg::FPU_ZFINX ), + .PULP_ZFINX ( magia_tile_pkg::ZFINX_CV32E40X ), .INPUT_BUFFER_DEPTH ( magia_tile_pkg::FPU_BUFFER_DEPTH ), .INPUT_BUFFER_FALL_THROUGH ( magia_tile_pkg::FPU_BUFFER_FT ), .OUT_OF_ORDER ( magia_tile_pkg::FPU_OOO ), @@ -2104,12 +1849,12 @@ module magia_tile ); xif_if2struct i_xif_if2struct ( - .xif_compressed_if_i ( xif_if.coproc_compressed ), - .xif_issue_if_i ( xif_coproc_if.coproc_issue[magia_tile_pkg::XIF_FPU_IDX] ), - .xif_commit_if_i ( xif_if.coproc_commit ), - .xif_mem_if_o ( xif_if.coproc_mem ), - .xif_mem_result_if_i ( xif_if.coproc_mem_result ), - .xif_result_if_o ( xif_fpu_if.coproc_result ), + .xif_compressed_if_i ( xif_if.coproc_compressed ), + .xif_issue_if_i ( xif_if.coproc_issue ), + .xif_commit_if_i ( xif_if.coproc_commit ), + .xif_mem_if_o ( xif_if.coproc_mem ), + .xif_mem_result_if_i ( xif_if.coproc_mem_result ), + .xif_result_if_o ( xif_if.coproc_result ), .x_compressed_valid_o ( x_compressed_valid ), .x_compressed_ready_i ( x_compressed_ready ), .x_compressed_req_o ( x_compressed_req ), @@ -2222,25 +1967,16 @@ module magia_tile assign core_irq_vec[i] = {20'b0, eu_core_irq_req[i], 11'b0}; end endgenerate - -`ifdef CV32E40X - assign eu_core_irq_ack = eu_core_irq_req; - assign eu_core_irq_ack_id = eu_core_irq_id; - - assign core_busy_o = !core_sleep_o; -`else - // PULP cluster cores are no longer wired to the event unit's IRQ port: - // tie their ack/ack_id slots so the EU sees them as idle/never-acking. generate for (genvar i = 0; i < magia_tile_pkg::N_CLUSTER_CORES; i++) begin : gen_cluster_irq_ack_tie assign eu_core_irq_ack[i+1] = 1'b0; assign eu_core_irq_ack_id[i+1] = '0; end endgenerate -`ifdef RI5CY - // RI5CY outputs core_busy_o (active-high: 1 = busy); derive core_sleep_o (active-high: 1 = sleeping) - assign core_sleep_o = ~core_busy_o; -`endif + +`ifdef CV32E40X + assign eu_core_irq_ack[0] = eu_core_irq_req[0]; + assign eu_core_irq_ack_id[0] = eu_core_irq_id[0]; `endif magia_event_unit #( @@ -2477,10 +2213,7 @@ always_ff @(posedge sys_clk or negedge rst_ni) begin for (int unsigned i = 0; i < magia_tile_pkg::N_CLUSTER_CORES; i++) begin // Clear on any ack: cluster cores have exactly one IRQ source (the // dispatch pulse), so irq_ack always refers to that source. - // CV32E40P acks with irq_id_o=11 (MEI, from priority encoder on irq_i[31:0]). - // RI5CY acks with irq_id_o=0 (reflects irq_id_i which is tied to '0). - // Checking irq_id==11 would never fire for RI5CY, leaving pending stuck - // HIGH and causing repeated trap-handler re-entry after every mret. + // CV32E40P acks with irq_id_o=11 (MEI, from priority encoder on irq_i[31:0]) if (cluster_irq_ack[i]) begin cluster_start_irq_pending[i] <= 1'b0; end else if (cluster_start_irq[i]) begin @@ -2498,105 +2231,6 @@ end generate for (genvar i = 0; i < magia_tile_pkg::N_CLUSTER_CORES; i++) begin : CORE - `ifdef RI5CY - // RI5CY core with integrated FPU and tracer - // cluster_id_i identifies WHICH cluster (= tile), same for all cores in a tile. - // core_id_i identifies WHICH core within the cluster (0-indexed). - // Use mhartid_i+1 for cluster_id so tile-0 cluster cores never get 0 (0 = standalone main core). - riscv_core #( - .N_EXT_PERF_COUNTERS ( magia_tile_pkg::N_EXT_PERF_COUNTERS ), - .INSTR_RDATA_WIDTH ( magia_tile_pkg::INSTR_RDATA_WIDTH ), - .PULP_SECURE ( magia_tile_pkg::PULP_SECURE ), - .N_PMP_ENTRIES ( magia_tile_pkg::N_PMP_ENTRIES ), - .USE_PMP ( magia_tile_pkg::USE_PMP ), - .PULP_CLUSTER ( magia_tile_pkg::PULP_CLUSTER ), - .FPU ( magia_tile_pkg::FPU ), - .Zfinx ( magia_tile_pkg::ZFINX ), - .FP_DIVSQRT ( magia_tile_pkg::FP_DIVSQRT ), - .SHARED_FP ( magia_tile_pkg::SHARED_FP ), - .SHARED_DSP_MULT ( magia_tile_pkg::SHARED_DSP_MULT ), - .SHARED_INT_MULT ( magia_tile_pkg::SHARED_INT_MULT ), - .SHARED_INT_DIV ( magia_tile_pkg::SHARED_INT_DIV ), - .SHARED_FP_DIVSQRT ( magia_tile_pkg::SHARED_FP_DIVSQRT ), - .WAPUTYPE ( magia_tile_pkg::WAPUTYPE ), - .APU_NARGS_CPU ( magia_tile_pkg::APU_NARGS_CPU ), - .APU_WOP_CPU ( magia_tile_pkg::APU_WOP_CPU ), - .APU_NDSFLAGS_CPU ( magia_tile_pkg::APU_NDSFLAGS_CPU ), - .APU_NUSFLAGS_CPU ( magia_tile_pkg::APU_NUSFLAGS_CPU ), - .DM_HaltAddress ( magia_tile_pkg::DM_HALT_ADDR ) - ) i_RI5CY_core ( - // Clock and Reset - .clk_i ( cluster_clk[i] ), // Always-on per-core cluster clock (NOT the EU-gated main-core clock) - .rst_ni ( rst_ni ), - - // Clock enable and test mode - .clock_en_i ( sys_clk_en ), - .test_en_i ( test_mode_i ), - - // Floating-point register file disable (for Zfinx) - .fregfile_disable_i ( 1'b0 ), // FPU enabled, use dedicated FP regfile - - // Boot configuration - .boot_addr_i ( cluster_boot_addr[i] ), - - // Cluster/Core IDs - .cluster_id_i ( 6'(mhartid_i) + 6'd1 ), // which cluster (tile+1, 1-indexed) - .core_id_i ( 4'(i) ), // which core within the cluster - - // Instruction memory interface - .instr_req_o ( cluster_instr_req[i].req ), - .instr_addr_o ( cluster_instr_req[i].addr ), - .instr_gnt_i ( cluster_instr_rsp[i].gnt ), - .instr_rvalid_i ( cluster_instr_rsp[i].rvalid ), - .instr_rdata_i ( cluster_instr_rsp[i].rdata ), - - // Data memory interface - .data_req_o ( cluster_data_req[i].req ), - .data_addr_o ( cluster_data_req[i].addr ), - .data_be_o ( cluster_data_req[i].be ), - .data_wdata_o ( cluster_data_req[i].wdata ), - .data_we_o ( cluster_data_req[i].we ), - .data_gnt_i ( cluster_data_rsp[i].gnt ), - .data_rvalid_i ( cluster_data_rsp[i].rvalid ), - .data_rdata_i ( cluster_data_rsp[i].rdata ), - - // APU interface (disabled - not connected) - .apu_master_req_o ( ), - .apu_master_ready_o ( ), - .apu_master_gnt_i ( '0 ), - - .apu_master_operands_o ( ), - .apu_master_op_o ( ), - .apu_master_type_o ( ), - .apu_master_flags_o ( ), - - .apu_master_valid_i ( '0 ), - .apu_master_result_i ( '0 ), - .apu_master_flags_i ( '0 ), - - // Interrupts - .irq_i ( cluster_start_irq_pending[i] ), - .irq_ack_o ( cluster_irq_ack[i] ), - .irq_id_o ( cluster_irq_id[i] ), - .irq_sec_i ( '0 ), - .irq_id_i ( '0 ), - - // Security level (unused) - .sec_lvl_o ( ), - - // Debug interface - .debug_req_i ( debug_req_i[i+1] ), - - // CPU control - .fetch_enable_i ( cluster_fetch_enable[i] ), - .core_busy_o ( cluster_core_busy[i] ), - - - // Performance counters - .ext_perf_counters_i ( '0 ) - ); - assign cluster_core_sleep[i] = ~cluster_core_busy[i]; // RI5CY: core_busy_o is active-high; derive core_sleep (active-high) - `else `ifndef CORE_TRACES cv32e40p_top #( `else @@ -2605,7 +2239,7 @@ generate .COREV_PULP ( 1 ), // For now this is a no .COREV_CLUSTER ( 1 ), .FPU ( FPU ), - .ZFINX ( magia_tile_pkg::ZFINX ), + .ZFINX ( magia_tile_pkg::ZFINX_CV32E40P ), .FPU_ADDMUL_LAT ( 1 ), // Match C_LAT_FP32=1 in fpnew wrapper .FPU_OTHERS_LAT ( 1 ), // Match C_LAT_NONCOMP=1 in fpnew wrapper .NUM_MHPMCOUNTERS ( 29 ) @@ -2645,23 +2279,26 @@ generate .irq_id_o ( cluster_irq_id[i] ), // Debug interface .debug_req_i ( debug_req_i[i+1] ), + // Debug status outputs unused: no tile-level output exposes per-cluster-core debug status. + .debug_havereset_o ( ), + .debug_running_o ( ), + .debug_halted_o ( ), // CPU control .fetch_enable_i ( cluster_fetch_enable[i] ), .core_sleep_o ( cluster_core_sleep[i] ) ); - `endif end endgenerate // Cluster core data demux (EU direct link) and OBI conversion generate for (genvar i = 0; i < magia_tile_pkg::N_CLUSTER_CORES; i++) begin : gen_cluster_data_obi - data2obi_req i_cluster_data2obi ( + cv32e40p_data2obi_req i_cluster_data2obi ( .data_req_i ( cluster_data_req[i] ), .obi_req_o ( cluster_obi_data_req[i] ) ); - obi2data_rsp i_cluster_obi2data ( + cv32e40p_obi2data_rsp i_cluster_obi2data ( .obi_rsp_i ( cluster_obi_data_rsp[i] ), .data_rsp_o ( cluster_data_rsp[i] ) ); diff --git a/hw/tile/magia_tile_pkg.sv b/hw/tile/magia_tile_pkg.sv index 65d911dc..52ac2854 100644 --- a/hw/tile/magia_tile_pkg.sv +++ b/hw/tile/magia_tile_pkg.sv @@ -266,25 +266,10 @@ package magia_tile_pkg; parameter bit CLIC_EN = 1'b0; // Specifies whether Smclic, Smclicshv and Smclicconfig are supported // Parameters used by cv32e40p core - parameter int unsigned N_EXT_PERF_COUNTERS = 0; // Number of external performance counters - parameter int unsigned INSTR_RDATA_WIDTH = 32; // Instruction data width - parameter bit PULP_SECURE = 1'b1; // PULP security features (must be 1 for writable mtvec; PULP_SECURE=0 hardwires mtvec_q to boot_addr_i) - parameter int unsigned N_PMP_ENTRIES = 16; // Number of PMP entries - parameter bit USE_PMP = 1'b1; // Enable PMP parameter bit PULP_CLUSTER = 1'b1; // PULP cluster mode parameter bit FPU = 1'b1; // Enable FPU (main feature) - parameter bit ZFINX = 1'b1; // Zfinx extension (integer FP in GPR) - Must be 0 for standard FPU + parameter bit ZFINX_CV32E40P = 1'b1; // Zfinx extension (integer FP in GPR) of the CV32E40P cores (control and cluster) parameter bit FP_DIVSQRT = 1'b1; // FP division and square root - parameter bit SHARED_FP = 1'b0; // Shared FP unit - parameter bit SHARED_DSP_MULT = 1'b0; // Shared DSP multiplier - parameter bit SHARED_INT_MULT = 1'b0; // Shared integer multiplier - parameter bit SHARED_INT_DIV = 1'b0; // Shared integer divider - parameter bit SHARED_FP_DIVSQRT = 1'b0; // Shared FP div/sqrt - parameter int unsigned WAPUTYPE = 0; // APU type width - parameter int unsigned APU_NARGS_CPU = 3; // APU number of arguments - parameter int unsigned APU_WOP_CPU = 6; // APU operation width - parameter int unsigned APU_NDSFLAGS_CPU = 15; // APU data side flags - parameter int unsigned APU_NUSFLAGS_CPU = 5; // APU user side flags parameter logic[31:0] DM_HALT_ADDR = 32'h1A110800; // Debug module halt address `ifdef CV32E40X @@ -294,6 +279,7 @@ package magia_tile_pkg; parameter int unsigned X_NUM_RS = 2; // Number of register file read ports (R-type instructions have 2 source operands) parameter int unsigned CLIC_ID_W = 5; // CLIC interrupt ID width (5 bits for 32 interrupts) `endif + parameter int unsigned CLIC_ID_W_CLUSTER = 5; // cv32e40p irq_id_o/irq_id_i width (fixed, independent of the ctrl core's CLIC_ID_W) // Parameters used by Event Unit parameter int unsigned EVENT_UNIT_IRQ_WIDTH = 5; // Width of Event Unit IRQ ID signals (supports up to 32 different event types) @@ -308,31 +294,24 @@ package magia_tile_pkg; parameter int unsigned REDMULE_UW = UWH; // RedMulE User Width // Parameters used by OBI - parameter int unsigned AUSER_WIDTH = 1; // Width of the auser signal (see OBI documentation): not used by the CV32E40X - parameter int unsigned WUSER_WIDTH = 1; // Width of the wuser signal (see OBI documentation): not used by the CV32E40X - parameter int unsigned ACHK_WIDTH = 1; // Width of the achk signal (see OBI documentation): not used by the CV32E40X - parameter int unsigned RUSER_WIDTH = 1; // Width of the ruser signal (see OBI documentation): not used by the CV32E40X - parameter int unsigned RCHK_WIDTH = 1; // Width of the rchk signal (see OBI documentation): not used by the CV32E40X - parameter int unsigned AID_WIDTH = 1; // Width of the aid signal (address channel identifier, see OBI documentation) - parameter int unsigned RID_WIDTH = 1; // Width of the rid signal (response channel identifier, see OBI documentation) - parameter int unsigned MID_WIDTH = 1; // Width of the mid signal (manager identifier, see OBI documentation) - parameter int unsigned OBI_ID_WIDTH = 1; // Width of the id - configuration - parameter int unsigned N_CLUSTER_CORES = 8; // Number of cores in the cluster (cntrl core not considered) -`ifdef CV32E40X - parameter int unsigned N_SBR = 5; // Number of slaves (HCI, AXI XBAR, Event_Unit, Tile_CSR, + unused RESERVED alias) -`else - parameter int unsigned N_SBR = 7; // Number of OBI slaves (HCI, AXI XBAR, RedMulE_Ctrl, iDMA_Ctrl, FSync_Ctrl, Event_Unit, Tile_CSR) -`endif + parameter int unsigned AUSER_WIDTH = 1; // Width of the auser signal (see OBI documentation): not used by the CV32E40X + parameter int unsigned WUSER_WIDTH = 1; // Width of the wuser signal (see OBI documentation): not used by the CV32E40X + parameter int unsigned ACHK_WIDTH = 1; // Width of the achk signal (see OBI documentation): not used by the CV32E40X + parameter int unsigned RUSER_WIDTH = 1; // Width of the ruser signal (see OBI documentation): not used by the CV32E40X + parameter int unsigned RCHK_WIDTH = 1; // Width of the rchk signal (see OBI documentation): not used by the CV32E40X + parameter int unsigned AID_WIDTH = 1; // Width of the aid signal (address channel identifier, see OBI documentation) + parameter int unsigned RID_WIDTH = 1; // Width of the rid signal (response channel identifier, see OBI documentation) + parameter int unsigned MID_WIDTH = 1; // Width of the mid signal (manager identifier, see OBI documentation) + parameter int unsigned OBI_ID_WIDTH = 1; + parameter int unsigned N_CLUSTER_CORES = 8; // Width of the id - configuration + parameter int unsigned N_SBR = 7; // Number of OBI slaves (HCI, AXI XBAR, RedMulE_Ctrl, iDMA_Ctrl, FSync_Ctrl, Event_Unit, Spatz_Ctrl) parameter int unsigned N_MGR = 3 + N_CLUSTER_CORES; // Number of masters (Core, AXI XBAR, Spatz CC) parameter int unsigned N_MAX_TRAN = 1; // Number of maximum outstanding transactions -`ifdef CV32E40X - parameter int unsigned N_ADDR_RULE = 6; // Number of address rules (L2, L1, Stack, Reserved, Event_Unit, Tile_CSR) -`else - parameter int unsigned N_ADDR_RULE = 9; // Number of OBI address rules (L2, L1, Stack, Reserved, RedMulE_Ctrl, iDMA_Ctrl, FSync_Ctrl, Event_Unit, Tile_CSR) -`endif + parameter int unsigned N_ADDR_RULE = 9; // Number of OBI address rules (L2, L1, Stack, Reserved, RedMulE_Ctrl, iDMA_Ctrl, FSync_Ctrl, Event_Unit, Spatz_Ctrl) localparam int unsigned N_BIT_SBR = $clog2(N_SBR); // Number of bits required to identify each slave localparam int unsigned N_BIT_MGR = $clog2(N_MGR); // Number of bits required to identify each master - localparam int unsigned N_BIT_CLUSTER_CORES = $clog2(N_CLUSTER_CORES); // Number of bits required to identify each core in the cluster + localparam int unsigned N_BIT_CLUSTER_CORES = $clog2(N_CLUSTER_CORES); // Number of bits required to identify each slave + // Parameters used by AXI parameter int unsigned AXI_DATA_ID_W = 3; // Width of the AXI Data ID (3 bits for 5 slave ports on crossbar: 2^3=8) parameter int unsigned AXI_INSTR_ID_W = 3; // Width of the AXI Instruction ID (3 bits for 5 slave ports on crossbar) @@ -373,85 +352,7 @@ package magia_tile_pkg; OBI2AXI = 1'b1 } idma_transfer_ch_e; // iDMA type of transfer channel - // Parameters used by the Xif Instruction Dispatcher - parameter int unsigned N_COPROC = 4; // RedMulE, iDMA, Fractal Sync and FPU - parameter int unsigned N_RULES = N_COPROC-1; // RedMulE, iDMA and Fractal Sync all have custom Xif instructions but not FPU - parameter int unsigned N_REDMULE_SIGN = 9; // Number of signitures (= {opcode, func3}) in the programming model of RedMulE - parameter int unsigned N_IDMA_SIGN = 5; // Number of signitures (= {opcode, func3}) in the programming model of the iDMA decoder - parameter int unsigned N_FSYNC_SIGN = 1; // Number of signitures (= {opcode, func3}) in the programming model of Fractal Sync - parameter int unsigned N_SIGN = 9; // Number of opcodes = max{RedMulE_signitures, iDMA_signitures, FractalSync_signitures} - typedef enum logic[1:0]{ - XIF_REDMULE_IDX = 2'b00, - XIF_IDMA_IDX = 2'b01, - XIF_FSYNC_IDX = 2'b10, - XIF_FPU_IDX = 2'b11 - } xif_inst_dispatch_idx_e; - parameter int unsigned DEFAULT_IDX = XIF_FPU_IDX; // FPU will handle the instructions by default - parameter int unsigned OPCODE_W = 7; // ISA OPCODE Width - parameter int unsigned OPCODE_OFF = 0; // ISA OPCODE Offset - parameter int unsigned FUNC3_W = 3; // ISA FUNC3 Width - parameter int unsigned FUNC3_OFF = 12; // ISA FUNC3 Offset - parameter int unsigned SIGN_W = OPCODE_W + FUNC3_W; // Width of the instruction signiture - parameter bit PRIORITY = 0; // Indicates that the dispatcher should rout the instruction to only 1 coprocessor (with highest priority) - - // Parameters used by the iDMA instruction decoder - parameter int unsigned DMA_INSTR_W = magia_pkg::INSTR_W; // iDMA Decoder instruction width - parameter int unsigned DMA_DATA_W = magia_pkg::DATA_W; // iDMA Decoder data width - parameter int unsigned DMA_ADDR_W = magia_pkg::ADDR_W; // iDMA Decoder address width - parameter int unsigned DMA_N_RF_PORTS = X_NUM_RS; // iDMA Decoder number of register file read ports - parameter int unsigned DMA_OPCODE_W = OPCODE_W; // iDMA Decoder OPCODE field width - parameter int unsigned DMA_FUNC3_W = FUNC3_W; // iDMA Decoder FUNC3 field width - parameter int unsigned DMA_ND_EN_W = 2; // iDMA Decoder ND_EN field width - parameter int unsigned DMA_DST_MAX_LOG_LEN_W = 3; // iDMA Decoder DST_MAX_LOG_LEN field width - parameter int unsigned DMA_SRC_MAX_LOG_LEN_W = 3; // iDMA Decoder SRC_MAX_LOG_LEN field width - parameter int unsigned DMA_DST_REDUCE_LEN_W = 1; // iDMA Decoder DST_REDUCE_LEN field width - parameter int unsigned DMA_SRC_REDUCE_LEN_W = 1; // iDMA Decoder SRC_REDUCE_LEN field width - parameter int unsigned DMA_DECOUPLE_R_W_W = 1; // iDMA Decoder DECOUPLE_R_W field width - parameter int unsigned DMA_DECOUPLE_R_AW_W = 1; // iDMA Decoder DECOUPLE_R_AW field width - parameter int unsigned DMA_DIRECTION_W = 1; // iDMA Decoder DIRECTION field width - parameter int unsigned DMA_OPCODE_OFF = OPCODE_OFF; // iDMA Decoder OPCODE field offset - parameter int unsigned DMA_FUNC3_OFF = FUNC3_OFF; // iDMA Decoder FUNC3 field offset - parameter int unsigned DMA_ND_EN_OFF = 26; // iDMA Decoder ND_EN field offset - parameter int unsigned DMA_DST_MAX_LOG_LEN_OFF = 22; // iDMA Decoder DST_MAX_LOG_LEN field offset - parameter int unsigned DMA_SRC_MAX_LOG_LEN_OFF = 19; // iDMA Decoder SRC_MAX_LOG_LEN field offset - parameter int unsigned DMA_DST_REDUCE_LEN_OFF = 18; // iDMA Decoder DST_REDUCE_LEN field offset - parameter int unsigned DMA_SRC_REDUCE_LEN_OFF = 17; // iDMA Decoder SRC_REDUCE_LEN field offset - parameter int unsigned DMA_DECOUPLE_R_W_OFF = 16; // iDMA Decoder DECOUPLE_R_W field offset - parameter int unsigned DMA_DECOUPLE_R_AW_OFF = 15; // iDMA Decoder DECOUPLE_R_AW field offset - parameter int unsigned DMA_DIRECTION_OFF = 25; // iDMA Decoder DIRECTION field offset - parameter int unsigned DMA_N_CFG_REG = 10; // iDMA Decoder number of configuration registers of the iDMA forntend: CONF, DST_ADDR, SRC_ADDR, LENGTH, DST_STRIDE_2, SRC_STRIDE_2, REPS_2, DST_STRIDE_3, SRC_STRIDE_3, REPS_3 - parameter int unsigned DMA_CONF_IDX = 0; // iDMA Decoder CONF cofiguration register index - parameter int unsigned DMA_DST_ADDR_IDX = 1; // iDMA Decoder DST_ADDR cofiguration register index - parameter int unsigned DMA_SRC_ADDR_IDX = 2; // iDMA Decoder SRC_ADDR cofiguration register index - parameter int unsigned DMA_LENGTH_IDX = 3; // iDMA Decoder LENGTH cofiguration register index - parameter int unsigned DMA_DST_STRIDE_2_IDX = 4; // iDMA Decoder DST_STRIDE_2 cofiguration register index - parameter int unsigned DMA_SRC_STRIDE_2_IDX = 5; // iDMA Decoder SRC_STRIDE_2 cofiguration register index - parameter int unsigned DMA_REPS_2_IDX = 6; // iDMA Decoder REPS_2 configuration register index - parameter int unsigned DMA_DST_STRIDE_3_IDX = 7; // iDMA Decoder DST_STRIDE_3 cofiguration register index - parameter int unsigned DMA_SRC_STRIDE_3_IDX = 8; // iDMA Decoder SRC_STRIDE_3 cofiguration register index - parameter int unsigned DMA_REPS_3_IDX = 9; // iDMA Decoder REPS_3 configuration register index - parameter logic[DMA_OPCODE_W-1:0] CONF_OPCODE = 7'b101_1011; // iDMA Decoder CONF instruction OPCODE - parameter logic[ DMA_FUNC3_W-1:0] CONF_FUNC3 = 3'b000; // iDMA Decoder CONF instruction FUNC3 - parameter logic[DMA_OPCODE_W-1:0] SET_OPCODE = 7'b111_1011; // iDMA Decoder SET (ADDR/LEN, STD_2/REP_2, STD_3/REP_3, START) instruction OPCODE - parameter logic[ DMA_FUNC3_W-1:0] SET_AL_FUNC3 = 3'b000; // iDMA Decoder ADDR/LEN instruction FUNC3 - parameter logic[ DMA_FUNC3_W-1:0] SET_SR2_FUNC3 = 3'b001; // iDMA Decoder STD_2/REP_2 instruction FUNC3 - parameter logic[ DMA_FUNC3_W-1:0] SET_SR3_FUNC3 = 3'b010; // iDMA Decoder STD_3/REP_3 instruction FUNC3 - parameter logic[ DMA_FUNC3_W-1:0] SET_S_FUNC3 = 3'b111; // iDMA Decoder START instruction FUNC3 - - // Parameters used by the Fractal Sync instruction decoder - parameter int unsigned FSYNC_INSTR_W = magia_pkg::INSTR_W; // Fractal Sync Decoder instruction width - parameter int unsigned FSYNC_DATA_W = magia_pkg::DATA_W; // Fractal Sync Decoder data width - parameter int unsigned FSYNC_ADDR_W = magia_pkg::ADDR_W; // Fractal Sync Decoder address width - parameter int unsigned FSYNC_N_RF_PORTS = X_NUM_RS; // Fractal Sync Decoder number of register file read ports - parameter int unsigned FSYNC_OPCODE_W = OPCODE_W; // Fractal Sync Decoder OPCODE field width - parameter int unsigned FSYNC_FUNC3_W = FUNC3_W; // Fractal Sync Decoder FUNC3 field width - parameter int unsigned FSYNC_OPCODE_OFF = OPCODE_OFF; // Fractal Sync Decoder OPCODE field offset - parameter int unsigned FSYNC_FUNC3_OFF = FUNC3_OFF; // Fractal Sync Decoder FUNC3 field offset - parameter int unsigned FSYNC_N_CFG_REG = 2; // Fractal Sync Decoder number of configuration registers: AGGR, ID - parameter int unsigned FSYNC_AGGR_IDX = 0; // Fractal Sync Decoder AGGR cofiguration register index - parameter int unsigned FSYNC_ID_IDX = 1; // Fractal Sync Decoder ID cofiguration register index - parameter logic[FSYNC_OPCODE_W-1:0] FSYNC_OPCODE = 7'b101_1011; // Fractal Sync Decoder instruction OPCODE - parameter logic[ FSYNC_FUNC3_W-1:0] FSYNC_FUNC3 = 3'b010; // Fractal Sync Decoder instruction FUNC3 + // Parameters used by Fractal Sync (memory-mapped interface) parameter int unsigned FSYNC_AGGR_W = magia_pkg::TILE_FSYNC_AGGR_W; // Fractal Sync Aggr. width for non-neighbor nodes parameter int unsigned FSYNC_LVL_W = magia_pkg::TILE_FSYNC_LVL_W; // Fractal Sync Level width for non-neighbor nodes parameter int unsigned FSYNC_ID_W = magia_pkg::TILE_FSYNC_ID_W; // Fractal Sync Id width for non-neighbor nodes @@ -507,7 +408,7 @@ package magia_tile_pkg; parameter int unsigned CLUSTER_FILL_DW = magia_pkg::DATA_W; // i$ Fill interface data width. Power of two; >= 8. // Parameters used by the FPU - parameter bit FPU_ZFINX = 1; // FPU use Zfinx extension instead of the F ISA extention + parameter bit ZFINX_CV32E40X = 0; // fpu_ss uses the F ISA extension, not Zfinx: CV32E40X is built with rv32imafc parameter int unsigned FPU_BUFFER_DEPTH = 8; // FPU FIFO depth that buffers instructions coming from core parameter bit FPU_BUFFER_FT = 0; // FPU FIFO fall through that buffers instructions coming from core parameter bit FPU_OOO = 1; // FPU enable out-of-order execution @@ -559,41 +460,47 @@ package magia_tile_pkg; logic err; } core_instr_rsp_t; -`ifdef CV32E40X typedef struct packed { logic req; logic[magia_pkg::ADDR_W-1:0] addr; - logic[5 :0] atop; logic[3 :0] be; - logic[1 :0] memtype; - logic[2 :0] prot; - logic dbg; logic[magia_pkg::DATA_W-1:0] wdata; logic we; - } core_data_req_t; + } cv32e40p_core_data_req_t; typedef struct packed { logic gnt; logic rvalid; logic[magia_pkg::DATA_W-1:0] rdata; logic err; - logic exokay; - } core_data_rsp_t; -`else + } cv32e40p_core_data_rsp_t; + typedef struct packed { logic req; logic[magia_pkg::ADDR_W-1:0] addr; + logic[5 :0] atop; logic[3 :0] be; + logic[1 :0] memtype; + logic[2 :0] prot; + logic dbg; logic[magia_pkg::DATA_W-1:0] wdata; logic we; - } core_data_req_t; + } cv32e40x_core_data_req_t; typedef struct packed { logic gnt; logic rvalid; logic[magia_pkg::DATA_W-1:0] rdata; logic err; - } core_data_rsp_t; + logic exokay; + } cv32e40x_core_data_rsp_t; + +`ifdef CV32E40X + typedef cv32e40x_core_data_req_t core_data_req_t; + typedef cv32e40x_core_data_rsp_t core_data_rsp_t; +`else + typedef cv32e40p_core_data_req_t core_data_req_t; + typedef cv32e40p_core_data_rsp_t core_data_rsp_t; `endif // EU Direct Link interface types @@ -624,16 +531,6 @@ package magia_tile_pkg; logic[NR_FETCH_PORTS-1:0] rerror; } core_cache_instr_rsp_t; -`ifdef CV32E40X - typedef enum logic[2:0]{ - OBI_XBAR_STACK_IDX = 5, - OBI_XBAR_TILE_CSR_IDX = 4, - OBI_XBAR_EVENT_UNIT_IDX = 3, - OBI_XBAR_RESERVED_IDX = 2, - OBI_XBAR_L1SPM_IDX = 1, - OBI_XBAR_L2_IDX = 0 - } obi_mem_array_idx_e; -`else typedef enum logic[3:0]{ OBI_XBAR_STACK_IDX = 8, OBI_XBAR_RESERVED_IDX = 7, @@ -645,7 +542,6 @@ package magia_tile_pkg; OBI_XBAR_L1SPM_IDX = 1, OBI_XBAR_L2_IDX = 0 } obi_mem_array_idx_e; -`endif typedef enum logic[2:0]{ AXI_XBAR_STACK_IDX = 4, @@ -670,9 +566,6 @@ package magia_tile_pkg; AXI_MST_BOOTROM_IDX = 2 } axi_xbar_mst_idx_e; - typedef struct packed { - logic[N_SIGN-1:0][SIGN_W-1:0] sign_list; - } xif_inst_rule_t; typedef logic[iDMA_AddrWidth-1:0] idma_addr_t; diff --git a/hw/tile/xif_inst_dispatcher.sv b/hw/tile/xif_inst_dispatcher.sv deleted file mode 100644 index c82fb6c6..00000000 --- a/hw/tile/xif_inst_dispatcher.sv +++ /dev/null @@ -1,204 +0,0 @@ -/* - * Copyright (C) 2023-2024 ETH Zurich and University of Bologna - * - * Licensed under the Solderpad Hardware License, Version 0.51 - * (the "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * SPDX-License-Identifier: SHL-0.51 - * - * Authors: Victor Isachi - * - * Xif Instruction Dispatcher - */ - -module xif_inst_dispatcher - import magia_tile_pkg::*; - import cv32e40x_pkg::*; -#( - parameter int unsigned N_COPROC = magia_tile_pkg::N_COPROC, - parameter int unsigned N_RULES = magia_tile_pkg::N_RULES, - parameter int unsigned N_SIGN = magia_tile_pkg::N_SIGN, - parameter int unsigned DEFAULT_IDX = magia_tile_pkg::DEFAULT_IDX, - parameter int unsigned OPCODE_OFF = magia_tile_pkg::OPCODE_OFF, - parameter int unsigned FUNC3_OFF = magia_tile_pkg::FUNC3_OFF, - parameter int unsigned OPCODE_W = magia_tile_pkg::OPCODE_W, - parameter int unsigned FUNC3_W = magia_tile_pkg::FUNC3_W, - parameter int unsigned SIGN_W = magia_tile_pkg::SIGN_W, - parameter type xif_inst_rule_t = magia_tile_pkg::xif_inst_rule_t -)( - input logic clk_i, - input logic rst_ni, - - cv32e40x_if_xif.coproc_issue xif_issue_if_i, - cv32e40x_if_xif.cpu_issue xif_issue_if_o[N_COPROC], - - cv32e40x_if_xif.coproc_result xif_result_if_o, - cv32e40x_if_xif.cpu_result xif_result_if_i, - - input magia_tile_pkg::xif_inst_rule_t[N_RULES-1:0] rules_i -); - -/*******************************************************/ -/** Parameters and Definitions Beginning **/ -/*******************************************************/ - - // IMPORTANT NOTE: must mirror what is found in cv32e40x_if_xif.sv - typedef struct packed { - logic accept; - logic writeback; - logic dualwrite; - logic[2:0] dualread; - logic loadstore; - logic ecswrite ; - logic exc; - } x_issue_resp_t; - - typedef enum logic[1:0] { - IDLE, - WAIT, - PROP - } result_state_e; - -/*******************************************************/ -/** Parameters and Definitions End **/ -/*******************************************************/ -/** Internal Signals Beginning **/ -/*******************************************************/ - - logic[OPCODE_W-1:0] opcode; - logic[ FUNC3_W-1:0] func3; - logic[ SIGN_W-1:0] sign; - logic[N_COPROC-1:0] coproc_sign; // Indicates which coprocessor expects detected signiture - logic[N_COPROC-1:0] coproc_issue; // Indicates to which coprocessor the instruction should be dispatched - logic[N_COPROC-1:0] coproc_issue_pr; // Priority encoded version of the above signal: used to ensure the instruction is dispatched to only 1 coprocessor - logic default_issue; // Indicates that the instruction should be dispatched to the default coprocessor - - logic [N_COPROC-1:0] issue_ready; - x_issue_resp_t[N_COPROC-1:0] issue_resp; - - result_state_e c_result_state, n_result_state; - -/*******************************************************/ -/** Internal Signals End **/ -/*******************************************************/ -/** Hardwired Signals Beginning **/ -/*******************************************************/ - - assign opcode = xif_issue_if_i.issue_req.instr[OPCODE_OFF+OPCODE_W-1:OPCODE_OFF]; - assign func3 = xif_issue_if_i.issue_req.instr[ FUNC3_OFF+FUNC3_W-1:FUNC3_OFF]; - assign sign = {opcode, func3}; - assign default_issue = ~(|coproc_sign); - assign coproc_issue = default_issue ? (1 << DEFAULT_IDX) : coproc_sign; - -/*******************************************************/ -/** Hardwired Signals End **/ -/*******************************************************/ -/** IF to Struct Beginning **/ -/*******************************************************/ - - for (genvar i = 0; i < N_COPROC; i++) begin: gen_if2signal - assign issue_ready[i] = xif_issue_if_o[i].issue_ready; - assign issue_resp[i].accept = xif_issue_if_o[i].issue_resp.accept; - assign issue_resp[i].writeback = xif_issue_if_o[i].issue_resp.writeback; - assign issue_resp[i].dualwrite = xif_issue_if_o[i].issue_resp.dualwrite; - assign issue_resp[i].dualread = xif_issue_if_o[i].issue_resp.dualread; - assign issue_resp[i].loadstore = xif_issue_if_o[i].issue_resp.loadstore; - assign issue_resp[i].ecswrite = xif_issue_if_o[i].issue_resp.ecswrite; - assign issue_resp[i].exc = xif_issue_if_o[i].issue_resp.exc; - end - -/*******************************************************/ -/** IF to Struct End **/ -/*******************************************************/ -/** Instruction Dispatcher Beginning **/ -/*******************************************************/ - - always_comb begin: sign_detector - for (int i = 0; i < N_COPROC; i++) begin - coproc_sign[i] = 1'b0; - if (i < N_RULES) begin // Only check first N_RULES coprocessors, the rest do not have associated rule - for (int j = 0; j < N_SIGN; j++) begin - coproc_sign[i] |= (sign == rules_i[i].sign_list[j]) ? 1'b1 : 1'b0; - end - end - end - end - - always_comb begin: priority_encoder - coproc_issue_pr = '0; - for (int i = 0; i < N_COPROC; i++) begin - if (coproc_issue[i]) begin - coproc_issue_pr = 1 << i; - break; - end - end - end - - for (genvar i = 0; i < N_COPROC; i++) begin: gen_issue_out - always_comb begin - if (coproc_issue_pr[i]) begin - xif_issue_if_o[i].issue_valid = xif_issue_if_i.issue_valid; - xif_issue_if_o[i].issue_req = xif_issue_if_i.issue_req; - end else begin - xif_issue_if_o[i].issue_valid = '0; - xif_issue_if_o[i].issue_req = '0; - end - end - end - - always_comb begin: issue_in - xif_issue_if_i.issue_ready = '0; - xif_issue_if_i.issue_resp = '0; - for (int i = 0; i < N_COPROC; i++) begin - if (coproc_issue_pr[i]) begin - xif_issue_if_i.issue_ready = issue_ready[i]; - xif_issue_if_i.issue_resp.accept = issue_resp[i].accept; - xif_issue_if_i.issue_resp.writeback = issue_resp[i].writeback; - xif_issue_if_i.issue_resp.dualwrite = issue_resp[i].dualwrite; - xif_issue_if_i.issue_resp.dualread = issue_resp[i].dualread; - xif_issue_if_i.issue_resp.loadstore = issue_resp[i].loadstore; - xif_issue_if_i.issue_resp.ecswrite = issue_resp[i].ecswrite; - xif_issue_if_i.issue_resp.exc = issue_resp[i].exc; - break; - end - end - end - - always_ff @(posedge clk_i, negedge rst_ni) begin: result_state_register - if (!rst_ni) c_result_state <= IDLE; - else c_result_state <= n_result_state; - end - - always_comb begin: result_state_logic - n_result_state = c_result_state; - case (c_result_state) - IDLE: if (!default_issue) n_result_state = WAIT; - WAIT: if (xif_result_if_o.result_ready) n_result_state = PROP; - PROP: if (!xif_result_if_o.result_ready) n_result_state = default_issue ? IDLE : WAIT; - endcase - end - - always_comb begin: result_handler - xif_result_if_o.result_valid = xif_result_if_i.result_valid; - xif_result_if_i.result_ready = xif_result_if_o.result_ready; - xif_result_if_o.result = xif_result_if_i.result; - if (c_result_state == PROP) begin - xif_result_if_o.result_valid = xif_result_if_o.result_ready; - xif_result_if_i.result_ready = 1'b0; - xif_result_if_o.result = '0; - end - end - -/*******************************************************/ -/** Instruction Dispatcher End **/ -/*******************************************************/ - -endmodule: xif_inst_dispatcher \ No newline at end of file diff --git a/setup_env.sh b/setup_env.sh index 21a963f6..9eb40bc2 100644 --- a/setup_env.sh +++ b/setup_env.sh @@ -10,13 +10,15 @@ export PATH=$BENDER_DIR:$PATH unset BENDER_DIR echo "Exporting SDK and GCC Toolchain paths" export XLEN=32 -if [[ "$core" == "CV32E40P" ]] || [[ "$core" == "RI5CY" ]]; then - echo "Exporting ISA extentions: I, M, C, PULP" - export XTEN=imfc +if [[ "$core" == "CV32E40X" ]]; then + echo "Exporting control core (CV32E40X) ISA extensions: I, M, A, F, C" + export CTRL_XTEN=imafc else - echo "Exporting ISA extentions: I, M, A, F, C" - export XTEN=imafc + echo "Exporting control core (CV32E40P) ISA extensions: I, M, C, PULP (Zfinx)" + export CTRL_XTEN=imc_xcvalu_xcvbi_xcvbitmanip_xcvhwlp_xcvmac_xcvmem_xcvsimd_xcvelw_zfinx_zhinxmin fi +echo "Exporting PULP cluster core (CV32E40P) ISA extensions: I, M, C, PULP (Zfinx)" +export CLUSTER_XTEN=imc_xcvalu_xcvbi_xcvbitmanip_xcvhwlp_xcvmac_xcvmem_xcvsimd_xcvelw_zfinx_zhinxmin echo "Sourcing python virtual environment" source ./magia_venv/bin/activate echo "Finished setting up the environment" \ No newline at end of file diff --git a/sw/kernel_pulp/Makefile b/sw/kernel_pulp/Makefile index 47b04cac..f426dfb5 100644 --- a/sw/kernel_pulp/Makefile +++ b/sw/kernel_pulp/Makefile @@ -29,29 +29,12 @@ ARCH ?= rv XLEN ?= 32 core ?= CV32E40P -ifeq ($(core), CV32E40X) - XTEN := imafc - CC = $(ISA)$(XLEN)-unknown-elf-gcc - OBJCOPY = $(ISA)$(XLEN)-unknown-elf-objcopy - OBJDUMP = $(ISA)$(XLEN)-unknown-elf-objdump - XABI :=f - ABI := ilp -else ifeq ($(core), RI5CY) - XTEN := imcxgap9 - CC = riscv$(XLEN)-unknown-elf-gcc - OBJCOPY = riscv$(XLEN)-unknown-elf-objcopy - OBJDUMP = riscv$(XLEN)-unknown-elf-objdump - XABI := - ABI := ilp -else - # CV32E40P with ZFINX=1 (FP ops on GPRs) — see top Makefile. - XTEN := imc_xcvalu_xcvbi_xcvbitmanip_xcvhwlp_xcvmac_xcvmem_xcvsimd_xcvelw_zfinx_zhinxmin - CC = riscv64-unknown-elf-gcc - OBJCOPY = riscv64-unknown-elf-objcopy - OBJDUMP = riscv64-unknown-elf-objdump - XABI := - ABI := ilp -endif +XTEN := imc_xcvalu_xcvbi_xcvbitmanip_xcvhwlp_xcvmac_xcvmem_xcvsimd_xcvelw_zfinx_zhinxmin +CC = riscv64-unknown-elf-gcc +OBJCOPY = riscv64-unknown-elf-objcopy +OBJDUMP = riscv64-unknown-elf-objdump +XABI := +ABI := ilp TEST_NAME ?= base_pulp_test task ?= @@ -72,7 +55,7 @@ ARCH_FLAGS = -march=$(ARCH)$(XLEN)$(XTEN) -mabi=$(ABI)$(XLEN)$(XABI) # is never fixed up: the indirect jump lands in unmapped space and the # cluster icache stalls forever on a fill that loops in the NoC. # Forcing compare-chains keeps every branch PC-relative (PIC-safe). -# Affects all cores (CV32E40P/RI5CY) and both mesh_dv settings. +# Affects both mesh_dv settings. CFLAGS = $(ARCH_FLAGS) -O2 -g -Wall -Wextra -Wno-unused-parameter \ -Wno-unused-variable -Wno-unused-function -Wundef \ -ffunction-sections -fdata-sections \ @@ -83,13 +66,6 @@ CFLAGS = $(ARCH_FLAGS) -O2 -g -Wall -Wextra -Wno-unused-parameter \ -DPULP_CORE_COUNT=$(PULP_CORE_COUNT) \ -D$(core) -U__riscv__ CFLAGS += -I../utils -I../../hw/include -I. -# RI5CY toolchain (riscv32-unknown-elf-gcc / gap9 binutils) uses an older -# assembler that does not recognise the 3-operand FLW pseudo-instruction -# `flw rd, symbol, rt` emitted by newer gcc when rv32*f* is in the march. -# -mexplicit-relocs forces gcc to emit lui+flw(%hi/%lo) instead. -ifeq ($(core), RI5CY) -CFLAGS += -mexplicit-relocs -endif LDFLAGS = $(ARCH_FLAGS) -nostartfiles -nostdlib \ -Wl,--gc-sections -Wl,--allow-multiple-definition \ diff --git a/sw/tests/cluster_tests/hello_pulp/main.c b/sw/tests/cluster_tests/hello_pulp/main.c index c33bed62..f97cacf7 100644 --- a/sw/tests/cluster_tests/hello_pulp/main.c +++ b/sw/tests/cluster_tests/hello_pulp/main.c @@ -43,18 +43,7 @@ static inline uint32_t get_hartid(void) { uint32_t hartid; asm volatile("csrr %0, mhartid" :"=r"(hartid):); - #ifndef RI5CY - return hartid; - #else - // RI5CY mhartid CSR: { 21'b0, cluster_id_i[5:0], 1'b0, core_id_i[3:0] } - // cluster_id_i = mhartid_tile + 1 (which tile/cluster, 1-indexed; 0 = standalone main core) - // core_id_i = i (which core within the cluster, 0-indexed) - uint32_t cluster_id = (hartid >> 5) & 0x3F; // = tile_hartid + 1 (same for all cores in a tile) - uint32_t core_id = hartid & 0xF; // = i (unique per core within tile) - if (cluster_id == 0) - return core_id; // standalone main tile core - return PULP_HARTID_BASE + (cluster_id - 1) * PULP_CORE_COUNT + core_id; - #endif + return hartid; } int main(void) { diff --git a/sw/tests/cluster_tests/hello_pulp/pulp_task/hello_pulp_task.c b/sw/tests/cluster_tests/hello_pulp/pulp_task/hello_pulp_task.c index 4abe95da..4cd12428 100644 --- a/sw/tests/cluster_tests/hello_pulp/pulp_task/hello_pulp_task.c +++ b/sw/tests/cluster_tests/hello_pulp/pulp_task/hello_pulp_task.c @@ -36,18 +36,7 @@ static inline uint32_t get_hartid(void) { uint32_t hartid; asm volatile("csrr %0, mhartid" :"=r"(hartid):); - #ifndef RI5CY - return hartid; - #else - // RI5CY mhartid CSR: { 21'b0, cluster_id_i[5:0], 1'b0, core_id_i[3:0] } - // cluster_id_i = mhartid_tile + 1 (which tile/cluster, 1-indexed; 0 = standalone main core) - // core_id_i = i (which core within the cluster, 0-indexed) - uint32_t cluster_id = (hartid >> 5) & 0x3F; // = tile_hartid + 1 (same for all cores in a tile) - uint32_t core_id = hartid & 0xF; // = i (unique per core within tile) - if (cluster_id == 0) - return core_id; // standalone main tile core - return PULP_HARTID_BASE + (cluster_id - 1) * PULP_CORE_COUNT + core_id; - #endif + return hartid; } void hello_pulp_task(void *data) { diff --git a/sw/tests/fpu_test.c b/sw/tests/fpu_test.c index 70019034..20ab7ff0 100644 --- a/sw/tests/fpu_test.c +++ b/sw/tests/fpu_test.c @@ -24,15 +24,15 @@ #define A_VAL (12.34f) #define B_VAL (56.78f) #define C_EXP (69.12f) +#define F_EXP 0x428A3D70 #ifdef CV32E40P #define FP_TH (1e-45f) #else -#ifdef RI5CY -#define FP_TH (8e-6f) -#endif +#define FP_TH (0.1f) #endif + #define abs_diff(x, y) (((x) > (y)) ? ((x) - (y)) : ((y) - (x))) inline uint32_t f_add(volatile uint32_t op_a, volatile uint32_t op_b){ @@ -60,11 +60,11 @@ int main(void) { printf("Test PASSED\n"); } #else - uint32_t a, b, c; - a = 0x414570A4; // Binary for 12.34f - b = 0x42631EB8; // Binary for 56.78f - c = f_add(a, b); - printf("Float operation result: 0x%0x [expected: 0x428A3D71(69.12f)]\n", c); + uint32_t D, E, F; + D = 0x414570A4; // Binary for 12.34f + E = 0x42631EB8; // Binary for 56.78f + F = f_add(D, E); + printf("Float operation result: 0x%08x [expected: 0x%08x]\n", F, F_EXP); #endif return error; diff --git a/sw/tests/xif_tests/fsync_extended_test.c b/sw/tests/xif_tests/fsync_extended_test.c deleted file mode 100644 index 4a1064f9..00000000 --- a/sw/tests/xif_tests/fsync_extended_test.c +++ /dev/null @@ -1,131 +0,0 @@ -/* - * Copyright (C) 2023-2024 ETH Zurich and University of Bologna - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * SPDX-License-Identifier: Apache-2.0 - * - * Authors: Victor Isachi - * - * MAGIA Extended FractalSync Synchronization Test - */ - -#include "magia_tile_utils.h" -#include "magia_utils.h" -#include "fsync_isa_utils.h" -#include "fsync_api.h" -#include "event_unit_utils.h" -#include "cache_fill.h" - -#define VERBOSE (0) - -int main(void) { - uint32_t aggregates[NUM_HARTS]; - uint32_t ids[NUM_HARTS]; - - // Initialize Event Unit once - eu_init(); - -#if NUM_HARTS == 16 - /// Custom 4x4 synch. - switch (get_hartid()){ - case 0: aggregates[get_hartid()] = 0b1111; ids[get_hartid()] = 7; break; - case 1: aggregates[get_hartid()] = 0b1111; ids[get_hartid()] = 7; break; - case 2: aggregates[get_hartid()] = 0b1111; ids[get_hartid()] = 7; break; - case 3: aggregates[get_hartid()] = 0b1111; ids[get_hartid()] = 7; break; - case 4: aggregates[get_hartid()] = 0b1111; ids[get_hartid()] = 7; break; - case 5: aggregates[get_hartid()] = 0b1111; ids[get_hartid()] = 7; break; - case 6: aggregates[get_hartid()] = 0b1111; ids[get_hartid()] = 7; break; - case 7: aggregates[get_hartid()] = 0b1111; ids[get_hartid()] = 7; break; - case 8: aggregates[get_hartid()] = 0b1111; ids[get_hartid()] = 7; break; - case 9: aggregates[get_hartid()] = 0b1111; ids[get_hartid()] = 7; break; - case 10: aggregates[get_hartid()] = 0b1111; ids[get_hartid()] = 7; break; - case 11: aggregates[get_hartid()] = 0b1111; ids[get_hartid()] = 7; break; - case 12: aggregates[get_hartid()] = 0b1111; ids[get_hartid()] = 7; break; - case 13: aggregates[get_hartid()] = 0b1111; ids[get_hartid()] = 7; break; - case 14: aggregates[get_hartid()] = 0b1111; ids[get_hartid()] = 7; break; - case 15: aggregates[get_hartid()] = 0b1111; ids[get_hartid()] = 7; break; - } - - printf("FractalSync aggregate: 0x%0x, id: %0d...\n", aggregates[get_hartid()], ids[get_hartid()]); - - // Clear Event Unit and ensure FSync mask is enabled - eu_clear_events(0xFFFFFFFF); - eu_enable_events(EU_FSYNC_DONE_MASK); - - fsync(ids[get_hartid()], aggregates[get_hartid()]); - - eu_fsync_wait_completion(EU_WAIT_MODE_POLLING); - - sentinel_instr_id(); -#endif - - printf("[FractalSync] Horizontal neighbor test starting\n"); - eu_clear_events(0xFFFFFFFF); - eu_enable_events(EU_FSYNC_DONE_MASK); - fsync_hnbr(); - eu_fsync_wait_completion(EU_WAIT_MODE_POLLING); - sentinel_instr_id(); - printf("[FractalSync] Horizontal neighbor test ending\n"); - - printf("[FractalSync] Horizontal ring neighbor test starting\n"); - eu_clear_events(0xFFFFFFFF); - eu_enable_events(EU_FSYNC_DONE_MASK); - fsync_hring(); - eu_fsync_wait_completion(EU_WAIT_MODE_POLLING); - sentinel_instr_id(); - printf("[FractalSync] Horizontal ring neighbor test ending\n"); - - printf("[FractalSync] Vertical neighbor test starting\n"); - eu_clear_events(0xFFFFFFFF); - eu_enable_events(EU_FSYNC_DONE_MASK); - fsync_vnbr(); - eu_fsync_wait_completion(EU_WAIT_MODE_POLLING); - sentinel_instr_id(); - printf("[FractalSync] Vertical neighbor test ending\n"); - - printf("[FractalSync] Vertical ring neighbor test starting\n"); - eu_clear_events(0xFFFFFFFF); - eu_enable_events(EU_FSYNC_DONE_MASK); - fsync_vring(); - eu_fsync_wait_completion(EU_WAIT_MODE_POLLING); - sentinel_instr_id(); - printf("[FractalSync] Vertical ring neighbor test ending\n"); - - printf("[FractalSync] Row test starting\n"); - eu_clear_events(0xFFFFFFFF); - eu_enable_events(EU_FSYNC_DONE_MASK); - fsync_rows(); - eu_fsync_wait_completion(EU_WAIT_MODE_POLLING); - sentinel_instr_id(); - printf("[FractalSync] Row test ending\n"); - - printf("[FractalSync] Column test starting\n"); - eu_clear_events(0xFFFFFFFF); - eu_enable_events(EU_FSYNC_DONE_MASK); - fsync_cols(); - eu_fsync_wait_completion(EU_WAIT_MODE_POLLING); - sentinel_instr_id(); - printf("[FractalSync] Column test ending\n"); - - printf("[FractalSync] Global test starting\n"); - eu_clear_events(0xFFFFFFFF); - eu_enable_events(EU_FSYNC_DONE_MASK); - fsync_global(); - eu_fsync_wait_completion(EU_WAIT_MODE_POLLING); - sentinel_instr_id(); - printf("[FractalSync] Global test ending\n"); - - printf("FractalSync test finished...\n"); - - return 0; -} \ No newline at end of file diff --git a/sw/tests/xif_tests/fsync_test.c b/sw/tests/xif_tests/fsync_test.c deleted file mode 100644 index 6ca2b6dc..00000000 --- a/sw/tests/xif_tests/fsync_test.c +++ /dev/null @@ -1,286 +0,0 @@ -/* - * Copyright (C) 2023-2024 ETH Zurich and University of Bologna - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * SPDX-License-Identifier: Apache-2.0 - * - * Authors: Victor Isachi - * - * MAGIA FractalSync Synchronization Test - */ - -#include "magia_tile_utils.h" -#include "magia_utils.h" -#include "fsync_isa_utils.h" -#include "fsync_api.h" -#include "event_unit_utils.h" -#include "cache_fill.h" - -#define VERBOSE (0) - -#define CLIB_FS_TEST -// #define GLOBAL_FS_TEST -// #define ROW_FS_TEST -// #define COL_FS_TEST -// #define HNBR_FS_TEST -// #define VNBR_FS_TEST -// #define HRING_FS_TEST -// #define VRING_FS_TEST - -#define NUM_LEVELS (31-__builtin_clz(NUM_HARTS)) - -#define CACHE_HEAT_CYCLES (3) - -int main(void) { - uint32_t tile_hartid = get_hartid(); - uint32_t tile_xhartid = GET_X_ID(tile_hartid); - uint32_t tile_yhartid = GET_Y_ID(tile_hartid); - - // Initialize Event Unit once - eu_init(); - - printf("Starting Fractal Sync test...\n"); - - // Filling up the cache - fill_icache(); - - // Execute synchronization multiple times to pre-heat the cache - for (int i = 0; i < CACHE_HEAT_CYCLES; i++) { -#ifdef CLIB_FS_TEST - // Climb FS tree test - for (int i = 0; i < NUM_LEVELS; i++){ - printf("Fractal Sync at level %0d...\n", i+1); - - uint32_t aggregates = (1 << (i+1))-1; - uint32_t ids = 0; -#if VERBOSE > 10 - printf("aggregate: 0x%0x\n", aggregates); - printf("id: 0x%0x\n", ids); -#endif - - // Instruction immediately preceding synchronization: indicates start of the synchronization region - sentinel_start(); - - eu_clear_events(0xFFFFFFFF); - eu_enable_events(EU_FSYNC_DONE_MASK); - fsync(ids, aggregates); - eu_fsync_wait_completion(EU_WAIT_MODE_POLLING); - - // Instruction immediately following synchronization: indicates end of the synchronization region - sentinel_end(); - - printf("Synchronized...\n"); - } -#endif - -#ifdef GLOBAL_FS_TEST -#if VERBOSE > 1 - printf("Fractal Sync global synchrnonization test...\n"); -#endif - -#if VERBOSE > 10 - printf("aggregate: 0x%0x\n", _FS_GLOBAL_AGGR); - printf("id: 0x%0x\n", _FS_GLOBAL_ID); -#endif - - // Instruction immediately preceding synchronization: indicates start of the synchronization region - sentinel_start(); - - eu_clear_events(0xFFFFFFFF); - eu_enable_events(EU_FSYNC_DONE_MASK); - fsync_global(); - eu_fsync_wait_completion(EU_WAIT_MODE_POLLING); - - // Instruction immediately following synchronization: indicates end of the synchronization region - sentinel_end(); - -#if VERBOSE > 1 - printf("Synchronized...\n"); -#endif -#endif - -#ifdef HNBR_FS_TEST -#if VERBOSE > 1 - printf("Fractal Sync horizontal neighbor synchrnonization test...\n"); -#endif - -#if VERBOSE > 10 - printf("aggregate: 0x%0x\n", _FS_HNBR_AGGR); - printf("id: 0x%0x\n", _FS_HNBR_ID); -#endif - - // Instruction immediately preceding synchronization: indicates start of the synchronization region - sentinel_start(); - - eu_clear_events(0xFFFFFFFF); - eu_enable_events(EU_FSYNC_DONE_MASK); - fsync_hnbr(); - eu_fsync_wait_completion(EU_WAIT_MODE_POLLING); - - // Instruction immediately following synchronization: indicates end of the synchronization region - sentinel_end(); - -#if VERBOSE > 1 - printf("Synchronized...\n"); -#endif -#endif - -#ifdef VNBR_FS_TEST -#if VERBOSE > 1 - printf("Fractal Sync vertical neighbor synchrnonization test...\n"); -#endif - -#if VERBOSE > 10 - printf("aggregate: 0x%0x\n", _FS_VNBR_AGGR); - printf("id: 0x%0x\n", _FS_VNBR_ID); -#endif - - // Instruction immediately preceding synchronization: indicates start of the synchronization region - sentinel_start(); - - eu_clear_events(0xFFFFFFFF); - eu_enable_events(EU_FSYNC_DONE_MASK); - fsync_vnbr(); - eu_fsync_wait_completion(EU_WAIT_MODE_POLLING); - - // Instruction immediately following synchronization: indicates end of the synchronization region - sentinel_end(); - -#if VERBOSE > 1 - printf("Synchronized...\n"); -#endif -#endif - -#ifdef HRING_FS_TEST -#if VERBOSE > 1 - printf("Fractal Sync horizontal ring synchrnonization test...\n"); -#endif - -#if VERBOSE > 10 - if ((tile_xhartid == 0) || (tile_xhartid == MESH_X_TILES-1)){ - uint32_t id = row_id_lookup(tile_yhartid); - printf("aggregate: 0x%0x\n", _FS_RC_LVL); - printf("id: 0x%0x\n", id); - } else { - printf("aggregate: 0x%0x\n", _FS_HRING_AGGR); - printf("id: 0x%0x\n", _FS_HRING_ID); - } -#endif - - // Instruction immediately preceding synchronization: indicates start of the synchronization region - sentinel_start(); - - eu_clear_events(0xFFFFFFFF); - eu_enable_events(EU_FSYNC_DONE_MASK); - fsync_hring(); - eu_fsync_wait_completion(EU_WAIT_MODE_POLLING); - - // Instruction immediately following synchronization: indicates end of the synchronization region - sentinel_end(); - -#if VERBOSE > 1 - printf("Synchronized...\n"); -#endif -#endif - -#ifdef VRING_FS_TEST -#if VERBOSE > 1 - printf("Fractal Sync vertical ring synchrnonization test...\n"); -#endif - -#if VERBOSE > 10 - if ((tile_yhartid == 0) || (tile_yhartid == MESH_Y_TILES-1)){ - uint32_t id = col_id_lookup(tile_xhartid); - printf("aggregate: 0x%0x\n", _FS_RC_LVL); - printf("id: 0x%0x\n", id); - } else { - printf("aggregate: 0x%0x\n", _FS_VRING_AGGR); - printf("id: 0x%0x\n", _FS_VRING_ID); - } -#endif - - // Instruction immediately preceding synchronization: indicates start of the synchronization region - sentinel_start(); - - eu_clear_events(0xFFFFFFFF); - eu_enable_events(EU_FSYNC_DONE_MASK); - fsync_vring(); - eu_fsync_wait_completion(EU_WAIT_MODE_POLLING); - - // Instruction immediately following synchronization: indicates end of the synchronization region - sentinel_end(); - -#if VERBOSE > 1 - printf("Synchronized...\n"); -#endif -#endif - -#ifdef ROW_FS_TEST -#if VERBOSE > 1 - printf("Fractal Sync row synchrnonization test...\n"); -#endif - -#if VERBOSE > 10 - uint32_t id = row_id_lookup(tile_yhartid); - printf("aggregate: 0x%0x\n", _FS_RC_AGGR); - printf("id: 0x%0x\n", id); -#endif - - // Instruction immediately preceding synchronization: indicates start of the synchronization region - sentinel_start(); - - eu_clear_events(0xFFFFFFFF); - eu_enable_events(EU_FSYNC_DONE_MASK); - fsync_rows(); - eu_fsync_wait_completion(EU_WAIT_MODE_POLLING); - - // Instruction immediately following synchronization: indicates end of the synchronization region - sentinel_end(); - -#if VERBOSE > 1 - printf("Synchronized...\n"); -#endif -#endif - -#ifdef COL_FS_TEST -#if VERBOSE > 1 - printf("Fractal Sync column synchrnonization test...\n"); -#endif - -#if VERBOSE > 10 - uint32_t id = col_id_lookup(tile_xhartid); - printf("aggregate: 0x%0x\n", _FS_RC_AGGR); - printf("id: 0x%0x\n", id); -#endif - - // Instruction immediately preceding synchronization: indicates start of the synchronization region - sentinel_start(); - - eu_clear_events(0xFFFFFFFF); - eu_enable_events(EU_FSYNC_DONE_MASK); - fsync_cols(); - eu_fsync_wait_completion(EU_WAIT_MODE_POLLING); - - // Instruction immediately following synchronization: indicates end of the synchronization region - sentinel_end(); - -#if VERBOSE > 1 - printf("Synchronized...\n"); -#endif -#endif - } - - printf("Fractal Sync test finished...\n"); - - return 0; -} diff --git a/sw/tests/xif_tests/idma_test.c b/sw/tests/xif_tests/idma_test.c deleted file mode 100644 index 8f85b7f4..00000000 --- a/sw/tests/xif_tests/idma_test.c +++ /dev/null @@ -1,213 +0,0 @@ -/* - * Copyright (C) 2023-2024 ETH Zurich and University of Bologna - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * SPDX-License-Identifier: Apache-2.0 - * - * Authors: Victor Isachi - * - * MAGIA iDMA Test - */ - -#include "magia_tile_utils.h" -#include "idma_isa_utils.h" -#include "event_unit_utils.h" - -#include "x_input.h" - -#define X_BASE (L1_BASE + 0x00012048) -#define Y_BASE (L1_BASE + 0x00016048) -#define Z_BASE (L2_BASE + 0x00001000) -#define W_BASE (L2_BASE + 0x00005000) - -#define M_SIZE (96) -#define N_SIZE (64) - -#define VERBOSE (0) - -#define WAIT_CYCLES (10) - -#define CONCURRENT - -int main(void) { - uint32_t dst_addr; - uint32_t src_addr; - uint32_t len; - - uint32_t dst_std_2; - uint32_t src_std_2; - uint32_t reps_2; - - uint32_t dst_std_3; - uint32_t src_std_3; - uint32_t reps_3; - - // Initialize Event Unit once - eu_init(); - - // Z - golden (reference) - for (int i = 0; i < M_SIZE*N_SIZE; i++) - mmio16(Z_BASE + 2*i) = x_inp[i]; -#if VERBOSE > 100 - for (int i = 0; i < M_SIZE*N_SIZE; i++) - printf("Z[%8x]: 0x%4x\n", Z_BASE + 2*i, mmio16(Z_BASE + 2*i)); -#endif - - idma_conf_in(); - - dst_addr = (uint32_t)X_BASE; - src_addr = (uint32_t)Z_BASE; - len = (uint32_t)(M_SIZE*N_SIZE*2); // 2 Bytes per element -#if VERBOSE > 10 - printf("dst_addr: 0x%8x (X_BASE)\n", dst_addr); - printf("src_addr: 0x%8x (Z_BASE)\n", src_addr); - printf("len: %0d\n", len); -#endif - idma_set_addr_len_in(dst_addr, src_addr, len); - - dst_std_2 = 0; - src_std_2 = 0; - reps_2 = 1; -#if VERBOSE > 10 - printf("dst_std_2: 0x%8x\n", dst_std_2); - printf("src_std_2: 0x%8x\n", src_std_2); - printf("reps_2: 0x%8x\n", reps_2); -#endif - idma_set_std2_rep2_in(dst_std_2, src_std_2, reps_2); - - dst_std_3 = 0; - src_std_3 = 0; - reps_3 = 1; -#if VERBOSE > 10 - printf("dst_std_3: 0x%8x\n", dst_std_3); - printf("src_std_3: 0x%8x\n", src_std_3); - printf("reps_3: 0x%8x\n", reps_3); -#endif - idma_set_std3_rep3_in(dst_std_3, src_std_3, reps_3); - - eu_clear_events(0xFFFFFFFF); - eu_enable_events(EU_IDMA_A2O_DONE_MASK); - - idma_start_in(); - printf("iDMA moving data from L2 to L1...\n"); - - eu_idma_wait_a2o_completion(EU_WAIT_MODE_POLLING); - - idma_conf_out(); - - dst_addr = (uint32_t)W_BASE; - src_addr = (uint32_t)X_BASE; - len = (uint32_t)(M_SIZE*N_SIZE*2); // 2 Bytes per element -#if VERBOSE > 10 - printf("dst_addr: 0x%8x (W_BASE)\n", dst_addr); - printf("src_addr: 0x%8x (X_BASE)\n", src_addr); - printf("len: %0d\n", len); -#endif - idma_set_addr_len_out(dst_addr, src_addr, len); - - dst_std_2 = 0; - src_std_2 = 0; - reps_2 = 1; -#if VERBOSE > 10 - printf("dst_std_2: 0x%8x\n", dst_std_2); - printf("src_std_2: 0x%8x\n", src_std_2); - printf("reps_2: 0x%8x\n", reps_2); -#endif - idma_set_std2_rep2_out(dst_std_2, src_std_2, reps_2); - - dst_std_3 = 0; - src_std_3 = 0; - reps_3 = 1; -#if VERBOSE > 10 - printf("dst_std_3: 0x%8x\n", dst_std_3); - printf("src_std_3: 0x%8x\n", src_std_3); - printf("reps_3: 0x%8x\n", reps_3); -#endif - idma_set_std3_rep3_out(dst_std_3, src_std_3, reps_3); - -#ifdef CONCURRENT - idma_conf_in(); - - dst_addr = (uint32_t)Y_BASE; - src_addr = (uint32_t)Z_BASE; - len = (uint32_t)(M_SIZE*N_SIZE*2); // 2 Bytes per element -#if VERBOSE > 10 - printf("dst_addr: 0x%8x (Y_BASE)\n", dst_addr); - printf("src_addr: 0x%8x (Z_BASE)\n", src_addr); - printf("len: %0d\n", len); -#endif - idma_set_addr_len_in(dst_addr, src_addr, len); - - dst_std_2 = 0; - src_std_2 = 0; - reps_2 = 1; -#if VERBOSE > 10 - printf("dst_std_2: 0x%8x\n", dst_std_2); - printf("src_std_2: 0x%8x\n", src_std_2); - printf("reps_2: 0x%8x\n", reps_2); -#endif - idma_set_std2_rep2_in(dst_std_2, src_std_2, reps_2); - - dst_std_3 = 0; - src_std_3 = 0; - reps_3 = 1; -#if VERBOSE > 10 - printf("dst_std_3: 0x%8x\n", dst_std_3); - printf("src_std_3: 0x%8x\n", src_std_3); - printf("reps_3: 0x%8x\n", reps_3); -#endif - idma_set_std3_rep3_in(dst_std_3, src_std_3, reps_3); - - eu_clear_events(0xFFFFFFFF); - eu_enable_events(EU_IDMA_ALL_DONE_MASK); - - idma_start_out(); - - idma_start_in(); - - eu_idma_wait_completion(EU_WAIT_MODE_POLLING); - - printf("iDMA moving concurrently data from L1 to L2 and from L2 to L1...\n"); -#else - eu_clear_events(0xFFFFFFFF); - eu_enable_events(EU_IDMA_O2A_DONE_MASK); - - idma_start_out(); - - eu_idma_wait_o2a_completion(EU_WAIT_MODE_POLLING); - - printf("iDMA moving data from L1 to L2...\n"); -#endif - - printf("Verifying results...\n"); - - unsigned int num_errors = 0; - - uint16_t detected_l1, detected_l2, expected; - for(int i = 0; i < M_SIZE*N_SIZE; i++){ - detected_l2 = mmio16(W_BASE + 2*i); -#ifdef CONCURRENT - detected_l1 = mmio16(Y_BASE + 2*i); -#else - detected_l1 = mmio16(X_BASE + 2*i); -#endif - expected = mmio16(Z_BASE + 2*i); - if((detected_l2 != expected) || (detected_l1 != expected)){ - num_errors++; - printf("**ERROR**: DETECTED L2[%0d](=0x%4x) || DETECTED L1[%0d](=0x%4x) != EXPECTED[%0d](=0x%4x)\n", i, detected_l2, i, detected_l1, i, expected); - } - } - printf("Finished test with %0d errors\n", num_errors); - - return num_errors; -} diff --git a/sw/tests/xif_tests/mesh_test.c b/sw/tests/xif_tests/mesh_test.c deleted file mode 100644 index d548f795..00000000 --- a/sw/tests/xif_tests/mesh_test.c +++ /dev/null @@ -1,265 +0,0 @@ -/* - * Copyright (C) 2023-2024 ETH Zurich and University of Bologna - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * SPDX-License-Identifier: Apache-2.0 - * - * Authors: Victor Isachi - * - * MAGIA Mesh Test - */ - -#include "magia_tile_utils.h" -#include "magia_utils.h" -#include "redmule_isa_utils.h" -#include "idma_isa_utils.h" -#include "event_unit_utils.h" - -#include "x_input.h" -#include "w_input.h" -#include "y_input.h" -#include "z_output.h" - -#define X_BASE (L1_BASE + 0x00012048) -#define W_BASE (L1_BASE + 0x00016048) -#define Y_BASE (L1_BASE + 0x0001A048) -#define Z_BASE (L2_BASE + 0x00042000) // Note: for a large number of tiles (e.g. 64x64 mesh) we might exceed memory range of L2 -#define V_BASE (L2_BASE + 0x00046000) // Note: for a large number of tiles (e.g. 64x64 mesh) we might exceed memory range of L2 -#define T_BASE (L2_BASE + 0x0004A000) // Note: for a large number of tiles (e.g. 64x64 mesh) we might exceed memory range of L2 - -#define MHARTID_OFFSET (0x00010000) - -#define M_SIZE (96) -#define N_SIZE (64) -#define K_SIZE (64) - -#define VERBOSE (0) - -#define WAIT_CYCLES (10) - -#define DIFF_TH (0x0011) - -#define CONCURRENT - -void idma_mv_in(unsigned int x_dim, unsigned int y_dim, uint16_t src_data[], uint32_t dst_address){ - uint32_t dst_addr; - uint32_t src_addr; - uint32_t len; - - uint32_t dst_std_2; - uint32_t src_std_2; - uint32_t reps_2; - - uint32_t dst_std_3; - uint32_t src_std_3; - uint32_t reps_3; - - for (int i = 0; i < x_dim*y_dim; i++) - mmio16(T_BASE + get_hartid()*MHARTID_OFFSET + 2*i) = src_data[i]; - - idma_conf_in(); - - dst_addr = (uint32_t)dst_address; - src_addr = (uint32_t)(T_BASE + get_hartid()*MHARTID_OFFSET); - len = (uint32_t)(x_dim*y_dim*2); // 2 Bytes per element -#if VERBOSE > 10 - printf("dst_addr: 0x%0x\n", dst_addr); - printf("src_addr: 0x%0x\n", src_addr); - printf("len: %0d\n", len); -#endif - idma_set_addr_len_in(dst_addr, src_addr, len); - - dst_std_2 = 0; - src_std_2 = 0; - reps_2 = 1; -#if VERBOSE > 100 - printf("dst_std_2: 0x%0x\n", dst_std_2); - printf("src_std_2: 0x%0x\n", src_std_2); - printf("reps_2: 0x%0x\n", reps_2); -#endif - idma_set_std2_rep2_in(dst_std_2, src_std_2, reps_2); - - dst_std_3 = 0; - src_std_3 = 0; - reps_3 = 1; -#if VERBOSE > 100 - printf("dst_std_3: 0x%0x\n", dst_std_3); - printf("src_std_3: 0x%0x\n", src_std_3); - printf("reps_3: 0x%0x\n", reps_3); -#endif - idma_set_std3_rep3_in(dst_std_3, src_std_3, reps_3); - - idma_start_in(); - - // Clear Event Unit and ensure A2O mask is enabled - eu_clear_events(0xFFFFFFFF); - eu_enable_events(EU_IDMA_A2O_DONE_MASK); - - // Use direction-specific wait for L2->L1 (A2O) - eu_wait_events_polling(EU_IDMA_A2O_DONE_MASK, 10000000); - -#if VERBOSE > 100 - for (int i = 0; i < x_dim*y_dim; i++){ - printf("DST[0x%0x]: 0x%0x\n", dst_addr + 2*i, mmio16(dst_addr + 2*i)); - } -#endif - -#if VERBOSE > 10 - unsigned int num_errors; - num_errors = 0; - for (int i = 0; i < x_dim*y_dim; i++) { - if (mmio16(dst_addr + 2*i) != src_data[i]) { - num_errors++; - printf("DST[0x%0x]: 0x%0x != SRC[%0d]: 0x%0x\n", dst_addr + 2*i, mmio16(dst_addr + 2*i), i, src_data[i]); - } - } - printf("Detected %0d error(s) in the transfer...\n", num_errors); -#endif -} - -void idma_mv_out(unsigned int x_dim, unsigned int y_dim, uint32_t src_address, uint32_t dst_address){ - uint32_t dst_addr; - uint32_t src_addr; - uint32_t len; - - uint32_t dst_std_2; - uint32_t src_std_2; - uint32_t reps_2; - - uint32_t dst_std_3; - uint32_t src_std_3; - uint32_t reps_3; - - idma_conf_out(); - - dst_addr = (uint32_t)dst_address; - src_addr = (uint32_t)src_address; - len = (uint32_t)(x_dim*y_dim*2); // 2 Bytes per element -#if VERBOSE > 10 - printf("dst_addr: 0x%0x\n", dst_addr); - printf("src_addr: 0x%0x\n", src_addr); - printf("len: %0d\n", len); -#endif - idma_set_addr_len_out(dst_addr, src_addr, len); - - dst_std_2 = 0; - src_std_2 = 0; - reps_2 = 1; -#if VERBOSE > 100 - printf("dst_std_2: 0x%0x\n", dst_std_2); - printf("src_std_2: 0x%0x\n", src_std_2); - printf("reps_2: 0x%0x\n", reps_2); -#endif - idma_set_std2_rep2_out(dst_std_2, src_std_2, reps_2); - - dst_std_3 = 0; - src_std_3 = 0; - reps_3 = 1; -#if VERBOSE > 100 - printf("dst_std_3: 0x%0x\n", dst_std_3); - printf("src_std_3: 0x%0x\n", src_std_3); - printf("reps_3: 0x%0x\n", reps_3); -#endif - idma_set_std3_rep3_out(dst_std_3, src_std_3, reps_3); - - idma_start_out(); - - // Clear Event Unit and ensure O2A mask is enabled - eu_clear_events(0xFFFFFFFF); - eu_enable_events(EU_IDMA_O2A_DONE_MASK); - - // Use direction-specific wait for L1->L2 (O2A) - eu_wait_events_polling(EU_IDMA_O2A_DONE_MASK, 10000000); - -#if VERBOSE > 100 - for (int i = 0; i < x_dim*y_dim; i++){ - printf("DST[0x%0x]: 0x%0x\n", dst_addr + 2*i, mmio16(dst_addr + 2*i)); - } -#endif - -#if VERBOSE > 10 - unsigned int num_errors; - num_errors = 0; - for (int i = 0; i < x_dim*y_dim; i++) { - if (mmio16(dst_addr + 2*i) != mmio16(src_addr + 2*i)) { - num_errors++; - printf("DST[0x%0x]: 0x%0x != SRC[%0d]: 0x%0x\n", dst_addr + 2*i, mmio16(dst_addr + 2*i), i, mmio16(src_addr + 2*i)); - } - } - printf("Detected %0d error(s) in the transfer...\n", num_errors); -#endif -} - -int main(void) { - // Initialize event unit - eu_init(); - - // X - printf("Initializing X through iDMA...\n"); - idma_mv_in(M_SIZE, N_SIZE, x_inp, (X_BASE + get_hartid()*L1_TILE_OFFSET)); - - // W - printf("Initializing W through iDMA...\n"); - idma_mv_in(N_SIZE, K_SIZE, w_inp, (W_BASE + get_hartid()*L1_TILE_OFFSET)); - - // Y - printf("Initializing Y through iDMA...\n"); - idma_mv_in(M_SIZE, K_SIZE, y_inp, (Y_BASE + get_hartid()*L1_TILE_OFFSET)); - -#if VERBOSE > 10 - printf("K_SIZE: 0x%0x\n", K_SIZE); - printf("M_SIZE: 0x%0x\n", M_SIZE); - printf("N_SIZE: 0x%0x\n", N_SIZE); -#endif - - printf("Testing matrix multiplication with RedMulE...\n"); - - redmule_mcnfig(K_SIZE, M_SIZE, N_SIZE); - - redmule_marith(Y_BASE + get_hartid()*L1_TILE_OFFSET, W_BASE + get_hartid()*L1_TILE_OFFSET, X_BASE + get_hartid()*L1_TILE_OFFSET); - - // Clear Event Unit and ensure RedMulE mask is enabled - eu_clear_events(0xFFFFFFFF); - eu_enable_events(EU_REDMULE_DONE_MASK); - - // Wait for HWPE completion - eu_wait_events_polling(EU_REDMULE_DONE_MASK, 10000000); - - printf("Moving results through iDMA...\n"); - idma_mv_out(M_SIZE, K_SIZE, Y_BASE + get_hartid()*L1_TILE_OFFSET, V_BASE + get_hartid()*MHARTID_OFFSET); - - printf("Verifying results...\n"); - - unsigned int num_errors[NUM_HARTS]; - num_errors[get_hartid()] = 0; - - uint16_t computed[NUM_HARTS], expected[NUM_HARTS], diff[NUM_HARTS]; - for(int i = 0; i < M_SIZE*K_SIZE; i++){ - computed[get_hartid()] = mmio16(V_BASE + get_hartid()*MHARTID_OFFSET + 2*i); - expected[get_hartid()] = z_oup[i]; - diff[get_hartid()] = (computed[get_hartid()] > expected[get_hartid()]) ? (computed[get_hartid()] - expected[get_hartid()]) : (expected[get_hartid()] - computed[get_hartid()]); - if(diff[get_hartid()] > DIFF_TH){ - num_errors[get_hartid()]++; - printf("**ERROR**: V[0x%0x](=0x%0x) != Z[%0d](=0x%0x)\n", V_BASE + get_hartid()*MHARTID_OFFSET + 2*i, computed[get_hartid()], i, expected[get_hartid()]); - } - } - printf("Finished test with %0d error(s)\n", num_errors[get_hartid()]); - - uint32_t exit_code[NUM_HARTS]; - if(num_errors[get_hartid()]) - exit_code[get_hartid()] = FAIL_EXIT_CODE; - else - exit_code[get_hartid()] = PASS_EXIT_CODE; - - return exit_code; -} diff --git a/sw/tests/xif_tests/redmule_test.c b/sw/tests/xif_tests/redmule_test.c deleted file mode 100644 index 4b4ca57e..00000000 --- a/sw/tests/xif_tests/redmule_test.c +++ /dev/null @@ -1,113 +0,0 @@ -/* - * Copyright (C) 2023-2024 ETH Zurich and University of Bologna - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * SPDX-License-Identifier: Apache-2.0 - * - * Authors: Victor Isachi - * - * MAGIA RedMulE Test - */ - -#include "magia_tile_utils.h" -#include "redmule_isa_utils.h" -#include "event_unit_utils.h" - -#include "x_input.h" -#include "w_input.h" -#include "y_input.h" -#include "z_output.h" - -#define X_BASE (L1_BASE + 0x00012048) -#define W_BASE (L1_BASE + 0x00016048) -#define Y_BASE (L1_BASE + 0x0001A048) -#define Z_BASE (L2_BASE + 0x00042000) - -#define M_SIZE (96) -#define N_SIZE (64) -#define K_SIZE (64) - -#define VERBOSE (0) - -#define WAIT_CYCLES (10) - -#define DIFF_TH (0x0011) - -int main(void) { - // Initialize Event Unit for RedMulE - eu_redmule_init(); - - // X - for (int i = 0; i < M_SIZE*N_SIZE; i++) - mmio16(X_BASE + 2*i) = x_inp[i]; -#if VERBOSE > 10 - for (int i = 0; i < M_SIZE*N_SIZE; i++) - printf("X[%8x]: 0x%4x\n", X_BASE + 2*i, mmio16(X_BASE + 2*i)); -#endif - - // W - for (int i = 0; i < N_SIZE*K_SIZE; i++) - mmio16(W_BASE + 2*i) = w_inp[i]; -#if VERBOSE > 10 - for (int i = 0; i < N_SIZE*K_SIZE; i++) - printf("W[%8x]: 0x%4x\n", W_BASE + 2*i, mmio16(W_BASE + 2*i)); -#endif - - // Y - for (int i = 0; i < M_SIZE*K_SIZE; i++) - mmio16(Y_BASE + 2*i) = y_inp[i]; -#if VERBOSE > 10 - for (int i = 0; i < M_SIZE*K_SIZE; i++) - printf("Y[%8x]: 0x%4x\n", Y_BASE + 2*i, mmio16(Y_BASE + 2*i)); -#endif - - // Z - golden (reference) - for (int i = 0; i < M_SIZE*K_SIZE; i++) - mmio16(Z_BASE + 2*i) = z_oup[i]; -#if VERBOSE > 10 - for (int i = 0; i < M_SIZE*K_SIZE; i++) - printf("Z[%8x]: 0x%4x\n", Z_BASE + 2*i, mmio16(Z_BASE + 2*i)); -#endif - -#if VERBOSE > 10 - printf("K_SIZE: %4x\n", K_SIZE); - printf("M_SIZE: %4x\n", M_SIZE); - printf("N_SIZE: %4x\n", N_SIZE); -#endif - - // Wait for end of computation - printf("Testing matrix multiplication with RedMulE...\n"); - - redmule_mcnfig(K_SIZE, M_SIZE, N_SIZE); - redmule_marith(Y_BASE, W_BASE, X_BASE); - - eu_redmule_wait_completion(EU_WAIT_MODE_POLLING); - - printf("Verifying results...\n"); - - unsigned int num_errors = 0; - - uint16_t computed, expected, diff; - for(int i = 0; i < M_SIZE*K_SIZE; i++){ - computed = mmio16(Y_BASE + 2*i); - expected = mmio16(Z_BASE + 2*i); - diff = (computed > expected) ? (computed - expected) : (expected - computed); - if(diff > DIFF_TH){ - num_errors++; - printf("**ERROR**: Y[%8x](=0x%4x) != Z[%8x](=0x%4x)\n", Y_BASE + 2*i, computed, Z_BASE + 2*i, expected); - } - } - printf("Finished test with %0d errors\n", num_errors); - - return num_errors; -} diff --git a/sw/tests/xif_tests/tile_test.c b/sw/tests/xif_tests/tile_test.c deleted file mode 100644 index e7cf1baf..00000000 --- a/sw/tests/xif_tests/tile_test.c +++ /dev/null @@ -1,255 +0,0 @@ -/* - * Copyright (C) 2023-2024 ETH Zurich and University of Bologna - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * SPDX-License-Identifier: Apache-2.0 - * - * Authors: Victor Isachi - * - * MAGIA Tile Test - */ - -#include "magia_tile_utils.h" -#include "redmule_isa_utils.h" -#include "idma_isa_utils.h" -#include "event_unit_utils.h" - -#include "x_input.h" -#include "w_input.h" -#include "y_input.h" -#include "z_output.h" - -#define X_BASE (L1_BASE + 0x00012048) -#define W_BASE (L1_BASE + 0x00016048) -#define Y_BASE (L1_BASE + 0x0001A048) -#define Z_BASE (L2_BASE + 0x00042000) -#define V_BASE (L2_BASE + 0x00046000) -#define T_BASE (L2_BASE + 0x0004A000) - -#define M_SIZE (96) -#define N_SIZE (64) -#define K_SIZE (64) - -#define VERBOSE (0) - -#define WAIT_CYCLES (10) - -#define DIFF_TH (0x0011) - -#define CONCURRENT - -void idma_mv_in(unsigned int x_dim, unsigned int y_dim, uint16_t src_data[], uint32_t dst_address){ - uint32_t dst_addr; - uint32_t src_addr; - uint32_t len; - - uint32_t dst_std_2; - uint32_t src_std_2; - uint32_t reps_2; - - uint32_t dst_std_3; - uint32_t src_std_3; - uint32_t reps_3; - - for (int i = 0; i < x_dim*y_dim; i++) - mmio16(T_BASE + 2*i) = src_data[i]; - - idma_conf_in(); - - dst_addr = (uint32_t)dst_address; - src_addr = (uint32_t)T_BASE; - len = (uint32_t)(x_dim*y_dim*2); // 2 Bytes per element -#if VERBOSE > 10 - printf("dst_addr: 0x%8x\n", dst_addr); - printf("src_addr: 0x%8x\n", src_addr); - printf("len: %0d\n", len); -#endif - idma_set_addr_len_in(dst_addr, src_addr, len); - - dst_std_2 = 0; - src_std_2 = 0; - reps_2 = 1; -#if VERBOSE > 100 - printf("dst_std_2: 0x%8x\n", dst_std_2); - printf("src_std_2: 0x%8x\n", src_std_2); - printf("reps_2: 0x%8x\n", reps_2); -#endif - idma_set_std2_rep2_in(dst_std_2, src_std_2, reps_2); - - dst_std_3 = 0; - src_std_3 = 0; - reps_3 = 1; -#if VERBOSE > 100 - printf("dst_std_3: 0x%8x\n", dst_std_3); - printf("src_std_3: 0x%8x\n", src_std_3); - printf("reps_3: 0x%8x\n", reps_3); -#endif - idma_set_std3_rep3_in(dst_std_3, src_std_3, reps_3); - - eu_clear_events(0xFFFFFFFF); - eu_enable_events(EU_IDMA_A2O_DONE_MASK); - - idma_start_in(); - - eu_wait_events_polling(EU_IDMA_A2O_DONE_MASK, 10000000); - -#if VERBOSE > 100 - for (int i = 0; i < x_dim*y_dim; i++) - printf("DST[%8x]: 0x%4x\n", dst_address + 2*i, mmio16(dst_address + 2*i)); -#endif - -#if VERBOSE > 10 - unsigned int num_errors; - num_errors = 0; - for (int i = 0; i < x_dim*y_dim; i++) { - if (mmio16(dst_address + 2*i) != src_data[i]) { - num_errors++; - printf("DST[%8x]: 0x%4x != SRC[%0d]: 0x%4x\n", dst_address + 2*i, mmio16(dst_address + 2*i), i, src_data[i]); - } - } - printf("Detected %0d error(s) in the transfer...\n", num_errors); -#endif -} - -void idma_mv_out(unsigned int x_dim, unsigned int y_dim, uint32_t src_address, uint32_t dst_address){ - uint32_t dst_addr; - uint32_t src_addr; - uint32_t len; - - uint32_t dst_std_2; - uint32_t src_std_2; - uint32_t reps_2; - - uint32_t dst_std_3; - uint32_t src_std_3; - uint32_t reps_3; - - idma_conf_out(); - - dst_addr = (uint32_t)dst_address; - src_addr = (uint32_t)src_address; - len = (uint32_t)(x_dim*y_dim*2); // 2 Bytes per element -#if VERBOSE > 10 - printf("dst_addr: 0x%8x\n", dst_addr); - printf("src_addr: 0x%8x\n", src_addr); - printf("len: %0d\n", len); -#endif - idma_set_addr_len_out(dst_addr, src_addr, len); - - dst_std_2 = 0; - src_std_2 = 0; - reps_2 = 1; -#if VERBOSE > 100 - printf("dst_std_2: 0x%8x\n", dst_std_2); - printf("src_std_2: 0x%8x\n", src_std_2); - printf("reps_2: 0x%8x\n", reps_2); -#endif - idma_set_std2_rep2_out(dst_std_2, src_std_2, reps_2); - - dst_std_3 = 0; - src_std_3 = 0; - reps_3 = 1; -#if VERBOSE > 100 - printf("dst_std_3: 0x%8x\n", dst_std_3); - printf("src_std_3: 0x%8x\n", src_std_3); - printf("reps_3: 0x%8x\n", reps_3); -#endif - idma_set_std3_rep3_out(dst_std_3, src_std_3, reps_3); - - eu_clear_events(0xFFFFFFFF); - eu_enable_events(EU_IDMA_O2A_DONE_MASK); - - idma_start_out(); - - eu_wait_events_polling(EU_IDMA_O2A_DONE_MASK, 10000000); - -#if VERBOSE > 100 - for (int i = 0; i < x_dim*y_dim; i++) - printf("DST[%8x]: 0x%4x\n", dst_address + 2*i, mmio16(dst_address + 2*i)); -#endif - -#if VERBOSE > 10 - unsigned int num_errors; - num_errors = 0; - for (int i = 0; i < x_dim*y_dim; i++) { - if (mmio16(dst_address + 2*i) != mmio16(src_address + 2*i)) { - num_errors++; - printf("DST[%8x]: 0x%4x != SRC[%8x]: 0x%4x\n", dst_address + 2*i, mmio16(dst_address + 2*i), src_address + 2*i, mmio16(src_address + 2*i)); - } - } - printf("Detected %0d error(s) in the transfer...\n", num_errors); -#endif -} - -int main(void) { - // Initialize event unit - eu_init(); - - // X - printf("Initializing X through iDMA...\n"); - idma_mv_in(M_SIZE, N_SIZE, x_inp, X_BASE); - - // W - printf("Initializing W through iDMA...\n"); - idma_mv_in(N_SIZE, K_SIZE, w_inp, W_BASE); - - // Y - printf("Initializing Y through iDMA...\n"); - idma_mv_in(M_SIZE, K_SIZE, y_inp, Y_BASE); - - // Z - golden (reference) - printf("Initializing Z - golden...\n"); - for (int i = 0; i < M_SIZE*K_SIZE; i++) - mmio16(Z_BASE + 2*i) = z_oup[i]; -#if VERBOSE > 100 - for (int i = 0; i < M_SIZE*K_SIZE; i++) - printf("Z[%8x]: 0x%4x\n", Z_BASE + 2*i, mmio16(Z_BASE + 2*i)); -#endif - -#if VERBOSE > 10 - printf("K_SIZE: %4x\n", K_SIZE); - printf("M_SIZE: %4x\n", M_SIZE); - printf("N_SIZE: %4x\n", N_SIZE); -#endif - - printf("Testing matrix multiplication with RedMulE...\n"); - - eu_clear_events(0xFFFFFFFF); - eu_enable_events(EU_REDMULE_DONE_MASK); - - redmule_mcnfig(K_SIZE, M_SIZE, N_SIZE); - redmule_marith(Y_BASE, W_BASE, X_BASE); - - eu_wait_events_polling(EU_REDMULE_DONE_MASK, 10000000); - - printf("Moving results through iDMA...\n"); - idma_mv_out(M_SIZE, K_SIZE, Y_BASE, V_BASE); - - printf("Verifying results...\n"); - - unsigned int num_errors = 0; - - uint16_t computed, expected, diff; - for(int i = 0; i < M_SIZE*K_SIZE; i++){ - computed = mmio16(V_BASE + 2*i); - expected = mmio16(Z_BASE + 2*i); - diff = (computed > expected) ? (computed - expected) : (expected - computed); - if(diff > DIFF_TH){ - num_errors++; - printf("**ERROR**: V[%8x](=0x%4x) != Z[%8x](=0x%4x)\n", V_BASE + 2*i, computed, Z_BASE + 2*i, expected); - } - } - printf("Finished test with %0d errors\n", num_errors); - - return num_errors; -} diff --git a/sw/utils/event_unit_utils.h b/sw/utils/event_unit_utils.h index 3bdf421e..5e746ba3 100644 --- a/sw/utils/event_unit_utils.h +++ b/sw/utils/event_unit_utils.h @@ -17,7 +17,7 @@ * Authors: Luca Balboni * * MAGIA Event Unit Utilities - * Two modes: POLLING (non-blocking) and WFE (blocking with p.elw sleep) + * Two modes: POLLING (non-blocking) and WFE (blocking with cv.elw sleep or standard lw) */ #ifndef EVENT_UNIT_UTILS_H @@ -45,7 +45,7 @@ #define EU_CORE_BUFFER_IRQ_MASKED (EU_BASE + 0x24) #define EU_CORE_BUFFER_CLEAR (EU_BASE + 0x28) -// Wait registers (blocking with p.elw) +// Wait registers (blocking event load - cv.elw if pulp extensions are activated) #define EU_CORE_EVENT_WAIT (EU_BASE + 0x38) #define EU_CORE_EVENT_WAIT_CLEAR (EU_BASE + 0x3C) @@ -137,7 +137,7 @@ typedef enum { static inline unsigned int evt_read32(unsigned int base, unsigned int offset) { unsigned int value; unsigned int addr = base + offset; -#if defined(__cv32e40p__) || defined(CV32E40P) +#if defined(CV32E40P) __asm__ __volatile__ ( "cv.elw %0, 0(%1)" : "=r" (value) @@ -145,8 +145,9 @@ static inline unsigned int evt_read32(unsigned int base, unsigned int offset) { : "memory" ); #else + // Standard lw for cores without PULP extensions (CV32E40X, etc.) __asm__ __volatile__ ( - "p.elw %0, 0(%1)" + "lw %0, 0(%1)" : "=r" (value) : "r" (addr) : "memory" @@ -221,7 +222,7 @@ static inline uint32_t eu_wait_events_polling(uint32_t event_mask, uint32_t time return 0; } -// WFE mode: blocking sleep with p.elw +// WFE mode: blocking event load (cv.elw or lw depending on if pulp extensions are activated) static inline uint32_t eu_wait_events_wfe(uint32_t event_mask) { eu_enable_events(event_mask); return evt_read32(EU_BASE, EU_CORE_EVENT_WAIT_CLEAR - EU_BASE); diff --git a/sw/utils/magia_utils.h b/sw/utils/magia_utils.h index 22c42765..7f1c4843 100644 --- a/sw/utils/magia_utils.h +++ b/sw/utils/magia_utils.h @@ -47,19 +47,7 @@ static inline uint32_t get_hartid(void) { uint32_t hartid; asm volatile("csrr %0, mhartid" :"=r"(hartid):); - #ifndef RI5CY - return hartid; - #else - // RI5CY mhartid CSR: { 21'b0, cluster_id_i[5:0], 1'b0, core_id_i[3:0] } - // cluster_id_i = mhartid_tile + 1 (which tile/cluster, 1-indexed; 0 = standalone main core) - // core_id_i = i (which core within the cluster, 0-indexed) - uint32_t cluster_id = (hartid >> 5) & 0x3F; // = tile_hartid + 1 (same for all cores in a tile) - uint32_t core_id = hartid & 0xF; // = i (unique per core within tile) - //printf ("%d\n",PULP_HARTID_BASE + (cluster_id - 1) * PULP_CORE_COUNT + core_id); - if (cluster_id == 0) - return core_id; // standalone main tile core - return PULP_HARTID_BASE + (cluster_id - 1) * PULP_CORE_COUNT + core_id; - #endif + return hartid; } static inline void amo_increment(volatile uint32_t addr, volatile uint32_t amnt){ From 8d62ed0ef3f70545d6edb46d52af0beacc499d23 Mon Sep 17 00:00:00 2001 From: Luca Balboni Date: Thu, 6 Aug 2026 13:47:07 +0200 Subject: [PATCH 2/3] zfinx parametrized and fixed crt0.s (for CV32E40X zfinx is always = 0, it has issue for =1 with fpu_ss) --- Makefile | 42 +++++++++++++---------- hw/tile/converters/cv32e40p_data2obi.sv | 4 --- hw/tile/converters/cv32e40p_obi2data.sv | 2 -- hw/tile/converters/cv32e40x_data2obi.sv | 2 -- hw/tile/converters/cv32e40x_obi2data.sv | 2 -- hw/tile/magia_tile.sv | 12 +++---- hw/tile/magia_tile_pkg.sv | 15 +++++++-- setup_env.sh | 12 ------- sw/kernel/crt0.S | 5 +++ sw/kernel_pulp/Makefile | 11 +++++-- sw/kernel_pulp/pulp_crt0.S | 5 +++ sw/tests/fpu_test.c | 44 +++++++++++++++++++++---- 12 files changed, 99 insertions(+), 57 deletions(-) diff --git a/Makefile b/Makefile index 83418b07..ea5e801b 100644 --- a/Makefile +++ b/Makefile @@ -41,16 +41,28 @@ BENDER_DIR ?= . ARCH ?= rv XLEN ?= 32 +zfinx := 1 +cluster_zfinx := 1 + +PULP_XTEN_BASE := xcvalu_xcvbi_xcvbitmanip_xcvhwlp_xcvmac_xcvmem_xcvsimd_xcvelw + ifeq ($(core), CV32E40X) - XTEN = imafc + #CV32E40X has a problem with zfinx=1, so is not a free parameter and it is forced to 0 (F extension) ISA = riscv + XTEN = imafc ABI ?= ilp XABI ?= f else - XTEN = imc_xcvalu_xcvbi_xcvbitmanip_xcvhwlp_xcvmac_xcvmem_xcvsimd_xcvelw_zfinx_zhinxmin ISA = cv32e40p - ABI ?= ilp - XABI ?= + ifeq ($(zfinx),1) + XTEN = imc_$(PULP_XTEN_BASE)_zfinx_zhinxmin + ABI ?= ilp + XABI ?= + else + XTEN = imfc_$(PULP_XTEN_BASE) + ABI ?= ilp + XABI ?= f + endif endif # Auto-detect test location under sw/tests/ recursively — no cluster= flag needed. @@ -146,15 +158,9 @@ LINKSCRIPT := sw/kernel/link.ld PULP_SW_DIR := sw/kernel_pulp -ifneq ($(core), CV32E40P) - CC=$(ISA)$(XLEN)-unknown-elf-gcc - OBJDUMP=$(ISA)$(XLEN)-unknown-elf-objdump - NM=$(ISA)$(XLEN)-unknown-elf-nm -else - CC=riscv64-unknown-elf-gcc - OBJDUMP=riscv64-unknown-elf-objdump - NM=riscv64-unknown-elf-nm -endif +CC=riscv64-unknown-elf-gcc +OBJDUMP=riscv64-unknown-elf-objdump +NM=riscv64-unknown-elf-nm LD=$(CC) ifneq ($(core), CV32E40P) CC_OPTS=-march=$(ARCH)$(XLEN)$(XTEN) -mabi=$(ABI)$(XLEN)$(XABI) -D__$(ISA)__ -O2 -g -Wextra -Wall -Wno-unused-parameter -Wno-unused-variable -Wno-unused-function -Wundef -fdata-sections -ffunction-sections -MMD -MP @@ -214,14 +220,12 @@ spatz-header: # Build PULP cluster binary (magia-sdk style): produces # sw/kernel_pulp/headers_bin/_pulp_task_bin.h # embedding the position-independent flat binary in section .pulp_binary. -# PULP cluster cores are always CV32E40P (see magia_tile.sv), independent of -# which core is selected for the control core via $(core) — so core=CV32E40P -# is hardcoded here rather than forwarding $(core). +# PULP cluster cores are always CV32E40P (see magia_tile.sv), independent of which core is selected via $(core) .PHONY: pulp-header pulp-header: @if [ -n "$(PULP_TASKS)" ]; then \ echo "[PULP] Auto-detected tasks: $(PULP_TASKS)"; \ - $(MAKE) -C $(PULP_SW_DIR) TEST_NAME=$(test) task="$(PULP_TASKS)" PULP_TASK_DIR=$(ROOT_DIR)/$(PULP_TASK_DIR_PATH) core=CV32E40P all; \ + $(MAKE) -C $(PULP_SW_DIR) TEST_NAME=$(test) task="$(PULP_TASKS)" PULP_TASK_DIR=$(ROOT_DIR)/$(PULP_TASK_DIR_PATH) core=CV32E40P zfinx=$(cluster_zfinx) all; \ else \ echo "[PULP] No pulp_task/ directory — skipping PULP cluster compilation"; \ fi @@ -349,6 +353,10 @@ else $(error Detected unsupported core, must choose among CV32E40X or CV32E40P ) endif +effective_ctrl_zfinx := $(if $(filter CV32E40X,$(core)),0,$(zfinx)) +bender_defs += -D ZFINX_CTRL=$(effective_ctrl_zfinx) +bender_defs += -D ZFINX_CLUSTER=$(cluster_zfinx) + bender_targs += -t rtl bender_targs += -t test bender_targs += -t cv32e40p_include_tracer diff --git a/hw/tile/converters/cv32e40p_data2obi.sv b/hw/tile/converters/cv32e40p_data2obi.sv index 1e1d030a..be33970c 100644 --- a/hw/tile/converters/cv32e40p_data2obi.sv +++ b/hw/tile/converters/cv32e40p_data2obi.sv @@ -18,10 +18,6 @@ * Luca Balboni * * CV32E40P Core Data - OBI REQ Converter - * - * CV32E40P has no atop/memtype/prot/dbg on its data channel, so those OBI - * optional fields are tied to their inactive defaults. Used by the PULP - * cluster cores (always CV32E40P) and by the control core when it is CV32E40P. */ module cv32e40p_data2obi_req diff --git a/hw/tile/converters/cv32e40p_obi2data.sv b/hw/tile/converters/cv32e40p_obi2data.sv index 5bb9ebf6..1c318593 100644 --- a/hw/tile/converters/cv32e40p_obi2data.sv +++ b/hw/tile/converters/cv32e40p_obi2data.sv @@ -19,8 +19,6 @@ * * OBI - CV32E40P Core Data RSP Converter * - * CV32E40P has no exokay on its data response. Used by the PULP cluster cores - * (always CV32E40P) and by the control core when it is CV32E40P. */ module cv32e40p_obi2data_rsp diff --git a/hw/tile/converters/cv32e40x_data2obi.sv b/hw/tile/converters/cv32e40x_data2obi.sv index f09e68db..522bd6cb 100644 --- a/hw/tile/converters/cv32e40x_data2obi.sv +++ b/hw/tile/converters/cv32e40x_data2obi.sv @@ -19,8 +19,6 @@ * * CV32E40X Core Data - OBI REQ Converter * - * CV32E40X drives atop/memtype/prot/dbg on its data channel, which are mapped - * onto the OBI optional fields. Used by the control core when it is CV32E40X. */ module cv32e40x_data2obi_req diff --git a/hw/tile/converters/cv32e40x_obi2data.sv b/hw/tile/converters/cv32e40x_obi2data.sv index b1c88e34..e99f6b1d 100644 --- a/hw/tile/converters/cv32e40x_obi2data.sv +++ b/hw/tile/converters/cv32e40x_obi2data.sv @@ -19,8 +19,6 @@ * * OBI - CV32E40X Core Data RSP Converter * - * CV32E40X consumes the exokay response bit. Used by the control core when it - * is CV32E40X. */ module cv32e40x_obi2data_rsp diff --git a/hw/tile/magia_tile.sv b/hw/tile/magia_tile.sv index 353995af..29e97462 100644 --- a/hw/tile/magia_tile.sv +++ b/hw/tile/magia_tile.sv @@ -402,11 +402,7 @@ module magia_tile magia_tile_pkg::eu_direct_req_t eu_direct_req; magia_tile_pkg::eu_direct_rsp_t eu_direct_rsp; - // Cluster core data interface (converted directly to OBI xbar). - // Cluster cores are always CV32E40P, so these are typed on the CV32E40P - // flavour and not on core_data_req_t, which follows the control core: with - // core=CV32E40X the extra atop/memtype/prot/dbg fields would never be driven - // and would propagate X into the OBI crossbar. + // Cluster core data interface (converted directly to OBI xbar) magia_tile_pkg::cv32e40p_core_data_req_t [magia_tile_pkg::N_CLUSTER_CORES-1:0] cluster_data_req; magia_tile_pkg::cv32e40p_core_data_rsp_t [magia_tile_pkg::N_CLUSTER_CORES-1:0] cluster_data_rsp; @@ -1297,7 +1293,7 @@ module magia_tile .COREV_PULP ( 1 ), // For now this is a no .COREV_CLUSTER ( 1 ), .FPU ( FPU ), - .ZFINX ( magia_tile_pkg::ZFINX_CV32E40P ), + .ZFINX ( magia_tile_pkg::ZFINX_CTRL ), .FPU_ADDMUL_LAT ( 1 ), // Match C_LAT_FP32=1 in fpnew wrapper .FPU_OTHERS_LAT ( 1 ), // Match C_LAT_NONCOMP=1 in fpnew wrapper .NUM_MHPMCOUNTERS ( 29 ) @@ -1816,7 +1812,7 @@ module magia_tile `ifdef CV32E40X fpu_ss #( - .PULP_ZFINX ( magia_tile_pkg::ZFINX_CV32E40X ), + .PULP_ZFINX ( magia_tile_pkg::ZFINX_CTRL ), .INPUT_BUFFER_DEPTH ( magia_tile_pkg::FPU_BUFFER_DEPTH ), .INPUT_BUFFER_FALL_THROUGH ( magia_tile_pkg::FPU_BUFFER_FT ), .OUT_OF_ORDER ( magia_tile_pkg::FPU_OOO ), @@ -2239,7 +2235,7 @@ generate .COREV_PULP ( 1 ), // For now this is a no .COREV_CLUSTER ( 1 ), .FPU ( FPU ), - .ZFINX ( magia_tile_pkg::ZFINX_CV32E40P ), + .ZFINX ( magia_tile_pkg::ZFINX_CLUSTER ), .FPU_ADDMUL_LAT ( 1 ), // Match C_LAT_FP32=1 in fpnew wrapper .FPU_OTHERS_LAT ( 1 ), // Match C_LAT_NONCOMP=1 in fpnew wrapper .NUM_MHPMCOUNTERS ( 29 ) diff --git a/hw/tile/magia_tile_pkg.sv b/hw/tile/magia_tile_pkg.sv index 52ac2854..34d47b1a 100644 --- a/hw/tile/magia_tile_pkg.sv +++ b/hw/tile/magia_tile_pkg.sv @@ -268,10 +268,22 @@ package magia_tile_pkg; // Parameters used by cv32e40p core parameter bit PULP_CLUSTER = 1'b1; // PULP cluster mode parameter bit FPU = 1'b1; // Enable FPU (main feature) - parameter bit ZFINX_CV32E40P = 1'b1; // Zfinx extension (integer FP in GPR) of the CV32E40P cores (control and cluster) parameter bit FP_DIVSQRT = 1'b1; // FP division and square root parameter logic[31:0] DM_HALT_ADDR = 32'h1A110800; // Debug module halt address + `ifdef ZFINX_CTRL + localparam bit ZFINX_CTRL_PARAM = `ZFINX_CTRL; + `else + localparam bit ZFINX_CTRL_PARAM = 1'b1; + `endif + `ifdef ZFINX_CLUSTER + localparam bit ZFINX_CLUSTER_PARAM = `ZFINX_CLUSTER; + `else + localparam bit ZFINX_CLUSTER_PARAM = 1'b1; + `endif + parameter bit ZFINX_CTRL = ZFINX_CTRL_PARAM; // Zfinx for the control core + parameter bit ZFINX_CLUSTER = ZFINX_CLUSTER_PARAM; // Zfinx for the PULP cluster cores + `ifdef CV32E40X parameter int unsigned X_NUM_RS = 3; // Number of register file read ports that can be used by the eXtension interface parameter int unsigned CLIC_ID_W = 1; // Width of clic_irq_id_i and clic_irq_id_o. The maximum number of supported interrupts in CLIC mode is 2^CLIC_ID_WIDTH. Trap vector table alignment is restricted as described in Machine Trap Vector Table Base Address (mtvt) @@ -408,7 +420,6 @@ package magia_tile_pkg; parameter int unsigned CLUSTER_FILL_DW = magia_pkg::DATA_W; // i$ Fill interface data width. Power of two; >= 8. // Parameters used by the FPU - parameter bit ZFINX_CV32E40X = 0; // fpu_ss uses the F ISA extension, not Zfinx: CV32E40X is built with rv32imafc parameter int unsigned FPU_BUFFER_DEPTH = 8; // FPU FIFO depth that buffers instructions coming from core parameter bit FPU_BUFFER_FT = 0; // FPU FIFO fall through that buffers instructions coming from core parameter bit FPU_OOO = 1; // FPU enable out-of-order execution diff --git a/setup_env.sh b/setup_env.sh index 9eb40bc2..18e6617d 100644 --- a/setup_env.sh +++ b/setup_env.sh @@ -1,5 +1,3 @@ -core="$1" -echo "Selected core: $core" export MAGIA_DIR=$(pwd) echo "Exporting MAGIA path to $MAGIA_DIR" @@ -9,16 +7,6 @@ echo "Exporting bender path to $BENDER_DIR" export PATH=$BENDER_DIR:$PATH unset BENDER_DIR echo "Exporting SDK and GCC Toolchain paths" -export XLEN=32 -if [[ "$core" == "CV32E40X" ]]; then - echo "Exporting control core (CV32E40X) ISA extensions: I, M, A, F, C" - export CTRL_XTEN=imafc -else - echo "Exporting control core (CV32E40P) ISA extensions: I, M, C, PULP (Zfinx)" - export CTRL_XTEN=imc_xcvalu_xcvbi_xcvbitmanip_xcvhwlp_xcvmac_xcvmem_xcvsimd_xcvelw_zfinx_zhinxmin -fi -echo "Exporting PULP cluster core (CV32E40P) ISA extensions: I, M, C, PULP (Zfinx)" -export CLUSTER_XTEN=imc_xcvalu_xcvbi_xcvbitmanip_xcvhwlp_xcvmac_xcvmem_xcvsimd_xcvelw_zfinx_zhinxmin echo "Sourcing python virtual environment" source ./magia_venv/bin/activate echo "Finished setting up the environment" \ No newline at end of file diff --git a/sw/kernel/crt0.S b/sw/kernel/crt0.S index e43adfa6..12fd86aa 100644 --- a/sw/kernel/crt0.S +++ b/sw/kernel/crt0.S @@ -74,6 +74,11 @@ _start: li t0, 0x8 csrrs zero, mie, t0 +#if defined(__riscv_f) && defined(__cv32e40p__) + li t0, 0x2000 + csrrs zero, mstatus, t0 +#endif + # Clear the BSS segment. la t0, _bss_start la t1, _bss_end diff --git a/sw/kernel_pulp/Makefile b/sw/kernel_pulp/Makefile index f426dfb5..b20f2b6d 100644 --- a/sw/kernel_pulp/Makefile +++ b/sw/kernel_pulp/Makefile @@ -29,11 +29,18 @@ ARCH ?= rv XLEN ?= 32 core ?= CV32E40P -XTEN := imc_xcvalu_xcvbi_xcvbitmanip_xcvhwlp_xcvmac_xcvmem_xcvsimd_xcvelw_zfinx_zhinxmin +zfinx ?= 1 +XTEN_BASE := xcvalu_xcvbi_xcvbitmanip_xcvhwlp_xcvmac_xcvmem_xcvsimd_xcvelw +ifeq ($(zfinx),1) + XTEN := imc_$(XTEN_BASE)_zfinx_zhinxmin + XABI := +else + XTEN := imfc_$(XTEN_BASE) + XABI := f +endif CC = riscv64-unknown-elf-gcc OBJCOPY = riscv64-unknown-elf-objcopy OBJDUMP = riscv64-unknown-elf-objdump -XABI := ABI := ilp TEST_NAME ?= base_pulp_test diff --git a/sw/kernel_pulp/pulp_crt0.S b/sw/kernel_pulp/pulp_crt0.S index 510ac453..14dda5a8 100644 --- a/sw/kernel_pulp/pulp_crt0.S +++ b/sw/kernel_pulp/pulp_crt0.S @@ -121,6 +121,11 @@ _start: li t0, 0x8 csrrs zero, mstatus, t0 +#ifdef __riscv_f + li t0, 0x2000 + csrrs zero, mstatus, t0 +#endif + /* Signal "core armed": write 1 to PULP_READY. CV32's pulp_init() polls * this until ClusterRegs has counted N_CLUSTER_CORES writes. */ li t0, PULP_READY_ADDR diff --git a/sw/tests/fpu_test.c b/sw/tests/fpu_test.c index 20ab7ff0..59b2e2e4 100644 --- a/sw/tests/fpu_test.c +++ b/sw/tests/fpu_test.c @@ -35,6 +35,11 @@ #define abs_diff(x, y) (((x) > (y)) ? ((x) - (y)) : ((y) - (x))) +static inline uint32_t f32_bits(float f){ + uint32_t *p = (volatile uint32_t *)&f; + return *p; +} + inline uint32_t f_add(volatile uint32_t op_a, volatile uint32_t op_b){ uint32_t result; asm volatile("fmv.s.x ft0, %0" ::"r"(op_a)); @@ -44,9 +49,26 @@ inline uint32_t f_add(volatile uint32_t op_a, volatile uint32_t op_b){ return result; } +inline uint32_t f_sub(volatile uint32_t op_a, volatile uint32_t op_b){ + uint32_t result; + asm volatile("fmv.s.x ft2, %0" ::"r"(op_a)); + asm volatile("fmv.s.x ft3, %0" ::"r"(op_b)); + asm volatile("fsub.s ft2,ft2,ft3" ::); + asm volatile("fmv.x.s %0,ft2" :"=r"(result):); + return result; +} + +inline uint32_t f_lt(volatile uint32_t op_a, volatile uint32_t op_b){ + volatile uint32_t result; + asm volatile("fmv.s.x ft4, %0" ::"r"(op_a)); + asm volatile("fmv.s.x ft5, %0" ::"r"(op_b)); + asm volatile("flt.s %0,ft4,ft5" :"=r"(result):); + return result; +} + int main(void) { uint32_t error = 0; - + #ifndef CV32E40X volatile float a, b, c; a = A_VAL; @@ -60,11 +82,21 @@ int main(void) { printf("Test PASSED\n"); } #else - uint32_t D, E, F; - D = 0x414570A4; // Binary for 12.34f - E = 0x42631EB8; // Binary for 56.78f - F = f_add(D, E); - printf("Float operation result: 0x%08x [expected: 0x%08x]\n", F, F_EXP); + volatile uint32_t a, b, c; + a = f32_bits(A_VAL); + b = f32_bits(B_VAL); + c = f_add(a, b); + + uint32_t diff = f_sub(c, f32_bits(C_EXP)); + if (f_lt(diff, 0)) + diff = f_sub(0, diff); + + if (f_lt(diff, f32_bits(FP_TH))){ + printf("Test PASSED\n"); + }else{ + printf("Test FAILED\n"); + error++; + } #endif return error; From 27aeb5b5cb44acb3704b20f29d6d83beb55318d2 Mon Sep 17 00:00:00 2001 From: Luca Balboni Date: Fri, 21 Aug 2026 15:19:08 +0200 Subject: [PATCH 3/3] Updated NON_FREE_COMMIT --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index ea5e801b..6ff8a49a 100644 --- a/Makefile +++ b/Makefile @@ -547,7 +547,7 @@ hw-all: hw-clean hw-lib hw-compile hw-opt # Nonfree components MAGIA_NONFREE_REMOTE ?= $(GITLAB_UNIBO_SSH_STRING)/magia/nonfree.git MAGIA_NONFREE_DIR ?= nonfree -MAGIA_NONFREE_COMMIT ?= 85b1df9cedbe7a52a361c05fea9181e084e2b4c8 +MAGIA_NONFREE_COMMIT ?= b394453ada24c84d5dcb7fd7b30d35fbf5cff4b1 MAGIA_NONFREE_DEPS ?= 1 .PHONY: magia-nonfree-init