BME-MIT FPGA labor HDL nyelvek: VHDL BUDAPESTI MŰSZAKI ÉS GAZDASÁGTUDOMÁNYI EGYETEM VILLAMOSMÉRNÖKI ÉS INFORMATIKAI KAR MÉRÉSTECHNIKA ÉS INFORMÁCIÓS RENDSZEREK TANSZÉK Fehér Béla Szántó Péter, Lazányi János, Raikovich Tamás BME MIT FPGA laboratórium
BME-MIT
FPGA labor
HDL nyelvek: VHDL
BUDAPESTI MŰSZAKI ÉS GAZDASÁGTUDOMÁNYI EGYETEM
VILLAMOSMÉRNÖKI ÉS INFORMATIKAI KAR
MÉRÉSTECHNIKA ÉS INFORMÁCIÓS RENDSZEREK TANSZÉK
Fehér Béla
Szántó Péter, Lazányi János, Raikovich Tamás
BME MIT
FPGA laboratórium
BME-MIT
FPGA labor
Strukturális elemek
• Entity: interfész megadás
• Architecture: viselkedés, funkcionalitás leírása
• Configuration: Architecture/Entity választás
• Package: függvények, típus deklarációk
• Library: lefordított VHDL objektumok
gyűjteménye
BME-MIT
FPGA labor
Entity
entity hadder is port ( a, b: in std_logic; s, co: out std_logic ); end hadder;
• Interfész megadás a modul és a külvilág között
BME-MIT
FPGA labor
Port típusok
• in
– Bemenet, csak olvasható
• out
– Kimenet, csak írható (!)
• buffer
– Kimenet, de olvasható, csak egy meghajtó jel
• inout
– Kétirányú port
BME-MIT
FPGA labor
Architecture
• A terv implementációt tartalmazó blokk
• Egy Entity tartalmazhat több Architecture-t
– Entity portok elérhetők az összes Architecture-ből
• Párhuzamosan végrehajtott utasításokat tartalmaz
entity hadder is port ( a, b: in std_logic; ……… ); end hadder; architecture rtl of hadder is ......... begin ……… ……… end rtl;
BME-MIT
FPGA labor
Strukturális leírás
• A VHDL támogatja a hierarchikus leírást, azaz a
komponensek „példányosítását”
– Komponens deklaráció
– Példányosítás (egyedi névvel)
– Port hozzárendelés
• név szerint
• sorrend szerint
BME-MIT
FPGA labor
Komponens deklaráció
architecture rtl of adder is ……… component hadder port ( a, b: in std_logic; s, co: out std_logic ); end component; ……… ……… ………
• Példányosítani kívánt komponensek deklarációja
BME-MIT
FPGA labor
Példányosítás (1) port(a, b, ci : in std_logic; so, co : out std_logic); …… …… architecture struct of adder is --komponens deklaráció signal c0, c1, s0 : std_logic; begin hadder_0: hadder port map(a, b, s0, c0); hader_1: hadder port map(s0, c0, so, c1); or_0: or2
port map(c0, c1, co);
BME-MIT
FPGA labor
Példányosítás (2) port(a, b, ci : in std_logic; so, co : out std_logic); …… …… architecture struct of adder is --komponens deklaráció signal c0, c1, s0 : std_logic; begin hadder_0: hadder port map(a=>a, b=>b, s=>s0, co=>c0); hader_1: hadder port map(a=>s0, b=>c0, s=>so, co=>c1); or_0: or2
port map(a=>c0, b=>c1, o=>co);
BME-MIT
FPGA labor
Példányosítás (3) port(a, b, ci : in std_logic; so, co : out std_logic); …… …… architecture struct of adder is -- NINCS komponens deklaráció!!! signal c0, c1, s0 : std_logic; begin hadder_0: entity work.hadder(rtl) port map(a=>a, b=>b, s=>s0, co=>c0); hader_1: entity work.hadder(rtl) port map(a=>s0, b=>c0, s=>so, co=>c1); or_0: entity work.or2(rtl)
port map(a=>c0, b=>c1, o=>co);
BME-MIT
FPGA labor
Package
• Package tartalmazhat:
– konstans deklarációk
– típus deklarációk
– komponensek
– szubrutinok
• Felhasználás Entity-ben:
package USER_PACK is ……… end USER_PACK;
use work.USER_PACK.all;
BME-MIT
FPGA labor
Package példa
library IEEE; use IEEE.STD_LOGIC_1164.all; package USER_PACK is function MIN (a: integer; b: integer) return integer; end USER_PACK; package body USER_PACK is function MIN( a: integer; b: integer) return integer is begin if (a<b) then return a; else return b; end if; end MIN; end USER_PACK;
BME-MIT
FPGA labor
Library
• Minden lefordított objektum Library-be kerül
– package, entity, architecture, configuration
• Saját objektumok: work library
• Standard library-k
• Felhasználás:
library IEEE; use IEEE.std_logic_1164.all;
BME-MIT
FPGA labor
Megjegyzések, konstansok
• Megjegyzések
– -- egy soros
– Nincs több soros
• Konstansok
– 1 bites: „0‟, „1‟
– Vektor
• Bináris: „00010010”
• Hexadecimális: x”AB” (a konstans és a változó
szélessége ugyanaz!!)
• CONV_STD_LOGIC_VECTOR(konstans, bitszám)
BME-MIT
FPGA labor
Adattípusok
• Standard adattípusok
– boolean (true, false)
– bit (0, 1)
– integer (platform függő, min. 32 bit)
– real (lebegőpontos, nem szintetizálható)
– time
• Library-kben előre definiált adattípusok
– szintézisre: std_logic_1164
• Saját adattípusok
BME-MIT
FPGA labor
Bit, integer
• Bit típus (csak 0, 1)
• Integer
• Szintézis után ugyanaz (lehet) az eredmény
signal sb : bit; signal sbv : bit_vector(3 downto 0); sb <= „0‟;
sbv <= „0000”; v. sbv <= x”A”;
signal si : integer range 0 to 15;
si <= 2;
BME-MIT
FPGA labor
Vektor változók
• Konkatenálás
– &: csak kifejezés jobb oldalán
• Csoportosítás
– (, , ,): kifejezés mindkét oldalán
• Kiválasztás
signal a2, b2, c2, d2: bit_vector(1 downto 0); signal a4, b4, c4: bit_vector(3 downto 0); a4 <= a2 & b2; (c2, d2) <= „0101”; d2 <= b4(2 downto 1);
c4 <= (0=>‟1‟, others=>‟0‟);
BME-MIT
FPGA labor
Time típus
• Mértékegység: fs, ps, ns, us, ms, sec, min, hr
• Szimulációhoz, modellezéshez használható
– végrehajtás késleltetése
– fizikai késleltetések modellezése
• Szorozható és osztható (eredmény: ‘time’):
– integer
– real
BME-MIT
FPGA labor
Time példa
constant PERIOD : time := 5 ns; begin process begin wait for PERIOD; ……… wait for 2*PERIOD; ……… wait for 3.5*PERIOD; ……… end process;
CLK <= not CLK after PERIOD/2;
BME-MIT
FPGA labor
IEEE std_logic
• std_ulogic, std_ulogic_vector, std_logic, std_logic_vector
• értékek:
– ` U `, nem inicializált
– ` X `, ismeretlen
– ` 0 `,
– ` 1 `,
– ` Z `, nagy impedanciás
– ` W `, ismeretlen (gyenge meghajtás)
– ` L `, gyenge 0
– ` H `, gyenge 1
– ` - `, don`t care
BME-MIT
FPGA labor
std_logic/std_ulogic
• Resolved/Unresolved
• Eredmény:
– std_logic: a = 1
– std_ulogic: ERROR
• Elvileg, de szintézer függő!
• Szimuláció alapállapot: U (undefined)
• Ipari szabvány: std_logic
a <= „1‟;
a <= b;
BME-MIT
FPGA labor
std_logic_arith (1)
• std_logic_arith package
– signed és unsigned datatípus
– NEM tud műveletet végezni std_logic_vector típuson
• std_logic_signed és std_logic_unsigned package
– std_logic_arith package kiterjesztése
– ugyanazokat a műveleteket ismeri, de std_logic típuson
– NEM használható egyszerre a kettő (egy file-ban)
• Történelmi hagyomány, NEM javasolt a használata
• Nem is igazán szabvány, IEEE megoldás hiányában a Synopsys kezdte el használni
signal a : signed(7 downto 0);
c <= signed(a)*signed(b);
BME-MIT
FPGA labor
std_logic_arith (2)
library ieee; use ieee.std_logic_1164.all; use ieee.std_logic_arith.all; use ieee.std_logic_signed.all; entity mul is port ( op_a, op_b : in std_logic_vector(17 downto 0); res : out std_logic_vector(35 downto 0) ); end mul; architecture rtl of mul is begin res <= op_a * op_b;
end mul;
BME-MIT
FPGA labor
IEEE.NUMERIC_STD (1)
• IEEE.NUMERIC_STD package
– signed és unsigned datatípus
• Operátorok
• Aritmetikai, logikai, shift
• RESIZE
• Típus konverziót meg kell adni
• std_logic_vector( signal név ): signed/unsigned std
• signed( signal név ): std signed
• 1 bit átadása st_logic-nak működik
signal a : signed(7 downto 0); signal a : unsigned(7 downto 0);
BME-MIT
FPGA labor
IEEE.NUMERIC_STD (2)
library IEEE; use IEEE.STD_LOGIC_1164.ALL; use IEEE.NUMERIC_STD.ALL; entity mul is port ( op_a, op_b : in std_logic_vector(17 downto 0); res : out std_logic_vector(35 downto 0) ); end mul; architecture rtl of mul is signal res_s: signed(35 downto 0); begin res_s <= signed(op_a) * signed(op_b); res <= std_logic_vector(res_s); end mul;
BME-MIT
FPGA labor
Tömbök
• Előre definiált méretű
• Deklarációkor állítható méret
• Index típus lehet bármi, de tipikusan csak az integer
szintetizálható
type array0 is array (15 downto 0) of std_logic_vector(7 downto 0);
signal m : array0;
type array0 is array (natural range <>) of std_logic_vector(7 downto 0);
signal m : array0(15 downto 0);
BME-MIT
FPGA labor
Record
• ~struktúra létrehozása
• record eleme lehet record
type date_r is record year : std_logic_vector(15 downto 0); month : std_logic_vector( 3 downto 0); day : std_logic_vector( 4 downto 0); end record; signal date0, date1, date2 : date_r; date0 <= (x”0000”, „0000”, „00000”); date1.year <= x”0000”;
date2 <= date1;
BME-MIT
FPGA labor
Egyedi típusok
• Tipikusan állapotgépekhez
– jobban olvasható kód
– limitált értékkészlet
• Értékadáskor, vizsgálatkor csak a definiált értékek
használhatók
• Szintézerek tipikusan automatikus leképzést (definíció -
bitminta) valósítanak meg
– De rögzíthető
type STATE_TYPE is (RED, GREEN, BLUE);
BME-MIT
FPGA labor
Logikai operátorok
• Prioritás: not; and, or, nand, xor, xnor
• Vektor változókon bitenként hajtódnak végre
– Minden operandusnak ugyanolyan típusúnak és méretűnek
kell lennie
BME-MIT
FPGA labor
Relációs operátorok
• <; <=; =; /=; >=; >
• Minden standard adattípusra definiált
• std_logic_vector
– std_logic_arith
– std_logic_signed/std_logic_unsigned package
• Előjeles változók!
BME-MIT
FPGA labor
Aritmetikai operátorok
• +; -; *; **; /; mod; abs; rem
• Előre definiált integer változókra
• std_logic_vector
– std_logic_arith
– std_logic_signed/std_logic_unsigned package
• NEM mindegyik szintetizálható
– tipikusan: +, -, *
BME-MIT
FPGA labor
Shift operátorok
• sll, srr
– logikai shiftelés
• sla, sra
– aritmetikai shiftelés
– az utolsó bit shiftelődik be
– általában megkötésekkel szintetizálható
• rol, ror
– rotálás
– a kieső bit shiftelődik be
– általában megkötésekkel szintetizálható
BME-MIT
FPGA labor
Konkurrens utasítások
• Architecture-ön belüli egyszerű értékadások
• Egymással és a process-ekkel párhuzamos
kiértékelés
• Signal típusú változónak adhatnak értéket
• A kifejezés bal oldala azonnal kiértékelődik ha a
jobb oldali változók megváltoznak
BME-MIT
FPGA labor
When
• Feltételes értékadás
– ÉRTÉK: konstans vagy signal
• When – Else: ~IF - ELSE szerkezet
• With – When: ~CASE szerkezet
CÉL <= ÉRTÉK_0 when FELTÉTEL_0 else ÉRTÉK_1 when FELTÉTEL_1 else …………
ÉRTÉK_N;
with VÁLTOZÓ select CÉL <= ÉRTÉK_0 when KONSTANS_0, ÉRTÉK_1 when KONSTANS_1 | KONSTANS_2, ………
ÉRTÉK_N when others;
BME-MIT
FPGA labor
When (példa)
res <= „001” when (din=1) else „010” when (din=2) else „011” when (din=4) else „100” when (din=8) else
„000”;
with din select res <= „001” when 1, res <= „010” when 2, res <= „011” when 4, res <= „100” when 8,
res <= „000” when others;
BME-MIT
FPGA labor
Process
• Architecture-ön belül használható
• A process-ek egymással (és a process-en kívüli
értékadásokkal) párhuzamosan hajtódnak végre
• A végrehajtást triggereli
– érzékenységi lista
– wait szerkezet
• Írható változók:
– signal
– variable (lokális változó)
– (shared variable)
BME-MIT
FPGA labor
Process
• Érzékenységi lista:
– a process végrehajtása ennek teljesülésekor történik
– szintérzékeny, élérzékeny process(a,b) begin c <= a or b;
end process;
process(clk) begin if (clk‟event and clk=„1‟) then c <= a or b; end if; end process;
process(clk) begin if rising_edge(clk) then c <= a or b; end if;
end process;
BME-MIT
FPGA labor
Szekvenciális kifejezések
• If szerkezet (csak process-ben)
• Case szerkezet (csak process-ben)
if FELTÉTEL then ……… elsif FELTÉTEL then ……… else ………
end if;
case KIFEJEZÉS is when ÉRTÉK_0 => ……… when ÉRTÉK_1 => ……… ………… when others => ………
end case;
BME-MIT
FPGA labor
For ciklus (1)
• Ciklus változó implicit deklarálva
• Ciklusok száma fix
• „Szekvenciális” végrehajtás, szintetizálható
– könnyű (túl) komplex logikát leírni !!
– „Gondolkozz HW fejjel” !!
• Pl.: 2:4 dekóder process(a) begin b <= „0000”; for I in 0 to 3 loop if (a=I) then b(I) <= „1‟; end if; end loop;
end process;
BME-MIT
FPGA labor
For ciklus (2) • Hexa decimális átalakítás
• Osztás, modulo képzés nem szintetizálható
• Kis változószélességre: ROM, VHDL kóddal számolva
dec_10 <= hex_num/10;
dec_1 <= hex_num mod 10;
process(hex_num) variable dec_v : std_logic_vector(3 downto 0); begin dec_v := (others=>'0'); for I in 1 to 15 loop if (hex_num = I) then dec_v := CONV_STD_LOGIC_VECTOR((I/10), 4); end if; dec_1 <= dec_v; end loop;
end process;
BME-MIT
FPGA labor
While ciklus
• Feltételtől függő számú ciklus végrehajtás
– feltétel függhet változótól
• Tipikusan NEM szintetizálható
• Szimulációban hasznos
while FELTÉTEL loop ……… ………
end loop;
BME-MIT
FPGA labor
Wait
• Wait felfüggeszti a process végrehajtását a feltétel
teljesüléséig
• NEM használható érzékenységi listával együtt
• Feltétel:
– adott ideig (szimuláció)
– jel értékétől függően
process(clk) begin if (clk‟event and clk=„1‟) then Q <= D; end if;
end prcess;
process begin Q <= D; wait until clk=„1‟;
end process;
BME-MIT
FPGA labor
Variable
• Process-en belül lokális (kivéve shared)
• Azonnali értékadás (signal: a process lefutása „után”)
• Értéke átadható signal-nak
• Értékét tartja a következő process „futásig”
• Pl.: túlcsordulás detekció:
process(clk) variable ovl : std_logic; begin ovl := not accu(34); for IB in 35 to 46 loop ovl := ovl or not accu(IB); end loop; ovl := ovl and accu(47); accu_ovl_n <= ovl;
end process;
BME-MIT
FPGA labor
Variable – signal (1)
process(clk) begin if rising_edge(clk) then d <= a + b; e <= d + c; end if;
end process;
BME-MIT
FPGA labor
Variable – signal (2)
process(clk) variable d : std_logic_vector(7 downto 0); begin if rising_edge(clk) then begin d := a + b; e <= d + c; end if;
end process;
BME-MIT
FPGA labor
Variable – signal (3)
process(clk) variable d : std_logic_vector(7 downto 0); begin if rising_edge(clk) then f <= d; d := a + b; -- ÉRTKADÁS SORREND!!!
e <= d + c; end if; end process;
BME-MIT
FPGA labor
Paraméterezhető modulok (1)
Entity deklaráció
entity adder generic( DWIDTH : integer ); port( a, b : in std_logic_vector(DWIDTH-1 downto 0); c : out std_logic_vector(DWIDTH downto 0) ); end adder; architecture rtl of adder is begin c <= („0‟ & a) + („0‟ & b);
end rtl;
BME-MIT
FPGA labor
Paraméterezhető modulok (2)
Példányosítás
……… ……… adder_16: entity work.adder(rtl) generic map( DWIDTH => 16 ) port map( a => in_data0, b => in_data1, c => out_data0 ); ……
……
BME-MIT
FPGA labor
Generate
• Architecture-en belül
• Struktúra ismétlése, tartalmazhat:
– Konkurrens értékadás
– Process
– Példányosítás
BME-MIT
FPGA labor
Generate példa
• Pl.: cím dekóder
• Eredmény:
– 16 db komparátor + 16 db ÉS kapu
signal cs_int : std_logic_vector(15 downto 0); GEN_CS_INT: for ICS in 0 to 15 generate cs_int(ICS) <= „1‟ when (cs=„1‟ and addr=ICS) else „0‟;
end generate;
BME-MIT
FPGA labor
Process – Flip Flop
• Flip Flop: élérzékeny D tároló
cba
clk
Q[0]D[0]
process (clk) begin if (clk‟event and clk=„1‟) then c <= a and b; end if;
end process;
process (clk) begin if rising_edge(clk) then c <= a and b; end if;
end process;
BME-MIT
FPGA labor
Process – Flip Flop
Szinkron reset Aszinkron reset
process(clk) begin if (clk‟event and clk=„1‟) then if (rst=„1‟) c <= „0‟; else c <= a and b; end if; end if;
end process;
cba
rst
clk
Q[0]D[0]R
process(clk, rst) begin if (rst=„1‟) c <= „1‟; elsif (clk‟event and clk=„1‟) then c <= a and b; end if;
end process;
BME-MIT
FPGA labor
Process – Flip Flop
• Xilinx FPGA-kban a FF egy CLK bemenettel, két
alaphelyzet beállító jellel és egy CE órajel engedélyező
bemenettel rendelkezik.
– Szinkron vezérlés: Minden jel kiértékelése szinkron, ebben
az esetben érvényesítés az órajel aktív élénél
process(clk) begin if (clk‟event and clk=„1‟) then if (rst=„1‟) then c <= „0‟; elsif (set=„1‟) then c <= „1‟; else c <= a and b; end if; end process;
R
S
cba
rst
setclk
Q[0]D[0]
BME-MIT
FPGA labor
Process – Flip Flop
• Xilinx FPGA-kban a FF egy CLK bemenettel, két
alaphelyzet beállító jellel és egy CE órajel engedélyező
bemenettel rendelkezik.
– Aszinkron vezérlés: A vezérlőjelek változása azonnal
érvényre jut, prioritás a felírás sorrendjében
R
S
cba
rst
setclk
Q[0]D[0]
process(clk, rst, set) begin if (rst=„1‟) then c <= „0‟; elsif (set=„1‟) then c <= „1‟; elsif (clk‟event and clk=„1‟) then c <= a and b; end if; end process;
BME-MIT
FPGA labor
Process – kombinációs logikához
• Szemléletesen:
– A process eseményvezérelt
– A bemenőjelek bármely változása ilyen esemény
– Ennek hatására az eljárás lefut, a kimenet
kiértékelődik
process (a, b) begin c <= a and b;
end process;
cba
BME-MIT
FPGA labor
Process – latch
• Latch tároló természetesen szándékosan is
generálható:
– Az engedélyező „gate” bemenet magas értéke
mellett a tároló transzparens, míg a „gate” bemenet
alacsony értéke mellett zárt, tartja értékét.
process (g, a, b) begin if (g=„1‟) then c <= a and b; end if; end process;
lat
c
cba
g
D[0]Q[0]
C
BME-MIT
FPGA labor
Process – latch hiba
• A tipikus véletlen „Latch”
– Nem teljes “if” vagy „case” szerkezet
– Szintézer általában figyelmeztet
process(sel,in0, in1, in2) begin case sel is when „00”=> r <= in0; when „01”=> r <= in1; when „10”=> r <= in2; end case; end process;
process(sel,in0, in1, in2) begin if (sel=0) then r <= in0; elsif (sel=1) then r <= in1; elsif (sel=2) then r <= in2; end if; end process;
BME-MIT
FPGA labor
Konkurrens értékadás – latch hiba
r <= in0 when (sel=0) else in1 when (sel=1) else
in2 when (sel=2);
with sel select r <= in0 when 0, r <= in1 when 1, r <= in2 when 2;
BME-MIT
FPGA labor
Process – helyes
• Helyes kód
process(sel,in0, in1, in2) begin case sel is when „00” => r <= in0; when „01” => r <= in1; when „10” => r <= in2; when others => r <= „X”; end case; end process;
process(sel,in0, in1, in2) begin if (sel=0) then r <= in0; elsif (sel=1) then r <= in1; else r <= in2; end if; end process;
BME-MIT
FPGA labor
Strukturális leírás
• Hierarchia felépítése: modulok összekapcsolása
signal xor0 : std_logic; …………… begin …………… xor_inst0 entity work.xor_m(rtl) port map(i0=>in0, i1=>in1, o=>xor0); xor_inst1 entity work.xor_m(rtl) port map(i0=>xor0, i1=>in2, o=>r); ……………
xor_m
xor_inst0
xor_m
xor_inst1
r
in2
in1
in0 i0
i1o i0
i1o
BME-MIT
FPGA labor
Strukturális leírás - generate
• Hierarchia felépítése: modulok összekapcsolása
in_bus0(0) <= in0; in_bus1 <= in2 & in1; GEN_INST: for I in 0 to 1 generate xor_inst entity work.xor_m(rtl) port map(i0=>in_bus0(I), i1=>in_bus1(I), o=>in_bus0(I+1)); end generate; r <= in_bus0(2);
xor_m
xor_inst0
xor_m
xor_inst1
r
in2
in1
in0 i0
i1o i0
i1o
BME-MIT
FPGA labor
Példa – MUX (1.)
• Különböző leírási stílusok a 2:1 multiplexerre
process(sel,in0, in1) begin case sel is when „0‟ => r <= in0; when „1‟ => r <= in1; end case; end process;
r <= in1 when (sel=„1‟) else in0;
process(sel,in0, in1) begin if (sel=1) then r <= in1; else r <= in0; end if; end process;
in_b <= in1 & in0; r <= in_b(CONV_INTEGER(sel));
BME-MIT
FPGA labor
Példa – MUX (2.)
• 4:1 multiplexer
0
1
0
1
r
in3
in2
in1
in0
sel[1:0]
I0
I1
[0] S
O[1]
[1]
process(sel, in0, in1, in2, in3) begin case sel is when „00” => r <= in0; when „01” => r <= in1; when „10” => r <= in2; when „11” => r <= in3; end case; end process;
BME-MIT
FPGA labor
Példa – 1 bites összeadó
xor_0: entity work.xor3_m(rtl) port map (i0=>a, i1=>b, i2=>cin, o=>s); and_0: entity work.and2_m(rtl) port map (i0=>a, i1=>b, o=>a0); and_1: entity work.and2_m(rtl) port map (i0=>a, i1=>cin, o=>a1); and_2: entity work.and2_m(rtl) port map (i0=>b, i1=>cin, o=>a2); or_0: entity work.or3_m(rtl) port map (i0=>a0, i1=>a1, i2=>a2, o=>cout);
s <= a xor b xor cin; cout <= (a and b) or (a and cin) or (b and cin);
signal dbus : std_logic_vector(1 downto 0); ……………… dbus <= a + b + cin; s <= dbus(0); cout <= dbus(1);
BME-MIT
FPGA labor
Példa – 4 bites összeadó
……… signal cout : std_logic_vector(3 downto 0); ……… add0: entity work.add1_full(rtl) port map (a=>a(0), b=>b(0), cin=>‟0‟, cout=>cout(0), s=>s(0)); add1: entity work.add1_full(rtl) port map (a=>a(1), b=>b(1), cin=>cout(0), cout=>cout(1), s=>s(1)); add2: entity work.add1_full(rtl) port map (a=>a(2), b=>b(2), cin=>cout(1), cout=>cout(2), s=>s(2)); add3: entity work.add1_full(rtl) port map (a=>a(3), b=>b(3), cin=>cout(2), cout=>s(4), s=>s(3)); ………
… a,b : in std_logic_vector(3 downto 0); s : out std_logic_vector(4 downto 0); …… s <= („0‟ & a) + („0‟ & b); ……
BME-MIT
FPGA labor
Példa – 4 bites összeadó, logikai op.
BME-MIT
FPGA labor
Példa – 4 bites összeadó, + operátor
BME-MIT
FPGA labor
Példa – 4 bites összeadó, +
LUT2_6
s_axb_1
LUT2_6
s_axb_2
LUT2_6
s_axb_3
LUT2_6
s_axb_0
XORCY
s_s_3
MUXCY
s_cry_3
XORCY
s_s_2
MUXCY_L
s_cry_2
XORCY
s_s_1
MUXCY_L
s_cry_1
MUXCY_L
s_cry_0
OBUF
s_obuf[4]
OBUF
s_obuf[3]
OBUF
s_obuf[2]
OBUF
s_obuf[1]
OBUF
s_obuf[0]
IBUF
b_ibuf[3]
IBUF
b_ibuf[2]
IBUF
b_ibuf[1]
IBUF
b_ibuf[0]
IBUF
a_ibuf[3]
IBUF
a_ibuf[2]
IBUF
a_ibuf[1]
IBUF
a_ibuf[0]
s[4:0][4:0]
b[3:0][3:0]
a[3:0][3:0]
[1]
[1]
[2]
[2]
[3]
[3]
[0]
[0]
[0]
[3]
[3] DI
CI
S
[4]
O
[2]
[2] DI
CI
S
LO
[1]
[1] DI
CI
S
LO
[0] DI
0 CI
[0] S
LO
[4] I[4]
O
[3] I[3]
O
[2] I[2]
O
[1] I[1]
O
[0] I[0]
O
[3] I[3]
O
[2] I[2]
O
[1] I[1]
O
[0] I[0]
O
[3] I[3]
O
[2] I[2]
O
[1] I[1]
O
[0] I[0]
O
BME-MIT
FPGA labor
Példa: Shift regiszter
• 16 bites shift regiszter,
– A LUT4 SRL16 soros shiftregiszter kihasználására
……… clk, sh, din: in std_logic; dout: out std_logic; ……… signal shr: std_logic_vector(15 downto 0); ……… process (clk) begin if (clk‟event and clk=„1‟) then if (sh=„1‟) then shr <= shr(14 downto 0) & din; end if; end if; dout <= shr(15);
BME-MIT
FPGA labor
Példa: Számláló
• Számláló minta leírás
– Szinkron, 8 bites
– Szinkron RESET
– Tölthető
– Engedélyezhető
– fel/le számláló
• Megj:
– A CE nagyobb
prioritású, mint a töltés,
ez nem tipikus
………… clk, rst, ce, load, dir : in std_logic; din: in std_logic_vector(7 downto 0), dout: out std_logic_vector(7 downto 0); ………… signal cntr_reg : std_logic_vector(7 downto 0); ………… process (clk) begin if (clk‟event and clk=„1‟) then if (rst=„1‟) then cntr_reg <= (others=>‟0‟); elsif (ce=„1‟) if (load=„1‟) then cntr_reg <= din; elsif (dir=„1‟) then cntr_reg <= cntr_reg – 1; else cntr_reg <= cntr_reg + 1; end if; end if; end if; end process; dout <= cntr_reg;
BME-MIT
FPGA labor
FPGA primitívek
• Minden FPGA erőforrás közvetlenül is beépíthető
• CLB
– LUT 16x1 bit ROM, RAM
– LUT 16x1 bit shift regiszter
– MUXFi, MUXCY, XORCY
– Flip-flop primitívek
• BlokkRAM
– 16384 bit dual port memória + paritás
– Paraméterezhető adatszélesség
• Hardver szorzó (aszinkron, szinkron)
BME-MIT
FPGA labor
LUT ROM
• ROM (aszinkron!)
– Xilinx primitívek
• ROM16X1, ROM32x1,…..
process (addr) begin case (addr) is when „0000” => dout <= ÉRTÉK_0; when „0001” => dout <= ÉRTÉK_1; ……… when „1111” => dout <= ÉRTÉK_15; end case;
end process;
BME-MIT
FPGA labor
LUT RAM
• RAM: szinkron írás, aszinkron olvasás
– Xilinx primitívek
• Single port: RAM16X1S, ….. Dual port: RAM16X1D,
type ram_array is array (15 downto 0) of std_logic; signal memory : ram_array; process (clk) begin if (clk‟event and clk=„1‟) then if (we=„1‟) then memory(CONV_INTEGER(addr)) <= din; end if; end if; end process;
dout <= memory(CONV_INTEGER(addr));
BME-MIT
FPGA labor
LUT RAM időzítés
• Olvasás: aszinkron
– Számlálóval generált címzés
• Írás: szinkron
– Írás történik a bejelölt órajel felfutó éleknél
0 1 2 3 4 5 6CÍM
D0 D1 D2 D3 D4 D5 D6ADAT
0 1 2 3 4 5 6CÍM
D0 D1 D2 D3 D4 D5 D6ADAT
WE
BME-MIT
FPGA labor
Shift regiszter
• LUT shift regiszter
– NINCS reset bemenet
– Xilinx primitívek: SRLC16, SRLC16E
signal srl : std_logic_vector(15 downto 0); process (clk) begin if (clk‟event and clk=„1‟) then if (en=„1‟) then srl <= srl(14 downto 0) & din; end if; end if; end process;
dout <= srl(CONV_INTEGER(addr));
BME-MIT
FPGA labor
Shift regiszter tömb
• Maximum 16 mély 8 bit széles késleltető regiszter type srl_ar is array (15 downto 0) of std_logic_vector(7 downto 0); signal srl : srl_ar; process (clk) begin if (clk‟event and clk=„1‟) then if (en=„1‟) then srl(0) <= din; for IW in 1 to 15 loop srl(IW) <= srl(IW-1); end loop; end if; end if; end process;
dout <= srl(CONV_INTEGER(addr));
BME-MIT
FPGA labor
BlockRAM
• Szinkron, dual port memória
– Méret: 16384 + 2048 (paritás)
– Adatszélesség: 1, 2, 4, 9, 18, 36 bit
– Portok:
• CLK, WE, EN, SSR (órajel, írás engedélyezés,
engedélyezés, reset)
• ADDR, DI, DO (cím, adat be-, kimenet)
• Minden bemenet mintavételezett
• Kimenet az órajel felfutó élt követően kb. 2-3 ns
– Xilinx primitívek
• Single port: RAMB16_S1…RAMB16_S36
• Dual port: RAMB16_S1_S1…RAMB16_S36_S36
BME-MIT
FPGA labor
BlockRAM időzítés
• Olvasás: szinkron
– Számlálóval generált címzés
• Írás: szinkron
– Írás történik a bejelölt órajel felfutó éleknél
0 1 2 3 4 5 6CÍM
D0 D1 D2 D3 D4 D5 D6ADAT
WE
0 1 2 3 4 5 6CÍM
D0 D1 D2 D3 D4 D5 D6ADAT
BME-MIT
FPGA labor
Írás-olvasás ütközés
• Írás alatt a BlockRAM adatkimenete (írási port)
– Nem változik (NO_ CHANGE)
– A régi adat kerül a kimenetre (READ_FIRST)
– Az éppen beírt adat kerül a kimenetre
(WRITE_FIRST)
• Dual-port konfiguráció esetében ha a két port címe
megegyezik, és az egyiken írás történik, a másik
adatkimenete érvénytelen (kivéve READ_FIRST
mód)
• Mindkét porton azonos címre történő írás
érvénytelenné teszi a beírt adatot
BME-MIT
FPGA labor
SP BlockRAM – Read First type MT is array (511 downto 0) of std_logic_vector(35 downto 0); signal mem : MT; process (clk) begin if (clk'event and clk='1') then if (ce='1') then if (we='1') then memory(CONV_INTEGER(addr)) <= din; end if; if (rst='1') then dout <= (others=>'0'); else dout <= memory(CONV_INTEGER(addr)); end if; end if; end if;
end process;
BME-MIT
FPGA labor
SP BlockRAM – Write First type MT is array (511 downto 0) of std_logic_vector(35 downto 0); signal mem : MT; process (clk) begin if (clk'event and clk='1') then if (ce='1') then if (we='1') then memory(CONV_INTEGER(addr)) <= din; end if; if (rst='1') then dout <= (others=>'0'); elsif (we=„1‟) then dout <= din; else dout <= memory(CONV_INTEGER(addr)); end if; end if; end if; end process;
BME-MIT
FPGA labor
True Dual-port memória
• Azonos órajelek
– Egy process, általában szintetizálható
• A két port különböző órajelről jár
– két process-ben kell ugyanazt a (memóriát
reprezentáló) változót írni
– Szintézer függő az implementáció
• signal típusú változó
• shared variable típus
BME-MIT
FPGA labor
Attribútumok
• Szintézer direktívák
– Attributum készlet szintézer függő
– Signal/variable, példány, entity, …
entity test is port( ………… ); attribute opt_mode: string; attribute opt_mode of test: entity is "area"; end test; architecture rtl of test is attribute max_fanout : string; signal res : std_logic_vector(7 downto 0); attribute max_fanout of res : signal is ”50”; begin ………… end rtl;
BME-MIT
FPGA labor
Attribútumok (1.)
• FSM_EXTRACT
• FSM_STYLE
• FSM_ENCODING
attribute FSM_EXTRACT : string; attribute FSM_EXTRACT of state: signal is „TRUE”;
attribute FSM_STYLE : string; attribute FSM_STYLE of state: signal is „lut”; -- LUT, BRAM
attribute FSM_ENCODING : string; attribute FSM_ENCODING of state: signal is „one-hot”; -- auto, one-hot, compact, sequential, gray, johnson, user
type state_type is (IDLE, CFG_RAM_RD, PREPARE, REQ, TRANSFER, SLAVE_TERM, CFG_RAM_WR); signal state : state_type; attribute fsm_encoding : string; attribute fsm_encoding of state : signal is "user"; attribute enum_encoding : string; attribute enum_encoding of state_type : type is "0000001 0000010 0000100 0001000 0010000 0100000 1000000";
BME-MIT
FPGA labor
Attribútumok (2.)
• REGISTER_DUPLICATION
• EQUIVALENT_REGISTER_REMOVAL
• REGISTER_BALANCING
attribute REGISTER_DUPLICATION : string; attribute REGISTER_DUPLICATION of test: entity is „yes”;
attribute EQUIVALENT_REGISTER_REMOVAL : string; attribute EQUIVALENT_REGISTER_REMOVAL of test: entity is „yes”;
attribute REGISTER_BALANCING : string; attribute REGISTER_BALANCING of test: entity is „yes”; -- signal/entity; yes, no, forward, backward
attribute MOVE_FIRST_STAGE : string; attribute MOVE_FIRST_STAGE of test: entity is „yes”;
attribute MOVE_LAST_STAGE : string; attribute MOVE_LAST_STAGE of test: entity is „yes”;
BME-MIT
FPGA labor
Attribútumok (3.)
• USE_CLOCK_ENABLE
• USE_SYNC_RESET
• USE_SYNC_SET
• Megj: setup time-ok: D: 0,27; CE: 0,47; RST: 0,78
attribute USE_CLOCK_ENABLE : string; attribute USE_CLOCK_ENABLE of data: signal is „yes”; -- signal, entity, component, instance; auto, yes, no
attribute USE_SYNC_RESET : string; attribute USE_SYNC_RESET of test: entity is „yes”;
attribute USE_SYNC_SET : string; attribute USE_SYNC_SET of test: entity is „yes”;
BME-MIT
FPGA labor
Attribútumok (4.)
• MAX_FANOUT
• KEEP
• IOB
attribute MAX_FANOUT : string; attribute MAX_FANOUT of data: signal is „5”; -- signal, entity; integer
attribute KEEP : string; attribute KEEP of data: signal is „TRUE”;
attribute IOB : string; attribute IOB of test: label is „TRUE”; -- component, entity, label; auto, true, false
BME-MIT
FPGA labor
Attribútumok (5.)
• ROM_STYLE
• RAM_STYLE
attribute ROM_STYLE : string; attribute ROM_STYLE of mem: signal is „distributed”; -- signal, entity; auto, block, distributed -- !! ROM_EXTRACT
attribute RAM_STYLE : string; attribute RAM_STYLE of data: signal is „block”; -- signal, entity; auto, block, distributed -- !! RAM_EXTRACT
BME-MIT
FPGA labor
Attribútumok (6.)
• USE_CARRY_CHAIN
• OPT_MODE
attribute USE_CARRY_CHAIN : string; attribute USE_CARRY_CHAIN of add: signal is „no”
attribute OPT_MODE : string; attribute OPT_MODE of test: entity is „area”; -- entity; area, speed
Példa: …… PORTOK …… ); attribute opt_mode: string; attribute opt_mode of test: entity is "area"; end test;
BME-MIT
FPGA labor
RLOC
attribute u_set : string; attribute u_set of XORCY_L_DW: label is ("SET" & str(NUM, 10)); attribute u_set of REG_OUT_DW: label is ("SET" & str(NUM, 10)); attribute rloc: string; attribute rloc of XORCY_L_DW : label is "X0Y0"; attribute rloc of REG_OUT_DW : label is "X0Y0"; muxcy_out(0) <= '0'; GEN_MUXCY: for I in 0 to DW generate mux_sel(I) <= (not op_a(I)) xor op_b(I); -- op_a != op_b MUXCY_L_i : MUXCY_L port map ( LO => muxcy_out(I+1), CI => muxcy_out(I), DI => op_a(I), S => mux_sel(I) ); end generate; XORCY_L_DW: XORCY_L port map ( LO => sub_res(DW), CI => muxcy_out(DW+1), LI => mux_sel(DW) ); REG_OUT_DW: FDCE port map ( Q => res(DW), C => clk, CE => en, CLR => '0', D => sub_res(DW) );
BME-MIT
FPGA labor
Időzítések (UCF)
• Csoportok
• Explicit
• „False Path”
• Clock-domain
INST „*cpu_if*” TNM=FFS TNM_CPU_REGS; INST „*filter*” TNM=FFS TNM_FILTER_REGS; -- FFS, RAMS, LATCHES, CPUS, MULTS
TIMESPEC "TS_FALSE1" = FROM "TNM_CPUREGS" TO „TNM_FILTER_REGS” 10 ns;
TIMESPEC "TS_FALSE1" = FROM "TNM_CPUREGS" TO „TNM_FILTER_REGS” TIG;
NET "clk1" TNM_NET = "clk1"; NET "clk2" TNM_NET = "clk2"; TIMESPEC “TS_clk1_to_clk2” = FROM “clk1” TO “clk2” 10 ns;
BME-MIT
FPGA labor
Elhelyezés
• Csoport
– GROUP: CLOSED, OPEN
– PLACE: CLOSED, OPEN
• Elemek hozzárendelése
AREA_GROUP "AGROUP1" RANGE = SLICE_X6Y11:SLICE_X9Y6 ;
INST "RAM_CCNT" AREA_GROUP = "AGROUP1";
BME-MIT
FPGA labor
Összefoglalás
• Az FPGA erőforrások használata a HDL nyelvekből különböző módokon is elérhető
• Érdemes a magasabb szintű leírást használni
– Kevesebb munka, tömör leírás
– Egyértelmű tervezői szándék specifikáció
– Eszköz független leírás, könnyebben migrálható más eszközökre
• A speciális funkciók, egyedi beállítások szükségessé tehetik az alacsonyszintű technológiai primitívek használatát