在FPGA开发中,跨时钟域数据传输一直是个棘手的问题。虽然现代FPGA内置了丰富的FIFO IP核,但某些特殊场景下,那些被遗忘在角落的老古董芯片——比如IDT7204/7205异步FIFO,反而能发挥意想不到的作用。这些上世纪90年代诞生的芯片,凭借其独特的并行接口和硬件级异步处理能力,至今仍在一些工业设备、测试仪器和传统系统中服役。本文将带你探索如何让这些"老将"在现代FPGA项目中焕发新生。
在Xilinx和Intel FPGA都提供高性能FIFO IP核的今天,我们仍有几个理由考虑使用外部异步FIFO芯片:
提示:在需要与遗留系统对接或对时序抖动极其敏感的场合,这类芯片往往比软核FIFO更可靠。
下表对比了IDT7205与Xilinx FIFO IP核的关键参数:
| 特性 | IDT7205 | Xilinx FIFO IP核 |
|---|---|---|
| 存取时间 | 12ns固定 | 取决于时钟频率 |
| 供电电压 | 5V | FPGA内核电压(通常1V) |
| 最大深度 | 8K×9(可扩展) | 受限于BRAM资源 |
| 跨时钟域能力 | 硬件支持 | 需正确约束时序 |
| 重传功能 | 硬件支持 | 需逻辑实现 |
连接IDT7205到Artix-7 FPGA的典型电路如下:
verilog复制// Verilog 引脚声明示例
module fifo_interface (
input wire clk_50m,
inout wire [8:0] fifo_data, // 双向数据总线
output wire fifo_wr_n,
output wire fifo_rd_n,
input wire fifo_ff_n,
input wire fifo_ef_n,
input wire fifo_hf_n,
output wire fifo_rs_n
);
关键连接注意事项:
尽管IDT7205标称工作电压5V±10%,但实际测试表明:
下面是一个可靠的写操作状态机片段:
verilog复制always @(posedge clk or posedge reset) begin
if (reset) begin
wr_state <= IDLE;
fifo_wr_n <= 1'b1;
end else begin
case(wr_state)
IDLE:
if (~fifo_ff_n & wr_req) begin
fifo_data_out <= wr_data;
wr_state <= ASSERT_WR;
end
ASSERT_WR:
begin
fifo_wr_n <= 1'b0;
wr_state <= DEASSERT_WR;
end
DEASSERT_WR:
begin
fifo_wr_n <= 1'b1;
wr_state <= IDLE;
end
endcase
end
end
在XDC文件中必须添加如下约束:
tcl复制# 确保满足tWHS(写使能保持时间)要求
set_input_delay -clock [get_clocks clk_50m] \
-min 5 [get_ports fifo_wr_n]
# 数据信号相对于写使能的建立时间
set_input_delay -clock [get_clocks clk_50m] \
-max 3 [get_ports fifo_data*]
重传(RT)功能是IDT7204/7205的杀手锏,特别适合需要数据回放的场景:
实现代码示例:
verilog复制// 重传控制模块
module retransmit_ctrl (
input wire clk,
input wire error_flag,
output reg fifo_rt_n
);
reg [7:0] counter;
always @(posedge clk) begin
if (error_flag) begin
fifo_rt_n <= 1'b0;
counter <= 8'd10; // 保持50ns(假设clk=50MHz)
end else if (counter > 0) begin
counter <= counter - 1;
end else begin
fifo_rt_n <= 1'b1;
end
end
endmodule
异步标志信号(如EF/FF)必须经过同步处理:
verilog复制// 双触发器同步链
reg ff_sync1, ff_sync2;
always @(posedge clk) begin
ff_sync1 <= fifo_ff_n;
ff_sync2 <= ff_sync1;
end
在一次电机控制项目中,我们发现当FPGA同时读写FIFO时,偶尔会出现状态标志抖动。最终通过以下措施解决: