\documentclass{article}

\usepackage[backend=bibtex]{biblatex}
\usepackage{graphicx}
\usepackage{hyperref}
\usepackage{siunitx}
\usepackage[table]{xcolor}

\bibliography{report}
\title{Classifying rocks via 7810-dimensional spectroscopy}
\author{Miroslav Vitkov}

\begin{document}
\maketitle

\begin{abstract}
This work explores classification of rocks by their laser ablasion spectrum in C++.

Multiclass classification over sparse input space is performed\footnote{https://github.com/MiroslavVitkov/rocks}.
The task is made significantly easier by having up to 64 input vectors with the same label.
The most promising algorithm is then tuned - kernel type, kernel parameters, data preprocessing.
The business application accuracy is theoretically derived from the per sample accuracy.

A secondary goal is overview of modern free C++ machine learning libraries.
\end{abstract}

\section{Introduction}
Geologists recognise three categories of rocks: \textit{sedimentary, metamorphic, and igneous}.
Each containing tens of concrete types of rock.
Measuring the type of a rock is currently being done by bulky equipment after rock sample collection.
This text explores the machine learning side of designing a device, which is:
\begin{itemize}
\item{hand-held}
\item{accurate to less than 1 failure per year of constant usage}
\item{afordable - an Android smartphone used for data processing.}
\end{itemize}
\par
One competitor of the device are the Nitron X-ray handhelds\cite{nitron}.
\\
\par
The theoretical conclusion is that the device is possible.

\section{Related Work}
Rocks from the Karkonosze Mountains have been classified via $[\SI{350}{\nano\metre}-\SI{2500}{\nano\metre}]$ spectroscopy\cite{karkonosze}.
They acheaved a macro averaged accuracy of 76.2\%.
A standartised light source was used instead of laser ablation.
\par
A lidar-based survey\cite{lidar} produced inconclusive results.
\par
The Curiosity mars rover was equipped with a LIBS unit\cite{curiosity} as will be the upcoming ExoMars\cite{exomars}.
\par
Interestingly, LIBS seems to be pretty loud and can in the future benefit from fusing the spectrogram with acoustic features\cite{microphone}.

\section{Dataset}
Laser-induced breakdown spectroscopy\cite{libs_intro} involves turning some matter into plasma and observing it's radiant spectrum.
That is measured by a spectrometer and discretized into 7810 buckets of central frequency from  \SI{180}{\nano\metre} upward in steps of \SI{0.1}{\nano\metre}.
The spectrometer has an apparent peak in sensitivity around \SI{440}{\nano\metre} but important spectral lines are spread through the whole measurement range.
\par
Key variables in LIBS are beam power, diameter; burn time(the spectrum changes with time during the burn).
They are held constant and unknown in this study.
\par
The 7810 measured values for each spectrum represent the radiance\cite{radiance} of the plasma convoluted with the \textbf{unknown} impulse response of the measurement equipment.
\par
The dataset consists of 2710 datapoints all classified within 6 labels( rock types ) and 45 sublabels( measurement neighbourhoods ).
The reference number of the dataset is 190401.
The excitation laser wavelength is \SI{1064}{\nano\metre}.

The string labels are encoded in integers in alphabetical order:
\\
\\
\rowcolors{1}{white}{lightgray}
\begin{tabular}{c | c}
azurite & 0     \\
brochantite & 1 \\
chalcopyrite & 2 \\
chrysocolla & 3  \\
malachite & 4    \\
tetrahedrite & 5 \\
\end{tabular}

The sub-labels are simply the consecutive number of the measured spot.

\section{Noise}
Boiling plasma is not theoretically expected to absorb light of any wavelength.
The dataset violates this assumption!
\par
\begin{verbatim}
Dataset consists of 2710 files.
The global micro average intensity is 114.398.
The global count of negative values is 2442125, which is 0.115385 of all datapoints.
The mean of all negative values is -9.10135.
The most extreme negative value is -1042.48.
\end{verbatim}s
\begin{itemize}
\item{One model of the noise is harmonics of the exciting laser.
This hypothesis fails due to it operating at \SI{1064}{\nano\metre}, which is not a multiple of the observed spikes' frequency.}
\item{Another model is Gaussian noise with $\mu=\SI{440}{\nano\metre}, \sigma=\SI{40}{\nano\metre}$.}
\item{Another model is uniform noise, multiplied by the impulse response of the measurement equipment.
Instrument IR can be recovered by averaging each frequency's mean value over all samples (i.e. stochastic multidimensional mean).}
\end{itemize}
\begin{figure}
\caption{Most extreme negative intensity}
\centering
\includegraphics[width=1.25\textwidth]{img/negatives}
\end{figure}
Noise filtering has not been implemented.
The models are expected to cope with the noise on their own.

\section{Dimensionality Reduction}
The number of features (7810) is larger than the dataset size(2711).
Thus better performance is expected from the classifiers after dimensionality reduction.

On the other hand, feature selection techniques should point to prominent spectral lines.
Those could be valuable to domain experts.

\subsection{Principal component analysis}
Numerous algorithms have been developed to compute this simple yet powerful transformation.
For example the Gram-Schmid ortogonalization can be parallelised over a GPU \cite{andrecut}.
Here we use the classical NIPALS-PCA algorithm for simlicity.

\subsection{Linear discriminant analysis}
$$ \frac{ \mu_1 - \mu_2 } { s^1 + s^2 } \to max$$

Like \textit{sklearn}'s LDA implementation, \textit{OpenCV}'s results in at most (num classes - 1) dimensional transformed space.
For the examined dataset \textit{d=5}.
The classification accuracy of the SVM dropped from 0.97 to 0.18.

\subsection{t-SNE}
For comparison, a t-distributed stochastic neighbour embedding should have been run.

\section{Preprocessing}
\subsection{Normalization}
$$ \vec{y} = (\vec{x} - \vec{E}) / \vec{\sigma} $$
, where all operations are performed element-wise.
Normalization surprisingly worsened performance from 0.97 to 0.93.

\subsection{Logarithm}
Compressing the signal range worsened the accuracy from 0.97 to 0.77.

\section{Models}
Each model conceptually accepts a single spectrum vector of 7810 real numbers.
Later in this text the sampling strategy and ensemble voting are discussed.
Each algorithm is trained on a labeled dataset (split from the original dataset via simple holdout).
And then evaluated on a similarly constructed test dataset, one spectrum (7810-dimensional vector) at a time.
\par
The following algorithms were tried with default parameters, this is the micro averaged accuracy:
\\ \par
\rowcolors{1}{white}{lightgray}
\begin{tabular}{ c | c | c | c | c }
algorithm      & accuracy                & predict          & train                            & acceleration \\
random chance  & 0.16                    & \SI{0}{\second}  & \SI{0}{\second}                  & single thread \\
correlation    & 0.85                    & \SI{76}{\second} & \SI{0}{\second}                  & multi-thread \\
SVM            & 0.97                    & \SI{0}{\second}  & \SI{3}{\minute} \SI{21}{\second} & multi-thread \\
neural network & 0.20                    & \SI{0}{\second}  & \SI{2}{\minute} \SI{7}{\second}  & multi-thread \\
random forest  & 0.17                    & \SI{21}{\second} & \SI{1}{\hour} \SI{49}{\minute}   & multi-thread \\
\end{tabular}

\subsection{Random Chance}
For sanity checking of the system, a random chance model was developed.
It looks only at the distribution of training labels and produces a similar stochastic distribution at prediction time.
An alternative would have been to always predict the most common class.
That would have improved repeatability between runs, but the generated distribution would have been too different than that of a predictive model.

\subsection{Correlation}
With such a small dataset, correlation is feasible.
It yields good results, but is not scalable.

\subsection{SVM}
A multiclass SVM is tested with a linear kernel because that is the only one dlib\cite{dlib} supports.

%maximum-margin classifier
%kernel trick
%hard/soft margin
%Radial basis function kernel
%http://webspace.ulbsibiu.ro/lucian.vintan/html/sci.pdf
%one vs one / one vs many
%curse of dimensionality
%https://stats.stackexchange.com/questions/77876/why-would-scaling-features-decrease-svm-performance?rq=1
%https://arxiv.org/pdf/0810.4752v1.pdf
%https://stats.stackexchange.com/questions/10423/number-of-features-vs-number-of-observations/10426#10426
%https://stats.stackexchange.com/a/10426/208261
%https://stats.stackexchange.com/questions/186184/does-dimensionality-curse-effect-some-models-more-than-others
%choice of regularization coefficient c
%choice of kernel
%choice of kernel parameters
% probabilistic classifier

\subsection{Neural Network}
A naive model with two hidden layers with relu activations performed extremely poorly.
It is unclear if this is due to programming errors or due to wrong architecture of the network.

\subsection{Random Forest}
An OpenMP-based random forest classifier took extremely long to train and yielded poor results.

\section{Measuring Accuracy}
Accuracy, as well as the other summary statistics, in the case of multiclass classification is not uniquely defined.
Those are the two approaches:
\begin{itemize}
\item{Micro average - record a True Positive and Total statistics among all classes. }
\item{Macro average - compute the accuracy for each class, then average those.}
\end{itemize}
Our approach is to calculate a confusion matrix because of it's usefulness in gaining insight into the problem.
Then reduce that to a signle number: micro averaged accuracy - so that models can be compared.

\section{Sampling}
Holdout sampling is performed thus: 66\% of all datapoints across all labels are selected as a training set.
The remaining 34\% are assigned to a test set with no validation set assigned.
The split is performed via a pseudorandom number generator because the application does not need to be cryptographically secure.
No regard is payed to labels when splitting.

\section{Tuning the model}
The SVM model performed well and runs quickly at prediction time.
This model was selected for parameter tuning.
However, the used implementation allows the use only linear kernels for multiclass SVMs (why)?
A grid search for the regularization coefficient c in the range [1e-5, 1e5] indicates said space is rather flat.

\begin{tabular}{ c | c }
c & accuracy  \\
1e-5 & 0.788652  \\
1e-4 & 0.780142  \\
1e-3 & 0.798582  \\
1e-2 & 0.794326  \\
1e-1 & 0.798582  \\
1e0 & 0.802837  \\
1e1 & 0.792908  \\
1e2 & 0.801418  \\
1e3 & 0.791489  \\
1e4 & 0.807092  \\
1e5 & 0.798582  \\
\end{tabular}

Also notice the drop in accuracy compared to the results reported in chapter 'Model'.
This is due to training on a smaller dataset, due to withholding the validation partition.
Naturally, both the training and validation partitions sets are used to train the final classifier.

\section{Implementation}
\subsection{Language}
C++ was chosen as the language of the implementation.

\subsection{Design}
The program uses the \textbf{Command} design pattern to fit different working modes into one executable.

The classifier models follow the Open/Close OOP principle.
They should have worked with either raw spectra or with preprocessed data, but that would have complicated the interface design.
Thus preprocessing techniques were tested in hardcoded SVMandX models.

To separate interface from implementation \textbf{pImpl} is used.
Not only do implementation details remain hidden, external includes also remain only in the .cpp file.

The \textbf{Factory} model::create() connects seamlessly with the command line parser module.

\subsection{Libraries}
\begin{itemize}
\item{dlib - a small mathematical library, used for correlation, neural networks, SVM.}
\item{Qwt - a native plotting library. It's main rival is the C++ bindings for pyplot.}
\item{OpenCV - used for PCA, because dlib's methods only work for binary classification problems out of the box.}
\end{itemize}

\subsection{Data structures}
Traditionally a dataframe is used to store and represent a dataset.
To the contrary we used a map from labels to a set of observations.
A function was provided for walking this structure.
Overall this setup performs well except when the shape of the dataframe needs to change.

\section{Voting}
Majority voting with n=60 samples and accuracy a=0.9828 yields overall expected error rate of
\begin{verbatim}
$ find . -name *.csv | wc -l
2710
$ calc "2710 / 45"
~60.22222
>>> import math
>>> # Probability of majority voting to fail:
>>> # ( 1 - 0.9828 ) ^ 30 + ( 1 - 0.9828 ) ^ 31 + ... + ( 1 - 0.9828 ) ^ 60
>>> # Let's take only the largest term.
>>> math.pow(( 1 - 0.9828 ),30)
1.163733153901975e-53
>>> # Let's assume one test per second.
>>> # The Mean Time Between Failures is the invese of the frequency of failures.
>>> 1 / 1.163733153901975e-53
8.593035238766027e+52  # seconds
>>> # Let's divide this by the age of the universe.
>>> 8.593035238766027e+52 / ( 31557600 * 13.8e9 )
1.973165617645385e+35
\end{verbatim}

\section{Conclusion}
\subsection{Experimental}
A large number of test points which are guaranteed to be of the same label is provided during real world operation.
This results in even a simple model like an SVM solving the problem practically perfectly.
A typical confusion matrix looks like this:
\begin{verbatim}
52  0  0  0  0  2
 0 63  0  0  0  0
 0  0 57  1  0  0
 0  0  0 64  0  0
 0  0  0  4 59  1
 2  0  0  0  0 62
\end{verbatim}

\subsection{Language}
Customarily machine learning is done in Python.
Those are our observations over the suitability of C++ for such tasks.
\begin{itemize}
\item{Central repository - Python "comes with the batteries included".
                           Somewhat mitigating this, this project uses a plethora of libraries known to be open-source, with permissive license, easy to use, efficient.
                           The project thus can be used as a demo of C++ ML libraries.
}
\item{Type safety - due to the nature of matrix multiplication, the result is rarely in the same form as the input.
                    Thus new types need to be created between any two operations, making pipelining more tedious.
                    Overall little is gained by labelling lists of numbers which change their representation but preserve their meaning.}
\item{Plotting - plotting libraries for C++ are scarce, one of the most popular candidates being the bindings to matplotlib.}
\item{Dataframes - matrix calculations, consistency between test run results.}
\item{GPU access - OS and hardware abstraction is almost impossible}
\end{itemize}

\printbibliography

\end{document}


\documentclass[11pt]{article}

\usepackage{texyousei}
\usepackage{tabularx}

\lhead{}
\chead{}
\rhead{}

\usepackage{comment}
\excludecomment{oops}

\setlength{\leftmargini}{0.3in}

\DeclarePairedDelimiter{\inner}{\langle}{\rangle}
\newcommand{\ddx}{\frac{d}{dx}}
\newcommand{\ddy}{\frac{d}{dy}}
\newcommand{\ddn}{\frac{d}{dn}}
\newcommand{\ddm}{\frac{d}{dm}}
\newcommand{\sgn}[1]{\ \textrm{sgn}\left(#1\right)}
\newcommand{\calDf}{\mathcal{D}_f}

\begin{document}

\maketitle{Path Planning using Repulsive Energies}{Chris Yu (christoy@cs.cmu.edu)}

\thispagestyle{empty}

\begin{figure}[h]
\includegraphics[width=\textwidth]{pathplan.png}
\caption{\emph{Left:} A path planning scenario in which each agent must move to the opposite corner. \emph{Right:} Motion trajectories can be represented as 3D curves, which can be optimized.}
\end{figure}

\paragraph{Background and motivation.} Avoiding collisions and self-collisions is a frequent challenge in design tasks. \emph{Repulsive energy functions} can be used to facilitate self-avoidance on curves and surfaces; these energies present an infinite potential barrier to collisions, and their gradient flows thus repel shapes, preventing them from self-intersecting.

One potential application of these energies lies in path planning, either involving single or multiple agents. Consider a robot that travels along the ground; its environment can be represented as a planar 2-dimensional region. Suppose that the robot's goal is to travel from point $x$ of its environment to point $y$. This equates to finding a time-parameterized curve $\gamma : [0,1] \to \R^2$ connecting the two points, meaning $\gamma(0) = x$ and $\gamma(1) = y$. The 3-dimensional graph of this curve then corresponds to a space curve in $\R^2 \times [0,1] \subset \R^3$, where the third coordinate corresponds to time. This curve can be optimized using repulsive energies to be made more robust to collisions.

The problem becomes even more interesting when multiple agents are involved; each agent's trajectory then corresponds to a separate curve $\gamma_i \subset \R^2 \times [0,1]$, and in addition to each such curve avoiding obstacles, the curves must also avoid each other -- a task that repulsive energies are well-suited for.

\paragraph{Goals.} The goal will be to develop a practical path planning algorithm for 2D environments, involving either single agents or multiple agents, that combines traditional approaches (e.g. traditional graph search) with continuous optimization using repulsive energies. The continuous optimization aspect of the problem so far does not seem to have been well-explored so far in path planning literature.

\paragraph{Skill set.} Students should ideally be familiar with basic differential geometry related to curves in space, as well as introductory optimization concepts such as gradient descent. Programming experience with C++ is also desirable. Some familiarity with robotic path planning is a bonus.

\end{document}


\documentclass[epsfig,10pt,fullpage]{article}

\newcommand{\LabNum}{9}
\newcommand{\CommonDocsPath}{../../../common/docs}
\input{\CommonDocsPath/preamble.tex}

\begin{document}

\centerline{\huge Digital Logic}
~\\
\centerline{\huge Laboratory Exercise \LabNum}
~\\
\centerline{\large A Simple Processor}
~\\

Figure~\ref{fig:fig1} shows a digital system that contains a number of 16-bit registers,
a multiplexer, an adder/subtracter, and a control unit (finite state machine).  Information
is input to this system via the 16-bit {\it DIN} input, which is loaded into the {\it IR}
register. Data can be transferred through the 16-bit wide multiplexer from one register
in the system to another, such as from register {\it IR} into one of the {\it general
purpose} registers $r0, \ldots, r7$.  The multiplexer's output is called {\it Buswires}
in the figure because the term {\it bus} is often used for wiring that allows data to be
transferred from one location in a system to another. The FSM controls the {\it Select}
lines of the multiplexer, which allows any of its inputs to be transferred to any register
that is connected to the bus wires.

~\\
The system can perform different operations in each clock cycle, as governed by the FSM.
It determines when particular data is placed onto the bus wires and controls which of the
registers is to be loaded with this data. For example, if the FSM selects $r0$ as the output of the
bus multiplexer and also asserts $A_{in}$, then the contents of register $r0$ will be loaded on the
next active clock edge into register {\it A}.

~\\
Addition or subtraction of signed numbers is performed by using the multiplexer to first
place one 16-bit number onto the bus wires, and then loading this number into register {\it A}.
Once this is done, a second 16-bit number is placed onto the bus, the adder/subtracter
performs the required operation, and the result is loaded into register {\it G}. The
data in {\it G} can then be transferred via the multiplexer to one of the other registers,
as required.

\begin{figure}[H]
	\begin{center}
		\includegraphics[scale = 0.8]{figures/figure1.pdf}
	\end{center}
	\caption{A digital system.}
	\label{fig:fig1}
\end{figure}

\newpage
\noindent
A system like the one in Figure~\ref{fig:fig1} is often called a {\it processor}. It
executes operations specified in the
form of {\it instructions}. Table~\ref{tab:instructions} lists the instructions that this
processor supports. The left column shows the name of an instruction and its operands.
The meaning of the syntax {\it rX} $\leftarrow$ {\it Op2} is that the second operand,
{\it Op2}, is loaded into register {\it rX}. The operand {\it Op2} can be either a
register, {\it rY}, or {\it immediate data}, \#{\it D}.

\begin{table}[H]
\begin{center}
\begin{tabular}{rl|c}
   \multicolumn{2}{c|}{Instruction} & Function performed \\ \hline
   \rule[0.01in]{0in}{0.15in}{\it mv} & {\it rX}, $Op2$ & {\it rX} $\leftarrow Op2$ \\
		  \rule[-0.075in]{0in}{0.2in}{\it mvt} & {\it rX,} \#{\it D} & {\it rX$_{15-8}$} $\leftarrow$ {\it D$_{15-8}$}\\
   \rule[-0.075in]{0in}{0.2in}{\it add} & {\it rX}, $Op2$ & {\it rX} $\leftarrow$ {\it rX} + $Op2$ \\
   \rule[-0.075in]{0in}{0.2in}{\it sub} & {\it rX}, $Op2$ & {\it rX} $\leftarrow$ {\it rX} $-$ $Op2$ \\
\end{tabular}
\caption{Instructions performed in the processor.}
\label{tab:instructions}
\end{center}
\end{table}

\noindent
Instructions are loaded from the external input {\it DIN}, and stored into the {\it IR} register,
using the connection indicated in Figure~\ref{fig:fig1}. Each instruction is {\it encoded} using
a 16-bit format. If $Op2$ specifies a register, then the instruction encoding is
\texttt{III0XXX000000YYY}, where \texttt{III} specifies the instruction, \texttt{XXX} gives
the {\it rX} register, and \texttt{YYY} gives the {\it rY} register. If $Op2$ specifies
immediate data \#{\it D}, then the encoding is
\texttt{III1XXXDDDDDDDDD}, where the 9-bit field \texttt{DDDDDDDDD} represents the constant data.
Although only two bits are needed to encode our four instructions, we are using three bits because
other instructions will be added to the processor later. Assume that \texttt{III} $= 000$ for
the {\it mv} instruction, $001$ for {\it mvt}, $010$ for {\it add}, and $011$ for {\it sub}.

~\\
The {\it mv} instruction ({\it move}) copies the contents of one register into
another, using the syntax \texttt{mv} \texttt{rX,rY}. It can also be used to initialize a
register with immediate data, as in \texttt{mv} \texttt{rX,\#D}.  Since the data {\it D}
is represented inside the encoded instruction using only nine bits, the processor has to
{\it zero-extend} the data, as in \texttt{0000000D$_{8-0}$}, before loading it into
register~{\it rX}.  The {\it mvt} instruction ({\it move top}) is used to initialize the
most-significant byte of a register.  For {\it mvt}, only eight bits of the {\it D} field in
the instruction are used, so that \texttt{mvt} \texttt{rX,\#D} loads the value
\texttt{D$_{15-8}$00000000} into {\it rX}. As an example, to load register $r0$ with the
value \texttt{0xFF00}, you would use the instruction \texttt{mvt r0,\#0xFF00}.  The instruction
\texttt{add} \texttt{rX,rY} produces the sum {\it rX} $+$ {\it rY} and loads the result
into {\it rX}. The instruction \texttt{add} \texttt{rX,\#D} produces the
sum {\it rX} $+$ {\it D}, where {\it D} is zero-extended to 16 bits, and saves the result
in {\it rX}. Similarly, the {\it sub} instruction generates
either {\it rX} $-$ {\it rY}, or {\it rX} $-$ \#{\it D} and loads the result into {\it rX}.

~\\
Some instructions, such as an {\it add} or {\it sub}, take a few clock cycles to complete,
because multiple transfers have to be performed across the bus. The finite state machine in the
processor ``steps through'' such instructions, asserting the control signals needed in
successive clock cycles until the instruction has completed.  The processor starts executing
the instruction on the {\it DIN} input when the {\it Run} signal is asserted and the processor
asserts the {\it Done} output when the instruction is finished.  Table~\ref{tab:control_signals}
indicates the control signals from Figure~\ref{fig:fig1} that have to be
asserted in each time step to implement the instructions in Table~\ref{tab:instructions}.  The
only control signal asserted in time step $T_0$, for all instructions, is {\it IR}$_{in}$.
The meaning of {\it Select = rY} or {\it IR} in the table is that the multiplexer selects
either register {\it rY} or the immediate data in {\it IR}, depending on the value of $Op2$.
For the {\it mv} instruction, when {\it IR} is selected the multiplexer outputs
\texttt{0000000DDDDDDDDD}, and for {\it mvt} the multiplexer outputs \texttt{DDDDDDDD00000000}.
Only signals from Figure~\ref{fig:fig1} that have to be asserted in each time
step are listed in Table~\ref{tab:instructions}; all other signals are not asserted. The
meaning of {\it AddSub} in step $T_2$ of the {\it sub} instruction is that this signal is set
to 1, and this setting causes the adder/subtracter unit to perform subtraction using
2's-complement arithmetic.

~\\
The processor in Figure~\ref{fig:fig1} can perform various tasks by using a sequence of
instructions. For example, the sequence below loads the number 28 into register $r0$ and then
calculates, in register $r1$, the 2's complement value $-28$.

\begin{minipage}[t]{15 cm}
\begin{lstlisting}
       mv    r0, #28        // original number = 28
       mvt   r1, #0xFF00
       add   r1, #0x00FF    // r1 = 0xFFFF
       sub   r1, r0         // r1 = 1's-complement of r0
       add   r1, #1         // r1 = 2's-complement of r0 = -28
\end{lstlisting}
\end{minipage}

\begin{table}[H]
\begin{center}
\begin{tabular}{r|c|c|c|c|}
\multicolumn{1}{c}{~} & \multicolumn{1}{c}{$T_0$} & \multicolumn{1}{c}{$T_1$} & \multicolumn{1}{c}{$T_2$} & \multicolumn{1}{c}{$T_3$} \rule[-0.075in]{0in}{0.25in}\\ \cline{2-5}
{\it mv~} & {\it IR}$_{in}$ & \rule[-0.075in]{0in}{0.25in}{\it Select} = {\it rY} or {\it IR}, &  &  \\
~ & ~ & {\it rX$_{in}$}, {\it Done} &  &  \\ \cline{2-5}
{\it mvt~} & {\it IR}$_{in}$ & \rule[-0.075in]{0in}{0.25in}{\it Select} = {\it IR}, &  &  \\
~ & ~ & {\it rX$_{in}$}, {\it Done} &  &  \\ \cline{2-5}
\rule[-0.075in]{0in}{0.25in}{\it add~} & {\it IR}$_{in}$ & {\it Select} = {\it rX}, & {\it Select} = {\it rY} or {\it IR}, & {\it Select = G}, {\it rX$_{in}$}, \\
~ & ~ & {\it A$_{in}$} &  {\it G$_{in}$} & {\it Done} \\
\cline{2-5}
\rule[-0.075in]{0in}{0.25in}{\it sub~} & {\it IR}$_{in}$ & {\it Select} = {\it rX}, & {\it Select} = {\it rY} or {\it IR}, & {\it Select = G}, {\it rX$_{in}$}, \\
~ & ~ & {\it A$_{in}$} &  {\it AddSub}, {\it G$_{in}$} & {\it Done} \\
\cline{2-5}
\end{tabular}
\caption{Control signals asserted in each instruction/time step.}
\label{tab:control_signals}
\end{center}
\end{table}

\section*{Part I}
\addcontentsline{toc}{1}{Part I}
Implement the processor shown in Figure~\ref{fig:fig1} using Verilog code, as follows:
\begin{enumerate}
\item Make a new folder for this part of the exercise.
Part of the Verilog code for the processor is shown in parts $a$ to $c$ of
Figure~\ref{fig:fig2}, and a more complete version of the code is provided with this exercise,
in a file named {\it proc.v}. You can modify this code to suit your own coding style
if desired---the provided code is just a suggested solution. Fill in the missing parts of
the Verilog code to complete the design of the processor.

\lstset{language=Verilog,numbers=none,escapechar=|}
\begin{figure}[h]
\begin{center}
\begin{minipage}[t]{15 cm}
\begin{lstlisting}[name=proc]
|\label{line:module}|
module proc(DIN, Resetn, Clock, Run, Done);
    input [15:0] DIN;
    input Resetn, Clock, Run;
    output Done;

    parameter T0 = 2'b00, T1 = 2'b01, T2 = 2'b10, T3 = 2'b11;
    |$\ldots$| declare variables
    assign III = IR[15:13];
    assign IMM = IR[12];
    assign rX = IR[11:9];
    assign rY = IR[2:0];
    dec3to8 decX (IR[4:6], 1'b1, Xreg);

    // Control FSM state table
    always @(Tstep_Q, Run, Done)
        case (Tstep_Q)
            T0: // data is loaded into IR in this time step
				    if (~Run) Tstep_D = T0;
				    else Tstep_D = T1;
	 		   T1: |$\ldots$|
	 		   |$\ldots$|
		  endcase
\end{lstlisting}
\end{minipage}
\caption{Skeleton Verilog code for the processor. (Part $a$)}
\label{fig:fig2}
\end{center}
\end{figure}

\begin{center}
\begin{minipage}[t]{15 cm}
\begin{lstlisting}[name=proc]
    parameter mv = 3'b000, mvt = 3'b001, add = 3'b010, sub = 3'b011;
    // selectors for the BusWires multiplexer
    parameter Sel_R0 = 4'b0000, Sel_R1 = 4'b0001, |$\ldots$|, Sel_R7 = 4'b0111,
        Sel_G = 4'b1000, Sel_D = 4'b1001, Sel_D8 = 4'b1010;

    // control FSM outputs
    always @(*) begin
        Done = 1'b0; Ain = 1'b0; |$\ldots$| // default values for variables
        case (Tstep_Q)
            T0: // store DIN into IR
                IRin = 1'b1;
            T1: // define signals in time step T1
                case (III)
                    mv: begin
                        if (!IMM) Sel = rY;     // mv rX, rY
                        else Sel = Sel_D;       // mv rX, #D
                        Rin = Xreg;
                        Done = 1'b1;
                    end
                    mvt: // mvt rX, #D
                    |$\ldots$|
                endcase
            T2: // define signals in time step T2
                case (III)
                    |$\ldots$|
                endcase
            T3: // define signals in time step T3
                case (III)
                    |$\ldots$|
                endcase
            default: ;
        endcase
    end

    // Control FSM flip-flops
    always @(posedge Clock, negedge Resetn)
        if (!Resetn)
            |$\ldots$|

    regn reg_0 (BusWires, Rin[0], Clock, R0);
    regn reg_1 (BusWires, Rin[0], Clock, R1);
    |$\ldots$|
    regn reg_7 (BusWires, Rin[0], Clock, R7);
    |$\ldots$| instantiate other registers |and| the adder/subtracter unit
\end{lstlisting}
\end{minipage}
\end{center}

\begin{center}
Figure 2: Skeleton Verilog code for the processor. (Part $b$)
\end{center}

\begin{center}
\begin{minipage}[t]{15 cm}
\begin{lstlisting}[name=proc]
    // define the internal processor bus
    always @(*)
        case (Sel)
            Sel_R0: BusWires = R0;
            Sel_R1: BusWires = R1;
            |$\ldots$|
            Sel_G: BusWires = G;
            Sel_D: BusWires = |$\ldots$|;    // used for mv, add, ..., with #D
            Sel_D8: BusWires = |$\ldots$|;   // used for mvt
            default: BusWires = 16'bxxxxxxxxxxxxxxxx;
        endcase
endmodule

module dec3to8(W, Y);
    input [2:0] W;
    output [0:7] Y;
    reg [0:7] Y;

    always @(*)
        case (W)
            3'b000: Y = 8'b10000000;
            3'b001: Y = 8'b01000000;
            3'b010: Y = 8'b00100000;
            3'b011: Y = 8'b00010000;
            3'b100: Y = 8'b00001000;
            3'b101: Y = 8'b00000100;
            3'b110: Y = 8'b00000010;
            3'b111: Y = 8'b00000001;
        endcase
endmodule
\end{lstlisting}
\end{minipage}
\end{center}

\begin{center}
Figure 2: Skeleton Verilog code for the processor. (Part $c$)
\end{center}

~\\
\item Set up the required subfolder and files so that your Verilog code can be compiled and
simulated using the ModelSim Simulator to verify that your processor works properly.
An example result produced by using {\it ModelSim} for a correctly-designed circuit
is given in Figure~\ref{fig:fig3}.  It shows the value \texttt{0x101C} being loaded into {\it IR}
from {\it DIN} at time 30 ns. This pattern represents the instruction \texttt{mv r0,\#28},
where the immediate value $D = 28$ (\texttt{0x1C}) is loaded into $r0$ on the clock edge at 50 ns.
The simulation results then show the instruction \texttt{mvt~r1,\#0xFF00} at 70 ns,
\texttt{add r0,\#0xFF} at 110 ns, and \texttt{sub r1,r0} at 190 ns.

You should perform a thorough simulation of your processor with the ModelSim simulator. A
sample Verilog testbench file, {\it testbench.v}, execution script, {\it testbench.tcl},
and waveform file, {\it wave.do} are provided along with this exercise.
\end{enumerate}
\begin{figure}[H]
	\begin{center}
		\includegraphics[scale=1.0]{figures/figure3.png}
	\end{center}
	\caption{Simulation results for the processor.}
	\label{fig:fig3}
\end{figure}
\section*{Part II}
\addcontentsline{toc}{2}{Part II}
In this part we will implement the circuit depicted in Figure~\ref{fig:fig4}, in which a
memory module and counter are connected to the processor. The
counter is used to read the contents of successive locations in the memory, and
this data is provided to the processor as a stream of instructions. To simplify the
design and testing of this circuit we have used separate clock signals, {\it PClock}
and {\it MClock}, for the processor and memory. Do the following:

\begin{enumerate}
\item A Quartus project file is provided along with this part of the exercise.  Use the
Quartus software to open this project, which is called {\it part2.qpf}.
\item A sample top-level Verilog file that instantiates the processor, memory module, and
counter is shown in Figure~\ref{fig:procmem}. This code is provided in a file named
{\it part2.v}; it is the top-level file for the Quartus project {\it part2.qpf}. The
code instantiates a memory module called {\it inst\_mem}. You have to create a Verilog file
that represents this memory module by using the Quartus software, as described below.

~\\
\begin{figure}[H]
	\begin{center}
		\includegraphics[]{figures/figure4.pdf}
	\end{center}
	\caption{Connecting the processor to a memory module and counter.}
	\label{fig:fig4}
\end{figure}
\newpage
\lstset{language=Verilog,numbers=none,escapechar=|}
\begin{figure}[h]
\begin{center}
\begin{minipage}[t]{12.5 cm}
\begin{lstlisting}[name=proc]
|\label{line:module}|
module part2 (KEY, SW, LEDR);
    input [1:0] KEY;
    input [9:0] SW;
    output [9:0] LEDR;

    wire Done, Resetn, PClock, MClock, Run;
    wire [15:0] DIN;
    wire [4:0] pc;

    assign Resetn = SW[0];
    assign MClock = KEY[0];
    assign PClock = KEY[1];
    assign Run = SW[9];

    proc U1 (DIN, Resetn, PClock, Run, Done);
    assign LEDR[9] = Done;

    inst_mem U2 (pc, MClock, DIN);
    count5 U3 (Resetn, MClock, pc);
endmodule

module count5 (Resetn, Clock, Q);
    input Resetn, Clock;
    output reg [4:0] Q;

    always @ (posedge Clock, negedge Resetn)
        if (Resetn == 0)
            Q <= 5'b00000;
        else
            Q <= Q + 1'b1;
endmodule
\end{lstlisting}
\end{minipage}
\caption{Verilog code for the top-level module.}
\label{fig:procmem}
\end{center}
\end{figure}

\item
A diagram of the memory module that you need to create is depicted in Figure~\ref{fig:fig_ROM}.
Since this memory module has only a read port, and no write port, it is called a {\it synchronous
read-only memory (synchronous ROM)}. Note that the memory module includes a register for
synchronously loading addresses. This register is required due to the design of the memory
resources in the Intel FPGA chip.

Use the Quartus IP Catalog tool to create the memory module, by clicking on
{\sf Tools} $>$ {\sf IP Catalog} in the Quartus software. In the IP Catalog window
choose the {\it ROM:~1-PORT} module,
which is found under the {\sf Basic Functions $>$  On Chip Memory} category.
Select {\sf Verilog HDL} as the type of output file to create, and give the file the name
{\it inst\_mem.v}.

Follow through the provided dialogue to create a memory that has one 16-bit
wide read data port and is 32 words deep. Figures~\ref{fig:fig5} and ~\ref{fig:fig6} show the
relevant pages and how to properly configure the memory.

\begin{figure}[t]
	\begin{center}
		\includegraphics[]{figures/figure_ROM.pdf}
	\end{center}
	\caption{The 32 {\sf x} 16 ROM with address register.}
	\label{fig:fig_ROM}
\end{figure}

\begin{figure}[H]
	\begin{center}
		\includegraphics[scale=1.0]{figures/figure5.png}
	\end{center}
	\caption{{Specifying memory size.}}
	\label{fig:fig5}
\end{figure}

To place processor instructions into the memory, you need to specify {\it initial values}
that should be stored in the memory when your circuit is programmed into the FPGA chip.
This can be done by initializing the memory using the contents of a {\it memory initialization
file (MIF)}. The appropriate screen is illustrated in Figure~\ref{fig:fig7}. We have specified
a file named {\it inst\_mem.mif}, which then has to be created in the folder that
contains the Quartus project. Clicking \texttt{Next} two more times will advance to the
\texttt{Summary} screen, which lists the names of files that will be created for the memory IP.
You should select {\it only} the Verilog file {\it inst\_mem.v}. Make sure that none of the
other types of files are selected, and then click \texttt{Finish}.

An example of a memory initialization file is given in
Figure~\ref{fig:fig_MIF}. Note that comments (\% $\ldots$ \%) are included in this file as a way of
documenting the meaning of the provided instructions.  Set the contents of
your {\it MIF} file such that it provides enough processor instructions to test your circuit.

\item The code in Figure~\ref{fig:procmem}, and the Quartus project, includes the necessary
port names and pin location assignments to implement the circuit on a DE-series board.
The switch {\it SW}$_{9}$ drives the processor's {\it Run} input, {\it SW}$_0$ is
connected to {\it Resetn}, {\it KEY}$_0$ to {\it MClock}, and {\it KEY}$_1$ to {\it PClock}.
The Run signal is displayed on {\it LEDR}$_{0}$ and {\it Done} is connected to {\it LEDR}$_{9}$.
\begin{figure}[H]
	\begin{center}
		\includegraphics[scale=1.0]{figures/figure6.png}
	\end{center}
	\caption{Specifying which memory ports are registered.}
	\label{fig:fig6}
\end{figure}

\begin{figure}[H]
	\begin{center}
		\includegraphics[scale=1.0]{figures/figure7.png}
	\end{center}
	\caption{Specifying a memory initialization file (MIF).}
	\label{fig:fig7}
\end{figure}

\item Use the ModelSim Simulator to test your Verilog code. Ensure
that instructions are read properly out of the ROM and executed by the processor. An example
of simulation results produced using ModelSim with the MIF file from
Figure~\ref{fig:fig_MIF} is shown in Figure~\ref{fig:fig_sim2}. The corresponding ModelSim
setup files are provided along with this exercise.
\item Once your simulations show a properly-working circuit, you may wish to download
it into a DE-series board. The functionality of the circuit on the board can be tested by
toggling the switches and observing the LEDs. Since the circuit's clock inputs are controlled
by pushbutton switches, it is possible to step through the execution of instructions and
observe the behavior of the circuit.
\end{enumerate}

\begin{figure}[H]
\begin{center}
\begin{minipage}[t]{12.5 cm}
\begin{tabbing}
{\bf DEPTH} = 32;\\
{\bf WIDTH} = 16;\\
{\bf ADDRESS\_RADIX} = HEX;\\
{\bf DATA\_RADIX} = BIN;\\
{\bf CONTENT}\\
{\bf BEGIN}\\
00	:	0001000000011100;~~~~~~\=\%~~mv  \=r0, \#0xFF00~~\=\% \kill
00	:	0001000000011100;	\>\% mv \>r0, \#28\>\%\\
01	:	0011001011111111; \>\% mvt \>r1, \#0xFF00\>\%\\
02	:	0101001011111111;	\>\% add  \>r1, \#0xFF\>\%\\
03	:	0110001000000000;	\>\% sub  \>r1, r0\>\%\\
04	:	0101001000000001;	\>\% add  \>r1, \#1\>\%\\
05	:	0000000000000000;\\
$\ldots$ (some lines not shown)\\
1F :	0000000000000000;\\
{\bf END};
\end{tabbing}
\end{minipage}
\end{center}
\caption{An example memory initialization file (MIF).}
\label{fig:fig_MIF}
\end{figure}

\begin{figure}[H]
	\begin{center}
		\includegraphics[scale=1.0]{figures/figure8.png}
	\end{center}
	\caption{An example simulation output using the MIF in Figure~\ref{fig:fig_MIF}.}
	\label{fig:fig_sim2}
\end{figure}

\section*{Enhanced Processor}
\addcontentsline{toc}{3}{Enhanced Processor}
It is possible to enhance the capability of the processor so that the counter in
Figure~\ref{fig:fig4} is no longer needed, and so that the processor has the ability to
perform read and write operations using memory or other devices. These enhancements involve
adding new instructions to the processor, as well as other capabilities---they are
discussed in the next lab exercise.

\end{document}