Skip to content

rolandbernard/kleine-riscv

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

kleine-riscv

This is a small RISC-V core written in synthesizable Verilog that supports the RV32I unprivileged ISA and parts of the privileged ISA, namely M-mode. This is only the RISC-V core and does not include any other peripherals.

Files in this Repository

  • The Verilog source of the core can be found inside the src directory. The top module is the core module inside src/core.v.
  • In the sim directory you find a small simulator that when compiled using Verilator is used for testing.
  • Inside the tests directory are the main tests testing the functionality of the core. Most of them are modified versions of the tests in riscv-tests.
    • The tests inside tests/rv32ui test the unprivileged ISA.
    • The tests inside tests/rv32mi test the privileged ISA.
  • The makefile contains the test and sim targets. If you want to run all the test, run make or make test. If you only want to build the simulator run make sim.

Architecture

This core is currently not really optimized in any way. It is designed mainly with simplicity in mind. There is currently no instruction and no data cache, which means that the speed of the core will depend significantly on the memory latency and speed. The core uses the classic five-stage RISC pipeline (FETCH, DECODE, EXECUTE, MEMORY, WRITEBACK). It also implements bypassing from the WRITEBACK and, when possible, from the MEMORY stages. All pipeline stages have their own file inside src/pipeline and are connected together inside the src/pipeline/pipeline.v module.

Memory interface

The native memory interface of the core is a simple 32 bit valid-ready interface that can run one memory transfer at a time.

output        ext_valid,
output        ext_instruction,
input         ext_ready,

output [31:0] ext_address,
output [31:0] ext_write_data,
output [ 3:0] ext_write_strobe,
input  [31:0] ext_read_data

Read

For a memory read operation (this includes instruction fetch) valid will be 1 and write_strobe will be 0. address points to the address that should be read and instruction is set to 1 if this operation is an instruction fetch. The operation's result should be returned by writing the value to read_data and asserting ready. After asserting ready for a single rising edge of the clock a new memory operation starts.

Write

For a memory write operation valid will be 1 and write_strobe will be different from 0. address points to the address that should be written to and write_data is set to the value that should be written. write_strobe indicates which bytes of the 32 bit word at address should be written to. write_strobe[0] indicates whether the least significant byte of data should be written, and write_strobe[3] indicates whether the most significant byte should be written. The operation's completion should be signalled by asserting ready. After asserting ready for a single rising edge of the clock a new memory operation starts.

Simulator

The simulator is only very simple. It allows you to set the amount of available memory, the memory latency and the maximum number of cycles to execute (this is used in the test to prevent infinite loops) and initialize the memory using ELF executable files. The simulator will also write every byte written to the address 0x10000000 to stderr (this is a placeholder for a real UART device).

About

A small and simple rv32i core written in Verilog

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages