- 多个driver/receiver的时候,接口都要设定为virtual。如果不使用关键字 “virtual” 那么在多次调用该接口时,在其中的一个实例中对接口中某一信号的修改会影响其他实例接口;如果使用了 “virtual” 关键字,那么每个实例是独立的。
- 线程间同步的三种方式,事件同步/信箱/旗语。
-
//在scoreboard的类中定义
event DONE; // flag to indicate goal reached
//check任务中插入
if (pkts_checked >= run_for_n_packets)
->this.DONE; //触发该事件,结束仿真
//在test.sv中插入等待本次仿真结束事件触发
//电平敏感
wait(sb.DONE.triggered);
//边沿敏感
@(DONE);
//使用wait fork等待多个线程
foreach (gen[i])
fork
automatic int k=i;
join_none
wait fork;
-
- 2.旗语(Semaphore)同步
- 当测试平台只有一个资源(比如一条总线或者端口),却有多个请求方,但是DUT只允许单一驱动,此时可以使用旗语。若一个线程无法请求到 钥匙(说明上个线程还没执行完将钥匙归还),那么就会一直阻塞。多个阻塞的线程会以fifo的形式进行排队。
- 例外:假如排在前面的线程需要2把,排在紧后面的需要1把,碰巧现在只有一把钥匙,那就会更换线程的执行顺序。
- Semaphore的四大方法:
new(); Create a semaphore with a specified number of keys
semaphore_name = new(numbers_of_keys);
put(); 归还钥匙(默认为1把)semaphore_name.put(number_of_keys); or semaphore_name.put();
get(); 获得钥匙semaphore_name.get(number_of_keys); or semaphore_name.get();
//若有钥匙则继续执行,若无钥匙则一直等直到有钥匙
try_get(); (默认为1把)semaphore_name.try_get(number_of_keys); or semaphore_name.try_get();
//若有钥匙则继续执行并返回1;若无钥匙则继续执行并返回0;
- 例子,两线程同时想display ,但是semaphore只有一把钥匙:
module semaphore_ex;
semaphore sema; //declaring semaphore sema
initial begin
sema=new(1); //creating sema with '1' key
fork
display(); //process-1
display(); //process-2
join
end
//display method
task automatic display();
sema.get(); //getting '1' key from sema
$display($time,"\tCurrent Simulation Time");
#30;
sema.put(); //putting '1' key to sema
endtask
endmodule
- 同时想display,但是只有一把钥匙,第二个线程在延时30之后,第一个线程归还了钥匙之后才能display:
Simulator Output
0 Current Simulation Time
30 Current Simulation Time
-
- 3.信箱(mailbox)同步
- 如何在两个线程之间传递数据?考虑到代码重用性和线程之间可能存在异步的情况,信箱是最优的解决方法。可以将其看成一个双端口FIFO,源把数据放入,收端从中获取数据。如信箱已满,则源端扔要想信箱方数据会发生阻塞直到有数据被拿出。同样,想从一个空信箱拿数据也会被阻塞,直到他被放入数据。
- 信箱是对象,必须用new()实例化,new(1)代表例化了一个定容信箱,容量为1.若未指定,那么信箱容量无限大。
- put、get任务分别向信箱中放数据和取数据,若信箱为满put阻塞,空则get阻塞。peek可以对信箱中的数据进行拷贝而不取出,若信箱有数据则为通路,否则阻塞。
- 虽然信箱中允许放多种类型的数据,但是不要这样,务必只放一种。
- 信箱里保存的是句柄而非对象。若涉及到将多个随机化对象放入信箱时,要注意对象的创建和随机化、放入信箱都必须都在一个repeat loop中,这样才会生成多个对象并且每一个对象都有句柄指向。若对象的创建在loop外部,那么就会生成多个句柄但都指向了最后一次loop时随机化的这个对象。