同步FIFO之VHDL描述
同步FIFO之VHDL描述
同步FIFO之VHDL描述(1)作者:skycanny时间:2007-09-28 16:09:38 来自:skycanny的笔记浏览次数:1601 文字大小:【大】【中】【小】同步FIFO之VHDL描述同步FIFO的意思是说FIFO的读写时钟是同一个时钟,不同于异步FIFO,异步FIFO的读写时钟是完全异步的。
同步FIFO的对外接口包括时钟,清零,读请求,写请求,数据输入总线,数据输出总线,空以及满信号。
下面分别对同步FIFO的对外接口信号作一描述:1.时钟,输入,用于同步FIFO的读和写,上升沿有效;2.清零,输入,异步清零信号,低电平有效,该信号有效时,FIFO被清空;3.写请求,输入,低电平有效,该信号有效时,表明外部电路请求向FIFO写入数据;4.读请求,输入,低电平有效,该信号有效时,表明外部电路请求从FIFO中读取数据;5.数据输入总线,输入,当写信号有效时,数据输入总线上的数据被写入到FIFO中;6.数据输出总线,输出,当读信号有效时,数据从FIFO中被读出并放到数据输出总线上;7.空,输出,高电平有效,当该信号有效时,表明FIFO中没有任何数据,全部为空;8.满,输出,高电平有效,当该信号有效时,表明FIFO已经满了,没有空间可用来存贮数据。
使用VHDL描述的FIFO将以上面的接口为基础,并且可以参数化配置FIFO的宽度和深度。
先把对外接口描述出来吧。
----------------------------------------------------------------------------------------------------------- Designer : skycanny-- Date : 2007-1-29-- Description : Synchronous FIFO created by VHDLlibrary ieee;use ieee.std_logic_1164.all;use ieee.std_logic_unsigned.all;use ieee.std_logic_arith.all;entity sfifo isgeneric(width : positivedepth : positive);port(clk : in std_logic;rst : in std_logic;wq : in std_logic;rq : in std_logic;data : in std_logic_vector(width - 1 downto 0);q : in std_logic_vector(width - 1 downto 0);empty : out std_logic;full : out std_logic);end entity sfifo;-----------------------------------------------------------------------------------------------------------同步FIFO内部通过控制电路和RAM实现,控制电路主要包括写指针管理电路,读指针管理电路,以及FIFO状态判断电路,对于同步FIFO来讲,读和写的指针管理电路实际上就是二进制计数器。
【CPLD Verilog】CPLD实现同步FIFO
CPLD实现同步FIFO1 实现原理CPLD实现8个字节的同步FIFO,实现8个字节数据的缓存。
CPLD内部模块逻辑框图如下所示。
Data_a_we_pulse写数据到FIFO的使能信号。
Data_a_rd_pulse从FIFO读取数据的使能信号。
Data_a_in和Data_a_out分别表示写入FIFO和从FIFO读出的数据的值。
Data_a_we_full指示FIFO写满的状态。
Data_a_rd_nop指示FIFO读空的状态。
2 CPLD代码module fifo_8B (clk,reset_n,data_a_in,data_a_we_pulse,data_a_we_full,data_a_out,data_a_rd_pulse,data_a_rd_nop);input clk;input reset_n;input [7:0] data_a_in;input data_a_we_pulse;output data_a_we_full;output [7:0] data_a_out;input data_a_rd_pulse;output data_a_rd_nop;//////////////////////////FIFO 写入数据逻辑////////////////////////////reg [7:0] fifo_mem [7:0]; //FIFO空间,8个8bit的空间reg [2:0] fifo_we_addr; //FIFO写地址寄存器reg fifo_we_addr_reverse_pulse; //FIFO写地址翻转状态寄存器,用于指示写//地址是否从最大地址翻转回到最小地址always@(posedge clk or negedge reset_n)beginif(reset_n == 1'b0)beginfifo_we_addr <= 3'h0;fifo_we_addr_reverse_pulse <= 1'b0;endelse if((data_a_we_pulse == 1'b1)&&(fifo_we_addr != 3'h7)&&(data_a_we_full == 1'b0)) beginfifo_mem[fifo_we_addr] <= data_a_in; //对应写地址,写入相应的值fifo_we_addr <= fifo_we_addr+3'h1;endelse if((data_a_we_pulse == 1'b1)&&(fifo_we_addr == 3'h7)&&(data_a_we_full == 1'b0)) beginfifo_mem[fifo_we_addr] <= data_a_in;fifo_we_addr <= fifo_we_addr+3'h1;fifo_we_addr_reverse_pulse <= ~fifo_we_addr_reverse_pulse;endelse;end//////////////////////////FIFO 读出数据逻辑////////////////////////////reg [2:0] fifo_rd_addr; //FIFO读地址寄存器reg fifo_rd_addr_reverse_pulse; //FIFO读地址翻转状态寄存器,用于指示读//地址是否从最大地址翻转回到最小地址reg [7:0] data_a_out;always@(posedge clk or negedge reset_n)beginif(reset_n == 1'b0)beginfifo_rd_addr <= 3'h0;fifo_rd_addr_reverse_pulse <= 1'b0;endelse if((data_a_rd_pulse == 1'b1)&&(fifo_rd_addr != 3'h7)&&(data_a_rd_nop == 1'b0)) begindata_a_out <= fifo_mem[fifo_rd_addr]; //对应读地址,读出相应的值fifo_rd_addr <= fifo_rd_addr+3'h1;endelse if((data_a_rd_pulse == 1'b1)&&(fifo_rd_addr == 3'h7)&&(data_a_rd_nop == 1'b0)) begindata_a_out <= fifo_mem[fifo_rd_addr];fifo_rd_addr <= fifo_rd_addr+3'h1;fifo_rd_addr_reverse_pulse <= ~fifo_rd_addr_reverse_pulse;endelse;end//////////////////////////FIFO 满空逻辑////////////////////////////wire fifo_addr_reverse_flag;assign fifo_addr_reverse_flag = (fifo_we_addr_reverse_pulse^fifo_rd_addr_reverse_pulse == 1'b1) ? 1'b1 : 1'b0;reg data_a_we_full;reg data_a_rd_nop;always@(posedge clk or negedge reset_n)beginif(reset_n == 1'b0)begindata_a_we_full <= 1'b0;data_a_rd_nop <= 1'b1;endelse if((fifo_rd_addr == fifo_we_addr)&&(fifo_addr_reverse_flag ==1'b1))begindata_a_we_full <= 1'b1;data_a_rd_nop <= 1'b0;endelse if((fifo_rd_addr == fifo_we_addr)&&(fifo_addr_reverse_flag ==1'b0))begindata_a_we_full <= 1'b0;data_a_rd_nop <= 1'b1;endelsebegindata_a_we_full <= 1'b0;data_a_rd_nop <= 1'b0;endendendmodule3 仿真结果3.1 正常写入读取FIFO仿真如下红色圆框,红色圆框表示向FIFO写入3个字节数据,红色方框表示从FIFO读取出2个字节数据。
verilog同步和异步FIFO,可直接仿真和综合解读
EDA/SOPC课程设计报告题目:同异步FIFO模块的设计与验证姓名:xxx学号:120260320同组人:xxx指导教师:xxx成绩:目录目录 (II)第1章课程设计的要求 (1)1.1 课程设计的目的 (1)1.2 课程设计的条件 (1)1.3 课程设计的要求 (1)第2章课程设计的内容 (2)2.1 设计思路 (2)2.2 软件流程图 (2)2.3 HDL代码阐述 (2)2.4 ModelSim验证 (2)第3章课程设计的心得 (3)第1章课程设计的要求1.1 课程设计的目的●掌握FIFO设计的基本原理与方法●培养Verilog语言模块化设计的思想意识●完成一个FIFO的设计与验证●掌握较大工程的基本开发技能●培养综合运用Modelsim工具进行硬件开发的能力●培养数字系统设计的基本能力●加强对课堂Verilog语言学习的理解与升华1.2 课程设计的条件●设计条件ISE、Modelsim等开发软件的使用1.3 课程设计的要求●设计要求1 设计同步FIFO并验证(包括仿真验证、FPGA验证)●设计要求2 设计异步FIFO并验证(包括仿真验证、FPGA验证)●设计要求3 采用Design Compiler完成其逻辑综合,评估其面积和时序●设计要求4 完成综合后的SDF反标仿真第2章课程设计的内容2.1 设计思路FIFO(First Input First Output),即先进先出队列。
在计算机中,先入先出队列是一种传统的按序执行方法,先进入的指令先完成并引退,跟着才执行第二条指令(指令就是计算机在响应用户操作的程序代码,对用户而言是透明的)。
如下图所示,当CPU在某一时段来不及响应所有的指令时,指令就会被安排在FIFO队列中,比如0号指令先进入队列,接着是1号指令、2号指令……当CPU完成当前指令以后就会从队列中取出0号指令先行执行,此时1号指令就会接替0号指令的位置,同样,2号指令、3号指令……都会向前挪一个位置,这样解释大家清楚了吧?在设计之初,我们只对FIFO有一个模糊的了解,只知道它是一个先入先出的队列,但是对于它是如何组成和如何工作并不了解,于是我们设计的首要任务就是查阅资料,逐步完善我们对于同步FIFO和异步FIFO的了解。
VHDL语言的主要描述语句
VHDL语言的主要描述语句按照语句的执行顺序对VHDL语言进行分类,包含两类语句:●并行描述语句该语句的执行与书写顺序无关,总是同时被执行●顺序描述语句从仿真的角度,该语句是顺序执行的进程语句(PROCESS)是最典型的并行语句,一个构造体可以有几个进程语句同时存在,而且并发执行。
但是进程部的所有语句都是顺序语句。
一、顺序描述语句顺序描述语句只能用在进程和子程序中,它和其他高级语言一样,其语句是按照语句的出现的顺序加以执行的。
如下分别介绍有关的顺序描述语句.1.WAIT语句进程在执行过程中总是处于两种状态:执行或挂起,进程的状态变化受等待语句的控制,当进程执行到等待语句,就被挂起,并等待再次执行进程.等待语句的格式:*WAIT 无限等待*WAIT ON 敏感信号变化*WAIT UNTIL 条件满足*WAIT FOR 时间到(1)WAIT ON格式:WAIT ON 信号[,信号]例5-1PROCESS(a,b)BEGINy<=a AND b;END PROCESS;该例中的进程与下例中进程相同:例5-1PROCESSBEGINy<=a AND b;WAIT ON a,b;END PROCESS;例5-2PROCESS(a,b)BEGINy<=a AND b;WAIT ON a,b;END PROCESS;(2)WAIT UNTIL 直到条件满足格式: WAIT UNTIL 布尔表达式当进程执行到该语句时,被挂起;若布尔表达式为真时,进程将被启动.例: WAIT UNTIL ((x*10)<100)(3)WAIT FOR 等到时间到格式: WAIT FOR 时间表达式当进程执行到该语句时,被挂起;等待一定的时间后,进程将被启动.例: WAIT FOR 20 ns;WAIT FOR (a*(b+c);(4)多条件WAIT 语句例: WAIT ON nmi,interrupt UNTIL ((nmi=TRUE) OR (interrupt=TRUE)) FOR 5 us 该等待有三个条件:第一,信号nmi和interrupt 任何一个有一次刷新动作第二, 信号nmi和interrupt 任何一个为真第三, 已等待5 us只要一个以上的条件被满足,进程就被启动.*注意:多条件等待时,表达式的值至少应包含一个信号量的值。
第5章VHDL基本描述语句
多个赋值源
SVEC(0) <= V1; --将V1在上面的赋值1,赋给SVEC(0)
SVEC(1) <= V2;
SVEC(2) <= S1; SVEC(3) <= S2;
--将V2在上面的赋值1,赋给SVEC(1)
--将S1在上面的赋值1,赋给SVEC(2) --将最下面的赋予S2的值‘0’,赋给SVEC(3)
FOR LOOP循环主要用在规定数目的重复情况;
WHILE LOOP则根据控制条件执行循环直到条件为
FALSE。
FOR LOOP语句
FOR LOOP格式:
[标号:] FOR 循环变量 IN 循环次数范围 LOOP
顺序处理语句;
END LOOP [标号];
循环变量:属于LOOP语句的局部变量,不需要事先定义,也不能 被赋值,它的值从循环次数范围的初值开始,执行一次顺序语句 自动加一,当其值超出循环次数范围时,则退出循环语句。
5.1.1赋值语句
语句格式: 变量赋值目标:= 赋值源;
信号赋值目标<= 赋值源;
比较: (1)信号赋值有一定的延时,在时序电路中,在时 钟信号触发下的信号赋值,目标信号要比源信号延迟 一个时钟周期;变量赋值语句立即执行,没有延时。 (2)进程中同一变量多次赋值时按顺序立即执行, 而信号多次赋值时,只有进程结束前最后一个赋值被 执行。
不完整IF语句
作用:形成锁存,用于构成时序电路,而组合电路只能
使用完整的IF语句。
例5-6: IF (clk’event and clk=’1’) then
Q<=d;
End if;
二选一IF语句
语句格式:
IF 条件 THEN 顺序执行语句1;
第五章(VHDL主要描述语句)
(4) CASE语句执行中必须选中,且只能选中所列条件语
句中一条。这表明CASE语句中至少要包含一个条件语句。
CASE语句常用来描写总线行为、编码器和译码器的结构。CASE语句 与IF语句功能相似但CASE语句的可读性好,非常简洁。
CASE语句的误用:
SIGNAL value : INTEGER RANGE 0 TO 15 ; SIGNAL out_1 : BIT ; CASE value IS -- 缺少 WHEN条件语句 END CASE ; -- 分支条件不包含2到15 CASE value IS WHEN 0 => out_1 <= „1‟; WHEN 1 => out_1 <=„0‟; END CASE ; -- 在5到10上发生重叠 CASE value IS WHEN 0 TO 10 => out_1 <= „1‟; WHEN 5 TO 15 => out_1 <= „0‟; END CASE ;
IF语句不仅可用于选择器设计,还可用于比较 器,译码器等进行条件控制的逻辑设计。IF语句 中至少应有一个条件句,条件句必须由布尔表达 式构成,条件表达式中能使用关系运算操作及逻 辑运算操作的组合表达式。 IF语句颠倒条件判别次序,会引起在综合时逻辑 功能的变化,即IF语句判别条件不可颠倒。 IF语句中,先处理最起始的条件;如果不满足, 再处理下一个条件。一般把条件约束最多的作为 起始条件。
例
用IF语句描述一个二位等值比较器
ARCHITECTURE a OF compare IS LIBRARY IEEE; BEGIN PROCESS(a,b) USE IEEE.STD_LOGIC_1164.ALL; BEGIN ENTITY compare IS IF(a>b) THEN eater<='1';equal<='0';less<='0'; generic(n:natural:=2); ELSIF (a=b) THEN PORT( greater<='0';equal<='1';less<='0'; ELSE a,b:IN STD_LOGIC_VECTOR(n-1 DOWNTO 0); greater<='0';equal<='0';less<='1'; greater,equal,less:OUT STD_LOGIC); END IF; END PROCESS; END; END;
实验八FIFO的VHDL设计
实验八 FIFO的VHDL实现实验内容:熟悉FIFO工作原理,采用VHDL语言设计FIFO模块。
实验目的:1)熟悉FIFO工作原理。
2)设计FIFO的VHDL代码和顶层VHDL仿真测试平台,并进行仿真。
实验步骤:1)创建FIFO的VHDL代码及其VHD 测试文件文件;2)编译工程中的测试文件;3)进行波形仿真并保存文件;附录:FIFO(First-In First-Out)芯片是一种具有存储功能的高速逻辑芯片,可在高速数字系统中用作数据缓存。
FIFO通常利用双口RA M和读写地址产生模块来实现其功能。
FIFO的接口信号包括写时钟和读时钟、与写时钟同步的写有效和写数据、与读时钟同步的读有效和读数据。
写地址产生模块一般还根据读地址和写地址来产生FIFO的满标志;读地址产生模块一般根据读地址和写地址来产生FIFO的空标志。
为了实现正确的读写和避免FIFO的上溢或下溢,通常还应给出与读时钟和写时钟同步的FIFO的空标志(empty)和满标志(ful1),以禁止读写操作。
写地址产生模块通常根据写时钟和写有效信号来产生递增的写地址,而读地址产生模块则根据读时钟和读有效信号来产生递增的读地址。
FIFO一般在操作时,首先在写时钟的上升沿且当写信号有效时,将数据写入双口RA M 中写地址对应的位置中,然后将读地址对应的双口RA M中的数据输出到读数据总线上,这样就可以实现先进先出功能。
读写操作一般会自动访问存储器中连续的存储单元。
从FIFO 中读取的数据顺序与写入的顺序相同,而地址的顺序则在内部已经预先定义好,因此,对FIFO芯片的操作不需要额外的地址信息,另外,FIFO芯片还能提供对读/写指针的复位功能。
同时,相对于原理图设计,硬件描述语言设计具有很多的优势,VHDL采用自顶向下的设计方法,使设计的方法更加灵活、效率更高、开发周期更短、移植性更强。
1.FIFO的原理结构及外部接口FIFO存储器通常用做为数据缓存器,有同步FIFO和异步FIFO之分。
帧差法
帧差法近些年来, 世界各地的学者们针对视频图像中的运动目标检测与跟踪问题做了大量而深入的研究, 提出了很多极其有效的算法难点主要在于视频序列中有各种不同的干扰因素, 这些因素主要包括: 光线明暗的变化、成像传感器本身的固有噪声、运动目标自身的形变或位移变化、背景中的杂波、运动目标的互相遮挡或者自遮挡等, 这些问题还有待于做进一步的研究。
目前, 常用的运动目标检侧方法有: 光流法、背景差分法和帧间差分法。
1.光流法光流法能够检测出运动目标较完整的运动信息, 不需要预先知道场景的任何信息, 能够较好的处理运动背景的情况, 并且可以用于摄像机运动的情况, 适用于帧间位移较大的情况。
但是由于透明性、阴影、多光源、遮挡和噪声等原因,利用光流法进行运动物体检测时, 计算量很大, 无法保证实时性和实用性, 故难以应用到实时系统, 同时对噪声比较敏感, 计算结果精度较低, 难以得到运动目标的精确边界。
2 .背景差分法操作简单, 能够提供完全的特征数据, 但对目标的检测能力较低, 尤其对天气、光照等噪声的影响极其敏感,3T 为预先设定的阈值, 可根据经验选取T , 若选取过大, 则检测的目标则可能出现较大的空洞甚至漏检, 若T 选取过小, 将出现大量噪声。
由于帧间差分法的不足, 就有学者提出了三帧差法, 三帧差法充分考虑了动像素的时间相关性, 对动态检测比较灵敏, 对随机噪声也有很好的抑制作用,但也存在一定缺陷, 即差分图像的检测阈值需手动设定, 大多数情况下只能依据实践经验。
三帧差分法的关键是选取合适的阈值对图像进行二值化。
运动目标自动跟踪是指对目标进行连续的检测并确定其运动轨迹[1].在视频监控领域中,目标智能识别与自动跟踪系统是近几年来的研究重点.在军事、国防和工业等领域有着广泛的应用前景.当前运动目标的检测方法主要有3类:光流法[2]、帧间差分法[3]和背景差分法[4].背景差分法具有简单、运算速度快等诸多优点,使得该法作为运动目标检测的基本方法被普遍采用.但该法暴露出若干问题:一种是因外部条件引起的,如对光线的变化、噪声等造成差分图像检测精度不高,甚至失效;另一种是由差分图像法本身内在局限引起的,主要有空洞[5]、拖影,以及运动目标被拉长等现象.光流法[6]虽然能够适用于静态背景和动态背景两种环境,有较好的适应性,但是其计算复杂度高,运算时间开销很大,不能满足实时性的要求.帧差法[7]比较简单,实时性高,它主要包括减背景方法和相邻帧相减法,即三帧差分法.减背景方法存在背景获取困难、受光照影响严重且更新困难等问题.三帧差分法受光照和阴影影响较小.笔者对三帧差分法进行改进,提出了一种简单有效的运动目标检测方法.1 运动目标实时跟踪系统1. 1 帧差法的基本原理帧间差分法的基本原理就是将前后两帧图像对应像素点的灰度值相减,在环境亮度变化不大的情况下,如果对应像素灰度相差很小,可以认为此处物是静止的;如果图像区域某处的灰度变化很大,可以认为这是由于图像中运动物体引起的,将这些区域标记下来,利用这些标记的像素区域,就可以求出运动目标在图像中的位置.一般采用的帧差法是在连续的图像序列[8]中2个或3个相邻帧间采用基于像素的时间差分并且阈值化来提取图像的运动区域.该运动目标实时跟踪系统是采用三帧差分来进行运动目标检测,这种方法不仅能提高运动目标检测[9]的速度,而且提高了所检测运动目标图像的完整性.均值滤波均值滤波是典型的线性滤波算法,它是指在图像上对目标像素给一个模板,该模板包括了其周围的临近像素(以目标象素为中心的周围8个像素,构成一个滤波模板,即去掉目标像素本身),再用模板中的全体像素的平均值来代替原来像素值。
同步fifo电路讲解
同步fifo电路讲解
同步FIFO(First-In-First-Out)电路是一种先进先出的数据交互方式,常用于数字ASIC设计中的数据缓冲。
同步FIFO的写时钟和读时钟为同一个时钟,FIFO内部所有逻辑都是同步逻辑。
同步FIFO电路通常由三部分组成:
1. FIFO写控制逻辑:主要功能是产生FIFO写地址、写有效信号,同时产生FIFO写满、写错等状态信号。
2. FIFO读控制逻辑:主要功能是产生FIFO读地址、读有效信号,同时产生FIFO读空、读错等状态信号。
3. FIFO存储实体(如Memory、Reg):用于存储数据。
在同步FIFO中,数据按照先进先出的原则进行读写,即先写入的数据会被先读出。
FIFO的读写操作都由同一时钟驱动,保证了数据的一致性和可靠性。
以上内容仅供参考,如需更多信息,建议查阅相关文献或咨询专业电子工程师。
同步fifo设计实验报告
课程设计报告题目:同步FIFO的设计姓名: 贾安乐学号:20105000学院:电子科学与应用物理学院专业:电子科学与技术10-3 组员: 徐健勋、兰伯章指导老师:杨小平、杞宁日期:2014.12.15一.课程设计要求1.课程设计的目的通过运用Verilog语言编写程序,体会程序的逻辑性,掌握基本的程序开发的注意事项。
在实践中,学习掌握简单、周全的编程方法。
掌握较大工程的基本开发技能。
培养综合运用Modelsim,Quartus II工具进行硬件开发的能力。
培养数字系统设计的基本能力。
理解FIFO的定义与功能,掌握FIFO的Verilog编写方法。
2.课程设计的条件FIFO的定义与功能Quartus II仿真工具3.课程设计的要求FIFO是英文First In First Out 的缩写,是一种先进先出的数据缓存器,他与普通存储器的区别是没有外部读写地址线,这样使用起来非常简单,但缺点就是只能顺序写入数据,顺序的读出数据,其数据地址由内部读写指针自动加1完成,不能像普通存储器那样可以由地址线决定读取或写入某个指定的地址。
使用Verilog语言和Quartus II仿真器完成同步FIFO的设计和验证。
使用Quartus II和SOPC实验箱验证设计的正确性。
Verilog代码要符合微电子中心编码标准。
4.Verilog语言Verilog HDL是一种硬件描述语言(HDL:Hardware Description Language),是一种以文本形式来描述数字系统硬件的结构和行为的语言,用它可以表示逻辑电路图、逻辑表达式,还可以表示数字逻辑系统所完成的逻辑功能。
Verilogs是由Gateway设计自动化公司的工程师于1983年末创立的。
当时Gateway设计自动化公司还叫做自动集成设计系统(Automated Integrated Design Systems),1985年公司将名字改成了前者。
该公司的菲尔·莫比(Phil Moorby)完成了Verilog的主要设计工作。
使用verilog_hdl实现8位宽,256位的深的同步fifo的实验原理
使用verilog hdl实现8位宽,256位的深的同步fifo的实验原理1. 引言1.1 概述本文旨在介绍如何使用Verilog HDL实现一个具有8位宽和256位深度的同步FIFO(First In, First Out)电路。
FIFO是一种常用的数据缓存结构,被广泛应用于数字系统中,具有先进先出的特性,能够实现数据的有序存储和检索。
文章将从FIFO的简介开始讲解,然后深入探讨同步FIFO设计时需要考虑的要点,并通过使用Verilog HDL进行设计和实现过程,最后对实验结果进行仿真验证、波形分析以及功能测试与性能评估。
1.2 文章结构本文总共包括五个部分。
首先是引言部分,概述了本文的目标和内容。
接下来是实验原理部分,从FIFO基本概念入手,详细介绍了同步FIFO设计时需要注意的要点以及Verilog HDL语言的简介。
然后是设计与实现部分,给出了8位宽、256位深度同步FIFO电路的设计思路,并逐步引导读者完成Verilog HDL代码的编写。
紧接着是实验结果与分析部分,通过仿真验证、波形分析以及功能测试与性能评估来验证所设计的同步FIFO电路是否符合预期。
最后是结论与展望部分,对实验结果进行总结,并探讨未来可能的改进方向和应用领域。
1.3 目的本文的主要目的是介绍使用Verilog HDL实现8位宽、256位深度同步FIFO电路的原理和方法。
读者可以通过本文了解到FIFO的基本原理和设计要点,以及如何使用Verilog HDL进行FIFO电路的实现。
通过本文,希望读者能够掌握基本的数字电路设计技巧和Verilog HDL编程能力,并在实践中提高对于同步FIFO电路设计的理解和应用能力。
同时,读者还可以通过仿真验证和功能测试等手段深入理解所实现的同步FIFO电路的性能特点,并为相关领域的研究与应用提供参考依据。
2. 实验原理:2.1 FIFO简介FIFO(First-In-First-Out)是一种常见的数据缓冲区结构,它的基本原则是按照先进先出的顺序处理输入和输出数据。
利用FPGA实现同步FIFO设置方法
第29卷第1期 2006年2月电 子 测 量 技 术EL ECT R ON IC M EASU R EM EN T T ECH N OL OG Y信息技术利用FPGA 实现同步FIFO 设置方法刘志杨 郭继昌 关 欣 黄彩彩 天津大学摘 要 文中在Q ua rtus 环境中,用V H DL 作为编程语言,实现用F PG A 器件对同步FIF O 设置的方法,在基于DSP 的图像处理系统中达到使同步FIF O 高效完成数据缓冲作用的目的。
这种方法对F IFO 的使用具有很好的借鉴意义。
关键词 先进先出(FIFO) 硬件描述语言 偏置寄存器Method of using FPGA to realize synchronous FIFO configurationL iu Zhiyang G uo Jichang Guan X in Huang CaicaiAbstract In this paper,a config ur ation method of synchro no us FI FOs w ith FP GA and V HD L lang uag e is realized in the Quar tus develo pment envir onment.A nd the pur po se o f effect ive data buffer with sy nchro no us F IFO s is obtained in the infrar ed imag e processing system based on DSP.T his metho d is o f import ant r eference v alue to the utility o f FIF Os.Keywords F IFO har dw are descr iption lang uage offset r egister1 系 统在基于DSP 的红外图像数据处理系统中,FIFO 器件IDT72V263[1]用作高速DSP 与低速设备的缓冲接口,系统的原理框图如图1所示。
基于乒乓操作的异步FIFO设计及VHDL实现
基于乒乓操作的异步FIFO设计及VHDL实现乒乓操作是一种常用的同步操作,可以实现数据的交换和缓存。
基于乒乓操作的异步FIFO设计,则是在原有的乒乓操作基础上,加入异步读写功能,实现了先进先出的数据存储。
在设计过程中,我们需要考虑以下几个关键点:1.写入数据的操作:当有新的数据要写入到FIFO中时,首先需要判断FIFO是否已满。
如果已满,则需要等待读取操作后再进行写入;如果未满,则直接将数据写入到空闲位置,并更新写指针。
2.读取数据的操作:当有读取操作时,首先需要判断FIFO是否为空。
如果为空,则需要等待写入操作后再进行读取;如果不为空,则从第一个有效数据开始读取,并将读取完的数据位置清空,并更新读指针。
3.FIFO的容量:FIFO的容量应该根据实际需求进行设置。
当FIFO中的数据量达到容量上限时,写操作将被阻塞,直到有读取操作释放空间。
基于以上设计思路,下面是一个简单的基于乒乓操作的异步FIFO的VHDL实现代码:```vhdllibrary ieee;use ieee.std_logic_1164.all;use ieee.numeric_std.all;entity Async_FIFO isgenericWIDTH : integer := 8; -- 数据位宽DEPTH : integer := 16 -- FIFO深度portclk : in std_logic; -- 时钟reset : in std_logic; -- 复位write : in std_logic; -- 写操作使能信号read : in std_logic; -- 读操作使能信号data_in : in std_logic_vector(WIDTH-1 downto 0); -- 输入数据data_out: out std_logic_vector(WIDTH-1 downto 0); -- 输出数据empty : out std_logic; -- FIFO为空标志位full : out std_logic -- FIFO为满标志位end Async_FIFO;architecture behavioral of Async_FIFO istype fifo_type is array (0 to DEPTH-1) ofstd_logic_vector(WIDTH-1 downto 0); -- FIFO存储类型signal fifo : fifo_type; -- FIFO数组signal write_ptr : integer range 0 to DEPTH-1 := 0; -- 写指针signal read_ptr : integer range 0 to DEPTH-1 := 0; -- 读指针signal count : integer range 0 to DEPTH := 0; -- FIFO计数器beginprocess(clk, reset)beginif reset = '1' then--复位write_ptr <= 0;read_ptr <= 0;count <= 0;elsif rising_edge(clk) then--写操作if write = '1' and count < DEPTH thenfifo(write_ptr) <= data_in;write_ptr <= write_ptr + 1;count <= count + 1;end if;--读操作if read = '1' and count > 0 thendata_out <= fifo(read_ptr);fifo(read_ptr) <= (others => '0');read_ptr <= read_ptr + 1;count <= count - 1;end if;end if;end process;empty <= '1' when count = 0 else '0';full <= '1' when count = DEPTH else '0';end behavioral;```上述代码中,首先定义了一个`fifo_type`类型,它是一个包含`DEPTH`个元素的数组,每个元素的大小为`WIDTH`位。
怎么用Verilog语言描述同步FIFO和异步FIFO
怎么⽤Verilog语⾔描述同步FIFO和异步FIFO感谢知乎龚⼤佬打杂⼤佬⽹上⼏个nice的博客(忘了是哪个了。
)前⾔虽然FIFO都有IP可以使⽤,但理解原理还是⾃⼰写⼀个来得透彻。
什么是FIFO?Fist in first out。
先⼊先出的数据缓存器,没有外部读写地址线,可同时读写。
规则:永远不要写⼀个已经写满了的fifo。
永远不要读⼀个读空了的fifo。
FIFO种类?同步FIFO和异步FIFO。
同步FIFO只有⼀个时钟,也就是说写端和读端的时钟是⼀⽑⼀样的。
异步FIFO读端和写端两个时钟则是不⼀样的。
包括同频异相,异频异相。
FIFO⽤途?1. 数据缓冲器。
⽐如你写端burst⼀个数据,没有fifo缓冲的话就炸了。
Fifo会把写端的突发数据吃到肚⼦⾥,读端可以慢慢的⼀个个读出来。
2. 跨时钟域。
异步fifo主要使⽤在不同时钟域的边缘,⽤来同步数据到另⼀个时钟域。
3.ALTERA FIFO IP 的缺点是什么?虽然altera贴⼼的提供了FIFO的IP块,但是对于可移植性与⾃定义位宽深度更好的话,还是⾃⼰写的更佳。
FIFO深度如何计算?(避免溢出)对于异步fifo,如果读时钟⼤于写时钟且每个周期读写,那么⼀定是会读空的,反之⼀定会被写满。
⼀般来说,不会设计这么⽆聊的东西。
假设写端有突发的数据,⽽读端是均匀的读出,怎么保证fifo不溢出呢?异步FIFO快转慢的问题:可能采样踩不到某些值。
同步FIFO:当缓冲器使⽤,可以⽤ram资源搭。
原理图:信号定义:clk:时钟信号rst_n:异步复位信号wr:写请求rd:读请求data:数据输⼊q:数据输出full:满信号,表⽰fifo吃饱了empty:空信号,表⽰fifo肚⼦已经空掉了usedw:表⽰fifo中已有的数据个数仿真:没有usedw款:有usedw款:资源使⽤量:如何设计⼀个异步FIFO?⼀般⽤作跨时钟域,可⽤ram搭。
判断读空与写满,读写指针要跨时钟域,所以采⽤格雷码减少亚稳态。
同步fifo的Verilog实现
同步fifo的Verilog实现FIFO是⼀种先进先出的数据缓存器,他与普通存储器相⽐: 优点:没有外部读写地址线,这样使⽤起来⾮常简单; 缺点:只能顺序写⼊数据,顺序的读出数据,其数据地址由内部读写指针⾃动加1完成,不能像普通存储器那样可以由地址线决定读取或写⼊某个指定的地址。
根据FIFO⼯作的时钟域,可以将FIFO分为同步FIFO和异步FIFO。
同步FIFO是指读时钟和写时钟为同⼀个时钟。
在时钟沿来临时同时发⽣读写操作。
异步FIFO是指读写时钟不⼀致,读写时钟是互相独⽴的。
FIFO设计的难点在于怎样判断FIFO的空/满状态。
为了保证数据正确的写⼊或读出,⽽不发⽣溢出或读空的状态出现,必须保证FIFO在满的情况下不能进⾏写操作,在空的状态下不能进⾏读操作。
因此,怎样判断FIFO的满/空就成了FIFO设计的核⼼问题。
实现⽅法1:module fifo(input clk,input rst,input din,input wr_en,input rd_en,output reg dout,output empty,output full);parameter WIDTH=4'd8,DEPTH=7'd64;//假设位宽为8,深度为64,只考虑深度为2的幂次⽅的情况reg [WIDTH-1 : 0] ram [DEPTH-1 : 0];//开辟存储区reg [5 : 0] count;reg rp,wp;//定义读写指针always@(posedge clk) begin if(rst) begin wp <= 0; rp <= 0; dout <= 0; empty <= 1; full <= 0; count <= 0; end else begin case({rd_en,wr_en}) begin 2'00:count <= count; 2'b01:begin if(~full) begin ram(wp) <= din; wp <= wp + 1; count <= count + 1; end end 2'b10:begin if(~empty) begin dout <= ram(rp); rp <= rp + 1; count <= count - 1; end end 2'b11:begin if(empty) begin ram(wp) <= din; wp <= wp + 1; count <= count + 1; end else begin ram(wp) <= din; wp <= wp + 1; dout <= ram(rp); rp <= rp + 1; count <= count; end end end endendassign full = (count == 6'd63) ? 1 : 0;assign empty = (count == 0) ? 1 : 0;实现⽅法2:module fifo(input clk,input rst,input din,input wr_en,input rd_en,output dout,output reg empty,output reg full);parameter WIDTH=4'd8,DEPTH=7'd64;//假设位宽为8,深度为64,只考虑深度为2的幂次⽅的情况reg [WIDTH-1 : 0] ram [DEPTH-1 : 0];//开辟存储区reg [DEPTH-1 : 0] count;wire [WIDTH-1 : 0] dout,din;//读写数据reg rp,wp;//定义读写指针//写⼊数据dinalways@(posedge clk) begin if((wr_en & ~full) || (full & wr_en & rd_en)) begin ram(wp) <= din; endend//读出数据doutassign dout = (rd_en & ~empty)?ram(rp):0;//写指针wpalways@(posedge clk)begin if(rst)begin wp <= 0; end else if(wr_en & ~full) begin wp <= wp + 1; end else if(full && (wr_en & rd_en)) begin wp <= wp + 1; endend//读指针rpalways@(posedge clk) begin if(rst) begin rp <= 0; end else if(rd_en & ~empty) begin rp <= rp + 1; endend//满标志fullalways@(posedge clk) begin if(rst) begin full <= 0; end else if((wr_en & ~rd_en) && (wp == rp - 1)) begin full <= 1; end else if(full & rd_en) begin full <= 0 endend//空标志emptyalways@(posedge clk) begin if(rst) begin empty <= 1; end else if(wr_en & empty) begin empty <= 0; end else if((rd_en & ~wr_en) && (rp == wp - 1)) begin empty <= 1; endend。
一同步FIFO的意思是说FIFO的读写时钟是同一个时钟不
一、同步FIFO的意思是说FIFO的读写时钟是同一个时钟,不同于异步FIFO,异步FIFO的读写时钟是完全异步的。
同步FIFO的对外接口包括时钟,清零,读请求,写请求,数据输入总线,数据输出总线,空以及满信号。
下面分别对同步FIFO的对外接口信号作一描述:1.时钟,输入,用于同步FIFO的读和写,上升沿有效;2.清零,输入,异步清零信号,低电平有效,该信号有效时,FIFO被清空;3.写请求,输入,低电平有效,该信号有效时,表明外部电路请求向FIFO写入数据;4.读请求,输入,低电平有效,该信号有效时,表明外部电路请求从FIFO中读取数据;5.数据输入总线,输入,当写信号有效时,数据输入总线上的数据被写入到FIFO中;6.数据输出总线,输出,当读信号有效时,数据从FIFO中被读出并放到数据输出总线上;7.空,输出,高电平有效,当该信号有效时,表明FIFO中没有任何数据,全部为空;8.满,输出,高电平有效,当该信号有效时,表明FIFO已经满了,没有空间可用来存贮数据。
使用VHDL描述的FIFO将以上面的接口为基础,并且可以参数化配置FIFO 的宽度和深度。
二、同步FIFO内部通过控制电路和RAM实现,控制电路主要包括写指针管理电路,读指针管理电路,以及FIFO状态判断电路,对于同步FIFO来讲,读和写的指针管理电路实际上就是二进制计数器。
现在的FPGA都具有Block RAM,通过VHDL描述可以对其进行调用,为了能够实现任意深度和宽度的FIFO,那么在用VHDL描述RAM的时候需要使用generic 使得RAM的调用能够参书化。
同样,对于读写指针计数器,也需要参数化的描述方法。
下面主要对FIFO的状态判断如何判断进行一些说明。
假设宽度任意而深度为8的FIFO,当读指针read_pointer和写指针write_pointer的值一样的时候,很显然,这时FIFO的状态为空。
比较麻烦的是对FIFO是否已经满的状态的判断,因为存在两种情况,第一种情况时写指针write_pointer比读指针read_pointer 大,比如writer_pointer = 7而read_pointer = 0,还有一种情况时写指针writer_pointer比读指针read_pointer小,比如writer_pointer = 2而read_pointer = 3。
EDA教程之第四章VHDL语言的主要描述语句
Y <= tmp;
END Process P1;
LOOP语句
循环变量(i)在信号说明、变量说明中不能出现,信号、 变量不能代入到循环变量中。
局部变量(tmp)仅能在进程中出现。 全局变量、信号可以将局部变量的值带ential statement
BEGIN
Indata <= S3 & S2 & S1 & S0;
P1:PROCESS (Indata, G1,G2)
IF( G1='0' AND G2='0') THEN
CASE indata IS
WHEN "0000"=> y <="01 11 11 11 11 11 11 11";
WHEN "0001"=> y <="10 11 11 11 11 11 11 11";
功能wait语句使系统暂时挂起(等同于end process),此时,信号值开始更新。条件满足后, 系统将继续运行。
顺序执行语句sequential statement
顺序执行语句sequential statement
顺序执行语句sequential statement
顺序执行语句sequential statement
并行处理语句concurrent statement
并行处理语句concurrent statement
并行处理语句concurrent statement
顺序执行语句和并行处理语句总结
1、顺序执行语句wait、assert、if -else 、 case、for-loop、while语句只能用在 process、function 和procedure 中; 2、并行处理语句(条件信号带入和选择信 号带入)只能用在architecture、block中;
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
同步F I F O之V H D L描述(1)同步FIFO之VHDL描述同步FIFO的意思是说FIFO的读写时钟是同一个时钟,不同于异步FIFO,异步FIFO的读写时钟是完全异步的。
同步FIFO的对外接口包括时钟,清零,读请求,写请求,数据输入总线,数据输出总线,空以及满信号。
下面分别对同步FI FO的对外接口信号作一描述:1.时钟,输入,用于同步FIFO的读和写,上升沿有效;2.清零,输入,异步清零信号,低电平有效,该信号有效时,FIFO被清空;3.写请求,输入,低电平有效,该信号有效时,表明外部电路请求向FIF O写入数据;4.读请求,输入,低电平有效,该信号有效时,表明外部电路请求从FIF O中读取数据;5.数据输入总线,输入,当写信号有效时,数据输入总线上的数据被写入到FIFO中;6.数据输出总线,输出,当读信号有效时,数据从FIFO中被读出并放到数据输出总线上;7.空,输出,高电平有效,当该信号有效时,表明FIFO中没有任何数据,全部为空;8.满,输出,高电平有效,当该信号有效时,表明FIFO已经满了,没有空间可用来存贮数据。
使用VHDL描述的FIFO将以上面的接口为基础,并且可以参数化配置FIFO的宽度和深度。
先把对外接口描述出来吧。
--------------------------------------- Designer : skycanny-- Date : 2007-1-29-- Description : Synchronous FIFO created by VHDL library ieee;use sfifo isgeneric(width : positivedepth : positive);port(clk : in std_logic;rst : in std_logic;wq : in std_logic;rq : in std_logic;data : in std_logic_vector(width - 1 downto 0);q : in std_logic_vector(width - 1 downto 0);empty : out std_logic;full : out std_logic);end entity sfifo;---------------------------------------同步FIFO内部通过控制电路和RAM实现,控制电路主要包括写指针管理电路,读指针管理电路,以及FIFO状态判断电路,对于同步FIFO来讲,读和写的指针管理电路实际上就是二进制计数器。
现在的FPGA都具有Block RAM,通过VHDL描述可以对其进行调用,为了能够实现任意深度和宽度的FIFO,那么在用VHDL描述RAM的时候需要使用generic使得RAM的调用能够参书化。
同样,对于读写指针计数器,也需要参数化的描述方法。
下面主要对FIFO的状态判断如何判断进行一些说明。
假设宽度任意而深度为8的FIFO,当读指针read_pointer和写指针write_pointer的值一样的时候,很显然,这时FIFO的状态为空。
比较麻烦的是对FIFO是否已经满的状态的判断,因为存在两种情况,第一种情况时写指针write_pointer比读指针read_pointer 大,比如writer_pointer = 7而read_pointer = 0,还有一种情况时写指针wri ter_pointer比读指针read_pointer小,比如writer_pointer = 2而read_poin ter = 3。
由于读写电路在循环的读写RAM,所以在上面的两种情况下FIFO实际上都已经满了。
那么如何对读写指针的判断比较容易的得出FIFO已经满了,同时这样的判断电路还要容易参数化第一种情况下,write_pointer – read_pointer = 7,实际上就是FIFO深度减一,第二种情况下,(write_pointer + 8) – read_ pointer = 7,也是FIFO深度减一。
从上面的讨论就可以很容易进行判断FIFO状态了,假设FIFO的深度用depth表示,则FIFO状态判断用伪码表示如下:1. Empty状态判断:If writer_pointer = read_pointerFIFO is empty;ElseFIFO is not empty;End if;2. Full状态判断:If writer_pointer > read_pointerIf write_pointer – read_pointer = depthFIFO is full;ElseFIFO is not full;End if;ElseIf write_pointer – read_pointer = 1FIFO is full;ElseFIFO is not full;End if;End if;下面的框图主要描述同步FIFO的内部结构,画出框图有助于对电路结构的理解,同样也有助于RTL代码的编写今天就先写到这里吧,大家有什么问题和意见可以提出来,以便我及早的发现问题,不要等到要写代码的的时候才发现就麻烦了。
今天又重新安装了UltraEdit, Quartus 和Modelsim SE ,这次安装以后系统没有发现什么异常。
另外还安装了紫光的拼音输入法,用习惯了这个,微软呀,智能ABC这些都用不太习惯。
最后把系统备份了一下,以免将来出了什么问题还可以还原一下,呵呵。
还是接着昨天的《同步FIFO之VHDL描述》。
突然发现用于实现FIFO的RAM必须是真正意义上的双口RAM,也就是读写可以同时进行的,以前只是用VHDL描述过单端口的RAM,双口RAM还没有描述过,不过曾经看到过Xilinx FPGA/CPLD 的开发工具ISE的Core Genertor好像提供双口RAM的软核,所以我想用HDL语言也就应该可以描述从而调用双口RAM,这个等到具体写双口RAM的RTL代码的时候再研究。
还有一个问题就是FIFO的读写请求控制信号必须要控制FIFO读写指针的产生电路,只有读写信号信号有效的时候,FIFO读写指针才能是有效的,负责是无效而且要保持不变,这个容易理解。
今天,就先完成写指针产生和管理电路的RTL代码吧,其实很简单,就是一个二进制计数器。
下面就是VHDL的代码,大家看看有没有什么问题。
------------------------------------------------------------------------------------------------------------- Designer : skycanny-- Date : 2007-2-2-- Description : write_pointer is created-- Modification : add FIFO status full judge 2007-2-3 skycannywr_pt_t <= (others => '0');elsif clk'event and clk = '1' then if wq = '0' and full = '0' thenwr_pt_t <= wr_pt_t + 1;end if;end process;wr_pt <= wr_pt_t;end RTL;同步FIFO之VHDL描述 (2)今天准备完成同步FIFO其他模块的代码,主要包括读指针管理和产生电路,FI FO状态判断电路,以及双端口RAM的VHDL描述。
先是读指针管理和产生电路:------------------------------------------------------------------------------------------------------------- Designer:skycanny-- Date:2007-2-3-- Description:read_pointer is createdlibrary ieee;useuseuse read_pointer isgeneric( depth:positive?);port( clk:instd_logic;rst:instd_logic;rq:instd_logic;empty:instd_logic;rd_pt:outstd_logic_vector(depth - 1 downto 0)?);end entity read_pointer;architecture RTL of read_pointer issignalrd_pt_t:std_logic_vector(depth - 1 downto 0); -- read pointer counterbeginprocess(rst, clk)beginif rst = '0' thenrd_pt_t <= (others => '0');elsif clk'event and clk = '1' thenif rq = '0' and empty = '0' thenrd_pt_t <= rd_pt_t + 1;end if;end process;rd_pt <= rd_pt_t;end RTL;------------------------------------------------------------------------------------------------------------刚才想了一下,读写指针产生电路必须要对FIFO的状态进行判断,所以又对上面的代码进行了一点修改(上面的代码是修改过的),判断FIFO的状态,这一点在刚开始的时候给疏忽了,幸好刚才给发现了。
同样昨天写的写指针产生电路没有判断FIFO的full状态,也要进行修改,还是在昨天的基础上修改吧,就不在这里罗嗦了,下面就是FIFO状态判断电路的VHDL描述。
------------------------------------------------------------------------------------------------------------- Designer : skycanny-- Date : 2007-2-3-- Description : read_pointer is createdlibrary ieee;use judge_status isgeneric(depth : positive);port(clk : in std_logic;rst : in std_logic;wr_pt : in std_logic_vector(depth - 1 downto 0);rd_pt : in std_logic_vector(depth - 1 downto 0);empty : out std_logic;full : out std_logic);end entity judge_status;architecture RTL of judge_status isbeginprocess(rst, clk)beginif rst = '0 thenempty <= '1';elsif clk'event and clk = '1' thenif wr_pt = rd_pt thenempty <= '1';elseempty <= '0';end if;end if;end process;process(rst, clk)beginif rst = '0' thenfull <= '0';elsif clk 'event and clk = '1' then if wr_pt > rd_pt thenif (rd_pt + depth) = wr_pt thenfull <= '1';elsefull <= '0';end if;elseif (wr_pt + 1 ) = rd_pt thenfull <= '1';elsefull <= '0';end if;end if;end if;end process;end RTL;-----------------------------------------------------------------------------------------------------------广告时间欢迎访问。