Потоковое описание (dataflow)
Dataflow - означает поток данных. Описание в стиле dataflow использует в архитектуре параллельно вычисляемые выражения. Количество параллельно вычисляемых выражений может быть любым. Так как вычисления происходят параллельно, то порядок записи выражений не имеет значения. Толчком к началу вычислений является изменение любого из сигналов, входящих в выражения. Рассмотрим модель одноразрядного сумматора, показанного на рис.1.6.
Рис.1.6. Одноразрядный сумматор
entity full_adder is
port (a, b, cin: in BIT; sum, cout: out BIT);
end full_adder;
architecture full_ad_conc of full_adder is
begin
sum <= (a xor b) xor cin after 15 ns;
cout <= (a and b)or(b and cin)or(cin and a) after 10ns;
end full_ad_conc;
Для описания потока данных здесь используются два выражения. Всегда, когда происходят изменения сигналов a, b или cin, оба выражения вычисляются и сигналам sum и cout присваиваются новые значения через 15ns и 10ns, соответственно. Знак <= оператор присваивания. Выражение after 15ns означает задержку, вносимую логикой, реализующей вычисление выражения для sum. Если задержка не введена явно, то предполагается наличие бесконечно малой задержки D. Такой прием позволяет упорядочить события модели dataflow. Рассмотрим схему рис. 1.7 и ее модель.
Рис. 1.7. Цепочка инверторов
entity fast_inverter is
port (a: in BIT; z: out BIT);
end fast_inverter;
architecture delta_delay of fast_inverter is
signal b,c: BIT;
begin
z <= not c; -- выражение 1
c <= not b; --выражение 2
b <= not a; --выражение 3
end delta_delay;
В выражениях 1, 2 и 3, присваивающих значения переменным z, c, b, подразумевается задержка D. Например, в момент T происходит изменение сигнала a. Запускается процесс вычисления выражения 3 и через задержку D переменной b будет присвоено новое значение (в момент T+D). В свою очередь изменение сигнала b запустит процесс вычисления выражения 2 и значение сигнала с будет обновлено в момент T+2D. Изменение сигнала с приведет к запуску процесса вычисления выражения 1 и значение сигнала z будет изменено в момент T+3D. Временные соотношения в схеме иллюстрирует рис. 1.8.
|
|
Рис. 1.8. Временные соотношения в цепочке инверторов.
Структурное описание.
Структурное описание интерпретирует устройство как набор компонентов, связанных между собой сигналами. Грубо говоря - это таблица соединений (netlist). Рассмотрим простую схему управления (рис.1.8) и ее структурную модель.
Рис. 1.9. Устройство местного управления
entity ctr_lck is
port (data, mr, clk, din: in BIT; rdy, ctrla:out Bit);
end ctr_lck;
architecture str_view of ctr_lck is
component AND2 -- декларируется компонент AND2
port (x,y in BIT; z: out BIT);
end component;
component DFF -- декларируется компонент DFF
port (d, clock: in BIT; Q,NOTQ: out BIT);
end component;
component NOR2 -- декларируется компонент NOR2
port (a,b: in BIT; z: out BIT);
end component;
signal s1,s2: BIT;
|
|
begin
D1: DFF port map (data, clk, s1,s2); -- выражение 1
A1: AND2 port map (s2, din, ctrla); -- выражение 2
N1: NOR2 port map (s1, mr, rdy); -- выражение 3
end str_view;
Здесь декларируются три компонента: AND2, DFF и NOR2. В тело архитектуры экземпляры компонентов вводятся с помощью выражений 1, 2 и 3. Компоненты связаны между собой сигналами s1 и s2. В декларации называется имя компонента и его интерфейс, что очень схоже с декларацией интерфейса устройства. Выражение для экземпляра компонента должно в первую очередь дать имя экземпляру или ярлык. Например, D1 – это ярлык для экземпляра триггера DFF. Далее следует список связей (association list). Он устанавливает связь между портами компонента и портами и сигналами устройства. Существует два варианта связи: позиционный и поименный. В позиционном списке первый порт декларации (слева направо) компонента соответствует первому порту экземпляра компонента (слева направо), второй – второму и так далее. Именно такой вариант списка был использован в приведенном выше примере. Вместо этого можно было использовать поименный вариант списка связей, например, выражение 3 можно было бы записать так:
N1: NOR2 port map (a=>s1, b=> mr, z=>rdy);
Рассмотрим еще пример. На рис.1.2 была приведена схема полусумматора. Его структурная модель должна предстать как набор следующих компонентов: XOR на два входа (например, 7486 или отечественный аналог ЛП5) и AND на два входа (например, 7408 или отечественный аналог ЛИ1 ).
|
|
entity half_adder is
port(a, b: in BIT; sum, cur: out BIT);
end half_adder;
architecture h_a_str of half_adder is
component a_7486
port (a_2: in BIT;
a_3: in BIT;
a_1: out BIT);
end component;
component a_7408
port (a_2: in BIT;
a_3: in BIT;
a_1: out BIT);
end component;
begin
X1: a_7486 port map (a, b, sum);
A1: a_7408 port map (a, b, cur);
end h_a_str;
Названия компонентов и их портов приведены такими, какими они даны в библиотеке фирмы ALTERA – известного производителя программируемых логических схем.
Декларации компонентов, использованные в архитектуре h_a_str полусумматора half_adder, можно упаковать в отдельный файл, например, maxplus2.vhd:
package maxplus2 is
component a_7486
port (a_2: in BIT;
a_3: in BIT;
a_1: out BIT);
end component;
component a_7408
port (a_2: in BIT;
a_3: in BIT;
a_1: out BIT);
end maxplus2;
Файл maxplus2 при компиляции может быть помещен в библиотеку, например, с названием altera. Ссылка на библиотеку позволит не декларировать компоненты в архитектуре:
|
|
library altera;
use altera.maxplus2.all;
entity half_adder is
port(a, b: in BIT; sum, cur: out BIT);
end half_adder;
architecture h_a_str of half_adder is
begin
X1: a_7486 port map (a, b, sum);
A1: a_7408 port map (a, b, cur);
end h_a_str;
Дата добавления: 2019-07-15; просмотров: 70; Мы поможем в написании вашей работы! |
Мы поможем в написании ваших работ!