Avtor: Klemen Bravhar
Dandanes si načrtovanja kompleksnih elektronskih vezij ne moremo predstavljati brez prehodnih simulacij, saj nam omogočajo podroben vpogled v odziv posameznih komponent glede na vhodne pogoje.
S simulacijami lahko natančno analiziramo obnašanje vsakega elementa znotraj novo nastalega vezja – od pasivnih komponent, kot so upori in kondenzatorji, do kompleksnejših aktivnih elementov, kot so tranzistorji in operacijski ojačevalniki.
Poleg tega simulacije bistveno skrajšajo razvojni cikel in do določene mere tudi znižajo stroške razvoja, saj v zgodnjih fazah projekta ni treba izdelovati fizičnih prototipov. Napake in pomanjkljivosti vezja je tako mogoče odkriti in odpraviti že v virtualnem okolju, preden se sploh začne postopek fizične realizacije. S tem se izognemo dragim iteracijam pri naročanju komponent, spajkanju in merjenju, ki bi sicer znatno obremenile tako časovni kot finančni okvir projekta.
Enako velja za vezja s programirljivimi logičnimi napravami (FPGA), kjer simulacije predstavljajo nepogrešljivo orodje v procesu načrtovanja. S prehodnimi simulacijami digitalnih vezij, opisanih v jeziku strojnem jeziku VHDL ali Verilog, lahko hitro in učinkovito preverimo logično pravilnost zasnove ter zagotovimo, da vezje deluje skladno z zahtevami specifikacije. Poleg funkcionalnega preverjanja nam simulacije omogočajo tudi analizo časovnih zamikov in morebitnih tveganj pri prenosih signalov, kar je ključnega pomena za zanesljivo delovanje pri visokih frekvencah.
Ta vsebina je samo za naročnike
Simulacijska orodja
Na trgu simulacijskih orodij za digitalna vezja najdemo širok nabor različnih rešitev, ki segajo od odprtokodnih in brezplačnih orodij, prek specializiranih simulatorjev za razvoj FPGA vezij, vse do naprednih profesionalnih orodij, ki so plačljiva. Vsaka od teh kategorij ima svoje prednosti in omejitve, zato je izbira ustreznega orodja odvisna od zahtev projekta, razpoložljivega proračuna in izkušenosti razvijalca.


