From 16b722c728f54ca4f76eabba0351e7daca5fb216 Mon Sep 17 00:00:00 2001 From: Michael Nolan Date: Wed, 4 Mar 2020 10:31:15 -0500 Subject: [PATCH] Hierarchial decoder semi-working --- src/decoder/power_decoder.py | 45 +++++++++++++++++++------- src/decoder/test/test_power_decoder.py | 32 +++++++++++------- 2 files changed, 53 insertions(+), 24 deletions(-) diff --git a/src/decoder/power_decoder.py b/src/decoder/power_decoder.py index 46de6170..dcfe7a97 100644 --- a/src/decoder/power_decoder.py +++ b/src/decoder/power_decoder.py @@ -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) diff --git a/src/decoder/test/test_power_decoder.py b/src/decoder/test/test_power_decoder.py index fdb17847..18686714 100644 --- a/src/decoder/test/test_power_decoder.py +++ b/src/decoder/test/test_power_decoder.py @@ -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): -- 2.30.2