Hanyho bastlírna
Poslední změny
Arduino - KeyCode/Alarm
Hardware
Mega8 Loader
Hardware
LPC interface
Hardware
Simple SNMP
Hardware
Řadič LCD
Hardware
Raspberry PI
Hardware
J-Link
Hardware
AVR miniTOOL
Hardware
ARM C3 STM32
Hardware
10-BaseT
Hardware
LCD SPI
Hardware
UDP Audio
Hardware
ZyXEL patch
Hardware
KIT NXP LPC17xx
Hardware
I2C LPT
Hardware
Digilent S3 DSP
Hardware
Xilinx DLC10
Hardware
Patmel USB
Hardware
POE injektor
Hardware
Xilinx ISE
Software

XILINX ISE

Pro programování CPLD a některých typů FPGA je k dispozici přímo od výrobce vývojový nástroj XILINX ISE (Webpack), který je možné získat zdarma na www.xilinx.com. XILINX ISE umožňuje dosáhnout cíle několika různými cestami. Klasickým postupem je použití některého z HDL jazyků, další možností, které ISE nabízí, je zadat obvod formou schématu nebo pomocí automatu. Kromě těchto možností nabízí ISE ještě několik dalších cest. Velkou výhodou tohoto prostředí je, že máme k dispozici na jednom místě hned několik nástrojů. Všechny nástroje jsou přístupné přes stromové menu vlevo dole, nemusíme tedy nic složitě hledat a spouštět.

ISE nabízí nástroje pro
Jak vidíme, je programování závislé na předchozích krocích. Jednotlivé kroky však nemusíme provádět postupně, prakticky stačí pouze spustit poslední krok, tj. programování (pomocí aplikace iMPACT). Systém již sám provede všechny potřebné kroky, které musí předcházet - tzn. syntézu a implementaci. Každý krok návrhu se spouští teprve po úspěšném ukončení kroků, na kterých závisí. Ke každému kroku je možné vygenerovat podrobné reporty.

Kroky vedoucí až k programování, které jsou nezbytné, jsou tyto

Screenshoty

ISE ISE - PACE editace omezení
ISE - RTL schéma získané syntézou ISE - iMPACT konfigurace

VHDL kód

Blikač byl vybrán z toho důvodu, že se jedná o relativně zajímavý obvod, na kterém se vždy demonstruje funkčnost určité součástky, např. procesoru a na první pohled člověk vidí, zda obvod funguje či nikoliv. Proč to nezkusit i s CPLD pomocí VHDL a mít radost z toho, že to něco dělá :-). Z hlediska kapacity CPLD a náročnosti kódu VHDL se jedná o velice jednoduchý obvod, který při správné a promyšlené implementaci zabere zlomek kapacity CPLD.
Protože cílem není předvést zajímavý blikač, ale ukázat jednoduchost programování a návrhu CPLD, navrhneme obvod velmi jednoduše.

