module fifo#(parameter fifo_depth = 8,
addr_width = 3,
data_width = 16)
(input clk,
input rst_n,
input [15:0] data_in,
output reg [15:0] data_out,
input rd_en,
input wr_en,
output reg empty,
output reg full);
reg [15:0] mem [7:0];
reg [3:0] rd_addr_ptr;
reg [3:0] wr_addr_ptr;
wire [2:0] rd_addr;
wire [2:0] wr_addr;
assign rd_addr = rd_addr_ptr[2:0];
assign wr_addr = wr_addr_ptr[2:0];
assign empty = wr_addr_ptr == rd_addr_ptr;
assign full = {~wr_addr_ptr[3],wr_addr_ptr[2:0]} == rd_addr_ptr;
// 读写指针
always@(posedge clk or negedge rst_n) begin
if(!rst_n) begin
wr_addr <= h’0;
end
else if (wr_en & ~full)
wr_addr <= wr_addr + 1’b1;
end
always@(posedge clk or negedge rst_n) begin
if(!rst_n) begin
rd_addr <= h’0;
end
else if (rd_en & ~empty)
rd_addr <= rd_addr + 1’b1;
end
//读写数据
always@(posedge clk or negedge rst_n) begin
if(!rst_n) begin
data_out <= h’0;
end
else if(rd_en & ~empty)
data_out <= mem[rd_addr];
end
always@(posedge clk or negedge rst_n) begin
if(!rst_n) begin
mem[wr_addr] <= h’0;
end
else if(wr_en & ~full)
mem[wr_addr] <= data_in;
end
endmodule
module FIFO_sync(
clk,
rst,
w_en,
r_en,
data_in,
data_out,
count,
full,
empty
);
parameter FIFO_data_size=16,
FIFO_addr_size=8;
input clk,rst;
input w_en,r_en;
input[FIFO_data_size-1:0] data_in;
output[FIFO_data_size-1:0] data_out;
output full,empty;
output[FIFO_addr_size:0]count;
reg [FIFO_data_size-1:0] data_out;
reg [FIFO_addr_size:0]count;
reg [FIFO_addr_size-1:0]w_addr,r_addr;
reg [FIFO_data_size-1:0]mem[{FIFO_addr_size{1'b1}}:0];
integer i;
//memory的初始化以及写操作
always@(posedge clk or negedge rst)
begin
if(!rst)
begin
w_addr<=0;
for(i=0;i<={FIFO_addr_size{1'b1}};i=i+1)
mem[i]<={FIFO_data_size{1'b0}};
end
else if(w_en&(~full))
begin
mem[w_addr]<=data_in;
w_addr<=w_addr+1;
end
end
//读操作
always@(posedge clk or negedge rst)
begin
if(!rst)
begin
data_out<={(FIFO_data_size-1){1'b0}};
r_addr<=0;
end
else if(r_en&(~empty))
begin
data_out<=mem[r_addr];
r_addr<=r_addr+1;
end
end
//count产生空满标志符
always@(posedge clk or negedge rst)
begin
if(!rst)
count<=0;
else if(((w_en)&(~full))&(~((r_en)&(~empty))))
count<=count+1;
else if(((r_en)&(~empty))&(~((w_en)&(~full))))
count<=count-1;
end
assign empty=(count==0);
assign full=(count=={FIFO_addr_size{1'b1}}+1);
endmodule