mirror of
				https://github.com/openhwgroup/cvw
				synced 2025-02-11 06:05:49 +00:00 
			
		
		
		
	More SPI optimizations.
This commit is contained in:
		
							parent
							
								
									745e53adf7
								
							
						
					
					
						commit
						120b21d7d5
					
				| @ -48,7 +48,7 @@ module spi_apb import cvw::*; #(parameter cvw_t P) ( | ||||
|   output logic                SPICLK | ||||
| ); | ||||
| 
 | ||||
|     // register map
 | ||||
|   // register map
 | ||||
|   localparam SPI_SCKDIV =  8'h00; | ||||
|   localparam SPI_SCKMODE = 8'h04; | ||||
|   localparam SPI_CSID =    8'h10; | ||||
| @ -89,7 +89,7 @@ module spi_apb import cvw::*; #(parameter cvw_t P) ( | ||||
|   logic        InactiveState; | ||||
|   logic [3:0]  FrameLength;   | ||||
| 
 | ||||
|   // 
 | ||||
|   // Starting Transmission and restarting SCLKenable
 | ||||
|   logic        ResetSCLKenable; | ||||
|   logic        TransmitStart; | ||||
|   logic        TransmitStartD; | ||||
| @ -98,15 +98,16 @@ module spi_apb import cvw::*; #(parameter cvw_t P) ( | ||||
|   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, ReceiveWriteMark, ReceiveReadMark;  | ||||
|   // FIFO Watermark signals - TransmitReadMark = ip[0], ReceiveWriteMark = ip[1]
 | ||||
|   logic        TransmitWriteMark, TransmitReadMark, ReceiveWriteMark, ReceiveReadMark; | ||||
| 
 | ||||
|   // Transmit FIFO Signals
 | ||||
|   logic        TransmitFIFOFull, TransmitFIFOEmpty; | ||||
|   logic        TransmitFIFOWriteInc; | ||||
|   logic        TransmitFIFOReadInc;                // Increments Tx FIFO read ptr 1 cycle after Tx FIFO is read
 | ||||
|   logic [7:0]  TransmitReadData; | ||||
| 
 | ||||
|   // 
 | ||||
|   // ReceiveFIFO Signals
 | ||||
|   logic        ReceiveFIFOWriteInc; | ||||
|   logic        ReceiveFIFOReadInc; | ||||
|   logic        ReceiveFIFOFull, ReceiveFIFOEmpty; | ||||
| @ -137,7 +138,6 @@ module spi_apb import cvw::*; #(parameter cvw_t P) ( | ||||
|   // 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
 | ||||
| @ -164,7 +164,7 @@ module spi_apb import cvw::*; #(parameter cvw_t P) ( | ||||
|       InterruptEnable <= 2'b0; | ||||
|       InterruptPending <= 2'b0; | ||||
|     end else begin // writes
 | ||||
|             /* verilator lint_off CASEINCOMPLETE */ | ||||
|       /* verilator lint_off CASEINCOMPLETE */ | ||||
|       if (Memwrite) | ||||
|         case(Entry) // flop to sample inputs
 | ||||
|           SPI_SCKDIV:  SckDiv <= Din[11:0]; | ||||
| @ -217,7 +217,7 @@ module spi_apb import cvw::*; #(parameter cvw_t P) ( | ||||
|    | ||||
|   spi_controller controller(PCLK, PRESETn, | ||||
|                             // Transmit Signals
 | ||||
|                             TransmitStart, TransmitStartD, ResetSCLKenable, | ||||
|                             TransmitStart, TransmitRegLoaded, ResetSCLKenable, | ||||
|                             // Register Inputs
 | ||||
|                             SckDiv, SckMode, ChipSelectMode, Delay0, Delay1, FrameLength, | ||||
|                             // txFIFO stuff
 | ||||
| @ -230,23 +230,17 @@ module spi_apb import cvw::*; #(parameter cvw_t P) ( | ||||
|                             SPICLK); | ||||
|    | ||||
|   // Transmit FIFO ---------------------------------------------------
 | ||||
|    | ||||
| 
 | ||||
|   // txFIFO write increment logic
 | ||||
|   always_ff @(posedge PCLK) | ||||
|     if (~PRESETn) begin | ||||
|       TransmitFIFOWriteInc <= 1'b0; | ||||
|     end else begin | ||||
|       TransmitFIFOWriteInc <= (Memwrite & (Entry == SPI_TXDATA) & ~TransmitFIFOFull); | ||||
|     end | ||||
|   flopr #(1) txwincreg(PCLK, ~PRESETn, | ||||
|                        (Memwrite & (Entry == SPI_TXDATA) & ~TransmitFIFOFull), | ||||
|                        TransmitFIFOWriteInc); | ||||
| 
 | ||||