Če se sprva osredotočimo na brezplačna orodja za simulacijo, velja omeniti, da imajo ta orodja določene omejitve. V večini primerov ne podpirajo mešanja jezikov, kot sta VHDL in Verilog znotraj istega projekta, kljub temu pa omogočajo simuliranje razvitega RTL opisa v enem samem strojnem jeziku. Najbolj popularno odprtokodno simulacijsko orodje za VHDL je GHDL, medtem ko se za Verilog najpogosteje uporabljata Verilator in Icarus Verilog. Verilator se od ostalih razlikuje po tem, da pretvori Verilog oziroma SystemVerilog kodo v C++ ali SystemC. Rezultat tega so izjemno hitre simulacije, ki so primerne za velike dizajne in avtomatizirano regresijsko testiranje. V obeh primerih potrebujemo tudi namenski pregledovalnik valovnih oblik (waveform viewer), ki nam vizualno predstavi časovni potek signalov skozi logična vrata in sekvenčna vezja. Najpogosteje se v ta namen uporablja odprtokodno orodje GTKWave, ki bere standardne VCD in FST datoteke, ki jih generirajo omenjeni simulatorji. Novejša alternativa je Surfer, ki ponuja sodobnejši in preglednejši grafični vmesnik.
Ker se danes veliko razvojnega dela odvija tudi v oblaku, je mogoče vezje simulirati neposredno v spletnem brskalniku prek platforme EDA Playground, ki ne zahteva nobene lokalne namestitve. Platforma podpira več simulacijskih zaledij, vključno z GHDL, Icarus Verilog in Verilatorjem, poleg tega pa v plačljivi različici omogoča dostop tudi do nekaterih komercialnih simulatorjev, kot sta Aldec in Synopsys. Platforma je še posebej primerna za učenje, hitro preizkušanje idej in deljenje primerov kode z drugimi. Prav tako ne smemo pozabiti, da razvojno okolje AMD Vivado vsebuje vgrajen simulator, ki je del brezplačne WebPACK licence. Neposredno znotraj Vivado okolja je mogoče pognati simulacijo in si v integriranem grafičnem vmesniku ogledati časovni potek signalov, kar poenostavi razvojni tok pri delu s Xilinx oziroma AMD FPGA napravami.
Za profesionalne namene obstajajo plačljivi simulatorji, ki v industriji veljajo za t.i. veliko trojko: Siemens Questa Sim (prej znan kot ModelSim), Cadence Xcelium (naslednik Incisive oziroma NCSim simulatorja) in Synopsys VCS. Ta orodja poleg klasičnih simulacij ponujajo tudi številne napredne funkcionalnosti, kot so funkcionalna pokritost (functional coverage), merjenje pokritosti kode (code coverage), sočasna uporaba VHDL in Verilog oziroma SystemVerilog jezika znotraj istega projekta, podpora za napredne verifikacijske metodologije UVM in OSVVM, statična časovna analiza ter integracija z orodji za formalno verifikacijo. Poleg velike trojke obstajajo tudi druga komercialna orodja, kot so Active-HDL in Riviera-PRO podjetja Aldec, Aeolus-DS ter MPSim, ki so prav tako prisotni v določenih industrijskih segmentih.
Med plačljivimi simulatorji ima posebno mesto ModelSim oziroma QuestaSim, saj sta obe različici vključeni v priljubljena FPGA razvojna okolja – ModelSim v Intel Quartus Prime, QuestaSim pa v Lattice Radiant. V okviru teh okolij sta orodji do določene mere brezplačni, a z omejitvami glede velikosti dizajna in nekaterih naprednih funkcionalnosti, ki so na voljo le v polni komercialni različici.
Metodologija simuliranja
Če zelo poenostavimo simulacijo nekega FPGA projekta, potrebujemo dve datoteki. V prvi opisujemo RTL funkcionalnost našega vezja, medtem ko v drugi datoteki opišemo potek vhodnih signalov – to datoteko poimenujemo testno okolje (ang. Testbench). Tudi testno okolje je zapisano v jeziku VHDL oziroma Verilog, odvisno od izbranega simulatorja in projekta.
Preprosto testno okolje najprej definira začetne pogoje vezja, kot so vrednosti taktnega signala, reset signal in začetne vrednosti vhodov. Temu nato sledi načrtovano spreminjanje stanj vhodnih signalov, ki se posredujejo v funkcionalnost opisano v prvi datoteki. Poleg tega lahko v testno okolje dodamo tudi monitorje oziroma preverjevalnike (checkers), katerih naloga je, da samodejno primerjajo dejanske izhodne signale iz funkcionalnega bloka s pričakovanimi vrednostmi, ki smo jih vnaprej določili. Na ta način simulacija ni le vizualni pregled valovnih oblik, temveč postane avtomatiziran postopek preverjanja pravilnosti delovanja vezja. V nadaljevanju bomo ta pristop simuliranja podprli s konkretnim primerom.
Poleg osnovnega pristopa se velja na kratko ozreti tudi na naprednejše verifikacijske metodologije, kot sta UVM (Universal Verification Methodology) in OSVVM (Open Source VHDL Verification Methodology) ter mnoge druge. UVM metodologija je zasnovana v jeziku SystemVerilog in v večini primerov podprta le v plačljivih komercialnih simulatorjih, kot so Questa, Xcelium in VCS. Nasprotno je OSVVM opisana v jeziku VHDL in predstavlja odprtokodno verifikacijsko metodologijo, ki je dobro podprta tudi v brezplačnem simulatorju GHDL. Obe metodologiji sta namenjeni strukturiranemu in ponovno uporabnemu načinu gradnje testnih okolij, kar je še posebej pomembno pri večjih in kompleksnejših projektih, kjer preprosto testno okolje ne zadostuje več. Ključna prednost omenjenih metodologij je uvedba konceptov, kot so naključno generiranje vhodnih podatkov (constrained random verification), merjenje funkcionalne pokritosti (functional coverage) ter modularna arhitektura testnih komponent, ki jih je mogoče prenašati med projekti.
Koraki simuliranja
V prejšnjem prispevku smo govorili o časovnih omejitvah neke RTL strukture, integrirane v FPGA vezje. Kot smo opazili, je bilo v primeru, ko je bila definirana frekvenca previsoka, Vivado okolje nezmožno časovno zapreti RTL strukturo. Da smo projekt uspešno časovno zaprli, smo frekvenco vezja znižali, nakar je Vivado okolje uspešno umestilo RTL strukturo v izbrano FPGA vezje. Časovni odziv vezja lahko preverimo tudi s simulacijskimi koraki, s katerimi hitro ugotovimo, ali kršimo časovne omejitve tipa Setup oziroma Hold.
Neko RTL strukturo lahko simuliramo v več korakih znotraj samega toka implementacije FPGA projekta:
- Funkcionalna simulacija (pre-synthesis) Vedno ko začnemo z novim projektom, izvedemo funkcionalno simulacijo, s katero potrdimo, da zasnovana funkcionalna arhitektura pokriva vse projektne zahteve. V tej fazi simulacija poteka brez upoštevanja časovnih zakasnitev komponent in povezav – preverja se izključno logična pravilnost delovanja vezja. Gre za najhitrejši in najpogosteje izvajan tip simulacije, ki ga izvajamo skozi celoten razvojni proces.
- Simulacija po sintezi (post-synthesis) Naslednji korak je simulacija po sintezi vezja, ki nam da dober vpogled v to, ali je bilo vezje pravilno sintetizirano in ali še vedno podpira zahtevano funkcionalnost. V tej fazi so že upoštevane nekatere časovne zakasnitve, ki izhajajo iz tehnološke knjižnice ciljnega FPGA vezja, medtem ko zakasnitve fizičnih povezav med komponentami še niso v celoti znane.
- Simulacija po implementaciji (post-implementation) V zadnjem koraku preverimo, ali je vezje po celotni implementaciji obdržalo pravilno funkcionalnost, ter ugotovimo, v kolikšni meri so zakasnitve fizičnih povezav in komponent vplivale na delovanje vezja. Ta simulacija je najpočasnejša, a hkrati tudi najbolj natančna, saj upošteva dejanske zakasnitve, ki izhajajo iz prostorske razporeditve elementov na integriranemu vezju (place and route). Prav v tej fazi je mogoče zanesljivo preveriti morebitne kršitve časovnih omejitev Setup in Hold.
Za vse tri korake simulacije lahko načeloma uporabimo eno in enako simulacijsko okolje (testbench), kar bistveno poenostavi razvojni proces in zmanjša količino potrebnega dela pri verifikaciji.

