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

machxo2/verilog - nie działają połączenia wire między licznikami - początkujący

piotrva 29 Mar 2013 10:53 2526 15
  • #1 29 Mar 2013 10:53
    piotrva
    Moderator na urlopie...

    Witam serdecznie!
    W temacie FPGA jestem zupełnie zielony - w praktyce z układami miałem styczność od 2 dni, ale podjąłem wyzwanie nauczenia się języka opisu sprzętu jakim jest verilog.
    Jako jeden z kodów które napisałem powstało coś takiego:

    Kod: verilog
    Zaloguj się, aby zobaczyć kod

    I wszystko pięknie działa (piny led i wejścia przypisane oczywiście do odpowiednich wyprowadzeń układu MACHXO2-7000HE). Jednak, jak pewnie Koledzy zauważą, staram się połączyć 2 4-bitowe liczniki. Jednak gdy zmienię drugą linijkę na:
    Kod: verilog
    Zaloguj się, aby zobaczyć kod

    To niestety wszystkie linie LED ustawiają się w stan HI-z.
    Pewnie popełniam jakiś podstawowy błąd, dlatego proszę Was o pomoc i naprowadzenie co jest nie tak z moim rozumowaniem.
    Z góry bardzo dziękuję za pomoc i inną konstruktywną krytykę kodu.
    PR

    0 15
  • Arrow Multisolution Day
  • Pomocny post
    #2 29 Mar 2013 13:19
    J.A
    Poziom 27  

    Code:
    always begin 
    
          if (count == 4'b0000) begin
             borrow <= 1;
          end else begin
             borrow <= 0;
          end


    to jest hardware, nie mozesz zalozyc, ze wszystkie
    4 bity count zmienia swoja wartosc w tej
    samej chwili, przejscie z 1000 na 0111 moze przez
    chwile wygenerowac krotki impuls na borrow;
    jesli ten sygnal uzywasz dalej jako zegar, dostaniesz
    falszywe przelaczenie;
    borrow uzyj jako clock enable;


    Code:
    licznik l1(m_clk, m_rst, {led[3],led[2],led[1],led[0]}, borrow12)

    dozwolone, ale bardzo 'bledno-genne';
    nieco wiecej pisania, ale od razu widac co jest polaczone z czym:
    Code:

    licznik l1
     (.clk(m_clk), .rst(m_rst),
      .count(led[3:0]) ...itd );


    rst uzyte jako zerowanie asynchroniczne
    [niezalezne od zegara] - dozwolone, jesli sam sygnal
    rst jest gdzies indziej dosynchronizowany do zegara,
    inaczej na pewno uklad bedzie wchodzil w dziwne, nieustalone stany,
    oczywiscie uklad bardziej skomplikowany niz ten przyklad;

    'moja' wersja:

    Code:
    module licznik
    
    (
       input            clk, rst, borrow_in,
       output           borrow_out,
       output reg [3:0] count
    );
     
       always @ (posedge clk or posedge rst)
          if(rst)
              count <= 4'b1111;
            else if (borrow_in)
              count <= count - 1'b1; // tak unikniesz ostrzezenia kompilatora
     ///    else count <= count;
                 
    assign borrow_out = (count == 4'b0000);
     
    endmodule
     
    module top
    (
       input        clk, rst,
       output [7:0] led,
       output       borrow
    );
       wire borrow12;
       
       licznik l1(.clk(clk)             .rst(rst),
                   .borrow_in(1'b1),     .borrow_out(borrow12),
                   .count(led[3:0]));
                   
        licznik l2(.clk(clk)             .rst(rst),
                   .borrow_in(borrow12), .borrow_out(borrow),
                   .count(led[7:4]));
       
    endmodule

    0
  • #3 29 Mar 2013 14:01
    piotrva
    Moderator na urlopie...

    Witaj,
    Wielkie dzięki za odpowiedź. Zaraz to sprawdzę.
    A powiedz mi dlaczego moje rozwiązanie nie działało?
    Jeśli chodzi o borrow to na pewno impuls był generowany, bo wcześniej to sprawdzałem analizatorem stanów logicznych, jednak jaki był powód tego, że układ wogóle nie uruchamiał się, tylko linie szły w hi-z?

    0
  • Pomocny post
    #4 29 Mar 2013 14:20
    J.A
    Poziom 27  

    a jak stwierdziles, ze wyjscia sa hi-z ?
    co zmierzyles/sprawdziles/zaobserwowales ?

    sam kod rtl w zaden sposob nie powinien ustawiac
    wyjsc w h-z;

    j.a

    0
  • Arrow Multisolution Day
  • #5 29 Mar 2013 14:31
    piotrva
    Moderator na urlopie...

    Stwierdziłem tak na podstawie tego, że po zwarciu m_clk na stałe do masy diody świeciły słabym światłem (zupełnie takim jak podczas programowania, gdzie na pewno są w HI-z, a przede wszystkim analizator nie wykazał żadnych zmian na tych pinach.

    EDIT:
    Podobnie zachowywał się taki kod:

    Kod: verilog
    Zaloguj się, aby zobaczyć kod

    tu też o1 i o2 były HI-z, ale za to za radą @leonw32 taki kod:
    Kod: verilog
    Zaloguj się, aby zobaczyć kod

    już działał...
    Chciałbym przede wszystkim zrozumieć dlaczego tak się dzieje...

    0
  • Pomocny post
    #6 29 Mar 2013 15:06
    alagner
    Poziom 25  

    Tzn. różnią się one tylko in- i outputami w nagłówku?
    To może chodzi o przyjętą wersję Veriloga, nie znam softu Lattice'a i ichniej implementacji tego, ale spróbuj przestawić np. na Verilog-2001 albo jeszcze lepiej na SystemVerilog.

    EDIT: Bo rozumiem, że w pin plannerze czy Lattice'owskim odpowiedniku takowego masz wyprowadzenia odpowiednio przypisane?

    0
  • #7 29 Mar 2013 15:45
    piotrva
    Moderator na urlopie...

    Tak, jak pisałem za każdym razem sprawdzam przypisanie wyprowadzeń.
    Spróbuję dziś wieczorem, jak znowu będę przy sprzęcie działania kodu Kolegi @J.A. oraz zbadam kwestię wersji veriloga (jeśli możecie mi ułatwić zadanie to byłbym wdzięczny za wskazówkę gdzie szukać, jak nie to poszukam sam tego).
    A różnią się one przede wszystkim chyba brakiem deklaracji połączeń jako wire...

    0
  • Pomocny post
    #10 29 Mar 2013 18:57
    alagner
    Poziom 25  

    Piotrze, a spróbuj jeszcze zamiast:
    always

    dać

    always @(*)

    Bo u mnie np. przy generacji schematu RTL wywala błąd

    E:/Alagner/Dokumenty/Lattice/liczniki/licznik.v(17,2) ERROR: (ST-6002) Always Block 'licznik_uniq_1.always' does not have a delay or sensitivity list, possible simulation hang.
    E:/Alagner/Dokumenty/Lattice/liczniki/licznik.v(17,2) ERROR: (ST-6002) Always Block 'licznik_uniq_2.always' does not have a delay or sensitivity list, possible simulation hang.

    Myślałem, że always bez niczego jest tożsame z always @(*) ale jednak nie ;)
    Poza tym: borrow ma być synchroniczny czy asynchroniczny (kombinacyjny)?
    Bo jeśli ten drugi, to użyj przypisań blokujących. Jeśli synchroniczny, to ok - ale musisz go też resetować. No i dodać clk na listę czułości.

    0
  • Pomocny post
    #11 29 Mar 2013 19:07
    J.A
    Poziom 27  

    piotrva napisał:

    Podobnie zachowywal sie taki kod:
    Kod: verilog
    Zaloguj się, aby zobaczyć kod

    Kod: verilog
    Zaloguj się, aby zobaczyć kod

    Chcialbym przede wszystkim zrozumiec dlaczego tak sie dzieje...


    tez chcialbym zrozumiec ...
    oba przyklady powyzej sa funkcjonalnie identyczne,
    verilog jako default przyjmuje, ze sygnaly sa wire, jesli nie
    zadeklarujesz inaczej: "`default_nettype none";
    dla samej nauki veriloga te 'wpadki' nie maja wiekszego znaczenia,
    zachowanie ktore opisujesz wydaje sie specyficzne dla konkretnej
    kostki/plytki ktorej uzywasz, ew. kompilator Lattice robi
    dziwne, niestandardowe rzeczy [choc tego bym akurat nie podejrzewal,
    bo to porzadna firma], bez fizycznego dostepu do hardware'u trudno
    znalezc przyczyne takiego zachowania;

    w kodzie rtl NIE MA zadnych przeslanek, by kompilator
    uzywal na wyjsciu buforow 3-stanowych


    podobnie w kodzie dwoch licznikow w twojej i mojej wersji;
    nie przychodzi mi do glowy zadna przyczyna, dla ktorej
    wyjscia mialyby byc ustawione w stan 'Z' w ktorymkolwiek
    przytaczanym przez ciebie przykladzie;

    jesli chcesz potrenowac verilog, sciagnij od altery quartus 9.1
    i symuluj swoje kody - wprawki, ten symulator symuluje tzw. netliste,
    czyli wynik kompilacji wraz z opoznieniami, wielce wiarygodnie
    oddajac zachowanie prawdziwego sprzetu, jednoczesnie dajac wglad
    zachowanie kazdego punktu projektu;
    znacznie bardziej efektywne i pouczajace niz mruganie diodami;

    j.a

    0
  • #13 29 Mar 2013 20:34
    J.A
    Poziom 27  

    jeszcze jedno - jaka jest czestotliwosc zegara m_clk ?
    jesli wiekasza niz kilkanascie Hz, to diody beda mrozyc,
    nawet jesli twoje liczniki dzalaja mniej wiecej poprawnie;

    j.a

    0
  • #14 29 Mar 2013 20:50
    piotrva
    Moderator na urlopie...

    :) Takie oczywiste oczywistości oczywiście przemyślałem - na wyprowadzenie m_clk podawany jest sygnał z generatora sterowanego komputerowo o częstotliwości 2Hz i wypełnieniu 50% - taki banał od jednego dnia bym zauważył, poza tym wtedy powiedziałbym też, że wersja w której 2 liczniki działają równolegle też nie działa ;)

    0
  • Pomocny post
    #15 29 Mar 2013 22:56
    leonow32

    Poziom 30  

    piotrva napisał:
    Hmm, zobaczymy co jeszcze kol. @leonow32 powie - bo ma ten sam sprzęt. Ja za parę godzinek siądę do tego i jeszcze się pozagłębiam w to.


    A co ja ekspert jakiś? :D jestem dopiero na etapie generatorów PWM :D

    Program jaki wrzuciłeś na forum działa u mnie. Wywaliłem śmieci z pliku LPF i dodałem wbudowany generator RC i już nie potrzeba zegara z zewnątrz. Trochę to uprościłem, wywaliłem borrow i zegar drugiego licznika biorę z najstarszego bitu licznika pierwszego.

    Kod: verilog
    Zaloguj się, aby zobaczyć kod


    Dodano po 25 [minuty]:

    Hej właśnie zauważyłem jedną rzecz - w Twoim projekcie używasz syntezatora Lattice LSE a ja SynplifyPRO. Kod z powyższego postu przetrawiony przez Lattice LSE również powoduje, że diody się żarzą. Jeśli wybierze się SynplifyPRO - wszystko działa. Bug jakiś?

    Wybierz Project - Synthesis Tool - SynplifyPRO i powinno od razu wszystko ruszyć.

    0
  • #16 30 Mar 2013 00:09
    piotrva
    Moderator na urlopie...

    Zaraz, zaraz, czyli kod przedstawiony przeze mnie w pierwszym poście tego wątku (z borrow12 jako zegar drugiego licznika) działa u Ciebie? Jeśli tak to czy mógłbyś załączyć cały Swój projekt?
    Nie wiem jakim cudem, ale ja mam u siebie ustawione Synplify PRO - na Lattice LSE to wogóle nic nie działało...

    leonow32 napisał:
    A co ja ekspert jakiś? :D jestem dopiero na etapie generatorów PWM :D

    Ale za to masz ten sam sprzęt i IDE

    Dodano po 20 [minuty]:

    Hahahaha
    Hahaha
    Haha
    Ha
    ...
    Panowie, wielkie dzięki wszystkim za zainteresowanie tematem. Mieli rację wszyscy mówiący, że problem nie leży w kodzie (acz dziękuję za zwrócenie uwagi na różne mankamenty tego kodu).

    Mianowicie podczas programowania układu od razu do pamięci SRAM mamy do wyboru 2 opcje: SRAM Fast Program i SRAM Erease,Program,Verify.
    Ja korzystałem z tej pierwszej i zapewne musiała nie kasować jakichś połączeń (ustawionych np. przez design wgrany do flasha) i stąd zamieszanie. Ustawienie tej drugiej opcji usunęło wszystkie problemy jak ręką odjął ;)

    A więc podsumowując całe rozważania (pomijając poprawność merytoryczną przedstawionego przeze mnie kodu, bo poprawny on nie jest - teraz widzę błędy w działaniu i nieodpowiedni moment wystawiania borrow12):
    1. Koniecznie należy ustawiać podczas programowania, nawet bezpośrednio do SRAM, cykl Erease,Write,Verify - inaczej narażamy się na nieoczekiwane, niemalże losowe błędy.
    2. Sprawdziłęm Lattice LSE i Synplify PRO na kodzie z pierwszego postu - oba teraz działają

    Temat do zamknięcia bo moja nauka poprawnego projektowania układów w Verilogu to już inny temat, a przedstawiony problem wynikał z innego "drobnego szczegółu" - a jak wiemy w elektronice zawsze diabeł tkwi w szczegółach ;)

    0