rework example slightly
authorLuke Kenneth Casson Leighton <lkcl@lkcl.net>
Mon, 8 Jun 2020 21:56:47 +0000 (22:56 +0100)
committerLuke Kenneth Casson Leighton <lkcl@lkcl.net>
Mon, 8 Jun 2020 21:56:47 +0000 (22:56 +0100)
Documentation/SOC/index.mdwn

index 24ccdc85a28dd26373b2e9d91bd920cdb728b135..2be3f446611da001eb6ff16caefaad880941439a 100644 (file)
@@ -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.