\chapter{About the \index{FC0}FC0 core}

 Here, we speak about characteristics that are specific to the FC0 ("F-CPU Core \#0"), 
and even though they influence the general definition of the F-CPU, they may be abandonned 
in the future. This is where the hardware engineer is getting more involved.
 
\section{The FC0 is \index{superpipelined}superpipelined}

 When designing a microprocessor, one of the first question is "what is the 
granularity of the pipeline ?". This is not a critical issue for "toy processors" or designs 
that are adapted from existing processors, but the F1 is not a toy and it must be very 
performant since the first prototype... For the F1 case, where the first prototype will 
probably be a FPGA or a sea-of-gates ASIC but not a full-custon chip, performance matters more
because the process will not be able to compete with existing chips. Performance always matters
anyway, but in our case there is a strong technological handicap. We need a technique that
reaches the same "speed" with slower technology.

 So the equation is : \textit{speed} = \textit{silicon technology} x \textit{critical datapath
length}, or \textit{speed} = \textit{speed of one transistor} x \textit{number of transistors},
so with slow transistors the
only way to run fast is to reduce the critical datapath (as an approximative estimation,
because other parameters, such as capacitance and wire lengths influence this). So now,
what is the minimal operation we can perform without overloading the chip with flip-flops ?

~

 The depth of around ten transistors is a compromise between functionality and atomicity. 
We can create circuits that have around six logical gates of depth or add eight-bit numbers.
On top of that, the maximum number of input per gate is set to 4, so it can be easily mapped
to existing libraries and FPGA architectures.
Care is taken to have simple and fast "building blocks", but the good side is that with 6 logic
gates we can't make complex things, while longer datapaths usually give birth to complex
problems. With this "limitation" in mind, we also limit complexity and only
neighbour-to-neighbour connexions between units are possible. Furthermore,
as soon as a unit becomes too complex, it becomes either "parallelized" (a
large lookup table can be used for example) or "serialized" (in another word,
pipelined) so there is no need to slow down the processor or use asynchronous technology.

~

 The net effect of this bias toward extremely fine grained logic and pipeline stages is that 
even an addition becomes "slow" because it needs more  cycles than usual. This apparent 
slowness is balanced by higher performance through overlapping of the operations (pipelining)
but requires the use of coding techniques usually found in superscalar processors (pointer 
duplication, loop unrolling and interleaving etc.). Because the stages are shorter, there are 
more pipeline stages than usual, that's why the FC0 can be considered as superpipelined. But it
is only one aspect of the project and today, several processors are also superpipelined.
 
\section{The FC0 implements an \index{Out Of Order Completion}\index{OOO}\textit{Out Of Order Completion} pipeline}

 It is a simple solution if we want to get more performance from a single-issue 
pipeline. This is NOT a superscalar or out-of-order execution (or OOO instruction \textit{issue})
scheme but the "adaptation" of a simple pipelined CPU where instructions are \textit{issued
in order}.

 The fundamental reason behind this choice is that not all instructions really take the same 
time to complete. This fact becomes more important in the F-CPU because it is superpipelined, 
and one short instruction will be penalized by longer instructions which would lengthen the 
pipeline. For example, if we want to calibrate the pipeline length on a 64-bit addition, then 
longer operations like division, multiplication or memory access with cache miss will freeze 
the whole pipeline ; on the other side, simple register-to-register moves or simply writing an 
immediate value to a register will be much slower than actually needed. This can be done on an 
early MIPS processor but not on a superpipelined processor.

 Let's look at the instructions that need to be completed, after the decoding stage :

\begin{center}
\begin{tabular}{|c|c|c|c|c|}
 \hline
  approximative cycles  &    1           &  2          &   3            &      4        \\
 \hline
 write imm to reg       &  write dest    &             &                &               \\
 \hline
 load from memory       &  read address  & access data: undetermined    &  write dest &  \\
 \hline
 write to memory        &  read address  & data access data             &  &             \\
 \hline
 logic operation        & read operands  & operation   & write result   &                \\
 \hline
 arithmetic op          & read operands  & operation1  & operation2     &   write result \\
 \hline   
 move reg to reg        & read source    &  write dest &                &                 \\
 \hline
\end{tabular}
\end{center}

 We can also notice that successive instructions may be independent, not needing the result 
