Mailboxes是进程间通信的另一种方式,但是比semaphores更强大,因为Mailboxes可以在两个进程之间交换消息。
数据可以由一个进程发送,由另一个进程获取,顾名思义就像是邮箱一样。
获取邮箱中信件的方式有两种:
1、一直等待信件的到来(blocking)
2、如果没有信件就先去干其他事情,过一会儿再来看是否信件到了。(non-blocking)
从Mailboxes中可以存放信件规模的角度,Mailboxes可以大致分为bounded Mailboxes和unbounded Mailboxes。
bounded Mailboxes就是指Mailboxes中能够容纳有限数量的信件,如果在Mailboxes满时写入会阻塞住,直到不满。unbounded Mailboxes可以容纳无限数量的信件。
Mailboxes也可以声明为只能存放某一类的信件。默认情况下,Mailboxes是无类型的,这意味着Mailboxes可以发送和接收任何不同类型的信件。
邮箱声明的语法是:
mailbox mbox;
Mailbox是一个SystemVerilog内置类,自然也提供了许多内置的方法:
1、new ()
创建一个mailbox,函数原型是:
functionnew()(intbound=0);
会返回一个mailbox句柄,默认bound是0,表示unbounded mailbox。
2、num ()
返回mailbox中信件的个数,函数原型是:
functionintnum();
3、put ()
blocking put(按照FIFO顺序),如果mailbox满了会阻塞进程,函数原型是:
task put (singular message)
4、try_put ( )
non-blocking put(按照FIFO顺序),如果mailbox满了不会阻塞进程,会返回值0。函数原型是:
functiontry_put(singularmessage);
5、get ()
blocking get(按照FIFO顺序),如果mailbox是空的,会一直blocking进程。函数原型是:
taskget(refsingularmessage);
6、try_get ( )
non-blocking get(按照FIFO顺序),如果mailbox是空的,不会阻塞进程,会返回值0。函数原型是:
function int try_get( ) (ref singular expression)
7、peek ( )
peek()不同于get(),peek会复制mailbox中的信件,而不会将信件从mailbox中删除。函数原型是:
taskpeek(refsingularmessage);
如果mailbox是空的,会一直block进程。
8、try_peek (),不过多言说,non-block peek。函数原型是:
function int try_peek ( ref singular expression)
示例:
module mB; bit [7:0] mem [0:3]; int i, j, data; mailbox mbox; //declare a mailbox initial begin mbox = new (4); //create a bounded mailbox fork DMA_write; CPU_read; join end task DMA_write; $display($stime,,, "DMA puts Mem Data into mbox"); for (i=0; i < 4; i++) begin mem[i] = $urandom; $display($stime,,, "DMA WRITE[%0d] = %0d",i,mem[i]); mbox.put(mem[i]); //put data into the mailbox end endtask task CPU_read; $display($stime,,, "CPU retrieves Mem Data from mbox"); for (j=0; j < 4; j++) begin mbox.get(data); //retrieve data from the mailbox $display($stime,,, "CPU READ[%0d] = %0d",i,data); end endtask endmodule
仿真log:
0 DMA puts Mem Data into mbox 0 DMA WRITE[0] = 36 0 DMA WRITE[1] = 129 0 DMA WRITE[2] = 9 0 DMA WRITE[3] = 99 0 CPU retrieves Mem Data from mbox 0 CPU READ[0] = 36 0 CPU READ[1] = 129 0 CPU READ[2] = 9 0 CPU READ[3] = 99 V C S S i m u l a t i o n R e p o r t
上面这个例子首先声明了一个mailbox “mbox”,然后例化深度为4。
后面两个并行的进程“DMA_write”和“CPU_read” 。从打印log来看并不存在两个进程之间的冲突。
参数化Mailbox
如果希望在mailbox put和get时进行类型检查,可以显式地声明mailbox的类型。
module pMailbox; typedef mailbox #(string) string_mbox; string s; initial begin static string_mbox SMbox = new; s = "hi"; SMbox.put( s ); $display("String 'put' is %s", s); SMbox.get( s ); $display("String 'get' is %s", s); end endmodule
仿真log:
String 'put' is hi String 'get' is hi
审核编辑:汤梓红
-
Verilog
+关注
关注
28文章
1345浏览量
109989 -
System
+关注
关注
0文章
165浏览量
36885 -
进程
+关注
关注
0文章
202浏览量
13948
原文标题:System Verilog中的Mailboxes
文章出处:【微信号:芯片验证工程师,微信公众号:芯片验证工程师】欢迎添加关注!文章转载请注明出处。
发布评论请先 登录
相关推荐
评论