verilog同步和异步FIFO,可直接仿真和综合

合集下载

Verilog笔记.5.同步、异步

Verilog笔记.5.同步、异步

Verilog笔记.5.同步、异步在数字电路中经常有同步synchronism、异步asynchronism的概念。

异步指输⼊信号和时钟⽆关;同步指输⼊信号和时钟信号有关,实际上就是输⼊信号和时钟信号进⾏了与运算或者与⾮运算。

实际开发中,经常有同步清零、异步清零、同步复位、异步复位等概念,下⾯就给与相关代码演⽰。

简单的异步复位1always @ (posedge clk or negedge rst_n)2if(!rst_n) b <= 1'b0;3else b <= a;简单的同步复位1always @ (posedge clk)2if(!rst_n) b <= 1'b0;3else b <= a;PS:同步复位信号RST必须⾄少长于⼀个时钟周期CLK,否则,这个复位信号引起的变化是不会被检测到的!异步复位、同步释放1always @ (posedge clk)2 rst_nr <= rst_n; //现将异步复位信号⽤同步时钟打⼀拍34always @ (posedge clk or negedge rst_nr)5if(!rst_nr) b <= 1'b0;6else b <= a;78always @ (posedge clk or negedge rst_nr)9if(!rst_nr) c <= 1'b0;10else c <= b;同步复位和异步复位的区别就在于前者的复何信号不能出现在always语句的敏感信号表中,⽆论是同步复位还是异步复位,always语句的结构都是if(Reset)...else... ,否则,综合⼯具将不能正确的综合所有always语句中的赋值最好采⽤⾮阻塞赋值语,否则,可能会导致仿真与综合的不⼀致”。

verilog语言的综合与不可综合

verilog语言的综合与不可综合

Verilog的综合与不可综合综合说明编的代码可以对应出具体的电路,不可综合说明没有对应的电路结构。

不可综合的代码编译通过,只能看到输出,不能实现电路,就是不能用来制作具体的芯片。

一、基本Verilog中的变量有线网类型和寄存器类型。

线网型变量综合成wire,而寄存器可能综合成WIRE,锁存器和触发器。

二:verilog语句结构到门级的映射1、连续性赋值:assign连续性赋值语句逻辑结构上就是将等式右边的驱动左边的结点。

因些连续性赋值的目标结点总是综合成由组合逻辑驱动的结点。

Assign语句中的延时综合时都将忽视。

2、过程性赋值:过程性赋值只出现在always语句中。

阻塞赋值和非阻塞赋值就该赋值本身是没有区别的,只是对后面的语句有不同的影响。

建议设计组合逻辑电路时用阻塞赋值,设计时序电路时用非阻塞赋值。

过程性赋值的赋值对象有可能综合成wire,latch,和flip-flop,取决于具体状况。

如,时钟控制下的非阻塞赋值综合成flip-flop。

过程性赋值语句中的任何延时在综合时都将忽略。

建议同一个变量单一地使用阻塞或者非阻塞赋值。

3、逻辑操作符:逻辑操作符对应于硬件中已有的逻辑门4、算术操作符:Verilog中将reg视为无符号数,而integer视为有符号数。

因此,进行有符号操作时使用integer,使用无符号操作时使用reg。

5、进位:通常会将进行运算操作的结果比原操作数扩展一位,用来存放进位或者借位。

如:Wire [3:0] A,B;Wire [4:0] C;Assign C=A+B;C的最高位用来存放进位。

6、关系运算符:关系运算符:<,>,<=,>=和算术操作符一样,可以进行有符号和无符号运算,取决于数据类型是reg,net还是integer。

7、相等运算符:==,!=注意:===和!==是不可综合的。

可以进行有符号或无符号操作,取决于数据类型8、移位运算符:左移,右移,右边操作数可以是常数或者是变量,二者综合出来的结果不同。

异步FIFO的Verilog HDL设计

异步FIFO的Verilog HDL设计

随 着 I 计 规 模 的不 断 扩 大 , 多 元 件 集 成 在 同 一 裸 片 C设 更 上 , 裸片尺寸越来越大 , 使 同步化设 计越 来越 困难 。一些新 的 方法 , 如整体异步局部同步( A S 结 构正在替代通 常的 同步 G L) 方法 J这样一个系统中就往往含 有多个时 钟 , , 不可避 免地要
维普资讯
旦丝堕窒 旦
文章编号 : 7 —14 (0 8 0 0 6 0 1 1 0 1 20 )3— 0 8— 2 6
仪 器仪表 用户
异步 F F 的 Vei gHD IO r o L设 计 l
蔡 发 志 ,苏 进 ,叶 兵
( 合肥 工业 大学 理学 院 , 肥 2 0 0 合 3 0 9)
通过 了验 证 。 关键 词 :亚稳 态 ;异步 时钟 域 ;同步 ; 雷 码 格
2 异 步设 计所产 生的 问题
2 1 亚 稳 态 .
中图分类号 : N 3 文献标识码 : T 42 B
Th eL ed sg fay c r n u I wi v rl h o
c m mu iat ewe feen lc oman gi C e in,Ths o nc e b t endi r tco kd isdi t I d sg al i t ss m a e n a alss a d rs rhf ra y c r n u F me he i k sa n y i n e eac o s n h o o s FIO m— or y,u ig gry c e oner a d dvdig t e d e s p c no sn a od p it s n ii n h a drs s a e it s m equ d a t odit g ih b t e ul n m py.Th e in i o a r nst si us ewe n fla d e n t e d sg s ba e n h ero HDL an u ge, d h e ut f s d o te v i g l l g a an te r s l o mo lsm s de i smuai n PGA eria i ot diae t e g e il i lt on a d F v ic t f on b h i c t hed sin i fasbe. n s Ke y wors: m ea t ly; a y c r o s lck do is; s n hr— d tsabl i t s n hon u co man y c o nz ie;Gry c e a od

verilog之可综合与不可综合

verilog之可综合与不可综合

verilog之可综合与不可综合可综合的意思是说所编写的代码可以对应成详细的,不行综合就是所写代码没有对应的电路结构,例如行为级语法就是一种不行综合的代码,通常用于写测试文件。

建立可综合模型时,需注重以下几点:不用法initial不用法10之类的延时语句不用法循环次数不确定的循环语句,如forever,while等不用法用户自定义原语(UDP元件)尽量用法同步方式设计电路用always块来描述组合规律时,应列出全部输入信号作为敏感信号列表,即always@(*)全部的内部寄存器都应当能够被复位,在用法实现设计时,尽量用法器件的全局复位端作为系统的总复位对时序规律描述和建模,尽量用法非堵塞赋值的方式,对组合规律描述和建模,虽然堵塞和非堵塞赋值的方式都可以,但在同一过程快中最好不要同时用法堵塞赋值和非堵塞赋值。

