Hi, I am working on writing a UVC that will help me generate synchronous and asynchronous stimuli, I already have the agent, driver, monitor, sequencer, and sequence_item written and working, I connected two instances of this UVC in the input of my dut configured as active and everything worked fine but when I connect another instance of the UVC to the output and configure it as passive I get the following warning
Warning-[ICPSD_W] Illegal combination of drivers
/home/bermudez/Desktop/vip/gpio_uvc/vip_vrf/../sv/gpio_uvc_if.sv, 8
Illegal combination of structural and procedural drivers.
Variable "gpio_pin" is driven by an invalid combination of structural and
procedural drivers. Variables driven by a structural driver cannot have any
other drivers.
This variable is declared at
"/home/bermudez/Desktop/vip/gpio_uvc/vip_vrf/../sv/gpio_uvc_if.sv", 8: logic
[7:0] gpio_pin;
The first driver is at
"/home/bermudez/Desktop/vip/gpio_uvc/vip_vrf/tb/tb.sv", 17: adder dut( .clk
(tb.port_a_if.clk), .rst (1'b0), .A (tb.port_a_if.gpio_pin), .B
(tb.port_b_if.gpio_pin), .C (tb.port_c_if.gpio_pin));
The second driver is at
"/home/bermudez/Desktop/vip/gpio_uvc/vip_vrf/../sv/gpio_uvc_if.sv", 12:
output gpio_pin = gpio_pin;
This warning will be upgraded to error in future releases
Warning-[ICPSD_W] Illegal combination of drivers
/home/bermudez/Desktop/vip/gpio_uvc/vip_vrf/../sv/gpio_uvc_if.sv, 8
Illegal combination of structural and procedural drivers.
Variable "gpio_pin" is driven by an invalid combination of structural and
procedural drivers. Variables driven by a structural driver cannot have any
other drivers.
This variable is declared at
"/home/bermudez/Desktop/vip/gpio_uvc/vip_vrf/../sv/gpio_uvc_if.sv", 8: logic
[7:0] gpio_pin;
The first driver is at
"/home/bermudez/Desktop/vip/gpio_uvc/vip_vrf/../sv/gpio_uvc_if.sv", 12
Hierarchical path: tb.port_c_if
The second driver is at
"/home/bermudez/Desktop/vip/gpio_uvc/vip_vrf/tb/tb.sv", 17
Hierarchical path: tb
This warning will be upgraded to error in future releases
This is the interface code
`ifndef GPIO_UVC_IF_SV
`define GPIO_UVC_IF_SV
interface gpio_uvc_if (
input logic clk
);
logic [7:0] gpio_pin;
clocking cb_drv @(posedge clk);
default output #1ns;
output gpio_pin;
endclocking : cb_drv
clocking cb_mon @(posedge clk);
default input #1ns;
input gpio_pin;
endclocking : cb_mon
modport drv (clocking cb_drv, output gpio_pin);
modport mon (clocking cb_mon, input gpio_pin);
endinterface : gpio_uvc_if
`endif // GPIO_UVC_IF_SV
and this is the testbench code
module tb;
import uvm_pkg::*;
import top_test_pkg::*;
// Clock generator
logic clk;
always #5 clk = ~clk;
initial begin
clk = 0;
end
gpio_uvc_if port_a_if(clk);
gpio_uvc_if port_b_if(clk);
gpio_uvc_if port_c_if(clk);
adder dut (
.clk(port_a_if.clk),
.rst(1'b0),
.A(port_a_if.gpio_pin),
.B(port_b_if.gpio_pin),
.C(port_c_if.gpio_pin)
);
initial begin
$timeformat(-9, 0, "ns", 10);
$fsdbDumpvars;
uvm_config_db #(virtual gpio_uvc_if)::set(null, "uvm_test_top.env.port_a_agent", "vif", port_a_if);
uvm_config_db #(virtual gpio_uvc_if)::set(null, "uvm_test_top.env.port_b_agent", "vif", port_b_if);
uvm_config_db #(virtual gpio_uvc_if)::set(null, "uvm_test_top.env.port_c_agent", "vif", port_c_if);
run_test();
end
endmodule : tb
in the environment
function void top_env::build_agents();
port_a_agent_cfg = gpio_uvc_config::type_id::create("port_a_agent_cfg", this);
port_a_agent_cfg.is_active = UVM_ACTIVE;
uvm_config_db #(gpio_uvc_config)::set(this, "port_a_agent", "cfg", port_a_agent_cfg);
port_a_agent = gpio_uvc_agent::type_id::create("port_a_agent", this);
port_b_agent_cfg = gpio_uvc_config::type_id::create("port_b_agent_cfg", this);
port_b_agent_cfg.is_active = UVM_ACTIVE;
uvm_config_db #(gpio_uvc_config)::set(this, "port_b_agent", "cfg", port_b_agent_cfg);
port_b_agent = gpio_uvc_agent::type_id::create("port_b_agent", this);
port_c_agent_cfg = gpio_uvc_config::type_id::create("port_c_agent_cfg", this);
port_c_agent_cfg.is_active = UVM_PASSIVE;
uvm_config_db #(gpio_uvc_config)::set(this, "port_c_agent", "cfg", port_c_agent_cfg);
port_c_agent = gpio_uvc_agent::type_id::create("port_c_agent", this);
endfunction : build_agents
I tried to solve it by using modport
to define the direction but it didn’t make any difference, the only thing that has worked is creating another variable to use when the UVC is configured as passive, is this normal or am I doing something wrong?
Temporal solution
`ifndef GPIO_UVC_IF_SV
`define GPIO_UVC_IF_SV
interface gpio_uvc_if (
input logic clk
);
logic [7:0] gpio_pin;
logic [7:0] gpio_pin_passive;
clocking cb_drv @(posedge clk);
default output #1ns;
output gpio_pin;
endclocking : cb_drv
clocking cb_mon @(posedge clk);
default input #1ns;
input gpio_pin;
input gpio_pin_passive;
endclocking : cb_mon
modport drv (clocking cb_drv, output gpio_pin);
modport mon (clocking cb_mon, input gpio_pin);
endinterface : gpio_uvc_if
`endif // GPIO_UVC_IF_SV
adder dut (
.clk(port_a_if.clk),
.rst(1'b0),
.A(port_a_if.gpio_pin),
.B(port_b_if.gpio_pin),
.C(port_c_if.gpio_pin_passive)
);
I’m using vcs version : T-2022.06 and UVM 1.2, despite the warning evething is working fine, but I’m worried that latter this warning will be upgraded to error in future releases. Thanks