MyHDL

Conversion naming issue

In the following code:

      def block_connect(self, pars, reset, clk, pipe_inpA, pipe_inpB, pipe_out_activ):
        ...
        < some code>
        ...
        ...
        @always_comb
        def shiftOperand_signal():
          shiftEn_i.next = 1 if  (pipe_inpA.valid == 1 and pipe_inpB.valid == 1) else 0

        inpAData=(operand_a.block_connect(pars, reset, clk, pipe_inpA, pipe_outA, ioA)) 

When i convert the following code to verilog, i see that the signal name in the entity is not uniform (please see the valid signal).

Converted verilog:

module lr_top (
    reset,
    clk,
    pipe_inpA_valid,
    inpAData_data_din1, // expected pipe_inpA_data
    inpAData_sop_din1, // expected pipe_inpA_sop
    ...
    ...

Why does the conversion creates signal names which are not matching the passed signals?
How can this be solved?

Can you please provide a complete simple example ?

Hello,
Here is a simple example which creates weird namings.

#!/usr/bin/python3 

from myhdl import Signal, intbv, toVerilog, instances, always_comb

def conditional_wire_assign(dout, condition, din1, din2):
  @always_comb
  def conditional_wire_assign_process():
    dout.next = din1 if (condition == 1) else din2
  return instances() 

class stimulus():
  def __init__(self):
    self.data = Signal(intbv(0)[32:])
    self.valid  = Signal(bool(0))
          
class mainblk():
  def block_connect(self,reset,clk,inpa):
    shift2=Signal(bool(1)) 
    op=stimulus() 
    
    valid=(conditional_wire_assign(op.valid, shift2, inpa.valid, 0)) 
    data=(conditional_wire_assign(op.data, shift2, inpa.data, 0)) 
  
    return instances()

class testblk():
  def test_top(self,reset,clk,inpa):
    shift1=Signal(bool(0))  
    
    @always_comb
    def shift1_process():
      shift1.next = 1 if  (inpa.valid == 1) else 0
   
    testMain=mainblk()
    inpConnect=(testMain.block_connect(reset, clk, inpa))
  
    return instances()

if __name__ == "__main__": 
  reset = Signal(bool(0))
  clk = Signal(bool(0))
  stim=stimulus()
  testMod=testblk()
  
  toVerilog(testMod.test_top,reset,clk,stim)

The conversion results creates a weird entity namings as following:

module naming_issue (
    reset,
    clk,
    inpConnect_data_din1,
    inpa_valid
);

Which MyHDL version are you using ?

The version i use is 0.10, does it convert properly for you?

You use old style syntax.
You should use new syntax with @block decorators.

Updated to block decorator.
The names are getting more weird!
Uploaded file here:
https://filebin.net/tpx08680jcceyldh/naming_issue.py?t=s5juam5b

Result:

module test_top (
    reset,
    clk,
    mainblk0_block_connect0_conditional_wire_assign1_din1,
    inpa_valid
);

It is hinting that something strange is happenning with namings in conditional_wire_assign_process.
If I dont use this process, the conversion works fine.

This is the way it works. The top level names change with logic content.
To avoid this behaviour, you should not use signal interfaces at the top level.
A top level wrapper converting simple signals to complex ones is recommended.
Something like this :

from myhdl import block, Signal, intbv, toVerilog, instances, always_comb

@block
def conditional_wire_assign(dout, condition, din1, din2):
  @always_comb
  def conditional_wire_assign_process():
    dout.next = din1 if (condition == 1) else din2
  return instances() 

class stimulus():
  def __init__(self):
    self.data = Signal(intbv(0)[32:])
    self.valid  = Signal(bool(0))
          
class mainblk():
  @block
  def block_connect(self,reset,clk,inpa):
    shift2=Signal(bool(1)) 
    op=stimulus() 
    
    valid=(conditional_wire_assign(op.valid, shift2, inpa.valid, 0)) 
    data=(conditional_wire_assign(op.data, shift2, inpa.data, 0)) 
  
    return instances()

class testblk():
  @block
  def test_top(self,reset,clk,inpa):
    shift1=Signal(bool(0))  

    @always_comb
    def shift1_process():
      shift1.next = 1 if  (inpa.valid == 1) else 0
   
    testMain=mainblk()
    inpConnect=(testMain.block_connect(reset, clk, inpa))
  
    return instances()

class testblk_top():
  @block
  def test_top(self,reset,clk,data,valid):
    inpa = stimulus()
    
    @always_comb
    def in_process():
      inpa.data.next = data
      inpa.valid.next = valid

    test=testblk().test_top(reset,clk,inpa)
  
    return instances()


if __name__ == "__main__": 
  reset = Signal(bool(0))
  clk = Signal(bool(0))

  stim=stimulus()
  testMod=testblk_top().test_top(reset,clk,stim.data,stim.valid)

  #data  = Signal(intbv(0)[32:])
  #valid = Signal(bool(0))
  #testMod=testblk_top().test_top(reset,clk,data,valid)
  
  testMod.convert(hdl='Verilog', name="test_top")
1 Like

Or change the code in conversion/_analyze.py to:

def expandinterface(v, name, obj):
    for attr, attrobj in vars(obj).items():
        if isinstance(attrobj, _Signal):
            signame = name + '_' + attr
            attrobj._name = signame
. . .

to force the interface_attribute naming

1 Like