Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Big cleanup work #47

Merged
merged 10 commits into from
Oct 2, 2023
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: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,14 @@

# Upcoming

- Feature: Added Zicsr extension and with that support for CSRs
- Feature: Starting to add support for Snitch architecture (Xssr)
- Feature: Add support for `.p2align` assembler directive
- Rework: Improve handling of immediates, so that `beq a0, a1, 1b` and `beq a0, a1, -16` can both can be handled correctly.
- BugFix: Fix some more errors in the RV32F implementation
- Dev: Move to poetry for project development environment
- Dev: Module refactoring, core datastructures now mostly live inside riscemu.core
- Perf: Improved performance by around 1.8x

## 2.1.1

Expand Down
180 changes: 180 additions & 0 deletions examples/estimate-cpu-freq.asm
Original file line number Diff line number Diff line change
@@ -0,0 +1,180 @@
.data
// 16 words of data for benchmarking loads/stores
buf0:
.word 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16

.text
.globl main

main:
mv s5, ra

// warmup
printf "warmup"
li a0, 1000
jal nop_loop

la a1, nop_loop
li a0, 1000
printf "Measuring nops:"
jal measure_loop
li a0, 10000
jal measure_loop

la a1, arith_loop
li a0, 1000
printf "Measuring addi:"
jal measure_loop
li a0, 10000
jal measure_loop

la a1, memory_loop
la a2, buf0
li a0, 1000
printf "Measuring load/stores:"
jal measure_loop
li a0, 10000
jal measure_loop

mv ra, s5
ret


// rtclock tickrate is 32768
// execute bench at addr a1, a0 times
measure_loop:
mv s4, ra
csrrs s0, zero, cycle
csrrs s2, zero, time
jalr ra, a1, 0
csrrs s1, zero, cycle
csrrs s3, zero, time
sub s0, s1, s0
sub s1, s3, s2
fcvt.s.w ft0, s1
li t1, 32768 // cpu tickrate
fcvt.s.w ft1, t1
fdiv.s ft0, ft0, ft1 // ft0 = seconds of execution time
fcvt.s.w ft1, s0 // ft1 = number of ins executed
fdiv.s ft2, ft1, ft0 // ft2 = ins/second
li t0, 1000
fcvt.s.w ft1, t0 // ft1 = 1k
fdiv.s ft2, ft2, ft1 // ft2 = kins/sec

printf "executed {} instructions in {:.4f} seconds ({:.2f}ki/s)", s0, ft0, ft2
mv ra, s4
ret

// first loop, executes a0*32 nop + a0 addi + a0 beq instructions (a0 > 1)
nop_loop:
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
addi a0, a0, -1
blt zero, a0, nop_loop
ret

// second loop, executes a0*16 load/store pairs + a0 addi + a0 beq instructions (a0 > 1)
memory_loop:
lw t0, 0(a2)
sw t0, 0(a2)
lw t0, 4(a2)
sw t0, 4(a2)
lw t0, 8(a2)
sw t0, 8(a2)
lw t0, 12(a2)
sw t0, 12(a2)
lw t0, 16(a2)
sw t0, 16(a2)
lw t0, 20(a2)
sw t0, 20(a2)
lw t0, 24(a2)
sw t0, 24(a2)
lw t0, 28(a2)
sw t0, 28(a2)
lw t0, 32(a2)
sw t0, 32(a2)
lw t0, 36(a2)
sw t0, 36(a2)
lw t0, 40(a2)
sw t0, 40(a2)
lw t0, 44(a2)
sw t0, 44(a2)
lw t0, 48(a2)
sw t0, 48(a2)
lw t0, 52(a2)
sw t0, 52(a2)
lw t0, 56(a2)
sw t0, 56(a2)
lw t0, 60(a2)
sw t0, 60(a2)
addi a0, a0, -1
bge a0, zero, nop_loop
ret

// third loop, executes a0*32 addi + a0 addi + a0 beq instructions (a0 > 1)
arith_loop:
addi t0, a0, 1234
addi t0, a0, 1234
addi t0, a0, 1234
addi t0, a0, 1234
addi t0, a0, 1234
addi t0, a0, 1234
addi t0, a0, 1234
addi t0, a0, 1234
addi t0, a0, 1234
addi t0, a0, 1234
addi t0, a0, 1234
addi t0, a0, 1234
addi t0, a0, 1234
addi t0, a0, 1234
addi t0, a0, 1234
addi t0, a0, 1234
addi t0, a0, 1234
addi t0, a0, 1234
addi t0, a0, 1234
addi t0, a0, 1234
addi t0, a0, 1234
addi t0, a0, 1234
addi t0, a0, 1234
addi t0, a0, 1234
addi t0, a0, 1234
addi t0, a0, 1234
addi t0, a0, 1234
addi t0, a0, 1234
addi t0, a0, 1234
addi t0, a0, 1234
addi t0, a0, 1234
addi t0, a0, 1234
addi a0, a0, -1
blt zero, a0, nop_loop
ret
2 changes: 1 addition & 1 deletion riscemu/IO/IOModule.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
from abc import ABC
from typing import Optional