of the precedent instructions. The last remark is that they don't all need the same hardware.
We can come to some conclusions : not all instructions need to read and write registers or
compute something, not all instructions complete at the same speed, and some instructions
may be much longer than others (for example, reading a memory location with a cache miss,
compared to a simple logic operation). We need a variable sized pipeline that allows several
instructions to be performed and finish at the same time. One way to envision this is to
consider the pipeline as "folded", or "forked" like in a superscalar processor. But this
all consists to three successive and optional things : reading operands, processing them
and writing the result.

\begin{itemize}
 \item  Reading the operands is not a problem since at most three registers can need 
        to be read in one cycle. this is limited by the instructions themselves,
 \item  Computing is fully pipelined and independent because specialized units process
        the data,
 \item  Writing the results is a bit more complex because several operations can complete 
        at the same time. A one cycle operation (logical operation for example) will complete 
        at the same time as a two cycle (arithmetic) operation that has been issued during the 
        preceding cycle.
\end{itemize}

~

 For this last reason, the register set has (at least) two write buses. 
The FC0 emits up to one instruction per cycle and several instructions can end at the
same time. In case more than two values must be written at the same time, the "oldest"
instruction (earliest issued) has priority.

This kind of processor core has the advantage that long operations don't slow down or block the
whole program if the result data are not needed before the slow operation is finished. For
example, a memory read can cause cache miss delays but this won't keep the other execution
units to do their job and write their result to the register set. Of course, this puts some
pressure on the compiler but not more than for other existing processors, and careful coding
has always paid anyway.

 The difference between OOO completion and OOO execution is that OOO execution CPUs can issue
the operations out of order and need a last unit called "completion unit" or "retire unit" that
validates the operations in the program order. This also requires "renamed" registers that hold
the temporary results before they are validated for good by the completion unit. All these
"features" can be avoided by the techniques described in this document and, unlike OOO execution
processors (like \index{PowerPC}PowerPC and \index{P6}P6 cores) the peak performance is not 
limited by the size of the completion unit's FIFO (or the "ReOrdering Buffer", ROB) but by the 
number of register ports.
 
\section{The FC0 uses a \index{scoreboard}scoreboard}
 
 It is the simplest way to handle the out-of-order nature of the core. The way it works is very
simple~: \textit{each register has a flag that is set when the result is currently being
computed, and the instructions are delayed until no flag is set for the registers it uses
for read and write}. This way, strict coherency is ensured and no operation can conflict
with another at the execution stage : verification of conflicts is done at only one point.

~

 These flags are not exactly like the "attribute" bits because they are not directly accessible
by the user but they have the same dynamic behaviour and are not saved or restored.
Because they don't occur often and are not critical for performance, write-after-write
situations are not examined by the scheduler. The simple rule of blocking an instruction
at the decode stage if at least one of the used (read or written) register is not ready is
strictly enforced. Of course, the Register 0 which is hardwired to 0 is the only exception
and does not block anything.

 The scoreboard interacts with the "Smooth Register Backup" mechanism to ensure coherency
between the switching tasks.

\section{The \index{crossbar}crossbar}
 The FC0 uses a crossbar between the register set and the execution units because :
\begin{itemize}
 \item  It is the easiest way to "fold" the pipeline,
 \item  It provides a "one fits all" register bypass bus that shortens the latency
   \textit{between} dependent instruction,
 \item  It reduces the number of register ports.
\end{itemize}

 Because of its role, the crossbar (or "Xbar" for short) is a central part of the FC0.
The register set is only written or read through this device which virtually provides it with
more than ten ports. It allows the execution units to communicate without the need to write and
read registers (in register bypass mode, when operations are dependent) it provides the
hardwired register 'zero' and the results are checked for zero with two additional ports.

 The Xbar extends the register set's read and write ports, making "vertical" buses (see
\underline{figure 2.1)}, and each vertical bus is connected to one of the input and output
ports of each execution unit with "horizontal" buses. It also performs some width formatting
(byte, word, etc) for the immediate values coming from the instruction decoder. Because of
the relatively high number of ports, the crossbar uses a lot of surface and transistors.
It requires a cycle of his own to let the data  flow through its whole length, and the goal of 
ten equivalent transistors is likely to be reached fast, because of both transistor count and
wire lengths. Therefore, accessing a register takes two cycles from the time the register number
has been decoded : one cycle for the register set and another for the Xbar. But when consecutive
instructions are dependent, the result that will be written to a register is present on the 
Xbar and can be used during the next cycle for the next operation ("register bypass").

 This can be summarized in the following drawing :

~

\begin{figure}[H]
  \begin{center}
    \includegraphics[width=9cm,draft=false]{latency.eps}
    \caption{The pipeline is folded around the Xbar}
  \end{center}
\end{figure}
