1 / 30

Najczęściej popełniane błędy w VHDL’u

Najczęściej popełniane błędy w VHDL’u. Ernest Jamro Kat. Elektroniki AGH. Wzory poprawnej syntezy. ActiveHDL: Menu/Tools/Language Assistant: Synthesis Templates ISE Procject Navigator: Menu/Edit/Language Templates: VHDL / Synthesis Constructs / (Coding Example).

topper
Télécharger la présentation

Najczęściej popełniane błędy w VHDL’u

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Najczęściej popełniane błędy w VHDL’u Ernest Jamro Kat. Elektroniki AGH

  2. Wzory poprawnej syntezy • ActiveHDL: Menu/Tools/Language Assistant: Synthesis Templates • ISE Procject Navigator: Menu/Edit/Language Templates: VHDL / Synthesis Constructs / (Coding Example)

  3. Poprawna składnia przerzutnikatypu D process (CLK, RESET) begin if RESET='1' then – reset asynchroniczny DOUT <= '0'; elsif (CLK'event and CLK='1') then DOUT <= DIN; end if; end process;

  4. Najczęstsze błędy process (CLK, RESET) – brak sygnału reset begin if RESET='1' then – reset asynchroniczny DOUT <= '0'; elsif (CLK'event and CLK='1') then DOUT <= DIN; end if; end process;

  5. Przerzutnik D z Clock Enable (CE) process (<clock>, <reset>) begin if <reset>=‘1' then <output> <= '0'; elsif (<clock>'event and <clock>='1') then if <clock_enable> = '1' then -- lub inna logika synchroniczna <output> <= <input>; end if; end if; end process;

  6. Błędy: Przerzutnik z CE process (<clock>, <reset>, <clock_enable>) begin if <reset>='0' then <output> <= '0'; elsif (<clock>'event and <clock>='1‘ and <clock_enable> = '1' ) <output> <= <input>; end if; end process;

  7. Błąd: Wymuszenie tego samego sygnału w dwóch procesach A0: process(...) begin .... if ( ...) a<= ‘0’; end if; end process; A1: process(...) begin .... if ( ...) a<= ‘1’; end if; end process;

  8. Przerzutnik typu Latch process (GATE, DIN) begin if GATE='1' then --GATE active High DOUT <= DIN; end if; end process; Przerzutników Latch należy raczej unikać – z reguły powstają one w wyniku błędu a nie zamierzonego projektowania

  9. Multiplekser (lub inna logika kombinacyjna) process (SEL, A, B, C) begin case SEL is when "00" => MUX_OUT <= A; when "01" => MUX_OUT <= B; when "10" => MUX_OUT <= C; when others => MUX_OUT <= 'X'; end case; end process;

  10. Multiplekser Błędy process (SEL, A, B, C)– brak jednego z sygnałów wejściowych (latch) begin case SEL is when "00" => MUX_OUT <= A; when "01" => MUX_OUT <= B; when "10" => MUX_OUT <= C; when others => MUX_OUT <= 'X'; end case; end process;

  11. Process – magiczne słowo Poza procesem nie można używać następujących składni: If ... Then ... Elsif ... End if For .... Loop Uwaga: Wiele operacji (szczególnie logiki kombinacyjnej) można umieścić poza procesem

  12. Alternatywne rozwiązanie Multiplekser • Mux_out<= A when sel = "00" else • B when sel = "01" else • C when sel = "10" else '-'; • LUB • WITH sel SELECT • Mux_out <=A when"00", • B when "01", • C when "10" • '-' when others; • inB AFTER 10 NS WHEN OTHERS;

  13. Umiejscawianie komponentów 1 entity FULL_ADDER port ( a, b, cin: in std_logic; s, cout: out std_logic); end FULL_ADDER; architecture arch of FULL_ADDER is begin s<= a xor b xor c; cout<= a when a=b else cin; end arch;

  14. Umiejscawianie komponentów 2 entity MY_ADDER generic (width: integer); port ( a, b: in std_logic_vector(0 to width-1); s: out std_logic_vector(0 to width-1); end MY_ADDER; architecture arch of MY_ADDER is component FULL_ADDER -- deklaracja komponentu port ( a, b, cin: in std_logic; s, cout: out std_logic); end component; signal carry: std_logic_vector(0 to dwidth); begin

  15. Umiejscawianie komponentów 3 Ciąg dalszy z poprzedniej strony (rozwiązanie nieoptymalne) Carry(0)<= ‘0’; Gi: for i in 0 to width-1 generate – wielokrotne użycie elementu! g: full_adder port map (a=> a(i), b=> b(i), cin=> carry(i), cout=> carry(i+1), s=> s(i)); end generate; end arch; Lepsze rozwiązanie (użyta dedykowana logika dodająca) s<= a+ b;

  16. Wartości domyślne, uaktualnienie modułów Stary komponent component and_gate port ( din1, din2: in std_logic; dout: out std_logic); end component; Nowy komponent component and_gate generic (invert_output: integer:= 0); -- dodanie dodatkowego parametru port ( din1, din2, din3: in std_logic:= ‘1’; -- wartość domyślna ‘1’ dout: out std_logic); end component;

  17. Użycie zmodyfikowanego komponentu Stary kod używa nowego elementu z nowymi wartościami w formie domyślnej A: and_gate port map (din1=> a, din2=> b, dout => y); Równoważne i zalecane w nowym kodzie: A: and_gate generic map (invert_output=>0) port map (din1=> a, din2=> b, din3=> ‘1’, dout => y);

  18. Po co wartości domyślne • Rozważany element jest elementem nadrzędnym podczas symulacji lub implementacji • Zgodność z poprzednimi wersjami tego samego elementu bez konieczności zmiany całego starego kodu

  19. Ustawianie wartości parametrów Architecture arch of my_gate is component and_gate generic (invert_output: integer:= 1); -- nie zmieniamy wartości parametru tutaj port ( din1, din2, din3: in std_logic:= ‘0’; -- nie zmieniamy wartości domyślnej tutaj dout: out std_logic); end component; begin a: and_gate -- użycie elementu generic map (invert_output=> 1) -- umieszczamy wartość każdego parametru port map (din1=> a, din2=> b, din3=> ‘0’); -- staramy się określić wartość każdego wejścia End arch;

  20. Dodawanie bibliotek library ieee; use ieee.std_logic_1164.all;-- użycie std_logic use ieee.std_logic_unsigned.all; -- każda wartość std_logic_vector jest traktowana jako integer bez znaku use ieee.std_logic_signed.all; -- każda wartość std_logic_vector jest traktowana jako integer ze znaku Nie można równocześnie użyć obu bibliotek: std_logic_unsigned oraz std_logic_signed. W tym wypadku należy użyć biblioteki: use ieee.std_logic_arith.all; oraz zamiast słowa kluczowego std_logic_vector należy użyć słów unsigned lub signed (wada: konieczność używania konwersji std_logic_vector  unsigned (lub signed))

  21. Programowanie pod kątem sprzętu Pamięć RAM 16x1 (distributed RAM) type mem_type is array (0 to 15) od std_logic_vector(0 to 7) signal mem: mem_type; begin process (<clock>) begin if (<clock>'event and <clock> = '1') then if (<write_enable> = '1') then mem(conv_integer(<address>)) <= <input_data>; end if; end if; end process; <ram_output> <= mem(conv_integer(<address>));

  22. Programowanie pod kątem sprzętu Pamięć blokowa BRAM (dwuportowa) PortA: process (<clockA>)begin if (<clockA>'event and <clockA> = '1') then if (<write_enableA> = '1') then <ram_name>(conv_integer(<addressA>)) <=<input_dataA>; end if; <addressA_sig> <= <addressA>; end if; end process; PortB: process (<clockB>)begin if (<clockB>'event and <clockB> = '1') then <addressB_sig> <= <addressB>; end if; end process; <ram_outputA> <= <ram_name>(conv_integer(<addressA_sig>)); <ram_outputB> <= <ram_name>(conv_integer(<addressB_sig>));

  23. Programowanie pod kątem sprzętu Biblioteka: unisim a pamięć blokowa BRAM entity RAMB16_S36_S36 is generic ( INIT_00 : bit_vector := X"0000000000000000000000000000000000000000000000000000000000000000"; .... INIT_3F : bit_vector := X"0000000000000000000000000000000000000000000000000000000000000000" ); port( DOA : out STD_LOGIC_VECTOR (31 downto 0);DOB : out STD_LOGIC_VECTOR (31 downto 0); DOPA : out STD_LOGIC_VECTOR (3 downto 0);DOPB : out STD_LOGIC_VECTOR (3 downto 0); ADDRA : in STD_LOGIC_VECTOR (8 downto 0);ADDRB : in STD_LOGIC_VECTOR (8 downto 0); CLKA : in STD_ULOGIC;CLKB : in STD_ULOGIC; DIA : in STD_LOGIC_VECTOR (31 downto 0);DIB : in STD_LOGIC_VECTOR (31 downto 0); DIPA : in STD_LOGIC_VECTOR (3 downto 0);DIPB : in STD_LOGIC_VECTOR (3 downto 0); ENA : in STD_ULOGIC;ENB : in STD_ULOGIC; SSRA : in STD_ULOGIC;SSRB : in STD_ULOGIC; WEA : in STD_ULOGIC;WEB : in STD_ULOGIC );

  24. Programowanie pod kątem sprzętu Biblioteka unisim: Pętla DLL (delay lock loop – działająca podobnie jak PLL) entity CLKDLL is port ( CLK0 : out std_ulogic := '0'; CLK180 : out std_ulogic := '0'; CLK270 : out std_ulogic := '0'; CLK2X : out std_ulogic := '0'; CLK90 : out std_ulogic := '0'; CLKDV : out std_ulogic := '0'; LOCKED : out std_ulogic := '0'; CLKFB : in std_ulogic := '0'; CLKIN : in std_ulogic := '0'; RST : in std_ulogic := '0‘ )

  25. Programowanie pod kątem sprzętu library UNISIM; use unisim.all; -- for global set reset signal componentROC port ( O : out std_ulogic := '1' ); end component Każdy przerzutnik powinien być zerowany (ustawiany) asynchronicznie tym sygnałem – jest to potrzebne zarówno do celów symulacyjnych jak i dla potrzeb ustawiania (wartość ‘1’) po procesie konfiguracji.

  26. Reset synchroniczny i asynchroniczny • Reset asynchroniczny należy używać jako reset inicjalizujący pracę układu FPGA po konfiguracji – jest on wspomagany sprzętowo • Reset synchroniczny (np. opb_rst) należy używać jako sygnał zerujący w pozostałych przypadkach np. podczas zerowania liczników, powtórnej inicjalizacji automatów, itd. • Nie należy mieszać resetów synchronicznych i asynchronicznych

  27. Poziomy logiczne Standard std_logic zawiera wiele poziomów nie tylko ‘0’, ‘1’, co może powodować inne zachowanie układu podczas symulacji funkcjonalnej, po syntezie i w rzeczywistym układzie. Przykład: if ce=‘1’ then Q<= D; end if; Co się stanie jeżeli dana wejściowa ce jest typu: ‘H’, ‘X’, ‘Z’ itd

  28. Operacje na wektorach - przesunięcia signal a, b: std_logic_vector(dwidth-1 downto 0); -- deklaracja wektorów, dwidth- szerokość wektora Przesuniecie o jeden bit w lewo (pomnożenie przez 2): a<= b(dwidth-2 downto 0) & ‘0’ Przesuwający o jeden bit w prawo (dzielenie liczb dodatnich przez 2): a<= ‘0’ & ‘b(dwidth-1 downto 1) ; Dzielenie liczb w kodzie uzupełnień do 2 przez 2: a<= b(dwidth-1) & b(dwidth-1) & b(dwidth-2 downto 1); -- kopiowanie bitu znaku b(dwidth-1) Przesunięcie o n-bitów w lewo (n- constant lub generic): a(dwidth-1 downto n)<= b(dwidth-1-n downto 0); a(n-1 downto 0)<= (others=>’0’); Podzielenie przez 2n liczby w kodzie U2: a(dwidth-1 downto dwidth-n-1)<= (others=> b(dwidth-1)); a(dwidth-2-n downto 0)<= b(dwidth-2 downto n);

  29. Operacje logiczne na wektorach signal c, a, b: std_logic_vector(dwidth-1 downto 0); -- deklaracja wektorów c<= a and b; Równoważne: Gi: for i in 0 to dwidth-1 generate c(i)<= a(i) and b(i); end generate;

  30. Operacje logiczne w ramach jednego wektora Operacje logicze w ramach jednego wektora: library IEEE; use IEEE.STD_LOGIC_1164.all; use IEEE.STD_LOGIC_MISC.all; -- dodatkowa biblioteka signal a: std_logic_vector(dwidth-1 downto 0); signal y: std_logic; y<= OR_REDUCE(a); Równoważne: y<= a(0) or a(1) or a(2) or ..... or a(dwidth-1); Równoważne: Process(a) variable b: std_logic; begin b:= ‘0’; for i in 0 to dwidth-1 loop b:= b or a(i); end loop; end process;

More Related