Update 4/21/2017: ROM memory has been added to the code. The plan going forward is to implement the Verilog code onto an FPGA as an all in one SOC computer. I am currently working on an assembler so that user inputted assembly code can be executed (As of now all instructions must be entered in binary). The long-term goal is to add a C compiler with the finalized version of this project being a fully functional text-based PC.

Introduction:

This report outlines a processor designed in Verilog whose instructions are based on a RISC instruction set with parameters similar to those of MIPS architecture. The code and its testbench were written in Verilog using the Atom text editing software and were executed using Icarus Verilog, a terminal based Verilog compiler.

 

Processor Specifications:

Register File Size 32 General Purpose Registers

Word Size 32-bit

Special Registers Program Counter, Stack Pointer

ALU Flags Negative, Zero, Carry, Overflow

 

Instruction Format:

Size 32-bit

Instruction Type 1 (3 register Instructions)

opcode31:26 Dest. Reg25:21 S Reg20:16 T Reg15:11 Func5:0


31:26
Opcode – Used to specify instruction category (Load, Store, Arithmetic, etc.)

25:21 Dest. Reg – Destination register for ALU output

20:16 S Reg – First operand register

15:11 T Reg – Second operand register

10:6 Unused

5:0 Func – Specific function within instruction category (Load Immediate, Add, etc.)

 

Instruction Type 2 (1 and 2 register Instructions)

opcode31:26 Dest. Reg25:21 S Reg20:16 Imm15:6 Shamt/Func5:0


31:26
Opcode – Used to specify instruction category (Load, Store, Arithmetic, etc.)

25:21 Dest. Reg – Destination register for ALU output

20:16 S Reg – Operand register (Unused if 1 register instruction)

15:6 Imm – Immediate

5:0 Func – Specific function within instruction categ

Shamt – Shift amount (Func is used as shift amount for shift/rotate instructions)

 

Verilog Code and Testbench

The attached Verilog code contains the following components: Clock Definition, I/O and Variable Definitions, Instruction Fetch, Hardcoding r0, Instruction Decode, Register Read, ALU, Register Write Back, and Test Outputs.

Clock Definition and Variable Definitions define the inputs, registers, outputs, and wires used in the program. The Instruction Fetch takes in an instruction from the Testbench into the Processor then the Instruction Decode block decodes the incoming instruction as both Type 1 and Type 2 instructions. Register read looks up the operand registers in the register file and prepares their values for use in the ALU. Next, the ALU executes the requested instruction and the Write Back block updates the register file. Finally, the entire register file and the program counter are sent as outputs from the processor to the test bench for verification. At the end of each instruction execution, the program counter increments by 4.

All of these functions were implemented in a single module using if/else and case statements.

The attached Testbench executes the following code to demonstrate each category of instruction/opcode:

LD r1 1 //Load 32-bit immediate 1 → r1

LD r2 2 //Load 32-bit immediate 2 → r2

ADD r3 r1 r2 //r3 = r1 + r2

MUL r4 r2 r3 //r4 = r2 * r3

AND r5 r4 r3 //r5 = r4 (bitwise AND) r3

LDR r6 r5 //r5 ← r6

BEQ r2 r5 12 //if r2 = r5, PC = 12

STR r7 r0 //Store register r0 in register r7

ROTR r6 r5 5 //Rotate r5 into r6 6 places