Add V3VariableOrder pass
A separate V3VariableOrder pass is now used to order module variables
before Emit. All variables are now ordered together, without
consideration for whether they are ports, signals form the design, or
additional internal variables added by Verilator (which used to be
ordered and emitted as separate groups in Emit). For single threaded
models, this is performance neutral. For multi-threaded models, the
MTask affinity based sorting was slightly modified, so variables with no
MTask affinity are emitted last, otherwise the MTask affinity sets are
sorted using the TSP sorter as before, but again, ports, signals, and
internal variables are not differentiated. This yields a 2%+ speedup for
the multithreaded model on OpenTitan.
2021-06-29 18:57:07 +02:00
|
|
|
// -*- mode: C++; c-file-style: "cc-mode" -*-
|
|
|
|
|
//*************************************************************************
|
|
|
|
|
// DESCRIPTION: Verilator: Variable ordering
|
|
|
|
|
//
|
|
|
|
|
// Code available from: https://verilator.org
|
|
|
|
|
//
|
|
|
|
|
//*************************************************************************
|
|
|
|
|
//
|
2024-01-01 09:19:59 +01:00
|
|
|
// Copyright 2003-2024 by Wilson Snyder. This program is free software; you
|
Add V3VariableOrder pass
A separate V3VariableOrder pass is now used to order module variables
before Emit. All variables are now ordered together, without
consideration for whether they are ports, signals form the design, or
additional internal variables added by Verilator (which used to be
ordered and emitted as separate groups in Emit). For single threaded
models, this is performance neutral. For multi-threaded models, the
MTask affinity based sorting was slightly modified, so variables with no
MTask affinity are emitted last, otherwise the MTask affinity sets are
sorted using the TSP sorter as before, but again, ports, signals, and
internal variables are not differentiated. This yields a 2%+ speedup for
the multithreaded model on OpenTitan.
2021-06-29 18:57:07 +02:00
|
|
|
// can redistribute it and/or modify it under the terms of either the GNU
|
|
|
|
|
// Lesser General Public License Version 3 or the Perl Artistic License
|
|
|
|
|
// Version 2.0.
|
|
|
|
|
// SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0
|
|
|
|
|
//
|
|
|
|
|
//*************************************************************************
|
|
|
|
|
// V3VariableOrder's Transformations:
|
|
|
|
|
//
|
|
|
|
|
// Each module:
|
|
|
|
|
// Order module variables
|
|
|
|
|
//
|
|
|
|
|
//*************************************************************************
|
|
|
|
|
|
2023-10-18 12:37:46 +02:00
|
|
|
#include "V3PchAstNoMT.h" // VL_MT_DISABLED_CODE_UNIT
|
|
|
|
|
|
Add V3VariableOrder pass
A separate V3VariableOrder pass is now used to order module variables
before Emit. All variables are now ordered together, without
consideration for whether they are ports, signals form the design, or
additional internal variables added by Verilator (which used to be
ordered and emitted as separate groups in Emit). For single threaded
models, this is performance neutral. For multi-threaded models, the
MTask affinity based sorting was slightly modified, so variables with no
MTask affinity are emitted last, otherwise the MTask affinity sets are
sorted using the TSP sorter as before, but again, ports, signals, and
internal variables are not differentiated. This yields a 2%+ speedup for
the multithreaded model on OpenTitan.
2021-06-29 18:57:07 +02:00
|
|
|
#include "V3VariableOrder.h"
|
2022-08-05 11:56:57 +02:00
|
|
|
|
Add V3VariableOrder pass
A separate V3VariableOrder pass is now used to order module variables
before Emit. All variables are now ordered together, without
consideration for whether they are ports, signals form the design, or
additional internal variables added by Verilator (which used to be
ordered and emitted as separate groups in Emit). For single threaded
models, this is performance neutral. For multi-threaded models, the
MTask affinity based sorting was slightly modified, so variables with no
MTask affinity are emitted last, otherwise the MTask affinity sets are
sorted using the TSP sorter as before, but again, ports, signals, and
internal variables are not differentiated. This yields a 2%+ speedup for
the multithreaded model on OpenTitan.
2021-06-29 18:57:07 +02:00
|
|
|
#include "V3AstUserAllocator.h"
|
|
|
|
|
#include "V3EmitCBase.h"
|
|
|
|
|
#include "V3TSP.h"
|
|
|
|
|
|
|
|
|
|
#include <vector>
|
|
|
|
|
|
2022-09-18 21:53:42 +02:00
|
|
|
VL_DEFINE_DEBUG_FUNCTIONS;
|
|
|
|
|
|
Add V3VariableOrder pass
A separate V3VariableOrder pass is now used to order module variables
before Emit. All variables are now ordered together, without
consideration for whether they are ports, signals form the design, or
additional internal variables added by Verilator (which used to be
ordered and emitted as separate groups in Emit). For single threaded
models, this is performance neutral. For multi-threaded models, the
MTask affinity based sorting was slightly modified, so variables with no
MTask affinity are emitted last, otherwise the MTask affinity sets are
sorted using the TSP sorter as before, but again, ports, signals, and
internal variables are not differentiated. This yields a 2%+ speedup for
the multithreaded model on OpenTitan.
2021-06-29 18:57:07 +02:00
|
|
|
//######################################################################
|
|
|
|
|
// Establish mtask variable sort order in mtasks mode
|
|
|
|
|
|
|
|
|
|
class VarTspSorter final : public V3TSP::TspStateBase {
|
|
|
|
|
// MEMBERS
|
|
|
|
|
const MTaskIdSet& m_mtaskIds; // Mtask we're ordering
|
|
|
|
|
static unsigned s_serialNext; // Unique ID to establish serial order
|
|
|
|
|
unsigned m_serial; // Serial ordering
|
|
|
|
|
public:
|
|
|
|
|
// CONSTRUCTORS
|
|
|
|
|
explicit VarTspSorter(const MTaskIdSet& mtaskIds)
|
|
|
|
|
: m_mtaskIds(mtaskIds) { // Cannot be {} or GCC 4.8 false warning
|
|
|
|
|
m_serial = ++s_serialNext; // Cannot be ()/{} or GCC 4.8 false warning
|
|
|
|
|
}
|
2022-07-30 16:01:25 +02:00
|
|
|
~VarTspSorter() override = default;
|
Add V3VariableOrder pass
A separate V3VariableOrder pass is now used to order module variables
before Emit. All variables are now ordered together, without
consideration for whether they are ports, signals form the design, or
additional internal variables added by Verilator (which used to be
ordered and emitted as separate groups in Emit). For single threaded
models, this is performance neutral. For multi-threaded models, the
MTask affinity based sorting was slightly modified, so variables with no
MTask affinity are emitted last, otherwise the MTask affinity sets are
sorted using the TSP sorter as before, but again, ports, signals, and
internal variables are not differentiated. This yields a 2%+ speedup for
the multithreaded model on OpenTitan.
2021-06-29 18:57:07 +02:00
|
|
|
// METHODS
|
2022-09-16 12:22:11 +02:00
|
|
|
bool operator<(const TspStateBase& other) const override {
|
2022-09-02 12:29:02 +02:00
|
|
|
return operator<(static_cast<const VarTspSorter&>(other));
|
Add V3VariableOrder pass
A separate V3VariableOrder pass is now used to order module variables
before Emit. All variables are now ordered together, without
consideration for whether they are ports, signals form the design, or
additional internal variables added by Verilator (which used to be
ordered and emitted as separate groups in Emit). For single threaded
models, this is performance neutral. For multi-threaded models, the
MTask affinity based sorting was slightly modified, so variables with no
MTask affinity are emitted last, otherwise the MTask affinity sets are
sorted using the TSP sorter as before, but again, ports, signals, and
internal variables are not differentiated. This yields a 2%+ speedup for
the multithreaded model on OpenTitan.
2021-06-29 18:57:07 +02:00
|
|
|
}
|
|
|
|
|
bool operator<(const VarTspSorter& other) const { return m_serial < other.m_serial; }
|
|
|
|
|
const MTaskIdSet& mtaskIds() const { return m_mtaskIds; }
|
2022-09-16 12:22:11 +02:00
|
|
|
int cost(const TspStateBase* otherp) const override {
|
2022-09-02 12:29:02 +02:00
|
|
|
return cost(static_cast<const VarTspSorter*>(otherp));
|
Add V3VariableOrder pass
A separate V3VariableOrder pass is now used to order module variables
before Emit. All variables are now ordered together, without
consideration for whether they are ports, signals form the design, or
additional internal variables added by Verilator (which used to be
ordered and emitted as separate groups in Emit). For single threaded
models, this is performance neutral. For multi-threaded models, the
MTask affinity based sorting was slightly modified, so variables with no
MTask affinity are emitted last, otherwise the MTask affinity sets are
sorted using the TSP sorter as before, but again, ports, signals, and
internal variables are not differentiated. This yields a 2%+ speedup for
the multithreaded model on OpenTitan.
2021-06-29 18:57:07 +02:00
|
|
|
}
|
2022-09-02 12:29:02 +02:00
|
|
|
int cost(const VarTspSorter* otherp) const {
|
Add V3VariableOrder pass
A separate V3VariableOrder pass is now used to order module variables
before Emit. All variables are now ordered together, without
consideration for whether they are ports, signals form the design, or
additional internal variables added by Verilator (which used to be
ordered and emitted as separate groups in Emit). For single threaded
models, this is performance neutral. For multi-threaded models, the
MTask affinity based sorting was slightly modified, so variables with no
MTask affinity are emitted last, otherwise the MTask affinity sets are
sorted using the TSP sorter as before, but again, ports, signals, and
internal variables are not differentiated. This yields a 2%+ speedup for
the multithreaded model on OpenTitan.
2021-06-29 18:57:07 +02:00
|
|
|
int cost = diffs(m_mtaskIds, otherp->m_mtaskIds);
|
|
|
|
|
cost += diffs(otherp->m_mtaskIds, m_mtaskIds);
|
|
|
|
|
return cost;
|
|
|
|
|
}
|
|
|
|
|
// Returns the number of elements in set_a that don't appear in set_b
|
|
|
|
|
static int diffs(const MTaskIdSet& set_a, const MTaskIdSet& set_b) {
|
|
|
|
|
int diffs = 0;
|
|
|
|
|
for (int i : set_a) {
|
|
|
|
|
if (set_b.find(i) == set_b.end()) ++diffs;
|
|
|
|
|
}
|
|
|
|
|
return diffs;
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
unsigned VarTspSorter::s_serialNext = 0;
|
|
|
|
|
|
|
|
|
|
class VariableOrder final {
|
|
|
|
|
// NODE STATE
|
|
|
|
|
// AstVar::user1() -> attributes, via m_attributes
|
2022-01-02 19:56:40 +01:00
|
|
|
const VNUser1InUse m_user1InUse; // AstVar
|
Add V3VariableOrder pass
A separate V3VariableOrder pass is now used to order module variables
before Emit. All variables are now ordered together, without
consideration for whether they are ports, signals form the design, or
additional internal variables added by Verilator (which used to be
ordered and emitted as separate groups in Emit). For single threaded
models, this is performance neutral. For multi-threaded models, the
MTask affinity based sorting was slightly modified, so variables with no
MTask affinity are emitted last, otherwise the MTask affinity sets are
sorted using the TSP sorter as before, but again, ports, signals, and
internal variables are not differentiated. This yields a 2%+ speedup for
the multithreaded model on OpenTitan.
2021-06-29 18:57:07 +02:00
|
|
|
|
2024-01-20 21:06:46 +01:00
|
|
|
struct VarAttributes final {
|
Add V3VariableOrder pass
A separate V3VariableOrder pass is now used to order module variables
before Emit. All variables are now ordered together, without
consideration for whether they are ports, signals form the design, or
additional internal variables added by Verilator (which used to be
ordered and emitted as separate groups in Emit). For single threaded
models, this is performance neutral. For multi-threaded models, the
MTask affinity based sorting was slightly modified, so variables with no
MTask affinity are emitted last, otherwise the MTask affinity sets are
sorted using the TSP sorter as before, but again, ports, signals, and
internal variables are not differentiated. This yields a 2%+ speedup for
the multithreaded model on OpenTitan.
2021-06-29 18:57:07 +02:00
|
|
|
uint32_t stratum; // Roughly equivalent to alignment requirement, to avoid padding
|
|
|
|
|
bool anonOk; // Can be emitted as part of anonymous structure
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
AstUser1Allocator<AstVar, VarAttributes> m_attributes; // Attributes used for sorting
|
|
|
|
|
|
|
|
|
|
//######################################################################
|
|
|
|
|
|
|
|
|
|
// Simple sort
|
|
|
|
|
void simpleSortVars(std::vector<AstVar*>& varps) {
|
|
|
|
|
stable_sort(varps.begin(), varps.end(),
|
|
|
|
|
[this](const AstVar* ap, const AstVar* bp) -> bool {
|
|
|
|
|
if (ap->isStatic() != bp->isStatic()) { // Non-statics before statics
|
|
|
|
|
return bp->isStatic();
|
|
|
|
|
}
|
|
|
|
|
const auto& attrA = m_attributes(ap);
|
|
|
|
|
const auto& attrB = m_attributes(bp);
|
|
|
|
|
if (attrA.anonOk != attrB.anonOk) { // Anons before non-anons
|
|
|
|
|
return attrA.anonOk;
|
|
|
|
|
}
|
|
|
|
|
return attrA.stratum < attrB.stratum; // Finally sort by stratum
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Sort by MTask-affinity first, then the same as simpleSortVars
|
|
|
|
|
void tspSortVars(std::vector<AstVar*>& varps) {
|
|
|
|
|
// Map from "MTask affinity" -> "variable list"
|
|
|
|
|
std::map<const MTaskIdSet, std::vector<AstVar*>> m2v;
|
|
|
|
|
for (AstVar* const varp : varps) { m2v[varp->mtaskIds()].push_back(varp); }
|
|
|
|
|
|
|
|
|
|
// Create a TSP sort state for each unique MTaskIdSet, except for the empty set
|
|
|
|
|
V3TSP::StateVec states;
|
|
|
|
|
for (const auto& pair : m2v) {
|
|
|
|
|
if (pair.first.empty()) continue;
|
2022-11-19 16:48:46 +01:00
|
|
|
states.push_back(new VarTspSorter{pair.first});
|
Add V3VariableOrder pass
A separate V3VariableOrder pass is now used to order module variables
before Emit. All variables are now ordered together, without
consideration for whether they are ports, signals form the design, or
additional internal variables added by Verilator (which used to be
ordered and emitted as separate groups in Emit). For single threaded
models, this is performance neutral. For multi-threaded models, the
MTask affinity based sorting was slightly modified, so variables with no
MTask affinity are emitted last, otherwise the MTask affinity sets are
sorted using the TSP sorter as before, but again, ports, signals, and
internal variables are not differentiated. This yields a 2%+ speedup for
the multithreaded model on OpenTitan.
2021-06-29 18:57:07 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Do the TSP sort
|
|
|
|
|
V3TSP::StateVec sortedStates;
|
|
|
|
|
V3TSP::tspSort(states, &sortedStates);
|
|
|
|
|
|
|
|
|
|
varps.clear();
|
|
|
|
|
|
|
|
|
|
// Helper function to sort given vector, then append to 'varps'
|
|
|
|
|
const auto sortAndAppend = [this, &varps](std::vector<AstVar*>& subVarps) {
|
|
|
|
|
simpleSortVars(subVarps);
|
|
|
|
|
for (AstVar* const varp : subVarps) { varps.push_back(varp); }
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
// Enumerate by sorted MTaskIdSet, sort within the set separately
|
|
|
|
|
for (const V3TSP::TspStateBase* const stateBasep : sortedStates) {
|
|
|
|
|
const VarTspSorter* const statep = dynamic_cast<const VarTspSorter*>(stateBasep);
|
|
|
|
|
sortAndAppend(m2v[statep->mtaskIds()]);
|
|
|
|
|
VL_DO_DANGLING(delete statep, statep);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Finally add the variables with no known MTask affinity
|
|
|
|
|
sortAndAppend(m2v[MTaskIdSet()]);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void orderModuleVars(AstNodeModule* modp) {
|
|
|
|
|
std::vector<AstVar*> varps;
|
|
|
|
|
|
|
|
|
|
// Unlink all module variables from the module, compute attributes
|
|
|
|
|
for (AstNode *nodep = modp->stmtsp(), *nextp; nodep; nodep = nextp) {
|
|
|
|
|
nextp = nodep->nextp();
|
|
|
|
|
if (AstVar* const varp = VN_CAST(nodep, Var)) {
|
|
|
|
|
// Unlink, add to vector
|
|
|
|
|
varp->unlinkFrBack();
|
|
|
|
|
varps.push_back(varp);
|
|
|
|
|
// Compute attributes up front
|
|
|
|
|
auto& attributes = m_attributes(varp);
|
|
|
|
|
// Stratum
|
|
|
|
|
const int sigbytes = varp->dtypeSkipRefp()->widthAlignBytes();
|
2022-08-30 04:49:19 +02:00
|
|
|
attributes.stratum = (v3Global.opt.hierChild() && varp->isPrimaryIO()) ? 0
|
|
|
|
|
: (varp->isUsedClock() && varp->widthMin() == 1) ? 1
|
|
|
|
|
: VN_IS(varp->dtypeSkipRefp(), UnpackArrayDType) ? 9
|
|
|
|
|
: (varp->basicp() && varp->basicp()->isOpaque()) ? 8
|
|
|
|
|
: (varp->isScBv() || varp->isScBigUint()) ? 7
|
|
|
|
|
: (sigbytes == 8) ? 6
|
|
|
|
|
: (sigbytes == 4) ? 5
|
|
|
|
|
: (sigbytes == 2) ? 3
|
|
|
|
|
: (sigbytes == 1) ? 2
|
|
|
|
|
: 10;
|
Add V3VariableOrder pass
A separate V3VariableOrder pass is now used to order module variables
before Emit. All variables are now ordered together, without
consideration for whether they are ports, signals form the design, or
additional internal variables added by Verilator (which used to be
ordered and emitted as separate groups in Emit). For single threaded
models, this is performance neutral. For multi-threaded models, the
MTask affinity based sorting was slightly modified, so variables with no
MTask affinity are emitted last, otherwise the MTask affinity sets are
sorted using the TSP sorter as before, but again, ports, signals, and
internal variables are not differentiated. This yields a 2%+ speedup for
the multithreaded model on OpenTitan.
2021-06-29 18:57:07 +02:00
|
|
|
// Anonymous structure ok
|
2023-03-18 17:05:29 +01:00
|
|
|
attributes.anonOk = EmitCBase::isAnonOk(varp);
|
Add V3VariableOrder pass
A separate V3VariableOrder pass is now used to order module variables
before Emit. All variables are now ordered together, without
consideration for whether they are ports, signals form the design, or
additional internal variables added by Verilator (which used to be
ordered and emitted as separate groups in Emit). For single threaded
models, this is performance neutral. For multi-threaded models, the
MTask affinity based sorting was slightly modified, so variables with no
MTask affinity are emitted last, otherwise the MTask affinity sets are
sorted using the TSP sorter as before, but again, ports, signals, and
internal variables are not differentiated. This yields a 2%+ speedup for
the multithreaded model on OpenTitan.
2021-06-29 18:57:07 +02:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!varps.empty()) {
|
|
|
|
|
// Sort variables
|
|
|
|
|
if (!v3Global.opt.mtasks()) {
|
|
|
|
|
simpleSortVars(varps);
|
|
|
|
|
} else {
|
|
|
|
|
tspSortVars(varps);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Insert them back under the module, in the new order, but at
|
|
|
|
|
// the front of the list so they come out first in dumps/XML.
|
|
|
|
|
auto it = varps.cbegin();
|
|
|
|
|
AstVar* const firstp = *it++;
|
|
|
|
|
for (; it != varps.cend(); ++it) firstp->addNext(*it);
|
|
|
|
|
if (AstNode* const stmtsp = modp->stmtsp()) {
|
|
|
|
|
stmtsp->unlinkFrBackWithNext();
|
2022-09-17 14:48:51 +02:00
|
|
|
AstNode::addNext<AstNode, AstNode>(firstp, stmtsp);
|
Add V3VariableOrder pass
A separate V3VariableOrder pass is now used to order module variables
before Emit. All variables are now ordered together, without
consideration for whether they are ports, signals form the design, or
additional internal variables added by Verilator (which used to be
ordered and emitted as separate groups in Emit). For single threaded
models, this is performance neutral. For multi-threaded models, the
MTask affinity based sorting was slightly modified, so variables with no
MTask affinity are emitted last, otherwise the MTask affinity sets are
sorted using the TSP sorter as before, but again, ports, signals, and
internal variables are not differentiated. This yields a 2%+ speedup for
the multithreaded model on OpenTitan.
2021-06-29 18:57:07 +02:00
|
|
|
}
|
2022-09-15 20:43:56 +02:00
|
|
|
modp->addStmtsp(firstp);
|
Add V3VariableOrder pass
A separate V3VariableOrder pass is now used to order module variables
before Emit. All variables are now ordered together, without
consideration for whether they are ports, signals form the design, or
additional internal variables added by Verilator (which used to be
ordered and emitted as separate groups in Emit). For single threaded
models, this is performance neutral. For multi-threaded models, the
MTask affinity based sorting was slightly modified, so variables with no
MTask affinity are emitted last, otherwise the MTask affinity sets are
sorted using the TSP sorter as before, but again, ports, signals, and
internal variables are not differentiated. This yields a 2%+ speedup for
the multithreaded model on OpenTitan.
2021-06-29 18:57:07 +02:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public:
|
2022-11-22 02:41:32 +01:00
|
|
|
static void processModule(AstNodeModule* modp) { VariableOrder{}.orderModuleVars(modp); }
|
Add V3VariableOrder pass
A separate V3VariableOrder pass is now used to order module variables
before Emit. All variables are now ordered together, without
consideration for whether they are ports, signals form the design, or
additional internal variables added by Verilator (which used to be
ordered and emitted as separate groups in Emit). For single threaded
models, this is performance neutral. For multi-threaded models, the
MTask affinity based sorting was slightly modified, so variables with no
MTask affinity are emitted last, otherwise the MTask affinity sets are
sorted using the TSP sorter as before, but again, ports, signals, and
internal variables are not differentiated. This yields a 2%+ speedup for
the multithreaded model on OpenTitan.
2021-06-29 18:57:07 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
//######################################################################
|
|
|
|
|
// V3VariableOrder static functions
|
|
|
|
|
|
|
|
|
|
void V3VariableOrder::orderAll() {
|
|
|
|
|
UINFO(2, __FUNCTION__ << ": " << endl);
|
|
|
|
|
for (AstNodeModule* modp = v3Global.rootp()->modulesp(); modp;
|
2021-10-22 14:56:48 +02:00
|
|
|
modp = VN_AS(modp->nextp(), NodeModule)) {
|
Add V3VariableOrder pass
A separate V3VariableOrder pass is now used to order module variables
before Emit. All variables are now ordered together, without
consideration for whether they are ports, signals form the design, or
additional internal variables added by Verilator (which used to be
ordered and emitted as separate groups in Emit). For single threaded
models, this is performance neutral. For multi-threaded models, the
MTask affinity based sorting was slightly modified, so variables with no
MTask affinity are emitted last, otherwise the MTask affinity sets are
sorted using the TSP sorter as before, but again, ports, signals, and
internal variables are not differentiated. This yields a 2%+ speedup for
the multithreaded model on OpenTitan.
2021-06-29 18:57:07 +02:00
|
|
|
VariableOrder::processModule(modp);
|
|
|
|
|
}
|
2024-01-09 16:35:13 +01:00
|
|
|
V3Global::dumpCheckGlobalTree("variableorder", 0, dumpTreeEitherLevel() >= 3);
|
Add V3VariableOrder pass
A separate V3VariableOrder pass is now used to order module variables
before Emit. All variables are now ordered together, without
consideration for whether they are ports, signals form the design, or
additional internal variables added by Verilator (which used to be
ordered and emitted as separate groups in Emit). For single threaded
models, this is performance neutral. For multi-threaded models, the
MTask affinity based sorting was slightly modified, so variables with no
MTask affinity are emitted last, otherwise the MTask affinity sets are
sorted using the TSP sorter as before, but again, ports, signals, and
internal variables are not differentiated. This yields a 2%+ speedup for
the multithreaded model on OpenTitan.
2021-06-29 18:57:07 +02:00
|
|
|
}
|