Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
168 changes: 70 additions & 98 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,10 +1,24 @@
# biRISC-V - 32-bit dual issue RISC-V CPU
<div align="center"> <h1> Computer Organization and Architecture III </h1>
</div>

This project is part of the Computer Organization and Architecture III (2024.2) course. The objective of the project was to implement a logical synthesis of [biRISC-V Core](http://github.com/ultraembedded/biriscv) using IBM 180 PDK and perform a Gate Level Simulation.


1. [biRISC-V](#biriscv)
2. [Logic Synthesis](#logic-synthesis)
3. [Generating Applications](#generating-applications)
4. [Gate Level Simulation](#gate-level-simulation)

<hr />

## biRISC-V <a name="biriscv"></a>

biRISC-V is a 32-bit dual issue RISC-V CPU made by [Ultraembedded](http://github.com/ultraembedded).

Github: [http://github.com/ultraembedded/biriscv](http://github.com/ultraembedded/biriscv)

![biRISC-V](docs/biRISC-V.png)

## Features
### Features
* 32-bit RISC-V ISA CPU core.
* Superscalar (dual-issue) in-order 6 or 7 stage pipeline.
* Support RISC-V’s integer (I), multiplication and division (M), and CSR instructions (Z) extensions (RV32IMZicsr).
Expand All @@ -26,109 +40,67 @@ Github: [http://github.com/ultraembedded/biriscv](http://github.com/ultraembedde
*A sequence showing execution of 2 instructions per cycle;*
![Dual-Issue](docs/dual_issue.png)

## Documentation
* [Configuration](docs/configuration.md)
* [Booting Linux](docs/linux.md)
* [Integration](docs/integration.md)
* [Custom Features](docs/custom.md)

## Similar Cores
* [SiFive E76](https://www.sifive.com/cores/e76)
* RV32IMAFC
* Dual issue in-order 8 stage pipeline
* 4 ALU units (2 early, 2 late)
* :heavy_multiplication_x: *Commercial closed source core/$$*
* [WD SweRV RISC-V Core EH1](https://github.com/chipsalliance/Cores-SweRV)
* RV32IMC
* Dual issue in-order 9 stage pipeline
* 4 ALU units (2 early, 2 late)
* :heavy_multiplication_x: *System Verilog + auto signal hookup*
* :heavy_multiplication_x: *No data cache option*
* :heavy_multiplication_x: *Not able to boot Linux*

## Project Aims
* Boot Linux all the way to a functional userspace environment. :heavy_check_mark:
* Achieve competitive performance for this class of in-order machine (i.e. aim for 80% of WD SweRV CoreMark score). :heavy_check_mark:
* Reasonable PPA / FPGA resource friendly. :heavy_check_mark:
* Fit easily onto cheap hobbyist FPGAs (e.g. Xilinx Artix 7) without using all LUT resources and synthesize > 50MHz. :heavy_check_mark:
* Support various cache and TCM options. :heavy_check_mark:
* Be constructed using readable, maintainable and documented IEEE 1364-2001 Verilog. :heavy_check_mark:
* Simulate in open-source tools such as Verilator and Icarus Verilog. :heavy_check_mark:
* *In later releases, add support for atomic extensions.*

*Booting the stock Linux 5.0.0-rc8 kernel built for RV32IMA to userspace on a Digilent Arty Artix 7 with biRISC-V (with atomic instructions emulated in the bootloader);*
![Linux-Boot](docs/linux-boot.png)

## Prior Work
Based on my previous work;
* Github: [http://github.com/ultraembedded/riscv](http://github.com/ultraembedded/riscv)

## Getting Started

#### Cloning

To clone this project and its dependencies;
## Logic Synthesis <a name="logic-synthesis"></a>

The synsthesis was performed with <i> Cadence RTL Compiler</i> , the execution scripts and the PDK (IBM 180) were provided by professor Mateus Beck.

The core modules that must be included in the synthesis filelist are:

```
project
└───src
│ biriscv_defs.v
│ biriscv_alu.v
│ biriscv_csr_regfile.v
│ biriscv_csr.v
│ biriscv_decoder.v
│ biriscv_decode.v
│ biriscv_divider.v
│ biriscv_exec.v
│ biriscv_fetch.v
│ biriscv_frontend.v
│ biriscv_issue.v
│ biriscv_lsu.v
│ biriscv_mmu.v
│ biriscv_multiplier.v
│ biriscv_npc.v
│ biriscv_pipe_ctrl.v
│ biriscv_regfile.v
│ biriscv_trace_sim.v
│ biriscv_xilinx_2r1w.v
│ riscv_core.v
```
git clone --recursive https://github.com/ultraembedded/biriscv.git

The non-synthesizable testbench modules are:

```
project
└───tb
└───tb_core_icarus
│ tcm_mem_ram.v
│ tcm_mem.v
│ biriscv_trace_sim_gls.sv
│ tb_top.v

```

#### Running Helloworld
## Generating Applications <a name="generating-applications"></a>

To run a simple test image on the core RTL using Icarus Verilog;
On `riscv-app-gen` you can find some risc-v applications (C, bin, elf) in the subdirectories. Also, you can generate your own program file by executing the `make` command specifying the C code e.g `make SRC=main.c`.

```
# Install Icarus Verilog (Debian / Ubuntu / Linux Mint)
sudo apt-get install iverilog
You must have [riscv-gnu-toolchain](https://github.com/riscv-collab/riscv-gnu-toolchain) installed with Linux multilib and available in your `PATH` environment variable.

# [or] Install Icarus Verilog (Redhat / Centos)
#sudo yum install iverilog
The linker script `riscv-app-gen/link.ld` was obtained from [Google's RISCV-DV](https://github.com/google/riscv-dv).

# Run a simple test image (test.elf)
cd tb/tb_core_icarus
make
```
The entry point specified in the linker command is the main function, therefore, you must check the entry point address code with the comand `make info` e.g `make info ELF=main.elf`. This entry point is required to execute the testbench and need to be passed to the `reset_vector_i` input in `src/riscv_core.v` .

The expected output is;
```
Starting bench
VCD info: dumpfile waveform.vcd opened for output.

Test:
1. Initialised data
2. Multiply
3. Divide
4. Shift left
5. Shift right
6. Shift right arithmetic
7. Signed comparision
8. Word access
9. Byte access
10. Comparision
```

#### Configuration

| Param Name | Valid Range | Description |
| ------------------------- |:--------------------:| ----------------------------------------------|
| SUPPORT_SUPER | 1/0 | Enable supervisor / user privilege levels. |
| SUPPORT_MMU | 1/0 | Enable basic memory management unit. |
| SUPPORT_MULDIV | 1/0 | Enable HW multiply / divide (RV-M). |
| SUPPORT_DUAL_ISSUE | 1/0 | Support superscalar operation. |
| SUPPORT_LOAD_BYPASS | 1/0 | Support load result bypass paths. |
| SUPPORT_MUL_BYPASS | 1/0 | Support multiply result bypass paths. |
| SUPPORT_REGFILE_XILINX | 1/0 | Support Xilinx optimised register file. |
| SUPPORT_BRANCH_PREDICTION | 1/0 | Enable branch prediction structures. |
| NUM_BTB_ENTRIES | 2 - | Number of branch target buffer entries. |
| NUM_BTB_ENTRIES_W | 1 - | Set to log2(NUM_BTB_ENTRIES). |
| NUM_BHT_ENTRIES | 2 - | Number of branch history table entries. |
| NUM_BHT_ENTRIES_W | 1 - | Set to log2(NUM_BHT_ENTRIES_W). |
| BHT_ENABLE | 1/0 | Enable branch history table based prediction. |
| GSHARE_ENABLE | 1/0 | Enable GSHARE branch prediction algorithm. |
| RAS_ENABLE | 1/0 | Enable return address stack prediction. |
| NUM_RAS_ENTRIES | 2 - | Number of return stack addresses supported. |
| NUM_RAS_ENTRIES_W | 1 - | Set to log2(NUM_RAS_ENTRIES_W). |
| EXTRA_DECODE_STAGE | 1/0 | Extra decode pipe stage for improved timing. |
| MEM_CACHE_ADDR_MIN | 32'h0 - 32'hffffffff | Lowest cacheable memory address. |
| MEM_CACHE_ADDR_MAX | 32'h0 - 32'hffffffff | Highest cacheable memory address. |
## Gate Level Simulation <a name="gate-level-simulation"></a>

Post-synthesis Simulation using Cadence SimVision. Bubble sort execution.

![Dual-Issue](docs/gls_sim_vision_bubble.png)
Binary file added docs/gls_sim_vision_bubble.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
32 changes: 32 additions & 0 deletions riscv-app-gen/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@

SRC ?= main.c

CC = riscv64-unknown-elf-gcc
OBJDUMP = riscv64-unknown-elf-objdump
READELF = riscv64-unknown-elf-readelf
OBJCOPY = riscv64-unknown-elf-objcopy

CFLAGS = -march=rv32im -mabi=ilp32
GCC_LDFLAGS = -T link.ld -nostartfiles -e main -O2

OBJ = $(SRC:.c=.o)
ELF = $(SRC:.c=.elf)
ASM = $(SRC:.c=.s)
BIN = $(SRC:.c=.bin)

# Regras
all: gcc_elf

info: $(ELF)
$(READELF) -h $(ELF)

gcc_elf: $(SRC)
$(CC) $(CFLAGS) $(GCC_LDFLAGS) -o $(ELF) $<
$(OBJCOPY) -O binary $(ELF) $(BIN)
$(OBJDUMP) -d $(ELF) > $(ASM)
$(READELF) -h $(ELF)

clean:
rm -f *.o *.elf *.s *.bin

.PHONY: all clean info
Binary file added riscv-app-gen/array_sum_mul/arraysum_mul.bin
Binary file not shown.
23 changes: 23 additions & 0 deletions riscv-app-gen/array_sum_mul/arraysum_mul.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
#include <stdio.h>


int main() {
int vetor1[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 7};
int vetor2[] = {7, 1, 8, 7, 6, 5, 4, 3, 2, 1};

int vetor_soma[10];
int vetor_produto[10];

// Multiplicacao ingenua
for (int i = 0; i < 10; i++) {
vetor_produto[i] = vetor1[i] * vetor2[i];
}

// Soma
for (int i = 0; i < 10; i++) {
vetor_soma[i] = vetor1[i] + vetor2[i];
}


return 0;
}
Binary file added riscv-app-gen/array_sum_mul/arraysum_mul.elf
Binary file not shown.
9 changes: 9 additions & 0 deletions riscv-app-gen/array_sum_mul/arraysum_mul.s
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@

arraysum_mul.elf: file format elf32-littleriscv


Disassembly of section .text.startup:

80000000 <main>:
80000000: 00000513 li a0,0
80000004: 00008067 ret
Binary file added riscv-app-gen/bubblesort/bubblesort.bin
Binary file not shown.
23 changes: 23 additions & 0 deletions riscv-app-gen/bubblesort/bubblesort.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
#include <stdio.h>

void bubbleSort(int arr[], int n) {
for (int i = 0; i < n - 1; i++) {
for (int j = 0; j < n - i - 1; j++) {
if (arr[j] > arr[j + 1]) {
// Troca os elementos
int temp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = temp;
}
}
}
}

int main() {
int arr[] = {5, 4, 3, 2, 1, 0,3};

bubbleSort(arr, 7);

return 0;
}

Binary file added riscv-app-gen/bubblesort/bubblesort.elf
Binary file not shown.
57 changes: 57 additions & 0 deletions riscv-app-gen/bubblesort/bubblesort.s
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@

bubblesort.elf: file format elf32-littleriscv


Disassembly of section .text:

80000000 <bubbleSort>:
80000000: 00100813 li a6,1
80000004: 04b85063 bge a6,a1,80000044 <bubbleSort+0x44>
80000008: 00259613 slli a2,a1,0x2
8000000c: 00c50633 add a2,a0,a2
80000010: 00450513 addi a0,a0,4
80000014: 00050793 mv a5,a0
80000018: 02b85863 bge a6,a1,80000048 <bubbleSort+0x48>
8000001c: ffc7a703 lw a4,-4(a5)
80000020: 0007a683 lw a3,0(a5)
80000024: 00e6d663 bge a3,a4,80000030 <bubbleSort+0x30>
80000028: fed7ae23 sw a3,-4(a5)
8000002c: 00e7a023 sw a4,0(a5)
80000030: 00478793 addi a5,a5,4
80000034: fec794e3 bne a5,a2,8000001c <bubbleSort+0x1c>
80000038: fff58593 addi a1,a1,-1
8000003c: ffc60613 addi a2,a2,-4
80000040: fd059ae3 bne a1,a6,80000014 <bubbleSort+0x14>
80000044: 00008067 ret
80000048: fff58593 addi a1,a1,-1
8000004c: ffc60613 addi a2,a2,-4
80000050: fc5ff06f j 80000014 <bubbleSort+0x14>

Disassembly of section .text.startup:

80000054 <main>:
80000054: 800007b7 lui a5,0x80000
80000058: 0b878793 addi a5,a5,184 # 800000b8 <main+0x64>
8000005c: 0007a303 lw t1,0(a5)
80000060: 0047a883 lw a7,4(a5)
80000064: 0087a803 lw a6,8(a5)
80000068: 00c7a603 lw a2,12(a5)
8000006c: 0107a683 lw a3,16(a5)
80000070: 0147a703 lw a4,20(a5)
80000074: 0187a783 lw a5,24(a5)
80000078: fd010113 addi sp,sp,-48
8000007c: 00410513 addi a0,sp,4
80000080: 00700593 li a1,7
80000084: 02112623 sw ra,44(sp)
80000088: 00612223 sw t1,4(sp)
8000008c: 01112423 sw a7,8(sp)
80000090: 01012623 sw a6,12(sp)
80000094: 00c12823 sw a2,16(sp)
80000098: 00d12a23 sw a3,20(sp)
8000009c: 00e12c23 sw a4,24(sp)
800000a0: 00f12e23 sw a5,28(sp)
800000a4: f5dff0ef jal 80000000 <bubbleSort>
800000a8: 02c12083 lw ra,44(sp)
800000ac: 00000513 li a0,0
800000b0: 03010113 addi sp,sp,48
800000b4: 00008067 ret
Binary file added riscv-app-gen/dot_product/dotproduct.bin
Binary file not shown.
21 changes: 21 additions & 0 deletions riscv-app-gen/dot_product/dotproduct.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
#include <stdio.h>

int produto_escalar(const int *vetor1, const int *vetor2) {
int resultado = 0;
for (int i = 0; i < 7; i++) {
resultado += vetor1[i] * vetor2[i];
}
return resultado;
}

int main() {
int n;

int vector1[] = {5, 8, 0, 2, 1, 5,3};

int vector2[] = {7, 6, 1, 0, 4, 1,2};

int resultado = produto_escalar(vector1, vector2);

return 0;
}
Binary file added riscv-app-gen/dot_product/dotproduct.elf
Binary file not shown.
24 changes: 24 additions & 0 deletions riscv-app-gen/dot_product/dotproduct.s
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@

dotproduct.elf: file format elf32-littleriscv


Disassembly of section .text:

80000000 <produto_escalar>:
80000000: 00050793 mv a5,a0
80000004: 01c50613 addi a2,a0,28
80000008: 00000513 li a0,0
8000000c: 0007a703 lw a4,0(a5)
80000010: 0005a683 lw a3,0(a1)
80000014: 00478793 addi a5,a5,4
80000018: 00458593 addi a1,a1,4
8000001c: 02d70733 mul a4,a4,a3
80000020: 00e50533 add a0,a0,a4
80000024: fec794e3 bne a5,a2,8000000c <produto_escalar+0xc>
80000028: 00008067 ret

Disassembly of section .text.startup:

8000002c <main>:
8000002c: 00000513 li a0,0
80000030: 00008067 ret
Loading