Skip to content
Merged
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
3 changes: 2 additions & 1 deletion .gitattributes
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
#
# https://help.github.com/articles/dealing-with-line-endings/
#
# Linux start script should use lf
# Linux scripts should use lf
/gradlew text eol=lf
*.sh text eol=lf

# These are Windows script files and should use crlf
*.bat text eol=crlf
Expand Down
25 changes: 25 additions & 0 deletions sys/risc-v/mia/rv_1stage.vadl
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
// SPDX-FileCopyrightText : © 2026 TU Wien <vadl@tuwien.ac.at>
// SPDX-License-Identifier: Apache-2.0

import "../rv32i"::RV32I
import "../rv32im"::RV32IM

import "../rv64i"::RV64I
import "../rv64im"::RV64IM

model Isa() : Id = {RV32I} // invoke vadl -m "Isa=RV64I" for 64 bit arch

/**
* Single stage MiA description.
*
* Placing the whole instruction behavior in a single pipeline stage may require the stage to
* take more than one cycle for execution. In this case an implementation could share resources
* between the execution steps (which our hardware generation currently does not do).
*/
micro architecture SingleStage implements $Isa = {

stage ISS -> ( ) = {
let instr = decode( fetchNext ) in // fetch next instruction from memory and decode
instr.write
}
}
44 changes: 44 additions & 0 deletions sys/risc-v/mia/rv_3stage.vadl
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
// SPDX-FileCopyrightText : © 2026 TU Wien <vadl@tuwien.ac.at>
// SPDX-License-Identifier: Apache-2.0

import "../rv32i"::RV32I
import "../rv32im"::RV32IM

import "../rv64i"::RV64I
import "../rv64im"::RV64IM

model Isa() : Id = {RV32I} // invoke vadl -m "Isa=RV64I" for 64 bit arch

/**
* Three stage MiA description.
*
* This models a pipeline with stages Instruction Fetch, Instruction Decode and Execute following
* the design of the Wildcat educational processor.
*
* Schoeberl, M. (2025). Wildcat: Educational RISC-V Microprocessors. arXiv.
* http://arxiv.org/abs/2502.20197
*/
micro architecture ThreeStage implements $Isa = {

stage IF -> ( fr : FetchResult ) = {
fr := fetchNext // fetch next instruction from memory (or cache)
}

stage ID -> ( ir : Instruction ) = {
let instr = decode( IF.fr ) in { // decode the fetch packet, gives an Instruction
// if ( instr.unknown ) then
// raise invalidInstruction // raise an invalid instruction exception
instr.address( @X ) // compute addresses to access register file X
instr.read( @X ) // read from the X register file
instr.read( @PC ) // read from the PC
ir := instr // stage output is the Instruction ir
}
}

stage EX -> ( ir : Instruction ) = {
let instr = ID.ir in {
instr.write // write PC
ir := instr
}
}
}
20 changes: 13 additions & 7 deletions sys/risc-v/rv64imFive.vadl → sys/risc-v/mia/rv_5stage.vadl
Original file line number Diff line number Diff line change
@@ -1,21 +1,27 @@
// SPDX-FileCopyrightText : © 2024 TU Wien <vadl@tuwien.ac.at>
// SPDX-License-Identifier: Apache-2.0

// RISC-V 32 I instruction set
// RISC-V five stage pipeline

import rv64im::{RV64IM}
import "../rv32i"::RV32I
import "../rv32im"::RV32IM

