FIFO IP核仿真

时间:2023-03-09 07:51:00
FIFO IP核仿真

FIFO IP核仿真

1.FIFO IP核配置

FIFO IP核仿真

FIFO IP核仿真

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:
//
////////////////////////////////////////////////////////////////////////////////// module top(
rst,
wr_clk,
rd_clk,
dout,
full,
empty,
rd_data_count,
wr_data_count
); //input
input rst;
input wr_clk;
input rd_clk; //output
output [:]dout;
output full;
output empty;
output [:]rd_data_count;
output [:]wr_data_count; //write state
reg [:]i;
reg read_start;
reg [:]din_r;
reg clear_fifo_full;
reg wr_en_r;
wire wr_en;
wire [:]din;
wire [:]wr_data_count;
wire full;
always@(posedge wr_clk)
begin
if(rst)
begin
wr_en_r <= 'b0;
i <= 'd0;
read_start <= 'b0;
clear_fifo_full <= 'b0;
din_r <= 'd0;
end
else
begin
case(i)
:
begin
if(!full) begin wr_en_r <= 'b1; i<=i+1'b1; end
else wr_en_r <= 'b0;
end
:
begin
if(wr_data_count =='d512) begin read_start <=1'b1; din_r <= din_r +'b1; i<=i+1'b1; end
else din_r <= din_r +'b1;
end
:
begin
if(full) begin clear_fifo_full <= 'b1; wr_en_r <= 1'b0; i<='d0; end
else din_r <= din_r +'b1;
end
endcase
end
end assign wr_en = wr_en_r;
assign din = din_r; //read state
reg rd_en_r;
reg [:]j;
reg clear_fifo_empty;
wire rd_en;
always@(posedge rd_clk)
begin
if(rst)
begin
rd_en_r <= 'b0;
j <= 'd0;
clear_fifo_empty <= 'b0;
end
else
begin
case(j)
:
begin
if(read_start & !empty) begin rd_en_r <= 'b1; j<=j+1'b1; end
else rd_en_r <= 'b0;
end
:
begin
if(empty) begin clear_fifo_empty <= 'b1; rd_en_r <= 1'b0; j<='d0; end
else rd_en_r <= '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 { 0ns} { 150000ps}
add_force {/top/wr_clk} -radix hex { 0ns} { 50000ps} -repeat_every 100000ps
add_force {/top/rd_clk} -radix hex { 0ns} { 49500ps} -repeat_every 99000ps

4.仿真波形分析

FIFO IP核仿真

仿真波形图

FIFO IP核仿真

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

FIFO IP核仿真

与写状态有关的信号分析

FIFO IP核仿真

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

FIFO IP核仿真

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

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

FIFO IP核仿真

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

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