FPGARelated.com
Forums

Why am I getting different results with two files collapsed into one?

Started by Kevin Simonson December 6, 2020
I wrote a Verilog file:
[code]
// (c) 2020 Kevin Simonson

module equ2
  ( output result
, output nrOut
, output xwOut
  , input  leftOp
  , input  rightOp);

wire    notRight, xorWeak;
supply1 power;
supply0 ground;

nmos #(3)  nRg( notRight, ground  , rightOp);
pmos #(3)  pRg( notRight, power   , rightOp);
nmos #(3) nXor( xorWeak , notRight, leftOp );
pmos #(3) pXor( xorWeak , right   , leftOp );
nmos #(3) nInv( result  , ground  , xorWeak);
pmos #(3) pInv( result  , power   , xorWeak);
assign nrOut =3D notRight;
assign xwOut =3D xorWeak ;

endmodule
[/code]
and then I wrote a driver:
[code]
module eqTest ();

wire rs;
wire nr, xw;
reg lfOp, rgOp;

equ2 eq( rs, nr, xw, lfOp, rgOp);

initial
begin
  lfOp    =3D 1'd0; rgOp =3D 1'd0;
  #10 $display( "lf: %d, rg: %d, nr: %d, xw: %d, rs: %d, exp: 1.", lfOp, rg=
Op, nr, xw, rs);
  #1 lfOp =3D 1'd1;
  #10 $display( "lf: %d, rg: %d, nr: %d, xw: %d, rs: %d, exp: 0.", lfOp, rg=
Op, nr, xw, rs);
  #1 lfOp =3D 1'd0; rgOp =3D 1'd1;
  #10 $display( "lf: %d, rg: %d, nr: %d, xw: %d, rs: %d, exp: 0.", lfOp, rg=
Op, nr, xw, rs);
  #1 lfOp =3D 1'd1;
  #10 $display( "lf: %d, rg: %d, nr: %d, xw: %d, rs: %d, exp: 1.", lfOp, rg=
Op, nr, xw, rs);
end

endmodule
[/code]
The purpose of (equ2) is to output in (result) a logical one if the two inp=
uts are identical, and to output in (result) a logical zero if the two inpu=
ts are different. I added outputs (nrOut) and (xwOut) so I could see interm=
ediate results along the way. When I ran this I got:
[code]
D:\Hf\Verilog\Unpacked\Wlt\Bug>\HdlTools\Icarus\bin\iverilog -g2009 -o eqTe=
st.vvp equ2.sv eqTest.sv

D:\Hf\Verilog\Unpacked\Wlt\Bug>\HdlTools\Icarus\bin\vvp eqTest.vvp
lf: 0, rg: 0, nr: 1, xw: z, rs: x, exp: 1.
lf: 1, rg: 0, nr: 1, xw: 1, rs: 0, exp: 0.
lf: 0, rg: 1, nr: 0, xw: z, rs: x, exp: 0.
lf: 1, rg: 1, nr: 0, xw: 0, rs: 1, exp: 1.

D:\Hf\Verilog\Unpacked\Wlt\Bug>
[/code]
This was not what I wanted, obviously. I tried moving all the functionality=
 into one file, and got:
[code]
module five ();

wire    rs  , notRight, xorWeak;
reg     lfOp, rgOp;
supply1 power;
supply0 ground;

nmos #(3)  nRg( notRight, ground  , rgOp   );
pmos #(3)  pRg( notRight, power   , rgOp   );
nmos #(3) nXor( xorWeak , notRight, lfOp   );
pmos #(3) pXor( xorWeak , rgOp    , lfOp   );
nmos #(3) nInv( rs      , ground  , xorWeak);
pmos #(3) pInv( rs      , power   , xorWeak);

