学习调用ISE的FIFO IP核(包含ISE IP核文件的 do文件仿真)
FIFO是什么
fifo: First Input First Output的缩写,先入先出队列,这是一种传统的按序执行方法,先进入的指令先完成并引退,跟着才执行第二条指令。fifo说直白了其实就是一个RAM,只是读写数据的顺序有了规定。
一般用于不同时钟域之间的数据传输,当然这种情况下就是异步RAM
同步RAM指的是输入和输出使用的是同一个时钟或者同频时钟
使用ISE调用与设置FIFO的IP核
step1:添加一个FIFO IP核,起一个名字,起名字的时候一般就说明这个FIFO是同步的还是异步的。还要在名字中说明这个FIFO是多大的,数据宽度为多少,数据深度为多少
native FIFO: 本机接口FIFO可以定制以利用区块RAM、分布式RAM或内置的FIFO资源,
AX14 FIFO: 除了支持native FIFO支持的应用程序,AX14 FIFO还可以用于AX14 系统总线和点对点高速应用程序。AX14 FIFO不支持内置的FIFO与移位寄存器的FIFO设置
Block RAM: 指的是FPGA内部硬件已经存在的RAM,是硬件资源。在FPGA芯片内部都有这种已经设置好的芯片资源。
distribute RAM: 分布式RAM,使用FPGA内部的寄存器和查找表搭建起来的RAM,当深度要求小于32的时候可以使用。
shift Register: 使用FIFO产生一个移位寄存器
Common clock: 指的就是同步FIFO
Independent clock: 指的就是异步FIFO
Standard FIFO与First_word fall-Through区别在请看芯片手册
write width 数据宽度
write depth 数据深度
这一页的选项就是一些标志位,用来标记我们是否出现了读写溢出之类的。
Almost Full flag:就是我们可以设置一个位置,当写指针写道这个位置的时候,就会提醒说近乎满了,常用来设计警告之类的。
Almost Empty Flag :类似上面的作用
overflow:就是写指针追到了读指针,然后还继续写就会overflow
具体的参数的设计还是要根据需求去设置
.v文件的书写与例化
module ex_ise_fifo(
input wire sclk,
input wire rst_n,
input wire [7:0] data_in,
input wire data_v, //当data_v为高的时候表示数据有效,与data_in配合使用
input wire r_flag, //r_flag 读FIFO的标志
output wire [7:0] dout
);
wire almost_full,wr_ack,overflow,almost_empty,valid,underflow;
wire w_full, r_empty; //分别表示写满和读空
wire wr_en;
wire rd_en;
assign wr_en = (~w_full)&data_v; //写使能要结合我们写满的信号来产生,不然会产生写溢出的情况
assign rd_en = (~r_empty)&r_flag;
sync_fifo_8_256 sync_fifo (
.clk(sclk), // input clk
.rst(rst_n), // input rst
.din(data_in), // 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(w_full), // output full
.almost_full(almost_full), // output almost_full
.wr_ack(wr_ack), // output wr_ack
.overflow(overflow), // output overflow
.empty(r_empty), // output empty
.almost_empty(almost_empty), // output almost_empty
.valid(valid), // output valid
.underflow(underflow) // output underflow
);
endmodule
测试文件
`timescale 1ns/1ns
module tb_ex_ise_fifo;
reg sclk,rst_n;
reg data_v;
reg r_flag;
reg [7:0] data;
wire [7:0] dout;
initial begin
sclk = 0;
rst_n = 0;
#100;
rst_n = 1;
end
initial begin
data_v = 0;
data = 0;
r_flag = 0;
#200
send_data();
#60;
read_Data();
end
always #10 sclk = ~sclk;
ex_ise_fifo ex_ise_fifo_inst(
.sclk(sclk),
.rst_n(rst_n),
.data_in(data),
.data_v(data_v),
.r_flag(r_flag),
.dout(dout)
);
task send_data();
integer i;
begin
for(i=0;i<256;i=i+1)
begin
@(posedge sclk)
data_v = 1'b1;
data = i;
end
@(posedge sclk) //如果不写这个的话在
data_v = 1'b0;
data = 0;
end
endtask
task read_Data();
integer i;
begin
for(i=0;i<259;i=i+1)
begin
@(posedge sclk)
r_flag = 1'b1;
end
@(posedge sclk)
data_v = 1'b0;
end
endtask
endmodule
使用do文件进行仿真
对包含 ISE IP核的文件进行do文件仿真的时候要注意,直接编译肯定会出错,因为没有编译IP核,这是要做的就是根据提示的错误在ISE的安装目录下找到 提示未编译的文件(大概的地方在ISE->14.7->ISE_DS->ISE->verilog->src 在该目录下搜索报错的文件),然后在仿真文件夹下再建一个ise_lib文件夹,将这个文件和src文件夹下的glbl.v文件放在该文件夹下,然后重新修改do文件。
quit -sim
.main clear
vlib work
vlog ./tb_ex_ise_fifo.v
vlog ./../design/ex_ise_fifo.v
vlog ./../ise_prj/ipcore_dir/*.v
vlog ./ise_lib/*.v
vsim -voptargs=+acc work.tb_ex_ise_fifo work.glbl
add wave tb_ex_ise_fifo/ex_ise_fifo_inst/*
run 10us
这里面编译的时候要注意编译 glbl文件,因为它是一个全局文件,调用了IP核的话就一定用得到这个文件。