% Diplomova prace: pos_buf
% Michal Trs
% Popis realizace

Při realizaci jsem použil vývojové prostředí ISE od firmy Xilinx. Zahrnuje v sobě editor, syntézní nástroj XST, simulátor, mapování na technologii, place \& route (PaR) a generování bitstreamu. Zdrojové kódy jsou psány v jazyce VHDL \cite{vhdl}, který umožňuje behaviorální i strukturální popis jednotky. Z hlediska doby realizace jsem se snažil využít dostupné komponenty.

\medskip
Adresář projektu má tuto strukturu:
\begin{verbatim}
   _ise           projekt + soubory generované ISE
   comp
      common      obecné jednotky z projektu Liberouter (FIFO, ...)
      ctrl_stat   implementace control / status jednotky
      hdlc_ctrl   implementace HDLC kontroléru
      ppp         implementace PPP kontroléru
      sonet       implementace SONET/SDH Frameru
   coregen        vygenerované soubory z Xilinx CORE generator
   pkg            globální VHDL package
   sim            simulace celé jednotky
   pos_buf.vhd    top level
\end{verbatim}




\section{SONET/SDH Framer}
SONET/SDH Framer je implementován podle blokového schématu \ref{img:sonet_framer_blsch} uvedeného v analýze. Implementace frameru je maximálně podřízena zadání, podporuje pouze rychlost OC-48, virtuální kontejner VC-4-16c a PPP rámce v SPE (byte C2 = 0xCF). Vysílací a přijímací část je na sobě nezávislá, jsou pouze zapouzdřeny ve společné \mbox{\uv{top level}} entitě \verb|sonet_framer.vhd|.

Jednotka je umístěna v adresáři \verb|sonet| a skládá se z těchto souborů:

\begin{verbatim}
   sim/                             simulace (testbench pro ModelSim)
   discard_fifo.vhd                 Vyrovnávací FIFO pro HDLC rámce
   fill_fifo.vhd                    FIFO generující nepřetržitý tok HDLC rámců
   overhead_gen.vhd                 generátor SONET/SDH hlaviček
   overhead_proc.vhd                zpracování SONE/SDH hlaviček
   pos_scrambler.vhd                implementace polynomu 1 + x^43
   position_gen.vhd                 generátor pozice
   sonet_framer.vhd                 top_level entita a komponenta
   xapp651_scrambler_sonet_16.vhd   SONET/SDH scrambler (Xilinx)
   xapp652_oc48_aligner_16.vhd      detekce začátku SONET/SDH rámce (Xilinx)
   xapp652_*.vhd                    pomocné jednotky xapp652
\end{verbatim}

Xilinx xapp651 (SONET/SDH Scrambler/descrambler) je použit, tak jak jej poskytuje firma \mbox{Xilinx}. V xapp652 (detekce začátku rámce) bylo nutné v souboru
\verb|xapp652_oc48_aligner_16.vhd| zakomentovat/odkomentovat řádky č. 160 a 161 takto:

\begin{verbatim}
   160 -- n <= "000001001111"; -- use to keep simulation quick
   161    n <= "100001101111"; -- use for implementation
\end{verbatim}

Bez této úpravy pracuje jednotka s menším SONET/SDH SPE, ale TOH zůstává stejné, což neodpovídá OC-48. Tato skutečnost není nikde popsána, a proto to zde uvádím.



\subsection{FIFO}
Zde popíšu \uv{discard} a \uv{fill} FIFO jednotky, které jsou navrženy výhradně pro práci s HDLC rámci. Obě zaobalují generickou FIFO paměť \cite{liberouter} realizovanou na projektu Liberouter, která umožňuje nastavit typ použité paměti (distribuovaná, bloková), šířku dat (1, 2, 4, 9, 18, 36), velikost položky a počet položek. V obou případech je použito FIFO s 18b datovou šířkou (využito pouze 16b)

\subsubsection{\uv{Discard} FIFO}
Jednotka slouží k dočasnému uložení nepřetržitého toku dat, který přichází z HDLC kontroléru a nemůže být přímo odesílán (přenos TOH). Aby nedocházelo k přeplnění FIFO paměti, a následnému zahazování dat jsou odstraněny přebytečné flagy 0x7E. K oddělení HDLC rámců stačí pouze jeden flag 0x7E, ostatní jsou použity jako výplň. Zjednodušené (vynechány vstupní/výstupní a pomocné registry) schéma jednotky je na obrázku \ref{img:fifo_discard}.

