How to make MyHDL generate variable with arbitrary width in process?

203 Views Asked by At

I would like to do a sum of signals that I have in a list, naturally I have used variable and for (as I would in VHDL):

    @always_comb
    def sum():
        sum = 0
        for i in range(len(summands)):
            sum = sum + summands[i]
        product.next = sum

The problem is that this will use integer (in VHDL) for sum variable, which is not much useful when the width of sum will be more than 32bits.

So I tried to do something like this:

    @always_comb
    def sum():
        sum = intbv(0, min=vmin, max=vmax)
        for i in range(len(summands)):
            sum = sum + summands[i]
        product.next = sum

I get following error (during conversion):

    Type mismatch with earlier assignment: sum

Which I don't understand how to work around. I guess it gets the value of intbv in sum as integer and therefore is different type.

Thanks for any suggestion

2

There are 2 best solutions below

0
On

For people who come across this in future. You can create the variable outside the @always_comb (or @always) function:

sum = intbv(0, min=vmin, max=vmax)

The syntax to assign to that variable is:

sum[:] = 0

The given example would then become:

sum = intbv(0, min=vmin, max=vmax)

@always_comb
def sum():
    sum[:] = 0
    for i in range(len(summands)):
        sum[:] = sum + summands[i]
    product.next = sum

This page in the MyHDL manual provides more detail.

2
On

I have managed to make very ugly workaround:

@always_comb
def sum():
    sum = intbv(0, min=vmin, max=vmax)
    for i in range(len(summands)):
        sum = intbv(sum + summands[i], min=vmin, max=vmax)
    product.next = sum

In this manner it will generate correct VHDL:

IIR_SOS_INST_0_PRODUCTS_1_SUM: process (sos_inst_0_products_1_summands) is
    variable sum: signed(44 downto 0);
begin
    sum := to_signed(0, 45);
    for i in 0 to 21-1 loop
        sum := to_signed((sum + sos_inst_0_products_1_summands(i)), 45);
    end loop;
    sos_inst_0_b1p <= sum;
end process IIR_SOS_INST_0_PRODUCTS_1_SUM;

But the performance of the simulation suffers considerably on creating a new intbv object on every assignment to sum.