Creating a group of Signals

Is there a recommended MyHDL way to create a group of Signals?

In Python, I can declare a bunch of empty lists as:

a,b,c = [],[],[]


a,b,c = [0]*16,[0]*8,[0,1,2]

Is there a more concise way in Python to declare a bunch of lists?

(I have also used list comprehensions, and dedicated classes to do it, and am just looking for a more terse way to do it.)

In Verilog I might do something like:

wire [31:0] a, b, c, d, e;


input [7:0] in1, in2 , etc.

In C++, I might model this using instances of a class Wire like:

Wire32 a, b, c;

In Python, if I were to use a class approach, one approach might be:

    a = Wire32() 
    b = Wire32() 
    c = Wire32() 

which seems a bit verbose to me. It gets even more complex when passing through MyHDL blocks. Still, I’m hoping this might be a reasonable simplification of the use case that might lead to relevant creative solutions.

My current solution is:

a,b,c = [Wire(32) for i in range(3) ]

I do not like a couple things about this solution:

1.  I have to count the number of elements which is cumbersome and error-prone
2.  The definition is after the list which is unfamiliar to the "customer" who will likely be a hw engineer familiar with Verilog

(This is a duplicate of a Stack Overflow question that is currently unanswered: python - Is there a more terse way to create a group of empty lists? - Stack Overflow )

I also found some information on creating MyHDL “Structures” of signals which could be a solution, but still having trouble wrapping my arms around it.

Here is an example of a post on interfaces that may lead to a good solution:

I’m sure there are other ways of creating classes to try create complex types, and then overload the operators, etc. for readability.

As always, thank you for your help as I try to learn the best practices in MyHDL!

My two pennies …
1. using a,b,c = [Signal(xxx) for __ in range(y)] is what most MyHDL users will do. This creates a number of Signals of the same type and size.
I personally only use this about once in every module. As you indicate one must keep count of the numbers, and this goes wrong at least once per day.
As I use descriptive (sometimes long) names I prefer the singular notation pixelcountersclr = Signal(bool(0); it is just easier to re-read if you put each one on its own line
I build structural class-based designs where there are less glue signals needed.

2. IMO will be less of a concern - the Verilog (or VHDL) engineer will learn.

Thanks again @Josyb–I agree with your points and feel better about moving on, now. Do you have any examples of the structures you mentioned?

For creating lists of signals, there’s not much freedom beside what you’ve already tried.
Obviously, the very compact n * [ element ] attempt will create a list of n references to element, thus ‘no such fun’ with mutable (!) Signals.
The other native pythonic method is the MEP-107 one (Conversion of Interfaces), based on that you can write your own class factories taking some compact bulk signal descriptor as a dict, etc. This does not infer to an interface in the VHDL-2019 sense though, myhdl guesses in/output direction based on assignment of the member Signal and unrolls into single signals in the port description.

The meta-programming approach with the fancy operator overloading will however not just magically work with conversion to HDL, because the code is translated via AST-analysis. So, again ‘no such fun’ with generators (such as bulk signal assignments using .next), unless you’re in the executed part of your HDL @block (outside the @always* functions). And there you’re limited to generating instances and signals, mostly.

Thank you so much, @hackfin

Do you have any examples of your code I can peruse for best practices?

Put up a jupyter NB here: myhdl_class_inheritance.ipynb · GitHub
It might be outdated but I’ve just run it against a recent myhdl 0.11 w/o unexpected issues. Should also upload and run in a jupyterhub binder, as GitHub - hackfin/hdlplayground: Document, build and simulate hardware designs (MyHDL, VHDL, Verilog).

Should also mention that the blackbox stuff was an experiment, so you may ignore that for the time being. A fully functional design would require to add some HW description for the UUT in this example.