其他分享
首页 > 其他分享> > SV -- Interprocess Communication (IPC 线程间通信)

SV -- Interprocess Communication (IPC 线程间通信)

作者:互联网

SV -- Interprocess Communication (IPC 线程间通信)

@(SV)

目录

1. Semaphore 旗语

语法:semaphore semaphore_name;
方法:

其中get和try_get的区别在于:

实例:并行进程之间通过旗语顺序执行

module semaphore_ex;
  semaphore sema; //declaring semaphore sema
 
  initial begin
    sema=new(4); //creating sema with '4' keys
    fork
      display(); //process-1
      display(); //process-2
      display(); //process-3
    join
  end
 
  //display method
  task automatic display();
    sema.get(2); //getting '2' keys from sema
    $display($time,"\tCurrent Simulation Time");
    #30;
    sema.put(2); //putting '2' keys to sema
  endtask
endmodule

上面例子输出:
0 Current Simulation Time
0 Current Simulation Time
30 Current Simulation Time

第三个进程需要等待前两个中一个归还了keys之后才能执行。
下面是有多个keys存取的情况:

module semaphore_ex;
  semaphore sema; //declaring semaphore sema
 
  initial begin
    sema=new(4); //creating sema with '4' keys
    fork
      display(2); //process-1
      display(3); //process-2
      display(2); //process-3
      display(1); //process-4
    join
  end
 
  //display method
  task automatic display(int key);
    sema.get(key); //getting 'key' number of keys from sema
    $display($time,"\tCurrent Simulation Time, Got %0d keys",key);
    #30;
    sema.put(key); //putting 'key' number of keys to sema
  endtask
endmodule

桶内只有四个键,会先依次取,第一个进程取了两个,第二个取三个不够,第三个可以取,此时进程1和3先执行,执行完后进程4和2再执行。

2. Mailbox 信箱

邮箱是一种通信机制,它允许在进程之间交换消息。希望与另一个进程通信的进程将消息发送到邮箱,邮箱将消息临时存储在系统定义的内存对象中,以便将消息传递给所需的进程。
mailbox按size分可以分为两种:

有界邮箱的大小已定义。邮箱在存储有限数量的消息时变为满的。试图将消息放入完整邮箱的进程将被挂起,直到邮箱队列中有足够的空间可用为止。
无界邮箱的大小无限。

按照类型也可分为两种:

跟旗语类似,信箱也有如下几种方法:

new();           - Create a mailbox
put();           - Place a message in a mailbox
try_put();       - Try to place a message in a mailbox without blocking
get(); or peek();- Retrieve a message from a mailbox
num();           - Returns the number of messages in the mailbox
try_get(); or try_peek();  - Try to retrieve a message from a mailbox without blocking

案例:
mailbox负责在generator和driver之间传输数据:

//-------------------------------------------------------------------------
// Packet
//-------------------------------------------------------------------------
class packet;
  rand bit [7:0] addr;
  rand bit [7:0] data;
 
  //Displaying randomized values
  function void post_randomize();
    $display("Packet::Packet Generated");
    $display("Packet::Addr=%0d,Data=%0d",addr,data);
  endfunction
endclass
 
//-------------------------------------------------------------------------
//Generator - Generates the transaction packet and send to driver
//-------------------------------------------------------------------------
class generator;
  packet pkt;
  mailbox m_box;
  //constructor, getting mailbox handle
  function new(mailbox m_box);
    this.m_box = m_box;
  endfunction
  task run;
    repeat(2) begin
      pkt = new();
      pkt.randomize(); //generating packet
      m_box.put(pkt);  //putting packet into mailbox
      $display("Generator::Packet Put into Mailbox");
      #5;
    end
  endtask
endclass
 
//-------------------------------------------------------------------------
// Driver - Gets the packet from generator and display's the packet items
//-------------------------------------------------------------------------
class driver;
  packet pkt;
  mailbox m_box;
 
  //constructor, getting mailbox handle
  function new(mailbox m_box);
    this.m_box = m_box;
  endfunction
 
  task run;
    repeat(2) begin
      m_box.get(pkt); //getting packet from mailbox
      $display("Driver::Packet Recived");
      $display("Driver::Addr=%0d,Data=%0d\n",pkt.addr,pkt.data);
    end
  endtask