\begin{figure}[!htp]
\begin{center}
\scalebox{1.0}{\includegraphics{img/fifo_discard.pdf}}
\end{center}
\caption{Discard FIFO}
\label{img:fifo_discard}
\end{figure}

Počet položek FIFO paměti je zvolen takto: \verb|k x TOH_width x OC-48|, kde \verb|k| je konstanta, \verb|TOH_width| je šířka hlavičky (=3) a \verb|OC-48| je použitá rychlost (=48). Je patrné, že tato implementace spoléhá na mezery mezi přenášenými HDLC rámci. Pokud bude tok dat nepřetržitý, začne docházet ke ztrátám. To je vyřešeno vytažením signálu \verb|FULL| z FIFO paměti a navázáním na FrameLink protokol, čímž zaručíme pozastavení vstupu.



\subsubsection{\uv{Fill} FIFO}
Ideové schéma jednotky je na obrázku \ref{img:fifo_fill}. Nejsou v něm zakresleny vstupní / výstupní registry a signály ošetřující platnost dat.

\begin{figure}[!htp]
\begin{center}
\scalebox{1.0}{\includegraphics{img/fifo_fill.pdf}}
\end{center}
\caption{Fill FIFO}
\label{img:fifo_fill}
\end{figure}

Data \verb|DIN| jsou do FIFO paměti ukládána, je-li signál \verb|WR = '1'| (je přenášen SPE). Pokud je ve vstupních datech flag 0x7E je nastaven RS registr a to způsobí vyčítání dat. Nastavení má větší prioritu než reset. Jakmile začnou přicházet jiná data než flag, zastaví se vyčítání dat z paměti do doby, než flag opět přijde. Tím je zaručeno, že HDLC rámec nebude přerušen (např. TOH). Mezi tím je na výstupu \verb|DOUT| neustále hodnota 0x7E. Flag oddělující dva HDLC rámce je vložen pouze jednou (není zakresleno ve schématu). Tím je minimalizována odezva mezi koncem uložením rámce a začátkem jeho vyčítání.

Počet položek FIFO paměti je nastaven na 33000. \verb|16B x 33000 > 64kB|, což je maximální velikost HDLC/PPP rámce.



\subsection{Generátor pozice (position\_gen)}
Jednotka realizuje dva binární čítače navržené pro generování pozice v \mbox{SONET OC-48/VC-4-16c} rámci. Čítač řádek \verb|LINE_NUMBER| má rozsah 0:8, čítač slov \verb|WORD_NUMBER| 0:2159. Poskytuje signály \verb|OVERHEAD| (hlavička) a \verb|PAYLOAD| (data), které udávají, zda aktuální pozice náleží hlavičce nebo datům. Do hlavičky je brán SOH, LOH i POH. To je možné díky VC-4-16c, kde je POH na pevném offsetu. Proto je u Xilinx xapp652, který je obecnější, signál \verb|OVERHEAD| aktivní pouze při SOH a LOH. Signál \verb|SCRAMBLE| je roven 0 pokud jsou přenášeny byte A1, A2 a J0. Slouží jako enable pro xapp651.



\subsection{Generátor hlavičky (overhead\_gen)}
Jednotka generuje SOH, LOH i POH hlavičky. Jsou implementány pouze \uv{Požadované} byty shrnuté v tabulce \ref{tab:reduce_toh}.

V distribuované paměti jsou uloženy konstanty (A1, A2, ...). Podle specifikace jsou počítány kontrolní součty B1 a B2 z předchozího zakódovaného rámce. Ilustrační schéma je na obrázku \ref{img:overhead_gen}.

\begin{figure}[!htp]
\begin{center}
\scalebox{1.0}{\includegraphics{img/overhead_gen.pdf}}
\end{center}
\caption{Generátor hlavičky}
\label{img:overhead_gen}
\end{figure}



\subsection{Zpracování hlavičky (overhead\_proc)}
Jednotka zpracovávající SONET/SDH hlavičky (TOH a POH) má za úkol především shromažďovat statistiky o přijatých rámcích. Skládá se z několika bloků (obrázek \ref{img:overhead_proc}).

