EDAboard.com | EDAboard.de | EDAboard.co.uk | WTWH Media

elektroda.net NewsGroups Forum Index - VHDL Language - **simple unsigned maths problem with if statement**

Guest

Thu Feb 22, 2018 1:38 pm

I'm having an issue with a simple if statement:

if ClampIn_u + DMD_u < x"FFFF" then --this doesn't work

ClampIn_u := ClampIn_u + DMD_u;

else

ClampIn_u := x"FFFF";

end if;

What happens is the addition always occurs, I end up overflowing and I get the wrong result.

I tried making the right hand side of the if bigger in attempt to make it work:

if ClampIn_u + DMD_u < x"0FFFF" then

but that fails in the same way.

If I rearrange the maths (subtract DMD_u from both sides):

if ClampIn_u < x"FFFF" - DMD_u then

this works.

DMD_u is an unsigned 16 bit signal, ClampIn_u is an unsigned 16 bit variable.

I'm struggling to find an explanation, I can see why my original might fail but I would have expected "0FFFF" to work.

Any insight would be appreciated :)

Dave

Guest

Thu Feb 22, 2018 2:54 pm

On 2/22/18 6:38 AM, David Perry wrote:

I'm having an issue with a simple if statement:

if ClampIn_u + DMD_u < x"FFFF" then --this doesn't work

ClampIn_u := ClampIn_u + DMD_u;

else

ClampIn_u := x"FFFF";

end if;

What happens is the addition always occurs, I end up overflowing and I get the wrong result.

I tried making the right hand side of the if bigger in attempt to make it work:

if ClampIn_u + DMD_u < x"0FFFF" then

but that fails in the same way.

If I rearrange the maths (subtract DMD_u from both sides):

if ClampIn_u < x"FFFF" - DMD_u then

this works.

DMD_u is an unsigned 16 bit signal, ClampIn_u is an unsigned 16 bit variable.

I'm struggling to find an explanation, I can see why my original might fail but I would have expected "0FFFF" to work.

Any insight would be appreciated :)

Dave

if ClampIn_u + DMD_u < x"FFFF" then --this doesn't work

ClampIn_u := ClampIn_u + DMD_u;

else

ClampIn_u := x"FFFF";

end if;

What happens is the addition always occurs, I end up overflowing and I get the wrong result.

I tried making the right hand side of the if bigger in attempt to make it work:

if ClampIn_u + DMD_u < x"0FFFF" then

but that fails in the same way.

If I rearrange the maths (subtract DMD_u from both sides):

if ClampIn_u < x"FFFF" - DMD_u then

this works.

DMD_u is an unsigned 16 bit signal, ClampIn_u is an unsigned 16 bit variable.

I'm struggling to find an explanation, I can see why my original might fail but I would have expected "0FFFF" to work.

Any insight would be appreciated :)

Dave

A 16 bit unsigned + a 16 bit unsigned will do the arithmetic in 16 bits,

and ignore the overflow/carry out. Making the right hand side bigger

doesn't affect how the left hand side is computed.

If you coerced the signals on the left hand side to be 17 bit signals

(by concatenating a higher order 0 bit), then the arithmetic would

produce the needed value, and the comparison would work.

Guest

Thu Feb 22, 2018 4:53 pm

I see, my assumptions were incorrect.

So something like:

MyTemp17b_u := ClampIn_u + DMD_u; --a 17bit unsigned variable

if MyTemp17b_u < x"FFFF" then

ClampIn_u := ClampIn_u + DMD_u;

else

ClampIn_u := x"FFFF";

end if;

I could perhaps then use that extra bit to my advantage by testing that rather than the whole result? Such as:

if MyTemp17b_u(16) = '0' then --check the overflow bit

And would I be best re-using the result and just copying the lower 16 bits, I suspect it might create a second addition otherwise, so I end up with:

MyTemp17b_u := ClampIn_u + DMD_u; --a 17bit unsigned variable

if MyTemp17b_u(16) = '0' then --check the overflow bit

ClampIn_u := MyTemp17b_u(15 downto 0);

else

ClampIn_u := x"FFFF";

end if;

I don't actually need to be gate efficient with what I'm playing with, but it's interesting to fiddle with :)

Appreciate the time Richard, cheers.

Dave

Guest

Sat Feb 24, 2018 2:43 am

On 2/22/18 9:53 AM, David Perry wrote:

I see, my assumptions were incorrect.

So something like:

MyTemp17b_u := ClampIn_u + DMD_u; --a 17bit unsigned variable

if MyTemp17b_u < x"FFFF" then

ClampIn_u := ClampIn_u + DMD_u;

