FIFO(一) —— Quartus中FIFO IP核的学习与modelsim仿真

文章目录

  • 一、FIFO的介绍
  • 二、FIFO常见参数
  • 三、FIFO的实现
  • 四、仿真
    • 4.1 同步FIFO的仿真
    • 4.2 FIFO普通和慢速两种模式的仿真
    • 4.3 异步FIFO的仿真

一、FIFO的介绍

1、 FIFO:(First In First Out),是有先进先出特性的缓存器,常被用于数据的缓存或者高速异步数据的交互。

2、 FIFO与普通存储器的区别在于:它没有外部读写地址线(其数据地址由内部读写指针自动加 1 完成),操作简单但不能指定某一地址。

3、主要包含两种:单时钟FIFO和双时钟FIFO
FIFO(一) —— Quartus中FIFO IP核的学习与modelsim仿真_第1张图片

详细的资料

二、FIFO常见参数

FIFO 的宽度:即 FIFO 一次读写操作的数据位;
FIFO 的深度:指的是 FIFO 可以存储多少个 N 位的数据(如果宽度为 N)。————深度的计算方式
同步与异步的设置。【同步读写位宽必须相同,异步的话可设置不同位宽】

FIFO(一) —— Quartus中FIFO IP核的学习与modelsim仿真_第2张图片

读时钟:读操作所遵循的时钟,在每个时钟沿来临时读数据。
写时钟:写操作所遵循的时钟,在每个时钟沿来临时写数据。
对于同步FIFO来说,读写为同一时钟。

FIFO(一) —— Quartus中FIFO IP核的学习与modelsim仿真_第3张图片

满标志full: FIFO 已满或将满时由 FIFO 的状态电路送出的一个信号,以阻止 FIFO的写操作继续向 FIFO 中写数据而造成溢出。
空标志empty: FIFO 已空或将空时由 FIFO 的状态电路送出的一个信号,以阻止 FIFO的读操作继续从 FIFO 中读出数据而造成无效数据的读出。

将满almost full:可设置将满的位置
将空almost empty:可设置将空的位置

FIFO(一) —— Quartus中FIFO IP核的学习与modelsim仿真_第4张图片

Normal模式: rdreq相当于读请求信号。rdreq有效,则下一clk上升沿即可读q数据。

Show-ahead模式: rdreq 相当于读应答信号,即 rdreq 还没有有效时, q 端口上已经输出了一个有效的数据, rdreq 信号有效时则,相当于通知 FIFO 内部的控制逻辑 q 端口上的数据已经被读取,则 FIFO 内部的逻辑会从 RAM 中再取出一个新的数据,在下一个时钟周期输出到 q 端口上。总之, q 端口上的数据 与 rdreq 同时有效,没有读潜伏期。

FIFO(一) —— Quartus中FIFO IP核的学习与modelsim仿真_第5张图片
FIFO(一) —— Quartus中FIFO IP核的学习与modelsim仿真_第6张图片

ip参数的学习

三、FIFO的实现

一种:根据需求自己编写FIFO
二种:调用IP核

四、仿真

4.1 同步FIFO的仿真

读写采用同一时钟,调用ip后,将其例化到顶层中:
FIFO(一) —— Quartus中FIFO IP核的学习与modelsim仿真_第7张图片

FIFO(一) —— Quartus中FIFO IP核的学习与modelsim仿真_第8张图片
编写tb进行仿真:

`timescale 1ns/1ps

module fifo_tb();

   reg	  clk;
	reg	[7:0]  data;
	reg	  rdreq;
	reg	  sclr;
	reg	  wrreq;
	
	wire	  almost_empty;
	wire	  almost_full;
	wire	  empty;
	wire	  full;
	wire	[7:0]  q;
	wire	[6:0]  usedw;

FIFO FIFO (
	.clk(clk),
	.data(data),
	.rdreq(rdreq),
	.sclr(sclr),
	.wrreq(wrreq),
	.almost_empty(almost_empty),
	.almost_full(almost_full),
	.empty(empty),
	.full(full),
	.q(q),
	.usedw(usedw)
);

//产生时钟激励

initial begin
    clk =   0;
	 data =  1;
	 rdreq = 0;
	 sclr =  0;
	 wrreq = 0;
	 
	 #201;
    sclr = 1;
	 #101;
	 sclr = 0;
	 #200;
	 
	 	repeat(128)begin
			wrreq = 1;
			#20;
			data = data + 1;
		end
		wrreq = 0;

		repeat(128)begin
			rdreq = 1;
			#20;
			data = data + 1;
		end
		rdreq = 0;
		
		#500;
		$stop;	 
end

always #10 clk = ~clk;

endmodule

整体波形如下:
可看到wrreq写使能的时候,q无输出。
当rdreq有效的时候,q才能读数据。
FIFO(一) —— Quartus中FIFO IP核的学习与modelsim仿真_第9张图片
wrreq高电平后,可以写数据,于是在clk上升沿处,usedw为1,说明已经使用了一个。usedw表示已使用深度
在这里插入图片描述
由于设置的FIFO深度是128,因此当写128个数据的时候,full满信号为高电平
在这里插入图片描述
当读使能rdreq为高电平的时候,开始读数据,先进先出,因此第一个数据从1开始,同时usedw已使用深度也逐渐减少。
在这里插入图片描述
当读到128的时候,说明数据全部读完,empty空信号标志为高电平,同时usedw已使用0.
在这里插入图片描述
由于设置的将空位置为2,因此是读到倒数第二个位置的时候almost_empty = 1
在这里插入图片描述
将满位置为125
在这里插入图片描述


4.2 FIFO普通和慢速两种模式的仿真

对Normal 和 how-ahead模式 进行验证

分别调用Normal 和 how-ahead模式的ip核,将二者均例化到顶层模块中。

这里不再观察usedw等信号,主要各个模式下,数据与rdreq信号的关系。
FIFO(一) —— Quartus中FIFO IP核的学习与modelsim仿真_第10张图片
tb测试文件:
同样的,wrreq高电平,写入1……128,共128个数据,rdreq高电平,将128先入先出读出来。

`timescale 1ns/1ps

