
\chapter {CCM Assembly}
\label{CHEN-Chapter6}

The programs written for the CCM are in the form of a list of binary 
bytes which are CCM instructions encoded by the programmer. This method
of programming is very tedious and error prone. All instruction encoding
formats had to be remembered in order to use them, and it is painful 
to look at and maintain this kind of programs. Therefore, a very simple 
assembly language, called {\bf CCM assembly} was created. With the CCM assembly,
the programmer needs only to remember the name of the CCM instructions.
This programming methodology still requires the programmer to think in 
terms of registers and individual instructions. This chapter will 
describe the CCM assembly and will give some examples.

\section{CCM Assembly}
\label{CHEN-section6.1}

In the CCM assembly, one instruction has two or three fields and occupies
one line; the fields are separated by blank spaces; and the comments can
be added after the last field of the instruction.
The names of the instructions, called {\bf mnemonics}, occupy the first
field in an instruction line. The subsequent fields are the operands of
the instruction.

In the syntax of CCM assembly, keywords are represented in upper case,
operands are represented in lower case, and they should be substituted
by actual operands when they are used.

There are four instructions in the CCM assembly, and their corresponding 
instructions are discussed in detail in section~\ref{CHEN-section5.3}. The syntax of them
is described as follows:
\begin{itemize}
\item 
   {\bf ENABLE/DISABLE}: The {\tt ENABLE/DISABLE} instructions are used 
   to enable/disable tri-state buffers in the CCM. The corresponding 
   CCM instruction is {\bf set tri-state buffers}.
   The syntax is as follows: \\
   \ccmasm{ENABLE control\_signal\_name}\\
   and \\ % \vspace{- \baselineskip} \\
   \ccmasm{DISABLE control\_signal\_name}\\
   where \texttt{control\_signal\_name} is one of {\tt ENADDRA}, 
   {\tt ENADDRB}, {\tt ENIFIFOA}, {\tt ENIFIFOD}, {\tt ENMEMAWR}, 
   {\tt ENMEMBRW}, {\tt ENILUA} and {\tt ENILUB} (see section~\ref{CHEN-section5.3.2}).
\item
   {\bf SET}: The {\tt SET} instructions are used to load the data into 
   registers and address units from their inputs. The corresponding 
   CCM instructions are {\bf set accumulator} and {\bf set registers}.
   The syntax is as follows: \\
   \ccmasm{SET register\_name, operand}\\
   where \texttt{register\_name} is one of {\tt ADDRA}, {\tt ADDRB},
   {\tt ADDRR}, {\tt WATER}, {\tt RIGHT}, {\tt INST}, {\tt ACCU}, 
   {\tt CONF}, {\tt PRPO}; the \texttt{operand} in the syntax is a binary
   number that will show up on {\it IBus}, the width of this number depends
   on the register of the instruction (see section~\ref{CHEN-section5.3.3}). 
\item 
   {\bf EXEC}: The {\tt EXEC} instruction is used to execute only one cube 
   operation. The corresponding CCM instruction is {\bf execute}. The syntax
   is as follows: \\
   \ccmasm{EXEC operand} \\
   where \texttt{operand} is a 30-bit-wide binary data that will show up
   on {\it IBus} when the instruction is executed (see section~\ref{CHEN-section5.3.4}). 

\item
   {\bf LOOP}: The {\tt LOOP} instruction is used to execute multiple cube
   operations continuously without fetching the input FIFO. The
   corresponding CCM instruction is {\it loop}. The syntax is as follows: \\
   \ccmasm{LOOP operand} \\
   where \texttt{operand} is a 30-bit-wide binary number that will show up
   on {\it IBus} when the instruction is executed (see section~\ref{CHEN-section5.3.5}). 
\end{itemize}

Two more efforts are made to make the CCM assembly program easy
to understand:
\begin{itemize}
\item The symbol slash ('-') can be inserted into binary number.
      The program that interprets the CCM assembly should ignore
      these slashes.
    
      \noindent
      \begin{example}
      ~\label{CHEN-Example6.1}
      \end{example}

      \noindent
 The functions of the following two instructions are identical.

      \nvs\ccmasm{set inst  000000000000100000000} \\
      \nvs\ccmasm{set inst  00-0-0-0-0000-0001-0000-0000} 

      It is obvious that the second instruction is easier to understand.

\item The unused bits at the end of a binary number can be omitted.
      The program that interprets the CCM assembly should fill these
      bits with 0's or 1's (only the omitted bits of the binary number, that 
      is the operand of ``{\tt set water}" instruction, will be filled with 1's,
      see the definition of {\it water} signal in section~\ref{CHEN-section3.4.1}). 

      \noindent
      \begin{example}
      ~\label{CHEN-Example6.2}
      \end{example}

      \noindent
       The functions of the following two instructions are identical.

      \nvs\ccmasm{set water 000011111111111} \\
          \ccmasm{set water 0000} 

      Both of these two instructions mean that only first 4 ITs are used;
      and it is obvious that the second instruction is easier to understand.

      \noindent
      \begin{example}
      ~\label{CHEN-Example6.3}
      \end{example}

      \noindent
       The functions of the following two instructions are identical.

      \nvs\ccmasm{set right 111100000000000} \\
      \nvs\ccmasm{set right 1111} 

\end{itemize}

The CCM assembly is a very simple assembly language. It is easy to develop
an interpreter for the CCM assembly, this CCM interpreter accepts CCM 
assembly programs as its input, then executes CCM instructions by 
calling proper DEC-PERLE-1 runtime library routines, and passes the result
back to the host program. 

For making the CCM easy to use, the CCM runtime library, a set of library
calls which can be called from C/C++ programs, need to be developed
by the next student in the CCM project group. For example, this
library should have a routine (function) to carry out sharp operation
on two arrays of cubes. The CCM runtime library can hide unnecessary 
details about the CCM hardware from the programmer, and enables 
programmers to think at a higher level and develop applications more 
efficiently. 

\section{Examples of Using CCM Assembly}
\label{CHEN-section6.2}

This section presents several examples of solving some cube operation
problems in CCM assembly. These examples serve as a tutorial about
how to use the CCM to solve the problems. All these programs have an 
assumption that the CCM is reset, which means that all registers and 
control signals of tri-state buffers are zeroed.

