\chapter{Popis Implementace Exportního Systému}
\section{Úvod}
Hlavní část exportního systému  tvoří třída \verb|VhdlExport| která je potomkem 
třídy \verb|Export| definující obecné rozhraní exportních tříd. 
Zároveň je také potomkem dvou tříd které tvoří klienty traverseru a 
definují virtuální metody pro export sémantických konstrukcí jazyka.
Tyto metody jsou volány příslušným traverserem a třída \verb|VhdlExport| je předefinovává.
Třída vlastní objekt třídy \verb|VhdlTraverse| která se stará o procházení 
struktury uložené v HUBu a volání sémantických metod. 
V konstruktoru exportní třídy může být specifikováno zda se bude 
exportovat obsah celého HUBu nebo pouze jedné knihovny, entity nebo architektury. 
Při konstrukci objektu této třídy se volá také konstruktor traverseru kterému 
se přidá informace o místě v hubu ze kterého bude export probíhat.
Export se spustí zavoláním přetíženého operátotu volání funkce jehož 
parametrem je určení místa v HUBu a jméno souboru.

\section{Traverzery}
Pro export do jazyka VHDL byli definovány dvě třídy které 
se starají o procházení struktury HUBu. 

\subsection{Traverzer vrchní vrstvy HUBu}
Třída \verb|VhdlExpTrav| se stará o procházení vrchní vrstvy HUBu. 
Jejího klienta tvoří objekt třídy \verb|VhdlExpTravClient|. 
Tento klient definuje virtuální metody které budou volány traverserem. 
Odkaz na tohoto klienta je nastaven při konstrukci objektu, 
je konstruován právě třídou \verb|VhdlExport| která nastaví sama sebe 
jako klienta traverzeru a tím se docílí toho že budou volány 
předefinované sémantické metody třídy VhdlExport.

Klient traverzeru procházejícího vrchní vrstvu HUBu je potomkem 
obecného klienta \verb|TraverserClient|, takže dědí všechny jeho sémantické metody.

Navíc definuje tyto metody:
\begin{verbatim}
virtual void havePortClause(void);
virtual void endPortClause(void);
\end{verbatim}
Kterými říká že začíná a končí část deklarace rozhraní portů entity.

Traverzer definuje tyto metody:
\begin{verbatim}
void travLib (hub::Library*);
void travEnt (hub::Entity*);
void travPorts(hub::Entity*);
\end{verbatim}
Traverzer po spuštění zavolá metodu klienta \verb|haveUnit| a poté pokud není 
specifikována knihovna ze které má export probíhat volá pro každou knihovnu 
v HUBu metodu \verb|travLib| která prochází obsah vybrané knihovny. 
Pokud knihovna byla specifikována volá metodu \verb|travLib| pouze pro tuto knihovnu. 
Nakonec zavolá metodu klienta \verb|endUnit|.

 
Metoda \verb|travLib| nejprve zavolá metodu klienta \verb|haveLib| a poté pokud 
není specifikována entita která má být exportována volá pro každou 
entitu v této knihovně metodu \verb|travEnt| která slouží k procházení entity. 
Pokud byla entita specifikována volá se tato metoda pouze pro vybranou entitu. 
Nakonec je zavolána metoda klienta \verb|endLib| informující 
o konci procházení dané knihovny.

Metoda \verb|travEnt| volá sémantické metody entity tj. nejprve zavolá metodu 
klienta  \verb|haveEnt| a poté informuje klienta o začátku deklarace portů, 
zavolá metodu na procházení portů a ukončí část deklarace portů a ukončí 
deklaraci entity metodou \verb|endEnt|. Pokud nebyla specifikována architektura 
která má být exportována projdou se všechny architektury patřící vybrané entitě. 
Pro každou se volá metoda \verb|haveArch| a \verb|endArch|.

