mirror of
https://github.com/vortexgpgpu/vortex.git
synced 2025-04-23 21:39:10 -04:00
fifo refactoring
This commit is contained in:
parent
bcf7d9f960
commit
370daf1025
2 changed files with 216 additions and 263 deletions
|
@ -36,225 +36,134 @@ module VX_fifo_queue #(
|
|||
output wire [SIZEW-1:0] size
|
||||
);
|
||||
|
||||
localparam ADDRW = `CLOG2(DEPTH);
|
||||
|
||||
`STATIC_ASSERT(ALM_FULL > 0, ("alm_full must be greater than 0!"))
|
||||
`STATIC_ASSERT(ALM_FULL < DEPTH, ("alm_full must be smaller than size!"))
|
||||
`STATIC_ASSERT(ALM_EMPTY > 0, ("alm_empty must be greater than 0!"))
|
||||
`STATIC_ASSERT(ALM_EMPTY < DEPTH, ("alm_empty must be smaller than size!"))
|
||||
`STATIC_ASSERT(`IS_POW2(DEPTH), ("size must be a power of 2!"))
|
||||
|
||||
VX_pending_size #(
|
||||
.SIZE (DEPTH),
|
||||
.ALM_EMPTY (ALM_EMPTY),
|
||||
.ALM_FULL (ALM_FULL)
|
||||
) pending_size (
|
||||
.clk (clk),
|
||||
.reset (reset),
|
||||
.incr (push),
|
||||
.decr (pop),
|
||||
.empty (empty),
|
||||
.full (full),
|
||||
.alm_empty(alm_empty),
|
||||
.alm_full(alm_full),
|
||||
.size (size)
|
||||
);
|
||||
|
||||
if (DEPTH == 1) begin
|
||||
|
||||
reg [DATAW-1:0] head_r;
|
||||
reg size_r;
|
||||
|
||||
always @(posedge clk) begin
|
||||
if (reset) begin
|
||||
head_r <= '0;
|
||||
size_r <= '0;
|
||||
end else begin
|
||||
`ASSERT(~push || ~full, ("runtime error: writing to a full queue"));
|
||||
`ASSERT(~pop || ~empty, ("runtime error: reading an empty queue"));
|
||||
if (push) begin
|
||||
if (~pop) begin
|
||||
size_r <= 1;
|
||||
end
|
||||
end else if (pop) begin
|
||||
size_r <= '0;
|
||||
end
|
||||
if (push) begin
|
||||
head_r <= data_in;
|
||||
end
|
||||
if (push) begin
|
||||
head_r <= data_in;
|
||||
end
|
||||
end
|
||||
|
||||
assign data_out = head_r;
|
||||
assign empty = (size_r == 0);
|
||||
assign alm_empty = 1'b1;
|
||||
assign full = (size_r != 0);
|
||||
assign alm_full = 1'b1;
|
||||
assign size = size_r;
|
||||
assign data_out = head_r;
|
||||
|
||||
end else begin
|
||||
|
||||
reg empty_r, alm_empty_r;
|
||||
reg full_r, alm_full_r;
|
||||
reg [ADDRW-1:0] used_r;
|
||||
wire [ADDRW-1:0] used_n;
|
||||
localparam ADDRW = `CLOG2(DEPTH);
|
||||
|
||||
always @(posedge clk) begin
|
||||
if (reset) begin
|
||||
empty_r <= 1;
|
||||
alm_empty_r <= 1;
|
||||
full_r <= 0;
|
||||
alm_full_r <= 0;
|
||||
used_r <= '0;
|
||||
end else begin
|
||||
`ASSERT(~(push && ~pop) || ~full, ("runtime error: incrementing full queue"));
|
||||
`ASSERT(~(pop && ~push) || ~empty, ("runtime error: decrementing empty queue"));
|
||||
if (push) begin
|
||||
if (~pop) begin
|
||||
empty_r <= 0;
|
||||
if (used_r == ADDRW'(ALM_EMPTY))
|
||||
alm_empty_r <= 0;
|
||||
if (used_r == ADDRW'(DEPTH-1))
|
||||
full_r <= 1;
|
||||
if (used_r == ADDRW'(ALM_FULL-1))
|
||||
alm_full_r <= 1;
|
||||
end
|
||||
end else if (pop) begin
|
||||
full_r <= 0;
|
||||
if (used_r == ADDRW'(ALM_FULL))
|
||||
alm_full_r <= 0;
|
||||
if (used_r == ADDRW'(1))
|
||||
empty_r <= 1;
|
||||
if (used_r == ADDRW'(ALM_EMPTY+1))
|
||||
alm_empty_r <= 1;
|
||||
end
|
||||
used_r <= used_n;
|
||||
end
|
||||
end
|
||||
if (OUT_REG != 0) begin
|
||||
|
||||
if (DEPTH == 2 && LUTRAM == 0) begin
|
||||
wire [DATAW-1:0] dout;
|
||||
reg [DATAW-1:0] dout_r;
|
||||
reg [ADDRW-1:0] wr_ptr_r;
|
||||
reg [ADDRW-1:0] rd_ptr_r;
|
||||
reg [ADDRW-1:0] rd_ptr_n_r;
|
||||
|
||||
assign used_n = used_r ^ (push ^ pop);
|
||||
|
||||
if (0 == OUT_REG) begin
|
||||
|
||||
reg [1:0][DATAW-1:0] shift_reg;
|
||||
|
||||
always @(posedge clk) begin
|
||||
if (push) begin
|
||||
shift_reg[1] <= shift_reg[0];
|
||||
shift_reg[0] <= data_in;
|
||||
end
|
||||
end
|
||||
|
||||
assign data_out = shift_reg[!used_r[0]];
|
||||
|
||||
end else begin
|
||||
|
||||
reg [DATAW-1:0] data_out_r;
|
||||
reg [DATAW-1:0] buffer;
|
||||
|
||||
always @(posedge clk) begin
|
||||
if (push) begin
|
||||
buffer <= data_in;
|
||||
end
|
||||
if (push && (empty_r || (used_r && pop))) begin
|
||||
data_out_r <= data_in;
|
||||
end else if (pop) begin
|
||||
data_out_r <= buffer;
|
||||
end
|
||||
end
|
||||
|
||||
assign data_out = data_out_r;
|
||||
|
||||
end
|
||||
|
||||
end else begin
|
||||
|
||||
assign used_n = $signed(used_r) + ADDRW'($signed(2'(push) - 2'(pop)));
|
||||
|
||||
if (0 == OUT_REG) begin
|
||||
|
||||
reg [ADDRW-1:0] rd_ptr_r;
|
||||
reg [ADDRW-1:0] wr_ptr_r;
|
||||
|
||||
always @(posedge clk) begin
|
||||
if (reset) begin
|
||||
rd_ptr_r <= '0;
|
||||
wr_ptr_r <= '0;
|
||||
end else begin
|
||||
wr_ptr_r <= wr_ptr_r + ADDRW'(push);
|
||||
rd_ptr_r <= rd_ptr_r + ADDRW'(pop);
|
||||
end
|
||||
end
|
||||
|
||||
VX_dp_ram #(
|
||||
.DATAW (DATAW),
|
||||
.SIZE (DEPTH),
|
||||
.LUTRAM (LUTRAM)
|
||||
) dp_ram (
|
||||
.clk (clk),
|
||||
.reset (reset),
|
||||
.read (1'b1),
|
||||
.write (push),
|
||||
.wren (1'b1),
|
||||
.waddr (wr_ptr_r),
|
||||
.wdata (data_in),
|
||||
.raddr (rd_ptr_r),
|
||||
.rdata (data_out)
|
||||
);
|
||||
|
||||
end else begin
|
||||
|
||||
wire [DATAW-1:0] dout;
|
||||
reg [DATAW-1:0] dout_r;
|
||||
reg [ADDRW-1:0] wr_ptr_r;
|
||||
reg [ADDRW-1:0] rd_ptr_r;
|
||||
reg [ADDRW-1:0] rd_ptr_n_r;
|
||||
|
||||
always @(posedge clk) begin
|
||||
if (reset) begin
|
||||
wr_ptr_r <= '0;
|
||||
rd_ptr_r <= '0;
|
||||
rd_ptr_n_r <= 1;
|
||||
end else begin
|
||||
wr_ptr_r <= wr_ptr_r + ADDRW'(push);
|
||||
if (pop) begin
|
||||
rd_ptr_r <= rd_ptr_n_r;
|
||||
if (DEPTH > 2) begin
|
||||
rd_ptr_n_r <= rd_ptr_r + ADDRW'(2);
|
||||
end else begin // (DEPTH == 2);
|
||||
rd_ptr_n_r <= ~rd_ptr_n_r;
|
||||
end
|
||||
always @(posedge clk) begin
|
||||
if (reset) begin
|
||||
wr_ptr_r <= '0;
|
||||
rd_ptr_r <= '0;
|
||||
rd_ptr_n_r <= 1;
|
||||
end else begin
|
||||
wr_ptr_r <= wr_ptr_r + ADDRW'(push);
|
||||
if (pop) begin
|
||||
rd_ptr_r <= rd_ptr_n_r;
|
||||
if (DEPTH > 2) begin
|
||||
rd_ptr_n_r <= rd_ptr_r + ADDRW'(2);
|
||||
end else begin // (DEPTH == 2);
|
||||
rd_ptr_n_r <= ~rd_ptr_n_r;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
wire going_empty;
|
||||
if (ALM_EMPTY == 1) begin
|
||||
assign going_empty = alm_empty_r;
|
||||
end else begin
|
||||
assign going_empty = (used_r == ADDRW'(1));
|
||||
end
|
||||
|
||||
VX_dp_ram #(
|
||||
.DATAW (DATAW),
|
||||
.SIZE (DEPTH),
|
||||
.LUTRAM (LUTRAM)
|
||||
) dp_ram (
|
||||
.clk (clk),
|
||||
.reset (reset),
|
||||
.read (1'b1),
|
||||
.write (push),
|
||||
.wren (1'b1),
|
||||
.waddr (wr_ptr_r),
|
||||
.wdata (data_in),
|
||||
.raddr (rd_ptr_n_r),
|
||||
.rdata (dout)
|
||||
);
|
||||
|
||||
always @(posedge clk) begin
|
||||
if (push && (empty_r || (going_empty && pop))) begin
|
||||
dout_r <= data_in;
|
||||
end else if (pop) begin
|
||||
dout_r <= dout;
|
||||
end
|
||||
end
|
||||
|
||||
assign data_out = dout_r;
|
||||
end
|
||||
end
|
||||
|
||||
assign empty = empty_r;
|
||||
assign alm_empty = alm_empty_r;
|
||||
assign full = full_r;
|
||||
assign alm_full = alm_full_r;
|
||||
assign size = {full_r, used_r};
|
||||
VX_dp_ram #(
|
||||
.DATAW (DATAW),
|
||||
.SIZE (DEPTH),
|
||||
.LUTRAM (LUTRAM)
|
||||
) dp_ram (
|
||||
.clk (clk),
|
||||
.reset (reset),
|
||||
.read (1'b1),
|
||||
.write (push),
|
||||
.wren (1'b1),
|
||||
.waddr (wr_ptr_r),
|
||||
.wdata (data_in),
|
||||
.raddr (rd_ptr_n_r),
|
||||
.rdata (dout)
|
||||
);
|
||||
|
||||
wire going_empty = (ALM_EMPTY == 1) ? alm_empty : (size[ADDRW] == ADDRW'(1));
|
||||
|
||||
always @(posedge clk) begin
|
||||
if (push && (empty || (going_empty && pop))) begin
|
||||
dout_r <= data_in;
|
||||
end else if (pop) begin
|
||||
dout_r <= dout;
|
||||
end
|
||||
end
|
||||
|
||||
assign data_out = dout_r;
|
||||
|
||||
end else begin
|
||||
|
||||
reg [ADDRW-1:0] rd_ptr_r;
|
||||
reg [ADDRW-1:0] wr_ptr_r;
|
||||
|
||||
always @(posedge clk) begin
|
||||
if (reset) begin
|
||||
rd_ptr_r <= '0;
|
||||
wr_ptr_r <= '0;
|
||||
end else begin
|
||||
wr_ptr_r <= wr_ptr_r + ADDRW'(push);
|
||||
rd_ptr_r <= rd_ptr_r + ADDRW'(pop);
|
||||
end
|
||||
end
|
||||
|
||||
VX_dp_ram #(
|
||||
.DATAW (DATAW),
|
||||
.SIZE (DEPTH),
|
||||
.LUTRAM (LUTRAM)
|
||||
) dp_ram (
|
||||
.clk (clk),
|
||||
.reset (reset),
|
||||
.read (1'b1),
|
||||
.write (push),
|
||||
.wren (1'b1),
|
||||
.waddr (wr_ptr_r),
|
||||
.wdata (data_in),
|
||||
.raddr (rd_ptr_r),
|
||||
.rdata (data_out)
|
||||
);
|
||||
|
||||
end
|
||||
end
|
||||
|
||||
`RUNTIME_ASSERT(~(push && ~pop) || ~full, ("runtime error: incrementing full queue"));
|
||||
`RUNTIME_ASSERT(~(pop && ~push) || ~empty, ("runtime error: decrementing empty queue"));
|
||||
|
||||
endmodule
|
||||
`TRACING_ON
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
|
||||
`include "VX_platform.vh"
|
||||
|
||||
//`TRACING_OFF
|
||||
`TRACING_OFF
|
||||
module VX_pending_size #(
|
||||
parameter SIZE = 1,
|
||||
parameter INCRW = 1,
|
||||
|
@ -34,97 +34,141 @@ module VX_pending_size #(
|
|||
);
|
||||
`STATIC_ASSERT(INCRW <= SIZEW, ("invalid parameter: %d vs %d", INCRW, SIZEW))
|
||||
`STATIC_ASSERT(DECRW <= SIZEW, ("invalid parameter: %d vs %d", DECRW, SIZEW))
|
||||
localparam ADDRW = `LOG2UP(SIZE);
|
||||
|
||||
reg empty_r, alm_empty_r;
|
||||
reg full_r, alm_full_r;
|
||||
if (SIZE == 1) begin
|
||||
|
||||
if (INCRW != 1 || DECRW != 1) begin
|
||||
|
||||
reg [SIZEW-1:0] size_r;
|
||||
|
||||
wire [SIZEW-1:0] size_n = size_r + SIZEW'(incr) - SIZEW'(decr);
|
||||
reg size_r;
|
||||
|
||||
always @(posedge clk) begin
|
||||
if (reset) begin
|
||||
empty_r <= 1;
|
||||
alm_empty_r <= 1;
|
||||
alm_full_r <= 0;
|
||||
full_r <= 0;
|
||||
size_r <= '0;
|
||||
size_r <= '0;
|
||||
end else begin
|
||||
`ASSERT((SIZEW'(incr) >= SIZEW'(decr)) || (size_n >= size_r), ("runtime error: counter overflow"));
|
||||
`ASSERT((SIZEW'(incr) <= SIZEW'(decr)) || (size_n <= size_r), ("runtime error: counter underflow"));
|
||||
size_r <= size_n;
|
||||
empty_r <= (size_n == SIZEW'(0));
|
||||
alm_empty_r <= (size_n == SIZEW'(ALM_EMPTY));
|
||||
full_r <= (size_n == SIZEW'(SIZE));
|
||||
alm_full_r <= (size_n == SIZEW'(ALM_FULL));
|
||||
if (incr) begin
|
||||
if (~decr) begin
|
||||
size_r <= 1;
|
||||
end
|
||||
end else if (decr) begin
|
||||
size_r <= '0;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
assign size = size_r;
|
||||
assign empty = (size_r == 0);
|
||||
assign full = (size_r != 0);
|
||||
assign alm_empty = 1'b1;
|
||||
assign alm_full = 1'b1;
|
||||
assign size = size_r;
|
||||
|
||||
end else begin
|
||||
|
||||
reg [ADDRW-1:0] used_r;
|
||||
wire [ADDRW-1:0] used_n;
|
||||
logic empty_r, alm_empty_r;
|
||||
logic full_r, alm_full_r;
|
||||
|
||||
always @(posedge clk) begin
|
||||
if (reset) begin
|
||||
empty_r <= 1;
|
||||
alm_empty_r <= 1;
|
||||
full_r <= 0;
|
||||
alm_full_r <= 0;
|
||||
used_r <= '0;
|
||||
end else begin
|
||||
`ASSERT(~(incr && ~decr) || ~full, ("runtime error: counter overflow"));
|
||||
`ASSERT(~(decr && ~incr) || ~empty, ("runtime error: counter underflow"));
|
||||
if (incr) begin
|
||||
if (~decr) begin
|
||||
empty_r <= 0;
|
||||
if (used_r == ADDRW'(ALM_EMPTY))
|
||||
alm_empty_r <= 0;
|
||||
if (used_r == ADDRW'(SIZE-1))
|
||||
full_r <= 1;
|
||||
if (used_r == ADDRW'(ALM_FULL-1))
|
||||
alm_full_r <= 1;
|
||||
end
|
||||
end else if (decr) begin
|
||||
if (used_r == ADDRW'(1))
|
||||
empty_r <= 1;
|
||||
if (used_r == ADDRW'(ALM_EMPTY+1))
|
||||
alm_empty_r <= 1;
|
||||
full_r <= 0;
|
||||
if (used_r == ADDRW'(ALM_FULL))
|
||||
alm_full_r <= 0;
|
||||
if (INCRW != 1 || DECRW != 1) begin
|
||||
|
||||
localparam SUBW = `MIN(SIZEW, `MAX(INCRW, DECRW)+1);
|
||||
|
||||
logic [SIZEW-1:0] size_n, size_r;
|
||||
|
||||
assign size_n = $signed(size_r) + SIZEW'($signed(SUBW'(incr) - SUBW'(decr)));
|
||||
|
||||
always @(posedge clk) begin
|
||||
if (reset) begin
|
||||
empty_r <= 1;
|
||||
full_r <= 0;
|
||||
alm_empty_r <= 1;
|
||||
alm_full_r <= 0;
|
||||
size_r <= '0;
|
||||
end else begin
|
||||
`ASSERT((SIZEW'(incr) >= SIZEW'(decr)) || (size_n >= size_r), ("runtime error: counter overflow"));
|
||||
`ASSERT((SIZEW'(incr) <= SIZEW'(decr)) || (size_n <= size_r), ("runtime error: counter underflow"));
|
||||
empty_r <= (size_n == SIZEW'(0));
|
||||
full_r <= (size_n == SIZEW'(SIZE));
|
||||
alm_empty_r <= (size_n <= SIZEW'(ALM_EMPTY));
|
||||
alm_full_r <= (size_n >= SIZEW'(ALM_FULL));
|
||||
size_r <= size_n;
|
||||
end
|
||||
used_r <= used_n;
|
||||
end
|
||||
end
|
||||
|
||||
if (SIZE == 2) begin
|
||||
assign used_n = used_r ^ (incr ^ decr);
|
||||
assign size = size_r;
|
||||
|
||||
end else begin
|
||||
assign used_n = $signed(used_r) + ADDRW'($signed(2'(incr) - 2'(decr)));
|
||||
end
|
||||
|
||||
if (SIZE > 1) begin
|
||||
if (SIZEW > ADDRW) begin
|
||||
assign size = {full_r, used_r};
|
||||
localparam ADDRW = `LOG2UP(SIZE);
|
||||
|
||||
reg [ADDRW-1:0] used_r;
|
||||
|
||||
wire is_empty_n = (used_r == ADDRW'(1));
|
||||
wire is_full_n = (used_r == ADDRW'(SIZE-1));
|
||||
|
||||
if (SIZE > 2) begin
|
||||
|
||||
wire is_alm_empty = (used_r == ADDRW'(ALM_EMPTY));
|
||||
wire is_alm_empty_n= (used_r == ADDRW'(ALM_EMPTY+1));
|
||||
wire is_alm_full = (used_r == ADDRW'(ALM_FULL));
|
||||
wire is_alm_full_n = (used_r == ADDRW'(ALM_FULL-1));
|
||||
|
||||
wire [1:0] push_minus_pop = {~incr & decr, incr ^ decr};
|
||||
|
||||
always @(posedge clk) begin
|
||||
if (reset) begin
|
||||
empty_r <= 1;
|
||||
full_r <= 0;
|
||||
alm_empty_r <= 0;
|
||||
alm_full_r <= 0;
|
||||
used_r <= '0;
|
||||
end else begin
|
||||
if (incr) begin
|
||||
if (~decr) begin
|
||||
empty_r <= 0;
|
||||
if (is_alm_empty)
|
||||
alm_empty_r <= 0;
|
||||
if (is_full_n)
|
||||
full_r <= 1;
|
||||
if (is_alm_full_n)
|
||||
alm_full_r <= 1;
|
||||
end
|
||||
end else if (decr) begin
|
||||
full_r <= 0;
|
||||
if (is_alm_full)
|
||||
alm_full_r <= 0;
|
||||
if (is_empty_n)
|
||||
empty_r <= 1;
|
||||
if (is_alm_empty_n)
|
||||
alm_empty_r <= 1;
|
||||
end
|
||||
used_r <= $signed(used_r) + ADDRW'($signed(push_minus_pop));
|
||||
end
|
||||
end
|
||||
|
||||
end else begin
|
||||
assign size = used_r;
|
||||
|
||||
always @(posedge clk) begin
|
||||
if (reset) begin
|
||||
empty_r <= 1;
|
||||
full_r <= 0;
|
||||
used_r <= '0;
|
||||
end else begin
|
||||
empty_r <= (empty_r & ~incr) | (~full_r & decr & ~incr);
|
||||
full_r <= (~empty_r & incr & ~decr) | (full_r & ~(decr ^ incr));
|
||||
used_r <= used_r ^ (incr ^ decr);
|
||||
end
|
||||
end
|
||||
|
||||
assign alm_empty_r = used_r;
|
||||
assign alm_full_r = used_r;
|
||||
end
|
||||
end else begin
|
||||
assign size = full_r;
|
||||
|
||||
assign size = {full_r, used_r};
|
||||
|
||||
end
|
||||
|
||||
assign empty = empty_r;
|
||||
assign full = full_r;
|
||||
assign alm_empty = alm_empty_r;
|
||||
assign alm_full = alm_full_r;
|
||||
|
||||
end
|
||||
|
||||
assign empty = empty_r;
|
||||
assign alm_empty = alm_empty_r;
|
||||
assign alm_full = alm_full_r;
|
||||
assign full = full_r;
|
||||
|
||||
endmodule
|
||||
//`TRACING_ON
|
||||
`TRACING_ON
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue