The Mega-One-8-One ALU used in the DDL4-CPU is a gate level replica of the 74181 ALU. The 74181 actually support two modes of operation. The first being a "MATH Mode". When the Mode pin is set low, The ALU can perform 16 specific math functions. When the Mode pin is set high, then the ALU is in "LOGIC Mode". In this mode, there are 16 separate bitwise logic functions that can be performed. Due to the number of op codes being limited to 16 on this design, I had initially made the decision to not add an op code for the "LOGIC Mode". The initial Instruction Set Architecture (ISA) that I had created only included the Math functions with carry and without (see All Your ISA Belong to Me!). After doing the first revision on the design, I came to the conclusion that the jump and jump with flags could be optimized reducing the number of jump commands from 3 to 1 ( see Masking Jump Requests). This freed up two operation codes (OP code), one of which could be used for the ALU logic functions. However, I ran into another problem. Every single pin of my dual EEPROM microcode was being used. If I wanted to support the ALU logic functions, I would need to decode them outside of the EEPROM microcode, similar to what I had done with the jump and jump with flags. I needed a way to easily decode 3 OP codes:
MWC - Math With Carry
MNC - Math No Carry
LOG - Logic Function
The solution actually turned out to be simpler than I had expected. By reorganizing the ISA OP codes, I was able to place the ALU functions as the first three ops codes:
This meant that for MWC and MNC, the first three binary digits were zeros. All other combinations of OP codes would not have the first three binary digits as zero. This provides a simple clean way of decoding with a 3-input OR gate. Since I am already using 2-input OR gates on the design it was easier to just implement the 3-input OR gate with two 2-input OR gates:
This simple hardware solution has expanded the capabilities of the DDL4-CPU tremendously by add 16 new logic functions. Of course, as a hardware decode solution, it has trade-offs as compared to implementing it in microcode. With microcode, if I want to change the overall design, I simply flash it with new microcode. If I want to change this ALU Mode implementation, it has to be done with new hardware. This has implications for real world problems such as those with the recently discovered CPU bugs Meltdown and Spectre. Since the core issue of these bugs are part of the physical hardware implementation, and not part of the microcode, they can't be easily fixed by producing new microcode.
As a side note, as I am working through these issues of optimization of the design, I've had a strong sense of connection with those pioneers of the 1970's and 1980's creating new microprocessor and microcontroller architectures. I now understand a lot more about how and why these developers went to such great lengths to "save one signal" or optimize their ISA with "weird" commands and groupings....