加入星计划,您可以享受以下权益:

  • 创作内容快速变现
  • 行业影响力扩散
  • 作品版权保护
  • 300W+ 专业用户
  • 1.5W+ 优质创作者
  • 5000+ 长期合作伙伴
立即加入
  • 正文
    • 1 Fifo的定制
    • 2 fifo的复位
    • 3 fifo的读写控制逻辑
    • 4 example
  • 推荐器件
  • 相关推荐
  • 电子产业图谱
申请入驻 产业图谱

FIFO的使用方式

09/04 21:53
294
阅读需 12 分钟
加入交流群
扫码加入
获取工程师必备礼包
参与热点资讯讨论

fifo的使用方式有很多种且方法灵活,这里不再做赘述。可以参考xilinx pg057文档及中研院总结的”fifo的使用”文档。本文档只推荐一种常用的native接口的fifo使用的建议方式,以满足大多数的应用场景。

1 Fifo的定制

  1. 通常情况选择independent clock模式,这样读写时钟是否同源都可以支持,便于后期维护修改。
  2. 根据所需深度选择distributed ram 与 blockram类型,原则上小的fifo建议使用distributed ram类型以节省block ram资源。
  3. 选择Standard 或FWFT模式,选择StandardFIFO ,默认为1clk延迟,FWFT无延时。当block ram类型时,可以选择添加output registers,在复杂布线情况下应该有助于布线结果,当然此时为2clk延迟。
  4. 使能resetpin,使能 reset synchronization,Full flags reset value值为1。
  5. 如果采用Prog_full信号反压写信号,需要根据链路延迟合理设置fullthreshold。
  6. 根据需要使能wr_data_cnt 和 rd_data_cnt。

2 fifo的复位

  1. 采用读写时钟中的慢速时钟产生至少8clk的复位信号进行fifo复位 , 若采用快时钟产生,保证产生宽度满足以上条件亦可。
  2. 复位完成后至少等待60个慢时钟周期再进行读写操作,严格来讲需要等待full信号拉低才可以(异步复位模式,Full flags reset value值为1)。此处以附带safetycircuit为例,若不带safety circuit,时间要比这个短,但在视频帧结构应用中,只要复位的时机合理,都可以保证此要求。
  3. 复位过程中严禁读写操作。
  4. 通常在视频帧结构处理中,采用视频vs的后沿构造,并满足以上需求。
  5. 复位过程时钟必须是稳定的。

3 fifo的读写控制逻辑

通常fifo的写使能和写数据由fifo的前后读写速度或progfull决定,保证fifo不应该被写溢出,且要保证在复位时刻写使能为0。

通常可以采用非空信号作为读使能(RST拉起来后empty也会拉高,可以保证复位时无读使能)。

也可以采用rd_data_cnt构造读使能。

也可以由独立的时序构造读使能,只要能从fifo的读写带宽上保证读使能来的时候fifo中一定由足够的数据即可。

建议对满写overflow和和空读underflow进行监测。

example

4.1 Example1

该用例可以应用于数据需要跨时钟域传输时,读端时钟速率大于等于写端时钟,或者是读端时钟速率略小于写端时钟速率,但可以利用数据流的行间隔时间以及合理的fifo深度,保证所有写入的数据均能够及时读出而不被新写入的数据覆盖。

此种应用时,fifo的复位可以是上电一次合理时间的复位,若是视频流,建议在视频垂直逆程通过vs的沿构造合理的周期性复位。

reg [9:0] vs_dly;
always @ (posedge wr_clk) 
begin
	    vs_d0 <= vs;
	    vs_d1 <= vs_d0;
	    vs_d2 <= vs_d1;
end
assign vs_pos = vs_d1 && (!vs_d2);
always @ (posedge wr_clk) 
begin	
	   vs_dly <= {vs_dly[8:0],vs_pos};
end
always @ (posedge wr_clk) 
begin
	fifo_rst <= |vs_dly[9:0];
end
AsyFifo_Std_64x36 inst_RxFifo(
  .rst      ( fifo_rst     ),
  .wr_clk   ( wr_clk       ), // 27M~165M
  .rd_clk   ( rx_clk       ), // 162.5M
  .din      ( wr_dat[35:0] ), 
  .wr_en    ( wr_en        ), // video in en
  .rd_en    ( rd_en        ), 
  .dout     ( rd_dat[35:0] ), 
  .full     ( full         ), 
  .empty    ( empty        ),
  .valid    (              )
  );
assign rd_en =~empty;
always @ (posedge RxClk) 
begin
    rd_en_d1          <= rd_en   ;
    fifo_rx_vld         <= rd_en_d1;
fifo_rd_dat[35:0]   <= rd_dat[35:0];
end

4.2 Example2

