Compare commits
	
		
			5 Commits
		
	
	
		
			hotfix/lat
			...
			34bb8e62ae
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 34bb8e62ae | |||
| da7e29fbb7 | |||
| c4da47cedd | |||
| ab554539e3 | |||
| d43b35949e | 
@@ -1,6 +1,6 @@
 | 
				
			|||||||
cmake_minimum_required(VERSION 3.12)
 | 
					cmake_minimum_required(VERSION 3.12)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
project("riscv" VERSION 1.0.0)
 | 
					project("tgfs" VERSION 1.0.0)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
include(GNUInstallDirs)
 | 
					include(GNUInstallDirs)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -28,7 +28,7 @@ add_subdirectory(softfloat)
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
# library files
 | 
					# library files
 | 
				
			||||||
FILE(GLOB RiscVSCHeaders ${CMAKE_CURRENT_SOURCE_DIR}/incl/sysc/*.h ${CMAKE_CURRENT_SOURCE_DIR}/incl/sysc/*/*.h)
 | 
					FILE(GLOB RiscVSCHeaders ${CMAKE_CURRENT_SOURCE_DIR}/incl/sysc/*.h ${CMAKE_CURRENT_SOURCE_DIR}/incl/sysc/*/*.h)
 | 
				
			||||||
set(LIB_HEADERS ${RiscVSCHeaders} )
 | 
					set(LIB_HEADERS tgfscVSCHeaders} )
 | 
				
			||||||
