From d66a613074f609962cc56506fd0ccfdd5c6bcdeb Mon Sep 17 00:00:00 2001 From: Huda-10xe Date: Mon, 28 Oct 2024 00:32:07 -0700 Subject: [PATCH 01/30] Renaming VM Coverage --- config/rv32gc/coverage.svh | 3 ++- config/rv64gc/coverage.svh | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/config/rv32gc/coverage.svh b/config/rv32gc/coverage.svh index 3a04643ad..415722efc 100644 --- a/config/rv32gc/coverage.svh +++ b/config/rv32gc/coverage.svh @@ -13,4 +13,5 @@ `include "RV32Zca_coverage.svh" `include "RV32Zcb_coverage.svh" `include "RV32ZcbM_coverage.svh" -`include "RV32ZcbZbb_coverage.svh" \ No newline at end of file +`include "RV32ZcbZbb_coverage.svh" +`include "VM_coverage.svh" \ No newline at end of file diff --git a/config/rv64gc/coverage.svh b/config/rv64gc/coverage.svh index 5b11b5a22..ed337a4ac 100644 --- a/config/rv64gc/coverage.svh +++ b/config/rv64gc/coverage.svh @@ -9,7 +9,7 @@ `include "RV64M_coverage.svh" `include "RV64F_coverage.svh" `include "RV64Zfh_coverage.svh" -`include "RV64VM_coverage.svh" +`include "VM_coverage.svh" `include "RV64VM_PMP_coverage.svh" `include "RV64CBO_VM_coverage.svh" `include "RV64CBO_PMP_coverage.svh" From 3f94fc3ca245604e71d0f8537127749cfc1bf8e9 Mon Sep 17 00:00:00 2001 From: Huda-10xe Date: Tue, 29 Oct 2024 03:13:53 -0700 Subject: [PATCH 02/30] Changing VM covergae name to incorporate sv32 coverpoints --- config/rv64gc/coverage.svh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config/rv64gc/coverage.svh b/config/rv64gc/coverage.svh index 20d5108d6..4e863b288 100644 --- a/config/rv64gc/coverage.svh +++ b/config/rv64gc/coverage.svh @@ -21,7 +21,7 @@ `include "RV64Zcd_coverage.svh" // Privileged extensions -`include "RVVM_coverage.svh" +`include "VM_coverage.svh" `include "ZicsrM_coverage.svh" // `include "RV64VM_PMP_coverage.svh" // `include "RV64CBO_VM_coverage.svh" From 8515c20c158c02e5202a753e565a38b690703e10 Mon Sep 17 00:00:00 2001 From: Huda-10xe Date: Tue, 29 Oct 2024 04:25:02 -0700 Subject: [PATCH 03/30] Removing VM_Covergae from this till its complete --- config/rv32gc/coverage.svh | 1 - 1 file changed, 1 deletion(-) diff --git a/config/rv32gc/coverage.svh b/config/rv32gc/coverage.svh index 96362fdf3..217e8788a 100644 --- a/config/rv32gc/coverage.svh +++ b/config/rv32gc/coverage.svh @@ -22,4 +22,3 @@ // Privileged extensions `include "ZicsrM_coverage.svh" -`include "VM_coverage.svh" From 896bb21f7c7d839904c20df5510e7fa49899fbd7 Mon Sep 17 00:00:00 2001 From: Rose Thompson Date: Tue, 29 Oct 2024 09:58:53 -0500 Subject: [PATCH 04/30] Added potential test. btbthrash forces jump and divide instructions to occupy the same location in the btb. Instruction class prediction mispredicts ever time. This is useful incase someone changes the hazard code or fpu. --- tests/coverage/btbthrash.S | 145 +++++++++++++++++++++++++++++++++++++ 1 file changed, 145 insertions(+) create mode 100644 tests/coverage/btbthrash.S diff --git a/tests/coverage/btbthrash.S b/tests/coverage/btbthrash.S new file mode 100644 index 000000000..8fedf372a --- /dev/null +++ b/tests/coverage/btbthrash.S @@ -0,0 +1,145 @@ +/////////////////////////////////////////// +// btbtrash.S +// +// Written: Rose Thompson rose@rosethompson.net 23 October 2024 +// +// Purpose: Test the branch target buffer alias with divide and cache pipeline stalls +// +// A component of the CORE-V-WALLY configurable RISC-V project. +// https://github.com/openhwgroup/cvw +// +// Copyright (C) 2021-23 Harvey Mudd College & Oklahoma State University +// +// SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1 +// +// Licensed under the Solderpad Hardware License v 2.1 (the “License”); you may not use this file +// except in compliance with the License, or, at your option, the Apache License version 2.0. You +// may obtain a copy of the License at +// +// https://solderpad.org/licenses/SHL-2.1/ +// +// Unless required by applicable law or agreed to in writing, any work distributed under the +// License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, +// either express or implied. See the License for the specific language governing permissions +// and limitations under the License. +//////////////////////////////////////////////////////////////////////////////////////////////// + +// load code to initalize stack, handle interrupts, terminate +#include "WALLY-init-lib.h" + +main: + + # Division test (having trouble with buildroot) + li x1, 1938759018 + li x2, 3745029 + li x3, 458 + li x4, 29587209347 + li x5, 28957 + li x6, 298 + li x7, 238562 + li x8, 198674 + li x9, 134 + li x10, 906732 + li x11, 29 + li x12, 50912 + li x13, 59 + li x14, 6902385 + li x15, 1923857 + li x16, 3985 + li x17, 3947 + li x18, 15984 + li x19, 5 + li x20, 9684658489 + li x21, 6548 + li x22, 3564 + li x23, 94 + li x24, 689464 + li x25, 42567 + li x26, 98453 + li x27, 648 + li x28, 984 + li x29, 6984 + li x30, 864 + + # x31 will be our loop counter + li x31, 4 + +.align 12 +jump1: + divuw x0, x1, x2 + j jump3 +jump4: + divuw x0, x5, x6 + j jump5 +jump6: + divuw x0, x10, x9 + j jump7 +jump8: + divuw x0, x14, x3 + j jump9 +jump10: + divuw x0, x18, x17 + j jump11 +jump12: + divuw x0, x21, x22 + j jump13 +jump14: + divuw x0, x24, x25 + j jump15 +jump16: + divuw x0, x29, x28 + j jump17 +jump18: + divuw x0, x1, x30 + j jump19 +jump20: + divuw x0, x3, x19 + j jump21 +jump22: + divuw x0, x12, x13 + j jump23 + +.align 12 # size of the 1024 btb apart +jump2: + j jump1 +jump3: + divuw x0, x4, x3 + j jump4 +jump5: + divuw x0, x7, x8 + j jump6 +jump7: + divuw x0, x12, x11 + j jump8 +jump9: + divuw x0, x15, x16 + j jump10 +jump11: + divuw x0, x20, x19 + j jump12 +jump13: + divuw x0, x24, x23 + j jump14 +jump15: + divuw x0, x26, x27 + j jump16 +jump17: + divuw x0, x29, x30 + j jump18 +jump19: + divuw x0, x2, x3 + j jump20 +jump21: + divuw x0, x4, x5 + j jump22 +jump23: + divuw x0, x20, x21 + #j jump22 + + fence.i + + addi x31, x31, -1 + bne x31, x0, jump1 +finsihed: + j done + From af74635216eeca9dca33d49c25b7a9206f23a71c Mon Sep 17 00:00:00 2001 From: Huda-10xe Date: Tue, 29 Oct 2024 09:44:18 -0700 Subject: [PATCH 05/30] reverting VM to RV64VM --- config/rv64gc/coverage.svh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config/rv64gc/coverage.svh b/config/rv64gc/coverage.svh index 4e863b288..0491b4ab3 100644 --- a/config/rv64gc/coverage.svh +++ b/config/rv64gc/coverage.svh @@ -21,7 +21,7 @@ `include "RV64Zcd_coverage.svh" // Privileged extensions -`include "VM_coverage.svh" +`include "RV64VM_coverage.svh" `include "ZicsrM_coverage.svh" // `include "RV64VM_PMP_coverage.svh" // `include "RV64CBO_VM_coverage.svh" From 7405456de5da940621b79f32a3f0e0ed7fc5c0b7 Mon Sep 17 00:00:00 2001 From: Rose Thompson Date: Tue, 29 Oct 2024 15:47:24 -0500 Subject: [PATCH 06/30] added script to install libncurses5 and libtinfo5 for ubuntu24.04. --- bin/vivado-ubuntu24.04-libs.sh | 52 ++++++++++++++++++++++++++++++++++ 1 file changed, 52 insertions(+) create mode 100755 bin/vivado-ubuntu24.04-libs.sh diff --git a/bin/vivado-ubuntu24.04-libs.sh b/bin/vivado-ubuntu24.04-libs.sh new file mode 100755 index 000000000..29a0f1671 --- /dev/null +++ b/bin/vivado-ubuntu24.04-libs.sh @@ -0,0 +1,52 @@ +#!/bin/bash + +# Rose Thompson rose@rosethompson.net +# Oct 29, 2024 +# Downloads libncurses5 and libtinfo5 from ubuntu 22.04, extracts the libraries and installs to the system. Requires root. + +# A component of the CORE-V-WALLY configurable RISC-V project. +# https://github.com/openhwgroup/cvw +# +# Copyright (C) 2021-23 Harvey Mudd College & Oklahoma State University +# +# SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1 +# +# Licensed under the Solderpad Hardware License v 2.1 (the “License”); you may not use this file +# except in compliance with the License, or, at your option, the Apache License version 2.0. You +# may obtain a copy of the License at +# +# https://solderpad.org/licenses/SHL-2.1/ +# +# Unless required by applicable law or agreed to in writing, any work distributed under the +# License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, +# either express or implied. See the License for the specific language governing permissions +# and limitations under the License. + +TmpDir=$(mktemp -d ) +echo $TmpDir + +cd $TmpDir + +wget http://security.ubuntu.com/ubuntu/pool/universe/n/ncurses/libtinfo5_6.3-2ubuntu0.1_amd64.deb +wget http://security.ubuntu.com/ubuntu/pool/universe/n/ncurses/libncurses5_6.3-2ubuntu0.1_amd64.deb + +dpkg-deb -xv libtinfo5_6.3-2ubuntu0.1_amd64.deb ./libtinfo5 +dpkg-deb -xv libncurses5_6.3-2ubuntu0.1_amd64.deb ./libncurses5 + +echo "Installing libraries." +sudo cp libncurses5/lib/x86_64-linux-gnu/* /usr/lib/x86_64-linux-gnu/ +sudo cp libncurses5/usr/lib/x86_64-linux-gnu/* /usr/lib/x86_64-linux-gnu/ +sudo cp libtinfo5/lib/x86_64-linux-gnu/* /usr/lib/x86_64-linux-gnu/ +sudo cp libtinfo5/usr/lib/x86_64-linux-gnu/* /usr/lib/x86_64-linux-gnu/ +sudo cp -r libtinfo5/usr/share/doc/* /usr/share/doc/ +sudo ln -f -s /usr/share/doc/libtinfo5/ /usr/share/doc/libncurses5 + +cd - + +echo "Removing temporary files." +rm -rf $TmpDir + +echo "Finished." + + + From b667581ffabd2d73e117f037147c53b915c6e02e Mon Sep 17 00:00:00 2001 From: Jacob Pease Date: Tue, 29 Oct 2024 17:50:36 -0500 Subject: [PATCH 07/30] Refactored SPI peripheral based on SPI controller module. Works in tests/custom/spitest. --- src/uncore/spi_apb.sv | 707 ++++++++++++++--------------------- src/uncore/spi_controller.sv | 123 +++--- 2 files changed, 335 insertions(+), 495 deletions(-) diff --git a/src/uncore/spi_apb.sv b/src/uncore/spi_apb.sv index 54a072ac9..ebe0726c1 100644 --- a/src/uncore/spi_apb.sv +++ b/src/uncore/spi_apb.sv @@ -30,438 +30,305 @@ //////////////////////////////////////////////////////////////////////////////////////////////// module spi_apb import cvw::*; #(parameter cvw_t P) ( - input logic PCLK, PRESETn, - input logic PSEL, - input logic [7:0] PADDR, - input logic [P.XLEN-1:0] PWDATA, - input logic [P.XLEN/8-1:0] PSTRB, - input logic PWRITE, - input logic PENABLE, - output logic PREADY, - output logic [P.XLEN-1:0] PRDATA, - output logic SPIOut, - input logic SPIIn, - output logic [3:0] SPICS, - output logic SPIIntr, - output logic SPICLK + input logic PCLK, PRESETn, + input logic PSEL, + input logic [7:0] PADDR, + input logic [P.XLEN-1:0] PWDATA, + input logic [P.XLEN/8-1:0] PSTRB, + input logic PWRITE, + input logic PENABLE, + output logic PREADY, + output logic [P.XLEN-1:0] PRDATA, + output logic SPIOut, + input logic SPIIn, + output logic [3:0] SPICS, + output logic SPIIntr, + output logic SPICLK ); // register map - localparam SPI_SCKDIV = 8'h00; - localparam SPI_SCKMODE = 8'h04; - localparam SPI_CSID = 8'h10; - localparam SPI_CSDEF = 8'h14; - localparam SPI_CSMODE = 8'h18; - localparam SPI_DELAY0 = 8'h28; - localparam SPI_DELAY1 = 8'h2C; - localparam SPI_FMT = 8'h40; - localparam SPI_TXDATA = 8'h48; - localparam SPI_RXDATA = 8'h4C; - localparam SPI_TXMARK = 8'h50; - localparam SPI_RXMARK = 8'h54; - localparam SPI_IE = 8'h70; - localparam SPI_IP = 8'h74; - - // receive shift register states - typedef enum logic [1:0] {ReceiveShiftFullState, ReceiveShiftNotFullState, ReceiveShiftDelayState} rsrstatetype; - - - // SPI control registers. Refer to SiFive FU540-C000 manual - logic [11:0] SckDiv; - logic [1:0] SckMode; - logic [1:0] ChipSelectID; - logic [3:0] ChipSelectDef; - logic [1:0] ChipSelectMode; - logic [15:0] Delay0, Delay1; - logic [4:0] Format; - logic [7:0] ReceiveData; - logic [2:0] TransmitWatermark, ReceiveWatermark; - logic [8:0] TransmitData; - logic [1:0] InterruptEnable, InterruptPending; - - // Bus interface signals - logic [7:0] Entry; - logic Memwrite; - logic [31:0] Din, Dout; - logic TransmitInactive; // High when there is no transmission, used as hardware interlock signal - - // FIFO FSM signals - // Watermark signals - TransmitReadMark = ip[0], ReceiveWriteMark = ip[1] - logic TransmitWriteMark, TransmitReadMark, RecieveWriteMark, RecieveReadMark; - logic TransmitFIFOWriteFull, TransmitFIFOReadEmpty; - logic TransmitFIFOWriteIncrement; - logic ReceiveFiFoWriteInc; - logic ReceiveFIFOReadIncrement; - logic ReceiveFIFOWriteFull, ReceiveFIFOReadEmpty; - logic [7:0] TransmitFIFOReadData; - /* verilator lint_off UNDRIVEN */ - logic [2:0] TransmitWriteWatermarkLevel, ReceiveReadWatermarkLevel; // unused generic FIFO outputs - /* verilator lint_off UNDRIVEN */ - logic [7:0] ReceiveShiftRegEndian; // Reverses ReceiveShiftReg if Format[2] set (little endian transmission) - rsrstatetype ReceiveState; - logic ReceiveFiFoTakingData; - - // Transmission signals - logic ZeroDiv; // High when SckDiv is 0 - logic [11:0] DivCounter; // Counter for sck - logic SCLKenable; // Flip flop enable high every sclk edge - - // Delay signals - logic [8:0] ImplicitDelay1; // Adds implicit delay to cs-sck delay counter based on phase - logic [8:0] ImplicitDelay2; // Adds implicit delay to sck-cs delay counter based on phase - logic [8:0] CS_SCKCount; // Counter for cs-sck delay - logic [8:0] SCK_CSCount; // Counter for sck-cs delay - logic [8:0] InterCSCount; // Counter for inter cs delay - logic [8:0] InterXFRCount; // Counter for inter xfr delay - logic ZeroDelayHoldMode; // High when ChipSelectMode is hold and Delay1[15:8] (InterXFR delay) is 0 - - // Frame counting signals - logic FirstFrame; - logic [3:0] FrameCount; // Counter for number of frames in transmission - logic ReceivePenultimateFrame; // High when penultimate frame in transmission has been reached - - // State fsm signals - logic Active; // High when state is either Active1 or Active0 (during transmission) - logic Active0; // High when state is Active0 - - // Shift reg signals - logic ShiftEdge; // Determines which edge of sck to shift from TransmitShiftReg - logic [7:0] TransmitShiftReg; // Transmit shift register - logic [7:0] ReceiveShiftReg; // Receive shift register - logic SampleEdge; // Determines which edge of sck to sample from ReceiveShiftReg - logic [7:0] TransmitDataEndian; // Reverses TransmitData from txFIFO if littleendian, since TransmitReg always shifts MSB - logic TransmitShiftRegLoad; // Determines when to load TransmitShiftReg - logic TransmitShiftRegLoadSingleCycle; // Version of TransmitShiftRegLoad which is only high for a single SCLK cycle to prevent double loads - logic TransmitShiftRegLoadDelay; // TransmitShiftRegLoad delayed by an SCLK cycle, inverted and anded with TransmitShiftRegLoad to create a single cycle signal - logic TransmitFIFOReadIncrement; // Increments Tx FIFO read ptr 1 cycle after Tx FIFO is read - logic ReceiveShiftFull; // High when receive shift register is full - logic TransmitShiftEmpty; // High when transmit shift register is empty - logic ShiftIn; // Determines whether to shift from SPIIn or SPIOut (if SPI_LOOPBACK_TEST) - logic [3:0] LeftShiftAmount; // Determines left shift amount to left-align data when little endian - logic [7:0] ASR; // AlignedReceiveShiftReg - logic ShiftEdgeSPICLK; // Changes ShiftEdge when SckDiv is 0 - - // CS signals - logic [3:0] ChipSelectAuto; // Assigns ChipSelect value to selected CS signal based on CS ID - logic [3:0] ChipSelectInternal; // Defines what each ChipSelect signal should be based on transmission status and ChipSelectDef - logic DelayMode; // Determines where to place implicit half cycle delay based on sck phase for CS assertion - - // Miscellaneous signals delayed/early by 1 PCLK cycle - logic ReceiveShiftFullDelay; // Delays ReceiveShiftFull signal by 1 PCLK cycle - logic ReceiveShiftFullDelayPCLK; // ReceiveShiftFull delayed by 1 PCLK cycle - logic TransmitFIFOReadEmptyDelay; - logic SCLKenableEarly; // SCLKenable 1 PCLK cycle early, needed for on time register changes when ChipSelectMode is hold and Delay1[15:8] (InterXFR delay) is 0 - - - - // APB access - assign Entry = {PADDR[7:2],2'b00}; // 32-bit word-aligned accesses - assign Memwrite = PWRITE & PENABLE & PSEL; // Only write in access phase - assign PREADY = Entry == SPI_TXDATA | Entry == SPI_RXDATA | Entry == SPI_IP | TransmitInactive; // Tie PREADY to transmission for hardware interlock - - // Account for subword read/write circuitry - // -- Note SPI registers are 32 bits no matter what; access them with LW SW. - - assign Din = PWDATA[31:0]; - if (P.XLEN == 64) assign PRDATA = { Dout, Dout}; - else assign PRDATA = Dout; - - // Register access - always_ff@(posedge PCLK) - if (~PRESETn) begin - SckDiv <= 12'd3; - SckMode <= 2'b0; - ChipSelectID <= 2'b0; - ChipSelectDef <= 4'b1111; - ChipSelectMode <= 2'b0; - Delay0 <= {8'b1,8'b1}; - Delay1 <= {8'b0,8'b1}; - Format <= {5'b10000}; - TransmitData <= 9'b0; - TransmitWatermark <= 3'b0; - ReceiveWatermark <= 3'b0; - InterruptEnable <= 2'b0; - InterruptPending <= 2'b0; - end else begin // writes - - - /* verilator lint_off CASEINCOMPLETE */ - if (Memwrite & TransmitInactive) - case(Entry) // flop to sample inputs - SPI_SCKDIV: SckDiv <= Din[11:0]; - SPI_SCKMODE: SckMode <= Din[1:0]; - SPI_CSID: ChipSelectID <= Din[1:0]; - SPI_CSDEF: ChipSelectDef <= Din[3:0]; - SPI_CSMODE: ChipSelectMode <= Din[1:0]; - SPI_DELAY0: Delay0 <= {Din[23:16], Din[7:0]}; - SPI_DELAY1: Delay1 <= {Din[23:16], Din[7:0]}; - SPI_FMT: Format <= {Din[19:16], Din[2]}; - SPI_TXMARK: TransmitWatermark <= Din[2:0]; - SPI_RXMARK: ReceiveWatermark <= Din[2:0]; - SPI_IE: InterruptEnable <= Din[1:0]; - endcase - - if (Memwrite) - case(Entry) - SPI_TXDATA: if (~TransmitFIFOWriteFull) TransmitData[7:0] <= Din[7:0]; - endcase - /* verilator lint_off CASEINCOMPLETE */ - - // According to FU540 spec: Once interrupt is pending, it will remain set until number - // of entries in tx/rx fifo is strictly more/less than tx/rxmark - InterruptPending[0] <= TransmitReadMark; - InterruptPending[1] <= RecieveWriteMark; - - case(Entry) // Flop to sample inputs - SPI_SCKDIV: Dout <= {20'b0, SckDiv}; - SPI_SCKMODE: Dout <= {30'b0, SckMode}; - SPI_CSID: Dout <= {30'b0, ChipSelectID}; - SPI_CSDEF: Dout <= {28'b0, ChipSelectDef}; - SPI_CSMODE: Dout <= {30'b0, ChipSelectMode}; - SPI_DELAY0: Dout <= {8'b0, Delay0[15:8], 8'b0, Delay0[7:0]}; - SPI_DELAY1: Dout <= {8'b0, Delay1[15:8], 8'b0, Delay1[7:0]}; - SPI_FMT: Dout <= {12'b0, Format[4:1], 13'b0, Format[0], 2'b0}; - SPI_TXDATA: Dout <= {TransmitFIFOWriteFull, 23'b0, 8'b0}; - SPI_RXDATA: Dout <= {ReceiveFIFOReadEmpty, 23'b0, ReceiveData[7:0]}; - SPI_TXMARK: Dout <= {29'b0, TransmitWatermark}; - SPI_RXMARK: Dout <= {29'b0, ReceiveWatermark}; - SPI_IE: Dout <= {30'b0, InterruptEnable}; - SPI_IP: Dout <= {30'b0, InterruptPending}; - default: Dout <= 32'b0; - endcase - end - - // SPI enable generation, where SCLK = PCLK/(2*(SckDiv + 1)) - // Asserts SCLKenable at the rising and falling edge of SCLK by counting from 0 to SckDiv - // Active at 2x SCLK frequency to account for implicit half cycle delays and actions on both clock edges depending on phase - // When SckDiv is 0, count doesn't work and SCLKenable is simply PCLK *** dh 10/26/24: this logic is seriously broken. SCLK is not scaled to PCLK/(2*(SckDiv + 1)). SCLKenableEarly doesn't work right for SckDiv=0 - assign ZeroDiv = ~|(SckDiv[10:0]); - assign SCLKenable = ZeroDiv ? 1 : (DivCounter == SckDiv); - assign SCLKenableEarly = ((DivCounter + 12'b1) == SckDiv); - always_ff @(posedge PCLK) - if (~PRESETn) DivCounter <= '0; - else if (SCLKenable) DivCounter <= 12'b0; - else DivCounter <= DivCounter + 12'b1; - - // Asserts when transmission is one frame before complete - assign ReceivePenultimateFrame = ((FrameCount + 4'b0001) == Format[4:1]); - assign FirstFrame = (FrameCount == 4'b0); - - // Computing delays - // When sckmode.pha = 0, an extra half-period delay is implicit in the cs-sck delay, and vice-versa for sck-cs - assign ImplicitDelay1 = SckMode[0] ? 9'b0 : 9'b1; - assign ImplicitDelay2 = SckMode[0] ? 9'b1 : 9'b0; - - // Calculate when tx/rx shift registers are full/empty - - // Transmit Shift FSM - always_ff @(posedge PCLK) - if (~PRESETn) TransmitShiftEmpty <= 1'b1; - else if (TransmitShiftEmpty) begin - if (TransmitFIFOReadEmpty | (~TransmitFIFOReadEmpty & (ReceivePenultimateFrame & Active0))) TransmitShiftEmpty <= 1'b1; - else if (~TransmitFIFOReadEmpty) TransmitShiftEmpty <= 1'b0; - end else begin - if (ReceivePenultimateFrame & Active0) TransmitShiftEmpty <= 1'b1; - else TransmitShiftEmpty <= 1'b0; - end - - // Receive Shift FSM - always_ff @(posedge PCLK) - if (~PRESETn) ReceiveState <= ReceiveShiftNotFullState; - else if (SCLKenable) begin - case (ReceiveState) - ReceiveShiftFullState: ReceiveState <= ReceiveShiftNotFullState; - ReceiveShiftNotFullState: if (ReceivePenultimateFrame & (SampleEdge)) ReceiveState <= ReceiveShiftDelayState; - else ReceiveState <= ReceiveShiftNotFullState; - ReceiveShiftDelayState: ReceiveState <= ReceiveShiftFullState; - endcase - end - - assign ReceiveShiftFull = SckMode[0] ? (ReceiveState == ReceiveShiftFullState) : (ReceiveState == ReceiveShiftDelayState); - - // Calculate tx/rx fifo write and recieve increment signals - - always_ff @(posedge PCLK) - if (~PRESETn) TransmitFIFOWriteIncrement <= 1'b0; - else TransmitFIFOWriteIncrement <= (Memwrite & (Entry == SPI_TXDATA) & ~TransmitFIFOWriteFull); - - always_ff @(posedge PCLK) - if (~PRESETn) ReceiveFIFOReadIncrement <= 1'b0; - else ReceiveFIFOReadIncrement <= ((Entry == SPI_RXDATA) & ~ReceiveFIFOReadEmpty & PSEL & ~ReceiveFIFOReadIncrement); - - assign TransmitShiftRegLoad = ~TransmitShiftEmpty & ~Active | (((ChipSelectMode == 2'b10) & ~|(Delay1[15:8])) & ((ReceiveShiftFullDelay | ReceiveShiftFull) & ~SampleEdge & ~TransmitFIFOReadEmpty)); - - always_ff @(posedge PCLK) - if (~PRESETn) TransmitShiftRegLoadDelay <=0; - else if (SCLKenable) TransmitShiftRegLoadDelay <= TransmitShiftRegLoad; - assign TransmitShiftRegLoadSingleCycle = TransmitShiftRegLoad & ~TransmitShiftRegLoadDelay; - always_ff @(posedge PCLK) - if (~PRESETn) TransmitFIFOReadIncrement <= 0; - else if (SCLKenable) TransmitFIFOReadIncrement <= TransmitShiftRegLoadSingleCycle; - // Tx/Rx FIFOs - spi_fifo #(3,8) txFIFO(PCLK, 1'b1, SCLKenable, PRESETn, TransmitFIFOWriteIncrement, TransmitFIFOReadIncrement, TransmitData[7:0], TransmitWriteWatermarkLevel, TransmitWatermark[2:0], - TransmitFIFOReadData[7:0], TransmitFIFOWriteFull, TransmitFIFOReadEmpty, TransmitWriteMark, TransmitReadMark); - spi_fifo #(3,8) rxFIFO(PCLK, SCLKenable, 1'b1, PRESETn, ReceiveFiFoWriteInc, ReceiveFIFOReadIncrement, ReceiveShiftRegEndian, ReceiveWatermark[2:0], ReceiveReadWatermarkLevel, - ReceiveData[7:0], ReceiveFIFOWriteFull, ReceiveFIFOReadEmpty, RecieveWriteMark, RecieveReadMark); - - always_ff @(posedge PCLK) - if (~PRESETn) TransmitFIFOReadEmptyDelay <= 1'b1; - else if (SCLKenable) TransmitFIFOReadEmptyDelay <= TransmitFIFOReadEmpty; - - always_ff @(posedge PCLK) - if (~PRESETn) ReceiveShiftFullDelay <= 1'b0; - else if (SCLKenable) ReceiveShiftFullDelay <= ReceiveShiftFull; - - assign ReceiveFiFoTakingData = ReceiveFiFoWriteInc & ~ReceiveFIFOWriteFull; + localparam SPI_SCKDIV = 8'h00; + localparam SPI_SCKMODE = 8'h04; + localparam SPI_CSID = 8'h10; + localparam SPI_CSDEF = 8'h14; + localparam SPI_CSMODE = 8'h18; + localparam SPI_DELAY0 = 8'h28; + localparam SPI_DELAY1 = 8'h2C; + localparam SPI_FMT = 8'h40; + localparam SPI_TXDATA = 8'h48; + localparam SPI_RXDATA = 8'h4C; + localparam SPI_TXMARK = 8'h50; + localparam SPI_RXMARK = 8'h54; + localparam SPI_IE = 8'h70; + localparam SPI_IP = 8'h74; - always_ff @(posedge PCLK) - if (~PRESETn) ReceiveFiFoWriteInc <= 1'b0; - else if (SCLKenable & ReceiveShiftFull) ReceiveFiFoWriteInc <= 1'b1; - else if (SCLKenable & ReceiveFiFoTakingData) ReceiveFiFoWriteInc <= 1'b0; - always_ff @(posedge PCLK) - if (~PRESETn) ReceiveShiftFullDelayPCLK <= 1'b0; - else if (SCLKenableEarly) ReceiveShiftFullDelayPCLK <= ReceiveShiftFull; + // SPI control registers. Refer to SiFive FU540-C000 manual + logic [11:0] SckDiv; + logic [1:0] SckMode; + logic [1:0] ChipSelectID; + logic [3:0] ChipSelectDef; + logic [1:0] ChipSelectMode; + logic [15:0] Delay0, Delay1; + logic [4:0] Format; + logic [7:0] ReceiveData; + logic [8:0] TransmitData; + logic [2:0] TransmitWatermark, ReceiveWatermark; + logic [1:0] InterruptEnable, InterruptPending; + // Bus interface signals + logic [7:0] Entry; + logic Memwrite; + logic [31:0] Din, Dout; + // SPI Controller signals + logic SCLKenable; + logic EndOfFrame; + logic EndOfFrameDelay; + logic Transmitting; + logic InactiveState; + logic ResetSCLKenable; + logic TransmitStart; - // Main FSM which controls SPI transmission - typedef enum logic [2:0] {CS_INACTIVE, DELAY_0, ACTIVE_0, ACTIVE_1, DELAY_1,INTER_CS, INTER_XFR} statetype; - statetype state; + // Transmit Start State Machine Variables + typedef enum logic [1:0] {READY, START, WAIT} txState; + txState CurrState, NextState; + + // FIFO FSM signals + // Watermark signals - TransmitReadMark = ip[0], ReceiveWriteMark = ip[1] + logic TransmitWriteMark, TransmitReadMark, RecieveWriteMark, RecieveReadMark; + logic TransmitFIFOWriteFull, TransmitFIFOReadEmpty; + logic TransmitFIFOWriteIncrement; + logic [7:0] TransmitFIFOReadData; - always_ff @(posedge PCLK) - if (~PRESETn) begin - state <= CS_INACTIVE; - FrameCount <= 4'b0; - SPICLK <= SckMode[1]; - end else if (SCLKenable) begin + logic ReceiveFIFOWriteInc; + logic ReceiveFIFOReadIncrement; + logic ReceiveFIFOWriteFull, ReceiveFIFOReadEmpty; + + /* verilator lint_off UNDRIVEN */ + logic [2:0] TransmitWriteWatermarkLevel, ReceiveReadWatermarkLevel; // unused generic FIFO outputs + /* verilator lint_off UNDRIVEN */ + logic [7:0] ReceiveShiftRegEndian; // Reverses ReceiveShiftReg if Format[2] set (little endian transmission) + + // Shift reg signals + logic ShiftEdge; // Determines which edge of sck to shift from TransmitReg + logic SampleEdge; // Determines which edge of sck to sample from ReceiveShiftReg + logic [7:0] TransmitReg; // Transmit shift register + logic [7:0] ReceiveShiftReg; // Receive shift register + logic [7:0] TransmitDataEndian; // Reverses TransmitData from txFIFO if littleendian, since TransmitReg always shifts MSB + logic TransmitLoad; // Determines when to load TransmitReg + logic TransmitFIFOReadIncrement; // Increments Tx FIFO read ptr 1 cycle after Tx FIFO is read + + // Shift stuff due to Format register? + logic ShiftIn; // Determines whether to shift from SPIIn or SPIOut (if SPI_LOOPBACK_TEST) + logic [3:0] LeftShiftAmount; // Determines left shift amount to left-align data when little endian + logic [7:0] ASR; // AlignedReceiveShiftReg + + // CS signals + logic [3:0] ChipSelectAuto; // Assigns ChipSelect value to selected CS signal based on CS ID + logic [3:0] ChipSelectInternal; // Defines what each ChipSelect signal should be based on transmission status and ChipSelectDef + + // APB access + assign Entry = {PADDR[7:2],2'b00}; // 32-bit word-aligned accesses + assign Memwrite = PWRITE & PENABLE & PSEL; // Only write in access phase + // assign PREADY = Entry == SPI_TXDATA | Entry == SPI_RXDATA | Entry == SPI_IP; + assign PREADY = 1'b1; + + // Account for subword read/write circuitry + // -- Note SPI registers are 32 bits no matter what; access them with LW SW. + + assign Din = PWDATA[31:0]; + if (P.XLEN == 64) assign PRDATA = { Dout, Dout}; + else assign PRDATA = Dout; + + // Register access + always_ff@(posedge PCLK) + if (~PRESETn) begin + SckDiv <= 12'd3; + SckMode <= 2'b0; + ChipSelectID <= 2'b0; + ChipSelectDef <= 4'b1111; + ChipSelectMode <= 2'b0; + Delay0 <= {8'b1,8'b1}; + Delay1 <= {8'b0,8'b1}; + Format <= {5'b10000}; + TransmitData <= 9'b0; + TransmitWatermark <= 3'b0; + ReceiveWatermark <= 3'b0; + InterruptEnable <= 2'b0; + InterruptPending <= 2'b0; + end else begin // writes /* verilator lint_off CASEINCOMPLETE */ - case (state) - CS_INACTIVE: begin - CS_SCKCount <= 9'b1; - SCK_CSCount <= 9'b10; - FrameCount <= 4'b0; - InterCSCount <= 9'b10; - InterXFRCount <= 9'b1; - if ((~TransmitFIFOReadEmpty | ~TransmitShiftEmpty) & ((|(Delay0[7:0])) | ~SckMode[0])) state <= DELAY_0; - else if ((~TransmitFIFOReadEmpty | ~TransmitShiftEmpty)) begin - state <= ACTIVE_0; - SPICLK <= ~SckMode[1]; - end else SPICLK <= SckMode[1]; - end - DELAY_0: begin - CS_SCKCount <= CS_SCKCount + 9'b1; - if (CS_SCKCount >= (({Delay0[7:0], 1'b0}) + ImplicitDelay1)) begin - state <= ACTIVE_0; - SPICLK <= ~SckMode[1]; - end - end - ACTIVE_0: begin - FrameCount <= FrameCount + 4'b1; - SPICLK <= SckMode[1]; - state <= ACTIVE_1; - end - ACTIVE_1: begin - InterXFRCount <= 9'b1; - if (FrameCount < Format[4:1]) begin - state <= ACTIVE_0; - SPICLK <= ~SckMode[1]; - end - else if ((ChipSelectMode[1:0] == 2'b10) & ~|(Delay1[15:8]) & (~TransmitFIFOReadEmpty)) begin - state <= ACTIVE_0; - SPICLK <= ~SckMode[1]; - CS_SCKCount <= 9'b1; - SCK_CSCount <= 9'b10; - FrameCount <= 4'b0; - InterCSCount <= 9'b10; - end - else if (ChipSelectMode[1:0] == 2'b10) state <= INTER_XFR; - else if (~|(Delay0[15:8]) & (~SckMode[0])) state <= INTER_CS; - else state <= DELAY_1; - end - DELAY_1: begin - SCK_CSCount <= SCK_CSCount + 9'b1; - if (SCK_CSCount >= (({Delay0[15:8], 1'b0}) + ImplicitDelay2)) state <= INTER_CS; - end - INTER_CS: begin - InterCSCount <= InterCSCount + 9'b1; - SPICLK <= SckMode[1]; - if (InterCSCount >= ({Delay1[7:0],1'b0})) state <= CS_INACTIVE; - end - INTER_XFR: begin - CS_SCKCount <= 9'b1; - SCK_CSCount <= 9'b10; - FrameCount <= 4'b0; - InterCSCount <= 9'b10; - InterXFRCount <= InterXFRCount + 9'b1; - if ((InterXFRCount >= ({Delay1[15:8], 1'b0})) & (~TransmitFIFOReadEmptyDelay | ~TransmitShiftEmpty)) begin - state <= ACTIVE_0; - SPICLK <= ~SckMode[1]; - end else if (~|ChipSelectMode[1:0]) state <= CS_INACTIVE; - else SPICLK <= SckMode[1]; - end - endcase - /* verilator lint_off CASEINCOMPLETE */ - end - - - - assign DelayMode = SckMode[0] ? (state == DELAY_1) : (state == ACTIVE_1 & ReceiveShiftFull); - assign ChipSelectInternal = (state == CS_INACTIVE | state == INTER_CS | DelayMode & ~|(Delay0[15:8])) ? ChipSelectDef : ~ChipSelectDef; - assign Active = (state == ACTIVE_0 | state == ACTIVE_1); - assign SampleEdge = SckMode[0] ? (state == ACTIVE_1) : (state == ACTIVE_0); - assign ZeroDelayHoldMode = ((ChipSelectMode == 2'b10) & (~|(Delay1[7:4]))); - assign TransmitInactive = ((state == INTER_CS) | (state == CS_INACTIVE) | (state == INTER_XFR) | (ReceiveShiftFullDelayPCLK & ZeroDelayHoldMode) | ((state == ACTIVE_1) & ((ChipSelectMode[1:0] == 2'b10) & ~|(Delay1[15:8]) & (~TransmitFIFOReadEmpty) & (FrameCount == Format[4:1])))); - assign Active0 = (state == ACTIVE_0); - assign ShiftEdgeSPICLK = ZeroDiv ? ~SPICLK : SPICLK; - - // Signal tracks which edge of sck to shift data - always_comb - case(SckMode[1:0]) - 2'b00: ShiftEdge = ShiftEdgeSPICLK & SCLKenable; - 2'b01: ShiftEdge = (~ShiftEdgeSPICLK & ~FirstFrame & (|(FrameCount) | (CS_SCKCount >= (({Delay0[7:0], 1'b0}) + ImplicitDelay1))) & SCLKenable & (FrameCount != Format[4:1]) & ~TransmitInactive); - 2'b10: ShiftEdge = ~ShiftEdgeSPICLK & SCLKenable; - 2'b11: ShiftEdge = (ShiftEdgeSPICLK & ~FirstFrame & (|(FrameCount) | (CS_SCKCount >= (({Delay0[7:0], 1'b0}) + ImplicitDelay1))) & SCLKenable & (FrameCount != Format[4:1]) & ~TransmitInactive); - default: ShiftEdge = ShiftEdgeSPICLK & SCLKenable; + if (Memwrite) + case(Entry) // flop to sample inputs + SPI_SCKDIV: SckDiv <= Din[11:0]; + SPI_SCKMODE: SckMode <= Din[1:0]; + SPI_CSID: ChipSelectID <= Din[1:0]; + SPI_CSDEF: ChipSelectDef <= Din[3:0]; + SPI_CSMODE: ChipSelectMode <= Din[1:0]; + SPI_DELAY0: Delay0 <= {Din[23:16], Din[7:0]}; + SPI_DELAY1: Delay1 <= {Din[23:16], Din[7:0]}; + SPI_FMT: Format <= {Din[19:16], Din[2]}; + SPI_TXMARK: TransmitWatermark <= Din[2:0]; + SPI_RXMARK: ReceiveWatermark <= Din[2:0]; + SPI_IE: InterruptEnable <= Din[1:0]; endcase - // Transmit shift register - assign TransmitDataEndian = Format[0] ? {TransmitFIFOReadData[0], TransmitFIFOReadData[1], TransmitFIFOReadData[2], TransmitFIFOReadData[3], TransmitFIFOReadData[4], TransmitFIFOReadData[5], TransmitFIFOReadData[6], TransmitFIFOReadData[7]} : TransmitFIFOReadData[7:0]; - always_ff @(posedge PCLK) - if(~PRESETn) TransmitShiftReg <= 8'b0; - else if (TransmitShiftRegLoadSingleCycle) TransmitShiftReg <= TransmitDataEndian; - else if (ShiftEdge & Active) TransmitShiftReg <= {TransmitShiftReg[6:0], TransmitShiftReg[0]}; - - assign SPIOut = TransmitShiftReg[7]; - - // If in loopback mode, receive shift register is connected directly to module's output pins. Else, connected to SPIIn - // There are no setup/hold time issues because transmit shift register and receive shift register always shift/sample on opposite edges - assign ShiftIn = P.SPI_LOOPBACK_TEST ? SPIOut : SPIIn; - - // Receive shift register - always_ff @(posedge PCLK) - if(~PRESETn) ReceiveShiftReg <= 8'b0; - else if (SampleEdge & SCLKenable) begin - if (~Active) ReceiveShiftReg <= 8'b0; - else ReceiveShiftReg <= {ReceiveShiftReg[6:0], ShiftIn}; - end - - // Aligns received data and reverses if little-endian - assign LeftShiftAmount = 4'h8 - Format[4:1]; - assign ASR = ReceiveShiftReg << LeftShiftAmount[2:0]; - assign ReceiveShiftRegEndian = Format[0] ? {ASR[0], ASR[1], ASR[2], ASR[3], ASR[4], ASR[5], ASR[6], ASR[7]} : ASR[7:0]; - - // Interrupt logic: raise interrupt if any enabled interrupts are pending - assign SPIIntr = |(InterruptPending & InterruptEnable); - - // Chip select logic - always_comb - case(ChipSelectID[1:0]) - 2'b00: ChipSelectAuto = {ChipSelectDef[3], ChipSelectDef[2], ChipSelectDef[1], ChipSelectInternal[0]}; - 2'b01: ChipSelectAuto = {ChipSelectDef[3],ChipSelectDef[2], ChipSelectInternal[1], ChipSelectDef[0]}; - 2'b10: ChipSelectAuto = {ChipSelectDef[3],ChipSelectInternal[2], ChipSelectDef[1], ChipSelectDef[0]}; - 2'b11: ChipSelectAuto = {ChipSelectInternal[3],ChipSelectDef[2], ChipSelectDef[1], ChipSelectDef[0]}; + if (Memwrite) + case(Entry) + SPI_TXDATA: if (~TransmitFIFOWriteFull) TransmitData[7:0] <= Din[7:0]; endcase + /* verilator lint_off CASEINCOMPLETE */ + + // According to FU540 spec: Once interrupt is pending, it will remain set until number + // of entries in tx/rx fifo is strictly more/less than tx/rxmark + InterruptPending[0] <= TransmitReadMark; + InterruptPending[1] <= RecieveWriteMark; + + case(Entry) // Flop to sample inputs + SPI_SCKDIV: Dout <= {20'b0, SckDiv}; + SPI_SCKMODE: Dout <= {30'b0, SckMode}; + SPI_CSID: Dout <= {30'b0, ChipSelectID}; + SPI_CSDEF: Dout <= {28'b0, ChipSelectDef}; + SPI_CSMODE: Dout <= {30'b0, ChipSelectMode}; + SPI_DELAY0: Dout <= {8'b0, Delay0[15:8], 8'b0, Delay0[7:0]}; + SPI_DELAY1: Dout <= {8'b0, Delay1[15:8], 8'b0, Delay1[7:0]}; + SPI_FMT: Dout <= {12'b0, Format[4:1], 13'b0, Format[0], 2'b0}; + SPI_TXDATA: Dout <= {TransmitFIFOWriteFull, 23'b0, 8'b0}; + SPI_RXDATA: Dout <= {ReceiveFIFOReadEmpty, 23'b0, ReceiveData[7:0]}; + SPI_TXMARK: Dout <= {29'b0, TransmitWatermark}; + SPI_RXMARK: Dout <= {29'b0, ReceiveWatermark}; + SPI_IE: Dout <= {30'b0, InterruptEnable}; + SPI_IP: Dout <= {30'b0, InterruptPending}; + default: Dout <= 32'b0; + endcase + end - assign SPICS = ChipSelectMode[0] ? ChipSelectDef : ChipSelectAuto; + // SPI enable generation, where SCLK = PCLK/(2*(SckDiv + 1)) + // Asserts SCLKenable at the rising and falling edge of SCLK by counting from 0 to SckDiv + // Active at 2x SCLK frequency to account for implicit half cycle delays and actions on both clock edges depending on phase + // When SckDiv is 0, count doesn't work and SCLKenable is simply PCLK *** dh 10/26/24: this logic is seriously broken. SCLK is not scaled to PCLK/(2*(SckDiv + 1)). + + // SPI Controller module ------------------------------------------- + // This module controls state and timing signals that drive the rest of this module + assign ResetSCLKenable = Memwrite & (Entry == SPI_SCKDIV); + + spi_controller controller(PCLK, PRESETn, + // Transmit Signals + TransmitStart, ResetSCLKenable, + // Register Inputs + SckDiv, SckMode, ChipSelectMode, Delay0, Delay1, + // txFIFO stuff + TransmitFIFOReadEmpty, + // Timing + SCLKenable, ShiftEdge, SampleEdge, EndOfFrame, EndOfFrameDelay, + // State stuff + Transmitting, InactiveState, + // Outputs + SPICLK); + + // Transmit FIFO --------------------------------------------------- + always_ff @(posedge PCLK) + if (~PRESETn) begin + TransmitFIFOWriteIncrement <= 1'b0; + TransmitFIFOReadIncrement <= 1'b0; + end else begin + TransmitFIFOWriteIncrement <= (Memwrite & (Entry == SPI_TXDATA) & ~TransmitFIFOWriteFull); + TransmitFIFOReadIncrement <= TransmitLoad; + end + + // Setup TransmitStart state machine + always_ff @(posedge PCLK) begin + if (~PRESETn) begin + CurrState <= READY; + end else if (SCLKenable) begin + CurrState <= NextState; + end + end + + // State machine for starting transmissions + always_comb begin + case (CurrState) + READY: if (~TransmitFIFOReadEmpty) NextState = START; + else NextState = READY; + START: NextState = WAIT; + WAIT: if (TransmitFIFOReadEmpty & ~Transmitting) NextState = READY; + else NextState = WAIT; + endcase + end + + assign TransmitStart = (CurrState == START); + + spi_fifo #(3,8) txFIFO(PCLK, 1'b1, SCLKenable, PRESETn, + TransmitFIFOWriteIncrement, TransmitFIFOReadIncrement, + TransmitData[7:0], + TransmitWriteWatermarkLevel, TransmitWatermark[2:0], + TransmitFIFOReadData[7:0], + TransmitFIFOWriteFull, + TransmitFIFOReadEmpty, + TransmitWriteMark, TransmitReadMark); + + + // Receive FIFO ---------------------------------------------------- + always_ff @(posedge PCLK) + if (~PRESETn) begin + ReceiveFIFOReadIncrement <= 1'b0; + ReceiveFIFOWriteInc <= 1'b0; + end else begin + ReceiveFIFOReadIncrement <= ((Entry == SPI_RXDATA) & ~ReceiveFIFOReadEmpty & PSEL & ~ReceiveFIFOReadIncrement); + ReceiveFIFOWriteInc <= EndOfFrameDelay; + end + + spi_fifo #(3,8) rxFIFO(PCLK, SCLKenable, 1'b1, PRESETn, + ReceiveFIFOWriteInc, ReceiveFIFOReadIncrement, + ReceiveShiftRegEndian, ReceiveWatermark[2:0], + ReceiveReadWatermarkLevel, + ReceiveData[7:0], + ReceiveFIFOWriteFull, + ReceiveFIFOReadEmpty, + RecieveWriteMark, RecieveReadMark); + + // Transmit shift register + assign TransmitLoad = TransmitStart | (EndOfFrameDelay & ~TransmitFIFOReadEmpty); + assign TransmitDataEndian = Format[0] ? {<<{TransmitFIFOReadData[7:0]}} : TransmitFIFOReadData[7:0]; + always_ff @(posedge PCLK) + if(~PRESETn) TransmitReg <= 8'b0; + else if (TransmitLoad) TransmitReg <= TransmitDataEndian; + else if (ShiftEdge) TransmitReg <= {TransmitReg[6:0], TransmitReg[0]}; + + assign SPIOut = TransmitReg[7]; + + // If in loopback mode, receive shift register is connected directly + // to module's output pins. Else, connected to SPIIn. There are no + // setup/hold time issues because transmit shift register and receive + // shift register always shift/sample on opposite edges + assign ShiftIn = P.SPI_LOOPBACK_TEST ? SPIOut : SPIIn; + + // Receive shift register + always_ff @(posedge PCLK) + if(~PRESETn) ReceiveShiftReg <= 8'b0; + else if (SampleEdge) begin + if (~Transmitting) ReceiveShiftReg <= 8'b0; + else ReceiveShiftReg <= {ReceiveShiftReg[6:0], ShiftIn}; + end + + // Aligns received data and reverses if little-endian + assign LeftShiftAmount = 4'h8 - Format[4:1]; + assign ASR = ReceiveShiftReg << LeftShiftAmount[2:0]; + assign ReceiveShiftRegEndian = Format[0] ? {<<{ASR[7:0]}} : ASR[7:0]; + + // Interrupt logic: raise interrupt if any enabled interrupts are pending + assign SPIIntr = |(InterruptPending & InterruptEnable); + + // Chip select logic + assign ChipSelectInternal = InactiveState ? ChipSelectDef : ~ChipSelectDef; + always_comb + case(ChipSelectID[1:0]) + 2'b00: ChipSelectAuto = {ChipSelectDef[3], ChipSelectDef[2], ChipSelectDef[1], ChipSelectInternal[0]}; + 2'b01: ChipSelectAuto = {ChipSelectDef[3],ChipSelectDef[2], ChipSelectInternal[1], ChipSelectDef[0]}; + 2'b10: ChipSelectAuto = {ChipSelectDef[3],ChipSelectInternal[2], ChipSelectDef[1], ChipSelectDef[0]}; + 2'b11: ChipSelectAuto = {ChipSelectInternal[3],ChipSelectDef[2], ChipSelectDef[1], ChipSelectDef[0]}; + endcase + assign SPICS = ChipSelectMode[0] ? ChipSelectDef : ChipSelectAuto; + endmodule diff --git a/src/uncore/spi_controller.sv b/src/uncore/spi_controller.sv index c4305047e..9692b7588 100644 --- a/src/uncore/spi_controller.sv +++ b/src/uncore/spi_controller.sv @@ -28,21 +28,33 @@ // and limitations under the License. //////////////////////////////////////////////////////////////////////////////////////////////// - -module spi_controller ( +module spi_controller ( input logic PCLK, input logic PRESETn, + + // Start Transmission input logic TransmitStart, + input logic ResetSCLKenable, + + // Registers input logic [11:0] SckDiv, input logic [1:0] SckMode, input logic [1:0] CSMode, - input logic [15:0] Delay0, - input logic [15:0] Delay1, - input logic [7:0] txFIFORead, + input logic [15:0] Delay0, + input logic [15:0] Delay1, + + // Is the Transmit FIFO Empty? input logic txFIFOReadEmpty, - output logic SPICLK, - output logic SPIOUT, - output logic CS + + // Control signals + output logic SCLKenable, + output logic ShiftEdge, + output logic SampleEdge, + output logic EndOfFrame, + output logic EndOfFrameDelay, + output logic Transmitting, + output logic InactiveState, + output logic SPICLK ); // CSMode Stuff @@ -55,36 +67,32 @@ module spi_controller ( // SCLKenable stuff logic [11:0] DivCounter; - logic SCLKenable; - logic SCLKenableEarly; - logic SCLKenableLate; - logic EdgeTiming; + // logic SCLKenable; + // logic SCLKenableEarly; logic ZeroDiv; - logic Clock0; - logic Clock1; logic SCK; // SUPER IMPORTANT, THIS CAN'T BE THE SAME AS SPICLK! // Shift and Sample Edges logic PreShiftEdge; logic PreSampleEdge; - logic ShiftEdge; - logic SampleEdge; + // logic ShiftEdge; + // logic SampleEdge; // Frame stuff logic [2:0] BitNum; logic LastBit; - logic EndOfFrame; - logic EndOfFrameDelay; + //logic EndOfFrame; + //logic EndOfFrameDelay; logic PhaseOneOffset; // Transmit Stuff logic ContinueTransmit; // SPIOUT Stuff - logic TransmitLoad; + // logic TransmitLoad; logic [7:0] TransmitReg; - logic Transmitting; + //logic Transmitting; logic EndTransmission; logic HoldMode; @@ -135,13 +143,9 @@ module spi_controller ( // SampleEdge. This makes sure that SPICLK is an output of a register // and it properly synchronizes signals. - assign SCLKenableLate = DivCounter > SckDiv; assign SCLKenable = DivCounter == SckDiv; - assign SCLKenableEarly = (DivCounter + 1'b1) == SckDiv; + // assign SCLKenableEarly = (DivCounter + 1'b1) == SckDiv; assign LastBit = BitNum == 3'd7; - assign EdgeTiming = SckDiv > 12'b0 ? SCLKenableEarly : SCLKenable; - - //assign SPICLK = Clock0; assign ContinueTransmit = ~txFIFOReadEmpty & EndOfFrame; assign EndTransmission = txFIFOReadEmpty & EndOfFrameDelay; @@ -196,7 +200,7 @@ module spi_controller ( end // Reset divider - if (SCLKenable | TransmitStart) begin + if (SCLKenable | TransmitStart | ResetSCLKenable) begin DivCounter <= 12'b0; end else begin DivCounter = DivCounter + 12'd1; @@ -242,8 +246,8 @@ module spi_controller ( // typedef enum logic [2:0] {INACTIVE, CSSCK, TRANSMIT, SCKCS, HOLD, INTERCS, INTERXFR} statetype; // statetype CurrState, NextState; - assign HoldMode = CSMode == 2'b10; - assign TransmitLoad = TransmitStart | (EndOfFrameDelay & ~txFIFOReadEmpty); + assign HoldMode = CSMode == HOLDMODE; + // assign TransmitLoad = TransmitStart | (EndOfFrameDelay & ~txFIFOReadEmpty); always_ff @(posedge PCLK) begin if (~PRESETn) begin @@ -255,61 +259,43 @@ module spi_controller ( always_comb begin case (CurrState) - INACTIVE: begin // INACTIVE case -------------------------------- - if (TransmitStart) begin - if (~HasCSSCK) begin - NextState = TRANSMIT; - end else begin - NextState = CSSCK; - end - end else begin - NextState = INACTIVE; - end - end - CSSCK: begin // DELAY0 case ------------------------------------- - if (EndOfCSSCK) begin - NextState = TRANSMIT; - end - end + INACTIVE: if (TransmitStart) + if (~HasCSSCK) NextState = TRANSMIT; + else NextState = CSSCK; + else NextState = INACTIVE; + CSSCK: if (EndOfCSSCK) NextState = TRANSMIT; + else NextState = CSSCK; TRANSMIT: begin // TRANSMIT case -------------------------------- case(CSMode) AUTOMODE: begin - if (EndTransmission) begin - NextState = INACTIVE; - end else if (ContinueTransmit) begin - NextState = SCKCS; - end + if (EndTransmission) NextState = INACTIVE; + else if (ContinueTransmit) NextState = SCKCS; end HOLDMODE: begin - if (EndTransmission) begin - NextState = HOLD; - end else if (ContinueTransmit) begin - if (HasINTERXFR) NextState = INTERXFR; - end + if (EndTransmission) NextState = HOLD; + else if (ContinueTransmit & HasINTERXFR) NextState = INTERXFR; + else NextState = TRANSMIT; end OFFMODE: begin end - endcase end SCKCS: begin // SCKCS case -------------------------------------- - if (EndOfSCKCS) begin - if (EndTransmission) begin + if (EndOfSCKCS) + if (EndTransmission) if (CSMode == AUTOMODE) NextState = INACTIVE; else if (CSMode == HOLDMODE) NextState = HOLD; - end else if (ContinueTransmit) begin + else if (ContinueTransmit) if (HasINTERCS) NextState = INTERCS; else NextState = TRANSMIT; - end - end end HOLD: begin // HOLD mode case ----------------------------------- if (CSMode == AUTOMODE) begin NextState = INACTIVE; end else if (TransmitStart) begin // If FIFO is written to, start again. NextState = TRANSMIT; - end + end else NextState = HOLD; end INTERCS: begin // INTERCS case ---------------------------------- if (EndOfINTERCS) begin @@ -330,19 +316,6 @@ module spi_controller ( assign Transmitting = CurrState == TRANSMIT; assign DelayIsNext = (NextState == CSSCK | NextState == SCKCS | NextState == INTERCS | NextState == INTERXFR); - - // - always_ff @(posedge PCLK) begin - if (~PRESETn) begin - TransmitReg <= 8'b0; - end else if (TransmitLoad) begin - TransmitReg <= txFIFORead; - end else if (ShiftEdge) begin - TransmitReg <= {TransmitReg[6:0], TransmitReg[0]}; - end - end - - assign SPIOUT = TransmitReg[7]; - assign CS = CurrState == INACTIVE | CurrState == INTERCS; + assign InactiveState = CurrState == INACTIVE | CurrState == INTERCS; endmodule From 57d1709582726e66c5c6dbd645e6e8e4e2e06f33 Mon Sep 17 00:00:00 2001 From: Rose Thompson Date: Wed, 30 Oct 2024 16:01:11 -0500 Subject: [PATCH 08/30] The path to the zsbl was wrong all this time, but for reason was working with older versions of Ubuntu, but one 24.04 it causes vivado to not find the rom and ram. --- fpga/constraints/marked_debug.txt | 19 +++++++++++++++++++ fpga/constraints/small-debug-spi.xdc | 1 - fpga/generator/Makefile | 4 ++-- fpga/generator/wally.tcl | 3 ++- 4 files changed, 23 insertions(+), 4 deletions(-) diff --git a/fpga/constraints/marked_debug.txt b/fpga/constraints/marked_debug.txt index 1d23c29a2..a50091827 100644 --- a/fpga/constraints/marked_debug.txt +++ b/fpga/constraints/marked_debug.txt @@ -5,3 +5,22 @@ wally/wallypipelinedcore.sv: logic InstrM lsu/lsu.sv: logic IEUAdrM lsu/lsu.sv: logic MemRWM mmu/hptw.sv: logic SATP_REGW +uncore/spi_apb.sv: logic ShiftIn +uncore/spi_apb.sv: logic ReceiveShiftReg +uncore/spi_apb.sv: logic SCLKenable +uncore/spi_apb.sv: logic SampleEdge +uncore/spi_apb.sv: logic Active +uncore/spi_apb.sv: statetype state +uncore/spi_apb.sv: typedef rsrstatetype +uncore/spi_apb.sv: logic SPICLK +uncore/spi_apb.sv: logic SPIOut +uncore/spi_apb.sv: logic SPICS +uncore/spi_apb.sv: logic SckMode +uncore/spi_apb.sv: logic SckDiv +uncore/spi_apb.sv: logic ShiftEdge +uncore/spi_apb.sv: logic TransmitShiftRegLoad +uncore/spi_apb.sv: logic TransmitShiftReg +uncore/spi_apb.sv: logic TransmitData +uncore/spi_apb.sv: logic ReceiveData +uncore/spi_apb.sv: logic ReceiveShiftRegEndian +uncore/spi_apb.sv: logic ASR diff --git a/fpga/constraints/small-debug-spi.xdc b/fpga/constraints/small-debug-spi.xdc index f62e3d4d3..5951bdcb8 100644 --- a/fpga/constraints/small-debug-spi.xdc +++ b/fpga/constraints/small-debug-spi.xdc @@ -191,7 +191,6 @@ set_property port_width 1 [get_debug_ports u_ila_0/probe33] set_property PROBE_TYPE DATA_AND_TRIGGER [get_debug_ports u_ila_0/probe33] connect_debug_port u_ila_0/probe33 [get_nets [list {wallypipelinedsoc/uncoregen.uncore/sdc.sdc/TransmitFIFOReadEmpty} ]] - # the debug hub has issues with the clocks from the mmcm so lets give up an connect to the 100Mhz input clock. #connect_debug_port dbg_hub/clk [get_nets default_100mhz_clk] connect_debug_port dbg_hub/clk [get_nets CPUCLK] diff --git a/fpga/generator/Makefile b/fpga/generator/Makefile index 7ffd9f163..52e46ec38 100644 --- a/fpga/generator/Makefile +++ b/fpga/generator/Makefile @@ -69,8 +69,8 @@ PreProcessFiles: ./insert_debug_comment.sh # This line allows the Bootloader to be loaded in a Block RAM on the FPGA sed -i "s/bit \[DATA_WIDTH-1:0\].*ROM.*/(\* rom_style=\"block\" \*) &/g" ../src/CopiedFiles_do_not_add_to_repo/generic/mem/rom1p1r.sv - sed -i 's/$$WALLY/\.\.\/\.\.\/\.\.\//g' ../src/CopiedFiles_do_not_add_to_repo/generic/mem/rom1p1r.sv - sed -i 's/$$WALLY/\.\.\/\.\.\/\.\.\//g' ../src/CopiedFiles_do_not_add_to_repo/generic/mem/ram1p1rwbe.sv + sed -i 's/$$WALLY/\.\.\/\.\.\//g' ../src/CopiedFiles_do_not_add_to_repo/generic/mem/rom1p1r.sv + sed -i 's/$$WALLY/\.\.\/\.\.\//g' ../src/CopiedFiles_do_not_add_to_repo/generic/mem/ram1p1rwbe.sv # build the Zero stage boot loader (ZSBL) .PHONY: zsbl diff --git a/fpga/generator/wally.tcl b/fpga/generator/wally.tcl index 3ca0c3360..7935b5913 100644 --- a/fpga/generator/wally.tcl +++ b/fpga/generator/wally.tcl @@ -102,7 +102,8 @@ if {$board=="ArtyA7"} { } else { #source ../constraints/vcu-small-debug.xdc #source ../constraints/small-debug.xdc - source ../constraints/small-debug-spi.xdc + #source ../constraints/small-debug.xdc + source ../constraints/big-debug-spi.xdc } From 1629eda6088fd3d4f916f6aed288941eaaeb144f Mon Sep 17 00:00:00 2001 From: Rose Thompson Date: Wed, 30 Oct 2024 16:07:05 -0500 Subject: [PATCH 09/30] Added btbthrash to tests.vh. --- testbench/tests.vh | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/testbench/tests.vh b/testbench/tests.vh index bef41ef22..2b8d3a2ec 100644 --- a/testbench/tests.vh +++ b/testbench/tests.vh @@ -72,7 +72,8 @@ string coverage64gc[] = '{ "pmpcfg2", "pmppriority", "pmpcbo", - "pmpadrdecs" + "pmpadrdecs", + "btbthrash" }; string buildroot[] = '{ From 4f0723f23618509255922671127d1eba00769c53 Mon Sep 17 00:00:00 2001 From: Jacob Pease Date: Wed, 30 Oct 2024 16:19:46 -0500 Subject: [PATCH 10/30] Fixed enabling of TransmitFIFOReadIncrement and ReceiveFIFOWriteIncrement --- src/uncore/spi_apb.sv | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/src/uncore/spi_apb.sv b/src/uncore/spi_apb.sv index ebe0726c1..8442cd1b7 100644 --- a/src/uncore/spi_apb.sv +++ b/src/uncore/spi_apb.sv @@ -231,17 +231,22 @@ module spi_apb import cvw::*; #(parameter cvw_t P) ( always_ff @(posedge PCLK) if (~PRESETn) begin TransmitFIFOWriteIncrement <= 1'b0; - TransmitFIFOReadIncrement <= 1'b0; end else begin TransmitFIFOWriteIncrement <= (Memwrite & (Entry == SPI_TXDATA) & ~TransmitFIFOWriteFull); - TransmitFIFOReadIncrement <= TransmitLoad; end + always_ff @(posedge PCLK) + if (~PRESETn) begin + TransmitFIFOReadIncrement <= 1'b0; + end else if (SCLKenable) begin + TransmitFIFOReadIncrement <= TransmitLoad; + end + // Setup TransmitStart state machine always_ff @(posedge PCLK) begin if (~PRESETn) begin CurrState <= READY; - end else if (SCLKenable) begin + end else begin CurrState <= NextState; end end @@ -273,9 +278,14 @@ module spi_apb import cvw::*; #(parameter cvw_t P) ( always_ff @(posedge PCLK) if (~PRESETn) begin ReceiveFIFOReadIncrement <= 1'b0; - ReceiveFIFOWriteInc <= 1'b0; end else begin ReceiveFIFOReadIncrement <= ((Entry == SPI_RXDATA) & ~ReceiveFIFOReadEmpty & PSEL & ~ReceiveFIFOReadIncrement); + end + + always_ff @(posedge PCLK) + if (~PRESETn) begin + ReceiveFIFOWriteInc <= 1'b0; + end else if (SCLKenable) begin ReceiveFIFOWriteInc <= EndOfFrameDelay; end From 9400a2aba419d83c39e62ab0e80daf6292059d9e Mon Sep 17 00:00:00 2001 From: Rose Thompson Date: Wed, 30 Oct 2024 17:20:53 -0500 Subject: [PATCH 11/30] Remove vivavdo-ubuntu24.04-04-lib.sh because Jordan found a better solution by symlinking the new libncurses6 and libtinfo6 to the old libraries. --- bin/vivado-ubuntu24.04-libs.sh | 52 ---------------------------------- 1 file changed, 52 deletions(-) delete mode 100755 bin/vivado-ubuntu24.04-libs.sh diff --git a/bin/vivado-ubuntu24.04-libs.sh b/bin/vivado-ubuntu24.04-libs.sh deleted file mode 100755 index 29a0f1671..000000000 --- a/bin/vivado-ubuntu24.04-libs.sh +++ /dev/null @@ -1,52 +0,0 @@ -#!/bin/bash - -# Rose Thompson rose@rosethompson.net -# Oct 29, 2024 -# Downloads libncurses5 and libtinfo5 from ubuntu 22.04, extracts the libraries and installs to the system. Requires root. - -# A component of the CORE-V-WALLY configurable RISC-V project. -# https://github.com/openhwgroup/cvw -# -# Copyright (C) 2021-23 Harvey Mudd College & Oklahoma State University -# -# SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1 -# -# Licensed under the Solderpad Hardware License v 2.1 (the “License”); you may not use this file -# except in compliance with the License, or, at your option, the Apache License version 2.0. You -# may obtain a copy of the License at -# -# https://solderpad.org/licenses/SHL-2.1/ -# -# Unless required by applicable law or agreed to in writing, any work distributed under the -# License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, -# either express or implied. See the License for the specific language governing permissions -# and limitations under the License. - -TmpDir=$(mktemp -d ) -echo $TmpDir - -cd $TmpDir - -wget http://security.ubuntu.com/ubuntu/pool/universe/n/ncurses/libtinfo5_6.3-2ubuntu0.1_amd64.deb -wget http://security.ubuntu.com/ubuntu/pool/universe/n/ncurses/libncurses5_6.3-2ubuntu0.1_amd64.deb - -dpkg-deb -xv libtinfo5_6.3-2ubuntu0.1_amd64.deb ./libtinfo5 -dpkg-deb -xv libncurses5_6.3-2ubuntu0.1_amd64.deb ./libncurses5 - -echo "Installing libraries." -sudo cp libncurses5/lib/x86_64-linux-gnu/* /usr/lib/x86_64-linux-gnu/ -sudo cp libncurses5/usr/lib/x86_64-linux-gnu/* /usr/lib/x86_64-linux-gnu/ -sudo cp libtinfo5/lib/x86_64-linux-gnu/* /usr/lib/x86_64-linux-gnu/ -sudo cp libtinfo5/usr/lib/x86_64-linux-gnu/* /usr/lib/x86_64-linux-gnu/ -sudo cp -r libtinfo5/usr/share/doc/* /usr/share/doc/ -sudo ln -f -s /usr/share/doc/libtinfo5/ /usr/share/doc/libncurses5 - -cd - - -echo "Removing temporary files." -rm -rf $TmpDir - -echo "Finished." - - - From 4e7e311b26756d724b4531df619bdedca9f716ac Mon Sep 17 00:00:00 2001 From: Jacob Pease Date: Wed, 30 Oct 2024 18:39:04 -0500 Subject: [PATCH 12/30] Fixed issues relating to SCLKenable and TransmitStart. Works at multiple dividers now, instead of just SckDiv = 0. --- src/uncore/spi_apb.sv | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/src/uncore/spi_apb.sv b/src/uncore/spi_apb.sv index 8442cd1b7..33978637b 100644 --- a/src/uncore/spi_apb.sv +++ b/src/uncore/spi_apb.sv @@ -89,6 +89,7 @@ module spi_apb import cvw::*; #(parameter cvw_t P) ( logic ResetSCLKenable; logic TransmitStart; + logic TransmitStartD; // Transmit Start State Machine Variables typedef enum logic [1:0] {READY, START, WAIT} txState; @@ -215,7 +216,7 @@ module spi_apb import cvw::*; #(parameter cvw_t P) ( spi_controller controller(PCLK, PRESETn, // Transmit Signals - TransmitStart, ResetSCLKenable, + TransmitStart, TransmitStartD, ResetSCLKenable, // Register Inputs SckDiv, SckMode, ChipSelectMode, Delay0, Delay1, // txFIFO stuff @@ -239,7 +240,7 @@ module spi_apb import cvw::*; #(parameter cvw_t P) ( if (~PRESETn) begin TransmitFIFOReadIncrement <= 1'b0; end else if (SCLKenable) begin - TransmitFIFOReadIncrement <= TransmitLoad; + TransmitFIFOReadIncrement <= TransmitStartD | (EndOfFrameDelay & ~TransmitFIFOReadEmpty) ; end // Setup TransmitStart state machine @@ -254,7 +255,7 @@ module spi_apb import cvw::*; #(parameter cvw_t P) ( // State machine for starting transmissions always_comb begin case (CurrState) - READY: if (~TransmitFIFOReadEmpty) NextState = START; + READY: if (~TransmitFIFOReadEmpty & ~Transmitting) NextState = START; else NextState = READY; START: NextState = WAIT; WAIT: if (TransmitFIFOReadEmpty & ~Transmitting) NextState = READY; @@ -263,6 +264,10 @@ module spi_apb import cvw::*; #(parameter cvw_t P) ( end assign TransmitStart = (CurrState == START); + always_ff @(posedge PCLK) + if (~PRESETn) TransmitStartD <= 1'b0; + else if (TransmitStart) TransmitStartD <= 1'b1; + else if (SCLKenable) TransmitStartD <= 1'b0; spi_fifo #(3,8) txFIFO(PCLK, 1'b1, SCLKenable, PRESETn, TransmitFIFOWriteIncrement, TransmitFIFOReadIncrement, From 35c9fe764803e6d3d905b19e2c7e9fc158b88f1c Mon Sep 17 00:00:00 2001 From: Jacob Pease Date: Wed, 30 Oct 2024 18:45:54 -0500 Subject: [PATCH 13/30] Added changed SPI controller module. New signal TransmitStartD that starts the FSM based on SCLKenable. TransmitStart is responsible for resetting SCLKenable and loading the Transmit Shift Register. --- src/uncore/spi_controller.sv | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/src/uncore/spi_controller.sv b/src/uncore/spi_controller.sv index 9692b7588..d3c800102 100644 --- a/src/uncore/spi_controller.sv +++ b/src/uncore/spi_controller.sv @@ -34,7 +34,8 @@ module spi_controller ( // Start Transmission input logic TransmitStart, - input logic ResetSCLKenable, + input logic TransmitStartD, + input logic ResetSCLKenable, // Registers input logic [11:0] SckDiv, @@ -168,25 +169,25 @@ module spi_controller ( SCK <= ~SCK; end - if ((CurrState == CSSCK) & SCK) begin + if ((CurrState == CSSCK) & SCK & SCLKenable) begin CSSCKCounter <= CSSCKCounter + 8'd1; - end else begin + end else if (SCLKenable) begin CSSCKCounter <= 8'd0; end - if ((CurrState == SCKCS) & SCK) begin + if ((CurrState == SCKCS) & SCK & SCLKenable) begin SCKCSCounter <= SCKCSCounter + 8'd1; - end else begin + end else if (SCLKenable) begin SCKCSCounter <= 8'd0; end - if ((CurrState == INTERCS) & SCK) begin + if ((CurrState == INTERCS) & SCK & SCLKenable) begin INTERCSCounter <= INTERCSCounter + 8'd1; end else begin INTERCSCounter <= 8'd0; end - if ((CurrState == INTERXFR) & SCK) begin + if ((CurrState == INTERXFR) & SCK & SCLKenable) begin INTERXFRCounter <= INTERXFRCounter + 8'd1; end else begin INTERXFRCounter <= 8'd0; @@ -259,7 +260,7 @@ module spi_controller ( always_comb begin case (CurrState) - INACTIVE: if (TransmitStart) + INACTIVE: if (TransmitStartD) if (~HasCSSCK) NextState = TRANSMIT; else NextState = CSSCK; else NextState = INACTIVE; @@ -293,7 +294,7 @@ module spi_controller ( HOLD: begin // HOLD mode case ----------------------------------- if (CSMode == AUTOMODE) begin NextState = INACTIVE; - end else if (TransmitStart) begin // If FIFO is written to, start again. + end else if (TransmitStartD) begin // If FIFO is written to, start again. NextState = TRANSMIT; end else NextState = HOLD; end From 27492499c69ec508a2f1390b59d1bf1a3233c96d Mon Sep 17 00:00:00 2001 From: Corey Hickson Date: Thu, 31 Oct 2024 02:48:53 -0700 Subject: [PATCH 14/30] Enabled ZfaF, ZfaD, ZfaZfh coverage --- config/rv32gc/coverage.svh | 3 +++ config/rv64gc/coverage.svh | 3 +++ 2 files changed, 6 insertions(+) diff --git a/config/rv32gc/coverage.svh b/config/rv32gc/coverage.svh index 217e8788a..2eb52541f 100644 --- a/config/rv32gc/coverage.svh +++ b/config/rv32gc/coverage.svh @@ -10,6 +10,9 @@ `include "RV32M_coverage.svh" `include "RV32F_coverage.svh" `include "RV32D_coverage.svh" +`include "RV32ZfaF_coverage.svh" +`include "RV32ZfaD_coverage.svh" +`include "RV32ZfaZfh_coverage.svh" `include "RV32ZfhD_coverage.svh" `include "RV32Zfh_coverage.svh" `include "RV32Zicond_coverage.svh" diff --git a/config/rv64gc/coverage.svh b/config/rv64gc/coverage.svh index 0491b4ab3..d594a3a44 100644 --- a/config/rv64gc/coverage.svh +++ b/config/rv64gc/coverage.svh @@ -10,6 +10,9 @@ `include "RV64M_coverage.svh" `include "RV64F_coverage.svh" `include "RV64D_coverage.svh" +`include "RV64ZfaF_coverage.svh" +`include "RV32ZfaD_coverage.svh" +`include "RV32ZfaZfh_coverage.svh" `include "RV64ZfhD_coverage.svh" `include "RV64Zfh_coverage.svh" `include "RV64Zicond_coverage.svh" From 419030bc331483042c8c85b557d5276b2d5fa74c Mon Sep 17 00:00:00 2001 From: Jacob Pease Date: Thu, 31 Oct 2024 10:41:38 -0500 Subject: [PATCH 15/30] Fixed FSM to continue transmitting after delay. --- src/uncore/spi_controller.sv | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/src/uncore/spi_controller.sv b/src/uncore/spi_controller.sv index d3c800102..10ff511a6 100644 --- a/src/uncore/spi_controller.sv +++ b/src/uncore/spi_controller.sv @@ -148,7 +148,8 @@ module spi_controller ( // assign SCLKenableEarly = (DivCounter + 1'b1) == SckDiv; assign LastBit = BitNum == 3'd7; - assign ContinueTransmit = ~txFIFOReadEmpty & EndOfFrame; + //assign EndOfFrame = SCLKenable & LastBit & Transmitting; + assign ContinueTransmit = ~txFIFOReadEmpty & EndOfFrameDelay; assign EndTransmission = txFIFOReadEmpty & EndOfFrameDelay; always_ff @(posedge PCLK) begin @@ -183,13 +184,13 @@ module spi_controller ( if ((CurrState == INTERCS) & SCK & SCLKenable) begin INTERCSCounter <= INTERCSCounter + 8'd1; - end else begin + end else if (SCLKenable) begin INTERCSCounter <= 8'd0; end if ((CurrState == INTERXFR) & SCK & SCLKenable) begin INTERXFRCounter <= INTERXFRCounter + 8'd1; - end else begin + end else if (SCLKenable) begin INTERXFRCounter <= 8'd0; end @@ -239,7 +240,7 @@ module spi_controller ( end else begin ShiftEdge <= ((SckMode[1] ^ SckMode[0] ^ SPICLK) & SCLKenable & ~LastBit & Transmitting) & PhaseOneOffset; PhaseOneOffset <= PhaseOneOffset == 0 ? Transmitting & SCLKenable : PhaseOneOffset; - SampleEdge <= (SckMode[1] ^ SckMode[0] ^ ~SPICLK) & SCLKenable & Transmitting; + SampleEdge <= (SckMode[1] ^ SckMode[0] ^ ~SPICLK) & SCLKenable & Transmitting & ~DelayIsNext; EndOfFrameDelay <= (SckMode[1] ^ SckMode[0] ^ SPICLK) & SCLKenable & LastBit & Transmitting; end end @@ -284,12 +285,13 @@ module spi_controller ( end SCKCS: begin // SCKCS case -------------------------------------- if (EndOfSCKCS) - if (EndTransmission) + if (txFIFOReadEmpty) begin if (CSMode == AUTOMODE) NextState = INACTIVE; else if (CSMode == HOLDMODE) NextState = HOLD; - else if (ContinueTransmit) + end else if (~txFIFOReadEmpty) begin if (HasINTERCS) NextState = INTERCS; else NextState = TRANSMIT; + end end HOLD: begin // HOLD mode case ----------------------------------- if (CSMode == AUTOMODE) begin From 72a854eb075f90fde3fa9bfb6ba653845c2d54f6 Mon Sep 17 00:00:00 2001 From: Jacob Pease Date: Thu, 31 Oct 2024 13:01:25 -0500 Subject: [PATCH 16/30] Refactored SPI passes regression save for hardware interlock tests. --- src/uncore/spi_apb.sv | 21 ++++++++++++-- src/uncore/spi_controller.sv | 53 +++++++++++++++++++++++++++--------- 2 files changed, 58 insertions(+), 16 deletions(-) diff --git a/src/uncore/spi_apb.sv b/src/uncore/spi_apb.sv index 33978637b..c8084de42 100644 --- a/src/uncore/spi_apb.sv +++ b/src/uncore/spi_apb.sv @@ -86,6 +86,7 @@ module spi_apb import cvw::*; #(parameter cvw_t P) ( logic EndOfFrameDelay; logic Transmitting; logic InactiveState; + logic [3:0] FrameLength; logic ResetSCLKenable; logic TransmitStart; @@ -213,12 +214,13 @@ module spi_apb import cvw::*; #(parameter cvw_t P) ( // SPI Controller module ------------------------------------------- // This module controls state and timing signals that drive the rest of this module assign ResetSCLKenable = Memwrite & (Entry == SPI_SCKDIV); + assign FrameLength = Format[4:1]; spi_controller controller(PCLK, PRESETn, // Transmit Signals TransmitStart, TransmitStartD, ResetSCLKenable, // Register Inputs - SckDiv, SckMode, ChipSelectMode, Delay0, Delay1, + SckDiv, SckMode, ChipSelectMode, Delay0, Delay1, FrameLength, // txFIFO stuff TransmitFIFOReadEmpty, // Timing @@ -243,6 +245,19 @@ module spi_apb import cvw::*; #(parameter cvw_t P) ( TransmitFIFOReadIncrement <= TransmitStartD | (EndOfFrameDelay & ~TransmitFIFOReadEmpty) ; end + // Check whether TransmitReg has been loaded. + // We use this signal to prevent returning to the Ready state for TransmitStart + logic TransmitRegLoaded; + always_ff @(posedge PCLK) begin + if (~PRESETn) begin + TransmitRegLoaded <= 1'b0; + end else if (TransmitLoad) begin + TransmitRegLoaded <= 1'b1; + end else if (ShiftEdge | EndOfFrameDelay) begin + TransmitRegLoaded <= 1'b0; + end + end + // Setup TransmitStart state machine always_ff @(posedge PCLK) begin if (~PRESETn) begin @@ -251,14 +266,14 @@ module spi_apb import cvw::*; #(parameter cvw_t P) ( CurrState <= NextState; end end - + // State machine for starting transmissions always_comb begin case (CurrState) READY: if (~TransmitFIFOReadEmpty & ~Transmitting) NextState = START; else NextState = READY; START: NextState = WAIT; - WAIT: if (TransmitFIFOReadEmpty & ~Transmitting) NextState = READY; + WAIT: if (TransmitFIFOReadEmpty & ~Transmitting & ~TransmitRegLoaded) NextState = READY; else NextState = WAIT; endcase end diff --git a/src/uncore/spi_controller.sv b/src/uncore/spi_controller.sv index 10ff511a6..2b74e79c9 100644 --- a/src/uncore/spi_controller.sv +++ b/src/uncore/spi_controller.sv @@ -43,6 +43,7 @@ module spi_controller ( input logic [1:0] CSMode, input logic [15:0] Delay0, input logic [15:0] Delay1, + input logic [3:0] FrameLength, // Is the Transmit FIFO Empty? input logic txFIFOReadEmpty, @@ -146,7 +147,7 @@ module spi_controller ( assign SCLKenable = DivCounter == SckDiv; // assign SCLKenableEarly = (DivCounter + 1'b1) == SckDiv; - assign LastBit = BitNum == 3'd7; + assign LastBit = (BitNum == FrameLength - 4'b1); //assign EndOfFrame = SCLKenable & LastBit & Transmitting; assign ContinueTransmit = ~txFIFOReadEmpty & EndOfFrameDelay; @@ -161,6 +162,10 @@ module spi_controller ( PreShiftEdge <= 0; PreSampleEdge <= 0; EndOfFrame <= 0; + CSSCKCounter <= 0; + SCKCSCounter <= 0; + INTERCSCounter <= 0; + INTERXFRCounter <= 0; end else begin // TODO: Consolidate into one delay counter since none of the // delays happen at the same time? @@ -172,25 +177,25 @@ module spi_controller ( if ((CurrState == CSSCK) & SCK & SCLKenable) begin CSSCKCounter <= CSSCKCounter + 8'd1; - end else if (SCLKenable) begin + end else if (SCLKenable & EndOfCSSCK) begin CSSCKCounter <= 8'd0; end if ((CurrState == SCKCS) & SCK & SCLKenable) begin SCKCSCounter <= SCKCSCounter + 8'd1; - end else if (SCLKenable) begin + end else if (SCLKenable & EndOfSCKCS) begin SCKCSCounter <= 8'd0; end if ((CurrState == INTERCS) & SCK & SCLKenable) begin INTERCSCounter <= INTERCSCounter + 8'd1; - end else if (SCLKenable) begin + end else if (SCLKenable & EndOfINTERCS) begin INTERCSCounter <= 8'd0; end if ((CurrState == INTERXFR) & SCK & SCLKenable) begin INTERXFRCounter <= INTERXFRCounter + 8'd1; - end else if (SCLKenable) begin + end else if (SCLKenable & EndOfINTERXFR) begin INTERXFRCounter <= 8'd0; end @@ -239,7 +244,7 @@ module spi_controller ( EndOfFrameDelay <= 0; end else begin ShiftEdge <= ((SckMode[1] ^ SckMode[0] ^ SPICLK) & SCLKenable & ~LastBit & Transmitting) & PhaseOneOffset; - PhaseOneOffset <= PhaseOneOffset == 0 ? Transmitting & SCLKenable : PhaseOneOffset; + PhaseOneOffset <= PhaseOneOffset == 0 ? Transmitting & SCLKenable : ~EndOfFrameDelay; SampleEdge <= (SckMode[1] ^ SckMode[0] ^ ~SPICLK) & SCLKenable & Transmitting & ~DelayIsNext; EndOfFrameDelay <= (SckMode[1] ^ SckMode[0] ^ SPICLK) & SCLKenable & LastBit & Transmitting; end @@ -251,6 +256,23 @@ module spi_controller ( assign HoldMode = CSMode == HOLDMODE; // assign TransmitLoad = TransmitStart | (EndOfFrameDelay & ~txFIFOReadEmpty); + logic ContinueTransmitD; + logic NextEndDelay; + logic CurrentEndDelay; + + assign NextEndDelay = NextState == SCKCS | NextState == INTERCS | NextState == INTERXFR; + assign CurrentEndDelay = CurrState == SCKCS | CurrState == INTERCS | CurrState == INTERXFR; + + always_ff @(posedge PCLK) begin + if (~PRESETn) begin + ContinueTransmitD <= 1'b0; + end else if (NextEndDelay & ~CurrentEndDelay) begin + ContinueTransmitD <= ContinueTransmit; + end else if (EndOfSCKCS & SCLKenable) begin + ContinueTransmitD <= 1'b0; + end + end + always_ff @(posedge PCLK) begin if (~PRESETn) begin CurrState <= INACTIVE; @@ -261,17 +283,19 @@ module spi_controller ( always_comb begin case (CurrState) - INACTIVE: if (TransmitStartD) + INACTIVE: if (TransmitStartD) begin if (~HasCSSCK) NextState = TRANSMIT; else NextState = CSSCK; - else NextState = INACTIVE; + end else begin + NextState = INACTIVE; + end CSSCK: if (EndOfCSSCK) NextState = TRANSMIT; else NextState = CSSCK; TRANSMIT: begin // TRANSMIT case -------------------------------- case(CSMode) AUTOMODE: begin if (EndTransmission) NextState = INACTIVE; - else if (ContinueTransmit) NextState = SCKCS; + else if (EndOfFrameDelay) NextState = SCKCS; end HOLDMODE: begin if (EndTransmission) NextState = HOLD; @@ -279,19 +303,22 @@ module spi_controller ( else NextState = TRANSMIT; end OFFMODE: begin - + if (EndTransmission) NextState = INACTIVE; + else if (ContinueTransmit & HasINTERXFR) NextState = INTERXFR; + else NextState = TRANSMIT; end endcase end SCKCS: begin // SCKCS case -------------------------------------- - if (EndOfSCKCS) - if (txFIFOReadEmpty) begin + if (EndOfSCKCS) begin + if (~ContinueTransmitD) begin if (CSMode == AUTOMODE) NextState = INACTIVE; else if (CSMode == HOLDMODE) NextState = HOLD; - end else if (~txFIFOReadEmpty) begin + end else begin if (HasINTERCS) NextState = INTERCS; else NextState = TRANSMIT; end + end end HOLD: begin // HOLD mode case ----------------------------------- if (CSMode == AUTOMODE) begin From 3ee5fffe02b3276a40c1eb99863db1ae19424d71 Mon Sep 17 00:00:00 2001 From: Jacob Pease Date: Thu, 31 Oct 2024 13:54:56 -0500 Subject: [PATCH 17/30] Fixing latches. --- src/uncore/spi_apb.sv | 1 + src/uncore/spi_controller.sv | 8 ++++++++ 2 files changed, 9 insertions(+) diff --git a/src/uncore/spi_apb.sv b/src/uncore/spi_apb.sv index c8084de42..911ab3a15 100644 --- a/src/uncore/spi_apb.sv +++ b/src/uncore/spi_apb.sv @@ -275,6 +275,7 @@ module spi_apb import cvw::*; #(parameter cvw_t P) ( START: NextState = WAIT; WAIT: if (TransmitFIFOReadEmpty & ~Transmitting & ~TransmitRegLoaded) NextState = READY; else NextState = WAIT; + default: NextState = READY; endcase end diff --git a/src/uncore/spi_controller.sv b/src/uncore/spi_controller.sv index 2b74e79c9..10ad09f91 100644 --- a/src/uncore/spi_controller.sv +++ b/src/uncore/spi_controller.sv @@ -296,6 +296,7 @@ module spi_controller ( AUTOMODE: begin if (EndTransmission) NextState = INACTIVE; else if (EndOfFrameDelay) NextState = SCKCS; + else NextState = TRANSMIT; end HOLDMODE: begin if (EndTransmission) NextState = HOLD; @@ -307,6 +308,7 @@ module spi_controller ( else if (ContinueTransmit & HasINTERXFR) NextState = INTERXFR; else NextState = TRANSMIT; end + default: NextState = TRANSMIT; endcase end SCKCS: begin // SCKCS case -------------------------------------- @@ -318,6 +320,8 @@ module spi_controller ( if (HasINTERCS) NextState = INTERCS; else NextState = TRANSMIT; end + end else begin + NextState = SCKCS; end end HOLD: begin // HOLD mode case ----------------------------------- @@ -331,11 +335,15 @@ module spi_controller ( if (EndOfINTERCS) begin if (HasCSSCK) NextState = CSSCK; else NextState = TRANSMIT; + end else begin + NextState = INTERCS; end end INTERXFR: begin // INTERXFR case -------------------------------- if (EndOfINTERXFR) begin NextState = TRANSMIT; + end else begin + NextState = INTERXFR; end end default: begin From 56a6ad3376276ece7ca22ae3979346b43d20babf Mon Sep 17 00:00:00 2001 From: Jacob Pease Date: Thu, 31 Oct 2024 15:56:16 -0500 Subject: [PATCH 18/30] Fixed lint issues. --- src/uncore/spi_apb.sv | 5 +++-- src/uncore/spi_controller.sv | 10 +++++----- 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/src/uncore/spi_apb.sv b/src/uncore/spi_apb.sv index 911ab3a15..5d3352154 100644 --- a/src/uncore/spi_apb.sv +++ b/src/uncore/spi_apb.sv @@ -337,8 +337,9 @@ module spi_apb import cvw::*; #(parameter cvw_t P) ( // Receive shift register always_ff @(posedge PCLK) - if(~PRESETn) ReceiveShiftReg <= 8'b0; - else if (SampleEdge) begin + if(~PRESETn) begin + ReceiveShiftReg <= 8'b0; + end else if (SampleEdge) begin if (~Transmitting) ReceiveShiftReg <= 8'b0; else ReceiveShiftReg <= {ReceiveShiftReg[6:0], ShiftIn}; end diff --git a/src/uncore/spi_controller.sv b/src/uncore/spi_controller.sv index 10ad09f91..605685b4b 100644 --- a/src/uncore/spi_controller.sv +++ b/src/uncore/spi_controller.sv @@ -82,7 +82,7 @@ module spi_controller ( // logic SampleEdge; // Frame stuff - logic [2:0] BitNum; + logic [3:0] BitNum; logic LastBit; //logic EndOfFrame; //logic EndOfFrameDelay; @@ -158,7 +158,7 @@ module spi_controller ( DivCounter <= 12'b0; SPICLK <= SckMode[1]; SCK <= 0; - BitNum <= 3'h0; + BitNum <= 4'h0; PreShiftEdge <= 0; PreSampleEdge <= 0; EndOfFrame <= 0; @@ -210,7 +210,7 @@ module spi_controller ( if (SCLKenable | TransmitStart | ResetSCLKenable) begin DivCounter <= 12'b0; end else begin - DivCounter = DivCounter + 12'd1; + DivCounter <= DivCounter + 12'd1; end // EndOfFrame controller @@ -226,9 +226,9 @@ module spi_controller ( // Increment BitNum if (ShiftEdge & Transmitting) begin - BitNum <= BitNum + 3'd1; + BitNum <= BitNum + 4'd1; end else if (EndOfFrameDelay) begin - BitNum <= 3'b0; + BitNum <= 4'b0; end end end From f258384596fd2975f14d3e6f0f86ebc4fb44ba52 Mon Sep 17 00:00:00 2001 From: Huda-10xe Date: Fri, 1 Nov 2024 06:07:49 -0700 Subject: [PATCH 19/30] Adding sv32 coverpoins --- config/rv32gc/coverage.svh | 2 ++ sim/questa/wally.do | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/config/rv32gc/coverage.svh b/config/rv32gc/coverage.svh index 2eb52541f..97496a8b9 100644 --- a/config/rv32gc/coverage.svh +++ b/config/rv32gc/coverage.svh @@ -25,3 +25,5 @@ // Privileged extensions `include "ZicsrM_coverage.svh" +`include "RV32VM_coverage.svh" +`include "RV32VM_PMP_coverage.svh" diff --git a/sim/questa/wally.do b/sim/questa/wally.do index a53a0e3c7..c692b06e1 100644 --- a/sim/questa/wally.do +++ b/sim/questa/wally.do @@ -181,7 +181,7 @@ if {$DEBUG > 0} { # suppress spurious warnngs about # "Extra checking for conflicts with always_comb done at vopt time" # because vsim will run vopt -set INC_DIRS "+incdir+${CONFIG}/${CFG} +incdir+${CONFIG}/deriv/${CFG} +incdir+${CONFIG}/shared +incdir+${FCRVVI} +incdir+${FCRVVI}/rv32 +incdir+${FCRVVI}/rv64 +incdir+${FCRVVI}/rv64_priv +incdir+${FCRVVI}/priv +incdir+${FCRVVI}/common +incdir+${FCRVVI}" +set INC_DIRS "+incdir+${CONFIG}/${CFG} +incdir+${CONFIG}/deriv/${CFG} +incdir+${CONFIG}/shared +incdir+${FCRVVI} +incdir+${FCRVVI}/rv32 +incdir+${FCRVVI}/rv64 +incdir+${FCRVVI}/rv64_priv +incdir+${FCRVVI}/priv +incdir+${FCRVVI}/rv32_priv +incdir+${FCRVVI}/common +incdir+${FCRVVI}" set SOURCES "${SRC}/cvw.sv ${TB}/${TESTBENCH}.sv ${TB}/common/*.sv ${SRC}/*/*.sv ${SRC}/*/*/*.sv ${WALLY}/addins/verilog-ethernet/*/*.sv ${WALLY}/addins/verilog-ethernet/*/*/*/*.sv" vlog -permissive -lint -work ${WKDIR} {*}${INC_DIRS} {*}${FCvlog} {*}${FCdefineCOVER_EXTS} {*}${lockstepvlog} {*}${SOURCES} -suppress 2282,2583,7053,7063,2596,13286 From eddae8e1a676045cf10144af5238ef62c8c43799 Mon Sep 17 00:00:00 2001 From: Jacob Pease Date: Fri, 1 Nov 2024 13:02:17 -0500 Subject: [PATCH 20/30] Fixed ShiftEdge and SampleEdge to not always include PhaseOneOffset. Before, it worked in simulation, but not on the FPGA. --- src/uncore/spi_controller.sv | 37 ++++++++++++++++++++++++++++++------ 1 file changed, 31 insertions(+), 6 deletions(-) diff --git a/src/uncore/spi_controller.sv b/src/uncore/spi_controller.sv index 605685b4b..576884374 100644 --- a/src/uncore/spi_controller.sv +++ b/src/uncore/spi_controller.sv @@ -243,10 +243,34 @@ module spi_controller ( SampleEdge <= 0; EndOfFrameDelay <= 0; end else begin - ShiftEdge <= ((SckMode[1] ^ SckMode[0] ^ SPICLK) & SCLKenable & ~LastBit & Transmitting) & PhaseOneOffset; - PhaseOneOffset <= PhaseOneOffset == 0 ? Transmitting & SCLKenable : ~EndOfFrameDelay; - SampleEdge <= (SckMode[1] ^ SckMode[0] ^ ~SPICLK) & SCLKenable & Transmitting & ~DelayIsNext; - EndOfFrameDelay <= (SckMode[1] ^ SckMode[0] ^ SPICLK) & SCLKenable & LastBit & Transmitting; + case(SckMode) + 2'b00: begin + ShiftEdge <= SPICLK & SCLKenable & ~LastBit & Transmitting; + SampleEdge <= ~SPICLK & SCLKenable & Transmitting & ~DelayIsNext; + EndOfFrameDelay <= SPICLK & SCLKenable & LastBit & Transmitting; + end + 2'b01: begin + ShiftEdge <= ~SPICLK & SCLKenable & ~LastBit & Transmitting & PhaseOneOffset; + SampleEdge <= SPICLK & SCLKenable & Transmitting & ~DelayIsNext; + EndOfFrameDelay <= ~SPICLK & SCLKenable & LastBit & Transmitting; + PhaseOneOffset <= (PhaseOneOffset == 0) ? Transmitting & SCLKenable : ~EndOfFrameDelay; + end + 2'b10: begin + ShiftEdge <= ~SPICLK & SCLKenable & ~LastBit & Transmitting; + SampleEdge <= SPICLK & SCLKenable & Transmitting & ~DelayIsNext; + EndOfFrameDelay <= ~SPICLK & SCLKenable & LastBit & Transmitting; + end + 2'b11: begin + ShiftEdge <= SPICLK & SCLKenable & ~LastBit & Transmitting & PhaseOneOffset; + SampleEdge <= ~SPICLK & SCLKenable & Transmitting & ~DelayIsNext; + EndOfFrameDelay <= SPICLK & SCLKenable & LastBit & Transmitting; + PhaseOneOffset <= (PhaseOneOffset == 0) ? Transmitting & SCLKenable : ~EndOfFrameDelay; + end + // ShiftEdge <= ((SckMode[1] ^ SckMode[0] ^ SPICLK) & SCLKenable & ~LastBit & Transmitting) & PhaseOneOffset; + // PhaseOneOffset <= PhaseOneOffset == 0 ? Transmitting & SCLKenable : ~EndOfFrameDelay; + // SampleEdge <= (SckMode[1] ^ SckMode[0] ^ ~SPICLK) & SCLKenable & Transmitting & ~DelayIsNext; + // EndOfFrameDelay <= (SckMode[1] ^ SckMode[0] ^ SPICLK) & SCLKenable & LastBit & Transmitting; + endcase end end @@ -314,8 +338,9 @@ module spi_controller ( SCKCS: begin // SCKCS case -------------------------------------- if (EndOfSCKCS) begin if (~ContinueTransmitD) begin - if (CSMode == AUTOMODE) NextState = INACTIVE; - else if (CSMode == HOLDMODE) NextState = HOLD; + // if (CSMode == AUTOMODE) NextState = INACTIVE; + if (CSMode == HOLDMODE) NextState = HOLD; + else NextState = INACTIVE; end else begin if (HasINTERCS) NextState = INTERCS; else NextState = TRANSMIT; From 960d72295c9dd34d2acda6de30e92edb8f7e01f0 Mon Sep 17 00:00:00 2001 From: naichewa Date: Fri, 1 Nov 2024 11:27:41 -0700 Subject: [PATCH 21/30] Removed SPI hardware interlock test cases --- addins/cvw-arch-verif | 2 +- addins/riscv-arch-test | 2 +- .../references/WALLY-spi-01.reference_output | 40 -------- .../rv32i_m/privilege/src/WALLY-spi-01.S | 95 ------------------- .../references/WALLY-spi-01.reference_output | 40 -------- .../rv64i_m/privilege/src/WALLY-spi-01.S | 88 ----------------- 6 files changed, 2 insertions(+), 265 deletions(-) diff --git a/addins/cvw-arch-verif b/addins/cvw-arch-verif index bbcba7864..189974e49 160000 --- a/addins/cvw-arch-verif +++ b/addins/cvw-arch-verif @@ -1 +1 @@ -Subproject commit bbcba78647080dee82e96bc1b8ff9cd9a3cf7fa1 +Subproject commit 189974e497d7b8d2c08bb1d151b1ccdeaf3a64c9 diff --git a/addins/riscv-arch-test b/addins/riscv-arch-test index ce04b4930..7152865ac 160000 --- a/addins/riscv-arch-test +++ b/addins/riscv-arch-test @@ -1 +1 @@ -Subproject commit ce04b4930545ae4c81e2f3b6f6935e2aac08679e +Subproject commit 7152865aca51062c87ff2cbb014e199a24bdc874 diff --git a/tests/wally-riscv-arch-test/riscv-test-suite/rv32i_m/privilege/references/WALLY-spi-01.reference_output b/tests/wally-riscv-arch-test/riscv-test-suite/rv32i_m/privilege/references/WALLY-spi-01.reference_output index 425866ac2..027e02f54 100644 --- a/tests/wally-riscv-arch-test/riscv-test-suite/rv32i_m/privilege/references/WALLY-spi-01.reference_output +++ b/tests/wally-riscv-arch-test/riscv-test-suite/rv32i_m/privilege/references/WALLY-spi-01.reference_output @@ -238,46 +238,6 @@ 0000001F -00000062 # hardware interlock - -00000026 - -000000D2 - -0000002D - -00000048 - -00000037 - -00000026 - -00000015 - -00000084 - -00000073 - -00000062 - -00000051 - -00000046 - -00000035 - -00000024 - -00000013 - -00000064 - -00000053 - -00000042 - -00000031 - 00000001 #watermark interrupts 00000000 #read mip 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 4048c4c4c..a004a5ea0 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 @@ -547,101 +547,6 @@ test_cases: #.4byte 0x0, 0x00000000, spi_data_wait # wait for transmission to end #.4byte rx_data, 0x000000F0, read32_test # read rx_data -#=========== Test Hardware Interlock ================ - -# interlock in base case - -.4byte fmt, 0x00080000, write32_test # reset fmt register -.4byte rx_mark, 0x0000001, write32_test # preset rx watermark b/c of hardware interlock -.4byte tx_data, 0x00000062, write32_test # initiate transmission -.4byte sck_mode, 0x00000002, write32_test # flip polarity during transmission -.4byte tx_data, 0x00000026, write32_test # transmit second frame w/ control register updated -.4byte 0x0, 0x00000001, spi_data_wait -.4byte rx_data, 0x00000062, read32_test -.4byte rx_data, 0x00000026, read32_test # clear rx fifo -.4byte sck_mode, 0x00000000, write32_test # reset polarity - -# interlock in case where cs_mode is auto, but there is minimal intercs delay - -.4byte delay0, 0x00000001, write32_test # set sck-cs delay to 0, with sck.pha 0 there is 0 delay -.4byte tx_data, 0x000000D2, write32_test # initiate transmission -.4byte sck_mode, 0x00000002, write32_test # flip sck polarity -.4byte tx_data, 0x0000002D, write32_test # transmit second frame -.4byte 0x0, 0x00000001, spi_data_wait -.4byte rx_data, 0x000000D2, read32_test -.4byte rx_data, 0x0000002D, read32_test # clear rx fifo -.4byte sck_mode, 0x00000000, write32_test # reset polarity - -# interlock in case where cs_mode = hold, 0 intercs delay -.4byte delay0, 0x00010001, write32_test # reset delay0 -.4byte sck_mode, 0x00000000, write32_test # reset polarity -.4byte cs_mode, 0x00000002, write32_test # set cs_mode to hold -.4byte tx_data, 0x15263748, spi_burst_send # place 4 frames into tx fifo -.4byte sck_mode, 0x00000002, write32_test # flip polarity (should change 2 second frame) -.4byte 0x0, 0x00000001, spi_data_wait # wait for second transmission to end -.4byte rx_mark, 0x0000003, write32_test # preset rx watermark b/c of hardware interlock -.4byte sck_mode, 0x00000000, write32_test # flip polarity again -.4byte 0x0, 0x00000003, spi_data_wait # wait for final frame -.4byte rx_data, 0x00000048, read32_test -.4byte rx_data, 0x00000037, read32_test -.4byte rx_data, 0x00000026, read32_test -.4byte rx_data, 0x00000015, read32_test #clear rx fifo - -# interlock in case where cs_mode = hold, intercs delay - -.4byte sck_mode, 0x00000000, write32_test # reset polarity -.4byte delay1, 0x00010001, write32_test # set intercs delay to 1 -.4byte rx_mark, 0x0000001, write32_test # preset rx watermark b/c of hardware interlock -.4byte tx_data, 0x51627384, spi_burst_send # place 4 frames into tx fifo -.4byte sck_mode, 0x00000002, write32_test # flip polarity (should change 2 second frame) -.4byte 0x0, 0x00000001, spi_data_wait # wait for second transmission to end -.4byte rx_mark, 0x0000003, write32_test # preset rx watermark b/c of hardware interlock -.4byte sck_mode, 0x00000000, write32_test # flip polarity again -.4byte 0x0, 0x00000003, spi_data_wait # wait for final frame -.4byte rx_data, 0x00000084, read32_test -.4byte rx_data, 0x00000073, read32_test -.4byte rx_data, 0x00000062, read32_test -.4byte rx_data, 0x00000051, read32_test #clear rx fifo - -# repeat previous set of tests with cs_mode = off - -.4byte cs_mode, 0x00000003, write32_test # set cs_mode to hold -.4byte rx_mark, 0x0000001, write32_test # preset rx watermark b/c of hardware interlock -.4byte tx_data, 0x13243546, spi_burst_send # place 4 frames into tx fifo -.4byte sck_mode, 0x00000002, write32_test # flip polarity (should change 2 second frame) -.4byte 0x0, 0x00000001, spi_data_wait # wait for second transmission to end -.4byte rx_mark, 0x0000003, write32_test # preset rx watermark b/c of hardware interlock -.4byte sck_mode, 0x00000000, write32_test # flip polarity again -.4byte 0x0, 0x00000003, spi_data_wait # wait for final frame -.4byte rx_data, 0x00000046, read32_test -.4byte rx_data, 0x00000035, read32_test -.4byte rx_data, 0x00000024, read32_test -.4byte rx_data, 0x00000013, read32_test #clear rx fifo - -# interlock in case where cs_mode = hold, intercs delay - -.4byte sck_mode, 0x00000000, write32_test # reset polarity -.4byte delay1, 0x00000000, write32_test # set intercs delay to 0 -.4byte rx_mark, 0x0000001, write32_test # preset rx watermark b/c of hardware interlock -.4byte tx_data, 0x31425364, spi_burst_send # place 4 frames into tx fifo -.4byte sck_mode, 0x00000002, write32_test # flip polarity (should change 2 second frame) -.4byte 0x0, 0x00000001, spi_data_wait # wait for second transmission to end -.4byte rx_mark, 0x0000003, write32_test # preset rx watermark b/c of hardware interlock -.4byte sck_mode, 0x00000000, write32_test # flip polarity again -.4byte 0x0, 0x00000003, spi_data_wait # wait for final frame -.4byte rx_data, 0x00000064, read32_test -.4byte rx_data, 0x00000053, read32_test -.4byte rx_data, 0x00000042, read32_test -.4byte rx_data, 0x00000031, read32_test #clear rx fifo - - - - - - - - - # =========== Test watermark interrupts =========== diff --git a/tests/wally-riscv-arch-test/riscv-test-suite/rv64i_m/privilege/references/WALLY-spi-01.reference_output b/tests/wally-riscv-arch-test/riscv-test-suite/rv64i_m/privilege/references/WALLY-spi-01.reference_output index 7520479ce..8d9ae8bbc 100644 --- a/tests/wally-riscv-arch-test/riscv-test-suite/rv64i_m/privilege/references/WALLY-spi-01.reference_output +++ b/tests/wally-riscv-arch-test/riscv-test-suite/rv64i_m/privilege/references/WALLY-spi-01.reference_output @@ -238,46 +238,6 @@ 00000000 0000001F 00000000 -00000062 # hardware interlock -00000000 -00000026 -00000000 -000000D2 -00000000 -0000002D -00000000 -00000048 -00000000 -00000037 -00000000 -00000026 -00000000 -00000015 -00000000 -00000084 -00000000 -00000073 -00000000 -00000062 -00000000 -00000051 -00000000 -00000046 -00000000 -00000035 -00000000 -00000024 -00000000 -00000013 -00000000 -00000064 -00000000 -00000053 -00000000 -00000042 -00000000 -00000031 -00000000 00000001 #watermark interrupts 00000000 00000000 #read mip 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 2a04f02f0..0f189b5e6 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 @@ -551,94 +551,6 @@ test_cases: #.8byte 0x0, 0x00000000, spi_data_wait # wait for transmission to end #.8byte rx_data, 0x000000F0, read32_test # read rx_data -#=========== Test Hardware Interlock ================ - -# interlock in base case - -.8byte fmt, 0x00080000, write32_test # reset fmt register -.8byte rx_mark, 0x0000001, write32_test # preset rx watermark b/c of hardware interlock -.8byte tx_data, 0x00000062, write32_test # initiate transmission -.8byte sck_mode, 0x00000002, write32_test # flip polarity during transmission -.8byte tx_data, 0x00000026, write32_test # transmit second frame w/ control register updated -.8byte 0x0, 0x00000001, spi_data_wait -.8byte rx_data, 0x00000062, read32_test -.8byte rx_data, 0x00000026, read32_test # clear rx fifo -.8byte sck_mode, 0x00000000, write32_test # reset polarity - -# interlock in case where cs_mode is auto, but there is minimal intercs delay - -.8byte delay0, 0x00000001, write32_test # set sck-cs delay to 0, with sck.pha 0 there is 0 delay -.8byte tx_data, 0x000000D2, write32_test # initiate transmission -.8byte sck_mode, 0x00000002, write32_test # flip sck polarity -.8byte tx_data, 0x0000002D, write32_test # transmit second frame -.8byte 0x0, 0x00000001, spi_data_wait -.8byte rx_data, 0x000000D2, read32_test -.8byte rx_data, 0x0000002D, read32_test # clear rx fifo -.8byte sck_mode, 0x00000000, write32_test # reset polarity - -# interlock in case where cs_mode = hold, 0 intercs delay -.8byte delay0, 0x00010001, write32_test # reset delay0 -.8byte sck_mode, 0x00000000, write32_test # reset polarity -.8byte cs_mode, 0x00000002, write32_test # set cs_mode to hold -.8byte tx_data, 0x15263748, spi_burst_send # place 4 frames into tx fifo -.8byte sck_mode, 0x00000002, write32_test # flip polarity (should change 2 second frame) -.8byte 0x0, 0x00000001, spi_data_wait # wait for second transmission to end -.8byte rx_mark, 0x0000003, write32_test # preset rx watermark b/c of hardware interlock -.8byte sck_mode, 0x00000000, write32_test # flip polarity again -.8byte 0x0, 0x00000003, spi_data_wait # wait for final frame -.8byte rx_data, 0x00000048, read32_test -.8byte rx_data, 0x00000037, read32_test -.8byte rx_data, 0x00000026, read32_test -.8byte rx_data, 0x00000015, read32_test #clear rx fifo - -# interlock in case where cs_mode = hold, intercs delay - -.8byte sck_mode, 0x00000000, write32_test # reset polarity -.8byte delay1, 0x00010001, write32_test # set intercs delay to 1 -.8byte rx_mark, 0x0000001, write32_test # preset rx watermark b/c of hardware interlock -.8byte tx_data, 0x51627384, spi_burst_send # place 4 frames into tx fifo -.8byte sck_mode, 0x00000002, write32_test # flip polarity (should change 2 second frame) -.8byte 0x0, 0x00000001, spi_data_wait # wait for second transmission to end -.8byte rx_mark, 0x0000003, write32_test # preset rx watermark b/c of hardware interlock -.8byte sck_mode, 0x00000000, write32_test # flip polarity again -.8byte 0x0, 0x00000003, spi_data_wait # wait for final frame -.8byte rx_data, 0x00000084, read32_test -.8byte rx_data, 0x00000073, read32_test -.8byte rx_data, 0x00000062, read32_test -.8byte rx_data, 0x00000051, read32_test #clear rx fifo - -# repeat previous set of tests with cs_mode = off - -.8byte cs_mode, 0x00000003, write32_test # set cs_mode to hold -.8byte rx_mark, 0x0000001, write32_test # preset rx watermark b/c of hardware interlock -.8byte tx_data, 0x13243546, spi_burst_send # place 4 frames into tx fifo -.8byte sck_mode, 0x00000002, write32_test # flip polarity (should change 2 second frame) -.8byte 0x0, 0x00000001, spi_data_wait # wait for second transmission to end -.8byte rx_mark, 0x0000003, write32_test # preset rx watermark b/c of hardware interlock -.8byte sck_mode, 0x00000000, write32_test # flip polarity again -.8byte 0x0, 0x00000003, spi_data_wait # wait for final frame -.8byte rx_data, 0x00000046, read32_test -.8byte rx_data, 0x00000035, read32_test -.8byte rx_data, 0x00000024, read32_test -.8byte rx_data, 0x00000013, read32_test #clear rx fifo - -# interlock in case where cs_mode = hold, intercs delay - -.8byte sck_mode, 0x00000000, write32_test # reset polarity -.8byte delay1, 0x00000000, write32_test # set intercs delay to 0 -.8byte rx_mark, 0x0000001, write32_test # preset rx watermark b/c of hardware interlock -.8byte tx_data, 0x31425364, spi_burst_send # place 4 frames into tx fifo -.8byte sck_mode, 0x00000002, write32_test # flip polarity (should change 2 second frame) -.8byte 0x0, 0x00000001, spi_data_wait # wait for second transmission to end -.8byte rx_mark, 0x0000003, write32_test # preset rx watermark b/c of hardware interlock -.8byte sck_mode, 0x00000000, write32_test # flip polarity again -.8byte 0x0, 0x00000003, spi_data_wait # wait for final frame -.8byte rx_data, 0x00000064, read32_test -.8byte rx_data, 0x00000053, read32_test -.8byte rx_data, 0x00000042, read32_test -.8byte rx_data, 0x00000031, read32_test #clear rx fifo - - From 3fda7ecb81a2179aeb385daa6fbe9db30ccf492a Mon Sep 17 00:00:00 2001 From: naichewa Date: Fri, 1 Nov 2024 13:09:41 -0700 Subject: [PATCH 22/30] Fix SPI regression tests --- .../riscv-test-suite/rv32i_m/privilege/src/WALLY-spi-01.S | 2 +- .../riscv-test-suite/rv64i_m/privilege/src/WALLY-spi-01.S | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) 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 a004a5ea0..94defaf87 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 @@ -553,7 +553,7 @@ test_cases: # Test transmit watermark interrupt (triggers when entries in tx FIFO < tx watermark) without external enables SETUP_PLIC - +.4byte fmt, 0x00080000, write32_test # reset format register .4byte delay1, 0x0000001, write32_test # reset delay1 register .4byte cs_mode, 0x00000000, write32_test # reset cs_mode .4byte tx_mark, 0x00000001, write32_test # set transmit watermark to 1 (any entry turns mark off) 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 0f189b5e6..23cfd169a 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 @@ -564,7 +564,7 @@ test_cases: # Test transmit watermark interrupt (triggers when entries in tx FIFO < tx watermark) without external enables SETUP_PLIC - +.8byte fmt, 0x00080000, write32_test # reset format register .8byte delay1, 0x0000001, write32_test # reset delay1 register .8byte cs_mode, 0x00000000, write32_test # reset cs_mode .8byte sck_div, 0x00000100, write32_test # lower SPI clock rate so reads are done at correct time when ICACHE not supported From e881bd31203a04a0c6e84b57dafd1461533a0b4f Mon Sep 17 00:00:00 2001 From: Jacob Pease Date: Fri, 1 Nov 2024 17:04:07 -0500 Subject: [PATCH 23/30] Changed the condition for TransmitStart fsm to avoid edge condition. --- src/uncore/spi_apb.sv | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/uncore/spi_apb.sv b/src/uncore/spi_apb.sv index 5d3352154..a15068f10 100644 --- a/src/uncore/spi_apb.sv +++ b/src/uncore/spi_apb.sv @@ -273,7 +273,7 @@ module spi_apb import cvw::*; #(parameter cvw_t P) ( READY: if (~TransmitFIFOReadEmpty & ~Transmitting) NextState = START; else NextState = READY; START: NextState = WAIT; - WAIT: if (TransmitFIFOReadEmpty & ~Transmitting & ~TransmitRegLoaded) NextState = READY; + WAIT: if (/*TransmitFIFOReadEmpty &*/ ~Transmitting & ~TransmitRegLoaded) NextState = READY; else NextState = WAIT; default: NextState = READY; endcase From c197d4a3c661b702f7be99ce0188836040fc134b Mon Sep 17 00:00:00 2001 From: Jacob Pease Date: Fri, 1 Nov 2024 17:35:55 -0500 Subject: [PATCH 24/30] Cleaned up some code. Still more work to do there. --- src/uncore/spi_apb.sv | 2 +- src/uncore/spi_controller.sv | 40 +++++++++++++++++++++--------------- 2 files changed, 25 insertions(+), 17 deletions(-) diff --git a/src/uncore/spi_apb.sv b/src/uncore/spi_apb.sv index a15068f10..e6bd34b6a 100644 --- a/src/uncore/spi_apb.sv +++ b/src/uncore/spi_apb.sv @@ -273,7 +273,7 @@ module spi_apb import cvw::*; #(parameter cvw_t P) ( READY: if (~TransmitFIFOReadEmpty & ~Transmitting) NextState = START; else NextState = READY; START: NextState = WAIT; - WAIT: if (/*TransmitFIFOReadEmpty &*/ ~Transmitting & ~TransmitRegLoaded) NextState = READY; + WAIT: if (~Transmitting & ~TransmitRegLoaded) NextState = READY; else NextState = WAIT; default: NextState = READY; endcase diff --git a/src/uncore/spi_controller.sv b/src/uncore/spi_controller.sv index 576884374..9e7bd6aeb 100644 --- a/src/uncore/spi_controller.sv +++ b/src/uncore/spi_controller.sv @@ -80,6 +80,9 @@ module spi_controller ( logic PreSampleEdge; // logic ShiftEdge; // logic SampleEdge; + logic ShiftEdgePulse; + logic SampleEdgePulse; + logic EndOfFramePulse; // Frame stuff logic [3:0] BitNum; @@ -220,6 +223,7 @@ module spi_controller ( // EndOfFrame <= 1'b0; // end + // TODO: Rename EndOfFrameDelay to EndOfFrame and remove this logic if (~TransmitStart) begin EndOfFrame <= (SckMode[1] ^ SckMode[0] ^ SPICLK) & SCLKenable & LastBit & Transmitting; end @@ -236,35 +240,39 @@ module spi_controller ( // Delay ShiftEdge and SampleEdge by a half PCLK period // Aligned EXACTLY ON THE MIDDLE of the leading and trailing edges. // Sweeeeeeeeeet... + + assign ShiftEdgePulse = SCLKenable & ~LastBit & Transmitting; + assign SampleEdgePulse = SCLKenable & Transmitting & ~DelayIsNext; + assign EndOfFramePulse = SCLKenable & LastBit & Transmitting; + always_ff @(posedge ~PCLK) begin if (~PRESETn | TransmitStart) begin ShiftEdge <= 0; PhaseOneOffset <= 0; SampleEdge <= 0; EndOfFrameDelay <= 0; - end else begin - case(SckMode) + end else begin + PhaseOneOffset <= (PhaseOneOffset == 0) ? Transmitting & SCLKenable : ~EndOfFrameDelay; + case(SckMode) 2'b00: begin - ShiftEdge <= SPICLK & SCLKenable & ~LastBit & Transmitting; - SampleEdge <= ~SPICLK & SCLKenable & Transmitting & ~DelayIsNext; - EndOfFrameDelay <= SPICLK & SCLKenable & LastBit & Transmitting; + ShiftEdge <= SPICLK & ShiftEdgePulse; + SampleEdge <= ~SPICLK & SampleEdgePulse; + EndOfFrameDelay <= SPICLK & EndOfFramePulse; end 2'b01: begin - ShiftEdge <= ~SPICLK & SCLKenable & ~LastBit & Transmitting & PhaseOneOffset; - SampleEdge <= SPICLK & SCLKenable & Transmitting & ~DelayIsNext; - EndOfFrameDelay <= ~SPICLK & SCLKenable & LastBit & Transmitting; - PhaseOneOffset <= (PhaseOneOffset == 0) ? Transmitting & SCLKenable : ~EndOfFrameDelay; + ShiftEdge <= ~SPICLK & ShiftEdgePulse & PhaseOneOffset; + SampleEdge <= SPICLK & SampleEdgePulse; + EndOfFrameDelay <= ~SPICLK & EndOfFramePulse; end 2'b10: begin - ShiftEdge <= ~SPICLK & SCLKenable & ~LastBit & Transmitting; - SampleEdge <= SPICLK & SCLKenable & Transmitting & ~DelayIsNext; - EndOfFrameDelay <= ~SPICLK & SCLKenable & LastBit & Transmitting; + ShiftEdge <= ~SPICLK & ShiftEdgePulse; + SampleEdge <= SPICLK & SampleEdgePulse; + EndOfFrameDelay <= ~SPICLK & EndOfFramePulse; end 2'b11: begin - ShiftEdge <= SPICLK & SCLKenable & ~LastBit & Transmitting & PhaseOneOffset; - SampleEdge <= ~SPICLK & SCLKenable & Transmitting & ~DelayIsNext; - EndOfFrameDelay <= SPICLK & SCLKenable & LastBit & Transmitting; - PhaseOneOffset <= (PhaseOneOffset == 0) ? Transmitting & SCLKenable : ~EndOfFrameDelay; + ShiftEdge <= SPICLK & ShiftEdgePulse & PhaseOneOffset; + SampleEdge <= ~SPICLK & SampleEdgePulse; + EndOfFrameDelay <= SPICLK & EndOfFramePulse; end // ShiftEdge <= ((SckMode[1] ^ SckMode[0] ^ SPICLK) & SCLKenable & ~LastBit & Transmitting) & PhaseOneOffset; // PhaseOneOffset <= PhaseOneOffset == 0 ? Transmitting & SCLKenable : ~EndOfFrameDelay; From 2a8e213f209d7bd280f9622c1fa53c4489e9cec1 Mon Sep 17 00:00:00 2001 From: Jacob Pease Date: Sat, 2 Nov 2024 12:33:27 -0500 Subject: [PATCH 25/30] Wrote a script that can take hexadecimal bytes from a file and write them to an output file and an sd card. --- linux/sdcard/write-bytes.sh | 43 +++++++++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) create mode 100755 linux/sdcard/write-bytes.sh diff --git a/linux/sdcard/write-bytes.sh b/linux/sdcard/write-bytes.sh new file mode 100755 index 000000000..ba847e876 --- /dev/null +++ b/linux/sdcard/write-bytes.sh @@ -0,0 +1,43 @@ +#!/bin/bash + +# This file writes a bunch of bytes to the flash card based on a text +# file input with bytes written in hexadecimal. + +INPUTFILE="" +OUTPUTFILE="" + +ARGS=() +while [ $OPTIND -le "$#" ] ; do + if getopts "hi:o:" arg ; then + case "${arg}" in + h) help + ;; + i) INPUTFILE=${OPTARG} + ;; + o) OUTPUTFILE=${OPTARG} + ;; + esac + else + ARGS+=("${!OPTIND}") + ((OPTIND++)) + fi +done + +SDCARD=${ARGS[0]} + +if [ ! -e $INPUTFILE ] ; then + echo -e "Error: Input file $INPUTFILE does not exist." + exit 1 +fi + +if [ -e $OUTPUTFILE ] ; then + echo -e "Error: Output file $OUTPUTFILE already exists." + exit 1 +fi + +for word in $(cat "$INPUTFILE") +do + echo -en "\x$word" >> $OUTPUTFILE +done + +dd if=$OUTPUTFILE of="$SDCARD" From e33c2f7a8ca03e48d93177dd561dc6563f0be414 Mon Sep 17 00:00:00 2001 From: Jacob Pease Date: Sat, 2 Nov 2024 12:36:45 -0500 Subject: [PATCH 26/30] Added usage and help functions to write-bytes.sh --- linux/sdcard/write-bytes.sh | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/linux/sdcard/write-bytes.sh b/linux/sdcard/write-bytes.sh index ba847e876..83a8481e5 100755 --- a/linux/sdcard/write-bytes.sh +++ b/linux/sdcard/write-bytes.sh @@ -3,6 +3,15 @@ # This file writes a bunch of bytes to the flash card based on a text # file input with bytes written in hexadecimal. +usage() { echo "Usage: $0 [-zh] [-b ] " 1>&2; exit 1; } + +help() { + echo "Usage: $0 [OPTIONS] " + echo " -i Input text file with hex bytes." + echo " -b Output binary file." + exit 0; +} + INPUTFILE="" OUTPUTFILE="" From 9c3937165743200a9bc560ca455fa0adf2dfb0cb Mon Sep 17 00:00:00 2001 From: Jacob Pease Date: Sat, 2 Nov 2024 14:14:31 -0500 Subject: [PATCH 27/30] Reverted bootloader optimizations to second iteration. Working on last optimization. --- fpga/zsbl/boot.c | 74 ++++++++++++++++++++++++------------------------ 1 file changed, 37 insertions(+), 37 deletions(-) diff --git a/fpga/zsbl/boot.c b/fpga/zsbl/boot.c index d9a824a49..7665b2df2 100644 --- a/fpga/zsbl/boot.c +++ b/fpga/zsbl/boot.c @@ -135,45 +135,45 @@ int disk_read(BYTE * buf, LBA_t sector, UINT count) { /* crc = crc16(crc, x); */ /* } while (--n > 0); */ - /* n = 512/8; */ - /* do { */ - /* // Send 8 dummy bytes (fifo should be empty) */ - /* for (j = 0; j < 8; j++) { */ - /* spi_sendbyte(0xff); */ - /* } */ - - /* // Reset counter. Process bytes AS THEY COME IN. */ - /* for (j = 0; j < 8; j++) { */ - /* while (!(read_reg(SPI_IP) & 2)) {} */ - /* uint8_t x = spi_readbyte(); */ - /* *p++ = x; */ - /* // crc = crc16(crc, x); */ - /* crc = ((crc << 8) ^ crctable[x ^ (crc >> 8)]) & 0xffff; */ - /* } */ - /* } while(--n > 0); */ - - n = 512; - // Initially fill the transmit fifo - for (j = 0; j < 8; j++) { - spi_sendbyte(0xff); - } - - - while (n > 0) { - // Wait for bytes to be received - while (!(read_reg(SPI_IP) & 2)) {} - // Read byte - uint8_t x = spi_readbyte(); - // Send another dummy byte - if (n > 8) { + n = 512/8; + do { + // Send 8 dummy bytes (fifo should be empty) + for (j = 0; j < 8; j++) { spi_sendbyte(0xff); } - // Place received byte into memory - *p++ = x; - // Update CRC16 with fast table based method - crc = ((crc << 8) ^ crctable[x ^ (crc >> 8)]) & 0xffff; - n = n - 1; - } + + // Reset counter. Process bytes AS THEY COME IN. + for (j = 0; j < 8; j++) { + while (!(read_reg(SPI_IP) & 2)) {} + uint8_t x = spi_readbyte(); + *p++ = x; + // crc = crc16(crc, x); + crc = ((crc << 8) ^ crctable[x ^ (crc >> 8)]) & 0xffff; + } + } while(--n > 0); + + /* n = 512; */ + /* // Initially fill the transmit fifo */ + /* for (j = 0; j < 8; j++) { */ + /* spi_sendbyte(0xff); */ + /* } */ + + + /* while (n > 0) { */ + /* // Wait for bytes to be received */ + /* while (!(read_reg(SPI_IP) & 2)) {} */ + /* // Read byte */ + /* uint8_t x = spi_readbyte(); */ + /* // Send another dummy byte */ + /* if (n > 8) { */ + /* spi_sendbyte(0xff); */ + /* } */ + /* // Place received byte into memory */ + /* *p++ = x; */ + /* // Update CRC16 with fast table based method */ + /* crc = ((crc << 8) ^ crctable[x ^ (crc >> 8)]) & 0xffff; */ + /* n = n - 1; */ + /* } */ // Read CRC16 and check crc_exp = ((uint16_t)spi_dummy() << 8); From 674d008f23a40445be7f6ffee9405337772c3a78 Mon Sep 17 00:00:00 2001 From: Jacob Pease Date: Sat, 2 Nov 2024 14:31:05 -0500 Subject: [PATCH 28/30] Added headers to files. --- linux/sdcard/flash-sd.sh | 26 ++++++++++++++++++++++++++ linux/sdcard/write-bytes.sh | 28 ++++++++++++++++++++++++++++ src/uncore/spi_apb.sv | 6 ++++-- src/uncore/spi_controller.sv | 5 ++--- 4 files changed, 60 insertions(+), 5 deletions(-) diff --git a/linux/sdcard/flash-sd.sh b/linux/sdcard/flash-sd.sh index 7a2c58d42..31e6ee45f 100755 --- a/linux/sdcard/flash-sd.sh +++ b/linux/sdcard/flash-sd.sh @@ -1,4 +1,30 @@ #!/bin/bash +########################################### +## flash-sd.sh +## +## Written: Jacob Pease jacobpease@protonmail.com +## Created: August 22, 2023 +## +## Purpose: A script to flash an sd card with a bootable linux image. +## +## A component of the CORE-V-WALLY configurable RISC-V project. +## https://github.com/openhwgroup/cvw +## +## Copyright (C) 2021-24 Harvey Mudd College & Oklahoma State University +## +## SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1 +## +## Licensed under the Solderpad Hardware License v 2.1 (the “License”); you may not use this file +## except in compliance with the License, or, at your option, the Apache License version 2.0. You +## may obtain a copy of the License at +## +## https:##solderpad.org/licenses/SHL-2.1/ +## +## Unless required by applicable law or agreed to in writing, any work distributed under the +## License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, +## either express or implied. See the License for the specific language governing permissions +## and limitations under the License. +################################################################################################ # Exit on any error (return code != 0) # set -e diff --git a/linux/sdcard/write-bytes.sh b/linux/sdcard/write-bytes.sh index 83a8481e5..b9c312ceb 100755 --- a/linux/sdcard/write-bytes.sh +++ b/linux/sdcard/write-bytes.sh @@ -1,4 +1,32 @@ #!/bin/bash +########################################### +## write-bytes.sh +## +## Written: Jacob Pease jacobpease@protonmail.com +## Created: November 2nd, 2024 +## Modified: +## +## Purpose: Write a sequence of bytes from text file to an output file and a flash card. +## +## A component of the CORE-V-WALLY configurable RISC-V project. +## https://github.com/openhwgroup/cvw +## +## Copyright (C) 2021-24 Harvey Mudd College & Oklahoma State University +## +## SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1 +## +## Licensed under the Solderpad Hardware License v 2.1 (the “License”); you may not use this file +## except in compliance with the License, or, at your option, the Apache License version 2.0. You +## may obtain a copy of the License at +## +## https:##solderpad.org/licenses/SHL-2.1/ +## +## Unless required by applicable law or agreed to in writing, any work distributed under the +## License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, +## either express or implied. See the License for the specific language governing permissions +## and limitations under the License. +################################################################################################ + # This file writes a bunch of bytes to the flash card based on a text # file input with bytes written in hexadecimal. diff --git a/src/uncore/spi_apb.sv b/src/uncore/spi_apb.sv index e6bd34b6a..293c2c2b5 100644 --- a/src/uncore/spi_apb.sv +++ b/src/uncore/spi_apb.sv @@ -1,7 +1,9 @@ /////////////////////////////////////////// // spi_apb.sv // -// Written: Naiche Whyte-Aguayo nwhyteaguayo@g.hmc.edu 11/16/2022 +// Written: Naiche Whyte-Aguayo nwhyteaguayo@g.hmc.edu +// Jacob Pease jacobpease@protonmail.com (October 29th, 2024) +// Created: November 16th, 2022 // // Purpose: SPI peripheral // @@ -13,7 +15,7 @@ // // A component of the Wally configurable RISC-V project. // -// Copyright (C) 2021-23 Harvey Mudd College & Oklahoma State University +// Copyright (C) 2021-24 Harvey Mudd College & Oklahoma State University // // SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1 // diff --git a/src/uncore/spi_controller.sv b/src/uncore/spi_controller.sv index 9e7bd6aeb..19b32cab3 100644 --- a/src/uncore/spi_controller.sv +++ b/src/uncore/spi_controller.sv @@ -1,9 +1,8 @@ /////////////////////////////////////////// // spi_controller.sv // -// Written: jacobpease@protonmail.com +// Written: Jacob Pease jacobpease@protonmail.com // Created: October 28th, 2024 -// Modified: // // Purpose: Controller logic for SPI // @@ -12,7 +11,7 @@ // A component of the CORE-V-WALLY configurable RISC-V project. // https://github.com/openhwgroup/cvw // -// Copyright (C) 2021-23 Harvey Mudd College & Oklahoma State University +// Copyright (C) 2021-24 Harvey Mudd College & Oklahoma State University // // SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1 // From c64c6c4cf1e7e183636f05da4640bdee25dba2e8 Mon Sep 17 00:00:00 2001 From: Jordan Carlin Date: Sat, 2 Nov 2024 16:09:14 -0700 Subject: [PATCH 29/30] Fix reverted submodules --- .gitmodules | 3 ++- addins/cvw-arch-verif | 2 +- addins/riscv-arch-test | 2 +- 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/.gitmodules b/.gitmodules index eed0bb58f..34a374174 100644 --- a/.gitmodules +++ b/.gitmodules @@ -25,9 +25,10 @@ sparseCheckout = true path = addins/verilog-ethernet url = https://github.com/rosethompson/verilog-ethernet.git -[submodule "cvw-arch-verif"] +[submodule "addins/cvw-arch-verif"] path = addins/cvw-arch-verif url = https://github.com/openhwgroup/cvw-arch-verif + ignore = dirty [submodule "addins/riscvISACOV"] path = addins/riscvISACOV url = https://github.com/riscv-verification/riscvISACOV.git diff --git a/addins/cvw-arch-verif b/addins/cvw-arch-verif index 189974e49..6d658b7b4 160000 --- a/addins/cvw-arch-verif +++ b/addins/cvw-arch-verif @@ -1 +1 @@ -Subproject commit 189974e497d7b8d2c08bb1d151b1ccdeaf3a64c9 +Subproject commit 6d658b7b42c83fd584008d72964cc75d0876b769 diff --git a/addins/riscv-arch-test b/addins/riscv-arch-test index 7152865ac..3843c736e 160000 --- a/addins/riscv-arch-test +++ b/addins/riscv-arch-test @@ -1 +1 @@ -Subproject commit 7152865aca51062c87ff2cbb014e199a24bdc874 +Subproject commit 3843c736e427a2b52a0d06e6220b073afa4be401 From 0c6e9dc770ba7787895e977da55005276a89a09f Mon Sep 17 00:00:00 2001 From: Corey Hickson Date: Sun, 3 Nov 2024 14:21:55 -0800 Subject: [PATCH 30/30] Fixed rmm rounding mode bug --- src/fpu/fround.sv | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/fpu/fround.sv b/src/fpu/fround.sv index 6c37d2973..b5c1b975e 100644 --- a/src/fpu/fround.sv +++ b/src/fpu/fround.sv @@ -126,7 +126,7 @@ module fround import cvw::*; #(parameter cvw_t P) ( 3'b001: RoundUp = 0; // RZ 3'b010: RoundUp = Xs & (Rp | Tp); // RN 3'b011: RoundUp = ~Xs & (Rp | Tp); // RP - 3'b101: RoundUp = Rp; // RNTA + 3'b100: RoundUp = Rp; // RNTA default: RoundUp = 0; // should never happen endcase