同步FIFO,自查自用
module sync_fifo
#(
parameter WIDTH=16,
parameter DEPTH=16
)
(
input clk,
input rstn
input wr_en,
input rd_en,
input [WIDTH-1:0] din,
output [DEPTH-1:0] dout,
output full,
output empty
)
reg[WIDTH-1:0] mem [DEPTH-1:0];
reg[$clog2(DEPTH)-1:0] wr_addr,rd_addr;
reg[$clog2(DEPTH):0] cnt;
wire wr_op,rd_op;
assign wr_op = (wr_en&(!full));
assign rd_op = (rd_en&(!empty));
always @ (posedge clk or negedge rstn)begin
if(!rstn)
wr_addr<='b0;
else if (wr_op)begin
mem[wr_addr] <= din;
wr_addr <= wr_addr + 1'b1;
end
end
always @ (posedge clk or negedge rstn)begin
if(!rstn)
rd_addr <= 'b0;
else if (rd_op)begin
dout <= mem[rd_addr];
rd_addr <= rd_addr + 1'b1;
end
end
always @ (posedge clk or negedge rstn)begin
if(!rstn)
cnt <= 'b0;
else begin
case({wr_op,rd_op})
2'b00: cnt <= cnt;
2'b01: cnt <= cnt - 1'b1;
2'b10: cnt <= cnt + 1'b1;
2'b11: cnt <= cnt;
default: null;
endcase
end
end
assign full = (cnt == DEPTH);
assign empty = (cnt == 0);
endmodule