Kurs FPGA Lattice (7). Analizator logiczny Reveal

Kurs FPGA Lattice (7). Analizator logiczny Reveal

Analizator logiczny pozwala nam obserwować, co dzieje się wewnątrz FPGA. Możemy podsłuchiwać połączenia pomiędzy modułami, a także zaglądać do środka przerzutników. Jest to bardzo pomocne narzędzie, które ułatwia znajdowanie błędów.

Wszyscy więksi producenci udostępniają narzędzia do analizowania sygnałów wewnątrz FPGA, które działają dość podobnie. Xilinx udostępnia narzędzie ChipScope, Intel oferuje Signal Tap, a Lattice daje nam Reveal. Jest to narzędzie bezpłatne i zintegrowane z pakietem Diamond, które możemy używać bez żadnych dodatkowych licencji czy ograniczeń.

Idea działania analizatora jest bardzo prosta. Przy pomocy programu Reveal Inserter tworzymy moduł analizatora, który łączymy z interesującymi nas sygnałami. Moduł ten jest w istocie zwyczajnym modułem sporządzonym w języku Verilog. Mamy nawet dostęp do jego plików źródłowych, chociaż ich ręczna edycja jest niepotrzebna. Wszystko możemy skonfigurować przy pomocy interfejsu graficznego.

Następnie, mając już utworzony moduł analizatora, dokonujemy syntezy, mapowania, generujemy bitstream i wgrywamy do go FPGA. Aby odczytywać dane z analizatora, wykorzystamy narzędzie Reveal Analyzer, które łączy się z analizatorem poprzez port JTAG – ten sam, który wykorzystywany jest przez programator. Dzięki takiemu rozwiązaniu nie potrzebujemy modyfikować projektu płytki, na której pracuje nasz układ FPGA.

Analizator i symulator to dwa narzędzia, które pomogą nam debugować kod. Każdy z nich ma swoje wady i zalety, dzięki czemu te narzędzia dobrze się uzupełniają. Największą zaletą analizatora jest to, że bada sygnały rzeczywiste, które faktycznie występują w badanym układzie FPGA. Jeżeli wyniki analizatora i symulatora nie zgadzają się ze sobą, to znaczy, że nie uwzględniliśmy czegoś w symulacji. Ponadto, analizator jest niezwykle przydatny, kiedy debugujemy komunikację FPGA z jakimiś innymi układami scalonymi. Symulowanie układów scalonych, które przesyłają dane do FPGA, jest dość trudne i czasochłonne.

Analizator ma jednak swoje wady. Musimy przeznaczyć dość sporo zasobów logicznych, aby analizator mógł w ogóle zacząć pracę. Może się okazać, że nasz design z doklejonym analizatorem nie zmieści się do FPGA. Nie ma możliwości, by Reveal zastosować w najmniejszych maluchach – układy MachXO2-256 oraz MachXO2-640 nie mają wystarczających zasobów, by mógł on działać. Obecność analizatora może także zmniejszyć maksymalną dopuszczalną częstotliwość zegara i wydłużyć czas propagacji sygnałów. Symulacja wygrywa pod tym względem – symulator nie potrzebuje żadnych zasobów w FPGA, ponieważ działa w całości na komputerze.

W tabeli 1 porównano, ile zasobów potrzebnych jest, aby zrealizować projekt z tego odcinka kursu w FPGA MachXO2-1200. Zasoby potrzebne na analizator Reveal mogą zmieniać się w bardzo szerokim zakresie. Zależą od liczby badanych sygnałów, wyzwalaczy oraz liczby próbek, jaka ma zostać zbadana i zapisana w pamięci.

Kolejną wadą jest konieczność ponownej syntezy i wgrywania bitstreamu do FPGA, kiedy zmieniamy konfigurację obserwowanych sygnałów i wyzwalaczy. Może to być czasochłonne, ale przy odrobinie wprawy można nauczyć się tak tworzyć analizatory, by spełniały oczekiwania już przy pierwszej próbie.

