parent
c9e012ba9a
commit
8ae0e48103
|
|
@ -0,0 +1,12 @@
|
|||
.. code-block:: sv
|
||||
:linenos:
|
||||
:emphasize-lines: 3,6
|
||||
|
||||
module t(input logic clk, input logic d, output logic q);
|
||||
|
||||
initial q = 1'b0; // <--- Warning
|
||||
|
||||
always_ff @(posedge clk) begin
|
||||
q <= d; // <--- Warning
|
||||
end
|
||||
endmodule
|
||||
|
|
@ -1414,9 +1414,11 @@ List Of Warnings
|
|||
|
||||
.. option:: MULTIDRIVEN
|
||||
|
||||
Warns that the specified signal comes from multiple ``always``
|
||||
blocks, each with different clocking. This warning does not look at
|
||||
individual bits (see the example below).
|
||||
Warns that the specified signal has multiple procedural drivers.
|
||||
|
||||
One case is when the signal comes from multiple ``always`` blocks,
|
||||
each with different clocking. This warning does not look at individual
|
||||
bits (see the example below).
|
||||
|
||||
This is considered bad style, as the consumer of a given signal may be
|
||||
unaware of the inconsistent clocking, causing clock domain crossing
|
||||
|
|
@ -1430,8 +1432,28 @@ List Of Warnings
|
|||
|
||||
.. include:: ../../docs/gen/ex_MULTIDRIVEN_msg.rst
|
||||
|
||||
Ignoring this warning will only slow simulations; it will simulate
|
||||
correctly. It may, however, cause longer simulation runtimes due to
|
||||
Another case is when a variable written in an ``always_comb`` or
|
||||
``always_ff`` block is also written by another process. IEEE 1800
|
||||
requires variables written in these specialized always blocks to be
|
||||
written only by that process.
|
||||
|
||||
Faulty ``always_ff`` example:
|
||||
|
||||
.. include:: ../../docs/gen/ex_MULTIDRIVEN_alwaysff_faulty.rst
|
||||
|
||||
To retain an initialization without adding another process, use a
|
||||
declaration initializer (or, for synthesizable code, add a reset term):
|
||||
|
||||
.. code-block:: sv
|
||||
|
||||
logic q = 1'b0;
|
||||
|
||||
always_ff @(posedge clk) begin
|
||||
q <= d;
|
||||
end
|
||||
|
||||
Ignoring this warning may hide clock domain crossing, timing, or
|
||||
portability bugs. It may also cause longer simulation runtimes due to
|
||||
reduced optimizations.
|
||||
|
||||
|
||||
|
|
@ -1798,12 +1820,18 @@ List Of Warnings
|
|||
|
||||
.. include:: ../../docs/gen/ex_PROCASSINIT_fixed.rst
|
||||
|
||||
Alternatively, use an initial block for the initialization:
|
||||
For non-``always_ff`` logic, alternatively use an initial block for
|
||||
the initialization:
|
||||
|
||||
.. code-block:: sv
|
||||
|
||||
initial flop_out = 1; // <--- Fixed
|
||||
|
||||
Do not use a separate initial block for a variable assigned by an
|
||||
``always_ff`` process, as IEEE 1800 requires an ``always_ff`` variable
|
||||
to be written only by that process. Use a declaration initializer, or
|
||||
initialize the variable from reset logic inside the ``always_ff``.
|
||||
|
||||
Disabled by default as this is a code-style warning; it will simulate
|
||||
correctly.
|
||||
|
||||
|
|
|
|||
|
|
@ -47,6 +47,7 @@ class UndrivenVarEntry final {
|
|||
= nullptr; // always_comb of var if driven within always_comb, else nullptr
|
||||
const FileLine* m_alwCombFileLinep = nullptr; // File line of always_comb of var if driven
|
||||
// within always_comb, else nullptr
|
||||
const AstAlways* m_alwFFp = nullptr; // always_ff of var if driven within always_ff
|
||||
const AstNodeVarRef* m_nodep = nullptr; // varref if driven, else nullptr
|
||||
const AstNode* m_initStaticp = nullptr; // varref if in InitialStatic driven
|
||||
const AstNode* m_initialp = nullptr; // varref if driven in an explicit initial block
|
||||
|
|
@ -58,7 +59,13 @@ class UndrivenVarEntry final {
|
|||
|
||||
const AstNodeFTaskRef* m_callNodep = nullptr; // Call node if driven via writeSummary
|
||||
|
||||
enum : uint8_t { FLAG_USED = 0, FLAG_DRIVEN = 1, FLAG_DRIVEN_ALWCOMB = 2, FLAGS_PER_BIT = 3 };
|
||||
enum : uint8_t {
|
||||
FLAG_USED = 0, // Signal or bit has been read/observed
|
||||
FLAG_DRIVEN = 1, // Signal or bit has been written/driven
|
||||
FLAG_DRIVEN_ALWCOMB = 2, // Whole signal has been driven from always_comb
|
||||
FLAG_DRIVEN_ALWFF = 3, // Whole signal has been driven from always_ff
|
||||
FLAGS_PER_BIT = 4 // Number of flags stored for each tracked bit
|
||||
};
|
||||
|
||||
public:
|
||||
// CONSTRUCTORS
|
||||
|
|
@ -151,6 +158,10 @@ public:
|
|||
m_alwCombp = alwCombp;
|
||||
m_alwCombFileLinep = fileLinep;
|
||||
}
|
||||
void drivenAlwaysFFWhole(const AstAlways* alwFFp, const AstVar* varp) {
|
||||
m_wholeFlags[FLAG_DRIVEN_ALWFF] = true;
|
||||
m_alwFFp = alwFFp;
|
||||
}
|
||||
|
||||
const AstNode* initStaticp() const { return m_initStaticp; }
|
||||
void initStaticp(const AstNode* nodep) { m_initStaticp = nodep; }
|
||||
|
|
@ -164,11 +175,13 @@ public:
|
|||
bool isUnderGen() const { return m_underGen; }
|
||||
bool isDrivenWhole() const { return m_wholeFlags[FLAG_DRIVEN]; }
|
||||
bool isDrivenAlwaysCombWhole() const { return m_wholeFlags[FLAG_DRIVEN_ALWCOMB]; }
|
||||
bool isDrivenAlwaysFFWhole() const { return m_wholeFlags[FLAG_DRIVEN_ALWFF]; }
|
||||
bool isFtaskDriven() const { return m_ftaskDriven; }
|
||||
const AstNodeVarRef* getNodep() const { return m_nodep; }
|
||||
const FileLine* getNodeFileLinep() const { return m_nodeFileLinep; }
|
||||
const AstAlways* getAlwCombp() const { return m_alwCombp; }
|
||||
const FileLine* getAlwCombFileLinep() const { return m_alwCombFileLinep; }
|
||||
const AstAlways* getAlwFFp() const { return m_alwFFp; }
|
||||
void usedBit(int bit, int width, const AstNode* nodep) {
|
||||
UINFO(9, "set u[" << (bit + width - 1) << ":" << bit << "] " << m_varp->name());
|
||||
for (int i = 0; i < width; i++) {
|
||||
|
|
@ -366,6 +379,7 @@ class UndrivenVisitor final : public VNVisitorConst {
|
|||
const AstNodeFTask* m_taskp = nullptr; // Current task
|
||||
const AstAlways* m_alwaysp = nullptr; // Current always of either type
|
||||
const AstAlways* m_alwaysCombp = nullptr; // Current always if combo, otherwise nullptr
|
||||
const AstAlways* m_alwaysFFp = nullptr; // Current always if ff, otherwise nullptr
|
||||
|
||||
V3UndrivenCapture* const m_capturep = nullptr; // Capture object. 'nullptr' if disabled.
|
||||
|
||||
|
|
@ -523,6 +537,8 @@ class UndrivenVisitor final : public VNVisitorConst {
|
|||
const AstNode* const otherWritep
|
||||
= entryp->getNodep() ? static_cast<const AstNode*>(entryp->getNodep())
|
||||
: entryp->callNodep();
|
||||
const bool otherWriteIsStaticInit
|
||||
= nodep->varp()->hasUserInit() && otherWritep == entryp->initStaticp();
|
||||
|
||||
if (m_alwaysCombp
|
||||
&& (!entryp->isDrivenAlwaysCombWhole()
|
||||
|
|
@ -545,6 +561,31 @@ class UndrivenVisitor final : public VNVisitorConst {
|
|||
<< nodep->warnContextPrimary() << '\n'
|
||||
<< otherWritep->warnOther()
|
||||
<< "... Location of always_comb write\n"
|
||||
<< otherWritep->warnContextSecondary());
|
||||
}
|
||||
if (m_alwaysFFp
|
||||
&& !otherWriteIsStaticInit
|
||||
&& (!entryp->isDrivenAlwaysFFWhole()
|
||||
|| (m_alwaysFFp != entryp->getAlwFFp()
|
||||
&& m_alwaysFFp->fileline()
|
||||
!= entryp->getAlwFFp()->fileline()))) {
|
||||
nodep->v3warn(
|
||||
MULTIDRIVEN,
|
||||
"Variable written to in always_ff also written by other process"
|
||||
<< " (IEEE 1800-2023 9.2.2.4): " << nodep->prettyNameQ() << '\n'
|
||||
<< nodep->warnOther() << '\n'
|
||||
<< nodep->warnContextPrimary() << '\n'
|
||||
<< otherWritep->warnOther() << "... Location of other write\n"
|
||||
<< otherWritep->warnContextSecondary());
|
||||
}
|
||||
if (!m_alwaysFFp && !m_inInitialStatic && entryp->isDrivenAlwaysFFWhole()) {
|
||||
nodep->v3warn(MULTIDRIVEN, "Variable also written to in always_ff"
|
||||
<< " (IEEE 1800-2023 9.2.2.4): "
|
||||
<< nodep->prettyNameQ() << '\n'
|
||||
<< nodep->warnOther() << '\n'
|
||||
<< nodep->warnContextPrimary() << '\n'
|
||||
<< otherWritep->warnOther()
|
||||
<< "... Location of always_ff write\n"
|
||||
<< otherWritep->warnContextSecondary());
|
||||
}
|
||||
}
|
||||
|
|
@ -558,6 +599,8 @@ class UndrivenVisitor final : public VNVisitorConst {
|
|||
entryp->underGenerate();
|
||||
if (m_alwaysCombp)
|
||||
entryp->drivenAlwaysCombWhole(m_alwaysCombp, m_alwaysCombp->fileline());
|
||||
if (m_alwaysFFp)
|
||||
entryp->drivenAlwaysFFWhole(m_alwaysFFp, nodep->varp());
|
||||
}
|
||||
if (nodep->access().isWriteOrRW()) {
|
||||
if (m_inInitialStatic && !entryp->initStaticp()) entryp->initStaticp(nodep);
|
||||
|
|
@ -645,6 +688,7 @@ class UndrivenVisitor final : public VNVisitorConst {
|
|||
void visit(AstAlways* nodep) override {
|
||||
VL_RESTORER(m_alwaysp);
|
||||
VL_RESTORER(m_alwaysCombp);
|
||||
VL_RESTORER(m_alwaysFFp);
|
||||
AstNode::user2ClearTree();
|
||||
m_alwaysp = nodep;
|
||||
if (nodep->keyword() == VAlwaysKwd::ALWAYS_COMB) {
|
||||
|
|
@ -653,6 +697,7 @@ class UndrivenVisitor final : public VNVisitorConst {
|
|||
} else {
|
||||
m_alwaysCombp = nullptr;
|
||||
}
|
||||
m_alwaysFFp = nodep->keyword() == VAlwaysKwd::ALWAYS_FF ? nodep : nullptr;
|
||||
iterateChildrenConst(nodep);
|
||||
if (nodep->keyword() == VAlwaysKwd::ALWAYS_COMB) UINFO(9, " Done " << nodep);
|
||||
}
|
||||
|
|
@ -684,6 +729,7 @@ class UndrivenVisitor final : public VNVisitorConst {
|
|||
entryp->drivenViaCall(nodep);
|
||||
if (m_alwaysCombp)
|
||||
entryp->drivenAlwaysCombWhole(m_alwaysCombp, m_alwaysCombp->fileline());
|
||||
if (m_alwaysFFp) entryp->drivenAlwaysFFWhole(m_alwaysFFp, varp);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -75,8 +75,7 @@ module t
|
|||
// FSM with ++/--
|
||||
// A more elaborate case statement, with if-else, for loops, etc
|
||||
// to confirm that ++/-- is handled by V3LinkInc.cpp
|
||||
logic [3:0] state_d, state_q;
|
||||
initial state_q = '0;
|
||||
logic [3:0] state_d, state_q = '0;
|
||||
logic [3:0] state_counter_d, state_counter_q;
|
||||
always_ff @(posedge clk) begin
|
||||
state_q <= state_d;
|
||||
|
|
|
|||
|
|
@ -368,10 +368,11 @@
|
|||
S2 = 3'd2
|
||||
} state_t;
|
||||
|
||||
int cyc;
|
||||
logic start;
|
||||
logic side;
|
||||
logic [2:0] dyn_case;
|
||||
int cyc = 0;
|
||||
logic start = 1'b0;
|
||||
logic side = 1'b0;
|
||||
logic dyn_side = 1'b0;
|
||||
logic [2:0] dyn_case = 3'd7;
|
||||
state_t state /*verilator fsm_reset_arc*/;
|
||||
|
||||
fsm_if_mixed_vars_bad mixed_vars_u (.clk(clk));
|
||||
|
|
@ -392,17 +393,10 @@
|
|||
fsm_direct_active_low_dynamic_reset_bad active_low_dynamic_reset_u (
|
||||
.clk(clk), .rst_n(cyc != 0), .dyn_reset(dyn_case[1:0]));
|
||||
|
||||
initial begin
|
||||
cyc = 0;
|
||||
start = 1'b0;
|
||||
side = 1'b0;
|
||||
dyn_case = 3'd7;
|
||||
end
|
||||
|
||||
always @(posedge clk) begin
|
||||
cyc <= cyc + 1;
|
||||
if (cyc == 1) side <= 1'b1;
|
||||
dyn_case <= {2'b11, side};
|
||||
if (cyc == 1) dyn_side <= 1'b1;
|
||||
dyn_case <= {2'b11, dyn_side};
|
||||
if (cyc == 5) begin
|
||||
$write("*-* All Finished *-*\n");
|
||||
$finish;
|
||||
|
|
|
|||
|
|
@ -362,10 +362,11 @@ module t (
|
|||
S2 = 3'd2
|
||||
} state_t;
|
||||
|
||||
int cyc;
|
||||
logic start;
|
||||
logic side;
|
||||
logic [2:0] dyn_case;
|
||||
int cyc = 0;
|
||||
logic start = 1'b0;
|
||||
logic side = 1'b0;
|
||||
logic dyn_side = 1'b0;
|
||||
logic [2:0] dyn_case = 3'd7;
|
||||
state_t state /*verilator fsm_reset_arc*/;
|
||||
|
||||
fsm_if_mixed_vars_bad mixed_vars_u (.clk(clk));
|
||||
|
|
@ -386,17 +387,10 @@ module t (
|
|||
fsm_direct_active_low_dynamic_reset_bad active_low_dynamic_reset_u (
|
||||
.clk(clk), .rst_n(cyc != 0), .dyn_reset(dyn_case[1:0]));
|
||||
|
||||
initial begin
|
||||
cyc = 0;
|
||||
start = 1'b0;
|
||||
side = 1'b0;
|
||||
dyn_case = 3'd7;
|
||||
end
|
||||
|
||||
always @(posedge clk) begin
|
||||
cyc <= cyc + 1;
|
||||
if (cyc == 1) side <= 1'b1;
|
||||
dyn_case <= {2'b11, side};
|
||||
if (cyc == 1) dyn_side <= 1'b1;
|
||||
dyn_case <= {2'b11, dyn_side};
|
||||
if (cyc == 5) begin
|
||||
$write("*-* All Finished *-*\n");
|
||||
$finish;
|
||||
|
|
|
|||
|
|
@ -17,11 +17,6 @@
|
|||
int cyc;
|
||||
state_t state;
|
||||
|
||||
initial begin
|
||||
cyc = 0;
|
||||
state = S0;
|
||||
end
|
||||
|
||||
always @(posedge clk) begin
|
||||
cyc <= cyc + 1;
|
||||
if (cyc == 4) begin
|
||||
|
|
|
|||
|
|
@ -16,11 +16,6 @@ module t (
|
|||
int cyc;
|
||||
state_t state;
|
||||
|
||||
initial begin
|
||||
cyc = 0;
|
||||
state = S0;
|
||||
end
|
||||
|
||||
always @(posedge clk) begin
|
||||
cyc <= cyc + 1;
|
||||
if (cyc == 4) begin
|
||||
|
|
|
|||
|
|
@ -65,13 +65,10 @@
|
|||
state_t state_q;
|
||||
state_t state_d;
|
||||
|
||||
initial begin
|
||||
aux = 1'b1;
|
||||
start = 1'b1;
|
||||
end
|
||||
|
||||
always_ff @(posedge clk) begin
|
||||
if (rst) begin
|
||||
aux <= 1'b1;
|
||||
start <= 1'b1;
|
||||
state_q <= S0;
|
||||
aux <= 1'b0;
|
||||
end else begin
|
||||
|
|
@ -81,14 +78,7 @@
|
|||
|
||||
always_comb begin
|
||||
state_d = state_q;
|
||||
%000002 case (state_q)
|
||||
// [FSM coverage]
|
||||
%000001 // [fsm_arc t.reset_other_assign_ok_u.state_q::ANY->S0[reset]] [reset arc, excluded from %]
|
||||
%000002 // [fsm_arc t.reset_other_assign_ok_u.state_q::S0->S1]
|
||||
%000000 // [fsm_arc t.reset_other_assign_ok_u.state_q::S0->S2]
|
||||
%000002 // [fsm_state t.reset_other_assign_ok_u.state_q::S0]
|
||||
%000002 // [fsm_state t.reset_other_assign_ok_u.state_q::S1]
|
||||
%000000 // [fsm_state t.reset_other_assign_ok_u.state_q::S2] *** UNCOVERED ***
|
||||
case (state_q)
|
||||
S0: state_d = start ? S1 : S2;
|
||||
default: state_d = S0;
|
||||
endcase
|
||||
|
|
@ -105,13 +95,8 @@
|
|||
S2 = 2'd2
|
||||
} state_t;
|
||||
|
||||
state_t state_q;
|
||||
state_t other_q;
|
||||
|
||||
initial begin
|
||||
state_q = S0;
|
||||
other_q = S2;
|
||||
end
|
||||
state_t state_q = S0;
|
||||
state_t other_q = S2;
|
||||
|
||||
always_ff @(posedge clk) begin
|
||||
if (rst) begin
|
||||
|
|
@ -140,13 +125,8 @@
|
|||
S2 = 2'd2
|
||||
} state_t;
|
||||
|
||||
state_t state_q;
|
||||
state_t other_q;
|
||||
|
||||
initial begin
|
||||
state_q = S0;
|
||||
other_q = S2;
|
||||
end
|
||||
state_t state_q = S0;
|
||||
state_t other_q = S2;
|
||||
|
||||
// Useful because the one-block reset fallback must ignore non-constant reset
|
||||
// assignments and still retain the supported case(state_q) FSM below.
|
||||
|
|
|
|||
|
|
@ -54,13 +54,10 @@ module fsm_reset_other_assign_ok (
|
|||
state_t state_q;
|
||||
state_t state_d;
|
||||
|
||||
initial begin
|
||||
aux = 1'b1;
|
||||
start = 1'b1;
|
||||
end
|
||||
|
||||
always_ff @(posedge clk) begin
|
||||
if (rst) begin
|
||||
aux <= 1'b1;
|
||||
start <= 1'b1;
|
||||
state_q <= S0;
|
||||
aux <= 1'b0;
|
||||
end else begin
|
||||
|
|
@ -87,13 +84,8 @@ module fsm_oneblock_reset_mismatch_ok (
|
|||
S2 = 2'd2
|
||||
} state_t;
|
||||
|
||||
state_t state_q;
|
||||
state_t other_q;
|
||||
|
||||
initial begin
|
||||
state_q = S0;
|
||||
other_q = S2;
|
||||
end
|
||||
state_t state_q = S0;
|
||||
state_t other_q = S2;
|
||||
|
||||
always_ff @(posedge clk) begin
|
||||
if (rst) begin
|
||||
|
|
@ -117,13 +109,8 @@ module fsm_oneblock_reset_nonconst_ok (
|
|||
S2 = 2'd2
|
||||
} state_t;
|
||||
|
||||
state_t state_q;
|
||||
state_t other_q;
|
||||
|
||||
initial begin
|
||||
state_q = S0;
|
||||
other_q = S2;
|
||||
end
|
||||
state_t state_q = S0;
|
||||
state_t other_q = S2;
|
||||
|
||||
// Useful because the one-block reset fallback must ignore non-constant reset
|
||||
// assignments and still retain the supported case(state_q) FSM below.
|
||||
|
|
|
|||
|
|
@ -65,13 +65,10 @@
|
|||
state_t state_q;
|
||||
state_t state_d;
|
||||
|
||||
initial begin
|
||||
aux = 1'b1;
|
||||
start = 1'b1;
|
||||
end
|
||||
|
||||
always_ff @(posedge clk) begin
|
||||
if (rst) begin
|
||||
aux <= 1'b1;
|
||||
start <= 1'b1;
|
||||
state_q <= S0;
|
||||
aux <= 1'b0;
|
||||
end else begin
|
||||
|
|
@ -81,14 +78,7 @@
|
|||
|
||||
always_comb begin
|
||||
state_d = state_q;
|
||||
%000002 case (state_q)
|
||||
// [FSM coverage]
|
||||
%000001 // [fsm_arc t.reset_other_assign_ok_u.state_q::ANY->S0[reset]]
|
||||
%000002 // [fsm_arc t.reset_other_assign_ok_u.state_q::S0->S1]
|
||||
%000000 // [fsm_arc t.reset_other_assign_ok_u.state_q::S0->S2]
|
||||
%000002 // [fsm_state t.reset_other_assign_ok_u.state_q::S0]
|
||||
%000002 // [fsm_state t.reset_other_assign_ok_u.state_q::S1]
|
||||
%000000 // [fsm_state t.reset_other_assign_ok_u.state_q::S2] *** UNCOVERED ***
|
||||
case (state_q)
|
||||
S0: state_d = start ? S1 : S2;
|
||||
default: state_d = S0;
|
||||
endcase
|
||||
|
|
@ -105,13 +95,8 @@
|
|||
S2 = 2'd2
|
||||
} state_t;
|
||||
|
||||
state_t state_q;
|
||||
state_t other_q;
|
||||
|
||||
initial begin
|
||||
state_q = S0;
|
||||
other_q = S2;
|
||||
end
|
||||
state_t state_q = S0;
|
||||
state_t other_q = S2;
|
||||
|
||||
always_ff @(posedge clk) begin
|
||||
if (rst) begin
|
||||
|
|
@ -140,13 +125,8 @@
|
|||
S2 = 2'd2
|
||||
} state_t;
|
||||
|
||||
state_t state_q;
|
||||
state_t other_q;
|
||||
|
||||
initial begin
|
||||
state_q = S0;
|
||||
other_q = S2;
|
||||
end
|
||||
state_t state_q = S0;
|
||||
state_t other_q = S2;
|
||||
|
||||
// Useful because the one-block reset fallback must ignore non-constant reset
|
||||
// assignments and still retain the supported case(state_q) FSM below.
|
||||
|
|
|
|||
|
|
@ -393,8 +393,6 @@
|
|||
%000004 state_t state_q;
|
||||
%000004 state_t state_d;
|
||||
|
||||
%000001 initial side = 1'b0;
|
||||
|
||||
000010 always_comb begin
|
||||
000010 state_d = state_q;
|
||||
000010 case (state_q)
|
||||
|
|
@ -404,8 +402,10 @@
|
|||
end
|
||||
|
||||
%000009 always_ff @(posedge clk) begin
|
||||
%000007 if (rst) state_q <= S0;
|
||||
%000007 else begin
|
||||
%000007 if (rst) begin
|
||||
%000002 side <= 1'b0;
|
||||
%000002 state_q <= S0;
|
||||
%000007 end else begin
|
||||
%000007 side <= ~side;
|
||||
%000007 state_q <= state_d;
|
||||
end
|
||||
|
|
|
|||
|
|
@ -336,8 +336,6 @@ module fsm_seqmix_off (
|
|||
state_t state_q;
|
||||
state_t state_d;
|
||||
|
||||
initial side = 1'b0;
|
||||
|
||||
always_comb begin
|
||||
state_d = state_q;
|
||||
case (state_q)
|
||||
|
|
@ -347,8 +345,10 @@ module fsm_seqmix_off (
|
|||
end
|
||||
|
||||
always_ff @(posedge clk) begin
|
||||
if (rst) state_q <= S0;
|
||||
else begin
|
||||
if (rst) begin
|
||||
side <= 1'b0;
|
||||
state_q <= S0;
|
||||
end else begin
|
||||
side <= ~side;
|
||||
state_q <= state_d;
|
||||
end
|
||||
|
|
|
|||
|
|
@ -760,6 +760,7 @@
|
|||
input logic start
|
||||
);
|
||||
/* verilator lint_off BLKANDNBLK */
|
||||
/* verilator lint_off MULTIDRIVEN */
|
||||
typedef enum logic [1:0] {
|
||||
S0 = 2'd0,
|
||||
S1 = 2'd1,
|
||||
|
|
@ -800,6 +801,7 @@
|
|||
.state_i(state_d),
|
||||
.state_o(state_q)
|
||||
);
|
||||
/* verilator lint_on MULTIDRIVEN */
|
||||
/* verilator lint_on BLKANDNBLK */
|
||||
endmodule
|
||||
|
||||
|
|
|
|||
|
|
@ -660,6 +660,7 @@ module fsm_competing_direct (
|
|||
input logic start
|
||||
);
|
||||
/* verilator lint_off BLKANDNBLK */
|
||||
/* verilator lint_off MULTIDRIVEN */
|
||||
typedef enum logic [1:0] {
|
||||
S0 = 2'd0,
|
||||
S1 = 2'd1,
|
||||
|
|
@ -692,6 +693,7 @@ module fsm_competing_direct (
|
|||
.state_i(state_d),
|
||||
.state_o(state_q)
|
||||
);
|
||||
/* verilator lint_on MULTIDRIVEN */
|
||||
/* verilator lint_on BLKANDNBLK */
|
||||
endmodule
|
||||
|
||||
|
|
|
|||
|
|
@ -86,22 +86,22 @@ module Test(/*AUTOARG*/
|
|||
wdata_d1r <= wdata;
|
||||
end
|
||||
|
||||
reg [31:0] csr0000;
|
||||
reg [31:0] csr0001;
|
||||
reg [31:0] csr0002;
|
||||
reg [31:0] csr0003;
|
||||
reg [31:0] csr0004;
|
||||
reg [31:0] csr0005;
|
||||
reg [31:0] csr0006;
|
||||
reg [31:0] csr0007;
|
||||
reg [31:0] csr0008;
|
||||
reg [31:0] csr0009;
|
||||
reg [31:0] csr000a;
|
||||
reg [31:0] csr000b;
|
||||
reg [31:0] csr000c;
|
||||
reg [31:0] csr000d;
|
||||
reg [31:0] csr000e;
|
||||
reg [31:0] csr000f;
|
||||
reg [31:0] csr0000 = 32'he172d365;
|
||||
reg [31:0] csr0001 = 32'h35cc25e2;
|
||||
reg [31:0] csr0002 = 32'haf48436e;
|
||||
reg [31:0] csr0003 = 32'h135e55e4;
|
||||
reg [31:0] csr0004 = 32'h5fd6e48a;
|
||||
reg [31:0] csr0005 = 32'hb07d34ad;
|
||||
reg [31:0] csr0006 = 32'h2aa05deb;
|
||||
reg [31:0] csr0007 = 32'hfe97b680;
|
||||
reg [31:0] csr0008 = 32'h960f20bb;
|
||||
reg [31:0] csr0009 = 32'h251129f0;
|
||||
reg [31:0] csr000a = 32'hef3d2f93;
|
||||
reg [31:0] csr000b = 32'hef4bc127;
|
||||
reg [31:0] csr000c = 32'h3dfecb10;
|
||||
reg [31:0] csr000d = 32'h1b4690f5;
|
||||
reg [31:0] csr000e = 32'ha07822ab;
|
||||
reg [31:0] csr000f = 32'hf817cbf6;
|
||||
wire [31:0] csr0010 = 32'h33675230;
|
||||
wire [31:0] csr0011 = 32'h00fa2144;
|
||||
wire [31:0] csr0012 = 32'h6a5e8e10;
|
||||
|
|
@ -118,25 +118,6 @@ module Test(/*AUTOARG*/
|
|||
wire [31:0] csr001d = 32'h02e7b33c;
|
||||
wire [31:0] csr001e = 32'h12101533;
|
||||
wire [31:0] csr001f = 32'h2cc1cce5;
|
||||
initial begin
|
||||
csr0000 = 32'he172d365;
|
||||
csr0001 = 32'h35cc25e2;
|
||||
csr0002 = 32'haf48436e;
|
||||
csr0003 = 32'h135e55e4;
|
||||
csr0004 = 32'h5fd6e48a;
|
||||
csr0005 = 32'hb07d34ad;
|
||||
csr0006 = 32'h2aa05deb;
|
||||
csr0007 = 32'hfe97b680;
|
||||
csr0008 = 32'h960f20bb;
|
||||
csr0009 = 32'h251129f0;
|
||||
csr000a = 32'hef3d2f93;
|
||||
csr000b = 32'hef4bc127;
|
||||
csr000c = 32'h3dfecb10;
|
||||
csr000d = 32'h1b4690f5;
|
||||
csr000e = 32'ha07822ab;
|
||||
csr000f = 32'hf817cbf6;
|
||||
end
|
||||
|
||||
always_ff @ (posedge clk) begin
|
||||
if (we_d1r && sel_d1r == 16'h0000) csr0000 <= wdata_d1r;
|
||||
if (we_d1r && sel_d1r == 16'h0001) csr0001 <= wdata_d1r;
|
||||
|
|
|
|||
|
|
@ -130,22 +130,22 @@ module Test ( /*AUTOARG*/
|
|||
wdata_d1r <= wdata;
|
||||
end
|
||||
|
||||
reg [31:0] csr0000;
|
||||
reg [31:0] csr0001;
|
||||
reg [31:0] csr0002;
|
||||
reg [31:0] csr0003;
|
||||
reg [31:0] csr0004;
|
||||
reg [31:0] csr0005;
|
||||
reg [31:0] csr0006;
|
||||
reg [31:0] csr0007;
|
||||
reg [31:0] csr0008;
|
||||
reg [31:0] csr0009;
|
||||
reg [31:0] csr000a;
|
||||
reg [31:0] csr000b;
|
||||
reg [31:0] csr000c;
|
||||
reg [31:0] csr000d;
|
||||
reg [31:0] csr000e;
|
||||
reg [31:0] csr000f;
|
||||
reg [31:0] csr0000 = 32'he172d365;
|
||||
reg [31:0] csr0001 = 32'h35cc25e2;
|
||||
reg [31:0] csr0002 = 32'haf48436e;
|
||||
reg [31:0] csr0003 = 32'h135e55e4;
|
||||
reg [31:0] csr0004 = 32'h5fd6e48a;
|
||||
reg [31:0] csr0005 = 32'hb07d34ad;
|
||||
reg [31:0] csr0006 = 32'h2aa05deb;
|
||||
reg [31:0] csr0007 = 32'hfe97b680;
|
||||
reg [31:0] csr0008 = 32'h960f20bb;
|
||||
reg [31:0] csr0009 = 32'h251129f0;
|
||||
reg [31:0] csr000a = 32'hef3d2f93;
|
||||
reg [31:0] csr000b = 32'hef4bc127;
|
||||
reg [31:0] csr000c = 32'h3dfecb10;
|
||||
reg [31:0] csr000d = 32'h1b4690f5;
|
||||
reg [31:0] csr000e = 32'ha07822ab;
|
||||
reg [31:0] csr000f = 32'hf817cbf6;
|
||||
wire [31:0] csr0010 = 32'h33675230;
|
||||
wire [31:0] csr0011 = 32'h00fa2144;
|
||||
wire [31:0] csr0012 = 32'h6a5e8e10;
|
||||
|
|
@ -162,25 +162,6 @@ module Test ( /*AUTOARG*/
|
|||
wire [31:0] csr001d = 32'h02e7b33c;
|
||||
wire [31:0] csr001e = 32'h12101533;
|
||||
wire [31:0] csr001f = 32'h2cc1cce5;
|
||||
initial begin
|
||||
csr0000 = 32'he172d365;
|
||||
csr0001 = 32'h35cc25e2;
|
||||
csr0002 = 32'haf48436e;
|
||||
csr0003 = 32'h135e55e4;
|
||||
csr0004 = 32'h5fd6e48a;
|
||||
csr0005 = 32'hb07d34ad;
|
||||
csr0006 = 32'h2aa05deb;
|
||||
csr0007 = 32'hfe97b680;
|
||||
csr0008 = 32'h960f20bb;
|
||||
csr0009 = 32'h251129f0;
|
||||
csr000a = 32'hef3d2f93;
|
||||
csr000b = 32'hef4bc127;
|
||||
csr000c = 32'h3dfecb10;
|
||||
csr000d = 32'h1b4690f5;
|
||||
csr000e = 32'ha07822ab;
|
||||
csr000f = 32'hf817cbf6;
|
||||
end
|
||||
|
||||
always_ff @(posedge clk) begin
|
||||
if (we_d1r && sel_d1r == 16'h0000) csr0000 <= wdata_d1r;
|
||||
if (we_d1r && sel_d1r == 16'h0001) csr0001 <= wdata_d1r;
|
||||
|
|
|
|||
|
|
@ -0,0 +1,19 @@
|
|||
%Warning-MULTIDRIVEN: t/t_lint_always_ff_multidriven_bad.v:14:5: Variable written to in always_ff also written by other process (IEEE 1800-2023 9.2.2.4): 'a'
|
||||
: ... note: In instance 't'
|
||||
t/t_lint_always_ff_multidriven_bad.v:14:5:
|
||||
14 | a <= 1'b1;
|
||||
| ^
|
||||
t/t_lint_always_ff_multidriven_bad.v:11:11: ... Location of other write
|
||||
11 | initial a = 1'b0;
|
||||
| ^
|
||||
... For warning description see https://verilator.org/warn/MULTIDRIVEN?v=latest
|
||||
... Use "/* verilator lint_off MULTIDRIVEN */" and lint_on around source to disable this message.
|
||||
%Warning-MULTIDRIVEN: t/t_lint_always_ff_multidriven_bad.v:23:11: Variable also written to in always_ff (IEEE 1800-2023 9.2.2.4): 'b'
|
||||
: ... note: In instance 't'
|
||||
t/t_lint_always_ff_multidriven_bad.v:23:11:
|
||||
23 | initial b = 1'b0;
|
||||
| ^
|
||||
t/t_lint_always_ff_multidriven_bad.v:20:5: ... Location of always_ff write
|
||||
20 | b <= 1'b1;
|
||||
| ^
|
||||
%Error: Exiting due to
|
||||
|
|
@ -0,0 +1,16 @@
|
|||
#!/usr/bin/env python3
|
||||
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
|
||||
#
|
||||
# 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 Wilson Snyder
|
||||
# SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0
|
||||
|
||||
import vltest_bootstrap
|
||||
|
||||
test.scenarios('linter')
|
||||
|
||||
test.lint(fails=True, expect_filename=test.golden_filename)
|
||||
|
||||
test.passes()
|
||||
|
|
@ -0,0 +1,25 @@
|
|||
// DESCRIPTION: Verilator: Verilog Test module
|
||||
//
|
||||
// This file ONLY is placed under the Creative Commons Public Domain.
|
||||
// SPDX-FileCopyrightText: 2026 Zhi QU
|
||||
// SPDX-License-Identifier: CC0-1.0
|
||||
|
||||
module t;
|
||||
|
||||
logic a;
|
||||
|
||||
initial a = 1'b0;
|
||||
|
||||
always_ff @(posedge a) begin
|
||||
a <= 1'b1; // <--- Warning
|
||||
end
|
||||
|
||||
logic b;
|
||||
|
||||
always_ff @(posedge b) begin
|
||||
b <= 1'b1;
|
||||
end
|
||||
|
||||
initial b = 1'b0; // <--- Warning
|
||||
|
||||
endmodule
|
||||
|
|
@ -254,15 +254,13 @@ endmodule
|
|||
// -> ^d[31:0]
|
||||
// Of course the correct result is ^d[38:0] = ^d
|
||||
module bug3470(input wire clk, input wire [31:0] in, output wire out);
|
||||
logic [38:0] d;
|
||||
initial d = 0;
|
||||
initial tmp = 0;
|
||||
initial expected = 0;
|
||||
logic [38:0] d = 0;
|
||||
logic tmp = 0;
|
||||
logic expected = 0;
|
||||
|
||||
always_ff @(posedge clk)
|
||||
d <= {d[6:0], in};
|
||||
|
||||
logic tmp, expected;
|
||||
always_ff @(posedge clk) begin
|
||||
tmp <= ^(d >> 32) ^ (^d[31:0]);
|
||||
expected <= ^d;
|
||||
|
|
|
|||
|
|
@ -19,9 +19,8 @@ module t ( /*AUTOARG*/
|
|||
);
|
||||
input clk;
|
||||
|
||||
int cyc;
|
||||
int cyc = 0;
|
||||
logic [`NUM_SUBS - 1:0] x;
|
||||
initial cyc = 0;
|
||||
|
||||
always_ff @(posedge clk) begin
|
||||
cyc <= cyc + 1;
|
||||
|
|
|
|||
Loading…
Reference in New Issue