| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869 |
- module sync_fifo #(parameter WIDTH = 8, DEPTH = 4, SHOWAEAD = 1) (
- input clk,
- input rstn,
- input wren,
- input rden,
- input [WIDTH-1:0] din,
- output [WIDTH-1:0] dout,
- output full,
- output empty
- );
- parameter FIFO_MIN = DEPTH > 1 ? 0 : 1;
- parameter FIFO_MAX = DEPTH > 1 ? DEPTH - 1 : 1;
- reg [WIDTH-1:0] fifo[FIFO_MAX:FIFO_MIN];
- reg [WIDTH-1:0] fifo_out;
- parameter ADDR = $clog2(DEPTH);
- reg [ADDR:0] counter;
- wire [WIDTH-1:0] fifo_head;
- wire wrreq = wren && !full;
- wire rdreq = rden && !empty;
- generate
- if (DEPTH > 1)
- assign fifo_head = fifo[counter[ADDR-1:0]];
- else
- assign fifo_head = fifo[1];
- endgenerate
- always @(posedge clk or negedge rstn) begin
- if (!rstn) begin
- counter <= 0;
- end else if (wrreq && !rdreq) begin
- counter <= counter + 1;
- end else if (rdreq && !wrreq) begin
- counter <= counter - 1;
- end
- end
- integer i;
- always @(posedge clk) begin
- if (wrreq) begin
- for (i = FIFO_MIN; i <= FIFO_MAX; i = i + 1) begin
- if (i == 0) begin
- fifo[i] <= fifo[FIFO_MAX];
- end else if (i == 1) begin
- fifo[i] <= din;
- end else begin
- fifo[i] <= fifo[i - 1];
- end
- end
- end
- end
- always @(posedge clk or negedge rstn) begin
- if (!rstn) begin
- fifo_out <= 0;
- end else if (rdreq) begin
- fifo_out <= fifo_head;
- end
- end
- assign dout = SHOWAEAD ? fifo_head : fifo_out;
- assign full = counter[ADDR];
- assign empty = counter == 0;
- endmodule
|