同步FIFO之VHDL描述.docx

上传人:b****9 文档编号:25455685 上传时间:2023-06-08 格式:DOCX 页数:22 大小:76.98KB
下载 相关 举报
同步FIFO之VHDL描述.docx_第1页
第1页 / 共22页
同步FIFO之VHDL描述.docx_第2页
第2页 / 共22页
同步FIFO之VHDL描述.docx_第3页
第3页 / 共22页
同步FIFO之VHDL描述.docx_第4页
第4页 / 共22页
同步FIFO之VHDL描述.docx_第5页
第5页 / 共22页
点击查看更多>>
下载资源
资源描述

同步FIFO之VHDL描述.docx

《同步FIFO之VHDL描述.docx》由会员分享,可在线阅读,更多相关《同步FIFO之VHDL描述.docx(22页珍藏版)》请在冰豆网上搜索。

同步FIFO之VHDL描述.docx

同步FIFO之VHDL描述

同步FIFO之VHDL描述

(1)

作者:

skycanny  时间:

2007-09-2816:

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:

SynchronousFIFOcreatedbyVHDL

libraryieee;

useieee.std_logic_1164.all;

useieee.std_logic_unsigned.all;

useieee.std_logic_arith.all;

entitysfifois

generic(width:

positive

depth:

positive

);

port

clk:

instd_logic;

rst:

instd_logic;

wq:

instd_logic;

rq:

instd_logic;

data       :

instd_logic_vector(width-1downto0);

q:

instd_logic_vector(width-1downto0);

empty:

outstd_logic;

full:

outstd_logic

);

endentitysfifo;

-----------------------------------------------------------------------------------------------------------

 

同步FIFO内部通过控制电路和RAM实现,控制电路主要包括写指针管理电路,读指针管理电路,以及FIFO状态判断电路,对于同步FIFO来讲,读和写的指针管理电路实际上就是二进制计数器。

现在的FPGA都具有BlockRAM,通过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。

由于读写电路在循环的读写RAM,所以在上面的两种情况下FIFO实际上都已经满了。

那么如何对读写指针的判断比较容易的得出FIFO已经满了,同时这样的判断电路还要容易参数化?

第一种情况下,write_pointer–read_pointer=7,实际上就是FIFO深度减一,第二种情况下,(write_pointer+8)–read_pointer=7,也是FIFO深度减一。

从上面的讨论就可以很容易进行判断FIFO状态了,假设FIFO的深度用depth表示,则FIFO状态判断用伪码表示如下:

1. Empty状态判断:

Ifwriter_pointer=read_pointer

FIFOisempty;

Else

FIFOisnotempty;

Endif;

2.Full状态判断:

Ifwriter_pointer>read_pointer

Ifwrite_pointer–read_pointer=depth

FIFOisfull;

Else

FIFOisnotfull;

Endif;

Else

Ifwrite_pointer–read_pointer=1

FIFOisfull;

Else

FIFOisnotfull;

Endif;

Endif;

下面的框图主要描述同步FIFO的内部结构,画出框图有助于对电路结构的理解,同样也有助于RTL代码的编写

        

    

       今天就先写到这里吧,大家有什么问题和意见可以提出来,以便我及早的发现问题,不要等到要写代码的的时候才发现就麻烦了。

 

今天又重新安装了UltraEdit,QuartusII6.0和ModelsimSE6.0,这次安装以后系统没有发现什么异常。

另外还安装了紫光的拼音输入法,用习惯了这个,微软呀,智能ABC这些都用不太习惯。

最后把系统备份了一下,以免将来出了什么问题还可以还原一下,呵呵。

还是接着昨天的《同步FIFO之VHDL描述》。

突然发现用于实现FIFO的RAM必须是真正意义上的双口RAM,也就是读写可以同时进行的,以前只是用VHDL描述过单端口的RAM,双口RAM还没有描述过,不过曾经看到过XilinxFPGA/CPLD的开发工具ISE的CoreGenertor好像提供双口RAM的软核,所以我想用HDL语言也就应该可以描述从而调用双口RAM,这个等到具体写双口RAM的RTL代码的时候再研究。

