missing simX changes from OPAE

This commit is contained in:
Blaise Tine
2020-03-27 22:44:16 -04:00
parent e80fa7f233
commit 89d5bfbef1
11 changed files with 552 additions and 425 deletions

View File

@@ -2,13 +2,13 @@
# HARPtools by Chad D. Kersey, Summer 2011 # # HARPtools by Chad D. Kersey, Summer 2011 #
################################################################################ ################################################################################
CXXFLAGS ?= -std=c++11 -fPIC -O3 -Wall -Wextra -pedantic -g -DUSE_DEBUG=3 -DPRINT_ACTIVE_THREADS CXXFLAGS ?= -std=c++11 -fPIC -O3 -Wall -Wextra -pedantic -DUSE_DEBUG=3 -DPRINT_ACTIVE_THREADS
# CXXFLAGS ?= -std=c++11 -fPIC -O0 -g -Wall -Wextra -pedantic # -g -DUSE_DEBUG=3 -DPRINT_ACTIVE_THREADS #CXXFLAGS ?= -std=c++11 -fPIC -g -O0 -Wall -Wextra -pedantic -DUSE_DEBUG=3 -DPRINT_ACTIVE_THREADS
LIB_OBJS=simX.cpp args.cpp mem.cpp core.cpp instruction.cpp enc.cpp util.cpp LIB_OBJS=simX.cpp args.cpp mem.cpp core.cpp instruction.cpp enc.cpp util.cpp
INCLUDE=-I. -I../rtl/shared_memory -I../rtl/cache -I../rtl/interfaces -Isimulate -I../rtl INCLUDE=-I. -I../old_rtl -I../old_rtl/interfaces -I../old_rtl/cache -I../old_rtl/shared_memory -Isimulate
FILE=cache_simX.v FILE=cache_simX.v
COMP=--compiler gcc COMP=--compiler gcc
LIB= LIB=

View File

