The lecture is about structural description of projects in VHDL: component declaration, component instantiation, for...generate, if...generate statements
3. Иерархическая структура проекта
ENTITY PROJECT
BB SB
ENTITY M11
BB
ENTITY M12
BB SB
ENTITY M11
BB
ENTITY M1n
BB SB
ENTITY M21
BB
ENTITY M22
BB SB
ENTITY M2m
BB
К нижним уровням иерархии
Top-Level
Design Entity
SB – Structural Body
BB – Behavioral Body
VHDL-файлы
4. Структурное описание проектов
Позволяет создавать сложные (иерархические)
проектные решения
• описываемое устройство состоит из более мелких
компонентов, каждый из которых реализует
некоторую функциональность
Операторы, используемые для структурного
описания проекта, относятся к классу
параллельных (concurrent statements)
Основано на конкретизации компонентов и
линий связи между ними и интерфейсом
5. Структурное описание проектов:
Основные шаги
Определение интерфейса связи с «внешней» средой:
• секция ENTITY
Декларация входящих компонентов
• оператор COMPONENT
Задание внутренних сигналов SIGNAL
(декларативная часть архитектурного тела),
определяющих необходимые линии связи в
устройстве
Спецификация всех вхождений каждого компонента
(конкретизация) и линии связи между ними и
интерфейсом
• оператор PORT MAP
6. Объявление компонента
COMPONENT entity_name IS
[GENERIC (generic_interface_list);]
[PORT (port_interface_list);]
END COMPONENT [entity_name];
Объявление компонента должно полностью совпадать
с объявлением соответствующего ему объекта-ENTITY:
• при этом ключевое слово ENTITY заменяется на
COMPONENT
Объявление компонента возможно в декларативной
части архитектурного тела (ARCHITECTURE) и пакете
(PACKAGE):
Имя сущности
7. project_pkg.vhd
n_reg.vhd
n_reg.vhd
Объявление компонента
-- USE work.project_pkg;
ENTITY reg_file IS
GENERIC (...);
PORT (...);
END ENTITY n_reg;
ARCHITECTURE rtl OF reg_file IS
BEGIN
...
END;
ENTITY n_reg IS
GENERIC (WIDTH: NATURAL := 8);
PORT (clk : IN STD_LOGIC;
data: IN STD_LOGIC_VECTOR(WIDTH-1 DOWNTO 0);
q : OUT STD_LOGIC_VECTOR(WIDTH-1 DOWNTO 0));
END ENTITY n_reg;
COMPONENT n_reg IS
...
END COMPONENT n_reg
PACKAGE project_pkg IS
END PACKAGE project_pkg ;
COMPONENT n_reg IS
...
END COMPONENT n_reg
8. Оператор назначения
(конкретизации) компонента
instantiation_label: [COMPONENT] component_name
[GENERIC MAP (generic_assocoation_list);]
[PORT MAP (port_association_list)];
Определяет подкомпонент сущности (ENTITY) проекта, в
котором он используется, и сопоставляет сигналы с
портами этого подкомпонента
Метка:
наличие - обязательно
имя должно быть уникальным в рамках
архитектурного тела
задает однозначное имя экземпляра компонента
в специфицируемой архитектуре
Специфицирует связи данного компонента с портами
других компонентов
9. Оператор назначения
(конкретизации) компонента
instantiation_label: [COMPONENT] component_name
[GENERIC MAP (generic_assocoation_list);]
[PORT MAP (port_association_list)];
{[port_name =>](signal_name|expression|OPEN)}{,…}
Порт (PORT) объекта моделирования,
описанный на один уровень выше
Внутренний сигнал SIGNAL
Имя порта в
составе компонента
Константное
значение
или выражение
Независимый порт
(порты компонента
не подключены)
Фактические значения обобщающих констант
{[constant_name :=] value} {, …}
10. Оператор назначения
(конкретизации) компонента
Соответствие (связывание) портов при создании экземпляров
компонентов может быть выполнено двумя способами:
• позиционное связывание (параметры-выражения
подставляются в порядке следования имен параметров в
объявлении компонента)
• именованное связывание (каждое имя порта связывается
с соответствующим сигналом с помощью символа "=>",
причем порядок следования портов может быть
произвольным )
11. Структурное описание проектов
ENTITY fulladder IS
PORT (a, b, cin : IN STD_LOGIC;
sum, carry : OUT STD_LOGIC);
END fulladder;
ARCHITECTURE behavior OF fulladder IS
-- декларация компонента, который входит в состав системы
COMPONENT halfadder
PORT(a, b : IN STD_LOGIC;
sum, carry : OUT STD_LOGIC);
END COMPONENT;
-- сигналы для связывания "экземпляров" компонентов
SIGNAL s1,c1,c2 : STD_LOGIC := '0';
BEGIN
-- назначение первого компонента, именованное связывание
HA1 : halfadder PORT MAP (a => a, b => b, sum => s1, carry => c1);
-- назначение компонента возможно без его декларации
HA2 : ENTITY work.halfadder(behave)
PORT MAP (a => s1, b => cin, sum => sum, carry => c2);
carry <= c1 OR c2; -- сигнал переноса
END ARCHITECTURE behavior;
Реализация полусумматора
выполнена в отдельном
halfadder.vhd файле
13. Структурное описание проектов
COMPONENT parity
GENERIC (N : NATURAL);
PORT (a : IN STD_LOGIC_VECTOR(N-1 DOWNTO 0);
odd : OUT STD_LOGIC);
END COMPONENT;
…………….
-- именованное связывание
U1: parity GENERIC MAP (N => 8);
PORT MAP (a => data_byte, odd => parity_byte);
-- позиционное связывание
U2: parity GENERIC MAP (N => 4);
PORT MAP (data_byte, parity_byte);
Допустимо проводить связывание сигналов (или элементы сигналов)
с элементами других сигналов, совпадающих с ними по типу
При описании объекта моделирования можно задать значения
входных сигналов по умолчанию. Тогда при использовании этого
объекта в качестве компонента другого объекта значения этих
сигналов для него можно не задавать, а указать ключевое слово OPEN
14. Структурное описание проектов
SIGNAL data_byte: STD_LOGIC_VECTOR(0 TO 7);
SIGNAL result: STD_LOGIC_VECTOR(0 TO 3);
-- Связывание с элементом массива data_byte
-- входной порт x3 подключен к '1'
nand1: and3_gate PORT MAP (x1 => data_byte(7),
x2 => data_byte(6),
x3 => '1',
y => result(3));
COMPONENT and3_gate
PORT(x1,x2,x3: IN STD_LOGIC;
y: out STD_LOGIC);
END COMPONENT;
15. Ключевое слово OPEN также может использоваться для
входных, выходных и двунаправленных сигналов:
1. Допустимо, если в декларации порта задано его начальное значение
2. Значения, принимаемые этими сигналами в модели,
будут игнорироваться
3. Внутри объекта будут использоваться значения по умолчанию, а вне
объекта сигнал не будут использоваться
Структурное описание проектов
COMPONENT halfadder
PORT(a, b : IN BIT; sum, carry : OUT BIT);
END COMPONENT;
...
HA1 : halfadder PORT MAP (a, b, s1, OPEN);
COMPONENT d_latch
PORT (d: IN BIT; en: IN BIT:='1'; q, qb: OUT BIT);
END COMPONENT;
-- позиционное связывание
d1: d_latch PORT MAP (data, OPEN, s1, OPEN);
16. Оператор генерации GENERATE
Используется для уменьшения количества строк
исходного кода в случае, если проектируемый объект
состоит из множества однотипных компонентов, для
которых оператор назначение имеет сходную структуру
Позволяет организовать цикл с параметром и
однократным параметризированным описанием внутри,
на базе которого будут сгенерированы описания для всей
группы однотипных компонентов
Интерпретируется исключительно на этапе компиляции
Определено два вида операторов:
• FOR … GENERATE
• IF … GENERATE
Оба оператора могут быть вложенными, в том числе
располагаться в «теле» друг друга
17. Оператор FOR … GENERATE
group_label: FOR index IN range GENERATE
[block_declarative_items
BEGIN]
{concurrent_statements} -- параллельные операторы
END GENERATE [group_label];
Групповая
метка
Параметр генерации - константа дискретного
типа в определенном (ограниченном)
диапазоне SIGNAL, VARIABLE
«Генерирует» строго фиксированное (заданное на этапе компиляции)
количество однотипных модулей, определенных в параметре
генерации
group_label: FOR index IN range GENERATE
element_label: component_name
[GENERIC MAP (generic_assocoation_list);]
[PORT MAP (port_association_list)];
END GENERATE [group_label];
18. Оператор FOR … GENERATE
-- Внутренние сигналы для «связки» компонентов (dff)
SIGNAL wires: STD_LOGIC_VECTOR(1 TO N+1);
...
wires(1) <= DI;
-- Наличие меток FIFO и d_ff является обязательным
FIFO: FOR i IN 1 TO N GENERATE
d_ff: dff(clk => clk, D => wires(i), Q => wires(i+1));
END GENERATE;
DO <= wires(N+1);
...
19. Оператор FOR … GENERATE
LIBRARY ieee;
USE ieee.std_logic_1164.all;
ENTITY bus_mux IS
GENERIC (N: NATURAL := 3);
PORT(a, b : IN STD_LOGIC_VECTOR(0 TO N-1);
sel : IN STD_LOGIC_VECTOR(0 TO N-1);
result : OUT STD_LOGIC_VECTOR(0 TO N-1));
END ENTITY bus_mux;
ARCHITECTURE rtl OF bus_mux IS
BEGIN
m_arr: FOR i IN 0 to N-1 GENERATE
result(i) <= a(i)
WHEN sel(i) = '1' ELSE b(i);
END GENERATE mux_array;
END ARCHITECTURE rtl;
20. Оператор FOR … GENERATE
LIBRARY ieee;
USE ieee.std_logic_1164.all;
ENTITY bus_mux IS
GENERIC (N: NATURAL := 3);
PORT(a, b : IN STD_LOGIC_VECTOR(0 TO N-1);
sel : IN STD_LOGIC;
result : OUT STD_LOGIC_VECTOR(0 TO N-1));
END ENTITY bus_mux;
ARCHITECTURE rtl OF bus_mux IS
BEGIN
m_arr: FOR i IN 0 to N-1 GENERATE
result(i) <= a(i)
WHEN sel = '1' ELSE b(i);
END GENERATE mux_array;
END ARCHITECTURE rtl;
21. Оператор FOR … GENERATE
ENTITY some_dev IS
GENERIC(N : natural := 3);
PORT(clk, sel : IN STD_LOGIC;
a, b : IN STD_LOGIC_VECTOR(0 TO N-1);
result : OUT STD_LOGIC_VECTOR(0 TO N-1);
q : OUT STD_LOGIC);
END ENTITY some_dev;
ARCHITECTURE RTL OF some_dev IS
SIGNAL d : STD_LOGIC;
SIGNAL tmp : STD_LOGIC_VECTOR(0 TO N-1);
BEGIN
mux_array : FOR i IN 0 TO N-1 GENERATE
tmp(i) <= a(i) WHEN sel = '1' ELSE b(i);
END GENERATE mux_array;
result <= tmp;
d <= tmp(0);
d_ff : PROCESS(CLK)
BEGIN
IF rising_edge(clk) THEN
q <= d;
END IF;
END PROCESS;
END ARCHITECTURE RTL;
22. Оператор IF … GENERATE
«Генерирует» компоненты в зависимости от некоторых
условий
Значение выражения должно быть статическим и
рассчитываться на этапе компиляции
Не содержит секций ELSE, ELSIF
generate_label: IF expression GENERATE
[block_declarative_items
BEGIN]
{concurrent_statements} –- параллельные операторы
END GENERATE [generate_label];
Метка
Выражение
(должно быть
определено на
этапе разработки)
23. Оператор IF … GENERATE
FIFO: FOR i IN 1 TO N GENERATE
-- для первого элемента в цепочке однотипных элементов
d0: IF i = 1 GENERATE
dff_0: dff PORT MAP(clk => clk, d => DI, q => wires(i+1));
END GENERATE;
-- для последнего элемента в цепочке однотипных элементов
dN: IF i = N GENERATE
dff_N : dff PORT MAP(clk => clk, d => wires(i-1), q => DO);
END GENERATE;
d_others : IF i /= 1 AND i /= N GENERATE
d_o: dff PORT MAP(clk => clk, d => wires(i), q => wires(i+1));
END GENERATE;
END GENERATE;
24. Оператор IF … GENERATE
ENTITY some_dev IS
GENERIC (N: NATURAL := 5);
PORT(a, b : IN STD_LOGIC_VECTOR(0 TO N-1);
sel : IN STD_LOGIC_VECTOR(0 TO N-1);
en : IN STD_LOGIC;
result : OUT STD_LOGIC_VECTOR(0 TO N-1));
END ENTITY some_dev;
ARCHITECTURE RTL OF some_dev IS
SIGNAL tmp: STD_LOGIC_VECTOR(0 TO N-1);
BEGIN
mux_array : FOR i IN 0 TO N-1 GENERATE
tmp(i) <= a(i)
WHEN sel(i) = '1' ELSE b(i);
enable: IF i MOD 2 = 0 GENERATE
result(i) <= tmp(i) AND en;
END GENERATE;
pass: IF i MOD 2 /= 0 GENERATE
result(i) <= tmp(i);
END GENERATE;
END GENERATE mux_array;
END ARCHITECTURE RTL;