当前位置:网站首页>07-SDRAM :FIFO控制模块
07-SDRAM :FIFO控制模块
2022-08-01 23:59:00 【刘颜儿】
设计文件
// fifo控制模块
// 1. sdram_wr_ack_d1、sdram_wr_ack_d2: 对 sdram_wr_ack 打2拍
// 2. sdram_wr_ack_fall: wr_ack 的下降沿
// 3. sdram_rd_ack_d1、sdram_rd_ack_d2: 对 sdram_rd_ack 打2拍
// 4. sdram_rd_ack_fall: rd_ack 的下降沿
// 5. wr_fifo_num: 写FIFO数据的个数
module fifo_ctrl(
input wire sdram_clk , //sdram时钟——100M
input wire sdram_rst_n , //sdram复位信号
//写fifo信号
input wire wr_fifo_wr_clk , //写FIFO写时钟——50M
input wire wr_fifo_rst , //写复位信号
input wire wr_fifo_wr_req , //写FIFO写请求
input wire [15:0] wr_fifo_wr_data , //写FIFO写数据
input wire [23:0] sdram_wr_b_addr , //写SDRAM首地址
input wire [23:0] sdram_wr_e_addr , //写SDRAM末地址
input wire [9:0] wr_burst_len , //写SDRAM数据突发长度
output wire [9:0] wr_fifo_num , //写fifo中的数据量
//读fifo信号
input wire rd_fifo_rd_clk , //读FIFO读时钟
input wire rd_fifo_rd_req , //读FIFO读请求
input wire [23:0] sdram_rd_b_addr , //读SDRAM首地址
input wire [23:0] sdram_rd_e_addr , //读SDRAM末地址
input wire [9:0] rd_burst_len , //读SDRAM数据突发长度
input wire rd_fifo_rst , //读复位信号
output wire [15:0] rd_fifo_rd_data , //读FIFO读数据
output wire [9:0] rd_fifo_num , //读fifo中的数据量
input wire read_valid , //SDRAM读使能
input wire init_end , //SDRAM初始化完成标志
//SDRAM写信号
input wire sdram_wr_ack , //SDRAM写响应
output reg sdram_wr_req , //SDRAM写请求
output reg [23:0] sdram_wr_addr , //SDRAM写地址
output wire [15:0] sdram_data_in , //写入SDRAM的数据
//SDRAM读信号
input wire sdram_rd_ack , //SDRAM响应
input wire [15:0] sdram_data_out , //读出SDRAM数据
output reg sdram_rd_req , //SDRAM读请求
output reg [23:0] sdram_rd_addr //SDRAM读地址
);
//==========================================parameter===========================================================
//==========================================reg=================================================================
reg sdram_wr_ack_d1 ; //写响应打1拍
reg sdram_wr_ack_d2 ; //写响应打2拍
reg sdram_rd_ack_d1 ; //读响应打1拍
reg sdram_rd_ack_d2 ; //读响应打2拍
//==========================================wire=================================================================
wire sdram_wr_ack_fall ; //写响应信号下降沿
wire sdram_rd_ack_fall ; //读响应信号下降沿
//==========================================assign=================================================================
//sdram_wr_ack_fall,sdram_rd_ack_fall:检测读写响应信号下降沿
assign sdram_wr_ack_fall = (sdram_wr_ack_d2 & ~sdram_wr_ack_d1);
assign sdram_rd_ack_fall = (sdram_rd_ack_d2 & ~sdram_rd_ack_d1);
//==========================================always=================================================================
//wr_ack_dly:写响应信号打拍,采集下降沿
[email protected](posedge sdram_clk or negedge sdram_rst_n)begin
if(!sdram_rst_n)begin
sdram_wr_ack_d1 <= 1'b0;
sdram_wr_ack_d2 <= 1'b0;
end
else begin
sdram_wr_ack_d1 <= sdram_wr_ack;
sdram_wr_ack_d2 <= sdram_wr_ack_d1;
end
end
//rd_ack_dly:读响应信号打拍,采集下降沿
[email protected](posedge sdram_clk or negedge sdram_rst_n)begin
if(!sdram_rst_n)begin
sdram_rd_ack_d1 <= 1'b0;
sdram_rd_ack_d2 <= 1'b0;
end
else begin
sdram_rd_ack_d1 <= sdram_rd_ack;
sdram_rd_ack_d2 <= sdram_rd_ack_d1;
end
end
//sdram_wr_addr:sdram写地址
[email protected](posedge sdram_clk or negedge sdram_rst_n)begin
if(!sdram_rst_n)
sdram_wr_addr <= 24'd0;
else if(wr_fifo_rst)
sdram_wr_addr <= sdram_wr_b_addr; //复位fifo则地址为初始地址
else if(sdram_wr_ack_fall) //一次突发写结束,更改写地址
begin
if(sdram_wr_addr < (sdram_wr_e_addr - wr_burst_len)) // SDRAM中一次突发写完成后,开始写下一行,于是地址就是,+突发长度 来表示
sdram_wr_addr <= sdram_wr_addr + wr_burst_len; //未达到末地址,写地址累加
else
sdram_wr_addr <= sdram_wr_b_addr; //到达末地址,回到写起始地址
end
end
//sdram_rd_addr:sdram读地址
[email protected](posedge sdram_clk or negedge sdram_rst_n)begin
if(!sdram_rst_n)
sdram_rd_addr <= 24'd0;
else if(rd_fifo_rst)
sdram_rd_addr <= sdram_rd_b_addr;
else if(sdram_rd_ack_fall) //一次突发读结束,更改读地址
begin
if(sdram_rd_addr < (sdram_rd_e_addr - rd_burst_len))
sdram_rd_addr <= sdram_rd_addr + rd_burst_len; //读地址未达到末地址,读地址累加
else
sdram_rd_addr <= sdram_rd_b_addr; //到达末地址,回到首地址
end
end
//sdram_wr_req,sdram_rd_req:读写请求信号
[email protected](posedge sdram_clk or negedge sdram_rst_n)begin
if(!sdram_rst_n)
begin
sdram_wr_req <= 1'b0;
sdram_rd_req <= 1'b0;
end
else if(init_end) //初始化完成后响应读写请求
begin //优先执行写操作,防止写入SDRAM中的数据丢失
if(wr_fifo_num >= wr_burst_len)begin //写FIFO中的数据量达到写突发长度
sdram_wr_req <= 1'b1; //写请求有效
sdram_rd_req <= 1'b0;
end
else if((rd_fifo_num < rd_burst_len) && (read_valid))begin //读FIFO中的数据量小于读突发长度,且读使能信号有效
sdram_wr_req <= 1'b0;
sdram_rd_req <= 1'b1; //读请求有效
end
else begin
sdram_wr_req <= 1'b0;
sdram_rd_req <= 1'b0;
end
end
else begin
sdram_wr_req <= 1'b0;
sdram_rd_req <= 1'b0;
end
end
//==========================================状态机=================================================================
//==========================================模块例化=================================================================
//------------- wr_fifo_data -------------
fifo_data wr_fifo_data(
//用户接口
.wrclk (wr_fifo_wr_clk ), //写时钟
.wrreq (wr_fifo_wr_req ), //写请求
.data (wr_fifo_wr_data), //写数据
//SDRAM接口
.rdclk (sdram_clk ), //读时钟
.rdreq (sdram_wr_ack ), //读请求
.q (sdram_data_in ), //读数据
.rdusedw (wr_fifo_num ), //FIFO中的数据量
.wrusedw ( ),
.aclr (~sdram_rst_n || wr_fifo_rst) //清零信号
);
//------------- rd_fifo_data -------------
fifo_data rd_fifo_data(
//sdram接口
.wrclk (sdram_clk ), //写时钟
.wrreq (sdram_rd_ack ), //写请求
.data (sdram_data_out ), //写数据
//用户接口
.rdclk (rd_fifo_rd_clk ), //读时钟
.rdreq (rd_fifo_rd_req ), //读请求
.q (rd_fifo_rd_data), //读数据
.rdusedw ( ),
.wrusedw (rd_fifo_num ), //FIFO中的数据量
.aclr (~sdram_rst_n || rd_fifo_rst) //清零信号
);
endmodule
边栏推荐
猜你喜欢
随机推荐
如何进行数据库备份
security跨域配置
recursion: method calls itself
如何用Redis实现分布式锁?
在MySQL登录时出现Access denied for user ‘root‘@‘localhost‘ (using password YES) 拒绝访问问题解决
控制电机的几种控制电路原理图
Architecture basic concept and nature of architecture
QML包管理
【MySQL系列】MySQL索引事务
CDH6 Hue to open a "ASCII" codec can 't encode characters
Excel表格数据导入MySQL数据库
2022 6th Strong Net Cup Part WP
OpenCV DNN blogFromImage() detailed explanation
How to reinstall Win11?One-click method to reinstall Win11
cdh的hue上oozie启动报错,Cannot allocate containers as requested resource is greater than maximum allowed
TexturePacker使用文档
学习英语的网站与资料
@Resource和@Autowired的区别
LeetCode_279_完全平方数
不就是个TCC分布式事务,有那么难吗?