我个人比较推举用堵塞赋值的方式描述组合规律不能在多个always块中对同一个变量举行赋值。

对同一个对象不能既用法非堵塞赋值,又用法堵塞赋值假如不决定让变量生成锁存器,那么必需在用法if语句或case语句时补全全部条件不行综合语句:initial 初始化语句,只能在testbench中用法,不行综合event event在同步testbench时更实用,不能综合real 不支持real数据类型的综合time 不支持time数据类型的综合assign 和 deassign 不支持对reg数据类型赋值的综合,但支持wire类型赋值的综合以开始的延时语句不能被综合verilog是一种硬件描述语言,我们在写verilog 代码时,首先要有所要写的module在硬件上如何实现的概念,而不是去想编译器如何说明这个module。

比如在打算是否用法 reg 定义时,要问问自己物理上是不是真正存在这个 register, 假如是,它的clock 是什么? D 端是什么?Q 端是什么?有没有清零和置位?同步还是异步?再比如上面研究的三态输出问题,首先想到的应当是在 register 的输出后面加一个三态门,而不是如何才干让编译器知道要“赋值”给一个信号为三态。

verilog基本电路设计(包括:时钟域同步、无缝切换、异步fifo、去抖滤波))

verilog基本电路设计(包括:时钟域同步、无缝切换、异步fifo、去抖滤波))

Verilog基本电路设计(包括:时钟域同步、无缝切换、异步FIFO、去抖滤波))Verilog基本电路设计共包括四部分:单bit跨时钟域同步时钟无缝切换异步FIFO去抖滤波Verilog基本电路设计之一: 单bit跨时钟域同步(帖子链接:/thread-605419-1-1.html)看到坛子里不少朋友,对于基本数字电路存在这样那样的疑惑,本人决定开贴,介绍数字电路最常见的模块单元,希望给初学者带来帮助,也欢迎大佬们前来拍砖。

如果想要做数字设计,下面这些电路是一定会碰到的,也是所有大型IP,SOC设计必不可少的基础,主要包括异步信号的同步处理,同步FIFO,异步FIFO,时钟无缝切换,信号滤波debounce等等,后面会根据大家反馈情况再介绍新电路。

首先介绍异步信号的跨时钟域同步问题。

一般分为单bit的控制信号同步,以及多bit的数据信号同步。

多bit的信号同步会使用异步FIFO完成,而单bit的信号同步,又是时钟无缝切换电路以及异步FIFO电路的设计基础,这里先介绍单bit信号同步处理。

clka域下的信号signal_a,向异步的clkb域传递时,会产生亚稳态问题。

所有的亚稳态,归根结底就是setup/hold时间不满足导致。

在同一个时钟域下的信号,综合以及布线工具可以在data路径或者clock路径上插入buffer使得每一个DFF的setup/hold时间都满足;但是当signal_a在clkb域下使用时,由于clka与clkb异步,它们的相位关系不确定,那么在clkb的时钟沿到来时,无法确定signal_a此时是否处于稳定无变化状态,也即setup/hold时间无法确定,从而产生亚稳态。

这种异步信号在前后端流程里面是无法做时序分析的,也就是静态时序分析里常说的false_path。

消除亚稳态,就是采用多级DFF来采样来自另一个时钟域的信号,级数越多,同步过来的信号越稳定。

对于频率很高的设计,建议至少用三级DFF,而两级DFF同步则是所有异步信号处理的最基本要求。

verilog同步和异步FIFO,可直接仿真和综合解读

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的了解。

Verilog语言的可综合性

Verilog语言的可综合性

V e r i l o g 语言的可综合性可综合的Verilog HDL 语句都是V e r i l o g H D L 标准( I E E E 1 3 6 4 ) 的一个子集,并且因所用工具不同而异。

在设计中不能采用不可综合的语句( 测试代码除外) 。

下面我们讨论一下大部分综合工具都支持的语句,具体到某种工具的特性还要查看说明文档。

对于数据类型、运算符、赋值语句、基本门级元件等的可综合性问题,因为都有固定的规定,这里就不多讨论了。

组合逻辑和时序逻辑的可综合性: 用a s s i g n 语句对w i r e 型变量进行赋值,综合后的结果是组合逻辑电路。

用a l w a y s @ ( 电平敏感变量表) ,即电平敏感的a l w a y s 块描述的电路综合后的结果是组合逻辑电路或电平敏感的锁存器,此时,a l w a y s 块内赋值语句左边的变量是r e g或i n t e g e r 型,块中要避免组合反馈回路,每次执行a l w a y s 块时,在生成组合逻辑的a l w a y s 块中被赋值的所有信号必须都在敏感电平列表中列出,否则在综合时将会为没有列出的信号隐含的产生一个透明的锁存器,这时综合后的电路已不是纯组合电路了。

用a l w a y s @( p o s e d g e c l o c k ) 或a l w a y s @ ( n e g e d g e c l o c k ) 块描述的电路综合为同步时序逻辑电路,设计同步时序逻辑电路的关键是建立描述该电路状态转移的可综合的有限状态机模型,在V e r i l o g H D L语言中最常用的描述同步时序状态机的结构是a l w a y s 和块内的c a s e . i f 语句,除了紧跟在a l w a y s 后的@( p o s e d g e c l o c k ) , @ ( n e g e d g e c l o c k ) 外,a l w a y s 块中不允许其他的@ ( e v e n t ) 语句,目前大多数综合工具不能综合V e r i l o g H D L描述的异步状态机,所以用V e r i l o g 设计的时序电路应该是同步时序电路。

怎么用Verilog语言描述同步FIFO和异步FIFO

