
Lek2013 / Lek8_FPGA
.docx
Тема параллельные операторы
Преимущество реализации алгоритма в виде аппаратной схемы перед чисто программной, с использованием процессора, в том, что отдельные части алгоритма можно вычислять параллельно.
Чтобы в программе на VHDL показать, что отдельные части алгоритма должны синтезироваться в отдельные блоки, а не выполняться последовательно, надо использовать параллельные операторы:
-
Process
-
When – параллельный аналог if
-
Select – параллельный аналог case
-
Port map
-
Generate
-
<=
В общем случае, при помощи только параллельных операторов можно реализовать исключительно комбинационную цифровую схему.
Порядок параллельных операторов в блоке Architecture не имеет значения, т.к. они начинают выполняться параллельно и одновременно. Изменение порядка параллельных команд приводит к генерации одной и той же схемы.
Оператор When
Позволяет назначить значение сигналу в зависимости от условия. Является параллельным аналогом оператора if.
Пример – мульиплексор.
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
entity mux2 is
Port ( x1,x2 : in STD_LOGIC_VECTOR (3 downto 0);
s : in STD_LOGIC;
y : out STD_LOGIC_VECTOR (3 downto 0));
end mux2;
architecture Beh of mux2 is
begin
y <= x1 when s ='1' else x2;
end Beh;
Оператор Select
Это параллельный оператор выбора, аналог последовательного оператора CASE.
Общий вид
Whith выражение select
Сигнал <= значение when значение
End;
Пример: Пусть надо составить программу управления светодиодным индикатором. При подаче данных в двоичном формате на индикаторе должно отображается число. Индикатор представляет из себя 7 светодиодов.
Обозначим светодиоды
-- ****d5****
-- * *
-- d4 d6
-- * *
-- ****d3****
-- * *
-- d0 d2
-- * *
-- ****d1****
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
entity mD is
Port ( x : in STD_LOGIC_VECTOR (2 downto 0);
d : out STD_LOGIC_VECTOR (6 downto 0));
end mD;
architecture Beh of mD is
begin
with x select
d <= "1110111" when "000",
"1000100" when "001",
"1101011" when "010",
---------------------
"0001000" when others;
end Beh;
Оператор Process
Process (список чувствительности)
Variable список переменных:тип;
Begin
Последовательные операторы
End process;
В списке чувствительности перечисляются все сигналы, от которых зависит процесс. При измени этих сигналов будет запускаться последовательный код процесса. Переменные, объявленные внутри процесса, являются локальными и не могут использоваться вне процесса. При использовании переменных генерируется комбинационная логика, а не триггеры.
Пример
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
entity main is
Port ( clk,reset : in STD_LOGIC;
a : in STD_LOGIC;
b : in STD_LOGIC;
y : out STD_LOGIC);
end main;
architecture Beh of main is
begin
process (clk)
variable tmp:std_logic;
begin
if reset='1' then
y<='0';
elsif clk'event and clk='1' then
tmp:=a and b;
y<=tmp;
end if;
end process;
end Beh;
Генерируемая схема состоит из триггера и логического элемента:
Если заменить переменную на сигнал и изменять значение сигнала внутри процесса по фронту сигнала, то в RTL схеме появиться еще одни триггер, вносящий задержку на один такт.
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
entity main is
Port ( clk,reset : in STD_LOGIC;
a : in STD_LOGIC;
b : in STD_LOGIC;
y : out STD_LOGIC);
end main;
architecture Beh of main is
signal tmp:std_logic;
begin
process (clk)
--variable tmp:std_logic;
begin
if reset='1' then
y<='0';
elsif clk'event and clk='1' then
tmp<=a and b;
y<=tmp;
end if;
end process;
end Beh;
Результат:
Доступ к общей шине из отдельных процессов. Реализации буфера с третьим состоянием на VHDL.
Вычислительная система может быть построена по архитектуре общей шины, когда различные модули поочередно будут устанавливать значения на шине.
Однако, напрямую управлять одной общей шиной из разных процессов запрещено, т.к. это приводит к ошибке типа:
Multi-source in Unit; this signal is connected to multiple drivers.
Ошибка вызвана попыткой подключить выходы двух вентилей к одному сигналу.
Для решения задачи можно использовать буферный элемент с третьим высокоимпедансным состоянием. При переходе буфера в третье состояние часть схемы отсоединяется от шины. Для присвоения сигналу значения, соответствующего третьему состоянию используется константа ‘Z’.
Пример реализации буфера с третьим состоянием
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
entity TrieState is
Port ( x : in STD_LOGIC_VECTOR (7 downto 0);
y : out STD_LOGIC_VECTOR (7 downto 0);
en : in STD_LOGIC);
end TrieState;
architecture Beh of TrieState is
begin
--y<= x when en='1' else "ZZZZZZZZ";
y<= x when en='1' else (others => 'Z') ; --более коротко
end Beh;
Пример: Пусть требуется выполнять над 4-х битными данными в зависимости от управляющего сигнала либо операцию сложения, либо операцию умножения.
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use ieee.std_logic_unsigned.all;
entity SumMul is
Port ( clk:std_logic;
a,b : in STD_LOGIC_VECTOR (3 downto 0);
op : in STD_LOGIC;
y : out STD_LOGIC_VECTOR (7 downto 0));
end SumMul;
architecture Beh of SumMul is
COMPONENT TrieState
PORT(
x : IN std_logic_vector(7 downto 0);
en : IN std_logic;
y : OUT std_logic_vector(7 downto 0)
);
END COMPONENT;
signal s1,s2:STD_LOGIC_VECTOR (7 downto 0);
begin
ts1:TrieState port map(x=>s1,en=>not op,y=>y);
ts2:TrieState port map(x=>s2,en=>op,y=>y);
process(clk)
begin
if clk'event and clk='1' then
s1(3 downto 0)<=a+b;
s1(7 downto 4)<= "0000";
end if;
end process;
process(clk)
begin
if clk'event and clk='1' then
s2<=a*b;
end if;
end process;
end Beh;
Полученная схема:
Формирование сигналов c заданными временными параметрами
Часто требуется сформировать периодические сигналы определенной частоты, при этом имеется тактовый генератор выдающий сигнал более высокой частоты.
Тактовый генератор выдает прямоугольный сигнал с постоянными периодом. Тактовый генератор нужен для обеспечения синхронной работы устройств цифровой схемы имеющих разное быстродействие.
Тактовые генераторы строятся на основе кварцевых резонаторов, имеющих высокую точность (как часы). Частота сигнала обычно от 32768кГц до 100MГц.
Если требуется получить больше частоты, то в вычислительное устройство добавляют блок ФАПЧ (блок фазовой автоподстройки частоты) в англоязычной литературе именуемый phase-locked loop PLL. Данный блок выступает как умножитель частоты сигнала, позволяющий из опорной частоты в 100 МГц получить частоты до нескольких ГГц.
Формирование сигнала заданной частоты основано на подсчете числа тактовых импульсов и при достижении заданного значения изменении выходного сигнала.
Пример 1:
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.std_logic_unsigned.all;
entity count is
generic(NCount:integer:=5);
Port ( clk : in STD_LOGIC; y : out STD_LOGIC:='0');
end count;
architecture Bhv of count is
signal s,flagOut:std_logic:='0';
begin
process(clk)
variable c:std_logic_vector(23 downto 0):=x"000000";
begin
if(clk'event and clk='1')
then
c:=c+1;
if(c=NCount) then
s<='1'; c:=x"000000";
else s<='0'; end if;
end if;
end process;
process(s)
begin
if(s'event and s='1')then
flagOut<=not flagOut;end if;
end process;
y<=flagOut;
end Bhv;
Результат
Пусть надо сформировать выходные символы с частотой 2 Гц
А тактовая частота = 40кГц
Tclk=1\40кГц=0.000025с.
Tout=1\2Гц=0.5c.
Ncount=Tout\Tclk\2=0.5\0.000025\2=10000