//同步FIFO设计
//深度16 位宽16
module top
#(
parameter depth = 16 ,
parameter width = 16
)
(
input clk ,
input rst_n ,
input wr_en ,
input [width-1:0] data_in ,
input rd_en ,
output [width-1:0] data_out ,
output full ,
output empty
);
reg [width-1:0] mem [depth:0] ;
reg [4:0] waddr ;
reg [4:0] raddr ;
reg [width-1:0] temp_rdata ;
//写指针
always@(posedge clk or negedge rst_n)
begin
if (!rst_n)
waddr <= 5'b0_0000;
else if (wr_en ==1'b1)
waddr <= waddr + 1'b1;
else
waddr <= waddr ;
end
//读指针
always@(posedge clk or negedge rst_n)
begin
if (!rst_n)
raddr <= 5'b0_0000;
else if (rd_en ==1'b1)
raddr <= raddr + 1'b1;
else
raddr <= raddr ;
end
//写数据
always@(posedge clk)
begin
mem[waddr] <= data_in;
end
//读数据 1 latency
assign data_out = temp_rdata;
always@(posedge clk or negedge rst_n)
begin
if (!rst_n)
temp_rdata <= {width{1'b0}};
else
temp_rdata <= mem[raddr];
end
//空信号判断
assign empty = (waddr == raddr) ? 1'b1 : 1'b0;
//满信号判断
assign full = ({~waddr[4],waddr[3:0]} == raddr) ? 1'b1 : 1'b0;
endmodule
//testbench
`timescale 1ns/1ns
module top_test();
reg clk ;
reg rst_n ;
reg wr_en ;
reg [15:0] data_in ;
reg rd_en ;
wire full ;
wire empty ;
wire [15:0] data_out;
top top_inst1(
.clk (clk ),
.rst_n (rst_n ),
.wr_en (wr_en ),
.data_in (data_in ),
.rd_en (rd_en ),
.data_out (data_out),
.full (full ),
.empty (empty )
);
initial
begin
clk = 1'b0;
rst_n = 1'b0;
wr_en = 1'b0;
rd_en = 1'b0;
data_in = 16'h0000;
repeat(5)@(posedge clk);
rst_n = 1'b1;
repeat(5)@(posedge clk);
drive_w();
repeat(5)@(posedge clk);
drive_r();
end
task drive_w;
integer i;
begin
for (i=0;i<16;i=i+1)
begin
wr_en <= 1'b1;
data_in <= i[15:0];
@(posedge clk);
wr_en <= 0;
end
end
endtask
task drive_r;
integer i;
begin
for (i=0;i<16;i=i+1)
begin
rd_en <= 1'b1;
@(posedge clk);
rd_en <= 1'b0;
end
end
endtask
always # 10 clk = ~clk;
endmodule