\begin{figure}[!htp]
\begin{center}
\scalebox{1.0}{\includegraphics{img/overhead_proc.pdf}}
\end{center}
\caption{Zpracování hlavičky}
\label{img:overhead_proc}
\end{figure}

\uv{WatchDog counter} při přetečení generuje (je nulován signálem \verb|FOUND| = nalezen začátek rámce) signál \verb|LOC| (lose of connection = ztráta nosné) a \verb|search| (startuje hledání začátku SONET/SDH rámce). V \uv{BlockRAM} je průběžně ukládána (přepisována) hlavička TOH pro možnost vyčtení do SW. Pro POH hlavičku k tomu samému slouží \uv{POH register}. \uv{All / PPP counter} představuje dva 32 bitové čítače pro uložení počtu všech přijatých SONET/SDH a SPE/PPP rámců.

\begin{table}[!htp]
   \begin{center}
   \begin{tabular}{|l|l|l|}
      \hline
      Hodnota signálu stat\_sel & Význam & výstup \verb|STAT| \\
      \hline \hline
      SONET\_CAPTURE\_FROOZEN & zastaví ukládání TOH & - \\ \hline
      SONET\_CAPTURE\_ENABLE  & start ukládání TOH (default) & - \\ \hline
      SONET\_CAPTURE\_READ    & vyčtení TOH &  648 x TOH(15:0) \\ \hline
      SONET\_STATUS          & stav jednotky & (1) LOCKED \footnote{synchroní přenos}, (0) LOC \\ \hline
      SONET\_RX\_ALL          & \# přijatých SONET rámců & počet 32b \\ \hline
      SONET\_RX\_PPP          & \# přijatých SPE/PPP rámců & počet 32b \\ \hline
   \end{tabular}
   \end{center}
   \caption{Poskytované informace jednotkou \uv{overhead\_proc}}
   \label{tab:overhead_proc}
\end{table}

Pro přepínání mezi výstupy z jednotek slouží signál \verb|STAT_SEL|. Možné hodnoty definované jako konstanty jsou uvedeny v tabulce \ref{tab:overhead_proc}.



\subsection{PoS\_scrambler}
Jednotka realizuje (od)kódování polynomem $1 + x^{43}$. Verze pro sériová data (1b) je v RFC 2615 \cite{rfc2615} na straně 3 a 4. Zapojení vysílací a přijímací části se od sebe liší vstupem do posuvného registru. Vysílací část má vstup za xor obvodem, přijímací před ním. Ke změně funkce (vysílání/příjem) jednotky slouží generic \verb|scramble|. Realizace pro 16b data vypadá zjednodušeně takto:

\begin{verbatim}
   xor_data <= shift_reg(15 downto 0) xor DATA_IN;
   DATA_OUT <= xor_data;

   -- 43b shift reg
   process(CLK)
   begin
      if CLK = '1' and CLK'event then
         if SCRAMBLE then
            shift_reg <= xor_data & shift_reg(42 downto 16);
         else
            shift_reg <= DATA_IN & shift_reg(42 downto 16);
         end if;
      end if;
   end process;
\end{verbatim}



\section{HDLC kontrolér}
Návrh je inspirován projektem 6.195 Final Project z MIT \cite{mit-hdlc}. Je rozdělen na vysílací a přijímací část, ale oproti \cite{mit-hdlc} je navržen pro datovou šířku 16b. Dalším rozdílem je rozdělení komponenty s automatem na 2 komponenty. Realizace se skládá z těchto souborů:

\begin{verbatim}
   sim/                    simulace (testbench pro ModelSim)
   hdlc16_tx.vhd           top level vysílací části
   hdlc16_tx_driver.vhd    automat generující HDLC protokol
   hdlc16_tx_bstuff.vhd    automat zajištující "Byte stuffing" na 16b datech
   hdlc16_rx.vhd           top level přijímací části
   hdlc16_rx_driver.vhd    automat přijímající HDLC protokol
   hdlc16_rx_bstuff.vhd    automat zajištující "Byte destuffing" na 16b datech
   crc32.vhd               výpočet kontrolního součtu
\end{verbatim}

V následujících podkapitolách popíšu zvlášť vysílací a přijímací část a komponentu pro výpočet kontrolního součtu, která je pro obě části společná.



