# Theory

An arithmetic logic unit (ALU) is a component that performs operations on (usually) two or more sets of inputs, and outputs results. The operation performed is designated by an `Operation`

signal.

# Design

Our ALU will start simple, and we’ll add more operations over time. First, let’s build an add/sub unit. I already have an adder, which can be used to subtract by swapping some signals: In single-rail (standard) logic, to subtract instead of add, the second input to the adder is inverted and the carry bit is set – in NCL, we invert the input by swapping `DATA0`

and `DATA1`

.

The swapper operates as the following equations

output.0 = input.0*swap.0 + input.1*swap.1 output.1 = input.1*swap.0 + input.0*swap.1

These can be implemented with THxor0 gates:

output.0 = THxor0(input.0, swap.0, input.1, swap.1) output.1 = THxor0(input.1, swap.0, input.0, swap.1)

Our add/sub module will have these on every bit on input to the adder, with iC having the `swap`

signal fed directly into it. `Swap`

will be exposed in the component’s port as the add/subtract selector:

Green is `iA`

, blue is `iB`

, and red is `iC`

on the Adder. If `Control`

is asserted (`DATA1`

) `iB`

will be inverted and the carry in will be asserted as well, resulting in subtraction.

This module actually fulfills the interface of an ALU by itself, it has data inputs, and a opcode. When we add more operations, we’ll wrap it all up in a ALU block and add a MUX.

# Implementation

To implement this in VHDL, we need 1 Adder module and `2*N`

`THxor0`

gates:

use ieee.std_logic_1164.all; use ieee.numeric_std.all; use work.ncl.all; entity AddSub is generic(NumBits : integer := 4); port(iA : in ncl_pair_vector(0 to NumBits-1); iB : in ncl_pair_vector(0 to NumBits-1); Operation : in ncl_pair; oS : out ncl_pair_vector(0 to NumBits-1); oC : out ncl_pair); end AddSub; architecture structural of AddSub is -- iB into adder, potentially inverted from entity input signal adder_iB : ncl_pair_vector(0 to NumBits-1); begin plainAdder: Adder generic map(NumAdderBits => NumBits) port map(iC => Operation, iA => iA, iB => adder_iB, oS => oS, oC => oC); bits: for iBit in 0 to NumBits-1 generate inverter0: THxor0 -- DATA0, Potentially inverted port map(A => iB(iBit).DATA0, B => Operation.DATA0, C => iB(iBit).DATA1, D => Operation.DATA1, output => adder_iB(iBit).DATA0); inverter1: THxor0 -- DATA1, Potentially inverted port map(A => iB(iBit).DATA0, B => Operation.DATA1, C => iB(iBit).DATA1, D => Operation.DATA0, output => adder_iB(iBit).DATA1); end generate; end structural;

# Testing

The 2-bit case above is a little small, but it runs quickly. I have tested the module up to 6 bits. To change the number of bits, change the number at the top of the test script. The first several cases (interpreted to decimal):

`0+0=0`

`0-0=0`

`0+1=1`

`0-1=-1`

`0+2=2`

`0-2=-2`

This test script does check the sum output, but it does not verify the carry out.

*Commit: 55d8c9f*