module SPIm ( input Clk_i, input Rst_i, input Start_i, input EmptyFlag_i, input ClockPhase_i, input [31:0] SpiData_i, input SelSt_i, input [1:0] WidthSel_i, input Lag_i, input Lead_i, input EndianSel_i, input [5:0] Stop_i, input PulsePol_i, output reg Mosi0_o, output reg Sck_o, output Ss_o, output reg Val_o ); //================================================================================ // REG/WIRE //================================================================================ reg startFlag; reg startR; reg [31:0] trCnt; reg valReg; reg valToRxFifo1; reg lineBusy; reg [5:0] ssCnt; reg Ss; reg [31:0]spiDataR; reg oldDataFlag; reg ssR; reg SSR; reg [31:0] mosiReg0; reg [5:0] ssNum; reg [2:0] delayCnt; reg stopFlag; wire ssPol = SelSt_i ? Ss : ~Ss; //================================================================================ // ASSIGNMENTS //================================================================================ assign Ss_o = ssPol; //================================================================================ // CODING //================================================================================ always @(*) begin if (Start_i) begin Val_o = valReg; end else begin Val_o = 1'b0; end end always @(*) begin if (SelSt_i) begin if (!Ss_o) begin lineBusy = 1'b1; end else begin lineBusy = 1'b0; end end else begin if (Ss_o) begin lineBusy = 1'b1; end else begin lineBusy = 1'b0; end end end always @(posedge Clk_i) begin if (valReg) begin spiDataR <= SpiData_i; end end always @(*) begin if (Rst_i) begin oldDataFlag = 1'b0; end else begin if (spiDataR == SpiData_i && (SpiData_i != 0) || EmptyFlag_i) begin oldDataFlag = 1'b1; end else begin oldDataFlag = 1'b0; end end end always @(posedge Clk_i) begin startR <= Start_i; end always @(*) begin if (Rst_i) begin valToRxFifo1 = 1'b0; end else begin if (Start_i && !startR) begin valToRxFifo1 = 1'b1; end else begin valToRxFifo1 = 1'b0; end end end always @(negedge 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 (ssPol && !ssR) begin stopFlag <= 1'b1; end else if ( delayCnt == Stop_i) begin stopFlag <= 1'b0; end end else begin if (!ssPol && ssR) begin stopFlag <= 1'b1; end else if (delayCnt == Stop_i) begin stopFlag <= 1'b0; end end end end always @(*) begin if (SelSt_i) begin if (PulsePol_i) begin if (ClockPhase_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 (ClockPhase_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 else begin if (PulsePol_i) begin if (ClockPhase_i) begin if (Lead_i == 0) begin if (ssPol && (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 (ssPol && (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 (ssPol && (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 (ssPol && (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 (ClockPhase_i) begin if (Lead_i == 0) begin if (ssPol && (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 (ssPol && (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 (ssPol && (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 (ssPol && (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 end always @(*) begin if (Rst_i) begin Mosi0_o = 1'b0; end else begin if (SelSt_i) begin if (!EndianSel_i) begin case (WidthSel_i) 0 : begin Mosi0_o = (!Ss&& (ssCnt <= ssNum+Lag_i && ssCnt > Lag_i))? (mosiReg0[7]):1'b0; end 1 : begin Mosi0_o = (!Ss&& (ssCnt <= ssNum+Lag_i && ssCnt > Lag_i))? (mosiReg0[15]):1'b0; end 2 : begin Mosi0_o = (!Ss&& (ssCnt <= ssNum+Lag_i && ssCnt > Lag_i))? (mosiReg0[23]):1'b0; end 3 : begin Mosi0_o = (!Ss&& (ssCnt <= ssNum+Lag_i && ssCnt > Lag_i))? (mosiReg0[31]):1'b0; end endcase end else begin case (WidthSel_i) 0 : begin Mosi0_o = (!Ss&& (ssCnt <= ssNum+Lag_i && ssCnt > Lag_i))? (mosiReg0[0]):1'b0; end 1 : begin Mosi0_o = (!Ss&& (ssCnt <= ssNum+Lag_i && ssCnt > Lag_i))? (mosiReg0[0]):1'b0; end 2 : begin Mosi0_o = (!Ss&& (ssCnt <= ssNum+Lag_i && ssCnt > Lag_i))? (mosiReg0[0]):1'b0; end 3 : begin Mosi0_o = (!Ss&& (ssCnt <= ssNum+Lag_i && ssCnt > Lag_i))? (mosiReg0[0]):1'b0; end endcase end end else begin if (!EndianSel_i) begin case (WidthSel_i) 0 : begin Mosi0_o = (ssPol&& (ssCnt <= ssNum+Lag_i && ssCnt > Lag_i))? (mosiReg0[7]):1'b0; end 1 : begin Mosi0_o = (ssPol&& (ssCnt <= ssNum+Lag_i && ssCnt > Lag_i))? (mosiReg0[15]):1'b0; end 2 : begin Mosi0_o = (ssPol&& (ssCnt <= ssNum+Lag_i && ssCnt > Lag_i))? (mosiReg0[23]):1'b0; end 3 : begin Mosi0_o = (ssPol&& (ssCnt <= ssNum+Lag_i && ssCnt > Lag_i))? (mosiReg0[31]):1'b0; end endcase end else begin case (WidthSel_i) 0 : begin Mosi0_o = (ssPol&& (ssCnt <= ssNum+Lag_i && ssCnt > Lag_i))? (mosiReg0[0]):1'b0; end 1 : begin Mosi0_o = (ssPol&& (ssCnt <= ssNum+Lag_i && ssCnt > Lag_i))? (mosiReg0[0]):1'b0; end 2 : begin Mosi0_o = (ssPol&& (ssCnt <= ssNum+Lag_i && ssCnt > Lag_i))? (mosiReg0[0]):1'b0; end 3 : begin Mosi0_o = (ssPol&& (ssCnt <= ssNum+Lag_i && ssCnt > Lag_i))? (mosiReg0[0]):1'b0; end endcase end end end end always @(posedge Clk_i) begin ssR <= ssPol; SSR <= Ss; end always @(*) begin if (Rst_i) begin startFlag = 1'b0; end else begin if (Start_i && !stopFlag && !EmptyFlag_i) begin startFlag = 1'b1; end else begin startFlag = 1'b0; end end end always @(*) begin if (SelSt_i) begin if (Ss_o && !ssR) begin valReg = 1'b1; end else begin valReg = 1'b0; end end else begin if (!Ss_o&& ssR) begin valReg = 1'b1; end else begin valReg = 1'b0; end end end always @(*) begin if (Rst_i) begin ssNum = 1'b0; end else begin case (WidthSel_i) 0 : begin ssNum = 8; end 1 : begin ssNum = 16; end 2 : begin ssNum = 24; end 3 : begin ssNum = 32; 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_i[31:0]; end else begin if (!EndianSel_i) begin if (!SSR && (ssCnt > Lag_i && ssCnt < ssNum + Lag_i + Lead_i)) begin mosiReg0 <= mosiReg0 << 1; end else begin mosiReg0 <= SpiData_i[31:0]; end end else begin if (!SSR && (ssCnt > Lag_i && ssCnt < ssNum + Lag_i + Lead_i)) begin mosiReg0 <= mosiReg0 >> 1; end else begin mosiReg0 <= SpiData_i[31:0]; end end end end endmodule