\subsection{Traverzer strukturní architektury}
Třída \verb|VhdlStructTraverser| se stará o procházení strukturní architektury. 
Jejího klienta tvoří objekt třídy \verb|VhdlStructTravClient|. Klient se používá 
a konstruuje stejně jako u traverzeru vrchní vrstvy HUBu. 
Tento klient je potomkem obecného klienta traverzeru strukturní 
architektury \verb|StructArchTravClient|. Dědí od něj tedy všechny 
sémantické metody a navíc definuje tyto metody:
\begin{verbatim}
virtual void haveNet (hub::StructArch* arch,hub::Net*);
virtual void haveComponent(hub::Entity*);
virtual void endComponent(void);
virtual void havePortClause(void); //declaration of component ports
virtual void endPortClause(void);
virtual void havePortProto(hub::PortProto*); // component port
virtual void havePrimInst(hub::Instance*);
\end{verbatim}

Konstruktor traverzeru strukturní architektury má dva parametry, 
prvním je odkaz na strukturní implementaci architektury kterou 
bude procházet a druhým parametrem je odkaz na klienta který 
definuje sémantické metody.

Traverzer definuje tyto metody:
\begin{verbatim}
void travNets (void);
void travPorts (void);
void travInsts (void);
void travComponents(void);
	
bool isPrimitive(hub::Instance* inst);
\end{verbatim}

Tyto metody jsou definovány jako public a jsou volány sémantickou 
metodou klienta exportující strukturní popis architektury. 
Jejich funkce je zřejmá z jejich pojmenování. 

Zajímavá je akorát metoda \verb|travComponents| která se stará o procházení komponent.
V této metodě je vytvořen objekt typu \verb|std::list| do kterého se ukládají 
odkazy na entity z nichž jsou vytvořeny instance každá entita je tam pouze jednou. 
Pomocí tohoto se docílí aby nebyla definována komponenta pro jednou entitu vícekrát.
 Metoda tedy prochází všechny instance architektury a kontroluje 
 zda rodičovská entita existuje v seznamu entit a zda se jedná o instanci 
 primitivní entity (ty se mapují jinak).
Pokud není ani jedna z těchto podmínek splněna jsou zavolány metody 
klienta deklarující tuto komponentu. Poté je odkaz na rodičovskou 
entitu této instance přidán do seznamu entit.

Metoda \verb|travInsts| prochází instance zapojené v dané architektuře a pro každou
zavolá sémantickou metodu která vygeneruje kód zapojení instance.
Pro instance primitivních entit je volána sémantická metoda \verb|havePrimInst| která
vygeneruje paralelní příkaz přiřazení signálu, pro ostatní instance je volána metoda
která generuje příkaz mapování komponenty.
Instance primitivních funkcí se poznají podle toho že jejich architektura je 
popsána objektem třídy \verb|SymFunc|. K tomuto objektu se lze dostat přes aktuálně 
namapovanou architekturu instance.
\label{pridano1}
 Metoda poskytující aktuální architekturu instance
zde chyběla, po domluvě s vedoucím práce byla do třídy \verb|Instance| 
přidána : \verb|Architecture* CurrentArch(void)|. 

\section{Export sémanticých konstrukcí jazyka VHDL}
O export těchto konstruckí se starají sémantické metody definované 
ve třídě \verb|VhdlExport|, každá z těchto metod zapisuje 
do souboru kód v syntaxi jazyka vhdl.
Zde je seznam těchto metod:
\begin{verbatim}
virtual void haveUnit (void);
virtual void endUnit  (void);
virtual void haveLibrary (hub::Library*);
virtual void endLibrary  (hub::Library*);
virtual void haveDesign (hub::Design*);
virtual void endDesign  (hub::Design*);
virtual void haveEntity (hub::Entity*);
virtual void endEntity  (hub::Entity*);
virtual void havePortProto (hub::PortProto*);
virtual void haveArch (hub::Architecture*);
virtual void endArch  (hub::Architecture*);
virtual void havePortClause(void);
virtual void endPortClause(void);

virtual void haveNet (hub::Net*);
virtual void haveNet (hub::StructArch* arch,hub::Net*);
virtual void endNet  (hub::Net*);
virtual void haveJoined (hub::Joinable*);
virtual void havePort (hub::Port <hub::StructArch>*);
virtual void haveInst (hub::Instance*);
virtual void havePrimInst(hub::Instance*);

virtual void haveComponent( hub::Entity* component );
virtual void endComponent(void);
\end{verbatim}

