diff --git a/.github/workflows/floogen.yml b/.github/workflows/floogen.yml index 318d3eba..50c5e33b 100644 --- a/.github/workflows/floogen.yml +++ b/.github/workflows/floogen.yml @@ -61,7 +61,7 @@ jobs: uses: actions/upload-artifact@v4 with: name: ${{ matrix.examples }} - path: generated/${{ matrix.examples }}_floo_noc.sv + path: generated/floo_${{ matrix.examples }}_noc.sv if-no-files-found: error retention-days: 1 diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index e84133b1..bcecbb8d 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -14,62 +14,6 @@ on: jobs: - ############### - # Check Clean # - ############### - check-clean: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - - uses: actions/setup-python@v5 - with: - python-version: '3.10' - cache: 'pip' - - name: Install dependencies and package - run: | - python -m pip install --upgrade pip - pip install . - - name: Install bender - uses: pulp-platform/pulp-actions/bender-install@v2 - - name: Install Verible - uses: chipsalliance/verible-actions-common/install-verible@main - with: - github_token: ${{ secrets.GITHUB_TOKEN }} - - name: Make clean sources - run: | - make clean pkg-sources - - name: Check clean - run: | - git status && test -z "$(git status --porcelain)" - - ############### - # Check Stale # - ############### - check-stale: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - - uses: actions/setup-python@v5 - with: - python-version: '3.10' - cache: 'pip' - - name: Install dependencies and package - run: | - python -m pip install --upgrade pip - pip install . - - name: Install bender - uses: pulp-platform/pulp-actions/bender-install@v2 - - name: Install Verible - uses: chipsalliance/verible-actions-common/install-verible@main - with: - github_token: ${{ secrets.GITHUB_TOKEN }} - - name: Make clean sources - run: | - make -B pkg-sources - - name: Check clean - run: | - git status && test -z "$(git status --porcelain)" - ##################### # Bender up-to-date # ##################### diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 2b8fa989..c5c83ce8 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -26,7 +26,7 @@ compile-vsim: stage: build script: - make compile-sim VC=true | tee compile.log 2>&1 - - '! grep "Error: " compile.log' + - '! grep "\*\* Error" compile.log' needs: - collect-bender-sources artifacts: @@ -49,7 +49,7 @@ run-vsim: - tb_floo_router - tb_floo_vc_router - tb_floo_axi_chimney - - tb_floo_narrow_wide_chimney + - tb_floo_nw_chimney - tb_floo_rob needs: - collect-bender-sources @@ -65,7 +65,7 @@ run-traffic: JOB_NAME: mesh parallel: matrix: - - VSIM_TB_DUT: [tb_floo_dma_mesh, tb_floo_vc_dma_mesh] + - VSIM_TB_DUT: [tb_floo_dma_mesh] # Fix: `tb_floo_vc_dma_mesh` has issues with boundary accesses TRAFFIC_TYPE: [random, hbm, onehop, bit_complement, bit_reverse, bit_rotation, neighbor, shuffle, transpose, tornado, single_dest_boundary, single_dest_center] TRAFFIC_RW: [read, write] needs: diff --git a/Bender.yml b/Bender.yml index 477fb40d..9d5f96cf 100644 --- a/Bender.yml +++ b/Bender.yml @@ -21,8 +21,6 @@ export_include_dirs: sources: # Level 0 - hw/floo_pkg.sv - - hw/floo_axi_pkg.sv - - hw/floo_narrow_wide_pkg.sv # Level 1 - hw/floo_cut.sv - hw/floo_fifo.sv @@ -36,11 +34,11 @@ sources: - hw/floo_rob_wrapper.sv - hw/floo_meta_buffer.sv # Level 2 - - hw/floo_narrow_wide_join.sv + - hw/floo_nw_join.sv - hw/floo_axi_chimney.sv - - hw/floo_narrow_wide_chimney.sv + - hw/floo_nw_chimney.sv - hw/floo_router.sv - - hw/floo_narrow_wide_router.sv + - hw/floo_nw_router.sv - target: vc_router files: @@ -56,12 +54,10 @@ sources: - hw/vc_router_util/floo_vc_assignment.sv - hw/vc_router_util/floo_vc_router_switch.sv - hw/vc_router_util/floo_vc_selection.sv - - hw/floo_vc_axi_pkg.sv - - hw/floo_vc_narrow_wide_pkg.sv # Level 2 - - hw/floo_vc_narrow_wide_chimney.sv - hw/floo_vc_router.sv - - hw/floo_vc_narrow_wide_router.sv + - hw/floo_nw_vc_chimney.sv + - hw/floo_nw_vc_router.sv - target: test include_dirs: @@ -79,11 +75,9 @@ sources: - hw/test/floo_hbm_model.sv # Level 2 - hw/tb/tb_floo_axi_chimney.sv - - hw/tb/tb_floo_narrow_wide_chimney.sv + - hw/tb/tb_floo_nw_chimney.sv - hw/tb/tb_floo_router.sv - hw/tb/tb_floo_rob.sv - - hw/tb/tb_floo_dma_chimney.sv - - hw/tb/tb_floo_dma_nw_chimney.sv - hw/tb/tb_floo_dma_mesh.sv - target: all(test, vc_router) diff --git a/CHANGELOG.md b/CHANGELOG.md index a899b0de..8df9f90c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,61 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/) and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## Unreleased + +### Added + +#### Hardware +- The `floo_pkg` was extended with helper functions to calculate the size of AXI payloads and mapping of AXI to Floo Channels. +- Multiple configuration structs were introduced to enable a more flexible and non-verbose configuration of the FlooNoC modules. + - The `AxiCfg` describes all the necessary parameters needed for the type definitions of a bidirectional AXI interface + - The `RouteCfg` describes all the necessary routing information parameters required by the chimneys. + - The `ChimneyCfg` describes all other parameters for the data path of the chimney (e.g. Mgr/Sbr port enable, number of oustanding transactions, RoB types & sizes, etc.) +- The `floo_test_pkg` now defines default configurations for all the new configuration structs that are used by the testbenches. + +#### FlooGen +- The `data_width` and `user_width` fields for `protocols` are now also validated to be compatible with each other. +- All the various `*Cfg`'s is now rendered by _FlooGen_, either in the `*_noc_pkg` or in the `*_noc` module itself. + +### Changed + +#### Hardware +- The `floo_narrow_wide_*` modules and the corresponding testbenches were renamed to `floo_nw_*` to be more concise. +- The flit type definitions are now implemented as SystemVerilog macros in `typedef.svh`. +- The parametrization of the chimney modules has changed dramatically. They now use the newly introduced `*Cfg`'s from the `floo_pkg`. In the narrow-wide chimneys, both datapaths now have their own configs (i.e. `*CfgN` and `*CfgW`), to reduce the verbosity of the module instantiation. +- The payload field name in each `*_chan_t` type previously had its own name. This was unified to `payload` since `*_chan_t` already determines the type of the payload. +- The input and output buffer FIFO depth of the routers were renamed to `InFifoDepth` and `OutFifoDepth` to be more consistent (previously `ChannelFifoDepth` and `OutputFifoDepth`). +- The narrow-wide router wrapper now also requires the `AxiCfg` structs to redefine the link types internally. +- The `ReorderBufferSize` parameters was shortened to `RoBSize`. +- All testbenches were adapted to all changes. +- All verification IPs were adapted to the new configuration structs. + +#### FlooGen +- The link typedefs are now renderd with the macros in `typedef.svh` instead of rendering them in pure SystemVerilog. +- The template files were renamed to use the more concise `nw` naming scheme. +- The generated modules and packages of _FlooGen_ are now named `floo_*_noc` resp. `floo_*_noc_pkg` which is more consistent since all other modules have the `floo_*` prefix. +- The `protocols` schema was adapted a bit to be more intuitive. + - The `type` field was renamed to `protocol`, which currently only accepts `AXI4`. A new `type` field now is used by _FlooGen_ to now where to attach the protocol in the network interface. Currently, _FlooGen_ only supports the narrow-wide AXI configuration, hence only `narrow|wide` is allowed as `type` values. + - The `direction` field in the `protocol` schema is no longer required, since the direction is determined when specifying `mgr_port_protocol` and `sbr_port_protocol`. + - The `name` field must be unique now, since it is used by `mgr_port_protocol` and `sbr_port_protocol` to reference the exact protocol. + - All examples were adapted to reflect those changes. + +### Fixed + +- A bug in the calcuation of the RoB offset in `floo_rob` was fixed. Previously, the allocation and the write process used the same counter in bursts for offset calculation, which resulted in wrong offsets. + +### Removed + +#### Hardware + +- As the flit type definitions were moved to `typedef.svh`, the auto-generated `floo_*_pkg` packages were removed from the repository. Furthermore, all the (global) imports of those packages in the modules were replaced by parameters. +- The testbench `tb_floo_nw_chimney` was removed since it was neither used nor maintained anymore. +- The `IdIsPort` routing algorithm was removed since it can only be used for routes over a single router. The same functionality can be achieved with the `SourceRouting` algorithm. + +#### FlooGen +- The package generation was removed from _FlooGen_ since it is now handled by the `typedef.svh` file. Further, the `--only-pkg` and `--pkg-outdir` flags were removed from the _FlooGen_ CLI. +- The calculation of link sizes and AXI to Floo channel mapping was removed from the _FlooGen_ configuration file. This is now handled by the `floo_pkg` helper functions. + ## [0.5.0] - 2024-09-13 ### Added diff --git a/Makefile b/Makefile index 72bdd4d0..ffbd74dc 100644 --- a/Makefile +++ b/Makefile @@ -72,15 +72,10 @@ endif ########### FLOOGEN ?= floogen +FLOO_CFG_DIR ?= $(MKFILE_DIR)floogen/examples +FLOOGEN_CFG ?= $(FLOO_CFG_DIR)/single_cluster.yml FLOOGEN_OUT_DIR ?= $(MKFILE_DIR)generated -FLOOGEN_PKG_OUT_DIR ?= $(MKFILE_DIR)hw -FLOOGEN_CFG_DIR ?= $(MKFILE_DIR)floogen/examples -FLOOGEN_TPL_DIR ?= $(MKFILE_DIR)floogen/templates - -FLOOGEN_PKG_CFG ?= $(shell find $(FLOOGEN_CFG_DIR) -name "*_pkg.yml") -FLOOGEN_PKG_SRC ?= $(patsubst $(FLOOGEN_CFG_DIR)/%_pkg.yml,$(FLOOGEN_PKG_OUT_DIR)/floo_%_pkg.sv,$(FLOOGEN_PKG_CFG)) -FLOOGEN_TPL ?= $(shell find $(FLOOGEN_TPL_DIR) -name "*.mako") .PHONY: install-floogen pkg-sources sources clean-sources @@ -90,12 +85,8 @@ check-floogen: install-floogen: @which $(FLOOGEN) > /dev/null || (echo "Installing floogen..." && pip install .) -pkg-sources: check-floogen $(FLOOGEN_PKG_SRC) -$(FLOOGEN_PKG_OUT_DIR)/floo_%_pkg.sv: $(FLOOGEN_CFG_DIR)/%_pkg.yml $(FLOOGEN_TPL) - $(FLOOGEN) -c $< --only-pkg --pkg-outdir $(FLOOGEN_PKG_OUT_DIR) $(FLOOGEN_ARGS) - sources: check-floogen - $(FLOOGEN) -c $(FLOOGEN_CFG) -o $(FLOOGEN_OUT_DIR) --pkg-outdir $(FLOOGEN_PKG_OUT_DIR) $(FLOOGEN_ARGS) + $(FLOOGEN) -c $(FLOOGEN_CFG) -o $(FLOOGEN_OUT_DIR) $(FLOOGEN_ARGS) clean-sources: rm -rf $(FLOOGEN_OUT_DIR) diff --git a/README.md b/README.md index 332d5287..6477e0aa 100644 --- a/README.md +++ b/README.md @@ -96,10 +96,9 @@ This repository includes the following NoC IPs: 1. **Routers:** A collection of different NoC router designs with varying features such as virtual channels, input/output buffering, and adaptive routing algorithms. 1. **Network Interfaces (NIs)**: A set of NoC network interfaces for connecting IPs to the NoC. -1. **Topologies:** A collection of NoC topologies, such as mesh, to enable the creation of various on-chip interconnects. -1. **Common IPs** A set of IPs used by the NoC IPs, such as FIFOs, Cuts and arbiters. -1. **Verification IPs (VIPs):** A set of VIPs to verify the correct functionality of the NoC IPs. -1. **Testbenches:** A set of testbenches to evaluate the performance of the NoC IPs, including throughput, latency. +2. **Common IPs** A set of IPs used by the NoC IPs, such as FIFOs, Cuts and arbiters. +3. **Verification IPs (VIPs):** A set of VIPs to verify the correct functionality of the NoC IPs. +4. **Testbenches:** A set of testbenches to evaluate the performance of the NoC IPs, including throughput, latency. ### Routers | Name | Description | Doc | @@ -113,12 +112,6 @@ This repository includes the following NoC IPs: | [floo_axi_chimney](hw/floo_axi_chimney.sv) | A bidirectional network interface for connecting AXI4 Buses to the NoC | | | [floo_narrow_wide_chimney](hw/floo_narrow_wide_chimney.sv) | A bidirectional network interface for connecting narrow & wide AXI Buses to the multi-link NoC | | -### Topologies -| Name | Description | Doc | -| --- | --- | --- | -| [floo_mesh](hw/floo_mesh.sv) | A mesh topology with configurable number of rows and columns | | -| [floo_mesh_ruche](hw/floo_mesh_ruche.sv) | A mesh topology with ruche channels and a configurable number of rows and columns | | - ### Common IPs | Name | Description | Doc | | --- | --- | --- | diff --git a/floogen/examples/axi_pkg.yml b/floogen/examples/axi_pkg.yml deleted file mode 100644 index 9ab6e5bd..00000000 --- a/floogen/examples/axi_pkg.yml +++ /dev/null @@ -1,35 +0,0 @@ -# Copyright 2024 ETH Zurich and University of Bologna. -# Licensed under the Apache License, Version 2.0, see LICENSE for details. -# SPDX-License-Identifier: Apache-2.0 - -name: "narrow" -description: "flit configuration for narrow-only AXI4 interfaces" - -routing: - route_algo: "XY" - use_id_table: false - addr_offset_bits: 16 - num_x_bits: 3 - num_y_bits: 3 - -protocols: - - name: "axi" - type: "AXI4" - direction: "manager" - data_width: 64 - addr_width: 32 - id_width: 3 - user_width: 1 - - name: "axi" - type: "AXI4" - direction: "subordinate" - data_width: 64 - addr_width: 32 - id_width: 3 - user_width: 1 - -endpoints: [] - -routers: [] - -connections: [] diff --git a/floogen/examples/narrow_wide_pkg.yml b/floogen/examples/narrow_wide_pkg.yml deleted file mode 100644 index c8c24f77..00000000 --- a/floogen/examples/narrow_wide_pkg.yml +++ /dev/null @@ -1,49 +0,0 @@ -# Copyright 2024 ETH Zurich and University of Bologna. -# Licensed under the Apache License, Version 2.0, see LICENSE for details. -# SPDX-License-Identifier: Apache-2.0 - -name: "narrow_wide" -description: "flit configuration for narrow and wide AXI4 interfaces" - -routing: - route_algo: "XY" - use_id_table: false - addr_offset_bits: 16 - num_x_bits: 3 - num_y_bits: 3 - -protocols: - - name: "narrow" - type: "AXI4" - direction: "manager" - data_width: 64 - addr_width: 48 - id_width: 4 - user_width: 1 - - name: "narrow" - type: "AXI4" - direction: "subordinate" - data_width: 64 - addr_width: 48 - id_width: 2 - user_width: 1 - - name: "wide" - type: "AXI4" - direction: "manager" - data_width: 512 - addr_width: 48 - id_width: 3 - user_width: 1 - - name: "wide" - type: "AXI4" - direction: "subordinate" - data_width: 512 - addr_width: 48 - id_width: 1 - user_width: 1 - -endpoints: [] - -routers: [] - -connections: [] diff --git a/floogen/examples/occamy_mesh.yml b/floogen/examples/occamy_mesh.yml index 050053a5..045d00c7 100644 --- a/floogen/examples/occamy_mesh.yml +++ b/floogen/examples/occamy_mesh.yml @@ -10,35 +10,36 @@ routing: use_id_table: true protocols: - - name: "narrow" - type: "AXI4" - direction: "manager" + - name: "narrow_in" + type: "narrow" + protocol: "AXI4" data_width: 64 addr_width: 48 id_width: 4 user_width: 1 - - name: "narrow" - type: "AXI4" - direction: "subordinate" + - name: "narrow_out" + type: "narrow" + protocol: "AXI4" data_width: 64 addr_width: 48 id_width: 2 user_width: 1 - - name: "wide" - type: "AXI4" - direction: "manager" + - name: "wide_in" + type: "wide" + protocol: "AXI4" data_width: 512 addr_width: 48 id_width: 3 user_width: 1 - - name: "wide" - type: "AXI4" - direction: "subordinate" + - name: "wide_out" + type: "wide" + protocol: "AXI4" data_width: 512 addr_width: 48 id_width: 1 user_width: 1 + endpoints: - name: "cluster" array: [3, 8] @@ -46,41 +47,41 @@ endpoints: base: 0x0000_1000_0000 size: 0x0000_0004_0000 mgr_port_protocol: - - "narrow" - - "wide" + - "narrow_in" + - "wide_in" sbr_port_protocol: - - "narrow" - - "wide" + - "narrow_out" + - "wide_out" - name: "hbm" array: [8] addr_range: base: 0x0000_8000_0000 size: 0x0000_4000_0000 sbr_port_protocol: - - "narrow" - - "wide" + - "narrow_out" + - "wide_out" - name: "serial_link" array: [3] addr_range: base: 0x0100_0000_0000 size: 0x0010_000_0000 mgr_port_protocol: - - "narrow" - - "wide" + - "narrow_in" + - "wide_in" sbr_port_protocol: - - "narrow" - - "wide" + - "narrow_out" + - "wide_out" - name: "cva6" mgr_port_protocol: - - "narrow" + - "narrow_in" - name: "peripherals" addr_range: start: 0x0000_0000_0000 end: 0x0000_0fff_ffff mgr_port_protocol: - - "narrow" + - "narrow_in" sbr_port_protocol: - - "narrow" + - "narrow_out" routers: - name: "router" diff --git a/floogen/examples/occamy_mesh_src.yml b/floogen/examples/occamy_mesh_src.yml index c73c7fc7..624b7f24 100644 --- a/floogen/examples/occamy_mesh_src.yml +++ b/floogen/examples/occamy_mesh_src.yml @@ -10,30 +10,30 @@ routing: use_id_table: true protocols: - - name: "narrow" - type: "AXI4" - direction: "manager" + - name: "narrow_in" + type: "narrow" + protocol: "AXI4" data_width: 64 addr_width: 48 id_width: 4 user_width: 1 - - name: "narrow" - type: "AXI4" - direction: "subordinate" + - name: "narrow_out" + type: "narrow" + protocol: "AXI4" data_width: 64 addr_width: 48 id_width: 2 user_width: 1 - - name: "wide" - type: "AXI4" - direction: "manager" + - name: "wide_in" + type: "wide" + protocol: "AXI4" data_width: 512 addr_width: 48 id_width: 3 user_width: 1 - - name: "wide" - type: "AXI4" - direction: "subordinate" + - name: "wide_out" + type: "wide" + protocol: "AXI4" data_width: 512 addr_width: 48 id_width: 1 @@ -46,41 +46,41 @@ endpoints: base: 0x0000_1000_0000 size: 0x0000_0004_0000 mgr_port_protocol: - - "narrow" - - "wide" + - "narrow_in" + - "wide_in" sbr_port_protocol: - - "narrow" - - "wide" + - "narrow_out" + - "wide_out" - name: "hbm" array: [8] addr_range: base: 0x0000_8000_0000 size: 0x0000_4000_0000 sbr_port_protocol: - - "narrow" - - "wide" + - "narrow_out" + - "wide_out" - name: "serial_link" array: [3] addr_range: base: 0x0100_0000_0000 size: 0x0010_000_0000 mgr_port_protocol: - - "narrow" - - "wide" + - "narrow_in" + - "wide_in" sbr_port_protocol: - - "narrow" - - "wide" + - "narrow_out" + - "wide_out" - name: "cva6" mgr_port_protocol: - - "narrow" + - "narrow_in" - name: "peripherals" addr_range: start: 0x0000_0000_0000 end: 0x0000_0fff_ffff mgr_port_protocol: - - "narrow" + - "narrow_in" sbr_port_protocol: - - "narrow" + - "narrow_out" routers: - name: "router" diff --git a/floogen/examples/occamy_tree.yml b/floogen/examples/occamy_tree.yml index bff07d58..45d80e9d 100644 --- a/floogen/examples/occamy_tree.yml +++ b/floogen/examples/occamy_tree.yml @@ -11,30 +11,30 @@ routing: protocols: - - name: "narrow" - type: "AXI4" - direction: "manager" + - name: "narrow_in" + protocol: "AXI4" + type: "narrow" data_width: 64 addr_width: 48 id_width: 4 user_width: 1 - - name: "narrow" - type: "AXI4" - direction: "subordinate" + - name: "narrow_out" + protocol: "AXI4" + type: "narrow" data_width: 64 addr_width: 48 id_width: 2 user_width: 1 - - name: "wide" - type: "AXI4" - direction: "manager" + - name: "wide_in" + protocol: "AXI4" + type: "wide" data_width: 512 addr_width: 48 id_width: 3 user_width: 1 - - name: "wide" - type: "AXI4" - direction: "subordinate" + - name: "wide_out" + protocol: "AXI4" + type: "wide" data_width: 512 addr_width: 48 id_width: 1 @@ -47,37 +47,37 @@ endpoints: base: 0x0000_1000_0000 size: 0x0000_0004_0000 mgr_port_protocol: - - "narrow" - - "wide" + - "narrow_in" + - "wide_in" sbr_port_protocol: - - "narrow" - - "wide" + - "narrow_out" + - "wide_out" - name: "hbm" array: [8] addr_range: base: 0x0000_8000_0000 size: 0x0000_4000_0000 sbr_port_protocol: - - "narrow" - - "wide" + - "narrow_out" + - "wide_out" - name: "serial_link" addr_range: start: 0x0100_0000_0000 end: 0x01ff_ffff_ffff mgr_port_protocol: - - "narrow" - - "wide" + - "narrow_in" + - "wide_in" sbr_port_protocol: - - "narrow" - - "wide" + - "narrow_out" + - "wide_out" - name: "peripherals" addr_range: start: 0x0000_0000_0000 end: 0x0000_0fff_ffff mgr_port_protocol: - - "narrow" + - "narrow_in" sbr_port_protocol: - - "narrow" + - "narrow_out" routers: - name: "router" diff --git a/floogen/examples/single_cluster.yml b/floogen/examples/single_cluster.yml index ad53453a..68f3c0b2 100644 --- a/floogen/examples/single_cluster.yml +++ b/floogen/examples/single_cluster.yml @@ -10,30 +10,30 @@ routing: use_id_table: true protocols: - - name: "narrow" - type: "AXI4" - direction: "manager" + - name: "narrow_in" + type: "narrow" + protocol: "AXI4" data_width: 64 addr_width: 48 id_width: 4 user_width: 1 - - name: "narrow" - type: "AXI4" - direction: "subordinate" + - name: "narrow_out" + type: "narrow" + protocol: "AXI4" data_width: 64 addr_width: 48 id_width: 2 user_width: 1 - - name: "wide" - type: "AXI4" - direction: "manager" + - name: "wide_in" + type: "wide" + protocol: "AXI4" data_width: 512 addr_width: 48 id_width: 3 user_width: 1 - - name: "wide" - type: "AXI4" - direction: "subordinate" + - name: "wide_out" + type: "wide" + protocol: "AXI4" data_width: 512 addr_width: 48 id_width: 1 @@ -45,39 +45,39 @@ endpoints: base: 0x0000_1000_0000 size: 0x0000_0004_0000 mgr_port_protocol: - - "narrow" - - "wide" + - "narrow_in" + - "wide_in" sbr_port_protocol: - - "narrow" - - "wide" + - "narrow_out" + - "wide_out" - name: "hbm" addr_range: base: 0x0010_0000_0000 size: 0x0000_4000_0000 sbr_port_protocol: - - "narrow" - - "wide" + - "narrow_out" + - "wide_out" - name: "serial_link" addr_range: base: 0x0100_0000_0000 size: 0x0010_000_0000 mgr_port_protocol: - - "narrow" - - "wide" + - "narrow_in" + - "wide_in" sbr_port_protocol: - - "narrow" - - "wide" + - "narrow_out" + - "wide_out" - name: "cva6" mgr_port_protocol: - - "narrow" + - "narrow_in" - name: "peripherals" addr_range: start: 0x0000_0000_0000 end: 0x0000_0fff_ffff mgr_port_protocol: - - "narrow" + - "narrow_in" sbr_port_protocol: - - "narrow" + - "narrow_out" routers: - name: "router" diff --git a/floogen/examples/terapool.yml b/floogen/examples/terapool.yml index 5d46c257..0ac92757 100644 --- a/floogen/examples/terapool.yml +++ b/floogen/examples/terapool.yml @@ -10,30 +10,32 @@ routing: use_id_table: true protocols: - - name: "narrow" - type: "AXI4" - direction: "manager" + - name: "narrow_in" + type: "narrow" + protocol: "AXI4" data_width: 64 addr_width: 48 id_width: 4 user_width: 1 - - name: "narrow" - type: "AXI4" - direction: "subordinate" + direction: "input" + - name: "narrow_out" + type: "narrow" + protocol: "AXI4" data_width: 64 addr_width: 48 id_width: 2 user_width: 1 - - name: "wide" - type: "AXI4" - direction: "manager" + direction: "output" + - name: "wide_in" + type: "wide" + protocol: "AXI4" data_width: 512 addr_width: 48 id_width: 3 user_width: 1 - - name: "wide" - type: "AXI4" - direction: "subordinate" + - name: "wide_out" + type: "wide" + protocol: "AXI4" data_width: 512 addr_width: 48 id_width: 1 @@ -43,22 +45,22 @@ endpoints: - name: "group" array: [4, 4] mgr_port_protocol: - - "wide" + - "wide_in" - name: "hbm" array: [16] addr_range: base: 0x0000_8000_0000 size: 0x0000_4000_0000 sbr_port_protocol: - - "wide" + - "wide_out" - name: "peripherals" addr_range: start: 0x0000_0000_0000 end: 0x0000_0fff_ffff mgr_port_protocol: - - "wide" + - "wide_in" sbr_port_protocol: - - "wide" + - "wide_out" routers: - name: "group_router" diff --git a/floogen/examples/vc_axi_pkg.yml b/floogen/examples/vc_axi_pkg.yml deleted file mode 100644 index 674cf303..00000000 --- a/floogen/examples/vc_axi_pkg.yml +++ /dev/null @@ -1,37 +0,0 @@ -# Copyright 2024 ETH Zurich and University of Bologna. -# Licensed under the Apache License, Version 2.0, see LICENSE for details. -# SPDX-License-Identifier: Apache-2.0 - -name: "narrow" -description: "flit configuration for narrow-only AXI4 interfaces" - -routing: - route_algo: "XY" - use_id_table: false - addr_offset_bits: 16 - num_x_bits: 3 - num_y_bits: 3 - port_id_bits: 2 - num_vc_id_bits: 3 - -protocols: - - name: "axi" - type: "AXI4" - direction: "manager" - data_width: 64 - addr_width: 32 - id_width: 3 - user_width: 1 - - name: "axi" - type: "AXI4" - direction: "subordinate" - data_width: 64 - addr_width: 32 - id_width: 3 - user_width: 1 - -endpoints: [] - -routers: [] - -connections: [] diff --git a/floogen/examples/vc_narrow_wide_pkg.yml b/floogen/examples/vc_narrow_wide_pkg.yml deleted file mode 100644 index 21995609..00000000 --- a/floogen/examples/vc_narrow_wide_pkg.yml +++ /dev/null @@ -1,51 +0,0 @@ -# Copyright 2024 ETH Zurich and University of Bologna. -# Licensed under the Apache License, Version 2.0, see LICENSE for details. -# SPDX-License-Identifier: Apache-2.0 - -name: "narrow_wide" -description: "flit configuration for narrow and wide AXI4 interfaces" - -routing: - route_algo: "XY" - use_id_table: false - addr_offset_bits: 16 - num_x_bits: 3 - num_y_bits: 3 - port_id_bits: 2 - num_vc_id_bits: 3 - -protocols: - - name: "narrow" - type: "AXI4" - direction: "manager" - data_width: 64 - addr_width: 48 - id_width: 4 - user_width: 1 - - name: "narrow" - type: "AXI4" - direction: "subordinate" - data_width: 64 - addr_width: 48 - id_width: 2 - user_width: 1 - - name: "wide" - type: "AXI4" - direction: "manager" - data_width: 512 - addr_width: 48 - id_width: 3 - user_width: 1 - - name: "wide" - type: "AXI4" - direction: "subordinate" - data_width: 512 - addr_width: 48 - id_width: 1 - user_width: 1 - -endpoints: [] - -routers: [] - -connections: [] diff --git a/floogen/floo_gen.py b/floogen/floo_gen.py index 9d232b5e..25bf9492 100755 --- a/floogen/floo_gen.py +++ b/floogen/floo_gen.py @@ -27,16 +27,6 @@ def parse_args(): required=False, help="Path to the output directory of the generated output.", ) - parser.add_argument( - "--pkg-outdir", - dest="pkg_outdir", - type=Path, - required=False, - help="Path to the output directory of the generated output.", - ) - parser.add_argument( - "--only-pkg", dest="only_pkg", action="store_true", help="Only generate the package file." - ) parser.add_argument( "--no-format", dest="no_format", @@ -59,51 +49,29 @@ def main(): # pylint: disable=too-many-branches # default output directory outdir = Path(os.getcwd(), "generated") - if args.pkg_outdir: - pkg_outdir = Path(os.getcwd(), args.pkg_outdir) - else: - # default output directory - pkg_outdir = Path(os.getcwd(), "hw") - if not pkg_outdir.exists(): - raise FileNotFoundError( - f"Was not able to find the directory to store the package file: {pkg_outdir}" - ) - - if not args.only_pkg: - network.create_network() - network.compile_network() - network.gen_routing_info() + network.create_network() + network.compile_network() + network.gen_routing_info() - # Visualize the network graph - if args.visualize: - if outdir: - network.visualize(filename=outdir / (network.name + ".pdf")) - else: - network.visualize(savefig=False) - - # Generate the network description - rendered_top = network.render_network() - if not args.no_format: - rendered_top = verible_format(rendered_top) - # Write the network description to file or print it to stdout + # Visualize the network graph + if args.visualize: if outdir: - outdir.mkdir(parents=True, exist_ok=True) - top_file_name = outdir / (network.name + "_floo_noc.sv") - with open(top_file_name, "w+", encoding="utf-8") as top_file: - top_file.write(rendered_top) + network.visualize(filename=outdir / (network.name + ".pdf")) else: - print(rendered_top) + network.visualize(savefig=False) - axi_type, rendered_pkg = network.render_link_cfg() + # Generate the network description + rendered_top = network.render_network() if not args.no_format: - rendered_pkg = verible_format(rendered_pkg) - # Write the link configuration to file or print it to stdout - if pkg_outdir: - cfg_file_name = pkg_outdir / (f"floo_{axi_type}_pkg.sv") - with open(cfg_file_name, "w+", encoding="utf-8") as cfg_file: - cfg_file.write(rendered_pkg) - else: - print(rendered_pkg) + rendered_top = verible_format(rendered_top) + # Write the network description to file or print it to stdout + if outdir: + outdir.mkdir(parents=True, exist_ok=True) + top_file_name = outdir / f"floo_{network.name}_noc.sv" + with open(top_file_name, "w+", encoding="utf-8") as top_file: + top_file.write(rendered_top) + else: + print(rendered_top) if __name__ == "__main__": diff --git a/floogen/model/connection.py b/floogen/model/connection.py index b31812bb..54555b0d 100644 --- a/floogen/model/connection.py +++ b/floogen/model/connection.py @@ -6,7 +6,7 @@ # Author: Tim Fischer from typing import Optional, List, Tuple -from pydantic import BaseModel, field_validator, model_validator +from pydantic import BaseModel, ConfigDict, field_validator, model_validator from floogen.model.routing import XYDirections @@ -14,6 +14,8 @@ class ConnectionDesc(BaseModel): """Connection class to describe a connection between routers and endpoints.""" + model_config = ConfigDict(extra="forbid") + description: Optional[str] = "" src: str dst: str diff --git a/floogen/model/endpoint.py b/floogen/model/endpoint.py index acf4ad00..42bcde72 100644 --- a/floogen/model/endpoint.py +++ b/floogen/model/endpoint.py @@ -5,7 +5,7 @@ # # Author: Tim Fischer from typing import Optional, List, Union, Tuple -from pydantic import BaseModel, field_validator, model_validator +from pydantic import BaseModel, ConfigDict, field_validator, model_validator from floogen.model.routing import AddrRange, Id, Coord from floogen.model.protocol import Protocols @@ -16,6 +16,8 @@ class EndpointDesc(BaseModel): Endpoint class to describe an endpoint with adress ranges and configuration parameters. """ + model_config = ConfigDict(extra="forbid") + name: str description: Optional[str] = "" array: Optional[Union[Tuple[int], Tuple[int, int]]] = None @@ -90,11 +92,11 @@ def from_desc(cls, desc: EndpointDesc, """Create an endpoint from a description.""" return cls(**desc.model_dump(), mgr_ports=mgr_ports, sbr_ports=sbr_ports) - def render_ports(self): + def render_ports(self, pkg_name=""): """Render the ports of the endpoint.""" ports = [] for port in self.mgr_ports: - ports += port.render_port() + ports += port.render_port(pkg_name) for port in self.sbr_ports: - ports += port.render_port() + ports += port.render_port(pkg_name) return ports diff --git a/floogen/model/link.py b/floogen/model/link.py index 165f35f3..2e6ce7e6 100644 --- a/floogen/model/link.py +++ b/floogen/model/link.py @@ -9,7 +9,7 @@ from abc import ABC, abstractmethod from pydantic import BaseModel -from floogen.utils import snake_to_camel, sv_typedef, sv_struct_typedef, clog2 +from floogen.utils import sv_struct_typedef class Link(BaseModel, ABC): @@ -37,118 +37,9 @@ def declare(self): def render_ports(self): """Declare the ports of the link.""" - @classmethod - def render_enum_decl(cls): - """Render the enum declaration of the link.""" - i = 0 - string = "" - for _, mapping in cls.channel_mapping.items(): - for ch_type, axi_chs in mapping.items(): - for axi_ch in axi_chs: - name = f"{ch_type}_{axi_ch}" - string += f"{snake_to_camel(name)} = TMP_BIT_WIDTH'd{i},\n" - i += 1 - bitwidth = clog2(i+1) - string = f"typedef enum logic [{bitwidth-1}:0]{{" + string - string = string.replace("TMP_BIT_WIDTH", str(bitwidth)) - string += f"NumAxiChannels = {bitwidth}'d{i}\n}} axi_ch_e;\n" - return string - - @classmethod - def get_inverted_mapping(cls): - """Return the mapping from axi to physical channels.""" - mappings = {} - for phys_ch, ch_types in cls.channel_mapping.items(): - for ch_type, axi_chs in ch_types.items(): - for axi_ch in axi_chs: - mappings.setdefault(ch_type, {})[axi_ch] = phys_ch - return mappings - - @classmethod - def calc_link_sizes(cls, protocols): - """Infer the link sizes from the network.""" - link_sizes = {} - for phys_ch, axi_chs in cls.channel_mapping.items(): - # Get all protocols that use this channel - prots = [ - p - for p in protocols - if p.name in axi_chs and p.direction == "manager" - ] - # Get only the exact AXI channels that are used by the link - used_axi_chs = [axi_chs[p.name] for p in prots] - # Get the sizes of the AXI channels - axi_ch_sizes = [p.get_axi_channel_sizes() for p in prots] - link_message_sizes = [] - for used_axi_ch, axi_ch_size in zip(used_axi_chs, axi_ch_sizes): - link_message_sizes += [axi_ch_size[ch] for ch in used_axi_ch] - # Get the maximum size of the link - link_sizes[phys_ch] = max(link_message_sizes) - return link_sizes - - @classmethod - def render_flit(cls, protocols): - """Render the flit of the protocol.""" - string = "" - inv_mapping = cls.get_inverted_mapping() - link_sizes = cls.calc_link_sizes(protocols) - for p in protocols: - if p.direction == "manager": - for axi_ch, size in p.get_axi_channel_sizes().items(): - phys_ch = inv_mapping[p.name][axi_ch] - phys_ch_size = link_sizes[phys_ch] - rsvd_size = phys_ch_size - size - struct_dict = { - "hdr": "hdr_t", - axi_ch: f"{p.full_name()}_{axi_ch}_chan_t", - } - if phys_ch_size - size > 0: - struct_dict["rsvd"] = f"logic[{rsvd_size-1}:0]" - string += sv_struct_typedef(f"floo_{p.name}_{axi_ch}_flit_t", struct_dict) - - for phys_ch, size in link_sizes.items(): - string += sv_typedef(f"floo_{phys_ch}_payload_t", "logic", size) - struct_dict = { - "hdr": "hdr_t", - "payload": f"floo_{phys_ch}_payload_t", - } - string += sv_struct_typedef(f"floo_{phys_ch}_generic_flit_t", struct_dict) - return string - - @classmethod - def render_channels(cls) -> str: - """Render the channels of the protocol.""" - string = "" - for phys_ch, axi_chs in cls.channel_mapping.items(): - struct_dict = {} - for axi_name, axi_chs in axi_chs.items(): - for axi_ch in axi_chs: - struct_dict[axi_name + '_' + axi_ch] = f"floo_{axi_name}_{axi_ch}_flit_t" - struct_dict["generic"] = f"floo_{phys_ch}_generic_flit_t" - string += sv_struct_typedef(f"floo_{phys_ch}_chan_t", struct_dict, union=True) - return string - - @classmethod - def render_link_typedefs(cls) -> str: - """Render the typedefs of the protocol.""" - string = "" - for phys_ch in cls.channel_mapping: - struct_dict = {"valid": "logic", - "ready": "logic", - phys_ch: f"floo_{phys_ch}_chan_t"} - string += sv_struct_typedef(f"floo_{phys_ch}_t", struct_dict) - return string - - class NarrowWideLink(Link): """Link class to describe a NarrowWidelink.""" - channel_mapping: ClassVar[Dict] = { - "req": {"narrow": ["aw", "w", "ar"], "wide": ["ar"]}, - "rsp": {"narrow": ["b", "r"], "wide": ["b"]}, - "wide": {"wide": ["aw", "w", "r"]}, - } - req_type: ClassVar[str] = "floo_req_t" rsp_type: ClassVar[str] = "floo_rsp_t" wide_type: ClassVar[str] = "floo_wide_t" @@ -168,21 +59,12 @@ def wide_name(self, is_reversed=False): return f"{self.source}_to_{self.dest}_wide" @classmethod - def get_axi_chs(cls): - """Return all the AXI channels.""" - channels = [] - for axi_chs in cls.channel_mapping.values(): - for key, values in axi_chs.items(): - for v in values: - channels.append(f"{key}_{v}") - return channels - - @classmethod - def get_mapping(cls): - """Return the mapping of the link.""" - return cls.channel_mapping - - + def render_typedefs(cls, axi_narrow, axi_wide, cfg_n, cfg_w): + """Render the typedefs of the links.""" + string = f"`FLOO_TYPEDEF_NW_CHAN_ALL(axi, req, rsp, wide, \ + {axi_narrow}, {axi_wide}, {cfg_n}, {cfg_w}, hdr_t)\n\n" + string += "`FLOO_TYPEDEF_NW_LINK_ALL(req, rsp, wide, req, rsp, wide)\n" + return string def declare(self): """Declare the link in the generated code.""" diff --git a/floogen/model/network.py b/floogen/model/network.py index 270644eb..3fd1d5e8 100644 --- a/floogen/model/network.py +++ b/floogen/model/network.py @@ -20,7 +20,7 @@ from floogen.model.endpoint import EndpointDesc, Endpoint from floogen.model.router import RouterDesc, NarrowWideRouter from floogen.model.connection import ConnectionDesc -from floogen.model.link import NarrowWideLink, NarrowWideVCLink, NarrowLink, NarrowVCLink +from floogen.model.link import NarrowWideLink, NarrowWideVCLink from floogen.model.network_interface import NarrowWideAxiNI from floogen.model.protocol import AXI4, AXI4Bus from floogen.utils import clog2, sv_enum_typedef, sv_param_decl @@ -32,14 +32,11 @@ class Network(BaseModel): # pylint: disable=too-many-public-methods Network class to describe a network with routers and endpoints. """ - model_config = ConfigDict(arbitrary_types_allowed=True) + model_config = ConfigDict(arbitrary_types_allowed=True, extra="forbid") - with as_file(files(floogen.templates).joinpath("floo_noc_top.sv.mako")) as _tpl_path: + with as_file(files(floogen.templates).joinpath("floo_top_noc.sv.mako")) as _tpl_path: tpl: ClassVar = Template(filename=str(_tpl_path)) - with as_file(files(floogen.templates).joinpath("floo_flit_pkg.sv.mako")) as _tpl_path: - tpl_pkg: ClassVar = Template(filename=str(_tpl_path)) - name: str description: Optional[str] protocols: List[AXI4] @@ -88,11 +85,21 @@ def validate_routers(cls, routers): @field_validator("protocols") @classmethod - def validate_addr_width(cls, protocols): - """Check that all protocols have the same address width.""" - addr_widths = [prot.addr_width for prot in protocols] - if len(set(addr_widths)) != 1: + def validate_protocols(cls, protocols): + """Check that names are unique and parameters are compatible.""" + # Check that address width is unique among all protocols + if len(set(prot.addr_width for prot in protocols)) != 1: raise ValueError("All protocols must have the same address width") + # Check that `narrow` and `wide` protocols have the same data width + if len(set(prot.data_width for prot in protocols if prot.type == "narrow")) != 1: + raise ValueError("All `narrow` protocols must have the same data width") + if len(set(prot.data_width for prot in protocols if prot.type == "wide")) != 1: + raise ValueError("All `wide` protocols must have the same data width") + # Check that `narrow` and `wide` protocols have the same user width + if len(set(prot.user_width for prot in protocols if prot.type == "narrow")) != 1: + raise ValueError("All `narrow` protocols must have the same user width") + if len(set(prot.user_width for prot in protocols if prot.type == "wide")) != 1: + raise ValueError("All `wide` protocols must have the same user width") return protocols @model_validator(mode="after") @@ -408,9 +415,11 @@ def compile_endpoints(self): if ep.is_mgr(): for i in ep.mgr_port_protocol: prot = {} - protocol = [ - p for p in self.protocols if p.name == i and p.direction == "manager" - ][0] + protocol = next(p for p in self.protocols if p.name == i) + if protocol.direction is None: + protocol.direction = "input" + elif protocol.direction != "input": + raise ValueError("Protocol cannot be used for both manager and subordinate") prot["base_name"] = f"{ep.name}_{protocol.name}" prot["source"] = ep_name prot["dest"] = ep.get_ni_name(ep_name) @@ -422,10 +431,12 @@ def compile_endpoints(self): self.graph.set_edge_obj((prot["source"], prot["dest"]), mgr_ports) if ep.is_sbr(): for i in ep.sbr_port_protocol: - protocol = [ - p for p in self.protocols if p.name == i and p.direction == "subordinate" - ][0] prot = {} + protocol = next(p for p in self.protocols if p.name == i) + if protocol.direction is None: + protocol.direction = "output" + elif protocol.direction != "output": + raise ValueError("Protocol cannot be used for both manager and subordinate") prot["base_name"] = f"{ep.name}_{protocol.name}" prot["source"] = ep.get_ni_name(ep_name) prot["dest"] = ep_name @@ -481,7 +492,7 @@ def compile_nis(self): mgr_prot_edges = self.graph.get_edges_to(ni_name, filters=[self.graph.is_prot_edge]) for protocols in sbr_prot_edges: for prot in protocols: - match prot.name: + match prot.type: case "narrow": ni_dict["sbr_narrow_port"] = prot case "wide": @@ -489,7 +500,7 @@ def compile_nis(self): for protocols in mgr_prot_edges: for prot in protocols: - match prot.name: + match prot.type: case "narrow": ni_dict["mgr_narrow_port"] = prot case "wide": @@ -610,17 +621,36 @@ def gen_sam(self): addr_table.append(addr_rule) return RouteMap(name="sam", rules=addr_table) - def render_ports(self): + def render_ports(self, pkg_name=""): """Render the ports in the generated code.""" ports, declared_ports = [], [] for ep in self.graph.get_ep_nodes(): if ep.name in declared_ports: continue - ports += ep.render_ports() + ports += ep.render_ports(pkg_name=pkg_name) declared_ports.append(ep.name) port_string = ",\n ".join(ports) + "\n" return port_string + def render_link_typedefs(self): + """Render the protocol configuration structs.""" + string = "" + narrow_in_prot = next((prot for prot in self.protocols + if prot.type == "narrow" and prot.direction == "input"), None) + narrow_out_prot = next((prot for prot in self.protocols + if prot.type == "narrow" and prot.direction == "output"), None) + wide_in_prot = next((prot for prot in self.protocols + if prot.type == "wide" and prot.direction == "input"), None) + wide_out_prot = next((prot for prot in self.protocols + if prot.type == "wide" and prot.direction == "output"), None) + string += AXI4.render_cfg("AxiCfgN", narrow_in_prot, narrow_out_prot) + string += AXI4.render_cfg("AxiCfgW", wide_in_prot, wide_out_prot) + + string += NarrowWideLink.render_typedefs( + narrow_in_prot.type_name(), wide_in_prot.type_name(), "AxiCfgN", "AxiCfgW" + ) + return string + def render_prots(self): """Render the protocols in the generated code.""" string = "" @@ -648,7 +678,8 @@ def render_ni_tables(self): string = "" sorted_ni_list = sorted(self.graph.get_ni_nodes(), key=lambda ni: ni.id.id, reverse=True) for ni in sorted_ni_list: - string += ni.table.render(num_route_bits=self.routing.num_route_bits, no_decl=True) + string += ni.table.render( + num_route_bits=self.routing.num_route_bits, no_decl=True) string += ",\n" string = "'{\n" + string[:-2] + "}\n" return sv_param_decl( @@ -676,22 +707,6 @@ def render_network(self): """Render the network in the generated code.""" return self.tpl.render(noc=self) - def render_link_cfg(self): - """Render the link configuration file""" - prot_names = [prot.name for prot in self.protocols] - if "wide" in prot_names and "narrow" in prot_names: - if self.routing.num_vc_id_bits > 0: - axi_type, link_type = "vc_narrow_wide", NarrowWideVCLink - else: - axi_type, link_type = "narrow_wide", NarrowWideLink - else: - if self.routing.num_vc_id_bits > 0: - axi_type, link_type = "vc_axi", NarrowVCLink - else: - axi_type, link_type = "axi", NarrowLink - - return axi_type, self.tpl_pkg.render(name=axi_type, noc=self, link=link_type) - def visualize(self, savefig=True, filename: pathlib.Path = "network.png"): """Visualize the network graph.""" ni_nodes = [name for name, _ in self.graph.get_ni_nodes(with_name=True)] diff --git a/floogen/model/network_interface.py b/floogen/model/network_interface.py index 8aa3cfdb..468561ed 100644 --- a/floogen/model/network_interface.py +++ b/floogen/model/network_interface.py @@ -51,7 +51,7 @@ class NarrowWideAxiNI(NetworkInterface): """ " NarrowWideNI class to describe a narrow-wide network interface.""" with as_file( - files(floogen.templates).joinpath("floo_narrow_wide_chimney.sv.mako") + files(floogen.templates).joinpath("floo_nw_chimney.sv.mako") ) as _tpl_path: tpl: ClassVar = Template(filename=str(_tpl_path)) diff --git a/floogen/model/protocol.py b/floogen/model/protocol.py index 2c7e15d3..2fe2262a 100644 --- a/floogen/model/protocol.py +++ b/floogen/model/protocol.py @@ -7,25 +7,18 @@ from typing import Optional, List, TypeVar, Union from typing_extensions import Annotated -from pydantic import BaseModel, StringConstraints, model_validator +from pydantic import BaseModel, StringConstraints -from floogen.utils import short_dir, snake_to_camel, sv_param_decl, sv_typedef +from floogen.utils import snake_to_camel, sv_param_decl, sv_typedef, sv_struct_render class ProtocolDesc(BaseModel): """Protocol class to describe a protocol.""" name: str description: Optional[str] = "" - type: str - direction: Annotated[str, StringConstraints(pattern=r"manager|subordinate")] - svdirection: str - - @model_validator(mode="before") - def set_svdirection(self): - """Set the SystemVerilog direction.""" - self["svdirection"] = "input" if self["direction"] == "manager" else "output" - return self - + protocol: Annotated[str, StringConstraints(pattern=r"AXI4")] + type: Annotated[str, StringConstraints(pattern=r"narrow|wide")] + direction: Optional[str] = None class AXI4(ProtocolDesc): """AXI4 protocol class.""" @@ -34,46 +27,13 @@ class AXI4(ProtocolDesc): addr_width: int id_width: int user_width: int + type_prefix: Optional[str] = "axi" - def get_axi_channel_sizes(self) -> dict: # pylint: disable=too-many-locals - """Return the sizes of each of the AXI channels.""" - - burst = 2 - resp = 2 - cache = 4 - prot = 3 - qos = 4 - region = 4 - length = 8 - size = 3 - atop = 6 - last = 1 - lock = 1 - - # Variable widths - iw = self.id_width - aw = self.addr_width - dw = self.data_width - uw = self.user_width - - axi_ch_size = {} - axi_ch_size["aw"] = ( - iw + aw + length + size + burst + lock + cache + prot + qos + region + atop + uw - ) - axi_ch_size["w"] = dw + dw // 8 + last + uw - axi_ch_size["b"] = iw + resp + uw - axi_ch_size["ar"] = ( - iw + aw + length + size + burst + lock + cache + prot + qos + region + uw - ) - axi_ch_size["r"] = iw + dw + resp + last + uw - - return axi_ch_size - - def full_name(self) -> str: - """Return the name of the protocol.""" - if "axi" in self.name: - return f"{self.name}_{short_dir(self.svdirection)}" - return f"axi_{self.name}_{short_dir(self.svdirection)}" + def type_name(self) -> str: + """Return the full name of the protocol.""" + if self.type_prefix is not None: + return f"{self.type_prefix}_{self.name}" + return self.name def render_params(self) -> str: """Render the parameters of the protocol.""" @@ -86,22 +46,34 @@ def render_params(self) -> str: def render_typedefs(self) -> str: """Render the typedefs of the protocol.""" - full_name = self.full_name() - string = sv_typedef(full_name + "_addr_t", array_size=self.addr_width) - string += sv_typedef(full_name + "_data_t", array_size=self.data_width) - string += sv_typedef(full_name + "_strb_t", array_size=self.data_width // 8) - string += sv_typedef(full_name + "_id_t", array_size=self.id_width) - string += sv_typedef(full_name + "_user_t", array_size=self.user_width) - string += f"`AXI_TYPEDEF_ALL_CT({full_name}, \ - {full_name}_req_t, \ - {full_name}_rsp_t, \ - {full_name}_addr_t, \ - {full_name}_id_t, \ - {full_name}_data_t, \ - {full_name}_strb_t, \ - {full_name}_user_t)\n\n" + name_t = self.type_name() + string = sv_typedef(name_t + "_addr_t", array_size=self.addr_width) + string += sv_typedef(name_t + "_data_t", array_size=self.data_width) + string += sv_typedef(name_t + "_strb_t", array_size=self.data_width // 8) + string += sv_typedef(name_t + "_id_t", array_size=self.id_width) + string += sv_typedef(name_t + "_user_t", array_size=self.user_width) + string += f"`AXI_TYPEDEF_ALL_CT({name_t}, \ + {name_t}_req_t, \ + {name_t}_rsp_t, \ + {name_t}_addr_t, \ + {name_t}_id_t, \ + {name_t}_data_t, \ + {name_t}_strb_t, \ + {name_t}_user_t)\n\n" return string + @classmethod + def render_cfg(cls, name, mgr_axi, sbr_axi) -> str: + """Render the configuration of the protocol.""" + fields = { + "AddrWidth": mgr_axi.addr_width, + "DataWidth": mgr_axi.data_width, + "UserWidth": mgr_axi.user_width, + "InIdWidth": mgr_axi.id_width, + "OutIdWidth": sbr_axi.id_width, + } + return sv_param_decl(name, sv_struct_render(fields), dtype="axi_cfg_t") + class AXI4Bus(AXI4): """AXI4 bus protocol class.""" @@ -113,15 +85,10 @@ class AXI4Bus(AXI4): arr_idx: Optional[List[int]] = None is_declared: bool = False subtype: str = "" - type_prefix: str = "axi" def _invert_dir(self): - """Invert the direction of the protocol.""" - return "input" if self.svdirection == "output" else "output" - - def _type_name(self): - """Return the type name of the protocol.""" - return f"{self.type_prefix}_{self.name}_{short_dir(self.svdirection)}" + """Returns the inverted direction of the protocol port.""" + return "input" if self.direction == "output" else "output" def _array_to_sv_array(self): """Convert the array to a SystemVerilog array.""" @@ -139,30 +106,19 @@ def _idx_to_sv_idx(self): return string return "" - def typedef(self) -> str: - """Return the typedef of the protocol.""" - return f"`AXI_TYPEDEF_ALL_CT({self._type_name()}, \ - {self._type_name()}_req_t, \ - {self._type_name()}_rsp_t, \ - logic[{self.addr_width-1}:0], \ - logic[{self.id_width-1}:0], \ - logic[{self.data_width-1}:0], \ - logic[{self.data_width//8-1}:0], \ - logic[{self.user_width-1}:0])" - def req_type(self) -> str: """Return the request type of the protocol.""" - return f"{self._type_name()}_req_t" + return f"{self.type_name()}_req_t" def rsp_type(self) -> str: """Return the response type of the protocol.""" - return f"{self._type_name()}_rsp_t" + return f"{self.type_name()}_rsp_t" def req_name(self, port=False, idx=False) -> str: """Return the request name of the protocol.""" idx = self._idx_to_sv_idx() if idx else "" if port: - return f"{self.base_name}_req_{self.svdirection[0]}{idx}" + return f"{self.base_name}_req_{str(self.direction)[0]}{idx}" return f"{self.source}_to_{self.dest}_req" def rsp_name(self, port=False, idx=False) -> str: @@ -178,16 +134,16 @@ def declare(self) -> str: string += f"{self.rsp_type()} {self.rsp_name()};\n" return string + "\n" - def render_port(self) -> List[str]: + def render_port(self, pkg_name="") -> List[str]: """Render the port of the protocol.""" rev_direction = self._invert_dir() ports = [] ports.append( - f"{self.svdirection} {self.req_type()} \ + f"{self.direction} {pkg_name}{self.req_type()} \ {self._array_to_sv_array()} {self.req_name(port=True)}" ) ports.append( - f"{rev_direction} {self.rsp_type()} \ + f"{rev_direction} {pkg_name}{self.rsp_type()} \ {self._array_to_sv_array()} {self.rsp_name(port=True)}" ) return ports diff --git a/floogen/model/router.py b/floogen/model/router.py index 461d26f6..dab48fcb 100644 --- a/floogen/model/router.py +++ b/floogen/model/router.py @@ -10,7 +10,7 @@ from importlib.resources import files, as_file from abc import ABC, abstractmethod -from pydantic import BaseModel, field_validator, model_validator +from pydantic import BaseModel, ConfigDict, field_validator, model_validator from mako.lookup import Template from floogen.model.routing import RouteMap, Id, Coord, RouteAlgo @@ -21,6 +21,8 @@ class RouterDesc(BaseModel): """Router class to describe (arrays of) a router""" + model_config = ConfigDict(extra="forbid") + name: str array: Optional[Union[Tuple[int], Tuple[int, int]]] = None tree: Optional[List[int]] = None @@ -75,7 +77,7 @@ class NarrowWideRouter(Router): """Router class to describe a narrow-wide router""" with as_file( - files(floogen.templates).joinpath("floo_narrow_wide_router.sv.mako") + files(floogen.templates).joinpath("floo_nw_router.sv.mako") ) as _tpl_path: _tpl: ClassVar = Template(filename=str(_tpl_path)) diff --git a/floogen/model/routing.py b/floogen/model/routing.py index 8f0d6e36..ef717b49 100644 --- a/floogen/model/routing.py +++ b/floogen/model/routing.py @@ -18,6 +18,7 @@ sv_struct_typedef, bool_to_sv, snake_to_camel, + sv_struct_render ) @@ -167,6 +168,8 @@ def get_dir(node, neighbor) -> XYDirections: class AddrRange(BaseModel): """Address range class.""" + model_config = ConfigDict(extra="forbid") + start: int = Field(ge=0) end: int = Field(ge=0) size: int @@ -430,7 +433,7 @@ def pprint(self): class Routing(BaseModel): """Routing Description class.""" - model_config = ConfigDict(arbitrary_types_allowed=True) + model_config = ConfigDict(arbitrary_types_allowed=True, extra="forbid") route_algo: RouteAlgo use_id_table: bool = True @@ -505,27 +508,30 @@ def render_typedefs(self) -> str: string += sv_typedef("route_t", array_size=self.num_route_bits) case _: pass - match self.route_algo: - case RouteAlgo.SRC: - string += sv_typedef("dst_t", dtype="route_t") - case _: - string += sv_typedef("dst_t", dtype="id_t") if self.num_vc_id_bits > 0: string += sv_typedef("vc_id_t", array_size=self.num_vc_id_bits) return string - def render_flit_header(self) -> str: + def render_hdr_typedef(self) -> str: """Render the SystemVerilog flit header.""" - header_fields = { - "rob_req": "logic", - "rob_idx": "rob_idx_t", - "dst_id": "dst_t", - "src_id": "id_t", - "last": "logic", - "atop": "logic", - "axi_ch": "axi_ch_e", + + dst_type = "route_t" if self.route_algo == RouteAlgo.SRC else "id_t" + + if self.num_vc_id_bits == 0: + return f"`FLOO_TYPEDEF_HDR_T(hdr_t, {dst_type}, id_t, nw_ch_e, rob_idx_t)" + return f"`FLOO_TYPEDEF_HDR_T(hdr_t, {dst_type}, id_t, vc_id_t, nw_ch_e, rob_idx_t, vc_id_t)" + + def render_route_cfg(self, name) -> str: + """Render the SystemVerilog routing configuration.""" + fields = { + "RouteAlgo": self.route_algo.value, + "UseIdTable": bool_to_sv(self.use_id_table), + "XYAddrOffsetX": self.addr_offset_bits if self.route_algo == RouteAlgo.XY else 0, + "XYAddrOffsetY": self.addr_offset_bits + self.num_x_bits if + self.route_algo == RouteAlgo.XY else 0, + "IdAddrOffset": self.addr_offset_bits if + self.route_algo == RouteAlgo.ID and not self.use_id_table else 0, + "NumSamRules": len(self.sam), + "NumRoutes": self.num_endpoints if self.route_algo == RouteAlgo.SRC else 0, } - if self.num_vc_id_bits > 0: - header_fields["vc_id"] = "vc_id_t" - header_fields["lookahead"] = "route_direction_e" - return sv_struct_typedef("hdr_t", header_fields) + return sv_param_decl(name, sv_struct_render(fields), dtype="route_cfg_t") diff --git a/floogen/templates/floo_narrow_wide_chimney.sv.mako b/floogen/templates/floo_nw_chimney.sv.mako similarity index 56% rename from floogen/templates/floo_narrow_wide_chimney.sv.mako rename to floogen/templates/floo_nw_chimney.sv.mako index b76659ef..8482007c 100644 --- a/floogen/templates/floo_narrow_wide_chimney.sv.mako +++ b/floogen/templates/floo_nw_chimney.sv.mako @@ -1,35 +1,36 @@ -<%! from floogen.utils import snake_to_camel %>\ +<%! from floogen.utils import snake_to_camel, bool_to_sv %>\ <% actual_xy_id = ni.id - ni.routing.id_offset if ni.routing.id_offset is not None else ni.id %>\ +<% narrow_in_prot = next((prot for prot in noc.protocols if prot.type == "narrow" and prot.direction == "input"), None) %>\ +<% narrow_out_prot = next((prot for prot in noc.protocols if prot.type == "narrow" and prot.direction == "output"), None) %>\ +<% wide_in_prot = next((prot for prot in noc.protocols if prot.type == "wide" and prot.direction == "input"), None) %>\ +<% wide_out_prot = next((prot for prot in noc.protocols if prot.type == "wide" and prot.direction == "output"), None) %>\ -floo_narrow_wide_chimney #( +floo_nw_chimney #( + .AxiCfgN(AxiCfgN), + .AxiCfgW(AxiCfgW), + .ChimneyCfgN(set_ports(ChimneyDefaultCfg, ${bool_to_sv(ni.sbr_narrow_port != None)}, ${bool_to_sv(ni.mgr_narrow_port != None)})), + .ChimneyCfgW(set_ports(ChimneyDefaultCfg, ${bool_to_sv(ni.sbr_wide_port != None)}, ${bool_to_sv(ni.mgr_wide_port != None)})), + .RouteCfg(RouteCfg), + .id_t(id_t), + .rob_idx_t(rob_idx_t), % if ni.routing.route_algo.value == 'SourceRouting': - .NumRoutes(${len(ni.table)}), + .route_t (route_t), + .dst_t (route_t), % endif -% if ni.routing.use_id_table: - .SamNumRules(${len(ni.routing.sam)}), + .hdr_t (hdr_t), .sam_rule_t(sam_rule_t), .Sam(Sam), -% endif -% if ni.sbr_narrow_port is None: - .EnNarrowSbrPort(1'b0), -% else: - .EnNarrowSbrPort(1'b1), -% endif -% if ni.mgr_narrow_port is None: - .EnNarrowMgrPort(1'b0), -% else: - .EnNarrowMgrPort(1'b1), -% endif -% if ni.sbr_wide_port is None: - .EnWideSbrPort(1'b0), -% else: - .EnWideSbrPort(1'b1), -% endif -% if ni.mgr_wide_port is None: - .EnWideMgrPort(1'b0) -% else: - .EnWideMgrPort(1'b1) -% endif + .axi_narrow_in_req_t(${narrow_in_prot.type_name()}_req_t), + .axi_narrow_in_rsp_t(${narrow_in_prot.type_name()}_rsp_t), + .axi_narrow_out_req_t(${narrow_out_prot.type_name()}_req_t), + .axi_narrow_out_rsp_t(${narrow_out_prot.type_name()}_rsp_t), + .axi_wide_in_req_t(${wide_in_prot.type_name()}_req_t), + .axi_wide_in_rsp_t(${wide_in_prot.type_name()}_rsp_t), + .axi_wide_out_req_t(${wide_out_prot.type_name()}_req_t), + .axi_wide_out_rsp_t(${wide_out_prot.type_name()}_rsp_t), + .floo_req_t(floo_req_t), + .floo_rsp_t(floo_rsp_t), + .floo_wide_t(floo_wide_t) ) ${ni.name} ( .clk_i, .rst_ni, diff --git a/floogen/templates/floo_narrow_wide_router.sv.mako b/floogen/templates/floo_nw_router.sv.mako similarity index 91% rename from floogen/templates/floo_narrow_wide_router.sv.mako rename to floogen/templates/floo_nw_router.sv.mako index e369f297..a274aca8 100644 --- a/floogen/templates/floo_narrow_wide_router.sv.mako +++ b/floogen/templates/floo_nw_router.sv.mako @@ -60,18 +60,24 @@ ${wide_type} [${len(router.outgoing)-1}:0] ${router.name}_wide_out; % endif % endfor -floo_narrow_wide_router #( +floo_nw_router #( + .AxiCfgN(AxiCfgN), + .AxiCfgW(AxiCfgW), + .RouteAlgo (${router.route_algo.value}), .NumRoutes (${router.degree}), .NumInputs (${len(router.incoming)}), .NumOutputs (${len(router.outgoing)}), - .ChannelFifoDepth (2), - .OutputFifoDepth (2), + .InFifoDepth (2), + .OutFifoDepth (2), .id_t(id_t), + .hdr_t(hdr_t), % if router.route_algo == RouteAlgo.ID: .NumAddrRules (${len(router.table.rules)}), .addr_rule_t (${router.name}_map_rule_t), % endif - .RouteAlgo (${router.route_algo.value}) + .floo_req_t(floo_req_t), + .floo_rsp_t(floo_rsp_t), + .floo_wide_t(floo_wide_t) ) ${router.name} ( .clk_i, .rst_ni, diff --git a/floogen/templates/floo_noc_top.sv.mako b/floogen/templates/floo_top_noc.sv.mako similarity index 66% rename from floogen/templates/floo_noc_top.sv.mako rename to floogen/templates/floo_top_noc.sv.mako index 703c9f2f..053e06f5 100644 --- a/floogen/templates/floo_noc_top.sv.mako +++ b/floogen/templates/floo_top_noc.sv.mako @@ -7,9 +7,12 @@ // AUTOMATICALLY GENERATED! DO NOT EDIT! -package ${noc.name}_floo_noc_pkg; +`include "axi/typedef.svh" +`include "floo_noc/typedef.svh" - import floo_narrow_wide_pkg::*; +package floo_${noc.name}_noc_pkg; + + import floo_pkg::*; ///////////////////// // Address Map // @@ -19,10 +22,12 @@ package ${noc.name}_floo_noc_pkg; ${noc.render_ep_enum()} % endif + ${noc.routing.render_typedefs()} + % if noc.routing.use_id_table: ${noc.routing.sam.render(aw=noc.routing.addr_width)} % else: - localparam int unsigned SamNumRules = 1; + localparam int unsigned NumSamRules = 1; typedef logic sam_rule_t; localparam sam_rule_t Sam = '0; % endif @@ -31,12 +36,20 @@ package ${noc.name}_floo_noc_pkg; ${noc.render_ni_tables()} % endif + ${noc.routing.render_route_cfg(name="RouteCfg")} + +% for prot in noc.protocols: + ${prot.render_typedefs()} +% endfor + + ${noc.routing.render_hdr_typedef()} + ${noc.render_link_typedefs()} + endpackage -module ${noc.name}_floo_noc +module floo_${noc.name}_noc import floo_pkg::*; - import floo_narrow_wide_pkg::*; - import ${noc.name}_floo_noc_pkg::*; + import floo_${noc.name}_noc_pkg::*; ( input logic clk_i, input logic rst_ni, diff --git a/floogen/utils.py b/floogen/utils.py index 3611a550..a17cda59 100644 --- a/floogen/utils.py +++ b/floogen/utils.py @@ -89,6 +89,13 @@ def sv_struct_typedef(name: str, fields: dict, union=False) -> str: typedef += f"}} {name};\n\n" return typedef +def sv_struct_render(fields: dict) -> str: + """Declare a SystemVerilog struct.""" + decl = "'{" + for field, value in fields.items(): + decl += f" {field}: {value},\n" + return decl[:-2] + "}" + def sv_enum_typedef(name: str, fields_dict: dict=None, fields_list: list=None) -> str: """Declare a SystemVerilog enum typedef.""" if fields_dict is not None: diff --git a/hw/floo_axi_chimney.sv b/hw/floo_axi_chimney.sv index bc22e016..0aa937f8 100644 --- a/hw/floo_axi_chimney.sv +++ b/hw/floo_axi_chimney.sv @@ -6,20 +6,17 @@ `include "common_cells/registers.svh" `include "common_cells/assertions.svh" +`include "axi/typedef.svh" +`include "floo_noc/typedef.svh" /// A bidirectional network interface for connecting AXI4 Buses to the NoC -module floo_axi_chimney - import floo_pkg::*; - import floo_axi_pkg::*; -#( - /// FlooNoC defines subordinate ports as requests that go out - /// of the NoC to AXI subordinates (i.e. memories) that return - /// a response, and manager ports as requests that come into the - /// NoC from AXI managers (i.e. cores) - /// Enable the subordinate port of the AXI4 interface - parameter bit EnSbrPort = 1'b1, - /// Enable the manager port of the AXI4 interface - parameter bit EnMgrPort = 1'b1, +module floo_axi_chimney #( + /// Config of the AXI interfaces (see floo_pkg::axi_cfg_t for details) + parameter floo_pkg::axi_cfg_t AxiCfg = '0, + /// Config of the data path in the chimney (see floo_pkg::chimney_cfg_t for details) + parameter floo_pkg::chimney_cfg_t ChimneyCfg = floo_pkg::ChimneyDefaultCfg, + /// Config for routing information (see floo_pkg::route_cfg_t for details) + parameter floo_pkg::route_cfg_t RouteCfg = floo_pkg::RouteDefaultCfg, /// Atomic operation support parameter bit AtopSupport = 1'b1, /// Maximum number of oustanding Atomic transactions, @@ -27,35 +24,46 @@ module floo_axi_chimney /// Every atomic transactions needs to have a unique ID /// and one ID is reserved for non-atomic transactions parameter int unsigned MaxAtomicTxns = 1, - /// ID address offset for ID routing - parameter int unsigned MaxTxns = 32, - /// The number of unique IDs that can be used to send out - /// requests - parameter int unsigned MaxUniqueIds = 1, - /// Maximum number of outstanding requests per ID - parameter int unsigned MaxTxnsPerId = MaxTxns, - /// Type of the narrow reorder buffer - parameter rob_type_e RoBType = NoRoB, - /// Capacity of the reorder buffer - parameter int unsigned ReorderBufferSize = 32, - /// Cut timing paths of outgoing requests - parameter bit CutAx = 1'b0, - /// Cut timing paths of incoming responses - parameter bit CutRsp = 1'b1, - /// Type for implementation inputs and outputs - parameter type sram_cfg_t = logic, - /// Number of System Address Map Rules - parameter int unsigned SamNumRules = 0, - /// Type of System Address Map Rule - parameter type sam_rule_t = logic, - /// System Address Map - parameter sam_rule_t [SamNumRules-1:0] Sam = '0, - /// Number of rules in the address map - parameter int unsigned NumRoutes = 0 + /// Node ID type for routing + parameter type id_t = logic, + /// RoB index type for reordering. + // (can be ignored if `RoBType == NoRoB`) + parameter type rob_idx_t = logic, + /// Route type for source-based routing + /// (only used if `RouteCfg.RouteAlgo == SourceRouting`) + parameter type route_t = logic, + /// Destination ID type for routing + /// The destination ID type is usually the same as the node ID type, + /// except for the case of source-based routing, where the destination + /// ID is the actual route to the destination i.e. `route_t` + parameter type dst_t = id_t, + /// Header type for the flits + parameter type hdr_t = logic, + /// Rule type for the System Address Map + /// (only used if `RouteCfg.UseIdTable == 1'b1`) + parameter type sam_rule_t = logic, + /// The System Address Map (SAM) rules + /// (only used if `RouteCfg.UseIdTable == 1'b1`) + parameter sam_rule_t [RouteCfg.NumSamRules-1:0] Sam = '0, + /// AXI manager request channel type + parameter type axi_in_req_t = logic, + /// AXI manager response channel type + parameter type axi_in_rsp_t = logic, + /// AXI subordinate request channel type + parameter type axi_out_req_t = logic, + // AXI subordinate response channel type + parameter type axi_out_rsp_t = logic, + /// Floo `req` link type + parameter type floo_req_t = logic, + /// Floo `rsp` link type + parameter type floo_rsp_t = logic, + /// SRAM configuration type + parameter type sram_cfg_t = logic ) ( input logic clk_i, input logic rst_ni, input logic test_enable_i, + /// SRAM configuration input sram_cfg_t sram_cfg_i, /// AXI4 side interfaces input axi_in_req_t axi_in_req_i, @@ -65,23 +73,36 @@ module floo_axi_chimney /// Coordinates/ID of the current tile input id_t id_i, /// Routing table for the current tile - input route_t [NumRoutes-1:0] route_table_i, - /// Output to NoC + input route_t [RouteCfg.NumRoutes-1:0] route_table_i, + /// Output links to NoC output floo_req_t floo_req_o, output floo_rsp_t floo_rsp_o, - /// Input from NoC + /// Input links from NoC input floo_req_t floo_req_i, input floo_rsp_t floo_rsp_i ); + import floo_pkg::*; + + typedef logic [AxiCfg.AddrWidth-1:0] axi_addr_t; + typedef logic [AxiCfg.InIdWidth-1:0] axi_in_id_t; + typedef logic [AxiCfg.UserWidth-1:0] axi_user_t; + typedef logic [AxiCfg.DataWidth-1:0] axi_data_t; + typedef logic [AxiCfg.DataWidth/8-1:0] axi_strb_t; + + // (Re-) definitons of `axi_in` and `floo` types, for transport + `AXI_TYPEDEF_ALL_CT(axi, axi_req_t, axi_rsp_t, axi_addr_t, axi_in_id_t, + axi_data_t, axi_strb_t, axi_user_t) + `FLOO_TYPEDEF_AXI_CHAN_ALL(axi, req, rsp, axi, AxiCfg, hdr_t) + // Duplicate AXI port signals to degenerate ports // in case they are not used - axi_in_req_t axi_req_in; - axi_in_rsp_t axi_rsp_out; + axi_req_t axi_req_in; + axi_rsp_t axi_rsp_out; // AX queue - axi_in_aw_chan_t axi_aw_queue; - axi_in_ar_chan_t axi_ar_queue; + axi_aw_chan_t axi_aw_queue; + axi_ar_chan_t axi_ar_queue; logic axi_aw_queue_valid_out, axi_aw_queue_ready_in; logic axi_ar_queue_valid_out, axi_ar_queue_ready_in; @@ -106,17 +127,17 @@ module floo_axi_chimney floo_axi_r_flit_t floo_axi_r; // Flit unpacking - axi_in_aw_chan_t axi_unpack_aw; - axi_in_ar_chan_t axi_unpack_ar; - axi_in_w_chan_t axi_unpack_w; - axi_in_b_chan_t axi_unpack_b; - axi_in_r_chan_t axi_unpack_r; + axi_aw_chan_t axi_unpack_aw; + axi_ar_chan_t axi_unpack_ar; + axi_w_chan_t axi_unpack_w; + axi_b_chan_t axi_unpack_b; + axi_r_chan_t axi_unpack_r; floo_req_generic_flit_t unpack_req_generic; floo_rsp_generic_flit_t unpack_rsp_generic; // Meta Buffer - axi_in_req_t axi_meta_buf_req_in; - axi_in_rsp_t axi_meta_buf_rsp_out; + axi_req_t meta_buf_req_in; + axi_rsp_t meta_buf_rsp_out; // Flit arbitration typedef enum logic {SelAw, SelW} aw_w_sel_e; @@ -124,12 +145,9 @@ module floo_axi_chimney // ID tracking typedef struct packed { - axi_in_id_t id; - logic rob_req; - rob_idx_t rob_idx; - id_t src_id; - logic atop; - } id_out_buf_t; + axi_in_id_t id; + hdr_t hdr; + } meta_buf_t; // Routing dst_t [NumAxiChannels-1:0] dst_id; @@ -137,21 +155,21 @@ module floo_axi_chimney route_t [NumAxiChannels-1:0] route_out; id_t [NumAxiChannels-1:0] id_out; - id_out_buf_t aw_out_data_in, aw_out_data_out; - id_out_buf_t ar_out_data_in, ar_out_data_out; + meta_buf_t aw_out_hdr_in, aw_out_hdr_out; + meta_buf_t ar_out_hdr_in, ar_out_hdr_out; /////////////////////// // Spill registers // /////////////////////// - if (EnMgrPort) begin : gen_sbr_port + if (ChimneyCfg.EnMgrPort) begin : gen_sbr_port assign axi_req_in = axi_in_req_i; assign axi_in_rsp_o = axi_rsp_out; - if (CutAx) begin : gen_ax_cuts + if (ChimneyCfg.CutAx) begin : gen_ax_cuts spill_register #( - .T ( axi_in_aw_chan_t ) + .T ( axi_aw_chan_t ) ) i_aw_queue ( .clk_i, .rst_ni, @@ -164,7 +182,7 @@ module floo_axi_chimney ); spill_register #( - .T ( axi_in_ar_chan_t ) + .T ( axi_ar_chan_t ) ) i_ar_queue ( .clk_i, .rst_ni, @@ -186,10 +204,10 @@ module floo_axi_chimney end end else begin : gen_err_slv_port axi_err_slv #( - .AxiIdWidth ( AxiInIdWidth ), - .ATOPs ( AtopSupport ), - .axi_req_t ( axi_in_req_t ), - .axi_resp_t ( axi_in_rsp_t ) + .AxiIdWidth ( AxiCfg.InIdWidth ), + .ATOPs ( AtopSupport ), + .axi_req_t ( axi_in_req_t ), + .axi_resp_t ( axi_in_rsp_t ) ) i_axi_err_slv ( .clk_i ( clk_i ), .rst_ni ( rst_ni ), @@ -204,7 +222,7 @@ module floo_axi_chimney assign axi_ar_queue_valid_out = 1'b0; end - if (CutRsp) begin : gen_rsp_cuts + if (ChimneyCfg.CutRsp) begin : gen_rsp_cuts spill_register #( .T ( floo_req_chan_t ) ) i_data_req_arb ( @@ -244,7 +262,7 @@ module floo_axi_chimney /////////////////////// // AW/B RoB - axi_in_b_chan_t axi_b_rob_out, axi_b_rob_in; + axi_b_chan_t axi_b_rob_out, axi_b_rob_in; logic aw_rob_req_out; rob_idx_t aw_rob_idx_out; logic aw_rob_valid_in, aw_rob_ready_out; @@ -253,7 +271,7 @@ module floo_axi_chimney logic b_rob_valid_out, b_rob_ready_in; // AR/R RoB - axi_in_r_chan_t axi_r_rob_out, axi_r_rob_in; + axi_r_chan_t axi_r_rob_out, axi_r_rob_in; logic ar_rob_req_out; rob_idx_t ar_rob_idx_out; logic ar_rob_valid_out, ar_rob_ready_in; @@ -272,17 +290,17 @@ module floo_axi_chimney end floo_rob_wrapper #( - .RoBType ( NoRoB ), - .ReorderBufferSize ( ReorderBufferSize ), - .MaxRoTxnsPerId ( MaxTxnsPerId ), - .OnlyMetaData ( 1'b1 ), - .ax_len_t ( axi_pkg::len_t ), - .ax_id_t ( axi_in_id_t ), - .rsp_chan_t ( axi_in_b_chan_t ), - .rsp_meta_t ( axi_in_b_chan_t ), - .rob_idx_t ( rob_idx_t ), - .dest_t ( id_t ), - .sram_cfg_t ( sram_cfg_t ) + .RoBType ( ChimneyCfg.BRoBType ), + .RoBSize ( ChimneyCfg.BRoBSize ), + .MaxRoTxnsPerId ( ChimneyCfg.MaxTxnsPerId ), + .OnlyMetaData ( 1'b1 ), + .ax_len_t ( axi_pkg::len_t ), + .ax_id_t ( axi_in_id_t ), + .rsp_chan_t ( axi_b_chan_t ), + .rsp_meta_t ( axi_b_chan_t ), + .rob_idx_t ( rob_idx_t ), + .dest_t ( id_t ), + .sram_cfg_t ( sram_cfg_t ) ) i_b_rob ( .clk_i, .rst_ni, @@ -307,50 +325,49 @@ module floo_axi_chimney .rsp_o ( axi_b_rob_out ) ); - typedef logic [AxiInDataWidth-1:0] r_rob_data_t; typedef struct packed { axi_in_id_t id; - axi_in_user_t user; + axi_user_t user; axi_pkg::resp_t resp; logic last; } r_rob_meta_t; floo_rob_wrapper #( - .RoBType ( NoRoB ), - .ReorderBufferSize ( ReorderBufferSize ), - .MaxRoTxnsPerId ( MaxTxnsPerId ), - .OnlyMetaData ( 1'b0 ), - .ax_len_t ( axi_pkg::len_t ), - .ax_id_t ( axi_in_id_t ), - .rsp_chan_t ( axi_in_r_chan_t ), - .rsp_data_t ( r_rob_data_t ), - .rsp_meta_t ( r_rob_meta_t ), - .rob_idx_t ( rob_idx_t ), - .dest_t ( id_t ), - .sram_cfg_t ( sram_cfg_t ) + .RoBType ( ChimneyCfg.RRoBType ), + .RoBSize ( ChimneyCfg.RRoBSize ), + .MaxRoTxnsPerId ( ChimneyCfg.MaxTxnsPerId ), + .OnlyMetaData ( 1'b0 ), + .ax_len_t ( axi_pkg::len_t ), + .ax_id_t ( axi_in_id_t ), + .rsp_chan_t ( axi_r_chan_t ), + .rsp_data_t ( axi_data_t ), + .rsp_meta_t ( r_rob_meta_t ), + .rob_idx_t ( rob_idx_t ), + .dest_t ( id_t ), + .sram_cfg_t ( sram_cfg_t ) ) i_r_rob ( .clk_i, .rst_ni, .sram_cfg_i, - .ax_valid_i ( axi_ar_queue_valid_out ), - .ax_ready_o ( axi_ar_queue_ready_in ), - .ax_len_i ( axi_ar_queue.len ), - .ax_id_i ( axi_ar_queue.id ), - .ax_dest_i ( id_out[AxiAr] ), - .ax_valid_o ( ar_rob_valid_out ), - .ax_ready_i ( ar_rob_ready_in ), - .ax_rob_req_o ( ar_rob_req_out ), - .ax_rob_idx_o ( ar_rob_idx_out ), - .rsp_valid_i ( r_rob_valid_in ), - .rsp_ready_o ( r_rob_ready_out ), - .rsp_i ( axi_r_rob_in ), - .rsp_rob_req_i ( floo_rsp_in.axi_r.hdr.rob_req ), - .rsp_rob_idx_i ( floo_rsp_in.axi_r.hdr.rob_idx ), - .rsp_last_i ( floo_rsp_in.axi_r.r.last ), - .rsp_valid_o ( r_rob_valid_out ), - .rsp_ready_i ( r_rob_ready_in ), - .rsp_o ( axi_r_rob_out ) + .ax_valid_i ( axi_ar_queue_valid_out ), + .ax_ready_o ( axi_ar_queue_ready_in ), + .ax_len_i ( axi_ar_queue.len ), + .ax_id_i ( axi_ar_queue.id ), + .ax_dest_i ( id_out[AxiAr] ), + .ax_valid_o ( ar_rob_valid_out ), + .ax_ready_i ( ar_rob_ready_in ), + .ax_rob_req_o ( ar_rob_req_out ), + .ax_rob_idx_o ( ar_rob_idx_out ), + .rsp_valid_i ( r_rob_valid_in ), + .rsp_ready_o ( r_rob_ready_out ), + .rsp_i ( axi_r_rob_in ), + .rsp_rob_req_i ( floo_rsp_in.axi_r.hdr.rob_req ), + .rsp_rob_idx_i ( floo_rsp_in.axi_r.hdr.rob_idx ), + .rsp_last_i ( floo_rsp_in.axi_r.payload.last ), + .rsp_valid_o ( r_rob_valid_out ), + .rsp_ready_i ( r_rob_ready_in ), + .rsp_o ( axi_r_rob_out ) ); ///////////////// @@ -358,17 +375,11 @@ module floo_axi_chimney ///////////////// floo_route_comp #( - .RouteAlgo ( RouteAlgo ), - .UseIdTable ( UseIdTable ), - .XYAddrOffsetX ( XYAddrOffsetX ), - .XYAddrOffsetY ( XYAddrOffsetY ), - .IdAddrOffset ( IdAddrOffset ), - .NumAddrRules ( SamNumRules ), - .NumRoutes ( NumRoutes ), - .id_t ( id_t ), - .addr_t ( axi_in_addr_t ), - .addr_rule_t ( sam_rule_t ), - .route_t ( route_t ) + .RouteCfg ( RouteCfg ), + .id_t ( id_t ), + .addr_t ( axi_addr_t ), + .addr_rule_t ( sam_rule_t ), + .route_t ( route_t ) ) i_floo_req_route_comp [1:0] ( .clk_i, .rst_ni, @@ -379,33 +390,31 @@ module floo_axi_chimney .route_o ( {route_out[AxiAw], route_out[AxiAr]} ), .id_o ( {id_out[AxiAw], id_out[AxiAr]} ) ); - if (RouteAlgo == SourceRouting) begin : gen_route_field + if (RouteCfg.RouteAlgo == SourceRouting) begin : gen_route_field floo_route_comp #( - .RouteAlgo ( RouteAlgo ), - .UseIdTable ( 1'b0 ), - .NumAddrRules ( SamNumRules ), - .NumRoutes ( NumRoutes ), - .id_t ( id_t ), - .addr_t ( axi_in_addr_t ), - .addr_rule_t ( sam_rule_t ), - .route_t ( route_t ) + .RouteCfg ( RouteCfg ), + .UseIdTable ( 1'b0 ), // Overwrite RouteCfg + .id_t ( id_t ), + .addr_t ( axi_addr_t ), + .addr_rule_t ( sam_rule_t ), + .route_t ( route_t ) ) i_floo_rsp_route_comp [1:0] ( .clk_i, .rst_ni, .route_table_i, - .addr_i ( '0 ), - .addr_map_i ( '0 ), - .id_i ({aw_out_data_out.src_id, ar_out_data_out.src_id} ), - .route_o ({route_out[AxiB], route_out[AxiR]} ), - .id_o ({id_out[AxiB], id_out[AxiR]} ) + .addr_i ( '0 ), + .addr_map_i ( '0 ), + .id_i ({aw_out_hdr_out.hdr.src_id, ar_out_hdr_out.hdr.src_id} ), + .route_o ({route_out[AxiB], route_out[AxiR]} ), + .id_o ({id_out[AxiB], id_out[AxiR]} ) ); assign route_out[AxiW] = axi_aw_id_q; assign dst_id = route_out; end else begin : gen_dst_field assign dst_id[AxiAw] = id_out[AxiAw]; assign dst_id[AxiAr] = id_out[AxiAr]; - assign dst_id[AxiB] = aw_out_data_out.src_id; - assign dst_id[AxiR] = ar_out_data_out.src_id; + assign dst_id[AxiB] = aw_out_hdr_out.hdr.src_id; + assign dst_id[AxiR] = ar_out_hdr_out.hdr.src_id; assign dst_id[AxiW] = axi_aw_id_q; end `FFL(axi_aw_id_q, dst_id[AxiAw], axi_aw_queue_valid_out && @@ -424,7 +433,7 @@ module floo_axi_chimney floo_axi_aw.hdr.last = 1'b0; floo_axi_aw.hdr.axi_ch = AxiAw; floo_axi_aw.hdr.atop = axi_aw_queue.atop != axi_pkg::ATOP_NONE; - floo_axi_aw.aw = axi_aw_queue; + floo_axi_aw.payload = axi_aw_queue; end always_comb begin @@ -435,7 +444,7 @@ module floo_axi_chimney floo_axi_w.hdr.src_id = id_i; floo_axi_w.hdr.last = axi_req_in.w.last; floo_axi_w.hdr.axi_ch = AxiW; - floo_axi_w.w = axi_req_in.w; + floo_axi_w.payload = axi_req_in.w; end always_comb begin @@ -446,33 +455,33 @@ module floo_axi_chimney floo_axi_ar.hdr.src_id = id_i; floo_axi_ar.hdr.last = 1'b1; floo_axi_ar.hdr.axi_ch = AxiAr; - floo_axi_ar.ar = axi_ar_queue; + floo_axi_ar.payload = axi_ar_queue; end always_comb begin floo_axi_b = '0; - floo_axi_b.hdr.rob_req = aw_out_data_out.rob_req; - floo_axi_b.hdr.rob_idx = aw_out_data_out.rob_idx; + floo_axi_b.hdr.rob_req = aw_out_hdr_out.hdr.rob_req; + floo_axi_b.hdr.rob_idx = aw_out_hdr_out.hdr.rob_idx; floo_axi_b.hdr.dst_id = dst_id[AxiB]; floo_axi_b.hdr.src_id = id_i; floo_axi_b.hdr.last = 1'b1; floo_axi_b.hdr.axi_ch = AxiB; - floo_axi_b.hdr.atop = aw_out_data_out.atop; - floo_axi_b.b = axi_meta_buf_rsp_out.b; - floo_axi_b.b.id = aw_out_data_out.id; + floo_axi_b.hdr.atop = aw_out_hdr_out.hdr.atop; + floo_axi_b.payload = meta_buf_rsp_out.b; + floo_axi_b.payload.id = aw_out_hdr_out.id; end always_comb begin floo_axi_r = '0; - floo_axi_r.hdr.rob_req = ar_out_data_out.rob_req; - floo_axi_r.hdr.rob_idx = ar_out_data_out.rob_idx; + floo_axi_r.hdr.rob_req = ar_out_hdr_out.hdr.rob_req; + floo_axi_r.hdr.rob_idx = ar_out_hdr_out.hdr.rob_idx; floo_axi_r.hdr.dst_id = dst_id[AxiR]; floo_axi_r.hdr.src_id = id_i; floo_axi_r.hdr.last = 1'b1; // There is no reason to do wormhole routing for R bursts floo_axi_r.hdr.axi_ch = AxiR; - floo_axi_r.hdr.atop = ar_out_data_out.atop; - floo_axi_r.r = axi_meta_buf_rsp_out.r; - floo_axi_r.r.id = ar_out_data_out.id; + floo_axi_r.hdr.atop = ar_out_hdr_out.hdr.atop; + floo_axi_r.payload = meta_buf_rsp_out.r; + floo_axi_r.payload.id = ar_out_hdr_out.id; end always_comb begin @@ -488,17 +497,17 @@ module floo_axi_chimney axi_aw_queue_valid_out)) || (aw_w_sel_q == SelW) && axi_req_in.w_valid; assign floo_req_arb_req_in[AxiAr] = ar_rob_valid_out; - assign floo_rsp_arb_req_in[AxiB] = axi_meta_buf_rsp_out.b_valid; - assign floo_rsp_arb_req_in[AxiR] = axi_meta_buf_rsp_out.r_valid; + assign floo_rsp_arb_req_in[AxiB] = meta_buf_rsp_out.b_valid; + assign floo_rsp_arb_req_in[AxiR] = meta_buf_rsp_out.r_valid; - assign aw_rob_ready_in = floo_req_arb_gnt_out[AxiW] && (aw_w_sel_q == SelAw); - assign axi_rsp_out.w_ready = floo_req_arb_gnt_out[AxiW] && (aw_w_sel_q == SelW); - assign ar_rob_ready_in = floo_req_arb_gnt_out[AxiAr]; + assign aw_rob_ready_in = floo_req_arb_gnt_out[AxiW] && (aw_w_sel_q == SelAw); + assign axi_rsp_out.w_ready = floo_req_arb_gnt_out[AxiW] && (aw_w_sel_q == SelW); + assign ar_rob_ready_in = floo_req_arb_gnt_out[AxiAr]; - assign floo_req_arb_in[AxiW] = (aw_w_sel_q == SelAw)? floo_axi_aw : floo_axi_w; - assign floo_req_arb_in[AxiAr] = floo_axi_ar; - assign floo_rsp_arb_in[AxiB] = floo_axi_b; - assign floo_rsp_arb_in[AxiR] = floo_axi_r; + assign floo_req_arb_in[AxiW] = (aw_w_sel_q == SelAw)? floo_axi_aw : floo_axi_w; + assign floo_req_arb_in[AxiAr] = floo_axi_ar; + assign floo_rsp_arb_in[AxiB] = floo_axi_b; + assign floo_rsp_arb_in[AxiR] = floo_axi_r; /////////////////////// // FLIT ARBITRATION // @@ -545,25 +554,25 @@ module floo_axi_chimney assign b_sel_atop = is_atop_b_rsp && !b_rob_pending_q; assign r_sel_atop = is_atop_r_rsp && !r_rob_pending_q; - assign axi_unpack_aw = floo_req_in.axi_aw.aw; - assign axi_unpack_w = floo_req_in.axi_w.w; - assign axi_unpack_ar = floo_req_in.axi_ar.ar; - assign axi_unpack_r = floo_rsp_in.axi_r.r; - assign axi_unpack_b = floo_rsp_in.axi_b.b; + assign axi_unpack_aw = floo_req_in.axi_aw.payload; + assign axi_unpack_w = floo_req_in.axi_w.payload; + assign axi_unpack_ar = floo_req_in.axi_ar.payload; + assign axi_unpack_r = floo_rsp_in.axi_r.payload; + assign axi_unpack_b = floo_rsp_in.axi_b.payload; assign unpack_req_generic = floo_req_in.generic; assign unpack_rsp_generic = floo_rsp_in.generic; assign axi_valid_in[AxiAw] = floo_req_in_valid && (unpack_req_generic.hdr.axi_ch == AxiAw); assign axi_valid_in[AxiW] = floo_req_in_valid && (unpack_req_generic.hdr.axi_ch == AxiW); assign axi_valid_in[AxiAr] = floo_req_in_valid && (unpack_req_generic.hdr.axi_ch == AxiAr); - assign axi_valid_in[AxiB] = EnMgrPort && floo_rsp_in_valid && + assign axi_valid_in[AxiB] = ChimneyCfg.EnMgrPort && floo_rsp_in_valid && (unpack_rsp_generic.hdr.axi_ch == AxiB); - assign axi_valid_in[AxiR] = EnMgrPort && floo_rsp_in_valid && + assign axi_valid_in[AxiR] = ChimneyCfg.EnMgrPort && floo_rsp_in_valid && (unpack_rsp_generic.hdr.axi_ch == AxiR); - assign axi_ready_out[AxiAw] = axi_meta_buf_rsp_out.aw_ready; - assign axi_ready_out[AxiW] = axi_meta_buf_rsp_out.w_ready; - assign axi_ready_out[AxiAr] = axi_meta_buf_rsp_out.ar_ready; + assign axi_ready_out[AxiAw] = meta_buf_rsp_out.aw_ready; + assign axi_ready_out[AxiW] = meta_buf_rsp_out.w_ready; + assign axi_ready_out[AxiAr] = meta_buf_rsp_out.ar_ready; assign axi_ready_out[AxiB] = b_rob_ready_out || b_sel_atop && axi_req_in.b_ready; assign axi_ready_out[AxiR] = r_rob_ready_out || r_sel_atop && axi_req_in.r_ready; @@ -574,7 +583,7 @@ module floo_axi_chimney // AXI req/rsp generation // //////////////////////////// - assign axi_meta_buf_req_in ='{ + assign meta_buf_req_in ='{ aw : axi_unpack_aw, aw_valid : axi_valid_in[AxiAw], w : axi_unpack_w, @@ -585,15 +594,15 @@ module floo_axi_chimney r_ready : floo_rsp_arb_gnt_out[AxiR] }; - assign b_rob_valid_in = axi_valid_in[AxiB] && !is_atop_b_rsp; - assign r_rob_valid_in = axi_valid_in[AxiR] && !is_atop_r_rsp; - assign axi_rsp_out.b_valid = b_rob_valid_out || is_atop_b_rsp; - assign axi_rsp_out.r_valid = r_rob_valid_out || is_atop_r_rsp; - assign b_rob_ready_in = axi_req_in.b_ready && !b_sel_atop; - assign r_rob_ready_in = axi_req_in.r_ready && !r_sel_atop; + assign b_rob_valid_in = axi_valid_in[AxiB] && !is_atop_b_rsp; + assign r_rob_valid_in = axi_valid_in[AxiR] && !is_atop_r_rsp; + assign axi_rsp_out.b_valid = b_rob_valid_out || is_atop_b_rsp; + assign axi_rsp_out.r_valid = r_rob_valid_out || is_atop_r_rsp; + assign b_rob_ready_in = axi_req_in.b_ready && !b_sel_atop; + assign r_rob_ready_in = axi_req_in.r_ready && !r_sel_atop; - assign axi_b_rob_in = axi_unpack_b; - assign axi_r_rob_in = axi_unpack_r; + assign axi_b_rob_in = axi_unpack_b; + assign axi_r_rob_in = axi_unpack_r; assign axi_rsp_out.b = (b_sel_atop)? axi_unpack_b : axi_b_rob_out; assign axi_rsp_out.r = (r_sel_atop)? axi_unpack_r : axi_r_rob_out; @@ -603,62 +612,58 @@ module floo_axi_chimney assign atop_has_r_rsp = AtopSupport && axi_valid_in[AxiAw] && axi_unpack_aw.atop[axi_pkg::ATOP_R_RESP]; - assign aw_out_data_in = '{ + assign aw_out_hdr_in = '{ id: axi_unpack_aw.id, - rob_req: unpack_req_generic.hdr.rob_req, - rob_idx: unpack_req_generic.hdr.rob_idx, - src_id: unpack_req_generic.hdr.src_id, - atop: unpack_req_generic.hdr.atop + hdr: unpack_req_generic.hdr }; - assign ar_out_data_in = '{ + assign ar_out_hdr_in = '{ id: (is_atop && atop_has_r_rsp)? axi_unpack_aw.id : axi_unpack_ar.id, - rob_req: unpack_req_generic.hdr.rob_req, - rob_idx: unpack_req_generic.hdr.rob_idx, - src_id: unpack_req_generic.hdr.src_id, - atop: unpack_req_generic.hdr.atop + hdr: unpack_req_generic.hdr }; - if (EnSbrPort) begin : gen_mgr_port + if (ChimneyCfg.EnSbrPort) begin : gen_mgr_port floo_meta_buffer #( - .MaxTxns ( MaxTxns ), - .MaxUniqueIds ( MaxUniqueIds ), - .AtopSupport ( AtopSupport ), - .MaxAtomicTxns ( MaxAtomicTxns ), - .buf_t ( id_out_buf_t ), - .axi_in_req_t ( axi_in_req_t ), - .axi_in_rsp_t ( axi_in_rsp_t ), - .axi_out_req_t ( axi_out_req_t ), - .axi_out_rsp_t ( axi_out_rsp_t ) + .InIdWidth ( AxiCfg.InIdWidth ), + .OutIdWidth ( AxiCfg.OutIdWidth ), + .MaxTxns ( ChimneyCfg.MaxTxns ), + .MaxUniqueIds ( ChimneyCfg.MaxUniqueIds ), + .AtopSupport ( AtopSupport ), + .MaxAtomicTxns ( MaxAtomicTxns ), + .buf_t ( meta_buf_t ), + .axi_in_req_t ( axi_in_req_t ), + .axi_in_rsp_t ( axi_in_rsp_t ), + .axi_out_req_t ( axi_out_req_t ), + .axi_out_rsp_t ( axi_out_rsp_t ) ) i_floo_meta_buffer ( .clk_i, .rst_ni, .test_enable_i, - .axi_req_i ( axi_meta_buf_req_in ), - .axi_rsp_o ( axi_meta_buf_rsp_out ), - .axi_req_o ( axi_out_req_o ), - .axi_rsp_i ( axi_out_rsp_i ), - .aw_buf_i ( aw_out_data_in ), - .ar_buf_i ( ar_out_data_in ), - .r_buf_o ( ar_out_data_out ), - .b_buf_o ( aw_out_data_out ) + .axi_req_i ( meta_buf_req_in ), + .axi_rsp_o ( meta_buf_rsp_out ), + .axi_req_o ( axi_out_req_o ), + .axi_rsp_i ( axi_out_rsp_i ), + .aw_buf_i ( aw_out_hdr_in ), + .ar_buf_i ( ar_out_hdr_in ), + .r_buf_o ( ar_out_hdr_out ), + .b_buf_o ( aw_out_hdr_out ) ); end else begin : gen_no_mgr_port axi_err_slv #( - .AxiIdWidth ( AxiInIdWidth ), - .ATOPs ( AtopSupport ), - .axi_req_t ( axi_in_req_t ), - .axi_resp_t ( axi_in_rsp_t ) + .AxiIdWidth ( AxiCfg.InIdWidth ), + .ATOPs ( AtopSupport ), + .axi_req_t ( axi_in_req_t ), + .axi_resp_t ( axi_in_rsp_t ) ) i_axi_err_slv ( - .clk_i ( clk_i ), - .rst_ni ( rst_ni ), - .test_i ( test_enable_i ), - .slv_req_i ( axi_meta_buf_req_in ), - .slv_resp_o ( axi_meta_buf_rsp_out ) + .clk_i ( clk_i ), + .rst_ni ( rst_ni ), + .test_i ( test_enable_i ), + .slv_req_i ( meta_buf_req_in ), + .slv_resp_o ( meta_buf_rsp_out ) ); assign axi_out_req_o = '0; - assign ar_out_data_out = '0; - assign aw_out_data_out = '0; + assign ar_out_hdr_out = '0; + assign aw_out_hdr_out = '0; end // Registers @@ -667,22 +672,23 @@ module floo_axi_chimney // Multiple outstanding atomics need to use different IDs // Non-atomic transactions all use the same ID - `ASSERT_INIT(ToSmallIdWidth, 1 + AtopSupport * MaxAtomicTxns <= 2**AxiOutIdWidth) + `ASSERT_INIT(ToSmallIdWidth, 1 + AtopSupport * MaxAtomicTxns <= 2**AxiCfg.OutIdWidth) // If Network Interface has no subordinate port, make sure that `RoBType` is `NoRoB` - `ASSERT_INIT(NoMgrPortRobType, EnMgrPort || (RoBType == NoRoB)) + `ASSERT_INIT(NoMgrPortRobType, ChimneyCfg.EnMgrPort || (ChimneyCfg.BRoBType == NoRoB && + ChimneyCfg.RRoBType == NoRoB)) // Network Interface cannot accept any B and R responses if `EnMgrPort` is not set - `ASSERT(NoMgrPortBResponse, EnMgrPort || !(floo_rsp_in_valid && + `ASSERT(NoMgrPortBResponse, ChimneyCfg.EnMgrPort || !(floo_rsp_in_valid && (unpack_rsp_generic.hdr.axi_ch == AxiB))) - `ASSERT(NoMgrPortRResponse, EnMgrPort || !(floo_rsp_in_valid && + `ASSERT(NoMgrPortRResponse, ChimneyCfg.EnMgrPort || !(floo_rsp_in_valid && (unpack_rsp_generic.hdr.axi_ch == AxiR))) // Network Interface cannot accept any AW, AR and W requests if `EnSbrPort` is not set - `ASSERT(NoSbrPortAwRequest, EnSbrPort || !(floo_req_in_valid && + `ASSERT(NoSbrPortAwRequest, ChimneyCfg.EnSbrPort || !(floo_req_in_valid && (unpack_req_generic.hdr.axi_ch == AxiAw))) - `ASSERT(NoSbrPortArRequest, EnSbrPort || !(floo_req_in_valid && + `ASSERT(NoSbrPortArRequest, ChimneyCfg.EnSbrPort || !(floo_req_in_valid && (unpack_req_generic.hdr.axi_ch == AxiAr))) - `ASSERT(NoSbrPortWRequest, EnSbrPort || !(floo_req_in_valid && + `ASSERT(NoSbrPortWRequest, ChimneyCfg.EnSbrPort || !(floo_req_in_valid && (unpack_req_generic.hdr.axi_ch == AxiW))) endmodule diff --git a/hw/floo_axi_pkg.sv b/hw/floo_axi_pkg.sv deleted file mode 100644 index 76bc6f18..00000000 --- a/hw/floo_axi_pkg.sv +++ /dev/null @@ -1,179 +0,0 @@ -// Copyright 2022 ETH Zurich and University of Bologna. -// Solderpad Hardware License, Version 0.51, see LICENSE for details. -// SPDX-License-Identifier: SHL-0.51 -// -// This file is auto-generated. Do not edit! Edit the template file instead - -`include "axi/typedef.svh" - -package floo_axi_pkg; - - import floo_pkg::*; - - //////////////////////// - // AXI Parameters // - //////////////////////// - - typedef enum logic [2:0] { - AxiAw = 3'd0, - AxiW = 3'd1, - AxiAr = 3'd2, - AxiB = 3'd3, - AxiR = 3'd4, - NumAxiChannels = 3'd5 - } axi_ch_e; - - - localparam int unsigned AxiInAddrWidth = 32; - localparam int unsigned AxiInDataWidth = 64; - localparam int unsigned AxiInIdWidth = 3; - localparam int unsigned AxiInUserWidth = 1; - - - localparam int unsigned AxiOutAddrWidth = 32; - localparam int unsigned AxiOutDataWidth = 64; - localparam int unsigned AxiOutIdWidth = 3; - localparam int unsigned AxiOutUserWidth = 1; - - - typedef logic [31:0] axi_in_addr_t; - typedef logic [63:0] axi_in_data_t; - typedef logic [7:0] axi_in_strb_t; - typedef logic [2:0] axi_in_id_t; - typedef logic [0:0] axi_in_user_t; - `AXI_TYPEDEF_ALL_CT(axi_in, axi_in_req_t, axi_in_rsp_t, axi_in_addr_t, axi_in_id_t, axi_in_data_t, - axi_in_strb_t, axi_in_user_t) - - - typedef logic [31:0] axi_out_addr_t; - typedef logic [63:0] axi_out_data_t; - typedef logic [7:0] axi_out_strb_t; - typedef logic [2:0] axi_out_id_t; - typedef logic [0:0] axi_out_user_t; - `AXI_TYPEDEF_ALL_CT(axi_out, axi_out_req_t, axi_out_rsp_t, axi_out_addr_t, axi_out_id_t, - axi_out_data_t, axi_out_strb_t, axi_out_user_t) - - - - ///////////////////////// - // Header Typedefs // - ///////////////////////// - - localparam route_algo_e RouteAlgo = XYRouting; - localparam bit UseIdTable = 1'b0; - localparam int unsigned NumXBits = 3; - localparam int unsigned NumYBits = 3; - localparam int unsigned XYAddrOffsetX = 16; - localparam int unsigned XYAddrOffsetY = 19; - localparam int unsigned IdAddrOffset = 0; - - - typedef logic [0:0] rob_idx_t; - typedef logic [0:0] port_id_t; - typedef logic [2:0] x_bits_t; - typedef logic [2:0] y_bits_t; - typedef struct packed { - x_bits_t x; - y_bits_t y; - port_id_t port_id; - } id_t; - - typedef logic route_t; - typedef id_t dst_t; - - - typedef struct packed { - logic rob_req; - rob_idx_t rob_idx; - dst_t dst_id; - id_t src_id; - logic last; - logic atop; - axi_ch_e axi_ch; - } hdr_t; - - - - //////////////////////// - // Flits Typedefs // - //////////////////////// - - typedef struct packed { - hdr_t hdr; - axi_in_aw_chan_t aw; - logic [2:0] rsvd; - } floo_axi_aw_flit_t; - - typedef struct packed { - hdr_t hdr; - axi_in_w_chan_t w; - } floo_axi_w_flit_t; - - typedef struct packed { - hdr_t hdr; - axi_in_b_chan_t b; - logic [64:0] rsvd; - } floo_axi_b_flit_t; - - typedef struct packed { - hdr_t hdr; - axi_in_ar_chan_t ar; - logic [8:0] rsvd; - } floo_axi_ar_flit_t; - - typedef struct packed { - hdr_t hdr; - axi_in_r_chan_t r; - } floo_axi_r_flit_t; - - typedef logic [73:0] floo_req_payload_t; - typedef struct packed { - hdr_t hdr; - floo_req_payload_t payload; - } floo_req_generic_flit_t; - - typedef logic [70:0] floo_rsp_payload_t; - typedef struct packed { - hdr_t hdr; - floo_rsp_payload_t payload; - } floo_rsp_generic_flit_t; - - - - ////////////////////////// - // Channel Typedefs // - ////////////////////////// - - typedef union packed { - floo_axi_aw_flit_t axi_aw; - floo_axi_w_flit_t axi_w; - floo_axi_ar_flit_t axi_ar; - floo_req_generic_flit_t generic; - } floo_req_chan_t; - - typedef union packed { - floo_axi_b_flit_t axi_b; - floo_axi_r_flit_t axi_r; - floo_rsp_generic_flit_t generic; - } floo_rsp_chan_t; - - - - /////////////////////// - // Link Typedefs // - /////////////////////// - - typedef struct packed { - logic valid; - logic ready; - floo_req_chan_t req; - } floo_req_t; - - typedef struct packed { - logic valid; - logic ready; - floo_rsp_chan_t rsp; - } floo_rsp_t; - - -endpackage diff --git a/hw/floo_mesh.sv b/hw/floo_mesh.sv deleted file mode 100644 index fe6412c7..00000000 --- a/hw/floo_mesh.sv +++ /dev/null @@ -1,131 +0,0 @@ -// Copyright 2022 ETH Zurich and University of Bologna. -// Solderpad Hardware License, Version 0.51, see LICENSE for details. -// SPDX-License-Identifier: SHL-0.51 -// -// Michael Rogenmoser -// Tim Fischer - -`include "floo_noc/typedef.svh" - -/// A mesh topology with configurable number of rows and columns -module floo_mesh -import floo_pkg::*; -#( - parameter int unsigned NumX = 4, - parameter int unsigned NumY = 4, - parameter int unsigned NumVirtChannels = 1, - parameter int unsigned NumPhysChannels = 1, - parameter route_algo_e RouteAlgo = IdTable, - parameter type flit_t = logic, - parameter type xy_id_t = logic -) ( - input logic clk_i, - input logic rst_ni, - input logic [NumX-1:0][NumY-1:0][NumVirtChannels-1:0] valid_i, - output logic [NumX-1:0][NumY-1:0][NumVirtChannels-1:0] ready_o, - input flit_t [NumX-1:0][NumY-1:0][NumPhysChannels-1:0] data_i, - - output logic [NumX-1:0][NumY-1:0][NumVirtChannels-1:0] valid_o, - input logic [NumX-1:0][NumY-1:0][NumVirtChannels-1:0] ready_i, - output flit_t [NumX-1:0][NumY-1:0][NumPhysChannels-1:0] data_o -); - - flit_t [NumX-2:0][NumY-1:0][NumPhysChannels-1:0] pos_x_flit; - logic [NumX-2:0][NumY-1:0][NumVirtChannels-1:0] pos_x_ready, pos_x_valid; - flit_t [NumX-2:0][NumY-1:0][NumPhysChannels-1:0] neg_x_flit; - logic [NumX-2:0][NumY-1:0][NumVirtChannels-1:0] neg_x_ready, neg_x_valid; - flit_t [NumX-1:0][NumY-2:0][NumPhysChannels-1:0] pos_y_flit; - logic [NumX-1:0][NumY-2:0][NumVirtChannels-1:0] pos_y_ready, pos_y_valid; - flit_t [NumX-1:0][NumY-2:0][NumPhysChannels-1:0] neg_y_flit; - logic [NumX-1:0][NumY-2:0][NumVirtChannels-1:0] neg_y_ready, neg_y_valid; - - for (genvar x = 0; x < NumX; x++) begin : gen_x - for (genvar y = 0; y < NumY; y++) begin : gen_y - xy_id_t current_id; - assign current_id = '{x: x, y: y}; - - flit_t [NumDirections-1:0][NumPhysChannels-1:0] in_flit; - logic [NumDirections-1:0][NumVirtChannels-1:0] in_ready, in_valid; - flit_t [NumDirections-1:0][NumPhysChannels-1:0] out_flit; - logic [NumDirections-1:0][NumVirtChannels-1:0] out_ready, out_valid; - - always_comb begin - in_flit[West:North] = '0; - in_valid[West:North] = '0; - out_ready[West:North] = '0; - - in_valid[Eject] = valid_i[x][y]; - in_flit[Eject] = data_i[x][y]; - ready_o[x][y] = in_ready[Eject]; - valid_o[x][y] = out_valid[Eject]; - data_o[x][y] = out_flit[Eject]; - out_ready[Eject] = ready_i[x][y]; - - // Y - if (y < NumY-1) begin - in_flit[North] = neg_y_flit[x][y]; - in_valid[North] = neg_y_valid[x][y]; - neg_y_ready[x][y] = in_ready[North]; - pos_y_flit[x][y] = out_flit[North]; - pos_y_valid[x][y] = out_valid[North]; - out_ready[North] = pos_y_ready[x][y]; - end - if (y > 0) begin - in_flit[South] = pos_y_flit[x][y-1]; - in_valid[South] = pos_y_valid[x][y-1]; - pos_y_ready[x][y-1] = in_ready[South]; - neg_y_flit[x][y-1] = out_flit[South]; - neg_y_valid[x][y-1] = out_valid[South]; - out_ready[South] = neg_y_ready[x][y-1]; - end - - // X - if (x < NumX-1) begin - in_flit[East] = neg_x_flit[x][y]; - in_valid[East] = neg_x_valid[x][y]; - neg_x_ready[x][y] = in_ready[East]; - pos_x_flit[x][y] = out_flit[East]; - pos_x_valid[x][y] = out_valid[East]; - out_ready[East] = pos_x_ready[x][y]; - end - if (x > 0) begin - in_flit[West] = pos_x_flit[x-1][y]; - in_valid[West] = pos_x_valid[x-1][y]; - pos_x_ready[x-1][y] = in_ready[West]; - neg_x_flit[x-1][y] = out_flit[West]; - neg_x_valid[x-1][y] = out_valid[West]; - out_ready[West] = neg_x_ready[x-1][y]; - end - end - - floo_router #( - .NumPhysChannels ( NumPhysChannels ), - .NumVirtChannels ( NumVirtChannels ), - .NumRoutes ( 5 ), - .flit_t ( flit_t ), - .RouteAlgo ( RouteAlgo ), - .ChannelFifoDepth( 2 ), - .IdWidth ( $bits(xy_id_t) ), - .id_t ( xy_id_t ), - .addr_rule_t ( logic ), - .NumAddrRules ( 1 ) - ) i_floo_router ( - .clk_i, - .rst_ni, - .test_enable_i ( 1'b0 ), - - .xy_id_i ( current_id ), - .id_route_map_i ( '0 ), - - .valid_i ( in_valid ), - .ready_o ( in_ready ), - .data_i ( in_flit ), - - .valid_o ( out_valid ), - .ready_i ( out_ready ), - .data_o ( out_flit ) - ); - end - end - -endmodule diff --git a/hw/floo_mesh_ruche.sv b/hw/floo_mesh_ruche.sv deleted file mode 100644 index 39b50d50..00000000 --- a/hw/floo_mesh_ruche.sv +++ /dev/null @@ -1,183 +0,0 @@ -// Copyright 2022 ETH Zurich and University of Bologna. -// Solderpad Hardware License, Version 0.51, see LICENSE for details. -// SPDX-License-Identifier: SHL-0.51 -// -// Michael Rogenmoser -// Tim Fischer - -`include "floo_noc/typedef.svh" - -/// A mesh topology with ruche channels and a configurable number of rows and columns -module floo_mesh_ruche - import floo_pkg::*; -#( - parameter int unsigned NumX = 4, - parameter int unsigned NumY = 4, - parameter int unsigned NumVirtChannels = 1, - parameter int unsigned NumPhysChannels = 1, - parameter int unsigned RucheFactor = 2, - parameter int unsigned NumRoutes = 5, - parameter route_algo_e RouteAlgo = IdTable, - parameter type flit_t = logic, - parameter type xy_id_t = logic -) ( - input logic clk_i, - input logic rst_ni, - input logic [NumX-1:0][NumY-1:0][NumVirtChannels-1:0] valid_i, - output logic [NumX-1:0][NumY-1:0][NumVirtChannels-1:0] ready_o, - input flit_t [NumX-1:0][NumY-1:0][NumPhysChannels-1:0] data_i, - - output logic [NumX-1:0][NumY-1:0][NumVirtChannels-1:0] valid_o, - input logic [NumX-1:0][NumY-1:0][NumVirtChannels-1:0] ready_i, - output flit_t [NumX-1:0][NumY-1:0][NumPhysChannels-1:0] data_o -); - - flit_t [NumX-2:0][NumY-1:0][NumPhysChannels-1:0] pos_x_flit; - logic [NumX-2:0][NumY-1:0][NumVirtChannels-1:0] pos_x_ready, pos_x_valid; - flit_t [NumX-2:0][NumY-1:0][NumPhysChannels-1:0] neg_x_flit; - logic [NumX-2:0][NumY-1:0][NumVirtChannels-1:0] neg_x_ready, neg_x_valid; - flit_t [NumX-1:0][NumY-2:0][NumPhysChannels-1:0] pos_y_flit; - logic [NumX-1:0][NumY-2:0][NumVirtChannels-1:0] pos_y_ready, pos_y_valid; - flit_t [NumX-1:0][NumY-2:0][NumPhysChannels-1:0] neg_y_flit; - logic [NumX-1:0][NumY-2:0][NumVirtChannels-1:0] neg_y_ready, neg_y_valid; - - flit_t [NumX-2:0][NumY-1:0][NumPhysChannels-1:0] ruche_pos_x_flit; - logic [NumX-2:0][NumY-1:0][NumVirtChannels-1:0] ruche_pos_x_ready, ruche_pos_x_valid; - flit_t [NumX-2:0][NumY-1:0][NumPhysChannels-1:0] ruche_neg_x_flit; - logic [NumX-2:0][NumY-1:0][NumVirtChannels-1:0] ruche_neg_x_ready, ruche_neg_x_valid; - flit_t [NumX-1:0][NumY-2:0][NumPhysChannels-1:0] ruche_pos_y_flit; - logic [NumX-1:0][NumY-2:0][NumVirtChannels-1:0] ruche_pos_y_ready, ruche_pos_y_valid; - flit_t [NumX-1:0][NumY-2:0][NumPhysChannels-1:0] ruche_neg_y_flit; - logic [NumX-1:0][NumY-2:0][NumVirtChannels-1:0] ruche_neg_y_ready, ruche_neg_y_valid; - - for (genvar x = 0; x < NumX; x++) begin : gen_x - for (genvar y = 0; y < NumY; y++) begin : gen_y - xy_id_t current_id; - assign current_id = '{x: x, y: y}; - - flit_t [4:0][NumPhysChannels-1:0] in_flit; - logic [4:0][NumVirtChannels-1:0] in_ready, in_valid; - flit_t [4:0][NumPhysChannels-1:0] out_flit; - logic [4:0][NumVirtChannels-1:0] out_ready, out_valid; - - flit_t [RucheWest:RucheNorth][NumPhysChannels-1:0] ruche_in_flit; - logic [RucheWest:RucheNorth][NumVirtChannels-1:0] ruche_in_ready, ruche_in_valid; - flit_t [RucheWest:RucheNorth][NumPhysChannels-1:0] ruche_out_flit; - logic [RucheWest:RucheNorth][NumVirtChannels-1:0] ruche_out_ready, ruche_out_valid; - - always_comb begin - in_flit[West:North] = '0; - in_valid[West:North] = '0; - out_ready[West:North] = '0; - - in_valid[Eject] = valid_i[x][y]; - in_flit[Eject] = data_i[x][y]; - ready_o[x][y] = in_ready[Eject]; - valid_o[x][y] = out_valid[Eject]; - data_o[x][y] = out_flit[Eject]; - out_ready[Eject] = ready_i[x][y]; - - // Y - if (y < NumY-1) begin - in_flit[North] = neg_y_flit[x][y]; - in_valid[North] = neg_y_valid[x][y]; - neg_y_ready[x][y] = in_ready[North]; - pos_y_flit[x][y] = out_flit[North]; - pos_y_valid[x][y] = out_valid[North]; - out_ready[North] = pos_y_ready[x][y]; - end - if (y > 0) begin - in_flit[South] = pos_y_flit[x][y-1]; - in_valid[South] = pos_y_valid[x][y-1]; - pos_y_ready[x][y-1] = in_ready[South]; - neg_y_flit[x][y-1] = out_flit[South]; - neg_y_valid[x][y-1] = out_valid[South]; - out_ready[South] = neg_y_ready[x][y-1]; - end - - // Y Rouche - if (y > RucheFactor) begin - ruche_in_flit[RucheSouth] = ruche_pos_y_flit[x][y-RucheFactor]; - ruche_in_valid[RucheSouth] = ruche_pos_y_valid[x][y-RucheFactor]; - ruche_pos_y_ready[x][y-RucheFactor] = ruche_in_ready[RucheSouth]; - ruche_neg_y_flit[x][y-RucheFactor] = ruche_out_flit[RucheSouth]; - ruche_neg_y_valid[x][y-RucheFactor] = ruche_out_valid[RucheSouth]; - ruche_out_ready[RucheSouth] = ruche_neg_y_ready[x][y-RucheFactor]; - end - if (y < NumY-RucheFactor) begin - ruche_in_flit[RucheNorth] = ruche_neg_y_flit[x][y]; - ruche_in_valid[RucheNorth] = ruche_neg_y_valid[x][y]; - ruche_neg_y_ready[x][y] = ruche_in_ready[RucheNorth]; - ruche_pos_y_flit[x][y] = ruche_out_flit[RucheNorth]; - ruche_pos_y_valid[x][y] = ruche_out_valid[RucheNorth]; - ruche_out_ready[RucheNorth] = ruche_pos_y_ready[x][y]; - end - - // X - if (x < NumX-1) begin - in_flit[East] = neg_x_flit[x][y]; - in_valid[East] = neg_x_valid[x][y]; - neg_x_ready[x][y] = in_ready[East]; - pos_x_flit[x][y] = out_flit[East]; - pos_x_valid[x][y] = out_valid[East]; - out_ready[East] = pos_x_ready[x][y]; - end - if (x > 0) begin - in_flit[West] = pos_x_flit[x-1][y]; - in_valid[West] = pos_x_valid[x-1][y]; - pos_x_ready[x-1][y] = in_ready[West]; - neg_x_flit[x-1][y] = out_flit[West]; - neg_x_valid[x-1][y] = out_valid[West]; - out_ready[West] = neg_x_ready[x-1][y]; - end - - // X Rouche - if (x > RucheFactor) begin - ruche_in_flit[RucheWest] = ruche_pos_x_flit[x-RucheFactor][y]; - ruche_in_valid[RucheWest] = ruche_pos_x_valid[x-RucheFactor][y]; - ruche_pos_x_ready[x-RucheFactor][y] = ruche_in_ready[RucheWest]; - ruche_neg_x_flit[x-RucheFactor][y] = ruche_out_flit[RucheWest]; - ruche_neg_x_valid[x-RucheFactor][y] = ruche_out_valid[RucheWest]; - ruche_out_ready[RucheWest] = ruche_neg_x_ready[x-RucheFactor][y]; - end - if (x < NumX-RucheFactor) begin - ruche_in_flit[RucheEast] = ruche_neg_x_flit[x][y]; - ruche_in_valid[RucheEast] = ruche_neg_x_valid[x][y]; - ruche_neg_x_ready[x][y] = ruche_in_ready[RucheEast]; - ruche_pos_x_flit[x][y] = ruche_out_flit[RucheEast]; - ruche_pos_x_valid[x][y] = ruche_out_valid[RucheEast]; - ruche_out_ready[RucheEast] = ruche_pos_x_ready[x][y]; - end - end - - floo_router #( - .NumPhysChannels ( NumPhysChannels ), - .NumVirtChannels ( NumVirtChannels ), - .NumRoutes ( NumRoutes ), - .flit_t ( flit_t ), - .RouteAlgo ( RouteAlgo ), - .ChannelFifoDepth( 2 ), - .IdWidth ( $bits(xy_id_t) ), - .id_t ( xy_id_t ), - .addr_rule_t ( logic ), - .NumAddrRules ( 1 ) - ) i_floo_router ( - .clk_i, - .rst_ni, - .test_enable_i ( 1'b0 ), - - .xy_id_i ( current_id ), - .id_route_map_i ( '0 ), - - .valid_i ( in_valid ), - .ready_o ( in_ready ), - .data_i ( in_flit ), - - .valid_o ( out_valid ), - .ready_i ( out_ready ), - .data_o ( out_flit ) - ); - end - end - -endmodule diff --git a/hw/floo_meta_buffer.sv b/hw/floo_meta_buffer.sv index 0763ee4b..0b686136 100644 --- a/hw/floo_meta_buffer.sv +++ b/hw/floo_meta_buffer.sv @@ -12,6 +12,10 @@ /// that need to be stored until the response arrives. /// Also supports atomics with unique IDs. module floo_meta_buffer #( + /// AXI in ID width + parameter int unsigned InIdWidth = 0, + /// AXI out ID width + parameter int unsigned OutIdWidth = 0, /// Maximum number of non-atomic outstanding requests parameter int MaxTxns = 32'd0, /// Number of unique non-atomic IDs @@ -45,11 +49,9 @@ module floo_meta_buffer #( ); // AXI parameters - localparam int unsigned IdInWidth = $bits(axi_req_i.aw.id); - localparam int unsigned IdOutWidth = $bits(axi_req_o.aw.id); - localparam int unsigned IdMinWidth = IdInWidth > IdOutWidth ? IdOutWidth : IdInWidth; - typedef logic [IdInWidth-1:0] id_in_t; - typedef logic [IdOutWidth-1:0] id_out_t; + localparam int unsigned IdMinWidth = InIdWidth > OutIdWidth ? OutIdWidth : InIdWidth; + typedef logic [InIdWidth-1:0] id_in_t; + typedef logic [OutIdWidth-1:0] id_out_t; typedef logic [IdMinWidth-1:0] id_min_t; logic ar_no_atop_buf_full, aw_no_atop_buf_full; @@ -112,13 +114,13 @@ module floo_meta_buffer #( id_out_t no_atop_aw_req_id_in, no_atop_ar_req_id_in; - // Non-atomic transaction IDs are assigned to the range [MaxAtomicTxns, 2**IdOutWidth-1), + // Non-atomic transaction IDs are assigned to the range [MaxAtomicTxns, 2**OutIdWidth-1), // Therefore `MaxAtomicTxns` is added/subtracted to/from the ID to get the original ID assign no_atop_aw_req_id = id_min_t'(MaxAtomicTxns) + id_min_t'(axi_req_i.aw.id); assign no_atop_ar_req_id = id_min_t'(MaxAtomicTxns) + id_min_t'(axi_req_i.ar.id); assign no_atop_aw_req_id_in = axi_rsp_i.b.id - id_min_t'(MaxAtomicTxns); assign no_atop_ar_req_id_in = axi_rsp_i.r.id - id_min_t'(MaxAtomicTxns); - `ASSERT_INIT(TooFewIdBits2, MaxAtomicTxns + id_min_t'('1) < 2**IdOutWidth) + `ASSERT_INIT(TooFewIdBits2, MaxAtomicTxns + id_min_t'('1) < 2**OutIdWidth) logic aw_no_atop_buf_not_full, ar_no_atop_buf_not_full; @@ -310,6 +312,6 @@ module floo_meta_buffer #( `ASSERT_INIT(NoAtomicTxns, AtopSupport || (!AtopSupport && (MaxAtomicTxns == 0))) // Multiple outstanding atomics need to use different IDs // Non-atomic transactions all use the same ID - `ASSERT_INIT(TooFewIdBits1, MaxUniqueIds + MaxAtomicTxns <= 2**IdOutWidth) + `ASSERT_INIT(TooFewIdBits1, MaxUniqueIds + MaxAtomicTxns <= 2**OutIdWidth) endmodule diff --git a/hw/floo_narrow_wide_pkg.sv b/hw/floo_narrow_wide_pkg.sv deleted file mode 100644 index 90b060cb..00000000 --- a/hw/floo_narrow_wide_pkg.sv +++ /dev/null @@ -1,267 +0,0 @@ -// Copyright 2022 ETH Zurich and University of Bologna. -// Solderpad Hardware License, Version 0.51, see LICENSE for details. -// SPDX-License-Identifier: SHL-0.51 -// -// This file is auto-generated. Do not edit! Edit the template file instead - -`include "axi/typedef.svh" - -package floo_narrow_wide_pkg; - - import floo_pkg::*; - - //////////////////////// - // AXI Parameters // - //////////////////////// - - typedef enum logic [3:0] { - NarrowAw = 4'd0, - NarrowW = 4'd1, - NarrowAr = 4'd2, - WideAr = 4'd3, - NarrowB = 4'd4, - NarrowR = 4'd5, - WideB = 4'd6, - WideAw = 4'd7, - WideW = 4'd8, - WideR = 4'd9, - NumAxiChannels = 4'd10 - } axi_ch_e; - - - localparam int unsigned AxiNarrowInAddrWidth = 48; - localparam int unsigned AxiNarrowInDataWidth = 64; - localparam int unsigned AxiNarrowInIdWidth = 4; - localparam int unsigned AxiNarrowInUserWidth = 1; - - - localparam int unsigned AxiNarrowOutAddrWidth = 48; - localparam int unsigned AxiNarrowOutDataWidth = 64; - localparam int unsigned AxiNarrowOutIdWidth = 2; - localparam int unsigned AxiNarrowOutUserWidth = 1; - - - localparam int unsigned AxiWideInAddrWidth = 48; - localparam int unsigned AxiWideInDataWidth = 512; - localparam int unsigned AxiWideInIdWidth = 3; - localparam int unsigned AxiWideInUserWidth = 1; - - - localparam int unsigned AxiWideOutAddrWidth = 48; - localparam int unsigned AxiWideOutDataWidth = 512; - localparam int unsigned AxiWideOutIdWidth = 1; - localparam int unsigned AxiWideOutUserWidth = 1; - - - typedef logic [47:0] axi_narrow_in_addr_t; - typedef logic [63:0] axi_narrow_in_data_t; - typedef logic [7:0] axi_narrow_in_strb_t; - typedef logic [3:0] axi_narrow_in_id_t; - typedef logic [0:0] axi_narrow_in_user_t; - `AXI_TYPEDEF_ALL_CT(axi_narrow_in, axi_narrow_in_req_t, axi_narrow_in_rsp_t, axi_narrow_in_addr_t, - axi_narrow_in_id_t, axi_narrow_in_data_t, axi_narrow_in_strb_t, - axi_narrow_in_user_t) - - - typedef logic [47:0] axi_narrow_out_addr_t; - typedef logic [63:0] axi_narrow_out_data_t; - typedef logic [7:0] axi_narrow_out_strb_t; - typedef logic [1:0] axi_narrow_out_id_t; - typedef logic [0:0] axi_narrow_out_user_t; - `AXI_TYPEDEF_ALL_CT(axi_narrow_out, axi_narrow_out_req_t, axi_narrow_out_rsp_t, - axi_narrow_out_addr_t, axi_narrow_out_id_t, axi_narrow_out_data_t, - axi_narrow_out_strb_t, axi_narrow_out_user_t) - - - typedef logic [47:0] axi_wide_in_addr_t; - typedef logic [511:0] axi_wide_in_data_t; - typedef logic [63:0] axi_wide_in_strb_t; - typedef logic [2:0] axi_wide_in_id_t; - typedef logic [0:0] axi_wide_in_user_t; - `AXI_TYPEDEF_ALL_CT(axi_wide_in, axi_wide_in_req_t, axi_wide_in_rsp_t, axi_wide_in_addr_t, - axi_wide_in_id_t, axi_wide_in_data_t, axi_wide_in_strb_t, axi_wide_in_user_t) - - - typedef logic [47:0] axi_wide_out_addr_t; - typedef logic [511:0] axi_wide_out_data_t; - typedef logic [63:0] axi_wide_out_strb_t; - typedef logic [0:0] axi_wide_out_id_t; - typedef logic [0:0] axi_wide_out_user_t; - `AXI_TYPEDEF_ALL_CT(axi_wide_out, axi_wide_out_req_t, axi_wide_out_rsp_t, axi_wide_out_addr_t, - axi_wide_out_id_t, axi_wide_out_data_t, axi_wide_out_strb_t, - axi_wide_out_user_t) - - - - ///////////////////////// - // Header Typedefs // - ///////////////////////// - - localparam route_algo_e RouteAlgo = XYRouting; - localparam bit UseIdTable = 1'b0; - localparam int unsigned NumXBits = 3; - localparam int unsigned NumYBits = 3; - localparam int unsigned XYAddrOffsetX = 16; - localparam int unsigned XYAddrOffsetY = 19; - localparam int unsigned IdAddrOffset = 0; - - - typedef logic [0:0] rob_idx_t; - typedef logic [0:0] port_id_t; - typedef logic [2:0] x_bits_t; - typedef logic [2:0] y_bits_t; - typedef struct packed { - x_bits_t x; - y_bits_t y; - port_id_t port_id; - } id_t; - - typedef logic route_t; - typedef id_t dst_t; - - - typedef struct packed { - logic rob_req; - rob_idx_t rob_idx; - dst_t dst_id; - id_t src_id; - logic last; - logic atop; - axi_ch_e axi_ch; - } hdr_t; - - - - //////////////////////// - // Flits Typedefs // - //////////////////////// - - typedef struct packed { - hdr_t hdr; - axi_narrow_in_aw_chan_t aw; - } floo_narrow_aw_flit_t; - - typedef struct packed { - hdr_t hdr; - axi_narrow_in_w_chan_t w; - logic [13:0] rsvd; - } floo_narrow_w_flit_t; - - typedef struct packed { - hdr_t hdr; - axi_narrow_in_b_chan_t b; - logic [64:0] rsvd; - } floo_narrow_b_flit_t; - - typedef struct packed { - hdr_t hdr; - axi_narrow_in_ar_chan_t ar; - logic [5:0] rsvd; - } floo_narrow_ar_flit_t; - - typedef struct packed { - hdr_t hdr; - axi_narrow_in_r_chan_t r; - } floo_narrow_r_flit_t; - - typedef struct packed { - hdr_t hdr; - axi_wide_in_aw_chan_t aw; - logic [490:0] rsvd; - } floo_wide_aw_flit_t; - - typedef struct packed { - hdr_t hdr; - axi_wide_in_w_chan_t w; - } floo_wide_w_flit_t; - - typedef struct packed { - hdr_t hdr; - axi_wide_in_b_chan_t b; - logic [65:0] rsvd; - } floo_wide_b_flit_t; - - typedef struct packed { - hdr_t hdr; - axi_wide_in_ar_chan_t ar; - logic [6:0] rsvd; - } floo_wide_ar_flit_t; - - typedef struct packed { - hdr_t hdr; - axi_wide_in_r_chan_t r; - logic [58:0] rsvd; - } floo_wide_r_flit_t; - - typedef logic [87:0] floo_req_payload_t; - typedef struct packed { - hdr_t hdr; - floo_req_payload_t payload; - } floo_req_generic_flit_t; - - typedef logic [71:0] floo_rsp_payload_t; - typedef struct packed { - hdr_t hdr; - floo_rsp_payload_t payload; - } floo_rsp_generic_flit_t; - - typedef logic [577:0] floo_wide_payload_t; - typedef struct packed { - hdr_t hdr; - floo_wide_payload_t payload; - } floo_wide_generic_flit_t; - - - - ////////////////////////// - // Channel Typedefs // - ////////////////////////// - - typedef union packed { - floo_narrow_aw_flit_t narrow_aw; - floo_narrow_w_flit_t narrow_w; - floo_narrow_ar_flit_t narrow_ar; - floo_wide_ar_flit_t wide_ar; - floo_req_generic_flit_t generic; - } floo_req_chan_t; - - typedef union packed { - floo_narrow_b_flit_t narrow_b; - floo_narrow_r_flit_t narrow_r; - floo_wide_b_flit_t wide_b; - floo_rsp_generic_flit_t generic; - } floo_rsp_chan_t; - - typedef union packed { - floo_wide_aw_flit_t wide_aw; - floo_wide_w_flit_t wide_w; - floo_wide_r_flit_t wide_r; - floo_wide_generic_flit_t generic; - } floo_wide_chan_t; - - - - /////////////////////// - // Link Typedefs // - /////////////////////// - - typedef struct packed { - logic valid; - logic ready; - floo_req_chan_t req; - } floo_req_t; - - typedef struct packed { - logic valid; - logic ready; - floo_rsp_chan_t rsp; - } floo_rsp_t; - - typedef struct packed { - logic valid; - logic ready; - floo_wide_chan_t wide; - } floo_wide_t; - - -endpackage diff --git a/hw/floo_narrow_wide_chimney.sv b/hw/floo_nw_chimney.sv similarity index 68% rename from hw/floo_narrow_wide_chimney.sv rename to hw/floo_nw_chimney.sv index f8c00c71..c8a3bf97 100644 --- a/hw/floo_narrow_wide_chimney.sv +++ b/hw/floo_nw_chimney.sv @@ -6,78 +6,87 @@ `include "common_cells/registers.svh" `include "common_cells/assertions.svh" +`include "axi/typedef.svh" +`include "floo_noc/typedef.svh" /// A bidirectional network interface for connecting narrow & wide AXI Buses to the multi-link NoC -module floo_narrow_wide_chimney - import floo_pkg::*; - import floo_narrow_wide_pkg::*; -#( - /// FlooNoC defines subordinate ports as requests that go out - /// of the NoC to AXI subordinates (i.e. memories) that return - /// a response, and manager ports as requests that come into the - /// NoC from AXI managers (i.e. cores) - /// Enable the subordinate port of the Narrow AXI4 interface - parameter bit EnNarrowSbrPort = 1'b1, - /// Enable the manager port of the Narrow AXI4 interface - parameter bit EnNarrowMgrPort = 1'b1, - /// Enable the subordinate port of the Wide AXI4 interface - parameter bit EnWideSbrPort = 1'b1, - /// Enable the manager port of the Wide AXI4 interface - parameter bit EnWideMgrPort = 1'b1, +module floo_nw_chimney #( + /// Config of the narrow AXI interfaces (see floo_pkg::axi_cfg_t for details) + parameter floo_pkg::axi_cfg_t AxiCfgN = '0, + /// Config of the wide AXI interfaces (see floo_pkg::axi_cfg_t for details) + parameter floo_pkg::axi_cfg_t AxiCfgW = '0, + /// Config of the narrow data path in the chimney (see floo_pkg::chimney_cfg_t for details) + parameter floo_pkg::chimney_cfg_t ChimneyCfgN = floo_pkg::ChimneyDefaultCfg, + /// Config of the wide data path in the chimney (see floo_pkg::chimney_cfg_t for details) + parameter floo_pkg::chimney_cfg_t ChimneyCfgW = floo_pkg::ChimneyDefaultCfg, + /// Config for routing information (see floo_pkg::route_cfg_t for details) + parameter floo_pkg::route_cfg_t RouteCfg = floo_pkg::RouteDefaultCfg, /// Atomic operation support, currently only implemented for /// the narrow network! parameter bit AtopSupport = 1'b1, /// Maximum number of oustanding Atomic transactions, - /// must be smaller or equal to 2**AxiOutIdWidth-1 since + /// must be smaller or equal to 2**`AxiCfgN.OutIdWidth`-1 since /// Every atomic transactions needs to have a unique ID /// and one ID is reserved for non-atomic transactions parameter int unsigned MaxAtomicTxns = 1, - /// Number of maximum oustanding requests on the narrow network - parameter int unsigned NarrowMaxTxns = 32, - /// Number of maximum oustanding requests on the wide network - parameter int unsigned WideMaxTxns = 32, - /// The number of unique IDs that can be used to send out - /// requests on the narrow network - parameter int unsigned NarrowMaxUniqueIds = 1, - /// The number of unique IDs that can be used to send out - /// requests on the wide network - parameter int unsigned WideMaxUniqueIds = 1, - /// Maximum number of outstanding requests per ID on the narrow network - parameter int unsigned NarrowMaxTxnsPerId = NarrowMaxTxns, - /// Maximum number of outstanding requests per ID on the wide network - parameter int unsigned WideMaxTxnsPerId = WideMaxTxns, - /// Type of the narrow reorder buffer - parameter rob_type_e NarrowRoBType = NoRoB, - /// Type of the wide reorder buffer - parameter rob_type_e WideRoBType = NoRoB, - /// Capacity of the narrow reorder buffers - parameter int unsigned NarrowReorderBufferSize = 256, - /// Capacity of the wide reorder buffers - parameter int unsigned WideReorderBufferSize = 256, - /// Cut timing paths of outgoing requests to the NoC - parameter bit CutAx = 1'b1, - /// Cut timing paths of incoming responses from the NoC - parameter bit CutRsp = 1'b1, - /// Type for implementation inputs and outputs - parameter type sram_cfg_t = logic, - /// Number of System Address Map Rules - parameter int unsigned SamNumRules = 0, - /// Type of System Address Map Rule - parameter type sam_rule_t = logic, - /// System Address Map - parameter sam_rule_t [SamNumRules-1:0] Sam = '0, - /// Number of routes in the routing table - parameter int unsigned NumRoutes = 0 + /// Node ID type for routing + parameter type id_t = logic, + /// RoB index type for reordering. + // (can be ignored if `RoBType == NoRoB`) + parameter type rob_idx_t = logic, + /// Route type for source-based routing + /// (only used if `RouteCfg.RouteAlgo == SourceRouting`) + parameter type route_t = logic, + /// Destination ID type for routing + /// The destination ID type is usually the same as the node ID type, + /// except for the case of source-based routing, where the destination + /// ID is the actual route to the destination i.e. `route_t` + parameter type dst_t = id_t, + /// Header type for the flits + parameter type hdr_t = logic, + /// Rule type for the System Address Map + /// (only used if `RouteCfg.UseIdTable == 1'b1`) + parameter type sam_rule_t = logic, + /// The System Address Map (SAM) rules + /// (only used if `RouteCfg.UseIdTable == 1'b1`) + parameter sam_rule_t [RouteCfg.NumSamRules-1:0] Sam = '0, + /// Narrow AXI manager request channel type + parameter type axi_narrow_in_req_t = logic, + /// Narrow AXI manager response channel type + parameter type axi_narrow_in_rsp_t = logic, + /// Narrow AXI subordinate request channel type + parameter type axi_narrow_out_req_t = logic, + /// Narrow AXI subordinate response channel type + parameter type axi_narrow_out_rsp_t = logic, + /// Wide AXI manager request channel type + parameter type axi_wide_in_req_t = logic, + /// Wide AXI manager response channel type + parameter type axi_wide_in_rsp_t = logic, + /// Wide AXI subordinate request channel type + parameter type axi_wide_out_req_t = logic, + /// Wide AXI subordinate response channel type + parameter type axi_wide_out_rsp_t = logic, + /// Floo `req` link type + parameter type floo_req_t = logic, + /// Floo `rsp` link type + parameter type floo_rsp_t = logic, + /// Floo `wide` link type + parameter type floo_wide_t = logic, + /// SRAM configuration type `tc_sram_impl` in RoB + /// Only used if technology-dependent SRAM is used + parameter type sram_cfg_t = logic ) ( input logic clk_i, input logic rst_ni, input logic test_enable_i, + /// SRAM configuration input sram_cfg_t sram_cfg_i, - /// AXI4 side interfaces + /// Narrow AXI4 side interfaces input axi_narrow_in_req_t axi_narrow_in_req_i, output axi_narrow_in_rsp_t axi_narrow_in_rsp_o, output axi_narrow_out_req_t axi_narrow_out_req_o, input axi_narrow_out_rsp_t axi_narrow_out_rsp_i, + /// Wide AXI4 side interfaces input axi_wide_in_req_t axi_wide_in_req_i, output axi_wide_in_rsp_t axi_wide_in_rsp_o, output axi_wide_out_req_t axi_wide_out_req_o, @@ -85,29 +94,48 @@ module floo_narrow_wide_chimney /// Coordinates/ID of the current tile input id_t id_i, /// Routing table for the current tile - input route_t [NumRoutes-1:0] route_table_i, - /// Output to NoC + input route_t [RouteCfg.NumRoutes-1:0] route_table_i, + /// Output links to NoC output floo_req_t floo_req_o, output floo_rsp_t floo_rsp_o, output floo_wide_t floo_wide_o, - /// Input from NoC + /// Input links from NoC input floo_req_t floo_req_i, input floo_rsp_t floo_rsp_i, input floo_wide_t floo_wide_i ); + import floo_pkg::*; + + typedef logic [AxiCfgN.AddrWidth-1:0] axi_addr_t; + typedef logic [AxiCfgN.InIdWidth-1:0] axi_narrow_in_id_t; + typedef logic [AxiCfgN.UserWidth-1:0] axi_narrow_user_t; + typedef logic [AxiCfgN.DataWidth-1:0] axi_narrow_data_t; + typedef logic [AxiCfgN.DataWidth/8-1:0] axi_narrow_strb_t; + typedef logic [AxiCfgW.InIdWidth-1:0] axi_wide_in_id_t; + typedef logic [AxiCfgW.UserWidth-1:0] axi_wide_user_t; + typedef logic [AxiCfgW.DataWidth-1:0] axi_wide_data_t; + typedef logic [AxiCfgW.DataWidth/8-1:0] axi_wide_strb_t; + + // (Re-) definitons of `axi_in` and `floo` types, for transport + `AXI_TYPEDEF_ALL_CT(axi_narrow, axi_narrow_req_t, axi_narrow_rsp_t, axi_addr_t, + axi_narrow_in_id_t, axi_narrow_data_t, axi_narrow_strb_t, axi_narrow_user_t) + `AXI_TYPEDEF_ALL_CT(axi_wide, axi_wide_req_t, axi_wide_rsp_t, axi_addr_t, + axi_wide_in_id_t, axi_wide_data_t, axi_wide_strb_t, axi_wide_user_t) + `FLOO_TYPEDEF_NW_CHAN_ALL(axi, req, rsp, wide, axi_narrow, axi_wide, AxiCfgN, AxiCfgW, hdr_t) + // Duplicate AXI port signals to degenerate ports // in case they are not used - axi_narrow_in_req_t axi_narrow_req_in; - axi_narrow_in_rsp_t axi_narrow_rsp_out; - axi_wide_in_req_t axi_wide_req_in; - axi_wide_in_rsp_t axi_wide_rsp_out; + axi_narrow_req_t axi_narrow_req_in; + axi_narrow_rsp_t axi_narrow_rsp_out; + axi_wide_req_t axi_wide_req_in; + axi_wide_rsp_t axi_wide_rsp_out; // AX queue - axi_narrow_in_aw_chan_t axi_narrow_aw_queue; - axi_narrow_in_ar_chan_t axi_narrow_ar_queue; - axi_wide_in_aw_chan_t axi_wide_aw_queue; - axi_wide_in_ar_chan_t axi_wide_ar_queue; + axi_narrow_aw_chan_t axi_narrow_aw_queue; + axi_narrow_ar_chan_t axi_narrow_ar_queue; + axi_wide_aw_chan_t axi_wide_aw_queue; + axi_wide_ar_chan_t axi_wide_ar_queue; logic axi_narrow_aw_queue_valid_out, axi_narrow_aw_queue_ready_in; logic axi_narrow_ar_queue_valid_out, axi_narrow_ar_queue_ready_in; logic axi_wide_aw_queue_valid_out, axi_wide_aw_queue_ready_in; @@ -126,19 +154,19 @@ module floo_narrow_wide_chimney floo_wide_chan_t floo_wide_in; logic floo_req_in_valid, floo_rsp_in_valid, floo_wide_in_valid; logic floo_req_out_ready, floo_rsp_out_ready, floo_wide_out_ready; - logic [NumAxiChannels-1:0] axi_valid_in, axi_ready_out; + logic [NumNWAxiChannels-1:0] axi_valid_in, axi_ready_out; // Flit packing - floo_narrow_aw_flit_t floo_narrow_aw; - floo_narrow_ar_flit_t floo_narrow_ar; - floo_narrow_w_flit_t floo_narrow_w; - floo_narrow_b_flit_t floo_narrow_b; - floo_narrow_r_flit_t floo_narrow_r; - floo_wide_aw_flit_t floo_wide_aw; - floo_wide_ar_flit_t floo_wide_ar; - floo_wide_w_flit_t floo_wide_w; - floo_wide_b_flit_t floo_wide_b; - floo_wide_r_flit_t floo_wide_r; + floo_axi_narrow_aw_flit_t floo_narrow_aw; + floo_axi_narrow_ar_flit_t floo_narrow_ar; + floo_axi_narrow_w_flit_t floo_narrow_w; + floo_axi_narrow_b_flit_t floo_narrow_b; + floo_axi_narrow_r_flit_t floo_narrow_r; + floo_axi_wide_aw_flit_t floo_wide_aw; + floo_axi_wide_ar_flit_t floo_wide_ar; + floo_axi_wide_w_flit_t floo_wide_w; + floo_axi_wide_b_flit_t floo_wide_b; + floo_axi_wide_r_flit_t floo_wide_r; // Flit arbitration typedef enum logic {SelAw, SelW} aw_w_sel_e; @@ -146,16 +174,16 @@ module floo_narrow_wide_chimney aw_w_sel_e wide_aw_w_sel_q, wide_aw_w_sel_d; // Flit unpacking - axi_narrow_in_aw_chan_t axi_narrow_unpack_aw; - axi_narrow_in_w_chan_t axi_narrow_unpack_w; - axi_narrow_in_b_chan_t axi_narrow_unpack_b; - axi_narrow_in_ar_chan_t axi_narrow_unpack_ar; - axi_narrow_in_r_chan_t axi_narrow_unpack_r; - axi_wide_in_aw_chan_t axi_wide_unpack_aw; - axi_wide_in_w_chan_t axi_wide_unpack_w; - axi_wide_in_b_chan_t axi_wide_unpack_b; - axi_wide_in_ar_chan_t axi_wide_unpack_ar; - axi_wide_in_r_chan_t axi_wide_unpack_r; + axi_narrow_aw_chan_t axi_narrow_unpack_aw; + axi_narrow_w_chan_t axi_narrow_unpack_w; + axi_narrow_b_chan_t axi_narrow_unpack_b; + axi_narrow_ar_chan_t axi_narrow_unpack_ar; + axi_narrow_r_chan_t axi_narrow_unpack_r; + axi_wide_aw_chan_t axi_wide_unpack_aw; + axi_wide_w_chan_t axi_wide_unpack_w; + axi_wide_b_chan_t axi_wide_unpack_b; + axi_wide_ar_chan_t axi_wide_unpack_ar; + axi_wide_r_chan_t axi_wide_unpack_r; floo_req_generic_flit_t floo_req_unpack_generic; floo_rsp_generic_flit_t floo_rsp_unpack_generic; floo_wide_generic_flit_t floo_wide_unpack_generic; @@ -169,43 +197,38 @@ module floo_narrow_wide_chimney // ID tracking typedef struct packed { axi_narrow_in_id_t id; - logic rob_req; - rob_idx_t rob_idx; - id_t src_id; - logic atop; - } narrow_id_out_buf_t; + hdr_t hdr; + } narrow_meta_buf_t; typedef struct packed { axi_wide_in_id_t id; - logic rob_req; - rob_idx_t rob_idx; - id_t src_id; - } wide_id_out_buf_t; + hdr_t hdr; + } wide_meta_buf_t; // Routing - dst_t [NumAxiChannels-1:0] dst_id; + dst_t [NumNWAxiChannels-1:0] dst_id; dst_t narrow_aw_id_q, wide_aw_id_q; - route_t [NumAxiChannels-1:0] route_out; - id_t [NumAxiChannels-1:0] id_out; + route_t [NumNWAxiChannels-1:0] route_out; + id_t [NumNWAxiChannels-1:0] id_out; - narrow_id_out_buf_t narrow_aw_out_data_in, narrow_aw_out_data_out; - narrow_id_out_buf_t narrow_ar_out_data_in, narrow_ar_out_data_out; - wide_id_out_buf_t wide_aw_out_data_in, wide_aw_out_data_out; - wide_id_out_buf_t wide_ar_out_data_in, wide_ar_out_data_out; + narrow_meta_buf_t narrow_aw_buf_hdr_in, narrow_aw_buf_hdr_out; + narrow_meta_buf_t narrow_ar_buf_hdr_in, narrow_ar_buf_hdr_out; + wide_meta_buf_t wide_aw_buf_hdr_in, wide_aw_buf_hdr_out; + wide_meta_buf_t wide_ar_buf_hdr_in, wide_ar_buf_hdr_out; /////////////////////// // Spill registers // /////////////////////// - if (EnNarrowMgrPort) begin : gen_narrow_sbr_port + if (ChimneyCfgN.EnMgrPort) begin : gen_narrow_sbr_port assign axi_narrow_req_in = axi_narrow_in_req_i; assign axi_narrow_in_rsp_o = axi_narrow_rsp_out; - if (CutAx) begin : gen_ax_cuts + if (ChimneyCfgN.CutAx) begin : gen_ax_cuts spill_register #( - .T ( axi_narrow_in_aw_chan_t ) + .T ( axi_narrow_aw_chan_t ) ) i_narrow_aw_queue ( .clk_i, .rst_ni, @@ -218,7 +241,7 @@ module floo_narrow_wide_chimney ); spill_register #( - .T ( axi_narrow_in_ar_chan_t ) + .T ( axi_narrow_ar_chan_t ) ) i_narrow_ar_queue ( .clk_i, .rst_ni, @@ -241,7 +264,7 @@ module floo_narrow_wide_chimney end else begin : gen_narrow_err_slv_port axi_err_slv #( - .AxiIdWidth ( AxiNarrowInIdWidth ), + .AxiIdWidth ( AxiCfgN.InIdWidth ), .ATOPs ( AtopSupport ), .axi_req_t ( axi_narrow_in_req_t ), .axi_resp_t ( axi_narrow_in_rsp_t ) @@ -259,14 +282,14 @@ module floo_narrow_wide_chimney assign axi_narrow_ar_queue_valid_out = 1'b0; end - if (EnWideMgrPort) begin : gen_wide_sbr_port + if (ChimneyCfgW.EnMgrPort) begin : gen_wide_sbr_port assign axi_wide_req_in = axi_wide_in_req_i; assign axi_wide_in_rsp_o = axi_wide_rsp_out; - if (CutAx) begin : gen_ax_cuts + if (ChimneyCfgW.CutAx) begin : gen_ax_cuts spill_register #( - .T ( axi_wide_in_aw_chan_t ) + .T ( axi_wide_aw_chan_t ) ) i_wide_aw_queue ( .clk_i, .rst_ni, @@ -279,7 +302,7 @@ module floo_narrow_wide_chimney ); spill_register #( - .T ( axi_wide_in_ar_chan_t ) + .T ( axi_wide_ar_chan_t ) ) i_wide_ar_queue ( .clk_i, .rst_ni, @@ -300,7 +323,7 @@ module floo_narrow_wide_chimney end end else begin : gen_wide_err_slv_port axi_err_slv #( - .AxiIdWidth ( AxiWideInIdWidth ), + .AxiIdWidth ( AxiCfgW.InIdWidth ), .ATOPs ( AtopSupport ), .axi_req_t ( axi_wide_in_req_t ), .axi_resp_t ( axi_wide_in_rsp_t ) @@ -318,7 +341,7 @@ module floo_narrow_wide_chimney assign axi_wide_ar_queue_valid_out = 1'b0; end - if (CutRsp) begin : gen_rsp_cuts + if (ChimneyCfgN.CutRsp && ChimneyCfgW.CutRsp) begin : gen_rsp_cuts spill_register #( .T ( floo_req_chan_t ) ) i_narrow_data_req_arb ( @@ -375,14 +398,14 @@ module floo_narrow_wide_chimney /////////////////////// // AW/B RoB - axi_narrow_in_b_chan_t axi_narrow_b_rob_out, axi_narrow_b_rob_in; + axi_narrow_b_chan_t axi_narrow_b_rob_out, axi_narrow_b_rob_in; logic narrow_aw_rob_req_out; rob_idx_t narrow_aw_rob_idx_out; logic narrow_aw_rob_valid_out, narrow_aw_rob_ready_in; logic narrow_aw_rob_valid_in, narrow_aw_rob_ready_out; logic narrow_b_rob_valid_in, narrow_b_rob_ready_out; logic narrow_b_rob_valid_out, narrow_b_rob_ready_in; - axi_wide_in_b_chan_t axi_wide_b_rob_out, axi_wide_b_rob_in; + axi_wide_b_chan_t axi_wide_b_rob_out, axi_wide_b_rob_in; logic wide_aw_rob_req_out; rob_idx_t wide_aw_rob_idx_out; logic wide_aw_rob_valid_out, wide_aw_rob_ready_in; @@ -390,13 +413,13 @@ module floo_narrow_wide_chimney logic wide_b_rob_valid_out, wide_b_rob_ready_in; // AR/R RoB - axi_narrow_in_r_chan_t axi_narrow_r_rob_out, axi_narrow_r_rob_in; + axi_narrow_r_chan_t axi_narrow_r_rob_out, axi_narrow_r_rob_in; logic narrow_ar_rob_req_out; rob_idx_t narrow_ar_rob_idx_out; logic narrow_ar_rob_valid_out, narrow_ar_rob_ready_in; logic narrow_r_rob_valid_in, narrow_r_rob_ready_out; logic narrow_r_rob_valid_out, narrow_r_rob_ready_in; - axi_wide_in_r_chan_t axi_wide_r_rob_out, axi_wide_r_rob_in; + axi_wide_r_chan_t axi_wide_r_rob_out, axi_wide_r_rob_in; logic wide_ar_rob_req_out; rob_idx_t wide_ar_rob_idx_out; logic wide_ar_rob_valid_out, wide_ar_rob_ready_in; @@ -424,17 +447,17 @@ module floo_narrow_wide_chimney end floo_rob_wrapper #( - .RoBType ( NarrowRoBType ), - .ReorderBufferSize ( NarrowReorderBufferSize ), - .MaxRoTxnsPerId ( NarrowMaxTxnsPerId ), - .OnlyMetaData ( 1'b1 ), - .ax_len_t ( axi_pkg::len_t ), - .ax_id_t ( axi_narrow_in_id_t ), - .rsp_chan_t ( axi_narrow_in_b_chan_t ), - .rsp_meta_t ( axi_narrow_in_b_chan_t ), - .rob_idx_t ( rob_idx_t ), - .dest_t ( id_t ), - .sram_cfg_t ( sram_cfg_t ) + .RoBType ( ChimneyCfgN.BRoBType ), + .RoBSize ( ChimneyCfgN.BRoBSize ), + .MaxRoTxnsPerId ( ChimneyCfgN.MaxTxnsPerId ), + .OnlyMetaData ( 1'b1 ), + .ax_len_t ( axi_pkg::len_t ), + .ax_id_t ( axi_narrow_in_id_t ), + .rsp_chan_t ( axi_narrow_b_chan_t ), + .rsp_meta_t ( axi_narrow_b_chan_t ), + .rob_idx_t ( rob_idx_t ), + .dest_t ( id_t ), + .sram_cfg_t ( sram_cfg_t ) ) i_narrow_b_rob ( .clk_i, .rst_ni, @@ -467,17 +490,17 @@ module floo_narrow_wide_chimney assign wide_b_rob_last = floo_rsp_in.wide_b.hdr.last; floo_rob_wrapper #( - .RoBType ( WideRoBType ), - .ReorderBufferSize ( WideReorderBufferSize ), - .MaxRoTxnsPerId ( WideMaxTxnsPerId ), - .OnlyMetaData ( 1'b1 ), - .ax_len_t ( axi_pkg::len_t ), - .ax_id_t ( axi_wide_in_id_t ), - .rsp_chan_t ( axi_wide_in_b_chan_t ), - .rsp_meta_t ( axi_wide_in_b_chan_t ), - .rob_idx_t ( rob_idx_t ), - .dest_t ( id_t ), - .sram_cfg_t ( sram_cfg_t ) + .RoBType ( ChimneyCfgW.BRoBType ), + .RoBSize ( ChimneyCfgW.BRoBSize ), + .MaxRoTxnsPerId ( ChimneyCfgW.MaxTxnsPerId ), + .OnlyMetaData ( 1'b1 ), + .ax_len_t ( axi_pkg::len_t ), + .ax_id_t ( axi_wide_in_id_t ), + .rsp_chan_t ( axi_wide_b_chan_t ), + .rsp_meta_t ( axi_wide_b_chan_t ), + .rob_idx_t ( rob_idx_t ), + .dest_t ( id_t ), + .sram_cfg_t ( sram_cfg_t ) ) i_wide_b_rob ( .clk_i, .rst_ni, @@ -503,39 +526,39 @@ module floo_narrow_wide_chimney ); typedef struct packed { - axi_narrow_in_id_t id; - axi_narrow_in_user_t user; - axi_pkg::resp_t resp; - logic last; - } narrow_meta_t; - - typedef struct packed { - axi_wide_in_id_t id; - axi_wide_in_user_t user; + axi_narrow_in_id_t id; + axi_narrow_user_t user; axi_pkg::resp_t resp; logic last; - } wide_meta_t; + } narrow_r_rob_meta_t; + + typedef struct packed { + axi_wide_in_id_t id; + axi_wide_user_t user; + axi_pkg::resp_t resp; + logic last; + } wide_r_rob_meta_t; logic narrow_r_rob_rob_req; logic narrow_r_rob_last; rob_idx_t narrow_r_rob_rob_idx; assign narrow_r_rob_rob_req = floo_rsp_in.narrow_r.hdr.rob_req; assign narrow_r_rob_rob_idx = floo_rsp_in.narrow_r.hdr.rob_idx; - assign narrow_r_rob_last = floo_rsp_in.narrow_r.r.last; + assign narrow_r_rob_last = floo_rsp_in.narrow_r.payload.last; floo_rob_wrapper #( - .RoBType ( NarrowRoBType ), - .ReorderBufferSize ( NarrowReorderBufferSize ), - .MaxRoTxnsPerId ( NarrowMaxTxnsPerId ), - .OnlyMetaData ( 1'b0 ), - .ax_len_t ( axi_pkg::len_t ), - .ax_id_t ( axi_narrow_in_id_t ), - .rsp_chan_t ( axi_narrow_in_r_chan_t ), - .rsp_data_t ( axi_narrow_in_data_t ), - .rsp_meta_t ( narrow_meta_t ), - .rob_idx_t ( rob_idx_t ), - .dest_t ( id_t ), - .sram_cfg_t ( sram_cfg_t ) + .RoBType ( ChimneyCfgN.RRoBType ), + .RoBSize ( ChimneyCfgN.RRoBSize ), + .MaxRoTxnsPerId ( ChimneyCfgN.MaxTxnsPerId ), + .OnlyMetaData ( 1'b0 ), + .ax_len_t ( axi_pkg::len_t ), + .ax_id_t ( axi_narrow_in_id_t ), + .rsp_chan_t ( axi_narrow_r_chan_t ), + .rsp_data_t ( axi_narrow_data_t ), + .rsp_meta_t ( narrow_r_rob_meta_t ), + .rob_idx_t ( rob_idx_t ), + .dest_t ( id_t ), + .sram_cfg_t ( sram_cfg_t ) ) i_narrow_r_rob ( .clk_i, .rst_ni, @@ -565,21 +588,21 @@ module floo_narrow_wide_chimney rob_idx_t wide_r_rob_rob_idx; assign wide_r_rob_rob_req = floo_wide_in.wide_r.hdr.rob_req; assign wide_r_rob_rob_idx = floo_wide_in.wide_r.hdr.rob_idx; - assign wide_r_rob_last = floo_wide_in.wide_r.r.last; + assign wide_r_rob_last = floo_wide_in.wide_r.payload.last; floo_rob_wrapper #( - .RoBType ( WideRoBType ), - .ReorderBufferSize ( WideReorderBufferSize ), - .MaxRoTxnsPerId ( WideMaxTxnsPerId ), - .OnlyMetaData ( 1'b0 ), - .ax_len_t ( axi_pkg::len_t ), - .ax_id_t ( axi_wide_in_id_t ), - .rsp_chan_t ( axi_wide_in_r_chan_t ), - .rsp_data_t ( axi_wide_in_data_t ), - .rsp_meta_t ( wide_meta_t ), - .rob_idx_t ( rob_idx_t ), - .dest_t ( id_t ), - .sram_cfg_t ( sram_cfg_t ) + .RoBType ( ChimneyCfgW.RRoBType ), + .RoBSize ( ChimneyCfgW.RRoBSize ), + .MaxRoTxnsPerId ( ChimneyCfgW.MaxTxnsPerId ), + .OnlyMetaData ( 1'b0 ), + .ax_len_t ( axi_pkg::len_t ), + .ax_id_t ( axi_wide_in_id_t ), + .rsp_chan_t ( axi_wide_r_chan_t ), + .rsp_data_t ( axi_wide_data_t ), + .rsp_meta_t ( wide_r_rob_meta_t ), + .rob_idx_t ( rob_idx_t ), + .dest_t ( id_t ), + .sram_cfg_t ( sram_cfg_t ) ) i_wide_r_rob ( .clk_i, .rst_ni, @@ -608,20 +631,14 @@ module floo_narrow_wide_chimney // ROUTING // ///////////////// - typedef axi_narrow_in_addr_t addr_t; + typedef axi_addr_t addr_t; floo_route_comp #( - .RouteAlgo ( RouteAlgo ), - .UseIdTable ( UseIdTable ), - .XYAddrOffsetX ( XYAddrOffsetX ), - .XYAddrOffsetY ( XYAddrOffsetY ), - .IdAddrOffset ( IdAddrOffset ), - .NumAddrRules ( SamNumRules ), - .NumRoutes ( NumRoutes ), - .id_t ( id_t ), - .addr_t ( addr_t ), - .addr_rule_t ( sam_rule_t ), - .route_t ( route_t ) + .RouteCfg ( RouteCfg ), + .id_t ( id_t ), + .addr_t ( addr_t ), + .addr_rule_t ( sam_rule_t ), + .route_t ( route_t ) ) i_floo_req_route_comp [3:0] ( .clk_i, .rst_ni, @@ -636,12 +653,10 @@ module floo_narrow_wide_chimney .id_o ({id_out[NarrowAw], id_out[NarrowAr],id_out[WideAw], id_out[WideAr]} ) ); - if (RouteAlgo == SourceRouting) begin : gen_route_field + if (RouteCfg.RouteAlgo == floo_pkg::SourceRouting) begin : gen_route_field floo_route_comp #( - .RouteAlgo ( RouteAlgo ), - .UseIdTable ( 1'b0 ), - .NumAddrRules ( SamNumRules ), - .NumRoutes ( NumRoutes ), + .RouteCfg ( RouteCfg ), + .UseIdTable ( 1'b0 ), // Overwrite `RouteCfg` .id_t ( id_t ), .addr_t ( addr_t ), .addr_rule_t ( sam_rule_t ), @@ -653,8 +668,8 @@ module floo_narrow_wide_chimney .addr_i ( '0 ), .addr_map_i ( '0 ), .id_i ({ - narrow_aw_out_data_out.src_id, narrow_ar_out_data_out.src_id, - wide_aw_out_data_out.src_id, wide_ar_out_data_out.src_id + narrow_aw_buf_hdr_out.hdr.src_id, narrow_ar_buf_hdr_out.hdr.src_id, + wide_aw_buf_hdr_out.hdr.src_id, wide_ar_buf_hdr_out.hdr.src_id }), .route_o ({route_out[NarrowB], route_out[NarrowR], route_out[WideB], route_out[WideR]} ), .id_o ({id_out[NarrowB], id_out[NarrowR], id_out[WideB], id_out[WideR]} ) @@ -667,10 +682,10 @@ module floo_narrow_wide_chimney assign dst_id[NarrowAr] = id_out[NarrowAr]; assign dst_id[WideAw] = id_out[WideAw]; assign dst_id[WideAr] = id_out[WideAr]; - assign dst_id[NarrowB] = narrow_aw_out_data_out.src_id; - assign dst_id[NarrowR] = narrow_ar_out_data_out.src_id; - assign dst_id[WideB] = wide_aw_out_data_out.src_id; - assign dst_id[WideR] = wide_ar_out_data_out.src_id; + assign dst_id[NarrowB] = narrow_aw_buf_hdr_out.hdr.src_id; + assign dst_id[NarrowR] = narrow_ar_buf_hdr_out.hdr.src_id; + assign dst_id[WideB] = wide_aw_buf_hdr_out.hdr.src_id; + assign dst_id[WideR] = wide_ar_buf_hdr_out.hdr.src_id; assign dst_id[NarrowW] = narrow_aw_id_q; assign dst_id[WideW] = wide_aw_id_q; end @@ -693,7 +708,7 @@ module floo_narrow_wide_chimney floo_narrow_aw.hdr.last = 1'b0; // AW and W need to be sent together floo_narrow_aw.hdr.axi_ch = NarrowAw; floo_narrow_aw.hdr.atop = axi_narrow_aw_queue.atop != axi_pkg::ATOP_NONE; - floo_narrow_aw.aw = axi_narrow_aw_queue; + floo_narrow_aw.payload = axi_narrow_aw_queue; end always_comb begin @@ -704,7 +719,7 @@ module floo_narrow_wide_chimney floo_narrow_w.hdr.src_id = id_i; floo_narrow_w.hdr.last = axi_narrow_req_in.w.last; floo_narrow_w.hdr.axi_ch = NarrowW; - floo_narrow_w.w = axi_narrow_req_in.w; + floo_narrow_w.payload = axi_narrow_req_in.w; end always_comb begin @@ -715,33 +730,33 @@ module floo_narrow_wide_chimney floo_narrow_ar.hdr.src_id = id_i; floo_narrow_ar.hdr.last = 1'b1; floo_narrow_ar.hdr.axi_ch = NarrowAr; - floo_narrow_ar.ar = axi_narrow_ar_queue; + floo_narrow_ar.payload = axi_narrow_ar_queue; end always_comb begin floo_narrow_b = '0; - floo_narrow_b.hdr.rob_req = narrow_aw_out_data_out.rob_req; - floo_narrow_b.hdr.rob_idx = rob_idx_t'(narrow_aw_out_data_out.rob_idx); + floo_narrow_b.hdr.rob_req = narrow_aw_buf_hdr_out.hdr.rob_req; + floo_narrow_b.hdr.rob_idx = rob_idx_t'(narrow_aw_buf_hdr_out.hdr.rob_idx); floo_narrow_b.hdr.dst_id = dst_id[NarrowB]; floo_narrow_b.hdr.src_id = id_i; floo_narrow_b.hdr.last = 1'b1; floo_narrow_b.hdr.axi_ch = NarrowB; - floo_narrow_b.hdr.atop = narrow_aw_out_data_out.atop; - floo_narrow_b.b = axi_narrow_meta_buf_rsp_out.b; - floo_narrow_b.b.id = narrow_aw_out_data_out.id; + floo_narrow_b.hdr.atop = narrow_aw_buf_hdr_out.hdr.atop; + floo_narrow_b.payload = axi_narrow_meta_buf_rsp_out.b; + floo_narrow_b.payload.id = narrow_aw_buf_hdr_out.id; end always_comb begin floo_narrow_r = '0; - floo_narrow_r.hdr.rob_req = narrow_ar_out_data_out.rob_req; - floo_narrow_r.hdr.rob_idx = rob_idx_t'(narrow_ar_out_data_out.rob_idx); + floo_narrow_r.hdr.rob_req = narrow_ar_buf_hdr_out.hdr.rob_req; + floo_narrow_r.hdr.rob_idx = rob_idx_t'(narrow_ar_buf_hdr_out.hdr.rob_idx); floo_narrow_r.hdr.dst_id = dst_id[NarrowR]; floo_narrow_r.hdr.src_id = id_i; floo_narrow_r.hdr.axi_ch = NarrowR; floo_narrow_r.hdr.last = 1'b1; // There is no reason to do wormhole routing for R bursts - floo_narrow_r.hdr.atop = narrow_ar_out_data_out.atop; - floo_narrow_r.r = axi_narrow_meta_buf_rsp_out.r; - floo_narrow_r.r.id = narrow_ar_out_data_out.id; + floo_narrow_r.hdr.atop = narrow_ar_buf_hdr_out.hdr.atop; + floo_narrow_r.payload = axi_narrow_meta_buf_rsp_out.r; + floo_narrow_r.payload.id = narrow_ar_buf_hdr_out.id; end always_comb begin @@ -752,7 +767,7 @@ module floo_narrow_wide_chimney floo_wide_aw.hdr.src_id = id_i; floo_wide_aw.hdr.last = 1'b0; // AW and W need to be sent together floo_wide_aw.hdr.axi_ch = WideAw; - floo_wide_aw.aw = axi_wide_aw_queue; + floo_wide_aw.payload = axi_wide_aw_queue; end always_comb begin @@ -763,7 +778,7 @@ module floo_narrow_wide_chimney floo_wide_w.hdr.src_id = id_i; floo_wide_w.hdr.last = axi_wide_req_in.w.last; floo_wide_w.hdr.axi_ch = WideW; - floo_wide_w.w = axi_wide_req_in.w; + floo_wide_w.payload = axi_wide_req_in.w; end always_comb begin @@ -774,31 +789,31 @@ module floo_narrow_wide_chimney floo_wide_ar.hdr.src_id = id_i; floo_wide_ar.hdr.last = 1'b1; floo_wide_ar.hdr.axi_ch = WideAr; - floo_wide_ar.ar = axi_wide_ar_queue; + floo_wide_ar.payload = axi_wide_ar_queue; end always_comb begin floo_wide_b = '0; - floo_wide_b.hdr.rob_req = wide_aw_out_data_out.rob_req; - floo_wide_b.hdr.rob_idx = rob_idx_t'(wide_aw_out_data_out.rob_idx); + floo_wide_b.hdr.rob_req = wide_aw_buf_hdr_out.hdr.rob_req; + floo_wide_b.hdr.rob_idx = rob_idx_t'(wide_aw_buf_hdr_out.hdr.rob_idx); floo_wide_b.hdr.dst_id = dst_id[WideB]; floo_wide_b.hdr.src_id = id_i; floo_wide_b.hdr.last = 1'b1; floo_wide_b.hdr.axi_ch = WideB; - floo_wide_b.b = axi_wide_meta_buf_rsp_out.b; - floo_wide_b.b.id = wide_aw_out_data_out.id; + floo_wide_b.payload = axi_wide_meta_buf_rsp_out.b; + floo_wide_b.payload.id = wide_aw_buf_hdr_out.id; end always_comb begin floo_wide_r = '0; - floo_wide_r.hdr.rob_req = wide_ar_out_data_out.rob_req; - floo_wide_r.hdr.rob_idx = rob_idx_t'(wide_ar_out_data_out.rob_idx); + floo_wide_r.hdr.rob_req = wide_ar_buf_hdr_out.hdr.rob_req; + floo_wide_r.hdr.rob_idx = rob_idx_t'(wide_ar_buf_hdr_out.hdr.rob_idx); floo_wide_r.hdr.dst_id = dst_id[WideR]; floo_wide_r.hdr.src_id = id_i; floo_wide_r.hdr.axi_ch = WideR; floo_wide_r.hdr.last = 1'b1; // There is no reason to do wormhole routing for R bursts - floo_wide_r.r = axi_wide_meta_buf_rsp_out.r; - floo_wide_r.r.id = wide_ar_out_data_out.id; + floo_wide_r.payload = axi_wide_meta_buf_rsp_out.r; + floo_wide_r.payload.id = wide_ar_buf_hdr_out.id; end always_comb begin @@ -926,16 +941,16 @@ module floo_narrow_wide_chimney assign b_sel_atop = is_atop_b_rsp && !b_rob_pending_q; assign r_sel_atop = is_atop_r_rsp && !r_rob_pending_q; - assign axi_narrow_unpack_aw = floo_req_in.narrow_aw.aw; - assign axi_narrow_unpack_w = floo_req_in.narrow_w.w; - assign axi_narrow_unpack_ar = floo_req_in.narrow_ar.ar; - assign axi_narrow_unpack_r = floo_rsp_in.narrow_r.r; - assign axi_narrow_unpack_b = floo_rsp_in.narrow_b.b; - assign axi_wide_unpack_aw = floo_wide_in.wide_aw.aw; - assign axi_wide_unpack_w = floo_wide_in.wide_w.w; - assign axi_wide_unpack_ar = floo_req_in.wide_ar.ar; - assign axi_wide_unpack_r = floo_wide_in.wide_r.r; - assign axi_wide_unpack_b = floo_rsp_in.wide_b.b; + assign axi_narrow_unpack_aw = floo_req_in.narrow_aw.payload; + assign axi_narrow_unpack_w = floo_req_in.narrow_w.payload; + assign axi_narrow_unpack_ar = floo_req_in.narrow_ar.payload; + assign axi_narrow_unpack_r = floo_rsp_in.narrow_r.payload; + assign axi_narrow_unpack_b = floo_rsp_in.narrow_b.payload; + assign axi_wide_unpack_aw = floo_wide_in.wide_aw.payload; + assign axi_wide_unpack_w = floo_wide_in.wide_w.payload; + assign axi_wide_unpack_ar = floo_req_in.wide_ar.payload; + assign axi_wide_unpack_r = floo_wide_in.wide_r.payload; + assign axi_wide_unpack_b = floo_rsp_in.wide_b.payload; assign floo_req_unpack_generic = floo_req_in.generic; assign floo_rsp_unpack_generic = floo_rsp_in.generic; assign floo_wide_unpack_generic = floo_wide_in.generic; @@ -949,17 +964,17 @@ module floo_narrow_wide_chimney (floo_req_unpack_generic.hdr.axi_ch == NarrowAr); assign axi_valid_in[WideAr] = floo_req_in_valid && (floo_req_unpack_generic.hdr.axi_ch == WideAr); - assign axi_valid_in[NarrowB] = EnNarrowMgrPort && floo_rsp_in_valid && + assign axi_valid_in[NarrowB] = ChimneyCfgN.EnMgrPort && floo_rsp_in_valid && (floo_rsp_unpack_generic.hdr.axi_ch == NarrowB); - assign axi_valid_in[NarrowR] = EnNarrowMgrPort && floo_rsp_in_valid && + assign axi_valid_in[NarrowR] = ChimneyCfgN.EnMgrPort && floo_rsp_in_valid && (floo_rsp_unpack_generic.hdr.axi_ch == NarrowR); - assign axi_valid_in[WideB] = EnWideMgrPort && floo_rsp_in_valid && + assign axi_valid_in[WideB] = ChimneyCfgW.EnMgrPort && floo_rsp_in_valid && (floo_rsp_unpack_generic.hdr.axi_ch == WideB); assign axi_valid_in[WideAw] = floo_wide_in_valid && (floo_wide_unpack_generic.hdr.axi_ch == WideAw); assign axi_valid_in[WideW] = floo_wide_in_valid && (floo_wide_unpack_generic.hdr.axi_ch == WideW); - assign axi_valid_in[WideR] = EnWideMgrPort && floo_wide_in_valid && + assign axi_valid_in[WideR] = ChimneyCfgW.EnMgrPort && floo_wide_in_valid && (floo_wide_unpack_generic.hdr.axi_ch == WideR); assign axi_ready_out[NarrowAw] = axi_narrow_meta_buf_rsp_out.aw_ready; @@ -1035,44 +1050,36 @@ module floo_narrow_wide_chimney assign atop_has_r_rsp = AtopSupport && axi_valid_in[NarrowAw] && axi_narrow_unpack_aw.atop[axi_pkg::ATOP_R_RESP]; - assign narrow_aw_out_data_in = '{ + assign narrow_aw_buf_hdr_in = '{ id: axi_narrow_unpack_aw.id, - rob_req: floo_req_in.narrow_aw.hdr.rob_req, - rob_idx: floo_req_in.narrow_aw.hdr.rob_idx, - src_id: floo_req_in.narrow_aw.hdr.src_id, - atop: floo_req_in.narrow_aw.hdr.atop + hdr: floo_req_unpack_generic.hdr }; - assign narrow_ar_out_data_in = '{ + assign narrow_ar_buf_hdr_in = '{ id: (is_atop && atop_has_r_rsp)? axi_narrow_unpack_aw.id : axi_narrow_unpack_ar.id, - rob_req: floo_req_in.narrow_ar.hdr.rob_req, - rob_idx: floo_req_in.narrow_ar.hdr.rob_idx, - src_id: floo_req_in.narrow_ar.hdr.src_id, - atop: floo_req_in.narrow_ar.hdr.atop + hdr: floo_req_unpack_generic.hdr }; - assign wide_aw_out_data_in = '{ + assign wide_aw_buf_hdr_in = '{ id: axi_wide_unpack_aw.id, - rob_req: floo_wide_in.wide_aw.hdr.rob_req, - rob_idx: floo_wide_in.wide_aw.hdr.rob_idx, - src_id: floo_wide_in.wide_aw.hdr.src_id + hdr: floo_wide_unpack_generic.hdr }; - assign wide_ar_out_data_in = '{ + assign wide_ar_buf_hdr_in = '{ id: axi_wide_unpack_ar.id, - rob_req: floo_req_in.wide_ar.hdr.rob_req, - rob_idx: floo_req_in.wide_ar.hdr.rob_idx, - src_id: floo_req_in.wide_ar.hdr.src_id + hdr: floo_req_unpack_generic.hdr }; - if (EnNarrowSbrPort) begin : gen_narrow_mgr_port + if (ChimneyCfgN.EnSbrPort) begin : gen_narrow_mgr_port floo_meta_buffer #( - .MaxTxns ( NarrowMaxTxns ), - .MaxUniqueIds ( NarrowMaxUniqueIds ), - .AtopSupport ( AtopSupport ), - .MaxAtomicTxns ( MaxAtomicTxns ), - .buf_t ( narrow_id_out_buf_t ), - .axi_in_req_t ( axi_narrow_in_req_t ), - .axi_in_rsp_t ( axi_narrow_in_rsp_t ), - .axi_out_req_t ( axi_narrow_out_req_t ), - .axi_out_rsp_t ( axi_narrow_out_rsp_t ) + .InIdWidth ( AxiCfgN.InIdWidth ), + .OutIdWidth ( AxiCfgN.OutIdWidth ), + .MaxTxns ( ChimneyCfgN.MaxTxns ), + .MaxUniqueIds ( ChimneyCfgN.MaxUniqueIds ), + .AtopSupport ( AtopSupport ), + .MaxAtomicTxns ( MaxAtomicTxns ), + .buf_t ( narrow_meta_buf_t ), + .axi_in_req_t ( axi_narrow_in_req_t ), + .axi_in_rsp_t ( axi_narrow_in_rsp_t ), + .axi_out_req_t ( axi_narrow_out_req_t ), + .axi_out_rsp_t ( axi_narrow_out_rsp_t ) ) i_narrow_meta_buffer ( .clk_i, .rst_ni, @@ -1081,17 +1088,17 @@ module floo_narrow_wide_chimney .axi_rsp_o ( axi_narrow_meta_buf_rsp_out ), .axi_req_o ( axi_narrow_out_req_o ), .axi_rsp_i ( axi_narrow_out_rsp_i ), - .aw_buf_i ( narrow_aw_out_data_in ), - .ar_buf_i ( narrow_ar_out_data_in ), - .r_buf_o ( narrow_ar_out_data_out ), - .b_buf_o ( narrow_aw_out_data_out ) + .aw_buf_i ( narrow_aw_buf_hdr_in ), + .ar_buf_i ( narrow_ar_buf_hdr_in ), + .r_buf_o ( narrow_ar_buf_hdr_out ), + .b_buf_o ( narrow_aw_buf_hdr_out ) ); end else begin : gen_no_narrow_mgr_port axi_err_slv #( - .AxiIdWidth ( AxiNarrowInIdWidth ), - .ATOPs ( AtopSupport ), - .axi_req_t ( axi_narrow_in_req_t ), - .axi_resp_t ( axi_narrow_in_rsp_t ) + .AxiIdWidth ( AxiCfgN.InIdWidth ), + .ATOPs ( AtopSupport ), + .axi_req_t ( axi_narrow_req_t ), + .axi_resp_t ( axi_narrow_rsp_t ) ) i_axi_err_slv ( .clk_i ( clk_i ), .rst_ni ( rst_ni ), @@ -1100,21 +1107,23 @@ module floo_narrow_wide_chimney .slv_resp_o ( axi_narrow_meta_buf_rsp_out ) ); assign axi_narrow_out_req_o = '0; - assign narrow_ar_out_data_out = '0; - assign narrow_aw_out_data_out = '0; + assign narrow_ar_buf_hdr_out = '0; + assign narrow_aw_buf_hdr_out = '0; end - if (EnWideSbrPort) begin : gen_wide_mgr_port + if (ChimneyCfgW.EnSbrPort) begin : gen_wide_mgr_port floo_meta_buffer #( - .MaxTxns ( WideMaxTxns ), - .MaxUniqueIds ( WideMaxUniqueIds ), - .AtopSupport ( 1'b0 ), - .MaxAtomicTxns ( '0 ), - .buf_t ( wide_id_out_buf_t ), - .axi_in_req_t ( axi_wide_in_req_t ), - .axi_in_rsp_t ( axi_wide_in_rsp_t ), - .axi_out_req_t ( axi_wide_out_req_t ), - .axi_out_rsp_t ( axi_wide_out_rsp_t ) + .InIdWidth ( AxiCfgW.InIdWidth ), + .OutIdWidth ( AxiCfgW.OutIdWidth ), + .MaxTxns ( ChimneyCfgW.MaxTxns ), + .MaxUniqueIds ( ChimneyCfgW.MaxUniqueIds ), + .AtopSupport ( 1'b0 ), + .MaxAtomicTxns ( '0 ), + .buf_t ( wide_meta_buf_t ), + .axi_in_req_t ( axi_wide_in_req_t ), + .axi_in_rsp_t ( axi_wide_in_rsp_t ), + .axi_out_req_t ( axi_wide_out_req_t ), + .axi_out_rsp_t ( axi_wide_out_rsp_t ) ) i_wide_meta_buffer ( .clk_i, .rst_ni, @@ -1123,14 +1132,14 @@ module floo_narrow_wide_chimney .axi_rsp_o ( axi_wide_meta_buf_rsp_out ), .axi_req_o ( axi_wide_out_req_o ), .axi_rsp_i ( axi_wide_out_rsp_i ), - .aw_buf_i ( wide_aw_out_data_in ), - .ar_buf_i ( wide_ar_out_data_in ), - .r_buf_o ( wide_ar_out_data_out ), - .b_buf_o ( wide_aw_out_data_out ) + .aw_buf_i ( wide_aw_buf_hdr_in ), + .ar_buf_i ( wide_ar_buf_hdr_in ), + .r_buf_o ( wide_ar_buf_hdr_out ), + .b_buf_o ( wide_aw_buf_hdr_out ) ); end else begin : gen_no_wide_mgr_port axi_err_slv #( - .AxiIdWidth ( AxiWideInIdWidth ), + .AxiIdWidth ( AxiCfgW.InIdWidth ), .ATOPs ( 1'b1 ), .axi_req_t ( axi_wide_in_req_t ), .axi_resp_t ( axi_wide_in_rsp_t ) @@ -1142,8 +1151,8 @@ module floo_narrow_wide_chimney .slv_resp_o ( axi_wide_meta_buf_rsp_out ) ); assign axi_wide_out_req_o = '0; - assign wide_ar_out_data_out = '0; - assign wide_aw_out_data_out = '0; + assign wide_ar_buf_hdr_out = '0; + assign wide_aw_buf_hdr_out = '0; end // Registers @@ -1155,18 +1164,23 @@ module floo_narrow_wide_chimney // ASSERTIONS // ///////////////// + // Check that the Address Width of the narrow and Wide interfaces are the same + `ASSERT_INIT(AddrWidthMatch, AxiCfgN.AddrWidth == AxiCfgW.AddrWidth) + + // `CutRsp` of the narrow and wide config must be the same + `ASSERT_INIT(CutRspMatch, ChimneyCfgN.CutRsp == ChimneyCfgW.CutRsp) + // Multiple outstanding atomics need to use different IDs // Non-atomic transactions all use the same ID - `ASSERT_INIT(ToSmallIdWidth, 1 + AtopSupport * MaxAtomicTxns <= 2**AxiNarrowOutIdWidth) + `ASSERT_INIT(ToSmallIdWidth, 1 + AtopSupport * MaxAtomicTxns <= 2**AxiCfgN.OutIdWidth) // If Network Interface has no subordinate port, make sure that `RoBType` is `NoRoB` - `ASSERT_INIT(NoNarrowMgrPortRobType, EnNarrowMgrPort || (NarrowRoBType == NoRoB)) - `ASSERT_INIT(NoWideMgrPortRobType, EnWideMgrPort || (WideRoBType == NoRoB)) - - // Check that all addresses have the same width - `ASSERT_INIT(SameAddrWidth1, AxiNarrowInAddrWidth == AxiNarrowOutAddrWidth) - `ASSERT_INIT(SameAddrWidth2, AxiWideInAddrWidth == AxiNarrowOutAddrWidth) - `ASSERT_INIT(SameAddrWidth3, AxiWideInAddrWidth == AxiWideOutAddrWidth) + `ASSERT_INIT(NoNarrowMgrPortRobType, ChimneyCfgN.EnMgrPort || + (ChimneyCfgN.BRoBType == floo_pkg::NoRoB && + ChimneyCfgN.RRoBType == floo_pkg::NoRoB)) + `ASSERT_INIT(NoWideMgrPortRobType, ChimneyCfgW.EnMgrPort || + (ChimneyCfgW.BRoBType == floo_pkg::NoRoB && + ChimneyCfgW.RRoBType == floo_pkg::NoRoB)) // Data and valid signals must be stable/asserted when ready is low `ASSERT(NarrowReqOutStableValid, floo_req_o.valid && @@ -1183,26 +1197,26 @@ module floo_narrow_wide_chimney !floo_wide_o.ready |=> floo_wide_i.valid) // Network Interface cannot accept any B and R responses if `En*MgrPort` are not set - `ASSERT(NoNarrowMgrPortBResponse, EnNarrowMgrPort || !(floo_rsp_in_valid && + `ASSERT(NoNarrowMgrPortBResponse, ChimneyCfgN.EnMgrPort || !(floo_rsp_in_valid && (floo_rsp_unpack_generic.hdr.axi_ch == NarrowB))) - `ASSERT(NoNarrowMgrPortRResponse, EnNarrowMgrPort || !(floo_rsp_in_valid && + `ASSERT(NoNarrowMgrPortRResponse, ChimneyCfgN.EnMgrPort || !(floo_rsp_in_valid && (floo_rsp_unpack_generic.hdr.axi_ch == NarrowR))) - `ASSERT(NoWideMgrPortBResponse, EnWideMgrPort || !(floo_rsp_in_valid && + `ASSERT(NoWideMgrPortBResponse, ChimneyCfgW.EnMgrPort || !(floo_rsp_in_valid && (floo_rsp_unpack_generic.hdr.axi_ch == WideB))) - `ASSERT(NoWideMgrPortRResponse, EnWideMgrPort || !(floo_wide_in_valid && + `ASSERT(NoWideMgrPortRResponse, ChimneyCfgW.EnMgrPort || !(floo_wide_in_valid && (floo_wide_unpack_generic.hdr.axi_ch == WideR))) // Network Interface cannot accept any AW, AR and W requests if `En*SbrPort` is not set - `ASSERT(NoNarrowSbrPortAwRequest, EnNarrowSbrPort || !(floo_req_in_valid && + `ASSERT(NoNarrowSbrPortAwRequest, ChimneyCfgN.EnSbrPort || !(floo_req_in_valid && (floo_req_unpack_generic.hdr.axi_ch == NarrowAw))) - `ASSERT(NoNarrowSbrPortArRequest, EnNarrowSbrPort || !(floo_req_in_valid && + `ASSERT(NoNarrowSbrPortArRequest, ChimneyCfgN.EnSbrPort || !(floo_req_in_valid && (floo_req_unpack_generic.hdr.axi_ch == NarrowAr))) - `ASSERT(NoNarrowSbrPortWRequest, EnNarrowSbrPort || !(floo_req_in_valid && + `ASSERT(NoNarrowSbrPortWRequest, ChimneyCfgN.EnSbrPort || !(floo_req_in_valid && (floo_req_unpack_generic.hdr.axi_ch == NarrowW))) - `ASSERT(NoWideSbrPortAwRequest, EnWideSbrPort || !(floo_req_in_valid && + `ASSERT(NoWideSbrPortAwRequest, ChimneyCfgW.EnSbrPort || !(floo_req_in_valid && (floo_req_unpack_generic.hdr.axi_ch == WideAw))) - `ASSERT(NoWideSbrPortArRequest, EnWideSbrPort || !(floo_req_in_valid && + `ASSERT(NoWideSbrPortArRequest, ChimneyCfgW.EnSbrPort || !(floo_req_in_valid && (floo_req_unpack_generic.hdr.axi_ch == WideAr))) - `ASSERT(NoWideSbrPortWRequest, EnWideSbrPort || !(floo_wide_in_valid && + `ASSERT(NoWideSbrPortWRequest, ChimneyCfgW.EnSbrPort || !(floo_wide_in_valid && (floo_wide_unpack_generic.hdr.axi_ch == WideW))) endmodule diff --git a/hw/floo_narrow_wide_join.sv b/hw/floo_nw_join.sv similarity index 99% rename from hw/floo_narrow_wide_join.sv rename to hw/floo_nw_join.sv index 752947d3..79881685 100644 --- a/hw/floo_narrow_wide_join.sv +++ b/hw/floo_nw_join.sv @@ -11,7 +11,7 @@ /// This module is intended to be used for instance in front /// of an HBM controller to enable access from both the /// narrow and the wide AXI bus. -module floo_narrow_wide_join #( +module floo_nw_join #( /// Filter Atops on the Narrow AXI bus parameter bit FilterNarrowAtops = 1'b0, /// Filter Atops on the Wide AXI bus diff --git a/hw/floo_narrow_wide_router.sv b/hw/floo_nw_router.sv similarity index 60% rename from hw/floo_narrow_wide_router.sv rename to hw/floo_nw_router.sv index 033e7211..e18c786a 100644 --- a/hw/floo_narrow_wide_router.sv +++ b/hw/floo_nw_router.sv @@ -4,40 +4,82 @@ // // Author: Tim Fischer +`include "axi/typedef.svh" +`include "floo_noc/typedef.svh" + /// Wrapper of a multi-link router for narrow and wide links -module floo_narrow_wide_router - import floo_pkg::*; - import floo_narrow_wide_pkg::*; - #( - parameter int unsigned NumRoutes = NumDirections, - parameter int unsigned NumInputs = NumRoutes, - parameter int unsigned NumOutputs = NumRoutes, - parameter int unsigned ChannelFifoDepth = 0, - parameter int unsigned OutputFifoDepth = 0, - parameter route_algo_e RouteAlgo = XYRouting, - parameter bit XYRouteOpt = 1'b1, - /// Used for ID-based and XY routing - parameter int unsigned IdWidth = 0, - parameter type id_t = logic[IdWidth-1:0], - /// Used for ID-based routing - parameter int unsigned NumAddrRules = 0, - parameter type addr_rule_t = logic +module floo_nw_router #( + /// Config of the narrow AXI interfaces (see floo_pkg::axi_cfg_t for details) + parameter floo_pkg::axi_cfg_t AxiCfgN = '0, + /// Config of the wide AXI interfaces (see floo_pkg::axi_cfg_t for details) + parameter floo_pkg::axi_cfg_t AxiCfgW = '0, + /// Routing algorithm + parameter floo_pkg::route_algo_e RouteAlgo = floo_pkg::XYRouting, + /// Number of input/output ports + parameter int unsigned NumRoutes = 0, + /// Number of input ports + parameter int unsigned NumInputs = NumRoutes, + /// Number of output ports + parameter int unsigned NumOutputs = NumRoutes, + /// Input buffer depth + parameter int unsigned InFifoDepth = 0, + /// Output buffer depth + parameter int unsigned OutFifoDepth = 0, + /// Disable illegal connections in router + /// (only applies for `RouteAlgo == XYRouting`) + parameter bit XYRouteOpt = 1'b1, + /// Node ID type + parameter type id_t = logic, + /// Header type + parameter type hdr_t = logic, + /// Number of rules in the route table + /// (only used for `RouteAlgo == IdTable`) + parameter int unsigned NumAddrRules = 0, + /// Address rule type + /// (only used for `RouteAlgo == IdTable`) + parameter type addr_rule_t = logic, + /// Floo `req` link type + parameter type floo_req_t = logic, + /// Floo `rsp` link type + parameter type floo_rsp_t = logic, + /// Floo `wide` link type + parameter type floo_wide_t = logic ) ( input logic clk_i, input logic rst_ni, input logic test_enable_i, - + /// Coordinate of the current node + /// (only used for `RouteAlgo == XYRouting`) input id_t id_i, + /// Routing table + /// (only used for `RouteAlgo == IdTable`) input addr_rule_t [NumAddrRules-1:0] id_route_map_i, - + /// Input and output links input floo_req_t [NumInputs-1:0] floo_req_i, input floo_rsp_t [NumOutputs-1:0] floo_rsp_i, output floo_req_t [NumOutputs-1:0] floo_req_o, output floo_rsp_t [NumInputs-1:0] floo_rsp_o, - input floo_wide_t [NumRoutes-1:0] floo_wide_i, - output floo_wide_t [NumRoutes-1:0] floo_wide_o + input floo_wide_t [NumRoutes-1:0] floo_wide_i, + output floo_wide_t [NumRoutes-1:0] floo_wide_o ); + typedef logic [AxiCfgN.AddrWidth-1:0] axi_addr_t; + typedef logic [AxiCfgN.InIdWidth-1:0] axi_narrow_in_id_t; + typedef logic [AxiCfgN.UserWidth-1:0] axi_narrow_user_t; + typedef logic [AxiCfgN.DataWidth-1:0] axi_narrow_data_t; + typedef logic [AxiCfgN.DataWidth/8-1:0] axi_narrow_strb_t; + typedef logic [AxiCfgW.InIdWidth-1:0] axi_wide_in_id_t; + typedef logic [AxiCfgW.UserWidth-1:0] axi_wide_user_t; + typedef logic [AxiCfgW.DataWidth-1:0] axi_wide_data_t; + typedef logic [AxiCfgW.DataWidth/8-1:0] axi_wide_strb_t; + + // (Re-) definitons of `axi_in` and `floo` types, for transport + `AXI_TYPEDEF_ALL_CT(axi_narrow, axi_narrow_req_t, axi_narrow_rsp_t, axi_addr_t, + axi_narrow_in_id_t, axi_narrow_data_t, axi_narrow_strb_t, axi_narrow_user_t) + `AXI_TYPEDEF_ALL_CT(axi_wide, axi_wide_req_t, axi_wide_rsp_t, axi_addr_t, + axi_wide_in_id_t, axi_wide_data_t, axi_wide_strb_t, axi_wide_user_t) + `FLOO_TYPEDEF_NW_CHAN_ALL(axi, req, rsp, wide, axi_narrow, axi_wide, AxiCfgN, AxiCfgW, hdr_t) + floo_req_chan_t [NumInputs-1:0] req_in; floo_rsp_chan_t [NumInputs-1:0] rsp_out; floo_req_chan_t [NumOutputs-1:0] req_out; @@ -83,11 +125,10 @@ module floo_narrow_wide_router .NumInput ( NumInputs ), .NumOutput ( NumOutputs ), .flit_t ( floo_req_generic_flit_t ), - .ChannelFifoDepth ( ChannelFifoDepth ), - .OutputFifoDepth ( OutputFifoDepth ), + .InFifoDepth ( InFifoDepth ), + .OutFifoDepth ( OutFifoDepth ), .RouteAlgo ( RouteAlgo ), .XYRouteOpt ( XYRouteOpt ), - .IdWidth ( IdWidth ), .id_t ( id_t ), .NumAddrRules ( NumAddrRules ), .addr_rule_t ( addr_rule_t ) @@ -111,11 +152,10 @@ module floo_narrow_wide_router .NumVirtChannels ( 1 ), .NumInput ( NumInputs ), .NumOutput ( NumOutputs ), - .ChannelFifoDepth ( ChannelFifoDepth ), - .OutputFifoDepth ( OutputFifoDepth ), + .InFifoDepth ( InFifoDepth ), + .OutFifoDepth ( OutFifoDepth ), .RouteAlgo ( RouteAlgo ), .XYRouteOpt ( XYRouteOpt ), - .IdWidth ( IdWidth ), .flit_t ( floo_rsp_generic_flit_t ), .id_t ( id_t ), .NumAddrRules ( NumAddrRules ), @@ -140,11 +180,10 @@ module floo_narrow_wide_router .NumVirtChannels ( 1 ), .NumRoutes ( NumRoutes ), .flit_t ( floo_wide_generic_flit_t ), - .ChannelFifoDepth ( ChannelFifoDepth ), - .OutputFifoDepth ( OutputFifoDepth ), + .InFifoDepth ( InFifoDepth ), + .OutFifoDepth ( OutFifoDepth ), .RouteAlgo ( RouteAlgo ), .XYRouteOpt ( XYRouteOpt ), - .IdWidth ( IdWidth ), .id_t ( id_t ), .NumAddrRules ( NumAddrRules ), .addr_rule_t ( addr_rule_t ) diff --git a/hw/floo_vc_narrow_wide_chimney.sv b/hw/floo_nw_vc_chimney.sv similarity index 73% rename from hw/floo_vc_narrow_wide_chimney.sv rename to hw/floo_nw_vc_chimney.sv index da7ac272..79631d90 100644 --- a/hw/floo_vc_narrow_wide_chimney.sv +++ b/hw/floo_nw_vc_chimney.sv @@ -7,96 +7,113 @@ `include "common_cells/registers.svh" `include "common_cells/assertions.svh" -`include "axi/assign.svh" +`include "axi/typedef.svh" +`include "floo_noc/typedef.svh" /// A bidirectional network interface for connecting narrow & wide AXI Buses to the multi-link NoC -module floo_vc_narrow_wide_chimney - import floo_pkg::*; - import floo_vc_narrow_wide_pkg::*; -#( - /// FlooNoC defines subordinate ports as requests that go out - /// of the NoC to AXI subordinates (i.e. memories) that return - /// a response, and manager ports as requests that come into the - /// NoC from AXI managers (i.e. cores) - /// Enable the subordinate port of the Narrow AXI4 interface - parameter bit EnNarrowSbrPort = 1'b1, - /// Enable the manager port of the Narrow AXI4 interface - parameter bit EnNarrowMgrPort = 1'b1, - /// Enable the subordinate port of the Wide AXI4 interface - parameter bit EnWideSbrPort = 1'b1, - /// Enable the manager port of the Wide AXI4 interface - parameter bit EnWideMgrPort = 1'b1, +module floo_nw_vc_chimney #( + /// Config of the narrow AXI interfaces (see floo_pkg::axi_cfg_t for details) + parameter floo_pkg::axi_cfg_t AxiCfgN = '0, + /// Config of the wide AXI interfaces (see floo_pkg::axi_cfg_t for details) + parameter floo_pkg::axi_cfg_t AxiCfgW = '0, + /// Config of the narrow data path in the chimney (see floo_pkg::chimney_cfg_t for details) + parameter floo_pkg::chimney_cfg_t ChimneyCfgN = floo_pkg::ChimneyDefaultCfg, + /// Config of the wide data path in the chimney (see floo_pkg::chimney_cfg_t for details) + parameter floo_pkg::chimney_cfg_t ChimneyCfgW = floo_pkg::ChimneyDefaultCfg, + /// Config for routing information (see floo_pkg::route_cfg_t for details) + parameter floo_pkg::route_cfg_t RouteCfg = floo_pkg::RouteDefaultCfg, /// Atomic operation support, currently only implemented for /// the narrow network! parameter bit AtopSupport = 1'b1, /// Maximum number of oustanding Atomic transactions, - /// must be smaller or equal to 2**AxiOutIdWidth-1 since + /// must be smaller or equal to 2**`AxiCfgN.OutIdWidth`-1 since /// Every atomic transactions needs to have a unique ID /// and one ID is reserved for non-atomic transactions parameter int unsigned MaxAtomicTxns = 1, - /// Number of maximum oustanding requests on the narrow network - parameter int unsigned NarrowMaxTxns = 32, - /// Number of maximum oustanding requests on the wide network - parameter int unsigned WideMaxTxns = 32, - /// The number of unique IDs that can be used to send out - /// requests on the narrow network - parameter int unsigned NarrowMaxUniqueIds = 1, - /// The number of unique IDs that can be used to send out - /// requests on the wide network - parameter int unsigned WideMaxUniqueIds = 1, - /// Maximum number of outstanding requests per ID on the narrow network - parameter int unsigned NarrowMaxTxnsPerId = NarrowMaxTxns, - /// Maximum number of outstanding requests per ID on the wide network - parameter int unsigned WideMaxTxnsPerId = WideMaxTxns, - /// Type of the narrow reorder buffer - parameter rob_type_e NarrowRoBType = NoRoB, - /// Type of the wide reorder buffer - parameter rob_type_e WideRoBType = NoRoB, - /// Capacity of the narrow reorder buffers - parameter int unsigned NarrowReorderBufferSize = 256, - /// Capacity of the wide reorder buffers - parameter int unsigned WideReorderBufferSize = 256, - /// Cut timing paths of outgoing requests to the NoC - parameter bit CutAx = 1'b1, - /// Cut timing paths of incoming responses from the NoC - parameter bit CutRsp = 1'b1, - /// Type for implementation inputs and outputs - parameter type sram_cfg_t = logic, - /// Used for ID-based and XY routing - parameter int unsigned IdWidth = 0, - //on which port the chimney is connected to the router (as seen from the router) - parameter route_direction_e OutputDir = Eject, - + /// Node ID type for routing + parameter type id_t = logic, + /// RoB index type for reordering. + // (can be ignored if `RoBType == NoRoB`) + parameter type rob_idx_t = logic, + /// Route type for source-based routing + /// (only used if `RouteCfg.RouteAlgo == SourceRouting`) + parameter type route_t = logic, + /// Destination ID type for routing + /// The destination ID type is usually the same as the node ID type, + /// except for the case of source-based routing, where the destination + /// ID is the actual route to the destination i.e. `route_t` + parameter type dst_t = id_t, + /// VC ID type + parameter type vc_id_t = logic, + /// Header type for the flits + parameter type hdr_t = logic, + /// Rule type for the System Address Map + /// (only used if `RouteCfg.UseIdTable == 1'b1`) + parameter type sam_rule_t = logic, + /// The System Address Map (SAM) rules + /// (only used if `RouteCfg.UseIdTable == 1'b1`) + parameter sam_rule_t [RouteCfg.NumSamRules-1:0] Sam = '0, + /// Narrow AXI manager request channel type + parameter type axi_narrow_in_req_t = logic, + /// Narrow AXI manager response channel type + parameter type axi_narrow_in_rsp_t = logic, + /// Narrow AXI subordinate request channel type + parameter type axi_narrow_out_req_t = logic, + /// Narrow AXI subordinate response channel type + parameter type axi_narrow_out_rsp_t = logic, + /// Wide AXI manager request channel type + parameter type axi_wide_in_req_t = logic, + /// Wide AXI manager response channel type + parameter type axi_wide_in_rsp_t = logic, + /// Wide AXI subordinate request channel type + parameter type axi_wide_out_req_t = logic, + /// Wide AXI subordinate response channel type + parameter type axi_wide_out_rsp_t = logic, + /// Floo `req` link type + parameter type floo_vc_req_t = logic, + /// Floo `rsp` link type + parameter type floo_vc_rsp_t = logic, + /// Floo `wide` link type + parameter type floo_vc_wide_t = logic, + /// SRAM configuration type `tc_sram_impl` in RoB + /// Only used if technology-dependent SRAM is used + parameter type sram_cfg_t = logic, + /// Address rule for the `id_route_map_i` + parameter type addr_rule_t = logic, + /// Number of Address Rules in the `id_route_map_i` + parameter int unsigned NumAddrRules = 0, + /// Which port the chimney is connected to the router (as seen from the router) + parameter floo_pkg::route_direction_e OutputDir = floo_pkg::Eject, + /// Number of Virtual channels parameter int NumVC = 4, // as seen from chimney - parameter int NumVCWidth = NumVC > 1 ? $clog2(NumVC) : 1, + /// Number of bits to encode the VC + parameter int NumVCWidth = cf_math_pkg::idx_width(NumVC), + /// Enables faster return of credits to the source parameter int CreditShortcut = 1, + /// Allow overflow to other VCs if the current VC is full parameter int AllowVCOverflow = 1, + /// Depth of incoming VC link buffers parameter int InputFifoDepth = 3, + /// Depth of outgoing VC link buffers parameter int VCDepth = 2, + /// Enables Wormhole routing parameter int FixedWormholeVC = 1, // if 1, force wormhole flits to wormholeVCId + /// VC ID to use for wormhole routing parameter int WormholeVCId = 0, - parameter int WormholeVCDepth = 3, - /// Used for ID-based routing - parameter int unsigned NumAddrRules = 0, - parameter type addr_rule_t = logic, - /// Number of System Address Map Rules - parameter int unsigned SamNumRules = 0, - /// Type of System Address Map Rule - parameter type sam_rule_t = logic, - /// System Address Map - parameter sam_rule_t [SamNumRules-1:0] Sam = '0, - /// Number of routes in the routing table - parameter int unsigned NumRoutes = 0 + /// Depth of the wormhole VC link buffers + parameter int WormholeVCDepth = 3 ) ( input logic clk_i, input logic rst_ni, input logic test_enable_i, + /// SRAM configuration input sram_cfg_t sram_cfg_i, - /// AXI4 side interfaces + /// Narrow AXI4 side interfaces input axi_narrow_in_req_t axi_narrow_in_req_i, output axi_narrow_in_rsp_t axi_narrow_in_rsp_o, output axi_narrow_out_req_t axi_narrow_out_req_o, input axi_narrow_out_rsp_t axi_narrow_out_rsp_i, + /// Wide AXI4 side interfaces input axi_wide_in_req_t axi_wide_in_req_i, output axi_wide_in_rsp_t axi_wide_in_rsp_o, output axi_wide_out_req_t axi_wide_out_req_o, @@ -104,31 +121,51 @@ module floo_vc_narrow_wide_chimney /// Coordinates/ID of the current tile input id_t id_i, /// Routing table for the current tile - input route_t [NumRoutes-1:0] route_table_i, + input route_t [RouteCfg.NumRoutes-1:0] route_table_i, + /// Route map used by lookahead routing. + /// (only used if `RouteCfg.RouteAlgo == IdTable`) input addr_rule_t [NumAddrRules-1:0] id_route_map_i, - - /// Output to NoC + /// Output links to NoC output floo_vc_req_t floo_req_o, output floo_vc_rsp_t floo_rsp_o, output floo_vc_wide_t floo_wide_o, - /// Input from NoC + /// Input links from NoC input floo_vc_req_t floo_req_i, input floo_vc_rsp_t floo_rsp_i, input floo_vc_wide_t floo_wide_i ); + import floo_pkg::*; + + typedef logic [AxiCfgN.AddrWidth-1:0] axi_addr_t; + typedef logic [AxiCfgN.InIdWidth-1:0] axi_narrow_in_id_t; + typedef logic [AxiCfgN.UserWidth-1:0] axi_narrow_user_t; + typedef logic [AxiCfgN.DataWidth-1:0] axi_narrow_data_t; + typedef logic [AxiCfgN.DataWidth/8-1:0] axi_narrow_strb_t; + typedef logic [AxiCfgW.InIdWidth-1:0] axi_wide_in_id_t; + typedef logic [AxiCfgW.UserWidth-1:0] axi_wide_user_t; + typedef logic [AxiCfgW.DataWidth-1:0] axi_wide_data_t; + typedef logic [AxiCfgW.DataWidth/8-1:0] axi_wide_strb_t; + + // (Re-) definitons of `axi_in` and `floo` types, for transport + `AXI_TYPEDEF_ALL_CT(axi_narrow, axi_narrow_req_t, axi_narrow_rsp_t, axi_addr_t, + axi_narrow_in_id_t, axi_narrow_data_t, axi_narrow_strb_t, axi_narrow_user_t) + `AXI_TYPEDEF_ALL_CT(axi_wide, axi_wide_req_t, axi_wide_rsp_t, axi_addr_t, + axi_wide_in_id_t, axi_wide_data_t, axi_wide_strb_t, axi_wide_user_t) + `FLOO_TYPEDEF_NW_CHAN_ALL(axi, req, rsp, wide, axi_narrow, axi_wide, AxiCfgN, AxiCfgW, hdr_t) + // Duplicate AXI port signals to degenerate ports // in case they are not used - axi_narrow_in_req_t axi_narrow_req_in; - axi_narrow_in_rsp_t axi_narrow_rsp_out; - axi_wide_in_req_t axi_wide_req_in; - axi_wide_in_rsp_t axi_wide_rsp_out; + axi_narrow_req_t axi_narrow_req_in; + axi_narrow_rsp_t axi_narrow_rsp_out; + axi_wide_req_t axi_wide_req_in; + axi_wide_rsp_t axi_wide_rsp_out; // AX queue - axi_narrow_in_aw_chan_t axi_narrow_aw_queue; - axi_narrow_in_ar_chan_t axi_narrow_ar_queue; - axi_wide_in_aw_chan_t axi_wide_aw_queue; - axi_wide_in_ar_chan_t axi_wide_ar_queue; + axi_narrow_aw_chan_t axi_narrow_aw_queue; + axi_narrow_ar_chan_t axi_narrow_ar_queue; + axi_wide_aw_chan_t axi_wide_aw_queue; + axi_wide_ar_chan_t axi_wide_ar_queue; logic axi_narrow_aw_queue_valid_out, axi_narrow_aw_queue_ready_in; logic axi_narrow_ar_queue_valid_out, axi_narrow_ar_queue_ready_in; logic axi_wide_aw_queue_valid_out, axi_wide_aw_queue_ready_in; @@ -147,19 +184,19 @@ module floo_vc_narrow_wide_chimney floo_wide_chan_t floo_wide_in; logic floo_req_in_valid, floo_rsp_in_valid, floo_wide_in_valid; logic floo_req_out_ready, floo_rsp_out_ready, floo_wide_out_ready; - logic [NumAxiChannels-1:0] axi_valid_in, axi_ready_out; + logic [NumNWAxiChannels-1:0] axi_valid_in, axi_ready_out; // Flit packing - floo_narrow_aw_flit_t floo_narrow_aw; - floo_narrow_ar_flit_t floo_narrow_ar; - floo_narrow_w_flit_t floo_narrow_w; - floo_narrow_b_flit_t floo_narrow_b; - floo_narrow_r_flit_t floo_narrow_r; - floo_wide_aw_flit_t floo_wide_aw; - floo_wide_ar_flit_t floo_wide_ar; - floo_wide_w_flit_t floo_wide_w; - floo_wide_b_flit_t floo_wide_b; - floo_wide_r_flit_t floo_wide_r; + floo_axi_narrow_aw_flit_t floo_narrow_aw; + floo_axi_narrow_ar_flit_t floo_narrow_ar; + floo_axi_narrow_w_flit_t floo_narrow_w; + floo_axi_narrow_b_flit_t floo_narrow_b; + floo_axi_narrow_r_flit_t floo_narrow_r; + floo_axi_wide_aw_flit_t floo_wide_aw; + floo_axi_wide_ar_flit_t floo_wide_ar; + floo_axi_wide_w_flit_t floo_wide_w; + floo_axi_wide_b_flit_t floo_wide_b; + floo_axi_wide_r_flit_t floo_wide_r; // Flit arbitration typedef enum logic {SelAw, SelW} aw_w_sel_e; @@ -193,16 +230,16 @@ module floo_vc_narrow_wide_chimney floo_wide_wormhole_detected, floo_wide_wh_valid_d, floo_wide_wh_valid; // Flit unpacking - axi_narrow_in_aw_chan_t axi_narrow_unpack_aw; - axi_narrow_in_w_chan_t axi_narrow_unpack_w; - axi_narrow_in_b_chan_t axi_narrow_unpack_b; - axi_narrow_in_ar_chan_t axi_narrow_unpack_ar; - axi_narrow_in_r_chan_t axi_narrow_unpack_r; - axi_wide_in_aw_chan_t axi_wide_unpack_aw; - axi_wide_in_w_chan_t axi_wide_unpack_w; - axi_wide_in_b_chan_t axi_wide_unpack_b; - axi_wide_in_ar_chan_t axi_wide_unpack_ar; - axi_wide_in_r_chan_t axi_wide_unpack_r; + axi_narrow_aw_chan_t axi_narrow_unpack_aw; + axi_narrow_w_chan_t axi_narrow_unpack_w; + axi_narrow_b_chan_t axi_narrow_unpack_b; + axi_narrow_ar_chan_t axi_narrow_unpack_ar; + axi_narrow_r_chan_t axi_narrow_unpack_r; + axi_wide_aw_chan_t axi_wide_unpack_aw; + axi_wide_w_chan_t axi_wide_unpack_w; + axi_wide_b_chan_t axi_wide_unpack_b; + axi_wide_ar_chan_t axi_wide_unpack_ar; + axi_wide_r_chan_t axi_wide_unpack_r; floo_req_generic_flit_t floo_req_unpack_generic; floo_rsp_generic_flit_t floo_rsp_unpack_generic; floo_wide_generic_flit_t floo_wide_unpack_generic; @@ -216,43 +253,38 @@ module floo_vc_narrow_wide_chimney // ID tracking typedef struct packed { axi_narrow_in_id_t id; - logic rob_req; - rob_idx_t rob_idx; - id_t src_id; - logic atop; - } narrow_id_out_buf_t; + hdr_t hdr; + } narrow_meta_buf_t; typedef struct packed { axi_wide_in_id_t id; - logic rob_req; - rob_idx_t rob_idx; - id_t src_id; - } wide_id_out_buf_t; + hdr_t hdr; + } wide_meta_buf_t; // Routing - dst_t [NumAxiChannels-1:0] dst_id; + dst_t [NumNWAxiChannels-1:0] dst_id; dst_t narrow_aw_id_q, wide_aw_id_q; - route_t [NumAxiChannels-1:0] route_out; - id_t [NumAxiChannels-1:0] id_out; + route_t [NumNWAxiChannels-1:0] route_out; + id_t [NumNWAxiChannels-1:0] id_out; - narrow_id_out_buf_t narrow_aw_out_data_in, narrow_aw_out_data_out; - narrow_id_out_buf_t narrow_ar_out_data_in, narrow_ar_out_data_out; - wide_id_out_buf_t wide_aw_out_data_in, wide_aw_out_data_out; - wide_id_out_buf_t wide_ar_out_data_in, wide_ar_out_data_out; + narrow_meta_buf_t narrow_aw_buf_hdr_in, narrow_aw_buf_hdr_out; + narrow_meta_buf_t narrow_ar_buf_hdr_in, narrow_ar_buf_hdr_out; + wide_meta_buf_t wide_aw_buf_hdr_in, wide_aw_buf_hdr_out; + wide_meta_buf_t wide_ar_buf_hdr_in, wide_ar_buf_hdr_out; /////////////////////// // Spill registers // /////////////////////// - if (EnNarrowMgrPort) begin : gen_narrow_sbr_port + if (ChimneyCfgN.EnMgrPort) begin : gen_narrow_sbr_port assign axi_narrow_req_in = axi_narrow_in_req_i; assign axi_narrow_in_rsp_o = axi_narrow_rsp_out; - if (CutAx) begin : gen_ax_cuts + if (ChimneyCfgN.CutAx) begin : gen_ax_cuts spill_register #( - .T ( axi_narrow_in_aw_chan_t ) + .T ( axi_narrow_aw_chan_t ) ) i_narrow_aw_queue ( .clk_i, .rst_ni, @@ -265,7 +297,7 @@ module floo_vc_narrow_wide_chimney ); spill_register #( - .T ( axi_narrow_in_ar_chan_t ) + .T ( axi_narrow_ar_chan_t ) ) i_narrow_ar_queue ( .clk_i, .rst_ni, @@ -288,7 +320,7 @@ module floo_vc_narrow_wide_chimney end else begin : gen_narrow_err_slv_port axi_err_slv #( - .AxiIdWidth ( AxiNarrowInIdWidth ), + .AxiIdWidth ( AxiCfgN.InIdWidth ), .ATOPs ( AtopSupport ), .axi_req_t ( axi_narrow_in_req_t ), .axi_resp_t ( axi_narrow_in_rsp_t ) @@ -306,14 +338,14 @@ module floo_vc_narrow_wide_chimney assign axi_narrow_ar_queue_valid_out = 1'b0; end - if (EnWideMgrPort) begin : gen_wide_sbr_port + if (ChimneyCfgW.EnMgrPort) begin : gen_wide_sbr_port assign axi_wide_req_in = axi_wide_in_req_i; assign axi_wide_in_rsp_o = axi_wide_rsp_out; - if (CutAx) begin : gen_ax_cuts + if (ChimneyCfgW.CutAx) begin : gen_ax_cuts spill_register #( - .T ( axi_wide_in_aw_chan_t ) + .T ( axi_wide_aw_chan_t ) ) i_wide_aw_queue ( .clk_i, .rst_ni, @@ -326,7 +358,7 @@ module floo_vc_narrow_wide_chimney ); spill_register #( - .T ( axi_wide_in_ar_chan_t ) + .T ( axi_wide_ar_chan_t ) ) i_wide_ar_queue ( .clk_i, .rst_ni, @@ -347,7 +379,7 @@ module floo_vc_narrow_wide_chimney end end else begin : gen_wide_err_slv_port axi_err_slv #( - .AxiIdWidth ( AxiWideInIdWidth ), + .AxiIdWidth ( AxiCfgW.InIdWidth ), .ATOPs ( AtopSupport ), .axi_req_t ( axi_wide_in_req_t ), .axi_resp_t ( axi_wide_in_rsp_t ) @@ -365,7 +397,7 @@ module floo_vc_narrow_wide_chimney assign axi_wide_ar_queue_valid_out = 1'b0; end - if (CutRsp) begin : gen_floo_input_fifos + if (ChimneyCfgN.CutRsp && ChimneyCfgW.CutRsp) begin : gen_floo_input_fifos floo_input_fifo #( .Depth ( InputFifoDepth ), .type_t ( floo_req_chan_t ) @@ -414,14 +446,14 @@ module floo_vc_narrow_wide_chimney /////////////////////// // AW/B RoB - axi_narrow_in_b_chan_t axi_narrow_b_rob_out, axi_narrow_b_rob_in; + axi_narrow_b_chan_t axi_narrow_b_rob_out, axi_narrow_b_rob_in; logic narrow_aw_rob_req_out; rob_idx_t narrow_aw_rob_idx_out; logic narrow_aw_rob_valid_out, narrow_aw_rob_ready_in; logic narrow_aw_rob_valid_in, narrow_aw_rob_ready_out; logic narrow_b_rob_valid_in, narrow_b_rob_ready_out; logic narrow_b_rob_valid_out, narrow_b_rob_ready_in; - axi_wide_in_b_chan_t axi_wide_b_rob_out, axi_wide_b_rob_in; + axi_wide_b_chan_t axi_wide_b_rob_out, axi_wide_b_rob_in; logic wide_aw_rob_req_out; rob_idx_t wide_aw_rob_idx_out; logic wide_aw_rob_valid_out, wide_aw_rob_ready_in; @@ -429,13 +461,13 @@ module floo_vc_narrow_wide_chimney logic wide_b_rob_valid_out, wide_b_rob_ready_in; // AR/R RoB - axi_narrow_in_r_chan_t axi_narrow_r_rob_out, axi_narrow_r_rob_in; + axi_narrow_r_chan_t axi_narrow_r_rob_out, axi_narrow_r_rob_in; logic narrow_ar_rob_req_out; rob_idx_t narrow_ar_rob_idx_out; logic narrow_ar_rob_valid_out, narrow_ar_rob_ready_in; logic narrow_r_rob_valid_in, narrow_r_rob_ready_out; logic narrow_r_rob_valid_out, narrow_r_rob_ready_in; - axi_wide_in_r_chan_t axi_wide_r_rob_out, axi_wide_r_rob_in; + axi_wide_r_chan_t axi_wide_r_rob_out, axi_wide_r_rob_in; logic wide_ar_rob_req_out; rob_idx_t wide_ar_rob_idx_out; logic wide_ar_rob_valid_out, wide_ar_rob_ready_in; @@ -463,17 +495,17 @@ module floo_vc_narrow_wide_chimney end floo_rob_wrapper #( - .RoBType ( NarrowRoBType ), - .ReorderBufferSize ( NarrowReorderBufferSize ), - .MaxRoTxnsPerId ( NarrowMaxTxnsPerId ), - .OnlyMetaData ( 1'b1 ), - .ax_len_t ( axi_pkg::len_t ), - .ax_id_t ( axi_narrow_in_id_t ), - .rsp_chan_t ( axi_narrow_in_b_chan_t ), - .rsp_meta_t ( axi_narrow_in_b_chan_t ), - .rob_idx_t ( rob_idx_t ), - .dest_t ( id_t ), - .sram_cfg_t ( sram_cfg_t ) + .RoBType ( ChimneyCfgN.BRoBType ), + .RoBSize ( ChimneyCfgN.BRoBSize ), + .MaxRoTxnsPerId ( ChimneyCfgN.MaxTxnsPerId ), + .OnlyMetaData ( 1'b1 ), + .ax_len_t ( axi_pkg::len_t ), + .ax_id_t ( axi_narrow_in_id_t ), + .rsp_chan_t ( axi_narrow_b_chan_t ), + .rsp_meta_t ( axi_narrow_b_chan_t ), + .rob_idx_t ( rob_idx_t ), + .dest_t ( id_t ), + .sram_cfg_t ( sram_cfg_t ) ) i_narrow_b_rob ( .clk_i, .rst_ni, @@ -506,17 +538,17 @@ module floo_vc_narrow_wide_chimney assign wide_b_rob_last = floo_rsp_in.wide_b.hdr.last; floo_rob_wrapper #( - .RoBType ( WideRoBType ), - .ReorderBufferSize ( WideReorderBufferSize ), - .MaxRoTxnsPerId ( WideMaxTxnsPerId ), - .OnlyMetaData ( 1'b1 ), - .ax_len_t ( axi_pkg::len_t ), - .ax_id_t ( axi_wide_in_id_t ), - .rsp_chan_t ( axi_wide_in_b_chan_t ), - .rsp_meta_t ( axi_wide_in_b_chan_t ), - .rob_idx_t ( rob_idx_t ), - .dest_t ( id_t ), - .sram_cfg_t ( sram_cfg_t ) + .RoBType ( ChimneyCfgW.BRoBType ), + .RoBSize ( ChimneyCfgW.BRoBSize ), + .MaxRoTxnsPerId ( ChimneyCfgW.MaxTxnsPerId ), + .OnlyMetaData ( 1'b1 ), + .ax_len_t ( axi_pkg::len_t ), + .ax_id_t ( axi_wide_in_id_t ), + .rsp_chan_t ( axi_wide_b_chan_t ), + .rsp_meta_t ( axi_wide_b_chan_t ), + .rob_idx_t ( rob_idx_t ), + .dest_t ( id_t ), + .sram_cfg_t ( sram_cfg_t ) ) i_wide_b_rob ( .clk_i, .rst_ni, @@ -542,17 +574,17 @@ module floo_vc_narrow_wide_chimney ); typedef struct packed { - axi_narrow_in_id_t id; - axi_narrow_in_user_t user; - axi_pkg::resp_t resp; - logic last; + axi_narrow_in_id_t id; + axi_narrow_user_t user; + axi_pkg::resp_t resp; + logic last; } narrow_meta_t; typedef struct packed { - axi_wide_in_id_t id; - axi_wide_in_user_t user; - axi_pkg::resp_t resp; - logic last; + axi_wide_in_id_t id; + axi_wide_user_t user; + axi_pkg::resp_t resp; + logic last; } wide_meta_t; logic narrow_r_rob_rob_req; @@ -560,21 +592,21 @@ module floo_vc_narrow_wide_chimney rob_idx_t narrow_r_rob_rob_idx; assign narrow_r_rob_rob_req = floo_rsp_in.narrow_r.hdr.rob_req; assign narrow_r_rob_rob_idx = floo_rsp_in.narrow_r.hdr.rob_idx; - assign narrow_r_rob_last = floo_rsp_in.narrow_r.r.last; + assign narrow_r_rob_last = floo_rsp_in.narrow_r.payload.last; floo_rob_wrapper #( - .RoBType ( NarrowRoBType ), - .ReorderBufferSize ( NarrowReorderBufferSize ), - .MaxRoTxnsPerId ( NarrowMaxTxnsPerId ), - .OnlyMetaData ( 1'b0 ), - .ax_len_t ( axi_pkg::len_t ), - .ax_id_t ( axi_narrow_in_id_t ), - .rsp_chan_t ( axi_narrow_in_r_chan_t ), - .rsp_data_t ( axi_narrow_in_data_t ), - .rsp_meta_t ( narrow_meta_t ), - .rob_idx_t ( rob_idx_t ), - .dest_t ( id_t ), - .sram_cfg_t ( sram_cfg_t ) + .RoBType ( ChimneyCfgN.RRoBType ), + .RoBSize ( ChimneyCfgN.RRoBSize ), + .MaxRoTxnsPerId ( ChimneyCfgN.MaxTxnsPerId ), + .OnlyMetaData ( 1'b0 ), + .ax_len_t ( axi_pkg::len_t ), + .ax_id_t ( axi_narrow_in_id_t ), + .rsp_chan_t ( axi_narrow_r_chan_t ), + .rsp_data_t ( axi_narrow_data_t ), + .rsp_meta_t ( narrow_meta_t ), + .rob_idx_t ( rob_idx_t ), + .dest_t ( id_t ), + .sram_cfg_t ( sram_cfg_t ) ) i_narrow_r_rob ( .clk_i, .rst_ni, @@ -604,21 +636,21 @@ module floo_vc_narrow_wide_chimney rob_idx_t wide_r_rob_rob_idx; assign wide_r_rob_rob_req = floo_wide_in.wide_r.hdr.rob_req; assign wide_r_rob_rob_idx = floo_wide_in.wide_r.hdr.rob_idx; - assign wide_r_rob_last = floo_wide_in.wide_r.r.last; + assign wide_r_rob_last = floo_wide_in.wide_r.payload.last; floo_rob_wrapper #( - .RoBType ( WideRoBType ), - .ReorderBufferSize ( WideReorderBufferSize ), - .MaxRoTxnsPerId ( WideMaxTxnsPerId ), - .OnlyMetaData ( 1'b0 ), - .ax_len_t ( axi_pkg::len_t ), - .ax_id_t ( axi_wide_in_id_t ), - .rsp_chan_t ( axi_wide_in_r_chan_t ), - .rsp_data_t ( axi_wide_in_data_t ), - .rsp_meta_t ( wide_meta_t ), - .rob_idx_t ( rob_idx_t ), - .dest_t ( id_t ), - .sram_cfg_t ( sram_cfg_t ) + .RoBType ( ChimneyCfgW.RRoBType ), + .RoBSize ( ChimneyCfgW.RRoBSize ), + .MaxRoTxnsPerId ( ChimneyCfgW.MaxTxnsPerId ), + .OnlyMetaData ( 1'b0 ), + .ax_len_t ( axi_pkg::len_t ), + .ax_id_t ( axi_wide_in_id_t ), + .rsp_chan_t ( axi_wide_r_chan_t ), + .rsp_data_t ( axi_wide_data_t ), + .rsp_meta_t ( wide_meta_t ), + .rob_idx_t ( rob_idx_t ), + .dest_t ( id_t ), + .sram_cfg_t ( sram_cfg_t ) ) i_wide_r_rob ( .clk_i, .rst_ni, @@ -647,20 +679,14 @@ module floo_vc_narrow_wide_chimney // ROUTING // ///////////////// - typedef axi_narrow_in_addr_t addr_t; + typedef axi_addr_t addr_t; floo_route_comp #( - .RouteAlgo ( RouteAlgo ), - .UseIdTable ( UseIdTable ), - .XYAddrOffsetX ( XYAddrOffsetX ), - .XYAddrOffsetY ( XYAddrOffsetY ), - .IdAddrOffset ( IdAddrOffset ), - .NumAddrRules ( SamNumRules ), - .NumRoutes ( NumRoutes ), - .id_t ( id_t ), - .addr_t ( addr_t ), - .addr_rule_t ( sam_rule_t ), - .route_t ( route_t ) + .RouteCfg ( RouteCfg ), + .id_t ( id_t ), + .addr_t ( addr_t ), + .addr_rule_t ( sam_rule_t ), + .route_t ( route_t ) ) i_floo_req_route_comp [3:0] ( .clk_i, .rst_ni, @@ -675,12 +701,10 @@ module floo_vc_narrow_wide_chimney .id_o ({id_out[NarrowAw], id_out[NarrowAr],id_out[WideAw], id_out[WideAr]} ) ); - if (RouteAlgo == SourceRouting) begin : gen_route_field + if (RouteCfg.RouteAlgo == floo_pkg::SourceRouting) begin : gen_route_field floo_route_comp #( - .RouteAlgo ( RouteAlgo ), - .UseIdTable ( 1'b0 ), - .NumAddrRules ( SamNumRules ), - .NumRoutes ( NumRoutes ), + .RouteCfg ( RouteCfg ), + .UseIdTable ( 1'b0 ), // Overwrite `RouteCfg` .id_t ( id_t ), .addr_t ( addr_t ), .addr_rule_t ( sam_rule_t ), @@ -692,8 +716,8 @@ module floo_vc_narrow_wide_chimney .addr_i ( '0 ), .addr_map_i ( '0 ), .id_i ({ - narrow_aw_out_data_out.src_id, narrow_ar_out_data_out.src_id, - wide_aw_out_data_out.src_id, wide_ar_out_data_out.src_id + narrow_aw_buf_hdr_out.hdr.src_id, narrow_ar_buf_hdr_out.hdr.src_id, + wide_aw_buf_hdr_out.hdr.src_id, wide_ar_buf_hdr_out.hdr.src_id }), .route_o ({route_out[NarrowB], route_out[NarrowR], route_out[WideB], route_out[WideR]} ), .id_o ({id_out[NarrowB], id_out[NarrowR], id_out[WideB], id_out[WideR]} ) @@ -706,10 +730,10 @@ module floo_vc_narrow_wide_chimney assign dst_id[NarrowAr] = id_out[NarrowAr]; assign dst_id[WideAw] = id_out[WideAw]; assign dst_id[WideAr] = id_out[WideAr]; - assign dst_id[NarrowB] = narrow_aw_out_data_out.src_id; - assign dst_id[NarrowR] = narrow_ar_out_data_out.src_id; - assign dst_id[WideB] = wide_aw_out_data_out.src_id; - assign dst_id[WideR] = wide_ar_out_data_out.src_id; + assign dst_id[NarrowB] = narrow_aw_buf_hdr_out.hdr.src_id; + assign dst_id[NarrowR] = narrow_ar_buf_hdr_out.hdr.src_id; + assign dst_id[WideB] = wide_aw_buf_hdr_out.hdr.src_id; + assign dst_id[WideR] = wide_ar_buf_hdr_out.hdr.src_id; assign dst_id[NarrowW] = narrow_aw_id_q; assign dst_id[WideW] = wide_aw_id_q; end @@ -735,7 +759,7 @@ module floo_vc_narrow_wide_chimney floo_narrow_aw.hdr.last = 1'b0; // AW and W need to be sent together floo_narrow_aw.hdr.axi_ch = NarrowAw; floo_narrow_aw.hdr.atop = axi_narrow_aw_queue.atop != axi_pkg::ATOP_NONE; - floo_narrow_aw.aw = axi_narrow_aw_queue; + floo_narrow_aw.payload = axi_narrow_aw_queue; end always_comb begin @@ -747,7 +771,7 @@ module floo_vc_narrow_wide_chimney floo_narrow_w.hdr.lookahead = ChimneyOutDir; // such that lookahead calculates correctly floo_narrow_w.hdr.last = axi_narrow_req_in.w.last; floo_narrow_w.hdr.axi_ch = NarrowW; - floo_narrow_w.w = axi_narrow_req_in.w; + floo_narrow_w.payload = axi_narrow_req_in.w; end always_comb begin @@ -759,35 +783,35 @@ module floo_vc_narrow_wide_chimney floo_narrow_ar.hdr.lookahead = ChimneyOutDir; // such that lookahead calculates correctly floo_narrow_ar.hdr.last = 1'b1; floo_narrow_ar.hdr.axi_ch = NarrowAr; - floo_narrow_ar.ar = axi_narrow_ar_queue; + floo_narrow_ar.payload = axi_narrow_ar_queue; end always_comb begin floo_narrow_b = '0; - floo_narrow_b.hdr.rob_req = narrow_aw_out_data_out.rob_req; - floo_narrow_b.hdr.rob_idx = rob_idx_t'(narrow_aw_out_data_out.rob_idx); + floo_narrow_b.hdr.rob_req = narrow_aw_buf_hdr_out.hdr.rob_req; + floo_narrow_b.hdr.rob_idx = rob_idx_t'(narrow_aw_buf_hdr_out.hdr.rob_idx); floo_narrow_b.hdr.dst_id = dst_id[NarrowB]; floo_narrow_b.hdr.src_id = id_i; floo_narrow_b.hdr.lookahead = ChimneyOutDir; // such that lookahead calculates correctly floo_narrow_b.hdr.last = 1'b1; floo_narrow_b.hdr.axi_ch = NarrowB; - floo_narrow_b.hdr.atop = narrow_aw_out_data_out.atop; - floo_narrow_b.b = axi_narrow_meta_buf_rsp_out.b; - floo_narrow_b.b.id = narrow_aw_out_data_out.id; + floo_narrow_b.hdr.atop = narrow_aw_buf_hdr_out.hdr.atop; + floo_narrow_b.payload = axi_narrow_meta_buf_rsp_out.b; + floo_narrow_b.payload.id = narrow_aw_buf_hdr_out.id; end always_comb begin floo_narrow_r = '0; - floo_narrow_r.hdr.rob_req = narrow_ar_out_data_out.rob_req; - floo_narrow_r.hdr.rob_idx = rob_idx_t'(narrow_ar_out_data_out.rob_idx); + floo_narrow_r.hdr.rob_req = narrow_ar_buf_hdr_out.hdr.rob_req; + floo_narrow_r.hdr.rob_idx = rob_idx_t'(narrow_ar_buf_hdr_out.hdr.rob_idx); floo_narrow_r.hdr.dst_id = dst_id[NarrowR]; floo_narrow_r.hdr.src_id = id_i; floo_narrow_r.hdr.lookahead = ChimneyOutDir; // such that lookahead calculates correctly floo_narrow_r.hdr.axi_ch = NarrowR; floo_narrow_r.hdr.last = 1'b1; // There is no reason to do wormhole routing for R bursts - floo_narrow_r.hdr.atop = narrow_ar_out_data_out.atop; - floo_narrow_r.r = axi_narrow_meta_buf_rsp_out.r; - floo_narrow_r.r.id = narrow_ar_out_data_out.id; + floo_narrow_r.hdr.atop = narrow_ar_buf_hdr_out.hdr.atop; + floo_narrow_r.payload = axi_narrow_meta_buf_rsp_out.r; + floo_narrow_r.payload.id = narrow_ar_buf_hdr_out.id; end always_comb begin @@ -799,7 +823,7 @@ module floo_vc_narrow_wide_chimney floo_wide_aw.hdr.lookahead = ChimneyOutDir; // such that lookahead calculates correctly floo_wide_aw.hdr.last = 1'b0; // AW and W need to be sent together floo_wide_aw.hdr.axi_ch = WideAw; - floo_wide_aw.aw = axi_wide_aw_queue; + floo_wide_aw.payload = axi_wide_aw_queue; end always_comb begin @@ -811,7 +835,7 @@ module floo_vc_narrow_wide_chimney floo_wide_w.hdr.lookahead = ChimneyOutDir; // such that lookahead calculates correctly floo_wide_w.hdr.last = axi_wide_req_in.w.last; floo_wide_w.hdr.axi_ch = WideW; - floo_wide_w.w = axi_wide_req_in.w; + floo_wide_w.payload = axi_wide_req_in.w; end always_comb begin @@ -823,33 +847,33 @@ module floo_vc_narrow_wide_chimney floo_wide_ar.hdr.lookahead = ChimneyOutDir; // such that lookahead calculates correctly floo_wide_ar.hdr.last = 1'b1; floo_wide_ar.hdr.axi_ch = WideAr; - floo_wide_ar.ar = axi_wide_ar_queue; + floo_wide_ar.payload = axi_wide_ar_queue; end always_comb begin floo_wide_b = '0; - floo_wide_b.hdr.rob_req = wide_aw_out_data_out.rob_req; - floo_wide_b.hdr.rob_idx = rob_idx_t'(wide_aw_out_data_out.rob_idx); + floo_wide_b.hdr.rob_req = wide_aw_buf_hdr_out.hdr.rob_req; + floo_wide_b.hdr.rob_idx = rob_idx_t'(wide_aw_buf_hdr_out.hdr.rob_idx); floo_wide_b.hdr.dst_id = dst_id[WideB]; floo_wide_b.hdr.src_id = id_i; floo_wide_b.hdr.lookahead = ChimneyOutDir; // such that lookahead calculates correctly floo_wide_b.hdr.last = 1'b1; floo_wide_b.hdr.axi_ch = WideB; - floo_wide_b.b = axi_wide_meta_buf_rsp_out.b; - floo_wide_b.b.id = wide_aw_out_data_out.id; + floo_wide_b.payload = axi_wide_meta_buf_rsp_out.b; + floo_wide_b.payload.id = wide_aw_buf_hdr_out.id; end always_comb begin floo_wide_r = '0; - floo_wide_r.hdr.rob_req = wide_ar_out_data_out.rob_req; - floo_wide_r.hdr.rob_idx = rob_idx_t'(wide_ar_out_data_out.rob_idx); + floo_wide_r.hdr.rob_req = wide_ar_buf_hdr_out.hdr.rob_req; + floo_wide_r.hdr.rob_idx = rob_idx_t'(wide_ar_buf_hdr_out.hdr.rob_idx); floo_wide_r.hdr.dst_id = dst_id[WideR]; floo_wide_r.hdr.src_id = id_i; floo_wide_r.hdr.lookahead = ChimneyOutDir; // such that lookahead calculates correctly floo_wide_r.hdr.axi_ch = WideR; floo_wide_r.hdr.last = 1'b1; // There is no reason to do wormhole routing for R bursts - floo_wide_r.r = axi_wide_meta_buf_rsp_out.r; - floo_wide_r.r.id = wide_ar_out_data_out.id; + floo_wide_r.payload = axi_wide_meta_buf_rsp_out.r; + floo_wide_r.payload.id = wide_ar_buf_hdr_out.id; end always_comb begin @@ -971,56 +995,53 @@ module floo_vc_narrow_wide_chimney /////////////////////// floo_look_ahead_routing #( - .NumRoutes ( NumRoutes ), - .hdr_t ( hdr_t ), - .RouteAlgo ( RouteAlgo ), - .IdWidth ( IdWidth ), - .id_t ( id_t ), - .NumAddrRules ( SamNumRules ), - .addr_rule_t ( sam_rule_t ) + .NumRoutes ( RouteCfg.NumRoutes ), + .hdr_t ( hdr_t ), + .RouteAlgo ( RouteCfg.RouteAlgo ), + .id_t ( id_t ), + .NumAddrRules ( RouteCfg.NumSamRules ), + .addr_rule_t ( sam_rule_t ) ) i_floo_req_look_ahead_routing ( .clk_i, .rst_ni, + .id_route_map_i, .hdr_i ( floo_req_arb_sel_hdr ), .hdr_o ( floo_req_sel_hdr ), .la_route_o ( floo_req_lookahead ), - .id_route_map_i, .xy_id_i ( id_i ) ); floo_look_ahead_routing #( - .NumRoutes ( NumRoutes ), - .hdr_t ( hdr_t ), - .RouteAlgo ( RouteAlgo ), - .IdWidth ( IdWidth ), - .id_t ( id_t ), - .NumAddrRules ( SamNumRules ), - .addr_rule_t ( sam_rule_t ) + .NumRoutes ( RouteCfg.NumRoutes ), + .hdr_t ( hdr_t ), + .RouteAlgo ( RouteCfg.RouteAlgo ), + .id_t ( id_t ), + .NumAddrRules ( RouteCfg.NumSamRules ), + .addr_rule_t ( sam_rule_t ) ) i_floo_rsp_look_ahead_routing ( .clk_i, .rst_ni, + .id_route_map_i, .hdr_i ( floo_rsp_arb_sel_hdr ), .hdr_o ( floo_rsp_sel_hdr ), .la_route_o ( floo_rsp_lookahead ), - .id_route_map_i, .xy_id_i ( id_i ) ); floo_look_ahead_routing #( - .NumRoutes ( NumRoutes ), - .hdr_t ( hdr_t ), - .RouteAlgo ( RouteAlgo ), - .IdWidth ( IdWidth ), - .id_t ( id_t ), - .NumAddrRules ( SamNumRules ), - .addr_rule_t ( sam_rule_t ) + .NumRoutes ( RouteCfg.NumRoutes ), + .hdr_t ( hdr_t ), + .RouteAlgo ( RouteCfg.RouteAlgo ), + .id_t ( id_t ), + .NumAddrRules ( RouteCfg.NumSamRules ), + .addr_rule_t ( sam_rule_t ) ) i_floo_wide_look_ahead_routing ( .clk_i, .rst_ni, + .id_route_map_i, .hdr_i ( floo_wide_arb_sel_hdr ), .hdr_o ( floo_wide_sel_hdr ), .la_route_o ( floo_wide_lookahead ), - .id_route_map_i, .xy_id_i ( id_i ) ); @@ -1289,16 +1310,16 @@ module floo_vc_narrow_wide_chimney assign b_sel_atop = is_atop_b_rsp && !b_rob_pending_q; assign r_sel_atop = is_atop_r_rsp && !r_rob_pending_q; - assign axi_narrow_unpack_aw = floo_req_in.narrow_aw.aw; - assign axi_narrow_unpack_w = floo_req_in.narrow_w.w; - assign axi_narrow_unpack_ar = floo_req_in.narrow_ar.ar; - assign axi_narrow_unpack_r = floo_rsp_in.narrow_r.r; - assign axi_narrow_unpack_b = floo_rsp_in.narrow_b.b; - assign axi_wide_unpack_aw = floo_wide_in.wide_aw.aw; - assign axi_wide_unpack_w = floo_wide_in.wide_w.w; - assign axi_wide_unpack_ar = floo_req_in.wide_ar.ar; - assign axi_wide_unpack_r = floo_wide_in.wide_r.r; - assign axi_wide_unpack_b = floo_rsp_in.wide_b.b; + assign axi_narrow_unpack_aw = floo_req_in.narrow_aw.payload; + assign axi_narrow_unpack_w = floo_req_in.narrow_w.payload; + assign axi_narrow_unpack_ar = floo_req_in.narrow_ar.payload; + assign axi_narrow_unpack_r = floo_rsp_in.narrow_r.payload; + assign axi_narrow_unpack_b = floo_rsp_in.narrow_b.payload; + assign axi_wide_unpack_aw = floo_wide_in.wide_aw.payload; + assign axi_wide_unpack_w = floo_wide_in.wide_w.payload; + assign axi_wide_unpack_ar = floo_req_in.wide_ar.payload; + assign axi_wide_unpack_r = floo_wide_in.wide_r.payload; + assign axi_wide_unpack_b = floo_rsp_in.wide_b.payload; assign floo_req_unpack_generic = floo_req_in.generic; assign floo_rsp_unpack_generic = floo_rsp_in.generic; assign floo_wide_unpack_generic = floo_wide_in.generic; @@ -1312,17 +1333,17 @@ module floo_vc_narrow_wide_chimney (floo_req_unpack_generic.hdr.axi_ch == NarrowAr); assign axi_valid_in[WideAr] = floo_req_in_valid && (floo_req_unpack_generic.hdr.axi_ch == WideAr); - assign axi_valid_in[NarrowB] = EnNarrowMgrPort && floo_rsp_in_valid && + assign axi_valid_in[NarrowB] = ChimneyCfgN.EnMgrPort && floo_rsp_in_valid && (floo_rsp_unpack_generic.hdr.axi_ch == NarrowB); - assign axi_valid_in[NarrowR] = EnNarrowMgrPort && floo_rsp_in_valid && + assign axi_valid_in[NarrowR] = ChimneyCfgN.EnMgrPort && floo_rsp_in_valid && (floo_rsp_unpack_generic.hdr.axi_ch == NarrowR); - assign axi_valid_in[WideB] = EnWideMgrPort && floo_rsp_in_valid && + assign axi_valid_in[WideB] = ChimneyCfgW.EnMgrPort && floo_rsp_in_valid && (floo_rsp_unpack_generic.hdr.axi_ch == WideB); assign axi_valid_in[WideAw] = floo_wide_in_valid && (floo_wide_unpack_generic.hdr.axi_ch == WideAw); assign axi_valid_in[WideW] = floo_wide_in_valid && (floo_wide_unpack_generic.hdr.axi_ch == WideW); - assign axi_valid_in[WideR] = EnWideMgrPort && floo_wide_in_valid && + assign axi_valid_in[WideR] = ChimneyCfgW.EnMgrPort && floo_wide_in_valid && (floo_wide_unpack_generic.hdr.axi_ch == WideR); assign axi_ready_out[NarrowAw] = axi_narrow_meta_buf_rsp_out.aw_ready; @@ -1398,44 +1419,36 @@ module floo_vc_narrow_wide_chimney assign atop_has_r_rsp = AtopSupport && axi_valid_in[NarrowAw] && axi_narrow_unpack_aw.atop[axi_pkg::ATOP_R_RESP]; - assign narrow_aw_out_data_in = '{ + assign narrow_aw_buf_hdr_in = '{ id: axi_narrow_unpack_aw.id, - rob_req: floo_req_in.narrow_aw.hdr.rob_req, - rob_idx: floo_req_in.narrow_aw.hdr.rob_idx, - src_id: floo_req_in.narrow_aw.hdr.src_id, - atop: floo_req_in.narrow_aw.hdr.atop + hdr: floo_req_unpack_generic.hdr }; - assign narrow_ar_out_data_in = '{ + assign narrow_ar_buf_hdr_in = '{ id: (is_atop && atop_has_r_rsp)? axi_narrow_unpack_aw.id : axi_narrow_unpack_ar.id, - rob_req: floo_req_in.narrow_ar.hdr.rob_req, - rob_idx: floo_req_in.narrow_ar.hdr.rob_idx, - src_id: floo_req_in.narrow_ar.hdr.src_id, - atop: floo_req_in.narrow_ar.hdr.atop + hdr: floo_req_unpack_generic.hdr }; - assign wide_aw_out_data_in = '{ + assign wide_aw_buf_hdr_in = '{ id: axi_wide_unpack_aw.id, - rob_req: floo_wide_in.wide_aw.hdr.rob_req, - rob_idx: floo_wide_in.wide_aw.hdr.rob_idx, - src_id: floo_wide_in.wide_aw.hdr.src_id + hdr: floo_wide_unpack_generic.hdr }; - assign wide_ar_out_data_in = '{ + assign wide_ar_buf_hdr_in = '{ id: axi_wide_unpack_ar.id, - rob_req: floo_req_in.wide_ar.hdr.rob_req, - rob_idx: floo_req_in.wide_ar.hdr.rob_idx, - src_id: floo_req_in.wide_ar.hdr.src_id + hdr: floo_req_unpack_generic.hdr }; - if (EnNarrowSbrPort) begin : gen_narrow_mgr_port + if (ChimneyCfgN.EnSbrPort) begin : gen_narrow_mgr_port floo_meta_buffer #( - .MaxTxns ( NarrowMaxTxns ), - .MaxUniqueIds ( NarrowMaxUniqueIds ), - .AtopSupport ( AtopSupport ), - .MaxAtomicTxns ( MaxAtomicTxns ), - .buf_t ( narrow_id_out_buf_t ), - .axi_in_req_t ( axi_narrow_in_req_t ), - .axi_in_rsp_t ( axi_narrow_in_rsp_t ), - .axi_out_req_t ( axi_narrow_out_req_t ), - .axi_out_rsp_t ( axi_narrow_out_rsp_t ) + .InIdWidth ( AxiCfgN.InIdWidth ), + .OutIdWidth ( AxiCfgN.OutIdWidth ), + .MaxTxns ( ChimneyCfgN.MaxTxns ), + .MaxUniqueIds ( ChimneyCfgN.MaxUniqueIds ), + .AtopSupport ( AtopSupport ), + .MaxAtomicTxns ( MaxAtomicTxns ), + .buf_t ( narrow_meta_buf_t ), + .axi_in_req_t ( axi_narrow_in_req_t ), + .axi_in_rsp_t ( axi_narrow_in_rsp_t ), + .axi_out_req_t ( axi_narrow_out_req_t ), + .axi_out_rsp_t ( axi_narrow_out_rsp_t ) ) i_narrow_meta_buffer ( .clk_i, .rst_ni, @@ -1444,14 +1457,14 @@ module floo_vc_narrow_wide_chimney .axi_rsp_o ( axi_narrow_meta_buf_rsp_out ), .axi_req_o ( axi_narrow_out_req_o ), .axi_rsp_i ( axi_narrow_out_rsp_i ), - .aw_buf_i ( narrow_aw_out_data_in ), - .ar_buf_i ( narrow_ar_out_data_in ), - .r_buf_o ( narrow_ar_out_data_out ), - .b_buf_o ( narrow_aw_out_data_out ) + .aw_buf_i ( narrow_aw_buf_hdr_in ), + .ar_buf_i ( narrow_ar_buf_hdr_in ), + .r_buf_o ( narrow_ar_buf_hdr_out ), + .b_buf_o ( narrow_aw_buf_hdr_out ) ); end else begin : gen_no_narrow_mgr_port axi_err_slv #( - .AxiIdWidth ( AxiNarrowInIdWidth ), + .AxiIdWidth ( AxiCfgN.InIdWidth ), .ATOPs ( AtopSupport ), .axi_req_t ( axi_narrow_in_req_t ), .axi_resp_t ( axi_narrow_in_rsp_t ) @@ -1463,21 +1476,23 @@ module floo_vc_narrow_wide_chimney .slv_resp_o ( axi_narrow_meta_buf_rsp_out ) ); assign axi_narrow_out_req_o = '0; - assign narrow_ar_out_data_out = '0; - assign narrow_aw_out_data_out = '0; + assign narrow_ar_buf_hdr_out = '0; + assign narrow_aw_buf_hdr_out = '0; end - if (EnWideSbrPort) begin : gen_wide_mgr_port + if (ChimneyCfgW.EnSbrPort) begin : gen_wide_mgr_port floo_meta_buffer #( - .MaxTxns ( WideMaxTxns ), - .MaxUniqueIds ( WideMaxUniqueIds ), - .AtopSupport ( 1'b0 ), - .MaxAtomicTxns ( '0 ), - .buf_t ( wide_id_out_buf_t ), - .axi_in_req_t ( axi_wide_in_req_t ), - .axi_in_rsp_t ( axi_wide_in_rsp_t ), - .axi_out_req_t ( axi_wide_out_req_t ), - .axi_out_rsp_t ( axi_wide_out_rsp_t ) + .InIdWidth ( AxiCfgW.InIdWidth ), + .OutIdWidth ( AxiCfgW.OutIdWidth ), + .MaxTxns ( ChimneyCfgW.MaxTxns ), + .MaxUniqueIds ( ChimneyCfgW.MaxUniqueIds ), + .AtopSupport ( 1'b0 ), + .MaxAtomicTxns ( '0 ), + .buf_t ( wide_meta_buf_t ), + .axi_in_req_t ( axi_wide_in_req_t ), + .axi_in_rsp_t ( axi_wide_in_rsp_t ), + .axi_out_req_t ( axi_wide_out_req_t ), + .axi_out_rsp_t ( axi_wide_out_rsp_t ) ) i_wide_meta_buffer ( .clk_i, .rst_ni, @@ -1486,14 +1501,14 @@ module floo_vc_narrow_wide_chimney .axi_rsp_o ( axi_wide_meta_buf_rsp_out ), .axi_req_o ( axi_wide_out_req_o ), .axi_rsp_i ( axi_wide_out_rsp_i ), - .aw_buf_i ( wide_aw_out_data_in ), - .ar_buf_i ( wide_ar_out_data_in ), - .r_buf_o ( wide_ar_out_data_out ), - .b_buf_o ( wide_aw_out_data_out ) + .aw_buf_i ( wide_aw_buf_hdr_in ), + .ar_buf_i ( wide_ar_buf_hdr_in ), + .r_buf_o ( wide_ar_buf_hdr_out ), + .b_buf_o ( wide_aw_buf_hdr_out ) ); end else begin : gen_no_wide_mgr_port axi_err_slv #( - .AxiIdWidth ( AxiWideInIdWidth ), + .AxiIdWidth ( AxiCfgN.InIdWidth ), .ATOPs ( 1'b1 ), .axi_req_t ( axi_wide_in_req_t ), .axi_resp_t ( axi_wide_in_rsp_t ) @@ -1505,8 +1520,8 @@ module floo_vc_narrow_wide_chimney .slv_resp_o ( axi_wide_meta_buf_rsp_out ) ); assign axi_wide_out_req_o = '0; - assign wide_ar_out_data_out = '0; - assign wide_aw_out_data_out = '0; + assign wide_ar_buf_hdr_out = '0; + assign wide_aw_buf_hdr_out = '0; end // Registers @@ -1518,40 +1533,42 @@ module floo_vc_narrow_wide_chimney // ASSERTIONS // ///////////////// + // Check that the Address Width of the narrow and Wide interfaces are the same + `ASSERT_INIT(AddrWidthMatch, AxiCfgN.AddrWidth == AxiCfgW.AddrWidth) + // Multiple outstanding atomics need to use different IDs // Non-atomic transactions all use the same ID - `ASSERT_INIT(ToSmallIdWidth, 1 + AtopSupport * MaxAtomicTxns <= 2**AxiNarrowOutIdWidth) + `ASSERT_INIT(ToSmallIdWidth, 1 + AtopSupport * MaxAtomicTxns <= 2**AxiCfgN.OutIdWidth) // If Network Interface has no subordinate port, make sure that `RoBType` is `NoRoB` - `ASSERT_INIT(NoNarrowMgrPortRobType, EnNarrowMgrPort || (NarrowRoBType == NoRoB)) - `ASSERT_INIT(NoWideMgrPortRobType, EnWideMgrPort || (WideRoBType == NoRoB)) - - // Check that all addresses have the same width - `ASSERT_INIT(SameAddrWidth1, AxiNarrowInAddrWidth == AxiNarrowOutAddrWidth) - `ASSERT_INIT(SameAddrWidth2, AxiWideInAddrWidth == AxiNarrowOutAddrWidth) - `ASSERT_INIT(SameAddrWidth3, AxiWideInAddrWidth == AxiWideOutAddrWidth) + `ASSERT_INIT(NoNarrowMgrPortRobType, ChimneyCfgN.EnMgrPort || + (ChimneyCfgN.BRoBType == floo_pkg::NoRoB && + ChimneyCfgN.RRoBType == floo_pkg::NoRoB)) + `ASSERT_INIT(NoWideMgrPortRobType, ChimneyCfgW.EnMgrPort || + (ChimneyCfgW.BRoBType == floo_pkg::NoRoB && + ChimneyCfgW.RRoBType == floo_pkg::NoRoB)) // Network Interface cannot accept any B and R responses if `En*MgrPort` are not set - `ASSERT(NoNarrowMgrPortBResponse, EnNarrowMgrPort || !(floo_rsp_in_valid && + `ASSERT(NoNarrowMgrPortBResponse, ChimneyCfgN.EnMgrPort || !(floo_rsp_in_valid && (floo_rsp_unpack_generic.hdr.axi_ch == NarrowB))) - `ASSERT(NoNarrowMgrPortRResponse, EnNarrowMgrPort || !(floo_rsp_in_valid && + `ASSERT(NoNarrowMgrPortRResponse, ChimneyCfgN.EnMgrPort || !(floo_rsp_in_valid && (floo_rsp_unpack_generic.hdr.axi_ch == NarrowR))) - `ASSERT(NoWideMgrPortBResponse, EnWideMgrPort || !(floo_rsp_in_valid && + `ASSERT(NoWideMgrPortBResponse, ChimneyCfgW.EnMgrPort || !(floo_rsp_in_valid && (floo_rsp_unpack_generic.hdr.axi_ch == WideB))) - `ASSERT(NoWideMgrPortRResponse, EnWideMgrPort || !(floo_wide_in_valid && + `ASSERT(NoWideMgrPortRResponse, ChimneyCfgW.EnMgrPort || !(floo_wide_in_valid && (floo_wide_unpack_generic.hdr.axi_ch == WideR))) // Network Interface cannot accept any AW, AR and W requests if `En*SbrPort` is not set - `ASSERT(NoNarrowSbrPortAwRequest, EnNarrowSbrPort || !(floo_req_in_valid && + `ASSERT(NoNarrowSbrPortAwRequest, ChimneyCfgN.EnSbrPort || !(floo_req_in_valid && (floo_req_unpack_generic.hdr.axi_ch == NarrowAw))) - `ASSERT(NoNarrowSbrPortArRequest, EnNarrowSbrPort || !(floo_req_in_valid && + `ASSERT(NoNarrowSbrPortArRequest, ChimneyCfgN.EnSbrPort || !(floo_req_in_valid && (floo_req_unpack_generic.hdr.axi_ch == NarrowAr))) - `ASSERT(NoNarrowSbrPortWRequest, EnNarrowSbrPort || !(floo_req_in_valid && + `ASSERT(NoNarrowSbrPortWRequest, ChimneyCfgN.EnSbrPort || !(floo_req_in_valid && (floo_req_unpack_generic.hdr.axi_ch == NarrowW))) - `ASSERT(NoWideSbrPortAwRequest, EnWideSbrPort || !(floo_req_in_valid && + `ASSERT(NoWideSbrPortAwRequest, ChimneyCfgW.EnSbrPort || !(floo_req_in_valid && (floo_req_unpack_generic.hdr.axi_ch == WideAw))) - `ASSERT(NoWideSbrPortArRequest, EnWideSbrPort || !(floo_req_in_valid && + `ASSERT(NoWideSbrPortArRequest, ChimneyCfgW.EnSbrPort || !(floo_req_in_valid && (floo_req_unpack_generic.hdr.axi_ch == WideAr))) - `ASSERT(NoWideSbrPortWRequest, EnWideSbrPort || !(floo_wide_in_valid && + `ASSERT(NoWideSbrPortWRequest, ChimneyCfgW.EnSbrPort || !(floo_wide_in_valid && (floo_wide_unpack_generic.hdr.axi_ch == WideW))) // all inputs need to go to vc 0 since there is only one vc `ASSERT(OnlyVC0Req, floo_req_i.req.generic.hdr.vc_id == '0 || !floo_req_i.valid) diff --git a/hw/floo_vc_narrow_wide_router.sv b/hw/floo_nw_vc_router.sv similarity index 72% rename from hw/floo_vc_narrow_wide_router.sv rename to hw/floo_nw_vc_router.sv index 2b5a7695..52e11479 100644 --- a/hw/floo_vc_narrow_wide_router.sv +++ b/hw/floo_nw_vc_router.sv @@ -5,46 +5,55 @@ // Tim Fischer // Lukas Berner +`include "axi/typedef.svh" +`include "floo_noc/typedef.svh" + /// Wrapper of a multi-link router for narrow and wide links -module floo_vc_narrow_wide_router +module floo_nw_vc_router import floo_pkg::*; - import floo_vc_narrow_wide_pkg::*; - #( - parameter int NumPorts = 5, - parameter int NumLocalPorts = NumPorts - 4, - parameter int NumVC [NumPorts] = - {1+NumLocalPorts, 3+NumLocalPorts, 1+NumLocalPorts, 3+NumLocalPorts, 4+NumLocalPorts-1}, - // Num VC from dir N,E,S,W,L0(,L1,L2,L3): 1313 for XY routing - parameter int NumVCMax = NumPorts - 1, - // NumVCWidth: needs to be 3 in routers with more than 1 local ports - parameter int NumVCWidth = 3, - // set this to 3 towards routers with more than 1 local ports: towards N,E,S,W,L0(,L1,L2,L3) - parameter int NumVCToOut [NumPorts] = {2,4,2,4,1}, - parameter int NumVCToOutMax = 4, - parameter int NumVCWidthToOutMax = 2, - - parameter int NumInputSaGlobal[NumPorts] = - {3+NumLocalPorts, 1+NumLocalPorts, 3+NumLocalPorts, 1+NumLocalPorts, 4+NumLocalPorts-1}, - // to dir N,E,S,W,L0(,L1,L2,L3) - parameter int VCDepth = 2, - parameter int VCDepthWidth = $clog2(VCDepth+1), - parameter int CreditShortcut = 1, // not used if SingleStage - parameter int AllowVCOverflow = 1, // 1: FVADA, 0: fixed VC per direction - parameter int FixedWormholeVC = 1, - parameter int WormholeVCId [NumPorts] = {0,1,0,2,0}, // as seen from output port - parameter int WormholeVCDepth = 3, - parameter int AllowOverflowFromDeeperVC = 1, //overriden if AllowVCOverflow is 0 - parameter int UpdateRRArbIfNotSent = 0, - parameter int SingleStage = 0, // 0: standard 2 stage, 1: single stage - - // Route Algorithm stuff - parameter route_algo_e RouteAlgo = XYRouting, - /// Used for ID-based and XY routing - parameter int unsigned IdWidth = 1, - parameter type id_t = logic[IdWidth-1:0], - /// Used for ID-based routing - parameter int unsigned NumAddrRules = 0, - parameter type addr_rule_t = logic +#( + parameter floo_pkg::axi_cfg_t AxiCfgN = '0, + parameter floo_pkg::axi_cfg_t AxiCfgW = '0, + parameter int NumPorts = 5, + parameter int NumLocalPorts = NumPorts - 4, + parameter int NumVC [NumPorts] = + {1+NumLocalPorts, 3+NumLocalPorts, 1+NumLocalPorts, 3+NumLocalPorts, 4+NumLocalPorts-1}, + // Num VC from dir N,E,S,W,L0(,L1,L2,L3): 1313 for XY routing + parameter int NumVCMax = NumPorts - 1, + // NumVCWidth: needs to be 3 in routers with more than 1 local ports + parameter int NumVCWidth = 3, + // set this to 3 towards routers with more than 1 local ports: towards N,E,S,W,L0(,L1,L2,L3) + parameter int NumVCToOut [NumPorts] = {2,4,2,4,1}, + parameter int NumVCToOutMax = 4, + parameter int NumVCWidthToOutMax = 2, + + parameter int NumInputSaGlobal[NumPorts] = + {3+NumLocalPorts, 1+NumLocalPorts, 3+NumLocalPorts, 1+NumLocalPorts, 4+NumLocalPorts-1}, + // to dir N,E,S,W,L0(,L1,L2,L3) + parameter int VCDepth = 2, + parameter int VCDepthWidth = $clog2(VCDepth+1), + parameter int CreditShortcut = 1, // not used if SingleStage + parameter int AllowVCOverflow = 1, // 1: FVADA, 0: fixed VC per direction + parameter int FixedWormholeVC = 1, + parameter int WormholeVCId [NumPorts] = {0,1,0,2,0}, // as seen from output port + parameter int WormholeVCDepth = 3, + parameter int AllowOverflowFromDeeperVC = 1, //overriden if AllowVCOverflow is 0 + parameter int UpdateRRArbIfNotSent = 0, + parameter int SingleStage = 0, // 0: standard 2 stage, 1: single stage + + // Route Algorithm stuff + parameter route_algo_e RouteAlgo = XYRouting, + /// Used for ID-based and XY routing + parameter int unsigned IdWidth = 1, + parameter type id_t = logic[IdWidth-1:0], + parameter type hdr_t = logic, + parameter type vc_id_t = logic, + /// Used for ID-based routing + parameter int unsigned NumAddrRules = 0, + parameter type addr_rule_t = logic, + parameter type floo_vc_req_t = logic, + parameter type floo_vc_rsp_t = logic, + parameter type floo_vc_wide_t = logic ) ( input logic clk_i, input logic rst_ni, @@ -60,6 +69,23 @@ module floo_vc_narrow_wide_router output floo_vc_wide_t [NumPorts-1:0] floo_wide_o ); + typedef logic [AxiCfgN.AddrWidth-1:0] axi_addr_t; + typedef logic [AxiCfgN.InIdWidth-1:0] axi_narrow_in_id_t; + typedef logic [AxiCfgN.UserWidth-1:0] axi_narrow_user_t; + typedef logic [AxiCfgN.DataWidth-1:0] axi_narrow_data_t; + typedef logic [AxiCfgN.DataWidth/8-1:0] axi_narrow_strb_t; + typedef logic [AxiCfgW.InIdWidth-1:0] axi_wide_in_id_t; + typedef logic [AxiCfgW.UserWidth-1:0] axi_wide_user_t; + typedef logic [AxiCfgW.DataWidth-1:0] axi_wide_data_t; + typedef logic [AxiCfgW.DataWidth/8-1:0] axi_wide_strb_t; + + // (Re-) definitons of `axi_in` and `floo` types, for transport + `AXI_TYPEDEF_ALL_CT(axi_narrow, axi_narrow_req_t, axi_narrow_rsp_t, axi_addr_t, + axi_narrow_in_id_t, axi_narrow_data_t, axi_narrow_strb_t, axi_narrow_user_t) + `AXI_TYPEDEF_ALL_CT(axi_wide, axi_wide_req_t, axi_wide_rsp_t, axi_addr_t, + axi_wide_in_id_t, axi_wide_data_t, axi_wide_strb_t, axi_wide_user_t) + `FLOO_TYPEDEF_NW_CHAN_ALL(axi, req, rsp, wide, axi_narrow, axi_wide, AxiCfgN, AxiCfgW, hdr_t) + floo_req_chan_t [NumPorts-1:0] req_in, req_out; floo_rsp_chan_t [NumPorts-1:0] rsp_in, rsp_out; floo_wide_chan_t [NumPorts-1:0] wide_in, wide_out; diff --git a/hw/floo_pkg.sv b/hw/floo_pkg.sv index bf399fcb..d9f151c2 100644 --- a/hw/floo_pkg.sv +++ b/hw/floo_pkg.sv @@ -9,13 +9,39 @@ /// Currently only contains useful functions and some constants and typedefs package floo_pkg; + /// Currently Supported Routing Algorithms typedef enum logic[1:0] { - IdIsPort, + /// `IdTable` routing uses a table of routing rules to determine to + /// which output port a packet should be routed, based on the + /// destination ID encoded in the header of the flit. Every router + /// needs its own table, that is passed to `id_route_map_i`. The + /// network interface only needs to convert the physical address to + /// the destination ID, that is later used by the routers. IdTable, + /// `SourceRouting` calculates the route to the destination in the + /// source itself (i.e. the network interfaces). The route is encoded + /// as a sequence of router ports that the packet should traverse. At + /// every router hop, a port is popped from the route list. The routes + /// need to be passed to the network interfaces `route_table_i`, whic + /// is a table of routes that can be indexed with the destination ID. + /// This algorithm is mainly useful for smaller networks with fewer + /// hops where the encoding size of the route does not become too large. SourceRouting, + /// `XYRouting` is a simple routing algorithm that routes packets + /// based on the XY coordinates of current and destination node. Every + /// router needs to be aware of its own XY coordinates and forwards + /// packets based on the difference of the coordinates. The network + /// interface needs to convert the physical address to the destination + /// XY coordinates, which can be done with addressoffsets `XYAddrOffsetX` + /// and `XYAddrOffsetY`, or by indexing the system address map `Sam`. This + /// is controlled with the `UseIdTable` parameter. XYRouting } route_algo_e; + /// The directions in a 2D mesh network, mainly useful for indexing + /// multi-directional arrays. If a router has more than one local + /// port, the additional ports can be defined as `Eject+p`, where `p` + /// is the local port index typedef enum logic[2:0] { North = 3'd0, // y increasing East = 3'd1, // x increasing @@ -25,17 +51,274 @@ package floo_pkg; NumDirections } route_direction_e; - typedef enum { - RucheNorth = 'd5, - RucheEast = 'd6, - RucheSouth = 'd7, - RucheWest = 'd8 - } ruche_direction_e; - + /// The types of Reorder Buffers (RoBs) that can be used in the network interface typedef enum logic [1:0] { + /// The most performant but also most complex RoB, which supports reodering + /// of responses. This reorder buffer retains the out-of-order nature of + /// AXI transactions with different IDs. Supports multiple outstanding + /// transactions and bursts. NormalRoB, + /// Simpler FIFO-like RoB, which does not support reordering of responses with + /// the same AXI txnID. Transactions with different txnIDs are effectively + /// serialized. Supports multiple outstanding transactions but currently does + /// not support burst transactions. Mainly useful for B-responses which are + /// single transactions. SimpleRoB, + /// No RoB, which stalls transactions of the same ID going to different destinations + /// until the previous transaction is completed. This is option is useful if the + /// ordering of transactions is handled downstream, e.g. in the DMA by issuing AXI + /// transactions with different txnIDs. The overhead of this RoB is very low, since + /// it only requires counters for tracking the number of outstanding transactions of + /// each txnID. NoRoB } rob_type_e; + /// The types of AXI channels in single AXI network interfaces + typedef enum logic [2:0] { + AxiAw = 3'd0, + AxiW = 3'd1, + AxiAr = 3'd2, + AxiB = 3'd3, + AxiR = 3'd4, + NumAxiChannels = 3'd5 + } axi_ch_e; + + /// The types of AXI channels in narrow-wide AXI network interfaces + typedef enum logic [3:0] { + NarrowAw = 4'd0, + NarrowW = 4'd1, + NarrowAr = 4'd2, + WideAr = 4'd3, + NarrowB = 4'd4, + NarrowR = 4'd5, + WideB = 4'd6, + WideAw = 4'd7, + WideW = 4'd8, + WideR = 4'd9, + NumNWAxiChannels = 4'd10 + } nw_ch_e; + + /// The link types in the Floo network + typedef enum logic [1:0] { + /// Request link of `AR, AW, W` type + FlooReq = 2'd0, + /// Response link of `R, B` type + FlooRsp = 2'd1, + /// Additional wide link for narrow-wide AXI interfaces + FlooWide = 2'd2 + } floo_chan_e; + + /// Configuration for a bidirectional AXI interface + typedef struct packed { + /// Width of the address + int unsigned AddrWidth; + /// Width of the data + int unsigned DataWidth; + /// Width of the user signals + int unsigned UserWidth; + /// Width of the incoming txnID (i.e. the txnID of a manager port) + int unsigned InIdWidth; + /// Width of the outgoing txnID (i.e. the txnID of a subordinate port) + int unsigned OutIdWidth; + } axi_cfg_t; + + /// Configuration to pass routing information to the routers + /// as well as network interfaces + typedef struct packed { + /// The routing algorithm that is used + route_algo_e RouteAlgo; + /// Whether to calculate the destination ID based based on + /// the system address map or with XY offset values. + bit UseIdTable; + /// The offset of the X coordinate in request address, + /// if `!UseIdTable && RouteAlgo == XYRouting` + int unsigned XYAddrOffsetX; + /// The offset of the Y coordinate in request address + /// if `!UseIdTable && RouteAlgo == XYRouting` + int unsigned XYAddrOffsetY; + /// The offset of the id in the request address + /// if `!UseIdTable && RouteAlgo != XYRouting` + int unsigned IdAddrOffset; + /// The number of endpoints in the System Address Map, + /// Only used if `UseIdTable` is set + int unsigned NumSamRules; + /// The number of routes for every routing table, + /// Only used if `RouteAlgo == SourceRouting` + int unsigned NumRoutes; + } route_cfg_t; + + /// Configuration for the network interface (chimney) + typedef struct packed { + /// Whether an AXI subordinate is attached to the network interfaces + /// (e.g. a DRAM memory) + bit EnSbrPort; + /// Whether an AXI manager is attached to the network interfaces + /// (e.g. a host core) + bit EnMgrPort; + /// The number of both incoming and outgoing transactions that can be + /// handled by the network interface. + int unsigned MaxTxns; + /// The number of unique transaction IDs that can be issued by the network + /// to AXI subordinates downstream. By default the network interface issues + /// with a single txnID, effectively serializing incoming transactions from + /// all managers in the entire system. If multiple txnIDs are used, incoming + /// transactions with different TxnIDs _might_ not be serialized. This is results + /// in more complex logic in the network interfaces, but might be useful for + /// downstream AXI networks that can handle out-of-order transactions. + int unsigned MaxUniqueIds; + /// Number of outstanding transactions per txnID. Only used if + /// `RoBType == NormalRoB`. + int unsigned MaxTxnsPerId; + /// The type of Reoder Buffer (RoB) that is used for B responses. + rob_type_e BRoBType; + /// The depth of the RoB for B responses. Only used if `BRoBType != NoRoB`. + int unsigned BRoBSize; + /// The type of Reoder Buffer (RoB) that is used for R responses. + rob_type_e RRoBType; + /// The depth of the RoB for R responses. Only used if `RRoBType != NoRoB`. + int unsigned RRoBSize; + /// Whether to buffer incoming AXI requests at the network interface, + /// to ease timing closure. + bit CutAx; + /// Whether to buffer incoming links at the network interface, + bit CutRsp; + } chimney_cfg_t; + + /// The default configuration for the network interface + localparam chimney_cfg_t ChimneyDefaultCfg = '{ + EnSbrPort: 1'b1, + EnMgrPort: 1'b1, + MaxTxns: 32, + MaxUniqueIds: 1, + MaxTxnsPerId: 32, + BRoBType: NoRoB, + BRoBSize: 0, + RRoBType: NoRoB, + RRoBSize: 0, + CutAx: 1'b0, + CutRsp: 1'b0 + }; + + /// The default configuration for routing + localparam route_cfg_t RouteDefaultCfg = '{ + RouteAlgo: XYRouting, + UseIdTable: 1'b0, + XYAddrOffsetX: 0, + XYAddrOffsetY: 0, + IdAddrOffset: 0, + NumSamRules: 0, + NumRoutes: 0 + }; + + /// The AXI channel to link mapping in a single-AXI network interface + function automatic floo_chan_e axi_chan_mapping(axi_ch_e ch); + if (ch == AxiAw || ch == AxiW || ch == AxiAr) begin + return FlooReq; + end else begin + return FlooRsp; + end + endfunction + + /// The AXI channel to link mapping in a narrow-wide AXI network interface + function automatic floo_chan_e nw_chan_mapping(nw_ch_e ch); + if (ch == NarrowAw || ch == NarrowW || ch == NarrowAr || ch == WideAr) begin + return FlooReq; + end else if (ch == WideAw || ch == WideW || ch == WideR) begin + return FlooWide; + end else begin + return FlooRsp; + end + endfunction + + /// Swaps the direction of the AXI interface config + function automatic axi_cfg_t axi_cfg_swap_iw(axi_cfg_t cfg); + return '{ + AddrWidth: cfg.AddrWidth, + DataWidth: cfg.DataWidth, + UserWidth: cfg.UserWidth, + InIdWidth: cfg.OutIdWidth, + OutIdWidth: cfg.InIdWidth + }; + endfunction + + /// Helper function to enable/disable the subordinate and manager ports + /// for a chimney config. + function automatic chimney_cfg_t set_ports(chimney_cfg_t cfg, bit en_sbr, bit en_mgr); + cfg.EnSbrPort = en_sbr; + cfg.EnMgrPort = en_mgr; + return cfg; + endfunction + + /// Returns the number of bits of an AXI channel for a single-AXI config + function automatic int unsigned get_axi_chan_width(axi_cfg_t cfg, axi_ch_e ch); + case (ch) + AxiAw: return axi_pkg::aw_width(cfg.AddrWidth, cfg.InIdWidth, cfg.UserWidth); + AxiW: return axi_pkg::w_width(cfg.DataWidth, cfg.UserWidth); + AxiB: return axi_pkg::b_width(cfg.InIdWidth, cfg.UserWidth); + AxiAr: return axi_pkg::ar_width(cfg.AddrWidth, cfg.InIdWidth, cfg.UserWidth); + AxiR: return axi_pkg::r_width(cfg.DataWidth, cfg.InIdWidth, cfg.UserWidth); + default: $error("Invalid AXI channel"); + endcase + endfunction + + /// Returns the number of bits of an AXI channel for a narrow-wide AXI config + function automatic int unsigned get_nw_chan_width(axi_cfg_t cfg_n, axi_cfg_t cfg_w, nw_ch_e ch); + case (ch) + NarrowAw: return axi_pkg::aw_width(cfg_n.AddrWidth, cfg_n.InIdWidth, cfg_n.UserWidth); + NarrowW: return axi_pkg::w_width(cfg_n.DataWidth, cfg_n.UserWidth); + NarrowAr: return axi_pkg::ar_width(cfg_n.AddrWidth, cfg_n.InIdWidth, cfg_n.UserWidth); + NarrowB: return axi_pkg::b_width(cfg_n.InIdWidth, cfg_n.UserWidth); + NarrowR: return axi_pkg::r_width(cfg_n.DataWidth, cfg_n.InIdWidth, cfg_n.UserWidth); + WideAw: return axi_pkg::aw_width(cfg_w.AddrWidth, cfg_w.InIdWidth, cfg_w.UserWidth); + WideW: return axi_pkg::w_width(cfg_w.DataWidth, cfg_w.UserWidth); + WideR: return axi_pkg::r_width(cfg_w.DataWidth, cfg_w.InIdWidth, cfg_w.UserWidth); + WideAr: return axi_pkg::ar_width(cfg_w.AddrWidth, cfg_w.InIdWidth, cfg_w.UserWidth); + WideB: return axi_pkg::b_width(cfg_w.InIdWidth, cfg_w.UserWidth); + default: $error("Invalid AXI channel"); + endcase + endfunction + + /// Calculates the maximum payload bits required for a link, based on the single-AXI + /// channel mapping + function automatic int unsigned get_max_axi_payload_bits(axi_cfg_t cfg, floo_chan_e ch); + int unsigned max_payload_bits = 0; + for (int unsigned i = 0; i < NumAxiChannels; i++) begin + if (axi_chan_mapping(axi_ch_e'(i)) == ch) begin + if (get_axi_chan_width(cfg, axi_ch_e'(i)) > max_payload_bits) begin + max_payload_bits = get_axi_chan_width(cfg, axi_ch_e'(i)); + end + end + end + return max_payload_bits + 1; // +1 because we need at least one `rsvd` bit + endfunction + + /// Calculates the maximum payload bits required for a link, based on the narrow-wide AXI + /// channel mapping + function automatic int unsigned get_max_nw_payload_bits( + axi_cfg_t cfg_n, axi_cfg_t cfg_w, floo_chan_e ch); + int unsigned max_payload_bits = 0; + for (int unsigned i = 0; i < NumNWAxiChannels; i++) begin + if (nw_chan_mapping(nw_ch_e'(i)) == ch) begin + if (get_nw_chan_width(cfg_n, cfg_w, nw_ch_e'(i)) > max_payload_bits) begin + max_payload_bits = get_nw_chan_width(cfg_n, cfg_w, nw_ch_e'(i)); + end + end + end + return max_payload_bits + 1; // +1 because we need at least one `rsvd` bit + endfunction + + /// Calculates the number of unused (i.e. reserved) bits in a link for a specific + /// AXI channel payload in a single-AXI config + function automatic int unsigned get_axi_rsvd_bits(axi_cfg_t cfg, axi_ch_e ch); + return get_max_axi_payload_bits(cfg, axi_chan_mapping(ch)) - + get_axi_chan_width(cfg, ch); + endfunction + + /// Calculates the number of unused (i.e. reserved) bits in a link for a specific + /// AXI channel payload in a narrow-wide AXI config + function automatic int unsigned get_nw_rsvd_bits(axi_cfg_t cfg_n, axi_cfg_t cfg_w, nw_ch_e ch); + return get_max_nw_payload_bits(cfg_n, cfg_w, nw_chan_mapping(ch)) - + get_nw_chan_width(cfg_n, cfg_w, ch); + endfunction + endpackage diff --git a/hw/floo_rob.sv b/hw/floo_rob.sv index e99f65f1..85d900e4 100644 --- a/hw/floo_rob.sv +++ b/hw/floo_rob.sv @@ -15,7 +15,7 @@ module floo_rob #( /// metadata will be stored in normal FFs parameter bit OnlyMetaData = 1'b0, /// Size of the reorder buffer - parameter int unsigned ReorderBufferSize = 32'd64, + parameter int unsigned RoBSize = 32'd64, /// Data type of response to be reordered parameter type ax_len_t = logic, parameter type ax_id_t = logic, @@ -54,7 +54,7 @@ module floo_rob #( localparam int unsigned NumIds = 2**AxiIdWidth; typedef logic[AxiIdWidth-1:0] axi_id_t; typedef logic[$clog2(NumIds)-1:0] num_id_t; - typedef logic[ReorderBufferSize-1:0] rob_flag_t; + typedef logic[RoBSize-1:0] rob_flag_t; ///////////////////////// // Transaction Table // @@ -121,10 +121,10 @@ module floo_rob #( if (!OnlyMetaData) begin : gen_rob_sram tc_sram_impl #( - .NumWords (ReorderBufferSize), - .DataWidth ($bits(rsp_data_t)), - .NumPorts ( 1 ), - .impl_in_t ( sram_cfg_t ) + .NumWords ( RoBSize ), + .DataWidth ( $bits(rsp_data_t) ), + .NumPorts ( 1 ), + .impl_in_t ( sram_cfg_t ) ) i_reorder_buffer ( .clk_i ( clk_i ), .rst_ni ( rst_ni ), @@ -141,7 +141,7 @@ module floo_rob #( assign rob_rdata = '0; end - rsp_meta_t [ReorderBufferSize-1:0] rob_meta_q, rob_meta_d; + rsp_meta_t [RoBSize-1:0] rob_meta_q, rob_meta_d; rob_flag_t rob_valid_q, rob_valid_d; rob_flag_t rob_alloc_q, rob_alloc_d; rob_idx_t rob_free_space; @@ -152,11 +152,11 @@ module floo_rob #( `FF(rsp_out_valid_q, rsp_out_valid_d, '0) `FFL(rob_meta_q, rob_meta_d, rob_req && rob_wen, '0) - assign rob_next_free_idx = ReorderBufferSize - rob_free_space; + assign rob_next_free_idx = RoBSize - rob_free_space; lzc #( - .WIDTH ( ReorderBufferSize ), - .MODE ( 1'b1 ) + .WIDTH ( RoBSize ), + .MODE ( 1'b1 ) ) i_lzc ( .in_i ( rob_alloc_q ), .cnt_o ( rob_free_space ), @@ -174,8 +174,10 @@ module floo_rob #( // In the ID table, only the pointer to the first entry of a specific response // is stored. From there an offset is used to calculate the exact index in the // reorder buffer. - rob_idx_t rob_idx_offset_q, rob_idx_offset_d; - `FF(rob_idx_offset_q, rob_idx_offset_d, '0) + rob_idx_t [NumIds-1:0] read_rob_idx_offset_q, read_rob_idx_offset_d; + rob_idx_t [NumIds-1:0] write_rob_idx_offset_q, write_rob_idx_offset_d; + `FF(read_rob_idx_offset_q, read_rob_idx_offset_d, '0) + `FF(write_rob_idx_offset_q, write_rob_idx_offset_d, '0) // `is_last_rsp_in_rob` denotes if it is the last beat in a burst. // For B responses, this is always true @@ -218,7 +220,8 @@ module floo_rob #( rob_addr = '0; rob_wen = 1'b0; - rob_idx_offset_d = rob_idx_offset_q; + read_rob_idx_offset_d = read_rob_idx_offset_q; + write_rob_idx_offset_d = write_rob_idx_offset_q; ax_valid_o = 1'b0; ax_ready_o = 1'b0; @@ -240,7 +243,7 @@ module floo_rob #( rsp_valid_o = 1'b0; rob_req = 1'b1; rob_wen = 1'b0; - rob_addr = st_peek_rob_idx + rob_idx_offset_q; + rob_addr = st_peek_rob_idx + read_rob_idx_offset_q[st_rsp_out_id]; // If the peek ID is valid and there is a valid item in the RoB // for the current response, then we can release the response @@ -253,12 +256,12 @@ module floo_rob #( rob_alloc_d[rob_addr] = 1'b0; rob_addr++; // increment the offset counter - rob_idx_offset_d++; + read_rob_idx_offset_d[st_rsp_out_id]++; // If this was the last beat for this ID, increment the rsp_counter if (is_last_rsp_in_rob) begin st_rsp_pop = 1'b1; rsp_out_valid_d = 1'b0; - rob_idx_offset_d = '0; + read_rob_idx_offset_d[st_rsp_out_id] = '0; end end // If the peeked entry is invalid or the ROB is empty, we can't release @@ -270,11 +273,13 @@ module floo_rob #( RoBWrite: begin - rob_addr = rsp_rob_idx_i + rob_idx_offset_q; + rob_addr = rsp_rob_idx_i + write_rob_idx_offset_q[st_rsp_out_id]; // If the peeked ID has a valid entry and there is data in the RoB, // we can release the response from the RoB to make place for new requests - if (st_peek_valid && rob_valid_q[st_peek_rob_idx]) begin + if (st_peek_valid && rob_valid_q[st_peek_rob_idx + + read_rob_idx_offset_q[st_rob_peek_id_q]]) + begin rob_state_d = RoBRead; // Don't forward the current response, since we are releasing one from the RoB rsp_valid_o = 1'b0; @@ -299,14 +304,14 @@ module floo_rob #( if (rsp_ready_i) begin // Unset the allocated bit rob_alloc_d[rob_addr] = 1'b0; - rob_idx_offset_d++; + write_rob_idx_offset_d[st_rsp_out_id]++; // If this was the last beat of a response for this ID, increment the // response counter and clear the entry in the ID status table if // this was the very last response if (rsp_last_i) begin // Pop the transaction st_rsp_pop = 1'b1; - rob_idx_offset_d = '0; + write_rob_idx_offset_d[st_rsp_out_id] = '0; end end // Otherwise, the response is out of order and has to be stored in the @@ -319,7 +324,8 @@ module floo_rob #( rsp_ready_o = 1'b1; rob_valid_d[rob_addr] = 1'b1; rob_meta_d[rob_addr] = rob_meta; - rob_idx_offset_d = (rsp_last_i)? '0 : rob_idx_offset_q + 1; + write_rob_idx_offset_d[st_rsp_out_id] = (rsp_last_i)? + '0 : write_rob_idx_offset_q[st_rsp_out_id] + 1; end end end diff --git a/hw/floo_rob_wrapper.sv b/hw/floo_rob_wrapper.sv index 855c3358..9e435e0f 100644 --- a/hw/floo_rob_wrapper.sv +++ b/hw/floo_rob_wrapper.sv @@ -17,7 +17,7 @@ module floo_rob_wrapper /// metadata will be stored in normal FFs parameter bit OnlyMetaData = 1'b0, /// Size of the reorder buffer - parameter int unsigned ReorderBufferSize = 32'd64, + parameter int unsigned RoBSize = 32'd64, /// Data type of response to be reordered parameter type ax_len_t = logic, parameter type ax_id_t = logic, @@ -54,17 +54,17 @@ module floo_rob_wrapper if (RoBType == NormalRoB) begin : gen_normal_rob floo_rob #( - .ReorderBufferSize ( ReorderBufferSize ), - .MaxRoTxnsPerId ( MaxRoTxnsPerId ), - .OnlyMetaData ( OnlyMetaData ), - .ax_len_t ( ax_len_t ), - .ax_id_t ( ax_id_t ), - .rsp_chan_t ( rsp_chan_t ), - .rsp_data_t ( rsp_data_t ), - .rsp_meta_t ( rsp_meta_t ), - .rob_idx_t ( rob_idx_t ), - .dest_t ( dest_t ), - .sram_cfg_t ( sram_cfg_t ) + .RoBSize ( RoBSize ), + .MaxRoTxnsPerId ( MaxRoTxnsPerId ), + .OnlyMetaData ( OnlyMetaData ), + .ax_len_t ( ax_len_t ), + .ax_id_t ( ax_id_t ), + .rsp_chan_t ( rsp_chan_t ), + .rsp_data_t ( rsp_data_t ), + .rsp_meta_t ( rsp_meta_t ), + .rob_idx_t ( rob_idx_t ), + .dest_t ( dest_t ), + .sram_cfg_t ( sram_cfg_t ) ) i_rob ( .clk_i, .rst_ni, @@ -91,16 +91,15 @@ module floo_rob_wrapper end else if (RoBType == SimpleRoB) begin : gen_simpl_rob floo_simple_rob #( - .ReorderBufferSize ( ReorderBufferSize ), - .MaxRoTxnsPerId ( MaxRoTxnsPerId ), - .OnlyMetaData ( OnlyMetaData ), - .ax_len_t ( ax_len_t ), - .rsp_chan_t ( rsp_chan_t ), - .rsp_data_t ( rsp_data_t ), - .rsp_meta_t ( rsp_meta_t ), - .rob_idx_t ( rob_idx_t ), - .dest_t ( dest_t ), - .sram_cfg_t ( sram_cfg_t ) + .RoBSize ( RoBSize ), + .OnlyMetaData ( OnlyMetaData ), + .ax_len_t ( ax_len_t ), + .rsp_chan_t ( rsp_chan_t ), + .rsp_data_t ( rsp_data_t ), + .rsp_meta_t ( rsp_meta_t ), + .rob_idx_t ( rob_idx_t ), + .dest_t ( dest_t ), + .sram_cfg_t ( sram_cfg_t ) ) i_rob ( .clk_i, .rst_ni, diff --git a/hw/floo_route_comp.sv b/hw/floo_route_comp.sv index 4ce7aa1b..966f3c28 100644 --- a/hw/floo_route_comp.sv +++ b/hw/floo_route_comp.sv @@ -9,23 +9,9 @@ module floo_route_comp import floo_pkg::*; #( - /// The type of routing algorithms to use - parameter route_algo_e RouteAlgo = IdTable, - /// Whether to use a routing table with address decoder - /// In case of XY Routing or the coordinates should be - /// directly read from the request address - parameter bit UseIdTable = 1'b1, - /// The offset bit to read the X coordinate from - parameter int unsigned XYAddrOffsetX = 0, - /// The offset bit to read the Y coordinate from - parameter int unsigned XYAddrOffsetY = 0, - /// The offset bit to read the ID from - parameter int unsigned IdAddrOffset = 0, - /// The number of possible rules - parameter int unsigned NumAddrRules = 0, - /// The number of possible routes - parameter int unsigned NumRoutes = 0, - /// The type of the coordinates or IDs + /// The route config + parameter floo_pkg::route_cfg_t RouteCfg = '0, + parameter bit UseIdTable = RouteCfg.UseIdTable, parameter type id_t = logic, /// The type of the address parameter type addr_t = logic, @@ -38,8 +24,8 @@ module floo_route_comp input logic rst_ni, input id_t id_i, input addr_t addr_i, - input addr_rule_t [NumAddrRules-1:0] addr_map_i, - input route_t [NumRoutes-1:0] route_table_i, + input addr_rule_t [RouteCfg.NumSamRules-1:0] addr_map_i, + input route_t [RouteCfg.NumRoutes-1:0] route_table_i, output route_t route_o, output id_t id_o ); @@ -51,9 +37,9 @@ module floo_route_comp // The reason for that is that a request destination is given by a physical address, while the // response destination is given by the ID of the source. if (UseIdTable && - ((RouteAlgo == IdTable) || - (RouteAlgo == XYRouting) || - (RouteAlgo == SourceRouting))) + ((RouteCfg.RouteAlgo == IdTable) || + (RouteCfg.RouteAlgo == XYRouting) || + (RouteCfg.RouteAlgo == SourceRouting))) begin : gen_table_routing logic dec_error; @@ -62,11 +48,11 @@ module floo_route_comp localparam int unsigned MaxPossibleId = 1 << $bits(id_o); addr_decode #( - .NoIndices ( MaxPossibleId ), - .NoRules ( NumAddrRules ), - .addr_t ( addr_t ), - .rule_t ( addr_rule_t ), - .idx_t ( id_t ) + .NoIndices ( MaxPossibleId ), + .NoRules ( RouteCfg.NumSamRules ), + .addr_t ( addr_t ), + .rule_t ( addr_rule_t ), + .idx_t ( id_t ) ) i_addr_dst_decode ( .addr_i ( addr_i ), .addr_map_i ( addr_map_i ), @@ -78,18 +64,18 @@ module floo_route_comp ); `ASSERT(DecodeError, !dec_error) - end else if (RouteAlgo == XYRouting) begin : gen_xy_bits_routing + end else if (RouteCfg.RouteAlgo == XYRouting) begin : gen_xy_bits_routing assign id_o.port_id = '0; - assign id_o.x = addr_i[XYAddrOffsetX +: $bits(id_o.x)]; - assign id_o.y = addr_i[XYAddrOffsetY +: $bits(id_o.y)]; - end else if (RouteAlgo == IdTable) begin : gen_id_bits_routing - assign id_o = addr_i[IdAddrOffset +: $bits(id_o)]; - end else if (RouteAlgo == SourceRouting) begin : gen_source_routing + assign id_o.x = addr_i[RouteCfg.XYAddrOffsetX +: $bits(id_o.x)]; + assign id_o.y = addr_i[RouteCfg.XYAddrOffsetY +: $bits(id_o.y)]; + end else if (RouteCfg.RouteAlgo == IdTable) begin : gen_id_bits_routing + assign id_o = addr_i[RouteCfg.IdAddrOffset +: $bits(id_o)]; + end else if (RouteCfg.RouteAlgo == SourceRouting) begin : gen_source_routing // Nothing to do here end else begin : gen_error $fatal(1, "Routing algorithm not implemented"); end - if (RouteAlgo == SourceRouting) begin : gen_route + if (RouteCfg.RouteAlgo == SourceRouting) begin : gen_route assign route_o = (UseIdTable)? route_table_i[id_o] : route_table_i[id_i]; end else begin : gen_no_route assign route_o = '0; diff --git a/hw/floo_route_select.sv b/hw/floo_route_select.sv index ac1d342f..d8f5557b 100644 --- a/hw/floo_route_select.sv +++ b/hw/floo_route_select.sv @@ -40,19 +40,7 @@ module floo_route_select logic [NumRoutes-1:0] route_sel; logic [RouteSelWidth-1:0] route_sel_id; - if (RouteAlgo == IdIsPort) begin : gen_id_is_port - // Routing assuming the ID is the port to be taken - - assign channel_o = channel_i; - - // One-hot encoding of the decoded route - always_comb begin : proc_route_sel - route_sel_id = channel_i.hdr.dst_id; - route_sel = '0; - route_sel[channel_i.hdr.dst_id] = 1'b1; - end - - end else if (RouteAlgo == IdTable) begin : gen_id_table +if (RouteAlgo == IdTable) begin : gen_id_table // Routing based on an ID table passed into the router (TBD parameter or signal) // Assumes an ID field present in the flit_t diff --git a/hw/floo_router.sv b/hw/floo_router.sv index 1a6ffdab..449f590f 100644 --- a/hw/floo_router.sv +++ b/hw/floo_router.sv @@ -7,13 +7,15 @@ `include "common_cells/assertions.svh" /// A simple router with configurable number of ports, physical and virtual channels, and input/output buffers -module floo_router import floo_pkg::*; #( +module floo_router + import floo_pkg::*; +#( parameter int unsigned NumRoutes = 0, parameter int unsigned NumVirtChannels = 0, parameter int unsigned NumPhysChannels = 1, parameter type flit_t = logic, - parameter int unsigned ChannelFifoDepth = 0, - parameter int unsigned OutputFifoDepth = 0, + parameter int unsigned InFifoDepth = 0, + parameter int unsigned OutFifoDepth = 0, parameter route_algo_e RouteAlgo = IdTable, /// Used for ID-based and XY routing parameter int unsigned IdWidth = 0, @@ -65,8 +67,8 @@ module floo_router import floo_pkg::*; #( (* ungroup *) stream_fifo_optimal_wrap #( - .Depth ( ChannelFifoDepth ), - .type_t ( flit_t ) + .Depth ( InFifoDepth ), + .type_t ( flit_t ) ) i_stream_fifo ( .clk_i ( clk_i ), .rst_ni ( rst_ni ), @@ -169,11 +171,11 @@ module floo_router import floo_pkg::*; #( .data_o ( out_data [out_route][v_chan] ) ); - if (OutputFifoDepth > 0) begin : gen_out_fifo + if (OutFifoDepth > 0) begin : gen_out_fifo (* ungroup *) stream_fifo_optimal_wrap #( - .Depth ( OutputFifoDepth ), - .type_t ( flit_t ) + .Depth ( OutFifoDepth ), + .type_t ( flit_t ) ) i_stream_fifo ( .clk_i ( clk_i ), .rst_ni ( rst_ni ), diff --git a/hw/floo_simple_rob.sv b/hw/floo_simple_rob.sv index 19906f73..2db501da 100644 --- a/hw/floo_simple_rob.sv +++ b/hw/floo_simple_rob.sv @@ -8,26 +8,25 @@ `include "common_cells/assertions.svh" /// A simplistic low-complexity Reorder Buffer, similar to a FIFO +/// WARNING: The implementation has a known bug for burst support, +/// and is therefore only advised to be used for B responses. module floo_simple_rob #( - /// Maximum number of transactions in flight per ID which *require* reordering - /// Not used in the simple RoB - parameter int unsigned MaxRoTxnsPerId = 32'd32, /// If the response only consists of small metadata i.e. B channel /// In this case no SRAM will be instantied and the response will be /// metadata will be stored in SCMs parameter bit OnlyMetaData = 1'b0, /// Size of the reorder buffer - parameter int unsigned ReorderBufferSize = 32'd64, + parameter int unsigned RoBSize = 32'd64, /// Data type of response to be reordered parameter type ax_len_t = logic, parameter type rsp_chan_t = logic, parameter type rsp_data_t = logic, parameter type rsp_meta_t = logic, - parameter type rob_idx_t = logic[$clog2(ReorderBufferSize)-1:0], + parameter type rob_idx_t = logic[$clog2(RoBSize)-1:0], parameter type dest_t = logic, parameter type sram_cfg_t = logic, // Dependent parameters, DO NOT OVERRIDE! - localparam type rob_flag_t = logic[ReorderBufferSize-1:0] + localparam type rob_flag_t = logic[RoBSize-1:0] ) ( input logic clk_i, input logic rst_ni, @@ -53,9 +52,9 @@ module floo_simple_rob #( rob_idx_t read_pointer_q, read_pointer_d; rob_idx_t write_pointer_q, write_pointer_d; - logic [$clog2(ReorderBufferSize):0] status_cnt_q, status_cnt_d; - logic [$clog2(ReorderBufferSize):0] free_entries; - rsp_meta_t [ReorderBufferSize-1:0] rob_meta_q, rob_meta_d; + logic [$clog2(RoBSize):0] status_cnt_q, status_cnt_d; + logic [$clog2(RoBSize):0] free_entries; + rsp_meta_t [RoBSize-1:0] rob_meta_q, rob_meta_d; rsp_meta_t rob_meta; rob_idx_t rsp_burst_cnt_q, rsp_burst_cnt_d; rob_flag_t rob_valid_q, rob_valid_d; @@ -78,10 +77,10 @@ module floo_simple_rob #( if (!OnlyMetaData) begin : gen_rob_sram tc_sram_impl #( - .NumWords (ReorderBufferSize), - .DataWidth ($bits(rsp_data_t)), - .NumPorts ( 1 ), - .impl_in_t ( sram_cfg_t ) + .NumWords ( RoBSize ), + .DataWidth ( $bits(rsp_data_t) ), + .NumPorts ( 1 ), + .impl_in_t ( sram_cfg_t ) ) i_reorder_buffer ( .clk_i ( clk_i ), .rst_ni ( rst_ni ), @@ -99,7 +98,7 @@ module floo_simple_rob #( end - assign free_entries = ReorderBufferSize - status_cnt_q; + assign free_entries = RoBSize - status_cnt_q; assign ax_len = (OnlyMetaData)? 1 : ax_len_i + 1'b1; always_comb begin @@ -130,8 +129,8 @@ module floo_simple_rob #( if (ax_ready_i) begin ax_ready_o = 1'b1; // Increment write and status counter - if (write_pointer_q + ax_len >= ReorderBufferSize) begin - write_pointer_d = write_pointer_q + ax_len - ReorderBufferSize; + if (write_pointer_q + ax_len >= RoBSize) begin + write_pointer_d = write_pointer_q + ax_len - RoBSize; end else begin write_pointer_d = write_pointer_q + ax_len; end @@ -150,6 +149,11 @@ module floo_simple_rob #( rob_addr = rsp_rob_idx_i + rsp_burst_cnt_q; rob_meta_d[rob_addr] = rob_meta; rob_valid_d[rob_addr] = 1'b1; + // WARNING: This implementation does not support interleaved + // bursts with different IDs. Each burst would need its own + // `rsp_burst_cnt` counter which is currently not implemented. + // The way to implement this would be to increment `rsp_rob_idx_i` + // at the endpoint which issues the responses. rsp_burst_cnt_d = (rsp_last_i)? '0 : rsp_burst_cnt_q + 1'b1; end @@ -165,8 +169,8 @@ module floo_simple_rob #( rsp_out_valid_d = 1'b1; if (rsp_valid_o && rsp_ready_i) begin rob_valid_d[read_pointer_q] = 1'b0; - if (read_pointer_q + 1'b1 >= ReorderBufferSize) begin - read_pointer_d = read_pointer_q + 1'b1 - ReorderBufferSize; + if (read_pointer_q + 1'b1 >= RoBSize) begin + read_pointer_d = read_pointer_q + 1'b1 - RoBSize; end else begin read_pointer_d = read_pointer_q + 1'b1; end @@ -209,4 +213,7 @@ module floo_simple_rob #( `FF(rob_state_q, rob_state_d, RoBWrite) `FF(rsp_out_valid_q, rsp_out_valid_d, '0) + // This module currently does not handle interleaved burst responses correctly + `ASSERT(NoBurstSupport, rsp_last_i == 1'b1) + endmodule diff --git a/hw/floo_vc_axi_pkg.sv b/hw/floo_vc_axi_pkg.sv deleted file mode 100644 index cf960b1e..00000000 --- a/hw/floo_vc_axi_pkg.sv +++ /dev/null @@ -1,184 +0,0 @@ -// Copyright 2022 ETH Zurich and University of Bologna. -// Solderpad Hardware License, Version 0.51, see LICENSE for details. -// SPDX-License-Identifier: SHL-0.51 -// -// This file is auto-generated. Do not edit! Edit the template file instead - -`include "axi/typedef.svh" - -package floo_vc_axi_pkg; - - import floo_pkg::*; - - //////////////////////// - // AXI Parameters // - //////////////////////// - - typedef enum logic [2:0] { - AxiAw = 3'd0, - AxiW = 3'd1, - AxiAr = 3'd2, - AxiB = 3'd3, - AxiR = 3'd4, - NumAxiChannels = 3'd5 - } axi_ch_e; - - - localparam int unsigned AxiInAddrWidth = 32; - localparam int unsigned AxiInDataWidth = 64; - localparam int unsigned AxiInIdWidth = 3; - localparam int unsigned AxiInUserWidth = 1; - - - localparam int unsigned AxiOutAddrWidth = 32; - localparam int unsigned AxiOutDataWidth = 64; - localparam int unsigned AxiOutIdWidth = 3; - localparam int unsigned AxiOutUserWidth = 1; - - - typedef logic [31:0] axi_in_addr_t; - typedef logic [63:0] axi_in_data_t; - typedef logic [7:0] axi_in_strb_t; - typedef logic [2:0] axi_in_id_t; - typedef logic [0:0] axi_in_user_t; - `AXI_TYPEDEF_ALL_CT(axi_in, axi_in_req_t, axi_in_rsp_t, axi_in_addr_t, axi_in_id_t, axi_in_data_t, - axi_in_strb_t, axi_in_user_t) - - - typedef logic [31:0] axi_out_addr_t; - typedef logic [63:0] axi_out_data_t; - typedef logic [7:0] axi_out_strb_t; - typedef logic [2:0] axi_out_id_t; - typedef logic [0:0] axi_out_user_t; - `AXI_TYPEDEF_ALL_CT(axi_out, axi_out_req_t, axi_out_rsp_t, axi_out_addr_t, axi_out_id_t, - axi_out_data_t, axi_out_strb_t, axi_out_user_t) - - - - ///////////////////////// - // Header Typedefs // - ///////////////////////// - - localparam route_algo_e RouteAlgo = XYRouting; - localparam bit UseIdTable = 1'b0; - localparam int unsigned NumXBits = 3; - localparam int unsigned NumYBits = 3; - localparam int unsigned XYAddrOffsetX = 16; - localparam int unsigned XYAddrOffsetY = 19; - localparam int unsigned IdAddrOffset = 0; - - - typedef logic [0:0] rob_idx_t; - typedef logic [1:0] port_id_t; - typedef logic [2:0] x_bits_t; - typedef logic [2:0] y_bits_t; - typedef struct packed { - x_bits_t x; - y_bits_t y; - port_id_t port_id; - } id_t; - - typedef logic route_t; - typedef id_t dst_t; - typedef logic [2:0] vc_id_t; - - - typedef struct packed { - logic rob_req; - rob_idx_t rob_idx; - dst_t dst_id; - id_t src_id; - logic last; - logic atop; - axi_ch_e axi_ch; - vc_id_t vc_id; - route_direction_e lookahead; - } hdr_t; - - - - //////////////////////// - // Flits Typedefs // - //////////////////////// - - typedef struct packed { - hdr_t hdr; - axi_in_aw_chan_t aw; - logic [2:0] rsvd; - } floo_axi_aw_flit_t; - - typedef struct packed { - hdr_t hdr; - axi_in_w_chan_t w; - } floo_axi_w_flit_t; - - typedef struct packed { - hdr_t hdr; - axi_in_b_chan_t b; - logic [64:0] rsvd; - } floo_axi_b_flit_t; - - typedef struct packed { - hdr_t hdr; - axi_in_ar_chan_t ar; - logic [8:0] rsvd; - } floo_axi_ar_flit_t; - - typedef struct packed { - hdr_t hdr; - axi_in_r_chan_t r; - } floo_axi_r_flit_t; - - typedef logic [73:0] floo_req_payload_t; - typedef struct packed { - hdr_t hdr; - floo_req_payload_t payload; - } floo_req_generic_flit_t; - - typedef logic [70:0] floo_rsp_payload_t; - typedef struct packed { - hdr_t hdr; - floo_rsp_payload_t payload; - } floo_rsp_generic_flit_t; - - - - ////////////////////////// - // Channel Typedefs // - ////////////////////////// - - typedef union packed { - floo_axi_aw_flit_t axi_aw; - floo_axi_w_flit_t axi_w; - floo_axi_ar_flit_t axi_ar; - floo_req_generic_flit_t generic; - } floo_req_chan_t; - - typedef union packed { - floo_axi_b_flit_t axi_b; - floo_axi_r_flit_t axi_r; - floo_rsp_generic_flit_t generic; - } floo_rsp_chan_t; - - - - /////////////////////// - // Link Typedefs // - /////////////////////// - - typedef struct packed { - logic valid; - logic credit_v; - vc_id_t credit_id; - floo_req_chan_t req; - } floo_vc_req_t; - - typedef struct packed { - logic valid; - logic credit_v; - vc_id_t credit_id; - floo_rsp_chan_t rsp; - } floo_vc_rsp_t; - - -endpackage diff --git a/hw/floo_vc_narrow_wide_pkg.sv b/hw/floo_vc_narrow_wide_pkg.sv deleted file mode 100644 index 56233d68..00000000 --- a/hw/floo_vc_narrow_wide_pkg.sv +++ /dev/null @@ -1,273 +0,0 @@ -// Copyright 2022 ETH Zurich and University of Bologna. -// Solderpad Hardware License, Version 0.51, see LICENSE for details. -// SPDX-License-Identifier: SHL-0.51 -// -// This file is auto-generated. Do not edit! Edit the template file instead - -`include "axi/typedef.svh" - -package floo_vc_narrow_wide_pkg; - - import floo_pkg::*; - - //////////////////////// - // AXI Parameters // - //////////////////////// - - typedef enum logic [3:0] { - NarrowAw = 4'd0, - NarrowW = 4'd1, - NarrowAr = 4'd2, - WideAr = 4'd3, - NarrowB = 4'd4, - NarrowR = 4'd5, - WideB = 4'd6, - WideAw = 4'd7, - WideW = 4'd8, - WideR = 4'd9, - NumAxiChannels = 4'd10 - } axi_ch_e; - - - localparam int unsigned AxiNarrowInAddrWidth = 48; - localparam int unsigned AxiNarrowInDataWidth = 64; - localparam int unsigned AxiNarrowInIdWidth = 4; - localparam int unsigned AxiNarrowInUserWidth = 1; - - - localparam int unsigned AxiNarrowOutAddrWidth = 48; - localparam int unsigned AxiNarrowOutDataWidth = 64; - localparam int unsigned AxiNarrowOutIdWidth = 2; - localparam int unsigned AxiNarrowOutUserWidth = 1; - - - localparam int unsigned AxiWideInAddrWidth = 48; - localparam int unsigned AxiWideInDataWidth = 512; - localparam int unsigned AxiWideInIdWidth = 3; - localparam int unsigned AxiWideInUserWidth = 1; - - - localparam int unsigned AxiWideOutAddrWidth = 48; - localparam int unsigned AxiWideOutDataWidth = 512; - localparam int unsigned AxiWideOutIdWidth = 1; - localparam int unsigned AxiWideOutUserWidth = 1; - - - typedef logic [47:0] axi_narrow_in_addr_t; - typedef logic [63:0] axi_narrow_in_data_t; - typedef logic [7:0] axi_narrow_in_strb_t; - typedef logic [3:0] axi_narrow_in_id_t; - typedef logic [0:0] axi_narrow_in_user_t; - `AXI_TYPEDEF_ALL_CT(axi_narrow_in, axi_narrow_in_req_t, axi_narrow_in_rsp_t, axi_narrow_in_addr_t, - axi_narrow_in_id_t, axi_narrow_in_data_t, axi_narrow_in_strb_t, - axi_narrow_in_user_t) - - - typedef logic [47:0] axi_narrow_out_addr_t; - typedef logic [63:0] axi_narrow_out_data_t; - typedef logic [7:0] axi_narrow_out_strb_t; - typedef logic [1:0] axi_narrow_out_id_t; - typedef logic [0:0] axi_narrow_out_user_t; - `AXI_TYPEDEF_ALL_CT(axi_narrow_out, axi_narrow_out_req_t, axi_narrow_out_rsp_t, - axi_narrow_out_addr_t, axi_narrow_out_id_t, axi_narrow_out_data_t, - axi_narrow_out_strb_t, axi_narrow_out_user_t) - - - typedef logic [47:0] axi_wide_in_addr_t; - typedef logic [511:0] axi_wide_in_data_t; - typedef logic [63:0] axi_wide_in_strb_t; - typedef logic [2:0] axi_wide_in_id_t; - typedef logic [0:0] axi_wide_in_user_t; - `AXI_TYPEDEF_ALL_CT(axi_wide_in, axi_wide_in_req_t, axi_wide_in_rsp_t, axi_wide_in_addr_t, - axi_wide_in_id_t, axi_wide_in_data_t, axi_wide_in_strb_t, axi_wide_in_user_t) - - - typedef logic [47:0] axi_wide_out_addr_t; - typedef logic [511:0] axi_wide_out_data_t; - typedef logic [63:0] axi_wide_out_strb_t; - typedef logic [0:0] axi_wide_out_id_t; - typedef logic [0:0] axi_wide_out_user_t; - `AXI_TYPEDEF_ALL_CT(axi_wide_out, axi_wide_out_req_t, axi_wide_out_rsp_t, axi_wide_out_addr_t, - axi_wide_out_id_t, axi_wide_out_data_t, axi_wide_out_strb_t, - axi_wide_out_user_t) - - - - ///////////////////////// - // Header Typedefs // - ///////////////////////// - - localparam route_algo_e RouteAlgo = XYRouting; - localparam bit UseIdTable = 1'b0; - localparam int unsigned NumXBits = 3; - localparam int unsigned NumYBits = 3; - localparam int unsigned XYAddrOffsetX = 16; - localparam int unsigned XYAddrOffsetY = 19; - localparam int unsigned IdAddrOffset = 0; - - - typedef logic [0:0] rob_idx_t; - typedef logic [1:0] port_id_t; - typedef logic [2:0] x_bits_t; - typedef logic [2:0] y_bits_t; - typedef struct packed { - x_bits_t x; - y_bits_t y; - port_id_t port_id; - } id_t; - - typedef logic route_t; - typedef id_t dst_t; - typedef logic [2:0] vc_id_t; - - - typedef struct packed { - logic rob_req; - rob_idx_t rob_idx; - dst_t dst_id; - id_t src_id; - logic last; - logic atop; - axi_ch_e axi_ch; - vc_id_t vc_id; - route_direction_e lookahead; - } hdr_t; - - - - //////////////////////// - // Flits Typedefs // - //////////////////////// - - typedef struct packed { - hdr_t hdr; - axi_narrow_in_aw_chan_t aw; - } floo_narrow_aw_flit_t; - - typedef struct packed { - hdr_t hdr; - axi_narrow_in_w_chan_t w; - logic [13:0] rsvd; - } floo_narrow_w_flit_t; - - typedef struct packed { - hdr_t hdr; - axi_narrow_in_b_chan_t b; - logic [64:0] rsvd; - } floo_narrow_b_flit_t; - - typedef struct packed { - hdr_t hdr; - axi_narrow_in_ar_chan_t ar; - logic [5:0] rsvd; - } floo_narrow_ar_flit_t; - - typedef struct packed { - hdr_t hdr; - axi_narrow_in_r_chan_t r; - } floo_narrow_r_flit_t; - - typedef struct packed { - hdr_t hdr; - axi_wide_in_aw_chan_t aw; - logic [490:0] rsvd; - } floo_wide_aw_flit_t; - - typedef struct packed { - hdr_t hdr; - axi_wide_in_w_chan_t w; - } floo_wide_w_flit_t; - - typedef struct packed { - hdr_t hdr; - axi_wide_in_b_chan_t b; - logic [65:0] rsvd; - } floo_wide_b_flit_t; - - typedef struct packed { - hdr_t hdr; - axi_wide_in_ar_chan_t ar; - logic [6:0] rsvd; - } floo_wide_ar_flit_t; - - typedef struct packed { - hdr_t hdr; - axi_wide_in_r_chan_t r; - logic [58:0] rsvd; - } floo_wide_r_flit_t; - - typedef logic [87:0] floo_req_payload_t; - typedef struct packed { - hdr_t hdr; - floo_req_payload_t payload; - } floo_req_generic_flit_t; - - typedef logic [71:0] floo_rsp_payload_t; - typedef struct packed { - hdr_t hdr; - floo_rsp_payload_t payload; - } floo_rsp_generic_flit_t; - - typedef logic [577:0] floo_wide_payload_t; - typedef struct packed { - hdr_t hdr; - floo_wide_payload_t payload; - } floo_wide_generic_flit_t; - - - - ////////////////////////// - // Channel Typedefs // - ////////////////////////// - - typedef union packed { - floo_narrow_aw_flit_t narrow_aw; - floo_narrow_w_flit_t narrow_w; - floo_narrow_ar_flit_t narrow_ar; - floo_wide_ar_flit_t wide_ar; - floo_req_generic_flit_t generic; - } floo_req_chan_t; - - typedef union packed { - floo_narrow_b_flit_t narrow_b; - floo_narrow_r_flit_t narrow_r; - floo_wide_b_flit_t wide_b; - floo_rsp_generic_flit_t generic; - } floo_rsp_chan_t; - - typedef union packed { - floo_wide_aw_flit_t wide_aw; - floo_wide_w_flit_t wide_w; - floo_wide_r_flit_t wide_r; - floo_wide_generic_flit_t generic; - } floo_wide_chan_t; - - - - /////////////////////// - // Link Typedefs // - /////////////////////// - - typedef struct packed { - logic valid; - logic credit_v; - vc_id_t credit_id; - floo_req_chan_t req; - } floo_vc_req_t; - - typedef struct packed { - logic valid; - logic credit_v; - vc_id_t credit_id; - floo_rsp_chan_t rsp; - } floo_vc_rsp_t; - - typedef struct packed { - logic valid; - logic credit_v; - vc_id_t credit_id; - floo_wide_chan_t wide; - } floo_vc_wide_t; - - -endpackage diff --git a/hw/include/floo_noc/typedef.svh b/hw/include/floo_noc/typedef.svh index 7c06e548..c7ca0fb9 100644 --- a/hw/include/floo_noc/typedef.svh +++ b/hw/include/floo_noc/typedef.svh @@ -1,36 +1,405 @@ // Copyright 2022 ETH Zurich and University of Bologna. // Solderpad Hardware License, Version 0.51, see LICENSE for details. // SPDX-License-Identifier: SHL-0.51 -// -// Michael Rogenmoser +// Authors: +// - Tim Fischer +// - Michael Rogenmoser + +// Macros to define the FlooNoC data types `ifndef FLOO_NOC_TYPEDEF_SVH_ `define FLOO_NOC_TYPEDEF_SVH_ -`define FLOO_NOC_TYPEDEF_FLIT_T(flit_t, FlitWidth) \ - typedef struct packed { \ - logic [FlitWidth-1:0] data; \ - logic last; \ - } flit_t; - -`define FLOO_NOC_TYPEDEF_ID_FLIT_T(flit_t, IdWidth, FlitWidth) \ - typedef struct packed { \ - logic [FlitWidth-1:0] data; \ - logic [IdWidth-1:0] dst_id; \ - logic last; \ - } flit_t; - -`define FLOO_NOC_TYPEDEF_XY_ID_T(xy_id_t, NumX, NumY) \ - typedef struct packed { \ - logic [$clog2(NumX)-1:0] x; \ - logic [$clog2(NumY)-1:0] y; \ - } xy_id_t; - -`define FLOO_NOC_TYPEDEF_XY_FLIT_T(flit_t, xy_id_t, FlitWidth) \ - typedef struct packed { \ - logic [FlitWidth-1:0] data; \ - xy_id_t dst_id; \ - logic last; \ - } flit_t; +//////////////////////////////////////////////////////////////////////////////////////////////////// +// Node ID for XY coordinates +// +// Arguments: +// - name: Name of the ID struct type +// - x_bits_t: Type of the X coordinate +// - y_bits_t: Type of the Y coordinate +// - port_id_t: Type of the port ID +// +// Usage Example: +// typedef logic [$clog2(NumX)-1:0] x_bits_t; +// typedef logic [$clog2(NumY)-1:0] y_bits_t; +// typedef logic port_id_t; +// `FLOO_TYPEDEF_XY_NODE_ID_T(id_t, x_bits_t, y_bits_t, port_id_t) +`define FLOO_TYPEDEF_XY_NODE_ID_T(name, x_bits_t, y_bits_t, p_bits_t) \ + typedef struct packed { \ + x_bits_t x; \ + y_bits_t y; \ + p_bits_t port_id; \ + } name; + +//////////////////////////////////////////////////////////////////////////////////////////////////// +// Header definition +// +// Arguments: +// - hdr_t: Name of the header struct type +// - dst_t: Type of the destination ID +// - src_t: Type of the source ID (Usually `dst_t`) +// - ch_t: Identifier type for the payload +// - rob_idx_t: Type of the RoB index +// +// Usage Example: +// `FLOO_TYPEDEF_XY_NODE_ID_T(id_t, ...) +// `FLOO_TYPEDEF_HDR_T(hdr_t, id_t, id_t, floo_pkg::axi_ch_e, logic) +// +// For `SourceRouting`: +// `FLOO_TYPEDEF_HDR_T(hdr_t, route_t, id_t, floo_pkg::axi_ch_e, logic) +`define FLOO_TYPEDEF_HDR_T(hdr_t, dst_t, src_t, ch_t, rob_idx_t) \ + typedef struct packed { \ + logic rob_req; \ + rob_idx_t rob_idx; \ + dst_t dst_id; \ + src_t src_id; \ + logic last; \ + logic atop; \ + ch_t axi_ch; \ + } hdr_t; + +//////////////////////////////////////////////////////////////////////////////////////////////////// +// Header definition for virtual channel and lookahead routing +// +// Arguments: +// - hdr_t: Name of the header struct type +// - dst_t: Type of the destination ID +// - src_t: Type of the source ID (Usually `dst_t`) +// - ch_t: Identifier type for the payload +// - rob_idx_t: Type of the RoB index +// - vc_id_t: Type of the virtual channel ID +// +// Usage Example: +// `FLOO_TYPEDEF_XY_NODE_ID_T(id_t, ...) +// `FLOO_TYPEDEF_HDR_T(hdr_t, id_t, id_t, floo_pkg::axi_ch_e, logic) +// +// For `SourceRouting`: +// `FLOO_TYPEDEF_HDR_T(hdr_t, route_t, id_t, floo_pkg::axi_ch_e, logic) +`define FLOO_TYPEDEF_VC_HDR_T(hdr_t, dst_t, src_t, ch_t, rob_idx_t, vc_id_t) \ + typedef struct packed { \ + logic rob_req; \ + rob_idx_t rob_idx; \ + dst_t dst_id; \ + src_t src_id; \ + logic last; \ + logic atop; \ + ch_t axi_ch; \ + vc_id_t vc_id; \ + floo_pkg::route_direction_e lookahead; \ + } hdr_t; + +//////////////////////////////////////////////////////////////////////////////////////////////////// +// Flit definition of a specific AXI Channel. +// +// Arguments: +// - name: Name of the flit type +// - hdr_t: Type of the header +// - payload_t: Type of the payload +// - rsvd_bits: Number of reserved bits that are not used by the payload +// +// Usage Example: +// `FLOO_TYPEDEF_HDR_T(hdr_t, ...) +// `FLOO_TYPEDEF_FLIT_T(my_payload, hdr_t, my_payload_t, 13) +`define FLOO_TYPEDEF_FLIT_T(name, hdr_t, payload_t, rsvd_bits) \ + typedef struct packed { \ + hdr_t hdr; \ + payload_t payload; \ + logic [rsvd_bits-1:0] rsvd; \ + } floo_``name``_flit_t; + +//////////////////////////////////////////////////////////////////////////////////////////////////// +// Flit definition of a generic flit. +// +// Arguments: +// - name: Name of the flit type +// - hdr_t: Type of the header +// - payload_t: Type of the payload +// +// Usage Example: +// `FLOO_TYPEDEF_HDR_T(hdr_t, ...) +// `FLOO_TYPEDEF_GENERIC_FLIT_T(req, hdr_t, logic [63:0]) +`define FLOO_TYPEDEF_GENERIC_FLIT_T(name, hdr_t, payload_t) \ + typedef payload_t floo_``name``_payload_t ; \ + typedef struct packed { \ + hdr_t hdr; \ + floo_``name``_payload_t payload; \ + } floo_``name``_generic_flit_t; + +//////////////////////////////////////////////////////////////////////////////////////////////////// +// Defines AXI channel types based on a `floo_pkg::AxiCfg`. +// Both incoming and outgoing channel are defined with the `name_in` and `name_out` suffix +// +// Arguments: +// - name: Prefix for the AXI channel types +// - cfg: AxiCfg struct type defining AddrWidth, DataWidth, User Width and +// IdWidth for in and out direction (see `floo_pkg::AxiCfg`) +// +// Usage Example: +// localparam floo_pkg::axi_cfg_t AxiCfg = '{ +// AddrWidth: 32, +// DataWidth: 64, +// UserWidth: 1, +// InIdWidth: 4, +// OutIdWidth: 2 +// }; +// `FLOO_TYPEDEF_AXI_FROM_CFG(axi, AxiCfg) +`define FLOO_TYPEDEF_AXI_FROM_CFG(name, cfg) \ + typedef logic [cfg.AddrWidth-1:0] ``name``_addr_t; \ + typedef logic [cfg.InIdWidth-1:0] ``name``_in_id_t; \ + typedef logic [cfg.OutIdWidth-1:0] ``name``_out_id_t; \ + typedef logic [cfg.UserWidth-1:0] ``name``_user_t; \ + typedef logic [cfg.DataWidth-1:0] ``name``_data_t; \ + typedef logic [cfg.DataWidth/8-1:0] ``name``_strb_t; \ + `AXI_TYPEDEF_ALL_CT(``name``_in, ``name``_in_req_t, ``name``_in_rsp_t, ``name``_addr_t, ``name``_in_id_t, ``name``_data_t, ``name``_strb_t, ``name``_user_t) \ + `AXI_TYPEDEF_ALL_CT(``name``_out, ``name``_out_req_t, ``name``_out_rsp_t, ``name``_addr_t, ``name``_out_id_t, ``name``_data_t, ``name``_strb_t, ``name``_user_t) + +//////////////////////////////////////////////////////////////////////////////////////////////////// +// Defines the all the flit types and physical channel for configuration +// with a single AXI interface and two physical channels `req` and `rsp`. +// It also defines `unions` named as `chan_t`, which can be used +// to represent multiple different flit types in a single variable. +// +// Arguments: +// - name: Name of flit types +// - req: Name of the `req` flit type +// - rsp: Name of the `rsp` flit type +// - axi_name: Prefix for the AXI channel types +// - cfg: AxiCfg struct type defining AddrWidth, DataWidth, User Width and +// IdWidth for in and out direction (see `floo_pkg::AxiCfg`) +// - hdr_t: Type of the header +// +// Usage Example: +// localparam floo_pkg::axi_cfg_t AxiCfg = '{...}; +// `FLOO_TYPEDEF_HDR_T(hdr_t, ...) +// `FLOO_TYPEDEF_AXI_FROM_CFG(my_axi, AxiCfg) +// `FLOO_TYPEDEF_AXI_CHAN_ALL(axi, req, rsp, my_axi, AxiCfg, hdr_t) +`define FLOO_TYPEDEF_AXI_CHAN_ALL(name, req, rsp, axi_name, cfg, hdr_t) \ + `FLOO_TYPEDEF_FLIT_T(``name``_aw, hdr_t, ``axi_name``_aw_chan_t, floo_pkg::get_axi_rsvd_bits(cfg, floo_pkg::AxiAw)) \ + `FLOO_TYPEDEF_FLIT_T(``name``_w, hdr_t, ``axi_name``_w_chan_t, floo_pkg::get_axi_rsvd_bits(cfg, floo_pkg::AxiW)) \ + `FLOO_TYPEDEF_FLIT_T(``name``_ar, hdr_t, ``axi_name``_ar_chan_t, floo_pkg::get_axi_rsvd_bits(cfg, floo_pkg::AxiAr)) \ + `FLOO_TYPEDEF_GENERIC_FLIT_T(req, hdr_t, logic [floo_pkg::get_max_axi_payload_bits(cfg, floo_pkg::FlooReq)-1:0]) \ + \ + `FLOO_TYPEDEF_FLIT_T(``name``_b, hdr_t, ``axi_name``_b_chan_t, floo_pkg::get_axi_rsvd_bits(cfg, floo_pkg::AxiB)) \ + `FLOO_TYPEDEF_FLIT_T(``name``_r, hdr_t, ``axi_name``_r_chan_t, floo_pkg::get_axi_rsvd_bits(cfg, floo_pkg::AxiR)) \ + `FLOO_TYPEDEF_GENERIC_FLIT_T(rsp, hdr_t, logic [floo_pkg::get_max_axi_payload_bits(cfg, floo_pkg::FlooRsp)-1:0]) \ + \ + typedef union packed { \ + floo_``name``_aw_flit_t axi_aw; \ + floo_``name``_w_flit_t axi_w; \ + floo_``name``_ar_flit_t axi_ar; \ + floo_``req``_generic_flit_t generic; \ + } floo_``req``_chan_t; \ + \ + typedef union packed { \ + floo_``name``_b_flit_t axi_b; \ + floo_``name``_r_flit_t axi_r; \ + floo_``rsp``_generic_flit_t generic; \ + } floo_``rsp``_chan_t; + +//////////////////////////////////////////////////////////////////////////////////////////////////// +// Defines the all the flit types and physical channel for configuration +// with a narrow and a wide AXI interface and three physical channels `req`, `rsp` and `wide`. +// It also defines `unions` named as `chan_t`, which can be used +// to represent multiple different flit types in a single variable. +// +// Arguments: +// - name: Name of flit types +// - req: Name of the `req` flit type +// - rsp: Name of the `rsp` flit type +// - wide: Name of the `wide` flit type +// - axi_narrow_name: Prefix for the AXI narrow channel types +// - axi_wide_name: Prefix for the AXI wide channel types +// - cfg_n: AxiCfg struct type for the narrow AXI interface, +// defining AddrWidth, DataWidth, User Width and +// IdWidth for in and out direction (see `floo_pkg::AxiCfg`) +// - cfg_w: AxiCfg struct type for the wide AXI interface, +// defining AddrWidth, DataWidth, User Width and +// IdWidth for in and out direction (see `floo_pkg::AxiCfg`) +// - hdr_t: Type of the header +// +// Usage Example: +// localparam floo_pkg::axi_cfg_t AxiCfgN = '{...}; +// localparam floo_pkg::axi_cfg_t AxiCfgW = '{...}; +// `FLOO_TYPEDEF_HDR_T(hdr_t, ...) +// `FLOO_TYPEDEF_AXI_FROM_CFG(my_axi_narrow, AxiCfgN) +// `FLOO_TYPEDEF_AXI_FROM_CFG(my_axi_wide, AxiCfgW) +// `FLOO_TYPEDEF_NW_CHAN_ALL(axi, req, rsp, wide, my_axi_narrow_in, my_axi_wide_in, AxiCfgN, AxiCfgW, hdr_t) +`define FLOO_TYPEDEF_NW_CHAN_ALL(name, req, rsp, wide, axi_narrow_name, axi_wide_name, cfg_n, cfg_w, hdr_t) \ + `AXI_TYPEDEF_ALL(__``name``_narrow, logic [cfg_n.AddrWidth-1:0], logic [cfg_n.InIdWidth-1:0], logic [cfg_n.DataWidth-1:0], logic [cfg_n.DataWidth/8-1:0], logic [cfg_n.UserWidth-1:0]) \ + `AXI_TYPEDEF_ALL(__``name``_wide, logic [cfg_w.AddrWidth-1:0], logic [cfg_w.InIdWidth-1:0], logic [cfg_w.DataWidth-1:0], logic [cfg_w.DataWidth/8-1:0], logic [cfg_w.UserWidth-1:0]) \ + `FLOO_TYPEDEF_FLIT_T(``name``_narrow_aw, hdr_t, ``axi_narrow_name``_aw_chan_t, floo_pkg::get_nw_rsvd_bits(cfg_n, cfg_w, floo_pkg::NarrowAw)) \ + `FLOO_TYPEDEF_FLIT_T(``name``_narrow_w, hdr_t, ``axi_narrow_name``_w_chan_t, floo_pkg::get_nw_rsvd_bits(cfg_n, cfg_w, floo_pkg::NarrowW)) \ + `FLOO_TYPEDEF_FLIT_T(``name``_narrow_ar, hdr_t, ``axi_narrow_name``_ar_chan_t, floo_pkg::get_nw_rsvd_bits(cfg_n, cfg_w, floo_pkg::NarrowAr)) \ + `FLOO_TYPEDEF_FLIT_T(``name``_wide_ar, hdr_t, ``axi_wide_name``_ar_chan_t, floo_pkg::get_nw_rsvd_bits(cfg_n, cfg_w, floo_pkg::WideAr)) \ + `FLOO_TYPEDEF_GENERIC_FLIT_T(req, hdr_t, logic [floo_pkg::get_max_nw_payload_bits(cfg_n, cfg_w, floo_pkg::FlooReq)-1:0]) \ + \ + `FLOO_TYPEDEF_FLIT_T(``name``_narrow_b, hdr_t, ``axi_narrow_name``_b_chan_t, floo_pkg::get_nw_rsvd_bits(cfg_n, cfg_w, floo_pkg::NarrowB)) \ + `FLOO_TYPEDEF_FLIT_T(``name``_narrow_r, hdr_t, ``axi_narrow_name``_r_chan_t, floo_pkg::get_nw_rsvd_bits(cfg_n, cfg_w, floo_pkg::NarrowR)) \ + `FLOO_TYPEDEF_FLIT_T(``name``_wide_b, hdr_t, ``axi_wide_name``_b_chan_t, floo_pkg::get_nw_rsvd_bits(cfg_n, cfg_w, floo_pkg::WideB)) \ + `FLOO_TYPEDEF_GENERIC_FLIT_T(rsp, hdr_t, logic [floo_pkg::get_max_nw_payload_bits(cfg_n, cfg_w, floo_pkg::FlooRsp)-1:0]) \ + \ + `FLOO_TYPEDEF_FLIT_T(``name``_wide_aw, hdr_t, ``axi_wide_name``_aw_chan_t, floo_pkg::get_nw_rsvd_bits(cfg_n, cfg_w, floo_pkg::WideAw)) \ + `FLOO_TYPEDEF_FLIT_T(``name``_wide_w, hdr_t, ``axi_wide_name``_w_chan_t, floo_pkg::get_nw_rsvd_bits(cfg_n, cfg_w, floo_pkg::WideW)) \ + `FLOO_TYPEDEF_FLIT_T(``name``_wide_r, hdr_t, ``axi_wide_name``_r_chan_t, floo_pkg::get_nw_rsvd_bits(cfg_n, cfg_w, floo_pkg::WideR)) \ + `FLOO_TYPEDEF_GENERIC_FLIT_T(wide, hdr_t, logic [floo_pkg::get_max_nw_payload_bits(cfg_n, cfg_w, floo_pkg::FlooWide)-1:0]) \ + \ + typedef union packed { \ + floo_``name``_narrow_aw_flit_t narrow_aw; \ + floo_``name``_narrow_w_flit_t narrow_w; \ + floo_``name``_narrow_ar_flit_t narrow_ar; \ + floo_``name``_wide_ar_flit_t wide_ar; \ + floo_``req``_generic_flit_t generic; \ + } floo_``req``_chan_t; \ + \ + typedef union packed { \ + floo_``name``_narrow_b_flit_t narrow_b; \ + floo_``name``_narrow_r_flit_t narrow_r; \ + floo_``name``_wide_b_flit_t wide_b; \ + floo_``rsp``_generic_flit_t generic; \ + } floo_``rsp``_chan_t; \ + \ + typedef union packed { \ + floo_``name``_wide_aw_flit_t wide_aw; \ + floo_``name``_wide_w_flit_t wide_w; \ + floo_``name``_wide_r_flit_t wide_r; \ + floo_``wide``_generic_flit_t generic; \ + } floo_``wide``_chan_t; + +//////////////////////////////////////////////////////////////////////////////////////////////////// +// Defines the all the link types with a ready-valid handshaking interface +// +// Arguments: +// - name: Name of the link type +// - chan_name: Name of the channel type to transport +// +// Usage Example: +// localparam floo_pkg::axi_cfg_t AxiCfg = '{...}; +// `FLOO_TYPEDEF_HDR_T(hdr_t, ...) +// `FLOO_TYPEDEF_AXI_FROM_CFG(my_axi, AxiCfg) +// `FLOO_TYPEDEF_AXI_CHAN_ALL(my_axi, req, rsp, my_axi_in, AxiCfg, hdr_t) +// FLOO_TYPEDEF_LINK_T(req, my_axi) +`define FLOO_TYPEDEF_LINK_T(name, chan_name) \ + typedef struct packed { \ + logic valid; \ + logic ready; \ + floo_``chan_name``_chan_t ``chan_name``; \ + } floo_``name``_t; + + +//////////////////////////////////////////////////////////////////////////////////////////////////// +// Defines the all the link types with credit-based flow control interface +// for use with virtual channels +// +// Arguments: +// - name: Name of the link type +// - chan_name: Name of the channel type to transport +// - vc_id_t: Type of the virtual channel ID +// +// Usage Example: +// localparam floo_pkg::axi_cfg_t AxiCfg = '{...}; +// `FLOO_TYPEDEF_HDR_T(hdr_t, ...) +// `FLOO_TYPEDEF_AXI_FROM_CFG(my_axi, AxiCfg) +// `FLOO_TYPEDEF_AXI_CHAN_ALL(my_axi, req, rsp, my_axi_in, AxiCfg, hdr_t) +// FLOO_TYPEDEF_LINK_T(vc_req, my_axi) +`define FLOO_TYPEDEF_VC_LINK_T(name, chan_name, vc_id_t) \ + typedef struct packed { \ + logic valid; \ + logic credit_v; \ + vc_id_t credit_id; \ + floo_``chan_name``_chan_t ``chan_name``; \ + } floo_``name``_t; + +//////////////////////////////////////////////////////////////////////////////////////////////////// +// Defines the all the link types with ready-valid handshaking interface +// for a single AXI interface configuration +// +// Arguments: +// - req: Name of the `req` link type +// - rsp: Name of the `rsp` link type +// - req_chan: Name of the `req` channel type to transport +// - rsp_chan: Name of the `rsp` channel type to transport +// +// Usage Example: +// localparam floo_pkg::axi_cfg_t AxiCfg = '{...}; +// `FLOO_TYPEDEF_HDR_T(hdr_t, ...) +// `FLOO_TYPEDEF_AXI_FROM_CFG(my_axi, AxiCfg) +// `FLOO_TYPEDEF_AXI_CHAN_ALL(my_axi, my_req, my_rsp, my_axi_in, AxiCfg, hdr_t) +// `FLOO_TYPEDEF_AXI_LINK_ALL(req, rsp, my_req, my_rsp) +`define FLOO_TYPEDEF_AXI_LINK_ALL(req, rsp, req_chan, rsp_chan) \ + `FLOO_TYPEDEF_LINK_T(req, req_chan) \ + `FLOO_TYPEDEF_LINK_T(rsp, rsp_chan) \ + +//////////////////////////////////////////////////////////////////////////////////////////////////// +// Defines the all the link types with ready-valid handshaking interface +// for a narrow-wide AXI interface configuration +// +// Arguments: +// - req: Name of the `req` link type +// - rsp: Name of the `rsp` link type +// - wide: Name of the `wide` link type +// - req_chan: Name of the `req` channel type to transport +// - rsp_chan: Name of the `rsp` channel type to transport +// - wide_chan: Name of the `wide` channel type to transport +// +// Usage Example: +// localparam floo_pkg::axi_cfg_t AxiCfgN = '{...}; +// localparam floo_pkg::axi_cfg_t AxiCfgW = '{...}; +// `FLOO_TYPEDEF_HDR_T(hdr_t, ...) +// `FLOO_TYPEDEF_AXI_FROM_CFG(my_narrow_axi, AxiCfgN) +// `FLOO_TYPEDEF_AXI_FROM_CFG(my_wide_axi, AxiCfgW) +// `FLOO_TYPEDEF_NW_CHAN_ALL(axi, my_req, my_rsp, my_wide, my_axi_narrow_in, my_axi_wide_in, AxiCfgN, AxiCfgW, hdr_t) +// `FLOO_TYPEDEF_NW_LINK_ALL(req, rsp, wide, my_req, my_rsp, my_wide) +`define FLOO_TYPEDEF_NW_LINK_ALL(req, rsp, wide, req_chan, rsp_chan, wide_chan) \ + `FLOO_TYPEDEF_LINK_T(req, req_chan) \ + `FLOO_TYPEDEF_LINK_T(rsp, rsp_chan) \ + `FLOO_TYPEDEF_LINK_T(wide, wide_chan) + +//////////////////////////////////////////////////////////////////////////////////////////////////// +// Defines the all the link types with credit-based flow control interface +// for a single AXI interface configuration +// +// Arguments: +// - req: Name of the `req` link type +// - rsp: Name of the `rsp` link type +// - req_chan: Name of the `req` channel type to transport +// - rsp_chan: Name of the `rsp` channel type to transport +// - vc_id_t: Type of the virtual channel ID +// +// Usage Example: +// localparam floo_pkg::axi_cfg_t AxiCfg = '{...}; +// `FLOO_TYPEDEF_HDR_T(hdr_t, ...) +// `FLOO_TYPEDEF_AXI_FROM_CFG(my_axi, AxiCfg) +// `FLOO_TYPEDEF_AXI_CHAN_ALL(my_axi, my_req, my_rsp, my_axi_in, AxiCfg, hdr_t) +// `FLOO_TYPEDEF_VC_AXI_LINK_ALL(vc_req, vc_rsp, my_req, my_rsp) +`define FLOO_TYPEDEF_VC_AXI_LINK_ALL(req, rsp, req_chan, rsp_chan, vc_id_t) \ + `FLOO_TYPEDEF_VC_LINK_T(req, req_chan, vc_id_t) \ + `FLOO_TYPEDEF_VC_LINK_T(rsp, rsp_chan, vc_id_t) \ + + +//////////////////////////////////////////////////////////////////////////////////////////////////// +// Defines the all the link types with credit-based flow control interface +// for a narrow-wide AXI interface configuration +// +// Arguments: +// - req: Name of the `req` link type +// - rsp: Name of the `rsp` link type +// - wide: Name of the `wide` link type +// - req_chan: Name of the `req` channel type to transport +// - rsp_chan: Name of the `rsp` channel type to transport +// - wide_chan: Name of the `wide` channel type to transport +// - vc_id_t: Type of the virtual channel ID +// +// Usage Example: +// localparam floo_pkg::axi_cfg_t AxiCfgN = '{...}; +// localparam floo_pkg::axi_cfg_t AxiCfgW = '{...}; +// `FLOO_TYPEDEF_HDR_T(hdr_t, ...) +// `FLOO_TYPEDEF_AXI_FROM_CFG(my_narrow_axi, AxiCfgN) +// `FLOO_TYPEDEF_AXI_FROM_CFG(my_wide_axi, AxiCfgW) +// `FLOO_TYPEDEF_NW_CHAN_ALL(axi, my_req, my_rsp, my_wide, my_axi_narrow_in, my_axi_wide_in, AxiCfgN, AxiCfgW, hdr_t) +// `FLOO_TYPEDEF_NW_LINK_ALL(vc_req, vc_rsp, vc_wide, my_req, my_rsp, my_wide) +`define FLOO_TYPEDEF_VC_NW_LINK_ALL(req, rsp, wide, req_chan, rsp_chan, wide_chan, vc_id_t) \ + `FLOO_TYPEDEF_VC_LINK_T(req, req_chan, vc_id_t) \ + `FLOO_TYPEDEF_VC_LINK_T(rsp, rsp_chan, vc_id_t) \ + `FLOO_TYPEDEF_VC_LINK_T(wide, wide_chan, vc_id_t) `endif // FLOO_NOC_TYPEDEF_SVH_ diff --git a/hw/tb/tb_floo_axi_chimney.sv b/hw/tb/tb_floo_axi_chimney.sv index f7ca26eb..8047304a 100644 --- a/hw/tb/tb_floo_axi_chimney.sv +++ b/hw/tb/tb_floo_axi_chimney.sv @@ -10,9 +10,6 @@ module tb_floo_axi_chimney; - import floo_pkg::*; - import floo_axi_pkg::*; - localparam time CyclTime = 10ns; localparam time ApplTime = 2ns; localparam time TestTime = 8ns; @@ -22,16 +19,18 @@ module tb_floo_axi_chimney; localparam int unsigned NumReads1 = 1000; localparam int unsigned NumWrites1 = 1000; - localparam bit AtopSupport = 1'b1; - localparam int unsigned NumTargets = 2; - localparam int unsigned ReorderBufferSize = 64; - localparam int unsigned MaxTxns = 32; - localparam int unsigned MaxTxnsPerId = 32; - logic clk, rst_n; + typedef logic [1:0] x_bits_t; + typedef logic [1:0] y_bits_t; + `FLOO_TYPEDEF_XY_NODE_ID_T(id_t, x_bits_t, y_bits_t, logic) + `FLOO_TYPEDEF_HDR_T(hdr_t, id_t, id_t, floo_pkg::axi_ch_e, logic) + `FLOO_TYPEDEF_AXI_FROM_CFG(axi, floo_test_pkg::AxiCfg) + `FLOO_TYPEDEF_AXI_CHAN_ALL(axi, req, rsp, axi_in, floo_test_pkg::AxiCfg, hdr_t) + `FLOO_TYPEDEF_AXI_LINK_ALL(req, rsp, req, rsp) + axi_in_req_t [NumTargets-1:0] node_man_req; axi_in_rsp_t [NumTargets-1:0] node_man_rsp; @@ -60,8 +59,8 @@ module tb_floo_axi_chimney; ); typedef struct packed { - logic [AxiInAddrWidth-1:0] start_addr; - logic [AxiInAddrWidth-1:0] end_addr; + logic [floo_test_pkg::AxiCfg.AddrWidth-1:0] start_addr; + logic [floo_test_pkg::AxiCfg.AddrWidth-1:0] end_addr; } node_addr_region_t; localparam int unsigned NumAddrRegions = 1; @@ -70,24 +69,19 @@ module tb_floo_axi_chimney; }; floo_axi_test_node #( - .AxiAddrWidth ( AxiInAddrWidth ), - .AxiDataWidth ( AxiInDataWidth ), - .AxiIdOutWidth ( AxiInIdWidth ), - .AxiIdInWidth ( AxiOutIdWidth ), - .AxiUserWidth ( AxiInUserWidth ), - .mst_req_t ( axi_in_req_t ), - .mst_rsp_t ( axi_in_rsp_t ), - .slv_req_t ( axi_out_req_t ), - .slv_rsp_t ( axi_out_rsp_t ), - .ApplTime ( ApplTime ), - .TestTime ( TestTime ), - .Atops ( AtopSupport ), - .AxiMaxBurstLen ( ReorderBufferSize ), - .NumAddrRegions ( NumAddrRegions ), - .rule_t ( node_addr_region_t ), - .AddrRegions ( AddrRegions ), - .NumReads ( NumReads0 ), - .NumWrites ( NumWrites0 ) + .AxiCfg ( floo_test_pkg::AxiCfg ), + .mst_req_t ( axi_in_req_t ), + .mst_rsp_t ( axi_in_rsp_t ), + .slv_req_t ( axi_out_req_t ), + .slv_rsp_t ( axi_out_rsp_t ), + .ApplTime ( ApplTime ), + .TestTime ( TestTime ), + .Atops ( floo_test_pkg::AtopSupport ), + .NumAddrRegions ( NumAddrRegions ), + .rule_t ( node_addr_region_t ), + .AddrRegions ( AddrRegions ), + .NumReads ( NumReads0 ), + .NumWrites ( NumWrites0 ) ) i_test_node_0 ( .clk_i ( clk ), .rst_ni ( rst_n ), @@ -99,15 +93,15 @@ module tb_floo_axi_chimney; ); axi_reorder_remap_compare #( - .AxiInIdWidth ( AxiInIdWidth ), - .AxiOutIdWidth ( AxiOutIdWidth ), - .aw_chan_t ( axi_in_aw_chan_t ), - .w_chan_t ( axi_in_w_chan_t ), - .b_chan_t ( axi_in_b_chan_t ), - .ar_chan_t ( axi_in_ar_chan_t ), - .r_chan_t ( axi_in_r_chan_t ), - .req_t ( axi_in_req_t ), - .rsp_t ( axi_in_rsp_t ) + .AxiInIdWidth ( floo_test_pkg::AxiCfg.InIdWidth ), + .AxiOutIdWidth ( floo_test_pkg::AxiCfg.OutIdWidth ), + .aw_chan_t ( axi_in_aw_chan_t ), + .w_chan_t ( axi_in_w_chan_t ), + .b_chan_t ( axi_in_b_chan_t ), + .ar_chan_t ( axi_in_ar_chan_t ), + .r_chan_t ( axi_in_r_chan_t ), + .req_t ( axi_in_req_t ), + .rsp_t ( axi_in_rsp_t ) ) i_axi_chan_compare_0 ( .clk_i ( clk ), .mon_mst_req_i ( node_man_req[0] ), @@ -118,11 +112,19 @@ module tb_floo_axi_chimney; ); floo_axi_chimney #( - .AtopSupport ( AtopSupport ), - .MaxAtomicTxns ( 4 ), - .MaxTxns ( MaxTxns ), - .MaxTxnsPerId ( MaxTxnsPerId ), - .ReorderBufferSize ( ReorderBufferSize ) + .AxiCfg ( floo_test_pkg::AxiCfg ), + .ChimneyCfg ( floo_test_pkg::ChimneyCfg ), + .RouteCfg ( floo_test_pkg::RouteCfg ), + .AtopSupport ( floo_test_pkg::AtopSupport ), + .MaxAtomicTxns ( floo_test_pkg::MaxAtomicTxns ), + .hdr_t ( hdr_t ), + .axi_in_req_t ( axi_in_req_t ), + .axi_in_rsp_t ( axi_in_rsp_t ), + .axi_out_req_t ( axi_out_req_t ), + .axi_out_rsp_t ( axi_out_rsp_t ), + .id_t ( id_t ), + .floo_req_t ( floo_req_t ), + .floo_rsp_t ( floo_rsp_t ) ) i_floo_axi_chimney_0 ( .clk_i ( clk ), .rst_ni ( rst_n ), @@ -141,11 +143,19 @@ module tb_floo_axi_chimney; ); floo_axi_chimney #( - .AtopSupport ( AtopSupport ), - .MaxAtomicTxns ( 4 ), - .MaxTxns ( MaxTxns ), - .MaxTxnsPerId ( MaxTxnsPerId ), - .ReorderBufferSize ( ReorderBufferSize ) + .AxiCfg ( floo_test_pkg::AxiCfg ), + .ChimneyCfg ( floo_test_pkg::ChimneyCfg ), + .RouteCfg ( floo_test_pkg::RouteCfg ), + .AtopSupport ( floo_test_pkg::AtopSupport ), + .MaxAtomicTxns ( floo_test_pkg::MaxAtomicTxns ), + .hdr_t ( hdr_t ), + .axi_in_req_t ( axi_in_req_t ), + .axi_in_rsp_t ( axi_in_rsp_t ), + .axi_out_req_t ( axi_out_req_t ), + .axi_out_rsp_t ( axi_out_rsp_t ), + .id_t ( id_t ), + .floo_req_t ( floo_req_t ), + .floo_rsp_t ( floo_rsp_t ) ) i_floo_axi_chimney_1 ( .clk_i ( clk ), .rst_ni ( rst_n ), @@ -164,15 +174,15 @@ module tb_floo_axi_chimney; ); axi_reorder_remap_compare #( - .AxiInIdWidth ( AxiInIdWidth ), - .AxiOutIdWidth ( AxiOutIdWidth ), - .aw_chan_t ( axi_in_aw_chan_t ), - .w_chan_t ( axi_in_w_chan_t ), - .b_chan_t ( axi_in_b_chan_t ), - .ar_chan_t ( axi_in_ar_chan_t ), - .r_chan_t ( axi_in_r_chan_t ), - .req_t ( axi_in_req_t ), - .rsp_t ( axi_in_rsp_t ) + .AxiInIdWidth ( floo_test_pkg::AxiCfg.InIdWidth ), + .AxiOutIdWidth ( floo_test_pkg::AxiCfg.OutIdWidth ), + .aw_chan_t ( axi_in_aw_chan_t ), + .w_chan_t ( axi_in_w_chan_t ), + .b_chan_t ( axi_in_b_chan_t ), + .ar_chan_t ( axi_in_ar_chan_t ), + .r_chan_t ( axi_in_r_chan_t ), + .req_t ( axi_in_req_t ), + .rsp_t ( axi_in_rsp_t ) ) i_axi_chan_compare_1 ( .clk_i ( clk ), .mon_mst_req_i ( node_man_req[1] ), @@ -183,24 +193,19 @@ module tb_floo_axi_chimney; ); floo_axi_test_node #( - .AxiAddrWidth ( AxiInAddrWidth ), - .AxiDataWidth ( AxiInDataWidth ), - .AxiIdInWidth ( AxiOutIdWidth ), - .AxiIdOutWidth ( AxiInIdWidth ), - .AxiUserWidth ( AxiInUserWidth ), - .mst_req_t ( axi_in_req_t ), - .mst_rsp_t ( axi_in_rsp_t ), - .slv_req_t ( axi_out_req_t ), - .slv_rsp_t ( axi_out_rsp_t ), - .ApplTime ( ApplTime ), - .TestTime ( TestTime ), - .Atops ( AtopSupport ), - .AxiMaxBurstLen ( ReorderBufferSize ), - .NumAddrRegions ( NumAddrRegions ), - .rule_t ( node_addr_region_t ), - .AddrRegions ( AddrRegions ), - .NumReads ( NumReads1 ), - .NumWrites ( NumWrites1 ) + .AxiCfg ( floo_test_pkg::AxiCfg ), + .mst_req_t ( axi_in_req_t ), + .mst_rsp_t ( axi_in_rsp_t ), + .slv_req_t ( axi_out_req_t ), + .slv_rsp_t ( axi_out_rsp_t ), + .ApplTime ( ApplTime ), + .TestTime ( TestTime ), + .Atops ( floo_test_pkg::AtopSupport ), + .NumAddrRegions ( NumAddrRegions ), + .rule_t ( node_addr_region_t ), + .AddrRegions ( AddrRegions ), + .NumReads ( NumReads1 ), + .NumWrites ( NumWrites1 ) ) i_test_node_1 ( .clk_i ( clk ), .rst_ni ( rst_n ), @@ -212,9 +217,9 @@ module tb_floo_axi_chimney; ); axi_bw_monitor #( - .req_t ( axi_in_req_t ), - .rsp_t ( axi_in_rsp_t ), - .AxiIdWidth ( AxiInIdWidth ) + .req_t ( axi_in_req_t ), + .rsp_t ( axi_in_rsp_t ), + .AxiIdWidth ( floo_test_pkg::AxiCfg.InIdWidth ) ) i_axi_bw_monitor ( .clk_i ( clk ), .en_i ( rst_n ), diff --git a/hw/tb/tb_floo_dma_mesh.sv b/hw/tb/tb_floo_dma_mesh.sv index abe24098..19aa1f02 100644 --- a/hw/tb/tb_floo_dma_mesh.sv +++ b/hw/tb/tb_floo_dma_mesh.sv @@ -4,13 +4,12 @@ // // Author: Tim Fischer +`include "axi/typedef.svh" `include "floo_noc/typedef.svh" -`include "common_cells/assertions.svh" module tb_floo_dma_mesh; import floo_pkg::*; - import floo_narrow_wide_pkg::*; localparam time CyclTime = 10ns; localparam time ApplTime = 2ns; @@ -20,29 +19,22 @@ module tb_floo_dma_mesh; localparam int unsigned NumY = 4; localparam int unsigned NumMax = (NumX > NumY) ? NumX : NumY; + typedef logic[$clog2(NumX+2)-1:0] x_bits_t; + typedef logic[$clog2(NumY+2)-1:0] y_bits_t; + `FLOO_TYPEDEF_XY_NODE_ID_T(id_t, x_bits_t, y_bits_t, logic) + `FLOO_TYPEDEF_HDR_T(hdr_t, id_t, id_t, floo_pkg::nw_ch_e, logic) + `FLOO_TYPEDEF_AXI_FROM_CFG(axi_narrow, floo_test_pkg::AxiCfgN) + `FLOO_TYPEDEF_AXI_FROM_CFG(axi_wide, floo_test_pkg::AxiCfgW) + `FLOO_TYPEDEF_NW_CHAN_ALL(axi, req, rsp, wide, axi_narrow_in, axi_wide_in, + floo_test_pkg::AxiCfgN, floo_test_pkg::AxiCfgW, hdr_t) + `FLOO_TYPEDEF_NW_LINK_ALL(req, rsp, wide, req, rsp, wide) + localparam int unsigned HBMLatency = 100; - localparam axi_narrow_in_addr_t HBMSize = 48'h10000; // 64KB - localparam axi_narrow_in_addr_t MemSize = HBMSize; - - if (RouteAlgo == XYRouting) begin : gen_asserts - `ASSERT_INIT(NotEnoughXBits, $clog2(NumX + 2) <= $bits(x_bits_t)) - `ASSERT_INIT(NotEnoughYBits, $clog2(NumY + 2) <= $bits(y_bits_t)) - `ASSERT_INIT(NotEnoughAddrOffset, $clog2(HBMSize) <= XYAddrOffsetX) - end else begin : gen_error - $fatal(1, "This testbench only supports XYRouting"); - end + localparam axi_narrow_addr_t HBMSize = 48'h10000; // 64KB + localparam axi_narrow_addr_t MemSize = HBMSize; - // Narrow Wide Chimney parameters - localparam bit CutAx = 1'b1; - localparam bit CutRsp = 1'b1; - localparam int unsigned NarrowMaxTxnsPerId = 4; - localparam int unsigned NarrowReorderBufferSize = 32'd256; - localparam int unsigned WideMaxTxnsPerId = 32; - localparam int unsigned WideReorderBufferSize = 32'd64; - localparam int unsigned NarrowMaxTxns = 32; - localparam int unsigned WideMaxTxns = 32; - localparam int unsigned ChannelFifoDepth = 2; - localparam int unsigned OutputFifoDepth = 2; + localparam int unsigned InFifoDepth = 2; + localparam int unsigned OutFifoDepth = 2; logic clk, rst_n; @@ -72,7 +64,7 @@ module tb_floo_dma_mesh; floo_req_t [NumX-1:0][NumY-1:0] narrow_chimney_man_req, narrow_chimney_sub_req; floo_rsp_t [NumX-1:0][NumY-1:0] narrow_chimney_man_rsp, narrow_chimney_sub_rsp; - floo_wide_t [NumX-1:0][NumY-1:0] wide_chimney_man, wide_chimney_sub; + floo_wide_t [NumX-1:0][NumY-1:0] wide_chimney_man, wide_chimney_sub; floo_req_t [NumX:0][NumY-1:0] req_hor_pos; floo_req_t [NumX:0][NumY-1:0] req_hor_neg; @@ -82,10 +74,10 @@ module tb_floo_dma_mesh; floo_rsp_t [NumX:0][NumY-1:0] rsp_hor_neg; floo_rsp_t [NumY:0][NumX-1:0] rsp_ver_pos; floo_rsp_t [NumY:0][NumX-1:0] rsp_ver_neg; - floo_wide_t [NumX:0][NumY-1:0] wide_hor_pos; - floo_wide_t [NumX:0][NumY-1:0] wide_hor_neg; - floo_wide_t [NumY:0][NumX-1:0] wide_ver_pos; - floo_wide_t [NumY:0][NumX-1:0] wide_ver_neg; + floo_wide_t [NumX:0][NumY-1:0] wide_hor_pos; + floo_wide_t [NumX:0][NumY-1:0] wide_hor_neg; + floo_wide_t [NumY:0][NumX-1:0] wide_ver_pos; + floo_wide_t [NumY:0][NumX-1:0] wide_ver_neg; logic [NumX-1:0][NumY-1:0][1:0] end_of_sim; @@ -103,21 +95,21 @@ module tb_floo_dma_mesh; //////////////////////////////// floo_hbm_model #( - .TA ( ApplTime ), - .TT ( TestTime ), - .Latency ( HBMLatency ), - .NumChannels ( 1 ), - .AddrWidth ( AxiWideOutAddrWidth ), - .DataWidth ( AxiWideOutDataWidth ), - .UserWidth ( AxiWideOutUserWidth ), - .IdWidth ( AxiWideOutIdWidth ), - .axi_req_t ( axi_wide_out_req_t ), - .axi_rsp_t ( axi_wide_out_rsp_t ), - .aw_chan_t ( axi_wide_out_aw_chan_t ), - .w_chan_t ( axi_wide_out_w_chan_t ), - .b_chan_t ( axi_wide_out_b_chan_t ), - .ar_chan_t ( axi_wide_out_ar_chan_t ), - .r_chan_t ( axi_wide_out_r_chan_t ) + .TA ( ApplTime ), + .TT ( TestTime ), + .Latency ( HBMLatency ), + .NumChannels ( 1 ), + .AddrWidth ( floo_test_pkg::AxiCfgW.AddrWidth ), + .DataWidth ( floo_test_pkg::AxiCfgW.DataWidth ), + .UserWidth ( floo_test_pkg::AxiCfgW.UserWidth ), + .IdWidth ( floo_test_pkg::AxiCfgW.OutIdWidth ), + .axi_req_t ( axi_wide_out_req_t ), + .axi_rsp_t ( axi_wide_out_rsp_t ), + .aw_chan_t ( axi_wide_out_aw_chan_t ), + .w_chan_t ( axi_wide_out_w_chan_t ), + .b_chan_t ( axi_wide_out_b_chan_t ), + .ar_chan_t ( axi_wide_out_ar_chan_t ), + .r_chan_t ( axi_wide_out_r_chan_t ) ) i_floo_wide_hbm_model [West:North][NumMax-1:0] ( .clk_i ( clk ), .rst_ni ( rst_n ), @@ -126,21 +118,21 @@ module tb_floo_dma_mesh; ); floo_hbm_model #( - .TA ( ApplTime ), - .TT ( TestTime ), - .Latency ( HBMLatency ), - .NumChannels ( 1 ), - .AddrWidth ( AxiNarrowOutAddrWidth ), - .DataWidth ( AxiNarrowOutDataWidth ), - .UserWidth ( AxiNarrowOutUserWidth ), - .IdWidth ( AxiNarrowOutIdWidth ), - .axi_req_t ( axi_narrow_out_req_t ), - .axi_rsp_t ( axi_narrow_out_rsp_t ), - .aw_chan_t ( axi_narrow_out_aw_chan_t ), - .w_chan_t ( axi_narrow_out_w_chan_t ), - .b_chan_t ( axi_narrow_out_b_chan_t ), - .ar_chan_t ( axi_narrow_out_ar_chan_t ), - .r_chan_t ( axi_narrow_out_r_chan_t ) + .TA ( ApplTime ), + .TT ( TestTime ), + .Latency ( HBMLatency ), + .NumChannels ( 1 ), + .AddrWidth ( floo_test_pkg::AxiCfgN.AddrWidth ), + .DataWidth ( floo_test_pkg::AxiCfgN.DataWidth ), + .UserWidth ( floo_test_pkg::AxiCfgN.UserWidth ), + .IdWidth ( floo_test_pkg::AxiCfgN.OutIdWidth ), + .axi_req_t ( axi_narrow_out_req_t ), + .axi_rsp_t ( axi_narrow_out_rsp_t ), + .aw_chan_t ( axi_narrow_out_aw_chan_t ), + .w_chan_t ( axi_narrow_out_w_chan_t ), + .b_chan_t ( axi_narrow_out_b_chan_t ), + .ar_chan_t ( axi_narrow_out_ar_chan_t ), + .r_chan_t ( axi_narrow_out_r_chan_t ) ) i_floo_narrow_hbm_model [West:North][NumMax-1:0] ( .clk_i ( clk ), .rst_ni ( rst_n ), @@ -159,7 +151,7 @@ module tb_floo_dma_mesh; if (i == North) begin : gen_north_hbm_chimneys for (genvar j = 0; j < NumChimneys; j++) begin : gen_hbm_chimney_xy_id - assign xy_id_hbm[j] = '{x: j+1, y: NumY+1}; + assign xy_id_hbm[j] = '{x: j+1, y: NumY+1, port_id: 0}; end assign req_hbm_in = req_ver_pos[NumY]; assign rsp_hbm_in = rsp_ver_pos[NumY]; @@ -170,7 +162,7 @@ module tb_floo_dma_mesh; end else if (i == South) begin : gen_south_hbm_chimneys for (genvar j = 0; j < NumChimneys; j++) begin : gen_hbm_chimney_xy_id - assign xy_id_hbm[j] = '{x: j+1, y: 0}; + assign xy_id_hbm[j] = '{x: j+1, y: 0, port_id: 0}; end assign req_hbm_in = req_ver_neg[0]; assign rsp_hbm_in = rsp_ver_neg[0]; @@ -181,7 +173,7 @@ module tb_floo_dma_mesh; end else if (i == East) begin : gen_east_hbm_chimneys for (genvar j = 0; j < NumChimneys; j++) begin : gen_hbm_chimney_xy_id - assign xy_id_hbm[j] = '{x: NumX+1, y: j+1}; + assign xy_id_hbm[j] = '{x: NumX+1, y: j+1, port_id: 0}; end assign req_hbm_in = req_hor_pos[NumX]; assign rsp_hbm_in = rsp_hor_pos[NumX]; @@ -192,7 +184,7 @@ module tb_floo_dma_mesh; end else if (i == West) begin : gen_west_hbm_chimneys for (genvar j = 0; j < NumChimneys; j++) begin : gen_hbm_chimney_xy_id - assign xy_id_hbm[j] = '{x: 0, y: j+1}; + assign xy_id_hbm[j] = '{x: 0, y: j+1, port_id: 0}; end assign req_hbm_in = req_hor_neg[0]; assign rsp_hbm_in = rsp_hor_neg[0]; @@ -202,13 +194,25 @@ module tb_floo_dma_mesh; assign wide_hor_pos[0] = wide_hbm_out; end - floo_narrow_wide_chimney #( - .NarrowMaxTxns ( NarrowMaxTxns ), - .WideMaxTxns ( WideMaxTxns ), - .NarrowReorderBufferSize ( NarrowReorderBufferSize ), - .WideReorderBufferSize ( WideReorderBufferSize ), - .CutAx ( CutAx ), - .CutRsp ( CutRsp ) + floo_nw_chimney #( + .AxiCfgN ( floo_test_pkg::AxiCfgN ), + .AxiCfgW ( floo_test_pkg::AxiCfgW ), + .ChimneyCfgN ( floo_test_pkg::ChimneyCfg ), + .ChimneyCfgW ( floo_test_pkg::ChimneyCfg ), + .RouteCfg ( floo_test_pkg::RouteCfg ), + .hdr_t ( hdr_t ), + .id_t ( id_t ), + .axi_narrow_in_req_t ( axi_narrow_in_req_t ), + .axi_narrow_in_rsp_t ( axi_narrow_in_rsp_t ), + .axi_narrow_out_req_t ( axi_narrow_out_req_t ), + .axi_narrow_out_rsp_t ( axi_narrow_out_rsp_t ), + .axi_wide_in_req_t ( axi_wide_in_req_t ), + .axi_wide_in_rsp_t ( axi_wide_in_rsp_t ), + .axi_wide_out_req_t ( axi_wide_out_req_t ), + .axi_wide_out_rsp_t ( axi_wide_out_rsp_t ), + .floo_req_t ( floo_req_t ), + .floo_rsp_t ( floo_rsp_t ), + .floo_wide_t ( floo_wide_t ) ) i_hbm_chimney [NumChimneys-1:0] ( .clk_i ( clk ), .rst_ni ( rst_n ), @@ -249,26 +253,23 @@ module tb_floo_dma_mesh; floo_wide_t [NumDirections-1:0] wide_out, wide_in; localparam int unsigned Index = y * NumX + x+1; - localparam logic [AxiNarrowInAddrWidth-1:0] MemBaseAddr = - (x+1) << XYAddrOffsetX | (y+1) << XYAddrOffsetY; - assign current_id = '{x: x+1, y: y+1}; + localparam axi_narrow_addr_t MemBaseAddr = + (x+1) << floo_test_pkg::RouteCfg.XYAddrOffsetX | + (y+1) << floo_test_pkg::RouteCfg.XYAddrOffsetY; + assign current_id = '{x: x+1, y: y+1, port_id: 0}; floo_dma_test_node #( - .TA ( ApplTime ), - .TT ( TestTime ), - .DataWidth ( AxiNarrowInDataWidth ), - .AddrWidth ( AxiNarrowInAddrWidth ), - .UserWidth ( AxiNarrowInUserWidth ), - .AxiIdInWidth ( AxiNarrowOutIdWidth ), - .AxiIdOutWidth ( AxiNarrowInIdWidth ), - .MemBaseAddr ( MemBaseAddr ), - .MemSize ( MemSize ), - .NumAxInFlight ( 2*NarrowMaxTxnsPerId ), - .axi_in_req_t ( axi_narrow_out_req_t ), - .axi_in_rsp_t ( axi_narrow_out_rsp_t ), - .axi_out_req_t ( axi_narrow_in_req_t ), - .axi_out_rsp_t ( axi_narrow_in_rsp_t ), - .JobId ( 100 + Index ) + .TA ( ApplTime ), + .TT ( TestTime ), + .AxiCfg ( axi_cfg_swap_iw(floo_test_pkg::AxiCfgN) ), + .MemBaseAddr ( MemBaseAddr ), + .MemSize ( MemSize ), + .NumAxInFlight ( 2*floo_test_pkg::ChimneyCfg.MaxTxnsPerId ), + .axi_in_req_t ( axi_narrow_out_req_t ), + .axi_in_rsp_t ( axi_narrow_out_rsp_t ), + .axi_out_req_t ( axi_narrow_in_req_t ), + .axi_out_rsp_t ( axi_narrow_in_rsp_t ), + .JobId ( 100 + Index ) ) i_narrow_dma_node ( .clk_i ( clk ), .rst_ni ( rst_n ), @@ -280,21 +281,17 @@ module tb_floo_dma_mesh; ); floo_dma_test_node #( - .TA ( ApplTime ), - .TT ( TestTime ), - .DataWidth ( AxiWideInDataWidth ), - .AddrWidth ( AxiWideInAddrWidth ), - .UserWidth ( AxiWideInUserWidth ), - .AxiIdInWidth ( AxiWideOutIdWidth ), - .AxiIdOutWidth ( AxiWideInIdWidth ), - .MemBaseAddr ( MemBaseAddr ), - .MemSize ( MemSize ), - .NumAxInFlight ( 2*WideMaxTxnsPerId ), - .axi_in_req_t ( axi_wide_out_req_t ), - .axi_in_rsp_t ( axi_wide_out_rsp_t ), - .axi_out_req_t ( axi_wide_in_req_t ), - .axi_out_rsp_t ( axi_wide_in_rsp_t ), - .JobId ( Index ) + .TA ( ApplTime ), + .TT ( TestTime ), + .AxiCfg ( axi_cfg_swap_iw(floo_test_pkg::AxiCfgW) ), + .MemBaseAddr ( MemBaseAddr ), + .MemSize ( MemSize ), + .NumAxInFlight ( 2*floo_test_pkg::ChimneyCfg.MaxTxnsPerId ), + .axi_in_req_t ( axi_wide_out_req_t ), + .axi_in_rsp_t ( axi_wide_out_rsp_t ), + .axi_out_req_t ( axi_wide_in_req_t ), + .axi_out_rsp_t ( axi_wide_in_rsp_t ), + .JobId ( Index ) ) i_wide_dma_node ( .clk_i ( clk ), .rst_ni ( rst_n ), @@ -306,10 +303,10 @@ module tb_floo_dma_mesh; ); axi_bw_monitor #( - .req_t ( axi_narrow_in_req_t ), - .rsp_t ( axi_narrow_in_rsp_t ), - .AxiIdWidth ( AxiNarrowInIdWidth ), - .Name ( NarrowDmaName ) + .req_t ( axi_narrow_in_req_t ), + .rsp_t ( axi_narrow_in_rsp_t ), + .AxiIdWidth ( floo_test_pkg::AxiCfgN.InIdWidth ), + .Name ( NarrowDmaName ) ) i_axi_narrow_bw_monitor ( .clk_i ( clk ), .en_i ( rst_n ), @@ -321,10 +318,10 @@ module tb_floo_dma_mesh; ); axi_bw_monitor #( - .req_t ( axi_wide_in_req_t ), - .rsp_t ( axi_wide_in_rsp_t ), - .AxiIdWidth ( AxiWideInIdWidth ), - .Name ( WideDmaName ) + .req_t ( axi_wide_in_req_t ), + .rsp_t ( axi_wide_in_rsp_t ), + .AxiIdWidth ( floo_test_pkg::AxiCfgW.InIdWidth ), + .Name ( WideDmaName ) ) i_axi_wide_bw_monitor ( .clk_i ( clk ), .en_i ( rst_n ), @@ -335,13 +332,25 @@ module tb_floo_dma_mesh; .aw_in_flight_o( ) ); - floo_narrow_wide_chimney #( - .NarrowMaxTxns ( NarrowMaxTxns ), - .WideMaxTxns ( WideMaxTxns ), - .NarrowReorderBufferSize ( NarrowReorderBufferSize ), - .WideReorderBufferSize ( WideReorderBufferSize ), - .CutAx ( CutAx ), - .CutRsp ( CutRsp ) + floo_nw_chimney #( + .AxiCfgN ( floo_test_pkg::AxiCfgN ), + .AxiCfgW ( floo_test_pkg::AxiCfgW ), + .ChimneyCfgN ( floo_test_pkg::ChimneyCfg ), + .ChimneyCfgW ( floo_test_pkg::ChimneyCfg ), + .RouteCfg ( floo_test_pkg::RouteCfg ), + .hdr_t ( hdr_t ), + .id_t ( id_t ), + .axi_narrow_in_req_t ( axi_narrow_in_req_t ), + .axi_narrow_in_rsp_t ( axi_narrow_in_rsp_t ), + .axi_narrow_out_req_t ( axi_narrow_out_req_t ), + .axi_narrow_out_rsp_t ( axi_narrow_out_rsp_t ), + .axi_wide_in_req_t ( axi_wide_in_req_t ), + .axi_wide_in_rsp_t ( axi_wide_in_rsp_t ), + .axi_wide_out_req_t ( axi_wide_out_req_t ), + .axi_wide_out_rsp_t ( axi_wide_out_rsp_t ), + .floo_req_t ( floo_req_t ), + .floo_rsp_t ( floo_rsp_t ), + .floo_wide_t ( floo_wide_t ) ) i_dma_chimney ( .clk_i ( clk ), .rst_ni ( rst_n ), @@ -365,13 +374,19 @@ module tb_floo_dma_mesh; .floo_wide_o ( wide_chimney_man[x][y] ) ); - floo_narrow_wide_router #( - .NumRoutes ( NumDirections ), - .ChannelFifoDepth ( ChannelFifoDepth ), - .OutputFifoDepth ( OutputFifoDepth ), - .RouteAlgo ( RouteAlgo ), - .XYRouteOpt ( 1'b0 ), - .id_t ( id_t ) + floo_nw_router #( + .AxiCfgN ( floo_test_pkg::AxiCfgN ), + .AxiCfgW ( floo_test_pkg::AxiCfgW ), + .NumRoutes ( NumDirections ), + .InFifoDepth ( InFifoDepth ), + .OutFifoDepth ( OutFifoDepth ), + .RouteAlgo ( floo_test_pkg::RouteCfg.RouteAlgo ), + .XYRouteOpt ( 1'b0 ), + .id_t ( id_t ), + .hdr_t ( hdr_t ), + .floo_req_t ( floo_req_t ), + .floo_rsp_t ( floo_rsp_t ), + .floo_wide_t ( floo_wide_t ) ) i_router ( .clk_i ( clk ), .rst_ni ( rst_n ), diff --git a/hw/tb/tb_floo_dma_nw_chimney.sv b/hw/tb/tb_floo_dma_nw_chimney.sv deleted file mode 100644 index b23c1501..00000000 --- a/hw/tb/tb_floo_dma_nw_chimney.sv +++ /dev/null @@ -1,414 +0,0 @@ -// Copyright 2022 ETH Zurich and University of Bologna. -// Solderpad Hardware License, Version 0.51, see LICENSE for details. -// SPDX-License-Identifier: SHL-0.51 -// -// Tim Fischer - -`include "axi/typedef.svh" -`include "axi/assign.svh" -`include "floo_noc/typedef.svh" - -module tb_floo_dma_nw_chimney; - - import floo_pkg::*; - import floo_narrow_wide_pkg::*; - - localparam time CyclTime = 10ns; - localparam time ApplTime = 2ns; - localparam time TestTime = 8ns; - - localparam int unsigned NumTargets = 2; - - localparam int unsigned ReorderBufferSize = 128; - localparam int unsigned MaxTxns = 32; - localparam int unsigned MaxTxnsPerId = 32; - - logic clk, rst_n; - - axi_narrow_in_req_t [NumTargets-1:0] narrow_man_req; - axi_narrow_in_rsp_t [NumTargets-1:0] narrow_man_rsp; - axi_wide_in_req_t [NumTargets-1:0] wide_man_req; - axi_wide_in_rsp_t [NumTargets-1:0] wide_man_rsp; - - axi_narrow_out_req_t [NumTargets-1:0] narrow_sub_req; - axi_narrow_out_rsp_t [NumTargets-1:0] narrow_sub_rsp; - axi_wide_out_req_t [NumTargets-1:0] wide_sub_req; - axi_wide_out_rsp_t [NumTargets-1:0] wide_sub_rsp; - - axi_narrow_in_req_t [NumTargets-1:0] narrow_sub_req_id_mapped; - axi_narrow_in_rsp_t [NumTargets-1:0] narrow_sub_rsp_id_mapped; - axi_wide_in_req_t [NumTargets-1:0] wide_sub_req_id_mapped; - axi_wide_in_rsp_t [NumTargets-1:0] wide_sub_rsp_id_mapped; - - for (genvar i = 0; i < NumDirections; i++) begin : gen_dir - `AXI_ASSIGN_REQ_STRUCT(narrow_sub_req_id_mapped[i], narrow_sub_req[i]) - `AXI_ASSIGN_RESP_STRUCT(narrow_sub_rsp_id_mapped[i], narrow_sub_rsp[i]) - `AXI_ASSIGN_REQ_STRUCT(wide_sub_req_id_mapped[i], wide_sub_req[i]) - `AXI_ASSIGN_RESP_STRUCT(wide_sub_rsp_id_mapped[i], wide_sub_rsp[i]) - end - - floo_req_t [NumTargets-1:0] chimney_req, chimney_req_cut; - floo_rsp_t [NumTargets-1:0] chimney_rsp, chimney_rsp_cut; - floo_wide_t [NumTargets-1:0] chimney_wide, chimney_wide_cut; - - logic [NumTargets*2-1:0] end_of_sim; - - clk_rst_gen #( - .ClkPeriod ( CyclTime ), - .RstClkCycles ( 5 ) - ) i_clk_gen ( - .clk_o ( clk ), - .rst_no ( rst_n ) - ); - - typedef struct packed { - logic [AxiNarrowInAddrWidth-1:0] start_addr; - logic [AxiNarrowInAddrWidth-1:0] end_addr; - } node_addr_region_t; - - localparam int unsigned MemBaseAddr = 32'h0000_0000; - localparam int unsigned MemSize = 32'h0001_0000; - - floo_dma_test_node #( - .TA ( ApplTime ), - .TT ( TestTime ), - .DataWidth ( AxiNarrowInDataWidth ), - .AddrWidth ( AxiNarrowInAddrWidth ), - .UserWidth ( AxiNarrowInUserWidth ), - .AxiIdInWidth ( AxiNarrowOutIdWidth ), - .AxiIdOutWidth ( AxiNarrowInIdWidth ), - .MemBaseAddr ( MemBaseAddr ), - .MemSize ( MemSize ), - .axi_in_req_t ( axi_narrow_out_req_t ), - .axi_in_rsp_t ( axi_narrow_out_rsp_t ), - .axi_out_req_t ( axi_narrow_in_req_t ), - .axi_out_rsp_t ( axi_narrow_in_rsp_t ), - .JobId ( 100 ) - ) i_narrow_dma_node_0 ( - .clk_i ( clk ), - .rst_ni ( rst_n ), - .axi_in_req_i ( narrow_sub_req[0] ), - .axi_in_rsp_o ( narrow_sub_rsp[0] ), - .axi_out_req_o ( narrow_man_req[0] ), - .axi_out_rsp_i ( narrow_man_rsp[0] ), - .end_of_sim_o ( end_of_sim[0] ) - ); - - floo_dma_test_node #( - .TA ( ApplTime ), - .TT ( TestTime ), - .DataWidth ( AxiWideInDataWidth ), - .AddrWidth ( AxiWideInAddrWidth ), - .UserWidth ( AxiWideInUserWidth ), - .AxiIdInWidth ( AxiWideOutIdWidth ), - .AxiIdOutWidth ( AxiWideInIdWidth ), - .MemBaseAddr ( MemBaseAddr ), - .MemSize ( MemSize ), - .axi_in_req_t ( axi_wide_out_req_t ), - .axi_in_rsp_t ( axi_wide_out_rsp_t ), - .axi_out_req_t ( axi_wide_in_req_t ), - .axi_out_rsp_t ( axi_wide_in_rsp_t ), - .JobId ( 0 ) - ) i_wide_dma_node_0 ( - .clk_i ( clk ), - .rst_ni ( rst_n ), - .axi_in_req_i ( wide_sub_req[0] ), - .axi_in_rsp_o ( wide_sub_rsp[0] ), - .axi_out_req_o ( wide_man_req[0] ), - .axi_out_rsp_i ( wide_man_rsp[0] ), - .end_of_sim_o ( end_of_sim[1] ) - ); - - axi_chan_compare #( - .aw_chan_t ( axi_narrow_in_aw_chan_t ), - .w_chan_t ( axi_narrow_in_w_chan_t ), - .b_chan_t ( axi_narrow_in_b_chan_t ), - .ar_chan_t ( axi_narrow_in_ar_chan_t ), - .r_chan_t ( axi_narrow_in_r_chan_t ), - .req_t ( axi_narrow_in_req_t ), - .resp_t ( axi_narrow_in_rsp_t ) - ) i_narrow_channel_compare_0 ( - .clk_a_i ( clk ), - .clk_b_i ( clk ), - .axi_a_req ( narrow_man_req[0] ), - .axi_a_res ( narrow_man_rsp[0] ), - .axi_b_req ( narrow_sub_req_id_mapped[1] ), - .axi_b_res ( narrow_sub_rsp_id_mapped[1] ) - ); - - axi_chan_compare #( - .aw_chan_t ( axi_wide_in_aw_chan_t ), - .w_chan_t ( axi_wide_in_w_chan_t ), - .b_chan_t ( axi_wide_in_b_chan_t ), - .ar_chan_t ( axi_wide_in_ar_chan_t ), - .r_chan_t ( axi_wide_in_r_chan_t ), - .req_t ( axi_wide_in_req_t ), - .resp_t ( axi_wide_in_rsp_t ) - ) i_wide_channel_compare_0 ( - .clk_a_i ( clk ), - .clk_b_i ( clk ), - .axi_a_req ( wide_man_req[0] ), - .axi_a_res ( wide_man_rsp[0] ), - .axi_b_req ( wide_sub_req_id_mapped[1] ), - .axi_b_res ( wide_sub_rsp_id_mapped[1] ) - ); - - floo_narrow_wide_chimney #( - .NarrowMaxTxns ( MaxTxns ), - .NarrowMaxTxnsPerId ( MaxTxnsPerId ), - .NarrowReorderBufferSize ( ReorderBufferSize ), - .WideMaxTxns ( MaxTxns ), - .WideMaxTxnsPerId ( MaxTxnsPerId ), - .WideReorderBufferSize ( ReorderBufferSize ) - ) i_floo_narrow_wide_chimney_0 ( - .clk_i ( clk ), - .rst_ni ( rst_n ), - .sram_cfg_i ( '0 ), - .test_enable_i ( 1'b0 ), - .axi_narrow_in_req_i ( narrow_man_req[0] ), - .axi_narrow_in_rsp_o ( narrow_man_rsp[0] ), - .axi_narrow_out_req_o ( narrow_sub_req[0] ), - .axi_narrow_out_rsp_i ( narrow_sub_rsp[0] ), - .axi_wide_in_req_i ( wide_man_req[0] ), - .axi_wide_in_rsp_o ( wide_man_rsp[0] ), - .axi_wide_out_req_o ( wide_sub_req[0] ), - .axi_wide_out_rsp_i ( wide_sub_rsp[0] ), - .id_i ( '0 ), - .route_table_i ( '0 ), - .floo_req_o ( chimney_req[0] ), - .floo_rsp_o ( chimney_rsp[0] ), - .floo_wide_o ( chimney_wide[0] ), - .floo_req_i ( chimney_req_cut[1] ), - .floo_rsp_i ( chimney_rsp_cut[1] ), - .floo_wide_i ( chimney_wide_cut[1] ) - ); - - floo_cut #( - .NumChannels ( 2 ), - .NumCuts ( 32'd7 ), // should simulate a hop with 2 routers - .flit_t ( floo_req_chan_t ) - ) i_floo_req_cut ( - .clk_i ( clk ), - .rst_ni ( rst_n ), - .valid_i ( {chimney_req[1].valid, chimney_req[0].valid} ), - .ready_o ( {chimney_req_cut[1].ready, chimney_req_cut[0].ready} ), - .data_i ( {chimney_req[1].req, chimney_req[0].req} ), - .valid_o ( {chimney_req_cut[1].valid, chimney_req_cut[0].valid} ), - .ready_i ( {chimney_req[1].ready, chimney_req[0].ready} ), - .data_o ( {chimney_req_cut[1].req, chimney_req_cut[0].req} ) - ); - - floo_cut #( - .NumChannels ( 2 ), - .NumCuts ( 32'd7 ), // should simulate a hop with 2 routers - .flit_t ( floo_rsp_chan_t ) - ) i_floo_rsp_cut ( - .clk_i ( clk ), - .rst_ni ( rst_n ), - .valid_i ( {chimney_rsp[1].valid, chimney_rsp[0].valid} ), - .ready_o ( {chimney_rsp_cut[1].ready, chimney_rsp_cut[0].ready} ), - .data_i ( {chimney_rsp[1].rsp, chimney_rsp[0].rsp} ), - .valid_o ( {chimney_rsp_cut[1].valid, chimney_rsp_cut[0].valid} ), - .ready_i ( {chimney_rsp[1].ready, chimney_rsp[0].ready} ), - .data_o ( {chimney_rsp_cut[1].rsp, chimney_rsp_cut[0].rsp} ) - ); - - floo_cut #( - .NumChannels ( 2 ), - .NumCuts ( 32'd4 ), // should simulate a hop with 2 routers - .flit_t ( floo_wide_chan_t ) - ) i_floo_wide_cut ( - .clk_i ( clk ), - .rst_ni ( rst_n ), - .valid_i ( {chimney_wide[1].valid, chimney_wide[0].valid} ), - .ready_o ( {chimney_wide_cut[1].ready, chimney_wide_cut[0].ready} ), - .data_i ( {chimney_wide[1].wide, chimney_wide[0].wide} ), - .valid_o ( {chimney_wide_cut[1].valid, chimney_wide_cut[0].valid} ), - .ready_i ( {chimney_wide[1].ready, chimney_wide[0].ready} ), - .data_o ( {chimney_wide_cut[1].wide, chimney_wide_cut[0].wide} ) - ); - - floo_narrow_wide_chimney #( - .NarrowMaxTxns ( MaxTxns ), - .NarrowMaxTxnsPerId ( MaxTxnsPerId ), - .NarrowReorderBufferSize ( ReorderBufferSize ), - .WideMaxTxns ( MaxTxns ), - .WideMaxTxnsPerId ( MaxTxnsPerId ), - .WideReorderBufferSize ( ReorderBufferSize ) - ) i_floo_narrow_wide_chimney_1 ( - .clk_i ( clk ), - .rst_ni ( rst_n ), - .sram_cfg_i ( '0 ), - .test_enable_i ( 1'b0 ), - .axi_narrow_in_req_i ( narrow_man_req[1] ), - .axi_narrow_in_rsp_o ( narrow_man_rsp[1] ), - .axi_narrow_out_req_o ( narrow_sub_req[1] ), - .axi_narrow_out_rsp_i ( narrow_sub_rsp[1] ), - .axi_wide_in_req_i ( wide_man_req[1] ), - .axi_wide_in_rsp_o ( wide_man_rsp[1] ), - .axi_wide_out_req_o ( wide_sub_req[1] ), - .axi_wide_out_rsp_i ( wide_sub_rsp[1] ), - .id_i ( '0 ), - .route_table_i ( '0 ), - .floo_req_o ( chimney_req[1] ), - .floo_rsp_o ( chimney_rsp[1] ), - .floo_wide_o ( chimney_wide[1] ), - .floo_req_i ( chimney_req_cut[0] ), - .floo_rsp_i ( chimney_rsp_cut[0] ), - .floo_wide_i ( chimney_wide_cut[0] ) - ); - - axi_chan_compare #( - .aw_chan_t ( axi_narrow_in_aw_chan_t ), - .w_chan_t ( axi_narrow_in_w_chan_t ), - .b_chan_t ( axi_narrow_in_b_chan_t ), - .ar_chan_t ( axi_narrow_in_ar_chan_t ), - .r_chan_t ( axi_narrow_in_r_chan_t ), - .req_t ( axi_narrow_in_req_t ), - .resp_t ( axi_narrow_in_rsp_t ) - ) i_narrow_channel_compare_1 ( - .clk_a_i ( clk ), - .clk_b_i ( clk ), - .axi_a_req ( narrow_man_req[1] ), - .axi_a_res ( narrow_man_rsp[1] ), - .axi_b_req ( narrow_sub_req_id_mapped[0] ), - .axi_b_res ( narrow_sub_rsp_id_mapped[0] ) - ); - - axi_chan_compare #( - .aw_chan_t ( axi_wide_in_aw_chan_t ), - .w_chan_t ( axi_wide_in_w_chan_t ), - .b_chan_t ( axi_wide_in_b_chan_t ), - .ar_chan_t ( axi_wide_in_ar_chan_t ), - .r_chan_t ( axi_wide_in_r_chan_t ), - .req_t ( axi_wide_in_req_t ), - .resp_t ( axi_wide_in_rsp_t ) - ) i_wide_channel_compare_1 ( - .clk_a_i ( clk ), - .clk_b_i ( clk ), - .axi_a_req ( wide_man_req[1] ), - .axi_a_res ( wide_man_rsp[1] ), - .axi_b_req ( wide_sub_req_id_mapped[0] ), - .axi_b_res ( wide_sub_rsp_id_mapped[0] ) - ); - - floo_dma_test_node #( - .TA ( ApplTime ), - .TT ( TestTime ), - .DataWidth ( AxiNarrowInDataWidth ), - .AddrWidth ( AxiNarrowInAddrWidth ), - .UserWidth ( AxiNarrowInUserWidth ), - .AxiIdInWidth ( AxiNarrowOutIdWidth ), - .AxiIdOutWidth ( AxiNarrowInIdWidth ), - .MemBaseAddr ( MemBaseAddr ), - .MemSize ( MemSize ), - .axi_in_req_t ( axi_narrow_out_req_t ), - .axi_in_rsp_t ( axi_narrow_out_rsp_t ), - .axi_out_req_t ( axi_narrow_in_req_t ), - .axi_out_rsp_t ( axi_narrow_in_rsp_t ), - .JobId ( 101 ) - ) i_narrow_dma_node_1 ( - .clk_i ( clk ), - .rst_ni ( rst_n ), - .axi_in_req_i ( narrow_sub_req[1] ), - .axi_in_rsp_o ( narrow_sub_rsp[1] ), - .axi_out_req_o ( narrow_man_req[1] ), - .axi_out_rsp_i ( narrow_man_rsp[1] ), - .end_of_sim_o ( end_of_sim[2] ) - ); - - floo_dma_test_node #( - .TA ( ApplTime ), - .TT ( TestTime ), - .DataWidth ( AxiWideInDataWidth ), - .AddrWidth ( AxiWideInAddrWidth ), - .UserWidth ( AxiWideInUserWidth ), - .AxiIdInWidth ( AxiWideOutIdWidth ), - .AxiIdOutWidth ( AxiWideInIdWidth ), - .MemBaseAddr ( MemBaseAddr ), - .MemSize ( MemSize ), - .axi_in_req_t ( axi_wide_out_req_t ), - .axi_in_rsp_t ( axi_wide_out_rsp_t ), - .axi_out_req_t ( axi_wide_in_req_t ), - .axi_out_rsp_t ( axi_wide_in_rsp_t ), - .JobId ( 1 ) - ) i_wide_dma_node_1 ( - .clk_i ( clk ), - .rst_ni ( rst_n ), - .axi_in_req_i ( wide_sub_req[1] ), - .axi_in_rsp_o ( wide_sub_rsp[1] ), - .axi_out_req_o ( wide_man_req[1] ), - .axi_out_rsp_i ( wide_man_rsp[1] ), - .end_of_sim_o ( end_of_sim[3] ) - ); - - axi_bw_monitor #( - .req_t ( axi_narrow_in_req_t ), - .rsp_t ( axi_narrow_in_rsp_t ), - .AxiIdWidth ( AxiNarrowInIdWidth ), - .Name ( "narrow 0" ) - ) i_axi_narrow_bw_monitor_0 ( - .clk_i ( clk ), - .en_i ( rst_n ), - .end_of_sim_i ( &end_of_sim ), - .req_i ( narrow_man_req[0] ), - .rsp_i ( narrow_man_rsp[0] ), - .ar_in_flight_o ( ), - .aw_in_flight_o ( ) - ); - - axi_bw_monitor #( - .req_t ( axi_narrow_in_req_t ), - .rsp_t ( axi_narrow_in_rsp_t ), - .AxiIdWidth ( AxiNarrowInIdWidth ), - .Name ( "narrow 1" ) - ) i_axi_narrow_bw_monitor_1 ( - .clk_i ( clk ), - .en_i ( rst_n ), - .end_of_sim_i ( &end_of_sim ), - .req_i ( narrow_man_req[1] ), - .rsp_i ( narrow_man_rsp[1] ), - .ar_in_flight_o ( ), - .aw_in_flight_o ( ) - ); - - axi_bw_monitor #( - .req_t ( axi_wide_in_req_t ), - .rsp_t ( axi_wide_in_rsp_t ), - .AxiIdWidth ( AxiWideInIdWidth ), - .Name ( "wide 0" ) - ) i_axi_wide_bw_monitor_0 ( - .clk_i ( clk ), - .en_i ( rst_n ), - .end_of_sim_i ( &end_of_sim ), - .req_i ( wide_man_req[0] ), - .rsp_i ( wide_man_rsp[0] ), - .ar_in_flight_o ( ), - .aw_in_flight_o ( ) - ); - - axi_bw_monitor #( - .req_t ( axi_wide_in_req_t ), - .rsp_t ( axi_wide_in_rsp_t ), - .AxiIdWidth ( AxiWideInIdWidth ), - .Name ( "wide 1" ) - ) i_axi_wide_bw_monitor_1 ( - .clk_i ( clk ), - .en_i ( rst_n ), - .end_of_sim_i ( &end_of_sim ), - .req_i ( wide_man_req[1] ), - .rsp_i ( wide_man_rsp[1] ), - .ar_in_flight_o ( ), - .aw_in_flight_o ( ) - ); - - initial begin - wait(&end_of_sim); - // Wait for some time - repeat (2) @(posedge clk); - // Stop the simulation - $stop; - end - - -endmodule diff --git a/hw/tb/tb_floo_narrow_wide_chimney.sv b/hw/tb/tb_floo_narrow_wide_chimney.sv deleted file mode 100644 index 9ceece4b..00000000 --- a/hw/tb/tb_floo_narrow_wide_chimney.sv +++ /dev/null @@ -1,361 +0,0 @@ -// Copyright 2022 ETH Zurich and University of Bologna. -// Solderpad Hardware License, Version 0.51, see LICENSE for details. -// SPDX-License-Identifier: SHL-0.51 -// -// Tim Fischer - -`include "axi/typedef.svh" -`include "axi/assign.svh" -`include "floo_noc/typedef.svh" - -module tb_floo_narrow_wide_chimney; - - import floo_pkg::*; - import floo_narrow_wide_pkg::*; - - localparam time CyclTime = 10ns; - localparam time ApplTime = 2ns; - localparam time TestTime = 8ns; - - localparam int unsigned NarrowNumReads = 1000; - localparam int unsigned NarrowNumWrites = 1000; - localparam int unsigned WideNumReads = 1000; - localparam int unsigned WideNumWrites = 1000; - - localparam bit AtopSupport = 1'b1; - localparam int unsigned WideMaxUniqueIds = 2; - localparam int unsigned MaxAtomicTxns = 3; - - localparam int unsigned NumTargets = 2; - - localparam int unsigned ReorderBufferSize = 128; - localparam int unsigned MaxTxns = 32; - localparam int unsigned MaxTxnsPerId = 32; - - logic clk, rst_n; - - axi_narrow_in_req_t [NumTargets-1:0] narrow_man_req; - axi_narrow_in_rsp_t [NumTargets-1:0] narrow_man_rsp; - axi_wide_in_req_t [NumTargets-1:0] wide_man_req; - axi_wide_in_rsp_t [NumTargets-1:0] wide_man_rsp; - - axi_narrow_out_req_t [NumTargets-1:0] narrow_sub_req; - axi_narrow_out_rsp_t [NumTargets-1:0] narrow_sub_rsp; - axi_wide_out_req_t [NumTargets-1:0] wide_sub_req; - axi_wide_out_rsp_t [NumTargets-1:0] wide_sub_rsp; - - axi_narrow_in_req_t [NumTargets-1:0] narrow_sub_req_id_mapped; - axi_narrow_in_rsp_t [NumTargets-1:0] narrow_sub_rsp_id_mapped; - axi_wide_in_req_t [NumTargets-1:0] wide_sub_req_id_mapped; - axi_wide_in_rsp_t [NumTargets-1:0] wide_sub_rsp_id_mapped; - - for (genvar i = 0; i < NumDirections; i++) begin : gen_dir - `AXI_ASSIGN_REQ_STRUCT(narrow_sub_req_id_mapped[i], narrow_sub_req[i]) - `AXI_ASSIGN_RESP_STRUCT(narrow_sub_rsp_id_mapped[i], narrow_sub_rsp[i]) - `AXI_ASSIGN_REQ_STRUCT(wide_sub_req_id_mapped[i], wide_sub_req[i]) - `AXI_ASSIGN_RESP_STRUCT(wide_sub_rsp_id_mapped[i], wide_sub_rsp[i]) - end - - floo_req_t [NumTargets-1:0] chimney_req; - floo_rsp_t [NumTargets-1:0] chimney_rsp; - floo_wide_t [NumTargets-1:0] chimney_wide; - - logic [NumTargets*3-1:0] end_of_sim; - - clk_rst_gen #( - .ClkPeriod ( CyclTime ), - .RstClkCycles ( 5 ) - ) i_clk_gen ( - .clk_o ( clk ), - .rst_no ( rst_n ) - ); - - typedef struct packed { - logic [AxiNarrowInAddrWidth-1:0] start_addr; - logic [AxiNarrowInAddrWidth-1:0] end_addr; - } node_addr_region_t; - - localparam int unsigned NumAddrRegions = 1; - localparam node_addr_region_t [NumAddrRegions-1:0] AddrRegions = '{ - '{start_addr: 48'h000_0000_0000, end_addr: 48'h000_0000_8000} - }; - - typedef struct packed { - int unsigned idx; - logic [AxiNarrowInAddrWidth-1:0] start_addr; - logic [AxiNarrowInAddrWidth-1:0] end_addr; - } node_addr_region_id_t; - - node_addr_region_id_t [NumTargets-1:0] node_addr_regions; - assign node_addr_regions = '{ - '{idx: 0, start_addr: 48'h000_0000_0000, end_addr: 48'h000_0000_4000}, - '{idx: 1, start_addr: 48'h000_0000_4000, end_addr: 48'h000_0000_8000} - }; - - floo_axi_test_node #( - .AxiAddrWidth ( AxiNarrowInAddrWidth ), - .AxiDataWidth ( AxiNarrowInDataWidth ), - .AxiIdInWidth ( AxiNarrowOutIdWidth ), - .AxiIdOutWidth ( AxiNarrowInIdWidth ), - .AxiUserWidth ( AxiNarrowInUserWidth ), - .mst_req_t ( axi_narrow_in_req_t ), - .mst_rsp_t ( axi_narrow_in_rsp_t ), - .slv_req_t ( axi_narrow_out_req_t ), - .slv_rsp_t ( axi_narrow_out_rsp_t ), - .ApplTime ( ApplTime ), - .TestTime ( TestTime ), - .Atops ( AtopSupport ), - .AxiMaxBurstLen ( ReorderBufferSize ), - .NumAddrRegions ( NumAddrRegions ), - .rule_t ( node_addr_region_t ), - .AddrRegions ( AddrRegions ), - .NumReads ( NarrowNumReads ), - .NumWrites ( NarrowNumWrites ) - ) i_narrow_test_node_0 ( - .clk_i ( clk ), - .rst_ni ( rst_n ), - .mst_port_req_o ( narrow_man_req[0] ), - .mst_port_rsp_i ( narrow_man_rsp[0] ), - .slv_port_req_i ( narrow_sub_req[0] ), - .slv_port_rsp_o ( narrow_sub_rsp[0] ), - .end_of_sim ( end_of_sim[0] ) - ); - - floo_axi_test_node #( - .AxiAddrWidth ( AxiWideInAddrWidth ), - .AxiDataWidth ( AxiWideInDataWidth ), - .AxiIdInWidth ( AxiWideOutIdWidth ), - .AxiIdOutWidth ( AxiWideInIdWidth ), - .AxiUserWidth ( AxiWideInUserWidth ), - .mst_req_t ( axi_wide_in_req_t ), - .mst_rsp_t ( axi_wide_in_rsp_t ), - .slv_req_t ( axi_wide_out_req_t ), - .slv_rsp_t ( axi_wide_out_rsp_t ), - .Atops ( 1'b0 ), - .ApplTime ( ApplTime ), - .TestTime ( TestTime ), - .AxiMaxBurstLen ( ReorderBufferSize ), - .NumAddrRegions ( NumAddrRegions ), - .rule_t ( node_addr_region_t ), - .AddrRegions ( AddrRegions ), - .NumReads ( WideNumReads ), - .NumWrites ( WideNumWrites ) - ) i_wide_test_node_0 ( - .clk_i ( clk ), - .rst_ni ( rst_n ), - .mst_port_req_o ( wide_man_req[0] ), - .mst_port_rsp_i ( wide_man_rsp[0] ), - .slv_port_req_i ( wide_sub_req[0] ), - .slv_port_rsp_o ( wide_sub_rsp[0] ), - .end_of_sim ( end_of_sim[1] ) - ); - - axi_reorder_remap_compare #( - .AxiInIdWidth ( AxiNarrowInIdWidth ), - .AxiOutIdWidth ( AxiNarrowOutIdWidth ), - .aw_chan_t ( axi_narrow_in_aw_chan_t ), - .w_chan_t ( axi_narrow_in_w_chan_t ), - .b_chan_t ( axi_narrow_in_b_chan_t ), - .ar_chan_t ( axi_narrow_in_ar_chan_t ), - .r_chan_t ( axi_narrow_in_r_chan_t ), - .req_t ( axi_narrow_in_req_t ), - .rsp_t ( axi_narrow_in_rsp_t ) - ) i_narrow_channel_compare_0 ( - .clk_i ( clk ), - .mon_mst_req_i ( narrow_man_req[0] ), - .mon_mst_rsp_i ( narrow_man_rsp[0] ), - .mon_slv_req_i ( narrow_sub_req_id_mapped[1] ), - .mon_slv_rsp_i ( narrow_sub_rsp_id_mapped[1] ), - .end_of_sim_o ( end_of_sim[2] ) - ); - - axi_chan_compare #( - .IgnoreId ( 1'b1 ), - .aw_chan_t ( axi_wide_in_aw_chan_t ), - .w_chan_t ( axi_wide_in_w_chan_t ), - .b_chan_t ( axi_wide_in_b_chan_t ), - .ar_chan_t ( axi_wide_in_ar_chan_t ), - .r_chan_t ( axi_wide_in_r_chan_t ), - .req_t ( axi_wide_in_req_t ), - .resp_t ( axi_wide_in_rsp_t ) - ) i_wide_channel_compare_0 ( - .clk_a_i ( clk ), - .clk_b_i ( clk ), - .axi_a_req ( wide_man_req[0] ), - .axi_a_res ( wide_man_rsp[0] ), - .axi_b_req ( wide_sub_req_id_mapped[1] ), - .axi_b_res ( wide_sub_rsp_id_mapped[1] ) - ); - - floo_narrow_wide_chimney #( - .AtopSupport ( AtopSupport ), - .MaxAtomicTxns ( MaxAtomicTxns ), - .NarrowMaxTxns ( MaxTxns ), - .NarrowMaxTxnsPerId ( MaxTxnsPerId ), - .NarrowReorderBufferSize ( ReorderBufferSize ), - .WideMaxTxns ( MaxTxns ), - .WideMaxUniqueIds ( WideMaxUniqueIds ), - .WideMaxTxnsPerId ( MaxTxnsPerId ), - .WideReorderBufferSize ( ReorderBufferSize ), - .CutAx ( 1'b0 ), - .CutRsp ( 1'b1 ) - ) i_floo_narrow_wide_chimney_0 ( - .clk_i ( clk ), - .rst_ni ( rst_n ), - .sram_cfg_i ( '0 ), - .test_enable_i ( 1'b0 ), - .axi_narrow_in_req_i ( narrow_man_req[0] ), - .axi_narrow_in_rsp_o ( narrow_man_rsp[0] ), - .axi_narrow_out_req_o ( narrow_sub_req[0] ), - .axi_narrow_out_rsp_i ( narrow_sub_rsp[0] ), - .axi_wide_in_req_i ( wide_man_req[0] ), - .axi_wide_in_rsp_o ( wide_man_rsp[0] ), - .axi_wide_out_req_o ( wide_sub_req[0] ), - .axi_wide_out_rsp_i ( wide_sub_rsp[0] ), - .id_i ( '0 ), - .route_table_i ( '0 ), - .floo_req_o ( chimney_req[0] ), - .floo_rsp_o ( chimney_rsp[0] ), - .floo_wide_o ( chimney_wide[0] ), - .floo_req_i ( chimney_req[1] ), - .floo_rsp_i ( chimney_rsp[1] ), - .floo_wide_i ( chimney_wide[1] ) - ); - - floo_narrow_wide_chimney #( - .AtopSupport ( AtopSupport ), - .MaxAtomicTxns ( MaxAtomicTxns ), - .NarrowMaxTxns ( MaxTxns ), - .NarrowMaxTxnsPerId ( MaxTxnsPerId ), - .NarrowReorderBufferSize ( ReorderBufferSize ), - .WideMaxTxns ( MaxTxns ), - .WideMaxUniqueIds ( WideMaxUniqueIds ), - .WideMaxTxnsPerId ( MaxTxnsPerId ), - .WideReorderBufferSize ( ReorderBufferSize ), - .CutAx ( 1'b0 ), - .CutRsp ( 1'b1 ) - ) i_floo_narrow_wide_chimney_1 ( - .clk_i ( clk ), - .rst_ni ( rst_n ), - .sram_cfg_i ( '0 ), - .test_enable_i ( 1'b0 ), - .axi_narrow_in_req_i ( narrow_man_req[1] ), - .axi_narrow_in_rsp_o ( narrow_man_rsp[1] ), - .axi_narrow_out_req_o ( narrow_sub_req[1] ), - .axi_narrow_out_rsp_i ( narrow_sub_rsp[1] ), - .axi_wide_in_req_i ( wide_man_req[1] ), - .axi_wide_in_rsp_o ( wide_man_rsp[1] ), - .axi_wide_out_req_o ( wide_sub_req[1] ), - .axi_wide_out_rsp_i ( wide_sub_rsp[1] ), - .id_i ( '0 ), - .route_table_i ( '0 ), - .floo_req_o ( chimney_req[1] ), - .floo_rsp_o ( chimney_rsp[1] ), - .floo_wide_o ( chimney_wide[1] ), - .floo_req_i ( chimney_req[0] ), - .floo_rsp_i ( chimney_rsp[0] ), - .floo_wide_i ( chimney_wide[0] ) - ); - - axi_reorder_remap_compare #( - .AxiInIdWidth ( AxiNarrowInIdWidth ), - .AxiOutIdWidth ( AxiNarrowOutIdWidth ), - .aw_chan_t ( axi_narrow_in_aw_chan_t ), - .w_chan_t ( axi_narrow_in_w_chan_t ), - .b_chan_t ( axi_narrow_in_b_chan_t ), - .ar_chan_t ( axi_narrow_in_ar_chan_t ), - .r_chan_t ( axi_narrow_in_r_chan_t ), - .req_t ( axi_narrow_in_req_t ), - .rsp_t ( axi_narrow_in_rsp_t ) - ) i_narrow_channel_compare_1 ( - .clk_i ( clk ), - .mon_mst_req_i ( narrow_man_req[1] ), - .mon_mst_rsp_i ( narrow_man_rsp[1] ), - .mon_slv_req_i ( narrow_sub_req_id_mapped[0] ), - .mon_slv_rsp_i ( narrow_sub_rsp_id_mapped[0] ), - .end_of_sim_o ( end_of_sim[3] ) - ); - - axi_chan_compare #( - .IgnoreId ( 1'b1 ), - .aw_chan_t ( axi_wide_in_aw_chan_t ), - .w_chan_t ( axi_wide_in_w_chan_t ), - .b_chan_t ( axi_wide_in_b_chan_t ), - .ar_chan_t ( axi_wide_in_ar_chan_t ), - .r_chan_t ( axi_wide_in_r_chan_t ), - .req_t ( axi_wide_in_req_t ), - .resp_t ( axi_wide_in_rsp_t ) - ) i_wide_channel_compare_1 ( - .clk_a_i ( clk ), - .clk_b_i ( clk ), - .axi_a_req ( wide_man_req[1] ), - .axi_a_res ( wide_man_rsp[1] ), - .axi_b_req ( wide_sub_req_id_mapped[0] ), - .axi_b_res ( wide_sub_rsp_id_mapped[0] ) - ); - - floo_axi_test_node #( - .AxiAddrWidth ( AxiNarrowInAddrWidth ), - .AxiDataWidth ( AxiNarrowInDataWidth ), - .AxiIdOutWidth ( AxiNarrowInIdWidth ), - .AxiIdInWidth ( AxiNarrowOutIdWidth ), - .AxiUserWidth ( AxiNarrowInUserWidth ), - .mst_req_t ( axi_narrow_in_req_t ), - .mst_rsp_t ( axi_narrow_in_rsp_t ), - .slv_req_t ( axi_narrow_out_req_t ), - .slv_rsp_t ( axi_narrow_out_rsp_t ), - .ApplTime ( ApplTime ), - .TestTime ( TestTime ), - .Atops ( AtopSupport ), - .AxiMaxBurstLen ( ReorderBufferSize ), - .NumAddrRegions ( NumAddrRegions ), - .rule_t ( node_addr_region_t ), - .AddrRegions ( AddrRegions ), - .NumReads ( NarrowNumReads ), - .NumWrites ( NarrowNumWrites ) - ) i_narrow_test_node_1 ( - .clk_i ( clk ), - .rst_ni ( rst_n ), - .mst_port_req_o ( narrow_man_req[1] ), - .mst_port_rsp_i ( narrow_man_rsp[1] ), - .slv_port_req_i ( narrow_sub_req[1] ), - .slv_port_rsp_o ( narrow_sub_rsp[1] ), - .end_of_sim ( end_of_sim[4] ) - ); - - floo_axi_test_node #( - .AxiAddrWidth ( AxiWideInAddrWidth ), - .AxiDataWidth ( AxiWideInDataWidth ), - .AxiIdInWidth ( AxiWideOutIdWidth ), - .AxiIdOutWidth ( AxiWideInIdWidth ), - .AxiUserWidth ( AxiWideInUserWidth ), - .mst_req_t ( axi_wide_in_req_t ), - .mst_rsp_t ( axi_wide_in_rsp_t ), - .slv_req_t ( axi_wide_out_req_t ), - .slv_rsp_t ( axi_wide_out_rsp_t ), - .ApplTime ( ApplTime ), - .TestTime ( TestTime ), - .Atops ( 1'b0 ), - .AxiMaxBurstLen ( ReorderBufferSize ), - .NumAddrRegions ( NumAddrRegions ), - .rule_t ( node_addr_region_t ), - .AddrRegions ( AddrRegions ), - .NumReads ( WideNumReads ), - .NumWrites ( WideNumWrites ) - ) i_wide_test_node_1 ( - .clk_i ( clk ), - .rst_ni ( rst_n ), - .mst_port_req_o ( wide_man_req[1] ), - .mst_port_rsp_i ( wide_man_rsp[1] ), - .slv_port_req_i ( wide_sub_req[1] ), - .slv_port_rsp_o ( wide_sub_rsp[1] ), - .end_of_sim ( end_of_sim[5] ) - ); - - initial begin - wait(&end_of_sim); - $stop; - end - - -endmodule diff --git a/hw/tb/tb_floo_nw_chimney.sv b/hw/tb/tb_floo_nw_chimney.sv new file mode 100644 index 00000000..ef8736bb --- /dev/null +++ b/hw/tb/tb_floo_nw_chimney.sv @@ -0,0 +1,372 @@ +// Copyright 2022 ETH Zurich and University of Bologna. +// Solderpad Hardware License, Version 0.51, see LICENSE for details. +// SPDX-License-Identifier: SHL-0.51 +// +// Tim Fischer + +`include "axi/typedef.svh" +`include "axi/assign.svh" +`include "floo_noc/typedef.svh" + +module tb_floo_nw_chimney; + + import floo_pkg::*; + + localparam time CyclTime = 10ns; + localparam time ApplTime = 2ns; + localparam time TestTime = 8ns; + + localparam int unsigned NarrowNumReads = 1000; + localparam int unsigned NarrowNumWrites = 1000; + localparam int unsigned WideNumReads = 1000; + localparam int unsigned WideNumWrites = 1000; + + localparam bit AtopSupport = 1'b1; + localparam int unsigned MaxAtomicTxns = 3; + + // Function to generate a chimney config UniqueIds for testing + function automatic chimney_cfg_t gen_wide_chimney_cfg(); + chimney_cfg_t cfg = ChimneyDefaultCfg; + // cfg.MaxUniqueIds = 2; + cfg.CutRsp = 1'b1; // Otherwise the compare will fail since it is a feedthrough + return cfg; + endfunction + + function automatic chimney_cfg_t gen_narrow_chimney_cfg(); + chimney_cfg_t cfg = ChimneyDefaultCfg; + cfg.CutRsp = 1'b1; // Otherwise the compare will fail since it is a feedthrough + return cfg; + endfunction + + // Default chimney config with RoB for testing + localparam chimney_cfg_t WideChimneyCfg = gen_wide_chimney_cfg(); + localparam chimney_cfg_t NarrowChimneyCfg = gen_narrow_chimney_cfg(); + + localparam int unsigned NumTargets = 2; + + logic clk, rst_n; + + typedef logic [1:0] x_bits_t; + typedef logic [1:0] y_bits_t; + `FLOO_TYPEDEF_XY_NODE_ID_T(id_t, x_bits_t, y_bits_t, logic) + `FLOO_TYPEDEF_HDR_T(hdr_t, id_t, id_t, floo_pkg::nw_ch_e, logic) + `FLOO_TYPEDEF_AXI_FROM_CFG(axi_narrow, floo_test_pkg::AxiCfgN) + `FLOO_TYPEDEF_AXI_FROM_CFG(axi_wide, floo_test_pkg::AxiCfgW) + `FLOO_TYPEDEF_NW_CHAN_ALL(axi, req, rsp, wide, axi_narrow_in, axi_wide_in, + floo_test_pkg::AxiCfgN, floo_test_pkg::AxiCfgW, hdr_t) + `FLOO_TYPEDEF_NW_LINK_ALL(req, rsp, wide, req, rsp, wide) + + axi_narrow_in_req_t [NumTargets-1:0] narrow_man_req; + axi_narrow_in_rsp_t [NumTargets-1:0] narrow_man_rsp; + axi_wide_in_req_t [NumTargets-1:0] wide_man_req; + axi_wide_in_rsp_t [NumTargets-1:0] wide_man_rsp; + + axi_narrow_out_req_t [NumTargets-1:0] narrow_sub_req; + axi_narrow_out_rsp_t [NumTargets-1:0] narrow_sub_rsp; + axi_wide_out_req_t [NumTargets-1:0] wide_sub_req; + axi_wide_out_rsp_t [NumTargets-1:0] wide_sub_rsp; + + axi_narrow_in_req_t [NumTargets-1:0] narrow_sub_req_id_mapped; + axi_narrow_in_rsp_t [NumTargets-1:0] narrow_sub_rsp_id_mapped; + axi_wide_in_req_t [NumTargets-1:0] wide_sub_req_id_mapped; + axi_wide_in_rsp_t [NumTargets-1:0] wide_sub_rsp_id_mapped; + + for (genvar i = 0; i < NumTargets; i++) begin : gen_dir + `AXI_ASSIGN_REQ_STRUCT(narrow_sub_req_id_mapped[i], narrow_sub_req[i]) + `AXI_ASSIGN_RESP_STRUCT(narrow_sub_rsp_id_mapped[i], narrow_sub_rsp[i]) + `AXI_ASSIGN_REQ_STRUCT(wide_sub_req_id_mapped[i], wide_sub_req[i]) + `AXI_ASSIGN_RESP_STRUCT(wide_sub_rsp_id_mapped[i], wide_sub_rsp[i]) + end + + floo_req_t [NumTargets-1:0] chimney_req; + floo_rsp_t [NumTargets-1:0] chimney_rsp; + floo_wide_t [NumTargets-1:0] chimney_wide; + + logic [NumTargets*3-1:0] end_of_sim; + + clk_rst_gen #( + .ClkPeriod ( CyclTime ), + .RstClkCycles ( 5 ) + ) i_clk_gen ( + .clk_o ( clk ), + .rst_no ( rst_n ) + ); + + typedef struct packed { + logic [floo_test_pkg::AxiCfg.AddrWidth-1:0] start_addr; + logic [floo_test_pkg::AxiCfg.AddrWidth-1:0] end_addr; + } node_addr_region_t; + + localparam int unsigned NumAddrRegions = 1; + localparam node_addr_region_t [NumAddrRegions-1:0] AddrRegions = '{ + '{start_addr: 32'h0000_0000, end_addr: 32'h0000_8000} + }; + + floo_axi_test_node #( + .AxiCfg ( floo_test_pkg::AxiCfgN ), + .mst_req_t ( axi_narrow_in_req_t ), + .mst_rsp_t ( axi_narrow_in_rsp_t ), + .slv_req_t ( axi_narrow_out_req_t ), + .slv_rsp_t ( axi_narrow_out_rsp_t ), + .ApplTime ( ApplTime ), + .TestTime ( TestTime ), + .Atops ( AtopSupport ), + .NumAddrRegions ( NumAddrRegions ), + .rule_t ( node_addr_region_t ), + .AddrRegions ( AddrRegions ), + .AxiMaxBurstLen ( 1 ), + .NumReads ( NarrowNumReads ), + .NumWrites ( NarrowNumWrites ) + ) i_narrow_test_node_0 ( + .clk_i ( clk ), + .rst_ni ( rst_n ), + .mst_port_req_o ( narrow_man_req[0] ), + .mst_port_rsp_i ( narrow_man_rsp[0] ), + .slv_port_req_i ( narrow_sub_req[0] ), + .slv_port_rsp_o ( narrow_sub_rsp[0] ), + .end_of_sim ( end_of_sim[0] ) + ); + + floo_axi_test_node #( + .AxiCfg ( floo_test_pkg::AxiCfg ), + .mst_req_t ( axi_wide_in_req_t ), + .mst_rsp_t ( axi_wide_in_rsp_t ), + .slv_req_t ( axi_wide_out_req_t ), + .slv_rsp_t ( axi_wide_out_rsp_t ), + .Atops ( 1'b0 ), + .NumAddrRegions ( NumAddrRegions ), + .rule_t ( node_addr_region_t ), + .AddrRegions ( AddrRegions ), + .ApplTime ( ApplTime ), + .TestTime ( TestTime ), + .NumReads ( WideNumReads ), + .NumWrites ( WideNumWrites ) + ) i_wide_test_node_0 ( + .clk_i ( clk ), + .rst_ni ( rst_n ), + .mst_port_req_o ( wide_man_req[0] ), + .mst_port_rsp_i ( wide_man_rsp[0] ), + .slv_port_req_i ( wide_sub_req[0] ), + .slv_port_rsp_o ( wide_sub_rsp[0] ), + .end_of_sim ( end_of_sim[1] ) + ); + + axi_reorder_remap_compare #( + .AxiInIdWidth ( floo_test_pkg::AxiCfgN.InIdWidth ), + .AxiOutIdWidth ( floo_test_pkg::AxiCfgN.OutIdWidth ), + .aw_chan_t ( axi_narrow_in_aw_chan_t ), + .w_chan_t ( axi_narrow_in_w_chan_t ), + .b_chan_t ( axi_narrow_in_b_chan_t ), + .ar_chan_t ( axi_narrow_in_ar_chan_t ), + .r_chan_t ( axi_narrow_in_r_chan_t ), + .req_t ( axi_narrow_in_req_t ), + .rsp_t ( axi_narrow_in_rsp_t ) + ) i_narrow_channel_compare_0 ( + .clk_i ( clk ), + .mon_mst_req_i ( narrow_man_req[0] ), + .mon_mst_rsp_i ( narrow_man_rsp[0] ), + .mon_slv_req_i ( narrow_sub_req_id_mapped[1] ), + .mon_slv_rsp_i ( narrow_sub_rsp_id_mapped[1] ), + .end_of_sim_o ( end_of_sim[2] ) + ); + + axi_chan_compare #( + .IgnoreId ( 1'b1 ), + .aw_chan_t ( axi_wide_in_aw_chan_t ), + .w_chan_t ( axi_wide_in_w_chan_t ), + .b_chan_t ( axi_wide_in_b_chan_t ), + .ar_chan_t ( axi_wide_in_ar_chan_t ), + .r_chan_t ( axi_wide_in_r_chan_t ), + .req_t ( axi_wide_in_req_t ), + .resp_t ( axi_wide_in_rsp_t ) + ) i_wide_channel_compare_0 ( + .clk_a_i ( clk ), + .clk_b_i ( clk ), + .axi_a_req ( wide_man_req[0] ), + .axi_a_res ( wide_man_rsp[0] ), + .axi_b_req ( wide_sub_req_id_mapped[1] ), + .axi_b_res ( wide_sub_rsp_id_mapped[1] ) + ); + + floo_nw_chimney #( + .AxiCfgN ( floo_test_pkg::AxiCfgN ), + .AxiCfgW ( floo_test_pkg::AxiCfgW ), + .ChimneyCfgN ( NarrowChimneyCfg ), + .ChimneyCfgW ( WideChimneyCfg ), + .RouteCfg ( floo_test_pkg::RouteCfg ), + .AtopSupport ( AtopSupport ), + .MaxAtomicTxns ( MaxAtomicTxns ), + .hdr_t ( hdr_t ), + .id_t ( id_t ), + .axi_narrow_in_req_t ( axi_narrow_in_req_t ), + .axi_narrow_in_rsp_t ( axi_narrow_in_rsp_t ), + .axi_narrow_out_req_t ( axi_narrow_out_req_t ), + .axi_narrow_out_rsp_t ( axi_narrow_out_rsp_t ), + .axi_wide_in_req_t ( axi_wide_in_req_t ), + .axi_wide_in_rsp_t ( axi_wide_in_rsp_t ), + .axi_wide_out_req_t ( axi_wide_out_req_t ), + .axi_wide_out_rsp_t ( axi_wide_out_rsp_t ), + .floo_req_t ( floo_req_t ), + .floo_rsp_t ( floo_rsp_t ), + .floo_wide_t ( floo_wide_t ) + ) i_floo_narrow_wide_chimney_0 ( + .clk_i ( clk ), + .rst_ni ( rst_n ), + .sram_cfg_i ( '0 ), + .test_enable_i ( 1'b0 ), + .axi_narrow_in_req_i ( narrow_man_req[0] ), + .axi_narrow_in_rsp_o ( narrow_man_rsp[0] ), + .axi_narrow_out_req_o ( narrow_sub_req[0] ), + .axi_narrow_out_rsp_i ( narrow_sub_rsp[0] ), + .axi_wide_in_req_i ( wide_man_req[0] ), + .axi_wide_in_rsp_o ( wide_man_rsp[0] ), + .axi_wide_out_req_o ( wide_sub_req[0] ), + .axi_wide_out_rsp_i ( wide_sub_rsp[0] ), + .id_i ( '0 ), + .route_table_i ( '0 ), + .floo_req_o ( chimney_req[0] ), + .floo_rsp_o ( chimney_rsp[0] ), + .floo_wide_o ( chimney_wide[0] ), + .floo_req_i ( chimney_req[1] ), + .floo_rsp_i ( chimney_rsp[1] ), + .floo_wide_i ( chimney_wide[1] ) + ); + + floo_nw_chimney #( + .AxiCfgN ( floo_test_pkg::AxiCfgN ), + .AxiCfgW ( floo_test_pkg::AxiCfgW ), + .ChimneyCfgN ( NarrowChimneyCfg ), + .ChimneyCfgW ( WideChimneyCfg ), + .RouteCfg ( floo_test_pkg::RouteCfg ), + .AtopSupport ( AtopSupport ), + .MaxAtomicTxns ( MaxAtomicTxns ), + .hdr_t ( hdr_t ), + .id_t ( id_t ), + .axi_narrow_in_req_t ( axi_narrow_in_req_t ), + .axi_narrow_in_rsp_t ( axi_narrow_in_rsp_t ), + .axi_narrow_out_req_t ( axi_narrow_out_req_t ), + .axi_narrow_out_rsp_t ( axi_narrow_out_rsp_t ), + .axi_wide_in_req_t ( axi_wide_in_req_t ), + .axi_wide_in_rsp_t ( axi_wide_in_rsp_t ), + .axi_wide_out_req_t ( axi_wide_out_req_t ), + .axi_wide_out_rsp_t ( axi_wide_out_rsp_t ), + .floo_req_t ( floo_req_t ), + .floo_rsp_t ( floo_rsp_t ), + .floo_wide_t ( floo_wide_t ) + ) i_floo_narrow_wide_chimney_1 ( + .clk_i ( clk ), + .rst_ni ( rst_n ), + .sram_cfg_i ( '0 ), + .test_enable_i ( 1'b0 ), + .axi_narrow_in_req_i ( narrow_man_req[1] ), + .axi_narrow_in_rsp_o ( narrow_man_rsp[1] ), + .axi_narrow_out_req_o ( narrow_sub_req[1] ), + .axi_narrow_out_rsp_i ( narrow_sub_rsp[1] ), + .axi_wide_in_req_i ( wide_man_req[1] ), + .axi_wide_in_rsp_o ( wide_man_rsp[1] ), + .axi_wide_out_req_o ( wide_sub_req[1] ), + .axi_wide_out_rsp_i ( wide_sub_rsp[1] ), + .id_i ( '0 ), + .route_table_i ( '0 ), + .floo_req_o ( chimney_req[1] ), + .floo_rsp_o ( chimney_rsp[1] ), + .floo_wide_o ( chimney_wide[1] ), + .floo_req_i ( chimney_req[0] ), + .floo_rsp_i ( chimney_rsp[0] ), + .floo_wide_i ( chimney_wide[0] ) + ); + + axi_reorder_remap_compare #( + .AxiInIdWidth ( floo_test_pkg::AxiCfgN.InIdWidth ), + .AxiOutIdWidth ( floo_test_pkg::AxiCfgN.OutIdWidth ), + .aw_chan_t ( axi_narrow_in_aw_chan_t ), + .w_chan_t ( axi_narrow_in_w_chan_t ), + .b_chan_t ( axi_narrow_in_b_chan_t ), + .ar_chan_t ( axi_narrow_in_ar_chan_t ), + .r_chan_t ( axi_narrow_in_r_chan_t ), + .req_t ( axi_narrow_in_req_t ), + .rsp_t ( axi_narrow_in_rsp_t ) + ) i_narrow_channel_compare_1 ( + .clk_i ( clk ), + .mon_mst_req_i ( narrow_man_req[1] ), + .mon_mst_rsp_i ( narrow_man_rsp[1] ), + .mon_slv_req_i ( narrow_sub_req_id_mapped[0] ), + .mon_slv_rsp_i ( narrow_sub_rsp_id_mapped[0] ), + .end_of_sim_o ( end_of_sim[3] ) + ); + + axi_chan_compare #( + .IgnoreId ( 1'b1 ), + .aw_chan_t ( axi_wide_in_aw_chan_t ), + .w_chan_t ( axi_wide_in_w_chan_t ), + .b_chan_t ( axi_wide_in_b_chan_t ), + .ar_chan_t ( axi_wide_in_ar_chan_t ), + .r_chan_t ( axi_wide_in_r_chan_t ), + .req_t ( axi_wide_in_req_t ), + .resp_t ( axi_wide_in_rsp_t ) + ) i_wide_channel_compare_1 ( + .clk_a_i ( clk ), + .clk_b_i ( clk ), + .axi_a_req ( wide_man_req[1] ), + .axi_a_res ( wide_man_rsp[1] ), + .axi_b_req ( wide_sub_req_id_mapped[0] ), + .axi_b_res ( wide_sub_rsp_id_mapped[0] ) + ); + + floo_axi_test_node #( + .AxiCfg ( floo_test_pkg::AxiCfgN ), + .mst_req_t ( axi_narrow_in_req_t ), + .mst_rsp_t ( axi_narrow_in_rsp_t ), + .slv_req_t ( axi_narrow_out_req_t ), + .slv_rsp_t ( axi_narrow_out_rsp_t ), + .ApplTime ( ApplTime ), + .TestTime ( TestTime ), + .Atops ( AtopSupport ), + .NumAddrRegions ( NumAddrRegions ), + .rule_t ( node_addr_region_t ), + .AddrRegions ( AddrRegions ), + + .AxiMaxBurstLen ( 1 ), + .NumReads ( NarrowNumReads ), + .NumWrites ( NarrowNumWrites ) + ) i_narrow_test_node_1 ( + .clk_i ( clk ), + .rst_ni ( rst_n ), + .mst_port_req_o ( narrow_man_req[1] ), + .mst_port_rsp_i ( narrow_man_rsp[1] ), + .slv_port_req_i ( narrow_sub_req[1] ), + .slv_port_rsp_o ( narrow_sub_rsp[1] ), + .end_of_sim ( end_of_sim[4] ) + ); + + floo_axi_test_node #( + .AxiCfg ( floo_test_pkg::AxiCfgW ), + .mst_req_t ( axi_wide_in_req_t ), + .mst_rsp_t ( axi_wide_in_rsp_t ), + .slv_req_t ( axi_wide_out_req_t ), + .slv_rsp_t ( axi_wide_out_rsp_t ), + .ApplTime ( ApplTime ), + .TestTime ( TestTime ), + .Atops ( 1'b0 ), + .NumAddrRegions ( NumAddrRegions ), + .rule_t ( node_addr_region_t ), + .AddrRegions ( AddrRegions ), + .NumReads ( WideNumReads ), + .NumWrites ( WideNumWrites ) + ) i_wide_test_node_1 ( + .clk_i ( clk ), + .rst_ni ( rst_n ), + .mst_port_req_o ( wide_man_req[1] ), + .mst_port_rsp_i ( wide_man_rsp[1] ), + .slv_port_req_i ( wide_sub_req[1] ), + .slv_port_rsp_o ( wide_sub_rsp[1] ), + .end_of_sim ( end_of_sim[5] ) + ); + + initial begin + wait(&end_of_sim); + $stop; + end + + +endmodule diff --git a/hw/tb/tb_floo_rob.sv b/hw/tb/tb_floo_rob.sv index 35e063e1..c9fcf060 100644 --- a/hw/tb/tb_floo_rob.sv +++ b/hw/tb/tb_floo_rob.sv @@ -11,8 +11,6 @@ module tb_floo_rob; import floo_pkg::*; - import floo_test_pkg::*; - import floo_axi_pkg::*; localparam time CyclTime = 10ns; localparam time ApplTime = 2ns; @@ -21,14 +19,32 @@ module tb_floo_rob; localparam int unsigned NumReads = 1000; localparam int unsigned NumWrites = 1000; - localparam int unsigned ReorderBufferSize = 64; - localparam int unsigned MaxTxns = 32; - localparam int unsigned MaxTxnsPerId = 32; - localparam int unsigned NumSlaves = 4; logic clk, rst_n; + // Function to generate a chimney config with a RoB + function automatic chimney_cfg_t gen_rob_chimney_cfg(); + chimney_cfg_t cfg = ChimneyDefaultCfg; + cfg.BRoBType = SimpleRoB; + cfg.BRoBSize = 64; + cfg.RRoBType = NoRoB; + cfg.RRoBSize = 64; + return cfg; + endfunction + + // Default chimney config with RoB for testing + localparam chimney_cfg_t RoBChimneyCfg = gen_rob_chimney_cfg(); + typedef logic [$clog2(RoBChimneyCfg.BRoBSize)-1:0] rob_idx_t; + + typedef logic [1:0] x_bits_t; + typedef logic [1:0] y_bits_t; + `FLOO_TYPEDEF_XY_NODE_ID_T(id_t, x_bits_t, y_bits_t, logic) + `FLOO_TYPEDEF_HDR_T(hdr_t, id_t, id_t, floo_pkg::axi_ch_e, rob_idx_t) + `FLOO_TYPEDEF_AXI_FROM_CFG(axi, floo_test_pkg::AxiCfg) + `FLOO_TYPEDEF_AXI_CHAN_ALL(axi, req, rsp, axi_in, floo_test_pkg::AxiCfg, hdr_t) + `FLOO_TYPEDEF_AXI_LINK_ALL(req, rsp, req, rsp) + axi_in_req_t node_mst_req; axi_in_rsp_t node_mst_rsp; @@ -52,7 +68,7 @@ module tb_floo_rob; logic [NumDirections-1:0] chimney_req_in_valid, chimney_req_in_ready; logic [NumDirections-1:0] chimney_rsp_in_valid, chimney_rsp_in_ready; - for (genvar i = 0; i < NumDirections; i++) begin : gen_directions + for (genvar i = 0; i < floo_pkg::NumDirections; i++) begin : gen_directions assign chimney_req_out_chan[i] = chimney_req_out[i].req; assign chimney_rsp_out_chan[i] = chimney_rsp_out[i].rsp; assign chimney_req_in[i].req = chimney_req_in_chan[i]; @@ -81,13 +97,13 @@ module tb_floo_rob; // Local Master // //////////////////// - id_t [NumDirections-1:0] xy_id; - assign xy_id[Eject] = '{x: 3'd1, y: 3'd1, port_id: 2'd0}; + id_t [floo_pkg::NumDirections-1:0] xy_id; + assign xy_id[floo_pkg::Eject] = '{x: 2'd1, y: 2'd1, port_id: 1'd0}; typedef struct packed { - int unsigned idx; - axi_in_addr_t start_addr; - axi_in_addr_t end_addr; + int unsigned idx; + axi_addr_t start_addr; + axi_addr_t end_addr; } node_addr_region_t; localparam int unsigned NumAddrRegions = 4; @@ -99,117 +115,153 @@ module tb_floo_rob; }; floo_axi_test_node #( - .AxiAddrWidth ( AxiInAddrWidth ), - .AxiDataWidth ( AxiInDataWidth ), - .AxiIdInWidth ( AxiInIdWidth ), - .AxiIdOutWidth ( AxiInIdWidth ), - .AxiUserWidth ( AxiInUserWidth ), - .mst_req_t ( axi_in_req_t ), - .mst_rsp_t ( axi_in_rsp_t ), - .slv_req_t ( axi_out_req_t ), - .slv_rsp_t ( axi_out_rsp_t ), - .ApplTime ( ApplTime ), - .TestTime ( TestTime ), - .AxiMaxBurstLen ( 4 ), - .NumAddrRegions ( NumAddrRegions ), - .rule_t ( node_addr_region_t ), - .AddrRegions ( AddrRegions ), - .NumReads ( NumReads ), - .NumWrites ( NumWrites ) + .AxiCfg ( floo_test_pkg::AxiCfg ), + .mst_req_t ( axi_in_req_t ), + .mst_rsp_t ( axi_in_rsp_t ), + .slv_req_t ( axi_out_req_t ), + .slv_rsp_t ( axi_out_rsp_t ), + .ApplTime ( ApplTime ), + .TestTime ( TestTime ), + .AxiMaxBurstLen ( 4 ), + .NumAddrRegions ( NumAddrRegions ), + .rule_t ( node_addr_region_t ), + .AddrRegions ( AddrRegions ), + .NumReads ( NumReads ), + .NumWrites ( NumWrites ) ) i_test_node_0 ( - .clk_i ( clk ), - .rst_ni ( rst_n ), - .mst_port_req_o ( node_mst_req ), - .mst_port_rsp_i ( node_mst_rsp ), - .slv_port_req_i ( node_slv_req[Eject] ), - .slv_port_rsp_o ( node_slv_rsp[Eject] ), - .end_of_sim ( end_of_sim[0] ) + .clk_i ( clk ), + .rst_ni ( rst_n ), + .mst_port_req_o ( node_mst_req ), + .mst_port_rsp_i ( node_mst_rsp ), + .slv_port_req_i ( node_slv_req[floo_pkg::Eject] ), + .slv_port_rsp_o ( node_slv_rsp[floo_pkg::Eject] ), + .end_of_sim ( end_of_sim[0] ) + ); + + axi_dumper #( + .BusName ( "MasterAxi" ), + .LogAW ( 1'b0 ), + .LogAR ( 1'b0 ), + .LogW ( 1'b0 ), + .LogB ( 1'b0 ), + .LogR ( 1'b0 ), + .axi_req_t ( axi_in_req_t ), + .axi_resp_t ( axi_in_rsp_t ) + ) i_axi_dumper ( + .clk_i ( clk ), + .rst_ni ( rst_n ), + .axi_req_i ( node_mst_req ), + .axi_resp_i ( node_mst_rsp ) ); floo_axi_chimney #( - .MaxTxns ( MaxTxns ), - .MaxTxnsPerId ( MaxTxnsPerId ), - .ReorderBufferSize ( ReorderBufferSize ) + .AxiCfg ( floo_test_pkg::AxiCfg ), + .ChimneyCfg ( RoBChimneyCfg ), // Needs RoB + .RouteCfg ( floo_test_pkg::RouteCfg ), + .AtopSupport ( floo_test_pkg::AtopSupport ), + .MaxAtomicTxns ( floo_test_pkg::MaxAtomicTxns ), + .axi_in_req_t ( axi_in_req_t ), + .axi_in_rsp_t ( axi_in_rsp_t ), + .axi_out_req_t ( axi_out_req_t ), + .axi_out_rsp_t ( axi_out_rsp_t ), + .rob_idx_t ( rob_idx_t ), + .id_t ( id_t ), + .hdr_t ( hdr_t ), + .floo_req_t ( floo_req_t ), + .floo_rsp_t ( floo_rsp_t ) ) i_floo_axi_chimney ( - .clk_i ( clk ), - .rst_ni ( rst_n ), - .sram_cfg_i ( '0 ), - .test_enable_i ( 1'b0 ), - .axi_in_req_i ( node_mst_req ), - .axi_in_rsp_o ( node_mst_rsp ), - .axi_out_req_o ( node_slv_req[Eject] ), - .axi_out_rsp_i ( node_slv_rsp[Eject] ), - .id_i ( xy_id[Eject] ), - .route_table_i ( '0 ), - .floo_req_o ( chimney_req_out[Eject] ), - .floo_rsp_o ( chimney_rsp_out[Eject] ), - .floo_req_i ( chimney_req_in[Eject] ), - .floo_rsp_i ( chimney_rsp_in[Eject] ) + .clk_i ( clk ), + .rst_ni ( rst_n ), + .sram_cfg_i ( '0 ), + .test_enable_i ( 1'b0 ), + .axi_in_req_i ( node_mst_req ), + .axi_in_rsp_o ( node_mst_rsp ), + .axi_out_req_o ( node_slv_req[floo_pkg::Eject] ), + .axi_out_rsp_i ( node_slv_rsp[floo_pkg::Eject] ), + .id_i ( xy_id[floo_pkg::Eject] ), + .route_table_i ( '0 ), + .floo_req_o ( chimney_req_out[floo_pkg::Eject] ), + .floo_rsp_o ( chimney_rsp_out[floo_pkg::Eject] ), + .floo_req_i ( chimney_req_in[floo_pkg::Eject] ), + .floo_rsp_i ( chimney_rsp_in[floo_pkg::Eject] ) ); floo_router #( - .NumRoutes ( NumDirections ), + .NumRoutes ( floo_pkg::NumDirections ), .NumVirtChannels ( 1 ), - .NumPhysChannels ( 1 ), .flit_t ( floo_req_generic_flit_t ), - .ChannelFifoDepth ( 4 ), - .RouteAlgo ( XYRouting ), + .InFifoDepth ( 2 ), + .RouteAlgo ( floo_pkg::XYRouting ), .id_t ( id_t ) ) i_floo_req_router ( - .clk_i ( clk ), - .rst_ni ( rst_n ), - .test_enable_i ( 1'b0 ), - .xy_id_i ( xy_id[Eject] ), - .id_route_map_i ( '0 ), - .valid_i ( chimney_req_out_valid ), - .ready_o ( chimney_req_in_ready ), - .data_i ( chimney_req_out_chan ), - .valid_o ( chimney_req_in_valid ), - .ready_i ( chimney_req_out_ready ), - .data_o ( chimney_req_in_chan ) + .clk_i ( clk ), + .rst_ni ( rst_n ), + .test_enable_i ( 1'b0 ), + .xy_id_i ( xy_id[floo_pkg::Eject] ), + .id_route_map_i ( '0 ), + .valid_i ( chimney_req_out_valid ), + .ready_o ( chimney_req_in_ready ), + .data_i ( chimney_req_out_chan ), + .valid_o ( chimney_req_in_valid ), + .ready_i ( chimney_req_out_ready ), + .data_o ( chimney_req_in_chan ) ); floo_router #( - .NumRoutes ( NumDirections ), + .NumRoutes ( floo_pkg::NumDirections ), .NumVirtChannels ( 1 ), - .NumPhysChannels ( 1 ), .flit_t ( floo_rsp_generic_flit_t ), - .ChannelFifoDepth ( 4 ), - .RouteAlgo ( XYRouting ), + .InFifoDepth ( 2 ), + .RouteAlgo ( floo_pkg::XYRouting ), .id_t ( id_t ) ) i_floo_rsp_router ( - .clk_i ( clk ), - .rst_ni ( rst_n ), - .test_enable_i ( 1'b0 ), - .xy_id_i ( xy_id[Eject] ), - .id_route_map_i ( '0 ), - .valid_i ( chimney_rsp_out_valid ), - .ready_o ( chimney_rsp_in_ready ), - .data_i ( chimney_rsp_out_chan ), - .valid_o ( chimney_rsp_in_valid ), - .ready_i ( chimney_rsp_out_ready ), - .data_o ( chimney_rsp_in_chan ) + .clk_i ( clk ), + .rst_ni ( rst_n ), + .test_enable_i ( 1'b0 ), + .xy_id_i ( xy_id[floo_pkg::Eject] ), + .id_route_map_i ( '0 ), + .valid_i ( chimney_rsp_out_valid ), + .ready_o ( chimney_rsp_in_ready ), + .data_i ( chimney_rsp_out_chan ), + .valid_o ( chimney_rsp_in_valid ), + .ready_i ( chimney_rsp_out_ready ), + .data_o ( chimney_rsp_in_chan ) ); - localparam slave_type_e SlaveType[NumDirections-1] = '{ - FastSlave, FastSlave, SlowSlave, MixedSlave}; + localparam floo_test_pkg::slave_type_e SlaveType[floo_pkg::NumDirections-1] = '{ + floo_test_pkg::FastSlave, + floo_test_pkg::FastSlave, + floo_test_pkg::SlowSlave, + floo_test_pkg::MixedSlave + }; for (genvar i = North; i <= West; i++) begin : gen_slaves if (i == North) begin : gen_north - assign xy_id[i] = '{x: 3'd1, y: 3'd2, port_id: 2'd0}; + assign xy_id[i] = '{x: 2'd1, y: 2'd2, port_id: 1'd0}; end else if (i == South) begin : gen_south - assign xy_id[i] = '{x: 3'd1, y: 3'd0, port_id: 2'd0}; + assign xy_id[i] = '{x: 2'd1, y: 2'd0, port_id: 1'd0}; end else if (i == East) begin : gen_east - assign xy_id[i] = '{x: 3'd2, y: 3'd1, port_id: 2'd0}; + assign xy_id[i] = '{x: 2'd2, y: 2'd1, port_id: 1'd0}; end else if (i == West) begin : gen_west - assign xy_id[i] = '{x: 3'd0, y: 3'd1, port_id: 2'd0}; + assign xy_id[i] = '{x: 2'd0, y: 2'd1, port_id: 1'd0}; end floo_axi_chimney #( - .MaxTxns ( MaxTxns ), - .MaxTxnsPerId ( MaxTxnsPerId ), - .ReorderBufferSize ( ReorderBufferSize ) + .AxiCfg ( floo_test_pkg::AxiCfg ), + .ChimneyCfg ( floo_test_pkg::ChimneyCfg ), // Does not need RoB + .RouteCfg ( floo_test_pkg::RouteCfg ), + .AtopSupport ( floo_test_pkg::AtopSupport ), + .MaxAtomicTxns ( floo_test_pkg::MaxAtomicTxns ), + .axi_in_req_t ( axi_in_req_t ), + .axi_in_rsp_t ( axi_in_rsp_t ), + .axi_out_req_t ( axi_out_req_t ), + .axi_out_rsp_t ( axi_out_rsp_t ), + .rob_idx_t ( rob_idx_t ), + .id_t ( id_t ), + .hdr_t ( hdr_t ), + .floo_req_t ( floo_req_t ), + .floo_rsp_t ( floo_rsp_t ) ) i_floo_axi_chimney ( .clk_i ( clk ), .rst_ni ( rst_n ), @@ -227,18 +279,31 @@ module tb_floo_rob; .floo_rsp_i ( chimney_rsp_in[i] ) ); + axi_dumper #( + .BusName ( $sformatf("Slave%0d", i)), + .LogAW ( 1'b0 ), + .LogAR ( 1'b0 ), + .LogW ( 1'b0 ), + .LogB ( 1'b0 ), + .LogR ( 1'b0 ), + .axi_req_t ( axi_in_req_t ), + .axi_resp_t ( axi_in_rsp_t ) + ) i_axi_dumper ( + .clk_i ( clk ), + .rst_ni ( rst_n ), + .axi_req_i ( node_slv_req[i] ), + .axi_resp_i ( node_slv_rsp[i] ) + ); + floo_axi_rand_slave #( - .AxiAddrWidth ( AxiOutAddrWidth ), - .AxiDataWidth ( AxiOutDataWidth ), - .AxiIdWidth ( AxiOutIdWidth ), - .AxiUserWidth ( AxiOutUserWidth ), - .axi_req_t ( axi_out_req_t ), - .axi_rsp_t ( axi_out_rsp_t ), - .ApplTime ( ApplTime ), - .TestTime ( TestTime ), - .SlaveType ( SlaveType[i] ), - .DstStartAddr ( 32'h0000_0000 ), // TODO: make this configurable - .DstEndAddr ( 32'h0000_8000 ) + .AxiCfg ( floo_test_pkg::AxiCfg ), + .axi_req_t ( axi_out_req_t ), + .axi_rsp_t ( axi_out_rsp_t ), + .ApplTime ( ApplTime ), + .TestTime ( TestTime ), + .SlaveType ( SlaveType[i] ), + .DstStartAddr ( 32'h0000_0000 ), // TODO: make this configurable + .DstEndAddr ( 32'h0000_8000 ) ) i_test_node_1 ( .clk_i ( clk ), .rst_ni ( rst_n ), @@ -251,28 +316,28 @@ module tb_floo_rob; end axi_reorder_compare #( - .NumSlaves ( NumSlaves ), - .AxiIdWidth ( AxiInIdWidth ), - .NumAddrRegions ( NumAddrRegions ), - .addr_t ( axi_in_addr_t ), - .rule_t ( node_addr_region_t ), - .AddrRegions ( AddrRegions ), - .aw_chan_t ( axi_in_aw_chan_t ), - .w_chan_t ( axi_in_w_chan_t ), - .b_chan_t ( axi_in_b_chan_t ), - .ar_chan_t ( axi_in_ar_chan_t ), - .r_chan_t ( axi_in_r_chan_t ), - .req_t ( axi_in_req_t ), - .rsp_t ( axi_in_rsp_t ), - .Verbose ( 1'b0 ) + .NumSlaves ( NumSlaves ), + .AxiIdWidth ( floo_test_pkg::AxiCfg.InIdWidth ), + .NumAddrRegions ( NumAddrRegions ), + .addr_t ( axi_addr_t ), + .rule_t ( node_addr_region_t ), + .AddrRegions ( AddrRegions ), + .aw_chan_t ( axi_in_aw_chan_t ), + .w_chan_t ( axi_in_w_chan_t ), + .b_chan_t ( axi_in_b_chan_t ), + .ar_chan_t ( axi_in_ar_chan_t ), + .r_chan_t ( axi_in_r_chan_t ), + .req_t ( axi_in_req_t ), + .rsp_t ( axi_in_rsp_t ), + .Verbose ( 1'b0 ) ) i_axi_reorder_compare ( - .clk_i ( clk ), - .rst_ni ( rst_n ), - .mon_mst_req_i ( node_mst_req ), - .mon_mst_rsp_i ( node_mst_rsp ), - .mon_slv_req_i ( node_slv_req_id_mapped[West:North] ), - .mon_slv_rsp_i ( node_slv_rsp_id_mapped[West:North] ), - .end_of_sim_o ( end_of_sim[1] ) + .clk_i ( clk ), + .rst_ni ( rst_n ), + .mon_mst_req_i ( node_mst_req ), + .mon_mst_rsp_i ( node_mst_rsp ), + .mon_slv_req_i ( node_slv_req_id_mapped[West:North] ), + .mon_slv_rsp_i ( node_slv_rsp_id_mapped[West:North] ), + .end_of_sim_o ( end_of_sim[1] ) ); initial begin diff --git a/hw/tb/tb_floo_router.sv b/hw/tb/tb_floo_router.sv index 61ac20f2..c72daa76 100644 --- a/hw/tb/tb_floo_router.sv +++ b/hw/tb/tb_floo_router.sv @@ -16,7 +16,6 @@ module tb_floo_router; import floo_pkg::*; - import floo_axi_pkg::*; localparam time CyclTime = 10ns; localparam time ApplTime = 2ns; @@ -42,6 +41,12 @@ module tb_floo_router; localparam int unsigned FlitWidth = 123; localparam int unsigned MaxPacketLength = 32; + typedef logic [FlitWidth-1:0] payload_t; + typedef logic [IdWidth-1:0] id_t; + + `FLOO_TYPEDEF_HDR_T(hdr_t, id_t, id_t, logic, logic) + `FLOO_TYPEDEF_GENERIC_FLIT_T(req, hdr_t, payload_t) + logic clk, rst_n; clk_rst_gen #( @@ -222,19 +227,19 @@ module tb_floo_router; floo_router #( - .NumRoutes ( NumPorts ), - .NumVirtChannels ( NumVirtChannels ), - .flit_t ( floo_req_generic_flit_t ), - .ChannelFifoDepth( 4 ), - .RouteAlgo ( IdIsPort ), - .IdWidth ( IdWidth ) + .NumRoutes ( NumPorts ), + .NumVirtChannels ( NumVirtChannels ), + .flit_t ( floo_req_generic_flit_t ), + .InFifoDepth ( 4 ), + .RouteAlgo ( SourceRouting ), + .IdWidth ( IdWidth ) ) i_dut ( .clk_i ( clk ), .rst_ni ( rst_n ), .test_enable_i ( '0 ), - .xy_id_i ( '0 ), // Unused for IdIsPort - .id_route_map_i( '0 ), // Unused for IdIsPort + .xy_id_i ( '0 ), // Unused for `SourceRouting` + .id_route_map_i( '0 ), // Unused for `SourceRouting` .valid_i ( valid_in ), .ready_o ( ready_in ), diff --git a/hw/tb/tb_floo_vc_dma_mesh.sv b/hw/tb/tb_floo_vc_dma_mesh.sv index a12294f1..8a4e6ad2 100644 --- a/hw/tb/tb_floo_vc_dma_mesh.sv +++ b/hw/tb/tb_floo_vc_dma_mesh.sv @@ -4,13 +4,12 @@ // // Author: Tim Fischer +`include "axi/typedef.svh" `include "floo_noc/typedef.svh" -`include "common_cells/assertions.svh" module tb_floo_vc_dma_mesh; import floo_pkg::*; - import floo_vc_narrow_wide_pkg::*; localparam time CyclTime = 10ns; localparam time ApplTime = 2ns; @@ -20,29 +19,30 @@ module tb_floo_vc_dma_mesh; localparam int unsigned NumY = 4; localparam int unsigned NumMax = (NumX > NumY) ? NumX : NumY; + typedef logic[$clog2(NumX+2)-1:0] x_bits_t; + typedef logic[$clog2(NumY+2)-1:0] y_bits_t; + typedef logic [2:0] vc_id_t; + `FLOO_TYPEDEF_XY_NODE_ID_T(id_t, x_bits_t, y_bits_t, logic) + `FLOO_TYPEDEF_VC_HDR_T(hdr_t, id_t, id_t, floo_pkg::nw_ch_e, logic, vc_id_t) + `FLOO_TYPEDEF_AXI_FROM_CFG(axi_narrow, floo_test_pkg::AxiCfgN) + `FLOO_TYPEDEF_AXI_FROM_CFG(axi_wide, floo_test_pkg::AxiCfgW) + `FLOO_TYPEDEF_NW_CHAN_ALL(axi, req, rsp, wide, axi_narrow_in, axi_wide_in, + floo_test_pkg::AxiCfgN, floo_test_pkg::AxiCfgW, hdr_t) + `FLOO_TYPEDEF_VC_NW_LINK_ALL(vc_req, vc_rsp, vc_wide, req, rsp, wide, vc_id_t) + + function automatic chimney_cfg_t gen_cut_rsp_cfg(); + chimney_cfg_t cfg = floo_pkg::ChimneyDefaultCfg; + cfg.CutRsp = 1'b1; + return cfg; + endfunction + + localparam chimney_cfg_t ChimneyCfg = gen_cut_rsp_cfg(); + localparam int unsigned HBMLatency = 100; - localparam axi_narrow_in_addr_t HBMSize = 48'h10000; // 64KB - localparam axi_narrow_in_addr_t MemSize = HBMSize; - - if (RouteAlgo == XYRouting) begin : gen_asserts - `ASSERT_INIT(NotEnoughXBits, $clog2(NumX + 2) <= $bits(x_bits_t)) - `ASSERT_INIT(NotEnoughYBits, $clog2(NumY + 2) <= $bits(y_bits_t)) - `ASSERT_INIT(NotEnoughAddrOffset, $clog2(HBMSize) <= XYAddrOffsetX) - end else begin : gen_error - $fatal(1, "This testbench only supports XYRouting"); - end + localparam axi_narrow_addr_t HBMSize = 48'h10000; // 64KB + localparam axi_narrow_addr_t MemSize = HBMSize; - // Narrow Wide Chimney parameters - localparam bit CutAx = 1'b1; - localparam bit CutRsp = 1'b1; - localparam int unsigned NarrowMaxTxnsPerId = 4; - localparam int unsigned NarrowReorderBufferSize = 32'd256; - localparam int unsigned WideMaxTxnsPerId = 32; - localparam int unsigned WideReorderBufferSize = 32'd64; - localparam int unsigned NarrowMaxTxns = 32; - localparam int unsigned WideMaxTxns = 32; - - localparam int unsigned ChannelFifoDepth = 2; // VCDepth + localparam int unsigned ChannelFifoDepth = 2; localparam int unsigned WormholeVCDepth = 3; // >= ChannelFifoDepth localparam int unsigned FixedWormholeVC = 1; // send all Wormhole flits to same VC localparam int unsigned AllowVCOverflow = 1; // 1: FVADA, 0: fixed VC, direction based @@ -112,21 +112,21 @@ module tb_floo_vc_dma_mesh; //////////////////////////////// floo_hbm_model #( - .TA ( ApplTime ), - .TT ( TestTime ), - .Latency ( HBMLatency ), - .NumChannels ( 1 ), - .AddrWidth ( AxiWideOutAddrWidth ), - .DataWidth ( AxiWideOutDataWidth ), - .UserWidth ( AxiWideOutUserWidth ), - .IdWidth ( AxiWideOutIdWidth ), - .axi_req_t ( axi_wide_out_req_t ), - .axi_rsp_t ( axi_wide_out_rsp_t ), - .aw_chan_t ( axi_wide_out_aw_chan_t ), - .w_chan_t ( axi_wide_out_w_chan_t ), - .b_chan_t ( axi_wide_out_b_chan_t ), - .ar_chan_t ( axi_wide_out_ar_chan_t ), - .r_chan_t ( axi_wide_out_r_chan_t ) + .TA ( ApplTime ), + .TT ( TestTime ), + .Latency ( HBMLatency ), + .NumChannels ( 1 ), + .AddrWidth ( floo_test_pkg::AxiCfgW.AddrWidth ), + .DataWidth ( floo_test_pkg::AxiCfgW.DataWidth ), + .UserWidth ( floo_test_pkg::AxiCfgW.UserWidth ), + .IdWidth ( floo_test_pkg::AxiCfgW.OutIdWidth ), + .axi_req_t ( axi_wide_out_req_t ), + .axi_rsp_t ( axi_wide_out_rsp_t ), + .aw_chan_t ( axi_wide_out_aw_chan_t ), + .w_chan_t ( axi_wide_out_w_chan_t ), + .b_chan_t ( axi_wide_out_b_chan_t ), + .ar_chan_t ( axi_wide_out_ar_chan_t ), + .r_chan_t ( axi_wide_out_r_chan_t ) ) i_floo_wide_hbm_model [West:North][NumMax-1:0] ( .clk_i ( clk ), .rst_ni ( rst_n ), @@ -135,21 +135,21 @@ module tb_floo_vc_dma_mesh; ); floo_hbm_model #( - .TA ( ApplTime ), - .TT ( TestTime ), - .Latency ( HBMLatency ), - .NumChannels ( 1 ), - .AddrWidth ( AxiNarrowOutAddrWidth ), - .DataWidth ( AxiNarrowOutDataWidth ), - .UserWidth ( AxiNarrowOutUserWidth ), - .IdWidth ( AxiNarrowOutIdWidth ), - .axi_req_t ( axi_narrow_out_req_t ), - .axi_rsp_t ( axi_narrow_out_rsp_t ), - .aw_chan_t ( axi_narrow_out_aw_chan_t ), - .w_chan_t ( axi_narrow_out_w_chan_t ), - .b_chan_t ( axi_narrow_out_b_chan_t ), - .ar_chan_t ( axi_narrow_out_ar_chan_t ), - .r_chan_t ( axi_narrow_out_r_chan_t ) + .TA ( ApplTime ), + .TT ( TestTime ), + .Latency ( HBMLatency ), + .NumChannels ( 1 ), + .AddrWidth ( floo_test_pkg::AxiCfgN.AddrWidth ), + .DataWidth ( floo_test_pkg::AxiCfgN.DataWidth ), + .UserWidth ( floo_test_pkg::AxiCfgN.UserWidth ), + .IdWidth ( floo_test_pkg::AxiCfgN.OutIdWidth ), + .axi_req_t ( axi_narrow_out_req_t ), + .axi_rsp_t ( axi_narrow_out_rsp_t ), + .aw_chan_t ( axi_narrow_out_aw_chan_t ), + .w_chan_t ( axi_narrow_out_w_chan_t ), + .b_chan_t ( axi_narrow_out_b_chan_t ), + .ar_chan_t ( axi_narrow_out_ar_chan_t ), + .r_chan_t ( axi_narrow_out_r_chan_t ) ) i_floo_narrow_hbm_model [West:North][NumMax-1:0] ( .clk_i ( clk ), .rst_ni ( rst_n ), @@ -212,22 +212,34 @@ module tb_floo_vc_dma_mesh; end floo_vc_narrow_wide_chimney #( - .NarrowMaxTxns ( NarrowMaxTxns ), - .WideMaxTxns ( WideMaxTxns ), - .NarrowReorderBufferSize ( NarrowReorderBufferSize ), - .WideReorderBufferSize ( WideReorderBufferSize ), - .CutAx ( CutAx ), - .CutRsp ( CutRsp ), - .NumRoutes ( int'(NumDirections) ), - .OutputDir ( route_direction_e'(i) ), - .NumVC (Only1VC? 1 : (i==North||i==South)? 2:4), - .InputFifoDepth ( WormholeVCDepth ), - .VCDepth ( ChannelFifoDepth ), - .CreditShortcut ( CreditShortcut ), - .AllowVCOverflow ( AllowVCOverflow ), - .FixedWormholeVC ( FixedWormholeVC ), - .WormholeVCId (i==East? 2: i==West? 1: 0), - .WormholeVCDepth ( WormholeVCDepth ) + .AxiCfgN ( floo_test_pkg::AxiCfgN ), + .AxiCfgW ( floo_test_pkg::AxiCfgW ), + .ChimneyCfgN ( ChimneyCfg ), + .ChimneyCfgW ( ChimneyCfg ), + .RouteCfg ( floo_test_pkg::RouteCfg ), + .OutputDir ( route_direction_e'(i) ), + .NumVC ( Only1VC? 1 : (i==North||i==South)? 2:4 ), + .InputFifoDepth ( WormholeVCDepth ), + .VCDepth ( ChannelFifoDepth ), + .CreditShortcut ( CreditShortcut ), + .AllowVCOverflow ( AllowVCOverflow ), + .FixedWormholeVC ( FixedWormholeVC ), + .WormholeVCId ( i==East? 2: i==West? 1: 0 ), + .WormholeVCDepth ( WormholeVCDepth ), + .hdr_t ( hdr_t ), + .id_t ( id_t ), + .vc_id_t ( vc_id_t ), + .axi_narrow_in_req_t ( axi_narrow_in_req_t ), + .axi_narrow_in_rsp_t ( axi_narrow_in_rsp_t ), + .axi_narrow_out_req_t ( axi_narrow_out_req_t ), + .axi_narrow_out_rsp_t ( axi_narrow_out_rsp_t ), + .axi_wide_in_req_t ( axi_wide_in_req_t ), + .axi_wide_in_rsp_t ( axi_wide_in_rsp_t ), + .axi_wide_out_req_t ( axi_wide_out_req_t ), + .axi_wide_out_rsp_t ( axi_wide_out_rsp_t ), + .floo_vc_req_t ( floo_vc_req_t ), + .floo_vc_rsp_t ( floo_vc_rsp_t ), + .floo_vc_wide_t ( floo_vc_wide_t ) ) i_hbm_chimney [NumChimneys-1:0] ( .clk_i ( clk ), .rst_ni ( rst_n ), @@ -269,26 +281,23 @@ module tb_floo_vc_dma_mesh; floo_vc_wide_t [NumDirections-1:0] wide_out, wide_in; localparam int unsigned Index = y * NumX + x+1; - localparam logic [AxiNarrowInAddrWidth-1:0] MemBaseAddr = - (x+1) << XYAddrOffsetX | (y+1) << XYAddrOffsetY; + localparam axi_narrow_addr_t MemBaseAddr = + (x+1) << floo_test_pkg::RouteCfg.XYAddrOffsetX | + (y+1) << floo_test_pkg::RouteCfg.XYAddrOffsetY; assign current_id = '{x: x+1, y: y+1, port_id: 0}; floo_dma_test_node #( - .TA ( ApplTime ), - .TT ( TestTime ), - .DataWidth ( AxiNarrowInDataWidth ), - .AddrWidth ( AxiNarrowInAddrWidth ), - .UserWidth ( AxiNarrowInUserWidth ), - .AxiIdInWidth ( AxiNarrowOutIdWidth ), - .AxiIdOutWidth ( AxiNarrowInIdWidth ), - .MemBaseAddr ( MemBaseAddr ), - .MemSize ( MemSize ), - .NumAxInFlight ( 2*NarrowMaxTxnsPerId ), - .axi_in_req_t ( axi_narrow_out_req_t ), - .axi_in_rsp_t ( axi_narrow_out_rsp_t ), - .axi_out_req_t ( axi_narrow_in_req_t ), - .axi_out_rsp_t ( axi_narrow_in_rsp_t ), - .JobId ( 100 + Index ) + .TA ( ApplTime ), + .TT ( TestTime ), + .AxiCfg ( axi_cfg_swap_iw(floo_test_pkg::AxiCfgN) ), + .MemBaseAddr ( MemBaseAddr ), + .MemSize ( MemSize ), + .NumAxInFlight ( 2*floo_test_pkg::ChimneyCfg.MaxTxnsPerId ), + .axi_in_req_t ( axi_narrow_out_req_t ), + .axi_in_rsp_t ( axi_narrow_out_rsp_t ), + .axi_out_req_t ( axi_narrow_in_req_t ), + .axi_out_rsp_t ( axi_narrow_in_rsp_t ), + .JobId ( 100 + Index ) ) i_narrow_dma_node ( .clk_i ( clk ), .rst_ni ( rst_n ), @@ -300,21 +309,17 @@ module tb_floo_vc_dma_mesh; ); floo_dma_test_node #( - .TA ( ApplTime ), - .TT ( TestTime ), - .DataWidth ( AxiWideInDataWidth ), - .AddrWidth ( AxiWideInAddrWidth ), - .UserWidth ( AxiWideInUserWidth ), - .AxiIdInWidth ( AxiWideOutIdWidth ), - .AxiIdOutWidth ( AxiWideInIdWidth ), - .MemBaseAddr ( MemBaseAddr ), - .MemSize ( MemSize ), - .NumAxInFlight ( 2*WideMaxTxnsPerId ), - .axi_in_req_t ( axi_wide_out_req_t ), - .axi_in_rsp_t ( axi_wide_out_rsp_t ), - .axi_out_req_t ( axi_wide_in_req_t ), - .axi_out_rsp_t ( axi_wide_in_rsp_t ), - .JobId ( Index ) + .TA ( ApplTime ), + .TT ( TestTime ), + .AxiCfg ( axi_cfg_swap_iw(floo_test_pkg::AxiCfgW) ), + .MemBaseAddr ( MemBaseAddr ), + .MemSize ( MemSize ), + .NumAxInFlight ( 2*floo_test_pkg::ChimneyCfg.MaxTxnsPerId ), + .axi_in_req_t ( axi_wide_out_req_t ), + .axi_in_rsp_t ( axi_wide_out_rsp_t ), + .axi_out_req_t ( axi_wide_in_req_t ), + .axi_out_rsp_t ( axi_wide_in_rsp_t ), + .JobId ( Index ) ) i_wide_dma_node ( .clk_i ( clk ), .rst_ni ( rst_n ), @@ -326,10 +331,10 @@ module tb_floo_vc_dma_mesh; ); axi_bw_monitor #( - .req_t ( axi_narrow_in_req_t ), - .rsp_t ( axi_narrow_in_rsp_t ), - .AxiIdWidth ( AxiNarrowInIdWidth ), - .Name ( NarrowDmaName ) + .req_t ( axi_narrow_in_req_t ), + .rsp_t ( axi_narrow_in_rsp_t ), + .AxiIdWidth ( floo_test_pkg::AxiCfgN.InIdWidth ), + .Name ( NarrowDmaName ) ) i_axi_narrow_bw_monitor ( .clk_i ( clk ), .en_i ( rst_n ), @@ -341,10 +346,10 @@ module tb_floo_vc_dma_mesh; ); axi_bw_monitor #( - .req_t ( axi_wide_in_req_t ), - .rsp_t ( axi_wide_in_rsp_t ), - .AxiIdWidth ( AxiWideInIdWidth ), - .Name ( WideDmaName ) + .req_t ( axi_wide_in_req_t ), + .rsp_t ( axi_wide_in_rsp_t ), + .AxiIdWidth ( floo_test_pkg::AxiCfgW.InIdWidth ), + .Name ( WideDmaName ) ) i_axi_wide_bw_monitor ( .clk_i ( clk ), .en_i ( rst_n ), @@ -356,22 +361,34 @@ module tb_floo_vc_dma_mesh; ); floo_vc_narrow_wide_chimney #( - .NarrowMaxTxns ( NarrowMaxTxns ), - .WideMaxTxns ( WideMaxTxns ), - .NarrowReorderBufferSize ( NarrowReorderBufferSize ), - .WideReorderBufferSize ( WideReorderBufferSize ), - .CutAx ( CutAx ), - .CutRsp ( CutRsp ), - .NumRoutes ( int'(NumDirections) ), - .OutputDir ( Eject ), - .InputFifoDepth ( WormholeVCDepth ), - .NumVC ( NumVCLocal ), - .VCDepth ( ChannelFifoDepth ), - .CreditShortcut ( CreditShortcut ), - .AllowVCOverflow ( AllowVCOverflow ), - .FixedWormholeVC ( FixedWormholeVC ), - .WormholeVCId ( 0 ), - .WormholeVCDepth ( WormholeVCDepth ) + .AxiCfgN ( floo_test_pkg::AxiCfgN ), + .AxiCfgW ( floo_test_pkg::AxiCfgW ), + .ChimneyCfgN ( ChimneyCfg ), + .ChimneyCfgW ( ChimneyCfg ), + .RouteCfg ( floo_test_pkg::RouteCfg ), + .OutputDir ( Eject ), + .InputFifoDepth ( WormholeVCDepth ), + .NumVC ( NumVCLocal ), + .VCDepth ( ChannelFifoDepth ), + .CreditShortcut ( CreditShortcut ), + .AllowVCOverflow ( AllowVCOverflow ), + .FixedWormholeVC ( FixedWormholeVC ), + .WormholeVCId ( 0 ), + .WormholeVCDepth ( WormholeVCDepth ), + .hdr_t ( hdr_t ), + .id_t ( id_t ), + .vc_id_t ( vc_id_t ), + .axi_narrow_in_req_t ( axi_narrow_in_req_t ), + .axi_narrow_in_rsp_t ( axi_narrow_in_rsp_t ), + .axi_narrow_out_req_t ( axi_narrow_out_req_t ), + .axi_narrow_out_rsp_t ( axi_narrow_out_rsp_t ), + .axi_wide_in_req_t ( axi_wide_in_req_t ), + .axi_wide_in_rsp_t ( axi_wide_in_rsp_t ), + .axi_wide_out_req_t ( axi_wide_out_req_t ), + .axi_wide_out_rsp_t ( axi_wide_out_rsp_t ), + .floo_vc_req_t ( floo_vc_req_t ), + .floo_vc_rsp_t ( floo_vc_rsp_t ), + .floo_vc_wide_t ( floo_vc_wide_t ) ) i_dma_chimney ( .clk_i ( clk ), .rst_ni ( rst_n ), @@ -397,12 +414,16 @@ module tb_floo_vc_dma_mesh; ); floo_vc_narrow_wide_router #( + .AxiCfgN ( floo_test_pkg::AxiCfgN ), + .AxiCfgW ( floo_test_pkg::AxiCfgW ), .NumPorts ( int'(NumDirections) ), .NumVC ( Only1VC ? {1, 1, 1, 1, NumVCLocal} : {2, 4, 2, 4, NumVCLocal} ), - .RouteAlgo ( RouteAlgo ), + .RouteAlgo ( floo_test_pkg::RouteCfg.RouteAlgo ), .id_t ( id_t ), + .hdr_t ( hdr_t ), + .vc_id_t ( vc_id_t ), .NumVCToOut ( Only1VC ? {1, 1, 1, 1, 1} : {y==NumY-1 ? 1 : 2, x==NumX-1 ? 1 : 4, @@ -418,7 +439,10 @@ module tb_floo_vc_dma_mesh; .AllowOverflowFromDeeperVC (AllowOverflowFromDeeperVC), .WormholeVCId ( Only1VC? {0, 0, 0, 0, 0} : - {0, 1, 0, 2, 0} ) + {0, 1, 0, 2, 0} ), + .floo_vc_req_t ( floo_vc_req_t ), + .floo_vc_rsp_t ( floo_vc_rsp_t ), + .floo_vc_wide_t ( floo_vc_wide_t ) ) i_router ( .clk_i ( clk ), .rst_ni ( rst_n ), diff --git a/hw/tb/tb_floo_vc_router.sv b/hw/tb/tb_floo_vc_router.sv index e58871a3..82c2aeb1 100644 --- a/hw/tb/tb_floo_vc_router.sv +++ b/hw/tb/tb_floo_vc_router.sv @@ -8,14 +8,21 @@ module tb_floo_vc_router; import floo_pkg::*; - import floo_vc_axi_pkg::*; localparam time CyclTime = 10ns; localparam time ApplTime = 2ns; localparam time TestTime = 8ns; + typedef logic [2:0] x_bits_t; + typedef logic [2:0] y_bits_t; + typedef logic [1:0] port_id_t; + typedef logic [2:0] vc_id_t; + typedef logic [63:0] payload_t; + `FLOO_TYPEDEF_XY_NODE_ID_T(id_t, x_bits_t, y_bits_t, port_id_t) + `FLOO_TYPEDEF_VC_HDR_T(hdr_t, id_t, id_t, logic, logic, vc_id_t) + `FLOO_TYPEDEF_GENERIC_FLIT_T(req, hdr_t, payload_t) + localparam type flit_t = floo_req_generic_flit_t; - localparam type payload_t = floo_req_payload_t; localparam int NumVCWidth = 2; localparam int NumPorts = 5; localparam int Debug = 0; diff --git a/hw/tb/wave/tb_floo_dma_mesh.wave.tcl b/hw/tb/wave/tb_floo_dma_mesh.wave.tcl index eb942b2a..6d57341d 100644 --- a/hw/tb/wave/tb_floo_dma_mesh.wave.tcl +++ b/hw/tb/wave/tb_floo_dma_mesh.wave.tcl @@ -8,7 +8,7 @@ floo_wave_init set tb_name tb_floo_dma_mesh -set routers [find instances -bydu floo_narrow_wide_router -nodu] +set routers [find instances -bydu floo_nw_router -nodu] set num_y [regexp -all {x\[0\]} $routers] set num_x [regexp -all {y\[0\]} $routers] @@ -25,17 +25,17 @@ for {set y 0} {$y < $num_y} {incr y} { for {set y 0} {$y < $num_y} {incr y} { # East - floo_narrow_wide_chimney_wave $tb_name/gen_hbm_chimneys[2]/i_hbm_chimney[$y] [list HBM East "Channel ${y}" Chimney] 1 + floo_narrow_wide_chimney_wave $tb_name/gen_hbm_chimneys[1]/i_hbm_chimney[$y] [list HBM East "Channel ${y}" Chimney] 1 # West - floo_narrow_wide_chimney_wave $tb_name/gen_hbm_chimneys[4]/i_hbm_chimney[$y] [list HBM West "Channel ${y}" Chimney] 1 + floo_narrow_wide_chimney_wave $tb_name/gen_hbm_chimneys[3]/i_hbm_chimney[$y] [list HBM West "Channel ${y}" Chimney] 1 } for {set x 0} {$x < $num_x} {incr x} { # North - floo_narrow_wide_chimney_wave $tb_name/gen_hbm_chimneys[1]/i_hbm_chimney[$x] [list HBM North "Channel ${x}" Chimney] 1 + floo_narrow_wide_chimney_wave $tb_name/gen_hbm_chimneys[0]/i_hbm_chimney[$x] [list HBM North "Channel ${x}" Chimney] 1 # South - floo_narrow_wide_chimney_wave $tb_name/gen_hbm_chimneys[3]/i_hbm_chimney[$x] [list HBM South "Channel ${x}" Chimney] 1 + floo_narrow_wide_chimney_wave $tb_name/gen_hbm_chimneys[2]/i_hbm_chimney[$x] [list HBM South "Channel ${x}" Chimney] 1 } floo_wave_style diff --git a/hw/tb/wave/tb_floo_dma_nw_chimney.wave.tcl b/hw/tb/wave/tb_floo_dma_nw_chimney.wave.tcl deleted file mode 100644 index 21b3d5eb..00000000 --- a/hw/tb/wave/tb_floo_dma_nw_chimney.wave.tcl +++ /dev/null @@ -1,15 +0,0 @@ -# Copyright 2023 ETH Zurich and University of Bologna. -# Solderpad Hardware License, Version 0.51, see LICENSE for details. -# SPDX-License-Identifier: SHL-0.51 - -source hw/tb/wave/wave.tcl - -floo_wave_init - -for {set i 0} {$i < 2} {incr i} { - set name [list "Chimney $i"] - set dut tb_floo_dma_nw_chimney/i_floo_narrow_wide_chimney_${i} - floo_narrow_wide_chimney_wave $dut $name -} - -floo_wave_style diff --git a/hw/tb/wave/tb_floo_narrow_wide_chimney.wave.tcl b/hw/tb/wave/tb_floo_nw_chimney.wave.tcl similarity index 100% rename from hw/tb/wave/tb_floo_narrow_wide_chimney.wave.tcl rename to hw/tb/wave/tb_floo_nw_chimney.wave.tcl diff --git a/hw/tb/wave/tb_floo_rob.wave.tcl b/hw/tb/wave/tb_floo_rob.wave.tcl index 269001ce..945ab797 100644 --- a/hw/tb/wave/tb_floo_rob.wave.tcl +++ b/hw/tb/wave/tb_floo_rob.wave.tcl @@ -8,9 +8,8 @@ floo_wave_init floo_axi_chimney_wave tb_floo_rob/i_floo_axi_chimney [list MstChimney] -for {set i 1} {$i <= 4} {incr i} { - set id [expr $i - 1] - set groups [list SlvChimney${id}] +for {set i 0} {$i < 4} {incr i} { + set groups [list SlvChimney${i}] floo_axi_chimney_wave tb_floo_rob/gen_slaves[${i}]/i_floo_axi_chimney $groups 0 } diff --git a/hw/tb/wave/tb_floo_vc_dma_mesh.wave.tcl b/hw/tb/wave/tb_floo_vc_dma_mesh.wave.tcl new file mode 100644 index 00000000..4ac58083 --- /dev/null +++ b/hw/tb/wave/tb_floo_vc_dma_mesh.wave.tcl @@ -0,0 +1,41 @@ +# Copyright 2023 ETH Zurich and University of Bologna. +# Solderpad Hardware License, Version 0.51, see LICENSE for details. +# SPDX-License-Identifier: SHL-0.51 + +source hw/tb/wave/wave.tcl + +floo_wave_init + +set tb_name tb_floo_vc_dma_mesh + +set routers [find instances -bydu floo_vc_narrow_wide_router -nodu] +set num_y [regexp -all {x\[0\]} $routers] +set num_x [regexp -all {y\[0\]} $routers] + +for {set y 0} {$y < $num_y} {incr y} { + for {set x 0} {$x < $num_x} {incr x} { + set groups [list Node X=${x} Y=${y}] + floo_vc_narrow_wide_chimney_wave $tb_name/gen_x[$x]/gen_y[$y]/i_dma_chimney [concat $groups [list Chimney]] + floo_router_wave $tb_name/gen_x[$x]/gen_y[$y]/i_router [concat $groups [list Router]] + + floo_add_wave $tb_name/gen_x[$x]/gen_y[$y]/i_axi_narrow_bw_monitor/*in_flight_o $groups 1 + floo_add_wave $tb_name/gen_x[$x]/gen_y[$y]/i_axi_wide_bw_monitor/*in_flight_o $groups 1 + } +} + +for {set y 0} {$y < $num_y} {incr y} { + # East + floo_vc_narrow_wide_chimney_wave $tb_name/gen_hbm_chimneys[1]/i_hbm_chimney[$y] [list HBM East "Channel ${y}" Chimney] + # West + floo_vc_narrow_wide_chimney_wave $tb_name/gen_hbm_chimneys[3]/i_hbm_chimney[$y] [list HBM West "Channel ${y}" Chimney] + +} + +for {set x 0} {$x < $num_x} {incr x} { + # North + floo_vc_narrow_wide_chimney_wave $tb_name/gen_hbm_chimneys[0]/i_hbm_chimney[$x] [list HBM North "Channel ${x}" Chimney] + # South + floo_vc_narrow_wide_chimney_wave $tb_name/gen_hbm_chimneys[2]/i_hbm_chimney[$x] [list HBM South "Channel ${x}" Chimney] +} + +floo_wave_style diff --git a/hw/tb/wave/wave.tcl b/hw/tb/wave/wave.tcl index b343ab20..96066db0 100644 --- a/hw/tb/wave/wave.tcl +++ b/hw/tb/wave/wave.tcl @@ -147,6 +147,10 @@ proc floo_narrow_wide_chimney_wave {dut groups {expand 1}} { } } +proc floo_vc_narrow_wide_chimney_wave {dut groups} { + floo_add_wave $dut/* $groups +} + proc floo_router_wave {dut groups} { floo_add_wave $dut/* $groups } diff --git a/hw/test/floo_axi_rand_slave.sv b/hw/test/floo_axi_rand_slave.sv index 1746273f..bee2d0fb 100644 --- a/hw/test/floo_axi_rand_slave.sv +++ b/hw/test/floo_axi_rand_slave.sv @@ -8,25 +8,18 @@ `include "axi/typedef.svh" /// A AXI4 Bus Multi-Slave generating random AXI respones with configurable response time -module floo_axi_rand_slave - import floo_test_pkg::*; -#( - parameter int unsigned AxiAddrWidth = 0, - parameter int unsigned AxiDataWidth = 0, - parameter int unsigned AxiIdWidth = 0, - parameter int unsigned AxiUserWidth = 0, +module floo_axi_rand_slave #( + parameter floo_pkg::axi_cfg_t AxiCfg = '0, parameter type axi_req_t = logic, parameter type axi_rsp_t = logic, - // Dependent parameter, DO NOT OVERWRITE! - parameter int unsigned AxiStrbWidth = AxiDataWidth/8, // TB Parameters parameter time ApplTime = 2ns, parameter time TestTime = 8ns, - parameter logic[AxiAddrWidth-1:0] DstStartAddr = '0, - parameter logic[AxiAddrWidth-1:0] DstEndAddr = '1, - parameter slave_type_e SlaveType = MixedSlave, + parameter logic[AxiCfg.AddrWidth-1:0] DstStartAddr = '0, + parameter logic[AxiCfg.AddrWidth-1:0] DstEndAddr = '1, + parameter floo_test_pkg::slave_type_e SlaveType = floo_test_pkg::MixedSlave, parameter int unsigned NumSlaves = 4, - localparam logic[AxiAddrWidth-1:0] SlvAddrSpace = (DstEndAddr - DstStartAddr) / NumSlaves + localparam logic[AxiCfg.AddrWidth-1:0] SlvAddrSpace = (DstEndAddr - DstStartAddr) / NumSlaves ) ( input logic clk_i, input logic rst_ni, @@ -38,25 +31,25 @@ module floo_axi_rand_slave output axi_rsp_t [NumSlaves-1:0] mon_mst_port_rsp_o ); - typedef logic [AxiAddrWidth-1:0] addr_t; - typedef logic [AxiDataWidth-1:0] data_t; - typedef logic [AxiStrbWidth-1:0] strb_t; - typedef logic [AxiIdWidth-1:0] id_t; - typedef logic [AxiUserWidth-1:0] user_t; + typedef logic [AxiCfg.AddrWidth-1:0] addr_t; + typedef logic [AxiCfg.DataWidth-1:0] data_t; + typedef logic [AxiCfg.DataWidth/8-1:0] strb_t; + typedef logic [AxiCfg.OutIdWidth-1:0] id_t; + typedef logic [AxiCfg.UserWidth-1:0] user_t; `AXI_TYPEDEF_ALL(axi_xbar, addr_t, id_t, data_t, strb_t, user_t) AXI_BUS_DV #( - .AXI_ADDR_WIDTH ( AxiAddrWidth ), - .AXI_DATA_WIDTH ( AxiDataWidth ), - .AXI_ID_WIDTH ( AxiIdWidth ), - .AXI_USER_WIDTH ( AxiUserWidth ) + .AXI_ADDR_WIDTH ( AxiCfg.AddrWidth ), + .AXI_DATA_WIDTH ( AxiCfg.DataWidth ), + .AXI_ID_WIDTH ( AxiCfg.OutIdWidth ), + .AXI_USER_WIDTH ( AxiCfg.UserWidth ) ) slave_dv [NumSlaves] (clk_i); typedef struct packed { logic [31:0] idx; - logic [AxiAddrWidth-1:0] start_addr; - logic [AxiAddrWidth-1:0] end_addr; + logic [AxiCfg.AddrWidth-1:0] start_addr; + logic [AxiCfg.AddrWidth-1:0] end_addr; } xbar_rule_t; xbar_rule_t [NumSlaves-1:0] XbarAddrMap; @@ -76,11 +69,11 @@ module floo_axi_rand_slave FallThrough: 1, LatencyMode: axi_pkg::CUT_ALL_PORTS, PipelineStages: 0, - AxiIdWidthSlvPorts: AxiIdWidth, - AxiIdUsedSlvPorts: AxiIdWidth, + AxiIdWidthSlvPorts: AxiCfg.OutIdWidth, + AxiIdUsedSlvPorts: AxiCfg.OutIdWidth, UniqueIds: 0, - AxiAddrWidth: AxiAddrWidth, - AxiDataWidth: AxiDataWidth, + AxiAddrWidth: AxiCfg.AddrWidth, + AxiDataWidth: AxiCfg.DataWidth, NoAddrRules: NumSlaves }; @@ -90,34 +83,34 @@ module floo_axi_rand_slave axi_xbar_resp_t [NumSlaves-1:0] xbar_out_rsp; axi_xbar #( - .Cfg (XbarCfg), - .Connectivity ('1), - .ATOPs (0), - .slv_aw_chan_t(axi_xbar_aw_chan_t), - .mst_aw_chan_t(axi_xbar_aw_chan_t), - .w_chan_t (axi_xbar_w_chan_t ), - .slv_b_chan_t (axi_xbar_b_chan_t ), - .mst_b_chan_t (axi_xbar_b_chan_t ), - .slv_ar_chan_t(axi_xbar_ar_chan_t), - .mst_ar_chan_t(axi_xbar_ar_chan_t), - .slv_r_chan_t (axi_xbar_r_chan_t ), - .mst_r_chan_t (axi_xbar_r_chan_t ), - .slv_req_t (axi_xbar_req_t ), - .slv_resp_t (axi_xbar_resp_t ), - .mst_req_t (axi_xbar_req_t ), - .mst_resp_t (axi_xbar_resp_t ), - .rule_t (xbar_rule_t) + .Cfg ( XbarCfg ), + .Connectivity ( '1 ), + .ATOPs ( 0 ), + .slv_aw_chan_t ( axi_xbar_aw_chan_t ), + .mst_aw_chan_t ( axi_xbar_aw_chan_t ), + .w_chan_t ( axi_xbar_w_chan_t ), + .slv_b_chan_t ( axi_xbar_b_chan_t ), + .mst_b_chan_t ( axi_xbar_b_chan_t ), + .slv_ar_chan_t ( axi_xbar_ar_chan_t ), + .mst_ar_chan_t ( axi_xbar_ar_chan_t ), + .slv_r_chan_t ( axi_xbar_r_chan_t ), + .mst_r_chan_t ( axi_xbar_r_chan_t ), + .slv_req_t ( axi_xbar_req_t ), + .slv_resp_t ( axi_xbar_resp_t ), + .mst_req_t ( axi_xbar_req_t ), + .mst_resp_t ( axi_xbar_resp_t ), + .rule_t ( xbar_rule_t ) ) i_xbar ( - .clk_i (clk_i), - .rst_ni (rst_ni), - .test_i (1'b0), - .slv_ports_req_i (xbar_in_req), - .slv_ports_resp_o (xbar_in_rsp), - .mst_ports_req_o (xbar_out_req), - .mst_ports_resp_i (xbar_out_rsp), - .addr_map_i (XbarAddrMap), - .en_default_mst_port_i('1), - .default_mst_port_i ('0) + .clk_i ( clk_i ), + .rst_ni ( rst_ni ), + .test_i ( 1'b0 ), + .slv_ports_req_i ( xbar_in_req ), + .slv_ports_resp_o ( xbar_in_rsp ), + .mst_ports_req_o ( xbar_out_req ), + .mst_ports_resp_i ( xbar_out_rsp ), + .addr_map_i ( XbarAddrMap ), + .en_default_mst_port_i ( '1 ), + .default_mst_port_i ( '0 ) ); assign xbar_in_req = slv_port_req_i; @@ -132,24 +125,24 @@ module floo_axi_rand_slave typedef axi_test::axi_rand_slave #( // AXI interface parameters - .AW ( AxiAddrWidth ), - .DW ( AxiDataWidth ), - .IW ( AxiIdWidth ), - .UW ( AxiUserWidth ), + .AW ( AxiCfg.AddrWidth ), + .DW ( AxiCfg.DataWidth ), + .IW ( AxiCfg.OutIdWidth ), + .UW ( AxiCfg.UserWidth ), // Stimuli application and test time - .TA ( ApplTime ), - .TT ( TestTime ) + .TA ( ApplTime ), + .TT ( TestTime ) ) axi_rand_slave_t; typedef axi_test::axi_rand_slave #( // AXI interface parameters - .AW ( AxiAddrWidth ), - .DW ( AxiDataWidth ), - .IW ( AxiIdWidth ), - .UW ( AxiUserWidth ), + .AW ( AxiCfg.AddrWidth ), + .DW ( AxiCfg.DataWidth ), + .IW ( AxiCfg.OutIdWidth ), + .UW ( AxiCfg.UserWidth ), // Stimuli application and test time - .TA ( ApplTime ), - .TT ( TestTime ), + .TA ( ApplTime ), + .TT ( TestTime ), // Responsiveness .AX_MIN_WAIT_CYCLES (0), .AX_MAX_WAIT_CYCLES (5), @@ -161,13 +154,13 @@ module floo_axi_rand_slave typedef axi_test::axi_rand_slave #( // AXI interface parameters - .AW ( AxiAddrWidth ), - .DW ( AxiDataWidth ), - .IW ( AxiIdWidth ), - .UW ( AxiUserWidth ), + .AW ( AxiCfg.AddrWidth ), + .DW ( AxiCfg.DataWidth ), + .IW ( AxiCfg.OutIdWidth ), + .UW ( AxiCfg.UserWidth ), // Stimuli application and test time - .TA ( ApplTime ), - .TT ( TestTime ), + .TA ( ApplTime ), + .TT ( TestTime ), // Responsiveness .AX_MIN_WAIT_CYCLES (50), .AX_MAX_WAIT_CYCLES (100), @@ -181,7 +174,7 @@ module floo_axi_rand_slave axi_rand_slow_slave_t axi_rand_slow_slave[NumSlaves]; axi_rand_fast_slave_t axi_rand_fast_slave[NumSlaves]; - if (SlaveType == SlowSlave) begin : gen_slow_slaves + if (SlaveType == floo_test_pkg::SlowSlave) begin : gen_slow_slaves for (genvar i = 0; i < NumSlaves; i++) begin : gen_slow_slaves initial begin axi_rand_slow_slave[i] = new( slave_dv[i] ); @@ -190,7 +183,7 @@ module floo_axi_rand_slave axi_rand_slow_slave[i].run(); end end - end else if (SlaveType == FastSlave) begin : gen_fast_slaves + end else if (SlaveType == floo_test_pkg::FastSlave) begin : gen_fast_slaves for (genvar i = 0; i < NumSlaves; i++) begin : gen_fast_slaves initial begin axi_rand_fast_slave[i] = new( slave_dv[i] ); @@ -199,7 +192,7 @@ module floo_axi_rand_slave axi_rand_fast_slave[i].run(); end end - end else if (SlaveType == MixedSlave) begin : gen_mixed_slaves + end else if (SlaveType == floo_test_pkg::MixedSlave) begin : gen_mixed_slaves for (genvar i = 0; i < NumSlaves; i++) begin : gen_mixed_slaves if (i % 2 == 0) begin : gen_slow_slaves initial begin diff --git a/hw/test/floo_axi_test_node.sv b/hw/test/floo_axi_test_node.sv index 72adf292..200b6df4 100644 --- a/hw/test/floo_axi_test_node.sv +++ b/hw/test/floo_axi_test_node.sv @@ -8,23 +8,17 @@ /// A AXI4 Bus Master-Slave Node for generating random AXI transactions module floo_axi_test_node #( - parameter int unsigned AxiAddrWidth = 0, - parameter int unsigned AxiDataWidth = 0, - parameter int unsigned AxiIdInWidth = 0, - parameter int unsigned AxiIdOutWidth = 0, - parameter int unsigned AxiUserWidth = 0, + parameter floo_pkg::axi_cfg_t AxiCfg = '{default:0}, parameter type mst_req_t = logic, parameter type mst_rsp_t = logic, parameter type slv_req_t = logic, parameter type slv_rsp_t = logic, - // Dependent parameter, DO NOT OVERWRITE! - parameter int unsigned AxiStrbWidth = AxiDataWidth/8, // TB Parameters parameter time ApplTime = 2ns, parameter time TestTime = 8ns, parameter bit Atops = 1'b0, parameter int unsigned AxiMaxBurstLen = 128, - parameter int unsigned NumAddrRegions = 1, + parameter int unsigned NumAddrRegions = 0, parameter type rule_t = logic, parameter rule_t [NumAddrRegions-1:0] AddrRegions = '0, parameter int unsigned NumReads = 0, @@ -41,11 +35,12 @@ module floo_axi_test_node #( output logic end_of_sim ); + AXI_BUS_DV #( - .AXI_ADDR_WIDTH ( AxiAddrWidth ), - .AXI_DATA_WIDTH ( AxiDataWidth ), - .AXI_ID_WIDTH ( AxiIdOutWidth ), - .AXI_USER_WIDTH ( AxiUserWidth ) + .AXI_ADDR_WIDTH ( AxiCfg.AddrWidth ), + .AXI_DATA_WIDTH ( AxiCfg.DataWidth ), + .AXI_ID_WIDTH ( AxiCfg.OutIdWidth ), + .AXI_USER_WIDTH ( AxiCfg.UserWidth ) ) master_dv (clk_i); `AXI_ASSIGN_TO_REQ(mst_port_req_o, master_dv) @@ -53,10 +48,10 @@ module floo_axi_test_node #( typedef axi_test::axi_rand_master #( // AXI interface parameters - .AW ( AxiAddrWidth ), - .DW ( AxiDataWidth ), - .IW ( AxiIdOutWidth ), - .UW ( AxiUserWidth ), + .AW ( AxiCfg.AddrWidth ), + .DW ( AxiCfg.DataWidth ), + .IW ( AxiCfg.OutIdWidth ), + .UW ( AxiCfg.UserWidth ), // Stimuli application and test time .TA ( ApplTime ), .TT ( TestTime ), @@ -77,10 +72,10 @@ module floo_axi_test_node #( ) axi_rand_master_t; AXI_BUS_DV #( - .AXI_ADDR_WIDTH ( AxiAddrWidth ), - .AXI_DATA_WIDTH ( AxiDataWidth ), - .AXI_ID_WIDTH ( AxiIdOutWidth ), - .AXI_USER_WIDTH ( AxiUserWidth ) + .AXI_ADDR_WIDTH ( AxiCfg.AddrWidth ), + .AXI_DATA_WIDTH ( AxiCfg.DataWidth ), + .AXI_ID_WIDTH ( AxiCfg.OutIdWidth ), + .AXI_USER_WIDTH ( AxiCfg.UserWidth ) ) slave_dv (clk_i); `AXI_ASSIGN_FROM_REQ(slave_dv, slv_port_req_i) @@ -88,10 +83,10 @@ module floo_axi_test_node #( typedef axi_test::axi_rand_slave #( // AXI interface parameters - .AW ( AxiAddrWidth ), - .DW ( AxiDataWidth ), - .IW ( AxiIdOutWidth ), - .UW ( AxiUserWidth ), + .AW ( AxiCfg.AddrWidth ), + .DW ( AxiCfg.DataWidth ), + .IW ( AxiCfg.OutIdWidth ), + .UW ( AxiCfg.UserWidth ), // Stimuli application and test time .TA ( ApplTime ), .TT ( TestTime ) diff --git a/hw/test/floo_dma_test_node.sv b/hw/test/floo_dma_test_node.sv index 598f4447..39dc7f66 100644 --- a/hw/test/floo_dma_test_node.sv +++ b/hw/test/floo_dma_test_node.sv @@ -15,12 +15,7 @@ module floo_dma_test_node #( parameter time TT = 9ns, parameter int unsigned BufferDepth = 16, parameter int unsigned NumAxInFlight = 16, - parameter int unsigned DataWidth = 32, - parameter int unsigned AddrWidth = 32, - parameter int unsigned UserWidth = 1, - parameter int unsigned AxiIdWidth = 2, - parameter int unsigned AxiIdInWidth = AxiIdWidth, - parameter int unsigned AxiIdOutWidth = AxiIdWidth, + parameter floo_pkg::axi_cfg_t AxiCfg = '{default:0}, parameter type axi_req_t = logic, parameter type axi_rsp_t = logic, parameter type axi_in_req_t = axi_req_t, @@ -29,8 +24,8 @@ module floo_dma_test_node #( parameter type axi_out_rsp_t = axi_rsp_t, parameter int unsigned TFLenWidth = 32, parameter int unsigned MemSysDepth = 0, - parameter logic [AddrWidth-1:0] MemBaseAddr = 32'h0, - parameter logic [AddrWidth-1:0] MemSize = 32'h10000, + parameter logic [AxiCfg.AddrWidth-1:0] MemBaseAddr = 32'h0, + parameter logic [AxiCfg.AddrWidth-1:0] MemSize = 32'h10000, parameter bit MaskInvalidData = 1, parameter bit RAWCouplingAvail = 1, parameter bit HardwareLegalizer = 1, @@ -56,7 +51,7 @@ module floo_dma_test_node #( localparam bit PrintFifoInfo = 1'b0; // dependent parameters - localparam int unsigned StrbWidth = DataWidth / 8; + localparam int unsigned StrbWidth = AxiCfg.DataWidth / 8; localparam int unsigned OffsetWidth = $clog2(StrbWidth); // parse error handling caps @@ -67,12 +62,12 @@ module floo_dma_test_node #( typedef logic [7:0] byte_t; // dependent typed - typedef logic [AddrWidth-1:0] addr_t; - typedef logic [DataWidth-1:0] data_t; + typedef logic [AxiCfg.AddrWidth-1:0] addr_t; + typedef logic [AxiCfg.DataWidth-1:0] data_t; typedef logic [StrbWidth-1:0] strb_t; - typedef logic [UserWidth-1:0] user_t; - typedef logic [AxiIdInWidth-1:0] id_in_t; - typedef logic [AxiIdOutWidth-1:0] id_out_t; + typedef logic [AxiCfg.UserWidth-1:0] user_t; + typedef logic [AxiCfg.InIdWidth-1:0] id_in_t; + typedef logic [AxiCfg.OutIdWidth-1:0] id_out_t; typedef logic [OffsetWidth-1:0] offset_t; typedef logic [TFLenWidth-1:0] tf_len_t; @@ -134,8 +129,8 @@ module floo_dma_test_node #( typedef struct packed { logic [31:0] idx; - logic [AddrWidth-1:0] start_addr; - logic [AddrWidth-1:0] end_addr; + logic [AxiCfg.AddrWidth-1:0] start_addr; + logic [AxiCfg.AddrWidth-1:0] end_addr; } xbar_rule_t; xbar_rule_t [0:0] XbarAddrMap; @@ -150,11 +145,11 @@ module floo_dma_test_node #( MaxMstTrans: 128, FallThrough: 1, LatencyMode: axi_pkg::CUT_ALL_PORTS, - AxiIdWidthSlvPorts: AxiIdOutWidth, - AxiIdUsedSlvPorts: AxiIdOutWidth, + AxiIdWidthSlvPorts: AxiCfg.OutIdWidth, + AxiIdUsedSlvPorts: AxiCfg.OutIdWidth, UniqueIds: 0, - AxiAddrWidth: AddrWidth, - AxiDataWidth: DataWidth, + AxiAddrWidth: AxiCfg.AddrWidth, + AxiDataWidth: AxiCfg.DataWidth, NoAddrRules: 1, PipelineStages: 0 }; @@ -163,10 +158,10 @@ module floo_dma_test_node #( // DMA //-------------------------------------- idma_backend_rw_axi #( - .DataWidth ( DataWidth ), - .AddrWidth ( AddrWidth ), - .AxiIdWidth ( AxiIdOutWidth ), - .UserWidth ( UserWidth ), + .DataWidth ( AxiCfg.DataWidth ), + .AddrWidth ( AxiCfg.AddrWidth ), + .AxiIdWidth ( AxiCfg.OutIdWidth ), + .UserWidth ( AxiCfg.UserWidth ), .TFLenWidth ( TFLenWidth ), .MaskInvalidData ( MaskInvalidData ), .BufferDepth ( BufferDepth ), @@ -252,11 +247,7 @@ module floo_dma_test_node #( ); floo_axi_rand_slave #( - .AxiAddrWidth ( AddrWidth ), - .AxiDataWidth ( DataWidth ), - .AxiIdWidth ( AxiIdOutWidth ), - .AxiUserWidth ( UserWidth ), - .AxiStrbWidth ( StrbWidth ), + .AxiCfg ( AxiCfg ), .ApplTime ( TA ), .TestTime ( TT ), .SlaveType ( floo_test_pkg::FastSlave ), @@ -273,17 +264,13 @@ module floo_dma_test_node #( ); floo_axi_rand_slave #( - .AxiAddrWidth ( AddrWidth ), - .AxiDataWidth ( DataWidth ), - .AxiIdWidth ( AxiIdInWidth ), - .AxiUserWidth ( UserWidth ), - .AxiStrbWidth ( StrbWidth ), - .ApplTime ( TA ), - .TestTime ( TT ), - .SlaveType ( floo_test_pkg::FastSlave ), - .NumSlaves ( 1 ), - .axi_req_t ( axi_in_req_t ), - .axi_rsp_t ( axi_in_rsp_t ) + .AxiCfg ( floo_pkg::axi_cfg_swap_iw(AxiCfg) ), + .ApplTime ( TA ), + .TestTime ( TT ), + .SlaveType ( floo_test_pkg::FastSlave ), + .NumSlaves ( 1 ), + .axi_req_t ( axi_in_req_t ), + .axi_rsp_t ( axi_in_rsp_t ) ) i_sink_in_mem ( .clk_i ( clk_i ), .rst_ni ( rst_ni ), @@ -305,22 +292,22 @@ module floo_dma_test_node #( //-------------------------------------- // virtual interface definition IDMA_DV #( - .DataWidth ( DataWidth ), - .AddrWidth ( AddrWidth ), - .UserWidth ( UserWidth ), - .AxiIdWidth ( AxiIdOutWidth ), - .TFLenWidth ( TFLenWidth ) + .DataWidth ( AxiCfg.DataWidth ), + .AddrWidth ( AxiCfg.AddrWidth ), + .UserWidth ( AxiCfg.UserWidth ), + .AxiIdWidth ( AxiCfg.OutIdWidth ), + .TFLenWidth ( TFLenWidth ) ) idma_dv (clk_i); // DMA driver type typedef idma_test::idma_driver #( - .DataWidth ( DataWidth ), - .AddrWidth ( AddrWidth ), - .UserWidth ( UserWidth ), - .AxiIdWidth ( AxiIdOutWidth ), - .TFLenWidth ( TFLenWidth ), - .TA ( TA ), - .TT ( TT ) + .DataWidth ( AxiCfg.DataWidth ), + .AddrWidth ( AxiCfg.AddrWidth ), + .UserWidth ( AxiCfg.UserWidth ), + .AxiIdWidth ( AxiCfg.OutIdWidth ), + .TFLenWidth ( TFLenWidth ), + .TA ( TA ), + .TT ( TT ) ) drv_t; // instantiation of the driver @@ -343,7 +330,7 @@ module floo_dma_test_node #( //-------------------------------------- // job type definition typedef idma_test::idma_job #( - .AddrWidth ( AddrWidth ) + .AddrWidth ( AxiCfg.AddrWidth ) ) tb_dma_job_t; // request and response queues @@ -403,7 +390,7 @@ module floo_dma_test_node #( // pop front to get a job automatic tb_dma_job_t now = req_jobs.pop_front(); // print job to terminal - if (EnableDebug) $display("[DMA%0d]%s", JobId + 1, now.pprint()); + if (EnableDebug) $display("[DMA%0d]%s", JobId, now.pprint()); // launch DUT drv.launch_tf( now.length, diff --git a/hw/test/floo_test_pkg.sv b/hw/test/floo_test_pkg.sv index 11138d16..32aa99ff 100644 --- a/hw/test/floo_test_pkg.sv +++ b/hw/test/floo_test_pkg.sv @@ -8,8 +8,6 @@ package floo_test_pkg; - import floo_pkg::*; - typedef enum { FastSlave, SlowSlave, @@ -25,20 +23,48 @@ package floo_test_pkg; localparam int unsigned ChannelFifoDepth = 2; localparam int unsigned OutputFifoDepth = 2; - // Chimney parameters - localparam bit CutAx = 1'b1; - localparam bit CutRsp = 1'b0; - localparam int unsigned MaxTxnsPerId = 16; - localparam rob_type_e RoBType = NormalRoB; - localparam int unsigned ReorderBufferSize = 32'd64; - - // Narrow Wide Chimney parameters - localparam bit NarrowRoBSimple = 1'b1; - localparam int unsigned NarrowMaxTxnsPerId = 4; - localparam rob_type_e NarrowRoBType = NoRoB; - localparam int unsigned NarrowReorderBufferSize = 32'd256; - localparam int unsigned WideMaxTxnsPerId = 32; - localparam rob_type_e WideRoBType = NoRoB; - localparam int unsigned WideReorderBufferSize = 32'd128; + // Default route config for testing + localparam floo_pkg::route_cfg_t RouteCfg = '{ + RouteAlgo: floo_pkg::XYRouting, + UseIdTable: 0, + XYAddrOffsetX: 16, + XYAddrOffsetY: 20, + IdAddrOffset: 0, + NumSamRules: 0, + NumRoutes: 0 + }; + + // Common chimney parameters + localparam bit AtopSupport = 1'b1; + localparam int unsigned MaxAtomicTxns = 4; + + // Axi chimney parameters + localparam floo_pkg::axi_cfg_t AxiCfg = '{ + AddrWidth: 32, + DataWidth: 64, + UserWidth: 1, + InIdWidth: 3, + OutIdWidth: 3 + }; + + localparam floo_pkg::axi_cfg_t AxiCfgN = '{ + AddrWidth: 48, + DataWidth: 64, + UserWidth: 5, + InIdWidth: 4, + OutIdWidth: 2 + }; + + // AXI nw_chimney parameters + localparam floo_pkg::axi_cfg_t AxiCfgW = '{ + AddrWidth: 48, + DataWidth: 512, + UserWidth: 1, + InIdWidth: 3, + OutIdWidth: 1 + }; + + // Default chimney config for testing + localparam floo_pkg::chimney_cfg_t ChimneyCfg = floo_pkg::ChimneyDefaultCfg; endpackage diff --git a/util/gen_jobs.py b/util/gen_jobs.py index 3d8c628e..11567264 100755 --- a/util/gen_jobs.py +++ b/util/gen_jobs.py @@ -13,6 +13,8 @@ MEM_SIZE = 2**16 NUM_X = 4 NUM_Y = 4 +XY_ADDR_OFFSET_X = 16 +XY_ADDR_OFFSET_Y = 20 data_widths = {"wide": 512, "narrow": 64} @@ -25,7 +27,7 @@ def clog2(x: int): def get_xy_base_addr(x: int, y: int): """Get the address of a tile in the mesh.""" assert x <= NUM_X+1 and y <= NUM_Y+1 - return (x + 2 ** clog2(NUM_X + 2) * y) * MEM_SIZE + return (x << XY_ADDR_OFFSET_X) + (y << XY_ADDR_OFFSET_Y) def gen_job_str(