DELHI TECHNOLOGICAL UNIVERSITY
Computer architecture
Submitted by
Amrit 2K19/EC/014
Daksh Garg 2K19/EC/050
Submitted to
Mr. Dinesh Chaudhary
Department of Electronics & Communication Engineering
Delhi Technological University, Delhi
Delhi-110042
April, 2021
Electronics & Communication Engg. Deptt.
DELHI TECHNOLOGICAL UNIVERSITY
(Formerly Delhi College of Engineering)
Shahbad Daulatpur, Bawana Road-Delhi-42
Candidate’s Declaration
I, hereby, declare that the work embodied in this project entitled “MIPS32
processor using Verilog” submitted to the Department of Electronics &
Communication Engineering, Delhi Technological University, Delhi is an
authentic record of my own bonafide work and is correct to the best of my
knowledge and belief. This work has been undertaken taking care of
engineering ethics.
Name and Signature of the Student:
Amrit & Daksh Garg
1
Acknowledgement
I would like to express my special thanks of gratitude to my Computer
architecture teacher “Mr. Dinesh Chaudhary” for their guidance and support in
completing my project. I would also like to extend my gratitude to the Vice
Chancellor Sir “Mr. Yogesh Singh” for providing me with all facilities that were
required for the project.
2
Certificate
This is to inform that “Amrit” and “Daksh Garg” students of the 2nd year ECE
branch have successfully completed the Computer architecture project on
“MIPS32 processor using verilog” under the guidance of “Mr. Dinesh
chaudhary” sir.
3
Abstract
In the project we will be creating a processor on a simulator using pipeline
implementation. We will be giving the instruction in Verilog according to which
the processor will work. A processor is a small chip or device in which we give
the input and it gives us the output according to the functionality defined in it.
Verilog is a hardware description language in which we write code to define all
the elements and in the background the circuit is created according to the model
defined by us in the code.
The name of the processor is MIPS32, this is a simple basic level processor
consisting of 32 bits.
4
Index
Candidates declaration
Acknowledgement
Certificate
Abstract
Introduction
About the Project
Language used
Data Path Diagrams
● MIPS32 data path (non pipelined)
● MIPS32 data path (pipelined)
Working Mechanism
● IF stage
● ID stage
● EX stage
● MEM stage
● WB stage
Project Code
● Project Design code MIPS32
● TestBench
1. Test bench 1
2. Test bench 2
3. Test bench 3
Bibliography
5
Introduction
MIPS (Microprocessor without Interlocked Pipeline Stages) is a reduced
instruction set computer (RISC) instruction set architecture (ISA) developed by
MIPS Computer Systems(MIPS Technologies) based in the United States.
There are multiple versions of MIPS: including MIPS I, II, III, IV, and V; as
well as five releases of MIPS32/64 (for 32 and 64-bit implementations,
respectively). The early MIPS architectures were 32-bit only; 64-bit versions
were developed later. MIPS32/64 primarily differs from MIPS I–V by defining
the privileged kernel mode System Control Coprocessor in addition to the user
mode architecture.
The MIPS architecture is based on a fixed-length, regularly encoded instruction
set and uses a load/store data model, in which all operations are performed on
operands in processor registers, and main memory is accessed only by load and
store instructions. The load/store model reduces the number of memory
accesses, thus easing memory bandwidth requirements, simplifies the
instruction set, and makes it easier for compilers to optimize register allocation.
Computer architecture courses in universities and technical schools often study
the MIPS architecture. The architecture greatly influenced later RISC
architectures such as Alpha. In March 2021, MIPS announced that the
development of the MIPS architecture had ended as the company was making
the transition to RISC-V.
6
About the project
We have implemented a subset of MIPS32 processor where we have tried to
implement the following functions/Instructions :
➢ LOAD / STORE instructions
○ LOAD
○ STORE
➢ ARITHMETIC and LOGIC instructions
○ ADD
○ SUB
○ AND
○ OR
○ MUL
○ SLT(Set Less Than)
➢ ARITHMETIC and LOGIC instructions(immediate operand)
○ ADDI
○ SUBI
○ SLTI
➢ BRANCH instructions
○ BEQZ (Branch Equal to Zero)
○ BNEQZ (Branch Not Equal to Zero)
7
Language Used
For the Mips32 processor, we used the very famous assembly language
‘VERILOG’.
Verilog is a Hardware Description Language (HDL). It is a language used for
describing a digital system such as a network switch, a microprocessor, a
memory, or a flip-flop. We can describe any digital hardware by using HDL at
any level. Designs described in HDL are independent of technology, very easy
for designing and debugging, and are normally more useful than schematics,
particularly for large circuits.
It was developed to simplify the process and make the HDL more robust and
flexible. Today, Verilog is the most popular HDL used and practiced throughout
the semiconductor industry.
Verilog creates a level of abstraction that helps hide away the details of its
implementation and technology.
For example, a D flip-flop design would require the knowledge of how the
transistors need to be arranged to achieve a positive-edge triggered FF and what
the rise, fall, and CLK-Q times required to latch the value onto a flop among
much other technology-oriented details.
(We will be using ‘EDA playground’ online platform to simulate our project and
for the corresponding test bench get the simulation output and EPwave .)
8
Data Path Diagram
1. MIPS32 Data Path (non-pipelined)
2. MIPS32 Data path(Pipelined)
9
Working mechanism
Mips32 follows an instruction cycle to execute any instruction. Instruction cycle
consists of 5 steps.
IF stage (Instruction Fetch)
ID stage(Instruction Decode/Register fetch)
EX stage(Execution Effective Address calculation)
MEM stage(Memory Access / branch completion)
WB stage (register Write Back)
IF stage:
Here the instruction pointed to by the PC(program counter) is fetched from
memory , and also the next value of the PC is computed.
ID stage:
The instruction already fetched in IR is decoded at this stage. Decoding
is done in parallel with reading the register operands Rs and Rt.
EX stage:
In this step , the ALU is used to perform some calculation. different instructions
are executed for different types of reference. (memory ref , register-register ref )
10
MEM stage:
Only load , store and branch instructions use this stage. The load and store
instructions access the memory. The branch instruction updates PC depending
upon the outcome of the branch condition .
WB stage:
In this step , the result is written back into the register file. Results may come
from the ALU or it may come from the memory system (viz. A LOAD
instruction). The position of destination register depends upon the instruction.
(R-type , I - type ).
11
Project Code
1. Processor Design code of MIPS32:
module pipe_MIPS32 (clk1,clk2);
input clk1,clk2; //two phase clock
reg [31:0] PC, IF_ID_IR, IF_ID_NPC;
reg [31:0] ID_EX_IR, ID_EX_NPC, ID_EX_A, ID_EX_B, ID_EX_Imm;
reg [2:0] ID_EX_type, EX_MEM_type, MEM_WB_type ;
reg [31:0] EX_MEM_IR, EX_MEM_ALUOut, EX_MEM_B ;
reg EX_MEM_cond;
reg[31:0] MEM_WB_IR,MEM_WB_ALUOut,MEM_WB_LMD;
reg [31:0] Reg[0:31]; //register bank (32x32)
reg [31:0] Mem [0:1023];
parameter ADD = 6'b000000, SUB = 6'b000001 , AND =
6'b000010, OR = 6'b000011 , SLT = 6'b000100 , MUL = 6'b000101,
HLT = 6'b111111 , LW = 6'b001000 , SW = 6'b001001 , ADDI =
6'b001010 , SUBI = 6'b001011 , SLTI = 6'b001100, BNEQZ =
6'b001101 , BEQZ = 6'b001110 ;
parameter RR_ALU = 3'b000 , RM_ALU = 3'b001 , LOAD = 3'b010,
STORE = 3'b011 , BRANCH = 3'b100 , HALT = 3'b101;
reg HALTED;
// Set after HLT instruction is completed (in WB stage)
reg TAKEN_BRANCH;
//required to disable instructions after branch
always @(posedge clk1) //IF stage
if (HALTED == 0)
begin
if ( ( (EX_MEM_IR[31:26] == BEQZ) && (EX_MEM_cond == 1) )
|| ( (EX_MEM_IR[31:26] == BNEQZ) && (EX_MEM_cond == 0) ) )
begin
IF_ID_IR <= #2 Mem[EX_MEM_ALUOut];
12
TAKEN_BRANCH <= #2 1'b1;
IF_ID_NPC <= #2 EX_MEM_ALUOut + 1;
PC <= #2 EX_MEM_ALUOut + 1;
end
else
begin
IF_ID_IR <= #2 Mem[PC];
IF_ID_NPC <= #2 PC + 1;
PC <= #2 PC + 1;
end
end
always @(posedge clk2)
if(HALTED == 0)
begin
if(IF_ID_IR[25:21] == 5'b00000) ID_EX_A <=0;
else ID_EX_A <= #2 Reg[IF_ID_IR[25:21]]; //"rs"
if(IF_ID_IR[20:16] == 5'b00000) ID_EX_B <=0;
else ID_EX_B <= #2 Reg[IF_ID_IR[20:16]]; //"rt"
ID_EX_NPC <= #2 IF_ID_NPC;
ID_EX_IR <= #2 IF_ID_IR;
ID_EX_Imm <= #2 {{16{IF_ID_IR[15] } } , {IF_ID_IR[15:0]
} };
case (IF_ID_IR[31:26])
ADD,SUB,AND,OR,SLT,MUL : ID_EX_type <= #2 RR_ALU;
ADDI,SUBI,SLTI : ID_EX_type <= #2 RM_ALU;
LW: ID_EX_type <= #2 LOAD;
SW: ID_EX_type <= #2 STORE;
13
BNEQZ,BEQZ: ID_EX_type <= #2 BRANCH;
HLT: ID_EX_type <= #2 HALT;
default: ID_EX_type <= #2 HALT;
endcase
end
always@(posedge clk1) //EX stage
if(HALTED ==0)
begin
EX_MEM_type <= #2 ID_EX_type;
EX_MEM_IR <= #2 ID_EX_IR;
TAKEN_BRANCH <= #2 0;
case (ID_EX_type)
RR_ALU: begin
case (ID_EX_IR[31:26]) //'OPCODE'
ADD: EX_MEM_ALUOut <= #2 ID_EX_A + ID_EX_B;
SUB: EX_MEM_ALUOut <= #2 ID_EX_A - ID_EX_B;
AND: EX_MEM_ALUOut <= #2 ID_EX_A & ID_EX_B;
OR: EX_MEM_ALUOut <= #2 ID_EX_A | ID_EX_B;
SLT: EX_MEM_ALUOut <= #2 ID_EX_A < ID_EX_B;
MUL: EX_MEM_ALUOut <= #2 ID_EX_A * ID_EX_B;
default: EX_MEM_ALUOut <= #2 32'hxxxxxxxx;
endcase
end
RM_ALU: begin
case (ID_EX_IR[31:26]) //'opcode'
ADDI: EX_MEM_ALUOut <= #2 ID_EX_A + ID_EX_Imm;
SUBI: EX_MEM_ALUOut <= #2 ID_EX_A - ID_EX_Imm;
SLTI: EX_MEM_ALUOut <= #2 ID_EX_A < ID_EX_Imm;
default: EX_MEM_ALUOut <= #2 32'hxxxxxxxx;
endcase
end
14
LOAD , STORE :
begin
EX_MEM_ALUOut <= #2 ID_EX_A + ID_EX_Imm;
EX_MEM_B <= #2 ID_EX_B;
end
BRANCH:
begin
EX_MEM_ALUOut <= #2 ID_EX_NPC + ID_EX_Imm;
EX_MEM_cond <= #2 (ID_EX_A == 0);
end
endcase
end
always @(posedge clk2) //MEM stage
if (HALTED == 0)
begin
MEM_WB_type <= EX_MEM_type;
MEM_WB_IR <= EX_MEM_IR;
case (EX_MEM_type)
RR_ALU, RM_ALU:
MEM_WB_ALUOut <=#2 EX_MEM_ALUOut;
LOAD : MEM_WB_LMD <=#2 Mem[EX_MEM_ALUOut];
STORE:
if(TAKEN_BRANCH == 0) //disable write
Mem[EX_MEM_ALUOut] <= #2 EX_MEM_B;
endcase
end
15
always @(posedge clk1) //WB stage
begin
if(TAKEN_BRANCH == 0) //disable write if branch taken
case (MEM_WB_type)
RR_ALU: Reg[MEM_WB_IR[15:11]] <= #2 MEM_WB_ALUOut;
//'rd'
RM_ALU: Reg[MEM_WB_IR[20:16]] <= #2 MEM_WB_ALUOut;
//'rt'
LOAD: Reg[MEM_WB_IR[20:16]] <= #2 MEM_WB_LMD; //'rt'
HALT: HALTED <= #2 1'b1;
endcase
end
endmodule
16
2. Test Benches (With Results and waveforms):
We have implemented 3 test benches for our mips32 processor.
1. Add three numbers 10,20,30 stored in processed registers.
2. Load a word stored in memory location 120, add 45 to it, and store
the result in memory location 121.
3. Compute the factorial of number N stored in memory location 120.
The result will be stored in memory location 198.
2.1 Test Bench 1
module test_mips32;
reg clk1,clk2;
integer k;
pipe_MIPS32 mips (clk1,clk2);
initial
begin
clk1 = 0; clk2 = 0;
repeat (20) //generating two phase clock
begin
#5 clk1 = 1; #5 clk1 = 0;
#5 clk2 = 1; #5 clk2 = 0;
end
end
initial
begin
for (k=0; k<31; k=k+1)
begin
mips.Reg[k] = k;
end
mips.Mem[0] = 32'h2801000a; //ADDI R1,R0,10
17
mips.Mem[1] = 32'h28020014; //ADDI R2,R0,20
mips.Mem[2] = 32'h28030019; //ADDI R3,R0,25
mips.Mem[3] = 32'h0ce77800; //OR R7,R7,R7--DUMMMYinstr.
mips.Mem[4] = 32'h0ce77800; //OR R7,R7,R7--DUMMMYinstr.
mips.Mem[5] = 32'h00222000; //ADD R4,R1,R2
mips.Mem[6] = 32'h0ce77800; //OR R7,R7,R7--DUMMMYinstr.
mips.Mem[7] = 32'h00832800; //ADD R5,R4,R3
mips.Mem[8] = 32'hfc000000; //HLT
mips.HALTED = 0;
mips.PC = 0;
mips.TAKEN_BRANCH = 0;
#280
for(k=0;k<6;k=k+1)
begin
$display ("R%1d - %2d",k,mips.Reg[k]);
end
end
initial
begin
$dumpfile ("mips.vcd");
$dumpvars(0,test_mips32);
#300 $finish;
end
endmodule
18
Result 1:
Waveform Timing Diagram:
2.2 Test Bench 2
module test_mips32;
reg clk1,clk2;
integer k;
pipe_MIPS32 mips (clk1 , clk2);
initial
begin
19
clk1 = 0; clk2 = 0;
repeat(50) //generating two-phase clock
begin
#5 clk1 = 1; #5 clk1 = 0;
#5 clk2 = 1; #5 clk2 = 0;
end
end
initial
begin
for(k=0;k<31;k = k+1)
begin
mips.Reg[k] = k;
end
mips.Mem[0] = 32'h28010078; //ADD R1,R0,120
mips.Mem[1] = 32'h0c631800; //OR R3,R3,R3 -- dummy instr.
mips.Mem[2] = 32'h20220000; //LW R2,0(R1)
mips.Mem[3] = 32'h0c631800; //OR R3,R3,R3 -- dummy instr.
mips.Mem[4] = 32'h2842002d; //ADDI R2,R2,45
mips.Mem[5] = 32'h0c631800; //OR R3,R3,R3 -- dummy instr.
mips.Mem[6] = 32'h24220001; //SW R2,1(R1)
mips.Mem[7] = 32'hfc000000; //HLT
mips.Mem[120] = 85;
mips.PC = 0;
mips.HALTED = 0;
mips.TAKEN_BRANCH = 0;
20
#500 $display ("Mem[120] : %4d \nMem[121] :%4d",
mips.Mem[120] , mips.Mem[121] );
end
initial
begin
$dumpfile ("mips.vcd");
$dumpvars (0,test_mips32);
#600 $finish;
end
endmodule
Result 2:
Waveform Timing Diagram:
21
2.3 Test Bench 3
module test_mips32;
reg clk1,clk2;
integer k;
pipe_MIPS32 mips (clk1 , clk2);
initial
begin
clk1 = 0; clk2 = 0;
repeat(50) //generating two-phase clock
begin
#5 clk1 = 1; #5 clk1 = 0;
#5 clk2 = 1; #5 clk2 = 0;
end
end
initial
begin
for(k=0;k<31;k=k+1)
mips.Reg[k] = k;
mips.Mem[0] = 32'h280a00c8; //ADDI R10,R0,200
mips.Mem[1] = 32'h28020001; //ADDI R2,R0,1
mips.Mem[2] = 32'h0e94a000; //OR R20,R20,R20 -- dummy
mips.Mem[3] = 32'h21430000; //LW R3,0(R10)
mips.Mem[4] = 32'h0e94a000; //OR R20,R20,R20 -- dummy
mips.Mem[5] = 32'h14431000; //Loop MUL R2,R2,R3
mips.Mem[6] = 32'h2c630001; //SUBI R3,R3,1
mips.Mem[7] = 32'h0e94a000; //OR R20,R20,R20 -- dummy
22
mips.Mem[8] = 32'h3460fffc; //BNEQZ R3,Loop (i.e. -4
offset)
mips.Mem[9] = 32'h2542fffe; //SW R2,-2(R10)
mips.Mem[10] = 32'hfc000000; //HLT
mips.Mem[200] = 7; //Find factorial of 7
mips.PC = 0;
mips.HALTED = 0;
mips.TAKEN_BRANCH = 0;
#2000 $display ("Mem[200] = %2d, Mem[198] =
%6d",mips.Mem[200],mips.Mem[198]);
end
initial
begin
$dumpfile ("mips.vcd");
$dumpvars (0,test_mips32);
$monitor ("R2 : %4d",mips.Reg[2]);
#3000 $finish;
end
endmodule
23
Result 3:
Waveform Timing Diagram:
24
Bibliography
1. https://youtube.com/playlist?list=PLUtfVcb-iqn-EkuBs3arreilxa
2UKIChl
2. https://en.wikipedia.org/wiki/MIPS_architecture
3. https://www.mips.com/products/architectures/mips32-2/
4. https://www2.cs.duke.edu/courses/fall13/compsci250/MIPS32_
QRC.pdf
5. https://www.dsi.unive.it/~gasparetto/materials/MIPS_Instruction
_Set.pdf
6. https://www.edaplayground.com/
25