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
genlabel:
if <boolean expression> generate
<conditional compiled code>
end generate;
FvM said:This is the only available construct in concurrent code:
Code:genlabel: if <boolean expression> generate <conditional compiled code> end generate;
g_thisisconditional : if c_mycondition generate
p1:process
begin
...stuff (sequential statements)
end process p1;
p2:process
begin
...stuff (sequential statements)
end process p2;
inst1: myentity port map (...); -- component instantiation
end generate g_thisisconditional;
constant c_mycondition : boolean := true;
entity myentity is
generic (c_mycondition : boolean)
port (...)
p3:process
begin
...stuff (sequential statements)
if c_mycondition then
...stuff
else
...stuff
end if;
end process p3;
Yes, I also use this method as a generate supplement in sequential code. But with most VHDL compilers, you get additional warnings regarding constant expression in if statement.A VHDL synthesis program is extremely good in optimization of constants and will eliminate the dead if/else branch without any additional logic being generated.
FvM said:The said configuration may be achieveable with numeric parameters for signal widths more easily, but VHDL generate statements should always work.
My personal favourite for variant designs is a library file with a package containing all constants (numeric and boolean or 0/1) that are varied between different project versions. This library is referenced in all project files. By exchanging the library file, all settings can be changed at once.
CONSTANT MS20_DIV : INTEGER := 40e6/(50*CLKDIV_PWM);
CONSTANT N_MS20 : INTEGER := INTEGER(CEIL(LOG2(REAL(MS20_DIV))));
CONSTANT MS16_DIV : INTEGER := 40e6/(60*CLKDIV_PWM);
FvM said:Any variable calculated at compile time is still a constant value. It's no probem to have constants depending on other constants, even using VHDL functions as LOG2() in the below example:
Code:CONSTANT MS20_DIV : INTEGER := 40e6/(50*CLKDIV_PWM); CONSTANT N_MS20 : INTEGER := INTEGER(CEIL(LOG2(REAL(MS20_DIV)))); CONSTANT MS16_DIV : INTEGER := 40e6/(60*CLKDIV_PWM);
FvM said:As another point, VHDL GENERATE can also be applied to SIGNAL and CONSTANT definition. Most likely, you won't find an example in most secondary literature and tool handbooks. You have to consult IEEE 1076 to learn the syntax of this option. I can't say, if it's supported by all tools, but Altera Quartus does. It's necessary e. g. to calculate constant arrays at compile time, for sine lookup table ans similar stuff.
FvM said:Another thing, that should work by VHDL language standard (I didn't yet use it), is a constant array, that has deferred values for each configuration. In your example, have an X, Y and Z constant array and A as the index. You may copy the actual value to another simple constant or use the array in each instantiation of the constant.
FvM said:Altera Quartus has still VHDL 1993 as most recent language level, but there are no differences to VHDL 2000 in this resepct, as far as I know.
TYPE SINTAB IS ARRAY(0 TO ROMSIZE-1) OF STD_LOGIC_VECTOR (NNCO-2 DOWNTO 0);
SIGNAL SINROM: SINTAB;
BEGIN
GENROM:
FOR idx in 0 TO ROMSIZE-1 GENERATE
CONSTANT x: REAL := SIN(real(idx)*MATH_PI/real(ROMSIZE));
CONSTANT xn: UNSIGNED (NNCO-2 DOWNTO 0) := CONV_UNSIGNED(INTEGER(x*real(ROMMAX)),NNCO-1);
BEGIN
SINROM(idx) <= STD_LOGIC_VECTOR(xn);
END GENERATE;
Yes, I also use this method as a generate supplement in sequential code. But with most VHDL compilers, you get additional warnings regarding constant expression in if statement.
constant msb_byte_order : Boolean := false;
procedure out_miosio(which: natural) is
begin
if msb_byte_order then
case which is
when 0 =>
ft_miosio <= dataReg(31 downto 24); -- msb first
when 1 =>
ft_miosio <= dataReg(23 downto 16);
when 2 =>
ft_miosio <= dataReg(15 downto 8);
when others =>
ft_miosio <= dataReg(7 downto 0);
end case;
else
case which is
when 0 =>
ft_miosio <= dataReg(7 downto 0);
when 1 =>
ft_miosio <= dataReg(15 downto 8);
when 2 =>
ft_miosio <= dataReg(23 downto 16);
when others =>
ft_miosio <= dataReg(31 downto 24); -- msb last
end case;
end if;
end out_miosio;
What I effectively need is not to have a condition on the generation of a certain block .. my target is to have a global variable, if defined, then a set of lower variable will be assigned a specific set of values ..
For example, If we design a MAC unit .. I need to define something called (Precision) .. If this (Precision) is set to (High), then the multipliers in the MAC unit become 16-bit multipliers .. adders will be 32-bit .. etc.
And when (Precision) is set to be (Medium) .. different sizes are selected for the Multipliers ..
I understand that I can have multiple architectures for the MAC unit and use configuration to select the desired one .. but this is much more complicated than just assigning set of values to my variables according to the String value of a global variable like (Precision).
function get_width(nominal_width : integer; precision : boolean) return integer is
begin
if x and nominal_width < 16 then
return 16;
else
return nominal_width;
end if;
end function;
signal dsp_p : std_logic_vector(get_width(10,PRECISION)-1 downto 0);
impure function get_local_width(nominal_width : integer) return integer is
begin
return get_width(nominal_width, PRECISION);
end function;
We use cookies and similar technologies for the following purposes:
Do you accept cookies and these technologies?
We use cookies and similar technologies for the following purposes:
Do you accept cookies and these technologies?