Параллельный оператор генерации "generate"

Страницы работы

Содержание работы

7 Параллельный оператор generate

Общий вид оператора generate(генерации):

метка : forпараметр генерации generate|

ifусловие generateпараллельные операторы endgenerate[метка];

Рассмотрим работу оператора на примерах сдвигового регистра и 7-разрядного сумматора, схема которого размещена ниже:

Параметр генерации - константа дискретного типа в определенном диапазоне. Параметром генерации не может быть декларированная переменная или сигнал.

Оператор генерации позволяет сокращенно (по существу используя цикл) описывать совокупности повторяющихся операторов, в том числе и операторов конкретизации компонентов, т. е. оператор генерации представляет собой механизм для проектирования (описания) регулярных (систолических) структур.

Например, структура регистра регулярна. Мы можем создать N экземпляров компонента DFF (D-триггера) и сделать N-битный сдвиговый регистр. Когда число N большое, значительно возрастает длина VHDL-кода. Оператор генерации представляет собой механизм для проектирования (описания) регулярных (систолических) структур.

Следующий пример показывает применение оператора генерации к описанию 8-битового сдвигового регистра.

    entity SHIFT is

        port (

           RSTn, CLK, SI : in  bit;

           SO            : out bit);

     end SHIFT;

architecture RTL2 of SHIFT is

   component DFF

   port (

      RSTn, CLK, D : in  bit;

      Q            : out bit);

   end component;

   signal T : bit_vector(6 downto 0);

begin

   g0 : for i in 7 downto 0 generate

      g1 : if (i = 7) generate

         bit7 : DFF

       port map (RSTn => RSTn, CLK => CLK, D => SI, Q

=> T(6));

      end generate;

      g2 : if (i > 0) and (i < 7) generate

         bitm : DFF

            port map (RSTn, CLK, T(i), T(i-1));

      end generate;

      g3 : if (i = 0) generate

         bit0 : DFF

            port map (RSTn, CLK, T(0), SO);

      end generate;

   end generate;

end RTL2;

Проанализировав данное описание, можно заметить, что некоторое "неудобство", связанное с установлением связей схемы в целом с полюсами элементов, возникает при описании входного (метка bit7) и выходного триггера (метка bit0). Избежать этого неудобства можно, если увеличить размерность сигнала Т.

architecture RTL3 of SHIFT is

   component DFF

   port (

      RSTn, CLK, D : in  bit;

      Q            : out bit);

   end component;

signal T : bit_vector(8 downto 0);      --  декларация сигнала T

begin

   T(8) <= SI;

   SO   <= T(0);

   g0 : for i in 7 downto 0 generate

      allbit : DFF

  port map (RSTn => RSTn, CLK => CLK, D => T(i+1), Q

=> T(i));

   end generate;

end RTL3;

Имеются два способа употребления оператора генерации.

Способ 1 - (способ for), синтаксис такой же, как у последовательного оператора forloop.

Способ 2 - (способ if) употребление подобно по синтаксису последовательному оператору if.

В архитектуре RTL2 способ ifупотреблен внутри способа for.

Укажем различия параллельного оператора генерации от последовательных операторов for, if.

1.  Оператор генерации есть параллельный оператор, a if, for loopесть последовательные операторы.

2.  Оператор генерации не имеет фраз else, elsif.

3.  Необходима метка для оператора генерации.

4. Только параллельные операторы могут появляться внутри оператора генерации. Только последовательные операторы могут появляться внутри последовательного forloopоператора и последовательного ifоператора.

Архитектура DFF может быть декларирована в пакете и употреблена в архитектурах RTL1, RTL2, RTL3. Затем эта компонента может быть удалена из этих архитектур.

В архитектуре RTL3 параметр iне нуждается в декларации. Все три архитектуры RTL1, RTL2, RTL3 описывают то же самое поведение.

В следующем примере VHDL-кода оператор generate употребляется для спецификации N-разрядного сумматора adder_N.

entity adder_N is

generic (N : natural := 4);

port (a,b : in bit_vector (0 to N-1);

        s : out bit_vector (0 to N-1);

        c  : out bit);

end adder_N;

architecture functional of adder_N is

component add1

port (b1,b2: in BIT;

      c1,s1: out BIT);

end component;

component  add2

port(c1, a1,a2:in BIT;

      c2,s2:out BIT);

end component;

signal c_in : bit_vector (0 to N-1);

begin

adder: for i in 0 to N-1 generate

first_bit: if (i=0) generate

        first_cell:

        add1 port map (b1 => a(0), b2 => b(0), c1 => c_in(0), s1 => s(0) );

end generate first_bit;

middle_bit: if (i>0) and (i < N-1) generate

        middle_cell:

        add2 port map (c1 => c_in(i-1), a1 => a(i), a2 => b(i), c2 => c_in(i),  s2 => s(i) );

end generate middle_bit;

end_bit: if (i=N-1) generate

        end_cell:

        add2 port map (c1 => c_in(i-1), a1 => a(i), a2 => b(i), c2 => c, s2 => s(i) );

end generate end_bit;

end generate adder;

end functional;

Изменяя число N в строке с ключевым словом generic, можно получать описание сумматора требуемой разрядности. В представленном ниже архитектурном теле func_l для N-разрядного сумматора используется только подсхема одноразрядного сумматора add2, при этом на вход переноса cl подсхемы add2 (в разряде с номером 0) подается нулевой сигнал, описание становится более компактным.

entity adder_N is

generic (N : natural := 4);

port (a,b : in bit_vector (0 to N-1);

        s : out bit_vector (0 to N-1);

        c  : out bit);

end adder_N;

architecture func_1 of adder_N is

component  add2

port(c1, a1,a2:in BIT;

      c2,s2:out BIT);

end component;

signal c_in : bit_vector (0 to N);

begin       -- в схеме все одноразрядные сумматоры - add2

c_in(0)<='0';

adder: for i in 0 to N-1 generate

i_bit_slice:    add2 port map (c1 => c_in(i), a1 => a(i), a2 => b(i),

c2 => c_in(i+1),  s2 => s(i) );

end generate adder;

c <= c_in(N);

end func_1;

Похожие материалы

Информация о работе