W tym odcinku użyjemy kodu, który opracowaliśmy w kwietniowym wydaniu EP. Kod całego projektu wraz z analizatorem jest dostępny w materiałach dodatkowych do artykułu. Jeżeli nie czytałeś poprzedniego odcinka, przeczytaj go koniecznie, ponieważ dalsza część tekstu będzie niezrozumiała.

Dla wygody wprowadzimy małą zmianę. W listingu 1 zmieńmy parametr, który jest odpowiedzialny za czas opóźnienia modułów filtrujących drgania styków przycisków. W liniach #1 i #2 zmieniamy czas na 1 mikrosekundę. Spowoduje to, że przy zegarze o częstotliwości 14 MHz, moduły Debouncer będą czekać przez zaledwie 14 cykli zegarowych, zamiast kilkunastu tysięcy. Chodzi po prostu o to, żeby dla naszej wygody, przebiegi analizatora zmieściły się na ekranie.

Listing 1. Kod pliku top.v

// Plik top.v
module top(
input Reset,
input ButtonUp,
input ButtonDown,
output [6:0] Segments
);

// Generator sygnału zegarowego
OSCH #(
.NOM_FREQ("14.00")
) OSCH_inst(
.STDBY(1’b0),
.OSC(Clock14MHz),
.SEDSTDBY()
);

// Odszumianie przycisku UP
wire ButtonUpFiltered;
Debouncer #(
.FREQUENCY_MHZ(14),
.PERIOD_US(1) // #1
) DebounceUp(
.Clock(Clock14MHz),
.Reset(Reset),
.NoisySignal(ButtonUp),
.FilteredSignal(ButtonUpFiltered)
);

// Odszumianie przycisku DOWN
wire ButtonDownFiltered;
Debouncer #(
.FREQUENCY_MHZ(14),
.PERIOD_US(1) // #2
) DebounceDown(
.Clock(Clock14MHz),
.Reset(Reset),
.NoisySignal(ButtonDown),
.FilteredSignal(ButtonDownFiltered)
);

// Wykrywanie zbocza rosnącego przycisku UP
wire RequestUp;
EdgeDetector UpDetector(
.Clock(Clock14MHz),
.Reset(Reset),
.Signal(ButtonUpFiltered),
.RisingEdge(RequestUp),
.FallingEdge()
);

// Wykrywanie zbocza rosnącego przycisku DOWN
wire RequestDown;
EdgeDetector DownDetector(
.Clock(Clock14MHz),
.Reset(Reset),
.Signal(ButtonDownFiltered),
.RisingEdge(RequestDown),
.FallingEdge()
);

// Licznik
wire [3:0] CountValue;
Counter #(
.WIDTH(4)
) Counter0(
.Clock(Clock14MHz),
.Reset(Reset),
.CountUp(RequestUp),
.CountDown(RequestDown),
.Value(CountValue)
);

// Dekoder wyświetlacza 7-segmentowego
Decoder7seg Dekoder0(
.Data(CountValue),
.Segments(Segments)
);


endmodule

Reveal Inserter

Analizator logiczny, podobnie jak oscyloskop, cyklicznie bada stan obserwowanych sygnałów i zapisuje wyniki do pamięci. Posiada jeden lub więcej sygnałów wyzwalających. Analizator oczekuje na wystąpienie konkretnego zdarzenia na sygnale wyzwalającym – na przykład może to być zbocze rosnące. Kiedy taka sytuacja wystąpi, wówczas określona liczba próbek przed i po zdarzeniu wyzwalającym, zostaje utrwalana w pamięci. Następnie analizator przesyła dane do komputera i oczekuje na ponowne uruchomienie przez użytkownika.

Istnieje możliwość skonfigurowania analizatora w taki sposób, by podczas jednego cyklu pracy, wyzwalał się kilka razy i przesyłał dane do komputera dopiero po wystąpieniu określonej liczby zdarzeń wyzwalających. W naszym przykładzie sygnałem wyzwalającym będzie naciśnięcie przycisku Up lub Down.

