1 from nmigen
import Module
, Signal
2 from nmigen
.compat
.fhdl
.structure
import If
3 from nmigen
.compat
.sim
import run_simulation
6 def __init__(self
, key_size
, data_size
):
8 self
.key
= Signal(key_size
)
11 self
.write
= Signal(1) # Read => 0 Write => 1
12 self
.key_in
= Signal(key_size
) # Reference key for the CAM
13 self
.data_in
= Signal(data_size
) # Data input when writing
16 self
.match
= Signal(1) # Result of the internal/input key comparison
17 self
.data
= Signal(data_size
)
20 def get_fragment(self
, platform
=None):
22 with m
.If(self
.write
== 1):
24 self
.key
.eq(self
.key_in
),
25 self
.data
.eq(self
.data_in
),
29 with m
.If(self
.key_in
== self
.key
):
30 m
.d
.sync
+= self
.match
.eq(0)
32 m
.d
.sync
+= self
.match
.eq(1)
40 # This function allows for the easy setting of values to the Cam Entry
41 # unless the key is incorrect
43 # dut: The CamEntry being tested
44 # w (write): Read (0) or Write (1)
45 # k (key): The key to be set
46 # d (data): The data to be set
47 def set_cam(dut
, w
, k
, d
):
49 yield dut
.key_in
.eq(k
)
50 yield dut
.data_in
.eq(d
)
53 # Verifies the given values via the requested operation
55 # pre (Prefix): Appended to the front of the assert statement
56 # e (Expected): The expected value
57 # out (Output): The output result
58 # op (Operation): (0 => ==), (1 => !=)
59 def check(pre
, e
, out
, op
):
62 assert out
== e
, pre
+ " Output " + str(out
) + " Expected " + str(e
)
65 assert out
!= e
, pre
+ " Output " + str(out
) + " Expected " + str(e
)
67 # Checks the key state of the CAM entry
69 # dut: The CamEntry being tested
70 # k (Key): The expected key
71 # op (Operation): (0 => ==), (1 => !=)
72 def check_key(dut
, k
, op
):
74 check("K", out_k
, k
, op
)
76 # Checks the data state of the CAM entry
78 # dut: The CamEntry being tested
79 # d (Data): The expected data
80 # op (Operation): (0 => ==), (1 => !=)
81 def check_data(dut
, d
, op
):
82 out_d
= yield dut
.data
83 check("D", out_d
, d
, op
)
85 # Checks the match state of the CAM entry
87 # dut: The CamEntry being tested
88 # m (Match): The expected match
89 # op (Operation): (0 => ==), (1 => !=)
90 def check_match(dut
, m
, op
):
91 out_m
= yield dut
.match
92 check("M", out_m
, m
, op
)
94 # Checks the state of the CAM entry
96 # dut: The CamEntry being tested
97 # k (key): The expected key
98 # d (data): The expected data
99 # m (match): The expected match
100 # kop (Operation): The operation for the key assertion (0 => ==), (1 => !=)
101 # dop (Operation): The operation for the data assertion (0 => ==), (1 => !=)
102 # mop (Operation): The operation for the match assertion (0 => ==), (1 => !=)
103 def check_all(dut
, k
, d
, m
, kop
, dop
, mop
):
104 yield from check_key(dut
, k
, kop
)
105 yield from check_data(dut
, d
, dop
)
106 yield from check_match(dut
, m
, mop
)
108 # This testbench goes through the paces of testing the CamEntry module
109 # It is done by writing and then reading various combinations of key/data pairs
110 # and reading the results with varying keys to verify the resulting stored
118 yield from set_cam(dut
, write
, key
, data
)
119 yield from check_all(dut
, key
, data
, match
, 0, 0, 0)
126 yield from set_cam(dut
, write
, key
, data
)
127 yield from check_all(dut
, key
, data
, match
, 1, 0, 0)
134 yield from set_cam(dut
, write
, key
, data
)
135 yield from check_all(dut
, key
, data
, match
, 0, 0, 0)
142 yield from set_cam(dut
, write
, key
, data
)
143 yield from check_all(dut
, key
, data
, match
, 0, 0, 0)
147 if __name__
== "__main__":
149 run_simulation(dut
, testbench(dut
), vcd_name
="Waveforms/cam_entry_test.vcd")