shangzheng的个人空间 https://blog.eetop.cn/188374 [收藏] [复制] [分享] [RSS]

空间首页 动态 记录 日志 相册 主题 分享 留言板 个人资料

日志

summary of systemverilog for verification (day8)

已有 1532 次阅读| 2008-1-28 15:34

Chapter7 Threads and Interprocess Communication

1 Most blocks in your testbench environment are modeled with a transactor and run in their own thread. The Systemverilog scheduler is the traffic cop that chooses which thread runs next. You can use the techniques in this chapter to control the threads and thus your testbench.

2 You cannot put an always block in a program. However, you can easily get around this by using a forever loop in an initial block.

3 Verilog's fork/join all statements inside the fork...join have to finish before the rest of the block can continue. fork...join_none :A fork...join_none block schedules each statement in the block, but execution continues in the parent thread.and fork...join_any : If one finished ,then you can execute the following  blocks. statements.Your testbench communicates, synchronizes, and controls these threads
with existing constructs such as events, @ event control, the wait and
disable statements, plus new language elements such as semaphores and
mailboxes.

4 Always use automatic variables to hold values in concurrent threads.

5 program automatic test(busif.TB bus);
// Code for interface not shown
task wait_for_tr(Transaction tr);
fork
begin
wait (bus.cb.addr != tr.addr);
$display("@%0d: Addr match %d", $time, tr.addr);
end
join_none
endtask
Transaction tr;
initial
repeat (10)
begin
// Create a random transaction
tr = new;
if (!tr.randomize) $finish;
// Send it into the DUT
transmit(tr); // Task not shown
// Wait for reply from DUT
wait_for_tr(tr);
end
endprogram

keep in mind that if you extend the wait_for_tr at here, then tr becomes a local variable, then it will have problems. so you need to invoke it in the routines

6 SystemVerilog schedules the threads inside a fork...join_none but they are not executed until after the original code blocks,

initial begin
for (int j=0; j<3; j++)
fork
$write(j); // Bug – gets final value of index
join_none
#0 $display("\n");
end        is executed as:

j Statement
0 for (j=0; ...
0 Spawn $write(j) [thread 0]
1 j++
1 Spawn $write(j) [thread 1]
2 j++
2 Spawn $write(j) [thread 2]
3 j++
3 join_none
3 #0
3 $write(j) [thread 0]
3 $write(j) [thread 1]
3 $write(j) [thread 2]
3 $display(“\n”)

7 You should use automatic variables inside a fork...join statement to
save a copy of a variable as shown below:

initial begin
for (int j=0; j<3; j++)
fork
automatic int k = j; // Make copy of index
$write(k); // Print copy
join_none
#0 $display;
end

8 parameter TIME_OUT = 1000;
task wait_for_tr(Transaction tr);
fork
begin
// Wait for response, or some maximum delay
fork : timeout_block
wait (bus.cb.addr != tr.addr);
#TIME_OUT $display("@%0d: Error: timeout", $time);
join_any
disable timeout_block;//to kill  threads in the timeout_block,all the threads in this block are killed
$display("@%0d: Addr match %d", $time, tr.addr);
end
join_none
endtask

9 SystemVerilog introduces the disable fork statement so you can stop all child threads that have been spawned from the current thread. Watch out, as you might unintentionally stop too many threads, such as those created from routine calls. You should always surround the target code with a fork...join to limit the scope of a disable fork statement.

10 initial begin
wait_for_tr(tr0); // Spawn thread 0
// Create a thread to limit scope of disable
fork
begin
wait_for_tr(tr1); // Spawn thread 2
fork // Spawn thread 3
wait_for_tr(tr2); // Spawn thread 4
join
// Stop threads 1 & 2, but leave 0 alone
#(TIME_OUT/2) disable fork;//disables threads in its level and its child.
end
join
end

The code calls wait_for_tr that starts thread 0. Next a fork...join
creates thread 1. Inside this thread, one is spawned by the wait_for_tr task
and one by the innermost fork...join, which spawns thread 4 by calling the
task. After a delay, a disable fork stops the child threads. Only threads 2,
3, and 4 are below thread 1, so they are the only ones stopped. Thread 0 is
outside the fork...join block that has the disable, so it is unaffected.

initial begin
wait_for_tr(tr0); // Spawn thread 0
begin : threads_1_2
wait_for_tr(tr1); // Spawn thread 1
wait_for_tr(tr2); // Spawn thread 2
end
// Stop threads 1 & 2, but leave 0 alone
#(TIME_OUT/2) disable threads_1_2;
join
end

11 task run_threads;
... // Create some transactions
wait_for_tr(tr1); // Spawn first thread
wait_for_tr(tr2); // Spawn second thread
wait_for_tr(tr3); // Spawn third thread
... // Do some other work
// Now wait for the above threads to complete
wait fork;
endtask

12 In Verilog a thread waits for an event with the @ operator.(edge sensitive,)
      First, an event is now a handle to a synchronization object that can be
passed around to routines. This feature allows you to share events across
objects without having to make the events global.

     There is always the possibility of a race condition in Verilog where one
thread blocks on an event at the same time another triggers it. If the triggering
thread executes before the blocking thread, the trigger is missed.
SystemVerilog introduces the triggered function that lets you check
whether an event has been triggered, including during the current time-slot.

13 to be continued


点赞

评论 (0 个评论)

facelist

您需要登录后才可以评论 登录 | 注册

  • 关注TA
  • 加好友
  • 联系TA
  • 0

    周排名
  • 0

    月排名
  • 0

    总排名
  • 0

    关注
  • 1

    粉丝
  • 0

    好友
  • 0

    获赞
  • 2

    评论
  • 139

    访问数
关闭

站长推荐 上一条 /1 下一条

小黑屋| 手机版| 关于我们| 联系我们| 隐私声明| EETOP 创芯网
( 京ICP备:10050787号 京公网安备:11010502037710 )

GMT+8, 2025-2-2 07:54 , Processed in 0.012625 second(s), 6 queries , Gzip On, Redis On.

eetop公众号 创芯大讲堂 创芯人才网
返回顶部