aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKarel Kočí <cynerd@email.cz>2017-11-25 15:08:07 +0100
committerKarel Kočí <cynerd@email.cz>2017-11-25 15:08:07 +0100
commitfcb67b16d13de62092e3720d08adb0ef5e35de3d (patch)
treeca9daaf9d80e14bddff224f2f7e81123acdd7dd8
parentf5d4468b2a8afa28ddad0bad425f762725eb69a7 (diff)
downloadqtmips-fcb67b16d13de62092e3720d08adb0ef5e35de3d.tar.gz
qtmips-fcb67b16d13de62092e3720d08adb0ef5e35de3d.tar.bz2
qtmips-fcb67b16d13de62092e3720d08adb0ef5e35de3d.zip
Test pipelined core
-rw-r--r--instructions.md43
-rw-r--r--qtmips_machine/core.cpp33
-rw-r--r--qtmips_machine/core.h6
-rw-r--r--qtmips_machine/instruction.cpp13
-rw-r--r--qtmips_machine/instruction.h1
-rw-r--r--qtmips_machine/tests/testcore.cpp54
-rw-r--r--qtmips_machine/tests/tst_machine.h6
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<Instruction>("i");
QTest::addColumn<Registers>("init");
QTest::addColumn<Registers>("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 <iostream>
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(&regs_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(&regs_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();
};