endclass
 
//-------------------------------------------------------------------------
//     tbench_top 
//-------------------------------------------------------------------------
module mailbox_ex;
  generator gen;
  driver    dri;
  mailbox m_box; //declaring mailbox m_box
 
  initial begin
    //Creating the mailbox, Passing the same handle to generator and driver, 
    //because same mailbox should be shared in-order to communicate.
    m_box = new(); //creating mailbox
 
    gen = new(m_box); //creating generator and passing mailbox handle
    dri = new(m_box); //creating driver and passing mailbox handle
    $display("------------------------------------------");
    fork
      gen.run(); //Process-1
      dri.run(); //Process-2
    join
    $display("------------------------------------------");
  end
endmodule

输出:
Packet::Packet Generated
Packet::Addr=3,Data=38
Generator::Packet Put into Mailbox
Driver::Packet Recived
Driver::Addr=3,Data=38

Packet::Packet Generated
Packet::Addr=118,Data=92
Generator::Packet Put into Mailbox
Driver::Packet Recived
Driver::Addr=118,Data=92

3. Event 事件

事件是对流程之间的同步非常有用的静态对象。事件操作是两个分阶段的流程,其中一个流程将触发事件,另一个流程将等待触发事件。

示例:@ .triggered

module events_ex;
  event ev_1; //declaring event ev_1
 
  initial begin
    fork
      //process-1, triggers the event
      begin
        #40;
        $display($time,"\tTriggering The Event");
        ->ev_1;
      end
     
      //process-2, wait for the event to trigger
      begin
        $display($time,"\tWaiting for the Event to trigger");
        @(ev_1.triggered);
        $display($time,"\tEvent triggered");
      end
    join
  end
endmodule

输出:
0 Waiting for the Event to trigger
40 Triggering The Event
40 Event triggered

上面的例子中,->ev_1需要发生在triggered之后,即使同一时间发生也不会识别到。

示例:wait(.triggered)

module events_ex;
  event ev_1; //declaring event ev_1
 
  initial begin
    fork
      //process-1, triggers the event
      begin
         $display($time,"\tTriggering The Event");
        ->ev_1;
      end
    
      //process-2, wait for the event to trigger
      begin
        $display($time,"\tWaiting for the Event to trigger");
        wait(ev_1.triggered);
        $display($time,"\tEvent triggered");
      end
    join
  end
endmodule

输出:
0 Triggering The Event
0 Waiting for the Event to trigger
0 Event triggered

上面的例子中,->ev_1可以和wait同一时间发生。

示例: wait_order()

module events_ex;
  event ev_1; //declaring event ev_1
  event ev_2; //declaring event ev_2
  event ev_3; //declaring event ev_3
 
  initial begin
    fork
      //process-1, triggers the event ev_1
      begin
        #6;
        $display($time,"\tTriggering The Event ev_1");
        ->ev_1;
      end
 
      //process-2, triggers the event ev_2
      begin
        #2;
        $display($time,"\tTriggering The Event ev_2");
        ->ev_2;
      end
 
      //process-3, triggers the event ev_3
      begin
        #1;
        $display($time,"\tTriggering The Event ev_3");
        ->ev_3;
      end
      //process-4, wait for the events to trigger in order of ev_2,ev_1 and ev_3
      begin
        $display($time,"\tWaiting for the Event's to trigger");
        wait_order(ev_2,ev_1,ev_3)
          $display($time,"\tEvent's triggered Inorder");
        else
          $display($time,"\tEvent's triggered Out-Of-Order");
      end
    join
  end
endmodule

输出:
0 Waiting for the Event's to trigger
1 Triggering The Event ev_3
1 Event's triggered Out-Of-Order
2 Triggering The Event ev_2
6 Triggering The Event ev_1

标签:event,IPC,keys,Communication,mailbox,间通信,ev,display,Event
来源: https://www.cnblogs.com/lyc-seu/p/12797089.html