\subsection{Vysílací část (TX)}
Blokové schéma vysílací části je na obrázku \ref{img:hdlc_tx_blsch}.

\begin{figure}[!htp]
\begin{center}
\scalebox{0.8}{\includegraphics{img/hdlc_tx_blsch.pdf}}
\end{center}
\caption{HDLC kontrolér - vysílací část}
\label{img:hdlc_tx_blsch}
\end{figure}

Komponenta \uv{Transmit driver FSM} (\verb|hdlc16_tx_driver.vhd|) implementuje automat, který je na obrázku \ref{img:hdlc_tx_driver}. Zajišťuje generování HDLC protokolu. Název stavu značí, že po přechodu byla určitá data odvysílána. Pro příklad ve stavu \verb|st_DF| bylo odvysíláno defaultní pole address a control tj. 0xFF03.

Automat zůstává ve stavu \verb|st_IDLE| dokud není signál\footnote{Signály \emph{PPP\_SOF} a \emph{PPP\_EOF} generuje PPP kontrolér a ohraničují PPP rámec.} \verb|PPP_SOF = '1'|. Poté jsou odvysílány defaultní položky a začíná přenos samotných dat z vyšší vrstvy, což odpovídá stavu \verb|st_DATA|. V tomto stavu automat setrvává, dokud je \verb|PPP_EOF = '0'|. Poté je vložen kontrolní součet. Pokud byl počet bytů dat sudý, automat pokračuje stavy \verb|st_FCS12| (spodních 16b kontrolního součtu) a \verb|st_FCS34| (horních 16b kontrolního součtu). V opačném případě je spodních 8b kontrolního součtu odesláno již s posledním bytem dat. Poté je odesláno prostředních 16b (\verb|st_FCS23|). Ve stavu \verb|st_FCS4| je odesláno horních 8b kontrolního součtu a nastaven signál \verb|HDLC_HI_INV = '1'|\footnote{HI\_INV = hi invalid = platné byty 7:0}.

\begin{figure}[!htp]
\begin{center}
\scalebox{0.8}{\includegraphics{img/hdlc_tx_driver.pdf}}
\end{center}
\caption{Automat generující HDLC protokol}
\label{img:hdlc_tx_driver}
\end{figure}

Výstup je připojen do komponenty \uv{Transmit stuffing FSM} (\verb|hdlc16_tx_bstuff.vhd|). Jedná se opět o konečný automat, který zajišťuje transparentnost dat. Uveden je na obrázku \ref{img:hdlc_tx_stuff}, který je značně zjednodušený (stavy SHIFT a END jsou sloučeny do jednoho a nejsou zakresleny výstupy). Pokud nejsou přenášena žádná data, je vysílán tzv. \uv{Flag} 0x7E7E. V přenášených datech jsou nahrazovány byty 0x7D a 0x7E za 0x7D a xor původního bytu. Pro 8b verzi by měl automat 3 stavy (idle, direct, stuff). 16b verze má 10 stavů a 42 přechodů, které musí řešit \uv{stuffing} dolního, horního nebo obou bytů ve vstupním slově a následné posunutí následujících slov.

\begin{figure}[!htp]
\begin{center}
\scalebox{0.8}{\includegraphics{img/hdlc_tx_stuff.pdf}}
\end{center}
\caption{Automat zajišťující transparentnost dat}
\label{img:hdlc_tx_stuff}
\end{figure}


V původním návrhu nebyly zahrnuty registry mezi komponentami \uv{Transmit driver FSM} a \uv{Transmit stuffing FSM}. Po syntéze byl odhad hodinové frekvence pouze 106,68 MHz. Po vložení registrů je odhad frekvence 156,17 MHz (pro OC-48 potřebujeme minimálně \mbox{155,52 MHz}).


\subsection{Přijímací část (RX)}
Přijímací část je velice podobná té vysílací. Blokové schéma je na obrázku \ref{img:hdlc_rx_blsch}.

\begin{figure}[!htp]
\begin{center}
\scalebox{0.8}{\includegraphics{img/hdlc_rx_blsch.pdf}}
\end{center}
\caption{HDLC kontrolér - přijímací část}
\label{img:hdlc_rx_blsch}
\end{figure}

