Line 33... |
Line 33... |
//
|
//
|
//
|
//
|
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
//
|
//
|
//
|
//
|
|
`default_nettype none
|
|
//
|
module ufifo(i_clk, i_rst, i_wr, i_data, o_empty_n, i_rd, o_data, o_status, o_err);
|
module ufifo(i_clk, i_rst, i_wr, i_data, o_empty_n, i_rd, o_data, o_status, o_err);
|
parameter BW=8; // Byte/data width
|
parameter BW=8; // Byte/data width
|
parameter [3:0] LGFLEN=4;
|
parameter [3:0] LGFLEN=4;
|
parameter RXFIFO=1'b0;
|
parameter RXFIFO=1'b0;
|
input i_clk, i_rst;
|
input wire i_clk, i_rst;
|
input i_wr;
|
input wire i_wr;
|
input [(BW-1):0] i_data;
|
input wire [(BW-1):0] i_data;
|
output wire o_empty_n; // True if something is in FIFO
|
output wire o_empty_n; // True if something is in FIFO
|
input i_rd;
|
input wire i_rd;
|
output wire [(BW-1):0] o_data;
|
output wire [(BW-1):0] o_data;
|
output wire [15:0] o_status;
|
output wire [15:0] o_status;
|
output wire o_err;
|
output wire o_err;
|
|
|
localparam FLEN=(1<<LGFLEN);
|
localparam FLEN=(1<<LGFLEN);
|
Line 65... |
Line 67... |
if (i_rst)
|
if (i_rst)
|
will_overflow <= 1'b0;
|
will_overflow <= 1'b0;
|
else if (i_rd)
|
else if (i_rd)
|
will_overflow <= (will_overflow)&&(i_wr);
|
will_overflow <= (will_overflow)&&(i_wr);
|
else if (i_wr)
|
else if (i_wr)
|
will_overflow <= (w_first_plus_two == r_last);
|
will_overflow <= (will_overflow)||(w_first_plus_two == r_last);
|
else if (w_first_plus_one == r_last)
|
else if (w_first_plus_one == r_last)
|
will_overflow <= 1'b1;
|
will_overflow <= 1'b1;
|
|
|
// Write
|
// Write
|
reg r_ovfl;
|
reg r_ovfl;
|
Line 109... |
Line 111... |
if (i_rst)
|
if (i_rst)
|
will_underflow <= 1'b1;
|
will_underflow <= 1'b1;
|
else if (i_wr)
|
else if (i_wr)
|
will_underflow <= (will_underflow)&&(i_rd);
|
will_underflow <= (will_underflow)&&(i_rd);
|
else if (i_rd)
|
else if (i_rd)
|
will_underflow <= (w_last_plus_one == r_first);
|
will_underflow <= (will_underflow)||(w_last_plus_one == r_first);
|
else
|
else
|
will_underflow <= (r_last == r_first);
|
will_underflow <= (r_last == r_first);
|
|
|
//
|
//
|
// Don't report FIFO underflow errors. These'll be caught elsewhere
|
// Don't report FIFO underflow errors. These'll be caught elsewhere
|
Line 141... |
Line 143... |
// o_data <= fifo[r_last+1];
|
// o_data <= fifo[r_last+1];
|
end
|
end
|
// else r_unfl <= 1'b1;
|
// else r_unfl <= 1'b1;
|
end
|
end
|
|
|
reg [7:0] fifo_here, fifo_next, r_data;
|
reg [(BW-1):0] fifo_here, fifo_next, r_data;
|
always @(posedge i_clk)
|
always @(posedge i_clk)
|
fifo_here <= fifo[r_last];
|
fifo_here <= fifo[r_last];
|
always @(posedge i_clk)
|
always @(posedge i_clk)
|
fifo_next <= fifo[r_next];
|
fifo_next <= fifo[r_next];
|
always @(posedge i_clk)
|
always @(posedge i_clk)
|
Line 170... |
Line 172... |
reg r_empty_n;
|
reg r_empty_n;
|
initial r_empty_n = 1'b0;
|
initial r_empty_n = 1'b0;
|
always @(posedge i_clk)
|
always @(posedge i_clk)
|
if (i_rst)
|
if (i_rst)
|
r_empty_n <= 1'b0;
|
r_empty_n <= 1'b0;
|
else case({i_wr, i_rd})
|
else casez({i_wr, i_rd, will_underflow})
|
2'b00: r_empty_n <= (r_first != r_last);
|
3'b00?: r_empty_n <= (r_first != r_last);
|
2'b11: r_empty_n <= (r_first != r_last);
|
3'b11?: r_empty_n <= (r_first != r_last);
|
2'b10: r_empty_n <= 1'b1;
|
3'b10?: r_empty_n <= 1'b1;
|
2'b01: r_empty_n <= (r_first != w_last_plus_one);
|
3'b010: r_empty_n <= (r_first != w_last_plus_one);
|
|
// 3'b001: r_empty_n <= 1'b0;
|
|
default: begin end
|
endcase
|
endcase
|
|
|
wire w_full_n;
|
wire w_full_n;
|
assign w_full_n = will_overflow;
|
assign w_full_n = will_overflow;
|
|
|
Line 188... |
Line 192... |
// the FIFO count that matters is the number of empty positions that
|
// the FIFO count that matters is the number of empty positions that
|
// can still be filled before the FIFO is full.
|
// can still be filled before the FIFO is full.
|
//
|
//
|
// Adjust for these differences here.
|
// Adjust for these differences here.
|
reg [(LGFLEN-1):0] r_fill;
|
reg [(LGFLEN-1):0] r_fill;
|
|
initial r_fill = 0;
|
always @(posedge i_clk)
|
always @(posedge i_clk)
|
if (RXFIFO!=0) begin
|
if (RXFIFO!=0) begin
|
// Calculate the number of elements in our FIFO
|
// Calculate the number of elements in our FIFO
|
//
|
//
|
// Although used for receive, this is actually the more
|
// Although used for receive, this is actually the more
|
// generic answer--should you wish to use the FIFO in
|
// generic answer--should you wish to use the FIFO in
|
// another context.
|
// another context.
|
if (i_rst)
|
if (i_rst)
|
r_fill <= 0;
|
r_fill <= 0;
|
else case({i_wr, i_rd})
|
else case({(i_wr)&&(!will_overflow), (i_rd)&&(!will_underflow)})
|
2'b01: r_fill <= r_first - r_next;
|
2'b01: r_fill <= r_first - r_next;
|
2'b10: r_fill <= r_first - r_last + 1'b1;
|
2'b10: r_fill <= r_first - r_last + 1'b1;
|
default: r_fill <= r_first - r_last;
|
default: r_fill <= r_first - r_last;
|
endcase
|
endcase
|
end else begin
|
end else begin
|
// Calculate the number of elements that are empty and
|
// Calculate the number of elements that are empty and
|
// can be filled within our FIFO
|
// can be filled within our FIFO. Hence, this is really
|
|
// not the fill, but (SIZE-1)-fill.
|
if (i_rst)
|
if (i_rst)
|
r_fill <= { (LGFLEN){1'b1} };
|
r_fill <= { (LGFLEN){1'b1} };
|
else case({i_wr, i_rd})
|
else case({i_wr, i_rd})
|
2'b01: r_fill <= r_last - r_first;
|
2'b01: r_fill <= r_last - r_first;
|
2'b10: r_fill <= r_last - w_first_plus_two;
|
2'b10: r_fill <= r_last - w_first_plus_two;
|