ALU on logic chips

Hello everyone! I continue a series of posts about my computer based on logical microcircuits. The only processor module left unattended so far is ALU, about him and will be discussed today.

Requirements

ALU accepts the following signals as input:

  • A, B – operands, each with 8 bits.

  • OP – operation code, 4 bits.

  • Cin – old saved carry flag, 1 bit.

  • Inv – flag of swapping operands, 1 bit.

  • OE – activation of the output buffer.

Output signals:

  • R – result, 8 bits.

  • Z – zero flag, 1 bit.

  • C – carry flag, 1 bit.

  • S – sign flag, 1 bit.

  • O – overflow flag, 1 bit.

There are no clock signals, that is, the ALU is asynchronous: the values ​​at the output are updated as soon as the signals at the inputs change.

Operations

Four bits of the opcode give 16 operations, where the entire “gentleman’s set” of arithmetic fits in and there is still room for one more strange operation:

  • MOV – copying;

  • ADC, ADD – addition (with and without transfer);

  • SBB, SUB – subtraction (with and without overshoot);

  • INC, DEC – increment and decrement;

  • NEG – sign change;

  • NOT – bit inversion;

  • SHL, SHR, SAR – shifts by one bit;

  • AND, OR, XOR – bitwise logical operations;

  • EXP – the stored carry flag applies to all bits of the result.

First version

When I started making the processor, I wanted not to spend too much time on ALU and rather get a working version, so I made the first version using tables in ROM. The simplest option would be like this:

All input signals are fed to the ROM input, and output signals are removed from the output. Need to only 222 = 4M words of 12 bits. I didn’t have such a microcircuit, so I had to invent something, and I came up with this:

It uses two microcircuits, 32k words each. The left one is responsible for the least significant 4 bits, and the right one for the most significant ones. Green and red lines convey information up or down. Transmission up (green line) is needed, for example, when adding, to transfer the carry from bit 3 to bit 4, and down (red), respectively, when subtracting. To avoid oscillations (the left microcircuit transmitted the right, the right left, and so on in a circle), these lines are run through a logical AND with the most significant bit of the operation. Thus, operations that transmit information “up” (addition, shift to the left) can be encoded only with codes from 0 to 7, and those transmitting information “down” (subtraction, shift to the right) – from 8 to 15.

What happened
The first version of ALU
The first version of ALU

Second version

Using ROM is cheating, so it was necessary to make the second version entirely on logical microcircuits. The general scheme of the ALU is as follows:

Operands A and B are fed to the multiplexer, which swaps them if the input Inv unit. Depending on the opcode, one of the OP1-OPn blocks is activated and supplies a value to the output bus, while the rest keep their outputs in a high resistance state. A microcircuit is used as the output buffer of each block. 74ACT244

Implementation of simple operations

The simplest operation is EXP… You just need to submit Cin to all inputs of the corresponding output buffer.

Shifts (SHR, SAR, SHL) are also simple: the lines of the operand are fed to the inputs of the buffers with mixing one bit in one direction or the other.

For logical inversion NOT you can use the 74ACT240 chip, which is similar to the 74ACT244, but has inverting outputs.

Bitwise logic operations can be performed on a pair of 74AC08 chips for AND and 74AC32 for OR (plus buffer 74ACT244, of course).

Adder

There are nine operations left. Eight of these can be expressed using addition or subtraction:

  • ADD A, B = A + B

  • ADC A, B = A + B + c

  • SUB A, B = A - B

  • SBB A, B = A - B - c

  • INC A = A + 1

  • DEC A = A - 1

  • NEG A = 0 - A

  • MOV A, B = B + 0

To implement all of them, a universal adder must be able to:

  • add and subtract;

  • add a carry bit to the second operand;

  • instead of any of the operands, substitute zero (you need to NEG and MOV);

  • substitute one for the second operand (for INC and DEC);

  • change the order of the operands.

The reordering of the operands has already been implemented by the input multiplexer.

Replacing the operand with zero is also implemented by the input multiplexer: in microcircuits 74AC157, of which it consists, there is an entrance E, at a high level at which the outputs of the microcircuit will be zeros.

To replace the second operand with one, you can replace it with zero (we already know how to do this), and send one to the least significant bit. This can be easily done by passing the least significant bit through a logical OR:

It remains to make an adder that can add and subtract. Let’s start with the classic full adder circuit:

Full adder
Full adder

Full adder calculates the sum of three bits A + B + c… The truth table of the full adder is as follows:

A   B   c  |  R  c_out
0   0   0  |  0  0
0   1   0  |  1  0
1   0   0  |  1  0
1   1   0  |  0  1
0   0   1  |  1  0
0   1   1  |  0  1
1   0   1  |  0  1
1   1   1  |  1  1

Now let’s build a truth table for subtraction A - B - c and compare:

A   B   c  |  R  c_out
0   0   0  |  0  0
0   1   0  |  1  1
1   0   0  |  1  0
1   1   0  |  0  0
0   0   1  |  1  1
0   1   1  |  0  1
1   0   1  |  0  0
1   1   1  |  1  1

Tables differ by column c_out… To convert an adder into a subtractor, you can add two inverters to the circuit:

But we need to be able to dynamically turn the adder into a subtractor. To do this, the inverters must be turned off, and the turned off inverters are XOR:

Now if at the entrance sub zero, the output of the circuit will be the sum, and if one is the difference. It remains to note that this circuit also computes the exclusive OR A and B – last unrealized ALU operation:

Next, we combine the resulting cells into a chain by starting c_out previous bit on c next.

Adder chain

In total, 14 microcircuits are needed for the adder, not counting the multiplexer, buffers and the OR element that supplies one to the least significant bit of the second operand.

Flags

In addition to the result of an arithmetic operation, the ALU must also issue flags that inform about the properties of the result.

The S (sign) flag is the simplest. This is just the most significant bit of the result.

The Z flag (zero) is computed as the inverse logical OR of all bits of the result.

Scheme

The C (carry) flag is the exit c_out the most significant bit of the adder in the case of addition and subtraction, or the “extra” bit of the operand for shifts.

Scheme

The O (overflow) flag is the result of exclusive OR carries from the two most significant bits of the adder. You can read more about carry and overflow flags. here

Scheme

Result

Board of the second version of ALU
Board of the second version of ALU

The board did not work out very well. Sometimes everything worked well, and sometimes there was some kind of high-frequency noise on all lines, including the power supply, which interfered with the operation of the entire computer. Now I have two versions of why there was interference:

  • firstly, I did not put capacitors next to the power legs of each microcircuit, but just scattered a few around the board;

  • secondly, the 74ACT series tends to give tips because of its sharp fronts.

I made the following boards with this wisdom in mind (capacitors for each microcircuit are visible on the red board of the register module on the right), and I corrected the ALU literally by typing. I ran a test program that was guaranteed to have interference and put my finger on different parts of the ALU board. It turned out that if you keep your finger on the foot 1 U36, the interference disappears. Everyone knows that a human is just a big capacitor, so I soldered a 10pF capacitor between this leg and ground, which fixed the problem.

Similar Posts

Leave a Reply

Your email address will not be published. Required fields are marked *