0% found this document useful (0 votes)
27 views

Building A RISC-V Processor

Uploaded by

Patrick YT Teng
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
27 views

Building A RISC-V Processor

Uploaded by

Patrick YT Teng
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 70

Building a RISC-V Processor

INF107

Ulrich Kühne Florian Brandner Tarik Graba Guillaume Duc


2023
Introduction

2/70 2023 INF107 Building a RISC-V Processor


Overview – Putting it all together

In this chapter, you will find answers to the following questions:

What’s inside a computer?


What does a processor do?
How to talk to a processor?
How to build a (simple) processor?

3/70 2023 INF107 Building a RISC-V Processor


What’s inside a computer?

Figure 1: Things you typically find in a computer

4/70 2023 INF107 Building a RISC-V Processor


The Main Board

Figure 2: Main circuit board with different components

5/70 2023 INF107 Building a RISC-V Processor


A More Systematic View on Things

Central Processing Unit (CPU, processor)


Memory (random access memory, main
memory)
Mass storage (hard disk, SSD)
Input/output peripherals
• Keyboard
• Mouse or touchpad
• Screen display
• Audio input and output
• Network devices (WiFi, ethernet)
• Many more…

6/70 2023 INF107 Building a RISC-V Processor


A Word on Interconnections

Components are interconncted via busses


Serial bus
• Few pins and cables
• Slow communication
• Used for external peripherals
• Examples: USB, I2C, SPI
Parallel bus
• Many pins required
• Fast communication
• Used for on-board communication
• Examples: PCI, AXI
Wireless communication
• Examples: Bluetooth, WiFi, ZigBee

7/70 2023 INF107 Building a RISC-V Processor


The Central Processing Unit

Performs (most of) the computations


Reads data from memory or peripherals
Processes it
Sends result back to memory or peripherals

8/70 2023 INF107 Building a RISC-V Processor


Processor Architecture

When we talk about processor architecture, this can mean different things

Instruction Set Architecture (ISA)


Determines the elementary operations (instructions) a processor can perform.

Micro-architecture
Refers to the internal organisation of a specific processor or a family of processors in order to
implement its ISA.

9/70 2023 INF107 Building a RISC-V Processor


Some Instruction Set Architectures
ARM
• Family of ISAs developed by ARM
• Used in embedded systems (mobile and low power)
and desktop (Apple’s M1)
x86
• Family of ISAs developed by Intel (and AMD)
• Used in general purpose computing systems (desktop
and servers)
RISC-V
• Family of open standard ISAs developed by University
of California, Berkeley
• Mostly used in embedded systems
MOS 6502
• Historical 8 bit architecture
• Used in first home computers (Commodore 64, Apple II)
and game consoles (Atari)

10/70 2023 INF107 Building a RISC-V Processor


Performance and Trade-Offs

Performance indicators of a processor


Instructions executed per second
Logic complexity (e.g. number of gates)
Power consumption
predictability / real-time behavior

Different architectural trade-offs


General purpose processor (GPP) Embedded micro-controller
• High average performance • Low performance
• High cost and power consumption • Low cost and power consumption
• Poor predictability • Good predictability

11/70 2023 INF107 Building a RISC-V Processor


The Machine Language

12/70 2023 INF107 Building a RISC-V Processor


How to Talk to a Processor?

Figure 3: Betty Jean Jennings and Fran Bilas programming the ENIAC

13/70 2023 INF107 Building a RISC-V Processor


How to Talk to a Processor?

Programming language
• Symbolic
• Human readable (hopefully)
• Use of variables and functions
Machine language
• Concrete low level instructions
• Machine readable
• Binary (ones and zeros)

How to close this gap?

14/70 2023 INF107 Building a RISC-V Processor


From High Level Language to Machine Language

Figure 4: The compilation process

15/70 2023 INF107 Building a RISC-V Processor


Compilation

Input: Output:
int square(int x) {
return x * x;
}

int main() {
int x = square(42);
}

16/70 2023 INF107 Building a RISC-V Processor


Assembler Code

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

17/70 2023 INF107 Building a RISC-V Processor


Assembler

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

18/70 2023 INF107 Building a RISC-V Processor


Instruction Classes (in RISC-V)

Arithmetic and logic instructions


Addition, subtraction
Bitwise and
Left shift

Memory access instructions


