# Negating a number in VHDL using least logic

I want to do something like this:

variable a, b (both signed)
variable error (signed also)

if (a is positive)
b = error
else
b = -error


So far I have something like this:

if (a(a'high) = '0') then
b <= error;
else
b <= -1 * error;
end if;


But this doesn't work because the multiplication makes the RHS a larger width.

What is the best way to attack this? I could write a function to do a 2's complement negation and use this, but I'm also rather worried about the effect on timing requirements.

-
Regardless of width issues, that can be trivially fixed, you do not want to sacrifice a hardware multiplier to do this. –  drxzcl Aug 14 '12 at 21:52
Why worry about least logic? The synthesis tool knows how to optimize. –  Brian Carlton Aug 14 '12 at 22:25
@BrianCarlton: If you prefer, read this question as "how can I specify this behavior in such a way that the synthesis tool produces optimal logic". –  drxzcl Aug 15 '12 at 6:53
RE: Bit extension: What do you want it to do with the maximal negative number? The +ve equivalent can't be represented in the same number of bits... –  Martin Thompson Aug 15 '12 at 9:38
@MartinThompson: Good point regarding the maximal negative number. However it should be OK, as if things have got that high (32767), then there are bigger issues. –  benjwy Aug 15 '12 at 21:50

Something like:

variable a: signed(7 downto 0);
variable error: signed(a'range);
variable b: unsigned(a'range);

if a < 0 then
b:=-error;
else
b:=error;
end if;


However you do it, the logic should end up the same (even if you multiply by -1, I'd hope the synth is smart enough to notice and just stick a set of LUTs and a carry chain in there!)

-
begin

b <= not(error) + "00000001";

end


There are some edge cases, watch out, read this carefully.

I believe you know it but I'll mention it just in case. bits are bits and the interpretation of them is made by the user, it can be a picture, signal, number, positive number etc. most FPGAs treats numbers as 2's complement.

-
Did you mean 'error' to be in place of 'b'? –  benjwy Aug 14 '12 at 21:51
Can't you just cast it to a signed and use the unary minus? –  drxzcl Aug 14 '12 at 21:57
@benjwy corrected –  0x90 Aug 15 '12 at 3:29