This repository is intended to document the learning outcomes and experience of a 4-week workshop on RISC-V using Open source tools like yosys and Skywater 130nm PDK.
Summary
Installed all required tools.
Riscv GNU Toolchain
git clone https://github.com/riscv/riscv-gnu-toolchain
sudo apt-get install autoconf automake autotools-dev curl python3 python3-pip libmpc-dev libmpfr-dev libgmp-dev gawk build-essential bison flex texinfo gperf libtool
patchutils bc zlib1g-dev libexpat-dev ninja-build git cmake libglib2.0-dev
./configure --prefix=/opt/riscv
makeYosys
git clone https://github.com/YosysHQ/yosys.git
cd yosys
sudo apt install make
sudo apt-get install build-essential clang bison flex \
libreadline-dev gawk tcl-dev libffi-dev git \
graphviz xdot pkg-config python3 libboost-system-dev \
libboost-python-dev libboost-filesystem-dev zlib1g-dev
make config-gcc
make
sudo make installOpenSTA
git clone https://github.com/The-OpenROAD-Project/OpenSTA.git
cd OpenSTA
mkdir build
cd build
cmake ..
makeNgspice
tar -zxvf ngspice-37.tar.gz
cd ngspice-37
mkdir release
cd release
../configure --with-x --with-readline=yes --disable-debug
make
sudo make installMagic
sudo apt-get install m4
sudo apt-get install tcsh
sudo apt-get install csh
sudo apt-get install libx11-dev
sudo apt-get install tcl-dev tk-dev
sudo apt-get install libcairo2-dev
sudo apt-get install mesa-common-dev libglu1-mesa-dev
sudo apt-get install libncurses-devOpenLane
sudo apt-get update
sudo apt-get upgrade
sudo apt install -y build-essential python3 python3-venv python3-pip make git
sudo apt install apt-transport-https ca-certificates curl software-properties-common
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg
echo "deb [arch=amd64 signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
sudo apt update
sudo apt install docker-ce docker-ce-cli containerd.io
sudo docker run hello-world
sudo groupadd docker
sudo usermod -aG docker $USER
sudo rebootIdentifying Instruction Type
In RISC-V, the base instruction format is a 32-bit instruction word divided into several fields. The basic format consists of opcode, rd (destination register), funct3 (function 3), rs1 (source register 1), imm (immediate value), and funct7 (function 7). This design allows for a wide range of instructions while maintaining simplicity and flexibility, which are key principles of the RISC-V architecture.
add r6,r2,r1
This is an R type instruction - instructions using 3 register inputs
– add, xor, mul —arithmetic/logical operations.
32-bit instruction format of R-format:
- opcode: Partially identifies the operation type (add in this case) (Bit 0 to Bit 6)
- rd: Specifies the destination register where the result will be stored (r6) (Bit 7 to Bit 11)
- funct3: Further encodes the operation (000 for addition) (Bit 12 to Bit 14)
- rs1: Specifies the first source register to be added (r2) (Bit 15 to Bit 19)
- rs2: Specifies the second source register to be add (r1) (Bit 20 to Bit 24)
- funct7: Specifies the exact operation to be executed (Bit 25 to Bit 31)
add x1, x2, x3 R-type
0000000 00011 00010 000 00001 0110011
funct7 x3 x2 funct3 x1 opcode
Compiling C code using Risc-V GNU Toolchain
#include<stdio.h>
int main() {
int sum=0, i=1, n=100;
for(i = 1; i <= n; ++i){
sum += 1;
}
printf("Sum of numbers from 1 to %d is %d \n",n,sum);
return 0;
}Checking if output of GCC and RISC-V GCC is same
The C code should give the same output when compiled using GCC X86 Compiler (F1) and riscv compiler (F2) (SPIKE Simulation)
To the C code on your terminal, run the following command:
```
gcc sum.c
./a.out
```
Assembly produced by x86 gcc compiler :
sahilprabhu@sahil:~$ cat sum.s
.file "sum.c"
.text
.section .rodata
.align 8
.LC0:
.string "sum of numbers from 1 to %d is %d \n"
.text
.globl main
.type main, @function
main:
.LFB0:
.cfi_startproc
endbr64
pushq %rbp
.cfi_def_cfa_offset 16
.cfi_offset 6, -16
movq %rsp, %rbp
.cfi_def_cfa_register 6
subq $16, %rsp
movl $0, -8(%rbp)
movl $100, -4(%rbp)
movl $1, -12(%rbp)
jmp .L2
.L3:
movl -12(%rbp), %eax
addl %eax, -8(%rbp)
addl $1, -12(%rbp)
.L2:
movl -12(%rbp), %eax
cmpl -4(%rbp), %eax
jl .L3
movl -8(%rbp), %edx
movl -4(%rbp), %eax
movl %eax, %esi
leaq .LC0(%rip), %rax
movq %rax, %rdi
movl $0, %eax
call printf@PLT
movl $0, %eax
leave
.cfi_def_cfa 7, 8
ret
.cfi_endproc
.LFE0:
.size main, .-main
.ident "GCC: (Ubuntu 13.2.0-23ubuntu4) 13.2.0"
.section .note.GNU-stack,"",@progbits
.section .note.gnu.property,"a"
.align 8
.long 1f - 0f
.long 4f - 1f
.long 5
0:
.string "GNU"
1:
.align 8
.long 0xc0000002
.long 3f - 2f
2:
.long 0x3
3:
.align 8
4:
Now run the following command to compile the code in riscv64 gcc compiler:
riscv64-unknown-elf-gcc -O1 -mabi=lp64 -march=rv64i -o sum.o sum.c
riscv64-unknown-elf-objdump -d sum.o | less
Type /main and press enter to find assembly code of sum.c program.
-Ofast: The option -Ofast in the command riscv64-unknown-elf-gcc -Ofast -mabi=lp64 -march=rv64i -o sum1ton.o sum1ton.c is a compiler optimization flag used with the GNU Compiler Collection (GCC). This flag is used to instruct the compiler to optimize the generated code for maximum speed. The use of -Ofast is typically chosen for applications where execution speed is critical and where deviations from standard behavior are acceptable. However, it's important to test thoroughly, as this level of optimization can introduce subtle bugs, especially in complex calculations or when strict compliance with external standards is required.
Debugging line by line using spike pk
spike -d pk sum.o
Running Verilog code and Testbench using IVerilog and simulating waveforms
Instruction to be run -
Instruction 1:add r6,r2,r1
Verilog Design Code
iiitb_rv32i.v
Verilog Testbench
iiitb_rv32i_tb.v
GTK Waveform Simulations
Where ID_EX_A and ID_EX_B are the Oprands,ADD=0 is operation, EX_MEM_ALUOUT is the output and EX_MEM_IR is the ADD OPCode/Instruction Code
Gate Level Simulation
GLS is generating the simulation output by running test bench with netlist file generated from synthesis as design under test. Netlist is logically same as RTL code, therefore, same test bench can be used for it.We perform this to verify logical correctness of the design after synthesizing it. Also ensuring the timing of the design is met. Folllowing are the commands to run the GLS simulation:
The output waveform of the synthesized netlist given below:
As we can see GLS is matching RTL Waveforms.



