@@ -1,5 +1,5 @@
`include "../rtl/VX_define.v" `include "../old_rtl/VX_define.v"
module cache_simX ( module cache_simX (
input wire clk, // Clock input wire clk, // Clock

View File

@@ -80,19 +80,17 @@ using namespace std;
void printTrace(trace_inst_t * trace, const char * stage_name) void printTrace(trace_inst_t * trace, const char * stage_name)
{ {
D(3, "********************************** " << stage_name << " *********************************"); D(3, stage_name << ": valid=" << trace->valid_inst);
D(3, "valid: " << trace->valid_inst); D(3, stage_name << ": PC=" << hex << trace->pc << dec);
D(3, "PC: " << hex << trace->pc << dec); D(3, stage_name << ": wid=" << trace->wid);
D(3, "wid: " << trace->wid); D(3, stage_name << ": rd=" << trace->rd << ", rs1=" << trace->rs1 << ", trs2=" << trace->rs2);
D(3, "rd: " << trace->rd << "\trs1: " << trace->rs1 << "\trs2: " << trace->rs2); D(3, stage_name << ": is_lw=" << trace->is_lw);
D(3, "is_lw: " << trace->is_lw); D(3, stage_name << ": is_sw=" << trace->is_sw);
D(3, "is_sw: " << trace->is_sw); D(3, stage_name << ": fetch_stall_cycles=" << trace->fetch_stall_cycles);
D(3, "fetch_stall_cycles: " << trace->fetch_stall_cycles); D(3, stage_name << ": mem_stall_cycles=" << trace->mem_stall_cycles);
D(3, "mem_stall_cycles: " << trace->mem_stall_cycles); D(3, stage_name << ": stall_warp=" << trace->stall_warp);
D(3, stage_name << ": wspawn=" << trace->wspawn);
D(3, "stall_warp: " << trace->stall_warp); D(3, stage_name << ": stalled=" << trace->stalled);
D(3, "wspawn: " << trace->wspawn);
D(3, "stalled: " << trace->stalled);
} }
#ifdef EMU_INSTRUMENTATION #ifdef EMU_INSTRUMENTATION
@@ -126,17 +124,14 @@ Core::Core(const ArchDef &a, Decoder &d, MemoryUnit &mem, Word id):
INIT_TRACE(inst_in_lsu); INIT_TRACE(inst_in_lsu);
INIT_TRACE(inst_in_wb); INIT_TRACE(inst_in_wb);
for (int i = 0; i < 32; i++) for (int i = 0; i < 32; i++) {
{
stallWarp[i] = false; stallWarp[i] = false;
for (int j = 0; j < 32; j++) for (int j = 0; j < 32; j++) {
{
renameTable[i][j] = true; renameTable[i][j] = true;
} }
} }
for(int i = 0; i < 32; i++) for(int i = 0; i < 32; i++) {
{
vecRenameTable[i] = true; vecRenameTable[i] = true;
} }
@@ -157,8 +152,9 @@ Core::Core(const ArchDef &a, Decoder &d, MemoryUnit &mem, Word id):
cache_simulator->reset = 0; cache_simulator->reset = 0;
cache_simulator->clk = 0; cache_simulator->clk = 0;
for (unsigned i = 0; i < a.getNWarps(); ++i) for (unsigned i = 0; i < a.getNWarps(); ++i) {
w.push_back(Warp(this, i)); w.push_back(Warp(this, i));
}
w[0].activeThreads = 1; w[0].activeThreads = 1;
w[0].spawned = true; w[0].spawned = true;
@@ -171,19 +167,17 @@ bool Core::interrupt(Word r0) {
void Core::step() void Core::step()
{ {
D(3, "\n\n\n------------------------------------------------------"); D(3, "###########################################################");
D(3, "Started core::step" << flush);
steps++; steps++;
this->num_cycles++; this->num_cycles++;
D(3, "CYCLE: " << this->num_cycles); D(3, "cycle: " << this->num_cycles);
D(3, "Stalled Warps:"); DPH(3, "stalled warps:");
for (int widd = 0; widd < a.getNWarps(); widd++) for (int widd = 0; widd < a.getNWarps(); widd++) {
{ DPN(3, " " << stallWarp[widd]);
D(3, stallWarp[widd] << " ");
} }
DPN(3, "\n");
// cout << "Rename table\n"; // cout << "Rename table\n";
// for (int regii = 0; regii < 32; regii++) // for (int regii = 0; regii < 32; regii++)
@@ -213,8 +207,7 @@ void Core::step()
stallWarp[release_warp_num] = false; stallWarp[release_warp_num] = false;
} }
D(3, "released warp" << flush); DPN(3, flush);
D(3, "Finished core::step" << flush);
} }
void Core::getCacheDelays(trace_inst_t * trace_inst) void Core::getCacheDelays(trace_inst_t * trace_inst)
@@ -400,11 +393,7 @@ void Core::warpScheduler()
void Core::fetch() void Core::fetch()
{ {
// #ifdef PRINT_ACTIVE_THREADS // D(-1, "Found schedule: " << foundSchedule);
D(3, "Threads:");
// #endif
// D(-1, "Found schedule: " << foundSchedule);
if ((!inst_in_scheduler.stalled) && (inst_in_fetch.fetch_stall_cycles == 0)) if ((!inst_in_scheduler.stalled) && (inst_in_fetch.fetch_stall_cycles == 0))
{ {
@@ -416,23 +405,24 @@ void Core::fetch()
if (foundSchedule) if (foundSchedule)
{ {
D(3, "Core step stepping warp " << schedule_w << '[' << w[schedule_w].activeThreads << ']'); auto active_threads_b = w[schedule_w].activeThreads;
this->num_instructions = this->num_instructions + w[schedule_w].activeThreads; this->num_instructions = this->num_instructions + w[schedule_w].activeThreads;
// this->num_instructions++; // this->num_instructions++;
w[schedule_w].step(&inst_in_fetch); w[schedule_w].step(&inst_in_fetch);
D(3, "Now " << w[schedule_w].activeThreads << " active threads in " << schedule_w << flush);
auto active_threads_a = w[schedule_w].activeThreads;
if (active_threads_b != active_threads_a) {
D(3, "** warp #" << schedule_w << " active threads changed from " << active_threads_b << " to " << active_threads_a);
}
this->getCacheDelays(&inst_in_fetch); this->getCacheDelays(&inst_in_fetch);
D(3, "Got cache delays" << flush);
if (inst_in_fetch.stall_warp) if (inst_in_fetch.stall_warp) {
{
stallWarp[inst_in_fetch.wid] = true; stallWarp[inst_in_fetch.wid] = true;
} }
D(3, "staled warps\n" << flush);
} }
D(3, "About to schedule warp\n" << flush);
warpScheduler(); warpScheduler();
D(3, "Scheduled warp" << flush);
} }
} }
else else
@@ -441,30 +431,19 @@ void Core::fetch()
if (inst_in_fetch.fetch_stall_cycles > 0) inst_in_fetch.fetch_stall_cycles--; if (inst_in_fetch.fetch_stall_cycles > 0) inst_in_fetch.fetch_stall_cycles--;
} }
D(3, "Printing trace" << flush);
printTrace(&inst_in_fetch, "Fetch"); printTrace(&inst_in_fetch, "Fetch");
D(3, "printed trace" << flush);
// #ifdef PRINT_ACTIVE_THREADS // #ifdef PRINT_ACTIVE_THREADS
D(3, "About to print active threads" << flush << "\n"); DPH(3, "active threads:");
for (unsigned j = 0; j < w[schedule_w].tmask.size(); ++j) { for (unsigned j = 0; j < w[schedule_w].tmask.size(); ++j) {
if (w[schedule_w].activeThreads > j && w[schedule_w].tmask[j]) if (w[schedule_w].activeThreads > j && w[schedule_w].tmask[j]) {
{ DPN(3, " 1");
D(3, " 1"); } else {
} DPN(3, " 0");
else
{
D(3, " 0");
} }
if (j != w[schedule_w].tmask.size()-1 || schedule_w != w.size()-1) }
{ DPN(3, "\n");
D(3, ','); // #endif
}
}
D(3, "\nPrinted active threads" << flush);
// #endif
// #ifdef PRINT_ACTIVE_THREADS // #ifdef PRINT_ACTIVE_THREADS
// #endif // #endif
@@ -472,9 +451,6 @@ void Core::fetch()
void Core::decode() void Core::decode()
{ {
if ((inst_in_fetch.fetch_stall_cycles == 0) && !inst_in_scheduler.stalled) if ((inst_in_fetch.fetch_stall_cycles == 0) && !inst_in_scheduler.stalled)
{ {
CPY_TRACE(inst_in_decode, inst_in_fetch); CPY_TRACE(inst_in_decode, inst_in_fetch);
@@ -493,7 +469,7 @@ void Core::scheduler()
INIT_TRACE(inst_in_decode); INIT_TRACE(inst_in_decode);
} }
//printTrace(&inst_in_scheduler, "scheduler"); //printTrace(&inst_in_scheduler, "Scheduler");
} }
void Core::load_store() void Core::load_store()
@@ -562,7 +538,6 @@ void Core::load_store()
void Core::execute_unit() void Core::execute_unit()
{ {
D(3, "$$$$$$$$$$$$$$$$$$$ EXE START\n" << flush);
bool do_nothing = false; bool do_nothing = false;
// EXEC is always not busy // EXEC is always not busy
if (inst_in_scheduler.is_lw || inst_in_scheduler.is_sw) if (inst_in_scheduler.is_lw || inst_in_scheduler.is_sw)
@@ -615,7 +590,7 @@ void Core::execute_unit()
} }
else else
{ {
D(3, "&&&&&&&&&&&&&&&&&&&&&&&& EXECUTE SRCS NOT READY"); D(3, "Execute: srcs not ready!");
inst_in_scheduler.stalled = true; inst_in_scheduler.stalled = true;
// INIT_TRACE(inst_in_exe); // INIT_TRACE(inst_in_exe);
do_nothing = true; do_nothing = true;
@@ -627,15 +602,12 @@ void Core::execute_unit()
// } // }
//printTrace(&inst_in_exe, "execute_unit"); //printTrace(&inst_in_exe, "EXE");
// INIT_TRACE(inst_in_exe); // INIT_TRACE(inst_in_exe);
D(3, "EXECUTE END" << flush);
} }
void Core::writeback() void Core::writeback()
{ {
if (inst_in_wb.rd > 0) renameTable[inst_in_wb.wid][inst_in_wb.rd] = true; if (inst_in_wb.rd > 0) renameTable[inst_in_wb.wid][inst_in_wb.rd] = true;
if (inst_in_wb.vd > 0) vecRenameTable[inst_in_wb.vd] = true; if (inst_in_wb.vd > 0) vecRenameTable[inst_in_wb.vd] = true;
@@ -697,9 +669,7 @@ bool Core::running() const {
if (stages_have_valid) return true; if (stages_have_valid) return true;
for (unsigned i = 0; i < w.size(); ++i) for (unsigned i = 0; i < w.size(); ++i)
if (w[i].running()) if (w[i].running()) {
{
D(3, "Warp ID " << i << " is running");
return true; return true;
} }
return false; return false;
@@ -777,8 +747,7 @@ void Warp::step(trace_inst_t * trace_inst) {
// ++steps; // ++steps;
D(3, "in step pc=0x" << hex << pc); D(3, "current PC=0x" << hex << pc);
D(3, "help: in PC: " << hex << pc << dec);
// std::cout << "pc: " << hex << pc << "\n"; // std::cout << "pc: " << hex << pc << "\n";
@@ -798,9 +767,6 @@ void Warp::step(trace_inst_t * trace_inst) {
decPos = 0; decPos = 0;
inst = core->iDec.decode(fetchBuffer, decPos, trace_inst); inst = core->iDec.decode(fetchBuffer, decPos, trace_inst);
D(3, "Fetched at 0x" << hex << pc);
D(3, "0x" << hex << pc << ": " << *inst);
// Update pc // Update pc
pc += decPos; pc += decPos;
@@ -821,12 +787,10 @@ void Warp::step(trace_inst_t * trace_inst) {
} }
D(3, "Thread mask:"); DPH(3, "Thread mask:");
D_RAW(" "); for (unsigned i = 0; i < tmask.size(); ++i) DPN(3, " " << tmask[i]);
for (unsigned i = 0; i < tmask.size(); ++i) D_RAW(tmask[i] << ' '); DPN(3, "\n");
D_RAW(endl);
D_RAW(endl);
D_RAW(endl);
// } // }
// #endif // #endif

View File

@@ -101,9 +101,6 @@ Instruction *WordDecoder::decode(const std::vector<Byte> &v, Size &idx, trace_in
bool predicated = false; bool predicated = false;
if (predicated) { inst.setPred((code>>(inst_s-p-1))&pMask); } if (predicated) { inst.setPred((code>>(inst_s-p-1))&pMask); }
// printf("CUrrent CODE: %x\n", code);
D(3, "Curr Code: " << hex << code << dec);
Opcode op = (Opcode)((code>>shift_opcode)&opcode_mask); Opcode op = (Opcode)((code>>shift_opcode)&opcode_mask);
// std::cout << "opcode: " << op << "\n"; // std::cout << "opcode: " << op << "\n";
inst.setOpcode(op); inst.setOpcode(op);
@@ -324,7 +321,7 @@ Instruction *WordDecoder::decode(const std::vector<Byte> &v, Size &idx, trace_in
// inst.setImmRef(*r); // inst.setImmRef(*r);
} }
D(2, "Decoded 0x" << hex << code << " into: " << inst << '\n'); D(2, "Decoded instr 0x" << hex << code << " into: " << inst);
return &inst; return &inst;
} }

View File

@@ -16,15 +16,16 @@ namespace Harp {
public: public:
struct Undefined {}; struct Undefined {};
ArchDef(const std::string &s) { ArchDef(const std::string &s, bool cpu_mode = false, int num_warps =32, int num_threads = 32)
: cpu_mode_(cpu_mode) {
std::istringstream iss(s.c_str()); std::istringstream iss(s.c_str());
wordSize = 4; wordSize = 4;
encChar = 'w'; encChar = 'w';
nRegs = 32; nRegs = 32;
nPRegs = 0; nPRegs = 0;
nThds = 32; nThds = num_warps;
nWarps = 32; nWarps = num_threads;
extent = EXT_WARPS; extent = EXT_WARPS;
@@ -98,6 +99,10 @@ namespace Harp {
ThdNum getNWarps() const { ThdNum getNWarps() const {
if (extent < EXT_WARPS) throw Undefined(); else return nWarps; if (extent < EXT_WARPS) throw Undefined(); else return nWarps;
} }
bool is_cpu_mode() const {
return cpu_mode_;
}
private: private:
enum Extent { enum Extent {
@@ -110,6 +115,7 @@ namespace Harp {
ThdNum nThds, nWarps; ThdNum nThds, nWarps;
RegNum nRegs, nPRegs; RegNum nRegs, nPRegs;
char encChar; char encChar;
bool cpu_mode_;
}; };
} }

View File

@@ -4,20 +4,34 @@
#ifndef __DEBUG_H #ifndef __DEBUG_H
#define __DEBUG_H #define __DEBUG_H
// #define USE_DEBUG 9 //#define USE_DEBUG 9
// #define USE_DEBUG 3
#ifdef USE_DEBUG #ifdef USE_DEBUG
#include <iostream> #include <iostream>
#define D(lvl, x) do { \ #define D(lvl, x) do { \
using namespace std; \ using namespace std; \
if ((lvl) == USE_DEBUG) { \ if ((lvl) <= USE_DEBUG) { \
cout << "DEBUG " << __FILE__ << ':' << dec << __LINE__ << ": " \ cout << "DEBUG " << __FILE__ << ':' << dec << __LINE__ << ": " \
<< x << endl; \ << x << endl; \
} \ } \
} while(0) } while(0)
#define DPH(lvl, x) do { \
using namespace std; \
if ((lvl) <= USE_DEBUG) { \
cout << "DEBUG " << __FILE__ << ':' << dec << __LINE__ << ": " \
<< x; \
} \
} while(0)
#define DPN(lvl, x) do { \
using namespace std; \
if ((lvl) <= USE_DEBUG) { \
cout << x; \
} \
} while(0)
#define D_RAW(x) do { \ #define D_RAW(x) do { \
std::cout << x; \ std::cout << x; \
} while (0) } while (0)
@@ -25,6 +39,8 @@
#else #else
#define D(lvl, x) do {} while(0) #define D(lvl, x) do {} while(0)
#define DPH(lvl, x) do {} while(0)
#define DPN(lvl, x) do {} while(0)
#define D_RAW(x) do {} while(0) #define D_RAW(x) do {} while(0)
#endif #endif

View File

