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

This If statement fails to be true

Ask a question - edaboard.com

elektroda.net NewsGroups Forum Index - VHDL Language - This If statement fails to be true

David Perry
Guest

Wed May 23, 2018 4:45 pm   



I have a simple if statment:
If Ctrl_uf > to_ufixed(0, 15, 0) then

Ctrl_uf is:
Signal Ctrl_uf : ufixed(15 downto 0) := x"8000";
it is never 0 for the purposes of trying to get this to work.
The code after the if statement is never enabled, if I comment out the if/end if then the code gets used.

For completeness here's a bit more code:

if Ctrl_Up = HI then
if Ctrl_uf < to_ufixed(65535, 15, 0) then
CtrlCalc_uf := Ctrl_uf + to_ufixed(1, 15, 0);
Ctrl_uf <= CtrlCalc_uf(15 downto 0);
end if;
else
if Ctrl_Dn = HI then
if Ctrl_uf > to_ufixed(0, 15, 0) then
CtrlCalc_uf := Ctrl_uf - to_ufixed(1, 15, 0);
Ctrl_uf <= CtrlCalc_uf(15 downto 0);
end if;
end if;
end if;

essentially, Ctrl_Up increments the value of Ctrl_uf correctly, but Ctrl_Dn doesn't and the signal is definitely there, if I comment out the problem 'if' statement, it works but without the end-stop protection.

Any ideas?

David Perry
Guest

Wed May 23, 2018 4:45 pm   



I forgot to mention, I did also use 0.0 as the number, it made no difference

David Perry
Guest

Wed May 23, 2018 5:45 pm   



Oh, and it simulates fine, when I put it on hardware it only increments, decrement only works with the if/end if commented out!

Jim Lewis
Guest

Wed May 23, 2018 6:45 pm   



On Wednesday, May 23, 2018 at 8:32:05 AM UTC-7, David Perry wrote:
Quote:
I have a simple if statment:
If Ctrl_uf > to_ufixed(0, 15, 0) then


You are working harder than you need to. The overloading allows both integer and real valued literals, so your comparison becomes:
if Ctrl_uf > 0 then
(ExtraCarryOut_sl, Ctrl_uf) <= Ctrl_uf - 1;

Have you also tried:
if Ctrl_uf /= 0 then

David Perry
Guest

Wed May 23, 2018 6:45 pm   



Quote:
You are working harder than you need to. The overloading allows both integer and real valued literals, so your comparison becomes:
if Ctrl_uf > 0 then
(ExtraCarryOut_sl, Ctrl_uf) <= Ctrl_uf - 1;


I have now tried:
if Ctrl_uf > 0 then
but this didn't work. I can't figure out how to make your carry bit work either Sad

David Perry
Guest

Wed May 23, 2018 7:45 pm   



Quote:
Have you also tried:
if Ctrl_uf /= 0 then


I finally tried that out of desperation, yes, that does work. However, this won't solve my problem when I want to change the endstop from zero. Eventually, I will have different addition/subtraction values, the endstops will need to account for these so that I don't overflow, but baby steps...

David Perry
Guest

Wed May 23, 2018 7:45 pm   



To prove to myself that I will have problems, I moved my end stops:

if Ctrl_Up = HI then
if Ctrl_uf < 65530 then
....
if Ctrl_Dn = HI then
if Ctrl_uf > 10 then

both controls fail. As it currently stands, the only comparisons I can get to work are:
/= 0
and
< 65535

David Perry
Guest

Wed May 23, 2018 8:45 pm   



Just for fun, I changed Ctrl_uf to a shared variable and did the following:

if Ctrl_Dn = HI then
Ctrl_uf := x"0F00";
if Ctrl_uf > 10 then
Ctrl_uf := x"0EFF";
end if;
end if;

The result? 0F00
This similuates absolutely fine, the result is 0EFF as expected.
I now suspect this is 'just' an issue with xilinx not compiling properly for some reason, I shall post on their forums. Sad

KJ
Guest

Thu May 24, 2018 1:45 am   



It could be that Xilinx software is treating the 8000 as a signed number rather than unsigned.

Kevin

David Perry
Guest

Thu May 24, 2018 7:45 am   



On Thursday, 24 May 2018 01:10:50 UTC+1, KJ wrote:
Quote:
It could be that Xilinx software is treating the 8000 as a signed number rather than unsigned.

