The following sections give a brief outline of the theoretical knowledge used to perform this research. 

\section{Existing simulation solutions}
This project is not the first in the field of architecture simulation, and, as such, similar solutions have been devised in order to satisfy the need for a system architecture environment. The following are a few of these existing packages, their aims and a comparisons of these aims and the aims of this research. 

\subsection{ArchC}
While not necessarily a simulation framework on its own, ArchC calls itself an Architecture Description Language (ADL) which intends to formulate a language, based on generic SystemC, which can be used to implement system architectures \citep{rigo2004archc}. 

\subsection{PTLsim}
A project more akin to the simulator envisioned bu this project is PTLsim \citep{yourst2007ptlsim}. PTLsim is a cycle accurate simulator with a specific focus on the x86 systemtam architecture. 

\subsection{gem5}
When compared to the former simulation solution, gem5 is a more general purpose simulation framework \citep{binkert2011gem5}. As opposed to only allowing simulation of the x86 architecture, gem5 allows the execution practically any architecture design.

With particular interest to this research is the fact that work has been done incorporating the functionality of SystemC-based architectures in the gem5 framework \citep{menard2017system}.

\subsection{SIM-PL}
A project which close to this project in terms of functionality 

\section{Simulation models}
Since this research's main focus is on simulating system architectures, it is important to identify various methods of simulation. As is true for many thing, simulation can be done in numerous ways, and each method can be seen as more or less applicable in certain specific use cases. 

\subsection{Continuous-time simulation} \label{sec:cts}
The first simulation technique covered in this theoretical introduction is known as continuous simulation. This technique makes use of continuous models in order to simulate a given system. Such a continuous model is usually formulated using using (a series of) differential equations.

[vultekst om twee stukken aan elkaar te knopen]

While not used to simulate the specific functioning of computing hardware, continuous models can still play a role in contemporary research. Using a model based on mathematical equations, certain characteristics of a given hardware component can be examined. For example, \cite{berg2006statistical} describes a method of predicting caching behaviour of a program, in particular data locality in the context of multi-threaded applications, based on a mathematical model. A given application is executed and during this execution certain architecture-independent data is collected. Following the execution, this collected data is fed into a series of equations, each of which aims to predict certain metrics. Another metric which can be modelled using continuous simulation is the power consumption of a given architecture \citep{kohl2016systemc}.

From these two examples, it becomes apparent that in the context of digital system components and system architectures, a continuous model does not satisfy the need for accurate functional simulation. 

For the purposes of simulating the functionality of system architectures as performed in this research, continuous simulation and continuous models have been deemed impractical, and inappropriate to the particular needs of the simulator. As will be discussed in the following subsection (\ref{sec:dts}), there exists a more suitable simulation technique with respects to the functional simulation of digital system architectures.

\subsection{Discrete-time simulation}\label{sec:dts}
Converse to the aforementioned continuous simulation there exists discrete simulation. Instead simulating a system with a theoretically infinite time resolution, the state of the system is simulated at discrete time intervals. A helpful analogy to illustrate the difference between these two simulation techniques might be that of the sampling of audio signals---technically any electronic signal. From a purely physical perspective sound is just a difference in pressure propagating through a gaseous medium. This phenomenon is continuous, as at any point in time the system has a certain state. When we want to record this sound however, the continuous nature poses a problem, as recording the signal with an infinite time resolution would require an infinite amount of storage. Instead, the signal is measured at a specific regular interval. From these sampled measured values, the original signal can be reconstructed. This deference between an original signal (red) and sampled values (blue) is illustrated in figure \ref{fig:cont-vs-disc}. 

\begin{figure}
    \centering
    \includegraphics[width=0.6\textwidth]{figures/temp_cont-vs-disc.png}
    \caption{[TEMPORARY FIGURE] Continuous signal versus sampled values}
    \label{fig:cont-vs-disc}
\end{figure}

