Change decoder to take the bits to select of the opcode as parameter
authorMichael Nolan <mtnolan2640@gmail.com>
Wed, 4 Mar 2020 14:36:33 +0000 (09:36 -0500)
committerMichael Nolan <mtnolan2640@gmail.com>
Wed, 4 Mar 2020 14:36:33 +0000 (09:36 -0500)
src/decoder/power_decoder.py
src/decoder/test/test_power_decoder.py

index d6b026008c6362a55d9e962ed4b11165968dd710..46de6170d373b649da9d80c8d0906f614c6d3201 100644 (file)
@@ -73,7 +73,10 @@ class PowerDecoder(Elaboratable):
     """PowerDecoder - decodes an incoming opcode into the type of operation
     """
 
-    def __init__(self, width, opcodes, opint=True, suffix=None):
+    def __init__(self, width, opcodes, *,
+                 bitsel, subdecoders=[],
+                 opint=True,
+                 suffix=None):
         self.opint = opint  # true if the opcode needs to be converted to int
         self.opcodes = opcodes
         self.opcode_in = Signal(width, reset_less=True)
@@ -82,6 +85,8 @@ class PowerDecoder(Elaboratable):
         self.suffix = suffix
         if suffix is not None and suffix[1] - suffix[0] >= width:
             self.suffix = None
+        self.bitsel = bitsel
+        self.subdecoders = subdecoders
         self.width = width
 
     def suffix_mask(self):
@@ -108,35 +113,38 @@ class PowerDecoder(Elaboratable):
         m = Module()
         comb = m.d.comb
 
-        if self.suffix:
-            opcodes = self.divide_opcodes()
-            opc_in = Signal(self.suffix[1] - self.suffix[0], reset_less=True)
-            comb += opc_in.eq(self.opcode_in[self.suffix[0]:self.suffix[1]])
-            with m.Switch(opc_in):
-                for key, row in opcodes.items():
-                    subdecoder = PowerDecoder(width=self.width - opc_in.width,
-                                              opcodes=row,
-                                              opint=False,
-                                              suffix=self.suffix)
-                    setattr(m.submodules, "dec%d" % key, subdecoder)
-                    comb += subdecoder.opcode_in.eq(self.opcode_in[self.suffix[1]:])
-                    with m.Case(key):
-                        comb += self.op.eq(subdecoder.op)
-
-        else:
-            with m.Switch(self.opcode_in):
-                for row in self.opcodes:
-                    opcode = row['opcode']
-                    if self.opint and '-' not in opcode:
-                        opcode = int(opcode, 0)
-                    if not row['unit']:
-                        continue
-                    with m.Case(opcode):
-                        comb += self.op._eq(row)
-                with m.Default():
-                        comb += self.op._eq(None)
+        # if self.suffix:
+        #     opcodes = self.divide_opcodes()
+        #     opc_in = Signal(self.suffix[1] - self.suffix[0], reset_less=True)
+        #     comb += opc_in.eq(self.opcode_in[self.suffix[0]:self.suffix[1]])
+        #     with m.Switch(opc_in):
+        #         for key, row in opcodes.items():
+        #             subdecoder = PowerDecoder(width=self.width - opc_in.width,
+        #                                       opcodes=row,
+        #                                       opint=False,
+        #                                       suffix=self.suffix)
+        #             setattr(m.submodules, "dec%d" % key, subdecoder)
+        #             comb += subdecoder.opcode_in.eq(self.opcode_in[self.suffix[1]:])
+        #             with m.Case(key):
+        #                 comb += self.op.eq(subdecoder.op)
+
+        # else:
+        opcode = Signal(self.bitsel[1] - self.bitsel[0], reset_less=True)
+        comb += opcode.eq(self.opcode_in[self.bitsel[0]:self.bitsel[1]])
+        with m.Switch(opcode):
+            for row in self.opcodes:
+                opcode = row['opcode']
+                if self.opint and '-' not in opcode:
+                    opcode = int(opcode, 0)
+                if not row['unit']:
+                    continue
+                with m.Case(opcode):
+                    comb += self.op._eq(row)
+            with m.Default():
+                    comb += self.op._eq(None)
         return m
 
+
     def ports(self):
         return [self.opcode_in] + self.op.ports()
 
