![]() |
|
|
|
#1 |
|
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; --------------------------------------------------------------------------- MM |
|
|
|
|
#2 |
|
Posts: n/a
|
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/ Renaud Pacalet |
|
|
|
#3 |
|
Posts: n/a
|
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/ Renaud Pacalet |
|
|
|
#4 |
|
Posts: n/a
|
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 MM |
|
![]() |
| Thread Tools | Search this Thread |
|
|