////////////////////////////////////////////////////////////////////////////////// // Company: TAIR // Engineer: // // Create Date: 10/30/2023 11:24:31 AM // Design Name: // Module Name: SpiSubSystem // Project Name: S5443_V3_FPGA3 // Target Devices: BOARD: BY5443v3. FPGA: xc7s25csga225-2 // Tool Versions: // Description: This is wrapper that encapsulates FIFO's, Spi modules and // modules that multiplex Spi output lines // // Dependencies: // // Revision: // Revision 1.0 - File Created // Additional Comments: // ////////////////////////////////////////////////////////////////////////////////// module SpiSubSystem #( parameter STAGES = 3, parameter AXI_DATA_WIDTH = 64, parameter CMD_REG_WIDTH = 32, parameter ADDR_REG_WIDTH = 12, parameter WIDTH = 1, parameter ISTEMPRD = 1, parameter ISPOWERRST = 1, parameter [AXI_DATA_WIDTH-1:0] SPI_BASE_ADDR = 64'h1000, parameter [AXI_DATA_WIDTH-1:0] RST_MEM_BASE_ADDR = 64'h9000, parameter [AXI_DATA_WIDTH-1:0] TMPRD_ADDR = 64'h9001 ) ( input Clk_i, input SpiClk_i, input Rst_i, input [CMD_REG_WIDTH-1:0] WrData_i, input [CMD_REG_WIDTH-1:0] WrAddr_i, input [CMD_REG_WIDTH-1:0] RdAddr_i, input Val_i, input PowRstEn_i, input TxEn_i, output [CMD_REG_WIDTH-1:0] RdData_o, output Sck_o, output Ss_o, output SsFlash_o, output Mosi0_o, inout Mosi1_io, output Mosi2_o, output Mosi3_o ); //================================================================================ // REG/WIRE //================================================================================ wire [CMD_REG_WIDTH-1:0] toSpiData; wire [CMD_REG_WIDTH-1:0] toSpiDataR; wire emptyFlagTx; wire sckR; wire ssR; wire mosi0R; wire valToTxR; wire valToRxR; wire sckQ; wire ssQ; wire mosi0Q; wire valToTxQ; wire valToTxFifoRead; wire valToRxFifoWrite; wire [CMD_REG_WIDTH-1:0] dataToRxFifo; wire [31:0] tempData; reg [31:0] tempDataReg; wire [31:0] powRstData; wire mosi1_o; /* Spi settings arrays */ wire [AXI_DATA_WIDTH - 1 : 0] spiCtrlArray; wire [AXI_DATA_WIDTH - 1 : 0] spiClkArray; wire [AXI_DATA_WIDTH - 1 : 0] spiCsDelayArray; wire [AXI_DATA_WIDTH - 1 : 0] spiCsCtrlArray; wire [AXI_DATA_WIDTH - 1 : 0] spiTxRxFifoCtrlArray; /* Common Regs */ wire [AXI_DATA_WIDTH-1:0] spiTxRxEnReg; wire [AXI_DATA_WIDTH-1:0] dataFromRegMap; /* Synced Regs */ wire [AXI_DATA_WIDTH-1:0] spiCtrlRR; wire [AXI_DATA_WIDTH-1:0] spiCsDelayRR; wire [AXI_DATA_WIDTH-1:0] spiCsCtrlRR; wire [AXI_DATA_WIDTH-1:0] spiTxRxFifoCtrlRR; /* SpiSettings */ wire [1:0] widthSel; wire spiEn; wire spiMode; wire clockPol; wire clockPhase; wire endianSel; wire selSt; wire assel; wire [5:0] stopDelay; wire lead; wire lag; wire fifoTxRst; wire fifoRxRst; wire txEn; wire chipSelFpga; wire chipSelFlash; wire fifoRxRstRdPtr; wire fifoTxRstWrPtr; wire [CMD_REG_WIDTH-1:0] dataFromRxFifo; //================================================================================ // ASSIGNMENTS //================================================================================ assign valToTxFifoRead = (spiMode) ? valToTxQ : valToTxR; assign Mosi1_io = (spiMode) ? mosi1_o : 1'bz; assign TempData_o = tempData; assign fifoRxRstRdPtr = spiTxRxFifoCtrlArray[32]; assign fifoTxRstWrPtr = spiTxRxFifoCtrlArray[0]; //================================================================================ // CODING //================================================================================ RegMap #( .AXI_DATA_WIDTH (AXI_DATA_WIDTH), .SPI_BASE_ADDR (SPI_BASE_ADDR) ) RegMap ( .Clk_i(s_axi_aclk), .RstN_i(s_axi_aresetn), .WrData_i(WrData_i), .WrAddr_i(WrAddr_i), .RdAddr_i(RdAddr_i), .Val_i(Val_i), .SpiCtrlReg_o(spiCtrlArray), .SpiClkReg_o(spiClkArray), .SpiCsDelayReg_o(spiCsDelayArray), .SpiCsCtrlReg_o(spiCsCtrlArray), .SpiTxRxFifoCtrlReg_o(spiTxRxFifoCtrlArray), .AnsDataReg_o(dataFromRegMap) ); /* CDC Block */ CDC #( .WIDTH (AXI_DATA_WIDTH), .STAGES (STAGES) ) synchronizer ( .ClkFast_i (s_axi_aclk), .ClkSlow_i (spiClkBus), .SpiCtrlReg_i (spiCtrlArray), .SpiCsCtrlReg_i (spiCsCtrlArray), .SpiCsDelayReg_i (spiCsDelayArray), .SpiTxRxFifoCtrlReg_i (spiTxRxFifoCtrlArray), .SpiCtrlReg_o (spiCtrlRR), .SpiCsCtrlReg_o (spiCsCtrlRR), .SpiCsDelayReg_o (spiCsDelayRR), .SpiTxRxFifoCtrlReg_o (spiTxRxFifoCtrlRR) ); /* Spi Settings Block */ SpiSettings #( .AXI_DATA_WIDTH(AXI_DATA_WIDTH) ) spiSettings ( .SpiCtrlReg_i(spiCtrlRR), .SpiCsDelayReg_i(spiCsDelayRR), .SpiClkReg_i(spiClkArray), .SpiCsCtrlReg_i(spiCsCtrlRR), .SpiTxRxFifoCtrlReg_i(spiTxRxFifoCtrlRR), .SpiTxRxEnReg_i(spiTxRxEnReg), .WidthSel_o(widthSel), .SpiEn_o(spiEn), .SpiMode_o(spiMode), .ClockPol_o(clockPol), .ClockPhase_o(clockPhase), .EndianSel_o(endianSel), .SelSt_o(selSt), .Assel(assel), .StopDelay_o(stopDelay), .Lead_o(lead), .Lag_o(lag), .BaudRate_o(baudRate), .SpiRst_o(SpiRst_o), .FifoRxRst_o(fifoRxRst), .FifoTxRst_o(fifoTxRst), .ChipSelFpga_o(chipSelFpga), .ChipSelFlash_o(chipSelFlash), .SpiDir_o(SpiDir_o), .TxEn_o(txEn) ); Sync1bit #( .WIDTH (1), .STAGES (STAGES) ) Sync1bit_inst ( .ClkFast_i (Clk_i), .ClkSlow_i (SpiClk_i), .TxEn_i (TxEn_i), .TxEn_o (spiTxEnSync) ); DataFifoWrapper #( .CMD_REG_WIDTH (CMD_REG_WIDTH), .ADDR_REG_WIDTH (ADDR_REG_WIDTH), .STAGES (STAGES), .TX_FIFO_ADDR (SPI_BASE_ADDR+64'h28), .RX_FIFO_ADDR (SPI_BASE_ADDR+64'h30) ) DataFifoWrapper ( .WrClk_i (Clk_i), .RdClk_i (SpiClk_i), .FifoRxRst_i (fifoRxRst), .FifoTxRst_i (fifoTxRst), .FifoRxRstRdPtr_i (), .FifoTxRstWrPtr_i (), .WrData_i (WrData_i), .WrAddr_i (WrAddr_i), .RdAddr_i (RdAddr_i), .Val_i (Val_i), .ToFifoRxData_i (dataToRxFifo), .ToFifoRxWriteVal_i (valToRxR), .ToFifoTxReadVal_i (valToTxFifoRead), .TxFifoCtrlReg_o (TxFifoCtrlReg_o), .RxFifoCtrlReg_o (RxFifoCtrlReg_o), .EmptyFlagTx_o (emptyFlagTx), .DataFromRxFifo_o (dataFromRxFifo), .ToSpiData_o (toSpiData) ); generate if (ISTEMPRD) begin : TempRdSpi SPIs TempRdSpi ( .Clk_i (SpiClk_i), .Rst_i (Rst_i | spiMode), .Sck_i (sckR), .Ss_i (ssR), .Mosi0_i (Mosi1_io), .WidthSel_i (widthSel), .EndianSel_i (endianSel), .SelSt_i (selSt), .DataToRxFifo_o (tempData), .Val_o (tempVal) ); always @(posedge Clk_i) begin if (Rst_i) begin tempDataReg <= 32'd0; end else begin if (tempVal) begin tempDataReg <= tempData; end end end assign RdData_o = (RdAddr_i == TMPRD_ADDR) ? tempDataReg : dataFromRxFifo; end else begin assign RdData_o = dataToRxFifo; end endgenerate generate if (ISPOWERRST) begin : PowRstMem PowRstMemWrapper #( .RST_MEM_BASE_ADDR(RST_MEM_BASE_ADDR) ) PowRstMemWrapper ( .Clk_i(Clk_i), .Rst_i(Rst_i), .WrData_i(WrData_i), .WrAddr_i(WrAddr_i), .Val_i(Val_i), .RdReq_i(), .Data_o(powRstData), .DataVal_o() ); SpiDataMuxer SpiDataMuxer( .Clk_i (Clk_i), .Rst_i (Rst_i), .PowRstEn_i (PowRstEn_i), .PowRstData_i (powRstData), .RegularData_i (toSpiData), .Data_o (toSpiDataR) ); SPIm SPIm ( .Clk_i (SpiClk_i), .Start_i (spiTxEnSync), .Rst_i (Rst_i | spiMode | !spiEn), .EmptyFlag_i (emptyFlagTx), .SpiData_i (toSpiDataR), .WidthSel_i (widthSel), .PulsePol_i (clockPol), .ClockPhase_i (clockPhase), .EndianSel_i (endianSel), .Lag_i (lag), .Lead_i (lead), .Stop_i (stopDelay), .SelSt_i (selSt), .Sck_o (sckR), .Ss_o (ssR), .Mosi0_o (mosi0R), .Val_o (valToTxR) ); SPIs SPIs ( .Clk_i (SpiClk_i), .Rst_i (Rst_i | spiMode), .Sck_i (sckR), .Ss_i (ssR), .Mosi0_i (Mosi1_io), .WidthSel_i (widthSel), .EndianSel_i (endianSel), .SelSt_i (selSt), .DataToRxFifo_o (dataToRxFifo), .Val_o (valToRxR) ); QuadSPIm QuadSPIm ( .Clk_i (SpiClk_i), .Start_i (spiTxEnSync), .Rst_i (Rst_i | !spiMode | !spiEn), .EmptyFlag_i (emptyFlagTx), .SpiData_i (toSpiDataR), .WidthSel_i (widthSel), .PulsePol_i (clockPol), .ClockPhase_i (clockPhase), .EndianSel_i (endianSel), .Lag_i (lag), .Lead_i (lead), .Stop_i (stopDelay), .SelSt_i (selSt), .Sck_o (sckQ), .Ss_o (ssQ), .Mosi0_o (mosi0Q), .Mosi1_o (mosi1_o), .Mosi2_o (Mosi2_o), .Mosi3_o (Mosi3_o), .Val_o (valToTxQ) ); SpiLinesMuxer SpiLinesMuxer ( .SsR_i (ssR), .SsQ_i (ssQ), .SckR_i (sckR), .SckQ_i (sckQ), .Mosi0R_i (mosi0R), .Mosi0Q_i (mosi0Q), .ChipSelFpga_i (chipSelFpga), .ChipSelFlash_i (chipSelFlash), .Assel_i (assel), .SpiMode_i (spiMode), .Ss_o (Ss_o), .SsFlash_o (SsFlash_o), .Sck_o (Sck_o), .Mosi0_o (Mosi0_o) ); end else begin SPIm SPIm ( .Clk_i (SpiClk_i), .Start_i (spiTxEnSync), .Rst_i (Rst_i | spiMode | !spiEn), .EmptyFlag_i (emptyFlagTx), .SpiData_i (toSpiData), .WidthSel_i (widthSel), .PulsePol_i (clockPol), .ClockPhase_i (clockPhase), .EndianSel_i (endianSel), .Lag_i (lag), .Lead_i (lead), .Stop_i (stopDelay), .SelSt_i (selSt), .Sck_o (sckR), .Ss_o (ssR), .Mosi0_o (mosi0R), .Val_o (valToTxR) ); SPIs SPIs ( .Clk_i (SpiClk_i), .Rst_i (Rst_i | spiMode), .Sck_i (sckR), .Ss_i (ssR), .Mosi0_i (Mosi1_io), .WidthSel_i (widthSel), .EndianSel_i (endianSel), .SelSt_i (selSt), .DataToRxFifo_o (dataToRxFifo), .Val_o (valToRxR) ); QuadSPIm QuadSPIm ( .Clk_i (SpiClk_i), .Start_i (spiTxEnSync), .Rst_i (Rst_i | !spiMode | !spiEn), .EmptyFlag_i (emptyFlagTx), .SpiData_i (toSpiData), .WidthSel_i (widthSel), .PulsePol_i (clockPol), .ClockPhase_i (clockPhase), .EndianSel_i (endianSel), .Lag_i (lag), .Lead_i (lead), .Stop_i (stopDelay), .SelSt_i (selSt), .Sck_o (sckQ), .Ss_o (ssQ), .Mosi0_o (mosi0Q), .Mosi1_o (mosi1_o), .Mosi2_o (Mosi2_o), .Mosi3_o (Mosi3_o), .Val_o (valToTxQ) ); SpiLinesMuxer SpiLinesMuxer ( .SsR_i (ssR), .SsQ_i (ssQ), .SckR_i (sckR), .SckQ_i (sckQ), .Mosi0R_i (mosi0R), .Mosi0Q_i (mosi0Q), .ChipSelFpga_i (chipSelFpga), .ChipSelFlash_i (chipSelFlash), .Assel_i (assel), .SpiMode_i (spiMode), .Ss_o (Ss_o), .SsFlash_o (SsFlash_o), .Sck_o (Sck_o), .Mosi0_o (Mosi0_o) ); end endgenerate endmodule