如果是简单的FIFO和自己写的FIFO是差不多 使用IP核最大的好处是可以加速设计进度吧
而且fpga厂商应该更了解自己的fpga架构 从而写出更优化的程序 我个人觉得....
复杂的还是有区别的吧 比如异步的FIFO什么的 第一次写也挺麻烦的
#120 cis_0 = 10'h155#20 wr = 1
//cis_0 = 10'h155保持了520ns,写时钟周期是120ns ,写入4个10'h155,之后 cis_0 = 10'h0
写入10‘h0
#500 cis_0 = 10'h0
# 90 rd =1
#100
//rd持续100ns,读时钟周期是40ns,可以读出2个数据,应该是10'h155、10'h155
你的Testbench写得不太好,数据少,时钟周期大。时间短。
建议:1.写频率要比读频率大,可以写时钟取10ns,读时钟取20ns。
2.输入数据采取随机形式,方便观察,也省事,用always #10 cis_0 = {$random}%1024
3.测试时间取大点,用initial 。。。#10000 $stop;end
代码如下:
`define ADDR_WIDTH 12//地址位宽`define DATA_WIDTH 12 //数据位宽
`define RAM_WIDTH 12 //RAM数据位宽
`define RAM_DEPTH 4096 //RAM深度
module fifo_test(clk_10M, //写时钟
clk_5M,//读时钟
rst_n, // 全局复位信号
wr_en, // 写使能 低有效
rd_en, // 读使能 低有效
wr_data, //12位数据输入
rd_data, //12位数据输出
wr_full, // 写满标志 高有效
rd_empty) // 读空标志 高有效
//输入信号
input clk_10M
input clk_5M
input rst_n
input wr_en
input rd_en
input[`DATA_WIDTH-1:0] wr_data
output reg [`DATA_WIDTH-1:0] rd_data
output reg wr_full
output reg rd_empty
reg [`RAM_WIDTH-1:0] mem[`RAM_DEPTH-1:0]// 12位4096单元
reg[`ADDR_WIDTH-1:0] wr_addr // 12位写地址
reg[`ADDR_WIDTH-1:0] rd_addr // 12位读地址
reg rd_flag
reg wr_flag
//写地址产生逻辑
always @(posedge clk_10M or negedge rst_n)
begin
if(!rst_n)
begin
wr_addr <= 12'h0
wr_flag <= 0
end
else if(!wr_en)
begin
if(!wr_full &&(rd_addr!=(wr_addr+1)))
begin
wr_flag <= 1
wr_addr <= wr_addr + 1'b1
end
else
wr_flag <= 0
end
end
// 写数据产生逻辑
always @(posedge clk_10M)
begin
if(!wr_en &&!wr_full &&wr_flag)
mem[wr_addr] <= wr_data
end
//写满产生标志
always @(posedge clk_10M or negedge rst_n)
begin
if(!rst_n)
wr_full <= 0
else if(rd_addr == (wr_addr+1))
wr_full <= 1'b1
else
wr_full <= 1'b0
end
//读地址产生逻辑
always @(posedge clk_5M or negedge rst_n)
begin
if(!rst_n)
begin
rd_flag <= 0
rd_addr <= 12'd0
end
else if(!rd_en)
begin
if(!rd_empty &&(wr_addr!=(rd_addr+1)))
begin
rd_flag <= 1
rd_addr <= rd_addr + 1'b1
end
else
rd_flag <= 0
end
end
//读数据产生逻辑
always @(posedge clk_5M)
begin
if(!rd_en &&!rd_empty &&rd_flag)
rd_data <= mem[rd_addr]
end
//读空产生标志
always @(posedge clk_5M or negedge rst_n)
begin
if(!rst_n)
rd_empty <= 1'b1
else if((wr_addr == (rd_addr+1))||(wr_addr == rd_addr))
rd_empty <= 1'b1
else
rd_empty <= 1'b0
end
endmodule
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)