2013-12-09 31 views
7

Poniżej znajduje się kod, który używam. Moje pytanie brzmi: dlaczego 3. spust wait until w modelsim? Wyjście konsoli to po prostu GOT HERE. Nigdy nie dociera do linii GOT HERE 2. Myślę, że posiadanie tego samego wait until <SIGNAL> = 1 dwa razy z rzędu byłoby w porządku, ponieważ warunek jest prawdziwy zarówno razy. Nie dodałem tam zdarzenia, więc nie sądzę, że symulator będzie musiał zobaczyć przewagę. Czy ktoś może wyjaśnić to zachowanie?Poczekaj, aż <signal> = 1 nigdy nie będzie prawdziwe w symulacji VHDL.

library ieee; 
use ieee.std_logic_1164.all; 
use ieee.numeric_std.all; 

entity example_wait_failure is 
end example_wait_failure; 

architecture behave of example_wait_failure is 

    signal r_CLK_TB : std_logic := '0'; 

begin 

    r_CLK_TB <= '1' after 20 ns, '0' after 40 ns, '1' after 60 ns; 


    p_TEST : process 
    begin 

    wait until r_CLK_TB = '1'; 
    report "GOT HERE" severity note; 

    wait until r_CLK_TB = '1'; 
    wait until r_CLK_TB = '1'; 
    report "GOT HERE 2 " severity note; 

    end process p_TEST; 

end behave; 

Odpowiedz

10

Zachowanie tkwi w szczegółach rachunku wait (szczegółowe dane dotyczące czekać tak Jim Lewis dotyczy). Powodem jest to, że oświadczenia wait ma trzy części:

wait 
    [on sensitivity_list] 
    [until condition] 
    [for time_expression]; -- Only for timeout, and not relevant here 

wait w odpowiednim kodem tylko ma until części, więc sensitivity_list tworzony jest zgodnie z normą VHDL: „Jeśli nie pojawia się wrażliwość klauzula, zestaw czułości jest skonstruowany zgodnie z następującą regułą (rekurencyjna): ... ". Wygenerowana w ten sposób lista wraŜliwości będzie w tym przypadku zawierać r_CLK_TB.

Standardowa VHDL ma przykład pasujący kod precyzyjnie, a to stwierdza:

wait until r_CLK_TB = '1'; 

jest identyczna:

loop 
    wait on r_CLK_TB; 
    exit when r_CLK_TB = '1'; 
end loop; 

Więc chociaż wait wyraźnie nie zawierają wait until r_CLK_TB'event (jak napisano w komentarzu), wykonanie powoduje czekanie aż wydarzenie na r_CLK_TB w celu przekazania pierwszego wait w wait on r_CLK_TB. Czy to intuicyjne ...Sędzia dla siebie ;-)

Więc może oryginalny kod powinien być zmienia się tak:

wait until r_CLK_TB = '1'; 

otrzymuje brzmienie:

if r_CLK_TB /= '1' then 
    wait until r_CLK_TB = '1'; 
end if; 

W tym przypadku zarówno „tu mamy” i „tu mamy 2 "są pokazane na 20 ns, ponieważ warunek wszystkich trzech konstrukcji będzie tutaj PRAWDA.

+0

Dziękuję za wyjaśnienie. Interesujące jest dla mnie, że oczekiwanie na r_CLK_TB jest częścią czekania do sprawdzenia r_CLK_TB = "1". Pozwól, że zadam jedno ostatnie pytanie, wtedy sprawdzę pudełko :) Podczas szukania pozytywnych krawędzi zegarka masz 2 opcje. Zakładając, że nie korzystasz z wait until rising_edge (r_CLK_TB) w normalnym kodzie RTL, którego używasz, poczekaj, aż r_CLK_TB'event i r_CLK_TB = "1". Czy mówisz mi, że poczekaj, aż r_CLK_TB'event będzie tutaj całkowicie bezużyteczny? – Russell

+1

W 'wait do r_CLK_TB'event i r_CLK_TB = '1'',' r_CLK_TB'event' będzie trywialne TRUE, gdy 'r_CLK_TB'event i r_CLK_TB =' 1'' jest oceniany, ponieważ jest to zdarzenie, które uruchamia ocenę jak sugerujesz, więc wyrażenie można zredukować do 'r_CLK_TB = '1''. –

+1

NEAT. Zamierzam zacząć pisać cały mój kod, po prostu, żeby zadzierać z ludźmi :) – Russell

3

Praca domowa? Egzamin?

Musisz przestudiować szczegóły dotyczące działania wait. Zaczekaj zawsze zawiesza się na co najmniej cykl delta. Poczekaj, aż wznowi się tylko wtedy, gdy zmieni się sygnał w warunku i wyrażenie będzie prawdziwe. A więc ile przejść do "1" potrzebujesz tutaj, aby dostać się do drugiego raportu?

Ile przejścia na „1” czy masz z:

signal r_CLK_TB : std_logic := '0'; 
... 
r_CLK_TB <= '1' after 20 ns, '0' after 40 ns, '1' after 60 ns; 

trzeba badać szczegóły, jak czekać prace. Zaczekaj zawsze zawiesza się na co najmniej cykl delta. Poczekaj, aż wznowi się tylko wtedy, gdy zmieni się sygnał w warunku, a wyrażenie będzie prawdziwe. Więc ile przejść do "1" potrzebujesz tutaj?

Co stanie się po zmianie r_CLK_TB na następujące?

r_CLK_TB <= not r_CLK_TB after 20 ns ; 
+0

Nie zadanie domowe ani egzamin ... znalazły ten problem podczas prawdziwej pracy! Dlaczego sygnał w stanie oczekiwania musi się zmienić? Jeśli warunek czekał aż r_CLK_TB = "1" był prawdziwy PRZED dotarciem do instrukcji wait, to po prostu poszedłby prosto, prawda? Zakładam, że poczekaj, aż r_CLK_TB'event będzie szukał przejścia. Obawiam się, że nadal nie całkiem rozumiem ... – Russell

+0

Mogę zaakceptować to jako "dobrze, że tak zachowuje się Modelsim", ale nie czuje się dobrze dla mnie. :) – Russell

+1

To nie jest tylko ModelSim, wszystkie symulatory VHDL robią to, ponieważ to zachowanie jest wymaganiem językowym. Innym sposobem myślenia jest to, że sygnały w tym stanie tworzą ukrytą listę wrażliwości. Rozumiem twoje myśli, ponieważ wiele z nich błędnie postrzega to jako kontrolę poziomu, ale jest to sprawdzanie krawędzi. Język został zaprojektowany w taki sposób, aby uprościć sprawdzanie procesu, który nigdy się nie zawiesza (zła nieskończona pętla) - jeśli proces zawiera instrukcję wait lub listę czułości procesu, zawiesza się. Na stołach testowych naprawdę musisz zrozumieć szczegóły działania czekania. –