add TT.size and use it in PowerDecoder and trap input record
[soc.git] / src / soc / decoder / power_decoder.py
index 6094da1b4c84cbe1e1342cda62733bd3e1db6774..b0ad17b2fe0b3c13522cdb9dad046e11892bdb65 100644 (file)
@@ -82,10 +82,12 @@ Top Level:
 from collections import namedtuple
 from nmigen import Module, Elaboratable, Signal, Cat, Mux
 from nmigen.cli import rtlil
-from soc.decoder.power_enums import (Function, Form, InternalOp,
-                         In1Sel, In2Sel, In3Sel, OutSel, RC, LdstLen,
-                         CryIn, get_csv, single_bit_flags,
-                         get_signal_name, default_values)
+from soc.decoder.power_enums import (Function, Form, MicrOp,
+                                     In1Sel, In2Sel, In3Sel, OutSel,
+                                     RC, LdstLen, LDSTMode, CryIn, get_csv,
+                                     single_bit_flags, CRInSel,
+                                     CROutSel, get_signal_name,
+                                     default_values, insns, asmidx)
 from soc.decoder.power_fields import DecodeFields
 from soc.decoder.power_fieldsn import SigDecode, SignalBitRange
 
@@ -105,17 +107,28 @@ Subdecoder = namedtuple("Subdecoder",
 
 class PowerOp:
     """PowerOp: spec for execution.  op type (ADD etc.) reg specs etc.
+
+    this is an internal data structure, set up by reading CSV files
+    (which uses _eq to initialise each instance, not eq)
+
+    the "public" API (as far as actual usage as a useful decoder is concerned)
+    is Decode2ToExecute1Type
     """
 
-    def __init__(self):
+    def __init__(self, incl_asm=True):
         self.function_unit = Signal(Function, reset_less=True)
-        self.internal_op = Signal(InternalOp, reset_less=True)
+        self.internal_op = Signal(MicrOp, reset_less=True)
         self.form = Signal(Form, reset_less=True)
+        if incl_asm: # for simulator only
+            self.asmcode = Signal(8, reset_less=True)
         self.in1_sel = Signal(In1Sel, reset_less=True)
         self.in2_sel = Signal(In2Sel, reset_less=True)
         self.in3_sel = Signal(In3Sel, reset_less=True)
         self.out_sel = Signal(OutSel, reset_less=True)
+        self.cr_in = Signal(CRInSel, reset_less=True)
+        self.cr_out = Signal(CROutSel, reset_less=True)
         self.ldst_len = Signal(LdstLen, reset_less=True)
+        self.upd = Signal(LDSTMode, reset_less=True)
         self.rc_sel = Signal(RC, reset_less=True)
         self.cry_in = Signal(CryIn, reset_less=True)
         for bit in single_bit_flags:
@@ -125,17 +138,41 @@ class PowerOp:
     def _eq(self, row=None):
         if row is None:
             row = default_values
+        # TODO: this conversion process from a dict to an object
+        # should really be done using e.g. namedtuple and then
+        # call eq not _eq
+        if False: # debugging
+            if row['CR in'] == '1':
+                import pdb; pdb.set_trace()
+                print(row)
+            if row['CR out'] == '0':
+                import pdb; pdb.set_trace()
+                print(row)
+            print(row)
+        ldst_mode = row['upd']
+        if ldst_mode.isdigit():
+            ldst_mode = LDSTMode(int(ldst_mode))
+        else:
+            ldst_mode = LDSTMode[ldst_mode]
         res = [self.function_unit.eq(Function[row['unit']]),
                self.form.eq(Form[row['form']]),
-               self.internal_op.eq(InternalOp[row['internal op']]),
+               self.internal_op.eq(MicrOp[row['internal op']]),
                self.in1_sel.eq(In1Sel[row['in1']]),
                self.in2_sel.eq(In2Sel[row['in2']]),
                self.in3_sel.eq(In3Sel[row['in3']]),
                self.out_sel.eq(OutSel[row['out']]),
+               self.cr_in.eq(CRInSel[row['CR in']]),
+               self.cr_out.eq(CROutSel[row['CR out']]),
                self.ldst_len.eq(LdstLen[row['ldst len']]),
+               self.upd.eq(ldst_mode),
                self.rc_sel.eq(RC[row['rc']]),
                self.cry_in.eq(CryIn[row['cry in']]),
                ]
+        if False:
+            print (row.keys())
+        asmcode = row['comment']
+        if hasattr(self, "asmcode") and asmcode in asmidx:
+            res.append(self.asmcode.eq(asmidx[asmcode]))
         for bit in single_bit_flags:
             sig = getattr(self, get_signal_name(bit))
             res.append(sig.eq(int(row.get(bit, 0))))
@@ -149,12 +186,17 @@ class PowerOp:
                self.in2_sel.eq(otherop.in2_sel),
                self.in3_sel.eq(otherop.in3_sel),
                self.out_sel.eq(otherop.out_sel),
+               self.cr_in.eq(otherop.cr_in),
+               self.cr_out.eq(otherop.cr_out),
                self.rc_sel.eq(otherop.rc_sel),
                self.ldst_len.eq(otherop.ldst_len),
+               self.upd.eq(otherop.upd),
                self.cry_in.eq(otherop.cry_in)]
         for bit in single_bit_flags:
             sig = getattr(self, get_signal_name(bit))
             res.append(sig.eq(getattr(otherop, get_signal_name(bit))))
+        if hasattr(self, "asmcode"):
+            res.append(self.asmcode.eq(otherop.asmcode))
         return res
 
     def ports(self):
@@ -163,10 +205,14 @@ class PowerOp:
                    self.in2_sel,
                    self.in3_sel,
                    self.out_sel,
+                   self.cr_in,
+                   self.cr_out,
                    self.ldst_len,
                    self.rc_sel,
                    self.internal_op,
                    self.form]
+        if hasattr(self, "asmcode"):
+            regular.append(self.asmcode)
         single_bit_ports = [getattr(self, get_signal_name(x))
                             for x in single_bit_flags]
         return regular + single_bit_ports
@@ -305,12 +351,13 @@ class TopPowerDecoder(PowerDecoder):
     def elaborate(self, platform):
         m = PowerDecoder.elaborate(self, platform)
         comb = m.d.comb
-        raw_be = self.raw_opcode_in
+        # raw opcode in assumed to be in LE order: byte-reverse it to get BE
+        raw_le = self.raw_opcode_in
         l = []
         for i in range(0, self.width, 8):
-            l.append(raw_be[i:i+8])
+            l.append(raw_le[i:i+8])
         l.reverse()
-        raw_le = Cat(*l)
+        raw_be = Cat(*l)
         comb += self.opcode_in.eq(Mux(self.bigendian, raw_be, raw_le))
 
         # add all signal from commonly-used fields
@@ -351,7 +398,7 @@ def create_pdecode():
     pminor = [
         m19,
         Subdecoder(pattern=30, opcodes=get_csv("minor_30.csv"),
-                   opint=True, bitsel=(1, 6), suffix=None, subdecoders=[]),
+                   opint=True, bitsel=(1, 5), suffix=None, subdecoders=[]),
         Subdecoder(pattern=31, opcodes=get_csv("minor_31.csv"),
                    opint=True, bitsel=(1, 11), suffix=0b00101, subdecoders=[]),
         Subdecoder(pattern=58, opcodes=get_csv("minor_58.csv"),