From 8513cb62c63d128eb6ca71cd921c50929758325c Mon Sep 17 00:00:00 2001 From: Michael Nolan Date: Sat, 29 Feb 2020 14:23:53 -0500 Subject: [PATCH] Begin adding power ISA decoder --- src/decoder/decoder.py | 36 ++++++++++++++++++++++++++++ src/decoder/major.csv | 35 +++++++++++++++++++++++++++ src/decoder/test/test_decoder.py | 41 ++++++++++++++++++++++++++++++++ 3 files changed, 112 insertions(+) create mode 100644 src/decoder/decoder.py create mode 100644 src/decoder/major.csv create mode 100644 src/decoder/test/test_decoder.py diff --git a/src/decoder/decoder.py b/src/decoder/decoder.py new file mode 100644 index 00000000..65aa3338 --- /dev/null +++ b/src/decoder/decoder.py @@ -0,0 +1,36 @@ +from nmigen import Module, Elaboratable, Signal +import csv +import os +from enum import Enum, unique + +class Function(Enum): + ALU = 0 + LDST = 1 + +def get_csv(name): + file_dir = os.path.dirname(os.path.realpath(__file__)) + with open(os.path.join(file_dir, name)) as csvfile: + reader = csv.DictReader(csvfile) + return list(reader) + +major_opcodes = get_csv("major.csv") + +class PowerDecoder(Elaboratable): + def __init__(self): + self.opcode_in = Signal(6, reset_less=True) + + self.function_unit = Signal(Function, reset_less=True) + def elaborate(self, platform): + m = Module() + comb = m.d.comb + + with m.Switch(self.opcode_in): + for row in major_opcodes: + opcode = int(row['opcode']) + with m.Case(opcode): + comb += self.function_unit.eq(Function[row['unit']]) + return m + + + + diff --git a/src/decoder/major.csv b/src/decoder/major.csv new file mode 100644 index 00000000..f58784a6 --- /dev/null +++ b/src/decoder/major.csv @@ -0,0 +1,35 @@ +opcode,unit,internal op,in1,in2,in3,out,CR in,CR out,inv A,inv out,cry in,cry out,ldst len,BR,sgn ext,upd,rsrv,32b,sgn,rc,lk,sgl pipe +12,ALU,OP_ADD,RA,CONST_SI,NONE,RT,0,0,0,0,ZERO,1,NONE,0,0,0,0,0,0,NONE,0,0,addic +13,ALU,OP_ADD,RA,CONST_SI,NONE,RT,0,0,0,0,ZERO,1,NONE,0,0,0,0,0,0,ONE,0,0,addic. +14,ALU,OP_ADD,RA_OR_ZERO,CONST_SI,NONE,RT,0,0,0,0,ZERO,0,NONE,0,0,0,0,0,0,NONE,0,0,addi +15,ALU,OP_ADD,RA_OR_ZERO,CONST_SI_HI,NONE,RT,0,0,0,0,ZERO,0,NONE,0,0,0,0,0,0,NONE,0,0,addis +28,ALU,OP_AND,NONE,CONST_UI,RS,RA,0,0,0,0,ZERO,0,NONE,0,0,0,0,0,0,ONE,0,0,andi. +29,ALU,OP_AND,NONE,CONST_UI_HI,RS,RA,0,0,0,0,ZERO,0,NONE,0,0,0,0,0,0,ONE,0,0,andis. +18,ALU,OP_B,NONE,CONST_LI,NONE,NONE,0,0,0,0,ZERO,0,NONE,0,0,0,0,0,0,NONE,1,0,b +16,ALU,OP_BC,SPR,CONST_BD,NONE,SPR,1,0,0,0,ZERO,0,NONE,0,0,0,0,0,0,NONE,1,0,bc +11,ALU,OP_CMP,RA,CONST_SI,NONE,NONE,0,1,1,0,ONE,0,NONE,0,0,0,0,0,1,NONE,0,0,cmpi +10,ALU,OP_CMP,RA,CONST_UI,NONE,NONE,0,1,1,0,ONE,0,NONE,0,0,0,0,0,0,NONE,0,0,cmpli +34,LDST,OP_LOAD,RA_OR_ZERO,CONST_SI,NONE,RT,0,0,0,0,ZERO,0,is1B,0,0,0,0,0,0,NONE,0,1,lbz +35,LDST,OP_LOAD,RA_OR_ZERO,CONST_SI,NONE,RT,0,0,0,0,ZERO,0,is1B,0,0,1,0,0,0,NONE,0,1,lbzu +42,LDST,OP_LOAD,RA_OR_ZERO,CONST_SI,NONE,RT,0,0,0,0,ZERO,0,is2B,0,1,0,0,0,0,NONE,0,1,lha +43,LDST,OP_LOAD,RA_OR_ZERO,CONST_SI,NONE,RT,0,0,0,0,ZERO,0,is2B,0,1,1,0,0,0,NONE,0,1,lhau +40,LDST,OP_LOAD,RA_OR_ZERO,CONST_SI,NONE,RT,0,0,0,0,ZERO,0,is2B,0,0,0,0,0,0,NONE,0,1,lhz +41,LDST,OP_LOAD,RA_OR_ZERO,CONST_SI,NONE,RT,0,0,0,0,ZERO,0,is2B,0,0,1,0,0,0,NONE,0,1,lhzu +32,LDST,OP_LOAD,RA_OR_ZERO,CONST_SI,NONE,RT,0,0,0,0,ZERO,0,is4B,0,0,0,0,0,0,NONE,0,1,lwz +33,LDST,OP_LOAD,RA_OR_ZERO,CONST_SI,NONE,RT,0,0,0,0,ZERO,0,is4B,0,0,1,0,0,0,NONE,0,1,lwzu +7,ALU,OP_MUL_L64,RA,CONST_SI,NONE,RT,0,1,0,0,ZERO,0,NONE,0,0,0,0,0,1,NONE,0,0,mulli +24,ALU,OP_OR,NONE,CONST_UI,RS,RA,0,0,0,0,ZERO,0,NONE,0,0,0,0,0,0,NONE,0,0,ori +25,ALU,OP_OR,NONE,CONST_UI_HI,RS,RA,0,0,0,0,ZERO,0,NONE,0,0,0,0,0,0,NONE,0,0,oris +20,ALU,OP_RLC,RA,CONST_SH32,RS,RA,0,0,0,0,ZERO,0,NONE,0,0,0,0,1,0,RC,0,0,rlwimi +21,ALU,OP_RLC,NONE,CONST_SH32,RS,RA,0,0,0,0,ZERO,0,NONE,0,0,0,0,1,0,RC,0,0,rlwinm +23,ALU,OP_RLC,NONE,RB,RS,RA,0,0,0,0,ZERO,0,NONE,0,0,0,0,1,0,RC,0,0,rlwnm +38,LDST,OP_STORE,RA_OR_ZERO,CONST_SI,RS,NONE,0,0,0,0,ZERO,0,is1B,0,0,0,0,0,0,RC,0,1,stb +39,LDST,OP_STORE,RA_OR_ZERO,CONST_SI,RS,NONE,0,0,0,0,ZERO,0,is1B,0,0,1,0,0,0,RC,0,1,stbu +44,LDST,OP_STORE,RA_OR_ZERO,CONST_SI,RS,NONE,0,0,0,0,ZERO,0,is2B,0,0,0,0,0,0,NONE,0,1,sth +45,LDST,OP_STORE,RA_OR_ZERO,CONST_SI,RS,NONE,0,0,0,0,ZERO,0,is2B,0,0,1,0,0,0,NONE,0,1,sthu +36,LDST,OP_STORE,RA_OR_ZERO,CONST_SI,RS,NONE,0,0,0,0,ZERO,0,is4B,0,0,0,0,0,0,NONE,0,1,stw +37,LDST,OP_STORE,RA_OR_ZERO,CONST_SI,RS,NONE,0,0,0,0,ZERO,0,is4B,0,0,1,0,0,0,NONE,0,1,stwu +8,ALU,OP_ADD,RA,CONST_SI,NONE,RT,0,0,1,0,ONE,1,NONE,0,0,0,0,0,0,NONE,0,0,subfic +2,ALU,OP_TDI,RA,CONST_SI,NONE,NONE,0,0,0,0,ZERO,0,NONE,0,0,0,0,0,0,NONE,0,1,tdi +26,ALU,OP_XOR,NONE,CONST_UI,RS,RA,0,0,0,0,ZERO,0,NONE,0,0,0,0,0,0,NONE,0,0,xori +27,ALU,OP_XOR,NONE,CONST_UI_HI,RS,RA,0,0,0,0,ZERO,0,NONE,0,0,0,0,0,0,NONE,0,0,xoris diff --git a/src/decoder/test/test_decoder.py b/src/decoder/test/test_decoder.py new file mode 100644 index 00000000..37faddd1 --- /dev/null +++ b/src/decoder/test/test_decoder.py @@ -0,0 +1,41 @@ +from nmigen import Module, Elaboratable, Signal +from nmigen.back.pysim import Simulator, Delay, Settle +from nmigen.test.utils import FHDLTestCase +from nmigen.cli import rtlil +import sys +import unittest +sys.path.append("../") +from decoder import PowerDecoder, Function, major_opcodes + +class DecoderTestCase(FHDLTestCase): + def test_function_unit(self): + m = Module() + comb = m.d.comb + opcode = Signal(6) + function_unit = Signal(Function) + + m.submodules.dut = dut = PowerDecoder() + comb += [dut.opcode_in.eq(opcode), + function_unit.eq(dut.function_unit)] + + sim = Simulator(m) + def process(): + for row in major_opcodes: + yield opcode.eq(int(row['opcode'])) + yield Delay(1e-6) + result = yield function_unit + expected = Function[row['unit']].value + self.assertEqual(expected, result) + sim.add_process(process) + with sim.write_vcd("test.vcd", "test.gtkw", traces=[opcode, function_unit]): + sim.run() + + def test_ilang(self): + dut = PowerDecoder() + vl = rtlil.convert(dut, ports=[dut.opcode_in, dut.function_unit]) + with open("power_decoder.il", "w") as f: + f.write(vl) + +if __name__ == "__main__": + unittest.main() + -- 2.30.2