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));