To clone the project:
git clone https://github.com/RISCeirb/Risc-v-processor.git
This project explores the RISC-V instruction set, an open-source architecture designed to be simple, extensible, and modular. The processeur implemented is an adapted implementation of the paterson processeur for RISC-V in VHDL.
This repository provides simple implementations of various RISC-V processors and tests using ModelSim and Rars RISC-V Assembler and Runtime Simulator.
LAST VERSION : RV32IM
(WITHOUT CSR AND FENCE INSTRUCTION)
Note : To improve the RV32IM, the process to calcul the MUL and DIV need to be divided in cycle to increase the max frequency of the processeur, a control unit can be added to improve the couple of instruction DIV/REM. Just one calcul instead of two to improve the critical path.
The available processors have the RV32I Base Instruction Set: (WITHOUT CSR AND FENCE INSTRUCTION)
- Monocycle
- Pipeline
- Pipeline with Branch Predictor
Have made the processor following the RISC-V ISA and the Patterson Book describing a MIPS processor.
Here the difference:
RISC-V | MIPS | |
---|---|---|
Similarities | - Based on RISC architecture | - Based on RISC architecture |
- Load/Store architecture | - Load/Store architecture | |
- 32 general-purpose registers with a fixed zero register | - 32 general-purpose registers with a fixed zero register | |
- Fixed-size instructions (32 bits) | - Fixed-size instructions (32 bits) | |
- Register to register operation | - Register to register operation | |
Differences | - Open-source, modular, and extensible ISA | - Proprietary ISA with specific extensions |
- Rd always the destination register | - Rd or Rt (for load) can be the destination register | |
- Standardized extensions (RV32M, RV32F, etc.) | - Specific extensions (MIPS-16, MIPS-3D, etc.) | |
- Simplicity in design for various types of processors | - Primarily designed for embedded systems |
A basic processor that executes one instruction per cycle. Momocycle processor MIPS in the Patterson Book that i have transform to RISC-V.
A 5-stage pipeline processor with the following stages:
- IF (Instruction Fetch): The program counter provides the address of the new instruction.
- ID (Instruction Decode): The instruction is sent to the control unit for decoding for the ALU.
- EX (Execute): The ALU performs calculations for jumps and branches, and a unit calculates the new PC.
- MEM (Memory Access): Load or store data from memory.
- WB (Write Back): Write data into the destination register.
The pipeline is based on the Patterson book (not an exact representation since RISC-V ≠ MIPS).
-
Forwarding Unit:
- This unit resolves data dependencies by forwarding results from later stages (such as MEM and WB) to earlier stages to avoid stalls.
-
Hazard Detection Units:
- Two important units: one for load-use hazards and another for managing branch instructions. These units help prevent data conflicts and ensure correct pipeline execution.
This processor uses a cache to predict whether a branch will be taken or not. (See the references for more explication). The branch predictor unit is added in the ID stage to reduce the number of stall. I made the choice to include the jump in the branch predictor but we can also imagine moving the calculation of the pc in the ID stage for the JUMP in the future.
- Direct-mapped memory: 10-bit index, 20-bit tag, and two bits for branch prediction.
PC | TAG_PC | INDEX_PC | Useless bit (address in byte) |
---|---|---|---|
PC | 31-12 | 11-2 | Useless bit (address in byte) |
History table:
VALID | INDEX | TAG | Target PC | 2 bits Prediction |
---|---|---|---|---|
VALID | 0 | TAG | Target PC | 2 bits Prediction |
VALID | 1 | TAG | Target PC | 2 bits Prediction |
VALID | 2 | TAG | Target PC | 2 bits Prediction |
... | ... | ... | ... | ... |
VALID | 511 | TAG | Target PC | 2 bits Prediction |
RISC-V is a reduced instruction set computer (RISC) architecture that offers flexibility and efficiency for modern processors. Being open-source, it encourages collaboration and innovation without the constraints of proprietary licenses.
The RISC-V instruction formats are:
- R-Type: For arithmetic and logical operations.
- I-Type: For operations with immediate values and loading data into registers.
- S-Type: For store instructions.
- B-Type: For branch instructions.
- U-Type: For large immediate values.
- J-Type: For jump instructions.
To test our processors, we use ModelSim and Rars. An example source code is available on the Rars page, and i have implemented a bubble sort in RISC-V assembly to test the processors.
You can write your own assembly code with Rars and test it on the processors.
- Write your assembly code in Rars.
- Run > Assembly: Run the assembly code to view the instruction, data memory, and register file.
- File > Dump to File > .data: Create the txt file for data memory. (You will probably have to change the writing format to make this file works)
- File > Dump to File > .text: Create the txt file for instruction memory.
You can find an example of this two file in the file with the vhdl code.
You can look in the reference the tutoriel for the modelsim installation.
- Create a new project
- Add all the VHDL file of one of the processeur and also add the txt file to implement in the instruction and data memory.
- Compile all the file ( you will need to compile more than one time )
- Run simulation > Add wave > ( you can set the time to 10 us and make the data in hexadecimal in the simulation property)
- Rerun and all the signal will be added
You will need to install the Risc-v cross complier, the final objective will be to test the processor with some signal processing application available on the code c section.
Here the instruction to compile the assembly code with the risc_v isa version rv32i. -march=rv32i
enable to chose the extention of the compilier and -mabi=ilp32
give access to rv32 because the compilier is set on rv64.
riscv64-unknown-linux-gnu-gcc -march=rv32i -mabi=ilp32 -S -o test_asm.s test_asm.c
- Gray-filter for BMP picture
After the compilation of the code c in asm, the code is not ready for rars. So i have rewrite the data and the compileur will use the sp (stack pointer) to make the operation in the safe memory zone, call memcpy is not recognize by rars, so i have write my own version of memcpy. It's a fonction that choose a source address, a target address and copy a number of bytes.
Image processing application on risc-v processor Gray-filter for BMP picture
We will use a Image processing application application on our processeur, the RV32IM
, to test it. I use the code c to generate two files .txt that give the data of the image before and after processing.
To generate this file, just do gcc on your computer. gcc -std=c99 -o recupdatarars recupdatarars.c
and ./recupdatarars >> imageorigine.txt
to get the data of the original picture.
gcc -std=c99 -o test3 test3.c
and ./test3 >> imagefinal.txt
to get the data of the final picture.
data image origine data image final
We verify data processing in the stack pointer (SP) of RARS. If the data matches, our code is functioning correctly, ensuring the correspondence between the text and hexadecimal addresses.
Txt line = to_decimal(sp_address - hex_address)/3*4
(There is 3 pixel for each line and 4 byte per data)
Here, the data 0x4a at the address 0x7FEFBBC0 correspond to the data 74 in the line 12157 of the image_final.txt with the following calcul :
Txt line = to_decimal(sp_address - hex_address)/3*4 = to_decimal(0x7FED81DC- 0x7FEFBBC0)/3*4 = to_decimal(239E4)/3*4 = 145892/3*4 = 12157
with the start address of the sp that is 0x7FED81DC in rars and in risc-v.
Here the image transformation :
I have implemented only the data and instruction memory in this processor, to execute more advance program, you can add the heap and stack counter memory.
Memory | Start Address | Description |
---|---|---|
Instruction Memory | 0x00400000 |
Contains the program instructions to be executed. |
Data Memory | 0x10010000 |
Stores the program's static and global data. |
Heap Memory | 0x10040000 |
Space for dynamic memory allocation (heap). |
Stack Pointer (SP) | 0x7fffeffc |
Stack pointer, used for local data and function calls. |
Global Pointer (gp) | Depends on the program | Pointer to global data, used for quick access to global variables. |
MMIO (Memory-Mapped I/O) | Depends on implementation | Mapping of I/O devices into memory space, allowing interaction with hardware via memory. |
M-extension enable to do a multiplication and division between two register, the div_mul_unit can be add as a second alu. A new flag need to be added to stall the pipeline during the time that the calculation is running because it's take a long time.
- Reduce the critical path by sequencing this operation is the next step. Instead of using a long combinatory path, use a clock to sequence the process.
The floating-point unit is not finished due to a lack of time. However, there is a section called FPU that i will add that is the begining of it. Also, Thirty-two registers need to be added to manipulate floating-point numbers. The CSR implementation needs to be added, or at least the floating-point control register.
Here the Single-Precision Floating-Point in RISC-V: (Look at the referencence for more specific information)
- IEEE Float:
Signe | Exponent | Mantissa |
---|---|---|
1 | 8 | 23 |
- Rounding Mode RISC-V:
Rounding Mode code | Mnemonic | Meaning |
---|---|---|
000 | RNE | Round to Nearest, ties to Even |
001 | RTZ | Round towards Zero |
010 | RDN | Round Down (towards -∞) |
011 | RUP | Round Up (towards +∞) |
100 | RMM | Round to Nearest, ties to Max Magnitude |
101 | Invalid | Reserved for future use |
110 | Invalid | Reserved for future use |
111 | Dynamic | Selects dynamic rounding mode in instruction's rm field; Invalid in Rounding Mode register |
- FLAG CONTROL RISC-V:
Flag | Meaning |
---|---|
NV | Invalid Operation |
DZ | Divide by Zero |
OF | Overflow |
UF | Underflow |
NX | Inexact |
To be completed .. (futur VHDL File will be added)
- Note that the CSR and FENCE instructiion are not implemented in this processeur even if present in the controle path.
- Possibility to add extention to the risc-v proccessor
- Use of different algorithme to test the processor (section code c in construction) (image processing)
- Addition of bootloader to implement the processor on fpga
- Changing solutions or increasing the stage number of the pipeline to increase the critical path.
- Documentation RISC-V
- RISC-V Specification v2.2
- Computer Organization and Design MIPS Edition: The Hardware/Software Interface by David A. Patterson and John L. Hennessy
- Cache Documentation 1
- Cache Documentation 2
- ModelSim Installation Tutorial
- Rars and Assembly in RISC-V
- Risc-v cross complier
- BMP-Processing
- M-extension explication
- Division Algorithm
- Float_adder
- Nan Float
- Norme Float IEEE 754
- Floating Point to Hex Converter
- FPU-example
- FPU-Out of order example
- A-extension explication
- Use of CHAT GPT for some parts of TEST BENCH and README writing
- Ensure that the assembly code generated by Rars (.data and .text files) is placed in the same directory as the VHDL file of the processor you are using for simulation.
- Note that CentOS 7 is not compatible with Rars. (I didn't make it work, maybe you can)