Skip to content

Commit

Permalink
Big cleanup work (#47)
Browse files Browse the repository at this point in the history
This moves a lot of internal data structures from `types` into `core`, because some imports got confused apparently.

It also adds csr registers, performance improvements, etc.
  • Loading branch information
AntonLydike authored Oct 2, 2023
1 parent 72aaf9d commit ddb0a0f
Show file tree
Hide file tree
Showing 62 changed files with 1,031 additions and 349 deletions.
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 <[email protected]>"
__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

0 comments on commit ddb0a0f

Please sign in to comment.