FIFO IP核仿真

摘要:
FIFOIP核仿真1.FIFOIP核配置2.FIFO测试逻辑代码首先往FIFO里面写入512个数据,然后再开始同时往FIFO里面写入,读出数据。FIFO读和写的时钟域不同,对于不同时钟域的信号应该进行区分,状态机也应该分开来写。下面来看FIFO读数据端的仿真波形当read_start信号拉高时,re_en信号开始拉高,FIFO才开始从dout端口读出数据,可以看到,刚开读出的数据为FIFOdin端口最先写入的数据。

FIFO IP核仿真

1.FIFO IP核配置

FIFO IP核仿真第1张

FIFO IP核仿真第2张

2.FIFO测试逻辑代码

首先往FIFO里面写入512个数据(FIFO深度的一半),然后再开始同时往FIFO里面写入,读出数据。FIFO读和写的时钟域不同,对于不同时钟域的信号应该进行区分,状态机也应该分开来写。

`timescale 1ns /1ps
//////////////////////////////////////////////////////////////////////////////////
//Company: 
//Engineer: chensimin
// 
//Create Date: 2017/10/23 16:11:32
//Design Name: 
//Module Name: top
//Project Name: 
//Target Devices: 
//Tool Versions: 
//Description: 
// 
//Dependencies: 
// 
//Revision:
//Revision 0.01 - File Created
//Additional Comments:
// 
//////////////////////////////////////////////////////////////////////////////////

moduletop(
    rst,
    wr_clk,
    rd_clk,
    dout,
    full,
    empty,
    rd_data_count,
    wr_data_count
    );

//input
inputrst;
inputwr_clk;
inputrd_clk;

//output
output [7:0]dout;
outputfull;
outputempty;
output [9:0]rd_data_count;
output [9:0]wr_data_count;

//write state
reg [2:0]i;
regread_start;
reg [7:0]din_r;
regclear_fifo_full;
regwr_en_r;
wirewr_en;
wire [7:0]din;
wire [9:0]wr_data_count;
wirefull;
always@(posedgewr_clk)
begin
    if(rst)
        beginwr_en_r <= 1'b0;
            i <= 3'd0;
            read_start <= 1'b0;
            clear_fifo_full <= 1'b0;
            din_r <= 8'd0;
        end
    else 
        begin
            case(i)
                0:
                begin 
                    if(!full) begin wr_en_r <= 1'b1; i<=i+1'b1; end
                    else wr_en_r <= 1'b0;
                end
                1:
                begin
                    if(wr_data_count ==10'd512) begin read_start <=1'b1; din_r <= din_r +1'b1; i<=i+1'b1; end
                    else din_r <= din_r +1'b1;
                end
                2:
                begin
                    if(full) begin clear_fifo_full <= 1'b1;  wr_en_r <= 1'b0;  i<=3'd0; end
                    else din_r <= din_r +1'b1;
                end
            endcase
        end
end

assign wr_en =wr_en_r;
assign din =din_r;

//read state
regrd_en_r;
reg [2:0]j;
regclear_fifo_empty;
wirerd_en;
always@(posedgerd_clk) 
begin
    if(rst) 
        beginrd_en_r <= 1'b0;
            j <= 3'd0;
            clear_fifo_empty <= 1'b0;
        end
    else 
        begin
            case(j)
                0:
                begin
                    if(read_start & !empty) begin rd_en_r <= 1'b1; j<=j+1'b1; end
                    else rd_en_r <= 1'b0;
                end
                1:
                begin
                    if(empty) begin  clear_fifo_empty <= 1'b1; rd_en_r <= 1'b0; j<=3'd0; end
                    else rd_en_r <= 1'b1;
                end
            endcase
        end
end

assign rd_en =rd_en_r;

fifo_generator_0 U1 (
  .rst(rst),                      //input wire rst
  .wr_clk(wr_clk),                //input wire wr_clk
  .rd_clk(rd_clk),                //input wire rd_clk
  .din(din),                      //input wire [7 : 0] din
  .wr_en(wr_en),                  //input wire wr_en
  .rd_en(rd_en),                  //input wire rd_en
  .dout(dout),                    //output wire [7 : 0] dout
  .full(full),                    //output wire full
  .empty(empty),                  //output wire empty
  .rd_data_count(rd_data_count),  //output wire [9 : 0] rd_data_count
  .wr_data_count(wr_data_count)  //output wire [9 : 0] wr_data_count
);

endmodule

3.测试脚本

add_force {/top/rst} -radix hex {1 0ns} {0150000ps} 
add_force {/top/wr_clk} -radix hex {0 0ns} {1 50000ps} -repeat_every 100000ps
add_force {/top/rd_clk} -radix hex {0 0ns} {1 49500ps} -repeat_every 99000ps

4.仿真波形分析

FIFO IP核仿真第3张

仿真波形图

FIFO IP核仿真第4张

FIFO进行复位操作,开始full,empty都会拉高一段时间,然后才会恢复正常。

FIFO IP核仿真第5张

与写状态有关的信号分析

FIFO IP核仿真第6张

full恢复正常后,写使能,同时状态机跳转。

FIFO IP核仿真第7张

当写入512个数据后(wr_data_count == 512),read_start信号开始拉高,FIFO开始读出数据,同时状态机也在此刻跳转,下一个状态再写数据的同时,也在监测FIFO是否已经被写满。

下面来看FIFO读数据端的仿真波形

FIFO IP核仿真第8张

read_start信号拉高时,re_en信号开始拉高,FIFO才开始从dout端口读出数据,可以看到,刚开读出的数据为FIFO din端口最先写入的数据。从rd_data_count端口可以看到,此时FIFO里面已经有500多个数据可以读。

结论:仿真结果与预期相符。

免责声明:文章转载自《FIFO IP核仿真》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇Redis 占用Windows系统盘空间23G第二章:Android Studio概述(二)[学习Android Studio汉化教程]下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

cpu IP核下载列表 (最新全集)

IP核下载列表 (最新全集) 下载必读:- n( R7 z! h: `/ D$ l/ V8 f* J1 c7 }2 e1 v$ |1 @3 V, q; i: B- Z, K& _1 G1. 绝大部分IP来自网络,缺乏足够的测试,仅供大家学习之用。, I: D% Y1 h2 u; R2. IP原作者版权所有,严禁商用。切记!1 }/ t+ b&...

