diff --git a/arches/isa_json/gen_uarch_rv64v_json.py b/arches/isa_json/gen_uarch_rv64v_json.py index 9307c65f..e7fcf6a3 100755 --- a/arches/isa_json/gen_uarch_rv64v_json.py +++ b/arches/isa_json/gen_uarch_rv64v_json.py @@ -51,14 +51,12 @@ "vwsub.wv" : {"pipe" : "vint", "uop_gen" : "WIDENING_MIXED", "latency" : 1}, "vwsub.wx" : {"pipe" : "vint", "uop_gen" : "WIDENING_MIXED", "latency" : 1}, -# TODO: Vector Integer Arithmetic Instructions: Vector Integer Extension -# FIXME: Requires Mavis fix to support correctly -# "vzext.vf2" : {"pipe" : "vint", "uop_gen" : "ARITH_EXT", "latency" : 1}, -# "vsext.vf2" : {"pipe" : "vint", "uop_gen" : "ARITH_EXT", "latency" : 1}, -# "vzext.vf4" : {"pipe" : "vint", "uop_gen" : "ARITH_EXT", "latency" : 1}, -# "vsext.vf4" : {"pipe" : "vint", "uop_gen" : "ARITH_EXT", "latency" : 1}, -# "vzext.vf8" : {"pipe" : "vint", "uop_gen" : "ARITH_EXT", "latency" : 1}, -# "vsext.vf8" : {"pipe" : "vint", "uop_gen" : "ARITH_EXT", "latency" : 1}, + "vzext.vf2" : {"pipe" : "vint", "uop_gen" : "INT_EXT", "latency" : 1}, + "vsext.vf2" : {"pipe" : "vint", "uop_gen" : "INT_EXT", "latency" : 1}, + "vzext.vf4" : {"pipe" : "vint", "uop_gen" : "INT_EXT", "latency" : 1}, + "vsext.vf4" : {"pipe" : "vint", "uop_gen" : "INT_EXT", "latency" : 1}, + "vzext.vf8" : {"pipe" : "vint", "uop_gen" : "INT_EXT", "latency" : 1}, + "vsext.vf8" : {"pipe" : "vint", "uop_gen" : "INT_EXT", "latency" : 1}, # Vector Integer Arithmetic Instructions: Vector Integer Add-with-Carry/Subtract-with-Borrow Instructions # FIXME: Requires Mavis fix to include vector mask diff --git a/arches/isa_json/olympia_uarch_rv64v.json b/arches/isa_json/olympia_uarch_rv64v.json index b1584811..56080fad 100644 --- a/arches/isa_json/olympia_uarch_rv64v.json +++ b/arches/isa_json/olympia_uarch_rv64v.json @@ -1735,21 +1735,21 @@ }, { "mnemonic": "vsext.vf2", - "pipe": "?", - "uop_gen": "NONE", - "latency": 0 + "pipe": "vint", + "uop_gen": "INT_EXT", + "latency": 1 }, { "mnemonic": "vsext.vf4", - "pipe": "?", - "uop_gen": "NONE", - "latency": 0 + "pipe": "vint", + "uop_gen": "INT_EXT", + "latency": 1 }, { "mnemonic": "vsext.vf8", - "pipe": "?", - "uop_gen": "NONE", - "latency": 0 + "pipe": "vint", + "uop_gen": "INT_EXT", + "latency": 1 }, { "mnemonic": "vslide1down.vx", @@ -2209,20 +2209,20 @@ }, { "mnemonic": "vzext.vf2", - "pipe": "?", - "uop_gen": "NONE", - "latency": 0 + "pipe": "vint", + "uop_gen": "INT_EXT", + "latency": 1 }, { "mnemonic": "vzext.vf4", - "pipe": "?", - "uop_gen": "NONE", - "latency": 0 + "pipe": "vint", + "uop_gen": "INT_EXT", + "latency": 1 }, { "mnemonic": "vzext.vf8", - "pipe": "?", - "uop_gen": "NONE", - "latency": 0 + "pipe": "vint", + "uop_gen": "INT_EXT", + "latency": 1 } ] \ No newline at end of file diff --git a/core/Inst.hpp b/core/Inst.hpp index 78f8afb1..0b3bff93 100644 --- a/core/Inst.hpp +++ b/core/Inst.hpp @@ -18,6 +18,7 @@ #include "VectorConfig.hpp" #include "MiscUtils.hpp" +#include #include #include #include @@ -221,29 +222,34 @@ namespace olympia } const VectorConfigPtr getVectorConfig() const { return vector_config_; } + VectorConfigPtr getVectorConfig() { return vector_config_; } void setTail(bool has_tail) { has_tail_ = has_tail; } + bool hasTail() const { return has_tail_; } void setUOpParent(sparta::SpartaWeakPointer & parent_uop) { parent_uop_ = parent_uop; } + sparta::SpartaWeakPointer getUOpParent() { return parent_uop_; } // Branch instruction was taken (always set for JAL/JALR) void setTakenBranch(bool taken) { is_taken_branch_ = taken; } // Is this branch instruction mispredicted? - bool isMispredicted() const { return is_mispredicted_; } - void setMispredicted() { is_mispredicted_ = true; } + bool isMispredicted() const { return is_mispredicted_; } + + void setMispredicted() { is_mispredicted_ = true; } // TBD -- add branch prediction void setSpeculative(bool spec) { is_speculative_ = spec; } // Last instruction within the cache block fetched from the ICache void setLastInFetchBlock(bool last) { last_in_fetch_block_ = last; } + bool isLastInFetchBlock() const { return last_in_fetch_block_; } // Opcode information @@ -271,25 +277,20 @@ namespace olympia bool hasZeroRegSource() const { return std::any_of(getSourceOpInfoList().begin(), getSourceOpInfoList().end(), - [](const mavis::OperandInfo::Element & elem) - { - return elem.field_value == 0; - }); + [](const mavis::OperandInfo::Element & elem) + { return elem.field_value == 0; }); } bool hasZeroRegDest() const { return std::any_of(getDestOpInfoList().begin(), getDestOpInfoList().end(), - [](const mavis::OperandInfo::Element & elem) - { - return elem.field_value == 0; - }); + [](const mavis::OperandInfo::Element & elem) + { return elem.field_value == 0; }); } uint64_t getImmediate() const { - sparta_assert(has_immediate_, - "Instruction does not have an immediate!"); + sparta_assert(has_immediate_, "Instruction does not have an immediate!"); return opcode_info_->getImmediate(); } @@ -298,7 +299,8 @@ namespace olympia try { // If vm bit is 0, masking is enabled - const uint64_t vm_bit = opcode_info_->getSpecialField(mavis::OpcodeInfo::SpecialField::VM); + const uint64_t vm_bit = + opcode_info_->getSpecialField(mavis::OpcodeInfo::SpecialField::VM); return vm_bit == 0; } catch (const mavis::UnsupportedExtractorSpecialFieldID & mavis_exception) @@ -344,7 +346,8 @@ namespace olympia bool isVector() const { return is_vector_; } - void setCoF(const bool &cof) { is_cof_ = cof; } + void setCoF(const bool & cof) { is_cof_ = cof; } + bool isCoF() const { return is_cof_; } // Rename information diff --git a/core/InstArchInfo.cpp b/core/InstArchInfo.cpp index 5edd5043..254cbae0 100644 --- a/core/InstArchInfo.cpp +++ b/core/InstArchInfo.cpp @@ -63,6 +63,7 @@ namespace olympia {"NARROWING", InstArchInfo::UopGenType::NARROWING}, {"MAC", InstArchInfo::UopGenType::MAC}, {"MAC_WIDE", InstArchInfo::UopGenType::MAC_WIDE}, + {"INT_EXT", InstArchInfo::UopGenType::INT_EXT}, {"NONE", InstArchInfo::UopGenType::NONE} }; diff --git a/core/InstArchInfo.hpp b/core/InstArchInfo.hpp index 175f5a59..600fded5 100644 --- a/core/InstArchInfo.hpp +++ b/core/InstArchInfo.hpp @@ -78,6 +78,7 @@ namespace olympia NARROWING, MAC, MAC_WIDE, + INT_EXT, NONE, UNKNOWN }; diff --git a/core/InstGenerator.cpp b/core/InstGenerator.cpp index 385b66f8..9ce6004e 100644 --- a/core/InstGenerator.cpp +++ b/core/InstGenerator.cpp @@ -137,7 +137,8 @@ namespace olympia if (jinst.find("vaddr") != jinst.end()) { - uint64_t vaddr = std::strtoull(jinst["vaddr"].get().c_str(), nullptr, 0); + uint64_t vaddr = + std::strtoull(jinst["vaddr"].get().c_str(), nullptr, 0); inst->setTargetVAddr(vaddr); } @@ -145,7 +146,8 @@ namespace olympia if (jinst.find("vtype") != jinst.end()) { // immediate, so decode from hex - uint64_t vtype = std::strtoull(jinst["vtype"].get().c_str(), nullptr, 0); + uint64_t vtype = + std::strtoull(jinst["vtype"].get().c_str(), nullptr, 0); std::string binaryString = std::bitset<32>(vtype).to_string(); uint32_t sew = std::pow(2, std::stoi(binaryString.substr(26, 3), nullptr, 2)) * 8; uint32_t lmul = std::pow(2, std::stoi(binaryString.substr(29, 3), nullptr, 2)); @@ -155,7 +157,7 @@ namespace olympia if (jinst.find("vta") != jinst.end()) { - const bool vta = jinst["vta"].get() > 0 ? true: false; + const bool vta = jinst["vta"].get() > 0 ? true : false; vector_config->setVTA(vta); } diff --git a/core/VectorUopGenerator.cpp b/core/VectorUopGenerator.cpp index adeb687a..c6cd7868 100644 --- a/core/VectorUopGenerator.cpp +++ b/core/VectorUopGenerator.cpp @@ -1,6 +1,9 @@ #include "VectorUopGenerator.hpp" +#include "Inst.hpp" +#include "InstArchInfo.hpp" #include "mavis/Mavis.h" #include "sparta/utils/LogUtils.hpp" +#include namespace olympia { @@ -12,19 +15,16 @@ namespace olympia vuops_generated_(&unit_stat_set_, "vector_uops_generated", "Number of vector uops generated", sparta::Counter::COUNT_NORMAL) { - // Vector uop generator, increment all src and dest register numbers + // Vector elementwise uop generator, increment all src and dest register numbers // For a "vadd.vv v12, v4,v8" with an LMUL of 4: // Uop 1: vadd.vv v12, v4, v8 // Uop 2: vadd.vv v13, v5, v9 // Uop 3: vadd.vv v14, v6, v10 // Uop 4: vadd.vv v15, v7, v11 { - constexpr bool SINGLE_DEST = false; - constexpr bool WIDE_DEST = false; - constexpr bool ADD_DEST_AS_SRC = false; uop_gen_function_map_.emplace( InstArchInfo::UopGenType::ELEMENTWISE, - &VectorUopGenerator::generateUops); + &VectorUopGenerator::generateUops); } // Vector single dest uop generator, only increment all src register numbers @@ -34,16 +34,14 @@ namespace olympia // Uop 3: vmseq.vv v12, v6, v10 // Uop 4: vmseq.vv v12, v7, v11 { - constexpr bool SINGLE_DEST = true; - constexpr bool WIDE_DEST = false; - constexpr bool ADD_DEST_AS_SRC = false; uop_gen_function_map_.emplace( InstArchInfo::UopGenType::SINGLE_DEST, - &VectorUopGenerator::generateUops); + &VectorUopGenerator::generateUops); } - // Vector wide dest uop generator, only increment src register numbers for even - // uops For a "vwmul.vv v12, v4, v8" with an LMUL of 4: + // Vector wide uop generator, only increment src register numbers for even + // uops + // For a "vwmul.vv v12, v4, v8" with an LMUL of 4: // Uop 1: vwmul.vv v12, v4, v8 // Uop 2: vwmul.vv v13, v4, v8 // Uop 3: vwmul.vv v14, v6, v10 @@ -53,12 +51,25 @@ namespace olympia // Uop 7: vwmul.vv v18, v10, v14 // Uop 8: vwmul.vv v19, v10, v14 { - constexpr bool SINGLE_DEST = false; - constexpr bool WIDENING = true; - constexpr bool ADD_DEST_AS_SRC = false; uop_gen_function_map_.emplace( InstArchInfo::UopGenType::WIDENING, - &VectorUopGenerator::generateUops); + &VectorUopGenerator::generateUops); + } + + // Vector wide mixed uop generator + // For a "vwaddu.wv v12, v4, v8" with an LMUL of 4: + // Uop 1: vwaddu.wv v12, v4, v8 + // Uop 2: vwaddu.wv v13, v5, v8 + // Uop 3: vwaddu.wv v14, v6, v10 + // Uop 4: vwaddu.wv v15, v7, v10 + // Uop 5: vwaddu.wv v16, v8, v12 + // Uop 6: vwaddu.wv v17, v9, v12 + // Uop 7: vwaddu.wv v18, v10, v14 + // Uop 8: vwaddu.wv v19, v11, v14 + { + uop_gen_function_map_.emplace( + InstArchInfo::UopGenType::WIDENING_MIXED, + &VectorUopGenerator::generateUops); } // Vector arithmetic multiply-add uop generator, add dest as source @@ -68,15 +79,12 @@ namespace olympia // Uop 3: vmacc.vv v14, v6, v10, v14 // Uop 4: vmacc.vv v15, v7, v11, v15 { - constexpr bool SINGLE_DEST = false; - constexpr bool WIDE_DEST = false; - constexpr bool ADD_DEST_AS_SRC = true; uop_gen_function_map_.emplace( InstArchInfo::UopGenType::MAC, - &VectorUopGenerator::generateUops); + &VectorUopGenerator::generateUops); } - // Vector multiply-add wide dest uop generator, add dest as source + // Vector multiply-add wide dest uop generator // For a "vwmacc.vv v12, v4, v8" with an LMUL of 4: // Uop 1: vwmacc.vv v12, v4, v8, v12 // Uop 2: vwmacc.vv v13, v4, v8, v13 @@ -87,12 +95,37 @@ namespace olympia // Uop 7: vwmacc.vv v18, v7, v11, v18 // Uop 8: vwmacc.vv v19, v7, v11, v19 { - constexpr bool SINGLE_DEST = false; - constexpr bool WIDE_DEST = true; - constexpr bool ADD_DEST_AS_SRC = true; uop_gen_function_map_.emplace( InstArchInfo::UopGenType::MAC_WIDE, - &VectorUopGenerator::generateUops); + &VectorUopGenerator::generateUops); + } + + // Vector fixed point clip narrow uop generator + // For a "vnclipu.wv v0, v4, v8" with an LMUL of 4: + // Uop 1: vnclipu.wv v0, v4, v12 + // Uop 2: vnclipu.wv v0, v5, v12 + // Uop 3: vnclipu.wv v1, v6, v13 + // Uop 4: vnclipu.wv v1, v7, v13 + // Uop 5: vnclipu.wv v2, v8, v14 + // Uop 6: vnclipu.wv v2, v9, v14 + // Uop 7: vnclipu.wv v3, v10, v15 + // Uop 8: vnclipu.wv v3, v11, v15 + { + uop_gen_function_map_.emplace( + InstArchInfo::UopGenType::NARROWING, + &VectorUopGenerator::generateUops); + } + + // Vector fixed point clip narrow uop generator + // For a "vzext.vf4 v0, v4" with an LMUL of 4: + // Uop 1: vzext.vf4 v0, v4 + // Uop 2: vzext.vf4 v1, v4 + // Uop 3: vzext.vf4 v2, v4 + // Uop 4: vzext.vf4 v3, v4 + { + uop_gen_function_map_.emplace( + InstArchInfo::UopGenType::INT_EXT, + &VectorUopGenerator::generateUops); } } @@ -111,15 +144,39 @@ namespace olympia sparta_assert(uop_gen_type != InstArchInfo::UopGenType::NONE, "Inst: " << current_inst_ << " uop gen type is none"); + if (uop_gen_type == InstArchInfo::UopGenType::INT_EXT) + { + auto mnemonic = inst->getMnemonic(); + auto modifier = mnemonic.substr(mnemonic.find(".") + 1); + + if (modifier == "vf2") + { + addModifier("viext", 2); + } + else if (modifier == "vf4") + { + addModifier("viext", 4); + } + else if (modifier == "vf8") + { + addModifier("viext", 8); + } + } + // Number of vector elements processed by each uop const VectorConfigPtr & vector_config = inst->getVectorConfig(); const uint64_t num_elems_per_uop = VectorConfig::VLEN / vector_config->getSEW(); // TODO: For now, generate uops for all elements even if there is a tail num_uops_to_generate_ = std::ceil(vector_config->getVLMAX() / num_elems_per_uop); - if ((uop_gen_type == InstArchInfo::UopGenType::WIDENING) - || (uop_gen_type == InstArchInfo::UopGenType::MAC_WIDE)) + if (uop_gen_type == InstArchInfo::UopGenType::WIDENING + || uop_gen_type == InstArchInfo::UopGenType::WIDENING_MIXED + || uop_gen_type == InstArchInfo::UopGenType::MAC_WIDE + || uop_gen_type == InstArchInfo::UopGenType::NARROWING) { + sparta_assert(vector_config->getLMUL() <= 4, + "LMUL must be lower or equal to 4.\n" + "These modes set EMUL = 2 * LMUL <= 8."); // TODO: Add parameter to support dual dests num_uops_to_generate_ *= 2; } @@ -168,27 +225,46 @@ namespace olympia return uop; } - template - const InstPtr VectorUopGenerator::generateUops() + template const InstPtr VectorUopGenerator::generateUops() { - // Increment source and destination register values auto srcs = current_inst_->getSourceOpInfoList(); for (auto & src : srcs) { - // Do not increment scalar sources for transfer instructions if (src.operand_type != mavis::InstMetaData::OperandTypes::VECTOR) - { continue; - } - if constexpr (WIDE_DEST == true) + if constexpr (Type == InstArchInfo::UopGenType::ELEMENTWISE + || Type == InstArchInfo::UopGenType::MAC) + { + src.field_value += num_uops_generated_; + } + else if constexpr (Type == InstArchInfo::UopGenType::WIDENING + || Type == InstArchInfo::UopGenType::MAC_WIDE) { - // Only increment source values for even uops src.field_value += num_uops_generated_ / 2; } - else + else if constexpr (Type == InstArchInfo::UopGenType::WIDENING_MIXED) { - src.field_value += num_uops_generated_; + if (src.field_id == mavis::InstMetaData::OperandFieldID::RS2) + src.field_value += num_uops_generated_; + else if (src.field_id == mavis::InstMetaData::OperandFieldID::RS1) + src.field_value += num_uops_generated_ / 2; + } + else if constexpr (Type == InstArchInfo::UopGenType::NARROWING) + { + if (src.field_id == mavis::InstMetaData::OperandFieldID::RS2) + src.field_value += num_uops_generated_ / 2; + else if (src.field_id == mavis::InstMetaData::OperandFieldID::RS1) + src.field_value += num_uops_generated_; + } + else if constexpr (Type == InstArchInfo::UopGenType::INT_EXT) + { + auto ext = getModifier("viext"); + if (!ext) + { + throw sparta::SpartaException("Modifier at current instruction doesnt exist."); + } + src.field_value += num_uops_generated_ / *ext; } } @@ -208,38 +284,27 @@ namespace olympia }; auto dests = current_inst_->getDestOpInfoList(); - if constexpr (SINGLE_DEST == false) + if constexpr (Type != InstArchInfo::UopGenType::SINGLE_DEST) { for (auto & dest : dests) { - dest.field_value += num_uops_generated_; - - if constexpr (ADD_DEST_AS_SRC == true) + if constexpr (Type == InstArchInfo::UopGenType::NARROWING) { - add_dest_as_src(srcs, dest); + dest.field_value += num_uops_generated_ / 2; + } + else + { + dest.field_value += num_uops_generated_; } - } - } - - // If uop contains tail or masked elements that need to be left undisturbed, we need to add - // the destination registers as source registers - if constexpr (ADD_DEST_AS_SRC == false) - { - const VectorConfigPtr & vector_config = current_inst_->getVectorConfig(); - const uint32_t num_elems_per_uop = vector_config->getVLMAX() / vector_config->getSEW(); - const bool uop_contains_tail_elems = - (num_elems_per_uop * num_uops_generated_) > vector_config->getVL(); - if (uop_contains_tail_elems && (vector_config->getVTA() == false)) - { - for (auto & dest : dests) + if constexpr (Type == InstArchInfo::UopGenType::MAC + || Type == InstArchInfo::UopGenType::MAC_WIDE) { add_dest_as_src(srcs, dest); } } } - // Create uop InstPtr uop; if (current_inst_->hasImmediate()) { diff --git a/core/VectorUopGenerator.hpp b/core/VectorUopGenerator.hpp index 23f55435..07032f9d 100644 --- a/core/VectorUopGenerator.hpp +++ b/core/VectorUopGenerator.hpp @@ -10,6 +10,8 @@ #include "FlushManager.hpp" #include "MavisUnit.hpp" +#include + namespace olympia { @@ -20,6 +22,22 @@ namespace olympia class VectorUopGenerator : public sparta::Unit { public: + class Modifier + { + public: + Modifier(std::string name, uint32_t value) : name_{name}, data_{value} {} + + std::string getName() const { return name_; } + + uint32_t getValue() const { return data_; } + + void setValue(uint32_t newValue) { data_ = newValue; } + + private: + std::string name_; + uint32_t data_; + }; + //! \brief Parameters for VectorUopGenerator model class VectorUopGeneratorParameterSet : public sparta::ParameterSet { @@ -46,8 +64,7 @@ namespace olympia const InstPtr generateUop(); - template - const InstPtr generateUops(); + template const InstPtr generateUops(); uint64_t getNumUopsRemaining() const { return num_uops_to_generate_; } @@ -65,6 +82,7 @@ namespace olympia // TODO: Use Sparta ValidValue InstPtr current_inst_ = nullptr; + std::vector current_inst_modifiers_; // UopGenFunctionMapType::iterator current_uop_gen_function_; sparta::Counter vuops_generated_; @@ -75,11 +93,29 @@ namespace olympia void reset_() { current_inst_ = nullptr; + current_inst_modifiers_.clear(); num_uops_generated_ = 0; num_uops_to_generate_ = 0; } - friend class VectorUopGeneratorTester; + void addModifier(const std::string & name, uint32_t value) + { + current_inst_modifiers_.emplace_back(name, value); + } + + std::optional getModifier(const std::string & name) + { + for (auto & m : current_inst_modifiers_) + { + if (m.getName() == name) + { + return m.getValue(); + } + } + return {}; + } + + friend class VectorUopGeneratorTester; }; class VectorUopGeneratorTester; diff --git a/test/core/dispatch/Dispatch_test.cpp b/test/core/dispatch/Dispatch_test.cpp index be1a1b54..134f185a 100644 --- a/test/core/dispatch/Dispatch_test.cpp +++ b/test/core/dispatch/Dispatch_test.cpp @@ -33,10 +33,6 @@ TEST_INIT -//////////////////////////////////////////////////////////////////////////////// -// Set up the Mavis decoder globally for the testing -olympia::InstAllocator inst_allocator(2000, 1000); - const char USAGE[] = "Usage:\n" " \n" "\n"; diff --git a/test/core/issue_queue/IssueQueue_test.cpp b/test/core/issue_queue/IssueQueue_test.cpp index dc4bd4dc..0e2a9f84 100644 --- a/test/core/issue_queue/IssueQueue_test.cpp +++ b/test/core/issue_queue/IssueQueue_test.cpp @@ -27,10 +27,6 @@ #include TEST_INIT -//////////////////////////////////////////////////////////////////////////////// -// Set up the Mavis decoder globally for the testing -olympia::InstAllocator inst_allocator(2000, 1000); - const char USAGE[] = "Usage:\n" " \n" "\n"; diff --git a/test/core/rename/Rename_test.cpp b/test/core/rename/Rename_test.cpp index ca3c7225..5374fc11 100644 --- a/test/core/rename/Rename_test.cpp +++ b/test/core/rename/Rename_test.cpp @@ -32,10 +32,6 @@ TEST_INIT -//////////////////////////////////////////////////////////////////////////////// -// Set up the Mavis decoder globally for the testing -olympia::InstAllocator inst_allocator(2000, 1000); - class olympia::RenameTester { public: void test_clearing_rename_structures(olympia::Rename &rename) { diff --git a/test/core/vector/CMakeLists.txt b/test/core/vector/CMakeLists.txt index 4f2c404f..4f6fde31 100644 --- a/test/core/vector/CMakeLists.txt +++ b/test/core/vector/CMakeLists.txt @@ -29,3 +29,38 @@ sparta_named_test(Vector_test_vmulvv Vector_test -l top info vmulvv.out sparta_named_test(Vector_test_vmseqvv Vector_test -l top info vmseqvv.out -c test_cores/test_big_core.yaml --input-file vmseqvv_e8m4.json) sparta_named_test(Vector_test_vsadd Vector_test -l top info vsadd.out -c test_cores/test_big_core.yaml --input-file vsadd.json) sparta_named_test(Vector_unsupported_test Vector_test -l top info unsupported.out -c test_cores/test_big_core.yaml --input-file vrgather.json) + +file(CREATE_LINK ${CMAKE_CURRENT_SOURCE_DIR}/elementwise.json ${CMAKE_CURRENT_BINARY_DIR}/elementwise.json SYMBOLIC) +file(CREATE_LINK ${CMAKE_CURRENT_SOURCE_DIR}/widening.json ${CMAKE_CURRENT_BINARY_DIR}/widening.json SYMBOLIC) +file(CREATE_LINK ${CMAKE_CURRENT_SOURCE_DIR}/widening_mixed.json ${CMAKE_CURRENT_BINARY_DIR}/widening_mixed.json SYMBOLIC) +file(CREATE_LINK ${CMAKE_CURRENT_SOURCE_DIR}/narrowing.json ${CMAKE_CURRENT_BINARY_DIR}/narrowing.json SYMBOLIC) +file(CREATE_LINK ${CMAKE_CURRENT_SOURCE_DIR}/mac.json ${CMAKE_CURRENT_BINARY_DIR}/mac.json SYMBOLIC) +file(CREATE_LINK ${CMAKE_CURRENT_SOURCE_DIR}/mac_widening.json ${CMAKE_CURRENT_BINARY_DIR}/mac_widening.json SYMBOLIC) +file(CREATE_LINK ${CMAKE_CURRENT_SOURCE_DIR}/single_dest.json ${CMAKE_CURRENT_BINARY_DIR}/single_dest.json SYMBOLIC) +file(CREATE_LINK ${CMAKE_CURRENT_SOURCE_DIR}/int_ext.json ${CMAKE_CURRENT_BINARY_DIR}/int_ext.json SYMBOLIC) + +sparta_named_test(Vector_test_elementwise + Vector_test -l top info vuop_elementwise.out -c test_cores/test_big_core.yaml --input-file elementwise.json +) +sparta_named_test(Vector_test_widening + Vector_test -l top info vuop_widening.out -c test_cores/test_big_core.yaml --input-file widening.json +) +sparta_named_test(Vector_test_widening_mixed + Vector_test -l top info vuop_widening_mixed.out -c test_cores/test_big_core.yaml --input-file widening_mixed.json +) +sparta_named_test(Vector_test_narrowing + Vector_test -l top info vuop_narrowing.out -c test_cores/test_big_core.yaml --input-file narrowing.json +) +sparta_named_test(Vector_test_mac + Vector_test -l top info vuop_mac.out -c test_cores/test_big_core.yaml --input-file mac.json +) +sparta_named_test(Vector_test_mac_widening + Vector_test -l top info vuop_mac_widening.out -c test_cores/test_big_core.yaml --input-file mac_widening.json +) +sparta_named_test(Vector_test_single_dest + Vector_test -l top info vuop_single_dest.out -c test_cores/test_big_core.yaml --input-file single_dest.json +) + +sparta_named_test(Vector_test_int_ext + Vector_test -l top info vuop_int_ext.out -c test_cores/test_big_core.yaml --input-file int_ext.json +) diff --git a/test/core/vector/Vector_test.cpp b/test/core/vector/Vector_test.cpp index 7005129c..ea3575d9 100644 --- a/test/core/vector/Vector_test.cpp +++ b/test/core/vector/Vector_test.cpp @@ -1,36 +1,16 @@ -#include "CPUFactory.hpp" -#include "CoreUtils.hpp" -#include "Dispatch.hpp" -#include "InstArchInfo.hpp" -#include "MavisUnit.hpp" -#include "OlympiaAllocators.hpp" #include "OlympiaSim.hpp" -#include "IssueQueue.hpp" +#include "Decode.hpp" +#include "ROB.hpp" #include "VectorUopGenerator.hpp" #include "sparta/app/CommandLineSimulator.hpp" -#include "sparta/app/Simulation.hpp" -#include "sparta/events/UniqueEvent.hpp" #include "sparta/kernel/Scheduler.hpp" -#include "sparta/report/Report.hpp" -#include "sparta/resources/Buffer.hpp" #include "sparta/simulation/ClockManager.hpp" -#include "sparta/sparta.hpp" -#include "sparta/statistics/StatisticSet.hpp" #include "sparta/utils/SpartaSharedPointer.hpp" #include "sparta/utils/SpartaTester.hpp" -#include -#include -#include -#include -#include TEST_INIT -//////////////////////////////////////////////////////////////////////////////// -// Set up the Mavis decoder globally for the testing -olympia::InstAllocator inst_allocator(2000, 1000); - const char USAGE[] = "Usage:\n" "\n" "\n"; @@ -133,8 +113,7 @@ void runTests(int argc, char** argv) int err_code = 0; if (!cls.parse(argc, argv, err_code)) { - sparta_assert(false, - "Command line parsing failed"); // Any errors already printed to cerr + sparta_assert(false, "Command line parsing failed"); } sparta::Scheduler scheduler; @@ -310,6 +289,102 @@ void runTests(int argc, char** argv) vuop_tester.test_num_vuops_generated(4); } + else if (input_file.find("elementwise.json") != std::string::npos) + { + cls.runSimulator(&sim); + + decode_tester.test_lmul(4); + decode_tester.test_vl(256); + decode_tester.test_vta(false); + decode_tester.test_sew(32); + decode_tester.test_vlmax(128); + + vuop_tester.test_num_vuops_generated(4); + } + else if (input_file.find("widening.json") != std::string::npos) + { + cls.runSimulator(&sim); + + decode_tester.test_lmul(4); + decode_tester.test_vl(256); + decode_tester.test_vta(false); + decode_tester.test_sew(32); + decode_tester.test_vlmax(128); + + vuop_tester.test_num_vuops_generated(8); + } + else if (input_file.find("widening_mixed.json") != std::string::npos) + { + cls.runSimulator(&sim); + + decode_tester.test_lmul(4); + decode_tester.test_vl(256); + decode_tester.test_vta(false); + decode_tester.test_sew(32); + decode_tester.test_vlmax(128); + + vuop_tester.test_num_vuops_generated(8); + } + else if (input_file.find("mac.json") != std::string::npos) + { + cls.runSimulator(&sim); + + decode_tester.test_lmul(4); + decode_tester.test_vl(256); + decode_tester.test_vta(false); + decode_tester.test_sew(32); + decode_tester.test_vlmax(128); + + vuop_tester.test_num_vuops_generated(4); + } + else if (input_file.find("mac_widening.json") != std::string::npos) + { + cls.runSimulator(&sim); + + decode_tester.test_lmul(4); + decode_tester.test_vl(256); + decode_tester.test_vta(false); + decode_tester.test_sew(32); + decode_tester.test_vlmax(128); + + vuop_tester.test_num_vuops_generated(8); + } + else if (input_file.find("single_dest.json") != std::string::npos) + { + cls.runSimulator(&sim); + + decode_tester.test_lmul(4); + decode_tester.test_vl(256); + decode_tester.test_vta(false); + decode_tester.test_sew(32); + decode_tester.test_vlmax(128); + + vuop_tester.test_num_vuops_generated(4); + } + else if (input_file.find("narrowing.json") != std::string::npos) + { + cls.runSimulator(&sim); + + decode_tester.test_lmul(4); + decode_tester.test_vl(256); + decode_tester.test_vta(false); + decode_tester.test_sew(32); + decode_tester.test_vlmax(128); + + vuop_tester.test_num_vuops_generated(8); + } + else if (input_file.find("int_ext.json") != std::string::npos) + { + cls.runSimulator(&sim); + + decode_tester.test_lmul(4); + decode_tester.test_vl(256); + decode_tester.test_vta(false); + decode_tester.test_sew(64); + decode_tester.test_vlmax(64); + + vuop_tester.test_num_vuops_generated(12); + } else { sparta_assert(false, "Invalid input file: " << input_file); diff --git a/test/core/vector/elementwise.json b/test/core/vector/elementwise.json new file mode 100644 index 00000000..5c63fb3d --- /dev/null +++ b/test/core/vector/elementwise.json @@ -0,0 +1,16 @@ +[ + { + "mnemonic": "vsetivli", + "rd": 0, + "imm": 256, + "vtype": "0x12", + "vl": 256, + "vta": 0 + }, + { + "mnemonic": "vadd.vv", + "vd": 12, + "vs2": 4, + "vs1": 8 + } +] diff --git a/test/core/vector/int_ext.json b/test/core/vector/int_ext.json new file mode 100644 index 00000000..cbe19ec1 --- /dev/null +++ b/test/core/vector/int_ext.json @@ -0,0 +1,25 @@ +[ + { + "mnemonic": "vsetivli", + "rd": 0, + "imm": 256, + "vtype": "0x1a", + "vl": 256, + "vta": 0 + }, + { + "mnemonic": "vzext.vf2", + "vd": 4, + "vs2": 8 + }, + { + "mnemonic": "vzext.vf4", + "vd": 4, + "vs2": 8 + }, + { + "mnemonic": "vzext.vf8", + "vd": 4, + "vs2": 8 + } +] diff --git a/test/core/vector/mac.json b/test/core/vector/mac.json new file mode 100644 index 00000000..4934a857 --- /dev/null +++ b/test/core/vector/mac.json @@ -0,0 +1,16 @@ +[ + { + "mnemonic": "vsetivli", + "rd": 0, + "imm": 256, + "vtype": "0x12", + "vl": 256, + "vta": 0 + }, + { + "mnemonic": "vmacc.vv", + "vd": 12, + "vs2": 4, + "vs1": 8 + } +] diff --git a/test/core/vector/mac_widening.json b/test/core/vector/mac_widening.json new file mode 100644 index 00000000..5bd133b0 --- /dev/null +++ b/test/core/vector/mac_widening.json @@ -0,0 +1,16 @@ +[ + { + "mnemonic": "vsetivli", + "rd": 0, + "imm": 256, + "vtype": "0x12", + "vl": 256, + "vta": 0 + }, + { + "mnemonic": "vwmacc.vv", + "vd": 12, + "vs2": 4, + "vs1": 8 + } +] diff --git a/test/core/vector/narrowing.json b/test/core/vector/narrowing.json new file mode 100644 index 00000000..88342956 --- /dev/null +++ b/test/core/vector/narrowing.json @@ -0,0 +1,16 @@ +[ + { + "mnemonic": "vsetivli", + "rd": 0, + "imm": 256, + "vtype": "0x12", + "vl": 256, + "vta": 0 + }, + { + "mnemonic": "vnclipu.wv", + "vd": 0, + "vs2": 4, + "vs1": 8 + } +] diff --git a/test/core/vector/single_dest.json b/test/core/vector/single_dest.json new file mode 100644 index 00000000..bcdcf1e8 --- /dev/null +++ b/test/core/vector/single_dest.json @@ -0,0 +1,16 @@ +[ + { + "mnemonic": "vsetivli", + "rd": 0, + "imm": 256, + "vtype": "0x12", + "vl": 256, + "vta": 0 + }, + { + "mnemonic": "vmseq.vv", + "vd": 0, + "vs2": 4, + "vs1": 8 + } +] diff --git a/test/core/vector/widening.json b/test/core/vector/widening.json new file mode 100644 index 00000000..c803566f --- /dev/null +++ b/test/core/vector/widening.json @@ -0,0 +1,16 @@ +[ + { + "mnemonic": "vsetivli", + "rd": 0, + "imm": 256, + "vtype": "0x12", + "vl": 256, + "vta": 0 + }, + { + "mnemonic": "vwmul.vv", + "vd": 12, + "vs2": 4, + "vs1": 8 + } +] diff --git a/test/core/vector/widening_mixed.json b/test/core/vector/widening_mixed.json new file mode 100644 index 00000000..996e5c3c --- /dev/null +++ b/test/core/vector/widening_mixed.json @@ -0,0 +1,16 @@ +[ + { + "mnemonic": "vsetivli", + "rd": 0, + "imm": 256, + "vtype": "0x12", + "vl": 256, + "vta": 0 + }, + { + "mnemonic": "vwaddu.vv", + "vd": 12, + "vs2": 4, + "vs1": 8 + } +]