怎么用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µÄVerilog?úÂëmodule fifo_syn(datain,rd,wr,rst,clk,dataout,full,empty);input [7:0] datain;input rd, wr, rst, clk;output [7:0] dataout;output full, empty;reg [7:0] dataout;reg full_in, empty_in;reg [7:0] mem [15:0];reg [3:0] rp, wp;assign full = full_in;assign empty = empty_in;// memory read out ÉÔ×?ÐÞ?Äalways@(posedge clk) beginif(rd && ~empty_in) dataout = mem[rp];end// memory write inalways@(posedge clk) beginif(wr && ~full_in) mem[wp]<=datain;end// memory write pointer incrementalways@(posedge clk or negedge rst)if(!rst)wp<=0;else wp <= (wr && ~full_in) ? (wp + 1'b1) : wp;// memory read pointer incrementalways@(posedge clk or negedge rst)if(!rst)rp <= 0;else rp <= (rd && ~empty_in)? (rp + 1'b1): rp;// Full signal generatealways@(posedge clk or negedge rst) beginif(!rst) full_in <= 1'b0;else beginif( (~rd && wr)&&((wp==rp-1) | | (rp==4'h0&&wp==4'hf))) full_in <= 1'b1;else if(full_in && rd) full_in <= 1'b0;endend// Empty signal generatealways@(posedge clk or negedge rst) beginif(!rst) empty_in <= 1'b1;else beginif((rd&&~wr)&&(rp==wp-1 || (rp==4'hf&&wp==4'h0)))empty_in<=1'b1;else if(empty_in && wr) empty_in<=1'b0;endendendmodule******************************************************************** ***********ÍøÉϵÄ?úÂë?ÁÊý?ÝÊä?ö(dataout)Ö??ÊÜ?ÁÊ?ÄÜ(rd)?ØÖÆ??ÏÔÈ?Ô??ËùÒÔÉ Ô×?ÐÞ?ÄÓ,ÅúÆÀ******************************************************************** ******************ÁíÒ?ÖÖ?ç?ñµÄÍFIFOmodule FIFO_Buffer(Data_out,stack_full,stack_almost_full,stack_half_full,stack_almost_empty,stack_empty,Data_in,write_to_stack,read_from_stack,clk,rst);parameter stack_width=32;parameter stack_height=8;parameter stack_ptr_width=3;parameter AE_level=2;parameter AF_level=6;parameter HF_level=4;output [stack_width-1:0] Data_out;output stack_full,stack_almost_full,stack_half_full; output stack_almost_empty,stack_empty;input[stack_width-1:0] Data_in;input write_to_stack,read_from_stack;input clk,rst;reg[stack_ptr_width-1:0] read_ptr,write_ptr;reg[stack_ptr_width:0] ptr_gap;reg[stack_width-1:0] Data_out;reg[stack_width-1:0] stack[stack_height-1:0]; assign stack_full=(ptr_gap==stack_height);assign stack_almost_full=(ptr_gap==AF_level);assign stack_half_full=(ptr_gap==HF_level);assign stack_almost_empty=(ptr_gap==AE_level);assign stack_empty=(ptr_gap==0);always @(posedge clk or posedge rst)if(rst)beginData_out<=0;read_ptr<=0;write_ptr<=0;ptr_gap<=0;endelse if(write_to_stack &&(!stack_full)&&(!read_from_stack))begin stack[write_ptr]<=Data_in;write_ptr<=write_ptr+1;ptr_gap<=ptr_gap+1;endelse if((!write_to_stack)&&(!stack_empty)&&read_from_stack)begin Data_out<=stack[read_ptr];read_ptr<=read_ptr+1;ptr_gap<=ptr_gap-1;endelse if(write_to_stack &&read_from_stack&&stack_empty)begin stack[write_ptr]<=Data_in;write_ptr<=write_ptr+1;ptr_gap<=ptr_gap+1;endelse if(write_to_stack &&read_from_stack&&stack_full)beginData_out<=stack[read_ptr];read_ptr<=read_ptr+1;ptr_gap<=ptr_gap-1;endelseif(write_to_stack&&read_from_stack&&(!stack_full)&&(!stack_empty)) beginData_out<=stack[read_ptr];stack[write_ptr]<=Data_in;read_ptr<=read_ptr+1;write_ptr<=write_ptr+1;endendmoduleÏÔÈ?Õâ?ö?È?ÏÈÝÒ×Àí?â。

可综合的verilog语句

可综合的verilog语句

可综合的verilog语句摘要:一、引言1.Verilog 简介2.Verilog 语句的可综合性二、可综合的Verilog 语句1.基本赋值语句2.组合逻辑实现3.时序逻辑实现4.实例化模块三、Verilog 语句的可综合性分析1.基本赋值语句的可综合性2.组合逻辑实现的可综合性3.时序逻辑实现的可综合性4.实例化模块的可综合性四、提高Verilog 代码可综合性的方法1.遵循可综合编程规范2.使用可综合的语法结构3.模块划分与层次设计五、总结1.Verilog 语句可综合性的重要性2.提高代码可综合性的实际应用价值正文:【引言】Verilog 是一种广泛应用于数字电路设计和验证的硬件描述语言。

在Verilog 中,语句的可综合性指的是能否将Verilog 代码转换为实际硬件电路。

了解可综合的Verilog 语句对于编写高效的硬件描述语言代码至关重要。

本文将介绍可综合的Verilog 语句及其可综合性分析,并提出提高代码可综合性的方法。

【可综合的Verilog 语句】Verilog 中有很多可综合的语句,包括基本赋值语句、组合逻辑实现、时序逻辑实现和实例化模块。

1.基本赋值语句基本赋值语句包括阻塞赋值(assignment)和非阻塞赋值(non-blocking assignment)。

这两种赋值语句都是可综合的。

2.组合逻辑实现组合逻辑实现通常使用与门(and)、或门(or)、非门(not)等基本逻辑门实现。

这些逻辑门的Verilog 实现都是可综合的。

3.时序逻辑实现时序逻辑实现通常使用寄存器(register)、计数器(counter)等元件实现。

这些元件的Verilog 实现都是可综合的。

4.实例化模块实例化模块是通过使用`实例化`关键字将一个模块复制多次。

实例化模块的Verilog 实现也是可综合的。

【Verilog 语句的可综合性分析】1.基本赋值语句的可综合性基本赋值语句的可综合性取决于赋值的目标。

同步FIFO和异步FIFO的Verilog实现

同步FIFO和异步FIFO的Verilog实现

FIFO是英文First In First Out 的缩写,是一种先进先出的数据缓存器,他与普通存储器的区别是没有外部读写地址线,这样使用起来非常简单,但缺点就是只能顺序写入数据,顺序的读出数据,其数据地址由内部读写指针自动加1完成,不能像普通存储器那样可以由地址线决定读取或写入某个指定的地址。

FIFO一般用于不同时钟域之间的数据传输,比如FIFO的一端是AD 数据采集,另一端是计算机的PCI总线,假设其AD采集的速率为16位100K SPS,那么每秒的数据量为100K×16bit=1.6Mbps,而PCI总线的速度为33MHz,总线宽度32bit,其最大传输速率为1056Mbps,在两个不同的时钟域间就可以采用FIFO来作为数据缓冲。

另外对于不同宽度的数据接口也可以用FIFO,例如单片机位8位数据输出,而DSP 可能是16位数据输入,在单片机与DSP连接时就可以使用FIFO来达到数据匹配的目的。

FIFO的分类根据FIFO工作的时钟域,可以将FIFO分为同步FIFO和异步FIFO。

同步FIFO是指读时钟和写时钟为同一个时钟。

在时钟沿来临时同时发生读写操作。

异步FIFO是指读写时钟不一致,读写时钟是互相独立的。

FIFO设计的难点在于怎样判断FIFO的空/满状态。

为了保证数据正确的写入或读出,而不发生益处或读空的状态出现,必须保证FIFO在满的情况下,不能进行写操作。

在空的状态下不能进行读操作。

