PROTOTÍPUSKÉSZÍTÉS VERILOG NYELVEN
Előadó: Dr. Oniga István
Összeállította Dr. Oniga István A következő anyagok felhasználásával • Digitális rendszerek tervezése FPGA áramkörökkel. Fehér Bela Szanto Peter, Lazanyi Janos, Raikovich Tamas (BME Merestechnika es Informacios Rendszerek Tanszek) • Embedded Design using Programmable Gate Arrays. Arrays Dennis Silage • Introduction I t d ti tto V Verilog il course. Xilinx Xili Inc. I
FPGA-k
•
FPGA: Field Programmable Gate Array –
• •
programozható logikai áramkör
JJelentősebb l tő bb gyártók: á tók Xilinx, Xili Altera, Alt Actel, A t l Quicklogic, Q i kl i LLattice tti Jellemzők – – –
A funkciót, funkciót működést a konfiguráció határozza meg A konfiguráció esetleg módosítható, törölhető Komplexitás p • • •
–
50000 – 8000000 kapu 100 – 600 I/O láb 100 – 400 MHz működés (terv függő)
Felépítés lehet pl. RAM alapú, MUX alapú
Xilinx FPGA-k •
Több család – –
•
Spartan: hatékony, optimalizált struktúra Virtex: speciális p funkciók, gy gyorsabb, komplexebb, p ggazdagabb g funkcionalitás
Felépítés: – – – – –
CLB: logikai blokk IOB: I/O blokk BlokkRAM: belső memória Szorzó Huzalozás
Xilinx FPGA: Alap logikai elem •
Logikai elem (Slice): 2 LUT + 2 FF + kiegészítő logika Carry OUT
L U T
4 LUT
I N
Carry C + MUX
Comb. OUT
FF
FF OUT
MUX IN •
LUT: Look-Up Table – – – –
Carry Ca y IN
16x1 bites memória (4 bemenet esetén) Cím: a logikai függvény bemeneti változói Tartalom: igazságtábla Bármilyen négy bemenetű, egy kimenetű logikai függvény megvalósítható
Xilinx FPGA FPGA-k k •
Részlet egy kész tervből: logikai blokkok + huzalozás
Xilinx FPGA FPGA-k: k: a logikai elem részletei
• A CLB belső felépítése az FPGA Edit b nézve Editor-ban é
Xilinx FPGA: konfiguráció •
• •
A kkonfigurációt fi á iót (LUT tartalom, t t l huzalozás, h l á csatlakozások, tl k á k egyéb éb paraméterek) ét k) SRAM tárolja Tápfeszültség kikapcsolásakor elveszíti a konfigurációt Bekapcsolás után konfiguráció szükséges – –
EEPROM-ból,, automatikusan Fejlesztői kábel segítségével ún. JTAG porton keresztül
Szabvány HDL nyelvek •
Szabványos HDL (hardware description language) nyelvek –
Verilog • • • • • •
–
1984: Gateway Design Automation Inc. 1990: Cadence -> Open Verilog International 1995: IEEE szabványosítás 2001: Verilog 2001 Verilog-2005 (IEEE Standard 1364-2005) SystemVerilog (IEEE standard P1800-2005).
VHDL • • •
1983-85: IBM, Texas Instruments 1987: IEEE szabvány 1994 VHDL-1993 1994: VHDL 1993
Egyéb HDL • • •
HDL fejlesztés a szoftver fejlesztéshez viszonyítva továbbra is időigényes Sok fejlesztő rendelkezik C/C++ ismerettel, viszonylag kevés HDL ismerettel Magasszintű hardver leíró nyelvek – – – –
• •
Celoxica Handel-C: C alapú, spec. kiegészítések SystemC: szabványos, ma már (részben) szintetizálható, C++ alapú Mentor Catapult-C: C++ kiegészítések nélkül Impulse-C, Mitrion-C
Gyorsabb y szimuláció/verifikáció HW/SW együttes tervezés
HDL nyelvek célja
•
Hardver modellezés –
–
•
•
Mindkét nyelv jelentős része csak a hardver funkciók modellezésére ill. szimulációra használható Szintetizálható részhalmaz szintézer függő
Kapuszintű modulokból építkező, kapcsolási rajzon alapuló tervezési módszerek leváltása RTL (register transfer level) szintű leírás – –
Automatikus hardver szintézis a leírásból Tervezői hatékonyság növelése
HDL nyelvek
• •
Alapvetően moduláris felépítésű tervezést tesz lehetővé HDL modul – –
•
Be-, kimenetek definiálása B ki Be-, kimenetek t k kö közötti ötti llogikai ik i kkapcsolatok l t k éés idő időzítések íté k definiálása d fi iálá
NEM szekvenciálisan végrehajtódó szoftver –
Alapvetően időben párhuzamos, párhuzamos konkurens működést ír le
Szintaktika
•
Megjegyzések (mint C-ben) – –
•
// /* */
egy soros több soros
Konstansok –
<‘alap><érték> < alap><érték> • • •
5’b00100: bináris szám 8’h4e: hexadecimális szám 4’bZ: bináris szám
decimális érték: 4, 5 bites: 00100 decimális érték: 78, 8 bites: 1001110 nagy impedanciás állapot: ZZZZ
–
Ha a bitszám nem adót, adót az alapértelmezet: 32 bit
–
Ha az alap nem specifikált, az alapértemezet decimális
Szintaktika • • • • • • • • • • • •
138 // decimal number, 32 bit as 00000000000000000000000010001010 10′d138 // decimal number, 10 bit as 0010001010 6′o74 // octal number, 6 bits as 111100 24′h25F // hexadecimal number, 24 bit as 000000000000001001011111 8′hxB // hexadecimal number, 8 bit as xxxx1011 3′b010 // binary bi number, b 3 bit bits as 010 -6′b101 // 6 bit, two’s complement of 000101 or 111011 -10 10′d15 d15 // 10 bit bit, two two’ss complement of 0000001111 or 1111110001 5′d124 // decimal number, 5 bits as 11100 since 7 bits are required 12′oF2 12 oF2 // invalid, invalid F is not a octal digit 8’b1010 – Automatically zero-extended and stored as 0000_1010 44’b10110111 b10110111 – Automatically truncated and stored as 0111
Modulok • „Építőelem” komplex rendszerek létrehozására • Hierarchikus leírás, feladat partícionálás • Top-down tervezés
Verilog: module (1995)
• • Dupla p munka,, kettős hibalehetőségg
Verilog: module (2001)
Preferált a kompakt lista, kevesebb hiba
Modul használat .... wire clock, reset; wire local_bus_in, _ _ local_bus_out; _ _ something inst_name ( .clock (clock), .resett (reset), ( t) .bus_in (local_bus_in), .bus_out bus out (local_bus_out) (local bus out) ); Almodulban „Itteni” valtozo deklaralt valtozo
Strukturális leírás • Hierarchia felépítése: modulok összekapcsolása module top p_level ((input p in0,, in1,, in2,, output p r); ); wire xor0; xor_m xor_inst0(.i0(in0), .i1(in1), .o(xor0)); xor_m xor_inst1(.i0(xor0), i t1( i0( 0) .i1(in2), i1(i 2) .o(r)); ( )) endmodule
Bitműveletek •
Logikai műveletek bitvektorokon (egy vagy több bites adatokon) – – – –
•
4’b1101 & 4’b0110 = 4’b0100
Ha a két operandus p szélessége g nem egyezik gy meg, g, a kisebbik az MSB biteken 0val kiterjesztve –
•
NAND, NOR NOR, XNOR.
Vektorokon bitenként, bitenként pl pl.:: –
•
~ negálás, & és, ~& | or, ~| ^ xor, ~^
2’b11 & 4’b1101 = 4’b0001
A felteteles kifejezesek logikai operatorai az igaz-hamis vizsgalatokhoz elterőek: –
!, &&, || (negalas, es, vagy)
Bit redukciós operátorok •
•
• • • • •
Egy operandusú művelet, a bitvektor összes bitjét önálló egybites változóként értelmezve, eredménye is egy bites (Egy vektor összes bitjén végeznek műveletet, kimenetük egy bites) &, ~&, |, ~|, ^, ~^ (es, nem es, vagy, nem vagy) Peldak: • &4’b1101 = 1’b0 • ||4’b1101 = 1’b1 Hasznalat: • Számláló kimenet végérték? •
•
assign tc = &cnt;
• ALU kimenet nulla? •
assign z = ~|result;
Komparátor operátorok •
C i t k i l megegyezőő C-szintakszissal
•
Egyenlőség gy g – –
– •
==, != ===: egyenlőség lő é az „x, z”” éértékek ték k figyelembevételével !==: nem egyenlő, „x, z” figyelembevételével
Nem egyenlőség –
<, >, <=, >=
Aritmetikai operátorok
• •
C-szintakszissal megegyező Operátorok: p +,, -,, *,, /,, % – Nem mindegyik szintetizálható •
–
Szintézer függő, függő de tipikusan / pl. pl csak akkor, akkor ha az osztó kettő hatvány
Negatív számok kettes komplemens kódban
Egyéb operátorok •
•
•
•
Konkatenálás (összefűzés): {}, pl: – {4’b0101, 4’b1110} = 8’b01011110 Shift operátor – <<, >> Bit ki kiválasztás ál tá – Kiválasztott rész konstans: data[5:3] Pl. – – – –
wire [ 31:0 ] DATA_BUS ; wire [ 0:7 ] H_BYTE ; reg [15:0 ] CONTROL ; assign DATA_BUS DATA BUS [ 31:28 ] = H H_BYTE BYTE [ 4:7 ] ;
Bit kiválasztás használata •
Pl. –
•
Kiválasztás iránya meg kell egyezzen az eredeti iránnyal – – – –
•
reg [ 7:0 ] CNTRL_BUS = 8’b11100011;
CNTRL_BUS CNTRL BUS [ 3:0 ] CNTRL_BUS [ 0:3 ] C CNTRL_BUS S [ 10:7 ] CNTRL_BUS [ 3:0 ]
OK ERROR returns unknown ‘x’ has value of 3 (0011)
Egy bit kiválasztása: –
assign H_BYTE H BYTE [ 7 ] = CONTROL [ 14 ] ;
Adattípusok „„wire” e assign ass g – Nevének megfelelően viselkedik (vezeték) – Pl. 8 bites vezeték: wire [7:0] data; • „reg „reg” always – Szintézis utáni eredmény nem mindig regiszter •
• • •
–
Vezeték Latch Flip-flop
Pl : reg [7:0] data; Pl.:
Assign • •
•
„assign”-val g csak „wire” típusú p változónak lehet értéket adni Folyamatos értékadás – A bal oldali változó folyamatosan kiértékelődik Pl. – assign c = a & b; a b
• •
•
c
Egy változó csak egy „assign” által kaphat értéket assign értékadások egymással párhuzamosan műkődnek (hardver) Kombinációs logika leírására alkalmas
Always két esete • Kombinációs logika always @ (a, b) c <= a & b;
a b
c
always l @ (*) c <= a & b;
• Flip-Flop clk
always @ (posedge clk) c <= a & b;
a b
D[0] Q[0]
c
Always blokk • Szintakszis: always @ (….) begin ….. ….. end
• • • • •
Érzékenységi lista Blokkon belüli műveletek
Egy gy változó csak egy gy always y blokkban kaphat p értéket always blokk nem lehet érzékeny a saját kimenetére always y blokkban nem használható assign g Az always blokkok egymással (es az assign típusú értékadásokkal) é é adáso a ) pá párhuzamosan u a osa működnek ű öd e
Always – értékadás • Blokkoló értékadás: = – Blokkolja az utána következő értékadásokat -> szekvenciális utasítás végrehajtás • Nem blokkoló értékadás: <= – A nem blokkoló értékadások párhuzamosan hajtódnak végre • Blokkoló – nem blokkoló példa később • Nem-blokkoló értékadás használata javasolt
Always – Flip Flop • Flip Flop: élérzékeny tároló always @ (posedge clk) c <= a & b;
clk a b
D[0] Q[0]
c
• Szinkron reset always y @ (p (posedge g clk)) if (rst) c <= 1'b0; else c <= a & b;
• Aszinkron reset always @ (posedge clk, posedge rst) if (rst) c <= < 1 1'b0; b0; else c <= a & b;
clk
a b
rst
D[0] Q[0] R
c
Always – Flip Flop • Xilinx FPGA-kban a FF maximum 3 élérzékeny bemenettel rendelkezik, ezek (prioritas sorrendben): reset, set, clock • A reset, t sett lehet l h t szinkron i k i is • Aszinkron: always @ (posedge clk, posedge rst, posedge set) if (rst) c <= 1'b0; else if (set) c <= 1'b1; 1 b1; else c <= a & b;
clk set a b rst
S D[0] Q[0] R
c
Always – komb. log. •
Szemléletesen: kombinációs logika esetén a kimenet bármely b bemenet t bármilyen bá il változásánál ált á á ál kié kiértékelődik ték lődik
always @ (a, b) c <= a & b; a b
always @ (*) c< <= a & b;
c
Always – latch •
Latch: szintvezérelt tároló: amíg a „gate” bemenente ‘1’, addig mintavételezi i t ét l i az adatbemenetet d tb t t
always @ (*) If (g) c <= a & b;
a b g
l t lat
D[0] C
Q[0]
c
c
Always – latch hiba •
Latch “véletlen” létrehozása – Nem teljes “if” vagy „case” szerkezet – Szintézer általában figyelmeztet
always @ (*) case (sel) 2’b00: r <= in0; 2’b01 r <= iin1; 2’b01: 1 2’b10: r <= in2; endcase always @ (*) if (sel==0) r< <= in0; else if (sel==1) r <= in1; else if (sel==2) (sel 2) r <= in2;
Always – helyes •
Helyes kód always @ (*) case (sel) 2’b00: 2 b00: r <= in0; 2’b01: r <= in1; 2’b10: r <= in2; default: r <= ‘bx;; endcase always @ (*) () if (sel==0) r <= in0; else if (sel==1) (sel 1) r <= in1; else r <= in2;;
Tervezési tanácsok • • • • • • • • • • • •
– 1 modul, egy funkcióért felelős (pl. órajel generátor, összeadó blokk, szűrő blokk, memória tömb etc...) – Minden modulban az always es assign utasítások párhuzamosan értékelődnek ki. ki – Always blokkban nem használunk assignt! – Egy gy always y blokk egy gy jjól meghatározott g funkciót tölt be. (pl. shift regiszter, multiplexer, órajel osztó etc.) – Egy always blokk egyetlen vagy néhány – funkciójában szorosan kapcsolódó- reg változónak ad értéket. – Minden (reg) változónak csak 1 always blokkban adjunk értéket.
Logikai operátorok & & Logikai og a ÉS S • | | Logikai OR • ! Logikai negáció •
•
Pl. x = 1001 és y = 0110 x && y = 0 x || y = 1
Prototípuskészítés Verilog nyelven
Logikai shift operátorok > > Logikai og a sshift jobb jobbraa – ba balról ó 0 töltődik ö őd • < < Logikai shift balra – jobbról 0 töltődik •
•
Pl. x = 10011100 x >> 2 = 00100111 x << 2 = 01110000
Prototípuskészítés Verilog nyelven
Aritmetikai shift operátorok >>> Aritmetikai e a sshift jobb jobbraa – ba balról ó MSB S töltődik ö őd • <<< Aritmetikai shift balra – jobbról 0 töltődik •
•
Pl. x = 10011100 x >>> 2 = 11100111 x <<< 2 = 01110000 (x << 2 = 01110000)
•
Logikai shift balra = Aritmetikai shift balra
Prototípuskészítés Verilog nyelven
Feltétel leírása • • •
• • •
? : Pl. assign wire_name = (condition) ? input1 : input0; c = (a > b) ? 1 : 0; // c = 1 vagy 0 c = ((a == b)) ? a – b : a + b; // c = a – b vagy gy a + b c = (a – b) > 4 ? a : b; // c = a vagy b IF utasítás
CASE utasítás
always @ ( * ) - always @ (posedge clk) if (condition0) sstatement0; a e e 0; else if (condition1) statement1; else St t Statement2; t2
always @ ( * ) - always @ (posedge clk) case (two_bit select) 2'b00 : statement0;; 2'b01 : statement1; 2'b10 : statement2; 2'b11 : statement3; d f lt statement_def; default: t t t d f endcase
Prototípuskészítés Verilog nyelven
Modul működés leírása
•
Három alapvető modell típus –
Strukturális modell • •
Explicit strukturális modell Implicit strukturális modell
–
Procedurális modell
–
a fentiek keveréke is lehet
Prototípuskészítés Verilog nyelven
Explicit strukturális modell •
•
•
•
Strukturális modellek objektumokat kapcsolnak össze a kívánt működésű rendszer megvalósításához. Megadja a felhasznált elemeket és az elemek összekapcsolását – Kapcsolat K l t az azonosítók ítók pozíciója í iój szerint i t – Kapcsolat név szerinti egymáshoz rendeléssel Az elem lehet egy, a nyelv által definiált funkcionális alapelem (primitive) vagy egy általunk külön definiált modul (UDP).
Pl. module Nand_Latch (output q, qbar, input preset, clear); wire preset, clear; nand #1 G1 (q, p preset,, q qbar), ), G2 (qbar, clear, q); Endmodule (#1) - 1ns késleltetést jelent (csak a szimulációnál van értelme) Prototípuskészítés Verilog nyelven
Explicit strukturális modell • KAPU SZINTŰ PRIMITIVEK (26 beépített, kombinációs) • FELHASZNÁLÓI PRIMITIVEK (kombinációs, szekvenciális) • Tranzisztor kapcsolási szintű primitívek • Modul deklaráció és hivatkozás • Késleltetési modellek: a kapuk inerciális, a huzalok transzport modellel • 4 értékű logika, 8 meghajtáserősséggel • Huzalozott AND és OR logikák g
Prototípuskészítés Verilog nyelven
Implicit strukturális modell •
• •
• •
RTL modell vagy adatfolyam (dataflow) - előre definiált nyelvi operátorokat és a k k konkurens “f “folytonos l t kij kijelölés" lölé " utasítást t ítá t hhasználja álj a llogikai ik i működés űködé előírására. lőí á á Az operátorok közvetve (implicit) meghatározzák a megvalósító hardvert is. Az ilyen közvetett strukturális modellek alapján a szintézer programok könnyen tudnak közel optimális logikai hálózatot generálni. assign folytonos értékadási utasítást használjuk. Pl. module vagy (output o, input a, b); assign o = a | b; endmodule
module vagy4 (output [3:0] o, input [3:0] a, b); assign o = a | b; // Bitenkénti OR endmodule
Operátorok “rugalmasak” Prototípuskészítés Verilog nyelven
Procedurális modell •
•
Algoritmikus működési leírás magasszintű HDL műveleti utasításokkal, ami a kívánt I/O működést írja le, le függetlenül a konkrét hardver megvalósítástól A korszerű szimulátorok mindig eseményvezéreltek, és a Verilog nyelv is a viselkedés eseményvezérelt kiértékelését támogatja.
module compare_2_ algoritmikus (output reg A_lt_B, A_gt_B, A_eq_B, input [1:0] A,B); always @ (A or B) // Esemény figyelő begin A lt B = 0; A_lt_B 0 A_gt_B = 0; A_eq_B = 0; if ((A==B)) A_eq_ eq B = 1;; else if (A>B) A_gt_B = 1; else A_lt_B = 1; end endmodule d d l
Always csak állapottartó, regiszter típusú változókat tud kezelni, ezért a kimeneti változók á to ó a de deklaráció a ác ó szerint s e t regiszter eg s te ttípusúak pusúa A begin ….end programrészleten belül SZEKVENCIÁLIS a programvégrehajtás. Prototípuskészítés Verilog nyelven
Szimuláció •
Testbench: ISE két lehetőséget biztosít – Testbench Waveform •
–
Verilog Test Fixture •
•
Grafikus felületen megadható bemenetek Verilog kódban megírt stimulus stim l s
Szimulátor – ISE szimulátor – Modelsim (MXE)
Prototípuskészítés Verilog nyelven
Verilog Test Fixture •
Test Fixture – – – –
•
A Test Fixture egy Verilog modul A tesztelendő modul almodulként van beillesztve Minden, a szintézisnél használt nyelvi elem felhasználható Nem szintetizálható nyelvi y elemek
Időalap –
‘timescale 1ns/1ps • •
Megadott idők ns-ban értendők Szimulációs lépésköz: 1 ps
Prototípuskészítés Verilog nyelven
Test Fixture - initial •
„initial” blokk – – –
•
0. időpillanatban kezdődik a végrehajtása Egyszer fut le Az „initial” blokkok egymással, és az „always” blokkokkal párhuzamosan működnek
Az „initial” blokkon belüli késleltetések összeadódnak, pl.
initial begin a <= 0; #10 a <= 1; #25 a <= 2; #5 a <= 0; end
Prototípuskészítés Verilog nyelven
1 0
10
2 35 40
0
Test Fixture - always •
Órajel generálás
initial clk <= 1; always #5 clk <= ~clk; •
Órajelre működő bemenetek (pl. (pl számláló)
initial cntr <= 0; always @ (posedge clk) #2 cntr <= cntr + 1;
0
1
tOH =2ns Prototípuskészítés Verilog nyelven
2
3
4
5
6
Strukturális leírás • Hierarchia felépítése: modulok összekapcsolása module top_level (input in0, in1, in2, output r); wire xor0; xor m xor_inst0(.i0(in0), xor_m xor inst0( i0(in0) .i1(in1), i1(in1) .o(xor0)); o(xor0)); xor_m xor_inst1(.i0(xor0), .i1(in2), .o(r)); endmodule module top_level (input in0, in1, in2, output r); wire xor0; xor_m _ xor_inst0(in0, _ ( in1, xor0); ) xor_m xor_inst1(xor0, in2, r); endmodule
in0 in1
xor_m
i0 i1
o
xor_inst0 in2
xor_m i0 i1
o
xor_inst1
r
Strukturális leírás - generate • Hierarchia felépítése: modulok összekapcsolása wire [2:0] in_bus0; wire [1:0] in_bus1; assign in_bus0[0] = in0; assign in in_bus1 bus1 = {in2 {in2, in1}; generate genvar k; for (k=0; k < 2; k++) begin: inst xor_m(.i0(in_bus0[k]), .i1(in_bus1[k]), .o(in_bus0[k+1]); end endgenerate
in0 in1
xor_m
i0 i1
o
xor_inst0 in2
xor_m i0 i1
o
xor_inst1
r
Példa – MUX (1.) • 2:1 multiplexer module mux_21 (input in0, in1, sel, output r); assign r = (sel==1’b1) ? in1 : in0; endmodule module mux_21 (input in0, in1, sel, output reg r); always y @ ((*)) if (sel==1’b1) r <= in1; else r <= in0; endmodule module mux_21 (input in0, in1, sel, output reg r); always @ (*) case(sel) 1’b0: r <= in0; 1’b1: r <= in1; endmodule
Példa – MUX (2.) • 4:1 multiplexer module mux_41 (input in0, in1, in2, in3, input [1:0] sel, output reg r); in0 always @ (*) case(sel) 2’b00: r <= in0; [1] 2’b01: r <= in1; 0 2’b10: 2 b10: r <= in2; in2 1 2’b11: r <= in3; endcase endmodule sel[1:0]
I0 [1] in1
O 0
I1
1 [0]
in3
S
r
Példa – MUX (3.) • 4:1 multiplexer, 4 bites kiválasztó jel always @ (*) casez(sel) /*synthesis parallel_case*/ 4’b1???: 4 b1???: r <= in0; 4’b?1??: r <= in1; 4’b??1?: r <= in2; 4’b???1: 4 b???1: r <= in3; default: r <= ‘bx; endcase endmodule
always @ (*) case(sel) 4’b1000: 4 b1000: r <= in0; 4’b0100: r <= in1; 4’b0010: r <= in2; 4’b0001: 4 b0001: r <= in3; default: r <= ‘bx; endcase endmodule [0]
e d
[1]
e d
in3 in2 [2]
e d
[3]
e d
in1 sel[3:0] in0
[3:0]
r
r