Komponenta \uv{Recieve destuffing FSM} (\verb|hdlc16_tx_bstuff.vhd|) převádí proud dat na rámec ohraničený signály \verb|SOS| a \verb|EOS|. Je realizována konečným automatem, který je velice podobný automatu v komponentě \uv{Transmit stuffing FSM}. Pokud je přijímán \uv{Flag} 0x7E7E zůstává automat ve stavu \verb|st_IDLE|. Po přijetí jiného bytu přechází k \uv{destuffingu} dat a je generován signál \uv{start of stream} (\verb|SOS|). Jsou nahrazovány byty 0x7D 0x5D bytem 0x7D a 0x7D 0x5E bytem 0x7E. Při dalším přijetí bytu 0x7E, je vygenerován signál \uv{end of stream} (\verb|EOS|) a dochází k ukončení přenosu.

Následuje komponenta \uv{Recieve driver FSM} (\verb|hdlc16_rx_driver.vhd|), která extrahuje data z HDLC rámce. Vstup je registrován ve dvou úrovních z důvodu ověření kontrolního součtu (obr. \ref{img:hdlc_rx_drv}). Pokud přijde signál \uv{end of stream} (\verb|EOS = '1'|) je v registrech uložen kontrolní součet. Ten je porovnán s vypočteným kontrolním součtem a přenos je ukončen. Podle výsledku porovnání je nastaven signál \verb|ERR_CRC|.

\begin{figure}[!htp]
\begin{center}
\scalebox{0.8}{\includegraphics{img/hdlc_rx_drv.pdf}}
\end{center}
\caption{Komponenta pro dekapsulaci dat z HDLC rámce}
\label{img:hdlc_rx_drv}
\end{figure}




\subsection{Generátor kontrolního součtu}

Do HDLC hlavičky je vkládán 32b CRC kontrolní součet, který je na přijímací straně znovu vypočítán a porovnán s údajem v hlavičce. Tímto je snadno detekován poškozený rámec.

Komponenta (\verb|crc32.vhd|) zahrnuje registr pro uložení doposud vypočteného kontrolní součtu. Ten je počítán pomocí xor stromu, který poskytují funkce \verb|nextCRC32_D16| a \verb|nextCRC32_D8|. K vygenerování těchto funkcí byl použit nástroj na stránce \verb|http://www.easics.com| \cite{easics}. Výstupem této komponenty je 32b cyklický kód (CRC32), který je opožděn za vstupem o 1 hodinový takt. Druhým výstupem je nejspodnějších 8b CRC32 právě vypočtených. To je vhodné pro vysílací jednotku, kdy je lichý počet vysílaných bytů a kontrolní součet musíme začít vkládat v tomto taktu.




\section{PPP kontrolér}
\label{par:ppp_ctrl}
PPP kontrolér vychází z hrubého návrhu v kapitole \ref{par:ppp}, obrázek \ref{img:ppp_blsch}. Blokové schéma je na obrázku \ref{img:ppp_blsch_real}. Zelenou přerušovanou čarou je rozděleno na tři pomyslné části. Vysílací (TX), přijímající (RX) a část (L2 PROC) zpracovávající pakety linkové vrstvy (LCP, NCP, ...).

\begin{figure}[!htp]
\begin{center}
\scalebox{1.0}{\includegraphics{img/ppp_blsch_real.pdf}}
\end{center}
\caption{PPP kontrolér - blokové schéma}
\label{img:ppp_blsch_real}
\end{figure}

Pro aplikace zaměřené na analýzu provozu, síťovou bezpečnost a jistě mnoho dalších, kde je zpracování nebo vysílání vlastních LCP paketů nežádoucí by postačovala zjednodušená implementace. V té by byly pouze části TX a RX. Z důvodu zachování univerzality řešení je implementován PPP kontrolér podle schématu. Níže je výčet souborů a adresářů, ze kterých se skládá řešení.

\begin{verbatim}
   prog/                   program a překladač pro PicoBlaze
   sim/                    simulace (testbench pro ModelSim)
   decaps_ppp_l3.vhd       dekapsulace paketů síťové vrstvy (OSI L3) z PPP rámce
   embedded_kcpsm3.vhd     PicoBlaze s pamětí programu
   encaps_l3_ppp.vhd       enkapsulace OSI L3 do PPP rámců
   fifo_16_8.vhd           FIFO paměť pro PicoBlaze (16b vstup, 8b výstup)
   fifo_8_16.vhd           FIFO paměť pro PicoBlaze (8b vstup, 16b výstup)
   kcpsm3.vhd              PicoBlaze
   ppp16.vhd               PPP top level
