1、fifo是一种先进先出的寄存方式,采用一个双端口的ram,一个端口用于读,另外一个端口用于写。fifo没有地址,采用先进先出。
2、fifo读写测试主要包括四个部分:一个伪双端口ram、一个控制空和满标志的计数器、写地址、读地址。相应verilog如下。并且编写tb测试代码。
module sameCLK_fifo(
input clk,
input rst_n,
input re_en,
input wr_en,
input [7:0] data_in,
output wire [7:0] data_out
);
reg empty; //flag
reg full; //flag
reg [3:0] count; //decide flag
reg [3:0] wr_addr;
reg [3:0] re_addr;
always@(posedge clk or negedge rst_n)begin //decide wr_addr
if(!rst_n)
wr_addr<=4'd0;
else if(wr_en==1'b1)begin
if(full==1'b0)
wr_addr<=wr_addr+1'b1;
else wr_addr<=wr_addr;
end
else wr_addr<=wr_addr;
end
always@(posedge clk or negedge rst_n)begin //decide re_addr
if(!rst_n)
re_addr<=4'd0;
else if(re_en==1'b1)begin
if(empty==1'b0)
re_addr<=re_addr+1'b1;
else re_addr<=re_addr;
end
else re_addr<=re_addr;
end
always@(posedge clk or negedge rst_n)begin //according en to decide count
if(!rst_n)
count<=4'd0;
else if((wr_en==1'b1) & (re_en==1'b1))
count<=count;
else if((wr_en==1'b0) & (re_en==1'b0))
count<=count;
else if((wr_en==1'b1) & (re_en==1'b0))begin
if(count<4'd15)begin
count<=count+1'b1;
end
else count<=count;
end
else if((wr_en==1'b0) & (re_en==1'b1))begin
if(count>4'd0)begin
count<=count-1'b1;
end
else count<=count;
end
end
always@(count)begin
if(count==4'd0)
empty<=1'b1;
else
empty<=1'b0;
end
always@(count)begin
if(count==4'd15)
full<=1'b1;
else
full<=1'b0;
end
ram u_ram(
.clk (clk),
.wr_en (wr_en),
.re_en (re_en),
.wr_addr (wr_addr),
.re_addr (re_addr),
.data (data_in),
.q (data_out)
);
endmodule
module ram(
input clk,
input wr_en,
input re_en,
input [3:0]wr_addr,
input [3:0]re_addr,
input [7:0] data,
output reg[7:0] q
);
reg [7:0] ram[15:0];
always@(posedge clk)begin
if(wr_en)
ram[wr_addr]<=data;
end
always@(posedge clk)begin
if(re_en)
q<=ram[re_addr];
else
q<=8'hxx;
end
endmodule
`timescale 1ns/1ps
module tb();
reg clk;
reg rst_n;
reg [7:0] data_in;
wire [7:0] data_out;
reg wr_en;
reg re_en;
initial begin
clk=1'b0;
rst_n=1'b0;
re_en=1'b0;
wr_en=1'b0;
data_in=8'd0;
#50
rst_n=1'b1;
wr_en=1'b1;
#200
re_en=1'b1;
#200
wr_en=1'b0;
#200
re_en=1'b0;
end
always #10 clk=~clk;
always #20 data_in<=data_in+1'b1;
sameCLK_fifo u_sameCLk_fifo(
.clk (clk),
.rst_n (rst_n),
.re_en (re_en),
.wr_en (wr_en),
.data_in (data_in),
.data_out (data_out)
);
endmodule
3、综合出来的电路如下
4、测试结果如下