Load (fetch data from memory to a register)
Store (save data from a register to memory)

Control flow
Unconditional jump
Conditional branch
Call (save return address before jumping)

19/70 2023 INF107 Building a RISC-V Processor


How to execute an instruction?

1. Read the instruction word from memory (fetch)


2. Determine the type of the instruction and its operands (decode)
3. Perform the demanded computations (execute)
4. Store the result in the requested location (write back)
5. Determine the next instruction and start again

20/70 2023 INF107 Building a RISC-V Processor


The RISC-V Instruction Set

Fixed size of 32 bits


32 registers
Load-store architecture
• Arithmetic and logic instructions working on registers only
• Specific instructions to move data from and to memory
Reduced Instruction Set (RISC) ISA
• Few (49) instructions in the base ISA
• Few and regular instruction formats
• Allows for very small hardware implementations
Standardized extensions of base ISA
• Multiplication and division
• Floating point
• Bit manipulation
• Vector computations
• …

21/70 2023 INF107 Building a RISC-V Processor


Example of A RISC-V Instruction

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)

22/70 2023 INF107 Building a RISC-V Processor


Building a RISC-V Processor

23/70 2023 INF107 Building a RISC-V Processor


Basic Ingredients

Memory
Processor
• Registers
• Lots of logic…
We will ignore peripherals for now

24/70 2023 INF107 Building a RISC-V Processor


Memory

Separate instruction and data memory (Harvard architecture)


Combinatorial read (result in the same cycle)
Synchronous write (update at rising edge)

32
DAddr
32 32 32 32
IAddr IMem Instr WData DMem RData
1
write

Figure 5: Instruction memory Figure 6: Data memory

25/70 2023 INF107 Building a RISC-V Processor


Program Counter

32 bit Register 32 32
Stores address of current instruction nIAddr D Q IAddr
Initialised to address 0 PC

26/70 2023 INF107 Building a RISC-V Processor


Putting things together: Fetching instructions
1. Read the instruction word from memory Program starts at address 0 (simplification)
2. Decode the instruction Fixed size instructions of 32 bits (4 bytes)
3. Perform the demanded computations Fetch consecutive instructions
4. Store the result
5. Determine the next instruction
32

32

32
PC

Imem Instruction

27/70 2023 INF107 Building a RISC-V Processor


Doing the actual work

1. Read the instruction word from memory


2. Decode the instruction
3. Perform the demanded computations
4. Store the result
5. Determine the next instruction

What do we need?

A circuit to decode the instruction


A place to store operands and results
Arithmetic and logic operators

28/70 2023 INF107 Building a RISC-V Processor


Register File

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

Synchronous write Write data

29/70 2023 INF107 Building a RISC-V Processor


Decoding instructions

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)

30/70 2023 INF107 Building a RISC-V Processor


R-type Instructions

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

Figure 7: R-type instructions

31/70 2023 INF107 Building a RISC-V Processor


Exercise: Encoding and Decoding Instructions

Encoding
Encode the following instructions:
xor x8, x4, x5
sub x6, x15, x1

Decoding
Decode the following instructions:
0x003110b3
0x007067b3

32/70 2023 INF107 Building a RISC-V Processor


Solution: Encoding and Decoding Instructions

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

33/70 2023 INF107 Building a RISC-V Processor


Decode Unit for R-type Instructions
I0
I1
I2
opcode I3 always 01100112 (for now)
I4
I5
I6
I7
I8
5
rd I9 Register write index
I10
I11
I12
3
funct3 I13 ALU operation
I14
32 I15
Instruction I16
5
rs1 I17 Register read index 1
I18
I19
I20
I21
5
rs2 I22 Register read index 2
I23
I24
I25
I26
I27
7
funct7 I28 ALU operation
I29
I30
I31

34/70 2023 INF107 Building a RISC-V Processor


Decode Unit for R-type Instructions

[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]

Decode by redirecting wires (for now)


Only need bit 6 of funct7 (bit 30 of instruction)

35/70 2023 INF107 Building a RISC-V Processor


Decode Unit for R-type Instructions

5
Register read index 1
5
Register read index 2
32 Decode 5
Instruction Register write index
Unit
Write
4
ALU operation

36/70 2023 INF107 Building a RISC-V Processor


Putting things together: R-type Instructions

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

