同步FIFO
![在这里插入图片描述](https://img-blog.csdnimg.cn/3140505f9bab45afb301e610de1454d9.png#pic_center)
- RAM:双端口RAM;
- 空满信号产生:通过比较读写地址指针来产生空满信号;
module sync_fifo #( parameter WIDTH = 8,
parameter DEPTH = 16)(
input clk,
input rst_n,
input winc,
input rinc,
input wdata,
output rdata,
output wfull,
output rempty
);
localparam ADDR = $clog2(DEPTH);
reg[ADDR:0] wptr;
reg[ADDR:0] rptr;
always@(posedge clk, negedge rst_n)begin
if(!rst_n)begin
wptr <= 'b0;
end
else if(winc & ~wfull)begin
wptr <= wptr +1'b1;
end
end
always@(posedge clk, negedge rst_n)begin
if(!rst_n)begin
rptr <= 'b0;
end
else if(rinc & ~rempty)begin
rptr <= rptr + 1'b1;
end
end
assign wfull = {~wptr[ADDR], wptr[ADDR-1:0]}==rptr;
assign rempty = wptr==rptr;
dual_ram #(.WIDTH(WIDTH),
.DEPTH(DEPTH))
ram(.wclk(clk),
.rclk(clk),
.waddr(wptr[ADDR-1:0]),
.raddr(rptr[ADDR-1:0]),
.wen(winc & ~wfull),
.ren(rinc & ~rempty),
.wdata(wdata),
.rdata(rdata)
);
endmodule
module dual_ram #(parameter WIDTH = 8,
parameter DEPTH = 16)(
input wclk,
input rclk,
input [$clog2(DEPTH)-1:0]waddr,
input [$clog2(DEPTH)-1:0]raddr,
input wen,
input ren,
input [WIDTH-1:0]wdata,
output reg [WIDTH-1:0]rdata
);
reg[WIDTH-1:0] ram[0:DEPTH-1];
always@(posedge wclk)begin
if(wen)
ram[waddr] <= wdata;
end
always@(posedge rclk)begin
if(ren)
rdata <= ram[raddr];
end
endmodule
![在这里插入图片描述](https://img-blog.csdnimg.cn/284a5904ebb04624b80abbc5f2ac94d5.png#pic_center)