26A FIFO模型与应用场景详解_哔哩哔哩_bilibili
//前面摸了好久的鱼,感觉是这个视频合集少了一些内容
//现在根据自学教程和其他资料来学习一下
1. FIFO (First In First Out)
对数据的存储具有先进先出 特性的一个缓存器,常被用于数据的缓存或者高速异步数据的交互。
它与普通存储器的区别是没有外部读写地址线,这样使用起来相对简单,但缺点就是只能顺序写入数据,顺序的读出数据,其数据地址由内部读写指针自动加 1 完成,不能像普通存储器那样可以由地址线决定读取或写入某个指定的地址。
重点是:写入时钟、读出时钟、输入位宽、输出位宽可以不同
2. FIFO IP核简单配置
搞一个,写入时钟50MHz , 位宽8 , 深度 256
输出时钟25MHz , 位宽16
这里的实际深度要注意一下
Read Mode
有两种类型可选,
Standard FIFO 是在给了读数据使能后, 数据才出来,
而 First Word Fall Through 模式是,当前数据提前已经到读数据线上,在读使能到来后,下一个数据会到数据线上,可以结合下面的时序图进行理解。这里选择
Standard FIFO
类型。
在
Output Register 勾选并选择
Embedded Register
,也可以选择
Fabric Register,或者两个寄存器都选加上,多加一个输出寄存器,输出数据就会多延迟一个时钟周期。
3. FIFO_tb
/ // Company: 武汉芯路恒科技有限公司 // Engineer: 小梅哥团队 // Web: www.corecourse.cn // // Create Date: 2021/09/20 00:00:00 // Design Name: dcfifo_tb // Module Name: dcfifo_tb // Project Name: dcfifo_tb // Target Devices: xc7z020clg400-2 // Tool Versions: Vivado 2018.3 // Description: dcfifo_tb // // Dependencies: // // Revision: // Revision 0.01 - File Created // Additional Comments: // // `timescale 1ns / 1ns `define WR_CLK_PERIOD 20 //一个周期 在配置时钟信号时,要用一半 `define RD_CLK_PERIOD 80
module fifo_tb(); reg rst; reg wr_clk; reg rd_clk; reg [7:0]din; reg wr_en; reg rd_en; wire [15:0]dout; wire full; wire almost_full; wire wr_ack; wire overflow; wire empty; wire almost_empty; wire valid; wire underflow; wire [6:0]rd_data_count; wire [7:0]wr_data_count; wire wr_rst_busy; wire rd_rst_busy; //配置时钟信号 initial wr_clk = 1;//50MHz always #(`WR_CLK_PERIOD/2) wr_clk = ~wr_clk;
initial rd_clk = 1;//12.5MHz always #(`RD_CLK_PERIOD/2) rd_clk = ~rd_clk; initial begin rst = 1'b1; wr_en = 1'b0; rd_en = 1'b0; din = 8'hff; #(`WR_CLK_PERIOD*8+1); rst = 1'b0; @(negedge wr_rst_busy); //等待下降沿信号 //之前都是些写 always 有这个的话就是每次检测到都要执行 ,本次只是进行一次写入操作 //write data while(full == 1'b0) begin @(posedge wr_clk); #1; wr_en = 1'b1; din = din + 1'b1; end //再多写一个数据,看overflow的变化 din = 8'hff; @(posedge wr_clk); wr_en = 1'b0;
wait(rd_rst_busy == 1'b0); #2000; while(empty == 1'b0) begin @(posedge rd_clk); #1; rd_en = 1'b1; end //再多给一个读使能,看underflow的变化 @(posedge rd_clk); rd_en = 1'b0; //reset #200; rst = 1'b1; #(`WR_CLK_PERIOD*3+1); rst = 1'b0; @(negedge wr_rst_busy); wait(rd_rst_busy == 1'b0); #2000; $stop; end
fifo_generator_0 fifo_inst ( .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 .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 [7 : 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 );
endmodule
嘎嘎嘎!!!这个问题看着是不是很离谱!!!!
之前遇到过不定态是将几条同名输出线接在一起
这个按照道理应该是FIFO内部产生的一个信号凭什么搞这样!!!!
仿真FIFO时,wr_rst_busy信号出现未知态的原因 - Vivado仿真相关问题 - 芯路恒电子技术论坛 - Powered by Discuz! (corecourse.cn)
设置一下:
嘎嘎嘎!!! 具体分析就不写啦~
自己检查一下就可以啦~