initial
begin
  lfOp    =3D 1'd0; rgOp =3D 1'd0;
  #10 $display
         ( "lfOp: %d, rgOp: %d, notRight: %d, xorWeak: %d, rs: %d, expected=
: 1."
         ,  lfOp    , rgOp    , notRight    , xorWeak    , rs);
  #1 lfOp =3D 1'd1;
  #10 $display
         ( "lfOp: %d, rgOp: %d, notRight: %d, xorWeak: %d, rs: %d, expected=
: 0."
         ,  lfOp    , rgOp    , notRight    , xorWeak    , rs);
  #1 lfOp =3D 1'd0; rgOp =3D 1'd1;
  #10 $display
         ( "lfOp: %d, rgOp: %d, notRight: %d, xorWeak: %d, rs: %d, expected=
: 0."
         ,  lfOp    , rgOp    , notRight    , xorWeak    , rs);
  #1 lfOp =3D 1'd1;
  #10 $display
         ( "lfOp: %d, rgOp: %d, notRight: %d, xorWeak: %d, rs: %d, expected=
: 1."
         ,  lfOp    , rgOp    , notRight    , xorWeak    , rs);
end

endmodule
[/code]
When I ran this I got:
[code]
D:\Hf\Verilog\Unpacked\Wlt\Bug>\HdlTools\Icarus\bin\iverilog -g2009 -o five=
.vvp five.sv

D:\Hf\Verilog\Unpacked\Wlt\Bug>\HdlTools\Icarus\bin\vvp five.vvp
lfOp: 0, rgOp: 0, notRight: 1, xorWeak: 0, rs: 1, expected: 1.
lfOp: 1, rgOp: 0, notRight: 1, xorWeak: 1, rs: 0, expected: 0.
lfOp: 0, rgOp: 1, notRight: 0, xorWeak: 1, rs: 0, expected: 0.
lfOp: 1, rgOp: 1, notRight: 0, xorWeak: 0, rs: 1, expected: 1.