micro architecture FiveStage implements RV64IM = {
import "../rv64i"::RV64I
import "../rv64im"::RV64IM

model Isa() : Id = {RV32I} // invoke vadl -m "Isa=RV64I" for 64 bit arch

micro architecture FiveStage implements $Isa = {

stage FETCH -> ( fr : FetchResult ) = {
fr := fetchNext // fetch next packet from memory (or cache)
fr := fetchNext // fetch next instruction from memory (or cache)
}

stage DECODE -> ( ir : Instruction ) = {
let instr = decode( FETCH. fr ) in { // decode the fetch packet, gives an Instruction
if ( instr.unknown ) then
raise invalidInstruction // raise an invalid instruction exception
instr.address( @X ) // output computed address (X + offset ) to memory
// if ( instr.unknown ) then
// raise invalidInstruction // raise an invalid instruction exception
instr.address( @X ) // compute addresses to access register file X
instr.read( @X ) // read from the X register file
instr.read( @PC ) // read from the PC
ir := instr // stage output is the Instruction ir
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,15 @@
// SPDX-FileCopyrightText : © 2024 TU Wien <vadl@tuwien.ac.at>
// SPDX-License-Identifier: Apache-2.0

// RISC-V 64 five stage pipeline with longer mul/div pipeline
// RISC-V five stage pipeline with longer mul/div pipeline

import rv64im::{RV64IM}
import "../rv32im"::RV32IM

micro architecture FiveStage implements RV64IM = {
import "../rv64im"::RV64IM

model Isa() : Id = {RV32IM} // invoke vadl -m "Isa=RV64IM" for 64 bit arch

micro architecture FiveStageMul implements $Isa = {

operation AddOps = {ADD, SUB, AND, OR, XOR, SLT, SLTU, SLL, SRL, SRA}
operation ImmOps = {ADDI, ANDI, ORI, XORI, SLTI, SLTIU, AUIPC, LUI}
Expand Down
14 changes: 7 additions & 7 deletions vadl-cli/main/vadl/cli/RtlCommand.java
Original file line number Diff line number Diff line change
Expand Up @@ -37,12 +37,6 @@
)
public class RtlCommand extends BaseCommand {

@CommandLine.Option(names = {"--dummy-mia"},
scope = INHERIT,
description = "Select a dummy MiA: ${COMPLETION-CANDIDATES} (stages in pipeline)",
defaultValue = "five")
RtlConfiguration.DummyMia dummyMia = RtlConfiguration.DummyMia.five;

@CommandLine.Option(names = {"--memory"},
scope = INHERIT,
description = "Configure external memory interface: ${COMPLETION-CANDIDATES}",
Expand Down Expand Up @@ -84,6 +78,12 @@ public class RtlCommand extends BaseCommand {
defaultValue = "false")
boolean keepSignals = false;

@CommandLine.Option(names = {"--rvfi"},
scope = INHERIT,
description = "Emit outputs for the RISC-V Formal Interface.",
defaultValue = "false")
boolean emitRVFI = false;

@CommandLine.Option(names = {"--dry-run"},
scope = INHERIT,
description = "Don't emit generated files.")
Expand All @@ -92,13 +92,13 @@ public class RtlCommand extends BaseCommand {
@Override
PassOrder passOrder(GeneralConfiguration configuration) throws IOException {
var rtlConfig = new RtlConfiguration(configuration);
rtlConfig.setDummyMia(dummyMia);
rtlConfig.setMemory(memory);
rtlConfig.setResetVector(resetVector);
rtlConfig.setKeepSignals(keepSignals);
rtlConfig.setScalaPackageAndDirs(scalaPackage);
rtlConfig.setTopModule(topModule);
rtlConfig.setProjectName(projectName);
rtlConfig.setEmitRVFI(emitRVFI);
rtlConfig.setDryRun(dryRun);
return PassOrders.rtl(rtlConfig);
}
Expand Down
51 changes: 29 additions & 22 deletions vadl/main/resources/templates/rtl/Makefile
Original file line number Diff line number Diff line change
@@ -1,29 +1,36 @@
# Makefile for [(${projectName})]

SHELL=/bin/bash
# Preserve test exit code when piping
SHELL=/bin/bash -o pipefail

.PHONY: test

test:
mkdir -p build
touch build/[(${topModule})]-riscv-tests.log
set -o pipefail # Preserve test exit code when piping to tee
sbt test 2>&1 | tee build/[(${topModule})]-riscv-tests.log

riscv-tests:
git clone https://github.com/riscv/riscv-tests
cd riscv-tests && \
git checkout b5ba87097c42aa41c56657e0ae049c2996e8d8d8 && \
git submodule update --init --recursive
# remove multicore disable because mhartid is not implemented
sed -ie '/#define RISCV_MULTICORE_DISABLE/{n;N;d}' riscv-tests/env/p/riscv_test.h
sed -ie '/csrr a0, mhartid;/d' riscv-tests/env/p/riscv_test.h
[# th:unless="${hasEcall}"] # patch ecall to also write test result to tohost address
sed -i '/ecall/i \
la a4, tohost; \\\
sw TESTNUM, 0(a4); \\' riscv-tests/env/p/riscv_test.h
[/] cd riscv-tests && \
autoconf && \
./configure --prefix=/usr && \
RISCV_GCC_OPTS="-static -mcmodel=medany -fvisibility=hidden -nostdlib -nostartfiles -I/usr/include" make isa
sbt "testOnly ElfSimTest"

# Elfsim with C++ memory model
SIM_BUILD=build/elfsim
SIM_WORK=$(SIM_BUILD)/workdir-verilator
SIM=$(SIM_WORK)/simulation
SIM_LOG=$(SIM_BUILD)/simulation.log
SIM_RPT=$(SIM_BUILD)/simulation.rpt

TESTS?=$(filter-out %.dump,$(wildcard /riscv-tests/isa/[(${#strings.substring(isaName, 0, 4).toLowerCase()})]ui-p-*))
TEST_OUT=$(SIM_BUILD)/tests

$(SIM):
sbt "test"

$(TEST_OUT): $(SIM)
mkdir -p $(TEST_OUT)

$(SIM_RPT): $(SIM) $(TESTS) $(TEST_OUT)
(for t in $(TESTS); do echo "test $$t"; \
echo -e "R a\nS 1 0\nR a\nS 1 1\nT 0 0,1-5*1\nS 1 0\nR 0\nW 1\nT 0 0,1-5*ffff\nD" \
| ($(SIM) "+elf=$$t" 2>&1 || true) | tee $(TEST_OUT)/`basename $$t`.log ; \
mv trace.vcd $(TEST_OUT)/`basename $$t`.vcd; done) \
| tee $(SIM_LOG)
grep -E "^(test|^RVTEST_)" $(SIM_LOG) | tee $(SIM_RPT)

# scalafmt download and format target
ifeq ($(OS),Windows_NT)
Expand Down
Loading