V jeziku VHDL lahko opisujemo vezje na ravni obnašanja (angl. behavior), kjer nam za opis vezja ni potrebno poznati strukture vezja. Obnašanje vezja določa algoritem v obliki zaporedja stavkov, ki so podobni stavkom običajnih programskih jezikov (npr. if, case...). Opis obnašanja vezja je podoben programiranju v običajnih programskih jezikih. Zaporedne stavke pišemo v jeziku VHDL znotraj posebnega okolja (npr. procesa ali procedure...), ki omogoča prirejanje vrednosti ali izraza nekemu signalu na več mestih. V takšnem primeru je vrstni red zapisa stavkov pomemben in izvede se zadnja prireditev. Spoznali bomo procese s katerimi opisujemo:
Znotraj procesa lahko opisujemo obnašanje kombinacijskih vezij s pogojnimi (if) stavki in prireditvenimi stavki. V pogojnem stavku za besedo then zapišemo stavke, ki se izvršijo, ko je pogoj izpolnjen, za else pa stavke, ki se izvršijo ob neizpolnjenem pogoju. Pogojni stavek zaključimo z end if.
if pogoj then zaporedni stavki; else zaporedni stavki; end if; |
if pogoj1 then zaporedni stavki; elsif pogoj2 then zaporedni stavki; ... else zaporedni stavki; end if; |
Kadar imamo več zaporednih (povezanih) pogojev, jih zapišemo z
if...elsif...else obliko pogojnega stavka. V takšnam stavku imajo pogoji,
ki so zapisani prej, prednost pred tistimi, ki so zapisani kasneje.
Stavek else lahko tudi izpustimo, vendar moramo v primeru opisa
kombinacijskih vezij poskrbeti, da bodo izhodi definirani pri vseh kombinacijah
na vhodih. V praksi to naredimo tako, da signalu priredimo privzeto vrednost
pred if stavkom.
Proces je okolje, ki vsebuje zaporedje stavkov, zapisanih med rezerviranima besedama begin in end process. Opis procesa se začne z oznako, sledi ji rezervirana beseda process in v oklepaju seznam vhodnih signalov. Simulator izvede stavke v procesnem okolju vsakokrat, ko se spremeni vrednost kateregakoli signala iz seznama signalov, na katere je občutljiv.
Poglejmo si primer dveh pravilnih in enega napačnega opisa kombinacijskega vezja, ki določa odprtost ventila ('1' ali '0') glede na stanje pretoka, s signalom stop pa v vsakem primeru postavimo ventil na '0'. Vrednost na signalu ventil se lahko spremeni, če se spremeni eden od signalov pretok ali stop, zato ta dva signala navedemo v seznam pri procesu. V prvih dveh primerih (p1 in p2) je signal ventil definiran pri vseh vhodnih kombinacijah. Tretji proces pa ne določa vrednosti signala ventil kadar nobeden izmed pogojev ni izpolnjen. V tem primeru mora signal ventil ohranjati zadnjo vrednost, zato proces p3 ne predstavlja kombinacijsko vezje!
Pravilno | Pravilno | Napačno |
---|---|---|
p1: process (pretok, stop) begin if pretok > 10 then ventil <= '1'; else ventil <= '0'; end if; if stop='1' then ventil <= '0'; end if; end process; |
p2: process (pretok, stop) begin ventil <= '0'; if pretok > 10 then ventil <= '1'; end if; if stop='1' then ventil <= '0'; end if; end process; |
p3: process (pretok, stop) begin if pretok > 10 then ventil <= '1'; end if; if stop='1' then ventil <= '0'; end if; end process; |
Pogledali si bomo načrtovanje sinhronih sekvenčnih vezij, ki preklapljajo izhode ob fronti urinega signala. Sinhrona sekvenčna vezja opišemo s sinhronim procesom. Proces je struktura v kateri lahko uporabljamo sekvenčne stavke: prireditveni stavek, pogojni stavek..., pri katerih je vrstni red v določenih primerih pomemben (npr. med več prireditvami istemu signalu se izvede le zadnja). Pri opisu sinhronih sekvenčnih vezij zapišemo vse stavke znotraj pogoja za fronto ure rising_edge(clk) ali falling_edge(clk).
Sinhroni proces I je struktura, ki jo bomo uporabljali za opis sinhronih sekvenčnih vezij. Kadar uporabljamo v opisu digitalnih sistemov več procesov, moramo vsakemu procesu prirediti svojo unikatno oznako. Simulacija sinhronega procesa naj se izvrši le ob spremembi ure (signala clk), ki jo navedemo v oklepaju za rezervirano besedo process.
Flip-flop |
Osnovni gradnik sinhronih vezij je D flip-flop. Flip flop ali register, ki ob fronti ure prenese na izhod vrednost iz vhoda opišemo s preprostim prireditvenim stavkom znotraj sinhronega procesa.
library IEEE;
use IEEE.std_logic_1164.all;
entity dff is
port ( vhod: in std_logic;
clk: in std_logic;
izhod: out std_logic );
end dff;
architecture opis of dff is
begin
p: process (clk)
begin
if rising_edge(clk) then
izhod <= vhod;
end if;
end process;
end opis;
Flip-flopi in registri imajo pogosto tudi reset vhod, s katerim postavimo izhod na vrednost 0. Vhod za resetiranje je lahko asinhroni (izhod se postavi na 0 takoj ob prisotnosti reset signala) ali pa sinhroni (izhod se postavi na 0 ob prisotnosti reset signala in prvi fronti urinega signala). Sekvenčne gradnike z asinhronim reset signalom opišemo znotraj strukture sinhroni proces II.
Arhitektura DFF z asinhronim resetom | Arhitektura DFF s sinhronim resetom |
---|---|
architecture opis2 of dff is begin p: process (clk, reset) begin if reset='1' then izhod <= '0'; elsif rising_edge(clk) then izhod <= vhod; end if; end process; end opis2; |
architecture opis3 of dff is begin p: process (clk) begin if rising_edge(clk) then if reset='1' then izhod <= '0'; else izhod <= vhod; end if; end if; end process; end opis3; |
Pri flip-flopu z asinhronim reset signalom moramo dati reset v seznam signalov, na katere je procesni stavek občutljiv. Asinhroni reset ima prednost pred uro, zato ga zapišemo kot prvi pogoj v pogojnem stavku.
Register |
Registre opišemo z enakimi strukturami kot flip-flope, le da uporabimo za signala vhod in izhod vektorski podatkovni tip. Poznamo registre brez reseta, registre z asinhronim in registre s sinhronim reset signalom. Registri imajo pogosto tudi dodaten vhod (angl. CE - clock enable) za omogočanje vpisa podatka.
library IEEE;
use IEEE.std_logic_1164.all;
entity reg8 is
port ( d: in std_logic_vector(7 downto 0);
clk: in std_logic;
ce: in std_logic;
q: out std_logic_vector(7 downto 0) );
end reg8;
architecture opis of reg8 is
begin
p: process (clk)
begin
if rising_edge(clk) then
if ce='1' then
q <= d;
end if;
end if;
end process;
end opis;
Sinhrona sekvenčna vezja imajo pogosto vgrajeno povratno zanko med izhodom iz registra in njegovim vhodom. Povratna zanka omogoča opis vezij, pri katerih je naslednje stanje odvisno od vhodov in trenutnega stanja.
Števec |
Dvojiški števec dobimo tako, da izhod iz registra ob vsakem urinem impulzu povečamo za 1. Deklarirali bomo notranji vektor st in mu določili začetno stanje ("0000") od katerega naprej bo začel šteti. Podatkovni tip vektorja naj bo unsigned, ker ima v knjižnici IEEE.numeric_std definirano operacijo seštevanja, ki jo uporabimo za prištevanje enice.
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.numeric_std.all;
entity stevec is
port ( clk: in std_logic;
ce: in std_logic;
izhod: out std_logic_vector(3 downto 0) );
end stevec;
architecture opis of stevec is
signal st: unsigned(3 downto 0) := "0000";
begin
p: process (clk)
begin
if rising_edge(clk) then
if ce='1' then
st <= st + 1;
end if;
end if;
end process;
izhod <= std_logic_vector(st);
end opis;
Opis števca je narejen s strukturo sinhroni proces I, kjer smo prištevanje vrednosti zapisali znotraj dodatnega pogoja za omogočanje štetja (signal ce, angl. count enable).
Avtomat |
Delovanje sekvenčnega avtomata predstavimo z diagramom prehajanja stanj. Poglejmo si avtomat za detekcijo pritiska tipke.Ob pritisku na tipko, gre avtomat iz mirovnega stanja v stanje impulz, ob naslednjem urinem ciklu pa v stanje čakaj, kjer ostane tako dolgo, dokler je tipka pritisnjena. Avtomat v stanju impulz generira izhodni signal, ki je dolg natanko eno urino periodo.
Za zapis stanj avtomata v jeziku VHDL definiramo nov podatkovni tip, v katerem naštejemo vsa možna stanja.
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.std_logic_unsigned.all;
entity avtomat is
port ( clk: in std_logic;
tipka: in std_logic;
izhod: out std_logic );
end avtomat;
architecture opis of avtomat is
type vsa_stanja is (mir, impulz, cakaj);
signal stanje: vsa_stanja;
begin
sekv: process (clk)
begin
if rising_edge(clk) then
case stanje is
when mir =>
if tipka='1' then
stanje <= impulz;
end if;
when impulz =>
stanje <= cakaj;
when others =>
if tipka='0' then
stanje <= mir;
end if;
end case;
end if;
end process;
komb: process (stanje)
begin
if stanje=impulz then
izhod <= '1';
else
izhod <= '0';
end if;
end process;
end opis;
Osnovni stavki | Strukturni opis |