Skonfigurujemy analizator w taki sposób, że każde wyzwolenie spowoduje rejestrację 32 próbek różnych sygnałów w modułach Debouncer, filtrujących drgania przycisków Up i Down, a także będziemy rejestrować stan licznika Counter, który w wyniku naciśnięcia tych przycisków jest zwiększany lub zmniejszany. Spośród zarejestrowanych 32 sampli, tylko 2 będą pokazywać, co działo się przed wystąpieniem wyzwalacza, a 30 sampli zostanie zarejestrowanych po wystąpieniu wyzwalacza. Analizator skonfigurujemy w taki sposób, by w jednym cyklu pracy obsługiwał 4 sygnały wyzwalające, po czym wszystkie zgromadzone dane będą przesyłane przez programator JTAG do komputera.

W pierwszej kolejności musimy utworzyć instancję analizatora logicznego i umieścić do w naszym projekcie. Z menu Tools wybieramy opcję Reveal Inserter. Otwiera się okno, w którym skonfigurujemy analizator i następnie automatycznie wygenerujemy kod w Verilogu. Działa to podobnie jak IP Express, który poznaliśmy w 5 odcinku kursu. Zobacz rysunek 1.

Rysunek 1. Konfiguracja badanych sygnałów w Reveal Inserter

Zacznijmy od okienka Dataset w lewym górnym rogu. Istnieje możliwość, by w jednym projekcie umieścić kilka analizatorów. W tym celu należy kliknąć Datasets prawym przyciskiem myszy, następnie wybrać Add New Core i dalej Add Logic Analyzer. Każdy analizator musi mieć swoją unikalną nazwę.

Domyślnie utworzony analizator nazywa się top_LA0. Proponuję kliknąć go prawym przyciskiem myszy i wybierając opcję Rename Core zmienić nazwę na PierwszyAnalizator.

W okienku Design Tree znajdziemy wszystkie obiekty, które możemy obserwować przy pomocy analizatora Reveal. Znajdziemy tutaj wszystkie moduły, a także ich sygnały i rejestry. Interesujące nas obiekty klikamy i przeciągamy do okienka Trace po prawej stronie. Skonfiguruj obserwowane sygnały w taki sposób, jak pokazano to na rysunku 1.

Kolejnym krokiem jest wskazanie sygnału zegarowego. Można jego nazwę wpisać ręcznie lub można także znaleźć go w Design Tree i przeciągnąć do pola tekstowego Sample Clock. Wadą analizatora Reveal jest to, że wykorzystuje on ten sam zegar do samplowania badanych sygnałów i do komunikacji przez JTAG. Częstotliwość zegara taktującego analizator powinna być większa niż częstotliwość zegara JTAG (12 MHz) i mniejsza niż 200 MHz. Jeżeli chcemy samplować z mniejszą częstotliwością, wówczas musimy wykorzystać opcję wielokrotnego wyzwalania, o czym będzie kilka akapitów dalej.

Następnie wybieramy pamięć, która zostanie przeznaczona na buforowanie zarejestrowanych próbek. W polu Implementation mamy dwie możliwości:

  • EBR – są to bloki pamięci RAM wbudowane w strukturę FPGA. Jeżeli mamy dostępną wolną pamięć RAM, to należy ją wykorzystać;
  • DistRAM – jest to pamięć RAM utworzona z uniwersalnych zasobów logicznych Slice. Wadą tego rozwiązania jest jego ogromna zasobożerność. Z tej opcji należy korzystać tylko wtedy, kiedy wszystkie bloki RAM zostały już użyte przez naszą aplikację.

