The Ita ISA
Roots
When I first start to think of the ISA for my computer I quickly decided
that I wanted an instruction set that was simple (perhaps overly so) with
the hope that it would be easier to implement in VHDL.
I previously read Elements of
Computing Systems and was quite amazed by the simplicity of the "Hack" CPU
that was introduced. The ALU used by my computer is very similar to the
ALU described in the book/course. If you look at the design of my CPU it
shares many similarities with the Hack CPU. However I have extended it
in a few ways to be more powerful and allow some operations to be done
more efficiently. I have also eliminated some features of the processor
that aren't really necessary in my ISA.
Overview
The CPU I designed has the following features
- 32x32bit registers
- 32bit address space
- Conditional execution of instructions
- A very "RISC" design
It's also interesting to note features that the system does not have.
- An MMU
- Complex instructions (e.g. multiply or divide)
- Support for interupts
The general philosophy is to keep the hardware as simple as possible and
move complexity into software where possible.
Registers
The processor has 32 separate 32bit registers. Some of these registers
have special purposes, but all registers are essentially accessed in similar
ways.
Register | Name | Description |
r0 | Immediate Register | The immediate register is set to the value of the immediate field of the currently executing instruction. |
r1 | Address Register | The address register can be implicitly modified by an address instruction. |
r2 | Memory Register | The memory register is used to read an write from memory. Reads or writes to the memory register will implicitly dereference the address register.. |
r3 | PC Register | The PC (program counter) register keeps track of the address of the next instruction to be loaded/executed. |
The remaining registers don't have any special meaning as far as the hardware
itself is concerned. Of course the software running on the CPU may choose
to assign special meanings to certain registers. For example the compiler
uses r4 to point to the current stack frame.
Instruction Set
The Ita instruction set consists of two types of instructions. The type of
instruction is determined by the most significant bit of the instruction.
If the bit is zero then the instruction is an address instruction,
and if it is one the instruction is a command instruction.
Address Instructions
Address instructions are very simple. When an address instruction is
encountered, the value of the instruction is written to the address register.
Address instructions may not be executed conditionally (i.e. they will
always execute).
Since the address instruction needs to have the msb set to zero, the
instruction may load a 31 bit value. No sign extension of the value is
performed.
Command Instructions
The command instruction has the following form:
bit position |
31 |
30 |
29 |
28 |
27 |
26 |
25 |
24 |
23 |
22 |
21 |
20 |
19 |
18 |
17 |
16 |
15 |
14 |
13 |
12 |
11 |
10 |
9 |
8 |
7 |
6 |
5 |
4 |
3 |
2 |
1 |
0 |
|
1 |
ALU Flags |
Dest Reg. |
Src0 Reg. |
Src1 Reg. |
Condition Flags |
Immediate Value |
ALU Flags
The ALU flags control the operation performed by the ALU. At its core
the only basic operations the ALU can do is add, AND or shift right.
However through clever use of bitwise negation it can be made to subtract,
OR and perform other operations.
Position | Name | Description |
30 | Negate Src0 | Performs a bitwise negation of the Src0 input register. |
29 | Negate Src1 | Performs a bitwise negation of the Src1 input register. |
28 | Negate Result | Performs a bitwise negation of the output of the ALU. |
27 | Function Select | Controls whether inputs are added or AND'ed together. |
26 | Shift Right | Controls whether a sign extending shift right of the ALU output is performed. |
Dest/Src Registers
The 5bit values for dest, src0 and src1 registers are used to indicate
what registers should be used as input to the ALU, and what register should
be assigned the result of the ALU operation.
Condition Flags
Command instructions are executed conditionally depending on the state
of the CPU's status registers. The condition flags are used to determine
if the command should execute.
Immediate Value
The immediate value field of the instruction is used to update the value
of the immediate value register. The instruction must use the immediate
register as either Src0 and/or Src1 for the immediate value field to be
useful.
The immediate value is treated as an unsigned 8bit value that is 0
extended to 32bits. However negative constants can be effectively achieved
by using a positive immediate value and then performing a bitwise negation
using ALU flags to create a negative value.
Position | Name | Description |
10 | Result Negative | Execute if negative flag is set |
9 | Result Zero | Execute if zero flag is set |
8 | Positive Result | Execute if positive flag is set |
Multiple flags may be set simultaneously. So it is possible to make instructions
execute when the last result was negative or zero (i.e. <= 0). Most
instructions have all the condition flags set so that they always execute.
Common Operations
Load/Store
Loading and storing from memory is accomplished by placing the address
in the address register and then loading or storing from the memory register.
Loading constants can be accomplished by using the address instruction
to move the constant into the address register.
Branching
Branching is accomplished by modifying the PC register. For example,
writing a constant to the PC register will branch to that address. A
relative branch may be performed by adding or subtracting a value from the
PC register and then storing the value back to the PC. For example:
PC = PC + offset
Conditional branches are performed by setting the appropriate condition
flags on the instruction that modifies the PC.
|