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

I wrote a Verilog file:

  // (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

and then I wrote a driver:
  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, rg Op, nr, xw, rs); #1 lfOp = 1'd1; #10 $display( "lf: %d, rg: %d, nr: %d, xw: %d, rs: %d, exp: 0.", lfOp, rg Op, 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, rg Op, nr, xw, rs); #1 lfOp = 1'd1; #10 $display( "lf: %d, rg: %d, nr: %d, xw: %d, rs: %d, exp: 1.", lfOp, rg Op, nr, xw, rs); end

endmodule

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

This was not what I wanted, obviously. I tried moving all the functionality into one file, and got:
  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

When I ran this I got:
  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>

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?

Reply to
Kevin Simonson
Loading thread data ...

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
Reply to
Gabor

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: is not declared.

--
Gabor
Reply to
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?

Reply to
Kevin Simonson

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
Reply to
Gabor

Got it.

Reply to
Kevin Simonson

ElectronDepot website is not affiliated with any of the manufacturers or service providers discussed here. All logos and trade names are the property of their respective owners.