FPGA, VHDL detekcja zbocza i problemy

May 22, 2009 10 Replies

Witam, pracuje ostatnio nad urządzeniem pośredniczącym między kontrolerem IDE z komputera a dyskiem twardym. Całość testuje na płytce startowej altera cyclone II starter board (http://

formatting link
.



Sygnały interfejsu ata idą do płytki startowej przez bufory 74lvc244 (sygnały sterujące) oraz '245 (dwukierunkowe linie danych).



Z podłączeniem wszystko okej, opisuje VHDLem prosty kawałek kodu który modyfikuje odpowiedź dysku na IDENTIFY DEVICE i to działa ładnie, transparentnie, bezproblemowo, ale mam problem, kiedy próbuje np. wykryć zbocze sygnału DIOR idącego z hosta.



Sygnał ten zgodnie ze specyfikacją ATA może mieć okres minimum 120ns (mowa o trybie Multiword DMA2). Zegar taktujący układ to 50MHz przepuszczone przez wbudowane PLL (3*50MHz)=150MHz. Nie powinno być więc problemów z wykrywaniem zmian sygnału DIOR bo częstotliwość ta jest wielokrotnie wyższa....



Niestety to tylko teoria, w praktyce prawie połowę zboczy sygnału HOST_DIOR_N "gubie", kiedy próbuje je wykrywać w procesie zsynchronizowanym z głównym zegarem...



Prosty przykład:



process(CLK,KEY0) begin if KEY0='0' then debug_cnt<=(others=>'0'); dior_edge<='0'; elsif CLK'event and CLK='1' then if HOST_DIOR_N='1' and dior_edge='0' then debug_cnt<=debug_cnt+1; dior_edge<='1'; else dior_edge<='0'; end if; end if; end process;



Moim skromnym zdaniem powinno to zliczać w debug_cnt ilość wystąpień narastających zboczy sygnału HOST_DIOR_N, który jest kilkanaście razy wolniejszy od CLK... I co się okazuje? Zmienna debug_cnt zawiera około połowę mniejszą wartość niż powinna....



Przykład drugi:



process(HOST_DIOR_N,KEY0) begin if KEY0='0' then debug_cnt<=(others=>'0'); elsif HOST_DIOR_N'event and HOST_DIOR_N='1' then debug_cnt<=debug_cnt+1; end if; end process;



W tym przypadku debug_cnt zawiera już właściwą wartość, zgodną z ilością zboczy narastających sygnału HOST_DIOR_N. Ja potrzebuję jednak mieć synchronizację z CLK głównym więc nie mogę sobie pozwolić na takie rozwiązanie.



Przepraszam za przydługiego posta i dziękuję za wytrwałość w czytaniu oraz ewentualną pomoc w rozwiązaniu problemu...



pozdrawiam.


HOST_DIOR_N jest synchroniczny z Twoim zegarem? Nie? To masz hazard. Daj przerzutnik D na noge Altery i opiero potem do 'if' - pomoze. Niestety wyjdzie Ci latencja 1CLK, i na to nie ma rady (chyba ze asynchronicznie wszystko zrobisz).

Tutaj HOST_DIOR_N nie musi byc synchronicznie z Twoim zegarem - dlatego dziala.

Ja tu widzę inny (niż widzi Jerry) problem. Nie wiem, czy on powoduje to o czym piszesz... teoretycznie może (przepełnienie ;))... Sam napisałeś, że sygnał HOST_DIOR_N jest *kilkanaście* *razy* *wolniejszy* od sygnału CLK. Rozumiem, że ma po prostu dłuższy okres i stan aktywny HOST_DIOR_N trwa ponad 1 cykl zegara CLK, tak?? To teraz przeanalizuj co się będzie działo w przypadku, gdy będziesz miał HOST_DIOR_N = 1 przez 10 taktów CLK. Kolejne numerki to kolejne zbocza narastające CLK

