diff options
-rw-r--r-- | qtmips_cli/main.cpp | 16 | ||||
-rw-r--r-- | qtmips_cli/tracer.cpp | 38 | ||||
-rw-r--r-- | qtmips_cli/tracer.h | 14 | ||||
-rw-r--r-- | qtmips_machine/core.cpp | 28 | ||||
-rw-r--r-- | qtmips_machine/core.h | 18 | ||||
-rw-r--r-- | qtmips_machine/instruction.cpp | 2 | ||||
-rw-r--r-- | qtmips_machine/instruction.h | 2 |
7 files changed, 91 insertions, 27 deletions
diff --git a/qtmips_cli/main.cpp b/qtmips_cli/main.cpp index 57187ce..fedf14d 100644 --- a/qtmips_cli/main.cpp +++ b/qtmips_cli/main.cpp @@ -18,7 +18,11 @@ void create_parser(QCommandLineParser &p) { p.addOptions({ {"pipelined", "Configure CPU to use five stage pipeline."}, {"no-delay-slot", "Disable jump delay slot."}, - {{"trace-fetch", "tr-fetch"}, "Trace fetched instruction."}, + {{"trace-fetch", "tr-fetch"}, "Trace fetched instruction (for both pipelined and not core)."}, + {{"trace-decode", "tr-decode"}, "Trace instruction in decode stage. (only for pipelined core)"}, + {{"trace-execute", "tr-execute"}, "Trace instruction in execute stage. (only for pipelined core)"}, + {{"trace-memory", "tr-memory"}, "Trace instruction in memory stage. (only for pipelined core)"}, + {{"trace-writeback", "tr-writeback"}, "Trace instruction in write back stage. (only for pipelined core)"}, {{"trace-pc", "tr-pc"}, "Print program counter register changes."}, {{"trace-gp", "tr-gp"}, "Print general purpose register changes. You can use * for all registers.", "REG"}, {{"trace-lo", "tr-lo"}, "Print LO register changes."}, @@ -44,6 +48,16 @@ void configure_machine(QCommandLineParser &p, MachineConfig &cc) { void configure_tracer(QCommandLineParser &p, Tracer &tr) { if (p.isSet("trace-fetch")) tr.fetch(); + if (p.isSet("pipelined")) { // Following are added only if we have stages + if (p.isSet("trace-decode")) + tr.decode(); + if (p.isSet("trace-execute")) + tr.execute(); + if (p.isSet("trace-memory")) + tr.memory(); + if (p.isSet("trace-writeback")) + tr.writeback(); + } if (p.isSet("trace-pc")) tr.reg_pc(); diff --git a/qtmips_cli/tracer.cpp b/qtmips_cli/tracer.cpp index ca66e09..4438fd8 100644 --- a/qtmips_cli/tracer.cpp +++ b/qtmips_cli/tracer.cpp @@ -25,7 +25,23 @@ Tracer::Tracer(QtMipsMachine *machine) { } while(false) void Tracer::fetch() { - CON(con_fetch, machine->core(), instruction_fetched(machine::Instruction&), instruction_fetch(machine::Instruction&)); + CON(con_fetch, machine->core(), instruction_fetched(const machine::Instruction&), instruction_fetch(const machine::Instruction&)); +} + +void Tracer::decode() { + CON(con_fetch, machine->core(), instruction_decoded(const machine::Instruction&), instruction_decode(const machine::Instruction&)); +} + +void Tracer::execute() { + CON(con_fetch, machine->core(), instruction_executed(const machine::Instruction&), instruction_execute(const machine::Instruction&)); +} + +void Tracer::memory() { + CON(con_fetch, machine->core(), instruction_memory(const machine::Instruction&), instruction_memory(const machine::Instruction&)); +} + +void Tracer::writeback() { + CON(con_fetch, machine->core(), instruction_writeback(const machine::Instruction&), instruction_writeback(const machine::Instruction&)); } void Tracer::reg_pc() { @@ -48,8 +64,24 @@ void Tracer::reg_hi() { r_hi = true; } -void Tracer::instruction_fetch(Instruction &inst) { - cout << inst.to_str().toStdString() << endl; +void Tracer::instruction_fetch(const Instruction &inst) { + cout << "Fetch: " << inst.to_str().toStdString() << endl; +} + +void Tracer::instruction_decode(const machine::Instruction &inst) { + cout << "Decode: " << inst.to_str().toStdString() << endl; +} + +void Tracer::instruction_execute(const machine::Instruction &inst) { + cout << "Execute: " << inst.to_str().toStdString() << endl; +} + +void Tracer::instruction_memory(const machine::Instruction &inst) { + cout << "Memory: " << inst.to_str().toStdString() << endl; +} + +void Tracer::instruction_writeback(const machine::Instruction &inst) { + cout << "Writeback: " << inst.to_str().toStdString() << endl; } void Tracer::regs_pc_update(std::uint32_t val) { diff --git a/qtmips_cli/tracer.h b/qtmips_cli/tracer.h index 913687c..53fd3e7 100644 --- a/qtmips_cli/tracer.h +++ b/qtmips_cli/tracer.h @@ -9,8 +9,12 @@ class Tracer : public QObject { public: Tracer(machine::QtMipsMachine *machine); - // Trace fetched instruction + // Trace instructions in different stages/sections void fetch(); + void decode(); + void execute(); + void memory(); + void writeback(); // Trace registers void reg_pc(); void reg_gp(std::uint8_t i); @@ -18,8 +22,12 @@ public: void reg_hi(); private slots: - void instruction_fetch(machine::Instruction &inst); - // TODO fetch + void instruction_fetch(const machine::Instruction &inst); + void instruction_decode(const machine::Instruction &inst); + void instruction_execute(const machine::Instruction &inst); + void instruction_memory(const machine::Instruction &inst); + void instruction_writeback(const machine::Instruction &inst); + void regs_pc_update(std::uint32_t val); void regs_gp_update(std::uint8_t i, std::uint32_t val); void regs_hi_lo_update(bool hi, std::uint32_t val); diff --git a/qtmips_machine/core.cpp b/qtmips_machine/core.cpp index faebd87..805d9be 100644 --- a/qtmips_machine/core.cpp +++ b/qtmips_machine/core.cpp @@ -103,8 +103,9 @@ struct Core::dtFetch Core::fetch() { }; } -struct Core::dtDecode Core::decode(struct dtFetch dt) { - struct DecodeMap dec = dmap[dt.inst.opcode()]; +struct Core::dtDecode Core::decode(const struct dtFetch &dt) { + emit instruction_decoded(dt.inst); + const struct DecodeMap &dec = dmap[dt.inst.opcode()]; if (!(dec.flags & DM_SUPPORTED)) // TODO message throw QTMIPS_EXCEPTION(UnsupportedInstruction, "", ""); @@ -128,8 +129,8 @@ struct Core::dtDecode Core::decode(struct dtFetch dt) { // TODO on jump there should be delay slot. Does processor addes it or compiler. And do we care? } -struct Core::dtExecute Core::execute(struct dtDecode dt) { - // TODO signals +struct Core::dtExecute Core::execute(const struct dtDecode &dt) { + emit instruction_executed(dt.inst); // Handle conditional move (we have to change regwrite signal if conditional is not met) // TODO can't we do this some cleaner way? @@ -142,6 +143,7 @@ struct Core::dtExecute Core::execute(struct dtDecode dt) { alu_sec = ((dt.inst.immediate() & 0x8000) << 16) | (dt.inst.immediate() & 0x7FFF); // Sign extend to 32bit return { + .inst = dt.inst, .memread = dt.memread, .memwrite = dt.memwrite, .regwrite = regwrite, @@ -152,8 +154,8 @@ struct Core::dtExecute Core::execute(struct dtDecode dt) { }; } -struct Core::dtMemory Core::memory(struct dtExecute dt) { - // TODO signals +struct Core::dtMemory Core::memory(const struct dtExecute &dt) { + emit instruction_memory(dt.inst); std::uint32_t towrite_val = dt.alu_val; if (dt.memwrite) @@ -162,20 +164,20 @@ struct Core::dtMemory Core::memory(struct dtExecute dt) { towrite_val = mem->read_ctl(dt.memctl, dt.alu_val); return { + .inst = dt.inst, .regwrite = dt.regwrite, .rwrite = dt.rwrite, .towrite_val = towrite_val, }; } -void Core::writeback(struct dtMemory dt) { - if (dt.regwrite) { +void Core::writeback(const struct dtMemory &dt) { + emit instruction_writeback(dt.inst); + if (dt.regwrite) regs->write_gp(dt.rwrite, dt.towrite_val); - } } -void Core::handle_pc(struct dtDecode dt) { - // TODO signals +void Core::handle_pc(const struct dtDecode &dt) { bool branch = false; bool link = false; // TODO implement link @@ -242,6 +244,7 @@ void Core::dtDecodeInit(struct dtDecode &dt) { } void Core::dtExecuteInit(struct dtExecute &dt) { + dt.inst = Instruction(0x00); dt.memread = false; dt.memwrite = false; dt.regwrite = false; @@ -252,6 +255,7 @@ void Core::dtExecuteInit(struct dtExecute &dt) { } void Core::dtMemoryInit(struct dtMemory &dt) { + dt.inst = Instruction(0x00); dt.regwrite = false; dt.rwrite = false; dt.towrite_val = 0; @@ -297,7 +301,7 @@ CorePipelined::CorePipelined(Registers *regs, MemoryAccess *mem) : \ void CorePipelined::step() { // TODO implement forward unit writeback(dt_m); - dt_m =memory(dt_e); + dt_m = memory(dt_e); dt_e = execute(dt_d); dt_d = decode(dt_f); dt_f = fetch(); diff --git a/qtmips_machine/core.h b/qtmips_machine/core.h index 1878bfc..3078c95 100644 --- a/qtmips_machine/core.h +++ b/qtmips_machine/core.h @@ -20,7 +20,11 @@ public: virtual void reset() = 0; // Reset core (only core, memory and registers has to be reseted separately) signals: - void instruction_fetched(machine::Instruction &inst); + void instruction_fetched(const machine::Instruction &inst); + void instruction_decoded(const machine::Instruction &inst); + void instruction_executed(const machine::Instruction &inst); + void instruction_memory(const machine::Instruction &inst); + void instruction_writeback(const machine::Instruction &inst); protected: Registers *regs; @@ -42,6 +46,7 @@ protected: std::uint32_t val_rt; // Value from register rt }; struct dtExecute { + Instruction inst; bool memread; bool memwrite; bool regwrite; @@ -51,17 +56,18 @@ protected: std::uint32_t alu_val; // Result of ALU execution }; struct dtMemory { + Instruction inst; bool regwrite; std::uint8_t rwrite; std::uint32_t towrite_val; }; struct dtFetch fetch(); - struct dtDecode decode(struct dtFetch); - struct dtExecute execute(struct dtDecode); - struct dtMemory memory(struct dtExecute); - void writeback(struct dtMemory); - void handle_pc(struct dtDecode); + struct dtDecode decode(const struct dtFetch&); + struct dtExecute execute(const struct dtDecode&); + struct dtMemory memory(const struct dtExecute&); + void writeback(const struct dtMemory&); + void handle_pc(const struct dtDecode&); // Initialize structures to NOPE instruction void dtFetchInit(struct dtFetch &dt); diff --git a/qtmips_machine/instruction.cpp b/qtmips_machine/instruction.cpp index edb6305..4ef65a4 100644 --- a/qtmips_machine/instruction.cpp +++ b/qtmips_machine/instruction.cpp @@ -228,7 +228,7 @@ static const struct AluInstructionMap alu_instruction_map[] = { }; #undef AIM_UNKNOWN -QString Instruction::to_str() { +QString Instruction::to_str() const { // TODO there are exception where some fields are zero and such so we should not print them in sych case if (opcode() >= (sizeof(instruction_map) / sizeof(struct InstructionMap))) return QString("UNKNOWN"); diff --git a/qtmips_machine/instruction.h b/qtmips_machine/instruction.h index 6232d3e..d84b0cb 100644 --- a/qtmips_machine/instruction.h +++ b/qtmips_machine/instruction.h @@ -29,7 +29,7 @@ public: bool operator!=(const Instruction &c) const; Instruction &operator=(const Instruction &c); - QString to_str(); + QString to_str() const; private: std::uint32_t dt; |