Rename AstAssignAlias to AstAlias and make it derive from AstNode instead of AstNodeStmt. Replace AstAlias with AstAssignW in V3LinkDot::linkDotScope, which is the last place we need to be aware of the alias construct. Using AstAssignW dowstream enables further optimization while preserving the same functionality.
This commit is contained in:
parent
a647747260
commit
40ca0527db
|
|
@ -1,5 +1,5 @@
|
|||
.. comment: generated by t_lint_didnotconverge_bad
|
||||
.. code-block::
|
||||
|
||||
-V{t#,#} 'stl' region trigger index 1 is active: @([hybrid] b)
|
||||
-V{t#,#} 'stl' region trigger index 1 is active: @([hybrid] a)
|
||||
%Error: t/t_lint_didnotconverge_bad.v:7: Settle region did not converge.
|
||||
|
|
|
|||
|
|
@ -505,7 +505,6 @@ class ActiveVisitor final : public VNVisitor {
|
|||
const ActiveDlyVisitor dlyvisitor{nodep, ActiveDlyVisitor::CT_INITIAL};
|
||||
moveUnderSpecial<AstSenItem::Final>(nodep);
|
||||
}
|
||||
void visit(AstAssignAlias* nodep) override { moveUnderSpecial<AstSenItem::Combo>(nodep); }
|
||||
void visit(AstCoverToggle* nodep) override { moveUnderSpecial<AstSenItem::Combo>(nodep); }
|
||||
void visit(AstAssignW* nodep) override { moveUnderSpecial<AstSenItem::Combo>(nodep); }
|
||||
void visit(AstAlways* nodep) override {
|
||||
|
|
|
|||
|
|
@ -131,9 +131,6 @@ class ActiveTopVisitor final : public VNVisitor {
|
|||
void visit(AstNodeProcedure* nodep) override { // LCOV_EXCL_LINE
|
||||
nodep->v3fatalSrc("Node should have been under ACTIVE");
|
||||
}
|
||||
void visit(AstAssignAlias* nodep) override { // LCOV_EXCL_LINE
|
||||
nodep->v3fatalSrc("Node should have been under ACTIVE");
|
||||
}
|
||||
void visit(AstAssignW* nodep) override { // LCOV_EXCL_LINE
|
||||
nodep->v3fatalSrc("Node should have been under ACTIVE");
|
||||
}
|
||||
|
|
|
|||
|
|
@ -456,6 +456,21 @@ public:
|
|||
inline bool hasClocked() const;
|
||||
inline bool hasCombo() const;
|
||||
};
|
||||
class AstAlias final : public AstNode {
|
||||
// Alias (currently only used internally, not as the SV 'alias' construct).
|
||||
// All references to the LHS are treated as references to the RHS
|
||||
// If both sides are wires, there's no LHS vs RHS,
|
||||
// @astgen op1 := rhsp : AstVarRef
|
||||
// @astgen op2 := lhsp : AstVarRef
|
||||
|
||||
public:
|
||||
AstAlias(FileLine* fl, AstVarRef* lhsp, AstVarRef* rhsp)
|
||||
: ASTGEN_SUPER_Alias(fl) {
|
||||
this->lhsp(lhsp);
|
||||
this->rhsp(rhsp);
|
||||
}
|
||||
ASTGEN_MEMBERS_AstAlias;
|
||||
};
|
||||
class AstBind final : public AstNode {
|
||||
// Parents: MODULE
|
||||
// Children: CELL
|
||||
|
|
|
|||
|
|
@ -1070,19 +1070,6 @@ public:
|
|||
}
|
||||
bool brokeLhsMustBeLvalue() const override { return true; }
|
||||
};
|
||||
class AstAssignAlias final : public AstNodeAssign {
|
||||
// Like AstAssignW, but a true bidirect interconnection alias
|
||||
// If both sides are wires, there's no LHS vs RHS,
|
||||
public:
|
||||
AstAssignAlias(FileLine* fl, AstVarRef* lhsp, AstVarRef* rhsp)
|
||||
: ASTGEN_SUPER_AssignAlias(fl, reinterpret_cast<AstNodeExpr*>(lhsp),
|
||||
reinterpret_cast<AstNodeExpr*>(rhsp)) {}
|
||||
ASTGEN_MEMBERS_AstAssignAlias;
|
||||
AstNodeAssign* cloneType(AstNodeExpr* lhsp, AstNodeExpr* rhsp) override {
|
||||
V3ERROR_NA_RETURN(nullptr);
|
||||
}
|
||||
bool brokeLhsMustBeLvalue() const override { return false; }
|
||||
};
|
||||
class AstAssignDly final : public AstNodeAssign {
|
||||
public:
|
||||
AstAssignDly(FileLine* fl, AstNodeExpr* lhsp, AstNodeExpr* rhsp,
|
||||
|
|
|
|||
|
|
@ -3145,7 +3145,7 @@ class ConstVisitor final : public VNVisitor {
|
|||
if (nodep->timingControlp()) m_hasJumpDelay = true;
|
||||
if (m_doNConst && replaceNodeAssign(nodep)) return;
|
||||
}
|
||||
void visit(AstAssignAlias* nodep) override {
|
||||
void visit(AstAlias* nodep) override {
|
||||
// Don't perform any optimizations, keep the alias around
|
||||
}
|
||||
void visit(AstAssignVarScope* nodep) override {
|
||||
|
|
|
|||
|
|
@ -155,7 +155,7 @@ class EmitVBaseVisitorConst VL_NOT_FINAL : public VNVisitorConst {
|
|||
iterateAndNextConstNull(nodep->rhsp());
|
||||
puts(";\n");
|
||||
}
|
||||
void visit(AstAssignAlias* nodep) override {
|
||||
void visit(AstAlias* nodep) override {
|
||||
putbs("alias ");
|
||||
iterateAndNextConstNull(nodep->lhsp());
|
||||
putfs(nodep, " = ");
|
||||
|
|
|
|||
|
|
@ -257,9 +257,6 @@ class GateBuildVisitor final : public VNVisitorConst {
|
|||
const bool slow = VN_IS(nodep, Initial) || VN_IS(nodep, Final);
|
||||
iterateLogic(nodep, slow, nodep->isJustOneBodyStmt() ? nullptr : "Multiple Stmts");
|
||||
}
|
||||
void visit(AstAssignAlias* nodep) override { //
|
||||
iterateLogic(nodep);
|
||||
}
|
||||
void visit(AstAssignW* nodep) override { //
|
||||
iterateLogic(nodep);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -317,7 +317,7 @@ class InlineRelinkVisitor final : public VNVisitor {
|
|||
nodep->name(m_cellp->name() + "__DOT__" + nodep->name());
|
||||
iterateChildren(nodep);
|
||||
}
|
||||
void visit(AstAssignAlias* nodep) override {
|
||||
void visit(AstAlias* nodep) override {
|
||||
// Don't replace port variable in the alias
|
||||
}
|
||||
void visit(AstVarRef* nodep) override {
|
||||
|
|
@ -501,8 +501,7 @@ void connectPort(AstNodeModule* modp, AstVar* nodep, AstNodeExpr* pinExprp) {
|
|||
modp->addStmtsp(
|
||||
new AstAssignVarScope{flp, portRef(VAccess::WRITE), pinRef(VAccess::READ)});
|
||||
} else {
|
||||
modp->addStmtsp(
|
||||
new AstAssignAlias{flp, portRef(VAccess::WRITE), pinRef(VAccess::READ)});
|
||||
modp->addStmtsp(new AstAlias{flp, portRef(VAccess::WRITE), pinRef(VAccess::READ)});
|
||||
}
|
||||
// They will become the same variable, so propagate file-line and variable attributes
|
||||
pinRefp->varp()->fileline()->modifyStateInherit(flp);
|
||||
|
|
|
|||
|
|
@ -2102,18 +2102,7 @@ class LinkDotParamVisitor final : public VNVisitor {
|
|||
pinImplicitExprRecurse(nodep->lhsp());
|
||||
iterateChildren(nodep);
|
||||
}
|
||||
void visit(AstAssignAlias* nodep) override { // ParamVisitor::
|
||||
// tran gates need implicit creation
|
||||
// As VarRefs don't exist in forPrimary, sanity check
|
||||
UASSERT_OBJ(!m_statep->forPrimary(), nodep, "Assign aliases unexpected pre-dot");
|
||||
if (AstVarRef* const forrefp = VN_CAST(nodep->lhsp(), VarRef)) {
|
||||
pinImplicitExprRecurse(forrefp);
|
||||
}
|
||||
if (AstVarRef* const forrefp = VN_CAST(nodep->rhsp(), VarRef)) {
|
||||
pinImplicitExprRecurse(forrefp);
|
||||
}
|
||||
iterateChildren(nodep);
|
||||
}
|
||||
|
||||
void visit(AstImplicit* nodep) override { // ParamVisitor::
|
||||
// Unsupported gates need implicit creation
|
||||
pinImplicitExprRecurse(nodep->exprsp());
|
||||
|
|
@ -2265,15 +2254,25 @@ class LinkDotScopeVisitor final : public VNVisitor {
|
|||
symp->fallbackp(m_modSymp);
|
||||
// No recursion, we don't want to pick up variables
|
||||
}
|
||||
void visit(AstAssignAlias* nodep) override { // ScopeVisitor::
|
||||
void visit(AstAlias* nodep) override { // ScopeVisitor::
|
||||
// Track aliases created by V3Inline; if we get a VARXREF(aliased_from)
|
||||
// we'll need to replace it with a VARXREF(aliased_to)
|
||||
UINFOTREE(9, nodep, "", "alias");
|
||||
AstVarScope* const fromVscp = VN_AS(nodep->lhsp(), VarRef)->varScopep();
|
||||
AstVarScope* const toVscp = VN_AS(nodep->rhsp(), VarRef)->varScopep();
|
||||
AstVarRef* const lhsp = nodep->lhsp();
|
||||
AstVarRef* const rhsp = nodep->rhsp();
|
||||
AstVarScope* const fromVscp = lhsp->varScopep();
|
||||
AstVarScope* const toVscp = rhsp->varScopep();
|
||||
UASSERT_OBJ(fromVscp && toVscp, nodep, "Bad alias scopes");
|
||||
fromVscp->user2p(toVscp);
|
||||
iterateChildren(nodep);
|
||||
|
||||
// Replace alias with an assignment. The LHS might still be references from otuside,
|
||||
// eg throught the VPI, and is traced, so we need the value to propagate.
|
||||
// TODO: this means external writes to the LHS (e.g.: through the VPI) don't work
|
||||
AstAssignW* const newp
|
||||
= new AstAssignW{nodep->fileline(), lhsp->unlinkFrBack(), rhsp->unlinkFrBack()};
|
||||
nodep->replaceWith(newp);
|
||||
VL_DO_DANGLING(pushDeletep(nodep), nodep);
|
||||
iterateChildren(newp);
|
||||
}
|
||||
void visit(AstAssignVarScope* nodep) override { // ScopeVisitor::
|
||||
UINFO(5, "ASSIGNVARSCOPE " << nodep);
|
||||
|
|
|
|||
|
|
@ -98,7 +98,7 @@ class LinkLValueVisitor final : public VNVisitor {
|
|||
VL_RESTORER(m_setStrengthSpecified);
|
||||
{
|
||||
m_setRefLvalue = VAccess::WRITE;
|
||||
m_setContinuously = VN_IS(nodep, AssignW) || VN_IS(nodep, AssignAlias);
|
||||
m_setContinuously = VN_IS(nodep, AssignW);
|
||||
if (const AstAssignW* const assignwp = VN_CAST(nodep, AssignW)) {
|
||||
if (assignwp->strengthSpecp()) m_setStrengthSpecified = true;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -327,10 +327,7 @@ class OrderGraphBuilder final : public VNVisitor {
|
|||
nodep->v3fatalSrc("AstFinal should not need ordering");
|
||||
} // LCOV_EXCL_STOP
|
||||
|
||||
//--- Logic akin go SystemVerilog continuous assignments
|
||||
void visit(AstAssignAlias* nodep) override { //
|
||||
iterateLogic(nodep);
|
||||
}
|
||||
//--- SystemVerilog continuous assignments
|
||||
void visit(AstAssignW* nodep) override { iterateLogic(nodep); }
|
||||
|
||||
//--- Verilator concoctions
|
||||
|
|
|
|||
|
|
@ -208,7 +208,7 @@ class ScopeVisitor final : public VNVisitor {
|
|||
m_scopep->addBlocksp(clonep);
|
||||
iterateChildren(clonep); // We iterate under the *clone*
|
||||
}
|
||||
void visit(AstAssignAlias* nodep) override {
|
||||
void visit(AstAlias* nodep) override {
|
||||
// Add to list of blocks under this scope
|
||||
UINFO(4, " Move " << nodep);
|
||||
AstNode* const clonep = nodep->cloneTree(false);
|
||||
|
|
@ -353,7 +353,7 @@ class ScopeCleanupVisitor final : public VNVisitor {
|
|||
}
|
||||
|
||||
void visit(AstNodeProcedure* nodep) override { movedDeleteOrIterate(nodep); }
|
||||
void visit(AstAssignAlias* nodep) override { movedDeleteOrIterate(nodep); }
|
||||
void visit(AstAlias* nodep) override { movedDeleteOrIterate(nodep); }
|
||||
void visit(AstAssignVarScope* nodep) override { movedDeleteOrIterate(nodep); }
|
||||
void visit(AstAssignW* nodep) override { movedDeleteOrIterate(nodep); }
|
||||
void visit(AstCoverToggle* nodep) override { movedDeleteOrIterate(nodep); }
|
||||
|
|
|
|||
|
|
@ -286,7 +286,6 @@ class SliceVisitor final : public VNVisitor {
|
|||
void visit(AstNodeAssign* nodep) override {
|
||||
// Called recursively on newly created assignments
|
||||
if (nodep->user1SetOnce()) return; // Process once
|
||||
if (VN_IS(nodep, AssignAlias)) return;
|
||||
UINFOTREE(9, nodep, "", "Deslice-In");
|
||||
VL_RESTORER(m_assignError);
|
||||
VL_RESTORER(m_assignp);
|
||||
|
|
|
|||
|
|
@ -337,6 +337,7 @@ static void process() {
|
|||
V3Const::constifyAll(v3Global.rootp());
|
||||
|
||||
// Flatten hierarchy, creating a SCOPE for each module's usage as a cell
|
||||
// No more AstAlias after linkDotScope
|
||||
V3Scope::scopeAll(v3Global.rootp());
|
||||
V3LinkDot::linkDotScope(v3Global.rootp());
|
||||
|
||||
|
|
|
|||
|
|
@ -1,9 +1,11 @@
|
|||
%Warning-UNOPTFLAT: t/t_dfg_true_cycle_bad.v:10:23: Signal unoptimizable: Circular combinational logic: 'o'
|
||||
%Warning-UNOPTFLAT: t/t_dfg_true_cycle_bad.v:10:23: Signal unoptimizable: Circular combinational logic: 't.o'
|
||||
10 | output wire [9:0] o
|
||||
| ^
|
||||
... For warning description see https://verilator.org/warn/UNOPTFLAT?v=latest
|
||||
... Use "/* verilator lint_off UNOPTFLAT */" and lint_on around source to disable this message.
|
||||
t/t_dfg_true_cycle_bad.v:10:23: Example path: t.o
|
||||
t/t_dfg_true_cycle_bad.v:10:23: Example path: ASSIGNW
|
||||
t/t_dfg_true_cycle_bad.v:10:23: Example path: o
|
||||
t/t_dfg_true_cycle_bad.v:12:22: Example path: ASSIGNW
|
||||
t/t_dfg_true_cycle_bad.v:10:23: Example path: o
|
||||
t/t_dfg_true_cycle_bad.v:10:23: Example path: ASSIGNW
|
||||
t/t_dfg_true_cycle_bad.v:10:23: Example path: t.o
|
||||
%Error: Exiting due to
|
||||
|
|
|
|||
|
|
@ -14,6 +14,6 @@ test.scenarios('vlt')
|
|||
test.lint(verilator_flags2=['--stats', '--expand-limit 5'])
|
||||
|
||||
test.file_grep(test.stats, r'Optimizations, Gate excluded wide expressions\s+(\d+)', 2)
|
||||
test.file_grep(test.stats, r'Optimizations, Gate sigs deleted\s+(\d+)', 4)
|
||||
test.file_grep(test.stats, r'Optimizations, Gate sigs deleted\s+(\d+)', 0)
|
||||
|
||||
test.passes()
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ test.scenarios('vlt')
|
|||
test.lint(verilator_flags2=['--stats', '--expand-limit 5', '-fno-var-split'])
|
||||
|
||||
test.file_grep(test.stats, r'Optimizations, Gate excluded wide expressions\s+(\d+)', 1)
|
||||
test.file_grep(test.stats, r'Optimizations, Gate sigs deleted\s+(\d+)', 9)
|
||||
test.file_grep(test.stats, r'Optimizations, Gate sigs deleted\s+(\d+)', 1)
|
||||
test.file_grep(test.stats, r'SplitVar, packed variables split automatically\s+(\d+)', 0)
|
||||
|
||||
test.passes()
|
||||
|
|
|
|||
|
|
@ -14,6 +14,6 @@ test.scenarios('vlt')
|
|||
test.lint(verilator_flags2=['--stats', '--expand-limit 5'])
|
||||
|
||||
test.file_grep(test.stats, r'Optimizations, Gate excluded wide expressions\s+(\d+)', 0)
|
||||
test.file_grep(test.stats, r'Optimizations, Gate sigs deleted\s+(\d+)', 3)
|
||||
test.file_grep(test.stats, r'Optimizations, Gate sigs deleted\s+(\d+)', 0)
|
||||
|
||||
test.passes()
|
||||
|
|
|
|||
|
|
@ -2974,7 +2974,7 @@
|
|||
]},
|
||||
{"type":"REFDTYPE","name":"my_t","addr":"(VB)","loc":"d,52:12,52:16","dtypep":"(ERB)","generic":false,"typedefp":"UNLINKED","refDTypep":"(ERB)","classOrPackagep":"UNLINKED","typeofp": [],"classOrPackageOpp": [],"paramsp": []},
|
||||
{"type":"BASICDTYPE","name":"logic","addr":"(KB)","loc":"d,23:23,23:24","dtypep":"(KB)","keyword":"logic","range":"31:0","generic":true,"rangep": []},
|
||||
{"type":"VOIDDTYPE","name":"","addr":"(CB)","loc":"d,11:8,11:9","dtypep":"(CB)","generic":false},
|
||||
{"type":"VOIDDTYPE","name":"","addr":"(CB)","loc":"a,0:0,0:0","dtypep":"(CB)","generic":false},
|
||||
{"type":"BASICDTYPE","name":"VlTriggerVec","addr":"(V)","loc":"d,11:8,11:9","dtypep":"(V)","keyword":"VlTriggerVec","generic":true,"rangep": []},
|
||||
{"type":"BASICDTYPE","name":"QData","addr":"(JQ)","loc":"d,11:8,11:9","dtypep":"(JQ)","keyword":"QData","range":"63:0","generic":true,"rangep": []},
|
||||
{"type":"BASICDTYPE","name":"logic","addr":"(GQ)","loc":"d,11:8,11:9","dtypep":"(GQ)","keyword":"logic","range":"63:0","generic":true,"rangep": []},
|
||||
|
|
|
|||
|
|
@ -44,48 +44,48 @@
|
|||
{"type":"VARSCOPE","name":"t.cell2.q","addr":"(PB)","loc":"d,50:22,50:23","dtypep":"(H)","isTrace":true,"scopep":"(AB)","varp":"(Z)"}
|
||||
],
|
||||
"blocksp": [
|
||||
{"type":"ASSIGNALIAS","name":"","addr":"(QB)","loc":"d,15:22,15:23","dtypep":"(H)",
|
||||
{"type":"ASSIGNW","name":"","addr":"(QB)","loc":"d,15:22,15:23","dtypep":"(H)",
|
||||
"rhsp": [
|
||||
{"type":"VARREF","name":"q","addr":"(RB)","loc":"d,15:22,15:23","dtypep":"(H)","access":"RD","varp":"(G)","varScopep":"(BB)","classOrPackagep":"UNLINKED"}
|
||||
],
|
||||
"lhsp": [
|
||||
{"type":"VARREF","name":"t.q","addr":"(SB)","loc":"d,15:22,15:23","dtypep":"(H)","access":"WR","varp":"(L)","varScopep":"(EB)","classOrPackagep":"UNLINKED"}
|
||||
],"timingControlp": []},
|
||||
{"type":"ASSIGNALIAS","name":"","addr":"(TB)","loc":"d,13:10,13:13","dtypep":"(J)",
|
||||
],"timingControlp": [],"strengthSpecp": []},
|
||||
{"type":"ASSIGNW","name":"","addr":"(TB)","loc":"d,13:10,13:13","dtypep":"(J)",
|
||||
"rhsp": [
|
||||
{"type":"VARREF","name":"clk","addr":"(UB)","loc":"d,13:10,13:13","dtypep":"(J)","access":"RD","varp":"(I)","varScopep":"(CB)","classOrPackagep":"UNLINKED"}
|
||||
],
|
||||
"lhsp": [
|
||||
{"type":"VARREF","name":"t.clk","addr":"(VB)","loc":"d,13:10,13:13","dtypep":"(J)","access":"WR","varp":"(M)","varScopep":"(FB)","classOrPackagep":"UNLINKED"}
|
||||
],"timingControlp": []},
|
||||
{"type":"ASSIGNALIAS","name":"","addr":"(WB)","loc":"d,14:16,14:17","dtypep":"(H)",
|
||||
],"timingControlp": [],"strengthSpecp": []},
|
||||
{"type":"ASSIGNW","name":"","addr":"(WB)","loc":"d,14:16,14:17","dtypep":"(H)",
|
||||
"rhsp": [
|
||||
{"type":"VARREF","name":"d","addr":"(XB)","loc":"d,14:16,14:17","dtypep":"(H)","access":"RD","varp":"(K)","varScopep":"(DB)","classOrPackagep":"UNLINKED"}
|
||||
],
|
||||
"lhsp": [
|
||||
{"type":"VARREF","name":"t.d","addr":"(YB)","loc":"d,14:16,14:17","dtypep":"(H)","access":"WR","varp":"(N)","varScopep":"(GB)","classOrPackagep":"UNLINKED"}
|
||||
],"timingControlp": []},
|
||||
{"type":"ASSIGNALIAS","name":"","addr":"(ZB)","loc":"d,36:30,36:31","dtypep":"(H)",
|
||||
],"timingControlp": [],"strengthSpecp": []},
|
||||
{"type":"ASSIGNW","name":"","addr":"(ZB)","loc":"d,36:30,36:31","dtypep":"(H)",
|
||||
"rhsp": [
|
||||
{"type":"VARREF","name":"t.between","addr":"(AC)","loc":"d,20:14,20:21","dtypep":"(H)","access":"RD","varp":"(O)","varScopep":"(HB)","classOrPackagep":"UNLINKED"}
|
||||
],
|
||||
"lhsp": [
|
||||
{"type":"VARREF","name":"t.cell1.q","addr":"(BC)","loc":"d,36:30,36:31","dtypep":"(H)","access":"WR","varp":"(U)","varScopep":"(LB)","classOrPackagep":"UNLINKED"}
|
||||
],"timingControlp": []},
|
||||
{"type":"ASSIGNALIAS","name":"","addr":"(CC)","loc":"d,34:24,34:27","dtypep":"(J)",
|
||||
],"timingControlp": [],"strengthSpecp": []},
|
||||
{"type":"ASSIGNW","name":"","addr":"(CC)","loc":"d,34:24,34:27","dtypep":"(J)",
|
||||
"rhsp": [
|
||||
{"type":"VARREF","name":"t.clk","addr":"(DC)","loc":"d,21:42,21:45","dtypep":"(J)","access":"RD","varp":"(M)","varScopep":"(FB)","classOrPackagep":"UNLINKED"}
|
||||
],
|
||||
"lhsp": [
|
||||
{"type":"VARREF","name":"t.cell1.clk","addr":"(EC)","loc":"d,34:24,34:27","dtypep":"(J)","access":"WR","varp":"(S)","varScopep":"(JB)","classOrPackagep":"UNLINKED"}
|
||||
],"timingControlp": []},
|
||||
{"type":"ASSIGNALIAS","name":"","addr":"(FC)","loc":"d,35:30,35:31","dtypep":"(H)",
|
||||
],"timingControlp": [],"strengthSpecp": []},
|
||||
{"type":"ASSIGNW","name":"","addr":"(FC)","loc":"d,35:30,35:31","dtypep":"(H)",
|
||||
"rhsp": [
|
||||
{"type":"VARREF","name":"t.d","addr":"(GC)","loc":"d,22:42,22:43","dtypep":"(H)","access":"RD","varp":"(N)","varScopep":"(GB)","classOrPackagep":"UNLINKED"}
|
||||
],
|
||||
"lhsp": [
|
||||
{"type":"VARREF","name":"t.cell1.d","addr":"(HC)","loc":"d,35:30,35:31","dtypep":"(H)","access":"WR","varp":"(T)","varScopep":"(KB)","classOrPackagep":"UNLINKED"}
|
||||
],"timingControlp": []},
|
||||
],"timingControlp": [],"strengthSpecp": []},
|
||||
{"type":"ALWAYS","name":"","addr":"(IC)","loc":"d,41:4,41:10","keyword":"always","isSuspendable":false,"needProcess":false,
|
||||
"sentreep": [
|
||||
{"type":"SENTREE","name":"","addr":"(JC)","loc":"d,41:11,41:12","isMulti":false,
|
||||
|
|
@ -105,27 +105,27 @@
|
|||
{"type":"VARREF","name":"t.between","addr":"(OC)","loc":"d,42:6,42:7","dtypep":"(H)","access":"WR","varp":"(O)","varScopep":"(HB)","classOrPackagep":"UNLINKED"}
|
||||
],"timingControlp": []}
|
||||
]},
|
||||
{"type":"ASSIGNALIAS","name":"","addr":"(PC)","loc":"d,49:16,49:17","dtypep":"(H)",
|
||||
{"type":"ASSIGNW","name":"","addr":"(PC)","loc":"d,49:16,49:17","dtypep":"(H)",
|
||||
"rhsp": [
|
||||
{"type":"VARREF","name":"t.between","addr":"(QC)","loc":"d,25:16,25:23","dtypep":"(H)","access":"RD","varp":"(O)","varScopep":"(HB)","classOrPackagep":"UNLINKED"}
|
||||
],
|
||||
"lhsp": [
|
||||
{"type":"VARREF","name":"t.cell2.d","addr":"(RC)","loc":"d,49:16,49:17","dtypep":"(H)","access":"WR","varp":"(Y)","varScopep":"(OB)","classOrPackagep":"UNLINKED"}
|
||||
],"timingControlp": []},
|
||||
{"type":"ASSIGNALIAS","name":"","addr":"(SC)","loc":"d,50:22,50:23","dtypep":"(H)",
|
||||
],"timingControlp": [],"strengthSpecp": []},
|
||||
{"type":"ASSIGNW","name":"","addr":"(SC)","loc":"d,50:22,50:23","dtypep":"(H)",
|
||||
"rhsp": [
|
||||
{"type":"VARREF","name":"t.q","addr":"(TC)","loc":"d,26:42,26:43","dtypep":"(H)","access":"RD","varp":"(L)","varScopep":"(EB)","classOrPackagep":"UNLINKED"}
|
||||
],
|
||||
"lhsp": [
|
||||
{"type":"VARREF","name":"t.cell2.q","addr":"(UC)","loc":"d,50:22,50:23","dtypep":"(H)","access":"WR","varp":"(Z)","varScopep":"(PB)","classOrPackagep":"UNLINKED"}
|
||||
],"timingControlp": []},
|
||||
{"type":"ASSIGNALIAS","name":"","addr":"(VC)","loc":"d,48:10,48:13","dtypep":"(J)",
|
||||
],"timingControlp": [],"strengthSpecp": []},
|
||||
{"type":"ASSIGNW","name":"","addr":"(VC)","loc":"d,48:10,48:13","dtypep":"(J)",
|
||||
"rhsp": [
|
||||
{"type":"VARREF","name":"t.clk","addr":"(WC)","loc":"d,27:42,27:45","dtypep":"(J)","access":"RD","varp":"(M)","varScopep":"(FB)","classOrPackagep":"UNLINKED"}
|
||||
],
|
||||
"lhsp": [
|
||||
{"type":"VARREF","name":"t.cell2.clk","addr":"(XC)","loc":"d,48:10,48:13","dtypep":"(J)","access":"WR","varp":"(X)","varScopep":"(NB)","classOrPackagep":"UNLINKED"}
|
||||
],"timingControlp": []},
|
||||
],"timingControlp": [],"strengthSpecp": []},
|
||||
{"type":"ASSIGNW","name":"","addr":"(YC)","loc":"d,53:13,53:14","dtypep":"(H)",
|
||||
"rhsp": [
|
||||
{"type":"VARREF","name":"t.between","addr":"(ZC)","loc":"d,17:22,17:29","dtypep":"(H)","access":"RD","varp":"(O)","varScopep":"(HB)","classOrPackagep":"UNLINKED"}
|
||||
|
|
|
|||
|
|
@ -14,20 +14,20 @@
|
|||
{"type":"VARSCOPE","name":"top.f.i_clk","addr":"(N)","loc":"d,7:24,7:29","dtypep":"(H)","isTrace":true,"scopep":"(K)","varp":"(J)"}
|
||||
],
|
||||
"blocksp": [
|
||||
{"type":"ASSIGNALIAS","name":"","addr":"(O)","loc":"d,11:24,11:29","dtypep":"(H)",
|
||||
{"type":"ASSIGNW","name":"","addr":"(O)","loc":"d,11:24,11:29","dtypep":"(H)",
|
||||
"rhsp": [
|
||||
{"type":"VARREF","name":"i_clk","addr":"(P)","loc":"d,11:24,11:29","dtypep":"(H)","access":"RD","varp":"(G)","varScopep":"(L)","classOrPackagep":"UNLINKED"}
|
||||
],
|
||||
"lhsp": [
|
||||
{"type":"VARREF","name":"top.i_clk","addr":"(Q)","loc":"d,11:24,11:29","dtypep":"(H)","access":"WR","varp":"(I)","varScopep":"(M)","classOrPackagep":"UNLINKED"}
|
||||
],"timingControlp": []},
|
||||
{"type":"ASSIGNALIAS","name":"","addr":"(R)","loc":"d,7:24,7:29","dtypep":"(H)",
|
||||
],"timingControlp": [],"strengthSpecp": []},
|
||||
{"type":"ASSIGNW","name":"","addr":"(R)","loc":"d,7:24,7:29","dtypep":"(H)",
|
||||
"rhsp": [
|
||||
{"type":"VARREF","name":"top.i_clk","addr":"(S)","loc":"d,12:7,12:8","dtypep":"(H)","access":"RD","varp":"(I)","varScopep":"(M)","classOrPackagep":"UNLINKED"}
|
||||
],
|
||||
"lhsp": [
|
||||
{"type":"VARREF","name":"top.f.i_clk","addr":"(T)","loc":"d,7:24,7:29","dtypep":"(H)","access":"WR","varp":"(J)","varScopep":"(N)","classOrPackagep":"UNLINKED"}
|
||||
],"timingControlp": []}
|
||||
],"timingControlp": [],"strengthSpecp": []}
|
||||
],"inlinesp": []}
|
||||
]}
|
||||
]}
|
||||
|
|
|
|||
|
|
@ -14,20 +14,20 @@
|
|||
{"type":"VARSCOPE","name":"top.f.i_clk","addr":"(N)","loc":"d,7:24,7:29","dtypep":"(H)","isTrace":true,"scopep":"(K)","varp":"(J)"}
|
||||
],
|
||||
"blocksp": [
|
||||
{"type":"ASSIGNALIAS","name":"","addr":"(O)","loc":"d,11:24,11:29","dtypep":"(H)",
|
||||
{"type":"ASSIGNW","name":"","addr":"(O)","loc":"d,11:24,11:29","dtypep":"(H)",
|
||||
"rhsp": [
|
||||
{"type":"VARREF","name":"i_clk","addr":"(P)","loc":"d,11:24,11:29","dtypep":"(H)","access":"RD","varp":"(G)","varScopep":"(L)","classOrPackagep":"UNLINKED"}
|
||||
],
|
||||
"lhsp": [
|
||||
{"type":"VARREF","name":"top.i_clk","addr":"(Q)","loc":"d,11:24,11:29","dtypep":"(H)","access":"WR","varp":"(I)","varScopep":"(M)","classOrPackagep":"UNLINKED"}
|
||||
],"timingControlp": []},
|
||||
{"type":"ASSIGNALIAS","name":"","addr":"(R)","loc":"d,7:24,7:29","dtypep":"(H)",
|
||||
],"timingControlp": [],"strengthSpecp": []},
|
||||
{"type":"ASSIGNW","name":"","addr":"(R)","loc":"d,7:24,7:29","dtypep":"(H)",
|
||||
"rhsp": [
|
||||
{"type":"VARREF","name":"top.i_clk","addr":"(S)","loc":"d,12:7,12:8","dtypep":"(H)","access":"RD","varp":"(I)","varScopep":"(M)","classOrPackagep":"UNLINKED"}
|
||||
],
|
||||
"lhsp": [
|
||||
{"type":"VARREF","name":"top.f.i_clk","addr":"(T)","loc":"d,7:24,7:29","dtypep":"(H)","access":"WR","varp":"(J)","varScopep":"(N)","classOrPackagep":"UNLINKED"}
|
||||
],"timingControlp": []}
|
||||
],"timingControlp": [],"strengthSpecp": []}
|
||||
],"inlinesp": []}
|
||||
]}
|
||||
]}
|
||||
|
|
|
|||
|
|
@ -32,34 +32,34 @@
|
|||
{"type":"VARSCOPE","name":"__Vfunc_vlvbound_test.foo__1__i","addr":"(OB)","loc":"d,17:13,17:14","dtypep":"(GB)","isTrace":true,"scopep":"(Q)","varp":"(PB)"}
|
||||
],
|
||||
"blocksp": [
|
||||
{"type":"ASSIGNALIAS","name":"","addr":"(QB)","loc":"d,9:25,9:28","dtypep":"(H)",
|
||||
{"type":"ASSIGNW","name":"","addr":"(QB)","loc":"d,9:25,9:28","dtypep":"(H)",
|
||||
"rhsp": [
|
||||
{"type":"VARREF","name":"i_a","addr":"(RB)","loc":"d,9:25,9:28","dtypep":"(H)","access":"RD","varp":"(G)","varScopep":"(R)","classOrPackagep":"UNLINKED"}
|
||||
],
|
||||
"lhsp": [
|
||||
{"type":"VARREF","name":"vlvbound_test.i_a","addr":"(SB)","loc":"d,9:25,9:28","dtypep":"(H)","access":"WR","varp":"(M)","varScopep":"(V)","classOrPackagep":"UNLINKED"}
|
||||
],"timingControlp": []},
|
||||
{"type":"ASSIGNALIAS","name":"","addr":"(TB)","loc":"d,10:25,10:28","dtypep":"(H)",
|
||||
],"timingControlp": [],"strengthSpecp": []},
|
||||
{"type":"ASSIGNW","name":"","addr":"(TB)","loc":"d,10:25,10:28","dtypep":"(H)",
|
||||
"rhsp": [
|
||||
{"type":"VARREF","name":"i_b","addr":"(UB)","loc":"d,10:25,10:28","dtypep":"(H)","access":"RD","varp":"(I)","varScopep":"(S)","classOrPackagep":"UNLINKED"}
|
||||
],
|
||||
"lhsp": [
|
||||
{"type":"VARREF","name":"vlvbound_test.i_b","addr":"(VB)","loc":"d,10:25,10:28","dtypep":"(H)","access":"WR","varp":"(N)","varScopep":"(W)","classOrPackagep":"UNLINKED"}
|
||||
],"timingControlp": []},
|
||||
{"type":"ASSIGNALIAS","name":"","addr":"(WB)","loc":"d,11:25,11:28","dtypep":"(K)",
|
||||
],"timingControlp": [],"strengthSpecp": []},
|
||||
{"type":"ASSIGNW","name":"","addr":"(WB)","loc":"d,11:25,11:28","dtypep":"(K)",
|
||||
"rhsp": [
|
||||
{"type":"VARREF","name":"o_a","addr":"(XB)","loc":"d,11:25,11:28","dtypep":"(K)","access":"RD","varp":"(J)","varScopep":"(T)","classOrPackagep":"UNLINKED"}
|
||||
],
|
||||
"lhsp": [
|
||||
{"type":"VARREF","name":"vlvbound_test.o_a","addr":"(YB)","loc":"d,11:25,11:28","dtypep":"(K)","access":"WR","varp":"(O)","varScopep":"(X)","classOrPackagep":"UNLINKED"}
|
||||
],"timingControlp": []},
|
||||
{"type":"ASSIGNALIAS","name":"","addr":"(ZB)","loc":"d,12:25,12:28","dtypep":"(K)",
|
||||
],"timingControlp": [],"strengthSpecp": []},
|
||||
{"type":"ASSIGNW","name":"","addr":"(ZB)","loc":"d,12:25,12:28","dtypep":"(K)",
|
||||
"rhsp": [
|
||||
{"type":"VARREF","name":"o_b","addr":"(AC)","loc":"d,12:25,12:28","dtypep":"(K)","access":"RD","varp":"(L)","varScopep":"(U)","classOrPackagep":"UNLINKED"}
|
||||
],
|
||||
"lhsp": [
|
||||
{"type":"VARREF","name":"vlvbound_test.o_b","addr":"(BC)","loc":"d,12:25,12:28","dtypep":"(K)","access":"WR","varp":"(P)","varScopep":"(Y)","classOrPackagep":"UNLINKED"}
|
||||
],"timingControlp": []},
|
||||
],"timingControlp": [],"strengthSpecp": []},
|
||||
{"type":"ALWAYS","name":"","addr":"(CC)","loc":"d,24:14,24:15","keyword":"always","isSuspendable":false,"needProcess":false,"sentreep": [],
|
||||
"stmtsp": [
|
||||
{"type":"COMMENT","name":"Function: foo","addr":"(DC)","loc":"d,24:16,24:19"},
|
||||
|
|
|
|||
|
|
@ -1,3 +1,3 @@
|
|||
-V{t#,#} 'stl' region trigger index 1 is active: @([hybrid] b)
|
||||
-V{t#,#} 'stl' region trigger index 1 is active: @([hybrid] a)
|
||||
%Error: t/t_lint_didnotconverge_bad.v:7: Settle region did not converge.
|
||||
Aborting...
|
||||
|
|
|
|||
|
|
@ -13,6 +13,6 @@ test.scenarios('simulator')
|
|||
|
||||
test.compile(verilator_flags2=['--sc', '--stats'])
|
||||
|
||||
test.file_grep(test.stats, r'Optimizations, Slice array assignments\s+(\d+)', 3)
|
||||
test.file_grep(test.stats, r'Optimizations, Slice array assignments\s+(\d+)', 5)
|
||||
|
||||
test.passes()
|
||||
|
|
|
|||
|
|
@ -1826,7 +1826,7 @@
|
|||
</unpackarraydtype>
|
||||
<refdtype loc="d,52,12,52,16" id="22" name="my_t" sub_dtype_id="2"/>
|
||||
<basicdtype loc="d,23,23,23,24" id="9" name="logic" left="31" right="0" signed="true"/>
|
||||
<voiddtype loc="d,11,8,11,9" id="7"/>
|
||||
<voiddtype loc="a,0,0,0,0" id="7"/>
|
||||
<basicdtype loc="d,11,8,11,9" id="6" name="VlTriggerVec"/>
|
||||
<basicdtype loc="d,11,8,11,9" id="18" name="QData" left="63" right="0"/>
|
||||
<basicdtype loc="d,11,8,11,9" id="17" name="logic" left="63" right="0"/>
|
||||
|
|
|
|||
|
|
@ -51,30 +51,30 @@
|
|||
<varscope loc="d,48,10,48,13" name="t.cell2.clk" dtype_id="2"/>
|
||||
<varscope loc="d,49,16,49,17" name="t.cell2.d" dtype_id="1"/>
|
||||
<varscope loc="d,50,22,50,23" name="t.cell2.q" dtype_id="1"/>
|
||||
<assignalias loc="d,15,22,15,23" dtype_id="1">
|
||||
<contassign loc="d,15,22,15,23" dtype_id="1">
|
||||
<varref loc="d,15,22,15,23" name="q" dtype_id="1"/>
|
||||
<varref loc="d,15,22,15,23" name="t.q" dtype_id="1"/>
|
||||
</assignalias>
|
||||
<assignalias loc="d,13,10,13,13" dtype_id="2">
|
||||
</contassign>
|
||||
<contassign loc="d,13,10,13,13" dtype_id="2">
|
||||
<varref loc="d,13,10,13,13" name="clk" dtype_id="2"/>
|
||||
<varref loc="d,13,10,13,13" name="t.clk" dtype_id="2"/>
|
||||
</assignalias>
|
||||
<assignalias loc="d,14,16,14,17" dtype_id="1">
|
||||
</contassign>
|
||||
<contassign loc="d,14,16,14,17" dtype_id="1">
|
||||
<varref loc="d,14,16,14,17" name="d" dtype_id="1"/>
|
||||
<varref loc="d,14,16,14,17" name="t.d" dtype_id="1"/>
|
||||
</assignalias>
|
||||
<assignalias loc="d,36,30,36,31" dtype_id="1">
|
||||
</contassign>
|
||||
<contassign loc="d,36,30,36,31" dtype_id="1">
|
||||
<varref loc="d,20,14,20,21" name="t.between" dtype_id="1"/>
|
||||
<varref loc="d,36,30,36,31" name="t.cell1.q" dtype_id="1"/>
|
||||
</assignalias>
|
||||
<assignalias loc="d,34,24,34,27" dtype_id="2">
|
||||
</contassign>
|
||||
<contassign loc="d,34,24,34,27" dtype_id="2">
|
||||
<varref loc="d,21,42,21,45" name="t.clk" dtype_id="2"/>
|
||||
<varref loc="d,34,24,34,27" name="t.cell1.clk" dtype_id="2"/>
|
||||
</assignalias>
|
||||
<assignalias loc="d,35,30,35,31" dtype_id="1">
|
||||
</contassign>
|
||||
<contassign loc="d,35,30,35,31" dtype_id="1">
|
||||
<varref loc="d,22,42,22,43" name="t.d" dtype_id="1"/>
|
||||
<varref loc="d,35,30,35,31" name="t.cell1.d" dtype_id="1"/>
|
||||
</assignalias>
|
||||
</contassign>
|
||||
<always loc="d,41,4,41,10">
|
||||
<sentree loc="d,41,11,41,12">
|
||||
<senitem loc="d,41,13,41,20" edgeType="POS">
|
||||
|
|
@ -86,18 +86,18 @@
|
|||
<varref loc="d,42,6,42,7" name="t.between" dtype_id="1"/>
|
||||
</assigndly>
|
||||
</always>
|
||||
<assignalias loc="d,49,16,49,17" dtype_id="1">
|
||||
<contassign loc="d,49,16,49,17" dtype_id="1">
|
||||
<varref loc="d,25,16,25,23" name="t.between" dtype_id="1"/>
|
||||
<varref loc="d,49,16,49,17" name="t.cell2.d" dtype_id="1"/>
|
||||
</assignalias>
|
||||
<assignalias loc="d,50,22,50,23" dtype_id="1">
|
||||
</contassign>
|
||||
<contassign loc="d,50,22,50,23" dtype_id="1">
|
||||
<varref loc="d,26,42,26,43" name="t.q" dtype_id="1"/>
|
||||
<varref loc="d,50,22,50,23" name="t.cell2.q" dtype_id="1"/>
|
||||
</assignalias>
|
||||
<assignalias loc="d,48,10,48,13" dtype_id="2">
|
||||
</contassign>
|
||||
<contassign loc="d,48,10,48,13" dtype_id="2">
|
||||
<varref loc="d,27,42,27,45" name="t.clk" dtype_id="2"/>
|
||||
<varref loc="d,48,10,48,13" name="t.cell2.clk" dtype_id="2"/>
|
||||
</assignalias>
|
||||
</contassign>
|
||||
<contassign loc="d,53,13,53,14" dtype_id="1">
|
||||
<varref loc="d,17,22,17,29" name="t.between" dtype_id="1"/>
|
||||
<varref loc="d,53,13,53,14" name="q" dtype_id="1"/>
|
||||
|
|
|
|||
|
|
@ -23,14 +23,14 @@
|
|||
<varscope loc="d,11,24,11,29" name="i_clk" dtype_id="1"/>
|
||||
<varscope loc="d,11,24,11,29" name="top.i_clk" dtype_id="1"/>
|
||||
<varscope loc="d,7,24,7,29" name="top.f.i_clk" dtype_id="1"/>
|
||||
<assignalias loc="d,11,24,11,29" dtype_id="1">
|
||||
<contassign loc="d,11,24,11,29" dtype_id="1">
|
||||
<varref loc="d,11,24,11,29" name="i_clk" dtype_id="1"/>
|
||||
<varref loc="d,11,24,11,29" name="top.i_clk" dtype_id="1"/>
|
||||
</assignalias>
|
||||
<assignalias loc="d,7,24,7,29" dtype_id="1">
|
||||
</contassign>
|
||||
<contassign loc="d,7,24,7,29" dtype_id="1">
|
||||
<varref loc="d,12,7,12,8" name="top.i_clk" dtype_id="1"/>
|
||||
<varref loc="d,7,24,7,29" name="top.f.i_clk" dtype_id="1"/>
|
||||
</assignalias>
|
||||
</contassign>
|
||||
</scope>
|
||||
</topscope>
|
||||
</module>
|
||||
|
|
|
|||
|
|
@ -23,14 +23,14 @@
|
|||
<varscope loc="d,11,24,11,29" name="i_clk" dtype_id="1"/>
|
||||
<varscope loc="d,11,24,11,29" name="top.i_clk" dtype_id="1"/>
|
||||
<varscope loc="d,7,24,7,29" name="top.f.i_clk" dtype_id="1"/>
|
||||
<assignalias loc="d,11,24,11,29" dtype_id="1">
|
||||
<contassign loc="d,11,24,11,29" dtype_id="1">
|
||||
<varref loc="d,11,24,11,29" name="i_clk" dtype_id="1"/>
|
||||
<varref loc="d,11,24,11,29" name="top.i_clk" dtype_id="1"/>
|
||||
</assignalias>
|
||||
<assignalias loc="d,7,24,7,29" dtype_id="1">
|
||||
</contassign>
|
||||
<contassign loc="d,7,24,7,29" dtype_id="1">
|
||||
<varref loc="d,12,7,12,8" name="top.i_clk" dtype_id="1"/>
|
||||
<varref loc="d,7,24,7,29" name="top.f.i_clk" dtype_id="1"/>
|
||||
</assignalias>
|
||||
</contassign>
|
||||
</scope>
|
||||
</topscope>
|
||||
</module>
|
||||
|
|
|
|||
|
|
@ -41,22 +41,22 @@
|
|||
<varscope loc="d,15,57,15,60" name="__Vfunc_vlvbound_test.foo__1__val" dtype_id="1"/>
|
||||
<varscope loc="d,16,17,16,20" name="__Vfunc_vlvbound_test.foo__1__ret" dtype_id="2"/>
|
||||
<varscope loc="d,17,13,17,14" name="__Vfunc_vlvbound_test.foo__1__i" dtype_id="3"/>
|
||||
<assignalias loc="d,9,25,9,28" dtype_id="1">
|
||||
<contassign loc="d,9,25,9,28" dtype_id="1">
|
||||
<varref loc="d,9,25,9,28" name="i_a" dtype_id="1"/>
|
||||
<varref loc="d,9,25,9,28" name="vlvbound_test.i_a" dtype_id="1"/>
|
||||
</assignalias>
|
||||
<assignalias loc="d,10,25,10,28" dtype_id="1">
|
||||
</contassign>
|
||||
<contassign loc="d,10,25,10,28" dtype_id="1">
|
||||
<varref loc="d,10,25,10,28" name="i_b" dtype_id="1"/>
|
||||
<varref loc="d,10,25,10,28" name="vlvbound_test.i_b" dtype_id="1"/>
|
||||
</assignalias>
|
||||
<assignalias loc="d,11,25,11,28" dtype_id="2">
|
||||
</contassign>
|
||||
<contassign loc="d,11,25,11,28" dtype_id="2">
|
||||
<varref loc="d,11,25,11,28" name="o_a" dtype_id="2"/>
|
||||
<varref loc="d,11,25,11,28" name="vlvbound_test.o_a" dtype_id="2"/>
|
||||
</assignalias>
|
||||
<assignalias loc="d,12,25,12,28" dtype_id="2">
|
||||
</contassign>
|
||||
<contassign loc="d,12,25,12,28" dtype_id="2">
|
||||
<varref loc="d,12,25,12,28" name="o_b" dtype_id="2"/>
|
||||
<varref loc="d,12,25,12,28" name="vlvbound_test.o_b" dtype_id="2"/>
|
||||
</assignalias>
|
||||
</contassign>
|
||||
<always loc="d,24,14,24,15">
|
||||
<comment loc="d,24,16,24,19" name="Function: foo"/>
|
||||
<assign loc="d,24,20,24,23" dtype_id="1">
|
||||
|
|
|
|||
Loading…
Reference in New Issue