Testování

Už blikáme LEDkou? Ještě ne, ještě furt ne, ale už se blížíme. Teď si zapojíme virtuální logickou sondu.

Už jsem to někde psal: když bude potřeba předvést něco reálného, tak použiju Quartus II, což je vývojové prostředí od Altery, s testovacím nástrojem Multisim (doporučuju stáhnout si verzi i s Multisimem, obojí je v té nejmenší edici zdarma). Další informace najdete na sesterském webu fpga.cz: Vývojová prostředí a První kroky s FPGA. Na webu fpga.cz naleznete i tipy a odkazy na levné vývojové kity (Kit s Cyclone II seženete do 500 Kč, programátor za 100 Kč).

Minule jsme si sestavili neúplnou jednobitovou sčítačku. Dnes si ji otestujeme. Vytvořil jsem si v Quartusu projekt (je potřeba dbát na to, že „hlavní entita“ se musí jmenovat stejně jako projekt, takže co třeba „projekt adder“?) a místo popisovaného nakreslení obvodu ve vizuálním nástroji (viz První kroky…) zvolím vytvoření VHDL souboru. File – New – VHDL file. Uložím si jej jako „adder.vhd“ („.vhd“ je standardní přípona VHDL souborů, Verilog používá „.v“).

Po spuštění překladu (Processing – Start – Analysis and Synthesis, též Ctrl-K) proběhne syntaktická kontrola a překlad. Pokud bylo něco špatně, Quartus zahlásí chyby, pokud bylo všechno OK, můžeme jásat.

Opravdu? No, ne tak docela. V programování je dobrým zvykem testovat, v elektronice taky. Jak se testuje ve VHDL? Princip je podobný.

Vytvoříme si testovací entitu (konvencí je pojmenovávat jí „test“ nebo „testbench“), ve které použijeme náš vytvořený obvod. Pomocí speciálního zápisu signálů (s určeným časem změny) připravíme pro testovaný obvod nějaké vstupní podmínky, a budeme se dívat, co se děje na výstupech. Uložím si ji do nového souboru (rozdělovat entity do souborů je taky dobrý zvyk) s názvem „testbench.vhd“.

Na začátku zase vidíme oblíbené deklarace použitých knihoven (dobře radím: Naučte se nazpaměť!). Entita se jmenuje „test“ a je prázdná – nenabízí žádné rozhraní, žádný port navenek. To je v pořádku. Představme si testovací zapojení jako desku s testovací elektronikou, do které se zasouvá testovací součástka – taky nemá navenek žádné rozhraní.

Architektura popisuje zapojení našeho testeru. Všimněte si, že mezi řádkem „architecture bench of test is…“ a vlastním „begin“ jsou uvedené dvě deklarace. První je deklarace komponenty. Podobně jako v C máte v hlavičkovém souboru „prototyp funkce“, tedy jeho deklaraci s uvedenými typy vstupních proměnných a výsledku funkce, tak i ve VHDL se použitá komponenta musí nejprve nadeklarovat, aby překladač věděl, jaké jsou k dispozici porty.

Entita je tedy „deklarace“ nějaké součástky, architektura je její „definice“, a komponenta je deklarace při použití. Všimněte si, že část od „component adder“ po „end component;“ je doslova shodná s entitou adder z minulého článku, pro jistotu zkopíruju:

Jediný rozdíl je v tom, že slovo „entity“ je nahrazeno slovem „component“. Touto deklarací překladač ví, že je někde nějaká externí entita „adder“, kterou použije jako komponentu pro sestavování aktuálního obvodu.

Pod komponentou (může jich zde být samozřejmě víc) je definice signálů. Je podobná definici vstupů a výstupů u entity, ale neudává se zde směr (in, out…) Signál si představme jako „drát“, který je někde uvnitř obvodu a není vyveden ven. Taková představa pro tuto chvíli stačí, ve skutečnosti je to o něco složitější, ale k tomu se dostaneme.

Pak už začíná vlastní popis toho, co se v testovacím obvodu děje. Už jsme viděli přiřazení hodnoty signálu nebo výstupu pomocí operátoru <=. Zde je použita jiná forma přiřazení, kdy na pravé straně není zapsaná hodnota, ale průběh signálu – v případě signálu tA se začíná v log. 0, po 30 nanosekundách přejde do log. 1 (‚1‘ after 30 NS), po 60 ns (od počátku simulace, ne od předchozího kroku) se změní zase do log. 0 a tak dál.

Všimněte si jedné důležité věci: Logické hodnoty se zapisují v apostrofech! Ve VHDL se totiž rozlišují logické hodnoty (‚1‘, ‚0‘ atd.) a čísla (1, 4, 255). Pokud se pokusíte přiřadit hodnotu nějakému signálu s typem std_logic nebo std_ulogic pomocí něčeho jako „Q <= 1„, překladač vám vynadá…