\end{verbatim}

Nyní popíšu jednotlivé bloky schématu, přičemž se přidržím rozdělení na tři části (RX, TX, \mbox{L2 PROC}).



\subsection{Vysílací část (TX)}
Vysílací část je tvořena blokem \uv{encaps} (\verb|encaps_l3_ppp.vhd|). Obsahuje v sobě vyrovnávací FIFO paměť (implementována na projektu Liberouter) a logiku pro přidání PPP pole \uv{protocol}. Velikost FIFO paměti je možné nastavit genericem ITEMS. Pole \uv{protocol} se zadává signálem \verb|PPP_PROTO: std_logic_vector(15 downto 0)| a je tedy možné jej za běhu měnit. V této aplikaci je na pevno nastaveno na hodnotu $0x0021$, což odpovídá IP paketu. Vstupem komponenty je 16b FrameLink a výstupem jsou signály pro HDLC kontrolér.



\subsection{Přijímací část (RX)}
Přijímací část je tvořena blokem \uv{decaps} (\verb|decaps_ppp_l3.vhd|). Opět v sobě zahrnuje vyrovnávací FIFO paměť a logiku pro odebrání PPP pole \uv{protocol}. Generic \verb|L3_KEEP_PPP| udává, zda má být pole odebráno. Jeho zachování může být v některých aplikacích užitečné. Vstupem jednotky jsou signály z HDLC kontroléru a výstupem je 16b FrameLink.



\subsection{Zpracování paketů linkové vrstvy (L2 PROC)}
Zpracování paketů linkové vrstvy se skládá z několika komponent. Na přijímací straně (od HDLC kontroléru) je multiplexor, který je přepínán komparátorem. Na začátku přenášeného rámce (aktivní signál \verb|SOF|) jsou porovnány horní 4 bity a podle nich je nastaven typ přijímaného rámce, potažmo multiplexor. Typy PPP rámců \cite{rfc1661} jsou definované typem \verb|t_pkt_type| a jsou shrnuty v tabluce \ref{tab:pkt_type}. V této implementaci jsou rámce označené \verb|pkt_L3| posílány do jednotky \uv{decaps}, ostatní pakety jsou zpracovány v procesoru.

\begin{table}[!htp]
   \begin{center}
   \begin{tabular}{|l|l|l|}
      \hline
      Hodnota pole \uv{protocol} & Význam & Hodnota \verb|t_pkt_type| \\
      \hline \hline
      0*** - 3*** & Protokol síťové vrstvy (NLP) & pkt\_L3 \\ \hline
      4*** - 7*** & Protokol s nízkou zátěží (LVP) & pkt\_LVP \\ \hline
      8*** - b*** & Protokol asociovaný s NLP (NCP) & pkt\_NCP \\ \hline
      c*** - f*** & Řídicí protokol linkové vrstvy (LCP) & pkt\_LCP \\
      \hline
   \end{tabular}
   \end{center}
   \caption{Typy a označení PPP rámců}
   \label{tab:pkt_type}
\end{table}

\begin{figure}[!htp]
\begin{center}
\scalebox{1.0}{\includegraphics{img/ppp_fifo_16_8.pdf}}
\end{center}
\caption{Komponenta FIFO 16-8}
\label{img:ppp_fifo_16_8}
\end{figure}

Před procesorem je komponenta nazvaná \uv{FIFO 16-8} (obrázek \ref{img:ppp_fifo_16_8}). Skládá se z 16b FL FIFO paměti, převodníku FL16 na FL8, 8b FL FIFO, čítače a několika registrů. Pakety po síti SONET/SDH jsou přenášeny řádově rychleji, než je PicoBlaze dokáže zpracovávat, ale je jich malé množství. Pakety jsou ukládány do FIFO paměti o šířce 16b. Z té jsou vyčítány přes převodník 16b /8b. Do 8b FIFO paměti je načten vždy jen jeden celý paket, poté je nastaven signál \uv{Ready to sent} (\verb|RTS|), který je zapojen do Status / command registru. Teprve až je celý paket vyčten procesorem, je načten do FIFO paměti další paket. Abychom nemuseli programově zjišťovat, jestli jsou na vstupu ještě platná data, je zde čítač. Je vhodné jej nejprve načíst a podle něj nastavit počet opakování cyklu, ve kterém FIFO vyčítáme.