else

ClampIn_u := x"FFFF";

end if;

I could perhaps then use that extra bit to my advantage by testing that rather than the whole result? Such as:

if MyTemp17b_u(16) = '0' then --check the overflow bit

And would I be best re-using the result and just copying the lower 16 bits, I suspect it might create a second addition otherwise, so I end up with:

MyTemp17b_u := ClampIn_u + DMD_u; --a 17bit unsigned variable

if MyTemp17b_u(16) = '0' then --check the overflow bit

ClampIn_u := MyTemp17b_u(15 downto 0);

else

ClampIn_u := x"FFFF";

end if;

I don't actually need to be gate efficient with what I'm playing with, but it's interesting to fiddle with :)

Appreciate the time Richard, cheers.

Dave

So something like:

MyTemp17b_u := ClampIn_u + DMD_u; --a 17bit unsigned variable

if MyTemp17b_u < x"FFFF" then

ClampIn_u := ClampIn_u + DMD_u;

else

ClampIn_u := x"FFFF";

end if;

I could perhaps then use that extra bit to my advantage by testing that rather than the whole result? Such as:

if MyTemp17b_u(16) = '0' then --check the overflow bit

And would I be best re-using the result and just copying the lower 16 bits, I suspect it might create a second addition otherwise, so I end up with:

MyTemp17b_u := ClampIn_u + DMD_u; --a 17bit unsigned variable

if MyTemp17b_u(16) = '0' then --check the overflow bit

ClampIn_u := MyTemp17b_u(15 downto 0);

else

ClampIn_u := x"FFFF";

end if;

I don't actually need to be gate efficient with what I'm playing with, but it's interesting to fiddle with :)

Appreciate the time Richard, cheers.

Dave

I am not an expert here, but my first expectation would be that the term

ClampIn_u + DMD_u would still be done to 16 bit here, and then that 16

bit result extended to 17 (but I would admit I might be wrong).

I would extend ClampIn_u and DMD_u to 17 bits first, and then add them

(preferably saving the 17 bit result for reuse).

Guest

Mon Feb 26, 2018 12:59 am

On 24.02.2018 01:43, Richard Damon wrote:

[...]

I am not an expert here, but my first expectation would be that the term

ClampIn_u + DMD_u would still be done to 16 bit here, and then that 16

bit result extended to 17 (but I would admit I might be wrong).

I would extend ClampIn_u and DMD_u to 17 bits first, and then add them

(preferably saving the 17 bit result for reuse).

ClampIn_u + DMD_u would still be done to 16 bit here, and then that 16

bit result extended to 17 (but I would admit I might be wrong).

I would extend ClampIn_u and DMD_u to 17 bits first, and then add them

(preferably saving the 17 bit result for reuse).

That's correct. However you only need to extend one operand to 17 bits

to force the result to 17 bits (though extending both works just as well

but requires a bit more typing)

Nicolas

Guest

Mon Feb 26, 2018 10:57 am

OK, how about:

MyTemp17b_u := '0' & ClampIn_u;

MyTemp17b_u := MyTemp17b_u + DMD_u;

I think I need to put the:

'0' &

in there as I have experienced what I can only describe as "filling from the left", something else I've struggled to understand :(

Cheers,

Dave

Guest

Mon Feb 26, 2018 6:34 pm

On 02/26/2018 12:57 AM, David Perry wrote:

OK, how about:

MyTemp17b_u := '0' & ClampIn_u;

MyTemp17b_u := MyTemp17b_u + DMD_u;

I think I need to put the:

'0' &

in there as I have experienced what I can only describe as "filling from the left", something else I've struggled to understand :(

Cheers,

Dave

MyTemp17b_u := '0' & ClampIn_u;

MyTemp17b_u := MyTemp17b_u + DMD_u;

I think I need to put the:

'0' &

in there as I have experienced what I can only describe as "filling from the left", something else I've struggled to understand :(

Cheers,

Dave

Well then write it this way to do precisely the same thing:

MyTemp17b_u := RESIZE(ClampIn_u, 17)

MyTemp17b_u := MyTemp17b_u + DMD_u;

You have an unsigned value in 16 bits; it's between 0-65535. You can

put as many zeros on as many additional MSBs as you like, which changes

the number of bits you're using to represent it, but the value there is

still 0-65535, the same as in decimal 10, 010, and 000010 all represent

the number between 9 and 11.

--

Rob Gaddi, Highland Technology -- www.highlandtechnology.com

Email address domain is currently out of order. See above to fix.

Guest

Tue Feb 27, 2018 4:35 pm

Ah, I forgot about resize! Thanks Rob

Guest

