Поведение комбинационных логических элементов описывается булевыми функциями, которые чаще всего представляются в виде таблиц истинности либо ДНФ. Многовыходные логические элементы описываются в виде систем ДНФ. Система ДНФ булевых функций может быть совместно минимизирована в классе ДНФ и логические выражения могут быть упрощены. Минимизированная система ДНФ в матричной форме представлена в таблице. От данной таблицы легко перейти к выражениям на языке VHDL, используя только логические операторы и операторы назначения сигналов.
Tx | Bf | |||||
---|---|---|---|---|---|---|
b1 | b2 | a1 | a2 | c2 | s2 | s1 |
- | - | 1 | 1 | 1 | 0 | 0 |
1 | 1 | - | 1 | 1 | 0 | 0 |
1 | 1 | 1 | - | 1 | 0 | 0 |
1 | 1 | 0 | 0 | 0 | 1 | 0 |
1 | 1 | 1 | 1 | 0 | 1 | 0 |
0 | - | 1 | 0 | 0 | 1 | 0 |
0 | - | 0 | 1 | 0 | 1 | 0 |
- | 0 | 1 | 0 | 0 | 1 | 0 |
- | 0 | 0 | 1 | 0 | 1 | 0 |
1 | 0 | - | - | 0 | 0 | 1 |
1 | 0 | - | - | 0 | 1 | 0 |
entity adder_2 is port ( a1, b1, a2, b2 : in BIT; c2, s2, s1 : out BIT); end adder_2; architecture functional_dnf of adder_2 is begin c2 <= (a1 and a2) or (b1 and b2 and a1) or (b1 and b2 and a2); s2 <= (b1 and b2 and not a1 and not a2) or (b1 and b2 and a1 and a2) or (not b1 and a1 and not a2) or (not b1 and not a1 and a2) or (not b2 and a1 and not a2) or (not b2 and not a1 and a2); s1 <= (b1 and not b2) or (not b1 and b2); end functional_dnf;
В общем случае ПЛМ предназначена для реализации системы ДНФ булевых функций f(x) = ( f1(x), …, fm(x)), x = (x1, …, xn), заданных на k общих элементарных конъюнкциях, и состоит из двух последовательно соединенных подсхем.
На входные шины ПЛМ подаются сигналы, соответствующие литералам входных переменных xi , i = 1, ..., n.
На матричной подсхеме первого уровня (матрице И) реализуется k элементарных конъюнкций системы ДНФ, матричная подсхема второго уровня (матрица ИЛИ) служит для реализации дизъюнкций элементарных конъюнкций.
ПЛМ, изображенная ниже, реализует следующую систему ДНФ булевых функций:
f1 = x̅1x̅3 ∨ x1x3 = k1∨k3;
f2 = x̅1x̅2x3 = k2;
f3 = x̅1x̅2x3 ∨ x1x3 = k2 ∨ k3.
f <= x1 xor (x2 and x3) xor (x1 and x4);
Ниже приведено описание логической схемы с помощью оператора создания экземпляра компонента. Схема состоит из трех компонент – логических элементов NAO22, NAO2, т.е. используются только два типа элементов.
entity circuit1 is port ( y, c, b, x1 : in bit; a : out bit); end circuit1; architecture struct_1 of circuit1 is component nao22 port ( a, b, c, d : in bit; y : out bit); end component; component nao2 port ( a, b, c : in bit; y : out bit); end component; signal w, d: bit; begin m_3: nao2 port map (b => y, y => A, c => d, a => w); met1: nao22 port map (a => Y, b => C, c => b, D => x1, y => w); met2: NAO22 port map (y, b, c, c, d); end struct_1; |
entity nao2 is port ( a, b, c : in bit; y : out bit); end nao2; architecture beh_1 of nao2 is begin y <=(not a ) or (not b and not c); end beh_1; entity nao22 is port ( a, b, c, d : in bit; y : out bit); end nao22; architecture beh_2 of nao22 is begin y <=(not a and not b) or (not c and not d); end beh_2; |
! Каждый оператор создания экземпляра компонента должен иметь метку.
Метки играют роль имен элементов схемы. Карта портов дается в скобках после ключевых слов port map.
Назначение портов компонентов является как позиционным, так и ключевым.
! Для выходных неиспользуемых портов компонентов нужно употребить ключевое слово open.
Следующий фрагмент VHDL-кода показывает, что при создании экземпляра компонента add1 на вход b1 можно подать константу 0 и выход c1 не использовать.
P1: add1 port map (b1 => '0', b2 =>x, s1 => s1, c1 => open);
Описание регулярных схем осуществляется с помощью параллельного оператора generate (генерации).
Общий вид оператора generate (генерации)
метка : for параметр генерации generate | if условие generate параллельные операторы end generate [метка];
Параметр генерации – константа дискретного типа в определенном диапазоне. Параметром генерации не может быть декларированная переменная или сигнал.
Оператор генерации позволяет сокращенно (по существу используя цикл) описывать совокупности повторяющихся операторов, в том числе и операторов конкретизации компонентов,
т. е. оператор генерации представляет собой механизм для проектирования (описания) регулярных (систолических) структур.
Укажем различия параллельного оператора генерации от последовательных операторов for, if.
Можно создать N экземпляров компонента DFF (D-триггера) и сделать N-битный сдвиговый регистр. Когда число N большое, значительно возрастает длина VHDL-кода. Оператор генерации представляет собой механизм для проектирования (описания) регулярных (систолических) структур. Следующий пример 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;
В сдвиговом регистре используется D-триггер (entity DFF), имеющий вход данных D, вход синхронизации CLK, вход предустановки RSTn.
entity DFF is port ( RSTn, CLK, D : in bit; Q : out bit); end DFF; architecture RTL of DFF is begin process (RSTn, CLK) begin if (RSTn = '0') then Q <= '0'; elsif (CLK'event and CLK = '1') then Q <= D; end if; end process; end RTL;
Проанализировав данное описание, можно заметить, что некоторое "неудобство", связанное с установлением связей схемы в целом с полюсами элементов, возникает при описании входного (метка bit7) и выходного триггера (метка bit0). Избежать этого неудобства можно, если увеличить размерность сигнала T .
entity SHIFT is port ( RSTn, CLK, SI : in bit; SO : out bit); end SHIFT; 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;
Имеются два способа употребления оператора генерации.
В архитектуре RTL2 способ if употреблен внутри способа for. Архитектура DFF может быть декларирована в пакете и употреблена в архитектурах RTL1, RTL2, RTL3. Затем эта компонента может быть удалена из этих архитектур. В архитектуре RTL3 параметр i не нуждается в декларации. Все три архитектуры RTL1, RTL2, RTL3 описывают то же самое поведение.
В следующем примере VHDL-кода оператор generate употребляется для спецификации N-разрядного сумматора adder_N. Изменяя число N в строке с ключевым словом generic, можно получать описание сумматора требуемой разрядности. В представленном ниже архитектурном теле func_1 для N-разрядного сумматора используется только подсхема одноразрядного сумматора add2, при этом на вход переноса c1 подсхемы 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 c_in(0) <= '0'; adder: for i in 0 to N-1 generate 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;