MyHDL Discourse

Conversion naming issue

#1

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?

0 Likes

#2

Can you please provide a complete simple example ?

0 Likes

#3

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
);
0 Likes

#4

Which MyHDL version are you using ?

0 Likes

#5

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

0 Likes

#6

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

0 Likes

#7

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.

0 Likes

#8

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

#9

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