I'm trying to implement a cache and index lookup memory in SystemVerilog. It's a simple CAM + circular buffer. The interface is:
input rst_n;
input clk;
input [WORD_BITS-1:0] inp;
input rd_en;
input wr_en;
output logic [DEPTH_BITS-1:0] index;
output logic index_valid;
reg [WORD_BITS-1:0] buffer[$pow(2, DEPTH_BITS)];
reg [DEPTH_BITS-1:0] next;
There's basic async reset code. There's a synchronous block that stores inp in buffer and advances next whenever wr_en is high.
Now I'm trying to come up with an efficient and readable way of finding the index of inp when rd_en is high. It seems this could be completely combinational except when clocking the result into the index output. The way I'm visualizing it in my head is to xor inp with all of the buffer locations (it will be fairly small, perhaps 64 entries) then if that is equal to 0 the entry was found. Then a block to arbitrarily choose one of the indices with a 0 value. This is where is differs from a traditional CAM, there could be multiple entries for the same value but I really only need the index of one of those and it doesn't matter which one.
Any thoughts on how to do this in System Verilog (2012)? I know I can loop through all the memory locations synchronously and save a bunch of area but I'd rather it be fast than small. I'm targeting FPGAs. (initially inexpensive Lattice and maybe Xilinx parts) I know a few of the Lattice parts actually have CAM blocks but this is for cases where that isn't available.