From 89c34824158a5f625b7f3d4b9743facce65a0a2c Mon Sep 17 00:00:00 2001 From: Rohan Kumar Date: Thu, 27 Aug 2026 17:38:56 -0700 Subject: [PATCH 1/2] Separate UCIe modules and bump ucie/ucie.h --- software/ucie.h | 162 +++++++++++++++++++++++++----------------------- src/Iris.scala | 11 +++- ucie | 2 +- 3 files changed, 94 insertions(+), 81 deletions(-) diff --git a/software/ucie.h b/software/ucie.h index 146ec6f..8fa4c54 100644 --- a/software/ucie.h +++ b/software/ucie.h @@ -17,43 +17,41 @@ #define UCIE_TX_DATA_MODE 0x18ULL #define UCIE_TX_LFSR_SEED 0x20ULL #define UCIE_TX_LFSR_SEED_WIDTH 0x8ULL -#define UCIE_TX_FSM_RST 0xa8ULL -#define UCIE_TX_EXECUTE 0xb0ULL -#define UCIE_TX_WRITE_CHUNK 0xb8ULL -#define UCIE_TX_PACKETS_SENT 0xc0ULL -#define UCIE_TX_MANUAL_REPEAT_PERIOD 0xc8ULL -#define UCIE_TX_PACKETS_TO_SEND 0xd0ULL -#define UCIE_TX_CLK_P 0xd8ULL -#define UCIE_TX_CLK_N 0xe0ULL -#define UCIE_TX_TRACK 0xe8ULL -#define UCIE_TX_DATA_LANE_GROUP 0xf0ULL -#define UCIE_TX_DATA_OFFSET 0xf8ULL -#define UCIE_TX_DATA_CHUNK_IN0 0x100ULL -#define UCIE_TX_DATA_CHUNK_IN1 0x108ULL -#define UCIE_TX_DATA_CHUNK_OUT0 0x110ULL -#define UCIE_TX_DATA_CHUNK_OUT1 0x118ULL -#define UCIE_TX_TEST_STATE 0x120ULL -#define UCIE_RX_DATA_MODE 0x128ULL -#define UCIE_RX_LFSR_SEED 0x130ULL +#define UCIE_TX_RST 0xb8ULL +#define UCIE_TX_EXECUTE 0xc0ULL +#define UCIE_TX_WRITE_CHUNK 0xc8ULL +#define UCIE_TX_PACKETS_SENT 0xd0ULL +#define UCIE_TX_MANUAL_REPEAT_PERIOD 0xd8ULL +#define UCIE_TX_PACKETS_TO_SEND 0xe0ULL +#define UCIE_TX_CLK_P 0xe8ULL +#define UCIE_TX_CLK_N 0xf0ULL +#define UCIE_TX_DATA_LANE_GROUP 0xf8ULL +#define UCIE_TX_DATA_OFFSET 0x100ULL +#define UCIE_TX_DATA_CHUNK_IN0 0x108ULL +#define UCIE_TX_DATA_CHUNK_IN1 0x110ULL +#define UCIE_TX_DATA_CHUNK_OUT0 0x118ULL +#define UCIE_TX_DATA_CHUNK_OUT1 0x120ULL +#define UCIE_TX_TEST_STATE 0x128ULL +#define UCIE_RX_DATA_MODE 0x130ULL +#define UCIE_RX_LFSR_SEED 0x138ULL #define UCIE_RX_LFSR_SEED_WIDTH 0x8ULL -#define UCIE_RX_BIT_ERRORS 0x1b8ULL +#define UCIE_RX_BIT_ERRORS 0x1d0ULL #define UCIE_RX_BIT_ERRORS_WIDTH 0x8ULL -#define UCIE_RX_BIT_ERRORS_EARLY 0x248ULL +#define UCIE_RX_BIT_ERRORS_EARLY 0x268ULL #define UCIE_RX_BIT_ERRORS_EARLY_WIDTH 0x8ULL -#define UCIE_RX_BIT_ERRORS_LATE 0x2d8ULL +#define UCIE_RX_BIT_ERRORS_LATE 0x300ULL #define UCIE_RX_BIT_ERRORS_LATE_WIDTH 0x8ULL -#define UCIE_RX_FSM_RST 0x368ULL -#define UCIE_RX_PACKETS_TO_RECEIVE 0x370ULL -#define UCIE_RX_PAUSE_COUNTERS 0x378ULL -#define UCIE_RX_PACKETS_RECEIVED 0x380ULL -#define UCIE_RX_SIGNATURE 0x388ULL -#define UCIE_RX_DATA_LANE 0x390ULL -#define UCIE_RX_DATA_OFFSET 0x398ULL -#define UCIE_RX_DATA_CHUNK 0x3a0ULL -#define UCIE_CLK_PHASE_SEL 0x3a8ULL -#define UCIE_CLK_FREQ_SEL 0x3b0ULL -#define UCIE_CLK_GATE_EN 0x3b8ULL -#define UCIE_TXCTL 0x3c0ULL +#define UCIE_RX_RST 0x398ULL +#define UCIE_RX_PACKETS_TO_RECEIVE 0x3a0ULL +#define UCIE_RX_PAUSE_COUNTERS 0x3a8ULL +#define UCIE_RX_PACKETS_RECEIVED 0x3b0ULL +#define UCIE_RX_SIGNATURE 0x3b8ULL +#define UCIE_RX_DATA_LANE 0x3c0ULL +#define UCIE_RX_DATA_OFFSET 0x3c8ULL +#define UCIE_RX_DATA_CHUNK 0x3d0ULL +#define UCIE_CLK_PHASE_SEL 0x3d8ULL +#define UCIE_CLK_FREQ_SEL 0x3e0ULL +#define UCIE_TXCTL 0x3e8ULL #define UCIE_TXCTL_DLL_RESET_OFS 0x0ULL #define UCIE_TXCTL_DRIVER_OFS 0x8ULL #define UCIE_TXCTL_SKEW_OFS 0x10ULL @@ -63,7 +61,7 @@ #define UCIE_TXCTL_DELAY_OFS 0x120ULL #define UCIE_TXCTL_DLL_CODE_OFS 0x128ULL #define UCIE_TXCTL_WIDTH 0x130ULL -#define UCIE_RXCTL 0x1b80ULL +#define UCIE_RXCTL 0x1cd8ULL #define UCIE_RXCTL_ZEN_OFS 0x0ULL #define UCIE_RXCTL_ZCTL_OFS 0x8ULL #define UCIE_RXCTL_VREF_SEL_OFS 0x10ULL @@ -76,40 +74,49 @@ #define UCIE_RXCTL_SAMPLE_NEGEDGE_OFS 0x138ULL #define UCIE_RXCTL_RX_DELAY_OFS 0x140ULL #define UCIE_RXCTL_WIDTH 0x148ULL -#define UCIE_COMMON_TX_TEST_MODE 0x3520ULL -#define UCIE_COMMON_TX_DATA_MODE 0x3528ULL -#define UCIE_COMMON_TX_LFSR_SEED 0x3530ULL -#define UCIE_COMMON_TX_FSM_RST 0x3538ULL -#define UCIE_COMMON_TX_EXECUTE 0x3540ULL -#define UCIE_COMMON_TX_MANUAL_REPEAT_PERIOD 0x3548ULL -#define UCIE_COMMON_TX_PACKETS_TO_SEND 0x3550ULL -#define UCIE_COMMON_DATA 0x3558ULL -#define UCIE_COMMON_DATA_WIDTH 0x8ULL -#define UCIE_COMMON_DRIVERCTL 0x35d8ULL -#define UCIE_COMMON_DRIVERCTL_WIDTH 0x8ULL -#define UCIE_COMMON_TXCTL_DLL_RESET 0x3608ULL -#define UCIE_COMMON_TXCTL_DRIVER 0x3610ULL -#define UCIE_COMMON_TXCTL_SKEW 0x3618ULL -#define UCIE_COMMON_TXCTL_SHUFFLER 0x3620ULL -#define UCIE_COMMON_TXCTL_SHUFFLER_WIDTH 0x8ULL -#define UCIE_TX_VALID 0x3720ULL -#define UCIE_RX_LFSR_VALID 0x3728ULL -#define UCIE_CONTROLLER_SEL 0x3730ULL -#define UCIE_MAINBAND_MODE 0x3738ULL -#define UCIE_SIDEBAND_MODE 0x3740ULL -#define UCIE_CREDIT_FLOW_ENABLE 0x3748ULL -#define UCIE_TX_VALID_LANE_SEL 0x3750ULL -#define UCIE_RX_VALID_LANE_SEL 0x3758ULL -#define UCIE_LAST_SEEN_TL_REQ 0x3760ULL -#define UCIE_SB_TX_PACKET 0x3768ULL -#define UCIE_SB_TX_SEND 0x3770ULL -#define UCIE_SB_TX_BUSY 0x3778ULL -#define UCIE_SB_RX_PACKET 0x3780ULL -#define UCIE_SB_RX_VALID 0x3788ULL -#define UCIE_SB_RX_POP 0x3790ULL -#define UCIE_SB_RX_OVERFLOW 0x3798ULL -#define UCIE_SB_RX_RST 0x37a0ULL -#define UCIE_SB_TL_RX_OVERFLOW 0x37a8ULL +#define UCIE_DEBUG_TX_TEST_MODE 0x37c0ULL +#define UCIE_DEBUG_TX_DATA_MODE 0x37c8ULL +#define UCIE_DEBUG_TX_LFSR_SEED 0x37d0ULL +#define UCIE_DEBUG_TX_FSM_RST 0x37d8ULL +#define UCIE_DEBUG_TX_EXECUTE 0x37e0ULL +#define UCIE_DEBUG_TX_MANUAL_REPEAT_PERIOD 0x37e8ULL +#define UCIE_DEBUG_TX_PACKETS_TO_SEND 0x37f0ULL +#define UCIE_DEBUG_DATA 0x37f8ULL +#define UCIE_DEBUG_DATA_WIDTH 0x8ULL +#define UCIE_DEBUG_DRIVERCTL 0x3878ULL +#define UCIE_DEBUG_DRIVERCTL_WIDTH 0x8ULL +#define UCIE_DEBUG_TXCTL_DLL_RESET 0x3898ULL +#define UCIE_DEBUG_TXCTL_DRIVER 0x38a0ULL +#define UCIE_DEBUG_TXCTL_SKEW 0x38a8ULL +#define UCIE_DEBUG_TXCTL_SHUFFLER 0x38b0ULL +#define UCIE_DEBUG_TXCTL_SHUFFLER_WIDTH 0x8ULL +#define UCIE_DEBUG_TXCTL_DLL_CODE 0x39b0ULL +#define UCIE_DEBUG_TX_TEST_STATE 0x39b8ULL +#define UCIE_DEBUG_TX_PACKETS_SENT 0x39c0ULL +#define UCIE_DEBUG_CLK_MUX_SEL 0x39c8ULL +#define UCIE_DEBUG_RX_LANE 0x39d0ULL +#define UCIE_DEBUG_RX_BIT 0x39d8ULL +#define UCIE_TX_VALID 0x39e0ULL +#define UCIE_RX_LFSR_VALID 0x39e8ULL +#define UCIE_CONTROLLER_SEL 0x39f0ULL +#define UCIE_MAINBAND_MODE 0x39f8ULL +#define UCIE_SIDEBAND_MODE 0x3a00ULL +#define UCIE_CREDIT_FLOW_ENABLE 0x3a08ULL +#define UCIE_TX_VALID_LANE_SEL 0x3a10ULL +#define UCIE_RX_VALID_LANE_SEL 0x3a18ULL +#define UCIE_LAST_SEEN_TL_REQ 0x3a20ULL +#define UCIE_SB_TX_PACKET 0x3a28ULL +#define UCIE_SB_TX_SEND 0x3a30ULL +#define UCIE_SB_TX_BUSY 0x3a38ULL +#define UCIE_SB_RX_PACKET 0x3a40ULL +#define UCIE_SB_RX_VALID 0x3a48ULL +#define UCIE_SB_RX_POP 0x3a50ULL +#define UCIE_SB_RX_OVERFLOW 0x3a58ULL +#define UCIE_SB_RX_RST 0x3a60ULL +#define UCIE_SB_TL_RX_OVERFLOW 0x3a68ULL +#define UCIE_UCIE_LINK_RESET 0x3a70ULL +#define UCIE_UCIE_PWR_GOOD 0x3a78ULL +#define UCIE_UCIE_RETRY_TRAINING_AMT 0x3a80ULL // === Constants === #define UCIE_TX_TEST_STATE_IDLE 0x0ULL @@ -120,7 +127,7 @@ #define UCIE_DATA_MODE_FINITE 0x0ULL #define UCIE_DATA_MODE_INFINITE 0x1ULL #define UCIE_TEST_TARGET_MAINBAND 0x0ULL -#define UCIE_TEST_TARGET_LOOPBACK 0x0ULL +#define UCIE_TEST_TARGET_LOOPBACK 0x1ULL #define UCIE_CONTROLLER_SEL_PHYTEST 0x0ULL #define UCIE_CONTROLLER_SEL_UCIE 0x1ULL #define UCIE_BAND_MODE_MANUAL 0x0ULL @@ -134,9 +141,9 @@ // === Helper functions === static inline void reset_fsms(uintptr_t base) { - reg_write64(base + UCIE_TX_FSM_RST, 0x1ULL); - reg_write64(base + UCIE_RX_FSM_RST, 0x1ULL); - reg_write64(base + UCIE_COMMON_TX_FSM_RST, 0x1ULL); + reg_write64(base + UCIE_TX_RST, 0x1ULL); + reg_write64(base + UCIE_RX_RST, 0x1ULL); + reg_write64(base + UCIE_DEBUG_TX_FSM_RST, 0x1ULL); assert(reg_read64(base + UCIE_TX_TEST_STATE) == (UCIE_TX_TEST_STATE_IDLE)); assert(reg_read64(base + UCIE_TX_PACKETS_SENT) == (0x0ULL)); assert(reg_read64(base + UCIE_RX_PACKETS_RECEIVED) == (0x0ULL)); @@ -160,16 +167,15 @@ static inline void setup_ucie(uintptr_t base) { } reg_write64(base + UCIE_TX_CLK_P, UCIE_DEFAULT_CLK_P); reg_write64(base + UCIE_TX_CLK_N, UCIE_DEFAULT_CLK_N); - reg_write64(base + UCIE_TX_TRACK, UCIE_DEFAULT_TRACK); reg_write64(base + UCIE_TX_VALID, UCIE_DEFAULT_VALID); reg_write64(base + UCIE_RX_LFSR_VALID, UCIE_DEFAULT_VALID); - reg_write64(base + UCIE_COMMON_TXCTL_DLL_RESET, 0x0ULL); + reg_write64(base + UCIE_DEBUG_TXCTL_DLL_RESET, 0x0ULL); reg_write64(base + UCIE_DIV_RESETB, 0x1ULL); - for (int i = 0; i < 6; i++) { - reg_write64(base + UCIE_COMMON_DRIVERCTL + 8 * i, UCIE_ENABLE_DRIVER_CTL); + for (int i = 0; i < 4; i++) { + reg_write64(base + UCIE_DEBUG_DRIVERCTL + 8 * i, UCIE_ENABLE_DRIVER_CTL); } - reg_write64(base + UCIE_COMMON_TXCTL_DRIVER, UCIE_ENABLE_DRIVER_CTL); - reg_write64(base + UCIE_COMMON_TXCTL_SKEW, UCIE_DEFAULT_SKEW_CTL); + reg_write64(base + UCIE_DEBUG_TXCTL_DRIVER, UCIE_ENABLE_DRIVER_CTL); + reg_write64(base + UCIE_DEBUG_TXCTL_SKEW, UCIE_DEFAULT_SKEW_CTL); reset_fsms(base); reg_write64(base + UCIE_CONTROLLER_SEL, UCIE_CONTROLLER_SEL_PHYTEST); reg_write64(base + UCIE_MAINBAND_MODE, UCIE_BAND_MODE_MANUAL); diff --git a/src/Iris.scala b/src/Iris.scala index 69d8ec8..2ab545a 100644 --- a/src/Iris.scala +++ b/src/Iris.scala @@ -476,17 +476,24 @@ class IrisConfig(sim: Boolean = false) new testchipip.soc.WithChipletRouting(testchipip.soc.ChipletRoutingParams( routerParams = testchipip.soc.OffchipRouterParams(tableEntries = 4), ports = Seq( + // The two ports are identical logic, so they would dedup into + // one SystemVerilog module. The orientation splits them into + // UcieTL_NS and UcieTL_EW so PD can harden each separately: port 0 + // is placed unrotated facing down, port 1 is rotated 90 degrees + // facing right. edu.berkeley.cs.uciedigital.tilelink.UcieTLParams( address = 0x200000, managerWhere = SBUS, numLanes = 16, - includeDefaultModels = true + includeDefaultModels = true, + orientation = edu.berkeley.cs.uciedigital.tilelink.UcieOrientation.NS ), edu.berkeley.cs.uciedigital.tilelink.UcieTLParams( address = 0x208000, managerWhere = SBUS, numLanes = 16, - includeDefaultModels = true + includeDefaultModels = true, + orientation = edu.berkeley.cs.uciedigital.tilelink.UcieOrientation.EW ) ))) ++ new WithIrisUncore(sim) diff --git a/ucie b/ucie index c5ce12f..7d18fe0 160000 --- a/ucie +++ b/ucie @@ -1 +1 @@ -Subproject commit c5ce12f400f804f763ab1eb2ae6283b856988c1a +Subproject commit 7d18fe03eedf90387b847e0cfb639ccdf4f929ee From 185dc7b6f6b67875d2689051e16953b683d92aa6 Mon Sep 17 00:00:00 2001 From: Rohan Kumar Date: Thu, 27 Aug 2026 19:15:14 -0700 Subject: [PATCH 2/2] Basic CI and codegen improvements --- .github/workflows/ci.yml | 88 ++++++++++++++++++++++++++++++++++++++++ software/Makefile | 18 ++++++++ software/ucie.h | 2 +- src/GenUcieHeader.scala | 65 +++++++++++++++++++++++++++++ ucie | 2 +- 5 files changed, 173 insertions(+), 2 deletions(-) create mode 100644 .github/workflows/ci.yml create mode 100644 src/GenUcieHeader.scala diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..1fdc4ed --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,88 @@ +name: CI + +on: + push: + branches: [main] + pull_request: + +# A new push to a branch cancels the run still in flight for it. +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + +jobs: + build: + name: Compile, elaborate, and check generated collateral + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + + # The .gitmodules URLs are SSH, but every submodule below is a public + # repo, so rewrite to HTTPS instead of giving the runner a deploy key. + # DRAMSim2 and tacit_decoder are simulation-only and not in the mill + # build, so they stay uninitialized. + - name: Check out submodules + run: | + git config --global url."https://github.com/".insteadOf "git@github.com:" + git submodule update --init \ + rocket-chip shuttle saturn-vectors testchipip ucie tacit + + - uses: actions/setup-java@v4 + with: + distribution: temurin + java-version: '21' + + # Dominated by the Chisel/rocket-chip artifacts and the firtool binary + # Chisel resolves at elaboration time. + - name: Cache JVM dependencies + uses: actions/cache@v4 + with: + path: | + ~/.cache/coursier + ~/.cache/mill + key: ${{ runner.os }}-mill-${{ hashFiles('build.mill', 'module.mill') }} + restore-keys: ${{ runner.os }}-mill- + + - name: Compile + run: ./mill test.compile + + # Elaboration only. The rest of IrisSpec drives VCS and needs RISC-V + # binaries, so it stays out of CI. + - name: Elaborate Iris + run: | + ./mill test.testOnly edu.berkeley.cs.iris.IrisSpec \ + -- -t "Iris should generate valid System Verilog" + + - name: Elaborate IrisDryRun + run: | + ./mill test.testOnly edu.berkeley.cs.iris.IrisSpec \ + -- -t "IrisDryRun should generate valid System Verilog" + + - name: Elaborate TinyIris + run: | + ./mill test.testOnly edu.berkeley.cs.iris.IrisSpec \ + -- -t "TinyIris should generate valid System Verilog for TinyIris" + + # PD hardens the two UCIe blocks separately, so they have to stay two + # SystemVerilog modules. They fold back into one as soon as their + # parameters -- orientation included -- match, and nothing else in the + # flow would notice. + - name: Check the UCIe blocks did not dedup + run: | + out=build/Iris_should_generate_valid_System_Verilog + n=$(grep -lE '^module UcieTL(_[A-Za-z0-9]+)?\(' "$out"/*.sv | wc -l) + if [ "$n" -ne 2 ]; then + echo "::error::expected 2 UcieTL modules in $out, found $n" + grep -hE '^module UcieTL(_[A-Za-z0-9]+)?\(' "$out"/*.sv || true + exit 1 + fi + + # Catches a ucie bump (or a UCIe parameter change) that moves the + # register map without the checked-in header following it. + - name: Check ucie.h is up to date + run: | + ./mill runMain edu.berkeley.cs.iris.GenUcieHeader "$RUNNER_TEMP/ucie.h" + if ! diff -u software/ucie.h "$RUNNER_TEMP/ucie.h"; then + echo "::error::software/ucie.h is stale; run 'make ucie.h' in software/" + exit 1 + fi diff --git a/software/Makefile b/software/Makefile index e55114d..2606cc4 100644 --- a/software/Makefile +++ b/software/Makefile @@ -1,3 +1,12 @@ +################################# +# Paths +################################# + +# Repo root, derived from this Makefile's own path rather than the working +# directory, so the mill invocation below works under `make -C`, `make -f`, or +# a plain `make` from this folder. +REPO_ROOT := $(abspath $(dir $(abspath $(lastword $(MAKEFILE_LIST))))/..) + ################################# # RISCV Toolchain ################################# @@ -58,6 +67,15 @@ ucie-vec-memcpy.riscv: ucie-vec-memcpy.o # Recipes ################################# +# ucie.h holds the UCIe register offsets, generated from the UCIe parameters in +# IrisConfig. It is checked in so building these programs needs only the RISC-V +# toolchain; regenerating it needs the Scala toolchain, so it is not a +# prerequisite of the program rules. Re-run this after bumping the ucie +# submodule or changing the UCIe ports in IrisConfig -- CI checks it is current. +.PHONY: ucie.h +ucie.h: + cd $(REPO_ROOT) && ./mill runMain edu.berkeley.cs.iris.GenUcieHeader software/ucie.h + .PHONY: clean clean: rm -f *.riscv *.o *.dump diff --git a/software/ucie.h b/software/ucie.h index 8fa4c54..10b88e9 100644 --- a/software/ucie.h +++ b/software/ucie.h @@ -1,6 +1,6 @@ // Auto-generated by edu.berkeley.cs.uciedigital.tilelink.GenUcieHeader. // Regenerate via: -// ./mill ucie.runMain edu.berkeley.cs.uciedigital.tilelink.GenUcieHeader +// ./mill runMain edu.berkeley.cs.iris.GenUcieHeader software/ucie.h // DO NOT EDIT. #ifndef __UCIE_H__ diff --git a/src/GenUcieHeader.scala b/src/GenUcieHeader.scala new file mode 100644 index 0000000..3f59c07 --- /dev/null +++ b/src/GenUcieHeader.scala @@ -0,0 +1,65 @@ +package edu.berkeley.cs.iris + +import org.chipsalliance.cde.config.Parameters +import testchipip.soc.ChipletRoutingKey +import edu.berkeley.cs.uciedigital.tilelink.UcieTLParams + +/** Writes the bringup software's `ucie.h` from the UCIe parameters IrisConfig + * actually uses. + * + * The register layout depends on those parameters -- the per-lane arrays are + * sized from `numLanes`, for one -- so generating from the ucie defaults would + * silently describe a different chip the moment IrisConfig moves off them. + * + * Run as: + * {{{ + * ./mill runMain edu.berkeley.cs.iris.GenUcieHeader software/ucie.h + * }}} + * or `make ucie.h` from `software/`. + */ +object GenUcieHeader { + val regenCommand = + "./mill runMain edu.berkeley.cs.iris.GenUcieHeader software/ucie.h" + + /** The UCIe ports of IrisConfig, in chiplet-router port order. */ + def uciePorts: Seq[UcieTLParams] = { + val p: Parameters = new IrisConfig + val ports = p(ChipletRoutingKey) + .map(_.ports.collect { case u: UcieTLParams => u }) + .getOrElse(Nil) + require(ports.nonEmpty, "IrisConfig has no UCIe chiplet-router ports") + ports + } + + def render(): String = { + val ports = uciePorts + // The header holds one register layout, so every port has to agree on + // everything that layout depends on. Address and orientation do not reach + // it: the offsets are relative to each port's own MMIO base, and the + // orientation only names modules. + val canonical = ports.map( + _.copy( + address = ports.head.address, + orientation = ports.head.orientation + ) + ) + require( + canonical.forall(_ == canonical.head), + "UCIe ports must share a register layout, but their parameters differ " + + s"beyond address and orientation: ${canonical.distinct.mkString("\n")}" + ) + edu.berkeley.cs.uciedigital.tilelink.GenUcieHeader + .render(ports.head, regenCommand) + } + + def main(args: Array[String]): Unit = { + require( + args.length == 1, + s"Usage: GenUcieHeader ; got ${args.mkString(" ")}" + ) + val out = os.Path(args(0), os.pwd) + os.makeDir.all(out / os.up) + os.write.over(out, render()) + println(s"Wrote $out") + } +} diff --git a/ucie b/ucie index 7d18fe0..81b52c9 160000 --- a/ucie +++ b/ucie @@ -1 +1 @@ -Subproject commit 7d18fe03eedf90387b847e0cfb639ccdf4f929ee +Subproject commit 81b52c932c1cff44930477484eb0fb06450c8210