`timescale 1ns / 1ps module S5443_3_tb; parameter CLK_PERIOD = 8.13; // Clock period in ns reg Clk_i; reg Rst_i; reg [10:0] SmcAddr_i; reg [15:0]SmcData_i; reg SmcAre_i; wire smcAre; reg SmcAwe_i; wire SmcAmsN_i; wire [1:0] SmcBe_i; wire SmcAoe_i; reg [31:0] tb_cnt; wire [15:0] smcData; reg mosi1reg; reg minorByte; reg [1:0] areCnt; //*********************************************** // SPI0 Adresses //*********************************************** // Address map for SPI0 localparam [10:0] BaseAddr0 = 11'h0; localparam [10:0] Spi0CtrlAddr = BaseAddr0; localparam [10:0] Spi0ClkAddr = (BaseAddr0 + 4)>>1; localparam [10:0] Spi0CsDelayAddr = (BaseAddr0 + 8)>>1; localparam [10:0] Spi0CsCtrlAddr = (BaseAddr0 + 12)>>1; localparam [10:0] Spi0TxFifoCtrlAddr = (BaseAddr0 + 16)>>1; localparam [10:0] Spi0RxFifoCtrlAddr = (BaseAddr0 + 20)>>1; localparam [10:0] Spi0TxFifoAddrL = (BaseAddr0 + 24)>>1; localparam [10:0] Spi0TxFifoAddrM = (BaseAddr0 + 26)>>1; localparam [10:0] Spi0RxFifoAddrL = (BaseAddr0 + 28)>>1; localparam [10:0] Spi0RxFifoAddrM = (BaseAddr0 + 30)>>1; // Data for SPI0CtrlReg //*********************************************** // SPI0 Ctrl Reg Data //*********************************************** localparam SpiEn0 = 1'b1;//1 for enable, 0 for disable localparam ClockPhase0 = 1'b0;// localparam ClockPolarity0 = 1'b0;//0 for active high, 1 for active low localparam Assel0 = 1'b1;//0 for software control, 1 for hardware control localparam SelSt0 = 1'b1; //1 - assert slave select(low), 0 - deassert slave select(high) localparam Size0 = 2'd2; //0 - 8 bits, 1 - 16 bits, 2 - 24 bits, 3 - 32 bits localparam Mode0 = 1'b0; // 1 - 4 Mosi, 0 - 1 Mosi localparam LSBF0 = 1'b0; // 1 - LSB first, 0 - MSB first localparam [15:0] Spi0CtrlRegData = {8'h0,LSBF0, Mode0, Size0, SelSt0, Assel0, ClockPolarity0, ClockPhase0, SpiEn0}; //*********************************************** // SPI0 Clk Reg Data //*********************************************** localparam Div = 4'd1; // Custom divider value(input clock frequency = 80 MHz) localparam Mux0 = 1'b1; // 0 - input clock, 1 - MMCM output clock localparam Mux1 = 3'd0; // MMCM output clock number localparam Spi0ClkRegData = {8'h0, Mux1, Mux0, Div}; //*********************************************** // SPI0 Cs Delay Reg Data //*********************************************** localparam Lag0 = 1'b0; //Extended SPI clock lag control, 0 - Disable, 1 - Enable localparam Lead0 = 1'b0; //Extended SPI clock lead control, 0 - Disable, 1 - Enable localparam Stop0 = 6'd0; //Number of clock cycles to wait after CS is deasserted localparam [15:0] Spi0CsDelayRegData = {8'h0, Stop0, Lead0, Lag0}; //*********************************************** // SPI0 Cs Ctrl Reg Data //*********************************************** localparam CS0 = 1'b1; // 1 - device selected, 0 - device deselected localparam CS1 = 1'b1; // 1 - device selected, 0 - device deselected localparam [15:0] Spi0CsCtrlRegData = {14'h0, CS1, CS0}; //*********************************************** // SPI0 Tx Fifo Ctrl Reg Data //*********************************************** localparam RstTxFifo0 = 1'b1; // 1 - Reset Tx FIFO, 0 - Normal operation // at least 5 clock cycles of a slow clock localparam [15:0] Spi0TxFifoCtrlRegDataRstOn = {15'h0, RstTxFifo0}; localparam [15:0] Spi0TxFifoCtrlRegDataRstOff = {15'h0, 1'b0}; //*********************************************** // SPI0 Rx Fifo Ctrl Reg Data //*********************************************** localparam RstRxFifo0 = 1'b1; // 1 - Reset Rx FIFO, 0 - Normal operation localparam [15:0] Spi0RxFifoCtrlRegDataRstOn = {15'h0, RstRxFifo0}; localparam [15:0] Spi0RxFifoCtrlRegDataRstOff = {15'h0, 1'b0}; //*********************************************** // SPITXRX Enable Register //*********************************************** localparam SpiTxRxEn0 = 1'b1; localparam SpiTxRxEn1 = 1'b0; localparam SpiTxRxEn2 = 1'b0; localparam SpiTxRxEn3 = 1'b0; localparam SpiTxRxEn4 = 1'b0; localparam SpiTxRxEn5 = 1'b0; localparam SpiTxRxEn6 = 1'b0; localparam [15:0] SpiTxRxEnRegData = {8'h0, SpiTxRxEn6, SpiTxRxEn5, SpiTxRxEn4, SpiTxRxEn3, SpiTxRxEn2, SpiTxRxEn1, SpiTxRxEn0}; //*********************************************** // GPIO Reg Data //*********************************************** localparam RstForSbTmsg = 1'b1; // 1 - Reset for SB TMSG, 0 - Normal operation localparam [15:0] GPIORegDataRstOn = {15'h0, RstForSbTmsg}; localparam [15:0] GPIORegDataRstOff = {15'h0, 1'b0}; //*********************************************** // SPI1HEADERS //*********************************************** localparam [10:0] BaseAddr1 = 11'h50; localparam [10:0] Spi1CtrlAddr = (BaseAddr1)>>1; localparam [10:0] Spi1ClkAddr = (BaseAddr1 + 4)>>1; localparam [10:0] Spi1CsDelayAddr = (BaseAddr1 + 8)>>1; localparam [10:0] Spi1CsCtrlAddr = (BaseAddr1 + 12)>>1; localparam [10:0] Spi1TxFifoCtrlAddr = (BaseAddr1 + 16)>>1; localparam [10:0] Spi1RxFifoCtrlAddr = (BaseAddr1 + 20)>>1; localparam [10:0] Spi1TxFifoAddr = (BaseAddr1 + 24)>>1; localparam [10:0] Spi1RxFifoAddr = (BaseAddr1 + 28)>>1; //*********************************************** // SPI2HEADERS //*********************************************** localparam [10:0] BaseAddr2 = 11'hF0; localparam [10:0] Spi2CtrlAddr = (BaseAddr2)>>1; localparam [10:0] Spi2ClkAddr = (BaseAddr2 + 4)>>1; localparam [10:0] Spi2CsDelayAddr = (BaseAddr2 + 8)>>1; localparam [10:0] Spi2CsCtrlAddr = (BaseAddr2 + 12)>>1; localparam [10:0] Spi2TxFifoCtrlAddr = (BaseAddr2 + 16)>>1; localparam [10:0] Spi2RxFifoCtrlAddr = (BaseAddr2 + 20)>>1; localparam [10:0] Spi2TxFifoAddr = (BaseAddr2 + 24)>>1; localparam [10:0] Spi2RxFifoAddr = (BaseAddr2 + 28)>>1; //*********************************************** // SPI3HEADERS //*********************************************** localparam [10:0] BaseAddr3 = 11'h140; localparam [10:0] Spi3CtrlAddr = (BaseAddr3)>>1; localparam [10:0] Spi3ClkAddr = (BaseAddr3 + 4)>>1; localparam [10:0] Spi3CsDelayAddr = (BaseAddr3 + 8)>>1; localparam [10:0] Spi3CsCtrlAddr = (BaseAddr3 + 12)>>1; localparam [10:0] Spi3TxFifoCtrlAddr = (BaseAddr3 + 16)>>1; localparam [10:0] Spi3RxFifoCtrlAddr = (BaseAddr3 + 20)>>1; localparam [10:0] Spi3TxFifoAddr = (BaseAddr3 + 24)>>1; localparam [10:0] Spi3RxFifoAddr = (BaseAddr3 + 28)>>1; //*********************************************** // SPI4HEADERS //*********************************************** localparam [10:0] BaseAddr4 = 11'h190; localparam [10:0] Spi4CtrlAddr = (BaseAddr4)>>1; localparam [10:0] Spi4ClkAddr = (BaseAddr4 + 4)>>1; localparam [10:0] Spi4CsDelayAddr = (BaseAddr4 + 8)>>1; localparam [10:0] Spi4CsCtrlAddr = (BaseAddr4 + 12)>>1; localparam [10:0] Spi4TxFifoCtrlAddr = (BaseAddr4 + 16)>>1; localparam [10:0] Spi4RxFifoCtrlAddr = (BaseAddr4 + 20)>>1; localparam [10:0] Spi4TxFifoAddr = (BaseAddr4 + 24)>>1; localparam [10:0] Spi4RxFifoAddr = (BaseAddr4 + 28)>>1; //*********************************************** // SPI5HEADERS //*********************************************** localparam [10:0] BaseAddr5 = 11'h1E0; localparam [10:0] Spi5CtrlAddr = (BaseAddr5)>>1; localparam [10:0] Spi5ClkAddr = (BaseAddr5 + 4)>>1; localparam [10:0] Spi5CsDelayAddr = (BaseAddr5 + 8)>>1; localparam [10:0] Spi5CsCtrlAddr = (BaseAddr5 + 12)>>1; localparam [10:0] Spi5TxFifoCtrlAddr = (BaseAddr5 + 16)>>1; localparam [10:0] Spi5RxFifoCtrlAddr = (BaseAddr5 + 20)>>1; localparam [10:0] Spi5TxFifoAddr = (BaseAddr5 + 24)>>1; localparam [10:0] Spi5RxFifoAddr = (BaseAddr5 + 28)>>1; //*********************************************** // SPI5HEADERS //*********************************************** localparam [10:0] BaseAddr6 = 11'h230; localparam [10:0] Spi6CtrlAddr = (BaseAddr6)>>1; localparam [10:0] Spi6ClkAddr = (BaseAddr6 + 4)>>1; localparam [10:0] Spi6CsDelayAddr = (BaseAddr6 + 8)>>1; localparam [10:0] Spi6CsCtrlAddr = (BaseAddr6 + 12)>>1; localparam [10:0] Spi6TxFifoCtrlAddr = (BaseAddr6 + 16)>>1; localparam [10:0] Spi6RxFifoCtrlAddr = (BaseAddr6 + 20)>>1; localparam [10:0] Spi6TxFifoAddr = (BaseAddr6 + 24)>>1; localparam [10:0] Spi6RxFifoAddr = (BaseAddr6 + 28)>>1; //*********************************************** // SPITXRX Enable Reg Adress //*********************************************** localparam SpiTxRxEnAddr = 11'h780; //*********************************************** // GPIO Reg Adress //*********************************************** localparam GPIOAddr = 11'h7F8; //*********************************************** // ASSIGNS //*********************************************** assign SmcBe_i = (tb_cnt >0 && tb_cnt <=374) ? 2'b00 : 2'b11; assign SmcAmsN_i = (tb_cnt > 0 && tb_cnt <= 44) ? 1'b0 : 1'b1; assign SmcAoe_i = (tb_cnt > 330 && tb_cnt <= 374) ? 1'b0 : 1'b1; assign smcData = (!SmcAoe_i && !SmcAre_i) ? 16'bz:SmcData_i; assign mosi1_io = (!Mode0) ? mosi0_o : 1'bz; assign smcAre = SmcAre_i; //*********************************************** // CLOCK GENERATION //*********************************************** always #(CLK_PERIOD/2) Clk_i = ~Clk_i; S5443_3Top uut ( .Clk123_i(Clk_i), .SmcAddr_i(SmcAddr_i), .SmcData_io(smcData), .SmcAwe_i(SmcAwe_i), .SmcAmsN_i(SmcAmsN_i), .SmcAre_i(smcAre), .SmcBe_i(SmcBe_i), .SmcAoe_i(SmcAoe_i), .Led_o(), .Mosi0_o(mosi0_o), .Mosi1_io(mosi1_io), .Mosi2_o(), .Mosi3_o(), .Ss_o(), .SsFlash_o(), .Sck_o(), .SpiRst_o(), .LD_o() ); always @(posedge Clk_i) begin if (Rst_i) begin SmcAwe_i <= 1'b1; end else begin if (tb_cnt > 0 && tb_cnt <= 44) begin if (tb_cnt % 2 != 0) begin SmcAwe_i <= 1'b1; end else begin SmcAwe_i <= 1'b0; end end end end always @(*) begin if (Rst_i) begin SmcAre_i <= 1'b1; end else begin if (tb_cnt > 330 && tb_cnt <= 374) begin if (tb_cnt % 2 != 0) begin if (areCnt < 3) begin SmcAre_i <= 1'b0; end else begin SmcAre_i = 1'b1; end end else begin SmcAre_i <= 1'b1; end end else begin SmcAre_i <= 1'b1; end end end always @(posedge Clk_i) begin if (Rst_i) begin SmcAddr_i <= 0; end else begin if (tb_cnt < 27) begin case (tb_cnt) 0: begin SmcAddr_i <= BaseAddr0; end 3: begin SmcAddr_i <= Spi0ClkAddr; end 5: begin SmcAddr_i <= Spi0CsDelayAddr; end 7: begin SmcAddr_i <= Spi0CsCtrlAddr; end 9: begin SmcAddr_i <= Spi0TxFifoCtrlAddr; end 11: begin SmcAddr_i <= Spi0RxFifoCtrlAddr; end 19 : begin SmcAddr_i <= Spi0TxFifoCtrlAddr; end 21 : begin SmcAddr_i <= Spi0RxFifoCtrlAddr; end 23 : begin SmcAddr_i <= SpiTxRxEnAddr; end endcase end else begin if (tb_cnt <= 44) begin if (tb_cnt % 2 != 0) begin SmcAddr_i <= Spi0TxFifoAddrL; end else begin SmcAddr_i <= Spi0TxFifoAddrM; end end else begin if (tb_cnt % 2 == 0) begin if (minorByte == 0) begin SmcAddr_i <= Spi0RxFifoCtrlAddr; end else begin SmcAddr_i <= Spi0RxFifoAddrL; end end end end end end always @(posedge Clk_i) begin if (Rst_i) begin areCnt <= 2'b0; end else begin if (!SmcAre_i) begin areCnt <= areCnt+1; end else begin areCnt <= 2'b0; end end end always @(posedge Clk_i) begin if (SmcAddr_i == Spi0RxFifoCtrlAddr) begin minorByte <= 1'b1; end else begin minorByte <= 1'b0; end end always @(posedge Clk_i) begin if (Rst_i) begin SmcData_i <= 16'h0; end else begin if (tb_cnt < 27 ) begin case (tb_cnt) 0 : begin SmcData_i <= Spi0CtrlRegData; end 3 : begin SmcData_i <= Spi0ClkRegData; end 5 : begin SmcData_i <= Spi0CsDelayRegData; end 7 : begin SmcData_i <= Spi0CsCtrlRegData; end 9 : begin SmcData_i <= Spi0TxFifoCtrlRegDataRstOn; end 11 : begin SmcData_i <= Spi0RxFifoCtrlRegDataRstOn; end 19 : begin SmcData_i <= Spi0TxFifoCtrlRegDataRstOff; end 21 : begin SmcData_i <= Spi0RxFifoCtrlRegDataRstOff; end 23 : begin SmcData_i <= SpiTxRxEnRegData; end endcase end else begin if (tb_cnt <300) SmcData_i <= $urandom_range(0, 8'hFF); end end end always @(posedge Clk_i) begin if (Rst_i) begin tb_cnt <= 0; end else begin if (SmcAre_i) begin tb_cnt <= tb_cnt + 1; end end end initial begin Clk_i = 1'b0; Rst_i = 1'b1; #(CLK_PERIOD*300) Rst_i = 1'b0; end endmodule