Added some qsim support
git-svn-id: http://www.cdkersey.com/harp/harptool@77 0246edb2-e076-4747-b392-db732a341fa2
This commit is contained in:
@@ -5,7 +5,7 @@ CXXFLAGS=-g -fPIC
|
|||||||
|
|
||||||
LIB_OBJS=args.o obj.o mem.o core.o instruction.o enc.o util.o lex.yy.o
|
LIB_OBJS=args.o obj.o mem.o core.o instruction.o enc.o util.o lex.yy.o
|
||||||
|
|
||||||
all: harptool libharplib.so libharplib.a qsim-harp.so
|
all: harptool libharplib.so libharplib.a libqsim-harp.so
|
||||||
|
|
||||||
# Use -static so we don't have to install the library in order to just run
|
# Use -static so we don't have to install the library in order to just run
|
||||||
# Harptool.
|
# Harptool.
|
||||||
@@ -29,8 +29,8 @@ core.o : core.cpp include/types.h include/util.h include/mem.h include/archdef.h
|
|||||||
|
|
||||||
QSIM_CXXFLAGS=-DEMU_INSTRUMENTATION
|
QSIM_CXXFLAGS=-DEMU_INSTRUMENTATION
|
||||||
|
|
||||||
qsim-harp.so: args.cpp enc.cpp instruction.cpp obj.cpp util.cpp mem.cpp core.cpp qsim-harp.cpp include/qsim-harp.h include/types.h include/core.h include/util.h include/enc.h include/archdef.h include/instruction.h include/asm-tokens.h include/mem.h
|
libqsim-harp.so: args.cpp enc.cpp instruction.cpp obj.cpp util.cpp mem.cpp core.cpp qsim-harp.cpp lex.yy.o include/qsim-harp.h include/types.h include/core.h include/util.h include/enc.h include/archdef.h include/instruction.h include/asm-tokens.h include/mem.h
|
||||||
$(CXX) $(CXXFLAGS) $(QSIM_CXXFLAGS) -shared -o $@ args.cpp enc.cpp instruction.cpp obj.cpp util.cpp mem.cpp core.cpp qsim-harp.cpp
|
$(CXX) $(CXXFLAGS) $(QSIM_CXXFLAGS) -shared -o $@ args.cpp enc.cpp instruction.cpp obj.cpp util.cpp mem.cpp core.cpp qsim-harp.cpp lex.yy.o
|
||||||
|
|
||||||
|
|
||||||
lex.yy.cc: scanner.lex
|
lex.yy.cc: scanner.lex
|
||||||
|
|||||||
19
src/core.cpp
19
src/core.cpp
@@ -30,19 +30,26 @@ void Harp::reg_doWrite(Word cpuId, Word regNum) {
|
|||||||
|
|
||||||
Core::Core(const ArchDef &a, Decoder &d, MemoryUnit &mem, Word id) :
|
Core::Core(const ArchDef &a, Decoder &d, MemoryUnit &mem, Word id) :
|
||||||
a(a), iDec(d), mem(mem), pc(0), interruptEnable(false), supervisorMode(true),
|
a(a), iDec(d), mem(mem), pc(0), interruptEnable(false), supervisorMode(true),
|
||||||
activeThreads(1), reg(0), pred(0), shadowReg(a.getNRegs()), shadowPReg(a.getNPRegs()),
|
activeThreads(1), reg(0), pred(0), shadowReg(a.getNRegs()),
|
||||||
interruptEntry(0), id(id)
|
shadowPReg(a.getNPRegs()), interruptEntry(0), id(id)
|
||||||
{
|
{
|
||||||
/* Build the register file. */
|
/* Build the register file. */
|
||||||
Word regNum(0);
|
Word regNum(0);
|
||||||
for (Word j = 0; j < a.getNThds(); ++j) {
|
for (Word j = 0; j < a.getNThds(); ++j) {
|
||||||
|
std::cout << "Pushing back a new register vector.\n";
|
||||||
reg.push_back(vector<Reg<Word> >(0));
|
reg.push_back(vector<Reg<Word> >(0));
|
||||||
for (Word i = 0; i < a.getNRegs(); ++i)
|
for (Word i = 0; i < a.getNRegs(); ++i) {
|
||||||
|
std::cout << "Pushing back a new register in thread " << j << "\n";
|
||||||
reg[j].push_back(Reg<Word>(id, regNum++));
|
reg[j].push_back(Reg<Word>(id, regNum++));
|
||||||
|
}
|
||||||
|
|
||||||
pred.push_back(vector<Reg<bool> >(0));
|
pred.push_back(vector<Reg<bool> >(0));
|
||||||
for (Word i = 0; i < a.getNPRegs(); ++i)
|
std::cout << "getnpregs returns " << a.getNPRegs() << '\n';
|
||||||
|
for (Word i = 0; i < a.getNPRegs(); ++i) {
|
||||||
|
std::cout << "Pushing back predicate reg " << i << ", thread " << j
|
||||||
|
<< "\n";
|
||||||
pred[j].push_back(Reg<bool>(id, regNum++));
|
pred[j].push_back(Reg<bool>(id, regNum++));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Set initial register contents. */
|
/* Set initial register contents. */
|
||||||
@@ -55,6 +62,8 @@ void Core::step() {
|
|||||||
|
|
||||||
if (activeThreads == 0) return;
|
if (activeThreads == 0) return;
|
||||||
|
|
||||||
|
cout << "in step pc=0x" << hex << pc << '\n';
|
||||||
|
|
||||||
/* Fetch and decode. */
|
/* Fetch and decode. */
|
||||||
if (wordSize < sizeof(pc)) pc &= ((1ll<<(wordSize*8))-1);
|
if (wordSize < sizeof(pc)) pc &= ((1ll<<(wordSize*8))-1);
|
||||||
Instruction *inst;
|
Instruction *inst;
|
||||||
@@ -78,7 +87,9 @@ void Core::step() {
|
|||||||
interrupt(pf.notFound?1:2);
|
interrupt(pf.notFound?1:2);
|
||||||
}
|
}
|
||||||
} while (fetchMore);
|
} while (fetchMore);
|
||||||
|
cout << "Fetched at 0x" << hex << pc << '\n';
|
||||||
//cout << "0x" << hex << pc << ": " << *inst << '\n';
|
//cout << "0x" << hex << pc << ": " << *inst << '\n';
|
||||||
|
cout << "sizeof(core)=" << dec << sizeof(*this) << '\n';
|
||||||
|
|
||||||
#ifdef EMU_INSTRUMENTATION
|
#ifdef EMU_INSTRUMENTATION
|
||||||
{ Addr pcPhys(mem.virtToPhys(pc));
|
{ Addr pcPhys(mem.virtToPhys(pc));
|
||||||
|
|||||||
@@ -344,7 +344,7 @@ Instruction *WordDecoder::decode(const std::vector<Byte> &v, Size &idx) {
|
|||||||
inst.setImmRef(*r);
|
inst.setImmRef(*r);
|
||||||
}
|
}
|
||||||
|
|
||||||
//cout << "Decoded 0x" << hex << code << " into: " << inst << '\n';
|
cout << "Decoded 0x" << hex << code << " into: " << inst << '\n';
|
||||||
|
|
||||||
return &inst;
|
return &inst;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,6 +4,7 @@
|
|||||||
#ifndef __ARCHDEF_H
|
#ifndef __ARCHDEF_H
|
||||||
#define __ARCHDEF_H
|
#define __ARCHDEF_H
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
|
|
||||||
@@ -15,6 +16,7 @@ namespace Harp {
|
|||||||
struct Undefined {};
|
struct Undefined {};
|
||||||
|
|
||||||
ArchDef(const std::string &s) {
|
ArchDef(const std::string &s) {
|
||||||
|
std::cout << "New archdef for \"" << s << "\"\n";
|
||||||
std::istringstream iss(s.c_str());
|
std::istringstream iss(s.c_str());
|
||||||
|
|
||||||
iss >> wordSize;
|
iss >> wordSize;
|
||||||
@@ -29,6 +31,8 @@ namespace Harp {
|
|||||||
iss >> sep >> nThds;
|
iss >> sep >> nThds;
|
||||||
if (!iss || sep != '/') { extent = EXT_PREGS; return; }
|
if (!iss || sep != '/') { extent = EXT_PREGS; return; }
|
||||||
extent = EXT_THDS;
|
extent = EXT_THDS;
|
||||||
|
|
||||||
|
std::cout << nRegs << " regs, " << nPRegs << " pred regs.\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
operator std::string () const {
|
operator std::string () const {
|
||||||
|
|||||||
@@ -50,7 +50,7 @@ namespace Harp {
|
|||||||
bool getSupervisorMode() const { return supervisorMode; }
|
bool getSupervisorMode() const { return supervisorMode; }
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
private:
|
// private:
|
||||||
const ArchDef a;
|
const ArchDef a;
|
||||||
Decoder &iDec;
|
Decoder &iDec;
|
||||||
MemoryUnit &mem;
|
MemoryUnit &mem;
|
||||||
|
|||||||
@@ -1,6 +1,10 @@
|
|||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
HARPtools by Chad D. Kersey, Summer 2011
|
HARPtools by Chad D. Kersey, Summer 2011
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
|
#ifndef EMU_INSTRUMENTATION
|
||||||
|
#define EMU_INSTRUMENTATION
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifndef __QSIM_HARP_H
|
#ifndef __QSIM_HARP_H
|
||||||
#define __QSIM_HARP_H
|
#define __QSIM_HARP_H
|
||||||
|
|
||||||
@@ -131,7 +135,8 @@ namespace Harp {
|
|||||||
class Cpu {
|
class Cpu {
|
||||||
public:
|
public:
|
||||||
Cpu(Harp::OSDomain &osd);
|
Cpu(Harp::OSDomain &osd);
|
||||||
~Cpu() { delete dec; delete core; }
|
Cpu(): dec(NULL), core(NULL) {}
|
||||||
|
~Cpu() { if (dec) delete dec; if (core) delete core; }
|
||||||
|
|
||||||
bool idle() const { return false; }
|
bool idle() const { return false; }
|
||||||
int get_tid() const { return 0; }
|
int get_tid() const { return 0; }
|
||||||
@@ -140,9 +145,9 @@ namespace Harp {
|
|||||||
void interrupt(int vec) { core->interrupt(vec); }
|
void interrupt(int vec) { core->interrupt(vec); }
|
||||||
bool booted() const { return core->running(); }
|
bool booted() const { return core->running(); }
|
||||||
|
|
||||||
|
Harp::OSDomain *osd;
|
||||||
Harp::Decoder *dec;
|
Harp::Decoder *dec;
|
||||||
Harp::Core *core;
|
Harp::Core *core;
|
||||||
Harp::OSDomain *osd;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
Harp::ArchDef arch;
|
Harp::ArchDef arch;
|
||||||
|
|||||||
@@ -7,15 +7,16 @@
|
|||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
using namespace Harp;
|
using namespace Harp;
|
||||||
|
using namespace Qsim;
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
Harp::OSDomain* Harp::OSDomain::osDomain(NULL);
|
Harp::OSDomain* Harp::OSDomain::osDomain(NULL);
|
||||||
|
|
||||||
Harp::OSDomain::OSDomain(ArchDef &arch, string imgFile) :
|
Harp::OSDomain::OSDomain(ArchDef &archref, string imgFile) :
|
||||||
/* TODO: Move the mu to the Cpu. They're sharing a TLB now! */
|
/* TODO: Move the mu to the Cpu. They're sharing a TLB now! */
|
||||||
arch(arch), mu(4096, arch.getWordSize()),
|
arch(archref), mu(4096, arch.getWordSize()),
|
||||||
ram(imgFile.c_str(), arch.getWordSize()),
|
ram(imgFile.c_str(), arch.getWordSize()),
|
||||||
cpus()
|
cpus(0)
|
||||||
{
|
{
|
||||||
if (osDomain != NULL) {
|
if (osDomain != NULL) {
|
||||||
cout << "Error: OSDomain is a singleton.";
|
cout << "Error: OSDomain is a singleton.";
|
||||||
@@ -23,6 +24,9 @@ Harp::OSDomain::OSDomain(ArchDef &arch, string imgFile) :
|
|||||||
}
|
}
|
||||||
osDomain = this;
|
osDomain = this;
|
||||||
|
|
||||||
|
std::cout << "Constructing an OSDomain with archref, " << archref.getNPRegs() << '\n';
|
||||||
|
|
||||||
|
std::cout << "Pushing back a Cpu in OSDomain constructor.\n";
|
||||||
cpus.push_back(Cpu(*this));
|
cpus.push_back(Cpu(*this));
|
||||||
|
|
||||||
console = new ConsoleMemDevice(arch.getWordSize(), cout, *cpus[0].core);
|
console = new ConsoleMemDevice(arch.getWordSize(), cout, *cpus[0].core);
|
||||||
@@ -33,6 +37,7 @@ Harp::OSDomain::OSDomain(ArchDef &arch, string imgFile) :
|
|||||||
|
|
||||||
void Harp::OSDomain::connect_console(std::ostream &s) {
|
void Harp::OSDomain::connect_console(std::ostream &s) {
|
||||||
/* For now this does nothing. ConsoleMemDevice is not redirectable. */
|
/* For now this does nothing. ConsoleMemDevice is not redirectable. */
|
||||||
|
std::cout << "in connect_console\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
Harp::OSDomain::Cpu::Cpu(Harp::OSDomain &o) :
|
Harp::OSDomain::Cpu::Cpu(Harp::OSDomain &o) :
|
||||||
@@ -40,10 +45,13 @@ Harp::OSDomain::Cpu::Cpu(Harp::OSDomain &o) :
|
|||||||
osd(&o), dec(new WordDecoder(osd->arch)),
|
osd(&o), dec(new WordDecoder(osd->arch)),
|
||||||
core(new Core(osd->arch, *dec, osd->mu))
|
core(new Core(osd->arch, *dec, osd->mu))
|
||||||
{
|
{
|
||||||
|
std::cout << "Constructing a new Cpu.\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
uint64_t Harp::OSDomain::Cpu::run(uint64_t n) {
|
uint64_t Harp::OSDomain::Cpu::run(uint64_t n) {
|
||||||
uint64_t i;
|
uint64_t i;
|
||||||
|
std::cout << "pc=0x" << std::hex << core->pc << ", " << std::dec << sizeof(*core) << '\n';
|
||||||
|
//osd->console->poll();
|
||||||
for (i = 0; i < n; ++i) core->step();
|
for (i = 0; i < n; ++i) core->step();
|
||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
|
|||||||
25
src/unit_test/qsim_test.cpp
Normal file
25
src/unit_test/qsim_test.cpp
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
#include <iostream>
|
||||||
|
#include <iomanip>
|
||||||
|
#include "include/qsim-harp.h"
|
||||||
|
|
||||||
|
class CallbackAdaptor {
|
||||||
|
public:
|
||||||
|
void inst_cb(int c, uint64_t v, uint64_t p, uint8_t l, const uint8_t *b,
|
||||||
|
enum inst_type t)
|
||||||
|
{
|
||||||
|
std::cout << "Inst @ 0x" << std::hex << v << "(0x" << p << ")\n";
|
||||||
|
}
|
||||||
|
} cba;
|
||||||
|
|
||||||
|
int main(int argc, char** argv) {
|
||||||
|
Harp::ArchDef arch("8w32/32/8");
|
||||||
|
Harp::OSDomain osd(arch, std::string("../test/sieve.bin"));
|
||||||
|
|
||||||
|
osd.set_inst_cb(&cba, &CallbackAdaptor::inst_cb);
|
||||||
|
|
||||||
|
for (unsigned i = 0; i < 1000; ++i) {
|
||||||
|
osd.run(0, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user