Jsou tedy definované hodnoty signálů tA a tB, a to pomocí průběhů v čase. Je dobré si uvědomit, že takový zápis má smysl pouze v simulacích, ve vlastním obvodu takovéhle hokus pokusy neuděláte, resp. syntetizér vás upozorní, že použije první hodnotu a zbytek ignoruje.

Poslední část architektury je strukturní zápis použití komponenty. Obecný tvar je

Pojmenování je název, který v rámci architektury ponese instance komponenty. Kdybychom chtěli použít dvě sčítačky, použijeme dvě různá jména. Název komponenty je stejný jako v deklaraci „component“, následují klíčová slova port map a v závorce seznam, podle něhož se komponenta do obvodu připojí. Seznam má tolik položek, kolik má deklarace port(), a ve stejném pořadí, v jakém jsou uvedeny vývody komponenty, uvedeme signály, které se na daný vývod mají připojit. Více si ukážeme v dalším pokračování. V tuto chvíli platí, že na vývod A připojíme signál tA, na vývod B připojíme signál tB atd.

Pojmenování je „UUT“, což je opět konvence pro testování: „Unit Under Test“.

Signály tQ a tCout jsou připojeny na výstupy testované komponenty, ale nijak se s nima dál nepracuje. To nám nevadí, protože my s nimi zde pracovat nechceme. My si na ně pouze připojíme „sondu“.

Nadešel čas testu… Spusťte si Multisim (Tools – Run Simulation Tool – RTL simulation, od instalace by mělo být vše sprtávně nastaveno, pokud nemáte nastaveno, musíte si nastavit, že budete používat Multisim). Rozhraní je mohutné, ale my ho zkoumat teď nebudeme, soustředíme se jen na okno s knihovnou (Library), kde by jao první knihovna měla být uvedena knihovna „work“ – tedy ta, na které pracujeme.

sim1

Vy byste tam měli vidět pouze entitu „adder“, já mám přidanou ještě entitu „ch02“, ale té si nevšímejte. Teď musím přeložit samotné testovací zapojení. V menu Compile vyberu Compile, najdu soubor testbench.vhd (bude o dvě úrovně adresáře výš – dialog se otevře v podadresáři „simulation/modelsim“, což je místo, kam si příště své testovací soubory ukládejte) a dvojitým poklepáním soubor přeložím. Pokud je bez chyb, přidá se do seznamu v knihovně „work“:

sim2

Kliknu pravým tlačítkem myši na „test“ a vyberu „simulate“. Okna se budou chvilku přeskupovat, a nakonec uvidíte něco velmi podobného:

sim3

Vlevo si můžete projít hierarchii celého zapojení (není moc složitá, je to „test“, který obsahuje „UUT“), vpravo pak vidíte signály pro vybranou entitu. U entity „test“ to jsou signály tA, tB, tQ a tCout. Vyberu je myší, kliknu pravým tlačítkem a zadám „Add Wave“ (nebo Ctrl-W). Otevře se okno s průběhy signálů (Wave – takový virtuální logický analyzátor). Kliknutím na ikonku v pravém horním rohu panelu si přepnu Wave ze zobrazení v panelu na samostatné okno. V něm proběhne vlastní simulace.

sim4

Nahoře uprostřed vidíte hodnotu „100 ps“ – tedy sto pikosekund. To je krok, po kterém chceme simulovat. Doporučuju přepsat na „100 ns“, protože signály měníme až po 30 ns, a tak bychom se taky nemuseli dočkat. Tlačítkem vpravo od výběru intervalu spustíme jeden simulační běh (nebo též stiskem F9). Na displeji se vykreslí čáry, které udávají průběh signálu – pravděpodobně budou všechny rovné, proto si nejprve pomocí lupy změňte měřítko osy tak, aby bylo vidět alespoň těch 100 ns najednou.

sim5

Vidíte, že vše funguje tak, jak má. Signály A a B se mění tak, jak jsme zapsali, a sčítačka správně nastavuje výstupy Q i Cout.

Testování je při vývoji nezbytná část, a proto jsem ji zařadil hned takhle na začátek. V dalším pokračování se budeme zase věnovat víc teorii, ale je dobré vědět, že máte k dispozici nástroj, kterým si můžete otestovat to, co jste se naučili.

(Já vím, to slibované blikání LEDkou to stále ještě není, ale zase uznejte – už to SKORO je, a který jiný jazyk vám umožní si svoje „hello world“ nasimulovat v duchu hesla „takhle nějak by to vypadalo, kdyby se to spustilo“?)