\noindent
\begin{example}
~\label{CHEN-Example6.4}
\end{example}
 
\noindent
Assuming two cubes $A=ab$ and $B=b~\overline{c}$, where $a$, $b$ and $c$ are 
binary variables. Write a CCM assembly program to calculate the intersection of cubes $A$ and $B$.

\noindent
{\bf Solution.}

\noindent
The intersection operation is a simple combinational cube operation,
it does not have {\bf pre-relation/pre-operation} (see section~\ref{CHEN-section3.5}), and \\
% For the intersection operation (from Table \ref{tbl:ccm2}),\\
\centerline{$ rel = \text{xxxx},\quad and\_or = \text{x},\quad bef = 0001 $}\\
Since we process cubes with 3 binary variables, we have \\
\centerline{$ water = \text{ 000-1111-1111-1111} , \quad 
            rightedge = \text{ 111-xxxx-xxxx-xxxx}     $}
Cubes $A$ and $B$ can be described in positional notation as: \\
\centerline{$ A = ab \rightarrow \text{01-01-11} , \quad
              B = b\overline{c} \rightarrow \text{11-01-10}   $}
Therefore, the program is as follows:

% \nvs\ccmasm{1. enable enififod}\\
% \nvs\ccmasm{2. set conf  100000100}\\
% \nvs\ccmasm{3. set water 000}\\
% \nvs\ccmasm{4. set right 111}\\
% \nvs\ccmasm{5. set inst  00-0-0-0-0000-0001-0000-0000  ;intersection }\\
% \nvs\ccmasm{6. set accu  01-01-11 ; cube A}\\
%     \ccmasm{7. exec 11-01-10 ; cube B}

\vspace*{10pt}
{\footnotesize
 \renewcommand{\baselinestretch}{1}
 \begin{alltt}
      1. enable    enififod
      2. set conf  100000100
      3. set water 000
      4. set right 111
      5. set inst  00-0-0-0-0000-0001-0000-0000  ;intersection 
      6. set accu  01-01-11                      ; cube A
      7. exec      11-01-10                      ; cube B
 \end{alltt}
 \renewcommand{\baselinestretch}{1.37}
}

Line numbers are not part of the CCM assembly, they are used here to
help identify specific lines of code in our discussion. Everything
to the right of the semi-colon ``;" are the comments.

Line 1 enables the tri-state buffer from the bus {\it IBus} to the 
{\it DBusA}, which means the data existing on the {\it IBus} exist also
on the bus {\it DBusA} at the same time. Line 2 sets $ASrc=OSrc=0$,
$toOFifo=1$ and $enFinish=1$, which means that the inputs of registers
{\it accu} and {\it data} are connected to the bus {\it DBusA} (see Figure
\ref{fig:ndes1}), and the CCM will write the result(s) to the output FIFO.
This instruction means also that the CCM is enabled to generate finish word.
In this example, we don't care about the other bits of the
{\it config} register.

Lines 3 to 5 are very straightforward. Line 6 lets the CCM load the cube
A into the {\it accumulator}. Line 7 lets the CCM load the cube B into
the {\it data} register and execute the cube operation (defined by {\it inst} 
and {\it prpo} registers) on the operand cubes (stored in the {\it Accu} 
and the {\it Data} registers). 
Please note that the CCM does not know (or does not care) the 
configuration of the datapath, it is the programmer's responsibility 
to set {\it config} register and the control bits of tri-state buffers
correctly before issuing the {\tt EXEC} command. In this example, these 
signals are set in Lines 1 and 2 of above program.

This is an example of executing pattern (a) (see section~\ref{CHEN-section5.1}), and
the dataflow mode used by this example is shown in \ref{fig:patns} (b)
(see section~\ref{CHEN-section5.2.4}).


\noindent
\begin{example}
~\label{CHEN-Example6.5}
~\label{CHEN-ExamplexX}
\end{example}

\noindent
Assuming four cubes $A=ac$, $B=ad$, $C=bd$ and $D=cd$, where $a$, $b$,
$c$ and $d$ are binary variables. Write a CCM assembly program to 
calculate the intersection of these four cubes: $A\cdot B\cdot C\cdot D$
(Try to use as few instructions as possible).

\noindent
{\bf Solution.}

\noindent
The program is as follows: 

% \nvs\ccmasm{1. enable enififod}\\
% \nvs\ccmasm{2. set water 0000}\\
% \nvs\ccmasm{3. set right 1111}\\
% \nvs\ccmasm{4. set inst 00-0-0-0-0000-0001-0000-0000 ; intersection operation}\\
% \nvs\ccmasm{5. set accu 01-11-01-11 ; cube A}\\
% \nvs\ccmasm{6. set conf 000010010 ; sent result back to ACCU}\\
% \nvs\ccmasm{7. enable   enIluB}\\
% \nvs\ccmasm{8. exec     01-11-11-01 ; cube B}\\
% \nvs\ccmasm{9. exec     11-01-11-01 ; cube C}\\
% \nvs\ccmasm{10. set conf 100000100}\\
% \nvs\ccmasm{11. disable  enIluB}\\
%     \ccmasm{12. exec     11-11-01-01 ; cube D}

\vspace*{10pt}
{\footnotesize
 \renewcommand{\baselinestretch}{1}
 \begin{alltt}
      1. enable    enififod
      2. set water 0000
      3. set right 1111
      4. set inst  00-0-0-0-0000-0001-0000-0000 ; intersection operation
      5. set accu  01-11-01-11                  ; cube A
      6. set conf  000010010                    ; sent result back to ACCU
      7. enable    enIluB
      8. exec      01-11-11-01                  ; cube B
      9. exec      11-01-11-01                  ; cube C
      10. set conf 100000100
      11. disable  enIluB
      12. exec     11-11-01-01                  ; cube D
 \end{alltt}
 \renewcommand{\baselinestretch}{1.37}
}

