int a, b, c; // parent variables
fork
[fork local declarations] // visible to all child threads
statement0; // child thread 1
statement1; // child thread 2
begin // child thread 3
statement2;
statement3; // statement1 and statement2 execute sequentially
end
join | join_any | join_none
statement4;
fork-join
안에서begin-end
로 묶인 statements들은 순서대로 동작하는 single concurrent child thread
join
: Child threads execute and all child threads must complete beforestatement4
is executed
join_any
: Child threads execute and one child thread must complete beforestatement4
is executed. Other child threads continue to run.
join_none
: Child threads are queued,statement4
executes. Child threads not executed until parent thread encounters a blocking statement or completes.
Thread executes until it finishes or a blocking statement is encountered
실행중인 쓰레드가 blocking statement 만나면 It is queued and a queued ready thread executes
Examples
@(rtr_io.cb);
wait (var_a == 1);
#10;
join_any
join
READY
- to be executed at current simulation timeWAIT
- blocked from execution until wait condition is meta = 0;
fork
begin
while ( a != 5 )
if ( $time > MAX_TIME )
$finish;
else
@(bus.cb);
end
begin
repeat(5) @rtr_io.cb;
bus.cb.reg <= 1'b1;
a = 5;
end
join
첫 쓰레드에
else
구문이 없으면 첫 쓰레드에는 시간 베이스가 없음.
두번째 쓰레드는rtr_io.cb
라는 BA가 있음.
그래서 첫 쓰레드는 무한루프 돎
program automatic test();
initial begin
for (int i = 0; i < 16; i++)
send(i);
wait fork;
end
task send(int j);
fork
begin
$display("Driving port %0d", j);
#1ns;
end
join_none
endtask: send
endprogram: test
wait
없으면 0ns에서(endprogram
만나서) 바로 끝남
program automatic test;
initial begin
for (int i = 0; i < 16; i++) begin
fork
int index = i;
send(index);
join_none
end
wait fork;
end
task send(int j);
$display("Driving port %0d", j);
#1ns;
endtask: send
endprogram: test
index
없으면i
를 공유해서됨i++
된 16만 출력됨
task recv();
fork
begin: frameo_n_neg
wait (rtr_io.cb.frame_n[7] !== 1'b0);
@(rtr_io.cb iff(rtr_io.cb.frameo_n[7] === 1'b0));
end
begin: timer
repeat(1000) @(rtr_io.cb);
$display("Timed out!");
$finish;
end
join_any
disable fork; // 모든 fork 종료 가능성
get_payload();
endtask
task recv();
fork begin
fork: recv_wd_timer
begin: frameo_n_neg
wait (rtr_io.cb.frame_n[7] !== 1'b0);
@(rtr_io.cb iff(rtr_io.cb.frameo_n[7] === 1'b0));
end
begin: timer
repeat(1000) @(rtr_io.cb);
$display("Timed out!");
$finish;
end
join_any
disable fork;
end join
get_payload();
endtask
task recv();
process thread_q[$];
fork
begin
thread_q.push_back(process::self());
wait (rtr_io.cb.frameeo_n[7] !== 1'b0);
@(rtr_io.cb iff(rtr_io.cb.frameo_n[7] === 1'b0));
end
begin
thread_q.push_back(process::self());
repeat(1000) @(rtr_io.cb);
$display("Timed out!");
$finish;
end
join_any
foreach (thread_q[i])
if (thread_q[i].status != process::FINISHED)
thread_q[i].kill();
thread_q.delete();
endtask: recv