2012-04-13 03:08:20 +02:00
|
|
|
// -*- mode: C++; c-file-style: "cc-mode" -*-
|
2006-08-26 13:35:28 +02:00
|
|
|
//*************************************************************************
|
|
|
|
|
// DESCRIPTION: Verilator: Ast node structure
|
|
|
|
|
//
|
2019-11-08 04:33:59 +01:00
|
|
|
// Code available from: https://verilator.org
|
2006-08-26 13:35:28 +02:00
|
|
|
//
|
|
|
|
|
//*************************************************************************
|
|
|
|
|
//
|
2021-01-01 16:29:54 +01:00
|
|
|
// Copyright 2003-2021 by Wilson Snyder. This program is free software; you
|
2020-03-21 16:24:24 +01:00
|
|
|
// can redistribute it and/or modify it under the terms of either the GNU
|
2009-05-04 23:07:57 +02:00
|
|
|
// Lesser General Public License Version 3 or the Perl Artistic License
|
|
|
|
|
// Version 2.0.
|
2020-03-21 16:24:24 +01:00
|
|
|
// SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0
|
2006-08-26 13:35:28 +02:00
|
|
|
//
|
|
|
|
|
//*************************************************************************
|
2019-10-05 02:17:11 +02:00
|
|
|
|
2021-03-04 03:57:07 +01:00
|
|
|
#ifndef VERILATOR_V3ASTNODES_H_
|
|
|
|
|
#define VERILATOR_V3ASTNODES_H_
|
2006-08-26 13:35:28 +02:00
|
|
|
|
2021-03-04 03:57:07 +01:00
|
|
|
#ifndef VERILATOR_V3AST_H_
|
2006-08-26 13:35:28 +02:00
|
|
|
#error "Use V3Ast.h as the include"
|
2021-06-05 18:40:56 +02:00
|
|
|
#include "V3Ast.h" // This helps code analysis tools pick up symbols in V3Ast.h
|
2006-08-26 13:35:28 +02:00
|
|
|
#endif
|
|
|
|
|
|
2008-11-20 02:15:05 +01:00
|
|
|
//######################################################################
|
|
|
|
|
// Standard defines for all AstNode final classes
|
|
|
|
|
|
2018-07-07 14:02:29 +02:00
|
|
|
#define ASTNODE_NODE_FUNCS_NO_DTOR(name) \
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual void accept(AstNVisitor& v) override { v.visit(this); } \
|
|
|
|
|
virtual AstNode* clone() override { return new Ast##name(*this); } \
|
2020-04-15 13:58:34 +02:00
|
|
|
static Ast##name* cloneTreeNull(Ast##name* nodep, bool cloneNextLink) { \
|
2020-08-15 16:12:55 +02:00
|
|
|
return nodep ? nodep->cloneTree(cloneNextLink) : nullptr; \
|
2020-04-15 13:58:34 +02:00
|
|
|
} \
|
|
|
|
|
Ast##name* cloneTree(bool cloneNext) { \
|
|
|
|
|
return static_cast<Ast##name*>(AstNode::cloneTree(cloneNext)); \
|
|
|
|
|
} \
|
|
|
|
|
Ast##name* clonep() const { return static_cast<Ast##name*>(AstNode::clonep()); }
|
2008-11-20 02:15:05 +01:00
|
|
|
|
2018-07-07 14:02:29 +02:00
|
|
|
#define ASTNODE_NODE_FUNCS(name) \
|
2020-11-17 01:56:16 +01:00
|
|
|
virtual ~Ast##name() override = default; \
|
2018-07-07 14:02:29 +02:00
|
|
|
ASTNODE_NODE_FUNCS_NO_DTOR(name)
|
|
|
|
|
|
2020-01-25 21:29:44 +01:00
|
|
|
//######################################################################
|
2021-05-22 12:13:02 +02:00
|
|
|
// Macros generated by 'astgen'
|
2020-01-25 21:29:44 +01:00
|
|
|
|
2021-05-22 12:13:02 +02:00
|
|
|
#include "V3AstNodes__gen_macros.h"
|
2020-01-25 21:29:44 +01:00
|
|
|
|
2006-08-26 13:35:28 +02:00
|
|
|
//######################################################################
|
|
|
|
|
//=== Ast* : Specific types
|
|
|
|
|
// Netlist interconnect
|
|
|
|
|
|
2020-11-19 03:32:16 +01:00
|
|
|
class AstConst final : public AstNodeMath {
|
2006-08-26 13:35:28 +02:00
|
|
|
// A constant
|
|
|
|
|
private:
|
2019-05-10 02:03:19 +02:00
|
|
|
V3Number m_num; // Constant value
|
|
|
|
|
void initWithNumber() {
|
|
|
|
|
if (m_num.isDouble()) {
|
|
|
|
|
dtypeSetDouble();
|
2018-03-10 22:51:34 +01:00
|
|
|
} else if (m_num.isString()) {
|
2019-05-10 02:03:19 +02:00
|
|
|
dtypeSetString();
|
|
|
|
|
} else {
|
2019-08-04 18:39:35 +02:00
|
|
|
dtypeSetLogicUnsized(m_num.width(), (m_num.sized() ? 0 : m_num.widthMin()),
|
2020-04-20 03:19:09 +02:00
|
|
|
VSigning::fromBool(m_num.isSigned()));
|
2018-03-10 22:51:34 +01:00
|
|
|
}
|
2019-08-04 20:14:28 +02:00
|
|
|
m_num.nodep(this);
|
2006-08-26 13:35:28 +02:00
|
|
|
}
|
2020-04-15 13:58:34 +02:00
|
|
|
|
2019-05-10 02:03:19 +02:00
|
|
|
public:
|
|
|
|
|
AstConst(FileLine* fl, const V3Number& num)
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_Const(fl)
|
2019-05-10 02:03:19 +02:00
|
|
|
, m_num(num) {
|
|
|
|
|
initWithNumber();
|
|
|
|
|
}
|
|
|
|
|
class WidthedValue {}; // for creator type-overload selection
|
|
|
|
|
AstConst(FileLine* fl, WidthedValue, int width, uint32_t value)
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_Const(fl)
|
2019-05-10 02:03:19 +02:00
|
|
|
, m_num(this, width, value) {
|
|
|
|
|
initWithNumber();
|
|
|
|
|
}
|
2020-04-15 13:58:34 +02:00
|
|
|
class DtypedValue {}; // for creator type-overload selection
|
2019-08-12 14:33:58 +02:00
|
|
|
AstConst(FileLine* fl, DtypedValue, AstNodeDType* nodedtypep, uint32_t value)
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_Const(fl)
|
2019-08-12 14:33:58 +02:00
|
|
|
, m_num(this, nodedtypep->width(), value, nodedtypep->widthSized()) {
|
|
|
|
|
initWithNumber();
|
|
|
|
|
}
|
2019-05-10 02:03:19 +02:00
|
|
|
class StringToParse {}; // for creator type-overload selection
|
|
|
|
|
AstConst(FileLine* fl, StringToParse, const char* sourcep)
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_Const(fl)
|
2019-05-10 02:03:19 +02:00
|
|
|
, m_num(this, sourcep) {
|
|
|
|
|
initWithNumber();
|
|
|
|
|
}
|
|
|
|
|
class VerilogStringLiteral {}; // for creator type-overload selection
|
|
|
|
|
AstConst(FileLine* fl, VerilogStringLiteral, const string& str)
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_Const(fl)
|
2019-05-10 02:03:19 +02:00
|
|
|
, m_num(V3Number::VerilogStringLiteral(), this, str) {
|
|
|
|
|
initWithNumber();
|
|
|
|
|
}
|
2006-08-26 13:35:28 +02:00
|
|
|
AstConst(FileLine* fl, uint32_t num)
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_Const(fl)
|
2019-07-11 22:00:56 +02:00
|
|
|
, m_num(this, 32, num) {
|
2020-04-20 03:19:09 +02:00
|
|
|
dtypeSetLogicUnsized(m_num.width(), 0, VSigning::UNSIGNED);
|
2019-05-10 02:03:19 +02:00
|
|
|
}
|
2018-08-23 11:09:12 +02:00
|
|
|
class Unsized32 {}; // for creator type-overload selection
|
2009-09-24 05:10:46 +02:00
|
|
|
AstConst(FileLine* fl, Unsized32, uint32_t num) // Unsized 32-bit integer of specified value
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_Const(fl)
|
2019-07-11 22:00:56 +02:00
|
|
|
, m_num(this, 32, num) {
|
2019-05-19 22:13:13 +02:00
|
|
|
m_num.width(32, false);
|
2020-04-20 03:19:09 +02:00
|
|
|
dtypeSetLogicUnsized(32, m_num.widthMin(), VSigning::UNSIGNED);
|
2019-05-10 02:03:19 +02:00
|
|
|
}
|
|
|
|
|
class Signed32 {}; // for creator type-overload selection
|
2013-01-20 18:19:22 +01:00
|
|
|
AstConst(FileLine* fl, Signed32, int32_t num) // Signed 32-bit integer of specified value
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_Const(fl)
|
2019-07-11 22:00:56 +02:00
|
|
|
, m_num(this, 32, num) {
|
2019-12-21 16:25:05 +01:00
|
|
|
m_num.width(32, true);
|
2020-04-20 03:19:09 +02:00
|
|
|
dtypeSetLogicUnsized(32, m_num.widthMin(), VSigning::SIGNED);
|
2019-05-10 02:03:19 +02:00
|
|
|
}
|
2020-04-16 01:39:03 +02:00
|
|
|
class Unsized64 {}; // for creator type-overload selection
|
|
|
|
|
AstConst(FileLine* fl, Unsized64, vluint64_t num)
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_Const(fl)
|
2020-04-16 01:39:03 +02:00
|
|
|
, m_num(this, 64, 0) {
|
|
|
|
|
m_num.setQuad(num);
|
2020-04-20 03:19:09 +02:00
|
|
|
dtypeSetLogicSized(64, VSigning::UNSIGNED);
|
2020-04-16 01:39:03 +02:00
|
|
|
}
|
2019-12-09 03:36:38 +01:00
|
|
|
class SizedEData {}; // for creator type-overload selection
|
|
|
|
|
AstConst(FileLine* fl, SizedEData, vluint64_t num)
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_Const(fl)
|
2019-12-09 03:36:38 +01:00
|
|
|
, m_num(this, VL_EDATASIZE, 0) {
|
|
|
|
|
m_num.setQuad(num);
|
2020-04-20 03:19:09 +02:00
|
|
|
dtypeSetLogicSized(VL_EDATASIZE, VSigning::UNSIGNED);
|
2019-12-09 03:36:38 +01:00
|
|
|
}
|
2019-05-10 02:03:19 +02:00
|
|
|
class RealDouble {}; // for creator type-overload selection
|
2011-07-24 21:01:51 +02:00
|
|
|
AstConst(FileLine* fl, RealDouble, double num)
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_Const(fl)
|
2020-04-15 13:58:34 +02:00
|
|
|
, m_num(this, 64) {
|
|
|
|
|
m_num.setDouble(num);
|
|
|
|
|
dtypeSetDouble();
|
|
|
|
|
}
|
2019-05-10 02:03:19 +02:00
|
|
|
class String {}; // for creator type-overload selection
|
2014-11-28 21:01:50 +01:00
|
|
|
AstConst(FileLine* fl, String, const string& num)
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_Const(fl)
|
2020-04-15 13:58:34 +02:00
|
|
|
, m_num(V3Number::String(), this, num) {
|
|
|
|
|
dtypeSetString();
|
|
|
|
|
}
|
2020-11-29 14:23:36 +01:00
|
|
|
class BitFalse {};
|
|
|
|
|
AstConst(FileLine* fl, BitFalse) // Shorthand const 0, dtype should be a logic of size 1
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_Const(fl)
|
2020-04-15 13:58:34 +02:00
|
|
|
, m_num(this, 1, 0) {
|
2020-11-29 14:23:36 +01:00
|
|
|
dtypeSetBit();
|
2020-04-15 13:58:34 +02:00
|
|
|
}
|
2020-11-29 17:31:38 +01:00
|
|
|
// Shorthand const 1 (or with argument 0/1), dtype should be a logic of size 1
|
2020-11-29 14:23:36 +01:00
|
|
|
class BitTrue {};
|
2020-11-29 17:31:38 +01:00
|
|
|
AstConst(FileLine* fl, BitTrue, bool on = true)
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_Const(fl)
|
2020-11-29 17:31:38 +01:00
|
|
|
, m_num(this, 1, on) {
|
2020-11-29 14:23:36 +01:00
|
|
|
dtypeSetBit();
|
2020-04-15 13:58:34 +02:00
|
|
|
}
|
2020-12-05 22:49:10 +01:00
|
|
|
class Null {};
|
|
|
|
|
AstConst(FileLine* fl, Null)
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_Const(fl)
|
2020-12-05 22:49:10 +01:00
|
|
|
, m_num(V3Number::Null{}, this) {
|
|
|
|
|
dtypeSetBit(); // Events 1 bit, objects 64 bits, so autoExtend=1 and use bit here
|
|
|
|
|
initWithNumber();
|
|
|
|
|
}
|
2016-11-05 14:47:56 +01:00
|
|
|
ASTNODE_NODE_FUNCS(Const)
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual string name() const override { return num().ascii(); } // * = Value
|
2019-07-11 22:00:56 +02:00
|
|
|
const V3Number& num() const { return m_num; } // * = Value
|
2019-07-23 19:58:17 +02:00
|
|
|
V3Number& num() { return m_num; } // * = Value
|
2019-05-19 22:13:13 +02:00
|
|
|
uint32_t toUInt() const { return num().toUInt(); }
|
|
|
|
|
vlsint32_t toSInt() const { return num().toSInt(); }
|
2008-09-03 23:40:01 +02:00
|
|
|
vluint64_t toUQuad() const { return num().toUQuad(); }
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual string emitVerilog() override { V3ERROR_NA_RETURN(""); }
|
|
|
|
|
virtual string emitC() override { V3ERROR_NA_RETURN(""); }
|
|
|
|
|
virtual bool cleanOut() const override { return true; }
|
|
|
|
|
virtual bool same(const AstNode* samep) const override {
|
2021-11-26 23:55:36 +01:00
|
|
|
const AstConst* const sp = static_cast<const AstConst*>(samep);
|
2020-04-15 13:58:34 +02:00
|
|
|
return num().isCaseEq(sp->num());
|
|
|
|
|
}
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual int instrCount() const override { return widthInstrs(); }
|
2011-12-01 00:50:21 +01:00
|
|
|
bool isEqAllOnes() const { return num().isEqAllOnes(width()); }
|
2015-05-15 03:46:07 +02:00
|
|
|
bool isEqAllOnesV() const { return num().isEqAllOnes(widthMinV()); }
|
2020-07-02 13:29:52 +02:00
|
|
|
// Parse string and create appropriate type of AstConst.
|
2020-08-15 16:12:55 +02:00
|
|
|
// May return nullptr on parse failure.
|
2020-07-02 13:29:52 +02:00
|
|
|
static AstConst* parseParamLiteral(FileLine* fl, const string& literal);
|
2006-08-26 13:35:28 +02:00
|
|
|
};
|
|
|
|
|
|
2021-12-12 02:39:58 +01:00
|
|
|
class AstEmpty final : public AstNode {
|
|
|
|
|
// Represents something missing, e.g. a missing argument in FOREACH
|
|
|
|
|
public:
|
|
|
|
|
AstEmpty(FileLine* fl)
|
|
|
|
|
: ASTGEN_SUPER_Empty(fl) {}
|
|
|
|
|
ASTNODE_NODE_FUNCS(Empty)
|
|
|
|
|
virtual bool same(const AstNode* samep) const override { return true; }
|
|
|
|
|
};
|
|
|
|
|
|
2021-08-28 23:23:35 +02:00
|
|
|
class AstEmptyQueue final : public AstNodeMath {
|
|
|
|
|
public:
|
|
|
|
|
AstEmptyQueue(FileLine* fl)
|
|
|
|
|
: ASTGEN_SUPER_EmptyQueue(fl) {}
|
|
|
|
|
ASTNODE_NODE_FUNCS(EmptyQueue)
|
2021-08-28 23:44:14 +02:00
|
|
|
virtual string emitC() override { V3ERROR_NA_RETURN(""); }
|
|
|
|
|
virtual string emitVerilog() override { return "{}"; }
|
2021-08-28 23:23:35 +02:00
|
|
|
virtual bool same(const AstNode* samep) const override { return true; }
|
2021-08-28 23:44:14 +02:00
|
|
|
virtual bool cleanOut() const override { return true; }
|
2021-08-28 23:23:35 +02:00
|
|
|
};
|
|
|
|
|
|
2020-11-19 03:32:16 +01:00
|
|
|
class AstRange final : public AstNodeRange {
|
2006-08-26 13:35:28 +02:00
|
|
|
// Range specification, for use under variables and cells
|
2009-10-25 21:53:55 +01:00
|
|
|
public:
|
2020-12-07 03:13:56 +01:00
|
|
|
AstRange(FileLine* fl, AstNode* leftp, AstNode* rightp)
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_Range(fl) {
|
2020-12-07 03:13:56 +01:00
|
|
|
setOp2p(leftp);
|
|
|
|
|
setOp3p(rightp);
|
2020-04-15 13:58:34 +02:00
|
|
|
}
|
2020-12-07 03:13:56 +01:00
|
|
|
AstRange(FileLine* fl, int left, int right)
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_Range(fl) {
|
2020-12-07 03:13:56 +01:00
|
|
|
setOp2p(new AstConst(fl, left));
|
|
|
|
|
setOp3p(new AstConst(fl, right));
|
2006-08-26 13:35:28 +02:00
|
|
|
}
|
2017-07-07 02:25:59 +02:00
|
|
|
AstRange(FileLine* fl, const VNumRange& range)
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_Range(fl) {
|
2020-12-07 03:13:56 +01:00
|
|
|
setOp2p(new AstConst(fl, range.left()));
|
|
|
|
|
setOp3p(new AstConst(fl, range.right()));
|
2013-02-02 22:52:08 +01:00
|
|
|
}
|
2016-11-05 14:47:56 +01:00
|
|
|
ASTNODE_NODE_FUNCS(Range)
|
2020-12-07 03:13:56 +01:00
|
|
|
AstNode* leftp() const { return op2p(); }
|
|
|
|
|
AstNode* rightp() const { return op3p(); }
|
2020-04-15 13:58:34 +02:00
|
|
|
int leftConst() const {
|
2021-11-26 23:55:36 +01:00
|
|
|
AstConst* const constp = VN_CAST(leftp(), Const);
|
2020-04-15 13:58:34 +02:00
|
|
|
return (constp ? constp->toSInt() : 0);
|
|
|
|
|
}
|
|
|
|
|
int rightConst() const {
|
2021-11-26 23:55:36 +01:00
|
|
|
AstConst* const constp = VN_CAST(rightp(), Const);
|
2020-04-15 13:58:34 +02:00
|
|
|
return (constp ? constp->toSInt() : 0);
|
|
|
|
|
}
|
2020-12-07 03:13:56 +01:00
|
|
|
int hiConst() const {
|
2021-11-26 23:55:36 +01:00
|
|
|
const int l = leftConst();
|
|
|
|
|
const int r = rightConst();
|
2020-12-07 03:13:56 +01:00
|
|
|
return l > r ? l : r;
|
|
|
|
|
}
|
|
|
|
|
int loConst() const {
|
2021-11-26 23:55:36 +01:00
|
|
|
const int l = leftConst();
|
|
|
|
|
const int r = rightConst();
|
2020-12-07 03:13:56 +01:00
|
|
|
return l > r ? r : l;
|
|
|
|
|
}
|
|
|
|
|
int elementsConst() const { return hiConst() - loConst() + 1; }
|
|
|
|
|
bool littleEndian() const { return leftConst() < rightConst(); }
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual void dump(std::ostream& str) const override;
|
2020-04-05 16:26:53 +02:00
|
|
|
virtual string emitC() { V3ERROR_NA_RETURN(""); }
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual bool same(const AstNode* samep) const override { return true; }
|
2006-08-26 13:35:28 +02:00
|
|
|
};
|
|
|
|
|
|
2020-11-19 03:32:16 +01:00
|
|
|
class AstBracketRange final : public AstNodeRange {
|
2020-06-09 13:13:40 +02:00
|
|
|
// Parser only concept "[lhsp]", a AstUnknownRange, QueueRange or Range,
|
|
|
|
|
// unknown until lhsp type is determined
|
2019-12-01 17:52:48 +01:00
|
|
|
public:
|
2020-06-09 13:13:40 +02:00
|
|
|
AstBracketRange(FileLine* fl, AstNode* elementsp)
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_BracketRange(fl) {
|
2020-06-09 13:13:40 +02:00
|
|
|
setOp1p(elementsp);
|
2019-12-01 17:52:48 +01:00
|
|
|
}
|
2020-06-09 13:13:40 +02:00
|
|
|
ASTNODE_NODE_FUNCS(BracketRange)
|
2020-04-05 16:26:53 +02:00
|
|
|
virtual string emitC() { V3ERROR_NA_RETURN(""); }
|
|
|
|
|
virtual string emitVerilog() { V3ERROR_NA_RETURN(""); }
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual bool same(const AstNode* samep) const override { return true; }
|
2020-06-09 13:13:40 +02:00
|
|
|
// Will be removed in V3Width, which relies on this
|
|
|
|
|
// being a child not a dtype pointed node
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual bool maybePointedTo() const override { return false; }
|
2020-06-09 13:13:40 +02:00
|
|
|
AstNode* elementsp() const { return op1p(); }
|
2019-12-01 18:35:49 +01:00
|
|
|
};
|
|
|
|
|
|
2020-11-19 03:32:16 +01:00
|
|
|
class AstUnsizedRange final : public AstNodeRange {
|
2017-12-17 22:28:58 +01:00
|
|
|
// Unsized range specification, for open arrays
|
|
|
|
|
public:
|
2020-01-25 21:29:44 +01:00
|
|
|
explicit AstUnsizedRange(FileLine* fl)
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_UnsizedRange(fl) {}
|
2017-12-17 22:28:58 +01:00
|
|
|
ASTNODE_NODE_FUNCS(UnsizedRange)
|
2020-04-05 16:26:53 +02:00
|
|
|
virtual string emitC() { V3ERROR_NA_RETURN(""); }
|
2017-12-17 22:28:58 +01:00
|
|
|
virtual string emitVerilog() { return "[]"; }
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual bool same(const AstNode* samep) const override { return true; }
|
2017-12-17 22:28:58 +01:00
|
|
|
};
|
|
|
|
|
|
2020-11-19 03:32:16 +01:00
|
|
|
class AstGatePin final : public AstNodeMath {
|
2014-05-16 02:57:09 +02:00
|
|
|
// Possibly expand a gate primitive input pin value to match the range of the gate primitive
|
2014-09-12 03:28:53 +02:00
|
|
|
public:
|
2020-01-25 21:29:44 +01:00
|
|
|
AstGatePin(FileLine* fl, AstNode* lhsp, AstRange* rangep)
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_GatePin(fl) {
|
2020-04-15 13:58:34 +02:00
|
|
|
setOp1p(lhsp);
|
|
|
|
|
setOp2p(rangep);
|
2014-05-16 02:57:09 +02:00
|
|
|
}
|
2016-11-05 14:47:56 +01:00
|
|
|
ASTNODE_NODE_FUNCS(GatePin)
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual string emitVerilog() override { return "%l"; }
|
|
|
|
|
virtual string emitC() override { V3ERROR_NA_RETURN(""); }
|
|
|
|
|
virtual bool cleanOut() const override { return true; }
|
2019-05-19 22:13:13 +02:00
|
|
|
AstNode* exprp() const { return op1p(); } // op1 = Pin expression
|
2021-10-22 14:56:48 +02:00
|
|
|
AstRange* rangep() const { return VN_AS(op2p(), Range); } // op2 = Range of pin
|
2014-05-16 02:57:09 +02:00
|
|
|
};
|
|
|
|
|
|
2020-04-05 15:30:23 +02:00
|
|
|
//######################################################################
|
|
|
|
|
// Classes
|
|
|
|
|
|
2020-11-19 03:32:16 +01:00
|
|
|
class AstClassPackage final : public AstNodeModule {
|
2020-04-05 15:30:23 +02:00
|
|
|
// The static information portion of a class (treated similarly to a package)
|
2020-08-15 19:11:27 +02:00
|
|
|
AstClass* m_classp
|
|
|
|
|
= nullptr; // Class package this is under (weak pointer, hard link is other way)
|
2020-04-05 15:30:23 +02:00
|
|
|
public:
|
|
|
|
|
AstClassPackage(FileLine* fl, const string& name)
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_ClassPackage(fl, name) {}
|
2020-04-05 15:30:23 +02:00
|
|
|
ASTNODE_NODE_FUNCS(ClassPackage)
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual string verilogKwd() const override { return "/*class*/package"; }
|
|
|
|
|
virtual const char* broken() const override;
|
2021-12-13 00:10:52 +01:00
|
|
|
virtual void cloneRelink() override;
|
2021-03-17 03:52:29 +01:00
|
|
|
virtual bool timescaleMatters() const override { return false; }
|
2020-04-05 15:30:23 +02:00
|
|
|
AstClass* classp() const { return m_classp; }
|
|
|
|
|
void classp(AstClass* classp) { m_classp = classp; }
|
|
|
|
|
};
|
|
|
|
|
|
2020-11-19 03:32:16 +01:00
|
|
|
class AstClass final : public AstNodeModule {
|
2020-04-05 15:30:23 +02:00
|
|
|
// TYPES
|
2021-03-13 00:10:45 +01:00
|
|
|
using MemberNameMap = std::map<const std::string, AstNode*>;
|
2019-12-23 21:03:04 +01:00
|
|
|
// MEMBERS
|
2020-04-05 15:30:23 +02:00
|
|
|
MemberNameMap m_members; // Members or method children
|
2020-11-25 03:56:03 +01:00
|
|
|
AstClassPackage* m_classOrPackagep = nullptr; // Class package this is under
|
2020-08-24 01:37:56 +02:00
|
|
|
bool m_virtual = false; // Virtual class
|
2020-08-24 02:00:39 +02:00
|
|
|
bool m_extended = false; // Is extension or extended by other classes
|
2020-04-05 15:30:23 +02:00
|
|
|
void insertCache(AstNode* nodep);
|
2020-04-15 13:58:34 +02:00
|
|
|
|
2019-12-23 21:03:04 +01:00
|
|
|
public:
|
|
|
|
|
AstClass(FileLine* fl, const string& name)
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_Class(fl, name) {}
|
2019-12-23 21:03:04 +01:00
|
|
|
ASTNODE_NODE_FUNCS(Class)
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual string verilogKwd() const override { return "class"; }
|
|
|
|
|
virtual bool maybePointedTo() const override { return true; }
|
|
|
|
|
virtual void dump(std::ostream& str) const override;
|
|
|
|
|
virtual const char* broken() const override {
|
2020-04-05 15:30:23 +02:00
|
|
|
BROKEN_BASE_RTN(AstNodeModule::broken());
|
2020-11-25 03:56:03 +01:00
|
|
|
BROKEN_RTN(m_classOrPackagep && !m_classOrPackagep->brokeExists());
|
2020-08-15 16:12:55 +02:00
|
|
|
return nullptr;
|
2020-04-05 15:30:23 +02:00
|
|
|
}
|
2021-12-13 00:10:52 +01:00
|
|
|
virtual void cloneRelink() override {
|
|
|
|
|
AstNodeModule::cloneRelink();
|
|
|
|
|
if (m_classOrPackagep && m_classOrPackagep->clonep()) {
|
|
|
|
|
m_classOrPackagep = m_classOrPackagep->clonep();
|
|
|
|
|
}
|
|
|
|
|
}
|
2021-03-17 03:52:29 +01:00
|
|
|
virtual bool timescaleMatters() const override { return false; }
|
2020-04-05 15:30:23 +02:00
|
|
|
// op1/op2/op3 in AstNodeModule
|
2020-11-25 03:56:03 +01:00
|
|
|
AstClassPackage* classOrPackagep() const { return m_classOrPackagep; }
|
|
|
|
|
void classOrPackagep(AstClassPackage* classpackagep) { m_classOrPackagep = classpackagep; }
|
2020-04-05 15:30:23 +02:00
|
|
|
AstNode* membersp() const { return stmtsp(); } // op2 = List of statements
|
|
|
|
|
void addMembersp(AstNode* nodep) {
|
|
|
|
|
insertCache(nodep);
|
|
|
|
|
addStmtp(nodep);
|
|
|
|
|
}
|
2021-10-22 14:56:48 +02:00
|
|
|
AstClassExtends* extendsp() const { return VN_AS(op4p(), ClassExtends); }
|
2020-08-24 01:37:56 +02:00
|
|
|
void extendsp(AstNode* nodep) { addNOp4p(nodep); }
|
2020-04-05 15:30:23 +02:00
|
|
|
void clearCache() { m_members.clear(); }
|
|
|
|
|
void repairCache();
|
|
|
|
|
AstNode* findMember(const string& name) const {
|
2020-08-16 17:43:49 +02:00
|
|
|
const auto it = m_members.find(name);
|
2020-08-15 16:12:55 +02:00
|
|
|
return (it == m_members.end()) ? nullptr : it->second;
|
2020-04-05 15:30:23 +02:00
|
|
|
}
|
2020-08-24 02:00:39 +02:00
|
|
|
bool isExtended() const { return m_extended; }
|
|
|
|
|
void isExtended(bool flag) { m_extended = flag; }
|
2020-06-30 03:03:14 +02:00
|
|
|
bool isVirtual() const { return m_virtual; }
|
|
|
|
|
void isVirtual(bool flag) { m_virtual = flag; }
|
2020-11-29 04:01:11 +01:00
|
|
|
// Return true if this class is an extension of base class (SLOW)
|
|
|
|
|
// Accepts nullptrs
|
|
|
|
|
static bool isClassExtendedFrom(const AstClass* refClassp, const AstClass* baseClassp);
|
2020-04-05 15:30:23 +02:00
|
|
|
};
|
|
|
|
|
|
2020-11-19 03:32:16 +01:00
|
|
|
class AstClassExtends final : public AstNode {
|
2020-05-22 03:31:15 +02:00
|
|
|
// Children: List of AstParseRef for packages/classes
|
|
|
|
|
// during early parse, then moves to dtype
|
2020-04-05 15:30:23 +02:00
|
|
|
public:
|
2020-05-22 03:31:15 +02:00
|
|
|
AstClassExtends(FileLine* fl, AstNode* classOrPkgsp)
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_ClassExtends(fl) {
|
2020-08-24 01:37:56 +02:00
|
|
|
setNOp2p(classOrPkgsp); // Only for parser
|
2020-04-05 15:30:23 +02:00
|
|
|
}
|
|
|
|
|
ASTNODE_NODE_FUNCS(ClassExtends)
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual bool hasDType() const override { return true; }
|
2020-08-24 01:37:56 +02:00
|
|
|
virtual string verilogKwd() const override { return "extends"; }
|
2021-10-22 14:56:48 +02:00
|
|
|
AstNodeDType* childDTypep() const { return VN_AS(op1p(), NodeDType); }
|
2020-08-24 01:37:56 +02:00
|
|
|
void childDTypep(AstNodeDType* nodep) { setOp1p(nodep); }
|
|
|
|
|
AstNode* classOrPkgsp() const { return op2p(); }
|
2020-04-05 15:30:23 +02:00
|
|
|
AstClass* classp() const; // Class being extended (after link)
|
2019-12-23 21:03:04 +01:00
|
|
|
};
|
|
|
|
|
|
2009-11-05 04:31:53 +01:00
|
|
|
//######################################################################
|
|
|
|
|
//==== Data Types
|
|
|
|
|
|
2020-11-19 03:32:16 +01:00
|
|
|
class AstParamTypeDType final : public AstNodeDType {
|
2016-03-15 02:51:31 +01:00
|
|
|
// Parents: MODULE
|
|
|
|
|
// A parameter type statement; much like a var or typedef
|
|
|
|
|
private:
|
2021-11-26 23:55:36 +01:00
|
|
|
const AstVarType m_varType; // Type of variable (for localparam vs. param)
|
2020-04-15 13:58:34 +02:00
|
|
|
string m_name; // Name of variable
|
2016-03-15 02:51:31 +01:00
|
|
|
public:
|
2020-04-15 13:58:34 +02:00
|
|
|
AstParamTypeDType(FileLine* fl, AstVarType type, const string& name, VFlagChildDType,
|
|
|
|
|
AstNodeDType* dtp)
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_ParamTypeDType(fl)
|
2020-08-16 17:40:42 +02:00
|
|
|
, m_varType{type}
|
|
|
|
|
, m_name{name} {
|
2019-05-19 22:13:13 +02:00
|
|
|
childDTypep(dtp); // Only for parser
|
2020-08-15 16:12:55 +02:00
|
|
|
dtypep(nullptr); // V3Width will resolve
|
2016-03-15 02:51:31 +01:00
|
|
|
}
|
2016-11-05 14:47:56 +01:00
|
|
|
ASTNODE_NODE_FUNCS(ParamTypeDType)
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual AstNodeDType* getChildDTypep() const override { return childDTypep(); }
|
2020-04-15 13:58:34 +02:00
|
|
|
// op1 = Type assigning to
|
2021-10-22 14:56:48 +02:00
|
|
|
AstNodeDType* childDTypep() const { return VN_AS(op1p(), NodeDType); }
|
2019-05-19 22:13:13 +02:00
|
|
|
void childDTypep(AstNodeDType* nodep) { setOp1p(nodep); }
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual AstNodeDType* subDTypep() const override {
|
|
|
|
|
return dtypep() ? dtypep() : childDTypep();
|
|
|
|
|
}
|
|
|
|
|
virtual AstBasicDType* basicp() const override { return subDTypep()->basicp(); }
|
|
|
|
|
virtual AstNodeDType* skipRefp() const override { return subDTypep()->skipRefp(); }
|
|
|
|
|
virtual AstNodeDType* skipRefToConstp() const override {
|
|
|
|
|
return subDTypep()->skipRefToConstp();
|
|
|
|
|
}
|
|
|
|
|
virtual AstNodeDType* skipRefToEnump() const override { return subDTypep()->skipRefToEnump(); }
|
|
|
|
|
virtual bool similarDType(AstNodeDType* samep) const override {
|
2021-11-26 23:55:36 +01:00
|
|
|
const AstParamTypeDType* const sp = static_cast<const AstParamTypeDType*>(samep);
|
2020-11-28 19:46:14 +01:00
|
|
|
return type() == samep->type() && sp
|
|
|
|
|
&& this->subDTypep()->skipRefp()->similarDType(sp->subDTypep()->skipRefp());
|
2017-04-28 12:10:14 +02:00
|
|
|
}
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual int widthAlignBytes() const override { return dtypep()->widthAlignBytes(); }
|
|
|
|
|
virtual int widthTotalBytes() const override { return dtypep()->widthTotalBytes(); }
|
2016-03-15 02:51:31 +01:00
|
|
|
// METHODS
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual string name() const override { return m_name; }
|
|
|
|
|
virtual bool maybePointedTo() const override { return true; }
|
|
|
|
|
virtual bool hasDType() const override { return true; }
|
|
|
|
|
virtual void name(const string& flag) override { m_name = flag; }
|
2016-03-15 02:51:31 +01:00
|
|
|
AstVarType varType() const { return m_varType; } // * = Type of variable
|
|
|
|
|
bool isParam() const { return true; }
|
2020-04-15 13:58:34 +02:00
|
|
|
bool isGParam() const { return (varType() == AstVarType::GPARAM); }
|
2020-12-13 01:19:16 +01:00
|
|
|
virtual bool isCompound() const override {
|
|
|
|
|
v3fatalSrc("call isCompound on subdata type, not reference");
|
|
|
|
|
return false;
|
|
|
|
|
}
|
2016-03-15 02:51:31 +01:00
|
|
|
};
|
|
|
|
|
|
2020-11-19 03:32:16 +01:00
|
|
|
class AstTypedef final : public AstNode {
|
2009-11-09 14:20:28 +01:00
|
|
|
private:
|
2020-04-15 13:58:34 +02:00
|
|
|
string m_name;
|
|
|
|
|
bool m_attrPublic;
|
|
|
|
|
string m_tag; // Holds the string of the verilator tag -- used in XML output.
|
2009-11-07 05:16:06 +01:00
|
|
|
public:
|
2020-04-15 13:58:34 +02:00
|
|
|
AstTypedef(FileLine* fl, const string& name, AstNode* attrsp, VFlagChildDType,
|
|
|
|
|
AstNodeDType* dtp)
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_Typedef(fl)
|
2020-08-16 17:40:42 +02:00
|
|
|
, m_name{name} {
|
2019-05-19 22:13:13 +02:00
|
|
|
childDTypep(dtp); // Only for parser
|
|
|
|
|
addAttrsp(attrsp);
|
2020-08-15 16:12:55 +02:00
|
|
|
dtypep(nullptr); // V3Width will resolve
|
2019-05-19 22:13:13 +02:00
|
|
|
m_attrPublic = false;
|
2009-11-07 05:16:06 +01:00
|
|
|
}
|
2016-11-05 14:47:56 +01:00
|
|
|
ASTNODE_NODE_FUNCS(Typedef)
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual void dump(std::ostream& str) const override;
|
|
|
|
|
virtual AstNodeDType* getChildDTypep() const override { return childDTypep(); }
|
2020-04-15 13:58:34 +02:00
|
|
|
// op1 = Type assigning to
|
2021-10-22 14:56:48 +02:00
|
|
|
AstNodeDType* childDTypep() const { return VN_AS(op1p(), NodeDType); }
|
2019-05-19 22:13:13 +02:00
|
|
|
void childDTypep(AstNodeDType* nodep) { setOp1p(nodep); }
|
2017-11-10 00:04:16 +01:00
|
|
|
virtual AstNodeDType* subDTypep() const { return dtypep() ? dtypep() : childDTypep(); }
|
2019-05-19 22:13:13 +02:00
|
|
|
void addAttrsp(AstNode* nodep) { addNOp4p(nodep); }
|
|
|
|
|
AstNode* attrsp() const { return op4p(); } // op4 = Attributes during early parse
|
2009-11-07 05:16:06 +01:00
|
|
|
// METHODS
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual string name() const override { return m_name; }
|
|
|
|
|
virtual bool maybePointedTo() const override { return true; }
|
|
|
|
|
virtual bool hasDType() const override { return true; }
|
|
|
|
|
virtual void name(const string& flag) override { m_name = flag; }
|
2014-11-07 13:50:11 +01:00
|
|
|
bool attrPublic() const { return m_attrPublic; }
|
|
|
|
|
void attrPublic(bool flag) { m_attrPublic = flag; }
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual void tag(const string& text) override { m_tag = text; }
|
|
|
|
|
virtual string tag() const override { return m_tag; }
|
2009-11-07 05:16:06 +01:00
|
|
|
};
|
|
|
|
|
|
2020-11-19 03:32:16 +01:00
|
|
|
class AstTypedefFwd final : public AstNode {
|
2009-11-07 05:16:06 +01:00
|
|
|
// Forward declaration of a type; stripped after netlist parsing is complete
|
2009-11-09 14:20:28 +01:00
|
|
|
private:
|
2020-04-15 13:58:34 +02:00
|
|
|
string m_name;
|
|
|
|
|
|
2009-11-07 05:16:06 +01:00
|
|
|
public:
|
|
|
|
|
AstTypedefFwd(FileLine* fl, const string& name)
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_TypedefFwd(fl)
|
2020-08-16 17:40:42 +02:00
|
|
|
, m_name{name} {}
|
2016-11-05 14:47:56 +01:00
|
|
|
ASTNODE_NODE_FUNCS(TypedefFwd)
|
2009-11-07 05:16:06 +01:00
|
|
|
// METHODS
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual string name() const override { return m_name; }
|
|
|
|
|
virtual bool maybePointedTo() const override { return true; }
|
2009-11-07 05:16:06 +01:00
|
|
|
};
|
|
|
|
|
|
2020-11-19 03:32:16 +01:00
|
|
|
class AstDefImplicitDType final : public AstNodeDType {
|
2010-01-07 01:04:20 +01:00
|
|
|
// 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
|
|
|
|
|
private:
|
2020-04-15 13:58:34 +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)
|
2021-05-21 15:34:27 +02:00
|
|
|
const int m_uniqueNum;
|
2020-04-15 13:58:34 +02:00
|
|
|
|
2010-01-07 01:04:20 +01:00
|
|
|
public:
|
2020-04-15 13:58:34 +02:00
|
|
|
AstDefImplicitDType(FileLine* fl, const string& name, void* containerp, VFlagChildDType,
|
|
|
|
|
AstNodeDType* dtp)
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_DefImplicitDType(fl)
|
2020-08-16 17:40:42 +02:00
|
|
|
, m_name{name}
|
2021-05-21 15:34:27 +02:00
|
|
|
, m_containerp{containerp}
|
|
|
|
|
, m_uniqueNum{uniqueNumInc()} {
|
2019-05-19 22:13:13 +02:00
|
|
|
childDTypep(dtp); // Only for parser
|
2020-08-15 16:12:55 +02:00
|
|
|
dtypep(nullptr); // V3Width will resolve
|
2010-01-07 01:04:20 +01:00
|
|
|
}
|
2016-11-05 14:47:56 +01:00
|
|
|
ASTNODE_NODE_FUNCS(DefImplicitDType)
|
2021-05-21 15:34:27 +02:00
|
|
|
int uniqueNum() const { return m_uniqueNum; }
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual bool same(const AstNode* samep) const override {
|
2021-11-26 23:55:36 +01:00
|
|
|
const AstDefImplicitDType* const sp = static_cast<const AstDefImplicitDType*>(samep);
|
2021-05-21 15:34:27 +02:00
|
|
|
return uniqueNum() == sp->uniqueNum();
|
2020-04-15 13:58:34 +02:00
|
|
|
}
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual bool similarDType(AstNodeDType* samep) const override {
|
2020-04-15 13:58:34 +02:00
|
|
|
return type() == samep->type() && same(samep);
|
|
|
|
|
}
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual AstNodeDType* getChildDTypep() const override { return childDTypep(); }
|
2020-04-15 13:58:34 +02:00
|
|
|
// op1 = Range of variable
|
2021-10-22 14:56:48 +02:00
|
|
|
AstNodeDType* childDTypep() const { return VN_AS(op1p(), NodeDType); }
|
2019-05-19 22:13:13 +02:00
|
|
|
void childDTypep(AstNodeDType* nodep) { setOp1p(nodep); }
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual AstNodeDType* subDTypep() const override {
|
|
|
|
|
return dtypep() ? dtypep() : childDTypep();
|
|
|
|
|
}
|
2019-05-19 22:13:13 +02:00
|
|
|
void* containerp() const { return m_containerp; }
|
2010-01-07 01:04:20 +01:00
|
|
|
// METHODS
|
2020-04-15 13:58:34 +02:00
|
|
|
// op1 = Range of variable
|
|
|
|
|
AstNodeDType* dtypeSkipRefp() const { return dtypep()->skipRefp(); }
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual AstBasicDType* basicp() const override { return subDTypep()->basicp(); }
|
|
|
|
|
virtual AstNodeDType* skipRefp() const override { return (AstNodeDType*)this; }
|
|
|
|
|
virtual AstNodeDType* skipRefToConstp() const override { return (AstNodeDType*)this; }
|
|
|
|
|
virtual AstNodeDType* skipRefToEnump() const override { return (AstNodeDType*)this; }
|
|
|
|
|
virtual int widthAlignBytes() const override { return dtypep()->widthAlignBytes(); }
|
|
|
|
|
virtual int widthTotalBytes() const override { return dtypep()->widthTotalBytes(); }
|
|
|
|
|
virtual string name() const override { return m_name; }
|
|
|
|
|
virtual void name(const string& flag) override { m_name = flag; }
|
2020-12-13 01:19:16 +01:00
|
|
|
virtual bool isCompound() const override { return false; }
|
2010-01-07 01:04:20 +01:00
|
|
|
};
|
|
|
|
|
|
2020-11-19 03:32:16 +01:00
|
|
|
class AstAssocArrayDType final : public AstNodeDType {
|
2019-12-01 17:52:48 +01:00
|
|
|
// Associative array data type, ie "[some_dtype]"
|
|
|
|
|
// Children: DTYPE (moved to refDTypep() in V3Width)
|
|
|
|
|
// Children: DTYPE (the key, which remains here as a pointer)
|
|
|
|
|
private:
|
|
|
|
|
AstNodeDType* m_refDTypep; // Elements of this type (after widthing)
|
|
|
|
|
AstNodeDType* m_keyDTypep; // Keys of this type (after widthing)
|
|
|
|
|
public:
|
|
|
|
|
AstAssocArrayDType(FileLine* fl, VFlagChildDType, AstNodeDType* dtp, AstNodeDType* keyDtp)
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_AssocArrayDType(fl) {
|
2019-12-01 17:52:48 +01:00
|
|
|
childDTypep(dtp); // Only for parser
|
|
|
|
|
keyChildDTypep(keyDtp); // Only for parser
|
2020-08-15 16:12:55 +02:00
|
|
|
refDTypep(nullptr);
|
|
|
|
|
keyDTypep(nullptr);
|
|
|
|
|
dtypep(nullptr); // V3Width will resolve
|
2019-12-01 17:52:48 +01:00
|
|
|
}
|
2021-12-11 17:29:01 +01:00
|
|
|
AstAssocArrayDType(FileLine* fl, AstNodeDType* dtp, AstNodeDType* keyDtp)
|
|
|
|
|
: ASTGEN_SUPER_AssocArrayDType(fl) {
|
|
|
|
|
refDTypep(dtp);
|
|
|
|
|
keyDTypep(keyDtp);
|
|
|
|
|
dtypep(dtp);
|
|
|
|
|
}
|
2019-12-01 17:52:48 +01:00
|
|
|
ASTNODE_NODE_FUNCS(AssocArrayDType)
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual const char* broken() const override {
|
2019-12-01 17:52:48 +01:00
|
|
|
BROKEN_RTN(!((m_refDTypep && !childDTypep() && m_refDTypep->brokeExists())
|
|
|
|
|
|| (!m_refDTypep && childDTypep())));
|
|
|
|
|
BROKEN_RTN(!((m_keyDTypep && !childDTypep() && m_keyDTypep->brokeExists())
|
|
|
|
|
|| (!m_keyDTypep && childDTypep())));
|
2020-08-15 16:12:55 +02:00
|
|
|
return nullptr;
|
2020-04-15 13:58:34 +02:00
|
|
|
}
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual void cloneRelink() override {
|
2021-02-22 03:25:21 +01:00
|
|
|
if (m_refDTypep && m_refDTypep->clonep()) m_refDTypep = m_refDTypep->clonep();
|
|
|
|
|
if (m_keyDTypep && m_keyDTypep->clonep()) m_keyDTypep = m_keyDTypep->clonep();
|
2020-04-15 13:58:34 +02:00
|
|
|
}
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual bool same(const AstNode* samep) const override {
|
2021-11-26 23:55:36 +01:00
|
|
|
const AstAssocArrayDType* const asamep = static_cast<const AstAssocArrayDType*>(samep);
|
2020-09-08 03:13:38 +02:00
|
|
|
if (!asamep->subDTypep()) return false;
|
|
|
|
|
if (!asamep->keyDTypep()) return false;
|
2020-04-15 13:58:34 +02:00
|
|
|
return (subDTypep() == asamep->subDTypep() && keyDTypep() == asamep->keyDTypep());
|
|
|
|
|
}
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual bool similarDType(AstNodeDType* samep) const override {
|
2021-11-26 23:55:36 +01:00
|
|
|
const AstAssocArrayDType* const asamep = static_cast<const AstAssocArrayDType*>(samep);
|
2020-11-28 19:46:14 +01:00
|
|
|
return type() == samep->type() && asamep->subDTypep()
|
|
|
|
|
&& subDTypep()->skipRefp()->similarDType(asamep->subDTypep()->skipRefp());
|
2019-12-01 17:52:48 +01:00
|
|
|
}
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual string prettyDTypeName() const override;
|
|
|
|
|
virtual void dumpSmall(std::ostream& str) const override;
|
|
|
|
|
virtual AstNodeDType* getChildDTypep() const override { return childDTypep(); }
|
|
|
|
|
virtual AstNodeDType* getChild2DTypep() const override { return keyChildDTypep(); }
|
2020-04-15 13:58:34 +02:00
|
|
|
// op1 = Range of variable
|
2021-10-22 14:56:48 +02:00
|
|
|
AstNodeDType* childDTypep() const { return VN_AS(op1p(), NodeDType); }
|
2019-12-01 17:52:48 +01:00
|
|
|
void childDTypep(AstNodeDType* nodep) { setOp1p(nodep); }
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual AstNodeDType* subDTypep() const override {
|
|
|
|
|
return m_refDTypep ? m_refDTypep : childDTypep();
|
|
|
|
|
}
|
2019-12-01 17:52:48 +01:00
|
|
|
void refDTypep(AstNodeDType* nodep) { m_refDTypep = nodep; }
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual AstNodeDType* virtRefDTypep() const override { return m_refDTypep; }
|
|
|
|
|
virtual void virtRefDTypep(AstNodeDType* nodep) override { refDTypep(nodep); }
|
|
|
|
|
virtual AstNodeDType* virtRefDType2p() const override { return m_keyDTypep; }
|
|
|
|
|
virtual void virtRefDType2p(AstNodeDType* nodep) override { keyDTypep(nodep); }
|
2019-12-01 17:52:48 +01:00
|
|
|
//
|
|
|
|
|
AstNodeDType* keyDTypep() const { return m_keyDTypep ? m_keyDTypep : keyChildDTypep(); }
|
|
|
|
|
void keyDTypep(AstNodeDType* nodep) { m_keyDTypep = nodep; }
|
2020-04-15 13:58:34 +02:00
|
|
|
// op1 = Range of variable
|
2021-10-22 14:56:48 +02:00
|
|
|
AstNodeDType* keyChildDTypep() const { return VN_AS(op2p(), NodeDType); }
|
2019-12-01 17:52:48 +01:00
|
|
|
void keyChildDTypep(AstNodeDType* nodep) { setOp2p(nodep); }
|
|
|
|
|
// METHODS
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual AstBasicDType* basicp() const override { return nullptr; }
|
|
|
|
|
virtual AstNodeDType* skipRefp() const override { return (AstNodeDType*)this; }
|
|
|
|
|
virtual AstNodeDType* skipRefToConstp() const override { return (AstNodeDType*)this; }
|
|
|
|
|
virtual AstNodeDType* skipRefToEnump() const override { return (AstNodeDType*)this; }
|
|
|
|
|
virtual int widthAlignBytes() const override { return subDTypep()->widthAlignBytes(); }
|
|
|
|
|
virtual int widthTotalBytes() const override { return subDTypep()->widthTotalBytes(); }
|
2020-12-13 01:19:16 +01:00
|
|
|
virtual bool isCompound() const override { return true; }
|
2019-12-01 17:52:48 +01:00
|
|
|
};
|
|
|
|
|
|
2020-11-19 03:32:16 +01:00
|
|
|
class AstBracketArrayDType final : public AstNodeDType {
|
2020-06-09 13:13:40 +02:00
|
|
|
// Associative/Queue/Normal array data type, ie "[dtype_or_expr]"
|
|
|
|
|
// only for early parsing then becomes another data type
|
|
|
|
|
// Children: DTYPE (moved to refDTypep() in V3Width)
|
|
|
|
|
// Children: DTYPE (the key)
|
|
|
|
|
public:
|
|
|
|
|
AstBracketArrayDType(FileLine* fl, VFlagChildDType, AstNodeDType* dtp, AstNode* elementsp)
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_BracketArrayDType(fl) {
|
2020-06-09 13:13:40 +02:00
|
|
|
setOp1p(dtp); // Only for parser
|
|
|
|
|
setOp2p(elementsp); // Only for parser
|
|
|
|
|
}
|
|
|
|
|
ASTNODE_NODE_FUNCS(BracketArrayDType)
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual bool similarDType(AstNodeDType* samep) const override { V3ERROR_NA_RETURN(false); }
|
2020-06-09 13:13:40 +02:00
|
|
|
// op1 = Range of variable
|
2021-10-22 14:56:48 +02:00
|
|
|
AstNodeDType* childDTypep() const { return VN_AS(op1p(), NodeDType); }
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual AstNodeDType* subDTypep() const override { return childDTypep(); }
|
2020-06-09 13:13:40 +02:00
|
|
|
// op2 = Range of variable
|
|
|
|
|
AstNode* elementsp() const { return op2p(); }
|
|
|
|
|
// METHODS
|
|
|
|
|
// Will be removed in V3Width, which relies on this
|
|
|
|
|
// being a child not a dtype pointed node
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual bool maybePointedTo() const override { return false; }
|
|
|
|
|
virtual AstBasicDType* basicp() const override { return nullptr; }
|
|
|
|
|
virtual AstNodeDType* skipRefp() const override { return (AstNodeDType*)this; }
|
|
|
|
|
virtual AstNodeDType* skipRefToConstp() const override { return (AstNodeDType*)this; }
|
|
|
|
|
virtual AstNodeDType* skipRefToEnump() const override { return (AstNodeDType*)this; }
|
|
|
|
|
virtual int widthAlignBytes() const override { V3ERROR_NA_RETURN(0); }
|
|
|
|
|
virtual int widthTotalBytes() const override { V3ERROR_NA_RETURN(0); }
|
2020-12-13 01:19:16 +01:00
|
|
|
virtual bool isCompound() const override { return true; }
|
2020-06-09 13:13:40 +02:00
|
|
|
};
|
|
|
|
|
|
2020-11-19 03:32:16 +01:00
|
|
|
class AstDynArrayDType final : public AstNodeDType {
|
2020-03-07 16:24:27 +01:00
|
|
|
// Dynamic array data type, ie "[]"
|
|
|
|
|
// Children: DTYPE (moved to refDTypep() in V3Width)
|
|
|
|
|
private:
|
|
|
|
|
AstNodeDType* m_refDTypep; // Elements of this type (after widthing)
|
|
|
|
|
public:
|
|
|
|
|
AstDynArrayDType(FileLine* fl, VFlagChildDType, AstNodeDType* dtp)
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_DynArrayDType(fl) {
|
2020-03-07 16:24:27 +01:00
|
|
|
childDTypep(dtp); // Only for parser
|
2020-08-15 16:12:55 +02:00
|
|
|
refDTypep(nullptr);
|
|
|
|
|
dtypep(nullptr); // V3Width will resolve
|
2020-03-07 16:24:27 +01:00
|
|
|
}
|
|
|
|
|
AstDynArrayDType(FileLine* fl, AstNodeDType* dtp)
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_DynArrayDType(fl) {
|
2020-03-07 16:24:27 +01:00
|
|
|
refDTypep(dtp);
|
2020-08-15 16:12:55 +02:00
|
|
|
dtypep(nullptr); // V3Width will resolve
|
2020-03-07 16:24:27 +01:00
|
|
|
}
|
|
|
|
|
ASTNODE_NODE_FUNCS(DynArrayDType)
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual const char* broken() const override {
|
2020-03-07 16:24:27 +01:00
|
|
|
BROKEN_RTN(!((m_refDTypep && !childDTypep() && m_refDTypep->brokeExists())
|
|
|
|
|
|| (!m_refDTypep && childDTypep())));
|
2020-08-15 16:12:55 +02:00
|
|
|
return nullptr;
|
2020-04-15 13:58:34 +02:00
|
|
|
}
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual void cloneRelink() override {
|
2021-02-22 03:25:21 +01:00
|
|
|
if (m_refDTypep && m_refDTypep->clonep()) m_refDTypep = m_refDTypep->clonep();
|
2020-04-15 13:58:34 +02:00
|
|
|
}
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual bool same(const AstNode* samep) const override {
|
2021-11-26 23:55:36 +01:00
|
|
|
const AstAssocArrayDType* const asamep = static_cast<const AstAssocArrayDType*>(samep);
|
2020-09-08 03:13:38 +02:00
|
|
|
if (!asamep->subDTypep()) return false;
|
2020-04-15 13:58:34 +02:00
|
|
|
return subDTypep() == asamep->subDTypep();
|
|
|
|
|
}
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual bool similarDType(AstNodeDType* samep) const override {
|
2021-11-26 23:55:36 +01:00
|
|
|
const AstAssocArrayDType* const asamep = static_cast<const AstAssocArrayDType*>(samep);
|
2020-11-28 19:46:14 +01:00
|
|
|
return type() == samep->type() && asamep->subDTypep()
|
|
|
|
|
&& subDTypep()->skipRefp()->similarDType(asamep->subDTypep()->skipRefp());
|
2020-03-07 16:24:27 +01:00
|
|
|
}
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual string prettyDTypeName() const override;
|
|
|
|
|
virtual void dumpSmall(std::ostream& str) const override;
|
|
|
|
|
virtual AstNodeDType* getChildDTypep() const override { return childDTypep(); }
|
2020-04-15 13:58:34 +02:00
|
|
|
// op1 = Range of variable
|
2021-10-22 14:56:48 +02:00
|
|
|
AstNodeDType* childDTypep() const { return VN_AS(op1p(), NodeDType); }
|
2020-03-07 16:24:27 +01:00
|
|
|
void childDTypep(AstNodeDType* nodep) { setOp1p(nodep); }
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual AstNodeDType* subDTypep() const override {
|
|
|
|
|
return m_refDTypep ? m_refDTypep : childDTypep();
|
|
|
|
|
}
|
2020-03-07 16:24:27 +01:00
|
|
|
void refDTypep(AstNodeDType* nodep) { m_refDTypep = nodep; }
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual AstNodeDType* virtRefDTypep() const override { return m_refDTypep; }
|
|
|
|
|
virtual void virtRefDTypep(AstNodeDType* nodep) override { refDTypep(nodep); }
|
2020-03-07 16:24:27 +01:00
|
|
|
// METHODS
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual AstBasicDType* basicp() const override { return nullptr; }
|
|
|
|
|
virtual AstNodeDType* skipRefp() const override { return (AstNodeDType*)this; }
|
|
|
|
|
virtual AstNodeDType* skipRefToConstp() const override { return (AstNodeDType*)this; }
|
|
|
|
|
virtual AstNodeDType* skipRefToEnump() const override { return (AstNodeDType*)this; }
|
|
|
|
|
virtual int widthAlignBytes() const override { return subDTypep()->widthAlignBytes(); }
|
|
|
|
|
virtual int widthTotalBytes() const override { return subDTypep()->widthTotalBytes(); }
|
2020-12-13 01:19:16 +01:00
|
|
|
virtual bool isCompound() const override { return true; }
|
2020-03-07 16:24:27 +01:00
|
|
|
};
|
|
|
|
|
|
2020-11-19 03:32:16 +01:00
|
|
|
class AstPackArrayDType final : public AstNodeArrayDType {
|
2019-09-27 09:44:23 +02:00
|
|
|
// Packed array data type, ie "some_dtype [2:0] var_name"
|
2012-04-29 16:14:13 +02:00
|
|
|
// Children: DTYPE (moved to refDTypep() in V3Width)
|
|
|
|
|
// Children: RANGE (array bounds)
|
2010-04-10 02:40:41 +02:00
|
|
|
public:
|
2013-01-12 22:19:25 +01:00
|
|
|
AstPackArrayDType(FileLine* fl, VFlagChildDType, AstNodeDType* dtp, AstRange* rangep)
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_PackArrayDType(fl) {
|
2019-05-19 22:13:13 +02:00
|
|
|
childDTypep(dtp); // Only for parser
|
2020-08-15 16:12:55 +02:00
|
|
|
refDTypep(nullptr);
|
2019-05-19 22:13:13 +02:00
|
|
|
setOp2p(rangep);
|
2020-08-15 16:12:55 +02:00
|
|
|
dtypep(nullptr); // V3Width will resolve
|
2021-06-21 00:32:57 +02:00
|
|
|
const int width = subDTypep()->width() * rangep->elementsConst();
|
2019-05-19 22:13:13 +02:00
|
|
|
widthForce(width, width);
|
2012-03-31 17:22:19 +02:00
|
|
|
}
|
2013-01-12 22:19:25 +01:00
|
|
|
AstPackArrayDType(FileLine* fl, AstNodeDType* dtp, AstRange* rangep)
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_PackArrayDType(fl) {
|
2019-05-19 22:13:13 +02:00
|
|
|
refDTypep(dtp);
|
|
|
|
|
setOp2p(rangep);
|
|
|
|
|
dtypep(this);
|
2021-06-21 00:32:57 +02:00
|
|
|
const int width = subDTypep()->width() * rangep->elementsConst();
|
2019-05-19 22:13:13 +02:00
|
|
|
widthForce(width, width);
|
2009-11-05 04:31:53 +01:00
|
|
|
}
|
2016-11-05 14:47:56 +01:00
|
|
|
ASTNODE_NODE_FUNCS(PackArrayDType)
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual string prettyDTypeName() const override;
|
2020-12-13 01:19:16 +01:00
|
|
|
virtual bool isCompound() const override { return false; }
|
2013-01-12 22:19:25 +01:00
|
|
|
};
|
|
|
|
|
|
2020-11-19 03:32:16 +01:00
|
|
|
class AstUnpackArrayDType final : public AstNodeArrayDType {
|
2013-01-12 22:19:25 +01:00
|
|
|
// Array data type, ie "some_dtype var_name [2:0]"
|
|
|
|
|
// Children: DTYPE (moved to refDTypep() in V3Width)
|
|
|
|
|
// Children: RANGE (array bounds)
|
2020-12-13 01:19:16 +01:00
|
|
|
bool m_isCompound = false; // Non-POD subDType, or parent requires compound
|
2013-01-12 22:19:25 +01:00
|
|
|
public:
|
|
|
|
|
AstUnpackArrayDType(FileLine* fl, VFlagChildDType, AstNodeDType* dtp, AstRange* rangep)
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_UnpackArrayDType(fl) {
|
2019-05-19 22:13:13 +02:00
|
|
|
childDTypep(dtp); // Only for parser
|
2020-08-15 16:12:55 +02:00
|
|
|
refDTypep(nullptr);
|
2019-05-19 22:13:13 +02:00
|
|
|
setOp2p(rangep);
|
2020-08-15 16:12:55 +02:00
|
|
|
dtypep(nullptr); // V3Width will resolve
|
2019-05-19 22:13:13 +02:00
|
|
|
// For backward compatibility AstNodeArrayDType and others inherit
|
|
|
|
|
// width and signing from the subDType/base type
|
|
|
|
|
widthFromSub(subDTypep());
|
2013-01-12 22:19:25 +01:00
|
|
|
}
|
|
|
|
|
AstUnpackArrayDType(FileLine* fl, AstNodeDType* dtp, AstRange* rangep)
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_UnpackArrayDType(fl) {
|
2019-05-19 22:13:13 +02:00
|
|
|
refDTypep(dtp);
|
|
|
|
|
setOp2p(rangep);
|
|
|
|
|
dtypep(this);
|
|
|
|
|
// For backward compatibility AstNodeArrayDType and others inherit
|
|
|
|
|
// width and signing from the subDType/base type
|
|
|
|
|
widthFromSub(subDTypep());
|
2013-01-12 22:19:25 +01:00
|
|
|
}
|
2016-11-05 14:47:56 +01:00
|
|
|
ASTNODE_NODE_FUNCS(UnpackArrayDType)
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual string prettyDTypeName() const override;
|
2020-12-13 01:19:16 +01:00
|
|
|
virtual bool same(const AstNode* samep) const override {
|
2021-11-26 23:55:36 +01:00
|
|
|
const AstUnpackArrayDType* const sp = static_cast<const AstUnpackArrayDType*>(samep);
|
2020-12-13 01:19:16 +01:00
|
|
|
return m_isCompound == sp->m_isCompound;
|
|
|
|
|
}
|
2020-11-19 14:02:58 +01:00
|
|
|
// Outer dimension comes first. The first element is this node.
|
|
|
|
|
std::vector<AstUnpackArrayDType*> unpackDimensions();
|
2020-12-13 01:19:16 +01:00
|
|
|
void isCompound(bool flag) { m_isCompound = flag; }
|
|
|
|
|
virtual bool isCompound() const override { return m_isCompound; }
|
2009-11-05 04:31:53 +01:00
|
|
|
};
|
|
|
|
|
|
2020-11-19 03:32:16 +01:00
|
|
|
class AstUnsizedArrayDType final : public AstNodeDType {
|
2017-12-17 22:28:58 +01:00
|
|
|
// Unsized/open-range Array data type, ie "some_dtype var_name []"
|
|
|
|
|
// Children: DTYPE (moved to refDTypep() in V3Width)
|
|
|
|
|
private:
|
|
|
|
|
AstNodeDType* m_refDTypep; // Elements of this type (after widthing)
|
|
|
|
|
public:
|
|
|
|
|
AstUnsizedArrayDType(FileLine* fl, VFlagChildDType, AstNodeDType* dtp)
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_UnsizedArrayDType(fl) {
|
2017-12-17 22:28:58 +01:00
|
|
|
childDTypep(dtp); // Only for parser
|
2020-08-15 16:12:55 +02:00
|
|
|
refDTypep(nullptr);
|
|
|
|
|
dtypep(nullptr); // V3Width will resolve
|
2017-12-17 22:28:58 +01:00
|
|
|
}
|
|
|
|
|
ASTNODE_NODE_FUNCS(UnsizedArrayDType)
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual const char* broken() const override {
|
2020-04-15 13:58:34 +02:00
|
|
|
BROKEN_RTN(!((m_refDTypep && !childDTypep() && m_refDTypep->brokeExists())
|
|
|
|
|
|| (!m_refDTypep && childDTypep())));
|
2020-08-15 16:12:55 +02:00
|
|
|
return nullptr;
|
2020-04-15 13:58:34 +02:00
|
|
|
}
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual void cloneRelink() override {
|
2021-02-22 03:25:21 +01:00
|
|
|
if (m_refDTypep && m_refDTypep->clonep()) m_refDTypep = m_refDTypep->clonep();
|
2020-04-15 13:58:34 +02:00
|
|
|
}
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual bool same(const AstNode* samep) const override {
|
2021-11-26 23:55:36 +01:00
|
|
|
const AstNodeArrayDType* const asamep = static_cast<const AstNodeArrayDType*>(samep);
|
2020-09-08 03:13:38 +02:00
|
|
|
if (!asamep->subDTypep()) return false;
|
2020-04-15 13:58:34 +02:00
|
|
|
return (subDTypep() == asamep->subDTypep());
|
|
|
|
|
}
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual bool similarDType(AstNodeDType* samep) const override {
|
2021-11-26 23:55:36 +01:00
|
|
|
const AstNodeArrayDType* const asamep = static_cast<const AstNodeArrayDType*>(samep);
|
2020-11-28 19:46:14 +01:00
|
|
|
return type() == samep->type() && asamep->subDTypep()
|
|
|
|
|
&& subDTypep()->skipRefp()->similarDType(asamep->subDTypep()->skipRefp());
|
2017-12-17 22:28:58 +01:00
|
|
|
}
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual void dumpSmall(std::ostream& str) const override;
|
|
|
|
|
virtual AstNodeDType* getChildDTypep() const override { return childDTypep(); }
|
2020-04-15 13:58:34 +02:00
|
|
|
// op1 = Range of variable
|
2021-10-22 14:56:48 +02:00
|
|
|
AstNodeDType* childDTypep() const { return VN_AS(op1p(), NodeDType); }
|
2017-12-17 22:28:58 +01:00
|
|
|
void childDTypep(AstNodeDType* nodep) { setOp1p(nodep); }
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual AstNodeDType* subDTypep() const override {
|
|
|
|
|
return m_refDTypep ? m_refDTypep : childDTypep();
|
|
|
|
|
}
|
2017-12-17 22:28:58 +01:00
|
|
|
void refDTypep(AstNodeDType* nodep) { m_refDTypep = nodep; }
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual AstNodeDType* virtRefDTypep() const override { return m_refDTypep; }
|
|
|
|
|
virtual void virtRefDTypep(AstNodeDType* nodep) override { refDTypep(nodep); }
|
2017-12-17 22:28:58 +01:00
|
|
|
// METHODS
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual AstBasicDType* basicp() const override { return subDTypep()->basicp(); }
|
|
|
|
|
virtual AstNodeDType* skipRefp() const override { return (AstNodeDType*)this; }
|
|
|
|
|
virtual AstNodeDType* skipRefToConstp() const override { return (AstNodeDType*)this; }
|
|
|
|
|
virtual AstNodeDType* skipRefToEnump() const override { return (AstNodeDType*)this; }
|
|
|
|
|
virtual int widthAlignBytes() const override { return subDTypep()->widthAlignBytes(); }
|
|
|
|
|
virtual int widthTotalBytes() const override { return subDTypep()->widthTotalBytes(); }
|
2020-12-13 01:19:16 +01:00
|
|
|
virtual bool isCompound() const override { return true; }
|
2017-12-17 22:28:58 +01:00
|
|
|
};
|
|
|
|
|
|
2020-11-19 03:32:16 +01:00
|
|
|
class AstBasicDType final : public AstNodeDType {
|
2009-11-02 14:06:04 +01:00
|
|
|
// Builtin atomic/vectored data type
|
2012-03-02 12:58:19 +01:00
|
|
|
// Children: RANGE (converted to constant in V3Width)
|
2009-11-02 14:06:04 +01:00
|
|
|
private:
|
2012-04-29 16:14:13 +02:00
|
|
|
struct Members {
|
2019-05-19 22:13:13 +02:00
|
|
|
AstBasicDTypeKwd 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 {
|
2020-04-15 13:58:34 +02:00
|
|
|
return rhs.m_keyword == m_keyword && rhs.m_nrange == m_nrange;
|
|
|
|
|
}
|
2012-04-29 16:14:13 +02:00
|
|
|
} m;
|
2018-06-22 12:35:27 +02:00
|
|
|
// See also in AstNodeDType: m_width, m_widthMin, m_numeric(issigned)
|
2009-11-02 14:06:04 +01:00
|
|
|
public:
|
2020-04-20 03:19:09 +02:00
|
|
|
AstBasicDType(FileLine* fl, AstBasicDTypeKwd kwd, const VSigning& signst = VSigning::NOSIGN)
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_BasicDType(fl) {
|
2020-08-15 16:12:55 +02:00
|
|
|
init(kwd, signst, 0, -1, nullptr);
|
2009-11-05 04:31:53 +01:00
|
|
|
}
|
2012-03-31 17:10:34 +02:00
|
|
|
AstBasicDType(FileLine* fl, VFlagLogicPacked, int wantwidth)
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_BasicDType(fl) {
|
2020-08-15 16:12:55 +02:00
|
|
|
init(AstBasicDTypeKwd::LOGIC, VSigning::NOSIGN, wantwidth, -1, nullptr);
|
2009-11-02 14:06:04 +01:00
|
|
|
}
|
2012-03-31 17:10:34 +02:00
|
|
|
AstBasicDType(FileLine* fl, VFlagBitPacked, int wantwidth)
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_BasicDType(fl) {
|
2020-08-15 16:12:55 +02:00
|
|
|
init(AstBasicDTypeKwd::BIT, VSigning::NOSIGN, wantwidth, -1, nullptr);
|
2012-04-29 16:14:13 +02:00
|
|
|
}
|
2020-04-20 03:19:09 +02:00
|
|
|
AstBasicDType(FileLine* fl, AstBasicDTypeKwd kwd, VSigning numer, int wantwidth, int widthmin)
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_BasicDType(fl) {
|
2020-08-15 16:12:55 +02:00
|
|
|
init(kwd, numer, wantwidth, widthmin, nullptr);
|
2012-01-26 14:29:55 +01:00
|
|
|
}
|
2020-04-20 03:19:09 +02:00
|
|
|
AstBasicDType(FileLine* fl, AstBasicDTypeKwd kwd, VSigning numer, VNumRange range,
|
2020-04-15 13:58:34 +02:00
|
|
|
int widthmin)
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_BasicDType(fl) {
|
2020-08-15 16:12:55 +02:00
|
|
|
init(kwd, numer, range.elements(), widthmin, nullptr);
|
2019-05-19 22:13:13 +02:00
|
|
|
m.m_nrange = range; // as init() presumes lsb==0, but range.lsb() might not be
|
2013-01-17 02:58:48 +01:00
|
|
|
}
|
2009-11-05 15:57:23 +01:00
|
|
|
// See also addRange in verilog.y
|
2009-11-02 14:06:04 +01:00
|
|
|
private:
|
2020-04-20 03:19:09 +02:00
|
|
|
void init(AstBasicDTypeKwd kwd, VSigning numer, int wantwidth, int wantwidthmin,
|
2020-04-15 13:58:34 +02:00
|
|
|
AstRange* rangep) {
|
2019-05-19 22:13:13 +02:00
|
|
|
// wantwidth=0 means figure it out, but if a widthmin is >=0
|
|
|
|
|
// we allow width 0 so that {{0{x}},y} works properly
|
|
|
|
|
// wantwidthmin=-1: default, use wantwidth if it is non zero
|
|
|
|
|
m.m_keyword = kwd;
|
|
|
|
|
// Implicitness: // "parameter X" is implicit and sized from initial
|
|
|
|
|
// value, "parameter reg x" not
|
2020-04-15 13:58:34 +02:00
|
|
|
if (keyword() == AstBasicDTypeKwd::LOGIC_IMPLICIT) {
|
2019-05-19 22:13:13 +02:00
|
|
|
if (rangep || wantwidth) m.m_keyword = AstBasicDTypeKwd::LOGIC;
|
|
|
|
|
}
|
2020-04-20 03:19:09 +02:00
|
|
|
if (numer == VSigning::NOSIGN) {
|
2020-04-15 13:58:34 +02:00
|
|
|
if (keyword().isSigned()) {
|
2020-04-20 03:19:09 +02:00
|
|
|
numer = VSigning::SIGNED;
|
2020-04-15 13:58:34 +02:00
|
|
|
} else if (keyword().isUnsigned()) {
|
2020-04-20 03:19:09 +02:00
|
|
|
numer = VSigning::UNSIGNED;
|
2020-04-15 13:58:34 +02:00
|
|
|
}
|
2019-05-19 22:13:13 +02:00
|
|
|
}
|
|
|
|
|
numeric(numer);
|
2020-04-15 13:58:34 +02:00
|
|
|
if (!rangep && (wantwidth || wantwidthmin >= 0)) { // Constant width
|
|
|
|
|
if (wantwidth > 1) m.m_nrange.init(wantwidth - 1, 0, false);
|
2021-06-21 00:32:57 +02:00
|
|
|
const int wmin = wantwidthmin >= 0 ? wantwidthmin : wantwidth;
|
2019-05-19 22:13:13 +02:00
|
|
|
widthForce(wantwidth, wmin);
|
|
|
|
|
} else if (!rangep) { // Set based on keyword properties
|
|
|
|
|
// V3Width will pull from this width
|
|
|
|
|
if (keyword().width() > 1 && !isOpaque()) {
|
2020-04-15 13:58:34 +02:00
|
|
|
m.m_nrange.init(keyword().width() - 1, 0, false);
|
2019-05-19 22:13:13 +02:00
|
|
|
}
|
|
|
|
|
widthForce(keyword().width(), keyword().width());
|
|
|
|
|
} else {
|
2020-04-15 13:58:34 +02:00
|
|
|
widthForce(rangep->elementsConst(),
|
|
|
|
|
rangep->elementsConst()); // Maybe unknown if parameters underneath it
|
2019-05-19 22:13:13 +02:00
|
|
|
}
|
|
|
|
|
setNOp1p(rangep);
|
|
|
|
|
dtypep(this);
|
2009-11-02 14:06:04 +01:00
|
|
|
}
|
2020-04-15 13:58:34 +02:00
|
|
|
|
2009-11-02 14:06:04 +01:00
|
|
|
public:
|
2016-11-05 14:47:56 +01:00
|
|
|
ASTNODE_NODE_FUNCS(BasicDType)
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual void dump(std::ostream& str) const override;
|
|
|
|
|
// width/widthMin/numeric compared elsewhere
|
|
|
|
|
virtual bool same(const AstNode* samep) const override {
|
2021-11-26 23:55:36 +01:00
|
|
|
const AstBasicDType* const sp = static_cast<const AstBasicDType*>(samep);
|
2020-04-15 13:58:34 +02:00
|
|
|
return m == sp->m;
|
|
|
|
|
}
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual bool similarDType(AstNodeDType* samep) const override {
|
2020-04-15 13:58:34 +02:00
|
|
|
return type() == samep->type() && same(samep);
|
|
|
|
|
}
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual string name() const override { return m.m_keyword.ascii(); }
|
|
|
|
|
virtual string prettyDTypeName() const override;
|
|
|
|
|
virtual const char* broken() const override {
|
2020-04-15 13:58:34 +02:00
|
|
|
BROKEN_RTN(dtypep() != this);
|
2020-08-15 16:12:55 +02:00
|
|
|
return nullptr;
|
2020-04-15 13:58:34 +02:00
|
|
|
}
|
2021-10-22 14:56:48 +02:00
|
|
|
AstRange* rangep() const { return VN_AS(op1p(), Range); } // op1 = Range of variable
|
2019-05-19 22:13:13 +02:00
|
|
|
void rangep(AstRange* nodep) { setNOp1p(nodep); }
|
2020-04-20 03:19:09 +02:00
|
|
|
void setSignedState(const VSigning& signst) {
|
2019-05-19 22:13:13 +02:00
|
|
|
// Note NOSIGN does NOT change the state; this is required by the parser
|
2020-04-20 03:19:09 +02:00
|
|
|
if (signst == VSigning::UNSIGNED) {
|
2020-04-15 13:58:34 +02:00
|
|
|
numeric(signst);
|
2020-04-20 03:19:09 +02:00
|
|
|
} else if (signst == VSigning::SIGNED) {
|
2020-04-15 13:58:34 +02:00
|
|
|
numeric(signst);
|
|
|
|
|
}
|
2009-11-02 14:06:04 +01:00
|
|
|
}
|
|
|
|
|
// METHODS
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual AstBasicDType* basicp() const override { return (AstBasicDType*)this; }
|
|
|
|
|
virtual AstNodeDType* skipRefp() const override { return (AstNodeDType*)this; }
|
|
|
|
|
virtual AstNodeDType* skipRefToConstp() const override { return (AstNodeDType*)this; }
|
|
|
|
|
virtual AstNodeDType* skipRefToEnump() const override { return (AstNodeDType*)this; }
|
2020-04-15 13:58:34 +02:00
|
|
|
// (Slow) recurses - Structure alignment 1,2,4 or 8 bytes (arrays affect this)
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual int widthAlignBytes() const override;
|
2020-05-25 21:34:24 +02:00
|
|
|
// (Slow) recurses - Width in bytes rounding up 1,2,4,8,12,...
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual int widthTotalBytes() const override;
|
|
|
|
|
virtual bool isFourstate() const override { return keyword().isFourstate(); }
|
2020-04-15 13:58:34 +02:00
|
|
|
AstBasicDTypeKwd keyword() const { // Avoid using - use isSomething accessors instead
|
|
|
|
|
return m.m_keyword;
|
|
|
|
|
}
|
2019-05-19 22:13:13 +02:00
|
|
|
bool isBitLogic() const { return keyword().isBitLogic(); }
|
|
|
|
|
bool isDouble() const { return keyword().isDouble(); }
|
2020-04-25 21:37:46 +02:00
|
|
|
bool isEventValue() const { return keyword().isEventValue(); }
|
2019-05-19 22:13:13 +02:00
|
|
|
bool isOpaque() const { return keyword().isOpaque(); }
|
|
|
|
|
bool isString() const { return keyword().isString(); }
|
|
|
|
|
bool isZeroInit() const { return keyword().isZeroInit(); }
|
|
|
|
|
bool isRanged() const { return rangep() || m.m_nrange.ranged(); }
|
2020-04-08 01:07:47 +02:00
|
|
|
bool isDpiBitVec() const { // DPI uses svBitVecVal
|
|
|
|
|
return keyword() == AstBasicDTypeKwd::BIT && isRanged();
|
|
|
|
|
}
|
|
|
|
|
bool isDpiLogicVec() const { // DPI uses svLogicVecVal
|
|
|
|
|
return keyword().isFourstate() && !(keyword() == AstBasicDTypeKwd::LOGIC && !isRanged());
|
|
|
|
|
}
|
|
|
|
|
bool isDpiPrimitive() const { // DPI uses a primitive type
|
|
|
|
|
return !isDpiBitVec() && !isDpiLogicVec();
|
|
|
|
|
}
|
2020-12-07 03:13:56 +01:00
|
|
|
// Generally the lo/hi/left/right funcs should be used instead of nrange()
|
2020-05-25 21:34:24 +02:00
|
|
|
const VNumRange& nrange() const { return m.m_nrange; }
|
2020-12-07 03:13:56 +01:00
|
|
|
int hi() const { return (rangep() ? rangep()->hiConst() : m.m_nrange.hi()); }
|
|
|
|
|
int lo() const { return (rangep() ? rangep()->loConst() : m.m_nrange.lo()); }
|
2021-05-07 13:17:54 +02:00
|
|
|
int elements() const { return (rangep() ? rangep()->elementsConst() : m.m_nrange.elements()); }
|
2020-12-07 03:13:56 +01:00
|
|
|
int left() const { return littleEndian() ? lo() : hi(); } // How to show a declaration
|
|
|
|
|
int right() const { return littleEndian() ? hi() : lo(); }
|
2020-04-15 13:58:34 +02:00
|
|
|
bool littleEndian() const {
|
|
|
|
|
return (rangep() ? rangep()->littleEndian() : m.m_nrange.littleEndian());
|
|
|
|
|
}
|
2019-05-19 22:13:13 +02:00
|
|
|
bool implicit() const { return keyword() == AstBasicDTypeKwd::LOGIC_IMPLICIT; }
|
2020-12-07 03:13:56 +01:00
|
|
|
VNumRange declRange() const { return isRanged() ? VNumRange{left(), right()} : VNumRange{}; }
|
2019-09-09 13:50:21 +02:00
|
|
|
void cvtRangeConst() { // Convert to smaller representation
|
2020-12-07 03:13:56 +01:00
|
|
|
if (rangep() && VN_IS(rangep()->leftp(), Const) && VN_IS(rangep()->rightp(), Const)) {
|
|
|
|
|
m.m_nrange = VNumRange{rangep()->leftConst(), rangep()->rightConst()};
|
2019-05-19 22:13:13 +02:00
|
|
|
rangep()->unlinkFrBackWithNext()->deleteTree();
|
2020-08-15 16:12:55 +02:00
|
|
|
rangep(nullptr);
|
2019-05-19 22:13:13 +02:00
|
|
|
}
|
2012-04-29 16:14:13 +02:00
|
|
|
}
|
2020-12-13 01:19:16 +01:00
|
|
|
virtual bool isCompound() const override { return isString(); }
|
2009-11-02 14:06:04 +01:00
|
|
|
};
|
|
|
|
|
|
2020-11-19 03:32:16 +01:00
|
|
|
class AstConstDType final : public AstNodeDType {
|
2011-07-02 18:45:26 +02:00
|
|
|
// 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.
|
2012-04-29 16:14:13 +02:00
|
|
|
private:
|
2020-04-15 13:58:34 +02:00
|
|
|
AstNodeDType* m_refDTypep; // Inherit from this base data type
|
2012-03-31 17:22:19 +02:00
|
|
|
public:
|
|
|
|
|
AstConstDType(FileLine* fl, VFlagChildDType, AstNodeDType* dtp)
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_ConstDType(fl) {
|
2019-05-19 22:13:13 +02:00
|
|
|
childDTypep(dtp); // Only for parser
|
2020-08-15 16:12:55 +02:00
|
|
|
refDTypep(nullptr); // V3Width will resolve
|
|
|
|
|
dtypep(nullptr); // V3Width will resolve
|
2019-05-19 22:13:13 +02:00
|
|
|
widthFromSub(subDTypep());
|
2011-07-02 18:45:26 +02:00
|
|
|
}
|
2016-11-05 14:47:56 +01:00
|
|
|
ASTNODE_NODE_FUNCS(ConstDType)
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual const char* broken() const override {
|
2020-04-15 13:58:34 +02:00
|
|
|
BROKEN_RTN(!((m_refDTypep && !childDTypep() && m_refDTypep->brokeExists())
|
|
|
|
|
|| (!m_refDTypep && childDTypep())));
|
2020-08-15 16:12:55 +02:00
|
|
|
return nullptr;
|
2020-04-15 13:58:34 +02:00
|
|
|
}
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual void cloneRelink() override {
|
2021-02-22 03:25:21 +01:00
|
|
|
if (m_refDTypep && m_refDTypep->clonep()) m_refDTypep = m_refDTypep->clonep();
|
2020-04-15 13:58:34 +02:00
|
|
|
}
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual bool same(const AstNode* samep) const override {
|
2021-11-26 23:55:36 +01:00
|
|
|
const AstConstDType* const sp = static_cast<const AstConstDType*>(samep);
|
2020-04-15 13:58:34 +02:00
|
|
|
return (m_refDTypep == sp->m_refDTypep);
|
|
|
|
|
}
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual bool similarDType(AstNodeDType* samep) const override {
|
2020-04-15 13:58:34 +02:00
|
|
|
return skipRefp()->similarDType(samep->skipRefp());
|
|
|
|
|
}
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual AstNodeDType* getChildDTypep() const override { return childDTypep(); }
|
2020-04-15 13:58:34 +02:00
|
|
|
// op1 = Range of variable
|
2021-10-22 14:56:48 +02:00
|
|
|
AstNodeDType* childDTypep() const { return VN_AS(op1p(), NodeDType); }
|
2012-04-29 16:14:13 +02:00
|
|
|
void childDTypep(AstNodeDType* nodep) { setOp1p(nodep); }
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual AstNodeDType* subDTypep() const override {
|
|
|
|
|
return m_refDTypep ? m_refDTypep : childDTypep();
|
|
|
|
|
}
|
2012-04-29 16:14:13 +02:00
|
|
|
void refDTypep(AstNodeDType* nodep) { m_refDTypep = nodep; }
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual AstNodeDType* virtRefDTypep() const override { return m_refDTypep; }
|
|
|
|
|
virtual void virtRefDTypep(AstNodeDType* nodep) override { refDTypep(nodep); }
|
2011-07-02 18:45:26 +02:00
|
|
|
// METHODS
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual AstBasicDType* basicp() const override { return subDTypep()->basicp(); }
|
|
|
|
|
virtual AstNodeDType* skipRefp() const override { return subDTypep()->skipRefp(); }
|
|
|
|
|
virtual AstNodeDType* skipRefToConstp() const override { return (AstNodeDType*)this; }
|
|
|
|
|
virtual AstNodeDType* skipRefToEnump() const override { return subDTypep()->skipRefToEnump(); }
|
|
|
|
|
virtual int widthAlignBytes() const override { return subDTypep()->widthAlignBytes(); }
|
|
|
|
|
virtual int widthTotalBytes() const override { return subDTypep()->widthTotalBytes(); }
|
2020-12-13 01:19:16 +01:00
|
|
|
virtual bool isCompound() const override {
|
|
|
|
|
v3fatalSrc("call isCompound on subdata type, not reference");
|
|
|
|
|
return false;
|
|
|
|
|
}
|
2011-07-02 18:45:26 +02:00
|
|
|
};
|
|
|
|
|
|
2020-11-19 03:32:16 +01:00
|
|
|
class AstClassRefDType final : public AstNodeDType {
|
2019-12-23 21:03:04 +01:00
|
|
|
// Reference to a class
|
2020-11-28 04:48:42 +01:00
|
|
|
// Children: PINs (for parameter settings)
|
2019-12-23 21:03:04 +01:00
|
|
|
private:
|
|
|
|
|
AstClass* m_classp; // data type pointed to, BELOW the AstTypedef
|
2020-11-25 03:56:03 +01:00
|
|
|
AstNodeModule* m_classOrPackagep = nullptr; // Package hierarchy
|
2019-12-23 21:03:04 +01:00
|
|
|
public:
|
2020-11-28 04:48:42 +01:00
|
|
|
AstClassRefDType(FileLine* fl, AstClass* classp, AstNode* paramsp)
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_ClassRefDType(fl)
|
2020-08-16 17:40:42 +02:00
|
|
|
, m_classp{classp} {
|
2019-12-23 21:03:04 +01:00
|
|
|
dtypep(this);
|
2020-11-28 04:48:42 +01:00
|
|
|
addNOp4p(paramsp);
|
2019-12-23 21:03:04 +01:00
|
|
|
}
|
|
|
|
|
ASTNODE_NODE_FUNCS(ClassRefDType)
|
|
|
|
|
// METHODS
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual const char* broken() const override {
|
2020-04-15 13:58:34 +02:00
|
|
|
BROKEN_RTN(m_classp && !m_classp->brokeExists());
|
2021-12-13 00:10:52 +01:00
|
|
|
BROKEN_RTN(m_classOrPackagep && !m_classOrPackagep->brokeExists());
|
2020-08-15 16:12:55 +02:00
|
|
|
return nullptr;
|
2020-04-15 13:58:34 +02:00
|
|
|
}
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual void cloneRelink() override {
|
2019-12-23 21:03:04 +01:00
|
|
|
if (m_classp && m_classp->clonep()) m_classp = m_classp->clonep();
|
2021-12-13 00:10:52 +01:00
|
|
|
if (m_classOrPackagep && m_classOrPackagep->clonep()) {
|
|
|
|
|
m_classOrPackagep = m_classOrPackagep->clonep();
|
|
|
|
|
}
|
2019-12-23 21:03:04 +01:00
|
|
|
}
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual bool same(const AstNode* samep) const override {
|
2021-11-26 23:55:36 +01:00
|
|
|
const AstClassRefDType* const asamep = static_cast<const AstClassRefDType*>(samep);
|
2020-11-25 03:56:03 +01:00
|
|
|
return (m_classp == asamep->m_classp && m_classOrPackagep == asamep->m_classOrPackagep);
|
2020-04-15 13:58:34 +02:00
|
|
|
}
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual bool similarDType(AstNodeDType* samep) const override {
|
2020-11-28 19:46:14 +01:00
|
|
|
return this == samep || (type() == samep->type() && same(samep));
|
2020-08-15 17:44:10 +02:00
|
|
|
}
|
|
|
|
|
virtual void dump(std::ostream& str = std::cout) const override;
|
|
|
|
|
virtual void dumpSmall(std::ostream& str) const override;
|
|
|
|
|
virtual string name() const override { return classp() ? classp()->name() : "<unlinked>"; }
|
|
|
|
|
virtual AstBasicDType* basicp() const override { return nullptr; }
|
|
|
|
|
virtual AstNodeDType* skipRefp() const override { return (AstNodeDType*)this; }
|
|
|
|
|
virtual AstNodeDType* skipRefToConstp() const override { return (AstNodeDType*)this; }
|
|
|
|
|
virtual AstNodeDType* skipRefToEnump() const override { return (AstNodeDType*)this; }
|
|
|
|
|
virtual int widthAlignBytes() const override { return 0; }
|
|
|
|
|
virtual int widthTotalBytes() const override { return 0; }
|
|
|
|
|
virtual AstNodeDType* virtRefDTypep() const override { return nullptr; }
|
|
|
|
|
virtual void virtRefDTypep(AstNodeDType* nodep) override {}
|
|
|
|
|
virtual AstNodeDType* subDTypep() const override { return nullptr; }
|
2020-11-25 03:56:03 +01:00
|
|
|
AstNodeModule* classOrPackagep() const { return m_classOrPackagep; }
|
|
|
|
|
void classOrPackagep(AstNodeModule* nodep) { m_classOrPackagep = nodep; }
|
2019-12-23 21:03:04 +01:00
|
|
|
AstClass* classp() const { return m_classp; }
|
|
|
|
|
void classp(AstClass* nodep) { m_classp = nodep; }
|
2021-10-22 14:56:48 +02:00
|
|
|
AstPin* paramsp() const { return VN_AS(op4p(), Pin); }
|
2020-12-13 01:19:16 +01:00
|
|
|
virtual bool isCompound() const override { return true; }
|
2019-12-23 21:03:04 +01:00
|
|
|
};
|
|
|
|
|
|
2020-11-19 03:32:16 +01:00
|
|
|
class AstIfaceRefDType final : public AstNodeDType {
|
2013-05-28 03:39:19 +02:00
|
|
|
// Reference to an interface, either for a port, or inside parent cell
|
|
|
|
|
private:
|
2020-04-15 13:58:34 +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
|
2020-08-15 19:11:27 +02:00
|
|
|
AstIface* m_ifacep = nullptr; // Pointer to interface; note cellp() should override
|
|
|
|
|
AstCell* m_cellp = nullptr; // When exact parent cell known; not a guess
|
|
|
|
|
AstModport* m_modportp = nullptr; // nullptr = unlinked or no modport
|
2020-04-15 13:58:34 +02:00
|
|
|
public:
|
|
|
|
|
AstIfaceRefDType(FileLine* fl, const string& cellName, const string& ifaceName)
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_IfaceRefDType(fl)
|
2020-08-16 17:40:42 +02:00
|
|
|
, m_modportFileline{nullptr}
|
|
|
|
|
, m_cellName{cellName}
|
|
|
|
|
, m_ifaceName{ifaceName}
|
|
|
|
|
, m_modportName{""} {}
|
2020-04-15 13:58:34 +02:00
|
|
|
AstIfaceRefDType(FileLine* fl, FileLine* modportFl, const string& cellName,
|
|
|
|
|
const string& ifaceName, const string& modport)
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_IfaceRefDType(fl)
|
2020-08-16 17:40:42 +02:00
|
|
|
, m_modportFileline{modportFl}
|
|
|
|
|
, m_cellName{cellName}
|
|
|
|
|
, m_ifaceName{ifaceName}
|
|
|
|
|
, m_modportName{modport} {}
|
2016-11-05 14:47:56 +01:00
|
|
|
ASTNODE_NODE_FUNCS(IfaceRefDType)
|
2013-05-28 03:39:19 +02:00
|
|
|
// METHODS
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual const char* broken() const override;
|
|
|
|
|
virtual void dump(std::ostream& str = std::cout) const override;
|
|
|
|
|
virtual void dumpSmall(std::ostream& str) const override;
|
|
|
|
|
virtual void cloneRelink() override;
|
|
|
|
|
virtual AstBasicDType* basicp() const override { return nullptr; }
|
|
|
|
|
virtual AstNodeDType* skipRefp() const override { return (AstNodeDType*)this; }
|
|
|
|
|
virtual AstNodeDType* skipRefToConstp() const override { return (AstNodeDType*)this; }
|
|
|
|
|
virtual AstNodeDType* skipRefToEnump() const override { return (AstNodeDType*)this; }
|
|
|
|
|
virtual bool similarDType(AstNodeDType* samep) const override { return this == samep; }
|
|
|
|
|
virtual int widthAlignBytes() const override { return 1; }
|
|
|
|
|
virtual int widthTotalBytes() const override { return 1; }
|
2019-07-14 21:06:49 +02:00
|
|
|
FileLine* modportFileline() const { return m_modportFileline; }
|
2013-05-28 03:39:19 +02:00
|
|
|
string cellName() const { return m_cellName; }
|
2019-05-19 22:13:13 +02:00
|
|
|
void cellName(const string& name) { m_cellName = name; }
|
2013-05-28 03:39:19 +02:00
|
|
|
string ifaceName() const { return m_ifaceName; }
|
2019-05-19 22:13:13 +02:00
|
|
|
void ifaceName(const string& name) { m_ifaceName = name; }
|
2013-05-28 03:39:19 +02:00
|
|
|
string modportName() const { return m_modportName; }
|
|
|
|
|
AstIface* ifaceViaCellp() const; // Use cellp or ifacep
|
|
|
|
|
AstIface* ifacep() const { return m_ifacep; }
|
2019-05-19 22:13:13 +02:00
|
|
|
void ifacep(AstIface* nodep) { m_ifacep = nodep; }
|
2013-05-28 03:39:19 +02:00
|
|
|
AstCell* cellp() const { return m_cellp; }
|
2019-05-19 22:13:13 +02:00
|
|
|
void cellp(AstCell* nodep) { m_cellp = nodep; }
|
2013-05-28 03:39:19 +02:00
|
|
|
AstModport* modportp() const { return m_modportp; }
|
2019-05-19 22:13:13 +02:00
|
|
|
void modportp(AstModport* modportp) { m_modportp = modportp; }
|
2013-05-28 03:39:19 +02:00
|
|
|
bool isModport() { return !m_modportName.empty(); }
|
2020-12-13 01:19:16 +01:00
|
|
|
virtual bool isCompound() const override { return true; } // But not relevant
|
2013-05-28 03:39:19 +02:00
|
|
|
};
|
|
|
|
|
|
2020-11-19 03:32:16 +01:00
|
|
|
class AstQueueDType final : public AstNodeDType {
|
2019-12-01 18:35:49 +01:00
|
|
|
// Queue array data type, ie "[ $ ]"
|
|
|
|
|
// Children: DTYPE (moved to refDTypep() in V3Width)
|
|
|
|
|
private:
|
|
|
|
|
AstNodeDType* m_refDTypep; // Elements of this type (after widthing)
|
|
|
|
|
public:
|
2019-12-15 03:39:47 +01:00
|
|
|
AstQueueDType(FileLine* fl, VFlagChildDType, AstNodeDType* dtp, AstNode* boundp)
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_QueueDType(fl) {
|
2019-12-15 03:39:47 +01:00
|
|
|
setNOp2p(boundp);
|
2019-12-01 18:35:49 +01:00
|
|
|
childDTypep(dtp); // Only for parser
|
2020-08-15 16:12:55 +02:00
|
|
|
refDTypep(nullptr);
|
|
|
|
|
dtypep(nullptr); // V3Width will resolve
|
2019-12-01 18:35:49 +01:00
|
|
|
}
|
2020-11-01 16:56:07 +01:00
|
|
|
AstQueueDType(FileLine* fl, AstNodeDType* dtp, AstNode* boundp)
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_QueueDType(fl) {
|
2020-11-01 16:56:07 +01:00
|
|
|
setNOp2p(boundp);
|
|
|
|
|
refDTypep(dtp);
|
|
|
|
|
dtypep(dtp);
|
|
|
|
|
}
|
2019-12-01 18:35:49 +01:00
|
|
|
ASTNODE_NODE_FUNCS(QueueDType)
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual const char* broken() const override {
|
2019-12-01 18:35:49 +01:00
|
|
|
BROKEN_RTN(!((m_refDTypep && !childDTypep() && m_refDTypep->brokeExists())
|
|
|
|
|
|| (!m_refDTypep && childDTypep())));
|
2020-08-15 16:12:55 +02:00
|
|
|
return nullptr;
|
2020-04-15 13:58:34 +02:00
|
|
|
}
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual void cloneRelink() override {
|
2021-02-22 03:25:21 +01:00
|
|
|
if (m_refDTypep && m_refDTypep->clonep()) m_refDTypep = m_refDTypep->clonep();
|
2020-04-15 13:58:34 +02:00
|
|
|
}
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual bool same(const AstNode* samep) const override {
|
2021-11-26 23:55:36 +01:00
|
|
|
const AstQueueDType* const asamep = static_cast<const AstQueueDType*>(samep);
|
2020-09-08 03:13:38 +02:00
|
|
|
if (!asamep->subDTypep()) return false;
|
2020-04-15 13:58:34 +02:00
|
|
|
return (subDTypep() == asamep->subDTypep());
|
|
|
|
|
}
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual bool similarDType(AstNodeDType* samep) const override {
|
2021-11-26 23:55:36 +01:00
|
|
|
const AstQueueDType* const asamep = static_cast<const AstQueueDType*>(samep);
|
2020-11-28 19:46:14 +01:00
|
|
|
return type() == samep->type() && asamep->subDTypep()
|
|
|
|
|
&& subDTypep()->skipRefp()->similarDType(asamep->subDTypep()->skipRefp());
|
2019-12-01 18:35:49 +01:00
|
|
|
}
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual void dumpSmall(std::ostream& str) const override;
|
|
|
|
|
virtual string prettyDTypeName() const override;
|
|
|
|
|
virtual AstNodeDType* getChildDTypep() const override { return childDTypep(); }
|
2020-04-15 13:58:34 +02:00
|
|
|
// op1 = Range of variable
|
2021-10-22 14:56:48 +02:00
|
|
|
AstNodeDType* childDTypep() const { return VN_AS(op1p(), NodeDType); }
|
2019-12-01 18:35:49 +01:00
|
|
|
void childDTypep(AstNodeDType* nodep) { setOp1p(nodep); }
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual AstNodeDType* subDTypep() const override {
|
|
|
|
|
return m_refDTypep ? m_refDTypep : childDTypep();
|
|
|
|
|
}
|
2019-12-01 18:35:49 +01:00
|
|
|
void refDTypep(AstNodeDType* nodep) { m_refDTypep = nodep; }
|
2020-08-15 16:12:55 +02:00
|
|
|
AstNode* boundp() const { return op2p(); } // op2 = Bound, nullptr = none
|
2019-12-15 03:39:47 +01:00
|
|
|
void boundp(AstNode* nodep) { setNOp2p(nodep); }
|
2020-04-15 13:58:34 +02:00
|
|
|
int boundConst() const {
|
2021-11-26 23:55:36 +01:00
|
|
|
AstConst* const constp = VN_CAST(boundp(), Const);
|
2020-04-15 13:58:34 +02:00
|
|
|
return (constp ? constp->toSInt() : 0);
|
|
|
|
|
}
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual AstNodeDType* virtRefDTypep() const override { return m_refDTypep; }
|
|
|
|
|
virtual void virtRefDTypep(AstNodeDType* nodep) override { refDTypep(nodep); }
|
2019-12-01 18:35:49 +01:00
|
|
|
// METHODS
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual AstBasicDType* basicp() const override { return nullptr; }
|
2020-04-06 00:30:46 +02:00
|
|
|
// cppcheck-suppress csyleCast
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual AstNodeDType* skipRefp() const override { return (AstNodeDType*)this; }
|
2020-04-06 00:30:46 +02:00
|
|
|
// cppcheck-suppress csyleCast
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual AstNodeDType* skipRefToConstp() const override { return (AstNodeDType*)this; }
|
2020-04-06 00:30:46 +02:00
|
|
|
// cppcheck-suppress csyleCast
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual AstNodeDType* skipRefToEnump() const override { return (AstNodeDType*)this; }
|
|
|
|
|
virtual int widthAlignBytes() const override { return subDTypep()->widthAlignBytes(); }
|
|
|
|
|
virtual int widthTotalBytes() const override { return subDTypep()->widthTotalBytes(); }
|
2020-12-13 01:19:16 +01:00
|
|
|
virtual bool isCompound() const override { return true; }
|
2019-12-01 18:35:49 +01:00
|
|
|
};
|
|
|
|
|
|
2020-11-19 03:32:16 +01:00
|
|
|
class AstRefDType final : public AstNodeDType {
|
2009-11-09 14:20:28 +01:00
|
|
|
private:
|
2020-05-24 20:22:06 +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
|
2020-08-15 19:11:27 +02:00
|
|
|
AstTypedef* m_typedefp = nullptr; // referenced type
|
2020-05-24 20:22:06 +02:00
|
|
|
// Post-width typedefs are removed and point to type directly
|
2020-08-15 19:11:27 +02:00
|
|
|
AstNodeDType* m_refDTypep = nullptr; // data type pointed to, BELOW the AstTypedef
|
2020-04-15 13:58:34 +02:00
|
|
|
string m_name; // Name of an AstTypedef
|
2020-11-25 03:56:03 +01:00
|
|
|
AstNodeModule* m_classOrPackagep = nullptr; // Package hierarchy
|
2009-11-07 05:16:06 +01:00
|
|
|
public:
|
|
|
|
|
AstRefDType(FileLine* fl, const string& name)
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_RefDType(fl)
|
2020-08-16 17:40:42 +02:00
|
|
|
, m_name{name} {}
|
2020-07-12 00:39:01 +02:00
|
|
|
AstRefDType(FileLine* fl, const string& name, AstNode* classOrPackagep, AstNode* paramsp)
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_RefDType(fl)
|
2020-08-16 17:40:42 +02:00
|
|
|
, m_name{name} {
|
2020-07-12 00:39:01 +02:00
|
|
|
setNOp3p(classOrPackagep);
|
|
|
|
|
addNOp4p(paramsp);
|
|
|
|
|
}
|
2020-01-26 16:28:13 +01:00
|
|
|
class FlagTypeOfExpr {}; // type(expr) for parser only
|
|
|
|
|
AstRefDType(FileLine* fl, FlagTypeOfExpr, AstNode* typeofp)
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_RefDType(fl) {
|
2020-01-26 16:28:13 +01:00
|
|
|
setOp2p(typeofp);
|
|
|
|
|
}
|
2016-11-05 14:47:56 +01:00
|
|
|
ASTNODE_NODE_FUNCS(RefDType)
|
2009-11-07 05:16:06 +01:00
|
|
|
// METHODS
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual const char* broken() const override {
|
2020-05-24 20:22:06 +02:00
|
|
|
BROKEN_RTN(m_typedefp && !m_typedefp->brokeExists());
|
2020-04-15 13:58:34 +02:00
|
|
|
BROKEN_RTN(m_refDTypep && !m_refDTypep->brokeExists());
|
2021-12-13 00:10:52 +01:00
|
|
|
BROKEN_RTN(m_classOrPackagep && !m_classOrPackagep->brokeExists());
|
2020-08-15 16:12:55 +02:00
|
|
|
return nullptr;
|
2020-04-15 13:58:34 +02:00
|
|
|
}
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual void cloneRelink() override {
|
2021-02-22 03:25:21 +01:00
|
|
|
if (m_typedefp && m_typedefp->clonep()) m_typedefp = m_typedefp->clonep();
|
|
|
|
|
if (m_refDTypep && m_refDTypep->clonep()) m_refDTypep = m_refDTypep->clonep();
|
2021-12-13 00:10:52 +01:00
|
|
|
if (m_classOrPackagep && m_classOrPackagep->clonep()) {
|
|
|
|
|
m_classOrPackagep = m_classOrPackagep->clonep();
|
|
|
|
|
}
|
2020-04-15 13:58:34 +02:00
|
|
|
}
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual bool same(const AstNode* samep) const override {
|
2021-11-26 23:55:36 +01:00
|
|
|
const AstRefDType* const asamep = static_cast<const AstRefDType*>(samep);
|
2020-05-24 20:22:06 +02:00
|
|
|
return (m_typedefp == asamep->m_typedefp && m_refDTypep == asamep->m_refDTypep
|
2020-11-25 03:56:03 +01:00
|
|
|
&& m_name == asamep->m_name && m_classOrPackagep == asamep->m_classOrPackagep);
|
2020-04-15 13:58:34 +02:00
|
|
|
}
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual bool similarDType(AstNodeDType* samep) const override {
|
2020-04-15 13:58:34 +02:00
|
|
|
return skipRefp()->similarDType(samep->skipRefp());
|
|
|
|
|
}
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual void dump(std::ostream& str = std::cout) const override;
|
|
|
|
|
virtual string name() const override { return m_name; }
|
|
|
|
|
virtual string prettyDTypeName() const override {
|
2020-04-15 13:58:34 +02:00
|
|
|
return subDTypep() ? subDTypep()->name() : prettyName();
|
|
|
|
|
}
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual AstBasicDType* basicp() const override {
|
|
|
|
|
return subDTypep() ? subDTypep()->basicp() : nullptr;
|
|
|
|
|
}
|
|
|
|
|
virtual AstNodeDType* subDTypep() const override {
|
2020-05-24 20:22:06 +02:00
|
|
|
if (typedefp()) return typedefp()->subDTypep();
|
2020-08-15 16:12:55 +02:00
|
|
|
return refDTypep(); // Maybe nullptr
|
2020-05-24 20:22:06 +02:00
|
|
|
}
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual AstNodeDType* skipRefp() const override {
|
2019-05-19 22:13:13 +02:00
|
|
|
// Skip past both the Ref and the Typedef
|
2020-05-24 20:22:06 +02:00
|
|
|
if (subDTypep()) {
|
|
|
|
|
return subDTypep()->skipRefp();
|
2020-04-15 13:58:34 +02:00
|
|
|
} else {
|
|
|
|
|
v3fatalSrc("Typedef not linked");
|
2020-08-15 16:12:55 +02:00
|
|
|
return nullptr;
|
2020-04-15 13:58:34 +02:00
|
|
|
}
|
2009-11-07 05:16:06 +01:00
|
|
|
}
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual AstNodeDType* skipRefToConstp() const override {
|
2020-05-24 20:22:06 +02:00
|
|
|
if (subDTypep()) {
|
|
|
|
|
return subDTypep()->skipRefToConstp();
|
2020-04-15 13:58:34 +02:00
|
|
|
} else {
|
|
|
|
|
v3fatalSrc("Typedef not linked");
|
2020-08-15 16:12:55 +02:00
|
|
|
return nullptr;
|
2020-04-15 13:58:34 +02:00
|
|
|
}
|
2013-11-01 03:39:26 +01:00
|
|
|
}
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual AstNodeDType* skipRefToEnump() const override {
|
2020-05-24 20:22:06 +02:00
|
|
|
if (subDTypep()) {
|
|
|
|
|
return subDTypep()->skipRefToEnump();
|
2020-04-15 13:58:34 +02:00
|
|
|
} else {
|
|
|
|
|
v3fatalSrc("Typedef not linked");
|
2020-08-15 16:12:55 +02:00
|
|
|
return nullptr;
|
2020-04-15 13:58:34 +02:00
|
|
|
}
|
2014-11-07 13:50:11 +01:00
|
|
|
}
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual int widthAlignBytes() const override { return dtypeSkipRefp()->widthAlignBytes(); }
|
|
|
|
|
virtual int widthTotalBytes() const override { return dtypeSkipRefp()->widthTotalBytes(); }
|
|
|
|
|
virtual void name(const string& flag) override { m_name = flag; }
|
2020-04-15 13:58:34 +02:00
|
|
|
// op1 = Range of variable
|
2020-05-24 20:22:06 +02:00
|
|
|
AstNodeDType* dtypeSkipRefp() const { return subDTypep()->skipRefp(); }
|
|
|
|
|
AstTypedef* typedefp() const { return m_typedefp; }
|
|
|
|
|
void typedefp(AstTypedef* nodep) { m_typedefp = nodep; }
|
2012-04-29 14:38:53 +02:00
|
|
|
AstNodeDType* refDTypep() const { return m_refDTypep; }
|
2019-05-19 22:13:13 +02:00
|
|
|
void refDTypep(AstNodeDType* nodep) { m_refDTypep = nodep; }
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual AstNodeDType* virtRefDTypep() const override { return refDTypep(); }
|
|
|
|
|
virtual void virtRefDTypep(AstNodeDType* nodep) override { refDTypep(nodep); }
|
2020-11-25 03:56:03 +01:00
|
|
|
AstNodeModule* classOrPackagep() const { return m_classOrPackagep; }
|
|
|
|
|
void classOrPackagep(AstNodeModule* nodep) { m_classOrPackagep = nodep; }
|
2020-01-26 16:28:13 +01:00
|
|
|
AstNode* typeofp() const { return op2p(); }
|
2020-11-25 03:28:04 +01:00
|
|
|
AstNode* classOrPackageOpp() const { return op3p(); }
|
2021-10-22 14:56:48 +02:00
|
|
|
AstPin* paramsp() const { return VN_AS(op4p(), Pin); }
|
2020-12-13 01:19:16 +01:00
|
|
|
virtual bool isCompound() const override {
|
|
|
|
|
v3fatalSrc("call isCompound on subdata type, not reference");
|
|
|
|
|
return false;
|
|
|
|
|
}
|
2009-11-07 05:16:06 +01:00
|
|
|
};
|
|
|
|
|
|
2020-11-19 03:32:16 +01:00
|
|
|
class AstStructDType final : public AstNodeUOrStructDType {
|
2014-09-12 03:28:53 +02:00
|
|
|
public:
|
2020-04-20 03:19:09 +02:00
|
|
|
// VSigning below is mispurposed to indicate if packed or not
|
|
|
|
|
AstStructDType(FileLine* fl, VSigning numericUnpack)
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_StructDType(fl, numericUnpack) {}
|
2016-11-05 14:47:56 +01:00
|
|
|
ASTNODE_NODE_FUNCS(StructDType)
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual string verilogKwd() const override { return "struct"; }
|
2012-07-29 16:16:20 +02:00
|
|
|
};
|
|
|
|
|
|
2020-11-19 03:32:16 +01:00
|
|
|
class AstUnionDType final : public AstNodeUOrStructDType {
|
2014-09-12 03:28:53 +02:00
|
|
|
public:
|
2020-04-15 13:58:34 +02:00
|
|
|
// UNSUP: bool isTagged;
|
2020-04-20 03:19:09 +02:00
|
|
|
// VSigning below is mispurposed to indicate if packed or not
|
|
|
|
|
AstUnionDType(FileLine* fl, VSigning numericUnpack)
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_UnionDType(fl, numericUnpack) {}
|
2016-11-05 14:47:56 +01:00
|
|
|
ASTNODE_NODE_FUNCS(UnionDType)
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual string verilogKwd() const override { return "union"; }
|
2012-07-29 16:16:20 +02:00
|
|
|
};
|
|
|
|
|
|
2020-11-19 03:32:16 +01:00
|
|
|
class AstMemberDType final : public AstNodeDType {
|
2012-07-29 16:16:20 +02:00
|
|
|
// A member of a struct/union
|
2019-12-17 04:46:09 +01:00
|
|
|
// PARENT: AstNodeUOrStructDType
|
2012-07-29 16:16:20 +02:00
|
|
|
private:
|
2019-05-19 22:13:13 +02:00
|
|
|
AstNodeDType* m_refDTypep; // Elements of this type (after widthing)
|
2020-04-15 13:58:34 +02:00
|
|
|
string m_name; // Name of variable
|
|
|
|
|
string m_tag; // Holds the string of the verilator tag -- used in XML output.
|
2020-08-15 19:11:27 +02:00
|
|
|
int m_lsb = -1; // Within this level's packed struct, the LSB of the first bit of the member
|
2020-04-15 13:58:34 +02:00
|
|
|
// UNSUP: int m_randType; // Randomization type (IEEE)
|
2012-07-29 16:16:20 +02:00
|
|
|
public:
|
|
|
|
|
AstMemberDType(FileLine* fl, const string& name, VFlagChildDType, AstNodeDType* dtp)
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_MemberDType(fl)
|
2020-08-16 17:40:42 +02:00
|
|
|
, m_name{name} {
|
2019-05-19 22:13:13 +02:00
|
|
|
childDTypep(dtp); // Only for parser
|
2020-08-15 16:12:55 +02:00
|
|
|
dtypep(nullptr); // V3Width will resolve
|
|
|
|
|
refDTypep(nullptr);
|
2012-07-29 16:16:20 +02:00
|
|
|
}
|
|
|
|
|
AstMemberDType(FileLine* fl, const string& name, AstNodeDType* dtp)
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_MemberDType(fl)
|
2020-08-16 17:40:42 +02:00
|
|
|
, m_name{name} {
|
2019-05-19 22:13:13 +02:00
|
|
|
UASSERT(dtp, "AstMember created with no dtype");
|
|
|
|
|
refDTypep(dtp);
|
|
|
|
|
dtypep(this);
|
|
|
|
|
widthFromSub(subDTypep());
|
2012-07-29 16:16:20 +02:00
|
|
|
}
|
2016-11-05 14:47:56 +01:00
|
|
|
ASTNODE_NODE_FUNCS(MemberDType)
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual string name() const override { return m_name; } // * = Var name
|
|
|
|
|
virtual bool hasDType() const override { return true; }
|
|
|
|
|
virtual bool maybePointedTo() const override { return true; }
|
2021-12-13 00:10:52 +01:00
|
|
|
virtual const char* broken() const override {
|
|
|
|
|
BROKEN_RTN(m_refDTypep && !m_refDTypep->brokeExists());
|
|
|
|
|
return nullptr;
|
|
|
|
|
}
|
|
|
|
|
virtual void cloneRelink() override {
|
|
|
|
|
if (m_refDTypep && m_refDTypep->clonep()) m_refDTypep = m_refDTypep->clonep();
|
|
|
|
|
}
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual AstNodeDType* getChildDTypep() const override { return childDTypep(); }
|
2020-04-15 13:58:34 +02:00
|
|
|
// op1 = Range of variable
|
2021-10-22 14:56:48 +02:00
|
|
|
AstNodeDType* childDTypep() const { return VN_AS(op1p(), NodeDType); }
|
2019-05-19 22:13:13 +02:00
|
|
|
void childDTypep(AstNodeDType* nodep) { setOp1p(nodep); }
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual AstNodeDType* subDTypep() const override {
|
|
|
|
|
return m_refDTypep ? m_refDTypep : childDTypep();
|
|
|
|
|
}
|
2012-07-29 16:16:20 +02:00
|
|
|
void refDTypep(AstNodeDType* nodep) { m_refDTypep = nodep; }
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual AstNodeDType* virtRefDTypep() const override { return m_refDTypep; }
|
|
|
|
|
virtual void virtRefDTypep(AstNodeDType* nodep) override { refDTypep(nodep); }
|
|
|
|
|
virtual bool similarDType(AstNodeDType* samep) const override { return this == samep; }
|
2012-07-29 16:16:20 +02:00
|
|
|
//
|
2019-05-19 22:13:13 +02:00
|
|
|
// (Slow) recurse down to find basic data type (Note don't need virtual -
|
|
|
|
|
// AstVar isn't a NodeDType)
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual AstBasicDType* basicp() const override { return subDTypep()->basicp(); }
|
2018-03-10 22:32:04 +01:00
|
|
|
// op1 = Range of variable (Note don't need virtual - AstVar isn't a NodeDType)
|
|
|
|
|
AstNodeDType* dtypeSkipRefp() const { return subDTypep()->skipRefp(); }
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual AstNodeDType* skipRefp() const override { return subDTypep()->skipRefp(); }
|
|
|
|
|
virtual AstNodeDType* skipRefToConstp() const override {
|
|
|
|
|
return subDTypep()->skipRefToConstp();
|
|
|
|
|
}
|
|
|
|
|
virtual AstNodeDType* skipRefToEnump() const override { return subDTypep()->skipRefToEnump(); }
|
2018-03-10 22:32:04 +01:00
|
|
|
// (Slow) recurses - Structure alignment 1,2,4 or 8 bytes (arrays affect this)
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual int widthAlignBytes() const override { return subDTypep()->widthAlignBytes(); }
|
2018-03-10 22:32:04 +01:00
|
|
|
// (Slow) recurses - Width in bytes rounding up 1,2,4,8,12,...
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual int widthTotalBytes() const override { return subDTypep()->widthTotalBytes(); }
|
2012-07-29 16:16:20 +02:00
|
|
|
// METHODS
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual void name(const string& name) override { m_name = name; }
|
|
|
|
|
virtual void tag(const string& text) override { m_tag = text; }
|
|
|
|
|
virtual string tag() const override { return m_tag; }
|
2012-07-29 16:16:20 +02:00
|
|
|
int lsb() const { return m_lsb; }
|
2019-05-19 22:13:13 +02:00
|
|
|
void lsb(int lsb) { m_lsb = lsb; }
|
2020-12-13 01:19:16 +01:00
|
|
|
virtual bool isCompound() const override {
|
|
|
|
|
v3fatalSrc("call isCompound on subdata type, not reference");
|
|
|
|
|
return false;
|
|
|
|
|
}
|
2012-07-29 16:16:20 +02:00
|
|
|
};
|
|
|
|
|
|
2021-08-28 23:23:35 +02:00
|
|
|
class AstEmptyQueueDType final : public AstNodeDType {
|
|
|
|
|
// For EmptyQueue
|
|
|
|
|
public:
|
|
|
|
|
explicit AstEmptyQueueDType(FileLine* fl)
|
|
|
|
|
: ASTGEN_SUPER_EmptyQueueDType(fl) {
|
|
|
|
|
dtypep(this);
|
|
|
|
|
}
|
|
|
|
|
ASTNODE_NODE_FUNCS(EmptyQueueDType)
|
|
|
|
|
virtual void dumpSmall(std::ostream& str) const override;
|
|
|
|
|
virtual bool hasDType() const override { return true; }
|
|
|
|
|
virtual bool maybePointedTo() const override { return true; }
|
2021-12-13 01:53:20 +01:00
|
|
|
virtual bool undead() const override { return true; }
|
2021-08-28 23:23:35 +02:00
|
|
|
virtual AstNodeDType* subDTypep() const override { return nullptr; }
|
|
|
|
|
virtual AstNodeDType* virtRefDTypep() const override { return nullptr; }
|
|
|
|
|
virtual void virtRefDTypep(AstNodeDType* nodep) override {}
|
|
|
|
|
virtual bool similarDType(AstNodeDType* samep) const override { return this == samep; }
|
|
|
|
|
virtual AstBasicDType* basicp() const override { return nullptr; }
|
|
|
|
|
// cppcheck-suppress csyleCast
|
|
|
|
|
virtual AstNodeDType* skipRefp() const override { return (AstNodeDType*)this; }
|
|
|
|
|
// cppcheck-suppress csyleCast
|
|
|
|
|
virtual AstNodeDType* skipRefToConstp() const override { return (AstNodeDType*)this; }
|
|
|
|
|
// cppcheck-suppress csyleCast
|
|
|
|
|
virtual AstNodeDType* skipRefToEnump() const override { return (AstNodeDType*)this; }
|
|
|
|
|
virtual int widthAlignBytes() const override { return 1; }
|
|
|
|
|
virtual int widthTotalBytes() const override { return 1; }
|
|
|
|
|
virtual bool isCompound() const override { return false; }
|
|
|
|
|
};
|
|
|
|
|
|
2020-11-19 03:32:16 +01:00
|
|
|
class AstVoidDType final : public AstNodeDType {
|
2019-12-01 17:52:48 +01:00
|
|
|
// For e.g. a function returning void
|
|
|
|
|
public:
|
2020-02-04 05:21:56 +01:00
|
|
|
explicit AstVoidDType(FileLine* fl)
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_VoidDType(fl) {
|
2020-04-15 13:58:34 +02:00
|
|
|
dtypep(this);
|
|
|
|
|
}
|
2019-12-01 17:52:48 +01:00
|
|
|
ASTNODE_NODE_FUNCS(VoidDType)
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual void dumpSmall(std::ostream& str) const override;
|
|
|
|
|
virtual bool hasDType() const override { return true; }
|
|
|
|
|
virtual bool maybePointedTo() const override { return true; }
|
2021-12-13 01:53:20 +01:00
|
|
|
virtual bool undead() const override { return true; }
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual AstNodeDType* subDTypep() const override { return nullptr; }
|
|
|
|
|
virtual AstNodeDType* virtRefDTypep() const override { return nullptr; }
|
|
|
|
|
virtual void virtRefDTypep(AstNodeDType* nodep) override {}
|
|
|
|
|
virtual bool similarDType(AstNodeDType* samep) const override { return this == samep; }
|
|
|
|
|
virtual AstBasicDType* basicp() const override { return nullptr; }
|
2020-04-06 00:30:46 +02:00
|
|
|
// cppcheck-suppress csyleCast
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual AstNodeDType* skipRefp() const override { return (AstNodeDType*)this; }
|
2020-04-06 00:30:46 +02:00
|
|
|
// cppcheck-suppress csyleCast
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual AstNodeDType* skipRefToConstp() const override { return (AstNodeDType*)this; }
|
2020-04-06 00:30:46 +02:00
|
|
|
// cppcheck-suppress csyleCast
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual AstNodeDType* skipRefToEnump() const override { return (AstNodeDType*)this; }
|
|
|
|
|
virtual int widthAlignBytes() const override { return 1; }
|
|
|
|
|
virtual int widthTotalBytes() const override { return 1; }
|
2020-12-13 01:19:16 +01:00
|
|
|
virtual bool isCompound() const override { return false; }
|
2019-12-01 17:52:48 +01:00
|
|
|
};
|
|
|
|
|
|
2020-11-19 03:32:16 +01:00
|
|
|
class AstEnumItem final : public AstNode {
|
2009-12-27 14:29:55 +01:00
|
|
|
private:
|
2020-04-15 13:58:34 +02:00
|
|
|
string m_name;
|
|
|
|
|
|
2009-12-27 14:29:55 +01:00
|
|
|
public:
|
|
|
|
|
// Parents: ENUM
|
|
|
|
|
AstEnumItem(FileLine* fl, const string& name, AstNode* rangep, AstNode* initp)
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_EnumItem(fl)
|
2020-08-16 17:40:42 +02:00
|
|
|
, m_name{name} {
|
2020-04-15 13:58:34 +02:00
|
|
|
addNOp1p(rangep);
|
|
|
|
|
addNOp2p(initp);
|
|
|
|
|
}
|
2016-11-05 14:47:56 +01:00
|
|
|
ASTNODE_NODE_FUNCS(EnumItem)
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual string name() const override { return m_name; }
|
|
|
|
|
virtual bool maybePointedTo() const override { return true; }
|
|
|
|
|
virtual bool hasDType() const override { return true; }
|
|
|
|
|
virtual void name(const string& flag) override { m_name = flag; }
|
2021-10-22 14:56:48 +02:00
|
|
|
AstRange* rangep() const { return VN_AS(op1p(), Range); } // op1 = Range for name appending
|
|
|
|
|
void rangep(AstRange* nodep) { addOp1p(nodep); }
|
2019-05-19 22:13:13 +02:00
|
|
|
AstNode* valuep() const { return op2p(); } // op2 = Value
|
2010-01-22 00:20:47 +01:00
|
|
|
void valuep(AstNode* nodep) { addOp2p(nodep); }
|
2009-12-27 14:29:55 +01:00
|
|
|
};
|
|
|
|
|
|
2020-11-19 03:32:16 +01:00
|
|
|
class AstEnumItemRef final : public AstNodeMath {
|
2009-12-27 14:29:55 +01:00
|
|
|
private:
|
2020-04-12 20:53:10 +02:00
|
|
|
AstEnumItem* m_itemp; // [AfterLink] Pointer to item
|
2020-11-25 03:56:03 +01:00
|
|
|
AstNodeModule* m_classOrPackagep; // Package hierarchy
|
2009-12-27 14:29:55 +01:00
|
|
|
public:
|
2020-11-25 03:56:03 +01:00
|
|
|
AstEnumItemRef(FileLine* fl, AstEnumItem* itemp, AstNodeModule* classOrPackagep)
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_EnumItemRef(fl)
|
2020-08-16 17:40:42 +02:00
|
|
|
, m_itemp{itemp}
|
2020-11-25 03:56:03 +01:00
|
|
|
, m_classOrPackagep{classOrPackagep} {
|
2019-05-19 22:13:13 +02:00
|
|
|
dtypeFrom(m_itemp);
|
2009-12-27 14:29:55 +01:00
|
|
|
}
|
2016-11-05 14:47:56 +01:00
|
|
|
ASTNODE_NODE_FUNCS(EnumItemRef)
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual void dump(std::ostream& str) const override;
|
|
|
|
|
virtual string name() const override { return itemp()->name(); }
|
|
|
|
|
virtual int instrCount() const override { return 0; }
|
2021-12-13 00:10:52 +01:00
|
|
|
virtual const char* broken() const override {
|
|
|
|
|
BROKEN_RTN(m_itemp && !m_itemp->brokeExists());
|
|
|
|
|
BROKEN_RTN(m_classOrPackagep && !m_classOrPackagep->brokeExists());
|
|
|
|
|
return nullptr;
|
|
|
|
|
}
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual void cloneRelink() override {
|
2021-10-22 18:36:58 +02:00
|
|
|
if (m_itemp->clonep()) m_itemp = m_itemp->clonep();
|
2020-04-15 13:58:34 +02:00
|
|
|
}
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual bool same(const AstNode* samep) const override {
|
2021-11-26 23:55:36 +01:00
|
|
|
const AstEnumItemRef* const sp = static_cast<const AstEnumItemRef*>(samep);
|
2020-04-15 13:58:34 +02:00
|
|
|
return itemp() == sp->itemp();
|
|
|
|
|
}
|
2009-12-27 14:29:55 +01:00
|
|
|
AstEnumItem* itemp() const { return m_itemp; }
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual string emitVerilog() override { V3ERROR_NA_RETURN(""); }
|
|
|
|
|
virtual string emitC() override { V3ERROR_NA_RETURN(""); }
|
|
|
|
|
virtual bool cleanOut() const override { return true; }
|
2020-11-25 03:56:03 +01:00
|
|
|
AstNodeModule* classOrPackagep() const { return m_classOrPackagep; }
|
|
|
|
|
void classOrPackagep(AstNodeModule* nodep) { m_classOrPackagep = nodep; }
|
2009-12-27 14:29:55 +01:00
|
|
|
};
|
|
|
|
|
|
2020-11-19 03:32:16 +01:00
|
|
|
class AstEnumDType final : public AstNodeDType {
|
2009-12-27 14:29:55 +01:00
|
|
|
// Parents: TYPEDEF/MODULE
|
|
|
|
|
// Children: ENUMVALUEs
|
2012-04-29 16:14:13 +02:00
|
|
|
private:
|
2018-10-08 00:07:42 +02:00
|
|
|
string m_name; // Name from upper typedef, if any
|
2019-05-19 22:13:13 +02:00
|
|
|
AstNodeDType* m_refDTypep; // Elements are of this type after V3Width
|
2021-05-21 15:34:27 +02:00
|
|
|
const int m_uniqueNum;
|
2020-04-15 13:58:34 +02:00
|
|
|
|
2012-03-31 17:22:19 +02:00
|
|
|
public:
|
|
|
|
|
AstEnumDType(FileLine* fl, VFlagChildDType, AstNodeDType* dtp, AstNode* itemsp)
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_EnumDType(fl)
|
2021-05-21 15:34:27 +02:00
|
|
|
, m_uniqueNum{uniqueNumInc()} {
|
2019-05-19 22:13:13 +02:00
|
|
|
childDTypep(dtp); // Only for parser
|
2020-08-15 16:12:55 +02:00
|
|
|
refDTypep(nullptr);
|
2019-05-19 22:13:13 +02:00
|
|
|
addNOp2p(itemsp);
|
2020-08-15 16:12:55 +02:00
|
|
|
dtypep(nullptr); // V3Width will resolve
|
2019-05-19 22:13:13 +02:00
|
|
|
widthFromSub(subDTypep());
|
2012-04-29 16:14:13 +02:00
|
|
|
}
|
2016-11-05 14:47:56 +01:00
|
|
|
ASTNODE_NODE_FUNCS(EnumDType)
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual const char* broken() const override {
|
2020-04-15 13:58:34 +02:00
|
|
|
BROKEN_RTN(!((m_refDTypep && !childDTypep() && m_refDTypep->brokeExists())
|
|
|
|
|
|| (!m_refDTypep && childDTypep())));
|
2020-08-15 16:12:55 +02:00
|
|
|
return nullptr;
|
2020-04-15 13:58:34 +02:00
|
|
|
}
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual void cloneRelink() override {
|
2021-02-22 03:25:21 +01:00
|
|
|
if (m_refDTypep && m_refDTypep->clonep()) m_refDTypep = m_refDTypep->clonep();
|
2020-04-15 13:58:34 +02:00
|
|
|
}
|
2021-05-21 15:34:27 +02:00
|
|
|
int uniqueNum() const { return m_uniqueNum; }
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual bool same(const AstNode* samep) const override {
|
2021-11-26 23:55:36 +01:00
|
|
|
const AstEnumDType* const sp = static_cast<const AstEnumDType*>(samep);
|
2021-05-21 15:34:27 +02:00
|
|
|
return uniqueNum() == sp->uniqueNum();
|
2020-04-15 13:58:34 +02:00
|
|
|
}
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual bool similarDType(AstNodeDType* samep) const override { return this == samep; }
|
|
|
|
|
virtual AstNodeDType* getChildDTypep() const override { return childDTypep(); }
|
2021-10-22 14:56:48 +02:00
|
|
|
AstNodeDType* childDTypep() const { return VN_AS(op1p(), NodeDType); } // op1 = Data type
|
2012-04-29 16:14:13 +02:00
|
|
|
void childDTypep(AstNodeDType* nodep) { setOp1p(nodep); }
|
2020-04-15 13:58:34 +02:00
|
|
|
// op1 = Range of variable
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual AstNodeDType* subDTypep() const override {
|
|
|
|
|
return m_refDTypep ? m_refDTypep : childDTypep();
|
|
|
|
|
}
|
2012-04-29 16:14:13 +02:00
|
|
|
void refDTypep(AstNodeDType* nodep) { m_refDTypep = nodep; }
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual AstNodeDType* virtRefDTypep() const override { return m_refDTypep; }
|
|
|
|
|
virtual void virtRefDTypep(AstNodeDType* nodep) override { refDTypep(nodep); }
|
|
|
|
|
virtual string name() const override { return m_name; }
|
|
|
|
|
virtual void name(const string& flag) override { m_name = flag; }
|
2021-10-22 14:56:48 +02:00
|
|
|
AstEnumItem* itemsp() const { return VN_AS(op2p(), EnumItem); } // op2 = AstEnumItem's
|
2009-12-27 14:29:55 +01:00
|
|
|
// METHODS
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual AstBasicDType* basicp() const override { return subDTypep()->basicp(); }
|
|
|
|
|
virtual AstNodeDType* skipRefp() const override { return subDTypep()->skipRefp(); }
|
|
|
|
|
virtual AstNodeDType* skipRefToConstp() const override {
|
|
|
|
|
return subDTypep()->skipRefToConstp();
|
|
|
|
|
}
|
2020-04-06 00:30:46 +02:00
|
|
|
// cppcheck-suppress csyleCast
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual AstNodeDType* skipRefToEnump() const override { return (AstNodeDType*)this; }
|
|
|
|
|
virtual int widthAlignBytes() const override { return subDTypep()->widthAlignBytes(); }
|
|
|
|
|
virtual int widthTotalBytes() const override { return subDTypep()->widthTotalBytes(); }
|
2020-12-07 23:55:22 +01:00
|
|
|
int itemCount() const {
|
|
|
|
|
size_t count = 0;
|
|
|
|
|
for (AstNode* itemp = itemsp(); itemp; itemp = itemp->nextp()) count++;
|
|
|
|
|
return count;
|
|
|
|
|
}
|
2020-12-13 01:19:16 +01:00
|
|
|
virtual bool isCompound() const override { return false; }
|
2009-12-27 14:29:55 +01:00
|
|
|
};
|
|
|
|
|
|
2020-11-19 03:32:16 +01:00
|
|
|
class AstParseTypeDType final : public AstNodeDType {
|
2016-03-15 02:51:31 +01:00
|
|
|
// 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
|
2016-04-01 04:26:49 +02:00
|
|
|
public:
|
2017-07-07 02:25:59 +02:00
|
|
|
explicit AstParseTypeDType(FileLine* fl)
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_ParseTypeDType(fl) {}
|
2016-11-05 14:47:56 +01:00
|
|
|
ASTNODE_NODE_FUNCS(ParseTypeDType)
|
2020-08-15 16:12:55 +02:00
|
|
|
AstNodeDType* dtypep() const { return nullptr; }
|
2016-03-15 02:51:31 +01:00
|
|
|
// METHODS
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual bool similarDType(AstNodeDType* samep) const override { return this == samep; }
|
|
|
|
|
virtual AstBasicDType* basicp() const override { return nullptr; }
|
|
|
|
|
virtual AstNodeDType* skipRefp() const override { return nullptr; }
|
2020-04-06 00:30:46 +02:00
|
|
|
// cppcheck-suppress csyleCast
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual AstNodeDType* skipRefToConstp() const override { return (AstNodeDType*)this; }
|
2020-04-06 00:30:46 +02:00
|
|
|
// cppcheck-suppress csyleCast
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual AstNodeDType* skipRefToEnump() const override { return (AstNodeDType*)this; }
|
|
|
|
|
virtual int widthAlignBytes() const override { return 0; }
|
|
|
|
|
virtual int widthTotalBytes() const override { return 0; }
|
2020-12-13 01:19:16 +01:00
|
|
|
virtual bool isCompound() const override {
|
|
|
|
|
v3fatalSrc("call isCompound on subdata type, not reference");
|
|
|
|
|
return false;
|
|
|
|
|
}
|
2016-03-15 02:51:31 +01:00
|
|
|
};
|
|
|
|
|
|
2009-11-05 04:31:53 +01:00
|
|
|
//######################################################################
|
|
|
|
|
|
2020-11-19 03:32:16 +01:00
|
|
|
class AstArraySel final : public AstNodeSel {
|
2006-08-26 13:35:28 +02:00
|
|
|
// Parents: math|stmt
|
|
|
|
|
// Children: varref|arraysel, math
|
2010-01-19 16:52:11 +01:00
|
|
|
private:
|
2012-02-20 15:55:20 +01:00
|
|
|
void init(AstNode* fromp) {
|
2018-02-02 03:32:58 +01:00
|
|
|
if (fromp && VN_IS(fromp->dtypep()->skipRefp(), NodeArrayDType)) {
|
2019-05-19 22:13:13 +02:00
|
|
|
// Strip off array to find what array references
|
2021-10-22 14:56:48 +02:00
|
|
|
dtypeFrom(VN_AS(fromp->dtypep()->skipRefp(), NodeArrayDType)->subDTypep());
|
2019-05-19 22:13:13 +02:00
|
|
|
}
|
2012-02-20 15:55:20 +01:00
|
|
|
}
|
2020-04-15 13:58:34 +02:00
|
|
|
|
2010-01-19 16:52:11 +01:00
|
|
|
public:
|
2006-08-26 13:35:28 +02:00
|
|
|
AstArraySel(FileLine* fl, AstNode* fromp, AstNode* bitp)
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_ArraySel(fl, fromp, bitp) {
|
2019-05-19 22:13:13 +02:00
|
|
|
init(fromp);
|
2006-08-26 13:35:28 +02:00
|
|
|
}
|
2008-12-12 21:34:02 +01:00
|
|
|
AstArraySel(FileLine* fl, AstNode* fromp, int bit)
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_ArraySel(fl, fromp, new AstConst(fl, bit)) {
|
2019-05-19 22:13:13 +02:00
|
|
|
init(fromp);
|
2008-12-12 21:34:02 +01:00
|
|
|
}
|
2016-11-05 14:47:56 +01:00
|
|
|
ASTNODE_NODE_FUNCS(ArraySel)
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual AstNode* cloneType(AstNode* lhsp, AstNode* rhsp) override {
|
2020-04-15 13:58:34 +02:00
|
|
|
return new AstArraySel(this->fileline(), lhsp, rhsp);
|
|
|
|
|
}
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) override {
|
2020-04-15 13:58:34 +02:00
|
|
|
V3ERROR_NA; /* How can from be a const? */
|
|
|
|
|
}
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual string emitVerilog() override { return "%k(%l%f[%r])"; }
|
|
|
|
|
virtual string emitC() override { return "%li%k[%ri]"; }
|
|
|
|
|
virtual bool cleanOut() const override { return true; }
|
|
|
|
|
virtual bool cleanLhs() const override { return false; }
|
|
|
|
|
virtual bool cleanRhs() const override { return true; }
|
|
|
|
|
virtual bool sizeMattersLhs() const override { return false; }
|
|
|
|
|
virtual bool sizeMattersRhs() const override { return false; }
|
|
|
|
|
virtual bool isGateOptimizable() const override {
|
|
|
|
|
return true;
|
|
|
|
|
} // esp for V3Const::ifSameAssign
|
|
|
|
|
virtual bool isPredictOptimizable() const override { return true; }
|
|
|
|
|
virtual bool same(const AstNode* samep) const override { return true; }
|
|
|
|
|
virtual int instrCount() const override { return widthInstrs(); }
|
2006-08-26 13:35:28 +02:00
|
|
|
// Special operators
|
2021-03-13 19:04:13 +01:00
|
|
|
// Return base var (or const) nodep dereferences
|
|
|
|
|
static AstNode* baseFromp(AstNode* nodep, bool overMembers);
|
2006-08-26 13:35:28 +02:00
|
|
|
};
|
|
|
|
|
|
2020-11-19 03:32:16 +01:00
|
|
|
class AstAssocSel final : public AstNodeSel {
|
2019-12-01 17:52:48 +01:00
|
|
|
// Parents: math|stmt
|
|
|
|
|
// Children: varref|arraysel, math
|
|
|
|
|
private:
|
|
|
|
|
void init(AstNode* fromp) {
|
|
|
|
|
if (fromp && VN_IS(fromp->dtypep()->skipRefp(), AssocArrayDType)) {
|
|
|
|
|
// Strip off array to find what array references
|
2021-10-22 14:56:48 +02:00
|
|
|
dtypeFrom(VN_AS(fromp->dtypep()->skipRefp(), AssocArrayDType)->subDTypep());
|
2019-12-01 17:52:48 +01:00
|
|
|
}
|
|
|
|
|
}
|
2020-04-15 13:58:34 +02:00
|
|
|
|
2019-12-01 17:52:48 +01:00
|
|
|
public:
|
|
|
|
|
AstAssocSel(FileLine* fl, AstNode* fromp, AstNode* bitp)
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_AssocSel(fl, fromp, bitp) {
|
2019-12-01 17:52:48 +01:00
|
|
|
init(fromp);
|
|
|
|
|
}
|
|
|
|
|
ASTNODE_NODE_FUNCS(AssocSel)
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual AstNode* cloneType(AstNode* lhsp, AstNode* rhsp) override {
|
2020-04-15 13:58:34 +02:00
|
|
|
return new AstAssocSel(this->fileline(), lhsp, rhsp);
|
|
|
|
|
}
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) override {
|
2020-04-15 13:58:34 +02:00
|
|
|
V3ERROR_NA;
|
|
|
|
|
}
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual string emitVerilog() override { return "%k(%l%f[%r])"; }
|
|
|
|
|
virtual string emitC() override { return "%li%k[%ri]"; }
|
|
|
|
|
virtual bool cleanOut() const override { return true; }
|
|
|
|
|
virtual bool cleanLhs() const override { return false; }
|
|
|
|
|
virtual bool cleanRhs() const override { return true; }
|
|
|
|
|
virtual bool sizeMattersLhs() const override { return false; }
|
|
|
|
|
virtual bool sizeMattersRhs() const override { return false; }
|
|
|
|
|
virtual bool isGateOptimizable() const override {
|
|
|
|
|
return true;
|
|
|
|
|
} // esp for V3Const::ifSameAssign
|
|
|
|
|
virtual bool isPredictOptimizable() const override { return false; }
|
|
|
|
|
virtual bool same(const AstNode* samep) const override { return true; }
|
|
|
|
|
virtual int instrCount() const override { return widthInstrs(); }
|
2019-12-01 17:52:48 +01:00
|
|
|
};
|
|
|
|
|
|
2020-11-19 03:32:16 +01:00
|
|
|
class AstWordSel final : public AstNodeSel {
|
2006-08-26 13:35:28 +02:00
|
|
|
// Select a single word from a multi-word wide value
|
2014-09-12 03:28:53 +02:00
|
|
|
public:
|
2006-08-26 13:35:28 +02:00
|
|
|
AstWordSel(FileLine* fl, AstNode* fromp, AstNode* bitp)
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_WordSel(fl, fromp, bitp) {
|
2019-12-09 03:36:38 +01:00
|
|
|
dtypeSetUInt32(); // Always used on WData arrays so returns edata size
|
2006-08-26 13:35:28 +02:00
|
|
|
}
|
2016-11-05 14:47:56 +01:00
|
|
|
ASTNODE_NODE_FUNCS(WordSel)
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual AstNode* cloneType(AstNode* lhsp, AstNode* rhsp) override {
|
2020-04-15 13:58:34 +02:00
|
|
|
return new AstWordSel(this->fileline(), lhsp, rhsp);
|
|
|
|
|
}
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual void numberOperate(V3Number& out, const V3Number& from, const V3Number& bit) override {
|
2020-04-15 13:58:34 +02:00
|
|
|
V3ERROR_NA;
|
|
|
|
|
}
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual string emitVerilog() override { return "%k(%l%f[%r])"; }
|
|
|
|
|
virtual string emitC() override {
|
|
|
|
|
return "%li[%ri]";
|
|
|
|
|
} // Not %k, as usually it's a small constant rhsp
|
|
|
|
|
virtual bool cleanOut() const override { return true; }
|
|
|
|
|
virtual bool cleanLhs() const override { return true; }
|
|
|
|
|
virtual bool cleanRhs() const override { return true; }
|
|
|
|
|
virtual bool sizeMattersLhs() const override { return false; }
|
|
|
|
|
virtual bool sizeMattersRhs() const override { return false; }
|
|
|
|
|
virtual bool same(const AstNode* samep) const override { return true; }
|
2006-08-26 13:35:28 +02:00
|
|
|
};
|
|
|
|
|
|
2020-11-19 03:32:16 +01:00
|
|
|
class AstSelLoopVars final : public AstNode {
|
2020-06-10 04:05:06 +02:00
|
|
|
// Parser only concept "[id, id, id]" for a foreach statement
|
|
|
|
|
// Unlike normal selects elements is a list
|
|
|
|
|
public:
|
|
|
|
|
AstSelLoopVars(FileLine* fl, AstNode* fromp, AstNode* elementsp)
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_SelLoopVars(fl) {
|
2020-06-10 04:05:06 +02:00
|
|
|
setOp1p(fromp);
|
|
|
|
|
addNOp2p(elementsp);
|
|
|
|
|
}
|
|
|
|
|
ASTNODE_NODE_FUNCS(SelLoopVars)
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual bool same(const AstNode* samep) const override { return true; }
|
|
|
|
|
virtual bool maybePointedTo() const override { return false; }
|
2020-06-10 04:05:06 +02:00
|
|
|
AstNode* fromp() const { return op1p(); }
|
2021-12-13 02:43:15 +01:00
|
|
|
void fromp(AstNode* nodep) { setOp1p(nodep); }
|
2020-06-10 04:05:06 +02:00
|
|
|
AstNode* elementsp() const { return op2p(); }
|
|
|
|
|
};
|
|
|
|
|
|
2020-11-19 03:32:16 +01:00
|
|
|
class AstSelExtract final : public AstNodePreSel {
|
2006-08-26 13:35:28 +02:00
|
|
|
// Range extraction, gets replaced with AstSel
|
2014-09-12 03:28:53 +02:00
|
|
|
public:
|
2006-08-26 13:35:28 +02:00
|
|
|
AstSelExtract(FileLine* fl, AstNode* fromp, AstNode* msbp, AstNode* lsbp)
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_SelExtract(fl, fromp, msbp, lsbp) {}
|
2016-11-05 14:47:56 +01:00
|
|
|
ASTNODE_NODE_FUNCS(SelExtract)
|
2020-12-07 03:13:56 +01:00
|
|
|
AstNode* leftp() const { return rhsp(); }
|
|
|
|
|
AstNode* rightp() const { return thsp(); }
|
2006-08-26 13:35:28 +02:00
|
|
|
};
|
|
|
|
|
|
2020-11-19 03:32:16 +01:00
|
|
|
class AstSelBit final : public AstNodePreSel {
|
2006-08-26 13:35:28 +02:00
|
|
|
// Single bit range extraction, perhaps with non-constant selection or array selection
|
|
|
|
|
// Gets replaced during link with AstArraySel or AstSel
|
2014-09-12 03:28:53 +02:00
|
|
|
public:
|
2006-08-26 13:35:28 +02:00
|
|
|
AstSelBit(FileLine* fl, AstNode* fromp, AstNode* bitp)
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_SelBit(fl, fromp, bitp, nullptr) {
|
2019-07-07 15:01:36 +02:00
|
|
|
UASSERT_OBJ(!v3Global.assertDTypesResolved(), this,
|
2020-04-15 13:58:34 +02:00
|
|
|
"not coded to create after dtypes resolved");
|
|
|
|
|
}
|
2016-11-05 14:47:56 +01:00
|
|
|
ASTNODE_NODE_FUNCS(SelBit)
|
2019-05-19 22:13:13 +02:00
|
|
|
AstNode* bitp() const { return rhsp(); }
|
2006-08-26 13:35:28 +02:00
|
|
|
};
|
|
|
|
|
|
2020-11-19 03:32:16 +01:00
|
|
|
class AstSelPlus final : public AstNodePreSel {
|
2006-08-26 13:35:28 +02:00
|
|
|
// +: range extraction, perhaps with non-constant selection
|
|
|
|
|
// Gets replaced during link with AstSel
|
2014-09-12 03:28:53 +02:00
|
|
|
public:
|
2006-08-26 13:35:28 +02:00
|
|
|
AstSelPlus(FileLine* fl, AstNode* fromp, AstNode* bitp, AstNode* widthp)
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_SelPlus(fl, fromp, bitp, widthp) {}
|
2016-11-05 14:47:56 +01:00
|
|
|
ASTNODE_NODE_FUNCS(SelPlus)
|
2019-05-19 22:13:13 +02:00
|
|
|
AstNode* bitp() const { return rhsp(); }
|
|
|
|
|
AstNode* widthp() const { return thsp(); }
|
2006-08-26 13:35:28 +02:00
|
|
|
};
|
|
|
|
|
|
2020-11-19 03:32:16 +01:00
|
|
|
class AstSelMinus final : public AstNodePreSel {
|
2006-08-26 13:35:28 +02:00
|
|
|
// -: range extraction, perhaps with non-constant selection
|
|
|
|
|
// Gets replaced during link with AstSel
|
2014-09-12 03:28:53 +02:00
|
|
|
public:
|
2006-08-26 13:35:28 +02:00
|
|
|
AstSelMinus(FileLine* fl, AstNode* fromp, AstNode* bitp, AstNode* widthp)
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_SelMinus(fl, fromp, bitp, widthp) {}
|
2016-11-05 14:47:56 +01:00
|
|
|
ASTNODE_NODE_FUNCS(SelMinus)
|
2019-05-19 22:13:13 +02:00
|
|
|
AstNode* bitp() const { return rhsp(); }
|
|
|
|
|
AstNode* widthp() const { return thsp(); }
|
2006-08-26 13:35:28 +02:00
|
|
|
};
|
|
|
|
|
|
2020-11-19 03:32:16 +01:00
|
|
|
class AstSel final : public AstNodeTriop {
|
2006-08-26 13:35:28 +02:00
|
|
|
// Multiple bit range extraction
|
|
|
|
|
// Parents: math|stmt
|
|
|
|
|
// Children: varref|arraysel, math, constant math
|
2020-09-07 23:09:25 +02:00
|
|
|
// Tempting to have an access() style method here as LHS selects are quite
|
2013-01-13 15:48:12 +01:00
|
|
|
// different, but that doesn't play well with V3Inst and bidirects which don't know direction
|
2013-01-15 03:49:22 +01:00
|
|
|
private:
|
2020-04-15 13:58:34 +02:00
|
|
|
VNumRange m_declRange; // Range of the 'from' array if isRanged() is set, else invalid
|
|
|
|
|
int m_declElWidth; // If a packed array, the number of bits per element
|
2013-01-15 03:49:22 +01:00
|
|
|
public:
|
2006-08-26 13:35:28 +02:00
|
|
|
AstSel(FileLine* fl, AstNode* fromp, AstNode* lsbp, AstNode* widthp)
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_Sel(fl, fromp, lsbp, widthp)
|
2020-08-16 17:40:42 +02:00
|
|
|
, m_declElWidth{1} {
|
2018-02-02 03:32:58 +01:00
|
|
|
if (VN_IS(widthp, Const)) {
|
2021-10-22 14:56:48 +02:00
|
|
|
dtypeSetLogicSized(VN_AS(widthp, Const)->toUInt(), VSigning::UNSIGNED);
|
2019-05-19 22:13:13 +02:00
|
|
|
}
|
2006-08-26 13:35:28 +02:00
|
|
|
}
|
2009-12-03 12:55:29 +01:00
|
|
|
AstSel(FileLine* fl, AstNode* fromp, int lsb, int bitwidth)
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_Sel(fl, fromp, new AstConst(fl, lsb), new AstConst(fl, bitwidth))
|
2020-08-16 17:40:42 +02:00
|
|
|
, m_declElWidth{1} {
|
2020-04-20 03:19:09 +02:00
|
|
|
dtypeSetLogicSized(bitwidth, VSigning::UNSIGNED);
|
2006-08-26 13:35:28 +02:00
|
|
|
}
|
2016-11-05 14:47:56 +01:00
|
|
|
ASTNODE_NODE_FUNCS(Sel)
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual void dump(std::ostream& str) const override;
|
2020-04-15 13:58:34 +02:00
|
|
|
virtual void numberOperate(V3Number& out, const V3Number& from, const V3Number& bit,
|
2020-08-15 17:44:10 +02:00
|
|
|
const V3Number& width) override {
|
2020-04-15 13:58:34 +02:00
|
|
|
out.opSel(from, bit.toUInt() + width.toUInt() - 1, bit.toUInt());
|
|
|
|
|
}
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual string emitVerilog() override { V3ERROR_NA_RETURN(""); }
|
|
|
|
|
virtual string emitC() override {
|
2021-11-28 19:44:16 +01:00
|
|
|
return widthp()->isOne() ? "VL_BITSEL_%nq%lq%rq%tq(%lw, %P, %li, %ri)"
|
|
|
|
|
: isWide() ? "VL_SEL_%nq%lq%rq%tq(%nw,%lw, %P, %li, %ri, %ti)"
|
|
|
|
|
: "VL_SEL_%nq%lq%rq%tq(%lw, %P, %li, %ri, %ti)";
|
2020-04-15 13:58:34 +02:00
|
|
|
}
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual bool cleanOut() const override { return false; }
|
|
|
|
|
virtual bool cleanLhs() const override { return true; }
|
|
|
|
|
virtual bool cleanRhs() const override { return true; }
|
|
|
|
|
virtual bool cleanThs() const override { return true; }
|
|
|
|
|
virtual bool sizeMattersLhs() const override { return false; }
|
|
|
|
|
virtual bool sizeMattersRhs() const override { return false; }
|
|
|
|
|
virtual bool sizeMattersThs() const override { return false; }
|
|
|
|
|
virtual bool same(const AstNode*) const override { return true; }
|
|
|
|
|
virtual int instrCount() const override {
|
|
|
|
|
return widthInstrs() * (VN_CAST(lsbp(), Const) ? 3 : 10);
|
|
|
|
|
}
|
2020-08-15 16:12:55 +02:00
|
|
|
AstNode* fromp() const {
|
|
|
|
|
return op1p();
|
|
|
|
|
} // op1 = Extracting what (nullptr=TBD during parsing)
|
2019-05-19 22:13:13 +02:00
|
|
|
AstNode* lsbp() const { return op2p(); } // op2 = Msb selection expression
|
|
|
|
|
AstNode* widthp() const { return op3p(); } // op3 = Width
|
2021-10-22 14:56:48 +02:00
|
|
|
int widthConst() const { return VN_AS(widthp(), Const)->toSInt(); }
|
|
|
|
|
int lsbConst() const { return VN_AS(lsbp(), Const)->toSInt(); }
|
2020-04-15 13:58:34 +02:00
|
|
|
int msbConst() const { return lsbConst() + widthConst() - 1; }
|
2013-01-15 03:49:22 +01:00
|
|
|
VNumRange& declRange() { return m_declRange; }
|
2019-10-20 17:49:41 +02:00
|
|
|
const VNumRange& declRange() const { return m_declRange; }
|
2013-01-15 03:49:22 +01:00
|
|
|
void declRange(const VNumRange& flag) { m_declRange = flag; }
|
|
|
|
|
int declElWidth() const { return m_declElWidth; }
|
|
|
|
|
void declElWidth(int flag) { m_declElWidth = flag; }
|
2006-08-26 13:35:28 +02:00
|
|
|
};
|
|
|
|
|
|
2020-11-19 03:32:16 +01:00
|
|
|
class AstSliceSel final : public AstNodeTriop {
|
2017-11-23 20:55:32 +01:00
|
|
|
// Multiple array element extraction
|
|
|
|
|
// Parents: math|stmt
|
|
|
|
|
// Children: varref|arraysel, math, constant math
|
|
|
|
|
private:
|
|
|
|
|
VNumRange m_declRange; // Range of the 'from' array if isRanged() is set, else invalid
|
|
|
|
|
public:
|
|
|
|
|
AstSliceSel(FileLine* fl, AstNode* fromp, const VNumRange& declRange)
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_SliceSel(fl, fromp, new AstConst(fl, declRange.lo()),
|
|
|
|
|
new AstConst(fl, declRange.elements()))
|
2020-08-16 17:40:42 +02:00
|
|
|
, m_declRange{declRange} {}
|
2017-11-23 20:55:32 +01:00
|
|
|
ASTNODE_NODE_FUNCS(SliceSel)
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual void dump(std::ostream& str) const override;
|
2020-04-15 13:58:34 +02:00
|
|
|
virtual void numberOperate(V3Number& out, const V3Number& from, const V3Number& lo,
|
2020-08-15 17:44:10 +02:00
|
|
|
const V3Number& width) override {
|
2020-04-15 13:58:34 +02:00
|
|
|
V3ERROR_NA;
|
|
|
|
|
}
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual string emitVerilog() override { V3ERROR_NA_RETURN(""); }
|
|
|
|
|
virtual string emitC() override { V3ERROR_NA_RETURN(""); } // Removed before EmitC
|
|
|
|
|
virtual bool cleanOut() const override { return false; }
|
|
|
|
|
virtual bool cleanLhs() const override { return false; }
|
|
|
|
|
virtual bool cleanRhs() const override { return true; }
|
|
|
|
|
virtual bool cleanThs() const override { return true; }
|
|
|
|
|
virtual bool sizeMattersLhs() const override { return false; }
|
|
|
|
|
virtual bool sizeMattersRhs() const override { return false; }
|
|
|
|
|
virtual bool sizeMattersThs() const override { return false; }
|
|
|
|
|
virtual bool same(const AstNode*) const override { return true; }
|
|
|
|
|
virtual int instrCount() const override { return 10; } // Removed before matters
|
2020-08-15 16:12:55 +02:00
|
|
|
AstNode* fromp() const {
|
|
|
|
|
return op1p();
|
|
|
|
|
} // op1 = Extracting what (nullptr=TBD during parsing)
|
2017-11-23 20:55:32 +01:00
|
|
|
// For widthConst()/loConst etc, see declRange().elements() and other VNumRange methods
|
|
|
|
|
VNumRange& declRange() { return m_declRange; }
|
2019-10-20 17:49:41 +02:00
|
|
|
const VNumRange& declRange() const { return m_declRange; }
|
2017-11-23 20:55:32 +01:00
|
|
|
void declRange(const VNumRange& flag) { m_declRange = flag; }
|
|
|
|
|
};
|
|
|
|
|
|
2020-11-19 03:32:16 +01:00
|
|
|
class AstMethodCall final : public AstNodeFTaskRef {
|
2014-11-29 02:34:23 +01:00
|
|
|
// A reference to a member task (or function)
|
2020-03-07 18:52:11 +01:00
|
|
|
// PARENTS: stmt/math
|
|
|
|
|
// Not all calls are statments vs math. AstNodeStmt needs isStatement() to deal.
|
|
|
|
|
// Don't need the class we are extracting from, as the "fromp()"'s datatype can get us to it
|
2014-11-29 02:34:23 +01:00
|
|
|
public:
|
2020-03-07 18:52:11 +01:00
|
|
|
AstMethodCall(FileLine* fl, AstNode* fromp, VFlagChildDType, const string& name,
|
|
|
|
|
AstNode* pinsp)
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_MethodCall(fl, false, name, pinsp) {
|
2020-03-07 18:52:11 +01:00
|
|
|
setOp2p(fromp);
|
2020-08-15 16:12:55 +02:00
|
|
|
dtypep(nullptr); // V3Width will resolve
|
2014-11-29 02:34:23 +01:00
|
|
|
}
|
2019-11-17 14:51:25 +01:00
|
|
|
AstMethodCall(FileLine* fl, AstNode* fromp, const string& name, AstNode* pinsp)
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_MethodCall(fl, false, name, pinsp) {
|
2020-03-07 18:52:11 +01:00
|
|
|
setOp2p(fromp);
|
2014-11-29 02:34:23 +01:00
|
|
|
}
|
2019-11-17 14:51:25 +01:00
|
|
|
ASTNODE_NODE_FUNCS(MethodCall)
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual const char* broken() const override {
|
2020-03-07 18:52:11 +01:00
|
|
|
BROKEN_BASE_RTN(AstNodeFTaskRef::broken());
|
|
|
|
|
BROKEN_RTN(!fromp());
|
2020-08-15 16:12:55 +02:00
|
|
|
return nullptr;
|
2020-03-07 18:52:11 +01:00
|
|
|
}
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual void dump(std::ostream& str) const override;
|
|
|
|
|
virtual bool hasDType() const override { return true; }
|
2020-04-15 13:58:34 +02:00
|
|
|
void makeStatement() {
|
|
|
|
|
statement(true);
|
|
|
|
|
dtypeSetVoid();
|
|
|
|
|
}
|
2020-08-15 16:12:55 +02:00
|
|
|
AstNode* fromp() const {
|
|
|
|
|
return op2p();
|
|
|
|
|
} // op2 = Extracting what (nullptr=TBD during parsing)
|
2020-03-07 18:52:11 +01:00
|
|
|
void fromp(AstNode* nodep) { setOp2p(nodep); }
|
2014-11-29 02:34:23 +01:00
|
|
|
};
|
|
|
|
|
|
2020-11-19 03:32:16 +01:00
|
|
|
class AstCMethodHard final : public AstNodeStmt {
|
2020-01-20 22:53:27 +01:00
|
|
|
// A reference to a "C" hardcoded member task (or function)
|
2019-12-01 17:52:48 +01:00
|
|
|
// PARENTS: stmt/math
|
|
|
|
|
// Not all calls are statments vs math. AstNodeStmt needs isStatement() to deal.
|
|
|
|
|
private:
|
|
|
|
|
string m_name; // Name of method
|
2020-08-15 19:11:27 +02:00
|
|
|
bool m_pure = false; // Pure optimizable
|
2019-12-01 17:52:48 +01:00
|
|
|
public:
|
2020-01-18 20:11:05 +01:00
|
|
|
AstCMethodHard(FileLine* fl, AstNode* fromp, VFlagChildDType, const string& name,
|
2019-12-01 17:52:48 +01:00
|
|
|
AstNode* pinsp)
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_CMethodHard(fl, false)
|
2020-08-16 17:40:42 +02:00
|
|
|
, m_name{name} {
|
2019-12-01 17:52:48 +01:00
|
|
|
setOp1p(fromp);
|
2020-08-15 16:12:55 +02:00
|
|
|
dtypep(nullptr); // V3Width will resolve
|
2019-12-01 17:52:48 +01:00
|
|
|
addNOp2p(pinsp);
|
|
|
|
|
}
|
2020-01-18 20:11:05 +01:00
|
|
|
AstCMethodHard(FileLine* fl, AstNode* fromp, const string& name, AstNode* pinsp)
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_CMethodHard(fl, false)
|
2020-08-16 17:40:42 +02:00
|
|
|
, m_name{name} {
|
2019-12-01 17:52:48 +01:00
|
|
|
setOp1p(fromp);
|
|
|
|
|
addNOp2p(pinsp);
|
|
|
|
|
}
|
2020-01-18 20:11:05 +01:00
|
|
|
ASTNODE_NODE_FUNCS(CMethodHard)
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual string name() const override { return m_name; } // * = Var name
|
|
|
|
|
virtual bool hasDType() const override { return true; }
|
|
|
|
|
virtual void name(const string& name) override { m_name = name; }
|
|
|
|
|
virtual bool same(const AstNode* samep) const override {
|
2020-01-18 20:11:05 +01:00
|
|
|
const AstCMethodHard* asamep = static_cast<const AstCMethodHard*>(samep);
|
2020-04-15 13:58:34 +02:00
|
|
|
return (m_name == asamep->m_name);
|
|
|
|
|
}
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual bool isPure() const override { return m_pure; }
|
2019-12-01 17:52:48 +01:00
|
|
|
void pure(bool flag) { m_pure = flag; }
|
2020-04-15 13:58:34 +02:00
|
|
|
void makeStatement() {
|
|
|
|
|
statement(true);
|
|
|
|
|
dtypeSetVoid();
|
|
|
|
|
}
|
2020-08-15 16:12:55 +02:00
|
|
|
AstNode* fromp() const {
|
|
|
|
|
return op1p();
|
|
|
|
|
} // op1 = Extracting what (nullptr=TBD during parsing)
|
2019-12-01 17:52:48 +01:00
|
|
|
void fromp(AstNode* nodep) { setOp1p(nodep); }
|
|
|
|
|
AstNode* pinsp() const { return op2p(); } // op2 = Pin interconnection list
|
|
|
|
|
void addPinsp(AstNode* nodep) { addOp2p(nodep); }
|
|
|
|
|
};
|
|
|
|
|
|
2020-11-19 03:32:16 +01:00
|
|
|
class AstVar final : public AstNode {
|
2006-08-26 13:35:28 +02:00
|
|
|
// A variable (in/out/wire/reg/param) inside a module
|
|
|
|
|
private:
|
2020-04-15 13:58:34 +02:00
|
|
|
string m_name; // Name of variable
|
|
|
|
|
string m_origName; // Original name before dot addition
|
|
|
|
|
string m_tag; // Holds the string of the verilator tag -- used in XML output.
|
|
|
|
|
AstVarType m_varType; // Type of variable
|
|
|
|
|
VDirection m_direction; // Direction input/output etc
|
|
|
|
|
VDirection m_declDirection; // Declared direction input/output etc
|
2018-10-05 02:24:41 +02:00
|
|
|
AstBasicDTypeKwd m_declKwd; // Keyword at declaration time
|
2021-06-19 19:41:19 +02:00
|
|
|
VLifetime m_lifetime; // Lifetime
|
|
|
|
|
VVarAttrClocker m_attrClocker;
|
|
|
|
|
MTaskIdSet m_mtaskIds; // MTaskID's that read or write this var
|
|
|
|
|
int m_pinNum = 0; // For XML, if non-zero the connection pin number
|
2020-04-15 13:58:34 +02:00
|
|
|
bool m_ansi : 1; // ANSI port list variable (for dedup check)
|
|
|
|
|
bool m_declTyped : 1; // Declared as type (for dedup check)
|
|
|
|
|
bool m_tristate : 1; // Inout or triwire or trireg
|
|
|
|
|
bool m_primaryIO : 1; // In/out to top level (or directly assigned from same)
|
|
|
|
|
bool m_sc : 1; // SystemC variable
|
|
|
|
|
bool m_scClocked : 1; // SystemC sc_clk<> needed
|
|
|
|
|
bool m_scSensitive : 1; // SystemC sensitive() needed
|
|
|
|
|
bool m_sigPublic : 1; // User C code accesses this signal or is top signal
|
|
|
|
|
bool m_sigModPublic : 1; // User C code accesses this signal and module
|
|
|
|
|
bool m_sigUserRdPublic : 1; // User C code accesses this signal, read only
|
|
|
|
|
bool m_sigUserRWPublic : 1; // User C code accesses this signal, read-write
|
|
|
|
|
bool m_usedClock : 1; // Signal used as a clock
|
|
|
|
|
bool m_usedParam : 1; // Parameter is referenced (on link; later signals not setup)
|
|
|
|
|
bool m_usedLoopIdx : 1; // Variable subject of for unrolling
|
|
|
|
|
bool m_funcLocal : 1; // Local variable for a function
|
|
|
|
|
bool m_funcReturn : 1; // Return variable for a function
|
|
|
|
|
bool m_attrClockEn : 1; // User clock enable attribute
|
|
|
|
|
bool m_attrScBv : 1; // User force bit vector attribute
|
|
|
|
|
bool m_attrIsolateAssign : 1; // User isolate_assignments attribute
|
|
|
|
|
bool m_attrSFormat : 1; // User sformat attribute
|
|
|
|
|
bool m_attrSplitVar : 1; // declared with split_var metacomment
|
|
|
|
|
bool m_fileDescr : 1; // File descriptor
|
2020-12-07 23:55:22 +01:00
|
|
|
bool m_isRand : 1; // Random variable
|
2020-04-15 13:58:34 +02:00
|
|
|
bool m_isConst : 1; // Table contains constant data
|
2020-04-26 18:45:06 +02:00
|
|
|
bool m_isStatic : 1; // Static C variable (for Verilog see instead isAutomatic)
|
2020-04-15 13:58:34 +02:00
|
|
|
bool m_isPulldown : 1; // Tri0
|
|
|
|
|
bool m_isPullup : 1; // Tri1
|
|
|
|
|
bool m_isIfaceParent : 1; // dtype is reference to interface present in this module
|
|
|
|
|
bool m_isDpiOpenArray : 1; // DPI import open array
|
2020-11-25 13:03:01 +01:00
|
|
|
bool m_isHideLocal : 1; // Verilog local
|
|
|
|
|
bool m_isHideProtected : 1; // Verilog protected
|
2020-04-15 13:58:34 +02:00
|
|
|
bool m_noReset : 1; // Do not do automated reset/randomization
|
|
|
|
|
bool m_noSubst : 1; // Do not substitute out references
|
2020-08-15 15:43:53 +02:00
|
|
|
bool m_overridenParam : 1; // Overridden parameter by #(...) or defparam
|
2020-04-15 13:58:34 +02:00
|
|
|
bool m_trace : 1; // Trace this variable
|
2021-01-05 20:26:01 +01:00
|
|
|
bool m_isLatched : 1; // Not assigned in all control paths of combo always
|
2006-08-26 13:35:28 +02:00
|
|
|
|
2018-10-27 23:29:00 +02:00
|
|
|
void init() {
|
2020-04-15 13:58:34 +02:00
|
|
|
m_ansi = false;
|
|
|
|
|
m_declTyped = false;
|
|
|
|
|
m_tristate = false;
|
|
|
|
|
m_primaryIO = false;
|
|
|
|
|
m_sc = false;
|
|
|
|
|
m_scClocked = false;
|
|
|
|
|
m_scSensitive = false;
|
|
|
|
|
m_usedClock = false;
|
|
|
|
|
m_usedParam = false;
|
|
|
|
|
m_usedLoopIdx = false;
|
|
|
|
|
m_sigPublic = false;
|
|
|
|
|
m_sigModPublic = false;
|
|
|
|
|
m_sigUserRdPublic = false;
|
|
|
|
|
m_sigUserRWPublic = false;
|
|
|
|
|
m_funcLocal = false;
|
|
|
|
|
m_funcReturn = false;
|
|
|
|
|
m_attrClockEn = false;
|
|
|
|
|
m_attrScBv = false;
|
|
|
|
|
m_attrIsolateAssign = false;
|
|
|
|
|
m_attrSFormat = false;
|
|
|
|
|
m_attrSplitVar = false;
|
|
|
|
|
m_fileDescr = false;
|
2020-12-23 21:21:33 +01:00
|
|
|
m_isRand = false;
|
2020-04-15 13:58:34 +02:00
|
|
|
m_isConst = false;
|
|
|
|
|
m_isStatic = false;
|
|
|
|
|
m_isPulldown = false;
|
|
|
|
|
m_isPullup = false;
|
|
|
|
|
m_isIfaceParent = false;
|
|
|
|
|
m_isDpiOpenArray = false;
|
2020-11-25 13:03:01 +01:00
|
|
|
m_isHideLocal = false;
|
|
|
|
|
m_isHideProtected = false;
|
2020-04-15 13:58:34 +02:00
|
|
|
m_noReset = false;
|
|
|
|
|
m_noSubst = false;
|
2020-08-15 15:43:53 +02:00
|
|
|
m_overridenParam = false;
|
2020-04-15 13:58:34 +02:00
|
|
|
m_trace = false;
|
2021-01-05 20:26:01 +01:00
|
|
|
m_isLatched = false;
|
2019-10-05 13:54:14 +02:00
|
|
|
m_attrClocker = VVarAttrClocker::CLOCKER_UNKNOWN;
|
2006-08-26 13:35:28 +02:00
|
|
|
}
|
2020-04-15 13:58:34 +02:00
|
|
|
|
2006-08-26 13:35:28 +02:00
|
|
|
public:
|
2012-03-31 17:22:19 +02:00
|
|
|
AstVar(FileLine* fl, AstVarType type, const string& name, VFlagChildDType, AstNodeDType* dtp)
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_Var(fl)
|
2020-08-16 17:40:42 +02:00
|
|
|
, m_name{name}
|
|
|
|
|
, m_origName{name} {
|
2019-03-14 00:47:36 +01:00
|
|
|
init();
|
2019-05-19 22:13:13 +02:00
|
|
|
combineType(type);
|
|
|
|
|
childDTypep(dtp); // Only for parser
|
2020-08-15 16:12:55 +02:00
|
|
|
dtypep(nullptr); // V3Width will resolve
|
2020-04-15 13:58:34 +02:00
|
|
|
if (dtp->basicp()) {
|
|
|
|
|
m_declKwd = dtp->basicp()->keyword();
|
|
|
|
|
} else {
|
|
|
|
|
m_declKwd = AstBasicDTypeKwd::LOGIC;
|
|
|
|
|
}
|
2012-03-31 17:22:19 +02:00
|
|
|
}
|
2011-11-30 04:36:51 +01:00
|
|
|
AstVar(FileLine* fl, AstVarType type, const string& name, AstNodeDType* dtp)
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_Var(fl)
|
2020-08-16 17:40:42 +02:00
|
|
|
, m_name{name}
|
|
|
|
|
, m_origName{name} {
|
2019-03-14 00:47:36 +01:00
|
|
|
init();
|
2019-05-19 22:13:13 +02:00
|
|
|
combineType(type);
|
|
|
|
|
UASSERT(dtp, "AstVar created with no dtype");
|
|
|
|
|
dtypep(dtp);
|
2020-04-15 13:58:34 +02:00
|
|
|
if (dtp->basicp()) {
|
|
|
|
|
m_declKwd = dtp->basicp()->keyword();
|
|
|
|
|
} else {
|
|
|
|
|
m_declKwd = AstBasicDTypeKwd::LOGIC;
|
|
|
|
|
}
|
2006-08-26 13:35:28 +02:00
|
|
|
}
|
2012-03-31 17:10:34 +02:00
|
|
|
AstVar(FileLine* fl, AstVarType type, const string& name, VFlagLogicPacked, int wantwidth)
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_Var(fl)
|
2020-08-16 17:40:42 +02:00
|
|
|
, m_name{name}
|
|
|
|
|
, m_origName{name} {
|
2019-03-14 00:47:36 +01:00
|
|
|
init();
|
|
|
|
|
combineType(type);
|
2020-04-20 03:19:09 +02:00
|
|
|
dtypeSetLogicSized(wantwidth, VSigning::UNSIGNED);
|
2018-10-05 02:24:41 +02:00
|
|
|
m_declKwd = AstBasicDTypeKwd::LOGIC;
|
2009-11-02 14:06:04 +01:00
|
|
|
}
|
2012-03-31 17:10:34 +02:00
|
|
|
AstVar(FileLine* fl, AstVarType type, const string& name, VFlagBitPacked, int wantwidth)
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_Var(fl)
|
2020-08-16 17:40:42 +02:00
|
|
|
, m_name{name}
|
|
|
|
|
, m_origName{name} {
|
2019-03-14 00:47:36 +01:00
|
|
|
init();
|
|
|
|
|
combineType(type);
|
2020-04-20 03:19:09 +02:00
|
|
|
dtypeSetBitSized(wantwidth, VSigning::UNSIGNED);
|
2018-10-05 02:24:41 +02:00
|
|
|
m_declKwd = AstBasicDTypeKwd::BIT;
|
2012-01-26 14:29:55 +01:00
|
|
|
}
|
2006-08-26 13:35:28 +02:00
|
|
|
AstVar(FileLine* fl, AstVarType type, const string& name, AstVar* examplep)
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_Var(fl)
|
2020-08-16 17:40:42 +02:00
|
|
|
, m_name{name}
|
|
|
|
|
, m_origName{name} {
|
2019-05-19 22:13:13 +02:00
|
|
|
init();
|
|
|
|
|
combineType(type);
|
2021-02-22 03:25:21 +01:00
|
|
|
if (examplep->childDTypep()) childDTypep(examplep->childDTypep()->cloneTree(true));
|
2019-05-19 22:13:13 +02:00
|
|
|
dtypeFrom(examplep);
|
2018-10-05 02:24:41 +02:00
|
|
|
m_declKwd = examplep->declKwd();
|
2006-08-26 13:35:28 +02:00
|
|
|
}
|
2016-11-05 14:47:56 +01:00
|
|
|
ASTNODE_NODE_FUNCS(Var)
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual void dump(std::ostream& str) const override;
|
|
|
|
|
virtual string name() const override { return m_name; } // * = Var name
|
|
|
|
|
virtual bool hasDType() const override { return true; }
|
|
|
|
|
virtual bool maybePointedTo() const override { return true; }
|
|
|
|
|
virtual string origName() const override { return m_origName; } // * = Original name
|
2013-02-18 17:22:24 +01:00
|
|
|
void origName(const string& name) { m_origName = name; }
|
|
|
|
|
AstVarType varType() const { return m_varType; } // * = Type of variable
|
2018-10-27 23:29:00 +02:00
|
|
|
void direction(const VDirection& flag) {
|
|
|
|
|
m_direction = flag;
|
2020-04-15 13:58:34 +02:00
|
|
|
if (m_direction == VDirection::INOUT) m_tristate = true;
|
|
|
|
|
}
|
2018-10-27 23:29:00 +02:00
|
|
|
VDirection direction() const { return m_direction; }
|
|
|
|
|
bool isIO() const { return m_direction != VDirection::NONE; }
|
|
|
|
|
void declDirection(const VDirection& flag) { m_declDirection = flag; }
|
|
|
|
|
VDirection declDirection() const { return m_declDirection; }
|
2013-02-18 17:22:24 +01:00
|
|
|
void varType(AstVarType type) { m_varType = type; }
|
2020-04-15 13:58:34 +02:00
|
|
|
void varType2Out() {
|
2020-06-02 05:16:02 +02:00
|
|
|
m_tristate = false;
|
2020-04-15 13:58:34 +02:00
|
|
|
m_direction = VDirection::OUTPUT;
|
|
|
|
|
}
|
|
|
|
|
void varType2In() {
|
2020-06-02 05:16:02 +02:00
|
|
|
m_tristate = false;
|
2020-04-15 13:58:34 +02:00
|
|
|
m_direction = VDirection::INPUT;
|
|
|
|
|
}
|
2018-10-05 02:24:41 +02:00
|
|
|
AstBasicDTypeKwd declKwd() const { return m_declKwd; }
|
2019-05-19 22:13:13 +02:00
|
|
|
string scType() const; // Return SysC type: bool, uint32_t, uint64_t, sc_bv
|
2020-04-15 13:58:34 +02:00
|
|
|
// Return C /*public*/ type for argument: bool, uint32_t, uint64_t, etc.
|
|
|
|
|
string cPubArgType(bool named, bool forReturn) const;
|
2019-05-19 22:13:13 +02:00
|
|
|
string dpiArgType(bool named, bool forReturn) const; // Return DPI-C type for argument
|
2020-11-19 14:02:58 +01:00
|
|
|
string dpiTmpVarType(const string& varName) const;
|
2018-03-10 22:32:04 +01:00
|
|
|
// Return Verilator internal type for argument: CData, SData, IData, WData
|
Introduce model interface class, make $root part or Syms (#3036)
This patch implements #3032. Verilator creates a module representing the
SystemVerilog $root scope (V3LinkLevel::wrapTop). Until now, this was
called the "TOP" module, which also acted as the user instantiated model
class. Syms used to hold a pointer to this root module, but hold
instances of any submodule. This patch renames this root scope module
from "TOP" to "$root", and introduces a separate model class which is
now an interface class. As the root module is no longer the user
interface class, it can now be made an instance of Syms, just like any
other submodule. This allows absolute references into the root module to
avoid an additional pointer indirection resulting in a potential speedup
(about 1.5% on OpenTitan). The model class now also contains all non
design specific generated code (e.g.: eval loops, trace config, etc),
which additionally simplifies Verilator internals.
Please see the updated documentation for the model interface changes.
2021-06-21 16:30:20 +02:00
|
|
|
string vlArgType(bool named, bool forReturn, bool forFunc, const string& namespc = "",
|
|
|
|
|
bool asRef = false) const;
|
2019-05-19 22:13:13 +02:00
|
|
|
string vlEnumType() const; // Return VerilatorVarType: VLVT_UINT32, etc
|
|
|
|
|
string vlEnumDir() const; // Return VerilatorVarDir: VLVD_INOUT, etc
|
2020-08-16 20:55:46 +02:00
|
|
|
string vlPropDecl(const string& propName) const; // Return VerilatorVarProps declaration
|
2019-05-19 22:13:13 +02:00
|
|
|
void combineType(AstVarType type);
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual AstNodeDType* getChildDTypep() const override { return childDTypep(); }
|
2020-04-15 13:58:34 +02:00
|
|
|
// op1 = Range of variable
|
2021-10-22 14:56:48 +02:00
|
|
|
AstNodeDType* childDTypep() const { return VN_AS(op1p(), NodeDType); }
|
2013-11-01 03:39:26 +01:00
|
|
|
AstNodeDType* dtypeSkipRefp() const { return subDTypep()->skipRefp(); }
|
2019-05-19 22:13:13 +02:00
|
|
|
// (Slow) recurse down to find basic data type (Note don't need virtual -
|
|
|
|
|
// AstVar isn't a NodeDType)
|
2018-03-10 22:32:04 +01:00
|
|
|
AstBasicDType* basicp() const { return subDTypep()->basicp(); }
|
2021-06-16 13:18:56 +02:00
|
|
|
// op3 = Initial value that never changes (static const), or constructor argument for
|
|
|
|
|
// MTASKSTATE variables
|
2020-04-15 13:58:34 +02:00
|
|
|
AstNode* valuep() const { return op3p(); }
|
|
|
|
|
// It's valuep(), not constp(), as may be more complicated than an AstConst
|
|
|
|
|
void valuep(AstNode* nodep) { setOp3p(nodep); }
|
2019-05-19 22:13:13 +02:00
|
|
|
void addAttrsp(AstNode* nodep) { addNOp4p(nodep); }
|
|
|
|
|
AstNode* attrsp() const { return op4p(); } // op4 = Attributes during early parse
|
|
|
|
|
void childDTypep(AstNodeDType* nodep) { setOp1p(nodep); }
|
2017-11-10 00:04:16 +01:00
|
|
|
virtual AstNodeDType* subDTypep() const { return dtypep() ? dtypep() : childDTypep(); }
|
2019-06-22 18:43:48 +02:00
|
|
|
void ansi(bool flag) { m_ansi = flag; }
|
|
|
|
|
void declTyped(bool flag) { m_declTyped = flag; }
|
2019-05-19 22:13:13 +02:00
|
|
|
void attrClockEn(bool flag) { m_attrClockEn = flag; }
|
2019-10-05 13:54:14 +02:00
|
|
|
void attrClocker(VVarAttrClocker flag) { m_attrClocker = flag; }
|
2019-05-19 22:13:13 +02:00
|
|
|
void attrFileDescr(bool flag) { m_fileDescr = flag; }
|
|
|
|
|
void attrScClocked(bool flag) { m_scClocked = flag; }
|
|
|
|
|
void attrScBv(bool flag) { m_attrScBv = flag; }
|
|
|
|
|
void attrIsolateAssign(bool flag) { m_attrIsolateAssign = flag; }
|
|
|
|
|
void attrSFormat(bool flag) { m_attrSFormat = flag; }
|
2020-02-29 01:15:08 +01:00
|
|
|
void attrSplitVar(bool flag) { m_attrSplitVar = flag; }
|
2019-05-19 22:13:13 +02:00
|
|
|
void usedClock(bool flag) { m_usedClock = flag; }
|
|
|
|
|
void usedParam(bool flag) { m_usedParam = flag; }
|
|
|
|
|
void usedLoopIdx(bool flag) { m_usedLoopIdx = flag; }
|
|
|
|
|
void sigPublic(bool flag) { m_sigPublic = flag; }
|
|
|
|
|
void sigModPublic(bool flag) { m_sigModPublic = flag; }
|
2020-04-15 13:58:34 +02:00
|
|
|
void sigUserRdPublic(bool flag) {
|
|
|
|
|
m_sigUserRdPublic = flag;
|
|
|
|
|
if (flag) sigPublic(true);
|
|
|
|
|
}
|
|
|
|
|
void sigUserRWPublic(bool flag) {
|
|
|
|
|
m_sigUserRWPublic = flag;
|
|
|
|
|
if (flag) sigUserRdPublic(true);
|
|
|
|
|
}
|
2019-05-19 22:13:13 +02:00
|
|
|
void sc(bool flag) { m_sc = flag; }
|
|
|
|
|
void scSensitive(bool flag) { m_scSensitive = flag; }
|
|
|
|
|
void primaryIO(bool flag) { m_primaryIO = flag; }
|
2020-12-07 23:55:22 +01:00
|
|
|
void isRand(bool flag) { m_isRand = flag; }
|
2019-05-19 22:13:13 +02:00
|
|
|
void isConst(bool flag) { m_isConst = flag; }
|
|
|
|
|
void isStatic(bool flag) { m_isStatic = flag; }
|
|
|
|
|
void isIfaceParent(bool flag) { m_isIfaceParent = flag; }
|
|
|
|
|
void funcLocal(bool flag) { m_funcLocal = flag; }
|
|
|
|
|
void funcReturn(bool flag) { m_funcReturn = flag; }
|
|
|
|
|
void isDpiOpenArray(bool flag) { m_isDpiOpenArray = flag; }
|
2017-12-17 22:28:58 +01:00
|
|
|
bool isDpiOpenArray() const { return m_isDpiOpenArray; }
|
2020-11-25 13:03:01 +01:00
|
|
|
bool isHideLocal() const { return m_isHideLocal; }
|
|
|
|
|
void isHideLocal(bool flag) { m_isHideLocal = flag; }
|
|
|
|
|
bool isHideProtected() const { return m_isHideProtected; }
|
|
|
|
|
void isHideProtected(bool flag) { m_isHideProtected = flag; }
|
2019-05-19 22:13:13 +02:00
|
|
|
void noReset(bool flag) { m_noReset = flag; }
|
2018-08-31 02:05:13 +02:00
|
|
|
bool noReset() const { return m_noReset; }
|
2019-05-19 22:13:13 +02:00
|
|
|
void noSubst(bool flag) { m_noSubst = flag; }
|
2014-11-28 21:01:50 +01:00
|
|
|
bool noSubst() const { return m_noSubst; }
|
2020-08-15 15:43:53 +02:00
|
|
|
void overriddenParam(bool flag) { m_overridenParam = flag; }
|
|
|
|
|
bool overriddenParam() const { return m_overridenParam; }
|
2019-05-19 22:13:13 +02:00
|
|
|
void trace(bool flag) { m_trace = flag; }
|
2021-01-05 20:26:01 +01:00
|
|
|
void isLatched(bool flag) { m_isLatched = flag; }
|
2006-08-26 13:35:28 +02:00
|
|
|
// METHODS
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual void name(const string& name) override { m_name = name; }
|
|
|
|
|
virtual void tag(const string& text) override { m_tag = text; }
|
|
|
|
|
virtual string tag() const override { return m_tag; }
|
2019-06-22 18:43:48 +02:00
|
|
|
bool isAnsi() const { return m_ansi; }
|
|
|
|
|
bool isDeclTyped() const { return m_declTyped; }
|
2018-10-27 23:29:00 +02:00
|
|
|
bool isInoutish() const { return m_direction.isInoutish(); }
|
|
|
|
|
bool isNonOutput() const { return m_direction.isNonOutput(); }
|
|
|
|
|
bool isReadOnly() const { return m_direction.isReadOnly(); }
|
|
|
|
|
bool isWritable() const { return m_direction.isWritable(); }
|
2018-10-04 01:51:05 +02:00
|
|
|
bool isTristate() const { return m_tristate; }
|
2018-10-27 23:29:00 +02:00
|
|
|
bool isPrimaryIO() const { return m_primaryIO; }
|
|
|
|
|
bool isPrimaryInish() const { return isPrimaryIO() && isNonOutput(); }
|
2020-04-15 13:58:34 +02:00
|
|
|
bool isIfaceRef() const { return (varType() == AstVarType::IFACEREF); }
|
2019-05-19 22:13:13 +02:00
|
|
|
bool isIfaceParent() const { return m_isIfaceParent; }
|
|
|
|
|
bool isSignal() const { return varType().isSignal(); }
|
2019-10-27 14:27:18 +01:00
|
|
|
bool isTemp() const { return varType().isTemp(); }
|
2019-05-19 22:13:13 +02:00
|
|
|
bool isToggleCoverable() const {
|
|
|
|
|
return ((isIO() || isSignal())
|
|
|
|
|
&& (isIO() || isBitLogic())
|
|
|
|
|
// Wrapper would otherwise duplicate wrapped module's coverage
|
2021-01-25 13:33:38 +01:00
|
|
|
&& !isSc() && !isPrimaryIO() && !isConst() && !isDouble() && !isString());
|
2020-04-15 13:58:34 +02:00
|
|
|
}
|
2020-04-11 03:10:21 +02:00
|
|
|
bool isClassMember() const { return varType() == AstVarType::MEMBER; }
|
2020-04-15 13:58:34 +02:00
|
|
|
bool isStatementTemp() const { return (varType() == AstVarType::STMTTEMP); }
|
|
|
|
|
bool isXTemp() const { return (varType() == AstVarType::XTEMP); }
|
|
|
|
|
bool isParam() const {
|
|
|
|
|
return (varType() == AstVarType::LPARAM || varType() == AstVarType::GPARAM);
|
|
|
|
|
}
|
|
|
|
|
bool isGParam() const { return (varType() == AstVarType::GPARAM); }
|
|
|
|
|
bool isGenVar() const { return (varType() == AstVarType::GENVAR); }
|
|
|
|
|
bool isBitLogic() const {
|
|
|
|
|
AstBasicDType* bdtypep = basicp();
|
|
|
|
|
return bdtypep && bdtypep->isBitLogic();
|
|
|
|
|
}
|
2019-05-19 22:13:13 +02:00
|
|
|
bool isUsedClock() const { return m_usedClock; }
|
|
|
|
|
bool isUsedParam() const { return m_usedParam; }
|
|
|
|
|
bool isUsedLoopIdx() const { return m_usedLoopIdx; }
|
|
|
|
|
bool isSc() const { return m_sc; }
|
|
|
|
|
bool isScQuad() const;
|
|
|
|
|
bool isScBv() const;
|
|
|
|
|
bool isScUint() const;
|
|
|
|
|
bool isScBigUint() const;
|
|
|
|
|
bool isScSensitive() const { return m_scSensitive; }
|
|
|
|
|
bool isSigPublic() const;
|
|
|
|
|
bool isSigModPublic() const { return m_sigModPublic; }
|
|
|
|
|
bool isSigUserRdPublic() const { return m_sigUserRdPublic; }
|
|
|
|
|
bool isSigUserRWPublic() const { return m_sigUserRWPublic; }
|
|
|
|
|
bool isTrace() const { return m_trace; }
|
2020-12-07 23:55:22 +01:00
|
|
|
bool isRand() const { return m_isRand; }
|
2019-05-19 22:13:13 +02:00
|
|
|
bool isConst() const { return m_isConst; }
|
|
|
|
|
bool isStatic() const { return m_isStatic; }
|
2021-01-05 20:26:01 +01:00
|
|
|
bool isLatched() const { return m_isLatched; }
|
2019-05-19 22:13:13 +02:00
|
|
|
bool isFuncLocal() const { return m_funcLocal; }
|
|
|
|
|
bool isFuncReturn() const { return m_funcReturn; }
|
|
|
|
|
bool isPullup() const { return m_isPullup; }
|
|
|
|
|
bool isPulldown() const { return m_isPulldown; }
|
|
|
|
|
bool attrClockEn() const { return m_attrClockEn; }
|
|
|
|
|
bool attrScBv() const { return m_attrScBv; }
|
|
|
|
|
bool attrFileDescr() const { return m_fileDescr; }
|
|
|
|
|
bool attrScClocked() const { return m_scClocked; }
|
|
|
|
|
bool attrSFormat() const { return m_attrSFormat; }
|
2020-02-29 01:15:08 +01:00
|
|
|
bool attrSplitVar() const { return m_attrSplitVar; }
|
2019-05-19 22:13:13 +02:00
|
|
|
bool attrIsolateAssign() const { return m_attrIsolateAssign; }
|
2019-10-05 13:54:14 +02:00
|
|
|
VVarAttrClocker attrClocker() const { return m_attrClocker; }
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual string verilogKwd() const override;
|
2020-04-26 18:45:06 +02:00
|
|
|
void lifetime(const VLifetime& flag) { m_lifetime = flag; }
|
|
|
|
|
VLifetime lifetime() const { return m_lifetime; }
|
2019-05-19 22:13:13 +02:00
|
|
|
void propagateAttrFrom(AstVar* fromp) {
|
|
|
|
|
// This is getting connected to fromp; keep attributes
|
|
|
|
|
// Note the method below too
|
|
|
|
|
if (fromp->attrClockEn()) attrClockEn(true);
|
|
|
|
|
if (fromp->attrFileDescr()) attrFileDescr(true);
|
|
|
|
|
if (fromp->attrIsolateAssign()) attrIsolateAssign(true);
|
2006-08-26 13:35:28 +02:00
|
|
|
}
|
2019-05-19 22:13:13 +02:00
|
|
|
bool gateMultiInputOptimizable() const {
|
|
|
|
|
// Ok to gate optimize; must return false if propagateAttrFrom would do anything
|
|
|
|
|
return (!attrClockEn() && !isUsedClock());
|
2006-08-26 13:35:28 +02:00
|
|
|
}
|
2018-10-27 23:29:00 +02:00
|
|
|
void combineType(AstVar* typevarp) {
|
|
|
|
|
// This is same as typevarp (for combining input & reg decls)
|
|
|
|
|
// "this" is the input var. typevarp is the reg var.
|
2019-05-19 22:13:13 +02:00
|
|
|
propagateAttrFrom(typevarp);
|
|
|
|
|
combineType(typevarp->varType());
|
|
|
|
|
if (typevarp->isSigPublic()) sigPublic(true);
|
|
|
|
|
if (typevarp->isSigModPublic()) sigModPublic(true);
|
|
|
|
|
if (typevarp->isSigUserRdPublic()) sigUserRdPublic(true);
|
|
|
|
|
if (typevarp->isSigUserRWPublic()) sigUserRWPublic(true);
|
|
|
|
|
if (typevarp->attrScClocked()) attrScClocked(true);
|
|
|
|
|
}
|
|
|
|
|
void inlineAttrReset(const string& name) {
|
2020-04-15 13:58:34 +02:00
|
|
|
if (direction() == VDirection::INOUT && varType() == AstVarType::WIRE) {
|
2018-10-27 23:29:00 +02:00
|
|
|
m_varType = AstVarType::TRIWIRE;
|
|
|
|
|
}
|
|
|
|
|
m_direction = VDirection::NONE;
|
|
|
|
|
m_name = name;
|
2006-08-26 13:35:28 +02:00
|
|
|
}
|
2015-02-26 03:09:55 +01:00
|
|
|
static AstVar* scVarRecurse(AstNode* nodep);
|
2018-07-23 02:54:28 +02:00
|
|
|
void addProducingMTaskId(int id) { m_mtaskIds.insert(id); }
|
|
|
|
|
void addConsumingMTaskId(int id) { m_mtaskIds.insert(id); }
|
|
|
|
|
const MTaskIdSet& mtaskIds() const { return m_mtaskIds; }
|
2021-06-19 19:41:19 +02:00
|
|
|
void pinNum(int id) { m_pinNum = id; }
|
|
|
|
|
int pinNum() const { return m_pinNum; }
|
2006-08-26 13:35:28 +02:00
|
|
|
};
|
|
|
|
|
|
2020-11-19 03:32:16 +01:00
|
|
|
class AstDefParam final : public AstNode {
|
2006-08-26 13:35:28 +02:00
|
|
|
// A defparam assignment
|
|
|
|
|
// Parents: MODULE
|
|
|
|
|
// Children: math
|
|
|
|
|
private:
|
2020-04-15 13:58:34 +02:00
|
|
|
string m_name; // Name of variable getting set
|
|
|
|
|
string m_path; // Dotted cellname to set parameter of
|
2006-08-26 13:35:28 +02:00
|
|
|
public:
|
|
|
|
|
AstDefParam(FileLine* fl, const string& path, const string& name, AstNode* rhsp)
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_DefParam(fl) {
|
2019-05-19 22:13:13 +02:00
|
|
|
setOp1p(rhsp);
|
|
|
|
|
m_name = name;
|
|
|
|
|
m_path = path;
|
2006-08-26 13:35:28 +02:00
|
|
|
}
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual string name() const override { return m_name; } // * = Scope name
|
2016-11-05 14:47:56 +01:00
|
|
|
ASTNODE_NODE_FUNCS(DefParam)
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual bool same(const AstNode*) const override { return true; }
|
2019-05-19 22:13:13 +02:00
|
|
|
AstNode* rhsp() const { return op1p(); } // op1 = Assign from
|
|
|
|
|
string path() const { return m_path; }
|
2006-08-26 13:35:28 +02:00
|
|
|
};
|
|
|
|
|
|
2020-11-19 03:32:16 +01:00
|
|
|
class AstImplicit final : public AstNode {
|
2010-01-08 04:08:48 +01:00
|
|
|
// Create implicit wires and do nothing else, for gates that are ignored
|
|
|
|
|
// Parents: MODULE
|
2014-09-12 03:28:53 +02:00
|
|
|
public:
|
2010-01-08 04:08:48 +01:00
|
|
|
AstImplicit(FileLine* fl, AstNode* exprsp)
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_Implicit(fl) {
|
2019-05-19 22:13:13 +02:00
|
|
|
addNOp1p(exprsp);
|
2010-01-08 04:08:48 +01:00
|
|
|
}
|
2016-11-05 14:47:56 +01:00
|
|
|
ASTNODE_NODE_FUNCS(Implicit)
|
2019-05-19 22:13:13 +02:00
|
|
|
AstNode* exprsp() const { return op1p(); } // op1 = Assign from
|
2010-01-08 04:08:48 +01:00
|
|
|
};
|
|
|
|
|
|
2020-11-19 03:32:16 +01:00
|
|
|
class AstScope final : public AstNode {
|
2006-08-26 13:35:28 +02:00
|
|
|
// A particular usage of a cell
|
|
|
|
|
// Parents: MODULE
|
|
|
|
|
// Children: NODEBLOCK
|
|
|
|
|
private:
|
2009-12-05 16:38:49 +01:00
|
|
|
// An AstScope->name() is special: . indicates an uninlined scope, __DOT__ an inlined scope
|
2020-04-15 13:58:34 +02:00
|
|
|
string m_name; // Name
|
2021-10-17 12:40:44 +02:00
|
|
|
AstScope* const m_aboveScopep; // Scope above this one in the hierarchy (nullptr if top)
|
|
|
|
|
AstCell* const m_aboveCellp; // Cell above this in the hierarchy (nullptr if top)
|
|
|
|
|
AstNodeModule* const m_modp; // Module scope corresponds to
|
2006-08-26 13:35:28 +02:00
|
|
|
public:
|
2020-04-15 13:58:34 +02:00
|
|
|
AstScope(FileLine* fl, AstNodeModule* modp, const string& name, AstScope* aboveScopep,
|
|
|
|
|
AstCell* aboveCellp)
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_Scope(fl)
|
2020-08-16 17:40:42 +02:00
|
|
|
, m_name{name}
|
|
|
|
|
, m_aboveScopep{aboveScopep}
|
|
|
|
|
, m_aboveCellp{aboveCellp}
|
|
|
|
|
, m_modp{modp} {}
|
2016-11-05 14:47:56 +01:00
|
|
|
ASTNODE_NODE_FUNCS(Scope)
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual void cloneRelink() override;
|
|
|
|
|
virtual const char* broken() const override;
|
|
|
|
|
virtual bool maybePointedTo() const override { return true; }
|
|
|
|
|
virtual string name() const override { return m_name; } // * = Scope name
|
|
|
|
|
virtual void name(const string& name) override { m_name = name; }
|
2020-11-12 01:00:10 +01:00
|
|
|
virtual void dump(std::ostream& str) const override;
|
2006-08-26 13:35:28 +02:00
|
|
|
string nameDotless() const;
|
2018-10-14 04:02:39 +02:00
|
|
|
string nameVlSym() const { return ((string("vlSymsp->")) + nameDotless()); }
|
2019-05-19 22:13:13 +02:00
|
|
|
AstNodeModule* modp() const { return m_modp; }
|
2021-10-17 12:40:44 +02:00
|
|
|
void addVarp(AstVarScope* nodep) { addOp1p((AstNode*)nodep); }
|
|
|
|
|
AstVarScope* varsp() const { return VN_AS(op1p(), VarScope); } // op1 = AstVarScope's
|
2006-08-26 13:35:28 +02:00
|
|
|
void addActivep(AstNode* nodep) { addOp2p(nodep); }
|
2019-05-19 22:13:13 +02:00
|
|
|
AstNode* blocksp() const { return op2p(); } // op2 = Block names
|
2006-08-26 13:35:28 +02:00
|
|
|
void addFinalClkp(AstNode* nodep) { addOp3p(nodep); }
|
2019-05-19 22:13:13 +02:00
|
|
|
AstNode* finalClksp() const { return op3p(); } // op3 = Final assigns for clock correction
|
2006-08-26 13:35:28 +02:00
|
|
|
AstScope* aboveScopep() const { return m_aboveScopep; }
|
|
|
|
|
AstCell* aboveCellp() const { return m_aboveCellp; }
|
2020-08-15 16:12:55 +02:00
|
|
|
bool isTop() const { return aboveScopep() == nullptr; } // At top of hierarchy
|
2006-08-26 13:35:28 +02:00
|
|
|
};
|
|
|
|
|
|
2020-11-19 03:32:16 +01:00
|
|
|
class AstTopScope final : public AstNode {
|
2021-10-17 11:29:17 +02:00
|
|
|
// A singleton, held under the top level AstModule. Holds the top level AstScope,
|
|
|
|
|
// and after V3ActiveTop, the global list of AstSenTrees (list of unique sensitivity lists).
|
|
|
|
|
// Parent: Top level AstModule
|
|
|
|
|
// Children: AstSenTree, AstScope
|
|
|
|
|
friend class AstNetlist; // Only the AstNetlist can create one
|
2006-08-26 13:35:28 +02:00
|
|
|
AstTopScope(FileLine* fl, AstScope* ascopep)
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_TopScope(fl) {
|
2021-10-17 11:29:17 +02:00
|
|
|
addOp2p(ascopep);
|
2020-04-15 13:58:34 +02:00
|
|
|
}
|
2021-10-17 11:29:17 +02:00
|
|
|
|
|
|
|
|
public:
|
2016-11-05 14:47:56 +01:00
|
|
|
ASTNODE_NODE_FUNCS(TopScope)
|
2021-10-17 11:29:17 +02:00
|
|
|
virtual bool maybePointedTo() const override { return true; }
|
|
|
|
|
AstSenTree* senTreesp() const { return VN_AS(op1p(), SenTree); }
|
|
|
|
|
void addSenTreep(AstSenTree* nodep) { addOp1p((AstNode*)nodep); }
|
|
|
|
|
AstScope* scopep() const { return VN_AS(op2p(), Scope); }
|
2006-08-26 13:35:28 +02:00
|
|
|
};
|
|
|
|
|
|
2020-11-19 03:32:16 +01:00
|
|
|
class AstVarScope final : public AstNode {
|
2006-08-26 13:35:28 +02:00
|
|
|
// A particular scoped usage of a variable
|
2019-05-19 22:13:13 +02:00
|
|
|
// That is, as a module is used under multiple cells, we get a different
|
|
|
|
|
// varscope for each var in the module
|
2006-08-26 13:35:28 +02:00
|
|
|
// Parents: MODULE
|
|
|
|
|
// Children: none
|
|
|
|
|
private:
|
2020-04-15 13:58:34 +02:00
|
|
|
AstScope* m_scopep; // Scope variable is underneath
|
|
|
|
|
AstVar* m_varp; // [AfterLink] Pointer to variable itself
|
|
|
|
|
bool m_circular : 1; // Used in circular ordering dependency, need change detect
|
|
|
|
|
bool m_trace : 1; // Tracing is turned on for this scope
|
2006-08-26 13:35:28 +02:00
|
|
|
public:
|
|
|
|
|
AstVarScope(FileLine* fl, AstScope* scopep, AstVar* varp)
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_VarScope(fl)
|
2020-08-16 17:40:42 +02:00
|
|
|
, m_scopep{scopep}
|
|
|
|
|
, m_varp{varp} {
|
2021-10-17 12:40:44 +02:00
|
|
|
UASSERT_OBJ(scopep, fl, "Scope must be non-null");
|
|
|
|
|
UASSERT_OBJ(varp, fl, "Var must be non-null");
|
2019-03-14 00:47:36 +01:00
|
|
|
m_circular = false;
|
2019-05-19 22:13:13 +02:00
|
|
|
m_trace = true;
|
|
|
|
|
dtypeFrom(varp);
|
2006-08-26 13:35:28 +02:00
|
|
|
}
|
2016-11-05 14:47:56 +01:00
|
|
|
ASTNODE_NODE_FUNCS(VarScope)
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual void cloneRelink() override {
|
2020-04-15 13:58:34 +02:00
|
|
|
if (m_varp && m_varp->clonep()) {
|
|
|
|
|
m_varp = m_varp->clonep();
|
|
|
|
|
UASSERT(m_scopep->clonep(), "No clone cross link: " << this);
|
|
|
|
|
m_scopep = m_scopep->clonep();
|
|
|
|
|
}
|
|
|
|
|
}
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual const char* broken() const override {
|
2020-04-15 13:58:34 +02:00
|
|
|
BROKEN_RTN(m_varp && !m_varp->brokeExists());
|
|
|
|
|
BROKEN_RTN(m_scopep && !m_scopep->brokeExists());
|
2020-08-15 16:12:55 +02:00
|
|
|
return nullptr;
|
2020-04-15 13:58:34 +02:00
|
|
|
}
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual bool maybePointedTo() const override { return true; }
|
|
|
|
|
virtual string name() const override { return scopep()->name() + "->" + varp()->name(); }
|
|
|
|
|
virtual void dump(std::ostream& str) const override;
|
|
|
|
|
virtual bool hasDType() const override { return true; }
|
2019-05-19 22:13:13 +02:00
|
|
|
AstVar* varp() const { return m_varp; } // [After Link] Pointer to variable
|
|
|
|
|
AstScope* scopep() const { return m_scopep; } // Pointer to scope it's under
|
2020-08-15 16:12:55 +02:00
|
|
|
// op1 = Calculation of value of variable, nullptr=complicated
|
2020-04-15 13:58:34 +02:00
|
|
|
AstNode* valuep() const { return op1p(); }
|
2019-05-19 22:13:13 +02:00
|
|
|
void valuep(AstNode* valuep) { addOp1p(valuep); }
|
|
|
|
|
bool isCircular() const { return m_circular; }
|
|
|
|
|
void circular(bool flag) { m_circular = flag; }
|
|
|
|
|
bool isTrace() const { return m_trace; }
|
|
|
|
|
void trace(bool flag) { m_trace = flag; }
|
2006-08-26 13:35:28 +02:00
|
|
|
};
|
|
|
|
|
|
2020-11-19 03:32:16 +01:00
|
|
|
class AstVarRef final : public AstNodeVarRef {
|
2006-08-26 13:35:28 +02:00
|
|
|
// A reference to a variable (lvalue or rvalue)
|
2014-09-12 03:28:53 +02:00
|
|
|
public:
|
2020-09-07 23:09:25 +02:00
|
|
|
AstVarRef(FileLine* fl, const string& name, const VAccess& access)
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_VarRef(fl, name, nullptr, access) {}
|
2018-03-10 22:32:04 +01:00
|
|
|
// This form only allowed post-link because output/wire compression may
|
|
|
|
|
// lead to deletion of AstVar's
|
2020-09-07 23:09:25 +02:00
|
|
|
AstVarRef(FileLine* fl, AstVar* varp, const VAccess& access)
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_VarRef(fl, varp->name(), varp, access) {}
|
2018-03-10 22:32:04 +01:00
|
|
|
// This form only allowed post-link (see above)
|
2020-09-07 23:09:25 +02:00
|
|
|
AstVarRef(FileLine* fl, AstVarScope* varscp, const VAccess& access)
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_VarRef(fl, varscp->varp()->name(), varscp->varp(), access) {
|
2019-05-19 22:13:13 +02:00
|
|
|
varScopep(varscp);
|
2006-08-26 13:35:28 +02:00
|
|
|
}
|
2016-11-05 14:47:56 +01:00
|
|
|
ASTNODE_NODE_FUNCS(VarRef)
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual void dump(std::ostream& str) const override;
|
|
|
|
|
virtual bool same(const AstNode* samep) const override {
|
2020-04-15 13:58:34 +02:00
|
|
|
return same(static_cast<const AstVarRef*>(samep));
|
|
|
|
|
}
|
2017-10-28 16:26:19 +02:00
|
|
|
inline bool same(const AstVarRef* samep) const {
|
2020-04-15 13:58:34 +02:00
|
|
|
if (varScopep()) {
|
2020-09-07 23:09:25 +02:00
|
|
|
return (varScopep() == samep->varScopep() && access() == samep->access());
|
2020-04-15 13:58:34 +02:00
|
|
|
} else {
|
2021-06-13 15:33:11 +02:00
|
|
|
return (selfPointer() == samep->selfPointer()
|
2020-11-25 04:46:02 +01:00
|
|
|
&& varp()->name() == samep->varp()->name() && access() == samep->access());
|
2020-04-15 13:58:34 +02:00
|
|
|
}
|
|
|
|
|
}
|
2012-11-29 02:18:41 +01:00
|
|
|
inline bool sameNoLvalue(AstVarRef* samep) const {
|
2020-04-15 13:58:34 +02:00
|
|
|
if (varScopep()) {
|
|
|
|
|
return (varScopep() == samep->varScopep());
|
|
|
|
|
} else {
|
2021-06-13 15:33:11 +02:00
|
|
|
return (selfPointer() == samep->selfPointer()
|
|
|
|
|
&& (!selfPointer().empty() || !samep->selfPointer().empty())
|
2020-10-08 13:54:01 +02:00
|
|
|
&& varp()->name() == samep->varp()->name());
|
2020-04-15 13:58:34 +02:00
|
|
|
}
|
|
|
|
|
}
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual int instrCount() const override {
|
2021-07-25 14:32:36 +02:00
|
|
|
return widthInstrs() * (access().isReadOrRW() ? INSTR_COUNT_LD : 1);
|
2020-08-15 17:44:10 +02:00
|
|
|
}
|
|
|
|
|
virtual string emitVerilog() override { V3ERROR_NA_RETURN(""); }
|
|
|
|
|
virtual string emitC() override { V3ERROR_NA_RETURN(""); }
|
|
|
|
|
virtual bool cleanOut() const override { return true; }
|
2006-08-26 13:35:28 +02:00
|
|
|
};
|
|
|
|
|
|
2020-11-19 03:32:16 +01:00
|
|
|
class AstVarXRef final : public AstNodeVarRef {
|
2006-08-26 13:35:28 +02:00
|
|
|
// A VarRef to something in another module before AstScope.
|
|
|
|
|
// Includes pin on a cell, as part of a ASSIGN statement to connect I/Os until AstScope
|
|
|
|
|
private:
|
2020-04-15 13:58:34 +02:00
|
|
|
string m_dotted; // Dotted part of scope the name()'ed reference is under or ""
|
|
|
|
|
string m_inlinedDots; // Dotted hierarchy flattened out
|
2006-08-26 13:35:28 +02:00
|
|
|
public:
|
2020-09-07 23:09:25 +02:00
|
|
|
AstVarXRef(FileLine* fl, const string& name, const string& dotted, const VAccess& access)
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_VarXRef(fl, name, nullptr, access)
|
2020-08-16 17:40:42 +02:00
|
|
|
, m_dotted{dotted} {}
|
2020-09-07 23:09:25 +02:00
|
|
|
AstVarXRef(FileLine* fl, AstVar* varp, const string& dotted, const VAccess& access)
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_VarXRef(fl, varp->name(), varp, access)
|
2020-08-16 17:40:42 +02:00
|
|
|
, m_dotted{dotted} {
|
2019-05-19 22:13:13 +02:00
|
|
|
dtypeFrom(varp);
|
2006-08-26 13:35:28 +02:00
|
|
|
}
|
2016-11-05 14:47:56 +01:00
|
|
|
ASTNODE_NODE_FUNCS(VarXRef)
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual void dump(std::ostream& str) const override;
|
2019-05-19 22:13:13 +02:00
|
|
|
string dotted() const { return m_dotted; }
|
|
|
|
|
void dotted(const string& dotted) { m_dotted = dotted; }
|
|
|
|
|
string inlinedDots() const { return m_inlinedDots; }
|
|
|
|
|
void inlinedDots(const string& flag) { m_inlinedDots = flag; }
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual string emitVerilog() override { V3ERROR_NA_RETURN(""); }
|
|
|
|
|
virtual string emitC() override { V3ERROR_NA_RETURN(""); }
|
|
|
|
|
virtual bool cleanOut() const override { return true; }
|
|
|
|
|
virtual int instrCount() const override { return widthInstrs(); }
|
|
|
|
|
virtual bool same(const AstNode* samep) const override {
|
2019-05-19 22:13:13 +02:00
|
|
|
const AstVarXRef* asamep = static_cast<const AstVarXRef*>(samep);
|
2021-06-13 15:33:11 +02:00
|
|
|
return (selfPointer() == asamep->selfPointer() && varp() == asamep->varp()
|
2020-04-15 13:58:34 +02:00
|
|
|
&& name() == asamep->name() && dotted() == asamep->dotted());
|
|
|
|
|
}
|
2006-08-26 13:35:28 +02:00
|
|
|
};
|
|
|
|
|
|
2021-06-13 15:33:11 +02:00
|
|
|
class AstAddrOfCFunc final : public AstNodeMath {
|
|
|
|
|
// Get address of CFunc
|
|
|
|
|
private:
|
|
|
|
|
AstCFunc* m_funcp; // Pointer to function itself
|
|
|
|
|
|
|
|
|
|
public:
|
|
|
|
|
AstAddrOfCFunc(FileLine* fl, AstCFunc* funcp)
|
|
|
|
|
: ASTGEN_SUPER_AddrOfCFunc(fl)
|
|
|
|
|
, m_funcp{funcp} {
|
|
|
|
|
dtypep(findCHandleDType());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public:
|
|
|
|
|
ASTNODE_NODE_FUNCS(AddrOfCFunc)
|
|
|
|
|
virtual void cloneRelink() override;
|
|
|
|
|
virtual const char* broken() const override;
|
|
|
|
|
virtual string emitVerilog() override { V3ERROR_NA_RETURN(""); }
|
|
|
|
|
virtual string emitC() override { V3ERROR_NA_RETURN(""); }
|
|
|
|
|
virtual bool cleanOut() const override { return true; }
|
|
|
|
|
AstCFunc* funcp() const { return m_funcp; }
|
|
|
|
|
};
|
|
|
|
|
|
2020-11-19 03:32:16 +01:00
|
|
|
class AstPin final : public AstNode {
|
2006-08-26 13:35:28 +02:00
|
|
|
// A pin on a cell
|
|
|
|
|
private:
|
2020-04-15 13:58:34 +02:00
|
|
|
int m_pinNum; // Pin number
|
|
|
|
|
string m_name; // Pin name, or "" for number based interconnect
|
2020-08-15 19:11:27 +02:00
|
|
|
AstVar* m_modVarp = nullptr; // Input/output this pin connects to on submodule.
|
|
|
|
|
AstParamTypeDType* m_modPTypep = nullptr; // Param type this pin connects to on submodule.
|
|
|
|
|
bool m_param = false; // Pin connects to parameter
|
|
|
|
|
bool m_svImplicit = false; // Pin is SystemVerilog .name'ed
|
2006-08-26 13:35:28 +02:00
|
|
|
public:
|
|
|
|
|
AstPin(FileLine* fl, int pinNum, const string& name, AstNode* exprp)
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_Pin(fl)
|
2020-08-16 17:40:42 +02:00
|
|
|
, m_pinNum{pinNum}
|
|
|
|
|
, m_name{name} {
|
2019-03-14 00:47:36 +01:00
|
|
|
setNOp1p(exprp);
|
2011-02-08 01:15:58 +01:00
|
|
|
}
|
2012-02-12 02:40:58 +01:00
|
|
|
AstPin(FileLine* fl, int pinNum, AstVarRef* varname, AstNode* exprp)
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_Pin(fl)
|
2020-08-16 17:40:42 +02:00
|
|
|
, m_pinNum{pinNum}
|
|
|
|
|
, m_name{varname->name()} {
|
2019-05-19 22:13:13 +02:00
|
|
|
setNOp1p(exprp);
|
2012-02-12 02:40:58 +01:00
|
|
|
}
|
2016-11-05 14:47:56 +01:00
|
|
|
ASTNODE_NODE_FUNCS(Pin)
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual void dump(std::ostream& str) const override;
|
|
|
|
|
virtual const char* broken() const override {
|
2019-05-19 22:13:13 +02:00
|
|
|
BROKEN_RTN(m_modVarp && !m_modVarp->brokeExists());
|
|
|
|
|
BROKEN_RTN(m_modPTypep && !m_modPTypep->brokeExists());
|
2020-08-15 16:12:55 +02:00
|
|
|
return nullptr;
|
2020-04-15 13:58:34 +02:00
|
|
|
}
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual string name() const override { return m_name; } // * = Pin name, ""=go by number
|
|
|
|
|
virtual void name(const string& name) override { m_name = name; }
|
|
|
|
|
virtual string prettyOperatorName() const override {
|
2020-04-15 13:58:34 +02:00
|
|
|
return modVarp()
|
|
|
|
|
? ((modVarp()->direction().isAny() ? modVarp()->direction().prettyName() + " "
|
|
|
|
|
: "")
|
|
|
|
|
+ "port connection " + modVarp()->prettyNameQ())
|
|
|
|
|
: "port connection";
|
|
|
|
|
}
|
2018-10-27 23:29:00 +02:00
|
|
|
bool dotStar() const { return name() == ".*"; } // Fake name for .* connections until linked
|
2019-05-19 22:13:13 +02:00
|
|
|
int pinNum() const { return m_pinNum; }
|
|
|
|
|
void exprp(AstNode* nodep) { addOp1p(nodep); }
|
2020-08-15 16:12:55 +02:00
|
|
|
// op1 = Expression connected to pin, nullptr if unconnected
|
2020-04-15 13:58:34 +02:00
|
|
|
AstNode* exprp() const { return op1p(); }
|
2019-05-19 22:13:13 +02:00
|
|
|
AstVar* modVarp() const { return m_modVarp; } // [After Link] Pointer to variable
|
|
|
|
|
void modVarp(AstVar* nodep) { m_modVarp = nodep; }
|
2020-04-15 13:58:34 +02:00
|
|
|
// [After Link] Pointer to variable
|
|
|
|
|
AstParamTypeDType* modPTypep() const { return m_modPTypep; }
|
2019-05-19 22:13:13 +02:00
|
|
|
void modPTypep(AstParamTypeDType* nodep) { m_modPTypep = nodep; }
|
|
|
|
|
bool param() const { return m_param; }
|
|
|
|
|
void param(bool flag) { m_param = flag; }
|
|
|
|
|
bool svImplicit() const { return m_svImplicit; }
|
|
|
|
|
void svImplicit(bool flag) { m_svImplicit = flag; }
|
2006-08-26 13:35:28 +02:00
|
|
|
};
|
|
|
|
|
|
2020-11-19 03:32:16 +01:00
|
|
|
class AstArg final : public AstNode {
|
2013-08-18 02:34:49 +02:00
|
|
|
// An argument to a function/task
|
|
|
|
|
private:
|
2020-04-15 13:58:34 +02:00
|
|
|
string m_name; // Pin name, or "" for number based interconnect
|
2013-08-18 02:34:49 +02:00
|
|
|
public:
|
|
|
|
|
AstArg(FileLine* fl, const string& name, AstNode* exprp)
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_Arg(fl)
|
2020-08-16 17:40:42 +02:00
|
|
|
, m_name{name} {
|
2019-05-19 22:13:13 +02:00
|
|
|
setNOp1p(exprp);
|
2013-08-18 02:34:49 +02:00
|
|
|
}
|
2016-11-05 14:47:56 +01:00
|
|
|
ASTNODE_NODE_FUNCS(Arg)
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual string name() const override { return m_name; } // * = Pin name, ""=go by number
|
|
|
|
|
virtual void name(const string& name) override { m_name = name; }
|
2019-05-19 22:13:13 +02:00
|
|
|
void exprp(AstNode* nodep) { addOp1p(nodep); }
|
2020-08-15 16:12:55 +02:00
|
|
|
// op1 = Expression connected to pin, nullptr if unconnected
|
2020-04-15 13:58:34 +02:00
|
|
|
AstNode* exprp() const { return op1p(); }
|
|
|
|
|
bool emptyConnectNoNext() const { return !exprp() && name() == "" && !nextp(); }
|
2013-08-18 02:34:49 +02:00
|
|
|
};
|
|
|
|
|
|
2020-11-19 03:32:16 +01:00
|
|
|
class AstModule final : public AstNodeModule {
|
2006-08-26 13:35:28 +02:00
|
|
|
// A module declaration
|
2020-07-16 13:31:16 +02:00
|
|
|
private:
|
2021-11-26 23:55:36 +01:00
|
|
|
const bool m_isProgram; // Module represents a program
|
2014-09-12 03:28:53 +02:00
|
|
|
public:
|
2020-07-16 13:31:16 +02:00
|
|
|
AstModule(FileLine* fl, const string& name, bool program = false)
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_Module(fl, name)
|
2020-08-16 17:40:42 +02:00
|
|
|
, m_isProgram{program} {}
|
2016-11-05 14:47:56 +01:00
|
|
|
ASTNODE_NODE_FUNCS(Module)
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual string verilogKwd() const override { return m_isProgram ? "program" : "module"; }
|
2021-03-17 03:52:29 +01:00
|
|
|
virtual bool timescaleMatters() const override { return true; }
|
2006-08-26 13:35:28 +02:00
|
|
|
};
|
|
|
|
|
|
2020-11-19 03:32:16 +01:00
|
|
|
class AstNotFoundModule final : public AstNodeModule {
|
2011-10-28 02:56:38 +02:00
|
|
|
// A missing module declaration
|
2014-09-12 03:28:53 +02:00
|
|
|
public:
|
2011-10-28 02:56:38 +02:00
|
|
|
AstNotFoundModule(FileLine* fl, const string& name)
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_NotFoundModule(fl, name) {}
|
2016-11-05 14:47:56 +01:00
|
|
|
ASTNODE_NODE_FUNCS(NotFoundModule)
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual string verilogKwd() const override { return "/*not-found-*/ module"; }
|
2021-03-17 03:52:29 +01:00
|
|
|
virtual bool timescaleMatters() const override { return false; }
|
2011-10-28 02:56:38 +02:00
|
|
|
};
|
|
|
|
|
|
2020-11-19 03:32:16 +01:00
|
|
|
class AstPackage final : public AstNodeModule {
|
2009-11-08 03:05:02 +01:00
|
|
|
// A package declaration
|
2014-09-12 03:28:53 +02:00
|
|
|
public:
|
2009-11-08 03:05:02 +01:00
|
|
|
AstPackage(FileLine* fl, const string& name)
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_Package(fl, name) {}
|
2016-11-05 14:47:56 +01:00
|
|
|
ASTNODE_NODE_FUNCS(Package)
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual string verilogKwd() const override { return "package"; }
|
2021-03-17 03:52:29 +01:00
|
|
|
virtual bool timescaleMatters() const override { return !isDollarUnit(); }
|
2009-11-08 03:05:02 +01:00
|
|
|
static string dollarUnitName() { return AstNode::encodeName("$unit"); }
|
|
|
|
|
bool isDollarUnit() const { return name() == dollarUnitName(); }
|
|
|
|
|
};
|
|
|
|
|
|
2020-11-19 03:32:16 +01:00
|
|
|
class AstPrimitive final : public AstNodeModule {
|
2010-01-08 04:44:30 +01:00
|
|
|
// A primitive declaration
|
2014-09-12 03:28:53 +02:00
|
|
|
public:
|
2010-01-08 04:44:30 +01:00
|
|
|
AstPrimitive(FileLine* fl, const string& name)
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_Primitive(fl, name) {}
|
2016-11-05 14:47:56 +01:00
|
|
|
ASTNODE_NODE_FUNCS(Primitive)
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual string verilogKwd() const override { return "primitive"; }
|
2021-03-17 03:52:29 +01:00
|
|
|
virtual bool timescaleMatters() const override { return false; }
|
2010-01-08 04:44:30 +01:00
|
|
|
};
|
|
|
|
|
|
2020-11-19 03:32:16 +01:00
|
|
|
class AstPackageExportStarStar final : public AstNode {
|
2017-09-21 03:04:59 +02:00
|
|
|
// A package export *::* declaration
|
|
|
|
|
public:
|
2017-10-14 20:51:57 +02:00
|
|
|
// cppcheck-suppress noExplicitConstructor
|
2017-09-21 03:04:59 +02:00
|
|
|
AstPackageExportStarStar(FileLine* fl)
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_PackageExportStarStar(fl) {}
|
2017-09-21 03:04:59 +02:00
|
|
|
ASTNODE_NODE_FUNCS(PackageExportStarStar)
|
|
|
|
|
};
|
|
|
|
|
|
2020-11-19 03:32:16 +01:00
|
|
|
class AstPackageExport final : public AstNode {
|
2017-09-21 03:04:59 +02:00
|
|
|
private:
|
|
|
|
|
// A package export declaration
|
2020-04-15 13:58:34 +02:00
|
|
|
string m_name;
|
|
|
|
|
AstPackage* m_packagep; // Package hierarchy
|
2017-09-21 03:04:59 +02:00
|
|
|
public:
|
|
|
|
|
AstPackageExport(FileLine* fl, AstPackage* packagep, const string& name)
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_PackageExport(fl)
|
2020-08-16 17:40:42 +02:00
|
|
|
, m_name{name}
|
|
|
|
|
, m_packagep{packagep} {}
|
2017-09-21 03:04:59 +02:00
|
|
|
ASTNODE_NODE_FUNCS(PackageExport)
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual const char* broken() const override {
|
2020-04-15 13:58:34 +02:00
|
|
|
BROKEN_RTN(!m_packagep || !m_packagep->brokeExists());
|
2020-08-15 16:12:55 +02:00
|
|
|
return nullptr;
|
2020-04-15 13:58:34 +02:00
|
|
|
}
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual void cloneRelink() override {
|
2020-04-15 13:58:34 +02:00
|
|
|
if (m_packagep && m_packagep->clonep()) m_packagep = m_packagep->clonep();
|
|
|
|
|
}
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual void dump(std::ostream& str) const override;
|
|
|
|
|
virtual string name() const override { return m_name; }
|
2017-09-21 03:04:59 +02:00
|
|
|
AstPackage* packagep() const { return m_packagep; }
|
2019-05-19 22:13:13 +02:00
|
|
|
void packagep(AstPackage* nodep) { m_packagep = nodep; }
|
2017-09-21 03:04:59 +02:00
|
|
|
};
|
|
|
|
|
|
2020-11-19 03:32:16 +01:00
|
|
|
class AstPackageImport final : public AstNode {
|
2009-11-10 01:07:59 +01:00
|
|
|
private:
|
|
|
|
|
// A package import declaration
|
2020-04-15 13:58:34 +02:00
|
|
|
string m_name;
|
|
|
|
|
AstPackage* m_packagep; // Package hierarchy
|
2009-11-10 01:07:59 +01:00
|
|
|
public:
|
|
|
|
|
AstPackageImport(FileLine* fl, AstPackage* packagep, const string& name)
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_PackageImport(fl)
|
2020-08-16 17:40:42 +02:00
|
|
|
, m_name{name}
|
|
|
|
|
, m_packagep{packagep} {}
|
2016-11-05 14:47:56 +01:00
|
|
|
ASTNODE_NODE_FUNCS(PackageImport)
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual const char* broken() const override {
|
2020-04-15 13:58:34 +02:00
|
|
|
BROKEN_RTN(!m_packagep || !m_packagep->brokeExists());
|
2020-08-15 16:12:55 +02:00
|
|
|
return nullptr;
|
2020-04-15 13:58:34 +02:00
|
|
|
}
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual void cloneRelink() override {
|
2020-04-15 13:58:34 +02:00
|
|
|
if (m_packagep && m_packagep->clonep()) m_packagep = m_packagep->clonep();
|
|
|
|
|
}
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual void dump(std::ostream& str) const override;
|
|
|
|
|
virtual string name() const override { return m_name; }
|
2009-11-10 01:07:59 +01:00
|
|
|
AstPackage* packagep() const { return m_packagep; }
|
2019-05-19 22:13:13 +02:00
|
|
|
void packagep(AstPackage* nodep) { m_packagep = nodep; }
|
2009-11-10 01:07:59 +01:00
|
|
|
};
|
|
|
|
|
|
2020-11-19 03:32:16 +01:00
|
|
|
class AstIface final : public AstNodeModule {
|
2013-05-28 03:39:19 +02:00
|
|
|
// A module declaration
|
2014-09-12 03:28:53 +02:00
|
|
|
public:
|
2013-05-28 03:39:19 +02:00
|
|
|
AstIface(FileLine* fl, const string& name)
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_Iface(fl, name) {}
|
2016-11-05 14:47:56 +01:00
|
|
|
ASTNODE_NODE_FUNCS(Iface)
|
2021-03-17 03:52:29 +01:00
|
|
|
// Interfaces have `timescale applicability but lots of code seems to
|
|
|
|
|
// get false warnings if we enable this
|
|
|
|
|
virtual bool timescaleMatters() const override { return false; }
|
2013-05-28 03:39:19 +02:00
|
|
|
};
|
|
|
|
|
|
2020-11-19 03:32:16 +01:00
|
|
|
class AstMemberSel final : public AstNodeMath {
|
2019-12-23 21:03:04 +01:00
|
|
|
// Parents: math|stmt
|
|
|
|
|
// Children: varref|arraysel, math
|
|
|
|
|
private:
|
|
|
|
|
// Don't need the class we are extracting from, as the "fromp()"'s datatype can get us to it
|
|
|
|
|
string m_name;
|
2020-08-15 19:11:27 +02:00
|
|
|
AstVar* m_varp = nullptr; // Post link, variable within class that is target of selection
|
2019-12-23 21:03:04 +01:00
|
|
|
public:
|
|
|
|
|
AstMemberSel(FileLine* fl, AstNode* fromp, VFlagChildDType, const string& name)
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_MemberSel(fl)
|
2020-08-16 17:40:42 +02:00
|
|
|
, m_name{name} {
|
2019-12-23 21:03:04 +01:00
|
|
|
setOp1p(fromp);
|
2020-08-15 16:12:55 +02:00
|
|
|
dtypep(nullptr); // V3Width will resolve
|
2019-12-23 21:03:04 +01:00
|
|
|
}
|
|
|
|
|
AstMemberSel(FileLine* fl, AstNode* fromp, AstNodeDType* dtp)
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_MemberSel(fl)
|
2020-08-16 17:40:42 +02:00
|
|
|
, m_name{dtp->name()} {
|
2019-12-23 21:03:04 +01:00
|
|
|
setOp1p(fromp);
|
|
|
|
|
dtypep(dtp);
|
|
|
|
|
}
|
|
|
|
|
ASTNODE_NODE_FUNCS(MemberSel)
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual void cloneRelink() override {
|
2021-02-22 03:25:21 +01:00
|
|
|
if (m_varp && m_varp->clonep()) m_varp = m_varp->clonep();
|
2020-04-15 13:58:34 +02:00
|
|
|
}
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual const char* broken() const override {
|
2020-04-15 13:58:34 +02:00
|
|
|
BROKEN_RTN(m_varp && !m_varp->brokeExists());
|
2020-08-15 16:12:55 +02:00
|
|
|
return nullptr;
|
2020-04-15 13:58:34 +02:00
|
|
|
}
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual void dump(std::ostream& str) const override;
|
|
|
|
|
virtual string name() const override { return m_name; }
|
|
|
|
|
virtual string emitVerilog() override { V3ERROR_NA_RETURN(""); }
|
|
|
|
|
virtual string emitC() override { V3ERROR_NA_RETURN(""); }
|
|
|
|
|
virtual bool cleanOut() const override { return false; }
|
|
|
|
|
virtual bool same(const AstNode* samep) const override {
|
|
|
|
|
return true;
|
|
|
|
|
} // dtype comparison does it
|
|
|
|
|
virtual int instrCount() const override { return widthInstrs(); }
|
2020-08-15 16:12:55 +02:00
|
|
|
AstNode* fromp() const {
|
|
|
|
|
return op1p();
|
|
|
|
|
} // op1 = Extracting what (nullptr=TBD during parsing)
|
2019-12-23 21:03:04 +01:00
|
|
|
void fromp(AstNode* nodep) { setOp1p(nodep); }
|
|
|
|
|
AstVar* varp() const { return m_varp; }
|
|
|
|
|
void varp(AstVar* nodep) { m_varp = nodep; }
|
|
|
|
|
};
|
|
|
|
|
|
2020-11-19 03:32:16 +01:00
|
|
|
class AstModportFTaskRef final : public AstNode {
|
2013-12-21 12:51:15 +01:00
|
|
|
// An import/export referenced under a modport
|
2019-05-19 22:13:13 +02:00
|
|
|
// The storage for the function itself is inside the
|
|
|
|
|
// interface/instantiator, thus this is a reference
|
2013-12-21 12:51:15 +01:00
|
|
|
// PARENT: AstModport
|
|
|
|
|
private:
|
2020-04-15 13:58:34 +02:00
|
|
|
string m_name; // Name of the variable referenced
|
|
|
|
|
bool m_export; // Type of the function (import/export)
|
2020-08-15 19:11:27 +02:00
|
|
|
AstNodeFTask* m_ftaskp = nullptr; // Link to the function
|
2013-12-21 12:51:15 +01:00
|
|
|
public:
|
|
|
|
|
AstModportFTaskRef(FileLine* fl, const string& name, bool isExport)
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_ModportFTaskRef(fl)
|
2020-08-16 17:40:42 +02:00
|
|
|
, m_name{name}
|
|
|
|
|
, m_export{isExport} {}
|
2016-11-05 14:47:56 +01:00
|
|
|
ASTNODE_NODE_FUNCS(ModportFTaskRef)
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual const char* broken() const override {
|
2020-04-15 13:58:34 +02:00
|
|
|
BROKEN_RTN(m_ftaskp && !m_ftaskp->brokeExists());
|
2020-08-15 16:12:55 +02:00
|
|
|
return nullptr;
|
2020-04-15 13:58:34 +02:00
|
|
|
}
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual void dump(std::ostream& str) const override;
|
|
|
|
|
virtual string name() const override { return m_name; }
|
|
|
|
|
virtual void cloneRelink() override {
|
2020-04-15 13:58:34 +02:00
|
|
|
if (m_ftaskp && m_ftaskp->clonep()) m_ftaskp = m_ftaskp->clonep();
|
|
|
|
|
}
|
2013-12-21 12:51:15 +01:00
|
|
|
bool isImport() const { return !m_export; }
|
|
|
|
|
bool isExport() const { return m_export; }
|
2019-05-19 22:13:13 +02:00
|
|
|
AstNodeFTask* ftaskp() const { return m_ftaskp; } // [After Link] Pointer to variable
|
|
|
|
|
void ftaskp(AstNodeFTask* ftaskp) { m_ftaskp = ftaskp; }
|
2013-12-21 12:51:15 +01:00
|
|
|
};
|
|
|
|
|
|
2020-11-19 03:32:16 +01:00
|
|
|
class AstModportVarRef final : public AstNode {
|
2013-05-28 03:39:19 +02:00
|
|
|
// A input/output/etc variable referenced under a modport
|
|
|
|
|
// The storage for the variable itself is inside the interface, thus this is a reference
|
2013-12-21 12:51:15 +01:00
|
|
|
// PARENT: AstModport
|
2013-05-28 03:39:19 +02:00
|
|
|
private:
|
2020-04-15 13:58:34 +02:00
|
|
|
string m_name; // Name of the variable referenced
|
|
|
|
|
VDirection m_direction; // Direction of the variable (in/out)
|
2020-08-15 19:11:27 +02:00
|
|
|
AstVar* m_varp = nullptr; // Link to the actual Var
|
2013-05-28 03:39:19 +02:00
|
|
|
public:
|
2018-10-27 23:29:00 +02:00
|
|
|
AstModportVarRef(FileLine* fl, const string& name, VDirection::en direction)
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_ModportVarRef(fl)
|
2020-08-16 17:40:42 +02:00
|
|
|
, m_name{name}
|
|
|
|
|
, m_direction{direction} {}
|
2016-11-05 14:47:56 +01:00
|
|
|
ASTNODE_NODE_FUNCS(ModportVarRef)
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual const char* broken() const override {
|
2020-04-15 13:58:34 +02:00
|
|
|
BROKEN_RTN(m_varp && !m_varp->brokeExists());
|
2020-08-15 16:12:55 +02:00
|
|
|
return nullptr;
|
2020-04-15 13:58:34 +02:00
|
|
|
}
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual void dump(std::ostream& str) const override;
|
|
|
|
|
virtual void cloneRelink() override {
|
2020-04-15 13:58:34 +02:00
|
|
|
if (m_varp && m_varp->clonep()) m_varp = m_varp->clonep();
|
|
|
|
|
}
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual string name() const override { return m_name; }
|
2018-10-27 23:29:00 +02:00
|
|
|
void direction(const VDirection& flag) { m_direction = flag; }
|
|
|
|
|
VDirection direction() const { return m_direction; }
|
2019-05-19 22:13:13 +02:00
|
|
|
AstVar* varp() const { return m_varp; } // [After Link] Pointer to variable
|
|
|
|
|
void varp(AstVar* varp) { m_varp = varp; }
|
2013-05-28 03:39:19 +02:00
|
|
|
};
|
|
|
|
|
|
2020-11-19 03:32:16 +01:00
|
|
|
class AstModport final : public AstNode {
|
2013-05-28 03:39:19 +02:00
|
|
|
// A modport in an interface
|
|
|
|
|
private:
|
2020-04-15 13:58:34 +02:00
|
|
|
string m_name; // Name of the modport
|
2013-05-28 03:39:19 +02:00
|
|
|
public:
|
2013-12-21 12:51:15 +01:00
|
|
|
AstModport(FileLine* fl, const string& name, AstNode* varsp)
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_Modport(fl)
|
2020-08-16 17:40:42 +02:00
|
|
|
, m_name{name} {
|
2020-04-15 13:58:34 +02:00
|
|
|
addNOp1p(varsp);
|
|
|
|
|
}
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual string name() const override { return m_name; }
|
|
|
|
|
virtual bool maybePointedTo() const override { return true; }
|
2016-11-05 14:47:56 +01:00
|
|
|
ASTNODE_NODE_FUNCS(Modport)
|
2019-05-19 22:13:13 +02:00
|
|
|
AstNode* varsp() const { return op1p(); } // op1 = List of Vars
|
2013-05-28 03:39:19 +02:00
|
|
|
};
|
|
|
|
|
|
2020-11-19 03:32:16 +01:00
|
|
|
class AstIntfRef final : public AstNode {
|
2019-12-07 15:42:09 +01:00
|
|
|
// An interface reference
|
|
|
|
|
private:
|
|
|
|
|
string m_name; // Name of the reference
|
|
|
|
|
public:
|
|
|
|
|
AstIntfRef(FileLine* fl, const string& name)
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_IntfRef(fl)
|
2020-08-16 17:40:42 +02:00
|
|
|
, m_name{name} {}
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual string name() const override { return m_name; }
|
2019-12-07 15:42:09 +01:00
|
|
|
ASTNODE_NODE_FUNCS(IntfRef)
|
|
|
|
|
};
|
|
|
|
|
|
2020-11-19 03:32:16 +01:00
|
|
|
class AstCell final : public AstNode {
|
2009-11-07 12:20:20 +01:00
|
|
|
// A instantiation cell or interface call (don't know which until link)
|
2006-08-26 13:35:28 +02:00
|
|
|
private:
|
2020-04-15 13:58:34 +02:00
|
|
|
FileLine* m_modNameFileline; // Where module the cell instances token was
|
|
|
|
|
string m_name; // Cell name
|
|
|
|
|
string m_origName; // Original name before dot addition
|
|
|
|
|
string m_modName; // Module the cell instances
|
2020-08-15 19:11:27 +02:00
|
|
|
AstNodeModule* m_modp = nullptr; // [AfterLink] Pointer to module instanced
|
2020-04-15 13:58:34 +02:00
|
|
|
bool m_hasIfaceVar : 1; // True if a Var has been created for this cell
|
|
|
|
|
bool m_recursive : 1; // Self-recursive module
|
|
|
|
|
bool m_trace : 1; // Trace this cell
|
|
|
|
|
public:
|
|
|
|
|
AstCell(FileLine* fl, FileLine* mfl, const string& instName, const string& modName,
|
2019-05-19 22:13:13 +02:00
|
|
|
AstPin* pinsp, AstPin* paramsp, AstRange* rangep)
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_Cell(fl)
|
2020-08-16 17:40:42 +02:00
|
|
|
, m_modNameFileline{mfl}
|
|
|
|
|
, m_name{instName}
|
|
|
|
|
, m_origName{instName}
|
|
|
|
|
, m_modName{modName}
|
|
|
|
|
, m_hasIfaceVar{false}
|
|
|
|
|
, m_recursive{false}
|
|
|
|
|
, m_trace{true} {
|
2020-04-15 13:58:34 +02:00
|
|
|
addNOp1p(pinsp);
|
|
|
|
|
addNOp2p(paramsp);
|
|
|
|
|
setNOp3p(rangep);
|
|
|
|
|
}
|
2016-11-05 14:47:56 +01:00
|
|
|
ASTNODE_NODE_FUNCS(Cell)
|
2006-08-26 13:35:28 +02:00
|
|
|
// No cloneRelink, we presume cloneee's want the same module linkages
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual void dump(std::ostream& str) const override;
|
|
|
|
|
virtual const char* broken() const override {
|
2020-04-15 13:58:34 +02:00
|
|
|
BROKEN_RTN(m_modp && !m_modp->brokeExists());
|
2020-08-15 16:12:55 +02:00
|
|
|
return nullptr;
|
2020-04-15 13:58:34 +02:00
|
|
|
}
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual bool maybePointedTo() const override { return true; }
|
2006-08-26 13:35:28 +02:00
|
|
|
// ACCESSORS
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual string name() const override { return m_name; } // * = Cell name
|
|
|
|
|
virtual void name(const string& name) override { m_name = name; }
|
|
|
|
|
virtual string origName() const override { return m_origName; } // * = Original name
|
2019-05-19 22:13:13 +02:00
|
|
|
void origName(const string& name) { m_origName = name; }
|
|
|
|
|
string modName() const { return m_modName; } // * = Instance name
|
|
|
|
|
void modName(const string& name) { m_modName = name; }
|
2019-07-14 21:06:49 +02:00
|
|
|
FileLine* modNameFileline() const { return m_modNameFileline; }
|
2021-10-22 14:56:48 +02:00
|
|
|
AstPin* pinsp() const { return VN_AS(op1p(), Pin); } // op1 = List of cell ports
|
2020-04-15 13:58:34 +02:00
|
|
|
// op2 = List of parameter #(##) values
|
2021-10-22 14:56:48 +02:00
|
|
|
AstPin* paramsp() const { return VN_AS(op2p(), Pin); }
|
2020-08-15 16:12:55 +02:00
|
|
|
// op3 = Range of arrayed instants (nullptr=not ranged)
|
2021-10-22 14:56:48 +02:00
|
|
|
AstRange* rangep() const { return VN_AS(op3p(), Range); }
|
2020-04-15 13:58:34 +02:00
|
|
|
// op4 = List of interface references
|
2021-10-22 14:56:48 +02:00
|
|
|
AstIntfRef* intfRefp() const { return VN_AS(op4p(), IntfRef); }
|
2019-05-19 22:13:13 +02:00
|
|
|
AstNodeModule* modp() const { return m_modp; } // [AfterLink] = Pointer to module instantiated
|
2006-09-01 17:31:07 +02:00
|
|
|
void addPinsp(AstPin* nodep) { addOp1p(nodep); }
|
|
|
|
|
void addParamsp(AstPin* nodep) { addOp2p(nodep); }
|
2019-12-07 15:42:09 +01:00
|
|
|
void addIntfRefp(AstIntfRef* nodep) { addOp4p(nodep); }
|
2019-05-19 22:13:13 +02:00
|
|
|
void modp(AstNodeModule* nodep) { m_modp = nodep; }
|
2013-05-28 03:39:19 +02:00
|
|
|
bool hasIfaceVar() const { return m_hasIfaceVar; }
|
|
|
|
|
void hasIfaceVar(bool flag) { m_hasIfaceVar = flag; }
|
2019-05-19 22:13:13 +02:00
|
|
|
void trace(bool flag) { m_trace = flag; }
|
2014-11-08 20:15:10 +01:00
|
|
|
bool isTrace() const { return m_trace; }
|
2017-11-18 23:42:35 +01:00
|
|
|
void recursive(bool flag) { m_recursive = flag; }
|
|
|
|
|
bool recursive() const { return m_recursive; }
|
2006-08-26 13:35:28 +02:00
|
|
|
};
|
|
|
|
|
|
2020-11-19 03:32:16 +01:00
|
|
|
class AstCellInline final : public AstNode {
|
2006-08-26 13:35:28 +02:00
|
|
|
// A instantiation cell that was removed by inlining
|
2019-10-02 03:57:45 +02:00
|
|
|
// For communication between V3Inline and V3LinkDot,
|
|
|
|
|
// except for VPI runs where it exists until the end.
|
|
|
|
|
// It is augmented with the scope in V3Scope for VPI.
|
2006-08-26 13:35:28 +02:00
|
|
|
// Children: When 2 levels inlined, other CellInline under this
|
|
|
|
|
private:
|
2020-04-15 13:58:34 +02:00
|
|
|
string m_name; // Cell name, possibly {a}__DOT__{b}...
|
2021-11-26 23:55:36 +01:00
|
|
|
const string
|
|
|
|
|
m_origModName; // Original name of the module, ignoring name() changes, for dot lookup
|
2020-08-15 19:11:27 +02:00
|
|
|
AstScope* m_scopep = nullptr; // The scope that the cell is inlined into
|
2020-04-16 01:39:03 +02:00
|
|
|
VTimescale m_timeunit; // Parent module time unit
|
2006-08-26 13:35:28 +02:00
|
|
|
public:
|
2020-04-16 01:39:03 +02:00
|
|
|
AstCellInline(FileLine* fl, const string& name, const string& origModName,
|
|
|
|
|
const VTimescale& timeunit)
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_CellInline(fl)
|
2020-08-16 17:40:42 +02:00
|
|
|
, m_name{name}
|
|
|
|
|
, m_origModName{origModName}
|
|
|
|
|
, m_timeunit{timeunit} {}
|
2016-11-05 14:47:56 +01:00
|
|
|
ASTNODE_NODE_FUNCS(CellInline)
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual void dump(std::ostream& str) const override;
|
|
|
|
|
virtual const char* broken() const override {
|
2020-04-15 13:58:34 +02:00
|
|
|
BROKEN_RTN(m_scopep && !m_scopep->brokeExists());
|
2020-08-15 16:12:55 +02:00
|
|
|
return nullptr;
|
2020-04-15 13:58:34 +02:00
|
|
|
}
|
2006-08-26 13:35:28 +02:00
|
|
|
// ACCESSORS
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual string name() const override { return m_name; } // * = Cell name
|
2019-05-19 22:13:13 +02:00
|
|
|
string origModName() const { return m_origModName; } // * = modp()->origName() before inlining
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual void name(const string& name) override { m_name = name; }
|
2019-10-02 03:57:45 +02:00
|
|
|
void scopep(AstScope* scp) { m_scopep = scp; }
|
|
|
|
|
AstScope* scopep() const { return m_scopep; }
|
2020-04-16 01:39:03 +02:00
|
|
|
void timeunit(const VTimescale& flag) { m_timeunit = flag; }
|
|
|
|
|
VTimescale timeunit() const { return m_timeunit; }
|
2006-08-26 13:35:28 +02:00
|
|
|
};
|
|
|
|
|
|
2020-11-19 03:32:16 +01:00
|
|
|
class AstCellRef final : public AstNode {
|
2015-10-23 02:13:49 +02:00
|
|
|
// As-of-yet unlinkable reference into a cell
|
|
|
|
|
private:
|
2020-04-15 13:58:34 +02:00
|
|
|
string m_name; // Cell name
|
2015-10-23 02:13:49 +02:00
|
|
|
public:
|
2020-04-15 13:58:34 +02:00
|
|
|
AstCellRef(FileLine* fl, const string& name, AstNode* cellp, AstNode* exprp)
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_CellRef(fl)
|
2020-08-16 17:40:42 +02:00
|
|
|
, m_name{name} {
|
2020-04-15 13:58:34 +02:00
|
|
|
addNOp1p(cellp);
|
|
|
|
|
addNOp2p(exprp);
|
|
|
|
|
}
|
2016-11-05 14:47:56 +01:00
|
|
|
ASTNODE_NODE_FUNCS(CellRef)
|
2015-10-23 02:13:49 +02:00
|
|
|
// ACCESSORS
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual string name() const override { return m_name; } // * = Array name
|
2019-05-19 22:13:13 +02:00
|
|
|
AstNode* cellp() const { return op1p(); } // op1 = Cell
|
|
|
|
|
AstNode* exprp() const { return op2p(); } // op2 = Expression
|
2015-10-23 02:13:49 +02:00
|
|
|
};
|
|
|
|
|
|
2020-11-19 03:32:16 +01:00
|
|
|
class AstCellArrayRef final : public AstNode {
|
2015-10-23 02:13:49 +02:00
|
|
|
// As-of-yet unlinkable reference into an array of cells
|
|
|
|
|
private:
|
2020-04-15 13:58:34 +02:00
|
|
|
string m_name; // Array name
|
2015-10-23 02:13:49 +02:00
|
|
|
public:
|
2020-04-15 13:58:34 +02:00
|
|
|
AstCellArrayRef(FileLine* fl, const string& name, AstNode* selectExprp)
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_CellArrayRef(fl)
|
2020-08-16 17:40:42 +02:00
|
|
|
, m_name{name} {
|
2020-04-15 13:58:34 +02:00
|
|
|
addNOp1p(selectExprp);
|
|
|
|
|
}
|
2016-11-05 14:47:56 +01:00
|
|
|
ASTNODE_NODE_FUNCS(CellArrayRef)
|
2015-10-23 02:13:49 +02:00
|
|
|
// ACCESSORS
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual string name() const override { return m_name; } // * = Array name
|
2019-05-19 22:13:13 +02:00
|
|
|
AstNode* selp() const { return op1p(); } // op1 = Select expression
|
2015-10-23 02:13:49 +02:00
|
|
|
};
|
|
|
|
|
|
2020-11-19 03:32:16 +01:00
|
|
|
class AstUnlinkedRef final : public AstNode {
|
2015-11-12 02:40:24 +01:00
|
|
|
// As-of-yet unlinkable Ref
|
2015-10-23 02:13:49 +02:00
|
|
|
private:
|
2020-04-15 13:58:34 +02:00
|
|
|
string m_name; // Var name
|
2015-10-23 02:13:49 +02:00
|
|
|
public:
|
2020-04-15 13:58:34 +02:00
|
|
|
AstUnlinkedRef(FileLine* fl, AstNode* refp, const string& name, AstNode* crp)
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_UnlinkedRef(fl)
|
2020-08-16 17:40:42 +02:00
|
|
|
, m_name{name} {
|
2020-04-15 13:58:34 +02:00
|
|
|
addNOp1p(refp);
|
|
|
|
|
addNOp2p(crp);
|
|
|
|
|
}
|
2016-11-05 14:47:56 +01:00
|
|
|
ASTNODE_NODE_FUNCS(UnlinkedRef)
|
2015-10-23 02:13:49 +02:00
|
|
|
// ACCESSORS
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual string name() const override { return m_name; } // * = Var name
|
2019-05-19 22:13:13 +02:00
|
|
|
AstNode* refp() const { return op1p(); } // op1 = VarXRef or AstNodeFTaskRef
|
|
|
|
|
AstNode* cellrefp() const { return op2p(); } // op2 = CellArrayRef or CellRef
|
2015-10-23 02:13:49 +02:00
|
|
|
};
|
|
|
|
|
|
2020-11-19 03:32:16 +01:00
|
|
|
class AstBind final : public AstNode {
|
2013-01-15 05:19:44 +01:00
|
|
|
// Parents: MODULE
|
|
|
|
|
// Children: CELL
|
|
|
|
|
private:
|
2020-04-15 13:58:34 +02:00
|
|
|
string m_name; // Binding to name
|
2013-01-15 05:19:44 +01:00
|
|
|
public:
|
|
|
|
|
AstBind(FileLine* fl, const string& name, AstNode* cellsp)
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_Bind(fl)
|
2020-08-16 17:40:42 +02:00
|
|
|
, m_name{name} {
|
2020-12-13 04:43:55 +01:00
|
|
|
UASSERT_OBJ(VN_IS(cellsp, Cell), cellsp, "Only instances allowed to be bound");
|
2019-05-19 22:13:13 +02:00
|
|
|
addNOp1p(cellsp);
|
2013-01-15 05:19:44 +01:00
|
|
|
}
|
2016-11-05 14:47:56 +01:00
|
|
|
ASTNODE_NODE_FUNCS(Bind)
|
2013-01-15 05:19:44 +01:00
|
|
|
// ACCESSORS
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual string name() const override { return m_name; } // * = Bind Target name
|
|
|
|
|
virtual void name(const string& name) override { m_name = name; }
|
2019-05-19 22:13:13 +02:00
|
|
|
AstNode* cellsp() const { return op1p(); } // op1 = cells
|
2013-01-15 05:19:44 +01:00
|
|
|
};
|
|
|
|
|
|
2020-11-19 03:32:16 +01:00
|
|
|
class AstPort final : public AstNode {
|
2006-08-26 13:35:28 +02:00
|
|
|
// A port (in/out/inout) on a module
|
|
|
|
|
private:
|
2020-04-15 13:58:34 +02:00
|
|
|
int m_pinNum; // Pin number
|
|
|
|
|
string m_name; // Name of pin
|
2006-08-26 13:35:28 +02:00
|
|
|
public:
|
|
|
|
|
AstPort(FileLine* fl, int pinnum, const string& name)
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_Port(fl)
|
2020-08-16 17:40:42 +02:00
|
|
|
, m_pinNum{pinnum}
|
|
|
|
|
, m_name{name} {}
|
2016-11-05 14:47:56 +01:00
|
|
|
ASTNODE_NODE_FUNCS(Port)
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual string name() const override { return m_name; } // * = Port name
|
2019-05-19 22:13:13 +02:00
|
|
|
int pinNum() const { return m_pinNum; } // * = Pin number, for order based instantiation
|
|
|
|
|
AstNode* exprp() const { return op1p(); } // op1 = Expression connected to port
|
2006-08-26 13:35:28 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
//######################################################################
|
|
|
|
|
|
2020-11-19 03:32:16 +01:00
|
|
|
class AstParseRef final : public AstNode {
|
2006-12-21 22:53:51 +01:00
|
|
|
// A reference to a variable, function or task
|
|
|
|
|
// We don't know which at parse time due to bison constraints
|
|
|
|
|
// The link stages will replace this with AstVarRef, or AstTaskRef, etc.
|
|
|
|
|
// Parents: math|stmt
|
2012-07-24 12:26:35 +02:00
|
|
|
// Children: TEXT|DOT|SEL*|TASK|FUNC (or expression under sel)
|
2006-12-21 22:53:51 +01:00
|
|
|
private:
|
2019-10-05 13:54:14 +02:00
|
|
|
VParseRefExp m_expect; // Type we think it should resolve to
|
|
|
|
|
string m_name;
|
2020-04-15 13:58:34 +02:00
|
|
|
|
2006-12-21 22:53:51 +01:00
|
|
|
public:
|
2020-08-15 16:12:55 +02:00
|
|
|
AstParseRef(FileLine* fl, VParseRefExp expect, const string& name, AstNode* lhsp = nullptr,
|
|
|
|
|
AstNodeFTaskRef* ftaskrefp = nullptr)
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_ParseRef(fl)
|
2020-08-16 17:40:42 +02:00
|
|
|
, m_expect{expect}
|
|
|
|
|
, m_name{name} {
|
2020-04-15 13:58:34 +02:00
|
|
|
setNOp1p(lhsp);
|
|
|
|
|
setNOp2p(ftaskrefp);
|
|
|
|
|
}
|
2016-11-05 14:47:56 +01:00
|
|
|
ASTNODE_NODE_FUNCS(ParseRef)
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual void dump(std::ostream& str) const override;
|
|
|
|
|
virtual string name() const override { return m_name; } // * = Var name
|
|
|
|
|
virtual bool same(const AstNode* samep) const override {
|
2021-11-26 23:55:36 +01:00
|
|
|
const AstParseRef* const asamep = static_cast<const AstParseRef*>(samep);
|
2020-04-15 13:58:34 +02:00
|
|
|
return (expect() == asamep->expect() && m_name == asamep->m_name);
|
|
|
|
|
}
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual void name(const string& name) override { m_name = name; }
|
2019-10-05 13:54:14 +02:00
|
|
|
VParseRefExp expect() const { return m_expect; }
|
|
|
|
|
void expect(VParseRefExp exp) { m_expect = exp; }
|
2006-12-21 22:53:51 +01:00
|
|
|
// op1 = Components
|
2019-05-19 22:13:13 +02:00
|
|
|
AstNode* lhsp() const { return op1p(); } // op1 = List of statements
|
|
|
|
|
AstNode* ftaskrefp() const { return op2p(); } // op2 = Function/task reference
|
|
|
|
|
void ftaskrefp(AstNodeFTaskRef* nodep) { setNOp2p(nodep); } // op2 = Function/task reference
|
2012-12-31 23:05:13 +01:00
|
|
|
};
|
|
|
|
|
|
2020-11-19 03:32:16 +01:00
|
|
|
class AstClassOrPackageRef final : public AstNode {
|
2012-12-31 23:05:13 +01:00
|
|
|
private:
|
2020-07-12 00:39:01 +02:00
|
|
|
string m_name;
|
2020-12-05 22:23:20 +01:00
|
|
|
// Node not NodeModule to appease some early parser usage
|
|
|
|
|
AstNode* m_classOrPackageNodep; // Package hierarchy
|
2012-12-31 23:05:13 +01:00
|
|
|
public:
|
2020-12-05 22:23:20 +01:00
|
|
|
AstClassOrPackageRef(FileLine* fl, const string& name, AstNode* classOrPackageNodep,
|
2020-07-12 00:39:01 +02:00
|
|
|
AstNode* paramsp)
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_ClassOrPackageRef(fl)
|
2020-08-16 17:40:42 +02:00
|
|
|
, m_name{name}
|
2020-12-05 22:23:20 +01:00
|
|
|
, m_classOrPackageNodep{classOrPackageNodep} {
|
2020-07-12 00:39:01 +02:00
|
|
|
addNOp4p(paramsp);
|
|
|
|
|
}
|
2020-07-11 16:29:15 +02:00
|
|
|
ASTNODE_NODE_FUNCS(ClassOrPackageRef)
|
2012-12-31 23:05:13 +01:00
|
|
|
// METHODS
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual const char* broken() const override {
|
2020-12-05 22:23:20 +01:00
|
|
|
BROKEN_RTN(m_classOrPackageNodep && !m_classOrPackageNodep->brokeExists());
|
2020-08-15 16:12:55 +02:00
|
|
|
return nullptr;
|
2020-04-15 13:58:34 +02:00
|
|
|
}
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual void cloneRelink() override {
|
2020-12-05 22:23:20 +01:00
|
|
|
if (m_classOrPackageNodep && m_classOrPackageNodep->clonep()) {
|
|
|
|
|
m_classOrPackageNodep = m_classOrPackageNodep->clonep();
|
2020-07-11 16:29:15 +02:00
|
|
|
}
|
2020-04-15 13:58:34 +02:00
|
|
|
}
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual bool same(const AstNode* samep) const override {
|
2020-12-05 22:23:20 +01:00
|
|
|
return (m_classOrPackageNodep
|
|
|
|
|
== static_cast<const AstClassOrPackageRef*>(samep)->m_classOrPackageNodep);
|
2020-04-15 13:58:34 +02:00
|
|
|
}
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual void dump(std::ostream& str = std::cout) const override;
|
|
|
|
|
virtual string name() const override { return m_name; } // * = Var name
|
2020-12-05 22:23:20 +01:00
|
|
|
AstNode* classOrPackageNodep() const { return m_classOrPackageNodep; }
|
|
|
|
|
void classOrPackageNodep(AstNode* nodep) { m_classOrPackageNodep = nodep; }
|
2021-10-22 14:56:48 +02:00
|
|
|
AstNodeModule* classOrPackagep() const { return VN_AS(m_classOrPackageNodep, NodeModule); }
|
|
|
|
|
AstPackage* packagep() const { return VN_AS(classOrPackageNodep(), Package); }
|
2020-12-05 22:23:20 +01:00
|
|
|
void classOrPackagep(AstNodeModule* nodep) { m_classOrPackageNodep = nodep; }
|
2021-10-22 14:56:48 +02:00
|
|
|
AstPin* paramsp() const { return VN_AS(op4p(), Pin); }
|
2006-12-21 22:53:51 +01:00
|
|
|
};
|
|
|
|
|
|
2020-11-19 03:32:16 +01:00
|
|
|
class AstDot final : public AstNode {
|
2018-06-22 12:35:27 +02:00
|
|
|
// A dot separating paths in an AstVarXRef, AstFuncRef or AstTaskRef
|
2012-07-24 12:26:35 +02:00
|
|
|
// These are eliminated in the link stage
|
2021-11-26 23:55:36 +01:00
|
|
|
const bool m_colon; // Is a "::" instead of a "." (lhs must be package/class)
|
2012-07-24 12:26:35 +02:00
|
|
|
public:
|
2020-05-23 18:44:15 +02:00
|
|
|
AstDot(FileLine* fl, bool colon, AstNode* lhsp, AstNode* rhsp)
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_Dot(fl)
|
2020-08-16 17:40:42 +02:00
|
|
|
, m_colon{colon} {
|
2020-04-15 13:58:34 +02:00
|
|
|
setOp1p(lhsp);
|
|
|
|
|
setOp2p(rhsp);
|
|
|
|
|
}
|
2016-11-05 14:47:56 +01:00
|
|
|
ASTNODE_NODE_FUNCS(Dot)
|
2020-04-11 16:54:42 +02:00
|
|
|
// For parser, make only if non-null package
|
2020-07-12 00:39:01 +02:00
|
|
|
static AstNode* newIfPkg(FileLine* fl, AstNode* packageOrClassp, AstNode* rhsp) {
|
|
|
|
|
if (!packageOrClassp) return rhsp;
|
|
|
|
|
return new AstDot(fl, true, packageOrClassp, rhsp);
|
2012-12-31 23:05:13 +01:00
|
|
|
}
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual void dump(std::ostream& str) const override;
|
2006-12-21 22:53:51 +01:00
|
|
|
AstNode* lhsp() const { return op1p(); }
|
2021-12-13 02:43:15 +01:00
|
|
|
void rhsp(AstNode* nodep) { setOp2p(nodep); }
|
2006-12-21 22:53:51 +01:00
|
|
|
AstNode* rhsp() const { return op2p(); }
|
2020-05-23 18:44:15 +02:00
|
|
|
bool colon() const { return m_colon; }
|
2006-12-21 22:53:51 +01:00
|
|
|
};
|
|
|
|
|
|
2020-11-19 03:32:16 +01:00
|
|
|
class AstUnbounded final : public AstNodeMath {
|
2019-12-01 18:35:49 +01:00
|
|
|
// A $ in the parser, used for unbounded and queues
|
2020-05-08 03:09:14 +02:00
|
|
|
// Due to where is used, treated as Signed32
|
2019-12-01 18:35:49 +01:00
|
|
|
public:
|
2020-02-04 05:21:56 +01:00
|
|
|
explicit AstUnbounded(FileLine* fl)
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_Unbounded(fl) {
|
2020-05-08 03:09:14 +02:00
|
|
|
dtypeSetSigned32();
|
|
|
|
|
}
|
2019-12-01 18:35:49 +01:00
|
|
|
ASTNODE_NODE_FUNCS(Unbounded)
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual string emitVerilog() override { return "$"; }
|
|
|
|
|
virtual string emitC() override { V3ERROR_NA_RETURN(""); }
|
|
|
|
|
virtual bool cleanOut() const override { return true; }
|
2019-12-01 18:35:49 +01:00
|
|
|
};
|
|
|
|
|
|
2006-08-26 13:35:28 +02:00
|
|
|
//######################################################################
|
|
|
|
|
|
2020-11-19 03:32:16 +01:00
|
|
|
class AstTask final : public AstNodeFTask {
|
2006-08-26 13:35:28 +02:00
|
|
|
// A task inside a module
|
2014-09-12 03:28:53 +02:00
|
|
|
public:
|
2006-08-26 13:35:28 +02:00
|
|
|
AstTask(FileLine* fl, const string& name, AstNode* stmtp)
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_Task(fl, name, stmtp) {}
|
2016-11-05 14:47:56 +01:00
|
|
|
ASTNODE_NODE_FUNCS(Task)
|
2006-08-26 13:35:28 +02:00
|
|
|
};
|
|
|
|
|
|
2020-11-19 03:32:16 +01:00
|
|
|
class AstFunc final : public AstNodeFTask {
|
2006-08-26 13:35:28 +02:00
|
|
|
// A function inside a module
|
2014-09-12 03:28:53 +02:00
|
|
|
public:
|
2006-08-26 13:35:28 +02:00
|
|
|
AstFunc(FileLine* fl, const string& name, AstNode* stmtp, AstNode* fvarsp)
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_Func(fl, name, stmtp) {
|
2019-03-14 00:47:36 +01:00
|
|
|
addNOp1p(fvarsp);
|
2006-08-26 13:35:28 +02:00
|
|
|
}
|
2016-11-05 14:47:56 +01:00
|
|
|
ASTNODE_NODE_FUNCS(Func)
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual bool hasDType() const override { return true; }
|
2006-08-26 13:35:28 +02:00
|
|
|
};
|
|
|
|
|
|
2020-11-19 03:32:16 +01:00
|
|
|
class AstTaskRef final : public AstNodeFTaskRef {
|
2006-08-26 13:35:28 +02:00
|
|
|
// A reference to a task
|
2014-09-12 03:28:53 +02:00
|
|
|
public:
|
2006-12-21 22:53:51 +01:00
|
|
|
AstTaskRef(FileLine* fl, AstParseRef* namep, AstNode* pinsp)
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_TaskRef(fl, true, namep, pinsp) {
|
2020-01-18 19:02:42 +01:00
|
|
|
statement(true);
|
|
|
|
|
}
|
2009-12-04 13:05:44 +01:00
|
|
|
AstTaskRef(FileLine* fl, const string& name, AstNode* pinsp)
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_TaskRef(fl, true, name, pinsp) {}
|
2016-11-05 14:47:56 +01:00
|
|
|
ASTNODE_NODE_FUNCS(TaskRef)
|
2006-08-26 13:35:28 +02:00
|
|
|
};
|
|
|
|
|
|
2020-11-19 03:32:16 +01:00
|
|
|
class AstFuncRef final : public AstNodeFTaskRef {
|
2006-08-26 13:35:28 +02:00
|
|
|
// A reference to a function
|
2014-09-12 03:28:53 +02:00
|
|
|
public:
|
2006-12-21 22:53:51 +01:00
|
|
|
AstFuncRef(FileLine* fl, AstParseRef* namep, AstNode* pinsp)
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_FuncRef(fl, false, namep, pinsp) {}
|
2009-12-04 13:05:44 +01:00
|
|
|
AstFuncRef(FileLine* fl, const string& name, AstNode* pinsp)
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_FuncRef(fl, false, name, pinsp) {}
|
2016-11-05 14:47:56 +01:00
|
|
|
ASTNODE_NODE_FUNCS(FuncRef)
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual bool hasDType() const override { return true; }
|
2006-08-26 13:35:28 +02:00
|
|
|
};
|
|
|
|
|
|
2020-11-19 03:32:16 +01:00
|
|
|
class AstDpiExport final : public AstNode {
|
2011-11-30 04:36:51 +01:00
|
|
|
// We could put an AstNodeFTaskRef instead of the verilog function name,
|
2009-12-03 12:55:29 +01:00
|
|
|
// however we're not *calling* it, so that seems somehow wrong.
|
|
|
|
|
// (Probably AstNodeFTaskRef should be renamed AstNodeFTaskCall and have-a AstNodeFTaskRef)
|
|
|
|
|
private:
|
2020-04-15 13:58:34 +02:00
|
|
|
string m_name; // Name of function
|
|
|
|
|
string m_cname; // Name of function on c side
|
2009-12-03 12:55:29 +01:00
|
|
|
public:
|
|
|
|
|
AstDpiExport(FileLine* fl, const string& vname, const string& cname)
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_DpiExport(fl)
|
2020-08-16 17:40:42 +02:00
|
|
|
, m_name{vname}
|
|
|
|
|
, m_cname{cname} {}
|
2016-11-05 14:47:56 +01:00
|
|
|
ASTNODE_NODE_FUNCS(DpiExport)
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual string name() const override { return m_name; }
|
|
|
|
|
virtual void name(const string& name) override { m_name = name; }
|
2009-12-03 12:55:29 +01:00
|
|
|
string cname() const { return m_cname; }
|
|
|
|
|
void cname(const string& cname) { m_cname = cname; }
|
|
|
|
|
};
|
|
|
|
|
|
2020-11-19 03:32:16 +01:00
|
|
|
class AstWithParse final : public AstNodeStmt {
|
2020-10-31 14:24:16 +01:00
|
|
|
// In early parse, FUNC(index) WITH equation-using-index
|
|
|
|
|
// Replaced with AstWith
|
|
|
|
|
// Parents: math|stmt
|
|
|
|
|
// Children: funcref, math
|
2020-07-01 03:37:11 +02:00
|
|
|
public:
|
2020-10-31 14:24:16 +01:00
|
|
|
AstWithParse(FileLine* fl, bool stmt, AstNode* funcrefp, AstNode* exprp)
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_WithParse(fl) {
|
2020-07-01 03:37:11 +02:00
|
|
|
statement(stmt);
|
|
|
|
|
setOp1p(funcrefp);
|
2020-10-31 14:24:16 +01:00
|
|
|
addNOp2p(exprp);
|
2020-07-01 03:37:11 +02:00
|
|
|
}
|
2020-10-31 14:24:16 +01:00
|
|
|
ASTNODE_NODE_FUNCS(WithParse)
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual bool same(const AstNode* samep) const override { return true; }
|
2020-07-01 03:37:11 +02:00
|
|
|
//
|
|
|
|
|
AstNode* funcrefp() const { return op1p(); }
|
2020-10-31 14:24:16 +01:00
|
|
|
AstNode* exprp() const { return op2p(); }
|
2020-07-01 03:37:11 +02:00
|
|
|
};
|
|
|
|
|
|
2020-11-19 03:32:16 +01:00
|
|
|
class AstLambdaArgRef final : public AstNodeMath {
|
2020-11-01 16:56:07 +01:00
|
|
|
// Lambda argument usage
|
|
|
|
|
// These are not AstVarRefs because we need to be able to delete/clone lambdas during
|
|
|
|
|
// optimizations and AstVar's are painful to remove.
|
|
|
|
|
private:
|
|
|
|
|
string m_name; // Name of variable
|
2020-11-24 05:18:58 +01:00
|
|
|
bool m_index; // Index, not value
|
2020-11-01 16:56:07 +01:00
|
|
|
|
|
|
|
|
public:
|
2020-11-24 05:18:58 +01:00
|
|
|
AstLambdaArgRef(FileLine* fl, const string& name, bool index)
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_LambdaArgRef(fl)
|
2020-11-24 05:18:58 +01:00
|
|
|
, m_name{name}
|
|
|
|
|
, m_index(index) {}
|
2020-11-01 16:56:07 +01:00
|
|
|
ASTNODE_NODE_FUNCS(LambdaArgRef)
|
|
|
|
|
virtual bool same(const AstNode* samep) const override { return true; }
|
|
|
|
|
virtual string emitVerilog() override { return name(); }
|
|
|
|
|
virtual string emitC() override { V3ERROR_NA_RETURN(""); }
|
2020-11-01 23:17:32 +01:00
|
|
|
virtual bool cleanOut() const override { return true; }
|
2020-11-01 16:56:07 +01:00
|
|
|
virtual bool hasDType() const override { return true; }
|
|
|
|
|
virtual int instrCount() const override { return widthInstrs(); }
|
|
|
|
|
virtual string name() const override { return m_name; } // * = Var name
|
|
|
|
|
virtual void name(const string& name) override { m_name = name; }
|
2020-11-24 05:18:58 +01:00
|
|
|
bool index() const { return m_index; }
|
2020-11-01 16:56:07 +01:00
|
|
|
};
|
|
|
|
|
|
2020-11-19 03:32:16 +01:00
|
|
|
class AstWith final : public AstNodeStmt {
|
2020-10-31 15:00:55 +01:00
|
|
|
// Used as argument to method, then to AstCMethodHard
|
|
|
|
|
// dtypep() contains the with lambda's return dtype
|
|
|
|
|
// Parents: funcref (similar to AstArg)
|
2020-11-24 05:18:58 +01:00
|
|
|
// Children: LambdaArgRef that declares the item variable
|
|
|
|
|
// Children: LambdaArgRef that declares the item.index variable
|
2020-10-31 15:00:55 +01:00
|
|
|
// Children: math (equation establishing the with)
|
|
|
|
|
public:
|
2020-11-24 05:18:58 +01:00
|
|
|
AstWith(FileLine* fl, AstLambdaArgRef* indexArgRefp, AstLambdaArgRef* valueArgRefp,
|
|
|
|
|
AstNode* exprp)
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_With(fl) {
|
2020-11-24 05:18:58 +01:00
|
|
|
addOp1p(indexArgRefp);
|
|
|
|
|
addOp2p(valueArgRefp);
|
|
|
|
|
addNOp3p(exprp);
|
2020-10-31 15:00:55 +01:00
|
|
|
}
|
|
|
|
|
ASTNODE_NODE_FUNCS(With)
|
|
|
|
|
virtual bool same(const AstNode* samep) const override { return true; }
|
|
|
|
|
virtual bool hasDType() const override { return true; }
|
2020-11-01 16:56:07 +01:00
|
|
|
virtual const char* broken() const override {
|
2020-11-24 05:18:58 +01:00
|
|
|
BROKEN_RTN(!indexArgRefp()); // varp needed to know lambda's arg dtype
|
|
|
|
|
BROKEN_RTN(!valueArgRefp()); // varp needed to know lambda's arg dtype
|
2020-11-01 16:56:07 +01:00
|
|
|
return nullptr;
|
|
|
|
|
}
|
2020-10-31 15:00:55 +01:00
|
|
|
//
|
2021-10-22 14:56:48 +02:00
|
|
|
AstLambdaArgRef* indexArgRefp() const { return VN_AS(op1p(), LambdaArgRef); }
|
|
|
|
|
AstLambdaArgRef* valueArgRefp() const { return VN_AS(op2p(), LambdaArgRef); }
|
2020-11-24 05:18:58 +01:00
|
|
|
AstNode* exprp() const { return op3p(); }
|
2020-10-31 15:00:55 +01:00
|
|
|
};
|
|
|
|
|
|
2006-08-26 13:35:28 +02:00
|
|
|
//######################################################################
|
|
|
|
|
|
2020-11-19 03:32:16 +01:00
|
|
|
class AstSenItem final : public AstNode {
|
2006-08-26 13:35:28 +02:00
|
|
|
// Parents: SENTREE
|
2020-07-05 19:13:03 +02:00
|
|
|
// Children: (optional) VARREF
|
2006-08-26 13:35:28 +02:00
|
|
|
private:
|
2019-10-05 13:54:14 +02:00
|
|
|
VEdgeType m_edgeType; // Edge type
|
2006-08-26 13:35:28 +02:00
|
|
|
public:
|
2020-04-15 13:58:34 +02:00
|
|
|
class Combo {}; // for creator type-overload selection
|
2019-05-19 22:13:13 +02:00
|
|
|
class Illegal {}; // for creator type-overload selection
|
|
|
|
|
class Initial {}; // for creator type-overload selection
|
2020-04-15 13:58:34 +02:00
|
|
|
class Settle {}; // for creator type-overload selection
|
|
|
|
|
class Never {}; // for creator type-overload selection
|
2019-10-05 13:54:14 +02:00
|
|
|
AstSenItem(FileLine* fl, VEdgeType edgeType, AstNode* varrefp)
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_SenItem(fl)
|
2020-08-16 17:40:42 +02:00
|
|
|
, m_edgeType{edgeType} {
|
2019-05-19 22:13:13 +02:00
|
|
|
setOp1p(varrefp);
|
2006-08-26 13:35:28 +02:00
|
|
|
}
|
|
|
|
|
AstSenItem(FileLine* fl, Combo)
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_SenItem(fl)
|
2020-08-16 17:40:42 +02:00
|
|
|
, m_edgeType{VEdgeType::ET_COMBO} {}
|
2016-12-22 00:23:14 +01:00
|
|
|
AstSenItem(FileLine* fl, Illegal)
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_SenItem(fl)
|
2020-08-16 17:40:42 +02:00
|
|
|
, m_edgeType{VEdgeType::ET_ILLEGAL} {}
|
2006-08-26 13:35:28 +02:00
|
|
|
AstSenItem(FileLine* fl, Initial)
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_SenItem(fl)
|
2020-08-16 17:40:42 +02:00
|
|
|
, m_edgeType{VEdgeType::ET_INITIAL} {}
|
2006-08-26 13:35:28 +02:00
|
|
|
AstSenItem(FileLine* fl, Settle)
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_SenItem(fl)
|
2020-08-16 17:40:42 +02:00
|
|
|
, m_edgeType{VEdgeType::ET_SETTLE} {}
|
2006-08-26 13:35:28 +02:00
|
|
|
AstSenItem(FileLine* fl, Never)
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_SenItem(fl)
|
2020-08-16 17:40:42 +02:00
|
|
|
, m_edgeType{VEdgeType::ET_NEVER} {}
|
2016-11-05 14:47:56 +01:00
|
|
|
ASTNODE_NODE_FUNCS(SenItem)
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual void dump(std::ostream& str) const override;
|
|
|
|
|
virtual bool same(const AstNode* samep) const override {
|
2020-04-15 13:58:34 +02:00
|
|
|
return edgeType() == static_cast<const AstSenItem*>(samep)->edgeType();
|
|
|
|
|
}
|
2019-10-05 13:54:14 +02:00
|
|
|
VEdgeType edgeType() const { return m_edgeType; } // * = Posedge/negedge
|
2020-04-15 13:58:34 +02:00
|
|
|
void edgeType(VEdgeType type) {
|
|
|
|
|
m_edgeType = type;
|
|
|
|
|
editCountInc();
|
|
|
|
|
} // * = Posedge/negedge
|
2019-05-19 22:13:13 +02:00
|
|
|
AstNode* sensp() const { return op1p(); } // op1 = Signal sensitized
|
2020-04-15 13:58:34 +02:00
|
|
|
AstNodeVarRef* varrefp() const {
|
|
|
|
|
return VN_CAST(op1p(), NodeVarRef);
|
|
|
|
|
} // op1 = Signal sensitized
|
2006-08-26 13:35:28 +02:00
|
|
|
//
|
2020-07-05 19:13:03 +02:00
|
|
|
bool isClocked() const { return edgeType().clockedStmt(); }
|
|
|
|
|
bool isCombo() const { return edgeType() == VEdgeType::ET_COMBO; }
|
|
|
|
|
bool isInitial() const { return edgeType() == VEdgeType::ET_INITIAL; }
|
|
|
|
|
bool isIllegal() const { return edgeType() == VEdgeType::ET_ILLEGAL; }
|
|
|
|
|
bool isSettle() const { return edgeType() == VEdgeType::ET_SETTLE; }
|
|
|
|
|
bool isNever() const { return edgeType() == VEdgeType::ET_NEVER; }
|
2020-04-15 13:58:34 +02:00
|
|
|
bool hasVar() const { return !(isCombo() || isInitial() || isSettle() || isNever()); }
|
2006-08-26 13:35:28 +02:00
|
|
|
};
|
|
|
|
|
|
2020-11-19 03:32:16 +01:00
|
|
|
class AstSenTree final : public AstNode {
|
2006-08-26 13:35:28 +02:00
|
|
|
// A list of senitems
|
|
|
|
|
// Parents: MODULE | SBLOCK
|
|
|
|
|
// Children: SENITEM list
|
|
|
|
|
private:
|
2020-08-15 19:11:27 +02:00
|
|
|
bool m_multi = false; // Created from combo logic by ORing multiple clock domains
|
2006-08-26 13:35:28 +02:00
|
|
|
public:
|
2020-07-05 19:13:03 +02:00
|
|
|
AstSenTree(FileLine* fl, AstSenItem* sensesp)
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_SenTree(fl) {
|
2019-05-19 22:13:13 +02:00
|
|
|
addNOp1p(sensesp);
|
2006-08-26 13:35:28 +02:00
|
|
|
}
|
2016-11-05 14:47:56 +01:00
|
|
|
ASTNODE_NODE_FUNCS(SenTree)
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual void dump(std::ostream& str) const override;
|
|
|
|
|
virtual bool maybePointedTo() const override { return true; }
|
2006-08-26 13:35:28 +02:00
|
|
|
bool isMulti() const { return m_multi; }
|
2020-04-15 13:58:34 +02:00
|
|
|
// op1 = Sensitivity list
|
2021-10-22 14:56:48 +02:00
|
|
|
AstSenItem* sensesp() const { return VN_AS(op1p(), SenItem); }
|
2020-07-05 19:13:03 +02:00
|
|
|
void addSensesp(AstSenItem* nodep) { addOp1p(nodep); }
|
2006-08-26 13:35:28 +02:00
|
|
|
void multi(bool flag) { m_multi = true; }
|
|
|
|
|
// METHODS
|
2019-05-19 22:13:13 +02:00
|
|
|
bool hasClocked() const; // Includes a clocked statement
|
2020-04-15 13:58:34 +02:00
|
|
|
bool hasSettle() const; // Includes a SETTLE SenItem
|
2019-05-19 22:13:13 +02:00
|
|
|
bool hasInitial() const; // Includes a INITIAL SenItem
|
2020-04-15 13:58:34 +02:00
|
|
|
bool hasCombo() const; // Includes a COMBO SenItem
|
2006-08-26 13:35:28 +02:00
|
|
|
};
|
|
|
|
|
|
2020-11-19 03:32:16 +01:00
|
|
|
class AstFinal final : public AstNodeProcedure {
|
2020-05-06 01:12:36 +02:00
|
|
|
public:
|
|
|
|
|
AstFinal(FileLine* fl, AstNode* bodysp)
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_Final(fl, bodysp) {}
|
2020-05-06 01:12:36 +02:00
|
|
|
ASTNODE_NODE_FUNCS(Final)
|
|
|
|
|
};
|
|
|
|
|
|
2020-11-19 03:32:16 +01:00
|
|
|
class AstInitial final : public AstNodeProcedure {
|
2020-05-06 01:12:36 +02:00
|
|
|
public:
|
|
|
|
|
AstInitial(FileLine* fl, AstNode* bodysp)
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_Initial(fl, bodysp) {}
|
2020-05-06 01:12:36 +02:00
|
|
|
ASTNODE_NODE_FUNCS(Initial)
|
|
|
|
|
};
|
|
|
|
|
|
2020-11-19 03:32:16 +01:00
|
|
|
class AstAlways final : public AstNodeProcedure {
|
2021-11-26 23:55:36 +01:00
|
|
|
const VAlwaysKwd m_keyword;
|
2020-04-15 13:58:34 +02:00
|
|
|
|
2013-05-01 04:55:28 +02:00
|
|
|
public:
|
|
|
|
|
AstAlways(FileLine* fl, VAlwaysKwd keyword, AstSenTree* sensesp, AstNode* bodysp)
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_Always(fl, bodysp)
|
2020-08-16 17:40:42 +02:00
|
|
|
, m_keyword{keyword} {
|
2020-04-15 13:58:34 +02:00
|
|
|
addNOp1p(sensesp);
|
2006-08-26 13:35:28 +02:00
|
|
|
}
|
2016-11-05 14:47:56 +01:00
|
|
|
ASTNODE_NODE_FUNCS(Always)
|
2006-08-26 13:35:28 +02:00
|
|
|
//
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual void dump(std::ostream& str) const override;
|
2021-10-22 14:56:48 +02:00
|
|
|
AstSenTree* sensesp() const { return VN_AS(op1p(), SenTree); } // op1 = Sensitivity list
|
2020-06-06 21:54:44 +02:00
|
|
|
void sensesp(AstSenTree* nodep) { setOp1p(nodep); }
|
2013-05-01 04:55:28 +02:00
|
|
|
VAlwaysKwd keyword() const { return m_keyword; }
|
2006-08-26 13:35:28 +02:00
|
|
|
};
|
2021-05-15 16:56:28 +02:00
|
|
|
|
2020-11-29 17:31:38 +01:00
|
|
|
class AstAlwaysPostponed final : public AstNodeProcedure {
|
|
|
|
|
// Like always but postponement scheduling region
|
|
|
|
|
|
|
|
|
|
public:
|
|
|
|
|
AstAlwaysPostponed(FileLine* fl, AstNode* bodysp)
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_AlwaysPostponed(fl, bodysp) {}
|
2020-11-29 17:31:38 +01:00
|
|
|
ASTNODE_NODE_FUNCS(AlwaysPostponed)
|
|
|
|
|
};
|
2006-08-26 13:35:28 +02:00
|
|
|
|
2021-05-15 16:56:28 +02:00
|
|
|
class AstAlwaysPost final : public AstNodeProcedure {
|
|
|
|
|
// Like always but post assignments for memory assignment IFs
|
|
|
|
|
public:
|
|
|
|
|
AstAlwaysPost(FileLine* fl, AstSenTree* sensesp, AstNode* bodysp)
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_AlwaysPost(fl, bodysp) {
|
2021-05-15 16:56:28 +02:00
|
|
|
addNOp1p(sensesp);
|
|
|
|
|
}
|
|
|
|
|
ASTNODE_NODE_FUNCS(AlwaysPost)
|
|
|
|
|
};
|
|
|
|
|
|
2020-11-19 03:32:16 +01:00
|
|
|
class AstAlwaysPublic final : public AstNodeStmt {
|
2010-04-06 02:01:17 +02:00
|
|
|
// "Fake" sensitivity created by /*verilator public_flat_rw @(edgelist)*/
|
|
|
|
|
// Body statements are just AstVarRefs to the public signals
|
2014-09-12 03:28:53 +02:00
|
|
|
public:
|
2010-04-06 02:01:17 +02:00
|
|
|
AstAlwaysPublic(FileLine* fl, AstSenTree* sensesp, AstNode* bodysp)
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_AlwaysPublic(fl) {
|
2020-04-15 13:58:34 +02:00
|
|
|
addNOp1p(sensesp);
|
|
|
|
|
addNOp2p(bodysp);
|
2010-04-06 02:01:17 +02:00
|
|
|
}
|
2016-11-05 14:47:56 +01:00
|
|
|
ASTNODE_NODE_FUNCS(AlwaysPublic)
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual bool same(const AstNode* samep) const override { return true; }
|
2010-04-06 02:01:17 +02:00
|
|
|
//
|
2021-10-22 14:56:48 +02:00
|
|
|
AstSenTree* sensesp() const { return VN_AS(op1p(), SenTree); } // op1 = Sensitivity list
|
2019-05-19 22:13:13 +02:00
|
|
|
AstNode* bodysp() const { return op2p(); } // op2 = Statements to evaluate
|
2010-04-06 02:01:17 +02:00
|
|
|
void addStmtp(AstNode* nodep) { addOp2p(nodep); }
|
|
|
|
|
// Special accessors
|
|
|
|
|
bool isJustOneBodyStmt() const { return bodysp() && !bodysp()->nextp(); }
|
|
|
|
|
};
|
|
|
|
|
|
2020-11-19 03:32:16 +01:00
|
|
|
class AstAssign final : public AstNodeAssign {
|
2014-09-12 03:28:53 +02:00
|
|
|
public:
|
2020-01-25 21:29:44 +01:00
|
|
|
AstAssign(FileLine* fl, AstNode* lhsp, AstNode* rhsp)
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_Assign(fl, lhsp, rhsp) {
|
2019-05-19 22:13:13 +02:00
|
|
|
dtypeFrom(lhsp);
|
2006-08-26 13:35:28 +02:00
|
|
|
}
|
2016-11-05 14:47:56 +01:00
|
|
|
ASTNODE_NODE_FUNCS(Assign)
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual AstNode* cloneType(AstNode* lhsp, AstNode* rhsp) override {
|
2020-04-15 13:58:34 +02:00
|
|
|
return new AstAssign(this->fileline(), lhsp, rhsp);
|
|
|
|
|
}
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual bool brokeLhsMustBeLvalue() const override { return true; }
|
2006-08-26 13:35:28 +02:00
|
|
|
};
|
|
|
|
|
|
2020-11-19 03:32:16 +01:00
|
|
|
class AstAssignAlias final : public AstNodeAssign {
|
2006-08-26 13:35:28 +02:00
|
|
|
// Like AstAssignW, but a true bidirect interconnection alias
|
|
|
|
|
// If both sides are wires, there's no LHS vs RHS,
|
2014-09-12 03:28:53 +02:00
|
|
|
public:
|
2020-01-25 21:29:44 +01:00
|
|
|
AstAssignAlias(FileLine* fl, AstVarRef* lhsp, AstVarRef* rhsp)
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_AssignAlias(fl, lhsp, rhsp) {}
|
2016-11-05 14:47:56 +01:00
|
|
|
ASTNODE_NODE_FUNCS(AssignAlias)
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual AstNode* cloneType(AstNode* lhsp, AstNode* rhsp) override {
|
|
|
|
|
V3ERROR_NA_RETURN(nullptr);
|
|
|
|
|
}
|
|
|
|
|
virtual bool brokeLhsMustBeLvalue() const override { return false; }
|
2006-08-26 13:35:28 +02:00
|
|
|
};
|
|
|
|
|
|
2020-11-19 03:32:16 +01:00
|
|
|
class AstAssignDly final : public AstNodeAssign {
|
2014-09-12 03:28:53 +02:00
|
|
|
public:
|
2020-01-25 21:29:44 +01:00
|
|
|
AstAssignDly(FileLine* fl, AstNode* lhsp, AstNode* rhsp)
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_AssignDly(fl, lhsp, rhsp) {}
|
2016-11-05 14:47:56 +01:00
|
|
|
ASTNODE_NODE_FUNCS(AssignDly)
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual AstNode* cloneType(AstNode* lhsp, AstNode* rhsp) override {
|
2020-04-15 13:58:34 +02:00
|
|
|
return new AstAssignDly(this->fileline(), lhsp, rhsp);
|
|
|
|
|
}
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual bool isGateOptimizable() const override { return false; }
|
|
|
|
|
virtual string verilogKwd() const override { return "<="; }
|
|
|
|
|
virtual bool brokeLhsMustBeLvalue() const override { return true; }
|
2006-08-26 13:35:28 +02:00
|
|
|
};
|
|
|
|
|
|
2020-11-19 03:32:16 +01:00
|
|
|
class AstAssignW final : public AstNodeAssign {
|
2006-08-26 13:35:28 +02:00
|
|
|
// Like assign, but wire/assign's in verilog, the only setting of the specified variable
|
2014-09-12 03:28:53 +02:00
|
|
|
public:
|
2020-01-25 21:29:44 +01:00
|
|
|
AstAssignW(FileLine* fl, AstNode* lhsp, AstNode* rhsp)
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_AssignW(fl, lhsp, rhsp) {}
|
2016-11-05 14:47:56 +01:00
|
|
|
ASTNODE_NODE_FUNCS(AssignW)
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual AstNode* cloneType(AstNode* lhsp, AstNode* rhsp) override {
|
2020-04-15 13:58:34 +02:00
|
|
|
return new AstAssignW(this->fileline(), lhsp, rhsp);
|
|
|
|
|
}
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual bool brokeLhsMustBeLvalue() const override { return true; }
|
2009-10-09 02:42:45 +02:00
|
|
|
AstAlways* convertToAlways() {
|
2021-11-26 23:55:36 +01:00
|
|
|
AstNode* const lhs1p = lhsp()->unlinkFrBack();
|
|
|
|
|
AstNode* const rhs1p = rhsp()->unlinkFrBack();
|
|
|
|
|
AstAlways* const newp = new AstAlways(fileline(), VAlwaysKwd::ALWAYS, nullptr,
|
|
|
|
|
new AstAssign(fileline(), lhs1p, rhs1p));
|
2019-05-19 22:13:13 +02:00
|
|
|
replaceWith(newp); // User expected to then deleteTree();
|
|
|
|
|
return newp;
|
2009-10-09 02:42:45 +02:00
|
|
|
}
|
2006-08-26 13:35:28 +02:00
|
|
|
};
|
|
|
|
|
|
2020-11-19 03:32:16 +01:00
|
|
|
class AstAssignVarScope final : public AstNodeAssign {
|
2013-05-28 03:39:19 +02:00
|
|
|
// Assign two VarScopes to each other
|
2014-09-12 03:28:53 +02:00
|
|
|
public:
|
2020-01-25 21:29:44 +01:00
|
|
|
AstAssignVarScope(FileLine* fl, AstNode* lhsp, AstNode* rhsp)
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_AssignVarScope(fl, lhsp, rhsp) {
|
2019-05-19 22:13:13 +02:00
|
|
|
dtypeFrom(rhsp);
|
2013-05-28 03:39:19 +02:00
|
|
|
}
|
2016-11-05 14:47:56 +01:00
|
|
|
ASTNODE_NODE_FUNCS(AssignVarScope)
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual AstNode* cloneType(AstNode* lhsp, AstNode* rhsp) override {
|
2020-04-15 13:58:34 +02:00
|
|
|
return new AstAssignVarScope(this->fileline(), lhsp, rhsp);
|
|
|
|
|
}
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual bool brokeLhsMustBeLvalue() const override { return false; }
|
2013-05-28 03:39:19 +02:00
|
|
|
};
|
|
|
|
|
|
2020-11-19 03:32:16 +01:00
|
|
|
class AstPull final : public AstNode {
|
2009-01-06 17:03:57 +01:00
|
|
|
private:
|
|
|
|
|
bool m_direction;
|
2020-04-15 13:58:34 +02:00
|
|
|
|
2009-01-06 17:03:57 +01:00
|
|
|
public:
|
2020-01-25 21:29:44 +01:00
|
|
|
AstPull(FileLine* fl, AstNode* lhsp, bool direction)
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_Pull(fl) {
|
2019-05-19 22:13:13 +02:00
|
|
|
setOp1p(lhsp);
|
|
|
|
|
m_direction = direction;
|
2009-01-06 17:03:57 +01:00
|
|
|
}
|
2016-11-05 14:47:56 +01:00
|
|
|
ASTNODE_NODE_FUNCS(Pull)
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual bool same(const AstNode* samep) const override {
|
2020-04-15 13:58:34 +02:00
|
|
|
return direction() == static_cast<const AstPull*>(samep)->direction();
|
|
|
|
|
}
|
2009-01-06 17:03:57 +01:00
|
|
|
void lhsp(AstNode* np) { setOp1p(np); }
|
2019-05-19 22:13:13 +02:00
|
|
|
AstNode* lhsp() const { return op1p(); } // op1 = Assign to
|
2020-04-15 13:58:34 +02:00
|
|
|
uint32_t direction() const { return (uint32_t)m_direction; }
|
2009-01-06 17:03:57 +01:00
|
|
|
};
|
|
|
|
|
|
2020-11-19 03:32:16 +01:00
|
|
|
class AstAssignPre final : public AstNodeAssign {
|
2006-08-26 13:35:28 +02:00
|
|
|
// Like Assign, but predelayed assignment requiring special order handling
|
2014-09-12 03:28:53 +02:00
|
|
|
public:
|
2020-01-25 21:29:44 +01:00
|
|
|
AstAssignPre(FileLine* fl, AstNode* lhsp, AstNode* rhsp)
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_AssignPre(fl, lhsp, rhsp) {}
|
2016-11-05 14:47:56 +01:00
|
|
|
ASTNODE_NODE_FUNCS(AssignPre)
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual AstNode* cloneType(AstNode* lhsp, AstNode* rhsp) override {
|
2020-04-15 13:58:34 +02:00
|
|
|
return new AstAssignPre(this->fileline(), lhsp, rhsp);
|
|
|
|
|
}
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual bool brokeLhsMustBeLvalue() const override { return true; }
|
2006-08-26 13:35:28 +02:00
|
|
|
};
|
|
|
|
|
|
2020-11-19 03:32:16 +01:00
|
|
|
class AstAssignPost final : public AstNodeAssign {
|
2006-08-26 13:35:28 +02:00
|
|
|
// Like Assign, but predelayed assignment requiring special order handling
|
2014-09-12 03:28:53 +02:00
|
|
|
public:
|
2020-01-25 21:29:44 +01:00
|
|
|
AstAssignPost(FileLine* fl, AstNode* lhsp, AstNode* rhsp)
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_AssignPost(fl, lhsp, rhsp) {}
|
2016-11-05 14:47:56 +01:00
|
|
|
ASTNODE_NODE_FUNCS(AssignPost)
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual AstNode* cloneType(AstNode* lhsp, AstNode* rhsp) override {
|
2020-04-15 13:58:34 +02:00
|
|
|
return new AstAssignPost(this->fileline(), lhsp, rhsp);
|
|
|
|
|
}
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual bool brokeLhsMustBeLvalue() const override { return true; }
|
2006-08-26 13:35:28 +02:00
|
|
|
};
|
|
|
|
|
|
2021-08-12 22:43:32 +02:00
|
|
|
class AstDpiExportUpdated final : public AstNodeStmt {
|
|
|
|
|
// Denotes that the referenced variable may have been updated via a DPI Export
|
|
|
|
|
public:
|
|
|
|
|
AstDpiExportUpdated(FileLine* fl, AstVarScope* varScopep)
|
|
|
|
|
: ASTGEN_SUPER_DpiExportUpdated(fl) {
|
|
|
|
|
addOp1p(new AstVarRef{fl, varScopep, VAccess::WRITE});
|
|
|
|
|
}
|
|
|
|
|
ASTNODE_NODE_FUNCS(DpiExportUpdated)
|
2021-10-22 14:56:48 +02:00
|
|
|
AstVarScope* varScopep() const { return VN_AS(op1p(), VarRef)->varScopep(); }
|
2021-08-12 22:43:32 +02:00
|
|
|
};
|
|
|
|
|
|
2020-12-06 04:58:36 +01:00
|
|
|
class AstExprStmt final : public AstNodeMath {
|
|
|
|
|
// Perform a statement, often assignment inside an expression/math node,
|
|
|
|
|
// the parent gets passed the 'resultp()'.
|
|
|
|
|
// resultp is evaluated AFTER the statement(s).
|
|
|
|
|
public:
|
|
|
|
|
AstExprStmt(FileLine* fl, AstNode* stmtsp, AstNode* resultp)
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_ExprStmt(fl) {
|
2020-12-06 04:58:36 +01:00
|
|
|
addOp1p(stmtsp);
|
|
|
|
|
setOp2p(resultp); // Possibly in future nullptr could mean return rhsp()
|
|
|
|
|
dtypeFrom(resultp);
|
|
|
|
|
}
|
|
|
|
|
ASTNODE_NODE_FUNCS(ExprStmt)
|
|
|
|
|
// ACCESSORS
|
|
|
|
|
AstNode* stmtsp() const { return op1p(); }
|
|
|
|
|
void addStmtsp(AstNode* nodep) { addOp1p(nodep); }
|
|
|
|
|
AstNode* resultp() const { return op2p(); }
|
|
|
|
|
// METHODS
|
|
|
|
|
virtual string emitVerilog() override { V3ERROR_NA_RETURN(""); }
|
|
|
|
|
virtual string emitC() override { V3ERROR_NA_RETURN(""); }
|
|
|
|
|
virtual bool cleanOut() const override { return false; }
|
|
|
|
|
virtual bool same(const AstNode*) const override { return true; }
|
|
|
|
|
};
|
|
|
|
|
|
2020-11-19 03:32:16 +01:00
|
|
|
class AstComment final : public AstNodeStmt {
|
2006-08-26 13:35:28 +02:00
|
|
|
// Some comment to put into the output stream
|
|
|
|
|
// Parents: {statement list}
|
|
|
|
|
// Children: none
|
|
|
|
|
private:
|
2021-11-26 23:55:36 +01:00
|
|
|
const bool m_showAt; // Show "at <fileline>"
|
|
|
|
|
const string m_name; // Text of comment
|
2006-08-26 13:35:28 +02:00
|
|
|
public:
|
2020-04-15 13:58:34 +02:00
|
|
|
AstComment(FileLine* fl, const string& name, bool showAt = false)
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_Comment(fl)
|
2020-08-16 17:40:42 +02:00
|
|
|
, m_showAt{showAt}
|
|
|
|
|
, m_name{name} {}
|
2016-11-05 14:47:56 +01:00
|
|
|
ASTNODE_NODE_FUNCS(Comment)
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual string name() const override { return m_name; } // * = Text
|
|
|
|
|
virtual bool same(const AstNode* samep) const override {
|
|
|
|
|
return true;
|
|
|
|
|
} // Ignore name in comments
|
2019-09-24 00:44:45 +02:00
|
|
|
virtual bool showAt() const { return m_showAt; }
|
2006-08-26 13:35:28 +02:00
|
|
|
};
|
|
|
|
|
|
2020-11-19 03:32:16 +01:00
|
|
|
class AstCond final : public AstNodeCond {
|
2006-08-26 13:35:28 +02:00
|
|
|
// Conditional ?: statement
|
|
|
|
|
// Parents: MATH
|
|
|
|
|
// Children: MATH
|
2014-09-12 03:28:53 +02:00
|
|
|
public:
|
2006-08-26 13:35:28 +02:00
|
|
|
AstCond(FileLine* fl, AstNode* condp, AstNode* expr1p, AstNode* expr2p)
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_Cond(fl, condp, expr1p, expr2p) {}
|
2016-11-05 14:47:56 +01:00
|
|
|
ASTNODE_NODE_FUNCS(Cond)
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual AstNode* cloneType(AstNode* condp, AstNode* expr1p, AstNode* expr2p) override {
|
2020-04-15 13:58:34 +02:00
|
|
|
return new AstCond(this->fileline(), condp, expr1p, expr2p);
|
|
|
|
|
}
|
2006-08-26 13:35:28 +02:00
|
|
|
};
|
|
|
|
|
|
2020-11-19 03:32:16 +01:00
|
|
|
class AstCondBound final : public AstNodeCond {
|
2019-05-12 00:42:27 +02:00
|
|
|
// Conditional ?: statement, specially made for safety checking of array bounds
|
2006-08-26 13:35:28 +02:00
|
|
|
// Parents: MATH
|
|
|
|
|
// Children: MATH
|
2014-09-12 03:28:53 +02:00
|
|
|
public:
|
2006-08-26 13:35:28 +02:00
|
|
|
AstCondBound(FileLine* fl, AstNode* condp, AstNode* expr1p, AstNode* expr2p)
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_CondBound(fl, condp, expr1p, expr2p) {}
|
2016-11-05 14:47:56 +01:00
|
|
|
ASTNODE_NODE_FUNCS(CondBound)
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual AstNode* cloneType(AstNode* condp, AstNode* expr1p, AstNode* expr2p) override {
|
2020-04-15 13:58:34 +02:00
|
|
|
return new AstCondBound(this->fileline(), condp, expr1p, expr2p);
|
|
|
|
|
}
|
2006-08-26 13:35:28 +02:00
|
|
|
};
|
|
|
|
|
|
2020-11-19 03:32:16 +01:00
|
|
|
class AstCoverDecl final : public AstNodeStmt {
|
2006-08-26 13:35:28 +02:00
|
|
|
// Coverage analysis point declaration
|
|
|
|
|
// Parents: {statement list}
|
|
|
|
|
// Children: none
|
|
|
|
|
private:
|
2020-04-15 13:58:34 +02:00
|
|
|
AstCoverDecl* m_dataDeclp; // [After V3CoverageJoin] Pointer to duplicate declaration to get
|
|
|
|
|
// data from instead
|
|
|
|
|
string m_page;
|
|
|
|
|
string m_text;
|
|
|
|
|
string m_hier;
|
2020-05-31 21:52:17 +02:00
|
|
|
string m_linescov;
|
|
|
|
|
int m_offset; // Offset column numbers to uniq-ify IFs
|
2020-04-15 13:58:34 +02:00
|
|
|
int m_binNum; // Set by V3EmitCSyms to tell final V3Emit what to increment
|
2006-08-26 13:35:28 +02:00
|
|
|
public:
|
2020-05-31 21:52:17 +02:00
|
|
|
AstCoverDecl(FileLine* fl, const string& page, const string& comment, const string& linescov,
|
|
|
|
|
int offset)
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_CoverDecl(fl) {
|
2020-04-15 13:58:34 +02:00
|
|
|
m_page = page;
|
2020-05-31 15:05:02 +02:00
|
|
|
m_text = comment;
|
2020-05-31 21:52:17 +02:00
|
|
|
m_linescov = linescov;
|
|
|
|
|
m_offset = offset;
|
2019-05-19 22:13:13 +02:00
|
|
|
m_binNum = 0;
|
2020-08-15 16:12:55 +02:00
|
|
|
m_dataDeclp = nullptr;
|
2006-08-26 13:35:28 +02:00
|
|
|
}
|
2016-11-05 14:47:56 +01:00
|
|
|
ASTNODE_NODE_FUNCS(CoverDecl)
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual const char* broken() const override {
|
2019-05-19 22:13:13 +02:00
|
|
|
BROKEN_RTN(m_dataDeclp && !m_dataDeclp->brokeExists());
|
2018-03-10 22:32:04 +01:00
|
|
|
if (m_dataDeclp && m_dataDeclp->m_dataDeclp) { // Avoid O(n^2) accessing
|
|
|
|
|
v3fatalSrc("dataDeclp should point to real data, not be a list");
|
|
|
|
|
}
|
2020-08-15 16:12:55 +02:00
|
|
|
return nullptr;
|
2020-04-15 13:58:34 +02:00
|
|
|
}
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual void cloneRelink() override {
|
2020-04-15 13:58:34 +02:00
|
|
|
if (m_dataDeclp && m_dataDeclp->clonep()) m_dataDeclp = m_dataDeclp->clonep();
|
|
|
|
|
}
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual void dump(std::ostream& str) const override;
|
2021-07-25 14:32:36 +02:00
|
|
|
virtual int instrCount() const override { return 1 + 2 * INSTR_COUNT_LD; }
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual bool maybePointedTo() const override { return true; }
|
2019-05-19 22:13:13 +02:00
|
|
|
void binNum(int flag) { m_binNum = flag; }
|
|
|
|
|
int binNum() const { return m_binNum; }
|
2020-05-31 21:52:17 +02:00
|
|
|
int offset() const { return m_offset; }
|
2019-05-19 22:13:13 +02:00
|
|
|
const string& comment() const { return m_text; } // text to insert in code
|
2020-05-31 21:52:17 +02:00
|
|
|
const string& linescov() const { return m_linescov; }
|
2008-12-12 22:04:56 +01:00
|
|
|
const string& page() const { return m_page; }
|
2006-08-26 13:35:28 +02:00
|
|
|
const string& hier() const { return m_hier; }
|
2019-05-19 22:13:13 +02:00
|
|
|
void hier(const string& flag) { m_hier = flag; }
|
|
|
|
|
void comment(const string& flag) { m_text = flag; }
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual bool same(const AstNode* samep) const override {
|
2021-11-26 23:55:36 +01:00
|
|
|
const AstCoverDecl* const asamep = static_cast<const AstCoverDecl*>(samep);
|
2020-05-31 21:52:17 +02:00
|
|
|
return (fileline() == asamep->fileline() && linescov() == asamep->linescov()
|
|
|
|
|
&& hier() == asamep->hier() && comment() == asamep->comment());
|
2020-04-15 13:58:34 +02:00
|
|
|
}
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual bool isPredictOptimizable() const override { return false; }
|
2019-05-19 22:13:13 +02:00
|
|
|
void dataDeclp(AstCoverDecl* nodep) { m_dataDeclp = nodep; }
|
2020-08-15 16:12:55 +02:00
|
|
|
// dataDecl nullptr means "use this one", but often you want "this" to
|
2019-05-19 22:13:13 +02:00
|
|
|
// indicate to get data from here
|
|
|
|
|
AstCoverDecl* dataDeclNullp() const { return m_dataDeclp; }
|
2020-04-15 13:58:34 +02:00
|
|
|
AstCoverDecl* dataDeclThisp() { return dataDeclNullp() ? dataDeclNullp() : this; }
|
2006-08-26 13:35:28 +02:00
|
|
|
};
|
|
|
|
|
|
2020-11-19 03:32:16 +01:00
|
|
|
class AstCoverInc final : public AstNodeStmt {
|
2006-08-26 13:35:28 +02:00
|
|
|
// Coverage analysis point; increment coverage count
|
|
|
|
|
// Parents: {statement list}
|
|
|
|
|
// Children: none
|
|
|
|
|
private:
|
2019-05-19 22:13:13 +02:00
|
|
|
AstCoverDecl* m_declp; // [After V3Coverage] Pointer to declaration
|
2006-08-26 13:35:28 +02:00
|
|
|
public:
|
|
|
|
|
AstCoverInc(FileLine* fl, AstCoverDecl* declp)
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_CoverInc(fl)
|
2020-08-16 17:40:42 +02:00
|
|
|
, m_declp{declp} {}
|
2016-11-05 14:47:56 +01:00
|
|
|
ASTNODE_NODE_FUNCS(CoverInc)
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual const char* broken() const override {
|
2020-04-15 13:58:34 +02:00
|
|
|
BROKEN_RTN(!declp()->brokeExists());
|
2020-08-15 16:12:55 +02:00
|
|
|
return nullptr;
|
2020-04-15 13:58:34 +02:00
|
|
|
}
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual void cloneRelink() override {
|
2020-04-15 13:58:34 +02:00
|
|
|
if (m_declp->clonep()) m_declp = m_declp->clonep();
|
|
|
|
|
}
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual void dump(std::ostream& str) const override;
|
2021-07-25 14:32:36 +02:00
|
|
|
virtual int instrCount() const override { return 1 + 2 * INSTR_COUNT_LD; }
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual bool same(const AstNode* samep) const override {
|
2020-04-15 13:58:34 +02:00
|
|
|
return declp() == static_cast<const AstCoverInc*>(samep)->declp();
|
|
|
|
|
}
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual bool isGateOptimizable() const override { return false; }
|
|
|
|
|
virtual bool isPredictOptimizable() const override { return false; }
|
|
|
|
|
virtual bool isOutputter() const override { return true; }
|
2011-12-16 01:13:54 +01:00
|
|
|
// but isPure() true
|
2019-05-19 22:13:13 +02:00
|
|
|
AstCoverDecl* declp() const { return m_declp; } // Where defined
|
2006-08-26 13:35:28 +02:00
|
|
|
};
|
|
|
|
|
|
2020-11-19 03:32:16 +01:00
|
|
|
class AstCoverToggle final : public AstNodeStmt {
|
2008-12-12 21:34:02 +01:00
|
|
|
// Toggle analysis of given signal
|
|
|
|
|
// Parents: MODULE
|
|
|
|
|
// Children: AstCoverInc, orig var, change det var
|
2014-09-12 03:28:53 +02:00
|
|
|
public:
|
2008-12-12 21:34:02 +01:00
|
|
|
AstCoverToggle(FileLine* fl, AstCoverInc* incp, AstNode* origp, AstNode* changep)
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_CoverToggle(fl) {
|
2019-05-19 22:13:13 +02:00
|
|
|
setOp1p(incp);
|
|
|
|
|
setOp2p(origp);
|
|
|
|
|
setOp3p(changep);
|
2008-12-12 21:34:02 +01:00
|
|
|
}
|
2016-11-05 14:47:56 +01:00
|
|
|
ASTNODE_NODE_FUNCS(CoverToggle)
|
2021-07-25 14:32:36 +02:00
|
|
|
virtual int instrCount() const override { return 3 + INSTR_COUNT_BRANCH + INSTR_COUNT_LD; }
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual bool same(const AstNode* samep) const override { return true; }
|
|
|
|
|
virtual bool isGateOptimizable() const override { return false; }
|
|
|
|
|
virtual bool isPredictOptimizable() const override { return true; }
|
|
|
|
|
virtual bool isOutputter() const override {
|
2020-04-15 13:58:34 +02:00
|
|
|
return false; // Though the AstCoverInc under this is an outputter
|
|
|
|
|
}
|
2011-12-16 01:13:54 +01:00
|
|
|
// but isPure() true
|
2021-10-22 14:56:48 +02:00
|
|
|
AstCoverInc* incp() const { return VN_AS(op1p(), CoverInc); }
|
2019-05-19 22:13:13 +02:00
|
|
|
void incp(AstCoverInc* nodep) { setOp1p(nodep); }
|
2008-12-12 21:34:02 +01:00
|
|
|
AstNode* origp() const { return op2p(); }
|
|
|
|
|
AstNode* changep() const { return op3p(); }
|
|
|
|
|
};
|
|
|
|
|
|
2020-11-19 03:32:16 +01:00
|
|
|
class AstDelay final : public AstNodeStmt {
|
2020-04-23 03:31:40 +02:00
|
|
|
// Delay statement
|
|
|
|
|
public:
|
|
|
|
|
AstDelay(FileLine* fl, AstNode* lhsp)
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_Delay(fl) {
|
2020-04-23 03:31:40 +02:00
|
|
|
setOp1p(lhsp);
|
|
|
|
|
}
|
|
|
|
|
ASTNODE_NODE_FUNCS(Delay)
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual bool same(const AstNode* samep) const override { return true; }
|
2020-04-23 03:31:40 +02:00
|
|
|
//
|
|
|
|
|
AstNode* lhsp() const { return op1p(); } // op2 = Statements to evaluate
|
|
|
|
|
void lhsp(AstNode* nodep) { setOp1p(nodep); }
|
|
|
|
|
};
|
|
|
|
|
|
2020-11-19 03:32:16 +01:00
|
|
|
class AstGenCase final : public AstNodeCase {
|
2006-08-26 13:35:28 +02:00
|
|
|
// Generate Case statement
|
|
|
|
|
// Parents: {statement list}
|
|
|
|
|
// exprp Children: MATHs
|
|
|
|
|
// casesp Children: CASEITEMs
|
2014-09-12 03:28:53 +02:00
|
|
|
public:
|
2020-01-25 21:29:44 +01:00
|
|
|
AstGenCase(FileLine* fl, AstNode* exprp, AstNode* casesp)
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_GenCase(fl, exprp, casesp) {}
|
2016-11-05 14:47:56 +01:00
|
|
|
ASTNODE_NODE_FUNCS(GenCase)
|
2006-08-26 13:35:28 +02:00
|
|
|
};
|
|
|
|
|
|
2020-11-19 03:32:16 +01:00
|
|
|
class AstCase final : public AstNodeCase {
|
2006-08-26 13:35:28 +02:00
|
|
|
// Case statement
|
|
|
|
|
// Parents: {statement list}
|
|
|
|
|
// exprp Children: MATHs
|
|
|
|
|
// casesp Children: CASEITEMs
|
|
|
|
|
private:
|
2020-04-15 13:58:34 +02:00
|
|
|
VCaseType m_casex; // 0=case, 1=casex, 2=casez
|
2020-08-16 17:40:42 +02:00
|
|
|
bool m_fullPragma = false; // Synthesis full_case
|
|
|
|
|
bool m_parallelPragma = false; // Synthesis parallel_case
|
|
|
|
|
bool m_uniquePragma = false; // unique case
|
|
|
|
|
bool m_unique0Pragma = false; // unique0 case
|
|
|
|
|
bool m_priorityPragma = false; // priority case
|
2006-08-26 13:35:28 +02:00
|
|
|
public:
|
2020-01-25 21:29:44 +01:00
|
|
|
AstCase(FileLine* fl, VCaseType casex, AstNode* exprp, AstNode* casesp)
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_Case(fl, exprp, casesp)
|
2020-08-16 17:40:42 +02:00
|
|
|
, m_casex{casex} {}
|
2016-11-05 14:47:56 +01:00
|
|
|
ASTNODE_NODE_FUNCS(Case)
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual string verilogKwd() const override {
|
|
|
|
|
return casez() ? "casez" : casex() ? "casex" : "case";
|
|
|
|
|
}
|
|
|
|
|
virtual bool same(const AstNode* samep) const override {
|
2020-04-15 13:58:34 +02:00
|
|
|
return m_casex == static_cast<const AstCase*>(samep)->m_casex;
|
|
|
|
|
}
|
|
|
|
|
bool casex() const { return m_casex == VCaseType::CT_CASEX; }
|
|
|
|
|
bool casez() const { return m_casex == VCaseType::CT_CASEZ; }
|
|
|
|
|
bool caseInside() const { return m_casex == VCaseType::CT_CASEINSIDE; }
|
|
|
|
|
bool caseSimple() const { return m_casex == VCaseType::CT_CASE; }
|
2019-05-19 22:13:13 +02:00
|
|
|
void caseInsideSet() { m_casex = VCaseType::CT_CASEINSIDE; }
|
|
|
|
|
bool fullPragma() const { return m_fullPragma; }
|
|
|
|
|
void fullPragma(bool flag) { m_fullPragma = flag; }
|
|
|
|
|
bool parallelPragma() const { return m_parallelPragma; }
|
|
|
|
|
void parallelPragma(bool flag) { m_parallelPragma = flag; }
|
|
|
|
|
bool uniquePragma() const { return m_uniquePragma; }
|
|
|
|
|
void uniquePragma(bool flag) { m_uniquePragma = flag; }
|
|
|
|
|
bool unique0Pragma() const { return m_unique0Pragma; }
|
|
|
|
|
void unique0Pragma(bool flag) { m_unique0Pragma = flag; }
|
|
|
|
|
bool priorityPragma() const { return m_priorityPragma; }
|
|
|
|
|
void priorityPragma(bool flag) { m_priorityPragma = flag; }
|
2006-08-26 13:35:28 +02:00
|
|
|
};
|
|
|
|
|
|
2020-11-19 03:32:16 +01:00
|
|
|
class AstCaseItem final : public AstNode {
|
2006-08-26 13:35:28 +02:00
|
|
|
// Single item of a case statement
|
|
|
|
|
// Parents: CASE
|
|
|
|
|
// condsp Children: MATH (Null condition used for default block)
|
|
|
|
|
// bodysp Children: Statements
|
|
|
|
|
public:
|
2020-01-25 21:29:44 +01:00
|
|
|
AstCaseItem(FileLine* fl, AstNode* condsp, AstNode* bodysp)
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_CaseItem(fl) {
|
2020-04-15 13:58:34 +02:00
|
|
|
addNOp1p(condsp);
|
|
|
|
|
addNOp2p(bodysp);
|
2006-08-26 13:35:28 +02:00
|
|
|
}
|
2016-11-05 14:47:56 +01:00
|
|
|
ASTNODE_NODE_FUNCS(CaseItem)
|
2021-07-25 14:32:36 +02:00
|
|
|
virtual int instrCount() const override { return widthInstrs() + INSTR_COUNT_BRANCH; }
|
2019-05-19 22:13:13 +02:00
|
|
|
AstNode* condsp() const { return op1p(); } // op1 = list of possible matching expressions
|
|
|
|
|
AstNode* bodysp() const { return op2p(); } // op2 = what to do
|
|
|
|
|
void condsp(AstNode* nodep) { setOp1p(nodep); }
|
|
|
|
|
void addBodysp(AstNode* newp) { addOp2p(newp); }
|
2020-08-15 16:12:55 +02:00
|
|
|
bool isDefault() const { return condsp() == nullptr; }
|
2006-08-26 13:35:28 +02:00
|
|
|
};
|
|
|
|
|
|
2020-11-19 03:32:16 +01:00
|
|
|
class AstSFormatF final : public AstNode {
|
2011-11-30 04:36:51 +01:00
|
|
|
// Convert format to string, generally under an AstDisplay or AstSFormat
|
2010-01-18 02:06:08 +01:00
|
|
|
// Also used as "real" function for /*verilator sformat*/ functions
|
2020-03-06 03:49:25 +01:00
|
|
|
string m_text;
|
2021-11-26 23:55:36 +01:00
|
|
|
const bool m_hidden; // Under display, etc
|
2020-03-06 03:49:25 +01:00
|
|
|
bool m_hasFormat; // Has format code
|
2021-11-26 23:55:36 +01:00
|
|
|
const char m_missingArgChar; // Format code when argument without format, 'h'/'o'/'b'
|
2020-04-16 01:39:03 +02:00
|
|
|
VTimescale m_timeunit; // Parent module time unit
|
2010-01-17 21:53:12 +01:00
|
|
|
public:
|
2017-01-10 01:19:21 +01:00
|
|
|
class NoFormat {};
|
2020-03-06 03:49:25 +01:00
|
|
|
AstSFormatF(FileLine* fl, const string& text, bool hidden, AstNode* exprsp,
|
|
|
|
|
char missingArgChar = 'd')
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_SFormatF(fl)
|
2020-08-16 17:40:42 +02:00
|
|
|
, m_text{text}
|
|
|
|
|
, m_hidden{hidden}
|
|
|
|
|
, m_hasFormat{true}
|
|
|
|
|
, m_missingArgChar{missingArgChar} {
|
2019-05-19 22:13:13 +02:00
|
|
|
dtypeSetString();
|
2020-04-15 13:58:34 +02:00
|
|
|
addNOp1p(exprsp);
|
2020-08-15 16:12:55 +02:00
|
|
|
addNOp2p(nullptr);
|
2020-04-15 13:58:34 +02:00
|
|
|
}
|
2020-06-10 01:40:49 +02:00
|
|
|
AstSFormatF(FileLine* fl, NoFormat, AstNode* exprsp, char missingArgChar = 'd',
|
|
|
|
|
bool hidden = true)
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_SFormatF(fl)
|
2020-08-16 17:40:42 +02:00
|
|
|
, m_text{""}
|
|
|
|
|
, m_hidden{hidden}
|
|
|
|
|
, m_hasFormat{false}
|
|
|
|
|
, m_missingArgChar{missingArgChar} {
|
2019-05-19 22:13:13 +02:00
|
|
|
dtypeSetString();
|
2020-04-15 13:58:34 +02:00
|
|
|
addNOp1p(exprsp);
|
2020-08-15 16:12:55 +02:00
|
|
|
addNOp2p(nullptr);
|
2020-04-15 13:58:34 +02:00
|
|
|
}
|
2016-11-05 14:47:56 +01:00
|
|
|
ASTNODE_NODE_FUNCS(SFormatF)
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual string name() const override { return m_text; }
|
2021-07-25 14:32:36 +02:00
|
|
|
virtual int instrCount() const override { return INSTR_COUNT_PLI; }
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual bool hasDType() const override { return true; }
|
|
|
|
|
virtual bool same(const AstNode* samep) const override {
|
2020-04-15 13:58:34 +02:00
|
|
|
return text() == static_cast<const AstSFormatF*>(samep)->text();
|
|
|
|
|
}
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual string verilogKwd() const override { return "$sformatf"; }
|
2017-10-21 19:50:31 +02:00
|
|
|
void addExprsp(AstNode* nodep) { addOp1p(nodep); } // op1 = Expressions to output
|
2019-05-19 22:13:13 +02:00
|
|
|
AstNode* exprsp() const { return op1p(); } // op1 = Expressions to output
|
|
|
|
|
string text() const { return m_text; } // * = Text to display
|
|
|
|
|
void text(const string& text) { m_text = text; }
|
2021-10-22 14:56:48 +02:00
|
|
|
AstScopeName* scopeNamep() const { return VN_AS(op2p(), ScopeName); }
|
2010-01-17 21:53:12 +01:00
|
|
|
void scopeNamep(AstNode* nodep) { setNOp2p(nodep); }
|
|
|
|
|
bool formatScopeTracking() const { // Track scopeNamep(); Ok if false positive
|
2020-04-15 13:58:34 +02:00
|
|
|
return (name().find("%m") != string::npos || name().find("%M") != string::npos);
|
|
|
|
|
}
|
2010-01-18 02:06:08 +01:00
|
|
|
bool hidden() const { return m_hidden; }
|
2019-05-19 22:13:13 +02:00
|
|
|
void hasFormat(bool flag) { m_hasFormat = flag; }
|
2017-01-10 01:19:21 +01:00
|
|
|
bool hasFormat() const { return m_hasFormat; }
|
2020-03-06 03:49:25 +01:00
|
|
|
char missingArgChar() const { return m_missingArgChar; }
|
2020-04-16 01:39:03 +02:00
|
|
|
void timeunit(const VTimescale& flag) { m_timeunit = flag; }
|
|
|
|
|
VTimescale timeunit() const { return m_timeunit; }
|
2010-01-17 21:53:12 +01:00
|
|
|
};
|
|
|
|
|
|
2020-11-19 03:32:16 +01:00
|
|
|
class AstDisplay final : public AstNodeStmt {
|
2006-12-21 22:53:51 +01:00
|
|
|
// Parents: stmtlist
|
2010-01-17 21:53:12 +01:00
|
|
|
// Children: file which must be a varref
|
|
|
|
|
// Children: SFORMATF to generate print string
|
2006-08-26 13:35:28 +02:00
|
|
|
private:
|
2020-03-06 03:49:25 +01:00
|
|
|
AstDisplayType m_displayType;
|
2020-04-15 13:58:34 +02:00
|
|
|
|
2006-08-26 13:35:28 +02:00
|
|
|
public:
|
2020-01-25 21:29:44 +01:00
|
|
|
AstDisplay(FileLine* fl, AstDisplayType dispType, const string& text, AstNode* filep,
|
2020-03-06 03:49:25 +01:00
|
|
|
AstNode* exprsp, char missingArgChar = 'd')
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_Display(fl) {
|
2020-03-06 03:49:25 +01:00
|
|
|
setOp1p(new AstSFormatF(fl, text, true, exprsp, missingArgChar));
|
2019-05-19 22:13:13 +02:00
|
|
|
setNOp3p(filep);
|
|
|
|
|
m_displayType = dispType;
|
2006-08-26 13:35:28 +02:00
|
|
|
}
|
2020-03-06 03:49:25 +01:00
|
|
|
AstDisplay(FileLine* fl, AstDisplayType dispType, AstNode* filep, AstNode* exprsp,
|
|
|
|
|
char missingArgChar = 'd')
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_Display(fl) {
|
2020-03-06 03:49:25 +01:00
|
|
|
setOp1p(new AstSFormatF(fl, AstSFormatF::NoFormat(), exprsp, missingArgChar));
|
2019-05-19 22:13:13 +02:00
|
|
|
setNOp3p(filep);
|
|
|
|
|
m_displayType = dispType;
|
2017-01-10 01:19:21 +01:00
|
|
|
}
|
2016-11-05 14:47:56 +01:00
|
|
|
ASTNODE_NODE_FUNCS(Display)
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual void dump(std::ostream& str) const override;
|
|
|
|
|
virtual const char* broken() const override {
|
2020-04-15 13:58:34 +02:00
|
|
|
BROKEN_RTN(!fmtp());
|
2020-08-15 16:12:55 +02:00
|
|
|
return nullptr;
|
2020-04-15 13:58:34 +02:00
|
|
|
}
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual string verilogKwd() const override {
|
2020-04-15 13:58:34 +02:00
|
|
|
return (filep() ? string("$f") + string(displayType().ascii())
|
|
|
|
|
: string("$") + string(displayType().ascii()));
|
|
|
|
|
}
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual bool isGateOptimizable() const override { return false; }
|
|
|
|
|
virtual bool isPredictOptimizable() const override { return false; }
|
|
|
|
|
virtual bool isPure() const override {
|
|
|
|
|
return false;
|
|
|
|
|
} // SPECIAL: $display has 'visual' ordering
|
|
|
|
|
virtual bool isOutputter() const override { return true; } // SPECIAL: $display makes output
|
|
|
|
|
virtual bool isUnlikely() const override { return true; }
|
|
|
|
|
virtual bool same(const AstNode* samep) const override {
|
2020-04-15 13:58:34 +02:00
|
|
|
return displayType() == static_cast<const AstDisplay*>(samep)->displayType();
|
|
|
|
|
}
|
2021-07-25 14:32:36 +02:00
|
|
|
virtual int instrCount() const override { return INSTR_COUNT_PLI; }
|
2019-05-19 22:13:13 +02:00
|
|
|
AstDisplayType displayType() const { return m_displayType; }
|
|
|
|
|
void displayType(AstDisplayType type) { m_displayType = type; }
|
2020-04-15 13:58:34 +02:00
|
|
|
// * = Add a newline for $display
|
|
|
|
|
bool addNewline() const { return displayType().addNewline(); }
|
2019-05-19 22:13:13 +02:00
|
|
|
void fmtp(AstSFormatF* nodep) { addOp1p(nodep); } // op1 = To-String formatter
|
2021-10-22 14:56:48 +02:00
|
|
|
AstSFormatF* fmtp() const { return VN_AS(op1p(), SFormatF); }
|
2019-05-19 22:13:13 +02:00
|
|
|
AstNode* filep() const { return op3p(); }
|
|
|
|
|
void filep(AstNodeVarRef* nodep) { setNOp3p(nodep); }
|
2009-11-24 03:24:55 +01:00
|
|
|
};
|
|
|
|
|
|
2020-11-19 03:32:16 +01:00
|
|
|
class AstDumpCtl final : public AstNodeStmt {
|
2020-03-02 03:39:23 +01:00
|
|
|
// $dumpon etc
|
|
|
|
|
// Parents: expr
|
|
|
|
|
// Child: expr based on type of control statement
|
2021-11-26 23:55:36 +01:00
|
|
|
const VDumpCtlType m_ctlType; // Type of operation
|
2020-03-02 03:39:23 +01:00
|
|
|
public:
|
2020-08-15 16:12:55 +02:00
|
|
|
AstDumpCtl(FileLine* fl, VDumpCtlType ctlType, AstNode* exprp = nullptr)
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_DumpCtl(fl)
|
2020-08-16 17:40:42 +02:00
|
|
|
, m_ctlType{ctlType} {
|
2020-03-02 03:39:23 +01:00
|
|
|
setNOp1p(exprp);
|
|
|
|
|
}
|
|
|
|
|
ASTNODE_NODE_FUNCS(DumpCtl)
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual string verilogKwd() const override { return ctlType().ascii(); }
|
|
|
|
|
virtual bool isGateOptimizable() const override { return false; }
|
|
|
|
|
virtual bool isPredictOptimizable() const override { return false; }
|
|
|
|
|
virtual bool isOutputter() const override { return true; }
|
2020-03-02 03:39:23 +01:00
|
|
|
virtual bool cleanOut() const { return true; }
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual bool same(const AstNode* samep) const override { return true; }
|
2020-03-02 03:39:23 +01:00
|
|
|
VDumpCtlType ctlType() const { return m_ctlType; }
|
|
|
|
|
AstNode* exprp() const { return op1p(); } // op2 = Expressions to output
|
|
|
|
|
void exprp(AstNode* nodep) { setOp1p(nodep); }
|
|
|
|
|
};
|
|
|
|
|
|
2020-11-19 03:32:16 +01:00
|
|
|
class AstElabDisplay final : public AstNode {
|
2019-08-05 04:34:54 +02:00
|
|
|
// Parents: stmtlist
|
|
|
|
|
// Children: SFORMATF to generate print string
|
|
|
|
|
private:
|
|
|
|
|
AstDisplayType m_displayType;
|
2020-04-15 13:58:34 +02:00
|
|
|
|
2019-08-05 04:34:54 +02:00
|
|
|
public:
|
2020-01-25 21:29:44 +01:00
|
|
|
AstElabDisplay(FileLine* fl, AstDisplayType dispType, AstNode* exprsp)
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_ElabDisplay(fl) {
|
2020-01-25 21:29:44 +01:00
|
|
|
setOp1p(new AstSFormatF(fl, AstSFormatF::NoFormat(), exprsp));
|
2019-08-05 04:34:54 +02:00
|
|
|
m_displayType = dispType;
|
|
|
|
|
}
|
|
|
|
|
ASTNODE_NODE_FUNCS(ElabDisplay)
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual const char* broken() const override {
|
2020-04-15 13:58:34 +02:00
|
|
|
BROKEN_RTN(!fmtp());
|
2020-08-15 16:12:55 +02:00
|
|
|
return nullptr;
|
2020-04-15 13:58:34 +02:00
|
|
|
}
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual string verilogKwd() const override {
|
|
|
|
|
return (string("$") + string(displayType().ascii()));
|
|
|
|
|
}
|
|
|
|
|
virtual bool isGateOptimizable() const override { return false; }
|
|
|
|
|
virtual bool isPredictOptimizable() const override { return false; }
|
|
|
|
|
virtual bool isPure() const override {
|
|
|
|
|
return false;
|
|
|
|
|
} // SPECIAL: $display has 'visual' ordering
|
|
|
|
|
virtual bool isOutputter() const override { return true; } // SPECIAL: $display makes output
|
|
|
|
|
virtual bool isUnlikely() const override { return true; }
|
|
|
|
|
virtual bool same(const AstNode* samep) const override {
|
2020-04-15 13:58:34 +02:00
|
|
|
return displayType() == static_cast<const AstElabDisplay*>(samep)->displayType();
|
|
|
|
|
}
|
2021-07-25 14:32:36 +02:00
|
|
|
virtual int instrCount() const override { return INSTR_COUNT_PLI; }
|
2019-08-05 04:34:54 +02:00
|
|
|
AstDisplayType displayType() const { return m_displayType; }
|
|
|
|
|
void displayType(AstDisplayType type) { m_displayType = type; }
|
|
|
|
|
void fmtp(AstSFormatF* nodep) { addOp1p(nodep); } // op1 = To-String formatter
|
2021-10-22 14:56:48 +02:00
|
|
|
AstSFormatF* fmtp() const { return VN_AS(op1p(), SFormatF); }
|
2019-08-05 04:34:54 +02:00
|
|
|
};
|
|
|
|
|
|
2020-11-19 03:32:16 +01:00
|
|
|
class AstSFormat final : public AstNodeStmt {
|
2009-11-24 03:24:55 +01:00
|
|
|
// Parents: statement container
|
|
|
|
|
// Children: string to load
|
2010-01-17 21:53:12 +01:00
|
|
|
// Children: SFORMATF to generate print string
|
2014-09-12 03:28:53 +02:00
|
|
|
public:
|
2020-03-06 03:49:25 +01:00
|
|
|
AstSFormat(FileLine* fl, AstNode* lhsp, const string& text, AstNode* exprsp,
|
|
|
|
|
char missingArgChar = 'd')
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_SFormat(fl) {
|
2020-03-06 03:49:25 +01:00
|
|
|
setOp1p(new AstSFormatF(fl, text, true, exprsp, missingArgChar));
|
2019-05-19 22:13:13 +02:00
|
|
|
setOp3p(lhsp);
|
2009-11-24 03:24:55 +01:00
|
|
|
}
|
2020-06-06 20:47:54 +02:00
|
|
|
AstSFormat(FileLine* fl, AstNode* lhsp, AstNode* exprsp, char missingArgChar = 'd')
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_SFormat(fl) {
|
2020-06-06 20:47:54 +02:00
|
|
|
setOp1p(new AstSFormatF(fl, AstSFormatF::NoFormat(), exprsp, missingArgChar));
|
|
|
|
|
setOp3p(lhsp);
|
|
|
|
|
}
|
2016-11-05 14:47:56 +01:00
|
|
|
ASTNODE_NODE_FUNCS(SFormat)
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual const char* broken() const override {
|
2020-04-15 13:58:34 +02:00
|
|
|
BROKEN_RTN(!fmtp());
|
2020-08-15 16:12:55 +02:00
|
|
|
return nullptr;
|
2020-04-15 13:58:34 +02:00
|
|
|
}
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual string verilogKwd() const override { return "$sformat"; }
|
|
|
|
|
virtual bool isGateOptimizable() const override { return false; }
|
|
|
|
|
virtual bool isPredictOptimizable() const override { return true; }
|
|
|
|
|
virtual bool isPure() const override { return true; }
|
|
|
|
|
virtual bool isOutputter() const override { return false; }
|
2019-10-20 17:58:41 +02:00
|
|
|
virtual bool cleanOut() const { return false; }
|
2021-07-25 14:32:36 +02:00
|
|
|
virtual int instrCount() const override { return INSTR_COUNT_PLI; }
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual bool same(const AstNode* samep) const override { return true; }
|
2019-05-19 22:13:13 +02:00
|
|
|
void fmtp(AstSFormatF* nodep) { addOp1p(nodep); } // op1 = To-String formatter
|
2021-10-22 14:56:48 +02:00
|
|
|
AstSFormatF* fmtp() const { return VN_AS(op1p(), SFormatF); }
|
2019-05-19 22:13:13 +02:00
|
|
|
AstNode* lhsp() const { return op3p(); }
|
|
|
|
|
void lhsp(AstNode* nodep) { setOp3p(nodep); }
|
2006-08-26 13:35:28 +02:00
|
|
|
};
|
|
|
|
|
|
2020-11-19 03:32:16 +01:00
|
|
|
class AstSysFuncAsTask final : public AstNodeStmt {
|
2018-03-09 05:40:19 +01:00
|
|
|
// Call what is normally a system function (with a return) in a non-return context
|
|
|
|
|
// Parents: stmtlist
|
|
|
|
|
// Children: a system function
|
|
|
|
|
public:
|
2020-01-25 21:29:44 +01:00
|
|
|
AstSysFuncAsTask(FileLine* fl, AstNode* exprsp)
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_SysFuncAsTask(fl) {
|
2020-04-15 13:58:34 +02:00
|
|
|
addNOp1p(exprsp);
|
|
|
|
|
}
|
2018-03-09 05:40:19 +01:00
|
|
|
ASTNODE_NODE_FUNCS(SysFuncAsTask)
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual string verilogKwd() const override { return ""; }
|
|
|
|
|
virtual bool isGateOptimizable() const override { return true; }
|
|
|
|
|
virtual bool isPredictOptimizable() const override { return true; }
|
|
|
|
|
virtual bool isPure() const override { return true; }
|
|
|
|
|
virtual bool isOutputter() const override { return false; }
|
|
|
|
|
virtual int instrCount() const override { return 0; }
|
|
|
|
|
virtual bool same(const AstNode* samep) const override { return true; }
|
2018-03-09 05:40:19 +01:00
|
|
|
AstNode* lhsp() const { return op1p(); } // op1 = Expressions to eval
|
|
|
|
|
void lhsp(AstNode* nodep) { addOp1p(nodep); } // op1 = Expressions to eval
|
|
|
|
|
};
|
|
|
|
|
|
2020-11-19 03:32:16 +01:00
|
|
|
class AstSysIgnore final : public AstNodeStmt {
|
2010-12-30 13:55:31 +01:00
|
|
|
// Parents: stmtlist
|
|
|
|
|
// Children: varrefs or exprs
|
2014-09-12 03:28:53 +02:00
|
|
|
public:
|
2020-01-25 21:29:44 +01:00
|
|
|
AstSysIgnore(FileLine* fl, AstNode* exprsp)
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_SysIgnore(fl) {
|
2020-04-15 13:58:34 +02:00
|
|
|
addNOp1p(exprsp);
|
|
|
|
|
}
|
2016-11-05 14:47:56 +01:00
|
|
|
ASTNODE_NODE_FUNCS(SysIgnore)
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual string verilogKwd() const override { return "$ignored"; }
|
|
|
|
|
virtual bool isGateOptimizable() const override { return false; } // Though deleted before opt
|
|
|
|
|
virtual bool isPredictOptimizable() const override {
|
|
|
|
|
return false;
|
|
|
|
|
} // Though deleted before opt
|
|
|
|
|
virtual bool isPure() const override { return false; } // Though deleted before opt
|
|
|
|
|
virtual bool isOutputter() const override { return true; } // Though deleted before opt
|
2021-07-25 14:32:36 +02:00
|
|
|
virtual int instrCount() const override { return INSTR_COUNT_PLI; }
|
2019-05-19 22:13:13 +02:00
|
|
|
AstNode* exprsp() const { return op1p(); } // op1 = Expressions to output
|
|
|
|
|
void exprsp(AstNode* nodep) { addOp1p(nodep); } // op1 = Expressions to output
|
2010-12-30 13:55:31 +01:00
|
|
|
};
|
|
|
|
|
|
2020-11-19 03:32:16 +01:00
|
|
|
class AstFClose final : public AstNodeStmt {
|
2006-12-21 22:53:51 +01:00
|
|
|
// Parents: stmtlist
|
|
|
|
|
// Children: file which must be a varref
|
2014-09-12 03:28:53 +02:00
|
|
|
public:
|
2020-01-25 21:29:44 +01:00
|
|
|
AstFClose(FileLine* fl, AstNode* filep)
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_FClose(fl) {
|
2019-05-19 22:13:13 +02:00
|
|
|
setNOp2p(filep);
|
2006-08-26 13:35:28 +02:00
|
|
|
}
|
2016-11-05 14:47:56 +01:00
|
|
|
ASTNODE_NODE_FUNCS(FClose)
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual string verilogKwd() const override { return "$fclose"; }
|
|
|
|
|
virtual bool isGateOptimizable() const override { return false; }
|
|
|
|
|
virtual bool isPredictOptimizable() const override { return false; }
|
|
|
|
|
virtual bool isPure() const override { return false; }
|
|
|
|
|
virtual bool isOutputter() const override { return true; }
|
|
|
|
|
virtual bool isUnlikely() const override { return true; }
|
|
|
|
|
virtual bool same(const AstNode* samep) const override { return true; }
|
2019-05-19 22:13:13 +02:00
|
|
|
AstNode* filep() const { return op2p(); }
|
2006-08-26 13:35:28 +02:00
|
|
|
void filep(AstNodeVarRef* nodep) { setNOp2p(nodep); }
|
|
|
|
|
};
|
|
|
|
|
|
2020-11-19 03:32:16 +01:00
|
|
|
class AstFOpen final : public AstNodeStmt {
|
2014-04-30 03:11:57 +02:00
|
|
|
// Although a system function in IEEE, here a statement which sets the file pointer (MCD)
|
2014-09-12 03:28:53 +02:00
|
|
|
public:
|
2020-01-25 21:29:44 +01:00
|
|
|
AstFOpen(FileLine* fl, AstNode* filep, AstNode* filenamep, AstNode* modep)
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_FOpen(fl) {
|
2019-05-19 22:13:13 +02:00
|
|
|
setOp1p(filep);
|
|
|
|
|
setOp2p(filenamep);
|
|
|
|
|
setOp3p(modep);
|
2006-08-26 13:35:28 +02:00
|
|
|
}
|
2016-11-05 14:47:56 +01:00
|
|
|
ASTNODE_NODE_FUNCS(FOpen)
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual string verilogKwd() const override { return "$fopen"; }
|
|
|
|
|
virtual bool isGateOptimizable() const override { return false; }
|
|
|
|
|
virtual bool isPredictOptimizable() const override { return false; }
|
|
|
|
|
virtual bool isPure() const override { return false; }
|
|
|
|
|
virtual bool isOutputter() const override { return true; }
|
|
|
|
|
virtual bool isUnlikely() const override { return true; }
|
|
|
|
|
virtual bool same(const AstNode* samep) const override { return true; }
|
2019-05-19 22:13:13 +02:00
|
|
|
AstNode* filep() const { return op1p(); }
|
|
|
|
|
AstNode* filenamep() const { return op2p(); }
|
|
|
|
|
AstNode* modep() const { return op3p(); }
|
2006-08-26 13:35:28 +02:00
|
|
|
};
|
|
|
|
|
|
2020-11-19 03:32:16 +01:00
|
|
|
class AstFOpenMcd final : public AstNodeStmt {
|
2020-05-15 00:03:00 +02:00
|
|
|
// Although a system function in IEEE, here a statement which sets the file pointer (MCD)
|
|
|
|
|
public:
|
|
|
|
|
AstFOpenMcd(FileLine* fl, AstNode* filep, AstNode* filenamep)
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_FOpenMcd(fl) {
|
2020-05-15 00:03:00 +02:00
|
|
|
setOp1p(filep);
|
|
|
|
|
setOp2p(filenamep);
|
|
|
|
|
}
|
|
|
|
|
ASTNODE_NODE_FUNCS(FOpenMcd)
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual string verilogKwd() const override { return "$fopen"; }
|
|
|
|
|
virtual bool isGateOptimizable() const override { return false; }
|
|
|
|
|
virtual bool isPredictOptimizable() const override { return false; }
|
|
|
|
|
virtual bool isPure() const override { return false; }
|
|
|
|
|
virtual bool isOutputter() const override { return true; }
|
|
|
|
|
virtual bool isUnlikely() const override { return true; }
|
|
|
|
|
virtual bool same(const AstNode* samep) const override { return true; }
|
2020-05-15 00:03:00 +02:00
|
|
|
AstNode* filep() const { return op1p(); }
|
|
|
|
|
AstNode* filenamep() const { return op2p(); }
|
|
|
|
|
};
|
|
|
|
|
|
2020-11-19 03:32:16 +01:00
|
|
|
class AstFFlush final : public AstNodeStmt {
|
2008-06-27 14:45:05 +02:00
|
|
|
// Parents: stmtlist
|
|
|
|
|
// Children: file which must be a varref
|
2014-09-12 03:28:53 +02:00
|
|
|
public:
|
2020-01-25 21:29:44 +01:00
|
|
|
AstFFlush(FileLine* fl, AstNode* filep)
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_FFlush(fl) {
|
2019-05-19 22:13:13 +02:00
|
|
|
setNOp2p(filep);
|
2008-06-27 14:45:05 +02:00
|
|
|
}
|
2016-11-05 14:47:56 +01:00
|
|
|
ASTNODE_NODE_FUNCS(FFlush)
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual string verilogKwd() const override { return "$fflush"; }
|
|
|
|
|
virtual bool isGateOptimizable() const override { return false; }
|
|
|
|
|
virtual bool isPredictOptimizable() const override { return false; }
|
|
|
|
|
virtual bool isPure() const override { return false; }
|
|
|
|
|
virtual bool isOutputter() const override { return true; }
|
|
|
|
|
virtual bool isUnlikely() const override { return true; }
|
|
|
|
|
virtual bool same(const AstNode* samep) const override { return true; }
|
2019-05-19 22:13:13 +02:00
|
|
|
AstNode* filep() const { return op2p(); }
|
2008-06-27 14:45:05 +02:00
|
|
|
void filep(AstNodeVarRef* nodep) { setNOp2p(nodep); }
|
|
|
|
|
};
|
|
|
|
|
|
2020-11-19 03:32:16 +01:00
|
|
|
class AstFRead final : public AstNodeMath {
|
2019-03-08 02:56:53 +01:00
|
|
|
// Parents: expr
|
|
|
|
|
// Children: varrefs to load
|
|
|
|
|
// Children: file which must be a varref
|
|
|
|
|
// Children: low index
|
|
|
|
|
// Children: count
|
|
|
|
|
public:
|
2020-04-15 13:58:34 +02:00
|
|
|
AstFRead(FileLine* fl, AstNode* memp, AstNode* filep, AstNode* startp, AstNode* countp)
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_FRead(fl) {
|
2019-03-08 02:56:53 +01:00
|
|
|
setOp1p(memp);
|
|
|
|
|
setOp2p(filep);
|
|
|
|
|
setNOp3p(startp);
|
|
|
|
|
setNOp4p(countp);
|
|
|
|
|
}
|
|
|
|
|
ASTNODE_NODE_FUNCS(FRead)
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual string verilogKwd() const override { return "$fread"; }
|
|
|
|
|
virtual string emitVerilog() override { V3ERROR_NA_RETURN(""); }
|
|
|
|
|
virtual string emitC() override { V3ERROR_NA_RETURN(""); }
|
|
|
|
|
virtual bool isGateOptimizable() const override { return false; }
|
|
|
|
|
virtual bool isPredictOptimizable() const override { return false; }
|
|
|
|
|
virtual bool isPure() const override { return false; } // SPECIAL: has 'visual' ordering
|
|
|
|
|
virtual bool isOutputter() const override { return true; } // SPECIAL: makes output
|
|
|
|
|
virtual bool cleanOut() const override { return false; }
|
|
|
|
|
virtual bool same(const AstNode* samep) const override { return true; }
|
2019-03-08 02:56:53 +01:00
|
|
|
AstNode* memp() const { return op1p(); }
|
|
|
|
|
void memp(AstNode* nodep) { setOp1p(nodep); }
|
|
|
|
|
AstNode* filep() const { return op2p(); }
|
|
|
|
|
void filep(AstNode* nodep) { setOp2p(nodep); }
|
|
|
|
|
AstNode* startp() const { return op3p(); }
|
|
|
|
|
void startp(AstNode* nodep) { setNOp3p(nodep); }
|
|
|
|
|
AstNode* countp() const { return op4p(); }
|
|
|
|
|
void countp(AstNode* nodep) { setNOp4p(nodep); }
|
|
|
|
|
};
|
|
|
|
|
|
2020-11-19 03:32:16 +01:00
|
|
|
class AstFRewind final : public AstNodeMath {
|
2019-09-04 03:28:15 +02:00
|
|
|
// Parents: stmtlist
|
|
|
|
|
// Children: file which must be a varref
|
|
|
|
|
public:
|
2020-01-25 21:29:44 +01:00
|
|
|
AstFRewind(FileLine* fl, AstNode* filep)
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_FRewind(fl) {
|
2019-09-04 03:28:15 +02:00
|
|
|
setNOp2p(filep);
|
|
|
|
|
}
|
|
|
|
|
ASTNODE_NODE_FUNCS(FRewind)
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual string verilogKwd() const override { return "$frewind"; }
|
|
|
|
|
virtual string emitVerilog() override { V3ERROR_NA_RETURN(""); }
|
|
|
|
|
virtual string emitC() override { V3ERROR_NA_RETURN(""); }
|
|
|
|
|
virtual bool isGateOptimizable() const override { return false; }
|
|
|
|
|
virtual bool isPredictOptimizable() const override { return false; }
|
|
|
|
|
virtual bool isPure() const override { return false; }
|
|
|
|
|
virtual bool isOutputter() const override { return true; }
|
|
|
|
|
virtual bool isUnlikely() const override { return true; }
|
|
|
|
|
virtual bool cleanOut() const override { return false; }
|
|
|
|
|
virtual bool same(const AstNode* samep) const override { return true; }
|
2019-09-04 03:28:15 +02:00
|
|
|
AstNode* filep() const { return op2p(); }
|
|
|
|
|
void filep(AstNodeVarRef* nodep) { setNOp2p(nodep); }
|
|
|
|
|
};
|
|
|
|
|
|
2020-11-19 03:32:16 +01:00
|
|
|
class AstFTell final : public AstNodeMath {
|
2019-09-04 03:28:15 +02:00
|
|
|
// Parents: stmtlist
|
|
|
|
|
// Children: file which must be a varref
|
|
|
|
|
public:
|
2020-01-25 21:29:44 +01:00
|
|
|
AstFTell(FileLine* fl, AstNode* filep)
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_FTell(fl) {
|
2019-09-04 03:28:15 +02:00
|
|
|
setNOp2p(filep);
|
|
|
|
|
}
|
|
|
|
|
ASTNODE_NODE_FUNCS(FTell)
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual string verilogKwd() const override { return "$ftell"; }
|
|
|
|
|
virtual string emitVerilog() override { V3ERROR_NA_RETURN(""); }
|
|
|
|
|
virtual string emitC() override { V3ERROR_NA_RETURN(""); }
|
|
|
|
|
virtual bool isGateOptimizable() const override { return false; }
|
|
|
|
|
virtual bool isPredictOptimizable() const override { return false; }
|
|
|
|
|
virtual bool isPure() const override { return false; }
|
|
|
|
|
virtual bool isOutputter() const override { return true; }
|
|
|
|
|
virtual bool isUnlikely() const override { return true; }
|
|
|
|
|
virtual bool cleanOut() const override { return false; }
|
|
|
|
|
virtual bool same(const AstNode* samep) const override { return true; }
|
2019-09-04 03:28:15 +02:00
|
|
|
AstNode* filep() const { return op2p(); }
|
|
|
|
|
void filep(AstNodeVarRef* nodep) { setNOp2p(nodep); }
|
|
|
|
|
};
|
|
|
|
|
|
2020-11-19 03:32:16 +01:00
|
|
|
class AstFSeek final : public AstNodeMath {
|
2019-09-04 03:28:15 +02:00
|
|
|
// Parents: expr
|
|
|
|
|
// Children: file which must be a varref
|
|
|
|
|
// Children: offset
|
|
|
|
|
// Children: operation
|
|
|
|
|
public:
|
2020-04-15 13:58:34 +02:00
|
|
|
AstFSeek(FileLine* fl, AstNode* filep, AstNode* offset, AstNode* operation)
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_FSeek(fl) {
|
2019-09-04 03:28:15 +02:00
|
|
|
setOp2p(filep);
|
|
|
|
|
setNOp3p(offset);
|
|
|
|
|
setNOp4p(operation);
|
|
|
|
|
}
|
|
|
|
|
ASTNODE_NODE_FUNCS(FSeek)
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual string verilogKwd() const override { return "$fseek"; }
|
|
|
|
|
virtual string emitVerilog() override { V3ERROR_NA_RETURN(""); }
|
|
|
|
|
virtual string emitC() override { V3ERROR_NA_RETURN(""); }
|
|
|
|
|
virtual bool isGateOptimizable() const override { return false; }
|
|
|
|
|
virtual bool isPredictOptimizable() const override { return false; }
|
|
|
|
|
virtual bool isPure() const override { return false; } // SPECIAL: has 'visual' ordering
|
|
|
|
|
virtual bool isOutputter() const override { return true; } // SPECIAL: makes output
|
|
|
|
|
virtual bool cleanOut() const override { return false; }
|
|
|
|
|
virtual bool same(const AstNode* samep) const override { return true; }
|
2019-09-04 03:28:15 +02:00
|
|
|
AstNode* filep() const { return op2p(); }
|
|
|
|
|
void filep(AstNode* nodep) { setOp2p(nodep); }
|
|
|
|
|
AstNode* offset() const { return op3p(); }
|
|
|
|
|
void offset(AstNode* nodep) { setNOp3p(nodep); }
|
|
|
|
|
AstNode* operation() const { return op4p(); }
|
|
|
|
|
void operation(AstNode* nodep) { setNOp4p(nodep); }
|
|
|
|
|
};
|
|
|
|
|
|
2020-11-19 03:32:16 +01:00
|
|
|
class AstFScanF final : public AstNodeMath {
|
2008-07-01 20:15:10 +02:00
|
|
|
// Parents: expr
|
|
|
|
|
// Children: file which must be a varref
|
|
|
|
|
// Children: varrefs to load
|
|
|
|
|
private:
|
2020-04-15 13:58:34 +02:00
|
|
|
string m_text;
|
|
|
|
|
|
2008-07-01 20:15:10 +02:00
|
|
|
public:
|
2020-01-25 21:29:44 +01:00
|
|
|
AstFScanF(FileLine* fl, const string& text, AstNode* filep, AstNode* exprsp)
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_FScanF(fl)
|
2020-08-16 17:40:42 +02:00
|
|
|
, m_text{text} {
|
2019-05-19 22:13:13 +02:00
|
|
|
addNOp1p(exprsp);
|
|
|
|
|
setNOp2p(filep);
|
2008-07-01 20:15:10 +02:00
|
|
|
}
|
2016-11-05 14:47:56 +01:00
|
|
|
ASTNODE_NODE_FUNCS(FScanF)
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual string name() const override { return m_text; }
|
|
|
|
|
virtual string verilogKwd() const override { return "$fscanf"; }
|
|
|
|
|
virtual string emitVerilog() override { V3ERROR_NA_RETURN(""); }
|
|
|
|
|
virtual string emitC() override { V3ERROR_NA_RETURN(""); }
|
|
|
|
|
virtual bool isGateOptimizable() const override { return false; }
|
|
|
|
|
virtual bool isPredictOptimizable() const override { return false; }
|
|
|
|
|
virtual bool isPure() const override { return false; } // SPECIAL: has 'visual' ordering
|
|
|
|
|
virtual bool isOutputter() const override { return true; } // SPECIAL: makes output
|
|
|
|
|
virtual bool cleanOut() const override { return false; }
|
|
|
|
|
virtual bool same(const AstNode* samep) const override {
|
2020-04-15 13:58:34 +02:00
|
|
|
return text() == static_cast<const AstFScanF*>(samep)->text();
|
|
|
|
|
}
|
2019-05-19 22:13:13 +02:00
|
|
|
AstNode* exprsp() const { return op1p(); } // op1 = Expressions to output
|
|
|
|
|
void exprsp(AstNode* nodep) { addOp1p(nodep); } // op1 = Expressions to output
|
|
|
|
|
string text() const { return m_text; } // * = Text to display
|
|
|
|
|
void text(const string& text) { m_text = text; }
|
|
|
|
|
AstNode* filep() const { return op2p(); }
|
|
|
|
|
void filep(AstNodeVarRef* nodep) { setNOp2p(nodep); }
|
2008-07-01 20:15:10 +02:00
|
|
|
};
|
|
|
|
|
|
2020-11-19 03:32:16 +01:00
|
|
|
class AstSScanF final : public AstNodeMath {
|
2008-07-01 20:15:10 +02:00
|
|
|
// Parents: expr
|
|
|
|
|
// Children: file which must be a varref
|
|
|
|
|
// Children: varrefs to load
|
|
|
|
|
private:
|
2020-04-15 13:58:34 +02:00
|
|
|
string m_text;
|
|
|
|
|
|
2008-07-01 20:15:10 +02:00
|
|
|
public:
|
2020-01-25 21:29:44 +01:00
|
|
|
AstSScanF(FileLine* fl, const string& text, AstNode* fromp, AstNode* exprsp)
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_SScanF(fl)
|
2020-08-16 17:40:42 +02:00
|
|
|
, m_text{text} {
|
2019-05-19 22:13:13 +02:00
|
|
|
addNOp1p(exprsp);
|
|
|
|
|
setOp2p(fromp);
|
2008-07-01 20:15:10 +02:00
|
|
|
}
|
2016-11-05 14:47:56 +01:00
|
|
|
ASTNODE_NODE_FUNCS(SScanF)
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual string name() const override { return m_text; }
|
|
|
|
|
virtual string verilogKwd() const override { return "$sscanf"; }
|
|
|
|
|
virtual string emitVerilog() override { V3ERROR_NA_RETURN(""); }
|
|
|
|
|
virtual string emitC() override { V3ERROR_NA_RETURN(""); }
|
|
|
|
|
virtual bool isGateOptimizable() const override { return false; }
|
|
|
|
|
virtual bool isPredictOptimizable() const override { return false; }
|
|
|
|
|
virtual bool isPure() const override { return false; } // SPECIAL: has 'visual' ordering
|
|
|
|
|
virtual bool isOutputter() const override { return true; } // SPECIAL: makes output
|
|
|
|
|
virtual bool cleanOut() const override { return false; }
|
|
|
|
|
virtual bool same(const AstNode* samep) const override {
|
2020-04-15 13:58:34 +02:00
|
|
|
return text() == static_cast<const AstSScanF*>(samep)->text();
|
|
|
|
|
}
|
2019-05-19 22:13:13 +02:00
|
|
|
AstNode* exprsp() const { return op1p(); } // op1 = Expressions to output
|
|
|
|
|
void exprsp(AstNode* nodep) { addOp1p(nodep); } // op1 = Expressions to output
|
|
|
|
|
string text() const { return m_text; } // * = Text to display
|
|
|
|
|
void text(const string& text) { m_text = text; }
|
|
|
|
|
AstNode* fromp() const { return op2p(); }
|
|
|
|
|
void fromp(AstNode* nodep) { setOp2p(nodep); }
|
2008-07-01 20:15:10 +02:00
|
|
|
};
|
|
|
|
|
|
2020-11-19 03:32:16 +01:00
|
|
|
class AstNodeReadWriteMem VL_NOT_FINAL : public AstNodeStmt {
|
2006-12-19 15:09:57 +01:00
|
|
|
private:
|
2021-11-26 23:55:36 +01:00
|
|
|
const bool m_isHex; // readmemh, not readmemb
|
2006-12-19 15:09:57 +01:00
|
|
|
public:
|
2020-04-15 13:58:34 +02:00
|
|
|
AstNodeReadWriteMem(AstType t, FileLine* fl, bool hex, AstNode* filenamep, AstNode* memp,
|
2018-03-12 21:44:01 +01:00
|
|
|
AstNode* lsbp, AstNode* msbp)
|
2020-04-15 13:58:34 +02:00
|
|
|
: AstNodeStmt(t, fl)
|
|
|
|
|
, m_isHex(hex) {
|
|
|
|
|
setOp1p(filenamep);
|
|
|
|
|
setOp2p(memp);
|
|
|
|
|
setNOp3p(lsbp);
|
|
|
|
|
setNOp4p(msbp);
|
2006-12-19 15:09:57 +01:00
|
|
|
}
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual bool isGateOptimizable() const override { return false; }
|
|
|
|
|
virtual bool isPredictOptimizable() const override { return false; }
|
|
|
|
|
virtual bool isPure() const override { return false; }
|
|
|
|
|
virtual bool isOutputter() const override { return true; }
|
|
|
|
|
virtual bool isUnlikely() const override { return true; }
|
|
|
|
|
virtual bool same(const AstNode* samep) const override {
|
2020-04-15 13:58:34 +02:00
|
|
|
return isHex() == static_cast<const AstNodeReadWriteMem*>(samep)->isHex();
|
2018-03-12 21:44:01 +01:00
|
|
|
}
|
2019-05-19 22:13:13 +02:00
|
|
|
bool isHex() const { return m_isHex; }
|
|
|
|
|
AstNode* filenamep() const { return op1p(); }
|
|
|
|
|
AstNode* memp() const { return op2p(); }
|
|
|
|
|
AstNode* lsbp() const { return op3p(); }
|
|
|
|
|
AstNode* msbp() const { return op4p(); }
|
2018-03-12 21:44:01 +01:00
|
|
|
virtual const char* cFuncPrefixp() const = 0;
|
|
|
|
|
};
|
|
|
|
|
|
2020-11-19 03:32:16 +01:00
|
|
|
class AstReadMem final : public AstNodeReadWriteMem {
|
2018-03-12 21:44:01 +01:00
|
|
|
public:
|
2020-01-25 21:29:44 +01:00
|
|
|
AstReadMem(FileLine* fl, bool hex, AstNode* filenamep, AstNode* memp, AstNode* lsbp,
|
|
|
|
|
AstNode* msbp)
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_ReadMem(fl, hex, filenamep, memp, lsbp, msbp) {}
|
2018-03-12 21:44:01 +01:00
|
|
|
ASTNODE_NODE_FUNCS(ReadMem);
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual string verilogKwd() const override { return (isHex() ? "$readmemh" : "$readmemb"); }
|
|
|
|
|
virtual const char* cFuncPrefixp() const override { return "VL_READMEM_"; }
|
2018-03-12 21:44:01 +01:00
|
|
|
};
|
|
|
|
|
|
2020-11-19 03:32:16 +01:00
|
|
|
class AstWriteMem final : public AstNodeReadWriteMem {
|
2018-03-12 21:44:01 +01:00
|
|
|
public:
|
2020-07-01 23:32:15 +02:00
|
|
|
AstWriteMem(FileLine* fl, bool hex, AstNode* filenamep, AstNode* memp, AstNode* lsbp,
|
|
|
|
|
AstNode* msbp)
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_WriteMem(fl, hex, filenamep, memp, lsbp, msbp) {}
|
2018-03-12 21:44:01 +01:00
|
|
|
ASTNODE_NODE_FUNCS(WriteMem)
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual string verilogKwd() const override { return (isHex() ? "$writememh" : "$writememb"); }
|
|
|
|
|
virtual const char* cFuncPrefixp() const override { return "VL_WRITEMEM_"; }
|
2006-12-19 15:09:57 +01:00
|
|
|
};
|
|
|
|
|
|
2020-11-29 17:31:38 +01:00
|
|
|
class AstMonitorOff final : public AstNodeStmt {
|
2021-11-26 23:55:36 +01:00
|
|
|
const bool m_off; // Monitor off. Using 0=on allows faster init and comparison
|
2020-11-29 17:31:38 +01:00
|
|
|
|
|
|
|
|
public:
|
|
|
|
|
AstMonitorOff(FileLine* fl, bool off)
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_MonitorOff(fl)
|
2020-11-29 17:31:38 +01:00
|
|
|
, m_off{off} {}
|
|
|
|
|
ASTNODE_NODE_FUNCS(MonitorOff)
|
|
|
|
|
virtual string verilogKwd() const override { return m_off ? "$monitoroff" : "$monitoron"; }
|
|
|
|
|
virtual bool isGateOptimizable() const override { return false; } // Though deleted before opt
|
|
|
|
|
virtual bool isPredictOptimizable() const override {
|
|
|
|
|
return false;
|
|
|
|
|
} // Though deleted before opt
|
|
|
|
|
virtual bool isPure() const override { return false; } // Though deleted before opt
|
|
|
|
|
virtual bool isOutputter() const override { return true; } // Though deleted before opt
|
2021-07-25 14:32:36 +02:00
|
|
|
virtual int instrCount() const override { return INSTR_COUNT_PLI; }
|
2020-11-29 17:31:38 +01:00
|
|
|
virtual bool same(const AstNode* samep) const override {
|
|
|
|
|
return m_off == static_cast<const AstMonitorOff*>(samep)->m_off;
|
|
|
|
|
}
|
|
|
|
|
bool off() const { return m_off; }
|
|
|
|
|
};
|
|
|
|
|
|
2020-11-19 03:32:16 +01:00
|
|
|
class AstSystemT final : public AstNodeStmt {
|
2011-11-20 08:01:48 +01:00
|
|
|
// $system used as task
|
2014-09-12 03:28:53 +02:00
|
|
|
public:
|
2020-01-25 21:29:44 +01:00
|
|
|
AstSystemT(FileLine* fl, AstNode* lhsp)
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_SystemT(fl) {
|
2019-05-19 22:13:13 +02:00
|
|
|
setOp1p(lhsp);
|
2011-11-20 08:01:48 +01:00
|
|
|
}
|
2016-11-05 14:47:56 +01:00
|
|
|
ASTNODE_NODE_FUNCS(SystemT)
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual string verilogKwd() const override { return "$system"; }
|
|
|
|
|
virtual bool isGateOptimizable() const override { return false; }
|
|
|
|
|
virtual bool isPredictOptimizable() const override { return false; }
|
|
|
|
|
virtual bool isPure() const override { return false; }
|
|
|
|
|
virtual bool isOutputter() const override { return true; }
|
|
|
|
|
virtual bool isUnlikely() const override { return true; }
|
|
|
|
|
virtual bool same(const AstNode* samep) const override { return true; }
|
2019-05-19 22:13:13 +02:00
|
|
|
AstNode* lhsp() const { return op1p(); }
|
2011-11-20 08:01:48 +01:00
|
|
|
};
|
|
|
|
|
|
2020-11-19 03:32:16 +01:00
|
|
|
class AstSystemF final : public AstNodeMath {
|
2011-11-20 08:01:48 +01:00
|
|
|
// $system used as function
|
2014-09-12 03:28:53 +02:00
|
|
|
public:
|
2020-01-25 21:29:44 +01:00
|
|
|
AstSystemF(FileLine* fl, AstNode* lhsp)
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_SystemF(fl) {
|
2019-05-19 22:13:13 +02:00
|
|
|
setOp1p(lhsp);
|
2011-11-20 08:01:48 +01:00
|
|
|
}
|
2016-11-05 14:47:56 +01:00
|
|
|
ASTNODE_NODE_FUNCS(SystemF)
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual string verilogKwd() const override { return "$system"; }
|
|
|
|
|
virtual string emitVerilog() override { return verilogKwd(); }
|
|
|
|
|
virtual string emitC() override { return "VL_SYSTEM_%nq(%lw, %P)"; }
|
|
|
|
|
virtual bool isGateOptimizable() const override { return false; }
|
|
|
|
|
virtual bool isPredictOptimizable() const override { return false; }
|
|
|
|
|
virtual bool isPure() const override { return false; }
|
|
|
|
|
virtual bool isOutputter() const override { return true; }
|
|
|
|
|
virtual bool isUnlikely() const override { return true; }
|
|
|
|
|
virtual bool cleanOut() const override { return true; }
|
|
|
|
|
virtual bool same(const AstNode* samep) const override { return true; }
|
2019-05-19 22:13:13 +02:00
|
|
|
AstNode* lhsp() const { return op1p(); }
|
2011-11-20 08:01:48 +01:00
|
|
|
};
|
|
|
|
|
|
2020-11-19 03:32:16 +01:00
|
|
|
class AstValuePlusArgs final : public AstNodeMath {
|
2009-11-19 23:04:21 +01:00
|
|
|
// Parents: expr
|
2020-08-15 16:12:55 +02:00
|
|
|
// Child: variable to set. If nullptr then this is a $test$plusargs instead of $value$plusargs
|
2009-11-19 23:04:21 +01:00
|
|
|
public:
|
2020-01-25 21:29:44 +01:00
|
|
|
AstValuePlusArgs(FileLine* fl, AstNode* searchp, AstNode* outp)
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_ValuePlusArgs(fl) {
|
2020-04-15 13:58:34 +02:00
|
|
|
setOp1p(searchp);
|
|
|
|
|
setOp2p(outp);
|
2009-11-19 23:04:21 +01:00
|
|
|
}
|
2016-11-05 14:47:56 +01:00
|
|
|
ASTNODE_NODE_FUNCS(ValuePlusArgs)
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual string verilogKwd() const override { return "$value$plusargs"; }
|
|
|
|
|
virtual string emitVerilog() override { return "%f$value$plusargs(%l, %k%r)"; }
|
|
|
|
|
virtual string emitC() override { V3ERROR_NA_RETURN(""); }
|
|
|
|
|
virtual bool isGateOptimizable() const override { return false; }
|
|
|
|
|
virtual bool isPredictOptimizable() const override { return false; }
|
2021-09-13 21:52:53 +02:00
|
|
|
virtual bool isPure() const override { return !outp(); }
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual bool cleanOut() const override { return true; }
|
|
|
|
|
virtual bool same(const AstNode* samep) const override { return true; }
|
2019-05-19 22:13:13 +02:00
|
|
|
AstNode* searchp() const { return op1p(); } // op1 = Search expression
|
|
|
|
|
void searchp(AstNode* nodep) { setOp1p(nodep); }
|
|
|
|
|
AstNode* outp() const { return op2p(); } // op2 = Expressions to output
|
|
|
|
|
void outp(AstNode* nodep) { setOp2p(nodep); }
|
2009-11-19 23:04:21 +01:00
|
|
|
};
|
|
|
|
|
|
2020-11-19 03:32:16 +01:00
|
|
|
class AstTestPlusArgs final : public AstNodeMath {
|
2009-11-19 23:04:21 +01:00
|
|
|
// Parents: expr
|
2020-08-15 16:12:55 +02:00
|
|
|
// Child: variable to set. If nullptr then this is a $test$plusargs instead of $value$plusargs
|
2009-11-19 23:04:21 +01:00
|
|
|
private:
|
2020-04-15 13:58:34 +02:00
|
|
|
string m_text;
|
|
|
|
|
|
2009-11-19 23:04:21 +01:00
|
|
|
public:
|
2020-01-25 21:29:44 +01:00
|
|
|
AstTestPlusArgs(FileLine* fl, const string& text)
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_TestPlusArgs(fl)
|
2020-08-16 17:40:42 +02:00
|
|
|
, m_text{text} {}
|
2016-11-05 14:47:56 +01:00
|
|
|
ASTNODE_NODE_FUNCS(TestPlusArgs)
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual string name() const override { return m_text; }
|
|
|
|
|
virtual string verilogKwd() const override { return "$test$plusargs"; }
|
|
|
|
|
virtual string emitVerilog() override { return verilogKwd(); }
|
|
|
|
|
virtual string emitC() override { return "VL_VALUEPLUSARGS_%nq(%lw, %P, nullptr)"; }
|
|
|
|
|
virtual bool isGateOptimizable() const override { return false; }
|
|
|
|
|
virtual bool isPredictOptimizable() const override { return false; }
|
|
|
|
|
virtual bool cleanOut() const override { return true; }
|
|
|
|
|
virtual bool same(const AstNode* samep) const override {
|
2020-04-15 13:58:34 +02:00
|
|
|
return text() == static_cast<const AstTestPlusArgs*>(samep)->text();
|
|
|
|
|
}
|
2019-05-19 22:13:13 +02:00
|
|
|
string text() const { return m_text; } // * = Text to display
|
|
|
|
|
void text(const string& text) { m_text = text; }
|
2009-11-19 23:04:21 +01:00
|
|
|
};
|
|
|
|
|
|
2020-11-19 03:32:16 +01:00
|
|
|
class AstGenFor final : public AstNodeFor {
|
2014-09-12 03:28:53 +02:00
|
|
|
public:
|
2020-01-25 21:29:44 +01:00
|
|
|
AstGenFor(FileLine* fl, AstNode* initsp, AstNode* condp, AstNode* incsp, AstNode* bodysp)
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_GenFor(fl, initsp, condp, incsp, bodysp) {}
|
2016-11-05 14:47:56 +01:00
|
|
|
ASTNODE_NODE_FUNCS(GenFor)
|
2006-08-26 13:35:28 +02:00
|
|
|
};
|
|
|
|
|
|
2020-11-19 03:32:16 +01:00
|
|
|
class AstForeach final : public AstNodeStmt {
|
2016-09-20 04:00:13 +02:00
|
|
|
public:
|
2020-06-10 04:05:06 +02:00
|
|
|
AstForeach(FileLine* fl, AstNode* arrayp, AstNode* bodysp)
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_Foreach(fl) {
|
2020-04-15 13:58:34 +02:00
|
|
|
setOp1p(arrayp);
|
|
|
|
|
addNOp4p(bodysp);
|
2016-09-20 04:00:13 +02:00
|
|
|
}
|
2016-11-05 14:47:56 +01:00
|
|
|
ASTNODE_NODE_FUNCS(Foreach)
|
2020-06-10 04:05:06 +02:00
|
|
|
AstNode* arrayp() const { return op1p(); } // op1 = array and index vars
|
2019-05-19 22:13:13 +02:00
|
|
|
AstNode* bodysp() const { return op4p(); } // op4 = body of loop
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual bool isGateOptimizable() const override { return false; }
|
2021-07-25 14:32:36 +02:00
|
|
|
virtual int instrCount() const override { return INSTR_COUNT_BRANCH; }
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual bool same(const AstNode* samep) const override { return true; }
|
2016-09-20 04:00:13 +02:00
|
|
|
};
|
|
|
|
|
|
2020-11-19 03:32:16 +01:00
|
|
|
class AstRepeat final : public AstNodeStmt {
|
2014-09-12 03:28:53 +02:00
|
|
|
public:
|
2020-01-25 21:29:44 +01:00
|
|
|
AstRepeat(FileLine* fl, AstNode* countp, AstNode* bodysp)
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_Repeat(fl) {
|
2020-04-15 13:58:34 +02:00
|
|
|
setOp2p(countp);
|
|
|
|
|
addNOp3p(bodysp);
|
2009-02-26 04:06:59 +01:00
|
|
|
}
|
2016-11-05 14:47:56 +01:00
|
|
|
ASTNODE_NODE_FUNCS(Repeat)
|
2019-05-19 22:13:13 +02:00
|
|
|
AstNode* countp() const { return op2p(); } // op2 = condition to continue
|
|
|
|
|
AstNode* bodysp() const { return op3p(); } // op3 = body of loop
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual bool isGateOptimizable() const override {
|
|
|
|
|
return false;
|
|
|
|
|
} // Not relevant - converted to FOR
|
2021-07-25 14:32:36 +02:00
|
|
|
virtual int instrCount() const override { return INSTR_COUNT_BRANCH; }
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual bool same(const AstNode* samep) const override { return true; }
|
2009-02-26 04:06:59 +01:00
|
|
|
};
|
|
|
|
|
|
2020-11-19 03:32:16 +01:00
|
|
|
class AstWait final : public AstNodeStmt {
|
2020-06-30 02:39:39 +02:00
|
|
|
public:
|
|
|
|
|
AstWait(FileLine* fl, AstNode* condp, AstNode* bodysp)
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_Wait(fl) {
|
2020-06-30 02:39:39 +02:00
|
|
|
setOp2p(condp);
|
|
|
|
|
addNOp3p(bodysp);
|
|
|
|
|
}
|
|
|
|
|
ASTNODE_NODE_FUNCS(Wait)
|
|
|
|
|
AstNode* bodysp() const { return op3p(); } // op3 = body of loop
|
|
|
|
|
};
|
|
|
|
|
|
2020-11-19 03:32:16 +01:00
|
|
|
class AstWhile final : public AstNodeStmt {
|
2014-09-12 03:28:53 +02:00
|
|
|
public:
|
2020-08-15 16:12:55 +02:00
|
|
|
AstWhile(FileLine* fl, AstNode* condp, AstNode* bodysp, AstNode* incsp = nullptr)
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_While(fl) {
|
2020-04-15 13:58:34 +02:00
|
|
|
setOp2p(condp);
|
|
|
|
|
addNOp3p(bodysp);
|
|
|
|
|
addNOp4p(incsp);
|
2006-08-26 13:35:28 +02:00
|
|
|
}
|
2016-11-05 14:47:56 +01:00
|
|
|
ASTNODE_NODE_FUNCS(While)
|
2020-04-15 13:58:34 +02:00
|
|
|
// op1 = prepare statements for condition (exec every loop)
|
|
|
|
|
AstNode* precondsp() const { return op1p(); }
|
2019-05-19 22:13:13 +02:00
|
|
|
AstNode* condp() const { return op2p(); } // op2 = condition to continue
|
|
|
|
|
AstNode* bodysp() const { return op3p(); } // op3 = body of loop
|
|
|
|
|
AstNode* incsp() const { return op4p(); } // op4 = increment (if from a FOR loop)
|
|
|
|
|
void addPrecondsp(AstNode* newp) { addOp1p(newp); }
|
|
|
|
|
void addBodysp(AstNode* newp) { addOp3p(newp); }
|
|
|
|
|
void addIncsp(AstNode* newp) { addOp4p(newp); }
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual bool isGateOptimizable() const override { return false; }
|
2021-07-25 14:32:36 +02:00
|
|
|
virtual int instrCount() const override { return INSTR_COUNT_BRANCH; }
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual bool same(const AstNode* samep) const override { return true; }
|
|
|
|
|
// Stop statement searchback here
|
|
|
|
|
virtual void addBeforeStmt(AstNode* newp, AstNode* belowp) override;
|
|
|
|
|
// Stop statement searchback here
|
|
|
|
|
virtual void addNextStmt(AstNode* newp, AstNode* belowp) override;
|
2006-08-26 13:35:28 +02:00
|
|
|
};
|
|
|
|
|
|
2020-11-19 03:32:16 +01:00
|
|
|
class AstBreak final : public AstNodeStmt {
|
2014-09-12 03:28:53 +02:00
|
|
|
public:
|
2020-01-25 21:29:44 +01:00
|
|
|
explicit AstBreak(FileLine* fl)
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_Break(fl) {}
|
2016-11-05 14:47:56 +01:00
|
|
|
ASTNODE_NODE_FUNCS(Break)
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual string verilogKwd() const override { return "break"; }
|
|
|
|
|
virtual bool isBrancher() const override {
|
2020-04-15 13:58:34 +02:00
|
|
|
return true; // SPECIAL: We don't process code after breaks
|
|
|
|
|
}
|
2010-02-14 16:01:21 +01:00
|
|
|
};
|
|
|
|
|
|
2020-11-19 03:32:16 +01:00
|
|
|
class AstContinue final : public AstNodeStmt {
|
2014-09-12 03:28:53 +02:00
|
|
|
public:
|
2020-01-25 21:29:44 +01:00
|
|
|
explicit AstContinue(FileLine* fl)
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_Continue(fl) {}
|
2016-11-05 14:47:56 +01:00
|
|
|
ASTNODE_NODE_FUNCS(Continue)
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual string verilogKwd() const override { return "continue"; }
|
|
|
|
|
virtual bool isBrancher() const override {
|
2020-04-15 13:58:34 +02:00
|
|
|
return true; // SPECIAL: We don't process code after breaks
|
|
|
|
|
}
|
2010-02-14 16:01:21 +01:00
|
|
|
};
|
|
|
|
|
|
2020-11-19 03:32:16 +01:00
|
|
|
class AstDisable final : public AstNodeStmt {
|
2011-06-29 03:26:49 +02:00
|
|
|
private:
|
2019-05-19 22:13:13 +02:00
|
|
|
string m_name; // Name of block
|
2011-06-29 03:26:49 +02:00
|
|
|
public:
|
2020-01-25 21:29:44 +01:00
|
|
|
AstDisable(FileLine* fl, const string& name)
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_Disable(fl)
|
2020-08-16 17:40:42 +02:00
|
|
|
, m_name{name} {}
|
2016-11-05 14:47:56 +01:00
|
|
|
ASTNODE_NODE_FUNCS(Disable)
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual string name() const override { return m_name; } // * = Block name
|
|
|
|
|
virtual void name(const string& flag) override { m_name = flag; }
|
|
|
|
|
virtual bool isBrancher() const override {
|
2020-04-15 13:58:34 +02:00
|
|
|
return true; // SPECIAL: We don't process code after breaks
|
|
|
|
|
}
|
2011-06-29 03:26:49 +02:00
|
|
|
};
|
|
|
|
|
|
2020-11-19 03:32:16 +01:00
|
|
|
class AstDisableFork final : public AstNodeStmt {
|
2020-06-30 02:22:39 +02:00
|
|
|
// A "disable fork" statement
|
|
|
|
|
public:
|
2020-12-23 21:21:33 +01:00
|
|
|
explicit AstDisableFork(FileLine* fl)
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_DisableFork(fl) {}
|
2020-06-30 02:22:39 +02:00
|
|
|
ASTNODE_NODE_FUNCS(DisableFork)
|
|
|
|
|
};
|
|
|
|
|
|
2020-11-19 03:32:16 +01:00
|
|
|
class AstWaitFork final : public AstNodeStmt {
|
2020-06-30 02:22:39 +02:00
|
|
|
// A "wait fork" statement
|
|
|
|
|
public:
|
2020-12-23 21:21:33 +01:00
|
|
|
explicit AstWaitFork(FileLine* fl)
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_WaitFork(fl) {}
|
2020-06-30 02:22:39 +02:00
|
|
|
ASTNODE_NODE_FUNCS(WaitFork)
|
|
|
|
|
};
|
|
|
|
|
|
2020-11-19 03:32:16 +01:00
|
|
|
class AstReturn final : public AstNodeStmt {
|
2014-09-12 03:28:53 +02:00
|
|
|
public:
|
2020-08-15 16:12:55 +02:00
|
|
|
explicit AstReturn(FileLine* fl, AstNode* lhsp = nullptr)
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_Return(fl) {
|
2019-05-19 22:13:13 +02:00
|
|
|
setNOp1p(lhsp);
|
2010-02-14 16:01:21 +01:00
|
|
|
}
|
2016-11-05 14:47:56 +01:00
|
|
|
ASTNODE_NODE_FUNCS(Return)
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual string verilogKwd() const override { return "return"; }
|
2019-05-19 22:13:13 +02:00
|
|
|
AstNode* lhsp() const { return op1p(); }
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual bool isBrancher() const override {
|
2020-04-15 13:58:34 +02:00
|
|
|
return true; // SPECIAL: We don't process code after breaks
|
|
|
|
|
}
|
2010-02-14 16:01:21 +01:00
|
|
|
};
|
|
|
|
|
|
2020-11-19 03:32:16 +01:00
|
|
|
class AstGenIf final : public AstNodeIf {
|
2014-09-12 03:28:53 +02:00
|
|
|
public:
|
2020-01-25 21:29:44 +01:00
|
|
|
AstGenIf(FileLine* fl, AstNode* condp, AstNode* ifsp, AstNode* elsesp)
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_GenIf(fl, condp, ifsp, elsesp) {}
|
2016-11-05 14:47:56 +01:00
|
|
|
ASTNODE_NODE_FUNCS(GenIf)
|
2006-08-26 13:35:28 +02:00
|
|
|
};
|
|
|
|
|
|
2020-11-19 03:32:16 +01:00
|
|
|
class AstIf final : public AstNodeIf {
|
2010-12-26 03:58:28 +01:00
|
|
|
private:
|
2020-04-15 13:58:34 +02:00
|
|
|
bool m_uniquePragma; // unique case
|
|
|
|
|
bool m_unique0Pragma; // unique0 case
|
|
|
|
|
bool m_priorityPragma; // priority case
|
2010-12-26 03:58:28 +01:00
|
|
|
public:
|
2020-08-15 16:12:55 +02:00
|
|
|
AstIf(FileLine* fl, AstNode* condp, AstNode* ifsp, AstNode* elsesp = nullptr)
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_If(fl, condp, ifsp, elsesp) {
|
2020-04-15 13:58:34 +02:00
|
|
|
m_uniquePragma = false;
|
|
|
|
|
m_unique0Pragma = false;
|
|
|
|
|
m_priorityPragma = false;
|
2006-08-26 13:35:28 +02:00
|
|
|
}
|
2016-11-05 14:47:56 +01:00
|
|
|
ASTNODE_NODE_FUNCS(If)
|
2019-05-19 22:13:13 +02:00
|
|
|
bool uniquePragma() const { return m_uniquePragma; }
|
|
|
|
|
void uniquePragma(bool flag) { m_uniquePragma = flag; }
|
|
|
|
|
bool unique0Pragma() const { return m_unique0Pragma; }
|
|
|
|
|
void unique0Pragma(bool flag) { m_unique0Pragma = flag; }
|
|
|
|
|
bool priorityPragma() const { return m_priorityPragma; }
|
|
|
|
|
void priorityPragma(bool flag) { m_priorityPragma = flag; }
|
2006-08-26 13:35:28 +02:00
|
|
|
};
|
|
|
|
|
|
2020-11-19 03:32:16 +01:00
|
|
|
class AstJumpBlock final : public AstNodeStmt {
|
2020-05-07 03:33:05 +02:00
|
|
|
// Block of code including a JumpGo and JumpLabel
|
2010-02-14 16:01:21 +01:00
|
|
|
// Parents: {statement list}
|
2020-05-07 03:33:05 +02:00
|
|
|
// Children: {statement list, with JumpGo and JumpLabel below}
|
2010-02-14 16:01:21 +01:00
|
|
|
private:
|
2020-12-23 21:21:33 +01:00
|
|
|
AstJumpLabel* m_labelp = nullptr; // [After V3Jump] Pointer to declaration
|
2020-08-15 19:11:27 +02:00
|
|
|
int m_labelNum = 0; // Set by V3EmitCSyms to tell final V3Emit what to increment
|
2010-02-14 16:01:21 +01:00
|
|
|
public:
|
2020-05-07 03:33:05 +02:00
|
|
|
// After construction must call ->labelp to associate with appropriate label
|
|
|
|
|
AstJumpBlock(FileLine* fl, AstNode* stmtsp)
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_JumpBlock(fl) {
|
2019-05-19 22:13:13 +02:00
|
|
|
addNOp1p(stmtsp);
|
2010-02-14 16:01:21 +01:00
|
|
|
}
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual const char* broken() const override;
|
|
|
|
|
virtual void cloneRelink() override;
|
2020-05-07 03:33:05 +02:00
|
|
|
ASTNODE_NODE_FUNCS(JumpBlock)
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual int instrCount() const override { return 0; }
|
|
|
|
|
virtual bool maybePointedTo() const override { return true; }
|
|
|
|
|
virtual bool same(const AstNode* samep) const override { return true; }
|
2010-02-14 16:01:21 +01:00
|
|
|
// op1 = Statements
|
2019-05-19 22:13:13 +02:00
|
|
|
AstNode* stmtsp() const { return op1p(); } // op1 = List of statements
|
2010-02-14 16:01:21 +01:00
|
|
|
void addStmtsp(AstNode* nodep) { addNOp1p(nodep); }
|
2020-05-07 03:33:05 +02:00
|
|
|
AstNode* endStmtsp() const { return op2p(); } // op1 = List of end-of-block
|
|
|
|
|
void addEndStmtsp(AstNode* nodep) { addNOp2p(nodep); }
|
2010-02-14 16:01:21 +01:00
|
|
|
int labelNum() const { return m_labelNum; }
|
2019-05-19 22:13:13 +02:00
|
|
|
void labelNum(int flag) { m_labelNum = flag; }
|
2020-05-07 03:33:05 +02:00
|
|
|
AstJumpLabel* labelp() const { return m_labelp; }
|
|
|
|
|
void labelp(AstJumpLabel* labelp) { m_labelp = labelp; }
|
|
|
|
|
};
|
|
|
|
|
|
2020-11-19 03:32:16 +01:00
|
|
|
class AstJumpLabel final : public AstNodeStmt {
|
2020-05-07 03:33:05 +02:00
|
|
|
// Jump point declaration
|
|
|
|
|
// Parents: {statement list with JumpBlock above}
|
|
|
|
|
// Children: none
|
|
|
|
|
private:
|
|
|
|
|
AstJumpBlock* m_blockp; // [After V3Jump] Pointer to declaration
|
|
|
|
|
public:
|
|
|
|
|
AstJumpLabel(FileLine* fl, AstJumpBlock* blockp)
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_JumpLabel(fl)
|
2020-08-16 17:40:42 +02:00
|
|
|
, m_blockp{blockp} {}
|
2020-05-07 03:33:05 +02:00
|
|
|
ASTNODE_NODE_FUNCS(JumpLabel)
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual bool maybePointedTo() const override { return true; }
|
|
|
|
|
virtual const char* broken() const override {
|
2020-05-07 03:33:05 +02:00
|
|
|
BROKEN_RTN(!blockp()->brokeExistsAbove());
|
|
|
|
|
BROKEN_RTN(blockp()->labelp() != this);
|
2020-08-15 16:12:55 +02:00
|
|
|
return nullptr;
|
2020-05-07 03:33:05 +02:00
|
|
|
}
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual void cloneRelink() override {
|
2020-05-07 03:33:05 +02:00
|
|
|
if (m_blockp->clonep()) m_blockp = m_blockp->clonep();
|
|
|
|
|
}
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual void dump(std::ostream& str) const override;
|
|
|
|
|
virtual int instrCount() const override { return 0; }
|
|
|
|
|
virtual bool same(const AstNode* samep) const override {
|
2020-05-07 03:33:05 +02:00
|
|
|
return blockp() == static_cast<const AstJumpLabel*>(samep)->blockp();
|
|
|
|
|
}
|
|
|
|
|
AstJumpBlock* blockp() const { return m_blockp; }
|
2010-02-14 16:01:21 +01:00
|
|
|
};
|
|
|
|
|
|
2020-11-19 03:32:16 +01:00
|
|
|
class AstJumpGo final : public AstNodeStmt {
|
2020-05-07 03:33:05 +02:00
|
|
|
// Jump point; branch down to a JumpLabel
|
|
|
|
|
// No support for backward jumps at present
|
|
|
|
|
// Parents: {statement list with JumpBlock above}
|
|
|
|
|
// Children: none
|
2010-02-14 16:01:21 +01:00
|
|
|
private:
|
2019-05-19 22:13:13 +02:00
|
|
|
AstJumpLabel* m_labelp; // [After V3Jump] Pointer to declaration
|
2010-02-14 16:01:21 +01:00
|
|
|
public:
|
|
|
|
|
AstJumpGo(FileLine* fl, AstJumpLabel* labelp)
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_JumpGo(fl)
|
2020-08-16 17:40:42 +02:00
|
|
|
, m_labelp{labelp} {}
|
2020-05-07 03:33:05 +02:00
|
|
|
ASTNODE_NODE_FUNCS(JumpGo);
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual const char* broken() const override {
|
2020-05-07 03:33:05 +02:00
|
|
|
BROKEN_RTN(!labelp()->brokeExistsBelow());
|
2020-08-15 16:12:55 +02:00
|
|
|
return nullptr;
|
2020-04-15 13:58:34 +02:00
|
|
|
}
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual void cloneRelink() override {
|
2020-04-15 13:58:34 +02:00
|
|
|
if (m_labelp->clonep()) m_labelp = m_labelp->clonep();
|
|
|
|
|
}
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual void dump(std::ostream& str) const override;
|
2021-07-25 14:32:36 +02:00
|
|
|
virtual int instrCount() const override { return INSTR_COUNT_BRANCH; }
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual bool same(const AstNode* samep) const override {
|
2020-04-15 13:58:34 +02:00
|
|
|
return labelp() == static_cast<const AstJumpGo*>(samep)->labelp();
|
|
|
|
|
}
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual bool isGateOptimizable() const override { return false; }
|
|
|
|
|
virtual bool isBrancher() const override {
|
2020-04-15 13:58:34 +02:00
|
|
|
return true; // SPECIAL: We don't process code after breaks
|
|
|
|
|
}
|
2010-02-14 16:01:21 +01:00
|
|
|
AstJumpLabel* labelp() const { return m_labelp; }
|
|
|
|
|
};
|
|
|
|
|
|
2020-11-19 03:32:16 +01:00
|
|
|
class AstChangeXor final : public AstNodeBiComAsv {
|
2006-08-26 13:35:28 +02:00
|
|
|
// A comparison to determine change detection, common & must be fast.
|
|
|
|
|
// Returns 32-bit or 64-bit value where 0 indicates no change.
|
|
|
|
|
// Parents: OR or LOGOR
|
|
|
|
|
// Children: VARREF
|
2014-09-12 03:28:53 +02:00
|
|
|
public:
|
2006-08-26 13:35:28 +02:00
|
|
|
AstChangeXor(FileLine* fl, AstNode* lhsp, AstNode* rhsp)
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_ChangeXor(fl, lhsp, rhsp) {
|
2019-05-19 22:13:13 +02:00
|
|
|
dtypeSetUInt32(); // Always used on, and returns word entities
|
2012-02-20 15:55:20 +01:00
|
|
|
}
|
2016-11-05 14:47:56 +01:00
|
|
|
ASTNODE_NODE_FUNCS(ChangeXor)
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual AstNode* cloneType(AstNode* lhsp, AstNode* rhsp) override {
|
2020-04-15 13:58:34 +02:00
|
|
|
return new AstChangeXor(this->fileline(), lhsp, rhsp);
|
|
|
|
|
}
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) override {
|
2020-04-15 13:58:34 +02:00
|
|
|
out.opChangeXor(lhs, rhs);
|
|
|
|
|
}
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual string emitVerilog() override { return "%k(%l %f^ %r)"; }
|
|
|
|
|
virtual string emitC() override { return "VL_CHANGEXOR_%li(%lw, %P, %li, %ri)"; }
|
|
|
|
|
virtual string emitSimpleOperator() override { return "^"; }
|
|
|
|
|
virtual bool cleanOut() const override { return false; } // Lclean && Rclean
|
|
|
|
|
virtual bool cleanLhs() const override { return true; }
|
|
|
|
|
virtual bool cleanRhs() const override { return true; }
|
|
|
|
|
virtual bool sizeMattersLhs() const override { return false; }
|
|
|
|
|
virtual bool sizeMattersRhs() const override { return false; }
|
|
|
|
|
virtual int instrCount() const override { return widthInstrs(); }
|
2006-08-26 13:35:28 +02:00
|
|
|
};
|
|
|
|
|
|
2020-11-19 03:32:16 +01:00
|
|
|
class AstChangeDet final : public AstNodeStmt {
|
2006-08-26 13:35:28 +02:00
|
|
|
// A comparison to determine change detection, common & must be fast.
|
|
|
|
|
public:
|
|
|
|
|
// Null lhs+rhs used to indicate change needed with no spec vars
|
2021-11-07 15:09:36 +01:00
|
|
|
AstChangeDet(FileLine* fl, AstNode* lhsp, AstNode* rhsp)
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_ChangeDet(fl) {
|
2020-04-15 13:58:34 +02:00
|
|
|
setNOp1p(lhsp);
|
|
|
|
|
setNOp2p(rhsp);
|
2012-04-29 16:14:13 +02:00
|
|
|
}
|
2016-11-05 14:47:56 +01:00
|
|
|
ASTNODE_NODE_FUNCS(ChangeDet)
|
2019-05-19 22:13:13 +02:00
|
|
|
AstNode* lhsp() const { return op1p(); }
|
|
|
|
|
AstNode* rhsp() const { return op2p(); }
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual bool isGateOptimizable() const override { return false; }
|
|
|
|
|
virtual bool isPredictOptimizable() const override { return false; }
|
2021-07-23 02:13:45 +02:00
|
|
|
virtual int instrCount() const override { return widthInstrs() * 2; } // xor, or/logor
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual bool same(const AstNode* samep) const override { return true; }
|
2006-08-26 13:35:28 +02:00
|
|
|
};
|
|
|
|
|
|
2020-11-19 03:32:16 +01:00
|
|
|
class AstConsAssoc final : public AstNodeMath {
|
2020-10-26 02:05:22 +01:00
|
|
|
// Construct an assoc array and return object, '{}
|
|
|
|
|
// Parents: math
|
|
|
|
|
// Children: expression (elements or other queues)
|
|
|
|
|
public:
|
|
|
|
|
AstConsAssoc(FileLine* fl, AstNode* defaultp)
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_ConsAssoc(fl) {
|
2020-10-26 02:05:22 +01:00
|
|
|
setNOp1p(defaultp);
|
|
|
|
|
}
|
|
|
|
|
ASTNODE_NODE_FUNCS(ConsAssoc)
|
|
|
|
|
virtual string emitVerilog() override { return "'{}"; }
|
|
|
|
|
virtual string emitC() override { V3ERROR_NA_RETURN(""); }
|
|
|
|
|
virtual string emitSimpleOperator() override { V3ERROR_NA_RETURN(""); }
|
|
|
|
|
virtual bool cleanOut() const override { return true; }
|
|
|
|
|
virtual int instrCount() const override { return widthInstrs(); }
|
|
|
|
|
AstNode* defaultp() const { return op1p(); }
|
|
|
|
|
virtual bool same(const AstNode* samep) const override { return true; }
|
|
|
|
|
};
|
2020-11-19 03:32:16 +01:00
|
|
|
class AstSetAssoc final : public AstNodeMath {
|
2020-10-26 02:05:22 +01:00
|
|
|
// Set an assoc array element and return object, '{}
|
|
|
|
|
// Parents: math
|
|
|
|
|
// Children: expression (elements or other queues)
|
|
|
|
|
public:
|
|
|
|
|
AstSetAssoc(FileLine* fl, AstNode* lhsp, AstNode* keyp, AstNode* valuep)
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_SetAssoc(fl) {
|
2020-10-26 02:05:22 +01:00
|
|
|
setOp1p(lhsp);
|
|
|
|
|
setNOp2p(keyp);
|
|
|
|
|
setOp3p(valuep);
|
|
|
|
|
}
|
|
|
|
|
ASTNODE_NODE_FUNCS(SetAssoc)
|
|
|
|
|
virtual string emitVerilog() override { return "'{}"; }
|
|
|
|
|
virtual string emitC() override { V3ERROR_NA_RETURN(""); }
|
|
|
|
|
virtual string emitSimpleOperator() override { V3ERROR_NA_RETURN(""); }
|
|
|
|
|
virtual bool cleanOut() const override { return true; }
|
|
|
|
|
virtual int instrCount() const override { return widthInstrs(); }
|
|
|
|
|
AstNode* lhsp() const { return op1p(); }
|
|
|
|
|
AstNode* keyp() const { return op2p(); }
|
|
|
|
|
AstNode* valuep() const { return op3p(); }
|
|
|
|
|
virtual bool same(const AstNode* samep) const override { return true; }
|
|
|
|
|
};
|
|
|
|
|
|
2020-11-19 03:32:16 +01:00
|
|
|
class AstConsDynArray final : public AstNodeMath {
|
2020-11-01 16:18:32 +01:00
|
|
|
// Construct a queue and return object, '{}. '{lhs}, '{lhs. rhs}
|
|
|
|
|
// Parents: math
|
|
|
|
|
// Children: expression (elements or other queues)
|
|
|
|
|
public:
|
2020-12-23 21:21:33 +01:00
|
|
|
explicit AstConsDynArray(FileLine* fl, AstNode* lhsp = nullptr, AstNode* rhsp = nullptr)
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_ConsDynArray(fl) {
|
2020-11-01 16:18:32 +01:00
|
|
|
setNOp1p(lhsp);
|
|
|
|
|
setNOp2p(rhsp);
|
|
|
|
|
}
|
|
|
|
|
ASTNODE_NODE_FUNCS(ConsDynArray)
|
|
|
|
|
virtual string emitVerilog() override { return "'{%l, %r}"; }
|
|
|
|
|
virtual string emitC() override { V3ERROR_NA_RETURN(""); }
|
|
|
|
|
virtual string emitSimpleOperator() override { V3ERROR_NA_RETURN(""); }
|
|
|
|
|
virtual bool cleanOut() const override { return true; }
|
|
|
|
|
virtual int instrCount() const override { return widthInstrs(); }
|
|
|
|
|
AstNode* lhsp() const { return op1p(); } // op1 = expression
|
|
|
|
|
AstNode* rhsp() const { return op2p(); } // op2 = expression
|
|
|
|
|
virtual bool same(const AstNode* samep) const override { return true; }
|
|
|
|
|
};
|
|
|
|
|
|
2020-11-19 03:32:16 +01:00
|
|
|
class AstConsQueue final : public AstNodeMath {
|
2020-10-18 19:23:02 +02:00
|
|
|
// Construct a queue and return object, '{}. '{lhs}, '{lhs. rhs}
|
|
|
|
|
// Parents: math
|
|
|
|
|
// Children: expression (elements or other queues)
|
|
|
|
|
public:
|
2020-12-23 21:21:33 +01:00
|
|
|
explicit AstConsQueue(FileLine* fl, AstNode* lhsp = nullptr, AstNode* rhsp = nullptr)
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_ConsQueue(fl) {
|
2020-10-18 19:23:02 +02:00
|
|
|
setNOp1p(lhsp);
|
|
|
|
|
setNOp2p(rhsp);
|
|
|
|
|
}
|
|
|
|
|
ASTNODE_NODE_FUNCS(ConsQueue)
|
|
|
|
|
virtual string emitVerilog() override { return "'{%l, %r}"; }
|
|
|
|
|
virtual string emitC() override { V3ERROR_NA_RETURN(""); }
|
|
|
|
|
virtual string emitSimpleOperator() override { V3ERROR_NA_RETURN(""); }
|
|
|
|
|
virtual bool cleanOut() const override { return true; }
|
|
|
|
|
virtual int instrCount() const override { return widthInstrs(); }
|
|
|
|
|
AstNode* lhsp() const { return op1p(); } // op1 = expression
|
|
|
|
|
AstNode* rhsp() const { return op2p(); } // op2 = expression
|
|
|
|
|
virtual bool same(const AstNode* samep) const override { return true; }
|
|
|
|
|
};
|
|
|
|
|
|
2020-11-19 03:32:16 +01:00
|
|
|
class AstBegin final : public AstNodeBlock {
|
2012-07-21 13:28:39 +02:00
|
|
|
// A Begin/end named block, only exists shortly after parsing until linking
|
|
|
|
|
// Parents: statement
|
|
|
|
|
// Children: statements
|
|
|
|
|
private:
|
2020-04-15 13:58:34 +02:00
|
|
|
bool m_generate; // Underneath a generate
|
2021-11-26 23:55:36 +01:00
|
|
|
const bool m_implied; // Not inserted by user
|
2012-07-21 13:28:39 +02:00
|
|
|
public:
|
|
|
|
|
// Node that simply puts name into the output stream
|
2020-02-26 04:21:16 +01:00
|
|
|
AstBegin(FileLine* fl, const string& name, AstNode* stmtsp, bool generate = false,
|
|
|
|
|
bool implied = false)
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_Begin(fl, name, stmtsp)
|
2020-08-16 17:40:42 +02:00
|
|
|
, m_generate{generate}
|
|
|
|
|
, m_implied{implied} {}
|
2016-11-05 14:47:56 +01:00
|
|
|
ASTNODE_NODE_FUNCS(Begin)
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual void dump(std::ostream& str) const override;
|
2020-04-23 03:31:40 +02:00
|
|
|
// op1p is statements in NodeBlock
|
2019-05-19 22:13:13 +02:00
|
|
|
AstNode* genforp() const { return op2p(); } // op2 = GENFOR, if applicable,
|
2012-07-21 23:12:42 +02:00
|
|
|
// might NOT be a GenFor, as loop unrolling replaces with Begin
|
|
|
|
|
void addGenforp(AstGenFor* nodep) { addOp2p(nodep); }
|
2012-07-21 13:28:39 +02:00
|
|
|
void generate(bool flag) { m_generate = flag; }
|
|
|
|
|
bool generate() const { return m_generate; }
|
2020-02-26 04:21:16 +01:00
|
|
|
bool implied() const { return m_implied; }
|
2012-07-21 13:28:39 +02:00
|
|
|
};
|
|
|
|
|
|
2020-11-19 03:32:16 +01:00
|
|
|
class AstFork final : public AstNodeBlock {
|
2020-04-23 03:31:40 +02:00
|
|
|
// A fork named block
|
|
|
|
|
// Parents: statement
|
|
|
|
|
// Children: statements
|
|
|
|
|
private:
|
|
|
|
|
VJoinType m_joinType; // Join keyword type
|
|
|
|
|
public:
|
|
|
|
|
// Node that simply puts name into the output stream
|
|
|
|
|
AstFork(FileLine* fl, const string& name, AstNode* stmtsp)
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_Fork(fl, name, stmtsp) {}
|
2020-04-23 03:31:40 +02:00
|
|
|
ASTNODE_NODE_FUNCS(Fork)
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual void dump(std::ostream& str) const override;
|
2020-04-23 03:31:40 +02:00
|
|
|
VJoinType joinType() const { return m_joinType; }
|
|
|
|
|
void joinType(const VJoinType& flag) { m_joinType = flag; }
|
|
|
|
|
};
|
|
|
|
|
|
2020-11-19 03:32:16 +01:00
|
|
|
class AstInside final : public AstNodeMath {
|
2014-09-12 03:28:53 +02:00
|
|
|
public:
|
2013-02-02 18:55:28 +01:00
|
|
|
AstInside(FileLine* fl, AstNode* exprp, AstNode* itemsp)
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_Inside(fl) {
|
2020-04-15 13:58:34 +02:00
|
|
|
addOp1p(exprp);
|
|
|
|
|
addOp2p(itemsp);
|
2020-11-29 14:23:36 +01:00
|
|
|
dtypeSetBit();
|
2013-02-02 18:55:28 +01:00
|
|
|
}
|
2016-11-05 14:47:56 +01:00
|
|
|
ASTNODE_NODE_FUNCS(Inside)
|
2019-05-19 22:13:13 +02:00
|
|
|
AstNode* exprp() const { return op1p(); } // op1 = LHS expression to compare with
|
2020-04-15 13:58:34 +02:00
|
|
|
// op2 = RHS, possibly a list of expr or AstInsideRange
|
|
|
|
|
AstNode* itemsp() const { return op2p(); }
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual string emitVerilog() override { return "%l inside { %r }"; }
|
|
|
|
|
virtual string emitC() override { V3ERROR_NA_RETURN(""); }
|
|
|
|
|
virtual bool cleanOut() const override { return false; } // NA
|
2013-02-02 18:55:28 +01:00
|
|
|
};
|
|
|
|
|
|
2020-11-19 03:32:16 +01:00
|
|
|
class AstInsideRange final : public AstNodeMath {
|
2014-09-12 03:28:53 +02:00
|
|
|
public:
|
2013-02-02 18:55:28 +01:00
|
|
|
AstInsideRange(FileLine* fl, AstNode* lhsp, AstNode* rhsp)
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_InsideRange(fl) {
|
2020-04-15 13:58:34 +02:00
|
|
|
addOp1p(lhsp);
|
|
|
|
|
addOp2p(rhsp);
|
2013-02-02 18:55:28 +01:00
|
|
|
}
|
2016-11-05 14:47:56 +01:00
|
|
|
ASTNODE_NODE_FUNCS(InsideRange)
|
2019-05-19 22:13:13 +02:00
|
|
|
AstNode* lhsp() const { return op1p(); } // op1 = LHS
|
|
|
|
|
AstNode* rhsp() const { return op2p(); } // op2 = RHS
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual string emitVerilog() override { return "[%l:%r]"; }
|
|
|
|
|
virtual string emitC() override { V3ERROR_NA_RETURN(""); }
|
|
|
|
|
virtual bool cleanOut() const override { return false; } // NA
|
2020-03-31 00:12:50 +02:00
|
|
|
// Create AstAnd(AstGte(...), AstLte(...))
|
|
|
|
|
AstNode* newAndFromInside(AstNode* exprp, AstNode* lhsp, AstNode* rhsp);
|
2013-02-02 18:55:28 +01:00
|
|
|
};
|
|
|
|
|
|
2020-11-19 03:32:16 +01:00
|
|
|
class AstInitItem final : public AstNode {
|
2019-11-09 21:34:41 +01:00
|
|
|
// Container for a item in an init array
|
|
|
|
|
// This container is present so that the value underneath may get replaced with a new nodep
|
|
|
|
|
// and the upper AstInitArray's map will remain correct (pointing to this InitItem)
|
|
|
|
|
public:
|
|
|
|
|
// Parents: INITARRAY
|
|
|
|
|
AstInitItem(FileLine* fl, AstNode* valuep)
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_InitItem(fl) {
|
2020-04-15 13:58:34 +02:00
|
|
|
addOp1p(valuep);
|
|
|
|
|
}
|
2019-11-09 21:34:41 +01:00
|
|
|
ASTNODE_NODE_FUNCS(InitItem)
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual bool maybePointedTo() const override { return true; }
|
|
|
|
|
virtual bool hasDType() const override { return false; } // See valuep()'s dtype instead
|
2019-11-09 21:34:41 +01:00
|
|
|
AstNode* valuep() const { return op1p(); } // op1 = Value
|
|
|
|
|
void valuep(AstNode* nodep) { addOp1p(nodep); }
|
|
|
|
|
};
|
|
|
|
|
|
2020-11-19 03:32:16 +01:00
|
|
|
class AstInitArray final : public AstNode {
|
2019-11-09 21:34:41 +01:00
|
|
|
// Set a var to a map of values
|
|
|
|
|
// The list of initsp() is not relevant
|
2016-06-16 04:46:34 +02:00
|
|
|
// If default is specified, the vector may be sparse, and not provide each value.
|
2019-11-09 21:34:41 +01:00
|
|
|
// Key values are C++ array style, with lo() at index 0
|
2006-08-26 13:35:28 +02:00
|
|
|
// Parents: ASTVAR::init()
|
2019-11-09 21:34:41 +01:00
|
|
|
// Children: AstInitItem
|
|
|
|
|
public:
|
2021-12-11 17:29:01 +01:00
|
|
|
using KeyItemMap = std::map<vluint64_t, AstInitItem*>;
|
2020-04-15 13:58:34 +02:00
|
|
|
|
2019-11-09 21:34:41 +01:00
|
|
|
private:
|
|
|
|
|
KeyItemMap m_map; // Node value for each array index
|
2014-09-12 03:28:53 +02:00
|
|
|
public:
|
2021-12-11 17:29:01 +01:00
|
|
|
AstInitArray(FileLine* fl, AstNodeDType* newDTypep, AstNode* defaultp)
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_InitArray(fl) {
|
2019-05-19 22:13:13 +02:00
|
|
|
dtypep(newDTypep);
|
|
|
|
|
addNOp1p(defaultp);
|
2006-08-26 13:35:28 +02:00
|
|
|
}
|
2016-11-05 14:47:56 +01:00
|
|
|
ASTNODE_NODE_FUNCS(InitArray)
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual void dump(std::ostream& str) const override;
|
|
|
|
|
virtual const char* broken() const override {
|
2019-11-09 21:34:41 +01:00
|
|
|
for (KeyItemMap::const_iterator it = m_map.begin(); it != m_map.end(); ++it) {
|
2021-10-22 18:36:58 +02:00
|
|
|
BROKEN_RTN(!it->second);
|
2019-11-09 21:34:41 +01:00
|
|
|
BROKEN_RTN(!it->second->brokeExists());
|
|
|
|
|
}
|
2020-08-15 16:12:55 +02:00
|
|
|
return nullptr;
|
2019-11-09 21:34:41 +01:00
|
|
|
}
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual void cloneRelink() override {
|
2019-11-09 21:34:41 +01:00
|
|
|
for (KeyItemMap::iterator it = m_map.begin(); it != m_map.end(); ++it) {
|
|
|
|
|
if (it->second->clonep()) it->second = it->second->clonep();
|
|
|
|
|
}
|
|
|
|
|
}
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual bool hasDType() const override { return true; }
|
|
|
|
|
virtual bool same(const AstNode* samep) const override {
|
2019-11-09 21:34:41 +01:00
|
|
|
// Only works if exact same children, instead should override comparison
|
|
|
|
|
// of children list, and instead use map-vs-map key/value compare
|
|
|
|
|
return m_map == static_cast<const AstInitArray*>(samep)->m_map;
|
|
|
|
|
}
|
|
|
|
|
AstNode* defaultp() const { return op1p(); } // op1 = Default if sparse
|
|
|
|
|
void defaultp(AstNode* newp) { setOp1p(newp); }
|
|
|
|
|
AstNode* initsp() const { return op2p(); } // op2 = Initial value expressions
|
|
|
|
|
void addValuep(AstNode* newp) { addIndexValuep(m_map.size(), newp); }
|
|
|
|
|
const KeyItemMap& map() const { return m_map; }
|
2021-12-11 17:29:01 +01:00
|
|
|
AstNode* addIndexValuep(vluint64_t index, AstNode* newp) {
|
2019-11-09 21:34:41 +01:00
|
|
|
// Returns old value, caller must garbage collect
|
2020-08-15 16:12:55 +02:00
|
|
|
AstNode* oldp = nullptr;
|
2020-08-16 17:43:49 +02:00
|
|
|
const auto it = m_map.find(index);
|
2019-11-09 21:34:41 +01:00
|
|
|
if (it != m_map.end()) {
|
|
|
|
|
oldp = it->second->valuep();
|
|
|
|
|
it->second->valuep(newp);
|
|
|
|
|
} else {
|
2021-11-26 23:55:36 +01:00
|
|
|
AstInitItem* const itemp = new AstInitItem(fileline(), newp);
|
2020-12-19 00:24:47 +01:00
|
|
|
m_map.emplace(index, itemp);
|
2019-11-09 21:34:41 +01:00
|
|
|
addOp2p(itemp);
|
|
|
|
|
}
|
|
|
|
|
return oldp;
|
|
|
|
|
}
|
2021-12-11 17:29:01 +01:00
|
|
|
AstNode* getIndexValuep(vluint64_t index) const {
|
2020-08-16 17:43:49 +02:00
|
|
|
const auto it = m_map.find(index);
|
2020-04-15 13:58:34 +02:00
|
|
|
if (it == m_map.end()) {
|
2020-08-15 16:12:55 +02:00
|
|
|
return nullptr;
|
2020-04-15 13:58:34 +02:00
|
|
|
} else {
|
|
|
|
|
return it->second->valuep();
|
|
|
|
|
}
|
2019-11-09 21:34:41 +01:00
|
|
|
}
|
2021-12-11 17:29:01 +01:00
|
|
|
AstNode* getIndexDefaultedValuep(vluint64_t index) const {
|
2019-11-09 21:34:41 +01:00
|
|
|
AstNode* valuep = getIndexValuep(index);
|
|
|
|
|
if (!valuep) valuep = defaultp();
|
|
|
|
|
return valuep;
|
|
|
|
|
}
|
2006-08-26 13:35:28 +02:00
|
|
|
};
|
|
|
|
|
|
2020-11-19 03:32:16 +01:00
|
|
|
class AstNew final : public AstNodeFTaskRef {
|
2020-03-06 04:33:31 +01:00
|
|
|
// New as constructor
|
|
|
|
|
// Don't need the class we are extracting from, as the "fromp()"'s datatype can get us to it
|
2019-12-23 21:03:04 +01:00
|
|
|
// Parents: math|stmt
|
|
|
|
|
// Children: varref|arraysel, math
|
|
|
|
|
public:
|
2020-04-13 00:57:12 +02:00
|
|
|
AstNew(FileLine* fl, AstNode* pinsp)
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_New(fl, false, "new", pinsp) {}
|
2019-12-23 21:03:04 +01:00
|
|
|
ASTNODE_NODE_FUNCS(New)
|
|
|
|
|
virtual bool cleanOut() const { return true; }
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual bool same(const AstNode* samep) const override { return true; }
|
|
|
|
|
virtual bool hasDType() const override { return true; }
|
|
|
|
|
virtual int instrCount() const override { return widthInstrs(); }
|
2020-03-06 04:33:31 +01:00
|
|
|
};
|
|
|
|
|
|
2020-11-19 03:32:16 +01:00
|
|
|
class AstNewCopy final : public AstNodeMath {
|
2020-03-06 04:33:31 +01:00
|
|
|
// New as shallow copy
|
|
|
|
|
// Parents: math|stmt
|
|
|
|
|
// Children: varref|arraysel, math
|
|
|
|
|
public:
|
|
|
|
|
AstNewCopy(FileLine* fl, AstNode* rhsp)
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_NewCopy(fl) {
|
2020-03-06 04:33:31 +01:00
|
|
|
dtypeFrom(rhsp); // otherwise V3Width will resolve
|
|
|
|
|
setNOp1p(rhsp);
|
|
|
|
|
}
|
|
|
|
|
ASTNODE_NODE_FUNCS(NewCopy)
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual string emitVerilog() override { return "new"; }
|
|
|
|
|
virtual string emitC() override { V3ERROR_NA_RETURN(""); }
|
|
|
|
|
virtual bool cleanOut() const override { return true; }
|
|
|
|
|
virtual bool same(const AstNode* samep) const override { return true; }
|
|
|
|
|
virtual int instrCount() const override { return widthInstrs(); }
|
2020-03-06 04:33:31 +01:00
|
|
|
AstNode* rhsp() const { return op1p(); }
|
|
|
|
|
};
|
|
|
|
|
|
2020-11-19 03:32:16 +01:00
|
|
|
class AstNewDynamic final : public AstNodeMath {
|
2020-03-06 04:33:31 +01:00
|
|
|
// New for dynamic array
|
|
|
|
|
// Parents: math|stmt
|
|
|
|
|
// Children: varref|arraysel, math
|
|
|
|
|
public:
|
|
|
|
|
AstNewDynamic(FileLine* fl, AstNode* sizep, AstNode* rhsp)
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_NewDynamic(fl) {
|
2020-03-06 04:33:31 +01:00
|
|
|
dtypeFrom(rhsp); // otherwise V3Width will resolve
|
|
|
|
|
setNOp1p(sizep);
|
|
|
|
|
setNOp2p(rhsp);
|
|
|
|
|
}
|
|
|
|
|
ASTNODE_NODE_FUNCS(NewDynamic)
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual string emitVerilog() override { return "new"; }
|
|
|
|
|
virtual string emitC() override { V3ERROR_NA_RETURN(""); }
|
|
|
|
|
virtual bool cleanOut() const override { return true; }
|
|
|
|
|
virtual bool same(const AstNode* samep) const override { return true; }
|
|
|
|
|
virtual int instrCount() const override { return widthInstrs(); }
|
2020-03-06 13:31:56 +01:00
|
|
|
AstNode* sizep() const { return op1p(); }
|
2020-03-06 04:33:31 +01:00
|
|
|
AstNode* rhsp() const { return op2p(); }
|
2019-12-23 21:03:04 +01:00
|
|
|
};
|
|
|
|
|
|
2020-11-19 03:32:16 +01:00
|
|
|
class AstPragma final : public AstNode {
|
2006-08-26 13:35:28 +02:00
|
|
|
private:
|
2021-11-26 23:55:36 +01:00
|
|
|
const AstPragmaType m_pragType; // Type of pragma
|
2006-08-26 13:35:28 +02:00
|
|
|
public:
|
|
|
|
|
// Pragmas don't result in any output code, they're just flags that affect
|
|
|
|
|
// other processing in verilator.
|
|
|
|
|
AstPragma(FileLine* fl, AstPragmaType pragType)
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_Pragma(fl)
|
2020-08-16 17:40:42 +02:00
|
|
|
, m_pragType{pragType} {}
|
2016-11-05 14:47:56 +01:00
|
|
|
ASTNODE_NODE_FUNCS(Pragma)
|
2019-05-19 22:13:13 +02:00
|
|
|
AstPragmaType pragType() const { return m_pragType; } // *=type of the pragma
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual bool isPredictOptimizable() const override { return false; }
|
|
|
|
|
virtual bool same(const AstNode* samep) const override {
|
2020-04-15 13:58:34 +02:00
|
|
|
return pragType() == static_cast<const AstPragma*>(samep)->pragType();
|
|
|
|
|
}
|
2006-08-26 13:35:28 +02:00
|
|
|
};
|
|
|
|
|
|
2020-11-19 03:32:16 +01:00
|
|
|
class AstPrintTimeScale final : public AstNodeStmt {
|
2020-04-16 01:39:03 +02:00
|
|
|
// Parents: stmtlist
|
|
|
|
|
string m_name; // Parent module name
|
|
|
|
|
VTimescale m_timeunit; // Parent module time unit
|
|
|
|
|
public:
|
2020-12-23 21:21:33 +01:00
|
|
|
explicit AstPrintTimeScale(FileLine* fl)
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_PrintTimeScale(fl) {}
|
2020-04-16 01:39:03 +02:00
|
|
|
ASTNODE_NODE_FUNCS(PrintTimeScale)
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual void name(const string& name) override { m_name = name; }
|
|
|
|
|
virtual string name() const override { return m_name; } // * = Var name
|
|
|
|
|
virtual void dump(std::ostream& str) const override;
|
|
|
|
|
virtual string verilogKwd() const override { return "$printtimescale"; }
|
|
|
|
|
virtual bool isGateOptimizable() const override { return false; }
|
|
|
|
|
virtual bool isPredictOptimizable() const override { return false; }
|
|
|
|
|
virtual bool isPure() const override { return false; }
|
|
|
|
|
virtual bool isOutputter() const override { return true; }
|
2021-07-25 14:32:36 +02:00
|
|
|
virtual int instrCount() const override { return INSTR_COUNT_PLI; }
|
2020-04-16 01:39:03 +02:00
|
|
|
void timeunit(const VTimescale& flag) { m_timeunit = flag; }
|
|
|
|
|
VTimescale timeunit() const { return m_timeunit; }
|
|
|
|
|
};
|
|
|
|
|
|
2020-11-19 03:32:16 +01:00
|
|
|
class AstStop final : public AstNodeStmt {
|
2014-09-12 03:28:53 +02:00
|
|
|
public:
|
2020-01-25 21:29:44 +01:00
|
|
|
AstStop(FileLine* fl, bool maybe)
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_Stop(fl) {}
|
2016-11-05 14:47:56 +01:00
|
|
|
ASTNODE_NODE_FUNCS(Stop)
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual bool isGateOptimizable() const override { return false; }
|
|
|
|
|
virtual bool isPredictOptimizable() const override { return false; }
|
|
|
|
|
virtual bool isPure() const override {
|
|
|
|
|
return false;
|
|
|
|
|
} // SPECIAL: $display has 'visual' ordering
|
|
|
|
|
virtual bool isOutputter() const override { return true; } // SPECIAL: $display makes output
|
|
|
|
|
virtual bool isUnlikely() const override { return true; }
|
|
|
|
|
virtual int instrCount() const override { return 0; } // Rarely executes
|
|
|
|
|
virtual bool same(const AstNode* samep) const override {
|
|
|
|
|
return fileline() == samep->fileline();
|
|
|
|
|
}
|
2006-08-26 13:35:28 +02:00
|
|
|
};
|
|
|
|
|
|
2020-11-19 03:32:16 +01:00
|
|
|
class AstFinish final : public AstNodeStmt {
|
2014-09-12 03:28:53 +02:00
|
|
|
public:
|
2015-10-04 04:33:06 +02:00
|
|
|
explicit AstFinish(FileLine* fl)
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_Finish(fl) {}
|
2016-11-05 14:47:56 +01:00
|
|
|
ASTNODE_NODE_FUNCS(Finish)
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual bool isGateOptimizable() const override { return false; }
|
|
|
|
|
virtual bool isPredictOptimizable() const override { return false; }
|
|
|
|
|
virtual bool isPure() const override {
|
|
|
|
|
return false;
|
|
|
|
|
} // SPECIAL: $display has 'visual' ordering
|
|
|
|
|
virtual bool isOutputter() const override { return true; } // SPECIAL: $display makes output
|
|
|
|
|
virtual bool isUnlikely() const override { return true; }
|
|
|
|
|
virtual int instrCount() const override { return 0; } // Rarely executes
|
|
|
|
|
virtual bool same(const AstNode* samep) const override {
|
|
|
|
|
return fileline() == samep->fileline();
|
|
|
|
|
}
|
2006-08-26 13:35:28 +02:00
|
|
|
};
|
|
|
|
|
|
2020-11-19 03:32:16 +01:00
|
|
|
class AstNullCheck final : public AstNodeUniop {
|
2020-04-05 15:30:23 +02:00
|
|
|
// Return LHS after checking that LHS is non-null
|
|
|
|
|
// Children: VarRef or something returning pointer
|
|
|
|
|
public:
|
|
|
|
|
AstNullCheck(FileLine* fl, AstNode* lhsp)
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_NullCheck(fl, lhsp) {
|
2020-04-05 15:30:23 +02:00
|
|
|
dtypeFrom(lhsp);
|
|
|
|
|
}
|
|
|
|
|
ASTNODE_NODE_FUNCS(NullCheck)
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual void numberOperate(V3Number& out, const V3Number& lhs) override { V3ERROR_NA; }
|
|
|
|
|
virtual int instrCount() const override { return 1; } // Rarely executes
|
|
|
|
|
virtual string emitVerilog() override { return "%l"; }
|
|
|
|
|
virtual string emitC() override { V3ERROR_NA_RETURN(""); }
|
|
|
|
|
virtual string emitSimpleOperator() override { V3ERROR_NA_RETURN(""); }
|
|
|
|
|
virtual bool cleanOut() const override { return true; }
|
|
|
|
|
virtual bool cleanLhs() const override { return true; }
|
|
|
|
|
virtual bool sizeMattersLhs() const override { return false; }
|
|
|
|
|
virtual bool same(const AstNode* samep) const override {
|
|
|
|
|
return fileline() == samep->fileline();
|
|
|
|
|
}
|
2020-04-05 15:30:23 +02:00
|
|
|
};
|
|
|
|
|
|
2020-11-19 03:32:16 +01:00
|
|
|
class AstTimingControl final : public AstNodeStmt {
|
2020-06-06 21:54:44 +02:00
|
|
|
// Parents: stmtlist
|
|
|
|
|
public:
|
|
|
|
|
AstTimingControl(FileLine* fl, AstSenTree* sensesp, AstNode* stmtsp)
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_TimingControl(fl) {
|
2020-06-06 21:54:44 +02:00
|
|
|
setNOp1p(sensesp);
|
|
|
|
|
setNOp2p(stmtsp);
|
|
|
|
|
}
|
|
|
|
|
ASTNODE_NODE_FUNCS(TimingControl)
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual string verilogKwd() const override { return "@(%l) %r"; }
|
|
|
|
|
virtual bool isGateOptimizable() const override { return false; }
|
|
|
|
|
virtual bool isPredictOptimizable() const override { return false; }
|
|
|
|
|
virtual bool isPure() const override { return false; }
|
|
|
|
|
virtual bool isOutputter() const override { return false; }
|
|
|
|
|
virtual int instrCount() const override { return 0; }
|
2021-10-22 14:56:48 +02:00
|
|
|
AstSenTree* sensesp() const { return VN_AS(op1p(), SenTree); }
|
2020-06-06 21:54:44 +02:00
|
|
|
AstNode* stmtsp() const { return op2p(); }
|
|
|
|
|
};
|
|
|
|
|
|
2020-11-19 03:32:16 +01:00
|
|
|
class AstTimeFormat final : public AstNodeStmt {
|
2020-04-16 01:39:03 +02:00
|
|
|
// Parents: stmtlist
|
|
|
|
|
public:
|
|
|
|
|
AstTimeFormat(FileLine* fl, AstNode* unitsp, AstNode* precisionp, AstNode* suffixp,
|
|
|
|
|
AstNode* widthp)
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_TimeFormat(fl) {
|
2020-04-16 01:39:03 +02:00
|
|
|
setOp1p(unitsp);
|
|
|
|
|
setOp2p(precisionp);
|
|
|
|
|
setOp3p(suffixp);
|
|
|
|
|
setOp4p(widthp);
|
|
|
|
|
}
|
|
|
|
|
ASTNODE_NODE_FUNCS(TimeFormat)
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual string verilogKwd() const override { return "$timeformat"; }
|
|
|
|
|
virtual bool isGateOptimizable() const override { return false; }
|
|
|
|
|
virtual bool isPredictOptimizable() const override { return false; }
|
|
|
|
|
virtual bool isPure() const override { return false; }
|
|
|
|
|
virtual bool isOutputter() const override { return true; }
|
2021-07-25 14:32:36 +02:00
|
|
|
virtual int instrCount() const override { return INSTR_COUNT_PLI; }
|
2020-04-16 01:39:03 +02:00
|
|
|
AstNode* unitsp() const { return op1p(); }
|
|
|
|
|
AstNode* precisionp() const { return op2p(); }
|
|
|
|
|
AstNode* suffixp() const { return op3p(); }
|
|
|
|
|
AstNode* widthp() const { return op4p(); }
|
|
|
|
|
};
|
|
|
|
|
|
2020-11-19 03:32:16 +01:00
|
|
|
class AstTraceDecl final : public AstNodeStmt {
|
2006-08-26 13:35:28 +02:00
|
|
|
// Trace point declaration
|
|
|
|
|
// Separate from AstTraceInc; as a declaration can't be deleted
|
|
|
|
|
// Parents: {statement list}
|
2020-05-09 00:42:34 +02:00
|
|
|
// Children: expression being traced
|
2006-08-26 13:35:28 +02:00
|
|
|
private:
|
2020-08-15 19:11:27 +02:00
|
|
|
uint32_t m_code = 0; // Trace identifier code; converted to ASCII by trace routines
|
2020-05-09 12:38:32 +02:00
|
|
|
const string m_showname; // Name of variable
|
|
|
|
|
const VNumRange m_bitRange; // Property of var the trace details
|
|
|
|
|
const VNumRange m_arrayRange; // Property of var the trace details
|
|
|
|
|
const uint32_t m_codeInc; // Code increment
|
|
|
|
|
const AstVarType m_varType; // Type of variable (for localparam vs. param)
|
|
|
|
|
const AstBasicDTypeKwd m_declKwd; // Keyword at declaration time
|
|
|
|
|
const VDirection m_declDirection; // Declared direction input/output etc
|
|
|
|
|
const bool m_isScoped; // Uses run-time scope (for interfaces)
|
2006-08-26 13:35:28 +02:00
|
|
|
public:
|
2018-10-04 01:51:05 +02:00
|
|
|
AstTraceDecl(FileLine* fl, const string& showname,
|
|
|
|
|
AstVar* varp, // For input/output state etc
|
2020-04-15 13:58:34 +02:00
|
|
|
AstNode* valuep, const VNumRange& bitRange, const VNumRange& arrayRange,
|
2019-12-07 15:42:09 +01:00
|
|
|
bool isScoped)
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_TraceDecl(fl)
|
2020-08-16 17:40:42 +02:00
|
|
|
, m_showname{showname}
|
|
|
|
|
, m_bitRange{bitRange}
|
|
|
|
|
, m_arrayRange{arrayRange}
|
2020-05-09 12:38:32 +02:00
|
|
|
, m_codeInc(
|
|
|
|
|
((arrayRange.ranged() ? arrayRange.elements() : 1) * valuep->dtypep()->widthWords()
|
|
|
|
|
* (VL_EDATASIZE / 32))) // A code is always 32-bits
|
2020-08-16 17:40:42 +02:00
|
|
|
, m_varType{varp->varType()}
|
|
|
|
|
, m_declKwd{varp->declKwd()}
|
|
|
|
|
, m_declDirection{varp->declDirection()}
|
|
|
|
|
, m_isScoped{isScoped} {
|
2019-05-19 22:13:13 +02:00
|
|
|
dtypeFrom(valuep);
|
2020-05-09 00:42:34 +02:00
|
|
|
addNOp1p(valuep);
|
2006-08-26 13:35:28 +02:00
|
|
|
}
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual int instrCount() const override { return 100; } // Large...
|
2016-11-05 14:47:56 +01:00
|
|
|
ASTNODE_NODE_FUNCS(TraceDecl)
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual string name() const override { return m_showname; }
|
|
|
|
|
virtual bool maybePointedTo() const override { return true; }
|
|
|
|
|
virtual bool hasDType() const override { return true; }
|
|
|
|
|
virtual bool same(const AstNode* samep) const override { return false; }
|
2019-05-19 22:13:13 +02:00
|
|
|
string showname() const { return m_showname; } // * = Var name
|
2006-08-26 13:35:28 +02:00
|
|
|
// Details on what we're tracing
|
2018-10-04 01:51:05 +02:00
|
|
|
uint32_t code() const { return m_code; }
|
2019-05-19 22:13:13 +02:00
|
|
|
void code(uint32_t code) { m_code = code; }
|
2018-10-04 01:51:05 +02:00
|
|
|
uint32_t codeInc() const { return m_codeInc; }
|
2013-12-14 18:17:31 +01:00
|
|
|
const VNumRange& bitRange() const { return m_bitRange; }
|
|
|
|
|
const VNumRange& arrayRange() const { return m_arrayRange; }
|
2018-10-04 01:51:05 +02:00
|
|
|
AstVarType varType() const { return m_varType; }
|
2018-10-05 02:24:41 +02:00
|
|
|
AstBasicDTypeKwd declKwd() const { return m_declKwd; }
|
2018-10-27 23:29:00 +02:00
|
|
|
VDirection declDirection() const { return m_declDirection; }
|
2019-12-07 15:42:09 +01:00
|
|
|
bool isScoped() const { return m_isScoped; }
|
2020-05-09 00:42:34 +02:00
|
|
|
AstNode* valuep() const { return op1p(); }
|
2006-08-26 13:35:28 +02:00
|
|
|
};
|
|
|
|
|
|
2020-11-19 03:32:16 +01:00
|
|
|
class AstTraceInc final : public AstNodeStmt {
|
2020-05-09 00:42:34 +02:00
|
|
|
// Trace point dump
|
2006-08-26 13:35:28 +02:00
|
|
|
// Parents: {statement list}
|
2020-05-09 00:42:34 +02:00
|
|
|
// Children: op1: things to emit before this node,
|
|
|
|
|
// op2: expression being traced (from decl)
|
|
|
|
|
|
2006-08-26 13:35:28 +02:00
|
|
|
private:
|
2020-05-09 00:42:34 +02:00
|
|
|
AstTraceDecl* m_declp; // Pointer to declaration
|
|
|
|
|
const bool m_full; // Is this a full vs incremental dump
|
2021-06-22 14:50:21 +02:00
|
|
|
const uint32_t m_baseCode; // Trace code base value in function containing this AstTraceInc
|
|
|
|
|
|
2006-08-26 13:35:28 +02:00
|
|
|
public:
|
2021-06-22 14:50:21 +02:00
|
|
|
AstTraceInc(FileLine* fl, AstTraceDecl* declp, bool full, uint32_t baseCode = 0)
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_TraceInc(fl)
|
2020-08-16 17:40:42 +02:00
|
|
|
, m_declp{declp}
|
2021-06-22 14:50:21 +02:00
|
|
|
, m_full{full}
|
|
|
|
|
, m_baseCode{baseCode} {
|
2019-05-19 22:13:13 +02:00
|
|
|
dtypeFrom(declp);
|
2020-05-09 00:42:34 +02:00
|
|
|
addOp2p(declp->valuep()->cloneTree(true));
|
2006-08-26 13:35:28 +02:00
|
|
|
}
|
2016-11-05 14:47:56 +01:00
|
|
|
ASTNODE_NODE_FUNCS(TraceInc)
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual const char* broken() const override {
|
2020-04-15 13:58:34 +02:00
|
|
|
BROKEN_RTN(!declp()->brokeExists());
|
2020-08-15 16:12:55 +02:00
|
|
|
return nullptr;
|
2020-04-15 13:58:34 +02:00
|
|
|
}
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual void cloneRelink() override {
|
2020-04-15 13:58:34 +02:00
|
|
|
if (m_declp->clonep()) m_declp = m_declp->clonep();
|
|
|
|
|
}
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual void dump(std::ostream& str) const override;
|
2021-07-25 14:32:36 +02:00
|
|
|
virtual int instrCount() const override { return 10 + 2 * INSTR_COUNT_LD; }
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual bool hasDType() const override { return true; }
|
|
|
|
|
virtual bool same(const AstNode* samep) const override {
|
2020-04-15 13:58:34 +02:00
|
|
|
return declp() == static_cast<const AstTraceInc*>(samep)->declp();
|
|
|
|
|
}
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual bool isGateOptimizable() const override { return false; }
|
|
|
|
|
virtual bool isPredictOptimizable() const override { return false; }
|
|
|
|
|
virtual bool isOutputter() const override { return true; }
|
2011-12-16 01:13:54 +01:00
|
|
|
// but isPure() true
|
2006-08-26 13:35:28 +02:00
|
|
|
// op1 = Statements before the value
|
2020-05-09 00:42:34 +02:00
|
|
|
AstNode* precondsp() const { return op1p(); }
|
2019-05-19 22:13:13 +02:00
|
|
|
void addPrecondsp(AstNode* newp) { addOp1p(newp); }
|
|
|
|
|
AstNode* valuep() const { return op2p(); }
|
2020-05-09 00:42:34 +02:00
|
|
|
AstTraceDecl* declp() const { return m_declp; }
|
|
|
|
|
bool full() const { return m_full; }
|
2021-06-22 14:50:21 +02:00
|
|
|
uint32_t baseCode() const { return m_baseCode; }
|
2006-08-26 13:35:28 +02:00
|
|
|
};
|
|
|
|
|
|
2020-11-19 03:32:16 +01:00
|
|
|
class AstActive final : public AstNode {
|
2006-08-26 13:35:28 +02:00
|
|
|
// Block of code with sensitivity activation
|
|
|
|
|
// Parents: MODULE | CFUNC
|
|
|
|
|
// Children: SENTREE, statements
|
|
|
|
|
private:
|
2020-04-15 13:58:34 +02:00
|
|
|
string m_name;
|
2019-05-19 22:13:13 +02:00
|
|
|
AstSenTree* m_sensesp;
|
2020-04-15 13:58:34 +02:00
|
|
|
|
2006-08-26 13:35:28 +02:00
|
|
|
public:
|
2020-01-25 21:29:44 +01:00
|
|
|
AstActive(FileLine* fl, const string& name, AstSenTree* sensesp)
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_Active(fl) {
|
2019-05-19 22:13:13 +02:00
|
|
|
m_name = name; // Copy it
|
|
|
|
|
UASSERT(sensesp, "Sensesp required arg");
|
|
|
|
|
m_sensesp = sensesp;
|
2006-08-26 13:35:28 +02:00
|
|
|
}
|
2016-11-05 14:47:56 +01:00
|
|
|
ASTNODE_NODE_FUNCS(Active)
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual void dump(std::ostream& str = std::cout) const override;
|
|
|
|
|
virtual string name() const override { return m_name; }
|
|
|
|
|
virtual const char* broken() const override {
|
2020-04-15 13:58:34 +02:00
|
|
|
BROKEN_RTN(m_sensesp && !m_sensesp->brokeExists());
|
2020-08-15 16:12:55 +02:00
|
|
|
return nullptr;
|
2020-04-15 13:58:34 +02:00
|
|
|
}
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual void cloneRelink() override {
|
2019-05-19 22:13:13 +02:00
|
|
|
if (m_sensesp->clonep()) {
|
|
|
|
|
m_sensesp = m_sensesp->clonep();
|
2020-04-15 13:58:34 +02:00
|
|
|
UASSERT(m_sensesp, "Bad clone cross link: " << this);
|
2019-05-19 22:13:13 +02:00
|
|
|
}
|
2006-08-26 13:35:28 +02:00
|
|
|
}
|
|
|
|
|
// Statements are broken into pieces, as some must come before others.
|
2019-05-19 22:13:13 +02:00
|
|
|
void sensesp(AstSenTree* nodep) { m_sensesp = nodep; }
|
|
|
|
|
AstSenTree* sensesp() const { return m_sensesp; }
|
2006-08-26 13:35:28 +02:00
|
|
|
// op1 = Sensitivity tree, if a clocked block in early stages
|
2019-05-19 22:13:13 +02:00
|
|
|
void sensesStorep(AstSenTree* nodep) { addOp1p(nodep); }
|
2021-10-22 14:56:48 +02:00
|
|
|
AstSenTree* sensesStorep() const { return VN_AS(op1p(), SenTree); }
|
2006-08-26 13:35:28 +02:00
|
|
|
// op2 = Combo logic
|
2019-05-19 22:13:13 +02:00
|
|
|
AstNode* stmtsp() const { return op2p(); }
|
2006-08-26 13:35:28 +02:00
|
|
|
void addStmtsp(AstNode* nodep) { addOp2p(nodep); }
|
|
|
|
|
// METHODS
|
|
|
|
|
bool hasInitial() const { return m_sensesp->hasInitial(); }
|
|
|
|
|
bool hasSettle() const { return m_sensesp->hasSettle(); }
|
|
|
|
|
bool hasClocked() const { return m_sensesp->hasClocked(); }
|
|
|
|
|
};
|
|
|
|
|
|
2020-11-19 03:32:16 +01:00
|
|
|
class AstAttrOf final : public AstNode {
|
2006-09-27 20:00:53 +02:00
|
|
|
private:
|
2006-08-26 13:35:28 +02:00
|
|
|
// Return a value of a attribute, for example a LSB or array LSB of a signal
|
2019-05-19 22:13:13 +02:00
|
|
|
AstAttrType m_attrType; // What sort of extraction
|
2006-08-26 13:35:28 +02:00
|
|
|
public:
|
2020-08-15 16:12:55 +02:00
|
|
|
AstAttrOf(FileLine* fl, AstAttrType attrtype, AstNode* fromp = nullptr,
|
|
|
|
|
AstNode* dimp = nullptr)
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_AttrOf(fl) {
|
2019-05-19 22:13:13 +02:00
|
|
|
setNOp1p(fromp);
|
|
|
|
|
setNOp2p(dimp);
|
2020-04-15 13:58:34 +02:00
|
|
|
m_attrType = attrtype;
|
|
|
|
|
}
|
2016-11-05 14:47:56 +01:00
|
|
|
ASTNODE_NODE_FUNCS(AttrOf)
|
2019-05-19 22:13:13 +02:00
|
|
|
AstNode* fromp() const { return op1p(); }
|
|
|
|
|
AstNode* dimp() const { return op2p(); }
|
|
|
|
|
AstAttrType attrType() const { return m_attrType; }
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual void dump(std::ostream& str = std::cout) const override;
|
2006-08-26 13:35:28 +02:00
|
|
|
};
|
|
|
|
|
|
2020-11-19 03:32:16 +01:00
|
|
|
class AstScopeName final : public AstNodeMath {
|
2009-12-05 16:38:49 +01:00
|
|
|
// For display %m and DPI context imports
|
2007-06-14 18:41:32 +02:00
|
|
|
// Parents: DISPLAY
|
|
|
|
|
// Children: TEXT
|
2009-12-20 14:27:00 +01:00
|
|
|
private:
|
2020-08-15 19:11:27 +02:00
|
|
|
bool m_dpiExport = false; // Is for dpiExport
|
2021-11-27 02:38:48 +01:00
|
|
|
const bool m_forFormat = false; // Is for a format %m
|
2018-10-15 00:39:33 +02:00
|
|
|
string scopeNameFormatter(AstText* scopeTextp) const;
|
|
|
|
|
string scopePrettyNameFormatter(AstText* scopeTextp) const;
|
2020-04-15 13:58:34 +02:00
|
|
|
|
2009-12-20 14:27:00 +01:00
|
|
|
public:
|
2021-11-27 02:38:48 +01:00
|
|
|
class ForFormat {};
|
|
|
|
|
AstScopeName(FileLine* fl, bool forFormat)
|
|
|
|
|
: ASTGEN_SUPER_ScopeName(fl)
|
|
|
|
|
, m_forFormat{forFormat} {
|
2020-01-25 21:29:44 +01:00
|
|
|
dtypeSetUInt64();
|
|
|
|
|
}
|
2016-11-05 14:47:56 +01:00
|
|
|
ASTNODE_NODE_FUNCS(ScopeName)
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual bool same(const AstNode* samep) const override {
|
2021-11-27 02:38:48 +01:00
|
|
|
return (m_dpiExport == static_cast<const AstScopeName*>(samep)->m_dpiExport
|
|
|
|
|
&& m_forFormat == static_cast<const AstScopeName*>(samep)->m_forFormat);
|
2020-04-15 13:58:34 +02:00
|
|
|
}
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual string emitVerilog() override { return ""; }
|
|
|
|
|
virtual string emitC() override { V3ERROR_NA_RETURN(""); }
|
|
|
|
|
virtual bool cleanOut() const override { return true; }
|
2021-11-27 02:38:48 +01:00
|
|
|
virtual void dump(std::ostream& str = std::cout) const override;
|
2021-10-22 14:56:48 +02:00
|
|
|
AstText* scopeAttrp() const { return VN_AS(op1p(), Text); }
|
2018-02-02 03:32:58 +01:00
|
|
|
void scopeAttrp(AstNode* nodep) { addOp1p(nodep); }
|
2021-10-22 14:56:48 +02:00
|
|
|
AstText* scopeEntrp() const { return VN_AS(op2p(), Text); }
|
2018-02-02 03:32:58 +01:00
|
|
|
void scopeEntrp(AstNode* nodep) { addOp2p(nodep); }
|
2018-03-10 22:32:04 +01:00
|
|
|
string scopeSymName() const { // Name for __Vscope variable including children
|
2020-04-15 13:58:34 +02:00
|
|
|
return scopeNameFormatter(scopeAttrp());
|
|
|
|
|
}
|
2018-03-10 22:32:04 +01:00
|
|
|
string scopeDpiName() const { // Name for DPI import scope
|
2020-04-15 13:58:34 +02:00
|
|
|
return scopeNameFormatter(scopeEntrp());
|
|
|
|
|
}
|
2018-03-10 22:32:04 +01:00
|
|
|
string scopePrettySymName() const { // Name for __Vscope variable including children
|
2020-04-15 13:58:34 +02:00
|
|
|
return scopePrettyNameFormatter(scopeAttrp());
|
|
|
|
|
}
|
2018-03-10 22:32:04 +01:00
|
|
|
string scopePrettyDpiName() const { // Name for __Vscope variable including children
|
2020-04-15 13:58:34 +02:00
|
|
|
return scopePrettyNameFormatter(scopeEntrp());
|
|
|
|
|
}
|
2009-12-20 14:27:00 +01:00
|
|
|
bool dpiExport() const { return m_dpiExport; }
|
2019-05-19 22:13:13 +02:00
|
|
|
void dpiExport(bool flag) { m_dpiExport = flag; }
|
2021-11-27 02:38:48 +01:00
|
|
|
bool forFormat() const { return m_forFormat; }
|
2007-06-14 18:41:32 +02:00
|
|
|
};
|
|
|
|
|
|
2020-11-19 03:32:16 +01:00
|
|
|
class AstUdpTable final : public AstNode {
|
2014-09-12 03:28:53 +02:00
|
|
|
public:
|
2009-11-21 01:53:40 +01:00
|
|
|
AstUdpTable(FileLine* fl, AstNode* bodysp)
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_UdpTable(fl) {
|
2019-05-19 22:13:13 +02:00
|
|
|
addNOp1p(bodysp);
|
2009-11-21 01:53:40 +01:00
|
|
|
}
|
2016-11-05 14:47:56 +01:00
|
|
|
ASTNODE_NODE_FUNCS(UdpTable)
|
2020-04-15 13:58:34 +02:00
|
|
|
// op1 = List of UdpTableLines
|
2021-10-22 14:56:48 +02:00
|
|
|
AstUdpTableLine* bodysp() const { return VN_AS(op1p(), UdpTableLine); }
|
2009-11-21 01:53:40 +01:00
|
|
|
};
|
|
|
|
|
|
2020-11-19 03:32:16 +01:00
|
|
|
class AstUdpTableLine final : public AstNode {
|
2020-04-15 13:58:34 +02:00
|
|
|
string m_text;
|
|
|
|
|
|
2009-11-21 01:53:40 +01:00
|
|
|
public:
|
|
|
|
|
AstUdpTableLine(FileLine* fl, const string& text)
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_UdpTableLine(fl)
|
2020-08-16 17:40:42 +02:00
|
|
|
, m_text{text} {}
|
2016-11-05 14:47:56 +01:00
|
|
|
ASTNODE_NODE_FUNCS(UdpTableLine)
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual string name() const override { return m_text; }
|
2009-11-21 01:53:40 +01:00
|
|
|
string text() const { return m_text; }
|
|
|
|
|
};
|
|
|
|
|
|
2006-08-26 13:35:28 +02:00
|
|
|
//======================================================================
|
|
|
|
|
// non-ary ops
|
|
|
|
|
|
2020-11-20 03:32:33 +01:00
|
|
|
class AstRand final : public AstNodeMath {
|
|
|
|
|
// $random/$random(seed) or $urandom/$urandom(seed)
|
2006-08-26 13:35:28 +02:00
|
|
|
// Return a random number, based upon width()
|
2008-06-27 17:36:25 +02:00
|
|
|
private:
|
2021-11-26 23:55:36 +01:00
|
|
|
const bool m_urandom = false; // $urandom vs $random
|
|
|
|
|
const bool m_reset = false; // Random reset, versus always random
|
2008-06-27 17:36:25 +02:00
|
|
|
public:
|
2020-11-20 03:32:33 +01:00
|
|
|
class Reset {};
|
|
|
|
|
AstRand(FileLine* fl, Reset, AstNodeDType* dtp, bool reset)
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_Rand(fl)
|
2020-08-16 17:40:42 +02:00
|
|
|
, m_reset{reset} {
|
2020-04-15 13:58:34 +02:00
|
|
|
dtypep(dtp);
|
|
|
|
|
}
|
2020-11-20 03:32:33 +01:00
|
|
|
AstRand(FileLine* fl, AstNode* seedp, bool urandom)
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_Rand(fl)
|
2020-11-20 03:32:33 +01:00
|
|
|
, m_urandom(urandom) {
|
|
|
|
|
setNOp1p(seedp);
|
|
|
|
|
}
|
2016-11-05 14:47:56 +01:00
|
|
|
ASTNODE_NODE_FUNCS(Rand)
|
2020-11-20 03:32:33 +01:00
|
|
|
virtual string emitVerilog() override {
|
|
|
|
|
return seedp() ? (m_urandom ? "%f$urandom(%l)" : "%f$random(%l)")
|
|
|
|
|
: (m_urandom ? "%f$urandom()" : "%f$random()");
|
2020-04-15 13:58:34 +02:00
|
|
|
}
|
2020-11-20 03:32:33 +01:00
|
|
|
virtual string emitC() override {
|
2021-11-28 20:00:19 +01:00
|
|
|
return m_reset ? "VL_RAND_RESET_%nq(%nw, %P)"
|
|
|
|
|
: seedp() ? "VL_RANDOM_SEEDED_%nq%lq(%li)"
|
|
|
|
|
: isWide() ? "VL_RANDOM_%nq(%nw, %P)" //
|
|
|
|
|
: "VL_RANDOM_%nq()";
|
2020-08-23 14:42:50 +02:00
|
|
|
}
|
2021-11-28 20:00:19 +01:00
|
|
|
virtual bool cleanOut() const override { return false; }
|
2020-08-23 14:42:50 +02:00
|
|
|
virtual bool isGateOptimizable() const override { return false; }
|
|
|
|
|
virtual bool isPredictOptimizable() const override { return false; }
|
2021-07-25 14:32:36 +02:00
|
|
|
virtual int instrCount() const override { return INSTR_COUNT_PLI; }
|
2020-08-23 14:42:50 +02:00
|
|
|
virtual bool same(const AstNode* samep) const override { return true; }
|
2021-11-28 20:17:28 +01:00
|
|
|
bool combinable(const AstRand* samep) const {
|
|
|
|
|
return !seedp() && !samep->seedp() && reset() == samep->reset()
|
|
|
|
|
&& urandom() == samep->urandom();
|
|
|
|
|
}
|
2020-11-20 03:32:33 +01:00
|
|
|
AstNode* seedp() const { return op1p(); }
|
|
|
|
|
bool reset() const { return m_reset; }
|
|
|
|
|
bool urandom() const { return m_urandom; }
|
2020-08-23 14:42:50 +02:00
|
|
|
};
|
|
|
|
|
|
2020-11-19 03:32:16 +01:00
|
|
|
class AstURandomRange final : public AstNodeBiop {
|
2020-08-23 14:42:50 +02:00
|
|
|
// $urandom_range
|
|
|
|
|
public:
|
|
|
|
|
explicit AstURandomRange(FileLine* fl, AstNode* lhsp, AstNode* rhsp)
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_URandomRange(fl, lhsp, rhsp) {
|
2020-08-23 14:42:50 +02:00
|
|
|
dtypeSetUInt32(); // Says IEEE
|
|
|
|
|
}
|
|
|
|
|
ASTNODE_NODE_FUNCS(URandomRange)
|
|
|
|
|
virtual AstNode* cloneType(AstNode* lhsp, AstNode* rhsp) override {
|
|
|
|
|
return new AstURandomRange(fileline(), lhsp, rhsp);
|
|
|
|
|
}
|
|
|
|
|
virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) override {
|
|
|
|
|
V3ERROR_NA;
|
|
|
|
|
}
|
|
|
|
|
virtual string emitVerilog() override { return "%f$urandom_range(%l, %r)"; }
|
|
|
|
|
virtual string emitC() override { return "VL_URANDOM_RANGE_%nq(%li, %ri)"; }
|
|
|
|
|
virtual bool cleanOut() const override { return true; }
|
|
|
|
|
virtual bool cleanLhs() const override { return true; }
|
|
|
|
|
virtual bool cleanRhs() const override { return true; }
|
|
|
|
|
virtual bool sizeMattersLhs() const override { return false; }
|
|
|
|
|
virtual bool sizeMattersRhs() const override { return false; }
|
|
|
|
|
virtual bool isGateOptimizable() const override { return false; }
|
|
|
|
|
virtual bool isPredictOptimizable() const override { return false; }
|
2021-07-25 14:32:36 +02:00
|
|
|
virtual int instrCount() const override { return INSTR_COUNT_PLI; }
|
2020-08-23 14:42:50 +02:00
|
|
|
};
|
|
|
|
|
|
2020-11-19 03:32:16 +01:00
|
|
|
class AstTime final : public AstNodeTermop {
|
2020-04-16 01:39:03 +02:00
|
|
|
VTimescale m_timeunit; // Parent module time unit
|
2014-09-12 03:28:53 +02:00
|
|
|
public:
|
2020-04-16 01:39:03 +02:00
|
|
|
AstTime(FileLine* fl, const VTimescale& timeunit)
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_Time(fl)
|
2020-08-16 17:40:42 +02:00
|
|
|
, m_timeunit{timeunit} {
|
2020-04-15 13:58:34 +02:00
|
|
|
dtypeSetUInt64();
|
|
|
|
|
}
|
2016-11-05 14:47:56 +01:00
|
|
|
ASTNODE_NODE_FUNCS(Time)
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual string emitVerilog() override { return "%f$time"; }
|
|
|
|
|
virtual string emitC() override { V3ERROR_NA_RETURN(""); }
|
|
|
|
|
virtual bool cleanOut() const override { return true; }
|
|
|
|
|
virtual bool isGateOptimizable() const override { return false; }
|
|
|
|
|
virtual bool isPredictOptimizable() const override { return false; }
|
2021-07-25 14:32:36 +02:00
|
|
|
virtual int instrCount() const override { return INSTR_COUNT_TIME; }
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual bool same(const AstNode* samep) const override { return true; }
|
|
|
|
|
virtual void dump(std::ostream& str = std::cout) const override;
|
2020-04-16 01:39:03 +02:00
|
|
|
void timeunit(const VTimescale& flag) { m_timeunit = flag; }
|
|
|
|
|
VTimescale timeunit() const { return m_timeunit; }
|
2006-08-26 13:35:28 +02:00
|
|
|
};
|
|
|
|
|
|
2020-11-19 03:32:16 +01:00
|
|
|
class AstTimeD final : public AstNodeTermop {
|
2020-04-16 01:39:03 +02:00
|
|
|
VTimescale m_timeunit; // Parent module time unit
|
2014-09-12 03:28:53 +02:00
|
|
|
public:
|
2020-04-16 01:39:03 +02:00
|
|
|
AstTimeD(FileLine* fl, const VTimescale& timeunit)
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_TimeD(fl)
|
2020-08-16 17:40:42 +02:00
|
|
|
, m_timeunit{timeunit} {
|
2020-04-15 13:58:34 +02:00
|
|
|
dtypeSetDouble();
|
|
|
|
|
}
|
2016-11-05 14:47:56 +01:00
|
|
|
ASTNODE_NODE_FUNCS(TimeD)
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual string emitVerilog() override { return "%f$realtime"; }
|
|
|
|
|
virtual string emitC() override { V3ERROR_NA_RETURN(""); }
|
|
|
|
|
virtual bool cleanOut() const override { return true; }
|
|
|
|
|
virtual bool isGateOptimizable() const override { return false; }
|
|
|
|
|
virtual bool isPredictOptimizable() const override { return false; }
|
2021-07-25 14:32:36 +02:00
|
|
|
virtual int instrCount() const override { return INSTR_COUNT_TIME; }
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual bool same(const AstNode* samep) const override { return true; }
|
|
|
|
|
virtual void dump(std::ostream& str = std::cout) const override;
|
2020-04-16 01:39:03 +02:00
|
|
|
void timeunit(const VTimescale& flag) { m_timeunit = flag; }
|
|
|
|
|
VTimescale timeunit() const { return m_timeunit; }
|
2011-07-24 21:01:51 +02:00
|
|
|
};
|
|
|
|
|
|
2020-11-19 03:32:16 +01:00
|
|
|
class AstUCFunc final : public AstNodeMath {
|
2006-08-26 13:35:28 +02:00
|
|
|
// User's $c function
|
2011-11-30 04:36:51 +01:00
|
|
|
// Perhaps this should be an AstNodeListop; but there's only one list math right now
|
2014-09-12 03:28:53 +02:00
|
|
|
public:
|
2006-08-26 13:35:28 +02:00
|
|
|
AstUCFunc(FileLine* fl, AstNode* exprsp)
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_UCFunc(fl) {
|
2019-05-19 22:13:13 +02:00
|
|
|
addNOp1p(exprsp);
|
2006-08-26 13:35:28 +02:00
|
|
|
}
|
2016-11-05 14:47:56 +01:00
|
|
|
ASTNODE_NODE_FUNCS(UCFunc)
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual bool cleanOut() const override { return false; }
|
|
|
|
|
virtual string emitVerilog() override { V3ERROR_NA_RETURN(""); }
|
|
|
|
|
virtual string emitC() override { V3ERROR_NA_RETURN(""); }
|
2019-05-19 22:13:13 +02:00
|
|
|
AstNode* bodysp() const { return op1p(); } // op1 = expressions to print
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual bool isPure() const override { return false; } // SPECIAL: User may order w/other sigs
|
|
|
|
|
virtual bool isOutputter() const override { return true; }
|
|
|
|
|
virtual bool isGateOptimizable() const override { return false; }
|
|
|
|
|
virtual bool isSubstOptimizable() const override { return false; }
|
|
|
|
|
virtual bool isPredictOptimizable() const override { return false; }
|
2021-07-25 14:32:36 +02:00
|
|
|
virtual int instrCount() const override { return INSTR_COUNT_PLI; }
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual bool same(const AstNode* samep) const override { return true; }
|
2006-08-26 13:35:28 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
//======================================================================
|
|
|
|
|
// Unary ops
|
|
|
|
|
|
2020-11-19 03:32:16 +01:00
|
|
|
class AstNegate final : public AstNodeUniop {
|
2014-09-12 03:28:53 +02:00
|
|
|
public:
|
2020-01-25 21:29:44 +01:00
|
|
|
AstNegate(FileLine* fl, AstNode* lhsp)
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_Negate(fl, lhsp) {
|
2020-04-15 13:58:34 +02:00
|
|
|
dtypeFrom(lhsp);
|
|
|
|
|
}
|
2016-11-05 14:47:56 +01:00
|
|
|
ASTNODE_NODE_FUNCS(Negate)
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual void numberOperate(V3Number& out, const V3Number& lhs) override { out.opNegate(lhs); }
|
|
|
|
|
virtual string emitVerilog() override { return "%f(- %l)"; }
|
|
|
|
|
virtual string emitC() override { return "VL_NEGATE_%lq(%lW, %P, %li)"; }
|
|
|
|
|
virtual string emitSimpleOperator() override { return "-"; }
|
|
|
|
|
virtual bool cleanOut() const override { return false; }
|
|
|
|
|
virtual bool cleanLhs() const override { return false; }
|
|
|
|
|
virtual bool sizeMattersLhs() const override { return true; }
|
2006-08-26 13:35:28 +02:00
|
|
|
};
|
2020-11-19 03:32:16 +01:00
|
|
|
class AstNegateD final : public AstNodeUniop {
|
2014-09-12 03:28:53 +02:00
|
|
|
public:
|
2020-01-25 21:29:44 +01:00
|
|
|
AstNegateD(FileLine* fl, AstNode* lhsp)
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_NegateD(fl, lhsp) {
|
2020-04-15 13:58:34 +02:00
|
|
|
dtypeSetDouble();
|
|
|
|
|
}
|
2016-11-05 14:47:56 +01:00
|
|
|
ASTNODE_NODE_FUNCS(NegateD)
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual void numberOperate(V3Number& out, const V3Number& lhs) override { out.opNegateD(lhs); }
|
|
|
|
|
virtual string emitVerilog() override { return "%f(- %l)"; }
|
|
|
|
|
virtual string emitC() override { V3ERROR_NA_RETURN(""); }
|
|
|
|
|
virtual string emitSimpleOperator() override { return "-"; }
|
|
|
|
|
virtual bool cleanOut() const override { return true; }
|
|
|
|
|
virtual bool cleanLhs() const override { return false; }
|
|
|
|
|
virtual bool sizeMattersLhs() const override { return false; }
|
2021-07-25 14:32:36 +02:00
|
|
|
virtual int instrCount() const override { return INSTR_COUNT_DBL; }
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual bool doubleFlavor() const override { return true; }
|
2011-07-24 21:01:51 +02:00
|
|
|
};
|
2020-11-19 03:32:16 +01:00
|
|
|
class AstRedAnd final : public AstNodeUniop {
|
2014-09-12 03:28:53 +02:00
|
|
|
public:
|
2020-01-25 21:29:44 +01:00
|
|
|
AstRedAnd(FileLine* fl, AstNode* lhsp)
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_RedAnd(fl, lhsp) {
|
2020-11-29 14:23:36 +01:00
|
|
|
dtypeSetBit();
|
2020-04-15 13:58:34 +02:00
|
|
|
}
|
2016-11-05 14:47:56 +01:00
|
|
|
ASTNODE_NODE_FUNCS(RedAnd)
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual void numberOperate(V3Number& out, const V3Number& lhs) override { out.opRedAnd(lhs); }
|
|
|
|
|
virtual string emitVerilog() override { return "%f(& %l)"; }
|
2021-11-28 19:44:16 +01:00
|
|
|
virtual string emitC() override { return "VL_REDAND_%nq%lq(%lw, %P, %li)"; }
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual bool cleanOut() const override { return true; }
|
|
|
|
|
virtual bool cleanLhs() const override { return true; }
|
|
|
|
|
virtual bool sizeMattersLhs() const override { return false; }
|
2006-08-26 13:35:28 +02:00
|
|
|
};
|
2020-11-19 03:32:16 +01:00
|
|
|
class AstRedOr final : public AstNodeUniop {
|
2014-09-12 03:28:53 +02:00
|
|
|
public:
|
2020-01-25 21:29:44 +01:00
|
|
|
AstRedOr(FileLine* fl, AstNode* lhsp)
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_RedOr(fl, lhsp) {
|
2020-11-29 14:23:36 +01:00
|
|
|
dtypeSetBit();
|
2020-04-15 13:58:34 +02:00
|
|
|
}
|
2016-11-05 14:47:56 +01:00
|
|
|
ASTNODE_NODE_FUNCS(RedOr)
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual void numberOperate(V3Number& out, const V3Number& lhs) override { out.opRedOr(lhs); }
|
|
|
|
|
virtual string emitVerilog() override { return "%f(| %l)"; }
|
|
|
|
|
virtual string emitC() override { return "VL_REDOR_%lq(%lW, %P, %li)"; }
|
|
|
|
|
virtual bool cleanOut() const override { return true; }
|
|
|
|
|
virtual bool cleanLhs() const override { return true; }
|
|
|
|
|
virtual bool sizeMattersLhs() const override { return false; }
|
2006-08-26 13:35:28 +02:00
|
|
|
};
|
2020-11-19 03:32:16 +01:00
|
|
|
class AstRedXor final : public AstNodeUniop {
|
2014-09-12 03:28:53 +02:00
|
|
|
public:
|
2020-01-25 21:29:44 +01:00
|
|
|
AstRedXor(FileLine* fl, AstNode* lhsp)
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_RedXor(fl, lhsp) {
|
2020-11-29 14:23:36 +01:00
|
|
|
dtypeSetBit();
|
2020-04-15 13:58:34 +02:00
|
|
|
}
|
2016-11-05 14:47:56 +01:00
|
|
|
ASTNODE_NODE_FUNCS(RedXor)
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual void numberOperate(V3Number& out, const V3Number& lhs) override { out.opRedXor(lhs); }
|
|
|
|
|
virtual string emitVerilog() override { return "%f(^ %l)"; }
|
|
|
|
|
virtual string emitC() override { return "VL_REDXOR_%lq(%lW, %P, %li)"; }
|
|
|
|
|
virtual bool cleanOut() const override { return false; }
|
|
|
|
|
virtual bool cleanLhs() const override {
|
2021-11-26 23:55:36 +01:00
|
|
|
const int w = lhsp()->width();
|
2020-04-15 13:58:34 +02:00
|
|
|
return (w != 1 && w != 2 && w != 4 && w != 8 && w != 16);
|
|
|
|
|
}
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual bool sizeMattersLhs() const override { return false; }
|
|
|
|
|
virtual int instrCount() const override { return 1 + V3Number::log2b(width()); }
|
2006-08-26 13:35:28 +02:00
|
|
|
};
|
|
|
|
|
|
2020-11-19 03:32:16 +01:00
|
|
|
class AstLenN final : public AstNodeUniop {
|
2017-12-08 01:57:11 +01:00
|
|
|
// Length of a string
|
|
|
|
|
public:
|
2020-01-25 21:29:44 +01:00
|
|
|
AstLenN(FileLine* fl, AstNode* lhsp)
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_LenN(fl, lhsp) {
|
2020-04-15 13:58:34 +02:00
|
|
|
dtypeSetSigned32();
|
|
|
|
|
}
|
2017-12-08 01:57:11 +01:00
|
|
|
ASTNODE_NODE_FUNCS(LenN)
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual void numberOperate(V3Number& out, const V3Number& lhs) override { out.opLenN(lhs); }
|
|
|
|
|
virtual string emitVerilog() override { return "%f(%l)"; }
|
|
|
|
|
virtual string emitC() override { return "VL_LEN_IN(%li)"; }
|
|
|
|
|
virtual bool cleanOut() const override { return true; }
|
|
|
|
|
virtual bool cleanLhs() const override { return true; }
|
|
|
|
|
virtual bool sizeMattersLhs() const override { return false; }
|
2017-12-08 01:57:11 +01:00
|
|
|
};
|
2020-11-19 03:32:16 +01:00
|
|
|
class AstLogNot final : public AstNodeUniop {
|
2014-09-12 03:28:53 +02:00
|
|
|
public:
|
2020-01-25 21:29:44 +01:00
|
|
|
AstLogNot(FileLine* fl, AstNode* lhsp)
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_LogNot(fl, lhsp) {
|
2020-11-29 14:23:36 +01:00
|
|
|
dtypeSetBit();
|
2020-04-15 13:58:34 +02:00
|
|
|
}
|
2016-11-05 14:47:56 +01:00
|
|
|
ASTNODE_NODE_FUNCS(LogNot)
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual void numberOperate(V3Number& out, const V3Number& lhs) override { out.opLogNot(lhs); }
|
|
|
|
|
virtual string emitVerilog() override { return "%f(! %l)"; }
|
|
|
|
|
virtual string emitC() override { return "VL_LOGNOT_%nq%lq(%nw,%lw, %P, %li)"; }
|
|
|
|
|
virtual string emitSimpleOperator() override { return "!"; }
|
|
|
|
|
virtual bool cleanOut() const override { return true; }
|
|
|
|
|
virtual bool cleanLhs() const override { return true; }
|
|
|
|
|
virtual bool sizeMattersLhs() const override { return false; }
|
2006-08-26 13:35:28 +02:00
|
|
|
};
|
2020-11-19 03:32:16 +01:00
|
|
|
class AstNot final : public AstNodeUniop {
|
2014-09-12 03:28:53 +02:00
|
|
|
public:
|
2020-01-25 21:29:44 +01:00
|
|
|
AstNot(FileLine* fl, AstNode* lhsp)
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_Not(fl, lhsp) {
|
2020-04-15 13:58:34 +02:00
|
|
|
dtypeFrom(lhsp);
|
|
|
|
|
}
|
2016-11-05 14:47:56 +01:00
|
|
|
ASTNODE_NODE_FUNCS(Not)
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual void numberOperate(V3Number& out, const V3Number& lhs) override { out.opNot(lhs); }
|
|
|
|
|
virtual string emitVerilog() override { return "%f(~ %l)"; }
|
|
|
|
|
virtual string emitC() override { return "VL_NOT_%lq(%lW, %P, %li)"; }
|
|
|
|
|
virtual string emitSimpleOperator() override { return "~"; }
|
|
|
|
|
virtual bool cleanOut() const override { return false; }
|
|
|
|
|
virtual bool cleanLhs() const override { return false; }
|
|
|
|
|
virtual bool sizeMattersLhs() const override { return true; }
|
2006-08-26 13:35:28 +02:00
|
|
|
};
|
2020-11-19 03:32:16 +01:00
|
|
|
class AstExtend final : public AstNodeUniop {
|
2006-08-26 13:35:28 +02:00
|
|
|
// Expand a value into a wider entity by 0 extension. Width is implied from nodep->width()
|
2014-09-12 03:28:53 +02:00
|
|
|
public:
|
2020-01-25 21:29:44 +01:00
|
|
|
AstExtend(FileLine* fl, AstNode* lhsp)
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_Extend(fl, lhsp) {}
|
2020-01-25 21:29:44 +01:00
|
|
|
AstExtend(FileLine* fl, AstNode* lhsp, int width)
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_Extend(fl, lhsp) {
|
2020-04-20 03:19:09 +02:00
|
|
|
dtypeSetLogicSized(width, VSigning::UNSIGNED);
|
2020-04-15 13:58:34 +02:00
|
|
|
}
|
2016-11-05 14:47:56 +01:00
|
|
|
ASTNODE_NODE_FUNCS(Extend)
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual void numberOperate(V3Number& out, const V3Number& lhs) override { out.opAssign(lhs); }
|
|
|
|
|
virtual string emitVerilog() override { return "%l"; }
|
|
|
|
|
virtual string emitC() override { return "VL_EXTEND_%nq%lq(%nw,%lw, %P, %li)"; }
|
|
|
|
|
virtual bool cleanOut() const override { return true; }
|
|
|
|
|
virtual bool cleanLhs() const override { return true; }
|
|
|
|
|
virtual bool sizeMattersLhs() const override {
|
2020-04-15 13:58:34 +02:00
|
|
|
return false; // Because the EXTEND operator self-casts
|
|
|
|
|
}
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual int instrCount() const override { return 0; }
|
2006-08-26 13:35:28 +02:00
|
|
|
};
|
2020-11-19 03:32:16 +01:00
|
|
|
class AstExtendS final : public AstNodeUniop {
|
2006-08-26 13:35:28 +02:00
|
|
|
// Expand a value into a wider entity by sign extension. Width is implied from nodep->width()
|
2014-09-12 03:28:53 +02:00
|
|
|
public:
|
2020-01-25 21:29:44 +01:00
|
|
|
AstExtendS(FileLine* fl, AstNode* lhsp)
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_ExtendS(fl, lhsp) {}
|
2020-01-25 21:29:44 +01:00
|
|
|
AstExtendS(FileLine* fl, AstNode* lhsp, int width)
|
2019-05-19 22:13:13 +02:00
|
|
|
// Important that widthMin be correct, as opExtend requires it after V3Expand
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_ExtendS(fl, lhsp) {
|
2020-04-20 03:19:09 +02:00
|
|
|
dtypeSetLogicSized(width, VSigning::UNSIGNED);
|
2020-04-15 13:58:34 +02:00
|
|
|
}
|
2016-11-05 14:47:56 +01:00
|
|
|
ASTNODE_NODE_FUNCS(ExtendS)
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual void numberOperate(V3Number& out, const V3Number& lhs) override {
|
2019-05-19 22:13:13 +02:00
|
|
|
out.opExtendS(lhs, lhsp()->widthMinV());
|
2015-05-15 03:46:07 +02:00
|
|
|
}
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual string emitVerilog() override { return "%l"; }
|
|
|
|
|
virtual string emitC() override { return "VL_EXTENDS_%nq%lq(%nw,%lw, %P, %li)"; }
|
|
|
|
|
virtual bool cleanOut() const override { return false; }
|
|
|
|
|
virtual bool cleanLhs() const override { return true; }
|
|
|
|
|
virtual bool sizeMattersLhs() const override {
|
2020-04-15 13:58:34 +02:00
|
|
|
return false; // Because the EXTEND operator self-casts
|
|
|
|
|
}
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual int instrCount() const override { return 0; }
|
|
|
|
|
virtual bool signedFlavor() const override { return true; }
|
2006-08-26 13:35:28 +02:00
|
|
|
};
|
2020-11-19 03:32:16 +01:00
|
|
|
class AstSigned final : public AstNodeUniop {
|
2006-08-26 13:35:28 +02:00
|
|
|
// $signed(lhs)
|
2014-09-12 03:28:53 +02:00
|
|
|
public:
|
2020-01-25 21:29:44 +01:00
|
|
|
AstSigned(FileLine* fl, AstNode* lhsp)
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_Signed(fl, lhsp) {
|
2019-07-07 15:01:36 +02:00
|
|
|
UASSERT_OBJ(!v3Global.assertDTypesResolved(), this,
|
2020-04-15 13:58:34 +02:00
|
|
|
"not coded to create after dtypes resolved");
|
|
|
|
|
}
|
2016-11-05 14:47:56 +01:00
|
|
|
ASTNODE_NODE_FUNCS(Signed)
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual void numberOperate(V3Number& out, const V3Number& lhs) override {
|
2020-04-15 13:58:34 +02:00
|
|
|
out.opAssign(lhs);
|
|
|
|
|
out.isSigned(false);
|
|
|
|
|
}
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual string emitVerilog() override { return "%f$signed(%l)"; }
|
|
|
|
|
virtual string emitC() override { V3ERROR_NA_RETURN(""); }
|
|
|
|
|
virtual bool cleanOut() const override { return false; }
|
|
|
|
|
virtual bool cleanLhs() const override { return false; } // Eliminated before matters
|
|
|
|
|
virtual bool sizeMattersLhs() const override { return true; } // Eliminated before matters
|
|
|
|
|
virtual int instrCount() const override { return 0; }
|
2006-08-26 13:35:28 +02:00
|
|
|
};
|
2020-11-19 03:32:16 +01:00
|
|
|
class AstUnsigned final : public AstNodeUniop {
|
2006-08-26 13:35:28 +02:00
|
|
|
// $unsigned(lhs)
|
2014-09-12 03:28:53 +02:00
|
|
|
public:
|
2020-01-25 21:29:44 +01:00
|
|
|
AstUnsigned(FileLine* fl, AstNode* lhsp)
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_Unsigned(fl, lhsp) {
|
2019-07-07 15:01:36 +02:00
|
|
|
UASSERT_OBJ(!v3Global.assertDTypesResolved(), this,
|
2020-04-15 13:58:34 +02:00
|
|
|
"not coded to create after dtypes resolved");
|
|
|
|
|
}
|
2016-11-05 14:47:56 +01:00
|
|
|
ASTNODE_NODE_FUNCS(Unsigned)
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual void numberOperate(V3Number& out, const V3Number& lhs) override {
|
2020-04-15 13:58:34 +02:00
|
|
|
out.opAssign(lhs);
|
|
|
|
|
out.isSigned(false);
|
|
|
|
|
}
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual string emitVerilog() override { return "%f$unsigned(%l)"; }
|
|
|
|
|
virtual string emitC() override { V3ERROR_NA_RETURN(""); }
|
|
|
|
|
virtual bool cleanOut() const override { return false; }
|
|
|
|
|
virtual bool cleanLhs() const override { return false; } // Eliminated before matters
|
|
|
|
|
virtual bool sizeMattersLhs() const override { return true; } // Eliminated before matters
|
|
|
|
|
virtual int instrCount() const override { return 0; }
|
2006-08-26 13:35:28 +02:00
|
|
|
};
|
2020-11-19 03:32:16 +01:00
|
|
|
class AstRToIS final : public AstNodeUniop {
|
2011-07-24 21:01:51 +02:00
|
|
|
// $rtoi(lhs)
|
2014-09-12 03:28:53 +02:00
|
|
|
public:
|
2020-01-25 21:29:44 +01:00
|
|
|
AstRToIS(FileLine* fl, AstNode* lhsp)
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_RToIS(fl, lhsp) {
|
2020-04-15 13:58:34 +02:00
|
|
|
dtypeSetSigned32();
|
|
|
|
|
}
|
2016-11-05 14:47:56 +01:00
|
|
|
ASTNODE_NODE_FUNCS(RToIS)
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual void numberOperate(V3Number& out, const V3Number& lhs) override { out.opRToIS(lhs); }
|
|
|
|
|
virtual string emitVerilog() override { return "%f$rtoi(%l)"; }
|
|
|
|
|
virtual string emitC() override { return "VL_RTOI_I_D(%li)"; }
|
|
|
|
|
virtual bool cleanOut() const override { return false; }
|
|
|
|
|
virtual bool cleanLhs() const override { return false; } // Eliminated before matters
|
|
|
|
|
virtual bool sizeMattersLhs() const override { return false; } // Eliminated before matters
|
2021-07-25 14:32:36 +02:00
|
|
|
virtual int instrCount() const override { return INSTR_COUNT_DBL; }
|
2011-07-24 21:01:51 +02:00
|
|
|
};
|
2020-11-19 03:32:16 +01:00
|
|
|
class AstRToIRoundS final : public AstNodeUniop {
|
2020-04-01 02:42:07 +02:00
|
|
|
// Convert real to integer, with arbitrary sized output (not just "integer" format)
|
2014-09-12 03:28:53 +02:00
|
|
|
public:
|
2020-01-25 21:29:44 +01:00
|
|
|
AstRToIRoundS(FileLine* fl, AstNode* lhsp)
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_RToIRoundS(fl, lhsp) {
|
2020-04-01 02:42:07 +02:00
|
|
|
dtypeSetSigned32();
|
|
|
|
|
}
|
2016-11-05 14:47:56 +01:00
|
|
|
ASTNODE_NODE_FUNCS(RToIRoundS)
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual void numberOperate(V3Number& out, const V3Number& lhs) override {
|
|
|
|
|
out.opRToIRoundS(lhs);
|
|
|
|
|
}
|
|
|
|
|
virtual string emitVerilog() override { return "%f$rtoi_rounded(%l)"; }
|
2021-11-28 19:44:16 +01:00
|
|
|
virtual string emitC() override {
|
|
|
|
|
return isWide() ? "VL_RTOIROUND_%nq_D(%nw, %P, %li)" : "VL_RTOIROUND_%nq_D(%li)";
|
|
|
|
|
}
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual bool cleanOut() const override { return false; }
|
|
|
|
|
virtual bool cleanLhs() const override { return false; }
|
|
|
|
|
virtual bool sizeMattersLhs() const override { return false; }
|
2021-07-25 14:32:36 +02:00
|
|
|
virtual int instrCount() const override { return INSTR_COUNT_DBL; }
|
2011-07-24 21:01:51 +02:00
|
|
|
};
|
2020-11-19 03:32:16 +01:00
|
|
|
class AstIToRD final : public AstNodeUniop {
|
2020-08-07 03:56:43 +02:00
|
|
|
// $itor where lhs is unsigned
|
2014-09-12 03:28:53 +02:00
|
|
|
public:
|
2020-01-25 21:29:44 +01:00
|
|
|
AstIToRD(FileLine* fl, AstNode* lhsp)
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_IToRD(fl, lhsp) {
|
2020-04-15 13:58:34 +02:00
|
|
|
dtypeSetDouble();
|
|
|
|
|
}
|
2016-11-05 14:47:56 +01:00
|
|
|
ASTNODE_NODE_FUNCS(IToRD)
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual void numberOperate(V3Number& out, const V3Number& lhs) override { out.opIToRD(lhs); }
|
|
|
|
|
virtual string emitVerilog() override { return "%f$itor(%l)"; }
|
|
|
|
|
virtual string emitC() override { return "VL_ITOR_D_%lq(%lw, %li)"; }
|
|
|
|
|
virtual bool cleanOut() const override { return false; }
|
|
|
|
|
virtual bool cleanLhs() const override { return true; }
|
|
|
|
|
virtual bool sizeMattersLhs() const override { return false; }
|
2021-07-25 14:32:36 +02:00
|
|
|
virtual int instrCount() const override { return INSTR_COUNT_DBL; }
|
2020-08-07 03:56:43 +02:00
|
|
|
};
|
2020-11-19 03:32:16 +01:00
|
|
|
class AstISToRD final : public AstNodeUniop {
|
2020-08-07 03:56:43 +02:00
|
|
|
// $itor where lhs is signed
|
|
|
|
|
public:
|
|
|
|
|
AstISToRD(FileLine* fl, AstNode* lhsp)
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_ISToRD(fl, lhsp) {
|
2020-08-07 03:56:43 +02:00
|
|
|
dtypeSetDouble();
|
|
|
|
|
}
|
|
|
|
|
ASTNODE_NODE_FUNCS(ISToRD)
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual void numberOperate(V3Number& out, const V3Number& lhs) override { out.opISToRD(lhs); }
|
|
|
|
|
virtual string emitVerilog() override { return "%f$itor($signed(%l))"; }
|
|
|
|
|
virtual string emitC() override { return "VL_ISTOR_D_%lq(%lw, %li)"; }
|
|
|
|
|
virtual bool emitCheckMaxWords() override { return true; }
|
|
|
|
|
virtual bool cleanOut() const override { return false; }
|
|
|
|
|
virtual bool cleanLhs() const override { return true; }
|
|
|
|
|
virtual bool sizeMattersLhs() const override { return false; }
|
2021-07-25 14:32:36 +02:00
|
|
|
virtual int instrCount() const override { return INSTR_COUNT_DBL; }
|
2011-07-24 21:01:51 +02:00
|
|
|
};
|
2020-11-19 03:32:16 +01:00
|
|
|
class AstRealToBits final : public AstNodeUniop {
|
2014-09-12 03:28:53 +02:00
|
|
|
public:
|
2020-01-25 21:29:44 +01:00
|
|
|
AstRealToBits(FileLine* fl, AstNode* lhsp)
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_RealToBits(fl, lhsp) {
|
2020-04-15 13:58:34 +02:00
|
|
|
dtypeSetUInt64();
|
|
|
|
|
}
|
2016-11-05 14:47:56 +01:00
|
|
|
ASTNODE_NODE_FUNCS(RealToBits)
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual void numberOperate(V3Number& out, const V3Number& lhs) override {
|
|
|
|
|
out.opRealToBits(lhs);
|
|
|
|
|
}
|
|
|
|
|
virtual string emitVerilog() override { return "%f$realtobits(%l)"; }
|
|
|
|
|
virtual string emitC() override { return "VL_CVT_Q_D(%li)"; }
|
|
|
|
|
virtual bool cleanOut() const override { return false; }
|
|
|
|
|
virtual bool cleanLhs() const override { return false; } // Eliminated before matters
|
|
|
|
|
virtual bool sizeMattersLhs() const override { return false; } // Eliminated before matters
|
2021-07-25 14:32:36 +02:00
|
|
|
virtual int instrCount() const override { return INSTR_COUNT_DBL; }
|
2011-07-24 21:01:51 +02:00
|
|
|
};
|
2020-11-19 03:32:16 +01:00
|
|
|
class AstBitsToRealD final : public AstNodeUniop {
|
2014-09-12 03:28:53 +02:00
|
|
|
public:
|
2020-01-25 21:29:44 +01:00
|
|
|
AstBitsToRealD(FileLine* fl, AstNode* lhsp)
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_BitsToRealD(fl, lhsp) {
|
2020-04-15 13:58:34 +02:00
|
|
|
dtypeSetDouble();
|
|
|
|
|
}
|
2016-11-05 14:47:56 +01:00
|
|
|
ASTNODE_NODE_FUNCS(BitsToRealD)
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual void numberOperate(V3Number& out, const V3Number& lhs) override {
|
|
|
|
|
out.opBitsToRealD(lhs);
|
|
|
|
|
}
|
|
|
|
|
virtual string emitVerilog() override { return "%f$bitstoreal(%l)"; }
|
|
|
|
|
virtual string emitC() override { return "VL_CVT_D_Q(%li)"; }
|
|
|
|
|
virtual bool cleanOut() const override { return false; }
|
|
|
|
|
virtual bool cleanLhs() const override { return false; } // Eliminated before matters
|
|
|
|
|
virtual bool sizeMattersLhs() const override { return false; } // Eliminated before matters
|
2021-07-25 14:32:36 +02:00
|
|
|
virtual int instrCount() const override { return INSTR_COUNT_DBL; }
|
2011-07-24 21:01:51 +02:00
|
|
|
};
|
|
|
|
|
|
2020-11-19 03:32:16 +01:00
|
|
|
class AstCLog2 final : public AstNodeUniop {
|
2014-09-12 03:28:53 +02:00
|
|
|
public:
|
2020-01-25 21:29:44 +01:00
|
|
|
AstCLog2(FileLine* fl, AstNode* lhsp)
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_CLog2(fl, lhsp) {}
|
2016-11-05 14:47:56 +01:00
|
|
|
ASTNODE_NODE_FUNCS(CLog2)
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual void numberOperate(V3Number& out, const V3Number& lhs) override { out.opCLog2(lhs); }
|
|
|
|
|
virtual string emitVerilog() override { return "%f$clog2(%l)"; }
|
|
|
|
|
virtual string emitC() override { return "VL_CLOG2_%lq(%lW, %P, %li)"; }
|
|
|
|
|
virtual bool cleanOut() const override { return false; }
|
|
|
|
|
virtual bool cleanLhs() const override { return true; }
|
|
|
|
|
virtual bool sizeMattersLhs() const override { return false; }
|
|
|
|
|
virtual int instrCount() const override { return widthInstrs() * 16; }
|
2008-04-24 15:52:51 +02:00
|
|
|
};
|
2020-11-19 03:32:16 +01:00
|
|
|
class AstCountBits final : public AstNodeQuadop {
|
2020-05-10 20:27:22 +02:00
|
|
|
// Number of bits set in vector
|
|
|
|
|
public:
|
|
|
|
|
AstCountBits(FileLine* fl, AstNode* exprp, AstNode* ctrl1p)
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_CountBits(fl, exprp, ctrl1p, ctrl1p->cloneTree(false),
|
|
|
|
|
ctrl1p->cloneTree(false)) {}
|
2020-05-10 20:27:22 +02:00
|
|
|
AstCountBits(FileLine* fl, AstNode* exprp, AstNode* ctrl1p, AstNode* ctrl2p)
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_CountBits(fl, exprp, ctrl1p, ctrl2p, ctrl2p->cloneTree(false)) {}
|
2020-05-10 20:27:22 +02:00
|
|
|
AstCountBits(FileLine* fl, AstNode* exprp, AstNode* ctrl1p, AstNode* ctrl2p, AstNode* ctrl3p)
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_CountBits(fl, exprp, ctrl1p, ctrl2p, ctrl3p) {}
|
2020-05-10 20:27:22 +02:00
|
|
|
ASTNODE_NODE_FUNCS(CountBits)
|
|
|
|
|
virtual void numberOperate(V3Number& out, const V3Number& expr, const V3Number& ctrl1,
|
2020-08-15 17:44:10 +02:00
|
|
|
const V3Number& ctrl2, const V3Number& ctrl3) override {
|
2020-05-10 20:27:22 +02:00
|
|
|
out.opCountBits(expr, ctrl1, ctrl2, ctrl3);
|
|
|
|
|
}
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual string emitVerilog() override { return "%f$countbits(%l, %r, %f, %o)"; }
|
|
|
|
|
virtual string emitC() override { return ""; }
|
|
|
|
|
virtual bool cleanOut() const override { return false; }
|
|
|
|
|
virtual bool cleanLhs() const override { return true; }
|
|
|
|
|
virtual bool cleanRhs() const override { return true; }
|
|
|
|
|
virtual bool cleanThs() const override { return true; }
|
|
|
|
|
virtual bool cleanFhs() const override { return true; }
|
|
|
|
|
virtual bool sizeMattersLhs() const override { return false; }
|
|
|
|
|
virtual bool sizeMattersRhs() const override { return false; }
|
|
|
|
|
virtual bool sizeMattersThs() const override { return false; }
|
|
|
|
|
virtual bool sizeMattersFhs() const override { return false; }
|
|
|
|
|
virtual int instrCount() const override { return widthInstrs() * 16; }
|
2020-05-10 20:27:22 +02:00
|
|
|
};
|
2020-11-19 03:32:16 +01:00
|
|
|
class AstCountOnes final : public AstNodeUniop {
|
2006-08-26 13:35:28 +02:00
|
|
|
// Number of bits set in vector
|
2014-09-12 03:28:53 +02:00
|
|
|
public:
|
2020-01-25 21:29:44 +01:00
|
|
|
AstCountOnes(FileLine* fl, AstNode* lhsp)
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_CountOnes(fl, lhsp) {}
|
2016-11-05 14:47:56 +01:00
|
|
|
ASTNODE_NODE_FUNCS(CountOnes)
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual void numberOperate(V3Number& out, const V3Number& lhs) override {
|
|
|
|
|
out.opCountOnes(lhs);
|
|
|
|
|
}
|
|
|
|
|
virtual string emitVerilog() override { return "%f$countones(%l)"; }
|
|
|
|
|
virtual string emitC() override { return "VL_COUNTONES_%lq(%lW, %P, %li)"; }
|
|
|
|
|
virtual bool cleanOut() const override { return false; }
|
|
|
|
|
virtual bool cleanLhs() const override { return true; }
|
|
|
|
|
virtual bool sizeMattersLhs() const override { return false; }
|
|
|
|
|
virtual int instrCount() const override { return widthInstrs() * 16; }
|
2006-08-26 13:35:28 +02:00
|
|
|
};
|
2020-11-19 03:32:16 +01:00
|
|
|
class AstIsUnknown final : public AstNodeUniop {
|
2006-08-26 13:35:28 +02:00
|
|
|
// True if any unknown bits
|
2014-09-12 03:28:53 +02:00
|
|
|
public:
|
2020-01-25 21:29:44 +01:00
|
|
|
AstIsUnknown(FileLine* fl, AstNode* lhsp)
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_IsUnknown(fl, lhsp) {
|
2020-11-29 14:23:36 +01:00
|
|
|
dtypeSetBit();
|
2020-04-15 13:58:34 +02:00
|
|
|
}
|
2016-11-05 14:47:56 +01:00
|
|
|
ASTNODE_NODE_FUNCS(IsUnknown)
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual void numberOperate(V3Number& out, const V3Number& lhs) override {
|
|
|
|
|
out.opIsUnknown(lhs);
|
|
|
|
|
}
|
|
|
|
|
virtual string emitVerilog() override { return "%f$isunknown(%l)"; }
|
|
|
|
|
virtual string emitC() override { V3ERROR_NA_RETURN(""); }
|
|
|
|
|
virtual bool cleanOut() const override { return false; }
|
|
|
|
|
virtual bool cleanLhs() const override { return false; }
|
|
|
|
|
virtual bool sizeMattersLhs() const override { return false; }
|
2006-08-26 13:35:28 +02:00
|
|
|
};
|
2020-11-19 03:32:16 +01:00
|
|
|
class AstIsUnbounded final : public AstNodeUniop {
|
2020-05-08 03:09:14 +02:00
|
|
|
// True if is unmbounded ($)
|
|
|
|
|
public:
|
|
|
|
|
AstIsUnbounded(FileLine* fl, AstNode* lhsp)
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_IsUnbounded(fl, lhsp) {
|
2020-11-29 14:23:36 +01:00
|
|
|
dtypeSetBit();
|
2020-05-08 03:09:14 +02:00
|
|
|
}
|
|
|
|
|
ASTNODE_NODE_FUNCS(IsUnbounded)
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual void numberOperate(V3Number& out, const V3Number&) override {
|
2020-05-08 03:09:14 +02:00
|
|
|
// Any constant isn't unbounded
|
|
|
|
|
out.setZero();
|
|
|
|
|
}
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual string emitVerilog() override { return "%f$isunbounded(%l)"; }
|
|
|
|
|
virtual string emitC() override { V3ERROR_NA_RETURN(""); }
|
|
|
|
|
virtual bool cleanOut() const override { return false; }
|
|
|
|
|
virtual bool cleanLhs() const override { return false; }
|
|
|
|
|
virtual bool sizeMattersLhs() const override { return false; }
|
2020-05-08 03:09:14 +02:00
|
|
|
};
|
2020-11-19 03:32:16 +01:00
|
|
|
class AstOneHot final : public AstNodeUniop {
|
2006-08-26 13:35:28 +02:00
|
|
|
// True if only single bit set in vector
|
2014-09-12 03:28:53 +02:00
|
|
|
public:
|
2020-01-25 21:29:44 +01:00
|
|
|
AstOneHot(FileLine* fl, AstNode* lhsp)
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_OneHot(fl, lhsp) {
|
2020-11-29 14:23:36 +01:00
|
|
|
dtypeSetBit();
|
2020-04-15 13:58:34 +02:00
|
|
|
}
|
2016-11-05 14:47:56 +01:00
|
|
|
ASTNODE_NODE_FUNCS(OneHot)
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual void numberOperate(V3Number& out, const V3Number& lhs) override { out.opOneHot(lhs); }
|
|
|
|
|
virtual string emitVerilog() override { return "%f$onehot(%l)"; }
|
|
|
|
|
virtual string emitC() override { return "VL_ONEHOT_%lq(%lW, %P, %li)"; }
|
|
|
|
|
virtual bool cleanOut() const override { return true; }
|
|
|
|
|
virtual bool cleanLhs() const override { return true; }
|
|
|
|
|
virtual bool sizeMattersLhs() const override { return false; }
|
|
|
|
|
virtual int instrCount() const override { return widthInstrs() * 4; }
|
2006-08-26 13:35:28 +02:00
|
|
|
};
|
2020-11-19 03:32:16 +01:00
|
|
|
class AstOneHot0 final : public AstNodeUniop {
|
2006-08-26 13:35:28 +02:00
|
|
|
// True if only single bit, or no bits set in vector
|
2014-09-12 03:28:53 +02:00
|
|
|
public:
|
2020-01-25 21:29:44 +01:00
|
|
|
AstOneHot0(FileLine* fl, AstNode* lhsp)
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_OneHot0(fl, lhsp) {
|
2020-11-29 14:23:36 +01:00
|
|
|
dtypeSetBit();
|
2020-04-15 13:58:34 +02:00
|
|
|
}
|
2016-11-05 14:47:56 +01:00
|
|
|
ASTNODE_NODE_FUNCS(OneHot0)
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual void numberOperate(V3Number& out, const V3Number& lhs) override { out.opOneHot0(lhs); }
|
|
|
|
|
virtual string emitVerilog() override { return "%f$onehot0(%l)"; }
|
|
|
|
|
virtual string emitC() override { return "VL_ONEHOT0_%lq(%lW, %P, %li)"; }
|
|
|
|
|
virtual bool cleanOut() const override { return true; }
|
|
|
|
|
virtual bool cleanLhs() const override { return true; }
|
|
|
|
|
virtual bool sizeMattersLhs() const override { return false; }
|
|
|
|
|
virtual int instrCount() const override { return widthInstrs() * 3; }
|
2006-08-26 13:35:28 +02:00
|
|
|
};
|
|
|
|
|
|
2020-11-19 03:32:16 +01:00
|
|
|
class AstCast final : public AstNode {
|
2011-03-18 03:25:49 +01:00
|
|
|
// Cast to appropriate data type - note lhsp is value, to match AstTypedef, AstCCast, etc
|
2014-09-12 03:28:53 +02:00
|
|
|
public:
|
2020-11-30 00:26:06 +01:00
|
|
|
AstCast(FileLine* fl, AstNode* lhsp, VFlagChildDType, AstNodeDType* dtp)
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_Cast(fl) {
|
2020-04-15 13:58:34 +02:00
|
|
|
setOp1p(lhsp);
|
|
|
|
|
setOp2p(dtp);
|
2019-05-19 22:13:13 +02:00
|
|
|
dtypeFrom(dtp);
|
2011-03-18 03:25:49 +01:00
|
|
|
}
|
2020-11-30 00:26:06 +01:00
|
|
|
AstCast(FileLine* fl, AstNode* lhsp, AstNodeDType* dtp)
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_Cast(fl) {
|
2020-11-30 00:26:06 +01:00
|
|
|
setOp1p(lhsp);
|
|
|
|
|
dtypeFrom(dtp);
|
|
|
|
|
}
|
2016-11-05 14:47:56 +01:00
|
|
|
ASTNODE_NODE_FUNCS(Cast)
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual bool hasDType() const override { return true; }
|
2012-04-29 16:14:13 +02:00
|
|
|
virtual string emitVerilog() { return "((%d)'(%l))"; }
|
2020-04-05 16:26:53 +02:00
|
|
|
virtual bool cleanOut() const { V3ERROR_NA_RETURN(true); }
|
2019-10-20 17:58:41 +02:00
|
|
|
virtual bool cleanLhs() const { return true; }
|
|
|
|
|
virtual bool sizeMattersLhs() const { return false; }
|
2011-03-18 03:25:49 +01:00
|
|
|
AstNode* lhsp() const { return op1p(); }
|
2020-12-05 23:11:00 +01:00
|
|
|
AstNode* fromp() const { return lhsp(); }
|
2020-11-09 01:07:33 +01:00
|
|
|
void lhsp(AstNode* nodep) { setOp1p(nodep); }
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual AstNodeDType* getChildDTypep() const override { return childDTypep(); }
|
2021-10-22 14:56:48 +02:00
|
|
|
AstNodeDType* childDTypep() const { return VN_AS(op2p(), NodeDType); }
|
2020-06-08 12:47:18 +02:00
|
|
|
virtual AstNodeDType* subDTypep() const { return dtypep() ? dtypep() : childDTypep(); }
|
2011-03-18 03:25:49 +01:00
|
|
|
};
|
|
|
|
|
|
2020-11-19 03:32:16 +01:00
|
|
|
class AstCastDynamic final : public AstNodeBiop {
|
2020-10-25 02:30:52 +02:00
|
|
|
// Verilog $cast used as a function
|
|
|
|
|
// Task usage of $cast is converted during parse to assert($cast(...))
|
|
|
|
|
// Parents: MATH
|
|
|
|
|
// Children: MATH
|
2020-12-05 23:11:00 +01:00
|
|
|
// lhsp() is value (we are converting FROM) to match AstCCast etc, this
|
|
|
|
|
// is opposite of $cast's order, because the first access is to the
|
|
|
|
|
// value reading from. Suggest use fromp()/top() instead of lhsp/rhsp().
|
2020-06-06 15:30:11 +02:00
|
|
|
public:
|
|
|
|
|
AstCastDynamic(FileLine* fl, AstNode* lhsp, AstNode* rhsp)
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_CastDynamic(fl, lhsp, rhsp) {}
|
2020-06-06 15:30:11 +02:00
|
|
|
ASTNODE_NODE_FUNCS(CastDynamic)
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) override {
|
2020-06-06 15:30:11 +02:00
|
|
|
V3ERROR_NA;
|
|
|
|
|
}
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual AstNode* cloneType(AstNode* lhsp, AstNode* rhsp) override {
|
2020-06-06 15:30:11 +02:00
|
|
|
return new AstCastDynamic(this->fileline(), lhsp, rhsp);
|
|
|
|
|
}
|
2020-12-06 04:58:36 +01:00
|
|
|
virtual string emitVerilog() override { return "%f$cast(%r, %l)"; }
|
|
|
|
|
virtual string emitC() override { return "VL_DYNAMIC_CAST(%r, %l)"; }
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual bool cleanOut() const override { return true; }
|
|
|
|
|
virtual bool cleanLhs() const override { return true; }
|
|
|
|
|
virtual bool cleanRhs() const override { return true; }
|
|
|
|
|
virtual bool sizeMattersLhs() const override { return false; }
|
|
|
|
|
virtual bool sizeMattersRhs() const override { return false; }
|
|
|
|
|
virtual int instrCount() const override { return widthInstrs() * 20; }
|
|
|
|
|
virtual bool isPure() const override { return true; }
|
2020-12-05 23:11:00 +01:00
|
|
|
AstNode* fromp() const { return lhsp(); }
|
|
|
|
|
AstNode* top() const { return rhsp(); }
|
2020-06-06 15:30:11 +02:00
|
|
|
};
|
|
|
|
|
|
2020-11-19 03:32:16 +01:00
|
|
|
class AstCastParse final : public AstNode {
|
2014-12-24 04:11:31 +01:00
|
|
|
// Cast to appropriate type, where we haven't determined yet what the data type is
|
|
|
|
|
public:
|
2020-01-25 21:29:44 +01:00
|
|
|
AstCastParse(FileLine* fl, AstNode* lhsp, AstNode* dtp)
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_CastParse(fl) {
|
2020-04-15 13:58:34 +02:00
|
|
|
setOp1p(lhsp);
|
|
|
|
|
setOp2p(dtp);
|
2014-12-24 04:11:31 +01:00
|
|
|
}
|
2016-11-05 14:47:56 +01:00
|
|
|
ASTNODE_NODE_FUNCS(CastParse)
|
2014-12-24 04:11:31 +01:00
|
|
|
virtual string emitVerilog() { return "((%d)'(%l))"; }
|
2020-04-05 16:26:53 +02:00
|
|
|
virtual string emitC() { V3ERROR_NA_RETURN(""); }
|
|
|
|
|
virtual bool cleanOut() const { V3ERROR_NA_RETURN(true); }
|
2019-10-20 17:58:41 +02:00
|
|
|
virtual bool cleanLhs() const { return true; }
|
|
|
|
|
virtual bool sizeMattersLhs() const { return false; }
|
2014-12-24 04:11:31 +01:00
|
|
|
AstNode* lhsp() const { return op1p(); }
|
|
|
|
|
AstNode* dtp() const { return op2p(); }
|
|
|
|
|
};
|
|
|
|
|
|
2020-11-19 03:32:16 +01:00
|
|
|
class AstCastSize final : public AstNode {
|
2013-03-06 04:13:22 +01:00
|
|
|
// Cast to specific size; signed/twostate inherited from lower element per IEEE
|
2014-09-12 03:28:53 +02:00
|
|
|
public:
|
2020-01-25 21:29:44 +01:00
|
|
|
AstCastSize(FileLine* fl, AstNode* lhsp, AstConst* rhsp)
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_CastSize(fl) {
|
2020-04-15 13:58:34 +02:00
|
|
|
setOp1p(lhsp);
|
|
|
|
|
setOp2p(rhsp);
|
2013-03-06 04:13:22 +01:00
|
|
|
}
|
2016-11-05 14:47:56 +01:00
|
|
|
ASTNODE_NODE_FUNCS(CastSize)
|
2015-08-13 01:37:25 +02:00
|
|
|
// No hasDType because widthing removes this node before the hasDType check
|
2013-03-06 04:13:22 +01:00
|
|
|
virtual string emitVerilog() { return "((%r)'(%l))"; }
|
2020-04-05 16:26:53 +02:00
|
|
|
virtual bool cleanOut() const { V3ERROR_NA_RETURN(true); }
|
2019-10-20 17:58:41 +02:00
|
|
|
virtual bool cleanLhs() const { return true; }
|
|
|
|
|
virtual bool sizeMattersLhs() const { return false; }
|
2013-03-06 04:13:22 +01:00
|
|
|
AstNode* lhsp() const { return op1p(); }
|
|
|
|
|
AstNode* rhsp() const { return op2p(); }
|
|
|
|
|
};
|
|
|
|
|
|
2020-11-19 03:32:16 +01:00
|
|
|
class AstCCast final : public AstNodeUniop {
|
2011-03-18 03:25:49 +01:00
|
|
|
// Cast to C-based data type
|
2006-08-26 13:35:28 +02:00
|
|
|
private:
|
2020-04-15 13:58:34 +02:00
|
|
|
int m_size;
|
|
|
|
|
|
2006-08-26 13:35:28 +02:00
|
|
|
public:
|
2020-04-15 13:58:34 +02:00
|
|
|
AstCCast(FileLine* fl, AstNode* lhsp, int setwidth, int minwidth = -1)
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_CCast(fl, lhsp) {
|
2019-05-19 22:13:13 +02:00
|
|
|
m_size = setwidth;
|
|
|
|
|
if (setwidth) {
|
2020-04-15 13:58:34 +02:00
|
|
|
if (minwidth == -1) minwidth = setwidth;
|
2020-04-20 03:19:09 +02:00
|
|
|
dtypeSetLogicUnsized(setwidth, minwidth, VSigning::UNSIGNED);
|
2019-05-19 22:13:13 +02:00
|
|
|
}
|
2006-08-26 13:35:28 +02:00
|
|
|
}
|
2020-01-25 21:29:44 +01:00
|
|
|
AstCCast(FileLine* fl, AstNode* lhsp, AstNode* typeFromp)
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_CCast(fl, lhsp) {
|
2019-05-19 22:13:13 +02:00
|
|
|
dtypeFrom(typeFromp);
|
|
|
|
|
m_size = width();
|
2006-08-26 13:35:28 +02:00
|
|
|
}
|
2016-11-05 14:47:56 +01:00
|
|
|
ASTNODE_NODE_FUNCS(CCast)
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual void numberOperate(V3Number& out, const V3Number& lhs) override { out.opAssign(lhs); }
|
|
|
|
|
virtual string emitVerilog() override { return "%f$_CAST(%l)"; }
|
|
|
|
|
virtual string emitC() override { return "VL_CAST_%nq%lq(%nw,%lw, %P, %li)"; }
|
|
|
|
|
virtual bool cleanOut() const override { return true; }
|
|
|
|
|
virtual bool cleanLhs() const override { return true; }
|
|
|
|
|
virtual bool sizeMattersLhs() const override { return false; } // Special cased in V3Cast
|
|
|
|
|
virtual bool same(const AstNode* samep) const override {
|
2020-04-15 13:58:34 +02:00
|
|
|
return size() == static_cast<const AstCCast*>(samep)->size();
|
|
|
|
|
}
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual void dump(std::ostream& str = std::cout) const override;
|
2006-08-26 13:35:28 +02:00
|
|
|
//
|
2019-05-19 22:13:13 +02:00
|
|
|
int size() const { return m_size; }
|
2006-08-26 13:35:28 +02:00
|
|
|
};
|
|
|
|
|
|
2020-11-19 03:32:16 +01:00
|
|
|
class AstCvtPackString final : public AstNodeUniop {
|
2014-11-28 21:01:50 +01:00
|
|
|
// Convert to Verilator Packed String (aka verilog "string")
|
2014-09-12 03:28:53 +02:00
|
|
|
public:
|
2020-01-25 21:29:44 +01:00
|
|
|
AstCvtPackString(FileLine* fl, AstNode* lhsp)
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_CvtPackString(fl, lhsp) {
|
2020-04-15 13:58:34 +02:00
|
|
|
dtypeSetString();
|
|
|
|
|
}
|
2016-11-05 14:47:56 +01:00
|
|
|
ASTNODE_NODE_FUNCS(CvtPackString)
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual void numberOperate(V3Number& out, const V3Number& lhs) override { V3ERROR_NA; }
|
|
|
|
|
virtual string emitVerilog() override { return "%f$_CAST(%l)"; }
|
|
|
|
|
virtual string emitC() override { return "VL_CVT_PACK_STR_N%lq(%lW, %li)"; }
|
|
|
|
|
virtual bool cleanOut() const override { return true; }
|
|
|
|
|
virtual bool cleanLhs() const override { return true; }
|
|
|
|
|
virtual bool sizeMattersLhs() const override { return false; }
|
|
|
|
|
virtual bool same(const AstNode* samep) const override { return true; }
|
2010-01-17 21:10:37 +01:00
|
|
|
};
|
|
|
|
|
|
2020-11-19 03:32:16 +01:00
|
|
|
class AstFEof final : public AstNodeUniop {
|
2014-09-12 03:28:53 +02:00
|
|
|
public:
|
2020-01-25 21:29:44 +01:00
|
|
|
AstFEof(FileLine* fl, AstNode* lhsp)
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_FEof(fl, lhsp) {}
|
2016-11-05 14:47:56 +01:00
|
|
|
ASTNODE_NODE_FUNCS(FEof)
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual void numberOperate(V3Number& out, const V3Number& lhs) override { V3ERROR_NA; }
|
|
|
|
|
virtual string emitVerilog() override { return "%f$feof(%l)"; }
|
|
|
|
|
virtual string emitC() override { return "(%li ? feof(VL_CVT_I_FP(%li)) : true)"; }
|
|
|
|
|
virtual bool cleanOut() const override { return true; }
|
|
|
|
|
virtual bool cleanLhs() const override { return true; }
|
|
|
|
|
virtual bool sizeMattersLhs() const override { return false; }
|
|
|
|
|
virtual int instrCount() const override { return widthInstrs() * 16; }
|
|
|
|
|
virtual bool isPure() const override {
|
|
|
|
|
return false;
|
|
|
|
|
} // SPECIAL: $display has 'visual' ordering
|
2019-05-19 22:13:13 +02:00
|
|
|
AstNode* filep() const { return lhsp(); }
|
2008-06-26 14:52:02 +02:00
|
|
|
};
|
|
|
|
|
|
2020-11-19 03:32:16 +01:00
|
|
|
class AstFError final : public AstNodeMath {
|
2020-04-05 17:22:05 +02:00
|
|
|
public:
|
|
|
|
|
AstFError(FileLine* fl, AstNode* filep, AstNode* strp)
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_FError(fl) {
|
2020-04-05 17:22:05 +02:00
|
|
|
setOp1p(filep);
|
|
|
|
|
setOp2p(strp);
|
|
|
|
|
}
|
|
|
|
|
ASTNODE_NODE_FUNCS(FError)
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual string emitVerilog() override { return "%f$ferror(%l, %r)"; }
|
|
|
|
|
virtual string emitC() override { V3ERROR_NA_RETURN(""); }
|
|
|
|
|
virtual bool cleanOut() const override { return true; }
|
2020-04-05 17:22:05 +02:00
|
|
|
virtual bool cleanLhs() const { return true; }
|
|
|
|
|
virtual bool sizeMattersLhs() const { return false; }
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual int instrCount() const override { return widthInstrs() * 64; }
|
|
|
|
|
virtual bool isPure() const override {
|
|
|
|
|
return false;
|
|
|
|
|
} // SPECIAL: $display has 'visual' ordering
|
2020-04-05 17:22:05 +02:00
|
|
|
void filep(AstNode* nodep) { setOp1p(nodep); }
|
|
|
|
|
AstNode* filep() const { return op1p(); }
|
|
|
|
|
void strp(AstNode* nodep) { setOp2p(nodep); }
|
|
|
|
|
AstNode* strp() const { return op2p(); }
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual bool same(const AstNode* samep) const override { return true; }
|
2020-04-05 17:22:05 +02:00
|
|
|
};
|
|
|
|
|
|
2020-11-19 03:32:16 +01:00
|
|
|
class AstFGetC final : public AstNodeUniop {
|
2014-09-12 03:28:53 +02:00
|
|
|
public:
|
2020-01-25 21:29:44 +01:00
|
|
|
AstFGetC(FileLine* fl, AstNode* lhsp)
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_FGetC(fl, lhsp) {}
|
2016-11-05 14:47:56 +01:00
|
|
|
ASTNODE_NODE_FUNCS(FGetC)
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual void numberOperate(V3Number& out, const V3Number& lhs) override { V3ERROR_NA; }
|
|
|
|
|
virtual string emitVerilog() override { return "%f$fgetc(%l)"; }
|
2009-12-17 03:28:35 +01:00
|
|
|
// Non-existent filehandle returns EOF
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual string emitC() override { return "(%li ? fgetc(VL_CVT_I_FP(%li)) : -1)"; }
|
|
|
|
|
virtual bool cleanOut() const override { return false; }
|
|
|
|
|
virtual bool cleanLhs() const override { return true; }
|
|
|
|
|
virtual bool sizeMattersLhs() const override { return false; }
|
|
|
|
|
virtual int instrCount() const override { return widthInstrs() * 64; }
|
|
|
|
|
virtual bool isPure() const override {
|
|
|
|
|
return false;
|
|
|
|
|
} // SPECIAL: $display has 'visual' ordering
|
2019-05-19 22:13:13 +02:00
|
|
|
AstNode* filep() const { return lhsp(); }
|
2008-06-28 02:04:20 +02:00
|
|
|
};
|
|
|
|
|
|
2020-11-19 03:32:16 +01:00
|
|
|
class AstFUngetC final : public AstNodeBiop {
|
2019-11-16 18:55:10 +01:00
|
|
|
public:
|
|
|
|
|
AstFUngetC(FileLine* fl, AstNode* lhsp, AstNode* rhsp)
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_FUngetC(fl, lhsp, rhsp) {}
|
2019-11-16 18:55:10 +01:00
|
|
|
ASTNODE_NODE_FUNCS(FUngetC)
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) override {
|
2020-04-15 13:58:34 +02:00
|
|
|
V3ERROR_NA;
|
|
|
|
|
}
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual AstNode* cloneType(AstNode* lhsp, AstNode* rhsp) override {
|
2020-04-15 13:58:34 +02:00
|
|
|
return new AstFUngetC(this->fileline(), lhsp, rhsp);
|
|
|
|
|
}
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual string emitVerilog() override { return "%f$ungetc(%r, %l)"; }
|
2019-11-16 18:55:10 +01:00
|
|
|
// Non-existent filehandle returns EOF
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual string emitC() override {
|
|
|
|
|
return "(%li ? (ungetc(%ri, VL_CVT_I_FP(%li)) >= 0 ? 0 : -1) : -1)";
|
|
|
|
|
}
|
|
|
|
|
virtual bool cleanOut() const override { return false; }
|
|
|
|
|
virtual bool cleanLhs() const override { return true; }
|
|
|
|
|
virtual bool cleanRhs() const override { return true; }
|
|
|
|
|
virtual bool sizeMattersLhs() const override { return false; }
|
|
|
|
|
virtual bool sizeMattersRhs() const override { return false; }
|
|
|
|
|
virtual int instrCount() const override { return widthInstrs() * 64; }
|
|
|
|
|
virtual bool isPure() const override {
|
|
|
|
|
return false;
|
|
|
|
|
} // SPECIAL: $display has 'visual' ordering
|
2019-11-16 18:55:10 +01:00
|
|
|
AstNode* filep() const { return lhsp(); }
|
|
|
|
|
AstNode* charp() const { return rhsp(); }
|
|
|
|
|
};
|
|
|
|
|
|
2020-11-19 03:32:16 +01:00
|
|
|
class AstNodeSystemUniop VL_NOT_FINAL : public AstNodeUniop {
|
2014-09-12 03:28:53 +02:00
|
|
|
public:
|
2020-01-25 21:29:44 +01:00
|
|
|
AstNodeSystemUniop(AstType t, FileLine* fl, AstNode* lhsp)
|
2020-04-15 13:58:34 +02:00
|
|
|
: AstNodeUniop(t, fl, lhsp) {
|
|
|
|
|
dtypeSetDouble();
|
|
|
|
|
}
|
2018-03-11 15:37:20 +01:00
|
|
|
ASTNODE_BASE_FUNCS(NodeSystemUniop)
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual bool cleanOut() const override { return true; }
|
|
|
|
|
virtual bool cleanLhs() const override { return false; }
|
|
|
|
|
virtual bool sizeMattersLhs() const override { return false; }
|
2021-07-25 14:32:36 +02:00
|
|
|
virtual int instrCount() const override { return INSTR_COUNT_DBL_TRIG; }
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual bool doubleFlavor() const override { return true; }
|
2011-09-29 03:35:16 +02:00
|
|
|
};
|
|
|
|
|
|
2020-11-19 03:32:16 +01:00
|
|
|
class AstLogD final : public AstNodeSystemUniop {
|
2014-09-12 03:28:53 +02:00
|
|
|
public:
|
2020-01-25 21:29:44 +01:00
|
|
|
AstLogD(FileLine* fl, AstNode* lhsp)
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_LogD(fl, lhsp) {}
|
2018-02-26 10:25:07 +01:00
|
|
|
ASTNODE_NODE_FUNCS(LogD)
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual void numberOperate(V3Number& out, const V3Number& lhs) override {
|
2021-03-27 02:23:18 +01:00
|
|
|
out.setDouble(std::log(lhs.toDouble()));
|
2020-04-15 13:58:34 +02:00
|
|
|
}
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual string emitVerilog() override { return "%f$ln(%l)"; }
|
|
|
|
|
virtual string emitC() override { return "log(%li)"; }
|
2018-02-26 10:25:07 +01:00
|
|
|
};
|
2020-11-19 03:32:16 +01:00
|
|
|
class AstLog10D final : public AstNodeSystemUniop {
|
2018-02-26 10:25:07 +01:00
|
|
|
public:
|
2020-01-25 21:29:44 +01:00
|
|
|
AstLog10D(FileLine* fl, AstNode* lhsp)
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_Log10D(fl, lhsp) {}
|
2018-02-26 10:25:07 +01:00
|
|
|
ASTNODE_NODE_FUNCS(Log10D)
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual void numberOperate(V3Number& out, const V3Number& lhs) override {
|
2021-03-27 02:23:18 +01:00
|
|
|
out.setDouble(std::log10(lhs.toDouble()));
|
2020-04-15 13:58:34 +02:00
|
|
|
}
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual string emitVerilog() override { return "%f$log10(%l)"; }
|
|
|
|
|
virtual string emitC() override { return "log10(%li)"; }
|
2018-02-26 10:25:07 +01:00
|
|
|
};
|
|
|
|
|
|
2020-11-19 03:32:16 +01:00
|
|
|
class AstExpD final : public AstNodeSystemUniop {
|
2018-02-26 10:25:07 +01:00
|
|
|
public:
|
2020-01-25 21:29:44 +01:00
|
|
|
AstExpD(FileLine* fl, AstNode* lhsp)
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_ExpD(fl, lhsp) {}
|
2016-11-05 14:47:56 +01:00
|
|
|
ASTNODE_NODE_FUNCS(ExpD)
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual void numberOperate(V3Number& out, const V3Number& lhs) override {
|
2021-03-27 02:23:18 +01:00
|
|
|
out.setDouble(std::exp(lhs.toDouble()));
|
2020-04-15 13:58:34 +02:00
|
|
|
}
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual string emitVerilog() override { return "%f$exp(%l)"; }
|
|
|
|
|
virtual string emitC() override { return "exp(%li)"; }
|
2011-09-29 03:35:16 +02:00
|
|
|
};
|
|
|
|
|
|
2020-11-19 03:32:16 +01:00
|
|
|
class AstSqrtD final : public AstNodeSystemUniop {
|
2014-09-12 03:28:53 +02:00
|
|
|
public:
|
2020-01-25 21:29:44 +01:00
|
|
|
AstSqrtD(FileLine* fl, AstNode* lhsp)
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_SqrtD(fl, lhsp) {}
|
2018-02-26 10:25:07 +01:00
|
|
|
ASTNODE_NODE_FUNCS(SqrtD)
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual void numberOperate(V3Number& out, const V3Number& lhs) override {
|
2021-03-27 02:23:18 +01:00
|
|
|
out.setDouble(std::sqrt(lhs.toDouble()));
|
2020-04-15 13:58:34 +02:00
|
|
|
}
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual string emitVerilog() override { return "%f$sqrt(%l)"; }
|
|
|
|
|
virtual string emitC() override { return "sqrt(%li)"; }
|
2018-02-26 10:25:07 +01:00
|
|
|
};
|
|
|
|
|
|
2020-11-19 03:32:16 +01:00
|
|
|
class AstFloorD final : public AstNodeSystemUniop {
|
2018-02-26 10:25:07 +01:00
|
|
|
public:
|
2020-01-25 21:29:44 +01:00
|
|
|
AstFloorD(FileLine* fl, AstNode* lhsp)
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_FloorD(fl, lhsp) {}
|
2016-11-05 14:47:56 +01:00
|
|
|
ASTNODE_NODE_FUNCS(FloorD)
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual void numberOperate(V3Number& out, const V3Number& lhs) override {
|
2021-03-27 02:23:18 +01:00
|
|
|
out.setDouble(std::floor(lhs.toDouble()));
|
2020-04-15 13:58:34 +02:00
|
|
|
}
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual string emitVerilog() override { return "%f$floor(%l)"; }
|
|
|
|
|
virtual string emitC() override { return "floor(%li)"; }
|
2011-09-29 03:35:16 +02:00
|
|
|
};
|
|
|
|
|
|
2020-11-19 03:32:16 +01:00
|
|
|
class AstCeilD final : public AstNodeSystemUniop {
|
2014-09-12 03:28:53 +02:00
|
|
|
public:
|
2020-01-25 21:29:44 +01:00
|
|
|
AstCeilD(FileLine* fl, AstNode* lhsp)
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_CeilD(fl, lhsp) {}
|
2018-02-26 10:25:07 +01:00
|
|
|
ASTNODE_NODE_FUNCS(CeilD)
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual void numberOperate(V3Number& out, const V3Number& lhs) override {
|
2021-03-27 02:23:18 +01:00
|
|
|
out.setDouble(std::ceil(lhs.toDouble()));
|
2020-04-15 13:58:34 +02:00
|
|
|
}
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual string emitVerilog() override { return "%f$ceil(%l)"; }
|
|
|
|
|
virtual string emitC() override { return "ceil(%li)"; }
|
2011-09-29 03:35:16 +02:00
|
|
|
};
|
|
|
|
|
|
2020-11-19 03:32:16 +01:00
|
|
|
class AstSinD final : public AstNodeSystemUniop {
|
2014-09-12 03:28:53 +02:00
|
|
|
public:
|
2020-01-25 21:29:44 +01:00
|
|
|
AstSinD(FileLine* fl, AstNode* lhsp)
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_SinD(fl, lhsp) {}
|
2018-02-26 10:25:07 +01:00
|
|
|
ASTNODE_NODE_FUNCS(SinD)
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual void numberOperate(V3Number& out, const V3Number& lhs) override {
|
2021-03-27 02:23:18 +01:00
|
|
|
out.setDouble(std::sin(lhs.toDouble()));
|
2020-04-15 13:58:34 +02:00
|
|
|
}
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual string emitVerilog() override { return "%f$sin(%l)"; }
|
|
|
|
|
virtual string emitC() override { return "sin(%li)"; }
|
2011-09-29 03:35:16 +02:00
|
|
|
};
|
|
|
|
|
|
2020-11-19 03:32:16 +01:00
|
|
|
class AstCosD final : public AstNodeSystemUniop {
|
2014-09-12 03:28:53 +02:00
|
|
|
public:
|
2020-01-25 21:29:44 +01:00
|
|
|
AstCosD(FileLine* fl, AstNode* lhsp)
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_CosD(fl, lhsp) {}
|
2018-02-26 10:25:07 +01:00
|
|
|
ASTNODE_NODE_FUNCS(CosD)
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual void numberOperate(V3Number& out, const V3Number& lhs) override {
|
2021-03-27 02:23:18 +01:00
|
|
|
out.setDouble(std::cos(lhs.toDouble()));
|
2020-04-15 13:58:34 +02:00
|
|
|
}
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual string emitVerilog() override { return "%f$cos(%l)"; }
|
|
|
|
|
virtual string emitC() override { return "cos(%li)"; }
|
2018-02-26 10:25:07 +01:00
|
|
|
};
|
|
|
|
|
|
2020-11-19 03:32:16 +01:00
|
|
|
class AstTanD final : public AstNodeSystemUniop {
|
2018-02-26 10:25:07 +01:00
|
|
|
public:
|
2020-01-25 21:29:44 +01:00
|
|
|
AstTanD(FileLine* fl, AstNode* lhsp)
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_TanD(fl, lhsp) {}
|
2018-02-26 10:25:07 +01:00
|
|
|
ASTNODE_NODE_FUNCS(TanD)
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual void numberOperate(V3Number& out, const V3Number& lhs) override {
|
2021-03-27 02:23:18 +01:00
|
|
|
out.setDouble(std::tan(lhs.toDouble()));
|
2020-04-15 13:58:34 +02:00
|
|
|
}
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual string emitVerilog() override { return "%f$tan(%l)"; }
|
|
|
|
|
virtual string emitC() override { return "tan(%li)"; }
|
2018-02-26 10:25:07 +01:00
|
|
|
};
|
|
|
|
|
|
2020-11-19 03:32:16 +01:00
|
|
|
class AstAsinD final : public AstNodeSystemUniop {
|
2018-02-26 10:25:07 +01:00
|
|
|
public:
|
2020-01-25 21:29:44 +01:00
|
|
|
AstAsinD(FileLine* fl, AstNode* lhsp)
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_AsinD(fl, lhsp) {}
|
2018-02-26 10:25:07 +01:00
|
|
|
ASTNODE_NODE_FUNCS(AsinD)
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual void numberOperate(V3Number& out, const V3Number& lhs) override {
|
2021-03-27 02:23:18 +01:00
|
|
|
out.setDouble(std::asin(lhs.toDouble()));
|
2020-04-15 13:58:34 +02:00
|
|
|
}
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual string emitVerilog() override { return "%f$asin(%l)"; }
|
|
|
|
|
virtual string emitC() override { return "asin(%li)"; }
|
2018-02-26 10:25:07 +01:00
|
|
|
};
|
|
|
|
|
|
2020-11-19 03:32:16 +01:00
|
|
|
class AstAcosD final : public AstNodeSystemUniop {
|
2018-02-26 10:25:07 +01:00
|
|
|
public:
|
2020-01-25 21:29:44 +01:00
|
|
|
AstAcosD(FileLine* fl, AstNode* lhsp)
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_AcosD(fl, lhsp) {}
|
2018-02-26 10:25:07 +01:00
|
|
|
ASTNODE_NODE_FUNCS(AcosD)
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual void numberOperate(V3Number& out, const V3Number& lhs) override {
|
2021-03-27 02:23:18 +01:00
|
|
|
out.setDouble(std::acos(lhs.toDouble()));
|
2020-04-15 13:58:34 +02:00
|
|
|
}
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual string emitVerilog() override { return "%f$acos(%l)"; }
|
|
|
|
|
virtual string emitC() override { return "acos(%li)"; }
|
2018-02-26 10:25:07 +01:00
|
|
|
};
|
|
|
|
|
|
2020-11-19 03:32:16 +01:00
|
|
|
class AstAtanD final : public AstNodeSystemUniop {
|
2018-02-26 10:25:07 +01:00
|
|
|
public:
|
2020-01-25 21:29:44 +01:00
|
|
|
AstAtanD(FileLine* fl, AstNode* lhsp)
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_AtanD(fl, lhsp) {}
|
2018-02-26 10:25:07 +01:00
|
|
|
ASTNODE_NODE_FUNCS(AtanD)
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual void numberOperate(V3Number& out, const V3Number& lhs) override {
|
2021-03-27 02:23:18 +01:00
|
|
|
out.setDouble(std::atan(lhs.toDouble()));
|
2020-04-15 13:58:34 +02:00
|
|
|
}
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual string emitVerilog() override { return "%f$atan(%l)"; }
|
|
|
|
|
virtual string emitC() override { return "atan(%li)"; }
|
2018-02-26 10:25:07 +01:00
|
|
|
};
|
|
|
|
|
|
2020-11-19 03:32:16 +01:00
|
|
|
class AstSinhD final : public AstNodeSystemUniop {
|
2018-02-26 10:25:07 +01:00
|
|
|
public:
|
2020-01-25 21:29:44 +01:00
|
|
|
AstSinhD(FileLine* fl, AstNode* lhsp)
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_SinhD(fl, lhsp) {}
|
2018-02-26 10:25:07 +01:00
|
|
|
ASTNODE_NODE_FUNCS(SinhD)
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual void numberOperate(V3Number& out, const V3Number& lhs) override {
|
2021-03-27 02:23:18 +01:00
|
|
|
out.setDouble(std::sinh(lhs.toDouble()));
|
2020-04-15 13:58:34 +02:00
|
|
|
}
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual string emitVerilog() override { return "%f$sinh(%l)"; }
|
|
|
|
|
virtual string emitC() override { return "sinh(%li)"; }
|
2018-02-26 10:25:07 +01:00
|
|
|
};
|
|
|
|
|
|
2020-11-19 03:32:16 +01:00
|
|
|
class AstCoshD final : public AstNodeSystemUniop {
|
2018-02-26 10:25:07 +01:00
|
|
|
public:
|
2020-01-25 21:29:44 +01:00
|
|
|
AstCoshD(FileLine* fl, AstNode* lhsp)
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_CoshD(fl, lhsp) {}
|
2018-02-26 10:25:07 +01:00
|
|
|
ASTNODE_NODE_FUNCS(CoshD)
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual void numberOperate(V3Number& out, const V3Number& lhs) override {
|
2021-03-27 02:23:18 +01:00
|
|
|
out.setDouble(std::cosh(lhs.toDouble()));
|
2020-04-15 13:58:34 +02:00
|
|
|
}
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual string emitVerilog() override { return "%f$cosh(%l)"; }
|
|
|
|
|
virtual string emitC() override { return "cosh(%li)"; }
|
2018-02-26 10:25:07 +01:00
|
|
|
};
|
|
|
|
|
|
2020-11-19 03:32:16 +01:00
|
|
|
class AstTanhD final : public AstNodeSystemUniop {
|
2018-02-26 10:25:07 +01:00
|
|
|
public:
|
2020-01-25 21:29:44 +01:00
|
|
|
AstTanhD(FileLine* fl, AstNode* lhsp)
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_TanhD(fl, lhsp) {}
|
2018-02-26 10:25:07 +01:00
|
|
|
ASTNODE_NODE_FUNCS(TanhD)
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual void numberOperate(V3Number& out, const V3Number& lhs) override {
|
2021-03-27 02:23:18 +01:00
|
|
|
out.setDouble(std::tanh(lhs.toDouble()));
|
2020-04-15 13:58:34 +02:00
|
|
|
}
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual string emitVerilog() override { return "%f$tanh(%l)"; }
|
|
|
|
|
virtual string emitC() override { return "tanh(%li)"; }
|
2018-02-26 10:25:07 +01:00
|
|
|
};
|
|
|
|
|
|
2020-11-19 03:32:16 +01:00
|
|
|
class AstAsinhD final : public AstNodeSystemUniop {
|
2018-02-26 10:25:07 +01:00
|
|
|
public:
|
2020-01-25 21:29:44 +01:00
|
|
|
AstAsinhD(FileLine* fl, AstNode* lhsp)
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_AsinhD(fl, lhsp) {}
|
2018-02-26 10:25:07 +01:00
|
|
|
ASTNODE_NODE_FUNCS(AsinhD)
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual void numberOperate(V3Number& out, const V3Number& lhs) override {
|
2021-03-27 02:23:18 +01:00
|
|
|
out.setDouble(std::asinh(lhs.toDouble()));
|
2020-04-15 13:58:34 +02:00
|
|
|
}
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual string emitVerilog() override { return "%f$asinh(%l)"; }
|
|
|
|
|
virtual string emitC() override { return "asinh(%li)"; }
|
2018-02-26 10:25:07 +01:00
|
|
|
};
|
|
|
|
|
|
2020-11-19 03:32:16 +01:00
|
|
|
class AstAcoshD final : public AstNodeSystemUniop {
|
2018-02-26 10:25:07 +01:00
|
|
|
public:
|
2020-01-25 21:29:44 +01:00
|
|
|
AstAcoshD(FileLine* fl, AstNode* lhsp)
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_AcoshD(fl, lhsp) {}
|
2018-02-26 10:25:07 +01:00
|
|
|
ASTNODE_NODE_FUNCS(AcoshD)
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual void numberOperate(V3Number& out, const V3Number& lhs) override {
|
2021-03-27 02:23:18 +01:00
|
|
|
out.setDouble(std::acosh(lhs.toDouble()));
|
2020-04-15 13:58:34 +02:00
|
|
|
}
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual string emitVerilog() override { return "%f$acosh(%l)"; }
|
|
|
|
|
virtual string emitC() override { return "acosh(%li)"; }
|
2018-02-26 10:25:07 +01:00
|
|
|
};
|
|
|
|
|
|
2020-11-19 03:32:16 +01:00
|
|
|
class AstAtanhD final : public AstNodeSystemUniop {
|
2018-02-26 10:25:07 +01:00
|
|
|
public:
|
2020-01-25 21:29:44 +01:00
|
|
|
AstAtanhD(FileLine* fl, AstNode* lhsp)
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_AtanhD(fl, lhsp) {}
|
2018-02-26 10:25:07 +01:00
|
|
|
ASTNODE_NODE_FUNCS(AtanhD)
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual void numberOperate(V3Number& out, const V3Number& lhs) override {
|
2021-03-27 02:23:18 +01:00
|
|
|
out.setDouble(std::atanh(lhs.toDouble()));
|
2020-04-15 13:58:34 +02:00
|
|
|
}
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual string emitVerilog() override { return "%f$atanh(%l)"; }
|
|
|
|
|
virtual string emitC() override { return "atanh(%li)"; }
|
2011-09-29 03:35:16 +02:00
|
|
|
};
|
2020-11-19 03:32:16 +01:00
|
|
|
class AstToLowerN final : public AstNodeUniop {
|
2019-11-17 11:05:09 +01:00
|
|
|
// string.tolower()
|
|
|
|
|
public:
|
2020-01-25 21:29:44 +01:00
|
|
|
AstToLowerN(FileLine* fl, AstNode* lhsp)
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_ToLowerN(fl, lhsp) {
|
2020-04-15 13:58:34 +02:00
|
|
|
dtypeSetString();
|
|
|
|
|
}
|
2019-11-17 11:05:09 +01:00
|
|
|
ASTNODE_NODE_FUNCS(ToLowerN)
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual void numberOperate(V3Number& out, const V3Number& lhs) override {
|
|
|
|
|
out.opToLowerN(lhs);
|
|
|
|
|
}
|
|
|
|
|
virtual string emitVerilog() override { return "%l.tolower()"; }
|
|
|
|
|
virtual string emitC() override { return "VL_TOLOWER_NN(%li)"; }
|
|
|
|
|
virtual bool cleanOut() const override { return true; }
|
|
|
|
|
virtual bool cleanLhs() const override { return true; }
|
|
|
|
|
virtual bool sizeMattersLhs() const override { return false; }
|
2019-11-17 11:05:09 +01:00
|
|
|
};
|
2020-11-19 03:32:16 +01:00
|
|
|
class AstToUpperN final : public AstNodeUniop {
|
2019-11-17 11:05:09 +01:00
|
|
|
// string.toupper()
|
|
|
|
|
public:
|
2020-01-25 21:29:44 +01:00
|
|
|
AstToUpperN(FileLine* fl, AstNode* lhsp)
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_ToUpperN(fl, lhsp) {
|
2020-04-15 13:58:34 +02:00
|
|
|
dtypeSetString();
|
|
|
|
|
}
|
2019-11-17 11:05:09 +01:00
|
|
|
ASTNODE_NODE_FUNCS(ToUpperN)
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual void numberOperate(V3Number& out, const V3Number& lhs) override {
|
|
|
|
|
out.opToUpperN(lhs);
|
|
|
|
|
}
|
|
|
|
|
virtual string emitVerilog() override { return "%l.toupper()"; }
|
|
|
|
|
virtual string emitC() override { return "VL_TOUPPER_NN(%li)"; }
|
|
|
|
|
virtual bool cleanOut() const override { return true; }
|
|
|
|
|
virtual bool cleanLhs() const override { return true; }
|
|
|
|
|
virtual bool sizeMattersLhs() const override { return false; }
|
2019-11-17 11:05:09 +01:00
|
|
|
};
|
2020-11-19 03:32:16 +01:00
|
|
|
class AstTimeImport final : public AstNodeUniop {
|
2020-04-16 01:39:03 +02:00
|
|
|
// Take a constant that represents a time and needs conversion based on time units
|
|
|
|
|
VTimescale m_timeunit; // Parent module time unit
|
|
|
|
|
public:
|
|
|
|
|
AstTimeImport(FileLine* fl, AstNode* lhsp)
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_TimeImport(fl, lhsp) {}
|
2020-04-16 01:39:03 +02:00
|
|
|
ASTNODE_NODE_FUNCS(TimeImport)
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual void numberOperate(V3Number& out, const V3Number& lhs) override { V3ERROR_NA; }
|
|
|
|
|
virtual string emitVerilog() override { return "%l"; }
|
|
|
|
|
virtual string emitC() override { V3ERROR_NA_RETURN(""); }
|
|
|
|
|
virtual bool cleanOut() const override { return false; }
|
|
|
|
|
virtual bool cleanLhs() const override { return false; }
|
|
|
|
|
virtual bool sizeMattersLhs() const override { return false; }
|
|
|
|
|
virtual void dump(std::ostream& str = std::cout) const override;
|
2020-04-16 01:39:03 +02:00
|
|
|
void timeunit(const VTimescale& flag) { m_timeunit = flag; }
|
|
|
|
|
VTimescale timeunit() const { return m_timeunit; }
|
|
|
|
|
};
|
2011-09-29 03:35:16 +02:00
|
|
|
|
2020-11-19 03:32:16 +01:00
|
|
|
class AstAtoN final : public AstNodeUniop {
|
2019-12-10 01:17:52 +01:00
|
|
|
// string.atoi(), atobin(), atohex(), atooct(), atoireal()
|
|
|
|
|
public:
|
2020-04-15 13:58:34 +02:00
|
|
|
enum FmtType { ATOI = 10, ATOHEX = 16, ATOOCT = 8, ATOBIN = 2, ATOREAL = -1 };
|
|
|
|
|
|
2019-12-10 01:17:52 +01:00
|
|
|
private:
|
2021-11-26 23:55:36 +01:00
|
|
|
const FmtType m_fmt; // Operation type
|
2019-12-10 01:17:52 +01:00
|
|
|
public:
|
|
|
|
|
AstAtoN(FileLine* fl, AstNode* lhsp, FmtType fmt)
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_AtoN(fl, lhsp)
|
2020-08-16 17:40:42 +02:00
|
|
|
, m_fmt{fmt} {
|
2019-12-10 01:17:52 +01:00
|
|
|
fmt == ATOREAL ? dtypeSetDouble() : dtypeSetSigned32();
|
|
|
|
|
}
|
|
|
|
|
ASTNODE_NODE_FUNCS(AtoN)
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual void numberOperate(V3Number& out, const V3Number& lhs) override {
|
|
|
|
|
out.opAtoN(lhs, m_fmt);
|
|
|
|
|
}
|
|
|
|
|
virtual string name() const override {
|
2019-12-10 01:17:52 +01:00
|
|
|
switch (m_fmt) {
|
|
|
|
|
case ATOI: return "atoi";
|
|
|
|
|
case ATOHEX: return "atohex";
|
|
|
|
|
case ATOOCT: return "atooct";
|
|
|
|
|
case ATOBIN: return "atobin";
|
|
|
|
|
case ATOREAL: return "atoreal";
|
|
|
|
|
default: V3ERROR_NA;
|
|
|
|
|
}
|
|
|
|
|
}
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual string emitVerilog() override { return "%l." + name() + "()"; }
|
|
|
|
|
virtual string emitC() override {
|
2019-12-10 01:17:52 +01:00
|
|
|
switch (m_fmt) {
|
|
|
|
|
case ATOI: return "VL_ATOI_N(%li, 10)";
|
|
|
|
|
case ATOHEX: return "VL_ATOI_N(%li, 16)";
|
|
|
|
|
case ATOOCT: return "VL_ATOI_N(%li, 8)";
|
|
|
|
|
case ATOBIN: return "VL_ATOI_N(%li, 2)";
|
|
|
|
|
case ATOREAL: return "std::atof(%li.c_str())";
|
|
|
|
|
default: V3ERROR_NA;
|
|
|
|
|
}
|
|
|
|
|
}
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual bool cleanOut() const override { return true; }
|
|
|
|
|
virtual bool cleanLhs() const override { return true; }
|
|
|
|
|
virtual bool sizeMattersLhs() const override { return false; }
|
2019-12-10 01:17:52 +01:00
|
|
|
FmtType format() const { return m_fmt; }
|
|
|
|
|
};
|
|
|
|
|
|
2006-08-26 13:35:28 +02:00
|
|
|
//======================================================================
|
|
|
|
|
// Binary ops
|
|
|
|
|
|
2020-11-19 03:32:16 +01:00
|
|
|
class AstLogOr final : public AstNodeBiop {
|
2021-12-12 00:38:23 +01:00
|
|
|
// LOGOR with optional side effects
|
|
|
|
|
// Side effects currently used in some V3Width code
|
|
|
|
|
// TBD if this concept is generally adopted for side-effect tracking
|
|
|
|
|
// versus V3Const tracking it itself
|
|
|
|
|
bool m_sideEffect = false; // Has side effect, relies on short-circuiting
|
2014-09-12 03:28:53 +02:00
|
|
|
public:
|
2020-01-25 21:29:44 +01:00
|
|
|
AstLogOr(FileLine* fl, AstNode* lhsp, AstNode* rhsp)
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_LogOr(fl, lhsp, rhsp) {
|
2020-11-29 14:23:36 +01:00
|
|
|
dtypeSetBit();
|
2020-04-15 13:58:34 +02:00
|
|
|
}
|
2016-11-05 14:47:56 +01:00
|
|
|
ASTNODE_NODE_FUNCS(LogOr)
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual AstNode* cloneType(AstNode* lhsp, AstNode* rhsp) override {
|
2020-04-15 13:58:34 +02:00
|
|
|
return new AstLogOr(this->fileline(), lhsp, rhsp);
|
|
|
|
|
}
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) override {
|
2020-04-15 13:58:34 +02:00
|
|
|
out.opLogOr(lhs, rhs);
|
|
|
|
|
}
|
2021-12-12 00:38:23 +01:00
|
|
|
virtual bool same(const AstNode* samep) const override {
|
|
|
|
|
const AstLogOr* const sp = static_cast<const AstLogOr*>(samep);
|
|
|
|
|
return m_sideEffect == sp->m_sideEffect;
|
|
|
|
|
}
|
|
|
|
|
virtual void dump(std::ostream& str = std::cout) const override;
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual string emitVerilog() override { return "%k(%l %f|| %r)"; }
|
|
|
|
|
virtual string emitC() override { return "VL_LOGOR_%nq%lq%rq(%nw,%lw,%rw, %P, %li, %ri)"; }
|
|
|
|
|
virtual string emitSimpleOperator() override { return "||"; }
|
|
|
|
|
virtual bool cleanOut() const override { return true; }
|
|
|
|
|
virtual bool cleanLhs() const override { return true; }
|
|
|
|
|
virtual bool cleanRhs() const override { return true; }
|
|
|
|
|
virtual bool sizeMattersLhs() const override { return false; }
|
|
|
|
|
virtual bool sizeMattersRhs() const override { return false; }
|
2021-07-25 14:32:36 +02:00
|
|
|
virtual int instrCount() const override { return widthInstrs() + INSTR_COUNT_BRANCH; }
|
2021-12-12 00:38:23 +01:00
|
|
|
virtual bool isPure() const override { return !m_sideEffect; }
|
|
|
|
|
void sideEffect(bool flag) { m_sideEffect = flag; }
|
|
|
|
|
bool sideEffect() const { return m_sideEffect; }
|
2006-08-26 13:35:28 +02:00
|
|
|
};
|
2020-11-19 03:32:16 +01:00
|
|
|
class AstLogAnd final : public AstNodeBiop {
|
2014-09-12 03:28:53 +02:00
|
|
|
public:
|
2020-01-25 21:29:44 +01:00
|
|
|
AstLogAnd(FileLine* fl, AstNode* lhsp, AstNode* rhsp)
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_LogAnd(fl, lhsp, rhsp) {
|
2020-11-29 14:23:36 +01:00
|
|
|
dtypeSetBit();
|
2020-04-15 13:58:34 +02:00
|
|
|
}
|
2016-11-05 14:47:56 +01:00
|
|
|
ASTNODE_NODE_FUNCS(LogAnd)
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual AstNode* cloneType(AstNode* lhsp, AstNode* rhsp) override {
|
2020-04-15 13:58:34 +02:00
|
|
|
return new AstLogAnd(this->fileline(), lhsp, rhsp);
|
|
|
|
|
}
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) override {
|
2020-04-15 13:58:34 +02:00
|
|
|
out.opLogAnd(lhs, rhs);
|
|
|
|
|
}
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual string emitVerilog() override { return "%k(%l %f&& %r)"; }
|
|
|
|
|
virtual string emitC() override { return "VL_LOGAND_%nq%lq%rq(%nw,%lw,%rw, %P, %li, %ri)"; }
|
|
|
|
|
virtual string emitSimpleOperator() override { return "&&"; }
|
|
|
|
|
virtual bool cleanOut() const override { return true; }
|
|
|
|
|
virtual bool cleanLhs() const override { return true; }
|
|
|
|
|
virtual bool cleanRhs() const override { return true; }
|
|
|
|
|
virtual bool sizeMattersLhs() const override { return false; }
|
|
|
|
|
virtual bool sizeMattersRhs() const override { return false; }
|
2021-07-25 14:32:36 +02:00
|
|
|
virtual int instrCount() const override { return widthInstrs() + INSTR_COUNT_BRANCH; }
|
2006-08-26 13:35:28 +02:00
|
|
|
};
|
2020-11-19 03:32:16 +01:00
|
|
|
class AstLogEq final : public AstNodeBiCom {
|
2014-09-12 03:28:53 +02:00
|
|
|
public:
|
2020-01-25 21:29:44 +01:00
|
|
|
AstLogEq(FileLine* fl, AstNode* lhsp, AstNode* rhsp)
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_LogEq(fl, lhsp, rhsp) {
|
2020-11-29 14:23:36 +01:00
|
|
|
dtypeSetBit();
|
2020-04-15 13:58:34 +02:00
|
|
|
}
|
2019-06-02 01:40:06 +02:00
|
|
|
ASTNODE_NODE_FUNCS(LogEq)
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual AstNode* cloneType(AstNode* lhsp, AstNode* rhsp) override {
|
2020-04-15 13:58:34 +02:00
|
|
|
return new AstLogEq(this->fileline(), lhsp, rhsp);
|
|
|
|
|
}
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) override {
|
2020-04-15 13:58:34 +02:00
|
|
|
out.opLogEq(lhs, rhs);
|
|
|
|
|
}
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual string emitVerilog() override { return "%k(%l %f<-> %r)"; }
|
|
|
|
|
virtual string emitC() override { return "VL_LOGEQ_%nq%lq%rq(%nw,%lw,%rw, %P, %li, %ri)"; }
|
|
|
|
|
virtual string emitSimpleOperator() override { return "<->"; }
|
|
|
|
|
virtual bool cleanOut() const override { return true; }
|
|
|
|
|
virtual bool cleanLhs() const override { return true; }
|
|
|
|
|
virtual bool cleanRhs() const override { return true; }
|
|
|
|
|
virtual bool sizeMattersLhs() const override { return false; }
|
|
|
|
|
virtual bool sizeMattersRhs() const override { return false; }
|
2021-07-25 14:32:36 +02:00
|
|
|
virtual int instrCount() const override { return widthInstrs() + INSTR_COUNT_BRANCH; }
|
2006-08-26 13:35:28 +02:00
|
|
|
};
|
2020-11-19 03:32:16 +01:00
|
|
|
class AstLogIf final : public AstNodeBiop {
|
2014-09-12 03:28:53 +02:00
|
|
|
public:
|
2020-01-25 21:29:44 +01:00
|
|
|
AstLogIf(FileLine* fl, AstNode* lhsp, AstNode* rhsp)
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_LogIf(fl, lhsp, rhsp) {
|
2020-11-29 14:23:36 +01:00
|
|
|
dtypeSetBit();
|
2020-04-15 13:58:34 +02:00
|
|
|
}
|
2019-06-02 01:40:06 +02:00
|
|
|
ASTNODE_NODE_FUNCS(LogIf)
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual AstNode* cloneType(AstNode* lhsp, AstNode* rhsp) override {
|
2020-04-15 13:58:34 +02:00
|
|
|
return new AstLogIf(this->fileline(), lhsp, rhsp);
|
|
|
|
|
}
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) override {
|
2020-04-15 13:58:34 +02:00
|
|
|
out.opLogIf(lhs, rhs);
|
|
|
|
|
}
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual string emitVerilog() override { return "%k(%l %f-> %r)"; }
|
|
|
|
|
virtual string emitC() override { return "VL_LOGIF_%nq%lq%rq(%nw,%lw,%rw, %P, %li, %ri)"; }
|
|
|
|
|
virtual string emitSimpleOperator() override { return "->"; }
|
|
|
|
|
virtual bool cleanOut() const override { return true; }
|
|
|
|
|
virtual bool cleanLhs() const override { return true; }
|
|
|
|
|
virtual bool cleanRhs() const override { return true; }
|
|
|
|
|
virtual bool sizeMattersLhs() const override { return false; }
|
|
|
|
|
virtual bool sizeMattersRhs() const override { return false; }
|
2021-07-25 14:32:36 +02:00
|
|
|
virtual int instrCount() const override { return widthInstrs() + INSTR_COUNT_BRANCH; }
|
2006-08-26 13:35:28 +02:00
|
|
|
};
|
2020-11-19 03:32:16 +01:00
|
|
|
class AstOr final : public AstNodeBiComAsv {
|
2014-09-12 03:28:53 +02:00
|
|
|
public:
|
2020-01-25 21:29:44 +01:00
|
|
|
AstOr(FileLine* fl, AstNode* lhsp, AstNode* rhsp)
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_Or(fl, lhsp, rhsp) {
|
2020-04-15 13:58:34 +02:00
|
|
|
dtypeFrom(lhsp);
|
|
|
|
|
}
|
2016-11-05 14:47:56 +01:00
|
|
|
ASTNODE_NODE_FUNCS(Or)
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual AstNode* cloneType(AstNode* lhsp, AstNode* rhsp) override {
|
2020-04-15 13:58:34 +02:00
|
|
|
return new AstOr(this->fileline(), lhsp, rhsp);
|
|
|
|
|
}
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) override {
|
2020-04-15 13:58:34 +02:00
|
|
|
out.opOr(lhs, rhs);
|
|
|
|
|
}
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual string emitVerilog() override { return "%k(%l %f| %r)"; }
|
|
|
|
|
virtual string emitC() override { return "VL_OR_%lq(%lW, %P, %li, %ri)"; }
|
|
|
|
|
virtual string emitSimpleOperator() override { return "|"; }
|
|
|
|
|
virtual bool cleanOut() const override { V3ERROR_NA_RETURN(false); }
|
|
|
|
|
virtual bool cleanLhs() const override { return false; }
|
|
|
|
|
virtual bool cleanRhs() const override { return false; }
|
|
|
|
|
virtual bool sizeMattersLhs() const override { return false; }
|
|
|
|
|
virtual bool sizeMattersRhs() const override { return false; }
|
2006-08-26 13:35:28 +02:00
|
|
|
};
|
2020-11-19 03:32:16 +01:00
|
|
|
class AstAnd final : public AstNodeBiComAsv {
|
2014-09-12 03:28:53 +02:00
|
|
|
public:
|
2020-01-25 21:29:44 +01:00
|
|
|
AstAnd(FileLine* fl, AstNode* lhsp, AstNode* rhsp)
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_And(fl, lhsp, rhsp) {
|
2020-04-15 13:58:34 +02:00
|
|
|
dtypeFrom(lhsp);
|
|
|
|
|
}
|
2016-11-05 14:47:56 +01:00
|
|
|
ASTNODE_NODE_FUNCS(And)
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual AstNode* cloneType(AstNode* lhsp, AstNode* rhsp) override {
|
2020-04-15 13:58:34 +02:00
|
|
|
return new AstAnd(this->fileline(), lhsp, rhsp);
|
|
|
|
|
}
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) override {
|
2020-04-15 13:58:34 +02:00
|
|
|
out.opAnd(lhs, rhs);
|
|
|
|
|
}
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual string emitVerilog() override { return "%k(%l %f& %r)"; }
|
|
|
|
|
virtual string emitC() override { return "VL_AND_%lq(%lW, %P, %li, %ri)"; }
|
|
|
|
|
virtual string emitSimpleOperator() override { return "&"; }
|
|
|
|
|
virtual bool cleanOut() const override { V3ERROR_NA_RETURN(false); }
|
|
|
|
|
virtual bool cleanLhs() const override { return false; }
|
|
|
|
|
virtual bool cleanRhs() const override { return false; }
|
|
|
|
|
virtual bool sizeMattersLhs() const override { return false; }
|
|
|
|
|
virtual bool sizeMattersRhs() const override { return false; }
|
2006-08-26 13:35:28 +02:00
|
|
|
};
|
2020-11-19 03:32:16 +01:00
|
|
|
class AstXor final : public AstNodeBiComAsv {
|
2014-09-12 03:28:53 +02:00
|
|
|
public:
|
2020-01-25 21:29:44 +01:00
|
|
|
AstXor(FileLine* fl, AstNode* lhsp, AstNode* rhsp)
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_Xor(fl, lhsp, rhsp) {
|
2020-04-15 13:58:34 +02:00
|
|
|
dtypeFrom(lhsp);
|
|
|
|
|
}
|
2016-11-05 14:47:56 +01:00
|
|
|
ASTNODE_NODE_FUNCS(Xor)
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual AstNode* cloneType(AstNode* lhsp, AstNode* rhsp) override {
|
2020-04-15 13:58:34 +02:00
|
|
|
return new AstXor(this->fileline(), lhsp, rhsp);
|
|
|
|
|
}
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) override {
|
2020-04-15 13:58:34 +02:00
|
|
|
out.opXor(lhs, rhs);
|
|
|
|
|
}
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual string emitVerilog() override { return "%k(%l %f^ %r)"; }
|
|
|
|
|
virtual string emitC() override { return "VL_XOR_%lq(%lW, %P, %li, %ri)"; }
|
|
|
|
|
virtual string emitSimpleOperator() override { return "^"; }
|
|
|
|
|
virtual bool cleanOut() const override { return false; } // Lclean && Rclean
|
|
|
|
|
virtual bool cleanLhs() const override { return false; }
|
|
|
|
|
virtual bool cleanRhs() const override { return false; }
|
|
|
|
|
virtual bool sizeMattersLhs() const override { return false; }
|
|
|
|
|
virtual bool sizeMattersRhs() const override { return false; }
|
2006-08-26 13:35:28 +02:00
|
|
|
};
|
2020-11-19 03:32:16 +01:00
|
|
|
class AstEq final : public AstNodeBiCom {
|
2014-09-12 03:28:53 +02:00
|
|
|
public:
|
2020-01-25 21:29:44 +01:00
|
|
|
AstEq(FileLine* fl, AstNode* lhsp, AstNode* rhsp)
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_Eq(fl, lhsp, rhsp) {
|
2020-11-29 14:23:36 +01:00
|
|
|
dtypeSetBit();
|
2020-04-15 13:58:34 +02:00
|
|
|
}
|
2016-11-05 14:47:56 +01:00
|
|
|
ASTNODE_NODE_FUNCS(Eq)
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual AstNode* cloneType(AstNode* lhsp, AstNode* rhsp) override {
|
2020-04-15 13:58:34 +02:00
|
|
|
return new AstEq(this->fileline(), lhsp, rhsp);
|
|
|
|
|
}
|
|
|
|
|
static AstNodeBiop* newTyped(FileLine* fl, AstNode* lhsp,
|
|
|
|
|
AstNode* rhsp); // Return AstEq/AstEqD
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) override {
|
2020-04-15 13:58:34 +02:00
|
|
|
out.opEq(lhs, rhs);
|
|
|
|
|
}
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual string emitVerilog() override { return "%k(%l %f== %r)"; }
|
|
|
|
|
virtual string emitC() override { return "VL_EQ_%lq(%lW, %P, %li, %ri)"; }
|
|
|
|
|
virtual string emitSimpleOperator() override { return "=="; }
|
|
|
|
|
virtual bool cleanOut() const override { return true; }
|
|
|
|
|
virtual bool cleanLhs() const override { return true; }
|
|
|
|
|
virtual bool cleanRhs() const override { return true; }
|
|
|
|
|
virtual bool sizeMattersLhs() const override { return false; }
|
|
|
|
|
virtual bool sizeMattersRhs() const override { return false; }
|
2006-08-26 13:35:28 +02:00
|
|
|
};
|
2020-11-19 03:32:16 +01:00
|
|
|
class AstEqD final : public AstNodeBiCom {
|
2014-09-12 03:28:53 +02:00
|
|
|
public:
|
2020-01-25 21:29:44 +01:00
|
|
|
AstEqD(FileLine* fl, AstNode* lhsp, AstNode* rhsp)
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_EqD(fl, lhsp, rhsp) {
|
2020-11-29 14:23:36 +01:00
|
|
|
dtypeSetBit();
|
2020-04-15 13:58:34 +02:00
|
|
|
}
|
2016-11-05 14:47:56 +01:00
|
|
|
ASTNODE_NODE_FUNCS(EqD)
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual AstNode* cloneType(AstNode* lhsp, AstNode* rhsp) override {
|
2020-04-15 13:58:34 +02:00
|
|
|
return new AstEqD(this->fileline(), lhsp, rhsp);
|
|
|
|
|
}
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) override {
|
2020-04-15 13:58:34 +02:00
|
|
|
out.opEqD(lhs, rhs);
|
|
|
|
|
}
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual string emitVerilog() override { return "%k(%l %f== %r)"; }
|
|
|
|
|
virtual string emitC() override { V3ERROR_NA_RETURN(""); }
|
|
|
|
|
virtual string emitSimpleOperator() override { return "=="; }
|
|
|
|
|
virtual bool cleanOut() const override { return true; }
|
|
|
|
|
virtual bool cleanLhs() const override { return false; }
|
|
|
|
|
virtual bool cleanRhs() const override { return false; }
|
|
|
|
|
virtual bool sizeMattersLhs() const override { return false; }
|
|
|
|
|
virtual bool sizeMattersRhs() const override { return false; }
|
2021-07-25 14:32:36 +02:00
|
|
|
virtual int instrCount() const override { return INSTR_COUNT_DBL; }
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual bool doubleFlavor() const override { return true; }
|
2011-07-24 21:01:51 +02:00
|
|
|
};
|
2020-11-19 03:32:16 +01:00
|
|
|
class AstEqN final : public AstNodeBiCom {
|
2014-11-28 21:01:50 +01:00
|
|
|
public:
|
2020-01-25 21:29:44 +01:00
|
|
|
AstEqN(FileLine* fl, AstNode* lhsp, AstNode* rhsp)
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_EqN(fl, lhsp, rhsp) {
|
2020-11-29 14:23:36 +01:00
|
|
|
dtypeSetBit();
|
2020-04-15 13:58:34 +02:00
|
|
|
}
|
2016-11-05 14:47:56 +01:00
|
|
|
ASTNODE_NODE_FUNCS(EqN)
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual AstNode* cloneType(AstNode* lhsp, AstNode* rhsp) override {
|
2020-04-15 13:58:34 +02:00
|
|
|
return new AstEqN(this->fileline(), lhsp, rhsp);
|
|
|
|
|
}
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) override {
|
2020-04-15 13:58:34 +02:00
|
|
|
out.opEqN(lhs, rhs);
|
|
|
|
|
}
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual string emitVerilog() override { return "%k(%l %f== %r)"; }
|
|
|
|
|
virtual string emitC() override { V3ERROR_NA_RETURN(""); }
|
|
|
|
|
virtual string emitSimpleOperator() override { return "=="; }
|
|
|
|
|
virtual bool cleanOut() const override { return true; }
|
|
|
|
|
virtual bool cleanLhs() const override { return false; }
|
|
|
|
|
virtual bool cleanRhs() const override { return false; }
|
|
|
|
|
virtual bool sizeMattersLhs() const override { return false; }
|
|
|
|
|
virtual bool sizeMattersRhs() const override { return false; }
|
2021-07-25 14:32:36 +02:00
|
|
|
virtual int instrCount() const override { return INSTR_COUNT_STR; }
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual bool stringFlavor() const override { return true; }
|
2014-11-28 21:01:50 +01:00
|
|
|
};
|
2020-11-19 03:32:16 +01:00
|
|
|
class AstNeq final : public AstNodeBiCom {
|
2014-09-12 03:28:53 +02:00
|
|
|
public:
|
2020-01-25 21:29:44 +01:00
|
|
|
AstNeq(FileLine* fl, AstNode* lhsp, AstNode* rhsp)
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_Neq(fl, lhsp, rhsp) {
|
2020-11-29 14:23:36 +01:00
|
|
|
dtypeSetBit();
|
2020-04-15 13:58:34 +02:00
|
|
|
}
|
2016-11-05 14:47:56 +01:00
|
|
|
ASTNODE_NODE_FUNCS(Neq)
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual AstNode* cloneType(AstNode* lhsp, AstNode* rhsp) override {
|
2020-04-15 13:58:34 +02:00
|
|
|
return new AstNeq(this->fileline(), lhsp, rhsp);
|
|
|
|
|
}
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) override {
|
2020-04-15 13:58:34 +02:00
|
|
|
out.opNeq(lhs, rhs);
|
|
|
|
|
}
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual string emitVerilog() override { return "%k(%l %f!= %r)"; }
|
|
|
|
|
virtual string emitC() override { return "VL_NEQ_%lq(%lW, %P, %li, %ri)"; }
|
|
|
|
|
virtual string emitSimpleOperator() override { return "!="; }
|
|
|
|
|
virtual bool cleanOut() const override { return true; }
|
|
|
|
|
virtual bool cleanLhs() const override { return true; }
|
|
|
|
|
virtual bool cleanRhs() const override { return true; }
|
|
|
|
|
virtual bool sizeMattersLhs() const override { return false; }
|
|
|
|
|
virtual bool sizeMattersRhs() const override { return false; }
|
2006-08-26 13:35:28 +02:00
|
|
|
};
|
2020-11-19 03:32:16 +01:00
|
|
|
class AstNeqD final : public AstNodeBiCom {
|
2014-09-12 03:28:53 +02:00
|
|
|
public:
|
2020-01-25 21:29:44 +01:00
|
|
|
AstNeqD(FileLine* fl, AstNode* lhsp, AstNode* rhsp)
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_NeqD(fl, lhsp, rhsp) {
|
2020-11-29 14:23:36 +01:00
|
|
|
dtypeSetBit();
|
2020-04-15 13:58:34 +02:00
|
|
|
}
|
2016-11-05 14:47:56 +01:00
|
|
|
ASTNODE_NODE_FUNCS(NeqD)
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual AstNode* cloneType(AstNode* lhsp, AstNode* rhsp) override {
|
2020-04-15 13:58:34 +02:00
|
|
|
return new AstNeqD(this->fileline(), lhsp, rhsp);
|
|
|
|
|
}
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) override {
|
2020-04-15 13:58:34 +02:00
|
|
|
out.opNeqD(lhs, rhs);
|
|
|
|
|
}
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual string emitVerilog() override { return "%k(%l %f!= %r)"; }
|
|
|
|
|
virtual string emitC() override { V3ERROR_NA_RETURN(""); }
|
|
|
|
|
virtual string emitSimpleOperator() override { return "!="; }
|
|
|
|
|
virtual bool cleanOut() const override { return true; }
|
|
|
|
|
virtual bool cleanLhs() const override { return false; }
|
|
|
|
|
virtual bool cleanRhs() const override { return false; }
|
|
|
|
|
virtual bool sizeMattersLhs() const override { return false; }
|
|
|
|
|
virtual bool sizeMattersRhs() const override { return false; }
|
2021-07-25 14:32:36 +02:00
|
|
|
virtual int instrCount() const override { return INSTR_COUNT_DBL; }
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual bool doubleFlavor() const override { return true; }
|
2011-07-24 21:01:51 +02:00
|
|
|
};
|
2020-11-19 03:32:16 +01:00
|
|
|
class AstNeqN final : public AstNodeBiCom {
|
2014-11-28 21:01:50 +01:00
|
|
|
public:
|
2020-01-25 21:29:44 +01:00
|
|
|
AstNeqN(FileLine* fl, AstNode* lhsp, AstNode* rhsp)
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_NeqN(fl, lhsp, rhsp) {
|
2020-11-29 14:23:36 +01:00
|
|
|
dtypeSetBit();
|
2020-04-15 13:58:34 +02:00
|
|
|
}
|
2016-11-05 14:47:56 +01:00
|
|
|
ASTNODE_NODE_FUNCS(NeqN)
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual AstNode* cloneType(AstNode* lhsp, AstNode* rhsp) override {
|
2020-04-15 13:58:34 +02:00
|
|
|
return new AstNeqN(this->fileline(), lhsp, rhsp);
|
|
|
|
|
}
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) override {
|
2020-04-15 13:58:34 +02:00
|
|
|
out.opNeqN(lhs, rhs);
|
|
|
|
|
}
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual string emitVerilog() override { return "%k(%l %f!= %r)"; }
|
|
|
|
|
virtual string emitC() override { V3ERROR_NA_RETURN(""); }
|
|
|
|
|
virtual string emitSimpleOperator() override { return "!="; }
|
|
|
|
|
virtual bool cleanOut() const override { return true; }
|
|
|
|
|
virtual bool cleanLhs() const override { return false; }
|
|
|
|
|
virtual bool cleanRhs() const override { return false; }
|
|
|
|
|
virtual bool sizeMattersLhs() const override { return false; }
|
|
|
|
|
virtual bool sizeMattersRhs() const override { return false; }
|
2021-07-25 14:32:36 +02:00
|
|
|
virtual int instrCount() const override { return INSTR_COUNT_STR; }
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual bool stringFlavor() const override { return true; }
|
2014-11-28 21:01:50 +01:00
|
|
|
};
|
2020-11-19 03:32:16 +01:00
|
|
|
class AstLt final : public AstNodeBiop {
|
2014-09-12 03:28:53 +02:00
|
|
|
public:
|
2020-01-25 21:29:44 +01:00
|
|
|
AstLt(FileLine* fl, AstNode* lhsp, AstNode* rhsp)
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_Lt(fl, lhsp, rhsp) {
|
2020-11-29 14:23:36 +01:00
|
|
|
dtypeSetBit();
|
2020-04-15 13:58:34 +02:00
|
|
|
}
|
2016-11-05 14:47:56 +01:00
|
|
|
ASTNODE_NODE_FUNCS(Lt)
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual AstNode* cloneType(AstNode* lhsp, AstNode* rhsp) override {
|
2020-04-15 13:58:34 +02:00
|
|
|
return new AstLt(this->fileline(), lhsp, rhsp);
|
|
|
|
|
}
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) override {
|
2020-04-15 13:58:34 +02:00
|
|
|
out.opLt(lhs, rhs);
|
|
|
|
|
}
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual string emitVerilog() override { return "%k(%l %f< %r)"; }
|
|
|
|
|
virtual string emitC() override { return "VL_LT_%lq(%lW, %P, %li, %ri)"; }
|
|
|
|
|
virtual string emitSimpleOperator() override { return "<"; }
|
|
|
|
|
virtual bool cleanOut() const override { return true; }
|
|
|
|
|
virtual bool cleanLhs() const override { return true; }
|
|
|
|
|
virtual bool cleanRhs() const override { return true; }
|
|
|
|
|
virtual bool sizeMattersLhs() const override { return false; }
|
|
|
|
|
virtual bool sizeMattersRhs() const override { return false; }
|
2006-08-26 13:35:28 +02:00
|
|
|
};
|
2020-11-19 03:32:16 +01:00
|
|
|
class AstLtD final : public AstNodeBiop {
|
2014-09-12 03:28:53 +02:00
|
|
|
public:
|
2020-01-25 21:29:44 +01:00
|
|
|
AstLtD(FileLine* fl, AstNode* lhsp, AstNode* rhsp)
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_LtD(fl, lhsp, rhsp) {
|
2020-11-29 14:23:36 +01:00
|
|
|
dtypeSetBit();
|
2020-04-15 13:58:34 +02:00
|
|
|
}
|
2016-11-05 14:47:56 +01:00
|
|
|
ASTNODE_NODE_FUNCS(LtD)
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual AstNode* cloneType(AstNode* lhsp, AstNode* rhsp) override {
|
2020-04-15 13:58:34 +02:00
|
|
|
return new AstLtD(this->fileline(), lhsp, rhsp);
|
|
|
|
|
}
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) override {
|
2020-04-15 13:58:34 +02:00
|
|
|
out.opLtD(lhs, rhs);
|
|
|
|
|
}
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual string emitVerilog() override { return "%k(%l %f< %r)"; }
|
|
|
|
|
virtual string emitC() override { V3ERROR_NA_RETURN(""); }
|
|
|
|
|
virtual string emitSimpleOperator() override { return "<"; }
|
|
|
|
|
virtual bool cleanOut() const override { return true; }
|
|
|
|
|
virtual bool cleanLhs() const override { return false; }
|
|
|
|
|
virtual bool cleanRhs() const override { return false; }
|
|
|
|
|
virtual bool sizeMattersLhs() const override { return false; }
|
|
|
|
|
virtual bool sizeMattersRhs() const override { return false; }
|
2021-07-25 14:32:36 +02:00
|
|
|
virtual int instrCount() const override { return INSTR_COUNT_DBL; }
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual bool doubleFlavor() const override { return true; }
|
2011-07-24 21:01:51 +02:00
|
|
|
};
|
2020-11-19 03:32:16 +01:00
|
|
|
class AstLtS final : public AstNodeBiop {
|
2014-09-12 03:28:53 +02:00
|
|
|
public:
|
2020-01-25 21:29:44 +01:00
|
|
|
AstLtS(FileLine* fl, AstNode* lhsp, AstNode* rhsp)
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_LtS(fl, lhsp, rhsp) {
|
2020-11-29 14:23:36 +01:00
|
|
|
dtypeSetBit();
|
2020-04-15 13:58:34 +02:00
|
|
|
}
|
2016-11-05 14:47:56 +01:00
|
|
|
ASTNODE_NODE_FUNCS(LtS)
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual AstNode* cloneType(AstNode* lhsp, AstNode* rhsp) override {
|
2020-04-15 13:58:34 +02:00
|
|
|
return new AstLtS(this->fileline(), lhsp, rhsp);
|
|
|
|
|
}
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) override {
|
2020-04-15 13:58:34 +02:00
|
|
|
out.opLtS(lhs, rhs);
|
|
|
|
|
}
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual string emitVerilog() override { return "%k(%l %f< %r)"; }
|
2021-11-28 19:44:16 +01:00
|
|
|
virtual string emitC() override { return "VL_LTS_%nq%lq%rq(%lw, %P, %li, %ri)"; }
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual string emitSimpleOperator() override { return ""; }
|
|
|
|
|
virtual bool cleanOut() const override { return true; }
|
|
|
|
|
virtual bool cleanLhs() const override { return true; }
|
|
|
|
|
virtual bool cleanRhs() const override { return true; }
|
|
|
|
|
virtual bool sizeMattersLhs() const override { return false; }
|
|
|
|
|
virtual bool sizeMattersRhs() const override { return false; }
|
|
|
|
|
virtual bool signedFlavor() const override { return true; }
|
2006-08-26 13:35:28 +02:00
|
|
|
};
|
2020-11-19 03:32:16 +01:00
|
|
|
class AstLtN final : public AstNodeBiop {
|
2014-11-28 21:01:50 +01:00
|
|
|
public:
|
2020-01-25 21:29:44 +01:00
|
|
|
AstLtN(FileLine* fl, AstNode* lhsp, AstNode* rhsp)
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_LtN(fl, lhsp, rhsp) {
|
2020-11-29 14:23:36 +01:00
|
|
|
dtypeSetBit();
|
2020-04-15 13:58:34 +02:00
|
|
|
}
|
2016-11-05 14:47:56 +01:00
|
|
|
ASTNODE_NODE_FUNCS(LtN)
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual AstNode* cloneType(AstNode* lhsp, AstNode* rhsp) override {
|
2020-04-15 13:58:34 +02:00
|
|
|
return new AstLtN(this->fileline(), lhsp, rhsp);
|
|
|
|
|
}
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) override {
|
2020-04-15 13:58:34 +02:00
|
|
|
out.opLtN(lhs, rhs);
|
|
|
|
|
}
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual string emitVerilog() override { return "%k(%l %f< %r)"; }
|
|
|
|
|
virtual string emitC() override { V3ERROR_NA_RETURN(""); }
|
|
|
|
|
virtual string emitSimpleOperator() override { return "<"; }
|
|
|
|
|
virtual bool cleanOut() const override { return true; }
|
|
|
|
|
virtual bool cleanLhs() const override { return false; }
|
|
|
|
|
virtual bool cleanRhs() const override { return false; }
|
|
|
|
|
virtual bool sizeMattersLhs() const override { return false; }
|
|
|
|
|
virtual bool sizeMattersRhs() const override { return false; }
|
2021-07-25 14:32:36 +02:00
|
|
|
virtual int instrCount() const override { return INSTR_COUNT_STR; }
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual bool stringFlavor() const override { return true; }
|
2014-11-28 21:01:50 +01:00
|
|
|
};
|
2020-11-19 03:32:16 +01:00
|
|
|
class AstGt final : public AstNodeBiop {
|
2014-09-12 03:28:53 +02:00
|
|
|
public:
|
2020-01-25 21:29:44 +01:00
|
|
|
AstGt(FileLine* fl, AstNode* lhsp, AstNode* rhsp)
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_Gt(fl, lhsp, rhsp) {
|
2020-11-29 14:23:36 +01:00
|
|
|
dtypeSetBit();
|
2020-04-15 13:58:34 +02:00
|
|
|
}
|
2016-11-05 14:47:56 +01:00
|
|
|
ASTNODE_NODE_FUNCS(Gt)
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual AstNode* cloneType(AstNode* lhsp, AstNode* rhsp) override {
|
2020-04-15 13:58:34 +02:00
|
|
|
return new AstGt(this->fileline(), lhsp, rhsp);
|
|
|
|
|
}
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) override {
|
2020-04-15 13:58:34 +02:00
|
|
|
out.opGt(lhs, rhs);
|
|
|
|
|
}
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual string emitVerilog() override { return "%k(%l %f> %r)"; }
|
|
|
|
|
virtual string emitC() override { return "VL_GT_%lq(%lW, %P, %li, %ri)"; }
|
|
|
|
|
virtual string emitSimpleOperator() override { return ">"; }
|
|
|
|
|
virtual bool cleanOut() const override { return true; }
|
|
|
|
|
virtual bool cleanLhs() const override { return true; }
|
|
|
|
|
virtual bool cleanRhs() const override { return true; }
|
|
|
|
|
virtual bool sizeMattersLhs() const override { return false; }
|
|
|
|
|
virtual bool sizeMattersRhs() const override { return false; }
|
2006-08-26 13:35:28 +02:00
|
|
|
};
|
2020-11-19 03:32:16 +01:00
|
|
|
class AstGtD final : public AstNodeBiop {
|
2014-09-12 03:28:53 +02:00
|
|
|
public:
|
2020-01-25 21:29:44 +01:00
|
|
|
AstGtD(FileLine* fl, AstNode* lhsp, AstNode* rhsp)
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_GtD(fl, lhsp, rhsp) {
|
2020-11-29 14:23:36 +01:00
|
|
|
dtypeSetBit();
|
2020-04-15 13:58:34 +02:00
|
|
|
}
|
2016-11-05 14:47:56 +01:00
|
|
|
ASTNODE_NODE_FUNCS(GtD)
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual AstNode* cloneType(AstNode* lhsp, AstNode* rhsp) override {
|
2020-04-15 13:58:34 +02:00
|
|
|
return new AstGtD(this->fileline(), lhsp, rhsp);
|
|
|
|
|
}
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) override {
|
2020-04-15 13:58:34 +02:00
|
|
|
out.opGtD(lhs, rhs);
|
|
|
|
|
}
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual string emitVerilog() override { return "%k(%l %f> %r)"; }
|
|
|
|
|
virtual string emitC() override { V3ERROR_NA_RETURN(""); }
|
|
|
|
|
virtual string emitSimpleOperator() override { return ">"; }
|
|
|
|
|
virtual bool cleanOut() const override { return true; }
|
|
|
|
|
virtual bool cleanLhs() const override { return false; }
|
|
|
|
|
virtual bool cleanRhs() const override { return false; }
|
|
|
|
|
virtual bool sizeMattersLhs() const override { return false; }
|
|
|
|
|
virtual bool sizeMattersRhs() const override { return false; }
|
2021-07-25 14:32:36 +02:00
|
|
|
virtual int instrCount() const override { return INSTR_COUNT_DBL; }
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual bool doubleFlavor() const override { return true; }
|
2011-07-24 21:01:51 +02:00
|
|
|
};
|
2020-11-19 03:32:16 +01:00
|
|
|
class AstGtS final : public AstNodeBiop {
|
2014-09-12 03:28:53 +02:00
|
|
|
public:
|
2020-01-25 21:29:44 +01:00
|
|
|
AstGtS(FileLine* fl, AstNode* lhsp, AstNode* rhsp)
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_GtS(fl, lhsp, rhsp) {
|
2020-11-29 14:23:36 +01:00
|
|
|
dtypeSetBit();
|
2020-04-15 13:58:34 +02:00
|
|
|
}
|
2016-11-05 14:47:56 +01:00
|
|
|
ASTNODE_NODE_FUNCS(GtS)
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual AstNode* cloneType(AstNode* lhsp, AstNode* rhsp) override {
|
2020-04-15 13:58:34 +02:00
|
|
|
return new AstGtS(this->fileline(), lhsp, rhsp);
|
|
|
|
|
}
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) override {
|
2020-04-15 13:58:34 +02:00
|
|
|
out.opGtS(lhs, rhs);
|
|
|
|
|
}
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual string emitVerilog() override { return "%k(%l %f> %r)"; }
|
2021-11-28 19:44:16 +01:00
|
|
|
virtual string emitC() override { return "VL_GTS_%nq%lq%rq(%lw, %P, %li, %ri)"; }
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual string emitSimpleOperator() override { return ""; }
|
|
|
|
|
virtual bool cleanOut() const override { return true; }
|
|
|
|
|
virtual bool cleanLhs() const override { return true; }
|
|
|
|
|
virtual bool cleanRhs() const override { return true; }
|
|
|
|
|
virtual bool sizeMattersLhs() const override { return false; }
|
|
|
|
|
virtual bool sizeMattersRhs() const override { return false; }
|
|
|
|
|
virtual bool signedFlavor() const override { return true; }
|
2006-08-26 13:35:28 +02:00
|
|
|
};
|
2020-11-19 03:32:16 +01:00
|
|
|
class AstGtN final : public AstNodeBiop {
|
2014-11-28 21:01:50 +01:00
|
|
|
public:
|
2020-01-25 21:29:44 +01:00
|
|
|
AstGtN(FileLine* fl, AstNode* lhsp, AstNode* rhsp)
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_GtN(fl, lhsp, rhsp) {
|
2020-11-29 14:23:36 +01:00
|
|
|
dtypeSetBit();
|
2020-04-15 13:58:34 +02:00
|
|
|
}
|
2016-11-05 14:47:56 +01:00
|
|
|
ASTNODE_NODE_FUNCS(GtN)
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual AstNode* cloneType(AstNode* lhsp, AstNode* rhsp) override {
|
2020-04-15 13:58:34 +02:00
|
|
|
return new AstGtN(this->fileline(), lhsp, rhsp);
|
|
|
|
|
}
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) override {
|
2020-04-15 13:58:34 +02:00
|
|
|
out.opGtN(lhs, rhs);
|
|
|
|
|
}
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual string emitVerilog() override { return "%k(%l %f> %r)"; }
|
|
|
|
|
virtual string emitC() override { V3ERROR_NA_RETURN(""); }
|
|
|
|
|
virtual string emitSimpleOperator() override { return ">"; }
|
|
|
|
|
virtual bool cleanOut() const override { return true; }
|
|
|
|
|
virtual bool cleanLhs() const override { return false; }
|
|
|
|
|
virtual bool cleanRhs() const override { return false; }
|
|
|
|
|
virtual bool sizeMattersLhs() const override { return false; }
|
|
|
|
|
virtual bool sizeMattersRhs() const override { return false; }
|
2021-07-25 14:32:36 +02:00
|
|
|
virtual int instrCount() const override { return INSTR_COUNT_STR; }
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual bool stringFlavor() const override { return true; }
|
2014-11-28 21:01:50 +01:00
|
|
|
};
|
2020-11-19 03:32:16 +01:00
|
|
|
class AstGte final : public AstNodeBiop {
|
2014-09-12 03:28:53 +02:00
|
|
|
public:
|
2020-01-25 21:29:44 +01:00
|
|
|
AstGte(FileLine* fl, AstNode* lhsp, AstNode* rhsp)
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_Gte(fl, lhsp, rhsp) {
|
2020-11-29 14:23:36 +01:00
|
|
|
dtypeSetBit();
|
2020-04-15 13:58:34 +02:00
|
|
|
}
|
2016-11-05 14:47:56 +01:00
|
|
|
ASTNODE_NODE_FUNCS(Gte)
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual AstNode* cloneType(AstNode* lhsp, AstNode* rhsp) override {
|
2020-04-15 13:58:34 +02:00
|
|
|
return new AstGte(this->fileline(), lhsp, rhsp);
|
|
|
|
|
}
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) override {
|
2020-04-15 13:58:34 +02:00
|
|
|
out.opGte(lhs, rhs);
|
|
|
|
|
}
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual string emitVerilog() override { return "%k(%l %f>= %r)"; }
|
|
|
|
|
virtual string emitC() override { return "VL_GTE_%lq(%lW, %P, %li, %ri)"; }
|
|
|
|
|
virtual string emitSimpleOperator() override { return ">="; }
|
|
|
|
|
virtual bool cleanOut() const override { return true; }
|
|
|
|
|
virtual bool cleanLhs() const override { return true; }
|
|
|
|
|
virtual bool cleanRhs() const override { return true; }
|
|
|
|
|
virtual bool sizeMattersLhs() const override { return false; }
|
|
|
|
|
virtual bool sizeMattersRhs() const override { return false; }
|
2006-08-26 13:35:28 +02:00
|
|
|
};
|
2020-11-19 03:32:16 +01:00
|
|
|
class AstGteD final : public AstNodeBiop {
|
2014-09-12 03:28:53 +02:00
|
|
|
public:
|
2020-01-25 21:29:44 +01:00
|
|
|
AstGteD(FileLine* fl, AstNode* lhsp, AstNode* rhsp)
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_GteD(fl, lhsp, rhsp) {
|
2020-11-29 14:23:36 +01:00
|
|
|
dtypeSetBit();
|
2020-04-15 13:58:34 +02:00
|
|
|
}
|
2016-11-05 14:47:56 +01:00
|
|
|
ASTNODE_NODE_FUNCS(GteD)
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual AstNode* cloneType(AstNode* lhsp, AstNode* rhsp) override {
|
2020-04-15 13:58:34 +02:00
|
|
|
return new AstGteD(this->fileline(), lhsp, rhsp);
|
|
|
|
|
}
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) override {
|
2020-04-15 13:58:34 +02:00
|
|
|
out.opGteD(lhs, rhs);
|
|
|
|
|
}
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual string emitVerilog() override { return "%k(%l %f>= %r)"; }
|
|
|
|
|
virtual string emitC() override { V3ERROR_NA_RETURN(""); }
|
|
|
|
|
virtual string emitSimpleOperator() override { return ">="; }
|
|
|
|
|
virtual bool cleanOut() const override { return true; }
|
|
|
|
|
virtual bool cleanLhs() const override { return false; }
|
|
|
|
|
virtual bool cleanRhs() const override { return false; }
|
|
|
|
|
virtual bool sizeMattersLhs() const override { return false; }
|
|
|
|
|
virtual bool sizeMattersRhs() const override { return false; }
|
2021-07-25 14:32:36 +02:00
|
|
|
virtual int instrCount() const override { return INSTR_COUNT_DBL; }
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual bool doubleFlavor() const override { return true; }
|
2011-07-24 21:01:51 +02:00
|
|
|
};
|
2020-11-19 03:32:16 +01:00
|
|
|
class AstGteS final : public AstNodeBiop {
|
2014-09-12 03:28:53 +02:00
|
|
|
public:
|
2020-01-25 21:29:44 +01:00
|
|
|
AstGteS(FileLine* fl, AstNode* lhsp, AstNode* rhsp)
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_GteS(fl, lhsp, rhsp) {
|
2020-11-29 14:23:36 +01:00
|
|
|
dtypeSetBit();
|
2020-04-15 13:58:34 +02:00
|
|
|
}
|
2016-11-05 14:47:56 +01:00
|
|
|
ASTNODE_NODE_FUNCS(GteS)
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual AstNode* cloneType(AstNode* lhsp, AstNode* rhsp) override {
|
2020-04-15 13:58:34 +02:00
|
|
|
return new AstGteS(this->fileline(), lhsp, rhsp);
|
|
|
|
|
}
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) override {
|
2020-04-15 13:58:34 +02:00
|
|
|
out.opGteS(lhs, rhs);
|
|
|
|
|
}
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual string emitVerilog() override { return "%k(%l %f>= %r)"; }
|
2021-11-28 19:44:16 +01:00
|
|
|
virtual string emitC() override { return "VL_GTES_%nq%lq%rq(%lw, %P, %li, %ri)"; }
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual string emitSimpleOperator() override { return ""; }
|
|
|
|
|
virtual bool cleanOut() const override { return true; }
|
|
|
|
|
virtual bool cleanLhs() const override { return true; }
|
|
|
|
|
virtual bool cleanRhs() const override { return true; }
|
|
|
|
|
virtual bool sizeMattersLhs() const override { return false; }
|
|
|
|
|
virtual bool sizeMattersRhs() const override { return false; }
|
|
|
|
|
virtual bool signedFlavor() const override { return true; }
|
2006-08-26 13:35:28 +02:00
|
|
|
};
|
2020-11-19 03:32:16 +01:00
|
|
|
class AstGteN final : public AstNodeBiop {
|
2014-11-28 21:01:50 +01:00
|
|
|
public:
|
2020-01-25 21:29:44 +01:00
|
|
|
AstGteN(FileLine* fl, AstNode* lhsp, AstNode* rhsp)
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_GteN(fl, lhsp, rhsp) {
|
2020-11-29 14:23:36 +01:00
|
|
|
dtypeSetBit();
|
2020-04-15 13:58:34 +02:00
|
|
|
}
|
2016-11-05 14:47:56 +01:00
|
|
|
ASTNODE_NODE_FUNCS(GteN)
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual AstNode* cloneType(AstNode* lhsp, AstNode* rhsp) override {
|
2020-04-15 13:58:34 +02:00
|
|
|
return new AstGteN(this->fileline(), lhsp, rhsp);
|
|
|
|
|
}
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) override {
|
2020-04-15 13:58:34 +02:00
|
|
|
out.opGteN(lhs, rhs);
|
|
|
|
|
}
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual string emitVerilog() override { return "%k(%l %f>= %r)"; }
|
|
|
|
|
virtual string emitC() override { V3ERROR_NA_RETURN(""); }
|
|
|
|
|
virtual string emitSimpleOperator() override { return ">="; }
|
|
|
|
|
virtual bool cleanOut() const override { return true; }
|
|
|
|
|
virtual bool cleanLhs() const override { return false; }
|
|
|
|
|
virtual bool cleanRhs() const override { return false; }
|
|
|
|
|
virtual bool sizeMattersLhs() const override { return false; }
|
|
|
|
|
virtual bool sizeMattersRhs() const override { return false; }
|
2021-07-25 14:32:36 +02:00
|
|
|
virtual int instrCount() const override { return INSTR_COUNT_STR; }
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual bool stringFlavor() const override { return true; }
|
2014-11-28 21:01:50 +01:00
|
|
|
};
|
2020-11-19 03:32:16 +01:00
|
|
|
class AstLte final : public AstNodeBiop {
|
2014-09-12 03:28:53 +02:00
|
|
|
public:
|
2020-01-25 21:29:44 +01:00
|
|
|
AstLte(FileLine* fl, AstNode* lhsp, AstNode* rhsp)
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_Lte(fl, lhsp, rhsp) {
|
2020-11-29 14:23:36 +01:00
|
|
|
dtypeSetBit();
|
2020-04-15 13:58:34 +02:00
|
|
|
}
|
2016-11-05 14:47:56 +01:00
|
|
|
ASTNODE_NODE_FUNCS(Lte)
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual AstNode* cloneType(AstNode* lhsp, AstNode* rhsp) override {
|
2020-04-15 13:58:34 +02:00
|
|
|
return new AstLte(this->fileline(), lhsp, rhsp);
|
|
|
|
|
}
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) override {
|
2020-04-15 13:58:34 +02:00
|
|
|
out.opLte(lhs, rhs);
|
|
|
|
|
}
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual string emitVerilog() override { return "%k(%l %f<= %r)"; }
|
|
|
|
|
virtual string emitC() override { return "VL_LTE_%lq(%lW, %P, %li, %ri)"; }
|
|
|
|
|
virtual string emitSimpleOperator() override { return "<="; }
|
|
|
|
|
virtual bool cleanOut() const override { return true; }
|
|
|
|
|
virtual bool cleanLhs() const override { return true; }
|
|
|
|
|
virtual bool cleanRhs() const override { return true; }
|
|
|
|
|
virtual bool sizeMattersLhs() const override { return false; }
|
|
|
|
|
virtual bool sizeMattersRhs() const override { return false; }
|
2006-08-26 13:35:28 +02:00
|
|
|
};
|
2020-11-19 03:32:16 +01:00
|
|
|
class AstLteD final : public AstNodeBiop {
|
2014-09-12 03:28:53 +02:00
|
|
|
public:
|
2020-01-25 21:29:44 +01:00
|
|
|
AstLteD(FileLine* fl, AstNode* lhsp, AstNode* rhsp)
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_LteD(fl, lhsp, rhsp) {
|
2020-11-29 14:23:36 +01:00
|
|
|
dtypeSetBit();
|
2020-04-15 13:58:34 +02:00
|
|
|
}
|
2016-11-05 14:47:56 +01:00
|
|
|
ASTNODE_NODE_FUNCS(LteD)
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual AstNode* cloneType(AstNode* lhsp, AstNode* rhsp) override {
|
2020-04-15 13:58:34 +02:00
|
|
|
return new AstLteD(this->fileline(), lhsp, rhsp);
|
|
|
|
|
}
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) override {
|
2020-04-15 13:58:34 +02:00
|
|
|
out.opLteD(lhs, rhs);
|
|
|
|
|
}
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual string emitVerilog() override { return "%k(%l %f<= %r)"; }
|
|
|
|
|
virtual string emitC() override { V3ERROR_NA_RETURN(""); }
|
|
|
|
|
virtual string emitSimpleOperator() override { return "<="; }
|
|
|
|
|
virtual bool cleanOut() const override { return true; }
|
|
|
|
|
virtual bool cleanLhs() const override { return false; }
|
|
|
|
|
virtual bool cleanRhs() const override { return false; }
|
|
|
|
|
virtual bool sizeMattersLhs() const override { return false; }
|
|
|
|
|
virtual bool sizeMattersRhs() const override { return false; }
|
2021-07-25 14:32:36 +02:00
|
|
|
virtual int instrCount() const override { return INSTR_COUNT_DBL; }
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual bool doubleFlavor() const override { return true; }
|
2011-07-24 21:01:51 +02:00
|
|
|
};
|
2020-11-19 03:32:16 +01:00
|
|
|
class AstLteS final : public AstNodeBiop {
|
2014-09-12 03:28:53 +02:00
|
|
|
public:
|
2020-01-25 21:29:44 +01:00
|
|
|
AstLteS(FileLine* fl, AstNode* lhsp, AstNode* rhsp)
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_LteS(fl, lhsp, rhsp) {
|
2020-11-29 14:23:36 +01:00
|
|
|
dtypeSetBit();
|
2020-04-15 13:58:34 +02:00
|
|
|
}
|
2016-11-05 14:47:56 +01:00
|
|
|
ASTNODE_NODE_FUNCS(LteS)
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual AstNode* cloneType(AstNode* lhsp, AstNode* rhsp) override {
|
2020-04-15 13:58:34 +02:00
|
|
|
return new AstLteS(this->fileline(), lhsp, rhsp);
|
|
|
|
|
}
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) override {
|
2020-04-15 13:58:34 +02:00
|
|
|
out.opLteS(lhs, rhs);
|
|
|
|
|
}
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual string emitVerilog() override { return "%k(%l %f<= %r)"; }
|
2021-11-28 19:44:16 +01:00
|
|
|
virtual string emitC() override { return "VL_LTES_%nq%lq%rq(%lw, %P, %li, %ri)"; }
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual string emitSimpleOperator() override { return ""; }
|
|
|
|
|
virtual bool cleanOut() const override { return true; }
|
|
|
|
|
virtual bool cleanLhs() const override { return true; }
|
|
|
|
|
virtual bool cleanRhs() const override { return true; }
|
|
|
|
|
virtual bool sizeMattersLhs() const override { return false; }
|
|
|
|
|
virtual bool sizeMattersRhs() const override { return false; }
|
|
|
|
|
virtual bool signedFlavor() const override { return true; }
|
2006-08-26 13:35:28 +02:00
|
|
|
};
|
2020-11-19 03:32:16 +01:00
|
|
|
class AstLteN final : public AstNodeBiop {
|
2014-11-28 21:01:50 +01:00
|
|
|
public:
|
2020-01-25 21:29:44 +01:00
|
|
|
AstLteN(FileLine* fl, AstNode* lhsp, AstNode* rhsp)
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_LteN(fl, lhsp, rhsp) {
|
2020-11-29 14:23:36 +01:00
|
|
|
dtypeSetBit();
|
2020-04-15 13:58:34 +02:00
|
|
|
}
|
2016-11-05 14:47:56 +01:00
|
|
|
ASTNODE_NODE_FUNCS(LteN)
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual AstNode* cloneType(AstNode* lhsp, AstNode* rhsp) override {
|
2020-04-15 13:58:34 +02:00
|
|
|
return new AstLteN(this->fileline(), lhsp, rhsp);
|
|
|
|
|
}
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) override {
|
2020-04-15 13:58:34 +02:00
|
|
|
out.opLteN(lhs, rhs);
|
|
|
|
|
}
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual string emitVerilog() override { return "%k(%l %f<= %r)"; }
|
|
|
|
|
virtual string emitC() override { V3ERROR_NA_RETURN(""); }
|
|
|
|
|
virtual string emitSimpleOperator() override { return "<="; }
|
|
|
|
|
virtual bool cleanOut() const override { return true; }
|
|
|
|
|
virtual bool cleanLhs() const override { return false; }
|
|
|
|
|
virtual bool cleanRhs() const override { return false; }
|
|
|
|
|
virtual bool sizeMattersLhs() const override { return false; }
|
|
|
|
|
virtual bool sizeMattersRhs() const override { return false; }
|
2021-07-25 14:32:36 +02:00
|
|
|
virtual int instrCount() const override { return INSTR_COUNT_STR; }
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual bool stringFlavor() const override { return true; }
|
2014-11-28 21:01:50 +01:00
|
|
|
};
|
2020-11-19 03:32:16 +01:00
|
|
|
class AstShiftL final : public AstNodeBiop {
|
2014-09-12 03:28:53 +02:00
|
|
|
public:
|
2020-04-15 13:58:34 +02:00
|
|
|
AstShiftL(FileLine* fl, AstNode* lhsp, AstNode* rhsp, int setwidth = 0)
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_ShiftL(fl, lhsp, rhsp) {
|
2021-02-22 03:25:21 +01:00
|
|
|
if (setwidth) dtypeSetLogicSized(setwidth, VSigning::UNSIGNED);
|
2006-08-26 13:35:28 +02:00
|
|
|
}
|
2016-11-05 14:47:56 +01:00
|
|
|
ASTNODE_NODE_FUNCS(ShiftL)
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual AstNode* cloneType(AstNode* lhsp, AstNode* rhsp) override {
|
2020-04-15 13:58:34 +02:00
|
|
|
return new AstShiftL(this->fileline(), lhsp, rhsp);
|
|
|
|
|
}
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) override {
|
2020-04-15 13:58:34 +02:00
|
|
|
out.opShiftL(lhs, rhs);
|
|
|
|
|
}
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual string emitVerilog() override { return "%k(%l %f<< %r)"; }
|
|
|
|
|
virtual string emitC() override { return "VL_SHIFTL_%nq%lq%rq(%nw,%lw,%rw, %P, %li, %ri)"; }
|
2021-02-14 17:15:12 +01:00
|
|
|
virtual string emitSimpleOperator() override {
|
|
|
|
|
return (rhsp()->isWide() || rhsp()->isQuad()) ? "" : "<<";
|
|
|
|
|
}
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual bool cleanOut() const override { return false; }
|
|
|
|
|
virtual bool cleanLhs() const override { return false; }
|
|
|
|
|
virtual bool cleanRhs() const override { return true; }
|
|
|
|
|
virtual bool sizeMattersLhs() const override { return true; }
|
|
|
|
|
virtual bool sizeMattersRhs() const override { return false; }
|
2006-08-26 13:35:28 +02:00
|
|
|
};
|
2020-11-19 03:32:16 +01:00
|
|
|
class AstShiftR final : public AstNodeBiop {
|
2014-09-12 03:28:53 +02:00
|
|
|
public:
|
2020-04-15 13:58:34 +02:00
|
|
|
AstShiftR(FileLine* fl, AstNode* lhsp, AstNode* rhsp, int setwidth = 0)
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_ShiftR(fl, lhsp, rhsp) {
|
2021-02-22 03:25:21 +01:00
|
|
|
if (setwidth) dtypeSetLogicSized(setwidth, VSigning::UNSIGNED);
|
2006-08-26 13:35:28 +02:00
|
|
|
}
|
2016-11-05 14:47:56 +01:00
|
|
|
ASTNODE_NODE_FUNCS(ShiftR)
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual AstNode* cloneType(AstNode* lhsp, AstNode* rhsp) override {
|
2020-04-15 13:58:34 +02:00
|
|
|
return new AstShiftR(this->fileline(), lhsp, rhsp);
|
|
|
|
|
}
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) override {
|
2020-04-15 13:58:34 +02:00
|
|
|
out.opShiftR(lhs, rhs);
|
|
|
|
|
}
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual string emitVerilog() override { return "%k(%l %f>> %r)"; }
|
|
|
|
|
virtual string emitC() override { return "VL_SHIFTR_%nq%lq%rq(%nw,%lw,%rw, %P, %li, %ri)"; }
|
2021-02-14 17:15:12 +01:00
|
|
|
virtual string emitSimpleOperator() override {
|
|
|
|
|
return (rhsp()->isWide() || rhsp()->isQuad()) ? "" : ">>";
|
|
|
|
|
}
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual bool cleanOut() const override { return false; }
|
|
|
|
|
virtual bool cleanLhs() const override { return true; }
|
|
|
|
|
virtual bool cleanRhs() const override { return true; }
|
2018-03-10 22:32:04 +01:00
|
|
|
// LHS size might be > output size, so don't want to force size
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual bool sizeMattersLhs() const override { return false; }
|
|
|
|
|
virtual bool sizeMattersRhs() const override { return false; }
|
2006-08-26 13:35:28 +02:00
|
|
|
};
|
2020-11-19 03:32:16 +01:00
|
|
|
class AstShiftRS final : public AstNodeBiop {
|
2014-03-10 02:28:28 +01:00
|
|
|
// Shift right with sign extension, >>> operator
|
|
|
|
|
// Output data type's width determines which bit is used for sign extension
|
2014-09-12 03:28:53 +02:00
|
|
|
public:
|
2020-04-15 13:58:34 +02:00
|
|
|
AstShiftRS(FileLine* fl, AstNode* lhsp, AstNode* rhsp, int setwidth = 0)
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_ShiftRS(fl, lhsp, rhsp) {
|
2019-05-19 22:13:13 +02:00
|
|
|
// Important that widthMin be correct, as opExtend requires it after V3Expand
|
2021-02-22 03:25:21 +01:00
|
|
|
if (setwidth) dtypeSetLogicSized(setwidth, VSigning::SIGNED);
|
2006-08-26 13:35:28 +02:00
|
|
|
}
|
2016-11-05 14:47:56 +01:00
|
|
|
ASTNODE_NODE_FUNCS(ShiftRS)
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual AstNode* cloneType(AstNode* lhsp, AstNode* rhsp) override {
|
2020-04-15 13:58:34 +02:00
|
|
|
return new AstShiftRS(this->fileline(), lhsp, rhsp);
|
|
|
|
|
}
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) override {
|
2020-04-15 13:58:34 +02:00
|
|
|
out.opShiftRS(lhs, rhs, lhsp()->widthMinV());
|
|
|
|
|
}
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual string emitVerilog() override { return "%k(%l %f>>> %r)"; }
|
|
|
|
|
virtual string emitC() override { return "VL_SHIFTRS_%nq%lq%rq(%nw,%lw,%rw, %P, %li, %ri)"; }
|
|
|
|
|
virtual string emitSimpleOperator() override { return ""; }
|
|
|
|
|
virtual bool cleanOut() const override { return false; }
|
|
|
|
|
virtual bool cleanLhs() const override { return true; }
|
|
|
|
|
virtual bool cleanRhs() const override { return true; }
|
|
|
|
|
virtual bool sizeMattersLhs() const override { return false; }
|
|
|
|
|
virtual bool sizeMattersRhs() const override { return false; }
|
|
|
|
|
virtual bool signedFlavor() const override { return true; }
|
2006-08-26 13:35:28 +02:00
|
|
|
};
|
2020-11-19 03:32:16 +01:00
|
|
|
class AstAdd final : public AstNodeBiComAsv {
|
2014-09-12 03:28:53 +02:00
|
|
|
public:
|
2020-01-25 21:29:44 +01:00
|
|
|
AstAdd(FileLine* fl, AstNode* lhsp, AstNode* rhsp)
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_Add(fl, lhsp, rhsp) {
|
2020-04-15 13:58:34 +02:00
|
|
|
dtypeFrom(lhsp);
|
|
|
|
|
}
|
2016-11-05 14:47:56 +01:00
|
|
|
ASTNODE_NODE_FUNCS(Add)
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual AstNode* cloneType(AstNode* lhsp, AstNode* rhsp) override {
|
2020-04-15 13:58:34 +02:00
|
|
|
return new AstAdd(this->fileline(), lhsp, rhsp);
|
|
|
|
|
}
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) override {
|
2020-04-15 13:58:34 +02:00
|
|
|
out.opAdd(lhs, rhs);
|
|
|
|
|
}
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual string emitVerilog() override { return "%k(%l %f+ %r)"; }
|
|
|
|
|
virtual string emitC() override { return "VL_ADD_%lq(%lW, %P, %li, %ri)"; }
|
|
|
|
|
virtual string emitSimpleOperator() override { return "+"; }
|
|
|
|
|
virtual bool cleanOut() const override { return false; }
|
|
|
|
|
virtual bool cleanLhs() const override { return false; }
|
|
|
|
|
virtual bool cleanRhs() const override { return false; }
|
|
|
|
|
virtual bool sizeMattersLhs() const override { return true; }
|
|
|
|
|
virtual bool sizeMattersRhs() const override { return true; }
|
2006-08-26 13:35:28 +02:00
|
|
|
};
|
2020-11-19 03:32:16 +01:00
|
|
|
class AstAddD final : public AstNodeBiComAsv {
|
2014-09-12 03:28:53 +02:00
|
|
|
public:
|
2020-01-25 21:29:44 +01:00
|
|
|
AstAddD(FileLine* fl, AstNode* lhsp, AstNode* rhsp)
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_AddD(fl, lhsp, rhsp) {
|
2020-04-15 13:58:34 +02:00
|
|
|
dtypeSetDouble();
|
|
|
|
|
}
|
2016-11-05 14:47:56 +01:00
|
|
|
ASTNODE_NODE_FUNCS(AddD)
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual AstNode* cloneType(AstNode* lhsp, AstNode* rhsp) override {
|
2020-04-15 13:58:34 +02:00
|
|
|
return new AstAddD(this->fileline(), lhsp, rhsp);
|
|
|
|
|
}
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) override {
|
2020-04-15 13:58:34 +02:00
|
|
|
out.opAddD(lhs, rhs);
|
|
|
|
|
}
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual string emitVerilog() override { return "%k(%l %f+ %r)"; }
|
|
|
|
|
virtual string emitC() override { V3ERROR_NA_RETURN(""); }
|
|
|
|
|
virtual string emitSimpleOperator() override { return "+"; }
|
|
|
|
|
virtual bool cleanOut() const override { return true; }
|
|
|
|
|
virtual bool cleanLhs() const override { return false; }
|
|
|
|
|
virtual bool cleanRhs() const override { return false; }
|
|
|
|
|
virtual bool sizeMattersLhs() const override { return false; }
|
|
|
|
|
virtual bool sizeMattersRhs() const override { return false; }
|
2021-07-25 14:32:36 +02:00
|
|
|
virtual int instrCount() const override { return INSTR_COUNT_DBL; }
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual bool doubleFlavor() const override { return true; }
|
2011-07-24 21:01:51 +02:00
|
|
|
};
|
2020-11-19 03:32:16 +01:00
|
|
|
class AstSub final : public AstNodeBiop {
|
2014-09-12 03:28:53 +02:00
|
|
|
public:
|
2020-01-25 21:29:44 +01:00
|
|
|
AstSub(FileLine* fl, AstNode* lhsp, AstNode* rhsp)
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_Sub(fl, lhsp, rhsp) {
|
2020-04-15 13:58:34 +02:00
|
|
|
dtypeFrom(lhsp);
|
|
|
|
|
}
|
2016-11-05 14:47:56 +01:00
|
|
|
ASTNODE_NODE_FUNCS(Sub)
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual AstNode* cloneType(AstNode* lhsp, AstNode* rhsp) override {
|
2020-04-15 13:58:34 +02:00
|
|
|
return new AstSub(this->fileline(), lhsp, rhsp);
|
|
|
|
|
}
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) override {
|
2020-04-15 13:58:34 +02:00
|
|
|
out.opSub(lhs, rhs);
|
|
|
|
|
}
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual string emitVerilog() override { return "%k(%l %f- %r)"; }
|
|
|
|
|
virtual string emitC() override { return "VL_SUB_%lq(%lW, %P, %li, %ri)"; }
|
|
|
|
|
virtual string emitSimpleOperator() override { return "-"; }
|
|
|
|
|
virtual bool cleanOut() const override { return false; }
|
|
|
|
|
virtual bool cleanLhs() const override { return false; }
|
|
|
|
|
virtual bool cleanRhs() const override { return false; }
|
|
|
|
|
virtual bool sizeMattersLhs() const override { return true; }
|
|
|
|
|
virtual bool sizeMattersRhs() const override { return true; }
|
2006-08-26 13:35:28 +02:00
|
|
|
};
|
2020-11-19 03:32:16 +01:00
|
|
|
class AstSubD final : public AstNodeBiop {
|
2014-09-12 03:28:53 +02:00
|
|
|
public:
|
2020-01-25 21:29:44 +01:00
|
|
|
AstSubD(FileLine* fl, AstNode* lhsp, AstNode* rhsp)
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_SubD(fl, lhsp, rhsp) {
|
2020-04-15 13:58:34 +02:00
|
|
|
dtypeSetDouble();
|
|
|
|
|
}
|
2016-11-05 14:47:56 +01:00
|
|
|
ASTNODE_NODE_FUNCS(SubD)
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual AstNode* cloneType(AstNode* lhsp, AstNode* rhsp) override {
|
2020-04-15 13:58:34 +02:00
|
|
|
return new AstSubD(this->fileline(), lhsp, rhsp);
|
|
|
|
|
}
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) override {
|
2020-04-15 13:58:34 +02:00
|
|
|
out.opSubD(lhs, rhs);
|
|
|
|
|
}
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual string emitVerilog() override { return "%k(%l %f- %r)"; }
|
|
|
|
|
virtual string emitC() override { V3ERROR_NA_RETURN(""); }
|
|
|
|
|
virtual string emitSimpleOperator() override { return "-"; }
|
|
|
|
|
virtual bool cleanOut() const override { return true; }
|
|
|
|
|
virtual bool cleanLhs() const override { return false; }
|
|
|
|
|
virtual bool cleanRhs() const override { return false; }
|
|
|
|
|
virtual bool sizeMattersLhs() const override { return false; }
|
|
|
|
|
virtual bool sizeMattersRhs() const override { return false; }
|
2021-07-25 14:32:36 +02:00
|
|
|
virtual int instrCount() const override { return INSTR_COUNT_DBL; }
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual bool doubleFlavor() const override { return true; }
|
2011-07-24 21:01:51 +02:00
|
|
|
};
|
2020-11-19 03:32:16 +01:00
|
|
|
class AstMul final : public AstNodeBiComAsv {
|
2014-09-12 03:28:53 +02:00
|
|
|
public:
|
2020-01-25 21:29:44 +01:00
|
|
|
AstMul(FileLine* fl, AstNode* lhsp, AstNode* rhsp)
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_Mul(fl, lhsp, rhsp) {
|
2020-04-15 13:58:34 +02:00
|
|
|
dtypeFrom(lhsp);
|
|
|
|
|
}
|
2016-11-05 14:47:56 +01:00
|
|
|
ASTNODE_NODE_FUNCS(Mul)
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual AstNode* cloneType(AstNode* lhsp, AstNode* rhsp) override {
|
2020-04-15 13:58:34 +02:00
|
|
|
return new AstMul(this->fileline(), lhsp, rhsp);
|
|
|
|
|
}
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) override {
|
2020-04-15 13:58:34 +02:00
|
|
|
out.opMul(lhs, rhs);
|
|
|
|
|
}
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual string emitVerilog() override { return "%k(%l %f* %r)"; }
|
|
|
|
|
virtual string emitC() override { return "VL_MUL_%lq(%lW, %P, %li, %ri)"; }
|
|
|
|
|
virtual string emitSimpleOperator() override { return "*"; }
|
|
|
|
|
virtual bool cleanOut() const override { return false; }
|
|
|
|
|
virtual bool cleanLhs() const override { return true; }
|
|
|
|
|
virtual bool cleanRhs() const override { return true; }
|
|
|
|
|
virtual bool sizeMattersLhs() const override { return true; }
|
|
|
|
|
virtual bool sizeMattersRhs() const override { return true; }
|
2021-07-25 14:32:36 +02:00
|
|
|
virtual int instrCount() const override { return widthInstrs() * INSTR_COUNT_INT_MUL; }
|
2006-08-26 13:35:28 +02:00
|
|
|
};
|
2020-11-19 03:32:16 +01:00
|
|
|
class AstMulD final : public AstNodeBiComAsv {
|
2014-09-12 03:28:53 +02:00
|
|
|
public:
|
2020-01-25 21:29:44 +01:00
|
|
|
AstMulD(FileLine* fl, AstNode* lhsp, AstNode* rhsp)
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_MulD(fl, lhsp, rhsp) {
|
2020-04-15 13:58:34 +02:00
|
|
|
dtypeSetDouble();
|
|
|
|
|
}
|
2016-11-05 14:47:56 +01:00
|
|
|
ASTNODE_NODE_FUNCS(MulD)
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual AstNode* cloneType(AstNode* lhsp, AstNode* rhsp) override {
|
2020-04-15 13:58:34 +02:00
|
|
|
return new AstMulD(this->fileline(), lhsp, rhsp);
|
|
|
|
|
}
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) override {
|
2020-04-15 13:58:34 +02:00
|
|
|
out.opMulD(lhs, rhs);
|
|
|
|
|
}
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual string emitVerilog() override { return "%k(%l %f* %r)"; }
|
|
|
|
|
virtual string emitC() override { V3ERROR_NA_RETURN(""); }
|
|
|
|
|
virtual string emitSimpleOperator() override { return "*"; }
|
|
|
|
|
virtual bool cleanOut() const override { return true; }
|
|
|
|
|
virtual bool cleanLhs() const override { return false; }
|
|
|
|
|
virtual bool cleanRhs() const override { return false; }
|
|
|
|
|
virtual bool sizeMattersLhs() const override { return true; }
|
|
|
|
|
virtual bool sizeMattersRhs() const override { return true; }
|
2021-07-25 14:32:36 +02:00
|
|
|
virtual int instrCount() const override { return INSTR_COUNT_DBL; }
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual bool doubleFlavor() const override { return true; }
|
2011-07-24 21:01:51 +02:00
|
|
|
};
|
2020-11-19 03:32:16 +01:00
|
|
|
class AstMulS final : public AstNodeBiComAsv {
|
2014-09-12 03:28:53 +02:00
|
|
|
public:
|
2020-01-25 21:29:44 +01:00
|
|
|
AstMulS(FileLine* fl, AstNode* lhsp, AstNode* rhsp)
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_MulS(fl, lhsp, rhsp) {
|
2020-04-15 13:58:34 +02:00
|
|
|
dtypeFrom(lhsp);
|
|
|
|
|
}
|
2016-11-05 14:47:56 +01:00
|
|
|
ASTNODE_NODE_FUNCS(MulS)
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual AstNode* cloneType(AstNode* lhsp, AstNode* rhsp) override {
|
2020-04-15 13:58:34 +02:00
|
|
|
return new AstMulS(this->fileline(), lhsp, rhsp);
|
|
|
|
|
}
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) override {
|
2020-04-15 13:58:34 +02:00
|
|
|
out.opMulS(lhs, rhs);
|
|
|
|
|
}
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual string emitVerilog() override { return "%k(%l %f* %r)"; }
|
2021-11-28 19:44:16 +01:00
|
|
|
virtual string emitC() override { return "VL_MULS_%nq%lq%rq(%lw, %P, %li, %ri)"; }
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual string emitSimpleOperator() override { return ""; }
|
|
|
|
|
virtual bool emitCheckMaxWords() override { return true; }
|
|
|
|
|
virtual bool cleanOut() const override { return false; }
|
|
|
|
|
virtual bool cleanLhs() const override { return true; }
|
|
|
|
|
virtual bool cleanRhs() const override { return true; }
|
|
|
|
|
virtual bool sizeMattersLhs() const override { return true; }
|
|
|
|
|
virtual bool sizeMattersRhs() const override { return true; }
|
2021-07-25 14:32:36 +02:00
|
|
|
virtual int instrCount() const override { return widthInstrs() * INSTR_COUNT_INT_MUL; }
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual bool signedFlavor() const override { return true; }
|
2006-08-26 13:35:28 +02:00
|
|
|
};
|
2020-11-19 03:32:16 +01:00
|
|
|
class AstDiv final : public AstNodeBiop {
|
2014-09-12 03:28:53 +02:00
|
|
|
public:
|
2020-01-25 21:29:44 +01:00
|
|
|
AstDiv(FileLine* fl, AstNode* lhsp, AstNode* rhsp)
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_Div(fl, lhsp, rhsp) {
|
2020-04-15 13:58:34 +02:00
|
|
|
dtypeFrom(lhsp);
|
|
|
|
|
}
|
2016-11-05 14:47:56 +01:00
|
|
|
ASTNODE_NODE_FUNCS(Div)
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual AstNode* cloneType(AstNode* lhsp, AstNode* rhsp) override {
|
2020-04-15 13:58:34 +02:00
|
|
|
return new AstDiv(this->fileline(), lhsp, rhsp);
|
|
|
|
|
}
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) override {
|
2020-04-15 13:58:34 +02:00
|
|
|
out.opDiv(lhs, rhs);
|
|
|
|
|
}
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual string emitVerilog() override { return "%k(%l %f/ %r)"; }
|
|
|
|
|
virtual string emitC() override { return "VL_DIV_%nq%lq%rq(%lw, %P, %li, %ri)"; }
|
|
|
|
|
virtual bool cleanOut() const override { return false; }
|
|
|
|
|
virtual bool cleanLhs() const override { return true; }
|
|
|
|
|
virtual bool cleanRhs() const override { return true; }
|
|
|
|
|
virtual bool sizeMattersLhs() const override { return true; }
|
|
|
|
|
virtual bool sizeMattersRhs() const override { return true; }
|
2021-07-25 14:32:36 +02:00
|
|
|
virtual int instrCount() const override { return widthInstrs() * INSTR_COUNT_INT_DIV; }
|
2006-08-26 13:35:28 +02:00
|
|
|
};
|
2020-11-19 03:32:16 +01:00
|
|
|
class AstDivD final : public AstNodeBiop {
|
2014-09-12 03:28:53 +02:00
|
|
|
public:
|
2020-01-25 21:29:44 +01:00
|
|
|
AstDivD(FileLine* fl, AstNode* lhsp, AstNode* rhsp)
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_DivD(fl, lhsp, rhsp) {
|
2020-04-15 13:58:34 +02:00
|
|
|
dtypeSetDouble();
|
|
|
|
|
}
|
2016-11-05 14:47:56 +01:00
|
|
|
ASTNODE_NODE_FUNCS(DivD)
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual AstNode* cloneType(AstNode* lhsp, AstNode* rhsp) override {
|
2020-04-15 13:58:34 +02:00
|
|
|
return new AstDivD(this->fileline(), lhsp, rhsp);
|
|
|
|
|
}
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) override {
|
2020-04-15 13:58:34 +02:00
|
|
|
out.opDivD(lhs, rhs);
|
|
|
|
|
}
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual string emitVerilog() override { return "%k(%l %f/ %r)"; }
|
|
|
|
|
virtual string emitC() override { V3ERROR_NA_RETURN(""); }
|
|
|
|
|
virtual string emitSimpleOperator() override { return "/"; }
|
|
|
|
|
virtual bool cleanOut() const override { return true; }
|
|
|
|
|
virtual bool cleanLhs() const override { return false; }
|
|
|
|
|
virtual bool cleanRhs() const override { return false; }
|
|
|
|
|
virtual bool sizeMattersLhs() const override { return false; }
|
|
|
|
|
virtual bool sizeMattersRhs() const override { return false; }
|
2021-07-25 14:32:36 +02:00
|
|
|
virtual int instrCount() const override { return INSTR_COUNT_DBL_DIV; }
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual bool doubleFlavor() const override { return true; }
|
2011-07-24 21:01:51 +02:00
|
|
|
};
|
2020-11-19 03:32:16 +01:00
|
|
|
class AstDivS final : public AstNodeBiop {
|
2014-09-12 03:28:53 +02:00
|
|
|
public:
|
2020-01-25 21:29:44 +01:00
|
|
|
AstDivS(FileLine* fl, AstNode* lhsp, AstNode* rhsp)
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_DivS(fl, lhsp, rhsp) {
|
2020-04-15 13:58:34 +02:00
|
|
|
dtypeFrom(lhsp);
|
|
|
|
|
}
|
2016-11-05 14:47:56 +01:00
|
|
|
ASTNODE_NODE_FUNCS(DivS)
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual AstNode* cloneType(AstNode* lhsp, AstNode* rhsp) override {
|
2020-04-15 13:58:34 +02:00
|
|
|
return new AstDivS(this->fileline(), lhsp, rhsp);
|
|
|
|
|
}
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) override {
|
2020-04-15 13:58:34 +02:00
|
|
|
out.opDivS(lhs, rhs);
|
|
|
|
|
}
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual string emitVerilog() override { return "%k(%l %f/ %r)"; }
|
|
|
|
|
virtual string emitC() override { return "VL_DIVS_%nq%lq%rq(%lw, %P, %li, %ri)"; }
|
|
|
|
|
virtual bool cleanOut() const override { return false; }
|
|
|
|
|
virtual bool cleanLhs() const override { return true; }
|
|
|
|
|
virtual bool cleanRhs() const override { return true; }
|
|
|
|
|
virtual bool sizeMattersLhs() const override { return true; }
|
|
|
|
|
virtual bool sizeMattersRhs() const override { return true; }
|
2021-07-25 14:32:36 +02:00
|
|
|
virtual int instrCount() const override { return widthInstrs() * INSTR_COUNT_INT_DIV; }
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual bool signedFlavor() const override { return true; }
|
2006-08-26 13:35:28 +02:00
|
|
|
};
|
2020-11-19 03:32:16 +01:00
|
|
|
class AstModDiv final : public AstNodeBiop {
|
2014-09-12 03:28:53 +02:00
|
|
|
public:
|
2020-01-25 21:29:44 +01:00
|
|
|
AstModDiv(FileLine* fl, AstNode* lhsp, AstNode* rhsp)
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_ModDiv(fl, lhsp, rhsp) {
|
2020-04-15 13:58:34 +02:00
|
|
|
dtypeFrom(lhsp);
|
|
|
|
|
}
|
2016-11-05 14:47:56 +01:00
|
|
|
ASTNODE_NODE_FUNCS(ModDiv)
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual AstNode* cloneType(AstNode* lhsp, AstNode* rhsp) override {
|
2020-04-15 13:58:34 +02:00
|
|
|
return new AstModDiv(this->fileline(), lhsp, rhsp);
|
|
|
|
|
}
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) override {
|
2020-04-15 13:58:34 +02:00
|
|
|
out.opModDiv(lhs, rhs);
|
|
|
|
|
}
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual string emitVerilog() override { return "%k(%l %f%% %r)"; }
|
|
|
|
|
virtual string emitC() override { return "VL_MODDIV_%nq%lq%rq(%lw, %P, %li, %ri)"; }
|
|
|
|
|
virtual bool cleanOut() const override { return false; }
|
|
|
|
|
virtual bool cleanLhs() const override { return true; }
|
|
|
|
|
virtual bool cleanRhs() const override { return true; }
|
|
|
|
|
virtual bool sizeMattersLhs() const override { return true; }
|
|
|
|
|
virtual bool sizeMattersRhs() const override { return true; }
|
2021-07-25 14:32:36 +02:00
|
|
|
virtual int instrCount() const override { return widthInstrs() * INSTR_COUNT_INT_DIV; }
|
2006-08-26 13:35:28 +02:00
|
|
|
};
|
2020-11-19 03:32:16 +01:00
|
|
|
class AstModDivS final : public AstNodeBiop {
|
2014-09-12 03:28:53 +02:00
|
|
|
public:
|
2020-01-25 21:29:44 +01:00
|
|
|
AstModDivS(FileLine* fl, AstNode* lhsp, AstNode* rhsp)
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_ModDivS(fl, lhsp, rhsp) {
|
2020-04-15 13:58:34 +02:00
|
|
|
dtypeFrom(lhsp);
|
|
|
|
|
}
|
2016-11-05 14:47:56 +01:00
|
|
|
ASTNODE_NODE_FUNCS(ModDivS)
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual AstNode* cloneType(AstNode* lhsp, AstNode* rhsp) override {
|
2020-04-15 13:58:34 +02:00
|
|
|
return new AstModDivS(this->fileline(), lhsp, rhsp);
|
|
|
|
|
}
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) override {
|
2020-04-15 13:58:34 +02:00
|
|
|
out.opModDivS(lhs, rhs);
|
|
|
|
|
}
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual string emitVerilog() override { return "%k(%l %f%% %r)"; }
|
|
|
|
|
virtual string emitC() override { return "VL_MODDIVS_%nq%lq%rq(%lw, %P, %li, %ri)"; }
|
|
|
|
|
virtual bool cleanOut() const override { return false; }
|
|
|
|
|
virtual bool cleanLhs() const override { return true; }
|
|
|
|
|
virtual bool cleanRhs() const override { return true; }
|
|
|
|
|
virtual bool sizeMattersLhs() const override { return true; }
|
|
|
|
|
virtual bool sizeMattersRhs() const override { return true; }
|
2021-07-25 14:32:36 +02:00
|
|
|
virtual int instrCount() const override { return widthInstrs() * INSTR_COUNT_INT_DIV; }
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual bool signedFlavor() const override { return true; }
|
2006-08-26 13:35:28 +02:00
|
|
|
};
|
2020-11-19 03:32:16 +01:00
|
|
|
class AstPow final : public AstNodeBiop {
|
2014-09-12 03:28:53 +02:00
|
|
|
public:
|
2020-01-25 21:29:44 +01:00
|
|
|
AstPow(FileLine* fl, AstNode* lhsp, AstNode* rhsp)
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_Pow(fl, lhsp, rhsp) {
|
2020-04-15 13:58:34 +02:00
|
|
|
dtypeFrom(lhsp);
|
|
|
|
|
}
|
2016-11-05 14:47:56 +01:00
|
|
|
ASTNODE_NODE_FUNCS(Pow)
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual AstNode* cloneType(AstNode* lhsp, AstNode* rhsp) override {
|
2020-04-15 13:58:34 +02:00
|
|
|
return new AstPow(this->fileline(), lhsp, rhsp);
|
|
|
|
|
}
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) override {
|
2020-04-15 13:58:34 +02:00
|
|
|
out.opPow(lhs, rhs);
|
|
|
|
|
}
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual string emitVerilog() override { return "%k(%l %f** %r)"; }
|
|
|
|
|
virtual string emitC() override { return "VL_POW_%nq%lq%rq(%nw,%lw,%rw, %P, %li, %ri)"; }
|
|
|
|
|
virtual bool emitCheckMaxWords() override { return true; }
|
|
|
|
|
virtual bool cleanOut() const override { return false; }
|
|
|
|
|
virtual bool cleanLhs() const override { return true; }
|
|
|
|
|
virtual bool cleanRhs() const override { return true; }
|
|
|
|
|
virtual bool sizeMattersLhs() const override { return true; }
|
|
|
|
|
virtual bool sizeMattersRhs() const override { return false; }
|
2021-07-25 14:32:36 +02:00
|
|
|
virtual int instrCount() const override { return widthInstrs() * INSTR_COUNT_INT_MUL * 10; }
|
2006-08-26 13:35:28 +02:00
|
|
|
};
|
2020-11-19 03:32:16 +01:00
|
|
|
class AstPowD final : public AstNodeBiop {
|
2014-09-12 03:28:53 +02:00
|
|
|
public:
|
2020-01-25 21:29:44 +01:00
|
|
|
AstPowD(FileLine* fl, AstNode* lhsp, AstNode* rhsp)
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_PowD(fl, lhsp, rhsp) {
|
2020-04-15 13:58:34 +02:00
|
|
|
dtypeSetDouble();
|
|
|
|
|
}
|
2016-11-05 14:47:56 +01:00
|
|
|
ASTNODE_NODE_FUNCS(PowD)
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual AstNode* cloneType(AstNode* lhsp, AstNode* rhsp) override {
|
2020-04-15 13:58:34 +02:00
|
|
|
return new AstPowD(this->fileline(), lhsp, rhsp);
|
|
|
|
|
}
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) override {
|
2020-04-15 13:58:34 +02:00
|
|
|
out.opPowD(lhs, rhs);
|
|
|
|
|
}
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual string emitVerilog() override { return "%k(%l %f** %r)"; }
|
|
|
|
|
virtual string emitC() override { return "pow(%li,%ri)"; }
|
|
|
|
|
virtual bool cleanOut() const override { return false; }
|
|
|
|
|
virtual bool cleanLhs() const override { return false; }
|
|
|
|
|
virtual bool cleanRhs() const override { return false; }
|
|
|
|
|
virtual bool sizeMattersLhs() const override { return false; }
|
|
|
|
|
virtual bool sizeMattersRhs() const override { return false; }
|
2021-07-25 14:32:36 +02:00
|
|
|
virtual int instrCount() const override { return INSTR_COUNT_DBL_DIV * 5; }
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual bool doubleFlavor() const override { return true; }
|
2011-07-24 21:01:51 +02:00
|
|
|
};
|
2020-11-19 03:32:16 +01:00
|
|
|
class AstPowSU final : public AstNodeBiop {
|
2014-09-12 03:28:53 +02:00
|
|
|
public:
|
2020-01-25 21:29:44 +01:00
|
|
|
AstPowSU(FileLine* fl, AstNode* lhsp, AstNode* rhsp)
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_PowSU(fl, lhsp, rhsp) {
|
2020-04-15 13:58:34 +02:00
|
|
|
dtypeFrom(lhsp);
|
|
|
|
|
}
|
2016-11-05 14:47:56 +01:00
|
|
|
ASTNODE_NODE_FUNCS(PowSU)
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual AstNode* cloneType(AstNode* lhsp, AstNode* rhsp) override {
|
2020-04-15 13:58:34 +02:00
|
|
|
return new AstPowSU(this->fileline(), lhsp, rhsp);
|
|
|
|
|
}
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) override {
|
2020-04-15 13:58:34 +02:00
|
|
|
out.opPowSU(lhs, rhs);
|
|
|
|
|
}
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual string emitVerilog() override { return "%k(%l %f** %r)"; }
|
|
|
|
|
virtual string emitC() override {
|
|
|
|
|
return "VL_POWSS_%nq%lq%rq(%nw,%lw,%rw, %P, %li, %ri, 1,0)";
|
|
|
|
|
}
|
|
|
|
|
virtual bool emitCheckMaxWords() override { return true; }
|
|
|
|
|
virtual bool cleanOut() const override { return false; }
|
|
|
|
|
virtual bool cleanLhs() const override { return true; }
|
|
|
|
|
virtual bool cleanRhs() const override { return true; }
|
|
|
|
|
virtual bool sizeMattersLhs() const override { return true; }
|
|
|
|
|
virtual bool sizeMattersRhs() const override { return false; }
|
2021-07-25 14:32:36 +02:00
|
|
|
virtual int instrCount() const override { return widthInstrs() * INSTR_COUNT_INT_MUL * 10; }
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual bool signedFlavor() const override { return true; }
|
2014-04-05 21:44:49 +02:00
|
|
|
};
|
2020-11-19 03:32:16 +01:00
|
|
|
class AstPowSS final : public AstNodeBiop {
|
2014-09-12 03:28:53 +02:00
|
|
|
public:
|
2020-01-25 21:29:44 +01:00
|
|
|
AstPowSS(FileLine* fl, AstNode* lhsp, AstNode* rhsp)
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_PowSS(fl, lhsp, rhsp) {
|
2020-04-15 13:58:34 +02:00
|
|
|
dtypeFrom(lhsp);
|
|
|
|
|
}
|
2016-11-05 14:47:56 +01:00
|
|
|
ASTNODE_NODE_FUNCS(PowSS)
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual AstNode* cloneType(AstNode* lhsp, AstNode* rhsp) override {
|
2020-04-15 13:58:34 +02:00
|
|
|
return new AstPowSS(this->fileline(), lhsp, rhsp);
|
|
|
|
|
}
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) override {
|
2020-04-15 13:58:34 +02:00
|
|
|
out.opPowSS(lhs, rhs);
|
|
|
|
|
}
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual string emitVerilog() override { return "%k(%l %f** %r)"; }
|
|
|
|
|
virtual string emitC() override {
|
|
|
|
|
return "VL_POWSS_%nq%lq%rq(%nw,%lw,%rw, %P, %li, %ri, 1,1)";
|
|
|
|
|
}
|
|
|
|
|
virtual bool emitCheckMaxWords() override { return true; }
|
|
|
|
|
virtual bool cleanOut() const override { return false; }
|
|
|
|
|
virtual bool cleanLhs() const override { return true; }
|
|
|
|
|
virtual bool cleanRhs() const override { return true; }
|
|
|
|
|
virtual bool sizeMattersLhs() const override { return true; }
|
|
|
|
|
virtual bool sizeMattersRhs() const override { return false; }
|
2021-07-25 14:32:36 +02:00
|
|
|
virtual int instrCount() const override { return widthInstrs() * INSTR_COUNT_INT_MUL * 10; }
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual bool signedFlavor() const override { return true; }
|
2014-04-05 21:44:49 +02:00
|
|
|
};
|
2020-11-19 03:32:16 +01:00
|
|
|
class AstPowUS final : public AstNodeBiop {
|
2014-09-12 03:28:53 +02:00
|
|
|
public:
|
2020-01-25 21:29:44 +01:00
|
|
|
AstPowUS(FileLine* fl, AstNode* lhsp, AstNode* rhsp)
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_PowUS(fl, lhsp, rhsp) {
|
2020-04-15 13:58:34 +02:00
|
|
|
dtypeFrom(lhsp);
|
|
|
|
|
}
|
2016-11-05 14:47:56 +01:00
|
|
|
ASTNODE_NODE_FUNCS(PowUS)
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual AstNode* cloneType(AstNode* lhsp, AstNode* rhsp) override {
|
2020-04-15 13:58:34 +02:00
|
|
|
return new AstPowUS(this->fileline(), lhsp, rhsp);
|
|
|
|
|
}
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) override {
|
2020-04-15 13:58:34 +02:00
|
|
|
out.opPowUS(lhs, rhs);
|
|
|
|
|
}
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual string emitVerilog() override { return "%k(%l %f** %r)"; }
|
|
|
|
|
virtual string emitC() override {
|
|
|
|
|
return "VL_POWSS_%nq%lq%rq(%nw,%lw,%rw, %P, %li, %ri, 0,1)";
|
|
|
|
|
}
|
|
|
|
|
virtual bool emitCheckMaxWords() override { return true; }
|
|
|
|
|
virtual bool cleanOut() const override { return false; }
|
|
|
|
|
virtual bool cleanLhs() const override { return true; }
|
|
|
|
|
virtual bool cleanRhs() const override { return true; }
|
|
|
|
|
virtual bool sizeMattersLhs() const override { return true; }
|
|
|
|
|
virtual bool sizeMattersRhs() const override { return false; }
|
2021-07-25 14:32:36 +02:00
|
|
|
virtual int instrCount() const override { return widthInstrs() * INSTR_COUNT_INT_MUL * 10; }
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual bool signedFlavor() const override { return true; }
|
2006-08-26 13:35:28 +02:00
|
|
|
};
|
2020-11-19 03:32:16 +01:00
|
|
|
class AstPreAdd final : public AstNodeTriop {
|
2020-05-29 00:08:15 +02:00
|
|
|
// Pre-increment/add
|
|
|
|
|
// Parents: MATH
|
|
|
|
|
// Children: lhsp: AstConst (1) as currently support only ++ not +=
|
|
|
|
|
// Children: rhsp: tree with AstVarRef that is value to read before operation
|
|
|
|
|
// Children: thsp: tree with AstVarRef LValue that is stored after operation
|
|
|
|
|
public:
|
|
|
|
|
AstPreAdd(FileLine* fl, AstNode* lhsp, AstNode* rhsp, AstNode* thsp)
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_PreAdd(fl, lhsp, rhsp, thsp) {}
|
2020-05-29 00:08:15 +02:00
|
|
|
ASTNODE_NODE_FUNCS(PreAdd)
|
|
|
|
|
virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs,
|
2020-08-15 17:44:10 +02:00
|
|
|
const V3Number& ths) override {
|
2020-05-29 02:32:07 +02:00
|
|
|
V3ERROR_NA; // Need to modify lhs
|
2020-05-29 00:08:15 +02:00
|
|
|
}
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual string emitVerilog() override { return "%k(++%r)"; }
|
|
|
|
|
virtual string emitC() override { V3ERROR_NA_RETURN(""); }
|
|
|
|
|
virtual string emitSimpleOperator() override { V3ERROR_NA_RETURN(""); }
|
|
|
|
|
virtual bool cleanOut() const override { return false; }
|
|
|
|
|
virtual bool cleanLhs() const override { return false; }
|
|
|
|
|
virtual bool cleanRhs() const override { return false; }
|
|
|
|
|
virtual bool cleanThs() const override { return false; }
|
|
|
|
|
virtual bool sizeMattersLhs() const override { return true; }
|
|
|
|
|
virtual bool sizeMattersRhs() const override { return true; }
|
|
|
|
|
virtual bool sizeMattersThs() const override { return true; }
|
2020-05-29 00:08:15 +02:00
|
|
|
};
|
2020-11-19 03:32:16 +01:00
|
|
|
class AstPreSub final : public AstNodeTriop {
|
2020-05-29 00:08:15 +02:00
|
|
|
// Pre-decrement/subtract
|
|
|
|
|
// Parents: MATH
|
|
|
|
|
// Children: lhsp: AstConst (1) as currently support only -- not -=
|
|
|
|
|
// Children: rhsp: tree with AstVarRef that is value to read before operation
|
|
|
|
|
// Children: thsp: tree with AstVarRef LValue that is stored after operation
|
|
|
|
|
public:
|
|
|
|
|
AstPreSub(FileLine* fl, AstNode* lhsp, AstNode* rhsp, AstNode* thsp)
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_PreSub(fl, lhsp, rhsp, thsp) {}
|
2020-05-29 00:08:15 +02:00
|
|
|
ASTNODE_NODE_FUNCS(PreSub)
|
|
|
|
|
virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs,
|
2020-08-15 17:44:10 +02:00
|
|
|
const V3Number& ths) override {
|
2020-05-29 02:32:07 +02:00
|
|
|
V3ERROR_NA; // Need to modify lhs
|
2020-05-29 00:08:15 +02:00
|
|
|
}
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual string emitVerilog() override { return "%k(--%r)"; }
|
|
|
|
|
virtual string emitC() override { V3ERROR_NA_RETURN(""); }
|
|
|
|
|
virtual string emitSimpleOperator() override { V3ERROR_NA_RETURN(""); }
|
|
|
|
|
virtual bool cleanOut() const override { return false; }
|
|
|
|
|
virtual bool cleanLhs() const override { return false; }
|
|
|
|
|
virtual bool cleanRhs() const override { return false; }
|
|
|
|
|
virtual bool cleanThs() const override { return false; }
|
|
|
|
|
virtual bool sizeMattersLhs() const override { return true; }
|
|
|
|
|
virtual bool sizeMattersRhs() const override { return true; }
|
|
|
|
|
virtual bool sizeMattersThs() const override { return true; }
|
2020-05-29 00:08:15 +02:00
|
|
|
};
|
2020-11-19 03:32:16 +01:00
|
|
|
class AstPostAdd final : public AstNodeTriop {
|
2020-05-29 00:08:15 +02:00
|
|
|
// Post-increment/add
|
|
|
|
|
// Parents: MATH
|
|
|
|
|
// Children: lhsp: AstConst (1) as currently support only ++ not +=
|
|
|
|
|
// Children: rhsp: tree with AstVarRef that is value to read before operation
|
|
|
|
|
// Children: thsp: tree with AstVarRef LValue that is stored after operation
|
|
|
|
|
public:
|
|
|
|
|
AstPostAdd(FileLine* fl, AstNode* lhsp, AstNode* rhsp, AstNode* thsp)
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_PostAdd(fl, lhsp, rhsp, thsp) {}
|
2020-05-29 00:08:15 +02:00
|
|
|
ASTNODE_NODE_FUNCS(PostAdd)
|
|
|
|
|
virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs,
|
2020-08-15 17:44:10 +02:00
|
|
|
const V3Number& ths) override {
|
2020-05-29 02:32:07 +02:00
|
|
|
V3ERROR_NA; // Need to modify lhs
|
2020-05-29 00:08:15 +02:00
|
|
|
}
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual string emitVerilog() override { return "%k(%r++)"; }
|
|
|
|
|
virtual string emitC() override { V3ERROR_NA_RETURN(""); }
|
|
|
|
|
virtual string emitSimpleOperator() override { V3ERROR_NA_RETURN(""); }
|
|
|
|
|
virtual bool cleanOut() const override { return false; }
|
|
|
|
|
virtual bool cleanLhs() const override { return false; }
|
|
|
|
|
virtual bool cleanRhs() const override { return false; }
|
|
|
|
|
virtual bool cleanThs() const override { return false; }
|
|
|
|
|
virtual bool sizeMattersLhs() const override { return true; }
|
|
|
|
|
virtual bool sizeMattersRhs() const override { return true; }
|
|
|
|
|
virtual bool sizeMattersThs() const override { return true; }
|
2020-05-29 00:08:15 +02:00
|
|
|
};
|
2020-11-19 03:32:16 +01:00
|
|
|
class AstPostSub final : public AstNodeTriop {
|
2020-05-29 00:08:15 +02:00
|
|
|
// Post-decrement/subtract
|
|
|
|
|
// Parents: MATH
|
|
|
|
|
// Children: lhsp: AstConst (1) as currently support only -- not -=
|
|
|
|
|
// Children: rhsp: tree with AstVarRef that is value to read before operation
|
|
|
|
|
// Children: thsp: tree with AstVarRef LValue that is stored after operation
|
|
|
|
|
public:
|
|
|
|
|
AstPostSub(FileLine* fl, AstNode* lhsp, AstNode* rhsp, AstNode* thsp)
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_PostSub(fl, lhsp, rhsp, thsp) {}
|
2020-05-29 00:08:15 +02:00
|
|
|
ASTNODE_NODE_FUNCS(PostSub)
|
|
|
|
|
virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs,
|
2020-08-15 17:44:10 +02:00
|
|
|
const V3Number& ths) override {
|
2020-05-29 02:32:07 +02:00
|
|
|
V3ERROR_NA; // Need to modify lhs
|
2020-05-29 00:08:15 +02:00
|
|
|
}
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual string emitVerilog() override { return "%k(%r--)"; }
|
|
|
|
|
virtual string emitC() override { V3ERROR_NA_RETURN(""); }
|
|
|
|
|
virtual string emitSimpleOperator() override { V3ERROR_NA_RETURN(""); }
|
|
|
|
|
virtual bool cleanOut() const override { return false; }
|
|
|
|
|
virtual bool cleanLhs() const override { return false; }
|
|
|
|
|
virtual bool cleanRhs() const override { return false; }
|
|
|
|
|
virtual bool cleanThs() const override { return false; }
|
|
|
|
|
virtual bool sizeMattersLhs() const override { return true; }
|
|
|
|
|
virtual bool sizeMattersRhs() const override { return true; }
|
|
|
|
|
virtual bool sizeMattersThs() const override { return true; }
|
2020-05-29 00:08:15 +02:00
|
|
|
};
|
2020-11-19 03:32:16 +01:00
|
|
|
class AstEqCase final : public AstNodeBiCom {
|
2014-09-12 03:28:53 +02:00
|
|
|
public:
|
2020-01-25 21:29:44 +01:00
|
|
|
AstEqCase(FileLine* fl, AstNode* lhsp, AstNode* rhsp)
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_EqCase(fl, lhsp, rhsp) {
|
2020-11-29 14:23:36 +01:00
|
|
|
dtypeSetBit();
|
2020-04-15 13:58:34 +02:00
|
|
|
}
|
2016-11-05 14:47:56 +01:00
|
|
|
ASTNODE_NODE_FUNCS(EqCase)
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual AstNode* cloneType(AstNode* lhsp, AstNode* rhsp) override {
|
2020-04-15 13:58:34 +02:00
|
|
|
return new AstEqCase(this->fileline(), lhsp, rhsp);
|
|
|
|
|
}
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) override {
|
2020-04-15 13:58:34 +02:00
|
|
|
out.opCaseEq(lhs, rhs);
|
|
|
|
|
}
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual string emitVerilog() override { return "%k(%l %f=== %r)"; }
|
|
|
|
|
virtual string emitC() override { return "VL_EQ_%lq(%lW, %P, %li, %ri)"; }
|
|
|
|
|
virtual string emitSimpleOperator() override { return "=="; }
|
|
|
|
|
virtual bool cleanOut() const override { return true; }
|
|
|
|
|
virtual bool cleanLhs() const override { return true; }
|
|
|
|
|
virtual bool cleanRhs() const override { return true; }
|
|
|
|
|
virtual bool sizeMattersLhs() const override { return false; }
|
|
|
|
|
virtual bool sizeMattersRhs() const override { return false; }
|
2006-08-26 13:35:28 +02:00
|
|
|
};
|
2020-11-19 03:32:16 +01:00
|
|
|
class AstNeqCase final : public AstNodeBiCom {
|
2014-09-12 03:28:53 +02:00
|
|
|
public:
|
2020-01-25 21:29:44 +01:00
|
|
|
AstNeqCase(FileLine* fl, AstNode* lhsp, AstNode* rhsp)
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_NeqCase(fl, lhsp, rhsp) {
|
2020-11-29 14:23:36 +01:00
|
|
|
dtypeSetBit();
|
2020-04-15 13:58:34 +02:00
|
|
|
}
|
2016-11-05 14:47:56 +01:00
|
|
|
ASTNODE_NODE_FUNCS(NeqCase)
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual AstNode* cloneType(AstNode* lhsp, AstNode* rhsp) override {
|
2020-04-15 13:58:34 +02:00
|
|
|
return new AstNeqCase(this->fileline(), lhsp, rhsp);
|
|
|
|
|
}
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) override {
|
2020-04-15 13:58:34 +02:00
|
|
|
out.opCaseNeq(lhs, rhs);
|
|
|
|
|
}
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual string emitVerilog() override { return "%k(%l %f!== %r)"; }
|
|
|
|
|
virtual string emitC() override { return "VL_NEQ_%lq(%lW, %P, %li, %ri)"; }
|
|
|
|
|
virtual string emitSimpleOperator() override { return "!="; }
|
|
|
|
|
virtual bool cleanOut() const override { return true; }
|
|
|
|
|
virtual bool cleanLhs() const override { return true; }
|
|
|
|
|
virtual bool cleanRhs() const override { return true; }
|
|
|
|
|
virtual bool sizeMattersLhs() const override { return false; }
|
|
|
|
|
virtual bool sizeMattersRhs() const override { return false; }
|
2006-08-26 13:35:28 +02:00
|
|
|
};
|
2020-11-19 03:32:16 +01:00
|
|
|
class AstEqWild final : public AstNodeBiop {
|
2007-07-18 17:01:39 +02:00
|
|
|
// Note wildcard operator rhs differs from lhs
|
2014-09-12 03:28:53 +02:00
|
|
|
public:
|
2020-01-25 21:29:44 +01:00
|
|
|
AstEqWild(FileLine* fl, AstNode* lhsp, AstNode* rhsp)
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_EqWild(fl, lhsp, rhsp) {
|
2020-11-29 14:23:36 +01:00
|
|
|
dtypeSetBit();
|
2020-04-15 13:58:34 +02:00
|
|
|
}
|
2016-11-05 14:47:56 +01:00
|
|
|
ASTNODE_NODE_FUNCS(EqWild)
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual AstNode* cloneType(AstNode* lhsp, AstNode* rhsp) override {
|
2020-04-15 13:58:34 +02:00
|
|
|
return new AstEqWild(this->fileline(), lhsp, rhsp);
|
|
|
|
|
}
|
|
|
|
|
static AstNodeBiop* newTyped(FileLine* fl, AstNode* lhsp,
|
|
|
|
|
AstNode* rhsp); // Return AstEqWild/AstEqD
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) override {
|
2020-04-15 13:58:34 +02:00
|
|
|
out.opWildEq(lhs, rhs);
|
|
|
|
|
}
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual string emitVerilog() override { return "%k(%l %f==? %r)"; }
|
|
|
|
|
virtual string emitC() override { return "VL_EQ_%lq(%lW, %P, %li, %ri)"; }
|
|
|
|
|
virtual string emitSimpleOperator() override { return "=="; }
|
|
|
|
|
virtual bool cleanOut() const override { return true; }
|
|
|
|
|
virtual bool cleanLhs() const override { return true; }
|
|
|
|
|
virtual bool cleanRhs() const override { return true; }
|
|
|
|
|
virtual bool sizeMattersLhs() const override { return false; }
|
|
|
|
|
virtual bool sizeMattersRhs() const override { return false; }
|
2007-07-18 17:01:39 +02:00
|
|
|
};
|
2020-11-19 03:32:16 +01:00
|
|
|
class AstNeqWild final : public AstNodeBiop {
|
2014-09-12 03:28:53 +02:00
|
|
|
public:
|
2020-01-25 21:29:44 +01:00
|
|
|
AstNeqWild(FileLine* fl, AstNode* lhsp, AstNode* rhsp)
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_NeqWild(fl, lhsp, rhsp) {
|
2020-11-29 14:23:36 +01:00
|
|
|
dtypeSetBit();
|
2020-04-15 13:58:34 +02:00
|
|
|
}
|
2016-11-05 14:47:56 +01:00
|
|
|
ASTNODE_NODE_FUNCS(NeqWild)
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual AstNode* cloneType(AstNode* lhsp, AstNode* rhsp) override {
|
2020-04-15 13:58:34 +02:00
|
|
|
return new AstNeqWild(this->fileline(), lhsp, rhsp);
|
|
|
|
|
}
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) override {
|
2020-04-15 13:58:34 +02:00
|
|
|
out.opWildNeq(lhs, rhs);
|
|
|
|
|
}
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual string emitVerilog() override { return "%k(%l %f!=? %r)"; }
|
|
|
|
|
virtual string emitC() override { return "VL_NEQ_%lq(%lW, %P, %li, %ri)"; }
|
|
|
|
|
virtual string emitSimpleOperator() override { return "!="; }
|
|
|
|
|
virtual bool cleanOut() const override { return true; }
|
|
|
|
|
virtual bool cleanLhs() const override { return true; }
|
|
|
|
|
virtual bool cleanRhs() const override { return true; }
|
|
|
|
|
virtual bool sizeMattersLhs() const override { return false; }
|
|
|
|
|
virtual bool sizeMattersRhs() const override { return false; }
|
2007-07-18 17:01:39 +02:00
|
|
|
};
|
2020-11-19 03:32:16 +01:00
|
|
|
class AstConcat final : public AstNodeBiop {
|
2006-08-26 13:35:28 +02:00
|
|
|
// If you're looking for {#{}}, see AstReplicate
|
2014-09-12 03:28:53 +02:00
|
|
|
public:
|
2020-01-25 21:29:44 +01:00
|
|
|
AstConcat(FileLine* fl, AstNode* lhsp, AstNode* rhsp)
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_Concat(fl, lhsp, rhsp) {
|
2019-05-19 22:13:13 +02:00
|
|
|
if (lhsp->dtypep() && rhsp->dtypep()) {
|
2020-04-15 13:58:34 +02:00
|
|
|
dtypeSetLogicSized(lhsp->dtypep()->width() + rhsp->dtypep()->width(),
|
2020-04-20 03:19:09 +02:00
|
|
|
VSigning::UNSIGNED);
|
2019-05-19 22:13:13 +02:00
|
|
|
}
|
2006-08-26 13:35:28 +02:00
|
|
|
}
|
2016-11-05 14:47:56 +01:00
|
|
|
ASTNODE_NODE_FUNCS(Concat)
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual AstNode* cloneType(AstNode* lhsp, AstNode* rhsp) override {
|
2020-04-15 13:58:34 +02:00
|
|
|
return new AstConcat(this->fileline(), lhsp, rhsp);
|
|
|
|
|
}
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual string emitVerilog() override { return "%f{%l, %k%r}"; }
|
|
|
|
|
virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) override {
|
2020-04-15 13:58:34 +02:00
|
|
|
out.opConcat(lhs, rhs);
|
|
|
|
|
}
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual string emitC() override { return "VL_CONCAT_%nq%lq%rq(%nw,%lw,%rw, %P, %li, %ri)"; }
|
|
|
|
|
virtual bool cleanOut() const override { return true; }
|
|
|
|
|
virtual bool cleanLhs() const override { return true; }
|
|
|
|
|
virtual bool cleanRhs() const override { return true; }
|
|
|
|
|
virtual bool sizeMattersLhs() const override { return false; }
|
|
|
|
|
virtual bool sizeMattersRhs() const override { return false; }
|
|
|
|
|
virtual int instrCount() const override { return widthInstrs() * 2; }
|
2006-08-26 13:35:28 +02:00
|
|
|
};
|
2020-11-19 03:32:16 +01:00
|
|
|
class AstConcatN final : public AstNodeBiop {
|
2014-11-28 21:01:50 +01:00
|
|
|
// String concatenate
|
|
|
|
|
public:
|
2020-01-25 21:29:44 +01:00
|
|
|
AstConcatN(FileLine* fl, AstNode* lhsp, AstNode* rhsp)
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_ConcatN(fl, lhsp, rhsp) {
|
2020-04-15 13:58:34 +02:00
|
|
|
dtypeSetString();
|
|
|
|
|
}
|
2016-11-05 14:47:56 +01:00
|
|
|
ASTNODE_NODE_FUNCS(ConcatN)
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual AstNode* cloneType(AstNode* lhsp, AstNode* rhsp) override {
|
2020-04-15 13:58:34 +02:00
|
|
|
return new AstConcatN(this->fileline(), lhsp, rhsp);
|
|
|
|
|
}
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual string emitVerilog() override { return "%f{%l, %k%r}"; }
|
|
|
|
|
virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) override {
|
2020-04-15 13:58:34 +02:00
|
|
|
out.opConcatN(lhs, rhs);
|
|
|
|
|
}
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual string emitC() override { return "VL_CONCATN_NNN(%li, %ri)"; }
|
|
|
|
|
virtual bool cleanOut() const override { return true; }
|
|
|
|
|
virtual bool cleanLhs() const override { return true; }
|
|
|
|
|
virtual bool cleanRhs() const override { return true; }
|
|
|
|
|
virtual bool sizeMattersLhs() const override { return false; }
|
|
|
|
|
virtual bool sizeMattersRhs() const override { return false; }
|
2021-07-25 14:32:36 +02:00
|
|
|
virtual int instrCount() const override { return INSTR_COUNT_STR; }
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual bool stringFlavor() const override { return true; }
|
2014-11-28 21:01:50 +01:00
|
|
|
};
|
2020-11-19 03:32:16 +01:00
|
|
|
class AstReplicate final : public AstNodeBiop {
|
2014-05-04 02:20:15 +02:00
|
|
|
// Also used as a "Uniop" flavor of Concat, e.g. "{a}"
|
|
|
|
|
// Verilog {rhs{lhs}} - Note rhsp() is the replicate value, not the lhsp()
|
2014-04-10 23:54:52 +02:00
|
|
|
public:
|
|
|
|
|
AstReplicate(FileLine* fl, AstNode* lhsp, AstNode* rhsp)
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_Replicate(fl, lhsp, rhsp) {
|
2020-08-15 16:26:38 +02:00
|
|
|
if (lhsp) {
|
2021-11-26 23:55:36 +01:00
|
|
|
if (const AstConst* const constp = VN_CAST(rhsp, Const)) {
|
2020-08-15 16:26:38 +02:00
|
|
|
dtypeSetLogicSized(lhsp->width() * constp->toUInt(), VSigning::UNSIGNED);
|
|
|
|
|
}
|
|
|
|
|
}
|
2020-04-15 13:58:34 +02:00
|
|
|
}
|
2006-08-26 13:35:28 +02:00
|
|
|
AstReplicate(FileLine* fl, AstNode* lhsp, uint32_t repCount)
|
2020-08-15 16:26:38 +02:00
|
|
|
: AstReplicate(fl, lhsp, new AstConst(fl, repCount)) {}
|
2016-11-05 14:47:56 +01:00
|
|
|
ASTNODE_NODE_FUNCS(Replicate)
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual AstNode* cloneType(AstNode* lhsp, AstNode* rhsp) override {
|
2020-04-15 13:58:34 +02:00
|
|
|
return new AstReplicate(this->fileline(), lhsp, rhsp);
|
|
|
|
|
}
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) override {
|
2020-04-15 13:58:34 +02:00
|
|
|
out.opRepl(lhs, rhs);
|
|
|
|
|
}
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual string emitVerilog() override { return "%f{%r{%k%l}}"; }
|
2021-11-28 19:44:16 +01:00
|
|
|
virtual string emitC() override { return "VL_REPLICATE_%nq%lq%rq(%lw, %P, %li, %ri)"; }
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual bool cleanOut() const override { return false; }
|
|
|
|
|
virtual bool cleanLhs() const override { return true; }
|
|
|
|
|
virtual bool cleanRhs() const override { return true; }
|
|
|
|
|
virtual bool sizeMattersLhs() const override { return false; }
|
|
|
|
|
virtual bool sizeMattersRhs() const override { return false; }
|
|
|
|
|
virtual int instrCount() const override { return widthInstrs() * 2; }
|
2006-08-26 13:35:28 +02:00
|
|
|
};
|
2020-11-19 03:32:16 +01:00
|
|
|
class AstReplicateN final : public AstNodeBiop {
|
2014-11-28 21:01:50 +01:00
|
|
|
// String replicate
|
|
|
|
|
public:
|
|
|
|
|
AstReplicateN(FileLine* fl, AstNode* lhsp, AstNode* rhsp)
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_ReplicateN(fl, lhsp, rhsp) {
|
2020-08-15 16:26:38 +02:00
|
|
|
dtypeSetString();
|
2020-04-15 13:58:34 +02:00
|
|
|
}
|
2014-11-28 21:01:50 +01:00
|
|
|
AstReplicateN(FileLine* fl, AstNode* lhsp, uint32_t repCount)
|
2020-08-15 16:26:38 +02:00
|
|
|
: AstReplicateN(fl, lhsp, new AstConst(fl, repCount)) {}
|
2016-11-05 14:47:56 +01:00
|
|
|
ASTNODE_NODE_FUNCS(ReplicateN)
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual AstNode* cloneType(AstNode* lhsp, AstNode* rhsp) override {
|
2020-04-15 13:58:34 +02:00
|
|
|
return new AstReplicateN(this->fileline(), lhsp, rhsp);
|
|
|
|
|
}
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) override {
|
2020-04-15 13:58:34 +02:00
|
|
|
out.opReplN(lhs, rhs);
|
|
|
|
|
}
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual string emitVerilog() override { return "%f{%r{%k%l}}"; }
|
2021-11-28 19:44:16 +01:00
|
|
|
virtual string emitC() override { return "VL_REPLICATEN_NN%rq(%li, %ri)"; }
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual bool cleanOut() const override { return false; }
|
|
|
|
|
virtual bool cleanLhs() const override { return true; }
|
|
|
|
|
virtual bool cleanRhs() const override { return true; }
|
|
|
|
|
virtual bool sizeMattersLhs() const override { return false; }
|
|
|
|
|
virtual bool sizeMattersRhs() const override { return false; }
|
|
|
|
|
virtual int instrCount() const override { return widthInstrs() * 2; }
|
|
|
|
|
virtual bool stringFlavor() const override { return true; }
|
2014-11-28 21:01:50 +01:00
|
|
|
};
|
2020-11-19 03:32:16 +01:00
|
|
|
class AstStreamL final : public AstNodeStream {
|
2014-04-10 02:29:35 +02:00
|
|
|
// Verilog {rhs{lhs}} - Note rhsp() is the slice size, not the lhsp()
|
2014-09-12 03:28:53 +02:00
|
|
|
public:
|
2020-01-25 21:29:44 +01:00
|
|
|
AstStreamL(FileLine* fl, AstNode* lhsp, AstNode* rhsp)
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_StreamL(fl, lhsp, rhsp) {}
|
2016-11-05 14:47:56 +01:00
|
|
|
ASTNODE_NODE_FUNCS(StreamL)
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual AstNode* cloneType(AstNode* lhsp, AstNode* rhsp) override {
|
2020-04-15 13:58:34 +02:00
|
|
|
return new AstStreamL(this->fileline(), lhsp, rhsp);
|
|
|
|
|
}
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual string emitVerilog() override { return "%f{ << %r %k{%l} }"; }
|
|
|
|
|
virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) override {
|
2020-04-15 13:58:34 +02:00
|
|
|
out.opStreamL(lhs, rhs);
|
|
|
|
|
}
|
2021-11-28 19:44:16 +01:00
|
|
|
virtual string emitC() override { return "VL_STREAML_%nq%lq%rq(%lw, %P, %li, %ri)"; }
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual bool cleanOut() const override { return true; }
|
|
|
|
|
virtual bool cleanLhs() const override { return true; }
|
|
|
|
|
virtual bool cleanRhs() const override { return true; }
|
|
|
|
|
virtual bool sizeMattersLhs() const override { return true; }
|
|
|
|
|
virtual bool sizeMattersRhs() const override { return false; }
|
|
|
|
|
virtual int instrCount() const override { return widthInstrs() * 2; }
|
2014-04-10 02:29:35 +02:00
|
|
|
};
|
2020-11-19 03:32:16 +01:00
|
|
|
class AstStreamR final : public AstNodeStream {
|
2014-04-10 02:29:35 +02:00
|
|
|
// Verilog {rhs{lhs}} - Note rhsp() is the slice size, not the lhsp()
|
2014-09-12 03:28:53 +02:00
|
|
|
public:
|
2020-01-25 21:29:44 +01:00
|
|
|
AstStreamR(FileLine* fl, AstNode* lhsp, AstNode* rhsp)
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_StreamR(fl, lhsp, rhsp) {}
|
2016-11-05 14:47:56 +01:00
|
|
|
ASTNODE_NODE_FUNCS(StreamR)
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual AstNode* cloneType(AstNode* lhsp, AstNode* rhsp) override {
|
2020-04-15 13:58:34 +02:00
|
|
|
return new AstStreamR(this->fileline(), lhsp, rhsp);
|
|
|
|
|
}
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual string emitVerilog() override { return "%f{ >> %r %k{%l} }"; }
|
|
|
|
|
virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) override {
|
2020-04-15 13:58:34 +02:00
|
|
|
out.opAssign(lhs);
|
|
|
|
|
}
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual string emitC() override { return isWide() ? "VL_ASSIGN_W(%nw, %P, %li)" : "%li"; }
|
|
|
|
|
virtual bool cleanOut() const override { return false; }
|
|
|
|
|
virtual bool cleanLhs() const override { return false; }
|
|
|
|
|
virtual bool cleanRhs() const override { return false; }
|
|
|
|
|
virtual bool sizeMattersLhs() const override { return true; }
|
|
|
|
|
virtual bool sizeMattersRhs() const override { return false; }
|
|
|
|
|
virtual int instrCount() const override { return widthInstrs() * 2; }
|
2014-04-10 02:29:35 +02:00
|
|
|
};
|
2020-11-19 03:32:16 +01:00
|
|
|
class AstBufIf1 final : public AstNodeBiop {
|
2011-02-24 03:21:59 +01:00
|
|
|
// lhs is enable, rhs is data to drive
|
2019-05-19 22:13:13 +02:00
|
|
|
// Note unlike the Verilog bufif1() UDP, this allows any width; each lhsp
|
|
|
|
|
// bit enables respective rhsp bit
|
2014-09-12 03:28:53 +02:00
|
|
|
public:
|
2020-01-25 21:29:44 +01:00
|
|
|
AstBufIf1(FileLine* fl, AstNode* lhsp, AstNode* rhsp)
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_BufIf1(fl, lhsp, rhsp) {
|
2020-04-15 13:58:34 +02:00
|
|
|
dtypeFrom(lhsp);
|
|
|
|
|
}
|
2016-11-05 14:47:56 +01:00
|
|
|
ASTNODE_NODE_FUNCS(BufIf1)
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual AstNode* cloneType(AstNode* lhsp, AstNode* rhsp) override {
|
2020-04-15 13:58:34 +02:00
|
|
|
return new AstBufIf1(this->fileline(), lhsp, rhsp);
|
|
|
|
|
}
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) override {
|
2020-04-15 13:58:34 +02:00
|
|
|
out.opBufIf1(lhs, rhs);
|
|
|
|
|
}
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual string emitVerilog() override { return "bufif(%r,%l)"; }
|
|
|
|
|
virtual string emitC() override { V3ERROR_NA_RETURN(""); } // Lclean || Rclean
|
|
|
|
|
virtual string emitSimpleOperator() override { V3ERROR_NA_RETURN(""); } // Lclean || Rclean
|
|
|
|
|
virtual bool cleanOut() const override { V3ERROR_NA_RETURN(""); } // Lclean || Rclean
|
|
|
|
|
virtual bool cleanLhs() const override { return false; }
|
|
|
|
|
virtual bool cleanRhs() const override { return false; }
|
|
|
|
|
virtual bool sizeMattersLhs() const override { return false; }
|
|
|
|
|
virtual bool sizeMattersRhs() const override { return false; }
|
2011-02-24 03:21:59 +01:00
|
|
|
};
|
2020-11-19 03:32:16 +01:00
|
|
|
class AstFGetS final : public AstNodeBiop {
|
2014-09-12 03:28:53 +02:00
|
|
|
public:
|
2020-01-25 21:29:44 +01:00
|
|
|
AstFGetS(FileLine* fl, AstNode* lhsp, AstNode* rhsp)
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_FGetS(fl, lhsp, rhsp) {}
|
2016-11-05 14:47:56 +01:00
|
|
|
ASTNODE_NODE_FUNCS(FGetS)
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual AstNode* cloneType(AstNode* lhsp, AstNode* rhsp) override {
|
2020-04-15 13:58:34 +02:00
|
|
|
return new AstFGetS(this->fileline(), lhsp, rhsp);
|
|
|
|
|
}
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) override {
|
2020-04-15 13:58:34 +02:00
|
|
|
V3ERROR_NA;
|
|
|
|
|
}
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual string emitVerilog() override { return "%f$fgets(%l,%r)"; }
|
2020-10-28 00:37:12 +01:00
|
|
|
virtual string emitC() override {
|
|
|
|
|
return strgp()->dtypep()->basicp()->isString() ? "VL_FGETS_NI(%li, %ri)"
|
|
|
|
|
: "VL_FGETS_%nqX%rq(%lw, %P, &(%li), %ri)";
|
|
|
|
|
}
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual bool cleanOut() const override { return false; }
|
|
|
|
|
virtual bool cleanLhs() const override { return true; }
|
|
|
|
|
virtual bool cleanRhs() const override { return true; }
|
|
|
|
|
virtual bool sizeMattersLhs() const override { return false; }
|
|
|
|
|
virtual bool sizeMattersRhs() const override { return false; }
|
|
|
|
|
virtual int instrCount() const override { return widthInstrs() * 64; }
|
2019-05-19 22:13:13 +02:00
|
|
|
AstNode* strgp() const { return lhsp(); }
|
|
|
|
|
AstNode* filep() const { return rhsp(); }
|
2008-06-28 02:04:20 +02:00
|
|
|
};
|
2006-08-26 13:35:28 +02:00
|
|
|
|
2020-11-19 03:32:16 +01:00
|
|
|
class AstNodeSystemBiop VL_NOT_FINAL : public AstNodeBiop {
|
2018-02-26 10:25:07 +01:00
|
|
|
public:
|
2020-01-25 21:29:44 +01:00
|
|
|
AstNodeSystemBiop(AstType t, FileLine* fl, AstNode* lhsp, AstNode* rhsp)
|
2020-04-15 13:58:34 +02:00
|
|
|
: AstNodeBiop(t, fl, lhsp, rhsp) {
|
|
|
|
|
dtypeSetDouble();
|
|
|
|
|
}
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual bool cleanOut() const override { return false; }
|
|
|
|
|
virtual bool cleanLhs() const override { return false; }
|
|
|
|
|
virtual bool cleanRhs() const override { return false; }
|
|
|
|
|
virtual bool sizeMattersLhs() const override { return false; }
|
|
|
|
|
virtual bool sizeMattersRhs() const override { return false; }
|
2021-07-25 14:32:36 +02:00
|
|
|
virtual int instrCount() const override { return INSTR_COUNT_DBL_TRIG; }
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual bool doubleFlavor() const override { return true; }
|
2018-02-26 10:25:07 +01:00
|
|
|
};
|
|
|
|
|
|
2020-11-19 03:32:16 +01:00
|
|
|
class AstAtan2D final : public AstNodeSystemBiop {
|
2018-02-26 10:25:07 +01:00
|
|
|
public:
|
2020-01-25 21:29:44 +01:00
|
|
|
AstAtan2D(FileLine* fl, AstNode* lhsp, AstNode* rhsp)
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_Atan2D(fl, lhsp, rhsp) {}
|
2018-02-26 10:25:07 +01:00
|
|
|
ASTNODE_NODE_FUNCS(Atan2D)
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual AstNode* cloneType(AstNode* lhsp, AstNode* rhsp) override {
|
2020-04-15 13:58:34 +02:00
|
|
|
return new AstAtan2D(this->fileline(), lhsp, rhsp);
|
|
|
|
|
}
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) override {
|
2021-03-27 02:23:18 +01:00
|
|
|
out.setDouble(std::atan2(lhs.toDouble(), rhs.toDouble()));
|
2020-04-15 13:58:34 +02:00
|
|
|
}
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual string emitVerilog() override { return "%f$atan2(%l,%r)"; }
|
|
|
|
|
virtual string emitC() override { return "atan2(%li,%ri)"; }
|
2018-02-26 10:25:07 +01:00
|
|
|
};
|
|
|
|
|
|
2020-11-19 03:32:16 +01:00
|
|
|
class AstHypotD final : public AstNodeSystemBiop {
|
2018-02-26 10:25:07 +01:00
|
|
|
public:
|
2020-01-25 21:29:44 +01:00
|
|
|
AstHypotD(FileLine* fl, AstNode* lhsp, AstNode* rhsp)
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_HypotD(fl, lhsp, rhsp) {}
|
2018-02-26 10:25:07 +01:00
|
|
|
ASTNODE_NODE_FUNCS(HypotD)
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual AstNode* cloneType(AstNode* lhsp, AstNode* rhsp) override {
|
2020-04-15 13:58:34 +02:00
|
|
|
return new AstHypotD(this->fileline(), lhsp, rhsp);
|
|
|
|
|
}
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) override {
|
2021-03-27 02:23:18 +01:00
|
|
|
out.setDouble(std::hypot(lhs.toDouble(), rhs.toDouble()));
|
2020-04-15 13:58:34 +02:00
|
|
|
}
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual string emitVerilog() override { return "%f$hypot(%l,%r)"; }
|
|
|
|
|
virtual string emitC() override { return "hypot(%li,%ri)"; }
|
2018-02-26 10:25:07 +01:00
|
|
|
};
|
2019-12-15 14:09:52 +01:00
|
|
|
|
2020-11-19 03:32:16 +01:00
|
|
|
class AstPutcN final : public AstNodeTriop {
|
2019-12-15 14:09:52 +01:00
|
|
|
// Verilog string.putc()
|
|
|
|
|
public:
|
2020-01-25 21:29:44 +01:00
|
|
|
AstPutcN(FileLine* fl, AstNode* lhsp, AstNode* rhsp, AstNode* ths)
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_PutcN(fl, lhsp, rhsp, ths) {
|
2020-04-15 13:58:34 +02:00
|
|
|
dtypeSetString();
|
|
|
|
|
}
|
2019-12-15 14:09:52 +01:00
|
|
|
ASTNODE_NODE_FUNCS(PutcN)
|
2020-04-15 13:58:34 +02:00
|
|
|
virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs,
|
2020-08-15 17:44:10 +02:00
|
|
|
const V3Number& ths) override {
|
2019-12-15 14:09:52 +01:00
|
|
|
out.opPutcN(lhs, rhs, ths);
|
|
|
|
|
}
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual string name() const override { return "putc"; }
|
|
|
|
|
virtual string emitVerilog() override { return "%k(%l.putc(%r,%t))"; }
|
|
|
|
|
virtual string emitC() override { return "VL_PUTC_N(%li,%ri,%ti)"; }
|
|
|
|
|
virtual string emitSimpleOperator() override { return ""; }
|
|
|
|
|
virtual bool cleanOut() const override { return true; }
|
|
|
|
|
virtual bool cleanLhs() const override { return true; }
|
|
|
|
|
virtual bool cleanRhs() const override { return true; }
|
|
|
|
|
virtual bool cleanThs() const override { return true; }
|
|
|
|
|
virtual bool sizeMattersLhs() const override { return false; }
|
|
|
|
|
virtual bool sizeMattersRhs() const override { return false; }
|
|
|
|
|
virtual bool sizeMattersThs() const override { return false; }
|
2019-12-15 14:09:52 +01:00
|
|
|
};
|
|
|
|
|
|
2020-11-19 03:32:16 +01:00
|
|
|
class AstGetcN final : public AstNodeBiop {
|
2019-12-15 14:09:52 +01:00
|
|
|
// Verilog string.getc()
|
|
|
|
|
public:
|
2020-01-25 21:29:44 +01:00
|
|
|
AstGetcN(FileLine* fl, AstNode* lhsp, AstNode* rhsp)
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_GetcN(fl, lhsp, rhsp) {
|
2020-04-20 03:19:09 +02:00
|
|
|
dtypeSetBitSized(8, VSigning::UNSIGNED);
|
2020-04-15 13:58:34 +02:00
|
|
|
}
|
2019-12-15 14:09:52 +01:00
|
|
|
ASTNODE_NODE_FUNCS(GetcN)
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual AstNode* cloneType(AstNode* lhsp, AstNode* rhsp) override {
|
2019-12-15 14:09:52 +01:00
|
|
|
return new AstGetcN(this->fileline(), lhsp, rhsp);
|
|
|
|
|
}
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) override {
|
2019-12-15 14:09:52 +01:00
|
|
|
out.opGetcN(lhs, rhs);
|
|
|
|
|
}
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual string name() const override { return "getc"; }
|
|
|
|
|
virtual string emitVerilog() override { return "%k(%l.getc(%r))"; }
|
|
|
|
|
virtual string emitC() override { return "VL_GETC_N(%li,%ri)"; }
|
|
|
|
|
virtual string emitSimpleOperator() override { return ""; }
|
|
|
|
|
virtual bool cleanOut() const override { return true; }
|
|
|
|
|
virtual bool cleanLhs() const override { return true; }
|
|
|
|
|
virtual bool cleanRhs() const override { return true; }
|
|
|
|
|
virtual bool sizeMattersLhs() const override { return false; }
|
|
|
|
|
virtual bool sizeMattersRhs() const override { return false; }
|
2020-01-26 22:38:22 +01:00
|
|
|
};
|
|
|
|
|
|
2020-11-19 03:32:16 +01:00
|
|
|
class AstGetcRefN final : public AstNodeBiop {
|
2020-01-26 22:38:22 +01:00
|
|
|
// Verilog string[#] on the left-hand-side of assignment
|
|
|
|
|
// Spec says is of type byte (not string of single character)
|
|
|
|
|
public:
|
|
|
|
|
AstGetcRefN(FileLine* fl, AstNode* lhsp, AstNode* rhsp)
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_GetcRefN(fl, lhsp, rhsp) {
|
2020-04-20 03:19:09 +02:00
|
|
|
dtypeSetBitSized(8, VSigning::UNSIGNED);
|
2020-04-15 13:58:34 +02:00
|
|
|
}
|
2020-01-26 22:38:22 +01:00
|
|
|
ASTNODE_NODE_FUNCS(GetcRefN)
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual AstNode* cloneType(AstNode* lhsp, AstNode* rhsp) override {
|
2020-01-26 22:38:22 +01:00
|
|
|
return new AstGetcRefN(this->fileline(), lhsp, rhsp);
|
|
|
|
|
}
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) override {
|
2020-01-26 22:38:22 +01:00
|
|
|
V3ERROR_NA;
|
|
|
|
|
}
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual string emitVerilog() override { return "%k%l[%r]"; }
|
|
|
|
|
virtual string emitC() override { V3ERROR_NA_RETURN(""); }
|
|
|
|
|
virtual string emitSimpleOperator() override { return ""; }
|
|
|
|
|
virtual bool cleanOut() const override { return true; }
|
|
|
|
|
virtual bool cleanLhs() const override { return true; }
|
|
|
|
|
virtual bool cleanRhs() const override { return true; }
|
|
|
|
|
virtual bool sizeMattersLhs() const override { return false; }
|
|
|
|
|
virtual bool sizeMattersRhs() const override { return false; }
|
2019-12-15 14:09:52 +01:00
|
|
|
};
|
|
|
|
|
|
2020-11-19 03:32:16 +01:00
|
|
|
class AstSubstrN final : public AstNodeTriop {
|
2019-12-15 14:09:52 +01:00
|
|
|
// Verilog string.substr()
|
|
|
|
|
public:
|
2020-01-25 21:29:44 +01:00
|
|
|
AstSubstrN(FileLine* fl, AstNode* lhsp, AstNode* rhsp, AstNode* ths)
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_SubstrN(fl, lhsp, rhsp, ths) {
|
2020-04-15 13:58:34 +02:00
|
|
|
dtypeSetString();
|
|
|
|
|
}
|
2019-12-15 14:09:52 +01:00
|
|
|
ASTNODE_NODE_FUNCS(SubstrN)
|
2020-04-15 13:58:34 +02:00
|
|
|
virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs,
|
2020-08-15 17:44:10 +02:00
|
|
|
const V3Number& ths) override {
|
2019-12-15 14:09:52 +01:00
|
|
|
out.opSubstrN(lhs, rhs, ths);
|
|
|
|
|
}
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual string name() const override { return "substr"; }
|
|
|
|
|
virtual string emitVerilog() override { return "%k(%l.substr(%r,%t))"; }
|
|
|
|
|
virtual string emitC() override { return "VL_SUBSTR_N(%li,%ri,%ti)"; }
|
|
|
|
|
virtual string emitSimpleOperator() override { return ""; }
|
|
|
|
|
virtual bool cleanOut() const override { return true; }
|
|
|
|
|
virtual bool cleanLhs() const override { return true; }
|
|
|
|
|
virtual bool cleanRhs() const override { return true; }
|
|
|
|
|
virtual bool cleanThs() const override { return true; }
|
|
|
|
|
virtual bool sizeMattersLhs() const override { return false; }
|
|
|
|
|
virtual bool sizeMattersRhs() const override { return false; }
|
|
|
|
|
virtual bool sizeMattersThs() const override { return false; }
|
2019-12-15 14:09:52 +01:00
|
|
|
};
|
2018-02-26 10:25:07 +01:00
|
|
|
|
2020-11-19 03:32:16 +01:00
|
|
|
class AstCompareNN final : public AstNodeBiop {
|
2019-12-10 01:17:52 +01:00
|
|
|
// Verilog str.compare() and str.icompare()
|
|
|
|
|
private:
|
2021-11-26 23:55:36 +01:00
|
|
|
const bool m_ignoreCase; // True for str.icompare()
|
2019-12-10 01:17:52 +01:00
|
|
|
public:
|
|
|
|
|
AstCompareNN(FileLine* fl, AstNode* lhsp, AstNode* rhsp, bool ignoreCase)
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_CompareNN(fl, lhsp, rhsp)
|
2020-08-16 17:40:42 +02:00
|
|
|
, m_ignoreCase{ignoreCase} {
|
2019-12-10 01:17:52 +01:00
|
|
|
dtypeSetUInt32();
|
|
|
|
|
}
|
|
|
|
|
ASTNODE_NODE_FUNCS(CompareNN)
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual AstNode* cloneType(AstNode* lhsp, AstNode* rhsp) override {
|
2019-12-10 01:17:52 +01:00
|
|
|
return new AstCompareNN(this->fileline(), lhsp, rhsp, m_ignoreCase);
|
|
|
|
|
}
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) override {
|
2019-12-10 01:17:52 +01:00
|
|
|
out.opCompareNN(lhs, rhs, m_ignoreCase);
|
|
|
|
|
}
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual string name() const override { return m_ignoreCase ? "icompare" : "compare"; }
|
|
|
|
|
virtual string emitVerilog() override {
|
2019-12-10 01:17:52 +01:00
|
|
|
return m_ignoreCase ? "%k(%l.icompare(%r))" : "%k(%l.compare(%r))";
|
|
|
|
|
}
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual string emitC() override {
|
2019-12-10 01:17:52 +01:00
|
|
|
return m_ignoreCase ? "VL_CMP_NN(%li,%ri,true)" : "VL_CMP_NN(%li,%ri,false)";
|
|
|
|
|
}
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual string emitSimpleOperator() override { return ""; }
|
|
|
|
|
virtual bool cleanOut() const override { return true; }
|
|
|
|
|
virtual bool cleanLhs() const override { return true; }
|
|
|
|
|
virtual bool cleanRhs() const override { return true; }
|
|
|
|
|
virtual bool sizeMattersLhs() const override { return false; }
|
|
|
|
|
virtual bool sizeMattersRhs() const override { return false; }
|
2019-12-10 01:17:52 +01:00
|
|
|
};
|
|
|
|
|
|
2020-11-19 03:32:16 +01:00
|
|
|
class AstFell final : public AstNodeMath {
|
2020-08-14 13:37:10 +02:00
|
|
|
// Verilog $fell
|
|
|
|
|
// Parents: math
|
|
|
|
|
// Children: expression
|
|
|
|
|
public:
|
|
|
|
|
AstFell(FileLine* fl, AstNode* exprp)
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_Fell(fl) {
|
2020-08-14 13:37:10 +02:00
|
|
|
addOp1p(exprp);
|
|
|
|
|
}
|
|
|
|
|
ASTNODE_NODE_FUNCS(Fell)
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual string emitVerilog() override { return "$fell(%l)"; }
|
|
|
|
|
virtual string emitC() override { V3ERROR_NA_RETURN(""); }
|
|
|
|
|
virtual string emitSimpleOperator() override { V3ERROR_NA_RETURN(""); }
|
|
|
|
|
virtual bool cleanOut() const override { V3ERROR_NA_RETURN(""); }
|
|
|
|
|
virtual int instrCount() const override { return widthInstrs(); }
|
2020-08-14 13:37:10 +02:00
|
|
|
AstNode* exprp() const { return op1p(); } // op1 = expression
|
2021-10-22 14:56:48 +02:00
|
|
|
AstSenTree* sentreep() const { return VN_AS(op2p(), SenTree); } // op2 = clock domain
|
2020-08-14 13:37:10 +02:00
|
|
|
void sentreep(AstSenTree* sentreep) { addOp2p(sentreep); } // op2 = clock domain
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual bool same(const AstNode* samep) const override { return true; }
|
2020-08-14 13:37:10 +02:00
|
|
|
};
|
|
|
|
|
|
2020-11-19 03:32:16 +01:00
|
|
|
class AstPast final : public AstNodeMath {
|
2018-09-23 21:09:47 +02:00
|
|
|
// Verilog $past
|
|
|
|
|
// Parents: math
|
|
|
|
|
// Children: expression
|
|
|
|
|
public:
|
2020-01-25 21:29:44 +01:00
|
|
|
AstPast(FileLine* fl, AstNode* exprp, AstNode* ticksp)
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_Past(fl) {
|
2020-04-15 13:58:34 +02:00
|
|
|
addOp1p(exprp);
|
|
|
|
|
addNOp2p(ticksp);
|
|
|
|
|
}
|
2018-09-23 21:09:47 +02:00
|
|
|
ASTNODE_NODE_FUNCS(Past)
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual string emitVerilog() override { V3ERROR_NA_RETURN(""); }
|
|
|
|
|
virtual string emitC() override { V3ERROR_NA_RETURN(""); }
|
|
|
|
|
virtual string emitSimpleOperator() override { V3ERROR_NA_RETURN(""); }
|
|
|
|
|
virtual bool cleanOut() const override { V3ERROR_NA_RETURN(""); }
|
|
|
|
|
virtual int instrCount() const override { return widthInstrs(); }
|
2018-09-23 21:09:47 +02:00
|
|
|
AstNode* exprp() const { return op1p(); } // op1 = expression
|
2020-08-15 16:12:55 +02:00
|
|
|
AstNode* ticksp() const { return op2p(); } // op2 = ticks or nullptr means 1
|
2021-10-22 14:56:48 +02:00
|
|
|
AstSenTree* sentreep() const { return VN_AS(op4p(), SenTree); } // op4 = clock domain
|
2018-09-23 21:09:47 +02:00
|
|
|
void sentreep(AstSenTree* sentreep) { addOp4p(sentreep); } // op4 = clock domain
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual bool same(const AstNode* samep) const override { return true; }
|
2018-09-23 21:09:47 +02:00
|
|
|
};
|
|
|
|
|
|
2020-11-19 03:32:16 +01:00
|
|
|
class AstRose final : public AstNodeMath {
|
2020-08-14 13:37:10 +02:00
|
|
|
// Verilog $rose
|
|
|
|
|
// Parents: math
|
|
|
|
|
// Children: expression
|
|
|
|
|
public:
|
|
|
|
|
AstRose(FileLine* fl, AstNode* exprp)
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_Rose(fl) {
|
2020-08-14 13:37:10 +02:00
|
|
|
addOp1p(exprp);
|
|
|
|
|
}
|
|
|
|
|
ASTNODE_NODE_FUNCS(Rose)
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual string emitVerilog() override { return "$rose(%l)"; }
|
|
|
|
|
virtual string emitC() override { V3ERROR_NA_RETURN(""); }
|
|
|
|
|
virtual string emitSimpleOperator() override { V3ERROR_NA_RETURN(""); }
|
|
|
|
|
virtual bool cleanOut() const override { V3ERROR_NA_RETURN(""); }
|
|
|
|
|
virtual int instrCount() const override { return widthInstrs(); }
|
2020-08-14 13:37:10 +02:00
|
|
|
AstNode* exprp() const { return op1p(); } // op1 = expression
|
2021-10-22 14:56:48 +02:00
|
|
|
AstSenTree* sentreep() const { return VN_AS(op2p(), SenTree); } // op2 = clock domain
|
2020-08-14 13:37:10 +02:00
|
|
|
void sentreep(AstSenTree* sentreep) { addOp2p(sentreep); } // op2 = clock domain
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual bool same(const AstNode* samep) const override { return true; }
|
2020-08-14 13:37:10 +02:00
|
|
|
};
|
|
|
|
|
|
2020-11-19 03:32:16 +01:00
|
|
|
class AstSampled final : public AstNodeMath {
|
2020-01-26 19:38:15 +01:00
|
|
|
// Verilog $sampled
|
|
|
|
|
// Parents: math
|
|
|
|
|
// Children: expression
|
|
|
|
|
public:
|
|
|
|
|
AstSampled(FileLine* fl, AstNode* exprp)
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_Sampled(fl) {
|
2020-04-15 13:58:34 +02:00
|
|
|
addOp1p(exprp);
|
|
|
|
|
}
|
2020-01-26 19:38:15 +01:00
|
|
|
ASTNODE_NODE_FUNCS(Sampled)
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual string emitVerilog() override { return "$sampled(%l)"; }
|
|
|
|
|
virtual string emitC() override { V3ERROR_NA_RETURN(""); }
|
|
|
|
|
virtual string emitSimpleOperator() override { V3ERROR_NA_RETURN(""); }
|
|
|
|
|
virtual bool cleanOut() const override { V3ERROR_NA_RETURN(""); }
|
|
|
|
|
virtual int instrCount() const override { return 0; }
|
2020-01-26 19:38:15 +01:00
|
|
|
AstNode* exprp() const { return op1p(); } // op1 = expression
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual bool same(const AstNode* samep) const override { return true; }
|
2020-01-26 19:38:15 +01:00
|
|
|
};
|
|
|
|
|
|
2020-11-19 03:32:16 +01:00
|
|
|
class AstStable final : public AstNodeMath {
|
2020-07-29 00:26:24 +02:00
|
|
|
// Verilog $stable
|
|
|
|
|
// Parents: math
|
|
|
|
|
// Children: expression
|
|
|
|
|
public:
|
|
|
|
|
AstStable(FileLine* fl, AstNode* exprp)
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_Stable(fl) {
|
2020-07-29 00:26:24 +02:00
|
|
|
addOp1p(exprp);
|
|
|
|
|
}
|
|
|
|
|
ASTNODE_NODE_FUNCS(Stable)
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual string emitVerilog() override { return "$stable(%l)"; }
|
|
|
|
|
virtual string emitC() override { V3ERROR_NA_RETURN(""); }
|
|
|
|
|
virtual string emitSimpleOperator() override { V3ERROR_NA_RETURN(""); }
|
|
|
|
|
virtual bool cleanOut() const override { V3ERROR_NA_RETURN(""); }
|
|
|
|
|
virtual int instrCount() const override { return widthInstrs(); }
|
2020-07-29 00:26:24 +02:00
|
|
|
AstNode* exprp() const { return op1p(); } // op1 = expression
|
2021-10-22 14:56:48 +02:00
|
|
|
AstSenTree* sentreep() const { return VN_AS(op2p(), SenTree); } // op2 = clock domain
|
2020-07-29 00:26:24 +02:00
|
|
|
void sentreep(AstSenTree* sentreep) { addOp2p(sentreep); } // op2 = clock domain
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual bool same(const AstNode* samep) const override { return true; }
|
2020-07-29 00:26:24 +02:00
|
|
|
};
|
|
|
|
|
|
2020-11-19 03:32:16 +01:00
|
|
|
class AstPattern final : public AstNodeMath {
|
2012-08-12 21:15:21 +02:00
|
|
|
// Verilog '{a,b,c,d...}
|
|
|
|
|
// Parents: AstNodeAssign, AstPattern, ...
|
|
|
|
|
// Children: expression, AstPattern, AstPatReplicate
|
2014-09-12 03:28:53 +02:00
|
|
|
public:
|
2020-01-25 21:29:44 +01:00
|
|
|
AstPattern(FileLine* fl, AstNode* itemsp)
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_Pattern(fl) {
|
2020-04-15 13:58:34 +02:00
|
|
|
addNOp2p(itemsp);
|
|
|
|
|
}
|
2016-11-05 14:47:56 +01:00
|
|
|
ASTNODE_NODE_FUNCS(Pattern)
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual string emitVerilog() override { V3ERROR_NA_RETURN(""); }
|
|
|
|
|
virtual string emitC() override { V3ERROR_NA_RETURN(""); }
|
|
|
|
|
virtual string emitSimpleOperator() override { V3ERROR_NA_RETURN(""); }
|
|
|
|
|
virtual bool cleanOut() const override { V3ERROR_NA_RETURN(""); }
|
|
|
|
|
virtual int instrCount() const override { return widthInstrs(); }
|
|
|
|
|
virtual AstNodeDType* getChildDTypep() const override { return childDTypep(); }
|
2017-11-10 00:04:16 +01:00
|
|
|
virtual AstNodeDType* subDTypep() const { return dtypep() ? dtypep() : childDTypep(); }
|
2020-05-24 03:57:08 +02:00
|
|
|
// op1 = Type assigning to
|
2021-10-22 14:56:48 +02:00
|
|
|
AstNodeDType* childDTypep() const { return VN_AS(op1p(), NodeDType); }
|
2020-05-24 03:57:08 +02:00
|
|
|
void childDTypep(AstNodeDType* nodep) { setOp1p(nodep); }
|
2019-05-19 22:13:13 +02:00
|
|
|
AstNode* itemsp() const { return op2p(); } // op2 = AstPatReplicate, AstPatMember, etc
|
2012-08-12 21:15:21 +02:00
|
|
|
};
|
2020-11-19 03:32:16 +01:00
|
|
|
class AstPatMember final : public AstNodeMath {
|
2012-08-12 21:15:21 +02:00
|
|
|
// Verilog '{a} or '{a{b}}
|
|
|
|
|
// Parents: AstPattern
|
|
|
|
|
// Children: expression, AstPattern, replication count
|
|
|
|
|
private:
|
2020-08-16 17:40:42 +02:00
|
|
|
bool m_default = false;
|
2020-04-15 13:58:34 +02:00
|
|
|
|
2012-08-12 21:15:21 +02:00
|
|
|
public:
|
2020-01-25 21:29:44 +01:00
|
|
|
AstPatMember(FileLine* fl, AstNode* lhsp, AstNode* keyp, AstNode* repp)
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_PatMember(fl) {
|
2020-04-15 13:58:34 +02:00
|
|
|
addOp1p(lhsp), setNOp2p(keyp), setNOp3p(repp);
|
|
|
|
|
}
|
2016-11-05 14:47:56 +01:00
|
|
|
ASTNODE_NODE_FUNCS(PatMember)
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual string emitVerilog() override { return lhssp() ? "%f{%r{%k%l}}" : "%l"; }
|
|
|
|
|
virtual string emitC() override { V3ERROR_NA_RETURN(""); }
|
|
|
|
|
virtual string emitSimpleOperator() override { V3ERROR_NA_RETURN(""); }
|
|
|
|
|
virtual bool cleanOut() const override { V3ERROR_NA_RETURN(""); }
|
|
|
|
|
virtual int instrCount() const override { return widthInstrs() * 2; }
|
2020-11-07 17:56:24 +01:00
|
|
|
virtual void dump(std::ostream& str = std::cout) const override;
|
2020-04-15 13:58:34 +02:00
|
|
|
// op1 = expression to assign or another AstPattern (list if replicated)
|
|
|
|
|
AstNode* lhssp() const { return op1p(); }
|
2019-05-19 22:13:13 +02:00
|
|
|
AstNode* keyp() const { return op2p(); } // op2 = assignment key (Const, id Text)
|
2020-08-15 16:12:55 +02:00
|
|
|
AstNode* repp() const { return op3p(); } // op3 = replication count, or nullptr for count 1
|
2012-08-12 21:15:21 +02:00
|
|
|
bool isDefault() const { return m_default; }
|
|
|
|
|
void isDefault(bool flag) { m_default = flag; }
|
|
|
|
|
};
|
|
|
|
|
|
2020-11-19 03:32:16 +01:00
|
|
|
class AstImplication final : public AstNodeMath {
|
2020-09-10 12:49:04 +02:00
|
|
|
// Verilog |-> |=>
|
|
|
|
|
// Parents: math
|
|
|
|
|
// Children: expression
|
|
|
|
|
public:
|
|
|
|
|
AstImplication(FileLine* fl, AstNode* lhs, AstNode* rhs)
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_Implication(fl) {
|
2020-09-10 12:49:04 +02:00
|
|
|
setOp1p(lhs);
|
|
|
|
|
setOp2p(rhs);
|
|
|
|
|
}
|
|
|
|
|
ASTNODE_NODE_FUNCS(Implication)
|
|
|
|
|
virtual string emitVerilog() override { V3ERROR_NA_RETURN(""); }
|
|
|
|
|
virtual string emitC() override { V3ERROR_NA_RETURN(""); }
|
|
|
|
|
virtual string emitSimpleOperator() override { V3ERROR_NA_RETURN(""); }
|
|
|
|
|
virtual bool cleanOut() const override { V3ERROR_NA_RETURN(""); }
|
|
|
|
|
virtual int instrCount() const override { return widthInstrs(); }
|
|
|
|
|
AstNode* lhsp() const { return op1p(); }
|
|
|
|
|
AstNode* rhsp() const { return op2p(); }
|
|
|
|
|
void lhsp(AstNode* nodep) { return setOp1p(nodep); }
|
|
|
|
|
void rhsp(AstNode* nodep) { return setOp2p(nodep); }
|
2021-10-22 14:56:48 +02:00
|
|
|
AstSenTree* sentreep() const { return VN_AS(op4p(), SenTree); } // op4 = clock domain
|
2020-09-10 12:49:04 +02:00
|
|
|
void sentreep(AstSenTree* sentreep) { addOp4p(sentreep); } // op4 = clock domain
|
|
|
|
|
virtual bool same(const AstNode* samep) const override { return true; }
|
|
|
|
|
};
|
|
|
|
|
|
2008-08-06 18:52:39 +02:00
|
|
|
//======================================================================
|
|
|
|
|
// Assertions
|
|
|
|
|
|
2020-11-19 03:32:16 +01:00
|
|
|
class AstClocking final : public AstNode {
|
2008-08-06 18:52:39 +02:00
|
|
|
// Set default clock region
|
|
|
|
|
// Parents: MODULE
|
|
|
|
|
// Children: Assertions
|
2014-09-12 03:28:53 +02:00
|
|
|
public:
|
2020-07-05 19:13:03 +02:00
|
|
|
AstClocking(FileLine* fl, AstSenItem* sensesp, AstNode* bodysp)
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_Clocking(fl) {
|
2019-05-19 22:13:13 +02:00
|
|
|
addOp1p(sensesp);
|
|
|
|
|
addNOp2p(bodysp);
|
2008-08-06 18:52:39 +02:00
|
|
|
}
|
2016-11-05 14:47:56 +01:00
|
|
|
ASTNODE_NODE_FUNCS(Clocking)
|
2020-04-15 13:58:34 +02:00
|
|
|
// op1 = Sensitivity list
|
2021-10-22 14:56:48 +02:00
|
|
|
AstSenItem* sensesp() const { return VN_AS(op1p(), SenItem); }
|
2019-05-19 22:13:13 +02:00
|
|
|
AstNode* bodysp() const { return op2p(); } // op2 = Body
|
2008-08-06 18:52:39 +02:00
|
|
|
};
|
|
|
|
|
|
2006-08-26 13:35:28 +02:00
|
|
|
//======================================================================
|
|
|
|
|
// PSL
|
|
|
|
|
|
2020-11-19 03:32:16 +01:00
|
|
|
class AstPropClocked final : public AstNode {
|
2006-08-26 13:35:28 +02:00
|
|
|
// A clocked property
|
|
|
|
|
// Parents: ASSERT|COVER (property)
|
|
|
|
|
// Children: SENITEM, Properties
|
2014-09-12 03:28:53 +02:00
|
|
|
public:
|
2020-07-05 19:13:03 +02:00
|
|
|
AstPropClocked(FileLine* fl, AstSenItem* sensesp, AstNode* disablep, AstNode* propp)
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_PropClocked(fl) {
|
2019-05-19 22:13:13 +02:00
|
|
|
addNOp1p(sensesp);
|
|
|
|
|
addNOp2p(disablep);
|
|
|
|
|
addOp3p(propp);
|
2006-08-26 13:35:28 +02:00
|
|
|
}
|
2019-12-17 03:43:52 +01:00
|
|
|
ASTNODE_NODE_FUNCS(PropClocked)
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual bool hasDType() const override {
|
|
|
|
|
return true;
|
|
|
|
|
} // Used under Cover, which expects a bool child
|
2021-10-22 14:56:48 +02:00
|
|
|
AstSenItem* sensesp() const { return VN_AS(op1p(), SenItem); } // op1 = Sensitivity list
|
2019-05-19 22:13:13 +02:00
|
|
|
AstNode* disablep() const { return op2p(); } // op2 = disable
|
|
|
|
|
AstNode* propp() const { return op3p(); } // op3 = property
|
2006-08-26 13:35:28 +02:00
|
|
|
};
|
|
|
|
|
|
2020-11-19 03:32:16 +01:00
|
|
|
class AstNodeCoverOrAssert VL_NOT_FINAL : public AstNodeStmt {
|
2019-12-17 03:43:52 +01:00
|
|
|
// Cover or Assert
|
2006-08-26 13:35:28 +02:00
|
|
|
// Parents: {statement list}
|
|
|
|
|
// Children: expression, report string
|
|
|
|
|
private:
|
2021-11-26 23:55:36 +01:00
|
|
|
const bool m_immediate; // Immediate assertion/cover
|
2019-05-19 22:13:13 +02:00
|
|
|
string m_name; // Name to report
|
2006-08-26 13:35:28 +02:00
|
|
|
public:
|
2020-04-15 13:58:34 +02:00
|
|
|
AstNodeCoverOrAssert(AstType t, FileLine* fl, AstNode* propp, AstNode* passsp, bool immediate,
|
|
|
|
|
const string& name = "")
|
2021-07-12 00:42:01 +02:00
|
|
|
: AstNodeStmt{t, fl}
|
|
|
|
|
, m_immediate{immediate}
|
|
|
|
|
, m_name{name} {
|
2019-05-19 22:13:13 +02:00
|
|
|
addOp1p(propp);
|
2019-12-17 03:43:52 +01:00
|
|
|
addNOp4p(passsp);
|
2006-08-26 13:35:28 +02:00
|
|
|
}
|
2019-12-17 03:43:52 +01:00
|
|
|
ASTNODE_BASE_FUNCS(NodeCoverOrAssert)
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual string name() const override { return m_name; } // * = Var name
|
|
|
|
|
virtual bool same(const AstNode* samep) const override { return samep->name() == name(); }
|
|
|
|
|
virtual void name(const string& name) override { m_name = name; }
|
|
|
|
|
virtual void dump(std::ostream& str = std::cout) const override;
|
2018-03-11 15:37:20 +01:00
|
|
|
AstNode* propp() const { return op1p(); } // op1 = property
|
2021-10-22 14:56:48 +02:00
|
|
|
AstSenTree* sentreep() const { return VN_AS(op2p(), SenTree); } // op2 = clock domain
|
2018-03-11 15:37:20 +01:00
|
|
|
void sentreep(AstSenTree* sentreep) { addOp2p(sentreep); } // op2 = clock domain
|
2019-12-17 03:43:52 +01:00
|
|
|
AstNode* passsp() const { return op4p(); } // op4 = statements (assert/cover passes)
|
|
|
|
|
bool immediate() const { return m_immediate; }
|
2018-03-11 15:37:20 +01:00
|
|
|
};
|
|
|
|
|
|
2020-11-19 03:32:16 +01:00
|
|
|
class AstAssert final : public AstNodeCoverOrAssert {
|
2018-09-23 21:20:12 +02:00
|
|
|
public:
|
2019-12-17 03:43:52 +01:00
|
|
|
ASTNODE_NODE_FUNCS(Assert)
|
2020-04-15 13:58:34 +02:00
|
|
|
AstAssert(FileLine* fl, AstNode* propp, AstNode* passsp, AstNode* failsp, bool immediate,
|
|
|
|
|
const string& name = "")
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_Assert(fl, propp, passsp, immediate, name) {
|
2019-12-17 03:43:52 +01:00
|
|
|
addNOp3p(failsp);
|
|
|
|
|
}
|
|
|
|
|
AstNode* failsp() const { return op3p(); } // op3 = if assertion fails
|
2018-09-23 21:20:12 +02:00
|
|
|
};
|
|
|
|
|
|
2020-12-06 04:58:36 +01:00
|
|
|
class AstAssertIntrinsic final : public AstNodeCoverOrAssert {
|
|
|
|
|
// A $cast or other compiler inserted assert, that must run even without --assert option
|
|
|
|
|
public:
|
|
|
|
|
ASTNODE_NODE_FUNCS(AssertIntrinsic)
|
|
|
|
|
AstAssertIntrinsic(FileLine* fl, AstNode* propp, AstNode* passsp, AstNode* failsp,
|
|
|
|
|
bool immediate, const string& name = "")
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_AssertIntrinsic(fl, propp, passsp, immediate, name) {
|
2020-12-06 04:58:36 +01:00
|
|
|
addNOp3p(failsp);
|
|
|
|
|
}
|
|
|
|
|
AstNode* failsp() const { return op3p(); } // op3 = if assertion fails
|
|
|
|
|
};
|
|
|
|
|
|
2020-11-19 03:32:16 +01:00
|
|
|
class AstCover final : public AstNodeCoverOrAssert {
|
2018-03-11 15:37:20 +01:00
|
|
|
public:
|
2019-12-17 03:43:52 +01:00
|
|
|
ASTNODE_NODE_FUNCS(Cover)
|
2020-04-15 13:58:34 +02:00
|
|
|
AstCover(FileLine* fl, AstNode* propp, AstNode* stmtsp, bool immediate,
|
|
|
|
|
const string& name = "")
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_Cover(fl, propp, stmtsp, immediate, name) {}
|
2018-03-11 15:37:20 +01:00
|
|
|
AstNode* coverincp() const { return op3p(); } // op3 = coverage node
|
|
|
|
|
void coverincp(AstCoverInc* nodep) { addOp3p(nodep); } // op3 = coverage node
|
2019-12-17 03:43:52 +01:00
|
|
|
virtual bool immediate() const { return false; }
|
2018-03-11 15:37:20 +01:00
|
|
|
};
|
|
|
|
|
|
2020-11-19 03:32:16 +01:00
|
|
|
class AstRestrict final : public AstNodeCoverOrAssert {
|
2018-03-11 15:37:20 +01:00
|
|
|
public:
|
2019-12-17 03:43:52 +01:00
|
|
|
ASTNODE_NODE_FUNCS(Restrict)
|
|
|
|
|
AstRestrict(FileLine* fl, AstNode* propp)
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_Restrict(fl, propp, nullptr, false, "") {}
|
2006-08-26 13:35:28 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
//======================================================================
|
|
|
|
|
// Text based nodes
|
|
|
|
|
|
2020-11-19 03:32:16 +01:00
|
|
|
class AstNodeSimpleText VL_NOT_FINAL : public AstNodeText {
|
2009-12-03 01:32:41 +01:00
|
|
|
private:
|
2019-05-19 22:13:13 +02:00
|
|
|
bool m_tracking; // When emit, it's ok to parse the string to do indentation
|
2009-12-03 01:32:41 +01:00
|
|
|
public:
|
2020-04-15 13:58:34 +02:00
|
|
|
AstNodeSimpleText(AstType t, FileLine* fl, const string& textp, bool tracking = false)
|
|
|
|
|
: AstNodeText(t, fl, textp)
|
|
|
|
|
, m_tracking(tracking) {}
|
2020-01-22 01:54:14 +01:00
|
|
|
ASTNODE_BASE_FUNCS(NodeSimpleText)
|
2009-12-03 01:32:41 +01:00
|
|
|
void tracking(bool flag) { m_tracking = flag; }
|
|
|
|
|
bool tracking() const { return m_tracking; }
|
2006-08-26 13:35:28 +02:00
|
|
|
};
|
|
|
|
|
|
2020-11-19 03:32:16 +01:00
|
|
|
class AstText final : public AstNodeSimpleText {
|
2020-01-22 01:54:14 +01:00
|
|
|
public:
|
2020-04-15 13:58:34 +02:00
|
|
|
AstText(FileLine* fl, const string& textp, bool tracking = false)
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_Text(fl, textp, tracking) {}
|
2020-01-22 01:54:14 +01:00
|
|
|
ASTNODE_NODE_FUNCS(Text)
|
|
|
|
|
};
|
|
|
|
|
|
2020-11-19 03:32:16 +01:00
|
|
|
class AstTextBlock final : public AstNodeSimpleText {
|
2019-09-27 09:44:23 +02:00
|
|
|
private:
|
|
|
|
|
bool m_commas; // Comma separate emitted children
|
|
|
|
|
public:
|
2020-02-04 05:21:56 +01:00
|
|
|
explicit AstTextBlock(FileLine* fl, const string& textp = "", bool tracking = false,
|
|
|
|
|
bool commas = false)
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_TextBlock(fl, textp, tracking)
|
2020-02-04 05:21:56 +01:00
|
|
|
, m_commas(commas) {}
|
2019-09-27 09:44:23 +02:00
|
|
|
ASTNODE_NODE_FUNCS(TextBlock)
|
|
|
|
|
void commas(bool flag) { m_commas = flag; }
|
|
|
|
|
bool commas() const { return m_commas; }
|
|
|
|
|
AstNode* nodesp() const { return op1p(); }
|
|
|
|
|
void addNodep(AstNode* nodep) { addOp1p(nodep); }
|
2020-04-15 13:58:34 +02:00
|
|
|
void addText(FileLine* fl, const string& textp, bool tracking = false) {
|
2019-09-27 09:44:23 +02:00
|
|
|
addNodep(new AstText(fl, textp, tracking));
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
2020-11-19 03:32:16 +01:00
|
|
|
class AstScCtor final : public AstNodeText {
|
2014-09-12 03:28:53 +02:00
|
|
|
public:
|
2006-08-26 13:35:28 +02:00
|
|
|
AstScCtor(FileLine* fl, const string& textp)
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_ScCtor(fl, textp) {}
|
2016-11-05 14:47:56 +01:00
|
|
|
ASTNODE_NODE_FUNCS(ScCtor)
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual bool isPure() const override { return false; } // SPECIAL: User may order w/other sigs
|
|
|
|
|
virtual bool isOutputter() const override { return true; }
|
2006-08-26 13:35:28 +02:00
|
|
|
};
|
|
|
|
|
|
2020-11-19 03:32:16 +01:00
|
|
|
class AstScDtor final : public AstNodeText {
|
2014-09-12 03:28:53 +02:00
|
|
|
public:
|
2006-08-30 19:27:53 +02:00
|
|
|
AstScDtor(FileLine* fl, const string& textp)
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_ScDtor(fl, textp) {}
|
2016-11-05 14:47:56 +01:00
|
|
|
ASTNODE_NODE_FUNCS(ScDtor)
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual bool isPure() const override { return false; } // SPECIAL: User may order w/other sigs
|
|
|
|
|
virtual bool isOutputter() const override { return true; }
|
2006-08-30 19:27:53 +02:00
|
|
|
};
|
|
|
|
|
|
2020-11-19 03:32:16 +01:00
|
|
|
class AstScHdr final : public AstNodeText {
|
2014-09-12 03:28:53 +02:00
|
|
|
public:
|
2006-08-26 13:35:28 +02:00
|
|
|
AstScHdr(FileLine* fl, const string& textp)
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_ScHdr(fl, textp) {}
|
2016-11-05 14:47:56 +01:00
|
|
|
ASTNODE_NODE_FUNCS(ScHdr)
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual bool isPure() const override { return false; } // SPECIAL: User may order w/other sigs
|
|
|
|
|
virtual bool isOutputter() const override { return true; }
|
2006-08-26 13:35:28 +02:00
|
|
|
};
|
|
|
|
|
|
2020-11-19 03:32:16 +01:00
|
|
|
class AstScImp final : public AstNodeText {
|
2014-09-12 03:28:53 +02:00
|
|
|
public:
|
2006-08-26 13:35:28 +02:00
|
|
|
AstScImp(FileLine* fl, const string& textp)
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_ScImp(fl, textp) {}
|
2016-11-05 14:47:56 +01:00
|
|
|
ASTNODE_NODE_FUNCS(ScImp)
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual bool isPure() const override { return false; } // SPECIAL: User may order w/other sigs
|
|
|
|
|
virtual bool isOutputter() const override { return true; }
|
2006-08-26 13:35:28 +02:00
|
|
|
};
|
|
|
|
|
|
2020-11-19 03:32:16 +01:00
|
|
|
class AstScImpHdr final : public AstNodeText {
|
2014-09-12 03:28:53 +02:00
|
|
|
public:
|
2006-08-26 13:35:28 +02:00
|
|
|
AstScImpHdr(FileLine* fl, const string& textp)
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_ScImpHdr(fl, textp) {}
|
2016-11-05 14:47:56 +01:00
|
|
|
ASTNODE_NODE_FUNCS(ScImpHdr)
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual bool isPure() const override { return false; } // SPECIAL: User may order w/other sigs
|
|
|
|
|
virtual bool isOutputter() const override { return true; }
|
2006-08-26 13:35:28 +02:00
|
|
|
};
|
|
|
|
|
|
2020-11-19 03:32:16 +01:00
|
|
|
class AstScInt final : public AstNodeText {
|
2014-09-12 03:28:53 +02:00
|
|
|
public:
|
2006-08-26 13:35:28 +02:00
|
|
|
AstScInt(FileLine* fl, const string& textp)
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_ScInt(fl, textp) {}
|
2016-11-05 14:47:56 +01:00
|
|
|
ASTNODE_NODE_FUNCS(ScInt)
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual bool isPure() const override { return false; } // SPECIAL: User may order w/other sigs
|
|
|
|
|
virtual bool isOutputter() const override { return true; }
|
2006-08-26 13:35:28 +02:00
|
|
|
};
|
|
|
|
|
|
2020-11-19 03:32:16 +01:00
|
|
|
class AstUCStmt final : public AstNodeStmt {
|
2006-08-26 13:35:28 +02:00
|
|
|
// User $c statement
|
2014-09-12 03:28:53 +02:00
|
|
|
public:
|
2006-08-26 13:35:28 +02:00
|
|
|
AstUCStmt(FileLine* fl, AstNode* exprsp)
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_UCStmt(fl) {
|
2019-05-19 22:13:13 +02:00
|
|
|
addNOp1p(exprsp);
|
2006-08-26 13:35:28 +02:00
|
|
|
}
|
2016-11-05 14:47:56 +01:00
|
|
|
ASTNODE_NODE_FUNCS(UCStmt)
|
2019-05-19 22:13:13 +02:00
|
|
|
AstNode* bodysp() const { return op1p(); } // op1 = expressions to print
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual bool isGateOptimizable() const override { return false; }
|
|
|
|
|
virtual bool isPredictOptimizable() const override { return false; }
|
|
|
|
|
virtual bool isPure() const override { return false; }
|
|
|
|
|
virtual bool isOutputter() const override { return true; }
|
|
|
|
|
virtual bool same(const AstNode* samep) const override { return true; }
|
2006-08-26 13:35:28 +02:00
|
|
|
};
|
|
|
|
|
|
2019-09-27 09:44:23 +02:00
|
|
|
//======================================================================
|
|
|
|
|
// Emitted file nodes
|
|
|
|
|
|
2020-11-19 03:32:16 +01:00
|
|
|
class AstNodeFile VL_NOT_FINAL : public AstNode {
|
2019-09-27 09:44:23 +02:00
|
|
|
// Emitted Otput file
|
|
|
|
|
// Parents: NETLIST
|
|
|
|
|
// Children: AstTextBlock
|
|
|
|
|
private:
|
2020-04-15 13:58:34 +02:00
|
|
|
string m_name; ///< Filename
|
2019-09-27 09:44:23 +02:00
|
|
|
public:
|
2020-01-25 21:29:44 +01:00
|
|
|
AstNodeFile(AstType t, FileLine* fl, const string& name)
|
|
|
|
|
: AstNode(t, fl) {
|
2019-09-27 09:44:23 +02:00
|
|
|
m_name = name;
|
|
|
|
|
}
|
2020-01-22 01:54:14 +01:00
|
|
|
ASTNODE_BASE_FUNCS(NodeFile)
|
2020-09-17 03:52:24 +02:00
|
|
|
virtual void dump(std::ostream& str) const override;
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual string name() const override { return m_name; }
|
|
|
|
|
virtual bool same(const AstNode* samep) const override { return true; }
|
2019-09-27 09:44:23 +02:00
|
|
|
void tblockp(AstTextBlock* tblockp) { setOp1p(tblockp); }
|
2021-10-22 14:56:48 +02:00
|
|
|
AstTextBlock* tblockp() { return VN_AS(op1p(), TextBlock); }
|
2019-09-27 09:44:23 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
//======================================================================
|
|
|
|
|
// Emit V nodes
|
|
|
|
|
|
2020-11-19 03:32:16 +01:00
|
|
|
class AstVFile final : public AstNodeFile {
|
2019-09-27 09:44:23 +02:00
|
|
|
// Verilog output file
|
|
|
|
|
// Parents: NETLIST
|
|
|
|
|
public:
|
|
|
|
|
AstVFile(FileLine* fl, const string& name)
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_VFile(fl, name) {}
|
2019-09-27 09:44:23 +02:00
|
|
|
ASTNODE_NODE_FUNCS(VFile)
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual void dump(std::ostream& str = std::cout) const override;
|
2019-09-27 09:44:23 +02:00
|
|
|
};
|
|
|
|
|
|
2006-08-26 13:35:28 +02:00
|
|
|
//======================================================================
|
|
|
|
|
// Emit C nodes
|
|
|
|
|
|
2020-11-19 03:32:16 +01:00
|
|
|
class AstCFile final : public AstNodeFile {
|
2006-08-26 13:35:28 +02:00
|
|
|
// C++ output file
|
|
|
|
|
// Parents: NETLIST
|
|
|
|
|
private:
|
2020-04-15 13:58:34 +02:00
|
|
|
bool m_slow : 1; ///< Compile w/o optimization
|
|
|
|
|
bool m_source : 1; ///< Source file (vs header file)
|
|
|
|
|
bool m_support : 1; ///< Support file (non systemc)
|
2006-08-26 13:35:28 +02:00
|
|
|
public:
|
|
|
|
|
AstCFile(FileLine* fl, const string& name)
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_CFile(fl, name)
|
2020-08-16 17:40:42 +02:00
|
|
|
, m_slow{false}
|
|
|
|
|
, m_source{false}
|
|
|
|
|
, m_support{false} {}
|
2016-11-05 14:47:56 +01:00
|
|
|
ASTNODE_NODE_FUNCS(CFile)
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual void dump(std::ostream& str = std::cout) const override;
|
2019-05-19 22:13:13 +02:00
|
|
|
bool slow() const { return m_slow; }
|
|
|
|
|
void slow(bool flag) { m_slow = flag; }
|
|
|
|
|
bool source() const { return m_source; }
|
|
|
|
|
void source(bool flag) { m_source = flag; }
|
|
|
|
|
bool support() const { return m_support; }
|
|
|
|
|
void support(bool flag) { m_support = flag; }
|
2006-08-26 13:35:28 +02:00
|
|
|
};
|
|
|
|
|
|
2020-11-19 03:32:16 +01:00
|
|
|
class AstCFunc final : public AstNode {
|
2006-08-26 13:35:28 +02:00
|
|
|
// C++ function
|
|
|
|
|
// Parents: MODULE/SCOPE
|
|
|
|
|
// Children: VAR/statements
|
|
|
|
|
private:
|
2020-04-15 13:58:34 +02:00
|
|
|
AstScope* m_scopep;
|
|
|
|
|
string m_name;
|
|
|
|
|
string m_cname; // C name, for dpiExports
|
|
|
|
|
string m_rtnType; // void, bool, or other return type
|
2020-08-24 01:37:56 +02:00
|
|
|
string m_argTypes; // Argument types
|
|
|
|
|
string m_ctorInits; // Constructor sub-class inits
|
2020-04-15 13:58:34 +02:00
|
|
|
string m_ifdef; // #ifdef symbol around this function
|
|
|
|
|
VBoolOrUnknown m_isConst; // Function is declared const (*this not changed)
|
2021-06-16 14:52:37 +02:00
|
|
|
bool m_isStatic : 1; // Function is static (no need for a 'this' pointer)
|
2021-06-22 14:50:21 +02:00
|
|
|
bool m_isTrace : 1; // Function is related to tracing
|
2020-04-15 13:58:34 +02:00
|
|
|
bool m_dontCombine : 1; // V3Combine shouldn't compare this func tree, it's special
|
|
|
|
|
bool m_declPrivate : 1; // Declare it private
|
|
|
|
|
bool m_formCallTree : 1; // Make a global function to call entire tree of functions
|
|
|
|
|
bool m_slow : 1; // Slow routine, called once or just at init time
|
|
|
|
|
bool m_funcPublic : 1; // From user public task/function
|
|
|
|
|
bool m_isConstructor : 1; // Is C class constructor
|
|
|
|
|
bool m_isDestructor : 1; // Is C class destructor
|
|
|
|
|
bool m_isMethod : 1; // Is inside a class definition
|
2021-06-13 15:33:11 +02:00
|
|
|
bool m_isLoose : 1; // Semantically this is a method, but is implemented as a function
|
|
|
|
|
// with an explicitly passed 'self' pointer as the first argument
|
2020-04-15 13:58:34 +02:00
|
|
|
bool m_isInline : 1; // Inline function
|
|
|
|
|
bool m_isVirtual : 1; // Virtual function
|
|
|
|
|
bool m_entryPoint : 1; // User may call into this top level function
|
|
|
|
|
bool m_pure : 1; // Pure function
|
2021-11-27 23:07:27 +01:00
|
|
|
bool m_dpiContext : 1; // Declared as 'context' DPI import/export function
|
2021-06-10 23:41:33 +02:00
|
|
|
bool m_dpiExportDispatcher : 1; // This is the DPI export entry point (i.e.: called by user)
|
|
|
|
|
bool m_dpiExportImpl : 1; // DPI export implementation (called from DPI dispatcher via lookup)
|
|
|
|
|
bool m_dpiImportPrototype : 1; // This is the DPI import prototype (i.e.: provided by user)
|
|
|
|
|
bool m_dpiImportWrapper : 1; // Wrapper for invoking DPI import prototype from generated code
|
2021-11-27 23:07:27 +01:00
|
|
|
bool m_dpiTraceInit : 1; // DPI trace_init
|
2020-04-15 13:58:34 +02:00
|
|
|
public:
|
|
|
|
|
AstCFunc(FileLine* fl, const string& name, AstScope* scopep, const string& rtnType = "")
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_CFunc(fl) {
|
2020-02-01 16:57:55 +01:00
|
|
|
m_isConst = VBoolOrUnknown::BU_UNKNOWN; // Unknown until analyzed
|
2019-01-16 06:38:42 +01:00
|
|
|
m_scopep = scopep;
|
2019-05-19 22:13:13 +02:00
|
|
|
m_name = name;
|
|
|
|
|
m_rtnType = rtnType;
|
2021-06-16 14:52:37 +02:00
|
|
|
m_isStatic = false;
|
2021-06-22 14:50:21 +02:00
|
|
|
m_isTrace = false;
|
2019-05-19 22:13:13 +02:00
|
|
|
m_dontCombine = false;
|
|
|
|
|
m_declPrivate = false;
|
|
|
|
|
m_formCallTree = false;
|
|
|
|
|
m_slow = false;
|
|
|
|
|
m_funcPublic = false;
|
2020-02-03 03:15:07 +01:00
|
|
|
m_isConstructor = false;
|
|
|
|
|
m_isDestructor = false;
|
2020-02-01 16:57:55 +01:00
|
|
|
m_isMethod = true;
|
2021-06-13 15:33:11 +02:00
|
|
|
m_isLoose = false;
|
2019-05-19 22:13:13 +02:00
|
|
|
m_isInline = false;
|
2020-02-03 03:15:07 +01:00
|
|
|
m_isVirtual = false;
|
2019-05-19 22:13:13 +02:00
|
|
|
m_entryPoint = false;
|
|
|
|
|
m_pure = false;
|
2021-11-27 23:07:27 +01:00
|
|
|
m_dpiContext = false;
|
2021-06-10 23:41:33 +02:00
|
|
|
m_dpiExportDispatcher = false;
|
|
|
|
|
m_dpiExportImpl = false;
|
|
|
|
|
m_dpiImportPrototype = false;
|
2018-07-07 14:02:29 +02:00
|
|
|
m_dpiImportWrapper = false;
|
2021-11-27 23:07:27 +01:00
|
|
|
m_dpiTraceInit = false;
|
2006-08-26 13:35:28 +02:00
|
|
|
}
|
2016-11-05 14:47:56 +01:00
|
|
|
ASTNODE_NODE_FUNCS(CFunc)
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual string name() const override { return m_name; }
|
|
|
|
|
virtual const char* broken() const override {
|
2020-04-15 13:58:34 +02:00
|
|
|
BROKEN_RTN((m_scopep && !m_scopep->brokeExists()));
|
2020-08-15 16:12:55 +02:00
|
|
|
return nullptr;
|
2020-04-15 13:58:34 +02:00
|
|
|
}
|
2021-12-13 00:10:52 +01:00
|
|
|
virtual void cloneRelink() override {
|
|
|
|
|
if (m_scopep && m_scopep->clonep()) m_scopep = m_scopep->clonep();
|
|
|
|
|
}
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual bool maybePointedTo() const override { return true; }
|
|
|
|
|
virtual void dump(std::ostream& str = std::cout) const override;
|
|
|
|
|
virtual bool same(const AstNode* samep) const override {
|
2021-11-26 23:55:36 +01:00
|
|
|
const AstCFunc* const asamep = static_cast<const AstCFunc*>(samep);
|
2021-06-22 14:50:21 +02:00
|
|
|
return ((isTrace() == asamep->isTrace()) && (rtnTypeVoid() == asamep->rtnTypeVoid())
|
2020-08-24 01:37:56 +02:00
|
|
|
&& (argTypes() == asamep->argTypes()) && (ctorInits() == asamep->ctorInits())
|
2021-06-13 15:33:11 +02:00
|
|
|
&& isLoose() == asamep->isLoose()
|
2021-06-10 23:41:33 +02:00
|
|
|
&& (!(dpiImportPrototype() || dpiExportImpl()) || name() == asamep->name()));
|
2020-04-15 13:58:34 +02:00
|
|
|
}
|
2006-08-26 13:35:28 +02:00
|
|
|
//
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual void name(const string& name) override { m_name = name; }
|
2021-07-25 17:10:55 +02:00
|
|
|
virtual int instrCount() const override {
|
|
|
|
|
return dpiImportPrototype() ? v3Global.opt.instrCountDpi() : 0;
|
|
|
|
|
}
|
2020-02-01 16:57:55 +01:00
|
|
|
VBoolOrUnknown isConst() const { return m_isConst; }
|
|
|
|
|
void isConst(bool flag) { m_isConst.setTrueOrFalse(flag); }
|
|
|
|
|
void isConst(VBoolOrUnknown flag) { m_isConst = flag; }
|
2021-06-16 14:52:37 +02:00
|
|
|
bool isStatic() const { return m_isStatic; }
|
|
|
|
|
void isStatic(bool flag) { m_isStatic = flag; }
|
2021-06-22 14:50:21 +02:00
|
|
|
bool isTrace() const { return m_isTrace; }
|
|
|
|
|
void isTrace(bool flag) { m_isTrace = flag; }
|
2019-05-19 22:13:13 +02:00
|
|
|
void cname(const string& name) { m_cname = name; }
|
|
|
|
|
string cname() const { return m_cname; }
|
|
|
|
|
AstScope* scopep() const { return m_scopep; }
|
|
|
|
|
void scopep(AstScope* nodep) { m_scopep = nodep; }
|
2020-04-15 13:58:34 +02:00
|
|
|
string rtnTypeVoid() const { return ((m_rtnType == "") ? "void" : m_rtnType); }
|
2021-06-22 14:50:21 +02:00
|
|
|
bool dontCombine() const { return m_dontCombine || isTrace(); }
|
2019-05-19 22:13:13 +02:00
|
|
|
void dontCombine(bool flag) { m_dontCombine = flag; }
|
2021-06-13 15:33:11 +02:00
|
|
|
bool dontInline() const { return dontCombine() || slow() || funcPublic(); }
|
2019-05-19 22:13:13 +02:00
|
|
|
bool declPrivate() const { return m_declPrivate; }
|
|
|
|
|
void declPrivate(bool flag) { m_declPrivate = flag; }
|
|
|
|
|
bool formCallTree() const { return m_formCallTree; }
|
|
|
|
|
void formCallTree(bool flag) { m_formCallTree = flag; }
|
|
|
|
|
bool slow() const { return m_slow; }
|
|
|
|
|
void slow(bool flag) { m_slow = flag; }
|
|
|
|
|
bool funcPublic() const { return m_funcPublic; }
|
|
|
|
|
void funcPublic(bool flag) { m_funcPublic = flag; }
|
|
|
|
|
void argTypes(const string& str) { m_argTypes = str; }
|
|
|
|
|
string argTypes() const { return m_argTypes; }
|
2020-08-24 01:37:56 +02:00
|
|
|
void ctorInits(const string& str) { m_ctorInits = str; }
|
|
|
|
|
string ctorInits() const { return m_ctorInits; }
|
2019-05-19 22:13:13 +02:00
|
|
|
void ifdef(const string& str) { m_ifdef = str; }
|
|
|
|
|
string ifdef() const { return m_ifdef; }
|
2020-02-03 03:15:07 +01:00
|
|
|
bool isConstructor() const { return m_isConstructor; }
|
|
|
|
|
void isConstructor(bool flag) { m_isConstructor = flag; }
|
|
|
|
|
bool isDestructor() const { return m_isDestructor; }
|
|
|
|
|
void isDestructor(bool flag) { m_isDestructor = flag; }
|
2020-02-01 16:57:55 +01:00
|
|
|
bool isMethod() const { return m_isMethod; }
|
|
|
|
|
void isMethod(bool flag) { m_isMethod = flag; }
|
2021-06-13 15:33:11 +02:00
|
|
|
bool isLoose() const { return m_isLoose; }
|
|
|
|
|
void isLoose(bool flag) { m_isLoose = flag; }
|
|
|
|
|
bool isProperMethod() const { return isMethod() && !isLoose(); }
|
2019-05-19 22:13:13 +02:00
|
|
|
bool isInline() const { return m_isInline; }
|
|
|
|
|
void isInline(bool flag) { m_isInline = flag; }
|
2020-02-03 03:15:07 +01:00
|
|
|
bool isVirtual() const { return m_isVirtual; }
|
|
|
|
|
void isVirtual(bool flag) { m_isVirtual = flag; }
|
2019-05-19 22:13:13 +02:00
|
|
|
bool entryPoint() const { return m_entryPoint; }
|
|
|
|
|
void entryPoint(bool flag) { m_entryPoint = flag; }
|
|
|
|
|
bool pure() const { return m_pure; }
|
|
|
|
|
void pure(bool flag) { m_pure = flag; }
|
2021-11-27 23:07:27 +01:00
|
|
|
bool dpiContext() const { return m_dpiContext; }
|
|
|
|
|
void dpiContext(bool flag) { m_dpiContext = flag; }
|
2021-06-10 23:41:33 +02:00
|
|
|
bool dpiExportDispatcher() const { return m_dpiExportDispatcher; }
|
|
|
|
|
void dpiExportDispatcher(bool flag) { m_dpiExportDispatcher = flag; }
|
|
|
|
|
bool dpiExportImpl() const { return m_dpiExportImpl; }
|
|
|
|
|
void dpiExportImpl(bool flag) { m_dpiExportImpl = flag; }
|
|
|
|
|
bool dpiImportPrototype() const { return m_dpiImportPrototype; }
|
|
|
|
|
void dpiImportPrototype(bool flag) { m_dpiImportPrototype = flag; }
|
2018-07-07 14:02:29 +02:00
|
|
|
bool dpiImportWrapper() const { return m_dpiImportWrapper; }
|
|
|
|
|
void dpiImportWrapper(bool flag) { m_dpiImportWrapper = flag; }
|
2021-11-27 23:07:27 +01:00
|
|
|
void dpiTraceInit(bool flag) { m_dpiTraceInit = flag; }
|
|
|
|
|
bool dpiTraceInit() const { return m_dpiTraceInit; }
|
2006-08-26 13:35:28 +02:00
|
|
|
//
|
2009-12-03 12:55:29 +01:00
|
|
|
// If adding node accessors, see below emptyBody
|
2019-05-19 22:13:13 +02:00
|
|
|
AstNode* argsp() const { return op1p(); }
|
2006-08-26 13:35:28 +02:00
|
|
|
void addArgsp(AstNode* nodep) { addOp1p(nodep); }
|
2019-05-19 22:13:13 +02:00
|
|
|
AstNode* initsp() const { return op2p(); }
|
2006-08-26 13:35:28 +02:00
|
|
|
void addInitsp(AstNode* nodep) { addOp2p(nodep); }
|
2019-05-19 22:13:13 +02:00
|
|
|
AstNode* stmtsp() const { return op3p(); }
|
2006-08-26 13:35:28 +02:00
|
|
|
void addStmtsp(AstNode* nodep) { addOp3p(nodep); }
|
2019-05-19 22:13:13 +02:00
|
|
|
AstNode* finalsp() const { return op4p(); }
|
2006-08-26 13:35:28 +02:00
|
|
|
void addFinalsp(AstNode* nodep) { addOp4p(nodep); }
|
|
|
|
|
// Special methods
|
2020-04-15 13:58:34 +02:00
|
|
|
bool emptyBody() const {
|
2020-08-15 16:12:55 +02:00
|
|
|
return argsp() == nullptr && initsp() == nullptr && stmtsp() == nullptr
|
|
|
|
|
&& finalsp() == nullptr;
|
2020-04-15 13:58:34 +02:00
|
|
|
}
|
2006-08-26 13:35:28 +02:00
|
|
|
};
|
|
|
|
|
|
2020-11-19 03:32:16 +01:00
|
|
|
class AstCCall final : public AstNodeCCall {
|
2006-08-26 13:35:28 +02:00
|
|
|
// C++ function call
|
|
|
|
|
// Parents: Anything above a statement
|
|
|
|
|
// Children: Args to the function
|
2021-07-13 18:42:17 +02:00
|
|
|
|
|
|
|
|
string m_selfPointer; // Output code object pointer (e.g.: 'this')
|
|
|
|
|
|
2006-08-26 13:35:28 +02:00
|
|
|
public:
|
2020-08-15 16:12:55 +02:00
|
|
|
AstCCall(FileLine* fl, AstCFunc* funcp, AstNode* argsp = nullptr)
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_CCall(fl, funcp, argsp) {}
|
2020-03-07 18:52:11 +01:00
|
|
|
ASTNODE_NODE_FUNCS(CCall)
|
2021-07-13 18:42:17 +02:00
|
|
|
|
|
|
|
|
string selfPointer() const { return m_selfPointer; }
|
|
|
|
|
void selfPointer(const string& value) { m_selfPointer = value; }
|
|
|
|
|
string selfPointerProtect(bool useSelfForThis) const;
|
2020-03-07 18:52:11 +01:00
|
|
|
};
|
|
|
|
|
|
2020-11-19 03:32:16 +01:00
|
|
|
class AstCMethodCall final : public AstNodeCCall {
|
2020-03-07 18:52:11 +01:00
|
|
|
// C++ method call
|
|
|
|
|
// Parents: Anything above a statement
|
|
|
|
|
// Children: Args to the function
|
|
|
|
|
public:
|
2020-08-15 16:12:55 +02:00
|
|
|
AstCMethodCall(FileLine* fl, AstNode* fromp, AstCFunc* funcp, AstNode* argsp = nullptr)
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_CMethodCall(fl, funcp, argsp) {
|
2020-03-07 18:52:11 +01:00
|
|
|
setOp1p(fromp);
|
2019-05-19 22:13:13 +02:00
|
|
|
}
|
2020-03-07 18:52:11 +01:00
|
|
|
ASTNODE_NODE_FUNCS(CMethodCall)
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual const char* broken() const override {
|
2020-03-07 18:52:11 +01:00
|
|
|
BROKEN_BASE_RTN(AstNodeCCall::broken());
|
|
|
|
|
BROKEN_RTN(!fromp());
|
2020-08-15 16:12:55 +02:00
|
|
|
return nullptr;
|
2006-08-26 13:35:28 +02:00
|
|
|
}
|
2020-08-15 16:12:55 +02:00
|
|
|
AstNode* fromp() const {
|
|
|
|
|
return op1p();
|
|
|
|
|
} // op1 = Extracting what (nullptr=TBD during parsing)
|
2020-03-07 18:52:11 +01:00
|
|
|
void fromp(AstNode* nodep) { setOp1p(nodep); }
|
2006-08-26 13:35:28 +02:00
|
|
|
};
|
|
|
|
|
|
2020-11-19 03:32:16 +01:00
|
|
|
class AstCNew final : public AstNodeCCall {
|
2020-04-13 00:57:12 +02:00
|
|
|
// C++ new() call
|
|
|
|
|
// Parents: Anything above an expression
|
|
|
|
|
// Children: Args to the function
|
|
|
|
|
public:
|
2020-08-15 16:12:55 +02:00
|
|
|
AstCNew(FileLine* fl, AstCFunc* funcp, AstNode* argsp = nullptr)
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_CNew(fl, funcp, argsp) {
|
2020-04-13 00:57:12 +02:00
|
|
|
statement(false);
|
|
|
|
|
}
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual bool hasDType() const override { return true; }
|
2020-04-13 00:57:12 +02:00
|
|
|
ASTNODE_NODE_FUNCS(CNew)
|
|
|
|
|
};
|
|
|
|
|
|
2020-11-19 03:32:16 +01:00
|
|
|
class AstCReturn final : public AstNodeStmt {
|
2006-08-26 13:35:28 +02:00
|
|
|
// C++ return from a function
|
|
|
|
|
// Parents: CFUNC/statement
|
|
|
|
|
// Children: Math
|
2014-09-12 03:28:53 +02:00
|
|
|
public:
|
2006-08-26 13:35:28 +02:00
|
|
|
AstCReturn(FileLine* fl, AstNode* lhsp)
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_CReturn(fl) {
|
2019-05-19 22:13:13 +02:00
|
|
|
setOp1p(lhsp);
|
2006-08-26 13:35:28 +02:00
|
|
|
}
|
2016-11-05 14:47:56 +01:00
|
|
|
ASTNODE_NODE_FUNCS(CReturn)
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual int instrCount() const override { return widthInstrs(); }
|
|
|
|
|
virtual bool same(const AstNode* samep) const override { return true; }
|
2006-08-26 13:35:28 +02:00
|
|
|
//
|
2019-05-19 22:13:13 +02:00
|
|
|
AstNode* lhsp() const { return op1p(); }
|
2006-08-26 13:35:28 +02:00
|
|
|
};
|
|
|
|
|
|
2020-11-19 03:32:16 +01:00
|
|
|
class AstCMath final : public AstNodeMath {
|
2009-12-03 01:32:41 +01:00
|
|
|
private:
|
2021-11-26 23:55:36 +01:00
|
|
|
const bool m_cleanOut;
|
2019-12-24 18:47:27 +01:00
|
|
|
bool m_pure; // Pure optimizable
|
2009-12-03 01:32:41 +01:00
|
|
|
public:
|
2006-08-26 13:35:28 +02:00
|
|
|
// Emit C textual math function (like AstUCFunc)
|
|
|
|
|
AstCMath(FileLine* fl, AstNode* exprsp)
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_CMath(fl)
|
2020-08-16 17:40:42 +02:00
|
|
|
, m_cleanOut{true}
|
|
|
|
|
, m_pure{false} {
|
2019-05-19 22:13:13 +02:00
|
|
|
addOp1p(exprsp);
|
|
|
|
|
dtypeFrom(exprsp);
|
2006-08-26 13:35:28 +02:00
|
|
|
}
|
2020-04-15 13:58:34 +02:00
|
|
|
AstCMath(FileLine* fl, const string& textStmt, int setwidth, bool cleanOut = true)
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_CMath(fl)
|
2020-08-16 17:40:42 +02:00
|
|
|
, m_cleanOut{cleanOut}
|
|
|
|
|
, m_pure{true} {
|
2019-05-19 22:13:13 +02:00
|
|
|
addNOp1p(new AstText(fl, textStmt, true));
|
2021-02-22 03:25:21 +01:00
|
|
|
if (setwidth) dtypeSetLogicSized(setwidth, VSigning::UNSIGNED);
|
2006-08-26 13:35:28 +02:00
|
|
|
}
|
2016-11-05 14:47:56 +01:00
|
|
|
ASTNODE_NODE_FUNCS(CMath)
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual bool isGateOptimizable() const override { return m_pure; }
|
|
|
|
|
virtual bool isPredictOptimizable() const override { return m_pure; }
|
|
|
|
|
virtual bool cleanOut() const override { return m_cleanOut; }
|
|
|
|
|
virtual string emitVerilog() override { V3ERROR_NA_RETURN(""); }
|
|
|
|
|
virtual string emitC() override { V3ERROR_NA_RETURN(""); }
|
|
|
|
|
virtual bool same(const AstNode* samep) const override { return true; }
|
2009-12-17 03:28:35 +01:00
|
|
|
void addBodysp(AstNode* nodep) { addNOp1p(nodep); }
|
2019-05-19 22:13:13 +02:00
|
|
|
AstNode* bodysp() const { return op1p(); } // op1 = expressions to print
|
2019-12-24 18:47:27 +01:00
|
|
|
bool pure() const { return m_pure; }
|
|
|
|
|
void pure(bool flag) { m_pure = flag; }
|
2006-08-26 13:35:28 +02:00
|
|
|
};
|
|
|
|
|
|
2020-11-19 03:32:16 +01:00
|
|
|
class AstCReset final : public AstNodeStmt {
|
2018-08-31 02:05:13 +02:00
|
|
|
// Reset variable at startup
|
2016-05-12 13:19:02 +02:00
|
|
|
public:
|
2021-10-22 14:56:48 +02:00
|
|
|
AstCReset(FileLine* fl, AstVarRef* exprsp)
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_CReset(fl) {
|
2019-05-19 22:13:13 +02:00
|
|
|
addNOp1p(exprsp);
|
2016-05-12 13:19:02 +02:00
|
|
|
}
|
2016-11-05 14:47:56 +01:00
|
|
|
ASTNODE_NODE_FUNCS(CReset)
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual bool isGateOptimizable() const override { return false; }
|
|
|
|
|
virtual bool isPredictOptimizable() const override { return false; }
|
|
|
|
|
virtual bool same(const AstNode* samep) const override { return true; }
|
2021-10-22 14:56:48 +02:00
|
|
|
AstVarRef* varrefp() const { return VN_AS(op1p(), VarRef); } // op1 = varref to reset
|
2016-05-12 13:19:02 +02:00
|
|
|
};
|
|
|
|
|
|
2020-11-19 03:32:16 +01:00
|
|
|
class AstCStmt final : public AstNodeStmt {
|
2006-08-26 13:35:28 +02:00
|
|
|
// Emit C statement
|
2014-09-12 03:28:53 +02:00
|
|
|
public:
|
2006-08-26 13:35:28 +02:00
|
|
|
AstCStmt(FileLine* fl, AstNode* exprsp)
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_CStmt(fl) {
|
2019-05-19 22:13:13 +02:00
|
|
|
addNOp1p(exprsp);
|
2006-08-26 13:35:28 +02:00
|
|
|
}
|
|
|
|
|
AstCStmt(FileLine* fl, const string& textStmt)
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_CStmt(fl) {
|
2019-05-19 22:13:13 +02:00
|
|
|
addNOp1p(new AstText(fl, textStmt, true));
|
2006-08-26 13:35:28 +02:00
|
|
|
}
|
2016-11-05 14:47:56 +01:00
|
|
|
ASTNODE_NODE_FUNCS(CStmt)
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual bool isGateOptimizable() const override { return false; }
|
|
|
|
|
virtual bool isPredictOptimizable() const override { return false; }
|
|
|
|
|
virtual bool same(const AstNode* samep) const override { return true; }
|
2009-12-17 03:28:35 +01:00
|
|
|
void addBodysp(AstNode* nodep) { addNOp1p(nodep); }
|
2019-05-19 22:13:13 +02:00
|
|
|
AstNode* bodysp() const { return op1p(); } // op1 = expressions to print
|
2006-08-26 13:35:28 +02:00
|
|
|
};
|
|
|
|
|
|
2020-11-19 03:32:16 +01:00
|
|
|
class AstCUse final : public AstNode {
|
2020-02-01 22:45:11 +01:00
|
|
|
// C++ use of a class or #include; indicates need of forward declaration
|
|
|
|
|
// Parents: NODEMODULE
|
|
|
|
|
private:
|
2021-07-20 20:52:15 +02:00
|
|
|
const VUseType m_useType; // What sort of use this is
|
|
|
|
|
const string m_name;
|
2020-04-15 13:58:34 +02:00
|
|
|
|
2020-02-01 22:45:11 +01:00
|
|
|
public:
|
|
|
|
|
AstCUse(FileLine* fl, VUseType useType, const string& name)
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_CUse(fl)
|
2020-08-16 17:40:42 +02:00
|
|
|
, m_useType{useType}
|
|
|
|
|
, m_name{name} {}
|
2020-02-01 22:45:11 +01:00
|
|
|
ASTNODE_NODE_FUNCS(CUse)
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual void dump(std::ostream& str = std::cout) const override;
|
2021-07-20 20:52:15 +02:00
|
|
|
virtual string name() const override { return m_name; }
|
2020-02-01 22:45:11 +01:00
|
|
|
VUseType useType() const { return m_useType; }
|
|
|
|
|
};
|
|
|
|
|
|
2020-11-19 03:32:16 +01:00
|
|
|
class AstMTaskBody final : public AstNode {
|
2018-07-23 02:54:28 +02:00
|
|
|
// Hold statements for each MTask
|
|
|
|
|
private:
|
2020-08-15 19:11:27 +02:00
|
|
|
ExecMTask* m_execMTaskp = nullptr;
|
2020-04-15 13:58:34 +02:00
|
|
|
|
2018-07-23 02:54:28 +02:00
|
|
|
public:
|
2020-01-25 21:29:44 +01:00
|
|
|
explicit AstMTaskBody(FileLine* fl)
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_MTaskBody(fl) {}
|
2018-07-23 02:54:28 +02:00
|
|
|
ASTNODE_NODE_FUNCS(MTaskBody);
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual const char* broken() const override {
|
2020-04-15 13:58:34 +02:00
|
|
|
BROKEN_RTN(!m_execMTaskp);
|
2020-08-15 16:12:55 +02:00
|
|
|
return nullptr;
|
2020-04-15 13:58:34 +02:00
|
|
|
}
|
2018-07-23 02:54:28 +02:00
|
|
|
AstNode* stmtsp() const { return op1p(); }
|
|
|
|
|
void addStmtsp(AstNode* nodep) { addOp1p(nodep); }
|
|
|
|
|
ExecMTask* execMTaskp() const { return m_execMTaskp; }
|
|
|
|
|
void execMTaskp(ExecMTask* execMTaskp) { m_execMTaskp = execMTaskp; }
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual void dump(std::ostream& str = std::cout) const override;
|
2018-07-23 02:54:28 +02:00
|
|
|
};
|
|
|
|
|
|
2020-11-19 03:32:16 +01:00
|
|
|
class AstExecGraph final : public AstNode {
|
2018-07-23 02:54:28 +02:00
|
|
|
// For parallel execution, this node contains a dependency graph. Each
|
|
|
|
|
// node in the graph is an ExecMTask, which contains a body for the
|
|
|
|
|
// mtask, which contains a set of AstActive's, each of which calls a
|
|
|
|
|
// leaf AstCFunc. whew!
|
|
|
|
|
//
|
|
|
|
|
// The mtask bodies are also children of this node, so we can visit
|
|
|
|
|
// them without traversing the graph (it's not always needed to
|
|
|
|
|
// traverse the graph.)
|
|
|
|
|
private:
|
2021-06-16 13:18:56 +02:00
|
|
|
V3Graph* const m_depGraphp; // contains ExecMTask's
|
|
|
|
|
|
2018-07-23 02:54:28 +02:00
|
|
|
public:
|
2020-01-25 21:29:44 +01:00
|
|
|
explicit AstExecGraph(FileLine* fl);
|
2018-07-23 02:54:28 +02:00
|
|
|
ASTNODE_NODE_FUNCS_NO_DTOR(ExecGraph)
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual ~AstExecGraph() override;
|
|
|
|
|
virtual const char* broken() const override {
|
2020-04-15 13:58:34 +02:00
|
|
|
BROKEN_RTN(!m_depGraphp);
|
2020-08-15 16:12:55 +02:00
|
|
|
return nullptr;
|
2020-04-15 13:58:34 +02:00
|
|
|
}
|
2018-07-23 02:54:28 +02:00
|
|
|
const V3Graph* depGraphp() const { return m_depGraphp; }
|
|
|
|
|
V3Graph* mutableDepGraphp() { return m_depGraphp; }
|
|
|
|
|
void addMTaskBody(AstMTaskBody* bodyp) { addOp1p(bodyp); }
|
2021-06-16 13:18:56 +02:00
|
|
|
void addStmtsp(AstNode* stmtp) { addOp2p(stmtp); }
|
2018-07-23 02:54:28 +02:00
|
|
|
};
|
|
|
|
|
|
2020-11-19 03:32:16 +01:00
|
|
|
class AstSplitPlaceholder final : public AstNode {
|
2018-02-28 12:58:41 +01:00
|
|
|
public:
|
|
|
|
|
// Dummy node used within V3Split; never exists outside of V3Split.
|
2020-01-25 21:29:44 +01:00
|
|
|
explicit AstSplitPlaceholder(FileLine* fl)
|
2021-05-22 12:13:02 +02:00
|
|
|
: ASTGEN_SUPER_SplitPlaceholder(fl) {}
|
2018-02-28 12:58:41 +01:00
|
|
|
ASTNODE_NODE_FUNCS(SplitPlaceholder)
|
|
|
|
|
};
|
|
|
|
|
|
2012-04-29 16:14:13 +02:00
|
|
|
//######################################################################
|
|
|
|
|
// Right below top
|
|
|
|
|
|
2020-11-19 03:32:16 +01:00
|
|
|
class AstTypeTable final : public AstNode {
|
2012-04-29 16:14:13 +02:00
|
|
|
// Container for hash of standard data types
|
|
|
|
|
// Children: NODEDTYPEs
|
2021-08-28 23:23:35 +02:00
|
|
|
AstEmptyQueueDType* m_emptyQueuep = nullptr;
|
2020-11-01 16:56:07 +01:00
|
|
|
AstQueueDType* m_queueIndexp = nullptr;
|
2021-08-28 23:23:35 +02:00
|
|
|
AstVoidDType* m_voidp = nullptr;
|
2012-04-29 16:14:13 +02:00
|
|
|
AstBasicDType* m_basicps[AstBasicDTypeKwd::_ENUM_MAX];
|
|
|
|
|
//
|
2021-03-13 00:10:45 +01:00
|
|
|
using DetailedMap = std::map<VBasicTypeKey, AstBasicDType*>;
|
2012-04-29 16:14:13 +02:00
|
|
|
DetailedMap m_detailedMap;
|
2020-04-15 13:58:34 +02:00
|
|
|
|
2012-04-29 16:14:13 +02:00
|
|
|
public:
|
2021-06-13 16:05:55 +02:00
|
|
|
explicit AstTypeTable(FileLine* fl);
|
2016-11-05 14:47:56 +01:00
|
|
|
ASTNODE_NODE_FUNCS(TypeTable)
|
2021-12-13 00:10:52 +01:00
|
|
|
virtual bool maybePointedTo() const override { return true; }
|
|
|
|
|
virtual const char* broken() const override {
|
|
|
|
|
BROKEN_RTN(m_emptyQueuep && !m_emptyQueuep->brokeExists());
|
|
|
|
|
BROKEN_RTN(m_queueIndexp && !m_queueIndexp->brokeExists());
|
|
|
|
|
BROKEN_RTN(m_voidp && !m_voidp->brokeExists());
|
|
|
|
|
return nullptr;
|
|
|
|
|
}
|
|
|
|
|
virtual void cloneRelink() override { V3ERROR_NA; }
|
2021-10-22 14:56:48 +02:00
|
|
|
AstNodeDType* typesp() const { return VN_AS(op1p(), NodeDType); } // op1 = List of dtypes
|
2012-04-29 16:14:13 +02:00
|
|
|
void addTypesp(AstNodeDType* nodep) { addOp1p(nodep); }
|
|
|
|
|
AstBasicDType* findBasicDType(FileLine* fl, AstBasicDTypeKwd kwd);
|
2020-04-15 13:58:34 +02:00
|
|
|
AstBasicDType* findLogicBitDType(FileLine* fl, AstBasicDTypeKwd kwd, int width, int widthMin,
|
2020-04-20 03:19:09 +02:00
|
|
|
VSigning numeric);
|
2020-08-16 20:55:46 +02:00
|
|
|
AstBasicDType* findLogicBitDType(FileLine* fl, AstBasicDTypeKwd kwd, const VNumRange& range,
|
2020-04-20 03:19:09 +02:00
|
|
|
int widthMin, VSigning numeric);
|
2012-04-29 16:14:13 +02:00
|
|
|
AstBasicDType* findInsertSameDType(AstBasicDType* nodep);
|
2021-08-28 23:23:35 +02:00
|
|
|
AstEmptyQueueDType* findEmptyQueueDType(FileLine* fl);
|
|
|
|
|
AstQueueDType* findQueueIndexDType(FileLine* fl);
|
|
|
|
|
AstVoidDType* findVoidDType(FileLine* fl);
|
2012-04-29 16:14:13 +02:00
|
|
|
void clearCache();
|
|
|
|
|
void repairCache();
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual void dump(std::ostream& str = std::cout) const override;
|
2012-04-29 16:14:13 +02:00
|
|
|
};
|
|
|
|
|
|
2021-06-13 16:05:55 +02:00
|
|
|
class AstConstPool final : public AstNode {
|
|
|
|
|
// Container for const static data
|
|
|
|
|
std::unordered_multimap<uint32_t, AstVarScope*> m_tables; // Constant tables (unpacked arrays)
|
|
|
|
|
std::unordered_multimap<uint32_t, AstVarScope*> m_consts; // Constant tables (scalars)
|
|
|
|
|
AstModule* const m_modp; // The Module holding the Scope below ...
|
|
|
|
|
AstScope* const m_scopep; // Scope holding the constant variables
|
|
|
|
|
|
|
|
|
|
AstVarScope* createNewEntry(const string& name, AstNode* initp);
|
|
|
|
|
|
|
|
|
|
public:
|
|
|
|
|
explicit AstConstPool(FileLine* fl);
|
|
|
|
|
ASTNODE_NODE_FUNCS(ConstPool)
|
2021-12-13 00:10:52 +01:00
|
|
|
virtual bool maybePointedTo() const override { return true; }
|
|
|
|
|
virtual const char* broken() const override {
|
|
|
|
|
BROKEN_RTN(m_modp && !m_modp->brokeExists());
|
|
|
|
|
BROKEN_RTN(m_scopep && !m_scopep->brokeExists());
|
|
|
|
|
return nullptr;
|
|
|
|
|
}
|
|
|
|
|
virtual void cloneRelink() override { V3ERROR_NA; }
|
2021-06-13 16:05:55 +02:00
|
|
|
AstModule* modp() const { return m_modp; }
|
|
|
|
|
|
|
|
|
|
// Find a table (unpacked array) within the constant pool which is initialized with the
|
|
|
|
|
// given value, or create one if one does not already exists. The returned VarScope *might*
|
|
|
|
|
// have a different dtype than the given initp->dtypep(), including a different element type,
|
|
|
|
|
// but it will always have the same size and element width. In contexts where this matters,
|
|
|
|
|
// the caller must handle the dtype difference as appropriate.
|
|
|
|
|
AstVarScope* findTable(AstInitArray* initp);
|
|
|
|
|
// Find a constant within the constant pool which is initialized with the given value, or
|
|
|
|
|
// create one if one does not already exists. If 'mergeDType' is true, then the returned
|
|
|
|
|
// VarScope *might* have a different type than the given initp->dtypep(). In contexts where
|
|
|
|
|
// this matters, the caller must handle the dtype difference as appropriate. If 'mergeDType' is
|
|
|
|
|
// false, the returned VarScope will have _->dtypep()->sameTree(initp->dtypep()) return true.
|
|
|
|
|
AstVarScope* findConst(AstConst* initp, bool mergeDType);
|
|
|
|
|
};
|
|
|
|
|
|
2006-08-26 13:35:28 +02:00
|
|
|
//######################################################################
|
|
|
|
|
// Top
|
|
|
|
|
|
2020-11-19 03:32:16 +01:00
|
|
|
class AstNetlist final : public AstNode {
|
2006-08-26 13:35:28 +02:00
|
|
|
// All modules are under this single top node.
|
|
|
|
|
// Parents: none
|
|
|
|
|
// Children: MODULEs & CFILEs
|
2012-04-29 16:14:13 +02:00
|
|
|
private:
|
2021-06-13 16:05:55 +02:00
|
|
|
AstTypeTable* const m_typeTablep; // Reference to top type table, for faster lookup
|
|
|
|
|
AstConstPool* const m_constPoolp; // Reference to constant pool, for faster lookup
|
2020-08-15 19:11:27 +02:00
|
|
|
AstPackage* m_dollarUnitPkgp = nullptr; // $unit
|
|
|
|
|
AstCFunc* m_evalp = nullptr; // The '_eval' function
|
|
|
|
|
AstExecGraph* m_execGraphp = nullptr; // Execution MTask graph for threads>1 mode
|
2021-08-12 22:43:32 +02:00
|
|
|
AstVarScope* m_dpiExportTriggerp = nullptr; // The DPI export trigger variable
|
2021-10-17 11:29:17 +02:00
|
|
|
AstTopScope* m_topScopep = nullptr; // The singleton AstTopScope under the top module
|
2020-04-16 01:39:03 +02:00
|
|
|
VTimescale m_timeunit; // Global time unit
|
|
|
|
|
VTimescale m_timeprecision; // Global time precision
|
2021-07-23 02:50:03 +02:00
|
|
|
bool m_changeRequest = false; // Have _change_request method
|
2021-01-02 00:31:27 +01:00
|
|
|
bool m_timescaleSpecified = false; // Input HDL specified timescale
|
2012-04-29 16:14:13 +02:00
|
|
|
public:
|
2021-06-13 16:05:55 +02:00
|
|
|
AstNetlist();
|
2016-11-05 14:47:56 +01:00
|
|
|
ASTNODE_NODE_FUNCS(Netlist)
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual const char* broken() const override {
|
2021-12-13 00:10:52 +01:00
|
|
|
BROKEN_RTN(m_typeTablep && !m_typeTablep->brokeExists());
|
|
|
|
|
BROKEN_RTN(m_constPoolp && !m_constPoolp->brokeExists());
|
2017-12-01 00:53:57 +01:00
|
|
|
BROKEN_RTN(m_dollarUnitPkgp && !m_dollarUnitPkgp->brokeExists());
|
|
|
|
|
BROKEN_RTN(m_evalp && !m_evalp->brokeExists());
|
2021-08-12 22:43:32 +02:00
|
|
|
BROKEN_RTN(m_dpiExportTriggerp && !m_dpiExportTriggerp->brokeExists());
|
2021-10-17 11:29:17 +02:00
|
|
|
BROKEN_RTN(m_topScopep && !m_topScopep->brokeExists());
|
2020-08-15 16:12:55 +02:00
|
|
|
return nullptr;
|
2017-12-01 00:53:57 +01:00
|
|
|
}
|
2021-12-13 00:10:52 +01:00
|
|
|
virtual void cloneRelink() override { V3ERROR_NA; }
|
2020-08-15 17:44:10 +02:00
|
|
|
virtual string name() const override { return "$root"; }
|
|
|
|
|
virtual void dump(std::ostream& str) const override;
|
2018-03-10 22:51:34 +01:00
|
|
|
AstNodeModule* modulesp() const { // op1 = List of modules
|
2021-10-22 14:56:48 +02:00
|
|
|
return VN_AS(op1p(), NodeModule);
|
2020-04-15 13:58:34 +02:00
|
|
|
}
|
2021-10-22 14:56:48 +02:00
|
|
|
AstNodeModule* topModulep() const { // Top module in hierarchy
|
|
|
|
|
return modulesp(); // First one in the list, for now
|
2020-04-15 13:58:34 +02:00
|
|
|
}
|
2009-11-07 12:20:20 +01:00
|
|
|
void addModulep(AstNodeModule* modulep) { addOp1p(modulep); }
|
2021-10-22 14:56:48 +02:00
|
|
|
AstNodeFile* filesp() const { return VN_AS(op2p(), NodeFile); } // op2 = List of files
|
2020-01-22 01:54:14 +01:00
|
|
|
void addFilesp(AstNodeFile* filep) { addOp2p(filep); }
|
2012-04-29 16:14:13 +02:00
|
|
|
void addMiscsp(AstNode* nodep) { addOp3p(nodep); }
|
|
|
|
|
AstTypeTable* typeTablep() { return m_typeTablep; }
|
2021-07-23 02:50:03 +02:00
|
|
|
void changeRequest(bool specified) { m_changeRequest = specified; }
|
|
|
|
|
bool changeRequest() const { return m_changeRequest; }
|
2021-06-13 16:05:55 +02:00
|
|
|
AstConstPool* constPoolp() { return m_constPoolp; }
|
2013-01-18 00:36:20 +01:00
|
|
|
AstPackage* dollarUnitPkgp() const { return m_dollarUnitPkgp; }
|
|
|
|
|
AstPackage* dollarUnitPkgAddp() {
|
2019-05-19 22:13:13 +02:00
|
|
|
if (!m_dollarUnitPkgp) {
|
|
|
|
|
m_dollarUnitPkgp = new AstPackage(fileline(), AstPackage::dollarUnitName());
|
2020-04-15 13:58:34 +02:00
|
|
|
// packages are always libraries; don't want to make them a "top"
|
|
|
|
|
m_dollarUnitPkgp->inLibrary(true);
|
2019-05-19 22:13:13 +02:00
|
|
|
m_dollarUnitPkgp->modTrace(false); // may reconsider later
|
|
|
|
|
m_dollarUnitPkgp->internal(true);
|
|
|
|
|
addModulep(m_dollarUnitPkgp);
|
|
|
|
|
}
|
2020-04-15 13:58:34 +02:00
|
|
|
return m_dollarUnitPkgp;
|
|
|
|
|
}
|
2017-12-01 00:53:57 +01:00
|
|
|
AstCFunc* evalp() const { return m_evalp; }
|
|
|
|
|
void evalp(AstCFunc* evalp) { m_evalp = evalp; }
|
2018-07-23 02:54:28 +02:00
|
|
|
AstExecGraph* execGraphp() const { return m_execGraphp; }
|
|
|
|
|
void execGraphp(AstExecGraph* graphp) { m_execGraphp = graphp; }
|
2021-08-12 22:43:32 +02:00
|
|
|
AstVarScope* dpiExportTriggerp() const { return m_dpiExportTriggerp; }
|
|
|
|
|
void dpiExportTriggerp(AstVarScope* varScopep) { m_dpiExportTriggerp = varScopep; }
|
2021-10-17 11:29:17 +02:00
|
|
|
AstTopScope* topScopep() const { return m_topScopep; }
|
|
|
|
|
void createTopScope(AstScope* scopep) {
|
|
|
|
|
UASSERT(scopep, "Must not be nullptr");
|
|
|
|
|
UASSERT_OBJ(!m_topScopep, scopep, "TopScope already exits");
|
|
|
|
|
m_topScopep = new AstTopScope{scopep->modp()->fileline(), scopep};
|
|
|
|
|
scopep->modp()->addStmtp(v3Global.rootp()->topScopep());
|
|
|
|
|
}
|
2020-04-16 01:39:03 +02:00
|
|
|
VTimescale timeunit() const { return m_timeunit; }
|
|
|
|
|
void timeunit(const VTimescale& value) { m_timeunit = value; }
|
|
|
|
|
VTimescale timeprecision() const { return m_timeprecision; }
|
|
|
|
|
void timeInit() {
|
|
|
|
|
m_timeunit = v3Global.opt.timeDefaultUnit();
|
|
|
|
|
m_timeprecision = v3Global.opt.timeDefaultPrec();
|
|
|
|
|
}
|
|
|
|
|
void timeprecisionMerge(FileLine*, const VTimescale& value);
|
2021-01-02 00:31:27 +01:00
|
|
|
void timescaleSpecified(bool specified) { m_timescaleSpecified = specified; }
|
|
|
|
|
bool timescaleSpecified() const { return m_timescaleSpecified; }
|
2006-08-26 13:35:28 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
//######################################################################
|
|
|
|
|
|
2021-06-05 18:40:56 +02:00
|
|
|
#include "V3AstInlines.h"
|
|
|
|
|
|
2019-05-19 22:13:13 +02:00
|
|
|
#endif // Guard
|