from riscemu.types import MemorySection, MemoryFlags, T_RelativeAddress
from riscemu.core import MemorySection, MemoryFlags, T_RelativeAddress


class IOModule(MemorySection, ABC):
Expand Down
4 changes: 2 additions & 2 deletions riscemu/IO/TextIO.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
from .IOModule import IOModule
from ..priv.Exceptions import InstructionAccessFault
from ..types import T_RelativeAddress, Instruction, MemoryFlags, Int32
from core.traps import InstructionAccessFault
from ..core import T_RelativeAddress, Instruction, MemoryFlags, Int32


class TextIO(IOModule):
Expand Down
26 changes: 1 addition & 25 deletions riscemu/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,33 +8,9 @@
It contains everything needed to run assembly files, so you don't need any custom compilers or toolchains
"""

from .types.exceptions import (
RiscemuBaseException,
LaunchDebuggerException,
InvalidSyscallException,
LinkerException,
ParseException,
NumberFormatException,
InvalidRegisterException,
MemoryAccessException,
OutOfMemoryException,
)

from .instructions import *

from .MMU import MMU
from .registers import Registers
from .syscall import SyscallInterface, Syscall
from .CPU import CPU, UserModeCPU
from .debug import launch_debug_session

from .config import RunConfig

from .parser import tokenize, parse_tokens, AssemblyFileLoader

# to read package version:
import importlib.metadata

__author__ = "Anton Lydike <Anton@Lydike.com>"
__copyright__ = "Copyright 2023 Anton Lydike"
__version__ = importlib.metadata.version(__name__)
__version__ = importlib.metadata.version("riscemu")
4 changes: 2 additions & 2 deletions riscemu/__main__.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@
"""
import sys

from riscemu import RiscemuBaseException
from riscemu.riscemu_main import RiscemuMain
from .core import RiscemuBaseException
from .riscemu_main import RiscemuMain


def main():
Expand Down
4 changes: 2 additions & 2 deletions riscemu/assembler.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,10 @@
from typing import Optional, Tuple, Union

from .colors import FMT_PARSE, FMT_NONE
from riscemu.types.exceptions import ParseException, ASSERT_LEN
from riscemu.core.exceptions import ParseException, ASSERT_LEN
from .helpers import parse_numeric_argument, align_addr, get_section_base_name
from .tokenizer import Token
from .types import (
from .core import (
Program,
T_RelativeAddress,
InstructionContext,
Expand Down
3 changes: 3 additions & 0 deletions riscemu/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,3 +24,6 @@ class RunConfig:
# runtime config
use_libc: bool = False
ignore_exit_code: bool = False
# csr stuff:
# frequency of the real-time clock
rtclock_tickrate: int = 32768
34 changes: 20 additions & 14 deletions riscemu/types/__init__.py → riscemu/core/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,20 +10,6 @@

NUMBER_SYMBOL_PATTERN = re.compile(r"^\d+[fb]$")

# base classes
from .flags import MemoryFlags
from .int32 import UInt32, Int32
from .float32 import Float32
from .instruction import Instruction, Immediate
from .instruction_context import InstructionContext
from .memory_section import MemorySection
from .program import Program
from .program_loader import ProgramLoader
from .cpu import CPU
from .simple_instruction import SimpleInstruction
from .instruction_memory_section import InstructionMemorySection
from .binary_data_memory_section import BinaryDataMemorySection

# exceptions
from .exceptions import (
ParseException,
Expand All @@ -39,3 +25,23 @@
UnimplementedInstruction,
INS_NOT_IMPLEMENTED,
)

# base classes
from .flags import MemoryFlags
from .int32 import UInt32, Int32
from .float32 import Float32
from .rtclock import RTClock
from .instruction import Instruction, Immediate, InstructionWithEncoding
from .instruction_context import InstructionContext
from .memory_section import MemorySection
from .program import Program
from .program_loader import ProgramLoader
from .privmodes import PrivModes
from .mmu import MMU
from .csr import CSR
from .registers import Registers
from .cpu import CPU
from .simple_instruction import SimpleInstruction
from .instruction_memory_section import InstructionMemorySection
from .binary_data_memory_section import BinaryDataMemorySection
from .usermode_cpu import UserModeCPU
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
T_RelativeAddress,
Instruction,
)
from ..types.exceptions import MemoryAccessException
from ..core.exceptions import MemoryAccessException


class BinaryDataMemorySection(MemorySection):
Expand Down
Loading