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