操作系统——进程,线程,锁

基本概念 状态、地址空间 三种基本状态 —— 就绪、运行、阻塞 进程控制块PCB(Process Control Block) 进程描述信息(如PID); 进程控制&管理信息(状态、优先级等); 源分配清单(地址空间状况、fd等); 处理其相关信息(各寄存器的值等) 进程存在的标识,在Linux系统中是task_struct,task_s...

Linux内核结构体--kfifo 环状缓冲区

转载链接:http://blog.csdn.net/yusiguyuan/article/details/41985907 1、前言   最近项目中用到一个环形缓冲区(ring buffer),代码是由Linux内核的kfifo改过来的。缓冲区在文件系统中经常用到,通过缓冲区缓解cpu读写内存和读写磁盘的速度。例如一个进程A产生数据发给另外一个进程B,进程...

UART

UART(Universal Asynchronous Receiver/Transmitter,通用异步收/发器) s3c2440A 提供了三个UART端口,它们都可以通过查询、中断和DMA方式传输数据,而且每个UART都分别有一个64个字节的接收FIFO和一个64个字节的发送FIFO。 OVERVIEW The UART can generate a...

pll的ip核调用

Quartus ii的pll ip核调用: 1、先建立好工程。点击“Tools”,接着点击“Mega Wizard Plug-In Manager”。 2、创建一个新的ip核: 2、这里需要的是pll的ip核,所以就搜索“pll”,并选中“ALTPLL”,接着修改成fpga芯片型号,Verilog HDL,还有设置好pll ip核的路径和名称,这里的名称...

【STM32H7教程】第72章 STM32H7的SPI总线基础知识和HAL库API

完整教程下载地址:http://www.armbbs.cn/forum.php?mod=viewthread&tid=86980 第72章       STM32H7的SPI总线基础知识和HAL库API 本章节为大家讲解SPI(Serial peripheral interface)总线的基础知识和对应的HAL库API。 72.1 初学者重要提示 7...