forked from Github_Repos/cvw
		
	added files needed for arch to build
This commit is contained in:
		
							parent
							
								
									93906b9457
								
							
						
					
					
						commit
						cf55b7edc0
					
				
							
								
								
									
										34
									
								
								tests/riscof/Makefile
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										34
									
								
								tests/riscof/Makefile
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,34 @@
 | 
			
		||||
arch_dir = ../../addins/riscv-arch-test
 | 
			
		||||
work_dir = "./riscof_work"
 | 
			
		||||
current_dir = $(shell pwd)
 | 
			
		||||
 | 
			
		||||
all: clone memfile
 | 
			
		||||
 | 
			
		||||
clone:
 | 
			
		||||
	mkdir -p $(work_dir)
 | 
			
		||||
	mkdir -p work
 | 
			
		||||
	sed 's,{0},$(current_dir),g;s,{1},32imc,g' config.ini > config32.ini
 | 
			
		||||
	sed 's,{0},$(current_dir),g;s,{1},64gc,g' config.ini > config64.ini
 | 
			
		||||
	riscof run --work-dir=$(work_dir) --config=config64.ini --suite=$(arch_dir)/riscv-test-suite/ --env=$(arch_dir)/riscv-test-suite/env
 | 
			
		||||
	cp -r $(work_dir)/rv64i_m work/
 | 
			
		||||
	riscof run --work-dir=$(work_dir) --config=config32.ini --suite=$(arch_dir)/riscv-test-suite/ --env=$(arch_dir)/riscv-test-suite/env
 | 
			
		||||
	cp -r $(work_dir)/rv32i_m work/
 | 
			
		||||
# sed  >> config64.ini
 | 
			
		||||
#	(cd $(arch_dir) && riscof validateyaml --config=config.ini)
 | 
			
		||||
#	(cd $(arch_dir) && riscof --verbose info arch-test --clone)
 | 
			
		||||
#	(cd $(arch_dir) && riscof testlist --config=config.ini --suite=riscv-arch-test/riscv-test-suite/ --env=riscv-arch-test/riscv-test-suite/env)
 | 
			
		||||
# sed -i 's/riscv{.}-unknown-/riscv64-unknown-/g' $(arch_dir)/spike/riscof_spike.py
 | 
			
		||||
# sed -i 's/riscv{.}-unknown-/riscv64-unknown-/g' $(arch_dir)/sail_cSim/riscof_sail_cSim.py
 | 
			
		||||
 | 
			
		||||
memfile:
 | 
			
		||||
	sleep 1
 | 
			
		||||
	find work/rv*/*/ -type f -name "*ref.elf" | while read f; do riscv64-unknown-elf-objdump -S -D "$$f" > "$$f.objdump"; done
 | 
			
		||||
	find work/rv32*/*/ -type f -name "*ref.elf" | while read f; do riscv64-unknown-elf-elf2hex --bit-width 32 --input "$$f" --output "$$f.memfile"; done
 | 
			
		||||
	find work/rv64*/*/ -type f -name "*ref.elf" | while read f; do riscv64-unknown-elf-elf2hex --bit-width 64 --input "$$f" --output "$$f.memfile"; done
 | 
			
		||||
	find work/rv*/*/ -type f -name "*.objdump" | while read f; do extractFunctionRadix.sh $$f; done
 | 
			
		||||
 | 
			
		||||
clean:
 | 
			
		||||
	rm -f config64.ini
 | 
			
		||||
	rm -f config32.ini
 | 
			
		||||
	rm -rf $(work_dir)
 | 
			
		||||
	rm -rf work
 | 
			
		||||
							
								
								
									
										14
									
								
								tests/riscof/config.ini
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										14
									
								
								tests/riscof/config.ini
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,14 @@
 | 
			
		||||
[RISCOF]
 | 
			
		||||
ReferencePlugin=sail_cSim
 | 
			
		||||
ReferencePluginPath={0}/sail_cSim
 | 
			
		||||
DUTPlugin=spike
 | 
			
		||||
DUTPluginPath={0}/spike
 | 
			
		||||
 | 
			
		||||
[spike]
 | 
			
		||||
pluginpath={0}/spike
 | 
			
		||||
ispec={0}/spike/spike_rv{1}_isa.yaml
 | 
			
		||||
pspec={0}/spike/spike_platform.yaml
 | 
			
		||||
target_run=1
 | 
			
		||||
 | 
			
		||||
[sail_cSim]
 | 
			
		||||
pluginpath={0}/sail_cSim
 | 
			
		||||
							
								
								
									
										2
									
								
								tests/riscof/sail_cSim/__init__.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										2
									
								
								tests/riscof/sail_cSim/__init__.py
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,2 @@
 | 
			
		||||
from pkgutil import extend_path
 | 
			
		||||
__path__ = extend_path(__path__, __name__)
 | 
			
		||||
							
								
								
									
										18
									
								
								tests/riscof/sail_cSim/env/link.ld
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										18
									
								
								tests/riscof/sail_cSim/env/link.ld
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@ -0,0 +1,18 @@
 | 
			
		||||
OUTPUT_ARCH( "riscv" )
 | 
			
		||||
ENTRY(rvtest_entry_point)
 | 
			
		||||
 | 
			
		||||
