parent
5ae285d268
commit
d40036239b
1
Changes
1
Changes
|
|
@ -13,6 +13,7 @@ Verilator 5.047 devel
|
|||
|
||||
**Other:**
|
||||
|
||||
* Fix wide conditional short circuiting (#7155).
|
||||
|
||||
|
||||
Verilator 5.046 2026-02-28
|
||||
|
|
|
|||
|
|
@ -2792,10 +2792,9 @@ static inline void VL_SELASSIGN_WW(int rbits, int obits, WDataOutP iowp, WDataIn
|
|||
//======================================================================
|
||||
// Triops
|
||||
|
||||
static inline WDataOutP VL_COND_WIWW(int obits, WDataOutP owp, int cond, WDataInP const w1p,
|
||||
WDataInP const w2p) VL_MT_SAFE {
|
||||
return VL_MEMCPY_W(owp, cond ? w1p : w2p, VL_WORDS_I(obits));
|
||||
}
|
||||
// This must be a macro in order for short-circuiting of the values to work.
|
||||
#define VL_COND_WIWW(obits, owp, cond, w1p, w2p) \
|
||||
VL_MEMCPY_W(owp, (cond) ? (w1p) : (w2p), VL_WORDS_I(obits))
|
||||
|
||||
//======================================================================
|
||||
// Constification
|
||||
|
|
|
|||
|
|
@ -39,37 +39,37 @@
|
|||
-000009 point: type=line comment=block hier=top.t
|
||||
%000009 {intf_sel_ff.foo, intf_sel_ff.bar, intf_sel_ff.baz} <=
|
||||
-000009 point: type=line comment=block hier=top.t
|
||||
%000009 cyc[0] ?
|
||||
-000009 point: type=branch comment=cond_then hier=top.t
|
||||
%000009 {intfs[1].foo, intfs[1].bar, intfs[1].baz} :
|
||||
-000009 point: type=branch comment=cond_then hier=top.t
|
||||
-000009 point: type=branch comment=cond_else hier=top.t
|
||||
%000009 {intfs[0].foo, intfs[0].bar, intfs[0].baz};
|
||||
-000009 point: type=branch comment=cond_else hier=top.t
|
||||
%000005 cyc[0] ?
|
||||
-000005 point: type=branch comment=cond_then hier=top.t
|
||||
%000005 {intfs[1].foo, intfs[1].bar, intfs[1].baz} :
|
||||
-000005 point: type=branch comment=cond_then hier=top.t
|
||||
-000004 point: type=branch comment=cond_else hier=top.t
|
||||
%000004 {intfs[0].foo, intfs[0].bar, intfs[0].baz};
|
||||
-000004 point: type=branch comment=cond_else hier=top.t
|
||||
end
|
||||
|
||||
000010 always_comb begin
|
||||
+000010 point: type=line comment=block hier=top.t
|
||||
000010 {intf_sel_comb.foo, intf_sel_comb.bar, intf_sel_comb.baz} =
|
||||
+000010 point: type=line comment=block hier=top.t
|
||||
000010 cyc[0] ?
|
||||
+000010 point: type=branch comment=cond_then hier=top.t
|
||||
000010 {intfs[1].foo, intfs[1].bar, intfs[1].baz} :
|
||||
+000010 point: type=branch comment=cond_then hier=top.t
|
||||
+000010 point: type=branch comment=cond_else hier=top.t
|
||||
000010 {intfs[0].foo, intfs[0].bar, intfs[0].baz};
|
||||
+000010 point: type=branch comment=cond_else hier=top.t
|
||||
%000005 cyc[0] ?
|
||||
-000005 point: type=branch comment=cond_then hier=top.t
|
||||
%000005 {intfs[1].foo, intfs[1].bar, intfs[1].baz} :
|
||||
-000005 point: type=branch comment=cond_then hier=top.t
|
||||
-000005 point: type=branch comment=cond_else hier=top.t
|
||||
%000005 {intfs[0].foo, intfs[0].bar, intfs[0].baz};
|
||||
-000005 point: type=branch comment=cond_else hier=top.t
|
||||
end
|
||||
|
||||
assign
|
||||
{intf_sel_assign.foo, intf_sel_assign.bar, intf_sel_assign.baz} =
|
||||
000010 cyc[0] ?
|
||||
+000010 point: type=branch comment=cond_then hier=top.t
|
||||
000010 {intfs[1].foo, intfs[1].bar, intfs[1].baz} :
|
||||
+000010 point: type=branch comment=cond_then hier=top.t
|
||||
+000010 point: type=branch comment=cond_else hier=top.t
|
||||
000010 {intfs[0].foo, intfs[0].bar, intfs[0].baz};
|
||||
+000010 point: type=branch comment=cond_else hier=top.t
|
||||
%000005 cyc[0] ?
|
||||
-000005 point: type=branch comment=cond_then hier=top.t
|
||||
%000005 {intfs[1].foo, intfs[1].bar, intfs[1].baz} :
|
||||
-000005 point: type=branch comment=cond_then hier=top.t
|
||||
-000005 point: type=branch comment=cond_else hier=top.t
|
||||
%000005 {intfs[0].foo, intfs[0].bar, intfs[0].baz};
|
||||
-000005 point: type=branch comment=cond_else hier=top.t
|
||||
|
||||
%000009 always @ (posedge clk) begin
|
||||
-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