From 7d88050ecdbfc90b78ca645c01c6d3d62e150724 Mon Sep 17 00:00:00 2001 From: naichewa Date: Wed, 8 Nov 2023 15:20:51 -0800 Subject: [PATCH] fix hardware interlock, hold mode deassert --- src/uncore/spi_apb.sv | 19 +++------- .../rv32i_m/privilege/src/WALLY-spi-01.S | 35 ++----------------- .../rv64i_m/privilege/src/WALLY-spi-01.S | 5 +-- 3 files changed, 10 insertions(+), 49 deletions(-) diff --git a/src/uncore/spi_apb.sv b/src/uncore/spi_apb.sv index 126eff6bb..b51516368 100644 --- a/src/uncore/spi_apb.sv +++ b/src/uncore/spi_apb.sv @@ -27,16 +27,14 @@ // Current limitations: Flash read sequencer mode not implemented, dual and quad modes untestable with current test plan. -// write tests for fifo full and empty watermark edge cases -// test case for two's complement rollover on fifo watermark calculation + watermark calc redesign -// rempty triggers when fifo full, txmark = 7 doesnt work // HoldModeDeassert make sure still works // Comment on FIFOs: watermark calculations // Comment all interface and internal signals on the lines they are declared // Get tabs correct so things line up // Relook at frame compare/ Delay count logic w/o multibit // look at ReadIncrement/WriteIncrement delay necessity -/* high level explanation of architecture + +/* SPI module is written to the specifications described in FU540-C000-v1.0. At the top level, it is consists of synchronous 8 byte transmit and recieve FIFOs connected to shift registers. The FIFOs are connected to WALLY by an apb bus control register interface, which includes various control registers for modifying the SPI transmission along with registers for writing to the transmit FIFO and reading from the receive FIFO. The transmissions themselves are then controlled by a finite state machine. The SPI module uses 4 tristate pins for SPI input/output, @@ -184,7 +182,7 @@ module spi_apb import cvw::*; #(parameter cvw_t P) ( //of entries in tx/rx fifo is strictly more/less than tx/rxmark /* verilator lint_off CASEINCOMPLETE */ - if (Memwrite) + if (Memwrite & TransmitInactive) case(Entry) //flop to sample inputs 8'h00: SckDiv <= Din[11:0]; 8'h04: SckMode <= Din[1:0]; @@ -308,7 +306,6 @@ module spi_apb import cvw::*; #(parameter cvw_t P) ( ACTIVE_1: begin InterXFRCount <= 9'b1; if (FrameCompareBoolean) state <= ACTIVE_0; - else if (HoldModeDeassert) state <= CS_INACTIVE; else if ((ChipSelectMode[1:0] == 2'b10) & ~|(Delay1[15:8]) & (~TransmitFIFOReadEmpty)) begin state <= ACTIVE_0; Delay0Count <= 9'b1; @@ -334,8 +331,7 @@ module spi_apb import cvw::*; #(parameter cvw_t P) ( FrameCount <= 5'b0; InterCSCount <= 9'b10; InterXFRCount <= InterXFRCount + 9'b1; - if (HoldModeDeassert) state <= CS_INACTIVE; - else if (InterXFRCompare & ~TransmitFIFOReadEmptyDelay) state <= ACTIVE_0; + if (InterXFRCompare & ~TransmitFIFOReadEmptyDelay) state <= ACTIVE_0; else if (~|ChipSelectMode[1:0]) state <= CS_INACTIVE; end endcase @@ -353,13 +349,6 @@ module spi_apb import cvw::*; #(parameter cvw_t P) ( assign Active0 = (state == ACTIVE_0); assign Inactive = (state == CS_INACTIVE); - // Ensures that when ChipSelectMode = hold, CS pin is deasserted only when a different value is written to csmode or csid or a write to csdeg changes the state - // of the selected pin - assign PWChipSelect = PWDATA[3:0]; - always_ff @(posedge PCLK, negedge PRESETn) - if (~PRESETn) HoldModeDeassert <= 0; - else if (~Inactive & Memwrite & ((ChipSelectMode[1:0] == 2'b10) & (Entry == (8'h18 | 8'h10) | ((Entry == 8'h14) & (PWChipSelect[ChipSelectID] != ChipSelectDef[ChipSelectID]))))) HoldModeDeassert <= 1; - // Signal tracks which edge of sck to shift data always_comb case(SckMode[1:0]) diff --git a/tests/wally-riscv-arch-test/riscv-test-suite/rv32i_m/privilege/src/WALLY-spi-01.S b/tests/wally-riscv-arch-test/riscv-test-suite/rv32i_m/privilege/src/WALLY-spi-01.S index 75643063d..b9c82c92d 100644 --- a/tests/wally-riscv-arch-test/riscv-test-suite/rv32i_m/privilege/src/WALLY-spi-01.S +++ b/tests/wally-riscv-arch-test/riscv-test-suite/rv32i_m/privilege/src/WALLY-spi-01.S @@ -69,36 +69,6 @@ test_cases: .equ ie, (SPI+0x70) .equ ip, (SPI+0x74) -test_cases: -# --------------------------------------------------------------------------------------------- -# Test Contents -# -# Here is where the actual tests are held, or rather, what the actual tests do. -# each entry consists of 3 values that will be read in as follows: -# -# '.4byte [x28 Value], [x29 Value], [x30 value]' -# or -# '.4byte [address], [value], [test type]' -# -# The encoding for x30 test type values can be found in the test handler in the framework file -# --------------------------------------------------------------------------------------------- - -.equ SPI, 0x10040000 -.equ sck_div, (SPI+0x00) -.equ sck_mode, (SPI+0x04) -.equ cs_id, (SPI+0x10) -.equ cs_def, (SPI+0x14) -.equ cs_mode, (SPI+0x18) -.equ delay0, (SPI+0x28) -.equ delay1, (SPI+0x2C) -.equ fmt, (SPI+0x40) -.equ tx_data, (SPI+0x48) -.equ rx_data, (SPI+0x4C) -.equ tx_mark, (SPI+0x50) -.equ rx_mark, (SPI+0x54) -.equ ie, (SPI+0x70) -.equ ip, (SPI+0x74) - # =========== Verify all registers reset to correct values =========== .4byte sck_div, 0x00000003, read32_test # sck_div reset to 0x3 @@ -405,9 +375,10 @@ test_cases: .4byte cs_mode, 0x00000002, write32_test # set cs_mode to hold .4byte tx_data, 0x000000CE, write32_test # place data into tx_data .4byte cs_id, 0x00000001, write32_test #change selected cs pin. should deassert cs[0] in hold mode -.4byte cs_def, 0x00001101, write32_test # change selected cs pins def value. should deassert cs[1] -.4byte cs_def, 0x00001111, write32_test # reset cs_def +.4byte cs_def, 0x0000000D, write32_test # change selected cs pins def value. should deassert cs[1] .4byte cs_mode, 0x00000000, write32_test # change cs_mode to auto, should deassert cs[1], have now gone through all deassertion conditions +.4byte cs_def, 0x0000000F, write32_test # reset cs_def +.4byte cs_id, 0x00000000, write32_test # reset cs_id .4byte rx_data, 0x000000CE, read32_test # clear rx_fifo # =========== Test frame format (fmt) register =========== diff --git a/tests/wally-riscv-arch-test/riscv-test-suite/rv64i_m/privilege/src/WALLY-spi-01.S b/tests/wally-riscv-arch-test/riscv-test-suite/rv64i_m/privilege/src/WALLY-spi-01.S index 3f2690162..266b0e74f 100644 --- a/tests/wally-riscv-arch-test/riscv-test-suite/rv64i_m/privilege/src/WALLY-spi-01.S +++ b/tests/wally-riscv-arch-test/riscv-test-suite/rv64i_m/privilege/src/WALLY-spi-01.S @@ -377,9 +377,10 @@ test_cases: .8byte cs_mode, 0x00000002, write32_test # set cs_mode to hold .8byte tx_data, 0x000000CE, write32_test # place data into tx_data .8byte cs_id, 0x00000001, write32_test #change selected cs pin. should deassert cs[0] in hold mode -.8byte cs_def, 0x00001101, write32_test # change selected cs pins def value. should deassert cs[1] -.8byte cs_def, 0x00001111, write32_test # reset cs_def +.8byte cs_def, 0x0000000D, write32_test # change selected cs pins def value. should deassert cs[1] .8byte cs_mode, 0x00000000, write32_test # change cs_mode to auto, should deassert cs[1], have now gone through all deassertion conditions +.8byte cs_def, 0x0000000F, write32_test # reset cs_def +.8byte cs_id, 0x00000000, write32_test # reset cs_id .8byte rx_data, 0x000000CE, read32_test # clear rx_fifo # =========== Test frame format (fmt) register ===========