@@ -168,16 +168,18 @@ namespace Harp {
bool disableVm; bool disableVm;
}; };
class RAM : public MemDevice { class RAM : public MemDevice {
public: public:
uint8_t* mem[1 << 12]; uint8_t* mem[1 << 12];
RAM(){ RAM(){
for(uint32_t i = 0;i < (1 << 12);i++) mem[i] = NULL; for(uint32_t i = 0;i < (1 << 12);i++)
mem[i] = NULL;
} }
~RAM(){ ~RAM(){
for(uint32_t i = 0;i < (1 << 12);i++) if(mem[i]) delete [] mem[i]; for(uint32_t i = 0;i < (1 << 12);i++)
if(mem[i])
delete [] mem[i];
} }
void clear(){ void clear(){
@@ -218,7 +220,7 @@ namespace Harp {
} }
} }
virtual Size size() const { return (1<<31); }; virtual Size size() const { return -1; }
void getBlock(uint32_t address, uint8_t *data) void getBlock(uint32_t address, uint8_t *data)
{ {
@@ -325,137 +327,9 @@ namespace Harp {
// MEMORY UTILS // MEMORY UTILS
uint32_t hti_old(char c) { void loadHexImpl(std::string path);
if (c >= 'A' && c <= 'F')
return c - 'A' + 10;
if (c >= 'a' && c <= 'f')
return c - 'a' + 10;
return c - '0';
}
uint32_t hToI_old(char *c, uint32_t size) {
uint32_t value = 0;
for (uint32_t i = 0; i < size; i++) {
value += hti_old(c[i]) << ((size - i - 1) * 4);
}
return value;
}
void loadHexImpl(std::string path) {
this->clear();
FILE *fp = fopen(&path[0], "r");
if(fp == 0){
std::cout << path << " not found" << std::endl;
}
//Preload 0x0 <-> 0x80000000 jumps
((uint32_t*)this->get(0))[0] = 0xf1401073;
((uint32_t*)this->get(0))[1] = 0xf1401073;
// ((uint32_t*)this->get(0))[1] = 0xf1401073;
((uint32_t*)this->get(0))[2] = 0x30101073;
((uint32_t*)this->get(0))[3] = 0x800000b7;
((uint32_t*)this->get(0))[4] = 0x000080e7;
((uint32_t*)this->get(0x80000000))[0] = 0x00000097;
((uint32_t*)this->get(0xb0000000))[0] = 0x01C02023;
// F00FFF10
((uint32_t*)this->get(0xf00fff10))[0] = 0x12345678;
((uint32_t*)this->get(0x70000000))[0] = 0x00008067;
{
uint32_t init_addr = 0x70000004;
for (int off = 0; off < 1024; off+=4)
{
uint32_t new_addr = init_addr+off;
((uint32_t*)this->get(new_addr))[0] = 0x00000000;
}
}
{
uint32_t init_addr = 0x71000000;
for (int off = 0; off < 1024; off+=4)
{
uint32_t new_addr = init_addr+off;
((uint32_t*)this->get(new_addr))[0] = 0x00000000;
}
}
{
uint32_t init_addr = 0x72000000;
for (int off = 0; off < 1024; off+=4)
{
uint32_t new_addr = init_addr+off;
((uint32_t*)this->get(new_addr))[0] = 0x00000000;
}
}
fseek(fp, 0, SEEK_END);
uint32_t size = ftell(fp);
fseek(fp, 0, SEEK_SET);
char* content = new char[size];
int x = fread(content, 1, size, fp);
if (!x) { std::cout << "COULD NOT READ FILE\n"; std::abort();}
int offset = 0;
char* line = content;
// std::cout << "WHTA\n";
while (1) {
if (line[0] == ':') {
uint32_t byteCount = hToI_old(line + 1, 2);
uint32_t nextAddr = hToI_old(line + 3, 4) + offset;
uint32_t key = hToI_old(line + 7, 2);
switch (key) {
case 0:
for (uint32_t i = 0; i < byteCount; i++) {
unsigned add = nextAddr + i;
*(this->get(add)) = hToI_old(line + 9 + i * 2, 2);
// std::cout << "lhi: Address: " << std::hex <<(add) << "\tValue: " << std::hex << hToI_old(line + 9 + i * 2, 2) << std::endl;
}
break;
case 2:
// cout << offset << endl;
offset = hToI_old(line + 9, 4) << 4;
break;
case 4:
// cout << offset << endl;
offset = hToI_old(line + 9, 4) << 16;
break;
default:
// cout << "??? " << key << endl;
break;
}
}
while (*line != '\n' && size != 0) {
line++;
size--;
}
if (size <= 1)
break;
line++;
size--;
}
if (content) delete[] content;
}
}; };
} }

View File