Wed Jun 13, 2018 5:45 pm

On Thursday, February 22, 2018 at 6:38:54 AM UTC-5, David Perry wrote:

I'm having an issue with a simple if statement:

if ClampIn_u + DMD_u < x"FFFF" then --this doesn't work

ClampIn_u := ClampIn_u + DMD_u;

else

ClampIn_u := x"FFFF";

end if;

What happens is the addition always occurs, I end up overflowing and I get the wrong result.

I tried making the right hand side of the if bigger in attempt to make it work:

if ClampIn_u + DMD_u < x"0FFFF" then

but that fails in the same way.

If I rearrange the maths (subtract DMD_u from both sides):

if ClampIn_u < x"FFFF" - DMD_u then

this works.

DMD_u is an unsigned 16 bit signal, ClampIn_u is an unsigned 16 bit variable.

I'm struggling to find an explanation, I can see why my original might fail but I would have expected "0FFFF" to work.

Any insight would be appreciated

if ClampIn_u + DMD_u < x"FFFF" then --this doesn't work

ClampIn_u := ClampIn_u + DMD_u;

else

ClampIn_u := x"FFFF";

end if;

What happens is the addition always occurs, I end up overflowing and I get the wrong result.

I tried making the right hand side of the if bigger in attempt to make it work:

if ClampIn_u + DMD_u < x"0FFFF" then

but that fails in the same way.

If I rearrange the maths (subtract DMD_u from both sides):

if ClampIn_u < x"FFFF" - DMD_u then

this works.

DMD_u is an unsigned 16 bit signal, ClampIn_u is an unsigned 16 bit variable.

I'm struggling to find an explanation, I can see why my original might fail but I would have expected "0FFFF" to work.

Any insight would be appreciated

This thread is getting a bit old in the tooth, but at least it is still the same year,

I see the problem (from the perspective of an old school hardware designer) as being one of not considering what hardware will be produced from your description. After all, HDL stands for "Hardware Description" Language and to produce the best code I think the resulting hardware should be considered when writing code.

The hardware produced by this code should be an adder followed by a multiplexer with the carry out of the adder used to control the mux. In fact, it really isn't even a mux, but just a set of OR gates to force the output to a 1. So this would utilize two 4 input LUTs for each input bit to produce a result. Even better yet would be if the tools were clever enough to combine the OR gates with the adder for 1 LUT per bit, but I'm not sure the tools are quite up to it. Still, the key is using the carry out of the adder to control the OR gates.

I would write this as a 17 bit addition outside of the conditional statement. Then use the msb (which the tools should understand is the carry out of the lower 16 bits) to drive the conditional which selects either the addition result or the max 16 bit value.

MyTemp17b_u := '0' & ClampIn_u + DMD_u;

if (MyTemp17b_u(MyTemp17b_u'high) = '1') then

Result := x"FFFF";

else

Result := MyTemp17b_u;

endif;

To me this is more clear and I am pretty confident of knowing what hardware will be produced by the code.

Rick C.

Guest

Wed Jun 13, 2018 7:45 pm

Oddly enough, I'm trying to move away from throwing down gates (I filled a spartan 3AN 1400 with schematics), but there are times when I think to myself, you know, I could throw this down in a few minutes if I didn't do it 'properly' using VHDL...

Guest

Thu Jun 14, 2018 1:45 am

On Wednesday, June 13, 2018 at 2:30:45 PM UTC-4, David Perry wrote:

> Oddly enough, I'm trying to move away from throwing down gates (I filled a spartan 3AN 1400 with schematics), but there are times when I think to myself, you know, I could throw this down in a few minutes if I didn't do it 'properly' using VHDL...

Sorry, I'm not clear on what you are saying. Are you saying you could work faster by not considering how your code is synthesized? Yes, that is certainly true. Or are you saying VHDL is a overstuffed pig of a language and you would just prefer to be laying down gates? I would not totally disagree with that either.

A long time ago one of the posters in c.a.f was famous for very high speed pipelined designs done in modular, hierarchical schematics. He resisted staunchly the movement to HDL... until he was taught how he could accomplish the same sort of library driven, modular, hierarchical designs in VHDL which in addition could be version controlled like any other software. That was when I realized I had no reason to regret having switched to VHDL (other than possibly not having switched to Verilog).

Rick C.

Guest

Thu Jun 14, 2018 1:45 pm

Prefer to lay down gates and ditch the VHDL. There are times when I think VHDL might be easier for certain tasks, then I start writing it and wish I'd implemented a schematic....

elektroda.net NewsGroups Forum Index - VHDL Language - **simple unsigned maths problem with if statement**