parent
5ae285d268
commit
d40036239b
1
Changes
1
Changes
|
|
@ -13,6 +13,7 @@ Verilator 5.047 devel
|
||||||
|
|
||||||
**Other:**
|
**Other:**
|
||||||
|
|
||||||
|
* Fix wide conditional short circuiting (#7155).
|
||||||
|
|
||||||
|
|
||||||
Verilator 5.046 2026-02-28
|
Verilator 5.046 2026-02-28
|
||||||
|
|
|
||||||
|
|
@ -2792,10 +2792,9 @@ static inline void VL_SELASSIGN_WW(int rbits, int obits, WDataOutP iowp, WDataIn
|
||||||
//======================================================================
|
//======================================================================
|
||||||
// Triops
|
// Triops
|
||||||
|
|
||||||
static inline WDataOutP VL_COND_WIWW(int obits, WDataOutP owp, int cond, WDataInP const w1p,
|
// This must be a macro in order for short-circuiting of the values to work.
|
||||||
WDataInP const w2p) VL_MT_SAFE {
|
#define VL_COND_WIWW(obits, owp, cond, w1p, w2p) \
|
||||||
return VL_MEMCPY_W(owp, cond ? w1p : w2p, VL_WORDS_I(obits));
|
VL_MEMCPY_W(owp, (cond) ? (w1p) : (w2p), VL_WORDS_I(obits))
|
||||||
}
|
|
||||||
|
|
||||||
//======================================================================
|
//======================================================================
|
||||||
// Constification
|
// Constification
|
||||||
|
|
|
||||||
|
|
@ -39,37 +39,37 @@
|
||||||
-000009 point: type=line comment=block hier=top.t
|
-000009 point: type=line comment=block hier=top.t
|
||||||
%000009 {intf_sel_ff.foo, intf_sel_ff.bar, intf_sel_ff.baz} <=
|
%000009 {intf_sel_ff.foo, intf_sel_ff.bar, intf_sel_ff.baz} <=
|
||||||
-000009 point: type=line comment=block hier=top.t
|
-000009 point: type=line comment=block hier=top.t
|
||||||
%000009 cyc[0] ?
|
%000005 cyc[0] ?
|
||||||
-000009 point: type=branch comment=cond_then hier=top.t
|
-000005 point: type=branch comment=cond_then hier=top.t
|
||||||
%000009 {intfs[1].foo, intfs[1].bar, intfs[1].baz} :
|
%000005 {intfs[1].foo, intfs[1].bar, intfs[1].baz} :
|
||||||
-000009 point: type=branch comment=cond_then hier=top.t
|
-000005 point: type=branch comment=cond_then hier=top.t
|
||||||
-000009 point: type=branch comment=cond_else hier=top.t
|
-000004 point: type=branch comment=cond_else hier=top.t
|
||||||
%000009 {intfs[0].foo, intfs[0].bar, intfs[0].baz};
|
%000004 {intfs[0].foo, intfs[0].bar, intfs[0].baz};
|
||||||
-000009 point: type=branch comment=cond_else hier=top.t
|
-000004 point: type=branch comment=cond_else hier=top.t
|
||||||
end
|
end
|
||||||
|
|
||||||
000010 always_comb begin
|
000010 always_comb begin
|
||||||
+000010 point: type=line comment=block hier=top.t
|
+000010 point: type=line comment=block hier=top.t
|
||||||
000010 {intf_sel_comb.foo, intf_sel_comb.bar, intf_sel_comb.baz} =
|
000010 {intf_sel_comb.foo, intf_sel_comb.bar, intf_sel_comb.baz} =
|
||||||
+000010 point: type=line comment=block hier=top.t
|
+000010 point: type=line comment=block hier=top.t
|
||||||
000010 cyc[0] ?
|
%000005 cyc[0] ?
|
||||||
+000010 point: type=branch comment=cond_then hier=top.t
|
-000005 point: type=branch comment=cond_then hier=top.t
|
||||||
000010 {intfs[1].foo, intfs[1].bar, intfs[1].baz} :
|
%000005 {intfs[1].foo, intfs[1].bar, intfs[1].baz} :
|
||||||
+000010 point: type=branch comment=cond_then hier=top.t
|
-000005 point: type=branch comment=cond_then hier=top.t
|
||||||
+000010 point: type=branch comment=cond_else hier=top.t
|
-000005 point: type=branch comment=cond_else hier=top.t
|
||||||
000010 {intfs[0].foo, intfs[0].bar, intfs[0].baz};
|
%000005 {intfs[0].foo, intfs[0].bar, intfs[0].baz};
|
||||||
+000010 point: type=branch comment=cond_else hier=top.t
|
-000005 point: type=branch comment=cond_else hier=top.t
|
||||||
end
|
end
|
||||||
|
|
||||||
assign
|
assign
|
||||||
{intf_sel_assign.foo, intf_sel_assign.bar, intf_sel_assign.baz} =
|
{intf_sel_assign.foo, intf_sel_assign.bar, intf_sel_assign.baz} =
|
||||||
000010 cyc[0] ?
|
%000005 cyc[0] ?
|
||||||
+000010 point: type=branch comment=cond_then hier=top.t
|
-000005 point: type=branch comment=cond_then hier=top.t
|
||||||
000010 {intfs[1].foo, intfs[1].bar, intfs[1].baz} :
|
%000005 {intfs[1].foo, intfs[1].bar, intfs[1].baz} :
|
||||||
+000010 point: type=branch comment=cond_then hier=top.t
|
-000005 point: type=branch comment=cond_then hier=top.t
|
||||||
+000010 point: type=branch comment=cond_else hier=top.t
|
-000005 point: type=branch comment=cond_else hier=top.t
|
||||||
000010 {intfs[0].foo, intfs[0].bar, intfs[0].baz};
|
%000005 {intfs[0].foo, intfs[0].bar, intfs[0].baz};
|
||||||
+000010 point: type=branch comment=cond_else hier=top.t
|
-000005 point: type=branch comment=cond_else hier=top.t
|
||||||
|
|
||||||
%000009 always @ (posedge clk) begin
|
%000009 always @ (posedge clk) begin
|
||||||
-000009 point: type=line comment=block hier=top.t
|
-000009 point: type=line comment=block hier=top.t
|
||||||
|
|
|
||||||
|
|
@ -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()
|
||||||
|
|
||||||
|
test.execute()
|
||||||
|
|
||||||
|
test.passes()
|
||||||
|
|
@ -0,0 +1,91 @@
|
||||||
|
// DESCRIPTION: Verilator: Verilog Test module
|
||||||
|
//
|
||||||
|
// This file ONLY is placed under the Creative Commons Public Domain.
|
||||||
|
// SPDX-FileCopyrightText: 2026 Wilson Snyder
|
||||||
|
// 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=%0x exp=%0x (%s !== %s)\n", `__FILE__,`__LINE__, (gotv), (expv), `"gotv`", `"expv`"); `stop; end while(0);
|
||||||
|
`ifdef verilator
|
||||||
|
`define optimize_barrier $c("")
|
||||||
|
`else
|
||||||
|
`define optimize_barrier
|
||||||
|
`endif
|
||||||
|
// verilog_format: on
|
||||||
|
|
||||||
|
module t;
|
||||||
|
|
||||||
|
class Map;
|
||||||
|
virtual function bit [95:0] get_value();
|
||||||
|
bit [95:0] result = 96'h11111111_22222222_33333333;
|
||||||
|
`optimize_barrier;
|
||||||
|
return result;
|
||||||
|
endfunction
|
||||||
|
endclass
|
||||||
|
|
||||||
|
class Cls;
|
||||||
|
function bit [95:0] get_default();
|
||||||
|
bit [95:0] result = 96'haaaaaaaa_bbbbbbbb_cccccccc;
|
||||||
|
`optimize_barrier;
|
||||||
|
return result;
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function bit [95:0] compute_LL(Map map);
|
||||||
|
bit [95:0] result;
|
||||||
|
`optimize_barrier;
|
||||||
|
// Wide operation is required, as results in VL_COND call which evaluates
|
||||||
|
// arguments
|
||||||
|
result = map == null ? this.get_default() : map.get_value();
|
||||||
|
`optimize_barrier;
|
||||||
|
return result;
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function bit [95:0] compute_LC(Map map);
|
||||||
|
bit [95:0] result;
|
||||||
|
bit sel1 = map == null;
|
||||||
|
`optimize_barrier;
|
||||||
|
result = sel1 ? 96'hffffffff_ffffffff_ffffffff : map.get_value();
|
||||||
|
`optimize_barrier;
|
||||||
|
return result;
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function bit [95:0] compute_CL(Map map);
|
||||||
|
bit [95:0] result;
|
||||||
|
bit sel1 = map != null;
|
||||||
|
`optimize_barrier;
|
||||||
|
result = sel1 ? map.get_value() : 96'hffffffff_ffffffff_ffffffff;
|
||||||
|
`optimize_barrier;
|
||||||
|
return result;
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
endclass
|
||||||
|
|
||||||
|
initial begin
|
||||||
|
Cls c;
|
||||||
|
Map mnull;
|
||||||
|
Map m;
|
||||||
|
bit [95:0] res;
|
||||||
|
|
||||||
|
c = new;
|
||||||
|
m = new;
|
||||||
|
|
||||||
|
res = c.compute_LL(mnull);
|
||||||
|
`checkh(res, 96'haaaaaaaa_bbbbbbbb_cccccccc);
|
||||||
|
res = c.compute_LL(m);
|
||||||
|
`checkh(res, 96'h11111111_22222222_33333333);
|
||||||
|
|
||||||
|
res = c.compute_LC(mnull);
|
||||||
|
`checkh(res, 96'hffffffff_ffffffff_ffffffff);
|
||||||
|
res = c.compute_LC(m);
|
||||||
|
`checkh(res, 96'h11111111_22222222_33333333);
|
||||||
|
|
||||||
|
res = c.compute_CL(mnull);
|
||||||
|
`checkh(res, 96'hffffffff_ffffffff_ffffffff);
|
||||||
|
res = c.compute_CL(m);
|
||||||
|
`checkh(res, 96'h11111111_22222222_33333333);
|
||||||
|
|
||||||
|
$finish;
|
||||||
|
end
|
||||||
|
|
||||||
|
endmodule
|
||||||
Loading…
Reference in New Issue