D:\Hf\Verilog\Unpacked\Wlt\Bug>
[/code]
This is precisely what I DID want. The two sets of code look virtually iden=
tical to me. Does anybody have any idea why I'm getting different results w=
hen I have the two files, "equ2.sv" and "eqTest.sv", than when I have just =
the one file, "five.sv"? Why is (xorWeak) ending up with a "z" value in "eq=
u2.sv" when (leftOp) has a zero value, while (xorWeak) has either a "0" val=
ue or a "1" value in "five.sv" with the same input?
On Sunday, 12/6/2020 12:27 AM, Kevin Simonson wrote:
> I wrote a Verilog file: > [code] > // (c) 2020 Kevin Simonson > > module equ2 > ( output result > , output nrOut > , output xwOut > , input leftOp > , input rightOp); > > wire notRight, xorWeak; > supply1 power; > supply0 ground; > > nmos #(3) nRg( notRight, ground , rightOp); > pmos #(3) pRg( notRight, power , rightOp); > nmos #(3) nXor( xorWeak , notRight, leftOp ); > pmos #(3) pXor( xorWeak , right , leftOp ); > nmos #(3) nInv( result , ground , xorWeak); > pmos #(3) pInv( result , power , xorWeak); > assign nrOut = notRight; > assign xwOut = xorWeak ; > > endmodule > [/code] > and then I wrote a driver: > [code] > module eqTest (); > > wire rs; > wire nr, xw; > reg lfOp, rgOp; > > equ2 eq( rs, nr, xw, lfOp, rgOp); > > initial > begin > lfOp = 1'd0; rgOp = 1'd0; > #10 $display( "lf: %d, rg: %d, nr: %d, xw: %d, rs: %d, exp: 1.", lfOp, rgOp, nr, xw, rs); > #1 lfOp = 1'd1; > #10 $display( "lf: %d, rg: %d, nr: %d, xw: %d, rs: %d, exp: 0.", lfOp, rgOp, nr, xw, rs); > #1 lfOp = 1'd0; rgOp = 1'd1; > #10 $display( "lf: %d, rg: %d, nr: %d, xw: %d, rs: %d, exp: 0.", lfOp, rgOp, nr, xw, rs); > #1 lfOp = 1'd1; > #10 $display( "lf: %d, rg: %d, nr: %d, xw: %d, rs: %d, exp: 1.", lfOp, rgOp, nr, xw, rs); > end > > endmodule > [/code] > The purpose of (equ2) is to output in (result) a logical one if the two inputs are identical, and to output in (result) a logical zero if the two inputs are different. I added outputs (nrOut) and (xwOut) so I could see intermediate results along the way. When I ran this I got: > [code] > D:\Hf\Verilog\Unpacked\Wlt\Bug>\HdlTools\Icarus\bin\iverilog -g2009 -o eqTest.vvp equ2.sv eqTest.sv > > D:\Hf\Verilog\Unpacked\Wlt\Bug>\HdlTools\Icarus\bin\vvp eqTest.vvp > lf: 0, rg: 0, nr: 1, xw: z, rs: x, exp: 1. > lf: 1, rg: 0, nr: 1, xw: 1, rs: 0, exp: 0. > lf: 0, rg: 1, nr: 0, xw: z, rs: x, exp: 0. > lf: 1, rg: 1, nr: 0, xw: 0, rs: 1, exp: 1. > > D:\Hf\Verilog\Unpacked\Wlt\Bug> > [/code] > This was not what I wanted, obviously. I tried moving all the functionality into one file, and got: > [code] > module five (); > > wire rs , notRight, xorWeak; > reg lfOp, rgOp; > supply1 power; > supply0 ground; > > nmos #(3) nRg( notRight, ground , rgOp ); > pmos #(3) pRg( notRight, power , rgOp ); > nmos #(3) nXor( xorWeak , notRight, lfOp ); > pmos #(3) pXor( xorWeak , rgOp , lfOp ); > nmos #(3) nInv( rs , ground , xorWeak); > pmos #(3) pInv( rs , power , xorWeak); > > initial > begin > lfOp = 1'd0; rgOp = 1'd0; > #10 $display > ( "lfOp: %d, rgOp: %d, notRight: %d, xorWeak: %d, rs: %d, expected: 1." > , lfOp , rgOp , notRight , xorWeak , rs); > #1 lfOp = 1'd1; > #10 $display > ( "lfOp: %d, rgOp: %d, notRight: %d, xorWeak: %d, rs: %d, expected: 0." > , lfOp , rgOp , notRight , xorWeak , rs); > #1 lfOp = 1'd0; rgOp = 1'd1; > #10 $display > ( "lfOp: %d, rgOp: %d, notRight: %d, xorWeak: %d, rs: %d, expected: 0." > , lfOp , rgOp , notRight , xorWeak , rs); > #1 lfOp = 1'd1; > #10 $display > ( "lfOp: %d, rgOp: %d, notRight: %d, xorWeak: %d, rs: %d, expected: 1." > , lfOp , rgOp , notRight , xorWeak , rs); > end > > endmodule > [/code] > When I ran this I got: > [code] > D:\Hf\Verilog\Unpacked\Wlt\Bug>\HdlTools\Icarus\bin\iverilog -g2009 -o five.vvp five.sv > > D:\Hf\Verilog\Unpacked\Wlt\Bug>\HdlTools\Icarus\bin\vvp five.vvp > lfOp: 0, rgOp: 0, notRight: 1, xorWeak: 0, rs: 1, expected: 1. > lfOp: 1, rgOp: 0, notRight: 1, xorWeak: 1, rs: 0, expected: 0. > lfOp: 0, rgOp: 1, notRight: 0, xorWeak: 1, rs: 0, expected: 0. > lfOp: 1, rgOp: 1, notRight: 0, xorWeak: 0, rs: 1, expected: 1. > > D:\Hf\Verilog\Unpacked\Wlt\Bug> > [/code] > This is precisely what I DID want. The two sets of code look virtually identical to me. Does anybody have any idea why I'm getting different results when I have the two files, "equ2.sv" and "eqTest.sv", than when I have just the one file, "five.sv"? Why is (xorWeak) ending up with a "z" value in "equ2.sv" when (leftOp) has a zero value, while (xorWeak) has either a "0" value or a "1" value in "five.sv" with the same input? >
nmos #(3) nRg( notRight, ground , rightOp); pmos #(3) pRg( notRight, power , rightOp); nmos #(3) nXor( xorWeak , notRight, leftOp ); pmos #(3) pXor( xorWeak , right , leftOp ); ^^^^ nmos #(3) nInv( result , ground , xorWeak); pmos #(3) pInv( result , power , xorWeak); assign nrOut = notRight; assign xwOut = xorWeak ; I think this needs to be rightOp instead of right to make the two codes equivalent. -- Gabor
On Sunday, 12/6/2020 4:46 PM, Gabor wrote:
> On Sunday, 12/6/2020 12:27 AM, Kevin Simonson wrote: >> I wrote a Verilog file: >> [code] >> // (c) 2020 Kevin Simonson >> >> module equ2 >>    ( output result >> , output nrOut >> , output xwOut >>    , input  leftOp >>    , input  rightOp); >> >> wire    notRight, xorWeak; >> supply1 power; >> supply0 ground; >> >> nmos #(3)  nRg( notRight, ground  , rightOp); >> pmos #(3)  pRg( notRight, power   , rightOp); >> nmos #(3) nXor( xorWeak , notRight, leftOp ); >> pmos #(3) pXor( xorWeak , right   , leftOp ); >> nmos #(3) nInv( result  , ground  , xorWeak); >> pmos #(3) pInv( result  , power   , xorWeak); >> assign nrOut = notRight; >> assign xwOut = xorWeak ; >> >> endmodule >> [/code] >> and then I wrote a driver: >> [code] >> module eqTest (); >> >> wire rs; >> wire nr, xw; >> reg lfOp, rgOp; >> >> equ2 eq( rs, nr, xw, lfOp, rgOp); >> >> initial >> begin >>    lfOp    = 1'd0; rgOp = 1'd0; >>    #10 $display( "lf: %d, rg: %d, nr: %d, xw: %d, rs: %d, exp: 1.", >> lfOp, rgOp, nr, xw, rs); >>    #1 lfOp = 1'd1; >>    #10 $display( "lf: %d, rg: %d, nr: %d, xw: %d, rs: %d, exp: 0.", >> lfOp, rgOp, nr, xw, rs); >>    #1 lfOp = 1'd0; rgOp = 1'd1; >>    #10 $display( "lf: %d, rg: %d, nr: %d, xw: %d, rs: %d, exp: 0.", >> lfOp, rgOp, nr, xw, rs); >>    #1 lfOp = 1'd1; >>    #10 $display( "lf: %d, rg: %d, nr: %d, xw: %d, rs: %d, exp: 1.", >> lfOp, rgOp, nr, xw, rs); >> end >> >> endmodule >> [/code] >> The purpose of (equ2) is to output in (result) a logical one if the >> two inputs are identical, and to output in (result) a logical zero if >> the two inputs are different. I added outputs (nrOut) and (xwOut) so I >> could see intermediate results along the way. When I ran this I got: >> [code] >> D:\Hf\Verilog\Unpacked\Wlt\Bug>\HdlTools\Icarus\bin\iverilog -g2009 -o >> eqTest.vvp equ2.sv eqTest.sv >> >> D:\Hf\Verilog\Unpacked\Wlt\Bug>\HdlTools\Icarus\bin\vvp eqTest.vvp >> lf: 0, rg: 0, nr: 1, xw: z, rs: x, exp: 1. >> lf: 1, rg: 0, nr: 1, xw: 1, rs: 0, exp: 0. >> lf: 0, rg: 1, nr: 0, xw: z, rs: x, exp: 0. >> lf: 1, rg: 1, nr: 0, xw: 0, rs: 1, exp: 1. >> >> D:\Hf\Verilog\Unpacked\Wlt\Bug> >> [/code] >> This was not what I wanted, obviously. I tried moving all the >> functionality into one file, and got: >> [code] >> module five (); >> >> wire    rs  , notRight, xorWeak; >> reg     lfOp, rgOp; >> supply1 power; >> supply0 ground; >> >> nmos #(3)  nRg( notRight, ground  , rgOp   ); >> pmos #(3)  pRg( notRight, power   , rgOp   ); >> nmos #(3) nXor( xorWeak , notRight, lfOp   ); >> pmos #(3) pXor( xorWeak , rgOp    , lfOp   ); >> nmos #(3) nInv( rs      , ground  , xorWeak); >> pmos #(3) pInv( rs      , power   , xorWeak); >> >> initial >> begin >>    lfOp    = 1'd0; rgOp = 1'd0; >>    #10 $display >>           ( "lfOp: %d, rgOp: %d, notRight: %d, xorWeak: %d, rs: %d, >> expected: 1." >>           ,  lfOp    , rgOp    , notRight    , xorWeak    , rs); >>    #1 lfOp = 1'd1; >>    #10 $display >>           ( "lfOp: %d, rgOp: %d, notRight: %d, xorWeak: %d, rs: %d, >> expected: 0." >>           ,  lfOp    , rgOp    , notRight    , xorWeak    , rs); >>    #1 lfOp = 1'd0; rgOp = 1'd1; >>    #10 $display >>           ( "lfOp: %d, rgOp: %d, notRight: %d, xorWeak: %d, rs: %d, >> expected: 0." >>           ,  lfOp    , rgOp    , notRight    , xorWeak    , rs); >>    #1 lfOp = 1'd1; >>    #10 $display >>           ( "lfOp: %d, rgOp: %d, notRight: %d, xorWeak: %d, rs: %d, >> expected: 1." >>           ,  lfOp    , rgOp    , notRight    , xorWeak    , rs); >> end >> >> endmodule >> [/code] >> When I ran this I got: >> [code] >> D:\Hf\Verilog\Unpacked\Wlt\Bug>\HdlTools\Icarus\bin\iverilog -g2009 -o >> five.vvp five.sv >> >> D:\Hf\Verilog\Unpacked\Wlt\Bug>\HdlTools\Icarus\bin\vvp five.vvp >> lfOp: 0, rgOp: 0, notRight: 1, xorWeak: 0, rs: 1, expected: 1. >> lfOp: 1, rgOp: 0, notRight: 1, xorWeak: 1, rs: 0, expected: 0. >> lfOp: 0, rgOp: 1, notRight: 0, xorWeak: 1, rs: 0, expected: 0. >> lfOp: 1, rgOp: 1, notRight: 0, xorWeak: 0, rs: 1, expected: 1. >> >> D:\Hf\Verilog\Unpacked\Wlt\Bug> >> [/code] >> This is precisely what I DID want. The two sets of code look virtually >> identical to me. Does anybody have any idea why I'm getting different >> results when I have the two files, "equ2.sv" and "eqTest.sv", than >> when I have just the one file, "five.sv"? Why is (xorWeak) ending up >> with a "z" value in "equ2.sv" when (leftOp) has a zero value, while >> (xorWeak) has either a "0" value or a "1" value in "five.sv" with the >> same input? >> > > nmos #(3)  nRg( notRight, ground  , rightOp); > pmos #(3)  pRg( notRight, power   , rightOp); > nmos #(3) nXor( xorWeak , notRight, leftOp ); > pmos #(3) pXor( xorWeak , right   , leftOp ); >                           ^^^^ > nmos #(3) nInv( result  , ground  , xorWeak); > pmos #(3) pInv( result  , power   , xorWeak); > assign nrOut = notRight; > assign xwOut = xorWeak ; > > I think this needs to be rightOp instead of right to make the two codes > equivalent. >
Just as a side note, I assume "right" was a typo. However the way the code is currently written it does not generate an error or even a warning, since it is perfectly OK to have implied wire creation. That's why I typically use `default_nettype to help find problems like this. For example if I add `default_nettype none to your code, and then include the "wire" declarations on inputs and outputs, I will get an error when compiling this: // (c) 2020 Kevin Simonson `default_nettype none module equ2 ( output wire result , output wire nrOut , output wire xwOut , input wire leftOp , input wire rightOp); wire notRight, xorWeak; supply1 power; supply0 ground; nmos #(3) nRg( notRight, ground , rightOp); pmos #(3) pRg( notRight, power , rightOp); nmos #(3) nXor( xorWeak , notRight, leftOp ); pmos #(3) pXor( xorWeak , right , leftOp ); nmos #(3) nInv( result , ground , xorWeak); pmos #(3) pInv( result , power , xorWeak); assign nrOut = notRight; assign xwOut = xorWeak ; endmodule `default_nettype wire With Xilinx ISIM I get: Analyzing Verilog file "C:/Projects/forums/../../Forums/newsgroup.v" into library isim_temp ERROR:HDLCompiler:69 - "C:/Projects/forums/../../Forums/newsgroup.v" Line 17: <right> is not declared. -- Gabor
On Sunday, December 6, 2020 at 2:06:18 PM UTC-8, Gabor wrote:

