Kasra GH
Kasra GH

Reputation: 157

Change the top level's variables inside the called modules in verilog

I've been trying to somehow implement the usage of global variable in Verilog. Or alternatively, have a shared variable amongst the modules. Or even pass wires or register by reference (like the one we have in most high level languages like c++). Either of them will do the trick for me. But I couldn't implement any of them!

module topLevel(output [1:0] Output);

    wire[1:0] PC;

    sum s1();

    assign Output = PC;


endmodule


module sum();

    assign topLevel.PC = 2'b11;

endmodule

The code runs without any error but the value of "PC" hasn't changed. What should I do?

Upvotes: 0

Views: 3441

Answers (2)

Karan Shah
Karan Shah

Reputation: 1992

I ran this code in VCS and the PC value is properly being changed.

Please see the following.

module topLevel(output [1:0] Output);
  wire[1:0] PC;

  sum s1();

  assign Output = PC;

  initial
    $monitor ("PC - %0b", PC);
endmodule

module sum();
  assign topLevel.PC = 2'b11;
endmodule

// Output - 
PC - 11

However I am not sure about synthesizability of the following code.

Inside a module, you should always access the internal nets & ports only.

So in the above design, you can connect Output net to the ports of the sum module like the following.

module topLevel(output [1:0] Output);
  wire[1:0] PC;

  sum s1(PC);

  assign Output = PC;
endmodule

module sum(output [1:0] x);
  assign x = 2'b11;
endmodule

Upvotes: 0

Greg
Greg

Reputation: 19112

With SystemVerilog you can declare the variable in a package. From there you can import the the content of the package (or the specific variable) to the module. Then use the variables names as though it was locally declare. Or you can not import and access the variable via its package scope. Example:

package my_pkg; // packages are globally accessible
  logic [1:0] PC; // static variable
endpackage

module topLevel(output [1:0] Output);
  import my_pkg::PC;  // or   import my_pkg::*;

  sum1 #(0,3)  s1();
  sum2 #(10,1) s2();
  assign Output = PC; // or   assign Output = my_pkg::PC;
endmodule

module sum1 #(parameter TIME=0, VALUE=0) ();
  import my_pkg::PC;          // or   import my_pkg::*;
  initial #(TIME) PC = VALUE;
endmodule
module sum2 #(parameter TIME=0, VALUE=0) ();
  initial #(TIME) my_pkg::PC = VALUE;
endmodule

Note that this works for simulation only and is generically NOT synthesizable.

To be synthesizeable or work with Verilog, you must add PC to the port lists throughout the hierarchy and ensure that there is only one active driver assigning PC. This means driven by one assign statement or updated by one always block.

Verilog and SystemVerilog are HDLs (Hardware Description Languages). A net (wire) represents a physical wire that has to be routed from one logic gate's output to the inputs of other logic gates. Any type of referencing support in the HDL language was added only to be used by the test-bench in simulations.

Upvotes: 1

Related Questions