# VHDL constant value overflow

**URL:** <https://discourse.myhdl.org/t/vhdl-constant-value-overflow/326>\
**Category:** Bug\
**Created:** [August 29, 2018, 12:35pm UTC](https://discourse.myhdl.org/t/vhdl-constant-value-overflow/326 "2018-08-29T12:35:11Z")\
**Posts on this page:** 17\
**Page:** 1

<div class="post-metadata">

**Author:** ![mhavu](https://yyz2.discourse-cdn.com/flex030/user_avatar/discourse.myhdl.org/mhavu/32/86_2.png) [@mhavu](https://discourse.myhdl.org/u/mhavu)\
**Post date:** [August 29, 2018, 12:35pm UTC](https://discourse.myhdl.org/t/vhdl-constant-value-overflow/326/1 "2018-08-29T12:35:11Z")

</div>

How do MyHDL people usually work around the VHDL size limit for integer literals? Consider the following MyHDL code:

```python
Y_LEN = 71
Y_MIN, Y_MAX = (-2**(Y_LEN - 1), 2**(Y_LEN - 1))
y = Signal(intbv(0, Y_MIN, Y_MAX))

# An attempt to implement saturation somewhere in the code
if result < 0:
    accumulator.next = Y_MIN
else:
    accumulator.next = Y_MAX - 1

```

This converts to VHDL as follows:

```auto
if (result < 0) then
    accumulator <= signed'("11111111111111111111111111111111111100000000000000000000000000000000000");
else
    accumulator <= to_signed(34359738368 - 1, 71);
end if;

```

The first case translates to a bit string literal, which is fine (although hexadecimal would be much easier to read than binary at these lengths). The second case with the arithmetic operation translates to an integer literal that is too large – at least as far as the compiler is concerned. Tweaking the constants would take care of this, but all the added plus ones and minus ones are not exactly good for reducing off-by-one errors. Are there any other options?

---

<div class="post-metadata">

**Author:** ![mhavu](https://yyz2.discourse-cdn.com/flex030/user_avatar/discourse.myhdl.org/mhavu/32/86_2.png) [@mhavu](https://discourse.myhdl.org/u/mhavu)\
**Post date:** [August 30, 2018, 9:28am UTC](https://discourse.myhdl.org/t/vhdl-constant-value-overflow/326/2 "2018-08-30T09:28:21Z")

</div>

Would it be difficult or undesirable for some reason to have MyHDL compute the result of constant expressions and replace them with bit string literals, just like in the case of a single constant?

---

<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:** [August 30, 2018, 11:28am UTC](https://discourse.myhdl.org/t/vhdl-constant-value-overflow/326/3 "2018-08-30T11:28:22Z")

</div>

IMHO it should be fairly straightforward to do, and surely an improvement. It would even be nicer if his code would generate a constant declaration:

```auto
    constant prefix_Y_MIN : signed(70 downto 0) := b"100...000...000...000";
    constant prefix_Y_MAX : signed(70 downto 0) := x"3fffffffffffffffff";
    constant prefix_Y_MAX_ALT : signed(70 downto 0) := (x"3fffffffffffffffff")(70 downto 0);

```

I’m not sure whether the hexadecimal notation will apply if the bits are a: not a multiple of 4 and b: more than 32. Perhaps the the alternative notation works?

_BTW: 34359738368 != 2\*\*70, neither is the binary string equal to -2\*\*70_

---

<div class="post-metadata">

**Author:** ![mhavu](https://yyz2.discourse-cdn.com/flex030/user_avatar/discourse.myhdl.org/mhavu/32/86_2.png) [@mhavu](https://discourse.myhdl.org/u/mhavu)\
**Post date:** [August 30, 2018, 1:30pm UTC](https://discourse.myhdl.org/t/vhdl-constant-value-overflow/326/4 "2018-08-30T13:30:51Z")

</div>

Ah, yes! Constant declarations would be sweet. I could try implementing them myself, but I find the MyHDL source code a bit hard to navigate, so I don’t know where to look for it.

> [@josyb](#):
>
> I’m not sure whether the hexadecimal notation will apply if the bits are a: not a multiple of 4 and b: more than 32. Perhaps the the alternative notation works?

Hexadecimal string literals need to contain a multiple of four bits, but there is no limit to the length. Only integers are limited to 32 bits. (Or is it 34 bits in the spec? Vendor tools may have the 32-bit limit anyway.)

> [@](#):
>
> _BTW: 34359738368 != 2` **`70, neither is the binary string equal to -2`** `70_

True. The saturation is at 36 bits. I copied a piece of code without thinking, so the Y\_MIN and Y\_MAX are not what they are supposed to be.

---

<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:** [August 30, 2018, 1:53pm UTC](https://discourse.myhdl.org/t/vhdl-constant-value-overflow/326/5 "2018-08-30T13:53:14Z")

</div>

I wonder whether the community is ready for a `Constant` type, but I think we can do it under the radar by tweaking the _\_toVHDL.py_ code.  
It would be nice if you’d provide small but complete example code; it saves me from having to type (and think) to get a test running.

---

<div class="post-metadata">

**Author:** ![mhavu](https://yyz2.discourse-cdn.com/flex030/user_avatar/discourse.myhdl.org/mhavu/32/86_2.png) [@mhavu](https://discourse.myhdl.org/u/mhavu)\
**Post date:** [August 31, 2018, 6:07am UTC](https://discourse.myhdl.org/t/vhdl-constant-value-overflow/326/6 "2018-08-31T06:07:40Z")

</div>

Would this Q0.x fixed-point gain be small enough?

```python
"""Scale fixed-point signal"""

from myhdl import block, always_comb, always_seq
from myhdl import Signal, ResetSignal, intbv

@block
def rescale(clk, reset, x, gain, shift, y):
    """Rescale with fractional gain and bit shift

    The rescale block operates with signed (two's complement) fixed-point
    numbers [-1.0, 1.0) with the following roles:
        Input: x
        Output: y = gain * x << shift
    """
    X_LEN = len(x)
    Y_LEN = len(y)
    GAIN_LEN = len(gain)
    Y_MIN, Y_MAX_M1 = (-2**(Y_LEN - 1), 2**(Y_LEN - 1) - 1)
    ZERO_SHIFT = GAIN_LEN - 1 + X_LEN - Y_LEN
    RESULT_LEN = Y_LEN + shift
    RESULT_MIN, RESULT_MAX = (-2**(RESULT_LEN - 1), 2**(RESULT_LEN - 1))
    
    # Internal signals
    result = Signal(intbv(0, RESULT_MIN, RESULT_MAX))
    
    @always_comb
    def logic():
        """Rescale"""
        result.next = x * gain >> ZERO_SHIFT - shift

    @always_seq(clk.posedge, reset=reset)
    def propagate():
        """Update y, and saturate in case of overflow"""
        if result[:Y_LEN].signed() > 0:
            y.next = Y_MAX_M1
        elif result[:Y_LEN].signed() < -1:
            y.next = Y_MIN
        else:
            y.next = result

    return logic, propagate

# Auxiliary functions

def convert(hdl):
    """Convert the design to HDL"""
    clk = Signal(bool(0))
    reset = ResetSignal(0, active=1, async=True)
    gain, shift = [Signal(intbv(0)[32:]) for _ in range(2)]
    x, y = [Signal(intbv(0)[32:]) for _ in range(2)]
    rtl = rescale(clk, reset, x, gain, shift, y)
    rtl.convert(hdl)

if __name__ == ' __main__':
    convert('VHDL')

```

It doesn’t have constant arithmetic expressions aside from the declaration, though, but one could change the following lines to make one:

```python
Y_MIN, Y_MAX = (-2**(Y_LEN - 1), 2**(Y_LEN - 1))
y.next = Y_MAX - 1

```

_Edit: The original example was purely combinational, but I’m not sure not sure whether it was actually synthesizable._

---

<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:** [August 31, 2018, 11:45am UTC](https://discourse.myhdl.org/t/vhdl-constant-value-overflow/326/7 "2018-08-31T11:45:17Z")

</div>

> [@mhavu](#):
>
> Hexadecimal string literals need to contain a multiple of four bits

With VHDL 2008, you can specify the bit length of the literal : 3X"2" is equal to “010”.  
The MyHDL VHDL converter already uses this notation.

> [@josyb](#):
>
> I wonder whether the community is ready for a `Constant` type

We already spoke about this before in other threads. I think we need constants in MyHDL.  
I already started to code such a functionality but only for VHDL, not for verilog.

---

<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:** [August 31, 2018, 12:03pm UTC](https://discourse.myhdl.org/t/vhdl-constant-value-overflow/326/8 "2018-08-31T12:03:25Z")

</div>

> [@DrPi](#):
>
> > I wonder whether the community is ready for a `Constant` type

I maybe should have said _senate_ in stead of _community_ 🙂

---

<div class="post-metadata">

**Author:** ![mhavu](https://yyz2.discourse-cdn.com/flex030/user_avatar/discourse.myhdl.org/mhavu/32/86_2.png) [@mhavu](https://discourse.myhdl.org/u/mhavu)\
**Post date:** [August 31, 2018, 12:21pm UTC](https://discourse.myhdl.org/t/vhdl-constant-value-overflow/326/9 "2018-08-31T12:21:35Z")

</div>

> [@DrPi](#):
>
> We already spoke about this before in other threads. I think we need constants in MyHDL.  
> I already started to code such a functionality but only for VHDL, not for verilog.

Do you mean [this one](http://discourse.myhdl.org/t/matching-a-signal-against-a-bitvector/274/8)? What do you guys think about adding generics support in the constant type? In my opinion, the constructor for the constant type could have a named parameter with default value `parameter=False`. If `parameter` were set to `True`, a generic would be generated instead of a constant.

---

<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:** [August 31, 2018, 12:37pm UTC](https://discourse.myhdl.org/t/vhdl-constant-value-overflow/326/10 "2018-08-31T12:37:29Z")

</div>

@mhavu  
No, not this one.  
There are few threads where it is discussed. I don’t remember which one exactly except this one : [VHDL conversion - missing constant](http://discourse.myhdl.org/t/vhdl-conversion-missing-constant/318/4)

From my point of view, the problem with MyHDL dev is with PRs that are very long to be accepted/rejected ( [A future for the MyHDL community?](http://discourse.myhdl.org/t/a-future-for-the-myhdl-community/235/64))

---

<div class="post-metadata">

**Author:** ![mhavu](https://yyz2.discourse-cdn.com/flex030/user_avatar/discourse.myhdl.org/mhavu/32/86_2.png) [@mhavu](https://discourse.myhdl.org/u/mhavu)\
**Post date:** [October 26, 2018, 10:51am UTC](https://discourse.myhdl.org/t/vhdl-constant-value-overflow/326/11 "2018-10-26T10:51:43Z")

</div>

I got bit by this again. MyHDL doesn’t always handle the large constants correctly. Take, for example, this piece of MyHDL-generated VHDL:

```auto
if (signed(unsigned(rescale1_result(68-1 downto drop))) >= 68719476735) then
            scaled_output <= signed'("011111111111111111111111111111111111");
            rescale2_overflow <= '1';
        elsif (signed(unsigned(rescale1_result(68-1 downto drop))) < (- 68719476736)) then
            scaled_output <= signed'("100000000000000000000000000000000000");
            rescale2_overflow <= '1';
        else
            scaled_output <= resize(signed(unsigned(rescale1_result(68-1 downto (drop + 1)))) + to_signed(rescale1_result(drop), 2), 36);
            rescale2_overflow <= '0';
        end if;

```

68719476735 and -68719476736 are values of two MyHDL constants. They are over 32 bits long, so I would have expected to see them converted to bit string literals. However, the conversion result is a 37-bit wide integer that breaks the compilation in Quartus. Can someone point me to a place in the MyHDL source code where this happens, so I can fix it? (Or if @DrPi’s constant type is ready, I’d be glad to test it.)

---

<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:** [October 26, 2018, 7:19pm UTC](https://discourse.myhdl.org/t/vhdl-constant-value-overflow/326/12 "2018-10-26T19:19:30Z")

</div>

Can you provide a fully functional minimal example reproducing the problem ?

---

<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:** [October 28, 2018, 8:00am UTC](https://discourse.myhdl.org/t/vhdl-constant-value-overflow/326/13 "2018-10-28T08:00:15Z")

</div>

In this case as the test-values are a power of 2 you could, as a work-around, use simple bit checking:

```auto
SCALING = 36
if not rescale_result[high] and rescale_result[high - 1 : drop + SCALING] != 0:
    scaled_output.next = ...
elif rescale_result[high] and rescale_result[high - 1 : drop + SCALING] == 0:
    scaled_output.next = ....
else:
   ...

```

This is how I did it in VHDL

---

<div class="post-metadata">

**Author:** ![mhavu](https://yyz2.discourse-cdn.com/flex030/user_avatar/discourse.myhdl.org/mhavu/32/86_2.png) [@mhavu](https://discourse.myhdl.org/u/mhavu)\
**Post date:** [October 29, 2018, 1:41pm UTC](https://discourse.myhdl.org/t/vhdl-constant-value-overflow/326/14 "2018-10-29T13:41:01Z")

</div>

@DrPi, here’s a minimum working example:

```auto
from myhdl import block, always_comb, Signal, intbv

@block
def test_constant(x, y):
    THRESHOLD = 2**(len(x) - 2)
    
    @always_comb
    def logic():
        if x > THRESHOLD:
            y.next = 1
        else:
            y.next = 0

    return logic

if __name__ == ' __main__':
    x = Signal(intbv(0, -2 **35, 2** 35))
    y = Signal(bool(0))
    rtl = test_constant(x, y)
    rtl.convert('VHDL')

```

The VHDL conversion results in:

```auto
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.numeric_std.all;
use std.textio.all;

use work.pck_myhdl_010.all;

entity test_constant is
    port (
        x: in signed (35 downto 0);
        y: out std_logic
    );
end entity test_constant;

architecture MyHDL of test_constant is

begin

TEST_CONSTANT_LOGIC: process (x) is
begin
    if (x > 17179869184) then
        y <= '1';
    else
        y <= '0';
    end if;
end process TEST_CONSTANT_LOGIC;

end architecture MyHDL;

```

The threshold constant 17179869184 is wider than 32 bits, but it is not expressed as a bit string literal.

@josyb, I used to do that (check that the high bits are either all 0 or all 1). If I remember correctly, it results in fewer FPGA resources being used as a bonus. However, if you want rounding, a new case is introduced (high bits all 0, low bits all 1), so the code would be much more readable with simple \>= and \< checks.

---

<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:** [October 30, 2018, 10:02am UTC](https://discourse.myhdl.org/t/vhdl-constant-value-overflow/326/15 "2018-10-30T10:02:50Z")

</div>

As a quick workaround, you can declare THRESHOLD like this :

```auto
THRESHOLD = Signal(intbv(2**(len(x) - 2), -2**35, 2**35))

```

I’m working on a better solution.

---

<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:** [November 5, 2018, 10:30am UTC](https://discourse.myhdl.org/t/vhdl-constant-value-overflow/326/16 "2018-11-05T10:30:47Z")

</div>

The fix is 4 lines of code in \_toVHDL.py module.

In \_AnnotateTypesVisitor() class, the new code for visit\_Compare() function is the following :

```python
    def visit_Compare(self, node):
        node.vhd = vhd_boolean()
        self.generic_visit(node)
        left, op, right = node.left, node.ops[0], node.comparators[0]
        if isinstance(left.vhd, vhd_std_logic) or isinstance(right.vhd, vhd_std_logic):
            left.vhd = right.vhd = vhd_std_logic()
        elif isinstance(left.vhd, vhd_unsigned) and maybeNegative(right.vhd):
            left.vhd = vhd_signed(left.vhd.size + 1)
        elif maybeNegative(left.vhd) and isinstance(right.vhd, vhd_unsigned):
            right.vhd = vhd_signed(right.vhd.size + 1)
        if isinstance(left.vhd, (vhd_nat, vhd_int)) : # New
            left.vhd = right.vhd # New
        if isinstance(right.vhd, (vhd_nat, vhd_int)) : # New
            right.vhd = left.vhd # New
        node.vhdOri = copy(node.vhd)

```

---

<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:** [July 24, 2024, 10:35am UTC](https://discourse.myhdl.org/t/vhdl-constant-value-overflow/326/17 "2024-07-24T10:35:02Z")

</div>

Hi all,

This thread has been recently (July 9th) mentioned on Matrix (previously: Gitter)

The issue is that the Vendors VHDL may restrict integers to 32 bits - GHDL on my machine allows 64 bits - the MyHDL simulator knows no boundaries 🙂

The good thing that since 0.11.43 we can declare a _constant_:

```python
THRESHOLD = Constant(intbv(2 **(len(w) - 2), min=-2** (len(w) - 1), max=2 ** (len(w) - 1))

```

giving this code:

```vhdl
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.numeric_std.all;
use std.textio.all;

use work.pck_myhdl_011.all;

entity sconstant is
	port(
		w : in signed(65 - 1 downto 0);
		a : out std_logic
	);
end entity sconstant;

architecture MyHDL of sconstant is

	constant THRESHOLD : signed(65 - 1 downto 0) := 65X"08000000000000000"; -- 9223372036854775808

begin

	SCONSTANT_COMB : process(w) is
	begin
		if (w > THRESHOLD) then
			a <= '1';
		else
			a <= '0';
		end if;
	end process SCONSTANT_COMB;

end architecture MyHDL;

```

Note that you explicitly have to declare an intbv.

The not so good news is that is not yet entered in the official MyHDL documentation so people have a hard time finding this gem.  
The second not so good news is that the Verilog output is not always correct so that needs revisiting ☹