set(LIB_SOURCES 
 | 
					set(LIB_SOURCES 
 | 
				
			||||||
	src/iss/tgf_b.cpp
 | 
						src/iss/tgf_b.cpp
 | 
				
			||||||
	src/iss/tgf_c.cpp
 | 
						src/iss/tgf_c.cpp
 | 
				
			||||||
@@ -49,56 +49,58 @@ set(LIB_SOURCES ${LIB_SOURCES}
 | 
				
			|||||||
endif()
 | 
					endif()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# Define the library
 | 
					# Define the library
 | 
				
			||||||
add_library(riscv SHARED ${LIB_SOURCES})
 | 
					add_library(tgfs SHARED ${LIB_SOURCES})
 | 
				
			||||||
target_compile_options(riscv PRIVATE -Wno-shift-count-overflow)
 | 
					# list code gen dependencies
 | 
				
			||||||
target_include_directories(riscv PUBLIC incl ../external/elfio)
 | 
					add_dependencies(tgfs TGF_C_src)
 | 
				
			||||||
target_link_libraries(riscv PUBLIC softfloat scc-util jsoncpp)
 | 
					
 | 
				
			||||||
target_link_libraries(riscv PUBLIC -Wl,--whole-archive dbt-core -Wl,--no-whole-archive)
 | 
					target_compile_options(tgfs PRIVATE -Wno-shift-count-overflow)
 | 
				
			||||||
set_target_properties(riscv PROPERTIES
 | 
					target_include_directories(tgfs PUBLIC incl)
 | 
				
			||||||
 | 
					target_link_libraries(tgfs PUBLIC softfloat scc-util)
 | 
				
			||||||
 | 
					target_link_libraries(tgfs PUBLIC -Wl,--whole-archive dbt-core -Wl,--no-whole-archive)
 | 
				
			||||||
 | 
					set_target_properties(tgfs PROPERTIES
 | 
				
			||||||
  VERSION ${PROJECT_VERSION}
 | 
					  VERSION ${PROJECT_VERSION}
 | 
				
			||||||
  FRAMEWORK FALSE
 | 
					  FRAMEWORK FALSE
 | 
				
			||||||
  PUBLIC_HEADER "${LIB_HEADERS}" # specify the public headers
 | 
					  PUBLIC_HEADER "${LIB_HEADERS}" # specify the public headers
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
if(SystemC_FOUND)
 | 
					if(SystemC_FOUND)
 | 
				
			||||||
	add_library(riscv_sc src/sysc/core_complex.cpp)
 | 
						add_library(tgfs_sc src/sysc/core_complex.cpp)
 | 
				
			||||||
	target_compile_definitions(riscv_sc PUBLIC WITH_SYSTEMC) 
 | 
						target_compile_definitions(tgfs_sc PUBLIC WITH_SYSTEMC) 
 | 
				
			||||||
	target_include_directories(riscv_sc PUBLIC ../incl ${SystemC_INCLUDE_DIRS} ${CCI_INCLUDE_DIRS})
 | 
						target_include_directories(tgfs_sc PUBLIC ../incl ${SystemC_INCLUDE_DIRS} ${CCI_INCLUDE_DIRS})
 | 
				
			||||||
	
 | 
						
 | 
				
			||||||
	if(SCV_FOUND)   
 | 
						if(SCV_FOUND)   
 | 
				
			||||||
	    target_compile_definitions(riscv_sc PUBLIC WITH_SCV)
 | 
						    target_compile_definitions(tgfs_sc PUBLIC WITH_SCV)
 | 
				
			||||||
	    target_include_directories(riscv_sc PUBLIC ${SCV_INCLUDE_DIRS})
 | 
						    target_include_directories(tgfs_sc PUBLIC ${SCV_INCLUDE_DIRS})
 | 
				
			||||||
	endif()
 | 
						endif()
 | 
				
			||||||
	target_link_libraries(riscv_sc PUBLIC riscv scc )
 | 
						target_link_libraries(tgfs_sc PUBLIC tgfs scc )
 | 
				
			||||||
	if(WITH_LLVM)
 | 
						if(WITH_LLVM)
 | 
				
			||||||
		target_link_libraries(riscv_sc PUBLIC ${llvm_libs})
 | 
							target_link_libraries(tgfs_sc PUBLIC ${llvm_libs})
 | 
				
			||||||
	endif()
 | 
						endif()
 | 
				
			||||||
	target_link_libraries(riscv_sc PUBLIC ${Boost_LIBRARIES} )
 | 
						target_link_libraries(tgfs_sc PUBLIC ${Boost_LIBRARIES} )
 | 
				
			||||||
	set_target_properties(riscv_sc PROPERTIES
 | 
						set_target_properties(tgfs_sc PROPERTIES
 | 
				
			||||||
	  VERSION ${PROJECT_VERSION}
 | 
						  VERSION ${PROJECT_VERSION}
 | 
				
			||||||
	  FRAMEWORK FALSE
 | 
						  FRAMEWORK FALSE
 | 
				
			||||||
	  PUBLIC_HEADER "${LIB_HEADERS}" # specify the public headers
 | 
						  PUBLIC_HEADER "${LIB_HEADERS}" # specify the public headers
 | 
				
			||||||
	)
 | 
						)
 | 
				
			||||||
endif()
 | 
					endif()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
project("riscv-sim")
 | 
					project("tgfs-sim")
 | 
				
			||||||
add_executable(riscv-sim src/main.cpp)
 | 
					add_executable(tgfs-sim src/main.cpp)
 | 
				
			||||||
# This sets the include directory for the reference project. This is the -I flag in gcc.
 | 
					# This sets the include directory for the reference project. This is the -I flag in gcc.
 | 
				
			||||||
target_include_directories(riscv-sim PRIVATE ../external/libGIS)
 | 
					
 | 
				
			||||||
if(WITH_LLVM)
 | 
					if(WITH_LLVM)
 | 
				
			||||||
	target_compile_definitions(riscv-sim PRIVATE WITH_LLVM)
 | 
						target_compile_definitions(tgfs-sim PRIVATE WITH_LLVM)
 | 
				
			||||||
	target_link_libraries(riscv-sim PUBLIC ${llvm_libs})
 | 
						target_link_libraries(tgfs-sim PUBLIC ${llvm_libs})
 | 
				
			||||||
endif()
 | 
					endif()
 | 
				
			||||||
# Links the target exe against the libraries
 | 
					# Links the target exe against the libraries
 | 
				
			||||||
target_link_libraries(riscv-sim riscv)
 | 
					target_link_libraries(tgfs-sim tgfs)
 | 
				
			||||||
target_link_libraries(riscv-sim jsoncpp)
 | 
					target_link_libraries(tgfs-sim jsoncpp)
 | 
				
			||||||
target_link_libraries(riscv-sim external)
 | 
					target_link_libraries(tgfs-sim ${Boost_LIBRARIES} )
 | 
				
			||||||
target_link_libraries(riscv-sim ${Boost_LIBRARIES} )
 | 
					 | 
				
			||||||
if (Tcmalloc_FOUND)
 | 
					if (Tcmalloc_FOUND)
 | 
				
			||||||
    target_link_libraries(riscv-sim ${Tcmalloc_LIBRARIES})
 | 
					    target_link_libraries(tgfs-sim ${Tcmalloc_LIBRARIES})
 | 
				
			||||||
endif(Tcmalloc_FOUND)
 | 
					endif(Tcmalloc_FOUND)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
install(TARGETS riscv riscv-sim
 | 
					install(TARGETS tgfs tgfs-sim
 | 
				
			||||||
  EXPORT ${PROJECT_NAME}Targets            # for downstream dependencies
 | 
					  EXPORT ${PROJECT_NAME}Targets            # for downstream dependencies
 | 
				
			||||||
  ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} COMPONENT libs   # static lib
 | 
					  ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} COMPONENT libs   # static lib
 | 
				
			||||||
  RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} COMPONENT libs   # binaries
 | 
					  RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} COMPONENT libs   # binaries
 | 
				
			||||||
 
 | 
				
			|||||||
 Submodule gen_input/CoreDSL-Instruction-Set-Description updated: 3bb3763e92...998444fba8
									
								
							@@ -4,25 +4,24 @@ import "CoreDSL-Instruction-Set-Description/RVC.core_desc"
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
Core TGF_B provides RV32I {
 | 
					Core TGF_B provides RV32I {
 | 
				
			||||||
	constants {
 | 
						constants {
 | 
				
			||||||
        XLEN:=32;
 | 
					        unsigned XLEN=32;
 | 
				
			||||||
        PCLEN:=32;
 | 
					        unsigned PCLEN=32;
 | 
				
			||||||
        // definitions for the architecture wrapper
 | 
					        // definitions for the architecture wrapper
 | 
				
			||||||
        //          XL    ZYXWVUTSRQPONMLKJIHGFEDCBA
 | 
					        //          XL    ZYXWVUTSRQPONMLKJIHGFEDCBA
 | 
				
			||||||
        MISA_VAL:=0b01000000000000000000000100000000;
 | 
					        unsigned MISA_VAL=0b01000000000000000000000100000000;
 | 
				
			||||||
        PGSIZE := 0x1000; //1 << 12;
 | 
					        unsigned PGSIZE = 0x1000; //1 << 12;
 | 
				
			||||||
        PGMASK := 0xfff; //PGSIZE-1
 | 
					        unsigned PGMASK = 0xfff; //PGSIZE-1
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Core TGF_C provides RV32I, RV32M, RV32IC {
 | 
					Core TGF_C provides RV32I, RV32M, RV32IC {
 | 
				
			||||||
    constants {
 | 
					    constants {
 | 
				
			||||||
        XLEN:=32;
 | 
					        unsigned XLEN=32;
 | 
				
			||||||
        PCLEN:=32;
 | 
					        unsigned PCLEN=32;
 | 
				
			||||||
        MUL_LEN:=64;
 | 
					 | 
				
			||||||
        // definitions for the architecture wrapper
 | 
					        // definitions for the architecture wrapper
 | 
				
			||||||
        //          XL    ZYXWVUTSRQPONMLKJIHGFEDCBA
 | 
					        //          XL    ZYXWVUTSRQPONMLKJIHGFEDCBA
 | 
				
			||||||
        MISA_VAL:=0b01000000000000000001000100000100;
 | 
					        unsigned MISA_VAL=0b01000000000000000001000100000100;
 | 
				
			||||||
        PGSIZE := 0x1000; //1 << 12;
 | 
					        unsigned PGSIZE = 0x1000; //1 << 12;
 | 
				
			||||||
        PGMASK := 0xfff; //PGSIZE-1
 | 
					        unsigned PGMASK = 0xfff; //PGSIZE-1
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@@ -1,74 +0,0 @@
 | 
				
			|||||||
import "RV32I.core_desc"
 | 
					 | 
				
			||||||
import "RV64I.core_desc"
 | 
					 | 
				
			||||||
import "RVM.core_desc"
 | 
					 | 
				
			||||||
import "RVA.core_desc"
 | 
					 | 
				
			||||||
import "RVC.core_desc"
 | 
					 | 
				
			||||||
import "RVF.core_desc"
 | 
					 | 
				
			||||||
import "RVD.core_desc"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Core MNRV32 provides RV32I, RV32IC {
 | 
					 | 
				
			||||||
    constants {
 | 
					 | 
				
			||||||
        XLEN:=32;
 | 
					 | 
				
			||||||
        PCLEN:=32;
 | 
					 | 
				
			||||||
        // definitions for the architecture wrapper
 | 
					 | 
				
			||||||
        //          XL    ZYXWVUTSRQPONMLKJIHGFEDCBA
 | 
					 | 
				
			||||||
        MISA_VAL:=0b01000000000101000001000100000101;
 | 
					 | 
				
			||||||
        PGSIZE := 0x1000; //1 << 12;
 | 
					 | 
				
			||||||
        PGMASK := 0xfff; //PGSIZE-1
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Core RV32IMAC provides RV32I, RV32M, RV32A, RV32IC {
 | 
					 | 
				
			||||||
    constants {
 | 
					 | 
				
			||||||
        XLEN:=32;
 | 
					 | 
				
			||||||
        PCLEN:=32;
 | 
					 | 
				
			||||||
        MUL_LEN:=64;
 | 
					 | 
				
			||||||
        // definitions for the architecture wrapper
 | 
					 | 
				
			||||||
        //          XL    ZYXWVUTSRQPONMLKJIHGFEDCBA
 | 
					 | 
				
			||||||
        MISA_VAL:=0b01000000000101000001000100000101;
 | 
					 | 
				
			||||||
        PGSIZE := 0x1000; //1 << 12;
 | 
					 | 
				
			||||||
        PGMASK := 0xfff; //PGSIZE-1
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Core RV32GC provides RV32I, RV32M, RV32A, RV32F, RV32D, RV32IC, RV32FC, RV32DC {
 | 
					 | 
				
			||||||
    constants {
 | 
					 | 
				
			||||||
        XLEN:=32;
 | 
					 | 
				
			||||||
        FLEN:=64;
 | 
					 | 
				
			||||||
        PCLEN:=32;
 | 
					 | 
				
			||||||
        MUL_LEN:=64;
 | 
					 | 
				
			||||||
        // definitions for the architecture wrapper
 | 
					 | 
				
			||||||
        //          XL    ZYXWVUTSRQPONMLKJIHGFEDCBA
 | 
					 | 
				
			||||||
        MISA_VAL:=0b01000000000101000001000100101101;
 | 
					 | 
				
			||||||
        PGSIZE := 0x1000; //1 << 12;
 | 
					 | 
				
			||||||
        PGMASK := 0xfff; //PGSIZE-1
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Core RV64I provides RV64I {
 | 
					 | 
				
			||||||
    constants {
 | 
					 | 
				
			||||||
        XLEN:=64;
 | 
					 | 
				
			||||||
        PCLEN:=64;
 | 
					 | 
				
			||||||
        // definitions for the architecture wrapper
 | 
					 | 
				
			||||||
        //          XL    ZYXWVUTSRQPONMLKJIHGFEDCBA
 | 
					 | 
				
			||||||
        MISA_VAL:=0b10000000000001000000000100000000;
 | 
					 | 
				
			||||||
        PGSIZE := 0x1000; //1 << 12;
 | 
					 | 
				
			||||||
        PGMASK := 0xfff; //PGSIZE-1
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Core RV64GC provides RV64I, RV64M, RV64A, RV64F, RV64D, RV32FC, RV32DC, RV64IC {
 | 
					 | 
				
			||||||
    constants {
 | 
					 | 
				
			||||||
        XLEN:=64;
 | 
					 | 
				
			||||||
        FLEN:=64;
 | 
					 | 
				
			||||||
        PCLEN:=64;
 | 
					 | 
				
			||||||
        MUL_LEN:=128;
 | 
					 | 
				
			||||||
        // definitions for the architecture wrapper
 | 
					 | 
				
			||||||
        //          XL    ZYXWVUTSRQPONMLKJIHGFEDCBA
 | 
					 | 
				
			||||||
        MISA_VAL:=0b01000000000101000001000100101101;
 | 
					 | 
				
			||||||
        PGSIZE := 0x1000; //1 << 12;
 | 
					 | 
				
			||||||
        PGMASK := 0xfff; //PGSIZE-1
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
@@ -1,5 +1,5 @@
 | 
				
			|||||||
/*******************************************************************************
 | 
					/*******************************************************************************
 | 
				
			||||||
 * Copyright (C) 2017, 2018 MINRES Technologies GmbH
 | 
					 * Copyright (C) 2017 - 2020 MINRES Technologies GmbH
 | 
				
			||||||
 * All rights reserved.
 | 
					 * All rights reserved.
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 * Redistribution and use in source and binary forms, with or without
 | 
					 * Redistribution and use in source and binary forms, with or without
 | 
				
			||||||
@@ -30,42 +30,11 @@
 | 
				
			|||||||
 *
 | 
					 *
 | 
				
			||||||
 *******************************************************************************/
 | 
					 *******************************************************************************/
 | 
				
			||||||
<% 
 | 
					<% 
 | 
				
			||||||
import com.minres.coredsl.coreDsl.Register
 | 
					def getRegisterSizes(){
 | 
				
			||||||
import com.minres.coredsl.coreDsl.RegisterFile
 | 
						def regs = registers.collect{it.size}
 | 
				
			||||||
import com.minres.coredsl.coreDsl.RegisterAlias
 | 
						regs[-1]=64 // correct for NEXT_PC
 | 
				
			||||||
def getOriginalName(reg){
 | 
						regs+=[32, 32, 32, 32, 64] // append TRAP_STATE, PENDING_TRAP, MACHINE_STATE, LAST_BRANCH, ICOUNT
 | 
				
			||||||
    if( reg.original instanceof RegisterFile) {
 | 
					    return regs
 | 
				
			||||||
    	if( reg.index != null ) {
 | 
					 | 
				
			||||||
        	return reg.original.name+generator.generateHostCode(reg.index)
 | 
					 | 
				
			||||||
        } else {
 | 
					 | 
				
			||||||
        	return reg.original.name
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    } else if(reg.original instanceof Register){
 | 
					 | 
				
			||||||
        return reg.original.name
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
def getRegisterNames(){
 | 
					 | 
				
			||||||
	def regNames = []
 | 
					 | 
				
			||||||
 	allRegs.each { reg -> 
 | 
					 | 
				
			||||||
		if( reg instanceof RegisterFile) {
 | 
					 | 
				
			||||||
			(reg.range.right..reg.range.left).each{
 | 
					 | 
				
			||||||
    			regNames+=reg.name.toLowerCase()+it
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
        } else if(reg instanceof Register){
 | 
					 | 
				
			||||||
    		regNames+=reg.name.toLowerCase()
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    return regNames
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
def getRegisterAliasNames(){
 | 
					 | 
				
			||||||
	def regMap = allRegs.findAll{it instanceof RegisterAlias }.collectEntries {[getOriginalName(it), it.name]}
 | 
					 | 
				
			||||||
 	return allRegs.findAll{it instanceof Register || it instanceof RegisterFile}.collect{reg ->
 | 
					 | 
				
			||||||
		if( reg instanceof RegisterFile) {
 | 
					 | 
				
			||||||
			return (reg.range.right..reg.range.left).collect{ (regMap[reg.name]?:regMap[reg.name+it]?:reg.name.toLowerCase()+it).toLowerCase() }
 | 
					 | 
				
			||||||
        } else if(reg instanceof Register){
 | 
					 | 
				
			||||||
    		regMap[reg.name]?:reg.name.toLowerCase()
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 	}.flatten()
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
%>
 | 
					%>
 | 
				
			||||||
#include "util/ities.h"
 | 
					#include "util/ities.h"
 | 
				
			||||||
@@ -77,10 +46,10 @@ def getRegisterAliasNames(){
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
using namespace iss::arch;
 | 
					using namespace iss::arch;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
constexpr std::array<const char*, ${getRegisterNames().size}>    iss::arch::traits<iss::arch::${coreDef.name.toLowerCase()}>::reg_names;
 | 
					constexpr std::array<const char*, ${registers.size}>    iss::arch::traits<iss::arch::${coreDef.name.toLowerCase()}>::reg_names;
 | 
				
			||||||
constexpr std::array<const char*, ${getRegisterAliasNames().size}>    iss::arch::traits<iss::arch::${coreDef.name.toLowerCase()}>::reg_aliases;
 | 
					constexpr std::array<const char*, ${registers.size}>    iss::arch::traits<iss::arch::${coreDef.name.toLowerCase()}>::reg_aliases;
 | 
				
			||||||
constexpr std::array<const uint32_t, ${regSizes.size}> iss::arch::traits<iss::arch::${coreDef.name.toLowerCase()}>::reg_bit_widths;
 | 
					constexpr std::array<const uint32_t, ${getRegisterSizes().size}> iss::arch::traits<iss::arch::${coreDef.name.toLowerCase()}>::reg_bit_widths;
 | 
				
			||||||
constexpr std::array<const uint32_t, ${regOffsets.size}> iss::arch::traits<iss::arch::${coreDef.name.toLowerCase()}>::reg_byte_offsets;
 | 
					constexpr std::array<const uint32_t, ${getRegisterSizes().size}> iss::arch::traits<iss::arch::${coreDef.name.toLowerCase()}>::reg_byte_offsets;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
${coreDef.name.toLowerCase()}::${coreDef.name.toLowerCase()}() {
 | 
					${coreDef.name.toLowerCase()}::${coreDef.name.toLowerCase()}() {
 | 
				
			||||||
    reg.icount = 0;
 | 
					    reg.icount = 0;
 | 
				
			||||||
@@ -1,5 +1,5 @@
 | 
				
			|||||||
/*******************************************************************************
 | 
					/*******************************************************************************
 | 
				
			||||||
 * Copyright (C) 2017, 2018 MINRES Technologies GmbH
 | 
					 * Copyright (C) 2017 - 2020 MINRES Technologies GmbH
 | 
				
			||||||
 * All rights reserved.
 | 
					 * All rights reserved.
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 * Redistribution and use in source and binary forms, with or without
 | 
					 * Redistribution and use in source and binary forms, with or without
 | 
				
			||||||
@@ -29,47 +29,22 @@
 | 
				
			|||||||
 * POSSIBILITY OF SUCH DAMAGE.
 | 
					 * POSSIBILITY OF SUCH DAMAGE.
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 *******************************************************************************/
 | 
					 *******************************************************************************/
 | 
				
			||||||
 | 
					 | 
				
			||||||
<% 
 | 
					<% 
 | 
				
			||||||
import com.minres.coredsl.coreDsl.Register
 | 
					def getRegisterSizes(){
 | 
				
			||||||
import com.minres.coredsl.coreDsl.RegisterFile
 | 
						def regs = registers.collect{it.size}
 | 
				
			||||||
import com.minres.coredsl.coreDsl.RegisterAlias
 | 
						regs[-1]=pc.size // correct for NEXT_PC
 | 
				
			||||||
def getTypeSize(size){
 | 
						regs+=[32, 32, 32, 32, 64] // append TRAP_STATE, PENDING_TRAP, MACHINE_STATE, LAST_BRANCH, ICOUNT
 | 
				
			||||||
	if(size > 32) 64 else if(size > 16) 32 else if(size > 8) 16 else 8
 | 
					    return regs
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
def getOriginalName(reg){
 | 
					def getRegisterOffsets(){
 | 
				
			||||||
    if( reg.original instanceof RegisterFile) {
 | 
						def regs = registers.collect{it.offset}
 | 
				
			||||||
    	if( reg.index != null ) {
 | 
						def offs= regs[-1]
 | 
				
			||||||
        	return reg.original.name+generator.generateHostCode(reg.index)
 | 
						 // append TRAP_STATE, PENDING_TRAP, MACHINE_STATE, LAST_BRANCH, ICOUNT offsets starting with NEXT_PC size
 | 
				
			||||||
        } else {
 | 
						[pc.size/8, 4, 4, 4, 4].each{ sz ->
 | 
				
			||||||
        	return reg.original.name
 | 
							regs+=offs+sz
 | 
				
			||||||
 | 
							offs+=sz
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
    } else if(reg.original instanceof Register){
 | 
					    return regs
 | 
				
			||||||
        return reg.original.name
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
def getRegisterNames(){
 | 
					 | 
				
			||||||
	def regNames = []
 | 
					 | 
				
			||||||
 	allRegs.each { reg -> 
 | 
					 | 
				
			||||||
		if( reg instanceof RegisterFile) {
 | 
					 | 
				
			||||||
			(reg.range.right..reg.range.left).each{
 | 
					 | 
				
			||||||
    			regNames+=reg.name.toLowerCase()+it
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
        } else if(reg instanceof Register){
 | 
					 | 
				
			||||||
    		regNames+=reg.name.toLowerCase()
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    return regNames
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
def getRegisterAliasNames(){
 | 
					 | 
				
			||||||
	def regMap = allRegs.findAll{it instanceof RegisterAlias }.collectEntries {[getOriginalName(it), it.name]}
 | 
					 | 
				
			||||||
 	return allRegs.findAll{it instanceof Register || it instanceof RegisterFile}.collect{reg ->
 | 
					 | 
				
			||||||
		if( reg instanceof RegisterFile) {
 | 
					 | 
				
			||||||
			return (reg.range.right..reg.range.left).collect{ (regMap[reg.name]?:regMap[reg.name+it]?:reg.name.toLowerCase()+it).toLowerCase() }
 | 
					 | 
				
			||||||
        } else if(reg instanceof Register){
 | 
					 | 
				
			||||||
    		regMap[reg.name]?:reg.name.toLowerCase()
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 	}.flatten()
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
%>
 | 
					%>
 | 
				
			||||||
#ifndef _${coreDef.name.toUpperCase()}_H_
 | 
					#ifndef _${coreDef.name.toUpperCase()}_H_
 | 
				
			||||||
@@ -89,41 +64,29 @@ template <> struct traits<${coreDef.name.toLowerCase()}> {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	constexpr static char const* const core_type = "${coreDef.name}";
 | 
						constexpr static char const* const core_type = "${coreDef.name}";
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
  	static constexpr std::array<const char*, ${getRegisterNames().size}> reg_names{
 | 
					  	static constexpr std::array<const char*, ${registers.size}> reg_names{
 | 
				
			||||||
 		{"${getRegisterNames().join("\", \"")}"}};
 | 
					 		{"${registers.collect{it.name}.join('", "')}"}};
 | 
				
			||||||
 
 | 
					 
 | 
				
			||||||
  	static constexpr std::array<const char*, ${getRegisterAliasNames().size}> reg_aliases{
 | 
					  	static constexpr std::array<const char*, ${registers.size}> reg_aliases{
 | 
				
			||||||
 		{"${getRegisterAliasNames().join("\", \"")}"}};
 | 
					 		{"${registers.collect{it.alias}.join('", "')}"}};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    enum constants {${coreDef.constants.collect{c -> c.name+"="+c.value}.join(', ')}};
 | 
					    enum constants {${constants.collect{c -> c.name+"="+c.value}.join(', ')}};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    constexpr static unsigned FP_REGS_SIZE = ${coreDef.constants.find {it.name=='FLEN'}?.value?:0};
 | 
					    constexpr static unsigned FP_REGS_SIZE = ${constants.find {it.name=='FLEN'}?.value?:0};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    enum reg_e {<%
 | 
					    enum reg_e {<%
 | 
				
			||||||
     	allRegs.each { reg -> 
 | 
					     	registers.each { reg -> %>
 | 
				
			||||||
    		if( reg instanceof RegisterFile) {
 | 
					 | 
				
			||||||
    			(reg.range.right..reg.range.left).each{%>
 | 
					 | 
				
			||||||
        ${reg.name}${it},<%
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
            } else if(reg instanceof Register){ %>
 | 
					 | 
				
			||||||
        ${reg.name},<%  
 | 
					        ${reg.name},<%  
 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
        }%>
 | 
					        }%>
 | 
				
			||||||
        NUM_REGS,
 | 
					 | 
				
			||||||
        NEXT_${pc.name}=NUM_REGS,
 | 
					        NEXT_${pc.name}=NUM_REGS,
 | 
				
			||||||
        TRAP_STATE,
 | 
					        TRAP_STATE,
 | 
				
			||||||
        PENDING_TRAP,
 | 
					        PENDING_TRAP,
 | 
				
			||||||
        MACHINE_STATE,
 | 
					        MACHINE_STATE,
 | 
				
			||||||
        LAST_BRANCH,
 | 
					        LAST_BRANCH,
 | 
				
			||||||
        ICOUNT<% 
 | 
					        ICOUNT
 | 
				
			||||||
     	allRegs.each { reg -> 
 | 
					 | 
				
			||||||
    		if(reg instanceof RegisterAlias){ def aliasname=getOriginalName(reg)%>,
 | 
					 | 
				
			||||||
        ${reg.name} = ${aliasname}<%
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
        }%>
 | 
					 | 
				
			||||||
    };
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    using reg_t = uint${regDataWidth}_t;
 | 
					    using reg_t = uint${addrDataWidth}_t;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    using addr_t = uint${addrDataWidth}_t;
 | 
					    using addr_t = uint${addrDataWidth}_t;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -133,17 +96,17 @@ template <> struct traits<${coreDef.name.toLowerCase()}> {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    using phys_addr_t = iss::typed_addr_t<iss::address_type::PHYSICAL>;
 | 
					    using phys_addr_t = iss::typed_addr_t<iss::address_type::PHYSICAL>;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 	static constexpr std::array<const uint32_t, ${regSizes.size}> reg_bit_widths{
 | 
					 	static constexpr std::array<const uint32_t, ${getRegisterSizes().size}> reg_bit_widths{
 | 
				
			||||||
 		{${regSizes.join(",")}}};
 | 
					 		{${getRegisterSizes().join(',')}}};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    static constexpr std::array<const uint32_t, ${regOffsets.size}> reg_byte_offsets{
 | 
					    static constexpr std::array<const uint32_t, ${getRegisterOffsets().size}> reg_byte_offsets{
 | 
				
			||||||
    	{${regOffsets.join(",")}}};
 | 
					 		{${getRegisterOffsets().join(',')}}};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    static const uint64_t addr_mask = (reg_t(1) << (XLEN - 1)) | ((reg_t(1) << (XLEN - 1)) - 1);
 | 
					    static const uint64_t addr_mask = (reg_t(1) << (XLEN - 1)) | ((reg_t(1) << (XLEN - 1)) - 1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    enum sreg_flag_e { FLAGS };
 | 
					    enum sreg_flag_e { FLAGS };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    enum mem_type_e { ${allSpaces.collect{s -> s.name}.join(', ')} };
 | 
					    enum mem_type_e { ${spaces.collect{it.name}.join(', ')} };
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct ${coreDef.name.toLowerCase()}: public arch_if {
 | 
					struct ${coreDef.name.toLowerCase()}: public arch_if {
 | 
				
			||||||
@@ -190,16 +153,10 @@ struct ${coreDef.name.toLowerCase()}: public arch_if {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
protected:
 | 
					protected:
 | 
				
			||||||
    struct ${coreDef.name}_regs {<%
 | 
					    struct ${coreDef.name}_regs {<%
 | 
				
			||||||
     	allRegs.each { reg -> 
 | 
					     	registers.each { reg -> if(reg.size>0) {%> 
 | 
				
			||||||
    		if( reg instanceof RegisterFile) {
 | 
					        uint${reg.size}_t ${reg.name} = 0;<%
 | 
				
			||||||
    			(reg.range.right..reg.range.left).each{%>
 | 
					        }}%>
 | 
				
			||||||
        uint${generator.getSize(reg)}_t ${reg.name}${it} = 0;<%
 | 
					        uint${pc.size}_t NEXT_${pc.name} = 0;
 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
            } else if(reg instanceof Register){ %>
 | 
					 | 
				
			||||||
        uint${generator.getSize(reg)}_t ${reg.name} = 0;<%
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
        }%>
 | 
					 | 
				
			||||||
        uint${generator.getSize(pc)}_t NEXT_${pc.name} = 0;
 | 
					 | 
				
			||||||
        uint32_t trap_state = 0, pending_trap = 0, machine_state = 0, last_branch = 0;
 | 
					        uint32_t trap_state = 0, pending_trap = 0, machine_state = 0, last_branch = 0;
 | 
				
			||||||
        uint64_t icount = 0;
 | 
					        uint64_t icount = 0;
 | 
				
			||||||
    } reg;
 | 
					    } reg;
 | 
				
			||||||
@@ -208,10 +165,10 @@ protected:
 | 
				
			|||||||
    
 | 
					    
 | 
				
			||||||
    uint64_t interrupt_sim=0;
 | 
					    uint64_t interrupt_sim=0;
 | 
				
			||||||
<%
 | 
					<%
 | 
				
			||||||
def fcsr = allRegs.find {it.name=='FCSR'}
 | 
					def fcsr = registers.find {it.name=='FCSR'}
 | 
				
			||||||
if(fcsr != null) {%>
 | 
					if(fcsr != null) {%>
 | 
				
			||||||
	uint${generator.getSize(fcsr)}_t get_fcsr(){return reg.FCSR;}
 | 
						uint${fcsr.size}_t get_fcsr(){return reg.FCSR;}
 | 
				
			||||||
	void set_fcsr(uint${generator.getSize(fcsr)}_t val){reg.FCSR = val;}		
 | 
						void set_fcsr(uint${fcsr.size}_t val){reg.FCSR = val;}		
 | 
				
			||||||
<%} else { %>
 | 
					<%} else { %>
 | 
				
			||||||
	uint32_t get_fcsr(){return 0;}
 | 
						uint32_t get_fcsr(){return 0;}
 | 
				
			||||||
	void set_fcsr(uint32_t val){}
 | 
						void set_fcsr(uint32_t val){}
 | 
				
			||||||
@@ -56,13 +56,14 @@ using namespace iss::debugger;
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
template <typename ARCH> class vm_impl : public iss::interp::vm_base<ARCH> {
 | 
					template <typename ARCH> class vm_impl : public iss::interp::vm_base<ARCH> {
 | 
				
			||||||
public:
 | 
					public:
 | 
				
			||||||
 | 
					    using traits = arch::traits<ARCH>;
 | 
				
			||||||
    using super       = typename iss::interp::vm_base<ARCH>;
 | 
					    using super       = typename iss::interp::vm_base<ARCH>;
 | 
				
			||||||
    using virt_addr_t = typename super::virt_addr_t;
 | 
					    using virt_addr_t = typename super::virt_addr_t;
 | 
				
			||||||
    using phys_addr_t = typename super::phys_addr_t;
 | 
					    using phys_addr_t = typename super::phys_addr_t;
 | 
				
			||||||
    using code_word_t = typename super::code_word_t;
 | 
					    using code_word_t = typename super::code_word_t;
 | 
				
			||||||
    using addr_t      = typename super::addr_t;
 | 
					    using addr_t      = typename super::addr_t;
 | 
				
			||||||
    using reg_t = typename traits<ARCH>::reg_t;
 | 
					    using reg_t       = typename traits::reg_t;
 | 
				
			||||||
    using iss::interp::vm_base<ARCH>::get_reg;
 | 
					    using mem_type_e  = typename traits::mem_type_e;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    vm_impl();
 | 
					    vm_impl();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -82,7 +83,7 @@ protected:
 | 
				
			|||||||
    using compile_ret_t = virt_addr_t;
 | 
					    using compile_ret_t = virt_addr_t;
 | 
				
			||||||
    using compile_func = compile_ret_t (this_class::*)(virt_addr_t &pc, code_word_t instr);
 | 
					    using compile_func = compile_ret_t (this_class::*)(virt_addr_t &pc, code_word_t instr);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    inline const char *name(size_t index){return traits<ARCH>::reg_aliases.at(index);}
 | 
					    inline const char *name(size_t index){return traits::reg_aliases.at(index);}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    virt_addr_t execute_inst(virt_addr_t start, std::function<bool(void)> pred) override;
 | 
					    virt_addr_t execute_inst(virt_addr_t start, std::function<bool(void)> pred) override;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -138,23 +139,31 @@ protected:
 | 
				
			|||||||
        return lut_val;
 | 
					        return lut_val;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    void raise_trap(uint16_t trap_id, uint16_t cause){
 | 
					    void raise(uint16_t trap_id, uint16_t cause){
 | 
				
			||||||
        auto trap_val =  0x80ULL << 24 | (cause << 16) | trap_id;
 | 
					        auto trap_val =  0x80ULL << 24 | (cause << 16) | trap_id;
 | 
				
			||||||
        this->template get_reg<uint32_t>(arch::traits<ARCH>::TRAP_STATE) = trap_val;
 | 
					        this->template get_reg<uint32_t>(traits::TRAP_STATE) = trap_val;
 | 
				
			||||||
        this->template get_reg<uint32_t>(arch::traits<ARCH>::NEXT_PC) = std::numeric_limits<uint32_t>::max();
 | 
					        this->template get_reg<uint32_t>(traits::NEXT_PC) = std::numeric_limits<uint32_t>::max();
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    void leave_trap(unsigned lvl){
 | 
					    void leave(unsigned lvl){
 | 
				
			||||||
        this->core.leave_trap(lvl);
 | 
					        this->core.leave_trap(lvl);
 | 
				
			||||||
        auto pc_val = super::template read_mem<reg_t>(traits<ARCH>::CSR, (lvl << 8) + 0x41);
 | 
					        auto pc_val = super::template read_mem<reg_t>(traits::CSR, (lvl << 8) + 0x41);
 | 
				
			||||||
        this->template get_reg<reg_t>(arch::traits<ARCH>::NEXT_PC) = pc_val;
 | 
					        this->template get_reg<reg_t>(traits::NEXT_PC) = pc_val;
 | 
				
			||||||
        this->template get_reg<uint32_t>(arch::traits<ARCH>::LAST_BRANCH) = std::numeric_limits<uint32_t>::max();
 | 
					        this->template get_reg<uint32_t>(traits::LAST_BRANCH) = std::numeric_limits<uint32_t>::max();
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    void wait(unsigned type){
 | 
					    void wait(unsigned type){
 | 
				
			||||||
        this->core.wait_until(type);
 | 
					        this->core.wait_until(type);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    inline uint8_t readSpace1(typename super::mem_type_e space, uint64_t addr){return super::template read_mem<uint8_t>(space, addr);}
 | 
				
			||||||
 | 
					    inline uint16_t readSpace2(typename super::mem_type_e space, uint64_t addr){return super::template read_mem<uint16_t>(space, addr);}
 | 
				
			||||||
 | 
					    inline uint32_t readSpace4(typename super::mem_type_e space, uint64_t addr){return super::template read_mem<uint32_t>(space, addr);}
 | 
				
			||||||
 | 
					    inline uint64_t readSpace8(typename super::mem_type_e space, uint64_t addr){return super::template read_mem<uint64_t>(space, addr);}
 | 
				
			||||||
 | 
					    inline void writeSpace1(typename super::mem_type_e space, uint64_t addr, uint8_t data){super::write_mem(space, addr, data);}
 | 
				
			||||||
 | 
					    inline void writeSpace2(typename super::mem_type_e space, uint64_t addr, uint16_t data){super::write_mem(space, addr, data);}
 | 
				
			||||||
 | 
					    inline void writeSpace4(typename super::mem_type_e space, uint64_t addr, uint32_t data){super::write_mem(space, addr, data);}
 | 
				
			||||||
 | 
					    inline void writeSpace8(typename super::mem_type_e space, uint64_t addr, uint64_t data){super::write_mem(space, addr, data);}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
private:
 | 
					private:
 | 
				
			||||||
    /****************************************************************************
 | 
					    /****************************************************************************
 | 
				
			||||||
@@ -170,13 +179,38 @@ private:
 | 
				
			|||||||
    const std::array<InstructionDesriptor, ${instructions.size}> instr_descr = {{
 | 
					    const std::array<InstructionDesriptor, ${instructions.size}> instr_descr = {{
 | 
				
			||||||
         /* entries are: size, valid value, valid mask, function ptr */<%instructions.each{instr -> %>
 | 
					         /* entries are: size, valid value, valid mask, function ptr */<%instructions.each{instr -> %>
 | 
				
			||||||
        /* instruction ${instr.instruction.name} */
 | 
					        /* instruction ${instr.instruction.name} */
 | 
				
			||||||
        {${instr.length}, ${instr.value}, ${instr.mask}, &this_class::__${generator.functionName(instr.name)}},<%}%>
 | 
					        {${instr.length}, ${instr.encoding}, ${instr.mask}, &this_class::__${generator.functionName(instr.name)}},<%}%>
 | 
				
			||||||
    }};
 | 
					    }};
 | 
				
			||||||
 
 | 
					 
 | 
				
			||||||
    /* instruction definitions */<%instructions.eachWithIndex{instr, idx -> %>
 | 
					    /* instruction definitions */<%instructions.eachWithIndex{instr, idx -> %>
 | 
				
			||||||
    /* instruction ${idx}: ${instr.name} */
 | 
					    /* instruction ${idx}: ${instr.name} */
 | 
				
			||||||
    compile_ret_t __${generator.functionName(instr.name)}(virt_addr_t& pc, code_word_t instr){<%instr.code.eachLine{%>
 | 
					    compile_ret_t __${generator.functionName(instr.name)}(virt_addr_t& pc, code_word_t instr){
 | 
				
			||||||
        ${it}<%}%>
 | 
					        // pre execution stuff
 | 
				
			||||||
 | 
					        this->do_sync(PRE_SYNC, ${idx});
 | 
				
			||||||
 | 
					        <%instr.fields.eachLine{%>${it}
 | 
				
			||||||
 | 
					        <%}%>if(this->disass_enabled){
 | 
				
			||||||
 | 
					            /* generate console output when executing the command */
 | 
				
			||||||
 | 
					            <%instr.disass.eachLine{%>${it}
 | 
				
			||||||
 | 
					            <%}%>
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        // prepare execution
 | 
				
			||||||
 | 
					        uint${addrDataWidth}_t* X = reinterpret_cast<uint${addrDataWidth}_t*>(this->regs_base_ptr+arch::traits<ARCH>::reg_byte_offsets[arch::traits<ARCH>::X0]);
 | 
				
			||||||
 | 
					        uint${addrDataWidth}_t* PC = reinterpret_cast<uint${addrDataWidth}_t*>(this->regs_base_ptr+arch::traits<ARCH>::reg_byte_offsets[arch::traits<ARCH>::PC]);
 | 
				
			||||||
 | 
					        // execute instruction
 | 
				
			||||||
 | 
					        <%instr.behavior.eachLine{%>${it}
 | 
				
			||||||
 | 
					        <%}%>// post execution stuff<% if(instr.modifiesPC) { %>
 | 
				
			||||||
 | 
					        super::template get_reg<reg_t>(arch::traits<ARCH>::NEXT_PC) = super::template get_reg<reg_t>(arch::traits<ARCH>::PC);<% } else { %>
 | 
				
			||||||
 | 
					        super::template get_reg<reg_t>(arch::traits<ARCH>::NEXT_PC) = pc.val + ${instr.length/8};<% } %>
 | 
				
			||||||
 | 
					        if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, ${idx});
 | 
				
			||||||
 | 
					        auto& trap_state = super::template get_reg<uint32_t>(arch::traits<ARCH>::TRAP_STATE);
 | 
				
			||||||
 | 
					        // trap check
 | 
				
			||||||
 | 
					        if(trap_state!=0){
 | 
				
			||||||
 | 
					            auto& last_br = super::template get_reg<uint32_t>(arch::traits<ARCH>::LAST_BRANCH);
 | 
				
			||||||
 | 
					            last_br = std::numeric_limits<uint32_t>::max();
 | 
				
			||||||
 | 
					            super::core.enter_trap(trap_state, pc.val);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        pc.val=super::template get_reg<reg_t>(arch::traits<ARCH>::NEXT_PC);
 | 
				
			||||||
 | 
					        return pc;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    <%}%>
 | 
					    <%}%>
 | 
				
			||||||
    /****************************************************************************
 | 
					    /****************************************************************************
 | 
				
			||||||
@@ -212,7 +246,7 @@ template <typename ARCH>
 | 
				
			|||||||
typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(virt_addr_t start, std::function<bool(void)> pred) {
 | 
					typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(virt_addr_t start, std::function<bool(void)> pred) {
 | 
				
			||||||
    // we fetch at max 4 byte, alignment is 2
 | 
					    // we fetch at max 4 byte, alignment is 2
 | 
				
			||||||
    enum {TRAP_ID=1<<16};
 | 
					    enum {TRAP_ID=1<<16};
 | 
				
			||||||
    const typename traits<ARCH>::addr_t upper_bits = ~traits<ARCH>::PGMASK;
 | 
					    const typename traits::addr_t upper_bits = ~traits::PGMASK;
 | 
				
			||||||
    code_word_t insn = 0;
 | 
					    code_word_t insn = 0;
 | 
				
			||||||
    auto *const data = (uint8_t *)&insn;
 | 
					    auto *const data = (uint8_t *)&insn;
 | 
				
			||||||
    auto pc=start;
 | 
					    auto pc=start;
 | 
				
			||||||
@@ -302,7 +302,7 @@ public:
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        void write_mstatus(T val) {
 | 
					        void write_mstatus(T val) {
 | 
				
			||||||
            auto mask = get_mask();
 | 
					            auto mask = get_mask();
 | 
				
			||||||
            auto new_val = (mstatus.backing.val & ~mask) | (val & mask);
 | 
					            auto new_val = (mstatus.st.value & ~mask) | (val & mask);
 | 
				
			||||||
            mstatus = new_val;
 | 
					            mstatus = new_val;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,5 +1,5 @@
 | 
				
			|||||||
/*******************************************************************************
 | 
					/*******************************************************************************
 | 
				
			||||||
 * Copyright (C) 2017, 2018 MINRES Technologies GmbH
 | 
					 * Copyright (C) 2017 - 2020 MINRES Technologies GmbH
 | 
				
			||||||
 * All rights reserved.
 | 
					 * All rights reserved.
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 * Redistribution and use in source and binary forms, with or without
 | 
					 * Redistribution and use in source and binary forms, with or without
 | 
				
			||||||
@@ -30,7 +30,6 @@
 | 
				
			|||||||
 *
 | 
					 *
 | 
				
			||||||
 *******************************************************************************/
 | 
					 *******************************************************************************/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 | 
				
			||||||
#ifndef _TGF_C_H_
 | 
					#ifndef _TGF_C_H_
 | 
				
			||||||
#define _TGF_C_H_
 | 
					#define _TGF_C_H_
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -48,13 +47,13 @@ template <> struct traits<tgf_c> {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	constexpr static char const* const core_type = "TGF_C";
 | 
						constexpr static char const* const core_type = "TGF_C";
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
  	static constexpr std::array<const char*, 33> reg_names{
 | 
					  	static constexpr std::array<const char*, 34> reg_names{
 | 
				
			||||||
 		{"x0", "x1", "x2", "x3", "x4", "x5", "x6", "x7", "x8", "x9", "x10", "x11", "x12", "x13", "x14", "x15", "x16", "x17", "x18", "x19", "x20", "x21", "x22", "x23", "x24", "x25", "x26", "x27", "x28", "x29", "x30", "x31", "pc"}};
 | 
					 		{"X0", "X1", "X2", "X3", "X4", "X5", "X6", "X7", "X8", "X9", "X10", "X11", "X12", "X13", "X14", "X15", "X16", "X17", "X18", "X19", "X20", "X21", "X22", "X23", "X24", "X25", "X26", "X27", "X28", "X29", "X30", "X31", "PC", "NUM_REGS"}};
 | 
				
			||||||
 
 | 
					 
 | 
				
			||||||
  	static constexpr std::array<const char*, 33> reg_aliases{
 | 
					  	static constexpr std::array<const char*, 34> reg_aliases{
 | 
				
			||||||
 		{"zero", "ra", "sp", "gp", "tp", "t0", "t1", "t2", "s0", "s1", "a0", "a1", "a2", "a3", "a4", "a5", "a6", "a7", "s2", "s3", "s4", "s5", "s6", "s7", "s8", "s9", "s10", "s11", "t3", "t4", "t5", "t6", "pc"}};
 | 
					 		{"X0", "X1", "X2", "X3", "X4", "X5", "X6", "X7", "X8", "X9", "X10", "X11", "X12", "X13", "X14", "X15", "X16", "X17", "X18", "X19", "X20", "X21", "X22", "X23", "X24", "X25", "X26", "X27", "X28", "X29", "X30", "X31", "PC", "NUM_REGS"}};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    enum constants {XLEN=32, PCLEN=32, MUL_LEN=64, MISA_VAL=0b1000000000000000001000100000100, PGSIZE=0x1000, PGMASK=0xfff};
 | 
					    enum constants {XLEN=32, PCLEN=32, MISA_VAL=0b1000000000000000001000100000100, PGSIZE=0x1000, PGMASK=0xfff, CSR_SIZE=4096, fence=0, fencei=1, fencevmal=2, fencevmau=3, MUL_LEN=64};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    constexpr static unsigned FP_REGS_SIZE = 0;
 | 
					    constexpr static unsigned FP_REGS_SIZE = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -98,39 +97,7 @@ template <> struct traits<tgf_c> {
 | 
				
			|||||||
        PENDING_TRAP,
 | 
					        PENDING_TRAP,
 | 
				
			||||||
        MACHINE_STATE,
 | 
					        MACHINE_STATE,
 | 
				
			||||||
        LAST_BRANCH,
 | 
					        LAST_BRANCH,
 | 
				
			||||||
        ICOUNT,
 | 
					        ICOUNT
 | 
				
			||||||
        ZERO = X0,
 | 
					 | 
				
			||||||
        RA = X1,
 | 
					 | 
				
			||||||
        SP = X2,
 | 
					 | 
				
			||||||
        GP = X3,
 | 
					 | 
				
			||||||
        TP = X4,
 | 
					 | 
				
			||||||
        T0 = X5,
 | 
					 | 
				
			||||||
        T1 = X6,
 | 
					 | 
				
			||||||
        T2 = X7,
 | 
					 | 
				
			||||||
        S0 = X8,
 | 
					 | 
				
			||||||
        S1 = X9,
 | 
					 | 
				
			||||||
        A0 = X10,
 | 
					 | 
				
			||||||
        A1 = X11,
 | 
					 | 
				
			||||||
        A2 = X12,
 | 
					 | 
				
			||||||
        A3 = X13,
 | 
					 | 
				
			||||||
        A4 = X14,
 | 
					 | 
				
			||||||
        A5 = X15,
 | 
					 | 
				
			||||||
        A6 = X16,
 | 
					 | 
				
			||||||
        A7 = X17,
 | 
					 | 
				
			||||||
        S2 = X18,
 | 
					 | 
				
			||||||
        S3 = X19,
 | 
					 | 
				
			||||||
        S4 = X20,
 | 
					 | 
				
			||||||
        S5 = X21,
 | 
					 | 
				
			||||||
        S6 = X22,
 | 
					 | 
				
			||||||
        S7 = X23,
 | 
					 | 
				
			||||||
        S8 = X24,
 | 
					 | 
				
			||||||
        S9 = X25,
 | 
					 | 
				
			||||||
        S10 = X26,
 | 
					 | 
				
			||||||
        S11 = X27,
 | 
					 | 
				
			||||||
        T3 = X28,
 | 
					 | 
				
			||||||
        T4 = X29,
 | 
					 | 
				
			||||||
        T5 = X30,
 | 
					 | 
				
			||||||
        T6 = X31
 | 
					 | 
				
			||||||
    };
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    using reg_t = uint32_t;
 | 
					    using reg_t = uint32_t;
 | 
				
			||||||
@@ -146,8 +113,8 @@ template <> struct traits<tgf_c> {
 | 
				
			|||||||
 	static constexpr std::array<const uint32_t, 39> reg_bit_widths{
 | 
					 	static constexpr std::array<const uint32_t, 39> reg_bit_widths{
 | 
				
			||||||
 		{32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,64}};
 | 
					 		{32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,64}};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    static constexpr std::array<const uint32_t, 40> reg_byte_offsets{
 | 
					    static constexpr std::array<const uint32_t, 39> reg_byte_offsets{
 | 
				
			||||||
    	{0,4,8,12,16,20,24,28,32,36,40,44,48,52,56,60,64,68,72,76,80,84,88,92,96,100,104,108,112,116,120,124,128,132,136,140,144,148,152,160}};
 | 
					 		{0,4,8,12,16,20,24,28,32,36,40,44,48,52,56,60,64,68,72,76,80,84,88,92,96,100,104,108,112,116,120,124,128,132,136,140,144,148,152}};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    static const uint64_t addr_mask = (reg_t(1) << (XLEN - 1)) | ((reg_t(1) << (XLEN - 1)) - 1);
 | 
					    static const uint64_t addr_mask = (reg_t(1) << (XLEN - 1)) | ((reg_t(1) << (XLEN - 1)) - 1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -33,10 +33,10 @@
 | 
				
			|||||||
#ifndef _SYSC_SIFIVE_FE310_H_
 | 
					#ifndef _SYSC_SIFIVE_FE310_H_
 | 
				
			||||||
#define _SYSC_SIFIVE_FE310_H_
 | 
					#define _SYSC_SIFIVE_FE310_H_
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include <tlm/scc/scv/tlm_rec_initiator_socket.h>
 | 
					#include "scc/initiator_mixin.h"
 | 
				
			||||||
#include "tlm/scc/initiator_mixin.h"
 | 
					 | 
				
			||||||
#include "scc/traceable.h"
 | 
					#include "scc/traceable.h"
 | 
				
			||||||
#include "scc/utilities.h"
 | 
					#include "scc/utilities.h"
 | 
				
			||||||
 | 
					#include "scv4tlm/tlm_rec_initiator_socket.h"
 | 
				
			||||||
#include <cci_configuration>
 | 
					#include <cci_configuration>
 | 
				
			||||||
#include <tlm>
 | 
					#include <tlm>
 | 
				
			||||||
#include <tlm_core/tlm_1/tlm_req_rsp/tlm_1_interfaces/tlm_core_ifs.h>
 | 
					#include <tlm_core/tlm_1/tlm_req_rsp/tlm_1_interfaces/tlm_core_ifs.h>
 | 
				
			||||||
@@ -75,7 +75,7 @@ class core_wrapper;
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
class core_complex : public sc_core::sc_module, public scc::traceable {
 | 
					class core_complex : public sc_core::sc_module, public scc::traceable {
 | 
				
			||||||
public:
 | 
					public:
 | 
				
			||||||
    tlm::scc::initiator_mixin<tlm::scc::scv::tlm_rec_initiator_socket<32>> initiator{"intor"};
 | 
					    scc::initiator_mixin<scv4tlm::tlm_rec_initiator_socket<32>> initiator{"intor"};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    sc_core::sc_in<sc_core::sc_time> clk_i{"clk_i"};
 | 
					    sc_core::sc_in<sc_core::sc_time> clk_i{"clk_i"};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,5 +1,5 @@
 | 
				
			|||||||
/*******************************************************************************
 | 
					/*******************************************************************************
 | 
				
			||||||
 * Copyright (C) 2017, 2018 MINRES Technologies GmbH
 | 
					 * Copyright (C) 2017 - 2020 MINRES Technologies GmbH
 | 
				
			||||||
 * All rights reserved.
 | 
					 * All rights reserved.
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 * Redistribution and use in source and binary forms, with or without
 | 
					 * Redistribution and use in source and binary forms, with or without
 | 
				
			||||||
@@ -39,10 +39,10 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
using namespace iss::arch;
 | 
					using namespace iss::arch;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
constexpr std::array<const char*, 33>    iss::arch::traits<iss::arch::tgf_c>::reg_names;
 | 
					constexpr std::array<const char*, 34>    iss::arch::traits<iss::arch::tgf_c>::reg_names;
 | 
				
			||||||
constexpr std::array<const char*, 33>    iss::arch::traits<iss::arch::tgf_c>::reg_aliases;
 | 
					constexpr std::array<const char*, 34>    iss::arch::traits<iss::arch::tgf_c>::reg_aliases;
 | 
				
			||||||
constexpr std::array<const uint32_t, 39> iss::arch::traits<iss::arch::tgf_c>::reg_bit_widths;
 | 
					constexpr std::array<const uint32_t, 39> iss::arch::traits<iss::arch::tgf_c>::reg_bit_widths;
 | 
				
			||||||
constexpr std::array<const uint32_t, 40> iss::arch::traits<iss::arch::tgf_c>::reg_byte_offsets;
 | 
					constexpr std::array<const uint32_t, 39> iss::arch::traits<iss::arch::tgf_c>::reg_byte_offsets;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
tgf_c::tgf_c() {
 | 
					tgf_c::tgf_c() {
 | 
				
			||||||
    reg.icount = 0;
 | 
					    reg.icount = 0;
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -83,7 +83,7 @@ int main(int argc, char *argv[]) {
 | 
				
			|||||||
        ("elf", po::value<std::vector<std::string>>(), "ELF file(s) to load")
 | 
					        ("elf", po::value<std::vector<std::string>>(), "ELF file(s) to load")
 | 
				
			||||||
        ("mem,m", po::value<std::string>(), "the memory input file")
 | 
					        ("mem,m", po::value<std::string>(), "the memory input file")
 | 
				
			||||||
        ("plugin,p", po::value<std::vector<std::string>>(), "plugin to activate")
 | 
					        ("plugin,p", po::value<std::vector<std::string>>(), "plugin to activate")
 | 
				
			||||||
        ("backend", po::value<std::string>()->default_value("tcc"), "the memory input file")
 | 
					        ("backend", po::value<std::string>()->default_value("interp"), "the memory input file")
 | 
				
			||||||
        ("isa", po::value<std::string>()->default_value("tgf_c"), "isa to use for simulation");
 | 
					        ("isa", po::value<std::string>()->default_value("tgf_c"), "isa to use for simulation");
 | 
				
			||||||
    // clang-format on
 | 
					    // clang-format on
 | 
				
			||||||
    auto parsed = po::command_line_parser(argc, argv).options(desc).allow_unregistered().run();
 | 
					    auto parsed = po::command_line_parser(argc, argv).options(desc).allow_unregistered().run();
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -331,7 +331,7 @@ void core_complex::disass_output(uint64_t pc, const std::string instr_str) {
 | 
				
			|||||||
    tr_handle.record_attribute("PC", pc);
 | 
					    tr_handle.record_attribute("PC", pc);
 | 
				
			||||||
    tr_handle.record_attribute("INSTR", instr_str);
 | 
					    tr_handle.record_attribute("INSTR", instr_str);
 | 
				
			||||||
    tr_handle.record_attribute("MODE", lvl[cpu->get_mode()]);
 | 
					    tr_handle.record_attribute("MODE", lvl[cpu->get_mode()]);
 | 
				
			||||||
    tr_handle.record_attribute("MSTATUS", cpu->get_state().mstatus.backing.val);
 | 
					    tr_handle.record_attribute("MSTATUS", cpu->get_state().mstatus.st.value);
 | 
				
			||||||
    tr_handle.record_attribute("LTIME_START", quantum_keeper.get_current_time().value() / 1000);
 | 
					    tr_handle.record_attribute("LTIME_START", quantum_keeper.get_current_time().value() / 1000);
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@@ -388,7 +388,7 @@ bool core_complex::read_mem(uint64_t addr, unsigned length, uint8_t *const data,
 | 
				
			|||||||
            if (is_fetch && tr_handle.is_active()) {
 | 
					            if (is_fetch && tr_handle.is_active()) {
 | 
				
			||||||
                tr_handle.end_transaction();
 | 
					                tr_handle.end_transaction();
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            auto preExt = new tlm::scc::scv4tlm::tlm_recording_extension(tr_handle, this);
 | 
					            auto preExt = new scv4tlm::tlm_recording_extension(tr_handle, this);
 | 
				
			||||||
            gp.set_extension(preExt);
 | 
					            gp.set_extension(preExt);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
@@ -434,7 +434,7 @@ bool core_complex::write_mem(uint64_t addr, unsigned length, const uint8_t *cons
 | 
				
			|||||||
        sc_time delay{quantum_keeper.get_local_time()};
 | 
					        sc_time delay{quantum_keeper.get_local_time()};
 | 
				
			||||||
#ifdef WITH_SCV
 | 
					#ifdef WITH_SCV
 | 
				
			||||||
        if (m_db != nullptr && tr_handle.is_valid()) {
 | 
					        if (m_db != nullptr && tr_handle.is_valid()) {
 | 
				
			||||||
            auto preExt = new tlm::scc::scv4tlm::tlm_recording_extension(tr_handle, this);
 | 
					            auto preExt = new scv4tlm::tlm_recording_extension(tr_handle, this);
 | 
				
			||||||
            gp.set_extension(preExt);
 | 
					            gp.set_extension(preExt);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 
 | 
				
			|||||||
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
		Reference in New Issue
	
	Block a user