Close

Adding an Unsigned Compare Function to Enable Wide Math

A project log for The Spikeputor

I am building a computer featuring a 16-bit RISC CPU made of discrete transistors for learning, fun and art. It will be pretty large.

spudfishscottspudfishScott 02/18/2019 at 21:490 Comments

As currently designed, the Spiekputor's ALU Compare functions worked with signed integers only. For whatever reason, the "Beta" processor from MITx, upon which the Spikeputor CPU was based, only included signed compares (so, for example, the number 0xC000 would be reported as less than 0x7000 because 0xC000 represents the signed integer -16384, rather than the unsigned integer 49152). This presents a problem if one desires to do math on numbers of a higher bit depth than the bit depth of the CPU registers and the ALU. To add two 32-bit numbers with a 16-bit ALU, for example, you need a way to calculate the carry after summing the lower 16 bits of the 32-bit numbers, then add that carry to the sum of the higher 16 bits. Calculating the carry can be done a variety of ways in code, but it comes directly by checking if the low order sum is less than either of the addends. Thus, an Unsigned Compare Less Than function would be a great addition to the ALU commands. Luckily, it was fairly easy to add the new compare function by expanding the Compare module, which simply subtracts one operand from the other and reports a result based on logic with (Z)zero, (N)egative, and o(V)erflow flags. Adding one more compare function (CMPUL for CoMPare Unsigned Less-than), and bringing in the Carry Out from the Bit 15 adder, as shown below, does the trick.

Previous Compare Module:

New Compare Module:

This change adds just four transistors to the circuit (converting a MUX3 to a MUX4 and inverting Cout[15]), and now, the Spikeputor will be able to easily do math on numbers arbitrarily larger than 16 bits. A very small price to pay, indeed!

Discussions