Primer simuliranja v okolju AMD Vivado
Za primer bomo izkoristili vezje iz prejšnjega prispevka [1], ki je predstavljalo dva sekvenčna elementa z verigo sto negatorjev med njima. Za simulacijo bomo uporabili razvojno okolje AMD Vivado, saj je enostavno za uporabo in vsebuje vse potrebno za izvedbo simulacije neposredno znotraj samega okolja. Za razliko od nekaterih drugih orodij, kot sta GHDL ali Icarus Verilog, pri Vivadu ni potrebno ročno generirati FPGA tehnoloških knjižnic, ki lahko zavzamejo tudi veliko prostora na računalniku.
- library IEEE;
- use IEEE.STD_LOGIC_1164.ALL;
- entity zakasnilni_cleni is
- Port(
clk :in STD_LOGIC;d_in :in STD_LOGIC;d_out :out STD_LOGIC- );
- end zakasnilni_cleni;
- architecture Behavioralof zakasnilni_
cleni is - –Signali za registre
signal reg_in : std_logic :='0';signal reg_out : std_logic :='0';- –Veriga signalov za negatorje
(101 povezava za 100 negatorjev) signal chain :std_logic_vector(100 downto 0);- — ATRIBUT:Prepreči Vivadu,
da bi optimiziral te negatorje stran attribute DONT_TOUCH :string;attribute DONT_TOUCH of chain : signal is«true«;- begin
- –Vhodni D Flip-Flop(DFF)
process(clk)- begin
- if rising_edge(clk)then
reg_in <= d_in;- endif;
- end process;
- –Veriga100 negatorjev
chain(0)<= reg_in;gen_inv:for i in0 to 99 generatechain(i+1)<=not chain(i);- end generate;
- –Izhodni D Flip-Flop(DFF)
process(clk)- begin
- if rising_edge(clk)then
reg_out <= chain(100);--Izhod zadnjega negatorja- endif;
- end process;
d_out <= reg_out;- endBehavioral;
Za simuliranje vezja je potrebno pripraviti tudi simulacijsko okolje, ki je prav tako opisano v jeziku VHDL. Simulacijsko okolje je podano v datoteki tb_zakasnilni_cleni in opravlja naslednje naloge:
definira periodo oziroma frekvenco taktnega signala clk,
določa potek vhodnega signala d_in,
ob času nič nastavi začetne pogoje vezja,
ob vsakem pozitivnem robu taktnega signala naključno spreminja vrednost signala d_in,
v proceduri apply_and_check samodejno preverja, ali se izhodni signal ujema s pričakovano vrednostjo.
- library IEEE;
- use IEEE.STD_LOGIC_1164.ALL;
- entity tb_zakasnilni_cleni is
- end tb_zakasnilni_cleni;
- architecture sim of tb_zakasnilni_cleni is
- constant CLK_PERIOD : time :=100 ns;
— definiramo časovno periodo ure - signal clk : std_logic :=’0′;
- signal d_in : std_logic :=’0′;
- signal d_out : std_logic;
- signal sim_done :boolean:=false;
- begin
- uut: entity work.zakasnilni_cleni
–povežemo našo VHDL funkcijo z
simulaijskim datoteko - port map (
- clk => clk,
- d_in => d_in,
- d_out => d_out
- );
- clk_process: process —
generiramo periodo ure - begin
- whilenot sim_done loop
- clk <=’0′;
- wait for CLK_PERIOD /2;
- clk <=’1′;
- wait for CLK_PERIOD /2;
- end loop;
- wait;
- end process;
- stim_process: process
- variable expected_d_out :
std_logic :=’0′; - –- ustvarimo process generiranja
podatkov ter preverimo
če so podatki pričakovani - procedure apply_and_check
(constant input_value :in std_logic)is - begin
- d_in <= input_value;
- wait until rising_edge(clk);
- wait for1 ns;
- assert d_out = expected_d_out
- report »d_out does not
match the expected one-clock
delayed d_in value« - severity error;
- expected_d_out := input_value;
- end procedure;
- begin
- wait for CLK_PERIOD /4;
- apply_and_check(‘0’);
- apply_and_check(‘1’);
- apply_and_check(‘1’);
- apply_and_check(‘0’);
- apply_and_check(‘1’);
- apply_and_check(‘0’);
- apply_and_check(‘0’);
- apply_and_check(‘1’);
- sim_done <=true;
- assertfalse
- report »Testbench completed
successfully« - severity note;
- wait;
- end process;
- end sim;
Kot je bilo že omenjeno, bomo naš primer podprli z vsemi tremi simulacijskimi koraki v procesu razvoja FPGA vezja: funkcionalno simulacijo, simulacijo po sintezi in simulacijo po implementaciji.
Preden preidemo na samo simulacijo, na kratko opišimo vmesnik AMD Vivado okolja. Na Slika 1 so označena naslednja področja:
Rdeči kvadrat – prikazuje korake toka implementacije FPGA projekta (Flow Navigator), kjer so razvidni posamezni koraki od sinteze do generiranja bitnega toka,
Zeleni kvadrat – predstavlja orodno vrstico za upravljanje simulacije, ki vsebuje ukaze za ponovni zagon simulacije, nastavitev časa trajanja, začasno ustavitev in nadaljevanje simulacije ter ostale možnosti,
Moder kvadrat – prikazuje grafični pregledovalnik valovnih oblik (waveform viewer), kjer lahko vizualno pregledamo časovni potek vseh signalov v vezju.
Funkcijska simulacija
Če želimo izvesti katero koli od zgoraj omenjenih simulacij, v razdelku SIMULATION kliknemo Run Simulation, nakar nam orodje ponudi izbiro med razpoložljivimi možnostmi. Pri tem je pomembno upoštevati, da za izvedbo simulacije po sintezi oziroma simulacije po implementaciji moramo predhodno uspešno zaključiti ustrezne korake – sintezo oziroma implementacijo. V nasprotnem primeru orodje omenjenih simulacij ne bo ponudilo oziroma jih ne bo dopustilo izvesti. Če želimo preveriti zgolj logično pravilnost vezja brez časovnih zakasnitev, izberemo možnost Behavioral Simulation, ki ne zahteva predhodne sinteze ali implementacije.
Preden poženemo simulacijo, moramo datoteko tb_zakasnilni_cleni.vhd dodati v projekt kot simulacijsko datoteko (simulation source). To storimo z desnim klikom na razdelek Simulation Sources v projektnem drevesu in izberemo Add Sources – Add or Create Simulation Sources.
Funkcionalna simulacija Slika 1 ne upošteva časovnih zakasnitev posameznih elementov, kar pomeni, da prehod signala skozi logično vezje – v našem primeru verigo negatorjev – poteka neskončno hitro oziroma brez kakršne koli zakasnitve. Drugače povedano, negirano stanje vhodnega signala se prenese na izhod v istem trenutku, kar je jasno razvidno iz časovnega grafa. Ta pojav imenujemo tudi idealna oziroma funkcionalna zakasnitev (ang. zero delay), kjer simulator predpostavlja, da so vse logične operacije trenutne in brez fizikalnih omejitev.
Takšen pristop je koristen predvsem v zgodnjih fazah razvoja, ko nas zanima izključno logična pravilnost vezja in ne njegova dejanska časovna usklajenost. Funkcionalna simulacija je tudi najhitrejša od vseh treh simulacijskih korakov, saj simulator ne potrebuje podatkov o fizičnih lastnostih ciljnega FPGA vezja. Prav zaradi tega jo izvajamo kot prvi korak v procesu verifikacije – šele ko smo prepričani, da je logično delovanje vezja pravilno, nadaljujemo s simulacijo po sintezi in simulacijo po implementaciji, kjer so časovne zakasnitve že upoštevane.
Post Sintezna Simulacija
Naslednji korak v procesu je simulacija po sintezi, katere namen je funkcionalno potrditi, da je bilo naše RTL-opisano vezje pravilno interpretirano in obdelano s strani FPGA-orodja. Z drugimi besedami, preverimo, ali orodje naš opis v jeziku RTL razume enako, kot smo si mi zamislili delovanje vezja. Za simulacijo uporabimo isto simulacijsko datoteko tb_zakasnilni_clen.tb kot pri predhodni simulaciji, vendar se tokrat kot izvorna datoteka za logično funkcijo ne uporabi naš izvorni RTL-opis, temveč netlist, ki ga orodje samodejno generira ob koncu sinteznega koraka. Netlist je natančen opis vezja na nivoju logičnih vrat, ki direktno odraža, kako bo vezje realizirano na FPGA vezju.
Simulacijo po sintezi lahko izvedemo takoj, ko orodje uspešno zaključi sintezo. Z dvema klikoma v meniju izberemo eno od dveh možnosti: »Run Simulation → Post-Synthesis Functional Simulation« ali »Run Simulation → Post-Synthesis Timing Simulation«. Obe možnosti zaženeta simulacijo na podlagi netliste, razlikujeta pa se v tem, koliko podrobnosti sta pri tem upoštevani.
Pri možnosti Post-Synthesis Functional Simulation se preverja zgolj logično delovanje vezja, brez upoštevanja časovnih zakasnitev, ki nastanejo zaradi fizičnih lastnosti elementov. Ta način simulacije je hitrejši in zadostuje za osnovno funkcionalno preverjanje. Pri možnosti Post-Synthesis Timing Simulation pa orodje v simulacijo vključi tudi časovne zakasnitve posameznih elementov, kar daje bistveno bolj realistično sliko dejanskega obnašanja vezja. Kot je razvidno s Slike 2, povzroči že en sam negator 0,482 ns zakasnitve na svojem izhodu glede na prihod signala na vhod. Te zakasnitve so posledica fizikalnih lastnosti tranzistorjev v logičnih elementih znotraj FPGA vezja ter imajo pri visokih frekvencah delovanja lahko pomemben vpliv na pravilno delovanje celotnega sistema (to lahko preverite če frekvenco v simulacijski datoteki spremenite na 100 MHz s spremembo spremenljivke constant CLK_PERIOD : time := 100 ns; na 10ns).
Post Implementacijska simulacija
Zadnja simulacija, ki nam da boljši vpogled v delovanje RTL strukture, je na voljo, ko orodje zaključi vstavitev (ang. Implementation) naše RTL strukture v izbrano FPGA vezje. Podobno kot pri sintezni simulaciji nam orodje tudi tukaj ponudi možnosti »Run Simulation – Post-Implementation Synthesis Functional Simulation« ali »Run Simulation – Post-Implementation Synthesis Timing Simulation«.
Funkcionalnost obeh simulacij je enaka, kot je bilo opisano v razdelku o sintezni simulaciji, z razliko, da je v tem primeru sintetizirano vezje implementirano na tehnologijo izbranega FPGA vezja. S simulacijo »Post-Implementation Synthesis Functional Simulation« preverimo, ali je funkcionalnost ostala nespremenjena, medtem ko s simulacijo »Post-Implementation Synthesis Timing Simulation« preverimo, ali so zakasnitve dovolj majhne, da funkcionalnost ostane nespremenjena glede na izbrano vhodno frekvenco.
Za naš primer bomo ponovno zagnali le simulacijo »Post-Implementation Synthesis Timing Simulation«. Kot je razvidno s slike 3 in iz pripadajoče simulacije, lahko vidimo, da so se časovne zakasnitve nekoliko izboljšale (negator v tem primeru proizvede zakasnitev 0,285 ns), saj je orodje med implementacijo preslikalo sintetizirano vezje na realne komponente. Za simulacijsko datoteko smo še vedno uporabili isto datoteko kot na začetku, z razliko, da je orodje za simulacijo uporabilo novo generirano netlist datoteko, pridobljeno po implementaciji.
Zaključek
V tem prispevku smo spoznali tri ključne simulacijske korake v procesu razvoja FPGA vezja v okolju AMD Vivado: funkcionalno simulacijo, simulacijo po sintezi in simulacijo po implementaciji. Vsak izmed teh korakov nam ponuja drugačen vpogled v delovanje našega vezja in služi drugačnemu namenu v procesu verifikacije.
Funkcionalna simulacija je najhitrejši in najpreprostejši korak, ki nam omogoča preverjanje logične pravilnosti vezja brez upoštevanja časovnih zakasnitev. Simulacija po sintezi nas prepriča, da je orodje naš RTL-opis pravilno interpretiralo in pretvorilo v ustrezno logično strukturo, hkrati pa nam z različico s časovnimi zakasnitvami že pokaže prve realistične ocene obnašanja vezja. Simulacija po implementaciji pa nam da najbolj natančen vpogled, saj so zakasnitve v tem koraku določene na podlagi dejanskih fizičnih komponent izbranega FPGA vezja – kot smo videli v našem primeru, je negator po implementaciji dosegel zakasnitev zgolj 0,285 ns, kar je boljše od 0,482 ns, izmerjenih po sintezi.
Opisani postopek verifikacije je dober primer tega, zakaj je simulacija nepogrešljiv del razvojnega procesa. Namesto da bi napake odkrivali šele na fizičnem vezju, jih z ustrezno kombinacijo simulacijskih korakov zaznamo že v zgodnji fazi razvoja, kar bistveno skrajša čas razvoja in zmanjša tveganje za napake v končnem produktu. Posebej pri visokih frekvencah delovanja, kjer imajo časovne zakasnitve velik vpliv na pravilno delovanje sistema, se natančna simulacija pokaže kot nujna, ne zgolj priporočljiva.
Reference
[1] https://github.com/klemenkomedenko/FPGA_simulation_primer_svetelektronike
