\chapter{Generování BIST kotroléru}

Pro generování BIST kontroléru byla napsaná aplikace \texttt{mbistgen}. Tato aplikace se skládá ze dvou
částí.

V první části je implementováno načítaní konfiguračních souborů (march algoritmu, souboru s primitivními
polynomy a modelu paměti). Jedná se o část psanou v jazyce C s využitím generátoru parserů Flex a
Bison\footnote{GNU implementace lex a yacc}. Zde je také implementována kompilace mikrokódu.

V druhé části jde o generování výstupních souborů na základě šablon a generování projektu BIST kontroléru. Tato část využívá jazyka Tcl a velmi jednoduché šablonovací knihovny.

Pro generování CFSR čítačů je potřeba znát alespoň jeden primitivní polynom pro danou šířku čítače.
Aplikace využívá seznam primitivních polynomů dostupný na
\url{https://www.commsys.isy.liu.se/~mikol92/polynomials/binary/primitive/one/BinaryPrimPolyList-0002-0100.txt}.

Aplikace byla vyvíjena na distribuci Debian Jessie. Mělo by ji být možné zkompilovat i na jiných POSIX kompatibilních systémech, během práce to však testováno nebylo.

\section{Model paměti}

Pro automatizované generování BIST kontroléru je třeba znát základní informace o testovaných pamětech, primárně jejich interface a logické uspořádání buněk. Z důvodu kompatibility s existujícími nástroji jsem využil existující formát využívaný firmou Mentor Graphics Corporation.
Jde o uloženou stromovou strukturu s datovými položkami. Syntaktický formát je následující:

%\setlength{\grammarparsep}{20pt plus 1pt minus 1pt} % increase separation between rules
%\setlength{\grammarindent}{12em} % increase separation between LHS/RHS 
%
%\begin{grammar}
%%[(colon){$\rightarrow$}]
%%[(semicolon){ $|$}]
%%[(period){ \rule{1ex}{1ex}\\}]
%%[(quote){‘}{’}]
%%  
%  <NUMBER> ::= `width'\'h`[0-9a-fA-F]' 
%  \alt         `width'\'b`[01]' 
%  \alt         `-?[0-9]+'
%  
%  <DOUBLE> ::= `-?[0-9.,]+'
%
%  <VALUE> ::= <STRING>
%  \alt <NUMBER>
%  \alt <DOUBLE>
%
%  <PROPERTY> ::= <STRING> `:' <VALUE> `;'
%  \alt <SECTION>
%
%  <SECTION\_BODY> ::= <PROPERTY>
%  \alt <SECTION\_BODY> <PROPERTY>
%
%  <SECTION\_HEADER> ::= <SECTION\_TYPE>
%  \alt <SECTION\_TYPE> ( <SECTION\_NAME>)
%
%  <SECTION> ::= <SECTION\_HEADER> <SECTION\_BODY>
%
%
%  <FILE> ::= <SECTION> 
%\end{grammar}

\begin{lstlisting}
  /* comment */
  section_type {
    property1: 4'b0101;
    property2: 8'hAB;
    property3: -0998;
    property4: yes;
    property5: TEST[3:0];
    subsection (section_name){
      property: value;
    }
  }
\end{lstlisting}

Hlavní sekcí konfiguračního souboru je \texttt{MemoryTemplate}. Popis jednotlivých klíčů je v 
tabulce \ref{tab:section-items}.

\tabulka{tab:section-items}{

\begin{tabular}{|l|p{11cm}|}
  \multicolumn{2}{|c|}{Sekce} \\
  \multicolumn{2}{|c|}{MemoryTemplate} \\
  CellName & Název buňky RAM paměti \\
  MemoryType & Typ paměti, musí být \texttt{"SRAM"} \\
  NumberofBits & Šířka datového slova paměti \\
  AddressCounter & Sekce popisující rozložení adresy na řádkovou a sloupcovou \\
  Port & Sekce popisující jeden port na paměti \\
\\
  \multicolumn{2}{|c|}{Sekce} \\
  \multicolumn{2}{|c|}{Port (\textit{Název portu})} \\
  Direction & Směr portu na paměťovém IP. Možnosti \texttt{INPUT} nebo \texttt{OUTPUT}. \\
  Function & Využití portu. Možnosti \texttt{Data, Address, WriteEnable, Select, Clock, LogicLow, LogicHigh} \\
  Polarity & Aktivní úroveň pinu. Možnosti \texttt{ActiveHigh, ActiveLow}\\
\\
  \multicolumn{2}{|c|}{Sekce} \\
  \multicolumn{2}{|c|}{AddressCounter} \\
  Function(\textit{Name}) & Jeden element popisující adresní čítač. Generující aplikace tento element vyžaduje 3x - s názvy: \textit{Address, RowAddress, ColumnAddress}\\
\\
  \multicolumn{2}{|c|}{Sekce} \\
  \multicolumn{2}{|c|}{Function (\textit{Name})} \\
  CountRange[\textit{hi}:\textit{lo}] & Čítač \textit{Name} má rozsah adres od \textit{lo} k \textit{hi}\\
  LogicAddressMap & Udává složení fyzické adresy ze sloupcové/řádkové \\
\end{tabular}
}{Popis konfiguračních sekcí a užitých klíčů.}

Sekce LogicAddressMaP přiřazuje jednotlivé čítače do logické adresy. Jednotlivé položky mají formát: \texttt{(Název čítače) [hi:lo]: Address [hi:lo];}.

Příkladem modelu paměti může být výpis \ref{lst:memory-model}. Z těchto dat je možno vygenerovat vhodný
interface k paměti. Položka \texttt{NumberofBits} a rozsahy čítačů se použijí pro konfiguraci test
kontroléru. Neznáme konfigurační sekce a klíče jsou ignorovány.

\begin{lstlisting}[basicstyle=\scriptsize, float, caption={Ukázková konfigurace paměti SRAM 512x22}, label=lst:memory-model]
MemoryTemplate ( spram512x22cm4Mhz10 ) {
   CellName:      spram512x22cm4Mhz10;
   MemoryType:    SRAM;
   NumberofWords:  512;
   NumberofBits :  22;
   AddressCounter {
     Function (Address) {
       LogicalAddressMaP {
         ColumnAddress [1:0] : Address [1:0] ;
         RowAddress [6:0] : Address [8:2] ;
       }
     }
     Function (Rowaddress) {
       CountRange [0:127];
     }
     Function (Columnaddress) {
       CountRange [0:3];
     }
   }
   Port (  Q[21:0] )
   {   
      Direction: OUTPUT;
      Function: data;
   }
   Port (  ADR[8:0] )
   {   
     Direction: INPUT;
     Function: Address;
   }
   Port (  D[21:0] )
   {   
     Direction: INPUT;
     Function: data;
   }
   Port (  WE )
   {   
     Direction: INPUT;
     Function: WriteEnable;
     Polarity: ActiveHigh;
   }
   Port  (  ME )
   {   
     Direction: INPUT;
     Function: Select;
     Polarity: ActiveHigh;
   }
   Port (  CLK )
   {   
     Direction: INPUT;
     Function: Clock;
     Polarity: ActiveHigh;
   }
}
\end{lstlisting}

\section{Šablony souborů}

Pro generování výstupních zdrojových kódů byl využít velmi jednoduchý šablonovací systém
TemplaTcl\footnote{K dispozici na: \url{http://wiki.tcl.tk/18175}.}. Tento šablonovací systém využívá
dvou druhů \uv{tagů} pro řízení generování výstupního souboru.
Tag \texttt{<\%= expression \%>} slouží k vložení hodnoty proměnné nebo výsledku výrazu do výstupu.
Tag \texttt{<\% code \%>} slouží  pro uvození Tcl kódu k řízení generování výstupu. 

Jednoduchý příklad využití je vidět na souboru \texttt{templates/mbist\_fof.tcl.ttcl} ve 
výpisu \ref{lst:mbist-fof}. Je zde vidět generování seznamu souborů pro kompilaci. Na 5.--7. řádku 
je smyčka pro všechny prvku předané  v seznamu \$Memories. Řádek 6 je tedy ve výsledku zopakován
pro každý element v poli \$Memories, pokaždé s odpovídajícím názvem.

\begin{lstlisting}[caption=Soubor templates/mbist\_fof.tcl.ttcl, label=lst:mbist-fof]
  VHDL_COMP $env(BM_RTL_DIR)/mbist_pkg.vhd
  VHDL_COMP $env(BM_RTL_DIR)/mbist_cnt.cfsr.rtl.vhd
  VHDL_COMP $env(BM_RTL_DIR)/mbist_ncnt.dec.rtl.vhd
  VHDL_COMP $env(BM_RTL_DIR)/mbist_ts_core.rtl.vhd<%
foreach {memory} $Memories { %>
  VHDL_COMP $env(BM_RTL_DIR)/mbist_mai_<%= [dictGetCI $memory ComponentName] %>.rtl.vhd<%  
} %>
  VHDL_COMP $env(BM_RTL_DIR)/mbist_top.str.vhd
\end{lstlisting}

\section{Tcl API}

V Tcl části jsou nachystané high level metody pro práci s generátorem BIST kontroléru. Všechny Tcl funkce jsou definovány v souboru \texttt{bootstrap.tcl}, který se načte po startu. Jedná se o funkce:

\paragraph{createTS targetDir sourceFile memories} \mbox{}

Zkompiluje mikrokód ze souboru \$sourceFile a vygeneruje blok řízení test kontroléru.
Šířky čítačů a počet kroků pro smarch operaci jsou určeny z pamětí v seznamu \$memories.

Tato funkce generuje soubory \texttt{mbist\_ts\_core.rtl.vhd} a \texttt{mbist\_pkg.vhd}, které uloží do adresáře \$targetDir. Ke generování použije šablonu \path{templates/mbist_ts_core.rtl.vhd.ttcl}.

\paragraph{createSS targetDir memoryFile} \mbox{}

Vygeneruje interface paměti pro model paměti v souboru \$memoryFile. Současně vrátí slovník obsahující informace o paměti pro generování TOP modulu.

Výsledek uloží do souboru \texttt{mbist\_mai\_(cellName).rtl.vhd} v adresáři \$targetDir. Ke generování používá šablonu \path{templates/mbist_mai_ssram.rtl.vhd.ttcl}.

\paragraph{createTop targetDir memories memoryNames memoryWords} \mbox{}

Vygeneruje top modul pro BIST kontrolér. Do TOP modulu vloží instanci test sequenceru a interface pro všechny paměti uvedené v seznamu \$memories. Ke vstupům a výstupům přidá předponu podle seznamu v \$memoryNames. Jako testovací vektory používá slova ze seznamu \$memoryWords.

Výsledek uloží do souboru \texttt{mbist\_top.str.vhd}. Ke generování použije šablonu \path{templates/mbist_top.str.vhd.ttcl}.

\paragraph{createBfm targetDir memories testSequencer} \mbox{}

Vygeneruje BFM pro BIST kontrolér. Pro jeho nastavení využije parametry pamětí v seznamu \$memories a parametry řízení BIST kontroléru ze slovníku \$testSequencer.
Výsledek uloží do souboru \texttt{mbist.sv}. Ke generování použije šablonu \path{templates/mbist_bfm.sv.ttcl}.

\paragraph{createFof targetDir memories}\mbox{}

Tato ukazuje možnost rozšíření generování o další soubory. V ukázkové implementaci generuje skript sloužící jako seznam jednotlivých HDL souborů ke kompilaci.

Výsledek uloží do souboru \texttt{mbist.fof.tcl} v adresáři \$targetDir. Ke generování použije šablonu \path{templates/mbist.fof.tcl.ttcl}.


Příklad jejich využití je na výpise \ref{lst:simple-project}.

\begin{lstlisting}[float, caption={Ukázkový projekt pro mbistgen -- paměť SRAM 512x22}, label=lst:simple-project]
#Define target directories for specified output types
set targetDir /cesta/k/adresari/s/rtl
set modelDir  /cesta/k/adresari/s/model
set configDir /cesta/k/adresari/s/config

#Prepare lists for data
set memories {}
set words {}
set memNames {}

#Load data about memory
lappend memories [createSS $targetDir $modelDir/spram512x22cm4Mhz10.lvlib]
lappend words [list x\"000000\" x\"3FFFFF\" x\"155555\" x\"2AAAAA\" x\"0CCCCC\" x\"333333\" x\"0F0F0F\" x\"30F0F0\"]
lappend memNames Name

#Create test sequencer
set ts [createTS $targetDir march/SMarchCHKBci.m $memories]

#Create BIST top module
createTop $targetDir $memories $memNames $words

#Create BFM
createBfm $modelDir $memories $ts

#Create files with list of generated files
createFof $configDir $memories
\end{lstlisting}

\section{Užití}

Aplikace určená pro generování BIST kontroléru má dva základní módy použití.

První je možnost využít napsaný \uv{projekt} ve formě Tcl skriptu podobného tomu ve
výpisu \ref{lst:simple-project}. Tento způsob má větší flexibilitu a uživatel může nakonfigurovat
jednotlivé kroky generování sám. Může také využít aplikaci pro generování BIST kontroléru pro více pamětí.
Nachystaný projekt se poté předá jako parametr aplikaci \texttt{mbistgen} následovně:
\texttt{./mbistgen -d projekt.tcl}.

Druhá možnost je využít zjednodušený mód pro generování BIST kontroléru pouze pro jedinou paměť.
V tomto případě se všechny potřebné informace předají pomocí parametrů aplikaci \texttt{mbistgen}.
Formát příkazové řadky je:
\texttt{./mbistgen -s -{}-memory[memoryModel.lvlib] -{}-target [targetDirectory] -{}-name [conn-} \newline
\texttt{ectionPrefix]}, kde \texttt{memoryModel.lvlib} představuje soubor s modelem paměti,
\texttt{connectionPrefix} předponu názvu pro signály pro danou paměť a \texttt{targetDirectory},
který ukazuje na adresář s cílovým HDL designem. 
Aplikace v takovém případě využije předpřipravený projekt v souboru \texttt{simple.tcl}. V tomto projektu
jsou již nachystané cesty do podadresářů pro jednotlivé generované části. Ten projekt tedy očekává,
že v adresáři targetDirectory bude již nachystaná následující adresářová struktura:

\dirtree{%
  .1 [targetDir]. 
  .2 config. 
  .2 hdl. 
  .3 rtl. 
  .3 model. 
  .3 testcase. 
}

\vspace{0.5cm}


V obou případech je interface TOP modulu \texttt{MBIST\_TOP} následující:

\begin{lstlisting}
entity MBIST_TOP is
  port (
    --Global signals
    CLK   : in std_logic;           -- Global clock signal
    RST_B : in std_logic;           -- Global reset signal

    --BIST interface
    BISTE : in std_logic;           -- Enable of bist controller
    DLY_CLK: in std_logic;          -- Clock for delay operation
    FAIL  : out std_logic;          -- Test found error in memory
    DONE  : out std_logic;          -- Test sequence hit end

    -- Section for memory $cennectionPrefix 
    $connectionPrefix_MEM_...       -- Connections for memory cell
    $connectionPrefix_DIG_...       -- Connections for digital logic

    -- Serial diagnostic interface
    SDI   : in std_logic;
    SCLK  : in std_logic;
    SME   : in std_logic;
    SEN   : in std_logic;
    SDO   : out std_logic
  );
end entity MBIST_TOP;
\end{lstlisting}
