\section{Custom Layout Design Functions in Software}
\label{sec:parameterized}

OpenRAM provides classes that can be used to generated parameterized
cells for the most common cells: transistors, inverters, nand2, nand3, etc...  
There are many advantages to having parameterized cells.
The main advantage is that it makes it easier to dynamically generate designs and cuts
down the necessary code to be written.  
We also need parameterized cells because some designs, such as the wordline drivers, need to be
dynamically sized based on the size of the memory. 
Lastly, there may be certain physical dimension requirements that need to be met for a
cell, while still maintaing the expected operation/performance.  
In OpenRAM we currently provide five parameterized cells: parameterized
transistor (\verb|ptx|), parameterized inverter (\verb|pinv|), parameterized nand2 (\verb|nand_2|), 
parameterized nand3 (\verb|nand_3|) and parameterized nor2 (\verb|nor_2|). 


\subsection{Parameterized Transistor}
\label{sec:ptx}

The parameterized transistor class generates a transistor of specified
width and number of mults.
The \verb|ptx| is constructed as follows:
\begin{verbatim}
def __init__(self,name,width,mults,tx_type)
\end{verbatim} 

An explanation of the \verb|ptx| parameters is shown in
Table~\ref{table:ptx_params}. A layout of ptx, generated by the
following instatiation, is depicted in Figure~\ref{fig:ptx_example}.
\begin{verbatim}
fet = ptx.ptx(name = "nmos_1_finger", width = tech.drc["minwidth_tx"], 
mults = 1, tx_type = "nmos").
\end{verbatim}

\begin{table}[h!] 
  \begin{center}
    \begin{tabular}{| l | c |}
    \hline
    Parameter & Explanation  \\ \hline
    \verb|width| & active\_height \\ \hline
    \verb|mults| & mult number of the transistor \\ \hline
    \verb|tx_type| & type of transistor,”nmos” and “pmos” \\ \hline
    \hline
    \end{tabular}
  \end{center}
  \caption{Parameter Explanation of ptx}
  \label{table:ptx_params}
\end{table}


\begin{figure}[h!]
\centering
\includegraphics[width=10cm]{./figs/ptx.pdf}
\caption{An example of Parameterized Transistor (ptx)}
\label{fig:ptx_example}
\end{figure}



\subsection{Parameterized Inverter}
\label{sec:pinv}

The parameterized inverter (\verb|pinv|) class generated an inverter
of a specified size/strength and height.  The \verb|pinv| is
constructed as follows:
\begin{verbatim}
def __init__(self, cell_name, size, beta=tech.[pinv.beta], 
cell_size=tech.cell[height])
\end{verbatim}

The parameterized inverter can provide significant drive strength
while adhering to physical cell size limitations. That is achieved by
having many small transistors connected in parallel, thus the height
of the inverter cell can be manipulated without the affecting the
drive strength. The NMOS size is an input parameter, and the PMOS size
will be determined by $beta*NMOS\_size$, where beta is the ratio of
the PMOS channel width to the NMOS channel width.  The following code
instatiates the \verb|pinv| instance seen in Figure~\ref{fig:pinv}.
\begin{verbatim}
a=pinv.pinv(cell_name="pinv",size=tech.drc["minwidth_tx"]*8)
\end{verbatim}
\begin{figure}[h!]
\centering
\includegraphics[width=10cm]{./figs/pinv.pdf}
\caption{An example of Parameterized Inverter(pinv)}
\label{fig:pinv}
\end{figure}


The \verb|pinv| parameters are explained in Table~\ref{table:pinv_params}.
\begin{table}[h!] 
  \begin{center}
    \begin{tabular}{| l | c |}
    \hline
    Parameter & Explanation \\ \hline
    \verb|size| & The logic size of the transistor of the nmos in the pinv \\ \hline
    \verb|beta| = tech.[pinv.beta] & Ratio of pmos channel width to nmos channel width. \\ \hline
    \verb|cell_size| = tech.cell[height] & physical dimension of cell height. \\ 
    \hline
    \end{tabular}
  \end{center}
  \caption{Parameter Explanation of pinv}
  \label{table:pinv_params}
\end{table}



\subsection{Parameterized NAND2}
\label{sec:nand2}

The parameterized nand2 (\verb|nand_2|) class generated a 2-input nand gate
of a specified size/strength and height.  The \verb|nand_2| is
constructed as follows:
\begin{verbatim}
def __init__(self, name, nmos_width, height=tech.cell_6t[height])
\end{verbatim}

The NMOS size is an input parameter, and the PMOS size
will be equal to NMOS to have the equal rising and falling for output. 
The following code instatiates the \verb|nand_2| instance seen in Figure~\ref{fig:nand2}.
\begin{verbatim}
a=nand_2.nand_2(name="nand2", nmos_width=2*tech.drc["minwidth_tx"], 
height=tech.cell_6t["height"])
\end{verbatim}

