perilus

git clone https://git.bradleygannon.com/perilus.git
Log | Files | Refs | Submodules | README

commit 9a08be53e52cf8b49d67746c838713773b930daa
parent bdedf3e3a899eb0d3b8723e306adc199573a7581
Author: Bradley Gannon <bradley@bradleygannon.com>
Date:   Fri, 17 Jul 2026 22:28:39 -0400

Add initial configuration for building riscv-arch-test

Diffstat:
M.gitignore | 2++
Mflake.lock | 19++++++++++++++++++-
Mflake.nix | 32+++++++++++++++++++++++++++++++-
Mjustfile | 13++++++++++++-
Atests/perilus/link.ld | 15+++++++++++++++
Atests/perilus/perilus.yaml | 53+++++++++++++++++++++++++++++++++++++++++++++++++++++
Atests/perilus/rvmodel_macros.h | 44++++++++++++++++++++++++++++++++++++++++++++
Atests/perilus/sail.json | 771+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Atests/perilus/test_config.yaml | 8++++++++
9 files changed, 954 insertions(+), 3 deletions(-)

diff --git a/.gitignore b/.gitignore @@ -13,4 +13,6 @@ project/metals.sbt project/project/ project/target/ target/ +tests/perilus-rv32i +tests/stamps verilated/ diff --git a/flake.lock b/flake.lock @@ -2,7 +2,8 @@ "nodes": { "root": { "inputs": { - "stable-pkgs": "stable-pkgs" + "stable-pkgs": "stable-pkgs", + "unstable-pkgs": "unstable-pkgs" } }, "stable-pkgs": { @@ -20,6 +21,22 @@ "repo": "nixpkgs", "type": "github" } + }, + "unstable-pkgs": { + "locked": { + "lastModified": 1784007870, + "narHash": "sha256-djcLt/JJphyNt4eDY9XTly+/WbCK5lqWq9lSgCmJkkQ=", + "owner": "nixos", + "repo": "nixpkgs", + "rev": "18b9261cb3294b6d2a06d03f96872827b8fe2698", + "type": "github" + }, + "original": { + "owner": "nixos", + "ref": "nixos-unstable", + "repo": "nixpkgs", + "type": "github" + } } }, "root": "root", diff --git a/flake.nix b/flake.nix @@ -3,30 +3,60 @@ inputs = { stable-pkgs.url = "github:nixos/nixpkgs?ref=nixos-26.05"; + unstable-pkgs.url = "github:nixos/nixpkgs?ref=nixos-unstable"; }; outputs = - { self, stable-pkgs }: + { + self, + stable-pkgs, + unstable-pkgs, + }: let system = "x86_64-linux"; stable = import stable-pkgs { inherit system; }; + unstable = import unstable-pkgs { + inherit system; + }; + libInputs = with stable; [ + stdenv.cc.cc.lib + ]; + lib-path = with stable; lib.makeLibraryPath libInputs; in { devShells.${system}.default = stable.mkShellNoCC { packages = with stable; [ act + bundler + cargo coursier + gcc + git + gnumake gtkwave jdk21 just llvm metals + pkgsCross.riscv64-embedded.binutils + pkgsCross.riscv64-embedded.gcc + ruby + rust-analyzer + rustc + rustfmt sbt typst + unstable.sail-riscv + uv verilator ]; + + shellHook = '' + export BUNDLE_FROZEN=1 + export "LD_LIBRARY_PATH=$LD_LIBRARY_PATH:${lib-path}" + ''; }; }; } diff --git a/justfile b/justfile @@ -1,8 +1,17 @@ ci: fmt clean test doc -test: +test: test-chisel test-official + +test-chisel: sbt test +test-official: + cd riscv-arch-test && \ + CONFIG_FILES=../tests/perilus/test_config.yaml \ + WORKDIR=../tests \ + make --jobs $(nproc) + # TODO run the tests in the simulator + doc: typst compile -f svg doc/perilus.typ @@ -33,3 +42,5 @@ clean: sbt clean rm -rf build generated verilated cd sim && cargo clean + rm -rf tests/perilus-rv32i tests/stamps + cd riscv-arch-test && make clean diff --git a/tests/perilus/link.ld b/tests/perilus/link.ld @@ -0,0 +1,15 @@ +OUTPUT_ARCH( "riscv" ) +ENTRY(rvtest_entry_point) + +SECTIONS +{ + . = 0x0; + .text.init : { *(.text.init) } + .text.rvtest : { *(.text.rvtest) *(.text.rvtest.*) } + . = ALIGN(0x100); + .data : { *(.data) } + . = ALIGN(0x100); + .text.rvmodel : { *(.text.rvmodel) *(.text.rvmodel.*) *(.text) *(.text.*) } + . = ALIGN(0x100); + _end = .; +} diff --git a/tests/perilus/perilus.yaml b/tests/perilus/perilus.yaml @@ -0,0 +1,53 @@ +# yaml-language-server: $schema=https://raw.githubusercontent.com/riscv/riscv-unified-db/main/spec/schemas/config_schema.json +--- +$schema: config_schema.json# +kind: architecture configuration +type: fully configured +name: perilus-rv32i +description: Perilus RISC-V processor +implemented_extensions: + - { name: I, version: "= 2.1" } + - { name: M, version: "= 2.0" } + - { name: Sm, version: "= 1.12.0" } +params: + MXLEN: 32 + PRECISE_SYNCHRONOUS_EXCEPTIONS: true + TRAP_ON_ECALL_FROM_M: true + TRAP_ON_EBREAK: true + MARCHID_IMPLEMENTED: true + ARCH_ID_VALUE: 1 + MIMPID_IMPLEMENTED: true + IMP_ID_VALUE: 0x0 + VENDOR_ID_BANK: 0x0 + VENDOR_ID_OFFSET: 0x0 + MISALIGNED_LDST: false + MISALIGNED_LDST_EXCEPTION_PRIORITY: high + TRAP_ON_ILLEGAL_WLRL: false + TRAP_ON_UNIMPLEMENTED_INSTRUCTION: true + TRAP_ON_RESERVED_INSTRUCTION: true + TRAP_ON_UNIMPLEMENTED_CSR: true + REPORT_VA_IN_MTVAL_ON_BREAKPOINT: true + REPORT_VA_IN_MTVAL_ON_LOAD_MISALIGNED: true + REPORT_VA_IN_MTVAL_ON_STORE_AMO_MISALIGNED: true + REPORT_VA_IN_MTVAL_ON_INSTRUCTION_MISALIGNED: true + REPORT_VA_IN_MTVAL_ON_LOAD_ACCESS_FAULT: true + REPORT_VA_IN_MTVAL_ON_STORE_AMO_ACCESS_FAULT: true + REPORT_VA_IN_MTVAL_ON_INSTRUCTION_ACCESS_FAULT: true + REPORT_ENCODING_IN_MTVAL_ON_ILLEGAL_INSTRUCTION: true + MTVAL_WIDTH: 32 + CONFIG_PTR_ADDRESS: 0 + PMA_GRANULARITY: 3 + PHYS_ADDR_WIDTH: 32 + M_MODE_ENDIANNESS: little + MISA_CSR_IMPLEMENTED: true + MTVEC_ACCESS: rw + MTVEC_MODES: [0, 1] + MTVEC_BASE_ALIGNMENT_DIRECT: 4 + MTVEC_BASE_ALIGNMENT_VECTORED: 4 + MTVEC_ILLEGAL_WRITE_BEHAVIOR: retain + NUM_PMP_ENTRIES: 0 + MUTABLE_MISA_M: false + MCOUNTINHIBIT_IMPLEMENTED: true + MCOUNTENABLE_EN: [false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false] + HPM_COUNTER_EN: [false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false] + COUNTINHIBIT_EN: [false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false] diff --git a/tests/perilus/rvmodel_macros.h b/tests/perilus/rvmodel_macros.h @@ -0,0 +1,44 @@ +#ifndef _RVMODEL_MACROS_H +#define _RVMODEL_MACROS_H + +#define RVMODEL_DATA_SECTION \ + .pushsection .tohost,"aw",@progbits; \ + .balign 8; .global tohost; tohost: .word 0; \ + .balign 8; .global fromhost; fromhost: .word 0; \ + .popsection + +#define RVMODEL_HALT_PASS \ + li x1, 1; \ + la t0, tohost; \ + write_tohost_pass: \ + sw x1, 0(t0); \ + sw x0, 4(t0); \ + j write_tohost_pass; \ + +#define RVMODEL_HALT_FAIL \ + li x1, 3; \ + la t0, tohost; \ + write_tohost_fail: \ + sw x1, 0(t0); \ + sw x0, 4(t0); \ + j write_tohost_fail; \ + +#define RVMODEL_IO_WRITE_STR(_R1, _R2, _R3, _STR_PTR) + +#define RVMODEL_INTERRUPT_LATENCY 0 +#define RVMODEL_TIMER_INT_SOON_DELAY 0 + +#define RVMODEL_SET_MEXT_INT(_R1, _R2) +#define RVMODEL_CLR_MEXT_INT(_R1, _R2) +#define RVMODEL_SET_MSW_INT(_R1, _R2) +#define RVMODEL_CLR_MSW_INT(_R1, _R2) + +#define RVMODEL_SET_SEXT_INT(_R1, _R2) +#define RVMODEL_CLR_SEXT_INT(_R1, _R2) +#define RVMODEL_SET_SSW_INT(_R1, _R2) +#define RVMODEL_CLR_SSW_INT(_R1, _R2) + +#define CLINT_BASE_ADDRESS 0x00000000 +#define RVMODEL_MSIP_ADDRESS (CLINT_BASE_ADDRESS + 0x0) + +#endif /* _RVMODEL_MACROS_H */ diff --git a/tests/perilus/sail.json b/tests/perilus/sail.json @@ -0,0 +1,771 @@ +{ + "$schema": "/opt/riscv/share/sail-riscv/sail_riscv_config_schema.json", + "base": { + "xlen": 32, + // Whether the base ISA is E, in which case accessing + // x16-31 is reserved and in this implementation will + // raise an illegal instruction exception. + "E": false, + "writable_misa": false, + "writable_fiom": true, + // The top 29 bits in this value control whether the corresponding + // HPM counters (hpmcounter31 .. hpmcounter3) are supported + // (i.e. are not read-only zero). A set bit specifies that the + // corresponding counter is supported. The lowest 3 bits + // (writable_hpm_counters[2 .. 0]) are ignored. + "writable_hpm_counters": { + "len": 32, + "value": "0x0" + }, + // The bits in this value control whether the corresponding bits + // of the `scounteren` CSR that control access to HPM counters, + // and `cycle`, `time` and `instret` registers, are read-only + // zero. A set bit specifies that the corresponding bit of + // `scounteren` is writable, otherwise the bit is read-only zero. + // If Sscounterenw is supported the top 29 bits must be a superset of + // the top 29 bits of `writable_hpm_counters`. + "scounteren_writable_bits": { + "len": 32, + "value": "0x0" + }, + // The bits in this value control whether the corresponding bits + // of the `mcounteren` CSR that control access to HPM counters, + // and `cycle`, `time` and `instret` registers at lower privilege + // modes, are read-only zero. A set bit specifies that the + // corresponding bit of `mcounteren` is writable, otherwise the + // bit is read-only zero. + "mcounteren_writable_bits": { + "len": 32, + "value": "0x0" + }, + // `mtvec.{direct,vectored}.supported` indicates whether the + // corresponding mode is supported for `mtvec`. At least one mode + // should be supported. If both modes are supported, the mode on + // reset is unspecified. + // The `mtvec.{direct,vectored}.base_alignment` parameters control the alignment + // of the trap vector base for each mode. The alignment is + // specified as the power of 2 of the desired byte alignment, and + // can range from a minimum of 2 upto a maximum of 24. If + // unaligned values are written to these CSRs, the lowest bits + // will be zeroed to respect the specified alignment. + "mtvec": { + "direct": { + "supported": true, + "base_alignment": 2 + }, + "vectored": { + "supported": true, + "base_alignment": 2 + } + }, + // Similar to `mtvec` above. If `S` mode is not supported, these + // values need to be present and legal but are ignored. + "stvec": { + // The spec requires `base_alignment` for `stvec.direct` to be 2 + // (i.e. 4-byte alignment), hence there is no configuration + // parameter for it. + "direct": { + "supported": false + }, + "vectored": { + "supported": false, + "base_alignment": 2 + } + }, + // These settings control whether the specified exceptions + // cause information to be written into the appropriate + // `xtval` registers. + "xtval_nonzero": { + "illegal_instruction": true, + "software_breakpoint": true, + "hardware_breakpoint": true, + "load_address_misaligned": true, + "load_access_fault": true, + "load_page_fault": true, + "samo_address_misaligned": true, + "samo_access_fault": true, + "samo_page_fault": true, + "fetch_address_misaligned": true, + "fetch_access_fault": true, + "fetch_page_fault": true, + "software_check": true, + "reserved_exceptions": false + }, + "reserved_behavior": { + // The configuration option determines how to handle the reserved behavior `amocas_odd_registers`. + // "AMOCAS_Fatal" – raise a Sail exception, stopping execution. + // "AMOCAS_Illegal" – treat it as an illegal instruction. + "amocas_odd_register": "AMOCAS_Fatal", + // The configuration option determines how to handle execution of a floating-point + // instruction with DYN (dynamic) rounding mode when `fcsr.FRM` contains a + // reserved value (0b101, 0b110, 0b111). + // This does not affect the execution of floating-point instructions that have a + // reserved rounding mode statically encoded in the instruction. + // "Fcsr_RM_Fatal" – raise a Sail exception, stopping execution. + // "Fcsr_RM_Illegal" – treat it as an illegal instruction. + "fcsr_rm": "Fcsr_RM_Fatal", + // The configuration option determines how to handle the reserved behavior `pmpcfg_with_R0W1`. + // "PMP_Fatal" – raise a Sail exception, stopping execution. + // "PMP_ClearPermissions" – convert a PMP entry with R=0, W=1 to R=0, W=0, X=0. + "pmpcfg_write_only": "PMP_ClearPermissions", + // The configuration option determines how to handle the reserved behavior `xenvcfg.CBIE` with 0b10. + // "Xenvcfg_Fatal" – raise a Sail exception, stopping execution. + // "Xenvcfg_ClearPermissions" – convert CBIE with 0b10 to 0b00. + "xenvcfg_cbie": "Xenvcfg_ClearPermissions", + // The configuration option determines how to handle the reserved behavior `xtvec[Mode] >= 2`. + // "Xtvec_Fatal" – raise a Sail exception, stopping execution. + // "Xtvec_Ignore" – use old Mode of xtvec. + "xtvec_mode": "Xtvec_Ignore", + // The configuration option determines how to handle the reserved behavior: Odd-numbered registers for RV32Zdinx. + // "Zdinx_Fatal" – raise a Sail exception, stopping execution. + // "Zdinx_Illegal" – treat it as an illegal instruction. + "rv32zdinx_odd_register": "Zdinx_Fatal" + }, + "mstatus": { + // The legal values for the FS and VS fields in this CSR are + // specified by the two fields below. Their values can be one + // of: + // - "ExtContext_FourState" allows all values {Off, Initial, Clean, Dirty}. + // - "ExtContext_TwoState" allows {Off, Dirty}, and writes of Initial and Clean get written as Dirty. + // - "ExtContext_Off" allows only {Off}. This makes the field read-only zero. + "fs_legal_states": "ExtContext_FourState", + "vs_legal_states": "ExtContext_Off" + } + }, + "memory": { + "pmp": { + "grain": 0, + // This specifies the number of PMP entries present. + // The value must be one of 0, 16, or 64. + "count": 0, + // This specifies the number of usable PMP entries. + // Entries higher than this are read-only-zero. + // The value must be less than or equal to `count`. + "usable_count": 0, + "tor_supported": true, + "na4_supported": true, + "napot_supported": true + }, + // These settings control global support for misaligned access so they are + // checked before address translation. `misaligned_fault` in + // `regions` is checked after address translation. + "misaligned": { + // `exceptions` specifies the treatment of misaligned accesses + // before address translation. If a fault is specified for an access, + // it will have a higher priority than memory-protection faults arising from + // that access if it were allowed to proceed. + "exceptions": { + // A misaligned scalar or vector load/store can either proceed + // without a fault (use `{"None" : null}`), or raise an access fault + // (use `{"Some": "AccessFault"}`) or a misaligned exception + // (use `{"Some": "AlignmentException"}`). + // This option controls scalar loads/stores. + "load_store": { + "Some": "AlignmentException" + }, + // A misaligned vector load/store can be configured + // independently of the scalar case above, but uses the same + // option values. + "vector": { + "Some": "AlignmentException" + }, + // A misaligned LR/SC currently always faults, and this field can specify + // whether it generates an access fault (use `"AccessFault"`) + // or a misaligned exception (use `"AlignmentException"`). + "lrsc": "AccessFault", + // Similarly, a misaligned AMO currently always faults, and this field + // can specify either `"AccessFault"` or `"AlignmentException"`. + "amo": "AccessFault" + }, + // If a misaligned access was specified to have no fault in `exceptions` above, the + // fields below specify how it is handled. + // + // Memory accesses that span multiple naturally aligned + // 2^allowed_within_exp sized regions will be split into multiple + // memory operations. 0 means all misaligned accesses will be split. + // The maximum value is 12 (one page). + "allowed_within_exp": 0, + // If the access gets split due to `allowed_within_exp` then the size + // of the operations will be one byte if `byte_by_byte` is set, otherwise + // they will be the maximum size possible based on the alignment. For + // example a 4-byte access to address 0x2 will use two 2-byte operations. + "byte_by_byte": false, + // If multiple memory operations are needed, this controls whether they + // are done in increasing or decreasing address order. This is architecturally + // observable because some store operations may succeed, and even for + // loads the resulting `xtval` may depend on this setting. + "order_decreasing": false + }, + // Address to write DTB to (if provided). This must be in a suitable memory + // region (see `memory.regions`). + "dtb_address": { + "len": 64, + "value": "0x1000" + }, + // The locations and sizes of memory regions and their PMAs. These regions + // are required to be aligned to 4K (page) boundaries. To specify + // the `misaligned` PMA attribute for a region, see the comments for + // `memory.misaligned.exceptions` above. + "regions": [ + // RAM (test code + data + signature region, includes ROM area) + { + "base": { + "len": 64, + "value": "0x0" + }, + "size": { + "len": 64, + "value": "0x50000" + }, + "attributes": { + "mem_type": "MainMemory", + "cacheable": true, + "coherent": true, + "executable": true, + "readable": true, + "writable": true, + "read_idempotent": true, + "write_idempotent": true, + "misaligned_exceptions": { + "load_store": { + "None": null + }, + "vector": { + "None": null + }, + "amo": "AccessFault" + }, + "atomic_support": "AMOArithmetic", + "reservability": "RsrvEventual", + "supports_cbo_zero": true, + "supports_pte_read": true, + "supports_pte_write": true + }, + "include_in_device_tree": false + }, + // MMIO + { + "base": { + "len": 64, + "value": "0x2000000" + }, + "size": { + "len": 64, + "value": "0x10000000" + }, + "attributes": { + "mem_type": "IOMemory", + "cacheable": false, + "coherent": true, + "executable": false, + "readable": true, + "writable": true, + "read_idempotent": false, + "write_idempotent": false, + "misaligned_exceptions": { + "load_store": { + "None": null + }, + "vector": { + "None": null + }, + "amo": "AccessFault" + }, + "atomic_support": "AMONone", + "reservability": "RsrvNone", + "supports_cbo_zero": false, + "supports_pte_read": false, + "supports_pte_write": false + }, + "include_in_device_tree": false + }, + // RAM + { + "base": { + "len": 64, + "value": "0x80000000" + }, + "size": { + "len": 64, + "value": "0x80000000" + }, + "attributes": { + "mem_type": "MainMemory", + "cacheable": true, + "coherent": true, + "executable": true, + "readable": true, + "writable": true, + "read_idempotent": true, + "write_idempotent": true, + "misaligned_exceptions": { + "load_store": { + "None": null + }, + "vector": { + "None": null + }, + "amo": "AccessFault" + }, + "atomic_support": "AMOCASQ", + "reservability": "RsrvEventual", + "supports_cbo_zero": true, + "supports_pte_read": true, + "supports_pte_write": true + }, + "include_in_device_tree": true + } + ] + }, + "platform": { + "vendorid": 0, + "archid": 0, + "impid": 0, + "hartid": 0, + // Cache block size, specified as a power of 2. + "cache_block_size_exp": 6, + "reservation": { + // This specifies both the size and alignment of the reservation set, specified as a power of 2. + // It must be at least 2 on RV32 and 3 on RV64 to support Zalrsc. It must not be more than + // 6 for Za64rs and 7 for Za128rs. In all cases, it must be less than or equal to 12. + "reservation_set_size_exp": 2, + // Some implementations (e.g. Spike) require the Store-Conditional to provide the same + // address as the matching Load-Reserve in order to succeed, regardless of the + // configured reservation set size. This controls whether such an exact address + // match is required for a Store-Conditional to succeed. + "require_exact_reservation_addr": true, + // Some implementations (e.g. SiFive U74) also invalidate the + // reservation on stores from the same hart. If this is set to `true`, the + // model invalidates the reservation if a store from the same hart lies within + // the reservation set. + "invalidate_on_same_hart_store": false + }, + "clint": { + // Whether the platform contains a CLINT. + "supported": true, + // If supported, this must be in a suitable IO memory region (see `memory.regions`). + // Otherwise, these values can be left as 0. + "base": 33554432, + "size": 786432 + }, + // Very simple MMIO device to generate interrupts for testing + // purposes. See docs/SimpleInterruptGenerator.md for details. + "simple_interrupt_generator": { + // Whether the platform contains this device. + "supported": true, + // If supported, this must be in a suitable IO memory region (see `memory.regions`) + // and 4-byte aligned. The size is always 0x20. If not supported, this can be left + // as 0. + "base": 201326592 + }, + "clock_frequency": 1000000000, + "instructions_per_tick": 2, + "wfi_is_nop": false, + // WFI is optionally available to User mode. Note that even if + // `wfi_is_nop` is set to `true` above, it will still not be + // available to User mode unless `wfi_available_to_user_mode` is + // also `true`. + "wfi_available_to_user_mode": false, + // The maximum increment in the time CSR before a wait instruction + // (e.g. WFI, WRS.NTO, WRS.STO) that is not a NOP expires its + // wait. It is not possible to wait indefinitely. + // + // If WFI or WRS.STO (Short TimeOut) exceed this limit in + // non-machine privilege with mstatus[TW] set, an illegal + // instruction is raised. Otherwise they retire successfully. + // + // Note: it is also legal for these instructions to spuriously + // retire successfully at any point, but there is currently no + // configuration option for this behaviour. + "max_time_to_wait": 200 + }, + "extensions": { + "M": { + "supported": true + }, + "A": { + "supported": true + }, + "F": { + "supported": true + }, + "D": { + "supported": true + }, + "V": { + // `support_level` must be one of the below strings: + // . "Disabled" for no vector extension support + // . "Integer" for Zve*x support + // . "Float_single" for Zve*f support + // . "Float_double" for Zve*d support + // . "Full" for the full V extension + // Note that `support_level` requires compatible + // values for `vlen_exp` and `elen_exp` below. + // For e.g. Zve32x and Zve32f require `elen_exp` >= 5, + // Zve64x, Zve64f, and Zve64d require `elen_exp` >= 6, + // and V requires `elen_exp` >= 6 and `vlen_exp` >= 7. + "support_level": "Disabled", + // `vlen_exp` and `elen_exp` should be between 3 and 16, + // inclusive. If `support_level` is `"Disabled"`, then these + // should be left as 3 (or any other legal value). + "vlen_exp": 8, + "elen_exp": 6, + "reserved_behavior": { + // This determines how to handle attempts by vsetvli, vsetivli, + // and vsetvl to set an unsupported or reserved vtype. + // "IllegalVtype_SetVill" - set vtype.vill, set vl to zero, clear vstart, and write rd. + // "IllegalVtype_Illegal" - treat it as an illegal instruction. + // "IllegalVtype_Fatal" - raise a Sail exception, stopping execution. + "illegal_vtype": "IllegalVtype_SetVill", + // This determines how to handle an out-of-bounds vstart (vstart >= VLMAX), which the + // vector spec marks reserved and recommends, but does not require, trapping. + // "Vstart_Illegal" - raise an illegal instruction exception. + // "Vstart_Ignore" - treat as a no-op, the instruction writes nothing. + "vstart_out_of_bounds": "Vstart_Illegal" + }, + "vl_use_ceil": false, + // The maximum index EEW for indexed vector addressing mode, as + // a power of 2. This must be at least 3 but must not exceed + // the supported ELEN. + "max_index_eew_exp": 6, + "vstart": { + // The vector specification permits implementations to raise an + // illegal instruction exception when `vstart` is non-zero for + // instructions that cannot produce such a `vstart` value through + // normal execution. + "zero_required": { + // Whether vector arithmetic instructions raise an illegal instruction + // exception when `vstart` is non-zero. This also governs instructions + // from the Zvbb, Zvbc, Zvabd, Zvfbfmin, and Zvfbfwma extensions. + "arith": true, + // Whether the vector scalar move instructions (vmv.x.s, vmv.s.x, + // vfmv.f.s and vfmv.s.f) raise an illegal instruction exception when + // `vstart` is non-zero. + "scalar_move": true + } + } + }, + "B": { + "supported": false + }, + "S": { + "supported": false + }, + "U": { + "supported": false + }, + "Zibi": { + "supported": false + }, + // This extension just asserts that the cache block size is 64 bytes. + // If you enable this you also need to ensure `platform.cache_block_size_exp` + // is 6, otherwise you will get a config validation error. + "Zic64b": { + "supported": false + }, + "Zicbom": { + "supported": false + }, + "Zicbop": { + "supported": false + }, + "Zicboz": { + "supported": false + }, + "Ziccamoa": { + "supported": false + }, + "Ziccamoc": { + "supported": false + }, + "Ziccif": { + "supported": false + }, + "Zicclsm": { + "supported": false + }, + "Ziccrse": { + "supported": false + }, + "Zicfilp": { + "supported": false + }, + "Zicfiss": { + "supported": false + }, + "Zicond": { + "supported": false + }, + "Zicntr": { + "supported": true + }, + "Zicsr": { + "supported": true + }, + "Zifencei": { + "supported": true + }, + "Zihintntl": { + "supported": false + }, + "Zihintpause": { + "supported": false + }, + "Zihpm": { + "supported": true + }, + "Zimop": { + "supported": false + }, + "Zmmul": { + "supported": true + }, + "Zaamo": { + "supported": true + }, + "Zabha": { + "supported": false + }, + "Zacas": { + "supported": false + }, + "Zalrsc": { + "supported": true + }, + "Zawrs": { + "supported": false, + // Whether `WRS.NTO` and `WRS.STO` behave as NOPS. If they do + // not, see above note for `platform.max_time_to_wait`. If + // Zawrs is not supported, these `is_nop` fields need to be + // present but their boolean values are ignored. + "nto": { + "is_nop": false + }, + "sto": { + "is_nop": false + } + }, + "Zfa": { + "supported": false + }, + "Zfbfmin": { + "supported": false + }, + "Zfh": { + "supported": false + }, + "Zfhmin": { + "supported": false + }, + "Zfinx": { + "supported": false + }, + "Zdinx": { + "supported": false + }, + "Zca": { + "supported": true + }, + "Zcf": { + "supported": true + }, + "Zcd": { + "supported": true + }, + "Zcb": { + "supported": false + }, + "Zcmop": { + "supported": false + }, + "Zba": { + "supported": false + }, + "Zbb": { + "supported": false + }, + "Zbs": { + "supported": false + }, + "Zbc": { + "supported": false + }, + "Zbkb": { + "supported": false + }, + "Zbkc": { + "supported": false + }, + "Zbkx": { + "supported": false + }, + "Zknd": { + "supported": false + }, + "Zkne": { + "supported": false + }, + "Zknh": { + "supported": false + }, + "Zkr": { + "supported": false, + // If Zkr is not supported, these fields need to be present but + // their boolean values are ignored. + "sseed_reset_value": false, + "useed_reset_value": false, + "sseed_read_only_zero": false, + "useed_read_only_zero": false + }, + "Zksed": { + "supported": false + }, + "Zksh": { + "supported": false + }, + "Zkt": { + "supported": false + }, + "Zhinx": { + "supported": false + }, + "Zhinxmin": { + "supported": false + }, + "Zvabd": { + "supported": false + }, + "Zvfbfmin": { + "supported": false + }, + "Zvfbfwma": { + "supported": false + }, + "Zvfh": { + "supported": false + }, + "Zvfhmin": { + "supported": false + }, + "Zvbb": { + "supported": false + }, + "Zvbc": { + "supported": false + }, + "Zvkb": { + "supported": false + }, + "Zvkg": { + "supported": false + }, + "Zvkned": { + "supported": false + }, + "Zvknha": { + "supported": false + }, + "Zvknhb": { + "supported": false + }, + "Zvksed": { + "supported": false + }, + "Zvksh": { + "supported": false + }, + "Zvkt": { + "supported": false + }, + "Ssccptr": { + "supported": false + }, + "Sscofpmf": { + "supported": false + }, + "Sscounterenw": { + "supported": false + }, + "Sstc": { + "supported": false + }, + // Enabling Sstvala requires that the exceptions specified in the extension + // have their appropriate settings under `base.xtval_nonzero`. + "Sstvala": { + "supported": false + }, + "Svade": { + "supported": false + }, + "Svadu": { + "supported": false + }, + "Svinval": { + "supported": false + }, + "Svrsw60t59b": { + "supported": false + }, + "Svnapot": { + "supported": false + }, + "Ssnpm": { + "supported": false, + "supported_pmlen_7": true, + "supported_pmlen_16": true + }, + "Smnpm": { + "supported": false, + "supported_pmlen_7": true, + "supported_pmlen_16": true + }, + "Smmpm": { + "supported": false, + "supported_pmlen_7": true, + "supported_pmlen_16": true + }, + "Smcntrpmf": { + "supported": false + }, + "Svbare": { + "supported": false, + "sfence_vma_illegal_if_svbare_only": true + }, + "Sv32": { + "supported": false + }, + "Sv39": { + "supported": false + }, + "Sv48": { + "supported": false + }, + "Sv57": { + "supported": false + }, + "Stateen": { + "Smstateen": { + "supported": false + }, + "Ssstateen": { + "supported": false + }, + "C_readonly_zero": true, + "SE0_readonly_zero": false + }, + "Ssqosid": { + "supported": false, + // These lengths should be between 1 and 12, inclusive. + // If Ssqosid is not supported, this should be left as 1 + // (or any other legal value). + "rcid_length": 12, + "mcid_length": 12 + }, + "Svpbmt": { + "supported": false + }, + "Svvptc": { + "supported": false + } + } +} diff --git a/tests/perilus/test_config.yaml b/tests/perilus/test_config.yaml @@ -0,0 +1,8 @@ +name: perilus-rv32i +compiler_exe: riscv64-none-elf-gcc +objdump_exe: riscv64-none-elf-objdump +ref_model_exe: sail_riscv_sim +udb_config: perilus.yaml +linker_script: link.ld +dut_include_dir: . +include_priv_tests: false