util_axis_fifo: Add room and level outputs

Add a room output on the input side that reports how many free entries the
FIFO has and a level output on the output side that reports how many valid
entries are in the FIFO.

Note that the level output is only accurate if the output of the FIFO is not
registered, otherwise it might be off by one.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
main
Lars-Peter Clausen 2015-04-09 14:32:44 +02:00
parent ae4e7a0c37
commit 762fa3290b
4 changed files with 36 additions and 12 deletions

View File

@ -42,13 +42,15 @@ module fifo_address_gray (
input m_axis_ready,
output reg m_axis_valid,
output [C_ADDRESS_WIDTH-1:0] m_axis_raddr_next,
output reg [C_ADDRESS_WIDTH:0] m_axis_level,
input s_axis_aclk,
input s_axis_aresetn,
output reg s_axis_ready,
input s_axis_valid,
output reg s_axis_empty,
output [C_ADDRESS_WIDTH-1:0] s_axis_waddr
output [C_ADDRESS_WIDTH-1:0] s_axis_waddr,
output reg [C_ADDRESS_WIDTH:0] s_axis_room
);
parameter C_ADDRESS_WIDTH = 4;

View File

@ -43,13 +43,15 @@ module fifo_address_gray_pipelined (
output reg m_axis_valid,
output [C_ADDRESS_WIDTH-1:0] m_axis_raddr_next,
output [C_ADDRESS_WIDTH-1:0] m_axis_raddr,
output reg [C_ADDRESS_WIDTH:0] m_axis_level,
input s_axis_aclk,
input s_axis_aresetn,
output reg s_axis_ready,
input s_axis_valid,
output reg s_axis_empty,
output [C_ADDRESS_WIDTH-1:0] s_axis_waddr
output [C_ADDRESS_WIDTH-1:0] s_axis_waddr,
output reg [C_ADDRESS_WIDTH:0] s_axis_room
);
parameter C_ADDRESS_WIDTH = 4;
@ -127,19 +129,23 @@ begin
if (s_axis_aresetn == 1'b0) begin
s_axis_ready <= 1'b1;
s_axis_empty <= 1'b1;
s_axis_room <= 2**C_ADDRESS_WIDTH;
end else begin
s_axis_ready <= (_s_axis_raddr[C_ADDRESS_WIDTH] == _s_axis_waddr_next[C_ADDRESS_WIDTH] ||
_s_axis_raddr[C_ADDRESS_WIDTH-1:0] != _s_axis_waddr_next[C_ADDRESS_WIDTH-1:0]);
s_axis_empty <= _s_axis_raddr == _s_axis_waddr_next;
s_axis_room <= _s_axis_raddr - _s_axis_waddr_next + 2**C_ADDRESS_WIDTH;
end
end
always @(posedge m_axis_aclk)
begin
if (s_axis_aresetn == 1'b0)
if (s_axis_aresetn == 1'b0) begin
m_axis_valid <= 1'b0;
else begin
m_axis_level <= 'h00;
end else begin
m_axis_valid <= _m_axis_waddr != _m_axis_raddr_next;
m_axis_level <= _m_axis_waddr - _m_axis_raddr_next;
end
end

View File

@ -44,18 +44,24 @@ module fifo_address_sync (
output reg m_axis_valid,
output reg [C_ADDRESS_WIDTH-1:0] m_axis_raddr,
output reg [C_ADDRESS_WIDTH-1:0] m_axis_raddr_next,
output [C_ADDRESS_WIDTH:0] m_axis_level,
output reg s_axis_ready,
input s_axis_valid,
output reg s_axis_empty,
output reg [C_ADDRESS_WIDTH-1:0] s_axis_waddr
output reg [C_ADDRESS_WIDTH-1:0] s_axis_waddr,
output [C_ADDRESS_WIDTH:0] s_axis_room
);
parameter C_ADDRESS_WIDTH = 4;
reg [C_ADDRESS_WIDTH:0] level;
reg [C_ADDRESS_WIDTH:0] room = 2**C_ADDRESS_WIDTH;
reg [C_ADDRESS_WIDTH:0] level = 'h00;
reg [C_ADDRESS_WIDTH:0] level_next;
assign s_axis_room = room;
assign m_axis_level = level;
wire read = m_axis_ready & m_axis_valid;
wire write = s_axis_ready & s_axis_valid;
@ -94,8 +100,12 @@ begin
if (resetn == 1'b0) begin
m_axis_valid <= 1'b0;
s_axis_ready <= 1'b0;
level <= 'h00;
room <= 2**C_ADDRESS_WIDTH;
s_axis_empty <= 'h00;
end else begin
level <= level_next;
room <= 2**C_ADDRESS_WIDTH - level_next;
m_axis_valid <= level_next != 0;
s_axis_ready <= level_next != 2**C_ADDRESS_WIDTH;
s_axis_empty <= level_next == 0;

View File

@ -42,13 +42,15 @@ module util_axis_fifo (
input m_axis_ready,
output m_axis_valid,
output [C_DATA_WIDTH-1:0] m_axis_data,
output [C_ADDRESS_WIDTH:0] m_axis_level,
input s_axis_aclk,
input s_axis_aresetn,
output s_axis_ready,
input s_axis_valid,
input [C_DATA_WIDTH-1:0] s_axis_data,
output s_axis_empty
output s_axis_empty,
output [C_ADDRESS_WIDTH:0] s_axis_room
);
parameter C_DATA_WIDTH = 64;
@ -86,8 +88,10 @@ sync_bits #(
);
assign m_axis_valid = m_axis_raddr != m_axis_waddr;
assign m_axis_level = m_axis_valid;
assign s_axis_ready = s_axis_raddr == s_axis_waddr;
assign s_axis_empty = s_axis_raddr == s_axis_waddr;
assign s_axis_empty = s_axis_ready;
assign s_axis_room = s_axis_ready;
always @(posedge s_axis_aclk) begin
if (s_axis_ready)
@ -131,17 +135,18 @@ fifo_address_gray_pipelined #(
) i_address_gray (
.m_axis_aclk(m_axis_aclk),
.m_axis_aresetn(m_axis_aresetn),
.m_axis_ready(_m_axis_ready),
.m_axis_valid(_m_axis_valid),
.m_axis_raddr(m_axis_raddr),
.m_axis_level(m_axis_level),
.s_axis_aclk(s_axis_aclk),
.s_axis_aresetn(s_axis_aresetn),
.s_axis_ready(s_axis_ready),
.s_axis_valid(s_axis_valid),
.s_axis_empty(s_axis_empty),
.s_axis_waddr(s_axis_waddr)
.s_axis_waddr(s_axis_waddr),
.s_axis_room(s_axis_room)
);
end else begin
@ -151,15 +156,16 @@ fifo_address_sync #(
) i_address_sync (
.clk(m_axis_aclk),
.resetn(m_axis_aresetn),
.m_axis_ready(_m_axis_ready),
.m_axis_valid(_m_axis_valid),
.m_axis_raddr(m_axis_raddr),
.m_axis_level(m_axis_level),
.s_axis_ready(s_axis_ready),
.s_axis_valid(s_axis_valid),
.s_axis_empty(s_axis_empty),
.s_axis_waddr(s_axis_waddr)
.s_axis_waddr(s_axis_waddr),
.s_axis_room(s_axis_room)
);
end