在FPGA中,数据进行跨时钟域传输时,会出现亚稳态的问题。跨时钟域也就是跨越了两个频率和相位不同的异步时钟域。为了解决亚稳态和由时钟不同步引起的其他问题,选用了FIFO。
本例中,选用了输入和输出为同一时钟来生成FIFO。生成FIFO后可在.veo文件中找到例化模版,如下图所示:
操作流程为:
Sources(1)→IP Sources(2)→Instantiation template(3)→.veo文件(4)。
然后新建测试文件并命名为top.v,在文件中进行实例化,实例化代码如下:
fifo_generator_0 your_instance_name (
.clk(!clk), // input wire clk
.srst(!rst), // 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(), // output wire full
.empty() // output wire empty
);
同时编写状态机对例化后的FIFO进行读写操作,代码如下所示:
always @(posedgerst or posedge clk)
begin
if(!rst)
begin
next_state <= ini;
j <= 0;
rd_en <= 1'b0;
wr_en <= 1'b0;
end
else
begin
case(next_state)
ini:
begin
j <= 0;
rd_en <= 1'b0;
if(wr_trig == 1'b1)
next_state <= wr_fifo;
end
wr_fifo:
begin
din <= data_in[j];
if(j == 15)
next_state <= ready;
else
begin
j <= j + 1;
wr_en <= 1'b1;
next_state <= wr_fifo;
end
end
ready:
begin
j <= 0;
wr_en <= 1'b0;
if(rd_trig == 1'b1)
next_state <= rd_fifo;
else
next_state <= ready;
end
rd_fifo:
begin
if(j == 15)
next_state <= ini;
else
begin
j <= j + 1;
rd_en <= 1'b1;
next_state <= rd_fifo;
end
end
endcase
end
end
在top.v中要对所用到的寄存器进行相应的初始化。创建相应的约束和仿真文件(主要用于模拟产生所需要的时钟信号和复位信号)。创建完成后进行综合和实现。没有错误的情况下进行FIFO仿真,如下图所示:
操作流程:
SIMULATION(1)→Run Simulation(2)→RunBehavioral Simulation(3)。
然后点击RUN按钮,进行适当的窗口调整可得到下图所示的图像界面: