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

Wszystko o układach programowalnych... podstawowe informacje

marenc 09 Maj 2008 18:46 14679 95
  • #61
    J.A
    Poziom 27  
    mariuszlorenc napisał:
    /.../

    uwazasz, ze to dobry pomysl umieszczac wszystkie swoje
    pytania w tym samym watku ? [tytul co prawda jest wystarczajaco pojemny...]
    mnie to osobiscie obojetne, ale moim zdaniem bajzel sie robi;
    Cytat:
    Myślałem, że syntezator automatycznie da dwa przerzutniki/.../

    nie wyobrazam sobie, jak to zapisac w sposob jednoznaczny tak,
    by kompilator polapal sie ktory FF jest czuly na ktore zbocze;
    [w ramach syntaksu vhdl/verilog];
    musisz takie 2 FF dzialajace na rozne zbocza napisac sam,
    'recznie';
    a przy okazji - nie podzielam zdania pndemon, ze nalezy
    unikac przerzutnikow pracujacych na obu zboczach w jednym projekcie;
    jak trzeba, to mozna, ale trzeba to robic uwaznie :);

    mariuszlorenc napisał:
    proces w IF dotyczącym testowania ACTIVE?

    active uzyj jako 'clock enable', tak jak to podpowiedzial pndemon;

    J.A
  • IGE-XAO
  • #62
    marenc
    Poziom 24  
    Co do "all in one" miałem nadzieje, że pewien moderator się zlituje i w pierwszym poście skróci większość problemów. Być może sam się tym zajmę, aby inny początkujący nie mieli takich problemów ;)

    Napisałem program inaczej i działa. Większość moich problemów jest spowodowana "lenistwem" podczas pisania w C. I tu się przypominają piękne czasy pisania w ASM dla AVR :D

    Dodano po 10 [minuty]:

    No i wiedziałem, że będę musiał kiedyś zadać to pytanie. Program napisałem dla układu z 36 makrocell'ami, a zajmuje on 42(informacja z ISE) przez co nie fitter wyświetla błędy.

    W układach programowalnych nie jesteśmy w stanie oszacować pisząc program ile makroceli zajmie, tak? Można ją zmniejszyć jakoś programowo?

    Dodano po 14 [minuty]:

    I prosił bym także o wytłumaczenie, dlaczego czasem poniższy kod się nie syntezuje :|

    Code:
       process(CLK)
    
          variable Done : integer range 0 to 2 := 0;
       begin
       
          if rising_edge(CLK) then
          
          ...
             
          end if;
          
          if falling_edge(CLK) then
             
          ...
          
          end if;
       
       end process;

    Pojawia się błąd:
    Cytat:
    ERROR:Xst:827 - "D:/Xilinx/Sampler/Sampler.vhd" line 40: Signal SYGNAL<10> cannot be synthesized, bad synchronous description.

    Czytałem już poradę z Xilinx'a ale nic ona nie dała. Teraz są osobno rising i falling ... wcześniej było IF..ELSIF..END i też nie działało. Często mi się to wyświetla i nie mogę dojść do tego dlaczego...

    //ps. błąd dotyczy pierwszej linijki kodu który umieściłem...
  • #63
    J.A
    Poziom 27  
    mariuszlorenc napisał:
    /.../nie jesteśmy w stanie oszacować/.../ile makroceli zajmie, tak?

    no raczej nie, dlatego najpierw sie pisze rtl, potem szacuje potrzeby,
    na koncu zamawia hardware;
    mariuszlorenc napisał:
    dlaczego czasem poniższy kod/.../

    jeden proces z 'rising_edge', 'end process',
    potem drugi proces z 'falling_edge';
    taka jest obecna sytuacja 'w temacie fpga', na razie w obszarze
    programowania hardware'u jestesmy na etapie assemblera;
    moze kiedys to sie zmieni;
    niepokoi mnie troche twoja uwaga:
    "czasem poniższy kod się nie syntezuje"
    twierdzisz, ze czasami taka konstrukcja przechodzi przez kompilacje ?

    =======================
    Cytat:
    Można ją zmniejszyć jakoś programowo?

    jesli kod jest zle napisany, to mozna napisac lepiej wykorzystujac mniej
    zasobow, jesli kod jest napisany dobrze, to zmieniajac parametry syntezy
    mozna czasem zmniejszyc ilosc uzywanych komorek o pare procent
    [zwykle kosztem szybkosci dzialania];

    J.A
  • #64
    marenc
    Poziom 24  
    No już tak robiłem ... i w zależności od zawartości tych IF'ów wewnętrznych się syntezowało lub też nie.

    Zaraz poprawię kod i napiszę czy ruszyło.

    //Ale chwilka ... mam kolejny problem, który jeszcze nie potrafię rozwiązać. Mając wszystko w jednym procesie miałem wspólną zmienną dla rising i falling, a teraz tak by nie było. Jak mogę zrobić zmienną globalną?(która nie będzie sygnałem zewnętrznym)

    ////Po zmianie posypało mi taką ilością błędów, że szok.
  • IGE-XAO
  • #65
    pndemon
    Poziom 19  
    w obszarze pomiędzy architecture a begin możesz definiować sygnały np.
    singal a: std_logic_vector(3 downto 0);
  • #66
    marenc
    Poziom 24  
    Dzięki - rozwiązałem to w inny sposób i o dziwo ładnie się zsyntezowało.

    Dałem coś w rodzaju: w procesie dałem if CLK'event then, a w tym testowanie stanu CLK i ładnie działa wg. założeń ;)
  • #67
    webmortiz
    Poziom 20  
    Skoro jest to temat "Wszystko o układach programowalnych... podstawowe informacje" moze ktos opisalby wykorzystanie IP Core'ow zarowno tych prostych jak i tych bardziej zlozonych np. modeli mikroprocesorow. Moze zle mysle ale przy wykorzystaniu IP modeli uC(powiedzmy '51) da sie tez kod napisany np. w C (dla owego '51) na nich odpalic. Moze sie ktos wypowiedziec z doswiadczeniem?
  • #68
    webmortiz
    Poziom 20  
    Ok. Znalazlem dosc zaawansowany IP core avr'ow, pod adresem http://doru.info/ , na ktorym da sie ponoc odpalic kod w C. Kontaktowalem sie z autorem tego IP i dowiedzialem sie ze IP core jeszcze nie jest w pelni sprawny, ma jeszcze troche bugow i do wiekszych projektow autor nie zaleca go uzywac. Probowal ktos jakies '51 albo znalazl jakis inny dla avr, moze arm?
  • #69
    marenc
    Poziom 24  
    IP - czyli chodzi Ci o emulację AVR w FPGA, zapewne? Jaki ma sens coś emulować na programowalnym układzie, skoro można kupić osobno? Zwiekszenie prędkości?
  • #70
    webmortiz
    Poziom 20  
    Niekoniecznie zwiekszenie predkosci. Ale w przypadku niektorych aplikacji jakie produkujemy w domu obsluzenie wszystkiego z poziomu vhdl'a jest bardzo ciezkie, wiec ta 'ciezka' czesc moglby za nas wykonac kod w C. Przy zegarach jakie sa stosowane w FPGA takie IP cory powinny smigac znosnie. A natchnelo mnie bo kiedy dawno temu w asm'ie pisalo sie kod dla prockow DSP to te ciezsze rzeczy opisywalo sie w C, chociaz tam taka kombinacja asm-C byla mozliwa bez problemu.
  • #71
    marenc
    Poziom 24  
    Witam, zacząłem modyfikować temat i się odkleił... to taka sugestia dla moderatorów ;)

    Mam drobny problem, więc nie będę pisał nowego wątku. W procesie chcę uzależnić pewne rzeczy od wcześniej wprowadzonych danych. Np. masz zmienną liczbową integer z zakresu 0 do 255 i chcę operować na bitach tej liczby. Np. Jeżeli bit 0 tej liczby ustawiony to cośtam...

    Jak mogę coś takiego wykonać? Wrzucanie tego w licznik i testowanie jego wyjść jest raczej marnotrawieniem sygnałów... poza tym wprowadzanie danej do licznika mogło by być kłopotliwe...

    //Zrobiłem zmienne na wektorach logicznych i działa... Pozdrawiam
  • #72
    Zaquadnik
    Poziom 27  
    Co do soft-procesorów to korzystałem z MicroBlaze w Spartanie 3. Fajny procesorek, 32-bitowy, możliwość duże możliwości modyfikacji, kod pisany w C. Korzystałem także z PicoBlaze, to w zasadzie sam rdzeń 8-mio biowy, malutki i strasznie upierdliwy (przydałoby się obudować go trochę peryferiami), ale jego ogromną zaletą jest właśnie to, że jest malutki i zajmuje niewiele zasobów FPGA. Do tego można ich wrzucić do FPGA ile tylko dusza zapragnie ;) Kod do tego pisałem w asm.
  • #73
    webmortiz
    Poziom 20  
    Zaquadnik: moglbys dac jakis przykladowy projekt w ktorym wykorzystujesz MicroBlaze, jak podczepiasz do niego kod w C i jak to wyglada od strony integracji z vhdl'em? Wiem ze moge sam posiedziec pogooglowac itp. ale w tej chwili mam malo czasu dla siebie a tez byc moze taki projekt bardzo ulatwilby mi zycie.

    mariuszlorenc: poszukaj funkcji konwertujacych z integer na wektory a wtedy mozesz sie juz dowolnie odwolywac do bitow. Jest cos takiego bodajze jak int2vec ale nie pamietam dokladnie.
  • #74
    marenc
    Poziom 24  
    Gdzie mogę szukać takich instrukcji? W necie?

    Mam jeszcze jedno pytanie... mam sygnał:
    Cytat:
    ADD : inout STD_LOGIC_VECTOR (15 downto 0);

    I chciałbym w takt zegara zwiekszać wartość prezentowaną przez te bity... jak to wykonać? Już pisałem sumator bitowy, ale to chyba nie ma sensu przy 16 bitach ... masakra!

    //Chodzi mi oczywiście o zwiększanie o 1 ;)
  • #75
    webmortiz
    Poziom 20  
    1. W necie. Wpisujac na przyklad w google int2vec vhdl
    2. Tworzysz sobie zmienna lub sygnal(wypadaloby tez zainicjowac) o identycznych parametrach i:
    Code:

    --- cut ---
    signal ADD_temp : std_logic_vector(15 downto 0):=(others => '0');--nie wiem czy strzalka w dobra strone
    --- cut ---
    process(clk)
    begin
    if rising_edge(clk)
       ADD_temp<=ADD_temp+1;
       ADD<=ADD_temp;
    end if;
    end process;

    kod moze zawierac bledy bo pisze go z glowy bez sprawdzania.
  • #76
    pndemon
    Poziom 19  
    po prostu jest to licznik, jeśli korzystasz z ISE to masz tam language templates i tam masz liczniki (counter)
  • #77
    marenc
    Poziom 24  
    Witam, poprzedni problem rozwiązałem wg. podpowiedzi "pndemon". Language Templates zawiera wiele przykładów zastosowania języka VHDL do własnych potrzeb ;)

    Mam kolejne pytanie, na które nie znalazłem jeszcze odpowiedzi w żadnym kursie.

    Potrzebuję wywoływać ten sam fragment kodu dla kilku zmian zbocza sygnału wejściowego. Wiem, że można dać IF i korzystając z funktora OR połączyć wszystko, ale mam troszkę inną koncepcję.

    Np. mam dwie linie zegarowe i chcę dla obydwu uruchamiać ten sam kod, a nie chcę robić tak, jak to wyżej opisałem. Dla programistów tłumaczę, że chodzi mi o coś w rodzaju procedur i funkcji. Jeżeli mogę prosić to jakiś prosty przykład napisanej takiej "procedury" i jej wykorzystania w kodzie ;)
  • #78
    webmortiz
    Poziom 20  
    Sam probowalem z funkcjami(jesli chodzi o webpack ise) i w glownym oknie jezeli sie deklaruje funkcje i procedury to nie za bardzo chcialo dzialac. Zrobilem to w ten sposob ze utworzylem sobie package i tam mozna smialo pisac taki kod. Mimo iz synteza i implementacja przeszly kreator ucf'ow nie widzial tej biblioteki i wywalal bledy. Tego jeszcze nie rozwiazalem. Natomiast ahdl widzi poprawnie takie konstrukcje. Polecam zajrzec do wnetrza podstawowych bibliotek jakie sa dolaczane przy tworzeniu projektu ewentualnie poczytac na temat dolaczania do projektu plikow package.
  • #79
    J.A
    Poziom 27  
    mariuszlorenc napisał:
    /.../Potrzebuję wywoływać ten sam fragment kodu/.../

    slabo znam tajniki vhdl, wiec zrobilbym to
    w najbardziej 'naturalny' sposob:
    Code:

    /.../
    architecture xyz of top_level is
    signal ...
    .....
    begin
     
      inst_1  my_module
       port_map
       (
         clk => top_level_clk,
         .......
       )

      inst_2  my_module
      port_map
      (
        clk => not top_level_clk,
        ....
      );
    ............ 

    i gdzies w innym pliku definicja entity my_module

    J.A
  • #80
    marenc
    Poziom 24  
    Chodzi o ISE, a zapisu J.A niezbyt rozumiem...

    Wiem, że można napisać definicję procedury oraz napisać ją samą ... wiem mniej więcej jak dzięki Language Templates, ale nie wiem w którym miejscu ... sam już kilka sprawdziłem i nigdzie się nie syntezuje :|
  • #81
    webmortiz
    Poziom 20  
    w ise dodajesz nowy plik do projektu. Plik ma byc typu vhdl package. A jak sie juz wygeneruje bedzie tam przykladowa funkcja, procedura, zmienne i prototypy. I potem w pliku glownym dodajesz use <nazwa modulu>.ALL Tak jak pisalem wczesniej synteza i implementacja powinno przejsc na tworzeniu ucf wywala mi blad ze biblioteki nie widzi.
  • #82
    marenc
    Poziom 24  
    Ciągle walczę z napisem "Signal SYGNAŁ_WEJŚCIOWY cannot be synthesized, bad synchronous description.". Ten sam kod w różnych miejscach raz się syntezuje, a raz nie :| Często pokazywany jest nieprawidłowy numer linii...

    Ma ktoś na to jakiś złoty środek? Obecnie pracuję na Xilinx'ach CPLD.

    Co do procedur to coś mi tam działa, ale nie mogę utworzyć żadnego pliku testowego, bo sypie mi tym błędem ...
  • #83
    J.A
    Poziom 27  
    mariuszlorenc napisał:
    /.../zapisu J.A niezbyt rozumiem/.../

    ja chyba nie rozumiem, co chcesz uzyskac;
    sa 2 mozliwosci:
    masz gdzies plik z opisem dzialania powiedzmy licznika
    i chcesz w pliku glownym miec 3 liczniki, jeden dzialajacy
    z CLK_A, drugi z CLK_B, trzeci z (not)CLK_A - taki przypadek
    opisuje moj przyklad;
    druga mozliwosc - potrzebujesz w swoim projekcie jeden licznik,
    ktory zaleznie od 'sytuacji' raz pracuje z CLK_A, potem z CLK_B,
    a w pewnych warunkach z (not)CLK_A;
    jesli chodzi ci o opcje druga, to nie ma innej mozliwosci
    [choc sa rozne mozliwosci formalnego zapisu] jak zdefiniowac
    zegar dla licznika jakos tak:

    if (<warunek_a>) clk_do_licznika = CLK_A;
    else if (<warunek_b>) clk_do_licznika = CLK_B;
    else clk_do_licznika = not CLK_A;

    i polaczyc wejscie zegarowe licznika do sygnalu 'clk_do_licznika';

    ewentualnie czasem, choc rzadko, lepiej jest zaimplementowac
    3 liczniki podlaczone do roznych wejsc a przelaczac wyjscie wedlug
    warunku;

    to czy pracujesz z ise czy z czymkolwiek innym nie ma zadnego
    znaczenia, poprawnie napisany kod w vhdl bedzie poprawnie
    skompilowany w kazdym srodowisku;

    J.A

    Dodano po 10 [minuty]:

    ===========
    mariuszlorenc napisał:
    /.../Ma ktoś na to jakiś złoty środek?/.../

    sam podaj swoj przyklad, by mozna bylo zrozumiec o co chodzi,
    cos calkiem uproszczonego, pokazujacego istote problemu;
    blad ktory cytujesz sugeruje, ze kompilator nie potrafi jednoznacznie
    rozpoznac sygnalu zegarowego i/lub zbocza tego sygnalu;
    obecnie przerzutniki w fpga dzialaja jedynie na jedno zbocze,
    koniec kropka;
    wiec do swojego modulu musisz polaczyc dobrze zdefiniowany
    zegar, jakkolwiek tenze zegar moze byc wyjsciem z jakiejs calkiem
    skomplikowanej logiki;

    a przy okazji - jesli musisz robic jakies sztuczki z zegarem,
    to na 90% masz zla koncepcje calosci;

    J.A
  • #84
    marenc
    Poziom 24  
    Opcja 2. Ten sam fragment kodu pracujący z różnymi zegarami z wyborem poprzez wartości zmiennej wektora logicznego.

    Czy kod:
    Code:
          if C_CLK(0) = '1' and CLK0'event and CLK0 = '1' then
    
             INT <= not INT;
          end if;

    Dla INT jako INOUT; CLK0 jako IN i C_CLK jako wektor 7 downto 0 ... jest niepoprawny? Wywala kod błędu jak wyżej dla zmiennej INT :|

    //Chyba rozumiem swój błąd ... definiując sygnały czułości dla procesu miałem ich 5, więc XST miał problem z odnalezieniem prawidłowego. Spróbuje jutro napisać osobne procesy dla każdego z sygnałów wejściowych. Nie wiem tylko czy tak się uda, bo już zauważyłem, że więcej niż jeden proces nie może kontrolować sygnału wyjściowego. Zmienna globalna i jej kontrolowanie przez wszystkie procesy?
  • #85
    J.A
    Poziom 27  
    napisał:

    no to moja odpowiedz na opcje 2;
    przed process zdefiniuj clock zaleznie od warunkow jako combo;
    w process tylko warunek: if clock'event and clock = '1' then

    J.A

    Dodano po 4 [minuty]:

    napisał:
    Zmienna globalna i jej kontrolowanie przez wszystkie procesy?

    NIE - to jest hardware, nie software;
    wszystkie 'procesy' w hardware usiluja nadac 'swoja' wartosc
    sygnalowi przez caly czas, ciagle;
    wiec syntetyzator musi miec podany jakis sposob, dzieki
    ktoremu bedzie mogl zdecydowac, jaka jest 'wlasciwa' wartosc
    sygnalu;

    J.A
  • #86
    marenc
    Poziom 24  
    Jestem chyba za mało doświadczony jeszcze w układach programowalnych, ponieważ nie rozumiem Twojej sugestii :P

    ps. gdzie deklarować zmienne globalne? Z samouczków, że dla procesów można je definiować przez begin procesu ... a globalne, gdzie?
  • #87
    J.A
    Poziom 27  
    moze taki przyklad - poniewaz nie mam 'w palcach' vhdl,
    to raczej pogladowy niz poprawny syntaktycznie;

    ZLE
    process (...)
    if warunek_a and clkA'event and clkA = '1' then
    a = a + 1;
    else if warunek_b and clkA'event and clkA = '0' then
    a = a + 1;


    lepiej

    clock = ( clkA & warunek_a) OR ( ~clkA & warunek_b ); '~' negacja
    process (...)
    if clock'event and clock = '1' then
    a = a + 1;

    J.A
  • #88
    webmortiz
    Poziom 20  
    Cala sprawa w tym ze tak jak wspomnial J.A. vhdl to nie jezyk softwarowy, tak wiec trzeba zmienic podejscie. A sprawa rozchodzi sie najprawdopodobniej o procesy synchroniczne i asynchroniczne. Z tymi pierwszymi syntezatory radza sobie elegancko, a z tymi drugimi maja problemy. Ciezko jest napisac dobry kod synchroniczny, a asynchroniczny sam wychodzi ;) jezeli nie znamy dobrze vhdl'a. A co do wspomnianej wczesniej opcji 2 to pierwsze rozwiazanie to wlasnie funkcje, chociaz mija sie to troche z zalozeniami jezyka opisu sprzetu, a druga opcja to port mapowanie jak wczesniej J.A. dal przyklad, wtedy mamy sparametryzowany ten sam fragment kodu, ktory mozemy wywolywac z roznymi sygnalami.
  • #89
    marenc
    Poziom 24  
    Chyba zaczynam to wszystko powoli rozumieć ;) Wychodzą po prostu moje przyzwyczajenia z mikrokontrolerów i aplikacji WIN32 ;)

    Jeżeli w jednym procesie mam ZMIENNA <= '0' i ZMIENNA <= '1', nawet jeżeli są w różnych IF'ach to program się nie zsyntezuje, tak? Bo oba zdarzenia mogą wystąpić jednocześnie, a układ nie pozwala na hazard logiczny?

    W jaki sposób można więc w jednym procesie kontrolować tą samą linię w kilku IF'ach?

    Mam kilka IF'ów reagujących na zbocza różnych linii i chciałbym, aby w zależności od zdarzenia(wykonywania jednego IF'a) linia wyjściowa ustawiała odpowiedni stan.

    Np. Gdy na linii R pojawi się zbocze narastające, to RESET <= '1', ale gdy CLK'event to RESET <= '0';(DWA OSOBNE IF'y)

    //Napisałem program w jednym procesie, który nie pozwala na jednoczesne wymuszanie dwóch stanów linii i wywala mi ten błąd ... pomóżcie :(

    Code:
    R : inout  STD_LOGIC := '1';
    
    ...
    if R = '0' then
    ...
    elsif D'event and D = '1' then
    R <= '0';
    end if;
  • #90
    J.A
    Poziom 27  
    mariuszlorenc napisał:
    Jeżeli w jednym procesie mam ZMIENNA<='0' i ZMIENNA<='1'/.../

    z grubsza o to chodzi;
    mozesz wyobrazic sobie, ze masz kawalek drutu, do ktorego
    podpiete wyjsciami sa twoje 2 'IFy', jesli jeden z nich usiluje
    wymusic stan '0', a drugi '1', to moze dojsc do uszkodzenia
    struktury fpga i zaden kompilator na to nie pozwoli;
    stan danego sygnalu przypisuj w dowolnie rozbudowanym,
    ale jednym 'IF' albo wielopziomowym 'CASE' ale jednym;

    mariuszlorenc napisał:
    /.../Gdy na linii R pojawi się zbocze narastające, to RESET <= '1'/.../

    nie rozumiem, wiec ci nie podpowiem, ale ... troche juz pracuje
    z fpga i takich cudactw jeszcze nie widzialem :)
    jesli opiszesz na jakims bardziej ogolnym poziomie w miare
    jasno, co chcesz osiagnac, to na pewno uzyskasz tu sugestie
    jak to zrobic;
    z twoich dotychczasowych pytan/opisow wynika dla mnie, ze
    wlazles w jakies maliny;

    J.A