diff --git a/arches/isa_json/gen_uarch_rv64v_json.py b/arches/isa_json/gen_uarch_rv64v_json.py index 7fabe099..7d9aae42 100755 --- a/arches/isa_json/gen_uarch_rv64v_json.py +++ b/arches/isa_json/gen_uarch_rv64v_json.py @@ -194,27 +194,49 @@ "vmv.v.i" : {"pipe" : "vint", "uop_gen" : "ARITH", "latency" : 1}, # Vector Fixed-Point Arithmetic Instructions: Vector Single-Width Saturating Add and Subtract - "vsaddu.vv" : {"pipe" : "vfixed", "uop_gen" : "ARITH", "latency" : 1}, - "vsaddu.vx" : {"pipe" : "vfixed", "uop_gen" : "ARITH", "latency" : 1}, - "vsaddu.vi" : {"pipe" : "vfixed", "uop_gen" : "ARITH", "latency" : 1}, + "vsaddu.vv" : {"pipe" : "vfixed", "uop_gen" : "ARITH", "latency" : 6}, + "vsaddu.vx" : {"pipe" : "vfixed", "uop_gen" : "ARITH", "latency" : 6}, + "vsaddu.vi" : {"pipe" : "vfixed", "uop_gen" : "ARITH", "latency" : 6}, - "vsadd.vv" : {"pipe" : "vfixed", "uop_gen" : "ARITH", "latency" : 1}, - "vsadd.vx" : {"pipe" : "vfixed", "uop_gen" : "ARITH", "latency" : 1}, - "vsadd.vi" : {"pipe" : "vfixed", "uop_gen" : "ARITH", "latency" : 1}, + "vsadd.vv" : {"pipe" : "vfixed", "uop_gen" : "ARITH", "latency" : 6}, + "vsadd.vx" : {"pipe" : "vfixed", "uop_gen" : "ARITH", "latency" : 6}, + "vsadd.vi" : {"pipe" : "vfixed", "uop_gen" : "ARITH", "latency" : 6}, - "vssubu.vv" : {"pipe" : "vfixed", "uop_gen" : "ARITH", "latency" : 1}, - "vssubu.vx" : {"pipe" : "vfixed", "uop_gen" : "ARITH", "latency" : 1}, + "vssubu.vv" : {"pipe" : "vfixed", "uop_gen" : "ARITH", "latency" : 6}, + "vssubu.vx" : {"pipe" : "vfixed", "uop_gen" : "ARITH", "latency" : 6}, - "vssub.vv" : {"pipe" : "vfixed", "uop_gen" : "ARITH", "latency" : 1}, - "vssub.vx" : {"pipe" : "vfixed", "uop_gen" : "ARITH", "latency" : 1}, + "vssub.vv" : {"pipe" : "vfixed", "uop_gen" : "ARITH", "latency" : 6}, + "vssub.vx" : {"pipe" : "vfixed", "uop_gen" : "ARITH", "latency" : 6}, + +# Vector Fixed-Point Arithmetic Instructions: Vector Single-Width Averaging Add and Subtract + "vaaddu.vv" : {"pipe" : "vfixed", "uop_gen" : "ARITH", "latency" : 6}, + "vaaddu.vx" : {"pipe" : "vfixed", "uop_gen" : "ARITH", "latency" : 6}, + "vaadd.vv" : {"pipe" : "vfixed", "uop_gen" : "ARITH", "latency" : 6}, + "vaadd.vx" : {"pipe" : "vfixed", "uop_gen" : "ARITH", "latency" : 6}, + "vasubu.vv" : {"pipe" : "vfixed", "uop_gen" : "ARITH", "latency" : 6}, + "vasubu.vx" : {"pipe" : "vfixed", "uop_gen" : "ARITH", "latency" : 6}, + "vasub.vv" : {"pipe" : "vfixed", "uop_gen" : "ARITH", "latency" : 6}, + "vasub.vx" : {"pipe" : "vfixed", "uop_gen" : "ARITH", "latency" : 6}, -# TODO: Vector Fixed-Point Arithmetic Instructions: Vector Single-Width Averaging Add and Subtract # Vector Fixed-Point Arithmetic Instructions: Vector Single-Width Fractional Multiply with Rounding and Saturation "vsmul.vx" : {"pipe" : "vmul", "uop_gen" : "ARITH", "latency" : 3}, "vsmul.vv" : {"pipe" : "vmul", "uop_gen" : "ARITH", "latency" : 3}, -# TODO: Vector Fixed-Point Arithmetic Instructions: Vector Single-Width Scaling Shift Instructions -# TODO: Vector Fixed-Point Arithmetic Instructions: Vector Narrowing Fixed-Point Clip Instructions +# Vector Fixed-Point Arithmetic Instructions: Vector Single-Width Scaling Shift Instructions + "vssrl.vv" : {"pipe" : "vfixed", "uop_gen" : "ARITH", "latency" : 6}, + "vssrl.vx" : {"pipe" : "vfixed", "uop_gen" : "ARITH", "latency" : 6}, + "vssrl.vi" : {"pipe" : "vfixed", "uop_gen" : "ARITH", "latency" : 6}, + "vssra.vv" : {"pipe" : "vfixed", "uop_gen" : "ARITH", "latency" : 6}, + "vssra.vx" : {"pipe" : "vfixed", "uop_gen" : "ARITH", "latency" : 6}, + "vssra.vi" : {"pipe" : "vfixed", "uop_gen" : "ARITH", "latency" : 6}, + +# Vector Fixed-Point Arithmetic Instructions: Vector Narrowing Fixed-Point Clip Instructions + "vnclipu.wv" : {"pipe" : "vfixed", "uop_gen" : "ARITH", "latency" : 2}, + "vnclipu.wx" : {"pipe" : "vfixed", "uop_gen" : "ARITH", "latency" : 2}, + "vnclipu.wi" : {"pipe" : "vfixed", "uop_gen" : "ARITH", "latency" : 2}, + "vnclip.wv" : {"pipe" : "vfixed", "uop_gen" : "ARITH", "latency" : 2}, + "vnclip.wx" : {"pipe" : "vfixed", "uop_gen" : "ARITH", "latency" : 2}, + "vnclip.wi" : {"pipe" : "vfixed", "uop_gen" : "ARITH", "latency" : 2}, # TODO: Vector Floating-Point Instructions: Vector Floating-Point Exception Flags # TODO: Vector Floating-Point Instructions: Vector Single-Width Floating-Point Add/Subtract Instructions diff --git a/arches/isa_json/olympia_uarch_rv64v.json b/arches/isa_json/olympia_uarch_rv64v.json index c46ba06c..2def1bab 100644 --- a/arches/isa_json/olympia_uarch_rv64v.json +++ b/arches/isa_json/olympia_uarch_rv64v.json @@ -1,27 +1,27 @@ [ { "mnemonic": "vaadd.vv", - "pipe": "?", - "uop_gen": "NONE", - "latency": 0 + "pipe": "vfixed", + "uop_gen": "ARITH", + "latency": 6 }, { "mnemonic": "vaadd.vx", - "pipe": "?", - "uop_gen": "NONE", - "latency": 0 + "pipe": "vfixed", + "uop_gen": "ARITH", + "latency": 6 }, { "mnemonic": "vaaddu.vv", - "pipe": "?", - "uop_gen": "NONE", - "latency": 0 + "pipe": "vfixed", + "uop_gen": "ARITH", + "latency": 6 }, { "mnemonic": "vaaddu.vx", - "pipe": "?", - "uop_gen": "NONE", - "latency": 0 + "pipe": "vfixed", + "uop_gen": "ARITH", + "latency": 6 }, { "mnemonic": "vadc.vim", @@ -79,27 +79,27 @@ }, { "mnemonic": "vasub.vv", - "pipe": "?", - "uop_gen": "NONE", - "latency": 0 + "pipe": "vfixed", + "uop_gen": "ARITH", + "latency": 6 }, { "mnemonic": "vasub.vx", - "pipe": "?", - "uop_gen": "NONE", - "latency": 0 + "pipe": "vfixed", + "uop_gen": "ARITH", + "latency": 6 }, { "mnemonic": "vasubu.vv", - "pipe": "?", - "uop_gen": "NONE", - "latency": 0 + "pipe": "vfixed", + "uop_gen": "ARITH", + "latency": 6 }, { "mnemonic": "vasubu.vx", - "pipe": "?", - "uop_gen": "NONE", - "latency": 0 + "pipe": "vfixed", + "uop_gen": "ARITH", + "latency": 6 }, { "mnemonic": "vcompress.vm", @@ -1393,39 +1393,39 @@ }, { "mnemonic": "vnclip.wi", - "pipe": "?", - "uop_gen": "NONE", - "latency": 0 + "pipe": "vfixed", + "uop_gen": "ARITH", + "latency": 2 }, { "mnemonic": "vnclip.wv", - "pipe": "?", - "uop_gen": "NONE", - "latency": 0 + "pipe": "vfixed", + "uop_gen": "ARITH", + "latency": 2 }, { "mnemonic": "vnclip.wx", - "pipe": "?", - "uop_gen": "NONE", - "latency": 0 + "pipe": "vfixed", + "uop_gen": "ARITH", + "latency": 2 }, { "mnemonic": "vnclipu.wi", - "pipe": "?", - "uop_gen": "NONE", - "latency": 0 + "pipe": "vfixed", + "uop_gen": "ARITH", + "latency": 2 }, { "mnemonic": "vnclipu.wv", - "pipe": "?", - "uop_gen": "NONE", - "latency": 0 + "pipe": "vfixed", + "uop_gen": "ARITH", + "latency": 2 }, { "mnemonic": "vnclipu.wx", - "pipe": "?", - "uop_gen": "NONE", - "latency": 0 + "pipe": "vfixed", + "uop_gen": "ARITH", + "latency": 2 }, { "mnemonic": "vnmsac.vv", @@ -1645,39 +1645,39 @@ }, { "mnemonic": "vsadd.vi", - "pipe": "vint", + "pipe": "vfixed", "uop_gen": "ARITH", - "latency": 1 + "latency": 6 }, { "mnemonic": "vsadd.vv", - "pipe": "vint", + "pipe": "vfixed", "uop_gen": "ARITH", - "latency": 1 + "latency": 6 }, { "mnemonic": "vsadd.vx", - "pipe": "vint", + "pipe": "vfixed", "uop_gen": "ARITH", - "latency": 1 + "latency": 6 }, { "mnemonic": "vsaddu.vi", - "pipe": "vint", + "pipe": "vfixed", "uop_gen": "ARITH", - "latency": 1 + "latency": 6 }, { "mnemonic": "vsaddu.vv", - "pipe": "vint", + "pipe": "vfixed", "uop_gen": "ARITH", - "latency": 1 + "latency": 6 }, { "mnemonic": "vsaddu.vx", - "pipe": "vint", + "pipe": "vfixed", "uop_gen": "ARITH", - "latency": 1 + "latency": 6 }, { "mnemonic": "vsbc.vvm", @@ -1909,63 +1909,63 @@ }, { "mnemonic": "vssra.vi", - "pipe": "?", - "uop_gen": "NONE", - "latency": 0 + "pipe": "vfixed", + "uop_gen": "ARITH", + "latency": 6 }, { "mnemonic": "vssra.vv", - "pipe": "?", - "uop_gen": "NONE", - "latency": 0 + "pipe": "vfixed", + "uop_gen": "ARITH", + "latency": 6 }, { "mnemonic": "vssra.vx", - "pipe": "?", - "uop_gen": "NONE", - "latency": 0 + "pipe": "vfixed", + "uop_gen": "ARITH", + "latency": 6 }, { "mnemonic": "vssrl.vi", - "pipe": "?", - "uop_gen": "NONE", - "latency": 0 + "pipe": "vfixed", + "uop_gen": "ARITH", + "latency": 6 }, { "mnemonic": "vssrl.vv", - "pipe": "?", - "uop_gen": "NONE", - "latency": 0 + "pipe": "vfixed", + "uop_gen": "ARITH", + "latency": 6 }, { "mnemonic": "vssrl.vx", - "pipe": "?", - "uop_gen": "NONE", - "latency": 0 + "pipe": "vfixed", + "uop_gen": "ARITH", + "latency": 6 }, { "mnemonic": "vssub.vv", - "pipe": "vint", + "pipe": "vfixed", "uop_gen": "ARITH", - "latency": 1 + "latency": 6 }, { "mnemonic": "vssub.vx", - "pipe": "vint", + "pipe": "vfixed", "uop_gen": "ARITH", - "latency": 1 + "latency": 6 }, { "mnemonic": "vssubu.vv", - "pipe": "vint", + "pipe": "vfixed", "uop_gen": "ARITH", - "latency": 1 + "latency": 6 }, { "mnemonic": "vssubu.vx", - "pipe": "vint", + "pipe": "vfixed", "uop_gen": "ARITH", - "latency": 1 + "latency": 6 }, { "mnemonic": "vsub.vv", diff --git a/core/VectorUopGenerator.cpp b/core/VectorUopGenerator.cpp index a67458ef..9178a043 100644 --- a/core/VectorUopGenerator.cpp +++ b/core/VectorUopGenerator.cpp @@ -6,8 +6,11 @@ namespace olympia { constexpr char VectorUopGenerator::name[]; - VectorUopGenerator::VectorUopGenerator(sparta::TreeNode* node, const VectorUopGeneratorParameterSet* p) : - sparta::Unit(node) + VectorUopGenerator::VectorUopGenerator(sparta::TreeNode* node, + const VectorUopGeneratorParameterSet* p) : + sparta::Unit(node), + vuops_generated_(&unit_stat_set_, "vector_uops_generated", + "Number of vector uops generated", sparta::Counter::COUNT_NORMAL) { // Vector arithmetic uop generator, increment all src and dest register numbers // For a "vadd.vv v12, v4,v8" with an LMUL of 4: @@ -19,7 +22,8 @@ namespace olympia constexpr bool SINGLE_DEST = false; constexpr bool WIDE_DEST = false; constexpr bool ADD_DEST_AS_SRC = false; - uop_gen_function_map_.emplace(InstArchInfo::UopGenType::ARITH, + uop_gen_function_map_.emplace( + InstArchInfo::UopGenType::ARITH, &VectorUopGenerator::generateArithUop); } @@ -33,12 +37,13 @@ namespace olympia constexpr bool SINGLE_DEST = true; constexpr bool WIDE_DEST = false; constexpr bool ADD_DEST_AS_SRC = false; - uop_gen_function_map_.emplace(InstArchInfo::UopGenType::ARITH_SINGLE_DEST, + uop_gen_function_map_.emplace( + InstArchInfo::UopGenType::ARITH_SINGLE_DEST, &VectorUopGenerator::generateArithUop); } - // Vector arithmetic 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 arithmetic wide dest 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 @@ -51,7 +56,8 @@ namespace olympia constexpr bool SINGLE_DEST = false; constexpr bool WIDE_DEST = true; constexpr bool ADD_DEST_AS_SRC = false; - uop_gen_function_map_.emplace(InstArchInfo::UopGenType::ARITH_WIDE_DEST, + uop_gen_function_map_.emplace( + InstArchInfo::UopGenType::ARITH_WIDE_DEST, &VectorUopGenerator::generateArithUop); } @@ -69,7 +75,8 @@ namespace olympia constexpr bool SINGLE_DEST = false; constexpr bool WIDE_DEST = false; constexpr bool ADD_DEST_AS_SRC = true; - uop_gen_function_map_.emplace(InstArchInfo::UopGenType::ARITH_MAC, + uop_gen_function_map_.emplace( + InstArchInfo::UopGenType::ARITH_MAC, &VectorUopGenerator::generateArithUop); } @@ -83,27 +90,26 @@ namespace olympia constexpr bool SINGLE_DEST = false; constexpr bool WIDE_DEST = true; constexpr bool ADD_DEST_AS_SRC = true; - uop_gen_function_map_.emplace(InstArchInfo::UopGenType::ARITH_MAC_WIDE_DEST, + uop_gen_function_map_.emplace( + InstArchInfo::UopGenType::ARITH_MAC_WIDE_DEST, &VectorUopGenerator::generateArithUop); } } - void VectorUopGenerator::onBindTreeLate_() - { - mavis_facade_ = getMavis(getContainer()); - } + void VectorUopGenerator::onBindTreeLate_() { mavis_facade_ = getMavis(getContainer()); } void VectorUopGenerator::setInst(const InstPtr & inst) { sparta_assert(current_inst_ == nullptr, - "Cannot start generating uops for a new vector instruction, " - "current instruction has not finished: " << current_inst_); + "Cannot start generating uops for a new vector instruction, " + "current instruction has not finished: " + << current_inst_); const auto uop_gen_type = inst->getUopGenType(); sparta_assert(uop_gen_type != InstArchInfo::UopGenType::UNKNOWN, - "Inst: " << current_inst_ << " uop gen type is unknown"); + "Inst: " << current_inst_ << " uop gen type is unknown"); sparta_assert(uop_gen_type != InstArchInfo::UopGenType::NONE, - "Inst: " << current_inst_ << " uop gen type is none"); + "Inst: " << current_inst_ << " uop gen type is none"); // Number of vector elements processed by each uop const VectorConfigPtr & vector_config = inst->getVectorConfig(); @@ -111,23 +117,23 @@ 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::ARITH_WIDE_DEST) || - (uop_gen_type == InstArchInfo::UopGenType::ARITH_MAC_WIDE_DEST)) + if ((uop_gen_type == InstArchInfo::UopGenType::ARITH_WIDE_DEST) + || (uop_gen_type == InstArchInfo::UopGenType::ARITH_MAC_WIDE_DEST)) { // TODO: Add parameter to support dual dests num_uops_to_generate_ *= 2; } current_inst_ = inst; - ILOG("Inst: " << current_inst_ << - " is being split into " << num_uops_to_generate_ << " UOPs"); + ILOG("Inst: " << current_inst_ << " is being split into " << num_uops_to_generate_ + << " UOPs"); } const InstPtr VectorUopGenerator::generateUop() { const auto uop_gen_type = current_inst_->getUopGenType(); sparta_assert(uop_gen_type <= InstArchInfo::UopGenType::NONE, - "Inst: " << current_inst_ << " uop gen type is unknown"); + "Inst: " << current_inst_ << " uop gen type is unknown"); // Generate uop auto uop_gen_func = uop_gen_function_map_.at(uop_gen_type); @@ -141,6 +147,7 @@ namespace olympia uop->setVectorConfig(vector_config); uop->setUOpID(num_uops_generated_); ++num_uops_generated_; + ++vuops_generated_; // Set weak pointer to parent vector instruction (first uop) sparta::SpartaWeakPointer parent_weak_ptr = current_inst_; @@ -151,7 +158,7 @@ namespace olympia uop->setTail((num_elems_per_uop * num_uops_generated_) > vector_config->getVL()); // Handle last uop - if(num_uops_generated_ == num_uops_to_generate_) + if (num_uops_generated_ == num_uops_to_generate_) { reset_(); } @@ -161,7 +168,7 @@ namespace olympia return uop; } - template + template const InstPtr VectorUopGenerator::generateArithUop() { // Increment source and destination register values @@ -177,8 +184,8 @@ namespace olympia if constexpr (WIDE_DEST == true) { // Only increment source values for even uops - src.field_value += (num_uops_generated_ % 2) ? num_uops_generated_ - 1 - : num_uops_generated_; + src.field_value += + (num_uops_generated_ % 2) ? num_uops_generated_ - 1 : num_uops_generated_; } else { @@ -188,16 +195,18 @@ namespace olympia // Add a destination to the list of sources auto add_dest_as_src = [](auto & srcs, auto & dest) - { - // OperandFieldID is an enum with RS1 = 0, RS2 = 1, etc. with a max RS of RS4 - using OperandFieldID = mavis::InstMetaData::OperandFieldID; - const OperandFieldID field_id = static_cast(srcs.size()); - sparta_assert(field_id <= OperandFieldID::RS_MAX, - "Mavis does not support instructions with more than " << std::dec << - static_cast>(OperandFieldID::RS_MAX) << - " sources"); - srcs.emplace_back(field_id, dest.operand_type, dest.field_value); - }; + { + // OperandFieldID is an enum with RS1 = 0, RS2 = 1, etc. with a max RS of RS4 + using OperandFieldID = mavis::InstMetaData::OperandFieldID; + const OperandFieldID field_id = static_cast(srcs.size()); + sparta_assert( + field_id <= OperandFieldID::RS_MAX, + "Mavis does not support instructions with more than " + << std::dec + << static_cast>(OperandFieldID::RS_MAX) + << " sources"); + srcs.emplace_back(field_id, dest.operand_type, dest.field_value); + }; auto dests = current_inst_->getDestOpInfoList(); if constexpr (SINGLE_DEST == false) @@ -219,7 +228,8 @@ namespace olympia { 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(); + 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)) { @@ -234,17 +244,13 @@ namespace olympia InstPtr uop; if (current_inst_->hasImmediate()) { - mavis::ExtractorDirectOpInfoList ex_info(current_inst_->getMnemonic(), - srcs, - dests, + mavis::ExtractorDirectOpInfoList ex_info(current_inst_->getMnemonic(), srcs, dests, current_inst_->getImmediate()); uop = mavis_facade_->makeInstDirectly(ex_info, getClock()); } else { - mavis::ExtractorDirectOpInfoList ex_info(current_inst_->getMnemonic(), - srcs, - dests); + mavis::ExtractorDirectOpInfoList ex_info(current_inst_->getMnemonic(), srcs, dests); uop = mavis_facade_->makeInstDirectly(ex_info, getClock()); } @@ -253,7 +259,7 @@ namespace olympia void VectorUopGenerator::handleFlush(const FlushManager::FlushingCriteria & flush_criteria) { - if(current_inst_ && flush_criteria.includedInFlush(current_inst_)) + if (current_inst_ && flush_criteria.includedInFlush(current_inst_)) { reset_(); } diff --git a/core/VectorUopGenerator.hpp b/core/VectorUopGenerator.hpp index d819ada5..344a784b 100644 --- a/core/VectorUopGenerator.hpp +++ b/core/VectorUopGenerator.hpp @@ -19,7 +19,7 @@ namespace olympia */ class VectorUopGenerator : public sparta::Unit { - public: + public: //! \brief Parameters for VectorUopGenerator model class VectorUopGeneratorParameterSet : public sparta::ParameterSet { @@ -27,8 +27,8 @@ namespace olympia VectorUopGeneratorParameterSet(sparta::TreeNode* n) : sparta::ParameterSet(n) {} //! \brief Generate uops for widening vector instructions with two dests - //PARAMETER(bool, widening_dual_dest, false, - // "Generate uops for widening vector instructions with two dests") + // PARAMETER(bool, widening_dual_dest, false, + // "Generate uops for widening vector instructions with two dests") }; /** @@ -46,26 +46,28 @@ namespace olympia const InstPtr generateUop(); - template + template const InstPtr generateArithUop(); uint64_t getNumUopsRemaining() const { return num_uops_to_generate_; } void handleFlush(const FlushManager::FlushingCriteria &); - private: + sparta::Counter vuops_generated_; + + private: void onBindTreeLate_() override; - MavisType * mavis_facade_; + MavisType* mavis_facade_; - //typedef std::function FUNC; - typedef std::function UopGenFunctionType; + // typedef std::function FUNC; + typedef std::function UopGenFunctionType; typedef std::map UopGenFunctionMapType; UopGenFunctionMapType uop_gen_function_map_; // TODO: Use Sparta ValidValue InstPtr current_inst_ = nullptr; - //UopGenFunctionMapType::iterator current_uop_gen_function_; + // UopGenFunctionMapType::iterator current_uop_gen_function_; uint64_t num_uops_generated_ = 0; uint64_t num_uops_to_generate_ = 0; diff --git a/test/core/vector/Vector_test.cpp b/test/core/vector/Vector_test.cpp index 54219499..ed97494a 100644 --- a/test/core/vector/Vector_test.cpp +++ b/test/core/vector/Vector_test.cpp @@ -6,6 +6,7 @@ #include "OlympiaAllocators.hpp" #include "OlympiaSim.hpp" #include "IssueQueue.hpp" +#include "VectorUopGenerator.hpp" #include "test/core/dispatch/Dispatch_test.hpp" #include "sparta/app/CommandLineSimulator.hpp" @@ -32,22 +33,17 @@ TEST_INIT olympia::InstAllocator inst_allocator(2000, 1000); const char USAGE[] = "Usage:\n" - " \n" + "\n" "\n"; sparta::app::DefaultValues DEFAULTS; class olympia::DecodeTester { -public: - DecodeTester(olympia::Decode * decode) : - decode_(decode) - {} + public: + DecodeTester(olympia::Decode* decode) : decode_(decode) {} - void test_waiting_on_vset() - { - EXPECT_TRUE(decode_->waiting_on_vset_ == true); - } + void test_waiting_on_vset() { EXPECT_TRUE(decode_->waiting_on_vset_ == true); } void test_waiting_on_vset(const bool expected_val) { @@ -79,16 +75,14 @@ class olympia::DecodeTester EXPECT_TRUE(decode_->vector_config_->getVTA() == expected_vta); } -private: - olympia::Decode * decode_; + private: + olympia::Decode* decode_; }; class olympia::ROBTester { -public: - ROBTester(olympia::ROB * rob) : - rob_(rob) - {} + public: + ROBTester(olympia::ROB* rob) : rob_(rob) {} void test_num_insts_retired(const uint64_t expected_num_insts_retired) { @@ -106,50 +100,47 @@ class olympia::ROBTester EXPECT_TRUE(rob_->last_inst_retired_->hasTail() == expected_tail); } -private: - olympia::ROB * rob_; + private: + olympia::ROB* rob_; }; -void runTests(int argc, char **argv) - { +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"); + 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"); // Any errors already printed to cerr + "Command line parsing failed"); // Any errors already printed to cerr } 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(); + OlympiaSim sim("simple", scheduler, num_cores, input_file, ilimit, show_factories); + sparta::RootTreeNode* root_node = sim.getRoot(); cls.populateSimulation(&sim); - olympia::Decode *my_decode = \ - root_node->getChild("cpu.core0.decode")->getResourceAs(); - olympia::DecodeTester decode_tester {my_decode}; + auto* my_decode = root_node->getChild("cpu.core0.decode")->getResourceAs(); + olympia::DecodeTester decode_tester{my_decode}; + + auto* my_rob = root_node->getChild("cpu.core0.rob")->getResourceAs(); - olympia::ROB *my_rob = \ - root_node->getChild("cpu.core0.rob")->getResourceAs(); - olympia::ROBTester rob_tester {my_rob}; + auto* my_vuop_generator = root_node->getChild("cpu.core0.decode.vec_uop_gen") + ->getResourceAs(); + + olympia::ROBTester rob_tester{my_rob}; if (input_file.find("vsetivli_vaddvv_e8m4.json") != std::string::npos) { @@ -176,7 +167,7 @@ void runTests(int argc, char **argv) rob_tester.test_num_uops_retired(5); rob_tester.test_last_inst_has_tail(false); } - else if(input_file.find("vsetvli_vaddvv_e32m1ta.json") != std::string::npos) + else if (input_file.find("vsetvli_vaddvv_e32m1ta.json") != std::string::npos) { cls.runSimulator(&sim); @@ -194,7 +185,7 @@ void runTests(int argc, char **argv) rob_tester.test_num_uops_retired(2); rob_tester.test_last_inst_has_tail(false); } - else if(input_file.find("vsetvl_vaddvv_e64m1ta.json") != std::string::npos) + else if (input_file.find("vsetvl_vaddvv_e64m1ta.json") != std::string::npos) { cls.runSimulator(&sim); @@ -212,7 +203,7 @@ void runTests(int argc, char **argv) rob_tester.test_num_uops_retired(2); rob_tester.test_last_inst_has_tail(false); } - else if(input_file.find("vsetivli_vaddvv_tail_e8m8ta.json") != std::string::npos) + else if (input_file.find("vsetivli_vaddvv_tail_e8m8ta.json") != std::string::npos) { cls.runSimulator(&sim); @@ -229,7 +220,7 @@ void runTests(int argc, char **argv) rob_tester.test_num_uops_retired(9); rob_tester.test_last_inst_has_tail(true); } - else if(input_file.find("multiple_vset.json") != std::string::npos) + else if (input_file.find("multiple_vset.json") != std::string::npos) { cls.runSimulator(&sim); @@ -246,7 +237,7 @@ void runTests(int argc, char **argv) // vset + 1 vadd.vv + vset + 2 vadd.vv + vset + 4 vadd.vv uop + vset + 8 vadd.vv rob_tester.test_num_uops_retired(19); } - else if(input_file.find("vmulvx_e8m4.json") != std::string::npos) + else if (input_file.find("vmulvx_e8m4.json") != std::string::npos) { cls.runSimulator(&sim); @@ -258,7 +249,7 @@ void runTests(int argc, char **argv) // TODO: Test source values for all uops } - else if(input_file.find("vwmulvv_e8m4.json") != std::string::npos) + else if (input_file.find("vwmulvv_e8m4.json") != std::string::npos) { cls.runSimulator(&sim); @@ -270,7 +261,7 @@ void runTests(int argc, char **argv) // TODO: Test destination values for all uops } - else if(input_file.find("vmseqvv_e8m4.json") != std::string::npos) + else if (input_file.find("vmseqvv_e8m4.json") != std::string::npos) { cls.runSimulator(&sim); @@ -282,13 +273,16 @@ void runTests(int argc, char **argv) // TODO: Test destination values for all uops } - else if(input_file.find("vrgather.json") != std::string::npos) + else if (input_file.find("vrgather.json") != std::string::npos) { // Unsupported vector instructions are expected to make the simulator to throw bool sparta_exception_fired = false; - try { + try + { cls.runSimulator(&sim); - } catch (const sparta::SpartaException& ex) { + } + catch (const sparta::SpartaException & ex) + { sparta_exception_fired = true; } EXPECT_TRUE(sparta_exception_fired); @@ -300,6 +294,8 @@ void runTests(int argc, char **argv) rob_tester.test_num_insts_retired(2); rob_tester.test_num_uops_retired(5); rob_tester.test_last_inst_has_tail(false); + + EXPECT_TRUE(my_vuop_generator->vuops_generated_.get() == 4); } else { @@ -307,8 +303,8 @@ void runTests(int argc, char **argv) } } -int main(int argc, char **argv) - { +int main(int argc, char** argv) +{ runTests(argc, argv); REPORT_ERROR; diff --git a/test/core/vector/test_cores/test_big_core.yaml b/test/core/vector/test_cores/test_big_core.yaml index 2ea2b8d1..9426a61b 100644 --- a/test/core/vector/test_cores/test_big_core.yaml +++ b/test/core/vector/test_cores/test_big_core.yaml @@ -25,7 +25,7 @@ top.cpu.core0.extension.core_extensions: ["float", "f2i"], ["br"], ["br"], - ["vint", "vset", "vdiv", "vmul"] + ["vint", "vset", "vdiv", "vmul", "vfixed"] ] issue_queue_to_pipe_map: [