diff --git a/software/ring-hello.c b/software/ring-hello.c index 2095f7c..41a0ea6 100644 --- a/software/ring-hello.c +++ b/software/ring-hello.c @@ -20,8 +20,10 @@ int main(void) { setup_ucie(UCIE0_REG_BASE); reg_write64(UCIE0_REG_BASE + UCIE_MAINBAND_MODE, UCIE_BAND_MODE_TL); + reset_datapath(UCIE0_REG_BASE); setup_ucie(UCIE1_REG_BASE); reg_write64(UCIE1_REG_BASE + UCIE_MAINBAND_MODE, UCIE_BAND_MODE_TL); + reset_datapath(UCIE1_REG_BASE); int next = (chip_id % 4) + 1; int prev = ((chip_id + 2) % 4) + 1; diff --git a/software/router.c b/software/router.c index e4d19b4..1933b04 100644 --- a/software/router.c +++ b/software/router.c @@ -50,6 +50,7 @@ int main(void) { if (chip_id == 1) { setup_ucie(UCIE0_REG_BASE); reg_write64(UCIE0_REG_BASE + UCIE_MAINBAND_MODE, UCIE_BAND_MODE_TL); + reset_datapath(UCIE0_REG_BASE); printf("Set up UCIe 0 for chip 1\n"); program_router(0, 2, 0); // Chip 1 UCIe0 -> Chip 2 UCIe1 rw_mem(OFFCHIP_OFFSET * 2); @@ -57,6 +58,7 @@ int main(void) { } else { setup_ucie(UCIE1_REG_BASE); reg_write64(UCIE1_REG_BASE + UCIE_MAINBAND_MODE, UCIE_BAND_MODE_TL); + reset_datapath(UCIE1_REG_BASE); printf("Set up UCIe 1 for chip 2\n"); program_router(0, 1, 1); // Chip 2 UCIe1 -> Chip 1 UCIe0 rw_mem(OFFCHIP_OFFSET * 1); diff --git a/software/tacit-always.c b/software/tacit-always.c index 0037349..3b597cf 100644 --- a/software/tacit-always.c +++ b/software/tacit-always.c @@ -36,7 +36,8 @@ static void branch_workload(void) int main(void) { - for (unsigned tile = 0; tile < 3; tile++) { + // One encoder per tile: the Shuttle tile and Rocket. + for (unsigned tile = 0; tile < 2; tile++) { tacit_select_always(tile); } branch_workload(); diff --git a/software/ucie-loopback.c b/software/ucie-loopback.c index be5ad6f..22fd3e0 100644 --- a/software/ucie-loopback.c +++ b/software/ucie-loopback.c @@ -54,9 +54,11 @@ int main(void) { printf("Setting up UCIe0\n"); setup_ucie(UCIE0_REG_BASE); reg_write64(UCIE0_REG_BASE + UCIE_MAINBAND_MODE, UCIE_BAND_MODE_TL); + reset_datapath(UCIE0_REG_BASE); printf("Setting up UCIe1\n"); setup_ucie(UCIE1_REG_BASE); reg_write64(UCIE1_REG_BASE + UCIE_MAINBAND_MODE, UCIE_BAND_MODE_TL); + reset_datapath(UCIE1_REG_BASE); printf("Testing UCIe at port 0\n"); program_router(0, 1, 0); diff --git a/software/ucie-vec-memcpy.c b/software/ucie-vec-memcpy.c index 7500c9e..afef76d 100644 --- a/software/ucie-vec-memcpy.c +++ b/software/ucie-vec-memcpy.c @@ -1,7 +1,7 @@ // two-chip UCIe RVV memcpy test // -// hart 0/1 are the Shuttle/OPU cores -// hart 2 is the Rocket tile with Saturn DMA +// hart 0 is the Shuttle/OPU core +// hart 1 is the Rocket tile with Saturn DMA // BENCH_HART_ID picks which hart runs this test #include @@ -24,10 +24,10 @@ #define COPY_BYTES 256 #endif -// Which hart runs the test. Hart 2 is the Saturn-DMA-only rocket tile added +// Which hart runs the test. Hart 1 is the Saturn-DMA-only rocket tile added // by IrisConfig's "Saturn DMA" line. Tunable: -DBENCH_HART_ID=. #ifndef BENCH_HART_ID -#define BENCH_HART_ID 2 +#define BENCH_HART_ID 1 #endif // Aligned to the 32-byte beat so the natural-alignment path is exercised. @@ -57,6 +57,7 @@ void __main(void) // ============================================================ setup_ucie(UCIE0_REG_BASE); reg_write64(UCIE0_REG_BASE + UCIE_MAINBAND_MODE, UCIE_BAND_MODE_TL); + reset_datapath(UCIE0_REG_BASE); program_router(0, 2, 0); uint64_t peer_chip_id = 2; @@ -90,6 +91,7 @@ void __main(void) // ============================================================ setup_ucie(UCIE1_REG_BASE); reg_write64(UCIE1_REG_BASE + UCIE_MAINBAND_MODE, UCIE_BAND_MODE_TL); + reset_datapath(UCIE1_REG_BASE); program_router(0, 1, 1); *done_flag = 0; diff --git a/software/ucie.h b/software/ucie.h index a01c8fe..286df8c 100644 --- a/software/ucie.h +++ b/software/ucie.h @@ -16,48 +16,51 @@ #define UCIE_TX_DATA_MODE 0x10ULL #define UCIE_TX_LFSR_SEED 0x18ULL #define UCIE_TX_LFSR_SEED_WIDTH 0x8ULL -#define UCIE_TX_RST 0xb0ULL -#define UCIE_TX_EXECUTE 0xb8ULL -#define UCIE_TX_WRITE_CHUNK 0xc0ULL -#define UCIE_TX_PACKETS_SENT 0xc8ULL -#define UCIE_TX_MANUAL_REPEAT_PERIOD 0xd0ULL -#define UCIE_TX_PACKETS_TO_SEND 0xd8ULL -#define UCIE_TX_CLK_P 0xe0ULL -#define UCIE_TX_CLK_N 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_DIVIDER_RST 0xb0ULL +#define UCIE_RX_DIVIDER_RST 0xb8ULL +#define UCIE_TX_DATAPATH_RST 0xc0ULL +#define UCIE_TX_FSM_RST 0xc8ULL +#define UCIE_TX_EXECUTE 0xd0ULL +#define UCIE_TX_WRITE_CHUNK 0xd8ULL +#define UCIE_TX_PACKETS_SENT 0xe0ULL +#define UCIE_TX_MANUAL_REPEAT_PERIOD 0xe8ULL +#define UCIE_TX_PACKETS_TO_SEND 0xf0ULL +#define UCIE_TX_CLK_P 0xf8ULL +#define UCIE_TX_CLK_N 0x100ULL +#define UCIE_TX_DATA_LANE_GROUP 0x108ULL +#define UCIE_TX_DATA_OFFSET 0x110ULL +#define UCIE_TX_DATA_CHUNK_IN0 0x118ULL +#define UCIE_TX_DATA_CHUNK_IN1 0x120ULL +#define UCIE_TX_DATA_CHUNK_OUT0 0x128ULL +#define UCIE_TX_DATA_CHUNK_OUT1 0x130ULL +#define UCIE_TX_TEST_STATE 0x138ULL +#define UCIE_RX_DATA_MODE 0x140ULL +#define UCIE_RX_LFSR_SEED 0x148ULL #define UCIE_RX_LFSR_SEED_WIDTH 0x8ULL -#define UCIE_RX_BIT_ERRORS 0x1c8ULL +#define UCIE_RX_BIT_ERRORS 0x1e0ULL #define UCIE_RX_BIT_ERRORS_WIDTH 0x8ULL -#define UCIE_RX_BIT_ERRORS_EARLY 0x260ULL +#define UCIE_RX_BIT_ERRORS_EARLY 0x278ULL #define UCIE_RX_BIT_ERRORS_EARLY_WIDTH 0x8ULL -#define UCIE_RX_BIT_ERRORS_LATE 0x2f8ULL +#define UCIE_RX_BIT_ERRORS_LATE 0x310ULL #define UCIE_RX_BIT_ERRORS_LATE_WIDTH 0x8ULL -#define UCIE_RX_RST 0x390ULL -#define UCIE_RX_PACKETS_TO_RECEIVE 0x398ULL -#define UCIE_RX_PAUSE_COUNTERS 0x3a0ULL -#define UCIE_RX_PACKETS_RECEIVED 0x3a8ULL -#define UCIE_RX_SIGNATURE 0x3b0ULL -#define UCIE_RX_DATA_LANE 0x3b8ULL -#define UCIE_RX_DATA_OFFSET 0x3c0ULL -#define UCIE_RX_DATA_CHUNK 0x3c8ULL -#define UCIE_CLK_PHASE_SEL 0x3d0ULL -#define UCIE_CLK_FREQ_SEL 0x3d8ULL -#define UCIE_TXCTL 0x3e0ULL +#define UCIE_RX_DATAPATH_RST 0x3a8ULL +#define UCIE_RX_FSM_RST 0x3b0ULL +#define UCIE_RX_PACKETS_TO_RECEIVE 0x3b8ULL +#define UCIE_RX_PAUSE_COUNTERS 0x3c0ULL +#define UCIE_RX_PACKETS_RECEIVED 0x3c8ULL +#define UCIE_RX_SIGNATURE 0x3d0ULL +#define UCIE_RX_IDLE_WORDS_OBSERVED 0x3d8ULL +#define UCIE_RX_DATA_LANE 0x3e0ULL +#define UCIE_RX_DATA_OFFSET 0x3e8ULL +#define UCIE_RX_DATA_CHUNK 0x3f0ULL +#define UCIE_TXCTL 0x3f8ULL #define UCIE_TXCTL_TILE_OFS 0x0ULL #define UCIE_TXCTL_SHUFFLER_OFS 0x8ULL #define UCIE_TXCTL_SHUFFLER_WIDTH 0x8ULL #define UCIE_TXCTL_SAMPLE_NEGEDGE_OFS 0x108ULL #define UCIE_TXCTL_DELAY_OFS 0x110ULL #define UCIE_TXCTL_WIDTH 0x118ULL -#define UCIE_RXCTL 0x1ad8ULL +#define UCIE_RXCTL 0x1af0ULL #define UCIE_RXCTL_ZEN_OFS 0x0ULL #define UCIE_RXCTL_ZCTL_OFS 0x8ULL #define UCIE_RXCTL_VREF_SEL_OFS 0x10ULL @@ -70,46 +73,146 @@ #define UCIE_RXCTL_SAMPLE_NEGEDGE_OFS 0x138ULL #define UCIE_RXCTL_RX_DELAY_OFS 0x140ULL #define UCIE_RXCTL_WIDTH 0x148ULL -#define UCIE_DEBUG_TX_TEST_MODE 0x35c0ULL -#define UCIE_DEBUG_TX_DATA_MODE 0x35c8ULL -#define UCIE_DEBUG_TX_LFSR_SEED 0x35d0ULL -#define UCIE_DEBUG_TX_FSM_RST 0x35d8ULL -#define UCIE_DEBUG_TX_EXECUTE 0x35e0ULL -#define UCIE_DEBUG_TX_MANUAL_REPEAT_PERIOD 0x35e8ULL -#define UCIE_DEBUG_TX_PACKETS_TO_SEND 0x35f0ULL -#define UCIE_DEBUG_DATA 0x35f8ULL +#define UCIE_DEBUG_TX_TEST_MODE 0x35d8ULL +#define UCIE_DEBUG_TX_DATA_MODE 0x35e0ULL +#define UCIE_DEBUG_TX_LFSR_SEED 0x35e8ULL +#define UCIE_DEBUG_TX_FSM_RST 0x35f0ULL +#define UCIE_DEBUG_TX_EXECUTE 0x35f8ULL +#define UCIE_DEBUG_TX_MANUAL_REPEAT_PERIOD 0x3600ULL +#define UCIE_DEBUG_TX_PACKETS_TO_SEND 0x3608ULL +#define UCIE_DEBUG_DATA 0x3610ULL #define UCIE_DEBUG_DATA_WIDTH 0x8ULL -#define UCIE_DEBUG_DRIVERCTL 0x3678ULL +#define UCIE_DEBUG_DRIVERCTL 0x3690ULL #define UCIE_DEBUG_DRIVERCTL_WIDTH 0x8ULL -#define UCIE_DEBUG_TXCTL_TILE 0x3698ULL -#define UCIE_DEBUG_TXCTL_SHUFFLER 0x36a0ULL +#define UCIE_DEBUG_TXCTL_TILE 0x36b0ULL +#define UCIE_DEBUG_TXCTL_SHUFFLER 0x36b8ULL #define UCIE_DEBUG_TXCTL_SHUFFLER_WIDTH 0x8ULL -#define UCIE_DEBUG_TX_TEST_STATE 0x37a0ULL -#define UCIE_DEBUG_TX_PACKETS_SENT 0x37a8ULL -#define UCIE_DEBUG_CLK_MUX_SEL 0x37b0ULL -#define UCIE_DEBUG_RX_LANE 0x37b8ULL -#define UCIE_DEBUG_RX_BIT 0x37c0ULL -#define UCIE_TX_VALID 0x37c8ULL -#define UCIE_RX_LFSR_VALID 0x37d0ULL -#define UCIE_CONTROLLER_SEL 0x37d8ULL -#define UCIE_MAINBAND_MODE 0x37e0ULL -#define UCIE_SIDEBAND_MODE 0x37e8ULL -#define UCIE_CREDIT_FLOW_ENABLE 0x37f0ULL -#define UCIE_TX_VALID_LANE_SEL 0x37f8ULL -#define UCIE_RX_VALID_LANE_SEL 0x3800ULL -#define UCIE_LAST_SEEN_TL_REQ 0x3808ULL -#define UCIE_SB_TX_PACKET 0x3810ULL -#define UCIE_SB_TX_SEND 0x3818ULL -#define UCIE_SB_TX_BUSY 0x3820ULL -#define UCIE_SB_RX_PACKET 0x3828ULL -#define UCIE_SB_RX_VALID 0x3830ULL -#define UCIE_SB_RX_POP 0x3838ULL -#define UCIE_SB_RX_OVERFLOW 0x3840ULL -#define UCIE_SB_RX_RST 0x3848ULL -#define UCIE_SB_TL_RX_OVERFLOW 0x3850ULL -#define UCIE_UCIE_LINK_RESET 0x3858ULL -#define UCIE_UCIE_PWR_GOOD 0x3860ULL -#define UCIE_UCIE_RETRY_TRAINING_AMT 0x3868ULL +#define UCIE_DEBUG_TX_TEST_STATE 0x37b8ULL +#define UCIE_DEBUG_TX_PACKETS_SENT 0x37c0ULL +#define UCIE_DEBUG_CLK_MUX_SEL 0x37c8ULL +#define UCIE_DEBUG_RX_LANE 0x37d0ULL +#define UCIE_DEBUG_RX_BIT 0x37d8ULL +#define UCIE_TX_VALID 0x37e0ULL +#define UCIE_RX_LFSR_VALID 0x37e8ULL +#define UCIE_CONTROLLER_SEL 0x37f0ULL +#define UCIE_MAINBAND_MODE 0x37f8ULL +#define UCIE_SIDEBAND_MODE 0x3800ULL +#define UCIE_CREDIT_FLOW_ENABLE 0x3808ULL +#define UCIE_TX_VALID_LANE_SEL 0x3810ULL +#define UCIE_RX_VALID_LANE_SEL 0x3818ULL +#define UCIE_LAST_SEEN_TL_REQ 0x3820ULL +#define UCIE_SB_TX_PACKET 0x3828ULL +#define UCIE_SB_TX_SEND 0x3830ULL +#define UCIE_SB_TX_BUSY 0x3838ULL +#define UCIE_SB_RX_PACKET 0x3840ULL +#define UCIE_SB_RX_VALID 0x3848ULL +#define UCIE_SB_RX_POP 0x3850ULL +#define UCIE_SB_RX_OVERFLOW 0x3858ULL +#define UCIE_SB_RX_RST 0x3860ULL +#define UCIE_SB_TL_RX_OVERFLOW 0x3868ULL +#define UCIE_PCIE_EXT_CAP_ID 0x4000ULL +#define UCIE_DVSEC_VENDOR_ID 0x4004ULL +#define UCIE_DVSEC_ID 0x4008ULL +#define UCIE_RAW_FORMAT 0x400cULL +#define UCIE_RAW_FORMAT_ENABLE 0x4010ULL +#define UCIE_RAW_FORMAT_ENABLED 0x4014ULL +#define UCIE_LINK_STATUS_CHANGED_INT_EN 0x4018ULL +#define UCIE_LOCATOR0_BIR 0x401cULL +#define UCIE_LOCATOR0_BLOCK_OFFSET_HI 0x4020ULL +#define UCIE_LOCATOR1_BIR 0x4024ULL +#define UCIE_LOCATOR1_BLOCK_OFFSET_HI 0x4028ULL +#define UCIE_MAILBOX_OPCODE 0x402cULL +#define UCIE_MAILBOX_ADDR_HI 0x4030ULL +#define UCIE_MAILBOX_DATA_LO 0x4034ULL +#define UCIE_MAILBOX_DATA_HI 0x4038ULL +#define UCIE_MAILBOX_TRIGGER 0x403cULL +#define UCIE_MAILBOX_STATUS 0x4040ULL +#define UCIE_VENDOR_ID 0x5000ULL +#define UCIE_VENDOR_REG_BLOCK_VERSION 0x5004ULL +#define UCIE_VENDOR_REG_BLOCK_LENGTH 0x5008ULL +#define UCIE_VENDOR_REG_BLOCK_RESERVED 0x500cULL +#define UCIE_UNCORR_ERR_STATUS 0x5010ULL +#define UCIE_UNCORR_ERR_MASK 0x5014ULL +#define UCIE_UNCORR_ERR_SEVERITY 0x5018ULL +#define UCIE_CORR_ERR_STATUS 0x501cULL +#define UCIE_CORR_ERR_MASK 0x5020ULL +#define UCIE_HEADER_LOG1_LO 0x5024ULL +#define UCIE_HEADER_LOG1_HI 0x5028ULL +#define UCIE_HL2_TIMEOUT_ENC 0x502cULL +#define UCIE_REMOTE_REG_ACCESS_THRESHOLD 0x5030ULL +#define UCIE_PARITY_LOG0_LO 0x5034ULL +#define UCIE_PARITY_LOG0_HI 0x5038ULL +#define UCIE_PARITY_LOG1_LO 0x503cULL +#define UCIE_PARITY_LOG1_HI 0x5040ULL +#define UCIE_PARITY_LOG2_LO 0x5044ULL +#define UCIE_PARITY_LOG2_HI 0x5048ULL +#define UCIE_PARITY_LOG3_LO 0x504cULL +#define UCIE_PARITY_LOG3_HI 0x5050ULL +#define UCIE_ADV_ADAPTER_CAP_LO 0x5054ULL +#define UCIE_ADV_ADAPTER_CAP_HI 0x5058ULL +#define UCIE_FIN_ADAPTER_CAP_LO 0x505cULL +#define UCIE_FIN_ADAPTER_CAP_HI 0x5060ULL +#define UCIE_ADV_CXL_CAP_LO 0x5064ULL +#define UCIE_ADV_CXL_CAP_HI 0x5068ULL +#define UCIE_FIN_CXL_CAP_LO 0x506cULL +#define UCIE_FIN_CXL_CAP_HI 0x5070ULL +#define UCIE_ADV_MULTIPROT_CAP_LO 0x5078ULL +#define UCIE_ADV_MULTIPROT_CAP_HI 0x507cULL +#define UCIE_FIN_MULTIPROT_CAP_LO 0x5080ULL +#define UCIE_FIN_MULTIPROT_CAP_HI 0x5084ULL +#define UCIE_ADV_CXL_CAP_STACK1_LO 0x5088ULL +#define UCIE_ADV_CXL_CAP_STACK1_HI 0x508cULL +#define UCIE_FIN_CXL_CAP_STACK1_LO 0x5090ULL +#define UCIE_FIN_CXL_CAP_STACK1_HI 0x5094ULL +#define UCIE_PHY_CAP_RSVD 0x6000ULL +#define UCIE_PHY_CTRL_RSVD 0x6004ULL +#define UCIE_PHY_STATUS_RSVD 0x6008ULL +#define UCIE_INIT_CONTROL 0x600cULL +#define UCIE_RLT_CTRL 0x6100ULL +#define UCIE_MODULE3_LANE_REPAIR_ID_RSVD_HI 0x6104ULL +#define UCIE_RUNTIME_LINK_TEST_BUSY 0x6108ULL +#define UCIE_NULL_EXT_CAP 0x6200ULL +#define UCIE_TS1_DATA_PATTERN_M0 0x6010ULL +#define UCIE_TS2_IDLE_COUNT_M0 0x6020ULL +#define UCIE_TS3_LANE_MASK_LO_M0 0x6030ULL +#define UCIE_TS3_LANE_MASK_HI_M0 0x6034ULL +#define UCIE_TS4_REPAIR_LANE_MASK_M0 0x6050ULL +#define UCIE_CURRENT_LANE_MAP_LO_M0 0x6060ULL +#define UCIE_CURRENT_LANE_MAP_HI_M0 0x6064ULL +#define UCIE_ERR_LOG0_STATE_NM0 0x6080ULL +#define UCIE_ERR_LOG1_STATE_NM3_M0 0x6090ULL +#define UCIE_VENDOR_REG_BLOCK_RSVD 0x700cULL +#define UCIE_VENDOR_DEBUG_UNLOCK 0x7010ULL +#define UCIE_VENDOR_FORCE_LINK_ACTIVE 0x7014ULL +#define UCIE_VENDOR_TS_OVERRIDE_EN 0x7018ULL +#define UCIE_UCIE_LINK_RESET 0x3c00ULL +#define UCIE_UCIE_PWR_GOOD 0x3c08ULL +#define UCIE_UCIE_RETRY_TRAINING_AMT 0x3c10ULL +#define UCIE_MAIN_CLK_SEL 0x10000ULL +#define UCIE_PLL8_EN 0x10008ULL +#define UCIE_PLL12_EN 0x10010ULL +#define UCIE_X2_EN 0x10018ULL +#define UCIE_TX_CLK_DIV 0x10020ULL +#define UCIE_TX_CLK_PHASE 0x10028ULL +#define UCIE_PHY_TEST_CLK_DIV 0x10030ULL +#define UCIE_PHY_TEST_CLK_BYPASS_EN 0x10038ULL +#define UCIE_CLK_PHASE_SEL 0x10040ULL +#define UCIE_CLK_GATE_EN 0x10048ULL +#define UCIE_RX_CLK_GATE_EN 0x10050ULL +#define UCIE_FREQ_SEL_AUTO_EN 0x10058ULL +#define UCIE_FREQ_SEL_OBSERVED 0x10060ULL +#define UCIE_SB_CLK_DIV 0x10068ULL +#define UCIE_SB_CLK_BYPASS_EN 0x10070ULL +#define UCIE_RX_CLK_FROM_TX_Q 0x10078ULL +#define UCIE_CLK_CFG_APPLY 0x10080ULL +#define UCIE_CLK_CFG_BUSY 0x10088ULL +#define UCIE_CLK_CFG_UNGATE_SRC 0x10090ULL +#define UCIE_CLK_CFG_UNGATE_DELAY 0x10098ULL +#define UCIE_CLK_CFG_UNGATE_REQ 0x100a0ULL +#define UCIE_PLL_LOCK_OBSERVED 0x100a8ULL +#define UCIE_UCIE_RST 0x100b0ULL +#define UCIE_RATE_CFG 0x10100ULL +#define UCIE_RATE_CFG_WIDTH 0x8ULL // === Constants === #define UCIE_TX_TEST_STATE_IDLE 0x0ULL @@ -130,12 +233,43 @@ #define UCIE_DEFAULT_VALID 0xf0f0f0fULL #define UCIE_DEFAULT_TRACK 0x55555555ULL #define UCIE_ENABLE_DRIVER_CTL 0x3ffeULL -#define UCIE_ENABLE_TX_CTL 0x1fff000000000ULL +#define UCIE_ENABLE_TX_CTL 0x3fffff000000000ULL +#define UCIE_TX_CTL_DELAY_LSB 0x0ULL +#define UCIE_TX_CTL_ENP_LSB 0x31ULL +#define UCIE_TX_CTL_ENN_LSB 0x28ULL +#define UCIE_TX_CTL_ENP_EQ_LSB 0x24ULL +#define UCIE_TX_CTL_ENN_EQ_LSB 0x20ULL +#define UCIE_TRAIN_LFSR_SEED 0x123456789abcdefULL +#define UCIE_TRAIN_DATA_LANES 0x10ULL +#define UCIE_TRAIN_VALID_LANE 0x10ULL +#define UCIE_TRAIN_SCORE_LANES 0x11ULL +#define UCIE_RATE_CFG_MAIN_CLK_SEL_LSB 0x8ULL +#define UCIE_RATE_CFG_TX_CLK_DIV_LSB 0x6ULL +#define UCIE_RATE_CFG_PHY_TEST_CLK_DIV_LSB 0x3ULL +#define UCIE_TRAIN_EYE_FINE_POINTS 0x4ULL +#define UCIE_TRAIN_EYE_FINE_STEP 0x10ULL +#define UCIE_TRAIN_EYE_DIVS 0x3ULL +#define UCIE_TRAIN_GLOBAL_CODES 0x10ULL +#define UCIE_TRAIN_GLOBAL_STEP 0x4ULL +#define UCIE_TRAIN_LOCAL_CODES 0x10ULL +#define UCIE_TRAIN_LOCAL_STEP 0x2ULL +#define UCIE_TRAIN_VREF_CODES 0x10ULL +#define UCIE_TRAIN_VREF_STEP 0x8ULL +#define UCIE_TRAIN_PACKETS 0x10ULL +#define UCIE_TRAIN_SLIP_RATIO 0x4ULL +#define UCIE_CLK_UNGATE_SRC_PLL_LOCK 0x0ULL +#define UCIE_CLK_UNGATE_SRC_MMIO 0x1ULL +#define UCIE_CLK_UNGATE_SRC_DELAY 0x2ULL // === Helper functions === +static inline void reset_datapath(uintptr_t base) { + reg_write64(base + UCIE_TX_DATAPATH_RST, 0x1ULL); + reg_write64(base + UCIE_RX_DATAPATH_RST, 0x1ULL); +} static inline void reset_fsms(uintptr_t base) { - reg_write64(base + UCIE_TX_RST, 0x1ULL); - reg_write64(base + UCIE_RX_RST, 0x1ULL); + reset_datapath(base); + reg_write64(base + UCIE_TX_FSM_RST, 0x1ULL); + reg_write64(base + UCIE_RX_FSM_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)); @@ -150,7 +284,77 @@ static inline void write_rxctl(uintptr_t base, uint64_t lane, uint64_t ofs, uint reg_write64(base + UCIE_RXCTL + lane * UCIE_RXCTL_WIDTH + ofs, v); } +static inline void set_clk_gate(uintptr_t base, uint64_t en) { + reg_write64(base + UCIE_CLK_GATE_EN, en); +} +static inline void set_rate_cfg(uintptr_t base, uint64_t rate, uint64_t main_sel, uint64_t tx_div, uint64_t phytest_div, uint64_t pll_en) { + reg_write64(base + UCIE_RATE_CFG + rate * UCIE_RATE_CFG_WIDTH, ((main_sel << UCIE_RATE_CFG_MAIN_CLK_SEL_LSB) | (tx_div << UCIE_RATE_CFG_TX_CLK_DIV_LSB) | (phytest_div << UCIE_RATE_CFG_PHY_TEST_CLK_DIV_LSB) | pll_en)); +} +static inline void set_freq_sel_auto(uintptr_t base, uint64_t en) { + reg_write64(base + UCIE_FREQ_SEL_AUTO_EN, en); +} +static inline void apply_clk_cfg(uintptr_t base) { + reg_write64(base + UCIE_CLK_CFG_APPLY, 0x1ULL); + for (int w = 0; w < 256; w++) { + uint64_t busy; + busy = reg_read64(base + UCIE_CLK_CFG_BUSY); + if (busy == 0) { + break; + } + } +} +static inline void set_ungate_src(uintptr_t base, uint64_t src, uint64_t delay) { + reg_write64(base + UCIE_CLK_CFG_UNGATE_SRC, src); + reg_write64(base + UCIE_CLK_CFG_UNGATE_DELAY, delay); +} +static inline void release_clk_gate(uintptr_t base) { + reg_write64(base + UCIE_CLK_CFG_UNGATE_REQ, 0x1ULL); +} +static inline void reset_ucie(uintptr_t base) { + reg_write64(base + UCIE_UCIE_RST, 0x1ULL); + reg_write64(base + UCIE_UCIE_RST, 0x0ULL); +} +static inline void reset_dividers(uintptr_t base) { + reg_write64(base + UCIE_TX_DIVIDER_RST, 0x1ULL); + reg_write64(base + UCIE_RX_DIVIDER_RST, 0x1ULL); + reg_write64(base + UCIE_TX_DIVIDER_RST, 0x0ULL); + reg_write64(base + UCIE_RX_DIVIDER_RST, 0x0ULL); +} +static inline void set_main_clk(uintptr_t base, uint64_t src, uint64_t div) { + reg_write64(base + UCIE_MAIN_CLK_SEL, src); + reg_write64(base + UCIE_TX_CLK_DIV, div); + reg_write64(base + UCIE_CLK_GATE_EN, 0x1ULL); + apply_clk_cfg(base); +} +static inline void set_tx_phase(uintptr_t base, uint64_t half_cycles) { + reg_write64(base + UCIE_CLK_GATE_EN, 0x0ULL); + reg_write64(base + UCIE_TX_CLK_PHASE, half_cycles); + reg_write64(base + UCIE_CLK_GATE_EN, 0x1ULL); +} +static inline void use_internal_clk(uintptr_t base, uint64_t phytest_div) { + reg_write64(base + UCIE_PLL8_EN, 0x1ULL); + reg_write64(base + UCIE_PLL12_EN, 0x1ULL); + reg_write64(base + UCIE_X2_EN, 0x1ULL); + reg_write64(base + UCIE_PHY_TEST_CLK_DIV, phytest_div); + reg_write64(base + UCIE_PHY_TEST_CLK_BYPASS_EN, 0x0ULL); + apply_clk_cfg(base); +} +static inline void set_rx_clk_gate(uintptr_t base, uint64_t en) { + reg_write64(base + UCIE_RX_CLK_GATE_EN, en); +} +static inline void set_global_delay(uintptr_t base, uint64_t taps) { + reg_write64(base + UCIE_CLK_PHASE_SEL, ((0x1ULL << taps) - 0x1ULL)); +} +static inline void set_tx_delay(uintptr_t base, uint64_t lane, uint64_t taps) { + write_txctl(base, lane, UCIE_TXCTL_TILE_OFS, (UCIE_ENABLE_TX_CTL | (((0x1ULL << taps) - 0x1ULL) << UCIE_TX_CTL_DELAY_LSB))); +} + +static inline void set_rx_vref(uintptr_t base, uint64_t lane, uint64_t code) { + write_rxctl(base, lane, UCIE_RXCTL_VREF_SEL_OFS, code); +} + static inline void setup_ucie(uintptr_t base) { + reset_ucie(base); for (int lane = 0; lane < 21; lane++) { write_txctl(base, lane, UCIE_TXCTL_TILE_OFS, UCIE_ENABLE_TX_CTL); write_rxctl(base, lane, UCIE_RXCTL_ZEN_OFS, 0x1ULL); @@ -164,10 +368,75 @@ static inline void setup_ucie(uintptr_t base) { reg_write64(base + UCIE_DEBUG_DRIVERCTL + 8 * i, UCIE_ENABLE_DRIVER_CTL); } reg_write64(base + UCIE_DEBUG_TXCTL_TILE, UCIE_ENABLE_TX_CTL); - reset_fsms(base); + set_clk_gate(base, 0x0ULL); + reset_dividers(base); + set_clk_gate(base, 0x1ULL); reg_write64(base + UCIE_CONTROLLER_SEL, UCIE_CONTROLLER_SEL_PHYTEST); reg_write64(base + UCIE_MAINBAND_MODE, UCIE_BAND_MODE_MANUAL); reg_write64(base + UCIE_SIDEBAND_MODE, UCIE_BAND_MODE_MANUAL); + reset_fsms(base); +} + +static inline void setup_ucie_digital(uintptr_t base) { + set_clk_gate(base, 0x0ULL); + set_global_delay(base, 0x1dULL); + reset_dividers(base); + set_clk_gate(base, 0x1ULL); + for (int lane = 0; lane < 20; lane++) { + write_txctl(base, lane, UCIE_TXCTL_TILE_OFS, UCIE_ENABLE_TX_CTL); + } + for (int lane = 0; lane < 18; lane++) { + write_rxctl(base, lane, UCIE_RXCTL_ZEN_OFS, 0x1ULL); + write_rxctl(base, lane, UCIE_RXCTL_ZCTL_OFS, 0x0ULL); + } + reg_write64(base + UCIE_CONTROLLER_SEL, UCIE_CONTROLLER_SEL_UCIE); + reset_datapath(base); + { + uint64_t linkControl; + linkControl = reg_read64(base + UCIE_RAW_FORMAT_ENABLE); + reg_write64(base + UCIE_RAW_FORMAT_ENABLE, linkControl | 0x401ULL); + } + reg_write64(base + UCIE_UNCORR_ERR_MASK, 0x0ULL); + reg_write64(base + UCIE_CORR_ERR_MASK, 0x0ULL); + while (1) { + uint64_t linkStatus; + linkStatus = reg_read64(base + UCIE_RAW_FORMAT_ENABLED); + if ((linkStatus >> 0xfULL) & 0x1ULL) { + break; + } + } +} + +static inline void seed_lfsrs(uintptr_t base) { + for (int i = 0; i < 19; i++) { + reg_write64(base + UCIE_TX_LFSR_SEED + i * UCIE_TX_LFSR_SEED_WIDTH, UCIE_TRAIN_LFSR_SEED); + reg_write64(base + UCIE_RX_LFSR_SEED + i * UCIE_RX_LFSR_SEED_WIDTH, UCIE_TRAIN_LFSR_SEED); + } +} + +static inline void run_lfsr(uintptr_t base, uint64_t packets) { + reset_fsms(base); + for (int s = 0; s < 64; s++) { + uint64_t settle_w; + settle_w = reg_read64(base + UCIE_RX_IDLE_WORDS_OBSERVED); + if (settle_w >= 4) { + break; + } + } + reg_write64(base + UCIE_TEST_TARGET, UCIE_TEST_TARGET_MAINBAND); + reg_write64(base + UCIE_TX_TEST_MODE, UCIE_TX_TEST_MODE_LFSR); + reg_write64(base + UCIE_TX_DATA_MODE, UCIE_DATA_MODE_FINITE); + reg_write64(base + UCIE_RX_DATA_MODE, UCIE_DATA_MODE_FINITE); + reg_write64(base + UCIE_RX_PACKETS_TO_RECEIVE, packets); + reg_write64(base + UCIE_TX_PACKETS_TO_SEND, packets); + reg_write64(base + UCIE_TX_EXECUTE, 0x1ULL); + for (int w = 0; w < 16; w++) { + uint64_t r; + r = reg_read64(base + UCIE_RX_PACKETS_RECEIVED); + if (r >= packets) { + break; + } + } } #endif diff --git a/src/Iris.scala b/src/Iris.scala index e4eb9af..85abb95 100644 --- a/src/Iris.scala +++ b/src/Iris.scala @@ -29,6 +29,8 @@ import freechips.rocketchip.subsystem._ import freechips.rocketchip.prci._ import freechips.rocketchip.devices.debug._ import freechips.rocketchip.devices.tilelink.BootROMLocated +import freechips.rocketchip.tilelink.{TLBuffer, TLFragmenter, TLWidthWidget} +import edu.berkeley.cs.uciedigital.tilelink.UcieChipletLink import freechips.rocketchip.util._ import sifive.blocks.inclusivecache.{InclusiveCachePortParameters} @@ -63,6 +65,20 @@ class IrisTop(implicit p: Parameters) extends LazyModule with BindingScope { .fixedClockNode def debugClockBundle = debugClockSinkNode.in.head._1 + // Each UCIe link's register port, on the chiplet router's control bus. The + // router cannot attach these itself: each is a crossbar in front of UcieTL's + // register blocks, not the bare register node it takes. + system.d2d_ports.foreach { ports => + val cbus = system.locateTLBusWrapper(p(ChipletRoutingKey).get.controlBusWhere) + val links = ports.collect { case link: UcieChipletLink => link } + links.foreach { link => + cbus.coupleTo(s"${link.name}_control") { + link.regNode := TLWidthWidget(cbus.beatBytes) := TLBuffer() := + TLFragmenter(cbus) := _ + } + } + } + override lazy val module = new IrisTopImpl class IrisTopImpl extends LazyRawModuleImp(this) with DontTouch { val io = IO(new Bundle { @@ -130,7 +146,7 @@ class IrisTop(implicit p: Parameters) extends LazyModule with BindingScope { // IrisConfig and IrisDryRunConfig differ only in // * the SBUS NoC node mapping, and // * which optional blocks are present: the Rocket Saturn DMA vector unit, the -// two Shuttle tiles with their Saturn OPU, and the UCIe chiplet router. +// Shuttle tile with its Saturn OPU, and the UCIe chiplet router. // Everything else is identical and lives in the fragments below. // // These are several fragments rather than one block because CDE composition is @@ -140,8 +156,8 @@ class IrisTop(implicit p: Parameters) extends LazyModule with BindingScope { // sit to the LEFT of WithIrisRocketCore. // * The Shuttle fragments must sit to the RIGHT of WithIrisRocketCore. Tile // ids are handed out from `up(NumTiles)`, so this ordering is what makes the -// Shuttle tiles harts 0-1 and Rocket hart 2 -- which the NoC mapping keys -// off by name ("Core 0 ICache", "Core 2 DCache"). +// Shuttle tile hart 0 and Rocket hart 1 -- which the NoC mapping keys +// off by name ("Core 0 ICache", "Core 1 DCache"). // ============================================================================ /** SBUS NoC parameters. Only the node mapping differs between the two chips; diff --git a/src/TinyIris.scala b/src/TinyIris.scala index 94a0de6..6243c35 100644 --- a/src/TinyIris.scala +++ b/src/TinyIris.scala @@ -29,6 +29,8 @@ import freechips.rocketchip.subsystem._ import freechips.rocketchip.prci._ import freechips.rocketchip.devices.debug._ import freechips.rocketchip.devices.tilelink.BootROMLocated +import freechips.rocketchip.tilelink.{TLBuffer, TLFragmenter, TLWidthWidget} +import edu.berkeley.cs.uciedigital.tilelink.UcieChipletLink import freechips.rocketchip.util._ import sifive.blocks.inclusivecache.{InclusiveCachePortParameters} @@ -44,6 +46,20 @@ class TinyIrisTop(implicit p: Parameters) extends LazyModule with BindingScope { .fixedClockNode def debugClockBundle = debugClockSinkNode.in.head._1 + // Each UCIe link's register port, on the chiplet router's control bus. The + // router cannot attach these itself: each is a crossbar in front of UcieTL's + // register blocks, not the bare register node it takes. + system.d2d_ports.foreach { ports => + val cbus = system.locateTLBusWrapper(p(ChipletRoutingKey).get.controlBusWhere) + val links = ports.collect { case link: UcieChipletLink => link } + links.foreach { link => + cbus.coupleTo(s"${link.name}_control") { + link.regNode := TLWidthWidget(cbus.beatBytes) := TLBuffer() := + TLFragmenter(cbus) := _ + } + } + } + override lazy val module = new IrisTopImpl class IrisTopImpl extends LazyRawModuleImp(this) with DontTouch { val io = IO(new Bundle { diff --git a/test/src/IrisSpec.scala b/test/src/IrisSpec.scala index da209de..01ca0c0 100644 --- a/test/src/IrisSpec.scala +++ b/test/src/IrisSpec.scala @@ -141,28 +141,21 @@ class TestHarness(nChips: Int, binaryPaths: Seq[Path], plusArgs: Seq[Seq[String] val reset = Input(Bool()) }) - val digitalFreqMHz = 500 - - val digitalClock = Wire(Clock()) - val source = Module(new ClockSourceAtFreqMHz(digitalFreqMHz)) - source.io.power := true.B - source.io.gate := false.B - digitalClock := source.io.clk - - val ucieBypassFreqMHz = 8000 - val ucieBypassClock = Wire(Clock()) - val ucieBypassClockSource = Module(new ClockSourceAtFreqMHz(ucieBypassFreqMHz)) - ucieBypassClockSource.io.power := true.B - ucieBypassClockSource.io.gate := false.B - ucieBypassClock := ucieBypassClockSource.io.clk - - val ucieDigitalBypassFreqMHz = 800 - val ucieDigitalBypassClock = Wire(Clock()) - val ucieDigitalBypassClockSource = Module(new ClockSourceAtFreqMHz(ucieDigitalBypassFreqMHz)) - ucieDigitalBypassClockSource.io.power := true.B - ucieDigitalBypassClockSource.io.gate := false.B - ucieDigitalBypassClock := ucieDigitalBypassClockSource.io.clk + // A free-running clock from a simulation clock source. + def freeRunningClock(freqMHz: Double): Clock = { + val source = Module(new ClockSourceAtFreqMHz(freqMHz)) + source.io.power := true.B + source.io.gate := false.B + source.io.clk + } + val digitalFreqMHz = 500 + val digitalClock = freeRunningClock(digitalFreqMHz) + val ucieBypassClock = freeRunningClock(8000) + val ucieDigitalBypassClock = freeRunningClock(800) + val ucieSidebandBypassClock = freeRunningClock(800) + // The clocking tile's PLL reference, as in the UCIe repo's own harness. + val ucieRefClock = freeRunningClock(100) implicit def view[A <: Data, B <: Data] : DataView[testchipip.tsi.TSIIO, TSIIO] = @@ -228,6 +221,8 @@ class TestHarness(nChips: Int, binaryPaths: Seq[Path], plusArgs: Seq[Seq[String] Seq(chiptop.c2c_ucie0, chiptop.c2c_ucie1).foreach { ucie => ucie.phy.bypassClk := ucieBypassClock ucie.phy.digitalBypassClk := ucieDigitalBypassClock + ucie.phy.sidebandBypassClk := ucieSidebandBypassClock + ucie.phy.refClk := ucieRefClock } Seq(chiptop.c2c_ucie0, chiptop.c2c_ucie1) diff --git a/test/src/Utils.scala b/test/src/Utils.scala index f58f577..c14f89f 100644 --- a/test/src/Utils.scala +++ b/test/src/Utils.scala @@ -52,7 +52,7 @@ verilator \\ -CFLAGS "$$CXXFLAGS -O3 -std=c++17 -DVERILATOR -I$$RISCV/include" \\ -LDFLAGS "$$LDFLAGS -L$$RISCV/lib -Wl,-rpath,$$RISCV/lib -lriscv -lfesvr" \\ -F ${sourceFilesList.toString} -script -f -c "./simulation >(spike-dasm > simulation.out)" simulation.log +script -e -f -c "./simulation >(spike-dasm > simulation.out)" simulation.log """ ) path.toIO.setExecutable(true) @@ -89,7 +89,7 @@ vcs \\ +define+layer$$Verification$$Cover$$Temporal \\ +define+VCS +define+FSDB +define+RANDOMIZE_MEM_INIT +define+RANDOMIZE_REG_INIT +define+RANDOMIZE_GARBAGE_ASSIGN +define+RANDOMIZE_INVALID_ASSIGN$debugCompileFlags \\ -o simulation -Mdir=vcs-sources -script -f -c "./simulation +permissive +vcs+thread+16 +dramsim +dramsim_ini_dir=${dramsim_ini.toString}${loadmem.map(p => s" +loadmem=${p.toString}").getOrElse("")}$debugRuntimeFlag +permissive-off placeholder-binary >(spike-dasm > simulation.out)" simulation.log +script -e -f -c "./simulation +permissive +vcs+thread+16 +dramsim +dramsim_ini_dir=${dramsim_ini.toString}${loadmem.map(p => s" +loadmem=${p.toString}").getOrElse("")}$debugRuntimeFlag +permissive-off placeholder-binary >(spike-dasm > simulation.out)" simulation.log """ ) path.toIO.setExecutable(true) @@ -162,5 +162,19 @@ script -f -c "./simulation +permissive +vcs+thread+16 +dramsim +dramsim_ini_dir= "/bin/bash", simScript ).call(stdout = os.Inherit, stderr = os.Inherit, cwd = simDir) + + // The simulator's exit status does not say whether the test passed: VCS + // ends with status 0 after a `$fatal`, whether from SimTop's timeout or + // from a failed assertion. SimTop prints its success line only when the + // chips report success, so the log decides it. + val simLog = os.read(simDir / "simulation.log") + val failure = + Seq("Assertion failed", "Fatal:", "Test timed out!").find(simLog.contains) + assert( + failure.isEmpty && simLog.contains("Test completed successfully."), + failure.fold("simulation ended without reporting success")(f => + s"simulation log reports \"$f\"" + ) + s"; see ${simDir / "simulation.log"}" + ) } } diff --git a/testchipip b/testchipip index fc8013c..86c9a82 160000 --- a/testchipip +++ b/testchipip @@ -1 +1 @@ -Subproject commit fc8013c30e098f46402f1c98543b9d4b7b9b36d2 +Subproject commit 86c9a824fd42b854526018f9111087b0f3d1d31c diff --git a/ucie b/ucie index caf0daf..4db6449 160000 --- a/ucie +++ b/ucie @@ -1 +1 @@ -Subproject commit caf0daf1135f5b87225fa4903fcc3dfb87863de5 +Subproject commit 4db6449716976a79765828a6dc27547c6a0c6366