OpenCores
URL https://opencores.org/ocsvn/marca/marca/trunk

Subversion Repositories marca

[/] [marca/] [trunk/] [doc/] [implementation.tex] - Rev 9

Go to most recent revision | Compare with Previous | Blame | View Log

\documentclass[10pt, twoside, a4paper]{article}
\usepackage{graphicx}
\usepackage{listings}
 
\title{marca - McAdam's RISC Computer Architecture\\Implementation Details}
\author{Wolfgang Puffitsch}
 
\begin{document}
 
  \maketitle
 
  \section{General}
 
  \begin{itemize}
  \item 16 16-bit registers
  \item 16KB instruction ROM (8192 instructions)
  \item 8KB data RAM
  \item 256 byte data ROM
  \item 75 instructions
  \item 16 interrupt vectors
  \end{itemize}
 
  \section{Internals}
 
  The processor features a 4-stage pipeline:
  \begin{itemize}
  \item instruction fetch
  \item instruction decode
  \item execution/memory access
  \item write back
  \end{itemize}
  This scheme is similar to the one used in the MIPS architecture,
  only execution and write back stage are drawn together. For our
  architecture does not support indexed addressing, it does not need
  the ALU's result and can work in parallel, having the advantage of
  reducing the possible hazards.
 
  Figure \ref{fig:marca} shows a rough scheme of the internals of the
  processor.
  \begin{figure}[ht!]
    \centering
    \includegraphics[width=.95\textwidth]{marca}
    \caption{Internal scheme}
    \label{fig:marca}
  \end{figure}
 
  \subsection{Branches}
  Branches are not predicted and if executed they stall the the
  pipeline, leading to a total execution time of 4 cycles. The fetch
  stage is not stalled, the decode stage however is stalled for two
  cycles to compensate that.
 
  \subsection{Instruction fetch}
  This stage is not spectacular: it simply reads an instruction from
  the instruction ROM, and extracts the bits for the source and
  destination registers.
 
  \subsection{Instruction decode}
  This stage translates the bit-patterns of the opcodes to the signals
  used internally for the operations. It also holds the register file
  and handles access to it. Immediate values are also constructed here.
 
  \subsection{Execution / Memory access}
  The execution stage is the heart and soul of the processor: it holds
  the ALU, the memory/IO unit and a unit for interrupt handling.
 
  \subsubsection{ALU}
  The ALU does all arithmetic and logic computations as well as taking
  care of the processors flags (which are organized as seen in table
  \ref{tab:flags}).
 
  \begin{table}[ht!]
    \centering
    \begin{tabular}{|p{.75em}|p{.75em}|p{.75em}|p{.75em}
                    |p{.75em}|p{.75em}|p{.75em}|p{.75em}
		    |p{.75em}|p{.75em}|p{.75em}|p{.75em}
		    |p{.75em}|p{.75em}|p{.75em}|p{.75em}|p{.75em}}
      \multicolumn{16}{c}{Bit 15 \hfill Bit 0} \\
      \hline
      & & & & & & & & & & P & I & N & V & C & Z \\
      \hline
    \end{tabular}
    \caption{The flag register}
    \label{tab:flags}
  \end{table}
 
  Operations which need more than one cycle to execute (multiplication,
  division and modulo) block the rest of the processor until they are
  finished.
 
  \subsubsection{Memory/IO unit}
  The memory/IO unit takes care of the ordinary data memory, the data
  ROM (which is mapped to the addresses right above the RAM) and the
  communication to peripheral modules. Peripheral modules are located
  within the memory/IO unit and mapped to the highest addresses.
 
  The memories (the instruction ROM too) are Altera specific; we
  decided not to use generic memories, because \textsl{Quartus} can update the
  contents of its proprietary ROMs without synthesizing the whole
  design. Because all memories are single-ported (and thus fairly
  simple) it should be easy to replace them with memories specific to
  other vendors.
 
  We also decided against the use of external memories; larger FPGAs
  can accommodate all addressable memory on-chip, so the implementation
  overhead would not have paid off.
 
  Accesses which take more than one cycle (stores to peripheral
  modules and all load operations) block the rest of the processor
  until they are finished.
 
  \paragraph{Peripheral modules}
  The peripheral modules use a slightly modified version of the SimpCon
  interface. The SimpCon specific signals are pulled together to
  records, and the words which can be read/written are limited to 16
  bits. For accessing such a module, one may only use \texttt{load}
  and \texttt{store} instructions which point to aligned addresses.
 
  \paragraph{UART}
  The built-in UART is derived from the sc\_uart from Martin
  Sch\"oberl.  Apart from adapting the SimpCon interface, an interrupt
  line and two bits for enabling/masking receive (bit 3 in the status
  register) and transmit (bit 2) interrupts. In the current version
  address 0xFFF8 (-8) correspond to the UART's status register and
  address 0xFFFA (-6) to the wr\_data/rd\_data register.
 
  \subsubsection{Interrupt unit}
  The interrupt unit takes care of the interrupt vectors and, of
  course, the triggering of interrupts. Interrupts are executed only
  if the global interrupt flag is set, none of the other units is busy
  and the instruction in the execution stage is valid (it takes 3
  cycles after jumps, branches etc. until a new valid instruction is
  in that stage).
 
  Instructions which cannot be decoded as well as the ``error''
  instruction trigger interrupt 0; the ALU can trigger interrupt 1
  (division by zero), the memory unit can trigger interrupt 2 (invalid
  memory access). In contrast to all other interrupts, these three
  interrupts do not repeat the instruction which is executed when they
  occur.
 
  \subsection{Write back}
  The write back stage passes on the result of the execution stage to
  all other stages.
 
  \section{Assembler}
  The assembler \textsl{spar} (SPear Assembler Recycled) uses a syntax
  quite like usual Unix-style assemblers. It accepts the pseudo-ops
  \texttt{.file}, \texttt{.text}, \texttt{.data}, \texttt{.bss},
  \texttt{.align}, \texttt{.comm}, \texttt{.lcomm}, \texttt{.org} and
  \texttt{.skip} with the usual meanings. The mnemonic \texttt{data}
  initializes a byte to some constant value. In difference to the
  instruction set architecture specification, \texttt{mod} and
  \texttt{umod} accept three operands (if a move is needed, it is
  silently inserted).
 
  The assembler produces three files: one file for the instruction
  ROM, one file for the even bytes of the data ROM and one file for
  the odd bytes of the instruction ROM. The splitting of the data is
  necessary, because the data memories internally are split into two
  8-bit memories in order to support unaligned memory accesses without
  delays.
 
  Three output formats are supported: .mif (Memory Initialization
  Format), .hex (Intel Hex Format) and a binary format designed for
  download via UART.
 
  \section{Resource usage and speed}
 
  The processor was synthesized with \textsl{Quartus II} for the
  \textsl{Cyclone EP1C12Q240C8} FPGA with 12060 logic cells and 29952
  bytes of on-chip memory available.
 
  The processor needs $\sim$3550 logic cells or 29\% when being
  compiled for maximum clock frequency, which is $\sim$60 MHz. When
  optimizing for area, it needs $\sim$2600 logic cells or 22\% at
  $\sim$25 MHz.
 
  The processor uses 24832 bytes or 83\% of on-chip memory.
 
  \section{Example}
 
  \subsection{Reversing a line}
 
  In listing \ref{lst:uart} one can see how to interface the uart via
  interrupts. The program reads in a line from the UART and the writes
  it back reversed. The lines 1 to 4 show how to instantiate memory
  (the two bytes defined form the DOS-style end-of-line). The
  lines 7 to 25 initialize the registers and register the interrupt
  vectors, line 28 builds a barrier against the rest of the code.
 
  The lines 32 to 76 form the interrupt service routine. It first
  checks if it is operating in read or in write mode. When reading, it
  reads from the UART and stores the result. A mode switch occurs when
  a newline character is encountered. In write mode the contents of
  the buffer is written to the UART and switching back to read mode is
  done when finished.
 
  In figure \ref{fig:sim} the results of the simulation are presented.
 
  \lstset{basicstyle=\footnotesize,numbers=left,numberstyle=\tiny}
  \lstset{caption=Example for the UART and interrupts}
  \lstset{label=lst:uart}
  \lstinputlisting{uart_reverse.s}
 
  \begin{figure}[ht!]
    \centering
    \includegraphics[width=.95\textwidth]{uart_sim}
    \caption{Simulation results}
    \label{fig:sim}    
  \end{figure}
 
  \subsection{Computing factorials}
 
  The example in \ref{lst:fact} computes the factorials of 1 \ldots 9
  and writes the results to the PC via UART. Note that the last result
  transmitted will be wrong, because it is truncated to 16 bits.
 
  \lstset{basicstyle=\footnotesize,numbers=left,numberstyle=\tiny}
  \lstset{caption=Computing factorials}
  \lstset{label=lst:fact}
  \lstinputlisting{factorial.s}
 
 
  \section{Versions Of This Document}
 
  2006-12-14: Draft version \textbf{0.1}
 
  \noindent
  2006-12-29: Draft version \textbf{0.2}
  \begin{itemize}
    \item A few refinements.
  \end{itemize}
 
  \noindent
  2007-01-22: Draft version \textbf{0.3}
  \begin{itemize}
    \item Added another example.
  \end{itemize}
 
  \noindent
  2007-02-02: Draft version \textbf{0.4}
  \begin{itemize}
    \item Updated resource usage and speed section.
  \end{itemize}
 
\end{document}
 

Go to most recent revision | Compare with Previous | Blame | View Log

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.