
Подпрограммы и пакеты vhdl
Для повторного использования кода следует создать пакет, в который можно поместить определение типа, константы и подпрограммы. Пользовательские пакеты добавляются в подключенную по умолчанию библиотеку work.
Подпрограммы могут быть оформлены в виде функции или процедуры.
Функция имеет только входные параметры и может содержать только последовательные операторы, таким образом код функции реализуется в виде комбинационной логики. В функции допустимо объявление переменной при помощи ключевого слова variable. Объявление внутри функции сигнала запрещено.
Процедура может иметь несколько как входных, так и выходных параметров. Тело процедуры допускает использование параллельных операторов. Аналогом процедуры в языке Verilog является Task (задача).
Описание пакета
library IEEE;
use IEEE.STD_LOGIC_1164.all;
package p1 is
function LedSwitch (x:std_logic) return std_logic;
end p1;
package body p1 is
function LedSwitch (x:std_logic) return std_logic is
variable tmp:std_logic:='0';
begin
tmp:=not x;
return tmp;
end;
end p1;
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use work.p1.all;
entity Main is
Port ( A : in STD_LOGIC; led : out STD_LOGIC);
end Main;
architecture Behavioral of Main is
begin
led<=LedSwitch(A);
end Behavioral;
Кроме пакета, подпрограммы могут быть добавлены в блок архитектуры или процесс.
Реализация конечного автомата на vhdl
Конечный автомат - это модель, описывающая поведение объекта конечным набором состояний и переходами между ними.
Введем определения:
R={;-
множество (алфавит) внутренних состояний.
Q={};
- входной алфавит.
W={};-выходной алфавит.
Функционирование автомата: в дискретные моменты времени, с входа автомата считывается один из элементов множества Q, и на выходе появляется выходной сигнал из множества W. Одновременно автомат из одного состояния, например r1, можете переключиться в другое состояние, например r3.
Различают конечный автомат Мура и конечный автомат Мили. В конечном автомате Мура выходные значение зависит только внутреннего состояния автомата, а в конечном автомате Мили как от состояния, так и от входных значений.
Для описания автомата можно
ввести функцию переходов
и функцию выходов
.
Для автомата Мура:
Для автомата Мили:
Конечный автомат можно также описать при помощи направленного графа или таблицы.
Пример:
Пусть требуется реализовать автомат Мура, заданный таблицей состояний:
Входные сигналы |
Состояния | ||
R1 |
R2 |
R3 | |
Q1 |
R1/w3 |
R3/w1 |
R1/w2 |
Q2 |
R3/w3 |
R2/w1 |
R3/w2 |
Q3 |
R2/w3 |
R2/w1 |
R2/w2 |
Для кодирования состояния в VHDL удобно использовать пользовательский тип данных, который объявляется при помощи ключевого слова type перед begin в блоке архитектуры.
type stateType is (r1,r2,r3);
Для входного и выходного портов будем использовать шину размеров 2 бита, т.к. такая шина позволяет представить входной и выходной алфавит.
Пусть для кодировки входного и выходного алфавита приняты следующие значения:
q1 = 01 q2 =10 q3= 11
w1=01 w2=10 w3=11
В общем случае, код описания конечного автомата будет состоять из 4-х блоков:
Описание портов и типов данных.
Процесса, формирующего переход к очередному состоянию автомата в момент времени прихода переднего фронта тактирующего сигнала
Процесса, зависящего от текущего состояния и входного сигнала, задающего в какое именно состояние следует перейти
Комбинаторной логики формирования выходного сигнала, в зависимости от текущего состояния.
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
entity FSM_Moor is
Port ( q : in STD_LOGIC_VECTOR (1 downto 0);
clk,reset:in STD_LOGIC;
w : out STD_LOGIC_VECTOR (1 downto 0));
end FSM_Moor;
architecture Bhv of FSM_Moor is
type stateType is (r1,r2,r3);
signal state,nxState:stateType;
begin
-- обработка тактового импульса и определение очередного состояния автомата
process (clk, reset) begin
if reset = '1' then state <= r1;
elsif clk'event and clk = '1' then
state <= nxState;
end if;
end process;
--логика определения последующего состояния автомата
process (state, q)
begin
case state is
when r1 => if q = "01" then nxState<=r1;
elsif q="10" then nxState<=r3;
elsif q="11" then nxState<=r2;
end if;
when r2 => if q = "01" then nxState<=r3;
elsif q="10" then nxState<=r2;
elsif q="11" then nxState<=r2;
end if;
when r3 => if q = "01" then nxState<=r1;
elsif q="10" then nxState<=r3;
elsif q="11" then nxState<=r2;
end if;
when others => nxState<=r1;
end case;
end process;
--логика формирования выходных значений
with state select
w<= "11" when r1,
"01" when r2,
"10" when r3;
end Bhv;
Для тестирования автомата добавим в проект тестирующий модуль:
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
entity test is
end test;
architecture Behavioral of test is
signal CLK,reset:std_logic;
signal q,w : STD_LOGIC_VECTOR (1 downto 0);
component FSM_Moor
Port ( q : in STD_LOGIC_VECTOR (1 downto 0);
clk,reset:in STD_LOGIC;
w : out STD_LOGIC_VECTOR (1 downto 0));
end component;
constant PERIOD:time:=100 ns;
begin
uut:FSM_Moor PORT MAP(q=>q,clk=>clk,reset=>reset,w=>w);
process
begin
CLK <= '0';
wait for PERIOD/2;
CLK <= '1';
wait for PERIOD/2;
end process;
process
begin
q<="01";
reset<='0';
wait for 100 ns;
reset<='1';
wait for 100 ns;
reset<='0';
wait for 100 ns;
q<="01";
wait for 100 ns;
q<="11";
wait for 100 ns;
q<="10";
wait for 100 ns;
q<="01";
wait for 100 ns;
q<="10";
wait for 100 ns;
q<="11";
wait;
end process;
end Behavioral;
Временная диаграмма работы автомата:
Синтезированная RTL схема:
В конечном автомате Мили в логике формирования выходных сигналов появятся дополнительные условия, выполнение которых будет зависеть как от внутреннего состояния, так и от входных сигналов.
Пример: (Поменяем в предыдущем примере R1Q2=>R3/w2
Входные сигналы |
Состояния | ||
R1 |
R2 |
R3 | |
Q1 |
R1/w3 |
R3/w1 |
R1/w2 |
Q2 |
R3/w2 |
R2/w1 |
R3/w2 |
Q3 |
R2/w3 |
R2/w1 |
R2/w2 |
В результате логика формирования выходного сигнала примет вид:
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
entity FSM_Mili is
Port ( q : in STD_LOGIC_VECTOR (1 downto 0);
clk,reset:in STD_LOGIC;
w : out STD_LOGIC_VECTOR (1 downto 0));
end FSM_Mili;
architecture Bhv of FSM_Mili is
type stateType is (r1,r2,r3);
signal state,nxState:stateType;
begin
-- обработка тактового импульса
process (clk, reset) begin
if reset = '1' then state <= r1;
elsif clk'event and clk = '1' then
state <= nxState;
end if;
end process;
--логика определения последующего состояния автомата
process (state, q)
begin
case state is
when r1 => if q = "01" then nxState<=r1;
elsif q="10" then nxState<=r3;
elsif q="11" then nxState<=r2;
end if;
when r2 => if q = "01" then nxState<=r3;
elsif q="10" then nxState<=r2;
elsif q="11" then nxState<=r2;
end if;
when r3 => if q = "01" then nxState<=r1;
elsif q="10" then nxState<=r3;
elsif q="11" then nxState<=r2;
end if;
when others => nxState<=r1;
end case;
end process;
--логика формирования выходных значений
w<= "10" when (state=r1 and q="10") else
"01" when (state=r2) else
"10" when (state=r3) else
"11" when (state=r1) else
"00";
end Bhv;