SECTIONS
 | 
			
		||||
{
 | 
			
		||||
  . = 0x80000000;
 | 
			
		||||
  .text.init : { *(.text.init) }
 | 
			
		||||
  . = ALIGN(0x1000);
 | 
			
		||||
  .tohost : { *(.tohost) }
 | 
			
		||||
  . = ALIGN(0x1000);
 | 
			
		||||
  .text : { *(.text) }
 | 
			
		||||
  . = ALIGN(0x1000);
 | 
			
		||||
  .data : { *(.data) }
 | 
			
		||||
  .data.string : { *(.data.string)}
 | 
			
		||||
  .bss : { *(.bss) }
 | 
			
		||||
  _end = .;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										55
									
								
								tests/riscof/sail_cSim/env/model_test.h
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										55
									
								
								tests/riscof/sail_cSim/env/model_test.h
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@ -0,0 +1,55 @@
 | 
			
		||||
#ifndef _COMPLIANCE_MODEL_H
 | 
			
		||||
#define _COMPLIANCE_MODEL_H
 | 
			
		||||
 | 
			
		||||
#define RVMODEL_DATA_SECTION \
 | 
			
		||||
        .pushsection .tohost,"aw",@progbits;                            \
 | 
			
		||||
        .align 8; .global tohost; tohost: .dword 0;                     \
 | 
			
		||||
        .align 8; .global fromhost; fromhost: .dword 0;                 \
 | 
			
		||||
        .popsection;                                                    \
 | 
			
		||||
        .align 8; .global begin_regstate; begin_regstate:               \
 | 
			
		||||
        .word 128;                                                      \
 | 
			
		||||
        .align 8; .global end_regstate; end_regstate:                   \
 | 
			
		||||
        .word 4;
 | 
			
		||||
 | 
			
		||||
//RV_COMPLIANCE_HALT
 | 
			
		||||
#define RVMODEL_HALT                                              \
 | 
			
		||||
  li x1, 1;                                                                   \
 | 
			
		||||
  write_tohost:                                                               \
 | 
			
		||||
    sw x1, tohost, t5;                                                        \
 | 
			
		||||
    j write_tohost;
 | 
			
		||||
 | 
			
		||||
#define RVMODEL_BOOT
 | 
			
		||||
 | 
			
		||||
//RV_COMPLIANCE_DATA_BEGIN
 | 
			
		||||
#define RVMODEL_DATA_BEGIN                                              \
 | 
			
		||||
  RVMODEL_DATA_SECTION                                                        \
 | 
			
		||||
  .align 4;\
 | 
			
		||||
  .global begin_signature; begin_signature:
 | 
			
		||||
 | 
			
		||||
//RV_COMPLIANCE_DATA_END
 | 
			
		||||
#define RVMODEL_DATA_END                                                      \
 | 
			
		||||
  .align 4; .global end_signature; end_signature:  
 | 
			
		||||
 | 
			
		||||
//RVTEST_IO_INIT
 | 
			
		||||
#define RVMODEL_IO_INIT
 | 
			
		||||
//RVTEST_IO_WRITE_STR
 | 
			
		||||
#define RVMODEL_IO_WRITE_STR(_R, _STR)
 | 
			
		||||
//RVTEST_IO_CHECK
 | 
			
		||||
#define RVMODEL_IO_CHECK()
 | 
			
		||||
//RVTEST_IO_ASSERT_GPR_EQ
 | 
			
		||||
#define RVMODEL_IO_ASSERT_GPR_EQ(_S, _R, _I)
 | 
			
		||||
//RVTEST_IO_ASSERT_SFPR_EQ
 | 
			
		||||
#define RVMODEL_IO_ASSERT_SFPR_EQ(_F, _R, _I)
 | 
			
		||||
//RVTEST_IO_ASSERT_DFPR_EQ
 | 
			
		||||
#define RVMODEL_IO_ASSERT_DFPR_EQ(_D, _R, _I)
 | 
			
		||||
 | 
			
		||||
#define RVMODEL_SET_MSW_INT
 | 
			
		||||
 | 
			
		||||
#define RVMODEL_CLEAR_MSW_INT
 | 
			
		||||
 | 
			
		||||
#define RVMODEL_CLEAR_MTIMER_INT
 | 
			
		||||
 | 
			
		||||
#define RVMODEL_CLEAR_MEXT_INT
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#endif // _COMPLIANCE_MODEL_H
 | 
			
		||||
							
								
								
									
										124
									
								
								tests/riscof/sail_cSim/riscof_sail_cSim.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										124
									
								
								tests/riscof/sail_cSim/riscof_sail_cSim.py
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,124 @@
 | 
			
		||||
import os
 | 
			
		||||
import re
 | 
			
		||||
import shutil
 | 
			
		||||
import subprocess
 | 
			
		||||
import shlex
 | 
			
		||||
import logging
 | 
			
		||||
import random
 | 
			
		||||
import string
 | 
			
		||||
from string import Template
 | 
			
		||||
 | 
			
		||||
import riscof.utils as utils
 | 
			
		||||
from riscof.pluginTemplate import pluginTemplate
 | 
			
		||||
import riscof.constants as constants
 | 
			
		||||
from riscv_isac.isac import isac
 | 
			
		||||
 | 
			
		||||
logger = logging.getLogger()
 | 
			
		||||
 | 
			
		||||
class sail_cSim(pluginTemplate):
 | 
			
		||||
    __model__ = "sail_c_simulator"
 | 
			
		||||
    __version__ = "0.5.0"
 | 
			
		||||
 | 
			
		||||
    def __init__(self, *args, **kwargs):
 | 
			
		||||
        sclass = super().__init__(*args, **kwargs)
 | 
			
		||||
 | 
			
		||||
        config = kwargs.get('config')
 | 
			
		||||
        if config is None:
 | 
			
		||||
            logger.error("Config node for sail_cSim missing.")
 | 
			
		||||
            raise SystemExit(1)
 | 
			
		||||
        self.num_jobs = str(config['jobs'] if 'jobs' in config else 1)
 | 
			
		||||
        self.pluginpath = os.path.abspath(config['pluginpath'])
 | 
			
		||||
        self.sail_exe = { '32' : os.path.join(config['PATH'] if 'PATH' in config else "","riscv_sim_RV32"),
 | 
			
		||||
                '64' : os.path.join(config['PATH'] if 'PATH' in config else "","riscv_sim_RV64")}
 | 
			
		||||
        self.isa_spec = os.path.abspath(config['ispec']) if 'ispec' in config else ''
 | 
			
		||||
        self.platform_spec = os.path.abspath(config['pspec']) if 'ispec' in config else ''
 | 
			
		||||
        self.make = config['make'] if 'make' in config else 'make'
 | 
			
		||||
        logger.debug("SAIL CSim plugin initialised using the following configuration.")
 | 
			
		||||
        for entry in config:
 | 
			
		||||
            logger.debug(entry+' : '+config[entry])
 | 
			
		||||
        return sclass
 | 
			
		||||
 | 
			
		||||
    def initialise(self, suite, work_dir, archtest_env):
 | 
			
		||||
        self.suite = suite
 | 
			
		||||
        self.work_dir = work_dir
 | 
			
		||||
        self.objdump_cmd = 'riscv64-unknown-elf-objdump -D {0} > {2};'
 | 
			
		||||
        self.compile_cmd = 'riscv64-unknown-elf-gcc -march={0} \
 | 
			
		||||
         -static -mcmodel=medany -fvisibility=hidden -nostdlib -nostartfiles\
 | 
			
		||||
         -T '+self.pluginpath+'/env/link.ld\
 | 
			
		||||
         -I '+self.pluginpath+'/env/\
 | 
			
		||||
         -I ' + archtest_env
 | 
			
		||||
 | 
			
		||||
    def build(self, isa_yaml, platform_yaml):
 | 
			
		||||
        ispec = utils.load_yaml(isa_yaml)['hart0']
 | 
			
		||||
        self.xlen = ('64' if 64 in ispec['supported_xlen'] else '32')
 | 
			
		||||
        self.isa = 'rv' + self.xlen
 | 
			
		||||
        self.compile_cmd = self.compile_cmd+' -mabi='+('lp64 ' if 64 in ispec['supported_xlen'] else 'ilp32 ')
 | 
			
		||||
        if "I" in ispec["ISA"]:
 | 
			
		||||
            self.isa += 'i'
 | 
			
		||||
        if "M" in ispec["ISA"]:
 | 
			
		||||
            self.isa += 'm'
 | 
			
		||||
        if "C" in ispec["ISA"]:
 | 
			
		||||
            self.isa += 'c'
 | 
			
		||||
        if "F" in ispec["ISA"]:
 | 
			
		||||
            self.isa += 'f'
 | 
			
		||||
        if "D" in ispec["ISA"]:
 | 
			
		||||
            self.isa += 'd'
 | 
			
		||||
        objdump = "riscv64-unknown-elf-objdump".format(self.xlen)
 | 
			
		||||
        if shutil.which(objdump) is None:
 | 
			
		||||
            logger.error(objdump+": executable not found. Please check environment setup.")
 | 
			
		||||
            raise SystemExit(1)
 | 
			
		||||
        compiler = "riscv64-unknown-elf-gcc".format(self.xlen)
 | 
			
		||||
        if shutil.which(compiler) is None:
 | 
			
		||||
            logger.error(compiler+": executable not found. Please check environment setup.")
 | 
			
		||||
            raise SystemExit(1)
 | 
			
		||||
        if shutil.which(self.sail_exe[self.xlen]) is None:
 | 
			
		||||
            logger.error(self.sail_exe[self.xlen]+ ": executable not found. Please check environment setup.")
 | 
			
		||||
            raise SystemExit(1)
 | 
			
		||||
        if shutil.which(self.make) is None:
 | 
			
		||||
            logger.error(self.make+": executable not found. Please check environment setup.")
 | 
			
		||||
            raise SystemExit(1)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    def runTests(self, testList, cgf_file=None):
 | 
			
		||||
        if os.path.exists(self.work_dir+ "/Makefile." + self.name[:-1]):
 | 
			
		||||
            os.remove(self.work_dir+ "/Makefile." + self.name[:-1])
 | 
			
		||||
        make = utils.makeUtil(makefilePath=os.path.join(self.work_dir, "Makefile." + self.name[:-1]))
 | 
			
		||||
        make.makeCommand = self.make + ' -j' + self.num_jobs
 | 
			
		||||
        for file in testList:
 | 
			
		||||
            testentry = testList[file]
 | 
			
		||||
            test = testentry['test_path']
 | 
			
		||||
            test_dir = testentry['work_dir']
 | 
			
		||||
            test_name = test.rsplit('/',1)[1][:-2]
 | 
			
		||||
 | 
			
		||||
            elf = 'ref.elf'
 | 
			
		||||
 | 
			
		||||
            execute = "@cd "+testentry['work_dir']+";"
 | 
			
		||||
 | 
			
		||||
            cmd = self.compile_cmd.format(testentry['isa'].lower(), self.xlen) + ' ' + test + ' -o ' + elf
 | 
			
		||||
            compile_cmd = cmd + ' -D' + " -D".join(testentry['macros'])
 | 
			
		||||
            execute+=compile_cmd+";"
 | 
			
		||||
 | 
			
		||||
            execute += self.objdump_cmd.format(elf, self.xlen, 'ref.disass')
 | 
			
		||||
            sig_file = os.path.join(test_dir, self.name[:-1] + ".signature")
 | 
			
		||||
 | 
			
		||||
            execute += self.sail_exe[self.xlen] + ' --test-signature={0} {1} > {2}.log 2>&1;'.format(sig_file, elf, test_name)
 | 
			
		||||
 | 
			
		||||
            cov_str = ' '
 | 
			
		||||
            for label in testentry['coverage_labels']:
 | 
			
		||||
                cov_str+=' -l '+label
 | 
			
		||||
 | 
			
		||||
            if cgf_file is not None:
 | 
			
		||||
                coverage_cmd = 'riscv_isac --verbose info coverage -d \
 | 
			
		||||
                        -t {0}.log --parser-name c_sail -o coverage.rpt  \
 | 
			
		||||
                        --sig-label begin_signature  end_signature \
 | 
			
		||||
                        --test-label rvtest_code_begin rvtest_code_end \
 | 
			
		||||
                        -e ref.elf -c {1} -x{2} {3};'.format(\
 | 
			
		||||
                        test_name, ' -c '.join(cgf_file), self.xlen, cov_str)
 | 
			
		||||
            else:
 | 
			
		||||
                coverage_cmd = ''
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
            execute+=coverage_cmd
 | 
			
		||||
 | 
			
		||||
            make.add_target(execute)
 | 
			
		||||
        make.execute_all(self.work_dir)
 | 
			
		||||
							
								
								
									
										18
									
								
								tests/riscof/spike/env/link.ld
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										18
									
								
								tests/riscof/spike/env/link.ld
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@ -0,0 +1,18 @@
 | 
			
		||||
