courses:system_design:synthesis:advanced_synthesis

Advanced Synthesis

Constant and Generic

  • Constant C identical in all referencing units
  • Generic G different but constant within each entity
  • Input signal S set/changed in operation (different operation modes)

Notes

Once you have finished a design, you hope that you will be able to use at least parts of the VHDL code in other designs as well. (Re-Use)

This is certainly possible as long as you can adopt the VHDL code via copy/paste.

But if the function has to be changed slightly, the designer will have to adapt the VHDL code.

To make this adaption easier and less error prone, VHDL provides several ways of parameterizing a design or a module, that means the behavior description depends on some parameters.

The value of these parameters can then be set differently in different implementations or even on the fly during operation. The intention is that by changing the parameter the behavior will change accordingly.

package T_PACK is
  constant MAX_VALUE:integer := 15;
end T_PACK;
use WORK.T_PACK.all;
entity COUNTER_C is
  port(...,
       COUNT : buffer integer
               range 0 to MAX_VALUE);
end COUNTER_C;
architecture RTL of COUNTER_C is
begin
  process(CLK) begin
    if CLK’event and CLK=1then
      if RESET=1then
        COUNT <= 0;
      elsif ENABLE=1then
        if COUNT < MAX_VALUE then
          COUNT <= COUNT + 1;
        else
          COUNT <= 0;
         end if;
       end if;
    end if;
 end process;
end RTL;
  • Constants are fixed for the complete design
  • Instantiations of COUNTER_C produce exactly the same counter
  • Parametric signals in port map

Notes

One way to parameterize a design is to use constants.

The example shows a counter with reset and enable. The counter is free wheeling when enabled. The maximum value (MAX_VALUE) is set by a constant which is defined and given a value in the package T_PACK. Wherever COUNTER_C is built in (by use of a component declaration and component instantiation) the counter range is fixed (from 0 to the value specified in the package).

entity COUNTER_G is
 generic (MAX_VALUE: integer :=15);
  port(...              -- default value
         COUNT : buffer integer
                 range 0 to MAX_VALUE);
end COUNTER_G;
 
architecture RTL of COUNTER_G is
begin
  process(CLK)
  begin
    if CLK’event and CLK=1then
      if RESET=1then
        COUNT <= 0;
      elsif ENABLE=1then
        if COUNT < MAX_VALUE then
           COUNT <= COUNT + 1;
        else
           COUNT <= 0 ;
        end if;
      end if;
    end if;
  end process;
end RTL;
  • Generics are defined in the entity declaration
  • Treated as constants in the architecture
  • Default values
  • Parametric signals in port map

Notes

If you want to instantiate counters with different counter ranges in one design you will have to switch to generics.

Generics are defined like the ports in the entity definition and receive their values during the step of component instantiation.

Therefore, in addition to the port map, a generic map is required to provide these values. Generics may be given a default value in the generic clause which will be used if the generic is not explicitly assigned a value.

entity TWO_COUNTERS IS
port(...);
end entity;
 
architecture RTL of TWO_COUNTERS is
  component COUNTER_G
    generic (MAX_VALUE:integer := 15);
    port(...);
  end component;
begin
  COUNTER1 : COUNTER_G
    port map (...); -- MAX_VALUE with
                    -- default value
  COUNTER2 : COUNTER_G
    generic map (MAX_VALUE => 31)
    port map (...);
...
end RTL;
  • Different values for different instantiations
    • Instantiation with default value
    • Instantiation with generic map
Every instantiation needs a label
Only generics of type integer are supported by synthesis tools

Notes

The component declaration is as usual except that you must not forget the generic clause.

But how does the instantiation of COUNTER_G work?

If default values were defined for the generics, the component instantiation does not need a generic map (COUNTER1).

The most useful feature is that entities using generics can be instantiated with different values for the generics within the same module.

The default value can be overwritten by setting the generic to an explicit value in the generic map of the component instantiation (COUNTER2).

Only integer type generics are synthesizable!

entity GENERATE_COUNTER IS
port(...);
end entity;
 
architecture RTL of GENERATE_COUNTER is
  component COUNTER_G
    generic (MAX_VALUE:integer := 15);
    port(...);
    end component;
 
begin
  GEN: for K in 2 to 5 generate
    COUNTER : COUNTER_G
      generic map (MAX_VALUE => 2**K-1)
      port map (...);
    end generate;
 
    . . .
end RTL;
  • ’for generate’ needs a label
  • “loop” for concurrent statements (component instantiations, signal assignments)
    • Several instantiations of the same component
    • Different values for generics
    • Loop variable implicitly declared

Notes

When a component has to be instantiated several times, the way described above would be exhaustive. The generate statement provides a shortcut to this problem.

Within a ’for…generate…’ loop concurrent statements can be iterated.

This applies not only to repeated component instantiations but also to concurrent signal assignments.

The loop variable is declared implicitly, again, and can only be read, e.g. as generic value.Value assignments will lead to an error.

entity GENERATE_COUNTER IS
  port(...);
end entity;
architecture RTL of GENERATE_COUNTER is
  component COUNTER_G
    generic (MAX_VALUE:integer := 15);
    port(...);
  end component;
begin
  GEN: for K in 1 to 8 generate
    COND1: if K<=5 generate
      COUNTER : COUNTER_G
        generic map (MAX_VALUE => 2**K-1)
        port map (...);
    end generate;
 
    COND2: if K>5 and FLAG generate
      MAX : COUNTER_G
        generic map (MAX_VALUE => 31)
        port map (...);
    end generate;
  end generate;
. . .
end RTL;
  • If condition is true then generate …
  • No elsif / else paths
  • Each generate needs a label

Notes

To make the generate statement even more powerful you can use an if-generate statement which allows to execute the concurrent statements subject to the value of a boolean expression.

In contrast to conditional signal assignments or the sequential if statement, elsif and else paths are not permitted.

In the example, 8 counters are instantiated.

For K=1…5 the maximum counter value is calculated according to the formula 2^K-1, i.e. 1, 3, 7, 15, 31.

For higher index values the maximum counter values remains 31.

It is also possible to evaluate constants or generics of the own entity in the expression of the if condition.

Constants and generics are very profitable when configuring a module before synthesizing.

entity COUNTER_S is
  port(MAX_VALUE : in integer range 0 to 1023
       . . .);
end COUNTER_S;
 
architecture RTL of COUNTER_S is
begin
  process(CLK)
  begin
    if CLK’event and CLK=1then
      if RESET=1then
        COUNT <= 0;
      elsif ENABLE=1then
        if COUNT < MAX_VALUE then
          COUNT <= COUNT+1;
        else
          COUNT <= 0 ;
        end if;
      end if;
    end if;
  end process;
end RTL;
  • Set different modes in operation (cf. MAX_VALUE)
  • No parametric signals in port map

Notes

If it is necessary to switch parameters during operation, the only solution is to feed these parameters via signals into the module.

→ additonally input port(s) needed

The counter range in the example above can be set to values between 1 and 1023 during operation.

For that reason, an overhead of hardware is generated to provide this flexibility in functionality. The signal MAX_VALUE must be stable when the active clock edge occurs. If this cannot be guaranteed, storing elements will have to be created, which hold the current value of MAX_VALUE and are updated at certain times, only.


Chapters of System Design > Synthesis