Вы находитесь на странице: 1из 11

138 проектирование

Продолжение. Начало в № 3 `2008


Краткий курс HDL.
Часть 5.
Написание кода, независимого
от аппаратной платформы

Содержание этой главы — основной стиль и методика создания текстов


описания проектов на языках HDL HDL в соответствии с документом фир5
мы Actel [1, раздел “Technology Independent Coding Styles”]. Приведен5
Иосиф КАРШЕНБОЙМ ные здесь примеры можно рассматривать как справочник по наиболее
iosifk@narod.ru часто используемым компонентам. Аналогичные описания можно найти
и в [2, 3].

риведенный здесь стиль описания Устройства с памятью от 1 до 0), но не переход от X в 1 или 0 в X,

П является примером эффективного


и стандартного HDL-кода и позволя-
ет создать описание компонентов, независи-
Устройство с памятью — это или триггер,
срабатывающий по фронту, или защелка, уп-
что, возможно, не будет являться достовер-
ным переходом для данного симулятора. Это
особенно существенно при использовании
мых от примененных микросхем. равляемая потенциалом. Это однобитовые таких типов данных, как std_logic, которые
устройства памяти. имеют девять возможных значений (U, X, 0,
Вентили (Gate) 1, Z, W, L, H).
Триггеры (регистры) В этом разделе будут представлены триг-
Ключевые слова: Кроме отдельных триггеров, в проектах геры, работающие по переднему фронту сиг-
and, nand, or, nor, xor, xnor, buf, not обычно используются массивы триггеров. нала.
Вентили, поддерживаемые языком Verilog, В этом случае массив из триггеров будет на-
определяются следующим образом: на пер- зываться регистром. Эти триггеры и регист- D-триггер,
вом месте помещается ключевое слово, по- ры в описании проектов на VHDL участвуют работающий по переднему фронту,
том пробел, имя и названия входов. Имя мо- в операторах “wait” и “if” в пределах процес- без асинхронного сброса и установки
жет быть опциональным. Вентили and и or са — “process”. Для тактирования триггеров Примеры 3 и 4 описывают D-триггер
имеют один выход и два или более входов. или регистров в описании используют или (рис. 1) без асинхронного или синхронного
Например, для and это будет выглядеть сле- положительный, или отрицательный фронт сброса и без предварительной установки.
дующим образом (пример 1). синхрочастоты, либо вызов функции. Есть Этот триггер представляет собой основной
два типа выражений, которые можно исполь- компонент, который находится в каждой
and <name><list of arguments> зовать: 'event — признак события или вызов ячейке FPGA. На рис. 1 и последующих ри-
and myand(out, in1, in2, in3); // вентиль and с тремя входами,
// имя вентиля — myand функции. Например: сунках, изображающих триггеры, прямо-
and (out, in1, in2); // вентиль and без имени. • (clk'event and clk = '1') — положительный угольник голубого цвета представляет собой
Пример 1. Синтаксис и примеры для вентилей and и or
фронт; схематическое изображение триггерного при-
• (clk'event and clk = '0') — отрицательный митива, находящегося в кристалле. В файлах
фронт; примеров названия портов даны произволь-
По соглашению о порядке расположения • rising_edge (clock) — вызов функции стро- но, например “data”, “clk” и т. д. Но в отече-
портов для вентилей, определенном в биб- бирования по положительному фронту; ственной практике большее распространение
лиотеке примитивов и в описании на язык • falling_edge (clock) — вызов функции стро- получили «ГОСТовские» названия “D”, “C”
Verilog, в начало списка аргументов поме- бирования по отрицательному фронту. и т. д. Поэтому на графические изображения,
щается сигнал выхода, а за ним следуют В примерах в этом справочнике использу- для того, чтобы примеры читались легче, на-
входы. ется только положительный фронт, но отри-
Вентили buf и not имеют только один вход цательный фронт синхросигнала тоже мож-
и один или несколько выходов. Для них по- но применять. Использование выражений
рядок расположения сигналов — обратный, 'event предпочтительнее, потому что некото-
то есть сначала следуют выходы, а последним рые инструментальные средства синтеза
сигналом записывается вход (пример 2). VHDL, вероятно, не могут распознать, какую
именно функцию им надо вызывать. Но, вме-
buf mybuf(out1, out2, out3, in); сте с тем, использование вызова функции еще
not (out, in);
предпочтительнее для моделирования, пото-
Пример 2. Синтаксис и примеры для вентилей buf и not му что вызов функции обнаруживает толь- Рис. 1. D&триггер
ко перепад на фронте импульса (от 0 до 1 или

КОМПОНЕНТЫ И ТЕХНОЛОГИИ • № 9 '2008


проектирование 139

несены и эти названия. Но необходимо под- Verilog


черкнуть, что это не названия портов для
приводимых примеров, а просто дополни- module dff_async_rst (data, clk, reset, q);
input data, clk, reset;
тельная информация, облегчающая понима- output q;
ние схемы. reg q;
always @(posedge clk or negedge reset)
if (~reset)
VHDL q = 1'b0;
else
library IEEE; q = data;
use IEEE.std_logic_1164.all; endmodule
entity dff is
port (data, clk : in std_logic; Пример 6. Verilog&код, описывающий D&триггер
q : out std_logic); с асинхронным сбросом Рис. 4. D&триггер с асинхронными входами
end dff; сброса и установки

architecture behav of dff is


begin D-триггер,
process (clk) begin работающий по переднему фронту, VHDL
if (clk'event and clk = '1') then
q <= data; с асинхронной установкой library IEEE;
end if; В примерах 7 и 8 показано, как произво- use IEEE.std_logic_1164.all;
end process;
end behav; дится описание D-триггера с асинхронной ус- entity dff_async is
тановкой (рис. 3). port (data, clk, reset, preset : in std_logic;
Пример 3. VHDL&код, описывающий D&триггер q : out std_logic);
end dff_async;

Verilog architecture behav of dff_async is


begin
module dff (data, clk, q); process (clk, reset, preset) begin
input data, clk; if (reset = '0') then
output q; q <= '0';
reg q; elsif (preset = '1') then
always @(posedge clk) q <= '1';
q = data; elsif (clk'event and clk = '1') then
endmodule q <= data;
end if;
Рис. 3. D&триггер с асинхронной установкой
Пример 4. Verilog&код, описывающий D&триггер end process;
end behav;

D-триггер, VHDL Пример 9. VHDL&код, описывающий D&триггер


с асинхронными входами сброса и установки
работающий по переднему фронту, library IEEE;
с асинхронным сбросом use IEEE.std_logic_1164.all;

В примерах 5 и 6 показано, как произво- Verilog


entity dff_async_pre is
дится описание D-триггера с асинхронным port (data, clk, preset : in std_logic; module dff_async (reset, preset, data, q, clk);
q : out std_logic);
сбросом (рис. 2). end dff_async_pre;
input clk;
input reset, preset, data;
output q;
architecture behav of dff_async_pre is
begin reg q;
process (clk, preset) begin
if (preset = '0') then always @ (posedge clk or negedge reset or posedge preset)
q <= '1'; if (~reset)
elsif (clk'event and clk = '1') then q = 1'b0;
q <= data; else if (preset)
end if; q = 1'b1;
end process; else q = data;
end behav; endmodule

Пример 7. VHDL&код, Пример 10. Verilog&код, описывающий D&триггер


Рис. 2. D&триггер с асинхронным сбросом описывающий D&триггер с асинхронной установкой с асинхронными входами сброса и установки

Verilog D-триггер,
VHDL
module dff_async_pre (data, clk, preset, q); работающий по переднему фронту,
library IEEE; input data, clk, preset;
use IEEE.std_logic_1164.all;
с синхронным входом сброса
output q;
reg q; В примерах 11 и 12 показано, как произво-
entity dff_async_rst is always @(posedge clk or negedge preset) дится описание D-триггера с синхронным
port (data, clk, reset : in std_logic; if (~preset)
q : out std_logic); q = 1'b1; входом сброса (рис. 5).
end dff_async_rst; else
q = data;
endmodule
architecture behav of dff_async_rst is
begin
process (clk, reset) begin Пример 8. Verilog&код,
if (reset = '0') then описывающий D&триггер с асинхронной установкой
q <= '0';
elsif (clk'event and clk = '1') then
q <= data; D-триггер, работающий по переднему
end if;
end process;
фронту, с асинхронными входами сброса
end behav; и установки
В примерах 9 и 10 показано, как произво-
Пример 5. VHDL&код, описывающий D&триггер
с асинхронным сбросом
дится описание D-триггера с асинхронными Рис. 5. D&триггер с синхронным входом сброса
входами сброса и установки (рис. 4).

КОМПОНЕНТЫ И ТЕХНОЛОГИИ • № 9 '2008 www.kit5e.ru


140 проектирование

VHDL Verilog

library IEEE; module dff_sync_pre (data, clk, preset, q);


use IEEE.std_logic_1164.all; input data, clk, preset;
output q;
entity dff_sync_rst is reg q;
port (data, clk, reset : in std_logic; always @ (posedge clk)
q : out std_logic); if (~preset)
end dff_sync_rst; q = 1'b1;
architecture behav of dff_sync_rst is else q = data;
begin endmodule
process (clk) begin
if (clk'event and clk = '1') then Рис. 8. D&триггер&защелка
Пример 14. Verilog&код, описывающий D&триггер с входом данных и входом разрешения записи
if (reset = '0') then
q <= '0';
с синхронным входом установки
else q <= data;
end if;
end if; D-триггер, работающий по переднему дом данных и входом разрешения записи
end process;
end behav; фронту, с асинхронным входом сброса (рис. 8).
и разрешением записи
Пример 11. VHDL&код, описывающий D&триггер В примерах 15 и 16 показано, как произво- VHDL
с синхронным входом сброса
дится описание D-триггера с асинхронным library IEEE;
входом сброса и разрешением записи (рис. 7). use IEEE.std_logic_1164.all;
Verilog
entity d_latch is
module dff_sync_rst (data, clk, reset, q); port (enable, data : in std_logic;
output q; y : out std_logic);
reg q; end d_latch;
always @ (posedge clk)
if (~reset) architecture behave of d_latch is
q = 1'b0; begin
else q = data; process (enable, data)
endmodule begin
if (enable = '1') then
y <= data;
Пример 12. Verilog&код, описывающий D&триггер end if;
с синхронным входом сброса end process;
end behave;
Рис. 7. D&триггер с асинхронным входом сброса
D-триггер, и разрешением записи Пример 17. VHDL&код,
описывающий D&триггер&защелку
работающий по переднему фронту,
с входом данных и входом разрешения записи
с синхронным входом установки
В примерах 13 и 14 показано, как произво- VHDL

дится описание D-триггера с синхронным library IEEE; Verilog


use IEEE.std_logic_1164.all;
входом установки (рис. 6). module d_latch (enable, data, y);
entity dff_ck_en is input enable, data;
port (data, clk, reset, en : in std_logic; output y;
q : out std_logic); reg y;
end dff_ck_en; always @(enable or data)
architecture behav of dff_ck_en is if (enable)
begin y = data;
process (clk, reset) begin endmodule
if (reset = '0') then
q <= '0'; Пример 18. Verilog&код,
elsif (clk'event and clk = '1') then описывающий D&триггер&защелку
if (en = '1') then с входом данных и входом разрешения записи
q <= data;
end if;
end if;
end process; D-триггер-защелка с входом данных
end behav;
Рис. 6. D&триггер с синхронным входом установки и асинхронным входом
Пример 15. VHDL&код, описывающий D&триггер разрешения данных
с асинхронным входом сброса и разрешением записи
В примерах 19 и 20 показано, как произво-
VHDL дится описание D-триггера-защелки с асин-
Verilog хронным входом разрешения данных (рис. 9).
library IEEE;
use IEEE.std_logic_1164.all; module dff_ck_en (data, clk, reset, en, q);
input data, clk, reset, en;
entity dff_sync_pre is output q;
port (data, clk, preset : in std_logic;
q : out std_logic); always @ (posedge clk or negedge reset)
end dff_sync_pre; if (~reset)
q = 1'b0;
architecture behav of dff_sync_pre is else if (en)
begin q = data;
endmodule
process (clk) begin
if (clk'event and clk = '1') then Рис. 9. D&триггер&защелка с входом данных
if (preset = '0') then Пример 16. Verilog&код, описывающий D&триггер
и асинхронным входом разрешения данных
q <= '1'; с асинхронным входом сброса и разрешением записи
else q <= data;
end if;
end if;
end process;
D-триггер-защелка (D-Latches) VHDL
end behav; D-триггер-защелка с входом данных
library IEEE;
и входом разрешения записи use IEEE.std_logic_1164.all;
Пример 13. VHDL&код, описывающий D&триггер
с синхронным входом установки
В примерах 17 и 18 показано, как произво-
entity d_latch_e is
дится описание D-триггера-защелки с вхо-

КОМПОНЕНТЫ И ТЕХНОЛОГИИ • № 9 '2008


проектирование 141

port (enable, gate, data : in std_logic; D-триггер-защелка


q : out std_logic); с асинхронным входом сброса
end d_latch_e;
В примерах 23 и 24 показано, как произво-
architecture behave of d_latch_e is дится описание D-триггера-защелки с асин-
begin
process (enable, gate, data) begin хронным входом сброса (рис. 11).
if (enable = '1') then
q <= data and gate;
end if;
end process;
end behave;
Рис. 12. Приоритетный шифратор,
Пример 19. VHDL&код, использующий функцию If&Then&Else
описывающий D&триггер&защелку с входом данных
и асинхронным входом разрешения данных
VHDL
Verilog
Рис. 11. D&триггер&защелка library IEEE;
с асинхронным входом сброса use IEEE.std_logic_1164.all;
module d_latch_e(enable, gate, data, q);
input enable, gate, data;
output q; entity my_if is
reg q; port (c, d, e, f : in std_logic;
always @ (enable or data or gate) s : in std_logic_vector(1 downto 0);
VHDL
if (enable) pout : out std_logic);
q = (data & gate); end my_if;
library IEEE;
endmodule
use IEEE.std_logic_1164.all; architecture my_arc of my_if is
Пример 20. Verilog&код, begin
entity d_latch_rst is myif_pro: process (s, c, d, e, f) begin
описывающий D&триггер&защелку с входом данных port (enable, data, reset : in std_logic; if s = «00» then
и асинхронным входом разрешения данных q : out std_logic); pout <= c;
end d_latch_rst; elsif s = «01» then
architecture behav of d_latch_rst is pout <= d;
begin elsif s = «10» then
D-триггер-защелка с входом разрешения process (enable, data, reset) begin pout <= e;
записи и асинхронным входом разрешения if (reset = '0') then else pout <= f;
q <= '0'; end if;
В примерах 21 и 22 показано, как произво- elsif (enable = '1') then end process myif_pro;
дится описание D-триггера-защелки с асин- q <= data; end my_arc;
хронным входом разрешения (рис. 10). end if;
end process; Пример 25. VHDL&код, описывающий приоритетный
end behav;
шифратор, использующий функцию If&Then&Else
Пример 23. VHDL&код, описывающий
D&триггер&защелку с асинхронным входом сброса Verilog

module IF_MUX (c, d, e, f, s, pout);


Verilog input c, d, e, f;
input [1:0]s;
module d_latch_rst (reset, enable, data, q); output pout;
input reset, enable, data; reg pout;
Рис. 10. D&триггер&защелка с входом разрешения output q; always @(c or d or e or f or s) begin
записи и асинхронным входом разрешения reg q; if (s == 2'b00)
always @ (reset or enable or data) pout = c;
if (~reset) else if (s ==2'b01)
q = 1'b0; pout = d;
else if (enable) else if (s ==2'b10)
VHDL pout = e;
q = data;
endmodule else pout = f;
library IEEE; end
use IEEE.std_logic_1164.all; endmodule
Пример 24. Verilog&код, описывающий
entity d_latch_en is D&триггер&защелку с асинхронным входом сброса Пример 26. Verilog&код, описывающий приоритетный
port (enable, gate, d : in std_logic;
q : out std_logic); шифратор, использующий функцию If&Then&Else
end d_latch_en;
architecture behave of d_latch_en is Приоритетный шифратор,
begin
process (enable, gate, d) begin
использующий функцию Мультиплексоры,
if ((enable and gate) = '1') then If5Then5Else использующие функцию Case
q <= d;
end if;
end process; Утверждения условного оператора if-then- Оператор case подразумевает параллель-
end behave;
else используются для того, чтобы по резуль- ное декодирование. Этот оператор использу-
Пример 21. VHDL&код, тату проверки условия выполнить последо- ется для того, чтобы выбрать одно из несколь-
описывающий D&триггер&защелку с входом вательность утверждений. Каждое из усло- ких альтернативных утверждений, основан-
разрешения записи и асинхронным входом разрешения
вий утверждения условного оператора ных на значении условия. Условие будет
проверяется до тех пор, пока не будет найде- проверяться в каждом из вариантов выбора
Verilog но условие-«истина». Утверждения, связан- в операторе case до тех пор, пока не будет най-
module d_latch_en(enable, gate, d, q); ные с таким условием, будут выполняться, дено соответствие. Когда соответствие будет
nput enable, gate, d; а остальная часть утверждения будет игнори- найдено, тогда будут выполнены утвержде-
output q;
reg q; роваться. Утверждения условного оператора ния, связанные с этим выбором. Оператор
always @ (enable or d or gate)
if (enable & gate)
if-then-else должны использоваться в том слу- case должен включить все возможные значе-
q = d; чае, когда необходимо иметь приоритет при ния для заданного условия или иметь выбор
endmodule
обработке сигналов. В примерах 25 и 26 сиг- значения по умолчанию, которое выполня-
Пример 22. Verilog&код, нал c будет проверяться первым, и, следова- ется, если ни одно из соответствий не выбра-
описывающий D&триггер&защелку с входом разрешения тельно, он будет иметь высший приоритет но. В следующих примерах показано выпол-
записи и асинхронным входом разрешения
при обработке (рис. 12). нение мультиплексора, использующее опе-

КОМПОНЕНТЫ И ТЕХНОЛОГИИ • № 9 '2008 www.kit5e.ru


142 проектирование

ратор case. Инструментальные средства син- Мультиплексор, else


теза VHDL автоматически производят парал- использующий функцию Case X case (Ain)
3'b000 : Yout = 8'b00000001;
лельное декодирование без приоритетов Пример 29, написанный на языке Verilog, 3'b001 : Yout = 8'b00000010;
в операторах case. показывает мультиплексор, в котором ис- 3'b010 : Yout = 8'b00000100;
3'b011 : Yout = 8'b00001000;
Однако некоторые инструментальные пользуется утверждение Case X. Но многие 3'b100 : Yout = 8'b00010000;
средства Verilog могут выполнить схему инструментальные средства синтеза VHDL 3'b101 : Yout = 8'b00100000;
3'b110 : Yout = 8'b01000000;
с приоритетом, и, возможно, необходимо и Verilog обычно не поддерживают уровень 3'b111 : Yout = 8'b10000000;
будет добавить директиву к используемо- сигнала X. default : Yout = 8'b00000000;
endcase
му оператору case, чтобы гарантировать, end
что нет выполнения логики с приоритетом. Verilog
endmodule
Более подробную информацию об этом //8 bit 4:1 multiplexor with don't care X,
Пример 31. Verilog&код,
можно получить в описаниях на инструмент // 3:1 equivalent mux
module mux4 (a, b, c, sel, q); описывающий декодер 3–8 с входом разрешения En
синтеза. input [7:0] a, b, c;
input [1:0] sel;
Мультиплексор 4:1 output [7:0] q; Счетчики
reg [7:0] q;
В примерах 27 и 28 приведено описание always @ (sel or a or b or c)
мультиплексора 4:1, использующее функцию casex (sel) Счетчики — это одни из наиболее приме-
2'b00: q = a;
Case (рис. 13). 2'b01: q = b; няемых в разработке цифровой аппаратуры
2'b1x: q = c; узлов. Они считают число изменений сигна-
default: q = c;
endcase
лов на входе. Эти изменения происходят или
endmodule в произвольные моменты времени, или в рав-
ные промежутки времени. Далее приведены
Пример 29. Verilog&код, описывающий мультиплексор,
примеры описания счетчиков с различными
в котором используется Case X
режимами работы. Компилятор, обрабаты-
вая весь проект, произведет оптимизацию
Декодер (демультиплексор) счетчика в соответствии с заданными ему
критериями. Но необходимо помнить, что
Декодеры применяются для того, чтобы де- в том случае, если ваш счетчик находится
Рис. 13. Мультиплексор 4:1, использующий Case кодировать данные. В примерах 30 и 31 по- в высокочастотной части проекта, где скоро-
казано использование декодера 3–8, имеюще- сти обработки данных велики, будет лучше
го вход разрешения En. воспользоваться библиотекой функциональ-
VHDL ных узлов, предоставляемой фирмой — из-
VHDL готовителем кристаллов. Можно воспользо-
--4:1 Multiplexor
library IEEE; library IEEE; ваться и визардом, входящим в состав про-
use IEEE.std_logic_1164.all; use IEEE.std_logic_1164.all; граммного инструмента, предоставляемого
entity mux is entity decode is фирмой-изготовителем. Такой компонент бу-
port (C, D, E, F : in std_logic; port ( Ain : in std_logic_vector (2 downto 0); дет оптимизирован и проверен под конкрет-
S : in std_logic_vector(1 downto 0); En : in std_logic;
mux_out : out std_logic); Yout : out std_logic_vector (7 downto 0));
ную технологию и конкретные кристаллы.
end mux; end decode; После того как сгенерированный компонент
architecture my_mux of mux is
будет выполнен в виде файла, его можно ско-
architecture decode_arch of decode is
begin begin пировать в проект или подключить как допол-
mux1: process (S, C, D, E, F) begin process (Ain) нительный файл проекта. Следующие приме-
case s is begin
when «00» => muxout <= C; if (En='0') then ры показывают различные типы счетчиков.
when «01» => muxout <= D; Yout <= (others => '0');
when «10» => muxout <= E; else
when others => muxout <= F; case Ain is
Счетчик 8-bit Up Counter
end case; when «000» => Yout <= «00000001»; с входом разрешения счета
end process mux1; when «001» => Yout <= «00000010»;
end my_mux; when «010» => Yout <= «00000100»;
и асинхронным сбросом
when «011» => Yout <= «00001000»; В примерах 32 и 33 показан счетчик 8-bit
Пример 27. VHDL&код, when «100» => Yout <= «00010000»; Up Counter с входом разрешения счета
описывающий мультиплексор 4:1, использующий Case when «101» => Yout <= «00100000»;
when «110» => Yout <= «01000000»; и асинхронным сбросом.
when «111» => Yout <= «10000000»;
Verilog when others => Yout <= «00000000»; VHDL
end case;
//4:1 Multiplexor end if; library IEEE;
module MUX (C, D, E, F, S, MUX_OUT); end process; use IEEE.std_logic_1164.all;
input C, D, E, F; end decode_arch; use IEEE.std_logic_unsigned.all;
input [1:0] S; use IEEE.std_logic_arith.all;
output MUX_OUT; Пример 30. VHDL&код,
reg MUX_OUT; entity counter8 is
описывающий декодер 3–8 с входом разрешения En port (clk, en, rst : in std_logic;
always @(C or D or E or F or S)
count : out std_logic_vector (7 downto 0));
begin
end counter8;
case (S)
Verilog
2'b00 : MUX_OUT = C; architecture behav of counter8 is
2'b01 : MUX_OUT = D; signal cnt: std_logic_vector (7 downto 0);
module decode (Ain, En, Yout);
2'b10 : MUX_OUT = E; begin
input En;
default : MUX_OUT = F; process (clk, en, cnt, rst)
endcase input [2:0] Ain;
begin
end output [7:0] Yout; if (rst = '0') then
endmodule reg [7:0] Yout; cnt <= (others => '0');
always @ (En or Ain) elsif (clk'event and clk = '1') then
begin if (en = '1') then
Пример 28. Verilog&код, if (!En) cnt <= cnt + '1';
описывающий мультиплексор 4:1, использующий Case Yout = 8'b0; end if;

КОМПОНЕНТЫ И ТЕХНОЛОГИИ • № 9 '2008


проектирование 143

end process; Счетчик 8-bit Up Counter


Verilog
count <= cnt; с входом параллельной загрузки,
end behav;
разрешения счета module count_load (out, data, load, clk, reset);
parameter Width = 8;
Пример 32. VHDL&код, с входом асинхронного сброса и выходом input load, clk, reset;
описывающий счетчик 8&bit Up Counter окончания счета при достижении input [Width-1:0] data;
с входом разрешения счета и асинхронным сбросом output [Width-1:0] out;
состояния «все единицы»
В примере 36 показан счетчик 8-bit Up reg [Width-1:0] out;
Verilog Counter с входом параллельной загрузки, раз-
always @(posedge clk or negedge reset)
module count_en (en, clock, reset, out); решения счета с входом асинхронного сбро- if (!reset)
parameter Width = 8; са и выходом окончания счета при достиже- out = 8'b0;
input clock, reset, en; else if (load)
output [Width-1:0] out;
нии состояния «все единицы». out = data;
reg [Width-1:0] out; else
always @(posedge clock or negedge reset) Verilog out = out + 1;
if (!reset) endmodule
out = 8'b0; module count_load (out, cout, data, load, clk, en, reset);
else if (en) parameter Width = 8; Пример 38. Verilog&код, описывающий счетчик
out = out + 1; input load, clk, en, reset; n&bit Up Counter с входом параллельной загрузки,
endmodule input [Width-1:0] data; разрешения счета и входом асинхронного сброса
output cout; // carry out
output [Width-1:0] out;
Пример 33. Verilog&код,
reg [Width-1:0] out;
описывающий счетчик 8&bit Up Counter Арифметические операторы
с входом разрешения счета и асинхронным сбросом always @(posedge clk or negedge reset)
if (!reset)
out = 8'b0; В примерах 39 и 40 приводятся арифмети-
else if (load)
Счетчик 8-bit Up Counter out = data;
ческие операторы: сложение, вычитание, ум-
с входом параллельной загрузки else if (en) ножение и деление. Программные инстру-
и входом асинхронного сброса out = out + 1; менты, применяемые для синтеза, позволя-
// cout=1 when all out bits equal 1
В примерах 34 и 35 показан счетчик 8-bit assign cout = &out; ют оптимизировать использование данных
Up Counter с входом параллельной загрузки endmodule операторов для применяемой элементной
и с входом асинхронного сброса. Пример 36. Verilog&код, описывающий счетчик
базы.
8&bit Up Counter с входом параллельной загрузки,
VHDL разрешения счета с входом асинхронного сброса VHDL

library IEEE;
и выходом окончания счета
library IEEE;
use IEEE.std_logic_1164.all; при достижении состояния «все единицы» use IEEE.std_logic_1164.all;
use IEEE.std_logic_unsigned.all; use IEEE.std_logic_arith.all;
use IEEE.std_logic_arith.all; use IEEE.std_logic_unsigned.all;

entity counter is Счетчик n-bit Up Counter


entity arithmetic is
port (clk, reset, load : in std_logic; с входом параллельной загрузки, port (A, B : in std_logic_vector (3 downto 0);
data : in std_logic_vector (7 downto 0); Q1 : out std_logic_vector (4 downto 0);
count : out std_logic_vector (7 downto 0)); разрешения счета
Q2, Q3 : out std_logic_vector (3 downto 0);
end counter; с входом асинхронного сброса Q4 : out std_logic_vector (7 downto 0));
В примерах 37 и 38 показан счетчик n-bit end arithmetic;
architecture behave of counter is
signal count_i : std_logic_vector (7 downto 0); Up Counter с входом параллельной загрузки,
begin architecture behav of arithmetic is
process (clk, reset) разрешения счета с входом асинхронного begin
begin process (A, B)
if (reset = '0') then
сброса. begin
count_i <= (others => '0'); Q1 <= ('0' & A) + ('0' & B); --addition
elsif (clk'event and clk = '1') then Q2 <= A — B; --subtraction
VHDL
if load = '1' then Q3 <= A / B; --division
count_i <= data; Q4 <= A * B; --multiplication
library IEEE;
else end process;
count_i <= count_i + '1'; use IEEE.std_logic_1164.all; end behav;
end if; use IEEE.std_logic_unsigned.all;
end if; use IEEE.std_logic_arith.all;
Пример 39. VHDL&код,
end process;
count <= count_i; entity counter is описывающий арифметические операторы
end behave; generic (width : integer := n);
port (data : in std_logic_vector (width-1 downto 0);
load, en, clk, rst : in std_logic;
Пример 34. VHDL&код, описывающий счетчик
q : out std_logic_vector (width-1 downto 0));
Если операнды умножения и деления
8&bit Up Counter с входом параллельной загрузки представляют собой числа, равные степени
end counter;
и входом асинхронного сброса
architecture behave of counter is
двух, то в проекте такое умножение и деле-
signal count : std_logic_vector (width-1 downto 0); ние может быть заменено соответствующи-
Verilog begin ми сдвигами на регистрах. Сдвиговые реги-
process (clk, rst)
module count_load (out, data, load, clk, reset); begin стры обеспечивают выполнение проекта
parameter Width = 8;
input load, clk, reset;
if rst = '1' then с большим выигрышем по скорости выпол-
count <= (others => '0');
input [Width-1:0] data; elsif (clk'event and clk = '1') then нения вычислительных операций, и они за-
output [Width-1:0] out;
reg [Width-1:0] out;
if load = '1' then нимают очень мало ресурсов. Например,
count <= data;
always @(posedge clk or negedge reset)
elsif en = '1' then операция:
if (!reset)
out = 8'b0; count <= count + '1';
else if (load) end if;
out = data; end if; Q <= C/16 + C*4;
else end process;
out = out + 1; q <= count;
endmodule end behave;
может быть представлена как:
Пример 35. Verilog&код, описывающий счетчик Пример 37. VHDL&код, описывающий счетчик
8&bit Up Counter с входом параллельной загрузки n&bit Up Counter с входом параллельной загрузки,
Q <= shr (C, «100») + shl (C, «10»);
и входом асинхронного сброса разрешения счета и входом асинхронного сброса

КОМПОНЕНТЫ И ТЕХНОЛОГИИ • № 9 '2008 www.kit5e.ru


144 проектирование

или на VHDL вот так: Verilog output Q1;


output Q2;
module relational (A, B, Q1, Q2, Q3, Q4); reg Q1, Q2;
Q <= «0000» & C (8 downto 4) + C (6 downto 0) & «00»; input [3:0] A, B; always @ (A or B)
output Q1, Q2, Q3, Q4; begin
reg Q1, Q2, Q3, Q4; Q1 = A == B; //equality
if (A != B) //inequality
Q2 = 1;
Функции “shr” и “shl” находятся в библи- always @ (A or B)
else
отеке IEEE.std_logic_arith.all. begin Q2 = 0;
// Q1 = A > B; //greater than end
Рассмотрим тот же случай: // Q2 = A < B; //less than endmodule
// Q3 = A >= B; //greater than equal to
if (A <= B) //less than equal to Пример 44. Verilog&код,
Q = C/16 + C*4; Q4 = 1; описывающий операторы равенства и неравенства
else
Q4 = 0;
end
в Verilog эта операция будет выглядеть сле- endmodule Операторы сдвига
дующим образом: (Shift Operators)
Пример 42. Verilog&код,
описывающий операторы соотношения
Q = {4b'0000 C[8:4]} + {C[6:0], 2b'00}; Операторы сдвига сдвигают данные влево
или вправо на то число битов, которое ука-
Операторы равенства зано в операторе. В примерах 45 и 46 показа-
Verilog и неравенства (Equality Operator) но применение этого оператора.
module arithmetic (A, B, Q1, Q2, Q3, Q4);
input [3:0] A, B; Операторы равенства и операторы нера- VHDL
output [4:0] Q1;
output [3:0] Q2, Q3; венства выполняют действия над операнда- library IEEE;
output [7:0] Q4; ми, выдавая значение true или false в зависи- use IEEE.std_logic_1164.all;
reg [4:0] Q1; use IEEE.std_logic_arith.all;
reg [3:0] Q2, Q3; мости от того, равны ли операнды друг дру- use IEEE.std_logic_unsigned.all;
reg [7:0] Q4; гу или нет. Примеры 43 и 44 показывают
always @ (A or B) entity shift is
begin применение операторов равенства. port (data : in std_logic_vector(3 downto 0);
Q1 = A + B; //addition q1, q2 : out std_logic_vector(3 downto 0));
Q2 = A — B; //subtraction end shift;
VHDL
Q3 = A / 2; //division
Q4 = A * B; //multiplication architecture rtl of shift is
library IEEE; begin
end
use IEEE.std_logic_1164.all; process (data)
endmodule
begin
entity equality is q1 <= shl (data, «10»); -- logical shift left
Пример 40. Verilog&код, port ( q2 <= shr (data, «10»); --logical shift right
описывающий арифметические операторы A : in STD_LOGIC_VECTOR (3 downto 0); end process;
B : in STD_LOGIC_VECTOR (3 downto 0); end rtl;
Q1 : out STD_LOGIC;
Q2 : out STD_LOGIC Или можно сделать вот так:
Операторы соотношения );
end equality;
(Relational Operators) library IEEE;
use IEEE.std_logic_1164.all;
architecture equality_arch of equality is
begin
Операторы соотношения выполняют дей- process (A, B)
entity shift is
port (data : in std_logic_vector(3 downto 0);
ствия над операндами, выдавая значение true q1, q2 : out std_logic_vector(3 downto 0));
begin
или false в зависимости от того, равны или Q1 <= A = B; -- equality
end shift;

не равны, больше или меньше операнды друг if (A /= B) then -- inequality architecture rtl of shift is
Q2 <= '1';
относительно друга или нет. Примеры 41 и 42 else
begin
process (data)
показывают применение операторов соотно- Q2 <= '0'; begin
end if;
шения. Программные инструменты, приме- end process;
q1 <= data(1 downto 0) & «10»; -- logical shift left
q2 <= «10» & data(3 downto 2); --logical shift right
няемые для синтеза, позволяют оптимизиро- end equality_arch; end process;
вать использование данных операторов для end rtl;
Или можно сделать вот так:
применяемой элементной базы. Пример 45. VHDL&код, описывающий операторы сдвига
library IEEE;
use IEEE.std_logic_1164.all;
VHDL
entity equality is
library IEEE; Verilog
port (
use IEEE.std_logic_1164.all; A : in STD_LOGIC_VECTOR (3 downto 0);
use IEEE.std_logic_arith.all; module shift (data, q1, q2);
B : in STD_LOGIC_VECTOR (3 downto 0);
input [3:0] data;
Q1 : out STD_LOGIC; output [3:0] q1, q2;
entity relational is
Q2 : out STD_LOGIC parameter B = 2;
port (A, B : in std_logic_vector(3 downto 0);
Q1, Q2, Q3, Q4 : out std_logic); ); reg [3:0] q1, q2;
end relational; end equality;
architecture behav of relational is always @ (data)
begin architecture equality_arch of equality is begin
process (A, B) begin q1 = data << B; // logical shift left
begin Q1 <= '1' when A = B else '0'; -- equality q2 = data >> B; //logical shift right
-- Q1 <= A > B; -- greater than Q2 <= '1' when A /= B else '0'; -- inequality end
-- Q2 <= A < B; -- less than end equality_arch; endmodule
-- Q3 <= A >= B; -- greater than equal to

if (A <= B) then -- less than equal to Пример 43. VHDL&код, Пример 46. Verilog&код,
Q4 <= '1'; описывающий операторы равенства и неравенства описывающий операторы сдвига
else
Q4 <= '0';
end if;
end process; Verilog Автоматы состояний
end behav;
module equality (A, B, Q1, Q2);
Пример 41. VHDL&код, input [3:0] A; Конечный автомат (finite state machine,
описывающий операторы соотношения input [3:0] B;
FSM) — это тип последовательной схемы, ко-

КОМПОНЕНТЫ И ТЕХНОЛОГИИ • № 9 '2008


проектирование 145

VHDL

-- Example of a 5-state Mealy FSM


library ieee;
use ieee.std_logic_1164.all;

entity mealy is
port (clock, reset : in std_logic;
data_out : out std_logic;
data_in : in std_logic_vector (1 downto 0));
end mealy;
architecture behave of mealy is
type state_values is (st0, st1, st2, st3, st4);
signal pres_state, next_state: state_values;
begin
-- FSM register
Рис. 14. FSM Мура и Мили statereg: process (clock, reset)
begin
if (reset = '0') then
pres_state <= st0;
торая спроектирована так, что она имеет на- мальная работа автомата. Если сигнал сбро- elsif (clock'event and clock ='1') then
pres_state <= next_state;
бор определенных конечных состояний, и ав- са не использовать, то невозможно предска- end if;
томат проходит через эти состояния предо- зать начальное значение триггеров регистра end process statereg;

пределенным последовательным способом. состояний в течение включения питания -- FSM combinational block
Есть два типа FSM — Мили (Mealy) и Мура FPGA. Они могут произвольно встать в одно fsm: process (pres_state, data_in)
begin
(Moore). FSM Мили имеет выходы, которые из незакодированных состояний и находить- case pres_state is
являются функцией текущего состояния ся там неопределенно долго. Сброс должен when st0 =>
case data_in is
и входов. FSM Мура имеет выходы, которые быть описан как одно из состояний в описа- when «00» => next_state <= st0;
являются функцией только текущего состо- нии FSM. when «01» => next_state <= st4;
when «10» => next_state <= st1;
яния. FSM состоит из трех частей: Асинхронный сброс будет предпочтитель- when «11» => next_state <= st2;
1. Регистр текущего состояния для последо- нее синхронного сброса, потому что асин- when others => next_state <= (others <= 'x');
end case;
вательных переходов — это регистр, име- хронный сброс не требует декодирующей ло- when st1 =>
ющий разядность в n-bit и состоящий из гики и не должен быть описан в неиспользу- case data_in is
when «00» => next_state <= st0;
триггеров (объявляются как вектор), син- емых состояниях автомата. when «10» => next_state <= st2;
хронизирующихся одним для всех тригге- Автомат состояний может быть выполнен when others => next_state <= st1;
end case;
ров сигналом синхрочастоты. Вектор со- в двух вариантах. В одном из вариантов схе- when st2 =>
стояния, имеющий разрядность в n-bit, ма содержит регистр состояний, имеющий case data_in is
when «00» => next_state <= st1;
имеет 2n возможных значений. Зачастую разрядность log2 (m) и выходную декодиру- when «01» => next_state <= st1;
не все из 2n состояний необходимы для ра- ющую логику. В другом варианте разряд- when «10» => next_state <= st3;
when «11» => next_state <= st3;
боты автомата, поэтому он должен быть ность регистра состояний выбирается равной when others => next_state <= (others <= 'x');
спроектирован таким образом, чтобы в те- числу состояний, при этом выходная логика end case;
when st3 =>
чение нормальной работы автомат не по- не используется. Такое выполнение называ- case data_in is
пал в неиспользованные состояния. Аль- ется “one hot”. Поскольку в структуре FPGA when «01» => next_state <= st4;
when «11» => next_state <= st4;
тернативно, FSM с m-состояниями потре- имеется достаточно много триггеров и реги- when others => next_state <= st3;
бует регистр с разрядностью, по крайней стров, то при выполнении программным ин- end case;
when st4 =>
мере, log2 (m). струментом синтеза конечного автомата по case data_in is
2. Комбинационная логика для следующего способу “one hot” можно получить оптималь- when «11» => next_state <= st4;
when others => next_state <= st0;
состояния. В каждый момент времени FSM ные результаты по использованию площади end case;
может находиться только в одном состоя- кристалла (area) и производительности. when others => next_state <= st0;

нии, и каждый активный фронт синхроча- end case;


стоты заставляет его изменяться от его те- Автомат Мили end process fsm;

кущего до следующего состояния так, как В примерах 47 и 48 представлен автомат -- Mealy output definition using pres_state w/ data_in
определено логической частью схемы. Сле- Мили для диаграммы состояний, показанной outputs: process (pres_state, data_in)
begin
дующее состояние определяется как функ- на рис. 15. case pres_state is
ция входов FSM и его текущего состояния. when st0 =>
case data_in is
3. Комбинационная логика для выходов. when «00» => data_out <= '0';
Для FSM Мура выходы — это функция те- when others => data_out <= '1';
end case;
кущего состояния. Для FSM Мили выхо- when st1 => data_out <= '0';
ды — это функция текущего состояния when st2 =>
case data_in is
и первичных входов FSM. Кроме того, when «00» => data_out <= '0';
в FSM Мура есть возможность получить when «01» => data_out <= '0';
when others => data_out <= '1';
сигналы выходов не из текущего состояния, end case;
а из следующего состояния, для того что- when st3 => data_out <= '1';
when st4 =>
бы уменьшить время распространения сиг- case data_in is
нала от фронта синхронизации до выхода. when «10» => data_out <= '1';
when «11» => data_out <= '1';
FSM Мура и Мили показаны на рис. 14. when others => data_out <= '0';
Сигнал сброс используется для того, что- end case;
when others => data_out <= '0';
бы гарантировать отказоустойчивое поведе- end case;
ние. Он гарантирует, что FSM всегда иници- end process outputs;
end behave;
ализируется в известное достоверное состо-
яние перед первым активным фронтом Рис. 15. Диаграмма переходов автомата Мили Пример 47. VHDL&код, описывающий автомат Мили
синхрочастоты, после чего и начинается нор-

КОМПОНЕНТЫ И ТЕХНОЛОГИИ • № 9 '2008 www.kit5e.ru


146 проектирование

begin 2'b11: next_state=st2;


Verilog
-- FSM register endcase
statereg: process (clock, reset) st1: case (data_in)
// Example of a 5-state Mealy FSM
begin 2'b00: next_state=st0;
module mealy (data_in, data_out, reset, clock);
output data_out; if (reset = '0') then 2'b10: next_state=st2;
input [1:0] data_in; pres_state <= st0; default: next_state=st1;
input reset, clock; elsif (clock ='1' and clock'event) then endcase
reg data_out; pres_state <= next_state; st2: case (data_in)
reg [2:0] pres_state, next_state; end if; 2'b0x: next_state=st1;
parameter st0=3'd0, st1=3'd1, st2=3'd2, st3=3'd3, st4=3'd4; end process statereg; 2'b1x: next_state=st3;
endcase
// FSM register -- FSM combinational block st3: case (data_in)
always @ (posedge clock or negedge reset) fsm: process (pres_state, data_in) 2'bx1: next_state=st4;
begin: statereg begin default: next_state=st3;
if (!reset)// asynchronous reset case pres_state is endcase
pres_state = st0; when st0 => st4: case (data_in)
else case data_in is 2'b11: next_state=st4;
pres_state = next_state; when «00» => next_state <= st0; default: next_state=st0;
end // statereg when «01» => next_state <= st4; endcase
when «10» => next_state <= st1; default: next_state=st0;
// FSM combinational block when «11» => next_state <= st2;
endcase
always @(pres_state or data_in) when others => next_state <= (others <= 'x');
end // fsm
begin: fsm end case;
case (pres_state) when st1 =>
// Moore output definition using pres_state only
st0: case (data_in) case data_in is
always @(pres_state)
2'b00: next_state=st0; when «00» => next_state <= st0;
begin: outputs
2'b01: next_state=st4; when «10» => next_state <= st2;
2'b10: next_state=st1; when others => next_state <= st1; case (pres_state)
2'b11: next_state=st2; end case; st0: data_out=1'b1;
endcase when st2 => st1: data_out=1'b0;
st1: case (data_in) case data_in is st2: data_out=1'b1;
2'b00: next_state=st0; when «00» => next_state <= st1; st3: data_out=1'b0;
2'b10: next_state=st2; when «01» => next_state <= st1; st4: data_out=1'b1;
default: next_state=st1; when «10» => next_state <= st3; default: data_out=1'b0;
endcase when «11» => next_state <= st3; endcase
st2: case (data_in) when others => next_state <= (others <= 'x'); end // outputs
2'b0x: next_state=st1; end case; endmodule // Moore
2'b1x: next_state=st3; when st3 =>
endcase case data_in is Пример 50. Verilog&код, описывающий автомат Мура
st3: case (data_in) when «01» => next_state <= st4;
2'bx1: next_state=st4; when «11» => next_state <= st4;
default: next_state=st3; when others => next_state <= st3;
endcase
st4: case (data_in)
end case; Буферы входов/выходов
when st4 =>
2'b11: next_state=st4; case data_in is (Input/Output Buffers)
default: next_state=st0; when «11» => next_state <= st4;
endcase when others => next_state <= st0;
default: next_state=st0; end case; В проектах можно использовать буферы
endcase
end // fsm
when others => next_state <= st0; входа/выхода. Приведенные далее примеры
end case;
end process fsm; показывают, как устанавливать в проект бу-
// Mealy output definition using pres_state w/ data_in
always @(data_in or pres_state) феры. Их устанавливают в проект верхнего
-- Moore output definition using pres_state only
begin: outputs outputs: process (pres_state) уровня.
case (pres_state) begin
st0: case (data_in) case pres_state is
2'b00: data_out=1'b0; when st0 => data_out <= '1'; Трехстабильные буферы
default: data_out=1'b1;
when st1 => data_out <= '0'; Буфер с третьим состоянием (рис. 16) мо-
endcase
when st2 => data_out <= '1';
st1: data_out=1'b0; жет работать как выход с возможностью пе-
when st3 => data_out <= '0';
st2: case (data_in)
when st4 => data_out <= '1';
2'b0x: data_out=1'b0;
when others => data_out <= '0';
рехода в состояние с высоким импедансом.
default: data_out=1'b1;
endcase
end case; В примерах 51 и 52 показано, как устанавли-
end process outputs;
st3: data_out=1'b1; вать в проект буфер с третьим состоянием.
st4: case (data_in)
end behave;
2'b1x: data_out=1'b1;
default: data_out=1'b0;
endcase Пример 49. VHDL&код, описывающий автомат Мура
default: data_out=1'b0;
endcase
end // outputs
Verilog
endmodule
// Example of a 5-state Moore FSM
module moore (data_in, data_out, reset, clock);
Пример 48. Verilog&код, описывающий автомат Мили output data_out;
input [1:0] data_in;
input reset, clock;
reg data_out;
Автомат Мура reg [2:0] pres_state, next_state; Рис. 16. Буфер с трехстабильным выходом
В примерах 49 и 50 показан статический ав- parameter st0=3'd0, st1=3'd1, st2=3'd2, st3=3'd3, st4=3'd4;

томат Мура. //FSM register


always @(posedge clock or negedge reset) VHDL
begin: statereg
VHDL
if (!reset) library IEEE;
-- Example of a 5-state Moore FSM pres_state = st0; use IEEE.std_logic_1164.all;
library ieee; else entity tristate is
use ieee.std_logic_1164.all; pres_state = next_state; port (e, a : in std_logic;
end // statereg y : out std_logic);
entity moore is end tristate;
port (clock, reset : in std_logic; // FSM combinational block
data_out : out std_logic; always @(pres_state or data_in) architecture tri of tristate is
data_in : in std_logic_vector (1 downto 0)); begin: fsm begin
end moore; case (pres_state) process (e, a)
st0: case (data_in) begin
architecture behave of moore is 2'b00: next_state=st0; if e = '1' then
type state_values is (st0, st1, st2, st3, st4); 2'b01: next_state=st4; y <= a;
signal pres_state, next_state: state_values; 2'b10: next_state=st1; else

КОМПОНЕНТЫ И ТЕХНОЛОГИИ • № 9 '2008


проектирование 147

y <= 'Z'; Двунаправленные буферы Y : out std_logic;


end if; Двунаправленный буфер (рис. 17) может PAD : inout std_logic);
end process; end component;
end tri; работать как вход или как выход с возмож-
begin
ностью перехода в состояние с высоким им- U1: BIBUF port map
Или можно сделать вот так:
педансом. В примерах 55 и 56 показано, как (D => a,
E => e,
library IEEE; устанавливать в проект двунаправленные Y => b,
use IEEE.std_logic_1164.all;
буферы. PAD => y);
end bi;
entity tristate is
port (e, a : in std_logic;
Пример 57. VHDL&код, описывающий установку
y : out std_logic);
end tristate; в проекте двунаправленного буфера

architecture tri of tristate is


begin Verilog
Y <= a when (e = '1') else 'Z';
end tri; module bidir (e, y, a, b);
input a, e;
inout y;
Пример 51. VHDL&код, output b;
описывающий буфер с трехстабильным выходом BIBUF U1 ( .PAD(y), .D(a), .E(e), .Y(b) );
endmodule

Verilog Пример 58. Verilog&код, описывающий установку


Рис. 17. Двунаправленный буфер
в проекте двунаправленного буфера
module TRISTATE (e, a, y);
input a, e;
output y;
reg y; VHDL Параметры
always @ (e or a) begin
library IEEE;
(Generics and Parameters)
if (e)
use IEEE.std_logic_1164.all;
y = a;
else entity bidir is
Параметры generic и parameter использу-
y = 1'bz; port (y : inout std_logic; ются для того, чтобы определить компонент
end e, a : in std_logic;
endmodule b : out std_logic); с переменными исполнениями. Это позволя-
end bidir; ет выполнять параметризированные компо-
Или можно сделать вот так:
architecture bi of bidir is ненты, у которых разрядность и определен-
module TRISTATE (e, a, y); begin ный наборов признаков можно задавать при
input a, e; process (e, a)
output y; begin установке этих компонентов в проект. В при-
case e is
when '1' => y <= a;
мерах 59 и 61 показано, как использовать па-
assign y = e ? a : 1'bZ;
when '0' => y <= 'Z'; раметры generic и parameter, описывая сум-
when others => y <= 'X';
endmodule end case; матор. А также то, как этот сумматор можно
end process; установить в проект, используя переменные
Пример 52. Verilog&код, b <= y;
end bi; значения параметров для разрядности.
описывающий буфер с трехстабильным выходом

Пример 55. VHDL&код, VHDL


описывающий двунаправленный буфер
Установка компонента в проекте показана library IEEE;
use IEEE.std_logic_1164.all;
в примерах 53 и 54. use IEEE.std_logic_arith.all;
Verilog use IEEE.std_logic_unsigned.all;
VHDL module bidir (e, y, a, b); entity adder is
input a, e; generic (WIDTH : integer := 8);
library IEEE; inout y;
use IEEE.std_logic_1164.all; port (A, B : in UNSIGNED(WIDTH-1 downto 0);
output b; CIN : in std_logic;
reg y_int; COUT : out std_logic;
entity tristate is wire y, b; Y : out UNSIGNED(WIDTH-1 downto 0));
port (e, a : in std_logic; always @ (a or e) end adder;
y : out std_logic); begin
end tristate; if (e == 1'b1)
architecture rtl of adder is
y_int <= a;
begin
architecture tri of tristate is else
process (A,B,CIN)
component TRIBUFF y_int <= 1'bz;
variable TEMP_A,TEMP_B,TEMP_Y:UNSIGNED(A'length
port (D, E : in std_logic; end
downto 0);
PAD : out std_logic); assign y = y_int;
begin
end component; assign b = y;
TEMP_A := '0' & A;
endmodule
TEMP_B := '0' & B;
begin TEMP_Y := TEMP_A + TEMP_B + CIN;
Пример 56. Verilog&код,
U1: TRIBUFF port map (D => a, Y <= TEMP_Y (A'length-1 downto 0);
E => e, описывающий двунаправленный буфер COUT <= TEMP_Y (A'length);
PAD => y); end process;
end tri; end rtl;
Установка компонента в проекте показана
Пример 53. VHDL&код, описывающий установку Пример 59. VHDL&код, описывающий сумматор
в примерах 57 и 58. с использованием параметра generic
в проекте буфера с трехстабильным выходом

VHDL
Verilog Параметр “Width” определяет разрядность
library IEEE;
use IEEE.std_logic_1164.all; сумматора. Вот как выглядит установка 16-раз-
module TRISTATE (e, a, y);
input a, e; entity bidir is рядного сумматора в проекте (пример 60).
output y; port (y : inout std_logic;
TRIBUFF U1 (.D(a), .E(e), .PAD(y)); e, a : in std_logic;
endmodule b : out std_logic); U1: adder generic map (16) port map (A_A, B_A, CIN_A, COUT_A, Y_A);
end bidir;
Пример 54. Verilog&код, описывающий установку architecture bi of bidir is Пример 60. VHDL&код, описывающий установку
component BIBUF 16&разрядного сумматора в проекте
в проекте буфера с трехстабильным выходом port (D, E : in std_logic;

КОМПОНЕНТЫ И ТЕХНОЛОГИИ • № 9 '2008 www.kit5e.ru


148 проектирование

Verilog

module adder (cout, sum, a, b, cin);


parameter Size = 8;
output cout;
output [Size-1:0] sum;
input cin;
input [Size-1:0] a, b;

assign {cout, sum} = a + b + cin;

endmodule

Пример 61. Verilog&код, описывающий сумматор


с использованием параметра parameter

Параметр “Size” определяет разрядность


сумматора. Вот как выглядит установка 16-раз-
рядного сумматора в проекте (пример 62).

adder #(16) adder16(cout_A, sun_A, a_A, b_A, cin_A);

Пример 62. Verilog&код, описывающий установку


16&разрядного сумматора в проекте

В следующем разделе мы обсудим вопро-


сы по написанию кода, зависимого от аппа-
ратной платформы. ■

Литература

1. Actel HDL CodingStyle Guide. http://www.actel.com


2. Predicting the output of Finite State Machines.
Application Note. Mentor Graphics, 1986–2006.
3. Golson S. State Machine Design Techniques for
Verilog and VHDL. Trilobyte Systems // Synopsys
Journal of High-Level Design. September 1994.

КОМПОНЕНТЫ И ТЕХНОЛОГИИ • № 9 '2008