Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

Lek2013 / Lek7_FPGA

.docx
Скачиваний:
49
Добавлен:
31.05.2015
Размер:
307.38 Кб
Скачать

Классификация операторов и общая структура программы

Все операторы vhdl делятся на две большие группы

Параллельные

Последовательные

Параллельные операторы могут присутствовать как в процессах и подпрограммах, так и в блоке architecture. Последовательные операторы присутствуют только в процессах и подпрограммах.

Также различают синтезируемые операторы, которые могут быть отражены на получаемой цифровой схеме, и не синтезируемые, применяемые в тестовых модулях.

В общем случае описание модуля на vhdl выглядит следующим образом:

library IEEE;

use ***************************** -- пакеты

Entity --описание интерфейса

Architecture – архитектура

Component --входящие компоненты

Signal --сигналы для связи компонент

Function, procedure --подпрограммы

Begin --начало описания архитектуры

********************************************--параллельные операторы

P1:process

Variable -- объявление локальных переменных

Begin

***********************************--Последовательные операторы

End process;

P2:process

Variable -- объявление локальных переменных

Begin

***********************************--Последовательные операторы

End process;

END ;

Последовательные операторы

Последовательные операторы могут появляться только внутри оператора процесса или внутри подпрограмм. Порядок появления последовательных операторов имеет значение. При помощи последовательных операторов описывают цифровую схему в поведенческом стиле.

К последовательным операторам относятся

  • If

  • Case

  • Loop

  • Next

  • Exit

  • Null

  • () вызов подпрограммы

  • Return

  • Assert (сообщение)

  • Wait

  • := (присваивание значение переменной)

Оператор if

Общий вид данного оператора

If условие then

оператор

[elseif условие then Оператор]

[else Оператор]

End if;

Рассмотрим работу оператора if на примере счетчика. Счетчик –это элемент цифровой схемы, задача которого подсчитывать число импульсов на входе и выдавать в двоичном виде на выходной шине их число. Счетчик дополнительно имеет вход сброса и вход разрешения подсчета импульсов.

Пример описания счетчика на VHDL:

library IEEE; use IEEE.STD_LOGIC_1164.ALL;

use IEEE.STD_LOGIC_UNSIGNED.ALL; -- библиотека для арифметики

entity counter is

Port ( clk, reset, EN : in STD_LOGIC;

q : inout STD_LOGIC_vector(7 downto 0));

end counter;

architecture Beh of counter is

begin

process (clk,reset)

begin

if(reset='1')then q<=x"00";

