mirror of
https://github.com/verilator/verilator.git
synced 2024-12-28 18:27:34 +00:00
Support extern constraint
This commit is contained in:
parent
6e204ed0dd
commit
a2f327f729
2
Changes
2
Changes
@ -19,7 +19,7 @@ Verilator 5.031 devel
|
||||
* Support parameter names in pattern initialization (#5593) (#5596). [Greg Davill]
|
||||
* Support randomize size constraints with restrictions (#5582 partial) (#5611). [Ryszard Rozak, Antmicro Ltd.]
|
||||
* Support `default disable iff` and `$inferred_disable` (#4016). [Srinivasan Venkataramanan]
|
||||
* Support `pure constraint`.
|
||||
* Support `extern constraint` and `pure constraint`.
|
||||
* Add `--no-std-waiver` and default reading of standard lint waivers file (#5607).
|
||||
* Add `--no-std-package` as subset-alias of `--no-std` (#5607).
|
||||
* Add `lint_off --contents` in configuration files (#5606).
|
||||
|
@ -68,8 +68,6 @@ class AstNodeFTask VL_NOT_FINAL : public AstNode {
|
||||
bool m_taskPublic : 1; // Public task
|
||||
bool m_attrIsolateAssign : 1; // User isolate_assignments attribute
|
||||
bool m_classMethod : 1; // Class method
|
||||
bool m_externProto : 1; // Extern prototype
|
||||
bool m_externDef : 1; // Extern definition
|
||||
bool m_prototype : 1; // Just a prototype
|
||||
bool m_dpiExport : 1; // DPI exported
|
||||
bool m_dpiImport : 1; // DPI imported
|
||||
@ -77,6 +75,8 @@ class AstNodeFTask VL_NOT_FINAL : public AstNode {
|
||||
bool m_dpiOpenChild : 1; // DPI import open array child wrapper
|
||||
bool m_dpiTask : 1; // DPI import task (vs. void function)
|
||||
bool m_isConstructor : 1; // Class constructor
|
||||
bool m_isExternProto : 1; // Extern prototype
|
||||
bool m_isExternDef : 1; // Extern definition
|
||||
bool m_isHideLocal : 1; // Verilog local
|
||||
bool m_isHideProtected : 1; // Verilog protected
|
||||
bool m_dpiPure : 1; // DPI import pure (vs. virtual pure)
|
||||
@ -97,8 +97,6 @@ protected:
|
||||
, m_taskPublic{false}
|
||||
, m_attrIsolateAssign{false}
|
||||
, m_classMethod{false}
|
||||
, m_externProto{false}
|
||||
, m_externDef{false}
|
||||
, m_prototype{false}
|
||||
, m_dpiExport{false}
|
||||
, m_dpiImport{false}
|
||||
@ -106,6 +104,8 @@ protected:
|
||||
, m_dpiOpenChild{false}
|
||||
, m_dpiTask{false}
|
||||
, m_isConstructor{false}
|
||||
, m_isExternProto{false}
|
||||
, m_isExternDef{false}
|
||||
, m_isHideLocal{false}
|
||||
, m_isHideProtected{false}
|
||||
, m_dpiPure{false}
|
||||
@ -144,10 +144,10 @@ public:
|
||||
void attrIsolateAssign(bool flag) { m_attrIsolateAssign = flag; }
|
||||
bool classMethod() const { return m_classMethod; }
|
||||
void classMethod(bool flag) { m_classMethod = flag; }
|
||||
bool isExternProto() const { return m_externProto; }
|
||||
void isExternProto(bool flag) { m_externProto = flag; }
|
||||
bool isExternDef() const { return m_externDef; }
|
||||
void isExternDef(bool flag) { m_externDef = flag; }
|
||||
bool isExternProto() const { return m_isExternProto; }
|
||||
void isExternProto(bool flag) { m_isExternProto = flag; }
|
||||
bool isExternDef() const { return m_isExternDef; }
|
||||
void isExternDef(bool flag) { m_isExternDef = flag; }
|
||||
bool prototype() const { return m_prototype; }
|
||||
void prototype(bool flag) { m_prototype = flag; }
|
||||
bool dpiExport() const { return m_dpiExport; }
|
||||
@ -1021,7 +1021,12 @@ public:
|
||||
class AstConstraint final : public AstNode {
|
||||
// Constraint
|
||||
// @astgen op1 := itemsp : List[AstNode]
|
||||
// @astgen op2 := classOrPackagep : Optional[AstNode]
|
||||
string m_name; // Name of constraint
|
||||
VBaseOverride m_baseOverride; // BaseOverride (inital/final/extends)
|
||||
bool m_isExternDef = false; // Extern prototype definition
|
||||
bool m_isExternExplicit = false; // Explicit prototype declaration (has extern)
|
||||
bool m_isExternProto = false; // Prototype declaration (implicit or explicit)
|
||||
bool m_isKwdPure = false; // Pure constraint
|
||||
bool m_isStatic = false; // Static constraint
|
||||
public:
|
||||
@ -1038,6 +1043,14 @@ public:
|
||||
bool isPredictOptimizable() const override { return false; }
|
||||
bool maybePointedTo() const override VL_MT_SAFE { return true; }
|
||||
bool sameNode(const AstNode* /*samep*/) const override { return true; }
|
||||
void baseOverride(const VBaseOverride& flag) { m_baseOverride = flag; }
|
||||
VBaseOverride baseOverride() const { return m_baseOverride; }
|
||||
bool isExternDef() const { return m_isExternDef; }
|
||||
void isExternDef(bool flag) { m_isExternDef = flag; }
|
||||
void isExternExplicit(bool flag) { m_isExternExplicit = flag; }
|
||||
bool isExternExplicit() const { return m_isExternExplicit; }
|
||||
void isExternProto(bool flag) { m_isExternProto = flag; }
|
||||
bool isExternProto() const { return m_isExternProto; }
|
||||
void isKwdPure(bool flag) { m_isKwdPure = flag; }
|
||||
bool isKwdPure() const { return m_isKwdPure; }
|
||||
void isStatic(bool flag) { m_isStatic = flag; }
|
||||
|
@ -368,12 +368,21 @@ void AstConsQueue::dumpJson(std::ostream& str) const {
|
||||
}
|
||||
void AstConstraint::dump(std::ostream& str) const {
|
||||
this->AstNode::dump(str);
|
||||
if (isExternDef()) str << " [EXTDEF]";
|
||||
if (isExternExplicit())
|
||||
str << " [PROTOEXP]";
|
||||
else if (isExternProto())
|
||||
str << " [PROTO]";
|
||||
if (isKwdPure()) str << " [KWDPURE]";
|
||||
if (isStatic()) str << " [STATIC]";
|
||||
}
|
||||
void AstConstraint::dumpJson(std::ostream& str) const {
|
||||
dumpJsonBoolFunc(str, isExternDef);
|
||||
dumpJsonBoolFunc(str, isExternExplicit);
|
||||
dumpJsonBoolFunc(str, isExternProto);
|
||||
dumpJsonBoolFunc(str, isKwdPure);
|
||||
dumpJsonBoolFunc(str, isStatic);
|
||||
if (baseOverride().isAny()) dumpJsonStr(str, "baseOverride", baseOverride().ascii());
|
||||
dumpJsonGen(str);
|
||||
}
|
||||
void AstConstraintExpr::dump(std::ostream& str) const {
|
||||
@ -1657,9 +1666,11 @@ void AstCellInlineScope::dumpJson(std::ostream& str) const {
|
||||
dumpJsonGen(str);
|
||||
}
|
||||
bool AstClass::isCacheableChild(const AstNode* nodep) {
|
||||
return (VN_IS(nodep, Var) || VN_IS(nodep, Constraint) || VN_IS(nodep, EnumItemRef)
|
||||
|| (VN_IS(nodep, NodeFTask) && !VN_AS(nodep, NodeFTask)->isExternProto())
|
||||
|| VN_IS(nodep, CFunc));
|
||||
return VN_IS(nodep, Var)
|
||||
|| (VN_IS(nodep, Constraint) && !VN_AS(nodep, Constraint)->isExternProto())
|
||||
|| VN_IS(nodep, EnumItemRef)
|
||||
|| (VN_IS(nodep, NodeFTask) && !VN_AS(nodep, NodeFTask)->isExternProto())
|
||||
|| VN_IS(nodep, CFunc);
|
||||
}
|
||||
AstClass* AstClass::baseMostClassp() {
|
||||
AstClass* basep = this;
|
||||
@ -2652,6 +2663,8 @@ void AstNodeFTask::dump(std::ostream& str) const {
|
||||
if (dpiImport()) str << " [DPII]";
|
||||
if (dpiOpenChild()) str << " [DPIOPENCHILD]";
|
||||
if (dpiOpenParent()) str << " [DPIOPENPARENT]";
|
||||
if (isExternDef()) str << " [EXTDEF]";
|
||||
if (isExternProto()) str << " [EXTPROTO]";
|
||||
if (prototype()) str << " [PROTOTYPE]";
|
||||
if (pureVirtual()) str << " [PUREVIRTUAL]";
|
||||
if (recursive()) str << " [RECURSIVE]";
|
||||
@ -2689,6 +2702,8 @@ void AstNodeFTask::dumpJson(std::ostream& str) const {
|
||||
dumpJsonBoolFunc(str, dpiImport);
|
||||
dumpJsonBoolFunc(str, dpiOpenChild);
|
||||
dumpJsonBoolFunc(str, dpiOpenParent);
|
||||
dumpJsonBoolFunc(str, isExternDef);
|
||||
dumpJsonBoolFunc(str, isExternProto);
|
||||
dumpJsonBoolFunc(str, prototype);
|
||||
dumpJsonBoolFunc(str, recursive);
|
||||
dumpJsonBoolFunc(str, taskPublic);
|
||||
|
@ -1207,8 +1207,7 @@ class LinkDotFindVisitor final : public VNVisitor {
|
||||
m_classOrPackagep = VN_AS(m_curSymp->nodep(), Class);
|
||||
}
|
||||
// Create symbol table for the task's vars
|
||||
const string name
|
||||
= std::string{nodep->isExternProto() ? "extern " : ""} + nodep->name();
|
||||
const string name = (nodep->isExternProto() ? "extern "s : ""s) + nodep->name();
|
||||
m_curSymp = m_statep->insertBlock(m_curSymp, name, nodep, m_classOrPackagep);
|
||||
m_curSymp->fallbackp(upSymp);
|
||||
// Convert the func's range to the output variable
|
||||
@ -1299,7 +1298,35 @@ class LinkDotFindVisitor final : public VNVisitor {
|
||||
}
|
||||
void visit(AstConstraint* nodep) override {
|
||||
VL_RESTORER(m_curSymp);
|
||||
m_curSymp = m_statep->insertBlock(m_curSymp, nodep->name(), nodep, m_classOrPackagep);
|
||||
// Change to appropriate package if extern declaration (vs definition)
|
||||
VSymEnt* upSymp = m_curSymp;
|
||||
if (nodep->classOrPackagep()) {
|
||||
AstClassOrPackageRef* const cpackagerefp
|
||||
= VN_CAST(nodep->classOrPackagep(), ClassOrPackageRef);
|
||||
if (!cpackagerefp) {
|
||||
nodep->v3warn(E_UNSUPPORTED,
|
||||
"Unsupported: extern constraint definition with class-in-class");
|
||||
} else {
|
||||
if (!cpackagerefp->classOrPackageSkipp()) {
|
||||
m_statep->resolveClassOrPackage(m_curSymp, cpackagerefp, false,
|
||||
"External definition :: reference");
|
||||
}
|
||||
AstClass* const classp = VN_CAST(cpackagerefp->classOrPackageSkipp(), Class);
|
||||
if (!classp) {
|
||||
nodep->v3error("Extern declaration's scope is not a defined class");
|
||||
} else {
|
||||
m_curSymp = m_statep->getNodeSym(classp);
|
||||
upSymp = m_curSymp;
|
||||
// Move it to proper spot under the target class
|
||||
nodep->unlinkFrBack();
|
||||
classp->addStmtsp(nodep);
|
||||
nodep->classOrPackagep()->unlinkFrBack()->deleteTree();
|
||||
}
|
||||
}
|
||||
}
|
||||
// Set the class as package for iteration
|
||||
const string name = (nodep->isExternProto() ? "extern "s : ""s) + nodep->name();
|
||||
m_curSymp = m_statep->insertBlock(upSymp, name, nodep, m_classOrPackagep);
|
||||
iterateChildren(nodep);
|
||||
}
|
||||
void visit(AstVar* nodep) override {
|
||||
@ -3287,6 +3314,31 @@ class LinkDotResolveVisitor final : public VNVisitor {
|
||||
UINFO(9, indent() << "set sym " << m_ds.ascii() << endl);
|
||||
}
|
||||
}
|
||||
void visit(AstConstraint* nodep) override {
|
||||
LINKDOT_VISIT_START();
|
||||
UINFO(5, indent() << "visit " << nodep << endl);
|
||||
checkNoDot(nodep);
|
||||
if (nodep->isExternDef()) {
|
||||
if (const VSymEnt* const foundp
|
||||
= m_curSymp->findIdFallback("extern " + nodep->name())) {
|
||||
const AstConstraint* const protop = VN_AS(foundp->nodep(), Constraint);
|
||||
// Copy specifiers.
|
||||
// External definition cannot have any specifiers, so no value will be overwritten.
|
||||
nodep->isStatic(protop->isStatic());
|
||||
} else {
|
||||
nodep->v3error("extern not found that declares " + nodep->prettyNameQ());
|
||||
}
|
||||
}
|
||||
if (nodep->isExternProto()) {
|
||||
if (!m_curSymp->findIdFallback(nodep->name()) && !nodep->isExternExplicit()) {
|
||||
nodep->v3error("Definition not found for extern " + nodep->prettyNameQ());
|
||||
}
|
||||
}
|
||||
VL_RESTORER(m_curSymp);
|
||||
VL_RESTORER(m_ds);
|
||||
m_ds.m_dotSymp = m_curSymp = m_statep->getNodeSym(nodep);
|
||||
iterateChildren(nodep);
|
||||
}
|
||||
void visit(AstConstraintRef* nodep) override {
|
||||
if (nodep->user3SetOnce()) return;
|
||||
LINKDOT_VISIT_START();
|
||||
@ -3819,14 +3871,14 @@ class LinkDotResolveVisitor final : public VNVisitor {
|
||||
if (nodep->isExternDef()) {
|
||||
if (const VSymEnt* const foundp
|
||||
= m_curSymp->findIdFallback("extern " + nodep->name())) {
|
||||
const AstNodeFTask* const funcProtop = VN_AS(foundp->nodep(), NodeFTask);
|
||||
const AstNodeFTask* const protop = VN_AS(foundp->nodep(), NodeFTask);
|
||||
// Copy specifiers.
|
||||
// External definition cannot have any specifiers, so no value will be overwritten.
|
||||
nodep->isHideLocal(funcProtop->isHideLocal());
|
||||
nodep->isHideProtected(funcProtop->isHideProtected());
|
||||
nodep->isStatic(funcProtop->isStatic());
|
||||
nodep->isVirtual(funcProtop->isVirtual());
|
||||
nodep->lifetime(funcProtop->lifetime());
|
||||
nodep->isHideLocal(protop->isHideLocal());
|
||||
nodep->isHideProtected(protop->isHideProtected());
|
||||
nodep->isStatic(protop->isStatic());
|
||||
nodep->isVirtual(protop->isVirtual());
|
||||
nodep->lifetime(protop->lifetime());
|
||||
} else {
|
||||
nodep->v3error("extern not found that declares " + nodep->prettyNameQ());
|
||||
}
|
||||
|
@ -72,6 +72,16 @@ class LinkResolveVisitor final : public VNVisitor {
|
||||
m_classp = nodep;
|
||||
iterateChildren(nodep);
|
||||
}
|
||||
void visit(AstConstraint* nodep) override {
|
||||
// V3LinkDot moved the isExternDef into the class, the extern proto was
|
||||
// checked to exist, and now isn't needed
|
||||
nodep->isExternDef(false);
|
||||
if (nodep->isExternProto()) {
|
||||
VL_DO_DANGLING(nodep->unlinkFrBack()->deleteTree(), nodep);
|
||||
return;
|
||||
}
|
||||
iterateChildren(nodep);
|
||||
}
|
||||
void visit(AstInitialAutomatic* nodep) override {
|
||||
iterateChildren(nodep);
|
||||
// Initial assignments under function/tasks can just be simple
|
||||
|
@ -4181,7 +4181,6 @@ function_subroutine_callNoMethod<nodeExprp>: // IEEE: function_subroutine
|
||||
// // We implement randomize as a normal funcRef, since randomize isn't a keyword
|
||||
// // Note yNULL is already part of expressions, so they come for free
|
||||
| funcRef yWITH__CUR constraint_block { $$ = new AstWithParse{$2, $1, $3}; }
|
||||
| funcRef yWITH__CUR '{' '}' { $$ = new AstWithParse{$2, $1, nullptr}; }
|
||||
;
|
||||
|
||||
system_t_call<nodeStmtp>: // IEEE: system_tf_call (as task)
|
||||
@ -7418,17 +7417,16 @@ memberQualOne<qualifiers>: // IEEE: property_qualifier + me
|
||||
class_constraint<constraintp>: // ==IEEE: class_constraint
|
||||
// // IEEE: constraint_declaration
|
||||
constraintStaticE yCONSTRAINT dynamic_override_specifiersE constraintIdNew constraint_block
|
||||
{ $$ = $4; $$->isStatic($1); $$->addItemsp($5); SYMP->popScope($$); }
|
||||
| constraintStaticE yCONSTRAINT dynamic_override_specifiersE constraintIdNew '{' '}'
|
||||
{ $$ = $4; $$->isStatic($1); SYMP->popScope($$); }
|
||||
{ $$ = $4; $$->isStatic($1); $$->baseOverride($3); $$->addItemsp($5); SYMP->popScope($$); }
|
||||
// // IEEE: constraint_prototype + constraint_prototype_qualifier
|
||||
| constraintStaticE yCONSTRAINT dynamic_override_specifiersE constraintIdNew ';'
|
||||
{ $$ = $4; $$->isStatic($1); SYMP->popScope($$); }
|
||||
| yEXTERN constraintStaticE yCONSTRAINT constraintIdNew ';'
|
||||
{ $$ = $4; $$->isStatic($1); SYMP->popScope($4);
|
||||
BBUNSUP($1, "Unsupported: extern constraint"); }
|
||||
{ $$ = $4; $$->isStatic($1); $$->baseOverride($3);
|
||||
$$->isExternProto(true); SYMP->popScope($$); }
|
||||
| yEXTERN constraintStaticE yCONSTRAINT dynamic_override_specifiersE constraintIdNew ';'
|
||||
{ $$ = $5; $$->isStatic($2); $$->baseOverride($4);
|
||||
$$->isExternProto(true); $$->isExternExplicit(true); SYMP->popScope($$); }
|
||||
| yPURE constraintStaticE yCONSTRAINT constraintIdNew ';'
|
||||
{ $$ = $4; $$->isKwdPure($1); $$->isStatic($1); SYMP->popScope($4); }
|
||||
{ $$ = $4; $$->isKwdPure($1); $$->isStatic($2); SYMP->popScope($4); }
|
||||
;
|
||||
|
||||
constraintIdNew<constraintp>: // IEEE: id part of class_constraint
|
||||
@ -7438,7 +7436,8 @@ constraintIdNew<constraintp>: // IEEE: id part of class_constraint
|
||||
;
|
||||
|
||||
constraint_block<nodep>: // ==IEEE: constraint_block
|
||||
'{' constraint_block_itemList '}' { $$ = $2; }
|
||||
'{' '}' { $$ = nullptr; }
|
||||
| '{' constraint_block_itemList '}' { $$ = $2; }
|
||||
//
|
||||
| '{' error '}' { $$ = nullptr; }
|
||||
| '{' constraint_block_itemList error '}' { $$ = $2; }
|
||||
@ -7529,9 +7528,10 @@ dist_item<distItemp>: // ==IEEE: dist_item + dist_weight
|
||||
$$ = nullptr; }
|
||||
;
|
||||
|
||||
extern_constraint_declaration<nodep>: // ==IEEE: extern_constraint_declaration
|
||||
constraintStaticE yCONSTRAINT dynamic_override_specifiersE packageClassScopeE idAny constraint_block
|
||||
{ $$ = nullptr; BBUNSUP($<fl>2, "Unsupported: extern constraint"); }
|
||||
extern_constraint_declaration<constraintp>: // ==IEEE: extern_constraint_declaration
|
||||
constraintStaticE yCONSTRAINT dynamic_override_specifiersE packageClassScopeE constraintIdNew constraint_block
|
||||
{ $$ = $5; $$->isStatic($1); $$->isExternDef(true);
|
||||
$$->baseOverride($3); $$->classOrPackagep($4); $$->addItemsp($6); SYMP->popScope($5); }
|
||||
;
|
||||
|
||||
constraintStaticE<cbool>: // IEEE: part of extern_constraint_declaration
|
||||
|
@ -9,6 +9,8 @@ class Packet;
|
||||
|
||||
constraint a { one > 0 && one < 2; }
|
||||
|
||||
constraint empty { }
|
||||
|
||||
endclass
|
||||
|
||||
module t (/*AUTOARG*/);
|
||||
|
21
test_regress/t/t_constraint_extern.py
Executable file
21
test_regress/t/t_constraint_extern.py
Executable file
@ -0,0 +1,21 @@
|
||||
#!/usr/bin/env python3
|
||||
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
|
||||
#
|
||||
# Copyright 2024 by Wilson Snyder. 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-License-Identifier: LGPL-3.0-only OR Artistic-2.0
|
||||
|
||||
import vltest_bootstrap
|
||||
|
||||
test.scenarios('simulator')
|
||||
|
||||
if not test.have_solver:
|
||||
test.skip("No constraint solver installed")
|
||||
|
||||
test.compile(verilator_flags2=['-Wno-CONSTRAINTIGN'])
|
||||
|
||||
test.execute()
|
||||
|
||||
test.passes()
|
41
test_regress/t/t_constraint_extern.v
Normal file
41
test_regress/t/t_constraint_extern.v
Normal file
@ -0,0 +1,41 @@
|
||||
// DESCRIPTION: Verilator: Verilog Test module
|
||||
//
|
||||
// This file ONLY is placed under the Creative Commons Public Domain, for
|
||||
// any use, without warranty, 2024 by Wilson Snyder.
|
||||
// SPDX-License-Identifier: CC0-1.0
|
||||
|
||||
class Packet;
|
||||
rand int one;
|
||||
rand int two;
|
||||
|
||||
extern function void f();
|
||||
constraint cone;
|
||||
extern constraint ctwo;
|
||||
extern constraint cmissing; // Ok per IEEE 1800-2023 18.5.1
|
||||
|
||||
endclass
|
||||
|
||||
constraint Packet::cone { one > 0 && one < 2; }
|
||||
|
||||
constraint Packet::ctwo { two > 1 && two < 3; }
|
||||
|
||||
function void Packet::f();
|
||||
endfunction
|
||||
|
||||
module t (/*AUTOARG*/);
|
||||
|
||||
Packet p;
|
||||
|
||||
int v;
|
||||
|
||||
initial begin
|
||||
p = new;
|
||||
v = p.randomize();
|
||||
if (v != 1) $stop;
|
||||
if (p.one != 1) $stop;
|
||||
if (p.two != 2) $stop;
|
||||
|
||||
$write("*-* All Finished *-*\n");
|
||||
$finish;
|
||||
end
|
||||
endmodule
|
7
test_regress/t/t_constraint_extern_bad.out
Normal file
7
test_regress/t/t_constraint_extern_bad.out
Normal file
@ -0,0 +1,7 @@
|
||||
%Error: t/t_constraint_extern_bad.v:8:15: Definition not found for extern 'missing_bad'
|
||||
8 | constraint missing_bad;
|
||||
| ^~~~~~~~~~~
|
||||
%Error: t/t_constraint_extern_bad.v:11:20: extern not found that declares 'missing_extern'
|
||||
11 | constraint Packet::missing_extern { }
|
||||
| ^~~~~~~~~~~~~~
|
||||
%Error: Exiting due to
|
@ -9,8 +9,8 @@
|
||||
|
||||
import vltest_bootstrap
|
||||
|
||||
test.scenarios('vlt')
|
||||
test.scenarios('linter')
|
||||
|
||||
test.lint(fails=True, expect_filename=test.golden_filename)
|
||||
test.lint(fails=test.vlt_all, expect_filename=test.golden_filename)
|
||||
|
||||
test.passes()
|
14
test_regress/t/t_constraint_extern_bad.v
Normal file
14
test_regress/t/t_constraint_extern_bad.v
Normal file
@ -0,0 +1,14 @@
|
||||
// DESCRIPTION: Verilator: Verilog Test module
|
||||
//
|
||||
// This file ONLY is placed under the Creative Commons Public Domain, for
|
||||
// any use, without warranty, 2024 by Wilson Snyder.
|
||||
// SPDX-License-Identifier: CC0-1.0
|
||||
|
||||
class Packet;
|
||||
constraint missing_bad;
|
||||
endclass
|
||||
|
||||
constraint Packet::missing_extern { }
|
||||
|
||||
module t (/*AUTOARG*/);
|
||||
endmodule
|
@ -27,7 +27,7 @@
|
||||
{"type":"VAR","name":"if_state_ok","addr":"(W)","loc":"d,13:13,13:24","dtypep":"(U)","origName":"if_state_ok","isSc":false,"isPrimaryIO":false,"direction":"NONE","isConst":false,"isPullup":false,"isPulldown":false,"isUsedClock":false,"isSigPublic":false,"isLatched":false,"isUsedLoopIdx":false,"noReset":false,"attrIsolateAssign":false,"attrFileDescr":false,"isDpiOpenArray":false,"isFuncReturn":false,"isFuncLocal":false,"attrClocker":"UNKNOWN","lifetime":"VAUTOM","varType":"MEMBER","dtypeName":"bit","isSigUserRdPublic":false,"isSigUserRWPublic":false,"isGParam":false,"isParam":false,"attrScBv":false,"attrSFormat":false,"sensIfacep":"UNLINKED","childDTypep": [],"delayp": [],"valuep": [],"attrsp": []},
|
||||
{"type":"VAR","name":"array","addr":"(X)","loc":"d,15:13,15:18","dtypep":"(Y)","origName":"array","isSc":false,"isPrimaryIO":false,"direction":"NONE","isConst":false,"isPullup":false,"isPulldown":false,"isUsedClock":false,"isSigPublic":false,"isLatched":false,"isUsedLoopIdx":false,"noReset":false,"attrIsolateAssign":false,"attrFileDescr":false,"isDpiOpenArray":false,"isFuncReturn":false,"isFuncLocal":false,"attrClocker":"UNKNOWN","lifetime":"VAUTOM","varType":"MEMBER","dtypeName":"","isSigUserRdPublic":false,"isSigUserRWPublic":false,"isGParam":false,"isParam":false,"attrScBv":false,"attrSFormat":false,"sensIfacep":"UNLINKED","childDTypep": [],"delayp": [],"valuep": [],"attrsp": []},
|
||||
{"type":"VAR","name":"state","addr":"(Z)","loc":"d,17:11,17:16","dtypep":"(M)","origName":"state","isSc":false,"isPrimaryIO":false,"direction":"NONE","isConst":false,"isPullup":false,"isPulldown":false,"isUsedClock":false,"isSigPublic":false,"isLatched":false,"isUsedLoopIdx":false,"noReset":false,"attrIsolateAssign":false,"attrFileDescr":false,"isDpiOpenArray":false,"isFuncReturn":false,"isFuncLocal":false,"attrClocker":"UNKNOWN","lifetime":"VAUTOM","varType":"MEMBER","dtypeName":"string","isSigUserRdPublic":false,"isSigUserRWPublic":false,"isGParam":false,"isParam":false,"attrScBv":false,"attrSFormat":false,"sensIfacep":"UNLINKED","childDTypep": [],"delayp": [],"valuep": [],"attrsp": []},
|
||||
{"type":"FUNC","name":"strings_equal","addr":"(AB)","loc":"d,61:17,61:30","dtypep":"(U)","method":true,"dpiExport":false,"dpiImport":false,"dpiOpenChild":false,"dpiOpenParent":false,"prototype":false,"recursive":false,"taskPublic":false,"cname":"strings_equal",
|
||||
{"type":"FUNC","name":"strings_equal","addr":"(AB)","loc":"d,61:17,61:30","dtypep":"(U)","method":true,"dpiExport":false,"dpiImport":false,"dpiOpenChild":false,"dpiOpenParent":false,"isExternDef":false,"isExternProto":false,"prototype":false,"recursive":false,"taskPublic":false,"cname":"strings_equal",
|
||||
"fvarp": [
|
||||
{"type":"VAR","name":"strings_equal","addr":"(BB)","loc":"d,61:17,61:30","dtypep":"(U)","origName":"strings_equal","isSc":false,"isPrimaryIO":false,"direction":"OUTPUT","isConst":false,"isPullup":false,"isPulldown":false,"isUsedClock":false,"isSigPublic":false,"isLatched":false,"isUsedLoopIdx":false,"noReset":false,"attrIsolateAssign":false,"attrFileDescr":false,"isDpiOpenArray":false,"isFuncReturn":true,"isFuncLocal":true,"attrClocker":"UNKNOWN","lifetime":"VAUTOM","varType":"MEMBER","dtypeName":"bit","isSigUserRdPublic":false,"isSigUserRWPublic":false,"isGParam":false,"isParam":false,"attrScBv":false,"attrSFormat":false,"sensIfacep":"UNLINKED","childDTypep": [],"delayp": [],"valuep": [],"attrsp": []}
|
||||
],"classOrPackagep": [],
|
||||
@ -48,7 +48,7 @@
|
||||
{"type":"VARREF","name":"strings_equal","addr":"(JB)","loc":"d,62:7,62:13","dtypep":"(U)","access":"WR","varp":"(BB)","varScopep":"UNLINKED","classOrPackagep":"UNLINKED"}
|
||||
],"timingControlp": []}
|
||||
],"scopeNamep": []},
|
||||
{"type":"FUNC","name":"new","addr":"(KB)","loc":"d,7:1,7:6","dtypep":"(LB)","method":true,"dpiExport":false,"dpiImport":false,"dpiOpenChild":false,"dpiOpenParent":false,"prototype":false,"recursive":false,"taskPublic":false,"cname":"new","fvarp": [],"classOrPackagep": [],"stmtsp": [],"scopeNamep": []},
|
||||
{"type":"FUNC","name":"new","addr":"(KB)","loc":"d,7:1,7:6","dtypep":"(LB)","method":true,"dpiExport":false,"dpiImport":false,"dpiOpenChild":false,"dpiOpenParent":false,"isExternDef":false,"isExternProto":false,"prototype":false,"recursive":false,"taskPublic":false,"cname":"new","fvarp": [],"classOrPackagep": [],"stmtsp": [],"scopeNamep": []},
|
||||
{"type":"VAR","name":"constraint","addr":"(MB)","loc":"d,7:1,7:6","dtypep":"(NB)","origName":"constraint","isSc":false,"isPrimaryIO":false,"direction":"NONE","isConst":false,"isPullup":false,"isPulldown":false,"isUsedClock":false,"isSigPublic":false,"isLatched":false,"isUsedLoopIdx":false,"noReset":false,"attrIsolateAssign":false,"attrFileDescr":false,"isDpiOpenArray":false,"isFuncReturn":false,"isFuncLocal":false,"attrClocker":"UNKNOWN","lifetime":"NONE","varType":"MEMBER","dtypeName":"VlRandomizer","isSigUserRdPublic":false,"isSigUserRWPublic":false,"isGParam":false,"isParam":false,"attrScBv":false,"attrSFormat":false,"sensIfacep":"UNLINKED","childDTypep": [],"delayp": [],"valuep": [],"attrsp": []}
|
||||
],"activesp": [],"extendsp": []}
|
||||
],"activesp": []}
|
||||
|
@ -3,5 +3,5 @@ Process::open: execvp(someimaginarysolver): No such file or directory
|
||||
%Warning: Unable to communicate with SAT solver, please check its installation or specify a different one in VERILATOR_SOLVER environment variable.
|
||||
... Tried: $ someimaginarysolver
|
||||
|
||||
%Error: t/t_constraint.v:23: Verilog $stop
|
||||
%Error: t/t_constraint.v:25: Verilog $stop
|
||||
Aborting...
|
||||
|
@ -17,7 +17,7 @@
|
||||
"lhsp": [
|
||||
{"type":"VARREF","name":"dotted","addr":"(X)","loc":"d,33:16,33:22","dtypep":"(S)","access":"WR","varp":"(R)","varScopep":"UNLINKED","classOrPackagep":"UNLINKED"}
|
||||
],"timingControlp": [],"strengthSpecp": []},
|
||||
{"type":"FUNC","name":"f","addr":"(Y)","loc":"d,35:13,35:14","dtypep":"(G)","method":false,"dpiExport":false,"dpiImport":false,"dpiOpenChild":false,"dpiOpenParent":false,"prototype":false,"recursive":false,"taskPublic":false,"cname":"f",
|
||||
{"type":"FUNC","name":"f","addr":"(Y)","loc":"d,35:13,35:14","dtypep":"(G)","method":false,"dpiExport":false,"dpiImport":false,"dpiOpenChild":false,"dpiOpenParent":false,"isExternDef":false,"isExternProto":false,"prototype":false,"recursive":false,"taskPublic":false,"cname":"f",
|
||||
"fvarp": [
|
||||
{"type":"VAR","name":"f","addr":"(Z)","loc":"d,35:13,35:14","dtypep":"(G)","origName":"f","isSc":false,"isPrimaryIO":false,"direction":"OUTPUT","isConst":false,"isPullup":false,"isPulldown":false,"isUsedClock":false,"isSigPublic":false,"isLatched":false,"isUsedLoopIdx":false,"noReset":false,"attrIsolateAssign":false,"attrFileDescr":false,"isDpiOpenArray":false,"isFuncReturn":true,"isFuncLocal":true,"attrClocker":"UNKNOWN","lifetime":"VAUTOM","varType":"VAR","dtypeName":"logic","isSigUserRdPublic":false,"isSigUserRWPublic":false,"isGParam":false,"isParam":false,"attrScBv":false,"attrSFormat":false,"sensIfacep":"UNLINKED","childDTypep": [],"delayp": [],"valuep": [],"attrsp": []}
|
||||
],"classOrPackagep": [],
|
||||
|
@ -1,8 +0,0 @@
|
||||
%Error-UNSUPPORTED: t/t_randomize_extern.v:17:4: Unsupported: extern constraint
|
||||
17 | extern constraint ex;
|
||||
| ^~~~~~
|
||||
... For error description see https://verilator.org/warn/UNSUPPORTED?v=latest
|
||||
%Error-UNSUPPORTED: t/t_randomize_extern.v:21:1: Unsupported: extern constraint
|
||||
21 | constraint Packet::ex { header == 2; }
|
||||
| ^~~~~~~~~~
|
||||
%Error: Exiting due to
|
@ -1,42 +0,0 @@
|
||||
// DESCRIPTION: Verilator: Verilog Test module
|
||||
//
|
||||
// This file ONLY is placed under the Creative Commons Public Domain, for
|
||||
// any use, without warranty, 2020 by Wilson Snyder.
|
||||
// SPDX-License-Identifier: CC0-1.0
|
||||
|
||||
class Base;
|
||||
pure constraint pur;
|
||||
endclass
|
||||
|
||||
class Packet extends Base;
|
||||
rand int header;
|
||||
rand int length;
|
||||
|
||||
constraint pur { length == 3; }
|
||||
|
||||
extern constraint ex;
|
||||
|
||||
endclass
|
||||
|
||||
constraint Packet::ex { header == 2; }
|
||||
|
||||
module t (/*AUTOARG*/);
|
||||
|
||||
Packet p;
|
||||
|
||||
initial begin
|
||||
|
||||
int v;
|
||||
v = p.randomize();
|
||||
if (v != 1) $stop;
|
||||
if (p.header != 2) $stop;
|
||||
if (p.length != 3) $stop;
|
||||
v = p.randomize(1);
|
||||
if (v != 1) $stop;
|
||||
if (p.header != 2) $stop;
|
||||
if (p.length != 3) $stop;
|
||||
|
||||
$write("*-* All Finished *-*\n");
|
||||
$finish;
|
||||
end
|
||||
endmodule
|
Loading…
Reference in New Issue
Block a user