Fifo ID Tracker
Track IDs inside the fifo
Introduction
In this PPA challenge, you are given a first-in first-out buffer (fifo) of requests and
need to report which request IDs are currently stored in it. Each request is a packed struct
with an ID, a write-or-read bit, an address and data. Alongside the fifo's usual push and pop
interface, the module drives valid_id_o, a bit vector with one bit per possible ID:
valid_id_o[k] must be asserted whenever at least one request with ID k is in the fifo.
For example, if the fifo holds requests with IDs 3, 5 and 7 (in any order, and even if an
ID appears more than once), then valid_id_o[3], valid_id_o[5] and valid_id_o[7] are
asserted and every other bit is low.
The boilerplate code works but is slow and large: it reads the fifo's whole storage at once, rotates it by the read pointer so the oldest request comes first, and then marks the ID of each stored request. Your task is to keep the same behaviour while improving the timing and area of the design. The synthesis and timing report after each run shows how your design compares with the reference solution.
All the flops should be positive edge triggered with active high resets (if any).
Interface Definition
DEPTH => Number of entries in the fifo
ID_W => Width of the request ID; there are 2**ID_W possible IDs
ADDR_W => Width of the request address
DATA_W => Width of the request data
push_i => Push a request into the fifo
push_req_i => The request to push: {id, write_or_read, addr, data}, id in the MSBs
pop_i => Pop the oldest request from the fifo
pop_req_o => The oldest request in the fifo
count_o => Number of requests currently in the fifo
valid_id_o => valid_id_o[k] is high when at least one request with ID k is in the fifoThe request layout, as used in the boilerplate:
typedef struct packed {
logic [ID_W-1:0] id;
logic write_or_read; // 1: write, 0: read
logic [ADDR_W-1:0] addr;
logic [DATA_W-1:0] data;
} req_t;Interface Requirements
- The fifo must keep requests in first-in first-out order
- Push and pop can happen in the same cycle
pop_req_omust show the oldest request whenever the fifo isn't emptycount_oandvalid_id_omust reflect the requests stored in the fifo at the start of the cycle (they update the cycle after a push or pop)- An ID stays valid until the last request with that ID is popped
push_iwill only be asserted when the fifo isn't full (count_o < DEPTH)pop_iwill only be asserted when the fifo isn't empty (count_o > 0)
Shared Modules
You are allowed to use the following shared module in your RTL:
module qs_fifo_broadside #(
parameter DATA_W = 4,
parameter DEPTH = 4
)(
input logic clk,
input logic reset,
input logic push_i,
input logic [DATA_W-1:0] push_data_i,
input logic pop_i,
output logic [DATA_W-1:0] pop_data_o,
output logic [DEPTH-1:0][DATA_W-1:0] fifo_data_o, // Storage slot i (not the i-th oldest entry)
output logic [$clog2(DEPTH+1)-1:0] count_o, // Number of stored entries
output logic [$clog2(DEPTH)-1:0] rd_ptr_o, // Slot of the oldest entry
output logic [$clog2(DEPTH)-1:0] wr_ptr_o // Slot the next push writes
);Loading the interactive workspace...