Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Vector] refactor vuop #228

Merged
merged 1 commit into from
Nov 28, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
325 changes: 176 additions & 149 deletions arches/isa_json/gen_uarch_rv64v_json.py

Large diffs are not rendered by default.

440 changes: 220 additions & 220 deletions arches/isa_json/olympia_uarch_rv64v.json

Large diffs are not rendered by default.

9 changes: 7 additions & 2 deletions core/Dispatch.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -178,7 +178,7 @@ namespace olympia
sparta::Counter::COUNT_NORMAL, getClock()),
sparta::CycleCounter(getStatisticSet(), "stall_vint_busy", "VINT busy",
sparta::Counter::COUNT_NORMAL, getClock()),
sparta::CycleCounter(getStatisticSet(), "stall_vfixed_busy", "VFIXED busy",
sparta::CycleCounter(getStatisticSet(), "stall_vfixed_busy", "VFIXED busy",
sparta::Counter::COUNT_NORMAL, getClock()),
sparta::CycleCounter(getStatisticSet(), "stall_vmask_busy", "VMASK busy",
sparta::Counter::COUNT_NORMAL, getClock()),
Expand Down Expand Up @@ -222,7 +222,7 @@ namespace olympia
sparta::Counter::COUNT_NORMAL),
sparta::Counter(getStatisticSet(), "count_vint_insts", "Total VINT insts",
sparta::Counter::COUNT_NORMAL),
sparta::Counter(getStatisticSet(), "count_vfixed_insts", "Total VFIXED insts",
sparta::Counter(getStatisticSet(), "count_vfixed_insts", "Total VFIXED insts",
sparta::Counter::COUNT_NORMAL),
sparta::Counter(getStatisticSet(), "count_vmask_insts", "Total VMASK insts",
sparta::Counter::COUNT_NORMAL),
Expand Down Expand Up @@ -280,6 +280,8 @@ namespace olympia
"count_cmov_insts + count_div_insts + count_faddsub_insts + count_float_insts + "
"count_fmac_insts + count_i2f_insts + count_f2i_insts + count_int_insts + "
"count_lsu_insts + count_mul_insts + count_br_insts"};

friend class DispatchTester;
};

using DispatchFactory =
Expand All @@ -305,5 +307,8 @@ namespace olympia
}

return os;

}

class DispatchTester;
} // namespace olympia
14 changes: 8 additions & 6 deletions core/InstArchInfo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -50,12 +50,14 @@ namespace olympia
};

const InstArchInfo::UopGenMap InstArchInfo::uop_gen_type_map = {
{"ARITH", InstArchInfo::UopGenType::ARITH},
{"ARITH_SINGLE_DEST", InstArchInfo::UopGenType::ARITH_SINGLE_DEST},
{"ARITH_WIDE_DEST", InstArchInfo::UopGenType::ARITH_WIDE_DEST},
{"ARITH_MAC", InstArchInfo::UopGenType::ARITH_MAC},
{"ARITH_MAC_WIDE_DEST", InstArchInfo::UopGenType::ARITH_MAC_WIDE_DEST},
{"NONE", InstArchInfo::UopGenType::NONE}
{"ELEMENTWISE", InstArchInfo::UopGenType::ELEMENTWISE},
{"SINGLE_DEST", InstArchInfo::UopGenType::SINGLE_DEST},
{"WIDENING", InstArchInfo::UopGenType::WIDENING},
{"WIDENING_MIXED", InstArchInfo::UopGenType::WIDENING_MIXED},
{"NARROWING", InstArchInfo::UopGenType::NARROWING},
{"MAC", InstArchInfo::UopGenType::MAC},
{"MAC_WIDE", InstArchInfo::UopGenType::MAC_WIDE},
{"NONE", InstArchInfo::UopGenType::NONE}
};

void InstArchInfo::update(const nlohmann::json & jobj)
Expand Down
12 changes: 7 additions & 5 deletions core/InstArchInfo.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -68,11 +68,13 @@ namespace olympia

enum class UopGenType
{
ARITH,
ARITH_SINGLE_DEST,
ARITH_WIDE_DEST,
ARITH_MAC,
ARITH_MAC_WIDE_DEST,
ELEMENTWISE,
SINGLE_DEST,
WIDENING,
WIDENING_MIXED,
NARROWING,
MAC,
MAC_WIDE,
NONE,
UNKNOWN
};
Expand Down
147 changes: 76 additions & 71 deletions core/VectorUopGenerator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,13 @@ 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
// Vector 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
Expand All @@ -19,26 +22,28 @@ 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,
&VectorUopGenerator::generateArithUop<SINGLE_DEST, WIDE_DEST, ADD_DEST_AS_SRC>);
uop_gen_function_map_.emplace(
InstArchInfo::UopGenType::ELEMENTWISE,
&VectorUopGenerator::generateUops<SINGLE_DEST, WIDE_DEST, ADD_DEST_AS_SRC>);
}