Kevin


I did briefly ponder that, but it fails with any value. I changed the top-end check away from 65535 and that then fails too. Also see the post prior to yours, clearly something is quite wrong Sad

David Perry
Guest

Thu May 24, 2018 9:45 am   



As a work-around I have used unsigned instead of ufixed then converted it to ufixed later where it's used in another process for some maths.

Why does ufixed insist on extending the vector size while unsigned doesn't when doing +/-? My subtraction ends up as a simple:
Ctrl_uf := Ctrl_uf - 1;

KJ
Guest

Thu May 24, 2018 11:45 pm   



ufixed adds a bit because mathematically that is the correct thing to do when adding or subtracting. This corrects a 'deficiency' with the unsigned type. Of course many times one does want modulo arithmetic in which case unsigned may be a better type to use...and using ufixed in those situations requires adding resize function calls.

I would think that if you take your test case, add a copy where the only difference is the type used and a conversion from ufixed to unsigned and show that you get two different outputs that would be an awfully strong bug case to let Xilinx chew on.

Have you tried defining a ufixed constant with the to_ufixed function and then using that constant in the > comparison. There is no reason that a bug free tool would work any differently, but if it does work it gives you a second workaround.

Kevin Jennings

David Perry
Guest

Fri May 25, 2018 10:45 am   



I see, that makes sense.

I have raised the issue on the xilinx forums:
https://forums.xilinx.com/t5/Simulation-and-Verification/Simple-If-statement-simulates-correctly-but-fails-in-hardware/td-p/858986

I haven't yet done an unsigned/ufixed comparative test, that could be well worth doing!

I did try using a constant ufixed, it didn't make any difference.

Charles Bailey
Guest

Wed May 30, 2018 5:45 pm   



On 2018-05-23 10:32, David Perry wrote:
Quote:
I have a simple if statment:
If Ctrl_uf > to_ufixed(0, 15, 0) then

Ctrl_uf is:
Signal Ctrl_uf : ufixed(15 downto 0) := x"8000";
it is never 0 for the purposes of trying to get this to work.
The code after the if statement is never enabled, if I comment out the if/end if then the code gets used.

For completeness here's a bit more code:

if Ctrl_Up = HI then
if Ctrl_uf < to_ufixed(65535, 15, 0) then
CtrlCalc_uf := Ctrl_uf + to_ufixed(1, 15, 0);
Ctrl_uf <= CtrlCalc_uf(15 downto 0);
end if;
else
if Ctrl_Dn = HI then
if Ctrl_uf > to_ufixed(0, 15, 0) then
CtrlCalc_uf := Ctrl_uf - to_ufixed(1, 15, 0);
Ctrl_uf <= CtrlCalc_uf(15 downto 0);
end if;
end if;
end if;

essentially, Ctrl_Up increments the value of Ctrl_uf correctly, but Ctrl_Dn doesn't and the signal is definitely there, if I comment out the problem 'if' statement, it works but without the end-stop protection.

Any ideas?


Why make it so hard? Why not just code something like this?
Signal Ctrl_uf : integer range 0 to 65535:=32768;

if Ctrl_Up = HI then
if Ctrl_uf < 65535 then
Ctrl_uf <= Ctrl_uf+1;
end if;
elsif Ctrl_Dn = HI then
if Ctrl_uf > 0 then
Ctrl_uf <= Ctrl_uf-1;
end if;
end if;

This should simulate an synthesize just fine.

Charles Bailey

David Perry
Guest

Thu May 31, 2018 10:45 am   



I originally did it with ufixed because I use the number in some maths elsewhere, which is also ufixed, the idea was to use the same types to make life easier. Irrespective of that, the problem seems to be real and the consequences could be quite bad if it is wider reaching than the problems I've found.

elektroda.net NewsGroups Forum Index - VHDL Language - This If statement fails to be true

Ask a question - edaboard.com

Arabic version Bulgarian version Catalan version Czech version Danish version German version Greek version English version Spanish version Finnish version French version Hindi version Croatian version Indonesian version Italian version Hebrew version Japanese version Korean version Lithuanian version Latvian version Dutch version Norwegian version Polish version Portuguese version Romanian version Russian version Slovak version Slovenian version Serbian version Swedish version Tagalog version Ukrainian version Vietnamese version Chinese version Turkish version
EDAboard.com map