Search code examples
verilogsystem-verilog

Is there any way to make my simulation tool to drive error instead of doing wrong process multiple assignments in one variable?


As in my knowledge, any variable(including wire and net) cannot have more than one assignment.(wire variable: one continuous assignment allowed. reg variable: one procedure assignment in one block allowed)

However, I simulated the code below in EDA Playground with Aldec Riviera Pro 2022.04.

//1st testbench code
module test;
   
   wire a;
   assign a = 0;
   assign a = 1;

endmodule

I believed this should bring about multidrive-ERROR since variable a is driven by two assignment.

However, simulation works with no ERROR.

KERNEL: Simulation has finished. There are no more test vectors to simulate. VSIM: Simulation has finished.

I concluded that there are something wrong with this simulation of which design is not synthesizable. To test this, I revised the testbench code.

//2nd testbench code
module test_2;
   wire a;
   assign a = 0;
   assign a = 1;
  
   initial begin
      #10 $finish;
   end

    initial begin
      $dumpfiles("wave.vcd");
      $dumpvars(0, test_2);
   end

  endmodule

result: variable a gives 'x' during the whole process.(wave.vcd)

So, I thought my conclusion is right since 'x' is not eligible value for result of normal continuous assignment.

Is there any way to make my simulation tool to point out error out instead of doing process of wrong assignments in one variable?

//This code block also works well that is wrong since reg cannot be driven by continuous assignment.


module test_2;
   reg a;
   assign a = 0;

endmodule


Solution

  • a very basic answer on the difference between reg and wire:

    • Reg can be assigned with one continuous statement.

    • Reg can also be assigned with multiple procedural statements in the same block, but only one will take place (the chosen statement depends on some ordering rules and syntax in the block).

    • Wire can only be assigned with one continuous statement.

    You can refer to this question for more detailed answer on this topic:

    What is the difference between reg and wire in a verilog module?

    'X' is valid value in simulations and simulators, and LRMs (Language Reference Manual) define it as a valid value.

    • For a variable with a 4-state data data type, X is the default initial state
    • If a simulator is unable to decide whether a logic value should be a '1', '0', or 'Z' for high impedance, it will assign an X.

    You can read more about it here:

    What exactly do x and z values represent in Verilog?

    Also, there are synthesizable HW units where there are two drivers on the same net. For example, tri state buffers:

    https://nandland.com/create-tri-state-buffer-in-vhdl-and-verilog/

    The bottom line is:

    1. This is allowed by HDL syntax.
    2. There are cases when it's required to code multi driven net.
    3. X is a valid value that is used by simulators, and exists in simulation.
    4. Simulations are allowed to be executed on non-synthesizable HW.

    So, there is no reason for the simulator to give such error, other than the fact that you know it's a BUG.

    If you know for a fact that signal "a" should never get into state "X", and you want to fail the simulation on it, you need to add an assertion that it never happens.

    I am also not aware of any simulator which can give such error upon configuration, but perhaps this is an option that can be enabled in some simulators. Nevertheless, this can't be the default behavior of the simulator, as it contradicts the LRM.

    Multi driven nets are also identified by RTL linters which are directed towards synthesis, or by the synthesis tools themselves.

    For extra information, and to expand your knowledge on how X's are used in some verification methodologies, you can also read the next blog:

    https://www.techdesignforums.com/practice/technique/catch-x-propagation-issues-rtl/