Wybieramy opcję EBR. Po prawej stronie od pola wyboru widzimy ile bloków EBR zostanie wykorzystanych przez nasz analizator – w naszym przykładzie będzie to dokładnie jeden blok, a układy MachXO2 w zależności od wersji, posiadają od 2 do 26 bloków pamięci EBR (każdy z nich ma pojemność 9 kbit).

W polu Buffer Depth musimy określić łączną liczbę próbek, jaka ma zostać zbuforowana w pamięci, zanim zostaną one przesłane do komputera przez JTAG. Ważne by pamiętać, że jest to łączna liczba próbek, niezależnie ile sygnałów wyzwalających ma być zarejestrowane podczas cyklu pracy analizatora.

Zgodnie z tym, co zostało opisane kilka akapitów wcześniej, ustawiamy pojemność bufora na 128 sampli.

Istnieje możliwość, by każda próbka miała zapisany dodatkowo timestamp, czyli znacznik czasowy. Jeżeli zaznaczymy opcję Timestamp, zostanie utworzony dodatkowy licznik, który będzie inkrementował swoją wartość z każdym taktem zegara. Musimy jeszcze wybrać, ile bitów ma mieć ten licznik. Ta opcja może być przydatna do badania odstępu czasowego pomiędzy wyzwalaczami. W przypadku stosowania pojedynczego wyzwalacza ta funkcja jest mało przydatna.

Idziemy dalej – w polu Sample Enable możemy podać sygnał, który ma uaktywniać analizator. Kiedy zaznaczymy pole Sample Enable, wówczas pojawi się textbox, w którym trzeba podać nazwę sygnału uaktywniającego wyzwalanie. Możemy określić, czy analizator ma być aktywny, kiedy sygnał aktywujący jest w stanie niskim czy wysokim. Ta funkcjonalność może być przydatna, kiedy w badanym układzie następuje dużo zdarzeń wyzwalających, ale interesuje nas obserwowanie badanych sygnałów tylko w jakimś konkretnym przypadku, np. kiedy na magistrali I²C zostanie wywołany adres interesującego nas urządzenia. W naszym przykładzie nie będziemy korzystać z tej opcji i pozostawiamy ją wyłączoną.

Kolejną ciekawą opcją jest POR Debug, co oznacza Power On Reset. Jest to funkcja umożliwiająca obserwowanie sygnałów zaraz po starcie FPGA. W sekcji Data Capture Mode mamy do wyboru dwie możliwości:

  • Single Trigger Mode – po uaktywnieniu analizatora i wystąpieniu zdarzenia wyzwalającego, analizator zgromadzi tyle próbek, ile określono w polu Buffer Depth, po czym prześle wyniki do komputera i będzie czekał na kolejne ręczne uaktywnienie.
  • Multiple Trigger Mode – po uaktywnieniu analizatora, będzie on wykonywał kilka cykli zbierania danych. Liczba wykrywanych wyzwalaczy zostanie ustalona później. Jedyne co musimy ustalić, to ile co najmniej próbek ma być zebranych na każdy sygnał wyzwalający. Może się to wydawać trochę dziwne, ale dzięki temu rozwiązaniu możemy zmieniać liczbę wyzwalaczy i liczbę zgromadzonych próbek bez konieczności syntezowania wszystkiego od nowa i wgrywania zmodyfikowanego bitstremu.

Wybierzmy opcję Multiple Trigger Mode, a w Minimum Sample per trigger zaznaczmy 32 próbki. Przy pojemności bufora rzędu 128 sampli, będziemy mogli zebrać dwie serie pomiarów po 64 sample lub cztery serie po 32 sample.

Zapiszmy projekt analizatora w pliku pierwszy_analizator.rvl w katalogu impl1/source. Powinniśmy zobaczyć plik analizatora w drzewku projektu w katalogu Debug Files. Może się zdarzyć, że nowo utworzony plik nie pojawi się tam automatycznie – wtedy klikamy na pozycję Debug Files, a następnie wybieramy Add Existing File i dodajemy utworzony plik.

