Проектирование цифровых систем на языках описания аппаратуры/Лекция 15
- Заголовок
- Автоматический синтез логических схем по VHDL описаниям.
- Автор
- Ланкевич Ю.Ю.
- Нижний колонтитул
- Проектирование цифровых систем на языках описания аппаратуры/Лекция 15
- Дополнительный нижний колонтитул
- Ланкевич Ю.Ю., 02:36, 21 ноября 2020
Содержание |
Слайд:Высокоуровневый и логический синтез
Процесс синтеза схемы по VHDL-описаниям обычно разбивается на четыре крупных этапа.
Последние три этапа объединяются под названием “логический синтез”. Кроме того, этап “Увеличение быстродействия” в научной литературе обычно не выделяется, так как включается в этап “Технологическое отображение”.
Ниже приведены этапы синтеза в LeonardoSpectrum
Этап | Название этапа в LeonardoSpectrum | Представление логической схемы |
---|---|---|
Высокоуровневый синтез | Elaborate | RTL-описание |
Технологически независимая оптимизация | Pre-optimize | RTL-описание |
Технологическое отображение | Optimize | Структурное описание |
Увеличение быстродействия | Timing optimization | Структурное описание |
RTL-описание (Register Transfer Logic) логической схемы представляет собой смешанное функционально-структурное описание. Элементы памяти (триггеры) представляются в виде структурного описания (элементы и их соединения), комбинационная логика представляется в виде логических выражений (уравнений). Если применить терминологию языка VHDL, то можно сказать, что комбинационная логика представляется операторами назначения сигналов (стиль data flow), элементы памяти представляются операторами создания экземпляров компонентов. RTL-описание является текстовым описанием и может быть сохранено в формате VHDL.
Высокоуровневый синтез осуществляется компилятивным способом – каждый оператор языка VHDL заменяется соответствующей логической подсхемой (компилятом). Например, арифметический оператор сложения заменяется сумматором, арифметический оператор умножения – схемой умножения (умножителем), операторы сравнения – компараторами и т.д. Операторы цикла “разворачиваются”, каждая итерация цикла заменяется соответствующей подсхемой, соответствующей совокупности операторов в теле цикла. Исходное VHDL-описание в результате “покрывается” логическими RTL-описаниями операторов – соответствующие операторам компиляты представляются на уровне регистровых передач (RTL-уровне).
Технологически независимая оптимизация осуществляется с целью минимизации сложности логической схемы и сводится к минимизации многоуровневых алгебраических представлений систем булевых функций, реализующих комбинационную логику. Основным критерием оптимизации является число литералов (букв) в представлениях функций.
Технологическое отображение позволяет реализовать оптимизированное RTL-представление логической схемой из элементов целевой библиотеки. В LeonardoSpectrum синтез структур FPGA, CPLD ведется четырьмя алгоритмами, после чего результирующие логические схемы сравниваются и выбирается лучшая схема. Для заказных СБИС синтез ведется одним алгоритмом. Для структур FPGA сложность схемы подсчитывается в числе конфигурируемых ячеек CLB, поэтому при установке критерия оптимизации Area минимизируется число ячеек CLB. Увеличение быстродействия осуществляется после того, как схема построена из элементов целевой библиотеки. Этап перестройки логической схемы с целью увеличения быстродействия отделен от этапа технологического отображения, так как обычно увеличение быстродействия схемы чаще всего влечет увеличение ее сложности. В LeonardoSpectrum имеется возможность управлять различными параметрами, характеризующими задержку схемы. Основным параметром, характеризующим задержку схемы, является задержка на критических путях (цепях), т. е. путях с наибольшей задержкой.
В LeonardoSpectrum имеется возможность увидеть на экране монитора графическое изображение как RTL-описания, так и результирующей логической схемы. Заметим, что в графическом изображении RTL-описания используются графические изображения параметрически генерируемых модулей (компилятов), которыми заменяются операторы высокоуровневого алгоритмического VHDL-описания. Графическое изображение результирующей логической схемы состоит из связанных между собой элементов целевой библиотеки синтеза.
Реализация операторов относится к этапу высокоуровневого синтеза. Проектировщик может управлять заменой операторов компилятами по критериям сложности и быстродействия. Имеются следующие режимы замены операторов.
Установка режима Smallest позволяет заменять все операторы подсхемами наименьшей сложности, установка режима Small позволяет заменять операторы подсхемами небольшой сложности, при этом есть надежда, что задержка этих подсхем будет меньше, чем при режиме Smallest.
Режим Fastest ориентирован на реализацию компилятов наиболее “быстрыми” подсхемами. Режим Fast ориентирован на реализацию компилятов “быстрыми” схемами, при этом предполагается, что сложность этих подсхем будет меньше, чем при режиме Fastest.
Естественно, когда говорится о подсхемах, соответствующих компилятам, то имеются в виду соответствующие RTL-описания.
Установка соответствующего режима касается одновременно всех операторов исходного VHDL-описания.
Извлечение макроописаний. В некоторых VHDL-описаниях могут быть фрагменты, соответствующие вполне определенным типовым подсхемам, таким, как дешифраторы, счетчики, блоки памяти (ПЗУ, ОЗУ). На этапе высокоуровневого синтеза такие описания могут быть распознаны и заменены соответствующими RTL-описаниями. Если режим извлечения (Extract) не установлен, то данные макроблоки не распознаются, а соответствующие “мелкие” операторы, входящие в макроблоки, заменяются по общим правилам. Ясно, что в этом случае могут быть получены другие RTL-описания, а от вида RTL-описания зависит и результат синтеза.
Обработка иерархических описаний. Иерархия VHDL-описания проекта цифровой системы – это способ “борьбы” со сложностью проектов и размерностью решаемых задач. Требования практики приводят к необходимости решения задач все большей и большей размерности, поэтому число уровней иерархии в структурном описании может быть большим – десяток и более.
Иерархия структурного описания в языке VHDL может быть графически изображена в LeonardoSpectrum в виде дерева. В качестве вершин дерева выступают entity и компоненты. На более низком уровне описания компоненты описываются, естественно, в виде entity. Заметим, что графическое представление данного дерева осуществляется в браузере проекта (Design Browser) в библиотеке Work. Там же пользователь может увидеть деревья, представляющие целевую библиотеку синтеза, библиотеку примитивов синтезатора LeonardoSpectrum и библиотеку использованных компилятов (параметрически сгенерированных модулей).
На результирующей логической схеме иерархия описания на самом нижнем уровне задает условные границы между элементами, каждая подсхема – это совокупность взаимосвязанных элементов. Иерархия на следующем, более высоком уровне иерархии заключается в том, что некоторые выделенные подсхемы объединяются в один модуль (компонент), т.е. проводится условная граница между подсхемами. На следующем уровне иерархии выде-ляются новые подсхемы, устанавливаются новые границы и т.д.
Самый простой способ обработки иерархического проекта – синтез согласно иерархии описания. Соответствующий режим именуется в LeonardoSpectrum как “Preserve”. Недостатком такого способа синтеза является большая сложность, так как оптимизация ведется только в рамках каждого блока описания. Достоинством является то, что структура результирующей схемы отражает структуру (иерархию) исходного описания, что может быть полезно для других целей (диагностика, размещение на платах и т.д.).
Противоположностью режима “Preserve” является режим “Flatten” , позволяющий устранить иерархию проекта и реализовать схему как один блок. Достоинством такого режима является меньшая сложность проекта, недостатком – “размытость” границ между подсхемами, что приводит к тому, что трудно выделить подсхему, соответствующую некоторому блоку исходного описания. Элементы, входящие в подсхему, реализующую некоторый блок исходного описания, “размазываются” по всей схеме.
Имеется еще режим Auto при работе с иерархическими проектами. Этот режим позволяет пользователю управлять размерностью выделяемого блока для оптимизации. Выделение блока соответствующей размерности устанавливается с помощью параметра Auto Dissolve Limit – этот параметр задает число “растворяемых” элементов, включаемых в один блок при установке режима Auto обработки иерархии.
Имеются также режим, запрещающий оптимизацию выделенного модуля, и режим, запрещающий оптимизацию поддерева проекта, а также режим оптимизации только одного уровня в иерархии проекта.
Оптимизация. На практике нужны не просто логические схемы, обеспечивающие нужное поведение, эквивалентное поведению исходного VHDL-описания проектируемой цифровой системы, а схемы, оптимизированные по тем или иным критериям. Задача получения оптимальной по сложности схемы даже в классе комбинационных логических схем, математическими моделями которых являются системы булевых функций, является NP-полной комбинаторной задачей. Речь о точных решениях не идет, на практике используются приближенные алгоритмы, позволяющие решать задачи большой размерности.
Алгоритмы оптимизации не описаны в пользовательской документации синтезатора LeonardoSpectrum, сообщается лишь о следующих приемах оптимизации.
Диаграммы двоичного выбора (BDD). Данный оптимизационный прием заключается в оптимизации многоуровневого представления булевой функции на основе разложения Шеннона.
Факторизация – выделение одинаковых сомножителей в элементарных конъюнкциях.
Реструктуризация схемы. Это изменение иерархии описания. Выполнение этого приема связано с переходом к функциональным описаниям, для чего используется экстракция.
Экстракция (извлечение) функциональных описаний элементов и подсхем из структурных описаний. Это соответствует понятию remapping – процедуре, обратной mapping (технологическому отображению).
Глобальная оптимизация ведется и возможна лишь для схем небольшой размерности, для схем большой размерности осуществляется блочная оптимизация.
При оптимизации может быть разрешен режим boundary optimization – “граничной” оптимизации, примерами которой являются упрощение схемы путем распространения констант, удаления инверторов, идущих друг за другом и т. д. и режим “common logic” совместного использования общих подсхем.
Слайд:Кодирование данных при синтезе
Тип данных bit заменяется типом std_logic, тип данных bit_vector заменяется типом std_logic_vector, при этом направление диапазона (возрастающий диапазон to, убывающий диапазон downto) не изменяется.
Если VHDL-код содержит типы std_logic, std_logic_vector, то данные типы не меняются при синтезе, а интерфейс схемы не изменяется после синтеза.
Данные типа integer заменяются данными типа std_logic_vector убывающего диапазона, т.е. число представляются массивом бит (двоичным кодом), старший разряд двоичной записи числа идет первым. Если тип integer декларирован для ограниченного диапазона и максимальное (по абсолютному значению) число в декларированном диапазоне равно k, то результирующий тип содержит w = ]log2 k[ бит (разрядов). Для отрицательных чисел добавляется еще один (первый) разряд для задания знака числа. Например, если тип my_int1, являющийся подтипом типа integer, декларирован следующим образом
type my_int1 is range –100 to - 4;
то k=8, поэтому сигналы x1, x2 типа my_int1 декларированные в виде
x1, x2 : in my_int1;
x1 : IN std_logic_vector (7 DOWNTO 0); x2 : IN std_logic_vector (7 DOWNTO 0);
package pack is type my_int1 is range 4 downto 2; end pack; package body pack is end pack; use work.pack.all; entity my_int is port( x1, x2 : in my_int1; y : out my_int1); end my_int; architecture str of my_int is begin y <= x1 + x2; end str;
Интерфейс синтезированной схемы my_int
entity my_int is port ( x1 : IN std_logic_vector (2 DOWNTO 0); x2 : IN std_logic_vector (2 DOWNTO 0); y : OUT std_logic_vector (2 DOWNTO 0)) ; end my_int ;
Как видно из следующего примера, данные типа integer, декларированные без указания диапазона, заменяются 32-разрядным двоичным вектором.
entity my_int_32 is port( x1, x2 : in integer; y : out integer); end my_int_32; architecture str of my_int_32 is begin y <= x1 + x2; end str;
library IEEE; use IEEE.STD_LOGIC_1164.all; entity my_int_32 is port ( x1 : IN std_logic_vector (31 DOWNTO 0) ; x2 : IN std_logic_vector (31 DOWNTO 0) ; y : OUT std_logic_vector (31 DOWNTO 0)) ; end my_int_32 ;
! Отрицательные числа при синтезе представляются в дополнительном коде.
Например, число –125 из диапазона [-128, 0] представляется булевым вектором 10000011. Напомним, что дополнительный код получается следующим образом: берется обратный код числа и добавляется единица. В примере единица в первом разряде свидетельствует о том, что число –125 является отрицательным, двоичный код числа 125 есть 1111101, обратный код 0000010, следовательно дополнительный код есть вектор 10000011.
Слайд:Кодирование данных перечислимого типа
Например, пять элементов send, receive, count, value, reset перечислимого типа могут быть закодированы тремя различными способами – кодами ONEHOT, BINARY, GRAY.
Унарное кодирование элементов перечислимого типа
Элемент перечислимого типа | Код ONEHOT | ||||
---|---|---|---|---|---|
Bit4 | Bit3 | Bit2 | Bit1 | Bit0 | |
Send | 0 | 0 | 0 | 0 | 1 |
Receive | 0 | 0 | 0 | 1 | 0 |
Count | 0 | 0 | 1 | 0 | 0 |
Value | 0 | 1 | 0 | 0 | 0 |
Reset | 1 | 0 | 0 | 0 | 0 |
Бинарное кодирование элементов перечислимого типа
Элемент перечислимого типа | Код BINARY | ||
---|---|---|---|
Bit2 | Bit1 | Bit0 | |
Send | 0 | 0 | 0 |
Receive | 0 | 0 | 1 |
Count | 0 | 1 | 0 |
Value | 0 | 1 | 1 |
Reset | 1 | 0 | 0 |
Код Грэя для кодирования элементов перечислимого типа
Элемент перечислимого типа | Код GRAY | ||
---|---|---|---|
Bit2 | Bit1 | Bit0 | |
Send | 0 | 0 | 0 |
Receive | 0 | 0 | 1 |
Count | 0 | 1 | 1 |
Value | 0 | 1 | 0 |
Reset | 1 | 1 | 0 |
В унитарном коде ONEHOT каждый элемент перечислимого типа кодируется своей булевой (битовой) переменной, код BINARY – это двоичный (бинарный) код с минимальным числом битовых кодирующих переменных, код GRAY – это код Грэя, т.е. код, в котором соседние кодовые комбинации отличаются в лишь в одном разряде.
Слайд:Кодирование данных типа array
В приводимом ниже примере основное внимание следует обратить на то, как кодируются (обозначаются) входные и выходные сигналы в синтезированной схеме для случая, когда входными и выходными сигналами в исходном VHDL-коде являются сигналы типа “массив”. В примере это массивы целых чисел.
Пример показывает также, что при синтезе поддерживаются операторы арифметического сложения, цикла и конструкции определения собственных подтипов, а также то, что могут использоваться пакеты для декларации подтипов.
package vv is type in_array is array (natural range 1 to 3) of integer range 0 to 3; type out_array is array (natural range 1 to 3) of integer range 0 to 6; end vv; package body vv is end vv; library work; use work.vv.all; entity massiv is port ( AA, BB: in in_array; CC : out out_array); end massiv; architecture functional of massiv is begin p0: process (AA,BB) variable DD : out_array; begin loop1: for i in 1 to 3 loop DD(i) := AA(i) + BB(i); end loop loop1; CC<=DD; end process; end functional;
Интерфейс синтезированной схемы massiv.
library IEEE; use IEEE.STD_LOGIC_1164.all; entity massiv is port ( aa_1_1 : IN std_logic ; aa_1_0 : IN std_logic ; aa_2_1 : IN std_logic ; aa_2_0 : IN std_logic ; aa_3_1 : IN std_logic ; aa_3_0 : IN std_logic ; bb_1_1 : IN std_logic ; bb_1_0 : IN std_logic ; bb_2_1 : IN std_logic ; bb_2_0 : IN std_logic ; bb_3_1 : IN std_logic ; bb_3_0 : IN std_logic ; cc_1_2 : OUT std_logic ; cc_1_1 : OUT std_logic ; cc_1_0 : OUT std_logic ; cc_2_2 : OUT std_logic ; cc_2_1 : OUT std_logic ; cc_2_0 : OUT std_logic ; cc_3_2 : OUT std_logic ; cc_3_1 : OUT std_logic ; cc_3_0 : OUT std_logic) ; end massiv ;
Слайд:Результирующая таблица замены типов данных при синтезе
Ниже в таблице указано преобразование типов данных при синтезе – все типы заменяются типом std_logic либо std_logic_vector.
Тип данных (до синтеза) | Тип данных (после синтеза) |
---|---|
boolean | std_logic |
bit | std_logic |
integer | std_logic_vector |
character | std_logic_vector |
array | множество сигналов типа std_logic |
record | множество сигналов типа std_logic |
string | множество сигналов типа std_logic |
std_logic | std_logic |
std_ulogic | std_logic |
std_logic_vector | std_logic_vector |
std_ulogic_vector | std_logic_vector |
перечислимый тип | std_logic_vector |
Слайд:Синтезируемые и несинтезируемые операторы и конструкции
Понятие синтезируемого подмножества языка VHDL является очень важным. Дело в том, что синтезаторы, в отличие от систем моделирования, поддерживают не весь язык VHDL, а только некоторое подмножество этого языка, которое принято называть синтезируемым.
Большинство конструкций VHDL являются синтезируемыми – по ним система синтеза может построить логическую схему в функционально полном базисе логических элементов.
Перечислим несинтезируемые конструкции, т. е. такие, по которым логические схемы синтезатором не строятся.
Слайд:Несинтезируемые VHDL конструкции
1. Операции над типом real не поддерживаются при синтезе.
Отсутствие поддержки понимается следующим образом: если проектировщик употребил в VHDL-коде тип real, то синтезаторы выдадут сообщение об ошибке и схема не будет построена.
2. Операции над файлами не поддерживаются при синтезе.
Данные операции используют ключевые слова VHDL: file (файл), accsess – (доступ).
3. Распределители (allocators) не поддерживаются при синтезе.
4. Атрибуты, определенные пользователем.
Синтезатор XST не поддерживает такие атрибуты, синтезатор Leonardo – поддерживает.
5. Сигналы, декларированные в пакете.
Синтезатор Leonardo не поддерживает такие декларации, синтезатор XST – поддерживает.
6. Ключевое слово after игнорируется при синтезе.
Это справедливо для обоих синтезаторов.
Игнорируется – это значит пропускается, как будто этого слова вовсе и нет.
Поэтому синтезаторы не гарантируют требуемую задержку синтезированной схемы, которая (задержка) определяется алгоритмической моделью.
Синтезаторы ориентированы на реализацию некоторых функций (алгоритмов), которые соответствуют событиям, связанным между собой причинно-следственными связями в физическом времени,
схемная реализация функций может привести к поведению во времени, отличающемуся от поведения во времени алгоритмической модели.
Например, оператор
Y <= X1 or X2 or X3 after 30 ns;
Y <= X1 or X2 or X3 after 1 ns;
7. Ограничения на инициализацию значений. Игнорируются инициальные значения сигналов в разделе декларации сигналов архитектурного тела. Игнорируются инициальные значения портов OUTPUT, INOUT в интерфейсе объекта проекта, т.е. в entity. В операторе процесса игнорируются инициальные значения переменных в разделе деклараций переменных.
8. Ограничения использования оператора цикла loop. Циклы поддерживаются, если цикловые переменные ограничены константами.
9. Ограничения на использование оператора wait. Выражение в условии until оператора wait должно определять передний или задний фронт. Многократные операторы wait допускаются в операторе процесса, однако условия ожидания должны быть одинаковыми. Для XST оператор wait не может быть внутри цикла (оператор цикла может быть в процессе, функции, процедуре), для Leonardo – может.
10. Ограничения на атрибуты выделения фронтов сигналов. Атрибуты 'event, 'stable могут быть использованы только для того, чтобы определить передний или задний фронты сигналов. Например,
clk'event and clk='1' --задание переднего фронта сигнала clk
clk'event and clk='0' --задание заднего фронта сигнала clk
not clk'stable and clk='0' --задание заднего фронта сигнала clk
If (clk'event and clk='1') then -- условие в операторе if
Wait until ((not clk'stable) and clk='0') -- условие в операторе wait
Block (clk'event and clk='1') -- охранное выражение в операторе блока
В условиях (выражениях), где есть синхросигнал clk, не допускается употребление других сигналов. Например, конструкция
If (clk'event and clk='1' and rst ='0') then
wait [on clock_signal] until [clock_signal’event | not clock_signal’stable) and] clock_signal= {'0'|'1'};
11. Ограничения для операций {/, rem, mod}. В выражениях
c <= x / y; -- операция деления, c – целая часть частного d <= x rem y; -- операция деления, d – остаток e <= x mod y; -- операция деления по модулю
c <= a /(-2) ; --error d <= b rem (3); --error e <= x mod (5); --error
12. Ограничения оператора ** (возведение в степень). Оператор
c <= a**(2); --error
c <= 2**(N); -- good
13. Охраняемый блок. В синтезаторе Leonardo схема по VHDL-коду блока с охранным выражением синтезируется, в XST выдается сообщение, что охраняемые сигналы не поддерживаются при синтезе, и схема не строится.
14. Назначение сигнала. В XST поддерживаются операторы назначения сигнала с ключевым словом transport, и не поддерживаются – со словом guarded (охраняемый). В Leonardo таких ограничений нет.
15. Сигналы типа register, bus. В XST не поддерживаются типы register, bus, а в Leonardo – поддерживаются. Если декларировать сигналы такого типа, то синтезатор XST выдает следующее сообщение: “Bus or register unsupported in signal declaration.”
16. Ключевое слово disconnect не поддерживается.
В таблице сведены результаты сравнения синтезаторов: знак “–” соответствует запрещенной для синтеза конструкции; знак “+” соответствует синтезируемой конструкции; знак “#” указывает на различное понимание синтезируемости конструкции в сравниваемых синтезаторах. В общем, оказывается, что Leonardo имеет меньше запрещенных VHDL-конструкций, исключение составляет только операция 2N возведения в степень – для этой операции XST не имеет ограничения N≤30. Поэтому проекты, синтезированные в XST, имеют шанс быть синтезированными в Leonardo без дополнительных изменений, но не наоборот. Однако это не абсолютный вывод, опытные проектировщики, возможно, встречались и с другими ситуациями несовместимости синтезаторов. Синтезаторы быстро совершенствуются и для следующих версий ситуация может быть уже другой.
VHDL-конструкция | Синтезатор XST | Синтезатор Leonardo |
---|---|---|
real | – | – |
file, access | – | – |
allocator | – | – |
disconnect | – | – |
guarded | – | + |
register | – | + |
bus | – | + |
linkage | – | + |
group | – | + |
wait | # | # |
x/a; x rem a; x mod a; (a=2N, N=0,1, 2, …) |
+ | + |
2**N | # | # |
a**(N) | – | – |
Декларация сигнала в пакете | + | – |
Атрибут, определенный пользователем | – | + |
after | игнорируется | игнорируется |
Для получения синтезируемых проектов, повышения их качества и возможности использования обоих синтезаторов XST и Leonardo можно рекомендовать следующее.
- Не используйте в VHDL-проектах задание времени в “явном” виде, т.е. cледует избегать конструкций вида wait for.
- Переключайте состояния проектируемых систем по изменениям фронтов и уровней сигналов.
- Не пользуйтесь конструкциями, которые не синтезируются (различаются в понимании) в обоих синтезаторах. Пользуйтесь теми конструкциями, которые понимаются одинаково в обоих синтезаторах, тем более что таких конструкций подавляющее большинство.
- Для унификации проектов пользуйтесь пакетами из библиотеки IEEE.
- Особенно осторожно следует обращаться с оператором wait ожидания и выражениями для условий ожидания, именно эти конструкции приводят к последовательностным схемам, т.е. схемам с триггерами и именно здесь есть важные отличия XST и Leonardo. В выражениях с сигналом clk должен участвовать только один сигнал clk, а не несколько сигналов – это типичная ошибка.
- Для описания комбинационной логики не используйте охраняемые сигналы и блоки – они ведут к триггерам.
Слайд:Примеры синтезируемых VHDL конструкций / Пример 1. Схемная реализация логических выражений
При синтезе происходит подстановка констант и последующее упрощение логических выражений.
entity const_log is port( x1, x2 : in bit_vector (0 to 4); y : out bit_vector (0 to 4)); end const_log; architecture beh of const_log is constant b : bit_vector (0 to 4) := "01010"; begin y <= (x1 and x2) or b; -- поразрядные логические -- операции and, or end beh;

! Все логические операторы схемно реализуются. Допускается использование констант в логических выражениях.
Слайд:Примеры синтезируемых VHDL конструкций / Пример 2. Схемная реализация цикла
! Оператор цикла (loop) поддерживается при синтезе.
Если цикл реализуе k итераций, то синтезированная схема состоит из k подсхем – каждая из подсхем соответвует одной итерации цикла.
entity control_loop is port ( a: in bit_vector (0 to 3); m: out bit_vector (0 to 3)); end control_loop; architecture example of control_loop is begin process (a) variable b: bit; begin b := '1'; for i in 0 to 3 loop b:= a(3-i) and b; m( i ) <= b; end loop; end process; end example;
! Начальные значения переменных игнорируются при синтезе.
