原创 一个intel员工写的 VHDL的FIFO程序

2009-7-6 12:20 3782 5 8 分类: EDA/ IP/ 设计与制造
懂FPGA VHDL 或者Verilog的 仔细体会一下的他的数据有效位和数据的同步,收发数据,有效位与时钟的关系, 有效位的触发。。。。。。。

非常严谨的程序,仔细品味。。。。。
给你一个片子 ,来两个这样的对称FIFO就可以检测 硬件系统平台的搭建是否成功。。。。

程序如下:
--====================================================================
--
--                                Project        :         PTD200_9572XL_4fifo
--                Title         :         FIFO MODULE for PTD200-5x Fifo
--                Device        :         XC9572XL-10C-TQ100
--
--                Produced :         Mingquanwentao
--                Date            :         2003.04.14
--                Rev.            :         1.0
--                Compiler        :         Xilinx ISE 4.1i
--                                Nodes                :         FIFO Depth  ====> 4
--                                                                FIFO Width  ====> 5
--
--====================================================================

LIBRARY ieee;
USE ieee.std_logic_1164.all;

ENTITY fifo IS
        PORT(
                --INPUT
                reset                 :                 IN STD_LOGIC                                                                ;        --Global reset signal
                txclk                        :                IN STD_LOGIC                                                                ;        --Transmission clock
                rxclk                        :                IN STD_LOGIC                                                                ;         --Receive clock
                rxer                        :                IN STD_LOGIC                                                                ;         --Receive error
                rxdv                        :                IN STD_LOGIC                                                                ;         --Receive data valid
                rxd                        :                IN STD_LOGIC_VECTOR(3 downto 0)                ;        --Receive data
      --OUTPUT
                txd                        :                OUT STD_LOGIC_VECTOR(3 downto 0)                ;        --Transmission data
                txen                        :                 OUT STD_LOGIC                                                ;        --Transmission data enable
                txer                        :                OUT STD_LOGIC                                                                        --Transmission error
        );
END fifo;


ARCHITECTURE behavior OF fifo IS
        SIGNAL in_sel                :        STD_LOGIC_VECTOR(1 downto 0)                        ;        --Write buffer pointer        
        SIGNAL out_sel                :        STD_LOGIC_VECTOR(1 downto 0)        ;           --Read buffer pointer                       
        SIGNAL dff_0                :        STD_LOGIC_VECTOR(4 downto 0)                    ;        --Buffer        0                       
        SIGNAL dff_1                :        STD_LOGIC_VECTOR(4 downto 0)                     ;        --Buffer        1                       
        SIGNAL dff_2                :        STD_LOGIC_VECTOR(4 downto 0)                      ;        --Buffer        2                       
        SIGNAL dff_3                :        STD_LOGIC_VECTOR(4 downto 0)                      ;        --Buffer        3                       
        SIGNAL reset_rx        :        STD_LOGIC          ;        --Data Input Enable                       
        SIGNAL reset_tx        :        STD_LOGIC             ;        --Data Output Enable                       
BEGIN


--////////////////////////////////////
--
--                        Input data to the fifo
--
--////////////////////////////////////