Skonfigurowaliśmy sygnały, które chcemy obserwować, a w następnym kroku musimy określić sygnały wyzwalające. Na samym dole okna klikamy zakładkę Trigger Signal Setup (rysunek 2). W sekcji Trigger Unit musimy podać sygnały, które będą wyzwalaczami naszego analizatora. Możemy podać kilka sygnałów, a następnie określimy warunki logiczne – może być tak, że analizator zostanie wyzwolony dowolnym sygnałem, wszystkimi sygnałami jednocześnie lub jakąś ich kombinacją.

Rysunek 2. Konfiguracja sygnałów wyzwalających w Reveal Inserter

Klikamy przycisk Add w sekcji Trigger Unit. Pojawiły się dwie linie w tabeli, oznaczone jako TU1 i TU2. W kolumnie Signals musimy umieścić sygnały, które staną się wyzwalaczami. W okienku Design Tree musimy odszukać sygnały ButtonUp i ButtonDown i przesuwamy je odpowiednio do TU1 i TU2. Są to sygnały pochodzące z przycisków, czyli naciśnięcie przycisku wyzwoli analizator.

W kolumnie Operator mamy możliwość wybrania różnorodnych porównań i warunków logicznych. Wybieramy opcję Rising Edge dla obu sygnałów. W kolumnie Radix mamy możliwość wyboru systemu liczbowego, jaki jest dla nas najwygodniejszy. Pozostawmy opcję Bin czyli zapis binarny. Zdefiniowane przez nas wyzwalacza są sygnałami 1-bitowymi, czyli przyjmują wartość 0 lub 1, zatem wybór systemu liczbowego w takim przypadku nic nie zmienia.

Kolumna Value stanowi pułapkę, w którą można łatwo wpaść. Jest to najbardziej nieintuicyjna nazwa, jaką można było nadać tej kolumnie. Chodzi tutaj o zdefiniowanie, które bity sygnału mają być brane pod uwagę przy wykrywaniu zbocza, a które mają być zignorowane. Sygnały istotne powinny być oznaczone jako 1, a nieistotne jako 0. Dla przykładu, jeżeli mamy magistralą 8-bitową i interesuje nas wykrywanie zbocza rosnącego na linii siódmej, szóstej i zerowej, powinniśmy wpisać 11000001. W naszym przypadku mamy sygnały 1-bitowe i chcemy wykrywać właśnie ten jeden bit, więc w obu liniach wpisujemy 1.

Przechodzimy do sekcji Trigger Expression. Musimy tutaj określić warunek logiczny, łączący poszczególne wyzwalacze, zdefiniowane w Trigger Unit. Mamy do dyspozycji różne operatory logiczne:

  • & – koniunkcja,
  • | – alternatywa,
  • ^ – xor,
  • ! – negacja,
  • nawiasy okrągłe,
  • THEN – najpierw ma być prawdziwy pierwszy warunek, a potem ma być prawdziwy drugi warunek,
  • NEXT – najpierw ma być spełniony pierwszy warunek, a drugi ma być spełniony w kolejnym cyklu zegara
  • # liczba – warunek ma być spełniony określoną liczbę razy
  • ## liczba – warunek ma być spełniony przez określoną liczbę taktów zegarowych.

Oto kilka przykładów:

  • TU1 & TU2 – oba warunki mają być spełnione jednocześnie,
  • TU1 | TU2 – ma być spełniony dowolny z warunków,
  • TU1 THEN TU2 #2 – najpierw ma być spełniony warunek TU1, a potem ma być spełniony dwukrotnie warunek TU2 w dowolnym czasie później,
  • (TU1 & TU2) ##10 NEXT TU3 – najpierw warunki TU1 i TU2 mają być spełnione jednocześnie przez 10 taktów zegara, a w kolejnym takcie ma być spełniony TU3,
  • TU1 THEN (1)#200 – po spełnieniu warunku TU1 czekaj przez 200 taktów zegara i dopiero wtedy wyzwól analizator.

