res.append(sig.eq(int(row.get(bit, 0))))
return res
+ def eq(self, otherop):
+ res = [self.function_unit.eq(otherop.function_unit),
+ self.internal_op.eq(otherop.internal_op),
+ self.in1_sel.eq(otherop.in1_sel),
+ self.in2_sel.eq(otherop.in2_sel),
+ self.in3_sel.eq(otherop.in3_sel),
+ self.out_sel.eq(otherop.out_sel),
+ self.rc_sel.eq(otherop.rc_sel),
+ self.ldst_len.eq(otherop.ldst_len),
+ 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))))
+ return res
+
def ports(self):
regular = [self.function_unit,
self.in1_sel,
"""PowerDecoder - decodes an incoming opcode into the type of operation
"""
- def __init__(self, width, csvname, opint=True):
- self.opint = opint # true if the opcode needs to be converted to int
- self.opcodes = get_csv(csvname)
+ def __init__(self, width, opcodes, 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)
self.op = PowerOp()
+ self.suffix = suffix
+ self.width = width
+
+ def suffix_mask(self):
+ return ((1 << self.suffix[1]) - 1) - ((1 << self.suffix[0]) - 1)
+
+ def divide_opcodes(self):
+ divided = {}
+ mask = self.suffix_mask()
+ for row in self.opcodes:
+ opcode = row['opcode']
+ if self.opint:
+ opcode = int(opcode, 0)
+ key = opcode & mask >> (self.suffix[0])
+ opcode = opcode >> self.suffix[1]
+ if key not in divided:
+ divided[key] = []
+ r = row.copy()
+ r['opcode'] = opcode
+ divided[key].append(r)
+ return divided
def elaborate(self, platform):
m = Module()
comb = m.d.comb
- with m.Switch(self.opcode_in):
- for row in self.opcodes:
- opcode = row['opcode']
- if self.opint:
- opcode = int(opcode, 0)
- if not row['unit']:
- continue
- print ("opcode", opcode)
- 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)
+ 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:
+ 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()
# 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)
+# 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)
from power_decoder import (PowerDecoder)
from power_enums import (Function, InternalOp, In1Sel, In2Sel, In3Sel,
OutSel, RC, LdstLen, CryIn, single_bit_flags,
- get_signal_name)
+ get_signal_name, get_csv)
class DecoderTestCase(FHDLTestCase):
- def run_test(self, width, csvname, opint=True):
+ def run_test(self, width, csvname, suffix=None, opint=True):
m = Module()
comb = m.d.comb
opcode = Signal(width)
ldst_len = Signal(LdstLen)
cry_in = Signal(CryIn)
- m.submodules.dut = dut = PowerDecoder(width, csvname, opint)
+ opcodes = get_csv(csvname)
+ m.submodules.dut = dut = PowerDecoder(width, opcodes, opint, suffix=suffix)
comb += [dut.opcode_in.eq(opcode),
function_unit.eq(dut.op.function_unit),
in1_sel.eq(dut.op.in1_sel),
in1_sel, in2_sel]):
sim.run()
- def generate_ilang(self, width, csvname, opint=True):
+ def generate_ilang(self, width, csvname, opint=True, suffix=None):
prefix = os.path.splitext(csvname)[0]
- dut = PowerDecoder(width, csvname, opint)
+ dut = PowerDecoder(width, get_csv(csvname), opint, suffix=suffix)
vl = rtlil.convert(dut, ports=dut.ports())
with open("%s_decoder.il" % prefix, "w") as f:
f.write(vl)
self.run_test(6, "major.csv")
self.generate_ilang(6, "major.csv")
- def test_minor_19(self):
- self.run_test(3, "minor_19.csv")
- self.generate_ilang(3, "minor_19.csv")
+ # def test_minor_19(self):
+ # self.run_test(3, "minor_19.csv")
+ # self.generate_ilang(3, "minor_19.csv")
def test_minor_30(self):
self.run_test(4, "minor_30.csv")
self.generate_ilang(4, "minor_30.csv")
def test_minor_31(self):
- self.run_test(10, "minor_31.csv")
- self.generate_ilang(10, "minor_31.csv")
+ self.run_test(10, "minor_31.csv", suffix=(0, 5))
+ self.generate_ilang(10, "minor_31.csv", suffix=(0, 5))
- def test_minor_31(self):
+ def test_extra(self):
self.run_test(32, "extra.csv", False)
self.generate_ilang(32, "extra.csv", False)