CAD Synteza strukturalna rawski@tele.pw.edu.pl http://rawski.zpt.tele.pw.edu.pl/
Strukturalna realizacja przepływu danych Koncepcja zmiennych i sekwencyjnego wykonania operacji tak charakterystyczna dla algorytmów jest niestety całkowicie odmienna od modelu układu cyfrowego, w którym operacje wykonywane są współbieżnie. Jednym ze sposobów przekształcenia algorytmu w układ cyfrowy jest odwzorowanie algorytmu na układ kaskadowo połączonych bloków sprzętowych odpowiadających kolejnym akcjom procesu opisywanego przez algorytm. ego typu realizację można określić jako strukturalny przepływ danych (structural data flow). W przypadku algorytmu +3 wymaga to rozwinięcia pętli (loop unrolling). 2
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 ewtona load = 1 x = data start = 1 cnt = 0 iech ƒ next (x) = x (x 3 17)/(3* x 2 ). x = f next (x) Obliczanie wartości 3 17 można przeprowadzić algorytmem iteracyjnym. cnt = 9 cnt = cnt + 1 res = x ready = 1 3
Rozwijanie pętli Metoda ewtona x0 := data; a := pow2(x0); b := a * x0; c := 3 * a; d := b 17; e := d / c; x1 := x0 e; Jedna iteracja algorytmu a := pow2(x1); b := a * x1; c := 3 * a; d := b 17; e := d / c; x2 := x1 e;... a := pow2(x9); b := a * x9; c := 3 * a; d := b 17; e := d / c; x10 := x9 e; result:= x10 4
Realizacja Metoda ewtona (1) library ieee; use ieee.std_logic_1164.all; use ieee.numeric_std.all; entity top is port( rst ); end top; : in std_logic; clk : in std_logic; data : in std_logic_vector(9 downto 0); result : out std_logic_vector(9 downto 0) architecture structure of top is constant valueofindherootof : natural := 17; signal x_reg, x_next : std_logic_vector(9 downto 0); signal result_reg, result_next : std_logic_vector(9 downto 0); type SLICE is array(9 downto 0) of std_logic_vector(9 downto 0); signal xn_function_in : SLICE; signal xn_function_result : SLICE; begin process(clk, rst) begin if rst = '1' then x_reg <= (others => '0'); result_reg <= (others => '0'); elsif rising_edge(clk) then x_reg <= x_next; result_reg <= result_next; end if; end process; Rejestry modelujące zmienne Sygnały xn_function_in, xn_function_result tworzą warstwy, które można zadeklarować jako tablice array component xn_function generic( number : integer := 99 ); port( x : in std_logic_vector(9 downto 0); xn : out std_logic_vector(9 downto 0) ); end component; 5
Realizacja Metoda ewtona (2) x_next <= data; xn_function_in(0) <= x_reg; b0 : xn_function generic map( number => valueofindherootof ) port map ( x => xn_function_in(0), xn => xn_function_result(0) ); Dzięki temu, że układ ma strukturę warstwową, gdzie każda warstwa jest podobna można wykorzystać konstrukcję for-generate loop_slices: for i in 1 to 9 generate xn_function_in(i) <= xn_function_result(i-1); bi : xn_function generic map( number => valueofindherootof ) port map ( x => xn_function_in(i), xn => xn_function_result(i) ); end generate; result_next <= xn_function_result(9); result <= result_reg; end; 6
Realizacja strukturalna wyniki Fitter Summary op-level Entity ame bin2bcd_struct_data_flow Family Stratix Device EP1S30F780C5 otal logic elements 17,196 / 32,470 ( 53 % ) otal pins 22 / 598 ( 4 % ) otal virtual pins 0 otal memory bits 0 / 920,448 ( 0 % ) DSP block 9-bit elements 96 / 96 ( 100 % ) otal PLLs 0 / 6 ( 0 % ) otal DLLs 0 / 2 ( 0 % ) Wynik jest obliczany w jednym cyklu zegarowym, czyli wynik otrzymujemy po 1435 ns (1,435 us). Realizacja ASMD Częstotliwość zegara f max = 7,26 MHz (t max = 137,801 ns). Obliczanie wymaga 24 taktów zegara. Wynik otrzymujemy po 3307 ns (3,307 us) Fitter Summary op-level Entity ame ASMD Family Stratix Device EP1S10F484C5 otal logic elements 1,162/ 10,570 ( 11 % ) otal pins 25 / 336 ( 7 % ) otal virtual pins 0 otal memory bits 0 / 920,448 ( 0 % ) DSP block 9-bit elements 16 / 48 ( 33 % ) otal PLLs 0 / 6 ( 0 % ) otal DLLs 0 / 2 ( 0 % ) 7
Projekt do realizacji Konwerter kodu binarnego na kod BCD W kodzie BCD (Binary Coded Decimal) każda cyfra liczby zapisanej w kodzie dziesiętnym jest przedstawiana czterobitową liczbą binarną p. liczba 489 zostanie zapisana jako wektor binarny z wykorzystaniem 12 bitów (3 4 bity) 4 8 9 0100 1000 1001 BI/BCD Wejście Wyjście (00011011) BI (00100111) BCD 0 liczby 99 8
Metoda +3 Liczba konwertowana zapisana jest w postaci binarnej Przekształcenie polega na wykonaniu określonej liczby razy tych samych operacji Wykorzystuje proste operacje na liczbach binarnych: przesunięcie w lewo, zwiększenie o 3, porównanie ze stałą. Przy konwersji liczb z zakresu 0 99 można algorytm uprościć do{ }until(start = 1); binv := data; bcd_a := 0; bcd_b := 0; cnt := 8; do{ if bcd_b >= 5 then bcd_b := bcd_b + 3; end if if bcd_a >= 5 then bcd_a := bcd_a + 3; end if binv := shl(binv); bcd_a := shl(bcd_a,bcd_b3); bcd_b := shl(bcd_b,binv7); cnt := cnt - 1; }until (cnt = 0); 9
Przykład działania 0 0 0 0 0 0 0 0 27 = 0 0 0 1 1 0 1 1 LDA LDB LB 0 0 0 0 0 0 0 0 LDB 5 IE AK LDB := LDB LDB := LDB+3 8 10
LDA LDB LB LDB < 5 LDB < 5 LDB < 5 LDB < 5 LDB < 5 LDB < 5 LDB 5 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 1 1 6 0 1 1 0 0 0 0 0 1 1 0 + 0 0 1 1 1 2 3 4 5 7 0 0 0 1 1 0 1 1 0 0 0 1 1 0 1 1 1 1 0 1 1 1 1 0 1 1 1 0 1 1 1 1 0 0 0 0 1 0 0 1 LDB < 5 0 0 0 1 0 0 1 1 8 1 0 0 1 0 0 1 1 1 LD BCD = 0 0 1 0 0 1 1 1 = 27 2 7 11
Algorytm zapisany w języku C++ Kompilator Dev-C++ Kompilacja w systemie Windows XP Specyfikacja komputera: Procesor AMD Athlon 64X2 Dual Core 4200+ 2.2 GHz Pamięć RAM 1,96 GB DDR2 Konieczność symulowania operacji na rejestrach: przesunięcie w lewo, zwiększenie o 3, porównanie ze stałą. Realizacja programowa 12
Efektywność realizacji Szybkość działania szacowana liczbą konwersji na sekundę Przepustowość = 9,17 * 10 6 = 9,17 mln liczb binarnych na sekundę 13
Rozwijanie pętli binv_0 := data; bcd_a_0 := 0; bcd_b_0 := 0; if bcd_b_0 >= 5 then bcd_b_inc_0 := bcd_b_0 + 3; end if if bcd_a_0 >= 5 then bcd_a_inc_0 := bcd_a_0 + 3; end if binv_1 := shl(binv_0); bcd_a_1 := shl(bcd_a_inc_0,bcd_b_inc_0[3]); bcd_b_1 := shl(bcd_b_inc_0,binv_0[7]); if bcd_b_1 >= 5 then bcd_b_inc_1 := bcd_b_1 + 3; end if if bcd_a_1 >= 5 then bcd_a_inc_1 := bcd_a_1 + 3; end if binv_2 := shl(binv_1); bcd_a_2 := shl(bcd_a_inc_1,bcd_b_inc_1[3]); bcd_b_2 := shl(bcd_b_inc_1,binv_1[7]);... if bcd_b_7 >= 5 then bcd_b_inc_7 := bcd_b_7 + 3; end if if bcd_a_7 >= 5 then bcd_a_inc_7 := bcd_a_7 + 3; end if binv_8 := shl(binv_7); bcd_a_8 := shl(bcd_a_inc_7,bcd_b_inc_7[3]); bcd_b_8 := shl(bcd_b_inc_7,binv_7[7]); Jedna iteracja algorytmu konwersji, na którą składają się przekształcenia zwiększenie o 3, przesunięcie w lewo, itp. 14
Realizacja library ieee; use ieee.std_logic_1164.all; use ieee.numeric_std.all; entity bin2bcd_struct is port( rst : in std_logic; clk : in std_logic; data : in std_logic_vector(6 downto 0); digita : out std_logic_vector(3 downto 0); digitb : out std_logic_vector(3 downto 0) ); end bin2bcd_struct; Dzięki temu, że układ ma strukturę warstwową, gdzie każda warstwa jest podobna można wykorzystać konstrukcję for-generate bcd_a(0) <= (others => '0'); bcd_b(0) <= (others => '0'); loop_slices: for i in 0 to 7 generate bcd_a_inc(i) <= bcd_a(i) + 3 when bcd_a(i) >= 5 else bcd_a(i); bcd_b_inc(i) <= bcd_b(i) + 3 when bcd_b(i) >= 5 else bcd_b(i); bcd_a(i+1) <= bcd_a_inc(i)(2 downto 0)& bcd_b_inc(i)(3); bcd_b(i+1) <= bcd_b_inc(i)(2 downto 0)& binv(i)(7); architecture data_flow of bin2bcd_struct is type slicei is array (0 to 8) of unsigned(3 downto 0); type sliceii is array (0 to 8) of unsigned(7 downto 0); signal bcd_a, bcd_a_inc : slicei; signal bcd_b, bcd_b_inc : slicei; signal binv : sliceii; signal result_reg, result_next : std_logic_vector(7 downto 0); binv(i+1) <= binv(i)(6 downto 0)&'0' ; end generate; result_next <= (std_logic_vector(bcd_a(8)) & std_logic_vector(bcd_b(8))); digita <= result_reg(7 downto 4); digitb <= result_reg(3 downto 0); end data_flow; begin process(clk, rst) begin if rst = '1' then binv(0) <= (others => '0'); result_reg <= (others => '0'); elsif rising_edge(clk) then binv(0) <= 0 & unsigned(data); result_reg <= result_next; end if; end process; Sygnały bcd_a, bcd_a_inc itd tworzą warstwy, które można zadeklarować jako tablice array 15
Realizacja strukturalna wyniki Fitter Summary op-level Entity ame bin2bcd_struct_data_flow Family Stratix Device EP1S10F484C5 otal logic elements 20 / 10,570 ( < 1 % ) otal pins 17 / 336 ( 6 % ) otal virtual pins 0 otal memory bits 0 / 920,448 ( 0 % ) DSP block 9-bit elements 0 / 48 ( 0 % ) otal PLLs 0 / 6 ( 0 % ) otal DLLs 0 / 2 ( 0 % ) Liczba jest konwertowana w każdym cyklu zegarowym Przepustowość = 289,52 * 10 6 = 289,52 mln liczb binarnych na sekundę 16
Metodologia projektowania RL Metodologia projektowania na poziomie przesłań międzyrejestrowych RL umożliwia zastosowanie koncepcji zmiennych i sekwencyjnego charakteru wykonania operacji charakterystycznych dla algorytmów. W metodologii RL wykorzystuje się rejestry do przechowywania wartości pośrednich co modeluje zmienne obecne w algorytmie. Zaprojektowana przez projektanta ścieżka danych ma za zadanie realizować wymagane przez algorytm operacje na wartościach przechowywanych w rejestrach. Układ sterujący natomiast projektowany jest w taki sposób, aby określić kolejność operacji wykonywanych na rejestrach. 17
Realizacja systemu cyfrowego X Z D Z US UO X P Z Y F Układ operacyjny (UO) budowany jest z bloków funkcjonalnych Układ sterujący (US) tworzony jest jako automat (lub układ mikroprogramowany) 18
Realizacja US UO (Bin2BCD) (1) Rejestry binv, bcd_a, bcd_b z operacjami: zeruj wpisz, przesuń. start=1 binv := data bcd_a := 0 bcd_b := 0 cnt := 8 Licznik cnt z operacjami: wpisz, zmniejsz o 1. bcd_b >= 5 bcd_a >= 5 bcd_b := bcd_b + 3 Sumator bcd_a := bcd_a + 3 Komparator binv := shl(binv) bcd_a := shl(bcd_a,bcd_b 3 ) bcd_b := shl(bcd_b,binv 7 ) cnt := cnt - 1 cnt = 0 result := bcd_a, bcd_b ready := 1 19
Realizacja US UO (Bin2BCD) (2) - układ operacyjny 20
Realizacja US UO (Bin2BCD) (3) X Z D start=1 binv := data bcd_a := 0 bcd_b := 0 cnt := 8 bcd_b >= 5 bcd_a >= 5 bcd_b := bcd_b + 3 US Z X P UO binv := shl(binv) bcd_a := shl(bcd_a,bcd_b 3 ) bcd_b := shl(bcd_b,binv 7 ) cnt := cnt - 1 cnt = 0 result := bcd_a, bcd_b ready := 1 bcd_a := bcd_a + 3 X Z = {start} D = {data} Z = { bcd_a_clr, bcd_a_inc, bcd_a_shift, bcd_b_clr, bcd_b_inc, bcd_b_shift, binv_load, binv_shift, cnt_load, cnt_dec, result_store } X P Y Z = {cnt_is_0, bcd_a_gt_5, bcd_b_gt_5} = {ready} F = {result} Y Z F 21
Realizacja US UO (Bin2BCD) (4) - układ sterujący idle start=1 binv := data bcd_a := 0 bcd_b := 0 cnt := 8 start=1 binv_load bcd_a_clr bcd_b_clr cnt_load init cmpb bcd_b >= 5 bcd_b := bcd_b + 3 bcd_b_gt_5 = 1 bcd_b_inc incb bcd_a >= 5 cmpa bcd_a := bcd_a + 3 bcd_a_gt_5 = 1 inca binv := shl(binv) bcd_a := shl(bcd_a,bcd_b 3 ) bcd_b := shl(bcd_b,binv 7 ) cnt := cnt - 1 cnt = 0 result := bcd_a, bcd_b ready := 1 binv_shift bcd_a_shift bcd_b_shift cnt_dec cnt_is_0 = 1 done shift bcd_a_inc result_store ready := 1 22
Realizacja US UO (Bin2BCD) (5) - układ sterujący Układ sterujący ma za zadanie wymusić odpowiednią kolejność operacji R. Realizowany jest on w postaci maszyny stanów FSM tworzonej na podstawie algorytmu, który ma zostać zrealizowany. W najprostszy sposób można to zrobić konwertując schemat blokowy algorytmu na diagram algorytmicznego układu sekwencyjnego ASM (Algorithmic State Machine). Pozwala on reprezentować układy sekwencyjne w postaci sieci działań, co znacznie zwiększa czytelność opisu. 23
Realizacja US UO (Bin2BCD) (6) library ieee; use ieee.std_logic_1164.all; use ieee.numeric_std.all; entity bin2bcd_us_uo is port( rst : in std_logic; clk : in std_logic; start : in std_logic; data : in std_logic_vector(7 downto 0); ready : out std_logic; digita : out std_logic_vector(3 downto 0); digitb : out std_logic_vector(3 downto 0) ); end bin2bcd_us_uo; architecture RL of bin2bcd_us_uo is type state_type is (idle, init, cmpb, incb, cmpa, inca, shift, done); signal state_reg, state_next : state_type; signal ready_reg, ready_next : std_logic; signal binv_reg, binv_next : std_logic_vector(7 downto 0); signal bcd_a_reg, bcd_a_next : unsigned(3 downto 0); signal bcd_b_reg, bcd_b_next : unsigned(3 downto 0); signal cnt_reg, cnt_next : unsigned(3 downto 0); signal result_reg, result_next : std_logic_vector(7 downto 0); signal cnt_is_0 : std_logic; signal bcd_a_gt_5 : std_logic; signal bcd_b_gt_5 : std_logic; signal bcd_a_clr, bcd_a_inc, bcd_a_shift : std_logic; signal bcd_b_clr, bcd_b_inc, bcd_b_shift : std_logic; signal binv_load, binv_shift : std_logic; signal cnt_load, cnt_dec : std_logic; signal result_store : std_logic; Interfejs układu Deklaracja sygnałów reprezentujących automat sterujący Deklaracja sygnałów reprezentujących rejestry odpowiedniki zmiennych w algorytmie Deklaracja sygnałów kontrolnych Deklaracja sygnałów sterujących 24
Realizacja US UO (Bin2BCD) (7) process(clk, rst) begin if rst = '1' then state_reg <= idle; ready_reg <= '0'; elsif rising_edge(clk) then state_reg <= state_next; ready_reg <= ready_next; end if; end process; process(state_reg, start, cnt_is_0, bcd_a_gt_5, bcd_b_gt_5) begin bcd_a_clr <= '0'; bcd_a_inc <= '0'; bcd_a_shift <= '0'; bcd_b_clr <= '0'; bcd_b_inc <= '0'; bcd_b_shift <= '0'; binv_load <= '0'; binv_shift <= '0'; cnt_load <= '0'; cnt_dec <= '0'; result_store <= '0'; ready_next <= '0'; Definicja rejestru stanów i buforowanego wyjścia ready Opis funkcji przejść automatu Wartości domyślne sygnałów kontrolnych Zachowanie automatu sterującego case state_reg is when idle => if start = '1' then state_next <= init; else state_next <= idle; end if; when init => binv_load <= '1'; bcd_a_clr <= '1'; bcd_b_clr <= '1'; cnt_load <= '1'; state_next <= cmpb; 25
Realizacja US UO (Bin2BCD) (8) when cmpb => if bcd_b_gt_5 = '1' then state_next <= incb; else state_next <= cmpa; end if; when incb => bcd_b_inc <= '1'; state_next <= cmpa; when cmpa => if bcd_a_gt_5 = '1' then state_next <= inca; else state_next <= shift; end if; when inca => bcd_a_inc <= '1'; state_next <= shift; when shift => bcd_a_shift <= '1'; bcd_b_shift <= '1'; binv_shift <= '1'; cnt_dec <= '1'; if cnt_is_0 = '1' then state_next <= done; else state_next <= cmpb; end if; when done => result_store <= '1'; ready_next <= '1'; state_next <= idle; when others => state_next <= idle; end case; end process; Opis funkcji przejść automatu 26
Realizacja US UO (Bin2BCD) (9) process(clk, rst) begin if rst = '1' then binv_reg <= (others => '0'); bcd_a_reg <= (others => '0'); bcd_b_reg <= (others => '0'); cnt_reg <= (others => '0'); result_reg <= (others => '0'); elsif rising_edge(clk) then binv_reg <= binv_next; bcd_a_reg <= bcd_a_next; bcd_b_reg <= bcd_b_next; cnt_reg <= cnt_next; result_reg <= result_next; end if; end process; Definicja rejestrów części operacyjnej Opis działania rejestrów części operacyjnej binv_next <= data binv_reg(6 downto 0)&'0' binv_reg; when binv_load = '1' else when binv_shift = '1' else bcd_a_next <= (others => '0') when bcd_a_clr = '1' else bcd_a_reg(2 downto 0)& bcd_b_reg(3) when bcd_a_shift = '1' else bcd_a_reg + 3 when bcd_a_inc = '1' else bcd_a_reg; bcd_b_next <= (others => '0') when bcd_b_clr = '1' else bcd_b_reg(2 downto 0)& binv_reg(7) when bcd_b_shift = '1' else bcd_b_reg + 3 when bcd_b_inc = '1' else bcd_b_reg; cnt_next <= "1000" when cnt_load = '1' else cnt_reg - 1 when cnt_dec = '1' else cnt_reg; result_next<= (std_logic_vector(bcd_a_reg) & std_logic_vector(bcd_b_reg)) when result_store = '1' else result_reg; 27
Realizacja US UO (Bin2BCD) (10) cnt_is_0 <= '1' when cnt_next = 0 else '0'; bcd_a_gt_5 <= '1' when bcd_a_reg >= 5 else '0'; bcd_b_gt_5 <= '1' when bcd_b_reg >= 5 else '0'; Definicja sygnałów controlnych ready <= ready_reg; digita <= result_reg(7 downto 4); digitb <= result_reg(3 downto 0); end RL; Wyjścia Start konwersji Wynik 28
Realizacja US UO (Bin2BCD) wyniki Fitter Summary op-level Entity ame bin2bcd_us_uo Family Stratix Device EP1S10F484C5 otal logic elements 46 / 10,570 ( < 1 % ) otal pins 20 / 336 ( 6 % ) otal virtual pins 0 otal memory bits 0 / 920,448 ( 0 % ) DSP block 9-bit elements 0 / 48 ( 0 % ) otal PLLs 0 / 6 ( 0 % ) otal DLLs 0 / 2 ( 0 % ) Liczba jest konwertowana w (około) 28 cyklach zegarowych Przepustowość = 384,32 * 10 6 / 28 = 13,735 mln liczb binarnych na sekundę 29
Realizacja ASMD (1) Innym sposobem realizacji algorytmu z wykorzystaniem metodologii RL jest zastosowanie algorytmicznego układu sekwencyjnego ze zintegrowaną ścieżką przepływu danych ASMD (ASM with data path). start=1 binv := data bcd_a := 0 bcd_b := 0 cnt := 8 idle init W tym podejściu nie dzieli się układu na część operacyjną i sterującą z sygnałami sterującymi Z i stanu X P służącymi do komunikacji między nimi. Operacje R integruje się z opisem automatu sterującego. cmpb bcd_b >= 5 cmpa incb bcd_b := bcd_b + 3 Znacznie upraszcza to konwersję algorytmu na realizację w sprzęcie. bcd_a >= 5 inca bcd_a := bcd_a + 3 Operacje R przedstawione są bezpośrednio na diagramie zaś w klatkach decyzyjnych testuje się bezpośrednio wartości rejestrów reprezentujących zmienne. binv := shl(binv) bcd_a := shl(bcd_a,bcd_b 3 ) bcd_b := shl(bcd_b,binv 7 ) cnt := cnt - 1 cnt = 0 done result := bcd_a, bcd_b ready := 1 shift 30
Realizacja ASMD (2) library ieee; use ieee.std_logic_1164.all; use ieee.numeric_std.all; entity bin2bcd_asmd is port( rst : in std_logic; clk : in std_logic; start : in std_logic; data : in std_logic_vector(7 downto 0); ready : out std_logic; digita : out std_logic_vector(3 downto 0); digitb : out std_logic_vector(3 downto 0) ); end bin2bcd_asmd ; architecture RL of bin2bcd_asmd is type state_type is (idle, init, cmpb, incb, cmpa, inca, shift, done); signal state_reg, state_next : state_type; signal ready_reg, ready_next : std_logic; signal binv_reg, binv_next : std_logic_vector(7 downto 0); signal bcd_a_reg, bcd_a_next : unsigned(3 downto 0); signal bcd_b_reg, bcd_b_next : unsigned(3 downto 0); signal cnt_reg, cnt_next : unsigned(3 downto 0); signal result_reg, result_next : std_logic_vector(7 downto 0); Interfejs układu Deklaracja sygnałów reprezentujących automat sterujący Deklaracja sygnałów reprezentujących rejestry odpowiedniki zmiennych w algorytmie 31
Realizacja ASMD (3) process(clk, rst) begin end process; process(state_reg, start, cnt_next, bcd_a_reg, bcd_b_reg) begin ready_next <= '0 ; case state_reg is when idle => if start = '1' then state_next <= init; else state_next <= idle; end if; when init => state_next <= cmpb; when cmpb => if bcd_b_reg >= 5 then state_next <= incb; else state_next <= cmpa; end if; when shift => if cnt_next = 0 then state_next <= done; else state_next <= cmpb; end if; when done => ready_next <= '1'; state_next <= idle; when others => state_next <= idle; end case; end process; Definicja rejestru stanów bez zmian Do kontroli działania automatu sterującego nie wykorzystuje się specjalnie do tego celu przeznaczonych sygnałów ale bada się stan rejestrów ścieżki przepływy danych Czasami niezbędne jest wykorzystanie nowej wartości rejestru przed jej zatrzaśnięciem Zmienna cnt modyfikowana jest w tym samym bloku, w którym sprawdzana jest jej wartość 32
Realizacja ASMD (4) process(clk, rst) begin end process; process(state_reg, data, cnt_reg, bcd_a_reg, bcd_b_reg, result_reg) begin binv_next <= binv_reg; bcd_a_next <= bcd_a_reg; bcd_b_next <= bcd_b_reg; cnt_next <= cnt_reg; result_next <= result_reg; case state_reg is when idle => when init => binv_next <= data; bcd_a_next <= (others =>'0'); bcd_b_next <= (others =>'0'); cnt_next <= "1000"; when cmpb => when incb => bcd_b_next <= bcd_b_reg + 3; when cmpa => when inca => bcd_a_next <= bcd_a_reg + 3; when shift => binv_next <= binv_reg(6 downto 0)&'0' ; bcd_a_next <= bcd_a_reg(2 downto 0)& bcd_b_reg(3); bcd_b_next <= bcd_b_reg(2 downto 0)& binv_reg(7); cnt_next <= cnt_reg - 1; when done => result_next <= (std_logic_vector(bcd_a_reg) & std_logic_vector(bcd_b_reg)); when others => end case; end process; end RL; Definicja rejestrów ścieżki przepływu danych bez zmian Domyślne zachowanie rejestrów Zachowanie rejestrów w zadanym stanie 33
Realizacja ASMD wyniki Liczba jest konwertowana w (około) 28 cyklach zegarowych Przepustowość = 385,65 * 10 6 / 28 = 13,773 mln liczb binarnych na sekundę Fitter Summary op-level Entity ame Bin2bcd_ASMD Family Stratix Device EP1S10F484C5 otal logic elements 50 / 10,570 ( < 1 % ) otal pins 20 / 336 ( 6 % ) otal virtual pins 0 otal memory bits 0 / 920,448 ( 0 % ) DSP block 9-bit elements 0 / 48 ( 0 % ) otal PLLs 0 / 6 ( 0 % ) otal DLLs 0 / 2 ( 0 % ) 34
Operacje R realizowane w trybie Mealy ego ajczęściej algorytm, który ma zostać zrealizowany w postaci sprzętu można przekonwertować na kilka różnych diagramów ASM. Pozwala to realizować zadany algorytm na wiele różnych sposobów. Można zauważyć, że w algorytmie konwersji metodą + 3 operacje bcd_a := bcd_a + 3 i bcd_b := bcd_b + 3 wykonywane są warunkowo. ak naprawdę operacje zwiększenia zawartości rejestrów o 3 wykonywane są równolegle a decyzja czy wynik tych operacji ma być załadowany do rejestrów bcd_a i bcd_b podejmowana jest na podstawie testu warunków. Oznacza to, że w realizacji sprzętowej użyte zostaną dodatkowe multipleksery wybierające wartości, które mają zostać załadowane do rejestrów. 35
Realizacja ASMD Mealy (1) idle start=1 binv := data bcd_a := 0 bcd_b := 0 cnt := 8 bcd_b >= 5 inc bcd_b := bcd_b + 3 bcd_a >= 5 bcd_a := bcd_a + 3 binv := shl(binv) bcd_a := shl(bcd_a,bcd_b 3 ) bcd_b := shl(bcd_b,binv 7 ) cnt := cnt - 1 cnt = 0 shift result := bcd_a, bcd_b ready := 1 36
Realizacja ASMD Mealy (2) library ieee; use ieee.std_logic_1164.all; use ieee.numeric_std.all; entity bin2bcd_asmd_mealy is port( rst : in std_logic; clk : in std_logic; start : in std_logic; data : in std_logic_vector(7 downto 0); ready : out std_logic; digita : out std_logic_vector(3 downto 0); digitb : out std_logic_vector(3 downto 0) ); end bin2bcd_asmd_mealy; architecture RL of bin2bcd_asmd_mealy is type state_type is (idle, inc, shift); signal state_reg, state_next : state_type; signal ready_reg, ready_next : std_logic; signal binv_reg, binv_next : std_logic_vector(7 downto 0); signal bcd_a_reg, bcd_a_next : unsigned(3 downto 0); signal bcd_b_reg, bcd_b_next : unsigned(3 downto 0); signal cnt_reg, cnt_next : unsigned(3 downto 0); signal result_reg, result_next : std_logic_vector(7 downto 0); Interfejs układu Deklaracja sygnałów reprezentujących automat sterujący mniejsza liczba stanów Deklaracja sygnałów reprezentujących rejestry odpowiedniki zmiennych w algorytmie 37
Realizacja ASMD Mealy (3) begin process(clk, rst) begin if rst = '1' then state_reg <= idle; ready_reg <= '0'; elsif rising_edge(clk) then state_reg <= state_next; ready_reg <= ready_next; end if; end process; process(state_reg, start, cnt_next) begin ready_next <= '0'; case state_reg is when idle => if start = '1' then state_next <= inc; else state_next <= idle; end if; when inc => state_next <= shift; when shift => if cnt_next = 0 then ready_next <= '1'; state_next <= idle; else state_next <= inc; end if; when others => state_next <= idle; end case; end process; Prostszy automat 38
Realizacja ASMD Mealy (4) process(state_reg, start, data ) begin binv_next <= binv_reg; bcd_a_next <= bcd_a_reg; bcd_b_next <= bcd_b_reg; cnt_next <= cnt_reg; result_next <= result_reg; case state_reg is when idle => if start = '1' then binv_next <= data; bcd_a_next <= (others =>'0'); bcd_b_next <= (others =>'0'); cnt_next <= "1000"; end if; when inc => if bcd_b_reg >= 5 then bcd_b_next <= bcd_b_reg + 3; end if; if bcd_a_reg >= 5 then bcd_a_next <= bcd_a_reg + 3; end if; when shift => binv_next <= binv_reg(6 downto 0)&'0' ; bcd_a_next <= bcd_a_reg(2 downto 0)& bcd_b_reg(3); bcd_b_next <= bcd_b_reg(2 downto 0)& binv_reg(7); cnt_next <= cnt_reg - 1; if cnt_next = 0 then result_next <= (std_logic_vector(bcd_a_next) & std_logic_vector(bcd_b_next)); end if; when others => end case; end process; end RL; Wybór akcji dokonywany jest sposób charakterystyczny dla wyjść Mealy ego 39
Realizacja ASMD wyniki Liczba jest konwertowana w 18 cyklach zegarowych Przepustowość = 252,02 * 10 6 / 18 = 14,001 mln liczb binarnych na sekundę Fitter Summary op-level Entity ame bin2bcd_asmd_mealy Family Stratix Device EP1S10F484C5 otal logic elements 47 / 10,570 ( < 1 % ) otal pins 20 / 336 ( 6 % ) otal virtual pins 0 otal memory bits 0 / 920,448 ( 0 % ) DSP block 9-bit elements 0 / 48 ( 0 % ) otal PLLs 0 / 6 ( 0 % ) otal DLLs 0 / 2 ( 0 % ) 40
ewton synteza strukturalna X Z D load = 1 x = data Z start = 1 US UO cnt = 0 X P x = f next (x) cnt = 9 cnt = cnt + 1 res = x ready = 1 X Z Y Z = {start, load} D = {data} Z = {cnt_reset, cnt_count, x_load, x_update, result_load} X P Y Z = {cnt_done} = {ready} F = {result} F
ewton układ operacyjny (1) entity uo is generic( number : integer := 99 ); port( rst : in std_logic; clk : in std_logic; cnt_reset : in std_logic; cnt_count : in std_logic; x_load : in std_logic; x_update : in std_logic; result_load : in std_logic; data : in std_logic_vector(9 downto 0); cnt_done : out std_logic; result : out std_logic_vector(9 downto 0) end uo; architecture structure of uo is Interfejs układu operacyjnego Sygnały sterujące Sygnał kontrolny load = 1 x = data start = 1 cnt = 0 x = f next (x) cnt = 9 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); Rejestry zmiennych cnt = cnt + 1 res = x ready = 1 signal xn_function_in : std_logic_vector(9 downto 0); signal xn_function_result : std_logic_vector(9 downto 0); Sygnały połączeniowe dla komponentu xn_function component xn_function generic( number : integer := 99 ); port( x : in std_logic_vector(9 downto 0); xn : out std_logic_vector(9 downto 0) ); end component; Deklaracja komponentu xn_function
ewton układ operacyjny (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; Rejestry zmiennych load = 1 x = data start = 1 cnt = 0 cnt_next <= to_unsigned(0, 4) when cnt_reset = '1' else cnt_reg + 1 when cnt_count = '1' else cnt_reg; x = f next (x) x_next <= signed(data) when x_load = '1' else signed(xn_function_result) when x_update = '1' else x_reg; result_next <= std_logic_vector(x_reg) when result_load = '1' else result_reg; Obliczenie wartości następnej rejestrów zmiennych cnt = cnt + 1 cnt = 9 res = x ready = 1 cnt_done <= '1' when cnt_reg = 9 else '0'; xn_function_in <= std_logic_vector(x_reg); b1 : xn_function generic map( number => number ) port map ( x => xn_function_in, xn => xn_function_result ); result end; <= result_reg; Sygnały kontrolny Podłączenie komponentu xn_function Wyprowadzenie rejestru z wynikiem na wyjście
ewton układ sterujący (1) entity us is port( rst : in std_logic; clk : in std_logic; start, load : in std_logic; cnt_done : in std_logic; cnt_reset : out std_logic; cnt_count : out std_logic; x_load : out std_logic; ); end us; x_update : out std_logic; result_load : out std_logic; ready : out std_logic Interfejs układu operacyjnego Sygnał kontrolny Sygnały sterujące load = 1 x_load start = 1 cnt_reset x_upadate s0 s1 s2 s3 s4 architecture asm of us is type SAE_YPE is (s0, s1, s2, s3, s4, s5, s6); signal state_reg, state_next : SAE_YPE; signal ready_reg, ready_next : std_logic; begin 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; Deklaracja sygnałów rejestru stanów Deklaracja sygnałów rejestru sygnału ready Rejestry stanów i sygnału ready cnt_count cnt_done = 1 s5 result_load ready = 1 s6
ewton układ sterujący (2) process(state_reg, start, load, cnt_done) begin ready_next <= '0'; case state_reg is when s0 => if load = '1' then state_next <= s1; else state_next <= s0; end if; when s1 => state_next <= s2; when s2 => if start = '1' then state_next <= s3; else state_next <= s2; end if; when s3 => state_next <= s4; when s4 => if cnt_done = '1' then state_next <= s6; else state_next <= s5; end if; when s5 => state_next <= s4; when s6 => state_next <= s0; ready_next <= '1'; when others => state_next <= s0; end case; end process; Funkcja przejść automatu load = 1 cnt_count x_load start = 1 cnt_reset x_upadate cnt_done = 1 s5 s0 s1 s2 s3 s4 result_load ready = 1 s6
ewton układ sterujący (3) process(state_reg) begin cnt_reset <= '0'; cnt_count <= '0'; x_load <= '0'; x_update <= '0'; result_load <= '0'; case state_reg is when s0 => -- do nothing when s1 => x_load <= '1'; when s2 => -- do nothing when s3 => cnt_reset <= '1'; when s4 => x_update <= '1'; when s5 => cnt_count <= '1'; when s6 => result_load <= '1'; when others => -- do nothing end case; end process; ready <= ready_reg; end; Funkcja wyjść automatu load = 1 Wyprowadzenie sygnału ready cnt_count x_load start = 1 cnt_reset x_upadate cnt_done = 1 s5 s0 s1 s2 s3 s4 result_load ready = 1 s6
ewton top (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 valueofindherootof : natural := 17; component uo generic( number : integer := 99 ); port( ); end component; Interfejs układu Wartość, z której liczony jest pierwiastek Deklaracja komponentów układu operacyjnego i sterującego component us port( ); end component; signal cnt_reset_wire : std_logic; signal cnt_count_wire : std_logic; signal x_load_wire : std_logic; signal x_update_wire : std_logic; signal result_load_wire: std_logic; signal cnt_done_wire : std_logic; Deklaracja sygnałów połączeniowych układu operacyjnego i sterującego
ewton top (2) begin b1 : uo generic map( number => valueofindherootof ) port map( rst => rst, clk => clk, cnt_reset => cnt_reset_wire, cnt_count => cnt_count_wire, x_load => x_load_wire, x_update => x_update_wire, result_load => result_load_wire, data => data, cnt_done => cnt_done_wire, result => result ); Konkretyzacja komponentów i ich połączenie end; b2 : us port map( rst => rst, clk => clk, start => start, load => load, cnt_done => cnt_done_wire, cnt_reset => cnt_reset_wire, cnt_count => cnt_count_wire, x_load => x_load_wire, x_update => x_update_wire, result_load => result_load_wire, ready => ready );
ewton wyniki Fitter Summary op-level Entity ame fnext Family Stratix Device EP1S10F484C5 otal logic elements 1,156 / 10,570 ( 11 % ) otal pins 25 / 336 ( 7 % ) otal virtual pins 0 otal memory bits 0 / 920,448 ( 0 % ) DSP block 9-bit elements 16 / 48 ( 33 % ) otal PLLs 0 / 6 ( 0 % ) otal DLLs 0 / 2 ( 0 % ) 49