Vstupem našeho obvodu bude hodinový signál clk a výstupem bude osm signálů připojených na LED diody leds(7:0).
Entita (obvod)
Zvolíme si, že stále bude svítit pouze jedna LED dioda a každou sekundu se svit přesune na další diodu (např z leva do prava). V případě, že bude svítit poslední dioda, začne se znovu od první diody. K rotaci využijeme posuvný registr, jehož zápis je následující (možné vidět ve druhém procesu)
ileds <= ileds(0) & ileds(7 downto 1);
Abychom mohli určit okamžik, kdy má dojít k rotaci, musíme vytvořit synchronní posuvný registr řízený nějakou hranou hodinového signálu, v našem případě nástupnou hranou signálu iclk.
if (iclk = '1') and (iclk'event) then
Signál clk generovaný oscilátorem nemůžeme použít přímo pro řízení posunu, protože jeho frekvence je vysoká - my požadujeme blikání po jedné sekundě, tzn. hodinový signál o frekvenci 1 Hz. Je nutné tedy zařadit před posuvný registr nějakou děličku hodinového signálu. Tu vytvoříme pomocí čítače, který při každém taktu hodin clk zvýší svoji hodnotu o jedničku a pokud dosáhne určité mezní hodnoty (dělitel), překlopí stav signálu iclk na opačný. Tím zajistíme to, že frekvence ficlk bude rovna fclk/dělitel.

Kompletní VHDL kód blikače

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;

entity blikac2 is
   port (
       clk : in std_logic; --vstupni hodninovy signal
       leds: out std_logic_vector(7 downto 0) --vystup na diody    
   );
end blikac2;

architecture beh2 of blikac2 is

 --definice subtypu integer, max. hodnota urcuje maximum citace
 --a zaroven potrebny pocet bitu
 subtype cntint is integer range 0 to 40000000;
 --signal udavajici stav citace
 signal  poc  : cntint := 0;
 --vnitrni hodinovy signal
 signal iclk  : std_logic := '1';
 --registr uchovavajici stav LED diod
 signal ileds : std_logic_vector(7 downto 0) := "11111110";

begin
  leds <= ileds;

  -- delicka vstupniho kmitoctu pomoci citace
  -- citac cita az do max. hodnoty, pri ktere dojde 
  -- k jeho znulovani a otoceni urovne iclk
  process (clk)
  begin
    if (clk='1') and (clk'event) then
       if (poc = cntint'high) then
          poc <= 0;
          iclk <= not iclk;
       else
          poc <= poc + 1;
       end if;
    end if;
  end process;

  -- vlastni blikac, pri kazde nastupne hrane iclk se
  -- provede posun obsahu registru ileds doprava
  process (iclk)
  begin
    if (iclk = '1') and (iclk'event) then
          ileds <= ileds(0) & ileds(7 downto 1);
    end if;
  end process;

end beh2;
blikac2.vhdl

Poznámka: To, jak se mají signály automaticky zinicializovat po resetu je určeno přiřazením hodnot v sekci deklarace signálů. Standartně tyto údaje slouží pouze pro simulaci. V případě CPLD se však využívají i pro syntézu, čímž nám odpadne nutnost generovat resetovací signál a provádět inicializaci ručně. "11111110" znamená, že bude svítit LED dioda, která je napojená na signál leds(0). To proto, že LED diody jsou zapojeny tak, že v případě logiké 0 na řídícím pinu, dioda svítí.

V mém případě jsem použil krystalový oscilátor o kmitočtu 40 MHz, proto dělitel 40 000 000. V případě, že dělíme takto vysokým dělitelem, musíme počítat s tím, že velmi mnoho logiky a klopných obvodů zabere jen tento čítač (je potřeba 26 bitový čítač, sčítačka a komparátor), je proto vhodné použít krystal s co nejmenší frekvencí, případně u časů, které nejsou kritické použít jednoduchý RC oscilátor, jak bylo zmíněno výše.

UCF

V předešlém kroku jsme vytvořili entitu blikac2, která má jeden vstupní signál clk a osm výstupních signálů leds(0)leds(7). Nyní musíme nějakým způsobem definovat, na které piny CPLD budou tyto signály připojeny. Tyto tzv. omezení se definují v souboru UCF (User Constraints File). My se omezíme pouze na deklaraci přiřazení signálů pinům, které se provádí pomocí parametru LOC (Location). Kromě tohoto parametru lze definovat i časové omezení signálu - např. požadovaná frekvence, velikost náběžných hran, způsob využití pinu apod.

Pokud nechceme psát soubor ručně, můžeme využít XILINX PACE, který nám umožní pomocí myši nadefinovat přiřazení signálů k vývodům konkrétního CPLD. Výhoda tohoto přístupu je, že vidíme přímo jednotlivé nožičky CPLD přesně tak, jak jsou rozmístěné ve skutečnosti. Nemusíme si tedy pamatovat jejich symbolické pojmenování P1-P44, které odpovídá číslu pinu.

Kompletní UCF pro blikač

Rozmístění signálů #PACE: Start of Constraints generated by PACE
#PACE: Start of PACE I/O Pin Assignments
NET "clk"      LOC = "P1" ;>
NET "leds<0>"  LOC = "P3" ;>
NET "leds<1>"  LOC = "P2" ;>
NET "leds<2>"  LOC = "P42" ;>
NET "leds<3>"  LOC = "P41" ;>
NET "leds<4>"  LOC = "P40" ;>
NET "leds<5>"  LOC = "P39" ;>
NET "leds<6>"  LOC = "P38" ;>
NET "leds<7>"  LOC = "P37" ;>
#PACE: Start of PACE Area Constraints>
#PACE: Start of PACE Prohibit Constraints>
#PACE: End of Constraints generated by PACE>


blikac2.ucf

Syntéza

Nyní již máme vše potřebné k tomu, abychom mohli přistoupit k implementaci. Prvním nezbytným krokem je syntéza. Syntéza provede překlad (rozklad) VHDL na základní stavební prvky programovatelné součástky. Výsledkem syntézy je tzv. netlist. U CPLD se jedná o hradla AND, OR a klopný obvod D. Výsledek syntézy se tedy liší podle toho, o jakou cílovou platformu se jedná. Syntéza detekuje určité programové konstrukce ve VHDL, které převádí na logické schema. Jedná se například o konstrukce vedoucí na čítače, registry, automaty, a další.

Po úspěšné syntéze si můžeme zobrazit RTL schéma, které by mělo obsahovat čítač, komparátor detekující konečnou hodnotu čítače, který zajišťuje nulování čítače a generování vnitřních hodin iclk a na konci celého řetězce určitá forma posuvného registru, který je napojen na výstup. Pokud klikneme na některou z komponent, dostáváme se na nižší úroveň abstrakce, až se dostaneme na jednotlivé stavební bloky PLD.

Po syntéze je nutné ještě provést mapování (Fit) na konkrétní PLD součástku, které spojí všechny vygenerované netlisty a s využitím UCF se snaží namapovat celý design do konkrétní PLD. V případě, že kapacita CPLD je nedostatečná, mapování končí chybovou hláškou. V opačném případě si můžeme zobrazit report, ve kterém lze vyčíst zabranou kapacitu CPLD - počet použitých makrobloků, termů, registrů, pinů a funkčních bloků. Kromě toho můžeme vyčíst i maximální pracovní kmitočet. Pokud se nám kmitočet nelíbí, můžeme buď udělat změnu v UCF nebo změnit design tak, abychom zkrátili nejdelší logickou cestu apod.

Programování

Po úspěšném mapování můžeme přejít k programování CPLD. Programování se provádí pomocí rozhraní JTAG. Jedná se o standart, který byl vyvinut především pro testování integrovaných obvodů, případně celých systémů. Pomocí protokolu JTAG je možné měnit stav každého (záleží na implementaci) vývodu testovaného obvodu a detekovat tak zkraty, chybné spoje, nefunkční obvod, nebo přímo ovládat připojenou součástku apod.

JTAG

Toto rozhraní využívá čtyři povinné signály: signál TMS, TCK, TDI a TDO a nepovinný resetovací signál TRST. TMS slouží k řízení stavového automatu, který je připojen kromě signálu TMS na signál TCK a případně TRST. Pomocí těchto signálů vytváří vnitřní signály pro řízení jednotlivých bloků uvnitř testovananého obvodu. Stav se mění každou nástupnou hranou hodinového signálu TCK. Resetovací signál je nepovinný, protože reset stavového automatu je možné provést pomocí nastavení TMS na log. 1 na dobu minimálně pěti hodinových impulsů. Je zaručeno, že ať byl automat v jakémkoliv stavu, pak po této proceduře se dostane do počátečního stavu. Podle stavu automatu je do řetězce mezi TDI a TDO připojen určitý registr. Základní povinné registry jsou instrukční registr, boundary scan registr, bypass registr a nepovinný ID registr, který slouží k detekci typu a výrobce součástky.

Jednotlivé testované obvody se propojucí do tzv. boundary řetězce seriově pomocí TDI a TDO. Ostatní signály jsou paralelně připojeny na každou součástku. Jelikož existuje bypass registr, který pouze jakoby propojuje TDI a TDO, můžeme kdykoliv "odpojit" veškeré prvky řetězce, a ponechat aktivní pouze jeden obvod, se kterým budeme pracovat.
Struktura JTAG rozhraní   Testovací řetězec  
Obr 9. Struktura JTAG rozhraní   Obr 10. Testovací řetězec  

JTAG adaptér

Pro programování je potřeba JTAG adaptér, který je připojen na paralelní port. Nejjednodušší programovací adaptér je možné udělat podle schema na obrázku 11. Tento adaptér jsem ale v iMPACTu netestoval. V případě, že chceme adaptér s trošku lepšími vlastnostmi, hlavně co se týče oddělení paralelního portu od signálů pro JTAG, je lepší využít zapojení tzv. Parallel Cable III, které doporučuje XILINX. Pokud opět použijeme obvody řady HC, pak bude pracovat i s napájecím napětím 3V3.
Cheap JTAG   XILINX Parallel Cable III  
Obr 11. Cheap JTAG   Obr 12. XILINX Parallel Cable III  

iMPACT

Pro programování se používá nástroj XILINX iMPACT, který je součástí ISE, jak bylo zmíněno výše. Po spuštění se aplikace ptá, jak cheme součástku programovat. Zde zvolíme Boundary-Scan Mode.

iMPACT krok 1  
Obr 13. iMPACT krok 1  

Dále se program zeptá, zda si přejeme zadat boundary řetězec ručně, nebo provést automatickou detekci.

iMPACT krok 2  
Obr 14. iMPACT krok 2  

V případě provedení automatické detekce bychom měli v řetězci vidět pouze CPLD XC9572XL.

iMPACT detekovaný řetězec  
Obr 15. iMPACT detekovaný řetězec  

Kliknutím na symbol CPLD vybereme JEDEC soubor, který chceme naprogramovat a pravým tlačítkem zvolíme v menu programovat. Ihned po naprogramování a verifikaci by se měl blikač rozběhnout.