\vspace*{- 8pt}
As mentioned before, there is an assumption that the CCM is reset, which 
means the {\it config} register is set to 000000000. Lines 2 to 5 set 
the registers {\it water}, {\it right\_edge}, {\it inst} and {\it accu}.
Lines 6 and 7 set a feedback path from the output of the ILU to the input
of the {\it Accu} and let the CCM write the results back to the {\it Accu}.

Line 8 let the CCM calculate $A \cdot B$ and write the result back to 
{\it Accu}. Line 9 let the CCM calculate $[Accu] \cdot C$ and write 
the result back to {\it Accu}, where $[Accu]$ represents the content of
the {\it Accu}. At this time, the content of {\it Accu} is the 
intersection of cubes $A$, $B$ and $C$.

Line 10 let the CCM write the result to the output FIFO; and enables
the CCM to generate ``finish word". Line 11
breaks the feedback path created by Lines 6 and 7. Line 12 let the CCM
calculate $[Accu] \cdot D$ and write the result to the output FIFO.

This is an example of executing pattern (c) (see section~\ref{CHEN-section5.1}), and
the dataflow mode used by this example is shown in \ref{fig:patns} (c)
(see section~\ref{CHEN-section5.2.4}).

\noindent
\begin{example}
~\label{CHEN-Example6.6}
\end{example}

\noindent
Let us assume two cubes $A=\overline{c}$ and $B=bd$, where $a$, $b$, $c$ and $d$
are binary variables. We present a a CCM assembly program to calculate 
the basic sharp of cubes A and B: $A \#_{basic} B$ (Cube $A$ is stored in
the {\it Accu} and cube $B$ is stored in the {\it data} register).

\noindent
{\bf Solution.}

\noindent
The program is as follows: 

