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.

Conditions in a generate loop

Status
Not open for further replies.

Binome

Full Member level 3
Joined
Nov 16, 2009
Messages
152
Helped
2
Reputation
4
Reaction score
2
Trophy points
1,298
Location
Lyon, France
Activity points
2,405
Hi,
I'm using two cascaded loops to generate components. The loops variables are i and j and I want the components depending oni and j (for example: i=2*j+3) but Modelsim gives warning telling the conditions have to be static (i=3 for example I suppose).
How to do that correctly?
Thanks.
 

Contradicting contradiction is contradictory. You say you have 2 loop variables i and j. And then you assign i=2*j+3. Which means that only j can be a loop variable. So which one is it? Other than that, code please.

- - - Updated - - -

To be more precise, please post full code + the error message.
 

Basically you can take parameters for constant values and run the loop with generate block. it is not advisory to follow the dynamic values in generate block. as it is not depending on the previous one.

i do implemented generate block i just tried for your question.put your code lets analyze
 

Hi,
I'm using two cascaded loops to generate components. The loops variables are i and j and I want the components depending oni and j (for example: i=2*j+3) but Modelsim gives warning telling the conditions have to be static (i=3 for example I suppose).
How to do that correctly?
Thanks.
You can declare a constant within the generate block and then use the constant. Something like this:

Code:
GEN1 : for i = 1 to 3 generate
   GEN2 : for j = 1 to 3 generate
      constant K: natural := 2*i*j+3; -- Now you can use this constant in the component
   begin
      ... Your component would go here as usual
   end generate GEN2;
end generate GEN1;
 

Thank you all but it won't work. Here's a part of my code!
Code:
etages : for i in 0 to log2N-1 generate
	begin		
	papillons : for j in 0 to N/2-1 generate
	begin	
		if_butt : if (n_butt=n_pack) generate
			n_pack <= n_pack+1;
			n_butt <= 0;
		end generate if_butt;
		
		if_butt2 : if (n_butt<n_pack) generate
			n_butt <= n_butt+1;
		end generate if_butt2;
		
	end generate papillons;
end generate etages;
n_pack and n_butt are integer signals. Modelsim says "Condition in IF GENERATE must be static."
How could I make it correct?
Thanks.
 

n_pack and n_butt are integer signals. Modelsim says "Condition in IF GENERATE must be static."
How could I make it correct?

Don't use "generate" inside the loop. You don't need it. Use "normal" code instead.
 

n_pack and n_butt are integer signals. Modelsim says "Condition in IF GENERATE must be static."
How could I make it correct?
Your generate code is at least incomplete because it doesn't include the definition of the signals. As K-J explained, you can only use local constants in a generate construct, no signals. Apart from VHDL syntax violations, the generate example also doesn't contain any generated logic or constants, it's effectively empty.

It would be better if you post an example that shows what you want to achieve. And which real code do you want to generate.

As a general hint, constants can be initialized by functions which can be arbitrarily complex, with the only restriction that they must be evaluated at compile time, in other words only depend on other constants and generics. They can be also used inside generate constructs, so you have effectively unlimited possibilities to design very complex generate schemes.
 

OK, here's all the code:
Code:
library ieee;
use     ieee.std_logic_1164.all;
use 	ieee.std_logic_arith.all;
use		ieee.math_real.all;

library work;
use		work.fft_pack.all;

entity fft_g is
	generic(
		Dwidth		: integer:=8;
		Twidth		: integer:=8;
		N			: integer:=128;
		log2N		: integer:=7;
		pipelined	: integer:=1;
		ifft		: boolean:=false);
	port(
		clk			: in  std_logic;
		rst			: in  std_logic;
		en			: in  std_logic;
		p_I			: in  fft_data(N-1 downto 0);
		p_Q			: in  fft_data(N-1 downto 0);
		x_I			: out fft_data(N-1 downto 0);
		x_Q			: out fft_data(N-1 downto 0);
		overflow	: out std_logic_vector(log2N-1 downto 0));
end fft_g;

architecture rtl of fft_g is

