`timescale 1ns / 1ps module SPI( // input clk ,//10Mhz input miso , input[23:0] data_wr , input start , // output mosi , output[7:0] data_rd , output sck_out , output cs , //output sfl ); reg[3:0] clk_cnt ; reg[4:0] cycle_cnt ; reg[4:0] rd_cnt ; reg[7:0] data_8 ; reg mosi_reg ; reg cs_reg ; reg sck_reg ; //1Mhz //reg sfl_reg ; reg start_reg_1 ; reg start_reg_2 ; wire start_posedge ; always @ (posedge clk) begin//clk_cnt from 0 to 9 if(clk_cnt < 9) begin clk_cnt <= clk_cnt + 1 ; end else begin clk_cnt <= 0 ; end end always @ (posedge clk) begin//sck update if((clk_cnt < 4)||(clk_cnt == 9)) begin sck_reg <= 0; end else if(clk_cnt >= 4) begin sck_reg <= 1; end end always @ (posedge clk) begin//when start_posedge come,cs & SFL stay low,recover high when cycle_cnt is 24 if(start_posedge) begin if(clk_cnt == 0) begin cs_reg <= 0; //sfl_reg<= 0; end end else if(cs_reg == 0) begin if((cycle_cnt == 24) && (clk_cnt == 3)) begin cs_reg <= 1; end end else begin cs_reg <= 1; end end always @ (posedge clk) begin//cycle_cnt from 0 to 24,stay 0 when cs is high,update when sck_posedge if(cs_reg == 0) begin if(clk_cnt == 4) begin if(cycle_cnt < 24) begin cycle_cnt <= cycle_cnt + 1; end else begin cycle_cnt <= 0; end end else begin cycle_cnt <= cycle_cnt; end end else begin cycle_cnt <= 0; end end always @ (posedge clk) begin//write data[23:8] then write data[7:0] or read data_8[7:0] if(cs_reg == 0) begin if(cycle_cnt < 16) begin if(clk_cnt == 2) begin mosi_reg <= data_wr[23-cycle_cnt]; end end else if(cycle_cnt >= 16) begin if(data_wr[23] == 0) //write begin if(clk_cnt == 2) begin mosi_reg <= data_wr[23-cycle_cnt]; end end else if(data_wr[23] == 1) //read begin if(clk_cnt == 4) begin data_8[7-rd_cnt] <= miso; end end end end else begin mosi_reg <= 0; end end always @ (posedge clk) begin//rd_cnt from 0 to 7,stay 0 when cs is high or cycle_cnt is <= 15,update when sck_posedge if(cs_reg == 0) begin if(clk_cnt == 4) begin if((rd_cnt < 7) && (cycle_cnt > 15)) begin rd_cnt <= rd_cnt + 1; end else begin rd_cnt <= 0; end end else begin rd_cnt <= rd_cnt; end end else begin rd_cnt <= 0; end end always @ (posedge clk) begin//activate start_posedge,update when sck_posedge if(clk_cnt == 4) begin start_reg_1 <= start; start_reg_2 <= start_reg_1; end else begin start_reg_1 <= start_reg_1; start_reg_2 <= start_reg_2; end end assign mosi = mosi_reg ; assign data_rd = data_8 ; assign cs = cs_reg ; assign sck_out = (sck_reg &&(~cs_reg)) ; //assign sfl = 1'b0 ; assign start_posedge = start_reg_1 & (~start_reg_2) ; endmodule