RDID
rdid即读电子签名,下图为rdid的时序图,代码通过线性序列机的方式实现。
因为m25p16手册中要求上升沿采样,可以采用spi的00和11模式,本文采用00模式,scl初始值为0。
(spi的四种模式可见https://blog.csdn.net/weixin_42263208/article/details/108803254),
RDID时序代码
module flash_rdid (
input wire clk,
input wire rst_n,
output reg flash_scl,
output reg flash_d,
output reg flash_cs_n,
input wire flash_q,
output reg q
);
localparam RDID = 8'h9f;
localparam T_half = 5;
always @ (posedge clk) q <= flash_q;
reg [8:0] cnt;
always @ (posedge clk) begin
if (rst_n == 0)
cnt <= 0;
else if(cnt == 321)
cnt <= cnt;
else
cnt <= cnt + 1'b1;
end
always @ (*) begin
if (rst_n == 0) begin flash_scl = 0; flash_d = 0;flash_cs_n = 1;end
else
case (cnt)
0 : begin flash_cs_n = 1;flash_scl = 0;flash_d = 0;end
1 : begin flash_cs_n = 0;flash_d = RDID[7];end
1 + T_half * 1 : begin flash_scl = 1;end
1 + T_half * 2 : begin flash_scl = 0;flash_d = RDID[6];end
1 + T_half * 3 : begin flash_scl = 1;end
1 + T_half * 4 : begin flash_scl = 0;flash_d = RDID[5];end
1 + T_half * 5 : begin flash_scl = 1;end
1 + T_half * 6 : begin flash_scl = 0;flash_d = RDID[4];end
1 + T_half * 7 : begin flash_scl = 1;end
1 + T_half * 8 : begin flash_scl = 0;flash_d = RDID[3];end
1 + T_half * 9 : begin flash_scl = 1;end
1 + T_half * 10 : begin flash_scl = 0;flash_d = RDID[2];end
1 + T_half * 11 : begin flash_scl = 1;end
1 + T_half * 12 : begin flash_scl = 0;flash_d = RDID[1];end
1 + T_half * 13 : begin flash_scl = 1;end
1 + T_half * 14 : begin flash_scl = 0;flash_d = RDID[0];end
1 + T_half * 15 : begin flash_scl = 1;end
1 + T_half * 16 : begin flash_scl = 0;flash_d = 0;end
1 + T_half * 17 : begin flash_scl = 1;end
1 + T_half * 18 : begin flash_scl = 0;end
1 + T_half * 19 : begin flash_scl = 1;end
1 + T_half * 20 : begin flash_scl = 0;end
1 + T_half * 21 : begin flash_scl = 1;end
1 + T_half * 22 : begin flash_scl = 0;end
1 + T_half * 23 : begin flash_scl = 1;end
1 + T_half * 24 : begin flash_scl = 0;end
1 + T_half * 25 : begin flash_scl = 1;end
1 + T_half * 26 : begin flash_scl = 0;end
1 + T_half * 27 : begin flash_scl = 1;end
1 + T_half * 28 : begin flash_scl = 0;end
1 + T_half * 29 : begin flash_scl = 1;end
1 + T_half * 30 : begin flash_scl = 0;end
1 + T_half * 31 : begin flash_scl = 1;end
1 + T_half * 32 : begin flash_scl = 0;end
1 + T_half * 33 : begin flash_scl = 1;end
1 + T_half * 34 : begin flash_scl = 0;end
1 + T_half * 35 : begin flash_scl = 1;end
1 + T_half * 36 : begin flash_scl = 0;end
1 + T_half * 37 : begin flash_scl = 1;end
1 + T_half * 38 : begin flash_scl = 0;end
1 + T_half * 39 : begin flash_scl = 1;end
1 + T_half * 40 : begin flash_scl = 0;end
1 + T_half * 41 : begin flash_scl = 1;end
1 + T_half * 42 : begin flash_scl = 0;end
1 + T_half * 43 : begin flash_scl = 1;end
1 + T_half * 44 : begin flash_scl = 0;end
1 + T_half * 45 : begin flash_scl = 1;end
1 + T_half * 46 : begin flash_scl = 0;end
1 + T_half * 47 : begin flash_scl = 1;end
1 + T_half * 48 : begin flash_scl = 0;end
1 + T_half * 49 : begin flash_scl = 1;end
1 + T_half * 50 : begin flash_scl = 0;end
1 + T_half * 51 : begin flash_scl = 1;end
1 + T_half * 52 : begin flash_scl = 0;end
1 + T_half * 53 : begin flash_scl = 1;end
1 + T_half * 54 : begin flash_scl = 0;end
1 + T_half * 55 : begin flash_scl = 1;end
1 + T_half * 56 : begin flash_scl = 0;end
1 + T_half * 57 : begin flash_scl = 1;end
1 + T_half * 58 : begin flash_scl = 0;end
1 + T_half * 59 : begin flash_scl = 1;end
1 + T_half * 60 : begin flash_scl = 0;end
1 + T_half * 61 : begin flash_scl = 1;end
1 + T_half * 62 : begin flash_scl = 0;end
1 + T_half * 63 : begin flash_scl = 1;end
1 + T_half * 64 : begin flash_scl = 0;flash_cs_n = 1;end
default : ;
endcase
end
endmodule
仿真代码
`timescale 1ns/1ps
module flash_rdid_tb;
reg clk;
reg rst_n;
wire flash_cs_n;
wire flash_d;
wire flash_scl;
wire flash_q;
wire q;
flash_rdid flash_rdid_inst(
.clk (clk),
.rst_n (rst_n),
.flash_scl (flash_scl),
.flash_d (flash_d),
.flash_cs_n (flash_cs_n),
.flash_q (flash_q),
.q (q)
);
m25p16 m25p16_inst(
.c (flash_scl),
.data_in (flash_d),
.s (flash_cs_n),
.w (1'b1),
.hold (1'b1),
.data_out (flash_q)
);
initial clk = 1;
always #10 clk = ~clk;
initial begin
rst_n = 0;
#201
rst_n = 1;
repeat (500)
@ (posedge clk);
#200
$stop;
end
endmodule
仿真图
完整工程:https://download.csdn.net/download/weixin_42263208/12890066
M25P16仿真模型文件:https://download.csdn.net/download/weixin_42263208/12889963