component butt is
	generic(
		Dwidth		: integer;
		Twidth		: integer;
		pipelined	: integer);
	port(
		clk			: in  std_logic;
		rst			: in  std_logic;
		en			: in  std_logic;
		twidd_cos	: in  std_logic_vector(Twidth-1 downto 0);
		twidd_sin	: in  std_logic_vector(Twidth-1 downto 0);
		p_I			: in  butt_data;
		p_Q			: in  butt_data;
		x_I			: out butt_data;
		x_Q			: out butt_data);
end component butt;

function ind_p(i, j, n_pack, n_butt : integer) return integer is
begin
	return j+n_pack*2**(i+1)+n_butt;
end ind_p;

function ind_i(i, j, n_pack, n_butt : integer) return integer is
begin
	return j+n_pack*2**(i+1)+n_butt+2**i;
end ind_i;

	signal in_ifft_I		: fft_data(N-1 downto 0);
	signal in_ifft_Q		: fft_data(N-1 downto 0);
	signal out_ifft_I		: fft_data(N-1 downto 0);
	signal out_ifft_Q		: fft_data(N-1 downto 0);
	signal out_ifft2_I		: fft_data(N-1 downto 0);
	signal out_ifft2_Q		: fft_data(N-1 downto 0);
	signal tmp_ifft_I : fft_data_2(N-1 downto 0);
	signal tmp_ifft_Q : fft_data_2(N-1 downto 0);
	signal tmp_ifft2_I : fft_data_2(N-1 downto 0);
	signal tmp_ifft2_Q : fft_data_2(N-1 downto 0);

    type twiddtab is array(N-1 downto 0) of std_logic_vector(Twidth-1 downto 0);
	signal costab			: twiddtab;
    signal sintab			: twiddtab;
    
    signal sigtmp_I			: sig_tmp(log2N downto 0, N-1 downto 0);
    signal sigtmp_Q			: sig_tmp(log2N downto 0, N-1 downto 0);
    signal sigtmp2_I		: sig_tmp(log2N downto 0, N-1 downto 0);
	signal sigtmp2_Q		: sig_tmp(log2N downto 0, N-1 downto 0);
   
    signal n_pack			: integer := 0;
    signal n_butt			: integer := 0;
    
begin

fft_x : if ifft=false generate
	pas_de_croisement : for k in 0 to N-1 generate
		in_ifft_I(k) <= p_I(k);
		in_ifft_Q(k) <= p_Q(k);
		x_I(k) <= out_ifft_I(k);
		x_Q(k) <= out_ifft_Q(k);
	end generate pas_de_croisement;
end generate fft_x;
	
ifft_x : if ifft=true generate
	croisement : for k in 0 to N-1 generate
		in_ifft_I(k) <= p_Q(k);
		in_ifft_Q(k) <= p_I(k);
		x_I(k) <= out_ifft2_Q(k);
		x_Q(k) <= out_ifft2_I(k);
	end generate croisement;	

	div_ifft : for k in 0 to N-1 generate
		tmp_ifft_I(k) <= sxt(out_ifft_I(k)(Dwidth-1 downto log2N-1),Dwidth+1);
		tmp_ifft2_I(k) <= signed(tmp_ifft_I(k))+signed(conv_std_logic_vector(1,Dwidth+1));
		out_ifft2_I(k) <= tmp_ifft2_I(k)(Dwidth downto 1);
		tmp_ifft_Q(k) <= sxt(out_ifft_Q(k)(Dwidth-1 downto log2N-1),Dwidth+1);
		tmp_ifft2_Q(k) <= signed(tmp_ifft_Q(k))+signed(conv_std_logic_vector(1,Dwidth+1));
		out_ifft2_Q(k) <= tmp_ifft2_Q(k)(Dwidth downto 1);
	end generate div_ifft;
end generate ifft_x;

init : for j in 0 to N-1 generate		
	sigtmp_I(0,j) <= in_ifft_I(j);
	sigtmp_Q(0,j) <= in_ifft_Q(j);
end generate init;
		
