Categories DWMC-16

DWMC-16: Initial 16 bit ALU and some Dark Register Magic

Now that I got some instruction set design done, I believe it is time to use the initial 4 bit ALU design and build up an initial full sized 16 bit ALU design. That means dealing with all the flags that can be set by the ALU, as well as dealing with the additional instructions that cannot be implemented in the hardware of the initial 4 bit sliced ALU.

Full Size 16 bit ALU

Of course in the simplest design, all I need is to chain four existing ALUs one after the other, followed by combining/splitting the 16 bit inputs into the 4 bit wide busses needed by the smaller ALUs. The carry bits of the individual 4 bit ALUs then become their own Flags, $ QC $ (quarter carry), $ HC $ (half carry), $ TC $(three quarter carry) and $ C $ (carry). Equally simple is the $ EQ $ (equal) flag, which is simply the $ A=B $ output from the last 4bit ALU. The $ N $ (negative) flag is simply the extension of the MSB (bit 15) of the output, indicating whether the number on the output is signed or not.

The $ Z $ (zero) flag is only a tiny bit more complex, simply combining the $ O=0 $ (Output equal to zero) and $ A=0 $ (A equal to zero) with an OR gate.

The $ O $ (overflow) flag is more complex, as there are three states when an overflow occurs during addition or subtraction. During addition, it happens when the MSB flips, either from 1 to 0 or from 0 to 1. During subtraction, an overflow occurs if the MSB flips from 1 to 0. The logic used is simply $ O = \overline{SubMSB[A]}MSB[O] \vee MSB[A]\overline{MSB[O]} $.

The new instruction of Logical Swap Byte lsb Rd is dealt with by the ‘swap bytes’ in the logical diagram. To select the operation, I am using the free operation in OSel at 0b111, which only needs a simple three input AND gate to select on the new multiplexer on the output.

Finally, we have the new Logical Rotate Left/Right lrl/lrr Rd. Here, I need to be able to slip the carry from the last 4 bit ALU into the first directly. This is achieved by the $ Rot $ input, which is set to high when lrl/lrr are executed. A multiplexer in the path ensures that $ Ci $ is only used when lrl/lrr are not executed.

Dark Register Magic

Something that came up in a discussion on Discord after my last post, was that the Flag register could be used to nondestructively test whether a bit it set or not. By going a push/pop of the Flag register to the stack before/after doing the testing instruction. I feel it would be a possibility, but it’s a bit too dark of register magic for me. However, there is the potential to implement a pair of branch instructions to nondestructively check whether a bit is set inside a 16 bit word, operating on another register. The logic itself would just be a multiplexer operating on the Flag Register and the new register.

I decided it would be register R8. R8 was originally meant to be the number zero, but after some thinking, I came to the conclusion that the only place I needed the number zero, would be when I do increments or decrements. This means R8 would be a perfectly usable register, but it would still allow to run those tests on each bit.

New Register Layout

General Register Layout

RegisterRegister Label
R08BTTest Register
R09FFlag Register
R11,R10PCH, PCLProgram Counter
R13,R12SPH, SPLStack Pointer
R15,R14ZH, ZLZ Address Register

New Conditional Branch Instructions

CommandMnemonicOperationOpcodeAffected Flags
Branch if Flagbf F, Addrif (F == 0): PC <= Addr0b10000000/0x80None
Branch if not Flagbnf F, Addrif (F != 0): PC <= Addr0b10000001/0x81None
Branch if Bitbb B, Addrif (B == 0): PC <= Addr0b10000010/0x82None
Branch if not Bitbnb B, Addrif (B !=0): PC <= Addr0b10000011/0x83None
Branch if Zero, Decrementbzd Rd, Addrif (Rd == 0): PC <= Addr
else Rd <= Rd – 1
0b10000100/0x84C, Z, N
Branch if not Zero, Decrementbnzd Rd, Addrif (Rd != 0): PC <= Addr
else Rd <= Rd – 1
0b10000101/0x85C, Z, N
Branch if Registers Equalbreq Rs, Rs2, Addr if (Rs == Rs2): PC <= Addr0b10000110/0x86C, Z, N
Branch if Registers not Equalbrne Rs, Rs2, Addrif (Rs != Rs2): PC <= Addr0b10000111/0x87C, Z, N
Branch if greater thenbgt Rs, Rs2, Addrif (Rs > Rs2): PC <= Addr0b10001001/0x88C, Z, N
Branch if greater then or equalbge Rs, Rs2, Addrif (Rs >= Rs2): PC <= Addr0b10001010/0x89C, Z, N


For the time being, I hope this will be everything I have to do to deal with the ALU and the instruction set. But knowing myself, I might come up with another idea or two to revise either. I certainly expect someone to come up and point me to an error. Though, this is generally an initial design and I will have to write a few tests to test both the 4bit ALU and the full 16 bit ALU in the logical circuit simulator software I am using.

Leave a Comment