Możliwości konfiguracji wyzwalaczy są całkiem rozbudowane i odsyłam po więcej informacji do instrukcji Reveal User Guide, dostępnej pod adresem [1].

W naszym przykładzie interesuje nas, aby analizator był wyzwalany po wciśnięciu obojętnie którego przycisku, więc w polu Expression wpisujemy TU1 | TU2. W kolumnie RAM Type musimy zdefiniować jaki rodzaj pamięci ma wykorzystywać logika wyzwalacza. Należy się tutaj kierować ilością zasobów, jaka pozostaje w FPGA po syntezie naszego układu, podobnie jak to było w przypadku pamięci na próbki. Program proponuje nam użycie jednego bloku EBR lub trzech komórek slice. W naszym przypadku wszystko jedno, ponieważ EBR-ów i Slice-ów mamy pod dostatkiem.

Następne kolumny potrzebne są do badania sekwencji sygnałów wyzwalających. My nie wykorzystujemy tej funkcjonalności, więc ustawiamy wszystko na 1. Nie będziemy także korzystać z licznika triggerów, więc Enable final trigger counter pozostawiamy niezaznaczone. Opcja Enable Trigger Out pozwala wyprowadzić sygnał wyzwalacza poza moduł analizatora. Może to być przydatne w sytuacji, kiedy analizator ma uruchamiać inne narzędzia pomiarowe, na przykład oscyloskop.

Rysunek 3. Kontrola i umieszczenie analizatora w projekcie

Ukończyliśmy konfigurację analizatora. Teraz musimy skontrolować poprawność konfiguracji. Klikamy przycisk kontroli, zaznaczony na rysunku 3. Po przeprowadzeniu kontroli, w konsoli na dole okna programu Diamond powinniśmy zobaczyć informację o zapotrzebowaniu na zasoby oraz pozytywny wynik kontroli lub informacje o błędach (listing 2).

Listing 2. Informacja o zapotrzebowaniu na zasoby oraz pozytywny wynik kontroli

Checking design rules ...
INFO - The number of EBRs needed is 2.
INFO - The number of DistRAM (logic/ROM/RAM) slices needed is 0.
Design Rule Check PASSED.

Następnie klikamy przycisk Insert Debug, po czym zostanie wygenerowany analizator i dodany do naszego kodu. Kod nie zostanie zmieniony w żaden sposób. Syntezujemy i generujemy bitstream w taki sam sposób, jak zawsze, a następnie wgrywamy go do naszego FPGA. Zobaczmy Netlist Analyzer, pokazany na rysunku 4. Na czerwono zaznaczyłem instancję analizatora. Widzimy, że jest osobny nowy twór, który jest podłączony do różnych sygnałów, jakie nas interesują.

Rysunek 4. Netlist Analyzer z zaznaczonym analizatorem Reveal

Reveal Analyzer

Program Reveal Inserter służy tylko do generowania modułów analizatora, które są syntezowalne, a po wgraniu bitstreamu do FPGA ten program możemy zamknąć. Z menu Tools wybieramy opcję Reveal Analyzer. Jest to program, który łączy się poprzez interfejs JTAG z analizatorem, wyświetla zgromadzone dane i umożliwia zmianę niektórych parametrów. Pojawi się nam okienko, jakie widać na rysunku 5.

Rysunek 5. Tworzenie pliku Reveal Analyzer

Musimy tutaj podać, jaki programator stosujemy oraz typ układu FPGA, z którym chcemy się łączyć przez JTAG. Przydają się przyciski Detect i Scan. W polu RVL Source musimy wskazać plik *.rvl, utworzony przez Reveal Inserter, który zawiera konfigurację naszego analizatora. Klikamy OK. Powinien pojawić się plik pierwszy_analizator.rva w drzewku projektowym w katalogu Debug Files. Otworzy się okno konfiguracji wyzwalaczy programu Reveal Analyzer, który wygląda bardzo podobnie do Reveal Inserter (rysunek 6). Mamy możliwość modyfikacji wcześniej zdefiniowanych wyzwalaczy. Ponadto, jeżeli zostało zdefiniowane kilka pozycji w sekcji Trigger Expression to możemy je włączać lub wyłączać w zależności od potrzeb.

