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

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

日志

summary of <systemveriog_for_verification> (day9)

已有 1540 次阅读| 2008-1-29 15:08

chapter7
7.4 event
event e1, e2;
initial begin
$display("@%0d: 1: before trigger", $time);
-> e1;
@e2;
$display("@%0d: 1: after trigger", $time);
end
initial begin
$display("@%0d: 2: before trigger", $time);
-> e2;
@e1;
$display("@%0d: 2: after trigger", $time);
end
In the same time-slot / the different initial block will definitely run in sequential. so you have problems when using the verilog
but the following is correct

event e1, e2;
initial begin
$display("\n@%0d: 1: before trigger", $time);
-> e1;
wait (e2.triggered);
$display("@%0d: 1: after trigger", $time);
end
initial begin
$display("@%0d: 2: before trigger", $time);
-> e2;
wait (e1.triggered);
$display("@%0d: 2: after trigger", $time);
end
you can see the result in the same slot

2 see more about the wait fork( you can wait more threads to finish using wait fork)

3 Semaphores
mutually exclusive access,” so a semaphore is known as a mutex and is used
to control access to a resource.
You create a semaphore with one or more keys using the new method, get one or more keys with get, and
return one or more keys with put. If you want to try to get a semaphore, but
not block, use the try_get function. It returns 1 if there are enough keys, and
0 if there are insufficient keys.

There are two things you should watch out for with semaphores. First, you
can put more keys back than you took out. Suddenly you may have two keys
but only one car! Secondly, be very careful if your testbench needs to get and
put multiple keys. Perhaps you have one key left, and a thread requests two,
causing it to block. Now a second thread requests a single semaphore – what
should happen? In SystemVerilog the second request is blocked because of
the fifo ordering, even though there are enough keys.
If you need to let smaller requests jump in before larger ones, you can
always write your own class

program automatic test;
semaphore sem; // Create a semaphore
initial begin
sem = new(1); // Allocate with 1 key
fork
sequencer; // Spawn two threads that both
sequencer; // do bus transactions
join
end
task sequencer;
repeat($urandom%10) // Random wait, 0-9 cycles
@bus.cb;
sendTrans; // Execute the transaction
endtask
task sendTrans;
sem.get(1); // Get the key to the bus
@bus.cb; // Drive signals onto bus
bus.cb.addr <= t.addr;
...
sem.put(1); // Put it back when done
endtask
endprogram
4 mailbox

the easiest way to think about a mailbox is that it is just a FIFO, with a source
and sink. The source puts data into the mailbox, and the sink gets values from
the mailbox. Mailboxes can have a maximum size or can be unlimited. When
the source puts a value into a sized mailbox that is full, it blocks until data is
removed. Likewise, if a sink tries to remove data from a mailbox that is
empty, it blocks until data is put into the mailbox.

You put data into a mailbox with the put task, and remove it with the get
task. A put can block if the mailbox is full and a get blocks if it is empty.
The peek task gets a copy of the data in the mailbox but does not remove it.
The data can be a single value, such as an integer, or logic of
any size. You can put a handle into a mailbox, not an object. By
default, a mailbox does not have a type, so you can put any mix
of data into it. Don’t do it! Stick to one type per mailbox

5 The solution is to make sure your loop has all three steps of constructing the object, randomizing it, and putting it in the mailbox
6 mailbox example:
program mailbox_example(bus_if.TB bus, ...);
class Generator;
Transaction tr;
mailbox mbx;
function new(mailbox mbx);
this.mbx = mbx;
endfunction
task run;
repeat (10) begin
tr = new;
assert(tr.randomize);
mbx.put(tr); // Send out transaction
end
endtask
endclass
class Driver;
Transaction tr;
mailbox mbx;
function new(mailbox mbx);
this.mbx = mbx;
endfunction
task run;
repeat (10) begin
mbx.get(tr); // Fetch next transaction
@(posedge busif.cb.ack);
bus.cb.kind <= tr.kind;
...
end
endtask
endclass
mailbox mbx; // Mailbox connecting gen & drv
Generator gen;
Driver drv;
initial begin
mbx = new;
gen = new(mbx);
drv = new(mbx);
fork
gen.run(); // Spawn the generator
drv.run(); // Spawn the driver
join
end
endprogram

7


点赞

评论 (0 个评论)

facelist

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

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

    周排名
  • 0

    月排名
  • 0

    总排名
  • 0

    关注
  • 1

    粉丝
  • 0

    好友
  • 0

    获赞
  • 2

    评论
  • 139

    访问数
关闭

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

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

GMT+8, 2024-11-16 22:22 , Processed in 0.010124 second(s), 6 queries , Gzip On, Redis On.

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