Fix X handling in UDPs (#6723)
This commit is contained in:
parent
087ca15138
commit
9632c614be
|
|
@ -138,6 +138,12 @@ class UdpVisitor final : public VNVisitor {
|
||||||
fl, logandp, new AstLogNot{fl, new AstVarRef{fl, varp, VAccess::READ}}};
|
fl, logandp, new AstLogNot{fl, new AstVarRef{fl, varp, VAccess::READ}}};
|
||||||
} else if (valName == "1" || valName == "r") {
|
} else if (valName == "1" || valName == "r") {
|
||||||
logandp = new AstLogAnd{fl, logandp, new AstVarRef{fl, varp, VAccess::READ}};
|
logandp = new AstLogAnd{fl, logandp, new AstVarRef{fl, varp, VAccess::READ}};
|
||||||
|
} else if (valName == "x" || valName == "X") {
|
||||||
|
// No x inputs supported yet, so this whole table line
|
||||||
|
// can never match. Drop the whole thing.
|
||||||
|
if (edgetrigp) pushDeletep(edgetrigp);
|
||||||
|
if (logandp) pushDeletep(logandp);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
iNodep = iNodep->nextp();
|
iNodep = iNodep->nextp();
|
||||||
|
|
@ -166,6 +172,12 @@ class UdpVisitor final : public VNVisitor {
|
||||||
} else if (oNodep->name() == "1") {
|
} else if (oNodep->name() == "1") {
|
||||||
logandp
|
logandp
|
||||||
= new AstLogAnd{fl, logandp, new AstVarRef{fl, m_oFieldVarp, VAccess::READ}};
|
= new AstLogAnd{fl, logandp, new AstVarRef{fl, m_oFieldVarp, VAccess::READ}};
|
||||||
|
} else if (oNodep->name() == "x" || oNodep->name() == "X") {
|
||||||
|
// No x inputs supported yet, so this whole table line
|
||||||
|
// can never match. Drop the whole thing.
|
||||||
|
if (edgetrigp) pushDeletep(edgetrigp);
|
||||||
|
if (logandp) pushDeletep(logandp);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -192,6 +204,7 @@ class UdpVisitor final : public VNVisitor {
|
||||||
void visit(AstLogNot* nodep) override { iterateChildren(nodep); }
|
void visit(AstLogNot* nodep) override { iterateChildren(nodep); }
|
||||||
// For logic processing.
|
// For logic processing.
|
||||||
bool isEdgeTrig(std::string& valName) {
|
bool isEdgeTrig(std::string& valName) {
|
||||||
|
if (valName == "x" || valName == "X") return false;
|
||||||
if (valName == "*") return true;
|
if (valName == "*") return true;
|
||||||
if (valName == "01" || valName == "p" || valName == "P" || valName == "r"
|
if (valName == "01" || valName == "p" || valName == "P" || valName == "r"
|
||||||
|| valName == "R") {
|
|| valName == "R") {
|
||||||
|
|
@ -204,7 +217,9 @@ class UdpVisitor final : public VNVisitor {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
if (valName.size() == 2) {
|
if (valName.size() == 2) {
|
||||||
if (valName[0] == '1' || valName[1] == '0')
|
if (valName[0] == 'x' || valName[0] == 'X' || valName[1] == 'x' || valName[1] == 'X')
|
||||||
|
valName = "x";
|
||||||
|
else if (valName[0] == '1' || valName[1] == '0')
|
||||||
valName = "f";
|
valName = "f";
|
||||||
else if (valName[0] == '0' || valName[1] == '1')
|
else if (valName[0] == '0' || valName[1] == '1')
|
||||||
valName = "r";
|
valName = "r";
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,18 @@
|
||||||
|
#!/usr/bin/env python3
|
||||||
|
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
|
||||||
|
#
|
||||||
|
# Copyright 2025 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('vlt_all')
|
||||||
|
|
||||||
|
test.compile()
|
||||||
|
|
||||||
|
test.execute()
|
||||||
|
|
||||||
|
test.passes()
|
||||||
|
|
@ -0,0 +1,49 @@
|
||||||
|
// DESCRIPTION: Verilator: Verilog Test module
|
||||||
|
//
|
||||||
|
// This file ONLY is placed under the Creative Commons Public Domain, for
|
||||||
|
// any use, without warranty, 2025 by Michael Bikovitsky.
|
||||||
|
// SPDX-License-Identifier: CC0-1.0
|
||||||
|
|
||||||
|
module t ();
|
||||||
|
|
||||||
|
wire true1;
|
||||||
|
not1 a(true1, '0);
|
||||||
|
|
||||||
|
wire false1;
|
||||||
|
not1 b(false1, '1);
|
||||||
|
|
||||||
|
wire true2;
|
||||||
|
not1 c(true2, '0);
|
||||||
|
|
||||||
|
wire false2;
|
||||||
|
not1 d(false2, '1);
|
||||||
|
|
||||||
|
initial begin
|
||||||
|
if (true1 != '1) $stop;
|
||||||
|
if (false1 != '0) $stop;
|
||||||
|
if (true2 != '1) $stop;
|
||||||
|
if (false2 != '0) $stop;
|
||||||
|
$finish;
|
||||||
|
end
|
||||||
|
|
||||||
|
endmodule
|
||||||
|
|
||||||
|
primitive not1 (q, d);
|
||||||
|
output q;
|
||||||
|
input d;
|
||||||
|
table
|
||||||
|
0 : 1;
|
||||||
|
1 : 0;
|
||||||
|
x : x;
|
||||||
|
endtable
|
||||||
|
endprimitive
|
||||||
|
|
||||||
|
primitive not2 (q, d);
|
||||||
|
output q;
|
||||||
|
input d;
|
||||||
|
table
|
||||||
|
0 : 1;
|
||||||
|
1 : 0;
|
||||||
|
X : X;
|
||||||
|
endtable
|
||||||
|
endprimitive
|
||||||
|
|
@ -0,0 +1,18 @@
|
||||||
|
#!/usr/bin/env python3
|
||||||
|
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
|
||||||
|
#
|
||||||
|
# Copyright 2025 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('vlt_all')
|
||||||
|
|
||||||
|
test.compile(verilator_flags2=["--x-assign", "1"])
|
||||||
|
|
||||||
|
test.execute()
|
||||||
|
|
||||||
|
test.passes()
|
||||||
|
|
@ -0,0 +1,66 @@
|
||||||
|
// DESCRIPTION: Verilator: Verilog Test module
|
||||||
|
//
|
||||||
|
// This file ONLY is placed under the Creative Commons Public Domain, for
|
||||||
|
// any use, without warranty, 2025 by Michael Bikovitsky.
|
||||||
|
// SPDX-License-Identifier: CC0-1.0
|
||||||
|
|
||||||
|
module t (
|
||||||
|
input wire clk
|
||||||
|
);
|
||||||
|
|
||||||
|
wire q1;
|
||||||
|
pos i_pos(q1, clk);
|
||||||
|
|
||||||
|
wire q2;
|
||||||
|
neg i_neg(q2, clk);
|
||||||
|
|
||||||
|
integer cycle = 0;
|
||||||
|
always @(posedge clk) begin
|
||||||
|
if (cycle == 10) $finish;
|
||||||
|
cycle <= cycle + 1;
|
||||||
|
end
|
||||||
|
|
||||||
|
always @(q1 or q2) begin
|
||||||
|
// q1 should be assigned to 0 on every posedge and to X otherwise.
|
||||||
|
// So when the value of q1 changes, *and* clk is positive, we expect
|
||||||
|
// q1 to be 1.
|
||||||
|
// Same for q2, but on the negedge.
|
||||||
|
if (clk && q1) $stop;
|
||||||
|
if (!clk && q2) $stop;
|
||||||
|
end
|
||||||
|
|
||||||
|
endmodule
|
||||||
|
|
||||||
|
primitive pos (q, clk);
|
||||||
|
output q;
|
||||||
|
reg q;
|
||||||
|
input clk;
|
||||||
|
table
|
||||||
|
(01) : ? : 0;
|
||||||
|
// Explicitly set the output to X on clk 0->X edge.
|
||||||
|
// This edge can never happen in Verilator.
|
||||||
|
// If all edges *from* 0 are treated as rising edges, this will cause
|
||||||
|
// the output to be 1, since we use --x-assign 1, and the test will fail.
|
||||||
|
// (Actually this depends on the evaluation order of the always blocks
|
||||||
|
// that V3Udp.cpp creates, but at the time of writing they seem to be
|
||||||
|
// evaluated in the order of the lines in the table.)
|
||||||
|
(0x) : ? : x;
|
||||||
|
endtable
|
||||||
|
endprimitive
|
||||||
|
|
||||||
|
primitive neg (q, clk);
|
||||||
|
output q;
|
||||||
|
reg q;
|
||||||
|
input clk;
|
||||||
|
table
|
||||||
|
(10) : ? : 0;
|
||||||
|
// Explicitly set the output to X on clk X->0 edge.
|
||||||
|
// This edge can never happen in Verilator.
|
||||||
|
// If all edges *to* 0 are treated as falling edges, this will cause
|
||||||
|
// the output to be 1, since we use --x-assign 1, and the test will fail.
|
||||||
|
// (Actually this depends on the evaluation order of the always blocks
|
||||||
|
// that V3Udp.cpp creates, but at the time of writing they seem to be
|
||||||
|
// evaluated in the order of the lines in the table.)
|
||||||
|
(x0) : ? : x;
|
||||||
|
endtable
|
||||||
|
endprimitive
|
||||||
Loading…
Reference in New Issue