\chapter{Analýza}
\section{Úvod}
Před započetím implementace modulu importu {\bf VHDL} do {\bf HUBu } a modulu exportujícího 
struktury uložené v {\bf HUBu} zpět do {\bf VHDL} bylo potřeba se důkladně seznámit 
se strukturou HUBu a poté zvolit způsob jakým budou 
jednotlivé prvky jazyka VHDL převedeny.

Jelikož {\bf VHDL} je velice komplexní jazyk bylo by velmi náročné ho 
implementovat kompletně celý. Požadavkem bylo se zaměřit zejména 
na podporu strukturně navržených obvodů ve {\bf VHDL}, bylo tedy potřeba 
vybrat části jazyka v těchto návrzích používané.

\section{Import}
\subsection{Syntaktická analýza}
Prvním krokem bylo vytvoření syntaktického analyzátoru který bude zpracovávat 
konstrukce jazyka {\bf VHDL }. Nejprve se uvažovalo že by se napsal analyzátor 
zpracovávající pouze implementovanou podmnožinu jazyku, toto řešení by bylo 
ale velmi nepraktické pokud by bylo potřeba rozšířit implementovanou podmnožinu. 
Bylo tedy zvoleno řešení kdy bude implementována kompletní gramatika jazyka {\bf VHDL} 
a pokud se v importovaném návrhu vyskytnou konstrukce které nejsou 
implementovány ohlásí se chyba. Jelikož gramatika {\bf VHDL} je poměrně 
rozsáhlá  zvolil jsem před tím než psát analyzátor ručně využití
 generátoru syntaktických analyzátorů Bison. Výhodou bylo zejména 
 to že dostupná gramatika jazyka {\bf VHDL} byla psána ve velmi podobné 
 syntaxi jako je ta kterou zpracovává Bison.
 
\subsection{Převod konstrukcí VHDL do HUBu}
Základní jednotkou popisu ve VHDL je pojmenovaná entita, která představuje 
stejně jako ve HUBu abstrakci nějakého obvodu . 
V {\bf HUBu} jsou základní jednotkou popisu knihovny a návrhy. 
Knihovny obsahují jednotlivé entity. Před importem je tedy potřeba 
specifikovat knihovnu do které se  budou entity ukládat. 
Knihovna může být buď specifikována před spustěním  importu, 
nebo pokud není specifikována musí být knihovna vytvořena. Zde byla zvolena možnost 
vytoření pracovní knihovny {\bf work}  do které se importované entity budou ukládat, 
byla zvažována také možnost pojmenovat knihovnu podle názvu 
importovaného {\bf VHDL} souboru.

Entita v {\bf HUBu} obsahuje prototyp rozhraní portů a jmenný prostor architektur.
Architektury tvoří alternativní popisy vnitřku bloku a to buď chováním nebo strukturou.
Deklarace entity ve vhdl obsahuje hlavičku ve které může být deklarace portů 
entity a generických parametrů. 

\subsection{Porty entity}
Jednotlivé porty v deklaraci portů odpovídají prototypům 
portů v rozhraní portů entity ve {\bf HUBu}. 
Každá deklarace portu obsahuje jeho jméno, mód (in | out | inout | buffer | linkage)  a 
identifikaci datového typu. 

Jazyk {\bf VHDL} podporuje deklarace typů a podtypů podobně 
jako je to u běžných programovacích jazyků. 
Tyto typy mohou být deklarovány v balíčcích (package), deklaračních částech 
entit a architektur. Základní typy obsahují 
knihovny \verb|ieee.Std_Logic_1164| a \verb|ieee.numeric_std|. Jelikož implementace 
těchto typů by byla značně náročná, byly stanoveny 2 základní nejčastěji
 používané typy s kterými import bude pracovat.
Jsou to \verb|std_logic|, a \verb|std_logic_vector|.
 
Port který bude typu \verb|std_logic| 
je jednobitový port k němuž může být v HUBu vytvořen odpovídají
 prototyp portu stejného jména a směru.
 
Port který bude typu \verb|std_logic_vector| (musí mít u sebe zadány meze) 
je vícebitový port označený jedním jménem, k jednotilvým bitům se 
ve VHDL přistupuje pomocí indexace.
V {\bf HUBu} nejsou podporovány vícebitové porty, každému bitu bude 
tedy vytvořen jeden prototyp portu se jménem uvedeným v deklaraci s přidaným číslem bitu. 
Po importu budou tyto porty jako jednotlivé porty v rozhraní 
a již  nebudou seskupeny, na funkčnost zapojení to nebude mít 
žádný vliv jde spíše o přehlednost a zkrácení zápisu, při exportu 
zpět do {\bf VHDL} budou deklarovány každý bit jako samostatný port typu \verb|std_logic|.

