Sub module Verilog synthesis error

Hi All,

I have an exmaple of code that produces output VHDL that is correct and Verilog that is incorrect. The incorrectness in Verilog stems from the fact there is an assignment to a wire type that should be a reg type.

Side note : Why don’t we move everything to System Verilog and use Logic and be done?

So here’s my code - it is supposed to be a settable set of sub modules that are optionally registered or not based on a mask in a pipeline (ultimately this is for a square root function I am writing)

Can someone either correct my code so it produces correct Verilog (I am still new to myHDL) or confirm I am not going mad and this is a bug and I will post this appropriately.

regards,

Steve.

=================================

from myhdl import *

@block
def example_top(
clock,
data_in,
data_out,
STAGES,
REG_MASK):

###########################################################################
@block
def stage_block(
        clock,
        d,
        q,
        REGISTERED):

    if (REGISTERED != 0) :
        @always(clock.posedge)
        def logic():
            q.next = d

    else:
        @always_comb
        def logic():
            q.next = d

    return instances()
###########################################################################

WIDTHD = len(data_out) if (len(data_out) > len(data_in)) else len(data_in)

da = [Signal(intbv(0)[WIDTHD:]) for _ in range(STAGES)]
qa = [Signal(intbv(0)[WIDTHD:]) for _ in range(STAGES)]
st = [None for _ in range(STAGES)]

for i in range(STAGES):
    if (i == 0):
        st[0] = stage_block(clock, data_in, qa[0], REG_MASK & (1 << i))
    else:
        st[i] = stage_block(clock, qa[i-1], qa[i], REG_MASK & (1 << i))

@always_comb
def comb_logic():
    data_out.next = qa[STAGES-1]

return instances()

##############################################################################

generate VHDL/Verilog

if (name == ‘main’):
LANGUAGE = “VHDL”
WIDTH = 8
STAGES = 12
REG_MASK = 0x888
clock = Signal(bool(0))
data_in = Signal(intbv(0)[WIDTH:])
data_out = Signal(intbv(0)[WIDTH:])
design = example_top(
clock,
data_in,
data_out,
STAGES,
REG_MASK)
design.convert(hdl=LANGUAGE)

Steve,

I’d rather say that Verilog’s wire / reg distinction is the problem.
MyHDL has no chance to make it right: if some of the entries need to be a reg and others a wire, how can it declare the array?
Yes SystemVerilog learned from VHDL and offered logic as the cure.
I think that current tendency in the community is to keep supporting Verilog. We could add SystemVerilog as a target conversion language, and introduce the logic type. I just wonder what other changes will be mandatory.

There is a workaround adding a local Signal:

    @block
    def stage_block(
            clock,
            d,
            q,
            REGISTERED):

        if (REGISTERED != 0):
            lq = Signal(q._val)  # take a local copy of the output argument

            @always_seq(clock.posedge, reset=None)
            def logic():
                lq.next = d

            @always_comb
            def mko():
                q.next = lq

        else:

            @always_comb
            def logic():
                q.next = d

        return instances()

Regards,
Josy

Hi Josy,

Thanks for the workaround. I would like to propose deprecating Verilog and moving to System Verilog. I am fairly sure all that needs to happen as a first step is change wire/reg to logic - all other Verilog syntax will follow. You shouldn’t need to add always_comb always_ff as a first pass as it is backward compatible.

Hi Steve,

Actually the always_comb and always_ff are less work than the logic as reg and wire are emitted in quite a few places in the _toVerilog.py code
I already have done similar for VHDL-2008: process( all ) :slight_smile:

Regards,
Josy