|   // txFIFO read increment logic
 | ||||
|   always_ff @(posedge PCLK) | ||||
|     if (~PRESETn) begin | ||||
|       TransmitFIFOReadInc <= 1'b0; | ||||
|     end else if (SCLKenable) begin | ||||
|       TransmitFIFOReadInc <= TransmitStartD | (EndOfFrame & ~TransmitFIFOEmpty) ; | ||||
|   end | ||||
| 
 | ||||
|   flopenr #(1) txrincreg(PCLK, ~PRESETn, SCLKenable, | ||||
|                          TransmitStartD | (EndOfFrame & ~TransmitFIFOEmpty),                   | ||||
|                          TransmitFIFOReadInc); | ||||
|    | ||||
|   // Check whether TransmitReg has been loaded.
 | ||||
|   // We use this signal to prevent returning to the Ready state for TransmitStart
 | ||||
|   always_ff @(posedge PCLK) begin | ||||
| @ -258,15 +252,11 @@ module spi_apb import cvw::*; #(parameter cvw_t P) ( | ||||
|       TransmitRegLoaded <= 1'b0;   | ||||
|     end | ||||
|   end | ||||
| 
 | ||||
|    | ||||
|   // Setup TransmitStart state machine
 | ||||
|   always_ff @(posedge PCLK) begin | ||||
|     if (~PRESETn) begin | ||||
|       CurrState <= READY; | ||||
|     end else begin | ||||
|       CurrState <= NextState; | ||||
|     end | ||||
|   end | ||||
|   always_ff @(posedge PCLK) | ||||
|     if (~PRESETn) CurrState <= READY; | ||||
|     else          CurrState <= NextState; | ||||
|    | ||||
|   // State machine for starting transmissions
 | ||||
|   always_comb begin | ||||
| @ -280,12 +270,14 @@ module spi_apb import cvw::*; #(parameter cvw_t P) ( | ||||
|     endcase | ||||
|   end | ||||
| 
 | ||||
|   // Delayed TransmitStart signal for incrementing tx read point.
 | ||||
|   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; | ||||
|    | ||||
| 
 | ||||
|   // Transmit FIFO
 | ||||
|   spi_fifo #(3,8) txFIFO(PCLK, 1'b1, SCLKenable, PRESETn, | ||||
|                          TransmitFIFOWriteInc, TransmitFIFOReadInc, | ||||
|                          TransmitData[7:0], | ||||
| @ -296,20 +288,17 @@ module spi_apb import cvw::*; #(parameter cvw_t P) ( | ||||
|                          TransmitWriteMark, TransmitReadMark); | ||||
| 
 | ||||
|   // Receive FIFO ----------------------------------------------------
 | ||||
|   always_ff @(posedge PCLK) | ||||
|     if (~PRESETn) begin | ||||
|       ReceiveFIFOReadInc <= 1'b0; | ||||
|     end else begin | ||||
|       ReceiveFIFOReadInc <= ((Entry == SPI_RXDATA) & ~ReceiveFIFOEmpty & PSEL & ~ReceiveFIFOReadInc); | ||||
|     end | ||||
| 
 | ||||
|   always_ff @(posedge PCLK) | ||||
|     if (~PRESETn) begin | ||||
|       ReceiveFIFOWriteInc <= 1'b0; | ||||
|     end else if (SCLKenable) begin | ||||
|       ReceiveFIFOWriteInc <= EndOfFrame; | ||||
|     end | ||||
|    | ||||
|   // Receive FIFO Read Increment register
 | ||||
|   flopr #(1) rxfiforincreg(PCLK, ~PRESETn, | ||||
|                            ((Entry == SPI_RXDATA) & ~ReceiveFIFOEmpty & PSEL & ~ReceiveFIFOReadInc), | ||||
|                            ReceiveFIFOReadInc); | ||||
| 
 | ||||
|   // Receive FIFO Write Increment register
 | ||||
|   flopenr #(1) rxfifowincreg(PCLK, ~PRESETn, SCLKenable, | ||||
|                              EndOfFrame, ReceiveFIFOWriteInc); | ||||
| 
 | ||||
|   // Receive FIFO
 | ||||
|   spi_fifo #(3,8) rxFIFO(PCLK, SCLKenable, 1'b1, PRESETn, | ||||
|                          ReceiveFIFOWriteInc, ReceiveFIFOReadInc, | ||||
|                          ReceiveShiftRegEndian, ReceiveWatermark[2:0], | ||||
| @ -319,6 +308,7 @@ module spi_apb import cvw::*; #(parameter cvw_t P) ( | ||||
|                          ReceiveFIFOEmpty, | ||||
|                          ReceiveWriteMark, ReceiveReadMark); | ||||
| 
 | ||||