Následuje již samotný procesor PicoBlaze s pamětí programu a externím Status / command registrem. Ukázkový program se nachází v podadresáři \verb|prog/|. Podrobněji bude popsán v následující podkapitole věnované programátorskému modelu.

Za procesorem je komponenta \uv{FIFO 8-16}, která je tvořena převodníkem 8b na 16b a 16b FL FIFO paměť. Po nahrání celého paketu procesorem do FIFO paměti je nutné programově nastavit bit \verb|sr_of_rts| ve Status / command registru. To zajistí přepnutí výstupního multiplexoru (pokud je právě přenášen paket síťové vrstvy, je multiplexor přepnut až po přenesení celého paketu) a odvysílání tohoto paketu.


\subsubsection{Programátorský model}
Procesor obsahuje 16 8b univerzálních registrů a 64B paměti. Každá instrukce se provádí 2 takty. Instrukční sada procesoru je popsána v uživatelské příručce \cite{ug129} a dle mého názoru v praktičtěji napsaném manuálu \cite{pb_manual}.
S okolím komunikuje pomocí vstupních / výstupních portů a přerušení.

Přerušení je vyvoláno detekcí nosné (nastavuje SONET/SDH Framer). V programu se to projeví odskokem na adresu 0x3FF (konec paměti). Je potřeba, aby na tomto místě byla instrukce \verb|JUMP|, která odskočí do přerušovací rutiny. Z obsluhy přerušení se vrátíme instrukcí \verb|RETURNI|.

Veškerá řídicí komunikace mezi procesorem a okolím je zprostředkována přes \uv{Status / command register} (SCR), který je dostupný pro čtení a zápis na portu PID\_SR. Kromě tohoto registru je k procesoru připojena vstupní a výstupní FIFO paměť, přes které jsou odesílány a přijímány pakety. Pokud je ve vstupní FIFO paměti (port PID\_FIN) připraven paket je nastaven bit sr\_if\_rts v SCR. Informaci o délce paketu je možné získat z čítače na portu PID\_FLC. Pokud jej čteme během zpracování paketu, udává počet bytů zbývajících k načtení. Do FIFO paměti je načten nový paket až po úplném vyčtení předchozího.
Pokud zapíšeme paket do výstupní FIFO paměti (port PID\_FOUT), je poté nutno nastavit bit sr\_of\_rts v SCR. Tento bit je po odeslání hardwarově nulován.
Přehled portů je shrnut v tabulce \ref{tab:pb_porty} a význam bitů SCR v tabulce \ref{tab:stat_cmd}.

\begin{table}[!htp]
   \begin{center}
   \begin{tabular}{|l|l|c|c|}
      \hline
      Význam & Označení & Hodnota & čtení (R) / zápis (W) \\
      \hline \hline
      Status / command register & PID\_SR & 0x01 & R/W \\ \hline
      Délka paketu ve FIFO z HDLC & PID\_FLC & 0x02 & R \\ \hline
      Vstupní FIFO (z HDLC) & PID\_FIN & 0x04 & R \\ \hline
      Výstupní FIFO (do HDLC) & PID\_FOUT & 0x08 & W \\ \hline
   \end{tabular}
   \end{center}
   \caption{V/V porty procesoru PicoBlaze}
   \label{tab:pb_porty}
\end{table}

\begin{table}[!htp]
   \begin{center}
   \begin{tabular}{|l|l|c|c|}
      \hline
      Význam & Označení & Hodnota & čtení (R) / zápis (W) \\
      \hline \hline
      Potvrzení funkčnosti fyzické vrstvy & sr\_L1\_wrk & 0x01 & W \\ \hline
      Povolení přenosu paktů síťové vrstvy & sr\_L2\_conf & 0x02 & W \\ \hline
      Paket ve výstupním FIFO připraven & sr\_of\_rts & 0x04 & W \\ \hline
      Vstupní FIFO obsahuje paket & sr\_if\_rts & 0x10 & R  \\ \hline
   \end{tabular}
   \end{center}
   \caption{Položky Status / command registru}
   \label{tab:stat_cmd}
