Kilka pytan o VHDL

Witam,

chcialbym zaimplementowac kilka algorytmow w VHDL, ktorego sie wlasnie zaczalem uczyc i mam kilka pytan o konwencje notacyjne i implementacyjne. Algorytmy zostaly wczesniej przetestowane w Octave i C++ (napisalem sobie zbior funkcji odpowiadajacy magafunctions Altery i z nich poskladalem moje "hardware" :-)), wiec na pewno sa dobre.

  1. Moduly generyczne. Dlaczego Quartus odrzuca przypisanie wartosci domyslnej, jesli wartosc ma byc taka sama, jak innego parametru modulu? Chcialbym napisac tak:

generic (

phase_accumulator_size : positive := 32; phase_offset_size : positive := 16; phase_output_size : positive := phase_accumulator_size; phase_step_size : positive := phase_accumulator_size );

a musze tak (mimo, ze w Internecie znalazlem konstrukcje odpowiadajaca powyzszemu zapisowi):

generic (

phase_accumulator_size : positive := 32; phase_offset_size : positive := 16; phase_output_size : positive := 32; phase_step_size : positive := 32 );

  1. W jaki dokladnie sposob korzysta sie z asercji? Chcialbym miec taki tester:

jesli phase_step_size > phase_accumulator_size, to zglos blad kompilacji.

Jak to zapisac za pomoca assert i (zwlaszcza) w ktorym miejscu to umiescic?

  1. Czy w konstrukcji generujacej for mozna uzywac arcus tangensa z wyrazenia stalego, obliczanego na podstawie iteratora, jako stalej?

  1. Chcialbym dodac do 16 starszych bitow 32-bitowej liczby unsigned, zakodowanej w std_logic_vector, 16-bitowa liczbe unsigned, rowniez pamietana w wektorze. W jaki sposob to najlepiej zapisac, jesli nie interesuje mnie przeniesienie generowane przez ten uklad (tzn. wszystko ma sie liczyc modulo 2^32)? A w jaki sposob, gdybym chcial miec informacje o przeniesieniu?

  2. Ogolniej: w jaki sposob mozna wyciagnac interesujacy mnie podzbior bitow z danego std_logic_vector? Np. chcialbym dostac wektor zlozony z bitow 1,2,3,19, 25 danego wektora
32-bitowego.

  1. Jak zrobic, by wynik dzialania jakiegos procesu byl zapamietywany w latchu? Zwiazany z nim modul powinien miec dwa N-bitowe latche, A i R, wejscia clk i N-bitwowe s i wyjscie N-bitowe f, a dzialac tak (zapis w pseudokodzie):

process(clk) if rising_edge(clk) then R := A; A := A + s; f := R; end end

Jak zadeklarowac latche A i R? Czy mozna prosic o kawalek kodu w VHDL realizujacy podana powyzej funkcje?

  1. Czym sie rozni "signal" od "variable"?

Pozdrawiam Piotr Wyderski

Reply to
Piotr Wyderski
Loading thread data ...

Witam!

A czy chcesz aby phase_step_size i phase_output_size mialy zawsze wartosc rowna phase_accumulator_size? Mozna by je wtedy zadeklarowac jako CONSTANT i przypisac wartosc rozmiaru akumualatora... Generalnie takie przypisanie wartosci domyslnej jakie chciales raczej sie nie uda. Np. Active-HDL twierdzi, ze nie moze odwolywac sie do wartosci parametru w miejscu deklaracji parametrow...

assert (phase_step_size <= phase_accumulator_size) report "Blad, phase_step_size jest wieksze od phase_accumulator_size" severity ERROR;

Gdzie umiescic? Tam, gdzie chcesz sprawdzic czy ten warunek jest prawdziwy;)

W pakiecie STD_LOGIC_UNSIGNED z biblioteki IEEE jest przeciazaona funkcja + dla obiektow STD_LOGIC_VECTOR. Nie wiem jak tam ona sobie radzi z przeniesieniami, trzeba by zeknac w jej kod, albo przetestowac.

np. Maly_Wektor <= Duzy_Wektor(1) & Duzy_Wektor(2) & Duzy_Wektor(3) & Duzy_Wektor(19) & Duzy_Wektor(25);

Oczywiscie Maly_Wektor musi miec odpowiednia dlugosc - w tym przypadku

5bitow. Mozna tez uzywac zakresow, jak i "danych bezposrednich:)" np Maly_Wektor <= Duzy_Wektor( 8 downto 6) & "01";

Oto ten kawalek kodu, z latchami (raczej powstana z tego FlipFlopy) A i R : (kod przykladowy)

process(clk, reset)

variable R: STD_LOGIC_VECTOR(N-1 downto 0); variable A: STD_LOGIC_VECTOR(N-1 downto 0);

