module EpSubSystem #( parameter AXI_DATA_WIDTH = 64, parameter SPI_NUM = 1, parameter AXI_ID_WIDTH = 4, parameter STAGES = 3, parameter [3:0] ISTEMPRD = 4'b0001, parameter [3:0] ISPOWERRST = 4'b0001, parameter FIFO_TX1_ADDR = 64'h0000000000001028, parameter FIFO_TX2_ADDR = 64'h0000000000002028, parameter FIFO_TX3_ADDR = 64'h0000000000003028, parameter FIFO_TX4_ADDR = 64'h0000000000004028, parameter FIFO_TX5_ADDR = 64'h0000000000005028, parameter FIFO_TX6_ADDR = 64'h0000000000006028, parameter FIFO_TX7_ADDR = 64'h0000000000007028, parameter FIFO_1_READ_ADDR = 64'h0000_0000_0000_1030, parameter FIFO_2_READ_ADDR = 64'h0000_0000_0000_2030, parameter FIFO_3_READ_ADDR = 64'h0000_0000_0000_3030, parameter FIFO_4_READ_ADDR = 64'h0000_0000_0000_4030, parameter FIFO_5_READ_ADDR = 64'h0000_0000_0000_5030, parameter FIFO_6_READ_ADDR = 64'h0000_0000_0000_6030, parameter FIFO_7_READ_ADDR = 64'h0000_0000_0000_7030 ) ( AxiMMBus.master Bus, /* Ld */ input [SPI_NUM-1:0] Ld_i, output [SPI_NUM-1:0] Mosi0_o, inout [SPI_NUM-1:0] Mosi1_io, //inout: when RSPI mode, input; when QSPI mode output; output [SPI_NUM-1:0] Mosi2_o, output [SPI_NUM-1:0] Mosi3_o, output [SPI_NUM-1:0] Ss_o, output [SPI_NUM-1:0] SsFlash_o, output [SPI_NUM-1:0] Sck_o, output [SPI_NUM-1:0] SpiRst_o, output [SPI_NUM-1:0] SpiDir_o, output LD_o ); //================================================================================ // REG/WIRE //================================================================================ /* SPI0 */ wire [AXI_DATA_WIDTH-1:0] spi0Ctrl; wire [AXI_DATA_WIDTH-1:0] spi0Clk; wire [AXI_DATA_WIDTH-1:0] spi0CsDelay; wire [AXI_DATA_WIDTH-1:0] spi0CsCtrl; wire [AXI_DATA_WIDTH-1:0] spi0TxRxFifoCtrl; /* SPI1 */ wire [AXI_DATA_WIDTH-1:0] spi1Ctrl; wire [AXI_DATA_WIDTH-1:0] spi1Clk; wire [AXI_DATA_WIDTH-1:0] spi1CsDelay; wire [AXI_DATA_WIDTH-1:0] spi1CsCtrl; wire [AXI_DATA_WIDTH-1:0] spi1TxRxFifoCtrl; /* SPI2 */ wire [AXI_DATA_WIDTH-1:0] spi2Ctrl; wire [AXI_DATA_WIDTH-1:0] spi2Clk; wire [AXI_DATA_WIDTH-1:0] spi2CsDelay; wire [AXI_DATA_WIDTH-1:0] spi2CsCtrl; wire [AXI_DATA_WIDTH-1:0] spi2TxRxFifoCtrl; /* SPI3 */ wire [AXI_DATA_WIDTH-1:0] spi3Ctrl; wire [AXI_DATA_WIDTH-1:0] spi3Clk; wire [AXI_DATA_WIDTH-1:0] spi3CsDelay; wire [AXI_DATA_WIDTH-1:0] spi3CsCtrl; wire [AXI_DATA_WIDTH-1:0] spi3TxRxFifoCtrl; /* SPI4 */ wire [AXI_DATA_WIDTH-1:0] spi4Ctrl; wire [AXI_DATA_WIDTH-1:0] spi4Clk; wire [AXI_DATA_WIDTH-1:0] spi4CsDelay; wire [AXI_DATA_WIDTH-1:0] spi4CsCtrl; wire [AXI_DATA_WIDTH-1:0] spi4TxRxFifoCtrl; /* SPI5 */ wire [AXI_DATA_WIDTH-1:0] spi5Ctrl; wire [AXI_DATA_WIDTH-1:0] spi5Clk; wire [AXI_DATA_WIDTH-1:0] spi5CsDelay; wire [AXI_DATA_WIDTH-1:0] spi5CsCtrl; wire [AXI_DATA_WIDTH-1:0] spi5TxRxFifoCtrl; /* SPI6 */ wire [AXI_DATA_WIDTH-1:0] spi6Ctrl; wire [AXI_DATA_WIDTH-1:0] spi6Clk; wire [AXI_DATA_WIDTH-1:0] spi6CsDelay; wire [AXI_DATA_WIDTH-1:0] spi6CsCtrl; wire [AXI_DATA_WIDTH-1:0] spi6TxRxFifoCtrl; /* Spi settings arrays */ wire [AXI_DATA_WIDTH - 1 : 0] spiCtrlArray [SPI_NUM-1:0]; wire [AXI_DATA_WIDTH - 1 : 0] spiClkArray [SPI_NUM-1:0]; wire [AXI_DATA_WIDTH - 1 : 0] spiCsDelayArray [SPI_NUM-1:0]; wire [AXI_DATA_WIDTH - 1 : 0] spiCsCtrlArray [SPI_NUM-1:0]; wire [AXI_DATA_WIDTH - 1 : 0] spiTxRxFifoCtrlArray [SPI_NUM-1:0]; /* 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 [SPI_NUM-1:0]; wire [AXI_DATA_WIDTH-1:0] spiCsDelayRR [SPI_NUM-1:0]; wire [AXI_DATA_WIDTH-1:0] spiCsCtrlRR [SPI_NUM-1:0]; wire [AXI_DATA_WIDTH-1:0] spiTxRxFifoCtrlRR [SPI_NUM-1:0]; /* AXI-Slave */ wire [AXI_DATA_WIDTH-1:0] rdDataToAxiSlave; wire [AXI_DATA_WIDTH-1:0] rdAddr; wire [AXI_DATA_WIDTH-1:0] wrDataFromAxiSlave; wire [AXI_DATA_WIDTH-1:0] wrAddrFromAxiSlave; wire valFromAxiSlave; wire valToRdFifo; /* Input Mux */ wire [AXI_DATA_WIDTH-1:0] toFifoData; wire [SPI_NUM-1:0] toFifoVal; wire [AXI_DATA_WIDTH-1:0] toRegMapData; wire [AXI_DATA_WIDTH-1:0] dataBus; wire [SPI_NUM:0] dataBusVal; wire toRegMapVal; wire [AXI_DATA_WIDTH-1:0] toRegMapAddr; /* Clock Manager */ wire [7:0] baudRate [SPI_NUM-1:0]; wire [SPI_NUM-1:0] spiClkBus; /* SpiSettings */ wire [1:0] widthSel [SPI_NUM-1:0]; wire [SPI_NUM-1:0] spiEn; wire [SPI_NUM-1:0] spiMode; wire [SPI_NUM-1:0] clockPol; wire [SPI_NUM-1:0] clockPhase; wire [SPI_NUM-1:0] endianSel; wire [SPI_NUM-1:0] selSt; wire [SPI_NUM-1:0] assel; wire [5:0] stopDelay [SPI_NUM-1:0]; wire [SPI_NUM-1:0] lead; wire [SPI_NUM-1:0] lag; wire [SPI_NUM-1:0] fifoTxRst; wire [SPI_NUM-1:0] fifoRxRst; wire [SPI_NUM-1:0] txEn; wire [SPI_NUM-1:0] chipSelFpga; wire [SPI_NUM-1:0] chipSelFlash; wire [SPI_NUM-1:0] fifoRxRstRdPtr; wire [SPI_NUM-1:0] fifoTxRstWrPtr; /* CDC LD */ wire [SPI_NUM-1:0] ldReg; /* Output Mux */ wire [AXI_DATA_WIDTH - 1 : 0] dataFromRxFifo [SPI_NUM-1:0]; //================================================================================ // ASSIGNMENTS //================================================================================ genvar j; generate for (j = 0; j < SPI_NUM; j = j +1) begin : Assignments assign fifoRxRstRdPtr[j] = spiTxRxFifoCtrlArray[j][32]; assign fifoTxRstWrPtr[j] = spiTxRxFifoCtrlArray[j][0]; end endgenerate //================================================================================ // CODING //================================================================================ AxiMMBus #(.AXI_DATA_WIDTH(AXI_DATA_WIDTH)) AxiBus(); AxiSlave #( .AXI_DATA_WIDTH(AXI_DATA_WIDTH) ) axi_slave ( .Bus(Bus), .RdData_i(rdDataToAxiSlave), .Val_o (valFromAxiSlave), .ValToRdFifo_o(valToRdFifo), .Data_o (wrDataFromAxiSlave), .RdAddr_o (rdAddr), .Addr_o (wrAddrFromAxiSlave) ); /* Input Mux */ InputMux #( .AXI_DATA_WIDTH (AXI_DATA_WIDTH), .SPI_NUM (SPI_NUM), .FIFO_TX1_ADDR (FIFO_TX1_ADDR), .FIFO_TX2_ADDR (FIFO_TX2_ADDR), .FIFO_TX3_ADDR (FIFO_TX3_ADDR), .FIFO_TX4_ADDR (FIFO_TX4_ADDR), .FIFO_TX5_ADDR (FIFO_TX5_ADDR), .FIFO_TX6_ADDR (FIFO_TX6_ADDR), .FIFO_TX7_ADDR (FIFO_TX7_ADDR) ) InputMux ( .Clk_i(s_axi_aclk), .RstN_i(s_axi_aresetn), .Val_i(valFromAxiSlave), .Addr_i(wrAddrFromAxiSlave), .Data_i(wrDataFromAxiSlave), .ToRegMapAddr_o(toRegMapAddr), .Val_o(dataBusVal), .Data_o(dataBus) ); /* Register Map */ RegMap #( .AXI_DATA_WIDTH (AXI_DATA_WIDTH), .SPI_NUM (SPI_NUM) ) RegMap ( .Clk_i(s_axi_aclk), .RstN_i(s_axi_aresetn), .WrData_i(dataBus), .WrAddr_i(toRegMapAddr), .RdAddr_i(rdAddr), .Val_i(dataBusVal[SPI_NUM]), .SpiCtrlReg_o(spiCtrlArray), .SpiClkReg_o(spiClkArray), .SpiCsDelayReg_o(spiCsDelayArray), .SpiCsCtrlReg_o(spiCsCtrlArray), .SpiTxRxFifoCtrlReg_o(spiTxRxFifoCtrlArray), .SpiTxRxEnReg_o(spiTxRxEnReg), .AnsDataReg_o(dataFromRegMap) ); /* Clock Manager */ ClkManager #( .SPI_NUM (SPI_NUM), .STAGES (STAGES) ) ClkManager ( .Clk_i(s_axi_aclk), .Rst_i(~s_axi_aresetn), .BaudRate_i (baudRate), .SpiClk_o(spiClkBus), .SubSystSyncRst_o(spiSubSysRst) ); /* CDC Block */ CDC #( .WIDTH (AXI_DATA_WIDTH), .STAGES (STAGES), .SPI_NUM (SPI_NUM) ) 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), .SPI_NUM(SPI_NUM) ) 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) ); /* Generate block */ genvar i; generate for (i = 0; i < SPI_NUM; i = i + 1) begin : SpiSubSystem SpiSubSystem #( .STAGES (STAGES), .CMD_REG_WIDTH (AXI_DATA_WIDTH), .ADDR_REG_WIDTH (AXI_DATA_WIDTH), .WIDTH (1), .FIFO_NUM (SPI_NUM), .ISTEMPRD (ISTEMPRD[i]), .ISPOWERRST (ISPOWERRST[i]) ) SpiSubSystem ( .Clk_i(s_axi_aclk), .SpiClk_i(spiClkBus[i]), .Rst_i(spiSubSysRst), .TxEn_i(txEn[i]), .FifoRxRst_i(fifoRxRst[i]), .FifoTxRst_i(fifoTxRst[i]), .FifoRxRstRdPtr_i(fifoRxRstRdPtr[i]), .FifoTxRstWrPtr_i(fifoTxRstWrPtr[i]), .ToFifoVal_i(dataBusVal[i]), .ToRstMemVal_i(dataBusVal[i]), .ToFifoData_i(dataBus), .WidthSel_i(widthSel[i]), .PulsePol_i(clockPol[i]), .ClockPhase_i(clockPhase[i]), .EndianSel_i(endianSel[i]), .Lag_i(lag[i]), .Lead_i(lead[i]), .SelSt_i(selSt[i]), .Stop_i(stopDelay[i]), .Assel_i(assel[i]), .ChipSelFpga_i(chipSelFpga[i]), .ChipSelFlash_i(chipSelFlash[i]), .SpiMode_i(spiMode[i]), .SpiEn_i(spiEn[i]), .TxFifoCtrlReg_o(), .RxFifoCtrlReg_o(), .DataFromRxFifo_o(dataFromRxFifo[i]), .Sck_o(Sck_o[i]), .Ss_o(Ss_o[i]), .SsFlash_o(SsFlash_o[i]), .Mosi0_o(Mosi0_o[i]), .Mosi1_io(Mosi1_io[i]), .Mosi2_o(Mosi2_o[i]), .Mosi3_o(Mosi3_o[i]), .Ctrl_i(), .TempData_o() ); xpm_cdc_single #( .DEST_SYNC_FF (3), .INIT_SYNC_FF (0), .SIM_ASSERT_CHK (0), .SRC_INPUT_REG (1) ) xpm_cdc_single_inst( .dest_out (ldReg[i]), .dest_clk (s_axi_aclk), .src_clk (spiClkBus[i]), .src_in (Ld_i[i]) ); end endgenerate /* Output Mux */ OutputMux #( .AXI_DATA_WIDTH (AXI_DATA_WIDTH), .SPI_NUM (SPI_NUM), .FIFO_1_READ_ADDR (FIFO_1_READ_ADDR), .FIFO_2_READ_ADDR (FIFO_2_READ_ADDR), .FIFO_3_READ_ADDR (FIFO_3_READ_ADDR), .FIFO_4_READ_ADDR (FIFO_4_READ_ADDR), .FIFO_5_READ_ADDR (FIFO_5_READ_ADDR), .FIFO_6_READ_ADDR (FIFO_6_READ_ADDR), .FIFO_7_READ_ADDR (FIFO_7_READ_ADDR) ) OutputMux ( .Clk_i(s_axi_aclk), .RstN_i(s_axi_aresetn), .DataFromRxFifo_i(dataFromRxFifo), .DataFromRegMap_i(dataFromRegMap), .Addr_i(rdAddr), .AnsData_o(rdDataToAxiSlave) ); endmodule