MyHDL

Unexpected signal name in converted VHDL

Hi, when converting my Design to VHDL I get unexpected results.

I have defined an interface:

# Wishbone Bus interface bundle

from myhdl import *

class Wishbone_bundle:
    def __init__(self,master,adrHigh,adrLow,dataWidth,b4_signals,bte_signals):
        self.cyc = Signal(bool(0))
        self.stb = Signal(bool(0))
        self.ack = Signal(bool(0))
        self.we =  Signal(bool(0))
        self.adr = Signal(intbv(0)[adrHigh:adrLow])
        self.db_write = Signal(intbv(0)[dataWidth:])
        self.db_read =  Signal(intbv(0)[dataWidth:])

My “conversion” toplevel looks like this:

from myhdl import *
from bonfire_led_pwm import *
from wishbone_bundle import *

numChannels=4



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

red_v=Signal(intbv(0)[numChannels:])
green_v=Signal(intbv(0)[numChannels:])
blue_v=Signal(intbv(0)[numChannels:])

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

bonfire_led_pwm_top = bonfire_led_pwm(wb,red_v,green_v,blue_v,clock,reset,numChannels,sim=False)

bonfire_led_pwm_top.convert(hdl='VHDL',std_logic_ports=True,path='vhdl')

The VHDL output looks like this:

....
entity bonfire_led_pwm is
    port (
        red_v: out std_logic_vector(3 downto 0);
        green_v: out std_logic_vector(3 downto 0);
        blue_v: out std_logic_vector(3 downto 0);
        clock: in std_logic;
        reset: in std_logic;
        wb_bus_we: in std_logic;
        wb_bus_adr: in std_logic_vector(1 downto 0);
        wb_bus_stb: in std_logic;
        wb_bus_ack: out std_logic;
        wb_bus_cyc: in std_logic;
        wb_bus_db_read: out std_logic_vector(31 downto 0);
        rgb_pwm0_bus_in: in std_logic_vector(31 downto 0) -- This should be wb_bus_db_write ...
    );
end entity bonfire_led_pwm;
....

rgb_pwm is a lower level module, finally the one which “consumes” the db_write signal because it contains the registers. I have not quoted it here for space reasons, but you can find the entire project here: https://github.com/bonfireprocessor/bonfire-pwm

It seems to be caused by the fact, that the signal db_write is never used directly, only slices of it are used over a shadow signal. “bus_in” is the parameter name of a lower-level block:

@block
def rgb_pwm(we, bus_in,bus_out,red_o,green_o,blue_o,cnt_en,clock,reset):


    # Bus out slices
    red_bus_out=Signal(intbv(0)[8:])
    green_bus_out=Signal(intbv(0)[8:])
    blue_bus_out=Signal(intbv(0)[8:])


    red_ch=pwm(we,bus_in(24,16),red_bus_out,red_o, cnt_en,clock,reset,8)
    green_ch=pwm(we,bus_in(16,8),green_bus_out,green_o,cnt_en,clock,reset,8)
    blue_ch=pwm(we,bus_in(8,0),blue_bus_out,blue_o,cnt_en,clock,reset,8)

    @always_comb
    def bus_concat():
        bus_out.next=concat(red_bus_out,green_bus_out,blue_bus_out)


    return instances()

The “caller” passes wb_bus.db_write to the bus_in parameter.

As a workaround I have added an intermediate signal to the outside block:

.....
db_write=Signal(intbv(0)[32:])
....
 @always_comb
    def bus_comb():
....
    db_write.next=wb_bus.db_write

When I work like this, the toplevel port name is correctly named wb_bus_db_write. The name of the temporary signal does not matter, the reason for the naming problem seems to be the sole use of wb_bus.db_write as source for a shadow signal.

I’m using MyHDL 0.11 with Python 2.7.12

Thomas

Hi,
This is the way it works.
From what I understand, this is due to the compilation made by Python when executing the code to convert.
Your workaround is currently the only solution.

I think this can be helped:
in conversion/_analyze.py in function expandinterface remove the if-condition to keep the already assigned signal name in stead of setting it to the expanded interface signal name;

#             signame = attrobj._name
#             if not signame:
        signame = name + '_' + attr
        attrobj._name = signame

I have this in my local MyHDL code, and haven’t seen a conflict yet …

Regards,
Josy

I will give it a try in the next days.
Thank you very much.

Thomas

Works:

entity bonfire_led_pwm_core is
    port (
        gpio_o: out std_logic_vector(11 downto 0);
        clock: in std_logic;
        reset: in std_logic;
        wb_we: in std_logic;
        wb_adr: in std_logic_vector(2 downto 0);
        wb_stb: in std_logic;
        wb_ack: out std_logic;
        wb_cyc: in std_logic;
        wb_db_read: out std_logic_vector(31 downto 0);
        wb_db_write: in std_logic_vector(31 downto 0)
    );
end entity bonfire_led_pwm_core;

Thomas