Guest
Fri May 22, 2009 3:40 pm
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://
www.kamami.pl/?id_prod=4520400).
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.
Jerry1111
Guest
Fri May 22, 2009 8:47 pm
krzysztof.jakubczyk@gmail.com wrote:
Quote:
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;
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).
Quote:
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.
Tutaj HOST_DIOR_N nie musi byc synchronicznie z Twoim zegarem - dlatego
dziala.
--
Jerry1111
Konop
Guest
Fri May 22, 2009 10:10 pm
Quote:
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;
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

...
Quote:
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....
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
Konop
Guest
Fri May 22, 2009 10:14 pm
Quote:
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).
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
Konop
Guest
Fri May 22, 2009 10:16 pm
Quote:
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

...
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
Jerry1111
Guest
Sat May 23, 2009 12:02 am
Konop wrote:
Quote:
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).
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??
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).
Quote:
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
Zobaczysz, zobaczysz... ino czasu troche potrzeba

Czasami naprawde
dziwne hazardy wychodza, np: dziala tylko z signal-tapem.
Quote:
Pozdrawiam!!
Rowniez!
--
Jerry1111
Guest
Sat May 23, 2009 6:40 am
On 23 Maj, 01:02, Jerry1111
<jerry1111alwaysattackedbys...@wp.pl.pl.wp> wrote:
Quote:
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).
Witam, przepraszam za wprowadzenie w blad. Podany przyklad pisałem "z
palca" żeby pokazać problem i faktycznie się pomyliłem z pośpiechu. W
Quartusie jednak napisałem tamto wykrywanie zbocza w sposób podobny do
Konopa no i skutek jest taki jak opisałem powyżej. Powoli koncza mi
sie pomysly i bedzie trzeba isc i zaobserwowac jak wygladaja te
sygnaly na jakims rejestratorze, bo wyglada to tak jakby DIOR_N mial
jednak okres porownywalny lub wrecz mniejszy od czestotliwosci CLK.
Wedlug specyfikacji taka sytuacja nigdy nie powinna miec miejsca. No
nic, dziekuje za rady w kazdym razie. Sprobuje jeszcze powalczyc sam
J.F.
Guest
Sat May 23, 2009 7:21 am
krzysztof.jakubczyk@gmail.com wrote:
Quote:
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....
A probowales obejrzec go oscyloskopem ?
Moze juz dawno nie ma 120ns ...
J.
Guest
Sat May 23, 2009 9:40 am
Wygląda na to, że zsynchronizowanie zewnętrznego sygnału poprzez
przerzutnik D załatwiło sprawę:
signal dior_n:std_logic;
HDD_DIOR_N<=dior_n;
process(CLK)
begin
if clk'event and clk='1' then
dior_n<=HOST_DIOR_N;
end if;
end process;
i teraz w kolejnym procesie licząc zbocza dior_n (tak jak w
poprzednich postach), mam właściwą
ilość.... Gdybym natomiast liczył bezpośrednio HOST_DIOR_N w procesie
zależnym od
CLK to dalej się krzaczy.
Może ktoś mi to z czystej ciekawości racjonalnie wyjaśni co dokładnie
się dzieje, w którym miejscu hazard, że gubie zbocza gdy nie stosuje
przerzutnika?
pozdrawiam i dziekuje za zainteresowanie tematem
Jerry1111
Guest
Sat May 23, 2009 10:09 am
krzysztof.jakubczyk@gmail.com wrote:
Quote:
Wygląda na to, że zsynchronizowanie zewnętrznego sygnału poprzez
przerzutnik D załatwiło sprawę:
signal dior_n:std_logic;
HDD_DIOR_N<=dior_n;
process(CLK)
begin
if clk'event and clk='1' then
dior_n<=HOST_DIOR_N;
end if;
end process;
i teraz w kolejnym procesie licząc zbocza dior_n (tak jak w
poprzednich postach), mam właściwą
ilość.... Gdybym natomiast liczył bezpośrednio HOST_DIOR_N w procesie
zależnym od
CLK to dalej się krzaczy.
Może ktoś mi to z czystej ciekawości racjonalnie wyjaśni co dokładnie
się dzieje, w którym miejscu hazard, że gubie zbocza gdy nie stosuje
przerzutnika?
Sygnal z pina idzie do wiecej niz jednej bramki/przerzutnika. Jesli
wezmiesz pod uwage opoznienia propagacji (a moga byc mocno rozne dla
dwoch roznych sciezek sygnalu), to czesto wychodzi ze jeden blok widzi
zbocze Twojego sygnalu przed, a inny po zdarzeniu CLK. I cala logika
glupieje, bo to jest stan 'zakazany'. Przez 'zakazany' tutaj rozumiem
to, ze VHDL moze zachowac sie dowolnie - tego nic ani nikt nie sprawdza,
na to nie ma optymizacji, nic absolutnie (nawet nie musi sie poprawnie
zachowac w nastepnym okresie zegara). Wstaw se SignalTap i popatrz na
wariant bez i z przerzutnikiem (moze byc problem - to nie zawsze idzie
zobaczyc; a jak Signaltap zmodyfikuje uklad to moze nawet zaczac dzialac).
Jest to klasyczny przyklad przechodzenia miedzy dwoma domenami zegarowymi.
--
Jerry1111
JA
Guest
Sun May 24, 2009 1:09 am
krzysztof.jakubczyk@gmail.com wrote:
/.../
Quote:
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...
/.../
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:
http://www.elektroda.pl/rtvforum/viewtopic.php?p=6016660&highlight=#6016660
ostatni 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