Your First Computer: Difference between revisions
Lawrziepan (talk | contribs) Wrote the opening of the guide |
Lawrziepan (talk | contribs) m →Example Program: made comments all aligned |
||
(6 intermediate revisions by 3 users not shown) | |||
Line 1: | Line 1: | ||
{{stub}} | |||
[[ | If you're a new player, you might have already built a few circuits already: an [[Full Adder|adder]], some kind of memory, a [[decoder]]. But getting to the next level where you have a functioning and [https://en.wikipedia.org/wiki/Turing%20completeness turing complete] computer, is incredibly daunting. This article will serve as a guide to how you might build your first computer. | ||
== Planning The Computer == | |||
[[File:Computer Structure diagram.png|300px|right|thumb|The structure of the computer in this article]]While you might be inclined to jump head first into building, this results in at the very least messy building in Logic World, or a malfunctioning computer. In our computer we are going to first plan and '''document''' the capabilities our computer will have. | |||
* | |||
To start with the planning section, it helps to think about what this computer we are building is for. This could range from wanting to test out an [[wikipedia:Arithmetic_logic_unit|ALU]] you built, or to perform a specific program you have in mind, e.g. matrix multiplication. | |||
In this guide, our computer will be built as a way to learn each of the different parts of a computer, without any bells or whistles. So, we are going to give the computer the bare minimum. | |||
=== Data Width === | |||
Data width refers to how many bits the binary numbers in our computer will use. This doesn’t have to be universal across an entire computer; for example, the memory might store in 32 bits, but our ALU only 16. In our computer however, we will use the same data width across our entire computer. While you can definitely go smaller, 8 bits is a good number to make it less complicated while being able to do a lot with our computer, so our data width is going to be 8 bits. | |||
=== The ROM === | |||
The read only memory in our computer is where we are going to store all of the instructions for our computer. We aren’t looking for anything too big, so to keep with our data width of 8 bits, we will have 2^8 or 256 addresses in our ROM (this only needs to be addressed with 8 bits). And each address will store 8 bits of data for our instructions. | |||
=== Instruction Set === | |||
This is the most influential part of planning. It’s tough for a beginner to get a feel for how to design an instruction set, and has the most impact on how easy it will be to build your computer. If you wanted to design a more advanced computer, you should design your own instruction set, and see how that influences your computer. | |||
Every instruction has an opcode that tells the computer what instruction you ''actually'' want it to perform. There are roughly 4 main types: | |||
* Data management. This involves moving data from one register to another, loading or saving to memory, or loading an arbitrary value into your registers, etc. | |||
* Operations. These instructions use your ALU to transform data in a specific way, e.g adding two registers or using bitwise logic. | |||
* Conditional logic. This is where jumps come into play. These instructions let you test registers against each other, and change the order the computer executes instructions based on tests. | |||
* Interrupts. While you generally wouldn’t find interrupts in a computer in Logic World, these let you talk to computer hardware, or call specific kernel functions (don’t worry if you don’t understand what that means, it isn’t important for this guide). | |||
With that, this is the instruction set we are going to base our computer around: | |||
{| class="wikitable" | |||
|+ | |||
!Name | |||
!Opcode (8 bits) | |||
!Opperands | |||
!Description | |||
|- | |||
|Immediate | |||
|00 xxxxxxxx | |||
|x: The immediate value. | |||
|Puts a value given by x into register 0. | |||
|- | |||
|Add | |||
|01 000___ | |||
| | |||
|Adds the values in register 1 and 2, and puts the result in register 3. | |||
|- | |||
|Subtract | |||
|01 001___ | |||
| | |||
|Subtracts the value in register 1 from register 2 and puts the result in register 3. | |||
|- | |||
|And | |||
|01 010___ | |||
| | |||
|Bit-wise ANDs the values in register 1 and 2, and puts the result in register 3. | |||
|- | |||
|Or | |||
|01 011___ | |||
| | |||
|Bit-wise ORs the values in register 1 and 2, and puts the result in register 3. | |||
|- | |||
|XOR | |||
|01 100___ | |||
| | |||
|Bit-wise XORs the values in register 1 and 2 and puts the result in register 3. | |||
|- | |||
|Not | |||
|01 101___ | |||
| | |||
|Bit-wise NOTs the values in register 1 and 2 and puts the result in register 3. | |||
|- | |||
|Move | |||
|10 xxx yyy | |||
|x: The register to move data from. y: The register to move data to. | |||
|Moves the data from register x into register y. | |||
|- | |||
|Test | |||
|11 000___ | |||
| | |||
|Tests the values in register 4 and 5 against each other, putting the result into the flags register. | |||
|- | |||
|Jump 0 | |||
|11 001___ | |||
| | |||
|Jumps to the instruction in register 6, if the 0 flag is {{On}}. | |||
|- | |||
|Jump carry | |||
|11 010___ | |||
| | |||
|Jumps to the instruction in register 6, if the carry flag is {{On}}. | |||
|- | |||
|Jump negative | |||
|11 011___ | |||
| | |||
|Jumps to the instruction in register 6, if the negative flag is {{On}}. | |||
|- | |||
|Jump equal | |||
|11 100___ | |||
| | |||
|Jumps to the instruction in register 6, if the equal flag is {{On}}. | |||
|- | |||
|Jump | |||
|11 101___ | |||
| | |||
|Jumps to the instruction in register 6, regardless of an flags. | |||
|} | |||
===Registers=== | |||
We will use 8 all-purpose registers, because of the 3-bit limit imposed by the Move instruction. Note that the program counter and instruction register is seperate to these all-purpose registers, so our program will not be able to ''directly'' edit the values in these registers. | |||
=== Flags === | |||
We will only have 3 flags in our computer, as can be seen in the instruction set: | |||
* 0 flag. This flag will be {{On}} only if the first value from the last test instruction was equal to 0. | |||
* Carry flag. This flag will be {{On}} only if that last add (or subtract) instruction carried/overflowed. | |||
* Negative flag. This flag will be {{On}} only if the first value from the last test instruction was negative (had its most significant bit {{On}}). | |||
* Equal flag. This flag will be {{On}} only if the values from the last test instruction were equal to each other. | |||
=== Example Program === | |||
This will show our instruction set using a fibonacci program. | |||
<syntaxhighlight lang="asm"> | |||
; Initialise registers | |||
Immediate 0 ; 00 000000 | |||
Move 2, 0 ; 10 000 010 | |||
Immediate 1 ; 00 000001 | |||
Move 1, 0 ; 10 000 001 | |||
; | |||
; Main loop | |||
Add ; 01 000 ___ | |||
Move 2, 1 ; 10 001 010 | |||
Move 1, 3 ; 10 011 001 | |||
Immediate 5 ; 00 000101 | |||
Move 6, 0 ; 10 000 110 | |||
Jump ; 11 101 ___ | |||
</syntaxhighlight> | |||
{{Todo|I will expand this article later}} |
Latest revision as of 13:40, 14 September 2025
If you're a new player, you might have already built a few circuits already: an adder, some kind of memory, a decoder. But getting to the next level where you have a functioning and turing complete computer, is incredibly daunting. This article will serve as a guide to how you might build your first computer.
Planning The Computer

While you might be inclined to jump head first into building, this results in at the very least messy building in Logic World, or a malfunctioning computer. In our computer we are going to first plan and document the capabilities our computer will have.
To start with the planning section, it helps to think about what this computer we are building is for. This could range from wanting to test out an ALU you built, or to perform a specific program you have in mind, e.g. matrix multiplication.
In this guide, our computer will be built as a way to learn each of the different parts of a computer, without any bells or whistles. So, we are going to give the computer the bare minimum.
Data Width
Data width refers to how many bits the binary numbers in our computer will use. This doesn’t have to be universal across an entire computer; for example, the memory might store in 32 bits, but our ALU only 16. In our computer however, we will use the same data width across our entire computer. While you can definitely go smaller, 8 bits is a good number to make it less complicated while being able to do a lot with our computer, so our data width is going to be 8 bits.
The ROM
The read only memory in our computer is where we are going to store all of the instructions for our computer. We aren’t looking for anything too big, so to keep with our data width of 8 bits, we will have 2^8 or 256 addresses in our ROM (this only needs to be addressed with 8 bits). And each address will store 8 bits of data for our instructions.
Instruction Set
This is the most influential part of planning. It’s tough for a beginner to get a feel for how to design an instruction set, and has the most impact on how easy it will be to build your computer. If you wanted to design a more advanced computer, you should design your own instruction set, and see how that influences your computer.
Every instruction has an opcode that tells the computer what instruction you actually want it to perform. There are roughly 4 main types:
- Data management. This involves moving data from one register to another, loading or saving to memory, or loading an arbitrary value into your registers, etc.
- Operations. These instructions use your ALU to transform data in a specific way, e.g adding two registers or using bitwise logic.
- Conditional logic. This is where jumps come into play. These instructions let you test registers against each other, and change the order the computer executes instructions based on tests.
- Interrupts. While you generally wouldn’t find interrupts in a computer in Logic World, these let you talk to computer hardware, or call specific kernel functions (don’t worry if you don’t understand what that means, it isn’t important for this guide).
With that, this is the instruction set we are going to base our computer around:
Name | Opcode (8 bits) | Opperands | Description |
---|---|---|---|
Immediate | 00 xxxxxxxx | x: The immediate value. | Puts a value given by x into register 0. |
Add | 01 000___ | Adds the values in register 1 and 2, and puts the result in register 3. | |
Subtract | 01 001___ | Subtracts the value in register 1 from register 2 and puts the result in register 3. | |
And | 01 010___ | Bit-wise ANDs the values in register 1 and 2, and puts the result in register 3. | |
Or | 01 011___ | Bit-wise ORs the values in register 1 and 2, and puts the result in register 3. | |
XOR | 01 100___ | Bit-wise XORs the values in register 1 and 2 and puts the result in register 3. | |
Not | 01 101___ | Bit-wise NOTs the values in register 1 and 2 and puts the result in register 3. | |
Move | 10 xxx yyy | x: The register to move data from. y: The register to move data to. | Moves the data from register x into register y. |
Test | 11 000___ | Tests the values in register 4 and 5 against each other, putting the result into the flags register. | |
Jump 0 | 11 001___ | Jumps to the instruction in register 6, if the 0 flag is ON. | |
Jump carry | 11 010___ | Jumps to the instruction in register 6, if the carry flag is ON. | |
Jump negative | 11 011___ | Jumps to the instruction in register 6, if the negative flag is ON. | |
Jump equal | 11 100___ | Jumps to the instruction in register 6, if the equal flag is ON. | |
Jump | 11 101___ | Jumps to the instruction in register 6, regardless of an flags. |
Registers
We will use 8 all-purpose registers, because of the 3-bit limit imposed by the Move instruction. Note that the program counter and instruction register is seperate to these all-purpose registers, so our program will not be able to directly edit the values in these registers.
Flags
We will only have 3 flags in our computer, as can be seen in the instruction set:
- 0 flag. This flag will be ON only if the first value from the last test instruction was equal to 0.
- Carry flag. This flag will be ON only if that last add (or subtract) instruction carried/overflowed.
- Negative flag. This flag will be ON only if the first value from the last test instruction was negative (had its most significant bit ON).
- Equal flag. This flag will be ON only if the values from the last test instruction were equal to each other.
Example Program
This will show our instruction set using a fibonacci program.
; Initialise registers
Immediate 0 ; 00 000000
Move 2, 0 ; 10 000 010
Immediate 1 ; 00 000001
Move 1, 0 ; 10 000 001
;
; Main loop
Add ; 01 000 ___
Move 2, 1 ; 10 001 010
Move 1, 3 ; 10 011 001
Immediate 5 ; 00 000101
Move 6, 0 ; 10 000 110
Jump ; 11 101 ___