# How to dynamically infer ports?

**URL:** <https://discourse.myhdl.org/t/how-to-dynamically-infer-ports/387>\
**Category:** Support\
**Created:** [July 24, 2019, 5:17pm UTC](https://discourse.myhdl.org/t/how-to-dynamically-infer-ports/387 "2019-07-24T17:17:51Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![ThomasHornschuh](https://yyz2.discourse-cdn.com/flex030/user_avatar/discourse.myhdl.org/thomashornschuh/32/124_2.png) [@ThomasHornschuh](https://discourse.myhdl.org/u/ThomasHornschuh)\
**Post date:** [July 24, 2019, 5:17pm UTC](https://discourse.myhdl.org/t/how-to-dynamically-infer-ports/387/1 "2019-07-24T17:17:51Z")

</div>

I have just started with MyHDL and was able to build a demo ip core with it. [https://github.com/bonfireprocessor/bonfire-pwm](https://github.com/bonfireprocessor/bonfire-pwm)

The project is a simple PWM driver for RGB LEDs with a Wishbone interface.

The only thing I’m struggling with is, that I don’t find a way to dynamically change the top level ports (my target language is VHDL).

The number of LEDs to support is configurable. I want a red, green, blue output port per LED on the VHDL toplevel.

I have not figured out how to do it. I created a class rgb\_bundle

```auto
class rgb_bundle:
    def __init__ (self):
        self.red=Signal(bool(0))
        self.green=Signal(bool(0))
        self.blue=Signal(bool(0))

```

When I create a single Signal instance of it and pass it to my toplevel block it works fine.  
But I want a dynamic number of rgb\_bundles which are mapped to ports.

When I pass a list of rgb\_bundles it is completely ignored.

My current testcode looks like:

```auto
from myhdl import *
from rgb_bundle import *
from bonfire_led_pwm import *
from wishbone_bundle import *
 numChannels=4

wb = Wishbone_bundle(False,4,2,32,False,False)

rgb={}
for i in range(4):
    rgb["rgb_"+str(i)]=rgb_bundle()

clock = Signal(bool(0))
reset = ResetSignal(0, active=1, isasync=False)

@block
def test(wb,clock,reset,rgb_0,rgb_1, **kwagrs):

    @always_seq(clock.posedge,reset=reset)
    def dummy():
        pass

    return instances()
    test_01=test(wb,clock,reset,**rgb)

```

The conversion looks as I want it:

```auto
entity test is
    port (
        clock: in std_logic;
        reset: in std_logic;
        rgb_0_blue: in std_logic;
        rgb_0_green: in std_logic;
        rgb_0_red: in std_logic;
        rgb_1_blue: in std_logic;
        rgb_1_green: in std_logic;
        rgb_1_red: in std_logic;
        wb_we: in std_logic;
        wb_adr: in std_logic_vector(1 downto 0);
        wb_stb: in std_logic;
        wb_ack: in std_logic;
        wb_cyc: in std_logic;
        wb_db_read: in std_logic_vector(31 downto 0);
        wb_db_write: in std_logic_vector(31 downto 0)
    );
end entity test;

```

It works because I have hard coded the parameters rgb\_1 and rgb\_2 for testing purposes, but of course this is not the solution.

I must confess that I’m not proficient in Python.

I hope somebody here can help me.

Thomas

Edit: Fixed the block quotes

---

<div class="post-metadata">

**Author:** ![josyb](https://yyz2.discourse-cdn.com/flex030/user_avatar/discourse.myhdl.org/josyb/32/5_2.png) [@josyb](https://discourse.myhdl.org/u/josyb)\
**Post date:** [July 26, 2019, 7:04am UTC](https://discourse.myhdl.org/t/how-to-dynamically-infer-ports/387/2 "2019-07-26T07:04:36Z")

</div>

Hi Thomas,  
Welcome to the MyHDL community!  
You hit a weak spot. At the moment conversion of a list of Signals is not supported, and by extrapolation, neither is conversion of a list of interfaces.  
@DrPi has a (local) patch for the list of Signals. He creates additional types in a VHDL package.  
However a list of Interfaces, as you like to have, takes further effort.  
Regards,  
Josy

---

<div class="post-metadata">

**Author:** ![hgomersall](https://yyz2.discourse-cdn.com/flex030/user_avatar/discourse.myhdl.org/hgomersall/32/10_2.png) [@hgomersall](https://discourse.myhdl.org/u/hgomersall)\
**Post date:** [July 26, 2019, 9:28am UTC](https://discourse.myhdl.org/t/how-to-dynamically-infer-ports/387/3 "2019-07-26T09:28:19Z")

</div>

Yeah, this is a limitation. It’s actually non trivial IMO because you end up with all sorts of potential naming corner cases. The real problem is the lack of support for rich semantics in V\* that make them poor IRs.

Interestingly, I suspect there is a work around for this using python meta-programming like approaches. Where you effectively create the correct function at run time based on the list - that is you expand out the list at elaboration time. This is potentially a bit flaky because the conversion code tends to look at the code, not the objects.

---

<div class="post-metadata">

**Author:** ![ThomasHornschuh](https://yyz2.discourse-cdn.com/flex030/user_avatar/discourse.myhdl.org/thomashornschuh/32/124_2.png) [@ThomasHornschuh](https://discourse.myhdl.org/u/ThomasHornschuh)\
**Post date:** [July 26, 2019, 4:43pm UTC](https://discourse.myhdl.org/t/how-to-dynamically-infer-ports/387/4 "2019-07-26T16:43:17Z")

</div>

Thanks for you quick answers. It is a bit unfortunate, because dynamically configurable toplevel ports was one of the problems I hoped to solve with MyHDL. So regarding configuration it currently does not go far beyond the possibilities of VHDL generic/generate.

Nevertheless with my first experiment I found a lot of things I like:

- Much less boilerplate and redundant coding
- No generic needed for the sole purpose of configurable bit length
- Interfaces, which also save a lot of redundant typing
- The possibility to encapsulate more then one block in a single Python module, so it allows to create libraries
- Simulation
- Signals semantics like in VHDL

On the other side the limitations of conversion create a steep learning curve, I spent much more time with getting my code converted to VHDL than getting it correctly simulated.

I’m also struggling with finding a way to write test benches which work well in MyHDL and can be converted to VHDL/Verilog. I will write an extra post for this topic.

---

<div class="post-metadata">

**Author:** ![hgomersall](https://yyz2.discourse-cdn.com/flex030/user_avatar/discourse.myhdl.org/hgomersall/32/10_2.png) [@hgomersall](https://discourse.myhdl.org/u/hgomersall)\
**Post date:** [July 27, 2019, 12:20pm UTC](https://discourse.myhdl.org/t/how-to-dynamically-infer-ports/387/5 "2019-07-27T12:20:37Z")

</div>

I’ve done quite a bit of work on convertible tests. Much of this is in [veriutils](https://github.com/hgomersall/Veriutils).

---

<div class="post-metadata">

**Author:** ![DrPi](https://yyz2.discourse-cdn.com/flex030/user_avatar/discourse.myhdl.org/drpi/32/36_2.png) [@DrPi](https://discourse.myhdl.org/u/DrPi)\
**Post date:** [July 29, 2019, 1:47pm UTC](https://discourse.myhdl.org/t/how-to-dynamically-infer-ports/387/6 "2019-07-29T13:47:16Z")

</div>

Hi,  
Creating a PR for lists in ports is on my high priority TODO list.  
Will do ASAP.

---

<div class="post-metadata">

**Author:** ![DrPi](https://yyz2.discourse-cdn.com/flex030/user_avatar/discourse.myhdl.org/drpi/32/36_2.png) [@DrPi](https://discourse.myhdl.org/u/DrPi)\
**Post date:** [August 1, 2019, 2:34pm UTC](https://discourse.myhdl.org/t/how-to-dynamically-infer-ports/387/7 "2019-08-01T14:34:51Z")

</div>

My PR is waiting for approval/merge.
