MVB TCAM
- ENTITY MVB_TCAM IS
Entity declaration
MVB wrapper around
TCAM2: instantiates one full, independent TCAM2 core per MVB item (MVB_ITEMS instances), each holding its own complete, identical copy of the table content. This is what makes it possible to match MVB_ITEMS independent keys against the table in the same clock cycle, but it also means FPGA resource usage scales linearly with MVB_ITEMS - a wide MVB bus with a large or wide TCAM table can become very expensive; consider whether the use case really needs a full MVB_ITEMS-way replicated TCAM.Warning
Only TCAM2 instance 0 is built with READ_FROM_TCAM enabled; the READ_* interface always reads through that single instance (WRITE_* is broadcast identically to every instance, so all copies stay in sync regardless).
Warning
MATCH_OUT_ADDR is not a binary address like READ_ADDR/WRITE_ADDR. For each MVB item it is an ITEMS-bit one-hot/bitmap vector, one bit per stored TCAM row, since a TCAM can match multiple (or zero) rows at once; MATCH_OUT_HIT for that item is simply the OR of its bits.
GenericsNote
A single WRITE_EN request and a match never overlap - the hardware always finishes one before starting the other - so a match always sees that one row’s complete old or complete new content, never a mix. You don’t need to add anything yourself for that.
This only covers a single row, though. Updating several rows is just a sequence of separate writes, and matches can happen in between them - seeing some rows already updated and others not yet. If your application needs the whole table to look consistent during a multi-row update, that’s up to you to arrange (e.g. by holding off match traffic for the duration).
PortsGeneric
Type
Default
Description
MVB_ITEMS
natural
4
Number of MVB items transferred in one word. Directly multiplies FPGA resource usage, see the WARNING above.
DATA_WIDTH
integer
36
Width of one TCAM item (and of WRITE_DATA/WRITE_MASK/MATCH_DATA/READ_DATA/READ_MASK per item), in bits.
ITEMS
integer
16
Number of rows (entries) in the TCAM table. For optimal resource usage should be a multiple of 2*L*(2^RESOURCES_SAVING) on Xilinx (where L is the number of LUTRAMs in one SLICEM), or of 16*(2^RESOURCES_SAVING) on Intel (32*(2^RESOURCES_SAVING) when USE_FRAGMENTED_MEM is set).
RESOURCES_SAVING
integer
0
Trade-off between FPGA resources and matching speed. Possible values are 0-4 on all devices. Higher values save resources and speed up writes, but cost both matching throughput and latency:
Throughput (how often a new match can be started): one match every CLK cycle at RESOURCES_SAVING = 0 (MATCH_DST_RDY stays asserted, one result per clock back-to-back); only one match every 2^RESOURCES_SAVING cycles for higher values (MATCH_DST_RDY drops after each accepted match until that many cycles pass).
RX-to-TX latency of one result (MATCH_OUT_* after the matching MATCH_DATA is accepted): a fixed 3 + (2^RESOURCES_SAVING - 1) CLK cycles - i.e. 3 cycles at RESOURCES_SAVING = 0, growing by 2^RESOURCES_SAVING - 1 for higher values.
Write speed (time until WRITE_RDY returns after a write) is 2^(5-RESOURCES_SAVING)+1 CLK cycles, the same on all devices.
WRITE_BEFORE_MATCH
boolean
true
When true, a WRITE_EN request presented in the same cycle as a MATCH_EN request is served first (match is delayed); when false, match has priority over write. A read request is only ever deprioritized against a concurrent write (READ_RDY is simply “not WRITE_EN”) - it is not affected by match activity at all, regardless of this generic’s value.
READ_FROM_TCAM
boolean
true
Enables the READ_* interface (through TCAM2 instance 0 only, see the WARNING above) by adding extra internal storage that mirrors WRITE_DATA/WRITE_MASK. Costs extra resources; leave false if the table content never needs to be read back.
OUTPUT_READ_REGS
boolean
true
Adds an output register stage on the READ_DATA/READ_MASK/READ_DATA_VLD path for better timing, at the cost of one extra CLK cycle of read latency. Has no effect unless READ_FROM_TCAM = true (that extra storage is what this register stage sits on).
USE_UNMATCHABLE
boolean
false
Changes the meaning of a masked-out bit (WRITE_MASK bit = ‘0’):
false - a masked bit is always don’t-care (matches both ‘0’ and ‘1’).
true - a masked bit is don’t-care only if the corresponding WRITE_DATA bit is ‘0’; if that WRITE_DATA bit is ‘1’, the whole row becomes permanently UNMATCHABLE.
USE_FRAGMENTED_MEM
boolean
false
Trade higher memory-primitive utilization for a discontinuous row address space: uses the full Intel MLAB width (20 instead of 16 bits, rows 21-32 unused per block) or the full Xilinx SLICEM width (14 instead of 8 on ULTRASCALE/VERSAL, 6 instead of 4 on 7SERIES, rows 15-16/7-8 unused per block).
DEVICE
string
“ULTRASCALE”
Target FPGA device. “7SERIES”, “ULTRASCALE”, “VERSAL”, “ARRIA10”, “STRATIX10”, “AGILEX”
IS_XILINX
boolean
(DEVICE = “7SERIES” or DEVICE = “ULTRASCALE” or DEVICE = “VERSAL”)
Manufacturer of the FPGA device, derived from DEVICE by default; only override together with DEVICE.
IS_INTEL
boolean
(DEVICE = “ARRIA10” or DEVICE = “STRATIX10” or DEVICE = “AGILEX”)
INTEL_DATA_WIDTH
integer
tsel(USE_FRAGMENTED_MEM, 20, 16)
The following generics are derived automatically from the generics above and are not meant to be overridden directly.
XILINX_DATA_WIDTH
integer
tsel(DEVICE = “ULTRASCALE” or DEVICE = “VERSAL”, tsel(USE_FRAGMENTED_MEM, 14, 8), tsel(USE_FRAGMENTED_MEM, 6, 4))
MEMORY_DATA_WIDTH
integer
tsel(IS_XILINX, XILINX_DATA_WIDTH, INTEL_DATA_WIDTH)
ALIGNED_DATA_WIDTH
integer
2**log2(MEMORY_DATA_WIDTH)
ITEMS_ALIGNED
natural
tsel(USE_FRAGMENTED_MEM, div_roundup(ITEMS,MEMORY_DATA_WIDTH)*ALIGNED_DATA_WIDTH, ITEMS)
ADDR_WIDTH
natural
max(1, log2(ITEMS_ALIGNED))
Port
Type
Mode
Description
CLK
std_logic
in
CLOCK AND RESET
RESET
std_logic
in
=====
READ INTERFACE (functional only when READ_FROM_TCAM = true; reads
=====
through TCAM2 instance 0, see the WARNING above)
READ_ADDR
std_logic_vector(ADDR_WIDTH-1 downto 0)
in
Row address to read; any value in 0 to ITEMS_ALIGNED-1.
READ_EN
std_logic
in
READ_RDY
std_logic
out
Equivalent to “not WRITE_EN” (combinational); deasserted only while WRITE_EN is currently asserted, independent of any match activity or of WRITE_BEFORE_MATCH.
READ_DATA
std_logic_vector(DATA_WIDTH-1 downto 0)
out
READ_MASK
std_logic_vector(DATA_WIDTH-1 downto 0)
out
READ_DATA_VLD
std_logic
out
Valid one CLK cycle after a request accepted with READ_RDY = ‘1’ (plus one more CLK cycle when OUTPUT_READ_REGS = true).
=====
WRITE INTERFACE (broadcast identically to every one of the
=====
MVB_ITEMS replicated TCAM2 instances)
WRITE_DATA
std_logic_vector(DATA_WIDTH-1 downto 0)
in
WRITE_MASK
std_logic_vector(DATA_WIDTH-1 downto 0)
in
‘0’ bit = don’t-care (or UNMATCHABLE, see USE_UNMATCHABLE); ‘1’ bit = must match WRITE_DATA.
WRITE_ADDR
std_logic_vector(ADDR_WIDTH-1 downto 0)
in
Row address to write; any value in 0 to ITEMS_ALIGNED-1.
WRITE_EN
std_logic
in
WRITE_RDY
std_logic
out
Asserted only when every one of the MVB_ITEMS replicated instances is ready to accept a write.
=====
MATCH INTERFACE
=====
=====
MATCH_DATA
std_logic_vector(MVB_ITEMS*DATA_WIDTH-1 downto 0)
in
MATCH_VLD
std_logic_vector(MVB_ITEMS-1 downto 0)
in
MATCH_SRC_RDY
std_logic
in
MATCH_DST_RDY
std_logic
out
Asserted only when every one of the MVB_ITEMS replicated instances is ready to match (i.e. the whole MVB word is matched together, or not at all).
=====
MATCH_OUT INTERFACE - result of a MATCH interface request, 3 CLK
=====
cycles later (plus the RESOURCES_SAVING match latency, see above)
MATCH_OUT_HIT
std_logic_vector(MVB_ITEMS-1 downto 0)
out
Per MVB item: ‘1’ if the table held at least one matching row for that item’s MATCH_DATA.
MATCH_OUT_ADDR
std_logic_vector(MVB_ITEMS*ITEMS-1 downto 0)
out
Per MVB item: one-hot/bitmap of matching rows (ITEMS bits), see the WARNING above - not a binary address.
MATCH_OUT_VLD
std_logic_vector(MVB_ITEMS-1 downto 0)
out
MATCH_OUT_SRC_RDY
std_logic
out