From f8613ef25d7332aeb429e2e25c9842ac9dcdf623 Mon Sep 17 00:00:00 2001 From: Isaac David Date: Sun, 8 Dec 2024 01:56:22 +0000 Subject: [PATCH 1/6] [vuop_gen] --- arches/isa_json/gen_uarch_rv64v_json.py | 15 +- arches/isa_json/olympia_uarch_rv64v.json | 36 ++-- core/Inst.hpp | 64 +++++-- core/InstArchInfo.cpp | 1 + core/InstArchInfo.hpp | 1 + core/InstGenerator.cpp | 25 ++- core/VectorUopGenerator.cpp | 155 ++++++++++------ core/VectorUopGenerator.hpp | 2 +- test/core/vector/CMakeLists.txt | 43 +++++ test/core/vector/Vuop_test.cpp | 216 +++++++++++++++++++++++ test/core/vector/elementwise.json | 16 ++ test/core/vector/int_ext.json | 25 +++ test/core/vector/mac.json | 16 ++ test/core/vector/mac_widening.json | 16 ++ test/core/vector/narrowing.json | 16 ++ test/core/vector/single_dest.json | 16 ++ test/core/vector/widening.json | 16 ++ test/core/vector/widening_mixed.json | 16 ++ 18 files changed, 594 insertions(+), 101 deletions(-) create mode 100644 test/core/vector/Vuop_test.cpp create mode 100644 test/core/vector/elementwise.json create mode 100644 test/core/vector/int_ext.json create mode 100644 test/core/vector/mac.json create mode 100644 test/core/vector/mac_widening.json create mode 100644 test/core/vector/narrowing.json create mode 100644 test/core/vector/single_dest.json create mode 100644 test/core/vector/widening.json create mode 100644 test/core/vector/widening_mixed.json diff --git a/arches/isa_json/gen_uarch_rv64v_json.py b/arches/isa_json/gen_uarch_rv64v_json.py index 9307c65f..8f861fde 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 @@ -188,7 +186,6 @@ "vwmaccus.vx" : {"pipe" : "vmul", "uop_gen" : "MAC_WIDE", "latency" : 3}, # Vector Integer Arithmetic Instructions: Vector Integer Merge Instructions -# FIXME: Requires Mavis fix to include vector mask "vmerge.vvm" : {"pipe" : "vint", "uop_gen" : "ELEMENTWISE", "latency" : 1}, "vmerge.vxm" : {"pipe" : "vint", "uop_gen" : "ELEMENTWISE", "latency" : 1}, "vmerge.vim" : {"pipe" : "vint", "uop_gen" : "ELEMENTWISE", "latency" : 1}, 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..c5324af6 100644 --- a/core/Inst.hpp +++ b/core/Inst.hpp @@ -18,11 +18,13 @@ #include "VectorConfig.hpp" #include "MiscUtils.hpp" +#include #include #include #include #include #include +#include namespace olympia { @@ -75,6 +77,22 @@ namespace olympia Reg data_reg_; }; + 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_; + }; + // Used by Mavis using PtrType = sparta::SpartaSharedPointer; @@ -221,29 +239,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 +294,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 +316,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 +363,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 @@ -419,6 +439,20 @@ namespace olympia return ss.str(); } + void addModifier(std::string name, uint32_t value) { modifiers_.emplace_back(name, value); } + + std::optional getModifier(std::string name) + { + for (auto & m : modifiers_) + { + if (m.getName() == name) + { + return m.getValue(); + } + } + return {}; + } + private: mavis::OpcodeInfo::PtrType opcode_info_; InstArchInfo::PtrType inst_arch_info_; @@ -473,6 +507,8 @@ namespace olympia RegisterBitMaskArray store_data_mask_; RenameData rename_data; static const std::unordered_map status2String; + + std::vector modifiers_; }; using InstPtr = Inst::PtrType; 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..acb04e37 100644 --- a/core/InstGenerator.cpp +++ b/core/InstGenerator.cpp @@ -134,10 +134,28 @@ namespace olympia mavis::ExtractorDirectOpInfoList ex_info(mnemonic, srcs, dests); inst = mavis_facade_->makeInstDirectly(ex_info, clk); } + if (inst->getUopGenType() == InstArchInfo::UopGenType::INT_EXT) + { + auto modifier = mnemonic.substr(mnemonic.find(".") + 1); + + if (modifier == "vf2") + { + inst->addModifier("viext", 2); + } + else if (modifier == "vf4") + { + inst->addModifier("viext", 4); + } + else if (modifier == "vf8") + { + inst->addModifier("viext", 8); + } + } 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 +163,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 +174,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..2dd061dd 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); } } @@ -117,8 +150,10 @@ namespace olympia // 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) { // TODO: Add parameter to support dual dests num_uops_to_generate_ *= 2; @@ -168,27 +203,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 = current_inst_->getModifier("viext"); + if (!ext) + { + throw sparta::SpartaException("Modifier at current instruction doesnt exist."); + } + src.field_value += num_uops_generated_ / ext.value(); } } @@ -208,38 +262,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..41b3cdfc 100644 --- a/core/VectorUopGenerator.hpp +++ b/core/VectorUopGenerator.hpp @@ -46,7 +46,7 @@ namespace olympia const InstPtr generateUop(); - template + template const InstPtr generateUops(); uint64_t getNumUopsRemaining() const { return num_uops_to_generate_; } diff --git a/test/core/vector/CMakeLists.txt b/test/core/vector/CMakeLists.txt index 4f2c404f..d5548676 100644 --- a/test/core/vector/CMakeLists.txt +++ b/test/core/vector/CMakeLists.txt @@ -29,3 +29,46 @@ 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) + +add_executable(Vuop_test + Vuop_test.cpp ${SIM_BASE}/sim/OlympiaSim.cpp +) + +target_link_libraries(Vuop_test + PRIVATE + core common_test ${STF_LINK_LIBS} mavis SPARTA::sparta +) +sparta_named_test(Vuop_test_elementwise + Vuop_test -l top info vuop_elementwise.out -c test_cores/test_big_core.yaml --input-file elementwise.json +) +sparta_named_test(Vuop_test_widening + Vuop_test -l top info vuop_widening.out -c test_cores/test_big_core.yaml --input-file widening.json +) +sparta_named_test(Vuop_test_widening_mixed + Vuop_test -l top info vuop_widening_mixed.out -c test_cores/test_big_core.yaml --input-file widening_mixed.json +) +sparta_named_test(Vuop_test_narrowing + Vuop_test -l top info vuop_narrowing.out -c test_cores/test_big_core.yaml --input-file narrowing.json +) +sparta_named_test(Vuop_test_mac + Vuop_test -l top info vuop_mac.out -c test_cores/test_big_core.yaml --input-file mac.json +) +sparta_named_test(Vuop_test_mac_widening + Vuop_test -l top info vuop_mac_widening.out -c test_cores/test_big_core.yaml --input-file mac_widening.json +) +sparta_named_test(Vuop_test_single_dest + Vuop_test -l top info vuop_single_dest.out -c test_cores/test_big_core.yaml --input-file single_dest.json +) + +sparta_named_test(Vuop_test_int_ext + Vuop_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/Vuop_test.cpp b/test/core/vector/Vuop_test.cpp new file mode 100644 index 00000000..9ede9c10 --- /dev/null +++ b/test/core/vector/Vuop_test.cpp @@ -0,0 +1,216 @@ +#include "OlympiaSim.hpp" +#include "Decode.hpp" +#include "VectorUopGenerator.hpp" + +#include "sparta/app/CommandLineSimulator.hpp" +#include "sparta/kernel/Scheduler.hpp" +#include "sparta/simulation/ClockManager.hpp" +#include "sparta/utils/SpartaSharedPointer.hpp" +#include "sparta/utils/SpartaTester.hpp" + +TEST_INIT + +const char USAGE[] = "Usage:\n" + "\n" + "\n"; + +sparta::app::DefaultValues DEFAULTS; + +class olympia::DecodeTester +{ + public: + DecodeTester(olympia::Decode* decode) : decode_(decode) {} + + void test_waiting_on_vset() { EXPECT_TRUE(decode_->waiting_on_vset_ == true); } + + void test_waiting_on_vset(const bool expected_val) + { + EXPECT_TRUE(decode_->waiting_on_vset_ == expected_val); + } + + void test_vl(const uint32_t expected_vl) + { + EXPECT_TRUE(decode_->vector_config_->getVL() == expected_vl); + } + + void test_sew(const uint32_t expected_sew) + { + EXPECT_TRUE(decode_->vector_config_->getSEW() == expected_sew); + } + + void test_lmul(const uint32_t expected_lmul) + { + EXPECT_TRUE(decode_->vector_config_->getLMUL() == expected_lmul); + } + + void test_vlmax(const uint32_t expected_vlmax) + { + EXPECT_TRUE(decode_->vector_config_->getVLMAX() == expected_vlmax); + } + + void test_vta(const bool expected_vta) + { + EXPECT_TRUE(decode_->vector_config_->getVTA() == expected_vta); + } + + private: + olympia::Decode* decode_; +}; + +class olympia::VectorUopGeneratorTester +{ + public: + VectorUopGeneratorTester(olympia::VectorUopGenerator* vuop) : vuop_{vuop} {} + + void test_num_vuops_generated(const uint64_t expected_num_vuops_generated) + { + EXPECT_TRUE(vuop_->vuops_generated_ == expected_num_vuops_generated); + } + + private: + VectorUopGenerator* vuop_; +}; + +void runTests(int argc, char** argv) +{ + DEFAULTS.auto_summary_default = "off"; + std::string input_file; + + sparta::app::CommandLineSimulator cls(USAGE, DEFAULTS); + auto & app_opts = cls.getApplicationOptions(); + app_opts.add_options()( + "input-file", + sparta::app::named_value("INPUT_FILE", &input_file)->default_value(""), + "Provide a JSON instruction stream", + "Provide a JSON file with instructions to run through Execute"); + + int err_code = 0; + if (!cls.parse(argc, argv, err_code)) + { + sparta_assert(false, "Command line parsing failed"); + } + + sparta::Scheduler scheduler; + uint32_t num_cores = 1; + uint64_t ilimit = 0; + bool show_factories = false; + OlympiaSim sim("simple", scheduler, num_cores, input_file, ilimit, show_factories); + sparta::RootTreeNode* root_node = sim.getRoot(); + cls.populateSimulation(&sim); + + auto* my_decode = root_node->getChild("cpu.core0.decode")->getResourceAs(); + olympia::DecodeTester decode_tester{my_decode}; + + auto* my_vuop_generator = root_node->getChild("cpu.core0.decode.vec_uop_gen") + ->getResourceAs(); + olympia::VectorUopGeneratorTester vuop_tester{my_vuop_generator}; + + 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); + } +} + +int main(int argc, char** argv) +{ + runTests(argc, argv); + + REPORT_ERROR; + return (int)ERROR_CODE; +} 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 + } +] From 64d9cf6c53771a63bb734729aa5db9e22385a9cb Mon Sep 17 00:00:00 2001 From: Isaac David Date: Sun, 8 Dec 2024 15:03:22 +0000 Subject: [PATCH 2/6] replace access to value in Optional --- core/VectorUopGenerator.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/VectorUopGenerator.cpp b/core/VectorUopGenerator.cpp index 2dd061dd..14da49bd 100644 --- a/core/VectorUopGenerator.cpp +++ b/core/VectorUopGenerator.cpp @@ -242,7 +242,7 @@ namespace olympia { throw sparta::SpartaException("Modifier at current instruction doesnt exist."); } - src.field_value += num_uops_generated_ / ext.value(); + src.field_value += num_uops_generated_ / *ext; } } From f9c8a80fd18dcf1d507b0e3fbf9901d410da393f Mon Sep 17 00:00:00 2001 From: Isaac David Date: Fri, 13 Dec 2024 21:23:51 +0000 Subject: [PATCH 3/6] [vuop_gen] move logic for viext --- arches/isa_json/gen_uarch_rv64v_json.py | 1 + core/Inst.hpp | 33 ------------------- core/InstGenerator.cpp | 17 ---------- core/VectorUopGenerator.cpp | 21 ++++++++++++- core/VectorUopGenerator.hpp | 42 +++++++++++++++++++++++-- 5 files changed, 60 insertions(+), 54 deletions(-) diff --git a/arches/isa_json/gen_uarch_rv64v_json.py b/arches/isa_json/gen_uarch_rv64v_json.py index 8f861fde..e7fcf6a3 100755 --- a/arches/isa_json/gen_uarch_rv64v_json.py +++ b/arches/isa_json/gen_uarch_rv64v_json.py @@ -186,6 +186,7 @@ "vwmaccus.vx" : {"pipe" : "vmul", "uop_gen" : "MAC_WIDE", "latency" : 3}, # Vector Integer Arithmetic Instructions: Vector Integer Merge Instructions +# FIXME: Requires Mavis fix to include vector mask "vmerge.vvm" : {"pipe" : "vint", "uop_gen" : "ELEMENTWISE", "latency" : 1}, "vmerge.vxm" : {"pipe" : "vint", "uop_gen" : "ELEMENTWISE", "latency" : 1}, "vmerge.vim" : {"pipe" : "vint", "uop_gen" : "ELEMENTWISE", "latency" : 1}, diff --git a/core/Inst.hpp b/core/Inst.hpp index c5324af6..0b3bff93 100644 --- a/core/Inst.hpp +++ b/core/Inst.hpp @@ -24,7 +24,6 @@ #include #include #include -#include namespace olympia { @@ -77,22 +76,6 @@ namespace olympia Reg data_reg_; }; - 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_; - }; - // Used by Mavis using PtrType = sparta::SpartaSharedPointer; @@ -439,20 +422,6 @@ namespace olympia return ss.str(); } - void addModifier(std::string name, uint32_t value) { modifiers_.emplace_back(name, value); } - - std::optional getModifier(std::string name) - { - for (auto & m : modifiers_) - { - if (m.getName() == name) - { - return m.getValue(); - } - } - return {}; - } - private: mavis::OpcodeInfo::PtrType opcode_info_; InstArchInfo::PtrType inst_arch_info_; @@ -507,8 +476,6 @@ namespace olympia RegisterBitMaskArray store_data_mask_; RenameData rename_data; static const std::unordered_map status2String; - - std::vector modifiers_; }; using InstPtr = Inst::PtrType; diff --git a/core/InstGenerator.cpp b/core/InstGenerator.cpp index acb04e37..9ce6004e 100644 --- a/core/InstGenerator.cpp +++ b/core/InstGenerator.cpp @@ -134,23 +134,6 @@ namespace olympia mavis::ExtractorDirectOpInfoList ex_info(mnemonic, srcs, dests); inst = mavis_facade_->makeInstDirectly(ex_info, clk); } - if (inst->getUopGenType() == InstArchInfo::UopGenType::INT_EXT) - { - auto modifier = mnemonic.substr(mnemonic.find(".") + 1); - - if (modifier == "vf2") - { - inst->addModifier("viext", 2); - } - else if (modifier == "vf4") - { - inst->addModifier("viext", 4); - } - else if (modifier == "vf8") - { - inst->addModifier("viext", 8); - } - } if (jinst.find("vaddr") != jinst.end()) { diff --git a/core/VectorUopGenerator.cpp b/core/VectorUopGenerator.cpp index 14da49bd..7787544f 100644 --- a/core/VectorUopGenerator.cpp +++ b/core/VectorUopGenerator.cpp @@ -144,6 +144,25 @@ 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(); @@ -237,7 +256,7 @@ namespace olympia } else if constexpr (Type == InstArchInfo::UopGenType::INT_EXT) { - auto ext = current_inst_->getModifier("viext"); + auto ext = getModifier("viext"); if (!ext) { throw sparta::SpartaException("Modifier at current instruction doesnt exist."); diff --git a/core/VectorUopGenerator.hpp b/core/VectorUopGenerator.hpp index 41b3cdfc..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; From 2fe674d521df96cf405e819c86b3e892bc29ac9e Mon Sep 17 00:00:00 2001 From: Isaac David Date: Fri, 13 Dec 2024 21:30:06 +0000 Subject: [PATCH 4/6] [vuop_gen] add assertion on allowed LMUL on widening & narrowing modes --- core/VectorUopGenerator.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/core/VectorUopGenerator.cpp b/core/VectorUopGenerator.cpp index 7787544f..c6cd7868 100644 --- a/core/VectorUopGenerator.cpp +++ b/core/VectorUopGenerator.cpp @@ -174,6 +174,9 @@ namespace olympia || 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; } From 7c48970630e4c817f104e70313f70fef31971170 Mon Sep 17 00:00:00 2001 From: Isaac David Date: Fri, 13 Dec 2024 21:41:00 +0000 Subject: [PATCH 5/6] Unify tests --- test/core/vector/CMakeLists.txt | 40 +++--- test/core/vector/Vector_test.cpp | 123 ++++++++++++++---- test/core/vector/Vuop_test.cpp | 216 ------------------------------- 3 files changed, 115 insertions(+), 264 deletions(-) delete mode 100644 test/core/vector/Vuop_test.cpp diff --git a/test/core/vector/CMakeLists.txt b/test/core/vector/CMakeLists.txt index d5548676..4f6fde31 100644 --- a/test/core/vector/CMakeLists.txt +++ b/test/core/vector/CMakeLists.txt @@ -39,36 +39,28 @@ file(CREATE_LINK ${CMAKE_CURRENT_SOURCE_DIR}/mac_widening.json ${CMAKE_CURRENT_B 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) -add_executable(Vuop_test - Vuop_test.cpp ${SIM_BASE}/sim/OlympiaSim.cpp +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 ) - -target_link_libraries(Vuop_test - PRIVATE - core common_test ${STF_LINK_LIBS} mavis SPARTA::sparta -) -sparta_named_test(Vuop_test_elementwise - Vuop_test -l top info vuop_elementwise.out -c test_cores/test_big_core.yaml --input-file elementwise.json -) -sparta_named_test(Vuop_test_widening - Vuop_test -l top info vuop_widening.out -c test_cores/test_big_core.yaml --input-file widening.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(Vuop_test_widening_mixed - Vuop_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_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(Vuop_test_narrowing - Vuop_test -l top info vuop_narrowing.out -c test_cores/test_big_core.yaml --input-file narrowing.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(Vuop_test_mac - Vuop_test -l top info vuop_mac.out -c test_cores/test_big_core.yaml --input-file mac.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(Vuop_test_mac_widening - Vuop_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_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(Vuop_test_single_dest - Vuop_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_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(Vuop_test_int_ext - Vuop_test -l top info vuop_int_ext.out -c test_cores/test_big_core.yaml --input-file int_ext.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/Vuop_test.cpp b/test/core/vector/Vuop_test.cpp deleted file mode 100644 index 9ede9c10..00000000 --- a/test/core/vector/Vuop_test.cpp +++ /dev/null @@ -1,216 +0,0 @@ -#include "OlympiaSim.hpp" -#include "Decode.hpp" -#include "VectorUopGenerator.hpp" - -#include "sparta/app/CommandLineSimulator.hpp" -#include "sparta/kernel/Scheduler.hpp" -#include "sparta/simulation/ClockManager.hpp" -#include "sparta/utils/SpartaSharedPointer.hpp" -#include "sparta/utils/SpartaTester.hpp" - -TEST_INIT - -const char USAGE[] = "Usage:\n" - "\n" - "\n"; - -sparta::app::DefaultValues DEFAULTS; - -class olympia::DecodeTester -{ - public: - DecodeTester(olympia::Decode* decode) : decode_(decode) {} - - void test_waiting_on_vset() { EXPECT_TRUE(decode_->waiting_on_vset_ == true); } - - void test_waiting_on_vset(const bool expected_val) - { - EXPECT_TRUE(decode_->waiting_on_vset_ == expected_val); - } - - void test_vl(const uint32_t expected_vl) - { - EXPECT_TRUE(decode_->vector_config_->getVL() == expected_vl); - } - - void test_sew(const uint32_t expected_sew) - { - EXPECT_TRUE(decode_->vector_config_->getSEW() == expected_sew); - } - - void test_lmul(const uint32_t expected_lmul) - { - EXPECT_TRUE(decode_->vector_config_->getLMUL() == expected_lmul); - } - - void test_vlmax(const uint32_t expected_vlmax) - { - EXPECT_TRUE(decode_->vector_config_->getVLMAX() == expected_vlmax); - } - - void test_vta(const bool expected_vta) - { - EXPECT_TRUE(decode_->vector_config_->getVTA() == expected_vta); - } - - private: - olympia::Decode* decode_; -}; - -class olympia::VectorUopGeneratorTester -{ - public: - VectorUopGeneratorTester(olympia::VectorUopGenerator* vuop) : vuop_{vuop} {} - - void test_num_vuops_generated(const uint64_t expected_num_vuops_generated) - { - EXPECT_TRUE(vuop_->vuops_generated_ == expected_num_vuops_generated); - } - - private: - VectorUopGenerator* vuop_; -}; - -void runTests(int argc, char** argv) -{ - DEFAULTS.auto_summary_default = "off"; - std::string input_file; - - sparta::app::CommandLineSimulator cls(USAGE, DEFAULTS); - auto & app_opts = cls.getApplicationOptions(); - app_opts.add_options()( - "input-file", - sparta::app::named_value("INPUT_FILE", &input_file)->default_value(""), - "Provide a JSON instruction stream", - "Provide a JSON file with instructions to run through Execute"); - - int err_code = 0; - if (!cls.parse(argc, argv, err_code)) - { - sparta_assert(false, "Command line parsing failed"); - } - - sparta::Scheduler scheduler; - uint32_t num_cores = 1; - uint64_t ilimit = 0; - bool show_factories = false; - OlympiaSim sim("simple", scheduler, num_cores, input_file, ilimit, show_factories); - sparta::RootTreeNode* root_node = sim.getRoot(); - cls.populateSimulation(&sim); - - auto* my_decode = root_node->getChild("cpu.core0.decode")->getResourceAs(); - olympia::DecodeTester decode_tester{my_decode}; - - auto* my_vuop_generator = root_node->getChild("cpu.core0.decode.vec_uop_gen") - ->getResourceAs(); - olympia::VectorUopGeneratorTester vuop_tester{my_vuop_generator}; - - 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); - } -} - -int main(int argc, char** argv) -{ - runTests(argc, argv); - - REPORT_ERROR; - return (int)ERROR_CODE; -} From a6ea0beb9e9192e9da49418027412a33528f19a5 Mon Sep 17 00:00:00 2001 From: Isaac David Date: Fri, 13 Dec 2024 21:45:10 +0000 Subject: [PATCH 6/6] Remove orphan inst_allocator from tests --- test/core/dispatch/Dispatch_test.cpp | 4 ---- test/core/issue_queue/IssueQueue_test.cpp | 4 ---- test/core/rename/Rename_test.cpp | 4 ---- 3 files changed, 12 deletions(-) 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) {