""" Content Addressable Memory (CAM) Entry
The purpose of this module is to represent an entry within a CAM.
- This module when given a read command will compare the given key
+ This module when given a read command will compare the given data
and output whether a match was found or not. When given a write
- command it will write the given key and data into internal registers.
+ command it will write the given data into internal registers.
"""
- def __init__(self, key_size, data_size):
+ def __init__(self, data_size):
""" Arguments:
- * key_size: (bit count) The size of the key
* data_size: (bit count) The size of the data
"""
- # Internal
- self.key = Signal(key_size)
-
# Input
self.command = Signal(2) # 00 => NA 01 => Read 10 => Write 11 => Reset
- self.key_in = Signal(key_size) # Reference key for the CAM
self.data_in = Signal(data_size) # Data input when writing
# Output
with m.Case("00"):
m.d.sync += self.match.eq(0)
with m.Case("01"):
- with m.If(self.key_in == self.key):
+ with m.If(self.data == self.data_in):
m.d.sync += self.match.eq(1)
with m.Else():
m.d.sync += self.match.eq(0)
with m.Case("10"):
m.d.sync += [
- self.key.eq(self.key_in),
self.data.eq(self.data_in),
self.match.eq(0)
]
with m.Case():
m.d.sync += [
self.match.eq(0),
- self.data.eq(0),
- self.key.eq(0)
+ self.data.eq(0)
]
return m
# Arguments:
# dut: The CamEntry being tested
# c (command): NA (0), Read (1), Write (2), Reserve (3)
-# k (key): The key to be set
# d (data): The data to be set
-def set_cam_entry(dut, c, k, d):
+def set_cam_entry(dut, c, d):
# Write desired values
yield dut.command.eq(c)
- yield dut.key_in.eq(k)
yield dut.data_in.eq(d)
yield
# Reset all lines
yield dut.command.eq(0)
- yield dut.key_in.eq(0)
yield dut.data_in.eq(0)
yield
-
-# Checks the key state of the CAM entry
-# Arguments:
-# dut: The CamEntry being tested
-# k (Key): The expected key
-# op (Operation): (0 => ==), (1 => !=)
-def check_key(dut, k, op):
- out_k = yield dut.key
- if op == 0:
- assert_eq("Key", out_k, k)
- else:
- assert_ne("Key", out_k, k)
# Checks the data state of the CAM entry
# Arguments:
# Checks the state of the CAM entry
# Arguments:
# dut: The CamEntry being tested
-# k (key): The expected key
# d (data): The expected data
-# m (match): The expected match
-# k_op (Operation): The operation for the key assertion (0 => ==), (1 => !=)
+# m (match): The expected match
# d_op (Operation): The operation for the data assertion (0 => ==), (1 => !=)
# m_op (Operation): The operation for the match assertion (0 => ==), (1 => !=)
-def check_all(dut, k, d, m, k_op, d_op, m_op):
- yield from check_key(dut, k, k_op)
+def check_all(dut, d, m, d_op, m_op):
yield from check_data(dut, d, d_op)
yield from check_match(dut, m, m_op)
def testbench(dut):
# Check write
command = 2
- key = 1
data = 1
match = 0
- yield from set_cam_entry(dut, command, key, data)
- yield from check_all(dut, key, data, match, 0, 0, 0)
+ yield from set_cam_entry(dut, command, data)
+ yield from check_all(dut, data, match, 0, 0)
# Check read miss
command = 1
- key = 2
- data = 1
- match = 0
- yield from set_cam_entry(dut, command, key, data)
- yield from check_all(dut, key, data, match, 1, 0, 0)
+ data = 2
+ match = 0
+ yield from set_cam_entry(dut, command, data)
+ yield from check_all(dut, data, match, 1, 0)
# Check read hit
command = 1
- key = 1
data = 1
match = 1
- yield from set_cam_entry(dut, command, key, data)
- yield from check_all(dut, key, data, match, 0, 0, 0)
+ yield from set_cam_entry(dut, command, data)
+ yield from check_all(dut, data, match, 0, 0)
# Check overwrite
command = 2
- key = 2
data = 5
match = 0
- yield from set_cam_entry(dut, command, key, data)
+ yield from set_cam_entry(dut, command, data)
yield
- yield from check_all(dut, key, data, match, 0, 0, 0)
+ yield from check_all(dut, data, match, 0, 0)
# Check read hit
command = 1
- key = 2
data = 5
match = 1
- yield from set_cam_entry(dut, command, key, data)
- yield from check_all(dut, key, data, match, 0, 0, 0)
+ yield from set_cam_entry(dut, command, data)
+ yield from check_all(dut, data, match, 0, 0)
# Check reset
command = 3
- key = 0
data = 0
match = 0
- yield from set_cam_entry(dut, command, key, data)
- yield from check_all(dut, key, data, match, 0, 0, 0)
+ yield from set_cam_entry(dut, command, data)
+ yield from check_all(dut, data, match, 0, 0)
# Extra clock cycle for waveform
yield
if __name__ == "__main__":
- dut = CamEntry(4, 4)
+ dut = CamEntry(4)
run_simulation(dut, testbench(dut), vcd_name="Waveforms/cam_entry_test.vcd")
print("CamEntry Unit Test Success")