vhdl
D-Flip-Flops (DFF) i zatrzaski
Szukaj…
Uwagi
D-Flip-Flops (DFF) i zatrzaski są elementami pamięci. DFF próbkuje dane wejściowe na jednej lub drugiej krawędzi swojego zegara (nie na obu), podczas gdy zatrzask jest przezroczysty na jednym poziomie jego aktywacji i zapamiętywany na drugim. Poniższy rysunek ilustruje różnicę:
Modelowanie DFF lub zatrzasków w VHDL jest łatwe, ale należy wziąć pod uwagę kilka ważnych aspektów:
Różnice między modelami DFF i zatrzasków VHDL.
Jak opisać krawędzie sygnału.
Jak opisać synchroniczny lub asynchroniczny zestaw lub resety.
Klapki D (DFF)
We wszystkich przykładach:
-
clk
to zegar, -
d
jest wejściem, -
q
jest wyjściem, -
srst
to aktywny reset synchroniczny wysokiego poziomu, -
srstn
to aktywny niski synchroniczny reset, -
arst
to aktywny wysoki asynchroniczny reset, -
arstn
to aktywny niski asynchroniczny reset, -
sset
jest aktywnym zestawem wysokiej synchronizacji, -
ssetn
to aktywny niski zestaw synchroniczny, -
aset
to aktywny wysoki zestaw asynchroniczny, -
asetn
jest aktywnym niskim zestawem asynchronicznym
Wszystkie sygnały są typu ieee.std_logic_1164.std_ulogic
. Zastosowana składnia prowadzi do poprawnych wyników syntezy we wszystkich syntezatorach logicznych. Zobacz przykład wykrywania krawędzi zegara, aby uzyskać dyskusję na temat alternatywnej składni.
Zegar wschodzącej krawędzi
process(clk)
begin
if rising_edge(clk) then
q <= d;
end if;
end process;
Falling edge clock
process(clk)
begin
if falling_edge(clk) then
q <= d;
end if;
end process;
Zegar narastający, synchroniczny aktywny wysoki reset
process(clk)
begin
if rising_edge(clk) then
if srst = '1' then
q <= '0';
else
q <= d;
end if;
end if;
end process;
Zegar narastający, asynchroniczny aktywny wysoki reset
process(clk, arst)
begin
if arst = '1' then
q <= '0';
elsif rising_edge(clk) then
q <= d;
end if;
end process;
Zegar opadającego zbocza, asynchroniczny aktywny niski reset, wysoki synchroniczny aktywny wysoki
process(clk, arstn)
begin
if arstn = '0' then
q <= '0';
elsif falling_edge(clk) then
if sset = '1' then
q <= '1';
else
q <= d;
end if;
end if;
end process;
Zegar narastającego zbocza, asynchroniczny aktywny wysoki reset, asynchroniczny aktywny niski poziom
Uwaga: zestaw ma wyższy priorytet niż reset
process(clk, arst, asetn)
begin
if asetn = '0' then
q <= '1';
elsif arst = '1' then
q <= '0';
elsif rising_edge(clk) then
q <= d;
end if;
end process;
Zatrzaski
We wszystkich przykładach:
-
en
jest sygnałem zezwolenia, -
d
jest wejściem, -
q
jest wyjściem, -
srst
to aktywny reset synchroniczny wysokiego poziomu, -
srstn
to aktywny niski synchroniczny reset, -
arst
to aktywny wysoki asynchroniczny reset, -
arstn
to aktywny niski asynchroniczny reset, -
sset
jest aktywnym zestawem wysokiej synchronizacji, -
ssetn
to aktywny niski zestaw synchroniczny, -
aset
to aktywny wysoki zestaw asynchroniczny, -
asetn
jest aktywnym niskim zestawem asynchronicznym
Wszystkie sygnały są typu ieee.std_logic_1164.std_ulogic
. Zastosowana składnia prowadzi do poprawnych wyników syntezy we wszystkich syntezatorach logicznych. Zobacz przykład wykrywania krawędzi zegara, aby uzyskać dyskusję na temat alternatywnej składni.
Aktywne wysokie zezwolenie
process(en, d)
begin
if en = '1' then
q <= d;
end if;
end process;
Aktywne niskie zezwolenie
process(en, d)
begin
if en = '0' then
q <= d;
end if;
end process;
Aktywne wysokie zezwolenie, synchroniczny aktywny wysoki reset
process(en, d)
begin
if en = '1' then
if srst = '1' then
q <= '0';
else
q <= d;
end if;
end if;
end process;
Aktywne wysokie zezwolenie, asynchroniczny aktywny wysoki reset
process(en, d, arst)
begin
if arst = '1' then
q <= '0';
elsif en = '1' then
q <= d;
end if;
end process;
Aktywne niskie zezwolenie, asynchroniczne aktywne zerowanie niskie, synchroniczne aktywne wysokie ustawienie
process(en, d, arstn)
begin
if arstn = '0' then
q <= '0';
elsif en = '0' then
if sset = '1' then
q <= '1';
else
q <= d;
end if;
end if;
end process;
Aktywne wysokie zezwolenie, asynchroniczny aktywny wysoki reset, asynchroniczny aktywny niski poziom
Uwaga: zestaw ma wyższy priorytet niż reset
process(en, d, arst, asetn)
begin
if asetn = '0' then
q <= '1';
elsif arst = '1' then
q <= '0';
elsif en = '1' then
q <= d;
end if;
end process;
Wykrywanie krawędzi zegara
Krótka historia
Whith VHDL 2008 i jeśli typ zegara jest bit
, boolean
, ieee.std_logic_1164.std_ulogic
lub ieee.std_logic_1164.std_logic
, wykrywanie krawędzi zegara mogą być kodowane za zboczem narastającym
-
if rising_edge(clock) then
-
if clock'event and clock = '1' then -- type bit, std_ulogic or std_logic
-
if clock'event and clock then -- type boolean
i do opadania krawędzi
-
if falling_edge(clock) then
-
if clock'event and clock = '0' then -- type bit, std_ulogic or std_logic
-
if clock'event and not clock then -- type boolean
Będzie to działać zgodnie z oczekiwaniami, zarówno w przypadku symulacji, jak i syntezy.
Uwaga: definicja zbocza narastającego na sygnale typu
std_ulogic
jest nieco bardziej złożona niż proste,if clock'event and clock = '1' then
. Na przykład standardowa funkcjarising_edge
ma inną definicję. Nawet jeśli prawdopodobnie nie będzie to miało znaczenia dla syntezy, może to zrobić dla symulacji.
Zdecydowanie zalecane jest korzystanie ze standardowych funkcji rising_edge
i falling_edge
. W poprzednich wersjach VHDL użycie tych funkcji może wymagać jawnego zadeklarowania użycia standardowych pakietów (np. ieee.numeric_bit
dla bit
typu) lub nawet zdefiniowania ich w pakiecie niestandardowym.
Uwaga: nie używaj standardowych funkcji
rising_edge
ifalling_edge
do wykrywania krawędzi sygnałów innych niż zegarowe. Niektóre syntezatory mogą wnioskować, że sygnał jest zegarem. Wskazówka: wykrywanie zbocza sygnału nie zegara może być często wykonywane przez próbkowanie sygnału w rejestrze przesuwnym i porównywanie próbkowanych wartości na różnych etapach rejestru przesuwnego.
Długa historia
Prawidłowe opisanie wykrycia krawędzi sygnału zegara jest niezbędne podczas modelowania D-Flip-Flops (DFF). Krawędź jest z definicji przejściem od jednej konkretnej wartości do drugiej. Na przykład, możemy zdefiniować zbocze narastające sygnału typu bit
(standardowy typ wyliczany VHDL, który przyjmuje dwie wartości: '0'
i '1'
) jako przejście z '0'
na '1'
. Dla typu boolean
możemy zdefiniować go jako przejście od false
do true
.
Często stosuje się bardziej złożone typy. Na ieee.std_logic_1164.std_ulogic
typ ieee.std_logic_1164.std_ulogic
jest również typem wyliczonym, podobnie jak bit
lub boolean
, ale ma 9 wartości zamiast 2:
Wartość | Znaczenie |
---|---|
'U' | Niezainicjowany |
'X' | Wymuszanie nieznane |
'0' | Wymuszanie niskiego poziomu |
'1' | Wymuszając wysoki poziom |
'Z' | Wysokiej impedancji |
'W' | Słaby nieznany |
'L' | Słaby niski poziom |
'H' | Słaby wysoki poziom |
'-' | Nie obchodzi mnie to |
Definiowanie zbocza narastającego na takim typie jest nieco bardziej złożone niż dla bit
lub boolean
. Możemy na przykład zdecydować, że jest to przejście z '0'
na '1'
. Możemy jednak zdecydować, że jest to przejście z '0'
lub 'L'
na '1'
lub 'H'
.
Uwaga: jest to druga definicja, której standard używa dla funkcji
ieee.std_logic_1164
rising_edge(signal s: std_ulogic)
zdefiniowanego wieee.std_logic_1164
.
Przy omawianiu różnych sposobów wykrywania krawędzi ważne jest zatem rozważenie rodzaju sygnału. Ważne jest również wzięcie pod uwagę celu modelowania: tylko symulacja czy synteza logiczna? Zilustrujmy to na kilku przykładach:
Narastająca krawędź DFF z bitem typu
signal clock, d, q: bit;
...
P1: process(clock)
begin
if clock = '1' then
q <= d;
end if;
end process P1;
Technicznie, z punktu widzenia czystej semantyki symulacji, proces P1
modeluje DFF wyzwalający zbocze narastające. Rzeczywiście, przypisanie q <= d
jest wykonywane wtedy i tylko wtedy, gdy:
-
clock
zmieniony (tak wyraża się lista czułości) i - aktualna wartość
clock
to'1'
.
Ponieważ clock
jest typu bitowego, a bit typu ma tylko wartości '0'
i '1'
, właśnie to zdefiniowaliśmy jako zbocze narastające sygnału typu bitowego. Każdy symulator obsłuży ten model zgodnie z oczekiwaniami.
Uwaga: w przypadku syntezatorów logicznych rzeczy są nieco bardziej złożone, co zobaczymy później.
Zbocze narastające DFF z asynchronicznym aktywnym wysokim resetem i bitem typu
Aby dodać asynchroniczny aktywny wysoki reset do naszego DFF, można spróbować czegoś takiego:
signal clock, reset, d, q: bit;
...
P2_BOGUS: process(clock, reset)
begin
if reset = '1' then
q <= '0';
elsif clock = '1' then
q <= d;
end if;
end process P2_BOGUS;
Ale to nie działa . Warunkiem wykonania przypisania q <= d
powinno być: narastające zbocze clock
podczas reset = '0'
. Ale modelowaliśmy:
-
clock
lubreset
lub oba zmienione i -
reset = '0'
i -
clock = '1'
Co nie jest takie samo: jeśli reset
zmieni się z '1'
na '0'
gdy clock = '1'
przypisanie zostanie wykonane, gdy nie będzie rosnącą krawędzią clock
.
W rzeczywistości nie ma możliwości modelowania tego w VHDL bez pomocy atrybutu signal:
P2_OK: process(clock, reset)
begin
if reset = '1' then
q <= '0';
elsif clock = '1' and clock'event then
q <= d;
end if;
end process P2_OK;
clock'event
to event
atrybutu sygnału zastosowane do clock
sygnału. Ocenia się jako wartość boolean
i jest true
wtedy i tylko wtedy, gdy clock
sygnału zmienił się podczas fazy aktualizacji sygnału, która tuż przed bieżącą fazą wykonania. Dzięki temu proces P2_OK
teraz doskonale modeluje to, czego chcemy w symulacji (i syntezie).
Semantyka syntezy
Wiele syntezatorów logicznych identyfikuje wykrywanie krawędzi sygnału na podstawie wzorców składniowych, a nie semantyki modelu VHDL. Innymi słowy, zastanawiają się, jak wygląda kod VHDL, a nie jakie zachowanie modeluje. Jednym z wzorców, które wszyscy rozpoznają, jest:
if clock = '1' and clock'event then
Tak więc, nawet w przykładzie procesu P1
powinniśmy go użyć, jeśli chcemy, aby nasz model był syntezowalny przez wszystkie syntezatory logiczne:
signal clock, d, q: bit;
...
P1_OK: process(clock)
begin
if clock = '1' and clock'event then
q <= d;
end if;
end process P1_OK;
and clock'event
część and clock'event
jest całkowicie zbędna z listą czułości, ale ponieważ niektóre syntezatory tego potrzebują ...
std_ulogic
krawędź DFF z asynchronicznym aktywnym wysokim resetem i wpisz std_ulogic
W takim przypadku wyrażenie rosnącego zbocza zegara i warunek resetowania mogą się skomplikować. Jeśli zachowamy definicję zbocza narastającego, którą zaproponowaliśmy powyżej i jeśli weźmiemy pod uwagę, że reset jest aktywny, jeśli jest to '1'
lub 'H'
, model staje się:
library ieee;
use ieee.std_logic_1164.all;
...
signal clock, reset, d, q: std_ulogic;
...
P4: process(clock, reset)
begin
if reset = '1' or reset = 'H' then
q <= '0';
elsif clock'event and
(clock'last_value = '0' or clock'last_value = 'L') and
(clock = '1' or clock = 'H') then
q <= d;
end if;
end process P4;
Uwaga:
'last_value
to kolejny atrybut sygnału, który zwraca wartość sygnału, który miał przed ostatnią zmianą wartości.
Funkcje pomocnicze
Standard VHDL 2008 oferuje kilka funkcji pomocniczych, aby uprościć wykrywanie krawędzi sygnału, szczególnie w przypadku wielowartościowych wyliczanych typów, takich jak std_ulogic
. std.standard
pakiet określa rising_edge
i falling_edge
funkcje dotyczące rodzajów bit
i boolean
, a ieee.std_logic_1164
pakiet definiuje je na typy std_ulogic
i std_logic
.
Uwaga: w poprzednich wersjach VHDL użycie tych funkcji może wymagać jawnego zadeklarowania użycia standardowych pakietów (np. Ieee.numeric_bit dla bitu typu) lub nawet zdefiniowania ich w pakiecie użytkownika.
Powróćmy do poprzednich przykładów i skorzystaj z funkcji pomocniczych:
signal clock, d, q: bit;
...
P1_OK_NEW: process(clock)
begin
if rising_edge(clock) then
q <= d;
end if;
end process P1_OK_NEW;
signal clock, d, q: bit;
...
P2_OK_NEW: process(clock, reset)
begin
if reset = '1' then
q <= '0';
elsif rising_edge(clock) then
q <= d;
end if;
end process P2_OK_NEW;
library ieee;
use ieee.std_logic_1164.all;
...
signal clock, reset, d, q: std_ulogic;
...
P4_NEW: process(clock, reset)
begin
if reset = '1' then
q <= '0';
elsif rising_edge(clock) then
q <= d;
end if;
end process P4_NEW;
Uwaga: w tym ostatnim przykładzie uprościliśmy również test dotyczący resetu. Resety pływające, o wysokiej impedancji są dość rzadkie, aw większości przypadków ta uproszczona wersja działa do symulacji i syntezy.