本用例采用prog_full信号反压写端数据流,从而保证fifo的读写的速率匹配。通常可用在fifo前端的数据已经在一个缓存中,并且可以随时访问。这样可以通过这个机制跨到fifo的读时钟域下。这里需要根据链路的延迟合理时钟progfull的阈值。

assign rd_ram_en =  ~prog_full;  
always@(posedge   wr_clk)
begin
	rd_ram_en_d1 <= rd_ram_en;
	wr_en  <= rd_ram_en_d1;
	wr_dat <= rd_ram_dat;
end
AsyFifo_Std_64x36  RxFifo(
  .rst      ( fifo_rst ),
  .wr_clk   ( wr_clk ), 
  .rd_clk   ( rd_clk ), 
  .din      ( wr_dat[35:0] ), 
  .wr_en    ( wr_en ), 
  .rd_en    ( ~empty), 
  .dout     ( rd_dat[35:0] ), 
  .full     (  ), 
  .empty    ( empty ),
  .valid    ( rx_vld   ),
  .prog_full( prog_full)
  );
always @(posedge rd_clk)
begin
	vin_de_out    <= rx_vld;
	vin_data_out  <= rd_dat;
end

4.2 Example3

该用例是典型的通过判断fifo中数据量构造读取fifo的逻辑,写端数据流可以不间断的写入fifo。所以需要保证fifo的读取速率能够大于写入速率。

通常如果有多路异步数据流需要同步到同一处理时钟域的时候,可以采用此种方式,只需保证读时钟大于写时钟即可。

读取fifo的使能信号还可以作为所有这路数据流后续所有处理逻辑的clock enable信号,以达到减少动态功耗的目的。

当然如果不采用ce的方式,也可以用读使能与上数据流中的嵌入的de,构造出新的数据使能信号。(写使能的机制能够保证所有数据能从fifo中读出)

assign wr_en = (fifo_rst || full) ? 0 : 1;
always@(posedge proc_clk)
begin
    if(rd_dat_cnt >= 8) // 根据fifo深度合理设置即可
        rd_set <= 1'b1;
    else
        rd_set <= 1'b0;
end
always@(posedge proc_clk)
begin
    if(rd_dat_cnt<=4)// 根据fifo深度合理设置即可
        rd_clear <= 1'b1;
    else
        rd_clear <= 1'b0;
end
always@(posedge proc_clk)
begin
    if(rd_set)
        rd_en <= 1'b1;
    else if(rd_clear)
        rd_en <= 1'b0;
    else
        rd_en <= rd_en;
end
AsyFifo_Std_64x24 inst_RxFifo(
  .rst      (fifo_rst ),
  .wr_clk   ( video_in_clk), //27M~165M
  .rd_clk   ( proc_clk    ), //200M
  .din      ( {video_in_de,video_in_data[23:0]} ), 
  .wr_en    ( wr_en        ), 
  .rd_en    ( rd_en        ), 
  .dout     ( rd_dat[24:0] ), 
  .full     ( full            ), 
  .empty    (              ),
  .rd_data_count(rd_dat_cnt)
  );
always @(posedge proc_clk)
begin
    if(rd_en)
        begin
            vin_de_out   <= rd_dat[24];
            vin_data_out <= rd_dat[23:0];
        end
end
assign clk_ce = rd_en;
or
always @(posedge proc_clk)
begin
    vin_de_out   <= rd_dat[24] && rd_en;
    vin_data_out <= rd_dat[23:0];
end

推荐器件

更多器件
器件型号 数量 器件厂商 器件描述 数据手册 ECAD模型 风险等级 参考价格 更多信息
EP4CE22E22I7N 1 Intel Corporation Field Programmable Gate Array, 1395 CLBs, 472.5MHz, 22320-Cell, PQFP144, 22 X 22 MM, 0.50 MM PITCH, LEAD FREE, EQFP-144

ECAD模型

下载ECAD模型
$280.9 查看
LFE3-70EA-8FN484C 1 Lattice Semiconductor Corporation Field Programmable Gate Array, 500MHz, 67000-Cell, PBGA484, 23 X 23 MM, LEAD FREE, FPBGA-484

ECAD模型

下载ECAD模型
$73.57 查看
5M1270ZT144C5N 1 Altera Corporation Flash PLD, 10ns, 980-Cell, CMOS, PQFP144, 22 X 22 MM, 0.50 MM PITCH, LEAD FREE, TQFP-144

ECAD模型

下载ECAD模型
$14.96 查看

相关推荐

电子产业图谱

公益知识星球:95后创业者;CCF学生会员;知识星球:ESTJ-A,森森FPGA学术技术分享;微信公众号:Lucky时先生;需要合作,请联系微信:c1996sks,备注合作+单位

知乎