Hierarchial decoder semi-working
authorMichael Nolan <mtnolan2640@gmail.com>
Wed, 4 Mar 2020 15:31:15 +0000 (10:31 -0500)
committerMichael Nolan <mtnolan2640@gmail.com>
Wed, 4 Mar 2020 15:31:15 +0000 (10:31 -0500)
src/decoder/power_decoder.py
src/decoder/test/test_power_decoder.py

index 46de6170d373b649da9d80c8d0906f614c6d3201..dcfe7a9723b748677bd3ac0cb54433bbc4ad3de1 100644 (file)
@@ -2,6 +2,9 @@ from nmigen import Module, Elaboratable, Signal
 from power_enums import (Function, InternalOp, In1Sel, In2Sel, In3Sel,
                          OutSel, RC, LdstLen, CryIn, get_csv, single_bit_flags,
                          get_signal_name, default_values)
+from collections import namedtuple
+
+Subdecoder = namedtuple("Subdecoder", ["pattern", "csv", "opint", "bitsel"])
 
 
 class PowerOp:
@@ -129,9 +132,10 @@ class PowerDecoder(Elaboratable):
         #                 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):
+        opcode_switch = Signal(self.bitsel[1] - self.bitsel[0], reset_less=True)
+        comb += opcode_switch.eq(self.opcode_in[self.bitsel[0]:self.bitsel[1]])
+        with m.Switch(opcode_switch):
+            self.handle_subdecoders(m)
             for row in self.opcodes:
                 opcode = row['opcode']
                 if self.opint and '-' not in opcode:
@@ -144,17 +148,34 @@ class PowerDecoder(Elaboratable):
                     comb += self.op._eq(None)
         return m
 
+    def handle_subdecoders(self, m):
+        for dec in self.subdecoders:
+            subdecoder = PowerDecoder(width=self.width,
+                                      opcodes=dec.csv,
+                                      opint=dec.opint,
+                                      bitsel=dec.bitsel)
+
+            setattr(m.submodules, "dec%d" % dec.pattern, subdecoder)
+            m.d.comb += subdecoder.opcode_in.eq(self.opcode_in)
+            with m.Case(dec.pattern):
+                m.d.comb += self.op.eq(subdecoder.op)
 
     def ports(self):
         return [self.opcode_in] + self.op.ports()
 
-# how about this?
-# if False:
-#     pminor = (0, 6, [(19, "minor_19", (1,11)), # pass to 'splitter' function
-#                      (30, "minor_30", (1,4)),
-#                      (31, "minor_31", (1,11)), # pass to 'splitter' function
-#                      (58, "minor_58", (0,1)),
-#                      (62, "minor_62", (0,1)),
-#                     ]
 
-#     pdecode = PowerDecoder(6, "major", subcoders = pminor)
+pminor = [
+    Subdecoder(pattern=19, csv=get_csv("minor_19.csv"),
+               opint=True, bitsel=(1, 11)),
+    Subdecoder(pattern=30, csv=get_csv("minor_30.csv"),
+               opint=True, bitsel=(1, 5)),
+    Subdecoder(pattern=31, csv=get_csv("minor_31.csv"),
+               opint=True, bitsel=(1, 11)),
+    # Subdecoder(pattern=58, csv=get_csv("minor_58.csv"),
+    #            opint=True, bitsel=(0, 1)),
+    # Subdecoder(pattern=62, csv=get_csv("minor_62.csv"),
+    #            opint=True, bitsel=(0, 1)),
+]
+
+opcodes = get_csv("major.csv")
+pdecode = PowerDecoder(32, opcodes, bitsel=(26, 32), subdecoders=pminor)
index fdb178475e7c86548850d21f9da708269d2d0a94..186867146ae200f1855fecc2dfebaf73bcef3648 100644 (file)
@@ -6,7 +6,7 @@ import sys
 import os
 import unittest
 sys.path.append("../")