还有一个问题就是FIFO的读写请求控制信号必须要控制FIFO读写指针的产生电路,只有读写信号信号有效的时候,FIFO读写指针才能是有效的,负责是无效而且要保持不变,这个容易理解。

今天,就先完成写指针产生和管理电路的RTL代码吧,其实很简单,就是一个二进制计数器。

下面就是VHDL的代码,大家看看有没有什么问题。

-----------------------------------------------------------------------------------------------------------

--Designer:

skycanny

--Date:

2007-2-2

--Description:

write_pointeriscreated

--Modification:

addFIFOstatusfulljudge2007-2-3skycanny

libraryieee;

useieee.std_logic_1164.all;

useieee.std_logic_unsigned.all;

useieee.std_logic_arith.all;

entitywrite_pointeris

generic

不明白写/读指针为什么是“depth-1downto0”位的矢量,depth不是FIFO的深度吗?

难道深度16的FIFO的写/读指针为std_logic_vector(15downto0)类型吗?

depth:

positive

);

port

clk:

instd_logic;

rst:

instd_logic;

wq:

instd_logic;

full:

instd_logic;

wr_pt:

outstd_logic_vector(depth-1downto0)

);

endentity;

architectureRTLofwrite_pointeris

signalwr_pt_t:

std_logic_vector(depth-1downto0);--writerpointercounter

begin

process(rst,clk)

begin

ifrst='0'then

wr_pt_t<=(others=>'0');

elsifclk'eventandclk='1'then

ifwq='0'andfull='0'then

wr_pt_t<=wr_pt_t+1;

endif;

endprocess;

wr_pt<=wr_pt_t;

endRTL;

同步FIFO之VHDL描述

(2)

作者:

skycanny  时间:

2007-09-2816:

09:

38  来自:

skycanny的笔记  浏览次数:

1602  文字大小:

【大】【中】【小】

今天准备完成同步FIFO其他模块的代码,主要包括读指针管理和产生电路,FIFO状态判断电路,以及双端口RAM的VHDL描述。

先是读指针管理和产生电路:

-----------------------------------------------------------------------------------------------------------

--Designer  :

 skycanny

--Date   :

 2007-2-3

--Description :

 read_pointeriscreated

libraryieee;

useieee.std_logic_1164.all;

useieee.std_logic_unsigned.all;

useieee.std_logic_arith.all;

entityread_pointeris

 generic

 (depth :

 positive 

 );

 port

 (clk  :

 in std_logic;

  rst  :

 in std_logic;

  rq  :

 in std_logic;

  empty :

 in std_logic;

  rd_pt :

 out std_logic_vector(depth-1downto0)  

 );

endentityread_pointer;

architectureRTLofread_pointeris

signal rd_pt_t :

 std_logic_vector(depth-1downto0); --readpointercounter

begin

 process(rst,clk)

 begin

  ifrst='0'then

   rd_pt_t<=(others=>'0');

  elsifclk'eventandclk='1'then

   ifrq='0'andempty='0'then

    rd_pt_t<=rd_pt_t+1;

   endif;

 endprocess;

 rd_pt<=rd_pt_t;

endRTL;

------------------------------------------------------------------------------------------------------------

 

 

刚才想了一下,读写指针产生电路必须要对FIFO的状态进行判断,所以又对上面的代码进行了一点修改(上面的代码是修改过的),判断FIFO的状态,这一点在刚开始的时候给疏忽了,幸好刚才给发现了。

同样昨天写的写指针产生电路没有判断FIFO的full状态,也要进行修改,还是在昨天的基础上修改吧,就不在这里罗嗦了,下面就是FIFO状态判断电路的VHDL描述。

-----------------------------------------------------------------------------------------------------------

--Designer:

skycanny

--Date:

2007-2-3

--Description:

read_pointeriscreated

 

libraryieee;

useieee.std_logic_1164.all;

useieee.std_logic_unsigned.all;

useieee.std_logic_arith.all;

 

entityjudge_statusis

generic

depth:

positive

);

port

clk:

instd_logic;

rst:

instd_logic;

wr_pt:

instd_logic_vector(depth-1downto0);

rd_pt:

instd_logic_vector(depth-1downto0);

empty:

outstd_logic;

full:

outstd_logic

);

endentityjudge_status;

 

architectureRTLofjudge_statusis

 begin

 

