The SOC is designed to be compliant with POWER 3.0B with somewhere near 300 instructions excluding Vector instructions.
+
+# Decoder
+
+The Decoder currently uses a class called PowerOp which get instantiated for every instruction. PowerOp class instantiation has member objects who's values get set respectively for each instruction.
+
+We use Pythons Enums to help with common decoder values.
+Below is the POWER add insruction.
+
+| 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 | comment | form |
+|--------------|------|-------------|-----|-----|------|-----|-------|--------|-------|---------|--------|---------|----------|----|---------|-----|------|-----|-----|----|----|----------|---------|------|
+| 0b0100001010 | ALU | OP_ADD | RA | RB | NONE | RT | 0 | 0 | 0 | 0 | ZERO | 0 | NONE | 0 | 0 | 0 | 0 | 0 | 0 | RC | 0 | 0 | add | XO |
+
+Here is an example of a toy multiplexer that sets various fields in the PowerOP signal class when 1 is set.
+
+ from nmigen import Module, Elaboratable, Signal, Cat, Mux
+ 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_fields import DecodeFields
+ from soc.decoder.power_fieldsn import SigDecode, SignalBitRange
+ from soc.decoder.power_decoder import PowerOp
+
+ class Op_Add_Example(Elaboratable):
+ def __init__(self):
+ self.select = Signal()
+ self.op_add = PowerOp()
+
+ def elaborate(self, platform):
+ m = Module()
+ op_add = self.op_add
+
+ with m.If(self.select == 1):
+ m.d.comb += op_add.function_unit.eq(Function['ALU'])
+ m.d.comb += op_add.form.eq(Form['XO'])
+ m.d.comb += op_add.internal_op.eq(InternalOp['OP_ADD'])
+ m.d.comb += op_add.in1_sel.eq(In1Sel['RA'])
+ m.d.comb += op_add.in2_sel.eq(In2Sel['RB'])
+ m.d.comb += op_add.in3_sel.eq(In3Sel['NONE'])
+ m.d.comb += op_add.out_sel.eq(OutSel['RT'])
+ m.d.comb += op_add.rc_sel.eq(RC['RC'])
+ m.d.comb += op_add.ldst_len.eq(LdstLen['NONE'])
+ m.d.comb += op_add.cry_in.eq(CryIn['ZERO'])
+
+ with m.Else():
+ m.d.comb += op_add.function_unit.eq(0)
+ m.d.comb += op_add.form.eq(0)
+ m.d.comb += op_add.internal_op.eq(0)
+ m.d.comb += op_add.in1_sel.eq(0)
+ m.d.comb += op_add.in2_sel.eq(0)
+ m.d.comb += op_add.in3_sel.eq(0)
+ m.d.comb += op_add.out_sel.eq(0)
+ m.d.comb += op_add.rc_sel.eq(0)
+ m.d.comb += op_add.ldst_len.eq(0)
+ m.d.comb += op_add.cry_in.eq(0)
+
+ return m
+
+ from nmigen.back import verilog
+ verilog_file = "op_add_example.v"
+ top = Op_Add_Example()
+ f = open(verilog_file, "w")
+ verilog = verilog.convert(top, name='top', strip_internal_attrs=True, ports= top.op_add.ports())
+ f.write(verilog)
+ print(f"Verilog Written to: {verilog_file}")