Input port cannot be driven

Hi,

When i bind an interface to the DUT, i get the following error:
**“Variable input ports cannot be driven.”
**
For example:

module A (
  input logic [31:0] addr
);

wire [31:0] addr_local;

assign addr_local = addr;

endmodule


interface dut_io ();

logic [31:0] addr;

endinterface


module tb;

   A a();
   dut_io io_if();

   assign a.addr = io_if.addr;

endmodule

But, when i remove the logic from the module A interface, everything is o.k.
Can anyone explain why i have this error, and how can i fix it without changing the dut?
I tried to use modports, but it didn’t help.
Thanks for your help.,

In reply to stas2005:

The error that you are getting is not correct. Please check the version of the tool that you are using and contact your vendor. There is no difference between

module A (
  input logic [31:0] addr
);

and

module A (
  input [31:0] addr
);

because they both declare ports that are implicitly ‘wire’. The first has an explicit data type 'logic, and the second has an implicit data type ‘logic’. See section 23.2.2.3 Rules for determining port kind, data type, and direction in the 1800-2012 LRM.

However, you can change the way you instantiate your dut to:

module tb;
 
   A a(io_if.addr);
   dut_io io_if();
 
endmodule


In reply to dave_59:

Thank you Dave,
I use latest version of VCS (L-2016.06-1). I tried with different versions, but still getting the same error:

Error-[VIPCBD] Variable input ports cannot be driven
tb.sv, 25
Variable input ports cannot be driven.
The input variable port “addr” of module “A” cannot be driven.
Source info: assign tb.a.addr = tb.io_if.addr;
Module ‘A’ is defined at “tb.sv”, 1

Unfortunately, I can’t use your suggestion in our TB without modifying a lot of files.
Maybe i’m missing some flags. I used the following command for this example:
vcs -lca -sverilog tb.sv

Thanks

In reply to stas2005:

I opened a case to Synopsys, and this is the answer I got. Thought it might help to someone else.

You can see below (LRM) that Assignments to variables declared as input ports shall be illegal.

23.3.3.2 Port connection rules for variables If a port declaration has a variable data type, then its direction controls how it can be connected when instantiated, as follows:
— An input port can be connected to any expression of a compatible data type. A continuous assignment shall be implied when a variable is connected to an input port declaration. Assignments to variables declared as input ports shall be illegal. If left unconnected, the port shall have the default initial value corresponding to the data type.

When you have logic inside the port declaration of addr, addr become variable (not net). When you omit logic, addr become net and it legal to assign to it directly.

You can do two experiments to see that without logic, addr become wire (net).
module A (
input [31:0] addr ///<— omit logic
//input logic [31:0] addr
);

wire [31:0] addr; ///<---- No error! legal logic [31:0] addr; ///<— ERORR! Ilegal

wire [31:0] addr_local;

assign addr_local = addr;

endmodule

In reply to stas2005:
But the port is a net, not a variable. See section 23.2.2.3 Rules for determining port kind, data type, and direction (“kind” is net or variable)
If the port kind is omitted:

  • For input and inout ports, the port shall default to a net of default net type. The default net type can be changed using the `default_nettype compiler directive (see 22.8).
  • For output ports, the default port kind depends on how the data type is specified:
  • - If the data type is omitted or declared with the implicit_data_type syntax, the port kind shall default to a net of default net type.
    - If the data type is declared with the explicit data_type syntax, the port kind shall default to variable.

Since this an an input port with the port kind omitted, it is a net.

In reply to stas2005:

can you please tell me how did you resolve this issue

is there any way to resolve this issue without removing logic

In reply to jela:

There are a number of ways to resolve this issue without removing the keyword logic.

  • Use a version of a tool that supports the LRM correctly
  • Add wire to port declaration
  • Change the port direction to inout
  • Remove the continuous assignment to the input port
  • Replace the assign with a force

In reply to stas2005:

In reply to stas2005:
I opened a case to Synopsys, and this is the answer I got. Thought it might help to someone else.
You can see below (LRM) that Assignments to variables declared as input ports shall be illegal.
23.3.3.2 Port connection rules for variables If a port declaration has a variable data type, then its direction controls how it can be connected when instantiated, as follows:
— An input port can be connected to any expression of a compatible data type. A continuous assignment shall be implied when a variable is connected to an input port declaration. Assignments to variables declared as input ports shall be illegal. If left unconnected, the port shall have the default initial value corresponding to the data type.
When you have logic inside the port declaration of addr, addr become variable (not net). When you omit logic, addr become net and it legal to assign to it directly.
You can do two experiments to see that without logic, addr become wire (net).
module A (
input [31:0] addr ///<— omit logic
//input logic [31:0] addr
);
wire [31:0] addr; ///<---- No error! legal logic [31:0] addr; ///<— ERORR! Ilegal
wire [31:0] addr_local;
assign addr_local = addr;
endmodule

SYNOPSYS has a switch for it. Ask their AE.

Another way,
I use vesion : vcs_all_vT-2022.06-sp2
Add compile option: -sv_net_ports
This will tel vcs deal the logic port as wire/net