102 lines
2.0 KiB
Verilog
102 lines
2.0 KiB
Verilog
`timescale 1ns/1ps
|
|
module sync_fifo #(
|
|
parameter W = 8
|
|
)
|
|
(
|
|
input clk,
|
|
input reset_n,
|
|
input rd_en,
|
|
output [W-1 : 0] rd_data,
|
|
input wr_en,
|
|
input [W-1 : 0] wr_data,
|
|
output reg full,
|
|
output reg empty
|
|
);
|
|
|
|
parameter D = 4;
|
|
|
|
parameter AW = (D == 4) ? 2 :
|
|
(D == 8) ? 3 :
|
|
(D == 16) ? 4 :
|
|
(D == 32) ? 5 :
|
|
(D == 64) ? 6 :
|
|
(D == 128) ? 7 :
|
|
(D == 256) ? 8 : 0;
|
|
|
|
// synopsys translate_off
|
|
initial begin
|
|
if (AW == 0) begin
|
|
$display ("%m : ERROR!!! Fifo depth %d not in range 4 to 256", D);
|
|
end // if (AW == 0)
|
|
end // initial begin
|
|
|
|
// synopsys translate_on
|
|
|
|
reg [W-1 : 0] mem[D-1 : 0];
|
|
reg [AW-1 : 0] rd_ptr, wr_ptr;
|
|
|
|
always @ (posedge clk or negedge reset_n)
|
|
if (reset_n == 1'b0) begin
|
|
wr_ptr <= {AW{1'b0}} ;
|
|
end
|
|
else begin
|
|
if (wr_en & !full) begin
|
|
wr_ptr <= wr_ptr + 1'b1 ;
|
|
end
|
|
end
|
|
|
|
always @ (posedge clk or negedge reset_n)
|
|
if (reset_n == 1'b0) begin
|
|
rd_ptr <= {AW{1'b0}} ;
|
|
end
|
|
else begin
|
|
if (rd_en & !empty) begin
|
|
rd_ptr <= rd_ptr + 1'b1 ;
|
|
end
|
|
end
|
|
|
|
|
|
always @ (posedge clk or negedge reset_n)
|
|
if (reset_n == 1'b0) begin
|
|
empty <= 1'b1 ;
|
|
end
|
|
else begin
|
|
empty <= (((wr_ptr - rd_ptr) == {{(AW-1){1'b0}}, 1'b1}) & rd_en & ~wr_en) ? 1'b1 :
|
|
((wr_ptr == rd_ptr) & ~rd_en & wr_en) ? 1'b0 : empty ;
|
|
end
|
|
|
|
always @ (posedge clk or negedge reset_n)
|
|
if (reset_n == 1'b0) begin
|
|
full <= 1'b0 ;
|
|
end
|
|
else begin
|
|
full <= (((wr_ptr - rd_ptr) == {{(AW-1){1'b1}}, 1'b0}) & ~rd_en & wr_en) ? 1'b1 :
|
|
(((wr_ptr - rd_ptr) == {AW{1'b1}}) & rd_en & ~wr_en) ? 1'b0 : full ;
|
|
end
|
|
|
|
always @ (posedge clk)
|
|
if (wr_en)
|
|
mem[wr_ptr] <= wr_data;
|
|
|
|
assign rd_data = mem[rd_ptr];
|
|
|
|
|
|
// synopsys translate_off
|
|
always @(posedge clk) begin
|
|
if (wr_en && full) begin
|
|
$display("%m : Error! sfifo overflow!");
|
|
end
|
|
end
|
|
|
|
always @(posedge clk) begin
|
|
if (rd_en && empty) begin
|
|
$display("%m : error! sfifo underflow!");
|
|
end
|
|
end
|
|
// synopsys translate_on
|
|
//---------------------------------------
|
|
|
|
endmodule
|
|
|
|
|