37/70 2023 INF107 Building a RISC-V Processor


Putting things together: R-type Instructions

Operation (+, −, . . . )

5 32
Register read index 1
5
Register read index 2
5 Register
Register write index
File 32
Write
Write data

32

38/70 2023 INF107 Building a RISC-V Processor


Putting things together: R-type Instructions

32

4
+ [30][14 : 12]
32

[19 : 15] 32
[24 : 20] 32

32 [11 : 7] Register
PC

Imem File
1

32

39/70 2023 INF107 Building a RISC-V Processor


Putting things together: R-type Instructions

32

xor x8, x4, x5


4
+ [30][14 : 12]
32 0x104

[19 : 15] 32
x4 ⊕
[24 : 20] 32
x5
32 [11 : 7] Register x4 ⊕ x5
PC

Imem x8
File
0x100 0x00524433
1

32

40/70 2023 INF107 Building a RISC-V Processor


Going Further

First working processor implementation


How to use constant values
• in computations?
• to initialise registers?

41/70 2023 INF107 Building a RISC-V Processor


Immediate Instructions

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

New opcode 0010011


Constant encoded in instruction word
12 bit integer value ∈ [−2048, 2047]
Sign extension to 32 bits
Use register rs1 as second operand
Store result in register rd

42/70 2023 INF107 Building a RISC-V Processor


Immediate Instructions

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

43/70 2023 INF107 Building a RISC-V Processor


Decoding Immediate Instructions

[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]

44/70 2023 INF107 Building a RISC-V Processor


Decoding Immediate Instructions

[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]

45/70 2023 INF107 Building a RISC-V Processor


Decoder Unit for R-type and I-type Instructions

5 Sign extended Immediate value


5
Register read index 1
ALU source signal to select
32 5
Register read index 2 between rs2 (1) and Immediate (0)
Instruction Register write index Implementation left as an exercise
Decode
Write
Unit 4
ALU operation
ALU source
32
Immediate

46/70 2023 INF107 Building a RISC-V Processor


Putting things together: R-type and I-type Data Path

4
+
op
rs1

rs2

rd

Decode
32 Register
PC

Imem File
write
1

0
imm

ALUsrc

47/70 2023 INF107 Building a RISC-V Processor


What’s missing?

Why is there no subi (subtract immediate)


instruction?
Why is there no not (bitwise negation)
instrucion?

48/70 2023 INF107 Building a RISC-V Processor


What else?

How to use data from memory?


How to store results in memory?

49/70 2023 INF107 Building a RISC-V Processor


Load Instruction(s)

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

Load word (32 bits) from memory to register rd


Address from register rs1 plus immediate offset
Similar instructions for different data sizes
• lb: load byte (8 bits)
• lh: load half-word (16 bits)
Assembler syntax: lw s0, 8(a0) loads MEM[𝑎0 + 8] in register s0

50/70 2023 INF107 Building a RISC-V Processor


Store Instruction(s)

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

Store word (32 bits) to memory from register rs2


Adress from register rs1 plus immediate offset
Similar instructions for different data sizes
• sb: store byte (8 bits)
• sh: store half-word (16 bits)
Assembler syntax: sw s0, 8(a0) stores register s0 in MEM[𝑎0 + 8]

51/70 2023 INF107 Building a RISC-V Processor


Data Path for Load/Store Instructions

Propose a data path for load and store! 32


DAddr
32 32
WData DMem RData
1
write

52/70 2023 INF107 Building a RISC-V Processor


Data Path for Load/Store Instructions

4
+ Addr

DMem
store op
rs1 WData RData

rs2 write

rd

Decode
Register
PC

Imem File
write
1

0
imm

load ALUsrc

53/70 2023 INF107 Building a RISC-V Processor


Data Path for Load/Store Instructions

New control signals load and store 4

New multiplexer to choose data to write + Addr

DMem
store op
rs1 WData RData

back: rs2

rd
write

• ALU result (load = 0)

Decode
Register

PC
Imem File

• Memory read data (load = 1)


write
1

0
imm

Use ALU to compute memory address offset load ALUsrc

• ALU operation is addition


0

• Select immediate input (ALUsrc = 0)


Register rs2 fed to memory data input

54/70 2023 INF107 Building a RISC-V Processor


Adding Control Flow

How to jump to another address?


