Intel® Quartus® Prime Software
Intel® Quartus® Prime Design Software, Design Entry, Synthesis, Simulation, Verification, Timing Analysis, System Design (Platform Designer, formerly Qsys)
17255 Discussions

need a help with strange error" left bound of the range must be a constant "

Altera_Forum
Honored Contributor II
3,908 Views

I have got this problem when I synthesize my design on Quartus II but when I use xilinx software its work perfectly 

 

the error is that " left bound of the range must be a constant "  

 

and it's indicated to this line 

 

----------------------------------------------- 

Reg_Q:process (CLK, r_by_2) 

begin 

if (CLK'event and CLK='1') then 

if RESET='1' then  

q<= (others => '0');  

else  

case CS is 

----------------------------------- 

when S2 =>  

q<=p; 

----------------------------------- 

when S4 =>  

if(r_by_2 = 1) then 

q <= q (m_size-r_by_2-1 downto 0) & q(m_size-1); 

else 

---------->>>>> q(m_size-1 downto r_by_2) <= q (m_size - r_by_2 - 1 downto 0); 

q(r_by_2-1 downto 0) <= q(m_size-1 downto m_size - r_by_2); 

end if; 

----------------------------------- 

when others => 

null; 

----------------------------------- 

end case; 

end if; 

end if; 

end process; 

 

----------------------------------------------- 

 

here is the signal definition 

 

signal p, q, t : std_logic_vector (m_size-1 downto 0); -- 

 

Does anyone have idea how to make this synthesizable? 

Im making a normal basis multiplier  

thank you
0 Kudos
11 Replies
Altera_Forum
Honored Contributor II
2,637 Views

what is the size of r_by_2? if its not a constant, how do you know that both vector sizes are the same? 

 

You could just stick it in a for loop and do it bit by bit. 

 

for i in 0 to r_by_2-1 loop q(i) <= q(i+r_by_2); q(i+r_by_2) <= q(i); end loop;
0 Kudos
Altera_Forum
Honored Contributor II
2,637 Views

the r_by_2 is  

 

r_by_2 : integer range 0 to m_size_1  

 

I have tried the for loop but its give me another errors 

 

I didnt get it so can you explain more  

the problem is I'm modifying this code and trying to break it down into datapath and controller  

then Im going to write another code using different numbering system so I need to understand it perfectly
0 Kudos
Altera_Forum
Honored Contributor II
2,637 Views

what dont you get? can you post more of your code?

0 Kudos
Altera_Forum
Honored Contributor II
2,637 Views

here is more of my code  

 

 

Reg_P:process (CLK) 

begin 

if (CLK'event and CLK='1') then 

if RESET='1' then  

p<= (others => '0'); 

else  

case CS is 

----------------------------------- 

when S1 =>  

p <= X_in; 

----------------------------------- 

when S7 =>  

if (mul_result = '1') then 

p <= mul_c; 

end if; 

----------------------------------- 

when S8 => 

p <= t; 

----------------------------------- 

when S10 => 

p <= p(m_size-2 downto 0) & p(m_size-1); 

----------------------------------- 

when others => 

null; 

----------------------------------- 

end case; 

end if; 

end if; 

end process; 

 

----------------------------------------------- 

Reg_Q:process (CLK, r_by_2) 

begin 

if (CLK'event and CLK='1') then 

if RESET='1' then  

q<= (others => '0');  

else  

case CS is 

----------------------------------- 

when S2 =>  

q<=p; 

----------------------------------- 

when S4 =>  

if(r_by_2 = 1) then 

q <= q (m_size-r_by_2-1 downto 0) & q(m_size-1); 

else 

q(m_size-1 downto r_by_2) <= q (m_size - r_by_2 - 1 downto 0); 

q(r_by_2-1 downto 0) <= q(m_size-1 downto m_size - r_by_2); 

end if; 

----------------------------------- 

when others => 

null; 

----------------------------------- 

end case; 

end if; 

end if; 

end process; 

0 Kudos
Altera_Forum
Honored Contributor II
2,637 Views

when S4 => if(r_by_2 = 1) then q <= q (m_size-r_by_2-1 downto 0) & q(m_size-1); else for i in 0 to r_by_2-1 loop q(i) <= q(i+r_by_2); q(i+r_by_2) <= q(i); end loop; end if;

0 Kudos
Altera_Forum
Honored Contributor II
2,637 Views

Unfortunately, important parts are still missing from the code, e.g. definition of all involved signals and generics. So the exact solution can't be given.  

 

The said error message about requiring constant range for bit vector slices is simply reflecting VHDL syntax rules. As mentioned by Tricky, a for loop with a bitwise copy is the usual way to implement assignments of dynamical varying size. A problem you probably stumbled upon is, that the for loop range also must be constant. So you need to do the iteration over the maximal range and decide with an if statement about the actual used range. I'm sure you can figure it out when thinking about it a little bit. 

 

P.S.: I fear, that the construct for i in 0 to r_by_2-1 loop doesn't work for the said reasons. You'll probably need 

 

for i in 0 to msize-1 loop if i < r_by_2 then end if; end loop;
0 Kudos
Altera_Forum
Honored Contributor II
2,637 Views

when S4 => if(r_by_2 = 1) then q <= q (m_size-r_by_2-1 downto 0) & q(m_size-1); else q(m_size-1 downto r_by_2) <= q (m_size - r_by_2 - 1 downto 0); q(r_by_2-1 downto 0) <= q(m_size-1 downto m_size - r_by_2); end if; 

can be replaced by: 

when S4 => for i in 0 to m_size - 1 loop q(i0) <= q((i + r_by_2) mod m_size) ; end loop ;  

This code synthesises (I checked!) 

You may want to use a barrel shift/rotate component in stead (especially if m_size is not a power of 2 as the code above then needs dividers to calculate the 'mod' function), it will probably use less resources and certainly run faster.
0 Kudos
Altera_Forum
Honored Contributor II
2,637 Views

TO_BE_DONE

0 Kudos
Altera_Forum
Honored Contributor II
2,637 Views

Please dont thread hijack - start your own thread. 

Dont use caps - its like shouting 

Please use code tags 

line 259 is "count <= count + 1" I dont think this is the line you're talking about.
0 Kudos
Altera_Forum
Honored Contributor II
2,637 Views

I have tried what you said and its work  

but the problem is that when I do the testbench the results need to be rotated to the lift one time  

 

 

--- Quote Start ---  

when S4 => if(r_by_2 = 1) then q <= q (m_size-r_by_2-1 downto 0) & q(m_size-1); else q(m_size-1 downto r_by_2) <= q (m_size - r_by_2 - 1 downto 0); q(r_by_2-1 downto 0) <= q(m_size-1 downto m_size - r_by_2); end if;can be replaced by: 

when S4 => for i in 0 to m_size - 1 loop q(i0) <= q((i + r_by_2) mod m_size) ; end loop ; This code synthesises (I checked!) 

You may want to use a barrel shift/rotate component in stead (especially if m_size is not a power of 2 as the code above then needs dividers to calculate the 'mod' function), it will probably use less resources and certainly run faster. 

--- Quote End ---  

0 Kudos
Altera_Forum
Honored Contributor II
2,637 Views

Looking a bit deeper, I realised that I gave you a solution for a 'right' rotate where your code shows a 'left' rotate. So I experimented a bit with my code, and at the same time getting to know some of ModelSim quirks (as sometimes QII synthesizes OK, but Modelsim stops on a negative value for a natural etc.) 

Here is my complete test code: 

library ieee; use ieee.std_logic_1164.all ; use ieee.numeric_std.all ; use ieee.math_real.all ; entity ahl2006 is generic ( MSIZE : natural := 16 ; SHIFT_DIRECTION : string := "RIGHT" ) ; port ( Clk : in std_logic ; Reset : in std_logic ; Ld : in std_logic ; Shift : in std_logic ; D : in std_logic_vector(MSIZE - 1 downto 0 ) ; Sel : in natural range 0 to MSIZE - 1 ; Q : out std_logic_vector(MSIZE - 1 downto 0 ) ) ; end ahl2006 ; architecture a of ahl2006 is constant MSIZE_IS_POWER_OF_2 : boolean := (2 ** floor( log2( real( MSIZE ))) = real( MSIZE ) ) ; constant MWIDTH : natural := integer( floor( log2( real( MSIZE )))) ; signal lq : std_logic_vector(MSIZE - 1 downto 0 ) ; begin process( Reset , Clk ) begin if (Reset = '1') then lq <= (others => '0') ; elsif rising_edge( Clk ) then if (Ld = '1') then lq <= D ; elsif (Shift = '1') then if SHIFT_DIRECTION = "LEFT" then for i in MSIZE - 1 downto 0 loop if MSIZE_IS_POWER_OF_2 then lq(i) <= lq( (MSIZE + i - Sel) mod MSIZE ) ; else if (i >= Sel) then lq(i) <= lq(i - Sel) ; else lq(i) <= lq( MSIZE + i - Sel) ; end if ; end if ; end loop ; else for i in 0 to MSIZE - 1 loop if MSIZE_IS_POWER_OF_2 then lq(i) <= lq((i + Sel) mod MSIZE) ; else if (i + Sel) < MSIZE then lq(i) <= lq(i + Sel) ; else lq(i) <= lq(i + Sel - MSIZE) ; end if ; end if ; end loop ; end if ; end if ; end if ; end process ; Q <= lq ; end a ;  

Today I also ran an RTL-siulation for MSIZE = 16, for both LEFT and RIGHT rotates to verify proper operation.
0 Kudos
Reply