VHDL – zmienne i sygnały
Dariusz Badura
Instytut Informatyki
Zakład Modelowania i Grafiki
Komputerowej
Instrukcja przypisania
zmiennej
... modyfikuje wartość zmiennej poprzez przypisanie
do niej nowej wartości.
Wartość jest wyliczona z wyrażenia będącego po
prawej stronie instrukcji przypisania.
instrukcja_przypisania_zmiennej ::= [etykieta:] cel
przypisania := wyrażenie
Po lewej stronie instrukcji przypisania zmiennej
występuje tzw. cel przypisania, który musi być tego
samego typu co wyrażenie instrukcji przypisania
zmiennej.
Przykład
variable num_value : Integer;
..............................
A1: num_value := 0;
..............................
A2: num_value := num_value +1;
Instrukcja przypisania
zmiennej
Zgodnie z syntaktyką języka, cel przypisania
może być nazwą zmiennej lub typowym tylko
dla języka VHDL złożeniem kilku nazw, tzw.
agregatem.
Cel przypisania może mieć postać:
• prostej nazwy zmiennej
• zmiennej wybranej,
• zmiennej indeksowej lub
• zakresu zmiennej
Przykłady
Cel przypisania jako nazwa prosta:
variable x: real;
variable A,B : bit_vector (0 to 7);
X := 1000.0;
A := B;
A := „11001100”;
Cel przypisania w postaci zakresu zmiennej:
A (3 to 6) := (‘1’,’0’,’1’,’1’);
A (0 to 5) := B (2 to 7);
Przykłady
Cel przypisania jako nazwa indeksowana:
A (7) := ‘0’;
B (0) := A (6);
Cel przypisania jako nazwa wybrana:
type bit_vector is record
a : bit;
b : integer;
end record
variable C, D : bit_record;
C.a := ‘1’;
D.b := C.b;
Instrukcja przypisania
zmiennej
Gdy cel przypisania jest agregatem, typ tego
agregatu musi być typem złożonym , który da się
określić z kontekstu.
Każdy element agregatu musi być w postaci nazwy
lokalnie statycznej, która reprezentuje zmienną.
Przykład:
variable E : Bit;
variable I : Integer;
(E,I) := C;
Agregat
Elementy agregatu mogą mieć bardziej złożone
formy zapisu: zmiennej wybranej, zmiennej
indeksowej lub zakresu zmiennej.
Przykład:
...................................................................
(C.a, C.b) := D;
...................................................................
type Bit_vector_record is record
a : Bit_vector;
b : Integer;
end record;
variable G, H : Bit_vector_record;
(G.a(0 to 7), K) := H;
...................................................................
(G.a(0), K) := D;
Sygnały
• Sygnały w języku VHDL służą do
reprezentacji rzeczywistych połączeń
między elementami projektu.
• Odpowiadają połączeniom pojedynczym lub
magistralom.
• Z sygnałami związane są opóźnienie w
związku z propagacją sygnału oraz
zdolność tłumienia sygnałów o czasie
trwania krótszym od zadanego.
Sygnały
• Operatorem przypisania w stosunku do
sygnałów jest '<='. Przykładowo
instrukcja:
z <= a;
powoduje przypisanie do sygnału z wartości
sygnału a.
Automat
Mealy’ego
Detektor sekwencji (1011),
zrealizowany w postaci
Maszyny Mealy’ego.
library ieee;
use ieee.std_logic_1164.all;
entity myvhdl is
port (CLK, RST, X: in STD_LOGIC;
Z: out STD_LOGIC);
end;
architecture myvhdl_arch of myvhdl
is
-- SYMBOLIC ENCODED state machine:
Sreg0
type Sreg0_type is (S1, S2, S3, S4);
signal Sreg0: Sreg0_type;
begin
Automat
Mealy’ego
--concurrent signal assignments
Sreg0_machine: process (CLK)
begin
if CLK'event and CLK = '1' then
if RST='1' then
Sreg0 <= S1;
else
case Sreg0 is
when S1 =>
if X='0' then
Sreg0 <= S1;
elsif X='1' then
Sreg0 <= S2;
end if;
when S2 =>
if X='1' then
Sreg0 <= S2;
elsif X='0' then
Sreg0 <= S3;
end if;
when S3 =>
if X='1' then
Sreg0 <= S4;
elsif X='0' then
Sreg0 <= S1;
end if;
when S4 =>
if X='0' then
Sreg0 <= S3;
elsif X='1' then
Sreg0 <= S2;
end if;
when others =>
null;
end case;
end if;
end if;
end process;
Sekwencyjna instrukcja
przypisania sygnału
Przypisując wartość do sygnału można
określić uzależnienia czasowe związane z
taką operacją. Przypisania sygnałów mogą
posiadać zdefiniowane opóźnienia typu
inertial lub transport.
Dodatkowo opóźnienie typu inertial może
posiadać wyspecyfikowany parametr
reject.
Sekwencyjna instrukcja
przypisania sygnału
Podstawienie do zmiennej wykonywane jest
za pomocą operatora <=.
Instrukcja:
z <= a after 5 ns;
powoduje przypisanie wartości sygnału a do
sygnału z po 5 nanosekundach. Dodatkowo
impulsy o długości poniżej 5 nanosekund
pojawiające się w sygnale a nie powodują
zmian wartości sygnału z.
Instrukcja przypisania
sygnału
Podstawienie
z <= reject 3 ns inertial a after 5 ns;
wprowadza opóźnienie 5 nanosekund i
wycina impulsy o długości poniżej 3
nanosekund. Odpowiada to linii sygnałowej
o zadanym opóźnieniu i ograniczonym
paśmie.
Instrukcja przypisania
sygnału
Podstawienie
z <= transport a after 5 ns;
powoduje opóźnienie sygnału o 5
nanosekund. Dowolnie krótki impuls jest
przenoszony. Odpowiada to linii o
nieskończonym widmie i może np.
posłużyć do modelowania linii
opóźniających.
B_OUT <= transport B_IN after 1
ns
L_OUT <= inertial L_IN after 1 ns
Q_OUT <= reject 500 ps inertial Q_IN
after 1 ns
Instrukcja przypisania
sygnału
Podstawienie
z <= '1' after 3 ns, '0' after 7 ns, '1'
after 17 ns;
tworzy falę 1->0->1 zmieniającą
wartości w chwilach czasu 3 ns, 7 ns
oraz 17 ns.
Wszystkie podstawienia sygnałów
wewnątrz bloku Architecture
wykonywane są w sposób równoległy
Współbieżna instrukcja
przypisania sygnału
Warunkowe przypisanie
sygnału
cel_przypisania_signal <= expression when Boolean_condition else
expression when Boolean_condition else
expression when Boolean_condition else
expression when Boolean_condition else
......................................................................
:
expression;
Warunkowe przypisanie
sygnału
-- Instrukcje przypisania sygnałów wyjściom kombinacyjnym
Z_assignment:
Z <= '0' when (Sreg0 = S1 and X='0') else
'0' when (Sreg0 = S1 and X='1') else
'0' when (Sreg0 = S2 and X='1') else
'0' when (Sreg0 = S2 and X='0') else
'0' when (Sreg0 = S3 and X='1') else
'0' when (Sreg0 = S3 and X='0') else
'0' when (Sreg0 = S4 and X='0') else
'1' when (Sreg0 = S4 and X='1') else
'1';
end myvhdl_arch;
Przykład multipleksera...
...4-to-1 multipleksera
entity MUX_4_1_Conc is
port (S1, S0, A, B, C, D: in std_logic;
Z: out std_logic);
end MUX_4_1_Conc;
architecture concurr_MUX41 of MUX_4_1_Conc is
begin
Z <=
A when S1=’0’ and S0=’0’ else
B when S1=’0’ and S0=’1’ else
C when S1=’1’ and S0=’0’ else
D;
end concurr_MUX41;
Przykład multipleksera...
... w bardziej skondensowanej formie:
entity MUX_4_1_funcTab is
port (A, B, C, D: in std_logic;
SEL: in std_logic_vector (1 downto 0);
Z: out std_logic);
end MUX_4_1_ funcTab;
architecture concurr_MUX41 of MUX_4_1_funcTab is
begin
Z <= A when SEL = ”00” else
B when SEL = ”01” else
C when SEL = “10” else
D;
end concurr_MUX41;
Selektywne przypisanie
sygnału
with wyrażenie_wyboru select
nazwa_celu <= wyrażenie when wybór,
nazwa_celu <= wyrażenie when wybór,
:
nazwa_celu <= wyrażenie when wybór;
Przykład
target <= value1 when “000”,
value2 when “001” | “011” | “101” ,
value3 when others;
Przykład ...
entity MUX_4_1_Conc2 is
port (A, B, C, D: in std_logic;
SEL: in std_logic_vector(1 downto 0);
Z: out std_logic);
end MUX_4_1_Conc2;
architecture concurr_MUX41b of MUX_4_1_Conc2 is
begin
with SEL select
Z <= A when “00”,
B when “01”,
C when “10”,
D when “11”;
end concurr_MUX41b;
Przykład sumatora
entity FullAdd_Conc is
port (A, B, C: in std_logic;
sum, cout: out std_logic);
end FullAdd_Conc;
architecture FullAdd_Conc of FullAdd_Conc is
--define internal signal: vector INS of the
input signals
signal INS: std_logic_vector (2 downto 0);
begin
--define the components of vector INS of the input
signals
INS(2) <= A;
INS(1) <= B;
INS(0) <= C;
.....................
.....................
end FullAdd_Conc;
Przykład sumatora c.d.
with INS select
(sum, cout) <= std_logic_vector’(“00”) when “000”,
std_logic_vector’(“10”) when “001”,
std_logic_vector’(“10”) when “010”,
std_logic_vector’(“01”) when “011”,
std_logic_vector’(“10”) when “100”,
std_logic_vector’(“01”) when “101”,
std_logic_vector’(“01”) when “110”,
std_logic_vector’(“11”) when “111”,
std_logic_vector’(“11”) when others;
end FullAdd_Conc;
Procedury i funkcje
Język VHDL umożliwia definicję zarówno funkcji jak
i procedur, które ogólnie zwane są podprogramami.
Przykładem działania funkcji jest transkodowanie,
czyli zmiana zapisu liczby w jednym kodzie na inny.
....................................................................
function Transcod(value: in bit_vector(0 to 7))
return bit_vector is
begin
case Value is
when "00000000" => return "01010101";
when "01010101" => return "00000000";
when others => return "11111111";
end case;
end Transcod;
Procedury i funkcje c.d.
Taka sama operacja może zostać zrealizowana
za pomocą procedury.
.............................................................................
..............
procedure Transcoder_1 (variable value: inout bit_vector
(0 to 7)) is
begin
case Value is
when "00000000" => Value:="01010101";
when "01010101" => Value:="00000000";
when others => Value:="11111111";
end case;
end procedure Transcoder_1;
Procedury i funkcje c.d.
•
Różnica polega na zwracane wartości:
procedura nie zwraca żadnej wartości i w
związku z tym nie może zostać użyta np. w
instrukcjach przypisania podczas gdy funkcja
zwraca wartość określonego typu.
•
Ewentualne wartości modyfikowane przez
procedurę muszą zostać zadeklarowane na
jej liście argumentów jako wyjściowe lub
wejściowo/wyjściowe (out lub inout).