2022-09-15 14:10:39 +02:00
|
|
|
// -*- mode: C++; c-file-style: "cc-mode" -*-
|
|
|
|
|
//*************************************************************************
|
|
|
|
|
// DESCRIPTION: Verilator: AstNode sub-types representing data types
|
|
|
|
|
//
|
|
|
|
|
// 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
|
2022-09-15 14:10:39 +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
|
|
|
|
|
//
|
|
|
|
|
//*************************************************************************
|
|
|
|
|
//
|
|
|
|
|
// This files contains all 'AstNode' sub-types that relate to the
|
|
|
|
|
// representation of data types.
|
|
|
|
|
//
|
|
|
|
|
//*************************************************************************
|
|
|
|
|
|
|
|
|
|
#ifndef VERILATOR_V3ASTNODEDTYPE_H_
|
|
|
|
|
#define VERILATOR_V3ASTNODEDTYPE_H_
|
|
|
|
|
|
|
|
|
|
#ifndef VERILATOR_V3AST_H_
|
|
|
|
|
#error "Use V3Ast.h as the include"
|
|
|
|
|
#include "V3Ast.h" // This helps code analysis tools pick up symbols in V3Ast.h
|
|
|
|
|
#define VL_NOT_FINAL // This #define fixes broken code folding in the CLion IDE
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
// === Abstract base node types (AstNode*) =====================================
|
|
|
|
|
|
|
|
|
|
class AstNodeDType VL_NOT_FINAL : public AstNode {
|
|
|
|
|
// Ideally width() would migrate to BasicDType as that's where it makes sense,
|
|
|
|
|
// but it's currently so prevalent in the code we leave it here.
|
|
|
|
|
// Note the below members are included in AstTypeTable::Key lookups
|
2022-09-15 14:54:04 +02:00
|
|
|
int m_width = 0; // (also in AstTypeTable::Key) Bit width of operation
|
|
|
|
|
int m_widthMin
|
|
|
|
|
= 0; // (also in AstTypeTable::Key) If unsized, bitwidth of minimum implementation
|
2022-09-15 14:10:39 +02:00
|
|
|
VSigning m_numeric; // (also in AstTypeTable::Key) Node is signed
|
|
|
|
|
// Other members
|
2022-09-15 14:54:04 +02:00
|
|
|
bool m_generic = false; // Simple globally referenced type, don't garbage collect
|
2022-09-15 14:10:39 +02:00
|
|
|
// Unique number assigned to each dtype during creation for IEEE matching
|
|
|
|
|
static int s_uniqueNum;
|
|
|
|
|
|
|
|
|
|
protected:
|
|
|
|
|
// CONSTRUCTORS
|
|
|
|
|
AstNodeDType(VNType t, FileLine* fl)
|
2022-09-15 14:54:04 +02:00
|
|
|
: AstNode{t, fl} {}
|
2022-09-15 14:10:39 +02:00
|
|
|
|
|
|
|
|
public:
|
2022-10-04 12:03:41 +02:00
|
|
|
ASTGEN_MEMBERS_AstNodeDType;
|
2022-09-15 14:10:39 +02:00
|
|
|
// ACCESSORS
|
2022-09-16 12:22:11 +02:00
|
|
|
void dump(std::ostream& str) const override;
|
2024-02-09 23:50:09 +01:00
|
|
|
void dumpJson(std::ostream& str) const override;
|
2024-03-02 14:57:26 +01:00
|
|
|
virtual void dumpSmall(std::ostream& str) const VL_MT_STABLE;
|
2022-09-16 12:22:11 +02:00
|
|
|
bool hasDType() const override { return true; }
|
2022-09-15 14:10:39 +02:00
|
|
|
/// Require VlUnpacked, instead of [] for POD elements.
|
|
|
|
|
/// A non-POD object is always compound, but some POD elements
|
|
|
|
|
/// are compound when methods calls operate on object, or when
|
|
|
|
|
/// under another compound-requiring object e.g. class
|
|
|
|
|
virtual bool isCompound() const = 0;
|
2023-02-12 22:32:36 +01:00
|
|
|
// Integral or packed, allowed inside an unpacked union/struct
|
|
|
|
|
virtual bool isIntegralOrPacked() const { return !isCompound(); }
|
2022-09-15 14:10:39 +02:00
|
|
|
// (Slow) recurse down to find basic data type
|
2023-03-17 00:48:56 +01:00
|
|
|
virtual AstBasicDType* basicp() const VL_MT_STABLE = 0;
|
2022-09-15 14:10:39 +02:00
|
|
|
// recurses over typedefs/const/enum to next non-typeref type
|
2023-03-17 00:48:56 +01:00
|
|
|
virtual AstNodeDType* skipRefp() const VL_MT_STABLE = 0;
|
2022-09-15 14:10:39 +02:00
|
|
|
// recurses over typedefs to next non-typeref-or-const type
|
|
|
|
|
virtual AstNodeDType* skipRefToConstp() const = 0;
|
|
|
|
|
// recurses over typedefs/const to next non-typeref-or-enum/struct type
|
|
|
|
|
virtual AstNodeDType* skipRefToEnump() const = 0;
|
|
|
|
|
// (Slow) recurses - Structure alignment 1,2,4 or 8 bytes (arrays affect this)
|
|
|
|
|
virtual int widthAlignBytes() const = 0;
|
|
|
|
|
// (Slow) recurses - Width in bytes rounding up 1,2,4,8,12,...
|
|
|
|
|
virtual int widthTotalBytes() const = 0;
|
2022-09-16 12:22:11 +02:00
|
|
|
bool maybePointedTo() const override { return true; }
|
2022-09-15 14:10:39 +02:00
|
|
|
// Iff has a non-null refDTypep(), as generic node function
|
|
|
|
|
virtual AstNodeDType* virtRefDTypep() const { return nullptr; }
|
|
|
|
|
// Iff has refDTypep(), set as generic node function
|
|
|
|
|
virtual void virtRefDTypep(AstNodeDType* nodep) {}
|
|
|
|
|
// Iff has a non-null second dtypep, as generic node function
|
|
|
|
|
virtual AstNodeDType* virtRefDType2p() const { return nullptr; }
|
|
|
|
|
// Iff has second dtype, set as generic node function
|
|
|
|
|
virtual void virtRefDType2p(AstNodeDType* nodep) {}
|
|
|
|
|
// Assignable equivalence. Call skipRefp() on this and samep before calling
|
2022-12-02 00:47:09 +01:00
|
|
|
virtual bool similarDType(const AstNodeDType* samep) const = 0;
|
2022-09-15 14:10:39 +02:00
|
|
|
// Iff has a non-null subDTypep(), as generic node function
|
2023-03-17 00:48:56 +01:00
|
|
|
virtual AstNodeDType* subDTypep() const VL_MT_SAFE { return nullptr; }
|
2022-09-15 14:10:39 +02:00
|
|
|
virtual bool isFourstate() const;
|
|
|
|
|
// Ideally an IEEE $typename
|
|
|
|
|
virtual string prettyDTypeName() const { return prettyTypeName(); }
|
|
|
|
|
string prettyDTypeNameQ() const { return "'" + prettyDTypeName() + "'"; }
|
|
|
|
|
//
|
|
|
|
|
// Changing the width may confuse the data type resolution, so must clear
|
|
|
|
|
// TypeTable cache after use.
|
|
|
|
|
void widthForce(int width, int widthMin) {
|
|
|
|
|
m_width = width;
|
|
|
|
|
m_widthMin = widthMin;
|
|
|
|
|
}
|
|
|
|
|
// For backward compatibility inherit width and signing from the subDType/base type
|
2022-10-03 05:04:55 +02:00
|
|
|
void widthFromSub(const AstNodeDType* nodep) {
|
2022-09-15 14:10:39 +02:00
|
|
|
m_width = nodep->m_width;
|
|
|
|
|
m_widthMin = nodep->m_widthMin;
|
|
|
|
|
m_numeric = nodep->m_numeric;
|
|
|
|
|
}
|
|
|
|
|
//
|
2022-10-18 23:07:09 +02:00
|
|
|
int width() const VL_MT_SAFE { return m_width; }
|
2022-09-15 14:10:39 +02:00
|
|
|
void numeric(VSigning flag) { m_numeric = flag; }
|
2022-10-18 23:07:09 +02:00
|
|
|
bool isSigned() const VL_MT_SAFE { return m_numeric.isSigned(); }
|
|
|
|
|
bool isNosign() const VL_MT_SAFE { return m_numeric.isNosign(); }
|
2022-09-15 14:10:39 +02:00
|
|
|
VSigning numeric() const { return m_numeric; }
|
2022-10-18 23:07:09 +02:00
|
|
|
int widthWords() const VL_MT_SAFE { return VL_WORDS_I(width()); }
|
|
|
|
|
int widthMin() const VL_MT_SAFE { // If sized, the size,
|
|
|
|
|
// if unsized the min digits to represent it
|
2022-09-15 14:10:39 +02:00
|
|
|
return m_widthMin ? m_widthMin : m_width;
|
|
|
|
|
}
|
|
|
|
|
int widthPow2() const;
|
|
|
|
|
void widthMinFromWidth() { m_widthMin = m_width; }
|
2022-10-18 23:07:09 +02:00
|
|
|
bool widthSized() const VL_MT_SAFE { return !m_widthMin || m_widthMin == m_width; }
|
|
|
|
|
bool generic() const VL_MT_SAFE { return m_generic; }
|
2022-09-15 14:10:39 +02:00
|
|
|
void generic(bool flag) { m_generic = flag; }
|
|
|
|
|
std::pair<uint32_t, uint32_t> dimensions(bool includeBasic);
|
|
|
|
|
uint32_t arrayUnpackedElements(); // 1, or total multiplication of all dimensions
|
|
|
|
|
static int uniqueNumInc() { return ++s_uniqueNum; }
|
|
|
|
|
const char* charIQWN() const {
|
|
|
|
|
return (isString() ? "N" : isWide() ? "W" : isQuad() ? "Q" : "I");
|
|
|
|
|
}
|
2024-03-03 16:23:47 +01:00
|
|
|
string cType(const string& name, bool forFunc, bool isRef, bool packed = false) const;
|
2023-03-17 00:48:56 +01:00
|
|
|
// Represents a C++ LiteralType? (can be constexpr)
|
|
|
|
|
bool isLiteralType() const VL_MT_STABLE;
|
2022-09-15 14:10:39 +02:00
|
|
|
|
|
|
|
|
private:
|
|
|
|
|
class CTypeRecursed;
|
2024-03-03 16:23:04 +01:00
|
|
|
CTypeRecursed cTypeRecurse(bool compound, bool packed) const;
|
2022-09-15 14:10:39 +02:00
|
|
|
};
|
|
|
|
|
class AstNodeArrayDType VL_NOT_FINAL : public AstNodeDType {
|
|
|
|
|
// Array data type, ie "some_dtype var_name [2:0]"
|
2022-09-15 20:43:56 +02:00
|
|
|
// @astgen op1 := childDTypep : Optional[AstNodeDType] // moved to refDTypep() in V3Width
|
|
|
|
|
// @astgen op2 := rangep : Optional[AstRange] // array bounds
|
2023-12-01 01:58:16 +01:00
|
|
|
//
|
|
|
|
|
// @astgen ptr := m_refDTypep : Optional[AstNodeDType] // Elements of this type (post-width)
|
2022-09-15 20:43:56 +02:00
|
|
|
AstNode* rangenp() const { return reinterpret_cast<AstNode*>(rangep()); }
|
|
|
|
|
|
2022-09-15 14:10:39 +02:00
|
|
|
protected:
|
|
|
|
|
AstNodeArrayDType(VNType t, FileLine* fl)
|
|
|
|
|
: AstNodeDType{t, fl} {}
|
|
|
|
|
|
|
|
|
|
public:
|
2022-10-04 12:03:41 +02:00
|
|
|
ASTGEN_MEMBERS_AstNodeArrayDType;
|
2022-09-16 12:22:11 +02:00
|
|
|
void dump(std::ostream& str) const override;
|
2024-02-09 23:50:09 +01:00
|
|
|
void dumpJson(std::ostream& str) const override;
|
2022-09-16 12:22:11 +02:00
|
|
|
void dumpSmall(std::ostream& str) const override;
|
|
|
|
|
const char* broken() const override {
|
2023-12-01 01:58:16 +01:00
|
|
|
BROKEN_RTN(!((m_refDTypep && !childDTypep()) || (!m_refDTypep && childDTypep())));
|
2022-09-15 14:10:39 +02:00
|
|
|
return nullptr;
|
|
|
|
|
}
|
2022-09-16 12:22:11 +02:00
|
|
|
bool same(const AstNode* samep) const override {
|
2023-10-16 11:17:52 +02:00
|
|
|
const AstNodeArrayDType* const asamep = VN_DBG_AS(samep, NodeArrayDType);
|
2022-09-15 14:10:39 +02:00
|
|
|
return (hi() == asamep->hi() && subDTypep() == asamep->subDTypep()
|
|
|
|
|
&& rangenp()->sameTree(asamep->rangenp()));
|
|
|
|
|
} // HashedDT doesn't recurse, so need to check children
|
2022-12-02 00:47:09 +01:00
|
|
|
bool similarDType(const AstNodeDType* samep) const override {
|
2023-10-16 11:17:52 +02:00
|
|
|
if (type() != samep->type()) return false;
|
|
|
|
|
const AstNodeArrayDType* const asamep = VN_DBG_AS(samep, NodeArrayDType);
|
|
|
|
|
return (hi() == asamep->hi() && rangenp()->sameTree(asamep->rangenp())
|
2022-09-15 14:10:39 +02:00
|
|
|
&& subDTypep()->skipRefp()->similarDType(asamep->subDTypep()->skipRefp()));
|
|
|
|
|
}
|
2022-09-16 12:22:11 +02:00
|
|
|
AstNodeDType* getChildDTypep() const override { return childDTypep(); }
|
2023-03-17 00:48:56 +01:00
|
|
|
AstNodeDType* subDTypep() const override VL_MT_STABLE {
|
2022-10-18 23:07:09 +02:00
|
|
|
return m_refDTypep ? m_refDTypep : childDTypep();
|
|
|
|
|
}
|
2022-09-15 14:10:39 +02:00
|
|
|
void refDTypep(AstNodeDType* nodep) { m_refDTypep = nodep; }
|
2022-09-16 12:22:11 +02:00
|
|
|
AstNodeDType* virtRefDTypep() const override { return m_refDTypep; }
|
|
|
|
|
void virtRefDTypep(AstNodeDType* nodep) override { refDTypep(nodep); }
|
2022-09-15 14:10:39 +02:00
|
|
|
// METHODS
|
2023-03-17 00:48:56 +01:00
|
|
|
AstBasicDType* basicp() const override VL_MT_STABLE {
|
2022-09-15 14:10:39 +02:00
|
|
|
return subDTypep()->basicp();
|
|
|
|
|
} // (Slow) recurse down to find basic data type
|
2023-03-17 00:48:56 +01:00
|
|
|
AstNodeDType* skipRefp() const override VL_MT_STABLE { return (AstNodeDType*)this; }
|
2022-09-16 12:22:11 +02:00
|
|
|
AstNodeDType* skipRefToConstp() const override { return (AstNodeDType*)this; }
|
|
|
|
|
AstNodeDType* skipRefToEnump() const override { return (AstNodeDType*)this; }
|
|
|
|
|
int widthAlignBytes() const override { return subDTypep()->widthAlignBytes(); }
|
|
|
|
|
int widthTotalBytes() const override {
|
2022-09-15 14:10:39 +02:00
|
|
|
return elementsConst() * subDTypep()->widthTotalBytes();
|
|
|
|
|
}
|
2023-03-17 00:48:56 +01:00
|
|
|
inline int left() const VL_MT_STABLE;
|
|
|
|
|
inline int right() const VL_MT_STABLE;
|
|
|
|
|
inline int hi() const VL_MT_STABLE;
|
|
|
|
|
inline int lo() const VL_MT_STABLE;
|
|
|
|
|
inline int elementsConst() const VL_MT_STABLE;
|
|
|
|
|
inline VNumRange declRange() const VL_MT_STABLE;
|
2022-09-15 14:10:39 +02:00
|
|
|
};
|
|
|
|
|
class AstNodeUOrStructDType VL_NOT_FINAL : public AstNodeDType {
|
|
|
|
|
// A struct or union; common handling
|
2022-09-15 20:43:56 +02:00
|
|
|
// @astgen op1 := membersp : List[AstMemberDType]
|
2023-12-01 01:58:16 +01:00
|
|
|
//
|
|
|
|
|
// @astgen ptr := m_classOrPackagep : Optional[AstNodeModule] // Package emitted with
|
2022-09-15 14:10:39 +02:00
|
|
|
string m_name; // Name from upper typedef, if any
|
|
|
|
|
const int m_uniqueNum;
|
2022-11-13 15:26:46 +01:00
|
|
|
bool m_packed;
|
|
|
|
|
bool m_isFourstate = false; // V3Width computes
|
2022-09-15 14:10:39 +02:00
|
|
|
|
|
|
|
|
protected:
|
|
|
|
|
AstNodeUOrStructDType(VNType t, FileLine* fl, VSigning numericUnpack)
|
|
|
|
|
: AstNodeDType{t, fl}
|
|
|
|
|
, m_uniqueNum{uniqueNumInc()} {
|
|
|
|
|
// VSigning::NOSIGN overloaded to indicate not packed
|
|
|
|
|
m_packed = (numericUnpack != VSigning::NOSIGN);
|
|
|
|
|
numeric(VSigning::fromBool(numericUnpack.isSigned()));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public:
|
2022-10-04 12:03:41 +02:00
|
|
|
ASTGEN_MEMBERS_AstNodeUOrStructDType;
|
2022-09-15 14:10:39 +02:00
|
|
|
int uniqueNum() const { return m_uniqueNum; }
|
2022-09-16 12:22:11 +02:00
|
|
|
void dump(std::ostream& str) const override;
|
2024-02-09 23:50:09 +01:00
|
|
|
void dumpJson(std::ostream& str) const override;
|
2022-12-21 01:22:42 +01:00
|
|
|
bool isCompound() const override { return !packed(); }
|
2022-09-15 14:10:39 +02:00
|
|
|
// For basicp() we reuse the size to indicate a "fake" basic type of same size
|
2022-09-16 12:22:11 +02:00
|
|
|
AstBasicDType* basicp() const override {
|
2022-09-15 14:10:39 +02:00
|
|
|
return (isFourstate()
|
|
|
|
|
? VN_AS(findLogicRangeDType(VNumRange{width() - 1, 0}, width(), numeric()),
|
|
|
|
|
BasicDType)
|
|
|
|
|
: VN_AS(findBitRangeDType(VNumRange{width() - 1, 0}, width(), numeric()),
|
|
|
|
|
BasicDType));
|
|
|
|
|
}
|
2023-03-17 00:48:56 +01:00
|
|
|
AstNodeDType* skipRefp() const override VL_MT_STABLE { return (AstNodeDType*)this; }
|
2022-09-16 12:22:11 +02:00
|
|
|
AstNodeDType* skipRefToConstp() const override { return (AstNodeDType*)this; }
|
|
|
|
|
AstNodeDType* skipRefToEnump() const override { return (AstNodeDType*)this; }
|
2022-09-15 14:10:39 +02:00
|
|
|
// (Slow) recurses - Structure alignment 1,2,4 or 8 bytes (arrays affect this)
|
2022-09-16 12:22:11 +02:00
|
|
|
int widthAlignBytes() const override;
|
2022-09-15 14:10:39 +02:00
|
|
|
// (Slow) recurses - Width in bytes rounding up 1,2,4,8,12,...
|
2022-09-16 12:22:11 +02:00
|
|
|
int widthTotalBytes() const override;
|
2022-12-02 00:47:09 +01:00
|
|
|
bool similarDType(const AstNodeDType* samep) const override {
|
2022-09-15 14:10:39 +02:00
|
|
|
return this == samep; // We don't compare members, require exact equivalence
|
|
|
|
|
}
|
2023-03-18 01:24:15 +01:00
|
|
|
string name() const override VL_MT_STABLE { return m_name; }
|
2022-09-16 12:22:11 +02:00
|
|
|
void name(const string& flag) override { m_name = flag; }
|
2022-10-18 23:07:09 +02:00
|
|
|
bool packed() const VL_MT_SAFE { return m_packed; }
|
2022-12-21 01:22:42 +01:00
|
|
|
void packed(bool flag) { m_packed = flag; }
|
2022-09-15 14:10:39 +02:00
|
|
|
// packed() but as don't support unpacked, presently all structs
|
|
|
|
|
static bool packedUnsup() { return true; }
|
|
|
|
|
void isFourstate(bool flag) { m_isFourstate = flag; }
|
2023-03-17 00:48:56 +01:00
|
|
|
bool isFourstate() const override VL_MT_SAFE { return m_isFourstate; }
|
2022-09-15 14:10:39 +02:00
|
|
|
static int lo() { return 0; }
|
|
|
|
|
int hi() const { return dtypep()->width() - 1; } // Packed classes look like arrays
|
|
|
|
|
VNumRange declRange() const { return VNumRange{hi(), lo()}; }
|
2023-01-28 04:41:12 +01:00
|
|
|
AstNodeModule* classOrPackagep() const { return m_classOrPackagep; }
|
|
|
|
|
void classOrPackagep(AstNodeModule* classpackagep) { m_classOrPackagep = classpackagep; }
|
2022-09-15 14:10:39 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
// === Concrete node types =====================================================
|
|
|
|
|
|
|
|
|
|
// === AstNode ===
|
|
|
|
|
class AstEnumItem final : public AstNode {
|
2022-09-15 20:43:56 +02:00
|
|
|
// @astgen op1 := rangep : Optional[AstRange] // Range for name appending
|
2022-11-13 21:33:11 +01:00
|
|
|
// @astgen op2 := valuep : Optional[AstNodeExpr]
|
2022-09-15 14:10:39 +02:00
|
|
|
string m_name;
|
|
|
|
|
|
|
|
|
|
public:
|
|
|
|
|
// Parents: ENUM
|
2022-11-13 21:33:11 +01:00
|
|
|
AstEnumItem(FileLine* fl, const string& name, AstRange* rangep, AstNodeExpr* valuep)
|
2022-09-15 14:10:39 +02:00
|
|
|
: ASTGEN_SUPER_EnumItem(fl)
|
|
|
|
|
, m_name{name} {
|
2022-09-15 20:43:56 +02:00
|
|
|
this->rangep(rangep);
|
|
|
|
|
this->valuep(valuep);
|
2022-09-15 14:10:39 +02:00
|
|
|
}
|
2022-10-04 12:03:41 +02:00
|
|
|
ASTGEN_MEMBERS_AstEnumItem;
|
2023-03-18 01:24:15 +01:00
|
|
|
string name() const override VL_MT_STABLE { return m_name; }
|
2022-09-16 12:22:11 +02:00
|
|
|
bool maybePointedTo() const override { return true; }
|
|
|
|
|
bool hasDType() const override { return true; }
|
|
|
|
|
void name(const string& flag) override { m_name = flag; }
|
2022-09-15 14:10:39 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
// === AstNodeDType ===
|
|
|
|
|
class AstAssocArrayDType final : public AstNodeDType {
|
|
|
|
|
// Associative array data type, ie "[some_dtype]"
|
2022-09-15 20:43:56 +02:00
|
|
|
// @astgen op1 := childDTypep : Optional[AstNodeDType] // moved to refDTypep() in V3Width
|
2022-09-21 16:24:17 +02:00
|
|
|
// @astgen op2 := keyChildDTypep : Optional[AstNodeDType]
|
2023-12-01 01:58:16 +01:00
|
|
|
//
|
|
|
|
|
// @astgen ptr := m_refDTypep : Optional[AstNodeDType] // Elements of this type (post-width)
|
|
|
|
|
// @astgen ptr := m_keyDTypep : Optional[AstNodeDType] // Keys of this type (post-width)
|
2022-09-15 14:10:39 +02:00
|
|
|
public:
|
|
|
|
|
AstAssocArrayDType(FileLine* fl, VFlagChildDType, AstNodeDType* dtp, AstNodeDType* keyDtp)
|
|
|
|
|
: ASTGEN_SUPER_AssocArrayDType(fl) {
|
|
|
|
|
childDTypep(dtp); // Only for parser
|
|
|
|
|
keyChildDTypep(keyDtp); // Only for parser
|
|
|
|
|
refDTypep(nullptr);
|
|
|
|
|
keyDTypep(nullptr);
|
|
|
|
|
dtypep(nullptr); // V3Width will resolve
|
|
|
|
|
}
|
|
|
|
|
AstAssocArrayDType(FileLine* fl, AstNodeDType* dtp, AstNodeDType* keyDtp)
|
|
|
|
|
: ASTGEN_SUPER_AssocArrayDType(fl) {
|
|
|
|
|
refDTypep(dtp);
|
|
|
|
|
keyDTypep(keyDtp);
|
|
|
|
|
dtypep(dtp);
|
|
|
|
|
}
|
2022-10-04 12:03:41 +02:00
|
|
|
ASTGEN_MEMBERS_AstAssocArrayDType;
|
2022-09-16 12:22:11 +02:00
|
|
|
const char* broken() const override {
|
2023-12-01 01:58:16 +01:00
|
|
|
BROKEN_RTN(!((m_refDTypep && !childDTypep()) || (!m_refDTypep && childDTypep())));
|
|
|
|
|
BROKEN_RTN(!((m_keyDTypep && !childDTypep()) || (!m_keyDTypep && childDTypep())));
|
2022-09-15 14:10:39 +02:00
|
|
|
return nullptr;
|
|
|
|
|
}
|
2022-09-16 12:22:11 +02:00
|
|
|
bool same(const AstNode* samep) const override {
|
2023-10-16 11:17:52 +02:00
|
|
|
const AstAssocArrayDType* const asamep = VN_DBG_AS(samep, AssocArrayDType);
|
2022-09-15 14:10:39 +02:00
|
|
|
if (!asamep->subDTypep()) return false;
|
|
|
|
|
if (!asamep->keyDTypep()) return false;
|
|
|
|
|
return (subDTypep() == asamep->subDTypep() && keyDTypep() == asamep->keyDTypep());
|
|
|
|
|
}
|
2022-12-02 00:47:09 +01:00
|
|
|
bool similarDType(const AstNodeDType* samep) const override {
|
2023-10-16 11:17:52 +02:00
|
|
|
if (type() != samep->type()) return false;
|
|
|
|
|
const AstAssocArrayDType* const asamep = VN_DBG_AS(samep, AssocArrayDType);
|
|
|
|
|
return asamep->subDTypep()
|
2022-09-15 14:10:39 +02:00
|
|
|
&& subDTypep()->skipRefp()->similarDType(asamep->subDTypep()->skipRefp());
|
|
|
|
|
}
|
2022-09-16 12:22:11 +02:00
|
|
|
string prettyDTypeName() const override;
|
|
|
|
|
void dumpSmall(std::ostream& str) const override;
|
|
|
|
|
AstNodeDType* getChildDTypep() const override { return childDTypep(); }
|
|
|
|
|
AstNodeDType* getChild2DTypep() const override { return keyChildDTypep(); }
|
2023-03-17 00:48:56 +01:00
|
|
|
AstNodeDType* subDTypep() const override VL_MT_STABLE {
|
2022-10-18 23:07:09 +02:00
|
|
|
return m_refDTypep ? m_refDTypep : childDTypep();
|
|
|
|
|
}
|
2022-09-15 14:10:39 +02:00
|
|
|
void refDTypep(AstNodeDType* nodep) { m_refDTypep = nodep; }
|
2022-09-16 12:22:11 +02:00
|
|
|
AstNodeDType* virtRefDTypep() const override { return m_refDTypep; }
|
|
|
|
|
void virtRefDTypep(AstNodeDType* nodep) override { refDTypep(nodep); }
|
|
|
|
|
AstNodeDType* virtRefDType2p() const override { return m_keyDTypep; }
|
|
|
|
|
void virtRefDType2p(AstNodeDType* nodep) override { keyDTypep(nodep); }
|
2022-09-15 14:10:39 +02:00
|
|
|
//
|
2023-03-17 00:48:56 +01:00
|
|
|
AstNodeDType* keyDTypep() const VL_MT_STABLE {
|
2022-10-18 23:07:09 +02:00
|
|
|
return m_keyDTypep ? m_keyDTypep : keyChildDTypep();
|
|
|
|
|
}
|
2022-09-15 14:10:39 +02:00
|
|
|
void keyDTypep(AstNodeDType* nodep) { m_keyDTypep = nodep; }
|
|
|
|
|
// METHODS
|
2023-03-17 00:48:56 +01:00
|
|
|
AstBasicDType* basicp() const override VL_MT_STABLE { return nullptr; }
|
|
|
|
|
AstNodeDType* skipRefp() const override VL_MT_STABLE { return (AstNodeDType*)this; }
|
2022-09-16 12:22:11 +02:00
|
|
|
AstNodeDType* skipRefToConstp() const override { return (AstNodeDType*)this; }
|
|
|
|
|
AstNodeDType* skipRefToEnump() const override { return (AstNodeDType*)this; }
|
|
|
|
|
int widthAlignBytes() const override { return subDTypep()->widthAlignBytes(); }
|
|
|
|
|
int widthTotalBytes() const override { return subDTypep()->widthTotalBytes(); }
|
|
|
|
|
bool isCompound() const override { return true; }
|
2022-09-15 14:10:39 +02:00
|
|
|
};
|
|
|
|
|
class AstBasicDType final : public AstNodeDType {
|
|
|
|
|
// Builtin atomic/vectored data type
|
2022-09-15 20:43:56 +02:00
|
|
|
// @astgen op1 := rangep : Optional[AstRange] // Range of variable
|
2024-01-20 21:06:46 +01:00
|
|
|
struct Members final {
|
2022-09-15 14:10:39 +02:00
|
|
|
VBasicDTypeKwd m_keyword; // (also in VBasicTypeKey) What keyword created basic type
|
|
|
|
|
VNumRange m_nrange; // (also in VBasicTypeKey) Numeric msb/lsb (if non-opaque keyword)
|
|
|
|
|
bool operator==(const Members& rhs) const {
|
|
|
|
|
return rhs.m_keyword == m_keyword && rhs.m_nrange == m_nrange;
|
|
|
|
|
}
|
|
|
|
|
} m;
|
|
|
|
|
// See also in AstNodeDType: m_width, m_widthMin, m_numeric(issigned)
|
|
|
|
|
public:
|
|
|
|
|
AstBasicDType(FileLine* fl, VBasicDTypeKwd kwd, const VSigning& signst = VSigning::NOSIGN)
|
|
|
|
|
: ASTGEN_SUPER_BasicDType(fl) {
|
|
|
|
|
init(kwd, signst, 0, -1, nullptr);
|
|
|
|
|
}
|
|
|
|
|
AstBasicDType(FileLine* fl, VFlagLogicPacked, int wantwidth)
|
|
|
|
|
: ASTGEN_SUPER_BasicDType(fl) {
|
|
|
|
|
init(VBasicDTypeKwd::LOGIC, VSigning::NOSIGN, wantwidth, -1, nullptr);
|
|
|
|
|
}
|
|
|
|
|
AstBasicDType(FileLine* fl, VFlagBitPacked, int wantwidth)
|
|
|
|
|
: ASTGEN_SUPER_BasicDType(fl) {
|
|
|
|
|
init(VBasicDTypeKwd::BIT, VSigning::NOSIGN, wantwidth, -1, nullptr);
|
|
|
|
|
}
|
|
|
|
|
AstBasicDType(FileLine* fl, VBasicDTypeKwd kwd, VSigning numer, int wantwidth, int widthmin)
|
|
|
|
|
: ASTGEN_SUPER_BasicDType(fl) {
|
|
|
|
|
init(kwd, numer, wantwidth, widthmin, nullptr);
|
|
|
|
|
}
|
|
|
|
|
AstBasicDType(FileLine* fl, VBasicDTypeKwd kwd, VSigning numer, VNumRange range, int widthmin)
|
|
|
|
|
: ASTGEN_SUPER_BasicDType(fl) {
|
|
|
|
|
init(kwd, numer, range.elements(), widthmin, nullptr);
|
|
|
|
|
m.m_nrange = range; // as init() presumes lsb==0, but range.lsb() might not be
|
|
|
|
|
}
|
|
|
|
|
// See also addRange in verilog.y
|
|
|
|
|
private:
|
|
|
|
|
void init(VBasicDTypeKwd kwd, VSigning numer, int wantwidth, int wantwidthmin,
|
|
|
|
|
AstRange* rangep);
|
|
|
|
|
|
|
|
|
|
public:
|
2022-10-04 12:03:41 +02:00
|
|
|
ASTGEN_MEMBERS_AstBasicDType;
|
2022-09-16 12:22:11 +02:00
|
|
|
void dump(std::ostream& str) const override;
|
2024-02-09 23:50:09 +01:00
|
|
|
void dumpJson(std::ostream& str) const override;
|
2022-09-15 14:10:39 +02:00
|
|
|
// width/widthMin/numeric compared elsewhere
|
2023-04-14 12:51:33 +02:00
|
|
|
bool same(const AstNode* samep) const override;
|
2022-12-02 00:47:09 +01:00
|
|
|
bool similarDType(const AstNodeDType* samep) const override {
|
2022-09-15 14:10:39 +02:00
|
|
|
return type() == samep->type() && same(samep);
|
|
|
|
|
}
|
2023-03-18 01:24:15 +01:00
|
|
|
string name() const override VL_MT_STABLE { return m.m_keyword.ascii(); }
|
2022-09-16 12:22:11 +02:00
|
|
|
string prettyDTypeName() const override;
|
|
|
|
|
const char* broken() const override {
|
2022-09-15 14:10:39 +02:00
|
|
|
BROKEN_RTN(dtypep() != this);
|
|
|
|
|
return nullptr;
|
|
|
|
|
}
|
|
|
|
|
void setSignedState(const VSigning& signst) {
|
|
|
|
|
// Note NOSIGN does NOT change the state; this is required by the parser
|
|
|
|
|
if (signst == VSigning::UNSIGNED) {
|
|
|
|
|
numeric(signst);
|
|
|
|
|
} else if (signst == VSigning::SIGNED) {
|
|
|
|
|
numeric(signst);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
// METHODS
|
2023-03-17 00:48:56 +01:00
|
|
|
AstBasicDType* basicp() const override VL_MT_STABLE { return (AstBasicDType*)this; }
|
|
|
|
|
AstNodeDType* skipRefp() const override VL_MT_STABLE { return (AstNodeDType*)this; }
|
2022-09-16 12:22:11 +02:00
|
|
|
AstNodeDType* skipRefToConstp() const override { return (AstNodeDType*)this; }
|
|
|
|
|
AstNodeDType* skipRefToEnump() const override { return (AstNodeDType*)this; }
|
2022-09-15 14:10:39 +02:00
|
|
|
// (Slow) recurses - Structure alignment 1,2,4 or 8 bytes (arrays affect this)
|
2022-09-16 12:22:11 +02:00
|
|
|
int widthAlignBytes() const override;
|
2022-09-15 14:10:39 +02:00
|
|
|
// (Slow) recurses - Width in bytes rounding up 1,2,4,8,12,...
|
2022-09-16 12:22:11 +02:00
|
|
|
int widthTotalBytes() const override;
|
|
|
|
|
bool isFourstate() const override { return keyword().isFourstate(); }
|
2022-10-18 23:07:09 +02:00
|
|
|
VBasicDTypeKwd keyword() const VL_MT_SAFE { // Avoid using - use isSomething accessors instead
|
2022-09-15 14:10:39 +02:00
|
|
|
return m.m_keyword;
|
|
|
|
|
}
|
|
|
|
|
bool isBitLogic() const { return keyword().isBitLogic(); }
|
2022-10-18 23:07:09 +02:00
|
|
|
bool isDouble() const VL_MT_SAFE { return keyword().isDouble(); }
|
|
|
|
|
bool isEvent() const VL_MT_SAFE { return keyword() == VBasicDTypeKwd::EVENT; }
|
|
|
|
|
bool isTriggerVec() const VL_MT_SAFE { return keyword() == VBasicDTypeKwd::TRIGGERVEC; }
|
|
|
|
|
bool isForkSync() const VL_MT_SAFE { return keyword() == VBasicDTypeKwd::FORK_SYNC; }
|
2023-06-01 16:02:08 +02:00
|
|
|
bool isProcessRef() const VL_MT_SAFE { return keyword() == VBasicDTypeKwd::PROCESS_REFERENCE; }
|
2022-10-18 23:07:09 +02:00
|
|
|
bool isDelayScheduler() const VL_MT_SAFE {
|
|
|
|
|
return keyword() == VBasicDTypeKwd::DELAY_SCHEDULER;
|
|
|
|
|
}
|
|
|
|
|
bool isTriggerScheduler() const VL_MT_SAFE {
|
|
|
|
|
return keyword() == VBasicDTypeKwd::TRIGGER_SCHEDULER;
|
|
|
|
|
}
|
2022-10-22 16:05:39 +02:00
|
|
|
bool isDynamicTriggerScheduler() const VL_MT_SAFE {
|
|
|
|
|
return keyword() == VBasicDTypeKwd::DYNAMIC_TRIGGER_SCHEDULER;
|
|
|
|
|
}
|
2022-10-18 23:07:09 +02:00
|
|
|
bool isOpaque() const VL_MT_SAFE { return keyword().isOpaque(); }
|
|
|
|
|
bool isString() const VL_MT_SAFE { return keyword().isString(); }
|
2022-09-15 14:10:39 +02:00
|
|
|
bool isZeroInit() const { return keyword().isZeroInit(); }
|
|
|
|
|
bool isRanged() const { return rangep() || m.m_nrange.ranged(); }
|
|
|
|
|
bool isDpiBitVec() const { // DPI uses svBitVecVal
|
|
|
|
|
return keyword() == VBasicDTypeKwd::BIT && isRanged();
|
|
|
|
|
}
|
|
|
|
|
bool isDpiLogicVec() const { // DPI uses svLogicVecVal
|
|
|
|
|
return keyword().isFourstate() && !(keyword() == VBasicDTypeKwd::LOGIC && !isRanged());
|
|
|
|
|
}
|
|
|
|
|
bool isDpiPrimitive() const { // DPI uses a primitive type
|
|
|
|
|
return !isDpiBitVec() && !isDpiLogicVec();
|
|
|
|
|
}
|
|
|
|
|
// Generally the lo/hi/left/right funcs should be used instead of nrange()
|
|
|
|
|
const VNumRange& nrange() const { return m.m_nrange; }
|
|
|
|
|
inline int hi() const;
|
|
|
|
|
inline int lo() const;
|
|
|
|
|
inline int elements() const;
|
2023-03-21 01:44:11 +01:00
|
|
|
int left() const { return ascending() ? lo() : hi(); } // How to show a declaration
|
|
|
|
|
int right() const { return ascending() ? hi() : lo(); }
|
|
|
|
|
inline bool ascending() const;
|
2022-09-15 14:10:39 +02:00
|
|
|
bool implicit() const { return keyword() == VBasicDTypeKwd::LOGIC_IMPLICIT; }
|
2022-11-01 23:53:47 +01:00
|
|
|
bool untyped() const { return keyword() == VBasicDTypeKwd::UNTYPED; }
|
2022-09-15 14:10:39 +02:00
|
|
|
VNumRange declRange() const { return isRanged() ? VNumRange{left(), right()} : VNumRange{}; }
|
|
|
|
|
void cvtRangeConst(); // Convert to smaller representation
|
2022-09-16 12:22:11 +02:00
|
|
|
bool isCompound() const override { return isString(); }
|
2023-02-12 22:32:36 +01:00
|
|
|
bool isIntegralOrPacked() const override { return keyword().isIntNumeric(); }
|
2022-09-15 14:10:39 +02:00
|
|
|
};
|
|
|
|
|
class AstBracketArrayDType final : public AstNodeDType {
|
|
|
|
|
// Associative/Queue/Normal array data type, ie "[dtype_or_expr]"
|
|
|
|
|
// only for early parsing then becomes another data type
|
2022-09-15 20:43:56 +02:00
|
|
|
// @astgen op1 := childDTypep : Optional[AstNodeDType] // moved to refDTypep() in V3Width
|
|
|
|
|
// @astgen op2 := elementsp : AstNode // ??? key dtype ???
|
2022-09-15 14:10:39 +02:00
|
|
|
public:
|
2022-09-15 20:43:56 +02:00
|
|
|
AstBracketArrayDType(FileLine* fl, VFlagChildDType, AstNodeDType* childDTypep,
|
|
|
|
|
AstNode* elementsp)
|
2022-09-15 14:10:39 +02:00
|
|
|
: ASTGEN_SUPER_BracketArrayDType(fl) {
|
2022-09-15 20:43:56 +02:00
|
|
|
this->childDTypep(childDTypep);
|
|
|
|
|
this->elementsp(elementsp);
|
2022-09-15 14:10:39 +02:00
|
|
|
}
|
2022-10-04 12:03:41 +02:00
|
|
|
ASTGEN_MEMBERS_AstBracketArrayDType;
|
2024-03-19 01:44:18 +01:00
|
|
|
bool similarDType(const AstNodeDType* samep) const override { return same(samep); }
|
2023-03-17 00:48:56 +01:00
|
|
|
AstNodeDType* subDTypep() const override VL_MT_STABLE { return childDTypep(); }
|
2022-09-15 14:10:39 +02:00
|
|
|
// METHODS
|
|
|
|
|
// Will be removed in V3Width, which relies on this
|
|
|
|
|
// being a child not a dtype pointed node
|
2022-09-16 12:22:11 +02:00
|
|
|
bool maybePointedTo() const override { return false; }
|
2023-03-17 00:48:56 +01:00
|
|
|
AstBasicDType* basicp() const override VL_MT_STABLE { return nullptr; }
|
|
|
|
|
AstNodeDType* skipRefp() const override VL_MT_STABLE { return (AstNodeDType*)this; }
|
2022-09-16 12:22:11 +02:00
|
|
|
AstNodeDType* skipRefToConstp() const override { return (AstNodeDType*)this; }
|
|
|
|
|
AstNodeDType* skipRefToEnump() const override { return (AstNodeDType*)this; }
|
|
|
|
|
int widthAlignBytes() const override { V3ERROR_NA_RETURN(0); }
|
|
|
|
|
int widthTotalBytes() const override { V3ERROR_NA_RETURN(0); }
|
|
|
|
|
bool isCompound() const override { return true; }
|
2022-09-15 14:10:39 +02:00
|
|
|
};
|
2023-09-19 03:17:21 +02:00
|
|
|
class AstCDType final : public AstNodeDType {
|
|
|
|
|
// Raw "C" data type passed directly to output
|
|
|
|
|
string m_name; // Name of data type, printed when do V3EmitC
|
|
|
|
|
public:
|
|
|
|
|
AstCDType(FileLine* fl, const string& name)
|
|
|
|
|
: ASTGEN_SUPER_CDType(fl)
|
|
|
|
|
, m_name{name} {
|
|
|
|
|
this->dtypep(this);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public:
|
|
|
|
|
ASTGEN_MEMBERS_AstCDType;
|
|
|
|
|
bool same(const AstNode* samep) const override {
|
2023-10-16 11:17:52 +02:00
|
|
|
const AstCDType* const asamep = VN_DBG_AS(samep, CDType);
|
2023-09-19 03:17:21 +02:00
|
|
|
return m_name == asamep->m_name;
|
|
|
|
|
}
|
|
|
|
|
bool similarDType(const AstNodeDType* samep) const override { return same(samep); }
|
|
|
|
|
string name() const override VL_MT_STABLE { return m_name; }
|
|
|
|
|
string prettyDTypeName() const override { return m_name; }
|
|
|
|
|
// METHODS
|
|
|
|
|
AstBasicDType* basicp() const override VL_MT_STABLE { return nullptr; }
|
|
|
|
|
AstNodeDType* skipRefp() const override VL_MT_STABLE { return (AstNodeDType*)this; }
|
|
|
|
|
AstNodeDType* skipRefToConstp() const override { return (AstNodeDType*)this; }
|
|
|
|
|
AstNodeDType* skipRefToEnump() const override { return (AstNodeDType*)this; }
|
|
|
|
|
int widthAlignBytes() const override { return 8; } // Assume
|
|
|
|
|
int widthTotalBytes() const override { return 8; } // Assume
|
|
|
|
|
bool isCompound() const override { return true; }
|
2024-03-03 16:23:04 +01:00
|
|
|
static string typeToHold(int width) {
|
|
|
|
|
if (width <= 8)
|
|
|
|
|
return "CData";
|
|
|
|
|
else if (width <= 16)
|
|
|
|
|
return "SData";
|
|
|
|
|
else if (width <= VL_IDATASIZE)
|
|
|
|
|
return "IData";
|
|
|
|
|
else if (width <= VL_QUADSIZE)
|
|
|
|
|
return "QData";
|
|
|
|
|
else
|
|
|
|
|
return "VlWide<" + std::to_string(VL_WORDS_I(width)) + ">";
|
2023-09-19 03:17:21 +02:00
|
|
|
}
|
|
|
|
|
};
|
2022-09-15 14:10:39 +02:00
|
|
|
class AstClassRefDType final : public AstNodeDType {
|
|
|
|
|
// Reference to a class
|
2022-09-15 20:43:56 +02:00
|
|
|
// @astgen op1 := paramsp: List[AstPin]
|
2023-12-01 01:58:16 +01:00
|
|
|
//
|
|
|
|
|
// @astgen ptr := m_classp : Optional[AstClass] // data type pointed to, BELOW the AstTypedef
|
|
|
|
|
// @astgen ptr := m_classOrPackagep : Optional[AstNodeModule] // Package hierarchy
|
2022-09-15 14:10:39 +02:00
|
|
|
public:
|
2022-09-15 20:43:56 +02:00
|
|
|
AstClassRefDType(FileLine* fl, AstClass* classp, AstPin* paramsp)
|
2022-09-15 14:10:39 +02:00
|
|
|
: ASTGEN_SUPER_ClassRefDType(fl)
|
|
|
|
|
, m_classp{classp} {
|
2022-09-15 20:43:56 +02:00
|
|
|
this->dtypep(this);
|
|
|
|
|
this->addParamsp(paramsp);
|
2022-09-15 14:10:39 +02:00
|
|
|
}
|
2022-10-04 12:03:41 +02:00
|
|
|
ASTGEN_MEMBERS_AstClassRefDType;
|
2022-09-15 14:10:39 +02:00
|
|
|
// METHODS
|
2022-09-16 12:22:11 +02:00
|
|
|
bool same(const AstNode* samep) const override {
|
2023-10-16 11:17:52 +02:00
|
|
|
const AstClassRefDType* const asamep = VN_DBG_AS(samep, ClassRefDType);
|
2022-09-15 14:10:39 +02:00
|
|
|
return (m_classp == asamep->m_classp && m_classOrPackagep == asamep->m_classOrPackagep);
|
|
|
|
|
}
|
2022-12-02 00:47:09 +01:00
|
|
|
bool similarDType(const AstNodeDType* samep) const override {
|
2022-09-15 14:10:39 +02:00
|
|
|
return this == samep || (type() == samep->type() && same(samep));
|
|
|
|
|
}
|
2022-09-16 12:22:11 +02:00
|
|
|
void dump(std::ostream& str = std::cout) const override;
|
2024-02-09 23:50:09 +01:00
|
|
|
void dumpJson(std::ostream& str = std::cout) const override;
|
2022-09-16 12:22:11 +02:00
|
|
|
void dumpSmall(std::ostream& str) const override;
|
2023-03-18 01:24:15 +01:00
|
|
|
string name() const override VL_MT_STABLE;
|
2023-03-17 00:48:56 +01:00
|
|
|
AstBasicDType* basicp() const override VL_MT_STABLE { return nullptr; }
|
|
|
|
|
AstNodeDType* skipRefp() const override VL_MT_STABLE { return (AstNodeDType*)this; }
|
2022-09-16 12:22:11 +02:00
|
|
|
AstNodeDType* skipRefToConstp() const override { return (AstNodeDType*)this; }
|
|
|
|
|
AstNodeDType* skipRefToEnump() const override { return (AstNodeDType*)this; }
|
|
|
|
|
int widthAlignBytes() const override { return 0; }
|
|
|
|
|
int widthTotalBytes() const override { return 0; }
|
|
|
|
|
AstNodeDType* virtRefDTypep() const override { return nullptr; }
|
|
|
|
|
void virtRefDTypep(AstNodeDType* nodep) override {}
|
2023-03-17 00:48:56 +01:00
|
|
|
AstNodeDType* subDTypep() const override VL_MT_SAFE { return nullptr; }
|
2022-09-15 14:10:39 +02:00
|
|
|
AstNodeModule* classOrPackagep() const { return m_classOrPackagep; }
|
|
|
|
|
void classOrPackagep(AstNodeModule* nodep) { m_classOrPackagep = nodep; }
|
2023-03-18 01:24:15 +01:00
|
|
|
AstClass* classp() const VL_MT_STABLE { return m_classp; }
|
2022-09-15 14:10:39 +02:00
|
|
|
void classp(AstClass* nodep) { m_classp = nodep; }
|
2022-09-16 12:22:11 +02:00
|
|
|
bool isCompound() const override { return true; }
|
2022-09-15 14:10:39 +02:00
|
|
|
};
|
|
|
|
|
class AstConstDType final : public AstNodeDType {
|
|
|
|
|
// const data type, ie "const some_dtype var_name [2:0]"
|
|
|
|
|
// ConstDType are removed in V3LinkLValue and become AstVar::isConst.
|
|
|
|
|
// When more generic types are supported AstConstDType will be propagated further.
|
2022-09-15 20:43:56 +02:00
|
|
|
// @astgen op1 := childDTypep : Optional[AstNodeDType]
|
2023-12-01 01:58:16 +01:00
|
|
|
//
|
|
|
|
|
// @astgen ptr := m_refDTypep : Optional[AstNodeDType] // Inherit from this base data type
|
2022-09-15 14:10:39 +02:00
|
|
|
public:
|
|
|
|
|
AstConstDType(FileLine* fl, VFlagChildDType, AstNodeDType* dtp)
|
|
|
|
|
: ASTGEN_SUPER_ConstDType(fl) {
|
|
|
|
|
childDTypep(dtp); // Only for parser
|
|
|
|
|
refDTypep(nullptr); // V3Width will resolve
|
|
|
|
|
dtypep(nullptr); // V3Width will resolve
|
|
|
|
|
widthFromSub(subDTypep());
|
|
|
|
|
}
|
2022-10-04 12:03:41 +02:00
|
|
|
ASTGEN_MEMBERS_AstConstDType;
|
2022-09-16 12:22:11 +02:00
|
|
|
const char* broken() const override {
|
2023-12-01 01:58:16 +01:00
|
|
|
BROKEN_RTN(!((m_refDTypep && !childDTypep()) || (!m_refDTypep && childDTypep())));
|
2022-09-15 14:10:39 +02:00
|
|
|
return nullptr;
|
|
|
|
|
}
|
2022-09-16 12:22:11 +02:00
|
|
|
bool same(const AstNode* samep) const override {
|
2023-10-16 11:17:52 +02:00
|
|
|
const AstConstDType* const sp = VN_DBG_AS(samep, ConstDType);
|
2022-09-15 14:10:39 +02:00
|
|
|
return (m_refDTypep == sp->m_refDTypep);
|
|
|
|
|
}
|
2022-12-02 00:47:09 +01:00
|
|
|
bool similarDType(const AstNodeDType* samep) const override {
|
2022-09-15 14:10:39 +02:00
|
|
|
return skipRefp()->similarDType(samep->skipRefp());
|
|
|
|
|
}
|
2022-09-16 12:22:11 +02:00
|
|
|
AstNodeDType* getChildDTypep() const override { return childDTypep(); }
|
2023-03-17 00:48:56 +01:00
|
|
|
AstNodeDType* subDTypep() const override VL_MT_STABLE {
|
|
|
|
|
return m_refDTypep ? m_refDTypep : childDTypep();
|
|
|
|
|
}
|
2022-09-15 14:10:39 +02:00
|
|
|
void refDTypep(AstNodeDType* nodep) { m_refDTypep = nodep; }
|
2022-09-16 12:22:11 +02:00
|
|
|
AstNodeDType* virtRefDTypep() const override { return m_refDTypep; }
|
|
|
|
|
void virtRefDTypep(AstNodeDType* nodep) override { refDTypep(nodep); }
|
2022-09-15 14:10:39 +02:00
|
|
|
// METHODS
|
2023-03-17 00:48:56 +01:00
|
|
|
AstBasicDType* basicp() const override VL_MT_STABLE { return subDTypep()->basicp(); }
|
|
|
|
|
AstNodeDType* skipRefp() const override VL_MT_STABLE { return subDTypep()->skipRefp(); }
|
2022-09-16 12:22:11 +02:00
|
|
|
AstNodeDType* skipRefToConstp() const override { return (AstNodeDType*)this; }
|
|
|
|
|
AstNodeDType* skipRefToEnump() const override { return subDTypep()->skipRefToEnump(); }
|
|
|
|
|
int widthAlignBytes() const override { return subDTypep()->widthAlignBytes(); }
|
|
|
|
|
int widthTotalBytes() const override { return subDTypep()->widthTotalBytes(); }
|
|
|
|
|
bool isCompound() const override {
|
2022-09-15 14:10:39 +02:00
|
|
|
v3fatalSrc("call isCompound on subdata type, not reference");
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
};
|
2023-11-12 02:20:37 +01:00
|
|
|
class AstConstraintRefDType final : public AstNodeDType {
|
|
|
|
|
// For e.g. a reference to constraint for constraint_mode
|
|
|
|
|
public:
|
|
|
|
|
explicit AstConstraintRefDType(FileLine* fl)
|
|
|
|
|
: ASTGEN_SUPER_ConstraintRefDType(fl) {
|
|
|
|
|
dtypep(this);
|
|
|
|
|
}
|
|
|
|
|
ASTGEN_MEMBERS_AstConstraintRefDType;
|
|
|
|
|
bool hasDType() const override { return true; }
|
|
|
|
|
bool maybePointedTo() const override { return true; }
|
|
|
|
|
bool undead() const override { return true; }
|
|
|
|
|
AstNodeDType* subDTypep() const override VL_MT_SAFE { return nullptr; }
|
|
|
|
|
AstNodeDType* virtRefDTypep() const override { return nullptr; }
|
|
|
|
|
void virtRefDTypep(AstNodeDType* nodep) override {}
|
|
|
|
|
bool similarDType(const AstNodeDType* samep) const override { return this == samep; }
|
|
|
|
|
AstBasicDType* basicp() const override VL_MT_STABLE { return nullptr; }
|
|
|
|
|
// cppcheck-suppress csyleCast
|
|
|
|
|
AstNodeDType* skipRefp() const override VL_MT_STABLE { return (AstNodeDType*)this; }
|
|
|
|
|
// cppcheck-suppress csyleCast
|
|
|
|
|
AstNodeDType* skipRefToConstp() const override { return (AstNodeDType*)this; }
|
|
|
|
|
// cppcheck-suppress csyleCast
|
|
|
|
|
AstNodeDType* skipRefToEnump() const override { return (AstNodeDType*)this; }
|
|
|
|
|
int widthAlignBytes() const override { return 1; }
|
|
|
|
|
int widthTotalBytes() const override { return 1; }
|
|
|
|
|
bool isCompound() const override { return false; }
|
|
|
|
|
};
|
2022-09-15 14:10:39 +02:00
|
|
|
class AstDefImplicitDType final : public AstNodeDType {
|
|
|
|
|
// For parsing enum/struct/unions that are declared with a variable rather than typedef
|
|
|
|
|
// This allows "var enum {...} a,b" to share the enum definition for both variables
|
|
|
|
|
// After link, these become typedefs
|
2022-09-15 20:43:56 +02:00
|
|
|
// @astgen op1 := childDTypep : Optional[AstNodeDType]
|
2022-09-15 14:10:39 +02:00
|
|
|
string m_name;
|
|
|
|
|
void* m_containerp; // In what scope is the name unique, so we can know what are duplicate
|
|
|
|
|
// definitions (arbitrary value)
|
|
|
|
|
const int m_uniqueNum;
|
|
|
|
|
|
|
|
|
|
public:
|
|
|
|
|
AstDefImplicitDType(FileLine* fl, const string& name, void* containerp, VFlagChildDType,
|
|
|
|
|
AstNodeDType* dtp)
|
|
|
|
|
: ASTGEN_SUPER_DefImplicitDType(fl)
|
|
|
|
|
, m_name{name}
|
|
|
|
|
, m_containerp{containerp}
|
|
|
|
|
, m_uniqueNum{uniqueNumInc()} {
|
|
|
|
|
childDTypep(dtp); // Only for parser
|
|
|
|
|
dtypep(nullptr); // V3Width will resolve
|
|
|
|
|
}
|
2022-10-04 12:03:41 +02:00
|
|
|
ASTGEN_MEMBERS_AstDefImplicitDType;
|
2022-09-15 14:10:39 +02:00
|
|
|
int uniqueNum() const { return m_uniqueNum; }
|
2022-09-16 12:22:11 +02:00
|
|
|
bool same(const AstNode* samep) const override {
|
2023-10-16 11:17:52 +02:00
|
|
|
const AstDefImplicitDType* const sp = VN_DBG_AS(samep, DefImplicitDType);
|
2022-09-15 14:10:39 +02:00
|
|
|
return uniqueNum() == sp->uniqueNum();
|
|
|
|
|
}
|
2022-12-02 00:47:09 +01:00
|
|
|
bool similarDType(const AstNodeDType* samep) const override {
|
2022-09-15 14:10:39 +02:00
|
|
|
return type() == samep->type() && same(samep);
|
|
|
|
|
}
|
2022-09-16 12:22:11 +02:00
|
|
|
AstNodeDType* getChildDTypep() const override { return childDTypep(); }
|
2023-03-17 00:48:56 +01:00
|
|
|
AstNodeDType* subDTypep() const override VL_MT_STABLE {
|
|
|
|
|
return dtypep() ? dtypep() : childDTypep();
|
|
|
|
|
}
|
2022-09-15 14:10:39 +02:00
|
|
|
void* containerp() const { return m_containerp; }
|
|
|
|
|
// METHODS
|
|
|
|
|
// op1 = Range of variable
|
|
|
|
|
AstNodeDType* dtypeSkipRefp() const { return dtypep()->skipRefp(); }
|
2023-03-17 00:48:56 +01:00
|
|
|
AstBasicDType* basicp() const override VL_MT_STABLE { return subDTypep()->basicp(); }
|
|
|
|
|
AstNodeDType* skipRefp() const override VL_MT_STABLE { return (AstNodeDType*)this; }
|
2022-09-16 12:22:11 +02:00
|
|
|
AstNodeDType* skipRefToConstp() const override { return (AstNodeDType*)this; }
|
|
|
|
|
AstNodeDType* skipRefToEnump() const override { return (AstNodeDType*)this; }
|
|
|
|
|
int widthAlignBytes() const override { return dtypep()->widthAlignBytes(); }
|
|
|
|
|
int widthTotalBytes() const override { return dtypep()->widthTotalBytes(); }
|
2023-03-18 01:24:15 +01:00
|
|
|
string name() const override VL_MT_STABLE { return m_name; }
|
2022-09-16 12:22:11 +02:00
|
|
|
void name(const string& flag) override { m_name = flag; }
|
|
|
|
|
bool isCompound() const override { return false; }
|
2022-09-15 14:10:39 +02:00
|
|
|
};
|
|
|
|
|
class AstDynArrayDType final : public AstNodeDType {
|
|
|
|
|
// Dynamic array data type, ie "[]"
|
2022-09-15 20:43:56 +02:00
|
|
|
// @astgen op1 := childDTypep : Optional[AstNodeDType] // moved to refDTypep() in V3Width
|
2023-12-01 01:58:16 +01:00
|
|
|
//
|
|
|
|
|
// @astgen ptr := m_refDTypep : Optional[AstNodeDType] // Elements of this type (post-width)
|
2022-09-15 14:10:39 +02:00
|
|
|
public:
|
|
|
|
|
AstDynArrayDType(FileLine* fl, VFlagChildDType, AstNodeDType* dtp)
|
|
|
|
|
: ASTGEN_SUPER_DynArrayDType(fl) {
|
|
|
|
|
childDTypep(dtp); // Only for parser
|
|
|
|
|
refDTypep(nullptr);
|
|
|
|
|
dtypep(nullptr); // V3Width will resolve
|
|
|
|
|
}
|
|
|
|
|
AstDynArrayDType(FileLine* fl, AstNodeDType* dtp)
|
|
|
|
|
: ASTGEN_SUPER_DynArrayDType(fl) {
|
|
|
|
|
refDTypep(dtp);
|
|
|
|
|
dtypep(nullptr); // V3Width will resolve
|
|
|
|
|
}
|
2022-10-04 12:03:41 +02:00
|
|
|
ASTGEN_MEMBERS_AstDynArrayDType;
|
2022-09-16 12:22:11 +02:00
|
|
|
const char* broken() const override {
|
2023-12-01 01:58:16 +01:00
|
|
|
BROKEN_RTN(!((m_refDTypep && !childDTypep()) || (!m_refDTypep && childDTypep())));
|
2022-09-15 14:10:39 +02:00
|
|
|
return nullptr;
|
|
|
|
|
}
|
2022-09-16 12:22:11 +02:00
|
|
|
bool same(const AstNode* samep) const override {
|
2023-10-16 11:17:52 +02:00
|
|
|
const AstDynArrayDType* const asamep = VN_DBG_AS(samep, DynArrayDType);
|
2022-09-15 14:10:39 +02:00
|
|
|
if (!asamep->subDTypep()) return false;
|
|
|
|
|
return subDTypep() == asamep->subDTypep();
|
|
|
|
|
}
|
2022-12-02 00:47:09 +01:00
|
|
|
bool similarDType(const AstNodeDType* samep) const override {
|
2023-10-16 11:17:52 +02:00
|
|
|
if (type() != samep->type()) return false;
|
|
|
|
|
const AstDynArrayDType* const asamep = VN_DBG_AS(samep, DynArrayDType);
|
|
|
|
|
return asamep->subDTypep()
|
2022-09-15 14:10:39 +02:00
|
|
|
&& subDTypep()->skipRefp()->similarDType(asamep->subDTypep()->skipRefp());
|
|
|
|
|
}
|
2022-09-16 12:22:11 +02:00
|
|
|
string prettyDTypeName() const override;
|
|
|
|
|
void dumpSmall(std::ostream& str) const override;
|
|
|
|
|
AstNodeDType* getChildDTypep() const override { return childDTypep(); }
|
2023-03-17 00:48:56 +01:00
|
|
|
AstNodeDType* subDTypep() const override VL_MT_STABLE {
|
2022-10-18 23:07:09 +02:00
|
|
|
return m_refDTypep ? m_refDTypep : childDTypep();
|
|
|
|
|
}
|
2022-09-15 14:10:39 +02:00
|
|
|
void refDTypep(AstNodeDType* nodep) { m_refDTypep = nodep; }
|
2022-09-16 12:22:11 +02:00
|
|
|
AstNodeDType* virtRefDTypep() const override { return m_refDTypep; }
|
|
|
|
|
void virtRefDTypep(AstNodeDType* nodep) override { refDTypep(nodep); }
|
2022-09-15 14:10:39 +02:00
|
|
|
// METHODS
|
2023-03-17 00:48:56 +01:00
|
|
|
AstBasicDType* basicp() const override VL_MT_STABLE { return nullptr; }
|
|
|
|
|
AstNodeDType* skipRefp() const override VL_MT_STABLE { return (AstNodeDType*)this; }
|
2022-09-16 12:22:11 +02:00
|
|
|
AstNodeDType* skipRefToConstp() const override { return (AstNodeDType*)this; }
|
|
|
|
|
AstNodeDType* skipRefToEnump() const override { return (AstNodeDType*)this; }
|
|
|
|
|
int widthAlignBytes() const override { return subDTypep()->widthAlignBytes(); }
|
|
|
|
|
int widthTotalBytes() const override { return subDTypep()->widthTotalBytes(); }
|
|
|
|
|
bool isCompound() const override { return true; }
|
2022-09-15 14:10:39 +02:00
|
|
|
};
|
|
|
|
|
class AstEmptyQueueDType final : public AstNodeDType {
|
|
|
|
|
// For EmptyQueue
|
|
|
|
|
public:
|
|
|
|
|
explicit AstEmptyQueueDType(FileLine* fl)
|
|
|
|
|
: ASTGEN_SUPER_EmptyQueueDType(fl) {
|
|
|
|
|
dtypep(this);
|
|
|
|
|
}
|
2022-10-04 12:03:41 +02:00
|
|
|
ASTGEN_MEMBERS_AstEmptyQueueDType;
|
2022-09-16 12:22:11 +02:00
|
|
|
void dumpSmall(std::ostream& str) const override;
|
|
|
|
|
bool hasDType() const override { return true; }
|
|
|
|
|
bool maybePointedTo() const override { return true; }
|
|
|
|
|
bool undead() const override { return true; }
|
2023-03-17 00:48:56 +01:00
|
|
|
AstNodeDType* subDTypep() const override VL_MT_SAFE { return nullptr; }
|
2022-09-16 12:22:11 +02:00
|
|
|
AstNodeDType* virtRefDTypep() const override { return nullptr; }
|
|
|
|
|
void virtRefDTypep(AstNodeDType* nodep) override {}
|
2022-12-02 00:47:09 +01:00
|
|
|
bool similarDType(const AstNodeDType* samep) const override { return this == samep; }
|
2023-03-17 00:48:56 +01:00
|
|
|
AstBasicDType* basicp() const override VL_MT_STABLE { return nullptr; }
|
2022-09-15 14:10:39 +02:00
|
|
|
// cppcheck-suppress csyleCast
|
2023-03-17 00:48:56 +01:00
|
|
|
AstNodeDType* skipRefp() const override VL_MT_STABLE { return (AstNodeDType*)this; }
|
2022-09-15 14:10:39 +02:00
|
|
|
// cppcheck-suppress csyleCast
|
2022-09-16 12:22:11 +02:00
|
|
|
AstNodeDType* skipRefToConstp() const override { return (AstNodeDType*)this; }
|
2022-09-15 14:10:39 +02:00
|
|
|
// cppcheck-suppress csyleCast
|
2022-09-16 12:22:11 +02:00
|
|
|
AstNodeDType* skipRefToEnump() const override { return (AstNodeDType*)this; }
|
|
|
|
|
int widthAlignBytes() const override { return 1; }
|
|
|
|
|
int widthTotalBytes() const override { return 1; }
|
|
|
|
|
bool isCompound() const override { return false; }
|
2022-09-15 14:10:39 +02:00
|
|
|
};
|
|
|
|
|
class AstEnumDType final : public AstNodeDType {
|
|
|
|
|
// Parents: TYPEDEF/MODULE
|
2022-09-15 20:43:56 +02:00
|
|
|
// @astgen op1 := childDTypep : Optional[AstNodeDType]
|
|
|
|
|
// @astgen op2 := itemsp : List[AstEnumItem]
|
2023-12-01 01:58:16 +01:00
|
|
|
//
|
|
|
|
|
// @astgen ptr := m_refDTypep : Optional[AstNodeDType] // Elements of this type (post-width)
|
2023-10-07 04:38:46 +02:00
|
|
|
public:
|
|
|
|
|
using TableMap = std::map<VAttrType, AstVar*>;
|
|
|
|
|
|
2022-09-15 14:10:39 +02:00
|
|
|
private:
|
|
|
|
|
string m_name; // Name from upper typedef, if any
|
|
|
|
|
const int m_uniqueNum = 0;
|
2023-10-07 04:38:46 +02:00
|
|
|
TableMap m_tableMap; // Created table for V3Width only to remove duplicates
|
2022-09-15 14:10:39 +02:00
|
|
|
|
|
|
|
|
public:
|
2022-09-15 20:43:56 +02:00
|
|
|
AstEnumDType(FileLine* fl, VFlagChildDType, AstNodeDType* dtp, AstEnumItem* itemsp)
|
2022-09-15 14:10:39 +02:00
|
|
|
: ASTGEN_SUPER_EnumDType(fl)
|
|
|
|
|
, m_uniqueNum{uniqueNumInc()} {
|
|
|
|
|
childDTypep(dtp); // Only for parser
|
|
|
|
|
refDTypep(nullptr);
|
2022-09-15 20:43:56 +02:00
|
|
|
addItemsp(itemsp);
|
2022-09-15 14:10:39 +02:00
|
|
|
dtypep(nullptr); // V3Width will resolve
|
|
|
|
|
widthFromSub(subDTypep());
|
|
|
|
|
}
|
2022-10-04 12:03:41 +02:00
|
|
|
ASTGEN_MEMBERS_AstEnumDType;
|
2023-10-07 04:38:46 +02:00
|
|
|
|
2023-11-06 13:13:31 +01:00
|
|
|
const char* broken() const override;
|
2022-09-15 14:10:39 +02:00
|
|
|
int uniqueNum() const { return m_uniqueNum; }
|
2022-09-16 12:22:11 +02:00
|
|
|
bool same(const AstNode* samep) const override {
|
2023-10-16 11:17:52 +02:00
|
|
|
const AstEnumDType* const sp = VN_DBG_AS(samep, EnumDType);
|
2022-09-15 14:10:39 +02:00
|
|
|
return uniqueNum() == sp->uniqueNum();
|
|
|
|
|
}
|
2022-12-02 00:47:09 +01:00
|
|
|
bool similarDType(const AstNodeDType* samep) const override { return this == samep; }
|
2022-09-16 12:22:11 +02:00
|
|
|
AstNodeDType* getChildDTypep() const override { return childDTypep(); }
|
2023-03-17 00:48:56 +01:00
|
|
|
AstNodeDType* subDTypep() const override VL_MT_STABLE {
|
|
|
|
|
return m_refDTypep ? m_refDTypep : childDTypep();
|
|
|
|
|
}
|
2022-09-15 14:10:39 +02:00
|
|
|
void refDTypep(AstNodeDType* nodep) { m_refDTypep = nodep; }
|
2022-09-16 12:22:11 +02:00
|
|
|
AstNodeDType* virtRefDTypep() const override { return m_refDTypep; }
|
|
|
|
|
void virtRefDTypep(AstNodeDType* nodep) override { refDTypep(nodep); }
|
2023-03-18 01:24:15 +01:00
|
|
|
string name() const override VL_MT_STABLE { return m_name; }
|
2022-09-16 12:22:11 +02:00
|
|
|
void name(const string& flag) override { m_name = flag; }
|
2022-11-19 19:23:28 +01:00
|
|
|
void dump(std::ostream& str = std::cout) const override;
|
2024-02-09 23:50:09 +01:00
|
|
|
void dumpJson(std::ostream& str = std::cout) const override;
|
2022-11-19 19:23:28 +01:00
|
|
|
void dumpSmall(std::ostream& str) const override;
|
2022-09-15 14:10:39 +02:00
|
|
|
// METHODS
|
2023-03-17 00:48:56 +01:00
|
|
|
AstBasicDType* basicp() const override VL_MT_STABLE { return subDTypep()->basicp(); }
|
|
|
|
|
AstNodeDType* skipRefp() const override VL_MT_STABLE { return subDTypep()->skipRefp(); }
|
2022-09-16 12:22:11 +02:00
|
|
|
AstNodeDType* skipRefToConstp() const override { return subDTypep()->skipRefToConstp(); }
|
2022-09-15 14:10:39 +02:00
|
|
|
// cppcheck-suppress csyleCast
|
2022-09-16 12:22:11 +02:00
|
|
|
AstNodeDType* skipRefToEnump() const override { return (AstNodeDType*)this; }
|
|
|
|
|
int widthAlignBytes() const override { return subDTypep()->widthAlignBytes(); }
|
|
|
|
|
int widthTotalBytes() const override { return subDTypep()->widthTotalBytes(); }
|
2022-09-15 14:10:39 +02:00
|
|
|
int itemCount() const {
|
|
|
|
|
size_t count = 0;
|
|
|
|
|
for (AstNode* itemp = itemsp(); itemp; itemp = itemp->nextp()) count++;
|
|
|
|
|
return count;
|
|
|
|
|
}
|
2022-09-16 12:22:11 +02:00
|
|
|
bool isCompound() const override { return false; }
|
2023-10-07 04:38:46 +02:00
|
|
|
TableMap& tableMap() { return m_tableMap; }
|
|
|
|
|
const TableMap& tableMap() const { return m_tableMap; }
|
2022-09-15 14:10:39 +02:00
|
|
|
};
|
2023-12-21 13:49:07 +01:00
|
|
|
|
2022-09-15 14:10:39 +02:00
|
|
|
class AstIfaceRefDType final : public AstNodeDType {
|
|
|
|
|
// Reference to an interface, either for a port, or inside parent cell
|
2022-10-20 12:31:00 +02:00
|
|
|
// @astgen op1 := paramsp : List[AstPin]
|
2023-12-01 01:58:16 +01:00
|
|
|
//
|
|
|
|
|
// @astgen ptr := m_ifacep : Optional[AstIface] // Interface; cellp() should override
|
|
|
|
|
// @astgen ptr := m_cellp : Optional[AstCell] // When exact parent cell known; not a guess
|
|
|
|
|
// @astgen ptr := m_modportp : Optional[AstModport] // nullptr = unlinked or no modport
|
2023-12-05 04:11:07 +01:00
|
|
|
bool m_virtual = false; // True if virtual interface
|
2022-09-15 14:10:39 +02:00
|
|
|
FileLine* m_modportFileline; // Where modport token was
|
|
|
|
|
string m_cellName; // "" = no cell, such as when connects to 'input' iface
|
|
|
|
|
string m_ifaceName; // Interface name
|
|
|
|
|
string m_modportName; // "" = no modport
|
|
|
|
|
public:
|
|
|
|
|
AstIfaceRefDType(FileLine* fl, const string& cellName, const string& ifaceName)
|
|
|
|
|
: ASTGEN_SUPER_IfaceRefDType(fl)
|
|
|
|
|
, m_modportFileline{nullptr}
|
|
|
|
|
, m_cellName{cellName}
|
|
|
|
|
, m_ifaceName{ifaceName}
|
|
|
|
|
, m_modportName{""} {}
|
|
|
|
|
AstIfaceRefDType(FileLine* fl, FileLine* modportFl, const string& cellName,
|
|
|
|
|
const string& ifaceName, const string& modport)
|
|
|
|
|
: ASTGEN_SUPER_IfaceRefDType(fl)
|
|
|
|
|
, m_modportFileline{modportFl}
|
|
|
|
|
, m_cellName{cellName}
|
|
|
|
|
, m_ifaceName{ifaceName}
|
|
|
|
|
, m_modportName{modport} {}
|
2022-10-20 12:31:00 +02:00
|
|
|
AstIfaceRefDType(FileLine* fl, FileLine* modportFl, const string& cellName,
|
|
|
|
|
const string& ifaceName, const string& modport, AstPin* paramsp)
|
|
|
|
|
: ASTGEN_SUPER_IfaceRefDType(fl)
|
|
|
|
|
, m_modportFileline{modportFl}
|
|
|
|
|
, m_cellName{cellName}
|
|
|
|
|
, m_ifaceName{ifaceName} {
|
|
|
|
|
addParamsp(paramsp);
|
|
|
|
|
}
|
2022-10-04 12:03:41 +02:00
|
|
|
ASTGEN_MEMBERS_AstIfaceRefDType;
|
2023-12-21 13:49:07 +01:00
|
|
|
|
2022-09-15 14:10:39 +02:00
|
|
|
// METHODS
|
2022-09-16 12:22:11 +02:00
|
|
|
void dump(std::ostream& str = std::cout) const override;
|
2024-02-09 23:50:09 +01:00
|
|
|
void dumpJson(std::ostream& str = std::cout) const override;
|
2022-09-16 12:22:11 +02:00
|
|
|
void dumpSmall(std::ostream& str) const override;
|
2023-03-17 00:48:56 +01:00
|
|
|
AstBasicDType* basicp() const override VL_MT_STABLE { return nullptr; }
|
|
|
|
|
AstNodeDType* skipRefp() const override VL_MT_STABLE { return (AstNodeDType*)this; }
|
2022-09-16 12:22:11 +02:00
|
|
|
AstNodeDType* skipRefToConstp() const override { return (AstNodeDType*)this; }
|
|
|
|
|
AstNodeDType* skipRefToEnump() const override { return (AstNodeDType*)this; }
|
2022-12-02 00:47:09 +01:00
|
|
|
bool similarDType(const AstNodeDType* samep) const override { return this == samep; }
|
2022-09-16 12:22:11 +02:00
|
|
|
int widthAlignBytes() const override { return 1; }
|
|
|
|
|
int widthTotalBytes() const override { return 1; }
|
2023-12-05 04:11:07 +01:00
|
|
|
void isVirtual(bool flag) {
|
|
|
|
|
m_virtual = flag;
|
|
|
|
|
if (flag) v3Global.setHasVirtIfaces();
|
|
|
|
|
}
|
|
|
|
|
bool isVirtual() const { return m_virtual; }
|
2022-09-15 14:10:39 +02:00
|
|
|
FileLine* modportFileline() const { return m_modportFileline; }
|
|
|
|
|
string cellName() const { return m_cellName; }
|
|
|
|
|
void cellName(const string& name) { m_cellName = name; }
|
|
|
|
|
string ifaceName() const { return m_ifaceName; }
|
|
|
|
|
void ifaceName(const string& name) { m_ifaceName = name; }
|
|
|
|
|
string modportName() const { return m_modportName; }
|
|
|
|
|
AstIface* ifaceViaCellp() const; // Use cellp or ifacep
|
|
|
|
|
AstIface* ifacep() const { return m_ifacep; }
|
|
|
|
|
void ifacep(AstIface* nodep) { m_ifacep = nodep; }
|
|
|
|
|
AstCell* cellp() const { return m_cellp; }
|
|
|
|
|
void cellp(AstCell* nodep) { m_cellp = nodep; }
|
|
|
|
|
AstModport* modportp() const { return m_modportp; }
|
|
|
|
|
void modportp(AstModport* modportp) { m_modportp = modportp; }
|
|
|
|
|
bool isModport() { return !m_modportName.empty(); }
|
2022-09-16 12:22:11 +02:00
|
|
|
bool isCompound() const override { return true; } // But not relevant
|
2022-09-15 14:10:39 +02:00
|
|
|
};
|
|
|
|
|
class AstMemberDType final : public AstNodeDType {
|
|
|
|
|
// A member of a struct/union
|
|
|
|
|
// PARENT: AstNodeUOrStructDType
|
2022-09-15 20:43:56 +02:00
|
|
|
// @astgen op1 := childDTypep : Optional[AstNodeDType]
|
2023-02-14 02:58:49 +01:00
|
|
|
// @astgen op3 := valuep : Optional[AstNode]
|
2023-12-01 01:58:16 +01:00
|
|
|
//
|
|
|
|
|
// @astgen ptr := m_refDTypep : Optional[AstNodeDType] // Elements of this type (post-width)
|
2022-09-15 14:10:39 +02:00
|
|
|
string m_name; // Name of variable
|
|
|
|
|
string m_tag; // Holds the string of the verilator tag -- used in XML output.
|
|
|
|
|
int m_lsb = -1; // Within this level's packed struct, the LSB of the first bit of the member
|
|
|
|
|
// UNSUP: int m_randType; // Randomization type (IEEE)
|
|
|
|
|
public:
|
2023-02-14 02:58:49 +01:00
|
|
|
AstMemberDType(FileLine* fl, const string& name, VFlagChildDType, AstNodeDType* dtp,
|
|
|
|
|
AstNode* valuep)
|
2022-09-15 14:10:39 +02:00
|
|
|
: ASTGEN_SUPER_MemberDType(fl)
|
|
|
|
|
, m_name{name} {
|
|
|
|
|
childDTypep(dtp); // Only for parser
|
2023-02-14 02:58:49 +01:00
|
|
|
this->valuep(valuep);
|
2022-09-15 14:10:39 +02:00
|
|
|
dtypep(nullptr); // V3Width will resolve
|
|
|
|
|
refDTypep(nullptr);
|
|
|
|
|
}
|
|
|
|
|
AstMemberDType(FileLine* fl, const string& name, AstNodeDType* dtp)
|
|
|
|
|
: ASTGEN_SUPER_MemberDType(fl)
|
|
|
|
|
, m_name{name} {
|
|
|
|
|
UASSERT(dtp, "AstMember created with no dtype");
|
|
|
|
|
refDTypep(dtp);
|
|
|
|
|
dtypep(this);
|
|
|
|
|
widthFromSub(subDTypep());
|
|
|
|
|
}
|
2022-10-04 12:03:41 +02:00
|
|
|
ASTGEN_MEMBERS_AstMemberDType;
|
2023-01-29 22:50:10 +01:00
|
|
|
void dumpSmall(std::ostream& str) const override;
|
2023-03-18 01:24:15 +01:00
|
|
|
string name() const override VL_MT_STABLE { return m_name; } // * = Var name
|
2022-09-16 12:22:11 +02:00
|
|
|
bool hasDType() const override { return true; }
|
|
|
|
|
bool maybePointedTo() const override { return true; }
|
|
|
|
|
AstNodeDType* getChildDTypep() const override { return childDTypep(); }
|
2023-05-07 03:41:17 +02:00
|
|
|
AstNodeUOrStructDType* getChildStructp() const;
|
2023-03-17 00:48:56 +01:00
|
|
|
AstNodeDType* subDTypep() const override VL_MT_STABLE {
|
|
|
|
|
return m_refDTypep ? m_refDTypep : childDTypep();
|
|
|
|
|
}
|
2022-09-15 14:10:39 +02:00
|
|
|
void refDTypep(AstNodeDType* nodep) { m_refDTypep = nodep; }
|
2022-09-16 12:22:11 +02:00
|
|
|
AstNodeDType* virtRefDTypep() const override { return m_refDTypep; }
|
|
|
|
|
void virtRefDTypep(AstNodeDType* nodep) override { refDTypep(nodep); }
|
2022-12-02 00:47:09 +01:00
|
|
|
bool similarDType(const AstNodeDType* samep) const override { return this == samep; }
|
2022-09-15 14:10:39 +02:00
|
|
|
//
|
|
|
|
|
// (Slow) recurse down to find basic data type (Note don't need virtual -
|
|
|
|
|
// AstVar isn't a NodeDType)
|
2023-03-17 00:48:56 +01:00
|
|
|
AstBasicDType* basicp() const override VL_MT_STABLE { return subDTypep()->basicp(); }
|
2022-09-15 14:10:39 +02:00
|
|
|
// op1 = Range of variable (Note don't need virtual - AstVar isn't a NodeDType)
|
|
|
|
|
AstNodeDType* dtypeSkipRefp() const { return subDTypep()->skipRefp(); }
|
2023-03-17 00:48:56 +01:00
|
|
|
AstNodeDType* skipRefp() const override VL_MT_STABLE { return subDTypep()->skipRefp(); }
|
2022-09-16 12:22:11 +02:00
|
|
|
AstNodeDType* skipRefToConstp() const override { return subDTypep()->skipRefToConstp(); }
|
|
|
|
|
AstNodeDType* skipRefToEnump() const override { return subDTypep()->skipRefToEnump(); }
|
2022-09-15 14:10:39 +02:00
|
|
|
// (Slow) recurses - Structure alignment 1,2,4 or 8 bytes (arrays affect this)
|
2022-09-16 12:22:11 +02:00
|
|
|
int widthAlignBytes() const override { return subDTypep()->widthAlignBytes(); }
|
2022-09-15 14:10:39 +02:00
|
|
|
// (Slow) recurses - Width in bytes rounding up 1,2,4,8,12,...
|
2022-09-16 12:22:11 +02:00
|
|
|
int widthTotalBytes() const override { return subDTypep()->widthTotalBytes(); }
|
2022-09-15 14:10:39 +02:00
|
|
|
// METHODS
|
2022-09-16 12:22:11 +02:00
|
|
|
void name(const string& name) override { m_name = name; }
|
|
|
|
|
void tag(const string& text) override { m_tag = text; }
|
|
|
|
|
string tag() const override { return m_tag; }
|
2022-09-15 14:10:39 +02:00
|
|
|
int lsb() const { return m_lsb; }
|
|
|
|
|
void lsb(int lsb) { m_lsb = lsb; }
|
2022-09-16 12:22:11 +02:00
|
|
|
bool isCompound() const override {
|
2022-09-15 14:10:39 +02:00
|
|
|
v3fatalSrc("call isCompound on subdata type, not reference");
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
};
|
Support NBAs to arrays inside loops (#5092)
For NBAs that might execute a dynamic number of times in a single
evaluation (specifically: those that assign to array elements inside
loops), we introduce a new run-time VlNBACommitQueue data-structure
(currently a vector), which stores all pending updates and the necessary
info to reconstruct the LHS reference of the AstAssignDly at run-time.
All variables needing a commit queue has their corresponding unique
commit queue.
All NBAs to a variable that requires a commit queue go through the
commit queue. This is necessary to preserve update order in sequential
code, e.g.:
a[7] <= 10
for (int i = 1 ; i < 10; ++i) a[i] <= i;
a[2] <= 10
needs to end with array elements 1..9 being 1, 10, 3, 4, 5, 6, 7, 8, 9.
This enables supporting common forms of NBAs to arrays on the left hand
side of <= in non-suspendable/non-fork code. (Suspendable/fork
implementation is unclear to me so I left it unchanged, see #5084).
Any NBA that does not need a commit queue (i.e.: those that were
supported before), use the same scheme as before, and this patch should
have no effect on the generated code for those NBAs.
2024-05-03 13:45:49 +02:00
|
|
|
class AstNBACommitQueueDType final : public AstNodeDType {
|
|
|
|
|
// @astgen ptr := m_subDTypep : AstNodeDType // Type of the corresponding variable
|
|
|
|
|
const bool m_partial; // Partial element update required
|
|
|
|
|
|
|
|
|
|
public:
|
|
|
|
|
AstNBACommitQueueDType(FileLine* fl, AstNodeDType* subDTypep, bool partial)
|
|
|
|
|
: ASTGEN_SUPER_NBACommitQueueDType(fl)
|
|
|
|
|
, m_partial{partial}
|
|
|
|
|
, m_subDTypep{subDTypep} {
|
|
|
|
|
dtypep(this);
|
|
|
|
|
}
|
|
|
|
|
ASTGEN_MEMBERS_AstNBACommitQueueDType;
|
|
|
|
|
|
|
|
|
|
AstNodeDType* subDTypep() const override { return m_subDTypep; }
|
|
|
|
|
bool partial() const { return m_partial; }
|
|
|
|
|
bool similarDType(const AstNodeDType* samep) const override { return this == samep; }
|
|
|
|
|
AstBasicDType* basicp() const override { return nullptr; }
|
|
|
|
|
AstNodeDType* skipRefp() const override { return (AstNodeDType*)this; }
|
|
|
|
|
AstNodeDType* skipRefToConstp() const override { return (AstNodeDType*)this; }
|
|
|
|
|
AstNodeDType* skipRefToEnump() const override { return (AstNodeDType*)this; }
|
|
|
|
|
int widthAlignBytes() const override { return 1; }
|
|
|
|
|
int widthTotalBytes() const override { return 24; }
|
|
|
|
|
bool isCompound() const override { return true; }
|
|
|
|
|
};
|
2022-09-15 14:10:39 +02:00
|
|
|
class AstParamTypeDType final : public AstNodeDType {
|
|
|
|
|
// Parents: MODULE
|
|
|
|
|
// A parameter type statement; much like a var or typedef
|
2022-09-15 20:43:56 +02:00
|
|
|
// @astgen op1 := childDTypep : Optional[AstNodeDType]
|
2022-09-15 14:10:39 +02:00
|
|
|
const VVarType m_varType; // Type of variable (for localparam vs. param)
|
|
|
|
|
string m_name; // Name of variable
|
|
|
|
|
public:
|
|
|
|
|
AstParamTypeDType(FileLine* fl, VVarType type, const string& name, VFlagChildDType,
|
|
|
|
|
AstNodeDType* dtp)
|
|
|
|
|
: ASTGEN_SUPER_ParamTypeDType(fl)
|
|
|
|
|
, m_varType{type}
|
|
|
|
|
, m_name{name} {
|
|
|
|
|
childDTypep(dtp); // Only for parser
|
|
|
|
|
dtypep(nullptr); // V3Width will resolve
|
|
|
|
|
}
|
2022-10-04 12:03:41 +02:00
|
|
|
ASTGEN_MEMBERS_AstParamTypeDType;
|
2022-10-21 15:00:40 +02:00
|
|
|
void dump(std::ostream& str = std::cout) const override;
|
2024-02-09 23:50:09 +01:00
|
|
|
void dumpJson(std::ostream& str = std::cout) const override;
|
2022-09-16 12:22:11 +02:00
|
|
|
AstNodeDType* getChildDTypep() const override { return childDTypep(); }
|
2023-03-17 00:48:56 +01:00
|
|
|
AstNodeDType* subDTypep() const override VL_MT_STABLE {
|
|
|
|
|
return dtypep() ? dtypep() : childDTypep();
|
|
|
|
|
}
|
|
|
|
|
AstBasicDType* basicp() const override VL_MT_STABLE { return subDTypep()->basicp(); }
|
|
|
|
|
AstNodeDType* skipRefp() const override VL_MT_STABLE { return subDTypep()->skipRefp(); }
|
2022-09-16 12:22:11 +02:00
|
|
|
AstNodeDType* skipRefToConstp() const override { return subDTypep()->skipRefToConstp(); }
|
|
|
|
|
AstNodeDType* skipRefToEnump() const override { return subDTypep()->skipRefToEnump(); }
|
2022-12-02 00:47:09 +01:00
|
|
|
bool similarDType(const AstNodeDType* samep) const override {
|
2023-10-16 11:17:52 +02:00
|
|
|
if (type() != samep->type()) return false;
|
|
|
|
|
const AstParamTypeDType* const sp = VN_DBG_AS(samep, ParamTypeDType);
|
|
|
|
|
return this->subDTypep()->skipRefp()->similarDType(sp->subDTypep()->skipRefp());
|
2022-09-15 14:10:39 +02:00
|
|
|
}
|
2022-09-16 12:22:11 +02:00
|
|
|
int widthAlignBytes() const override { return dtypep()->widthAlignBytes(); }
|
|
|
|
|
int widthTotalBytes() const override { return dtypep()->widthTotalBytes(); }
|
2022-09-15 14:10:39 +02:00
|
|
|
// METHODS
|
2023-03-18 01:24:15 +01:00
|
|
|
string name() const override VL_MT_STABLE { return m_name; }
|
2022-09-16 12:22:11 +02:00
|
|
|
bool maybePointedTo() const override { return true; }
|
|
|
|
|
bool hasDType() const override { return true; }
|
|
|
|
|
void name(const string& flag) override { m_name = flag; }
|
2022-09-15 14:10:39 +02:00
|
|
|
VVarType varType() const { return m_varType; } // * = Type of variable
|
|
|
|
|
bool isParam() const { return true; }
|
|
|
|
|
bool isGParam() const { return (varType() == VVarType::GPARAM); }
|
2022-09-16 12:22:11 +02:00
|
|
|
bool isCompound() const override {
|
2022-09-15 14:10:39 +02:00
|
|
|
v3fatalSrc("call isCompound on subdata type, not reference");
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
class AstParseTypeDType final : public AstNodeDType {
|
|
|
|
|
// Parents: VAR
|
|
|
|
|
// During parsing, this indicates the type of a parameter is a "parameter type"
|
|
|
|
|
// e.g. the data type is a container of any data type
|
|
|
|
|
public:
|
|
|
|
|
explicit AstParseTypeDType(FileLine* fl)
|
|
|
|
|
: ASTGEN_SUPER_ParseTypeDType(fl) {}
|
2022-10-04 12:03:41 +02:00
|
|
|
ASTGEN_MEMBERS_AstParseTypeDType;
|
2022-09-15 14:10:39 +02:00
|
|
|
AstNodeDType* dtypep() const { return nullptr; }
|
|
|
|
|
// METHODS
|
2022-12-02 00:47:09 +01:00
|
|
|
bool similarDType(const AstNodeDType* samep) const override { return this == samep; }
|
2023-03-17 00:48:56 +01:00
|
|
|
AstBasicDType* basicp() const override VL_MT_STABLE { return nullptr; }
|
|
|
|
|
AstNodeDType* skipRefp() const override VL_MT_STABLE { return nullptr; }
|
2022-09-15 14:10:39 +02:00
|
|
|
// cppcheck-suppress csyleCast
|
2022-09-16 12:22:11 +02:00
|
|
|
AstNodeDType* skipRefToConstp() const override { return (AstNodeDType*)this; }
|
2022-09-15 14:10:39 +02:00
|
|
|
// cppcheck-suppress csyleCast
|
2022-09-16 12:22:11 +02:00
|
|
|
AstNodeDType* skipRefToEnump() const override { return (AstNodeDType*)this; }
|
|
|
|
|
int widthAlignBytes() const override { return 0; }
|
|
|
|
|
int widthTotalBytes() const override { return 0; }
|
|
|
|
|
bool isCompound() const override {
|
2022-09-15 14:10:39 +02:00
|
|
|
v3fatalSrc("call isCompound on subdata type, not reference");
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
class AstQueueDType final : public AstNodeDType {
|
|
|
|
|
// Queue array data type, ie "[ $ ]"
|
2022-09-15 20:43:56 +02:00
|
|
|
// @astgen op1 := childDTypep : Optional[AstNodeDType] // moved to refDTypep() in V3Width
|
2022-11-13 21:33:11 +01:00
|
|
|
// @astgen op2 := boundp : Optional[AstNodeExpr]
|
2023-12-01 01:58:16 +01:00
|
|
|
//
|
|
|
|
|
// @astgen ptr := m_refDTypep : Optional[AstNodeDType] // Elements of this type (post-width)
|
2022-09-15 14:10:39 +02:00
|
|
|
public:
|
2022-11-13 21:33:11 +01:00
|
|
|
AstQueueDType(FileLine* fl, VFlagChildDType, AstNodeDType* dtp, AstNodeExpr* boundp)
|
2022-09-15 14:10:39 +02:00
|
|
|
: ASTGEN_SUPER_QueueDType(fl) {
|
2022-09-15 20:43:56 +02:00
|
|
|
this->childDTypep(dtp);
|
|
|
|
|
this->boundp(boundp);
|
2022-09-15 14:10:39 +02:00
|
|
|
refDTypep(nullptr);
|
|
|
|
|
dtypep(nullptr); // V3Width will resolve
|
|
|
|
|
}
|
2022-11-13 21:33:11 +01:00
|
|
|
AstQueueDType(FileLine* fl, AstNodeDType* dtp, AstNodeExpr* boundp)
|
2022-09-15 14:10:39 +02:00
|
|
|
: ASTGEN_SUPER_QueueDType(fl) {
|
2022-09-15 20:43:56 +02:00
|
|
|
this->boundp(boundp);
|
2022-09-15 14:10:39 +02:00
|
|
|
refDTypep(dtp);
|
|
|
|
|
dtypep(dtp);
|
|
|
|
|
}
|
2022-10-04 12:03:41 +02:00
|
|
|
ASTGEN_MEMBERS_AstQueueDType;
|
2022-09-16 12:22:11 +02:00
|
|
|
const char* broken() const override {
|
2023-12-01 01:58:16 +01:00
|
|
|
BROKEN_RTN(!((m_refDTypep && !childDTypep()) || (!m_refDTypep && childDTypep())));
|
2022-09-15 14:10:39 +02:00
|
|
|
return nullptr;
|
|
|
|
|
}
|
2022-09-16 12:22:11 +02:00
|
|
|
bool same(const AstNode* samep) const override {
|
2023-10-16 11:17:52 +02:00
|
|
|
const AstQueueDType* const asamep = VN_DBG_AS(samep, QueueDType);
|
2022-09-15 14:10:39 +02:00
|
|
|
if (!asamep->subDTypep()) return false;
|
|
|
|
|
return (subDTypep() == asamep->subDTypep());
|
|
|
|
|
}
|
2022-12-02 00:47:09 +01:00
|
|
|
bool similarDType(const AstNodeDType* samep) const override {
|
2023-10-16 11:17:52 +02:00
|
|
|
if (type() != samep->type()) return false;
|
|
|
|
|
const AstQueueDType* const asamep = VN_DBG_AS(samep, QueueDType);
|
|
|
|
|
return asamep->subDTypep()
|
2022-09-15 14:10:39 +02:00
|
|
|
&& subDTypep()->skipRefp()->similarDType(asamep->subDTypep()->skipRefp());
|
|
|
|
|
}
|
2022-09-16 12:22:11 +02:00
|
|
|
void dumpSmall(std::ostream& str) const override;
|
|
|
|
|
string prettyDTypeName() const override;
|
|
|
|
|
AstNodeDType* getChildDTypep() const override { return childDTypep(); }
|
2023-03-17 00:48:56 +01:00
|
|
|
AstNodeDType* subDTypep() const override VL_MT_STABLE {
|
2022-10-18 23:07:09 +02:00
|
|
|
return m_refDTypep ? m_refDTypep : childDTypep();
|
|
|
|
|
}
|
2022-09-15 14:10:39 +02:00
|
|
|
void refDTypep(AstNodeDType* nodep) { m_refDTypep = nodep; }
|
2023-03-17 00:48:56 +01:00
|
|
|
inline int boundConst() const VL_MT_STABLE;
|
2022-09-16 12:22:11 +02:00
|
|
|
AstNodeDType* virtRefDTypep() const override { return m_refDTypep; }
|
|
|
|
|
void virtRefDTypep(AstNodeDType* nodep) override { refDTypep(nodep); }
|
2022-09-15 14:10:39 +02:00
|
|
|
// METHODS
|
2023-03-17 00:48:56 +01:00
|
|
|
AstBasicDType* basicp() const override VL_MT_STABLE { return nullptr; }
|
2022-09-15 14:10:39 +02:00
|
|
|
// cppcheck-suppress csyleCast
|
2023-03-17 00:48:56 +01:00
|
|
|
AstNodeDType* skipRefp() const override VL_MT_STABLE { return (AstNodeDType*)this; }
|
2022-09-15 14:10:39 +02:00
|
|
|
// cppcheck-suppress csyleCast
|
2022-09-16 12:22:11 +02:00
|
|
|
AstNodeDType* skipRefToConstp() const override { return (AstNodeDType*)this; }
|
2022-09-15 14:10:39 +02:00
|
|
|
// cppcheck-suppress csyleCast
|
2022-09-16 12:22:11 +02:00
|
|
|
AstNodeDType* skipRefToEnump() const override { return (AstNodeDType*)this; }
|
|
|
|
|
int widthAlignBytes() const override { return subDTypep()->widthAlignBytes(); }
|
|
|
|
|
int widthTotalBytes() const override { return subDTypep()->widthTotalBytes(); }
|
|
|
|
|
bool isCompound() const override { return true; }
|
2022-09-15 14:10:39 +02:00
|
|
|
};
|
|
|
|
|
class AstRefDType final : public AstNodeDType {
|
2022-09-21 16:24:17 +02:00
|
|
|
// @astgen op1 := typeofp : Optional[AstNode]
|
2022-11-13 21:33:11 +01:00
|
|
|
// @astgen op2 := classOrPackageOpp : Optional[AstNodeExpr]
|
2022-09-15 20:43:56 +02:00
|
|
|
// @astgen op3 := paramsp : List[AstPin]
|
2023-12-01 01:58:16 +01:00
|
|
|
//
|
2022-09-15 14:10:39 +02:00
|
|
|
// Pre-Width must reference the Typeref, not what it points to, as some child
|
|
|
|
|
// types like AstBracketArrayType will disappear and can't lose the handle
|
2023-12-01 01:58:16 +01:00
|
|
|
// @astgen ptr := m_typedefp : Optional[AstTypedef] // Referenced type
|
2022-09-15 14:10:39 +02:00
|
|
|
// Post-width typedefs are removed and point to type directly
|
2023-12-01 01:58:16 +01:00
|
|
|
// @astgen ptr := m_refDTypep : Optional[AstNodeDType] // Data type references
|
|
|
|
|
// @astgen ptr := m_classOrPackagep : Optional[AstNodeModule] // Class/package defined in
|
2022-09-15 14:10:39 +02:00
|
|
|
string m_name; // Name of an AstTypedef
|
|
|
|
|
public:
|
|
|
|
|
AstRefDType(FileLine* fl, const string& name)
|
|
|
|
|
: ASTGEN_SUPER_RefDType(fl)
|
|
|
|
|
, m_name{name} {}
|
2022-11-13 21:33:11 +01:00
|
|
|
AstRefDType(FileLine* fl, const string& name, AstNodeExpr* classOrPackagep, AstPin* paramsp)
|
2022-09-15 14:10:39 +02:00
|
|
|
: ASTGEN_SUPER_RefDType(fl)
|
|
|
|
|
, m_name{name} {
|
2022-09-15 20:43:56 +02:00
|
|
|
this->classOrPackageOpp(classOrPackagep);
|
|
|
|
|
addParamsp(paramsp);
|
2022-09-15 14:10:39 +02:00
|
|
|
}
|
|
|
|
|
class FlagTypeOfExpr {}; // type(expr) for parser only
|
|
|
|
|
AstRefDType(FileLine* fl, FlagTypeOfExpr, AstNode* typeofp)
|
|
|
|
|
: ASTGEN_SUPER_RefDType(fl) {
|
2022-09-15 20:43:56 +02:00
|
|
|
this->typeofp(typeofp);
|
2023-06-20 20:10:07 +02:00
|
|
|
if (AstNodeDType* const dtp = VN_CAST(typeofp, NodeDType)) refDTypep(dtp);
|
2022-09-15 14:10:39 +02:00
|
|
|
}
|
2022-10-04 12:03:41 +02:00
|
|
|
ASTGEN_MEMBERS_AstRefDType;
|
2022-09-15 14:10:39 +02:00
|
|
|
// METHODS
|
2022-09-16 12:22:11 +02:00
|
|
|
bool same(const AstNode* samep) const override {
|
2023-10-16 11:17:52 +02:00
|
|
|
const AstRefDType* const asamep = VN_DBG_AS(samep, RefDType);
|
2022-09-15 14:10:39 +02:00
|
|
|
return (m_typedefp == asamep->m_typedefp && m_refDTypep == asamep->m_refDTypep
|
|
|
|
|
&& m_name == asamep->m_name && m_classOrPackagep == asamep->m_classOrPackagep);
|
|
|
|
|
}
|
2022-12-02 00:47:09 +01:00
|
|
|
bool similarDType(const AstNodeDType* samep) const override {
|
2022-09-15 14:10:39 +02:00
|
|
|
return skipRefp()->similarDType(samep->skipRefp());
|
|
|
|
|
}
|
2022-09-16 12:22:11 +02:00
|
|
|
void dump(std::ostream& str = std::cout) const override;
|
2024-02-09 23:50:09 +01:00
|
|
|
void dumpJson(std::ostream& str = std::cout) const override;
|
2022-11-19 19:23:28 +01:00
|
|
|
void dumpSmall(std::ostream& str) const override;
|
2023-03-18 01:24:15 +01:00
|
|
|
string name() const override VL_MT_STABLE { return m_name; }
|
2022-09-16 12:22:11 +02:00
|
|
|
string prettyDTypeName() const override {
|
2022-11-27 11:59:40 +01:00
|
|
|
return subDTypep() ? prettyName(subDTypep()->name()) : prettyName();
|
2022-09-15 14:10:39 +02:00
|
|
|
}
|
2023-03-17 00:48:56 +01:00
|
|
|
AstBasicDType* basicp() const override VL_MT_STABLE {
|
2022-09-15 14:10:39 +02:00
|
|
|
return subDTypep() ? subDTypep()->basicp() : nullptr;
|
|
|
|
|
}
|
2023-03-17 00:48:56 +01:00
|
|
|
AstNodeDType* subDTypep() const override VL_MT_STABLE;
|
|
|
|
|
AstNodeDType* skipRefp() const override VL_MT_STABLE {
|
2022-09-15 14:10:39 +02:00
|
|
|
// Skip past both the Ref and the Typedef
|
|
|
|
|
if (subDTypep()) {
|
|
|
|
|
return subDTypep()->skipRefp();
|
|
|
|
|
} else {
|
|
|
|
|
v3fatalSrc("Typedef not linked");
|
|
|
|
|
return nullptr;
|
|
|
|
|
}
|
|
|
|
|
}
|
2022-09-16 12:22:11 +02:00
|
|
|
AstNodeDType* skipRefToConstp() const override {
|
2022-09-15 14:10:39 +02:00
|
|
|
if (subDTypep()) {
|
|
|
|
|
return subDTypep()->skipRefToConstp();
|
|
|
|
|
} else {
|
|
|
|
|
v3fatalSrc("Typedef not linked");
|
|
|
|
|
return nullptr;
|
|
|
|
|
}
|
|
|
|
|
}
|
2022-09-16 12:22:11 +02:00
|
|
|
AstNodeDType* skipRefToEnump() const override {
|
2022-09-15 14:10:39 +02:00
|
|
|
if (subDTypep()) {
|
|
|
|
|
return subDTypep()->skipRefToEnump();
|
|
|
|
|
} else {
|
|
|
|
|
v3fatalSrc("Typedef not linked");
|
|
|
|
|
return nullptr;
|
|
|
|
|
}
|
|
|
|
|
}
|
2022-09-16 12:22:11 +02:00
|
|
|
int widthAlignBytes() const override { return dtypeSkipRefp()->widthAlignBytes(); }
|
|
|
|
|
int widthTotalBytes() const override { return dtypeSkipRefp()->widthTotalBytes(); }
|
|
|
|
|
void name(const string& flag) override { m_name = flag; }
|
2022-09-15 14:10:39 +02:00
|
|
|
AstNodeDType* dtypeSkipRefp() const { return subDTypep()->skipRefp(); }
|
2023-03-17 00:48:56 +01:00
|
|
|
AstTypedef* typedefp() const VL_MT_SAFE { return m_typedefp; }
|
2022-09-15 14:10:39 +02:00
|
|
|
void typedefp(AstTypedef* nodep) { m_typedefp = nodep; }
|
2023-03-17 00:48:56 +01:00
|
|
|
AstNodeDType* refDTypep() const VL_MT_SAFE { return m_refDTypep; }
|
2022-09-15 14:10:39 +02:00
|
|
|
void refDTypep(AstNodeDType* nodep) { m_refDTypep = nodep; }
|
2022-09-16 12:22:11 +02:00
|
|
|
AstNodeDType* virtRefDTypep() const override { return refDTypep(); }
|
|
|
|
|
void virtRefDTypep(AstNodeDType* nodep) override { refDTypep(nodep); }
|
2022-09-15 14:10:39 +02:00
|
|
|
AstNodeModule* classOrPackagep() const { return m_classOrPackagep; }
|
|
|
|
|
void classOrPackagep(AstNodeModule* nodep) { m_classOrPackagep = nodep; }
|
2022-09-16 12:22:11 +02:00
|
|
|
bool isCompound() const override {
|
2022-09-15 14:10:39 +02:00
|
|
|
v3fatalSrc("call isCompound on subdata type, not reference");
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
};
|
2022-12-23 13:34:49 +01:00
|
|
|
class AstSampleQueueDType final : public AstNodeDType {
|
|
|
|
|
// @astgen op1 := childDTypep : Optional[AstNodeDType] // moved to refDTypep() in V3Width
|
2023-12-01 01:58:16 +01:00
|
|
|
//
|
|
|
|
|
// @astgen ptr := m_refDTypep : Optional[AstNodeDType] // Elements of this type (post-width)
|
2022-12-23 13:34:49 +01:00
|
|
|
public:
|
|
|
|
|
AstSampleQueueDType(FileLine* fl, AstNodeDType* dtp)
|
|
|
|
|
: ASTGEN_SUPER_SampleQueueDType(fl) {
|
|
|
|
|
refDTypep(dtp);
|
|
|
|
|
dtypep(dtp);
|
|
|
|
|
}
|
|
|
|
|
ASTGEN_MEMBERS_AstSampleQueueDType;
|
|
|
|
|
const char* broken() const override {
|
2023-12-01 01:58:16 +01:00
|
|
|
BROKEN_RTN(!((m_refDTypep && !childDTypep()) || (!m_refDTypep && childDTypep())));
|
2022-12-23 13:34:49 +01:00
|
|
|
return nullptr;
|
|
|
|
|
}
|
|
|
|
|
bool same(const AstNode* samep) const override {
|
2023-10-16 11:17:52 +02:00
|
|
|
const AstSampleQueueDType* const asamep = VN_DBG_AS(samep, SampleQueueDType);
|
2022-12-23 13:34:49 +01:00
|
|
|
if (!asamep->subDTypep()) return false;
|
|
|
|
|
return (subDTypep() == asamep->subDTypep());
|
|
|
|
|
}
|
|
|
|
|
bool similarDType(const AstNodeDType* samep) const override {
|
2023-10-16 11:17:52 +02:00
|
|
|
if (type() != samep->type()) return false;
|
|
|
|
|
const AstSampleQueueDType* const asamep = VN_DBG_AS(samep, SampleQueueDType);
|
|
|
|
|
return asamep->subDTypep()
|
2022-12-23 13:34:49 +01:00
|
|
|
&& subDTypep()->skipRefp()->similarDType(asamep->subDTypep()->skipRefp());
|
|
|
|
|
}
|
|
|
|
|
void dumpSmall(std::ostream& str) const override;
|
|
|
|
|
AstNodeDType* getChildDTypep() const override { return childDTypep(); }
|
|
|
|
|
// op1 = Range of variable
|
2023-03-17 00:48:56 +01:00
|
|
|
AstNodeDType* subDTypep() const override VL_MT_STABLE {
|
|
|
|
|
return m_refDTypep ? m_refDTypep : childDTypep();
|
|
|
|
|
}
|
2022-12-23 13:34:49 +01:00
|
|
|
void refDTypep(AstNodeDType* nodep) { m_refDTypep = nodep; }
|
|
|
|
|
AstNodeDType* virtRefDTypep() const override { return m_refDTypep; }
|
|
|
|
|
void virtRefDTypep(AstNodeDType* nodep) override { refDTypep(nodep); }
|
|
|
|
|
// METHODS
|
2023-03-17 00:48:56 +01:00
|
|
|
AstBasicDType* basicp() const override VL_MT_STABLE { return subDTypep()->basicp(); }
|
|
|
|
|
AstNodeDType* skipRefp() const override VL_MT_STABLE { return (AstNodeDType*)this; }
|
2022-12-23 13:34:49 +01:00
|
|
|
AstNodeDType* skipRefToConstp() const override { return (AstNodeDType*)this; }
|
|
|
|
|
AstNodeDType* skipRefToEnump() const override { return (AstNodeDType*)this; }
|
|
|
|
|
int widthAlignBytes() const override { return sizeof(std::map<std::string, std::string>); }
|
|
|
|
|
int widthTotalBytes() const override { return sizeof(std::map<std::string, std::string>); }
|
|
|
|
|
bool isCompound() const override { return true; }
|
|
|
|
|
};
|
2023-06-14 04:46:42 +02:00
|
|
|
class AstStreamDType final : public AstNodeDType {
|
|
|
|
|
// Stream data type, used only as data type of stream operations
|
|
|
|
|
// Should behave like AstPackArrayDType, but it doesn't have a size
|
|
|
|
|
public:
|
|
|
|
|
explicit AstStreamDType(FileLine* fl)
|
|
|
|
|
: ASTGEN_SUPER_StreamDType(fl) {
|
|
|
|
|
dtypep(this);
|
|
|
|
|
}
|
|
|
|
|
ASTGEN_MEMBERS_AstStreamDType;
|
|
|
|
|
void dumpSmall(std::ostream& str) const override;
|
|
|
|
|
bool hasDType() const override { return true; }
|
|
|
|
|
bool maybePointedTo() const override { return true; }
|
|
|
|
|
bool undead() const override { return true; }
|
|
|
|
|
AstNodeDType* subDTypep() const override VL_MT_SAFE { return nullptr; }
|
|
|
|
|
AstNodeDType* virtRefDTypep() const override { return nullptr; }
|
|
|
|
|
void virtRefDTypep(AstNodeDType* nodep) override {}
|
|
|
|
|
bool similarDType(const AstNodeDType* samep) const override { return this == samep; }
|
|
|
|
|
AstBasicDType* basicp() const override VL_MT_STABLE { return nullptr; }
|
|
|
|
|
// cppcheck-suppress csyleCast
|
|
|
|
|
AstNodeDType* skipRefp() const override VL_MT_STABLE { return (AstNodeDType*)this; }
|
|
|
|
|
// cppcheck-suppress csyleCast
|
|
|
|
|
AstNodeDType* skipRefToConstp() const override { return (AstNodeDType*)this; }
|
|
|
|
|
// cppcheck-suppress csyleCast
|
|
|
|
|
AstNodeDType* skipRefToEnump() const override { return (AstNodeDType*)this; }
|
|
|
|
|
int widthAlignBytes() const override { return 1; }
|
|
|
|
|
int widthTotalBytes() const override { return 1; }
|
|
|
|
|
bool isCompound() const override { return false; }
|
|
|
|
|
};
|
2022-09-15 14:10:39 +02:00
|
|
|
class AstUnsizedArrayDType final : public AstNodeDType {
|
|
|
|
|
// Unsized/open-range Array data type, ie "some_dtype var_name []"
|
2022-09-15 20:43:56 +02:00
|
|
|
// @astgen op1 := childDTypep : Optional[AstNodeDType] // moved to refDTypep() in V3Width
|
2023-12-01 01:58:16 +01:00
|
|
|
//
|
|
|
|
|
// @astgen ptr := m_refDTypep : Optional[AstNodeDType] // Elements of this type (post-width)
|
2022-09-15 14:10:39 +02:00
|
|
|
public:
|
|
|
|
|
AstUnsizedArrayDType(FileLine* fl, VFlagChildDType, AstNodeDType* dtp)
|
|
|
|
|
: ASTGEN_SUPER_UnsizedArrayDType(fl) {
|
|
|
|
|
childDTypep(dtp); // Only for parser
|
|
|
|
|
refDTypep(nullptr);
|
|
|
|
|
dtypep(nullptr); // V3Width will resolve
|
|
|
|
|
}
|
2022-10-04 12:03:41 +02:00
|
|
|
ASTGEN_MEMBERS_AstUnsizedArrayDType;
|
2022-09-16 12:22:11 +02:00
|
|
|
const char* broken() const override {
|
2023-12-01 01:58:16 +01:00
|
|
|
BROKEN_RTN(!((m_refDTypep && !childDTypep()) || (!m_refDTypep && childDTypep())));
|
2022-09-15 14:10:39 +02:00
|
|
|
return nullptr;
|
|
|
|
|
}
|
|
|
|
|
bool same(const AstNode* samep) const override;
|
2022-12-02 00:47:09 +01:00
|
|
|
bool similarDType(const AstNodeDType* samep) const override;
|
2022-09-16 12:22:11 +02:00
|
|
|
void dumpSmall(std::ostream& str) const override;
|
|
|
|
|
AstNodeDType* getChildDTypep() const override { return childDTypep(); }
|
2023-03-17 00:48:56 +01:00
|
|
|
AstNodeDType* subDTypep() const override VL_MT_STABLE {
|
|
|
|
|
return m_refDTypep ? m_refDTypep : childDTypep();
|
|
|
|
|
}
|
2022-09-15 14:10:39 +02:00
|
|
|
void refDTypep(AstNodeDType* nodep) { m_refDTypep = nodep; }
|
2022-09-16 12:22:11 +02:00
|
|
|
AstNodeDType* virtRefDTypep() const override { return m_refDTypep; }
|
|
|
|
|
void virtRefDTypep(AstNodeDType* nodep) override { refDTypep(nodep); }
|
2022-09-15 14:10:39 +02:00
|
|
|
// METHODS
|
2023-03-17 00:48:56 +01:00
|
|
|
AstBasicDType* basicp() const override VL_MT_STABLE { return subDTypep()->basicp(); }
|
|
|
|
|
AstNodeDType* skipRefp() const override VL_MT_STABLE { return (AstNodeDType*)this; }
|
2022-09-16 12:22:11 +02:00
|
|
|
AstNodeDType* skipRefToConstp() const override { return (AstNodeDType*)this; }
|
|
|
|
|
AstNodeDType* skipRefToEnump() const override { return (AstNodeDType*)this; }
|
|
|
|
|
int widthAlignBytes() const override { return subDTypep()->widthAlignBytes(); }
|
|
|
|
|
int widthTotalBytes() const override { return subDTypep()->widthTotalBytes(); }
|
|
|
|
|
bool isCompound() const override { return true; }
|
2022-09-15 14:10:39 +02:00
|
|
|
};
|
|
|
|
|
class AstVoidDType final : public AstNodeDType {
|
|
|
|
|
// For e.g. a function returning void
|
|
|
|
|
public:
|
|
|
|
|
explicit AstVoidDType(FileLine* fl)
|
|
|
|
|
: ASTGEN_SUPER_VoidDType(fl) {
|
|
|
|
|
dtypep(this);
|
|
|
|
|
}
|
2022-10-04 12:03:41 +02:00
|
|
|
ASTGEN_MEMBERS_AstVoidDType;
|
2022-09-16 12:22:11 +02:00
|
|
|
void dumpSmall(std::ostream& str) const override;
|
|
|
|
|
bool hasDType() const override { return true; }
|
|
|
|
|
bool maybePointedTo() const override { return true; }
|
|
|
|
|
bool undead() const override { return true; }
|
2023-03-17 00:48:56 +01:00
|
|
|
AstNodeDType* subDTypep() const override VL_MT_SAFE { return nullptr; }
|
2022-09-16 12:22:11 +02:00
|
|
|
AstNodeDType* virtRefDTypep() const override { return nullptr; }
|
|
|
|
|
void virtRefDTypep(AstNodeDType* nodep) override {}
|
2022-12-02 00:47:09 +01:00
|
|
|
bool similarDType(const AstNodeDType* samep) const override { return this == samep; }
|
2023-03-17 00:48:56 +01:00
|
|
|
AstBasicDType* basicp() const override VL_MT_STABLE { return nullptr; }
|
2022-09-15 14:10:39 +02:00
|
|
|
// cppcheck-suppress csyleCast
|
2023-03-17 00:48:56 +01:00
|
|
|
AstNodeDType* skipRefp() const override VL_MT_STABLE { return (AstNodeDType*)this; }
|
2022-09-15 14:10:39 +02:00
|
|
|
// cppcheck-suppress csyleCast
|
2022-09-16 12:22:11 +02:00
|
|
|
AstNodeDType* skipRefToConstp() const override { return (AstNodeDType*)this; }
|
2022-09-15 14:10:39 +02:00
|
|
|
// cppcheck-suppress csyleCast
|
2022-09-16 12:22:11 +02:00
|
|
|
AstNodeDType* skipRefToEnump() const override { return (AstNodeDType*)this; }
|
|
|
|
|
int widthAlignBytes() const override { return 1; }
|
|
|
|
|
int widthTotalBytes() const override { return 1; }
|
|
|
|
|
bool isCompound() const override { return false; }
|
2022-09-15 14:10:39 +02:00
|
|
|
};
|
|
|
|
|
class AstWildcardArrayDType final : public AstNodeDType {
|
|
|
|
|
// Wildcard index type associative array data type, ie "some_dtype var_name [*]"
|
2022-09-15 20:43:56 +02:00
|
|
|
// @astgen op1 := childDTypep : Optional[AstNodeDType] // moved to refDTypep() in V3Width
|
2023-12-01 01:58:16 +01:00
|
|
|
//
|
|
|
|
|
// @astgen ptr := m_refDTypep : Optional[AstNodeDType] // Elements of this type (post-width)
|
2022-09-15 14:10:39 +02:00
|
|
|
public:
|
|
|
|
|
AstWildcardArrayDType(FileLine* fl, VFlagChildDType, AstNodeDType* dtp)
|
|
|
|
|
: ASTGEN_SUPER_WildcardArrayDType(fl) {
|
|
|
|
|
childDTypep(dtp); // Only for parser
|
|
|
|
|
refDTypep(nullptr);
|
|
|
|
|
dtypep(nullptr); // V3Width will resolve
|
|
|
|
|
}
|
2022-10-04 12:03:41 +02:00
|
|
|
ASTGEN_MEMBERS_AstWildcardArrayDType;
|
2022-09-16 12:22:11 +02:00
|
|
|
const char* broken() const override {
|
2023-12-01 01:58:16 +01:00
|
|
|
BROKEN_RTN(!((m_refDTypep && !childDTypep()) || (!m_refDTypep && childDTypep())));
|
2022-09-15 14:10:39 +02:00
|
|
|
return nullptr;
|
|
|
|
|
}
|
|
|
|
|
bool same(const AstNode* samep) const override;
|
2022-12-02 00:47:09 +01:00
|
|
|
bool similarDType(const AstNodeDType* samep) const override;
|
2022-09-16 12:22:11 +02:00
|
|
|
void dumpSmall(std::ostream& str) const override;
|
|
|
|
|
AstNodeDType* getChildDTypep() const override { return childDTypep(); }
|
2023-03-17 00:48:56 +01:00
|
|
|
AstNodeDType* subDTypep() const override VL_MT_STABLE {
|
2022-10-18 23:07:09 +02:00
|
|
|
return m_refDTypep ? m_refDTypep : childDTypep();
|
|
|
|
|
}
|
2022-09-15 14:10:39 +02:00
|
|
|
void refDTypep(AstNodeDType* nodep) { m_refDTypep = nodep; }
|
2022-09-16 12:22:11 +02:00
|
|
|
AstNodeDType* virtRefDTypep() const override { return m_refDTypep; }
|
|
|
|
|
void virtRefDTypep(AstNodeDType* nodep) override { refDTypep(nodep); }
|
2022-09-15 14:10:39 +02:00
|
|
|
// METHODS
|
2023-03-17 00:48:56 +01:00
|
|
|
AstBasicDType* basicp() const override VL_MT_STABLE { return subDTypep()->basicp(); }
|
|
|
|
|
AstNodeDType* skipRefp() const override VL_MT_STABLE { return (AstNodeDType*)this; }
|
2022-09-16 12:22:11 +02:00
|
|
|
AstNodeDType* skipRefToConstp() const override { return (AstNodeDType*)this; }
|
|
|
|
|
AstNodeDType* skipRefToEnump() const override { return (AstNodeDType*)this; }
|
|
|
|
|
int widthAlignBytes() const override { return sizeof(std::map<std::string, std::string>); }
|
|
|
|
|
int widthTotalBytes() const override { return sizeof(std::map<std::string, std::string>); }
|
|
|
|
|
bool isCompound() const override { return true; }
|
2022-09-15 14:10:39 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
// === AstNodeArrayDType ===
|
|
|
|
|
class AstPackArrayDType final : public AstNodeArrayDType {
|
|
|
|
|
// Packed array data type, ie "some_dtype [2:0] var_name"
|
|
|
|
|
public:
|
|
|
|
|
inline AstPackArrayDType(FileLine* fl, VFlagChildDType, AstNodeDType* dtp, AstRange* rangep);
|
|
|
|
|
inline AstPackArrayDType(FileLine* fl, AstNodeDType* dtp, AstRange* rangep);
|
2022-10-04 12:03:41 +02:00
|
|
|
ASTGEN_MEMBERS_AstPackArrayDType;
|
2022-09-16 12:22:11 +02:00
|
|
|
string prettyDTypeName() const override;
|
|
|
|
|
bool isCompound() const override { return false; }
|
2022-09-15 14:10:39 +02:00
|
|
|
};
|
|
|
|
|
class AstUnpackArrayDType final : public AstNodeArrayDType {
|
|
|
|
|
// Array data type, ie "some_dtype var_name [2:0]"
|
|
|
|
|
bool m_isCompound = false; // Non-POD subDType, or parent requires compound
|
|
|
|
|
public:
|
|
|
|
|
AstUnpackArrayDType(FileLine* fl, VFlagChildDType, AstNodeDType* dtp, AstRange* rangep)
|
|
|
|
|
: ASTGEN_SUPER_UnpackArrayDType(fl) {
|
2022-09-15 20:43:56 +02:00
|
|
|
this->childDTypep(dtp); // Only for parser
|
|
|
|
|
this->rangep(rangep);
|
2022-09-15 14:10:39 +02:00
|
|
|
refDTypep(nullptr);
|
|
|
|
|
dtypep(nullptr); // V3Width will resolve
|
|
|
|
|
// For backward compatibility AstNodeArrayDType and others inherit
|
|
|
|
|
// width and signing from the subDType/base type
|
|
|
|
|
widthFromSub(subDTypep());
|
|
|
|
|
}
|
|
|
|
|
AstUnpackArrayDType(FileLine* fl, AstNodeDType* dtp, AstRange* rangep)
|
|
|
|
|
: ASTGEN_SUPER_UnpackArrayDType(fl) {
|
2022-09-15 20:43:56 +02:00
|
|
|
this->rangep(rangep);
|
2022-09-15 14:10:39 +02:00
|
|
|
refDTypep(dtp);
|
|
|
|
|
dtypep(this);
|
|
|
|
|
// For backward compatibility AstNodeArrayDType and others inherit
|
|
|
|
|
// width and signing from the subDType/base type
|
|
|
|
|
widthFromSub(subDTypep());
|
|
|
|
|
}
|
2022-10-04 12:03:41 +02:00
|
|
|
ASTGEN_MEMBERS_AstUnpackArrayDType;
|
2022-09-16 12:22:11 +02:00
|
|
|
string prettyDTypeName() const override;
|
|
|
|
|
bool same(const AstNode* samep) const override {
|
2023-10-16 11:17:52 +02:00
|
|
|
const AstUnpackArrayDType* const sp = VN_DBG_AS(samep, UnpackArrayDType);
|
2022-09-15 14:10:39 +02:00
|
|
|
return m_isCompound == sp->m_isCompound;
|
|
|
|
|
}
|
|
|
|
|
// Outer dimension comes first. The first element is this node.
|
|
|
|
|
std::vector<AstUnpackArrayDType*> unpackDimensions();
|
|
|
|
|
void isCompound(bool flag) { m_isCompound = flag; }
|
2022-10-18 23:07:09 +02:00
|
|
|
bool isCompound() const override VL_MT_SAFE { return m_isCompound; }
|
2023-02-12 22:32:36 +01:00
|
|
|
bool isIntegralOrPacked() const override { return false; }
|
2022-09-15 14:10:39 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
// === AstNodeUOrStructDType ===
|
|
|
|
|
class AstStructDType final : public AstNodeUOrStructDType {
|
|
|
|
|
public:
|
|
|
|
|
// VSigning below is mispurposed to indicate if packed or not
|
|
|
|
|
AstStructDType(FileLine* fl, VSigning numericUnpack)
|
|
|
|
|
: ASTGEN_SUPER_StructDType(fl, numericUnpack) {}
|
2022-10-04 12:03:41 +02:00
|
|
|
ASTGEN_MEMBERS_AstStructDType;
|
2022-09-16 12:22:11 +02:00
|
|
|
string verilogKwd() const override { return "struct"; }
|
2022-09-15 14:10:39 +02:00
|
|
|
};
|
|
|
|
|
class AstUnionDType final : public AstNodeUOrStructDType {
|
|
|
|
|
public:
|
|
|
|
|
// UNSUP: bool isTagged;
|
|
|
|
|
// VSigning below is mispurposed to indicate if packed or not
|
|
|
|
|
AstUnionDType(FileLine* fl, VSigning numericUnpack)
|
|
|
|
|
: ASTGEN_SUPER_UnionDType(fl, numericUnpack) {}
|
2022-10-04 12:03:41 +02:00
|
|
|
ASTGEN_MEMBERS_AstUnionDType;
|
2022-09-16 12:22:11 +02:00
|
|
|
string verilogKwd() const override { return "union"; }
|
2022-09-15 14:10:39 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
#endif // Guard
|