ALU

chapter 2



2.1 Why do we need an ALU?
The ALU enables the core to carry out mathematical operations (+, -, /, x, *) and logical operations (==, >=, <=, >, <, &&, !, ~, !=) on binary instructions and data. Example, In high level codes like;
(if int var >= 12){do something},
int var = 12 * int test,
while(int var > 0){do something}
int test = (int var == 4)? 1:0
The ALU will be used to perform these computations above. If a system does not execute too many AL(Arithmetic and logical) operations, the ALU can be ignored. A separate block for each operation can integrated at the specific nodes where they are needed e.g. an adder block or multiplier etc. Cores which run too many instructions need an ALU because it centralizes all AL operation and provides varieties. The brainIO is expected to run high level programs which perform complex AL operations like the examples above. This is why we need an ALU




2.2 The Alu Pinout
In a typical ALU operation, two registers are selected from the Register unit Here, they are referred to as registerA and registerB in the ALU diagram above. The operation to be executed is loaded into the operand and executed.

The ALU supports arithmetic and logic operations between registers or between a constant and a register. Single register operations can also be executed in the ALU. After an arithmetic operation, the alu_set signal updates the Alu_register to reflect the output. For operations involving memory, data have to be moved from memory to register before they can accessed in this unit. Logical operations which can be used in loops or if-statement are fetched using GT, LT, EQ signals which represent Greater than, Less than and equal to, respectively. Other pins on the ALU are the flags- zero flag, carry flag, negative flag.. The table below shows the different ALU operation , their operand bits, and how they select registers to be performed on.



2.3 The Alu operations
Instruction Operation Operand bits
Inverse not(regA) 0000
Negate 0 - regA 0001
Decrement regA-- 0010
Subtraction regA - regB 0011
Addition regA + regB 0100
Increment regA++ 0101
Shift right regA >> regB 0110
Shift left regA << regB 0111
XOR regA ^ regB 1000
OR regA | regB 1001
AND regA & regB 1010
MAX max(regA, regB) 1011
MIN min(regA, regB) 1100


Hint:1
Each subsystem discussed will consist of its VHDL file, and C translation. The c file will have a corresponding header file. A common.h file is also common to most of the subsystems.
Hint:2
The corresponding header files will contain a struct whose items are equivalent to the output ports of the subsystems, so whenever these outputs are needed in another subsystem, their header files is simply included. As a result most of the functions are void, they simply change values in the struct which will be accessed by other subsystems.
Hint:3
Each subunit header file will include other header files which contains the input of the subunit and are also output of the files that own them.


2.4 ALU.vhd
First we Introduced the title. A double dash represents a single line comment in VHDL, therefore they won’t be executed. On line 2 , is the website name. Line 4 , is the name of this script, ALU.vhd. Line 6 , is the My name and my Email. Line 8 , is link to this project online. Next is the project name and finally the copyright.

Next we declare the IEEE libraries.

Lets, create the entity and its port. Its named ‘ALU’. The ports consists of all the pinouts in the diagram we discussed above.

Next we create the signals. We will describe what each signal does while we use them later below.


The VHDL Case Statement works exactly the way that a switch statement in C works. Given an input, the statement looks at each possible condition to find one that the input signal satisfies. They are useful to check one input signal against many combinations.
This process block uses a case statement to select the ALU operation to be performed. These operations are described in the table above. The operand signal is used in the case statement as the selector and the alu_out signal is the output. On line 64 and 66 is the shift right and shift left operation. Here, regA is shifted according to value in regB 3 downto 0. This is because for a 16-bit data, you can only shift a maximum of 16-times which is 4 bits only(x’F’). The rest of the operations are self-explanatory. On line 70 and 71 is the compareG and compareL signal. These two signals are used for max and min operation which would be discussed below.


The compareG signal, selects regA as the output to the alu_out if regA signal is greater than regB, else it selects regB. The compareL signal selects regA signal when it is less than regB else it selects regB . These two operation are used if you are comparing two values. Example syntax in an high level language will be :
int var1 = max(int var2, int var3);
int var1 = min(int var2, int var3);


This process block is used to deternmine the output of four registers. After an ALU operation the alu_set signal is used to store the outputs of the computation. On line, 90 down to 94 , is the lt_reg register(less than). This register stores a high if regA is less than regB , else it stores '0'. On line, 96 down to 100 , is the gt_reg register(greater than). This register stores a high if regA is greater than regB , else it stores '0'. On line, 102 down to 106 , is the eq_reg register(equal to). This register stores a high if regA is equal to regB , else it stores '0'. These three registers are used for feedback signals or conditional statements . example high level usage will be if-statement, while-loop etc. :
if (int var1 > int var2){do something}
while(int var1 > 0 ; int var1++){do something}
. These registers are different from the max() and min() operation. They return a signal while the later returns a value. On line 108 down to 111 , is the alu_register, this stores the output of the alu operation.

The registers discussed above are used to store outputs on line 114 to line 119



C version

2.5 common.h
We would first create a common header file. This file will contain the frequently used standard C header files. The stdbool.h (boolean type and values), stdio.h (has the necessary information to include the input/output related functions in our program. Example printf, scanf etc.), Stddef.h (standard type definitions), stdint.h (integer types), string.h (declares a set of functions to work strings.), stdlib.h (standard library definitions).



2.6 alumath.h
Next the alumath.h file. This file will contain the alu type definitions, struct and function declarations. On line 4 , we included the common.h file we just created. Next we include mult.h. This is the databus header file also called multiplexer. The two alu register signal data comes from the databus, and we need to reference them.

We will create the struct Alus alu which contains the alu outputs: LT, GT, EQ and the alu ouput register.

On line 16 down to 30 we create enum alu_op . This enum is a list of all alu operation we would select.

On line is the declaration of alu_set function. This is the only function that the alu executes.

2.7 alumath.c
On line 1 , we include the alu header file (alumath.h), next we declare three functions: GT(), EQ(), LT(). This 3 functions returns the state the alu operation registerA is : greater than, less than or equal to registerB . The output is also stored in the Alus struct in alumath.h.


The two alu registers are referred to as: databus_data.regA and databus_data.MULTOUT. The two outputs of the databus unit are : MULTOUT and regA, and they are items in a struct called dbus databus_data. The three functions below are used to compare the outputs of the databus.

The alu_set function takes operand as its only argument. This signal is an instance of the alu_op enum type we discussed in alu.h and contains the alu operation to be performed. A switch statement scans through the alu_op enum till it finds the operation that matches the operand. The output of the alu is the ALU_OUT signal and its an item in the Alus alu struct. Here It is referred to as : alu.ALU_OUT.

Finally, Immediately after the switch statement the EQ(), LT() and GT() functions are called.





BrainIO Program Memory