290 lines
10 KiB
C
290 lines
10 KiB
C
|
|
// -*- mode: C++; c-file-style: "cc-mode" -*-
|
||
|
|
//*************************************************************************
|
||
|
|
// DESCRIPTION: Verilator: AstNode sub-types for functional coverage
|
||
|
|
//
|
||
|
|
// Code available from: https://verilator.org
|
||
|
|
//
|
||
|
|
//*************************************************************************
|
||
|
|
//
|
||
|
|
// This program is free software; you can redistribute it and/or modify it
|
||
|
|
// under the terms of either the GNU Lesser General Public License Version 3
|
||
|
|
// or the Perl Artistic License Version 2.0.
|
||
|
|
// SPDX-FileCopyrightText: 2026-2026 by Wilson Snyder
|
||
|
|
// SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0
|
||
|
|
//
|
||
|
|
//*************************************************************************
|
||
|
|
//
|
||
|
|
// This file contains AST nodes for SystemVerilog functional coverage
|
||
|
|
// (IEEE 1800-2023 Section 19)
|
||
|
|
//
|
||
|
|
//*************************************************************************
|
||
|
|
|
||
|
|
#ifndef VERILATOR_V3ASTNODEFUNCCOV_H_
|
||
|
|
#define VERILATOR_V3ASTNODEFUNCCOV_H_
|
||
|
|
|
||
|
|
#ifndef VERILATOR_V3AST_H_
|
||
|
|
#error "Use V3Ast.h as the include"
|
||
|
|
#include "V3Ast.h"
|
||
|
|
#define VL_NOT_FINAL
|
||
|
|
#endif
|
||
|
|
|
||
|
|
//######################################################################
|
||
|
|
// Enumerations
|
||
|
|
|
||
|
|
enum class VCoverBinsType : uint8_t {
|
||
|
|
USER,
|
||
|
|
ARRAY,
|
||
|
|
AUTO,
|
||
|
|
BINS_IGNORE, // Renamed to avoid Windows macro conflict
|
||
|
|
BINS_ILLEGAL, // Renamed to avoid Windows macro conflict
|
||
|
|
DEFAULT,
|
||
|
|
BINS_WILDCARD, // Renamed to avoid Windows macro conflict
|
||
|
|
TRANSITION
|
||
|
|
};
|
||
|
|
|
||
|
|
enum class VCoverOptionType : uint8_t {
|
||
|
|
WEIGHT,
|
||
|
|
GOAL,
|
||
|
|
AT_LEAST,
|
||
|
|
AUTO_BIN_MAX,
|
||
|
|
PER_INSTANCE,
|
||
|
|
COMMENT
|
||
|
|
};
|
||
|
|
|
||
|
|
enum class VTransRepType : uint8_t {
|
||
|
|
NONE, // No repetition
|
||
|
|
CONSEC, // Consecutive repetition [*]
|
||
|
|
GOTO, // Goto repetition [->]
|
||
|
|
NONCONS // Nonconsecutive repetition [=]
|
||
|
|
};
|
||
|
|
|
||
|
|
//######################################################################
|
||
|
|
// Base classes
|
||
|
|
|
||
|
|
class AstNodeFuncCovItem VL_NOT_FINAL : public AstNode {
|
||
|
|
protected:
|
||
|
|
string m_name;
|
||
|
|
|
||
|
|
public:
|
||
|
|
AstNodeFuncCovItem(VNType t, FileLine* fl, const string& name)
|
||
|
|
: AstNode{t, fl}
|
||
|
|
, m_name{name} {}
|
||
|
|
ASTGEN_MEMBERS_AstNodeFuncCovItem;
|
||
|
|
string name() const override VL_MT_STABLE { return m_name; }
|
||
|
|
void name(const string& flag) override { m_name = flag; }
|
||
|
|
bool maybePointedTo() const override { return true; }
|
||
|
|
};
|
||
|
|
|
||
|
|
//######################################################################
|
||
|
|
// Concrete nodes - ORDER MATTERS FOR ASTGEN!
|
||
|
|
// Must be in order: CoverBin, CoverCrossBins, CoverOption, CoverSelectExpr,
|
||
|
|
// CoverTransItem, CoverTransSet, Covergroup, CoverpointRef, CoverCross,
|
||
|
|
// Coverpoint
|
||
|
|
|
||
|
|
// Forward declarations for types used in constructors
|
||
|
|
class AstCoverTransSet;
|
||
|
|
class AstCoverSelectExpr;
|
||
|
|
|
||
|
|
class AstCoverBin final : public AstNode {
|
||
|
|
// @astgen op1 := rangesp : List[AstNode]
|
||
|
|
// @astgen op2 := iffp : Optional[AstNodeExpr]
|
||
|
|
// @astgen op3 := arraySizep : Optional[AstNodeExpr]
|
||
|
|
// @astgen op4 := transp : List[AstCoverTransSet]
|
||
|
|
string m_name;
|
||
|
|
VCoverBinsType m_type;
|
||
|
|
bool m_isArray = false;
|
||
|
|
|
||
|
|
public:
|
||
|
|
AstCoverBin(FileLine* fl, const string& name, AstNode* rangesp, bool isIgnore, bool isIllegal,
|
||
|
|
bool isWildcard = false)
|
||
|
|
: ASTGEN_SUPER_CoverBin(fl)
|
||
|
|
, m_name{name}
|
||
|
|
, m_type{isWildcard ? VCoverBinsType::BINS_WILDCARD
|
||
|
|
: (isIllegal ? VCoverBinsType::BINS_ILLEGAL
|
||
|
|
: (isIgnore ? VCoverBinsType::BINS_IGNORE
|
||
|
|
: VCoverBinsType::USER))} {
|
||
|
|
if (rangesp) addRangesp(rangesp);
|
||
|
|
}
|
||
|
|
// Constructor for automatic bins
|
||
|
|
AstCoverBin(FileLine* fl, const string& name, AstNodeExpr* arraySizep)
|
||
|
|
: ASTGEN_SUPER_CoverBin(fl)
|
||
|
|
, m_name{name}
|
||
|
|
, m_type{VCoverBinsType::AUTO}
|
||
|
|
, m_isArray{true} {
|
||
|
|
this->arraySizep(arraySizep);
|
||
|
|
}
|
||
|
|
// Constructor for default bins (catch-all)
|
||
|
|
AstCoverBin(FileLine* fl, const string& name, VCoverBinsType type)
|
||
|
|
: ASTGEN_SUPER_CoverBin(fl)
|
||
|
|
, m_name{name}
|
||
|
|
, m_type{type} {
|
||
|
|
// DEFAULT bins have no ranges - they catch everything not in other bins
|
||
|
|
}
|
||
|
|
// Constructor for transition bins
|
||
|
|
AstCoverBin(FileLine* fl, const string& name, AstCoverTransSet* transp, bool isIgnore,
|
||
|
|
bool isIllegal, bool isArrayBin = false)
|
||
|
|
: ASTGEN_SUPER_CoverBin(fl)
|
||
|
|
, m_name{name}
|
||
|
|
, m_type{isIllegal ? VCoverBinsType::BINS_ILLEGAL
|
||
|
|
: (isIgnore ? VCoverBinsType::BINS_IGNORE : VCoverBinsType::TRANSITION)}
|
||
|
|
, m_isArray{isArrayBin} {
|
||
|
|
if (transp) addTransp(transp);
|
||
|
|
}
|
||
|
|
ASTGEN_MEMBERS_AstCoverBin;
|
||
|
|
void dump(std::ostream& str) const override;
|
||
|
|
void dumpJson(std::ostream& str) const override;
|
||
|
|
string name() const override VL_MT_STABLE { return m_name; }
|
||
|
|
VCoverBinsType binsType() const { return m_type; }
|
||
|
|
bool isArray() const { return m_isArray; }
|
||
|
|
void isArray(bool flag) { m_isArray = flag; }
|
||
|
|
};
|
||
|
|
|
||
|
|
class AstCoverCrossBins final : public AstNode {
|
||
|
|
// @astgen op1 := selectp : Optional[AstCoverSelectExpr]
|
||
|
|
string m_name;
|
||
|
|
|
||
|
|
public:
|
||
|
|
AstCoverCrossBins(FileLine* fl, const string& name, AstCoverSelectExpr* selectp)
|
||
|
|
: ASTGEN_SUPER_CoverCrossBins(fl)
|
||
|
|
, m_name{name} {
|
||
|
|
this->selectp(selectp);
|
||
|
|
}
|
||
|
|
ASTGEN_MEMBERS_AstCoverCrossBins;
|
||
|
|
void dump(std::ostream& str) const override;
|
||
|
|
void dumpJson(std::ostream& str) const override;
|
||
|
|
string name() const override VL_MT_STABLE { return m_name; }
|
||
|
|
};
|
||
|
|
|
||
|
|
class AstCoverOption final : public AstNode {
|
||
|
|
// @astgen op1 := valuep : AstNodeExpr
|
||
|
|
VCoverOptionType m_type;
|
||
|
|
|
||
|
|
public:
|
||
|
|
AstCoverOption(FileLine* fl, VCoverOptionType type, AstNodeExpr* valuep)
|
||
|
|
: ASTGEN_SUPER_CoverOption(fl)
|
||
|
|
, m_type{type} {
|
||
|
|
this->valuep(valuep);
|
||
|
|
}
|
||
|
|
ASTGEN_MEMBERS_AstCoverOption;
|
||
|
|
void dump(std::ostream& str) const override;
|
||
|
|
void dumpJson(std::ostream& str) const override;
|
||
|
|
VCoverOptionType optionType() const { return m_type; }
|
||
|
|
};
|
||
|
|
|
||
|
|
class AstCoverSelectExpr final : public AstNode {
|
||
|
|
// @astgen op1 := exprp : AstNodeExpr
|
||
|
|
public:
|
||
|
|
AstCoverSelectExpr(FileLine* fl, AstNodeExpr* exprp)
|
||
|
|
: ASTGEN_SUPER_CoverSelectExpr(fl) {
|
||
|
|
this->exprp(exprp);
|
||
|
|
}
|
||
|
|
ASTGEN_MEMBERS_AstCoverSelectExpr;
|
||
|
|
void dump(std::ostream& str) const override;
|
||
|
|
void dumpJson(std::ostream& str) const override;
|
||
|
|
};
|
||
|
|
|
||
|
|
// Represents a single transition item: value or value[*N] or value[->N] or value[=N]
|
||
|
|
class AstCoverTransItem final : public AstNode {
|
||
|
|
// @astgen op1 := valuesp : List[AstNode] // Range list (values or ranges)
|
||
|
|
// @astgen op2 := repMinp : Optional[AstNodeExpr] // Repetition min count (for [*], [->], [=])
|
||
|
|
// @astgen op3 := repMaxp : Optional[AstNodeExpr] // Repetition max count (for ranges)
|
||
|
|
VTransRepType m_repType;
|
||
|
|
|
||
|
|
public:
|
||
|
|
AstCoverTransItem(FileLine* fl, AstNode* valuesp, VTransRepType repType = VTransRepType::NONE)
|
||
|
|
: ASTGEN_SUPER_CoverTransItem(fl)
|
||
|
|
, m_repType{repType} {
|
||
|
|
if (valuesp) addValuesp(valuesp);
|
||
|
|
}
|
||
|
|
ASTGEN_MEMBERS_AstCoverTransItem;
|
||
|
|
void dump(std::ostream& str) const override;
|
||
|
|
void dumpJson(std::ostream& str) const override;
|
||
|
|
VTransRepType repType() const { return m_repType; }
|
||
|
|
};
|
||
|
|
|
||
|
|
// Represents a transition set: value1 => value2 => value3
|
||
|
|
class AstCoverTransSet final : public AstNode {
|
||
|
|
// @astgen op1 := itemsp : List[AstCoverTransItem]
|
||
|
|
public:
|
||
|
|
AstCoverTransSet(FileLine* fl, AstCoverTransItem* itemsp)
|
||
|
|
: ASTGEN_SUPER_CoverTransSet(fl) {
|
||
|
|
if (itemsp) addItemsp(itemsp);
|
||
|
|
}
|
||
|
|
ASTGEN_MEMBERS_AstCoverTransSet;
|
||
|
|
void dump(std::ostream& str) const override;
|
||
|
|
void dumpJson(std::ostream& str) const override;
|
||
|
|
};
|
||
|
|
|
||
|
|
class AstCovergroup final : public AstNode {
|
||
|
|
// @astgen op1 := argsp : List[AstVar]
|
||
|
|
// @astgen op2 := membersp : List[AstNode]
|
||
|
|
// @astgen op3 := eventp : Optional[AstSenTree]
|
||
|
|
string m_name;
|
||
|
|
bool m_isClass = false;
|
||
|
|
|
||
|
|
public:
|
||
|
|
AstCovergroup(FileLine* fl, const string& name, AstNode* membersp, AstSenTree* eventp)
|
||
|
|
: ASTGEN_SUPER_Covergroup(fl)
|
||
|
|
, m_name{name} {
|
||
|
|
if (membersp) addMembersp(membersp);
|
||
|
|
this->eventp(eventp);
|
||
|
|
}
|
||
|
|
ASTGEN_MEMBERS_AstCovergroup;
|
||
|
|
void dump(std::ostream& str) const override;
|
||
|
|
void dumpJson(std::ostream& str) const override;
|
||
|
|
string name() const override VL_MT_STABLE { return m_name; }
|
||
|
|
void name(const string& name) override { m_name = name; }
|
||
|
|
bool isClass() const { return m_isClass; }
|
||
|
|
void isClass(bool flag) { m_isClass = flag; }
|
||
|
|
bool maybePointedTo() const override { return true; }
|
||
|
|
};
|
||
|
|
|
||
|
|
class AstCoverpointRef final : public AstNode {
|
||
|
|
// @astgen ptr := m_coverpointp : Optional[AstCoverpoint]
|
||
|
|
string m_name;
|
||
|
|
|
||
|
|
public:
|
||
|
|
AstCoverpointRef(FileLine* fl, const string& name)
|
||
|
|
: ASTGEN_SUPER_CoverpointRef(fl)
|
||
|
|
, m_name{name} {}
|
||
|
|
ASTGEN_MEMBERS_AstCoverpointRef;
|
||
|
|
void dump(std::ostream& str) const override;
|
||
|
|
void dumpJson(std::ostream& str) const override;
|
||
|
|
string name() const override VL_MT_STABLE { return m_name; }
|
||
|
|
AstCoverpoint* coverpointp() const { return m_coverpointp; }
|
||
|
|
void coverpointp(AstCoverpoint* nodep) { m_coverpointp = nodep; }
|
||
|
|
};
|
||
|
|
|
||
|
|
class AstCoverCross final : public AstNodeFuncCovItem {
|
||
|
|
// @astgen op1 := itemsp : List[AstCoverpointRef]
|
||
|
|
// @astgen op2 := binsp : List[AstCoverCrossBins]
|
||
|
|
// @astgen op3 := optionsp : List[AstCoverOption]
|
||
|
|
public:
|
||
|
|
AstCoverCross(FileLine* fl, const string& name, AstCoverpointRef* itemsp)
|
||
|
|
: ASTGEN_SUPER_CoverCross(fl, name) {
|
||
|
|
if (itemsp) addItemsp(itemsp);
|
||
|
|
}
|
||
|
|
ASTGEN_MEMBERS_AstCoverCross;
|
||
|
|
void dump(std::ostream& str) const override;
|
||
|
|
void dumpJson(std::ostream& str) const override;
|
||
|
|
};
|
||
|
|
|
||
|
|
class AstCoverpoint final : public AstNodeFuncCovItem {
|
||
|
|
// @astgen op1 := exprp : AstNodeExpr
|
||
|
|
// @astgen op2 := binsp : List[AstCoverBin]
|
||
|
|
// @astgen op3 := iffp : Optional[AstNodeExpr]
|
||
|
|
// @astgen op4 := optionsp : List[AstCoverOption]
|
||
|
|
public:
|
||
|
|
AstCoverpoint(FileLine* fl, const string& name, AstNodeExpr* exprp)
|
||
|
|
: ASTGEN_SUPER_Coverpoint(fl, name) {
|
||
|
|
this->exprp(exprp);
|
||
|
|
}
|
||
|
|
ASTGEN_MEMBERS_AstCoverpoint;
|
||
|
|
void dump(std::ostream& str) const override;
|
||
|
|
void dumpJson(std::ostream& str) const override;
|
||
|
|
};
|
||
|
|
|
||
|
|
//######################################################################
|
||
|
|
|
||
|
|
#endif // Guard
|