\subsubsection{Discrete event modelling}
While discrete modelling can be done using equations, as was true for its continuous counterpart, discrete simulation can also be based on the occurrence of events and the relationship between these events. Such event-driven modelling lends itself particularly well to the simulations of systems where there is a clear action-reaction relation between actors. As will be further illustrated in section \ref{sec:sysarch}, this latter characteristic holds true for computer system architectures, where components react to a given stimulus and this reaction might in turn be the triggering stimulus for one or more other components. 

Choosing which events are allowed to be handled at a particular stage of the simulation depends of whether the simulation is either time driven or event driven. In the former case, handling of events takes place based on the the clock inside the simulation. Inside such a simulation, there is a global time and events are scheduled based on their starting time. 

An example of this technique \textbf{[EXAMPLE]}

In case of the event driven approach, events are handled as they are triggered by other events. There is no set regular time between each simulation step, instead, timing between stages is based on the duration of events and the order in which new events are triggered. 

this technique can be illustrated using a slightly tweaked version of the example of the former technique. \textbf{[EXAMPLE]}



% \subsubsection{Time-based modelling}
% The first technique for determining the simulation interval is time-based. This means that the simulation steps occur after a certain amount of time passes inside the simulation. 

% \subsubsection{Event-based modelling}
% The second 

% \subsection{TLM vs. RTL}


\section{SystemC}
Central to this research is the C++ class library SystemC \citep{ieee1666}. SystemC is a library aimed at allowing the user to implement hardware functionality on various different levels of abstraction. [mist nog spul] 

What makes SystemC especially suitable for this research is the way it allows for multiple levels of abstraction. On the one hand, using SystemC, an entire system architecture can be constructed by combining atomic logic gates who's individual implementation involves trivial bit operations. On the other side of the spectrum, SystemC allows for the implementation of a components complete functionality using C/C++ code, while still using SystemC as its interface to communicate with other components. 

With the use of the example module in listing \ref{lst:sysc-exm}, the sections below will illustrate the basic principles and functionality of SystemC.

\lstinputlisting[language=C++, label={lst:sysc-exm}, caption={SystemC example module}]{listing/sysc-exm.cpp}
% \begin{lstlisting}[language=C++, caption={SystemC example module}, label=1]
% SC_MODULE(example)
% {
%     sc_in<bool> clock{ "CLOCK" }, poll{ "POLL" };
%     sc_out<sc_uint<20>> out{ "VALUE" };
    
%     and_g and1{ "AND1" };
%     not_g not1{ "NOT1" };
    
%     sc_signal sig{ "SIG" };
    
%     void handle_poll()
%     {
%         out.write(1337);
%     }
    
%     void handle_clock()
%     {
%         while (true)
%         {
%             out.write(5318008);
%             wait();
%         }
%     }
    
%     SC_CTOR(example)
%     {
%         SC_METHOD(handle_poll)
%         sensitive << poll;
        
%         SC_THREAD(handle_clock)
%         sensitive << clock.pos();
        
%         and1.out(sig);
%         not1.in(sig);
%     }
% };
% \end{lstlisting}

\subsection{SystemC components and constructs}
\subsubsection{Data types}
Apart from the new classes it introduces, SystemC also comes with some data types which are useful in a hardware design context.  

\texttt{sc\_int<w>} and \texttt{sc\_uint<w>} are the respective signed and unsigned fixed width integer types in SystemC. Using the template variable \texttt{w}, the amount of bits used to represent the value of the integer in question can be specified. These data types ensure the correct bit width independent on the architecture it is compiled on, as opposed to C/C++ built-in types like \texttt{int}. The only limitation of these types is the fact that they are limited to a width of 64 bits. In order to use integer values with arbitrary bit width, \texttt{sc\_bigint<w>} and \texttt{sc\_biguint<w>} can be used as the respective counterparts of the aforementioned types.