Jejich význam je zřejmý z jejich pojemenování. 
Metoda \verb|haveLibrary| navíc otevře nový soubor pojemnovanný podle 
jména knihovny a na jeho začátek vypíše VHDL příkaz pro zviditelnění 
standartních knihoven. Metoda \verb|endLibrary| tento soubor zavře.

Metoda \verb|haveArch| starající se o export architektury zjišťuje 
zda je daná architektura popsána strukturně nebo behaviorálně:
\begin{verbatim}
StructArch* sa = a->Impl <StructArch> ();
	if (sa) {
	   //projdi strukturni arch
	} 
	BehavArch* ba = a->Impl <BehavArch> ();
	if (ba) {
	   //najdi funkci popisujici danou architekturu
	}
\end{verbatim}

\subsection{Popis architektury strukturou}
Pokud je popsána strukturně vytvoří se objekt třídy  \verb|VhdlStructTraverser| 
pomocí kterého se tato architektura bude procházet. 
Nejprve je zavolána metoda která projde jednotlivé spoje, pro každý 
spoj je vytvořena deklarace signálu. Při deklaraci signálu se používají
pomocné metody třídy VHDL export:
\begin{verbatim}
hub::Name augmentNetName(hub::StructArch* arch,hub::Net* net);
hub::Name generateNetName(hub::StructArch* arch,hub::Net* net);
bool isPort(hub::Net* net); 
\end{verbatim}
Signál deklaruje metoda  \verb|haveNet (hub::StructArch* arch,hub::Net* net)|
ve které je nejprve zavolána metoda která zjistí zda se nejedná o spoj který je 
propojen se stejně pojmenovaným portem, pokud je takto propojený deklarace se neprovede.
Pokud není takto propojený vygeneruje se jeho deklarace a jeho jménu  vypíše metoda
\verb|augmentNetName| která kontroluje zda rozhraní architektury neobsahuje stejně pojmenovanný port,
pokud jej obsahuje přidá ke jménu spoje index.

Poté je zavolána metoda procházející komponenty, pro každou komponentu 
je vytvořena deklarace komponenty. Jméno komponenty odpovídá jménu 
entity která je na komponentu nakonfigurována.

V příkazové části architektury jsou zavolány metody které 
procházejí instance a porty.
Pro generování kódu zapojení instance v architektře se používají dvě metody:
\begin{verbatim}
	virtual void haveInst (hub::Instance*);
	virtual void havePrimInst(hub::Instance*);
\end{verbatim}
Metoda \verb|haveInst| vygeneruje vhdl kód instalace komponenty s mapováním portů.
Tato metoda funguje tak že prochází porty instance a vygeneruje jméno tohoto portu 
namapované na spoj ke kterému je port připojený. Tento spoj se získá 
metodou \verb|Connected| zavolanou na daný port Instance. 
\label{pridano2}
Tato metoda nebyla  součástí HUBu, po domluvě s vedoucím byla do 
šablony \verb|Port| přidána.

Metoda \verb|havePrimInst| slouží k vygenerování kódu instancí které jsou 
instancemi primitivních entit (and, xor, nand, \ldots ). 
Pro tyto instance je vygenerován VHDL příkaz přiřazení signálu.

Pro každý spoj ke kterému je připojen nějaký port instance je volána metoda
\verb|generateNetName| která vytvoří jeho jméno.

Nakonec se projdou porty rozhraní architektury a pro porty ke kterým nejsou
připojeny stejně pojmenovanné spoje se vygeneruje příkaz přiřazení.

\subsection{Popis architektury chováním}
Pokud je architektura popsána behaviorálně, získá se ukazatel 
na její konkrétní popis (potomek třídy \verb|BehavDescr|). 
Pokud tato architektura má nějaký popis je zavolána metoda perform na 
objektu exportní mapy, která vyhledá funkci reprezentující získaný typ 
behaviorálního popisu a spustí tuto funkci s jedním parametrem 
ukazujícím na exportní třídu (\verb|VhdlExport|) a druhým parametrem 
ukazujícím na získaný popis. 
Tato funkce vygeneruje popis chování podle typu třídy popisu. 
Zatím je  implementován pouze popis chování symetrických funkcí (\verb|SymFunc|).







