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
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:
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))))
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):
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
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
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"),