SystemVerilog中Semaphore(旗语)是一个多个进程之间同步的机制之一,这里需要同步的原因是这多个进程共享某些资源。
举一个场景:SoC中的,CPU和DMA都希望去访问相同地址的内存空间。实际的情况可能是CPU的访问覆盖DMA的访问,或者相反。
简而言之,这其中存在着冲突,这也是SystemVerilog中Semaphore的应用场景。
如果CPU访问某个地址,CPU会先锁住这块地址空间,等到CPU访问完成才会解锁,这个互斥锁可以通过Semaphore来实现。在CPU锁住这个块地址空间期间,DMA是无法访问的。
semaphore的相关用法如下:
1、声明一个旗语。
semaphore semaphore_name;
2、声明旗语中互斥锁的个数,默认是0。
function new (int keyCount = 0);
3、获取互斥锁,默认是1。
task get (int keyCount = 1);
4、回收互斥锁,默认是1.
function void put (int keyCount = 1);
5、获取互斥锁,默认是1。和get()的区别是try_get ( )是non-blocking的。
function int try_get (int keyCount = 1);
semaphore示例:
module sema; bit [7:0] mem [0:3]; int i, data; semaphore s1; initial begin s1 = new (1); //Create semaphore with 1 key fork DMA_write; CPU_read; join end task DMA_write; if (s1.try_get(1)) //non-blocking. Locks (gets) $display($stime,,, "DMA gets a KEY from semaphore"); else wait (s1.try_get(1)); //DMA writes data for (i=0; i < 4; i++) begin mem[i] = $urandom; $display($stime,,, "DMA WRITE[%0d] = %0d",i,mem[i]); end #5; //do something else s1.put(1); //DMA releases (puts) the key $display($stime,,, "DMA puts the KEY into semaphore"); endtask task CPU_read; #0; s1.get (1); //WAIT to get the key - blocking $display($stime,,, "CPU gets the KEY from semaphore"); //CPU reads data for (i=0; i < 4; i++) begin data = mem[i]; $display($stime,,, "CPU READ[%0d] = %0d",i,data); end endtask endmodule
上面的例子中有两个并行的进程DMA_write和CPU_read。
一开始DMA拿到互斥锁后,写入4次。后面CPU拿到互斥锁后,再读取这些值。因为无法保证开始时刻DMA先拿到互斥锁,还是CPU拿到互斥锁,所以加上了#0。
仿真log:
0 DMA gets a KEY from semaphore 0 DMA WRITE[0] = 36 0 DMA WRITE[1] = 129 0 DMA WRITE[2] = 9 0 DMA WRITE[3] = 99 5 DMA puts the KEY into semaphore 5 CPU gets the KEY from semaphore 5 CPU READ[0] = 36 5 CPU READ[1] = 129 5 CPU READ[2] = 9 5 CPU READ[3] = 99 V C S S i m u l a t i o n R e p o r t
审核编辑:汤梓红
全部0条评论
快来发表一下你的评论吧 !