Rysunek 6. Konfiguracja wyzwalaczy w Reveal Inserter

Przejdźmy do sekcji Trigger Options. W polu wyboru Enable TE możemy zdefiniować jaki spójnik logiczny ma łączyć wszystkie zdefiniowane Trigger Expression. My zdefiniowaliśmy tylko jeden (TE1), więc ta opcja nie ma dla nas znaczenia. Poniżej ustawiamy Sample Per Trigger oraz Number of Trigger. Liczby możliwe do skonfigurowania w tych opcjach zależne są od sumarycznej liczby próbek w pamięci, zdefiniowanej w Buffer Depth. Wybierzmy 32 sample na trigger oraz liczbę triggerów ustawiamy na 4.

W sekcji Trigger Position możemy określić, ile próbek chcemy obserwować przed i po wystąpieniu wyzwalacza. Proponuję wybrać opcję Pre-Trigger. Jeżeli zaznaczymy User Selected, wówczas przesuwając pasek po prawej stronie będziemy mogli dowolnie wybrać liczbę widocznych próbek przed i po sygnale wyzwalającym. W górnej części okna klikamy zielony przycisk strzałki w prawo. Zostaniemy przeniesieni do widoku sygnałów. Status widoczny w lewym górnym narożniku zmieni się na Connecting, a po chwili zobaczymy Running. Oznacza to, że analizator pracuje i oczekuje na sygnał wyzwalający. Wciskaj przyciski Up i Down, które są połączone z FPGA. Każde wciśnięcie powinno zostać zarejestrowane jako wyzwolenie analizatora. Po czterech wciśnięciach, wszystkie dane zostaną przesłane do komputera i przedstawione w postaci wykresu, co widzimy na rysunku 7.

Rysunek 7. Przebiegi sygnałów zarejestrowane przez Reveal

Sygnały wyzwalacza zarejestrowane są różową pionową linią, a żółte linie oddzielają cztery cykle pracy. Klikając w dowolne miejsce na wykresie, przesuwamy kursor, który jest czerwony. W kolumnie Data możemy odczytać wartości wszystkich sygnałów. Możemy zmienić format liczb z binarnego na dziesiętny lub szesnastkowy, aby stan licznika był czytelniejszy. W tym celu w kolumnie Data klikamy wybraną wartość, a następnie wybieramy Dec lub Hex.

Klikając i przeciągając kursor myszki możemy zmierzyć długość zaznaczonego fragmentu. Domyślnie tej czas podawany jest w liczbie taktów zegara. Możemy tę liczbę automatycznie przeliczyć na czas. W tym celu klikamy prawym przyciskiem na tło i wybieramy opcję Set Clock Period, a następnie wpisujemy częstotliwość lub okres sygnały zegarowego. Wybierając Add Cursor możemy dodać kilka dodatkowych kursorów, aby zaznaczyć interesujące momenty.

Patrząc na sygnały DebounceUp/NoisySignal oraz DebounceDown/NoisySignal przedstawione na rysunku 7 widzimy, kiedy naciskałem przyciski – jest to widoczne jako zmiana stanu tych sygnałów z 0 na 1. Następnie uruchamia się licznik Counter w modułach Debounce, którego zadaniem jest sprawdzenie czy przycisk został wciśnięty odpowiednio długo czy zmiana stanu jest spowodowana tylko krótkotrwałym drganiem styków przycisku. Kiedy licznik zliczy żądaną liczbę taktów zegarowych, wtedy sygnał FilteredSignal zmienia swój stan z 0 na 1. Ten z kolei doprowadzony jest do modułu EdgeDetector, który zajmuje się wykrywaniem zbocza rosnącego. Jeżeli takie zbocze zostanie wykryte, wówczas na wyjściach tych modułów, nazwanych RequestUp i RequestDown pojawia się stan wysoki tylko przez jeden takt zegara. Następnie, licznik Counter0/Value jest zwiększany lub zmniejszany o 1. W linii na samym dole widzimy stan licznika, który przyjmuje wartości 1, 2, 3, 4, 3 (akurat różowa linia wyzwalacza została narysowana dokładnie w miejscu, gdzie jest cyfra stanu licznika).