怎样判断FIFO的满/空就成了FIFO设计的核心问题。

.............................................................................................................. ...........................同步FIFO的Verilog代码之一在modlesim中验证过。

/******************************************************A fifo controller verilog description.******************************************************/module fifo(datain, rd, wr, rst, clk, dataout, full, empty);input [7:0] datain;input rd, wr, rst, clk;output [7:0] dataout;output full, empty;wire [7:0] dataout;reg full_in, empty_in;reg [7:0] mem [15:0];reg [3:0] rp, wp;assign full = full_in;assign empty = empty_in;// memory read outassign dataout = mem[rp];// memory write inalways@(posedge clk) beginif(wr && ~full_in) mem[wp]<=datain;end// memory write pointer incrementalways@(posedge clk or negedge rst) beginif(!rst) wp<=0;else beginif(wr && ~full_in) wp<= wp+1'b1;endend// memory read pointer incrementalways@(posedge clk or negedge rst)beginif(!rst) rp <= 0;else beginif(rd && ~empty_in) rp <= rp + 1'b1;endend// Full signal generatealways@(posedge clk or negedge rst) beginif(!rst) full_in <= 1'b0;else beginif( (~rd && wr)&&((wp==rp-1)||(rp==4'h0&&wp==4'hf))) full_in <= 1'b1;else if(full_in && rd) full_in <= 1'b0;endend// Empty signal generatealways@(posedge clk or negedge rst) beginif(!rst) empty_in <= 1'b1;else beginif((rd&&~wr)&&(rp==wp-1 || (rp==4'hf&&wp==4'h0)))empty_in<=1'b1;else if(empty_in && wr) empty_in<=1'b0;endendendmodule.............................................................................................................. .............同步FIFO的Verilog代码之二这一种设计的FIFO,是基于触发器的。

使用VerilogHDL实现异步FIFO设计与实现FIFO读写时序[试题]

使用VerilogHDL实现异步FIFO设计与实现FIFO读写时序[试题]

使用Verilog HDL实现异步FIFO设计与实现FIFO 读写时序在现代IC设计中,特别是在模块与外围芯片的通信设计中,多时钟域的情况不可避免。

当数据从一个时钟域传递到另一个域,并且目标时钟域与源时钟域不相关时,这些域中的动作是不相关的,从而消除了同步操作的可能性,并使系统重复地进入亚稳定状态[1]。

在有大量的数据需要进行跨时钟域传输且对数据传输速度要求比较高的场合,异步FIFO 是一种简单、快捷的解决方案。

异步FIFO用一种时钟写入数据,而用另外一种时钟读出数据。

读写指针的变化动作由不同的时钟产生。

因此,对FIFO空或满的判断是跨时钟域的。

如何根据异步的指针信号产生正确的空、满标志,是异步FIFO设计成败的关键。

本文提出一种新颖的异步FIFO设计方案,它通过先比较读写地址并结合象限检测法产生异步的空/满标志,再把异步的空/满标志同步到相应的时钟域。

通过仿真验证,该方法是稳定有效的。

1异步信号传输问题的分析在一个AS IC或FPGA库中,每种触发器都有时序要求。

对于使用上升沿触发的触发器来说,建立时间(Setup Time)是在时钟上升沿到来之前,触发器数据保持稳定的最小时间;而保持时间(Hold Time)是在时钟上升沿到来之后,触发器数据还应该保持的最小时间[2]。

如图1所示,在时钟上升沿前后的这个窗口内数据应该保持不变,否则会使触发器工作在一个不确定的状态,即亚稳态。

当触发器处于亚稳态,且处于亚稳态的时间超过了一个时钟周期时,这种不确定的状态将会影响到下一级的触发器,最终导致连锁反应,从而使整个系统功能失常。

当一个信号跨越某个时钟域时,对新时钟域的电路来说它就是一个异步信号。

由于异步信号之间的时序是毫无关系的,因此必然存在SetupTime/Hold Time冲突。

为了避免亚稳态问题,采用如图2所示的双锁存器法[3],即在一个信号进入另一个时钟域前,将该信号用两个锁存器连续锁存两次,最后得到的采样结果就可以消除亚稳态。

基于verilog hdl的异步FIFO设计

基于verilog hdl的异步FIFO设计

基于verilog hdl的异步FIFO设计陕西理工学院毕业设计题目基于verilog hdl的异步FIFO设计学生姓名薛博阳学号 1113014175所在学院物理与电信工程学院专业班级电子1105 指导教师吴燕 __ ____ __完成地点博远楼实验室年月日第 1 页共 36 页陕西理工学院毕业设计基于Verilog HDL的异步FIFO设计与实现摘要在现代IC设计中,特别是在模块与外围芯片的通信设计中,多时钟域的情况不可避免。

当数据从一个时钟域传递到另一个域,并且目标时钟域与源时钟域不相关时,这些域中的动作是不相关的,从而消除了同步操作的可能性,并使系统重复地进入亚稳定状态,出)存储器来实现。

本文提出一种新颖的异步FIFO设计方案,它通过先比较读写地址并结合象限检测法产生异步的空/满标志,再把异步的空/满标志同步到相应的时钟域。

通过仿真验证,该方法是稳定有效的。

关键词:异步;FIFO;亚稳态;格雷码;结绳法第 2 页共 36 页造成系统时钟时序上的紊乱。

