verilator/test_regress/t/t_timing_class.v

171 lines
4.5 KiB
Systemverilog

// DESCRIPTION: Verilator: Verilog Test module
//
// This file ONLY is placed under the Creative Commons Public Domain, for
// any use, without warranty, 2022 by Antmicro Ltd.
// SPDX-License-Identifier: CC0-1.0
`ifdef TEST_VERBOSE
`define WRITE_VERBOSE(args) $write args
`else
`define WRITE_VERBOSE(args)
`endif
module t;
// =============================================
// EVENTS
class EventClass;
event e;
task sleep; /* @e; */ endtask // Unsupported
task wake; ->e; endtask
endclass
EventClass ec = new;
int event_trig_count = 0;
initial begin
@ec.e;
ec.sleep;
end
initial #25 ec.wake;
initial #50 ->ec.e;
always @ec.e begin
event_trig_count++;
`WRITE_VERBOSE(("Event in class triggered at time %0t!\n", $time));
end
// =============================================
// DELAYS
virtual class DelayClass;
pure virtual task do_delay;
pure virtual task do_sth_else;
endclass
`ifdef TEST_VERBOSE
`define DELAY_CLASS(dt) \
class Delay``dt extends DelayClass; \
virtual task do_delay; \
$write("Starting a #%0d delay\n", dt); \
#dt \
$write("Ended a #%0d delay\n", dt); \
endtask \
virtual task do_sth_else; \
$write("Task with no delay (in Delay%0d)\n", dt); \
endtask \
endclass
`else
`define DELAY_CLASS(dt) \
class Delay``dt extends DelayClass; \
virtual task do_delay; \
#dt; \
endtask \
virtual task do_sth_else; \
endtask \
endclass
`endif
`DELAY_CLASS(10);
`DELAY_CLASS(20);
`DELAY_CLASS(40);
class NoDelay extends DelayClass;
virtual task do_delay;
`WRITE_VERBOSE(("Task with no delay\n"));
endtask
virtual task do_sth_else;
`WRITE_VERBOSE(("Task with no delay (in NoDelay)\n"));
endtask
endclass
class AssignDelayClass;
logic x;
logic y;
task do_assign;
y = #10 x;
`WRITE_VERBOSE(("Did assignment with delay\n"));
endtask
endclass
initial begin
DelayClass dc;
Delay10 d10 = new;
Delay20 d20 = new;
Delay40 d40 = new;
NoDelay dNo = new;
AssignDelayClass dAsgn = new;
`WRITE_VERBOSE(("I'm at time %0t\n", $time));
dc = d10;
dc.do_delay;
dc.do_sth_else;
`WRITE_VERBOSE(("I'm at time %0t\n", $time));
if ($time != 10) $stop;
dc = d20;
dc.do_delay;
dc.do_sth_else;
`WRITE_VERBOSE(("I'm at time %0t\n", $time));
if ($time != 30) $stop;
dc = d40;
dc.do_delay;
dc.do_sth_else;
`WRITE_VERBOSE(("I'm at time %0t\n", $time));
if ($time != 70) $stop;
dc = dNo;
dc.do_delay;
dc.do_sth_else;
`WRITE_VERBOSE(("I'm at time %0t\n", $time));
dAsgn.x = 1;
dAsgn.y = 0;
fork #5 dAsgn.x = 0; join_none
dAsgn.do_assign;
if ($time != 80) $stop;
if (event_trig_count != 2) $stop;
if (dAsgn.y != 1) $stop;
// Test if the object is deleted before do_assign finishes:
fork dAsgn.do_assign; join_none
#5 dAsgn = null;
#15 $write("*-* All Finished *-*\n");
$finish;
end
// =============================================
// FORKS
class ForkDelayClass;
task do_delay; #40; endtask
endclass
class ForkClass;
int done = 0;
task do_fork();
ForkDelayClass d;
fork
begin
#10 done++;
`WRITE_VERBOSE(("Forked process %0d ending at time %0t\n", done, $time));
end
begin
#20 done++;
`WRITE_VERBOSE(("Forked process %0d ending at time %0t\n", done, $time));
d = new;
end
begin
#30 d.do_delay;
done++;
`WRITE_VERBOSE(("Forked process %0d ending at time %0t\n", done, $time));
end
join
done++;
`WRITE_VERBOSE(("All forked processes ended at time %0t\n", $time));
endtask
endclass
initial begin
ForkClass fc = new;
fc.do_fork;
if (fc.done != 4 || $time != 70) $stop;
end
initial #101 $stop; // timeout
endmodule