Processor Design - EE739
Project Report
Pipelined IITB-RISC Processor
Instructor : Prof. Virendra Singh
Submitted By –
Mohd. Faizaan Qureshi (203070062)
Kanak Vijay (203070050)
Muhaamad. Shoaib Iqbaal (203070058)
0
Hardware flowchart
R-type instructions
Opcode Ra Rb Rc condition
PC_current_value instr_memA, alu2_A
+1 alu2_B
alu2_out PC_1
IF
instr_memD IWR
IF_ID_reg
IWR ( 11-9 ) Rf_A1
IWR ( 8-6 ) Rf_A2
ID & OF
Rf_D1 T1
Rf_D2 T2
ID_EX_reg
T1 alu1_A
EX T2 alu1_B
alu1_out T3
EX_MEM_reg
MEM
No operation in MEM
MEM_WB_reg
WB T3 Rf_D3
IWR ( 5-3 ) Rf_A3 1
LW instruction
Opcode Ra Rb Immediate
PC_current_value instr_memA, alu2_A
+1 alu2_B
IF
alu2_out PC_1
instr_memD IWR
IF_ID_reg
IWR ( 8-6 ) Rf_A1
ID & OF
Rf_D1 T1
ID_EX_reg
T1 alu1_A
EX
IWR (5-0) SE6 alu1_B
alu1_out T3
EX_MEM_reg
T3 data_memA
MEM data_memD T4
MEM_WB_reg
WB T4 Rf_D3
IWR ( 11-9 ) Rf_A3
2
SW instruction
Opcode Ra Rb Immediate
PC_current_value instr_memA, alu2_A
+1 alu2_B
IF
alu2_out PC_1
instr_memD IWR
IF_ID_reg
IWR ( 8-6 ) Rf_A1
ID & OF IWR ( 11-9 ) Rf_A2
Rf_D1 T1
Rf_D2 T2
ID_EX_reg
T1 alu1_A
EX
IWR (5-0) SE6 alu1_B
alu1_out T3
EX_MEM_reg
T3 data_memA
MEM
T2 data_memD
MEM_WB_reg
WB
No Operation
3
BEQ instruction
Opcode Ra Rb Immediate
PC_current_value instr_memA, alu2_A
+1 alu2_B
IF
alu2_out PC_1
instr_memD IWR
IF_ID_reg
IWR ( 11-9 ) Rf_A1
IWR ( 8-6 ) Rf_A2
ID & OF
Rf_D1 T1
Rf_D2 T2
PC alu3_A
IWR ( 5-0 ) SE6 alu3_B
alu3_out PC_2
ID_EX_reg
T1 alu1_A
IWR (5-0) SE6 alu1_B
alu1_out T3
EX
if ( alu1_zero ) then PC_2 PC_3
else PC_1 PC_3
EX_MEM_reg
No Operation
MEM
MEM_WB_reg
4
WB No Operation
LHI instruction
Opcode Ra Immediate
PC_current_value instr_memA, alu2_A
+1 alu2_B
IF
alu2_out PC_1
instr_memD IWR
IF_ID_reg
ID & OF NO Operation
ID_EX_reg
IWR ( 8-0 ) SEM9 T3
EX
( Here ignore adder result )
EX_MEM_reg
T3 data_memA
MEM data_memD T4
MEM_WB_reg
WB T4 Rf_D3
IWR ( 11-9 ) Rf_A3
5
JAL instruction
Opcode Ra Immediate
PC_current_value instr_memA, alu2_A
+1 alu2_B
IF
alu2_out PC_1
instr_memD IWR
IF_ID_reg
PC alu3_A
ID & OF
IWR ( 8-0 ) SE9 alu3_B
alu3_out PC_2
ID_EX_reg
No Operation
EX
EX_MEM_reg
MEM
No Operation
MEM_WB_reg
WB PC_1 Rf_D3
IWR ( 11-9 ) Rf_A3
6
JLR instruction
Opcode Ra Rb
PC_current_value instr_memA, alu2_A
+1 alu2_B
IF
alu2_out PC_1
instr_memD IWR
IF_ID_reg
IWR ( 8-6 ) Rf_A1
ID & OF
Rf_D1 PC_2
ID_EX_reg
No Operation
EX
EX_MEM_reg
MEM
No Operation
MEM_WB_reg
WB PC_1 Rf_D3
IWR ( 11-9 ) Rf_A3
7
JRI instruction
Opcode Ra Immediate
PC_current_value instr_memA, alu2_A
+1 alu2_B
IF
alu2_out PC_1
instr_memD IWR
IF_ID_reg
IWR ( 11-9 ) Rf_A1
ID & OF
Rf_D1 T1
ID_EX_reg
T1 alu1_A
EX IWR (8-0) SE9 alu1_B
alu1_out T3 PC_3
EX_MEM_reg
No Operation
MEM
MEM_WB_reg
WB No Operation
8
LM Instruction
Opcode Ra Immediate
LA Instruction
Opcode Ra Immediate
9
SM Instruction
Opcode Ra Immediate
SA Instruction
Opcode Ra Immediate
10
Control Signals
Signal Name Size
alu1_src 2 bit
alu1_op 2 bit
t3_sel 1 bit
load 1 bit
sig_multiple 1 bit
sig_all 1 bit
branch 1 bit
jump 1 bit
jump_type 2 bit
mem_read 1 bit
mem_write 1 bit
reg_write 1 bit
reg_write_data_sel 2 bit
reg_write_addr_sel 2 bit
Pipeline Registers
Register Name Size
IF_ID_reg 49 bits
ID_EX_reg 116 bits
EX_MEM_reg 97 bits
MEM_WB_reg 78 bits
Look Up table we have used has 8 entries and each has width 34 bits.
Data Hazards
Data Hazards occur when there is a violation in producer – consumer relationships.
All instructions that read operands which is being written by previous instruction, then
there may be hazards.
All instructions which are writing in to register file =
All R-type instructions, LW, LHI, JAL, JLR
11
All instructions which read from register file in decode and operand read stage =
All R-type instructions, LW, SW, BEQ, JLR, JRI, SM, SA, LM, LA
So, there can be many possible dependencies which can occur, and we have covered all
possible dependencies.
Let’s test the processor
TEST1
Instructions =>
LW R1, R0, 1
LW R2, R0, 2
ADD R3, R1, R2 // there is a dependency, need R1, R2
ADD R4, R1, R3 // there is a dependency, need R1, R3
ADD R5, R2, R3 // there is a dependency, need R2, R3
ADD R6, R3, R4 // there is a dependency, need R3, R4
NOP
12
Data Memory content =>
Reg file content at the end of execution in modelsim =>
R7 is program counter.
Due to immediate dependency after load, there will be necessary STALL, which can be
seen in above figure, pc_enable went to logic 0 for a while.
13
Simulation Waveforms =>
RegFile data flow from ports =>
Here in above figure, pc_value_out is R7 which stores program counter , and it is
inside Register File module.
Data Memory data flow from ports =>
TEST2
Instructions =>
LM R1, 11111110
ADD R2, R6, R7 //there is a dependency, need R6
ADD R3, R7, R5 // there is a no dependency (R5 has been written)
ADD R4, R6, R5
ADD R5, R4, R5 //there is a dependency, need R4
ADD R6, R5, R3 //there is a dependency, need R5, R3
ADD R7, R6, R2 //there is a dependency, need R6, and there will be jump
SM R2, 11111111 //skipped
NOP
14
Data Memory Content =>
Reg file content at the end of execution in modelsim =>
15
Here in this case ADD instruction is writing into R7, so there will be entry in look
table =>
Flush signal is also generated on encountering jump instruction =>
For LM instruction there would be STALL till its complete execution =>
16
Simulation Waveforms =>
Register File data flow from it’s ports =>
Here pc_value_out is R7. And clearly we can see PC=R7=8, it went to PC=R7=64
Data Memory data flow from it’s ports =>
TEST3
Instructions =>
LA R1 //LA loads only R0 to R6
ADD R2, R5, R6 // there is a dependency , need R6, (R5 has been written)
ADD R3, R6, R4
ADD R4, R5, R4
ADD R5, R3, R4 // there is a dependency, need R4, R3
ADD R6, R4, R5 // there is a dependency, need R5, R4
SA R4
NOP
17
Data Memory Content =>
Reg file content at the end of execution in modelsim =>
18
Data Memory Content after executon (since SA stored all registers from R0 to R6)=>
Simulation Waveforms =>
Register File data flow from it’s ports =>
Here as always, R7 = PC Counter, represented by pc_value_out in above figure.
Data Memory data flow from it’s ports =>
19
Here mem_read and mem_write signals are clearly shown.
TEST4
Instructions =>
LW R1, R0, 1
LW R2, R0, 2
LW R3, R0, 3
BEQ R2, R3, 3 //there is a dependency, need R2, R3
ADD R2, R2, R1 // there is a dependency, need R2
JRI R0, 3
NOP
Data Memory Content =>
20
Register File content after first time encountering of Branch and jump instructions =>
Look up table after first time encountering of Branch and jump instructions =>
Here Branch has History Bit = 01, initially. Further it can be changed based on taken or
not taken branch.
But Jump instruction is always taken branch instruction, so History Bit = 11 always.
Look up table after 2nd time encountering Branch instruction (1st entry in look table ),
History Bit has been changed to 00. =>
21
Here , in below image, we can see first time after jump it has to go beyond, because
there is no entry in look table, pc_current_value = 5,6,7, then 3
But after entry in look up table, pc_current_value = 5,3,4,5,3…… So, here look table
table is saving some cycles per instructions (CPI)
Look up table after branch taken to exit the loop =>
History bit here now is 01
Register File Content after complete execution = >
, Here loop breaks after R2 = R3 = 15.
22
Simulation Waveforms =>
Register File data flow from it’s ports =>
Data Memory data flow from it’s ports =>
Here there can be unnecessary data at it’s ports, but mem_read and mem_write knows
when to read and when to write, which is given by processor.
TEST5
Instructions =>
LM R0, 11111000
ADD R3, R1, R2 // Here R3 would be 12
NDU R0, R3, R4 // (12 NAND 26) = 1111 1111 1111 0111 = -9
ADZ R1, R3, R0 // Zero not asserted before, so no write here, but carry will be 1
ADC R5, R1, R3 //here carry was 1, so write R5 = 21
ADC R5, R1, R3 //here carry was 0 from previous, so not write R5=21
NOP
23
Data Memory Content =>
Register File Content after execution =>
Reg_write = 0 for last ADC instruction =>
24
Simulation Waveforms = >
Register File data flow from it’s ports =>
Data Memory data flow from it’s ports =>
TEST6
Instructions =>
LW R1, R0, 1
LW R2, R0, 2
ADD R3, R1, R2 // there is a dependency, need R1, R2
ADD R4, R2, R3 // there is a dependency, need R2, R3
JAL R5, 7 // It is function call, so make a new entry in look up table
ADD R5, R3, R4 // skipped for the first time
ADD R5, R5, R4 // skipped for the first time
25
NOP
NOP
NOP
NOP
LW R6, R0, 3 // starting of function
ADD R4, R6, R4 // there is a dependency, need R6
ADD R4, R4, R3 // there is a dependency, need R4
ADD R3, R4, R2 // there is a dependency, need R3, R4
JRI R5, 0 // return to next instruction of function call instruction
26
Data Memory Content =>
Look up table having entry of functional call from JAL and return instruction from JRI
=>
Register file content after execution =>
27
Simulation Waveforms =>
Register File data flow from it’s ports =>
Data Memory data flow from it’s ports =>
TEST7 (Fibonacci Sequence generating)
Instructions =>
LW R1, R0, 1
LW R2, R0, 1
LW R5, R0, 2
BEQ R4, R5, 7 // there is a dependency, need R5
ADD R3, R1, R2 //there is a dependency, need R2
ADI R1, R2, 0
ADI R2, R3, 0 // there is a dependency, need R3
SW R3, R4, 5 // there is a dependency, need R3
ADI R4, R4, 1
JRI R0, 3
28
Data Memory before execution =>
Look up table after encountering first time Branch and jump =>
Register File Content initially =>
29
Look up table after again encountering branch, making it confirm not to take branch,
i.e. History Bit = 00, =>
Look up table after loop exit, here Branch instruction History Bit would become 01=>
Register File Content after execution =>
30
Data Memory Content after written 15 Fibonacci no from memory address 5 =>
Waveforms showing CPI improvement by look up table =>
Here in waveforms, we can see that first time after jump (PC=9), it had fetched PC=10,
11. But after again fetching same jump instruction, then it did not fetch PC=10 instr.
instead it looked in look up table and got Branch Target Address, and fetched PC=3
directly =>
So, in the loop, with the help of look up table, PC is going like = 3,4,5,6,7,8,9,3,4…..
31
Simulation Waveforms =>
Register file data in and out of port =>
Here pc_value_out is R7.
Data Memory Waveform =>
Clearly it can be seen, that Fibonacci numbers are being written on successive memory
address.
32
Control Signals =>
PC current changing as required =>
TEST8 (Addition of 2 arrays)
Instructions =>
LW R2, R0, 1 // [R2] Mem([R0] + 1)
BEQ R1, R2, 7 //there is a dependency, need R2
LW R3, R1, 2 // [R3] Mem([R1] + 2)
LW R4, R1, 7 // [R4] Mem([R1] + 7)
ADD R5, R3, R4 // there is a dependency , need R3, R4 (It is R5=R3+R4)
SW R5, R1, 12 //Mem([R1] + 12) [R5], dependency here, need R5
ADI R1, R1, 1 // [R1] [R1] + 1
JRI R0, 1 // jump to [R0] + 1
NOP
33
Data Memory Content at the starting of execution =>
We have 2 arrays or vectors of length 5 each. In memory, one array is from address 2,
and other array is from address 7
34
Register File Content during and at the end of execution =>
Look Up table Content during and at end of execution =>
35
Data Memory Content after execution =>
Here we can see from memory address 12 onwards, we are getting result of 2
vectors/arrays of length 5.
36
Simulation Waveforms =>
Reg_file ports data
Data Memory data flow =>
Control Signals and stall condition activation =>
Some intermediate Signals and pc_current_value =>
37
TEST9 ( Minimum number finder )
Instructions =>
LW R5, R0, 1 // R5 1
LW R2, R0, 2 // R2 5 ( i.e size of array )
LW R4, R0, 3 // R4 3 ( i.e first element of an array )
BEQ R2, R5, 8 // there is a dependency, need R2, R5, which has not been written
LW R6, R5, 3 //R6 mem(1 + 3) = 5
NDU R3, R6, R6 // nand all R6 with R6 to get inverted bits of R6 in R3
ADI R3, R3, 1 // add 1 to get 2’s compliment of no.
ADD R3, R4, R3 // R3 R4 + R3, if +ve, carry generated, else not
ADC R4, R6, R0 // if carry generated previously , then only work
ADI R5, R5, 1 // R5 R5 + 1, increment the loop counter
JRI R0, 3 // jump to branch instr.
SW R2, R4, 4 // store the result of minimum value after loop ends
NOP
38
Data Memory content before execution =>
As we can see, there is no result at address 9, as of now.
We have array of 5 length ( size written at memory address 2, which program would
need during execution ), which has numbers as we can see = {3, 5, 1, 2, 4}, starting
from memory address 3.
Register File contents during execution =>
39
Look up table showing entries of branch instructions, conditional branch, and
unconditional jump instr. =>
Data Memory content after execution =>
40
Here we can see, memory address 9 has minimun value “1”, among numbers (
3,5,1,2,4 ).
Simulation Waveforms =>
Register File data flow from it’s ports =>
Data Memory data flow from it’s ports =>
41
Conclusion
We made a processor based on given Instruction Set Architecture, and it is required
that it should overcome all dependency issues , so that no pipelining hazards should
occur and also to improve CPI, it should have Branch Prediction system and also R7
register should store PC value. So after making whole design, we picked couple of test
examples and run on our design of IITB-RISC processor, and all test cases
successfully passed and all simulation waveforms and modelsim output screenshots
are attached with the test examples.
42