Create implicit nets for inputs of gate primitives.
Prior to this we failed to create implicit nets for inputs of gate primitives, which is required by the standard (IEEE 1800-2017 6.10). Note: outputs were covered due to being modeled as the LHS of assignments, which do create implicit nets.
This commit is contained in:
parent
4c0edd2efb
commit
d330100542
|
|
@ -183,5 +183,6 @@ Yuri Victorovich
|
|||
Yutetsu TAKATSUKASA
|
||||
Yves Mathieu
|
||||
Zhanglei Wang
|
||||
Zhou Shen
|
||||
Zixi Li
|
||||
أحمد المحمودي
|
||||
|
|
|
|||
|
|
@ -1679,7 +1679,7 @@ private:
|
|||
}
|
||||
void visit(AstImplicit* nodep) override {
|
||||
// Unsupported gates need implicit creation
|
||||
pinImplicitExprRecurse(nodep);
|
||||
pinImplicitExprRecurse(nodep->exprsp());
|
||||
// We're done with implicit gates
|
||||
VL_DO_DANGLING(nodep->unlinkFrBack()->deleteTree(), nodep);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -55,6 +55,7 @@
|
|||
#define DELAY_LIST(delayp, assignsp) \
|
||||
if (delayp) { \
|
||||
for (auto* nodep = assignsp; nodep; nodep = nodep->nextp()) { \
|
||||
if (VN_IS(nodep, Implicit)) continue; \
|
||||
auto* const assignp = VN_AS(nodep, NodeAssign); \
|
||||
assignp->timingControlp(nodep == assignsp ? delayp : delayp->cloneTree(false)); \
|
||||
} \
|
||||
|
|
@ -373,6 +374,7 @@ int V3ParseGrammar::s_modTypeImpNum = 0;
|
|||
{ \
|
||||
if (AstStrengthSpec* const specp = VN_CAST(strengthSpecNodep, StrengthSpec)) { \
|
||||
for (auto* nodep = beginp; nodep; nodep = nodep->nextp()) { \
|
||||
if (VN_IS(nodep, Implicit)) continue; \
|
||||
auto* const assignp = VN_AS(nodep, typeToCast); \
|
||||
assignp->strengthSpecp(nodep == beginp ? specp : specp->cloneTree(false)); \
|
||||
} \
|
||||
|
|
@ -5347,7 +5349,8 @@ gateBuf<nodep>:
|
|||
gateFront variable_lvalue ',' exprList ')'
|
||||
{ AstNodeExpr* inp = $4;
|
||||
while (inp->nextp()) inp = VN_AS(inp->nextp(), NodeExpr);
|
||||
$$ = new AstAssignW{$<fl>1, $2, GRAMMARP->createGatePin(inp->cloneTree(false))};
|
||||
$$ = new AstImplicit{$<fl>1, inp->cloneTree(false)};
|
||||
$$->addNext(new AstAssignW{$<fl>1, $2, GRAMMARP->createGatePin(inp->cloneTree(false))});
|
||||
for (AstNodeExpr* outp = $4; outp->nextp(); outp = VN_CAST(outp->nextp(), NodeExpr)) {
|
||||
$$->addNext(new AstAssignW{$<fl>1, outp->cloneTree(false),
|
||||
GRAMMARP->createGatePin(inp->cloneTree(false))});
|
||||
|
|
@ -5358,8 +5361,9 @@ gateNot<nodep>:
|
|||
gateFront variable_lvalue ',' exprList ')'
|
||||
{ AstNodeExpr* inp = $4;
|
||||
while (inp->nextp()) inp = VN_AS(inp->nextp(), NodeExpr);
|
||||
$$ = new AstAssignW{$<fl>1, $2, new AstNot{$<fl>1,
|
||||
GRAMMARP->createGatePin(inp->cloneTree(false))}};
|
||||
$$ = new AstImplicit{$<fl>1, inp->cloneTree(false)};
|
||||
$$->addNext(new AstAssignW{$<fl>1, $2, new AstNot{$<fl>1,
|
||||
GRAMMARP->createGatePin(inp->cloneTree(false))}});
|
||||
for (AstNodeExpr* outp = $4; outp->nextp(); outp = VN_CAST(outp->nextp(), NodeExpr)) {
|
||||
$$->addNext(new AstAssignW{$<fl>1, outp->cloneTree(false),
|
||||
new AstNot{$<fl>1,
|
||||
|
|
@ -5369,44 +5373,58 @@ gateNot<nodep>:
|
|||
;
|
||||
gateBufif0<nodep>:
|
||||
gateFront variable_lvalue ',' gatePinExpr ',' gatePinExpr ')'
|
||||
{ $$ = new AstAssignW{$<fl>1, $2, new AstBufIf1{$<fl>1, new AstNot{$<fl>1, $6}, $4}}; DEL($1); }
|
||||
{ $$ = new AstImplicit{$<fl>1, $6->cloneTree(false)};
|
||||
$<implicitp>$->addExprsp($4->cloneTree(false));
|
||||
$$->addNext(new AstAssignW{$<fl>1, $2, new AstBufIf1{$<fl>1, new AstNot{$<fl>1, $6}, $4}}); DEL($1); }
|
||||
;
|
||||
gateBufif1<nodep>:
|
||||
gateFront variable_lvalue ',' gatePinExpr ',' gatePinExpr ')'
|
||||
{ $$ = new AstAssignW{$<fl>1, $2, new AstBufIf1{$<fl>1, $6, $4}}; DEL($1); }
|
||||
{ $$ = new AstImplicit{$<fl>1, $6->cloneTree(false)};
|
||||
$<implicitp>$->addExprsp($4->cloneTree(false));
|
||||
$$->addNext(new AstAssignW{$<fl>1, $2, new AstBufIf1{$<fl>1, $6, $4}}); DEL($1); }
|
||||
;
|
||||
gateNotif0<nodep>:
|
||||
gateFront variable_lvalue ',' gatePinExpr ',' gatePinExpr ')'
|
||||
{ $$ = new AstAssignW{$<fl>1, $2, new AstBufIf1{$<fl>1, new AstNot{$<fl>1, $6},
|
||||
new AstNot{$<fl>1, $4}}}; DEL($1); }
|
||||
{ $$ = new AstImplicit{$<fl>1, $6->cloneTree(false)};
|
||||
$<implicitp>$->addExprsp($4->cloneTree(false));
|
||||
$$->addNext(new AstAssignW{$<fl>1, $2, new AstBufIf1{$<fl>1, new AstNot{$<fl>1, $6},
|
||||
new AstNot{$<fl>1, $4}}}); DEL($1); }
|
||||
;
|
||||
gateNotif1<nodep>:
|
||||
gateFront variable_lvalue ',' gatePinExpr ',' gatePinExpr ')'
|
||||
{ $$ = new AstAssignW{$<fl>1, $2, new AstBufIf1{$<fl>1, $6, new AstNot{$<fl>1, $4}}}; DEL($1); }
|
||||
{ $$ = new AstImplicit{$<fl>1, $6->cloneTree(false)};
|
||||
$<implicitp>$->addExprsp($4->cloneTree(false));
|
||||
$$->addNext(new AstAssignW{$<fl>1, $2, new AstBufIf1{$<fl>1, $6, new AstNot{$<fl>1, $4}}}); DEL($1); }
|
||||
;
|
||||
gateAnd<nodep>:
|
||||
gateFront variable_lvalue ',' gateAndPinList ')'
|
||||
{ $$ = new AstAssignW{$<fl>1, $2, $4}; DEL($1); }
|
||||
{ $$ = new AstImplicit{$<fl>1, $4->cloneTree(false)};
|
||||
$$->addNext(new AstAssignW{$<fl>1, $2, $4}); DEL($1); }
|
||||
;
|
||||
gateNand<nodep>:
|
||||
gateFront variable_lvalue ',' gateAndPinList ')'
|
||||
{ $$ = new AstAssignW{$<fl>1, $2, new AstNot{$<fl>1, $4}}; DEL($1); }
|
||||
{ $$ = new AstImplicit{$<fl>1, $4->cloneTree(false)};
|
||||
$$->addNext(new AstAssignW{$<fl>1, $2, new AstNot{$<fl>1, $4}}); DEL($1); }
|
||||
;
|
||||
gateOr<nodep>:
|
||||
gateFront variable_lvalue ',' gateOrPinList ')'
|
||||
{ $$ = new AstAssignW{$<fl>1, $2, $4}; DEL($1); }
|
||||
{ $$ = new AstImplicit{$<fl>1, $4->cloneTree(false)};
|
||||
$$->addNext(new AstAssignW{$<fl>1, $2, $4}); DEL($1); }
|
||||
;
|
||||
gateNor<nodep>:
|
||||
gateFront variable_lvalue ',' gateOrPinList ')'
|
||||
{ $$ = new AstAssignW{$<fl>1, $2, new AstNot{$<fl>1, $4}}; DEL($1); }
|
||||
{ $$ = new AstImplicit{$<fl>1, $4->cloneTree(false)};
|
||||
$$->addNext(new AstAssignW{$<fl>1, $2, new AstNot{$<fl>1, $4}}); DEL($1); }
|
||||
;
|
||||
gateXor<nodep>:
|
||||
gateFront variable_lvalue ',' gateXorPinList ')'
|
||||
{ $$ = new AstAssignW{$<fl>1, $2, $4}; DEL($1); }
|
||||
{ $$ = new AstImplicit{$<fl>1, $4->cloneTree(false)};
|
||||
$$->addNext(new AstAssignW{$<fl>1, $2, $4}); DEL($1); }
|
||||
;
|
||||
gateXnor<nodep>:
|
||||
gateFront variable_lvalue ',' gateXorPinList ')'
|
||||
{ $$ = new AstAssignW{$<fl>1, $2, new AstNot{$<fl>1, $4}}; DEL($1); }
|
||||
{ $$ = new AstImplicit{$<fl>1, $4->cloneTree(false)};
|
||||
$$->addNext(new AstAssignW{$<fl>1, $2, new AstNot{$<fl>1, $4}}); DEL($1); }
|
||||
;
|
||||
gatePullup<nodep>:
|
||||
gateFront variable_lvalue ')' { $$ = new AstPull{$<fl>1, $2, true}; DEL($1); }
|
||||
|
|
|
|||
|
|
@ -0,0 +1,166 @@
|
|||
%Warning-IMPLICIT: t/t_gate_primitives_implicit_net.v:15:21: Signal definition not found, creating implicitly: 'i_and1'
|
||||
15 | and g_and(o_and, i_and1, i_and2, i_and3);
|
||||
| ^~~~~~
|
||||
... For warning description see https://verilator.org/warn/IMPLICIT?v=latest
|
||||
... Use "/* verilator lint_off IMPLICIT */" and lint_on around source to disable this message.
|
||||
%Warning-IMPLICIT: t/t_gate_primitives_implicit_net.v:15:29: Signal definition not found, creating implicitly: 'i_and2'
|
||||
: ... Suggested alternative: 'i_and1'
|
||||
15 | and g_and(o_and, i_and1, i_and2, i_and3);
|
||||
| ^~~~~~
|
||||
%Warning-IMPLICIT: t/t_gate_primitives_implicit_net.v:15:37: Signal definition not found, creating implicitly: 'i_and3'
|
||||
: ... Suggested alternative: 'i_and1'
|
||||
15 | and g_and(o_and, i_and1, i_and2, i_and3);
|
||||
| ^~~~~~
|
||||
%Warning-IMPLICIT: t/t_gate_primitives_implicit_net.v:15:14: Signal definition not found, creating implicitly: 'o_and'
|
||||
: ... Suggested alternative: 'i_and1'
|
||||
15 | and g_and(o_and, i_and1, i_and2, i_and3);
|
||||
| ^~~~~
|
||||
%Warning-IMPLICIT: t/t_gate_primitives_implicit_net.v:16:30: Signal definition not found, creating implicitly: 'i_not1'
|
||||
16 | not g_not(o_not1, o_not2, i_not1);
|
||||
| ^~~~~~
|
||||
%Warning-IMPLICIT: t/t_gate_primitives_implicit_net.v:16:14: Signal definition not found, creating implicitly: 'o_not1'
|
||||
: ... Suggested alternative: 'i_not1'
|
||||
16 | not g_not(o_not1, o_not2, i_not1);
|
||||
| ^~~~~~
|
||||
%Warning-IMPLICIT: t/t_gate_primitives_implicit_net.v:16:22: Signal definition not found, creating implicitly: 'o_not2'
|
||||
: ... Suggested alternative: 'o_not1'
|
||||
16 | not g_not(o_not1, o_not2, i_not1);
|
||||
| ^~~~~~
|
||||
%Warning-IMPLICIT: t/t_gate_primitives_implicit_net.v:17:21: Signal definition not found, creating implicitly: 'i_nor1'
|
||||
: ... Suggested alternative: 'i_not1'
|
||||
17 | nor g_nor(o_nor, i_nor1, i_nor2, i_nor3);
|
||||
| ^~~~~~
|
||||
%Warning-IMPLICIT: t/t_gate_primitives_implicit_net.v:17:29: Signal definition not found, creating implicitly: 'i_nor2'
|
||||
: ... Suggested alternative: 'i_nor1'
|
||||
17 | nor g_nor(o_nor, i_nor1, i_nor2, i_nor3);
|
||||
| ^~~~~~
|
||||
%Warning-IMPLICIT: t/t_gate_primitives_implicit_net.v:17:37: Signal definition not found, creating implicitly: 'i_nor3'
|
||||
: ... Suggested alternative: 'i_nor1'
|
||||
17 | nor g_nor(o_nor, i_nor1, i_nor2, i_nor3);
|
||||
| ^~~~~~
|
||||
%Warning-IMPLICIT: t/t_gate_primitives_implicit_net.v:17:14: Signal definition not found, creating implicitly: 'o_nor'
|
||||
: ... Suggested alternative: 'i_nor1'
|
||||
17 | nor g_nor(o_nor, i_nor1, i_nor2, i_nor3);
|
||||
| ^~~~~
|
||||
%Warning-IMPLICIT: t/t_gate_primitives_implicit_net.v:18:18: Signal definition not found, creating implicitly: 'i_or1'
|
||||
: ... Suggested alternative: 'i_nor1'
|
||||
18 | or g_or(o_or, i_or1, i_or2, i_or3);
|
||||
| ^~~~~
|
||||
%Warning-IMPLICIT: t/t_gate_primitives_implicit_net.v:18:25: Signal definition not found, creating implicitly: 'i_or2'
|
||||
: ... Suggested alternative: 'i_nor2'
|
||||
18 | or g_or(o_or, i_or1, i_or2, i_or3);
|
||||
| ^~~~~
|
||||
%Warning-IMPLICIT: t/t_gate_primitives_implicit_net.v:18:32: Signal definition not found, creating implicitly: 'i_or3'
|
||||
: ... Suggested alternative: 'i_nor3'
|
||||
18 | or g_or(o_or, i_or1, i_or2, i_or3);
|
||||
| ^~~~~
|
||||
%Warning-IMPLICIT: t/t_gate_primitives_implicit_net.v:18:12: Signal definition not found, creating implicitly: 'o_or'
|
||||
: ... Suggested alternative: 'o_nor'
|
||||
18 | or g_or(o_or, i_or1, i_or2, i_or3);
|
||||
| ^~~~
|
||||
%Warning-IMPLICIT: t/t_gate_primitives_implicit_net.v:19:24: Signal definition not found, creating implicitly: 'i_nand1'
|
||||
: ... Suggested alternative: 'i_and1'
|
||||
19 | nand g_nand(o_nand, i_nand1, i_nand2, i_nand3);
|
||||
| ^~~~~~~
|
||||
%Warning-IMPLICIT: t/t_gate_primitives_implicit_net.v:19:33: Signal definition not found, creating implicitly: 'i_nand2'
|
||||
: ... Suggested alternative: 'i_and2'
|
||||
19 | nand g_nand(o_nand, i_nand1, i_nand2, i_nand3);
|
||||
| ^~~~~~~
|
||||
%Warning-IMPLICIT: t/t_gate_primitives_implicit_net.v:19:42: Signal definition not found, creating implicitly: 'i_nand3'
|
||||
: ... Suggested alternative: 'i_and3'
|
||||
19 | nand g_nand(o_nand, i_nand1, i_nand2, i_nand3);
|
||||
| ^~~~~~~
|
||||
%Warning-IMPLICIT: t/t_gate_primitives_implicit_net.v:19:16: Signal definition not found, creating implicitly: 'o_nand'
|
||||
: ... Suggested alternative: 'o_and'
|
||||
19 | nand g_nand(o_nand, i_nand1, i_nand2, i_nand3);
|
||||
| ^~~~~~
|
||||
%Warning-IMPLICIT: t/t_gate_primitives_implicit_net.v:20:21: Signal definition not found, creating implicitly: 'i_xor1'
|
||||
: ... Suggested alternative: 'i_nor1'
|
||||
20 | xor g_xor(o_xor, i_xor1, i_xor2, i_xor3);
|
||||
| ^~~~~~
|
||||
%Warning-IMPLICIT: t/t_gate_primitives_implicit_net.v:20:29: Signal definition not found, creating implicitly: 'i_xor2'
|
||||
: ... Suggested alternative: 'i_nor2'
|
||||
20 | xor g_xor(o_xor, i_xor1, i_xor2, i_xor3);
|
||||
| ^~~~~~
|
||||
%Warning-IMPLICIT: t/t_gate_primitives_implicit_net.v:20:37: Signal definition not found, creating implicitly: 'i_xor3'
|
||||
: ... Suggested alternative: 'i_nor3'
|
||||
20 | xor g_xor(o_xor, i_xor1, i_xor2, i_xor3);
|
||||
| ^~~~~~
|
||||
%Warning-IMPLICIT: t/t_gate_primitives_implicit_net.v:20:14: Signal definition not found, creating implicitly: 'o_xor'
|
||||
: ... Suggested alternative: 'o_nor'
|
||||
20 | xor g_xor(o_xor, i_xor1, i_xor2, i_xor3);
|
||||
| ^~~~~
|
||||
%Warning-IMPLICIT: t/t_gate_primitives_implicit_net.v:21:23: Signal definition not found, creating implicitly: 'i_xnor1'
|
||||
: ... Suggested alternative: 'i_nor1'
|
||||
21 | xnor g_xor(o_xnor, i_xnor1, i_xnor2, i_xnor3);
|
||||
| ^~~~~~~
|
||||
%Warning-IMPLICIT: t/t_gate_primitives_implicit_net.v:21:32: Signal definition not found, creating implicitly: 'i_xnor2'
|
||||
: ... Suggested alternative: 'i_nor2'
|
||||
21 | xnor g_xor(o_xnor, i_xnor1, i_xnor2, i_xnor3);
|
||||
| ^~~~~~~
|
||||
%Warning-IMPLICIT: t/t_gate_primitives_implicit_net.v:21:41: Signal definition not found, creating implicitly: 'i_xnor3'
|
||||
: ... Suggested alternative: 'i_nor3'
|
||||
21 | xnor g_xor(o_xnor, i_xnor1, i_xnor2, i_xnor3);
|
||||
| ^~~~~~~
|
||||
%Warning-IMPLICIT: t/t_gate_primitives_implicit_net.v:21:15: Signal definition not found, creating implicitly: 'o_xnor'
|
||||
: ... Suggested alternative: 'o_nor'
|
||||
21 | xnor g_xor(o_xnor, i_xnor1, i_xnor2, i_xnor3);
|
||||
| ^~~~~~
|
||||
%Warning-IMPLICIT: t/t_gate_primitives_implicit_net.v:22:30: Signal definition not found, creating implicitly: 'i_buf1'
|
||||
22 | buf g_buf(o_buf1, o_buf2, i_buf1);
|
||||
| ^~~~~~
|
||||
%Warning-IMPLICIT: t/t_gate_primitives_implicit_net.v:22:14: Signal definition not found, creating implicitly: 'o_buf1'
|
||||
: ... Suggested alternative: 'i_buf1'
|
||||
22 | buf g_buf(o_buf1, o_buf2, i_buf1);
|
||||
| ^~~~~~
|
||||
%Warning-IMPLICIT: t/t_gate_primitives_implicit_net.v:22:22: Signal definition not found, creating implicitly: 'o_buf2'
|
||||
: ... Suggested alternative: 'o_buf1'
|
||||
22 | buf g_buf(o_buf1, o_buf2, i_buf1);
|
||||
| ^~~~~~
|
||||
%Warning-IMPLICIT: t/t_gate_primitives_implicit_net.v:23:41: Signal definition not found, creating implicitly: 'i_bufif02'
|
||||
23 | bufif0 g_bufif0(o_bufif0, i_bufif01, i_bufif02);
|
||||
| ^~~~~~~~~
|
||||
%Warning-IMPLICIT: t/t_gate_primitives_implicit_net.v:23:30: Signal definition not found, creating implicitly: 'i_bufif01'
|
||||
: ... Suggested alternative: 'i_bufif02'
|
||||
23 | bufif0 g_bufif0(o_bufif0, i_bufif01, i_bufif02);
|
||||
| ^~~~~~~~~
|
||||
%Warning-IMPLICIT: t/t_gate_primitives_implicit_net.v:23:20: Signal definition not found, creating implicitly: 'o_bufif0'
|
||||
: ... Suggested alternative: 'i_bufif01'
|
||||
23 | bufif0 g_bufif0(o_bufif0, i_bufif01, i_bufif02);
|
||||
| ^~~~~~~~
|
||||
%Warning-IMPLICIT: t/t_gate_primitives_implicit_net.v:24:41: Signal definition not found, creating implicitly: 'i_bufif12'
|
||||
: ... Suggested alternative: 'i_bufif02'
|
||||
24 | bufif1 g_bufif1(o_bufif1, i_bufif11, i_bufif12);
|
||||
| ^~~~~~~~~
|
||||
%Warning-IMPLICIT: t/t_gate_primitives_implicit_net.v:24:30: Signal definition not found, creating implicitly: 'i_bufif11'
|
||||
: ... Suggested alternative: 'i_bufif01'
|
||||
24 | bufif1 g_bufif1(o_bufif1, i_bufif11, i_bufif12);
|
||||
| ^~~~~~~~~
|
||||
%Warning-IMPLICIT: t/t_gate_primitives_implicit_net.v:24:20: Signal definition not found, creating implicitly: 'o_bufif1'
|
||||
: ... Suggested alternative: 'o_bufif0'
|
||||
24 | bufif1 g_bufif1(o_bufif1, i_bufif11, i_bufif12);
|
||||
| ^~~~~~~~
|
||||
%Warning-IMPLICIT: t/t_gate_primitives_implicit_net.v:25:41: Signal definition not found, creating implicitly: 'i_notif02'
|
||||
: ... Suggested alternative: 'i_bufif02'
|
||||
25 | notif0 g_notif0(o_notif0, i_notif01, i_notif02);
|
||||
| ^~~~~~~~~
|
||||
%Warning-IMPLICIT: t/t_gate_primitives_implicit_net.v:25:30: Signal definition not found, creating implicitly: 'i_notif01'
|
||||
: ... Suggested alternative: 'i_notif02'
|
||||
25 | notif0 g_notif0(o_notif0, i_notif01, i_notif02);
|
||||
| ^~~~~~~~~
|
||||
%Warning-IMPLICIT: t/t_gate_primitives_implicit_net.v:25:20: Signal definition not found, creating implicitly: 'o_notif0'
|
||||
: ... Suggested alternative: 'i_notif01'
|
||||
25 | notif0 g_notif0(o_notif0, i_notif01, i_notif02);
|
||||
| ^~~~~~~~
|
||||
%Warning-IMPLICIT: t/t_gate_primitives_implicit_net.v:26:41: Signal definition not found, creating implicitly: 'i_notif12'
|
||||
: ... Suggested alternative: 'i_notif02'
|
||||
26 | notif1 g_notif1(o_notif1, i_notif11, i_notif12);
|
||||
| ^~~~~~~~~
|
||||
%Warning-IMPLICIT: t/t_gate_primitives_implicit_net.v:26:30: Signal definition not found, creating implicitly: 'i_notif11'
|
||||
: ... Suggested alternative: 'i_notif01'
|
||||
26 | notif1 g_notif1(o_notif1, i_notif11, i_notif12);
|
||||
| ^~~~~~~~~
|
||||
%Warning-IMPLICIT: t/t_gate_primitives_implicit_net.v:26:20: Signal definition not found, creating implicitly: 'o_notif1'
|
||||
: ... Suggested alternative: 'o_notif0'
|
||||
26 | notif1 g_notif1(o_notif1, i_notif11, i_notif12);
|
||||
| ^~~~~~~~
|
||||
|
|
@ -0,0 +1,23 @@
|
|||
#!/usr/bin/env perl
|
||||
if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; }
|
||||
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
|
||||
#
|
||||
# Copyright 2023 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
|
||||
|
||||
scenarios(vlt => 1);
|
||||
|
||||
compile(
|
||||
verilator_flags2 => ["-Wno-fatal --no-skip-identical"],
|
||||
expect_filename => $Self->{golden_filename},
|
||||
);
|
||||
|
||||
execute(
|
||||
check_finished => 1,
|
||||
);
|
||||
|
||||
ok(1);
|
||||
1;
|
||||
|
|
@ -0,0 +1,101 @@
|
|||
// DESCRIPTION: Verilator: Verilog Test module
|
||||
//
|
||||
// This file ONLY is placed under the Creative Commons Public Domain, for
|
||||
// any use, without warranty, 2023 by Wilson Snyder.
|
||||
// SPDX-License-Identifier: CC0-1.0
|
||||
|
||||
module t(/*AUTOARG*/
|
||||
// Inputs
|
||||
clk
|
||||
);
|
||||
input clk;
|
||||
int cyc=1;
|
||||
|
||||
// Instantiate the primitive gates to be tested.
|
||||
and g_and(o_and, i_and1, i_and2, i_and3);
|
||||
not g_not(o_not1, o_not2, i_not1);
|
||||
nor g_nor(o_nor, i_nor1, i_nor2, i_nor3);
|
||||
or g_or(o_or, i_or1, i_or2, i_or3);
|
||||
nand g_nand(o_nand, i_nand1, i_nand2, i_nand3);
|
||||
xor g_xor(o_xor, i_xor1, i_xor2, i_xor3);
|
||||
xnor g_xor(o_xnor, i_xnor1, i_xnor2, i_xnor3);
|
||||
buf g_buf(o_buf1, o_buf2, i_buf1);
|
||||
bufif0 g_bufif0(o_bufif0, i_bufif01, i_bufif02);
|
||||
bufif1 g_bufif1(o_bufif1, i_bufif11, i_bufif12);
|
||||
notif0 g_notif0(o_notif0, i_notif01, i_notif02);
|
||||
notif1 g_notif1(o_notif1, i_notif11, i_notif12);
|
||||
|
||||
// Generate random data for inputs
|
||||
reg rd_data1, rd_data2, rd_data3;
|
||||
always @(posedge clk) begin
|
||||
rd_data1 = 1'($random);
|
||||
rd_data2 = 1'($random);
|
||||
rd_data3 = 1'($random);
|
||||
end
|
||||
|
||||
// Assign the input of primitive gates.
|
||||
`default_nettype none
|
||||
assign i_and1 = rd_data1;
|
||||
assign i_and2 = rd_data2;
|
||||
assign i_and3 = rd_data3;
|
||||
|
||||
assign i_not1 = rd_data1;
|
||||
|
||||
assign i_nor1 = rd_data1;
|
||||
assign i_nor2 = rd_data2;
|
||||
assign i_nor3 = rd_data3;
|
||||
|
||||
assign i_or1 = rd_data1;
|
||||
assign i_or2 = rd_data2;
|
||||
assign i_or3 = rd_data3;
|
||||
|
||||
assign i_nand1 = rd_data1;
|
||||
assign i_nand2 = rd_data2;
|
||||
assign i_nand3 = rd_data3;
|
||||
|
||||
assign i_xor1 = rd_data1;
|
||||
assign i_xor2 = rd_data2;
|
||||
assign i_xor3 = rd_data3;
|
||||
|
||||
assign i_xnor1 = rd_data1;
|
||||
assign i_xnor2 = rd_data2;
|
||||
assign i_xnor3 = rd_data3;
|
||||
|
||||
assign i_buf1 = rd_data1;
|
||||
|
||||
assign i_bufif01 = rd_data1;
|
||||
assign i_bufif02 = rd_data2;
|
||||
|
||||
assign i_bufif11 = rd_data1;
|
||||
assign i_bufif12 = rd_data2;
|
||||
|
||||
assign i_notif01 = rd_data1;
|
||||
assign i_notif02 = rd_data2;
|
||||
|
||||
assign i_notif11 = rd_data1;
|
||||
assign i_notif12 = rd_data2;
|
||||
|
||||
// Check the outputs of the gate instances
|
||||
always @(negedge clk) begin
|
||||
if (o_and !== (i_and1 & i_and2 & i_and3)) $stop;
|
||||
if ((o_not1 !== ~i_not1) || (o_not2 != ~i_not1)) $stop;
|
||||
if (o_nor !== !(i_nor1 | i_nor2 | i_nor3)) $stop;
|
||||
if (o_or !== (i_or1 | i_or2 | i_or3)) $stop;
|
||||
if (o_nand !== !(i_nand1 & i_nand2 & i_nand3)) $stop;
|
||||
if (o_xor !== (i_xor1 ^ i_xor2 ^ i_xor3)) $stop;
|
||||
if (o_xnor !== !(i_xnor1 ^ i_xnor2 ^ i_xnor3)) $stop;
|
||||
if ((o_buf1 !== i_buf1) || (o_buf2 !== i_buf1)) $stop;
|
||||
if (!(o_bufif0 == (i_bufif01 & !i_bufif02))) $stop;
|
||||
if (!(o_bufif1 == (i_bufif11 & i_bufif12))) $stop;
|
||||
if (!(o_notif0 == (!i_notif01 & !i_notif02))) $stop;
|
||||
if (!(o_notif1 == (!i_notif11 & i_notif12))) $stop;
|
||||
end
|
||||
|
||||
always @(posedge clk) begin
|
||||
cyc = cyc + 1;
|
||||
if (cyc == 100) begin
|
||||
$write("*-* All Finished *-*\n");
|
||||
$finish;
|
||||
end
|
||||
end
|
||||
endmodule
|
||||
Loading…
Reference in New Issue