How to jump depending on a certain
condition?
How to implement loops?
How to call a function?
How to return from a function?

55/70 2023 INF107 Building a RISC-V Processor


Conditional Branches

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

Instruction blt: Branch if less than


New opcode 1100011
Tests if register rs1 is less than register rs2
Jumps to address PC + offset if condition is true
Offset in range [−4096, 4095] (LSB is always zero)

56/70 2023 INF107 Building a RISC-V Processor


Conditional Branches

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

beq: Branch if equal bge: Branch if greater or equal


bne: Branch if not equal bltu: Branch if less than unsigned
blt: Branch if less than bgeu: Branch if greater or equal unsigned

57/70 2023 INF107 Building a RISC-V Processor


Conditional Branches

Propose a data path to implement branches!

58/70 2023 INF107 Building a RISC-V Processor


Data Path for B-type Instructions

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

59/70 2023 INF107 Building a RISC-V Processor


Data Path for B-type Instructions

New control signal branch 1

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

60/70 2023 INF107 Building a RISC-V Processor


Unconditional Jump/Call

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

jal: jump and link


Jump to address PC + offset
Offset in range [−1.048.576, 1.048.575]
Store PC + 4 in register rd
31 27 26 25 24 20 19 15 14 12 11 7 6 0
imm[11:0] rs1 000 rd 1100111 JALR
offset funct3 opcode

jalr: jump and link register


Same as jal, with target address register rs1 plus offset

61/70 2023 INF107 Building a RISC-V Processor


Data Path for Jump Instructions

What do we need to add in order to implement jumps (not shown in this lecture)?

62/70 2023 INF107 Building a RISC-V Processor


Miscellaneous Instructions

Some instructions not covered in this lecture:

lui: load upper immediate (→ homework)


auipc: add upper immediate to PC (used for long jumps)
ecall, ebreak: switching privilege level (→ third part of this lecture)

63/70 2023 INF107 Building a RISC-V Processor


RISC-V Assembler

64/70 2023 INF107 Building a RISC-V Processor


Register Names

Reg Name Usage Reg Name Usage

x0 zero Constant zero x12 a2 Function argument 2


x1 ra Return address ... ... …
x2 sp Stack pointer x17 a7 Function argument 7
x3 gp Global pointer x18 s2 Saved register 2
x4 tp Thread pointer ... ... …
x5 t0 Temporary register 0 x27 s11 Saved register 11
x6 t1 Temporary register 1 x28 t3 Temporary register 3
x7 t2 Temporary register 2 ... ... …
x8 s0 / fp Saved register 0 / frame pointer x31 t6 Temporary register 6
x9 s1 Saved register 1
x10 a0 Function argument 0 / return value 0
x11 a1 Function argument 1 / return value 1

65/70 2023 INF107 Building a RISC-V Processor


Pseudo Instructions

Convenient names for important use cases


Leads to more readable code

Mnemonic Usage Translated to

nop No operation addi zero, zero, 0


mv Copy register addi rd, rs, 0
not Bitwise negation xori rd, rs, -1
li Load immediate (lui +) addi
la Load address auipc + addi
j Jump jal zero
call Jump to subroutine jal ra
ret Return from subroutine jalr zero, 0(ra)

66/70 2023 INF107 Building a RISC-V Processor


Directives

Encoding constant data


.byte 0xff: 8 bit constant value
.half 0xeeff: 16 bit constant value
.word 0xaabbccdd: 32 bit constant value
.dword 0x00112233aabbccdd: 64 bit constant value

Alignment
.align N aligns next instruction or data to address divisible by 2𝑁
Needed e.g. to align constant data to word boundaries

67/70 2023 INF107 Building a RISC-V Processor


Labels

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

68/70 2023 INF107 Building a RISC-V Processor


Example Program

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)

.align 2 # Some data to be processed


data:
.word 0x0000cafe, 0x00010023, 0x0

end: # This is the end


nop

69/70 2023 INF107 Building a RISC-V Processor


Summary

Different processor architecture trade-offs


Programs are compiled to machine code
Instructions are simple elementary operations
Example in this lecture: RISC-V base ISA
Fetch, decode, execute, write-back cycle
Construct data path from basic logic components
Low-level programming in assembler

70/70 2023 INF107 Building a RISC-V Processor

You might also like