begin

if reset = '1' then A := 0; R := 0;

elsif rising_edge(clk) then R := A; A := A + s; f := R; end if; end process;

Jak widzisz wiele zmian nie ma. Ty tworzysz zmienne lub syganly. To syntezator tworzy z nich latche, flip-flopy czy tylko kawalki "drutu". Ty tylko piszesz jak ma dzialac uklad, korzystajac z opisu behawioralnego, wysokiego poziomu.

Najwieksza roznica - jezeli wewnatrz procesu przypisujesz wartosc zmiennej, to ta nowa wartosc obowiazuje OD RAZU, jeszcze w ramach tego samego procesu, natomisat, jesli przypiszesz nowa wartosc sygnalowi, bedzie ona obowiazywac DOPIERO przy nastepnym uruchomieniu procesu. Niby mala roznica, ale ma kolosalne znaczenie w praktycznym dzialaniu ukladu.

Pozdrawiam rowniez! Marek

Reply to
Marek N.

Mowiac ogolnie: nie, ale chce, by domyslnie tak bylo.

Tutaj tak zrobiono:

formatting link

OK, dziekuje.

:-) Chodzi mi o to, czy w entity, czy w architecture, a jesli w tym drugim, to w ciele, czy sekcji deklaracji?

A jesli interesuje mnie spojna grupa, np. bity od 16..31, to istnieje na to jakis skrot notacyjny?

[ciach reszta] -- dziekuje za wyjasnienia!

Pozdrawiam Piotr Wyderski

Reply to
Piotr Wyderski

Faktycznie... Sprawdzilem - napisalem jakis banalny komponent z takim genericem i:

1) Xilinx ISE - syntezuje bez bledu, 2) Quatus II - blad nielegalnego przypisania, synteza niemozliwa, 3) Active-HDL - blad kompilacji.

Czyli to jak widac zalezy od programu. Moze specyfikacja jezyka VHDL nie przewiduje takiej konstrukcji, a panowie z Xilinxa wyposazyli XST w mechanizmy radzenia sobie z takimi wpisami? Musisz wiec chyba jednak pozostac przy opcji podania liczby jako wartosci domyslnej...

Nie zrocilem uwagi na jedno: w swoim poprzednim poscie napisales : "jesli phase_step_size > phase_accumulator_size, to zglos blad _kompilacji._" Instrukcja ASSERT wykonuje sie tylko podczas symulacji. Kompilator / Syntezator nie zwraca na nia uwagi. Dlatego umieszcza sie ja w ciele architektury i np. wyglada to tak:

... process(clk) ... state <= next_state; assert (next_state < "1111" ) report "Wystapil stan zabroniony! Popraw swoje FSM, bo cos schrzaniles." severnity warning; ...

Problem jest taki - jak Duzy_Wektor zadeklarowany jest jako (A downto B), to nie da sie wyciac z niego kawalku (C to D), mozna tylko (D downto C). Mozesz wiec napisac (31 downto 16), ale nie (16 to 31). Chyba, ze wektor zadeklarowany jest jako (0 to 31), wtedy mozna wyciac (16 to 31).

Pozdrawiam Marek N.

Reply to
Marek N.

Marku mozesz odezwac sie na priva ?

Adam

Reply to
Adam

bez przeniesienia: Process(liczba_a,liczba_b) begin wynik(15 downto 0) <= liczba_a(31 downto 16) + liczba_b(31 downto 16); end process;

jeśli checsz z przeniesieniem to musisz z liczb 16 bitowych zrobić 17 bitowe, dodać je i zapamiętać wynik w liczbie 17 bitowej (bit 17 jest informacją o przeniesieniu):

liczba_17a(16 downto 0) <= '0' & liczba_a(15 downto 0); liczba_17b(16 downto 0) <= '0' & liczba_b(15 downto 0);

Process(liczba_a,liczba_b) begin wynik(16 downto 0) <= liczba_a(16 downto 0) + liczba_b(16 downto 0); end process;

aby tak dodawać to musisz mieć na początku pliku: use ieee.std_logic_unsigned.all;

podzbior(0) <= wektor(1); podzbior(1) <= wektor(2); podzbior(2) <= wektor(3); podzbior(3) <= wektor(19); podzbior(4) <= wektor(25);

Latch zapamiętuje nie na zboczu tylko na poziomie. Dla przykładu latch A:

process(clk) if clk='1' then A <= A + s; end; end process;

Pozdrawiam, Piotrek

Reply to
Piotrek
[ciach] -- rowniez dziekuje za pomoc.

Pozdrawiam Piotr Wyderski

Reply to
Piotr Wyderski

ElectronDepot website is not affiliated with any of the manufacturers or service providers discussed here. All logos and trade names are the property of their respective owners.