Monday 29 August 2016

A little more on the ALU

The ALU I discussed in the last episode works nicely as an ALU but does have a couple or three practical issues.

Multiplexors

The first is that pair of multiplexors in the middle of the arithmetic circuitry. In practical terms, they're easy to implement but bulky in terms of board area - each multiplexor requires two 8-wide tri-state buffers - twenty-pin wide packages. At least it is not necessary to implement a separate 8-wide inverter; an inverting buffer is available. But we can do a little better... consider an XOR gate's logic:

A B Q
0 0 0
0 1 1
1 0 1
1 1 0

The Q output is high only if both the A and B inputs are different. Looked at another way, though, it can be thought of as a controllable inverter. The output is B if the A input is low, and ~B if the A input is high (and of course the same using the A input to control B - it's symmetrical) which is exactly what we want. Using standard 74HC parts, that still needs two chips, but they're narrow and only fourteen pins each - much less board real estate is required.

That sorts out one of the multiplexors; what about the other? The first one that the B signal meets is doing nothing more than switching between the B input and zero. Here's an AND gate:

A B Q
0 0 0
0 1 0
1 0 0
1 1 1

Here the output is high if and only if both inputs are high. We can use the A input to control things here; if it's high, then the output is the B input. Thus we generate either our B input or zeros, in two 14-pin chips. But we  can do better...

We will need to put the B register through a buffer anyway - actually, the buffer will be the 'enable' output of the register latch. When the buffer is not enabled, the output is high impedance; it's pulling neither to the high or low level. If we apply some pull-down resistors on the output, then the input to the next stage of logic will be zero if the buffer is not enabled, or the contents of the register if it is.


A note about timing and clock signals

Throughout this discussion I have glossed over just how this processor will be clocked. Here's the basic idea:
  • a system clock called phase0 is fed with a square wave - an equal mark-space ratio.
  • When phase0 is low, a selected register's output is placed on an internal data bus. That register might be a simple register, or something more complex such as the ALU, or a value from external memory.
  • As phase0 rises, the internal databus contents are latched into a selected register.

The B input

The second point concerns the B input.

The accumulator needs two inputs and provides a single output, plus the flags. I'll implement this such that one of the inputs is internally latched - call it the B register - and the other is the internal data bus. Any operation takes two clock cycles: on the first, the B register is loaded and on the second the desired operation takes place using the internal bus as the A input; at the rising edge of the clock on the second operation the result and flags are latched.

The increment and decrement operations, which do not use the B register, take just a single cycle.

The Flags

We have only two flags on the ALU - zero and carry. We never need to read the flags directly (I'm not planning on implementing an interrupt function, where they would need to be stored unchanged across the interrupt) so they don't need multiplexing to the internal data bus; instead they'll have dedicated lines back to the control logic so that conditional jumps can be made.

The zero flag is set on every ALU operation; if the result of the operation is zero, the flag is set. The carry flag, on the other hand, is set only for the the arithmetic and shift operations - the logic operations don't affect it. A little glue logic enables it at the correct times. 

However, the carry flag must be set appropriately before addition or subtraction. This is done by two dedicated lines from the control logic. Since the carry flag is held in the ALU, the carry input can be connected directly to the carry output without a need for a direct input.

Finally, since the A and B inputs are valid at different times, we don't need two inputs and can join them together.

Here's the completed ALU. Note that on Logisim diagrams green lines are single bits - light for high and dark for low - and black lines are multiple bit buses.




No comments:

Post a Comment