Deklarace dále může obsahovat deklarační a příkazovou část, tyto části nebyli implementovány.

\subsection{Architektury}
Vnitřky bloků(entit) jsou ve vhdl popsány rovněž jako u {\bf HUBU} architekturami. 
Každá entita může mít několik různých architektur ,popsané buď chováním nebo strukturou.
Požadavek byl se zaměřit hlavně na podporu strukturně navržených návrhů.
Strukturní popis architektury je ve vhdl řešen pomocí komponent, 
které představují rozhraní entity která bude v architektuře propojena. 
Jejich deklarace se zapisuje v deklarační části architektury, mapování 
je realizováno  v příkazové části architektury.

\subsection{Komponenty}
Existuje více způsobů deklarace komponent (viz. kapitola \ref{popis_vhdl}). 
Nejjednoduší způsob deklarace komponent je takový, že jméno komponenty se 
shoduje se jménem existující entity.
U tohoto způsobu odpadá konfigurace komponent, nevýhoda je že 
nelze explicitně stanovit  s jakou architekturou jsou instance entit do 
architektury zapojeny, je vybrána naposledy přeložená architektura. 
Konfigurace komponent se zapisuje následujícím způsobem:
\begin{verbatim}
for instantiation_list:component_name  use entity entity_name 
[(architecture_identifier)]
end for;
\end{verbatim}

Při tomto způsobu deklarace komponent by bylo třeba vytvářet pomocné 
pole entit bez architektur, které by představovalo komponenty. 
Při konfiguraci komponent by se konrolovalo rozhrani entit z pole komponent 
s rozhranim entity ktera by byla na komponentu konfigurovana. Také by bylo 
potřeba zaznamenávat jména instancí a  jim příslušnou nakonfigurovanou 
entitu a její architekturu.

Výše zmíněná konfigurace zatím není naimplementována a je implementován 
první způsob deklarace komponent, kdy v deklaraci komponenty se kontroluje 
zda existuje entita se stejným jménem jako komponenta a pokud je nalezena 
kontroluje se zda se shodují rozhraní.

Pokud chceme explicitně stanovit z jakou architekturou má být entita 
namapována je možné při mapování komponenty použít přímou instalaci 
komponenty se specifikovanou entitou a její architekturou.

\subsection{Deklarace signálu}
Pro strukturní popis architektury je důležité aby byla naimplementována 
podpora deklarace signálů v deklarační části architektury. 
Signál ve {\bf VHDL} v podstatě odpovídá spoji zde v {\bf HUBu}, 
pro každý deklarovaný signál se tedy v implementaci architekrutry vytvoří 
stejně pojmenovaný spoj.

\subsection{Příkazová část architektury}
Může obsahovat proces, volání procedury, přiřazení signálu, 
příkaz bloku, příkaz assert,
Příkaz generate, přiřazení vybraného signálu,příkaz 
generate a příkaz instantiace komponenty.

Aby návrh byl strukturní je zřejmé že musí být 
podporován příkaz instalace komponent.
Aby mohly být používany symetrické funkce jako jsou and, nand, or ,\ldots 
je potřeba povolit příkaz přiřazení signálu.

