phanrahan/magma

[RFC] Mantle Style Conventions

Closed this issue · 2 comments

I have am close to finishing a first pass on the low-level primitives for the ice40.

I wanted to get comments on my coding conventions since I would like to be consistent throughout Mantle.

  1. I have replaced all the DeclareCircuits with subclassing Circuit. I have also used this style for circuit with fixed inputs and outputs and fixed topology. These circuits can still be passed parameters when they are instantiated. A good example is ice40/PLB.py.

  2. I have been using function calls as an aid to create more intuitive arguments for instances. A good example is FF.py where the function chooses amongst all the various types of DFFs using flags such as has_enable. These functions often use an AnonymousCircuit to wire up constants to inputs or to handle different IO structures. These functions may also instantiate a few simple sub-circuits. For example, see the TFF example. In a sense, these functions inline the circuits and do not create new circuits.

I haven't been using Generators at this level, but I imagine I could. For example, TFF could be a Circuit.

The use of the Circuit subclass looks good.

I would avoid import * https://github.com/phanrahan/mantle2/blob/main/mantle/lattice/ice40/DFF.py#L2 since it can sometimes lead to confusing issues with name collisions (could either import the dff names epxlicitly or import the plb module and reference them from that namespace).

For function calls versus generators, I think this is a choice that's up to the user. For simpler structures, "inlining" the implementations (using a function rather than generator) can be useful for various reasons. In the generated code, the lack of hierarchy might promote optimizations without needing flattening, it can also be easier to read/debug since the logic is there rather than requiring looking up the instance definition. On the other hand, wrapping things in a separate definition can be good for the same reasons modularity is good in general. E.g. if a fairly complex structure is repeated, it may be better to use instances of a single definition rather than replicating the logic in all instances. This can also be useful for pattern matching, finding instances of a module rather than specific structure patterns.

I'm removing all the import * from my code.