ZINQ Processor
A simple single-cycle 16-bit processor designed for educational purposes. Written in VHDL.
Running and Testing
For the simulation process, the supported method is to use Parvaj (which makes use of GHDL and GtkWave). You can also use well-known possibly-commercial tools (like Xilinx ISE), but you're completely on your own.
First, clone the project with all its dependencies:
git clone https://github.com/Kiarash-Parvizi/ZINQ-Processor --recursive
Now, you need to initialize Parvaj. Install the requirements specified here, and then do the following:
composer install -d scripts/parvaj/
Everything is ready. Deep dive into simulating the project:
./scripts/parvaj/bin/parvaj simulate test_main --waveform=vcd
Note: This could take a while (about 2 minutes on my personal system).
Boom! You can now see a simulation of the processor. Dig into the source code and learn more!
Testing Other Entities
Almost all entities are well-tested and for each, a unit-test (i.e. test-bench) is written. Feel free to simulate those tests as well.
For instance, if you want to test the controller alone, run:
./scripts/parvaj/bin/parvaj simulate test_controller
Note: The process should work on all Linux distributions, and other Unix variants. Windows users might be able to simulate as well, however it's not guaranteed.
Note: If the simulation process takes forever, you should either use --stop-time=1ns
(prevent to run infinitely), or --waveform=vcd
. In latter case, the reason is sometimes the default GHW waveform output format causes GHDL to hang.
The Design
Every processor has an instruction set and instructions format (defined as layout of bits of instructions). These two defines what the processor features and how it can be used (e.g. by a compiler). However, these are only definitions, and they have to be actually implemented.
In a simple realization, ZINQ processor divides into two separated but connected datapath and controller entities. They are first designed conceptually and visually, and then implemented in VHDL, making the design process simple.
In the datapath, we have two register files named as Main and Bank. The main has 8 registers and the bank has 4.
Keep going for more details.
Instructions Format
ZINQ processor has four types of instructions, Z-type, I-type, N-type and Q-type. Each type has a unique format shown in the table below.
15 | 14 | 13 | 12 | 11 | 10 | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 | |
Z-Type | Rd | Imm | OPC | Rs | Rt | |||||||||||
I-Type | Imm | OPC | Shamt | Rd | ||||||||||||
N-Type | Immh | Addr | OPC | Imml | Funct | |||||||||||
Q-Type | Rs | q | Rd | OPC | Rt | Shamt |
Fields Explanations
-
OPC and Funct: Operation of the instruction. Specifies which instruction is it, along with its type (e.g. Z-type) to extract other fields.
-
R* and Addr: The number of a register, in which its value is used when referenced. The first one is for the main register file, the second is for the bank one.
-
Imm*: A constant value. Stands for immediate.
-
Shamt: Shift amount used in dynamic shift operations.
For more details, see the Instruction Set section below.
Instruction Set
Type | OPC | Funct | Assembly Format | Operation |
---|---|---|---|---|
Z | 000 | ‐ | stoi Rd, Rs, Rt, Imm |
Mem[Rs + Rt] ← 16×U.S(Rd) + Z.E(Imm) |
Z | 001 | - | cmpi Rd, Rs, Rt, Imm |
If (Rs == S.E(Imm)) Rd ← 0x"FFFF" Else Rd ← 0x"0000" |
I | 010 | ‐ | ltor Rd, Imm, Shamt |
Rd ← (Mem[S.E(Imm & “0000”)) << (4 ^ Shamt)) |
I | 011 | - | luis Rd, Imm, Shamt |
Rd ← (S.E(Imm) << Shamt )[15:8] & 0x"00" |
N | 111 | 01 | bgti Imml, Immh, Addr |
If (S.E(Imml) < S.E(Immh)) PC ← (PC[15:12] & Bank[Addr][11:0]) Bank[3] ← (PC + 2) Else PC ← (PC + 2) Bank[Addr] ← (PC + 2) |
N | 111 | 10 | jalv Imml, Immh, Addr |
PC ← (Z.E(Immh & Imml)<<1) + (PC + 2) Bank[Addr] ← (PC+2) |
Q | 100 | - | subs Rd, Rs, Rt, Shamt |
If (q == 1) Rd ← (Rs ‐ Rt) << Shamt Else Rd ← (U.S(Rs) ‐ U.S(Rt)) << Shamt |
Q | 110 | - | beon Rd, Rs, Rt, Shamt |
If (q == 1) Rd ← Rs[15:8] & Rt[7:0] PC ← PC + ((Rs × 64) + (4 ^ Shamt)) Else Rd ← NOT(Rs) PC ← (PC << Shamt) |
Operations Explained
- S.E: Sign Extend
- Z.E: Zero Extend
- U.S: Unsigned
- &: Concatenation
- <<: Left Shift
- ^: Power (i.e. Exponentiation)
Datapath
Controller
The controller is an FSM (Final State Machine).
Other Resources
If you want to know how the connection signals between datapath and controller are implemented and optimized, see this image.
Contributions
Feel free to contribute of any kind. By any kind, we mean just ANY kind! :)
Documentation
The code is well-documented, and this README should help you through the general overview of the project.
But you think it is a must? Create an issue and tell why.
License
Licensed under GPLv3.