In reply to
rag123
:
You have 2 forked tasks in parallel. The change in data is not detected in the begin-end task.
my_first_task (addr,data);
begin
@ $changed(data);
$display ("Read from bus %h \n",data);
end join
Ben
SystemVerilog.us
If i change it to non blocking, it is not compiling.
Error-[DTNBA] Dynamic type in non-blocking assignment
testbench.sv, 7
tb, "data"
Dynamic type (Automatic variable in this case) cannot be used on the
left-hand side of non blocking assignments.
The following worked. Some notes:
The task or function ‘my_first_task’ with ref arguments must be
automatic
.
data <= 8’h1; // non-blocking assignment may not be an automatic variable
my_first_task needs the
#1
; Love it or hate it, it’s the nature of the beast.
module tb;
// The task or function 'my_first_task' with ref arguments must be automatic.
task automatic my_first_task (input logic [31:0] addr, ref logic [31:0] data);
#1; // <----------- NEEDED THiS
data = 8'h1; // non-blocking assignment may not be an automatic variable
for (int i=0; i <1; i++) begin
$display ("Entering the loop");
for (int i=0; i <1; i++) begin
$display ("Entering the second loop");
endtask
logic [31:0] addr, data;
initial begin
data = 'h10;
addr = 'h01;
my_first_task (addr,data);
begin
@ (data); // <-------- $changed requires a cloking event for the past of data
$display ("Read from bus %h \n",data);
endmodule
Entering the loop
# Entering the second loop
# Read from bus 00000001
Ben Cohen
http://www.systemverilog.us/
[email protected]
For training, consulting, services: contact
Home - My cvcblr
SVA Handbook 4th Edition, 2016 ISBN 978-1518681448
A Pragmatic Approach to VMM Adoption 2006 ISBN 0-9705394-9-5
Using PSL/SUGAR for Formal and Dynamic Verification 2nd Edition, 2004, ISBN 0-9705394-6-0
Real Chip Design and Verification Using Verilog and VHDL, 2002 isbn 978-1539769712
Component Design by Example ", 2001 ISBN 0-9705394-0-1
VHDL Coding Styles and Methodologies, 2nd Edition, 1999 ISBN 0-7923-8474-1
VHDL Answers to Frequently Asked Questions, 2nd Edition ISBN 0-7923-8115
SVA Alternative for Complex Assertions
Verification Horizons - March 2018 Issue | Verification Academy
SVA: Package for dynamic and range delays and repeats | Verification Academy
SVA in a UVM Class-based Environment
SVA in a UVM Class-based Environment | Verification Horizons | Verification Academy
In reply to
[email protected]
:
Typically, one uses clocking events. The following works, regardless of the order of the blocks in the fork-join
module tb;
bit clk;
initial forever #10 clk=!clk;
task automatic my_first_task (input logic [31:0] addr, ref logic [31:0] data);
@(posedge clk);
data = 8'h2; // non-blocking assignment may not be an automatic variable
for (int i=0; i <1; i++) begin
$display ("@ %t Entering the loop ", $realtime);
for (int i=0; i <1; i++) begin
$display ("Entering the second loop");
endtask
logic [31:0] addr, data;
initial begin
data = 'h10;
addr = 'h01;
begin
// @(posedge clk);
@ (data);
$display ("@ %t Read from bus %h \n", $realtime, data);
my_first_task (addr,data);
endmodule
# @ 10 Entering the loop
# Entering the second loop
# @ 10 Read from bus 00000002
****
NOTE
The following has a race condition
module tb;
bit clk;
initial forever #10 clk=!clk;
task automatic my_first_task (input logic [31:0] addr, ref logic [31:0] data);
@(posedge clk);
data = 8'h2; // non-blocking assignment may not be an automatic variable
for (int i=0; i <1; i++) begin
$display ("@ %t Entering the loop ", $realtime);
for (int i=0; i <1; i++) begin
$display ("Entering the second loop");
endtask
logic [31:0] addr, data;
initial begin
data = 'h10;
addr = 'h01;
begin
@(posedge clk);
$display ("@ %t Before the @data %h \n", $realtime, data);
@ (data); // <<< Gets bloked here, waiting for a new change
$display ("@ %t Read from bus %h \n", $realtime, data);
my_first_task (addr,data);
$display ("@ %t After the joins %h \n", $realtime, data);
endmodule
@ 10 Entering the loop
# Entering the second loop
# @ 10 Before the @data 00000002
@ 10 Before the @data 00000010
# @ 11 Entering the loop
# Entering the second loop
# @ 11 Read from bus 00000002
# @ 11 After the joins 00000002
BTW, this forum does not discuss tools. One should ever identify the tool you are using. You can just say “my tool deos this”, but in the this, delete anything that can identify the tool. Your question is Not a tool issue, but a SystemVerilog issue.
Ben Cohen
http://www.systemverilog.us/
[email protected]
For training, consulting, services: contact
Home - My cvcblr
SVA Handbook 4th Edition, 2016 ISBN 978-1518681448
A Pragmatic Approach to VMM Adoption 2006 ISBN 0-9705394-9-5
Using PSL/SUGAR for Formal and Dynamic Verification 2nd Edition, 2004, ISBN 0-9705394-6-0
Real Chip Design and Verification Using Verilog and VHDL, 2002 isbn 978-1539769712
Component Design by Example ", 2001 ISBN 0-9705394-0-1
VHDL Coding Styles and Methodologies, 2nd Edition, 1999 ISBN 0-7923-8474-1
VHDL Answers to Frequently Asked Questions, 2nd Edition ISBN 0-7923-8115
SVA Alternative for Complex Assertions
Verification Horizons - March 2018 Issue | Verification Academy
SVA: Package for dynamic and range delays and repeats | Verification Academy
SVA in a UVM Class-based Environment
SVA in a UVM Class-based Environment | Verification Horizons | Verification Academy
In reply to
rag123
:
See
https://verificationacademy.com/forums/systemverilog/driving-wire-task-interface
.
On using nonblocking assignment in tasks
Driving a wire thru a task is illegal.
Quote:
1800-2012 14.3 Clocking block declaration
A clockvar whose clocking_direction is inout shall behave as if it were two clockvars, one input and one output, having the same name and the same clocking_signal.
Reading the value of such an inout clockvar shall be equivalent to reading the corresponding input clockvar.
Writing to such an inout clockvar shall be equivalent to writing to the corresponding output clockvar.
interface dut_mem_if (input logic clk);
wire[31:0] data; // <------------------- the bi-direct
clocking driver_cb @ (posedge clk);
inout data; // <------------------- the bi-direct
endclocking : driver_cb
endinterface : dut_mem_if
class dut_mem_driver;
virtual interface dut_mem_if.drvr_if_mp vif;
// ...
virtual task write_task(logic [31:0] data, address);
this.vif.driver_cb.data <= data;
task my_first_task ();
// @(posedge clk);
data <= 8'h2; // non-blocking assignment may not be an automatic variable
for (int i=0; i <1; i++) begin
$display ("@ %t Entering the loop ", $realtime);
for (int i=0; i <1; i++) begin
$display ("Entering the second loop");
endtask
logic [31:0] addr, data;
initial begin
data = 'h10;
addr = 'h01;
begin
// @(posedge clk);
@ (data);
$display ("@ %t Read from bus %h \n", $realtime, data);
my_first_task ();
endmodule
KERNEL: @ 0 Entering the loop
In reply to
[email protected]
:
There are a number of issues at play here.
A task must have automatic lifetime in order to pass an argument by reference. That argument does not know the lifetime of the actual variable passed to it, so it places the most restrictive rules for assignments and does not allow non-blocking assignments. That was my mistake.
The original question exposes a race condition—there are a many ways of dealing with it. Without knowing the requirements behind what the code was trying to accomplish, it’s difficult to give a best solution.