Elektroda.pl
Elektroda.pl
X
Proszę, dodaj wyjątek dla www.elektroda.pl do Adblock.
Dzięki temu, że oglądasz reklamy, wspierasz portal i użytkowników.

[cpld][vhdl] - 1szy projekt - Licznik do adresowania pamięci ROM

13 Paź 2015 01:12 2328 7
  • Poziom 16  
    Cześć!

    Po wielu nieudanych podejściach do stworzenia pierwszego poważniejszego projektu samemu postanowiłem zasięgnąć porady na elektrodzie.

    Zupełnie pierwsze kroki mam już za sobą (na 704-K Xilinx starter kit) - udało mi się rozrysować schemat, który zsyntetyzował się poprawnie ("migacz" diodą w zależności od naciśniętego przycisku).

    Poważniejszym projektem jest licznik, zaprezentowany na poniższym schemacie.

    [cpld][vhdl] - 1szy projekt - Licznik do adresowania pamięci ROM

    Licznik ten docelowo liczy +1 lub +256 w zależności od 4ch sygnałów wejściowych.

    Z powodu niedogodności związanych z edytowaniem tego schematu (edytor jest zwyczajnie niewygodny, wiesza się, nie można usuwać fragmentów połączeń, tylko całe gałęzie) jak i chęcią nauki VHDL, postanowiłem zrobić ten moduł od nowa, pisząc własnoręcznie program (szczególnie mając na uwadze nieczytelność/objętość kodu generowanego przy kompilowaniu schematu).

    O ile układ ze schematu niezbyt szczęśliwie ale jednak działał, uznałem ze potrzebuję również móc symulować zachowanie układu (sonda logiczna i 8-kanałowy analizator są na etapie projektowania/modelowania zdecydowanie znacznie mniej wygodne).

    Używam Xilinx ISE 10.1 oraz multisim 5.7.

    W skrócie sam układ powinien działać następująco:
    Gdy CS == 1 - nic się nie dzieje.
    Gdy CS == 0 - układ pracuje według następujących zmiennych:
    Zapis - resetuje licznik.
    odczyt gdy A0 == 0 daje licznik+1
    odczyt gdy A0 == 1 daje licznik+256

    Moje pytania:

    1. Czy poniższy kod ma szanse działać?
    2. Czemu poniższy kod wraz z dołączonym test benchem nie daje wykresów w multisim?

    jeśli brakuje w opisie detali jak układ ma się zachowywać, to proszę o zadawanie pytań.

    Kod: vhdl
    Zaloguj się, aby zobaczyć kod


    Kod: vhdl
    Zaloguj się, aby zobaczyć kod
  • Poziom 27  
    w testbench masz:
    COMPONENT counter PORT(clock : IN std_logic; clear : IN std_logic; ...
    w entity counter brak portow clock i clear;

    skad taki dziwaczny sposob zerowania?
    if lowCS = '0' and lowWR = '0' and lowRD = '1' and A0 = '1' then
    Pre_Q := Pre_Q - Pre_Q;


    napisales 'process' bez jakichkolwiek ograniczen czasowych [clk'event,risingedge],
    wiec ISE zrozumie taka linie:
    if A0 = '0' then Pre_Q := Pre_Q + 1;
    ze Pre_Q ma byc zwiekszane o '1' ciagle, "w czasie 0 sekund"
    a zapewne nie chodzi ci o to, by uklad wpadl w jakies drgawki

    j.
  • Poziom 16  
    J.A napisał:
    w testbench masz:
    COMPONENT counter PORT(clock : IN std_logic; clear : IN std_logic; ...
    w entity counter brak portow clock i clear;


    Czy sygnał clock jest potrzebny do pracy tego układu?
    Dodatkowy reset poza tym wynikającym z kombinacji zmiennych wejściowych nie jest mi potrzebny, usunę go więc z bench'a.

    Cytat:

    skad taki dziwaczny sposob zerowania?
    if lowCS = '0' and lowWR = '0' and lowRD = '1' and A0 = '1' then
    Pre_Q := Pre_Q - Pre_Q;



    Znalazłem gdzieś w internecie, uzasadnienie było takie, że to się lepiej syntezuje.

    Cytat:

    napisales 'process' bez jakichkolwiek ograniczen czasowych [clk'event,risingedge],
    wiec ISE zrozumie taka linie:
    if A0 = '0' then Pre_Q := Pre_Q + 1;[/]
    ze Pre_Q ma byc zwiekszane o '1' ciagle, "w czasie 0 sekund"
    a zapewne nie chodzi ci o to, by uklad wpadl w jakies drgawki

    j.


    Ok, to może by przyczyna, potrzebuje żeby przetwarzanie następowało przy opadającym zboczu CS, czy mogę użyć analogii stąd:
    http://stackoverflow.com/questions/18661936/set-and-reset-on-rising-and-falling-edge
    używając if falling_edge(lowCS) then... ?
  • Pomocny post
    Poziom 27  
    Rafraf napisał:

    Czy sygnał clock jest potrzebny do pracy tego układu?
    Dodatkowy reset poza tym wynikającym z kombinacji zmiennych wejściowych nie jest mi potrzebny, usunę go więc z bench'a.


    do pracy TEGO ukladu raczej tak,
    dobra inzynierska praktyka wymaga takze zerowania;

    Rafraf napisał:

    Znalazłem gdzieś w internecie, uzasadnienie było takie, że to się lepiej syntezuje.


    nie sadze by to sie lepiej syntetyzowalo niz zwykle 'X := 0';


    Rafraf napisał:

    Ok, to może by przyczyna, potrzebuje żeby przetwarzanie następowało przy opadającym zboczu CS, czy mogę użyć analogii stąd:
    http://stackoverflow.com/questions/18661936/set-and-reset-on-rising-and-falling-edge
    używając if falling_edge(lowCS) then... ?


    nie wydaje mi sie, by to byla dobra analogia, tam jest dyskutowany inny problem;

    w twoim przypadku powinienes po prostu logike licznika zamknac w:
    PROCESS (clk)
    IF (rising_edge clk) THEN

    if (lowCS = '0' then .....
    else if (A0 = '0') then ...
    else ...

    END IF;


    j.
  • Poziom 16  
    W międzyczasie projekt rozwinął się w dobrym kierunku, na symulatorze mam już takie przebiegi jakich oczekuję, aczkolwiek pojawił się problem zegara, bo jak mniemam ten układ potrzebuje zewnętrznego taktowania? Jeśli tak - jak skonfigurować piny odpowiedzialne za zegar dla fizycznego CPLD i w który pin się wpiąć? (widziałem, że jest tam kilka źródeł zegara)?
  • Poziom 20  
    Tak, potrzebuje zewnętrznego taktowania. Poszukaj w dokumentacji twojej płytki do którego pinu jest podpięty zegar i go normalnie przypisz (w *.ucf lub GUI) do sygnału 'clock'. Kilka źródeł zegara które widziałeś to są specjalne IO do którego można doprowadzić zegar - wszystko zależy od tego co tam fizycznie jest podłączone.

    Pozdrawiam
  • Poziom 16  
    W toku rozwoju projektu pojawiają się kolejne pytania:
    czy te liczniki muszą mieć zewnętrzny zegar aby działać?

    Czy zliczanie według zasad podanych w pierwszym poście mogłoby mi zapewnić zmodyfikowanie kodu

    Code:

    PROCESS (clk)
    IF (rising_edge clk) THEN


    tak aby był uwarunkowany na:

    Code:

    IF (falling_edge A0) THEN


    Jak się okazało urządzenie nadrzędne nie przekazuje zegara a ja sobie używałem syntetyczny do symulacji.
  • Poziom 20  
    Liczniki potrzebują zegara, a dokładniej jego zbocza do zatrzaśnięcia kolejnych wartości.
    Jeżeli licznik ma się inkrementować przy odczycie to można go taktować (zatrzaskiwać kolejne wartości) sygnałem 'lowRD'. Musisz wtedy zwrócić uwagę w jaki sposób urządzenie nadrzędne generuje sygnały sterujące. Gdy zostanie wystawiony sygnał odczytu i zmieniony adres A0 to nic się na wyjściu nie zmieni, bo nie było zbocza na lowRD. Urządzenie nadrzędne może się wtedy spodziewać że odczytuje dane z adresu powiększonego o dwa.

    Można by to obejść używając do taktowania generator kwarcowy który jest zamontowany na twoim kicie, a inkrementowanie licznika odbywało by się po wykryciu zmiany stanu na 'lowRD' lub 'A0'. Jednak to rozwiązanie zwiększy pobór mocy, zużycie zasobów i wymaga zegara(co komplikuje nieco sprawę jeśli chciałbyś przenieść układ poza kit ).

    Wszystko zależy od tego jakiego działania oczekujesz.

    Pozdrawiam