Możemy ponownie uruchomić analizator, klikając ten sam przycisk zielonej strzałki. Możemy także wrócić do ustawień wyzwalania i zmienić konfigurację. Możemy zmieniać do woli konfigurację wyzwalaczy, a następnie wystarczy tylko kliknąć przycisk zielonej strzałki. Niestety jednak w Reveal Analyzer nie możemy zmienić wszystkiego i czasami będzie konieczna modyfikacja w Reveal Inserter. Pamiętaj, że zmiana czegokolwiek w programie Reveal Inserter powoduje konieczności ponownego wygenerowania analizatora, syntezy i wgrywania bitstreamu.

Z ciekawszych opcji, jakich jeszcze nie omawialiśmy jest Token Set Manager, który znajdziemy w menu Design, ale tylko wtedy, kiedy Reveal Analyzer jest otwarty. Przy pomocy tego narzędzia możemy zdefiniować słowne etykiety dla różnych wartości liczbowych. Taka funkcjonalność jest przydatna do analizowania automatów stanów. Może się także przydać, by łatwiej było rozpoznawać instrukcje, wykonywane przez procesor.

Ostatnią rzeczą, jaką powinniśmy wykonać, jest wyłączenie analizatora z obecnej implementacji. Analizator nie będzie nam potrzebny w finalnej aplikacji, ale warto go zachować, zamiast bezpowrotnie usuwać. W drzewku projektu kliknij prawym przyciskiem myszy na plik pierwszy_analizator.rvl i następnie wybierz Set as Inactive. Dzięki temu możemy syntezować kod bez analizatora, a jeżeli będziemy chcieli ponownie go wykorzystać, wtedy klikamy ten plik prawym przyciskiem myszy i wybieramy Set as Active Debug File.

W następnym odcinku kursu poznamy podstawy symulacji. Podstawy, ponieważ symulacja to temat bardzo obszerny i też bardzo czasochłonny. Symulowanie i testowanie układów w symulatorze zajmuje zdecydowanie więcej czasu niż zabawa z analizatorem Reveal, jednak ma istotne zalety.

Dominik Bieczyński
leonow32@gmail.com

Czytaj więcej:
[1] Reveal User Guide – https://bit.ly/3V5UxJn
[2] Reveal Troubleshooting Guide – https://bit.ly/3UORJ2Q

Artykuł ukazał się w
Elektronika Praktyczna
maj 2023
DO POBRANIA
Materiały dodatkowe
Elektronika Praktyczna Plus lipiec - grudzień 2012

Elektronika Praktyczna Plus

Monograficzne wydania specjalne

Elektronik grudzień 2024

Elektronik

Magazyn elektroniki profesjonalnej

Raspberry Pi 2015

Raspberry Pi

Wykorzystaj wszystkie możliwości wyjątkowego minikomputera

Świat Radio listopad - grudzień 2024

Świat Radio

Magazyn krótkofalowców i amatorów CB

Automatyka, Podzespoły, Aplikacje listopad - grudzień 2024

Automatyka, Podzespoły, Aplikacje

Technika i rynek systemów automatyki

Elektronika Praktyczna grudzień 2024

Elektronika Praktyczna

Międzynarodowy magazyn elektroników konstruktorów

Elektronika dla Wszystkich grudzień 2024

Elektronika dla Wszystkich

Interesująca elektronika dla pasjonatów