Electronic – VHDL if generate in the preamble, is it possible

vhdl

Is it possible to generate different set of constants in a vhdl preamble using a kind of "if generate statement"?

For example I was trying:

library ieee;
use ieee.std_logic_1164.all;

entity my_entity is
   generic(flag : integer);
   port(x : in std_logic_vector(31 downto 0);
        y : out std_logic_vector(31 downto 0));
end entity my_entity;

architecture arch of my_entity is

   flag_true : if flag /= 0 generate
      constant K1 : integer := 32;
   end generate flag_true;

   flag_false : if flag = 0 generate
      constant K2 : integer 32;
   end generate flag_false;

begin

   flag_true_conc : if flag /= 0 generate
      y(K1 - 1 downto 0) <= not x(K1 - 1 downto 0);
   end generate flag_true_conc;

   flag_false_conc : if flag = 0 generate
      y(K2 - 1 downto 0) <= x(K2 - 2 downto 0) & x(K2 - 1);
   end generate flag_false_conc;

end architecture arch; 

But when I run the ncvhdl for the syntax check it returns me loads of errors:

ncvhdl: 14.20-s029: (c) Copyright 1995-2016 Cadence Design Systems, Inc.
architecture arch of my_entity is
                                  |
ncvhdl_p: *E,EXPBEG (entity_test.vhd,10|34): expecting the reserved word 'BEGIN' [1.2].
      constant K1 : integer := 32;
                                   |
ncvhdl_p: *E,EXPBEG (entity_test.vhd,13|35): expecting the reserved word 'BEGIN' [9.7].
      constant K2 : integer 32;
                            |
ncvhdl_p: *E,EXPSMI (entity_test.vhd,17|28): expecting a semicolon (';') [4.3.1.1].
      constant K2 : integer 32;
                                |
ncvhdl_p: *E,EXPBEG (entity_test.vhd,17|32): expecting the reserved word 'BEGIN' [9.7].
   end generate flag_false;
                            |
ncvhdl_p: *E,EXPEND (entity_test.vhd,18|28): expecting the reserved word 'END' [1.2].

I don't think except for the if generate in the preamble I've done something weird.

Assuming I made you understand what I'm trying to achieve is it possible to do that?

(You have to imagine the situation where in the preamble I want to generate different set of constants based on some kind of flag or condition).

Best Answer

You can't put statements in (formally there is no "preamble" so) the declarative region.

However you can wrap statements and their associated declarations in a block statement. This keeps the declarations and their statements closely scoped together, avoiding bugs where statements are associated with the wrong declarations (which would be possible in your example.

So do that :

architecture arch of my_entity is
-- declarative region

begin
-- concurrent statement region

   flag_true : if flag /= 0 generate
      -- a block statement
      true_block : block
         constant K1 : integer := 32;
      begin
         y(K1 - 1 downto 0) <= not x(K1 - 1 downto 0);
      end;
   end generate flag_true;

end architecture arch; 

And an observation :

if /=0 means true there is probably something very wrong with the design : you have true booleans in VHDL, you don't have to obscure the meaning so you can do everything with an integer. Then you can write

if flag generate ...
Related Topic