mirror of
https://github.com/verilator/verilator.git
synced 2026-10-06 01:54:01 +02:00
Closes #7339.
This commit is contained in:
Executable
+18
@@ -0,0 +1,18 @@
|
||||
#!/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('simulator')
|
||||
|
||||
test.compile(timing_loop=True, verilator_flags2=['--timing'])
|
||||
|
||||
test.execute()
|
||||
|
||||
test.passes()
|
||||
@@ -0,0 +1,70 @@
|
||||
// DESCRIPTION: Verilator: Verilog Test module
|
||||
//
|
||||
// This file ONLY is placed under the Creative Commons Public Domain.
|
||||
// SPDX-FileCopyrightText: 2026 PlanV GmbH
|
||||
// SPDX-License-Identifier: CC0-1.0
|
||||
|
||||
// verilog_format: off
|
||||
`define stop $stop
|
||||
`define checkh(gotv,expv) do if ((gotv) !== (expv)) begin $write("%%Error: %s:%0d: got='h%x exp='h%x\n", `__FILE__,`__LINE__, (gotv), (expv)); `stop; end while(0);
|
||||
`ifdef verilator
|
||||
`define no_optimize(v) $c(v)
|
||||
`else
|
||||
`define no_optimize(v) (v)
|
||||
`endif
|
||||
// verilog_format: on
|
||||
|
||||
// verilator lint_off MULTIDRIVEN
|
||||
|
||||
interface ifc;
|
||||
// Tristate net resolved across an inout port connected hierarchically to
|
||||
// this interface signal (iface.data <-> dut inout port).
|
||||
wire [7:0] data;
|
||||
endinterface
|
||||
|
||||
module dut (
|
||||
inout wire [7:0] data,
|
||||
input bit oe,
|
||||
input logic [7:0] val
|
||||
);
|
||||
// The inout port drives the interface net when enabled, releases it (Z) otherwise.
|
||||
assign data = oe ? val : 8'hzz;
|
||||
endmodule
|
||||
|
||||
module t;
|
||||
ifc ifc0 ();
|
||||
bit oe, top_oe;
|
||||
logic [7:0] val, topval;
|
||||
|
||||
// A second driver from the top, so resolution is observable from both sides.
|
||||
assign ifc0.data = top_oe ? topval : 8'hzz;
|
||||
|
||||
dut u (
|
||||
.data(ifc0.data),
|
||||
.oe(oe),
|
||||
.val(val)
|
||||
);
|
||||
|
||||
initial begin
|
||||
// dut drives the interface net through the inout port.
|
||||
oe = `no_optimize(1'b1);
|
||||
val = `no_optimize(8'hA5);
|
||||
top_oe = `no_optimize(1'b0);
|
||||
topval = `no_optimize(8'h00);
|
||||
#1;
|
||||
`checkh(ifc0.data, 8'hA5);
|
||||
// top drives, dut releases.
|
||||
oe = `no_optimize(1'b0);
|
||||
top_oe = `no_optimize(1'b1);
|
||||
topval = `no_optimize(8'h3C);
|
||||
#1;
|
||||
`checkh(ifc0.data, 8'h3C);
|
||||
// Neither drives: net floats to Z.
|
||||
oe = `no_optimize(1'b0);
|
||||
top_oe = `no_optimize(1'b0);
|
||||
#1;
|
||||
`checkh(ifc0.data, 8'hzz);
|
||||
$write("*-* All Finished *-*\n");
|
||||
$finish;
|
||||
end
|
||||
endmodule
|
||||
+18
@@ -0,0 +1,18 @@
|
||||
#!/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('simulator')
|
||||
|
||||
test.compile(timing_loop=True, verilator_flags2=['--timing'])
|
||||
|
||||
test.execute()
|
||||
|
||||
test.passes()
|
||||
@@ -0,0 +1,104 @@
|
||||
// DESCRIPTION: Verilator: Verilog Test module
|
||||
//
|
||||
// This file ONLY is placed under the Creative Commons Public Domain.
|
||||
// SPDX-FileCopyrightText: 2026 PlanV GmbH
|
||||
// SPDX-License-Identifier: CC0-1.0
|
||||
|
||||
// verilog_format: off
|
||||
`define stop $stop
|
||||
`define checkh(gotv,expv) do if ((gotv) !== (expv)) begin $write("%%Error: %s:%0d: got='h%x exp='h%x\n", `__FILE__,`__LINE__, (gotv), (expv)); `stop; end while(0);
|
||||
`ifdef verilator
|
||||
`define no_optimize(v) $c(v)
|
||||
`else
|
||||
`define no_optimize(v) (v)
|
||||
`endif
|
||||
// verilog_format: on
|
||||
|
||||
// verilator lint_off MULTIDRIVEN
|
||||
|
||||
interface ifc;
|
||||
wire [1:0] w;
|
||||
// Self-contained interface-internal tristate driver: 'z while en==0, so any
|
||||
// external driver must win the net resolution. no_optimize keeps the driver
|
||||
// values from being constant-folded, so the resolution runs at run time.
|
||||
logic en;
|
||||
logic [1:0] wint;
|
||||
assign en = `no_optimize(1'b0);
|
||||
assign wint = `no_optimize(2'b11);
|
||||
assign w = en ? wint : 2'bzz;
|
||||
// Read the resolved net from inside the interface (a consumer's view), so the
|
||||
// check sees the true resolution, not the driving module's own local copy.
|
||||
function automatic logic [1:0] get_w();
|
||||
return w;
|
||||
endfunction
|
||||
endinterface
|
||||
|
||||
// Interface net made tristate only by an external 'z driver (no internal driver).
|
||||
interface ifc_tri;
|
||||
tri [1:0] w;
|
||||
endinterface
|
||||
|
||||
module driver (
|
||||
ifc io,
|
||||
input logic [1:0] din
|
||||
);
|
||||
// Plain (non-Z) cross-hierarchy driver of an interface tristate net.
|
||||
// This module's own tristate graph has no 'z on io.w, so before the fix this
|
||||
// contribution was silently dropped and io.w resolved to the interface-internal
|
||||
// 'z (== 0) only.
|
||||
assign io.w = din;
|
||||
endmodule
|
||||
|
||||
module driver_tri (
|
||||
ifc_tri io,
|
||||
input logic [1:0] din
|
||||
);
|
||||
assign io.w = din;
|
||||
endmodule
|
||||
|
||||
module zdriver (
|
||||
ifc_tri io
|
||||
);
|
||||
assign io.w = 2'bzz;
|
||||
endmodule
|
||||
|
||||
module t;
|
||||
// u_a, u_b: interface nets driven plainly from the top module (depth-0 xref).
|
||||
// u_c: interface net driven plainly from a child module (depth-1 xref).
|
||||
ifc u_a ();
|
||||
ifc u_b ();
|
||||
ifc u_c ();
|
||||
// u_e: net is tristate only via zdriver's external 'z; the plain driver must
|
||||
// still win (the interface itself has no internal driver).
|
||||
ifc_tri u_e ();
|
||||
|
||||
logic [1:0] va, vb, vc, ve;
|
||||
assign va = `no_optimize(2'b01);
|
||||
assign vb = `no_optimize(2'b10);
|
||||
assign vc = `no_optimize(2'b11);
|
||||
assign ve = `no_optimize(2'b01);
|
||||
|
||||
assign u_a.w = va; // plain top-level driver
|
||||
assign u_b.w = vb; // plain top-level driver
|
||||
driver u_drv (
|
||||
.io(u_c),
|
||||
.din(vc)
|
||||
); // plain driver in a child module
|
||||
driver_tri u_pdrv (
|
||||
.io(u_e),
|
||||
.din(ve)
|
||||
); // plain driver of an externally-tristated net
|
||||
zdriver u_zdrv (.io(u_e)); // external 'z driver
|
||||
|
||||
initial begin
|
||||
#1;
|
||||
// The plain external driver must win over the interface-internal 'z.
|
||||
`checkh(u_a.get_w(), 2'b01);
|
||||
`checkh(u_b.get_w(), 2'b10);
|
||||
`checkh(u_c.get_w(), 2'b11);
|
||||
// The plain driver must win over an external-only 'z (no internal driver).
|
||||
`checkh(u_e.w, 2'b01);
|
||||
$write("*-* All Finished *-*\n");
|
||||
$finish;
|
||||
end
|
||||
endmodule
|
||||
@@ -0,0 +1,19 @@
|
||||
#!/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('simulator')
|
||||
test.top_filename = "t_interface_tristate_plain_xhier.v"
|
||||
|
||||
test.compile(timing_loop=True, verilator_flags2=['--timing', '-fno-inline'])
|
||||
|
||||
test.execute()
|
||||
|
||||
test.passes()
|
||||
Reference in New Issue
Block a user