@@ -45,7 +45,7 @@ ostream &Harp::operator<<(ostream& os, Instruction &inst) {
// else os << "#0x" << hex << inst.immsrc; // else os << "#0x" << hex << inst.immsrc;
// } // }
D(3, instTable[inst.op].opString << ';\n'); os << instTable[inst.op].opString;
return os; return os;
} }
@@ -347,8 +347,6 @@ void trap_to_simulator(Warp & c)
} }
void Instruction::executeOn(Warp &c, trace_inst_t * trace_inst) { void Instruction::executeOn(Warp &c, trace_inst_t * trace_inst) {
D(3, "Begin instruction execute.");
/* If I try to execute a privileged instruction in user mode, throw an /* If I try to execute a privileged instruction in user mode, throw an
exception 3. */ exception 3. */
if (instTable[op].privileged && !c.supervisorMode) { if (instTable[op].privileged && !c.supervisorMode) {
@@ -357,11 +355,8 @@ void Instruction::executeOn(Warp &c, trace_inst_t * trace_inst) {
return; return;
} }
bool is_vec = false; bool is_vec = false;
Size nextActiveThreads = c.activeThreads; Size nextActiveThreads = c.activeThreads;
Size wordSz = c.core->a.getWordSize(); Size wordSz = c.core->a.getWordSize();
Word nextPc = c.pc; Word nextPc = c.pc;
@@ -425,7 +420,6 @@ void Instruction::executeOn(Warp &c, trace_inst_t * trace_inst) {
case R_INST: case R_INST:
// std::cout << "R_INST\n"; // std::cout << "R_INST\n";
m_exten = func7 & 0x1; m_exten = func7 & 0x1;
if (m_exten) if (m_exten)
{ {
// std::cout << "FOUND A MUL/DIV\n"; // std::cout << "FOUND A MUL/DIV\n";
@@ -434,11 +428,12 @@ void Instruction::executeOn(Warp &c, trace_inst_t * trace_inst) {
{ {
case 0: case 0:
// MUL // MUL
// cout << "MUL\n"; D(3, "MUL: r" << rdest << " <- r" << rsrc[0] << ", r" << rsrc[1]);
reg[rdest] = ((int) reg[rsrc[0]]) * ((int) reg[rsrc[1]]); reg[rdest] = ((int) reg[rsrc[0]]) * ((int) reg[rsrc[1]]);
break; break;
case 1: case 1:
// MULH // MULH
D(3, "MULH: r" << rdest << " <- r" << rsrc[0] << ", r" << rsrc[1]);
{ {
int64_t first = (int64_t) reg[rsrc[0]]; int64_t first = (int64_t) reg[rsrc[0]];
if (reg[rsrc[0]] & 0x80000000) if (reg[rsrc[0]] & 0x80000000)
@@ -458,6 +453,7 @@ void Instruction::executeOn(Warp &c, trace_inst_t * trace_inst) {
break; break;
case 2: case 2:
// MULHSU // MULHSU
D(3, "MULHSU: r" << rdest << " <- r" << rsrc[0] << ", r" << rsrc[1]);
{ {
int64_t first = (int64_t) reg[rsrc[0]]; int64_t first = (int64_t) reg[rsrc[0]];
if (reg[rsrc[0]] & 0x80000000) if (reg[rsrc[0]] & 0x80000000)
@@ -470,6 +466,7 @@ void Instruction::executeOn(Warp &c, trace_inst_t * trace_inst) {
break; break;
case 3: case 3:
// MULHU // MULHU
D(3, "MULHU: r" << rdest << " <- r" << rsrc[0] << ", r" << rsrc[1]);
{ {
uint64_t first = (uint64_t) reg[rsrc[0]]; uint64_t first = (uint64_t) reg[rsrc[0]];
uint64_t second = (uint64_t) reg[rsrc[1]]; uint64_t second = (uint64_t) reg[rsrc[1]];
@@ -479,6 +476,7 @@ void Instruction::executeOn(Warp &c, trace_inst_t * trace_inst) {
break; break;
case 4: case 4:
// DIV // DIV
D(3, "DIV: r" << rdest << " <- r" << rsrc[0] << ", r" << rsrc[1]);
if (reg[rsrc[1]] == 0) if (reg[rsrc[1]] == 0)
{ {
reg[rdest] = -1; reg[rdest] = -1;
@@ -490,6 +488,7 @@ void Instruction::executeOn(Warp &c, trace_inst_t * trace_inst) {
break; break;
case 5: case 5:
// DIVU // DIVU
D(3, "DIVU: r" << rdest << " <- r" << rsrc[0] << ", r" << rsrc[1]);
if (reg[rsrc[1]] == 0) if (reg[rsrc[1]] == 0)
{ {
reg[rdest] = -1; reg[rdest] = -1;
@@ -499,6 +498,7 @@ void Instruction::executeOn(Warp &c, trace_inst_t * trace_inst) {
break; break;
case 6: case 6:
// REM // REM
D(3, "REM: r" << rdest << " <- r" << rsrc[0] << ", r" << rsrc[1]);
if (reg[rsrc[1]] == 0) if (reg[rsrc[1]] == 0)
{ {
reg[rdest] = reg[rsrc[0]]; reg[rdest] = reg[rsrc[0]];
@@ -508,6 +508,7 @@ void Instruction::executeOn(Warp &c, trace_inst_t * trace_inst) {
break; break;
case 7: case 7:
// REMU // REMU
D(3, "REMU: r" << rdest << " <- r" << rsrc[0] << ", r" << rsrc[1]);
if (reg[rsrc[1]] == 0) if (reg[rsrc[1]] == 0)
{ {
reg[rdest] = reg[rsrc[0]]; reg[rdest] = reg[rsrc[0]];
@@ -528,20 +529,24 @@ void Instruction::executeOn(Warp &c, trace_inst_t * trace_inst) {
case 0: case 0:
if (func7) if (func7)
{ {
D(3, "SUBI: r" << rdest << " <- r" << rsrc[0] << ", r" << rsrc[1]);
reg[rdest] = reg[rsrc[0]] - reg[rsrc[1]]; reg[rdest] = reg[rsrc[0]] - reg[rsrc[1]];
reg[rdest].trunc(wordSz); reg[rdest].trunc(wordSz);
} }
else else
{ {
D(3, "ADDI: r" << rdest << " <- r" << rsrc[0] << ", r" << rsrc[1]);
reg[rdest] = reg[rsrc[0]] + reg[rsrc[1]]; reg[rdest] = reg[rsrc[0]] + reg[rsrc[1]];
reg[rdest].trunc(wordSz); reg[rdest].trunc(wordSz);
} }
break; break;
case 1: case 1:
reg[rdest] = reg[rsrc[0]] << reg[rsrc[1]]; D(3, "SLLI: r" << rdest << " <- r" << rsrc[0] << ", r" << rsrc[1]);
reg[rdest].trunc(wordSz); reg[rdest] = reg[rsrc[0]] << reg[rsrc[1]];
reg[rdest].trunc(wordSz);
break; break;
case 2: case 2:
D(3, "SLTI: r" << rdest << " <- r" << rsrc[0] << ", r" << rsrc[1]);
if ( int(reg[rsrc[0]]) < int(reg[rsrc[1]])) if ( int(reg[rsrc[0]]) < int(reg[rsrc[1]]))
{ {
reg[rdest] = 1; reg[rdest] = 1;
@@ -552,7 +557,8 @@ void Instruction::executeOn(Warp &c, trace_inst_t * trace_inst) {
} }
break; break;
case 3: case 3:
if ( Word_u(reg[rsrc[0]]) < Word_u(reg[rsrc[1]])) D(3, "SLTU: r" << rdest << " <- r" << rsrc[0] << ", r" << rsrc[1]);
if (Word_u(reg[rsrc[0]]) < Word_u(reg[rsrc[1]]))
{ {
reg[rdest] = 1; reg[rdest] = 1;
} }
@@ -562,24 +568,29 @@ void Instruction::executeOn(Warp &c, trace_inst_t * trace_inst) {
} }
break; break;
case 4: case 4:
D(3, "XORI: r" << rdest << " <- r" << rsrc[0] << ", r" << rsrc[1]);
reg[rdest] = reg[rsrc[0]] ^ reg[rsrc[1]]; reg[rdest] = reg[rsrc[0]] ^ reg[rsrc[1]];
break; break;
case 5: case 5:
if (func7) if (func7)
{ {
D(3, "SRLI: r" << rdest << " <- r" << rsrc[0] << ", r" << rsrc[1]);
reg[rdest] = int(reg[rsrc[0]]) >> int(reg[rsrc[1]]); reg[rdest] = int(reg[rsrc[0]]) >> int(reg[rsrc[1]]);
reg[rdest].trunc(wordSz); reg[rdest].trunc(wordSz);
} }
else else
{ {
D(3, "SRLU: r" << rdest << " <- r" << rsrc[0] << ", r" << rsrc[1]);
reg[rdest] = Word_u(reg[rsrc[0]]) >> Word_u(reg[rsrc[1]]); reg[rdest] = Word_u(reg[rsrc[0]]) >> Word_u(reg[rsrc[1]]);
reg[rdest].trunc(wordSz); reg[rdest].trunc(wordSz);
} }
break; break;
case 6: case 6:
D(3, "ORI: r" << rdest << " <- r" << rsrc[0] << ", r" << rsrc[1]);
reg[rdest] = reg[rsrc[0]] | reg[rsrc[1]]; reg[rdest] = reg[rsrc[0]] | reg[rsrc[1]];
break; break;
case 7: case 7:
D(3, "ANDI: r" << rdest << " <- r" << rsrc[0] << ", r" << rsrc[1]);
reg[rdest] = reg[rsrc[0]] & reg[rsrc[1]]; reg[rdest] = reg[rsrc[0]] & reg[rsrc[1]];
break; break;
default: default:
@@ -589,35 +600,35 @@ void Instruction::executeOn(Warp &c, trace_inst_t * trace_inst) {
} }
break; break;
case L_INST: case L_INST:
//std::cout << "L_INST\n"; memAddr = ((reg[rsrc[0]] + immsrc) & 0xFFFFFFFC);
shift_by = ((reg[rsrc[0]] + immsrc) & 0x00000003) * 8;
memAddr = ((reg[rsrc[0]] + immsrc) & 0xFFFFFFFC); data_read = c.core->mem.read(memAddr, c.supervisorMode);
shift_by = ((reg[rsrc[0]] + immsrc) & 0x00000003) * 8; trace_inst->is_lw = true;
data_read = c.core->mem.read(memAddr, c.supervisorMode); trace_inst->mem_addresses[t] = memAddr;
trace_inst->is_lw = true; switch (func3) {
trace_inst->mem_addresses[t] = memAddr;
// //std::cout <<std::hex<< "EXECUTE: " << reg[rsrc[0]] << " + " << immsrc << " = " << memAddr << " -> data_read: " << data_read << "\n";
switch (func3)
{
case 0: case 0:
// LB // LBI
D(3, "LBI: r" << rdest << " <- r" << rsrc[0] << ", imm=" << (int)immsrc);
reg[rdest] = signExt((data_read >> shift_by) & 0xFF, 8, 0xFF); reg[rdest] = signExt((data_read >> shift_by) & 0xFF, 8, 0xFF);
break; break;
case 1: case 1:
// LH // LWI
// //std::cout << "shifting by: " << shift_by << " final data: " << ((data_read >> shift_by) & 0xFFFF, 16, 0xFFFF) << "\n"; D(3, "LWI: r" << rdest << " <- r" << rsrc[0] << ", imm=" << (int)immsrc);
reg[rdest] = signExt((data_read >> shift_by) & 0xFFFF, 16, 0xFFFF); reg[rdest] = signExt((data_read >> shift_by) & 0xFFFF, 16, 0xFFFF);
break; break;
case 2: case 2:
// LDI
D(3, "LDI: r" << rdest << " <- r" << rsrc[0] << ", imm=" << (int)immsrc);
reg[rdest] = int(data_read & 0xFFFFFFFF); reg[rdest] = int(data_read & 0xFFFFFFFF);
break; break;
case 4: case 4:
// LBU // LBU
D(3, "LBU: r" << rdest << " <- r" << rsrc[0] << ", imm=" << (int)immsrc);
reg[rdest] = unsigned((data_read >> shift_by) & 0xFF); reg[rdest] = unsigned((data_read >> shift_by) & 0xFF);
break; break;
case 5: case 5:
// LWU
D(3, "LWU: r" << rdest << " <- r" << rsrc[0] << ", imm=" << (int)immsrc);
reg[rdest] = unsigned((data_read >> shift_by) & 0xFFFF); reg[rdest] = unsigned((data_read >> shift_by) & 0xFFFF);
break; break;
default: default:
@@ -625,19 +636,22 @@ void Instruction::executeOn(Warp &c, trace_inst_t * trace_inst) {
std::abort(); std::abort();
c.memAccesses.push_back(Warp::MemAccess(false, memAddr)); c.memAccesses.push_back(Warp::MemAccess(false, memAddr));
} }
D(3, "LOAD MEM ADDRESS: " << std::hex << memAddr);
D(3, "LOAD MEM DATA: " << std::hex << data_read);
break; break;
case I_INST: case I_INST:
//std::cout << "I_INST\n"; //std::cout << "I_INST\n";
switch (func3) switch (func3)
{ {
case 0: case 0:
// ADDI // ADDI
D(3, "ADDI: r" << rdest << " <- r" << rsrc[0] << ", imm=" << immsrc);
reg[rdest] = reg[rsrc[0]] + immsrc; reg[rdest] = reg[rsrc[0]] + immsrc;
reg[rdest].trunc(wordSz); reg[rdest].trunc(wordSz);
break; break;
case 2: case 2:
// SLTI // SLTI
D(3, "SLTI: r" << rdest << " <- r" << rsrc[0] << ", imm=" << immsrc);
if ( int(reg[rsrc[0]]) < int(immsrc)) if ( int(reg[rsrc[0]]) < int(immsrc))
{ {
reg[rdest] = 1; reg[rdest] = 1;
@@ -649,6 +663,7 @@ void Instruction::executeOn(Warp &c, trace_inst_t * trace_inst) {
break; break;
case 3: case 3:
// SLTIU // SLTIU
D(3, "SLTIU: r" << rdest << " <- r" << rsrc[0] << ", imm=" << immsrc);
op1 = (unsigned) reg[rsrc[0]]; op1 = (unsigned) reg[rsrc[0]];
if ( unsigned(reg[rsrc[0]]) < unsigned(immsrc)) if ( unsigned(reg[rsrc[0]]) < unsigned(immsrc))
{ {
@@ -661,18 +676,22 @@ void Instruction::executeOn(Warp &c, trace_inst_t * trace_inst) {
break; break;
case 4: case 4:
// XORI // XORI
D(3, "XORI: r" << rdest << " <- r" << rsrc[0] << ", imm=0x" << hex << immsrc);
reg[rdest] = reg[rsrc[0]] ^ immsrc; reg[rdest] = reg[rsrc[0]] ^ immsrc;
break; break;
case 6: case 6:
// ORI; // ORI
D(3, "ORI: r" << rdest << " <- r" << rsrc[0] << ", imm=0x" << hex << immsrc);
reg[rdest] = reg[rsrc[0]] | immsrc; reg[rdest] = reg[rsrc[0]] | immsrc;
break; break;
case 7: case 7:
// ANDI // ANDI
D(3, "ANDI: r" << rdest << " <- r" << rsrc[0] << ", imm=0x" << hex << immsrc);
reg[rdest] = reg[rsrc[0]] & immsrc; reg[rdest] = reg[rsrc[0]] & immsrc;
break; break;
case 1: case 1:
// SLLI // SLLI
D(3, "SLLI: r" << rdest << " <- r" << rsrc[0] << ", imm=0x" << hex << immsrc);
reg[rdest] = reg[rsrc[0]] << immsrc; reg[rdest] = reg[rsrc[0]] << immsrc;
reg[rdest].trunc(wordSz); reg[rdest].trunc(wordSz);
break; break;
@@ -680,31 +699,20 @@ void Instruction::executeOn(Warp &c, trace_inst_t * trace_inst) {
if ((func7 == 0)) if ((func7 == 0))
{ {
// SRLI // SRLI
// //std::cout << "WTF\n"; D(3, "SRLI: r" << rdest << " <- r" << rsrc[0] << ", imm=" << immsrc);
bool isNeg = ((0x80000000 & reg[rsrc[0]])) > 0; bool isNeg = ((0x80000000 & reg[rsrc[0]])) > 0;
Word result = Word_u(reg[rsrc[0]]) >> Word_u(immsrc); Word result = Word_u(reg[rsrc[0]]) >> Word_u(immsrc);
// if (isNeg) reg[rdest] = result;
// { reg[rdest].trunc(wordSz);
// Word mask = 0x80000000;
// for (int i = 32; i < Word_u(immsrc); i++)
// {
// result |= mask;
// mask = mask >> 1;
// }
// }
reg[rdest] = result;
reg[rdest].trunc(wordSz);
} }
else else
{ {
// SRAI // SRAI
// //std::cout << "WOHOOOOO\n"; D(3, "SRAI: r" << rdest << " <- r" << rsrc[0] << ", imm=" << immsrc);
op1 = reg[rsrc[0]]; op1 = reg[rsrc[0]];
op2 = immsrc; op2 = immsrc;
reg[rdest] = op1 >> op2; reg[rdest] = op1 >> op2;
reg[rdest].trunc(wordSz); reg[rdest].trunc(wordSz);
} }
break; break;
default: default:
@@ -713,11 +721,8 @@ void Instruction::executeOn(Warp &c, trace_inst_t * trace_inst) {
} }
break; break;
case S_INST: case S_INST:
//std::cout << "S_INST\n";
++c.stores; ++c.stores;
memAddr = reg[rsrc[0]] + immsrc; memAddr = reg[rsrc[0]] + immsrc;
D(3, "STORE MEM ADDRESS: " << std::hex << reg[rsrc[0]] << " + " << immsrc << "\n");
D(3, "STORE MEM ADDRESS: " << std::hex << memAddr);
trace_inst->is_sw = true; trace_inst->is_sw = true;
trace_inst->mem_addresses[t] = memAddr; trace_inst->mem_addresses[t] = memAddr;
// //std::cout << "FUNC3: " << func3 << "\n"; // //std::cout << "FUNC3: " << func3 << "\n";
@@ -730,21 +735,25 @@ void Instruction::executeOn(Warp &c, trace_inst_t * trace_inst) {
switch (func3) switch (func3)
{ {
case 0: case 0:
// //std::cout << "SB\n"; // SB
D(3, "SB: r" << rsrc[1] << " <- r" << rsrc[0] << ", imm=" << (int)immsrc);
c.core->mem.write(memAddr, reg[rsrc[1]] & 0x000000FF, c.supervisorMode, 1); c.core->mem.write(memAddr, reg[rsrc[1]] & 0x000000FF, c.supervisorMode, 1);
break; break;
case 1: case 1:
// //std::cout << "SH\n"; // SH
D(3, "SH: r" << rsrc[1] << " <- r" << rsrc[0] << ", imm=" << (int)immsrc);
c.core->mem.write(memAddr, reg[rsrc[1]], c.supervisorMode, 2); c.core->mem.write(memAddr, reg[rsrc[1]], c.supervisorMode, 2);
break; break;
case 2: case 2:
// //std::cout << std::hex << "SW: about to write: " << reg[rsrc[1]] << " to " << memAddr << "\n"; // SD
D(3, "SD: r" << rsrc[1] << " <- r" << rsrc[0] << ", imm=" << (int)immsrc);
c.core->mem.write(memAddr, reg[rsrc[1]], c.supervisorMode, 4); c.core->mem.write(memAddr, reg[rsrc[1]], c.supervisorMode, 4);
break; break;
default: default:
cout << "ERROR: UNSUPPORTED S INST\n"; cout << "ERROR: UNSUPPORTED S INST\n";
std::abort(); std::abort();
} }
D(3, "STORE MEM ADDRESS: " << std::hex << memAddr);
c.memAccesses.push_back(Warp::MemAccess(true, memAddr)); c.memAccesses.push_back(Warp::MemAccess(true, memAddr));
#ifdef EMU_INSTRUMENTATION #ifdef EMU_INSTRUMENTATION
Harp::OSDomain::osDomain-> Harp::OSDomain::osDomain->
@@ -752,13 +761,12 @@ void Instruction::executeOn(Warp &c, trace_inst_t * trace_inst) {
#endif #endif
break; break;
case B_INST: case B_INST:
//std::cout << "B_INST\n"; trace_inst->stall_warp = true;
trace_inst->stall_warp = true;
D(3,"func3:" << func3 << endl);
switch (func3) switch (func3)
{ {
case 0: case 0:
// BEQ // BEQ
D(3,"BEQ: r" << rsrc[0] << ", r" << rsrc[1] << ", imm=" << (int)immsrc);
if (int(reg[rsrc[0]]) == int(reg[rsrc[1]])) if (int(reg[rsrc[0]]) == int(reg[rsrc[1]]))
{ {
if (!pcSet) nextPc = (c.pc - 4) + immsrc; if (!pcSet) nextPc = (c.pc - 4) + immsrc;
@@ -767,7 +775,7 @@ void Instruction::executeOn(Warp &c, trace_inst_t * trace_inst) {
break; break;
case 1: case 1:
// BNE // BNE
D(3, "rsrc0: " << reg[rsrc[0]] << " rsrc1 : " << reg[rsrc[1]] << endl); D(3,"BNE: r" << rsrc[0] << ", r" << rsrc[1] << ", imm=" << (int)immsrc);
if (int(reg[rsrc[0]]) != int(reg[rsrc[1]])) if (int(reg[rsrc[0]]) != int(reg[rsrc[1]]))
{ {
if (!pcSet) nextPc = (c.pc - 4) + immsrc; if (!pcSet) nextPc = (c.pc - 4) + immsrc;
@@ -776,6 +784,7 @@ void Instruction::executeOn(Warp &c, trace_inst_t * trace_inst) {
break; break;
case 4: case 4:
// BLT // BLT
D(3,"BLT: r" << rsrc[0] << ", r" << rsrc[1] << ", imm=" << (int)immsrc);
if (int(reg[rsrc[0]]) < int(reg[rsrc[1]])) if (int(reg[rsrc[0]]) < int(reg[rsrc[1]]))
{ {
if (!pcSet) nextPc = (c.pc - 4) + immsrc; if (!pcSet) nextPc = (c.pc - 4) + immsrc;
@@ -784,6 +793,7 @@ void Instruction::executeOn(Warp &c, trace_inst_t * trace_inst) {
break; break;
case 5: case 5:
// BGE // BGE
D(3,"BGE: r" << rsrc[0] << ", r" << rsrc[1] << ", imm=" << (int)immsrc);
if (int(reg[rsrc[0]]) >= int(reg[rsrc[1]])) if (int(reg[rsrc[0]]) >= int(reg[rsrc[1]]))
{ {
if (!pcSet) nextPc = (c.pc - 4) + immsrc; if (!pcSet) nextPc = (c.pc - 4) + immsrc;
@@ -792,6 +802,7 @@ void Instruction::executeOn(Warp &c, trace_inst_t * trace_inst) {
break; break;
case 6: case 6:
// BLTU // BLTU
D(3,"BLTU: r" << rsrc[0] << ", r" << rsrc[1] << ", imm=" << (int)immsrc);
if (Word_u(reg[rsrc[0]]) < Word_u(reg[rsrc[1]])) if (Word_u(reg[rsrc[0]]) < Word_u(reg[rsrc[1]]))
{ {
if (!pcSet) nextPc = (c.pc - 4) + immsrc; if (!pcSet) nextPc = (c.pc - 4) + immsrc;
@@ -800,6 +811,7 @@ void Instruction::executeOn(Warp &c, trace_inst_t * trace_inst) {
break; break;
case 7: case 7:
// BGEU // BGEU
D(3,"BGEU: r" << rsrc[0] << ", r" << rsrc[1] << ", imm=" << (int)immsrc);
if (Word_u(reg[rsrc[0]]) >= Word_u(reg[rsrc[1]])) if (Word_u(reg[rsrc[0]]) >= Word_u(reg[rsrc[1]]))
{ {
if (!pcSet) nextPc = (c.pc - 4) + immsrc; if (!pcSet) nextPc = (c.pc - 4) + immsrc;
@@ -809,26 +821,25 @@ void Instruction::executeOn(Warp &c, trace_inst_t * trace_inst) {
} }
break; break;
case LUI_INST: case LUI_INST:
//std::cout << "LUI_INST\n"; D(3, "LUI: r" << rdest << " <- imm=0x" << hex << immsrc);
reg[rdest] = (immsrc << 12) & 0xfffff000; reg[rdest] = (immsrc << 12) & 0xfffff000;
break; break;
case AUIPC_INST: case AUIPC_INST:
//std::cout << "AUIPC_INST\n"; D(3, "AUIPC: r" << rdest << " <- imm=0x" << hex << immsrc);
reg[rdest] = ((immsrc << 12) & 0xfffff000) + (c.pc - 4); reg[rdest] = ((immsrc << 12) & 0xfffff000) + (c.pc - 4);
break; break;
case JAL_INST: case JAL_INST:
//std::cout << "JAL_INST\n"; D(3, "JAL: r" << rdest << " <- imm=" << (int)immsrc);
trace_inst->stall_warp = true; trace_inst->stall_warp = true;
if (!pcSet) nextPc = (c.pc - 4) + immsrc; if (!pcSet) nextPc = (c.pc - 4) + immsrc;
if (!pcSet) {/*std::cout << "JAL... SETTING PC: " << nextPc << "\n"; */} if (!pcSet) {/*std::cout << "JAL... SETTING PC: " << nextPc << "\n"; */}
if (rdest != 0) if (rdest != 0) {
{
reg[rdest] = c.pc; reg[rdest] = c.pc;
} }
pcSet = true; pcSet = true;
break; break;
case JALR_INST: case JALR_INST:
D(3, "JALR_INST\n"); D(3, "JALR: r" << rdest << " <- r" << rsrc[0] << ", imm=" << (int)immsrc);
trace_inst->stall_warp = true; trace_inst->stall_warp = true;
if (!pcSet) nextPc = reg[rsrc[0]] + immsrc; if (!pcSet) nextPc = reg[rsrc[0]] + immsrc;
if (!pcSet) {/*std::cout << "JALR... SETTING PC: " << nextPc << "\n";*/ } if (!pcSet) {/*std::cout << "JALR... SETTING PC: " << nextPc << "\n";*/ }
@@ -841,99 +852,109 @@ void Instruction::executeOn(Warp &c, trace_inst_t * trace_inst) {
case SYS_INST: case SYS_INST:
//std::cout << "SYS_INST\n"; //std::cout << "SYS_INST\n";
temp = reg[rsrc[0]]; temp = reg[rsrc[0]];
if (immsrc == 0x20) // ThreadID
{ if (!c.core->a.is_cpu_mode()) {
reg[rdest] = t; //
D(2, "CSR Reading tid " << hex << immsrc << dec << " and returning " << reg[rdest]); // GPGPU CSR extension
} else if (immsrc == 0x21) // WarpID //
{ if (immsrc == 0x20) // ThreadID
reg[rdest] = c.id; {
D(2, "CSR Reading wid " << hex << immsrc << dec << " and returning " << reg[rdest]); reg[rdest] = t;
} else if (immsrc == 0x25) D(2, "CSR Reading tid " << hex << immsrc << dec << " and returning " << reg[rdest]);
{ }
reg[rdest] = c.core->num_instructions; else if (immsrc == 0x21) // WarpID
} else if (immsrc == 0x26) {
{ reg[rdest] = c.id;
reg[rdest] = c.core->num_cycles; D(2, "CSR Reading wid " << hex << immsrc << dec << " and returning " << reg[rdest]);
}
else if (immsrc == 0x25)
{
reg[rdest] = c.core->num_instructions;
}
else if (immsrc == 0x26)
{
reg[rdest] = c.core->num_cycles;
}
} else {
switch (func3)
{
case 1:
// printf("Case 1\n");
if (rdest != 0)
{
reg[rdest] = c.csr[immsrc & 0x00000FFF];
}
c.csr[immsrc & 0x00000FFF] = temp;
break;
case 2:
// printf("Case 2\n");
if (rdest != 0)
{
// printf("Reading from CSR: %d = %d\n", (immsrc & 0x00000FFF), c.csr[immsrc & 0x00000FFF]);
reg[rdest] = c.csr[immsrc & 0x00000FFF];
}
// printf("Writing to CSR --> %d = %d\n", immsrc, (temp | c.csr[immsrc & 0x00000FFF]));
c.csr[immsrc & 0x00000FFF] = temp | c.csr[immsrc & 0x00000FFF];
break;
case 3:
// printf("Case 3\n");
if (rdest != 0)
{
reg[rdest] = c.csr[immsrc & 0x00000FFF];
}
c.csr[immsrc & 0x00000FFF] = temp & (~c.csr[immsrc & 0x00000FFF]);
break;
case 5:
// printf("Case 5\n");
if (rdest != 0)
{
reg[rdest] = c.csr[immsrc & 0x00000FFF];
}
c.csr[immsrc & 0x00000FFF] = rsrc[0];
break;
case 6:
// printf("Case 6\n");
if (rdest != 0)
{
reg[rdest] = c.csr[immsrc & 0x00000FFF];
}
c.csr[immsrc & 0x00000FFF] = rsrc[0] | c.csr[immsrc & 0x00000FFF];
break;
case 7:
// printf("Case 7\n");
if (rdest != 0)
{
reg[rdest] = c.csr[immsrc & 0x00000FFF];
}
c.csr[immsrc & 0x00000FFF] = rsrc[0] & (~c.csr[immsrc & 0x00000FFF]);
break;
case 0:
if (immsrc < 2)
{
//std::cout << "INTERRUPT ECALL/EBREAK\n";
nextActiveThreads = 0;
c.spawned = false;
// c.interrupt(0);
}
break;
default:
break;
}
} }
// switch (func3)
// {
// case 1:
// // printf("Case 1\n");
// if (rdest != 0)
// {
// reg[rdest] = c.csr[immsrc & 0x00000FFF];
// }
// c.csr[immsrc & 0x00000FFF] = temp;
// break;
// case 2:
// // printf("Case 2\n");
// if (rdest != 0)
// {
// // printf("Reading from CSR: %d = %d\n", (immsrc & 0x00000FFF), c.csr[immsrc & 0x00000FFF]);
// reg[rdest] = c.csr[immsrc & 0x00000FFF];
// }
// // printf("Writing to CSR --> %d = %d\n", immsrc, (temp | c.csr[immsrc & 0x00000FFF]));
// c.csr[immsrc & 0x00000FFF] = temp | c.csr[immsrc & 0x00000FFF];
// break;
// case 3:
// // printf("Case 3\n");
// if (rdest != 0)
// {
// reg[rdest] = c.csr[immsrc & 0x00000FFF];
// }
// c.csr[immsrc & 0x00000FFF] = temp & (~c.csr[immsrc & 0x00000FFF]);
// break;
// case 5:
// // printf("Case 5\n");
// if (rdest != 0)
// {
// reg[rdest] = c.csr[immsrc & 0x00000FFF];
// }
// c.csr[immsrc & 0x00000FFF] = rsrc[0];
// break;
// case 6:
// // printf("Case 6\n");
// if (rdest != 0)
// {
// reg[rdest] = c.csr[immsrc & 0x00000FFF];
// }
// c.csr[immsrc & 0x00000FFF] = rsrc[0] | c.csr[immsrc & 0x00000FFF];
// break;
// case 7:
// // printf("Case 7\n");
// if (rdest != 0)
// {
// reg[rdest] = c.csr[immsrc & 0x00000FFF];
// }
// c.csr[immsrc & 0x00000FFF] = rsrc[0] & (~c.csr[immsrc & 0x00000FFF]);
// break;
// case 0:
// if (immsrc < 2)
// {
// //std::cout << "INTERRUPT ECALL/EBREAK\n";
// nextActiveThreads = 0;
// c.spawned = false;
// // c.interrupt(0);
// }
// break;
// default:
// break;
// }
break; break;
case TRAP: case TRAP:
//std::cout << "INTERRUPT TRAP\n"; D(3, "TRAP");
nextActiveThreads = 0; nextActiveThreads = 0;
c.interrupt(0); c.interrupt(0);
break; break;
case FENCE: case FENCE:
//std::cout << "FENCE_INST\n"; D(3, "FENCE");
break; break;
case PJ_INST: case PJ_INST:
// pred jump reg // pred jump reg
@@ -950,13 +971,13 @@ void Instruction::executeOn(Warp &c, trace_inst_t * trace_inst) {
{ {
case 1: case 1:
// WSPAWN // WSPAWN
D(3, "WSPAWN\n"); D(3, "WSPAWN");
trace_inst->wspawn = true; trace_inst->wspawn = true;
if (sjOnce) if (sjOnce)
{ {
sjOnce = false; sjOnce = false;
// //std::cout << "SIZE: " << c.core->w.size() << "\n"; // //std::cout << "SIZE: " << c.core->w.size() << "\n";
num_to_wspawn = reg[rsrc[0]]; num_to_wspawn = std::min<unsigned>(reg[rsrc[0]], c.core->a.getNWarps());
D(0, "Spawning " << num_to_wspawn << " new warps at PC: " << hex << reg[rsrc[1]]); D(0, "Spawning " << num_to_wspawn << " new warps at PC: " << hex << reg[rsrc[1]]);
for (unsigned i = 1; i < num_to_wspawn; ++i) for (unsigned i = 1; i < num_to_wspawn; ++i)
@@ -992,7 +1013,7 @@ void Instruction::executeOn(Warp &c, trace_inst_t * trace_inst) {
case 2: case 2:
{ {
// SPLIT // SPLIT
//std::cout << "SPLIT\n"; D(3, "SPLIT");
trace_inst->stall_warp = true; trace_inst->stall_warp = true;
if (sjOnce) if (sjOnce)
{ {
@@ -1025,8 +1046,7 @@ void Instruction::executeOn(Warp &c, trace_inst_t * trace_inst) {
} }
case 3: case 3:
// JOIN // JOIN
//std::cout << "JOIN\n"; D(3, "JOIN");
D(3, "JOIN INSTRUCTION");
if (sjOnce) if (sjOnce)
{ {
sjOnce = false; sjOnce = false;
@@ -1062,9 +1082,9 @@ void Instruction::executeOn(Warp &c, trace_inst_t * trace_inst) {
break; break;
case 0: case 0:
// TMC // TMC
//std::cout << "JALRS\n"; D(3, "TMC");
trace_inst->stall_warp = true; trace_inst->stall_warp = true;
nextActiveThreads = reg[rsrc[0]]; nextActiveThreads = std::min<unsigned>(reg[rsrc[0]], c.core->a.getNThds());
{ {
for (int ff = 0; ff < c.tmask.size(); ff++) for (int ff = 0; ff < c.tmask.size(); ff++)
{ {
@@ -2418,8 +2438,6 @@ void Instruction::executeOn(Warp &c, trace_inst_t * trace_inst) {
// std::cout << "finished instruction" << endl << flush; // std::cout << "finished instruction" << endl << flush;
D(3, "End instruction execute." << flush);
c.activeThreads = nextActiveThreads; c.activeThreads = nextActiveThreads;
// if (nextActiveThreads != 0) // if (nextActiveThreads != 0)
@@ -2430,8 +2448,6 @@ void Instruction::executeOn(Warp &c, trace_inst_t * trace_inst) {
// } // }
// } // }
// //std::cout << "new thread mask: "; // //std::cout << "new thread mask: ";
// for (int i = 0; i < c.tmask.size(); ++i) //std::cout << " " << c.tmask[i]; // for (int i = 0; i < c.tmask.size(); ++i) //std::cout << " " << c.tmask[i];
// //std::cout << "\n"; // //std::cout << "\n";

View File

@@ -280,6 +280,120 @@ void DiskControllerMemDevice::write(Addr a, Word w) {
} }
} }
static uint32_t hti_old(char c) {
if (c >= 'A' && c <= 'F')
return c - 'A' + 10;
if (c >= 'a' && c <= 'f')
return c - 'a' + 10;
return c - '0';
}
static uint32_t hToI_old(char *c, uint32_t size) {
uint32_t value = 0;
for (uint32_t i = 0; i < size; i++) {
value += hti_old(c[i]) << ((size - i - 1) * 4);
}
return value;
}
void RAM::loadHexImpl(std::string path) {
this->clear();
FILE *fp = fopen(&path[0], "r");
if(fp == 0){
std::cout << path << " not found" << std::endl;
}
//Preload 0x0 <-> 0x80000000 jumps
((uint32_t*)this->get(0))[0] = 0xf1401073;
((uint32_t*)this->get(0))[1] = 0xf1401073;
((uint32_t*)this->get(0))[2] = 0x30101073;
((uint32_t*)this->get(0))[3] = 0x800000b7;
((uint32_t*)this->get(0))[4] = 0x000080e7;
((uint32_t*)this->get(0x80000000))[0] = 0x00000097;
((uint32_t*)this->get(0xb0000000))[0] = 0x01C02023;
((uint32_t*)this->get(0xf00fff10))[0] = 0x12345678;
((uint32_t*)this->get(0x70000000))[0] = 0x00008067;
{
uint32_t init_addr = 0x70000004;
for (int off = 0; off < 1024; off+=4) {
uint32_t new_addr = init_addr+off;
((uint32_t*)this->get(new_addr))[0] = 0x00000000;
}
}
{
uint32_t init_addr = 0x71000000;
for (int off = 0; off < 1024; off+=4) {
uint32_t new_addr = init_addr+off;
((uint32_t*)this->get(new_addr))[0] = 0x00000000;
}
}
{
uint32_t init_addr = 0x72000000;
for (int off = 0; off < 1024; off+=4) {
uint32_t new_addr = init_addr+off;
((uint32_t*)this->get(new_addr))[0] = 0x00000000;
}
}
fseek(fp, 0, SEEK_END);
uint32_t size = ftell(fp);
fseek(fp, 0, SEEK_SET);
char* content = new char[size];
int x = fread(content, 1, size, fp);
if (!x) {
std::cout << "COULD NOT READ FILE\n"; std::abort();
}
int offset = 0;
char* line = content;
// std::cout << "WHTA\n";
while (1) {
if (line[0] == ':') {
uint32_t byteCount = hToI_old(line + 1, 2);
uint32_t nextAddr = hToI_old(line + 3, 4) + offset;
uint32_t key = hToI_old(line + 7, 2);
switch (key) {
case 0:
for (uint32_t i = 0; i < byteCount; i++) {
unsigned add = nextAddr + i;
*(this->get(add)) = hToI_old(line + 9 + i * 2, 2);
// std::cout << "lhi: Address: " << std::hex <<(add) << "\tValue: " << std::hex << hToI_old(line + 9 + i * 2, 2) << std::endl;
}
break;
case 2:
// cout << offset << endl;
offset = hToI_old(line + 9, 4) << 4;
break;
case 4:
// cout << offset << endl;
offset = hToI_old(line + 9, 4) << 16;
break;
default:
// cout << "??? " << key << endl;
break;
}
}
while (*line != '\n' && size != 0) {
line++;
size--;
}
if (size <= 1)
break;
line++;
size--;
}
if (content)
delete[] content;
}

View File

@@ -55,40 +55,46 @@ HarpToolMode findMode(int argc, char** argv) {
} }
int emu_main(int argc, char **argv) { int emu_main(int argc, char **argv) {
string archString("rv32i"), imgFileName("a.dsfsdout.bin"); string archString("rv32i");
bool showHelp, showStats, basicMachine, batch; string imgFileName("a.dsfsdout.bin");
bool showHelp(false), showStats(false), basicMachine(true);
bool cpu_mode(false);
int max_warps(32);
int max_threads(32);
/* Read the command line arguments. */ /* Read the command line arguments. */
CommandLineArgFlag fh("-h", "--help", "", showHelp); CommandLineArgFlag fh("-h", "--help", "", showHelp);
CommandLineArgSetter<string>fc("-c", "--core", "", imgFileName); CommandLineArgSetter<string>fc("-c", "--core", "", imgFileName);
CommandLineArgSetter<string>fa("-a", "--arch", "", archString); CommandLineArgSetter<string>fa("-a", "--arch", "", archString);
CommandLineArgFlag fs("-s", "--stats", "", showStats); CommandLineArgFlag fs("-s", "--stats", "", showStats);
CommandLineArgFlag fb("-b", "--basic", "", basicMachine); CommandLineArgFlag fb("-b", "--basic", "", basicMachine);
CommandLineArgFlag fi("-i", "--batch", "", batch); CommandLineArgFlag fx("-x", "--cpu", "", cpu_mode);
CommandLineArgSetter<int> fw("-w", "--warps", "", max_warps);
CommandLineArg::readArgs(argc, argv); CommandLineArgSetter<int> ft("-t", "--threads", "", max_threads);
if (showHelp) {
cout << Help::emuHelp; CommandLineArg::readArgs(argc, argv);
return 0;
} if (showHelp) {
cout << Help::emuHelp;
return 0;
}
/* Instantiate a Core, RAM, and console output. */ /* Instantiate a Core, RAM, and console output. */
ArchDef arch(archString); ArchDef arch(archString, cpu_mode, max_warps, max_threads);
Decoder *dec; Decoder *dec;
switch (arch.getEncChar()) { switch (arch.getEncChar()) {
case 'b': dec = new WordDecoder(arch); break; case 'b': dec = new WordDecoder(arch); break;
case 'w': dec = new WordDecoder(arch); break; case 'w': dec = new WordDecoder(arch); break;
case 'r': dec = new WordDecoder(arch); break; case 'r': dec = new WordDecoder(arch); break;
default: default:
cout << "Unrecognized decoder type: '" << arch.getEncChar() << "'.\n"; cout << "Unrecognized decoder type: '" << arch.getEncChar() << "'.\n";
return 1; return 1;
} }
// std::cout << "TESTING: " << tests[t] << "\n"; // std::cout << "TESTING: " << tests[t] << "\n";
MemoryUnit mu(4096, arch.getWordSize(), basicMachine); MemoryUnit mu(4096, arch.getWordSize(), basicMachine);
Core core(arch, *dec, mu/*, ID in multicore implementations*/); Core core(arch, *dec, mu/*, ID in multicore implementations*/);

View File

@@ -1,7 +1,141 @@
make
cd obj_dir
echo start > results.txt echo start > results.txt
# echo ../kernel/vortex_test.hex echo ./riscv_tests/rv32ui-p-add.hex >> results.txt
make ./Vcache_simX -E --cpu -a rv32i --core ../riscv_tests/rv32ui-p-add.hex -s -b >> results.txt
printf "Fasten your seatbelts ladies and gentelmen!!\n\n\n\n"
#cd obj_dir && ./Vcache_simX -E -a rv32i --core ../../runtime/mains/simple/vx_simple_main.hex -s -b 1> emulator.debug echo ./riscv_tests/rv32ui-p-addi.hex >> results.txt
cd obj_dir && ./Vcache_simX -E -a rv32i --core /home/priya/Desktop/new_vortex/Vortex/rvvector/benchmark_temp/vx_vec_benchmark.hex -s -b 1> emulator.debug ./Vcache_simX -E --cpu -a rv32i --core ../riscv_tests/rv32ui-p-addi.hex -s -b >> results.txt
echo ./riscv_tests/rv32ui-p-and.hex >> results.txt
./Vcache_simX -E --cpu -a rv32i --core ../riscv_tests/rv32ui-p-and.hex -s -b >> results.txt
echo ./riscv_tests/rv32ui-p-andi.hex >> results.txt
./Vcache_simX -E --cpu -a rv32i --core ../riscv_tests/rv32ui-p-andi.hex -s -b >> results.txt
echo ./riscv_tests/rv32ui-p-auipc.hex >> results.txt
./Vcache_simX -E --cpu -a rv32i --core ../riscv_tests/rv32ui-p-auipc.hex -s -b >> results.txt
echo ./riscv_tests/rv32ui-p-beq.hex >> results.txt
./Vcache_simX -E --cpu -a rv32i --core ../riscv_tests/rv32ui-p-beq.hex -s -b >> results.txt
echo ./riscv_tests/rv32ui-p-bge.hex >> results.txt
./Vcache_simX -E --cpu -a rv32i --core ../riscv_tests/rv32ui-p-bge.hex -s -b >> results.txt
echo ./riscv_tests/rv32ui-p-bgeu.hex >> results.txt
./Vcache_simX -E --cpu -a rv32i --core ../riscv_tests/rv32ui-p-bgeu.hex -s -b >> results.txt
echo ./riscv_tests/rv32ui-p-blt.hex >> results.txt
./Vcache_simX -E --cpu -a rv32i --core ../riscv_tests/rv32ui-p-blt.hex -s -b >> results.txt
echo ./riscv_tests/rv32ui-p-bltu.hex >> results.txt
./Vcache_simX -E --cpu -a rv32i --core ../riscv_tests/rv32ui-p-bltu.hex -s -b >> results.txt
echo ./riscv_tests/rv32ui-p-bne.hex >> results.txt
./Vcache_simX -E --cpu -a rv32i --core ../riscv_tests/rv32ui-p-bne.hex -s -b >> results.txt
echo ./riscv_tests/rv32ui-p-jal.hex >> results.txt
./Vcache_simX -E --cpu -a rv32i --core ../riscv_tests/rv32ui-p-jal.hex -s -b >> results.txt
echo ./riscv_tests/rv32ui-p-jalr.hex >> results.txt
./Vcache_simX -E --cpu -a rv32i --core ../riscv_tests/rv32ui-p-jalr.hex -s -b >> results.txt
echo ./riscv_tests/rv32ui-p-lb.hex >> results.txt
./Vcache_simX -E --cpu -a rv32i --core ../riscv_tests/rv32ui-p-lb.hex -s -b >> results.txt
echo ./riscv_tests/rv32ui-p-lbu.hex >> results.txt
./Vcache_simX -E --cpu -a rv32i --core ../riscv_tests/rv32ui-p-lbu.hex -s -b >> results.txt
echo ./riscv_tests/rv32ui-p-lh.hex >> results.txt
./Vcache_simX -E --cpu -a rv32i --core ../riscv_tests/rv32ui-p-lh.hex -s -b >> results.txt
echo ./riscv_tests/rv32ui-p-lhu.hex >> results.txt
./Vcache_simX -E --cpu -a rv32i --core ../riscv_tests/rv32ui-p-lhu.hex -s -b >> results.txt
echo ./riscv_tests/rv32ui-p-lui.hex >> results.txt
./Vcache_simX -E --cpu -a rv32i --core ../riscv_tests/rv32ui-p-lui.hex -s -b >> results.txt
echo ./riscv_tests/rv32ui-p-lw.hex >> results.txt
./Vcache_simX -E --cpu -a rv32i --core ../riscv_tests/rv32ui-p-lw.hex -s -b >> results.txt
echo ./riscv_tests/rv32ui-p-or.hex >> results.txt
./Vcache_simX -E --cpu -a rv32i --core ../riscv_tests/rv32ui-p-or.hex -s -b >> results.txt
echo ./riscv_tests/rv32ui-p-ori.hex >> results.txt
./Vcache_simX -E --cpu -a rv32i --core ../riscv_tests/rv32ui-p-ori.hex -s -b >> results.txt
echo ./riscv_tests/rv32ui-p-sb.hex >> results.txt
./Vcache_simX -E --cpu -a rv32i --core ../riscv_tests/rv32ui-p-sb.hex -s -b >> results.txt
echo ./riscv_tests/rv32ui-p-sh.hex >> results.txt
./Vcache_simX -E --cpu -a rv32i --core ../riscv_tests/rv32ui-p-sh.hex -s -b >> results.txt
echo ./riscv_tests/rv32ui-p-simple.hex >> results.txt
./Vcache_simX -E --cpu -a rv32i --core ../riscv_tests/rv32ui-p-simple.hex -s -b >> results.txt
echo ./riscv_tests/rv32ui-p-sll.hex >> results.txt
./Vcache_simX -E --cpu -a rv32i --core ../riscv_tests/rv32ui-p-sll.hex -s -b >> results.txt
echo ./riscv_tests/rv32ui-p-slli.hex >> results.txt
./Vcache_simX -E --cpu -a rv32i --core ../riscv_tests/rv32ui-p-slli.hex -s -b >> results.txt
echo ./riscv_tests/rv32ui-p-slt.hex >> results.txt
./Vcache_simX -E --cpu -a rv32i --core ../riscv_tests/rv32ui-p-slt.hex -s -b >> results.txt
echo ./riscv_tests/rv32ui-p-slti.hex >> results.txt
./Vcache_simX -E --cpu -a rv32i --core ../riscv_tests/rv32ui-p-slti.hex -s -b >> results.txt
echo ./riscv_tests/rv32ui-p-sltiu.hex >> results.txt
./Vcache_simX -E --cpu -a rv32i --core ../riscv_tests/rv32ui-p-sltiu.hex -s -b >> results.txt
echo ./riscv_tests/rv32ui-p-sltu.hex >> results.txt
./Vcache_simX -E --cpu -a rv32i --core ../riscv_tests/rv32ui-p-sltu.hex -s -b >> results.txt
echo ./riscv_tests/rv32ui-p-sra.hex >> results.txt
./Vcache_simX -E --cpu -a rv32i --core ../riscv_tests/rv32ui-p-sra.hex -s -b >> results.txt
echo ./riscv_tests/rv32ui-p-srai.hex >> results.txt
./Vcache_simX -E --cpu -a rv32i --core ../riscv_tests/rv32ui-p-srai.hex -s -b >> results.txt
echo ./riscv_tests/rv32ui-p-srl.hex >> results.txt
./Vcache_simX -E --cpu -a rv32i --core ../riscv_tests/rv32ui-p-srl.hex -s -b >> results.txt
echo ./riscv_tests/rv32ui-p-srli.hex >> results.txt
./Vcache_simX -E --cpu -a rv32i --core ../riscv_tests/rv32ui-p-srli.hex -s -b >> results.txt
echo ./riscv_tests/rv32ui-p-sub.hex >> results.txt
./Vcache_simX -E --cpu -a rv32i --core ../riscv_tests/rv32ui-p-sub.hex -s -b >> results.txt
echo ./riscv_tests/rv32ui-p-sw.hex >> results.txt
./Vcache_simX -E --cpu -a rv32i --core ../riscv_tests/rv32ui-p-sw.hex -s -b >> results.txt
echo ./riscv_tests/rv32ui-p-xor.hex >> results.txt
./Vcache_simX -E --cpu -a rv32i --core ../riscv_tests/rv32ui-p-xor.hex -s -b >> results.txt
echo ./riscv_tests/rv32ui-p-xori.hex >> results.txt
./Vcache_simX -E --cpu -a rv32i --core ../riscv_tests/rv32ui-p-xori.hex -s -b >> results.txt
# echo ./riscv_tests/rv32um-p-div.hex >> results.txt
# ./Vcache_simX -E --cpu -a rv32i --core ../riscv_tests/rv32um-p-div.hex -s -b >> results.txt
# echo ./riscv_tests/rv32um-p-divu.hex >> results.txt
# ./Vcache_simX -E --cpu -a rv32i --core ../riscv_tests/rv32um-p-divu.hex -s -b >> results.txt
# echo ./riscv_tests/rv32um-p-mul.hex >> results.txt
# ./Vcache_simX -E --cpu -a rv32i --core ../riscv_tests/rv32um-p-mul.hex -s -b >> results.txt
# echo ./riscv_tests/rv32um-p-mulh.hex >> results.txt
# ./Vcache_simX -E --cpu -a rv32i --core ../riscv_tests/rv32um-p-mulh.hex -s -b >> results.txt
# echo ./riscv_tests/rv32um-p-mulhsu.hex >> results.txt
# ./Vcache_simX -E --cpu -a rv32i --core ../riscv_tests/rv32um-p-mulhsu.hex -s -b >> results.txt
# echo ./riscv_tests/rv32um-p-mulhu.hex >> results.txt
# ./Vcache_simX -E --cpu -a rv32i --core ../riscv_tests/rv32um-p-mulhu.hex -s -b >> results.txt
# echo ./riscv_tests/rv32um-p-rem.hex >> results.txt
# ./Vcache_simX -E --cpu -a rv32i --core ../riscv_tests/rv32um-p-rem.hex -s -b >> results.txt
# echo ./riscv_tests/rv32um-p-remu.hex >> results.txt
# ./Vcache_simX -E --cpu -a rv32i --core ../riscv_tests/rv32um-p-remu.hex -s -b >> results.txt