main go back

16b1x CPU

date: 2022-02-22 (yes, single day)
desc: first CPU ever done, HEAVILY inspired by UCB CS61C, contains massive mistakes and bad design decisions
proj: https://github.com/sarvl/16b1x




Table Of Contents

  1. Overview
  2. ISA
  3. The Good
  4. The Bad
  5. The Ugly


OVERVIEW

schematic
full image


As the name suggests, it is 16bit CPU.
The ISA is very simple and does not even utilize all space for instructions.
Design is pretty much copycat of what was shown in course because that was all I knew at that time. It was simple enough to get everything working without thinking about design too much, this was never again possible in the future.
Instruction and data memory are separated so every instruction takes exactly 1 cycle.

CPU was implemented in logisim and I was assembler for longer than I would like to admit before writing proper one in c++.

ISA

Instructions

Instruction Format

r-format
	15    12 11  8 7   6 5      0
	[OPCODE] [Rd ] [Rs ] [UNUSED]
		
i-format
	15    12 11  8 7    0 
	[OPCODE] [Rd ] [IMM8] 
		
note: ^ this is wrong, see THE BAD

Registers

all are 16bit

Example Program


	mvi 	A, 0x0
	mvi 	B, 0x1

#(n + 2)th fib number
	mvi 	E, 0x5
#to be able to subtract one
	mvi 	F, 0x1

LABEL loop
	#C = A + B
	mvr 	C, A
	add 	C, B

	#A = B
	mvr 	A, B
	#B = C
	mvr 	B, C

	#M[0] = C
	str 	C, ZERO

	#E -= F
	sub 	E, F

	jnz 	E, loop

		

THE GOOD

The very best thing is that it works.

It is hard to find any other thing that is noteworthy good. At the time I was proud of using mux to select correct control signals instead of combinational logic. Later I realized that not only this is quite common, I should've used ROM component directly.


THE BAD

The worst thing in this design is that somehow a bit was skipped.
Instruction format shown previously has bits 11:8 assigned for Rd, it is 4 not 3, Rs has bits 7:6, it is 2, not 3. Correct thing would be Rd - 11:9, Rs - 7:5. For r-format it's not so bad as total bit count stays the same, but immediate has wasted bit for no reason. Since r-format and i-format have unused bits then this additional bit could be used to select between reg/immediate as second operand and it would be way more convientient to code. Later designs fixed this issue in exactly this way.
I became aware of this while wiring control, I was tired already so I decided that I do not care.

Zero register is completely useless and terribly inefficient idea for cpu with 8 registers in total.
It was kind of needed because of lack of immediate operand for every instruction (see paragraph above). Nonetheless, if it was needed then simple mvi Rd, 0 would suffice and would not waste a register.


THE UGLY

ISA mentions SP but it was not used.
Similarly local isa.txt mentions memory regions but it was never implemented.

Seperated data and instruction memory was ok at that time but was suboptimal and later designs changed it.
//In fact, main goal of the 2nd iteration was to unify memory and fix terrible mistakes here.

0x0000 should not have been mvr Z, Z becaues of NOP slide.
Unfortunatelly I became aware of this fairly recently /*as of writing this post*/ and so next 2 designs also feature this problem. This is not that bad for architecture that was not designed for serious use which is why it's in this section and not THE BAD.

main go back