Elvis Napisano Listopad 26, 2017 Udostępnij Napisano Listopad 26, 2017 W komentarzach wątku Kurs FPGA - #7 - symulacja działania układu pojawił się pomysł rozszerzenia kursu o własne doświadczenia i wiadomości. Pozwólcie, że rozpocznę bardzo krótkim programikiem. W części #4 kursu opisywany był przykładowy program z migającą diodą. Tym co mnie nieco zaskoczyło było używanie if-a do wykrywania zakresu licznika. Takie rozwiązanie jest bardzo dobre, bo pozwala na dowolny wybór zakresu licznika, ale wydawało mi się że jest mało optymalne w układach cyfrowych. Czytając nieco o FPGA znalazłem inną implementację, którą chciałbym opsiać. Zamiast zliczać do pewnej wartości, tworzymy n-bitowy licznik. Taki licznik po przekroczeniu sam wróci do zera. Zobaczmy jakie wartości miałby licznik 3-bitowy: 000001 010 011 100 101 110 111 Kolejna wartość to zero i licznik sam zacznie działać od początku. A jak taki licznik można wykorzystać jako dzielnik częstotliwości? Wystarczy, że weźmiemy najwyższy bit. Mając odpowiednio większy licznik możemy migać diodami nie używając if-a. Mój programik wygląda następująco: library IEEE; use IEEE.STD_LOGIC_1164.ALL; use IEEE.STD_LOGIC_UNSIGNED.ALL; use IEEE.NUMERIC_STD.ALL; entity blink2 is Port ( clk : in std_logic; led : out std_logic_vector(7 downto 0) ); end blink2; architecture Behavioral of blink2 is constant NBit : integer := 24; signal licznik : std_logic_vector(NBit-1 downto 0); begin blink: process(clk) begin if rising_edge(clk) then licznik <= licznik + 1; end if; end process; led <= (others => licznik(NBit-1)); end Behavioral; Nie wiem, czy jest w czymkolwiek lepszy niż oryginał ale chciałem go zaprezentować na początek żeby pokazać dlaczego potęgi dwójki w dzielnikach, czy częstotliwościach są często używane w układach cyfrowych. To po prostu wiele ułatwia 🙂 1 Cytuj Link do komentarza Share on other sites More sharing options...
marek1707 Listopad 26, 2017 Udostępnij Listopad 26, 2017 "Wystarczy, że weźmiemy najwyższy bit.." Tylko że nikt tak nie robi. Biorąc stan któregokolwiek bitu jako sygnał do taktowania czegoś innego (bo obserwacja LEDów to tylko zabawa), wchodzisz w obszar układów asynchronicznych a to bardzo niepopularne i niebezpieczne. Odpowiednikiem tego jest dodawanie krótkich delay'ów w skomplikowanym programie by ten zaczął działać gdy nie umiesz w inny sposób zapewnić prawidłowej synchronizacji procesów. Na jednej maszynie się uda, ale na drugiej program zwiśnie. Oczywiście dzielniki częstotliwości są często wykorzystywane, ale nawet jeśli masz podział przez 2^n robisz to wyłącznie za pomocą detektora ostatniego (same jedynki) lub pierwszego (same zera) stanu licznika, który to detektor także jest przerzutnikiem synchronicznym taktowanym tym samym zegarem co licznik. Dostajesz wtedy impulsy o długości jednego zegara umieszczone co 2^n taktów. Dopiero to możesz swobodnie wykorzystać do odpalania kolejnych bloków w tej domenie zegara, ale wciąż jako sygnał kwalifikatora a nie zegar. Możesz też np. zrobić wybór bitu licznika multiplekserem (asynchronicznym blokiem kombinacyjnym), ale jego wyjście musisz znowu przepuścić przez synchronizator by odtworzyć czasy ustalania i przetrzymywania (setup/hold time) dla następnych stopni. A następnym stopniem powinien być rzecz jasna detektor zbocza narastającego (dwa przerzutniki), z którego dostajesz już wyżej opisany krótki impuls co 2^n zegarów. To właśnie z tego powodu FPGA są tak bogate w przerzutniki i to z tego powodu podstawowe komórki FPGA wyglądają jak funkcja kombinacyjna kilku zmiennych zakończona przerzutnikiem. Dodawanie stopni synchronizacji nic nie kosztuje (bo i tak tam są) a skutkuje szybszą, przewidywalną i bezproblemową pracą całości. Podejście asynchroniczne jest trudno testowalne i bardzo podatne na problem wyścigów szczególnie wtedy gdy sygnały z różnych domen zaczynasz łączyć razem. Najlepiej w swoich projektach załóż sobie jako warunek konieczny, by wszystkie sygnały jakie generujesz były synchroniczne do jednego, głównego, wspólnego zegara. Nigdy nie produkuj z niego żadnych innych wolniejszych zegarów do asynchronicznego taktowania czegokolwiek. Dopiero gdy nabierzesz wprawy, gdy już swobodnie będziesz korzystał z symulacji i rozumiał działanie nawet skomplikowanych bloków cyfrowych możesz próbować świadomie generować i stosować różne zegary. I to wciąż z dużą uwagą i przemyśleniem czy to naprawdę jest konieczne. A praktycznie nigdy nie jest. Cytuj Link do komentarza Share on other sites More sharing options...
Elvis Listopad 26, 2017 Autor tematu Udostępnij Listopad 26, 2017 Jak zwykle Marku dużo napiasłeś, dziękuję. Możliwe że nieprecyzyjnie się wyraziłem, nie chodziło mi o używanie najwyższego bitu jako wygnału zegarowego. Faktycznie, tak kiedyś próbowałem robić, ale to nie było dobre rozwiązanie. Ale dlatego chciałem założyć wątek o FPGA - żeby można było podyskutować lepsze i gorsze rozwiązania 🙂 Chociaż faktycznie, może i użycie tego bitu do sterowania led-em to nie najlepszy pomysł. [ Dodano: 26-11-2017, 16:55 ] A skoro jesteśmy przy temacie poprawniej implementowanych dzielników. Marku, czy chodziło Ci mniej więcej o coś takiego? library IEEE; use IEEE.STD_LOGIC_1164.ALL; use IEEE.STD_LOGIC_UNSIGNED.ALL; entity divider is generic(N : natural); port (clk_in : in std_logic; clk_out : out std_logic); end divider; architecture Behavioral of divider is signal cnt : integer range 0 to N-1; begin process(clk_in) is begin if rising_edge(clk_in) then if cnt = N-1 then cnt <= 0; clk_out <= '1'; else cnt <= cnt + 1; clk_out <= '0'; end if; end if; end process; end Behavioral; Cytuj Link do komentarza Share on other sites More sharing options...
marek1707 Listopad 26, 2017 Udostępnij Listopad 26, 2017 W projektach używam Veriloga a VHDL jest dla mnie językiem read-only, mimo kilku podejść i szczerych chęci jakoś nigdy go nie polubiłem.. O ile dobrze rozumiem co napisałeś, to tak. Synchroniczne zmiany wyjścia clk_out są tym o co postulowałem. Sama nazwa sygnału jest trochę myląca, ale to już kwestia gustu. Trzy literki 'clk' zawsze zostawiam dla prawdziwych zegarów. EDIT: Użycie do sterowania LEDem jest OK, przecież to tylko wprawko-zabawa. Ponieważ jednak jest to jakieś odniesienie do forbotowego kursu i czytają to rzesze młodych (jeszcze niezrażonych) entuzjastów FPGA 🙂 warto chyba takie szczegóły podkreślać. Inaczej można się szybko zaplątać w szczegóły implementacji liczników czy rejestrów (niech już będzie) przesuwnych tracąc z oczu kwestie podstawowe. Nawet wyjadacze z czasów kostek TTL mają manię optymalizacji każdej bramki czy przerzutnika, bo tam każdy scalak to było miejsce na PCB, prąd i koszt. Dlatego zegarki (stołowe) były robione na asynchronicznych 7490 a interfejsy enkoderów kwadraturowych na dziwnych kombinacjach dwóch przerzutników. To zostaje ludziom na całe życie a podejście do projektowania systemów w FPGA jest zupełnie inne, często dla takich ludzi zaskakujące. Moim zdaniem warto - oprócz pompowania wiedzy merytorycznej - takie podstawy w kursach podkreślać. Cytuj Link do komentarza Share on other sites More sharing options...
Polecacz 101 Zarejestruj się lub zaloguj, aby ukryć tę reklamę. Zarejestruj się lub zaloguj, aby ukryć tę reklamę. Produkcja i montaż PCB - wybierz sprawdzone PCBWay! • Darmowe płytki dla studentów i projektów non-profit • Tylko 5$ za 10 prototypów PCB w 24 godziny • Usługa projektowania PCB na zlecenie • Montaż PCB od 30$ + bezpłatna dostawa i szablony • Darmowe narzędzie do podglądu plików Gerber Zobacz również » Film z fabryki PCBWay
Elvis Listopad 26, 2017 Autor tematu Udostępnij Listopad 26, 2017 Dla mnie FPGA to tylko hobby, więc nie przywiązuję należytej uwagi do nazw niestety. Ale będę się bardziej starać od teraz 🙂 Faktycznie verilog jest mniej przegadany, tyle że jakoś wciągnęłem się w VHDL, więc na razie nie będę zmieniał. Chciałem zachęcić innych użytkowników do dzielenia się eksperymentami wykonanymi przy okazji kursu - dzielnik gdzieś podpatrzyłem i podobał mi się ze względu na minimalizm. Ale ogólnie fakt, że lepiej uważać na co się patrzy w internecie - więc zapomnijmy o wykorzystywaniu najwyższych bitów, postaram się w kolejnym lub kolejnych postach wkleić nieco poprawniejszy przykład z licznikiem i wyświetlaczem 7-segmentowym. Wszelkie uwagi mile widziane 🙂 Cytuj Link do komentarza Share on other sites More sharing options...
Kolumbryna22 Grudzień 2, 2017 Udostępnij Grudzień 2, 2017 Hej! Czy mógłby ktoś napisać prosty program do zapalenia diody przyciskiem?, ale wykorzystując diodę nie z płytki, tylko podłączając zewnętrzną przez rezystor do pinów GPIO. Z góry dziękuję za pomoc 🙂 Cytuj Link do komentarza Share on other sites More sharing options...
Elvis Grudzień 2, 2017 Autor tematu Udostępnij Grudzień 2, 2017 Kolumbryna22, nie bardzo rozumiem w czym jest problem - sam kod będzie właściwie identyczny, cała sztuczka to zmiana pliku ograniczeń. Mógłbyś nieco dokładniej opisać co chcesz zrobić i w czym jest problem? Cytuj Link do komentarza Share on other sites More sharing options...
Kolumbryna22 Grudzień 2, 2017 Udostępnij Grudzień 2, 2017 Program się kompiluje bez błędów, ale wciśnięcie przycisku nic nie zmienia (sprawdzałem napięcie potencjometrem na pinach) Program w VHDL library IEEE; use IEEE.STD_LOGIC_1164.ALL; entity obslugagpiodioda is port( DPSwitch: in STD_LOGIC; dioda: out STD_LOGIC); end obslugagpiodioda; architecture Behavioral of obslugagpiodioda is begin dioda <= not DPSwitch; end Behavioral; Przypisanie pinów w pliku ucf NET "DPSwitch" LOC = P70 | PULLUP | IOSTANDARD = LVCMOS33 | SLEW = SLOW | DRIVE = 12; NET "dioda" LOC = P31 | IOSTANDARD = LVCMOS33 | SLEW = SLOW | DRIVE = 12; __________ Komentarz dodany przez: Treker Kody programów należy umieszczać przez narzędzie KOD (znajdziesz je w edytorze pod ikonką "<>"). Dzięki niemu składania programów jest automatycznie kolorowana, a wtedy wszystkim znacznie łatwiej analizować wklejone programy. Proszę to poprawić - z góry dziękuję za zrozumienie i pomoc przy utrzymaniu porządku na forum. Cytuj Link do komentarza Share on other sites More sharing options...
Elvis Grudzień 2, 2017 Autor tematu Udostępnij Grudzień 2, 2017 Przepisałem program i wszystko działa - sprawdź czy nie masz jakiegoś błędu w połączeniu. Cytuj Link do komentarza Share on other sites More sharing options...
Kolumbryna22 Grudzień 3, 2017 Udostępnij Grudzień 3, 2017 Podpiąłem jeszcze raz i działa jak należy. Wcześniej chyba na płytce stykowej coś się nie połączyło. Dzięki Elvis za pomoc 🙂 Cytuj Link do komentarza Share on other sites More sharing options...
Pomocna odpowiedź
Dołącz do dyskusji, napisz odpowiedź!
Jeśli masz już konto to zaloguj się teraz, aby opublikować wiadomość jako Ty. Możesz też napisać teraz i zarejestrować się później.
Uwaga: wgrywanie zdjęć i załączników dostępne jest po zalogowaniu!