najczęściej popełniane błędy w vhdl’u

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

Upload: topper

Post on 19-Jan-2016

83 views

Category:

Documents


0 download

DESCRIPTION

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). - PowerPoint PPT Presentation

TRANSCRIPT

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

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

Ernest Jamro

Kat. Elektroniki

AGH

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

Wzory poprawnej syntezy

• ActiveHDL: Menu/Tools/Language Assistant: Synthesis Templates

• ISE Procject Navigator: Menu/Edit/Language Templates:

VHDL / Synthesis Constructs / (Coding Example)

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

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;

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

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;

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

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;

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

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;

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

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;

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

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

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

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;

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

Multiplekser Błędyprocess (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;

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

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

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

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;

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

Umiejscawianie komponentów 1entity 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;

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

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

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

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;

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

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;

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

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);

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

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

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

Ustawianie wartości parametrówArchitecture 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;

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

Dodawanie biblioteklibrary 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))

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

Programowanie pod kątem sprzętuPamięć 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>));

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

Programowanie pod kątem sprzętuPamięć 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>));

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

Programowanie pod kątem sprzętuBiblioteka: 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

);

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

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‘ )

Programowanie pod kątem sprzętu

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

library UNISIM;

use unisim.all; -- for global set reset signal

component ROC

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.

Programowanie pod kątem sprzętu

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

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

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

Poziomy logiczneStandard 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

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

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);

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

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;

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

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 bibliotekasignal 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;