In reply to tfitz:
Thanks Tom.
In reply to mseyunni:
Can you please elaborate on what you said above, may be with an example.
virtual interfaces come into play when using classes to defer at a later stage the definition of the physical interface to the one being worked on in the class.
The other advantage is that a class can be instanced multiple times and connect to different physical interfaces.
As mentioned previously, you cannot refer in a class an actual interface. Consider a system with two redundant identical buses. Both may be active, thus serving different DUTs, or they may be redundant for self-checking, where the passive bus has its drivers inactive (i.e., the driver is in monitor/checking mode). Below is such an example.
class mem_agent extends uvm_agent;
mem_sequencer sequencer;
mem_driver driver1, driver2; // <--- 2 drivers
mem_monitor monitor;
mem_checker m_checker;
virtual mem_if mem_if_1, mem_if2; // <-- 2 identical interfaces
...
extern virtual function void connect_phase(uvm_phase phase);
endclass : mem_agent
function void mem_agent::connect_phase(uvm_phase phase);
//...
this.driver1.vif = this.mem_if_1; // <-- the connection to driver1
this.driver2.vif = this.mem_if_2; // <-- the connection to driver2
endfunction : connect_phase
Ben Cohen SystemVerilog.us
Interface signals are static ( Physically available ) & where Class are dynamic and which needed virtual interface to communicate the actual interface signals
In reply to mseyunni:
Hi tfitz,
Does it mean that by declaring the interface as virtual then all classes using that interface will obtain the same values?
For example, driver will put a value on the virtual interface, then the monitor will get the same value also.
Is this the reason why virtual is used for the interface?
Thanks.
Regards,
Reuben
The interface is used to simplify the connection between DUT and Testbench. As the interface can’t be instantiated inside a class or program block, we need a virtual interface to point the physical interface.
So, the virtual interface is a pointer to the actual interface and using virtual interface, a class can point to different physical interfaces, dynamically (at run time).
In reply to Reuben:
Does it mean that by declaring the interface as virtual then all classes using that interface will obtain the same values?
For example, driver will put a value on the virtual interface, then the monitor will get the same value also.
Yes, using virtual interface, it is possible that the data driven by the driver is available to monitor, if the same instance of an interface is passed to both.
In reply to mseyunni:
The question is why you need “virtual interface” in System Verilog.
Well, you dont. You can easily connect module ports to class members by dotting into the module.
You could also 'define the module signal in order to get a single place to change when you change your class based TB to another module.
But people use it because it is a variable that refers to the interface’s dotted net.
virtual Interface_Name foo; can save the name for you, which you can use as a generic foo.
Cheers.
Soummya
In reply to mallick1:
Well, you dont. You can easily connect module ports to class members by dotting into the module.
You could also 'define the module signal in order to get a single place to change when you change your class based TB to another module.
virtual Interface_Name foo; can save the name for you, which you can use as a generic foo.
Can you elaborate on those above?
In reply to mallick1:
Well, you dont. You can easily connect module ports to class members by dotting into the module.
This is the crux of the issue. If you are putting classes in a package, you can’t have hierarchical references (dotted names) inside a package, and even if not using packages, you should not be putting in hierarchical reference inside to make your testbench re-usable. A `define won’t work if several instances of the class needs to connect to different places in the design.
In reply to mseyunni:
Responding to seyunni, you can easily drive a module wire from within a task member of a class as follows
task drive();
@(posedge clk)
dut.signal <= 1;
without needing any virtual interface.
As Dave pointed out earlier, you dont want hierarchical references in your class based tb for reasons he mentioned.
Also mentioned is that vi provides runtime binding, i.e. connections can be made and broken (only to be remade again) at run time (I rarely do). 'defines will fall short.
Soummya
In reply to mallick1:
I disagree with your statement "you can easily drive a module wire from within a task member of a class as follows
task drive();
@(posedge clk)
dut.signal <= 1;
Below is an example from my SVA book on verifying assertions. See the task is_illegal;
module ld_reg #(SIZE=8)
(input logic clk, ld,
input logic[SIZE-1:0] d_in,
output logic[SIZE-1:0] r_out, d_out,k_out,
inout logic[SIZE-1:0] data1, data2, data3);
logic a, b=1'b1, oe; // local variable
wire[SIZE-1:0] wdata1, wdata2, wdata3;
always @ (posedge clk) begin : FF_LD
// The begin statement is only needed
// if multiple statements in body of always
r_out <= d_in;
// data1 <= d_in; // illegal
// line above: A net is not a legal lvalue in this context
// wdata1 = d_in; // illegal
// line above: A net is not a legal lvalue in this context
//assign wdata3 = 'bZ; // illegal
assign d_out=oe ? 8'b101_1110 : 'bZ;
end : FF_LD
task is_illegal;
@ (posedge clk)
data1 <= d_in; // Illegal reference to net "data1".
wdata1 <= d_in; // Illegal reference to net "wdata1".
endtask
assign data1 = oe ? 8'b101_0000 : 'bZ;
assign k_out=8'b10X_XZZ0;
endmodule : ld_reg
I explain in the book the following:
Assignments to inout port or module wire:
In reply to ben@SystemVerilog.us:
Thanks Ben for your input.
The example you are showing has got to do with continuous assign contention and that is true.
If 2 continuous assigns drive the same net, it will go to x in a hurry.
The question asked here has got to do with the question virtual interface existance in the language, at least that is what I am trying to answer.
The port being driven in my example dut.signal, whether driven via a virtual interface or a member of a modport, through a dotted reference, needs to be legally driveable, i.e. needs to be an input wire or NOT a wire.
Soummya
In reply to mallick1:
Your initial statement was “drive a module wire from within a task”
Can’t do that from a task.
You clarified by stating “legally driveable, i.e. needs to be an input wire or NOT a wire.” What about driving an inout port of a module when the state is in the input mode?
Again, you can’t do that from within a task, regardless of where the task is (i.e., in a module or a class instance).
SystemVerilog interface do have wires too.
Ben Cohen SystemVerilog.us
In reply to ben@SystemVerilog.us:
Hi Ben,
You are right.
In my mind, the legally drivable statement covers the wire/reg caveats.
Thanks for your point about inout wire port configured as input.
I am surprised as to why you say this is not drivable from a task. hope you can elaborate
I have been driving inout ports with ff->(reg q)->(inout wire net) all the time.
Soummya
Thanks for your inputs guys. All of them are helpful.
I like what Dave said regarding the disadvantage of using dotting to drive a signal. I was using that before in my testcase, test.env.agt.drv.signal <= 1’b1. But now I think I should not since the test will not become reusable.
In reply to mallick1:
I can’t easily locate where in 1800 those rules are defined. However, with 2 separate simulators, I get the same errors for the following code:
module ld_reg #(SIZE=8)
(input logic clk, ld,
input logic[SIZE-1:0] d_in,
output logic[SIZE-1:0] r_out, d_out,k_out,
inout logic[SIZE-1:0] data1, data2, data3);
logic a, b=1'b1, oe; // local variable
wire[SIZE-1:0] wdata1, wdata2, wdata3;
always @ (posedge clk) begin : FF_LD
// The begin statement is only needed
// if multiple statements in body of always
r_out <= d_in;
data3 <= d_in; // **** illegal LINE 13
// line above: A net is not a legal lvalue in this context
// wdata1 = d_in; // illegal
// line above: A net is not a legal lvalue in this context
//assign wdata3 = 'bZ; // illegal
assign d_out=oe ? 8'b101_1110 : 'bZ;
end : FF_LD
task is_illegal;
@ (posedge clk)
data1 <= d_in; // **** Illegal reference to net "data1". line 23
wdata1 <= d_in; // Illegal reference to net "wdata1".
endtask
// assign data1 = oe ? 8'b101_0000 : 'bZ;
assign k_out=8'b10X_XZZ0;
endmodule : ld_reg
// COMPILATION RESULTS:
# ** Error: ld_reg.sv(13): Illegal reference to net "data3".
#
# ** Error: ld_reg.sv(23): Illegal reference to net "data1".
#
# ** Error: ld_reg.sv(24): Illegal reference to net "wdata1".
Ben
In reply to ben@SystemVerilog.us:
Thanks Dave for clarifying this issue.
The LRM says in many places that A net cannot be procedurally assigned. (6.5 Nets and variables) Table 10-1—Legal left-hand forms in assignment statements
An the LRM says that 23.3.3.2 Port connection rules for variables
— A variable data type is not permitted on either side of an inout port.
Therefore you cannot make a procedural assignment to an inout port
In reply to ben@SystemVerilog.us:
Here is a simple example of what ben is trying to say
ex1: [Net type cannot be used on the left side of this assignment]
wire x // not allowed needs to be logic
initial x <= 1;
ex2 [Non-net variable ‘x’ cannot be an inout port]
module x(inout logic x); // not allowed, needs to be net type
endmodule
In reply to ben@SystemVerilog.us:
Hi Ben,
I have just started learning uvm.
Can you tell me what do you mean by this?
virtual interfaces come into play when using classes to defer at a later stage the definition of the physical interface to the one being worked on in the class.
In reply to pghosh:
See my example above from November 20, 2013 at 10:35 am
Basically, since the interface is “virtual” and not physically real, you can connect it to any real physical interface at a later stage. Think of it as a power plug to your toaster; that “plug” is really useless because it does not connect to a power 110 or 220 power source. However, during the fabrication of the toaster, you create a cord and a power plug without knowing which socket it will be connected to. Therefore, until it is connected to a “real” socket, you can tune to the toaster and the design of that plug (e.g., 3 plug, 2 plug, USA design, European design).
Ben Cohen
http://www.systemverilog.us/ ben@systemverilog.us
For training, consulting, services: contact Home - My cvcblr
In reply to dave_59:
Hi dave
as above explain for dynamic class if we want use interface we need to use keyword virtual.I want to know exactly what “virtual” keyword does so that interface can easily use in classes.