01
线程控制
线程,即独立运行的程序;
线程需要被触发执行,可以结束或者不结束;
验证环境需要initial语句块,在仿真过程中,验证环境中的对象可以创建和销毁,故验证环境的资源是动态的;
Begin……end中语句顺序执行,而fork……join中语句并发执行;
与fork……join类似的并行语句有fork……join_any、fork……join_none;
fork……join需要所有并行线程都结束才会继续执行;
fork……join_any其中任意一个线程结束就继续执行;
fork……join_none不等待子线程,直接继续执行;
Fork……join_any和fork……join_none继续执行后,其一些未完成的子线程仍将继续在后台执行;
如果要等待或者停止这些子线程,可使用wait fork 或者disable fork;
task do_test;
fork
……
join_any
fork
……
join_none
wait fork;//等待所有子线程结束
endtask
task get_first(output ubt adr);
fork
……
join_any
disable fork;
endtask
延迟控制即通过#来完成;
#100 clk2=clk1;
事件(event)控制即通过@来完成;
@a clk1=clk2; //等待事件
@(posedge clk)a=b;//边沿触发
Wait语句可以与事件或者表达式结合使用;
Real AOR[];
Initial wait(AOR,size()>0) //wait语句完成电平触发
02
线程同步
测试平台所有线程都需要同步并进行交换数据;
一个线程等待另一个线程;
event done,blast; //声明两个独立的事件
event done_too=done; //事件done赋值给done_too
task trigger(event ev);
->ev; //触发ev事件
endtask
……
fork
@done_too; //等待done_too
#1 trigger(done); //触发done事件
join
fork
->blast; //触发blast事件
wait(blast.triggered); //电平触发等待
join
wait_order(a,b,c);
旗语是一个互斥体,使用旗语可以实现对同一资源的访问控制;
在创建旗语时,会为其分配固定的钥匙数量;
使用旗语的进程必须先获得钥匙,才可访问资源;
旗语的钥匙数量可以有多个,等待旗语的进程也可以有多个;
旗语的等待队列是先进先出(FIFO),即先排队等待旗语的将优先得到钥匙;
旗语操作
创建旗语
semaphore sm;//创建一个旗语
sm=new(1); //分配一个钥匙
创建一个固定钥匙数量的旗语:new
从旗语获取一个或多个钥匙(阻塞型):get
返回一个或多个钥匙:put
获取一个或多个钥匙而不被阻塞:try_get
task send;
sem.get(1) ///获取钥匙
……
sem.put(1); //处理完成时把钥匙返回
endtask
03
线程通信
用于收发信息,SV中信箱可以存放任何数据类型,也可以从信箱中读取这些数据,
创建信箱:new()
将信息写入信箱:put()
写入信箱但不会阻塞:try_put()
获取信息:get() 获取信息并取出数据:
peek()获取信息不会取出数据
从信箱获取数据但不会阻塞:try_get()/try_peek()
获取信箱信息数目:num()
END