状态机实现
module spi_m25p16 (
input sys_clk ,
input sys_rst_n ,
input key_flag ,
output reg cs_n ,
output reg sck ,
output reg mosi
);
reg [3:0] current_state , next_state ;
reg [4:0] cnt_clk ;
reg [3:0] cnt_byte ;
reg [2:0] cnt_sck ;
reg [2:0] cnt_bit ;
parameter IDLE = 4'b0001,
WREN = 4'b0010,
DELAY= 4'b0100,
BE = 4'b1000;
//状态机三段式
always @(posedge sys_clk or negedge sys_rst_n) begin
if(!sys_rst_n)
current_state <= IDLE;
else
current_state <= next_state;
end
always @(*) begin
if(!sys_rst_n)
next_state <= IDLE ;
else begin
case(current_state)
IDLE: if(key_flag == 'd1)
next_state <= WREN ;
else
next_state <= IDLE;
WREN: if (cnt_byte == 4'd2 && cnt_clk== 5'd31)
next_state <= DELAY ;
else
next_state <= WREN ;
DELAY: if (cnt_byte == 4'd3 && cnt_clk== 5'd31)
next_state <= BE ;
else
next_state <= DELAY ;
BE : if (cnt_byte == 4'd6 && cnt_clk== 5'd31)
next_state <= IDLE ;
else
next_state <= BE ;
default:
next_state <= IDLE ;
endcase
end
end
always @(posedge sys_clk or negedge sys_rst_n) begin
if(!sys_rst_n)
cnt_clk <= 5'd0;
else if (current_state != IDLE)
cnt_clk <= cnt_clk + 1'b1 ; // 32
end
//cnt_byte
always @(posedge sys_clk or negedge sys_rst_n) begin
if(!sys_rst_n)
cnt_byte <= 4'd0 ;
else if( cnt_byte == 4'd6 && cnt_clk == 5'd31) //计数到头了
cnt_byte <= 4'd0;
else if( cnt_clk == 5'd31 )
cnt_byte <= cnt_byte + 4'd1;
end
always @(posedge sys_clk or negedge sys_rst_n) begin //字节计数器 相当于 分频这这里分频
if(!sys_rst_n)
cnt_sck <= 2'd0 ;
else if( current_state == WREN && cnt_byte == 4'd1 )
cnt_sck <= cnt_sck + 2'd1 ;
else if( current_state == BE && cnt_byte == 4'd5 )
cnt_sck <= cnt_sck + 2'd1 ;
end
//cnt_bit
always @(posedge sys_clk or negedge sys_rst_n) begin //字节计数器 一个8个bit 字节的传输
if(!sys_rst_n)
cnt_bit <= 3'd0 ;
else if(cnt_sck == 2'd2)
cnt_bit <= cnt_bit + 2'd1;
end
always @(posedge sys_clk or negedge sys_rst_n) begin //字节计数器 一个8个bit 字节的传输
if(!sys_rst_n)
cs_n <= 1'b1 ; //空闲
else if( key_flag == 1'b1)
cs_n <= 1'b0 ;
else if( cnt_byte ==4'd2 && cnt_clk == 5'd31 && current_state == WREN )
cs_n <= 1'b1 ;
else if( cnt_byte ==4'd3 && cnt_clk == 5'd31 && current_state == DELAY )
cs_n <= 1'b0;
else if( cnt_byte ==4'd6 && cnt_clk == 5'd31 && current_state == BE )
cs_n <= 1'b1;
end
parameter WREN_IN = 8'b0000_0010 ,
BE_IN = 8'b1100_0111;
always @(posedge sys_clk or negedge sys_rst_n) begin //字节计数器 一个8个bit 字节的传输
if(!sys_rst_n)
mosi <= 1'b0 ;
else if( current_state == WREN && cnt_byte == 4'd2)
mosi <= 1'b0 ;
else if( current_state== BE && cnt_byte == 4'd6)
mosi <= 1'b0 ;
else if( current_state ==WREN && cnt_byte == 4'd1 && cnt_sck == 2'd0)
mosi <= WREN_IN [7 - cnt_bit] ;
else if( current_state == BE && cnt_byte == 4'd5 && cnt_sck == 2'd0)
mosi <= BE_IN [7 - cnt_bit] ;
end
always @(posedge sys_clk or negedge sys_rst_n) begin //字节计数器 一个8个bit 字节的传输
if(!sys_rst_n)
sck <= 1'b0 ;
else if ( cnt_sck == 2'd0 )
sck <= 1'b0 ;
else if ( cnt_sck == 2'd2 )
sck <= 1'b1 ;
end
endmodule