diff options
-rw-r--r-- | qtmips_gui/coreview/instructionview.cpp | 13 | ||||
-rw-r--r-- | qtmips_gui/coreview/instructionview.h | 4 | ||||
-rw-r--r-- | qtmips_machine/core.cpp | 58 | ||||
-rw-r--r-- | qtmips_machine/core.h | 22 | ||||
-rw-r--r-- | qtmips_machine/qtmipsmachine.cpp | 15 | ||||
-rw-r--r-- | qtmips_machine/qtmipsmachine.h | 4 |
6 files changed, 74 insertions, 42 deletions
diff --git a/qtmips_gui/coreview/instructionview.cpp b/qtmips_gui/coreview/instructionview.cpp index d989b7b..495edfb 100644 --- a/qtmips_gui/coreview/instructionview.cpp +++ b/qtmips_gui/coreview/instructionview.cpp @@ -52,7 +52,8 @@ InstructionView::InstructionView() : QGraphicsObject(nullptr), text(this) { f.setPointSize(6); text.setFont(f); - instruction_update(machine::Instruction(), 0); // Initialize to NOP + // Initialize to NOP + instruction_update(machine::Instruction(), 0, machine::EXCAUSE_NONE); } QRectF InstructionView::boundingRect() const { @@ -61,13 +62,19 @@ QRectF InstructionView::boundingRect() const { void InstructionView::paint(QPainter *painter, const QStyleOptionGraphicsItem *option __attribute__((unused)), QWidget *widget __attribute__((unused))) { painter->setPen(QPen(QColor(240, 240, 240))); - painter->setBrush(QBrush(QColor(240, 240, 240))); + if (excause == machine::EXCAUSE_NONE) + painter->setBrush(QBrush(QColor(240, 240, 240))); + else + painter->setBrush(QBrush(QColor(255, 100, 100))); painter->drawRoundRect(-WIDTH/2, 0, WIDTH, HEIGHT, ROUND, ROUND); } -void InstructionView::instruction_update(const machine::Instruction &i, std::uint32_t inst_addr) { +void InstructionView::instruction_update(const machine::Instruction &i, + std::uint32_t inst_addr, machine::ExceptionCause excause) { + QRectF prev_box = boundingRect(); text.setText(i.to_str(inst_addr)); + this->excause = excause; QRectF box = text.boundingRect(); text.setPos(-box.width()/2, GAP); update(prev_box.united(boundingRect())); diff --git a/qtmips_gui/coreview/instructionview.h b/qtmips_gui/coreview/instructionview.h index 8c63fc1..6e39bdd 100644 --- a/qtmips_gui/coreview/instructionview.h +++ b/qtmips_gui/coreview/instructionview.h @@ -51,10 +51,12 @@ public: void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget); public slots: - void instruction_update(const machine::Instruction &i, std::uint32_t inst_addr); + void instruction_update(const machine::Instruction &i, std::uint32_t inst_addr, + machine::ExceptionCause excause); private: QGraphicsSimpleTextItem text; + machine::ExceptionCause excause; }; } diff --git a/qtmips_machine/core.cpp b/qtmips_machine/core.cpp index 7c92949..e744848 100644 --- a/qtmips_machine/core.cpp +++ b/qtmips_machine/core.cpp @@ -50,9 +50,9 @@ Core::Core(Registers *regs, MemoryAccess *mem_program, MemoryAccess *mem_data, this->hwr_user_local = 0xe0000000; } -void Core::step() { +void Core::step(bool skip_break) { cycle_c++; - do_step(); + do_step(skip_break); } void Core::reset() { @@ -135,17 +135,19 @@ bool Core::handle_exception(Core *core, Registers *regs, ExceptionCause excause, return false; } -struct Core::dtFetch Core::fetch() { +struct Core::dtFetch Core::fetch(bool skip_break) { enum ExceptionCause excause = EXCAUSE_NONE; std::uint32_t inst_addr = regs->read_pc(); - emit fetch_inst_addr_value(inst_addr); Instruction inst(mem_program->read_word(inst_addr)); - emit instruction_fetched(inst, inst_addr); - hwBreak *brk = hw_breaks.value(inst_addr); - if (brk != nullptr) { - excause = EXCAUSE_HWBREAK; + if (!skip_break) { + hwBreak *brk = hw_breaks.value(inst_addr); + if (brk != nullptr) { + excause = EXCAUSE_HWBREAK; + } } + emit fetch_inst_addr_value(inst_addr); + emit instruction_fetched(inst, inst_addr, excause); return { .inst = inst, .inst_addr = inst_addr, @@ -156,8 +158,6 @@ struct Core::dtFetch Core::fetch() { struct Core::dtDecode Core::decode(const struct dtFetch &dt) { uint8_t rwrite; - emit decode_inst_addr_value(dt.inst_addr); - emit instruction_decoded(dt.inst, dt.inst_addr); enum InstructionFlags flags; enum AluOp alu_op; enum AccessControl mem_ctl; @@ -191,6 +191,8 @@ struct Core::dtDecode Core::decode(const struct dtFetch &dt) { excause = dt.inst.encoded_exception(); } + emit decode_inst_addr_value(dt.inst_addr); + emit instruction_decoded(dt.inst, dt.inst_addr, excause); emit decode_instruction_value(dt.inst.data()); emit decode_reg1_value(val_rs); emit decode_reg2_value(val_rt); @@ -246,8 +248,6 @@ struct Core::dtDecode Core::decode(const struct dtFetch &dt) { } struct Core::dtExecute Core::execute(const struct dtDecode &dt) { - emit execute_inst_addr_value(dt.inst_addr); - emit instruction_executed(dt.inst, dt.inst_addr); bool discard; // Handle conditional move (we have to change regwrite signal if conditional is not met) @@ -283,6 +283,8 @@ struct Core::dtExecute Core::execute(const struct dtDecode &dt) { } } + emit execute_inst_addr_value(dt.inst_addr); + emit instruction_executed(dt.inst, dt.inst_addr, dt.excause); emit execute_alu_value(alu_val); emit execute_reg1_value(dt.val_rs); emit execute_reg2_value(dt.val_rt); @@ -313,8 +315,6 @@ struct Core::dtExecute Core::execute(const struct dtDecode &dt) { } struct Core::dtMemory Core::memory(const struct dtExecute &dt) { - emit memory_inst_addr_value(dt.inst_addr); - emit instruction_memory(dt.inst, dt.inst_addr); std::uint32_t towrite_val = dt.alu_val; std::uint32_t mem_addr = dt.alu_val; bool memread = dt.memread; @@ -344,6 +344,8 @@ struct Core::dtMemory Core::memory(const struct dtExecute &dt) { } } + emit memory_inst_addr_value(dt.inst_addr); + emit instruction_memory(dt.inst, dt.inst_addr, dt.excause); emit memory_alu_value(dt.alu_val); emit memory_rt_value(dt.val_rt); emit memory_mem_value(memread ? towrite_val : 0); @@ -367,7 +369,7 @@ struct Core::dtMemory Core::memory(const struct dtExecute &dt) { void Core::writeback(const struct dtMemory &dt) { emit writeback_inst_addr_value(dt.inst_addr); - emit instruction_writeback(dt.inst, dt.inst_addr); + emit instruction_writeback(dt.inst, dt.inst_addr, dt.excause); emit writeback_value(dt.towrite_val); emit writeback_regw_value(dt.regwrite); emit writeback_regw_num_value(dt.rwrite); @@ -377,7 +379,7 @@ void Core::writeback(const struct dtMemory &dt) { bool Core::handle_pc(const struct dtDecode &dt) { bool branch = false; - emit instruction_program_counter(dt.inst, dt.inst_addr); + emit instruction_program_counter(dt.inst, dt.inst_addr, EXCAUSE_NONE); if (dt.jump) { if (!dt.bjr_req_rs) { @@ -487,11 +489,11 @@ CoreSingle::~CoreSingle() { delete jmp_delay_decode; } -void CoreSingle::do_step() { +void CoreSingle::do_step(bool skip_break) { bool in_delay_slot = false; std::uint32_t jump_branch_pc; - struct dtFetch f = fetch(); + struct dtFetch f = fetch(skip_break); struct dtDecode d = decode(f); // Handle PC before instruction following jump leaves decode stage @@ -535,7 +537,7 @@ CorePipelined::CorePipelined(Registers *regs, MemoryAccess *mem_program, MemoryA reset(); } -void CorePipelined::do_step() { +void CorePipelined::do_step(bool skip_break) { bool stall = false; bool excpt_in_progress = false; std::uint32_t jump_branch_pc = dt_m.inst_addr; @@ -548,14 +550,19 @@ void CorePipelined::do_step() { // Resolve exceptions excpt_in_progress = dt_m.excause != EXCAUSE_NONE; - if (excpt_in_progress) + if (excpt_in_progress) { dtExecuteInit(dt_e); + emit instruction_executed(dt_e.inst, dt_e.inst_addr, dt_e.excause); + } excpt_in_progress = excpt_in_progress || dt_e.excause != EXCAUSE_NONE; - if (excpt_in_progress) + if (excpt_in_progress) { dtDecodeInit(dt_d); + emit instruction_decoded(dt_d.inst, dt_d.inst_addr, dt_d.excause); + } excpt_in_progress = excpt_in_progress || dt_e.excause != EXCAUSE_NONE; if (excpt_in_progress) { dtFetchInit(dt_f); + emit instruction_fetched(dt_f.inst, dt_f.inst_addr, dt_f.excause); if (dt_m.excause != EXCAUSE_NONE) { regs->pc_abs_jmp(dt_e.inst_addr); handle_exception(this, regs, dt_m.excause, dt_m.inst_addr, @@ -656,18 +663,21 @@ void CorePipelined::do_step() { // Now process program counter (loop connections from decode stage) if (!stall) { - dt_f = fetch(); + dt_f = fetch(skip_break); if (handle_pc(dt_d)) { dt_f.in_delay_slot = true; } else { - if (dt_d.nb_skip_ds) + if (dt_d.nb_skip_ds) { dtFetchInit(dt_f); + emit instruction_fetched(dt_f.inst, dt_f.inst_addr, dt_f.excause); + } } } else { // Run fetch stage on empty - fetch(); + fetch(skip_break); // clear decode latch (insert nope to execute stage) dtDecodeInit(dt_d); + emit instruction_decoded(dt_d.inst, dt_d.inst_addr, dt_d.excause); } } diff --git a/qtmips_machine/core.h b/qtmips_machine/core.h index bd62f52..97a15c1 100644 --- a/qtmips_machine/core.h +++ b/qtmips_machine/core.h @@ -72,7 +72,7 @@ public: Core(Registers *regs, MemoryAccess *mem_program, MemoryAccess *mem_data, unsigned int min_cache_row_size = 1); - void step(); // Do single step + void step(bool skip_break = false); // Do single step void reset(); // Reset core (only core, memory and registers has to be reseted separately) unsigned cycles(); // Returns number of executed cycles @@ -92,12 +92,12 @@ public: }; signals: - void instruction_fetched(const machine::Instruction &inst, std::uint32_t inst_addr); - void instruction_decoded(const machine::Instruction &inst, std::uint32_t inst_addr); - void instruction_executed(const machine::Instruction &inst, std::uint32_t inst_addr); - void instruction_memory(const machine::Instruction &inst, std::uint32_t inst_addr); - void instruction_writeback(const machine::Instruction &inst, std::uint32_t inst_addr); - void instruction_program_counter(const machine::Instruction &inst, std::uint32_t inst_addr); + void instruction_fetched(const machine::Instruction &inst, std::uint32_t inst_addr, ExceptionCause excause); + void instruction_decoded(const machine::Instruction &inst, std::uint32_t inst_addr, ExceptionCause excause); + void instruction_executed(const machine::Instruction &inst, std::uint32_t inst_addr, ExceptionCause excause); + void instruction_memory(const machine::Instruction &inst, std::uint32_t inst_addr, ExceptionCause excause); + void instruction_writeback(const machine::Instruction &inst, std::uint32_t inst_addr, ExceptionCause excause); + void instruction_program_counter(const machine::Instruction &inst, std::uint32_t inst_addr, ExceptionCause excause); void fetch_inst_addr_value(std::uint32_t); void fetch_jump_reg_value(std::uint32_t); @@ -151,7 +151,7 @@ signals: void stop_on_exception_reached(); protected: - virtual void do_step() = 0; + virtual void do_step(bool skip_break = false) = 0; virtual void do_reset() = 0; bool handle_exception(Core *core, Registers *regs, @@ -225,7 +225,7 @@ protected: bool in_delay_slot; }; - struct dtFetch fetch(); + struct dtFetch fetch(bool skip_break = false); struct dtDecode decode(const struct dtFetch&); struct dtExecute execute(const struct dtDecode&); struct dtMemory memory(const struct dtExecute&); @@ -257,7 +257,7 @@ public: ~CoreSingle(); protected: - void do_step(); + void do_step(bool skip_break = false); void do_reset(); private: @@ -269,7 +269,7 @@ public: CorePipelined(Registers *regs, MemoryAccess *mem_program, MemoryAccess *mem_data, enum MachineConfig::HazardUnit hazard_unit = MachineConfig::HU_STALL_FORWARD); protected: - void do_step(); + void do_step(bool skip_break = false); void do_reset(); private: diff --git a/qtmips_machine/qtmipsmachine.cpp b/qtmips_machine/qtmipsmachine.cpp index 23a83d3..382a9f2 100644 --- a/qtmips_machine/qtmipsmachine.cpp +++ b/qtmips_machine/qtmipsmachine.cpp @@ -68,7 +68,7 @@ QtMipsMachine::QtMipsMachine(const MachineConfig &cc) : QObject(), mcnf(&cc) { run_t = new QTimer(this); set_speed(0); // In default run as fast as possible - connect(run_t, SIGNAL(timeout()), this, SLOT(step())); + connect(run_t, SIGNAL(timeout()), this, SLOT(step_timer())); } QtMipsMachine::~QtMipsMachine() { @@ -150,6 +150,7 @@ void QtMipsMachine::play() { CTL_GUARD; set_status(ST_RUNNING); run_t->start(); + step_internal(true); } void QtMipsMachine::pause() { @@ -159,13 +160,13 @@ void QtMipsMachine::pause() { run_t->stop(); } -void QtMipsMachine::step() { +void QtMipsMachine::step_internal(bool skip_break) { CTL_GUARD; enum Status stat_prev = stat; set_status(ST_BUSY); emit tick(); try { - cr->step(); + cr->step(skip_break); } catch (QtMipsException &e) { run_t->stop(); set_status(ST_TRAPPED); @@ -183,6 +184,14 @@ void QtMipsMachine::step() { emit post_tick(); } +void QtMipsMachine::step() { + step_internal(true); +} + +void QtMipsMachine::step_timer() { + step_internal(); +} + void QtMipsMachine::restart() { pause(); regs->reset(); diff --git a/qtmips_machine/qtmipsmachine.h b/qtmips_machine/qtmipsmachine.h index de5275a..22ba0f9 100644 --- a/qtmips_machine/qtmipsmachine.h +++ b/qtmips_machine/qtmipsmachine.h @@ -95,7 +95,11 @@ signals: void tick(); // Time tick void post_tick(); // Emitted after tick to allow updates +private slots: + void step_timer(); + private: + void step_internal(bool skip_break = false); MachineConfig mcnf; Registers *regs; |