separate out PowerOps from PowerDecoder, simplifies code and also makes
authorLuke Kenneth Casson Leighton <lkcl@lkcl.net>
Sun, 1 Mar 2020 14:21:39 +0000 (14:21 +0000)
committerLuke Kenneth Casson Leighton <lkcl@lkcl.net>
Sun, 1 Mar 2020 14:21:39 +0000 (14:21 +0000)
it possible to set (later) from explicit row specs (nop etc.)

src/decoder/power_decoder.py

index 52e4f7911372023ef300e4f17d32f9b49bd20ff9..08b8ab2efff7b2e9191398ee9d3c404c38849ccd 100644 (file)
@@ -4,11 +4,8 @@ from power_enums import (Function, InternalOp, In1Sel, In2Sel, In3Sel,
                          get_signal_name)
 
 
-class PowerDecoder(Elaboratable):
-    def __init__(self, width, csvname):
-        self.opcodes = get_csv(csvname)
-        self.opcode_in = Signal(width, reset_less=True)
-
+class PowerOp:
+    def __init__(self):
         self.function_unit = Signal(Function, reset_less=True)
         self.internal_op = Signal(InternalOp, reset_less=True)
         self.in1_sel = Signal(In1Sel, reset_less=True)
@@ -20,8 +17,47 @@ class PowerDecoder(Elaboratable):
         self.cry_in = Signal(CryIn, reset_less=True)
         for bit in single_bit_flags:
             name = get_signal_name(bit)
-            setattr(self, name,
-                    Signal(reset_less=True, name=name))
+            setattr(self, name, Signal(reset_less=True, name=name))
+
+    def _eq(self, row):
+        if row is None:
+            row = {}
+        res = [self.function_unit.eq(Function[row.get('unit', Function.NONE)]),
+               self.internal_op.eq(InternalOp[row.get('internal op',
+                                                      InternalOp.OP_ILLEGAL)])
+               self.in1_sel.eq(In1Sel[row.get('in1', 0)])
+               self.in2_sel.eq(In2Sel[row.get('in2', 0)])
+               self.in3_sel.eq(In3Sel[row.get('in3', 0)])
+               self.out_sel.eq(OutSel[row.get('out', 0)])
+               self.ldst_len.eq(LdstLen[row.get('ldst len', 0)])
+               self.rc_sel.eq(RC[row.get('rc', 0)])
+               self.cry_in.eq(CryIn[row.get('cry in', 0)])
+               ]
+        for bit in single_bit_flags:
+            sig = getattr(self, get_signal_name(bit))
+            res.append(sig.eq(0))
+        return res
+
+    def ports(self):
+        regular = [self.function_unit,
+                   self.in1_sel,
+                   self.in2_sel,
+                   self.in3_sel,
+                   self.out_sel,
+                   self.ldst_len,
+                   self.rc_sel,
+                   self.internal_op]
+        single_bit_ports = [getattr(self, get_signal_name(x))
+                            for x in single_bit_flags]
+        return regular + single_bit_ports
+
+
+class PowerDecoder(Elaboratable):
+    def __init__(self, width, csvname):
+        self.opcodes = get_csv(csvname)
+        self.opcode_in = Signal(width, reset_less=True)
+
+        self.op = PowerOp()
 
     def elaborate(self, platform):
         m = Module()
@@ -33,43 +69,11 @@ class PowerDecoder(Elaboratable):
                 if not row['unit']:
                     continue
                 with m.Case(opcode):
-                    comb += self.function_unit.eq(Function[row['unit']])
-                    comb += self.internal_op.eq(InternalOp[row['internal op']])
-                    comb += self.in1_sel.eq(In1Sel[row['in1']])
-                    comb += self.in2_sel.eq(In2Sel[row['in2']])
-                    comb += self.in3_sel.eq(In3Sel[row['in3']])
-                    comb += self.out_sel.eq(OutSel[row['out']])
-                    comb += self.ldst_len.eq(LdstLen[row['ldst len']])
-                    comb += self.rc_sel.eq(RC[row['rc']])
-                    comb += self.cry_in.eq(CryIn[row['cry in']])
-                    for bit in single_bit_flags:
-                        sig = getattr(self, get_signal_name(bit))
-                        comb += sig.eq(int(row[bit]))
+                    comb += self.op._eq(row)
             with m.Default():
-                comb += self.function_unit.eq(Function.NONE)
-                comb += self.internal_op.eq(InternalOp.OP_ILLEGAL)
-                comb += self.in1_sel.eq(0)
-                comb += self.in2_sel.eq(0)
-                comb += self.in3_sel.eq(0)
-                comb += self.out_sel.eq(0)
-                comb += self.ldst_len.eq(0)
-                comb += self.rc_sel.eq(0)
-                comb += self.cry_in.eq(0)
-                for bit in single_bit_flags:
-                    sig = getattr(self, get_signal_name(bit))
-                    comb += sig.eq(0)
+                    comb += self.op._eq(None)
         return m
 
     def ports(self):
-        regular = [self.opcode_in,
-                   self.function_unit,
-                   self.in1_sel,
-                   self.in2_sel,
-                   self.in3_sel,
-                   self.out_sel,
-                   self.ldst_len,
-                   self.rc_sel,
-                   self.internal_op]
-        single_bit_ports = [getattr(self, get_signal_name(x))
-                            for x in single_bit_flags]
-        return regular + single_bit_ports
+        return [self.opcode_in] + self.op.ports()
+