Separated warp and core in preparation for wspawn support.

This commit is contained in:
cdkersey
2015-08-04 10:58:53 -06:00
parent e243c4c6d6
commit 3011e4e757
4 changed files with 68 additions and 28 deletions

View File

@@ -29,21 +29,45 @@ void Harp::reg_doWrite(Word cpuId, Word regNum) {
} }
#endif #endif
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)
activeThreads(1), reg(0), pred(0), shadowReg(a.getNRegs()), {
shadowPReg(a.getNPRegs()), interruptEntry(0), id(id) w.push_back(Warp(this));
// TODO: core-level initialization
}
bool Core::interrupt(Word r0) {
w[0].interrupt(r0);
}
void Core::step() {
for (unsigned i = 0; i < w.size(); ++i)
w[i].step();
}
bool Core::running() const {
for (unsigned i = 0; i < w.size(); ++i)
if (!w[i].running()) return false;
return true;
}
Warp::Warp(Core *c, Word id) :
core(c), pc(0), interruptEnable(false),
supervisorMode(true), activeThreads(1), reg(0), pred(0),
shadowReg(core->a.getNRegs()), shadowPReg(core->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 < core->a.getNThds(); ++j) {
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 < core->a.getNRegs(); ++i) {
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) { for (Word i = 0; i < core->a.getNPRegs(); ++i) {
pred[j].push_back(Reg<bool>(id, regNum++)); pred[j].push_back(Reg<bool>(id, regNum++));
} }
@@ -52,11 +76,11 @@ Core::Core(const ArchDef &a, Decoder &d, MemoryUnit &mem, Word id) :
} }
/* Set initial register contents. */ /* Set initial register contents. */
reg[0][0] = (a.getNThds()<<(a.getWordSize()*8 / 2)) | id; reg[0][0] = (core->a.getNThds()<<(core->a.getWordSize()*8 / 2)) | id;
} }
void Core::step() { void Warp::step() {
Size fetchPos(0), decPos, wordSize(a.getWordSize()); Size fetchPos(0), decPos, wordSize(core->a.getWordSize());
vector<Byte> fetchBuffer(wordSize); vector<Byte> fetchBuffer(wordSize);
if (activeThreads == 0) return; if (activeThreads == 0) return;
@@ -73,10 +97,10 @@ void Core::step() {
fetchMore = false; fetchMore = false;
unsigned fetchSize(wordSize - (pc+fetchPos)%wordSize); unsigned fetchSize(wordSize - (pc+fetchPos)%wordSize);
fetchBuffer.resize(fetchPos + fetchSize); fetchBuffer.resize(fetchPos + fetchSize);
Word fetched = mem.fetch(pc + fetchPos, supervisorMode); Word fetched = core->mem.fetch(pc + fetchPos, supervisorMode);
writeWord(fetchBuffer, fetchPos, fetchSize, fetched); writeWord(fetchBuffer, fetchPos, fetchSize, fetched);
decPos = 0; decPos = 0;
inst = iDec.decode(fetchBuffer, decPos); inst = core->iDec.decode(fetchBuffer, decPos);
} catch (OutOfBytes o) { } catch (OutOfBytes o) {
D(3, "Caught OutOfBytes. Fetching more."); D(3, "Caught OutOfBytes. Fetching more.");
fetchMore = true; fetchMore = true;
@@ -91,9 +115,9 @@ void Core::step() {
D(3, "0x" << hex << pc << ": " << *inst); D(3, "0x" << hex << pc << ": " << *inst);
#ifdef EMU_INSTRUMENTATION #ifdef EMU_INSTRUMENTATION
{ Addr pcPhys(mem.virtToPhys(pc)); { Addr pcPhys(core->mem.virtToPhys(pc));
Harp::OSDomain::osDomain-> Harp::OSDomain::osDomain->
do_inst(0, pc, pcPhys, decPos, mem.getPtr(pcPhys, decPos), do_inst(0, pc, pcPhys, decPos, core->mem.getPtr(pcPhys, decPos),
(enum inst_type)inst->instTable[inst->getOpcode()].iType); (enum inst_type)inst->instTable[inst->getOpcode()].iType);
} }
#endif #endif
@@ -146,7 +170,7 @@ void Core::step() {
delete inst; delete inst;
} }
bool Core::interrupt(Word r0) { bool Warp::interrupt(Word r0) {
if (!interruptEnable) return false; if (!interruptEnable) return false;
#ifdef EMU_INSTRUMENTATION #ifdef EMU_INSTRUMENTATION

View File

@@ -67,9 +67,27 @@ namespace Harp {
Word pc; Word pc;
}; };
class Warp;
class Core { class Core {
public: public:
Core(const ArchDef &a, Decoder &d, MemoryUnit &mem, Word id=0); Core(const ArchDef &a, Decoder &d, MemoryUnit &mem, Word id=0);
bool interrupt(Word r0);
bool running() const;
void step();
const ArchDef &a;
Decoder &iDec;
MemoryUnit &mem;
std::vector<Warp> w;
};
class Warp {
public:
Warp(Core *c, Word id=0);
void step(); void step();
bool interrupt(Word r0); bool interrupt(Word r0);
bool running() const { return activeThreads; } bool running() const { return activeThreads; }
@@ -78,9 +96,7 @@ namespace Harp {
#endif #endif
// private: // private:
const ArchDef a; Core *core;
Decoder &iDec;
MemoryUnit &mem;
Word pc, interruptEntry, shadowPc, id; Word pc, interruptEntry, shadowPc, id;
Size activeThreads, shadowActiveThreads; Size activeThreads, shadowActiveThreads;

View File

@@ -9,7 +9,7 @@
#include "types.h" #include "types.h"
namespace Harp { namespace Harp {
class Core; class Warp;
class Ref; class Ref;
static const Size MAX_REG_SOURCES(3); static const Size MAX_REG_SOURCES(3);
@@ -53,7 +53,7 @@ namespace Harp {
predicated(false), nRsrc(0), nPsrc(0), immsrcPresent(false), predicated(false), nRsrc(0), nPsrc(0), immsrcPresent(false),
rdestPresent(false), pdestPresent(false), refLiteral(NULL) {} rdestPresent(false), pdestPresent(false), refLiteral(NULL) {}
void executeOn(Core &core); void executeOn(Warp &warp);
friend std::ostream &operator<<(std::ostream &, Instruction &); friend std::ostream &operator<<(std::ostream &, Instruction &);
/* Setters used to "craft" the instruction. */ /* Setters used to "craft" the instruction. */

View File

@@ -112,7 +112,7 @@ ostream &Harp::operator<<(ostream& os, Instruction &inst) {
return os; return os;
} }
void Instruction::executeOn(Core &c) { void Instruction::executeOn(Warp &c) {
D(3, "Begin instruction execute."); 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
@@ -135,7 +135,7 @@ void Instruction::executeOn(Core &c) {
} }
Size nextActiveThreads = c.activeThreads; Size nextActiveThreads = c.activeThreads;
Size wordSz = c.a.getWordSize(); Size wordSz = c.core->a.getWordSize();
Word nextPc = c.pc; Word nextPc = c.pc;
bool sjOnce(true), // Has not yet split or joined once. bool sjOnce(true), // Has not yet split or joined once.
@@ -157,9 +157,9 @@ void Instruction::executeOn(Core &c) {
break; break;
case EI: c.interruptEnable = true; case EI: c.interruptEnable = true;
break; break;
case TLBADD: c.mem.tlbAdd(reg[rsrc[0]], reg[rsrc[1]], reg[rsrc[2]]); case TLBADD: c.core->mem.tlbAdd(reg[rsrc[0]], reg[rsrc[1]], reg[rsrc[2]]);
break; break;
case TLBFLUSH: c.mem.tlbFlush(); case TLBFLUSH: c.core->mem.tlbFlush();
break; break;
case ADD: reg[rdest] = reg[rsrc[0]] + reg[rsrc[1]]; case ADD: reg[rdest] = reg[rsrc[0]] + reg[rsrc[1]];
reg[rdest].trunc(wordSz); reg[rdest].trunc(wordSz);
@@ -253,15 +253,15 @@ void Instruction::executeOn(Core &c) {
case LD: memAddr = reg[rsrc[0]] + immsrc; case LD: memAddr = reg[rsrc[0]] + immsrc;
#ifdef EMU_INSTRUMENTATION #ifdef EMU_INSTRUMENTATION
Harp::OSDomain::osDomain-> Harp::OSDomain::osDomain->
do_mem(0, memAddr, c.mem.virtToPhys(memAddr), 8, true); do_mem(0, memAddr, c.core->mem.virtToPhys(memAddr), 8, true);
#endif #endif
reg[rdest] = c.mem.read(memAddr, c.supervisorMode); reg[rdest] = c.core->mem.read(memAddr, c.supervisorMode);
break; break;
case ST: memAddr = reg[rsrc[1]] + immsrc; case ST: memAddr = reg[rsrc[1]] + immsrc;
c.mem.write(memAddr, reg[rsrc[0]], c.supervisorMode); c.core->mem.write(memAddr, reg[rsrc[0]], c.supervisorMode);
#ifdef EMU_INSTRUMENTATION #ifdef EMU_INSTRUMENTATION
Harp::OSDomain::osDomain-> Harp::OSDomain::osDomain->
do_mem(0, memAddr, c.mem.virtToPhys(memAddr), 8, true); do_mem(0, memAddr, c.core->mem.virtToPhys(memAddr), 8, true);
#endif #endif
break; break;
case LDI: reg[rdest] = immsrc; case LDI: reg[rdest] = immsrc;