Inter-Thread Communications

SungchulCHA·2024년 8월 30일
0

System Verilog

목록 보기
5/6
post-thumbnail
ITC

Event Based ITC

  • event variables 이용하여 동기화
  • one shot : @event_var [, event2]);
  • persistent : wait(event_var.triggered);
initial begin
  event A;
  fork
    my_task1(A);
    my_task2(A);
  join
end

task my_task1(event A1);
  wait(A1.triggered);
  $display("Print 2nd");
endtask

task my_task2(event A2);
  $display("Print 1st");
  ->A2;
endtask

-> : trigger
Assign 할경우 같아짐.

event a, b, c;
a = b;
-> a; // also triggers b
-> b; // also triggers a
event a, b, c;
a = c;
b = a;
-> a; // also triggers b and c
-> b; // also triggers a and c
-> c; // also triggers a and b

Controlling Termination of Simulation

program automatic test(router_io.TB rtr_io);
  event DONE;
  
  task check();
    forever begin
      ...
      if ($get_coverage() == 100)
        -> DONE;
    end
  endtask: check
  
  initial begin
    fork
      gen();
      check();
    join_none
    for (int i = 0; i < 16; i++) begin
      int j = i;
      fork
        send(j);
        recv(j);
      join_none
    end
    wait(DONE.triggered)
  end
  ...
endprogram: test

Resource Sharing ITC

  • shared resource 이용한 쓰레드 간의 접근
  • C랑 똑같음. critical section, lock 등

Semaphores

  • keys 가 deposited 되고 removed 되는 bucket
  • built-in class임
semaphore sem;
sem = new(3);         // bucket with 3 keys is created
seg.get(2);
if (!sem.try_get(2))  // does not block
  $display("Failed");
sem.get(2);           // blocks until 2 keys available

semaphore sem1;
sem1 = new();  // 0 keys
sem1.put(2);   // Create 2 keys
sem1.get(1);   // Use 1 key
sem1.put(1);   // Return 1 key

Semaphore Arrays

semaphore sem_array[];
sem_array = new[4];
//sem_array[2].put(2); // 생성 전에 사용 안됨
foreach (sem_array[i])
  sem_array[i] = new(i);
sem_array[2].put(2);   // foreach에서 2개 만들고, 2개 추가로 넣었으니 총 4개의 키 존재

Example

program automatic test(router_io.TB rtr_io);
  semaphore sem[];
  ...
  sem = new[16];
  foreach(sem[i])
    sem[i] = new(1);
  ...
  
  task send();
    sem[da].get(1);
    send_addrs();
    send_pad();
    send_payload();
    sem[da].put(1);
  endtask: send
  ...
endprogram: test

Mailbox

  • C랑 비슷
  • built-in mailbox class

Create

mailbox #(Packet) mbx[];
mailbox #(instr_e) mbx_unbound;
mbx_unbound = new(); // new()의 인자의 초기값은 0
max = new[4];
for (int i = 0; i < mbx.size(); i++) begin
  mbx[i] = new(i+2);
end

put

int status;
typedef enum {ADD=1, SUB, MUL, DIV} instr_e;
instr_e instr = ADD;

mailbox #(instr_e) mbox = new(1);
mbox.put(instr);
status = mbox.try_put(instr);

task put() : block if exceeds bound
function int try_put() : non-blocking. return 0 if mailbox is full

get

int status;
typedef enum {ADD=1, SUB, MUL, DIV} instr_e
instr_e instr1 = MUL, instr2;

mailbox #(instr_e) mbox = new(1);
mbox.put(instr1);
mbox.get(instr2);
$display("inst2 = %s", instr2.name());
status = mbox.try_get(instr2);    // 비어 있으니 get 못함. 0반환
status = mbox.try_put(instr1);    // 비어 있으니 put 가능. 1반환
mbox.get(instr2);
mbox.get(instr2);                 // 비어있음. blocking

peek

int status;
Packet pkt_obj1 = new();
Packet pkt_obj2 = new(), pkt2drv;

mailbox #(Packet) mbox = new();
mbox.put(pkt_obj1);
status = mbox.try_put(pkt_obj2);  // unbound이므로 1반환
$display("%0d messages", mbox.num());

mbox.peek(pkt2drv);                // 2 messages가 있음
$display(mbox.try_peek(pkt2drv));
$display(mbox.try_get(pkt2drv));
profile
Myongji UNIV. B.S. in Electronic Engineering

0개의 댓글