-from power_decoder import (PowerDecoder)
+from power_decoder import (PowerDecoder, pdecode)
 from power_enums import (Function, InternalOp, In1Sel, In2Sel, In3Sel,
                          OutSel, RC, LdstLen, CryIn, single_bit_flags,
                          get_signal_name, get_csv)
@@ -14,7 +14,7 @@ from power_enums import (Function, InternalOp, In1Sel, In2Sel, In3Sel,
 
 class DecoderTestCase(FHDLTestCase):
 
-    def run_tst(self, bitsel, csvname, suffix=None, opint=True):
+    def run_tst(self, bitsel, csvname, minor=None, suffix=None, opint=True):
         m = Module()
         comb = m.d.comb
         opcode = Signal(32)
@@ -28,9 +28,10 @@ class DecoderTestCase(FHDLTestCase):
         ldst_len = Signal(LdstLen)
         cry_in = Signal(CryIn)
 
-        opcodes = get_csv(csvname)
-        m.submodules.dut = dut = PowerDecoder(32, opcodes, bitsel=bitsel,
-                                              opint=opint, suffix=suffix)
+        # opcodes = get_csv(csvname)
+        # m.submodules.dut = dut = PowerDecoder(32, opcodes, bitsel=bitsel,
+        #                                       opint=opint, suffix=suffix)
+        m.submodules.dut = dut = pdecode
         comb += [dut.opcode_in.eq(opcode),
                  function_unit.eq(dut.op.function_unit),
                  in1_sel.eq(dut.op.in1_sel),
@@ -43,17 +44,23 @@ class DecoderTestCase(FHDLTestCase):
                  internal_op.eq(dut.op.internal_op)]
 
         sim = Simulator(m)
+        opcodes = get_csv(csvname)
 
         def process():
-            for row in dut.opcodes:
+            for row in opcodes:
                 if not row['unit']:
                     continue
                 op = row['opcode']
                 if not opint: # HACK: convert 001---10 to 0b00100010
                     op = "0b" + op.replace('-', '0')
                 print ("opint", opint, row['opcode'], op)
+                print(row)
                 yield opcode.eq(0)
                 yield opcode[bitsel[0]:bitsel[1]].eq(int(op, 0))
+                if minor:
+                    print(minor)
+                    minorbits = minor[1]
+                    yield opcode[minorbits[0]:minorbits[1]].eq(minor[0])
                 yield Delay(1e-6)
                 signals = [(function_unit, Function, 'unit'),
                            (internal_op, InternalOp, 'internal op'),
@@ -97,19 +104,20 @@ class DecoderTestCase(FHDLTestCase):
         self.generate_ilang((26, 32), "major.csv")
 
     def test_minor_19(self):
-        self.run_tst((1, 11), "minor_19.csv", suffix=(0, 5))
+        self.run_tst((1, 11), "minor_19.csv", minor=(19, (26, 32)),
+                     suffix=(0, 5))
         self.generate_ilang((1, 11), "minor_19.csv", suffix=(0, 5))
 
-    def test_minor_19_00000(self):
-        self.run_tst((1, 11), "minor_19_00000.csv")
-        self.generate_ilang((1, 11), "minor_19_00000.csv")
+    def test_minor_19_00000(self):
+        self.run_tst((1, 11), "minor_19_00000.csv")
+        self.generate_ilang((1, 11), "minor_19_00000.csv")
 
     def test_minor_30(self):
-        self.run_tst((1, 5), "minor_30.csv")
+        self.run_tst((1, 5), "minor_30.csv", minor=(30, (26, 32)))
         self.generate_ilang((1, 5), "minor_30.csv")
 
     def test_minor_31(self):
-        self.run_tst((1, 11), "minor_31.csv", suffix=(0, 5))
+        self.run_tst((1, 11), "minor_31.csv", minor=(31, (26, 32)))
         self.generate_ilang((1, 11), "minor_31.csv", suffix=(0, 5))
 
     # #def test_minor_31_prefix(self):