[Home](index.html) | [Vivado](vivado.htm) | [Blokovni diagram](vivado-blok.htm) | Enostaven IP | [AXI IP](vivado-axi.htm)
[SDK](sdk.htm)
# Enostavna komponenta IP
Komponenta ali jedro IP (angl. Intellectual Property core) je logični blok, ki je sestavni del digitalnega
integriranega vezja in je namenjen za uporabo v več različnih projektih. IP-XACT je standard (IEEE 1685-2014)
za opis komponent IP v obliki datoteke XML v kateri so definirani priključki, vmesniki in povezave do izvornih
datotek. Program **Vivado** vsebuje orodje *IP Packager* s katerim naredimo standardni opis komponent IP iz
datotek z opisom vezja v jeziku VHDL ali Verilog. Opis komponente vsebuje vsaj tri datoteke:
* component.xml je glavna IP-XACT datoteka
* ime.vhd je izvorna datoteka v strojno-opisnem jeziku
* ime_v1_0.tcl v podmapi xgui je skripta za prilagoditev grafičnega simbola
Program **Vivado** vsebuje urejevalnik blokovnega diagrama v katerem sestavljamo digitalni sistem
iz komponent IP. Za vsako komponento blokovnega diagrama naredi datoteko XCI (Xilinx Core Instance) v
kateri so zapisani nastavljeni parametri.
## Hitra izdelava komponente IP
Najprej bomo pokazali hiter postopek izdelave koponent IP, ki ne zahteva posebnih nastavitev.
Vzemimo primer pulzno-širinskega modulatorja v jeziku VHDL:
```vhdl
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity pwm is
generic (N : integer := 8); -- PWM counter width
port ( clk : in std_logic;
pwm_width : in std_logic_vector(N-1 downto 0); -- 0 == OFF; 2^N-1 == ON
pwm_out : out std_logic);
end pwm;
architecture rtl of pwm is
signal cnt : unsigned(N-1 downto 0) := (others => '0');
begin
p_out : process(clk)
begin
if rising_edge(clk) then
if cnt < unsigned(pwm_width) then
pwm_out <= '1';
else
pwm_out <= '0';
end if;
if cnt < to_unsigned(2**N-2, N) then -- count to 2^N - 2
cnt <= cnt + 1;
else
cnt <= (others => '0');
end if;
end if;
end process p_out;
end rtl;
```
V programu Vivado 2017 naredi nov projekt za razvojno ploščo ZedBoard - glej: [Blokovni diagram](vivado-blok.htm)
Na disku pripravi mapo za komponento pwm (D:/designs/moja_mapa/pwm) v katero kopiraj kodo
enostavnega pulzno-širinskega modulatorja [pwm.vhd](./pwm.vhd).
Izberi iz menuja *Tools > Create and Package NEW IP*, klikni *Next* in izberi opcijo *Package a specified directory*.
V naslednjem oknu nastavi Directory: D:/designs/moja_mapa/pwm, nato pa *Next* do konca. Program bo naredil nov projekt,
določil parametre pakiranja in odpril okno z nastavitvami:
* Identification: nastavimo ime, opis in osnovne podatke o komponenti.
* Compatibility: če je potrebno, določimo ciljno družino vezij
* File Groups: opisuje vključene datoteke (v našem primeru pwm.vhd in .tcl z opisom grafičnega simbola)
* Customization parameters: v kodi pwm.vhd je parameter N, ki ga lahko tukaj natančneje omejimo
* Ports and Interfaces: program avtomatsko zazna priključke in vmesnike
* Addressing and Memory: posebne nastavitzve za komponente na perifernem vodilu procesorja
* Customization GUI: grafični simbol
* Review and Package: končne nastavitve in pakiranje
Za komponento pwm.vhd dobimo opozorilo glede ure: "Bus Interface 'clk': ASSOCIATED_BUSIF bus parameter is missing.",
ki ga lahko ignoriramo. Nastavitve pakiranja so v zadnjem zavihku *Review and Package* pod *Edit packaging settings*.
![](./img/Vivado_pack_set.png)
* Create archive of IP povzroči, da bo po pakiranju v mapi D:/designs/moja_mapa/pwm poleg datotek projekta
tudi arhivska datoteka z vsemi datotekami komponente IP (xilinx.com_user_pwm_1.0.zip).
* Add IP to the IP Catalog avtomatsko doda komponento v katalog projekta iz katerega smo odprli
projekt za pakiranje.
Po opravljenih nastavitvah klikni na gumb Package IP v zavihku *Review and Package* in zapri projekt.
![](./img/Vivado_package.png)
## Izdelava komponente IP s parametri
Poglejmo še primer komponente [stevec.vhd](./stevec.vhd), ki ima parametrično določene vhodne in izhodne priključke.
V opisu števca je z generičnim parametrom določeno število bitov, dva parametra vrste boolean
pa določata ali bo v vezju uporabljen vhodni signal rst in izhodni ce. Uporabo signala rst
opcijsko vključmo s pogojnim stavkom v procesu, logiko za izračun ce pa s stavkom if-generate.
```vhdl
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;
entity stevec is
generic( SIZE: integer := 4;
USE_RST: boolean := true;
USE_CE: boolean := false );
port ( clk: in std_logic;
rst: in std_logic := '0';
cnt: out std_logic_vector(SIZE-1 downto 0);
ce: out std_logic );
end stevec;
architecture rtl of stevec is
signal q: unsigned(SIZE-1 downto 0) := (others=>'0');
begin
p_stej: process(clk)
begin
if rising_edge(clk) then
q <= q + 1;
if USE_RST then -- opcijski reset stevca
if rst='0' then
q <= (others=>'0');
end if;
end if;
end if;
end process;
p_ce: if USE_CE generate -- opcijski ce izhod
ce <= '1' when q = (q´range => '1') else '0';
end generate;
cnt <= std_logic_vector(q);
end rtl;
```
Pakiranje komponente naredimo s *Tools > Create and Package NEW IP*, izbiro *Package a specified directory* in
nastavitvijo ustreznega direktorija. V zavihku *Package IP* klikni na *Customization Parameters*. Program je
sam našel parametre vezja, ki jih lahko tu še dodatno prilagodimo. Najprej bomo določili območje vrednosti
parametra SIZE: z desnim klikom na SIZE odpri meni in izberi Edit Parameter... v katerem naredi kljukico
na Specify Range in vnesi: Minimum: 2, Maximum: 32.
![](./img/Vivado_ip_param.png)
Določimo še pogoj za prikaz signalov rst in ce na grafičnem simbolu komponente. Odpri zavihek
*Ports and Interfaces* in poišči signal ce. Z desnim klikom na simbol signala ce izberi Edit Port in
nastavi Driver value: '0', izberi Port Presence: Optional in zapiši pogoj: $USE_CE == true:
![](./img/Vivado_ip_port.png)
Podobno naredi za vhod rst, kjer nastavi Optional in zapiši pogoj: `$USE_RST == true`. Nastavljen grafični
simbol lahko pregledamo v zavihku *Customization GUI*
![](./img/Vivado_ip_gui.png)
## Uporaba v blokovnem diagramu
Naredili bomo sistem s procesorjem in vmesnikom GPIO prek katerega nastavljamo komponento pwm.
Najprej naredimo osnovi projekt za ZedBoard z blokovnim diagramom, na katerem je procesorski
del in GPIO (glej navodila za: [blokovni diagram](vivado-blok.htm)).
![](./img/Vivado_blok2.png)
Novo komponento IP dodaj na blokovno shemo: *Add IP* in v *Search* vnesi "pwm". Če program ne najde komponente,
verjetno ni pravilno nastavljen repozitorij. Nastavitve so v levem meniju *Settings* pod IP Repository, kjer s
+ dodamo novo lokacijo datotek s komponentami IP.
### Prilagoditev komponent
Komponente s parametri prilagodimo tako, da odpremo nastavitveno okno z dvoklikom na posamezno komponento.
Z dvoklikom na komponento pwm odpri okno za nastavitev parametra N, ki je privzeto 8, kar pomeni da ima
vhodni signal pwm_width 8 bitov \[7:0\]. Enako naj bo nastavljen izhod vmesnika GPIO: en kanal na bo nastavi
kot izhod (All Outputs) vellikosti 8 bitov:
![](./img/Vivado_GPIO1.png)
Povezave na diagramu naredimo tako, da kliknemo na priključek (npr. vhod clk komponente pwm), držimo levi gumb
in povlečemo svinčnik do ustreznega signala (s_axi_aclk). Za povezovanje vodila pwm_width moramo najprej odkriti
izhodni signal komponente GPIO, ki se skriva v zunanjem vodilu. Vodilo odpremo s klikom na + zraven GPIO + in
pokaže se signal gpio_io_o[7:0], ki ga povežemo na pwm. Izhod vežemo na zunanji priključek tako, da z desnim
gumbom kliknemo na signal pwm_out in izberemo *Make External* (ctrl+T).
Izhodnemu priključku pwm_out moramo določiti lastnosti v datoteki z omejitvami (angl. constraints).
V levem meniju izberi *Add Sources* in *Add or create constraints*
ter v naslednjem oknu *Create File*. Datoteko poimenuj (npr. led) in odpri z dvoklikom na ikono v *Sources*,
*Constraints*:
![](./img/Vivado_constr.png)
V datoteko prekopiraj dve nastavitvi: prva določa lokacijo signala pwm_out (LED0 na ZedBoard),
druga pa napetostni standard.
```tcl
set_property PACKAGE_PIN T22 [get_ports pwm_out]
set_property IOSTANDARD LVCMOS25 [get_ports pwm_out]
```
### Prevajanje in preizkus
Pred prevajanjem blokovnega diagrama naredimo *Validate Design* (F6) in *Generate Block Design*.
V tem koraku bo program **Vivado** prensel iz repozitorija vse izvorne datoteke komponent IP,
naredil ustrezne vmesnike (prilagoditev) komponent in izvedel sintezo.
Prevedi *Run Implementation*, *Generate Bitstream*, izvozi *File > Export > Export Hardware*, Include bitstream. Odpri Vivado SDK (*File > Launch SDK) in preizkusi delovanje s kodo:
```C
#include "xparameters.h"
#include "xgpio.h"
int main()
{
XGpio gpio;
XGpio_Initialize(&gpio, XPAR_AXI_GPIO_0_DEVICE_ID);
XGpio_DiscreteWrite(&gpio, 1, 100);
return 0;
}
```