Update CAM to represent and actual CAM. No more key!
authorDaniel Benusovich <flyingmonkeys1996@gmail.com>
Mon, 4 Mar 2019 05:47:02 +0000 (21:47 -0800)
committerDaniel Benusovich <flyingmonkeys1996@gmail.com>
Tue, 5 Mar 2019 07:28:36 +0000 (23:28 -0800)
TLB/src/Cam.py
TLB/test/test_cam.py

index 62b5462a138adc5825dd65fee9066789db981b03..4fc9ccfe86a8aefd0b409c75667edcb6d1738244 100644 (file)
@@ -1,6 +1,5 @@
 from nmigen import Array, Module, Signal
 from nmigen.lib.coding import Encoder, Decoder
-from nmigen.compat.fhdl.structure import ClockDomain
 from nmigen.cli import main #, verilog
 
 from CamEntry import CamEntry
@@ -25,44 +24,47 @@ class Cam():
         the read to be ignored.
     """
 
-    def __init__(self, key_size, data_size, cam_size):
+    def __init__(self data_size, cam_size):
         """ Arguments:
-            * key_size: (bit count) The size of the key
             * data_size: (bit count) The size of the data
             * cam_size: (entry count) The number of entries int he CAM
         """
+
         # Internal
         self.cam_size = cam_size
-        self.entry_array = Array(CamEntry(key_size, data_size) \
+        self.encoder = Encoder(cam_size)
+        self.decoder = Decoder(cam_size)
+        self.entry_array = Array(CamEntry(data_size) \
                             for x in range(cam_size))
 
         # Input
         # 000 => NA 001 => Read 010 => Write 011 => Search
         # 100 => Reset 101, 110, 111 => Reserved
-        self.command = Signal(3)
+        self.command = Signal(3) 
+        self.enable = Signal(1)
+        self.data_in = Signal(data_size) # The data to be written
+        self.data_mask = Signal(data_size) # mask for ternary writes
+        self.write_enable = Signal(1) # write
         self.address = Signal(max=cam_size) # address of CAM Entry to write/read
-        self.key_in = Signal(key_size) # The key to search for or to be written
-        self.data_in = Signal(key_size) # The data to be written
-
+        
         # Output
         self.data_hit = Signal(1) # Denotes a key data pair was stored at key_in
         self.data_out = Signal(data_size) # The data mapped to by key_in
 
     def elaborate(self, platform=None):
         m = Module()
-
         # Encoder is used to selecting what data is output when searching
-        m.submodules.encoder = encoder = Encoder(self.cam_size)
+        m.submodules += self.encoder
         # Decoder is used to select which entry will be written to
-        m.submodules.decoder = decoder = Decoder(self.cam_size)
+        m.submodules += self.decoder
         # Don't forget to add all entries to the submodule list
         entry_array = self.entry_array
         m.submodules += entry_array
 
         # Decoder logic
         m.d.comb += [
-            decoder.i.eq(self.address),
-            decoder.n.eq(0)
+            self.decoder.i.eq(self.address),
+            self.decoder.n.eq(0)
         ]
 
         # Set the key value for every CamEntry
@@ -72,13 +74,13 @@ class Cam():
                 with m.Case("0-1"):
                     m.d.comb += entry_array[index].command.eq(1)
                     # Only read if an encoder value is not ready
-                    with m.If(decoder.o[index] & encoder.n):
+                    with m.If(self.decoder.o[index] & self.encoder.n):
                         m.d.comb += self.data_out.eq(entry_array[index].data)
                 # Write only to one entry
                 with m.Case("010"):
                     # Address is decoded and selects which
                     # entry will be written to
-                    with m.If(decoder.o[index]):
+                    with m.If(self.decoder.o[index]):
                         m.d.comb += entry_array[index].command.eq(2)
                     with m.Else():
                         m.d.comb += entry_array[index].command.eq(0)
@@ -93,16 +95,15 @@ class Cam():
                     m.d.comb += entry_array[index].command.eq(0)
 
             m.d.comb += [
-                   entry_array[index].key_in.eq(self.key_in),
                    entry_array[index].data_in.eq(self.data_in),
-                   encoder.i[index].eq(entry_array[index].match)
+                   self.encoder.i[index].eq(entry_array[index].match)
             ]
 
         # Process out data based on encoder address
-        with m.If(encoder.n == 0):
+        with m.If(self.encoder.n == 0):
             m.d.comb += [
                 self.data_hit.eq(1),
-                self.data_out.eq(entry_array[encoder.o].data)
+                self.data_out.eq(entry_array[self.encoder.o].data)
             ]
         with m.Else():
             m.d.comb += self.data_hit.eq(0)
index 2e05863408f59830066a2c932fa4dbb482ee0f15..b3ce3572c2d6882d0032231755cd53a238efdb7b 100644 (file)
@@ -8,10 +8,9 @@ from Cam import Cam
 
 from test_helper import assert_eq, assert_ne
 
-def set_cam(dut, c, a, k, d):
+def set_cam(dut, c, a, d):
     yield dut.command.eq(c)
     yield dut.address.eq(a)
-    yield dut.key_in.eq(k)
     yield dut.data_in.eq(d)
     yield   
     
@@ -38,63 +37,66 @@ def testbench(dut):
     # NA
     command = 0
     address = 0
-    key = 0
     data = 0
     data_hit = 0
-    yield from set_cam(dut, command, address, key, data)
+    yield from set_cam(dut, command, address, data)
     yield from check_data_hit(dut, data_hit, 0)
     
     # Search
     command = 3
     address = 0
-    key = 0
     data = 0
     data_hit = 0
-    yield from set_cam(dut, command, address, key, data)
+    yield from set_cam(dut, command, address, data)
     yield from check_data_hit(dut, data_hit, 0)    
     
     # Write Entry 0
     command = 2
     address = 0
-    key = 5
     data = 4
     data_hit = 0
-    yield from set_cam(dut, command, address, key, data)
+    yield from set_cam(dut, command, address, data)
     yield from check_data_hit(dut, data_hit, 0) 
     
     # Read Entry 0
     command = 1
     address = 0
-    key = 0
     data = 4
     data_hit = 0
-    yield from set_cam(dut, command, address, key, data)
+    yield from set_cam(dut, command, address, data)
     yield from check_all(dut, data_hit, data, 0, 0) 
     
-    # Search 
+    # Search Hit
     command = 3
     address = 0
-    key = 5
     data = 4
     data_hit = 1
-    yield from set_cam(dut, command, address, key, data)
+    yield from set_cam(dut, command, address, data)
     yield
     yield from check_all(dut, data_hit, data, 0, 0)
     
+    # Search Miss
+    command = 3
+    address = 0
+    data = 5
+    data_hit = 0
+    yield from set_cam(dut, command, address, data)
+    yield
+    yield from check_all(dut, data_hit, data, 0, 1)     
+    
     # Reset 
     command = 4
     address = 0
-    key = 0
     data = 0
     data_hit = 0
-    yield from set_cam(dut, command, address, key, data)
+    yield from set_cam(dut, command, address, data)
     yield
-    yield from check_all(dut, data_hit, data, 0, 0)      
+    yield from check_all(dut, data_hit, data, 0, 0) 
     
     yield 
     
 
 if __name__ == "__main__":
-    dut = Cam(4, 4, 4)
+    dut = Cam(4, 4)
     run_simulation(dut, testbench(dut), vcd_name="Waveforms/cam_test.vcd")
     print("Cam Unit Test Success")
\ No newline at end of file