The one and only, Whiskerss
What’s a thing you have made which demonstrates sufficient engineering knowledge?:
I have made a turing complete 8-Bit, 4-stage pipelined CPU.
10t Clock (1Hz)
4 Stage latched pipeline : Fetch | Decode | Execute | Writeback
5bit opcode | 3bit operand
1op architecture (ACC based) Pure harvard
7 Registers, lower 5bits used for: indirect PC addressing, indirect RAM addressing, indirect ROM addressing(reg7 is used for rom address)
10Bit PC (5bit lower[iCache] | 5bit upper[ROM])
1KiB ROM (32 bytes per page, 32 pages)
32Byte RAM (addressed indirectly by reg pointer)
26 instructions | 3 flags [0, COUT, LSB] - 8 Conditions: EVEN-EQ-NEQ-LT-GT-GTEQ-LTEQ
Barrel Shifter (made by Qsmally) implemented for right shift and left shit (overflow and underflow detection has not been implemented)
8 IO ports. Signals: Acknowledge | Request | Sending Data is optional and can be implemented easily for different programs
32Byte dummy screen (shows what’s in RAM and updates with memory store) (also this is optional, but it is useful for sorting algos)
BRC and ICS stall for 1 cycle for condition checking, MLD stalls for 1 cycle due to memory speed
Hazards can be taken care of by inserting NOPs in assembly. Or can be used as “features” as I like to call them. (Forwarders not included)
CPU haus included (thanks to Hyperholy)
This CPU is incredibly compact.
What engineering work went into designing this device?:
I aimed for Carbon’s clock speed to be 8t (1.25 Hz), but after lots and lots of debugging, 2t were added to the clock due to timings. I initially wanted Carbon to be a compact and simple CPU while still running complex programs. QCPU and BlackBoxV2 both inspired me to build Carbon since QCPU was compact, and BlackBoxV2 was simple.
Carbon’s Main Stages in Construction
Carbon had 5 stages in mind:
- Stage 1: Which took a week or so
- Stage 2: Which took hella 4 months
- Stage 3: 3 months god damn
- Stage 4: 4 months
- Stage 5: Here we are :DD
Stage 1: Constructing the Components and putting them together
Stage 2: Wiring all instructions to those components while adding more components and fixing them
Stage 3: Pipelining Stage 2 while fixing Stage 1
Stage 4: Debugging the entire CPU while fixing Stage 2 and Stage 3 and adding more components
Stage 5: Publishing Carbon (Well here I am ;))
Carbon’s Construction || The Dataloop
I first began with the dataloop. I planned in mind that the dataloop must meet the speed requirements of carbon, (trying to keep it 8t). I’ve actually had Kuggo’s dataloop in my stock collection consisting of: ALU – 7Registers – ACC. and I wired the flags 0, LSB, and COUT later.
Later then, I added a barrel shifter so that programs that would require bit shifting would become useful. I decided to use Qsmally’s barrel shifter.
To take care of data hazards, it wasn’t that easy. Because of Carbon’s spaghetti wiring and claustrophobic insides, it was almost impossible to add forwarders and forwarding logic in the given amount of space. So Carbon was going to sustain hazards by adding NOPs into the program. Or, the user can tend to use them as features
I also added 32 Bytes of RAM. Like I said, I wanted Carbon to be simple. I made it so that RAM would be addressable by register pointers (lower 5 bits) of any register of user’s choice. Reading from RAM stalls for 1 cycle (This is because of the latency from the ram busses and pointer output for the address. I didn’t take it into consideration, but I plan for my next CPU to overtake this). I also added 8 IO ports including 2 signals: acknowledge & request (sending data[optional but could be implemented easily]) for communication between the CPU and the user or other external parts. PS the IO ports were designed by me :DD
Carbon’s Construction || The Control Unit
I decided to implement an iCache holding 32 Bytes per page, still taking into consideration that Carbon needed to be simple, but I thought that it should wrap around people’s heads and the idea was noticeable. This allowed me to swap pages every 32 Bytes of a large program. I also decided to use Qsmally’s Hex->Bin converter.
I planned out that Carbon will have snek towers for the decoder. Carbon consists of 26 OPCODES, so that will mean 26 snek towers (Some extra snek towers are there just for other control wiring for faster results). Since Carbon had very scarce space, I decided to directly wire the instructions to the components instead of encoding them into control wires.
For the PC, I made a lower-PC and an upper-PC. The lower-PC will be in charge of controlling the iCache’s lines (5bit lower-pc, 32 lines). And the upper-PC will be in charge of controlling the ROM’s pages (5bit upper-pc, 32 pages) to branch to the PC, I made it so that the cpu will use BRC (branch) and a condition including JMP (Jump). (It was SomeoneNotYou’s idea to remove the JMP instruction and insert it in BRC’s conditions since it was the exact same thing as an unconditional branch) so BRC will take the upper 5bits of the 2nd Byte of the instruction (next cycle) and disable instruction decoders so that the upper 5 bits of the instruction length can go through the decoder, and straight into the PC through an “allow address to pc” controller. It will allow the address only if the condition was true. Also if the condition was true then BRC will disable iCache’s output or fetch entirely to prevent the next instruction from executing. The PC also supports in-direct addressing (JID) of any reg[x]
This ROM took me about 1 month to debug in Carbon. (SomeoneNotYou helped but plan failed so I did another plan). The ROM size itself is 1KiB (1,024 B - 1.024 KB) Which is 32 pages x 32 lines. For addressing the ROM, I use a lower 5bit pointer from reg. When doing ICS (iCache Swap) and give it a condition, it will stall for 1 cycle (condition checking) and if the condition is true, then it will read reg, allow branch address, branch upper-PC, Set page, and then ICS takes a 2nd byte for line addressing to the lower-PC, so it will take the same condition as the page swap did, disable fetch or iCache reads (This is to prevent the next instruction from going into decode-execute… If the condition was true.) branch the lower-PC, and set line to given address.
After all of that work, Carbon was capable of running (these programs are ranked from worst to best):
– Incrementing program
– Decrementing program
– Addition program
– Fibonacci program
– 2-Player Number Guessing Game
– 16-bit Addition ( It can be expandable to 24, 32, etc… due to the usage of ADC(Add with Carry))
– Controllable Ball ( Up-Down-Left-Right-UpRight-UpLeft-DownRight-DownLeft )
– Collatz Conjecture program
– Bubble sort (8B - 16B - 32B) program
– Bouncing ball (16x32 screen) program
– Bresenham’s line drawing program (1 octant, but carbon can do all with enough programming >:])
– 1Player Pong Game program
– 2Player Pong Game program
Carbon can obviously run a lot more programs than these with 1KiB of ROM. Although I’m not really that good of a programmer lol
Image/s and/or video/s of the device:
Carbon by itself:
Program Videos/Screenshots (This shit is rly cool):
^ Controllable Ball
^ Bouncing Ball
^ Collatz (Without Screen, raw binary)
^ Collatz (With Screen)
^ 32B Bubble Sort on reversed array
^ Bresenham’s line drawing algo (1 octant)
^ 1P Pong Game
^ 2P Pong Game
For the future, I plan on making Carbon Dioxide which will be 10x more powerful than Carbon.
And I’m sure that Carbon can run way more programs than these examples with more dedication in programming. (1,000 lines of code is a lot u know xd, 2 player pong was like 5/32 of carbon’s ROM capacity)
Overall, Carbon took me almost a year to complete ( Life sometimes got in the way ). And it would be an honor to be an engineer in a server which has changed my life. (Video dropping soon for carbon let’s focufkingg goo!!).
---------------------------------------------------------------- Credits ----------------------------------------------------------------
- emm - Assembler
- MNbiom - Schematic generator
- SomeoneNotYou - Helping with plans and solutions
- drzxcv, Firetner, Aminotreal, Powsi, Qsmally - Wiring in small spaces
- Kuggo, _rzecz, TosinV1, AlexEnderKat, Analyzers - Being there for me when I needed it