module spi_read(
input clk, //system clock:50M
input rst,
output reg cs, //chip select
output reg sck, //chip clock:50K
input din, //DO
output reg dout, //DI
input rflag, //read enable
output reg[7:0] data
);
//general chip clock:50K
/*reg temp;
reg[9:0] count;
always@(posedge clk or posedge rst)
if(rst) begin count <= 10'd0; temp <= 1'b0; end
else
begin
count <= count+1'b1;
if(count == 10'd999) begin temp <= 1'b1; count <= 10'd0; end
else if(count == 10'd499) temp <= 1'b0;
end
assign sck = temp;
`define high (count == 10'd999) // 时钟上升沿
`define low (count == 10'd499)*/ // 时钟下降沿
reg[9:0] count;
always@(posedge clk or posedge rst)
if(rst)
begin
count <= 10'd0;
sck <= 1'b0;
end
else if(count >= 10'd499)
begin
count <= 10'd0;
sck <= ~sck;
end
else count <= count+1'b1;
//capture posedge and negedge of sck
reg sck_m;
wire high;
wire low;
always@(posedge clk or posedge rst)
if(rst) sck_m <= 1'b0;
else sck_m <= sck;
assign high = ~sck_m & sck;
assign low = sck_m & ~sck;
//start read
reg[7:0] rstate;
//reg[7:0] data;
always@(posedge clk or posedge rst)
begin
if(rst)
begin
rstate <= 8'd0;
cs <= 1'b0;
dout <= 1'b0;
data <= 8'd0;
end
else
begin
case(rstate)
6'd0: begin
if(rflag)
begin
rstate <= 6'd1;
cs <= 1'b1;
dout <= 1'b0;
end
else
begin
rstate <= 1'b0;
cs <= 1'b0;
dout <= 1'b0;
end
end
6'd1: begin
if(low) begin rstate <= 6'd2; dout <= 1'b1; cs <= 1'b1; end //SB=1
else begin rstate <= 6'd1; end
end
6'd2: begin
if(low) begin rstate <= 6'd3; dout <= 1'b1; cs <= 1'b1; end //OP0=1
else begin rstate <= 6'd2; end
end
6'd3: begin
if(low) begin rstate <= 6'd4; dout <= 1'b0; cs <= 1'b1; end //OP1=0
else begin rstate <= 6'd3; end
end
6'd4: begin
if(low) begin rstate <= 6'd5; dout <= 1'b0; cs <= 1'b1; end //A6=0
else begin rstate <= 6'd4; end
end
6'd5: begin
if(low) begin rstate <= 6'd6; dout <= 1'b0; cs <= 1'b1; end //A5=0
else begin rstate <= 6'd5; end
end
6'd6: begin
if(low) begin rstate <= 6'd7; dout <= 1'b0; cs <= 1'b1; end //A4=0
else begin rstate <= 6'd6; end
end
6'd7: begin
if(low) begin rstate <= 6'd8; dout <= 1'b0; cs <= 1'b1; end //A3=0
else begin rstate <= 6'd7; end
end
6'd8: begin
if(low) begin rstate <= 6'd9; dout <= 1'b1; cs <= 1'b1; end //A2=1
else begin rstate <= 6'd8; end
end
6'd9: begin
if(low) begin rstate <= 6'd10; dout <= 1'b0; cs <= 1'b1; end //A1=0
else begin rstate <= 6'd9; end
end
6'd10: begin
if(low) begin rstate <= 6'd11; dout <= 1'b1; cs <= 1'b1; end //A0=1
else begin rstate <= 6'd10; end
end
6'd11: begin
if(!din) begin rstate <= 6'd12; cs <= 1'b1; end //
else begin rstate <= 6'd11; end
end
6'd12: begin
if(low) begin rstate <= 6'd13; cs <= 1'b1; end //invalid
else begin rstate <= 6'd12; end
end
6'd13: begin
if(low) begin rstate <= 6'd14; data[7] <= din; cs <= 1'b1; end //D7
else begin rstate <= 6'd13; end
end
6'd14: begin
if(low) begin rstate <= 6'd15; data[6] <= din; cs <= 1'b1; end //D6
else begin rstate <= 6'd14; end
end
6'd15: begin
if(low) begin rstate <= 6'd16; data[5] <= din; cs <= 1'b1; end //D5
else begin rstate <= 6'd15; end
end
6'd16: begin
if(low) begin rstate <= 6'd17; data[4] <= din; cs <= 1'b1; end //D4
else begin rstate <= 6'd16; end
end
6'd17: begin
if(low) begin rstate <= 6'd18; data[3] <= din; cs <= 1'b1; end //D3
else begin rstate <= 6'd17; end
end
6'd18: begin
if(low) begin rstate <= 6'd19; data[2] <= din; cs <= 1'b1; end //D2
else begin rstate <= 6'd18; end
end
6'd19: begin
if(low) begin rstate <= 6'd20; data[1] <= din; cs <= 1'b1; end //D1
else begin rstate <= 6'd19; end
end
6'd20: begin
if(low) begin rstate <= 6'd21; data[0] <= din; cs <= 1'b1; end //D0
else begin rstate <= 6'd20; end
end
6'd21: begin
if(low) begin rstate <= 6'd22; cs <= 1'b0; end //数据读完,拉低CS
else begin rstate <= 6'd21; end
end
6'd22: begin
if(low) begin rstate <= 6'd0; end //stop
else begin rstate <= 6'd22; end
end
endcase
end
end
//assign data_out = data;
endmodule