Building A RISC-V Processor
Building A RISC-V Processor
INF107
When we talk about processor architecture, this can mean different things
Micro-architecture
Refers to the internal organisation of a specific processor or a family of processors in order to
implement its ISA.
Figure 3: Betty Jean Jennings and Fran Bilas programming the ENIAC
Programming language
• Symbolic
• Human readable (hopefully)
• Use of variables and functions
Machine language
• Concrete low level instructions
• Machine readable
• Binary (ones and zeros)
Input: Output:
int square(int x) {
return x * x;
}
int main() {
int x = square(42);
}
ISA-specific
Textual representation of
• Symbolic labels
• Instructions
• Registers
• Literals
Further directives (e.g. alignment)
Fixed number of registers
No complex control flow (no loops)
Lowest human-readable level
Input: Output:
0000000 0113 ff01 2623 0011 2423 0081 0413 0101
0000010 2823 fea4 2583 ff04 2503 ff04 0097 0000
0000020 80e7 0000 0793 0005 8513 0007 2083 00c1
0000030 2403 0081 0113 0101 8067 0000 0113 ff01
0000040 2623 0011 2423 0081 0413 0101 0513 02a0
0000050 0097 0000 80e7 0000 2823 fea4 0793 0000
0000060 8513 0007 2083 00c1 2403 0081 0113 0101
0000070 8067 0000
0000074
Control flow
Unconditional jump
Conditional branch
Call (save return address before jumping)
31 27 26 25 24 20 19 15 14 12 11 7 6 0
0000000 rs2 rs1 000 rd 0110011 ADD
funct7 funct3 opcode
What to do?
• opcode (register-to-register instruction)
• function fields (addition)
Where to get the operands?
• opcode (register-to-register instruction)
• rs1/rs2 (source registers)
Where to put the result?
• rd (destination register)
Memory
Processor
• Registers
• Lots of logic…
We will ignore peripherals for now
32
DAddr
32 32 32 32
IAddr IMem Instr WData DMem RData
1
write
32 bit Register 32 32
Stores address of current instruction nIAddr D Q IAddr
Initialised to address 0 PC
32
32
PC
Imem Instruction
What do we need?
32 registers of 32 bit 5
• Register 0 hard wired to 0 Register read index 1
5 32
Two separate read ports Register read index 2 Register data 1
5 Register
One write port Register write index
File 32
Combinatorial read Write
32
Register data 2
31 27 26 25 24 20 19 15 14 12 11 7 6 0
0000000 rs2 rs1 000 rd 0110011 ADD
funct7 funct3 opcode
What to do?
• opcode (register-to-register instruction)
• function fields (addition)
Where to get the operands?
• opcode (register-to-register instruction)
• rs1/rs2 (source registers)
Where to put the result?
• rd (destination register)
31 27 26 25 24 20 19 15 14 12 11 7 6 0
funct7 rs2 rs1 funct3 rd opcode R-type
31 27 26 25 24 20 19 15 14 12 11 7 6 0
0000000 rs2 rs1 000 rd 0110011 ADD
0100000 rs2 rs1 000 rd 0110011 SUB
0000000 rs2 rs1 001 rd 0110011 SLL
0000000 rs2 rs1 010 rd 0110011 SLT
0000000 rs2 rs1 011 rd 0110011 SLTU
0000000 rs2 rs1 100 rd 0110011 XOR
0000000 rs2 rs1 101 rd 0110011 SRL
0000000 rs2 rs1 110 rd 0110011 OR
0000000 rs2 rs1 111 rd 0110011 AND
Encoding
Encode the following instructions:
xor x8, x4, x5
sub x6, x15, x1
Decoding
Decode the following instructions:
0x003110b3
0x007067b3
Encoding
Encode the following instructions:
xor x8, x4, x5 # 0x00524433 (0000 0000 0101 0010 0100 0100 0011 0011)
sub x6, x15, x1 # 0x40178333 (0100 0000 0001 0111 1000 0011 0011 0011)
Decoding
Decode the following instructions:
0x003110b3 # sll x1, x2, x3
0x007067b3 # or x15, x0, x7
[11 : 7] 5
Register write index
4
ALU operation
[30][14 : 12]
32
Instruction
[19 : 15] 5
Register read index 1
5
Register read index 2
[24 : 20]
5
Register read index 1
5
Register read index 2
32 Decode 5
Instruction Register write index
Unit
Write
4
ALU operation
Operation (+, −, . . . )
5 32
Register read index 1
5 +
Register read index 2
5 Register n
Register write index
File 0
Write
⊕
Write data 32
32
Operation (+, −, . . . )
5 32
Register read index 1
5
Register read index 2
5 Register
Register write index
File 32
Write
Write data
32
32
4
+ [30][14 : 12]
32
[19 : 15] 32
[24 : 20] 32
32 [11 : 7] Register
PC
Imem File
1
32
32
[19 : 15] 32
x4 ⊕
[24 : 20] 32
x5
32 [11 : 7] Register x4 ⊕ x5
PC
Imem x8
File
0x100 0x00524433
1
32
31 27 26 25 24 20 19 15 14 12 11 7 6 0
imm[11:0] rs1 100 rd 0010011 XORI
imm funct3 opcode
Figure 8: Immediate instruction xori
31 27 26 25 24 20 19 15 14 12 11 7 6 0
imm[11:0] rs1 funct3 rd opcode I-type
31 27 26 25 24 20 19 15 14 12 11 7 6 0
imm[11:0] rs1 000 rd 0010011 ADDI
imm[11:0] rs1 010 rd 0010011 SLTI
imm[11:0] rs1 011 rd 0010011 SLTIU
imm[11:0] rs1 100 rd 0010011 XORI
imm[11:0] rs1 110 rd 0010011 ORI
imm[11:0] rs1 111 rd 0010011 ANDI
0000000 shamt rs1 001 rd 0010011 SLLI
0000000 shamt rs1 101 rd 0010011 SRLI
[11 : 7] 5
Register Write Index
4
0[14 : 12]
ALU Operation
32
Instruction
[19 : 15] 5
Register Read Index
12
Immediate operand
[31 : 20]
[11 : 7] 5
Register Write Index
4
ALU Operation Ignore bit 30!
0[14 : 12]
32
Instruction
[19 : 15] 5
Register Read Index
12
Immediate operand New!
[31 : 20]
4
+
op
rs1
rs2
rd
Decode
32 Register
PC
Imem File
write
1
0
imm
ALUsrc
31 27 26 25 24 20 19 15 14 12 11 7 6 0
imm[11:0] rs1 010 rd 0000011 LW
offset funct3 opcode
31 27 26 25 24 20 19 15 14 12 11 7 6 0
imm[11:5] rs2 rs1 010 imm[4:0] 0100011 SW
offset funct3 offset opcode
4
+ Addr
DMem
store op
rs1 WData RData
rs2 write
rd
Decode
Register
PC
Imem File
write
1
0
imm
load ALUsrc
DMem
store op
rs1 WData RData
back: rs2
rd
write
Decode
Register
PC
Imem File
0
imm
31 27 26 25 24 20 19 15 14 12 11 7 6 0
imm[12|10:5] rs2 rs1 100 imm[4:1|11] 1100011 BLT
offset funct3 offset opcode
31 27 26 25 24 20 19 15 14 12 11 7 6 0
imm[12|10:5] rs2 rs1 funct3 imm[4:1|11] opcode B-type
31 27 26 25 24 20 19 15 14 12 11 7 6 0
imm[12|10:5] rs2 rs1 000 imm[4:1|11] 1100011 BEQ
imm[12|10:5] rs2 rs1 001 imm[4:1|11] 1100011 BNE
imm[12|10:5] rs2 rs1 100 imm[4:1|11] 1100011 BLT
imm[12|10:5] rs2 rs1 101 imm[4:1|11] 1100011 BGE
imm[12|10:5] rs2 rs1 110 imm[4:1|11] 1100011 BLTU
imm[12|10:5] rs2 rs1 111 imm[4:1|11] 1100011 BGEU
0 4
+
[0]
Addr
DMem
store op
WData RData
branch
rs1
rs2 write
rd
Decode
Register
PC
Imem File
write
1
0
imm
load ALUsrc
0 4
Use lowest bit of ALU result for condition +
[0]
Addr
DMem
Choose ALU operation according to branch
store op
WData RData
branch
rs1
rs2 write
condition
rd
Decode
Register
PC
Imem
Multiplexer to select PC offset (4 or write
File
1
immediate)
imm
load ALUsrc
31 27 26 25 24 20 19 15 14 12 11 7 6 0
imm[20|10:1|11|19:12] rd 1101111 JAL
offset opcode
What do we need to add in order to implement jumps (not shown in this lecture)?
Alignment
.align N aligns next instruction or data to address divisible by 2𝑁
Needed e.g. to align constant data to word boundaries
Labels for
foo:
• Jump and branch targets addi t0, t0, 1
• Beginning of functions j foo
• Location of data
Use label instead of constant jump or
bar:
la a0, data
branch targets lw t0, 0(a0)
Use label to initialise a register with an
.align 2
address data:
.word 0xcafe
foo:
la s0, data # Load address of data into s0
lw a0, 0(s0) # Load word at data
lw a1, 4(s0) # Load word at data + 4
jal bar # Call function bar, save return address in ra
sw a0, 8(s0) # Store function result at data + 8
j end # jump to the end
bar:
add a0, a0, a1 # Add function arguments, save sum to a0
ret # Return to caller site (return address in ra)