mirror of
https://github.com/openhwgroup/cvw
synced 2025-02-11 06:05:49 +00:00
Merge branch 'main' of github.com:openhwgroup/cvw
This commit is contained in:
commit
0ce4d1b452
@ -517,6 +517,8 @@ def main():
|
|||||||
TIMEOUT_DUR = 60*1440 # 1 day
|
TIMEOUT_DUR = 60*1440 # 1 day
|
||||||
elif args.testfloat:
|
elif args.testfloat:
|
||||||
TIMEOUT_DUR = 30*60 # seconds
|
TIMEOUT_DUR = 30*60 # seconds
|
||||||
|
elif args.nightly:
|
||||||
|
TIMEOUT_DUR = 30*60 # seconds
|
||||||
else:
|
else:
|
||||||
TIMEOUT_DUR = 10*60 # seconds
|
TIMEOUT_DUR = 10*60 # seconds
|
||||||
|
|
||||||
|
13
bin/wsim
13
bin/wsim
@ -28,6 +28,7 @@ parser.add_argument("--tb", "-t", help="Testbench", choices=["testbench", "testb
|
|||||||
parser.add_argument("--gui", "-g", help="Simulate with GUI", action="store_true")
|
parser.add_argument("--gui", "-g", help="Simulate with GUI", action="store_true")
|
||||||
parser.add_argument("--ccov", "-c", help="Code Coverage", action="store_true")
|
parser.add_argument("--ccov", "-c", help="Code Coverage", action="store_true")
|
||||||
parser.add_argument("--fcov", "-f", help="Functional Coverage, implies lockstep", action="store_true")
|
parser.add_argument("--fcov", "-f", help="Functional Coverage, implies lockstep", action="store_true")
|
||||||
|
parser.add_argument("--fcov2", "-f2", help="Functional Coverage, implies lockstep", action="store_true")
|
||||||
parser.add_argument("--fcovrvvi", "-fr", help="Functional Coverage RVVI", action="store_true")
|
parser.add_argument("--fcovrvvi", "-fr", help="Functional Coverage RVVI", action="store_true")
|
||||||
parser.add_argument("--args", "-a", help="Optional arguments passed to simulator via $value$plusargs", default="")
|
parser.add_argument("--args", "-a", help="Optional arguments passed to simulator via $value$plusargs", default="")
|
||||||
parser.add_argument("--vcd", "-v", help="Generate testbench.vcd", action="store_true")
|
parser.add_argument("--vcd", "-v", help="Generate testbench.vcd", action="store_true")
|
||||||
@ -66,7 +67,7 @@ if(args.testsuite.endswith('.elf') and args.elf == ""): # No --elf argument; che
|
|||||||
|
|
||||||
|
|
||||||
# Validate arguments
|
# Validate arguments
|
||||||
if (args.gui or args.ccov or args.fcov or args.fcovrvvi or args.lockstep):
|
if (args.gui or args.ccov or args.fcov or args.fcov2 or args.fcovrvvi or args.lockstep):
|
||||||
if args.sim not in ["questa", "vcs"]:
|
if args.sim not in ["questa", "vcs"]:
|
||||||
print("Option only supported for Questa and VCS")
|
print("Option only supported for Questa and VCS")
|
||||||
exit(1)
|
exit(1)
|
||||||
@ -81,7 +82,7 @@ if (args.rvvi):
|
|||||||
if(int(args.locksteplog) >= 1): EnableLog = 1
|
if(int(args.locksteplog) >= 1): EnableLog = 1
|
||||||
else: EnableLog = 0
|
else: EnableLog = 0
|
||||||
if (args.lockstep):
|
if (args.lockstep):
|
||||||
prefix = "IMPERAS_TOOLS=" + WALLY + "/sim/imperas.ic"
|
prefix = "IMPERAS_TOOLS=" + WALLY + "/config/"+args.config+"/imperas.ic"
|
||||||
if(args.locksteplog != 0): ImperasPlusArgs = " +IDV_TRACE2LOG=" + str(EnableLog) + " +IDV_TRACE2LOG_AFTER=" + str(args.locksteplog)
|
if(args.locksteplog != 0): ImperasPlusArgs = " +IDV_TRACE2LOG=" + str(EnableLog) + " +IDV_TRACE2LOG_AFTER=" + str(args.locksteplog)
|
||||||
else: ImperasPlusArgs = ""
|
else: ImperasPlusArgs = ""
|
||||||
if(args.fcov):
|
if(args.fcov):
|
||||||
@ -90,6 +91,12 @@ if (args.lockstep):
|
|||||||
else: EnableLog = 0
|
else: EnableLog = 0
|
||||||
ImperasPlusArgs = " +IDV_TRACE2COV=" + str(EnableLog) + " +TRACE2LOG_AFTER=" + str(args.covlog) + " +TRACE2COV_ENABLE=" + CovEnableStr;
|
ImperasPlusArgs = " +IDV_TRACE2COV=" + str(EnableLog) + " +TRACE2LOG_AFTER=" + str(args.covlog) + " +TRACE2COV_ENABLE=" + CovEnableStr;
|
||||||
suffix = ""
|
suffix = ""
|
||||||
|
if(args.fcov2):
|
||||||
|
CovEnableStr = "1" if int(args.covlog) > 0 else "0";
|
||||||
|
if(args.covlog >= 1): EnableLog = 1
|
||||||
|
else: EnableLog = 0
|
||||||
|
ImperasPlusArgs = " +IDV_TRACE2COV=" + str(EnableLog) + " +TRACE2LOG_AFTER=" + str(args.covlog) + " +TRACE2COV_ENABLE=" + CovEnableStr;
|
||||||
|
suffix = ""
|
||||||
else:
|
else:
|
||||||
CovEnableStr = ""
|
CovEnableStr = ""
|
||||||
suffix = "--lockstep"
|
suffix = "--lockstep"
|
||||||
@ -104,6 +111,8 @@ if (args.ccov):
|
|||||||
flags += " --ccov"
|
flags += " --ccov"
|
||||||
if (args.fcov):
|
if (args.fcov):
|
||||||
flags += " --fcov"
|
flags += " --fcov"
|
||||||
|
if (args.fcov2):
|
||||||
|
flags += " --fcov2"
|
||||||
if (args.fcovrvvi):
|
if (args.fcovrvvi):
|
||||||
flags += "--fcovrvvi"
|
flags += "--fcovrvvi"
|
||||||
|
|
||||||
|
119
config/rv32gc/imperas.ic
Normal file
119
config/rv32gc/imperas.ic
Normal file
@ -0,0 +1,119 @@
|
|||||||
|
# imperas.ic
|
||||||
|
# Initialization file for ImperasDV lock step simulation
|
||||||
|
# David_Harris@hmc.edu 15 August 2024
|
||||||
|
# SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1
|
||||||
|
|
||||||
|
#--mpdconsole
|
||||||
|
#--gdbconsole
|
||||||
|
#--showoverrides
|
||||||
|
#--showcommands
|
||||||
|
|
||||||
|
# Core settings
|
||||||
|
--variant RV32GC # for RV32GC
|
||||||
|
--override cpu/priv_version=1.12
|
||||||
|
--override cpu/user_version=20191213
|
||||||
|
# arch
|
||||||
|
--override cpu/mimpid=0x100
|
||||||
|
--override cpu/mvendorid=0x602
|
||||||
|
--override cpu/marchid=0x24
|
||||||
|
--override refRoot/cpu/tvec_align=64
|
||||||
|
--override refRoot/cpu/envcfg_mask=1 # dh 1/26/24 this should be deleted when ImperasDV is updated to allow envcfg.FIOM to be written
|
||||||
|
|
||||||
|
# bit manipulation
|
||||||
|
--override cpu/add_Extensions=B
|
||||||
|
--override cpu/bitmanip_version=1.0.0
|
||||||
|
--override cpu/misa_B_Zba_Zbb_Zbs=T
|
||||||
|
|
||||||
|
# More extensions
|
||||||
|
--override cpu/Zcb=T
|
||||||
|
--override cpu/Zicond=T
|
||||||
|
--override cpu/Zfh=T
|
||||||
|
--override cpu/Zfa=T
|
||||||
|
|
||||||
|
# Cache block operations
|
||||||
|
--override cpu/Zicbom=T
|
||||||
|
--override cpu/Zicbop=T
|
||||||
|
--override cpu/Zicboz=T
|
||||||
|
--override cmomp_bytes=64 # Zic64b
|
||||||
|
--override cmoz_bytes=64 # Zic64b
|
||||||
|
--override lr_sc_grain=8 # Za64rs requires <=64; we use native word size
|
||||||
|
|
||||||
|
# 64 KiB continuous huge pages supported
|
||||||
|
#--override cpu/Svpbmt=F
|
||||||
|
#--override cpu/Svnapot_page_mask=65536
|
||||||
|
|
||||||
|
# SV32 supported
|
||||||
|
--override cpu/Sv_modes=3
|
||||||
|
#--showoverrides
|
||||||
|
|
||||||
|
--override cpu/Svinval=T
|
||||||
|
|
||||||
|
|
||||||
|
# clarify
|
||||||
|
#--override refRoot/cpu/mtvec_sext=F
|
||||||
|
|
||||||
|
--override cpu/tval_ii_code=T
|
||||||
|
|
||||||
|
#--override cpu/time_undefined=T
|
||||||
|
#--override cpu/cycle_undefined=T
|
||||||
|
#--override cpu/instret_undefined=T
|
||||||
|
#--override cpu/hpmcounter_undefined=T
|
||||||
|
|
||||||
|
--override cpu/reset_address=0x80000000
|
||||||
|
|
||||||
|
--override cpu/unaligned=F # Zicclsm (should be true)
|
||||||
|
--override cpu/ignore_non_leaf_DAU=1
|
||||||
|
--override cpu/wfi_is_nop=T
|
||||||
|
--override cpu/misa_Extensions_mask=0x0 # MISA not writable
|
||||||
|
--override cpu/Sstc=T
|
||||||
|
|
||||||
|
# Enable SVADU hardware update of A/D bits when menvcfg.ADUE=1
|
||||||
|
--override cpu/Svadu=T
|
||||||
|
#--override cpu/updatePTEA=F
|
||||||
|
#--override cpu/updatePTED=F
|
||||||
|
|
||||||
|
--override cpu/PMP_registers=16
|
||||||
|
--override cpu/PMP_undefined=T
|
||||||
|
|
||||||
|
# mstatus.FS is set dirty on any write to a FPR, or when a fp operation signals an exception
|
||||||
|
--override cpu/mstatus_fs_mode=write_1
|
||||||
|
|
||||||
|
# PMA Settings
|
||||||
|
# 'r': read access allowed
|
||||||
|
# 'w': write access allowed
|
||||||
|
# 'x': execute access allowed
|
||||||
|
# 'a': aligned access required
|
||||||
|
# 'A': atomic instructions NOT allowed (actually USER1 privilege needed)
|
||||||
|
# 'P': push/pop instructions NOT allowed (actually USER2 privilege needed)
|
||||||
|
# '1': 1-byte accesses allowed
|
||||||
|
# '2': 2-byte accesses allowed
|
||||||
|
# '4': 4-byte accesses allowed
|
||||||
|
# '8': 8-byte accesses allowed
|
||||||
|
# '-', space: ignored (use for input string formatting).
|
||||||
|
#
|
||||||
|
# SVxx Memory 0x0000000000 0x7FFFFFFFFF
|
||||||
|
#
|
||||||
|
--callcommand refRoot/cpu/setPMA -lo 0x0000000000 -hi 0xFFFFFFFFFFFFFFFFFF -attributes " ---a-- ---- " # All memory inaccessible unless defined otherwise
|
||||||
|
--callcommand refRoot/cpu/setPMA -lo 0x0000000000 -hi 0x7FFFFFFFFF -attributes " ---a-- ---- " # INITIAL
|
||||||
|
--callcommand refRoot/cpu/setPMA -lo 0x0000001000 -hi 0x0000001FFF -attributes " r-x-A- 1248 " # BOOTROM
|
||||||
|
--callcommand refRoot/cpu/setPMA -lo 0x0000012100 -hi 0x000001211F -attributes " rw-aA- --48 " # SDC
|
||||||
|
--callcommand refRoot/cpu/setPMA -lo 0x0002000000 -hi 0x000200FFFF -attributes " rw-aA- 1248 " # CLINT
|
||||||
|
--callcommand refRoot/cpu/setPMA -lo 0x000C000000 -hi 0x000FFFFFFF -attributes " rw-aA- --4- " # PLIC
|
||||||
|
--callcommand refRoot/cpu/setPMA -lo 0x0010000000 -hi 0x0010000007 -attributes " rw-aA- 1--- " # UART0 error - 0x10000000 - 0x100000FF
|
||||||
|
--callcommand refRoot/cpu/setPMA -lo 0x0010060000 -hi 0x00100600FF -attributes " rw-aA- --4- " # GPIO error - 0x10069000 - 0x100600FF
|
||||||
|
--callcommand refRoot/cpu/setPMA -lo 0x0010040000 -hi 0x0010040FFF -attributes " rw-aA- --4- " # SPI error - 0x10040000 - 0x10040FFF
|
||||||
|
--callcommand refRoot/cpu/setPMA -lo 0x0080000000 -hi 0x008FFFFFFF -attributes " rwx--- 1248 " # UNCORE_RAM
|
||||||
|
|
||||||
|
# Enable the Imperas instruction coverage
|
||||||
|
#-extlib refRoot/cpu/cv=imperas.com/intercept/riscvInstructionCoverage/1.0
|
||||||
|
#-override refRoot/cpu/cv/cover=basic
|
||||||
|
#-override refRoot/cpu/cv/extensions=RV32I
|
||||||
|
|
||||||
|
# Add Imperas simulator application instruction tracing
|
||||||
|
# uncomment these to provide tracing
|
||||||
|
--verbose --trace --tracechange --traceshowicount --tracemode -tracemem ASX --monitornetschange # --traceafter 300000000
|
||||||
|
--override cpu/debugflags=6 --override cpu/verbose=1
|
||||||
|
--override cpu/show_c_prefix=T
|
||||||
|
|
||||||
|
# Store simulator output to logfile
|
||||||
|
--output imperas.log
|
@ -109,9 +109,9 @@
|
|||||||
|
|
||||||
# Add Imperas simulator application instruction tracing
|
# Add Imperas simulator application instruction tracing
|
||||||
# uncomment these to provide tracing
|
# uncomment these to provide tracing
|
||||||
--verbose --trace --tracechange --traceshowicount --tracemode -tracemem ASX --monitornetschange # --traceafter 300000000
|
#--verbose --trace --tracechange --traceshowicount --tracemode -tracemem ASX --monitornetschange # --traceafter 300000000
|
||||||
--override cpu/debugflags=6 --override cpu/verbose=1
|
#--override cpu/debugflags=6 --override cpu/verbose=1
|
||||||
--override cpu/show_c_prefix=T
|
#--override cpu/show_c_prefix=T
|
||||||
|
|
||||||
# Store simulator output to logfile
|
# Store simulator output to logfile
|
||||||
--output imperas.log
|
--output imperas.log
|
@ -1,3 +1,32 @@
|
|||||||
|
///////////////////////////////////////////////////////////////////////
|
||||||
|
// spi.h
|
||||||
|
//
|
||||||
|
// Written: Jaocb Pease jacob.pease@okstate.edu 7/22/2024
|
||||||
|
//
|
||||||
|
// Purpose: Header file for interfaceing with the SPI peripheral
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// A component of the Wally configurable RISC-V project.
|
||||||
|
//
|
||||||
|
// Copyright (C) 2021-23 Harvey Mudd College & Oklahoma State University
|
||||||
|
//
|
||||||
|
// SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1
|
||||||
|
//
|
||||||
|
// Licensed under the Solderpad Hardware License v 2.1 (the
|
||||||
|
// “License”); you may not use this file except in compliance with the
|
||||||
|
// License, or, at your option, the Apache License version 2.0. You
|
||||||
|
// may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// https://solderpad.org/licenses/SHL-2.1/
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, any work
|
||||||
|
// distributed under the License is distributed on an “AS IS” BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||||
|
// implied. See the License for the specific language governing
|
||||||
|
// permissions and limitations under the License.
|
||||||
|
///////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
#ifndef SPI_HEADER
|
#ifndef SPI_HEADER
|
||||||
#define SPI_HEADER
|
#define SPI_HEADER
|
||||||
|
@ -149,10 +149,32 @@ if {$FunctCoverageIndex >= 0} {
|
|||||||
set lst [lreplace $lst $FunctCoverageIndex $FunctCoverageIndex]
|
set lst [lreplace $lst $FunctCoverageIndex $FunctCoverageIndex]
|
||||||
}\
|
}\
|
||||||
|
|
||||||
|
set FunctCoverageIndex2 [lsearch -exact $lst "--fcov2"]
|
||||||
|
if {$FunctCoverageIndex2 >= 0} {
|
||||||
|
set FunctCoverage 1
|
||||||
|
set riscvISACOVsrc +incdir+$env(IMPERAS_HOME)/ImpProprietary/source/host/riscvISACOV/source
|
||||||
|
|
||||||
|
set FCdefineINCLUDE_TRACE2COV "+define+INCLUDE_TRACE2COV"
|
||||||
|
set FCdefineCOVER_BASE_RV64I "+define+COVER_BASE_RV64I"
|
||||||
|
set FCdefineCOVER_LEVEL_DV_PR_EXT "+define+COVER_LEVEL_DV_PR_EXT"
|
||||||
|
# Uncomment various cover statements below to control which extensions get functional coverage
|
||||||
|
set FCdefineCOVER_RV64I "+define+COVER_RV64I"
|
||||||
|
#set FCdefineCOVER_RV64M "+define+COVER_RV64M"
|
||||||
|
#set FCdefineCOVER_RV64A "+define+COVER_RV64A"
|
||||||
|
#set FCdefineCOVER_RV64F "+define+COVER_RV64F"
|
||||||
|
#set FCdefineCOVER_RV64D "+define+COVER_RV64D"
|
||||||
|
#set FCdefineCOVER_RV64ZICSR "+define+COVER_RV64ZICSR"
|
||||||
|
#set FCdefineCOVER_RV64C "+define+COVER_RV64C"
|
||||||
|
set FCdefineIDV_INCLUDE_TRACE2COV "+define+IDV_INCLUDE_TRACE2COV"
|
||||||
|
set FCTRACE2COV "+TRACE2COV_ENABLE=1"
|
||||||
|
set FCdefineIDV_TRACE2COV "+IDV_TRACE2COV=1"
|
||||||
|
set lst [lreplace $lst $FunctCoverageIndex2 $FunctCoverageIndex2]
|
||||||
|
}\
|
||||||
|
|
||||||
set LockStepIndex [lsearch -exact $lst "--lockstep"]
|
set LockStepIndex [lsearch -exact $lst "--lockstep"]
|
||||||
# ugh. can't have more than 9 arguments passed to vsim. why? I'll have to remove --lockstep when running
|
# ugh. can't have more than 9 arguments passed to vsim. why? I'll have to remove --lockstep when running
|
||||||
# functional coverage and imply it.
|
# functional coverage and imply it.
|
||||||
if {$LockStepIndex >= 0 || $FunctCoverageIndex >= 0} {
|
if {$LockStepIndex >= 0 || $FunctCoverageIndex >= 0 || $FunctCoverageIndex2 >= 0} {
|
||||||
set lockstep 1
|
set lockstep 1
|
||||||
|
|
||||||
# ideally this would all be one or two variables, but questa is having a real hard time
|
# ideally this would all be one or two variables, but questa is having a real hard time
|
||||||
|
@ -169,12 +169,17 @@ module wallyTracer import cvw::*; #(parameter cvw_t P) (rvviTrace rvvi);
|
|||||||
CSRArray[12'h143] = testbench.dut.core.priv.priv.csr.csrs.csrs.STVAL_REGW;
|
CSRArray[12'h143] = testbench.dut.core.priv.priv.csr.csrs.csrs.STVAL_REGW;
|
||||||
CSRArray[12'h142] = testbench.dut.core.priv.priv.csr.csrs.csrs.SCAUSE_REGW;
|
CSRArray[12'h142] = testbench.dut.core.priv.priv.csr.csrs.csrs.SCAUSE_REGW;
|
||||||
CSRArray[12'h144] = testbench.dut.core.priv.priv.csr.csrm.MIP_REGW & 12'h222 & testbench.dut.core.priv.priv.csr.csrm.MIDELEG_REGW;
|
CSRArray[12'h144] = testbench.dut.core.priv.priv.csr.csrm.MIP_REGW & 12'h222 & testbench.dut.core.priv.priv.csr.csrm.MIDELEG_REGW;
|
||||||
CSRArray[12'h14D] = testbench.dut.core.priv.priv.csr.csrs.csrs.STIMECMP_REGW;
|
CSRArray[12'h14D] = testbench.dut.core.priv.priv.csr.csrs.csrs.STIMECMP_REGW[P.XLEN-1:0];
|
||||||
// user CSRs
|
// user CSRs
|
||||||
CSRArray[12'h001] = testbench.dut.core.priv.priv.csr.csru.csru.FFLAGS_REGW;
|
CSRArray[12'h001] = testbench.dut.core.priv.priv.csr.csru.csru.FFLAGS_REGW;
|
||||||
CSRArray[12'h002] = testbench.dut.core.priv.priv.csr.csru.csru.FRM_REGW;
|
CSRArray[12'h002] = testbench.dut.core.priv.priv.csr.csru.csru.FRM_REGW;
|
||||||
CSRArray[12'h003] = {testbench.dut.core.priv.priv.csr.csru.csru.FRM_REGW, testbench.dut.core.priv.priv.csr.csru.csru.FFLAGS_REGW};
|
CSRArray[12'h003] = {testbench.dut.core.priv.priv.csr.csru.csru.FRM_REGW, testbench.dut.core.priv.priv.csr.csru.csru.FFLAGS_REGW};
|
||||||
|
|
||||||
|
if (P.XLEN == 32) begin
|
||||||
|
CSRArray[12'h310] = testbench.dut.core.priv.priv.csr.csrsr.MSTATUSH_REGW;
|
||||||
|
CSRArray[12'h31A] = testbench.dut.core.priv.priv.csr.csrm.MENVCFGH_REGW;
|
||||||
|
CSRArray[12'h15D] = testbench.dut.core.priv.priv.csr.csrs.csrs.STIMECMP_REGW[63:32];
|
||||||
|
end
|
||||||
end else begin // hold the old value if the pipeline is stalled.
|
end else begin // hold the old value if the pipeline is stalled.
|
||||||
|
|
||||||
// PMP CFG 3A0 to 3AF
|
// PMP CFG 3A0 to 3AF
|
||||||
|
@ -762,7 +762,7 @@ end
|
|||||||
void'(rvviRefConfigSetString(IDV_CONFIG_MODEL_VENDOR, "riscv.ovpworld.org"));
|
void'(rvviRefConfigSetString(IDV_CONFIG_MODEL_VENDOR, "riscv.ovpworld.org"));
|
||||||
void'(rvviRefConfigSetString(IDV_CONFIG_MODEL_NAME, "riscv"));
|
void'(rvviRefConfigSetString(IDV_CONFIG_MODEL_NAME, "riscv"));
|
||||||
void'(rvviRefConfigSetString(IDV_CONFIG_MODEL_VARIANT, "RV64GCK"));
|
void'(rvviRefConfigSetString(IDV_CONFIG_MODEL_VARIANT, "RV64GCK"));
|
||||||
void'(rvviRefConfigSetInt(IDV_CONFIG_MODEL_ADDRESS_BUS_WIDTH, 56));
|
void'(rvviRefConfigSetInt(IDV_CONFIG_MODEL_ADDRESS_BUS_WIDTH, XLEN==64 ? 56 : 34));
|
||||||
void'(rvviRefConfigSetInt(IDV_CONFIG_MAX_NET_LATENCY_RETIREMENTS, 6));
|
void'(rvviRefConfigSetInt(IDV_CONFIG_MAX_NET_LATENCY_RETIREMENTS, 6));
|
||||||
|
|
||||||
if(elffilename == "buildroot") filename = "";
|
if(elffilename == "buildroot") filename = "";
|
||||||
@ -824,15 +824,25 @@ end
|
|||||||
void'(rvviRefCsrSetVolatile(0, 32'hC02)); // INSTRET
|
void'(rvviRefCsrSetVolatile(0, 32'hC02)); // INSTRET
|
||||||
void'(rvviRefCsrSetVolatile(0, 32'hB02)); // MINSTRET
|
void'(rvviRefCsrSetVolatile(0, 32'hB02)); // MINSTRET
|
||||||
void'(rvviRefCsrSetVolatile(0, 32'hC01)); // TIME
|
void'(rvviRefCsrSetVolatile(0, 32'hC01)); // TIME
|
||||||
|
if (P.XLEN == 32) begin
|
||||||
|
void'(rvviRefCsrSetVolatile(0, 32'hC80)); // CYCLEH
|
||||||
|
void'(rvviRefCsrSetVolatile(0, 32'hB80)); // MCYCLEH
|
||||||
|
void'(rvviRefCsrSetVolatile(0, 32'hC82)); // INSTRETH
|
||||||
|
void'(rvviRefCsrSetVolatile(0, 32'hB82)); // MINSTRETH
|
||||||
|
void'(rvviRefCsrSetVolatile(0, 32'hC81)); // TIMEH
|
||||||
|
end
|
||||||
// User HPMCOUNTER3 - HPMCOUNTER31
|
// User HPMCOUNTER3 - HPMCOUNTER31
|
||||||
for (iter='hC03; iter<='hC1F; iter++) begin
|
for (iter='hC03; iter<='hC1F; iter++) begin
|
||||||
void'(rvviRefCsrSetVolatile(0, iter)); // HPMCOUNTERx
|
void'(rvviRefCsrSetVolatile(0, iter)); // HPMCOUNTERx
|
||||||
|
if (P.XLEN == 32)
|
||||||
|
void'(rvviRefCsrSetVolatile(0, iter+128)); // HPMCOUNTERxH
|
||||||
end
|
end
|
||||||
|
|
||||||
// Machine MHPMCOUNTER3 - MHPMCOUNTER31
|
// Machine MHPMCOUNTER3 - MHPMCOUNTER31
|
||||||
for (iter='hB03; iter<='hB1F; iter++) begin
|
for (iter='hB03; iter<='hB1F; iter++) begin
|
||||||
void'(rvviRefCsrSetVolatile(0, iter)); // MHPMCOUNTERx
|
void'(rvviRefCsrSetVolatile(0, iter)); // MHPMCOUNTERx
|
||||||
|
if (P.XLEN == 32)
|
||||||
|
void'(rvviRefCsrSetVolatile(0, iter+128)); // MHPMCOUNTERxH
|
||||||
end
|
end
|
||||||
|
|
||||||
// cannot predict this register due to latency between
|
// cannot predict this register due to latency between
|
||||||
|
112
tests/custom/spitest/Makefile
Normal file
112
tests/custom/spitest/Makefile
Normal file
@ -0,0 +1,112 @@
|
|||||||
|
CEXT := c
|
||||||
|
CPPEXT := cpp
|
||||||
|
AEXT := s
|
||||||
|
SEXT := S
|
||||||
|
SRCEXT := \([$(CEXT)$(AEXT)$(SEXT)]\|$(CPPEXT)\)
|
||||||
|
OBJEXT := o
|
||||||
|
DEPEXT := d
|
||||||
|
SRCDIR := .
|
||||||
|
BUILDDIR := OBJ
|
||||||
|
|
||||||
|
SOURCES ?= $(shell find $(SRCDIR) -type f -regex ".*\.$(SRCEXT)" | sort)
|
||||||
|
OBJECTS := $(SOURCES:.$(CEXT)=.$(OBJEXT))
|
||||||
|
OBJECTS := $(OBJECTS:.$(AEXT)=.$(OBJEXT))
|
||||||
|
OBJECTS := $(OBJECTS:.$(SEXT)=.$(OBJEXT))
|
||||||
|
OBJECTS := $(OBJECTS:.$(CPPEXT)=.$(OBJEXT))
|
||||||
|
OBJECTS := $(patsubst $(SRCDIR)/%,$(BUILDDIR)/%,$(OBJECTS))
|
||||||
|
|
||||||
|
TARGETDIR := bin
|
||||||
|
TARGET := $(TARGETDIR)/spitest.elf
|
||||||
|
ROOT := ..
|
||||||
|
LIBRARY_DIRS :=
|
||||||
|
LIBRARY_FILES :=
|
||||||
|
|
||||||
|
MARCH :=-march=rv64imfdc
|
||||||
|
MABI :=-mabi=lp64d
|
||||||
|
LINK_FLAGS :=$(MARCH) $(MABI) -nostartfiles
|
||||||
|
LINKER :=$(ROOT)/linker8000-0000.x
|
||||||
|
|
||||||
|
|
||||||
|
AFLAGS =$(MARCH) $(MABI) -W
|
||||||
|
CFLAGS =$(MARCH) $(MABI) -mcmodel=medany -O2
|
||||||
|
AS=riscv64-unknown-elf-as
|
||||||
|
CC=riscv64-unknown-elf-gcc
|
||||||
|
AR=riscv64-unknown-elf-ar
|
||||||
|
|
||||||
|
|
||||||
|
#Default Make
|
||||||
|
all: directories $(TARGET).memfile
|
||||||
|
|
||||||
|
#Remake
|
||||||
|
remake: clean all
|
||||||
|
|
||||||
|
#Make the Directories
|
||||||
|
directories:
|
||||||
|
@mkdir -p $(TARGETDIR)
|
||||||
|
@mkdir -p $(BUILDDIR)
|
||||||
|
|
||||||
|
clean:
|
||||||
|
rm -rf $(BUILDDIR) $(TARGETDIR) *.memfile *.objdump
|
||||||
|
|
||||||
|
|
||||||
|
#Needed for building additional library projects
|
||||||
|
ifdef LIBRARY_DIRS
|
||||||
|
LIBS+=${LIBRARY_DIRS:%=-L%} ${LIBRARY_FILES:%=-l%}
|
||||||
|
INC+=${LIBRARY_DIRS:%=-I%}
|
||||||
|
|
||||||
|
${LIBRARY_DIRS}:
|
||||||
|
make -C $@ -j 1
|
||||||
|
|
||||||
|
.PHONY: $(LIBRARY_DIRS) $(TARGET)
|
||||||
|
endif
|
||||||
|
|
||||||
|
|
||||||
|
#Pull in dependency info for *existing* .o files
|
||||||
|
-include $(OBJECTS:.$(OBJEXT)=.$(DEPEXT))
|
||||||
|
|
||||||
|
#Link
|
||||||
|
$(TARGET): $(OBJECTS) $(LIBRARY_DIRS)
|
||||||
|
$(CC) $(LINK_FLAGS) -g -o $(TARGET) $(OBJECTS) ${LIBS} -T ${LINKER}
|
||||||
|
|
||||||
|
|
||||||
|
#Compile
|
||||||
|
$(BUILDDIR)/%.$(OBJEXT): $(SRCDIR)/%.$(CEXT)
|
||||||
|
@mkdir -p $(dir $@)
|
||||||
|
$(CC) $(CFLAGS) $(INC) -c -o $@ $< > $(BUILDDIR)/$*.list
|
||||||
|
@$(CC) $(CFLAGS) $(INC) -MM $(SRCDIR)/$*.$(CEXT) > $(BUILDDIR)/$*.$(DEPEXT)
|
||||||
|
@cp -f $(BUILDDIR)/$*.$(DEPEXT) $(BUILDDIR)/$*.$(DEPEXT).tmp
|
||||||
|
@sed -e 's|.*:|$(BUILDDIR)/$*.$(OBJEXT):|' < $(BUILDDIR)/$*.$(DEPEXT).tmp > $(BUILDDIR)/$*.$(DEPEXT)
|
||||||
|
@sed -e 's/.*://' -e 's/\\$$//' < $(BUILDDIR)/$*.$(DEPEXT).tmp | fmt -1 | sed -e 's/^ *//' -e 's/$$/:/' >> $(BUILDDIR)/$*.$(DEPEXT)
|
||||||
|
@rm -f $(BUILDDIR)/$*.$(DEPEXT).tmp
|
||||||
|
|
||||||
|
# gcc won't output dependencies for assembly files for some reason
|
||||||
|
# most asm files don't have dependencies so the echo will work for now.
|
||||||
|
$(BUILDDIR)/%.$(OBJEXT): $(SRCDIR)/%.$(AEXT)
|
||||||
|
@mkdir -p $(dir $@)
|
||||||
|
$(CC) $(CFLAGS) -c -o $@ $< > $(BUILDDIR)/$*.list
|
||||||
|
@echo $@: $< > $(BUILDDIR)/$*.$(DEPEXT)
|
||||||
|
|
||||||
|
$(BUILDDIR)/%.$(OBJEXT): $(SRCDIR)/%.$(SEXT)
|
||||||
|
@mkdir -p $(dir $@)
|
||||||
|
$(CC) $(CFLAGS) $(INC) -c -o $@ $< > $(BUILDDIR)/$*.list
|
||||||
|
@echo $@: $< > $(BUILDDIR)/$*.$(DEPEXT)
|
||||||
|
|
||||||
|
# C++
|
||||||
|
$(BUILDDIR)/%.$(OBJEXT): $(SRCDIR)/%.$(CPPEXT)
|
||||||
|
@mkdir -p $(dir $@)
|
||||||
|
$(CC) $(CFLAGS) $(INC) -c -o $@ $< > $(BUILDDIR)/$*.list
|
||||||
|
@$(CC) $(CFLAGS) $(INC) -MM $(SRCDIR)/$*.$(CPPEXT) > $(BUILDDIR)/$*.$(DEPEXT)
|
||||||
|
@cp -f $(BUILDDIR)/$*.$(DEPEXT) $(BUILDDIR)/$*.$(DEPEXT).tmp
|
||||||
|
@sed -e 's|.*:|$(BUILDDIR)/$*.$(OBJEXT):|' < $(BUILDDIR)/$*.$(DEPEXT).tmp > $(BUILDDIR)/$*.$(DEPEXT)
|
||||||
|
@sed -e 's/.*://' -e 's/\\$$//' < $(BUILDDIR)/$*.$(DEPEXT).tmp | fmt -1 | sed -e 's/^ *//' -e 's/$$/:/' >> $(BUILDDIR)/$*.$(DEPEXT)
|
||||||
|
@rm -f $(BUILDDIR)/$*.$(DEPEXT).tmp
|
||||||
|
|
||||||
|
# convert to hex
|
||||||
|
$(TARGET).memfile: $(TARGET)
|
||||||
|
@echo 'Making object dump file.'
|
||||||
|
@riscv64-unknown-elf-objdump -D $< > $<.objdump
|
||||||
|
@echo 'Making memory file'
|
||||||
|
riscv64-unknown-elf-elf2hex --bit-width 64 --input $^ --output $@
|
||||||
|
extractFunctionRadix.sh $<.objdump
|
||||||
|
mkdir -p ../work/
|
||||||
|
cp -f $(TARGETDIR)/* ../work/
|
116
tests/custom/spitest/spi.h
Normal file
116
tests/custom/spitest/spi.h
Normal file
@ -0,0 +1,116 @@
|
|||||||
|
///////////////////////////////////////////////////////////////////////
|
||||||
|
// spi.h
|
||||||
|
//
|
||||||
|
// Written: Jaocb Pease jacob.pease@okstate.edu 7/22/2024
|
||||||
|
//
|
||||||
|
// Purpose: Header file for interfaceing with the SPI peripheral
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// A component of the Wally configurable RISC-V project.
|
||||||
|
//
|
||||||
|
// Copyright (C) 2021-23 Harvey Mudd College & Oklahoma State University
|
||||||
|
//
|
||||||
|
// SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1
|
||||||
|
//
|
||||||
|
// Licensed under the Solderpad Hardware License v 2.1 (the
|
||||||
|
// “License”); you may not use this file except in compliance with the
|
||||||
|
// License, or, at your option, the Apache License version 2.0. You
|
||||||
|
// may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// https://solderpad.org/licenses/SHL-2.1/
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, any work
|
||||||
|
// distributed under the License is distributed on an “AS IS” BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||||
|
// implied. See the License for the specific language governing
|
||||||
|
// permissions and limitations under the License.
|
||||||
|
///////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
#ifndef SPI_HEADER
|
||||||
|
#define SPI_HEADER
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#define SPI_BASE 0x13000 /* Base address of SPI device used for SDC */
|
||||||
|
|
||||||
|
/* register offsets */
|
||||||
|
#define SPI_SCKDIV SPI_BASE + 0x00 /* Serial clock divisor */
|
||||||
|
#define SPI_SCKMODE SPI_BASE + 0x04 /* Serial clock mode */
|
||||||
|
#define SPI_CSID SPI_BASE + 0x10 /* Chip select ID */
|
||||||
|
#define SPI_CSDEF SPI_BASE + 0x14 /* Chip select default */
|
||||||
|
#define SPI_CSMODE SPI_BASE + 0x18 /* Chip select mode */
|
||||||
|
#define SPI_DELAY0 SPI_BASE + 0x28 /* Delay control 0 */
|
||||||
|
#define SPI_DELAY1 SPI_BASE + 0x2c /* Delay control 1 */
|
||||||
|
#define SPI_FMT SPI_BASE + 0x40 /* Frame format */
|
||||||
|
#define SPI_TXDATA SPI_BASE + 0x48 /* Tx FIFO data */
|
||||||
|
#define SPI_RXDATA SPI_BASE + 0x4c /* Rx FIFO data */
|
||||||
|
#define SPI_TXMARK SPI_BASE + 0x50 /* Tx FIFO [<35;39;29Mwatermark */
|
||||||
|
#define SPI_RXMARK SPI_BASE + 0x54 /* Rx FIFO watermark */
|
||||||
|
|
||||||
|
/* Non-implemented
|
||||||
|
#define SPI_FCTRL SPI_BASE + 0x60 // SPI flash interface control
|
||||||
|
#define SPI_FFMT SPI_BASE + 0x64 // SPI flash instruction format
|
||||||
|
*/
|
||||||
|
#define SPI_IE SPI_BASE + 0x70 /* Interrupt Enable Register */
|
||||||
|
#define SPI_IP SPI_BASE + 0x74 /* Interrupt Pendings Register */
|
||||||
|
|
||||||
|
/* delay0 bits */
|
||||||
|
#define SIFIVE_SPI_DELAY0_CSSCK(x) ((uint32_t)(x))
|
||||||
|
#define SIFIVE_SPI_DELAY0_CSSCK_MASK 0xffU
|
||||||
|
#define SIFIVE_SPI_DELAY0_SCKCS(x) ((uint32_t)(x) << 16)
|
||||||
|
#define SIFIVE_SPI_DELAY0_SCKCS_MASK (0xffU << 16)
|
||||||
|
|
||||||
|
/* delay1 bits */
|
||||||
|
#define SIFIVE_SPI_DELAY1_INTERCS(x) ((uint32_t)(x))
|
||||||
|
#define SIFIVE_SPI_DELAY1_INTERCS_MASK 0xffU
|
||||||
|
#define SIFIVE_SPI_DELAY1_INTERXFR(x) ((uint32_t)(x) << 16)
|
||||||
|
#define SIFIVE_SPI_DELAY1_INTERXFR_MASK (0xffU << 16)
|
||||||
|
|
||||||
|
/* csmode bits */
|
||||||
|
#define SIFIVE_SPI_CSMODE_MODE_AUTO 0U
|
||||||
|
#define SIFIVE_SPI_CSMODE_MODE_HOLD 2U
|
||||||
|
#define SIFIVE_SPI_CSMODE_MODE_OFF 3U
|
||||||
|
|
||||||
|
// inline void write_reg(uintptr_t addr, uint32_t value);
|
||||||
|
//inline uint32_t read_reg(uintptr_t addr);
|
||||||
|
//inline void spi_sendbyte(uint8_t byte);
|
||||||
|
//inline void waittx();
|
||||||
|
//inline void waitrx();
|
||||||
|
uint8_t spi_txrx(uint8_t byte);
|
||||||
|
uint8_t spi_dummy();
|
||||||
|
//inline uint8_t spi_readbyte();
|
||||||
|
//uint64_t spi_read64();
|
||||||
|
void spi_init();
|
||||||
|
void spi_set_clock(uint32_t clkin, uint32_t clkout);
|
||||||
|
|
||||||
|
static inline void write_reg(uintptr_t addr, uint32_t value) {
|
||||||
|
volatile uint32_t * loc = (volatile uint32_t *) addr;
|
||||||
|
*loc = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Read a register
|
||||||
|
static inline uint32_t read_reg(uintptr_t addr) {
|
||||||
|
return *(volatile uint32_t *) addr;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Queues a single byte in the transfer fifo
|
||||||
|
static inline void spi_sendbyte(uint8_t byte) {
|
||||||
|
// Write byte to transfer fifo
|
||||||
|
write_reg(SPI_TXDATA, byte);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void waittx() {
|
||||||
|
while(!(read_reg(SPI_IP) & 1)) {}
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void waitrx() {
|
||||||
|
while(read_reg(SPI_IP) & 2) {}
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline uint8_t spi_readbyte() {
|
||||||
|
return read_reg(SPI_RXDATA);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
107
tests/custom/spitest/spitest.c
Normal file
107
tests/custom/spitest/spitest.c
Normal file
@ -0,0 +1,107 @@
|
|||||||
|
///////////////////////////////////////////////////////////////////////
|
||||||
|
// spi.c
|
||||||
|
//
|
||||||
|
// Written: Jaocb Pease jacob.pease@okstate.edu 8/27/2024
|
||||||
|
//
|
||||||
|
// Purpose: C code to test SPI bugs
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// A component of the Wally configurable RISC-V project.
|
||||||
|
//
|
||||||
|
// Copyright (C) 2021-23 Harvey Mudd College & Oklahoma State University
|
||||||
|
//
|
||||||
|
// SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1
|
||||||
|
//
|
||||||
|
// Licensed under the Solderpad Hardware License v 2.1 (the
|
||||||
|
// “License”); you may not use this file except in compliance with the
|
||||||
|
// License, or, at your option, the Apache License version 2.0. You
|
||||||
|
// may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// https://solderpad.org/licenses/SHL-2.1/
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, any work
|
||||||
|
// distributed under the License is distributed on an “AS IS” BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||||
|
// implied. See the License for the specific language governing
|
||||||
|
// permissions and limitations under the License.
|
||||||
|
///////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
#include "spi.h"
|
||||||
|
|
||||||
|
// Testing SPI peripheral in loopback mode
|
||||||
|
// TODO: Need to make sure the configuration I'm using uses loopback
|
||||||
|
// mode. This can be specified in derivlists.txt
|
||||||
|
// TODO:
|
||||||
|
|
||||||
|
uint8_t spi_txrx(uint8_t byte) {
|
||||||
|
spi_sendbyte(byte);
|
||||||
|
waittx();
|
||||||
|
return spi_readbyte();
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t spi_dummy() {
|
||||||
|
return spi_txrx(0xff);
|
||||||
|
}
|
||||||
|
|
||||||
|
void spi_set_clock(uint32_t clkin, uint32_t clkout) {
|
||||||
|
uint32_t div = (clkin/(2*clkout)) - 1;
|
||||||
|
write_reg(SPI_SCKDIV, div);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Initialize Sifive FU540 based SPI Controller
|
||||||
|
void spi_init(uint32_t clkin) {
|
||||||
|
// Enable interrupts
|
||||||
|
write_reg(SPI_IE, 0x3);
|
||||||
|
|
||||||
|
// Set TXMARK to 1. If the number of entries is < 1
|
||||||
|
// IP's txwm field will go high.
|
||||||
|
// Set RXMARK to 0. If the number of entries is > 0
|
||||||
|
// IP's rwxm field will go high.
|
||||||
|
write_reg(SPI_TXMARK, 1);
|
||||||
|
write_reg(SPI_RXMARK, 0);
|
||||||
|
|
||||||
|
// Set Delay 0 to default
|
||||||
|
write_reg(SPI_DELAY0,
|
||||||
|
SIFIVE_SPI_DELAY0_CSSCK(1) |
|
||||||
|
SIFIVE_SPI_DELAY0_SCKCS(1));
|
||||||
|
|
||||||
|
// Set Delay 1 to default
|
||||||
|
write_reg(SPI_DELAY1,
|
||||||
|
SIFIVE_SPI_DELAY1_INTERCS(1) |
|
||||||
|
SIFIVE_SPI_DELAY1_INTERXFR(0));
|
||||||
|
|
||||||
|
// Initialize the SPI controller clock to
|
||||||
|
// div = (20MHz/(2*400kHz)) - 1 = 24 = 0x18
|
||||||
|
write_reg(SPI_SCKDIV, 0x18);
|
||||||
|
}
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
spi_init(100000000);
|
||||||
|
|
||||||
|
spi_set_clock(100000000,50000000);
|
||||||
|
|
||||||
|
volatile uint8_t *p = (uint8_t *)(0x8F000000);
|
||||||
|
int j;
|
||||||
|
uint64_t n = 0;
|
||||||
|
|
||||||
|
write_reg(SPI_CSMODE, SIFIVE_SPI_CSMODE_MODE_HOLD);
|
||||||
|
//n = 512/8;
|
||||||
|
|
||||||
|
n = 4;
|
||||||
|
do {
|
||||||
|
// Send 8 dummy bytes (fifo should be empty)
|
||||||
|
for (j = 0; j < 8; j++) {
|
||||||
|
spi_sendbyte(0xaa + j);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Reset counter. Process bytes AS THEY COME IN.
|
||||||
|
for (j = 0; j < 8; j++) {
|
||||||
|
while (!(read_reg(SPI_IP) & 2)) {}
|
||||||
|
uint8_t x = spi_readbyte();
|
||||||
|
*p++ = x;
|
||||||
|
}
|
||||||
|
} while(--n > 0);
|
||||||
|
|
||||||
|
write_reg(SPI_CSMODE, SIFIVE_SPI_CSMODE_MODE_AUTO);
|
||||||
|
}
|
59
tests/custom/spitest/start.s
Normal file
59
tests/custom/spitest/start.s
Normal file
@ -0,0 +1,59 @@
|
|||||||
|
.section .init
|
||||||
|
.global _start
|
||||||
|
.type _start, @function
|
||||||
|
|
||||||
|
_start:
|
||||||
|
# Initialize global pointer
|
||||||
|
.option push
|
||||||
|
.option norelax
|
||||||
|
1:auipc gp, %pcrel_hi(__global_pointer$)
|
||||||
|
addi gp, gp, %pcrel_lo(1b)
|
||||||
|
.option pop
|
||||||
|
|
||||||
|
li x1, 0
|
||||||
|
li x2, 0
|
||||||
|
li x4, 0
|
||||||
|
li x5, 0
|
||||||
|
li x6, 0
|
||||||
|
li x7, 0
|
||||||
|
li x8, 0
|
||||||
|
li x9, 0
|
||||||
|
li x10, 0
|
||||||
|
li x11, 0
|
||||||
|
li x12, 0
|
||||||
|
li x13, 0
|
||||||
|
li x14, 0
|
||||||
|
li x15, 0
|
||||||
|
li x16, 0
|
||||||
|
li x17, 0
|
||||||
|
li x18, 0
|
||||||
|
li x19, 0
|
||||||
|
li x20, 0
|
||||||
|
li x21, 0
|
||||||
|
li x22, 0
|
||||||
|
li x23, 0
|
||||||
|
li x24, 0
|
||||||
|
li x25, 0
|
||||||
|
li x26, 0
|
||||||
|
li x27, 0
|
||||||
|
li x28, 0
|
||||||
|
li x29, 0
|
||||||
|
li x30, 0
|
||||||
|
li x31, 0
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# set the stack pointer to the top of memory - 8 bytes (pointer size)
|
||||||
|
li sp, 0x87FFFFF8
|
||||||
|
|
||||||
|
jal ra, main
|
||||||
|
jal ra, _halt
|
||||||
|
|
||||||
|
.section .text
|
||||||
|
.global _halt
|
||||||
|
.type _halt, @function
|
||||||
|
_halt:
|
||||||
|
li gp, 1
|
||||||
|
li a0, 0
|
||||||
|
ecall
|
||||||
|
j _halt
|
Loading…
Reference in New Issue
Block a user