From 75ff39499dbf285257dabf1258f35f543d713c0a Mon Sep 17 00:00:00 2001 From: Pavel Pisa Date: Sun, 24 Feb 2019 01:09:41 +0100 Subject: Add some more labels and clarify rs, rt, rd in execute stage. This allows simple visual compare of rs and rt in execution stage with register number to be written in memory and write-back stages. Signed-off-by: Pavel Pisa --- qtmips_gui/coreview.cpp | 16 ++++++++++++++++ qtmips_gui/coreview.h | 1 + qtmips_machine/core.cpp | 51 ++++++++++++++++++++++++++++++------------------- qtmips_machine/core.h | 6 ++++++ 4 files changed, 54 insertions(+), 20 deletions(-) diff --git a/qtmips_gui/coreview.cpp b/qtmips_gui/coreview.cpp index 7b5275f..ce438ca 100644 --- a/qtmips_gui/coreview.cpp +++ b/qtmips_gui/coreview.cpp @@ -204,10 +204,14 @@ CoreViewScene::CoreViewScene(machine::QtMipsMachine *machine) : QGraphicsScene() // Write back stage NEW_V(710, 330, writeback_value, true); // Write back value + new_label("RsD", 215, 241); NEW_V(205, 250, decode_rs_num_value, false, 2, 0, 10); + new_label("RtD", 215, 261); NEW_V(205, 270, decode_rt_num_value, false, 2, 0, 10); + new_label("RtD", 297, 372); NEW_V(320, 380, decode_rt_num_value, false, 2, 0, 10); + new_label("RdD", 297, 380); NEW_V(320, 390, decode_rd_num_value, false, 2, 0, 10); NEW_V(320, 500, writeback_regw_num_value, false, 2, 0, 10); @@ -472,6 +476,10 @@ CoreViewScenePipelined::CoreViewScenePipelined(machine::QtMipsMachine *machine) NEW_V(460, 105, execute_regw_value, false, 1); NEW_V(560, 105, memory_regw_value, false, 1); + new_label("RtE", 427, 372); + NEW_V(450, 380, execute_rt_num_value, false, 2, 0, 10); + new_label("RdE", 427, 380); + NEW_V(450, 390, execute_rd_num_value, false, 2, 0, 10); NEW_V(510, 385, execute_regw_num_value, false, 2, 0, 10); NEW_V(610, 385, memory_regw_num_value, false, 2, 0, 10); @@ -499,6 +507,14 @@ CoreViewScenePipelined::CoreViewScenePipelined(machine::QtMipsMachine *machine) con = new_bus(hu.j_alu_out->new_connector(CON_AX_X), dc.cmp->new_connector(0.5, 1)); con->setAxes({CON_AXIS_Y(380), CON_AXIS_X(330)}); + struct coreview::Latch::ConnectorPair regdest_dc_rs = latch_id_ex->new_connector(ex.mux_regdest->connector_in(0)->point().y() - latch_id_ex->y() - 8); + new_bus(dc.instr_bus->new_connector(0, ex.mux_regdest->connector_in(0)->y() - 8), regdest_dc_rs.in, 2); + new_label("RsE", 427, 364); + NEW_V(450, 370, execute_rs_num_value, false, 2, 0, 10); + NEW(Junction, ex.j_rs_num, 442, 372); + new_bus(regdest_dc_rs.out, ex.j_rs_num->new_connector(coreview::Connector::AX_X), 2); + + NEW_V(434, 250, execute_reg1_ff_value, false, 1); // Register 1 forward to ALU NEW_V(434, 303, execute_reg2_ff_value, false, 1); // Register 2 forward to ALU diff --git a/qtmips_gui/coreview.h b/qtmips_gui/coreview.h index fe6d951..0abc870 100644 --- a/qtmips_gui/coreview.h +++ b/qtmips_gui/coreview.h @@ -98,6 +98,7 @@ protected: } dc; struct { coreview::Junction *j_mux; + coreview::Junction *j_rs_num; coreview::Multiplexer *mux_imm, *mux_regdest; } ex; struct { diff --git a/qtmips_machine/core.cpp b/qtmips_machine/core.cpp index a282807..980a736 100644 --- a/qtmips_machine/core.cpp +++ b/qtmips_machine/core.cpp @@ -233,8 +233,11 @@ struct Core::dtDecode Core::decode(const struct dtFetch &dt) { if (!(flags & IMF_SUPPORTED)) throw QTMIPS_EXCEPTION(UnsupportedInstruction, "Instruction with following opcode is not supported", QString::number(dt.inst.opcode(), 16)); - std::uint32_t val_rs = regs->read_gp(dt.inst.rs()); - std::uint32_t val_rt = regs->read_gp(dt.inst.rt()); + std::uint8_t num_rs = dt.inst.rs(); + std::uint8_t num_rt = dt.inst.rt(); + std::uint8_t num_rd = dt.inst.rd(); + std::uint32_t val_rs = regs->read_gp(num_rs); + std::uint32_t val_rt = regs->read_gp(num_rt); std::uint32_t immediate_val; bool regwrite = flags & IMF_REGWRITE; bool regd = flags & IMF_REGD; @@ -268,16 +271,16 @@ struct Core::dtDecode Core::decode(const struct dtFetch &dt) { emit decode_memread_value((bool)(flags & IMF_MEMREAD)); emit decode_alusrc_value((bool)(flags & IMF_ALUSRC)); emit decode_regdest_value((bool)(flags & IMF_REGD)); - emit decode_rs_num_value(dt.inst.rs()); - emit decode_rt_num_value(dt.inst.rt()); - emit decode_rd_num_value(dt.inst.rd()); + emit decode_rs_num_value(num_rs); + emit decode_rt_num_value(num_rt); + emit decode_rd_num_value(num_rd); emit decode_regd31_value(regd31); if (regd31) { val_rt = dt.inst_addr + 8; } - rwrite = regd31 ? 31: regd ? dt.inst.rd() : dt.inst.rt(); + rwrite = regd31 ? 31: regd ? num_rd : num_rt; return { .inst = dt.inst, @@ -300,6 +303,9 @@ struct Core::dtDecode Core::decode(const struct dtFetch &dt) { .forward_m_d_rt = false, .aluop = alu_op, .memctl = mem_ctl, + .num_rs = num_rs, + .num_rt = num_rt, + .num_rd = num_rd, .val_rs = val_rs, .val_rt = val_rt, .immediate_val = immediate_val, @@ -327,13 +333,13 @@ struct Core::dtExecute Core::execute(const struct dtDecode &dt) { if (excause == EXCAUSE_NONE) { alu_val = alu_operate(dt.aluop, dt.val_rs, - alu_sec, dt.inst.shamt(), dt.inst.rd(), regs, + alu_sec, dt.inst.shamt(), dt.num_rd, regs, discard, excause); if (discard) regwrite = false; if (dt.aluop == ALU_OP_RDHWR) { - switch (dt.inst.rd()) { + switch (dt.num_rd) { case 0: // CPUNum alu_val = 0; break; @@ -370,6 +376,9 @@ struct Core::dtExecute Core::execute(const struct dtDecode &dt) { emit execute_alusrc_value(dt.alusrc); emit execute_regdest_value(dt.regd); emit execute_regw_num_value(dt.rwrite); + emit execute_rs_num_value(dt.num_rs); + emit execute_rt_num_value(dt.num_rt); + emit execute_rd_num_value(dt.num_rd); if (dt.stall) emit execute_stall_forward_value(1); else if (dt.ff_rs != FORWARD_NONE || dt.ff_rt != FORWARD_NONE) @@ -518,6 +527,8 @@ void Core::dtDecodeInit(struct dtDecode &dt) { dt.forward_m_d_rt = false; dt.aluop = ALU_OP_SLL; dt.memctl = AC_NONE; + dt.num_rs = 0; + dt.num_rt = 0; dt.val_rs = 0; dt.val_rt = 0; dt.rwrite = 0; @@ -659,8 +670,8 @@ void CorePipelined::do_step(bool skip_break) { #define HAZARD(STAGE) ( \ (STAGE).regwrite && (STAGE).rwrite != 0 && \ - ((dt_d.alu_req_rs && (STAGE).rwrite == dt_d.inst.rs()) || \ - (dt_d.alu_req_rt && (STAGE).rwrite == dt_d.inst.rt())) \ + ((dt_d.alu_req_rs && (STAGE).rwrite == dt_d.num_rs) || \ + (dt_d.alu_req_rt && (STAGE).rwrite == dt_d.num_rt)) \ ) // Note: We make exception with $0 as that has no effect and is used in nop instruction // Write back stage combinatoricly propagates written instruction to decode stage so nothing has to be done for that stage @@ -668,11 +679,11 @@ void CorePipelined::do_step(bool skip_break) { // Hazard with instruction in memory stage if (hazard_unit == MachineConfig::HU_STALL_FORWARD) { // Forward result value - if (dt_d.alu_req_rs && dt_m.rwrite == dt_d.inst.rs()) { + if (dt_d.alu_req_rs && dt_m.rwrite == dt_d.num_rs) { dt_d.val_rs = dt_m.towrite_val; dt_d.ff_rs = FORWARD_FROM_W; } - if (dt_d.alu_req_rt && dt_m.rwrite == dt_d.inst.rt()) { + if (dt_d.alu_req_rt && dt_m.rwrite == dt_d.num_rt) { dt_d.val_rt = dt_m.towrite_val; dt_d.ff_rt = FORWARD_FROM_W; } @@ -686,11 +697,11 @@ void CorePipelined::do_step(bool skip_break) { stall = true; else { // Forward result value - if (dt_d.alu_req_rs && dt_e.rwrite == dt_d.inst.rs()) { + if (dt_d.alu_req_rs && dt_e.rwrite == dt_d.num_rs) { dt_d.val_rs = dt_e.alu_val; dt_d.ff_rs = FORWARD_FROM_M; } - if (dt_d.alu_req_rt && dt_e.rwrite == dt_d.inst.rt()) { + if (dt_d.alu_req_rt && dt_e.rwrite == dt_d.num_rt) { dt_d.val_rt = dt_e.alu_val; dt_d.ff_rt = FORWARD_FROM_M; } @@ -700,24 +711,24 @@ void CorePipelined::do_step(bool skip_break) { } #undef HAZARD if (dt_e.rwrite != 0 && dt_e.regwrite && - ((dt_d.bjr_req_rs && dt_d.inst.rs() == dt_e.rwrite) || - (dt_d.bjr_req_rt && dt_d.inst.rt() == dt_e.rwrite))) { + ((dt_d.bjr_req_rs && dt_d.num_rs == dt_e.rwrite) || + (dt_d.bjr_req_rt && dt_d.num_rt == dt_e.rwrite))) { stall = true; branch_stall = true; } else { if (hazard_unit != MachineConfig::HU_STALL_FORWARD || dt_m.memtoreg) { if (dt_m.rwrite != 0 && dt_m.regwrite && - ((dt_d.bjr_req_rs && dt_d.inst.rs() == dt_m.rwrite) || - (dt_d.bjr_req_rt && dt_d.inst.rt() == dt_m.rwrite))) + ((dt_d.bjr_req_rs && dt_d.num_rs == dt_m.rwrite) || + (dt_d.bjr_req_rt && dt_d.num_rt == dt_m.rwrite))) stall = true; } else { if (dt_m.rwrite != 0 && dt_m.regwrite && - dt_d.bjr_req_rs && dt_d.inst.rs() == dt_m.rwrite) { + dt_d.bjr_req_rs && dt_d.num_rs == dt_m.rwrite) { dt_d.val_rs = dt_m.towrite_val; dt_d.forward_m_d_rs = true; } if (dt_m.rwrite != 0 && dt_m.regwrite && - dt_d.bjr_req_rt && dt_d.inst.rt() == dt_m.rwrite) { + dt_d.bjr_req_rt && dt_d.num_rt == dt_m.rwrite) { dt_d.val_rt = dt_m.towrite_val; dt_d.forward_m_d_rt = true; } diff --git a/qtmips_machine/core.h b/qtmips_machine/core.h index 8140f61..f70a19d 100644 --- a/qtmips_machine/core.h +++ b/qtmips_machine/core.h @@ -137,6 +137,9 @@ signals: void execute_regdest_value(std::uint32_t); void execute_regw_num_value(std::uint32_t); void execute_stall_forward_value(std::uint32_t); + void execute_rs_num_value(std::uint32_t); + void execute_rt_num_value(std::uint32_t); + void execute_rd_num_value(std::uint32_t); void memory_inst_addr_value(std::uint32_t); void memory_alu_value(std::uint32_t); void memory_rt_value(std::uint32_t); @@ -198,6 +201,9 @@ protected: bool forward_m_d_rt; // forwarding required for beq, bne enum AluOp aluop; // Decoded ALU operation enum AccessControl memctl; // Decoded memory access type + std::uint8_t num_rs; // Number of the register s + std::uint8_t num_rt; // Number of the register t + std::uint8_t num_rd; // Number of the register d std::uint32_t val_rs; // Value from register rs std::uint32_t val_rt; // Value from register rt std::uint32_t immediate_val; // zero or sign-extended immediate value -- cgit v1.2.3