Mam obwód synchronizatora magistrali do przekazywania szerokiego rejestru w domenach zegarowych.
Podam uproszczony opis, pomijając logikę asynchronicznego resetowania.
Dane są generowane na jednym zegarze. Aktualizacje mają wiele (przynajmniej kilkanaście) krawędzi zegara:
PROCESS (src_clk)
BEGIN
IF RISING_EDGE(clock) THEN
IF computation_done THEN
data <= computation;
ready_spin <= NOT ready_spin;
END IF;
END IF;
END PROCESS;
Sygnał sterujący dla świeżych danych, który jest zakodowany w NRZI (więc prawidłowe słowo na magistrali odpowiada przejściu w sygnale sterującym). Sygnał sterujący przechodzi przez łańcuch DFF działający jak synchronizator.
PROCESS (dest_clk)
BEGIN
IF RISING_EDGE(dest_clk) THEN
ready_spin_q3 <= ready_spin_q2;
ready_spin_q2 <= ready_spin_q1;
ready_spin_q1 <= ready_spin;
END IF;
END PROCESS;
Obwód synchronizatora wprowadza krótkie opóźnienie, które zapewnia dużo czasu na ustabilizowanie szyny danych; próbka magistrali danych jest pobierana bezpośrednio bez ryzyka metastabilności:
PROCESS (dest_clk)
BEGIN
IF RISING_EDGE(dest_clk) THEN
IF ready_spin_q3 /= ready_spin_q2 THEN
rx_data <= data;
END IF;
END IF;
END PROCESS;
Kompiluje się i działa dobrze, gdy zostanie zsyntetyzowany do FPGA Cyclone II. Jednak TimeQuest zgłasza przypadki naruszenia ustawień i wstrzymania, ponieważ nie rozpoznaje synchronizatora. Gorzej, mówi Quartus manual
Skoncentruj się na ulepszaniu ścieżek, które wykazują najgorszy zastój. Monter pracuje najtrudniej na ścieżkach z najgorszym luzem. Jeśli naprawisz te ścieżki, instalator może poprawić inne niedziałające ścieżki czasowe w projekcie.
Chcę więc dodać odpowiednie ograniczenia czasowe do mojego projektu, aby Quartus poświęcił wysiłek Montera na inne obszary projektu.
Jestem prawie pewien, że set_multicycle_path
jest to właściwe polecenie SDC (Synopsis Design Constraint), ponieważ linie danych będą miały wiele cykli docelowego zegara do ustabilizowania się, ale nie mogę znaleźć żadnych pełnych przykładów, używając tego polecenia do opisania logiki przekraczania domeny zegara .
Byłbym bardzo wdzięczny za wskazówki dotyczące pisania ograniczeń czasowych SDC dla synchronizatorów. Jeśli zauważysz problem z tym podejściem, daj mi również znać.
Szczegóły zegara:
Zewnętrzny generator zegara: dwa kanały, refclk = 20 MHz, refclk2 = refclk / 2 (10 MHz i powiązane).
Altera PLL: src_clk = refclk * 9/5 = 36 MHz
Altera PLL: dest_clk = refclk2 * 10 = 100 MHz
Mam również dane idące w innym kierunku, z 100 MHz src_clk i 36 MHz dest_clk.
TL; DR: Jakie są prawidłowe ograniczenia czasowe SDC dla powyższego kodu?
Odpowiedzi:
Nie mam doświadczenia z Kwartusem, więc potraktuj to jako ogólną radę.
Podczas pracy na ścieżkach między domenami zegarowymi narzędzia do pomiaru czasu rozszerzają zegary do najmniej wspólnej wielokrotności ich okresów i wybierają najbliższą parę krawędzi.
W przypadku ścieżek od zegara 36 MHz (27,777 ns) do zegara 100 MHz (10 ns), jeśli poprawnie wykonałem moje szybkie obliczenia, najbliższa para rosnących krawędzi wynosi 138,888 ns na zegarze źródłowym i 140 ns na zegarze docelowym. To skutecznie ograniczenie 900 MHz dla tych ścieżek! W zależności od zaokrąglenia (lub w przypadku zegarów bez związku) może to wyglądać gorzej.
Istnieją co najmniej trzy sposoby zapisywania ograniczeń dla tej struktury. Mam zamiar zadzwonić na zegary
fast_clk
islow_clk
jak sądzę, to jest bardziej zrozumiałe dla ilustracji.Opcja 1: wyłącz synchronizację za pomocą
set_false_path
Najłatwiejszym rozwiązaniem jest
set_false_path
wyłączenie synchronizacji między zegarami:Nie jest to całkowicie poprawne, ponieważ istnieją wymagania dotyczące synchronizacji, aby synchronizator działał poprawnie. Jeśli implementacja fizyczna zbytnio opóźnia dane w stosunku do sygnału sterującego, synchronizator nie będzie działać. Ponieważ jednak na ścieżce nie ma żadnej logiki, jest mało prawdopodobne, aby naruszono ograniczenie czasowe.
set_false_path
jest powszechnie stosowany w tego rodzaju strukturach, nawet w układach ASIC, w których wysiłek kontra ryzyko w przypadku awarii o niskim prawdopodobieństwie jest bardziej ostrożny niż w przypadku układów FPGA.Opcja 2: rozluźnij ograniczenie
set_multicycle_path
Możesz wyznaczyć dodatkowy czas dla niektórych ścieżek za pomocą
set_multicycle_path
. Bardziej powszechne jest używanie ścieżek wielokołowych z blisko spokrewnionymi zegarami (np. Interakcja zegarów 1X i 2X), ale zadziała tutaj, jeśli narzędzie wystarczająco je obsługuje.Domyślną relacją zbocza dla konfiguracji jest pojedynczy cykl, tj
set_multicycle_path 1
. Te polecenia pozwalają na jeszcze jeden cykl zegara punktu końcowego (-end
) dla ścieżek instalacji.-hold
Jest prawie zawsze potrzebne przy ustalaniu obsługujący kilka ścieżek rowerowych, dla bardziej patrz poniżej regulacja z jedna liczba jest mniejsza niż ograniczenie konfiguracji.Aby podobnie ograniczyć ścieżki w drugim kierunku (rozluźnienie ograniczenia o jeden okres szybszego zegara), zmień
-end
na-start
:Opcja 3: bezpośrednio określ wymaganie
set_max_delay
Jest to podobne do efektu polegającego na tym,
set_multicycle_path
że oszczędza konieczności przemyślenia relacji między krawędziami i wpływu na ograniczenia wstrzymania.Możesz sparować to z
set_min_delay
czekami wstrzymującymi lub pozostawić domyślne czekanie wstrzymane na miejscu. Możesz także zrobić,set_false_path -hold
aby wyłączyć sprawdzanie wstrzymania, jeśli Twoje narzędzie to obsługuje.Krwawe szczegóły wyboru krawędzi dla ścieżek wielocyklowych
Aby zrozumieć dostosowanie blokady, które łączy się z każdą regulacją konfiguracji, rozważ ten prosty przykład z relacją 3: 2. Każda cyfra reprezentuje rosnącą krawędź zegara:
Domyślny test konfiguracji używa krawędzi 2 i 6. Domyślny test blokady używa krawędzi 1 i 4.
Zastosowanie ograniczenia wielu cykli o wartości 2 z
-end
dostosowuje domyślną kontrolę konfiguracji i wstrzymania, aby użyć następnej krawędzi po tym, czego pierwotnie używano, co oznacza, że kontrola konfiguracji używa teraz krawędzi 2 i 7, a kontrola wstrzymania używa krawędzi 1 i 5. Dla dwóch zegary na tej samej częstotliwości, ta regulacja ma sens - każde uruchomienie danych odpowiada jednemu przechwytywaniu danych, a jeśli krawędź przechwytywania zostanie przesunięta o jeden, kontrola wstrzymania powinna również zostać przesunięta o jeden. Ten rodzaj ograniczenia może mieć sens dla dwóch gałęzi jednego zegara, jeśli jedna z gałęzi ma duże opóźnienie. Jednak w tej sytuacji sprawdzenie wstrzymania przy użyciu krawędzi 1 i 5 nie jest pożądane, ponieważ jedynym sposobem na jego naprawienie jest dodanie całego cyklu opóźnienia zegara na ścieżce.Ograniczenie wstrzymania dla wielu cykli wynoszące 1 (dla wstrzymania domyślnie jest to 0) dostosowuje krawędź docelowego zegara używanego do sprawdzania wstrzymania wstecz o jedną krawędź. Połączenie 2-cyklowych ustawień MCP konfiguracji i 1-cyklowych ograniczeń MCP wstrzymania spowoduje sprawdzenie konfiguracji przy użyciu krawędzi 2 i 7 oraz kontrolę blokady przy użyciu krawędzi 1 i 4.
źródło
Nie znam odpowiedzi dla Altera, ale w Xilinx Land możesz ustawić opóźnienie czasowe z jednej domeny zegarowej na drugą. Musisz opracować matematykę (zależy ona od projektu), ale zwykle jest to najkrótszy z dwóch okresów zegarowych. Pomyśl o tym czasie jako o maksymalnym odchyleniu między dowolnymi dwoma sygnałami (w tym sygnałem kontrolnym) i możesz sprawdzić, czy obwód synchronizacji będzie w stanie sobie z tym poradzić.
set_mulkle_path nie jest właściwą opcją, ponieważ normalnie dotyczyłoby to przypadków, gdy źródło i miejsce docelowe znajdują się w tej samej domenie zegara. Ponownie opieram to na moich doświadczeniach z Xilinx, aby twój przebieg mógł się różnić.
źródło
Myślę, że można bezpiecznie ustawić set_false_path na synchronizatorze.
Możesz także wstawić „set_global_assignment -name SYNCHRONIZER_IDENTIFICATION AUTO” w qsf, aby pomóc Quartusowi wykryć synchronizator.
źródło
set_false_path -from ready_spin -to ready_spin_q2
? Iset_false_path -from data -to rx_data
?set_false_path -from src_clk -to ready_spin
Nie jestem pewien, czy należy podać fałszywą ścieżkę do danych, ponieważ nie synchronizujesz jej.Podejrzewam, że problem polega na tym, że chociaż możesz wiedzieć, że sygnały magistrali nie zmienią się nigdzie w pobliżu punktu, w którym zostały zatrzaśnięte, oprogramowanie tego nie wie. Najlepszym rozwiązaniem jest wyraźne poinformowanie oprogramowania, że nadchodzące sygnały magistrali są zsynchronizowane z zegarem magistrali, i wyłączenie optymalizacji przed miejscem, w którym je zatrzaskujesz (optymalizator mógłby teoretycznie zastąpić obwód w takim, który byłby równoważny jeśli wejścia naprawdę byłyby zsynchronizowane, ale które można by rzucić w pętlę, jeśli zmieniłyby się w cyklach taktowania, na których narysowany obwód nie miałby znaczenia).
źródło
set_multicycle_path
byłby to sposób, aby powiedzieć syntezatorowi / analizatorowi taktowania, jak często sygnały źródłowe mogą się zmieniać? I nie jestem pewien, co rozumiesz przez „zegar autobusowy”, jest tu autobus sygnałowy przekraczający domeny zegarowe, więc który zegar nazywasz „zegarem autobusowym”? Myślę, że masz rację, że nadal może istnieć metastabilność, jeśli syntezator wprowadza usterki w okresach, gdy nie aktualizujędata
. Wydaje mi się, że mógłbym tam konkretnie utworzyć bloki DFF :(