1.fifo为先进先出的ip核,与ram的不同的是,fifo只读一次。
将fifo放到一个模块中,利用测试模块产生fifo所需要的信号,这次调取的fifo ip核主要有输入数据、写使能信号、读使能信号,以及、数据空状态、数据满状态这5个输入信号,这些信号需要在测试模块中产生。fifo的写使能处于高电平状态、时钟采集沿就会采集数据。
2.fifo模块程序,调用ip核对于ise要在工程中使用,ip核需要建ip核工程文件。
module les_fifo(
input wire sclk,
input wire [7:0] data,
input wire wr_en,
input wire rd_en,
output wire [7:0] dout,
output wire full_flag,
output wire empty_flag
);
fifo_256_8 fifo_256_8_inst (
.clk(sclk), // input clk
.din(data), // input [7 : 0] din
.wr_en(wr_en), // input wr_en
.rd_en(rd_en), // input rd_en
.dout(dout), // output [7 : 0] dout
.full(full_flag), // output full
.empty(empty_flag) // output empty
);
endmodule
3.测试模块,这次对ip核模块进行了4次仿真。这里只P前2中,然后对模块对应信号给出解释。
`timescale 1ns/1ns
module tb_fifo;
reg sclk;
reg [7:0] data;
reg wr_en;
reg rd_en;
reg rst_n;
wire[7:0] dout;
wire full_flag;
wire empty_flag;
initial
begin
sclk=0;
data<=8'd0;
wr_en<=0;
rd_en<=0;
rst_n<=0;
#50
rst_n<=1;
end
always #20 sclk=~sclk;
always@(posedge sclk or negedge rst_n) //产生数据
if(!rst_n)
data<=8'd0;
else if(data==255)
data<=data;
else data<=data+1'b1;
always@(posedge sclk or negedge rst_n) //产生写使能信号
if(!rst_n)
wr_en<=0;
else if(data==255)
wr_en<=0;
else wr_en<=1;
always@(posedge sclk or negedge rst_n) //产生读使能信号
if(!rst_n)
rd_en<=0;
else rd_en<=wr_en;
les_fifo les_fifo_inst(
.sclk (sclk),
.data (data),
.wr_en (wr_en),
.rd_en (rd_en),
.dout (dout),
.full_flag (full_flag),
.empty_flag (empty_flag)
);
endmodule
`timescale 1ns/1ns
module tb_fifo2;
reg sclk;
reg n_sclk;
reg [7:0] data;
reg wr_en;
reg rd_en;
reg rst_n;
wire[7:0] dout;
wire full_flag;
wire empty_flag;
initial
begin
sclk=0;
n_sclk<=0;
data<=8'd0;
wr_en<=0;
rd_en<=0;
rst_n<=0;
#50
rst_n<=1;
end
always #20 sclk=~sclk;
always@(posedge sclk or negedge rst_n) //产生新时钟的保持
if(!rst_n)
n_sclk<=0;
else n_sclk=~n_sclk;
always@(posedge n_sclk or negedge rst_n) //产生数据
if(!rst_n)
data<=8'd0;
else if(data==255)
data<=data;
else data<=data+1'b1;
always@(posedge sclk or negedge rst_n) //产生写使能信号
if(!rst_n)
wr_en<=0;
else if(data==255)
wr_en<=0;
else wr_en<=1;
always@(posedge sclk or negedge rst_n) //产生读使能信号
if(!rst_n)
rd_en<=0;
else if(data==255&&wr_en==0)
rd_en<=1;
les_fifo les_fifo_inst(
.sclk (sclk),
.data (data),
.wr_en (wr_en),
.rd_en (rd_en),
.dout (dout),
.full_flag (full_flag),
.empty_flag (empty_flag)
);
endmodule
4.对应测试文件的仿真结果如下图。
图1,可以看出输出数据dout比输入数据data慢了2个时钟周期,这是因为写使能和读使能信号均往后打拍,而输入数据满即使full_flag信号一直处于低电平时因为输入输出数据都及时读出来了。本次仿真的实验fifo的输入数据为256个8bit的数据。
图2对fifo ip核仿真,不同的是这次读信号在输进来的数据结束的时候,才让其处于高电平状态,从图中可以看出这次让输入的数据保持2个系统时钟周期。所以读写使能对每个时钟的数据进行了读写。而由于这次ip的位宽为8深度是256的缓存,所以只能存256个数据,即对0--128进行了2次缓存。而full_flag信号在输入数据为128的时候进行了拉高标志。空标志即empty_flag在数据读完拉高。