Příkaz přiřazení signálu se skládá z cílového spoje nebo signálu na levé straně 
a výrazu na pravé straně. Výraz může obsahovat logické operátory  jejichž
operandy tvoří jména spojů nebo portů rozhraní. Tento výraz představuje propojení
entit primitivních funkcí. Jelikož výraz se v jazyce VHDL nevyskytuje pouze u
příkazu přiřazení, není možné propojovat entity primitivních funkcí v něm obažených
přímo při procházení syntaktickým analyzátorem ale je třeba vytvořit syntaktický strom
jehož uzly budou mít metodu která bude sloužit k propojení prvků v HUBu.
Tato metoda byla definována tak že vrací jméno spoje který byl vytvořen např.
u binarního operátoru vrací jméno výstupního spoje instance primitivní entity 
představující funkci operátoru.
Dále se zde vyskytl problém jak vyřešit propojení cílového spoje nebo portu
se spojem který vrátí propojení výrazu na pravé straně. Ve VHDL je možné propojovat 
mezi sebou spoje ale HUB tuto vlastnost nepodporuje. Tento problém byl vyřešen tak,
že z cíle bude vytvořen vždy spoj, tzn. pokud tam byl port je k němu připojen nový spoj.
Výraz na pravé tedy musí vracet port. Kvůli tomu do metody propojující prvky stromu
byl přidán parametr který říká aby nebyl vytvořen výstupní spoj, tím se docílí toho
že operátor na vrcholu stromu vrátí port a bude moct být připojen k cílovému spoji.
Toto řešení funguje když je na pravé straně výraz alespoň s jedním operátorem nebo
pouze jméno portu. Nefunguje v případě že je na pravé straně pouze jménou spoje, tento
případ je zatím řešen způsobem že je vyhozena vyjímka informující o tom že takto 
propojovat nelze. Pokud by následující propojení mělo být povoleno dalo by se řešit 
například vytvořením instance primitivní entity buffer a pomocí ní tyto dva spoje 
propojit.


\section{Export}
\subsection{Výpis knihoven}
{\bf Hub} podporuje export architektury, entity (je vygenerován kód entity 
a všechny jeji architektury), knihovny (je vygenerován kód všech entit s 
architekturami v příslušné knihovně). Pokud není specifikována architektura, 
entita ani knihovna je exportován obsah všech knihoven. Zde může nastat 
problém, pokud by se postupně obsah všech knihoven postupně exportoval 
do jednoho souboru mohlo by se vyskytnout v tomto souboru více stejně pojmenovaných entit. 
Možnost jak tomuto předejít je buď zakázat export ze všech knihoven zároveň 
nebo obsah každé knihovny generovat do zvláštního souboru. Jako řešení byla 
zvolena druhá možnost, výstupní soubory jsou pojmenovány jako knihovna v HUBu.
Vygenerovaný soubor tedy obsahuje deklarace entit a architektur které byly
uloženy v dané knihovně.

Pro každou entitu je vygenerován kód s deklarací portů, po té se prochazejí 
všechny architekrury dané entity a generuje se jejich kód.

\subsection{Popis architektury strukturou}
Prvky strukturní architektury v HUBu tvoří porty rozhraní entity, instance a 
spoje.  V deklarační části architektury je třeba vypsat deklarace signálů které 
jsou v architektuře zapojené tzn. projít všechny spoje architektury.
Ve VHDL není povoleno deklarovat spoj který by se jmenoval stejně jako nějaký port 
rozhraní protože tyto porty mají vytvořeny stejně pojmenované spoje implicitně.
Tento problém by se dal řešit tím že by se před jméno každého spoje přidal nějaký
prefix ale mohlo by to vést k tomu že by se jméno spoje s prefixem mohlo shodovat 
se jménem nějakého portu rozhraní. 
Jako řešení byl zvolen způsob kdy se při deklaraci
signálu kontroluje zda je spoj připojen ke stejně pojmenovannému portu , pokud ano
jeho deklarace se nevypisuje. Pokud se jméno spoje shoduje se jménem nějakého jiného portu
rozhraní ke kterému není tento spoj připojen je k jeho jménu přidán index, se kterým
se poté objevuje např. při mapování instancí nebo v příkazu přiřazení. Pro takto
oindexovaný spoj se vypíše deklarace signálu.

Dále po deklaraci signálů nasledují deklarace komponent.
První návrh řešení výpisu instancí obsažených v architektuře byl takový,
že se nejprve projdou všechny instance a pro každou se vytvoří v deklaraci 
komponenta pojmenovaná jako entita z níž je instance vytvořena. 
Poté se v příkazové části architektury vygeneruje kód ve kterém budou 
tyto instance mapovány. 
Výše zmíněné řešení by bylo sice jednoduché a systematické ale jeho nevýhodu 
je že se vytvářejí komponenty i pro entity představující 
primitivní funkce (and, nand, nor, \ldots ) a 
tím by se vygenerovaný kód stal delší a méně přehledný. 
Předchozí postup byl tedy jeětě upraven o kontrolu zda se 
nejedná o instance primitivních entit. 
Pro instance primitivních entit se místo 
mapování komponenty vygeneruje příkaz přiřazení s funkcí odpovídající instance.












 