etages : for i in 0 to log2N-1 generate
	constant k : natural := 2**(i+1)-1;
	begin
    gentab :
		for idx in 0 to 2**i-1 generate
			constant s : real := real(2**(Twidth-2))*sin(-real(idx)*real(2)*math_pi/real(2**i));
			constant sn : std_logic_vector(Twidth-1 downto 0) := conv_std_logic_vector(integer(s),Twidth);
			constant c : real := real(2**(Twidth-2))*cos(-real(idx)*real(2)*math_pi/real(2**i));
			constant cn : std_logic_vector(Twidth-1 downto 0) := conv_std_logic_vector(integer(c),Twidth);
		begin
			costab(idx) <= cn;
			sintab(idx) <= sn;
		end generate;
		
	papillons : for j in 0 to N/2-1 generate
	begin	
		twidd : butt
		generic map(
			Dwidth => Dwidth,
			Twidth => Twidth,
			pipelined => pipelined-1)
		port map(
			clk => clk,
			rst => rst,
			en => en,
				
			twidd_cos => costab(j),
			twidd_sin => sintab(j),
					
			p_I(0) => sigtmp2_I(i,j),
			p_I(1) => sigtmp2_I(i,j+N/2),
			p_Q(0) => sigtmp2_Q(i,j),
			p_Q(1) => sigtmp2_Q(i,j+N/2),
			x_I(0) => sigtmp2_I(i+1,j),
			x_I(1) => sigtmp2_I(i+1,j+N/2),
			x_Q(0) => sigtmp2_Q(i+1,j),
			x_Q(1) => sigtmp2_Q(i+1,j+N/2));
		
		sigtmp2_I(i,j) 		<= sigtmp_I(i,ind_p(i,j,n_pack,n_butt));
		sigtmp2_I(i,j+N/2) 	<= sigtmp_I(i,ind_i(i,j,n_pack,n_butt));
		sigtmp2_Q(i,j) 		<= sigtmp_Q(i,ind_p(i,j,n_pack,n_butt));
		sigtmp2_Q(i,j+N/2) 	<= sigtmp_Q(i,ind_i(i,j,n_pack,n_butt));
		sigtmp_I(i+1,ind_p(i,j,n_pack,n_butt)) <= sigtmp2_I(i+1,j);
		sigtmp_I(i+1,ind_i(i,j,n_pack,n_butt)) <= sigtmp2_I(i+1,j+N/2);
		sigtmp_Q(i+1,ind_p(i,j,n_pack,n_butt)) <= sigtmp2_Q(i+1,j);
		sigtmp_Q(i+1,ind_i(i,j,n_pack,n_butt)) <= sigtmp2_Q(i+1,j+N/2);

		if_butt : if (n_butt=n_pack) generate
			n_pack <= n_pack+1;
			n_butt <= 0;
		end generate if_butt;
		
		if_butt2 : if (n_butt<n_pack) generate
			n_butt <= n_butt+1;
		end generate if_butt2;
		
	end generate papillons;
end generate etages;

end rtl;

and here are the type definitions:
Code:
library IEEE;
use     IEEE.std_logic_1164.all;
use     IEEE.std_logic_arith.all;

package fft_pack is

	type fft_data is array(natural range <>) of std_logic_vector(7 downto 0);
	type butt_data is array(1 downto 0) of std_logic_vector(7 downto 0);
	type sig_tmp is array(natural range <>,natural range <>) of std_logic_vector(7 downto 0);
	
end fft_pack;
 
Last edited:

Write functions that return values for n_butt and n_pack depending on loop variables i and j.

Code:
for j in 0 to N/2-1 generate
  constant n_butt: integer := n_butt_gen(i,j);
  constant n_pack: integer := n_pack_gen(i,j);
begin
 

Stop using generates for runtime code. Imagine generates as an instruction to the person with the soldering iron:

if day=wednesday then connect pin A to pin B;
else connect pin A to Pin C.

How would you expect a circuit to change the wires around while it is running?

Your counters need to be inside a clocked process.

If they are there for setting up which pins connect to which other pins - they need to be CONSTANT not signals
 

Status
Not open for further replies.

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top