index 3efc7922fb54f3e6984e96c2e268e32986281e34..0cb708ea13046d18ef9715d0bd873287314e13b1 100644 (file)
@@ -14,10 +14,10 @@ from power_enums import (Function, InternalOp, In1Sel, In2Sel, In3Sel,
 
 class DecoderTestCase(FHDLTestCase):
 
-    def run_tst(self, width, csvname, suffix=None, opint=True):
+    def run_tst(self, bitsel, csvname, suffix=None, opint=True):
         m = Module()
         comb = m.d.comb
-        opcode = Signal(width)
+        opcode = Signal(32)
         function_unit = Signal(Function)
         internal_op = Signal(InternalOp)
         in1_sel = Signal(In1Sel)
@@ -29,7 +29,8 @@ class DecoderTestCase(FHDLTestCase):
         cry_in = Signal(CryIn)
 
         opcodes = get_csv(csvname)
-        m.submodules.dut = dut = PowerDecoder(width, opcodes, opint, suffix=suffix)
+        m.submodules.dut = dut = PowerDecoder(32, opcodes, bitsel=bitsel,
+                                              opint=opint, suffix=suffix)
         comb += [dut.opcode_in.eq(opcode),
                  function_unit.eq(dut.op.function_unit),
                  in1_sel.eq(dut.op.in1_sel),
@@ -51,7 +52,8 @@ class DecoderTestCase(FHDLTestCase):
                 if not opint: # HACK: convert 001---10 to 0b00100010
                     op = "0b" + op.replace('-', '0')
                 print ("opint", opint, row['opcode'], op)
-                yield opcode.eq(int(op, 0))
+                yield opcode.eq(0)
+                yield opcode[bitsel[0]:bitsel[1]].eq(int(op, 0))
                 yield Delay(1e-6)
                 signals = [(function_unit, Function, 'unit'),
                            (internal_op, InternalOp, 'internal op'),
@@ -74,47 +76,49 @@ class DecoderTestCase(FHDLTestCase):
                     msg = f"{sig.name} == {result}, expected: {expected}"
                     self.assertEqual(expected, result, msg)
         sim.add_process(process)
-        with sim.write_vcd("test.vcd", "test.gtkw", traces=[
+        prefix = os.path.splitext(csvname)[0]
+        with sim.write_vcd("%s.vcd" % prefix, "%s.gtkw" % prefix, traces=[
                 opcode, function_unit, internal_op,
                 in1_sel, in2_sel]):
             sim.run()
 
-    def generate_ilang(self, width, csvname, opint=True, suffix=None):
+    def generate_ilang(self, bitsel, csvname, opint=True, suffix=None):
         prefix = os.path.splitext(csvname)[0]
         if suffix:
             prefix += ".%s" % str(suffix).replace(" ", "")[1:-1]
-        dut = PowerDecoder(width, get_csv(csvname), opint, suffix=suffix)
+        dut = PowerDecoder(32, get_csv(csvname), bitsel=bitsel,
+                           opint=opint, suffix=suffix)
         vl = rtlil.convert(dut, ports=dut.ports())
         with open("%s_decoder.il" % prefix, "w") as f:
             f.write(vl)
 
     def test_major(self):
-        self.run_tst(6, "major.csv")
-        self.generate_ilang(6, "major.csv")
+        self.run_tst((26, 32), "major.csv")
+        self.generate_ilang((26, 32), "major.csv")
 
-    def test_minor_19(self):
-        self.run_tst(10, "minor_19.csv", suffix=(0, 5))
-        self.generate_ilang(10, "minor_19.csv", suffix=(0, 5))
+    def test_minor_19(self):
+        self.run_tst(10, "minor_19.csv", suffix=(0, 5))
+        self.generate_ilang(10, "minor_19.csv", suffix=(0, 5))
 
-    def test_minor_19_00000(self):
-        self.run_tst(10, "minor_19_00000.csv")
-        self.generate_ilang(10, "minor_19_00000.csv")
+    def test_minor_19_00000(self):
+        self.run_tst(10, "minor_19_00000.csv")
+        self.generate_ilang(10, "minor_19_00000.csv")
 
-    def test_minor_30(self):
-        self.run_tst(4, "minor_30.csv")
-        self.generate_ilang(4, "minor_30.csv")
+    def test_minor_30(self):
+        self.run_tst(4, "minor_30.csv")
+        self.generate_ilang(4, "minor_30.csv")
 
-    def test_minor_31(self):
-        self.run_tst(10, "minor_31.csv", suffix=(0, 5))
-        self.generate_ilang(10, "minor_31.csv", suffix=(0, 5))
+    def test_minor_31(self):
+        self.run_tst(10, "minor_31.csv", suffix=(0, 5))
+        self.generate_ilang(10, "minor_31.csv", suffix=(0, 5))
 
-    #def test_minor_31_prefix(self):
-    #    self.run_tst(10, "minor_31.csv", suffix=(5, 10))
-    #    self.generate_ilang(10, "minor_31.csv", suffix=(5, 10))
+    # #def test_minor_31_prefix(self):
+    #    self.run_tst(10, "minor_31.csv", suffix=(5, 10))
+    #    self.generate_ilang(10, "minor_31.csv", suffix=(5, 10))
 
-    def test_extra(self):
-        self.run_tst(32, "extra.csv", opint=False)
-        self.generate_ilang(32, "extra.csv", opint=False)
+    def test_extra(self):
+        self.run_tst(32, "extra.csv", opint=False)
+        self.generate_ilang(32, "extra.csv", opint=False)
 
 
 if __name__ == "__main__":