> Just as a side note, I assume "right" was a typo. However the way the > code is currently written it does not generate an error or even a > warning, since it is perfectly OK to have implied wire creation. That's > why I typically use `default_nettype to help find problems like this. > For example if I add `default_nettype none to your code, and then > include the "wire" declarations on inputs and outputs, I will get an > error when compiling this: > // (c) 2020 Kevin Simonson > `default_nettype none > module equ2 > ( output wire result > , output wire nrOut > , output wire xwOut > , input wire leftOp > , input wire rightOp); > wire notRight, xorWeak; > supply1 power; > supply0 ground; > > nmos #(3) nRg( notRight, ground , rightOp); > pmos #(3) pRg( notRight, power , rightOp); > nmos #(3) nXor( xorWeak , notRight, leftOp ); > pmos #(3) pXor( xorWeak , right , leftOp ); > nmos #(3) nInv( result , ground , xorWeak); > pmos #(3) pInv( result , power , xorWeak); > assign nrOut = notRight; > assign xwOut = xorWeak ; > > endmodule > `default_nettype wire > > With Xilinx ISIM I get: > Analyzing Verilog file "C:/Projects/forums/../../Forums/newsgroup.v" > into library isim_temp > ERROR:HDLCompiler:69 - "C:/Projects/forums/../../Forums/newsgroup.v" > Line 17: <right> is not declared. > > -- > Gabor
Thanks for finding my typo for me! I replaced (right) with (rightOp) and my code worked just fine. Thanks for pointing me to "`default_nettype" too. Do I just always insert "`default_nettype wire" right after "endmodule" in my Verilog source like you did?
On Wednesday, 12/9/2020 12:02 AM, Kevin Simonson wrote:
> On Sunday, December 6, 2020 at 2:06:18 PM UTC-8, Gabor wrote: > >> Just as a side note, I assume "right" was a typo. However the way the >> code is currently written it does not generate an error or even a >> warning, since it is perfectly OK to have implied wire creation. That's >> why I typically use `default_nettype to help find problems like this. >> For example if I add `default_nettype none to your code, and then >> include the "wire" declarations on inputs and outputs, I will get an >> error when compiling this: >> // (c) 2020 Kevin Simonson >> `default_nettype none >> module equ2 >> ( output wire result >> , output wire nrOut >> , output wire xwOut >> , input wire leftOp >> , input wire rightOp); >> wire notRight, xorWeak; >> supply1 power; >> supply0 ground; >> >> nmos #(3) nRg( notRight, ground , rightOp); >> pmos #(3) pRg( notRight, power , rightOp); >> nmos #(3) nXor( xorWeak , notRight, leftOp ); >> pmos #(3) pXor( xorWeak , right , leftOp ); >> nmos #(3) nInv( result , ground , xorWeak); >> pmos #(3) pInv( result , power , xorWeak); >> assign nrOut = notRight; >> assign xwOut = xorWeak ; >> >> endmodule >> `default_nettype wire >> >> With Xilinx ISIM I get: >> Analyzing Verilog file "C:/Projects/forums/../../Forums/newsgroup.v" >> into library isim_temp >> ERROR:HDLCompiler:69 - "C:/Projects/forums/../../Forums/newsgroup.v" >> Line 17: <right> is not declared. >> >> -- >> Gabor > > Thanks for finding my typo for me! I replaced (right) with (rightOp) and my code worked just fine. Thanks for pointing me to "`default_nettype" too. Do I just always insert "`default_nettype wire" right after "endmodule" in my Verilog source like you did? >
The line that does the job for you is at the top of the file before the module declaration: `default_nettype none `default_nettype, like `define, is global. Note that it is outside the module definition at top and bottom of the file. Putting the default net type back to wire at the end of your file allows you to compile other files that would break if implicit wire creation causes an error. You don't need to have this line at the end of the file if you're only compiling your own code and it's all written to avoid implicit wire creation. -- Gabor
On Wednesday, December 9, 2020 at 6:36:57 AM UTC-8, Gabor wrote:

> The line that does the job for you is at the top of the file before the > module declaration: > > `default_nettype none > > `default_nettype, like `define, is global. Note that it is outside the > module definition at top and bottom of the file. Putting the default > net type back to wire at the end of your file allows you to compile > other files that would break if implicit wire creation causes an error. > You don't need to have this line at the end of the file if you're only > compiling your own code and it's all written to avoid implicit wire > creation. > > -- > Gabor
Got it.