南通优普高端网站建设,wordpress 煎蛋主题,网站上传到虚拟空间,新乡辉县网站建设什么是FIFO
FIFO (First In First Out) ,也就是先进先出。FPGA或者ASIC中使用到的FIFO一般指的是对数据的存储具有先进先出特性的一个缓存器,常被用于数据的缓存或者高速异步数据的交互。它与普通存储器的区别是没有外部读写地址线,这样使用起来相对简单,但缺点就是只能顺序写…什么是FIFO
FIFO (First In First Out) ,也就是先进先出。FPGA或者ASIC中使用到的FIFO一般指的是对数据的存储具有先进先出特性的一个缓存器,常被用于数据的缓存或者高速异步数据的交互。它与普通存储器的区别是没有外部读写地址线,这样使用起来相对简单,但缺点就是只能顺序写入数据,顺序的读出数据,其数据地址由内部读写指针自动加1完成不能像普通存储器那样可以由地址线决定读取或写入某个指定的地址。
FIFO作用对于存储的数据先存入FIFO的先被读出可以确保数据的连续性
1特征数据产生速率数据消耗速率 FIFO写入侧位宽 FIFO读出侧位宽 2特征数据产生速率数据消耗速率 FIFO写入侧位宽 FIFO读出侧位宽 标准读模式同步FIFO
利用以下例子来熟悉FIFO使用 打开vivado 创建工程 点击ok FIFO配置完成
然后编写FIFO测试文件
代码如下
timescale 1ns / 1ps
module bram_sync_fifo_tb;reg clk; // input wire clkreg srst; // input wire srstreg [7:0]din; // input wire [7 : 0] dinreg wr_en; // input wire wr_enreg rd_en; // input wire rd_enwire [7:0]dout; // output wire [7 : 0] doutwire full; // output wire fullwire almost_full; // output wire almost_fullwire wr_ack; // output wire wr_ackwire overflow; // output wire overflowwire empty; // output wire emptywire almost_empty; // output wire almost_emptywire valid; // output wire validwire underflow; // output wire underflowwire [7:0]data_count; // output wire [7 : 0] data_count bram_sync_fifo your_instance_name (.clk(clk), // input wire clk.srst(srst), // input wire srst.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.almost_full(almost_full), // output wire almost_full.wr_ack(wr_ack), // output wire wr_ack.overflow(overflow), // output wire overflow.empty(empty), // output wire empty.almost_empty(almost_empty), // output wire almost_empty.valid(valid), // output wire valid.underflow(underflow), // output wire underflow.data_count(data_count) // output wire [7 : 0] data_count);initial clk 1;always #10 clk ~clk;initial beginsrst 1b1;wr_en 1b0;rd_en 1b0;din 8hff;#21;srst 1b0;//写操作 从0-255 共256数据while(full 1b0)begin(posedge clk);#1;wr_en 1b1;din din 1b1;end//再多写1个数据 观察overflow的变化din 8hf0;(posedge clk);#1;wr_en 1b0;#2000;//读操作 读256次while(empty 1b0)begin(posedge clk)#1;rd_en 1b1;end//再多给一个读使能 看underflow的变化(posedge clk)#1;rd_en 1b0;//复位#200;srst 1b1;#21;srst 1b0;#2000;$stop;endendmodule仿真波形 写入时的波形
写满时的波形
读出时的波形 读完时的波形 FWFT读模式异步FIFO 点击ok FIFO配置完成
然后编写FWFT读模式异步FIFO测试文件
代码如下
timescale 1ns / 1ps
module bram_asynv_fifo_tb;reg rst; // input wire rstreg wr_clk; // input wire wr_clkreg rd_clk; // input wire rd_clkreg [7:0]din; // input wire [7 : 0] dinreg wr_en; // input wire wr_enreg rd_en; // input wire rd_enwire [15:0]dout; // output wire [15 : 0] doutwire full; // output wire fullwire almost_full; // output wire almost_fullwire wr_ack; // output wire wr_ackwire overflow; // output wire overflowwire empty; // output wire emptywire almost_empty; // output wire almost_emptywire valid; // output wire validwire underflow; // output wire underflowwire [7:0]rd_data_count; // output wire [7 : 0] rd_data_countwire [8:0]wr_data_count; // output wire [8 : 0] wr_data_countwire wr_rst_busy; // output wire wr_rst_busywire rd_rst_busy; // output wire rd_rst_busybram_async_fifo your_instance_name (.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 [15 : 0] dout.full(full), // output wire full.almost_full(almost_full), // output wire almost_full.wr_ack(wr_ack), // output wire wr_ack.overflow(overflow), // output wire overflow.empty(empty), // output wire empty.almost_empty(almost_empty), // output wire almost_empty.valid(valid), // output wire valid.underflow(underflow), // output wire underflow.rd_data_count(rd_data_count), // output wire [7 : 0] rd_data_count.wr_data_count(wr_data_count), // output wire [8 : 0] wr_data_count.wr_rst_busy(wr_rst_busy), // output wire wr_rst_busy.rd_rst_busy(rd_rst_busy) // output wire rd_rst_busy);initial wr_clk 1;always #10 wr_clk ~wr_clk;initial rd_clk 1;always #5 rd_clk ~rd_clk;reg [5:0]cnt;always(posedge rd_clk or posedge rst)if(rst)#1 cnt 1b0;else if(cnt 6d31)#1 cnt 1b0;else if(rd_en)#1 cnt cnt 1b1;always(posedge rd_clk or posedge rst)if(rst)#1 rd_en 1b0;else if(rd_data_count 9d31)#1 rd_en 1b1;else if(cnt 6d31)#1 rd_en 1b0;initial beginrst 1b1;wr_en 1b0;din 8hff;#(20*31);rst 1b0;//写数据(negedge wr_rst_busy);wait(rd_rst_busy 1b0);repeat(257)begin(posedge wr_clk)#1;wr_en 1b1;din din 1b1;endwr_en 1b0;#1000;$stop;endendmodule仿真波形 写入时的波形
wr_en拉高 开始写数据 问题1解答
这一块是由于仿真器设置导致的在设置中语言选择的是Verilog和VHDL混合模式所以会导致这个现象但不建议直接改为Verilog语言模式因为在一些IP核的底层是由Verilog和VHDL写好的如果在这里改过来虽然这一块波形是好的但有可能在其他地方出现问题。 问题2解答
看手册可以得知 空FIFO下 wr_data_count的值和 写深度与读深度的比例有关
在前面FIFO设置中写深度与读深度比例是256:128即2:1
看手册可知 wr_data_count的值为4。 问题3解答
查看手册 可知在设置more accurate data counts后,当FIFO为空或几乎空时,写计数会多计数两个读数据量。当empty取消断言后,在almost_empty取消断言后的几个写时钟周期内写计数会存在一个过渡期来让自己的值正确。
为此会出现下列情况:
1·虽然没有读操作,但是写计数会出现递减
2.由于写操作的持续写计数的值并不会按照预期增加
读出时波形
rd_en拉高 开始读数据