8 Bit ALU with Bit manipulation


So far, we have seen a few examples how to do arithmetic
with a one Bit CPU that wasn't designed to do arithmetic.

Now for some examples, how to use an 8 Bit CPU for Bit manipulation.

For instance, there is the famous/infamous 8031 (or 8051) family
of microcontrollers.

Famous when building a small programmable logic controller, because
the Carry Flag can operate a little bit like the Result Register
in our MC14500, although with less functionality...
Infamous when it comes to running C code, because there only is
one single 16 Bit pointer for acessing external memory,
but we're going off topic again.

Let's imagine we want to implement Bit manipulation
in our self_built 8 Bit TTL CPU.
The 8031 encodes the number of the Bit in a Byte to be addressed as
a part of the memory address, and I wouldn't recommend that approach.
For 68k, the number of the Bit is either located in a register,
or it is part of the instruction word.


Anyhow, we have 8 Bits to select, so we take a 74138 decoder,
which converts a three Bit number from our instruction word etc.
into an 8 Bit "bitmask".
Note, that the 74138 has low_active outputs, means that all Bits are 1,
except for the active/selected Bit, which is 0.

We then have to buffer the bitmask by a 74245 before feeding it
into the ALU, because there are also a few other registers that
connect to this ALU input.

Now an example how to set a Bit:

Let's suppose, that the Bit number is two, or binary 010.
The 74138 generates binary 11111011.
The ALU is configurated to invert this pattern to 00000100,
and then performs a logic OR with a Byte from memory,
which is overwritten by the result.
It's easy.


Clearing a Bit also is simple:

If the ALU is set to AND, the Bit in memory is cleared.


Now to toggle a Bit.
Means, if the selected Bit was 0, its set to 1.
And if the selected Bit was 1, it's set to 0.

The ALU is configurated to XNOR, means the bitmask from
the 74138 is inverted before we do XOR with memory.
Point is, when inventing one input of an XOR gate,
it turns into XNOR.


Maybe we are going to need two groups of SET, CLEAR, TOGGLE instructions:
Unconditional instructons that are always executed, and conditional
instructions tied to the status of a Flag, which might be useful
to emulate flipflops when running PLC code.

Now that we know how to manipulate a Bit in memory, we take care
about the problem how to get a Bit from memory into a Flag.

One approach would be, connecting a 74151 8:1 multiplexer to the
data bus, to extract the selected Bit and send it into sort of a
Flag/"Register".

But we're trying something more difficult instead:
First we generate the bitmask with the 74138, like binary 11111011 again.
We invert it inside the ALU to 00000100, and then perform a logic AND with
the Byte from memory, so the result would be either 00000000, or 00000100.

We now have to check, if the ALU output is zero, or something different.
Fortunately, we already had built sort of an 8_input NOR gate in our CPU
for all the other arithmetic/logic operations.

It usually woud directly connect to the Zero Flag, but we now place
a Logic Unit (LU) in between.
For the usual set of arithmetic/logic operations, the LU just passes
through the signal from the NOR gate.
But when we test a Bit in memory, this signal would be 1, when the Bit was 0.

Means, if we want to copy a Bit from memory into the Zero Flag, we would
have to configurate the LU to invert the signal.
You sure can imagine, how to read the complement of a Bit.

Always be aware about the polarity of the signal from the
zero detection logic when testing Bits. You also could use a 74688
comparator to test for zero instead of building an 8_input NOR gate.

And since we have a LU in there, we are able to perform any
logic operation there is between Memory and Zero Flag,
like with the MC14500.


Now to take care about how to write the Flag back into memory.

We know how to set and to clear a Bit, so we attach a 2:1 multiplexer
to the ALU, to make it switch between "set" and "clear" mode,
depending on the content of the Flag.
And the rest is simple...

When having a "write complement" instruction, we either need an XOR
to invert the signal from the Flag, or we somehow might exchange the
"SET" and "CLEAR" ALU configuration words before they enter the
2:1 multiplexer.


Another question is, if it's a good idea to use the Zero Flag
as a "Result Register" for logic operations.
For instance, when conditionally loading a timer etc. with a constant,
the Zero Flag might get corrupted, so it could be a good idea to use the
Carry Flag instead... or to be able to choose between Zero and Carry Flag
by software.

We also could spend a few thoughts on stack support.
If we happen to have a long/complicated set of logic equations, we might
consider that AND precedes OR, pretty much like * precedes + in arithmetic.

Most CPUs already have an instruction that pushes the status register
(which contains all the Flags) on stack, so we could think about having
an addressing mode to pop a Byte from stack for instructions that read
a Bit from memory to set/modify our "Result Register".

That's all for now.
On to part 4.


[HOME] [UP]/ [BACK] [1] [2] [3] [4] [5] [6] [7] [8]

(c) Dieter Mueller 2008

AltStyle によって変換されたページ (->オリジナル) /