| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205 |
- `timescale 1ns / 1ps
- module ExtSpiMEmul
- (
- input Rst_i,
- input Clk_i,
-
- input Start_i,
- output TxDone_o,
-
- output Sck_o,
- output reg Ss_o,
- output reg Mosi_o
-
- );
- //================================================================================
- // PARAMETERS
- localparam [1:0] IDLE = 0;
- localparam [1:0] CMD = 1;
- localparam [1:0] TX = 2;
- localparam [1:0] PAUSE = 3;
- parameter MODE = 1'h0;
- parameter [4:0] DEVID = 5'h1;
- parameter [16:0] WORDSNUM = 17'h3;
- parameter EOPBIT = 1'b1;
-
- //================================================================================
- // REG/WIRE
- reg [1:0] currState;
- reg [1:0] nextState;
-
- reg [6:0] txCnt;
- reg [6:0] cmdCnt;
- reg [3:0] pauseCnt;
- wire txStop = (cmdCnt >= WORDSNUM+1);
-
- reg [23:0] headerCmd = {MODE,DEVID,WORDSNUM,EOPBIT};
- reg [23:0] spiData;
-
- reg [23:0] dspSpiData;
-
- reg sckFlag;
- //================================================================================
- // ASSIGNMENTS
- assign Sck_o = (sckFlag)? ~Clk_i:1'b1;
- assign TxDone_o = (txStop & (currState== CMD));
- //================================================================================
- // CODING
- always @(posedge Clk_i) begin
- if (!Rst_i) begin
- if (currState == CMD) begin
- if (!txStop) begin
- cmdCnt <= cmdCnt+1;
- end else begin
- cmdCnt <= 0;
- end
- end
- end else begin
- cmdCnt <= 0;
- end
- end
- always @(posedge Clk_i) begin
- if (!Rst_i) begin
- if (currState == TX) begin
- txCnt <= txCnt+1;
- end else begin
- txCnt <= 0;
- end
- end else begin
- txCnt <= 0;
- end
- end
- always @(posedge Clk_i) begin
- if (!Rst_i) begin
- if (currState == PAUSE) begin
- pauseCnt <= pauseCnt+1;
- end else begin
- pauseCnt <= 0;
- end
- end else begin
- pauseCnt <= 0;
- end
- end
-
- always @(posedge Clk_i) begin
- if (!Rst_i) begin
- if (currState == CMD) begin
- spiData <= spiData+cmdCnt;
- end
- end else begin
- spiData <= 24'hab;
- end
- end
- always @(posedge Clk_i) begin
- if (currState == CMD) begin
- if (cmdCnt == 0) begin
- dspSpiData <= headerCmd;
- end else begin
- dspSpiData <= spiData;
- end
- end else if (currState == TX) begin
- dspSpiData <= dspSpiData<<1;
- end if (currState == IDLE) begin
- dspSpiData <= 0;
- end
- end
- always @(posedge Clk_i) begin
- if (currState == TX) begin
- if (txCnt >= 7'd0) begin
- Mosi_o <= dspSpiData[23];
- end else begin
- Mosi_o <= 1'b1;
- end
- end else begin
- Mosi_o <= 1'b1;
- end
- end
- always @(posedge Clk_i) begin
- if (currState == TX) begin
- Ss_o <= 1'b0;
- sckFlag <= 1'b1;
- end else begin
- Ss_o <= 1'b1;
- sckFlag <= 1'b0;
- end
- end
- always @(posedge Clk_i) begin
- if (Rst_i) begin
- currState <= IDLE;
- end else begin
- currState <= nextState;
- end
- end
- always @(*) begin
- nextState = IDLE;
- case(currState)
- IDLE : begin
- if (Start_i) begin
- nextState = CMD;
- end else begin
- nextState = IDLE;
- end
- end
-
- CMD : begin
- if (!txStop) begin
- nextState = TX;
- end else begin
- nextState = IDLE;
- end
- end
- TX : begin
- if (txCnt==6'd23) begin
- nextState = PAUSE;
- end else begin
- nextState = TX;
- end
- end
-
- PAUSE : begin
- if (pauseCnt==4'd2) begin
- nextState = CMD;
- end else begin
- nextState = PAUSE;
- end
- end
- endcase
- end
- endmodule
|