cfelton / rhea

A collection of MyHDL cores and tools for complex digital circuit design

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

[bug] device_clock_mgmt_prim() will not convert due to using unsupported myhdl features.

NickShaffner opened this issue · comments

This one is a little odd. I was trying to get clock management to synthesize, but kept getting:

File "C:\Users\nshaffner\AppData\Local\Continuum\Anaconda3\lib\site-packages\myhdl-1.0.dev0-py3.5.egg\myhdl\conversion_analyze.py", line 203, in visit_Tuple
self.raiseError(node, _error.NotSupported, "tuple assignment")
File "C:\Users\nshaffner\AppData\Local\Continuum\Anaconda3\lib\site-packages\myhdl-1.0.dev0-py3.5.egg\myhdl\conversion_misc.py", line 148, in raiseError
raise ConversionError(kind, msg, info)
myhdl.ConversionError: in file C:\Users\nshaffner\AppData\Local\Continuum\Anaconda3\lib\site-packages\rhea-0.0.1-py3.5.egg\rhea\vendor\device_clock_mgmt_prim.py, line 62:
Not supported: tuple assignment

the code in question is: (device_clock_mgmt_prim.py, line 62)

    @always_comb
    def clk_assign():
        clkmgmt.clockin_out.next = clockin
        for ii, clk in enumerate(clkmgmt.clocks):
            clocksout.next[ii] = clk

The error makes sense according to myHDL's documentation disallows it: (http://docs.myhdl.org/en/stable/manual/conversion.html)

for
The only supported iteration scheme is iterating through sequences of integers returned by built-in > function range() or MyHDL function downrange(). The optional else clause is not supported.

HOWEVER, strangely, test/test_vendor/test_device_clock_mgmt.py succeeds.

So the reason it succeeds is that it runs a simulation prior to conversion, and uses the same clock management object. (simulation apparently has no qualms about tuple assignment). It seems that the simulation is causing the clock management object to be elaborated, and then when it gets to the conversion part, it reuses the same object, the for() has already been expanded. If you remove the simulation step right before the conversion, the test will fail with the same error as above due to the lack of a prior side effecting elaboration step.

Suggestion:

  • Alter test_device_clock_mgmt.py to seperate simulation and conversion steps (use different block objects)
  • Alter (device_clock_mgmt_prim.py, line 62) to only use range or downrange in it's for statement, and index into the clocks array directly.

Ran into a number of additional issues while trying to fix this, including duplicated assignments of clocksout between the vendor/device_clock_management and vendor/device_clock_management_prim, and errors converting ticks. (again, only when the sim isn't run first. Running the sim first gets around a lot of the conversion checks).

I'm stopping work on fixing this because I don't have this history to know where Rhea wants to go with this, or if it's just atrophied and sitting around. Is the whole thing pending a refactor, etc.

@NickShaffner this block is not intended to be convertible, part of confusion is the type in the docstring (should be model vs. module).

The vendor subpackage is intended to be generic wrappers around the primitives, to use it should look like this example:
xilinx example
altera example

The "vendor" needs to be define (which primitive to insert) otherwise it will use the generic model (good for simulating).

This project is large (many dependent components) and the documentation needs a lot of work before the first release (0.1).

What I mentioned in the previous comment is the intent but the existing examples seem to have an issue ... investigating.

This is an issue with the changes between myhdl 0.9 and 1.0, this will require some digging. Previously I would set the function attribute (verilog_code) to the generic block, that way it would seamlessly work with simulation or conversion.

    prim_inst = device_clock_mgmt_prim(clkmgmt)
    device_clock_mgmt_prim.verilog_code = clock_mgmt_verilog_code(clkmgmt)

In the above snippet, the converter is suppose to skip the device_clock_mgmt_prim and insert the HDL defined in the verilog_code attribute (I think I might simply need to change the order ... of the test ...).

With the 1.0 changes it seems this is not possible. I need to investigate this issue and see what options are possible with the 1.0 @myhdl.block addition.

Good, changing the order of the snippet in the previous comment works, will need to update the xilinx and altera primitives (and remember this in the future).

Awesome, thanks chris! Verified locally that your commit 8830d85 fixes it.

As an aside:

@cfelton

this block is not intended to be convertible, part of confusion is the type in the docstring (should be model vs. module).

Even if it's not intended to be convertible, it's still intended to be myhdl rather than python right? I'm a bit surprised that the myhdl simulator doesn't enforce the same language rules as the converter.