elsif (clk' event and clk='1' and en='1') then

q<=q +1;

end if;

end process;

end Beh;

В результате синтезируется схема, состоящая из 8 последовательно включенных триггеров. Сброс по команде reset выполняется асинхронно т.к. не зависит от входного тактирующего сигнала.

Замечание: если оператор if пометить вне оператора процесса то будет ошибка компиляции.

Схема асинхронного счетчика на 4 разряда:

Замечание по схеме: если на вход следующего триггера брать данные не с инверсного, а с прямого выхода, то получится реверсивный счетчик уменьшающий значения.

Оператор ASSERT

Позволяет выдать сообщение в программе моделирования (ISim) при выполнении заданного условия. Сообщение выдается когда условия в скобках ЛОЖНО!.

Пример

assert (not(B='1' and B'event) ) report "pushb=1" severity Warning;

здесь сообщение появиться только при положительном фронте сигнала.

вместо Warning, может стоять слово Error, тогда при выполнении условия будет генерироваться не предупреждение, а ошибка

Оператор ASSERT не синтезируемый и в результирующем RTL представлении программы он не присутствует. Не синтезируемые операторы используются в тестовых модулях.

Если требуется отобразить в программе отладки тестовую информацию то можно использовать оператор report.

Пример:

USE ieee.numeric_std.ALL;

………………………………………………………………………………………

q:inout STD_LOGIC_VECTOR(7 downto 0)

…………………………………………………………………………………….

report "q=" & integer'image(to_integer(unsigned(q)));

оператор Wait

Данный оператор приостанавливает процесс или подпрограмму до выполнения условия.

Wait on A,B

Wait until (C=0);

Wait for 50 ns;

Данный оператор как и оператор ASSERT не синтезируемый и применяется в модулях моделирования, чтобы дать возможность параллельным процессам изменить выходные значения.

Тестовые модули

На этапе оптимизации кода и рефакторинга важно периодически проверять правильность работы модуля. Для осуществления автоматической проверки в проект добавляют тестирующий модуль, задачей которого является формирование тестового воздействия, а также классификация полученного ответа как правильного или ложного. Дополнительно, тестовый модуль формирует временную диаграмму, что помогает при отладке системы.

Особенностью любого тестирующего модуля является пустой блок entity, т.к. его задача самому генерировать воздействующий сигнал для тестируемого модуля.

Пример: Тестируемый модуль

library IEEE;

use IEEE.STD_LOGIC_1164.ALL;

entity m1 is

Port ( a,b : in STD_LOGIC;

x,y : out STD_LOGIC);

end m1;

architecture Bhv of m1 is

begin

x<=a or b; y<=a and b;

end Bhv;

Для добавления тестового модуля следует выбрать пункт New Source -> VHDL Test Bench –> далее ввести имя модуля

Сообщения оператора Assert можно посмотреть с симуляторе (ISim) если выбрать в меню View->Panels->Console.

Тестирующий модуль:

LIBRARY ieee;

USE ieee.std_logic_1164.ALL;

ENTITY test IS

END test;

ARCHITECTURE behavior OF test IS

COMPONENT m1

PORT(a,b : IN std_logic;

x,y : OUT std_logic );

END COMPONENT;

signal a,b,x,y : std_logic;

BEGIN

uut: m1 PORT MAP ( a => a, b => b, x => x, y => y );

process

begin

a<='0'; b<='0';

wait for 100 ns;

assert (y='0' and x='0') report " a=0 b=0 not valid " severity Error;

a<='1'; b<='0';

wait for 100 ns;

assert (y='0' and x='1') report " a=1 b=0 not valid " severity Error;

a<='0'; b<='1';

wait for 100 ns;

assert (y='0' and x='1') report " a=0 b=1 not valid " severity Error;

a<='1'; b<='1';

wait for 100 ns;

assert (y='1' and x='1') report " a=1 b=1 not valid " severity Error;

wait;

end process;

END;

Пример 2. Пусть нужно написать тестовый модель для счетчика со входом синхронизации clk ( рассмотренного выше).

Тестовый модуль будет состоять из двух процессов: первый процесс формирует периодический сигнал, моделирующий работу тактового генератора, а второй процесс формирует управляющее воздействие от периферийных устройств (например, кнопок управления прибором).

Пример тестируемого модуля:

library IEEE;

use IEEE.STD_LOGIC_1164.ALL;

use IEEE.STD_LOGIC_UNSIGNED.ALL;

USE ieee.numeric_std.ALL;

entity ST is

Port ( clk,reset,en : in STD_LOGIC;

q:inout STD_LOGIC_VECTOR(7 downto 0)

);

end ST;

architecture Behavioral of ST is

begin

process(clk,reset)

begin

if(reset='1') then

q<=x"00";

elsif clk'event and clk='1' and en='1' then

q<=q+1;

assert q<x"10" report "big value" severity Error;

report "q=" & integer'image(to_integer(unsigned(q)));

end if;

end process;

end Behavioral;

Пример тестирующего модуля:

LIBRARY ieee;

USE ieee.std_logic_1164.ALL;

ENTITY Test IS END Test;

ARCHITECTURE behavior OF Test IS

COMPONENT counter

PORT( clk,reset,EN : IN std_logic;

q : INOUT std_logic_vector(7 downto 0) );

END COMPONENT;

signal clk : std_logic := '0';

signal reset : std_logic := '0';

signal EN : std_logic := '0';

signal q : std_logic_vector(7 downto 0);

constant clk_period : time := 100 ns; -- 10MHz

BEGIN

uut: counter PORT MAP (clk => clk,reset => reset,EN => EN,q => q);

clk_process :process

begin

clk <= '0';

wait for clk_period/2;

clk <= '1';

wait for clk_period/2;

end process;

stim_proc: process

begin

reset<='1';

wait for 100 ns;

reset<='0';

-- wait for 200 ns; --задержка перед включением счета

en<='1';

wait for clk_period*5;

reset<='1';

wait for 100 ns;

reset<='0';

wait;

end process;

END;

Оператор :=

Это оператор присваивания. В отличие от операторов присваивания <= может применяться только к переменным, а не к сигналам.

Переменная объявляется внутри процесса или подпрограммы при помощи ключевого слова Variable.

При присваивании переменной внутри процесса ее значение меняется немедленно, а при присваивании сигналу значение поменяется только после приостановки процесса после возникновения события (например, прихода следующего тактового импульса).

Последовательные операторы LOOP,Next, Exit

Оператор LOOP аналогичен оператору for в С++

Оператор next- continue C++

Exit эквивалентен break в языке C++

Пример использования цикла. Пусть надо посчитать сумму элементов в массиве (ответ sum=5):

library IEEE;

use IEEE.STD_LOGIC_1164.ALL;

use ieee.std_logic_unsigned.all;

entity Main is

Port ( clk: in STD_LOGIC;

sum : out STD_LOGIC_VECTOR (7 downto 0));

end Main;

architecture Beh of Main is

TYPE ArrayType is ARRAY (0 to 7) of std_logic_vector(3 downto 0);

signal mem:ArrayType:=(x"1",x"2",x"3",x"1",x"6",x"1",x"7",x"1");

signal i:std_logic_vector(2 downto 0):="000";

begin

process(clk)

variable tmp:STD_LOGIC_VECTOR (7 downto 0);

begin

if clk'event and clk='1' then

tmp:=x"00";

for i in 0 to 7 loop

exit when mem(i)=x"7";

next when mem(i)>x"2";

tmp:=tmp+mem(i);

end loop; end if;

sum<=tmp;

end process;

end ;

12

Соседние файлы в папке Lek2013