In order to steam line the passing of and the operations on groupings of individual bits, SystemC includes a so called bit vector in the form of \texttt{sc\_bv<n>}. With this vector comprising of \texttt{n} bits, each individual bit can be addressed and manipulated. This eliminates the need to perform bit masks on existing data types like \texttt{int} and allows for the formation of more flexible amounts of bits---other than the usual 8, 32 and 64 bits.

When dealing with true hardware signals, value analogies using only two values---i.e. 'true' or 'false' or 1 and 0---actually don't suffice. In the real world, the values of a signal are characterised using one of the following possible categories: false (0), true (1), intermediate value (X) and floating value (Z). These possible values can be encoded in SystemC using the \texttt{sc\_logic} data type. Several logic values can be combined using the \texttt{sc\_lv<w>} type. 

\subsubsection{Modules}
The fundamental building block of any SystemC-described hardware component is the module. Modules are packets containing the internal structure of a given component and its functionality. Listing \ref{lst:sysc-exm} shows the definition of a new module called \texttt{example} (line 1-35) and the instantiation of 2 e existing modules \texttt{and\_g} and \texttt{not\_g} in lines 5 and 6 respectively.

\subsubsection{Ports}
In order to facilitate in- and outbound communication from withing modules, SystemC offers so called ports. The three basic types of ports \texttt{sc\_in<T>}, \texttt{sc\_out<T>} and \texttt{sc\_inout<T>} handle inbound, outbound and a combination of the two respectively. Each port has to specify the type of data which is transported by way of this port using the template variable \texttt{T}. In the example in listing \ref{lst:sysc-exm}, the ports of the module are declared in lines 3 and 4. In this case, there are two input ports of type \texttt{bool} and one output port of type \texttt{sc\_uint<20>}. Processes can read from a port using the \texttt{read()} method and write to a port using the \texttt{write([value])} method. 

\subsubsection{Signals}
The aforementioned modules with their respective ports exist on their own, but somehow need to be connected. To establish this connection the supplied type \texttt{sc\_signal<T>} can be used. As with the ports, for each signal the desired data type which is to be transported along the signal is specified using template variable \texttt{T}. In the example in listing \ref{lst:sysc-exm} a new signal is declared in line 8 and the signal is connected between the output of the and gate in line 32 and the input port of the not gate in line 33.

\subsection{Processes}
Having described the structural components of a SystemC hardware design, the following outlines the way in which functionality of components can be implemented in SystemC. As described in the introduction of this section, functionality of SystemC can be constructed on various levels of abstraction. The functional implementation of a component like a half-adder can be done by combining logic gates inside a overarching module, or bu implementing the addition logic inside the half-adder module using C/C++ code. The latter of these techniques and also the functionality of the logic gates used in the former technique both rely on the use of processes inside a SystemC module.

\subsubsection{Methods and threads}
Processes inside a SystemC module come in two main distinct varieties, namely methods and threads. 

\subsubsection{Simulation scheduling}


\subsection{Constructing hierarchy}
SystemC allows for the embedding of components according to a desired hierarchy. This allows for the construction of more basic types, which in turn can be combined to form more complex structures. In principle, this means that based on mere atomic logic gates (e.g. AND, OR, NOT and XOR), or even single transistors, a whole system architecture can be implemented. A rudimentary example of this process is given in listing \ref{lst:sysc-exm}, where through the combination of an AND gate and a NOT gate inside the the \texttt{example} module using a signal, a new NAND gate is constructed. 

\section{System architectures}\label{sec:sysarch}
\subsection{Architecture properties}

\subsection{Common system architectures}



\section{Used libraries}

\section{VHDL}
\cite{cote2002automated}
\cite{chen2011synthesizable}

\subsection{Hardware description language}


\subsection{VHDL ---}


\subsection{SystemC to VHDL conversion}


\subsubsection{Constraints to SystemC}

\section{Ethical implications}