Многократные Процессы в Архитектуре
Действительно ли нам нужен VHDL? Представление Системы в VHDL: Единицы Проекта Объекты VHDL:Сигнал Спецификация Интерфейса Системы Конструкции VHDL для Описания Поведения Системы Описание Поведения при помощи Процессов Многократные Процессы в Архитектуре Определение Структуры Системы Испытание Проекта при помощи Испытательного стенда |
Глава 7
Многократные Процессы в Архитектуре
Содержание Главы 7
7.1. Краткий обзор Главы
7.2. Параллелизм? Это настолько Естественно …
7.2.1. Многомерность Мира
7.2.2. Параллельная Природа Систем
7.2.3. Структура Поведенческой Архитектуры
7.2.4. Как Архитектура Выполненяется
7.2.5. Прохождение Информации Между Процессами
7.3. Упрощенные Процессы: Назначение Сигнала
7.3.1. Некоторые Процессы - такие Простые …
7.3.2. . Активизация Параллельных Назначений
7.3.3. Условное Присваивание Сигнала
7.3.4. Выборочное Присваивание Сигнала
7.4. Драйвера и Атрибуты Сигнала
7.4.1. Концепция Драйвера
7.4.2. Каждый Сигнал Имеет Хронологию и Будущее
7.4.3. Время Зависимые Атрибуты Сигналов
7.4.4. Другие Атрибуты
7.5. Разрешение
7.5.1. Может ли Сигнал иметь Два Драйвера?
7.5.2. Многократный Драйвер Сигнала Должен Быть Разрешен
7.5.3. Двузначная Логика Не Достаточна Для Разрешений
7.5.4. Многозначная Логика
7.5.5. Разрешенния Для Многозначной логики
Резюме
7.1. Краткий обзор Главы
Каждый процесс имеет последовательную спецификацию и не может использоваться, чтобы описать комплексные системы, потому что такие системы по существу параллельны. В секции 2 мы покажем, как описать архитектуру VHDL, которая будет состоять из одновременно выполненных процессов.
Иногда, мы должны описать такие простые блоки как логические схемы. Определение их с процессами было бы излишне сложно. Для таких блоков как схемы мы должны использовать упрощенный процесс, названный одновременное присваивание сигнала. Такие конструкции, элементы и способ выполнения определены в Секции3.
Секция 4 объясняет, почему в процессах назначение сигналам определенной величины происходит не тогда когда сталкиваются с назначением, а когда процесс приостановлен.
Драйвера играют значительную роль в одновременных назначениях сигнала, также, как и форма сигнала, атрибуты, которые представлены в той же самой секции.
Как только происходит одновременное назначение сигнала сразу же должны быть многократные драйвера для того же самого сигнала. Так как различные значения сигнала могут приходить в одно и тоже время, то для этого случая требуется решить, какое значение будет преобладать и какое будет назначено сигналу. Секция 5 показывает, как это выполнено через функцию разрешения и многозначную логику. Промышленные стандарты логических типов std_logic и std_logic_vector представлены в этой секции также.
7.2.1.Многомерность Мира
Ключевые вопросы:
В то время как удобно определить предметы последовательным способом, это - только упрощенный способ описания действительности. Фактически, мир не последователен вообще. Только осмотритесь вокруг Вас: Вы изучаете VHDL, кто - то читает газету, дети играют в баскетбол, ваш друг пытается вызывать Вас и вашего босса, который поехал в отпуск и находиться с другой стороны земного шара. Все эти результаты случаются в одно и то же самое время или одновременно. Если мы трактуем каждого из этих людей как отдельную систему (Глава 2 объяснила, почему мы можем делать это) то эти системы функционируют одновременно.
Примеры:
Рисунок:
7.2.2. Параллельная Природа Систем
Ключевые вопросы:
В общем мы пришли к выводу, что некоторые системы могут быть параллельны внутри и в тоже время полностью автономные снаружи . Только на определенном уровне детализации мы рассматриваем данную подсистему как последовательность действий или процессов.Так как VHDL - иерархический язык, мы способны определить систему, такой какой она в действительности является, а именно как " набор одновременно работающих подсистем ". Каждая из них может быть взаимосвязанной в рамках подсистемы и мы можем определить подсистему как отдельный процесс. Уровень детализации будет зависеть от потребностей - иногда процесс можно определит поведением составных компонент таких как процессор, а в других случаях, мы его может детализировать до уровня процесса на логическом вентиле.
Это ведет к заключению, что поведенческая спецификация системы - набор одновременных последовательных процессов.
Примеры:
Рассмотрите двух-разрядный сдвиговый регистр с внутренним датчиком меток времени как пример параллельного поведения. Регистр состоит из трех процессов:entity reg is
port(d : in bit;
q : out bit);
end reg;
architecture reg_arch of reg is
signal s1 : bit;
signal clock : bit;
begin
clk:process -- main clock
-- generator
begin
clock <= '0';
wait for 5 ns;
clock <= '1';
wait for 5 ns;
end process; d1:process (clock)
begin
if clock='1' then
s1 <= d;
end if;
end process ;
d2:process (clock)
begin
if clock='0' then
q <= s1;
end if;
end process ;
end reg_arch;
Рисунок:
7.2.3. Структура Поведенческой Архитектуры
Ключевые вопросы:
Пришло время, чтобы определить как поведенческая архитектура должна выглядеть. До этого мы сконцентрировались на таких элементах архитектуры как декларации и отдельные процессы.Подобно другим комплексным конструкциям VHDL, архитектура состоит из шаблона и тела. Шаблон определяет архитектуру и обеспечивает имя и границы тела. Он также включает декларации объектов, которые являются внутренними к архитектуре
Заметьте: Все процессы полностью определены внутри тела архитектуры.
Характерная особенность заголовка архитектуры - ассоциация с сущность, потому что каждая архитектура должна принадлежать сущности (должна быть чем-то сущности).
Тело архитектуры имеет параллельную структуру, которая является иногда трудно вообразимой, потому что все утверждения (процессы и их содержание) внесены в список последовательно. Однако, все процессы в любой архитектуре выполняются одновременно друг с другом.
Примеры:
Этот пример основан на D-триггере со внутренним генератором датчика меток времени, который может быть скрыт сигналом m, который является активным когда он логический '0':entity dff is
port(m,d : in bit;
q, nq : buffer bit);
end dff;
architecture dff_arch of dff is
signal s1, s2 : bit;
signal clock : bit;
begin
clk:process -- main clock
-- generator
begin
clock <= '0';
wait for 5 ns;
clock <= '1';
wait for 5 ns;
end process; n1:process(m)
begin
s1 <= not(m);
end process;
nand1:process(s1,clock)
begin
s2 <= s1 nand clock;
end process;
d1:process (s2)
begin
if s2='1' then
q <= d;
nq <= not(d);
end if;
end process ;
end dff_arch;
Рисунок:
7.2.4. Как Архитектура Выполненяется
Ключевые вопросы:
Является ли параллельное выполнение процессов и последовательное выполнение операторов внутри процессов небольшое перепутывание? Эта смесь последовательных и одновременных действий - одно из наиболее трудных понятий в VHDL. Теперь Мы ближе рассмотрим эту проблему , чтобы удостовериться, что она хорошо понята.Как Вы помните из предыдущей главы, приостановленный процесс возобновляется, когда любой из сигналов в списке чувствительности изменяет свое значение. Это правило также применимо к многократным процессам в архитектуре и когда сигнал изменяет значение, то все процессы, которые имеют этот сигнал в их списках чувствительности, возобновляются. Операторы внутри возобновленных процессов выполняются последовательно. Однако, они выполняются независимо от операторов в других процессах.
Идея относительно параллелизма была бы намного проще, для понимания, если бы мы смогли описать процессы рядом, а не один под другим. К сожалению, из-за изобразительных ограничений все программы, включая параллельные VHDL спецификации, внесены в список последовательно.
Примеры:
Каждая цепь этого полного сумматора, определена как отдельный процесс, который выполняется одновременно с другими:entity fadder is
port (
a : in bit;
b : in bit;
Ci : in bit;
S : out bit;
Co : out bit
);
end fadder;
architecture fadder_arch1 of fadder is
signal s1, s2, s3, s4 : bit;
begin
p1: process(b, Ci)
begin
s1 <= b xor Ci;
end process p1;
p2: process(b, Ci)
begin
s2 <= b and Ci;
end process p2; p3: process(a, b)
begin
s3 <= a and b;
end process p3;
p4: process(a, Ci)
begin
s4 <= a and Ci;
end process p4;
p5: process(a, s1)
begin
S <= a xor s1;
end process p5;
p6: process(s2, s3, s4)
begin
Co <= s2 or s3 or s4;
end process p6;
end fadder_arch1;
Рисунок:
7.2.5. Прохождение Информации Между Процессами
Ключевые вопросы:
Так как процессы не различимы между сигналами, сгенерированными внешним образом (приходящими от устройств) и сигналами сгенерированными внутри (объявленные внутри архитектуры), то сигналы, которые активизируют процессы, могут быть сгенерированы другими процессами в той же самой архитектуре. Всякий раз, когда сигнал в списке чувствительности процесса изменяет значение, процесс активизируется. Это случается независимо от того, был ли сигнал изменен окружающей средой системы или другим процессом.Заметьте: Только сигналы могут использоваться для пересылки информации между процессами. Потому что переменные - местные объекты по отношению к процессам, они не могут использоваться для переноса информации между процессами.
Примеры:
Здесь приведен пример обмена информацией внутри архитектуры; JK триггера, построенного на базе D триггеров, имеющим датчика меток времени внутри их архитектуры.entity jkff is
port(j,k : in bit;
q, nq : buffer bit);
end jkff;
architecture jkff_arch of jkff is
signal s1, s2, s3, s4 : bit;
signal clock : bit;
begin
clk:process -- main clock generator
begin
clock <= '0';
wait for 5 ns;
clock <= '1';
wait for 5 ns;
end process;
nand1:process(j,nq)
begin
s1 <= j nand nq;
end process; nand2:process(s1,s4)
begin
s2 <= s1 nand s4;
end process;
nand3:process(s3,q)
begin
s4 <= s3 nand q;
end process;
not1:process(k)
begin
s3 <= not(k);
end process;
d1:process (clock)
begin
if clock='1' then
q <= s2;
nq <= not(s2);
end if;
end process ;
end jkff_arch;
Рисунок:
7.3.1. Некоторые Процессы - такие Простые
Ключевые вопросы:
Иногда Вы можете пожелать использовать простую логическую схему как отдельный блок в архитектуре, например:OutAND <= InAND1 and InAND2;
Определение такого поведения с процессом требовало бы трех дополнительных операторов (заголовка процесса, предложение begin и предложение end process) которые являются самыми массовыми для цепи AND . VHDL разрешает упрощать такие процессы с одним назначением при помощи строки оператора называемого concurrent signal assignment (одновременное назначение сигнала).
Оператор одновременного назначения сигнала может появляться внутри архитектуры параллельно с некоторыми процессами и может выполняться одновременно с другими назначениями, подобно процессам. Если два или больше присваиваний появляются в процессе, то они будут выполнены согласно внесенной в список последовательности. Однако, если они были представлены одновременными назначениями сигнала, они будут выполнены одновременно.
Заметьте: параллельное присваивание сигнала эквивалентно процессу с только одним назначением сигнала. Если два или больше присваиваний появляются в процессе, они будут выполнены в предопределенной последовательности. Однако, если они были представлены параллельными присваиваниями сигнала, они будут выполнены одновременно.
Примеры:
Асинхронный S/R триггер - хороший пример параллельного выполнения присваивания сигнала в архитектуре:entity rs is
port (
set: in bit;
reset: in bit;
q: buffer bit;
nq: buffer bit
);
end rs;
architecture rs_arch of rs is
begin
q <= not ( nq and set ) after 1 ns;
nq <= not ( q and reset) after 1 ns;
end rs_arch;
Рисунок:
7.3.2. Активизация Параллельных Назначений
Ключевые вопросы:
Процессы имеют списки чувствительности или операторы wait , которые определяют условия для их активизации или возобновления. Как относительно одновременных операций назначения? Они не имеют ни операторов wait ни списков чувствительности.Так как Вы, возможно, наблюдали на рисунке предыдущего экрана, списки чувствительности всех процессов содержат сигналы, которые появились позже в результате выполнения выражений, которые присваивали значения выходным сигналам процессов.
Это может потребовать, чтобы операторы одновременного назначения сигнала были чувствительны к изменению любого сигнала, который появляется справа после символа назначения. Фактически, это то, как VHDL моделирующие устройства действительно работают: при изменении любого из сигналов с правой стороны одновременно назначаются сигналы и активизируются выполнения присваивания. Это присваивание может быть отсрочено при помощи предложения after, или инерционной, или транспортной задержкой.
Примеры:
Предварительно описанный полный сумматор может быть упрощен при помощи операторов параллельного назначения сигнала:entity fadder is
port (
a: in bit;
b: in bit;
Ci: in bit;
S: out bit;
Co: out bit
);
end fadder;
architecture fadder_arch2 of fadder is
signal s1, s2, s3, s4 : bit;
begin
s1 <= b xor Ci;
s2 <= b and Ci;
s3 <= a and b;
s4 <= a and Ci;
S <= a xor s1;
Co <= s2 or s3 or s4;
end fadder_arch2;
Рисунок:
7.3.3. Условное Присваивание Сигнала
Ключевые вопросы:
Иногда Вы можете нуждаться выполнить назначение сигнала для случая когда условие истинно. Начиная с условного оператора " если … затем … " последовательные операторы ограничены только процессами, поэтому Вам, вероятно, придется использовать условное назначение сигнала, которое может также использоваться внутри архитектуры. Это функциональный эквивалент условного оператора, но написан различными способами отличными от условного назначения сигнала.Синтаксис условного назначения сигнала определяется способом, в котором дан порядок элементов: присваивание определенной величины сигналу, когда условие истинно, а если нет или иначе присваивание другого значения. Оператор else может быть вложен.
Важная разница между условным присваиванием сигнала и условным оператором в том, что вышеупомянутый ограничен только присваиванием сигнала, а последний может использоваться для любых видов последовательных операторов.
Примеры:
Модель цепи XOR. Первая архитектура применяет конструцию " если ...
затем ... еще ... ", в то время как вторая использует условное присваивание сигнала:
entity xor_gate is
port (
a: in bit;
b: in bit;
y: out bit
);
end xor_gate;
architecture xor_gate_arch1 of xor_gate is
begin
gate:process(a , b)
begin
if a=b then y<='0';
else y<='1';
end if;
end process gate;
end xor_gate_arch1;
architecture xor_gate_arch2 of xor_gate is
begin
Y <= '0' when a=b else
'1';
end xor_gate_arch2;
Рисунок:
7.3.4. Выборочное Присваивание Сигнала
Ключевые вопросы:
Для условного присваивания сигналу одного из отдельных значений, используют конструкцию выборочного присваивания сигнала. Это параллельная конструкция, которая не может использоваться внутри процессов, у которых операторы выбора должны использоваться вместо нее. Также истинно обратное: оператор выбора не может быть использован внешними процессами, у которых конструкции выборочного присваивания сигнала должны использоваться.Заметьте: В отличие от оператора case, выборочное присваивание сигнала ограничено присваиванием только сигнала и не может содержать любые другие операторы.
Примеры:
Модель мультиплексора; Архитектура sel1_arch использовала выборочное присвоение сигнала а архитектура sel2_arch основана на операторе выбора (внутри процесса):entity sel is
port (
i: in bit_vector (0 to 3);
s: in bit_vector (0 to 1);
o: out bit
);
end sel;
architecture sel1_arch of sel is
begin
with s select
o <= i(0) when "00",
i(1) when "01",
i(2) when "10",
i(3) when others;
end sel1_arch;
architecture sel2_arch of sel is
begin
mux :process (i, s)
begin
case s is
when "00" => o <= i(0);
when "01" => o <= i(1);
when "10" => o <= i(2);
when others => o <= i(3);
end case;
end process mux;
end sel2_arch;
Рисунок:
7.4.1. Концепция Драйвера
Ключевые вопросы:
Вы помните, что когда сигналы назначены, то их новые значения внутри процессов? Это назначение происходит только после того, как процесс приостановлен.
Кроме того, если имеется больше чем одно присвоение на сигнал, только последний будет воздействовать. Как при этом мы можем хранить информацию относительно сигнала?
Эта функция выполняется драйвером. VHDL компилятор создает драйвера для каждого сигнала, которому присвоено значение внутри процесса. Правило очень просто: независимо от того, как присвоено значение сигналу в процессе, имеется только один драйвер сигнала на процесс. Все действия выполняются при помощи драйвера, который копируется к сигналу только тогда, когда процесс приостановлен.
Рисунок:
7.4.2. Каждый Сигнал Имеет Хронологию и Будущее
Text:Ключевые вопросы:
Благодаря драйверу, сигнал может иметь прошлое, настоящее и будущие значение. Драйвера, содержащие текущее значение сигнала, показаны на предыдущей странице. Однако, драйвера могут также определять проектную форму сигнала для выходного сигнала. Каждому драйверу может быть назначена такая форма сигнала, состоящая из последовательности одних или большего количества транзакций. Транзакция состоит из значения сигнала и времени. Время определяет момент, когда драйверу будет назначено новое значение, указанное транзакцией.Форма сигнала может быть определена явно как последовательность значений, а связанные задержки относились к тем же самым точкам времени. Формы сигнала могут рассматриваться как проектируемое будущее сигналов.
Так как моделирующие устройства хранят транзакции для каждого сигнала, они создают фактически хронологию сигналов.
Примеры:
Это - модель синхронизации сигнал-генератора. Здесь не сложно описать хронологию и будущее сигнала меток времени.entity clk_gen is
port(clock : out bit);
end clk_gen;
architecture clk_gen_arch of clk_gen is
begin
clk:process -- main clock generator
begin
clock <= '0';
wait for 5 ns;
clock <= '1';
wait for 5 ns;
end process;
end clk_gen_arch;
Рисунок:
7.4.3. Время Зависимые Атрибуты Сигналов
Ключевые вопросы:
Описание будущих сигналов важно для создания так называемых испытательных стендов, где VHDL спецификация проверена в VHDL окружающей среде, и стимулы представлены формами сигнала.
Мы возвратимся этому подробние в Главе 9.
Почему мы нуждаемся в хронологии сигнала? Имеются веские причины. Например, наличие только настоящего значения не разрешила бы, чтобы мы проверили, изменился ли сигнал недавно, или проверили, был ли это переход с низкого уровня на высокий и наоборот. Хронология сигнала представлена атрибутами сигнала. Атрибуты это фрагменты информации, присоединенные к каждому сигналу и автоматически модифицируемые на основании хронологии сигнала. Информация включает предыдущее значение сигнала, количество времени, которое прошло от последнего изменения значения сигнала, и т.д. Чтобы получить текущее значение атрибута, Вы должны определить имя сигнала, сопровождаемое апострофом и имя атрибута.
Примеры:
-- flip flop D typelibrary IEEE;
use IEEE.std_logic_1164.all;
entity ffd is
generic(setup_time : time := 2 ns;
hold_time : time := 5 ns);
port (d: in std_logic;
clk: in std_logic;
q: out std_logic);
end ffd;
architecture ffd_arch of ffd is
begin
main:process (clk)
begin
if rising_edge(clk) then
assert(d'last_event>=setup_time)
-- setup_check
report "setup time violation"
severity warning;
q <= d; -- assigning value
-- to the output
end if;
end process ; hold_check:process (clk'delayed(hold_time))
begin
if rising_edge(clk'delayed(hold_time))
then
assert (d'last_event>=hold_time)
-- setup_check
report "hold time violation"
severity warning;
end if;
end process ;
end ffd_arch;
Рисунок:
7.4.4. Другие Атрибуты
Ключевые вопросы:
Атрибуты относящиеся к хронологии сигналов - не единственные доступные атрибуты. Фактически, атрибуты совершенно часто используются в VHDL, и язык определяет 36 различных атрибутов для различных классов объектов: скалярные типы, дискретные типы, массивы, сигналы и именованные объекты. См. Руководство по применению для списка всех предопределенных атрибутов.Кроме предопределенных атрибутов Вы можете также определять ваши атрибуты, расширяя набор VHDL почти до бесконечности.
Атрибуты имеют много приложений – от краевого детектирования ( основанного на атрибуте результата) до размерно-независимых спецификаций. Некоторые из наиболее типичных примеров приложений атрибута приведены на рисунке с права
Примеры:
Функция преобразовывает bit_vector в целое число. Объявление reverse_range и атрибутов длины делает эту функцию универсальный (она может использоваться для любого размера bit_vector без каких либо изменений кода).entity decode is
port( i : in bit_vector(7 downto 0);
q : out integer range 0 to 255);
end decode;
architecture decode_arch of decode is
function bit_vec2int (Input: bit_vector) return integer is
variable Output: integer := 0;
variable power: integer := 1;
begin
if Input'length=0 then return Output; end if;
for I in Input'reverse_range loop
if Input(I)='1' then Output:= Output + power; end if;
power:= power * 2;
end loop;
return Output;
end bit_vec2int;
begin
q <= bit_vec2int( i );
end decode_arch;
Рисунок:
7.5.1. Может ли Сигнал иметь Два Драйвера?
Ключевые вопросы:
Когда сигнал имеет только один драйвер, его значение просто определить. Однако, что случается, когда сигнал имеет множество драйверов? Какие значения сигнала такие драйвера генерируют?Сигналы с многократными источниками могут быть найдены в многочисленных приложениях. Например, шина передачи данных компьютера может получать данные из процессора, памяти, дисков и устройств ввода-вывода. Каждый из тех элементов управляет шиной, и каждая сигнальная линия шины может иметь множество драйверов. С тех пор VHDL стал языком для описания цифровых систем, такие многократные драйверы обрабатываются в VHDL просто.
Трудно определить заранее, если "многократно - исходный" сигнал будет всегда управляться только отдельным источником. В некоторых системах это будет всегда истинно, в то же время в других может быть необходимость в смешанных сигналах из различных источников, эмулируя, например операции " зашитый И " или " зашитый ИЛИ ".
В общем случае, многократно - исходные сигналы требуют установления метода для определения результирующего значения, когда отдельные источники одновременно питают ту же самую сигнальную линию.
Примеры:
Это – модель контроллера шины для записи и чтения на\из устройств ввода-вывода. Также к шине можно обращаться снаружи. Заметьте: многократные драйвера сигналов шины и присвоение сигналов в различных процессах.library ieee;
use ieee.std_logic_1164.all;
entity system is
port(instr : in integer range 0 to 4; -- code of instruction
data_bus : inout std_logic_vector(7 downto 0)); -- data bus
end system;
architecture system_arch of system is
signal rw : std_logic; -- '1' read; '0' write
signal sd : std_logic; -- select device - '1' memory; '0' I/O
-- interface
begin
ctrl:process(instr) --control process
begin
case instr is
when 0 => rw<='1'; sd<='1';-- intruction of
-- reading from memory
when 1 => rw<='0'; sd<='1';-- intruction of writing
-- from memory
when 2 => rw<='1'; sd<='0';-- intruction of reading from I/O
when 3 => rw<='0'; sd<='0';-- intruction of writing from I/O
when 4 => rw<='Z'; sd<='Z';-- no operation
end case;
end process ctrl;
mem:process(sd, rw) -- memory is emulated by process mem
variable cell : std_logic_vector(7 downto 0);
begin
if sd='1' then
if rw='1' then data_bus <= cell after 7 ns; -- reading from memory
else cell := data_bus; -- writing to memory
end if;
else data_bus <= ( others => 'Z'); -- setting high impedance
end if;
end process mem;
io_proc :process(sd, rw) -- input/output interface is emulated by process io
variable io : std_logic_vector(7 downto 0);
begin
if sd='0' and sd'event then
if rw='1' then data_bus <= io after 12 ns; -- reading from I/O port
else io := data_bus; -- writing to I/O port
end if;
else data_bus <= ( others => 'Z'); -- setting high impedance
end if;
end process io_proc;
end system_arch;
Рисунок:
7.5.2. Многократный Драйвер Сигнала Должен Быть Разрешен
Ключевые вопросы:
VHDL моделирующее устройство не может заранее "знать" будет ли сигнал с многократными драйверами активизирован из двух или больше источников в одно и то же самое время. Из-за этого, моделирующее устройство должно быть подготовлено к смешиванию значений сигнала. Такое "смешивание" сигналов называется в VHDL разрешение. Правила для смешивания значения сигнала определены как таблица, которая называется функцией разрешения. Таблица вносит в список все возможные значения сигнала в колоннах и строках, и каждая ячейка содержит информацию относительно того, что за значение будет сгенерировано, если два значения смешаны.Сигналы Смешивания от различных водителей могли сравниваться с цветами смешивания на палитре живописца: каждый цвет, являющийся эквивалентом стоимости(значения) сигнала. Чистые цвета могли приравниваться к сигналам оденарной системы шин - driver. Однако, многократные цвета, наложенные на друг друге привели бы к полностью новому цвету.
Примеры:
Пример управления при помощи двух драйверов одним выходом. S сигнал определит, будет выход соединен с a или not a.library ieee;
use ieee.std_logic_1164.all;
entity drivers is
port (
A : in std_logic;
S : in std_logic;
Y : out std_logic);
end drivers;
architecture drivers_arch of drivers is
begin
P1 : process (A, S)
begin
if S='1' then Y<=A;
else Y<='Z';
end if;
end process;
P2 : process (A, S)
begin
if S='0' then Y<=not A;
else Y<='Z';
end if;
end process;
end drivers_arch;
Рисунок:
7.5.3. Двузначная Логика Не Достаточна Для Разрешений
Ключевые вопросы:
Как Вы наверно отметили на предыдущей странице, функция разрешений требует больше информации чем основной набор значений. Например, три основных цвета из экрана на предыдущей странице нуждались в трех дополнительных, чтобы быть решенными.Подобное имеет место , когда мы пытаемся представлять многократно - исходные сигналы в VHDL. Когда мы смотрим на сигнал битового типа, возникает очевидный вопрос,: что случится, если мы смешиваем '0' и '1' (какое разрешенное значение '0' и '1'?).
Проблема с битовым типом состоит в том, что не возможно определить разрешенные сигналы только при помощи двух значений и не имеется никакого ответа на вышеупомянутый вопрос.
Этот факт будет иметь далеко идущие последствия: если Вы используете только типы bit и bit_vector, Вы НЕ способны определить микропроцессор в VHDL. Неразрешенные типы (подобные двум вышеупомянутым) не могут использоваться для сигналов с многократными драйверами, так как для них по очереди необходимымо определить шины передачи данных (которые очевидно существуют в каждом микропроцессоре). Чтобы решать эту проблему, Вы будете должны использовать некоторый другой логический тип данных, а именно с больше чем двумя значениями и функцией разрешения, который определен для всех комбинаций значения сигнала.
Примеры:
library ieee;use ieee.std_logic_1164.all;
entity driver is
port (a : in bit;
y : out bit;
b : in std_logic;
z : out std_logic);
end driver;
architecture driver_arch of driver is
begin
p1:process( a )
begin -- this is enough condition for rising edge detection using
-- bit type
if a='1' and a'event then y <= a after 1 ns;
end if;
end process;
p2:process( b )
begin -- this is enough condition for rising edge
-- detection using std_logic type
if b='1' and b'event and b'last_value='0' then z <= b after 3 ns;
end if;
end process;
end driver_arch;
Рисунок:
7.5.4. Многозначная Логика
Ключевые вопросы:
Одних значений '0' и '1' не достаточно для разрешения многократно - исходных сигналов. Даже некоторые простые - исходные сигналы часто требуют больше чем два значения для представления реальной жизни цифровые объектов:Этот блок также содержит определение векторного типа, который основан на типе std_ulogic и элементах std_ulogic_vector. Оба типа также имеют набор основных логических действий, определенных для них.
Примечание: буква 'u' внутри названия ulogic указывает на " неразрешенные типы ". Такие значения не могут использоваться сигналами, которые имеют множественные драйвера.
Примеры:
Это - пример таблицы разрешения и функции разрешения типа std_logic. Это - самый простой способ определить функцию разрешения для логики с 9 значениями:PACKAGE BODY std_logic_1164 IS
-- part of real code taken from IEEE standard logic package
-- below is presented resolution table and resolution function
CONSTANT resolution_table : stdlogic_table := (
-- ---------------------------------------------------------
-- | U X 0 1 Z W L H - | |
-- ---------------------------------------------------------
( 'U', 'U', 'U', 'U', 'U', 'U', 'U', 'U', 'U' ), -- | U |
( 'U', 'X', 'X', 'X', 'X', 'X', 'X', 'X', 'X' ), -- | X |
( 'U', 'X', '0', 'X', '0', '0', '0', '0', 'X' ), -- | 0 |
( 'U', 'X', 'X', '1', '1', '1', '1', '1', 'X' ), -- | 1 |
( 'U', 'X', '0', '1', 'Z', 'W', 'L', 'H', 'X' ), -- | Z |
( 'U', 'X', '0', '1', 'W', 'W', 'W', 'W', 'X' ), -- | W |
( 'U', 'X', '0', '1', 'L', 'W', 'L', 'W', 'X' ), -- | L |
( 'U', 'X', '0', '1', 'H', 'W', 'W', 'H', 'X' ), -- | H |
( 'U', 'X', 'X', 'X', 'X', 'X', 'X', 'X', 'X' ) -- | - |
);
function resolved ( s : std_ulogic_vector ) return std_ulogic IS
variable result : std_ulogic := 'Z'; -- weakest state default
begin
-- the test for a single driver is essential otherwise the
-- loop would return 'X' for a single driver of '-' and that
-- would conflict with the value of a single driver unresolved
-- signal
if (s'length = 1) then return s(s'low);
else
for i in s'range loop
result := resolution_table(result, s(i));
end loop;
end if;
return result;
end resolved;
Рисунок:
7.5.5. Разрешенния Для Многозначной логики
Ключевые вопросы:
Тип std_ulogic поддерживает все значения, которые могут быть необходимы, чтобы определить типичную цифровую систему.Для многозначных сигналов неразрешение делает все эти механизмы бесполезными. Из-за этого еще один тип std_logic определен в блоке Std_logic_1164:. Это соединяет выразительную мощность девяти значений std_ulogic с разрешением, давая проектировщику на VHDL действительно универсальный логический тип. Std_logic - в настоящее время фактический промышленный стандарт.
Единственное различие между std_logic и std_ulogic - то, что вышеупомянутый тип является решенной версией последних. Благодаря этому, все действия и функции (включая rising_edge и falling_edge) определенные для std_ulogic могут использоваться в std_logic без любых дополнительных деклараций.
Имеется разрешенная версия std_ulogic_vector также. Название получается совершенно логически: std_logic_vector (функция разрешения устраняет 'u' с названия).
Примеры:
Один выход управляется двумя независимыми драйверами:library IEEE;
use IEEE.std_logic_1164.all;
entity drv is
port (
en_a: in boolean;
en_b: in boolean;
a: in std_logic;
b: in std_logic;
y: out std_logic
);
end drv;
architecture drv_arch of drv is
signal sa, sb : std_logic;
begin
sa <= a when en_a else 'Z';
sb <= b when en_b else 'Z';
p1:process (sa)
begin
y <= sa;
end process p1;
p2:process (sb)
begin
y <= sb;
end process p2;
end drv_arch;
Рисунок:
Резюме
- VHDL это иерархический язык. Теперь мы должны можем определить системы как " набор параллельно работающих подсистем ". Каждая из этих подсистем будет определена как отдельный процесс, в котором поведенческая спецификация будет даваться как набор одновременно последовательных процессов.
- Как и большинство комплексных конструкций VHDL, архитектура состоит из шаблона и тела. Шаблон определяет, что эта конструкция архитектура и разрешает вводить в имя архитектуры и границы тела архитектуры.
- Исполнительная часть архитектуры (тело архитектуры) - параллельная структура.
- Всякий раз, когда сигнал в списке чувствительности процесса изменяет значение, процесс активизирован, независимо от того, заменен ли сигнал окружающей средой системы или другим процессом.
Фактически, даже тот же самый процесс может изменять процесс. - Сигналы - единственные средства для пересылки информации между процессами.
- Одновременные операторы присваивания сигнала могут появляться внутри архитектуры вместе с процессами. Как их название предполагает, они могут быть выполнены одновременно друг с другом, как одноименные процессы.
- Одновременные операторы присваивания сигнала должны быть чувствительны к изменению любого сигнала, который появляется справа от символа назначения: изменение любого из сигналов справа для одновременного назначения сигнала, активизирует выполнение присваивания.
- Подобно присваиванию сигнала в процессах, часто необходимо выполнить присваивание только тогда, когда некоторое условие истинно. Неопытные пользователи VHDL пробуют писать это, используя конструкции " если … затем … ", но к их удивлению, никакие моделирующие устройства не принимают такую спецификацию. Вместо " если … затем … ", условное присваивание сигнала может использоваться внутри архитектуры. Синтаксис условного присваивания сигнала совершенно естественна и следует за способом, который дает порядок, а именно : присваивает заданную величину сигналу, когда условие выполнено, и в противном случае, присваивает другое значение.
- Чтобы присвоить сигналу, одно из отдельных значений, в зависимости от значения того же самого объекта, используется выборочное назначение сигнала. Эти параллельные конструкции не могут использоваться внутри процесса (где должен использоваться оператор case ).
- Каждый скалярный сигнал назначен набору драйверов (или, другими словами, управляется драйверами). Каждый раз, когда VHDL сталкивается с операторами присваивания сигнала, драйвер для того сигнала сгенерирован. Вся информация относительно ожидаемых изменений значения сигнала сохранена в драйвере сигнала.
- Каждый драйвер представлен формой сигнала, которая состоит из одной или более последовательных транзакций. Транзакция, состоит из значения и времени (сигнал имеет хронологию).
- Атрибуты - различные фрагменты информации, присоединенной к каждому сигналу и они автоматически реализуются на основе хронологии сигнала.
Далее>>