# Conversion producing invalid register names

**URL:** <https://discourse.myhdl.org/t/conversion-producing-invalid-register-names/242>\
**Category:** Support\
**Created:** [January 3, 2018, 4:39am UTC](https://discourse.myhdl.org/t/conversion-producing-invalid-register-names/242 "2018-01-03T04:39:10Z")\
**Posts on this page:** 10\
**Page:** 1

<div class="post-metadata">

**Author:** ![romanenkor](https://avatars.discourse-cdn.com/v4/letter/r/f475e1/32.png) [@romanenkor](https://discourse.myhdl.org/u/romanenkor)\
**Post date:** [January 3, 2018, 4:39am UTC](https://discourse.myhdl.org/t/conversion-producing-invalid-register-names/242/1 "2018-01-03T04:39:10Z")

</div>

Hello, everybody. I have been trying to create a bus arbiter module to externally set an “access granted” flag for each device in a list. I ended up writing following code:

```
#bus.py
from myhdl import *

# Grants access to a device with lowest index in a list if it's request flag is set
def arbiter(clk, devices):
    request_list = [device.request for device in devices]
    request_vector = ConcatSignal(*reversed(request_list))
    grant_list = [device.grant for device in devices]
    grant_vector = ConcatSignal(*reversed(grant_list))

    @always(clk.posedge)
    def logic():
        grant_vector.next = request_vector & (-request_vector)
        # Also tried this:
        # for i, device in enumerate(devices):
        # device.grant.next = grant_vector[i]
    return instances(), grant_vector

#test module
from myhdl import *
from bus import arbiter

# Device template, should increment it's counter if allowed by an arbiter.
# Implementation only tests the arbiter, nothing useful yet
class Device:
    def __init__ (self):
        self.request = Signal(bool())
        self.grant = Signal(bool())
    
    def instance(self, clk):
        counter = Signal(intbv())

        @always(clk.posedge)
        def logic():
            if self.grant == 1:
                counter.next = counter + 2
            self.request.next = 1
        return instances()

clk = Signal(bool())
devices = [Device(), Device()]

def top(clk):
    a = arbiter(clk, devices)
    di = [device.instance(clk) for device in devices]
    return instances()

toVerilog(top, clk)

```

This results in an invalid conversion to Verilog:

```
// File: top.v
// Generated by MyHDL 0.9.0
// Date: Tue Jan 2 21:14:46 2018

`timescale 1ns/10ps

module top (
    clk
);

input clk;

always @(posedge clk) begin: MYHDL1_BLOCK
    if ((False == 1)) begin
        0 <= (0 + 1);
    end
    False <= 1;
end

always @(posedge clk) begin: MYHDL2_BLOCK
    if ((False == 1)) begin
        0 <= (0 + 1);
    end
    False <= 1;
end

endmodule

```

I wanted grant to be a wire that is set by the arbiter on the same cycle, so the device can understand if it is allowed to use a shared resource. It should scale up to any reasonable number of devices. However, it doesn’t seem to work. Maybe because of indirect access to a signal? If it is the cause, then it will be hard to build scaleable hardware designs. Nobody would want their arbiter code to merge with a “Device” logic, so some kind of abstraction is needed.

I’ve got following response:

> grant\_vector = ConcatSignal(\*reversed(grant\_list))
> 
> grant\_vector is a ShadowSignal and cannot be assigned to.  
> use a Signal(intbv()) instead
> 
> grant\_vector = Signal(intbv(0)[len(request\_list):])
> 
> You then still have to assign each bit of this vector to the grant-bit in its respective Device.

Then I changed arbiter code as follows:

from myhdl import \*

```
def arbiter(clk, devices):
    request_list = [device.request for device in devices]
    request_vector = ConcatSignal(*reversed(request_list))
    grant_vector = Signal(intbv(0)[len(request_vector):])
    grant_list = [device.grant for device in reversed(devices)]

    @always(clk.posedge)
    def logic():
        grant_vector.next = request_vector & (-request_vector)
        for i, grant in enumerate(grant_list):
            grant.next = grant_vector[i]
    return instances()

```

Unfortunaltely, this doesn’t seem to work and I don’t really know how to set bits in devices properly.

> myhdl.ConversionError: in file D:\Projects\CPU\bus.py, line 12:  
> Not supported: tuple assignment  
> Thanks in advance.

---

<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:** [January 3, 2018, 8:12am UTC](https://discourse.myhdl.org/t/conversion-producing-invalid-register-names/242/2 "2018-01-03T08:12:45Z")

</div>

`for i, grant in enumerate(grant_list):` is not _convertible_  
I assumed you would have added the following:

```auto
@always_comb
def assign():
    for i in range(len(request_list)):
        grant_list[i].next = grant_vector[i]

```

as a separate _combinatorial_ function.

---

<div class="post-metadata">

**Author:** ![romanenkor](https://avatars.discourse-cdn.com/v4/letter/r/f475e1/32.png) [@romanenkor](https://discourse.myhdl.org/u/romanenkor)\
**Post date:** [January 3, 2018, 8:30am UTC](https://discourse.myhdl.org/t/conversion-producing-invalid-register-names/242/3 "2018-01-03T08:30:24Z")

</div>

Thanks for your reply, I will try this solution later.  
P.S. This is really sad, since “enumerate” was developed specifically to  
prevent this kind of loop and make it simpler.

---

<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:** [January 3, 2018, 9:22am UTC](https://discourse.myhdl.org/t/conversion-producing-invalid-register-names/242/4 "2018-01-03T09:22:51Z")

</div>

`enumerate` has no direct counterpart in Verilog nor VHDL. In order to convert, that construct would have to be re-written , on the fly in the conversion process, like the one I showed.  
Like the synthesise-able constructs are a subset both in Verilog and in VHDL, you must see this restriction as a convertible subset of the Python language (into V\*)  
I wouldn’t call that sad.

---

<div class="post-metadata">

**Author:** ![romanenkor](https://avatars.discourse-cdn.com/v4/letter/r/f475e1/32.png) [@romanenkor](https://discourse.myhdl.org/u/romanenkor)\
**Post date:** [January 3, 2018, 9:54am UTC](https://discourse.myhdl.org/t/conversion-producing-invalid-register-names/242/5 "2018-01-03T09:54:43Z")

</div>

Well, I am a software dev, so I really like high-level constructs in HLL’s.  
Basically nothing, except of basic math, is available on the hardware-level.  
So we map high-level constructs like expressions, objects, templates, etc.  
to lower-level stuff.  
So my point is: if HLL’s would work like assembly, why would anyone need  
them?  
Same thing for HDL’s: if a HLL-HDL works exactly the same way, as Verilog  
does, why anyone would want this new HDL?

My colleague who works with FPGA’s once said: “Vivado and Quartus both have  
well-built development and debugging/verification tools. Verilog/VHDL also  
have good parameterization tools, can load ROM’s from files and do almost  
anything. So why should I stick with a Python HDL?”

My only response was: “Well, if you could “write” software and hardware  
almost the same way, it would be amazing, right? One technology to learn,  
basically”.

So I guess this is how I saw MyHDL: unified tool, connecting both SW and HW  
worlds.  
So I would be able to do something like that:

```
class CPU:
    bits = 32

class ALU:
    latency = math.log2(CPU.bits)

    def add(self, result, a, b):
        ...
    def sub(self, result, a, b):
        ...

def top(clk, instruction, result, a, b):
    alu = ALU()

    @always(clk)
    def logic():
        if instruction == 1:
            alu.add(result, a, b)
        elif instruction == 2:
            alu.sub(result, a, b)

```

This wouldn’t have direct mapping to any current HDL, but would generalize  
well between HW/SW development. For now this doesn’t seem possible and  
would generate exception “non-synthesizeable functuon call”. However, this  
problem can be solved by inlining code/registers from ALU into “cycle”.

Best Regards.

---

<div class="post-metadata">

**Author:** ![romanenkor](https://avatars.discourse-cdn.com/v4/letter/r/f475e1/32.png) [@romanenkor](https://discourse.myhdl.org/u/romanenkor)\
**Post date:** [January 3, 2018, 10:48am UTC](https://discourse.myhdl.org/t/conversion-producing-invalid-register-names/242/6 "2018-01-03T10:48:11Z")

</div>

Changed bus code to:

```
def arbiter(clk, devices):
    request_list = [device.request for device in devices]
    request_vector = ConcatSignal(*reversed(request_list))
    grant_vector = Signal(intbv(0)[len(request_list):])
    grant_list = [device.grant for device in reversed(devices)]

    @always_comb
    def logic():
        grant_vector.next = request_vector & (-request_vector)

    @always_comb
    def assign():
        for i in range(len(request_list)):
            grant_list[i].next = grant_vector[i]
    return instances()

```

Got an error "‘Call’ object has no attribute ‘starargs’"  
Stack trace:

```
File ".\test.py", line 26, in <module>
    toVerilog(top, clk)
  File "C:\Users\RoMu4\AppData\Local\Programs\Python\Python36\lib\site-packages\myhdl\conversion\_toVerilog.py", line 151, in __call__
    genlist = _analyzeGens(arglist, h.absnames)
  File "C:\Users\RoMu4\AppData\Local\Programs\Python\Python36\lib\site-packages\myhdl\conversion\_analyze.py", line 164, in _analyzeGens
    v.visit(tree)
  File "C:\Users\RoMu4\AppData\Local\Programs\Python\Python36\lib\ast.py", line 253, in visit
    return visitor(node)
  File "C:\Users\RoMu4\AppData\Local\Programs\Python\Python36\lib\ast.py", line 261, in generic_visit
    self.visit(item)
  File "C:\Users\RoMu4\AppData\Local\Programs\Python\Python36\lib\ast.py", line 253, in visit
    return visitor(node)
  File "C:\Users\RoMu4\AppData\Local\Programs\Python\Python36\lib\site-packages\myhdl\conversion\_analyze.py", line 290, in visit_FunctionDef
    self.visitList(node.body)
  File "C:\Users\RoMu4\AppData\Local\Programs\Python\Python36\lib\site-packages\myhdl\conversion\_misc.py", line 162, in visitList
    self.visit(n)
  File "C:\Users\RoMu4\AppData\Local\Programs\Python\Python36\lib\ast.py", line 253, in visit
    return visitor(node)
  File "C:\Users\RoMu4\AppData\Local\Programs\Python\Python36\lib\ast.py", line 263, in generic_visit
    self.visit(value)
  File "C:\Users\RoMu4\AppData\Local\Programs\Python\Python36\lib\ast.py", line 253, in visit
    return visitor(node)
  File "C:\Users\RoMu4\AppData\Local\Programs\Python\Python36\lib\site-packages\myhdl\conversion\_analyze.py", line 264, in visit_Call
    if node.starargs:
AttributeError: 'Call' object has no attribute 'starargs'
```

---

<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:** [January 3, 2018, 11:21am UTC](https://discourse.myhdl.org/t/conversion-producing-invalid-register-names/242/7 "2018-01-03T11:21:22Z")

</div>

> [@romanenkor](#):
>
> Same thing for HDL’s: if a HLL-HDL works exactly the same way, as Verilog
> 
> does, why anyone would want this new HDL?
> 
> My colleague who works with FPGA’s once said: “Vivado and Quartus both have
> 
> well-built development and debugging/verification tools. Verilog/VHDL also
> 
> have good parameterization tools, can load ROM’s from files and do almost
> 
> anything. So why should I stick with a Python HDL?”

There is no silver bullet in HW-design. RTL-code is quite different than SW… You may want to explore the HLS-route instead.  
The gain is in simulation: e.g. try feeding an .avi image into the Verilog/VHDL test-bench. In Python this is easy (I did, and I am a hardware guy …)  
Writing a test-bench in MyHDL is a lot faster (and thus a lot more fun) than in VHDL (I actually don’t do Verilog)

You can do class-based design in MyHDL, see my gist:[Exploring improved structural design - Part 1 · GitHub](https://gist.github.com/josyb/afd84c9a06fdec77f2fd) and [Structural Design in MyHDL - to @block or not to @block? · GitHub](https://gist.github.com/josyb/d119a2f3f12dcc28533ac612e30576af)  
It is not exactly what you describe, but it may serve the purpose.  
(I only do class-based design.)

You are using MyHDL 0.9. I would suggest to use the 1.0-dev package. It will still complain about the class method, I have looked into that but haven’t resolved it (yet).

I will try your code later tonight. Perhaps post the code in gist?

Regards,  
Josy

---

<div class="post-metadata">

**Author:** ![romanenkor](https://avatars.discourse-cdn.com/v4/letter/r/f475e1/32.png) [@romanenkor](https://discourse.myhdl.org/u/romanenkor)\
**Post date:** [January 3, 2018, 4:15pm UTC](https://discourse.myhdl.org/t/conversion-producing-invalid-register-names/242/8 "2018-01-03T16:15:44Z")

</div>

Thanks for your help!  
Here’s the code: [https://gist.github.com/romanenkor/6ff99edbe9f9948105d67ec3f37c87b6](https://gist.github.com/romanenkor/6ff99edbe9f9948105d67ec3f37c87b6)

---

<div class="post-metadata">

**Author:** ![cfelton](https://yyz2.discourse-cdn.com/flex030/user_avatar/discourse.myhdl.org/cfelton/32/3_2.png) [@cfelton](https://discourse.myhdl.org/u/cfelton)\
**Post date:** [January 5, 2018, 1:25am UTC](https://discourse.myhdl.org/t/conversion-producing-invalid-register-names/242/9 "2018-01-05T01:25:14Z")

</div>

@romanenkor

Here are some reasons why to use and and what myhdl is not.  
[http://www.myhdl.org/start/why.html](http://www.myhdl.org/start/why.html)  
[http://www.myhdl.org/start/whatitisnot.html](http://www.myhdl.org/start/whatitisnot.html)

To get many of features you eluded, you need to be creative with your elaboration (code outside the myhdl generators) and not purely adopt V\* patterns.

---

<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:** [January 5, 2018, 2:24pm UTC](https://discourse.myhdl.org/t/conversion-producing-invalid-register-names/242/10 "2018-01-05T14:24:19Z")

</div>

> [@josyb](#):
>
> There is no silver bullet in HW-design. RTL-code is quite different than SW… You may want to explore the HLS-route instead.

From my point of view, MyHDL is a higher language than VHDL/verilog. For example, VHDL entity ports must be completely specified while in MyHDL, you don’t have to. This allows to write much more flexible blocs of code.

> [@josyb](#):
>
> The gain is in simulation: e.g. try feeding an .avi image into the Verilog/VHDL test-bench. In Python this is easy (I did, and I am a hardware guy …)
> 
> Writing a test-bench in MyHDL is a lot faster (and thus a lot more fun) than in VHDL (I actually don’t do Verilog)

I agree with Josy.  
On my side, my MyHDL designs are used in audio devices. It is very easy to input multi track audio files content in test benches. It is a nightmare in VHDL.  
When designing an audio filter, I can easily inject a sinus, swiping in frequency, and display the frequency response directly with matplotlib. Forget it with VHDL.