% \nvs\ccmasm{1. enable enififod}\\
% \nvs\ccmasm{2. set conf  100000100}\\
% \nvs\ccmasm{3. set water 0000}\\
% \nvs\ccmasm{4. set right 1111}\\
% \nvs\ccmasm{5. set inst  00-1-0-0-0010-0011-0010-0011 
%                ; basic sharp [Accu]\#[Data]}\\
% \nvs\ccmasm{6. set accu  11-11-10-11 ; cube A}\\
%   \ccmasm{7. exec 11-01-11-01 ; cube B}

\vspace*{10pt}
{\footnotesize
 \renewcommand{\baselinestretch}{1}
 \begin{alltt}
      1. enable    enififod
      2. set conf  100000100
      3. set water 0000
      4. set right 1111
      5. set inst  00-1-0-0-0010-0011-0010-0011 ; basic sharp [Accu]#[Data]
      6. set accu  11-11-10-11                  ; cube A
      7. exec      11-01-11-01                  ; cube B
 \end{alltt}
 \renewcommand{\baselinestretch}{1.37}
}

This example is the same as Example~\ref{CHEN-Example6.4} except that it uses a different
operation on different operand cubes. This is an example of executing
pattern (b) (see section~\ref{CHEN-section5.1}), and the dataflow mode used by this example
is shown in \ref{fig:patns} (b) (see section~\ref{CHEN-section5.2.4}).

\noindent
\begin{example}
~\label{CHEN-Example6.7}
\end{example}

\noindent
Write a program in the CCM assembly to calculate the basic sharp operation
of two cubes $A$ and $B$: $B \;\#_{basic}\; A$, where cubes $A$ and $B$ 
are the same as in the previous example (Again, cube $A$ is stored in the 
{\it Accu}, and cube $B$ is stored in the {\it data} register).


\noindent
{\bf Solution.}

\noindent
It can be seen from the definition of sharp that $(A\,\#_{basic}\, B)\neq 
(B\,\#_{basic}\, A)$, and $B\,\#_{basic}\, A$ is not listed in Table
\ref{tbl:ccm2}. This is a ``new" cube operation. This operation is very 
useful to execute the sharp operation on an array of cubes and a cube.

The functions $rel$, $bef$, $act$ and $aft$ are 2 inputs Boolean function 
$f(a_i,b_i)$. The 4 output values of each function are corresponding to
minterms $\overline{a_i}~\overline{b_i}$, $\overline{a_i}b_i$, $a_i\overline{b_i}$ and $a_ib_i$, 
respectively, where $a_i$ comes from operand cube stored in {\it Accu},
and $b_i$ comes from operand cube stored in {\it data} register.

Now, we want to perform sharp operation $[Data]\#_{basic} [Accu]$ (where
$[Data]$, $[Accu]$ represent the contents of {\it data} and {\it Accu}
registers, respectively), therefore, we have to substitute $a_i$ with 
$b_i$ and $b_i$ with $a_i$ in function $f(a_i,b_i)$ in order to
obtain function $f(b_i,a_i)$. Its minterms are ($b_i$ is the most 
significant bit now): $\overline{b_i}~\overline{a_i}$, $\overline{b_i}a_i$, 
$b_i\overline{a_i}$ and $b_ia_i$, respectively. We have to 
use the format of $f(a_i,b_i)$ to represent $f(b_i,a_i)$ in the 
instruction, and we can obtain it by swapping minterms $\overline{b}a$ and 
$b\overline{a}$. Therefore, we just swap second and third output values of the
functions $rel$, $bef$, $act$ and $aft$. 
Therefore, only Line 5 of previous example needs to be changed. The whole
program is as follows:

% \nvs\ccmasm{1. enable enififod}\\
% \nvs\ccmasm{2. set conf  00000100}\\
% \nvs\ccmasm{3. set water 0000}\\
% \nvs\ccmasm{4. set right 1111}\\
% \nvs\ccmasm{5. set inst  00-1-0-0-0100-0101-0100-0101 
%                ; basic sharp [Data]\#[Accu]}\\
% \nvs\ccmasm{6. set accu  11-11-10-11 ; cube A}\\
%     \ccmasm{7. exec 11-01-11-01 ; cube B}

\vspace*{10pt}
{\footnotesize
 \renewcommand{\baselinestretch}{1}
 \begin{alltt}
      1. enable    enififod
      2. set conf  100000100
      3. set water 0000
      4. set right 1111
      5. set inst  00-1-0-0-0100-0101-0100-0101 ; basic sharp [Data]#[Accu]
      6. set accu  11-11-10-11                  ; cube A
      7. exec      11-01-11-01                  ; cube B
 \end{alltt}
 \renewcommand{\baselinestretch}{1.37}
}

\vspace*{- 8pt}

\noindent
\begin{example} 
~\label{CHEN-Example6.8}
\end{example} 

\noindent
Write a program in the CCM assembly to calculate basic sharp operation:\;
$\vec{B}\;\#_{basic}\; A = (B_1\, B_2\, B_3)\,\#\, A 
= (a\, b, c)\,\#\, bd$, where $B$ is an array of 3 cubes, $A$ is a cube,
and $a$, $b$, $c$ and $d$ are binary variables (Try to use as few 
instructions as possible).

\noindent
{\bf Solution.}

\noindent
The program is as follows: 

% \nvs\ccmasm{1. enable enififod}\\
% \nvs\ccmasm{2. set conf  00000100}\\
% \nvs\ccmasm{3. set water 0000}\\
% \nvs\ccmasm{4. set right 1111}\\
% \nvs\ccmasm{5. set inst  00-1-0-0-0100-0101-0100-0101 
%                ; basic sharp [Data]\#[Accu]}\\
% \nvs\ccmasm{6. set accu  11-11-10-11 ; cube A}\\
% \nvs\ccmasm{7. exec 01-11-11-11 ; cube B1}\\
% \nvs\ccmasm{8. exec 11-01-11-11 ; cube B2}\\
%     \ccmasm{9. exec 11-11-01-11 ; cube B3}

\vspace*{10pt}
{\footnotesize
 \renewcommand{\baselinestretch}{1}
 \begin{alltt}
      1. enable    enififod
      2. set conf  000000100
      3. set water 0000
      4. set right 1111
      5. set inst  00-1-0-0-0100-0101-0100-0101 ; basic sharp [Data]#[Accu]
      6. set accu  11-11-10-11                  ; cube A
      7. exec 01-11-11-11                       ; cube B1
      8. exec 11-01-11-11                       ; cube B2
      9. set conf  100000100                    : generate finish word
      10. exec     11-11-01-11                  ; cube B3
 \end{alltt}
 \renewcommand{\baselinestretch}{1.37}
}

\vspace*{- 8pt}
This is an example of executing pattern (d) (see section~\ref{CHEN-section5.1}). 

\noindent
\begin{example}
~\label{CHEN-Example6.9}
\end{example}

\noindent
Write a program in the CCM assembly to calculate disjoint sharp operation:
$A \;\#d\;\vec{B}=A \;\#d\; (B_1 + B_2 + B_3) = 1 \;\#\; 
(ab+\overline{a}c+\overline{b}~\overline{c})$ where $A$ is a cube, $\vec{B}$ is a 
array of cubes, and $a$, $b$ and $c$ are three binary variables. 
Please note that this example shows how to use the loop instruction.

\noindent
{\bf Solution.}

\noindent
The program is as follows: 

% \nvs\ccmasm{1. set conf  00000000}\\
% \nvs\ccmasm{2. enable enififoa}\\
% \nvs\ccmasm{3. set addrb 0}\\
% \nvs\ccmasm{4. disable enififoa}\\
% \nvs\ccmasm{5. enable enififod}\\
% \nvs\ccmasm{6. set water 000}\\
% \nvs\ccmasm{7. set right 111}\\
% \nvs\ccmasm{8. set prpo 1-1110-10-0-0101--0-0100-01-0-0000 
%                ; P-REL for D (\#d) A}\\
% \nvs\ccmasm{9. set inst  11-1-0-0-0100-0101-0100-0001
%                ; INST for D (\#d) Accu}\\
% \nvs\ccmasm{10. set accu  01-11-11 ; cube B1}\\
% \nvs\ccmasm{11. set conf  01000001 ; write result to MEM\_B}\\
% \nvs\ccmasm{12. enable enIluB}\\
% \nvs\ccmasm{13. disable MemBRW}\\
% \nvs\ccmasm{14. exec 01-11-11 ; cube A1}\\
% \nvs\ccmasm{15. exec 10-11-11 ; cube A2}\\
% \nvs\ccmasm{16. disable enIluB}\\
% \nvs\ccmasm{17. enable addrb ; [AddrB] => [AddrR]}\\
% \nvs\ccmasm{18. set addrr 0 ; operand 0 is useless but required}\\
% \nvs\ccmasm{19. disable addrb}\\
% \nvs\ccmasm{20. enable enIFifoA}\\
% \nvs\ccmasm{21. set addrb 0}\\
% \nvs\ccmasm{22. disable enIFifoA}\\
% \nvs\ccmasm{23. set accu  11-01-11 ; cube B2}\\
% \nvs\ccmasm{24. disable enIFifoD}\\
% \nvs\ccmasm{25. set conf  11101001 ; memB=>ILU=>memA}\\
% \nvs\ccmasm{26. enable MemBRW}\\
% \nvs\ccmasm{27. disable MemARW}\\
% \nvs\ccmasm{28. enable enIluA}\\
% \nvs\ccmasm{29. loop 0 ; operand 0 is useless but required}\\
% \nvs\ccmasm{30. disable MemBRW}\\
% \nvs\ccmasm{31. disable enIluA}\\
% \nvs\ccmasm{32. enable addra ; [AddrA] => [AddrR]}\\
% \nvs\ccmasm{33. set addrr 0}\\
% \nvs\ccmasm{34. disable addra}\\
% \nvs\ccmasm{35. enable enIFifoA}\\
% \nvs\ccmasm{36. set addra 0}\\
% \nvs\ccmasm{37. disable enIFifoA}\\
% \nvs\ccmasm{38. set conf  00000000}\\
% \nvs\ccmasm{39. enable enIFifoD}\\
% \nvs\ccmasm{40. set accu  11-11-01 ; cube B3}\\
% \nvs\ccmasm{41. disable enIFifoD}\\
% \nvs\ccmasm{42. set conf  10000100 ; memA=>ILU=>OFifo}\\
% \nvs\ccmasm{43. enable MemARW}\\
%     \ccmasm{44. loop 0 }

\vspace*{8pt}
{\footnotesize
 \renewcommand{\baselinestretch}{1}
 \begin{alltt}
       1. set conf  000000000
       2. enable    enififoa
       3. set addrb 0
       4. disable   enififoa
       5. enable    enififod
       6. set water 000
       7. set right 111
       8. set prpo  1-1110-10-0-0101--0-0100-01-0-0000 ; disjoint sharp [D]#d[A]
       9. set inst  11-1-0-0-0100-0101-0100-0001       ; disjoint sharp [D]#d[A]
      10. set accu  01-01-11                           ; cube B1
      11. set conf  001000001                          ; write result to MEM_B
      12. enable    enIluB
      13. disable   MemBRW
      14. exec      11-11-11                           ; cube A1
      15. disable   enIluB
      16. enable    enaddrb                            ; [AddrB] => [AddrR]
      17. set addrr 0                                   
      18. disable   enaddrb
      19. enable    enIFifoA
      20. set addrb 0
      21. disable   enIFifoA
      22. set accu  10-11-01                           ; cube B2
      23. disable   enIFifoD
      24. set conf  011101001                          ; memB=>ILU=>memA
      25. enable    MemBRW
      26. disable   MemARW
      27. enable    enIluA
      28. loop 0
      29. disable   MemBRW
      30. disable   enIluA
      31. enable    enaddra                            ; [AddrA] => [AddrR]
      32. set addrr 0
      33. disable   enaddra
      34. enable    enIFifoA
      35. set addra 0
      36. disable   enIFifoA
      37. set conf  000000000
      38. enable    enIFifoD
      39. set accu  11-10-10                           ; cube B3
      40. disable   enIFifoD
      41. set conf  110000100                          ; memA=>ILU=>OFifo
      42. enable    MemARW
      43. loop 0
 \end{alltt}
 \renewcommand{\baselinestretch}{1.37}
}

\vspace*{- 8pt}
This is a little bit more complex example. Lines 2 to 4 set {\it AddrB} to 0.
Lines 5 to 9 set {\it water} {\it right\_edge}, {\it inst} and {\it prpo}
registers. Please note that this example shows how to carry out
pre-relation/pre-operation.

Lines 10 to 15 calculate $A \;\#\;B_1$ and write
result (called $\vec{I1}$ here) to MEM\_B (please note that the result 
can not write to MEM\_A at this time because the {\it execute} instruction
needs {\it DBusA} to load cubes $A$). The dataflow mode used in
this step is shown in Figure \ref{fig:patns} (d) (see section~\ref{CHEN-section5.2.4}).

Lines 16 to 30 calculate $\vec{I1}\;\#\;B_2$ and write result (called
$\vec{I2}$) to MEM\_A. This is an example of using loop instruction.
Now what we want to do is to calculate the following operation:
\begin{equation*}
\vec{I1} \, \# \, B_2 = (I1_1 \# B_2 \; I1_2 \# B_2 \; \ldots)
\end{equation*}
Because the array of cube $\vec{I1}$ is stored in memory bank MEM\_B,
we can use the ``loop" instruction to carry this out.

The loop instruction loads one cube from one of two memory banks
(determined by signal {\it enMemA}, {\it enMemB}, {\it MemARW}
and {\it MemBRW}, see section~\ref{CHEN-section5.2}) to the {\it Data} register. Then
the memory address pointer will be increased by 1, and the operation
currently set in the {\it inst} and the {\it prpo} registers is executed
on two cubes stored in {\it Accu} and {\it Data} registers. After the
operation is done, the GCU checks if the loop operation is done by
comparing the content of {\it AddrR} with {\it AddrA} or {\it AddrB}.
% (determined by signal {\it CmpSrc}, see section~\ref{CHEN-section5.3.3}). 
If their contents are not the same, the GCU will load one cube from 
the memory to the {\it Data} register again, and will repeat the whole 
process until the contents of {\it AddrR} and {\it AddrA} (or {\it AddrB})
become the same.

The array of cubes $\vec{I1}$ is stored in MEM\_B. For using loop
instruction, we need to set the content of {\it AddrR} to the number of
cubes of $\vec{I1}$, which is currently stored in {\it AddrB}. Lines
16 to 18 copy the content of {\it AddrB} to {\it AddrR}. After that,
the content of {\it AddrB} is set to 0 (Lines 19 to 21) to point the
beginning of $\vec{I1}$. Line 22 loads cube $B_2$ into {\it Accu}. 

The operation $\vec{I1}\#B_2$ is not the last operation of this 
example, and the result will be used in the subsequent operation,
therefore, the result array of cubes of the operation will be stored in
MEM\_A.  The dataflow mode used in this step is shown in Figure 
\ref{fig:patns} (f) (see section~\ref{CHEN-section5.2.4}). Lines 23 to 27 set the data
flow mode.

The loop instruction is issued in Line 28. Lines 29 and 30 remove
the drivers of buses {\it DBusA} and {\it DBusB} for the subsequent 
operation since the subsequent operation will use different dataflow
mode, which means that the driver of {\it DBusA} and {\it DBusB} 
will be changed (remember for setting new bus driver, we have to 
remove the previous driver first, see section~\ref{CHEN-section5.3.2}).

Lines 31 to 43 calculate $\vec{I2}\#B_3$ in the similar
way with Lines 16 to 30. The difference is that the GCU loads the 
array of cubes $\vec{I2}$ from MEM\_A, and write the results to the
output FIFO this time. By comparing to Line 16 to 30, Line 31 to 43 are
not hard to understand. The dataflow mode used in this step is shown in 
Figure \ref{fig:patns} (e) (see section~\ref{CHEN-section5.2.4}).

The operation $1\#(ab + \overline{a}c + \overline{b}~\overline{c}) = \overline{a}b\overline{c}+
a\overline{b}c$. This example is used as a test program to test the entire
CCM (see section~\ref{CHEN-section7.2.6}).

\noindent
\begin{example}
~\label{CHEN-Example6.10}
\end{example}

\noindent
Write a program in the CCM assembly to calculate the following operation: 
\begin{align*}
  \vec{A}\cdot\vec{B}\cdot\vec{C}
  & = (A_1+A_2+A_3)\cdot (B_1+B_2+B_3)\cdot (C_1+C_2+C_3) \\
  & = (ab + bc + cd) \cdot (bc + cd + ad) \cdot (\overline{a} + \overline{b} + \overline{c})
\end{align*}
where $A$, $B$ and $C$ are three arrays of cubes, and $a$, $b$, $c$ and
$d$ are four binary variables. 

\noindent
{\bf Solution.} 

\noindent
The program is as follows: 

% \nvs\ccmasm{1. set conf  00000000}\\
% \nvs\ccmasm{2. enable enififoa}\\
% \nvs\ccmasm{3. set addrb 0}\\
% \nvs\ccmasm{4. disable enififoa}\\
% \nvs\ccmasm{5. enable enififod}\\
% \nvs\ccmasm{6. set water 0000}\\
% \nvs\ccmasm{7. set right 1111}\\
% \nvs\ccmasm{8. set inst 00-0-0-0-0000-0001-0000-0000 
%                ; intersection}\\
% \nvs\ccmasm{9. set accu  01-11-11-11 ; cube A1}\\
% \nvs\ccmasm{10. set conf  01000001 ; write result to MEM\_B}\\
% \nvs\ccmasm{11. enable enIluB}\\
% \nvs\ccmasm{12. disable MemBRW}\\
% \nvs\ccmasm{13. exec 11-01-11-11 ; cube B1}\\
% \nvs\ccmasm{14. exec 11-11-01-11 ; cube B2}\\
% \nvs\ccmasm{15. exec 11-11-11-01 ; cube B3}\\
% \nvs\ccmasm{16. set accu  11-01-11-11 ; cube A2}\\
% \nvs\ccmasm{17. exec 11-01-11-11 ; cube B1}\\
% \nvs\ccmasm{18. exec 11-11-01-11 ; cube B2}\\
% \nvs\ccmasm{19. exec 11-11-11-01 ; cube B3}\\
% \nvs\ccmasm{20. set accu  11-11-01-11 ; cube A3}\\
% \nvs\ccmasm{21. exec 11-01-11-11 ; cube B1}\\
% \nvs\ccmasm{22. exec 11-11-01-11 ; cube B2}\\
% \nvs\ccmasm{23. exec 11-11-11-01 ; cube B3}\\
% \nvs\ccmasm{24. disable enilub}\\
% \nvs\ccmasm{25. enable addrb ; [AddrB] => [AddrR]}\\
% \nvs\ccmasm{26. set addrr 0 ; operand 0 is useless but required}\\
% \nvs\ccmasm{27. disable addrb}\\
% \nvs\ccmasm{28. enable enIFifoA}\\
% \nvs\ccmasm{29. set addrb 0}\\
% \nvs\ccmasm{30. set conf  01101100 ; memB=>ILU=>OFifo}\\
% \nvs\ccmasm{31. enable MemBRW}\\
% \nvs\ccmasm{32. set accu  10-11-11-11 ; cube C1}\\
% \nvs\ccmasm{33. loop 0 } \\
% \nvs\ccmasm{34. set addrb 0}\\
% \nvs\ccmasm{35. set accu  11-10-11-11 ; cube C2}\\
% \nvs\ccmasm{36. loop 0 } \\
% \nvs\ccmasm{37. set addrb 0}\\
% \nvs\ccmasm{38. set accu  11-11-10-11 ; cube C3}\\
%     \ccmasm{39. loop 0 }

\vspace*{10pt}
{\footnotesize
 \renewcommand{\baselinestretch}{1}
 \begin{alltt}
       1. set conf  000000000
       2. enable    enififoa
       3. set addrb 0
       4. disable   enififoa
       5. enable    enififod
       6. set water 0000
       7. set right 1111
       8. set inst  00-0-0-0-0000-0001-0000-0000 ; intersection
       9. set accu  01-01-11-11                  ; cube A1
      10. set conf  001000001                    ; write result to MEM_B
      11. enable    enIluB
      12. disable   MemBRW
      13. exec      11-01-01-11                  ; cube B1
      14. exec      11-11-01-01                  ; cube B2
      15. exec      01-11-11-01                  ; cube B3
      16. set accu  11-01-01-11                  ; cube A2
      17. exec      11-01-01-11                  ; cube B1
      18. exec      11-11-01-01                  ; cube B2
      19. exec      01-11-11-01                  ; cube B3
      20. set accu  11-11-01-01                  ; cube A3
      21. exec      11-01-01-11                  ; cube B1
      22. exec      11-11-01-01                  ; cube B2
      23. exec      01-11-11-01                  ; cube B3
      24. disable   enIluB
      25. enable    enaddrb                      ; [AddrB] => [AddrR]
      26. set addrr 0
      27. disable   enaddrb
      28. enable    enIFifoA
      29. set addrb 0
      30. set conf  001101100                    ; memB=>ILU=>OFifo
      31. enable    MemBRW
      32. set accu  10-11-11-11                  ; cube C1
      33. loop 0
      34. set addrb 0
      35. set accu  11-10-11-11                  ; cube C2
      36. loop 0
      37. set addrb 0
      38. set accu  11-11-10-11                  ; cube C3
      39. set conf  101101100                    ; generate finish word
      40. loop 0
 \end{alltt}
 \renewcommand{\baselinestretch}{1.37}
}

\vspace*{- 8pt}
This program is very straightforward. Lines 1 to 23 calculate 
$\vec{A} \cdot \vec{B}$ and write the results (called $\vec{I}$) 
to MEM\_B.  Lines 24 to 38 calculate $\vec{I} \cdot \vec{C}$
and write the result to the output FIFO. 
This example is used as a test program to test the entire
CCM (see section~\ref{CHEN-section7.2.6}), the result is also shown there.


\section{Simulation}
\label{CHEN-Chapter7}

A complete design of the Cube Calculus Machine version II (CCM2)
has been created in this book. It has been captured in VHDL
and simulated by QuickHDL \cite{mentor1,mentor2}, a VHDL/HDL
simulator from Mentor Graphics. The functionality of this design
was tested and approved to be correct.

\section{Design Capture}
\label{CHEN-section7.1}

The design of CCM2 is captured in VHDL code hierarchically, which
means that the VHDL codes of the lower level design blocks were
captured first, then these blocks are tested (through simulation) and 
modified until their function was proved to be correct. This way, 
the design bugs can be identified
earlier and can be fixed easier. Later, these blocks were used
in the VHDL code of upper level design blocks. Figure \ref{fig:hier}
shows the hierarchical structure of the CCM. The rectangular boxes in
the figure represent design blocks, their names and corresponding VHDL
file names (in parentheses) are shown in the boxes. The ``other logic"
rectangular box includes VHDL modes of some basic components, like
D flip-flop, multiplexer and others. Details about 
VHDL language can be found in \cite{vhdl1,vhdl2}; details
about how to use QuickHDL tool can be found in \cite{mentor2}.
The VHDL code of this design is available in the next chapters, also on a WWW Page of
this author, \makeatletter(mperkows@ee.pdx.edu)\makeatother .

\begin{figure}[H]
\centerline{\hbox{\psfig{figure=fig/hier.eps,width=3.5in}}}
\caption{Hierarchical structure of the CCM}
\label{fig:hier}
\end{figure}

\section{Functional Verification}
\label{CHEN-section7.2}

After the design of the CCM is captured, its functionality needs to
be fully tested to make sure that it does what it is supposed to. 
Functional verification of the CCM was performed through simulation using
the QuickHDL tool.

A test bench file (testccm.vhd) was created. This test bench file 
realizes CCM assembly described in Chapter~\ref{CHEN-Chapter6}, which means that it accepts
the CCM assembly instructions as input instead of a ``force" file, and
prints out the resultant cube(s). The test bench file greatly improves the
efficiency of the functional verification. Due to the VHDL not
accepting variable-length strings, this test bench file always uses 
``test.ccm" as the input file name, which means that the user has to rename 
his/her CCM assembly program to ``test.ccm" before he/she tests it.

The test bench is very simple, it just simulates the function of the
host computer (just interface part). The test bench contains two
VHDL processes:
\begin{itemize}
\item Verify: This process reads one CCM instruction from file test.ccm,
      then encodes this instruction into binary format and pushes it
      into the input FIFO of the CCM. This procedure will be repeated 
      until all CCM instructions in file test.ccm are processed.
      This process simulates the host computer sending CCM instructions
      to the CCM.
\item Read Output FIFO: This process fetches the resultant cubes from
      the output FIFO of the CCM. This process simulates the host
      computer receiving the result from the CCM.   
\end{itemize}
For more information about the test bench, please read 
Chapter~\ref{CHEN-Chapter10}
of \cite{vhdl2}.

A test plan was drafted to systematically verify the functionality of 
the CCM. The test procedure is as follows:
\begin{itemize}
\item A single combinational operation (like Example~\ref{CHEN-Example6.4}) was selected
      to be tested first because this is the simplest case.
\item A single complex combinational operation without 
      pre-relation/pre-operation has been tested.
\item A single complex combinational operation with
      pre-relation/pre-operation had been tested.
\item A single sequential operation without pre-relation/pre-operation
      had been tested.
\item A single sequential operation with pre-relation/pre-operation
      had been tested.
\item Complicated programs shown in Examples~\ref{CHEN-Example6.9}
 and~\ref{CHEN-Example6.10} have been
      tested. These two tests both perform multiple cube operations.
      The memory banks and several data flow modes are also tested 
      in these two tests.
\end{itemize}

This following section will represent some tests that we have performed.
All test programs (CCM assembly programs) are given in Chapter~\ref{Appendix-A}, except
the last two tests.

\begin{figure}[H]
\centerline{\hbox{\psfig{figure=fig/simscreen.ps,height=4.5in}}}
\caption{The simulation of Test1} 
\label{fig:simscreen}
\end{figure}

\subsection{Simple combinational cube operation}

This test is to test an intersection operation. TEST1.A tests an 
intersection operation which creates a resultant cube. TEST1.B tests
an intersection operation which creates a contradiction.

\subsubsection{TEST1.A}

Example~\ref{CHEN-Example2.4} is used as the test operation. 
The screen of the simulation is shown in Figure \ref{fig:simscreen}.
As shown in the figure, every line read from file ``test.ccm" shows 
on the simulation window, and if the input line is a valid instruction, 
its encoding shows on the simulation windows too. There are two resultant
cubes for this test (near the bottom of the figure):\\
\nvs\ccmasm{result cube (No.1): 00-01011000-00000000-00000000-000000}\\
    \ccmasm{result cube (No.2): 10-01011000-00000000-00000000-000000}\\
If the highest 2 bits of the resultant cube are ``00", then the lower
30 bits are the resultant cube; if the highest 2 bits of the resultant cube are 
``10", then this word represents the ``finish word" (see section~\ref{CHEN-section5.3}, 
Execute instruction). For this test, the first resultant cube is a valid 
resultant cube which represents $ab\overline{c}$; the second resultant cube is the
``finish word". This result is correct.

\subsubsection{TEST1.B}

Example~\ref{CHEN-Example2.18} is used as a test operation. This test just produces a 
``finish word" which means there is no resultant cube, and it is correct.

\subsection{Complex combinational operation without pre-relation}

This test is to test a cofactor operation. Example~\ref{CHEN-Example2.8} is used as the
test operation. There are two resultant cubes for this test: \\
\nvs\ccmasm{result cube (No.1): 00-11010000-00000000-00000000-000000}\\
    \ccmasm{result cube (No.2): 10-11010000-00000000-00000000-000000}\\
which means that the resultant cube is $x_2$, and it is correct.

\subsection{Complex combinational operation with pre-relation}

This test is to test a consensus operation. TEST3.A tests first
pre-relation/pre-operation ($distance(A,B)=0$). TEST3.B tests 
second pre-relation/pre-operation ($distance(A,B)>1$). TEST3.C
test the basic consensus operation ($distance(A,B)=1$).

\subsubsection{TEST3.A}

Assuming two cubes $A=x_1\bar{x_3}$ and $B=x_1\bar{x_2}$,
where $x_1$, $x_2$, $x_3$ and $x_4$ are binary variables.
Because the distance of cubes $A$ and $B$ is 0, then the consensus
of cubes $A$ and $B$ is: $A\, *\, B = A \cap B = x_1\bar{x_2}\bar{x_3}$.
The outputs of the simulation are:\\
\nvs\ccmasm{result cube (No.1): 00-01101011-00000000-00000000-000000}\\
    \ccmasm{result cube (No.2): 10-01101011-00000000-00000000-000000}\\
which is correct.

\subsubsection{TEST3.B}

Assuming two cubes $A=\bar{x_1}x_2\bar{x_3}$ and $B=x_1\bar{x_2}$,
where $x_1$, $x_2$, $x_3$ and $x_4$ are binary variables.
Because the distance of cubes $A$ and $B$ is 2 ($>1$), then there is
no consensus of cubes $A$ and $B$. The output of the simulation is 
a ``finish word", which is correct.

\subsubsection{TEST3.C}

Example~\ref{CHEN-Example2.7} is used as the test operation. There are two resultant cubes for 
this test: \\
\nvs\ccmasm{result cube (No.1): 00-01111011-00000000-00000000-000000}\\
    \ccmasm{result cube (No.2): 10-01111011-00000000-00000000-000000}\\
which means that the result cube is $x_1\bar{x_3}$, and it is correct.

\subsection{Test sequential cube operation without pre-relation}

This test is to test a crosslink operation. Example~\ref{CHEN-Example2.9} is used as the 
test operation. There are two resultant cubes for 
this test: \\
\nvs\ccmasm{result cube (No.1): 00-11111011-00000000-00000000-000000}\\
\nvs\ccmasm{result cube (No.2): 00-01111111-00000000-00000000-000000}\\
    \ccmasm{result cube (No.3): 10-01111111-00000000-00000000-000000}\\
which means that the result cubes are $\bar{x_3}$ and $x_1$, and it is correct.


\subsection{Test sequential cube operation with pre-relation}

This test is to test disjoint sharp operation. TEST3.A tests first
pre-relation/pre-operation ($A\cap B=0$). TEST3.B tests 
second pre-relation/pre-operation ($A\subseteq B$). TEST3.C
tests the basic disjoint sharp operation.

\subsubsection{TEST5.A}

Assuming two cubes $A=\bar{x_3}$ and $B=x_2x_3x_4$,
where $x_1$, $x_2$, $x_3$ and $x_4$ are binary variables.
Because $A \cap B = \o$, then the disjoint sharp $A\, \#d\, B = A$.
The outputs of the simulation are:\\
\nvs\ccmasm{result cube (No.1): 00-11111011-00000000-00000000-000000}\\
    \ccmasm{result cube (No.2): 10-11111011-00000000-00000000-000000}\\
which means that the resultant cube is $\bar{x_3}$ (cube $A$), and it is
correct.

\subsubsection{TEST5.B}

Assuming two cubes $A=x_1x_2\bar{x_3}$ and $B=x_1x_2$,
where $x_1$, $x_2$, $x_3$ and $x_4$ are binary variables.
Because $A \subseteq B$, then the disjoint sharp $A\, \#d\, B = \o$.
The output of the simulation is a ``finish word", which is correct.

\subsubsection{TEST5.C}

Example~\ref{CHEN-Example2.11} is used as the test operation. There are two resultant cubes for 
this test: \\
\nvs\ccmasm{result cube (No.1): 00-11101011-00000000-00000000-000000}\\
\nvs\ccmasm{result cube (No.2): 00-11011010-00000000-00000000-000000}\\
    \ccmasm{result cube (No.3): 10-11011010-00000000-00000000-000000}\\
which means that the resultant cubes are $\bar{x_2}\bar{x_3}$ and
$x_2\bar{x_3}\bar{x_4}$, and it is correct.

\subsection{Test two complex cases}

This test is to test cube operation on array of cubes. The memory
read/write operations and several data flow modes are verified in
this test.

\subsubsection{TEST6.A}

Example~\ref{CHEN-Example6.9} is used as the test operation. There are three resultant cubes
for this test: \\
\nvs\ccmasm{result cube (No.1): 00-10011000-00000000-00000000-000000}\\
\nvs\ccmasm{result cube (No.2): 00-01100100-00000000-00000000-000000}\\
    \ccmasm{result cube (No.3): 10-00000000-00000000-00000000-000000}\\
There are one ``finish" words and two valid resultant cube 
$\bar{a}b\bar{c}$ and $a\bar{b}c$, which means 
$1\#(ab + \bar{a}c + \bar{b}\bar{c}) = \bar{a}b\bar{c}+ a\bar{b}c$,
and it is correct.

\subsubsection{TEST6.B}

Example~\ref{CHEN-Example6.10} is used as the test operation. Let us multiply out the
function manually first:
\begin{align*}
   &(ab+bc+cd)(bc+cd+ad)(\bar{a}+\bar{b}+\bar{c}) \\
=\;&(abc+abcd+abd + bc+bcd+abcd + bcd+cd+acd)(\bar{a}+\bar{b}+\bar{c}) \\
=\;& \bar{a}bc+\bar{a}bcd+\bar{a}bcd+\bar{a}cd + \\
   & bar{b}cd+a\bar{b}cd + \\
   & ab\bar{c}d 
\end{align*}
Therefore, there are 7 cubes in the result array of cubes. Please note that
the duplicated cubes are not removed, and the function is not simplified.
The simulation produced 8 resultant cubes for this test: \\
\nvs\ccmasm{result cube (No.1): 00-10010111-00000000-00000000-000000}\\
\nvs\ccmasm{result cube (No.2): 00-10010101-00000000-00000000-000000}\\
\nvs\ccmasm{result cube (No.3): 00-10010101-00000000-00000000-000000}\\
\nvs\ccmasm{result cube (No.4): 00-10110101-00000000-00000000-000000}\\
\nvs\ccmasm{result cube (No.5): 00-11100101-00000000-00000000-000000}\\
\nvs\ccmasm{result cube (No.6): 00-01100101-00000000-00000000-000000}\\
\nvs\ccmasm{result cube (No.7): 00-01011001-00000000-00000000-000000}\\
    \ccmasm{result cube (No.8): 10-00000000-00000000-00000000-000000}\\
The resultant array of cubes is correct.