为了有效的解决这个问题,我们采用一种异步FIFO(先进先陕西理工学院毕业设计Design and accomplish asynchronousFIFO based on Verilog HDLAbstractIn modern IC design, particularly in the communications module and peripheral chip design, multiple clock domains of the inevitable. When data passes from one clock domain to another domain, and the target clock domains are not associated with the source clock domain, these domains are not related movements, thus eliminating the possibility of simultaneous operation and allows the system to enter the sub-repeat steady-state, causing disorder on the system clock timing. In order to effectively solve this problem, we use a asynchronous FIFO (FIFO) memory to achieve. This paper proposes a novel asynchronous FIFO design, which compared reading and writing through the first address and generate an asynchronous combination of quadrant detection empty / full flag, then asynchronous empty / full flag synchronized to the corresponding clock domain. The simulation results that the method is stable and effective.Key Words: asynchronous; FIFO; metastable state; Gray code; tie knots France第 3 页共 36 页陕西理工学院毕业设计目录1 引言 (6)1.1 FIFO研究意义 ........................................................6 1.2 生产需求状况 (6)1.3 存储器外发展状况 (7)1.4 FIFO设计技术简介 (9)1.4.1 基于信元的FIFO设计方法 (9)1.4.2 基于SRAM/DRAM的大容量FIFO的设计与实现 ........................ 9 1.5 异步FIFO设计中存在的问题及解决办法 .. (10)1.5.1 亚稳态 (10)1.5.2 空/满指针的解决方法 ........................................... 11 1.6 论文主要内容 ....................................................... 11 2 异步FIFO工作原理简介 . (12)2.1 关于异步信号 ....................................................... 12 2.2 异步FIFO芯片简介 .. (13)2.3 FIFO的一些重要参数 (14)2.4 异步FIFO设计的难点 (15)2.4.1 异步FIFO设计难点概述 (15)2.4.1.1 解决FIFO的满/空技术方法概述和特点 (15)2.4.1.2 亚稳态问题的产生及解决 (15)2.5 FIFO的功能简介 .....................................................16 2.6 Modelsim仿真工具简介 (16)2.6.1 主要特点 (16)2.7 Verilog HDL语言的简介 (17)2.8 HDL语言 (17)2.8.1 HDL与原理图输入法的关系 (17)2.8.2 HDL开发流程 (17)3 异步FIFO实现的技所涉及的技术及其解决方法 (18)3.1格雷码 ..............................................................18 3.2结绳法 (19)4 异步FIFO具体实现方法 ....................................................204.1 亚稳态问题的解决方案 ...............................................204.1.1 问题的产生 (20)4.1.2 常见的解决方法 (21)4.1.2.1 格雷码编码法 (21)4.1.2.2 双触发器法 .............................................. 22 4.1.2.3结绳法 (22)4.2 基于异步比较FIFO逻辑标志的产生 ....................................234.2.1 设计思想 (23)4.2.2 标志位的产生 (24)4.2.2.1 异步比较FI FO逻辑标志与时钟的同步 (24)4.2.2.2 保守的空/满标志 ......................................... 26 4.2.2.3半满、将近满、将近空的产生 (27)第 4 页共 36 页陕西理工学院毕业设计4.2.2.4 FIFO异步空/满信号的同步 (28)4.3 仿真验证和综合 .....................................................28 5 总结 (29)5.1 异步FIFO设计的总结 ................................................29 5.2 设计方法的不足之处 (29)附录一 .....................................................................30 参考文献 (35)第 5 页共 36 页感谢您的阅读,祝您生活愉快。

Verilog语言的可综合性

Verilog语言的可综合性

V e r i l o g 语言的可综合性可综合的Verilog HDL 语句都是V e r i l o g H D L 标准( I E E E 1 3 6 4 ) 的一个子集,并且因所用工具不同而异。

在设计中不能采用不可综合的语句( 测试代码除外) 。

下面我们讨论一下大部分综合工具都支持的语句,具体到某种工具的特性还要查看说明文档。

对于数据类型、运算符、赋值语句、基本门级元件等的可综合性问题,因为都有固定的规定,这里就不多讨论了。

组合逻辑和时序逻辑的可综合性: 用a s s i g n 语句对w i r e 型变量进行赋值,综合后的结果是组合逻辑电路。

用a l w a y s @ ( 电平敏感变量表) ,即电平敏感的a l w a y s 块描述的电路综合后的结果是组合逻辑电路或电平敏感的锁存器,此时,a l w a y s 块内赋值语句左边的变量是r e g或i n t e g e r 型,块中要避免组合反馈回路,每次执行a l w a y s 块时,在生成组合逻辑的a l w a y s 块中被赋值的所有信号必须都在敏感电平列表中列出,否则在综合时将会为没有列出的信号隐含的产生一个透明的锁存器,这时综合后的电路已不是纯组合电路了。

用a l w a y s @( p o s e d g e c l o c k ) 或a l w a y s @ ( n e g e d g e c l o c k ) 块描述的电路综合为同步时序逻辑电路,设计同步时序逻辑电路的关键是建立描述该电路状态转移的可综合的有限状态机模型,在V e r i l o g H D L语言中最常用的描述同步时序状态机的结构是a l w a y s 和块内的c a s e . i f 语句,除了紧跟在a l w a y s 后的@( p o s e d g e c l o c k ) , @ ( n e g e d g e c l o c k ) 外,a l w a y s 块中不允许其他的@ ( e v e n t ) 语句,目前大多数综合工具不能综合V e r i l o g H D L描述的异步状态机,所以用V e r i l o g 设计的时序电路应该是同步时序电路。

使用VerilogHDL进行数字逻辑设计、综合、仿真的步骤及工具软件使用简要说明[指南]

使用VerilogHDL进行数字逻辑设计、综合、仿真的步骤及工具软件使用简要说明[指南]

使用V erilog HDL进行数字逻辑设计、综合、仿真的步骤及工具软件使用简要说明综合工具使用synplify pro 7.0仿真工具使用modelsim 5.5e (几个菜单排列与5.6有不同,文中有介绍)布局布线工具及时序仿真模型生成使用maxplusII 10.0一.写在开干之前1.涉及到的文件a.源程序(*.v)用户编写的用于描述所需电路的module (可能有多个文件,多个module相互调用)如果用于综合,则源程序内用于描述的V erilog语言必须是可综合风格的。

否则将只能做功能仿真(前仿真),而不能做综合后的仿真和时序仿真(后仿真)。

b.综合后的V erilog HDL 模型(网表) (*.vm)用综合工具synplify对a 进行综合后生成的电路的V erilog HDL 描述。

由synplify自动生成(必须在Implementation Option —Implementation results选项中选中write mapped verilog netlist后才会生成vm文件)。

此文件用于作综合后的仿真c.布局布线后生成的时序仿真模型(网表) (*.vo)文件使用maxplusII对设计进行布局布线之后,生成的带有布局布线及具体器件延迟特性等参数的电路模型的V erilog HDL描述。

要让maxplusII生成vo文件,必须在maxplusII的compile interface中选中verilog netlist writer。

此文件用于作时序仿真(后仿真)d.测试文件(*.v或*.tf)用户编写的V erilog HDL源程序。

用于测试源程序(a,b,c)中所描述电路。

在测试文件中调用被测试的module,生成被测点路所需的输入信号。

所用V erilog HDL语句不需要是可以综合的,只需语法正确。

如果被测试的模型为a,则对应的仿真为前仿真(功能仿真)如果被测试的模型为b, 则对应的仿真为综合后仿真如果被测试的模型为c, 则对应的仿真为后仿真2.强烈建议a.在写用于综合的源程序时,一个源程序文件里只写一个moduleb.源程序文件名与其内所描述的module名相同(如module myadder 文件名myadder.v)c.为了方便管理文件,为每一个设计都单独创建一个目录,目录内创建source, test子目录分别用于存放源程序(用于综合的)和测试文件。

异步FIFO的verilog代码实现(包含将满和将空逻辑)

异步FIFO的verilog代码实现(包含将满和将空逻辑)

异步FIFO的verilog代码实现(包含将满和将空逻辑)异步FIFO的verilog代码实现(包含将满和将空逻辑)代码参考来源:1. Clifford E. Cummings, "Simulation and Synthesis Techniques for Asynchronous FIFO Design".2.⽬录异步FIFO简介使⽤场景:在有⼤量的数据需要进⾏跨时钟域传输,并且对数据传输速度要求⽐较⾼的场合。

⼀个异步 FIFO ⼀般由如下部分组成:1. Memory, 作为数据的存储器;2.写逻辑部分,主要负责产⽣写信号和地址;3.读逻辑部分,主要负责产⽣读信号和地址;4.地址⽐较部分,主要负责产⽣ FIFO 空、满的标志。

跟普通的FIFO相⽐,异步FIFO实际上多了读写地址的跨时钟域同步的逻辑,以及两个时钟域中读写信号的⽐较逻辑。

异步FIFO关键技术1 -- 读写信号跨时钟域同步⾸先,FIFO的关键是需要判断读空和写满,⽽这两个信号的产⽣依赖读地址和写地址。

在异步FIFO中,读和写是分在两个时钟域中的,在写时钟域,需要得到读地址的信息进⽽判断是否写满(写指针是否追上读指针),同理,在读时钟域,也需要写地址的信息。

我们知道跨时钟域的单⽐特数据⼀般可以⽤双寄存器法进⾏同步,但读写地址通常都是多⽐特的信号,此时如何进⾏同步呢?当然,多⽐特的同步肯定可以通过增加握⼿信号来解决,但实际上对于数值上连续的信号,可以采⽤格雷码进⾏多⽐特到单⽐特的传输。

格雷码再次不做介绍,具体原理可以参考:有了格雷码,就可以将读写地址同步到各⾃的时钟域了。

异步FIFO关键技术2 -- 读写地址的⽐较跟普通fifo⼀样,异步fifo也是通过⽐较读写地址是否相同来判断当前fifo是否空满。

区别在于,异步FIFO因为使⽤了格雷码对地址进⾏编码传输。

⽐如读信号通过格雷码编码后同步到写时钟域,此时需要只需要写信号对应的格雷码和读信号格雷码是否相同(有效位相同)。

system verilog 中进程间通讯的常用机制

system verilog 中进程间通讯的常用机制

system verilog 中进程间通讯的常用机制SystemVerilog是一种硬件描述语言,用于设计和验证复杂的数字系统。

在SystemVerilog中,进程间通信是设计和验证中一个重要的方面。

本文将介绍SystemVerilog中进程间通信的常用机制。

一、FIFO队列FIFO(First In, First Out)队列是SystemVerilog中最常用的进程间通信机制之一。

它可以实现单个或多个生产者与单个或多个消费者之间的数据传输。

FIFO队列由一组寄存器组成,其中包含用于存储和传输数据的缓冲区。

FIFO队列通常具有读指针和写指针,用于指示下一个要读取的数据和下一个要写入的数据的位置。

当生产者向队列中写入数据时,写指针递增,当消费者从队列中读取数据时,读指针递增。

通过读取和写入指针的比较,可以确定队列是否为空或已满。

二、信号量信号量是另一种常见的进程间通信机制。

它用于控制共享资源的访问。

信号量有一个计数器,在资源被占用时递减,在资源释放时递增。

当计数器为零时,其他进程需要等待资源可用。

在SystemVerilog中,可以使用`semaphore`关键字定义信号量。

通过使用`wait()`和`signal()`方法,进程可以申请和释放信号量。

三、事件事件是SystemVerilog中用于进程同步的常见机制之一。

事件表示某个特定条件是否满足。

当事件发生时,其他进程可以通过等待该事件来进行进一步操作。

SystemVerilog中,可以使用`event`关键字定义事件。

通过使用`->`操作符,可以将事件关联到条件或表达式上。

四、互斥锁互斥锁是用于保护共享资源的进程同步机制。

只有一个进程可以获得互斥锁,并访问被保护的资源。

其他进程需要等待互斥锁被释放后才能访问资源。

在SystemVerilog中,可以使用`lock()`和`trylock()`方法获取互斥锁,并使用`unlock()`方法释放互斥锁。

Verilog中同步复位和异步复位比较

Verilog中同步复位和异步复位比较

【Verilog】同步复位和异步复位比较async vs. sync相关讨论:1、同步电路和异步电路的区别是什么?异步电路主要是组合逻辑电路,用于产生地址译码器、FIFO或RAM的读写控制信号脉冲,但它同时也用在时序电路中,此时它没有统一的时钟,状态变化的时刻是不稳定的,通常输入信号只在电路处于稳定状态时才发生变化。

也就是说一个时刻允许一个输入发生变化,以避免输入信号之间造成的竞争冒险。

电路的稳定需要有可靠的建立时间和保持时间,待下面介绍。

同步电路是由时序电路(寄存器和各种触发器)和组合逻辑电路构成的电路,其所有操作都是在严格的时钟控制下完成的。

这些时序电路共享同一个时钟CLK,而所有的状态变化都是在时钟的上升沿(或下降沿)完成的。

比如D触发器,当上升延到来时,寄存器把D端的电平传到Q输出端。

在同步电路设计中一般采用D触发器,异步电路设计中一般采用Latch。

2、什么是同步逻辑和异步逻辑?同步逻辑是时钟之间有固定的因果关系。

异步逻辑是各时钟之间没有固定的因果关系。

电路设计可分类为同步电路和异步电路设计。

同步电路利用时钟脉冲使其子系统同步运作,而异步电路不使用时钟脉冲做同步,其子系统是使用特殊的“开始”和“完成”信号使之同步。

由于异步电路具有下列优点--无时钟歪斜问题、低电源消耗、平均效能而非最差效能、模块性、可组合和可复用性--因此近年来对异步电路研究增加快速,论文发表数以倍增,而Intel Pentium 4处理器设计,也开始采用异步电路设计。

异步电路主要是组合逻辑电路,用于产生地址译码器、FIFO或RAM的读写控制信号脉冲,其逻辑输出与任何时钟信号都没有关系,译码输出产生的毛刺通常是可以监控的。

同步电路是由时序电路(寄存器和各种触发器)和组合逻辑电路构成的电路,其所有操作都是在严格的时钟控制下完成的。

这些时序电路共享同一个时钟CLK,而所有的状态变化都是在时钟的上升沿(或下降沿)完成的。

3、什么是"线与"逻辑,要实现它,在硬件特性上有什么具体要求?线与逻辑是两个输出信号相连可以实现与的功能。

verilog中可综合和不可综合语句概述

verilog中可综合和不可综合语句概述

Verilog中可综合及不可综合语句概述Verilog硬件描述语言有很完整的语法结构和系统,类似高级语言,这些语法结构的应用给我们的设计描述带来很多方便。

但是,我们知道,Verilog是描述硬件电路的,它是建立在硬件电路的基础上的。

有些语法结构是不能与实际硬件电路对应起来的,也就是说我们在把一个语言描述的程序映射成实际硬件电路中的结构时是不能实现的。

下面就是我多年工作经验总结出来的大部分综合工具支持或不支持的verilog语法结构。

一.用verilog建立可综合模型的原则要保证Verilog HDL赋值语句的可综合性,在建模时应注意以下要点:(1)不使用initial。

(2)不使用#10。

(3)不使用循环次数不确定的循环语句,如forever、while等。

(4)不使用用户自定义原语(UDP元件)。

(5)尽量使用同步方式设计电路。

(6)除非是关键路径的设计,一般不采用调用门级元件来描述设计的方法,建议采用行为语句来完成设计。

(7)用always过程块描述组合逻辑,应在敏感信号列表中列出所有的输入信号。

(8)所有的内部寄存器都应该能够被复位,在使用FPGA实现设计时,应尽量使用器件的全局复位端作为系统总的复位。

(9)对时序逻辑描述和建模,应尽量使用非阻塞赋值方式。

对组合逻辑描述和建模,既可以用阻塞赋值,也可以用非阻塞赋值。

但在同一个过程块中,最好不要同时用阻塞赋值和非阻塞赋值。

(10)不能在一个以上的always过程块中对同一个变量赋值。

而对同一个赋值对象不能既使用阻塞式赋值,又使用非阻塞式赋值。

(11)如果不打算把变量推导成锁存器,那么必须在if语句或case语句的所有条件分支中都对变量明确地赋值。

(12)避免混合使用上升沿和下降沿触发的触发器。

(13)同一个变量的赋值不能受多个时钟控制,也不能受两种不同的时钟条件(或者不同的时钟沿)控制。

(14)避免在case语句的分支项中使用x值或z值。

二.不可综合verilog语句1、initial只能在testbench中使用,不能综合。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

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 软件流程图 (3)2.3 HDL代码阐述 (7)2.4 ModelSim验证 (13)第3章课程设计的心得 (21)第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的了解。

在前两天的工作当中,我们查阅了中外各类资料和文献,对FIFO的组成和工作原理有了深入的了解,最终决定以老师给的两篇《Simulation and Synthesis T echniques for Asynchronous FIFO Design》和《Simulation and Synthesis Techniques for Asynchronous FIFO Design with Asynchronous Pointer Comparisons》为学习和参考的重要资料完成本次的课程设计。

在两天的研究中,我们敲定异步FIFO的整体设计原理图如下:在懂得设计模块之后,我们接下来就要逐步编写每个子模块的程序。

并且在写完每个子模块的设计之后,我们为了验证的方便起见,要求验证FIFO在每个时钟沿自动完成数据从0到15的自增一,观察当数据写满深度为15的FIFO之后能否自动产生”写满“信号并且自动开始”读模式“,在读的状态,关键步骤就是验证是否在读空之后不再继续读。

当然,这也是FIFO设计的关键,如何在写满的时候不让外界继续对FIFO继续写入,在读空的时候如何让FIFO不再继续读,在这方面的程序设计中我们走了很多的弯路,最终在两篇重要的论文中找到了解决问题的方式,在写自己代码的时候我们也参考了文章中的代码,感到受益匪浅!2.2 软件流程图一:同步FIFO设计流程图:二:异步FIFO设计流程图1) FIFOMEMORY部分2)sync_r2w 部分3) sync_w2r部分4)wptr_full部分5)rptr_empty部分6) 主模块afifo部分因为这一部分就是将前几部分联系成一个整体,因此无需再画这部分流程图。

