vortex/hw/rtl/libs/VX_index_queue.sv

77 lines
2.3 KiB
Systemverilog

// Copyright © 2019-2023
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
`include "VX_platform.vh"
`TRACING_OFF
module VX_index_queue #(
parameter DATAW = 1,
parameter SIZE = 1
) (
input wire clk,
input wire reset,
input wire [DATAW-1:0] write_data,
output wire [`LOG2UP(SIZE)-1:0] write_addr,
input wire push,
input wire pop,
output wire full,
output wire empty,
input wire [`LOG2UP(SIZE)-1:0] read_addr,
output wire [DATAW-1:0] read_data
);
reg [DATAW-1:0] entries [SIZE-1:0];
reg [SIZE-1:0] valid;
reg [`LOG2UP(SIZE):0] rd_ptr, wr_ptr;
wire [`LOG2UP(SIZE)-1:0] rd_a, wr_a;
wire enqueue, dequeue;
assign rd_a = rd_ptr[`LOG2UP(SIZE)-1:0];
assign wr_a = wr_ptr[`LOG2UP(SIZE)-1:0];
assign empty = (wr_ptr == rd_ptr);
assign full = (wr_a == rd_a) && (wr_ptr[`LOG2UP(SIZE)] != rd_ptr[`LOG2UP(SIZE)]);
assign enqueue = push;
assign dequeue = !empty && !valid[rd_a]; // auto-remove when head is invalid
`RUNTIME_ASSERT(!push || !full, ("%t: *** invalid inputs", $time))
always @(posedge clk) begin
if (reset) begin
rd_ptr <= '0;
wr_ptr <= '0;
valid <= '0;
end else begin
if (enqueue) begin
valid[wr_a] <= 1;
wr_ptr <= wr_ptr + 1;
end
if (dequeue) begin
rd_ptr <= rd_ptr + 1;
end
if (pop) begin
valid[read_addr] <= 0;
end
end
if (enqueue) begin
entries[wr_a] <= write_data;
end
end
assign write_addr = wr_a;
assign read_data = entries[read_addr];
endmodule
`TRACING_ON