module fifo_model_tb(); //对两种模式的fifo仿真

   reg	  clk;
	reg	[7:0]  data;
	
	reg	  rdreq;
	reg	  wrreq;
	
	wire	[7:0]  q_normal;
	wire	[7:0]  q_show_ahead;

FIFO FIFO (
	.clk(clk),
	.data(data),
	
	.rdreq(rdreq),
	.wrreq(wrreq),

	.q_normal(q_normal),
	.q_show_ahead(q_show_ahead)
);


//产生激励

initial begin
    clk =   0;
	 data =  1;
	 
	 rdreq = 0;
	 wrreq = 0;
	 
	 	repeat(128)begin
			wrreq = 1;
			#20;
			data = data + 1;
		end
		wrreq = 0;

		repeat(128)begin
			rdreq = 1;
			#20;
			data = data + 1;
		end
		rdreq = 0;
		
		#500;
		$stop;

	 
end
always #10 clk = ~clk;
endmodule

前面我们提到了
Normal模式: rdreq相当于读请求信号。rdreq有效,则下一clk上升沿即可读q数据。

Show-ahead模式: rdreq 相当于读应答信号,即 rdreq 还没有有效时, q 端口上已经输出了一个有效的数据, rdreq 信号有效时则,相当于通知 FIFO 内部的控制逻辑 q 端口上的数据已经被读取,则 FIFO 会再取出紧接着的新数据,在下一个时钟周期输出到 q 端口上。


波形如下,观察两种模式下,输出与rdreq的关系:

波形可看出,rdreq=1,normal模式下,在下一clk上升沿开始读数据1……128。
当Show-ahead模式下,rdreq=0无效时,q已经输出了一个有效数据1,rdreq=1有效时,相当于读应答,可告诉fifo,q输出上的1已经被读取,紧接着,在下一clk即可读下一个数据,也就是2……128。

因此波形验证与理论分析相同。

FIFO(一) —— Quartus中FIFO IP核的学习与modelsim仿真_第11张图片


4.3 异步FIFO的仿真

调用异步FIFO的ip核:
FIFO(一) —— Quartus中FIFO IP核的学习与modelsim仿真_第12张图片
将其例化到顶层中

FIFO(一) —— Quartus中FIFO IP核的学习与modelsim仿真_第13张图片

编写tb文件:

`timescale 1ns/1ps

module fifo_tb(); //对同步fifo仿真

	reg	[7:0]  data;
   reg	  wrclk;
	reg     wrreq;
	
   reg	  rdclk;
	reg	  rdreq;
	
	wire rdempty;
   wire wrfull;
	wire	[7:0]  q;


DC_FIFO u1 (
	
	.data(data),
	.wrclk(wrclk),
	.wrreq(wrreq),
	
	.rdclk(rdclk),
	.rdreq(rdreq),
	
	.rdempty(rdempty),
	.wrfull(wrfull),
	
	.q(q)

);


//产生激励

initial begin
    wrclk = 0;
	 rdclk = 0;
	 
	 data =  1;
	 
	 rdreq = 0;
	 wrreq = 0;
	 #10;

	 
	 	repeat(32)begin
			wrreq = 1;
			#20;
			data = data + 1;
		end
		wrreq = 0;

		repeat(32)begin
		   #10;
			rdreq = 1;
			#20;
			data = data + 1;
		end
		rdreq = 0;
		
		#500;
		$stop;

	 
end
always #10 wrclk = ~wrclk;  //20ns
always #5 rdclk = ~rdclk;  //10ns

endmodule

波形:
波形可看出,读写采用了不同的时钟,同时wrreq=1开始写数据,写完32个数据后,wrreq = 0,wrfull = 1,同时写使能信号和写满标志信号的变化都发生在wrclk上升沿。——写有关的信号均与写时钟同步
FIFO(一) —— Quartus中FIFO IP核的学习与modelsim仿真_第14张图片
关于读:
当rdreq=1,开始读数据,从1……32。可看到rdreq=1时,在rdclk上升沿读到第一个数据1,当读完32个数据后,rdempty在rdclk上升沿处变为高电平。——读有关的信号均与读时钟同步
FIFO(一) —— Quartus中FIFO IP核的学习与modelsim仿真_第15张图片

五、手写FIFO

我这里学习手写FIFO是为了更好地学习FIFO的本质。手写FIFO请看FIFO(二)。

你可能感兴趣的:(接口协议,SDRAM,FIFO,乒乓,tcp/ip,学习,fpga开发)