OUTPUT_ARCH( "riscv" )
 | 
			
		||||
ENTRY(rvtest_entry_point)
 | 
			
		||||
 | 
			
		||||
SECTIONS
 | 
			
		||||
{
 | 
			
		||||
  . = 0x80000000;
 | 
			
		||||
  .text.init : { *(.text.init) }
 | 
			
		||||
  . = ALIGN(0x1000);
 | 
			
		||||
  .tohost : { *(.tohost) }
 | 
			
		||||
  . = ALIGN(0x1000);
 | 
			
		||||
  .text : { *(.text) }
 | 
			
		||||
  . = ALIGN(0x1000);
 | 
			
		||||
  .data : { *(.data) }
 | 
			
		||||
  .data.string : { *(.data.string)}
 | 
			
		||||
  .bss : { *(.bss) }
 | 
			
		||||
  _end = .;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										60
									
								
								tests/riscof/spike/env/model_test.h
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										60
									
								
								tests/riscof/spike/env/model_test.h
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@ -0,0 +1,60 @@
 | 
			
		||||
#ifndef _COMPLIANCE_MODEL_H
 | 
			
		||||
#define _COMPLIANCE_MODEL_H
 | 
			
		||||
#define RVMODEL_DATA_SECTION \
 | 
			
		||||
        .pushsection .tohost,"aw",@progbits;                            \
 | 
			
		||||
        .align 8; .global tohost; tohost: .dword 0;                     \
 | 
			
		||||
        .align 8; .global fromhost; fromhost: .dword 0;                 \
 | 
			
		||||
        .popsection;                                                    \
 | 
			
		||||
        .align 8; .global begin_regstate; begin_regstate:               \
 | 
			
		||||
        .word 128;                                                      \
 | 
			
		||||
        .align 8; .global end_regstate; end_regstate:                   \
 | 
			
		||||
        .word 4;
 | 
			
		||||
 | 
			
		||||
//RV_COMPLIANCE_HALT
 | 
			
		||||
#define RVMODEL_HALT                                              \
 | 
			
		||||
  li x1, 1;                                                                   \
 | 
			
		||||
  write_tohost:                                                               \
 | 
			
		||||
    sw x1, tohost, t5;                                                        \
 | 
			
		||||
    j write_tohost;
 | 
			
		||||
 | 
			
		||||
#define RVMODEL_BOOT
 | 
			
		||||
 | 
			
		||||
//RV_COMPLIANCE_DATA_BEGIN
 | 
			
		||||
#define RVMODEL_DATA_BEGIN                                              \
 | 
			
		||||
  RVMODEL_DATA_SECTION                                                        \
 | 
			
		||||
  .align 4;\
 | 
			
		||||
  .global begin_signature; begin_signature:
 | 
			
		||||
 | 
			
		||||
//RV_COMPLIANCE_DATA_END
 | 
			
		||||
#define RVMODEL_DATA_END                                                      \
 | 
			
		||||
  .align 4;\
 | 
			
		||||
  .global end_signature; end_signature:  
 | 
			
		||||
 | 
			
		||||
//RVTEST_IO_INIT
 | 
			
		||||
#define RVMODEL_IO_INIT
 | 
			
		||||
//RVTEST_IO_WRITE_STR
 | 
			
		||||
#define RVMODEL_IO_WRITE_STR(_R, _STR)
 | 
			
		||||
//RVTEST_IO_CHECK
 | 
			
		||||
#define RVMODEL_IO_CHECK()
 | 
			
		||||
//RVTEST_IO_ASSERT_GPR_EQ
 | 
			
		||||
#define RVMODEL_IO_ASSERT_GPR_EQ(_S, _R, _I)
 | 
			
		||||
//RVTEST_IO_ASSERT_SFPR_EQ
 | 
			
		||||
#define RVMODEL_IO_ASSERT_SFPR_EQ(_F, _R, _I)
 | 
			
		||||
//RVTEST_IO_ASSERT_DFPR_EQ
 | 
			
		||||
#define RVMODEL_IO_ASSERT_DFPR_EQ(_D, _R, _I)
 | 
			
		||||
 | 
			
		||||
#define RVMODEL_SET_MSW_INT       \
 | 
			
		||||
 li t1, 1;                         \
 | 
			
		||||
 li t2, 0x2000000;                 \
 | 
			
		||||
 sw t1, 0(t2);
 | 
			
		||||
 | 
			
		||||
#define RVMODEL_CLEAR_MSW_INT     \
 | 
			
		||||
 li t2, 0x2000000;                 \
 | 
			
		||||
 sw x0, 0(t2);
 | 
			
		||||
 | 
			
		||||
#define RVMODEL_CLEAR_MTIMER_INT
 | 
			
		||||
 | 
			
		||||
#define RVMODEL_CLEAR_MEXT_INT
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#endif // _COMPLIANCE_MODEL_H
 | 
			
		||||
							
								
								
									
										253
									
								
								tests/riscof/spike/riscof_spike.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										253
									
								
								tests/riscof/spike/riscof_spike.py
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,253 @@
 | 
			
		||||
import os
 | 
			
		||||
import re
 | 
			
		||||
import shutil
 | 
			
		||||
import subprocess
 | 
			
		||||
import shlex
 | 
			
		||||
import logging
 | 
			
		||||
import random
 | 
			
		||||
import string
 | 
			
		||||
from string import Template
 | 
			
		||||
import sys
 | 
			
		||||
 | 
			
		||||
import riscof.utils as utils
 | 
			
		||||
import riscof.constants as constants
 | 
			
		||||
from riscof.pluginTemplate import pluginTemplate
 | 
			
		||||
 | 
			
		||||
logger = logging.getLogger()
 | 
			
		||||
 | 
			
		||||
class spike(pluginTemplate):
 | 
			
		||||
    __model__ = "spike"
 | 
			
		||||
 | 
			
		||||
    #TODO: please update the below to indicate family, version, etc of your DUT.
 | 
			
		||||
    __version__ = "XXX"
 | 
			
		||||
 | 
			
		||||
    def __init__(self, *args, **kwargs):
 | 
			
		||||
        sclass = super().__init__(*args, **kwargs)
 | 
			
		||||
 | 
			
		||||
        config = kwargs.get('config')
 | 
			
		||||
 | 
			
		||||
        # If the config node for this DUT is missing or empty. Raise an error. At minimum we need
 | 
			
		||||
        # the paths to the ispec and pspec files
 | 
			
		||||
        if config is None:
 | 
			
		||||
            print("Please enter input file paths in configuration.")
 | 
			
		||||
            raise SystemExit(1)
 | 
			
		||||
 | 
			
		||||
        # In case of an RTL based DUT, this would be point to the final binary executable of your
 | 
			
		||||
        # test-bench produced by a simulator (like verilator, vcs, incisive, etc). In case of an iss or
 | 
			
		||||
        # emulator, this variable could point to where the iss binary is located. If 'PATH variable
 | 
			
		||||
        # is missing in the config.ini we can hardcode the alternate here.
 | 
			
		||||
        self.dut_exe = os.path.join(config['PATH'] if 'PATH' in config else "","spike")
 | 
			
		||||
 | 
			
		||||
        # Number of parallel jobs that can be spawned off by RISCOF
 | 
			
		||||
        # for various actions performed in later functions, specifically to run the tests in
 | 
			
		||||
        # parallel on the DUT executable. Can also be used in the build function if required.
 | 
			
		||||
        self.num_jobs = str(config['jobs'] if 'jobs' in config else 1)
 | 
			
		||||
 | 
			
		||||
        # Path to the directory where this python file is located. Collect it from the config.ini
 | 
			
		||||
        self.pluginpath=os.path.abspath(config['pluginpath'])
 | 
			
		||||
 | 
			
		||||
        # Collect the paths to the  riscv-config absed ISA and platform yaml files. One can choose
 | 
			
		||||
        # to hardcode these here itself instead of picking it from the config.ini file.
 | 
			
		||||
        self.isa_spec = os.path.abspath(config['ispec'])
 | 
			
		||||
        self.platform_spec = os.path.abspath(config['pspec'])
 | 
			
		||||
 | 
			
		||||
        #We capture if the user would like the run the tests on the target or
 | 
			
		||||
        #not. If you are interested in just compiling the tests and not running
 | 
			
		||||
        #them on the target, then following variable should be set to False
 | 
			
		||||
        if 'target_run' in config and config['target_run']=='0':
 | 
			
		||||
            self.target_run = False
 | 
			
		||||
        else:
 | 
			
		||||
            self.target_run = True
 | 
			
		||||
 | 
			
		||||
        # Return the parameters set above back to RISCOF for further processing.
 | 
			
		||||
        return sclass
 | 
			
		||||
 | 
			
		||||
    def initialise(self, suite, work_dir, archtest_env):
 | 
			
		||||
 | 
			
		||||
       # capture the working directory. Any artifacts that the DUT creates should be placed in this
 | 
			
		||||
       # directory. Other artifacts from the framework and the Reference plugin will also be placed
 | 
			
		||||
       # here itself.
 | 
			
		||||
       self.work_dir = work_dir
 | 
			
		||||
 | 
			
		||||
       # capture the architectural test-suite directory.
 | 
			
		||||
       self.suite_dir = suite
 | 
			
		||||
 | 
			
		||||
       # Note the march is not hardwired here, because it will change for each
 | 
			
		||||
       # test. Similarly the output elf name and compile macros will be assigned later in the
 | 
			
		||||
       # runTests function
 | 
			
		||||
       self.compile_cmd = 'riscv64-unknown-elf-gcc -march={0} \
 | 
			
		||||
         -static -mcmodel=medany -fvisibility=hidden -nostdlib -nostartfiles -g\
 | 
			
		||||
         -T '+self.pluginpath+'/env/link.ld\
 | 
			
		||||
         -I '+self.pluginpath+'/env/\
 | 
			
		||||
         -I ' + archtest_env + ' {2} -o {3} {4}'
 | 
			
		||||
 | 
			
		||||
       # add more utility snippets here
 | 
			
		||||
 | 
			
		||||
    def build(self, isa_yaml, platform_yaml):
 | 
			
		||||
 | 
			
		||||
      # load the isa yaml as a dictionary in python.
 | 
			
		||||
      ispec = utils.load_yaml(isa_yaml)['hart0']
 | 
			
		||||
 | 
			
		||||
      # capture the XLEN value by picking the max value in 'supported_xlen' field of isa yaml. This
 | 
			
		||||
      # will be useful in setting integer value in the compiler string (if not already hardcoded);
 | 
			
		||||
      self.xlen = ('64' if 64 in ispec['supported_xlen'] else '32')
 | 
			
		||||
 | 
			
		||||
      # for spike start building the '--isa' argument. the self.isa is dutnmae specific and may not be
 | 
			
		||||
      # useful for all DUTs
 | 
			
		||||
      self.isa = 'rv' + self.xlen
 | 
			
		||||
      if "I" in ispec["ISA"]:
 | 
			
		||||
          self.isa += 'i'
 | 
			
		||||
      if "M" in ispec["ISA"]:
 | 
			
		||||
          self.isa += 'm'
 | 
			
		||||
      if "F" in ispec["ISA"]:
 | 
			
		||||
          self.isa += 'f'
 | 
			
		||||
      if "D" in ispec["ISA"]:
 | 
			
		||||
          self.isa += 'd'
 | 
			
		||||
      if "C" in ispec["ISA"]:
 | 
			
		||||
          self.isa += 'c'
 | 
			
		||||
 | 
			
		||||
      #TODO: The following assumes you are using the riscv-gcc toolchain. If
 | 
			
		||||
      #      not please change appropriately
 | 
			
		||||
      self.compile_cmd = self.compile_cmd+' -mabi='+('lp64 ' if 64 in ispec['supported_xlen'] else 'ilp32 ')
 | 
			
		||||
 | 
			
		||||
    def runTests(self, testList):
 | 
			
		||||
 | 
			
		||||
      # Delete Makefile if it already exists.
 | 
			
		||||
      if os.path.exists(self.work_dir+ "/Makefile." + self.name[:-1]):
 | 
			
		||||
            os.remove(self.work_dir+ "/Makefile." + self.name[:-1])
 | 
			
		||||
      # create an instance the makeUtil class that we will use to create targets.
 | 
			
		||||
      make = utils.makeUtil(makefilePath=os.path.join(self.work_dir, "Makefile." + self.name[:-1]))
 | 
			
		||||
 | 
			
		||||
      # set the make command that will be used. The num_jobs parameter was set in the __init__
 | 
			
		||||
      # function earlier
 | 
			
		||||
      make.makeCommand = 'make -j' + self.num_jobs
 | 
			
		||||
 | 
			
		||||
      # we will iterate over each entry in the testList. Each entry node will be refered to by the
 | 
			
		||||
      # variable testname.
 | 
			
		||||
      for testname in testList:
 | 
			
		||||
 | 
			
		||||
          # for each testname we get all its fields (as described by the testList format)
 | 
			
		||||
          testentry = testList[testname]
 | 
			
		||||
 | 
			
		||||
          # we capture the path to the assembly file of this test
 | 
			
		||||
          test = testentry['test_path']
 | 
			
		||||
 | 
			
		||||
          # capture the directory where the artifacts of this test will be dumped/created. RISCOF is
 | 
			
		||||
          # going to look into this directory for the signature files
 | 
			
		||||
          test_dir = testentry['work_dir']
 | 
			
		||||
 | 
			
		||||
          # name of the elf file after compilation of the test
 | 
			
		||||
          elf = 'my.elf'
 | 
			
		||||
 | 
			
		||||
          # name of the signature file as per requirement of RISCOF. RISCOF expects the signature to
 | 
			
		||||
          # be named as DUT-<dut-name>.signature. The below variable creates an absolute path of
 | 
			
		||||
          # signature file.
 | 
			
		||||
          sig_file = os.path.join(test_dir, self.name[:-1] + ".signature")
 | 
			
		||||
 | 
			
		||||
          # for each test there are specific compile macros that need to be enabled. The macros in
 | 
			
		||||
          # the testList node only contain the macros/values. For the gcc toolchain we need to
 | 
			
		||||
          # prefix with "-D". The following does precisely that.
 | 
			
		||||
          compile_macros= ' -D' + " -D".join(testentry['macros'])
 | 
			
		||||
 | 
			
		||||
          # substitute all variables in the compile command that we created in the initialize
 | 
			
		||||
          # function
 | 
			
		||||
          cmd = self.compile_cmd.format(testentry['isa'].lower(), self.xlen, test, elf, compile_macros)
 | 
			
		||||
 | 
			
		||||
	  # if the user wants to disable running the tests and only compile the tests, then
 | 
			
		||||
	  # the "else" clause is executed below assigning the sim command to simple no action
 | 
			
		||||
	  # echo statement.
 | 
			
		||||
          if self.target_run:
 | 
			
		||||
            # set up the simulation command. Template is for spike. Please change.
 | 
			
		||||
            simcmd = self.dut_exe + ' --isa={0} +signature={1} +signature-granularity=4 {2}'.format(self.isa, sig_file, elf)
 | 
			
		||||
          else:
 | 
			
		||||
            simcmd = 'echo "NO RUN"'
 | 
			
		||||
 | 
			
		||||
          # concatenate all commands that need to be executed within a make-target.
 | 
			
		||||
          execute = '@cd {0}; {1}; {2};'.format(testentry['work_dir'], cmd, simcmd)
 | 
			
		||||
 | 
			
		||||
          # create a target. The makeutil will create a target with the name "TARGET<num>" where num
 | 
			
		||||
          # starts from 0 and increments automatically for each new target that is added
 | 
			
		||||
          make.add_target(execute)
 | 
			
		||||
 | 
			
		||||
      # if you would like to exit the framework once the makefile generation is complete uncomment the
 | 
			
		||||
      # following line. Note this will prevent any signature checking or report generation.
 | 
			
		||||
      #raise SystemExit
 | 
			
		||||
 | 
			
		||||
      # once the make-targets are done and the makefile has been created, run all the targets in
 | 
			
		||||
      # parallel using the make command set above.
 | 
			
		||||
      make.execute_all(self.work_dir)
 | 
			
		||||
 | 
			
		||||
      # if target runs are not required then we simply exit as this point after running all
 | 
			
		||||
      # the makefile targets.
 | 
			
		||||
      if not self.target_run:
 | 
			
		||||
          raise SystemExit(0)
 | 
			
		||||
 | 
			
		||||
#The following is an alternate template that can be used instead of the above.
 | 
			
		||||
#The following template only uses shell commands to compile and run the tests.
 | 
			
		||||
 | 
			
		||||
#    def runTests(self, testList):
 | 
			
		||||
#
 | 
			
		||||
#      # we will iterate over each entry in the testList. Each entry node will be referred to by the
 | 
			
		||||
#      # variable testname.
 | 
			
		||||
#      for testname in testList:
 | 
			
		||||
#
 | 
			
		||||
#          logger.debug('Running Test: {0} on DUT'.format(testname))
 | 
			
		||||
#          # for each testname we get all its fields (as described by the testList format)
 | 
			
		||||
#          testentry = testList[testname]
 | 
			
		||||
#
 | 
			
		||||
#          # we capture the path to the assembly file of this test
 | 
			
		||||
#          test = testentry['test_path']
 | 
			
		||||
#
 | 
			
		||||
#          # capture the directory where the artifacts of this test will be dumped/created.
 | 
			
		||||
#          test_dir = testentry['work_dir']
 | 
			
		||||
#
 | 
			
		||||
#          # name of the elf file after compilation of the test
 | 
			
		||||
#          elf = 'my.elf'
 | 
			
		||||
#
 | 
			
		||||
#          # name of the signature file as per requirement of RISCOF. RISCOF expects the signature to
 | 
			
		||||
#          # be named as DUT-<dut-name>.signature. The below variable creates an absolute path of
 | 
			
		||||
#          # signature file.
 | 
			
		||||
#          sig_file = os.path.join(test_dir, self.name[:-1] + ".signature")
 | 
			
		||||
#
 | 
			
		||||
#          # for each test there are specific compile macros that need to be enabled. The macros in
 | 
			
		||||
#          # the testList node only contain the macros/values. For the gcc toolchain we need to
 | 
			
		||||
#          # prefix with "-D". The following does precisely that.
 | 
			
		||||
#          compile_macros= ' -D' + " -D".join(testentry['macros'])
 | 
			
		||||
#
 | 
			
		||||
#          # collect the march string required for the compiler
 | 
			
		||||
#          marchstr = testentry['isa'].lower()
 | 
			
		||||
#
 | 
			
		||||
#          # substitute all variables in the compile command that we created in the initialize
 | 
			
		||||
#          # function
 | 
			
		||||
#          cmd = self.compile_cmd.format(marchstr, self.xlen, test, elf, compile_macros)
 | 
			
		||||
#
 | 
			
		||||
#          # just a simple logger statement that shows up on the terminal
 | 
			
		||||
#          logger.debug('Compiling test: ' + test)
 | 
			
		||||
#
 | 
			
		||||
#          # the following command spawns a process to run the compile command. Note here, we are
 | 
			
		||||
#          # changing the directory for this command to that pointed by test_dir. If you would like
 | 
			
		||||
#          # the artifacts to be dumped else where change the test_dir variable to the path of your
 | 
			
		||||
#          # choice.
 | 
			
		||||
#          utils.shellCommand(cmd).run(cwd=test_dir)
 | 
			
		||||
#
 | 
			
		||||
#          # for debug purposes if you would like stop the DUT plugin after compilation, you can
 | 
			
		||||
#          # comment out the lines below and raise a SystemExit
 | 
			
		||||
#
 | 
			
		||||
#          if self.target_run:
 | 
			
		||||
#            # build the command for running the elf on the DUT. In this case we use spike and indicate
 | 
			
		||||
#            # the isa arg that we parsed in the build stage, elf filename and signature filename.
 | 
			
		||||
#            # Template is for spike. Please change for your DUT
 | 
			
		||||
#            execute = self.dut_exe + ' --isa={0} +signature={1} +signature-granularity=4 {2}'.format(self.isa, sig_file, elf)
 | 
			
		||||
#            logger.debug('Executing on Spike ' + execute)
 | 
			
		||||
#
 | 
			
		||||
#          # launch the execute command. Change the test_dir if required.
 | 
			
		||||
#          utils.shellCommand(execute).run(cwd=test_dir)
 | 
			
		||||
#
 | 
			
		||||
#          # post-processing steps can be added here in the template below
 | 
			
		||||
#          #postprocess = 'mv {0} temp.sig'.format(sig_file)'
 | 
			
		||||
#          #utils.shellCommand(postprocess).run(cwd=test_dir)
 | 
			
		||||
#
 | 
			
		||||
#      # if target runs are not required then we simply exit as this point after running all
 | 
			
		||||
#      # the makefile targets.
 | 
			
		||||
#      if not self.target_run:
 | 
			
		||||
#          raise SystemExit
 | 
			
		||||
							
								
								
									
										10
									
								
								tests/riscof/spike/spike_platform.yaml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										10
									
								
								tests/riscof/spike/spike_platform.yaml
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,10 @@
 | 
			
		||||
mtime:
 | 
			
		||||
  implemented: true
 | 
			
		||||
  address: 0xbff8
 | 
			
		||||
mtimecmp:
 | 
			
		||||
  implemented: true
 | 
			
		||||
  address: 0x4000
 | 
			
		||||
nmi:
 | 
			
		||||
  label: nmi_vector
 | 
			
		||||
reset:
 | 
			
		||||
  label: reset_vector
 | 
			
		||||
							
								
								
									
										29
									
								
								tests/riscof/spike/spike_rv32imc_isa.yaml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										29
									
								
								tests/riscof/spike/spike_rv32imc_isa.yaml
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,29 @@
 | 
			
		||||
hart_ids: [0]
 | 
			
		||||
hart0:
 | 
			
		||||
  ISA: RV32IMCZicsr_Zifencei
 | 
			
		||||
  physical_addr_sz: 32
 | 
			
		||||
  User_Spec_Version: '2.3'
 | 
			
		||||
  supported_xlen: [32]
 | 
			
		||||
  misa:
 | 
			
		||||
   reset-val: 0x40001104
 | 
			
		||||
   rv32:
 | 
			
		||||
     accessible: true
 | 
			
		||||
     mxl:
 | 
			
		||||
       implemented: true
 | 
			
		||||
       type:
 | 
			
		||||
           warl:
 | 
			
		||||
              dependency_fields: []
 | 
			
		||||
              legal:
 | 
			
		||||
                - mxl[1:0] in [0x1]
 | 
			
		||||
              wr_illegal:
 | 
			
		||||
                - Unchanged
 | 
			
		||||
     extensions:
 | 
			
		||||
       implemented: true
 | 
			
		||||
       type:
 | 
			
		||||
           warl:
 | 
			
		||||
              dependency_fields: []
 | 
			
		||||
              legal:
 | 
			
		||||
                - extensions[25:0] bitmask [0x0001104, 0x0000000]
 | 
			
		||||
              wr_illegal:
 | 
			
		||||
                - Unchanged
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										31
									
								
								tests/riscof/spike/spike_rv64gc_isa.yaml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										31
									
								
								tests/riscof/spike/spike_rv64gc_isa.yaml
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,31 @@
 | 
			
		||||
hart_ids: [0]
 | 
			
		||||
hart0:
 | 
			
		||||
  ISA: RV64IMAFDCSUZicsr_Zifencei
 | 
			
		||||
  physical_addr_sz: 56
 | 
			
		||||
  User_Spec_Version: '2.3'
 | 
			
		||||
  supported_xlen: [64]
 | 
			
		||||
  misa:
 | 
			
		||||
   reset-val: 0x800000000014112D
 | 
			
		||||
   rv32:
 | 
			
		||||
      accessible: false
 | 
			
		||||
   rv64:
 | 
			
		||||
     accessible: true
 | 
			
		||||
     mxl:
 | 
			
		||||
       implemented: true
 | 
			
		||||
       type:
 | 
			
		||||
           warl:
 | 
			
		||||
              dependency_fields: []
 | 
			
		||||
              legal:
 | 
			
		||||
                - mxl[1:0] in [0x2]
 | 
			
		||||
              wr_illegal:
 | 
			
		||||
                - Unchanged
 | 
			
		||||
     extensions:
 | 
			
		||||
       implemented: true
 | 
			
		||||
       type:
 | 
			
		||||
           warl:
 | 
			
		||||
              dependency_fields: []
 | 
			
		||||
              legal:
 | 
			
		||||
                - extensions[25:0] bitmask [0x014112D, 0x0000000]
 | 
			
		||||
              wr_illegal:
 | 
			
		||||
                - Unchanged
 | 
			
		||||
 
 | 
			
		||||
		Loading…
	
		Reference in New Issue
	
	Block a user