Fix initialization of 2 state vars to zero
This commit is contained in:
parent
af5aa38bc3
commit
d608fd77b9
|
|
@ -238,7 +238,6 @@ descriptions in the next sections for more information.
|
|||
--trace Enable waveform creation
|
||||
--trace-depth <levels> Depth of tracing
|
||||
-U<var> Undefine preprocessor define
|
||||
--underline-zero Zero signals with leading _'s
|
||||
--unroll-count <loops> Tune maximum loop iterations
|
||||
--unroll-stmts <stmts> Tune maximum loop body size
|
||||
-V Verbose version and config
|
||||
|
|
@ -628,13 +627,6 @@ Specify the number of levels deep to enable tracing, for example
|
|||
entire model. Using a small number will decrease visibility, but greatly
|
||||
improve runtime and trace file size.
|
||||
|
||||
=item --underline-zero
|
||||
|
||||
Rarely needed. Signals starting with a underline should be initialized to
|
||||
zero, as was done in Verilator 2. Default is for all signals including
|
||||
those with underlines being randomized. This option may be depreciated in
|
||||
future versions.
|
||||
|
||||
=item --unroll-count I<loops>
|
||||
|
||||
Rarely needed. Specifies the maximum number of loop iterations that may be
|
||||
|
|
|
|||
|
|
@ -241,6 +241,9 @@ public:
|
|||
int isFourstate() const {
|
||||
return m_e==INTEGER || m_e==LOGIC || m_e==LOGIC_IMPLICIT;
|
||||
}
|
||||
int isZeroInit() const { // Otherwise initializes to X
|
||||
return m_e==BIT || m_e==BYTE || m_e==INT || m_e==LONGINT || m_e==SHORTINT;
|
||||
}
|
||||
int isSloppy() const { // Don't be as anal about width warnings
|
||||
return !(m_e==LOGIC || m_e==BIT);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -231,6 +231,7 @@ public:
|
|||
virtual int widthTotalBytes() const; // (Slow) recurses - Width in bytes rounding up 1,2,4,8,12,...
|
||||
bool isBitLogic() const { return keyword().isBitLogic(); }
|
||||
bool isSloppy() const { return keyword().isSloppy(); }
|
||||
bool isZeroInit() const { return keyword().isZeroInit(); }
|
||||
int msb() const { if (!rangep()) return 0; return rangep()->msbConst(); }
|
||||
int lsb() const { if (!rangep()) return 0; return rangep()->lsbConst(); }
|
||||
int msbEndianed() const { if (!rangep()) return 0; return littleEndian()?rangep()->lsbConst():rangep()->msbConst(); }
|
||||
|
|
|
|||
|
|
@ -1238,6 +1238,7 @@ void EmitCImp::emitVarResets(AstNodeModule* modp) {
|
|||
puts("; ++"+ivar+") {\n");
|
||||
}
|
||||
bool zeroit = (varp->attrFileDescr() // Zero it out, so we don't core dump if never call $fopen
|
||||
|| (varp->basicp() && varp->basicp()->isZeroInit())
|
||||
|| (varp->name().c_str()[0]=='_' && v3Global.opt.underlineZero()));
|
||||
if (varp->isWide()) {
|
||||
// DOCUMENT: We randomize everything. If the user wants a _var to be zero,
|
||||
|
|
|
|||
|
|
@ -682,7 +682,7 @@ void V3Options::parseOptsList(FileLine* fl, int argc, char** argv) {
|
|||
else if ( onoff (sw, "-stats", flag/*ref*/) ) { m_stats = flag; }
|
||||
else if ( onoff (sw, "-trace", flag/*ref*/) ) { m_trace = flag; }
|
||||
else if ( onoff (sw, "-trace-dups", flag/*ref*/) ) { m_traceDups = flag; }
|
||||
else if ( onoff (sw, "-underline-zero", flag/*ref*/) ) { m_underlineZero = flag; }
|
||||
else if ( onoff (sw, "-underline-zero", flag/*ref*/) ) { m_underlineZero = flag; } // Undocumented, old Verilator-2
|
||||
// Optimization
|
||||
else if ( !strncmp (sw, "-O", 2) ) {
|
||||
for (const char* cp=sw+strlen("-O"); *cp; ++cp) {
|
||||
|
|
|
|||
|
|
@ -116,7 +116,7 @@ class V3Options {
|
|||
bool m_stats; // main switch: --stats
|
||||
bool m_trace; // main switch: --trace
|
||||
bool m_traceDups; // main switch: --trace-dups
|
||||
bool m_underlineZero;// main switch: --underline-zero
|
||||
bool m_underlineZero;// main switch: --underline-zero; undocumented old Verilator 2
|
||||
|
||||
int m_errorLimit; // main switch: --error-limit
|
||||
int m_inlineMult; // main switch: --inline-mult
|
||||
|
|
|
|||
|
|
@ -7,6 +7,8 @@ if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); di
|
|||
# Lesser General Public License Version 3 or the Perl Artistic License
|
||||
# Version 2.0.
|
||||
|
||||
$Self->{verilated_randReset} = 1; # allow checking if we initialize vars to zero only when needed
|
||||
|
||||
compile (
|
||||
);
|
||||
|
||||
|
|
|
|||
|
|
@ -48,54 +48,66 @@ module t (/*AUTOARG*/);
|
|||
localparam logic [1:0] p_logic2= {96{1'b1}};
|
||||
// verilator lint_on WIDTH
|
||||
|
||||
// We do this in two steps so we can check that initialization inside functions works properly
|
||||
// verilator lint_off WIDTH
|
||||
function f_implicit; f_implicit = {96{1'b1}}; endfunction
|
||||
function [89:0] f_explicit; f_explicit = {96{1'b1}}; endfunction
|
||||
function byte f_byte; f_byte = {96{1'b1}}; endfunction
|
||||
function shortint f_shortint; f_shortint = {96{1'b1}}; endfunction
|
||||
function int f_int; f_int = {96{1'b1}}; endfunction
|
||||
function longint f_longint; f_longint = {96{1'b1}}; endfunction
|
||||
function integer f_integer; f_integer = {96{1'b1}}; endfunction
|
||||
function reg f_reg; f_reg = {96{1'b1}}; endfunction
|
||||
function bit f_bit; f_bit = {96{1'b1}}; endfunction
|
||||
function logic f_logic; f_logic = {96{1'b1}}; endfunction
|
||||
function reg [1:0] f_reg2; f_reg2 = {96{1'b1}}; endfunction
|
||||
function bit [1:0] f_bit2; f_bit2 = {96{1'b1}}; endfunction
|
||||
function logic [1:0] f_logic2; f_logic2 = {96{1'b1}}; endfunction
|
||||
function time f_time; f_time = {96{1'b1}}; endfunction
|
||||
function f_implicit; reg lv_implicit; f_implicit = lv_implicit; endfunction
|
||||
function [89:0] f_explicit; reg [89:0] lv_explicit; f_explicit = lv_explicit; endfunction
|
||||
function byte f_byte; byte lv_byte; f_byte = lv_byte; endfunction
|
||||
function shortint f_shortint; shortint lv_shortint; f_shortint = lv_shortint; endfunction
|
||||
function int f_int; int lv_int; f_int = lv_int; endfunction
|
||||
function longint f_longint; longint lv_longint; f_longint = lv_longint; endfunction
|
||||
function integer f_integer; integer lv_integer; f_integer = lv_integer; endfunction
|
||||
function reg f_reg; reg lv_reg; f_reg = lv_reg; endfunction
|
||||
function bit f_bit; bit lv_bit; f_bit = lv_bit; endfunction
|
||||
function logic f_logic; logic lv_logic; f_logic = lv_logic; endfunction
|
||||
function reg [1:0] f_reg2; reg [1:0] lv_reg2; f_reg2 = lv_reg2; endfunction
|
||||
function bit [1:0] f_bit2; bit [1:0] lv_bit2; f_bit2 = lv_bit2; endfunction
|
||||
function logic [1:0] f_logic2; logic [1:0] lv_logic2; f_logic2 = lv_logic2; endfunction
|
||||
function time f_time; time lv_time; f_time = lv_time; endfunction
|
||||
// verilator lint_on WIDTH
|
||||
|
||||
`define CHECK_ALL(name,bits,issigned,twostate) \
|
||||
`ifdef verilator
|
||||
// For verilator zeroinit detection to work properly, we need to x-rand-reset to all 1s. This is the default!
|
||||
`define XINIT 1'b1
|
||||
`define ALL_TWOSTATE 1'b1
|
||||
`else
|
||||
`define XINIT 1'bx
|
||||
`define ALL_TWOSTATE 1'b0
|
||||
`endif
|
||||
|
||||
`define CHECK_ALL(name,nbits,issigned,twostate,zeroinit) \
|
||||
if (zeroinit ? ((name & 1'b1)!==1'b0) : ((name & 1'b1)!==`XINIT)) \
|
||||
begin $display("%%Error: Bad zero/X init for %s: %b",`"name`",name); $stop; end \
|
||||
name = {96{1'b1}}; \
|
||||
if (name !== {(bits){1'b1}}) begin $display("%%Error: Bad size for %s",`"name`"); $stop; end \
|
||||
if (name !== {(nbits){1'b1}}) begin $display("%%Error: Bad size for %s",`"name`"); $stop; end \
|
||||
if (issigned ? (name > 0) : (name < 0)) begin $display("%%Error: Bad signed for %s",`"name`"); $stop; end \
|
||||
name = {96{1'bx}}; \
|
||||
|
||||
//Everything is twostate in Verilator
|
||||
// if (name !== {(bits){twostate ? 1'b0 : 1'bx}}) begin $display("%%Error: Bad twostate for %s",`"name`"); $stop; end \
|
||||
if (name !== {(nbits){`ALL_TWOSTATE ? `XINIT : (twostate ? 1'b0 : `XINIT)}}) \
|
||||
begin $display("%%Error: Bad twostate for %s: %b",`"name`",name); $stop; end \
|
||||
|
||||
initial begin
|
||||
// verilator lint_off WIDTH
|
||||
// verilator lint_off UNSIGNED
|
||||
// name b sign twost
|
||||
`CHECK_ALL(d_byte ,8 ,1'b1,1'b1);
|
||||
`CHECK_ALL(d_shortint ,16,1'b1,1'b1);
|
||||
`CHECK_ALL(d_int ,32,1'b1,1'b1);
|
||||
`CHECK_ALL(d_longint ,64,1'b1,1'b1);
|
||||
`CHECK_ALL(d_integer ,32,1'b1,1'b0);
|
||||
`CHECK_ALL(d_time ,64,1'b0,1'b1);
|
||||
`CHECK_ALL(d_bit ,1 ,1'b0,1'b1);
|
||||
`CHECK_ALL(d_logic ,1 ,1'b0,1'b0);
|
||||
`CHECK_ALL(d_reg ,1 ,1'b0,1'b0);
|
||||
`CHECK_ALL(d_bit2 ,2 ,1'b0,1'b1);
|
||||
`CHECK_ALL(d_logic2 ,2 ,1'b0,1'b0);
|
||||
`CHECK_ALL(d_reg2 ,2 ,1'b0,1'b0);
|
||||
// name b sign twost 0init
|
||||
`CHECK_ALL(d_byte ,8 ,1'b1,1'b1,1'b1);
|
||||
`CHECK_ALL(d_shortint ,16,1'b1,1'b1,1'b1);
|
||||
`CHECK_ALL(d_int ,32,1'b1,1'b1,1'b1);
|
||||
`CHECK_ALL(d_longint ,64,1'b1,1'b1,1'b1);
|
||||
`CHECK_ALL(d_integer ,32,1'b1,1'b0,1'b0);
|
||||
`CHECK_ALL(d_time ,64,1'b0,1'b0,1'b0);
|
||||
`CHECK_ALL(d_bit ,1 ,1'b0,1'b1,1'b1);
|
||||
`CHECK_ALL(d_logic ,1 ,1'b0,1'b0,1'b0);
|
||||
`CHECK_ALL(d_reg ,1 ,1'b0,1'b0,1'b0);
|
||||
`CHECK_ALL(d_bit2 ,2 ,1'b0,1'b1,1'b1);
|
||||
`CHECK_ALL(d_logic2 ,2 ,1'b0,1'b0,1'b0);
|
||||
`CHECK_ALL(d_reg2 ,2 ,1'b0,1'b0,1'b0);
|
||||
// verilator lint_on WIDTH
|
||||
// verilator lint_on UNSIGNED
|
||||
|
||||
`define CHECK_P(name,bits) \
|
||||
if (name !== {(bits){1'b1}}) begin $display("%%Error: Bad size for %s",`"name`"); $stop; end \
|
||||
`define CHECK_P(name,nbits) \
|
||||
if (name !== {(nbits){1'b1}}) begin $display("%%Error: Bad size for %s",`"name`"); $stop; end \
|
||||
|
||||
// name b
|
||||
`CHECK_P(p_implicit ,96);
|
||||
`CHECK_P(p_explicit ,90);
|
||||
`CHECK_P(p_byte ,8 );
|
||||
|
|
@ -110,23 +122,24 @@ module t (/*AUTOARG*/);
|
|||
`CHECK_P(p_logic2 ,2 );
|
||||
`CHECK_P(p_reg2 ,2 );
|
||||
|
||||
`define CHECK_F(name,bits) \
|
||||
if (name() !== {(bits){1'b1}}) begin $display("%%Error: Bad size for %s",`"name`"); $stop; end \
|
||||
`define CHECK_F(fname,nbits,zeroinit) \
|
||||
if ($bits(fname()) !== nbits) begin $display("%%Error: Bad size for %s",`"fname`"); $stop; end \
|
||||
|
||||
`CHECK_F(f_implicit ,1 ); // Note 1 bit, not 96
|
||||
`CHECK_F(f_explicit ,90);
|
||||
`CHECK_F(f_byte ,8 );
|
||||
`CHECK_F(f_shortint ,16);
|
||||
`CHECK_F(f_int ,32);
|
||||
`CHECK_F(f_longint ,64);
|
||||
`CHECK_F(f_integer ,32);
|
||||
`CHECK_F(f_time ,64);
|
||||
`CHECK_F(f_bit ,1 );
|
||||
`CHECK_F(f_logic ,1 );
|
||||
`CHECK_F(f_reg ,1 );
|
||||
`CHECK_F(f_bit2 ,2 );
|
||||
`CHECK_F(f_logic2 ,2 );
|
||||
`CHECK_F(f_reg2 ,2 );
|
||||
// name b 0init
|
||||
`CHECK_F(f_implicit ,1 ,1'b0); // Note 1 bit, not 96
|
||||
`CHECK_F(f_explicit ,90,1'b0);
|
||||
`CHECK_F(f_byte ,8 ,1'b1);
|
||||
`CHECK_F(f_shortint ,16,1'b1);
|
||||
`CHECK_F(f_int ,32,1'b1);
|
||||
`CHECK_F(f_longint ,64,1'b1);
|
||||
`CHECK_F(f_integer ,32,1'b0);
|
||||
`CHECK_F(f_time ,64,1'b0);
|
||||
`CHECK_F(f_bit ,1 ,1'b1);
|
||||
`CHECK_F(f_logic ,1 ,1'b0);
|
||||
`CHECK_F(f_reg ,1 ,1'b0);
|
||||
`CHECK_F(f_bit2 ,2 ,1'b1);
|
||||
`CHECK_F(f_logic2 ,2 ,1'b0);
|
||||
`CHECK_F(f_reg2 ,2 ,1'b0);
|
||||
|
||||
// For unpacked types we don't want width warnings for unsized numbers that fit
|
||||
d_byte = 2;
|
||||
|
|
|
|||
Loading…
Reference in New Issue