\end{table}

Nyní krátce popíšu ukázkový program pro procesor PicoBlaze. Program se stará o navázání spojení na linkové vrstvě (implementuje LCP protokol). Po jeho navázání umožní přenos paketů síťové vrstvy nastavením bitu sr\_L2\_conf v SCR.

Program se skládá z hlavní smyčky a pomocných rutin pro příjem a odeslání LCP paketu. V hlavní smyčce je povoleno přerušení, v obslužných rutinách je zakázáno. Pokud dojde k přerušení, jsou vynulovány interní registry, je odeslán \uv{LCP Configure-Request} paket a nastaven příznak o jeho odeslání. V hlavní smyčce je dále realizován time-out čítač (možné realizovat též hardwarově), který je spuštěn odesláním \uv{Request} paketu a nulován přijetím \uv{Ack} paketu. Pokud dojde k přetečení time-out čítače, je znovu poslán odpovídající \uv{Request} paket. Nedílnou součástí hlavní smyčky je načítání SCR. Pokud je zjištěn paket ve vstupní FIFO paměti, je přijat, a podle jeho typu je provedena následná akce. Pokud se jedná o \uv{LCP Configure-Ack} paket, který odpovídá předchozímu \uv{LCP Configure-Request} paketu je spojení nakonfigurováno a nastaven bit sr\_L2\_conf v SCR. Zpravidla příchozí \uv{Request} paket vyvolá sestavení a odeslání příslušného \uv{Ack} paketu.

V úvahu připadala rozdílná implementace založená na tabulce přerušení. Při jakékoliv změně \uv{Status / command register} se vyvolá přerušení. V obsluze přerušení je nutné tento registr načíst a zareagovat na něj příslušnou akcí. Odpadá tím nutnost periodicky vyčítat \uv{Status / command register} což lze brát za výhodu. Přináší to ovšem problém s maskováním přerušení. Pokud jsme v obsluze přerušení, je vyvolání dalšího přerušení defaultně zakázáno. Tím bychom mohli nějakou událost ztratit. Proto jsem se rozhodl pro implementaci výše popsanou.



\section{Shrnutí}
V tabulce \ref{tab:zdroje} jsou shrnuty odhady frekvence po syntéze a využité zdroje FPGA čipu pro jednotku \emph{pos\_buf}. Frekvence je uvažována pro FPGA Virtex 2 Pro s označením xc2vpx20-6ff896.

\begin{table}[!htp]
   \begin{center}
   \begin{tabular}{|l|c|c|}
      \hline
      Blok & Frekvence [MHz] & \# Slices \\
      \hline \hline
      hdlc16\_tx & 162 & 213 \\ \hline
      hdlc16\_rx & 238 & 193 \\ \hline
      ppp16 & 172 & 3015 \\ \hline
      sonet\_framer & 168 & 1389 \\ \hline
      ctrl\_stat & 253 & 152 \\ \hline
   \end{tabular}
   \end{center}
   \caption{Odhad frekvence po syntéze a využité zdroje na čipu}
   \label{tab:zdroje}
\end{table}

Pro syntézu byl použit nástroj XST od firmy Xilinx. Celá jednotka zabírá 4596 Slices což je 46\% tohoto FPGA. Odhad maximální frekvence po syntéze je 126 MHz. Mapování na technologii (MAP) a Place and Route (PaR) úspěšně proběhnou. Počet využitých Slices se po MAP snížil na 3929 (40\%) a frekvence se po PaR zvýšila na 136,5 MHz.

Vložíme-li jednotku do připravené \uv{obály} \emph{pos\_buf\_rio} s insatncovaným RocketIO-X rozhraním a DCM (Digital Clock Manager), počet obsazených Slices se po MAP zvýší na 4057, ale frekvence po PaR zůstane přibližně stejná (135,6 MHz).

Je patrné, že v obou případech nejsou splněné časové constrainy stanovené na 6,4 ns \mbox{(156 MHz)}. V navazující práci bude nutné podrobně analyzovat kritické cesty a navrhnout jejich odstranění.
