Synplify doesn't like it...

M

MM

The code below compiles fine in Active HDL and synthesizes by XST, however
Synplify says
that the sig_num((sig_num'Left - 1) downto 0) slice is out of range. How
should I write it so it will understand?

/Mikhail

---------------------------------------------------------------------------
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.std_logic_UNSIGNED.all;

package num_convert is
function two_cmplt ( sig_num : std_logic_vector )
return std_logic_vector;
end package num_convert ;


package body num_convert is

function two_cmplt ( sig_num : std_logic_vector )
return std_logic_vector is
variable result : std_logic_vector (sig_num'LENGTH-1 downto 0);
begin
if sig_num(sig_num'Left)='1' then
result := '1' & ((not sig_num((sig_num'Left - 1) downto 0)) + 1);
else
result := sig_num;
end if;

return result;
end two_cmplt;

end package body num_convert;
---------------------------------------------------------------------------
 
R

Renaud Pacalet

MM a écrit :
The code below compiles fine in Active HDL and synthesizes by XST, however
Synplify says
that the sig_num((sig_num'Left - 1) downto 0) slice is out of range. How
should I write it so it will understand?

/Mikhail

---------------------------------------------------------------------------
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.std_logic_UNSIGNED.all;

package num_convert is
function two_cmplt ( sig_num : std_logic_vector )
return std_logic_vector;
end package num_convert ;


package body num_convert is

function two_cmplt ( sig_num : std_logic_vector )
return std_logic_vector is
variable result : std_logic_vector (sig_num'LENGTH-1 downto 0);
begin
if sig_num(sig_num'Left)='1' then
result := '1' & ((not sig_num((sig_num'Left - 1) downto 0)) + 1);
else
result := sig_num;
end if;

return result;
end two_cmplt;

end package body num_convert;

Very common problem: as you know nothing about the argument that will be
passed to your function you can't decide that:
sig_num((sig_num'Left - 1) downto 0)
is in range. Example:

variable A: std_logic_vector(8 to 16);
...
two_cmplt(A);

then you'll have:
sig_num'Left = 8
and
sig_num((sig_num'Left - 1) downto 0) = A(7 downto 0) -- out of range

Solution: renormalize the argument:

function two_cmplt ( sig_num : std_logic_vector )
return std_logic_vector is
variable v, result : std_logic_vector (sig_num'LENGTH-1 downto 0);
begin
v := sig_num;
if v(v'LENGTH - 1) = '1' then
result := '1' & ((not v(v'LENGTH - 2 downto 0) + 1);
else
result := v;
end if;
return result;
end two_cmplt;

But if your function is supposed to compute the absolute value of its
argument then you'll be disapointed ; with argument -1 on 4 bits
("1111") it will return "1001" (-7) instead of "0001" (1). Moreover
there are much more efficient, elegant, readable, ways:

library IEEE;
use IEEE.STD_LOGIC_1164.all;
use IEEE.NUMERIC_STD.all; -- this one is a standard one!

function TWO_CMPLT(SIG_NUM: STD_LOGIC_VECTOR) return STD_LOGIC_VECTOR is
begin
return STD_LOGIC_VECTOR(abs(SIGNED(SIG_NUM)));
end TWO_CMPLT;

Best regards,
--
Renaud Pacalet, GET/ENST/COMELEC/LabSoC
Institut Eurecom BP 193, 2229 route des Cretes
F-06904 Sophia-Antipolis Cedex
Tel : +33 (0) 4 9300 2770
Fax : +33 (0) 4 9300 2627
Fight Spam! Join EuroCAUCE: http://www.euro.cauce.org/
 
R

Renaud Pacalet

Renaud Pacalet a écrit :
...
But if your function is supposed to compute the absolute value of its
argument then you'll be disapointed ; with argument -1 on 4 bits
("1111") it will return "1001" (-7) instead of "0001" (1). Moreover
there are much more efficient, elegant, readable, ways:

library IEEE;
use IEEE.STD_LOGIC_1164.all;
use IEEE.NUMERIC_STD.all; -- this one is a standard one!

function TWO_CMPLT(SIG_NUM: STD_LOGIC_VECTOR) return STD_LOGIC_VECTOR is
begin
return STD_LOGIC_VECTOR(abs(SIGNED(SIG_NUM)));
end TWO_CMPLT;

I just understood that your argument representation was probably sign
and magnitude and not 2's complement as I first thought. Sorry. My first
remark above is nonsense. But the second one remains true:

function TWO_CMPLT(SIG_NUM: STD_LOGIC_VECTOR) return STD_LOGIC_VECTOR is
variable V: SIGNED(SIG_NUM'length - 1 downto 0) := SIG_NUM;
begin
if V(V'left) = '1' then
V(V'left) := '0';
V := -V;
end if;
return STD_LOGIC_VECTOR(V);
end TWO_CMPLT;

Best regards,
--
Renaud Pacalet, GET/ENST/COMELEC/LabSoC
Institut Eurecom BP 193, 2229 route des Cretes
F-06904 Sophia-Antipolis Cedex
Tel : +33 (0) 4 9300 2770
Fax : +33 (0) 4 9300 2627
Fight Spam! Join EuroCAUCE: http://www.euro.cauce.org/
 
M

MM

Thanks a lot, Renaud.
But if your function is supposed to compute the absolute value of its
argument then you'll be disapointed ; with argument -1 on 4 bits
("1111") it will return "1001" (-7) instead of "0001" (1).

No, it is supposed to do two's complement...

/Mikhail
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,769
Messages
2,569,580
Members
45,055
Latest member
SlimSparkKetoACVReview

Latest Threads

Top