// Vector arithmetic single dest uop generator, only increment all src register numbers
// For a "vmseq.vv v12, v4,v8" with an LMUL of 4:
// Uop 1: vadd.vv v12, v4, v8
// Uop 2: vadd.vv v12, v5, v9
// Uop 3: vadd.vv v12, v6, v10
// Uop 4: vadd.vv v12, v7, v11
// Vector single dest uop generator, only increment all src register numbers
// For a "vmseq.vv v12, v4, v8" with an LMUL of 4:
// Uop 1: vmseq.vv v12, v4, v8
// Uop 2: vmseq.vv v12, v5, v9
// 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::ARITH_SINGLE_DEST,
&VectorUopGenerator::generateArithUop<SINGLE_DEST, WIDE_DEST, ADD_DEST_AS_SRC>);
uop_gen_function_map_.emplace(
InstArchInfo::UopGenType::SINGLE_DEST,
&VectorUopGenerator::generateUops<SINGLE_DEST, WIDE_DEST, ADD_DEST_AS_SRC>);
}

// 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 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
Expand All @@ -49,14 +54,30 @@ namespace olympia
// Uop 8: vwmul.vv v19, v10, v14
{
constexpr bool SINGLE_DEST = false;
constexpr bool WIDE_DEST = true;
constexpr bool WIDENING = true;
constexpr bool ADD_DEST_AS_SRC = false;
uop_gen_function_map_.emplace(InstArchInfo::UopGenType::ARITH_WIDE_DEST,
&VectorUopGenerator::generateArithUop<SINGLE_DEST, WIDE_DEST, ADD_DEST_AS_SRC>);
uop_gen_function_map_.emplace(
InstArchInfo::UopGenType::WIDENING,
&VectorUopGenerator::generateUops<SINGLE_DEST, WIDENING, ADD_DEST_AS_SRC>);
}

// Vector arithmetic multiplay-add wide dest uop generator, add dest as source
// Vector arithmetic multiply-add uop generator, add dest as source
// For a "vmacc.vv v12, v4, v8" with an LMUL of 4:
// Uop 1: vmacc.vv v12, v4, v8, v12
// Uop 2: vmacc.vv v13, v5, v9, v13
// 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<SINGLE_DEST, WIDE_DEST, ADD_DEST_AS_SRC>);
}

// Vector multiply-add wide dest uop generator, add dest as source
// 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
// Uop 3: vwmacc.vv v14, v5, v9, v14
Expand All @@ -65,69 +86,54 @@ namespace olympia
// Uop 6: vwmacc.vv v17, v6, v10, v17
// 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 = false;
constexpr bool ADD_DEST_AS_SRC = true;
uop_gen_function_map_.emplace(InstArchInfo::UopGenType::ARITH_MAC,
&VectorUopGenerator::generateArithUop<SINGLE_DEST, WIDE_DEST, ADD_DEST_AS_SRC>);
}

// Vector arithmetic multiplay-add uop generator, add dest as source
// For a "vmacc.vv v12, v4, v8" with an LMUL of 4:
// Uop 1: vmacc.vv v12, v4, v8, v12
// Uop 2: vmacc.vv v13, v5, v9, v13
// 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 = true;
constexpr bool ADD_DEST_AS_SRC = true;
uop_gen_function_map_.emplace(InstArchInfo::UopGenType::ARITH_MAC_WIDE_DEST,
&VectorUopGenerator::generateArithUop<SINGLE_DEST, WIDE_DEST, ADD_DEST_AS_SRC>);
uop_gen_function_map_.emplace(
InstArchInfo::UopGenType::MAC_WIDE,
&VectorUopGenerator::generateUops<SINGLE_DEST, WIDE_DEST, ADD_DEST_AS_SRC>);
}
}

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();
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::ARITH_WIDE_DEST) ||
(uop_gen_type == InstArchInfo::UopGenType::ARITH_MAC_WIDE_DEST))
if ((uop_gen_type == InstArchInfo::UopGenType::WIDENING)
|| (uop_gen_type == InstArchInfo::UopGenType::MAC_WIDE))
{
// 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);
Expand All @@ -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<olympia::Inst> parent_weak_ptr = current_inst_;
Expand All @@ -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_();
}
Expand All @@ -161,8 +168,8 @@ namespace olympia
return uop;
}

template<bool SINGLE_DEST, bool WIDE_DEST, bool ADD_DEST_AS_SRC>
const InstPtr VectorUopGenerator::generateArithUop()
template <bool SINGLE_DEST, bool WIDE_DEST, bool ADD_DEST_AS_SRC>
const InstPtr VectorUopGenerator::generateUops()
{
// Increment source and destination register values
auto srcs = current_inst_->getSourceOpInfoList();
Expand All @@ -177,8 +184,7 @@ 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;
}
else
{
Expand All @@ -188,16 +194,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<OperandFieldID>(srcs.size());
sparta_assert(field_id <= OperandFieldID::RS_MAX,
"Mavis does not support instructions with more than " << std::dec <<
static_cast<std::underlying_type_t<OperandFieldID>>(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<OperandFieldID>(srcs.size());
sparta_assert(
field_id <= OperandFieldID::RS_MAX,
"Mavis does not support instructions with more than "
<< std::dec
<< static_cast<std::underlying_type_t<OperandFieldID>>(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)
Expand All @@ -219,7 +227,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))
{
Expand All @@ -234,17 +243,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());
}

Expand All @@ -253,7 +258,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_();
}
Expand Down
Loading
Loading