inputs:
PROCESS(rxclk, reset_rx)
BEGIN
        if( reset = '0')then                                                                --Global reset ;
                 in_sel        <= "00";
                 dff_0         <= "00000"        ;
                 dff_1         <= "00000"        ;
                 dff_2         <= "00000"        ;
                 dff_3         <= "00000"        ;
        elsif(rxclk'EVENT AND rxclk = '1')THEN                --Synchronize the rising edge of the rxclk ;
                IF(reset_rx = '0' ) THEN                                   --No data need to write ;
                        if(reset_tx = '0')then                                        --No data in fifo                 ;
                                in_sel <= "00";                                               --Reset the write-pointer;
                                 dff_0 <= "00000";                                          --Set the buffer to zero ;
                                 dff_1 <= "00000";
                                 dff_2 <= "00000";
                                 dff_3 <= "00000";               
                        ELSE                                                                   --Valid data still in the fifo;
                                IF(in_sel = "00")THEN                
                                        dff_0 <= "00000";               --Set the present buffer to zero and               
                                        in_sel <= "01";              --Move the write-pointer to next buffer ;
                                elsif(in_sel = "01")THEN
                                        dff_1 <= "00000";
                                        in_sel <= "10";
                                elsif(in_sel = "10")THEN
                                        dff_2 <= "00000";
                                        in_sel<= "11";
                                elsif(in_sel = "11")THEN
                                        dff_3 <= "00000";
                                        in_sel <= "00";
                                END IF;
                        END IF;
                ELSE                                                 --Want to write data into the fifo ;
                        IF(in_sel = "00")THEN                           --when write-pointer in_sel is "00" ;
                                        dff_0 <= rxd & rxdv;                          --Load data into dff_0
                                        in_sel <= "01";               --Move the write-pointer the next buffer ;
                        elsif(in_sel = "01")THEN               
                                        dff_1 <= rxd & rxdv;  
                                        in_sel <= "10";
                        elsif(in_sel = "10")THEN
                                        dff_2 <= rxd & rxdv;  
                                        in_sel <= "11";
                        elsif(in_sel = "11")THEN
                                        dff_3 <= rxd & rxdv;  
                                        in_sel <= "00";
                        END IF;
                END IF;
        END IF;
END PROCESS;


--////////////////////////////////////
--
--                        Output data from the fifo
--
--////////////////////////////////////

outputs:
PROCESS(txclk, reset_tx)
BEGIN
        if(reset = '0')then                                                                --Global reset ;                                                               
                txd <="0000";
                out_sel <= "10";
        elsif(txclk'EVENT AND txclk = '0')THEN                --Synchronize the falling edge of the txclk ;
                IF(reset_tx = '0') THEN                            --Do not need to read data from fifo ;
                        txd <= "0000";                                 --Reset state & pointer for next packet ;
                        out_sel <= "10";
                ELSE        
                        IF(out_sel = "00")THEN               --When read-pointer out_sel is "00"
                                        txd <= dff_0(4 downto 1);       --Read the data from buffer dff_0 ;
                                        --txer <= dff_b(1);
                                        txen <= dff_0(0);                  
                                        out_sel <= "01";                        --Move the pointer to next buffer;
                        elsif(out_sel = "01")then
                                        txd <= dff_1(4 downto 1);
                                        --txer <= dff_a(1);
                                        txen <= dff_1(0);
                                        out_sel <= "10";
                        elsif(out_sel = "10")then
                                        txd <= dff_2(4 downto 1);
                                        --txer <= dff_a(1);
                                        txen <= dff_2(0);
                                        out_sel <= "11";
                        elsif(out_sel = "11")then
                                        txd <= dff_3(4 downto 1);
                                        --txer <= dff_a(1);
                                        txen <= dff_3(0);
                                        out_sel <= "00";
                        END IF;
                END IF;
        END IF;
END PROCESS;

--///////////////////////////////////////////////
--
--                        Data Input Enable reset_rx generation
--
--///////////////////////////////////////////////

reset_rx_gen:
PROCESS(rxclk, rxdv)
BEGIN
        if(reset = '0')then                                                                --Global reset ;
                reset_rx <= '0';
        elsif(reset_rx = '0')THEN                     --When do not need to write data to the buffer ;
                        reset_rx <= rxdv;               --Asynchronous set... setup before the rising edge
        else if(rxclk'EVENT AND rxclk = '1')THEN        --When need to write data to the buffer and
--                        IF(reset_rx = '1')THEN
                                reset_rx <= rxdv;                                         --Synchronous clear
--                        END IF;
                END IF;
        END IF;
END PROCESS;

--////////////////////////////////////////////////
--
--                        Data Output Enable reset_tx generation
--
--////////////////////////////////////////////////
reset_tx_gen:
PROCESS(txclk, rxdv)
BEGIN
        if(reset = '0')then                                                                --Global reset ;       
                reset_tx <= '0';
        elsif(txclk'EVENT AND txclk = '0')THEN                --Synchronize the falling edge of the txclk ;  
                reset_tx <= rxdv OR dff_0(0) OR dff_1(0) OR dff_2(0) OR dff_3(0) ;
        END IF;                                --Setting the read-flag to true When valid data in the buffer
END PROCESS;

txer <= '0';                                                                    --Transmission no error ;

END behavior;
PARTNER CONTENT

文章评论3条评论)

登录后参与讨论

用户1487752 2011-5-14 22:16

值得借鉴,谢谢指教

用户120337 2011-5-14 18:48

其实,在做项目时,真没有必要做这种小板子。直接整合到系统里,更可靠。反正,出错了,都是要重新设计PCB的。

用户1471583 2009-7-19 13:13

呵呵 这个代码是我从网上找到的 直接就复制过来了 有时候排版不好 看的不方便 不过打包后看起来还得下载 也不太方便 呵呵

用户124183 2009-7-11 11:34

博主能不能将代码打包一下附在文章后面?在网页上看代码好累的~

用户212292 2009-7-6 21:15

一个fifo都要这么长的啊。。。
相关推荐阅读
用户1471583 2012-01-11 22:32
SOPC设计中多时钟域间的数据传递《转》
1 引言   可编程系统芯片SOPC的设计过程中经常会遇到如磁盘控制器、CD/DVD-ROM控制器、调制解调器、网络处理器等不同模块或系统间的数据传输。不同功能模块之间往往使用不同的时钟频率,各...
用户1471583 2012-01-11 22:30
FPGA异步时钟设计中的同步策略《转》
1 引言   基于FPGA的数字系统设计中大都推荐采用同步时序的设计,也就是单时钟系统。但是实际的工程中,纯粹单时钟系统设计的情况很少,特别是设计模块与外围芯片的通信中,跨时钟域的情况经常不可...
用户1471583 2012-01-11 22:20
MATLAB画双纵坐标
具有两个纵坐标标度的图形 在MATLAB中,如果需要绘制出具有不同纵坐标标度的两个图形,可以使用plotyy绘图函数。调用格式为: plotyy(x1,y1,x2,y2) 其中x1,y1对应...
用户1471583 2009-09-16 10:58
什么是TLB ?
TLB的基本概念:  TLB:Translation lookaside buffer,即旁路转换缓冲,或称为页表缓冲;里面存放的是一些页表文件(虚拟地址到物理地址的转换表)。  X86保护模式下的寻...
用户1471583 2009-07-26 15:52
Intel hex 文件格式(z)
Intel hex 文件常用来保存单片机或其他处理器的目标程序代码。它保存物理程序存储区中的目标代码映象。一般的编程器都支持这种格式。    Intel hex 文件全部由可打印的ASCII字符组成(...
用户1471583 2009-07-26 15:50
关于QuartusII里面调用MATLAB里生成的mif文件的一些问题(转)
最近做DDS正弦信号发生器,需要用到MATLAB生成一个正弦信号的ROM(MIF文件)。首先在MATLAB里面建立一个M-File,程序如下:depth=4096;                 %...
EE直播间
更多
我要评论
3
5
关闭 站长推荐上一条 /3 下一条