\begin{figure}[h!]
\centering
\includegraphics[width=10cm]{./figs/nand2.pdf}
\caption{An example of Parameterized NAND2(nand\_2)}
\label{fig:nand2}
\end{figure}


The \verb|nand_2| parameters are explained in Table~\ref{table:nand2_params}.
\begin{table}[h!] 
  \begin{center}
    \begin{tabular}{| l | c |}
    \hline
    Parameter & Explanation \\ \hline
    \verb|nmos_width| & The logic size of the transistor of the nmos in the nand2 \\ \hline
    \verb|height| = tech.cell\_6t[height] & physical dimension of cell height. \\ 
    \hline
    \end{tabular}
  \end{center}
  \caption{Parameter Explanation of nand2}
  \label{table:nand2_params}
\end{table}



\subsection{Parameterized NAND3}
\label{sec:nand3}

The parameterized nand3 (\verb|nand_3|) class generated a 3-input nand gate
of a specified size/strength and height.  The \verb|nand_3| is
constructed as follows:
\begin{verbatim}
def __init__(self, name, nmos_width, height=tech.cell_6t[height])
\end{verbatim}
The NMOS size is an input parameter, and the PMOS size
will be equal to $2/3$ NMOS size to have the equal rising and falling for output.
The following code instatiates the \verb|nand_3| instance seen in Figure~\ref{fig:nand3}.
\begin{verbatim}
a=nand_3.nand_3(name="nand3", nmos_width=3*tech.drc["minwidth_tx"], 
height=tech.cell_6t["height"])
\end{verbatim}


\begin{figure}[h!]
\centering
\includegraphics[width=10cm]{./figs/nand3.pdf}
\caption{An example of Parameterized NAND3(nand\_3)}
\label{fig:nand3}
\end{figure}

The \verb|nand_3| parameters are explained in Table~\ref{table:nand3_params}.
\begin{table}[h!] 
  \begin{center}
    \begin{tabular}{| l | c |}
    \hline
    Parameter & Explanation \\ \hline
    \verb|nmos_width| & The logic size of the transistor of the nmos in the nand3 \\ \hline
    \verb|height| = tech.cell\_6t[height] & physical dimension of cell height. \\ 
    \hline
    \end{tabular}
  \end{center}
  \caption{Parameter Explanation of nand3}
  \label{table:nand3_params}
\end{table}


\subsection{Parameterized NOR2}
\label{sec:nor2}

The parameterized nor2 (\verb|nor_2|) class generated a 2-input nor gate
of a specified size/strength and height.  The \verb|nor_2| is
constructed as follows:
\begin{verbatim}
def __init__(self, name, nmos_width, height=tech.cell_6t[height])
\end{verbatim}
The NMOS size is an input parameter, and the PMOS size
will be equal to $2$ NMOS size to have the equal rising and falling for output.
The following code instatiates the \verb|nor_2| instance seen in Figure~\ref{fig:nor2}.
\begin{verbatim}
a=nor_2.nor_2(name="nor2", nmos_width=2*tech.drc["minwidth_tx"], 
height=tech.cell_6t["height"])
\end{verbatim}


\begin{figure}[h!]
\centering
\includegraphics[width=10cm]{./figs/nor2.pdf}
\caption{An example of Parameterized NOR2(nor\_2)}
\label{fig:nor2}
\end{figure}

The \verb|nor_2| parameters are explained in Table~\ref{table:nor2_params}.
\begin{table}[h!] 
  \begin{center}
    \begin{tabular}{| l | c |}
    \hline
    Parameter & Explanation \\ \hline
    \verb|nmos_width| & The logic size of the transistor of the nmos in the nor2 \\ \hline
    \verb|height| = tech.cell\_6t[height] & physical dimension of cell height. \\ 
    \hline
    \end{tabular}
  \end{center}
  \caption{Parameter Explanation of nor2}
  \label{table:nor2_params}
\end{table}



\subsection{Path and Wire}
\label{sec:path and wire}
OpenRam provides two routing classes in custom layout design.
Both Path and wire class will take a set of coordinates connect those points 
with rectilinear metal connection.

The difference is that path only use the same layers for both vertical and 
horizontal connection while wire will use two different adjacent metal layers.
The this example will construct a metal1 layer path
\begin{verbatim}
layer_stack = ("metal1")
position_list = [(0,0), (0,3), (1,3), (1,1), (4,3)]
w=path.path(layer_stack,position_list) 
\end{verbatim}
and This exmaple will construct a wire using metal1 for vertical connection and metal2 for 
horizontal connection:
\begin{verbatim}
layer_stack = ("metal1","via1","metal2")
position_list = [(0,0), (0,3), (1,3), (1,1), (4,3)]
w=wire.wire(layer_stack,position_list)
\end{verbatim}