1) dior_edge = 0, więc dodajemy 1 i dajemy dior_edge<=1 2) poniewaz warunek HOST_DIOR_N='1' _and_ dior_edge='0' NIE JEST spełniony, "wykonywane" jest dior_edge<=0 !! 3) identyczny z 1) itd: 2=4=6=8=10 i 1=3=5=7=9 :)...

Efekt - zliczasz 5 impulsów, a chciałeś 1 ;)... wystarczy tego enda rozbić na dwa ify i będzie po sprawie ;)...

if HOST_DIOR_N='1' if dior_edge='0' then debug_cnt<=debug_cnt+1;**** dior_edge<='1'; else dior_edge<='0'; end if; W lini z **** na końcu nie jestem pewny czy nie trzeba dawać end if, nie pamiętam po prostu dokładnie składni VHDLa ;)...

Fakt, że zmienna powinna zawierać zdecydowanie większą wartość niż powinna, ale może przepełnienie robi swoje?? ;)... Nie wiem jak deklarujesz tę zmienną i ile teoretycznie możesz tam zliczać ;)...

Pozdrawiam Konop

Mógłbyś rozwinąć?? Bo szczerze mówiąc jeśli czas trwania "jedynki" w HOST_DIOR_N jest dłuższy niż okres zegara CLK, fakt synchroniczności zegarów nie ma tu nic do rzeczy! Tzn ma, bo ten kod jest napisany źle, ale to wyjaśniłem w innym poście w tym wątku. Nie wiem, czy chodziło Ci o to samo co mnie, czy nie bardzo?? Ja w każdym bądź razie nie widzę problemów, aby zliczać impulsy jednego sygnału synchronizując się innym sygnałem zegarowym, pod warunkiem, że będzie spełniona zależność czasowa: t_wejście_aktywne > Tclk :)

Pozdrawiam!! Konop

Sam sobie odpowiem!! Można to zrobić jeszcze tak: process(...) if HOST_DIOR_N='1' and dior_edge='0' then debug_cnt<=debug_cnt+1;**** end if; dior_edge<=HOST_DIOR_N; end process;

Wówczas możnaby nawet zmienić nazwę dior_edge na previous_dior albo last_dior czy coś w tym stylu ;)... W każdym bądź razie to takie "typowe" wykrywanie zobczy - mamy 1, a było 0, to jest zbocze ;)...

Pozdrawiam Konop

Nie bardzo. To o czym ja pisze wyjdzie tylko czasami - jest zalezne od sposobu optymalizacji i kompilacji. Optymalizator zalozy (chyba ze bedziesz mial jakies d-cell czy inne kurestwo bezposrednio na pinach) ze sygnal jest synchroniczny. Moga sie przez to dziac rozne (czesto nieoczywiste) cuda. Np: licznik do enkodera nie dziala ;-)

Inna sprawa - jak na to spojrzalem, to potem juz nie chcialo mi sie dalej analizowac. Inna sprawa, ze jak HOST_DIOR_N bedzie trwal 10 impulsow, to licznik policzy do 5 (w oryginalnym poscie). Tu az sie prosi o prosciutkie state-machine (szybciej to, niz myslec nad trzema if-ami).

Zobaczysz, zobaczysz... ino czasu troche potrzeba ;-) Czasami naprawde dziwne hazardy wychodza, np: dziala tylko z signal-tapem.

Rowniez!

A probowales obejrzec go oscyloskopem ?

Moze juz dawno nie ma 120ns ...

J.

/.../

/.../

moga wystepowac co najmniej 2 efekty, pierwszy opisal KONOP - wielokrotne zliczanie, jesli impuls mierzony ma okres dluzszy niz okres zegara mierzacego; opis drugiego efektu znajdziesz w watku:

formatting link
post wraz z obrazkiem symulacji; odsylam na elektrode, bo tam mozna zamieszczac obrazki, ktore wyjasniaja o wiele wicej, niz pisaniana na p.m.e J.A

Join the Discussion

Have something to add? Share your thoughts — no account required.

Didn't find your answer?

Ask the community — no account required