Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

Synopsys DC: ELAB-922 (error) %s Constant value required

Status
Not open for further replies.

omara007

Advanced Member level 4
Joined
Jan 6, 2003
Messages
1,237
Helped
50
Reputation
102
Reaction score
16
Trophy points
1,318
Location
Cairo/Egypt
Activity points
9,716
constant value required

Hi guys ..

I designed a VHDL function that returns a truncated-vector from the effective range of a SIGNED vector. In other words, the truncation is done on the smallest size vector that can contain that signed value without any duplication to the sign bit.


Here is the function:
Code:
   ----------------------------------------------------------------------------
   -- TRUNCATE_EFFECTIVE
   ----------------------------------------------------------------------------
   function TRUNCATE_EFFECTIVE (INPUT_VECTOR : SIGNED; TRUNCATION_SIZE : POSITIVE) return SIGNED is
     constant NAS             : SIGNED (1 downto 0) := (others => '0');
     variable RESULT          : SIGNED(TRUNCATION_SIZE-1 downto 0);
     variable ZERO_INDEX      : INTEGER;     
     variable ONE_INDEX       : INTEGER;
   begin
     if (INPUT_VECTOR'length<1) then
       return NAS;
     elsif INPUT_VECTOR'length = TRUNCATION_SIZE then
       return INPUT_VECTOR;
     elsif INPUT_VECTOR'length < TRUNCATION_SIZE then
       RESULT := RESIZE(INPUT_VECTOR, TRUNCATION_SIZE);
       return RESULT;
     elsif INPUT_VECTOR'length > TRUNCATION_SIZE then
        if INPUT_VECTOR(INPUT_VECTOR'left) = '0' then     -- (+ve) input vector
          ONE_INDEX := ONE_FIRST_OCCURANCE(INPUT_VECTOR);
          if ONE_INDEX = -1 then
            RESULT := (others => '0');
          elsif ONE_INDEX <= TRUNCATION_SIZE-1 then
            RESULT := INPUT_VECTOR(TRUNCATION_SIZE-1 downto 0);             
          else
            RESULT := INPUT_VECTOR(ONE_INDEX+1 downto ONE_INDEX-TRUNCATION_SIZE+2);
          end if;               
        elsif INPUT_VECTOR(INPUT_VECTOR'left) = '1' then  -- (-ve) input vector
          ZERO_INDEX := ZERO_FIRST_OCCURANCE(INPUT_VECTOR);
          if ZERO_INDEX = -1 then
            RESULT := (others => '1');             
          elsif ZERO_INDEX <= TRUNCATION_SIZE-1 then
            RESULT := INPUT_VECTOR(TRUNCATION_SIZE-1 downto 0);
          else
            RESULT := INPUT_VECTOR(ZERO_INDEX+1 downto ZERO_INDEX-TRUNCATION_SIZE+2);                         
          end if; 
        end if;
       return RESULT;     
     end if;
   end TRUNCATE_EFFECTIVE;
   ----------------------------------------------------------------------------


Where (ZERO_FIRST_OCCURANCE) and (ONE_FIRST_OCCURANCE) are as their names indicate .. and here are their codes:


Code:
   ----------------------------------------------------------------------------
   -- ZERO_FIRST_OCCURANCE
   ----------------------------------------------------------------------------
   function ZERO_FIRST_OCCURANCE (ARG : SIGNED) return INTEGER is
   -- ARG'right has to always be (0). For example, ARG: signed(15 downto 0)
     
     constant NAS : SIGNED (1 downto 0) := (others => '0');
     variable INTERMEDIATE_VECTOR : SIGNED(ARG'length-1 downto 0);  -- An intermediate vector of the
                                                                    -- same size as the input vector
                                                                    -- and contains only one bit set
                                                                    -- to '1' and the rest of the bits
                                                                    -- are all zeros.
                                                                    -- This '1' has the order of the
                                                                    -- first 'ZERO' occurance.
     variable CHECK_ALL_ONES : STD_LOGIC;  -- ='1' if the input vector is ALL_ONES, '0' otherwise
     constant N              : POSITIVE := ARG'length;  -- Length of the input vector
     variable ZERO_INDEX     : NATURAL;     -- Index of '1' in the intermediate vector
     
   begin
     if (ARG'length<1) then
       return to_integer(NAS);
     else
       CHECK_ALL_ONES := all_ones(std_logic_vector(ARG));
       if CHECK_ALL_ONES = '0' then
         INTERMEDIATE_VECTOR(N-1) := not(ARG(N-1));
         for i in N-2 downto 1 loop
           INTERMEDIATE_VECTOR(i) := and_reduce(ARG(N-1 downto i+1) & not(ARG(i)) & to_signed(-1,i));
         end loop;  -- i
         INTERMEDIATE_VECTOR(0) := and_reduce(ARG(N-1 downto 1) & not(ARG(0)));
         for j in N-1 downto 0 loop
           if INTERMEDIATE_VECTOR(j) = '1'then
             ZERO_INDEX := j;
           end if;
         end loop;  -- j
         return ZERO_INDEX;         
       else
          return -1;
       end if;
     end if;
   end ZERO_FIRST_OCCURANCE;
   ----------------------------------------------------------------------------

Code:
  ----------------------------------------------------------------------------
   -- ONE_FIRST_OCCURANCE
   ----------------------------------------------------------------------------
   function ONE_FIRST_OCCURANCE (ARG : SIGNED) return INTEGER is
   -- ARG'right has to always be (0). For example, ARG: signed(15 downto 0)
     constant NAS             : SIGNED (1 downto 0) := (others => '0');
     variable CHECK_ALL_ZEROS : STD_LOGIC;  -- ='1' if the input vector is ALL_ZEROS, '0' otherwise
     variable ARG_STD         : STD_LOGIC_VECTOR(ARG'length-1 downto 0);
     variable INV_ARG_STD     : STD_LOGIC_VECTOR(ARG'length-1 downto 0);
     variable INV_ARG         : SIGNED(ARG'length-1 downto 0);
     variable ONE_INDEX       : INTEGER;     
   begin
     if (ARG'length<1) then
       return to_integer(NAS);
     else
       CHECK_ALL_ZEROS := all_zeros(std_logic_vector(ARG));
       if CHECK_ALL_ZEROS = '0' then
         ARG_STD        := std_logic_vector(ARG);
         INV_ARG_STD    := not ARG_STD;
         INV_ARG        := signed(INV_ARG_STD);
         ONE_INDEX      := ZERO_FIRST_OCCURANCE(INV_ARG);
         return ONE_INDEX;         
       else
         return -1;
       end if;
     end if;
   end ONE_FIRST_OCCURANCE;
   ----------------------------------------------------------------------------


I have effectively used (TRUNCATE_EFFECTIVE) function with completely no issue during simulation. Yet, when it came to synthesis using DC, I got the following error:

Code:
Error:  [i]/file.vhd:line_number[/i]: Constant value required. (ELAB-922)


And that was pointing to the following line of code in the function:
RESULT := INPUT_VECTOR(ONE_INDEX+1 downto ONE_INDEX-TRUNCATION_SIZE+2);


So, what could be the problem ?
 

Status
Not open for further replies.

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top