CAD Cyfrowe przetwarzanie sygnałów Mariusz Rawski rawski@tele.pw.edu.pl http://rawski.zpt.tele.pw.edu.pl/
Cyfrowe przetwarzanie sygnału A/D konwersja sygnału analogowego na cyfrowy (próbkowanie, kwantyzacja, kodowanie) DSP układy cyfrowego przetwarzania : filtracja FIR y( n) b m x( n m) filtracja IIR transformacja Fouriera funkcja korelacji wzajemnej = M m = 0 N 1 n= 0 j(2π / N ) nk ( k ) = x( n) e M m = 0 N k = 1 ( n ) = b m x ( n m ) + a y ( n k ) Charakterystyczne jest to, że wszystkie te obliczenia posiadają postać: A = N x n y n = x y + x y + + x y n = 1 1 1 2 2... N N Składają się z mnożeń połączonych z akumulacją MAC (Multiply and Accumulate). D/A konwersja sygnału cyfrowego na analogowy X y R x, y 1 N ( m) = x( n) y( n + m) = N n 0 k Mariusz Rawski 2
Operacja MAC (Multiply and Accumulate) Podstawowa operacja w cyfrowym przetwarzaniu sygnałów Składa się z operacji mnożenia i dodawania Data in Rejestr Realizowana w procesorach DSP jako jednostka obliczeniowa Algorytm iteracyjny Jednostka MAC Data out Przykład: Filtr FIR 256 rzędu = 256 operacji mnóż i przechowaj (MAC) na pojedynczą próbkę danych Mariusz Rawski 3
Wydajne Procesory DSP Procesory DSP vs. FPGA Wysoce zrównoleglone przetwarzanie w FPGA MAC MAC MAC MAC MAC MAC MAC MAC MAC MAC MAC MAC MAC MAC MAC MAC MAC MAC MAC MAC MAC MAC MAC MAC MAC MAC MAC MAC MAC MAC MAC MAC MAC MAC MAC MAC Stała nieelastyczna architektura Można realizować setki przekształceń MAC w jednym układzie FPGA Typowo 1-8 jednostki MAC Stała szerokość danych Przetwarzanie szeregowe ogranicza przepustowość Współdzielone w czasie jednostki MAC Duże częstotliwości taktowania stawiają duże wyzwania projektantom systemów Wymagane wiele cykli zegara Filtr FIR 200 stopniowy wymagać będzie 25+ cykli zegara na próbkę w przypadku procesora z 8 jednostkami MAC Zrównoleglona realizacja umożliwia dużą przepustowość Filtr FIR 200 stopniowy wymaga 1 cykl zegara na próbkę Mariusz Rawski 4
Elastyczność układów FPGA MAC FPGA Optymalizacja realizacji Parallel Semi-Parallel Serial + + + + + + + + + D Q + + D Q + Q = (A x B) + (C x D) + (E x F) + (G x H) Szybkość Koszt Mariusz Rawski 5
Architektura FPGA vs. DSP wydajność kosztem powierzchni Źródło: WP116, Xilinx Spartan-II FIR Filter Solution, 2000 Mariusz Rawski 6
Filtr cyfrowy FIR Definicja y n L 1 = k= 0 x k c n k n = 0,..., N 1 Filtracja proces przetwarzania sygnału w dziedzinie czasu polegający na redukowaniu i usunięciu niepożądanych składowych zawartych w sygnale wejściowym. Filtr cyfrowy to algorytm lub proces obliczeniowy w wyniku którego jedna sekwencja liczb (tzn.sygnał wejściowy) zamieniany jest w inną sekwencję (tzn. sygnał wyjściowy). Jest szeroko stosowana w przetwarzaniu sygnałów. Obliczenie tych sum w sposób bezpośredni wymaga O(L 2 ) operacji arytmetycznych Mariusz Rawski 7
Filtr o skończonej odpowiedzi impulsowej FIR y n = L 1 k =0 n k L rząd filtru, c[n] współczynnik, z -1 element opóźniający x k c L-1 sumowań, L mnożeń Mariusz Rawski 8
y = Realizacja operacji MAC L 1 x n c n n= 0 = x 0 c 0 + x 1 c 1 +... + x L 1 c L 1 Rejestr przesuwający Ukł. mnożący Sumator Akumulator X[L-1] X[1] X[0] C[L-1] C[1] C[0] + R Mariusz Rawski 9
Sumatory Sumowanie jest najpowszechniejszą operacją arytmetyczną A B Służy jako część składowa innych operacji (np.. mnożenia) Służy do realizacji odejmowania poprzez sumowanie argumentu ze zmienionym znakiem Sumator jest logiką kombinacyjną, Można użyć najprostszego sposobu i opisać sumator tablicą prawdy S Mariusz Rawski 10
Prosta realizacja sumatora library ieee; use ieee.std_logic_1164.all; entity add_tab is port( a, b : in std_logic_vector(7 downto 0 cout : out std_logic; s : out std_logic_vector(7 downto 0) end add_tab; architecture arch of add_tab is signal tab_in : std_logic_vector(15 downto 0 signal tab_out : std_logic_vector(8 downto 0 begin tab_in <= (a & b s <= tab_out(7 downto 0 cout <= tab_out(8 PLA: process(tab_in) begin case tab_in is when "0000000000000000" => tab_out <= "000000000"; when "0000000000000001" => tab_out <= "000000001"; when "0000000000000010" => tab_out <= "000000010"; when "0000000000000011" => tab_out <= "000000011"; when "1111111111111110" => tab_out <= "111111101"; when "1111111111111111" => tab_out <= "111111110"; when others => tab_out <= "XXXXXXXXX"; end case; end process; end; Sumator jest logiką kombinacyjną Można użyć najprostszego sposobu i opisać sumator tablicą prawdy Zadanie: Zaprojektować sumator dwuargumentowy 4- bitowy A Dane: A[7..0], B[7..0] Wynik: cout, S[7..0] Zbyt proste, żeby było ZALETY Prosta koncepcja Zaprojektowanie takiego sumatora nie wymaga zbyt wielkiej wiedzy cout S B Mariusz Rawski 11
Prosta realizacja sumatora wyniki Fitter Summary Top-level Entity Name Family Device Prosta koncepcja, ale sposób opisu nie do przyjęcia: dla sumatora 8-bitowego tablica ma 2 16 = 65 536 wierszy dla sumatora 16-bitowego tablica ma 2 32 = 4 294 967 296 wierszy add_tab Stratix EP1S10F484C5 Total logic elements 29 / 10,570 ( < 1 % ) Total pins 25 / 336 ( 7 % ) Total virtual pins 0 Total memory bits 0 / 920,448 ( 0 % ) DSP block 9-bit elements 0 / 48 ( 0 % ) Total PLLs 0 / 6 ( 0 % ) Total DLLs 0 / 2 ( 0 % ) Mariusz Rawski 12
Równania sumatora Sumator 1-bitowy full adder Równanie boolowskie sumy: s k = a k xor b k xor c k = a k b k c k Równanie boolowskie przeniesienia: c k+1 = (a k and b k ) or (a k and c k ) or (b k and c k ) = (a k y k ) + (a k c k ) + (b k c k ) library ieee; use ieee.std_logic_1164.all; entity full_adder_1bit is port( a, b, cin : in std_logic; s, cout : out std_logic end; k k k k k k architecture arch of full_adder_1bit is begin s <= a xor b xor cin; cout <= (a and b) or (a and cin) or ( b and cin end; c k a k b k c k+1 s k 0 0 0 0 0 0 0 1 0 1 0 1 0 0 1 0 1 1 1 0 1 0 0 0 1 1 0 1 1 0 1 1 0 1 0 1 1 1 1 1 Mariusz Rawski 13
library ieee; use ieee.std_logic_1164.all; use ieee.numeric_std.all; Sumator ripple-carry adder (RCA) entity rca is generic( WIDTH : integer := 8 port( a, b : in std_logic_vector(width-1 downto 0 cout : out std_logic; s : out std_logic_vector(width-1 downto 0) end; architecture arch of rca is component full_adder_1bit is port( a, b, cin : in std_logic; s, cout : out std_logic end component; signal c : std_logic_vector(width downto 0 begin c(0) <= '0'; cout <= c(width rcastages: for i in WIDTH-1 downto 0 generate stagei : full_adder_1bit port map( a => a(i), b => b(i), cin => c(i), s => s(i), end generate; end; cout => c(i+1) Mariusz Rawski
Sumator ripple-carry adder wyniki Fitter Summary Top-level Entity Name rca Family Stratix Device EP1S10F484C5 Total logic elements 18 / 10,570 ( < 1 % ) Total pins 25 / 336 ( 7 % ) Total virtual pins 0 Total memory bits 0 / 920,448 ( 0 % ) DSP block 9-bit elements 0 / 48 ( 0 % ) Total PLLs 0 / 6 ( 0 % ) Total DLLs 0 / 2 ( 0 % ) Mariusz Rawski 15
Carry-ripple adder - wady Jaka jest ścieżka krytyczna tego układu? Liczba komórek: O(N) liniowo zależna od wielkości sumatora Opóźnienie: O(N) liniowo zależne od wielkości sumatora Mariusz Rawski 16
Przyspieszenie sumowania Kluczem do przyspieszenia dodawania jest zmniejszenie opóźnienia sieci propagacji sygnału przeniesienia Z punktu widzenia propagacji tego sygnału nieistotne są wartości konkretnych operandów Znaczenie ma czy w danym stopniu sumatora sygnał przeniesienia jest generowany (generate), propagowany (propagate), pochłaniany (anihilate). Mariusz Rawski 17
Optymalizacja propagacji przeniesienia Warunek generacji przeniesienia: g i = a i and b i Warunek propagacji przeniesienia: p i = a i xor b i Warunek pochłaniania przeniesienia: ani i = (not a i ) and (not b i ) c k a k b k c k+1 s k 0 0 0 0 0 0 0 1 0 1 0 1 0 0 1 0 1 1 1 0 1 0 0 0 1 1 0 1 1 0 1 1 0 1 0 1 1 1 1 1 Mariusz Rawski 18
Sumator carry lookahead (CLA) Przewidywanie przeniesienia c i = g i-1 + c i-1 p i-1 Przeniesienia kolejnych stopni sumatora c 1 = g 0 + c in p 0 c 2 = g 1 + g 0 p 1 + c in p 0 p 1 c 3 = g 2 + g 1 p 2 + g 0 p 1 p 2 + c in p 0 p 1 p 2 Mariusz Rawski 19
Warunek generacji przeniesienia: g i = a i and b i Warunek propagacji przeniesienia: p i = a i xor b i Przewidywanie przeniesienia c i = g i-1 + c i-1 p i-1 Sumator carry lookahead (CLA) library ieee; use ieee.std_logic_1164.all; use ieee.numeric_std.all; entity cla is generic( WIDTH : integer := 8 port( a, b : in std_logic_vector(width-1 downto 0 cout : out std_logic; s : out std_logic_vector(width-1 downto 0) end; architecture arch of cla is signal c : std_logic_vector(width-1 downto 0 signal p : std_logic_vector(width-1 downto 0 signal g : std_logic_vector(width-1 downto 0 begin pstructure: for i in WIDTH-1 downto 0 generate p(i) <= a(i) xor b(i g(i) <= a(i) and b(i end generate; c(0) <= '0'; cout <= g(width-1) or (p(width-1) and c(width-1) cstructure: for i in WIDTH-1 downto 1 generate c(i) <= g(i-1) or (p(i-1) and c(i-1) end generate; sstructure: for i in WIDTH-1 downto 0 generate s(i) <= a(i) xor b(i) xor c(i end generate; end; Mariusz Rawski
Sumator carry lookahead (CLA) wyniki Fitter Summary Top-level Entity Name cla Family Stratix Device EP1S10F484C5 Total logic elements 15 / 10,570 ( < 1 % ) Total pins 25 / 336 ( 7 % ) Total virtual pins 0 Total memory bits 0 / 920,448 ( 0 % ) DSP block 9-bit elements 0 / 48 ( 0 % ) Total PLLs 0 / 6 ( 0 % ) Total DLLs 0 / 2 ( 0 % ) Mariusz Rawski 21
P = A B, n = 4 Mnożenie w układzie kombinacyjnym M i = b i A 2 i a 3 a 2 a 1 a 0 b 3 b 2 b 1 b 0 0 0 0 0 a 3 b 0 a 2 b 0 a 1 b 0 a 0 b 0 M 0 0 0 0 a 3 b 1 a 2 b 1 a 1 b 1 a 0 b 1 0 M 1 0 0 a 3 b 2 a 2 b 2 a 1 b 2 a 0 b 2 0 0 M 2 Mnożenie to w zasadzie wielokrotnie wykonywane dodawanie. 0 a 3 b 3 a 2 b 3 a 1 b 3 a 0 b 3 0 0 0 M 3 p 7 p 6 p 5 p 4 p 3 p 2 p 1 p 0 Mariusz Rawski 22
Nowoczesne struktury FPGA ALM Inputs ALM 1 2 3 4 5 6 7 8 Adder Reg Comb. Logic Adder Reg Linie połączeniowe carry-chain o małych opóźnieniach spinające wiele bloków logicznych pozwalają przyspeszyć operacje dodawania i odejmowania Względnie wydajne przy realizacji operacji dodawania i odejmowania. Jednakże nie optymalne pod względem kosztu, szybkości i poboru mocy w przypadku realizacji operacji mnożenia i dzielenia
Nowoczesne struktury FPGA 37 36 + 36 37 +-Σ 36 38 Output Register Unit +-Σ Output Multiplexer Optional Pipelining 144 Input Register Unit 36 144 Producenci układów FPGA wbudowują w swoje układy dedykowane bloki realizujące funkcję mnożenia. Niektórzy poszli nawet dalej ścieżką integracji udostępniając w pełni funkcjonalne bloki MAC zwane blokami DSP
Operacja dodawania library ieee; use ieee.std_logic_1164.all; use ieee.numeric_std.all; entity add is generic( WIDTH : integer := 8 port( a, b : in std_logic_vector(width-1 downto 0 cout : out std_logic; s : out std_logic_vector(width-1 downto 0) end; architecture arch of add is signal result : unsigned(width downto 0 begin result <= unsigned('0' & a) + unsigned('0' & b cout <= result(width s <= std_logic_vector(result(width-1 downto 0) end; Kompilator automatycznie wykorzystał mechanizm carry-chain Mariusz Rawski
Operacja dodawania wyniki Fitter Summary Top-level Entity Name add Family Stratix Device EP1S10F484C5 Total logic elements 9 / 10,570 ( < 1 % ) Total pins 25 / 336 ( 7 % ) Total virtual pins 0 Total memory bits 0 / 920,448 ( 0 % ) DSP block 9-bit elements 0 / 48 ( 0 % ) Total PLLs 0 / 6 ( 0 % ) Total DLLs 0 / 2 ( 0 % ) Najszybsza i najoszczędniejsza realizacja. Realizacja własnego modułu sumatora ma sens tylko, gdy stosowany jest specyficzny schemat dodawania, np. z wykorzystaniem potokowania lub sumatory wieloargumentowe. Mariusz Rawski 26
Operacja mnożenia library ieee; use ieee.std_logic_1164.all; use ieee.numeric_std.all; entity mul is generic( WIDTH : integer := 8 port( a, b : in std_logic_vector(width-1 downto 0 p : out std_logic_vector(2*width-1 downto 0) end; architecture arch of mul is signal result : unsigned(2*width-1 downto 0 begin result <= unsigned(a) * unsigned(b p <= std_logic_vector(result end; Kompilator automatycznie wykorzystał wbudowany blok mnożarki Mariusz Rawski
Operacja mnożenia Fitter Summary Top-level Entity Name mul Family Stratix Device EP1S10F484C5 Total logic elements 0 / 10,570 ( < 1 % ) Total pins 32 / 336 ( 9 % ) Total virtual pins 0 Total memory bits 0 / 920,448 ( 0 % ) DSP block 9-bit elements 1 / 48 ( 2 % ) Total PLLs 0 / 6 ( 0 % ) Total DLLs 0 / 2 ( 0 % ) Bardzo wydajna realizacja. Gdyby jednak nie wykorzystywać dedykowanego bloku mnożącego układ zajmowałby 106 komórek a t pd wynosiłoby 22,346 ns. Realizacja własnego modułu mnożącego dopasowanego do konkretnego algorytmu często prowadzi do lepszych rezultatów. Mariusz Rawski 28
Obliczanie wartości funkcji w DSP W cyfrowym przetwarzaniu sygnałów zazwyczaj nie jest potrzebne wykorzystanie dokładnych wartości funkcji matematycznych takich jak logarytm, pierwiastek czy funkcje trygonometryczne. Zazwyczaj dopuszcza się pewien stopień niedokładności i kładzie się nacisk na szybkość obliczeń Stąd też obliczanie przybliżonych wartości funkcji matematycznych jest bardzo ważnym zagadnieniem w DSP Jedną z często wykorzystywanych funkcji jest pierwiastek stopnia n (najczęściej pierwiastek kwadratowy). Można do tego celu wykorzystać np. szeregi Taylora. Jednakże znalezienie wartości np. 3 q jest równoznaczne z rozwiązaniem 3 równania x q = 0 Stąd też można do tego celu zastosować dowolny algorytm znajdowania miejsca zerowego funkcji taki jak np. metoda Newtona Mariusz Rawski 29
Metoda Newtona Zwana również metodą Newtona-Raphsona lub metodą stycznych iteracyjny algorytm wyznaczania przybliżonej wartości miejsca zerowego funkcji. Dla zadanej funkcji ƒ(x) oraz jej pochodnej ƒ '(x), zaczynamy od pierwszego przybliżenia x 0. Lepsze przybliżenie x 1 otrzymuje się ze wzoru x 1 = x 0 f ( x f '( x 0 ' 0 ) )
Zadanie: wyznaczyć wartość 17 3 Dla 17 ƒ(x) = x 3 17, stąd x 1 = x 0 (x 03 17)/(3* x 02 ) 3 Metoda Newtona N N load = 1 T x = data start = 1 T cnt = 0 Niech ƒ next (x) = x (x 3 17)/(3* x 2 ). x = f next (x) Obliczanie wartości 3 17 można przeprowadzić algorytmem iteracyjnym. N cnt = 9 T cnt = cnt + 1 res = x ready = 1
Metoda Newtona Algorytm iteracyjny z wczytaniem początkowej wartości Wynik: liczba 10 bitowa w formacie U2 Wykorzystanie metodologii RTL konieczna implementacja modułu realizującego funkcję f next Jest to najbardziej skomplikowana operacja Wykorzystanie ASMD
ƒ next (x) = x (x 3 17)/(3* x 2 ) = x (x 2 *x 17)/(3* x 2 ) Blok f next Kolejne przybliżenia reprezentowane są przez 10 bitową liczbę w kodzie U2 power2_in [9..0] x[9..0] Blok f next zostanie zbudowany z następujących elementów: power2 obliczanie x 2 multiply20b obliczanie x 2 *x multiply_by_3 obliczanie 3*x 2 divide30b obliczanie dzielenia power2_result [19..0] multiply20b_ina [19..0] multiply20b_inb [9..0] multiply_by_3_in [19..0] multiply_by_3_result [22..0] multiply20b_result [29..0] Bloki power2, multiply20b, multiply_by_3, divide30b zostaną wzięta z biblioteki gotowych komponentów. divide30b_ina [22..0] divide30b_inb [29..0] divide30b_result [29..0] xn[9..0] Mariusz Rawski 33
Realizacja bloku f next (1) library ieee; use ieee.std_logic_1164.all; use ieee.numeric_std.all; entity fnext is generic( number : integer := 1 port( x : in std_logic_vector(9 downto 0 xn : out std_logic_vector(9 downto 0) end fnext; Interfejs układu Wartość, z której liczony jest pierwiastek Deklaracja sygnałów do połączenia komponentów architecture structure of fnext is signal power2_in : std_logic_vector(9 downto 0 signal power2_result : std_logic_vector(19 downto 0 signal multiply20b_ina : std_logic_vector(19 downto 0 signal multiply20b_inb : std_logic_vector(9 downto 0 signal multiply20b_result : std_logic_vector(29 downto 0 signal multiply_by_3_in : std_logic_vector(19 downto 0 signal multiply_by_3_result: std_logic_vector(22 downto 0 signal divide30b_ina : std_logic_vector(22 downto 0 signal divide30b_inb : std_logic_vector(29 downto 0 signal divide30b_result : std_logic_vector(29 downto 0 Mariusz Rawski 34
Realizacja bloku f next (2) component power2 port ( dataa : in std_logic_vector(9 downto 0 result : out std_logic_vector(19 downto 0) end component; Deklaracja komponentów component multiply20b port ( dataa : in std_logic_vector(19 downto 0 datab : in std_logic_vector(9 downto 0 result : out std_logic_vector(29 downto 0) end component; component multiply_by_3 port ( dataa : in std_logic_vector (19 downt 0 result : out std_logic_vector (22 downt 0) end component; component divide30b port ( denom : in std_logic_vector(22 downto 0 numer : in std_logic_vector(29 downto 0 quotient : out std_logic_vector(29 downto 0 remain : out std_logic_vector(22 downto 0) end component; Mariusz Rawski 35
Realizacja bloku f next (3) begin b1 : power2 port map ( dataa => power2_in, result => power2_result Konkretyzacja komponentów i podłączenie do sygnałów end; b2 : multiply20b port map ( dataa => multiply20b_ina, datab => multiply20b_inb, result => multiply20b_result b3 : multiply_by_3 port map ( dataa => multiply_by_3_in, result => multiply_by_3_result b4 : divide30b port map( denom => divide30b_ina, numer => divide30b_inb, quotient => divide30b_result power2_in <= x; multiply_by_3_in <= power2_result; multiply20b_ina <= power2_result; multiply20b_inb <= x; divide30b_ina <= multiply_by_3_result; divide30b_inb <= std_logic_vector(signed(multiply20b_result) to_signed(number,30) xn <= std_logic_vector(signed(x) signed(divide30b_result(9 downto 0)) Mariusz Rawski 36
Realizacja bloku f next wyniki ƒ next (1) = 1 (1 3 17)/(3* 1 2 ) = 1 ( 5,33) = 6,33 ƒ next (2) = 2 (2 3 17)/(3* 2 2 ) = 2 ( 0,75) = 2,75 Pojawiają się błędy zaokrągleń. Fitter Summary Top-level Entity Name fnext Family Stratix Device EP1S10F484C5 Total logic elements 1,133/ 10,570 ( 11 % ) Total pins 20 / 336 ( 6 % ) Total virtual pins 0 Total memory bits 0 / 920,448 ( 0 % ) DSP block 9-bit elements 16 / 48 ( 33 % ) Total PLLs 0 / 6 ( 0 % ) Total DLLs 0 / 2 ( 0 % ) Mariusz Rawski 37
Metoda Newtona ASMD (1) entity top is port( rst : in std_logic; clk : in std_logic; start, load : in std_logic; data : in std_logic_vector(9 downto 0 ready : out std_logic; end top; result : out std_logic_vector(9 downto 0) architecture structure of top is constant valuetofindtherootof : natural := 17; type STATE_TYPE is (s0, s1, s2, s3, s4, s5, s6 signal state_reg, state_next : STATE_TYPE; signal ready_reg, ready_next : std_logic; signal cnt_reg, cnt_next : unsigned(3 downto 0 signal x_reg, x_next : signed(9 downto 0 signal result_reg, result_next : std_logic_vector(9 downto 0 Interfejs Liczba dla której liczony jest pierwiastek Stany automatu FSMD Rejestry modelujące zmienne algorytmu Sygnały do podłączenia modułu fnext Deklaracja komponentu fnext signal xn_function_in : std_logic_vector(9 downto 0 signal xn_function_result : std_logic_vector(9 downto 0 component fnext generic( number : integer := 99 port( x : in std_logic_vector(9 downto 0 xn : out std_logic_vector(9 downto 0) end component;
Metoda Newtona ASMD (2) begin process(clk, rst) begin if rst = '1' then cnt_reg <= (others => '0' x_reg <= (others => '0' result_reg <= (others => '0' elsif rising_edge(clk) then cnt_reg <= cnt_next; x_reg <= x_next; result_reg <= result_next; end if; end process; process(rst, clk) begin if rst = '1' then state_reg <= s0; ready_reg <= '0'; elsif rising_edge(clk) then state_reg <= state_next; ready_reg <= ready_next; end if; end process; Rejestry modelujące zmienne Rejestr stanu automatu FSMD Konkretyzacja komponentu i podłączenie sygnałów xn_function_in <= std_logic_vector(x_reg b1 : fnext generic map( number => valuetofindtherootof ) port map ( x => xn_function_in, xn => xn_function_result result <= result_reg; ready <= ready_reg;
Metoda Newtona ASMD (2) process(state_reg, start, load, cnt_reg, x_reg, result_reg) begin ready_next <= '0'; cnt_next <= cnt_reg; x_next <= x_reg; result_next <= result_reg; case state_reg is when s0 => if load = '1' then state_next <= s1; else state_next <= s0; end if; when s1 => x_next <= signed(data state_next <= s2; when s2 => if start = '1' then state_next <= s3; else state_next <= s2; end if; when s3 => cnt_next <= to_unsigned(0, 4 state_next <= s4; when s4 => x_next <= signed(xn_function_result if cnt_reg = 9 then state_next <= s6; else state_next <= s5; end if; when s5 => cnt_next <= cnt_reg + 1; state_next <= s4; when s6 => result_next <= std_logic_vector(x_reg ready_next <= '1'; state_next <= s0; when others => state_next <= s0; end case; end process; end; Wartości domyślne Opis zachowania się automatu FSM i rejestrów zmiennych
Realizacja ASMD wyniki 3 17 = 2,571281 Układ oblicza wartość z dużym błędem. 3 Dla 121 wynik jest 6 Podczas, gdy prawidłowa wartość to 4,946087 Fitter Summary Top-level Entity Name fnext Family Stratix Device EP1S10F484C5 Total logic elements 1,162/ 10,570 ( 11 % ) Total pins 25 / 336 ( 7 % ) Total virtual pins 0 Total memory bits 0 / 920,448 ( 0 % ) DSP block 9-bit elements 16 / 48 ( 33 % ) Total PLLs 0 / 6 ( 0 % ) Total DLLs 0 / 2 ( 0 % ) Mariusz Rawski 41
Liczby w notacji stałopozycyjnej (1) Liczby a = 15,671 b = 2,3 Suma 1 5, 6 7 1 + 2, 3 0 0 1 7, 9 7 1 Przy dodawaniu i odejmowaniu należy pamiętać by liczby miały ustawiony przecinek w tym samym miejscu. Natomiast przy mnożeniu i dzieleniu należy pamiętać o odpowiednim ustawieniu przecinka w wyniku Iloczyn 1 5, 6 7 1 2, 3 3 6, 0 3 3 3 Mariusz Rawski 42
Liczby w notacji stałopozycyjnej (2) Liczby a = 15,671 U2Fix5.3 = 01111.101 (15,625) b = 2,3 U2Fix3.5 = 010.01001 (2,28) Przy dodawaniu i odejmowaniu należy dopasować liczby w zapisie stałopozycyjnym by miały ten sam format ( ustawiony przecinek w tym samym miejscu). Suma 0 1 1 1 1, 1 0 1 0 0 + 0 1 0, 0 1 0 0 1 1 0 0 0 1, 1 1 1 0 1 Natomiast przy mnożeniu i dzieleniu należy pamiętać o tym jaki jest format wyniku (odpowiednim ustawieniu przecinka w wyniku) a+b 17,90625 U2Fix5.5 Iloczyn 0 1 1 1 1, 1 0 1 0 1 0, 0 1 0 0 1 1 0 0 0 1 1 1, 0 1 0 0 1 0 1 a b 35,64453125 U2Fix6.8 Mariusz Rawski 43
Blok f next Niech x będzie w formacie U2Fix 4.6 power2_result [19..0] U2Fix 8.12 Kolejne przybliżenia reprezentowane są przez 10 bitową liczbę w kodzie U2Fix4.6 x[9..0] multiply_by_3_in [19..0] U2Fix 8.12 multiply_by_3_result [22..0] U2Fix 11.12 multiply20b_ina [19..0] U2Fix 8.12 multiply20b_inb [9..0] U2Fix 4.6 multiply20b_result [29..0] U2Fix 12.18 multiply_by_3_in [19..0] (8.12) power2_in [9..0] (4.6) power2_result [19..0] (8.12) multiply20b_inb [9..0] (4.6) multiply20b_ina [19..0] (8.12) divide30b_ina [22..0] U2Fix 11.12 divide30b_inb [29..0] U2Fix 12.18 divide30b_result [29..0] U2Fix 24.6 multiply_by_3_result [22..0] (11.12) multiply20b_result [29..0] (12.18) Należy 17 zapisać w formacie U2Fix12.18 divide30b_ina [22..0] (11.12) divide30b_inb [29..0] (12.18) divide30b_result [29..0] (24.6) xn[9..0] Mariusz Rawski 44
Realizacja bloku f next Fix4.6 begin b1 : power2 port map ( dataa => power2_in, result => power2_result b2 : multiply20b port map ( dataa => multiply20b_ina, datab => multiply20b_inb, result => multiply20b_result Nie ma żadnych zmian w użytych komponentach. Operują one na wektorach binarnych Zapis liczby 17 w formacie U2Fix12.18 dodanie 18 zer na najmłodszych bitach end; b3 : multiply_by_3 port map ( dataa => multiply_by_3_in, result => multiply_by_3_result b4 : divide30b port map( denom => divide30b_ina, numer => divide30b_inb, quotient => divide30b_result power2_in <= x; multiply_by_3_in <= power2_result; multiply20b_ina <= power2_result; multiply20b_inb <= x; divide30b_ina <= multiply_by_3_result; divide30b_inb <= std_logic_vector(signed(multiply20b_result) shift_left(to_signed(number,30), 18) xn <= std_logic_vector(signed(x) signed(divide30b_result(9 downto 0)) Mariusz Rawski 45
Realizacja ASMD wyniki Liczba 1 w U2Fix4.6 to 64 3 17 = 2,571281 165 w zapisie U2Fix4.6 reprezentuje wartość 165/64 = 2.578125. Jest to już znacznie lepsze przybliżenie. Fitter Summary Top-level Entity Name fnext Family Stratix Device EP1S10F484C5 Total logic elements 1,144/ 10,570 ( 11 % ) Total pins 25 / 336 ( 7 % ) Total virtual pins 0 Total memory bits 0 / 920,448 ( 0 % ) DSP block 9-bit elements 16 / 48 ( 33 % ) Total PLLs 0 / 6 ( 0 % ) Total DLLs 0 / 2 ( 0 % ) Mariusz Rawski 46