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}}};
|
||||
} else if (valName == "1" || valName == "r") {
|
||||
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();
|
||||
|
|
@ -166,6 +172,12 @@ class UdpVisitor final : public VNVisitor {
|
|||
} else if (oNodep->name() == "1") {
|
||||
logandp
|
||||
= 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); }
|
||||
// For logic processing.
|
||||
bool isEdgeTrig(std::string& valName) {
|
||||
if (valName == "x" || valName == "X") return false;
|
||||
if (valName == "*") return true;
|
||||
if (valName == "01" || valName == "p" || valName == "P" || valName == "r"
|
||||
|| valName == "R") {
|
||||
|
|
@ -204,7 +217,9 @@ class UdpVisitor final : public VNVisitor {
|
|||
return true;
|
||||
}
|
||||
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";
|
||||
else if (valName[0] == '0' || valName[1] == '1')
|
||||
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