|   // Shift Registers --------------------------------------------------
 | ||||
|   // Transmit shift register
 | ||||
|   assign TransmitLoad = TransmitStart | (EndOfFrame & ~TransmitFIFOEmpty); | ||||
|   assign TransmitDataEndian = Format[0] ? {<<{TransmitReadData[7:0]}} : TransmitReadData[7:0]; | ||||
| @ -340,12 +330,11 @@ module spi_apb import cvw::*; #(parameter cvw_t P) ( | ||||
|     if(~PRESETn) begin | ||||
|       ReceiveShiftReg <= 8'b0; | ||||
|     end else if (SampleEdge) begin | ||||
|       if (~Transmitting) ReceiveShiftReg <= 8'b0; | ||||
|       else               ReceiveShiftReg <= {ReceiveShiftReg[6:0], ShiftIn}; | ||||
|       ReceiveShiftReg <= {ReceiveShiftReg[6:0], ShiftIn}; | ||||
|     end | ||||
| 
 | ||||
|   // Aligns received data and reverses if little-endian
 | ||||
|   assign LeftShiftAmount = 4'h8 - Format[4:1]; | ||||
|   assign LeftShiftAmount = 4'h8 - FrameLength; | ||||
|   assign ASR = ReceiveShiftReg << LeftShiftAmount[2:0]; | ||||
|   assign ReceiveShiftRegEndian = Format[0] ? {<<{ASR[7:0]}} : ASR[7:0]; | ||||
| 
 | ||||
|  | ||||
| @ -33,7 +33,7 @@ module spi_controller ( | ||||
| 
 | ||||
|   // Start Transmission
 | ||||
|   input logic        TransmitStart, | ||||
|   input logic        TransmitStartD, | ||||
|   input logic        TransmitRegLoaded, | ||||
|   input logic        ResetSCLKenable,  | ||||
| 
 | ||||
|   // Registers
 | ||||
| @ -84,7 +84,7 @@ module spi_controller ( | ||||
|   // Transmit Stuff
 | ||||
|   logic       ContinueTransmit;        | ||||
|   logic       EndTransmission; | ||||
|   logic       ContinueTransmitD; // TODO: Could be replaced by TransmitRegLoaded?
 | ||||
|   // logic       TransmitRegLoaded; // TODO: Could be replaced by TransmitRegLoaded?
 | ||||
|   logic       NextEndDelay; | ||||
|   logic       CurrentEndDelay; | ||||
| 
 | ||||
| @ -151,8 +151,7 @@ module spi_controller ( | ||||
|       BitNum <= 4'h0; | ||||
|       DelayCounter <= 0; | ||||
|     end else begin | ||||
|       // TODO: Consolidate into one delay counter since none of the
 | ||||
|       // delays happen at the same time?
 | ||||
|       // SCK logic for delay times  
 | ||||
|       if (TransmitStart) begin | ||||
|         SCK <= 0; | ||||
|       end else if (SCLKenable) begin | ||||
| @ -242,17 +241,6 @@ module spi_controller ( | ||||
|   // Logic for continuing to transmit through Delay states after end of frame
 | ||||
|   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 | ||||
| @ -264,7 +252,7 @@ module spi_controller ( | ||||
|    | ||||
|   always_comb begin | ||||
|     case (CurrState)   | ||||
|       INACTIVE: if (TransmitStartD) begin | ||||
|       INACTIVE: if (TransmitRegLoaded) begin | ||||
|                   if (~HasCSSCK) NextState = TRANSMIT; | ||||
|                   else NextState = CSSCK; | ||||
|                 end else begin | ||||
| @ -294,7 +282,7 @@ module spi_controller ( | ||||
|       end | ||||
|       SCKCS: begin // SCKCS case --------------------------------------
 | ||||
|         if (EndOfSCKCS) begin | ||||
|           if (~ContinueTransmitD) begin | ||||
|           if (~TransmitRegLoaded) begin | ||||
|             // if (CSMode == AUTOMODE) NextState = INACTIVE;
 | ||||
|             if (CSMode == HOLDMODE) NextState = HOLD; | ||||
|             else NextState = INACTIVE; | ||||
| @ -309,7 +297,7 @@ module spi_controller ( | ||||
|       HOLD: begin // HOLD mode case -----------------------------------
 | ||||
|         if (CSMode == AUTOMODE) begin | ||||
|           NextState = INACTIVE; | ||||
|         end else if (TransmitStartD) begin // If FIFO is written to, start again.
 | ||||
|         end else if (TransmitRegLoaded) begin // If FIFO is written to, start again.
 | ||||
|           NextState = TRANSMIT; | ||||
|         end else NextState = HOLD; | ||||
|       end | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user