process(rst,clk)

begin

ifrst='0then

empty<='1';

elsifclk'eventandclk='1'then

ifwr_pt=rd_ptthen

empty<='1';

else

empty<='0';

endif;

endif;

endprocess;

process(rst,clk)

begin

ifrst='0'then

full<='0';

elsifclk'eventandclk='1'then

ifwr_pt>rd_ptthen

if(rd_pt+depth)=wr_ptthen

full<='1';

else

full<='0';

endif;

else

if(wr_pt+1)=rd_ptthen

full<='1';

else

full<='0';

endif;

endif;

endif;

endprocess;

 

endRTL;

-----------------------------------------------------------------------------------------------------------

 

广告时间欢迎访问skycanny的笔记(副站)。

现在就开始双口RAM的VHDL描述吧,这个可是很重要的。

下面的代码在Altera的CycloneII系列的器件上通过了后仿真。

-----------------------------------------------------------------------------------------------------------

--Designer:

skycanny

--Date:

2007-2-3

--Description:

ThisVHDLfileisdesignedtogenerateadualportram

--Device:

CycloneII

 

libraryieee;

useieee.std_logic_1164.all;

useieee.std_logic_unsigned.all;

useieee.std_logic_arith.all;

 

entitydualramis

generic

width:

positive:

=16;

depth:

positive:

=8

);

port

-------------------------portaisonlyforwriting-------------------------------

clka:

instd_logic;

wr:

instd_logic;

addra:

instd_logic_vector(depth-1downto0);

datain:

instd_logic_vector(width-1downto0);

------------------------------------------------------------------------------------

-------------------------portbisonlyforreading-------------------------------

clkb:

instd_logic;

rd:

instd_logic;

addrb:

instd_logic_vector(depth-1downto0);

dataout:

outstd_logic_vector(width-1downto0)

------------------------------------------------------------------------------------

);

endentitydualram;

 

architectureBehavioralofdualramis

 

typeramisarray(2**depth-1downto0)ofstd_logic_vector(width-1downto0);

signaldualram:

ram;

 

begin

 

process(clka,clkb)

begin

ifclka'eventandclka='1'then

ifwr='0'then

dualram(conv_integer(addra))<=datain;

endif;

endif;

endprocess;

process(clkb)

begin

ifclkb'eventandclkb='1'then

ifrd='0'then

dataout<=dualram(conv_integer(addrb));

endif;

endif;

endprocess;

 

endBehavioral;

-----------------------------------------------------------------------------------------------------------

抓个后仿真的图形吧,需要testbench的投票留言。

另外今天还发现前仿真的时候可以用generic传递参数,而后仿真的时候就不能用generic传递参数了,Modelsim会报错“Nodefaultbindingforcomponentat”。

后来想了一下确实应该是这样的,因为后仿真的时候电路都已经布局布线完成了,还有什么参数需要generic传递呀?

昨天晚上把所有的模块描述都完成了,同时还完成了双端口RAM的后仿真,从目前的仿真结果来看,应该没有什么问题。

今天的任务就是把这些模块组装起来并完成前后仿真,这样同步FIFO的VHDL描述就算全部完成了。

按照前面的思路和框图,把这些模块组装起来应该很简单,下面就直接给出VHDL代码。

当然组装的过程还要排查除了双口RAM以外电路的代码描述有没有问题,如果有问题的话就就地改正了,呵呵。

在代码的集成和仿真的时候还真发现了一些问题,主要包括数据的寄存,以及空满状态判断上,最后的代码使用QuartusII6.0综合和布局布线,选用的是CycloneII系列的器件,并用Modelsim进行了功能仿真和时序仿真,两种仿真均通过。

下面主要是集成的定层文件和时序仿真图(图1,图2,图3,图4,图5)。

 

---------------------------------------------------------------------------------------------------------

--Designer:

skycanny

--Date:

2007-2-4

--Description:

SynchronousFIFOcreatedbyVHDL

libraryieee;

useieee.std_logic_1164.all;

useieee.std_logic_unsigned.all;

useieee.std_logic_arith.all;

 

entitysfifois

generic

width:

positive:

=16;

depth:

positive:

=8

);

port

clk:

instd_logic;

rst:

instd

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 工作范文 > 其它

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1