文档视界 最新最全的文档下载
当前位置:文档视界 › 同步FIFO之VHDL描述

同步FIFO之VHDL描述

同步FIFO之VHDL描述
同步FIFO之VHDL描述

同步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 is

generic(width : positive

depth : 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_pointer

FIFO is empty;

Else

FIFO is not empty;

End if;

2. Full状态判断:

If writer_pointer > read_pointer

If write_pointer – read_pointer = depth

FIFO is full;

Else

FIFO is not full;

End if;

Else

If write_pointer – read_pointer = 1

FIFO is full;

Else

FIFO 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 skycanny

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

elsif clk'event and clk = '1' then if wq = '0' and full = '0' then

wr_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 created

library ieee;

use

use

use read_pointer is

generic

( 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 is

signalrd_pt_t:std_logic_vector(depth - 1 downto 0); -- read pointer counter

begin

process(rst, clk)

begin

if rst = '0' then

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

elsif clk'event and clk = '1' then

if rq = '0' and empty = '0' then

rd_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 created

library ieee;

use judge_status is

generic

(

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 is

begin

process(rst, clk)

begin

if rst = '0 then

empty <= '1';

elsif clk'event and clk = '1' then

if wr_pt = rd_pt then

empty <= '1';

else

empty <= '0';

end if;

end if;

end process;

process(rst, clk)

begin

if rst = '0' then

full <= '0';

elsif clk 'event and clk = '1' then if wr_pt > rd_pt then

if (rd_pt + depth) = wr_pt then

full <= '1';

else

full <= '0';

end if;

else

if (wr_pt + 1 ) = rd_pt then

full <= '1';

else

full <= '0';

end if;

end if;

end if;

end process;

end RTL;

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

广告时间欢迎访问。现在就开始双口RAM的VHDL描述吧,这个可是很重要的。下面的代码在Altera的CycloneII系列的器件上通过了后仿真。

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

-- Designer : skycanny

-- Date : 2007-2-3

-- Description : This VHDL file is designed to generate a dual po rt ram

-- Device : Cyclone II

library ieee;

use dualram is

generic

(

width : positive := 16;

depth : positive := 8

);

port

(

------------------------- port a is only for writing -------------------------------

clka : in std_logic;

wr : in std_logic;

addra : in std_logic_vector(depth - 1 downto 0);

datain : in std_logic_vector(width - 1 downto 0);

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

------------------------- port b is only for reading -------------------------------

clkb : in std_logic;

rd : in std_logic;

addrb : in std_logic_vector(depth - 1 downto 0);

dataout : out std_logic_vector(width - 1 downto 0)

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

);

end entity dualram;

architecture Behavioral of dualram is

type ram is array(2 ** depth - 1 downto 0) of std_logic_vector(width - 1 downto 0);

signal dualram : ram;

begin

process(clka, clkb)

begin

if clka'event and clka = '1' then

if wr = '0' then

dualram(conv_integer(addra)) <= datain;

end if;

end if;

end process;

process(clkb)

begin

if clkb'event and clkb = '1' then

if rd = '0' then

dataout <= dualram(conv_integer(addrb));

end if;

end if;

end process;

end Behavioral;

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

抓个后仿真的图形吧,需要testbench的投票留言。另外今天还发现前仿真的时候可以用generic传递参数,而后仿真的时候就不能用generic传递参数了,M odelsim会报错“No default binding for component at”。后来想了一下确实应该是这样的,因为后仿真的时候电路都已经布局布线完成了,还有什么参数需要generic传递呀

昨天晚上把所有的模块描述都完成了,同时还完成了双端口RAM的后仿真,从目前的仿真结果来看,应该没有什么问题。今天的任务就是把这些模块组装起来并完成前后仿真,这样同步FIFO的VHDL描述就算全部完成了。按照前面的思路和框图,把这些模块组装起来应该很简单,下面就直接给出VHDL代码。当然组装的过程还要排查除了双口RAM以外电路的代码描述有没有问题,如果有问题的话就就地改正了,呵呵。

在代码的集成和仿真的时候还真发现了一些问题,主要包括数据的寄存,以及空满状态判断上,最后的代码使用Quartus 综合和布局布线,选用的是CycloneI I系列的器件,并用Modelsim进行了功能仿真和时序仿真,两种仿真均通过。下面主要是集成的定层文件和时序仿真图(图1,图2,图3,图4,图5)。

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

-- Designer : skycanny

-- Date : 2007-2-4

-- Description : Synchronous FIFO created by VHDL

library ieee;

use sfifo is

generic

(

width : positive := 16;

depth : positive := 8

);

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 : out std_logic_vector(width - 1 downto 0);

empty : out std_logic;

full : out std_logic

);

end entity sfifo;

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

architecture structure of sfifo is

signal empty_t : std_logic;

signal full_t : std_logic;

signal wr_pt : std_logic_vector(depth - 1 downto 0);

signal rd_pt : std_logic_vector(depth - 1 downto 0);

signal wr : std_logic;

signal rd : std_logic;

component write_pointer

generic

(

depth : positive :=8

);

port

(

clk : in std_logic;

rst : in std_logic;

wq : in std_logic;

full : in std_logic;

wr : out std_logic;

wr_pt : out std_logic_vector(depth - 1 downto 0) );

end component;

component read_pointer

generic

(

depth : positive :=8

);

port

(

clk : in std_logic;

rst : in std_logic;

rq : in std_logic;

empty : in std_logic;

rd : out std_logic;

rd_pt : out std_logic_vector(depth - 1 downto 0) );

end component;

component judge_status

generic

(

depth : positive :=8

);

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 component;

component dualram

generic

(

width : positive := 16;

depth : positive := 8

);

port

(

------------------------- port a is only for writing -------------------------------

clka : in std_logic;

wr : in std_logic;

addra : in std_logic_vector(depth - 1 downto 0);

datain : in std_logic_vector(width - 1 downto 0);

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

------------------------- port b is only for reading -------------------------------

clkb : in std_logic;

rd : in std_logic;

addrb : in std_logic_vector(depth - 1 downto 0);

dataout : out std_logic_vector(width - 1 downto 0)

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

);

end component;

begin

empty <= empty_t;

相关文档