FPGA FIFO IP核(3)- 仿真

仿真思路

  • 如何在写入标志信号(写入请求信号)有效时将数据写入到FIFO中?
    在调用模块代码中,pi_flag每四个时钟周期产生一个有效信号,即写请求信号。每次当pi_data检测到pi_flag信号有效时加1,从0~255循环变化。实现效果就是在pi_flag有效时将pi_data写入到FIFO中。
  • 读请求信号rdreq在FIFO的满标志信号full有效时拉高,空标志信号empty有效时拉低。

仿真代码

'timescale 1ns/1ns
module	tb_fifo();

//定义寄存器,定义线束
reg			sys_clk  ;
reg	[7:0]	pi_data  ;
reg			pi_flag  ;
reg			rdreq    ;
reg			sys_rst_n;
reg	[1:0]	cnt_baud ;

wire	[7:0]	po_data;
wire			empty  ;
wire			full   ;
wire	[7:0]	usedw  ;
//***********主要代码*************
//系统时钟初始化,复位信号
initial begin
	sys_clk		=	1'b1;
	sys_rst_n  <=	1'b0;
	#100;//延迟100ns
	sys_rst_n  <=   1'b1;
end
//50Mhz系统时钟设置:周期为20ns,每10ns电平翻转一次
always	#10	 sys_clk = ~sys_clk;
//计数器设置,计数0~3
always@(posedge	sys_clk	or	negedge	sys_rst_n)
	if(sys_rst_n  ==  1'b0)
		cnt_baud  <=  2'b0;
	else	if(&cnt_baud == 1'b1)
	    cnt_baud  <=  2'b0;
	else
		cnt_baud  <=  cnt_baud + 1'b1;
//pi_flag:写请求信号,输入有效标志信号,每四个时钟周期且没有读要求时产生一个数据有效标志信号
always@(posedge	sys_clk	or	negedge	sys_rst_n)
	if(sys_rst_n == 1'b0)
		pi_flag  <= 1'b0;
	else	if((cnt_baud == 2'd0) &&  (rdreq == 1'b0))
		pi_flag  <= 1'b1;
	else
		pi_flag  <= 1'b0;
//写入的数据:pi_data 0~255的循环
always@(posedge	sys_clk	or	negedge	sys_rst_n)
	if(sys_rst_n == 1'b0)
		pi_data  <= 8'b0;
	else	if((pi_data == 8'd255) && (pi_flag == 1'b1))
		pi_data <= 8'b0;
	else	if(pi_flag == 1'b1)
		pi_data <= pi_data +1'b1;
//读请求信号
always@(posedge	sys_clk	or	negedge	sys_rst_n)
	if(sys_rst_n == 1'b0)
		rdreq <= 1'b0;
	else	if(full == 1'b1)
		rdreq <= 1'b1;
	else	if(empty == 1'b1)
		rdreq <= 1'b0;
//例化
 fifo fifo_inst(
 	.sys_clk	(sys_clk),
 	.pi_data	(pi_data),
 	.pi_flag	(pi_flag),
 	.rdreq		(rdreq  ),
 	.po_data	(po_data),
 	.empty		(empty  ),
 	.full		(full   ),
 	.usedw		(usedw	)
 );
 endmodule

编译,设置NativeLink后,进行仿真,在设置testbech时将仿真时间设置为100微秒,设置testbech的具体步骤不再赘述。
在这里插入图片描述

仿真结果分析

运行Modelsim后,出现仿真结果如下,其中:
pi_data(写入数据)与po_data(读出数据)交替出现;
pi_flag(数据有效标志信号)与pi_data对应;
rdreq(读请求信号)为高电平有效时,po_data信号输出;
在这里插入图片描述
将写入数据与读出数据衔接的时间段放大后来看:
pi_data信号为11111111(255),且pi_flag信号为1时,full(满标志信号)拉高,表明存储空间已满。
此时usedw(存储数据的个数)也变为了0。
在这里插入图片描述
下图中,full(满标志信号)有效时,rdreq(读请求信号)也被拉高,开启读数据。
读取数据开始时,有两个时钟周期的0,第一个潜伏期导致,第二个为读出的数据0。
在这里插入图片描述
整体来看,随着数据被逐渐读出,存储的数据也慢慢减少,full信号在读出第一个数据后就迅速被拉低。如下图所示:
在这里插入图片描述
之前设置的是普通模式,如下图,在读到数据11111110时,empty信号就被拉高,原因是这里读出的数据要比读使能信号延一拍
在这里插入图片描述
在之前的FIFO IP核配置过程中,如果把普通模式更改为先出数据模式,如下图,则会出现相对容易理解的结果。
在这里插入图片描述
这里当rdreq(读请求信号)有效时,数据并没有像之前一样有一个潜伏的0信号,读数据和rdreq信号是同步的。
在这里插入图片描述
而对于empty信号,在读出最大数11111111(255)后被立刻拉高:
在这里插入图片描述

小结

OK,上面就是同步时钟FIFO IP 的仿真结果相关分析了,可以发现结合信号波形来理解FIFO,很多之前不太理解的地方会变的清晰一些,但是有些地方还是有些模模糊糊。还有一个异步时钟FIFO IP核的仿真,还得再写一期。

参考资料:《FPGA Verilog开发实战指南》《Verilog数字系统设计教程》
特别鸣谢:BiliBili

  • 17
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值