Refactored SPI passes regression save for hardware interlock tests.

This commit is contained in:
Jacob Pease 2024-10-31 13:01:25 -05:00
parent 419030bc33
commit 72a854eb07
2 changed files with 58 additions and 16 deletions

View File

@ -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

View File

@ -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