From 415a4e84d907f11485d0410c16f9655a10a5d75d Mon Sep 17 00:00:00 2001 From: Luke Kenneth Casson Leighton Date: Mon, 8 Jun 2020 22:56:47 +0100 Subject: [PATCH] rework example slightly --- Documentation/SOC/index.mdwn | 51 ++++++++++++++++++++++-------------- 1 file changed, 32 insertions(+), 19 deletions(-) diff --git a/Documentation/SOC/index.mdwn b/Documentation/SOC/index.mdwn index 24ccdc85a..2be3f4466 100644 --- a/Documentation/SOC/index.mdwn +++ b/Documentation/SOC/index.mdwn @@ -1,18 +1,23 @@ -The SOC is designed to be compliant with POWER 3.0B with somewhere near 300 instructions excluding Vector instructions. +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 signals who's values get set respectively for each instruction. +The Decoder currently uses a class called PowerOp which get instantiated +for every instruction. PowerOp class instantiation has member signals +whose values get set respectively for each instruction. -We use Pythons Enums to help with common decoder values. +We use Python 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 to the correct values for the add instruction when select==1 is set. -This should give you a feel for how we work with enums and PowerOP. +Here is an example of a toy multiplexer that sets various fields in the +PowerOP signal class to the correct values for the add instruction when +select is set equal to 1. This should give you a feel for how we work with +enums and PowerOP. from nmigen import Module, Elaboratable, Signal, Cat, Mux from soc.decoder.power_enums import (Function, Form, InternalOp, @@ -25,7 +30,7 @@ This should give you a feel for how we work with enums and PowerOP. class Op_Add_Example(Elaboratable): def __init__(self): - self.select = Signal() + self.select = Signal(reset_less=True) self.op_add = PowerOp() def elaborate(self, platform): @@ -33,16 +38,16 @@ This should give you a feel for how we work with enums and PowerOP. 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']) + 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) return m @@ -50,12 +55,20 @@ This should give you a feel for how we work with enums and PowerOP. 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()) + 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}") The [actual POWER9 Decoder](https://git.libre-soc.org/?p=soc.git;a=blob;f=src/soc/decoder/power_decoder2.py;hb=HEAD) -uses this principle, in conjunction with reading the information shown in the table above, from CSV files as opposed to hardcoding them in python source. +uses this principle, in conjunction with reading the information shown +in the table above from CSV files (as opposed to hardcoding them in +python source). These CSV files, being machine-readable in a wide variety +of programming languages, are therefore much more convenient for use by +other projects beyond this SOC. -This demonstrates one of the design aspects taken in this project: to *combine* the power of python's full capabilities in order to create advanced dynamically generated HDL, rather than (as done with MyHDL) limit python code to a subset of its full capabilities. +This also demonstrates one of the design aspects taken in this project: to +*combine* the power of python's full capabilities in order to create +advanced dynamically generated HDL, rather than (as done with MyHDL) +limit python code to a subset of its full capabilities. -- 2.30.2