读Manufacturer / Device ID (90h):先发送命令字90,再发送24位的地址(全0),然后接收2个byte的数据(第一个数据是Manufacturor:FEh,第二个是设备的Device ID:17h)。数据在时钟的上升沿采样。
`timescale 1ns / 1ps
//
// Company:
// Engineer:
//
// Create Date: 2019/09/04 19:06:31
// Design Name:
// Module Name: top
// Project Name:
// Target Devices:
// Tool Versions:
// Description:
//
// Dependencies:
//
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
//
//
module top(
input CLK,
input RSTn,
output flash_clk,
output flash_cs,
output flash_datain,
input flash_dataout,
output [3:0] led
);
reg [3:0] led_r;
reg [2:0] state;
reg is_start;
wire is_done;
reg [7:0] cmd;
reg [23:0] addr;
wire [15:0] rec_data_o;
reg [27:0] cnt;
always @(posedge CLK or negedge RSTn)
begin
if(!RSTn) begin
state <= 3'd0;
cmd <= 8'd0;
addr <= 24'd0;
is_start <= 1'd0;
cnt <= 28'd0;
end
else begin
case(state)
3'd0: begin
if(cnt == 28'hfffffff) begin
cnt <= 28'd0;
state <= state + 3'd1;
end
else begin
cnt <= cnt + 28'd1;
end
end
3'd1: begin
if(is_done) begin
is_start <= 1'd0;
state <= state + 3'd1;
led_r <= rec_data_o[3:0];
end
else begin
is_start <= 1'd1;
cmd <= 8'h90;
addr <= 24'h0;
end
end
endcase
end
end
assign led = led_r;
spi spi_inst(
.CLK(CLK),
.RSTn(RSTn),
.flash_clk(flash_clk),
.flash_cs(flash_cs),
.flash_datain(flash_datain),
.flash_dataout(flash_dataout),
.is_start(is_start),
.is_done(is_done),
.cmd(cmd),
.addr(addr),
.rec_data_o(rec_data_o)
);
endmodule
`timescale 1ns / 1ps
//
// Company:
// Engineer:
//
// Create Date: 2019/09/09 21:21:01
// Design Name:
// Module Name: spi
// Project Name:
// Target Devices:
// Tool Versions:
// Description:
//
// Dependencies:
//
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
//
//
module spi(
input CLK,
input RSTn,
output reg flash_clk,
output reg flash_cs,
output reg flash_datain,
input flash_dataout,
input is_start,
output reg is_done,
input [7:0] cmd,
input [23:0] addr,
output reg [15:0] rec_data_o
);
reg [5:0] state;
reg [3:0] cnt;
reg is_clk;
always @(posedge CLK or negedge RSTn)
begin
if(!RSTn) begin
state <= 6'd0;
cnt <= 4'd0;
is_clk <= 1'd0;
is_done <= 1'd0;
flash_cs <= 1'd1;
end
else if(is_start) begin
case(state)
6'd0: begin
cnt <= 4'd0;
flash_cs <= 1'd0;
is_done <= 1'd0;
is_clk <= 1'd1;
flash_datain <= cmd[6'd7 - state];
state <= state + 6'd1;
end
6'd1, 6'd2, 6'd3, 6'd4, 6'd5, 6'd6, 6'd7: begin
flash_cs <= 1'd0;
is_done <= 1'd0;
is_clk <= 1'd1;
if(cnt == 4'd1) begin
cnt <= 4'd0;
state <= state + 6'd1;
flash_datain <= cmd[6'd7 - state];
end
else begin
cnt <= cnt + 4'd1;
end
end
6'd8, 6'd9, 6'd10, 6'd11, 6'd12, 6'd13, 6'd14, 6'd15, 6'd16, 6'd17, 6'd18,
6'd19, 6'd20, 6'd21, 6'd22, 6'd23, 6'd24, 6'd25, 6'd26, 6'd27, 6'd28,
6'd29, 6'd30, 6'd31: begin
is_clk <= 1'd1;
if(cnt == 4'd1) begin
cnt <= 4'd0;
state <= state + 6'd1;
flash_datain <= addr[6'd31 - state];
end
else begin
cnt <= cnt + 4'd1;
end
end
6'd32: begin
if(cnt == 4'd1) begin
cnt <= 4'd0;
state <= state + 6'd1;
end
else begin
cnt <= cnt + 4'd1;
end
end
6'd33, 6'd34, 6'd35, 6'd36, 6'd37, 6'd38, 6'd39,
6'd40, 6'd41, 6'd42, 6'd43, 6'd44, 6'd45, 6'd46, 6'd47: begin
if(cnt == 4'd1) begin
cnt <= 4'd0;
state <= state + 6'd1;
//flash_cs <= 1'd1;
end
else begin
cnt <= cnt + 4'd1;
rec_data_o <= {rec_data_o[14:0], flash_dataout};
end
end
6'd48: begin
if(cnt == 4'd1) begin
cnt <= 4'd0;
state <= state + 6'd1;
flash_cs <= 1'd1;
is_clk <= 1'd0;
end
else begin
cnt <= cnt + 4'd1;
rec_data_o <= {rec_data_o[14:0], flash_dataout};
end
end
6'd49: begin
is_clk <= 1'd0;
is_done <= 1'd1;
flash_cs <= 1'd1;
state <= state + 6'd1;
end
6'd50: begin
is_done <= 1'd0;
state <= 6'd0;
end
endcase
end
end
always @(posedge CLK or negedge RSTn)
begin
if(!RSTn) flash_clk <= 1'd0;
else if(is_clk) flash_clk <= ~flash_clk;
end
endmodule