generate working ISS from CoreDSL 2.0
This commit is contained in:
parent
da7e29fbb7
commit
34bb8e62ae
@ -1 +1 @@
|
||||
Subproject commit ab8ac7045927ca1d12e0142c476cd2e146083169
|
||||
Subproject commit 998444fba8e9273fda6a4d9c89303b62129500f2
|
@ -24,4 +24,4 @@ Core TGF_C provides RV32I, RV32M, RV32IC {
|
||||
unsigned PGSIZE = 0x1000; //1 << 12;
|
||||
unsigned PGMASK = 0xfff; //PGSIZE-1
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -29,7 +29,14 @@
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*******************************************************************************/
|
||||
|
||||
<%
|
||||
def getRegisterSizes(){
|
||||
def regs = registers.collect{it.size}
|
||||
regs[-1]=64 // correct for NEXT_PC
|
||||
regs+=[32, 32, 32, 32, 64] // append TRAP_STATE, PENDING_TRAP, MACHINE_STATE, LAST_BRANCH, ICOUNT
|
||||
return regs
|
||||
}
|
||||
%>
|
||||
#include "util/ities.h"
|
||||
#include <util/logging.h>
|
||||
#include <iss/arch/${coreDef.name.toLowerCase()}.h>
|
||||
@ -41,8 +48,8 @@ using namespace iss::arch;
|
||||
|
||||
constexpr std::array<const char*, ${registers.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_aliases;
|
||||
constexpr std::array<const uint32_t, ${registers.size}> iss::arch::traits<iss::arch::${coreDef.name.toLowerCase()}>::reg_bit_widths;
|
||||
constexpr std::array<const uint32_t, ${registers.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_bit_widths;
|
||||
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()}() {
|
||||
reg.icount = 0;
|
||||
|
@ -29,7 +29,24 @@
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*******************************************************************************/
|
||||
|
||||
<%
|
||||
def getRegisterSizes(){
|
||||
def regs = registers.collect{it.size}
|
||||
regs[-1]=pc.size // correct for NEXT_PC
|
||||
regs+=[32, 32, 32, 32, 64] // append TRAP_STATE, PENDING_TRAP, MACHINE_STATE, LAST_BRANCH, ICOUNT
|
||||
return regs
|
||||
}
|
||||
def getRegisterOffsets(){
|
||||
def regs = registers.collect{it.offset}
|
||||
def offs= regs[-1]
|
||||
// append TRAP_STATE, PENDING_TRAP, MACHINE_STATE, LAST_BRANCH, ICOUNT offsets starting with NEXT_PC size
|
||||
[pc.size/8, 4, 4, 4, 4].each{ sz ->
|
||||
regs+=offs+sz
|
||||
offs+=sz
|
||||
}
|
||||
return regs
|
||||
}
|
||||
%>
|
||||
#ifndef _${coreDef.name.toUpperCase()}_H_
|
||||
#define _${coreDef.name.toUpperCase()}_H_
|
||||
|
||||
@ -61,7 +78,6 @@ template <> struct traits<${coreDef.name.toLowerCase()}> {
|
||||
registers.each { reg -> %>
|
||||
${reg.name},<%
|
||||
}%>
|
||||
NUM_REGS,
|
||||
NEXT_${pc.name}=NUM_REGS,
|
||||
TRAP_STATE,
|
||||
PENDING_TRAP,
|
||||
@ -80,11 +96,11 @@ template <> struct traits<${coreDef.name.toLowerCase()}> {
|
||||
|
||||
using phys_addr_t = iss::typed_addr_t<iss::address_type::PHYSICAL>;
|
||||
|
||||
static constexpr std::array<const uint32_t, ${registers.size}> reg_bit_widths{
|
||||
{${registers.collect{it.size}.join(',')}}};
|
||||
static constexpr std::array<const uint32_t, ${getRegisterSizes().size}> reg_bit_widths{
|
||||
{${getRegisterSizes().join(',')}}};
|
||||
|
||||
static constexpr std::array<const uint32_t, ${registers.size}> reg_byte_offsets{
|
||||
{${registers.collect{it.offset}.join(',')}}};
|
||||
static constexpr std::array<const uint32_t, ${getRegisterOffsets().size}> reg_byte_offsets{
|
||||
{${getRegisterOffsets().join(',')}}};
|
||||
|
||||
static const uint64_t addr_mask = (reg_t(1) << (XLEN - 1)) | ((reg_t(1) << (XLEN - 1)) - 1);
|
||||
|
||||
@ -137,9 +153,9 @@ struct ${coreDef.name.toLowerCase()}: public arch_if {
|
||||
|
||||
protected:
|
||||
struct ${coreDef.name}_regs {<%
|
||||
registers.each { reg ->%>
|
||||
registers.each { reg -> if(reg.size>0) {%>
|
||||
uint${reg.size}_t ${reg.name} = 0;<%
|
||||
}%>
|
||||
}}%>
|
||||
uint${pc.size}_t NEXT_${pc.name} = 0;
|
||||
uint32_t trap_state = 0, pending_trap = 0, machine_state = 0, last_branch = 0;
|
||||
uint64_t icount = 0;
|
||||
|
@ -185,27 +185,32 @@ private:
|
||||
/* instruction definitions */<%instructions.eachWithIndex{instr, idx -> %>
|
||||
/* instruction ${idx}: ${instr.name} */
|
||||
compile_ret_t __${generator.functionName(instr.name)}(virt_addr_t& pc, code_word_t instr){
|
||||
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}
|
||||
<%}%>}
|
||||
auto cur_pc_val = pc.val;
|
||||
super::template get_reg<reg_t>(arch::traits<ARCH>::NEXT_PC) = cur_pc_val + ${instr.length/8};
|
||||
uint${addrDataWidth}_t* X = reinterpret_cast<uint${addrDataWidth}_t*>(this->regs_base_ptr+arch::traits<ARCH>::X0);
|
||||
uint${addrDataWidth}_t* PC = reinterpret_cast<uint${addrDataWidth}_t*>(this->regs_base_ptr+arch::traits<ARCH>::PC);
|
||||
<%instr.behavior.eachLine{%>${it}
|
||||
<%}%>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, cur_pc_val);
|
||||
}
|
||||
pc.val=super::template get_reg<reg_t>(arch::traits<ARCH>::NEXT_PC);
|
||||
return pc;
|
||||
// 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;
|
||||
}
|
||||
<%}%>
|
||||
/****************************************************************************
|
||||
|
@ -47,11 +47,11 @@ template <> struct traits<tgf_c> {
|
||||
|
||||
constexpr static char const* const core_type = "TGF_C";
|
||||
|
||||
static constexpr std::array<const char*, 33> 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"}};
|
||||
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", "NUM_REGS"}};
|
||||
|
||||
static constexpr std::array<const char*, 33> 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"}};
|
||||
static constexpr std::array<const char*, 34> reg_aliases{
|
||||
{"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, MISA_VAL=0b1000000000000000001000100000100, PGSIZE=0x1000, PGMASK=0xfff, CSR_SIZE=4096, fence=0, fencei=1, fencevmal=2, fencevmau=3, MUL_LEN=64};
|
||||
|
||||
@ -110,11 +110,11 @@ template <> struct traits<tgf_c> {
|
||||
|
||||
using phys_addr_t = iss::typed_addr_t<iss::address_type::PHYSICAL>;
|
||||
|
||||
static constexpr std::array<const uint32_t, 33> 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}};
|
||||
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}};
|
||||
|
||||
static constexpr std::array<const uint32_t, 33> 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}};
|
||||
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}};
|
||||
|
||||
static const uint64_t addr_mask = (reg_t(1) << (XLEN - 1)) | ((reg_t(1) << (XLEN - 1)) - 1);
|
||||
|
||||
|
@ -39,10 +39,10 @@
|
||||
|
||||
using namespace iss::arch;
|
||||
|
||||
constexpr std::array<const char*, 33> 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 uint32_t, 33> iss::arch::traits<iss::arch::tgf_c>::reg_bit_widths;
|
||||
constexpr std::array<const uint32_t, 33> iss::arch::traits<iss::arch::tgf_c>::reg_byte_offsets;
|
||||
constexpr std::array<const char*, 34> iss::arch::traits<iss::arch::tgf_c>::reg_names;
|
||||
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_byte_offsets;
|
||||
|
||||
tgf_c::tgf_c() {
|
||||
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")
|
||||
("mem,m", po::value<std::string>(), "the memory input file")
|
||||
("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");
|
||||
// clang-format on
|
||||
auto parsed = po::command_line_parser(argc, argv).options(desc).allow_unregistered().run();
|
||||
|
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user