# Variables in VHDL conversion

**URL:** <https://discourse.myhdl.org/t/variables-in-vhdl-conversion/327>\
**Category:** Bug\
**Created:** [August 31, 2018, 7:26am UTC](https://discourse.myhdl.org/t/variables-in-vhdl-conversion/327 "2018-08-31T07:26:35Z")\
**Posts on this page:** 16\
**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 31, 2018, 7:26am UTC](https://discourse.myhdl.org/t/variables-in-vhdl-conversion/327/1 "2018-08-31T07:26:35Z")

</div>

Consider the following MyHDL code:

```python
@always_comb
def add():
    bx_sum = bx[0].signed() + bx[1].signed() + bx[2].signed()
    ay_sum = ay[0].signed() + ay[1].signed()
    result.next = (bx_sum << BX_SHIFT) - (ay_sum << AY_SHIFT)

```

It converts to this piece of VHDL:

```auto
PREFIX_ADD: process (bx, ay) is
    variable bx_sum: integer;
    variable ay_sum: integer;
begin
    bx_sum := to_integer((bx(0) + bx(1)) + bx(2));
    ay_sum := to_integer(ay(0) + ay(1));
    result <= to_signed(shift_left(bx_sum, 12) - shift_left(ay_sum, 0), 67);
end process PREFIX_ADD;

```

This won’t compile, because the compiler can’t determine whether the first argument of `shift_left()` is signed or unsigned. I think this is a bug in the VHDL conversion. To fix this, let’s try moving the shift to where the compiler can still infer the type:

```python
@always_comb
def add():
    bx_sum = bx[0].signed() + bx[1].signed() + bx[2].signed() << BX_SHIFT
    ay_sum = ay[0].signed() + ay[1].signed() << AY_SHIFT
    result.next = bx_sum - ay_sum

```

Now we get this:

```auto
PREFIX_ADD: process (bx, ay) is
    variable ay_sum: integer;
    variable bx_sum: integer;
begin
    bx_sum := to_integer(shift_left(((bx(0) + bx(1)) + bx(2)), 12));
    ay_sum := to_integer(shift_left((ay(0) + ay(1)), 0));
    result <= to_signed(bx_sum - ay_sum, 67);
end process PREFIX_ADD;

```

This compiles, but is it safe? Do vendor tools support arbitrarily large integer variables? Should I do this instead:

```python
@always_comb
def add():
    result.next = (
        (bx[0].signed() + bx[1].signed() + bx[2].signed() << BX_SHIFT) -
        (ay[0].signed() + ay[1].signed() << AY_SHIFT)
    )

```

This gives the following VHDL, which compiles and should definitely be safe:

```auto
result <= (shift_left(((bx(0) + bx(1)) + bx(2)), 12) - shift_left((ay(0) + ay(1)), 0));

```

However, I think the first version (the one that doesn’t compile now) is the most readable.

---

<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:42pm UTC](https://discourse.myhdl.org/t/variables-in-vhdl-conversion/327/2 "2018-08-31T12:42:57Z")

</div>

> [@mhavu](#):
>
> result.next = (bx\_sum \<\< BX\_SHIFT) - (ay\_sum \<\< AY\_SHIFT)

What about the sign of bx\_sum and ay\_sum after the shift (independently of MyHDL/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:** [August 31, 2018, 12:47pm UTC](https://discourse.myhdl.org/t/variables-in-vhdl-conversion/327/3 "2018-08-31T12:47:27Z")

</div>

> [@DrPi](#):
>
> > result.next = (bx\_sum \<\< BX\_SHIFT) - (ay\_sum \<\< AY\_SHIFT)
> 
> What about the sign of bx\_sum and ay\_sum after the shift (independently of MyHDL/VHDL) ?

What about it? Both bx\_sum and ay\_sum are signed integers. Shifting doesn’t affect the sign. Is that what you meant?

---

<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:50pm UTC](https://discourse.myhdl.org/t/variables-in-vhdl-conversion/327/4 "2018-08-31T12:50:14Z")

</div>

> [@mhavu](#):
>
> Is that what you meant?

That’s it.  
“1010110” is negative.  
“1010110” \<\< 1 = “0101100” This is positive.

---

<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:53pm UTC](https://discourse.myhdl.org/t/variables-in-vhdl-conversion/327/5 "2018-08-31T12:53:52Z")

</div>

> [@DrPi](#):
>
> That’s it.  
> “1010110” is negative.  
> “1010110” \<\< 1 = “0101100” This is positive.

In Python, shifting doesn’t affect sign. The same is true for shifting signed types in VHDL. So as far as I know, “1010110” \<\< 1 ≠ “0101100”.

_Edit: I missed your point about the shifted value not being wider than the original, like it is in Python. As far as I know, this is the case also in VHDL, so the first bit would not be dropped._

_Edit: Except I’m wrong:_

> function SHIFT\_LEFT (ARG: SIGNED; COUNT: NATURAL) return SIGNED;  
> – Result subtype: SIGNED(ARG’LENGTH-1 downto 0)  
> – Result: Performs a shift-left on a SIGNED vector COUNT times.  
> – The vacated positions are filled with ‘0’.  
> – **The COUNT leftmost elements are lost.**

_So I actually want to concatenate, not shift._

---

<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, 1:03pm UTC](https://discourse.myhdl.org/t/variables-in-vhdl-conversion/327/6 "2018-08-31T13:03:39Z")

</div>

Don’t forget that you can simulate code that is not convertible to VHDL/verilog. This is usefull but you must be careful about 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:** [August 31, 2018, 1:05pm UTC](https://discourse.myhdl.org/t/variables-in-vhdl-conversion/327/7 "2018-08-31T13:05:39Z")

</div>

> [@mhavu](#):
>
> So I actually want to concatenate, not shift.

That’s it 😉

(Have to type more than 20 char, so lets go…)

---

<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, 1:09pm UTC](https://discourse.myhdl.org/t/variables-in-vhdl-conversion/327/8 "2018-08-31T13:09:52Z")

</div>

> [@DrPi](#):
>
> Don’t forget that you can simulate code that is not convertible to VHDL/verilog. This is usefull but you must be careful about it.

Except that in this case it does convert. It just doesn’t do the same thing, which is rather dangerous. I will need to review my code for erroneous uses of the shift operator.

---

<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, 1:12pm UTC](https://discourse.myhdl.org/t/variables-in-vhdl-conversion/327/9 "2018-08-31T13:12:39Z")

</div>

This is why co-simulation exists.  
I personally don’t use it. I check VHDL generated code when I have a doubt.

---

<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, 6:07pm UTC](https://discourse.myhdl.org/t/variables-in-vhdl-conversion/327/10 "2018-08-31T18:07:42Z")

</div>

@mhavu Perhaps declare _interim_ Signal avoiding the inference of variables. Unfortunately MyHDL will now _wrongly_ complain that you are reading outputs of the `@always_comb` process back - I commented that out in my MHDL code base 😄  
I also think that you can promote the variable by specifying it outside the `@always_comb` as an `intbv`, so the 32-bit limit of the integer (in VHDL) doesn’t bite.

---

<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:** [September 3, 2018, 1:57pm UTC](https://discourse.myhdl.org/t/variables-in-vhdl-conversion/327/11 "2018-09-03T13:57:18Z")

</div>

> [@josyb](#):
>
> Perhaps declare _interim_ Signal avoiding the inference of variables. Unfortunately MyHDL will now _wrongly_ complain that you are reading outputs of the `@always_comb` process back

I can get rid of the complaint by adding one more `@always_comb` process. This may be the cleanest option. It will also allow me to continue using left shift the way I have been doing. (Thanks for @DrPi for spotting the error!)

> [@](#):
>
> I also think that you can promote the variable by specifying it outside the `@always_comb` as an `intbv` , so the 32-bit limit of the integer (in VHDL) doesn’t bite.

That won’t work because of Python’s duck typing. The assignment will just replace whatever `intbv` value the variable had by a new integer value. The VHDL conversion in MyHDL is not clever enough to intervene with that. (I don’t know whether that would even be possible.)

---

<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:** [September 3, 2018, 2:00pm UTC](https://discourse.myhdl.org/t/variables-in-vhdl-conversion/327/12 "2018-09-03T14:00:08Z")

</div>

I think it works like this:

```auto
temp = intbv(0)[8:]

@always_comb
def comb():
   temp[:] = something + whatever

```

I almost never use variables 🙂

---

<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:** [September 3, 2018, 2:04pm UTC](https://discourse.myhdl.org/t/variables-in-vhdl-conversion/327/13 "2018-09-03T14:04:12Z")

</div>

Ah, true. That should work.

---

<div class="post-metadata">

**Author:** ![hgomersall](https://yyz2.discourse-cdn.com/flex030/user_avatar/discourse.myhdl.org/hgomersall/32/10_2.png) [@hgomersall](https://discourse.myhdl.org/u/hgomersall)\
**Post date:** [September 5, 2018, 1:34pm UTC](https://discourse.myhdl.org/t/variables-in-vhdl-conversion/327/14 "2018-09-05T13:34:19Z")

</div>

Should there be a `.next` in there?

---

<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:** [September 5, 2018, 1:48pm UTC](https://discourse.myhdl.org/t/variables-in-vhdl-conversion/327/15 "2018-09-05T13:48:42Z")

</div>

Not if `temp` is not a `Signal`. If it is, `temp.next` will suffice. (The `[:]` is not necessary.)

---

<div class="post-metadata">

**Author:** ![hgomersall](https://yyz2.discourse-cdn.com/flex030/user_avatar/discourse.myhdl.org/hgomersall/32/10_2.png) [@hgomersall](https://discourse.myhdl.org/u/hgomersall)\
**Post date:** [September 5, 2018, 2:27pm UTC](https://discourse.myhdl.org/t/variables-in-vhdl-conversion/327/16 "2018-09-05T14:27:27Z")

</div>

Oh yeah, missed lack of a `Signal` 🙂

TBH, I always use a signal explicitly. I’m very wary of variables because I keep getting burned by them inside the downstream tools.
