标签:wire FPGA 为例 flash key output input reg
flash M25P128读操作
我们本次实验的内容是,对flash读一个字节的数据,系统框图如下:
所用到的软硬件环境为:
硬件:锆石A4plus开发板
软件:quartus II 13.1
从技术手册中我们可以得到如下信息:
从上述信息中我们可以得到:
1、一个读指令操作可以读取整个flash的数据。
2、所利用的时序仍为SPI时序
时序图设计
同样我们也对flash的擦除时序进行一定程度的更改如下:
这里的时序图画的稍微乱点,但相信同学们有了前面的基础肯定可以学会。接下来便直接上代码。
flash_read模块的书写
这里的传统不说废话,直接上代码:
`timescale 1ns / 1ps
// *********************************************************************************
// Project Name : OSXXXX
// Author : zhangningning
// Email : nnzhang1996@foxmail.com
// Website :
// Module Name : flash_read.v
// Create Time : 2020-01-09 12:52:26
// Editor : sublime text3, tab size (4)
// CopyRight(c) : All Rights Reserved
//
// *********************************************************************************
// Modification History:
// Date By Version Change Description
// -----------------------------------------------------------------------
// XXXX zhangningning 1.0 Original
//
// *********************************************************************************
module flash_read(
input sclk ,
input rst_n ,
input key_flag ,
output reg cs_n ,
output reg sck ,
output reg sdi ,
input sdo ,
output reg [ 7:0] data_out ,
output reg data_flag
);
//========================================================================================\
//**************Define Parameter and Internal Signals**********************************
//========================================================================================/
parameter READ_INST = 8'h03 ;
parameter READ_ADDR = 24'h00_03_21 ;
reg [ 4:0] cnt_32 ;
reg [ 2:0] cnt_state ;
reg [ 1:0] cnt_4 ;
reg [ 4:0] bit_cnt ;
//========================================================================================\
//************** Main Code **********************************
//========================================================================================/
always @(posedge sclk or negedge rst_n)
if(rst_n == 1'b0)
cs_n <= 1'b1;
else if(key_flag == 1'b1)
cs_n <= 1'b0;
else if(cnt_32 == 'd31 && cnt_state == 'd6)
cs_n <= 1'b1;
else
cs_n <= cs_n;
always @(posedge sclk or negedge rst_n)
if(rst_n == 1'b0)
cnt_32 <= 5'd0;
else if(cnt_32 == 'd31)
cnt_32 <= 5'd0;
else if(cs_n == 1'b0)
cnt_32 <= cnt_32 + 1'b1;
else
cnt_32 <= 5'd0;
always @(posedge sclk or negedge rst_n)
if(rst_n == 1'b0)
cnt_state <= 3'd0;
else if(cnt_state == 'd6 && cnt_32 == 'd31)
cnt_state <= 3'd0;
else if(cnt_32 == 'd31)
cnt_state <= cnt_state + 1'b1;
else
cnt_state <= cnt_state;
always @(posedge sclk or negedge rst_n)
if(rst_n == 1'b0)
cnt_4 <= 2'd0;
else if(cnt_state >= 'd1 && cnt_state <= 'd5)
cnt_4 <= cnt_4 + 1'b1;
else
cnt_4 <= 2'd0;
always @(posedge sclk or negedge rst_n)
if(rst_n == 1'b0)
sck <= 1'b0;
else if(cnt_4 == 'd0)
sck <= 1'b0;
else if(cnt_4 == 'd2)
sck <= 1'b1;
else
sck <= sck;
always @(posedge sclk or negedge rst_n)
if(rst_n == 1'b0)
sdi <= 1'b0;
else if(cnt_32 == 'd31 && cnt_state == 'd4)
sdi <= 1'b0;
else if(cnt_4 == 'd0 && cnt_state == 'd1)
sdi <= READ_INST[7-bit_cnt];
else if(cnt_4 == 'd0 &&cnt_state >= 3'd2 && cnt_state <= 3'd4)
sdi <= READ_ADDR[23-bit_cnt];
else
sdi <= sdi;
always @(posedge sclk or negedge rst_n)
if(rst_n == 1'b0)
bit_cnt <= 5'd0;
else if(cnt_32 == 'd30 && cnt_state == 3'd1)
bit_cnt <= 5'd0;
else if(cnt_32 == 'd30 && cnt_state == 3'd4)
bit_cnt <= 5'd0;
else if(cnt_4 == 'd2 && cnt_state >= 3'd1 && cnt_state <= 3'd4)
bit_cnt <= bit_cnt + 1'b1;
else
bit_cnt <= bit_cnt;
always @(posedge sclk or negedge rst_n)
if(rst_n == 1'b0)
data_out <= 8'd0;
else if(cnt_4 == 'd2 && cnt_state == 3'd5)
data_out <= {data_out[6:0],sdo};
else if(cnt_32 == 'd31 && cnt_state == 'd6)
data_out <= 8'd0;
else
data_out <= data_out;
always @(posedge sclk or negedge rst_n)
if(rst_n == 1'b0)
data_flag <= 1'b0;
else if(cnt_state == 'd5 && cnt_32 == 'd30)
data_flag <= 1'b1;
else
data_flag <= 1'b0;
endmodule
结合时序图和手册信息相信大家可以很容易理解上面代码的书写。
flash_read测试模块的代码
这里为了方便同学们调试代码,直接给出该模块的测试代码:
`timescale 1ns / 1ps
`define CLOCK 20
// *********************************************************************************
// Project Name : OSXXXX
// Author : zhangningning
// Email : nnzhang1996@foxmail.com
// Website :
// Module Name : flash_earse_tb.v
// Create Time : 2020-01-08 19:57:13
// Editor : sublime text3, tab size (4)
// CopyRight(c) : All Rights Reserved
//
// *********************************************************************************
// Modification History:
// Date By Version Change Description
// -----------------------------------------------------------------------
// XXXX zhangningning 1.0 Original
//
// *********************************************************************************
module flash_read_tb();
reg sclk ;
reg rst_n ;
reg key_flag ;
wire cs_n ;
wire sck ;
wire sdi ;
wire [ 7:0] data_out ;
wire data_flag ;
initial begin
sclk <= 1'b0;
rst_n <= 1'b0;
key_flag <= 1'b0;
#(100*`CLOCK)
rst_n <= 1'b1;
#(100*`CLOCK)
key_flag <= 1'b1;
#(`CLOCK)
key_flag <= 1'b0;
#(1000*`CLOCK)
key_flag <= 1'b1;
#(`CLOCK)
key_flag <= 1'b0;
end
always #(`CLOCK/2) sclk <= ~sclk;
flash_read flash_read_inst(
.sclk (sclk ),
.rst_n (rst_n ),
.key_flag (key_flag ),
.cs_n (cs_n ),
.sck (sck ),
.sdi (sdi ),
.sdo (1'b1 ),
.data_out (data_out ),
.data_flag (data_flag )
);
endmodule
其他模块的代码
为了方便同学们可以直接使用该代码,这里我们将所有的代码复制如下,整体的工程也可以进群自取:
key模块代码:
`timescale 1ns / 1ps
// *********************************************************************************
// Project Name : OSXXXX
// Author : zhangningning
// Email : nnzhang1996@foxmail.com
// Website :
// Module Name : key.v
// Create Time : 2020-01-05 13:49:36
// Editor : sublime text3, tab size (4)
// CopyRight(c) : All Rights Reserved
//
// *********************************************************************************
// Modification History:
// Date By Version Change Description
// -----------------------------------------------------------------------
// XXXX zhangningning 1.0 Original
//
// *********************************************************************************
module key(
input sclk ,
input rst_n ,
input key ,
output reg key_o
);
//========================================================================================\
//**************Define Parameter and Internal Signals**********************************
//========================================================================================/
parameter IDLE = 4'b0001 ;
parameter S1 = 4'b0010 ;
parameter S2 = 4'b0100 ;
parameter S3 = 4'b1000 ;
reg [ 3:0] state ;
reg [ 9:0] cnt ;
reg key_r1 ;
reg key_r2 ;
reg key_r3 ;
reg nege_flag ;
reg pose_flag ;
//========================================================================================\
//************** Main Code **********************************
//========================================================================================/
always @(posedge sclk)
key_r1 <= key;
always @(posedge sclk)
key_r2 <= key_r1;
always @(posedge sclk)
key_r3 <= key_r2;
always @(posedge sclk or negedge rst_n)
if(rst_n == 1'b0)
nege_flag <= 1'b0;
else if(key_r3 == 1'b1 && key_r2 == 1'b0)
nege_flag <= 1'b1;
else
nege_flag <= 1'b0;
always @(posedge sclk or negedge rst_n)
if(rst_n == 1'b0)
pose_flag <= 1'b0;
else if(key_r3 == 1'b0 && key_r2 == 1'b1)
pose_flag <= 1'b1;
else
pose_flag <= 1'b0;
always @(posedge sclk or negedge rst_n)
if(rst_n == 1'b0)
state <= IDLE;
else case(state)
IDLE : if(nege_flag == 1'b1)
state <= S1;
else
state <= IDLE;
S1 : if(cnt == 10'd999)
state <= S2;
else if(pose_flag == 1'b1)
state <= IDLE;
else
state <= S1;
S2 : if(pose_flag == 1'b1)
state <= S3;
else
state <= S2;
S3 : if(cnt == 10'd999)
state <= IDLE;
else if(nege_flag == 1'b1)
state <= S2;
else
state <= S3;
default : state <= IDLE;
endcase
always @(posedge sclk or negedge rst_n)
if(rst_n == 1'b0)
cnt <= 10'd0;
else if(state != S1 && state != S3)
cnt <= 10'd0;
else
cnt <= cnt + 1'b1;
always @(posedge sclk or negedge rst_n)
if(rst_n == 1'b0)
key_o <= 1'b0;
else if(state == S1 && cnt == 10'd999)
key_o <= 1'b1;
else
key_o <= 1'b0;
endmodule
top模块:
`timescale 1ns / 1ps
// *********************************************************************************
// Project Name : OSXXXX
// Author : zhangningning
// Email : nnzhang1996@foxmail.com
// Website :
// Module Name : top.v
// Create Time : 2020-01-08 21:18:52
// Editor : sublime text3, tab size (4)
// CopyRight(c) : All Rights Reserved
//
// *********************************************************************************
// Modification History:
// Date By Version Change Description
// -----------------------------------------------------------------------
// XXXX zhangningning 1.0 Original
//
// *********************************************************************************
module top(
input sclk ,
input rst_n ,
input key ,
output wire cs_n ,
output wire sck ,
output wire sdi ,
input sdo ,
output reg [ 7:0] led
);
//========================================================================================\
//**************Define Parameter and Internal Signals**********************************
//========================================================================================/
wire key_flag ;
wire [ 7:0] data_out ;
wire data_flag ;
//========================================================================================\
//************** Main Code **********************************
//========================================================================================/
always @(posedge sclk or negedge rst_n)
if(rst_n == 1'b0)
led <= 8'd0;
else if(data_flag == 1'b1)
led <= data_out;
else
led <= led;
key key_inst(
.sclk (sclk ),
.rst_n (rst_n ),
.key (~key ),
.key_o (key_flag )
);
flash_read flash_read_inst(
.sclk (sclk ),
.rst_n (rst_n ),
.key_flag (key_flag ),
.cs_n (cs_n ),
.sck (sck ),
.sdi (sdi ),
.sdo (sdo ),
.data_out (data_out ),
.data_flag (data_flag )
);
endmodule
实验结果
这里的实验结果就是我们把上一篇文章中写入flash的数据读出并且显示再led上面,实验结果证明了我们flash读写操作的正确性。
结束语
创作不易,认为文章有帮助的同学们可以收藏点赞支持。(工程也都在群中)对文章有什么看法或者需要更近一步交流的同学,可以加入下面的群:
标签:wire,FPGA,为例,flash,key,output,input,reg 来源: https://blog.csdn.net/zhangningning1996/article/details/103935670
本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享; 2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关; 3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关; 4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除; 5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。