Komentarze do wpisów
Czemu X zamiast jedynki?
25.11.2006 - Sobota - 18:27
Spodobał mi się VHDL, więc postanowiłem nieco głębiej w niego "wejść", no ale do tego potrzebne mi jest oprogramowanie. Oczywiście, mogę sobie kupić płytkę testową z układem programowalnym, ale wydatek rzędu 150 dolarów mnie przeraża. Muszę korzystać z symulatorów. A pod Linuksem wcale nie jest tak różowo. Co prawda Altera i Xilinx (dwaj czołowi producenci układów programowalnych) udostępniają swoje oprogramowanie w wersji dla Linuksa, ale... ISE Webpack Xilinksa to nieco ponad gigabajt danych do ściągnięcia i spore wymagania jeśli chodzi o sprzęt. A na dodatek "Requires Red Hat Enterprise 3.0", przez co już wiadomo, że mogą być kłopoty z jego uruchomieniem na Ubuntu. W przypadku Altery też podobnie...
Dlatego muszę skorzystać z GHDL-a i Gtkwave'a. Niestety zintegrowanego pakietu, który zrobiłby wszystko za mnie nie znalazłem, ale może i dobrze. Lepiej poznam ten język. W pakietach typu ISE Webpack czy Quartus (Altera) po napisaniu kodu można sobie "wyklikać" przebiegi testowe i zobaczyć odpowiedź układu. W przypadku GHDL-a muszę sobie napisać samemu testbencha (program testujący). I tu się zaczynają schody...
Na początek napisałem sobie prosty licznik modulo 16:
library ieee; use ieee.std_logic_1164.all; use ieee.numeric_std.all; entity licznik16 is port( CLK: in std_logic; Q: out std_logic_vector(3 downto 0); R: in std_logic); end licznik16; architecture licz of licznik16 is begin process(CLK, R) variable stan: unsigned(3 downto 0):="0000"; begin if R = '0' then stan:="0000"; elsif (CLK'event and CLK='1') then stan:=stan+1; end if; Q <= std_logic_vector(stan); end process; end licz;
Napisałem, stwierdziłem, że powinien działać, ale warto byłoby go sprawdzić. No to wziąłem się za pisanie testbencha... Na początku wszystko szło bez przeszkód. Testbench napisał się momentalnie. Nieco zaglądałem do podręczników i skakałem po przykładach z Internetu, ale jakoś napisałem. Udało się skompilować i wygenerowałem plik z przebiegami, który obejrzałem sobie w Gtkwave. I tu zaskoczenie! Wszystko gra, ale nie do końca... Ale najpierw rzućmy okiem na testbencha:
library ieee; use ieee.std_logic_1164.all; use ieee.numeric_std.all; entity licztb is end licztb; architecture licztbarch of licztb is component licznik16 port(CLK: in std_logic; Q: out std_logic_vector(3 downto 0); R: in std_logic); end component; signal zegar, reset: std_logic; signal Q: std_logic_vector(3 downto 0); begin mapowanie: licznik16 port map(CLK=>zegar, R=>reset, Q=>Q); process begin Q<"0000"; wait for 10 ns; zegar <= '0'; wait for 10 ns; reset <= '1' after 1 ns, '0' after 90 ns, '1' after 150 ns; wait for 10 ns; for i in 0 to 100 loop zegar <= not(zegar); wait for 50 ns; end loop; wait; end process; end licztbarch;
Czyli jak widać, najpierw zeruję wyjście, co na przebiegach widać. Chwilę potem inicjalizuję zegar (zegar ma operować tylko na stanach 0 i 1, wszelkie pozostałe stany są wykluczone), co też widać. Następnie sprytnie generuję sygnał resetujący licznik, chociaż nie muszę tak naprawdę tego robić, bo licznik został zresetowany na początku procesu. W pętli, tworzę prostokątny przebieg zegara o okresie 100 nanosekund. Zegar ten jest sprzężony z zegarem CLK w w samym liczniku. Czyli z każdym zboczem narastającym (CLK'event and CLK='1') licznik będzie się zwiększał o jeden. I wszystko byłoby ok, gdyby nie to, że zamiast stanu 1 na przebiegach pojawia się stan X (co w logice dziewięciowartościowej oznacza stan nieznany). Mało tego! Układ traktuje go jako jedynkę, bo wcale jego pojawienie się nie zaburza działania. Ale mimo to tego stanu tam nie powinno być!
Ślęczę nad tym już którąś godzinę i nie wiem co z tym zrobić... Czyżby to było związane z konwersją zmiennej typu unsigned na sygnał std_logic_vector? Nie wiem... Ktoś pomoże?
Słowa kluczowe: vhdl programowanie komputer linux
