From fcb67b16d13de62092e3720d08adb0ef5e35de3d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Karel=20Ko=C4=8D=C3=AD?= Date: Sat, 25 Nov 2017 15:08:07 +0100 Subject: Test pipelined core --- instructions.md | 43 +++++++++++++++--------------- qtmips_machine/core.cpp | 33 ++++++++++++++++++----- qtmips_machine/core.h | 6 +++++ qtmips_machine/instruction.cpp | 13 +++++++++ qtmips_machine/instruction.h | 1 + qtmips_machine/tests/testcore.cpp | 54 +++++++++++++++++++++++++++++--------- qtmips_machine/tests/tst_machine.h | 6 +++-- 7 files changed, 114 insertions(+), 42 deletions(-) diff --git a/instructions.md b/instructions.md index 11ea04e..383d234 100644 --- a/instructions.md +++ b/instructions.md @@ -5,15 +5,14 @@ This is list of all MIPS1 instructions and their implementation status in QtMips Explanation of checkboxes: * [ ] Not tested * [?] Somewhat tested but not sure about correctness of implementation -* [-] Tested non-pipelined core -* [x] Tested on non-pipelined and pipelined core +* [x] Tested CPU Arithmetic Instruction -------------------------- -* [-] ADD -* [-] ADDI -* [-] ADDIU -* [-] ADDU +* [x] ADD +* [x] ADDI +* [x] ADDIU +* [x] ADDU * [ ] CLO * [ ] CLZ * [ ] DIV @@ -25,12 +24,12 @@ CPU Arithmetic Instruction * [ ] MUL * [ ] MULT * [ ] MULTU -* [-] SLT -* [-] SLTI -* [-] SLTIU +* [x] SLT +* [x] SLTI +* [x] SLTIU * [?] SLTU -* [-] SUB -* [-] SUBU +* [x] SUB +* [x] SUBU CPU Branch and Jump Instructions -------------------------------- @@ -76,14 +75,14 @@ CPU Load, Store and Memory Control Instructions CPU Logical Instructions ------------------------ -* [-] AND -* [-] ANDI +* [x] AND +* [x] ANDI * [ ] LUI -* [-] NOR -* [-] OR -* [-] ORI -* [-] XOR -* [-] XORI +* [x] NOR +* [x] OR +* [x] ORI +* [x] XOR +* [x] XORI CPU Move Instruction -------------------- @@ -97,12 +96,12 @@ CPU Move Instruction CPU Shift Instructions ---------------------- -* [-] SLL -* [-] SLLV +* [x] SLL +* [x] SLLV * [?] SRA * [?] SRAV -* [-] SRL -* [-] SRLV +* [x] SRL +* [x] SRLV CPU Trap Instructions --------------------- diff --git a/qtmips_machine/core.cpp b/qtmips_machine/core.cpp index d86a6f4..75690a3 100644 --- a/qtmips_machine/core.cpp +++ b/qtmips_machine/core.cpp @@ -163,14 +163,35 @@ void CoreSingle::step() { CorePipelined::CorePipelined(Registers *regs, MemoryAccess *mem) : \ Core(regs, mem) { - // Nothing to do + // Initialize to NOPE // + // dtFetch + dt_f.inst = Instruction(0x00); + // dtDecode + dt_d.inst = dt_f.inst; + dt_d.mem2reg = false; + dt_d.memwrite = false; + dt_d.alusrc = false; + dt_d.regd = false; + dt_d.regwrite = false; + dt_d.branch = false; + dt_d.aluop = ALU_OP_SLL; + dt_d.val_rs = 0; + dt_d.val_rt = 0; + // dtExecute + dt_e.regwrite = dt_d.regwrite; + dt_e.rwrite = dt_d.regwrite; + dt_e.alu_val = 0; + // dtMemory + dt_m.regwrite = dt_e.regwrite; + dt_m.rwrite = dt_e.rwrite; + dt_m.alu_val = dt_e.alu_val; } void CorePipelined::step() { // TODO implement pipelined - struct dtFetch f = fetch(); - struct dtDecode d = decode(f); - struct dtExecute e = execute(d); - struct dtMemory m =memory(e); - writeback(m); + writeback(dt_m); + 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 9829741..b566a38 100644 --- a/qtmips_machine/core.h +++ b/qtmips_machine/core.h @@ -69,6 +69,12 @@ public: CorePipelined(Registers *regs, MemoryAccess *mem); void step(); + +private: + struct Core::dtFetch dt_f; + struct Core::dtDecode dt_d; + struct Core::dtExecute dt_e; + struct Core::dtMemory dt_m; }; #endif // CORE_H diff --git a/qtmips_machine/instruction.cpp b/qtmips_machine/instruction.cpp index 58b6ffa..b6abebc 100644 --- a/qtmips_machine/instruction.cpp +++ b/qtmips_machine/instruction.cpp @@ -16,6 +16,13 @@ const struct InstructionMap instruction_map[] = { IM_UNKNOWN, IM_UNKNOWN, {"ADDI"}, + {"ADDIU"}, + {"SLTI"}, + {"SLTIU"}, + {"ANDI"}, + {"ORI"}, + {"XORI"}, + {"LUI"}, IM_UNKNOWN, IM_UNKNOWN, IM_UNKNOWN, @@ -116,3 +123,9 @@ bool Instruction::operator==(const Instruction &c) const { bool Instruction::operator!=(const Instruction &c) const { return ! this->operator==(c); } + +Instruction &Instruction::operator=(const Instruction &c) { + if (this != &c) + this->dt = c.data(); + return *this; +} diff --git a/qtmips_machine/instruction.h b/qtmips_machine/instruction.h index aa53973..0a87826 100644 --- a/qtmips_machine/instruction.h +++ b/qtmips_machine/instruction.h @@ -28,6 +28,7 @@ public: bool operator==(const Instruction &c) const; bool operator!=(const Instruction &c) const; + Instruction &operator=(const Instruction &c); private: std::uint32_t dt; diff --git a/qtmips_machine/tests/testcore.cpp b/qtmips_machine/tests/testcore.cpp index 43d4c90..31f61ab 100644 --- a/qtmips_machine/tests/testcore.cpp +++ b/qtmips_machine/tests/testcore.cpp @@ -1,7 +1,7 @@ #include "tst_machine.h" #include "core.h" -void MachineTests::core_regs_data() { +static void core_regs_data() { QTest::addColumn("i"); QTest::addColumn("init"); QTest::addColumn("res"); @@ -123,28 +123,58 @@ void MachineTests::core_regs_data() { } } +void MachineTests::singlecore_regs_data() { + core_regs_data(); +} + +void MachineTests::pipecore_regs_data() { + core_regs_data(); +} + #include using namespace std; -void MachineTests::core_regs() { +void MachineTests::singlecore_regs() { QFETCH(Instruction, i); QFETCH(Registers, init); QFETCH(Registers, res); Memory mem; // Just memory (it shouldn't be used here except instruction) mem.write_word(res.read_pc(), i.data()); // Store single instruction (anything else should be 0 so NOP effectively) + Memory mem_used(mem); // Create memory copy + + CoreSingle core(&init, &mem_used); + core.step(); // Single step should be enought as this is risc without pipeline - // Test on non-piplined res.pc_inc(); // We did single step so increment program counter accordingly - Memory mem_single(mem); // Create memory copy - Registers regs_single(init); // Create registers copy - CoreSingle core_single(®s_single, &mem_single); - core_single.step(); // Single step should be enought as this is risc without pipeline - cout << "well:" << regs_single.read_gp(26) << endl; - QCOMPARE(regs_single, res); // After doing changes from initial state this should be same state as in case of passed expected result - QCOMPARE(mem, mem_single); // There should be no change in memory - - // TODO on pipelined core + QCOMPARE(init, res); // After doing changes from initial state this should be same state as in case of passed expected result + QCOMPARE(mem, mem_used); // There should be no change in memory +} + +void MachineTests::pipecore_regs() { + QFETCH(Instruction, i); + QFETCH(Registers, init); + QFETCH(Registers, res); + + Memory mem; // Just memory (it shouldn't be used here except instruction) + mem.write_word(res.read_pc(), i.data()); // Store single instruction (anything else should be 0 so NOP effectively) + + Memory mem_used(mem); + Registers regs_used(init); + + res.pc_jmp(0x14); + + CorePipelined core(®s_used, &mem_used); + for (int i = 0; i < 4; i++) { + core.step(); // Fire steps for five pipelines stages + init.pc_inc(); + QCOMPARE(init, regs_used); // Untill writeback there should be no change in registers + } + core.step(); + + //cout << "well:" << init.read_gp(26) << ":" << regs_used.read_gp(26) << endl; + QCOMPARE(regs_used, res); // After doing changes from initial state this should be same state as in case of passed expected result + QCOMPARE(mem, mem_used); // There should be no change in memory } void MachineTests::core_mem_data() { diff --git a/qtmips_machine/tests/tst_machine.h b/qtmips_machine/tests/tst_machine.h index 35104c4..3feaddd 100644 --- a/qtmips_machine/tests/tst_machine.h +++ b/qtmips_machine/tests/tst_machine.h @@ -30,8 +30,10 @@ private Q_SLOTS: void alu_except(); void alu_except_data(); // Core - void core_regs(); - void core_regs_data(); + void singlecore_regs(); + void singlecore_regs_data(); + void pipecore_regs(); + void pipecore_regs_data(); void core_mem(); void core_mem_data(); }; -- cgit v1.2.3