Internals: Refactor to create VCMethod (#3715). No functional change intended.
This commit is contained in:
parent
89cd5417ef
commit
3b623dc12e
|
|
@ -233,7 +233,8 @@ private:
|
|||
new AstSenItem{flp, VEdgeType::ET_CHANGED, skewedReadRefp->cloneTree(false)});
|
||||
AstCMethodHard* const trigp = new AstCMethodHard{
|
||||
nodep->fileline(),
|
||||
new AstVarRef{flp, m_clockingp->ensureEventp(), VAccess::READ}, "isTriggered"};
|
||||
new AstVarRef{flp, m_clockingp->ensureEventp(), VAccess::READ},
|
||||
VCMethod::EVENT_IS_TRIGGERED};
|
||||
trigp->dtypeSetBit();
|
||||
ifp->condp(new AstLogAnd{flp, ifp->condp()->unlinkFrBack(), trigp});
|
||||
m_clockingp->addNextHere(new AstAlwaysReactive{flp, senTreep, ifp});
|
||||
|
|
@ -285,7 +286,7 @@ private:
|
|||
// Create a process like this:
|
||||
// always queue.push(<sampled var>);
|
||||
AstCMethodHard* const pushp = new AstCMethodHard{
|
||||
flp, new AstVarRef{flp, queueVarp, VAccess::WRITE}, "push",
|
||||
flp, new AstVarRef{flp, queueVarp, VAccess::WRITE}, VCMethod::DYN_PUSH,
|
||||
new AstTime{nodep->fileline(), m_modp->timeunit()}};
|
||||
pushp->addPinsp(exprp->cloneTreePure(false));
|
||||
pushp->dtypeSetVoid();
|
||||
|
|
@ -294,7 +295,7 @@ private:
|
|||
// Create a process like this:
|
||||
// always @<clocking event> queue.pop(<skew>, /*out*/<skewed var>);
|
||||
AstCMethodHard* const popp = new AstCMethodHard{
|
||||
flp, new AstVarRef{flp, queueVarp, VAccess::READWRITE}, "pop",
|
||||
flp, new AstVarRef{flp, queueVarp, VAccess::READWRITE}, VCMethod::DYN_POP,
|
||||
new AstTime{nodep->fileline(), m_modp->timeunit()}};
|
||||
popp->addPinsp(skewp->unlinkFrBack());
|
||||
popp->addPinsp(refp);
|
||||
|
|
|
|||
|
|
@ -49,6 +49,28 @@ bool VNUser4InUse::s_userBusy = false;
|
|||
|
||||
int AstNodeDType::s_uniqueNum = 0;
|
||||
|
||||
V3AST_VCMETHOD_ITEMDATA_DECL;
|
||||
|
||||
//======================================================================
|
||||
// VCMethod information
|
||||
|
||||
VCMethod VCMethod::arrayMethod(const string& name) {
|
||||
for (auto& it : s_itemData)
|
||||
if (it.m_name == name) return it.m_e;
|
||||
v3fatalSrc("Not a method name known to VCMethod::s_itemData: '" << name << '\'');
|
||||
return VCMethod{};
|
||||
}
|
||||
void VCMethod::selfTest() {
|
||||
int i = 0;
|
||||
for (auto& it : s_itemData) {
|
||||
VCMethod exp{i};
|
||||
UASSERT_STATIC(it.m_e == exp,
|
||||
"VCMethod::s_itemData table rows are out-of-order, starting at row "s
|
||||
+ cvtToStr(i) + " '" + +it.m_name + '\'');
|
||||
++i;
|
||||
}
|
||||
}
|
||||
|
||||
//######################################################################
|
||||
// VNType
|
||||
|
||||
|
|
|
|||
241
src/V3AstAttr.h
241
src/V3AstAttr.h
|
|
@ -703,6 +703,247 @@ inline std::ostream& operator<<(std::ostream& os, const VBranchPred& rhs) {
|
|||
|
||||
// ######################################################################
|
||||
|
||||
class VCMethod final {
|
||||
public:
|
||||
// Entries in this table need to match below VCMethod::s_itemData[] table
|
||||
enum en : uint8_t {
|
||||
_NONE, // Unknown
|
||||
ARRAY_AND,
|
||||
ARRAY_AT,
|
||||
ARRAY_AT_BACK,
|
||||
ARRAY_AT_WRITE,
|
||||
ARRAY_FIND,
|
||||
ARRAY_FIND_FIRST,
|
||||
ARRAY_FIND_FIRST_INDEX,
|
||||
ARRAY_FIND_INDEX,
|
||||
ARRAY_FIND_LAST,
|
||||
ARRAY_FIND_LAST_INDEX,
|
||||
ARRAY_FIRST,
|
||||
ARRAY_INSIDE,
|
||||
ARRAY_LAST,
|
||||
ARRAY_MAX,
|
||||
ARRAY_MIN,
|
||||
ARRAY_NEXT,
|
||||
ARRAY_OR,
|
||||
ARRAY_POP_BACK,
|
||||
ARRAY_POP_FRONT,
|
||||
ARRAY_PREV,
|
||||
ARRAY_PRODUCT,
|
||||
ARRAY_PUSH_BACK,
|
||||
ARRAY_PUSH_FRONT,
|
||||
ARRAY_REVERSE,
|
||||
ARRAY_RSORT,
|
||||
ARRAY_R_AND,
|
||||
ARRAY_R_OR,
|
||||
ARRAY_R_PRODUCT,
|
||||
ARRAY_R_SUM,
|
||||
ARRAY_R_XOR,
|
||||
ARRAY_SHUFFLE,
|
||||
ARRAY_SORT,
|
||||
ARRAY_SUM,
|
||||
ARRAY_UNIQUE,
|
||||
ARRAY_UNIQUE_INDEX,
|
||||
ARRAY_XOR,
|
||||
ASSOC_CLEAR,
|
||||
ASSOC_ERASE,
|
||||
ASSOC_EXISTS,
|
||||
ASSOC_FIRST,
|
||||
ASSOC_NEXT,
|
||||
ASSOC_SIZE,
|
||||
CLASS_SET_RANDMODE,
|
||||
DYN_AT_WRITE_APPEND,
|
||||
DYN_AT_WRITE_APPEND_BACK,
|
||||
DYN_CLEAR,
|
||||
DYN_ERASE,
|
||||
DYN_INSERT,
|
||||
DYN_POP,
|
||||
DYN_POP_FRONT,
|
||||
DYN_PUSH,
|
||||
DYN_PUSH_FRONT,
|
||||
DYN_RENEW,
|
||||
DYN_RENEW_COPY,
|
||||
DYN_RESIZE,
|
||||
DYN_SIZE,
|
||||
DYN_SLICE,
|
||||
DYN_SLICE_BACK_BACK,
|
||||
DYN_SLICE_FRONT_BACK,
|
||||
EVENT_CLEAR_FIRED,
|
||||
EVENT_CLEAR_TRIGGERED,
|
||||
EVENT_FIRE,
|
||||
EVENT_IS_FIRED,
|
||||
EVENT_IS_TRIGGERED,
|
||||
FORK_DONE,
|
||||
FORK_INIT,
|
||||
FORK_JOIN,
|
||||
RANDOMIZER_BASIC_STD_RANDOMIZATION,
|
||||
RANDOMIZER_CLEAR,
|
||||
RANDOMIZER_HARD,
|
||||
RANDOMIZER_WRITE_VAR,
|
||||
RNG_GET_RANDSTATE,
|
||||
RNG_SET_RANDSTATE,
|
||||
SCHED_ANY_TRIGGERED,
|
||||
SCHED_AWAITING_CURRENT_TIME,
|
||||
SCHED_COMMIT,
|
||||
SCHED_DELAY,
|
||||
SCHED_DO_POST_UPDATES,
|
||||
SCHED_ENQUEUE,
|
||||
SCHED_EVALUATE,
|
||||
SCHED_EVALUATION,
|
||||
SCHED_POST_UPDATE,
|
||||
SCHED_RESUME,
|
||||
SCHED_RESUMPTION,
|
||||
SCHED_TRIGGER,
|
||||
SCHED_TRIGGERED,
|
||||
TRIGGER_AND_NOT,
|
||||
TRIGGER_ANY,
|
||||
TRIGGER_CLEAR,
|
||||
TRIGGER_SET_BIT,
|
||||
TRIGGER_SET_WORD,
|
||||
TRIGGER_THIS_OR,
|
||||
TRIGGER_WORD,
|
||||
UNPACKED_ASSIGN,
|
||||
UNPACKED_FILL,
|
||||
UNPACKED_NEQ,
|
||||
_ENUM_MAX // Leave last
|
||||
};
|
||||
|
||||
private:
|
||||
struct Item final {
|
||||
enum en m_e; // Method's enum mnemonic, for checking
|
||||
const char* m_name; // Method name, printed into C++
|
||||
bool m_pure; // Method being called is pure
|
||||
};
|
||||
static Item s_itemData[];
|
||||
|
||||
public:
|
||||
enum en m_e;
|
||||
VCMethod()
|
||||
: m_e{_NONE} {}
|
||||
// cppcheck-suppress noExplicitConstructor
|
||||
constexpr VCMethod(en _e)
|
||||
: m_e{_e} {}
|
||||
explicit VCMethod(int _e)
|
||||
: m_e(static_cast<en>(_e)) {} // Need () or GCC 4.8 false warning
|
||||
constexpr operator en() const { return m_e; }
|
||||
const char* ascii() const VL_PURE { return s_itemData[m_e].m_name; }
|
||||
bool isPure() const VL_PURE { return s_itemData[m_e].m_pure; }
|
||||
// Return array method for given name
|
||||
static VCMethod arrayMethod(const string& name);
|
||||
static void selfTest();
|
||||
};
|
||||
constexpr bool operator==(const VCMethod& lhs, const VCMethod& rhs) { return lhs.m_e == rhs.m_e; }
|
||||
constexpr bool operator==(const VCMethod& lhs, VCMethod::en rhs) { return lhs.m_e == rhs; }
|
||||
constexpr bool operator==(VCMethod::en lhs, const VCMethod& rhs) { return lhs == rhs.m_e; }
|
||||
inline std::ostream& operator<<(std::ostream& os, const VCMethod& rhs) {
|
||||
return os << rhs.ascii();
|
||||
}
|
||||
|
||||
// Entries in this table need to match above VCMethod enum table
|
||||
//
|
||||
// {Mnemonic, C++ method, pure}
|
||||
#define V3AST_VCMETHOD_ITEMDATA_DECL \
|
||||
VCMethod::Item VCMethod::s_itemData[] \
|
||||
= {{_NONE, "_none", false}, \
|
||||
{ARRAY_AND, "and", true}, \
|
||||
{ARRAY_AT, "at", true}, \
|
||||
{ARRAY_AT_BACK, "atBack", true}, \
|
||||
{ARRAY_AT_WRITE, "atWrite", true}, \
|
||||
{ARRAY_FIND, "find", true}, \
|
||||
{ARRAY_FIND_FIRST, "find_first", true}, \
|
||||
{ARRAY_FIND_FIRST_INDEX, "find_first_index", true}, \
|
||||
{ARRAY_FIND_INDEX, "find_index", true}, \
|
||||
{ARRAY_FIND_LAST, "find_last", true}, \
|
||||
{ARRAY_FIND_LAST_INDEX, "find_last_index", true}, \
|
||||
{ARRAY_FIRST, "first", false}, \
|
||||
{ARRAY_INSIDE, "inside", true}, \
|
||||
{ARRAY_LAST, "last", false}, \
|
||||
{ARRAY_MAX, "max", true}, \
|
||||
{ARRAY_MIN, "min", true}, \
|
||||
{ARRAY_NEXT, "next", false}, \
|
||||
{ARRAY_OR, "or", true}, \
|
||||
{ARRAY_POP_BACK, "pop_back", false}, \
|
||||
{ARRAY_POP_FRONT, "pop_front", false}, \
|
||||
{ARRAY_PREV, "prev", false}, \
|
||||
{ARRAY_PRODUCT, "product", true}, \
|
||||
{ARRAY_PUSH_BACK, "push_back", false}, \
|
||||
{ARRAY_PUSH_FRONT, "push_front", false}, \
|
||||
{ARRAY_REVERSE, "reverse", false}, \
|
||||
{ARRAY_RSORT, "rsort", false}, \
|
||||
{ARRAY_R_AND, "r_and", true}, \
|
||||
{ARRAY_R_OR, "r_or", true}, \
|
||||
{ARRAY_R_PRODUCT, "r_product", true}, \
|
||||
{ARRAY_R_SUM, "r_sum", true}, \
|
||||
{ARRAY_R_XOR, "r_xor", true}, \
|
||||
{ARRAY_SHUFFLE, "shuffle", false}, \
|
||||
{ARRAY_SORT, "sort", false}, \
|
||||
{ARRAY_SUM, "sum", true}, \
|
||||
{ARRAY_UNIQUE, "unique", true}, \
|
||||
{ARRAY_UNIQUE_INDEX, "unique_index", true}, \
|
||||
{ARRAY_XOR, "xor", true}, \
|
||||
{ASSOC_CLEAR, "clear", false}, \
|
||||
{ASSOC_ERASE, "erase", false}, \
|
||||
{ASSOC_EXISTS, "exists", true}, \
|
||||
{ASSOC_FIRST, "first", false}, \
|
||||
{ASSOC_NEXT, "next", false}, \
|
||||
{ASSOC_SIZE, "size", true}, \
|
||||
{CLASS_SET_RANDMODE, "set_randmode", false}, \
|
||||
{DYN_AT_WRITE_APPEND, "atWriteAppend", false}, \
|
||||
{DYN_AT_WRITE_APPEND_BACK, "atWriteAppendBack", false}, \
|
||||
{DYN_CLEAR, "clear", false}, \
|
||||
{DYN_ERASE, "erase", false}, \
|
||||
{DYN_INSERT, "insert", false}, \
|
||||
{DYN_POP, "pop", false}, \
|
||||
{DYN_POP_FRONT, "pop_front", false}, \
|
||||
{DYN_PUSH, "push", false}, \
|
||||
{DYN_PUSH_FRONT, "push_front", false}, \
|
||||
{DYN_RENEW, "renew", false}, \
|
||||
{DYN_RENEW_COPY, "renew_copy", false}, \
|
||||
{DYN_RESIZE, "resize", false}, \
|
||||
{DYN_SIZE, "size", true}, \
|
||||
{DYN_SLICE, "slice", true}, \
|
||||
{DYN_SLICE_BACK_BACK, "sliceBackBack", true}, \
|
||||
{DYN_SLICE_FRONT_BACK, "sliceFrontBack", true}, \
|
||||
{EVENT_CLEAR_FIRED, "clearFired", false}, \
|
||||
{EVENT_CLEAR_TRIGGERED, "clearTriggered", false}, \
|
||||
{EVENT_FIRE, "fire", false}, \
|
||||
{EVENT_IS_FIRED, "isFired", true}, \
|
||||
{EVENT_IS_TRIGGERED, "isTriggered", true}, \
|
||||
{FORK_DONE, "done", false}, \
|
||||
{FORK_INIT, "init", false}, \
|
||||
{FORK_JOIN, "join", false}, \
|
||||
{RANDOMIZER_BASIC_STD_RANDOMIZATION, "basicStdRandomization", false}, \
|
||||
{RANDOMIZER_CLEAR, "clear", false}, \
|
||||
{RANDOMIZER_HARD, "hard", false}, \
|
||||
{RANDOMIZER_WRITE_VAR, "write_var", false}, \
|
||||
{RNG_GET_RANDSTATE, "__Vm_rng.get_randstate", true}, \
|
||||
{RNG_SET_RANDSTATE, "__Vm_rng.set_randstate", false}, \
|
||||
{SCHED_ANY_TRIGGERED, "anyTriggered", false}, \
|
||||
{SCHED_AWAITING_CURRENT_TIME, "awaitingCurrentTime", true}, \
|
||||
{SCHED_COMMIT, "commit", false}, \
|
||||
{SCHED_DELAY, "delay", false}, \
|
||||
{SCHED_DO_POST_UPDATES, "doPostUpdates", false}, \
|
||||
{SCHED_ENQUEUE, "enqueue", false}, \
|
||||
{SCHED_EVALUATE, "evaluate", false}, \
|
||||
{SCHED_EVALUATION, "evaluation", false}, \
|
||||
{SCHED_POST_UPDATE, "postUpdate", false}, \
|
||||
{SCHED_RESUME, "resume", false}, \
|
||||
{SCHED_RESUMPTION, "resumption", false}, \
|
||||
{SCHED_TRIGGER, "trigger", false}, \
|
||||
{SCHED_TRIGGERED, "triggered", false}, \
|
||||
{TRIGGER_AND_NOT, "andNot", false}, \
|
||||
{TRIGGER_ANY, "any", true}, \
|
||||
{TRIGGER_CLEAR, "clear", false}, \
|
||||
{TRIGGER_SET_BIT, "setBit", false}, \
|
||||
{TRIGGER_SET_WORD, "setWord", false}, \
|
||||
{TRIGGER_THIS_OR, "thisOr", false}, \
|
||||
{TRIGGER_WORD, "word", true}, \
|
||||
{UNPACKED_ASSIGN, "assign", false}, \
|
||||
{UNPACKED_FILL, "fill", false}, \
|
||||
{UNPACKED_NEQ, "neq", true}, \
|
||||
{_ENUM_MAX, "_ENUM_MAX", false}};
|
||||
|
||||
// ######################################################################
|
||||
|
||||
class VCaseType final {
|
||||
public:
|
||||
enum en : uint8_t { CT_CASE, CT_CASEX, CT_CASEZ, CT_CASEINSIDE };
|
||||
|
|
|
|||
|
|
@ -618,24 +618,22 @@ class AstCMethodHard final : public AstNodeExpr {
|
|||
// PARENTS: stmt/expr
|
||||
// @astgen op1 := fromp : AstNodeExpr // Subject of method call
|
||||
// @astgen op2 := pinsp : List[AstNodeExpr] // Arguments
|
||||
string m_name; // Name of method
|
||||
VCMethod m_method; // Which method to call
|
||||
bool m_pure = false; // Pure optimizable
|
||||
bool m_usePtr = false; // Use '->' not '.'
|
||||
public:
|
||||
AstCMethodHard(FileLine* fl, AstNodeExpr* fromp, const string& name,
|
||||
AstNodeExpr* pinsp = nullptr)
|
||||
AstCMethodHard(FileLine* fl, AstNodeExpr* fromp, VCMethod method, AstNodeExpr* pinsp = nullptr)
|
||||
: ASTGEN_SUPER_CMethodHard(fl)
|
||||
, m_name{name} {
|
||||
, m_method{method} {
|
||||
this->fromp(fromp);
|
||||
addPinsp(pinsp);
|
||||
setPurity();
|
||||
}
|
||||
ASTGEN_MEMBERS_AstCMethodHard;
|
||||
string name() const override VL_MT_STABLE { return m_name; } // * = Var name
|
||||
void name(const string& name) override { m_name = name; }
|
||||
string name() const override VL_MT_STABLE { return method().ascii(); }
|
||||
bool sameNode(const AstNode* samep) const override {
|
||||
const AstCMethodHard* const asamep = VN_DBG_AS(samep, CMethodHard);
|
||||
return (m_name == asamep->m_name);
|
||||
return (m_method == asamep->m_method);
|
||||
}
|
||||
bool isPure() override { return m_pure; }
|
||||
int instrCount() const override;
|
||||
|
|
@ -644,6 +642,8 @@ public:
|
|||
bool cleanOut() const override { return true; }
|
||||
bool usePtr() const { return m_usePtr; }
|
||||
void usePtr(bool flag) { m_usePtr = flag; }
|
||||
VCMethod method() const VL_MT_STABLE { return m_method; }
|
||||
void method(VCMethod value) { m_method = value; }
|
||||
|
||||
private:
|
||||
void setPurity();
|
||||
|
|
|
|||
|
|
@ -91,12 +91,10 @@ bool AstNodeFTaskRef::getPurityRecurse() const {
|
|||
AstNodeFTask* const taskp = this->taskp();
|
||||
// Unlinked yet, so treat as impure
|
||||
if (!taskp) return false;
|
||||
|
||||
// First compute the purity of arguments
|
||||
for (AstNode* pinp = this->pinsp(); pinp; pinp = pinp->nextp()) {
|
||||
if (!pinp->isPure()) return false;
|
||||
}
|
||||
|
||||
return taskp->isPure();
|
||||
}
|
||||
bool AstNodeFTaskRef::isGateOptimizable() const { return m_taskp && m_taskp->isGateOptimizable(); }
|
||||
|
|
@ -3144,94 +3142,17 @@ void AstCAwait::dump(std::ostream& str) const {
|
|||
void AstCAwait::dumpJson(std::ostream& str) const { dumpJsonGen(str); }
|
||||
int AstCMethodHard::instrCount() const {
|
||||
if (const AstBasicDType* const basicp = fromp()->dtypep()->basicp()) {
|
||||
// TODO: add a more structured description of library methods, rather than using string
|
||||
// matching. See issue #3715.
|
||||
if (basicp->isTriggerVec() && m_name == "word") {
|
||||
if (basicp->isTriggerVec() && m_method == VCMethod::TRIGGER_WORD) {
|
||||
// This is an important special case for scheduling so we compute it precisely,
|
||||
// it is simply a load.
|
||||
return INSTR_COUNT_LD;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
return 0; // TODO
|
||||
}
|
||||
void AstCMethodHard::setPurity() {
|
||||
static const std::map<std::string, bool> isPureMethod{{"__Vm_rng.get_randstate", true},
|
||||
{"__Vm_rng.set_randstate", false},
|
||||
{"andNot", false},
|
||||
{"any", true},
|
||||
{"anyTriggered", false},
|
||||
{"assign", false},
|
||||
{"at", true},
|
||||
{"atBack", true},
|
||||
{"atWrite", true},
|
||||
{"awaitingCurrentTime", true},
|
||||
{"basicStdRandomization", false},
|
||||
{"clear", false},
|
||||
{"clearFired", false},
|
||||
{"commit", false},
|
||||
{"delay", false},
|
||||
{"done", false},
|
||||
{"enqueue", false},
|
||||
{"erase", false},
|
||||
{"evaluate", false},
|
||||
{"evaluation", false},
|
||||
{"exists", true},
|
||||
{"fill", false},
|
||||
{"find", true},
|
||||
{"find_first", true},
|
||||
{"find_first_index", true},
|
||||
{"find_index", true},
|
||||
{"find_last", true},
|
||||
{"find_last_index", true},
|
||||
{"fire", false},
|
||||
{"first", false},
|
||||
{"hard", false},
|
||||
{"init", false},
|
||||
{"insert", false},
|
||||
{"inside", true},
|
||||
{"isFired", true},
|
||||
{"isTriggered", true},
|
||||
{"join", false},
|
||||
{"last", false},
|
||||
{"max", true},
|
||||
{"min", true},
|
||||
{"neq", true},
|
||||
{"next", false},
|
||||
{"pop", false},
|
||||
{"pop_back", false},
|
||||
{"pop_front", false},
|
||||
{"prev", false},
|
||||
{"push", false},
|
||||
{"push_back", false},
|
||||
{"push_front", false},
|
||||
{"r_and", true},
|
||||
{"r_or", true},
|
||||
{"r_product", true},
|
||||
{"r_sum", true},
|
||||
{"r_xor", true},
|
||||
{"renew", false},
|
||||
{"renew_copy", false},
|
||||
{"resize", false},
|
||||
{"resume", false},
|
||||
{"reverse", false},
|
||||
{"rsort", false},
|
||||
{"setBit", false},
|
||||
{"setWord", false},
|
||||
{"set_randmode", false},
|
||||
{"shuffle", false},
|
||||
{"size", true},
|
||||
{"slice", true},
|
||||
{"sliceBackBack", true},
|
||||
{"sliceFrontBack", true},
|
||||
{"sort", false},
|
||||
{"thisOr", false},
|
||||
{"trigger", false},
|
||||
{"unique", true},
|
||||
{"unique_index", true},
|
||||
{"word", true},
|
||||
{"write_var", false}};
|
||||
|
||||
if (name() == "atWriteAppend" || name() == "atWriteAppendBack") {
|
||||
if (method() == VCMethod::DYN_AT_WRITE_APPEND
|
||||
|| method() == VCMethod::DYN_AT_WRITE_APPEND_BACK) {
|
||||
m_pure = false;
|
||||
// Treat atWriteAppend as pure if the argument is a loop iterator
|
||||
if (const AstNodeExpr* const argp = pinsp()) {
|
||||
|
|
@ -3241,11 +3162,7 @@ void AstCMethodHard::setPurity() {
|
|||
}
|
||||
return;
|
||||
}
|
||||
auto isPureIt = isPureMethod.find(name());
|
||||
// cppcheck-suppress derefInvalidIteratorRedundantCheck
|
||||
UASSERT_OBJ(isPureIt != isPureMethod.end(), this, "Unknown purity of method " + name());
|
||||
// cppcheck-suppress derefInvalidIteratorRedundantCheck
|
||||
m_pure = isPureIt->second;
|
||||
m_pure = method().isPure();
|
||||
if (!m_pure) return;
|
||||
if (!fromp()->isPure()) m_pure = false;
|
||||
if (!m_pure) return;
|
||||
|
|
|
|||
|
|
@ -485,9 +485,9 @@ AstNode* V3Begin::convertToWhile(AstForeach* nodep) {
|
|||
? new AstArraySel{fl, subfromp->cloneTreePure(false),
|
||||
new AstVarRef{fl, nestedIndexp, VAccess::READ}}
|
||||
: subfromp->cloneTreePure(false),
|
||||
"size"};
|
||||
VCMethod::DYN_SIZE};
|
||||
AstVarRef* varRefp = new AstVarRef{fl, varp, VAccess::READ};
|
||||
subfromp = new AstCMethodHard{fl, subfromp, "at", varRefp};
|
||||
subfromp = new AstCMethodHard{fl, subfromp, VCMethod::ARRAY_AT, varRefp};
|
||||
subfromp->dtypep(fromDtp);
|
||||
rightp->dtypeSetSigned32();
|
||||
rightp->protect(false);
|
||||
|
|
@ -503,15 +503,15 @@ AstNode* V3Begin::convertToWhile(AstForeach* nodep) {
|
|||
first_varp->usedLoopIdx(true);
|
||||
first_varp->lifetime(VLifetime::AUTOMATIC_EXPLICIT);
|
||||
AstNodeExpr* const firstp
|
||||
= new AstCMethodHard{fl, subfromp->cloneTreePure(false), "first",
|
||||
= new AstCMethodHard{fl, subfromp->cloneTreePure(false), VCMethod::ASSOC_FIRST,
|
||||
new AstVarRef{fl, varp, VAccess::READWRITE}};
|
||||
firstp->dtypeSetSigned32();
|
||||
AstNodeExpr* const nextp
|
||||
= new AstCMethodHard{fl, subfromp->cloneTreePure(false), "next",
|
||||
= new AstCMethodHard{fl, subfromp->cloneTreePure(false), VCMethod::ASSOC_NEXT,
|
||||
new AstVarRef{fl, varp, VAccess::READWRITE}};
|
||||
nextp->dtypeSetSigned32();
|
||||
AstVarRef* varRefp = new AstVarRef{fl, varp, VAccess::READ};
|
||||
subfromp = new AstCMethodHard{fl, subfromp, "at", varRefp};
|
||||
subfromp = new AstCMethodHard{fl, subfromp, VCMethod::ARRAY_AT, varRefp};
|
||||
subfromp->dtypep(fromDtp);
|
||||
AstNode* const first_clearp
|
||||
= new AstAssign{fl, new AstVarRef{fl, first_varp, VAccess::WRITE},
|
||||
|
|
|
|||
|
|
@ -3012,8 +3012,8 @@ class ConstVisitor final : public VNVisitor {
|
|||
|
||||
if (const AstCMethodHard* const aCallp = VN_CAST(ap, CMethodHard)) {
|
||||
const AstCMethodHard* const bCallp = VN_AS(bp, CMethodHard);
|
||||
if (aCallp->name() < bCallp->name()) return -1;
|
||||
if (aCallp->name() > bCallp->name()) return 1;
|
||||
if (aCallp->method() < bCallp->method()) return -1;
|
||||
if (aCallp->method() > bCallp->method()) return 1;
|
||||
if (const int c = cmp(aCallp->fromp(), bCallp->fromp())) return c;
|
||||
const AstNodeExpr* aPinsp = aCallp->pinsp();
|
||||
const AstNodeExpr* bPinsp = bCallp->pinsp();
|
||||
|
|
|
|||
|
|
@ -859,8 +859,8 @@ class DelayedVisitor final : public VNVisitor {
|
|||
AstAlwaysPost* const postp = new AstAlwaysPost{flp};
|
||||
activep->addStmtsp(postp);
|
||||
// Add the commit
|
||||
AstCMethodHard* const callp
|
||||
= new AstCMethodHard{flp, new AstVarRef{flp, queueVscp, VAccess::READWRITE}, "commit"};
|
||||
AstCMethodHard* const callp = new AstCMethodHard{
|
||||
flp, new AstVarRef{flp, queueVscp, VAccess::READWRITE}, VCMethod::SCHED_COMMIT};
|
||||
callp->dtypeSetVoid();
|
||||
callp->addPinsp(new AstVarRef{flp, vscp, VAccess::WRITE});
|
||||
postp->addStmtsp(callp->makeStmt());
|
||||
|
|
@ -969,7 +969,8 @@ class DelayedVisitor final : public VNVisitor {
|
|||
|
||||
// Enqueue the update at the site of the original NBA
|
||||
AstCMethodHard* const callp = new AstCMethodHard{
|
||||
flp, new AstVarRef{flp, vscpInfo.valueQueueKit().vscp, VAccess::READWRITE}, "enqueue"};
|
||||
flp, new AstVarRef{flp, vscpInfo.valueQueueKit().vscp, VAccess::READWRITE},
|
||||
VCMethod::SCHED_ENQUEUE};
|
||||
callp->dtypeSetVoid();
|
||||
callp->addPinsp(valuep);
|
||||
if (partial) callp->addPinsp(maskp);
|
||||
|
|
|
|||
|
|
@ -280,7 +280,7 @@ void V3DfgPasses::binToOneHot(DfgGraph& dfg, V3DfgBinToOneHotContext& ctx) {
|
|||
}
|
||||
{ // tab.fill(0)
|
||||
AstCMethodHard* const callp = new AstCMethodHard{
|
||||
flp, new AstVarRef{flp, tabVtxp->varp(), VAccess::WRITE}, "fill"};
|
||||
flp, new AstVarRef{flp, tabVtxp->varp(), VAccess::WRITE}, VCMethod::UNPACKED_FILL};
|
||||
callp->addPinsp(new AstConst{flp, AstConst::BitFalse{}});
|
||||
callp->dtypeSetVoid();
|
||||
initp->addStmtsp(callp->makeStmt());
|
||||
|
|
|
|||
|
|
@ -293,7 +293,7 @@ class HasherVisitor final : public VNVisitorConst {
|
|||
}
|
||||
void visit(AstCMethodHard* nodep) override {
|
||||
m_hash += hashNodeAndIterate(nodep, false, HASH_CHILDREN, [this, nodep]() { //
|
||||
m_hash += nodep->name();
|
||||
m_hash += nodep->method();
|
||||
});
|
||||
}
|
||||
void visit(AstCAwait* nodep) override {
|
||||
|
|
|
|||
|
|
@ -233,7 +233,8 @@ class RandomizeMarkVisitor final : public VNVisitor {
|
|||
nodep->v3error("Cannot call 'rand_mode()' on packed array element");
|
||||
valid = false;
|
||||
} else if (AstCMethodHard* const methodHardp = VN_CAST(fromp, CMethodHard)) {
|
||||
if (methodHardp->name() == "at" || methodHardp->name() == "atWrite") {
|
||||
if (methodHardp->method() == VCMethod::ARRAY_AT
|
||||
|| methodHardp->method() == VCMethod::ARRAY_AT_WRITE) {
|
||||
nodep->v3warn(E_UNSUPPORTED,
|
||||
"Unsupported: 'rand_mode()' on dynamic array element");
|
||||
valid = false;
|
||||
|
|
@ -622,7 +623,7 @@ class ConstraintExprVisitor final : public VNVisitor {
|
|||
AstNodeDType* const arrDtp = arrayp->unlinkFrBack()->dtypep();
|
||||
AstNodeExpr* selp = nullptr;
|
||||
if (VN_IS(arrDtp, QueueDType) || VN_IS(arrDtp, DynArrayDType))
|
||||
selp = new AstCMethodHard{fl, arrayp, "at", idxp};
|
||||
selp = new AstCMethodHard{fl, arrayp, VCMethod::ARRAY_AT, idxp};
|
||||
else if (VN_IS(arrDtp, UnpackArrayDType))
|
||||
selp = new AstArraySel{fl, arrayp, idxp};
|
||||
else if (VN_IS(arrDtp, AssocArrayDType))
|
||||
|
|
@ -662,7 +663,7 @@ class ConstraintExprVisitor final : public VNVisitor {
|
|||
nodep->fileline(),
|
||||
new AstVarRef{varp->fileline(), VN_AS(m_randModeVarp->user2p(), NodeModule),
|
||||
m_randModeVarp, VAccess::READ},
|
||||
"at", new AstConst{nodep->fileline(), randMode.index}};
|
||||
VCMethod::ARRAY_AT, new AstConst{nodep->fileline(), randMode.index}};
|
||||
atp->dtypeSetUInt32();
|
||||
exprp = new AstCond{varp->fileline(), atp, exprp, constFormatp};
|
||||
} else {
|
||||
|
|
@ -675,7 +676,7 @@ class ConstraintExprVisitor final : public VNVisitor {
|
|||
varp->fileline(),
|
||||
new AstVarRef{varp->fileline(), VN_AS(m_genp->user2p(), NodeModule), m_genp,
|
||||
VAccess::READWRITE},
|
||||
"write_var"};
|
||||
VCMethod::RANDOMIZER_WRITE_VAR};
|
||||
uint32_t dimension = 0;
|
||||
if (VN_IS(varp->dtypep(), UnpackArrayDType) || VN_IS(varp->dtypep(), DynArrayDType)
|
||||
|| VN_IS(varp->dtypep(), QueueDType) || VN_IS(varp->dtypep(), AssocArrayDType)) {
|
||||
|
|
@ -991,7 +992,7 @@ class ConstraintExprVisitor final : public VNVisitor {
|
|||
nodep->fileline(),
|
||||
new AstVarRef{nodep->fileline(), VN_AS(m_genp->user2p(), NodeModule), m_genp,
|
||||
VAccess::READWRITE},
|
||||
"hard", nodep->exprp()->unlinkFrBack()};
|
||||
VCMethod::RANDOMIZER_HARD, nodep->exprp()->unlinkFrBack()};
|
||||
callp->dtypeSetVoid();
|
||||
nodep->replaceWith(callp->makeStmt());
|
||||
VL_DO_DANGLING(nodep->deleteTree(), nodep);
|
||||
|
|
@ -1000,7 +1001,7 @@ class ConstraintExprVisitor final : public VNVisitor {
|
|||
if (editFormat(nodep)) return;
|
||||
FileLine* const fl = nodep->fileline();
|
||||
|
||||
if (nodep->name() == "at" && nodep->fromp()->user1()) {
|
||||
if (nodep->method() == VCMethod::ARRAY_AT && nodep->fromp()->user1()) {
|
||||
iterateChildren(nodep);
|
||||
AstNodeExpr* pinp = nodep->pinsp()->unlinkFrBack();
|
||||
if (VN_IS(pinp, SFormatF) && m_structSel) VN_AS(pinp, SFormatF)->name("%x");
|
||||
|
|
@ -1015,7 +1016,7 @@ class ConstraintExprVisitor final : public VNVisitor {
|
|||
return;
|
||||
}
|
||||
|
||||
if (nodep->name() == "inside") {
|
||||
if (nodep->method() == VCMethod::ARRAY_INSIDE) {
|
||||
bool randArr = nodep->fromp()->user1();
|
||||
|
||||
AstVar* const newVarp
|
||||
|
|
@ -1455,7 +1456,7 @@ class RandomizeVisitor final : public VNVisitor {
|
|||
FileLine* const fl = ftaskp->fileline();
|
||||
AstCMethodHard* const setRandModep = new AstCMethodHard{
|
||||
fl, new AstVarRef{fl, VN_AS(genp->user2p(), NodeModule), genp, VAccess::WRITE},
|
||||
"set_randmode",
|
||||
VCMethod::CLASS_SET_RANDMODE,
|
||||
new AstVarRef{fl, VN_AS(randModeVarp->user2p(), NodeModule), randModeVarp,
|
||||
VAccess::READ}};
|
||||
setRandModep->dtypeSetVoid();
|
||||
|
|
@ -1506,7 +1507,7 @@ class RandomizeVisitor final : public VNVisitor {
|
|||
FileLine* fl = modeVarp->fileline();
|
||||
AstCMethodHard* const dynarrayNewp
|
||||
= new AstCMethodHard{fl, new AstVarRef{fl, modeVarModp, modeVarp, VAccess::WRITE},
|
||||
"resize", new AstConst{fl, modeCount}};
|
||||
VCMethod::DYN_RESIZE, new AstConst{fl, modeCount}};
|
||||
dynarrayNewp->dtypeSetVoid();
|
||||
AstNodeFTask* const newp = VN_AS(m_memberMap.findMember(classp, "new"), NodeFTask);
|
||||
UASSERT_OBJ(newp, classp, "No new() in class");
|
||||
|
|
@ -1520,10 +1521,11 @@ class RandomizeVisitor final : public VNVisitor {
|
|||
AstVar* const iterVarp = new AstVar{fl, VVarType::BLOCKTEMP, "i", lhsp->findUInt32DType()};
|
||||
iterVarp->funcLocal(inTask);
|
||||
iterVarp->lifetime(VLifetime::AUTOMATIC_EXPLICIT);
|
||||
AstCMethodHard* const sizep = new AstCMethodHard{fl, lhsp, "size", nullptr};
|
||||
AstCMethodHard* const sizep = new AstCMethodHard{fl, lhsp, VCMethod::DYN_SIZE, nullptr};
|
||||
sizep->dtypeSetUInt32();
|
||||
AstCMethodHard* const setp = new AstCMethodHard{
|
||||
fl, lhsp->cloneTree(false), "atWrite", new AstVarRef{fl, iterVarp, VAccess::READ}};
|
||||
AstCMethodHard* const setp
|
||||
= new AstCMethodHard{fl, lhsp->cloneTree(false), VCMethod::ARRAY_AT_WRITE,
|
||||
new AstVarRef{fl, iterVarp, VAccess::READ}};
|
||||
setp->dtypeSetUInt32();
|
||||
AstNode* const stmtsp = iterVarp;
|
||||
stmtsp->addNext(
|
||||
|
|
@ -1550,7 +1552,7 @@ class RandomizeVisitor final : public VNVisitor {
|
|||
if (mode.usesMode) {
|
||||
AstCMethodHard* const atp = new AstCMethodHard{
|
||||
fl, new AstVarRef{fl, VN_AS(modeVarp->user2p(), Class), modeVarp, VAccess::READ},
|
||||
"at", new AstConst{fl, mode.index}};
|
||||
VCMethod::ARRAY_AT, new AstConst{fl, mode.index}};
|
||||
atp->dtypeSetUInt32();
|
||||
return new AstIf{fl, atp, stmtp};
|
||||
}
|
||||
|
|
@ -1651,7 +1653,8 @@ class RandomizeVisitor final : public VNVisitor {
|
|||
AstNodeExpr* const tempExprp = tempElementp ? tempElementp : exprp;
|
||||
AstVarRef* const tempRefp = new AstVarRef{fl, newRandLoopIndxp, VAccess::READ};
|
||||
if (VN_IS(tempDTypep, DynArrayDType)) {
|
||||
tempElementp = new AstCMethodHard{fl, tempExprp, "atWrite", tempRefp};
|
||||
tempElementp
|
||||
= new AstCMethodHard{fl, tempExprp, VCMethod::ARRAY_AT_WRITE, tempRefp};
|
||||
} else if (VN_IS(tempDTypep, UnpackArrayDType)) {
|
||||
AstNodeArrayDType* const aryDTypep = VN_CAST(tempDTypep, NodeArrayDType);
|
||||
// Adjust the bitp to ensure it covers all possible indices
|
||||
|
|
@ -1665,7 +1668,8 @@ class RandomizeVisitor final : public VNVisitor {
|
|||
} else if (VN_IS(tempDTypep, AssocArrayDType)) {
|
||||
tempElementp = new AstAssocSel{fl, tempExprp, tempRefp};
|
||||
} else if (VN_IS(tempDTypep, QueueDType)) {
|
||||
tempElementp = new AstCMethodHard{fl, tempExprp, "atWriteAppend", tempRefp};
|
||||
tempElementp
|
||||
= new AstCMethodHard{fl, tempExprp, VCMethod::DYN_AT_WRITE_APPEND, tempRefp};
|
||||
}
|
||||
tempElementp->dtypep(tempDTypep->subDTypep());
|
||||
tempDTypep = tempDTypep->virtRefDTypep();
|
||||
|
|
@ -1797,7 +1801,7 @@ class RandomizeVisitor final : public VNVisitor {
|
|||
AstCMethodHard* const clearp = new AstCMethodHard{
|
||||
fileline,
|
||||
new AstVarRef{fileline, VN_AS(genp->user2p(), NodeModule), genp, VAccess::READWRITE},
|
||||
"clear"};
|
||||
VCMethod::RANDOMIZER_CLEAR};
|
||||
clearp->dtypeSetVoid();
|
||||
return clearp->makeStmt();
|
||||
}
|
||||
|
|
@ -1909,7 +1913,7 @@ class RandomizeVisitor final : public VNVisitor {
|
|||
nodep->fileline(),
|
||||
new AstVarRef{fl, VN_AS(randModeVarp->user2p(), NodeModule), randModeVarp,
|
||||
VAccess::WRITE},
|
||||
"atWrite", new AstConst{nodep->fileline(), randMode.index}};
|
||||
VCMethod::ARRAY_AT_WRITE, new AstConst{nodep->fileline(), randMode.index}};
|
||||
setp->dtypeSetUInt32();
|
||||
newp->addStmtsp(new AstAssign{fl, setp, new AstConst{fl, 0}});
|
||||
}
|
||||
|
|
@ -1973,8 +1977,8 @@ class RandomizeVisitor final : public VNVisitor {
|
|||
// mode
|
||||
const RandomizeMode rmode = {.asInt = receiverp->user1()};
|
||||
UASSERT_OBJ(rmode.usesMode, ftaskRefp, "Failed to set usesMode");
|
||||
AstCMethodHard* const setp
|
||||
= new AstCMethodHard{fl, lhsp, "atWrite", new AstConst{fl, rmode.index}};
|
||||
AstCMethodHard* const setp = new AstCMethodHard{fl, lhsp, VCMethod::ARRAY_AT_WRITE,
|
||||
new AstConst{fl, rmode.index}};
|
||||
setp->dtypeSetUInt32();
|
||||
m_stmtp->replaceWith(new AstAssign{fl, setp, rhsp});
|
||||
} else {
|
||||
|
|
@ -1988,8 +1992,8 @@ class RandomizeVisitor final : public VNVisitor {
|
|||
UASSERT_OBJ(receiverp, ftaskRefp, "Should have receiver");
|
||||
const RandomizeMode rmode = {.asInt = receiverp->user1()};
|
||||
UASSERT_OBJ(rmode.usesMode, ftaskRefp, "Failed to set usesMode");
|
||||
AstCMethodHard* const setp
|
||||
= new AstCMethodHard{fl, lhsp, "atWrite", new AstConst{fl, rmode.index}};
|
||||
AstCMethodHard* const setp = new AstCMethodHard{fl, lhsp, VCMethod::ARRAY_AT_WRITE,
|
||||
new AstConst{fl, rmode.index}};
|
||||
setp->dtypeSetUInt32();
|
||||
ftaskRefp->replaceWith(setp);
|
||||
VL_DO_DANGLING(pushDeletep(ftaskRefp), ftaskRefp);
|
||||
|
|
@ -2057,9 +2061,9 @@ class RandomizeVisitor final : public VNVisitor {
|
|||
tmpVarps = AstNode::addNext(tmpVarps, randModeTmpVarp);
|
||||
}
|
||||
const RandomizeMode randMode = {.asInt = randVarp->user1()};
|
||||
AstCMethodHard* setp
|
||||
= new AstCMethodHard{fl, makeSiblingRefp(exprp, randModeVarp, VAccess::WRITE),
|
||||
"atWrite", new AstConst{fl, randMode.index}};
|
||||
AstCMethodHard* setp = new AstCMethodHard{
|
||||
fl, makeSiblingRefp(exprp, randModeVarp, VAccess::WRITE),
|
||||
VCMethod::ARRAY_AT_WRITE, new AstConst{fl, randMode.index}};
|
||||
setp->dtypeSetUInt32();
|
||||
setStmtsp
|
||||
= AstNode::addNext(setStmtsp, new AstAssign{fl, setp, new AstConst{fl, 1}});
|
||||
|
|
@ -2306,7 +2310,7 @@ class RandomizeVisitor final : public VNVisitor {
|
|||
AstCMethodHard* const basicMethodp = new AstCMethodHard{
|
||||
nodep->fileline(),
|
||||
new AstVarRef{nodep->fileline(), stdrand, VAccess::READWRITE},
|
||||
"basicStdRandomization"};
|
||||
VCMethod::RANDOMIZER_BASIC_STD_RANDOMIZATION};
|
||||
AstVar* const refvarp
|
||||
= new AstVar{exprp->fileline(), VVarType::MEMBER,
|
||||
"__Varg"s + std::to_string(++argn), exprp->dtypep()};
|
||||
|
|
@ -2456,7 +2460,9 @@ class RandomizeVisitor final : public VNVisitor {
|
|||
void visit(AstCMethodHard* nodep) override {
|
||||
iterateChildren(nodep);
|
||||
FileLine* const fl = nodep->fileline();
|
||||
if (m_constraintp && nodep->fromp()->user1() && nodep->name() == "size") {
|
||||
if (m_constraintp && nodep->fromp()->user1()
|
||||
&& (nodep->method() == VCMethod::ASSOC_SIZE
|
||||
|| nodep->method() == VCMethod::DYN_SIZE)) {
|
||||
AstClass* const classp = VN_AS(m_modp, Class);
|
||||
AstVarRef* const queueVarRefp = VN_CAST(nodep->fromp(), VarRef);
|
||||
if (!queueVarRefp) {
|
||||
|
|
@ -2480,7 +2486,7 @@ class RandomizeVisitor final : public VNVisitor {
|
|||
m_constraintp->user3p(resizerTaskp);
|
||||
}
|
||||
AstCMethodHard* const resizep
|
||||
= new AstCMethodHard{fl, nodep->fromp()->unlinkFrBack(), "resize",
|
||||
= new AstCMethodHard{fl, nodep->fromp()->unlinkFrBack(), VCMethod::DYN_RESIZE,
|
||||
new AstVarRef{fl, sizeVarp, VAccess::READ}};
|
||||
resizep->dtypep(nodep->findVoidDType());
|
||||
resizerTaskp->addStmtsp(new AstStmtExpr{fl, resizep});
|
||||
|
|
|
|||
|
|
@ -221,8 +221,8 @@ EvalLoop createEvalLoop(
|
|||
phaseFuncp->addStmtsp(phasePrepp);
|
||||
|
||||
// Check if any triggers are fired, save the result
|
||||
AstCMethodHard* const callp
|
||||
= new AstCMethodHard{flp, new AstVarRef{flp, trigp, VAccess::READ}, "any"};
|
||||
AstCMethodHard* const callp = new AstCMethodHard{
|
||||
flp, new AstVarRef{flp, trigp, VAccess::READ}, VCMethod::TRIGGER_ANY};
|
||||
callp->dtypeSetBit();
|
||||
phaseFuncp->addStmtsp(
|
||||
new AstAssign{flp, new AstVarRef{flp, executeFlagp, VAccess::WRITE}, callp});
|
||||
|
|
@ -523,7 +523,7 @@ struct TriggerKit final {
|
|||
void addFirstIterationTriggerAssignment(AstVarScope* flagp, uint32_t index) const {
|
||||
FileLine* const flp = flagp->fileline();
|
||||
AstVarRef* const vrefp = new AstVarRef{flp, m_vscp, VAccess::WRITE};
|
||||
AstCMethodHard* const callp = new AstCMethodHard{flp, vrefp, "setBit"};
|
||||
AstCMethodHard* const callp = new AstCMethodHard{flp, vrefp, VCMethod::TRIGGER_SET_BIT};
|
||||
callp->addPinsp(new AstConst{flp, index});
|
||||
callp->addPinsp(new AstVarRef{flp, flagp, VAccess::READ});
|
||||
callp->dtypeSetVoid();
|
||||
|
|
@ -534,7 +534,7 @@ struct TriggerKit final {
|
|||
void addExtraTriggerAssignment(AstVarScope* extraTriggerVscp, uint32_t index) const {
|
||||
FileLine* const flp = extraTriggerVscp->fileline();
|
||||
AstVarRef* const vrefp = new AstVarRef{flp, m_vscp, VAccess::WRITE};
|
||||
AstCMethodHard* const callp = new AstCMethodHard{flp, vrefp, "setBit"};
|
||||
AstCMethodHard* const callp = new AstCMethodHard{flp, vrefp, VCMethod::TRIGGER_SET_BIT};
|
||||
callp->addPinsp(new AstConst{flp, index});
|
||||
callp->addPinsp(new AstVarRef{flp, extraTriggerVscp, VAccess::READ});
|
||||
callp->dtypeSetVoid();
|
||||
|
|
@ -570,7 +570,7 @@ AstSenTree* createTriggerSenTree(AstNetlist* netlistp, AstVarScope* const vscp,
|
|||
const uint32_t wordIndex = index / 64;
|
||||
const uint32_t bitIndex = index % 64;
|
||||
AstCMethodHard* const callp
|
||||
= new AstCMethodHard{flp, vrefp, "word", new AstConst{flp, wordIndex}};
|
||||
= new AstCMethodHard{flp, vrefp, VCMethod::TRIGGER_WORD, new AstConst{flp, wordIndex}};
|
||||
callp->dtypeSetUInt64();
|
||||
AstNodeExpr* const termp
|
||||
= new AstAnd{flp, new AstConst{flp, AstConst::Unsized64{}, 1ULL << bitIndex}, callp};
|
||||
|
|
@ -663,8 +663,8 @@ const TriggerKit createTriggers(AstNetlist* netlistp, AstCFunc* const initFuncp,
|
|||
|
||||
// Add a print to the dumping function if there are no triggers pending
|
||||
{
|
||||
AstCMethodHard* const callp
|
||||
= new AstCMethodHard{flp, new AstVarRef{flp, vscp, VAccess::READ}, "any"};
|
||||
AstCMethodHard* const callp = new AstCMethodHard{
|
||||
flp, new AstVarRef{flp, vscp, VAccess::READ}, VCMethod::TRIGGER_ANY};
|
||||
callp->dtypeSetBit();
|
||||
AstIf* const ifp = new AstIf{flp, callp};
|
||||
dumpp->addStmtsp(ifp);
|
||||
|
|
@ -674,7 +674,7 @@ const TriggerKit createTriggers(AstNetlist* netlistp, AstCFunc* const initFuncp,
|
|||
// Set the given trigger to the given value
|
||||
const auto setTrigBit = [&](uint32_t index, AstNodeExpr* valp) {
|
||||
AstVarRef* const vrefp = new AstVarRef{flp, vscp, VAccess::WRITE};
|
||||
AstCMethodHard* const callp = new AstCMethodHard{flp, vrefp, "setBit"};
|
||||
AstCMethodHard* const callp = new AstCMethodHard{flp, vrefp, VCMethod::TRIGGER_SET_BIT};
|
||||
callp->addPinsp(new AstConst{flp, index});
|
||||
callp->addPinsp(valp);
|
||||
callp->dtypeSetVoid();
|
||||
|
|
@ -687,7 +687,7 @@ const TriggerKit createTriggers(AstNetlist* netlistp, AstCFunc* const initFuncp,
|
|||
const uint32_t wordIndex = index / 64;
|
||||
const uint32_t bitIndex = index % 64;
|
||||
AstCMethodHard* const callp
|
||||
= new AstCMethodHard{flp, vrefp, "word", new AstConst{flp, wordIndex}};
|
||||
= new AstCMethodHard{flp, vrefp, VCMethod::TRIGGER_WORD, new AstConst{flp, wordIndex}};
|
||||
callp->dtypeSetUInt64();
|
||||
AstNodeExpr* const termp
|
||||
= new AstAnd{flp, new AstConst{flp, AstConst::Unsized64{}, 1ULL << bitIndex}, callp};
|
||||
|
|
@ -776,7 +776,8 @@ const TriggerKit createTriggers(AstNetlist* netlistp, AstCFunc* const initFuncp,
|
|||
}
|
||||
// Set the whole word in the trigger vector
|
||||
AstVarRef* const vrefp = new AstVarRef{flp, vscp, VAccess::WRITE};
|
||||
AstCMethodHard* const callp = new AstCMethodHard{flp, vrefp, "setWord"};
|
||||
AstCMethodHard* const callp
|
||||
= new AstCMethodHard{flp, vrefp, VCMethod::TRIGGER_SET_WORD};
|
||||
callp->addPinsp(new AstConst{flp, triggerBitIdx / TRIG_VEC_WORD_SIZE});
|
||||
callp->addPinsp(trigExprps[0]);
|
||||
callp->dtypeSetVoid();
|
||||
|
|
@ -1015,7 +1016,7 @@ AstNode* createInputCombLoop(AstNetlist* netlistp, AstCFunc* const initFuncp,
|
|||
|
||||
AstStmtExpr* createTriggerClearCall(FileLine* const flp, AstVarScope* const vscp) { // Trigger
|
||||
AstVarRef* const refp = new AstVarRef{flp, vscp, VAccess::WRITE};
|
||||
AstCMethodHard* const callp = new AstCMethodHard{flp, refp, "clear"};
|
||||
AstCMethodHard* const callp = new AstCMethodHard{flp, refp, VCMethod::TRIGGER_CLEAR};
|
||||
callp->dtypeSetVoid();
|
||||
return callp->makeStmt();
|
||||
}
|
||||
|
|
@ -1024,7 +1025,7 @@ AstStmtExpr* createTriggerSetCall(FileLine* const flp, AstVarScope* const toVscp
|
|||
AstVarScope* const fromVscp) {
|
||||
AstVarRef* const lhsp = new AstVarRef{flp, toVscp, VAccess::WRITE};
|
||||
AstVarRef* const argp = new AstVarRef{flp, fromVscp, VAccess::READ};
|
||||
AstCMethodHard* const callp = new AstCMethodHard{flp, lhsp, "thisOr", argp};
|
||||
AstCMethodHard* const callp = new AstCMethodHard{flp, lhsp, VCMethod::TRIGGER_THIS_OR, argp};
|
||||
callp->dtypeSetVoid();
|
||||
return callp->makeStmt();
|
||||
}
|
||||
|
|
@ -1035,7 +1036,7 @@ AstStmtExpr* createTriggerAndNotCall(FileLine* const flp, AstVarScope* const lhs
|
|||
AstVarRef* const opap = new AstVarRef{flp, aVscp, VAccess::READ};
|
||||
AstVarRef* const opbp = new AstVarRef{flp, bVscp, VAccess::READ};
|
||||
opap->addNext(opbp);
|
||||
AstCMethodHard* const callp = new AstCMethodHard{flp, lhsp, "andNot", opap};
|
||||
AstCMethodHard* const callp = new AstCMethodHard{flp, lhsp, VCMethod::TRIGGER_AND_NOT, opap};
|
||||
callp->dtypeSetVoid();
|
||||
return callp->makeStmt();
|
||||
}
|
||||
|
|
@ -1125,8 +1126,8 @@ void createEval(AstNetlist* netlistp, //
|
|||
AstIf* const ifp = new AstIf{flp, new AstVarRef{flp, nbaEventTriggerp, VAccess::READ}};
|
||||
ifp->addThensp(setVar(continuep, 1));
|
||||
ifp->addThensp(setVar(nbaEventTriggerp, 0));
|
||||
AstCMethodHard* const firep
|
||||
= new AstCMethodHard{flp, new AstVarRef{flp, nbaEventp, VAccess::WRITE}, "fire"};
|
||||
AstCMethodHard* const firep = new AstCMethodHard{
|
||||
flp, new AstVarRef{flp, nbaEventp, VAccess::WRITE}, VCMethod::EVENT_FIRE};
|
||||
firep->dtypeSetVoid();
|
||||
ifp->addThensp(firep->makeStmt());
|
||||
return ifp;
|
||||
|
|
|
|||
|
|
@ -126,7 +126,7 @@ AstCCall* TimingKit::createCommit(AstNetlist* const netlistp) {
|
|||
auto* const newactp = new AstActive{flp, "", negSentreep};
|
||||
// Create the commit call and put it in the commit function
|
||||
auto* const commitp = new AstCMethodHard{
|
||||
flp, new AstVarRef{flp, schedulerp, VAccess::READWRITE}, "commit"};
|
||||
flp, new AstVarRef{flp, schedulerp, VAccess::READWRITE}, VCMethod::SCHED_COMMIT};
|
||||
if (resumep->pinsp()) commitp->addPinsp(resumep->pinsp()->cloneTree(false));
|
||||
commitp->dtypeSetVoid();
|
||||
newactp->addStmtsp(commitp->makeStmt());
|
||||
|
|
@ -184,7 +184,7 @@ TimingKit prepareTiming(AstNetlist* const netlistp) {
|
|||
FileLine* const flp = sentreep->fileline();
|
||||
// Create a resume() call on the timing scheduler
|
||||
auto* const resumep = new AstCMethodHard{
|
||||
flp, new AstVarRef{flp, schedulerp, VAccess::READWRITE}, "resume"};
|
||||
flp, new AstVarRef{flp, schedulerp, VAccess::READWRITE}, VCMethod::SCHED_RESUME};
|
||||
resumep->dtypeSetVoid();
|
||||
if (schedulerp->dtypep()->basicp()->isTriggerScheduler()) {
|
||||
UASSERT_OBJ(methodp->pinsp(), methodp,
|
||||
|
|
@ -197,7 +197,7 @@ TimingKit prepareTiming(AstNetlist* const netlistp) {
|
|||
}
|
||||
} else if (schedulerp->dtypep()->basicp()->isDynamicTriggerScheduler()) {
|
||||
auto* const postp = resumep->cloneTree(false);
|
||||
postp->name("doPostUpdates");
|
||||
postp->method(VCMethod::SCHED_DO_POST_UPDATES);
|
||||
m_postUpdatesr = AstNode::addNext(m_postUpdatesr, postp->makeStmt());
|
||||
}
|
||||
// Put it in an active and put that in the global resume function
|
||||
|
|
|
|||
|
|
@ -133,7 +133,8 @@ private:
|
|||
}
|
||||
|
||||
if (VN_IS(exprp->dtypep()->skipRefp(), UnpackArrayDType)) {
|
||||
AstCMethodHard* const cmhp = new AstCMethodHard{flp, wrPrev(), "assign", rdCurr()};
|
||||
AstCMethodHard* const cmhp
|
||||
= new AstCMethodHard{flp, wrPrev(), VCMethod::UNPACKED_ASSIGN, rdCurr()};
|
||||
cmhp->dtypeSetVoid();
|
||||
m_results.m_postUpdates.push_back(cmhp->makeStmt());
|
||||
} else {
|
||||
|
|
@ -160,7 +161,8 @@ private:
|
|||
if (VN_IS(senp->dtypep()->skipRefp(), UnpackArrayDType)) {
|
||||
// operand order reversed to avoid calling neq() method on non-VlUnpacked type, see
|
||||
// issue #5125
|
||||
AstCMethodHard* const resultp = new AstCMethodHard{flp, prevp(), "neq", currp()};
|
||||
AstCMethodHard* const resultp
|
||||
= new AstCMethodHard{flp, prevp(), VCMethod::UNPACKED_NEQ, currp()};
|
||||
resultp->dtypeSetBit();
|
||||
return {resultp, true};
|
||||
}
|
||||
|
|
@ -176,13 +178,15 @@ private:
|
|||
{
|
||||
// Clear 'fired' state when done
|
||||
// No need to check if the event was fired, we need the flag clear regardless
|
||||
AstCMethodHard* const clearp = new AstCMethodHard{flp, currp(), "clearFired"};
|
||||
AstCMethodHard* const clearp
|
||||
= new AstCMethodHard{flp, currp(), VCMethod::EVENT_CLEAR_FIRED};
|
||||
clearp->dtypeSetVoid();
|
||||
m_results.m_postUpdates.push_back(clearp->makeStmt());
|
||||
}
|
||||
|
||||
// Get 'fired' state
|
||||
AstCMethodHard* const callp = new AstCMethodHard{flp, currp(), "isFired"};
|
||||
AstCMethodHard* const callp
|
||||
= new AstCMethodHard{flp, currp(), VCMethod::EVENT_IS_FIRED};
|
||||
callp->dtypeSetBit();
|
||||
return {callp, false};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -506,10 +506,11 @@ class TaskVisitor final : public VNVisitor {
|
|||
refArgOk = true;
|
||||
} else if (AstCMethodHard* const cMethodp = VN_CAST(pinp, CMethodHard)) {
|
||||
if (VN_IS(cMethodp->fromp()->dtypep()->skipRefp(), QueueDType)) {
|
||||
refArgOk = cMethodp->name() == "atWriteAppend"
|
||||
|| cMethodp->name() == "atWriteAppendBack";
|
||||
refArgOk = cMethodp->method() == VCMethod::DYN_AT_WRITE_APPEND
|
||||
|| cMethodp->method() == VCMethod::DYN_AT_WRITE_APPEND_BACK;
|
||||
} else {
|
||||
refArgOk = cMethodp->name() == "at" || cMethodp->name() == "atBack";
|
||||
refArgOk = cMethodp->method() == VCMethod::ARRAY_AT
|
||||
|| cMethodp->method() == VCMethod::ARRAY_AT_BACK;
|
||||
}
|
||||
}
|
||||
if (refArgOk) {
|
||||
|
|
|
|||
|
|
@ -543,7 +543,7 @@ class TimingControlVisitor final : public VNVisitor {
|
|||
FileLine* const flp = m_scopeTopp->fileline();
|
||||
auto* const awaitingCurrentTimep
|
||||
= new AstCMethodHard{flp, new AstVarRef{flp, getCreateDelayScheduler(), VAccess::READ},
|
||||
"awaitingCurrentTime"};
|
||||
VCMethod::SCHED_AWAITING_CURRENT_TIME};
|
||||
awaitingCurrentTimep->dtypeSetBit();
|
||||
m_delaySensesp
|
||||
= new AstSenTree{flp, new AstSenItem{flp, VEdgeType::ET_TRUE, awaitingCurrentTimep}};
|
||||
|
|
@ -566,7 +566,7 @@ class TimingControlVisitor final : public VNVisitor {
|
|||
FileLine* const flp = m_scopeTopp->fileline();
|
||||
auto* const awaitingCurrentTimep = new AstCMethodHard{
|
||||
flp, new AstVarRef{flp, getCreateDynamicTriggerScheduler(), VAccess::READ},
|
||||
"evaluate"};
|
||||
VCMethod::SCHED_EVALUATE};
|
||||
awaitingCurrentTimep->dtypeSetBit();
|
||||
m_dynamicSensesp
|
||||
= new AstSenTree{flp, new AstSenItem{flp, VEdgeType::ET_TRUE, awaitingCurrentTimep}};
|
||||
|
|
@ -712,7 +712,7 @@ class TimingControlVisitor final : public VNVisitor {
|
|||
void addForkDone(AstBegin* const beginp, AstVarScope* const forkVscp) const {
|
||||
FileLine* const flp = beginp->fileline();
|
||||
auto* const donep = new AstCMethodHard{
|
||||
beginp->fileline(), new AstVarRef{flp, forkVscp, VAccess::WRITE}, "done"};
|
||||
beginp->fileline(), new AstVarRef{flp, forkVscp, VAccess::WRITE}, VCMethod::FORK_DONE};
|
||||
donep->dtypeSetVoid();
|
||||
addDebugInfo(donep);
|
||||
beginp->addStmtsp(donep->makeStmt());
|
||||
|
|
@ -735,13 +735,13 @@ class TimingControlVisitor final : public VNVisitor {
|
|||
if (forkp->joinType().joinAny()) joinCount = 1;
|
||||
// Set the join counter
|
||||
auto* const initp = new AstCMethodHard{flp, new AstVarRef{flp, forkVscp, VAccess::WRITE},
|
||||
"init", new AstConst{flp, joinCount}};
|
||||
VCMethod::FORK_INIT, new AstConst{flp, joinCount}};
|
||||
initp->dtypeSetVoid();
|
||||
addProcessInfo(initp);
|
||||
forkp->addHereThisAsNext(initp->makeStmt());
|
||||
// Await the join at the end
|
||||
auto* const joinp
|
||||
= new AstCMethodHard{flp, new AstVarRef{flp, forkVscp, VAccess::WRITE}, "join"};
|
||||
auto* const joinp = new AstCMethodHard{flp, new AstVarRef{flp, forkVscp, VAccess::WRITE},
|
||||
VCMethod::FORK_JOIN};
|
||||
joinp->dtypeSetVoid();
|
||||
addProcessInfo(joinp);
|
||||
addDebugInfo(joinp);
|
||||
|
|
@ -884,7 +884,8 @@ class TimingControlVisitor final : public VNVisitor {
|
|||
}
|
||||
// Replace self with a 'co_await dlySched.delay(<valuep>)'
|
||||
AstCMethodHard* const delayMethodp = new AstCMethodHard{
|
||||
flp, new AstVarRef{flp, getCreateDelayScheduler(), VAccess::WRITE}, "delay", valuep};
|
||||
flp, new AstVarRef{flp, getCreateDelayScheduler(), VAccess::WRITE},
|
||||
VCMethod::SCHED_DELAY, valuep};
|
||||
delayMethodp->dtypeSetVoid();
|
||||
addProcessInfo(delayMethodp);
|
||||
addDebugInfo(delayMethodp);
|
||||
|
|
@ -922,7 +923,7 @@ class TimingControlVisitor final : public VNVisitor {
|
|||
// call
|
||||
auto* const evalMethodp = new AstCMethodHard{
|
||||
flp, new AstVarRef{flp, getCreateDynamicTriggerScheduler(), VAccess::WRITE},
|
||||
"evaluation"};
|
||||
VCMethod::SCHED_EVALUATION};
|
||||
evalMethodp->dtypeSetVoid();
|
||||
addProcessInfo(evalMethodp);
|
||||
auto* const sentreep = nodep->sentreep();
|
||||
|
|
@ -954,21 +955,21 @@ class TimingControlVisitor final : public VNVisitor {
|
|||
// If it was, a call to the scheduler's evaluate() will return true
|
||||
AstCMethodHard* const anyTriggeredMethodp = new AstCMethodHard{
|
||||
flp, new AstVarRef{flp, getCreateDynamicTriggerScheduler(), VAccess::WRITE},
|
||||
"anyTriggered", new AstVarRef{flp, trigvscp, VAccess::READ}};
|
||||
VCMethod::SCHED_ANY_TRIGGERED, new AstVarRef{flp, trigvscp, VAccess::READ}};
|
||||
anyTriggeredMethodp->dtypeSetVoid();
|
||||
loopp->addStmtsp(anyTriggeredMethodp->makeStmt());
|
||||
// If the post update is destructive (e.g. event vars are cleared), create an await for
|
||||
// the post update step
|
||||
if (destructivePostUpdate(sentreep)) {
|
||||
AstCAwait* const awaitPostUpdatep = awaitEvalp->cloneTree(false);
|
||||
VN_AS(awaitPostUpdatep->exprp(), CMethodHard)->name("postUpdate");
|
||||
VN_AS(awaitPostUpdatep->exprp(), CMethodHard)->method(VCMethod::SCHED_POST_UPDATE);
|
||||
loopp->addStmtsp(awaitPostUpdatep->makeStmt());
|
||||
}
|
||||
// Put the post updates at the end of the loop
|
||||
for (AstNodeStmt* const stmtp : senResults.m_postUpdates) loopp->addStmtsp(stmtp);
|
||||
// Finally, await the resumption step in 'act'
|
||||
AstCAwait* const awaitResumep = awaitEvalp->cloneTree(false);
|
||||
VN_AS(awaitResumep->exprp(), CMethodHard)->name("resumption");
|
||||
VN_AS(awaitResumep->exprp(), CMethodHard)->method(VCMethod::SCHED_RESUMPTION);
|
||||
AstNode::addNext<AstNodeStmt, AstNodeStmt>(loopp, awaitResumep->makeStmt());
|
||||
// Replace the event control with the loop
|
||||
nodep->replaceWith(loopp);
|
||||
|
|
@ -979,7 +980,7 @@ class TimingControlVisitor final : public VNVisitor {
|
|||
// Replace self with a 'co_await trigSched.trigger()'
|
||||
auto* const triggerMethodp = new AstCMethodHard{
|
||||
flp, new AstVarRef{flp, getCreateTriggerSchedulerp(sentreep), VAccess::WRITE},
|
||||
"trigger"};
|
||||
VCMethod::SCHED_TRIGGER};
|
||||
triggerMethodp->dtypeSetVoid();
|
||||
// If it should be committed immediately, pass true, otherwise false
|
||||
triggerMethodp->addPinsp(nodep->user2() ? new AstConst{flp, AstConst::BitTrue{}}
|
||||
|
|
|
|||
138
src/V3Width.cpp
138
src/V3Width.cpp
|
|
@ -1800,7 +1800,8 @@ class WidthVisitor final : public VNVisitor {
|
|||
switch (nodep->attrType()) {
|
||||
case VAttrType::DIM_SIZE: {
|
||||
AstNodeExpr* const fromp = VN_AS(nodep->fromp()->unlinkFrBack(), NodeExpr);
|
||||
AstNode* const newp = new AstCMethodHard{nodep->fileline(), fromp, "size"};
|
||||
AstNode* const newp
|
||||
= new AstCMethodHard{nodep->fileline(), fromp, VCMethod::DYN_SIZE};
|
||||
newp->dtypeSetSigned32();
|
||||
newp->didWidth(true);
|
||||
newp->protect(false);
|
||||
|
|
@ -1819,7 +1820,7 @@ class WidthVisitor final : public VNVisitor {
|
|||
case VAttrType::DIM_HIGH: {
|
||||
AstNodeExpr* const fromp = VN_AS(nodep->fromp()->unlinkFrBack(), NodeExpr);
|
||||
AstNodeExpr* const sizep
|
||||
= new AstCMethodHard{nodep->fileline(), fromp, "size"};
|
||||
= new AstCMethodHard{nodep->fileline(), fromp, VCMethod::DYN_SIZE};
|
||||
sizep->dtypeSetSigned32();
|
||||
sizep->didWidth(true);
|
||||
sizep->protect(false);
|
||||
|
|
@ -3076,8 +3077,8 @@ class WidthVisitor final : public VNVisitor {
|
|||
|| VN_IS(itemDtp, QueueDType)) {
|
||||
// Unsupported in parameters
|
||||
AstNodeExpr* const cexprp = exprp->cloneTreePure(true);
|
||||
AstNodeExpr* const inewp
|
||||
= new AstCMethodHard{nodep->fileline(), itemp->unlinkFrBack(), "inside", cexprp};
|
||||
AstNodeExpr* const inewp = new AstCMethodHard{nodep->fileline(), itemp->unlinkFrBack(),
|
||||
VCMethod::ARRAY_INSIDE, cexprp};
|
||||
iterateCheckTyped(nodep, "inside value", cexprp, itemDtp->subDTypep(), BOTH);
|
||||
VL_DANGLING(cexprp); // Might have been replaced
|
||||
inewp->dtypeSetBit();
|
||||
|
|
@ -3708,7 +3709,7 @@ class WidthVisitor final : public VNVisitor {
|
|||
|| nodep->name() == "size") {
|
||||
methodOkArguments(nodep, 0, 0);
|
||||
newp = new AstCMethodHard{nodep->fileline(), nodep->fromp()->unlinkFrBack(),
|
||||
"size"}; // So don't need num()
|
||||
VCMethod::ASSOC_SIZE}; // So don't need num()
|
||||
newp->dtypeSetSigned32();
|
||||
} else if (nodep->name() == "first" // function int first(ref index)
|
||||
|| nodep->name() == "last" //
|
||||
|
|
@ -3724,21 +3725,21 @@ class WidthVisitor final : public VNVisitor {
|
|||
methodOkArguments(nodep, 1, 1);
|
||||
iterateCheckSelf(nodep, "argument", methodArg(nodep, 0), SELF, BOTH);
|
||||
AstNodeExpr* const index_exprp = methodCallWildcardIndexExpr(nodep, adtypep);
|
||||
newp = new AstCMethodHard{nodep->fileline(), nodep->fromp()->unlinkFrBack(), "exists",
|
||||
index_exprp->unlinkFrBack()};
|
||||
newp = new AstCMethodHard{nodep->fileline(), nodep->fromp()->unlinkFrBack(),
|
||||
VCMethod::ASSOC_EXISTS, index_exprp->unlinkFrBack()};
|
||||
newp->dtypeSetLogicUnsized(32, 1, VSigning::SIGNED);
|
||||
} else if (nodep->name() == "delete") { // function void delete([input integer index])
|
||||
methodOkArguments(nodep, 0, 1);
|
||||
methodCallLValueRecurse(nodep, nodep->fromp(), VAccess::WRITE);
|
||||
if (!nodep->pinsp()) {
|
||||
newp = new AstCMethodHard{nodep->fileline(), nodep->fromp()->unlinkFrBack(),
|
||||
"clear"};
|
||||
VCMethod::ASSOC_CLEAR};
|
||||
newp->dtypeSetVoid();
|
||||
} else {
|
||||
iterateCheckSelf(nodep, "argument", methodArg(nodep, 0), SELF, BOTH);
|
||||
AstNodeExpr* const index_exprp = methodCallWildcardIndexExpr(nodep, adtypep);
|
||||
newp = new AstCMethodHard{nodep->fileline(), nodep->fromp()->unlinkFrBack(),
|
||||
"erase", index_exprp->unlinkFrBack()};
|
||||
VCMethod::ASSOC_ERASE, index_exprp->unlinkFrBack()};
|
||||
newp->dtypeSetVoid();
|
||||
}
|
||||
} else if (nodep->name() == "sort" || nodep->name() == "rsort"
|
||||
|
|
@ -3754,14 +3755,14 @@ class WidthVisitor final : public VNVisitor {
|
|||
methodOkArguments(nodep, 0, 0);
|
||||
methodCallLValueRecurse(nodep, nodep->fromp(), VAccess::READ);
|
||||
newp = new AstCMethodHard{nodep->fileline(), nodep->fromp()->unlinkFrBack(),
|
||||
"r_" + nodep->name(), withp};
|
||||
VCMethod::arrayMethod("r_" + nodep->name()), withp};
|
||||
newp->dtypeFrom(withp ? withp->dtypep() : adtypep->subDTypep());
|
||||
if (!nodep->firstAbovep()) newp->dtypeSetVoid();
|
||||
} else if (nodep->name() == "min" || nodep->name() == "max" || nodep->name() == "unique") {
|
||||
methodOkArguments(nodep, 0, 0);
|
||||
methodCallLValueRecurse(nodep, nodep->fromp(), VAccess::READ);
|
||||
newp = new AstCMethodHard{nodep->fileline(), nodep->fromp()->unlinkFrBack(),
|
||||
nodep->name()};
|
||||
VCMethod::arrayMethod(nodep->name())};
|
||||
newp->dtypep(queueDTypeIndexedBy(adtypep->subDTypep()));
|
||||
if (!nodep->firstAbovep()) newp->dtypeSetVoid();
|
||||
} else if (nodep->name() == "find" || nodep->name() == "find_first"
|
||||
|
|
@ -3772,7 +3773,7 @@ class WidthVisitor final : public VNVisitor {
|
|||
methodOkArguments(nodep, 0, 0);
|
||||
methodCallLValueRecurse(nodep, nodep->fromp(), VAccess::READ);
|
||||
newp = new AstCMethodHard{nodep->fileline(), nodep->fromp()->unlinkFrBack(),
|
||||
nodep->name(), withp};
|
||||
VCMethod::arrayMethod(nodep->name()), withp};
|
||||
newp->dtypep(queueDTypeIndexedBy(adtypep->subDTypep()));
|
||||
if (!nodep->firstAbovep()) newp->dtypeSetVoid();
|
||||
} else if (nodep->name() == "map") {
|
||||
|
|
@ -3796,7 +3797,7 @@ class WidthVisitor final : public VNVisitor {
|
|||
|| nodep->name() == "size") {
|
||||
methodOkArguments(nodep, 0, 0);
|
||||
newp = new AstCMethodHard{nodep->fileline(), nodep->fromp()->unlinkFrBack(),
|
||||
"size"}; // So don't need num()
|
||||
VCMethod::ASSOC_SIZE}; // So don't need num()
|
||||
newp->dtypeSetSigned32();
|
||||
} else if (nodep->name() == "first" // function int first(ref index)
|
||||
|| nodep->name() == "last" //
|
||||
|
|
@ -3806,9 +3807,10 @@ class WidthVisitor final : public VNVisitor {
|
|||
iterateCheckTyped(nodep, "argument", methodArg(nodep, 0), adtypep->keyDTypep(), BOTH);
|
||||
AstNodeExpr* const index_exprp = methodCallAssocIndexExpr(nodep, adtypep);
|
||||
methodCallLValueRecurse(nodep, index_exprp, VAccess::READWRITE);
|
||||
newp = new AstCMethodHard{nodep->fileline(), nodep->fromp()->unlinkFrBack(),
|
||||
nodep->name(), // first/last/next/prev
|
||||
index_exprp->unlinkFrBack()};
|
||||
newp
|
||||
= new AstCMethodHard{nodep->fileline(), nodep->fromp()->unlinkFrBack(),
|
||||
VCMethod::arrayMethod(nodep->name()), // first/last/next/prev
|
||||
index_exprp->unlinkFrBack()};
|
||||
newp->dtypeSetSigned32();
|
||||
if (!nodep->firstAbovep()) newp->dtypeSetVoid();
|
||||
} else if (nodep->name() == "exists") { // function int exists(input index)
|
||||
|
|
@ -3816,22 +3818,22 @@ class WidthVisitor final : public VNVisitor {
|
|||
methodOkArguments(nodep, 1, 1);
|
||||
iterateCheckTyped(nodep, "argument", methodArg(nodep, 0), adtypep->keyDTypep(), BOTH);
|
||||
AstNodeExpr* const index_exprp = methodCallAssocIndexExpr(nodep, adtypep);
|
||||
newp = new AstCMethodHard{nodep->fileline(), nodep->fromp()->unlinkFrBack(), "exists",
|
||||
index_exprp->unlinkFrBack()};
|
||||
newp = new AstCMethodHard{nodep->fileline(), nodep->fromp()->unlinkFrBack(),
|
||||
VCMethod::ASSOC_EXISTS, index_exprp->unlinkFrBack()};
|
||||
newp->dtypeSetLogicUnsized(32, 1, VSigning::SIGNED);
|
||||
} else if (nodep->name() == "delete") { // function void delete([input integer index])
|
||||
methodOkArguments(nodep, 0, 1);
|
||||
methodCallLValueRecurse(nodep, nodep->fromp(), VAccess::WRITE);
|
||||
if (!nodep->pinsp()) {
|
||||
newp = new AstCMethodHard{nodep->fileline(), nodep->fromp()->unlinkFrBack(),
|
||||
"clear"};
|
||||
VCMethod::ASSOC_CLEAR};
|
||||
newp->dtypeSetVoid();
|
||||
} else {
|
||||
iterateCheckTyped(nodep, "argument", methodArg(nodep, 0), adtypep->keyDTypep(),
|
||||
BOTH);
|
||||
AstNodeExpr* const index_exprp = methodCallAssocIndexExpr(nodep, adtypep);
|
||||
newp = new AstCMethodHard{nodep->fileline(), nodep->fromp()->unlinkFrBack(),
|
||||
"erase", index_exprp->unlinkFrBack()};
|
||||
VCMethod::ASSOC_ERASE, index_exprp->unlinkFrBack()};
|
||||
newp->dtypeSetVoid();
|
||||
}
|
||||
} else if (nodep->name() == "sort" || nodep->name() == "rsort"
|
||||
|
|
@ -3846,7 +3848,7 @@ class WidthVisitor final : public VNVisitor {
|
|||
methodOkArguments(nodep, 0, 0);
|
||||
methodCallLValueRecurse(nodep, nodep->fromp(), VAccess::READ);
|
||||
newp = new AstCMethodHard{nodep->fileline(), nodep->fromp()->unlinkFrBack(),
|
||||
"r_" + nodep->name(), withp};
|
||||
VCMethod::arrayMethod("r_" + nodep->name()), withp};
|
||||
newp->dtypeFrom(withp ? withp->dtypep() : adtypep->subDTypep());
|
||||
if (!nodep->firstAbovep()) newp->dtypeSetVoid();
|
||||
} else if (nodep->name() == "min" || nodep->name() == "max" || nodep->name() == "unique"
|
||||
|
|
@ -3856,7 +3858,7 @@ class WidthVisitor final : public VNVisitor {
|
|||
methodOkArguments(nodep, 0, 0);
|
||||
methodCallLValueRecurse(nodep, nodep->fromp(), VAccess::READ);
|
||||
newp = new AstCMethodHard{nodep->fileline(), nodep->fromp()->unlinkFrBack(),
|
||||
nodep->name(), withp};
|
||||
VCMethod::arrayMethod(nodep->name()), withp};
|
||||
if (nodep->name() == "unique_index") {
|
||||
newp->dtypep(queueDTypeIndexedBy(adtypep->keyDTypep()));
|
||||
} else {
|
||||
|
|
@ -3870,7 +3872,7 @@ class WidthVisitor final : public VNVisitor {
|
|||
methodOkArguments(nodep, 0, 0);
|
||||
methodCallLValueRecurse(nodep, nodep->fromp(), VAccess::READ);
|
||||
newp = new AstCMethodHard{nodep->fileline(), nodep->fromp()->unlinkFrBack(),
|
||||
nodep->name(), withp};
|
||||
VCMethod::arrayMethod(nodep->name()), withp};
|
||||
newp->dtypep(queueDTypeIndexedBy(adtypep->subDTypep()));
|
||||
if (!nodep->firstAbovep()) newp->dtypeSetVoid();
|
||||
} else if (nodep->name() == "find_index" || nodep->name() == "find_first_index"
|
||||
|
|
@ -3880,7 +3882,7 @@ class WidthVisitor final : public VNVisitor {
|
|||
methodOkArguments(nodep, 0, 0);
|
||||
methodCallLValueRecurse(nodep, nodep->fromp(), VAccess::READ);
|
||||
newp = new AstCMethodHard{nodep->fileline(), nodep->fromp()->unlinkFrBack(),
|
||||
nodep->name(), withp};
|
||||
VCMethod::arrayMethod(nodep->name()), withp};
|
||||
newp->dtypep(queueDTypeIndexedBy(adtypep->keyDTypep()));
|
||||
if (!nodep->firstAbovep()) newp->dtypeSetVoid();
|
||||
} else if (nodep->name() == "map") {
|
||||
|
|
@ -3915,16 +3917,31 @@ class WidthVisitor final : public VNVisitor {
|
|||
}
|
||||
void methodCallLValueRecurse(AstMethodCall* nodep, AstNode* childp, const VAccess& access) {
|
||||
if (AstCMethodHard* const ichildp = VN_CAST(childp, CMethodHard)) {
|
||||
const std::string name = ichildp->name();
|
||||
if (name == "at" || name == "atWrite" || name == "atBack" || name == "atWriteAppend"
|
||||
|| name == "atWriteAppendBack") {
|
||||
bool methAt = false;
|
||||
bool methAtBack = false;
|
||||
bool methAtWrite = false;
|
||||
switch (ichildp->method()) {
|
||||
case VCMethod::ARRAY_AT: // FALLTHRU
|
||||
methAt = true;
|
||||
break;
|
||||
case VCMethod::ARRAY_AT_BACK: // FALLTHRU
|
||||
methAtBack = true;
|
||||
break;
|
||||
case VCMethod::ARRAY_AT_WRITE: // FALLTHRU
|
||||
case VCMethod::DYN_AT_WRITE_APPEND: // FALLTHRU
|
||||
case VCMethod::DYN_AT_WRITE_APPEND_BACK: //
|
||||
methAtWrite = true;
|
||||
break;
|
||||
default: break;
|
||||
}
|
||||
if (methAt || methAtBack || methAtWrite) {
|
||||
const AstNodeDType* const fromDtypep = ichildp->fromp()->dtypep()->skipRefp();
|
||||
if (VN_IS(fromDtypep, QueueDType) || VN_IS(fromDtypep, DynArrayDType)) {
|
||||
// Change access methods to writable ones
|
||||
if (name == "at") {
|
||||
ichildp->name("atWrite");
|
||||
} else if (name == "atBack") {
|
||||
ichildp->name("atWriteAppendBack");
|
||||
if (methAt) {
|
||||
ichildp->method(VCMethod::ARRAY_AT_WRITE);
|
||||
} else if (methAtBack) {
|
||||
ichildp->method(VCMethod::DYN_AT_WRITE_APPEND_BACK);
|
||||
}
|
||||
}
|
||||
methodCallLValueRecurse(nodep, ichildp->fromp(), access);
|
||||
|
|
@ -3958,7 +3975,7 @@ class WidthVisitor final : public VNVisitor {
|
|||
methodOkArguments(nodep, 0, 0);
|
||||
methodCallLValueRecurse(nodep, nodep->fromp(), VAccess::WRITE);
|
||||
newp = new AstCMethodHard{nodep->fileline(), nodep->fromp()->unlinkFrBack(),
|
||||
nodep->name(), withp};
|
||||
VCMethod::arrayMethod(nodep->name()), withp};
|
||||
newp->dtypeSetVoid();
|
||||
} else if (nodep->name() == "min" || nodep->name() == "max" || nodep->name() == "unique"
|
||||
|| nodep->name() == "unique_index") {
|
||||
|
|
@ -3967,7 +3984,7 @@ class WidthVisitor final : public VNVisitor {
|
|||
methodOkArguments(nodep, 0, 0);
|
||||
methodCallLValueRecurse(nodep, nodep->fromp(), VAccess::READ);
|
||||
newp = new AstCMethodHard{nodep->fileline(), nodep->fromp()->unlinkFrBack(),
|
||||
nodep->name(), withp};
|
||||
VCMethod::arrayMethod(nodep->name()), withp};
|
||||
if (nodep->name() == "unique_index") {
|
||||
newp->dtypep(newp->findQueueIndexDType());
|
||||
} else {
|
||||
|
|
@ -3982,7 +3999,7 @@ class WidthVisitor final : public VNVisitor {
|
|||
methodOkArguments(nodep, 0, 0);
|
||||
methodCallLValueRecurse(nodep, nodep->fromp(), VAccess::READ);
|
||||
newp = new AstCMethodHard{nodep->fileline(), nodep->fromp()->unlinkFrBack(),
|
||||
nodep->name(), withp};
|
||||
VCMethod::arrayMethod(nodep->name()), withp};
|
||||
newp->dtypep(queueDTypeIndexedBy(adtypep->subDTypep()));
|
||||
if (!nodep->firstAbovep()) newp->dtypeSetVoid();
|
||||
} else if (nodep->name() == "find_index" || nodep->name() == "find_first_index"
|
||||
|
|
@ -3993,7 +4010,7 @@ class WidthVisitor final : public VNVisitor {
|
|||
methodOkArguments(nodep, 0, 0);
|
||||
methodCallLValueRecurse(nodep, nodep->fromp(), VAccess::READ);
|
||||
newp = new AstCMethodHard{nodep->fileline(), nodep->fromp()->unlinkFrBack(),
|
||||
nodep->name(), withp};
|
||||
VCMethod::arrayMethod(nodep->name()), withp};
|
||||
newp->dtypep(newp->findQueueIndexDType());
|
||||
if (!nodep->firstAbovep()) newp->dtypeSetVoid();
|
||||
} else if (nodep->name() == "map") {
|
||||
|
|
@ -4008,23 +4025,26 @@ class WidthVisitor final : public VNVisitor {
|
|||
if (nodep->name() == "at") { // Created internally for []
|
||||
methodOkArguments(nodep, 1, 1);
|
||||
iterateCheckSigned32(nodep, "argument", methodArg(nodep, 0), BOTH);
|
||||
newp = new AstCMethodHard{nodep->fileline(), nodep->fromp()->unlinkFrBack(), "at"};
|
||||
newp = new AstCMethodHard{nodep->fileline(), nodep->fromp()->unlinkFrBack(),
|
||||
VCMethod::ARRAY_AT};
|
||||
newp->dtypeFrom(adtypep->subDTypep());
|
||||
} else if (nodep->name() == "atWrite") { // Created internally for []
|
||||
methodOkArguments(nodep, 1, 1);
|
||||
iterateCheckSigned32(nodep, "argument", methodArg(nodep, 0), BOTH);
|
||||
methodCallLValueRecurse(nodep, nodep->fromp(), VAccess::WRITE);
|
||||
newp
|
||||
= new AstCMethodHard{nodep->fileline(), nodep->fromp()->unlinkFrBack(), "atWrite"};
|
||||
newp = new AstCMethodHard{nodep->fileline(), nodep->fromp()->unlinkFrBack(),
|
||||
VCMethod::ARRAY_AT_WRITE};
|
||||
newp->dtypeFrom(adtypep->subDTypep());
|
||||
} else if (nodep->name() == "size") {
|
||||
methodOkArguments(nodep, 0, 0);
|
||||
newp = new AstCMethodHard{nodep->fileline(), nodep->fromp()->unlinkFrBack(), "size"};
|
||||
newp = new AstCMethodHard{nodep->fileline(), nodep->fromp()->unlinkFrBack(),
|
||||
VCMethod::DYN_SIZE};
|
||||
newp->dtypeSetSigned32();
|
||||
} else if (nodep->name() == "delete") { // function void delete()
|
||||
methodOkArguments(nodep, 0, 0);
|
||||
methodCallLValueRecurse(nodep, nodep->fromp(), VAccess::WRITE);
|
||||
newp = new AstCMethodHard{nodep->fileline(), nodep->fromp()->unlinkFrBack(), "clear"};
|
||||
newp = new AstCMethodHard{nodep->fileline(), nodep->fromp()->unlinkFrBack(),
|
||||
VCMethod::DYN_CLEAR};
|
||||
newp->dtypeSetVoid();
|
||||
} else if (nodep->name() == "and" || nodep->name() == "or" || nodep->name() == "xor"
|
||||
|| nodep->name() == "sum" || nodep->name() == "product") {
|
||||
|
|
@ -4035,7 +4055,7 @@ class WidthVisitor final : public VNVisitor {
|
|||
methodOkArguments(nodep, 0, 0);
|
||||
methodCallLValueRecurse(nodep, nodep->fromp(), VAccess::READ);
|
||||
newp = new AstCMethodHard{nodep->fileline(), nodep->fromp()->unlinkFrBack(),
|
||||
"r_" + nodep->name(), withp};
|
||||
VCMethod::arrayMethod("r_" + nodep->name()), withp};
|
||||
newp->dtypeFrom(adtypep->subDTypep());
|
||||
if (!nodep->firstAbovep()) newp->dtypeSetVoid();
|
||||
} else if ((newp = methodCallArray(nodep, adtypep))) {
|
||||
|
|
@ -4057,7 +4077,7 @@ class WidthVisitor final : public VNVisitor {
|
|||
methodOkArguments(nodep, 1, 1);
|
||||
iterateCheckSigned32(nodep, "argument", methodArg(nodep, 0), BOTH);
|
||||
newp = new AstCMethodHard{nodep->fileline(), nodep->fromp()->unlinkFrBack(),
|
||||
nodep->name()};
|
||||
VCMethod::arrayMethod(nodep->name())};
|
||||
newp->dtypeFrom(adtypep->subDTypep());
|
||||
} else if (nodep->name() == "atWriteAppend"
|
||||
|| nodep->name() == "atWriteAppendBack") { // Created internally for []
|
||||
|
|
@ -4065,31 +4085,32 @@ class WidthVisitor final : public VNVisitor {
|
|||
iterateCheckSigned32(nodep, "argument", methodArg(nodep, 0), BOTH);
|
||||
methodCallLValueRecurse(nodep, nodep->fromp(), VAccess::WRITE);
|
||||
newp = new AstCMethodHard{nodep->fileline(), nodep->fromp()->unlinkFrBack(),
|
||||
nodep->name()};
|
||||
VCMethod::arrayMethod(nodep->name())};
|
||||
newp->dtypeFrom(adtypep->subDTypep());
|
||||
} else if (nodep->name() == "num" // function int num()
|
||||
|| nodep->name() == "size") {
|
||||
methodOkArguments(nodep, 0, 0);
|
||||
newp = new AstCMethodHard{nodep->fileline(), nodep->fromp()->unlinkFrBack(), "size"};
|
||||
newp = new AstCMethodHard{nodep->fileline(), nodep->fromp()->unlinkFrBack(),
|
||||
VCMethod::DYN_SIZE};
|
||||
newp->dtypeSetSigned32();
|
||||
} else if (nodep->name() == "delete") { // function void delete([input integer index])
|
||||
methodOkArguments(nodep, 0, 1);
|
||||
methodCallLValueRecurse(nodep, nodep->fromp(), VAccess::WRITE);
|
||||
if (!nodep->pinsp()) {
|
||||
newp = new AstCMethodHard{nodep->fileline(), nodep->fromp()->unlinkFrBack(),
|
||||
"clear"};
|
||||
VCMethod::DYN_CLEAR};
|
||||
newp->dtypeSetVoid();
|
||||
} else {
|
||||
iterateCheckSigned32(nodep, "argument", methodArg(nodep, 0), BOTH);
|
||||
AstNodeExpr* const index_exprp = methodCallQueueIndexExpr(nodep);
|
||||
if (index_exprp->isZero()) { // delete(0) is a pop_front
|
||||
newp = new AstCMethodHard{nodep->fileline(), nodep->fromp()->unlinkFrBack(),
|
||||
"pop_front"};
|
||||
VCMethod::DYN_POP_FRONT};
|
||||
newp->dtypeFrom(adtypep->subDTypep());
|
||||
newp->dtypeSetVoid();
|
||||
} else {
|
||||
newp = new AstCMethodHard{nodep->fileline(), nodep->fromp()->unlinkFrBack(),
|
||||
"erase", index_exprp->unlinkFrBack()};
|
||||
VCMethod::DYN_ERASE, index_exprp->unlinkFrBack()};
|
||||
newp->dtypeSetVoid();
|
||||
}
|
||||
}
|
||||
|
|
@ -4102,11 +4123,11 @@ class WidthVisitor final : public VNVisitor {
|
|||
iterateCheckTyped(nodep, "insert value", argp->exprp(), adtypep->subDTypep(), BOTH);
|
||||
if (index_exprp->isZero()) { // insert(0, ...) is a push_front
|
||||
newp = new AstCMethodHard{nodep->fileline(), nodep->fromp()->unlinkFrBack(),
|
||||
"push_front", argp->exprp()->unlinkFrBack()};
|
||||
VCMethod::DYN_PUSH_FRONT, argp->exprp()->unlinkFrBack()};
|
||||
newp->dtypeSetVoid();
|
||||
} else {
|
||||
newp = new AstCMethodHard{nodep->fileline(), nodep->fromp()->unlinkFrBack(),
|
||||
nodep->name(), index_exprp->unlinkFrBack()};
|
||||
VCMethod::DYN_INSERT, index_exprp->unlinkFrBack()};
|
||||
newp->addPinsp(argp->exprp()->unlinkFrBack());
|
||||
newp->dtypeSetVoid();
|
||||
}
|
||||
|
|
@ -4115,7 +4136,7 @@ class WidthVisitor final : public VNVisitor {
|
|||
// Returns element, so method both consumes (reads) and modifies the queue
|
||||
methodCallLValueRecurse(nodep, nodep->fromp(), VAccess::READWRITE);
|
||||
newp = new AstCMethodHard{nodep->fileline(), nodep->fromp()->unlinkFrBack(),
|
||||
nodep->name()};
|
||||
VCMethod::arrayMethod(nodep->name())};
|
||||
newp->dtypeFrom(adtypep->subDTypep());
|
||||
} else if (nodep->name() == "push_back" || nodep->name() == "push_front") {
|
||||
methodOkArguments(nodep, 1, 1);
|
||||
|
|
@ -4124,7 +4145,8 @@ class WidthVisitor final : public VNVisitor {
|
|||
AstArg* const argp = VN_AS(nodep->pinsp(), Arg);
|
||||
iterateCheckTyped(nodep, "push value", argp->exprp(), adtypep->subDTypep(), BOTH);
|
||||
newp = new AstCMethodHard{nodep->fileline(), nodep->fromp()->unlinkFrBack(),
|
||||
nodep->name(), argp->exprp()->unlinkFrBack()};
|
||||
VCMethod::arrayMethod(nodep->name()),
|
||||
argp->exprp()->unlinkFrBack()};
|
||||
newp->dtypeSetVoid();
|
||||
} else if (nodep->name() == "and" || nodep->name() == "or" || nodep->name() == "xor"
|
||||
|| nodep->name() == "sum" || nodep->name() == "product") {
|
||||
|
|
@ -4134,7 +4156,7 @@ class WidthVisitor final : public VNVisitor {
|
|||
methodOkArguments(nodep, 0, 0);
|
||||
methodCallLValueRecurse(nodep, nodep->fromp(), VAccess::READ);
|
||||
newp = new AstCMethodHard{nodep->fileline(), nodep->fromp()->unlinkFrBack(),
|
||||
"r_" + nodep->name(), withp};
|
||||
VCMethod::arrayMethod("r_" + nodep->name()), withp};
|
||||
newp->dtypeFrom(withp ? withp->dtypep() : adtypep->subDTypep());
|
||||
if (!nodep->firstAbovep()) newp->dtypeSetVoid();
|
||||
} else if ((newp = methodCallArray(nodep, adtypep))) {
|
||||
|
|
@ -4353,7 +4375,7 @@ class WidthVisitor final : public VNVisitor {
|
|||
v3Global.useRandomizeMethods(true);
|
||||
AstCMethodHard* const newp
|
||||
= new AstCMethodHard{nodep->fileline(), nodep->fromp()->unlinkFrBack(),
|
||||
"__Vm_rng.get_randstate", nullptr};
|
||||
VCMethod::RNG_GET_RANDSTATE, nullptr};
|
||||
newp->usePtr(true);
|
||||
newp->dtypeSetString();
|
||||
nodep->replaceWith(newp);
|
||||
|
|
@ -4368,7 +4390,7 @@ class WidthVisitor final : public VNVisitor {
|
|||
v3Global.useRandomizeMethods(true);
|
||||
AstCMethodHard* const newp
|
||||
= new AstCMethodHard{nodep->fileline(), nodep->fromp()->unlinkFrBack(),
|
||||
"__Vm_rng.set_randstate", exprp->unlinkFrBack()};
|
||||
VCMethod::RNG_SET_RANDSTATE, exprp->unlinkFrBack()};
|
||||
newp->usePtr(true);
|
||||
newp->dtypeSetString();
|
||||
nodep->replaceWith(newp);
|
||||
|
|
@ -4456,7 +4478,7 @@ class WidthVisitor final : public VNVisitor {
|
|||
methodCallLValueRecurse(nodep, nodep->fromp(), VAccess::READ);
|
||||
AstCMethodHard* const newp
|
||||
= new AstCMethodHard{nodep->fileline(), nodep->fromp()->unlinkFrBack(),
|
||||
"r_" + nodep->name(), withp};
|
||||
VCMethod::arrayMethod("r_" + nodep->name()), withp};
|
||||
newp->dtypeFrom(withp ? withp->dtypep() : adtypep->subDTypep());
|
||||
if (!nodep->firstAbovep()) newp->dtypeSetVoid();
|
||||
newp->protect(false);
|
||||
|
|
@ -4503,7 +4525,7 @@ class WidthVisitor final : public VNVisitor {
|
|||
if (nodep->name() == "triggered") {
|
||||
methodOkArguments(nodep, 0, 0);
|
||||
AstCMethodHard* const callp = new AstCMethodHard{
|
||||
nodep->fileline(), nodep->fromp()->unlinkFrBack(), "isTriggered"};
|
||||
nodep->fileline(), nodep->fromp()->unlinkFrBack(), VCMethod::EVENT_IS_TRIGGERED};
|
||||
callp->dtypeSetBit();
|
||||
nodep->replaceWith(callp);
|
||||
VL_DO_DANGLING(pushDeletep(nodep), nodep);
|
||||
|
|
@ -5634,10 +5656,10 @@ class WidthVisitor final : public VNVisitor {
|
|||
AstCMethodHard* newp;
|
||||
if (!dynp->rhsp()) {
|
||||
newp = new AstCMethodHard{nodep->fileline(), nodep->lhsp()->unlinkFrBack(),
|
||||
"renew", dynp->sizep()->unlinkFrBack()};
|
||||
VCMethod::DYN_RENEW, dynp->sizep()->unlinkFrBack()};
|
||||
} else {
|
||||
newp = new AstCMethodHard{nodep->fileline(), nodep->lhsp()->unlinkFrBack(),
|
||||
"renew_copy", dynp->sizep()->unlinkFrBack()};
|
||||
VCMethod::DYN_RENEW_COPY, dynp->sizep()->unlinkFrBack()};
|
||||
newp->addPinsp(dynp->rhsp()->unlinkFrBack());
|
||||
}
|
||||
newp->didWidth(true);
|
||||
|
|
|
|||
|
|
@ -488,8 +488,8 @@ private:
|
|||
}
|
||||
void visit(AstCMethodHard* nodep) override {
|
||||
VL_RESTORER(m_dynsizedelem);
|
||||
if (nodep->name() == "atWrite" || nodep->name() == "atWriteAppend"
|
||||
|| nodep->name() == "at")
|
||||
if (nodep->method() == VCMethod::ARRAY_AT || nodep->method() == VCMethod::ARRAY_AT_WRITE
|
||||
|| nodep->method() == VCMethod::DYN_AT_WRITE_APPEND)
|
||||
m_dynsizedelem = true;
|
||||
iterateChildren(nodep);
|
||||
editDType(nodep);
|
||||
|
|
|
|||
|
|
@ -286,9 +286,10 @@ class WidthSelVisitor final : public VNVisitor {
|
|||
VL_DO_DANGLING(pushDeletep(nodep), nodep);
|
||||
} else if (const AstDynArrayDType* const adtypep = VN_CAST(ddtypep, DynArrayDType)) {
|
||||
// SELBIT(array, index) -> CMETHODCALL(queue, "at", index)
|
||||
const char* methodName = nodep->access().isWriteOrRW() ? "atWrite" : "at";
|
||||
const VCMethod method
|
||||
= nodep->access().isWriteOrRW() ? VCMethod::ARRAY_AT_WRITE : VCMethod::ARRAY_AT;
|
||||
AstCMethodHard* const newp
|
||||
= new AstCMethodHard{nodep->fileline(), fromp, methodName, rhsp};
|
||||
= new AstCMethodHard{nodep->fileline(), fromp, method, rhsp};
|
||||
newp->dtypeFrom(adtypep->subDTypep()); // Need to strip off queue reference
|
||||
UINFOTREE(9, newp, "", "SELBTq");
|
||||
nodep->replaceWith(newp);
|
||||
|
|
@ -296,12 +297,16 @@ class WidthSelVisitor final : public VNVisitor {
|
|||
} else if (const AstQueueDType* const adtypep = VN_CAST(ddtypep, QueueDType)) {
|
||||
// SELBIT(array, index) -> CMETHODCALL(queue, "at", index)
|
||||
AstCMethodHard* newp;
|
||||
const char* methodName = nodep->access().isWriteOrRW() ? "atWriteAppend" : "at";
|
||||
if (AstNodeExpr* const backnessp = selQueueBackness(rhsp)) {
|
||||
newp = new AstCMethodHard{nodep->fileline(), fromp,
|
||||
std::string(methodName) + "Back", backnessp};
|
||||
const VCMethod method = nodep->access().isWriteOrRW()
|
||||
? VCMethod::DYN_AT_WRITE_APPEND_BACK
|
||||
: VCMethod::ARRAY_AT_BACK;
|
||||
newp = new AstCMethodHard{nodep->fileline(), fromp, method, backnessp};
|
||||
} else {
|
||||
newp = new AstCMethodHard{nodep->fileline(), fromp, methodName, rhsp};
|
||||
const VCMethod method = nodep->access().isWriteOrRW()
|
||||
? VCMethod::DYN_AT_WRITE_APPEND
|
||||
: VCMethod::ARRAY_AT;
|
||||
newp = new AstCMethodHard{nodep->fileline(), fromp, method, rhsp};
|
||||
}
|
||||
newp->dtypeFrom(adtypep->subDTypep()); // Need to strip off queue reference
|
||||
UINFOTREE(9, newp, "", "SELBTq");
|
||||
|
|
@ -379,10 +384,10 @@ class WidthSelVisitor final : public VNVisitor {
|
|||
// queue size, this allows a single queue reference, to support
|
||||
// for equations in side effects that select the queue to
|
||||
// operate upon.
|
||||
std::string name = (qleftBacknessp ? "sliceBackBack"
|
||||
: qrightBacknessp ? "sliceFrontBack"
|
||||
: "slice");
|
||||
AstCMethodHard* const newp = new AstCMethodHard{nodep->fileline(), fromp, name};
|
||||
VCMethod method = (qleftBacknessp ? VCMethod::DYN_SLICE_BACK_BACK
|
||||
: qrightBacknessp ? VCMethod::DYN_SLICE_FRONT_BACK
|
||||
: VCMethod::DYN_SLICE);
|
||||
AstCMethodHard* const newp = new AstCMethodHard{nodep->fileline(), fromp, method};
|
||||
if (qleftBacknessp) {
|
||||
VL_DO_DANGLING(pushDeletep(qleftp), qleftp);
|
||||
newp->addPinsp(qleftBacknessp);
|
||||
|
|
|
|||
|
|
@ -701,6 +701,7 @@ static bool verilate(const string& argString) {
|
|||
if (v3Global.opt.debugSelfTest()) {
|
||||
V3Os::selfTest();
|
||||
V3Number::selfTest();
|
||||
VCMethod::selfTest();
|
||||
VString::selfTest();
|
||||
VHashSha256::selfTest();
|
||||
VSpellCheck::selfTest();
|
||||
|
|
|
|||
Loading…
Reference in New Issue