module QuadSPIm( input Clk_i, input Rst_i, input Start_i, input CPHA_i, input [31:0] SPIdata, input SELST_i, input [1:0] WidthSel_i, input [1:0] LAG_i, input [1:0] LEAD_i, input EndianSel_i, input [1:0] Stop_i, input PulsePol_i, output reg Mosi0_i, output reg Mosi1_i, output reg Mosi2_i, output reg Mosi3_i, output reg Sck_o, output reg Val_o, output Ss_o ); //================================================================================ // REG/WIRE //================================================================================ reg startFlag; reg [2:0] ssCnt; reg Ss; reg SSr; reg [6:0] mosiReg0; reg [6:0] mosiReg1; reg [6:0] mosiReg2; reg [6:0] mosiReg3; reg [3:0] ssNum; reg [2:0] delayCnt; reg stopFlag; wire SsPol = SELST_i ? Ss : ~Ss; //================================================================================ // ASSIGNMENTS //================================================================================ assign Ss_o = SsPol; //================================================================================ // CODING //================================================================================ always @(posedge Clk_i) begin if (Rst_i) begin delayCnt <= 1'b0; end else begin if (stopFlag &&delayCnt < Stop_i) begin delayCnt <= delayCnt + 1'b1; end else begin delayCnt <= 1'b0; end end end always @(posedge Clk_i) begin if (Rst_i) begin stopFlag <= 1'b0; end else begin if (SELST_i) begin if (Ss && !SSr) begin stopFlag <= 1'b1; end else if ( delayCnt == Stop_i) begin stopFlag <= 1'b0; end end else begin if (!Ss && SSr) begin stopFlag <= 1'b1; end else if (delayCnt == Stop_i) begin stopFlag <= 1'b0; end end end end always @(*) begin if (PulsePol_i) begin if (CPHA_i) begin if (LEAD_i == 0) begin if (!Ss && (ssCnt <= ssNum+LAG_i+LEAD_i && ssCnt > LAG_i) ) begin Sck_o = ~(~Clk_i); end else begin Sck_o = 1'b0; end end else begin if (!Ss && (ssCnt < ssNum+LAG_i+LEAD_i && ssCnt > LAG_i)) begin Sck_o = ~(~Clk_i); end else begin Sck_o = 1'b0; end end end else begin if (LEAD_i == 0) begin if (!Ss && (ssCnt <= ssNum+LAG_i+LEAD_i && ssCnt > LAG_i) ) begin Sck_o = ~(Clk_i); end else begin Sck_o = 1'b0; end end else begin if (!Ss && (ssCnt < ssNum + LAG_i + LEAD_i && ssCnt > LAG_i)) begin Sck_o = ~(Clk_i); end else begin Sck_o = 1'b0; end end end end else begin if (CPHA_i) begin if (LEAD_i == 0) begin if (!Ss && (ssCnt <= ssNum+LAG_i+LEAD_i && ssCnt > LAG_i) ) begin Sck_o = ~(Clk_i); end else begin Sck_o = 1'b0; end end else begin if (!Ss && (ssCnt LAG_i)) begin Sck_o = ~(Clk_i); end else begin Sck_o = 1'b0; end end end else begin if (LEAD_i == 0) begin if (!Ss && (ssCnt <= ssNum+LAG_i+LEAD_i && ssCnt > LAG_i) ) begin Sck_o = ~(~Clk_i); end else begin Sck_o = 1'b0; end end else begin if (!Ss && (ssCnt < ssNum + LAG_i + LEAD_i && ssCnt > LAG_i)) begin Sck_o = ~(~Clk_i); end else begin Sck_o = 1'b0; end end end end end always @(*) begin if (EndianSel_i) begin case (WidthSel_i) 0 : begin Mosi0_i = (!Ss&& (ssCnt < ssNum+LAG_i && ssCnt > LAG_i) ) ? (mosiReg3[1]):1'b0; Mosi1_i = (!Ss&& (ssCnt < ssNum+LAG_i && ssCnt > LAG_i)) ? (mosiReg2[1]):1'b0; Mosi2_i = (!Ss&& (ssCnt < ssNum+LAG_i && ssCnt > LAG_i)) ? (mosiReg1[1]):1'b0; Mosi3_i = (!Ss&& (ssCnt < ssNum+LAG_i && ssCnt > LAG_i)) ? (mosiReg0[1]):1'b0; end 1 : begin Mosi0_i = (!Ss&& (ssCnt < ssNum+LAG_i && ssCnt > LAG_i)) ? (mosiReg3[3]):1'b0; Mosi1_i = (!Ss&& (ssCnt < ssNum+LAG_i && ssCnt > LAG_i)) ? (mosiReg2[3]):1'b0; Mosi2_i = (!Ss&& (ssCnt < ssNum+LAG_i && ssCnt > LAG_i)) ? (mosiReg1[3]):1'b0; Mosi3_i = (!Ss&& (ssCnt < ssNum+LAG_i && ssCnt > LAG_i)) ? (mosiReg0[3]):1'b0; end 2 : begin Mosi0_i = (!Ss&& (ssCnt < ssNum+LAG_i && ssCnt > LAG_i)) ? (mosiReg3[5]):1'b0; Mosi1_i = (!Ss&& (ssCnt < ssNum+LAG_i && ssCnt > LAG_i)) ? (mosiReg2[5]):1'b0; Mosi2_i = (!Ss&& (ssCnt < ssNum+LAG_i && ssCnt > LAG_i)) ? (mosiReg1[5]):1'b0; Mosi3_i = (!Ss&& (ssCnt < ssNum+LAG_i && ssCnt > LAG_i)) ? (mosiReg0[5]):1'b0; end 3 : begin Mosi0_i = (!Ss&& (ssCnt < ssNum+LAG_i && ssCnt > LAG_i)) ? (mosiReg3[7]):1'b0; Mosi1_i = (!Ss&& (ssCnt < ssNum+LAG_i && ssCnt > LAG_i)) ? (mosiReg2[7]):1'b0; Mosi2_i = (!Ss&& (ssCnt < ssNum+LAG_i && ssCnt > LAG_i)) ? (mosiReg1[7]):1'b0; Mosi3_i = (!Ss&& (ssCnt < ssNum+LAG_i && ssCnt > LAG_i)) ? (mosiReg0[7]):1'b0; end endcase end else begin case (WidthSel_i) 0 : begin Mosi0_i = (!Ss&& (ssCnt < ssNum+LAG_i && ssCnt > LAG_i))? (mosiReg0[1]):1'b0; Mosi1_i = (!Ss&& (ssCnt < ssNum+LAG_i && ssCnt > LAG_i))? (mosiReg1[1]):1'b0; Mosi2_i = (!Ss&& (ssCnt < ssNum+LAG_i && ssCnt > LAG_i))? (mosiReg2[1]):1'b0; Mosi3_i = (!Ss&& (ssCnt < ssNum+LAG_i && ssCnt > LAG_i))? (mosiReg3[1]):1'b0; end 1 : begin Mosi0_i = (!Ss&& (ssCnt < ssNum+LAG_i && ssCnt > LAG_i))? (mosiReg0[3]):1'b0; Mosi1_i = (!Ss&& (ssCnt < ssNum+LAG_i && ssCnt > LAG_i))? (mosiReg1[3]):1'b0; Mosi2_i = (!Ss&& (ssCnt < ssNum+LAG_i && ssCnt > LAG_i))? (mosiReg2[3]):1'b0; Mosi3_i = (!Ss&& (ssCnt < ssNum+LAG_i && ssCnt >LAG_i))? (mosiReg3[3]):1'b0; end 2 : begin Mosi0_i = (!Ss&& (ssCnt < ssNum+LAG_i && ssCnt > LAG_i))? (mosiReg0[5]):1'b0; Mosi1_i = (!Ss&& (ssCnt < ssNum+LAG_i && ssCnt > LAG_i))? (mosiReg1[5]):1'b0; Mosi2_i = (!Ss&& (ssCnt < ssNum+LAG_i && ssCnt > LAG_i))? (mosiReg2[5]):1'b0; Mosi3_i = (!Ss&& (ssCnt < ssNum+LAG_i && ssCnt > LAG_i))? (mosiReg3[5]):1'b0; end 3 : begin Mosi0_i = (!Ss&& (ssCnt < ssNum+LAG_i && ssCnt > LAG_i))? (mosiReg0[7]):1'b0; Mosi1_i = (!Ss&& (ssCnt < ssNum+LAG_i && ssCnt > LAG_i))? (mosiReg1[7]):1'b0; Mosi2_i = (!Ss&& (ssCnt < ssNum+LAG_i && ssCnt > LAG_i))? (mosiReg2[7]):1'b0; Mosi3_i = (!Ss&& (ssCnt < ssNum+LAG_i && ssCnt > LAG_i))? (mosiReg3[7]):1'b0; end endcase end end always @(posedge Clk_i) begin if (Rst_i) begin SSr <=1'b0; end else begin SSr <= Ss; end end always @(*) begin if (SELST_i) begin if (Ss && !SSr) begin Val_o = 1'b1; end else begin Val_o = 1'b0; end end else begin if (!Ss&& SSr) begin Val_o = 1'b1; end else begin Val_o = 1'b0; end end end always @(*) begin if (Rst_i) begin startFlag = 1'b0; end else begin if (Start_i&& !stopFlag) begin startFlag = 1'b1; end else begin startFlag = 1'b0; end end end always @(*) begin if (Rst_i) begin ssNum = 1'b0; end else begin case (WidthSel_i) 0 : begin ssNum = 2; end 1 : begin ssNum = 4; end 2 : begin ssNum = 6; end 3 : begin ssNum = 8; end endcase end end always @(negedge Clk_i) begin if (Rst_i) begin ssCnt <= 1'b0; end else if (ssCnt < (ssNum+LAG_i+LEAD_i) && startFlag ) begin ssCnt <= ssCnt + 1'b1; end else begin if (ssCnt == ssNum-1 || !startFlag) begin ssCnt <= 1'b0; end end end always @(negedge Clk_i) begin if (Rst_i) begin Ss <= 1'b1; end else begin if (ssCnt < (ssNum+LAG_i+LEAD_i) && startFlag ) begin Ss <= 1'b0; end else begin Ss <= 1'b1; end end end always @(negedge Clk_i) begin if (Rst_i) begin mosiReg0 <= SPIdata[31:24]; end else begin if (!SSr && (ssCnt > LAG_i && ssCnt < ssNum + LAG_i + LEAD_i)) begin mosiReg0 <= { mosiReg0[6:0],1'b0 }; end else begin mosiReg0 <= SPIdata[31:24]; end end end always @(negedge Clk_i) begin if (Rst_i) begin mosiReg1 <= SPIdata[23:16]; end else begin if (!SSr&& (ssCnt > LAG_i && ssCnt < ssNum + LAG_i + LEAD_i)) begin mosiReg1 <= { mosiReg1[6:0],1'b0 }; end else begin mosiReg1 <= SPIdata[23:16]; end end end always @(negedge Clk_i) begin if (Rst_i) begin mosiReg2 <= SPIdata[15:8]; end else begin if (!SSr&& (ssCnt > LAG_i && ssCnt < ssNum + LAG_i + LEAD_i)) begin mosiReg2 <= { mosiReg2[6:0],1'b0 }; end else begin mosiReg2 <= SPIdata[15:8]; end end end always @(negedge Clk_i) begin if (Rst_i) begin mosiReg3 <= SPIdata[7:0]; end else begin if (!SSr&& (ssCnt > LAG_i && ssCnt < ssNum + LAG_i + LEAD_i)) begin mosiReg3 <= { mosiReg3[6:0],1'b0 }; end else begin mosiReg3 <= SPIdata[7:0]; end end end endmodule