Fix initialization of 2 state vars to zero

This commit is contained in:
Wilson Snyder 2009-11-23 19:08:25 -05:00
parent af5aa38bc3
commit d608fd77b9
8 changed files with 72 additions and 60 deletions

View File

@ -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

View File

@ -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);
}

View File

@ -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(); }

View File

@ -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,

View File

@ -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) {

View File

@ -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

View File

@ -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 (
);

View File

@ -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;