2.3 HDL代码阐述1)同步FIFO设计代码:`define DEL 1module synfifo(clock,reset_n,data_in,read_n,write_n,data_out,full,empty);input clock,reset_n,read_n,write_n;input [0:7] data_in;output [0:7] data_out;output full,empty;wire clock,reset_n,read_n,write_n;wire [0:7] data_in;reg [0:7] data_out;wire full,empty;//?reg[7:0] fifo_mem[14:0];reg [3:0] counter;reg[3:0] rd_pointer;reg[3:0] wr_pointer;assign #`DEL full=(counter==15)?1'b1:1'b0;//当计数值为15时代表已经满了assign #`DEL empty=(counter==0)?1'b1:1'b0;//当计数值为0的时候代表空了always @(posedge clock or negedge reset_n)beginif(~reset_n)//复位状态begin#`DEL;rd_pointer<=4'b0;wr_pointer<=4'b0;counter<=4'b0;data_out<=8'b0;endelse if(~read_n)//读信号有效beginif(counter==0)begin$display("\nERROR at time %0t:",$time);$display("\FIFO Underflow\n");$stop;endif(write_n)//只读不写begincounter<=counter-1;enddata_out<=#`DEL fifo_mem[rd_pointer];//数据读出if(rd_pointer==14)rd_pointer<= #`DEL 4'b0;elserd_pointer<=rd_pointer+1;endelse if(~write_n)//写状态有效beginif(counter==15)begin$display("\nERROR at time %0t:",$time);$display("FIFO Overflow\n");$stop;endif(read_n)//只写不读begincounter<=#`DEL counter+1;endfifo_mem[wr_pointer]<=#`DEL data_in;//数据写入if(wr_pointer==14)wr_pointer<=#`DEL 4'b0;elsewr_pointer<=#`DEL wr_pointer+1;endendendmodule2)异步FIFO设计:1、 FIFOmemory部分:module fifomem(rdata,wdata,waddr,raddr,wclken,wfull,wclk,rrst_n,rinc,rempty,rclk);input[7:0]wdata;input[3:0]waddr,raddr;input wclken,wfull,wclk,rrst_n,rinc,rempty,rclk;output[7:0]rdata;reg[7:0]rdata;reg[7:0]mem[0:15];always@(posedge rclk or negedge rrst_n)if(!rrst_n)rdata<=8'b0;else if(rinc&&!rempty)//读有效并且没空rdata<=mem[raddr];//数据读出always@(posedge wclk)if(wclken&&!wfull)//写有效并且没满mem[waddr]<=wdata;endmodule3) sync_r2w部分:module sync_r2w(wq2_rptr,rptr,wq1_rptr,wclk,wrst_n);input[4:0]rptr;input wclk,wrst_n;output [4:0] wq1_rptr,wq2_rptr;reg [4:0] wq1_rptr,wq2_rptr;always@(posedge wclk or negedge wrst_n)//这部分进行写地址到到读地址的同步if(!wrst_n){wq2_rptr,wq1_rptr}<=0;else{wq2_rptr,wq1_rptr}<={wq1_rptr,rptr};endmodule4) sync_w2r部分:module sync_w2r(rq2_wptr,wptr,rq1_wptr,rclk,rrst_n);input[4:0]wptr;input rclk,rrst_n;output [4:0] rq1_wptr,rq2_wptr;reg [4:0] rq1_wptr,rq2_wptr;always@(posedge rclk or negedge rrst_n)//读地址到写地址的同步if(!rrst_n){rq2_wptr,rq1_wptr}<=0;else{rq2_wptr,rq1_wptr}<={rq1_wptr,wptr};Endmodule5) wptr_full部分:module wptr_full(wfull,waddr,wbin,wptr,wq2_rptr,winc,wclk,wrst_n);input wrst_n,wclk,winc;input [4:0]wq2_rptr;output [3:0]waddr;output [4:0]wptr;output wfull;output[4:0]wbin;reg wfull;reg [4:0]wptr;reg[4:0]wbin;wire[4:0]wgraynext,wbinnext;always@(posedge wclk or negedge wrst_n)//转化成格雷码进行比较if(!wrst_n)beginwbin<=5'b0;wptr<=5'b0;endelsebeginwbin<=wbinnext;wptr<=wgraynext;endassign waddr=wbin[3:0];assign wbinnext=wbin+(winc&!wfull);assign wgraynext=(wbinnext>>1)^wbinnext;assign wfull_val = (wgraynext =={!wq2_rptr[4:3],wq2_rptr[2:0]});//如果高两位不同,低3位相同那么写满标志有效always @(posedge wclk or negedge wrst_n)if (!wrst_n)wfull <= 1'b0;elsewfull <= wfull_val;endmodule6) rptr_empty部分:module rptr_empty(rempty,raddr,rbin,rptr,rq2_wptr,rinc,rclk,rrst_n);input rrst_n,rclk,rinc;input [4:0]rq2_wptr;output [3:0]raddr;output [4:0]rptr;output rempty;output[4:0]rbin;reg rempty;reg [4:0]rptr;reg[4:0]rbin;wire[4:0]rgraynext,rbinnext;always@(posedge rclk or negedge rrst_n)if(!rrst_n)beginrbin<=5'b0;rptr<=5'b0;endelsebeginrbin<=rbinnext;rptr<=rgraynext;endassign raddr=rbin[3:0];assign rbinnext=rbin+(rinc&!rempty);assign rgraynext=(rbinnext>>1)^rbinnext;assign rempty_val = (rgraynext == rq2_wptr)?1'b1:1'b0;//均相同时则为空有效always @(posedge rclk or negedge rrst_n)if (!rrst_n)rempty <= 1'b1;elserempty <= rempty_val;endmodule7) afifo部分:module afifo(output [7:0] rdata,output wfull,output rempty,input [7:0] wdata,input winc, wclk, wrst_n,input rinc, rclk, rrst_n);wire [3:0] waddr, raddr;wire [4:0] wptr, rptr, wq2_rptr, rq2_wptr;//每个模块的每个信号都需要例化sync_r2w sync_r2w(.wq2_rptr(wq2_rptr), .rptr(rptr),.wclk(wclk), .wrst_n(wrst_n));sync_w2r sync_w2r(.rq2_wptr(rq2_wptr), .wptr(wptr),.rclk(rclk), .rrst_n(rrst_n));fifomem fifomem(.rdata(rdata), .wdata(wdata),.waddr(waddr), .raddr(raddr),.wclken(winc), .wfull(wfull),.wclk(wclk),.rrst_n(rrst_n),.rinc(rinc),.rempty(rempty),.rclk(rclk));rptr_empty rptr_empty(.rempty(rempty),.raddr(raddr),.rbin(rbin),.rptr(rptr), .rq2_wptr(rq2_wptr),.rinc(rinc), .rclk(rclk),.rrst_n(rrst_n));wptr_full wptr_full(.wfull(wfull), .waddr(waddr),.wbin(wbin),.wptr(wptr), .wq2_rptr(wq2_rptr),.winc(winc), .wclk(wclk),.wrst_n(wrst_n));endmodule2.4 ModelSim验证一、同步FIFO1、HDL验证语言:`define DEL 10module syn_tb;reg clock,reset_n,read_n,write_n;reg [7:0] in_data;wire [7:0] out_data;wire full,empty;integer fifo_count;reg [7:0] exp_data;reg fast_read,fast_write;reg filled_flag;reg cycle_count;synfifosynfifo_tb(.clock(clock),.reset_n(reset_n),.data_in(in_data),.read_n(read_n),.write_n(write_n),.data_out(out_data),.full(full),.empty(empty));initialbeginin_data=0;exp_data=0;fifo_count=0;read_n=1;write_n=1;filled_flag=0;cycle_count=0;clock=1;fast_read=0;fast_write=1;reset_n=1;#20 reset_n=0;#20 reset_n=1;if(empty!==1)begin$display("\nerror at time %0t:",$time);$display("after reset,empty status not asserted\n");$stop;endif(full!==0)begin$display("\nerror at time %0t:",$time);$display("\nerror at time %0t:",$time);$stop;endendalways #100 clock=~clock;always @(posedge clock)beginif(~write_n && read_n)fifo_count=fifo_count+1;else if(write_n && ~read_n)fifo_count=fifo_count-1;endalways @(negedge clock)beginif(~read_n && (out_data!==exp_data))begin$display("\nerror at time %0t:",$time);$display("expected data ut=%h",exp_data);$display("actual data ut=%h\n",out_data);$stop;endif((fast_write&&(cycle_count&1'b1))&&~full)//?beginwrite_n=0;in_data=in_data+1;endelsewrite_n=1;if((fast_read&&(cycle_count&1'b1))&&~empty)//?beginread_n=0;exp_data=exp_data+1;endelseread_n=1;if(full)beginfast_read=1;fast_write=0;filled_flag=1;endif(filled_flag&&empty)begin$display("\nsimulation complete -no errors\n");$finish;endcycle_count=cycle_count+1;endalways@(fifo_count)begin# `DEL;# `DEL;# `DEL;case (fifo_count)0:beginif((empty!==1)||(full!==0))begin$display("\nerror at time %0t:",$time);$display("fifo_count=%h",fifo_count);$display("empty=%h\n",empty);$display("full=%h\n",full);$stop;endif(filled_flag==1)begin$display("\nsimulation complete -no error\n");$finish;endend15:beginif((empty!==0)||(full!==1))begin$display("\nerror at time %0t:",$time);$display("fifo_count=%h",fifo_count);$display("empty=%h\n",empty);$display("full=%h\n",full);$stop;endfilled_flag=1;fast_write=0;fast_read=1;enddefault:beginif((empty!==0)||(full!==0))begin$display("\nerror at time %0t:",$time);$display("fifo_count=%h",fifo_count);$display("empty=%h\n",empty);$display("full=%h\n",full);$stop;endendendcaseendinitial begin$fsdbdumpfile("sfifo.fsdb");$fsdbdumpvars();endendmodule2、仿真波形:3、说明当写FIFO的时候,一个上升的时钟沿一来,并且写信号有效,读信号无效时,数据逐个写入FIFO存储器中。

相关文档
最新文档