路科验证学习笔记(V0_5)——用类构建验证结构及线程间通信

  • 多个driver/receiver的时候,接口都要设定为virtual。如果不使用关键字 “virtual” 那么在多次调用该接口时,在其中的一个实例中对接口中某一信号的修改会影响其他实例接口;如果使用了 “virtual” 关键字,那么每个实例是独立的。
  • 线程间同步的三种方式,事件同步/信箱/旗语。
    • 1.事件同步
//在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时随机化的这个对象。
SystemVerilog的听课学习笔记,包括讲义截取、知识点记录、注意事项等细节的标注。 目录如下: 第一章 SV环境构建常识 1 1.1 数据类型 1 四、二值逻辑 4 定宽数组 9 foreach 13 动态数组 16 队列 19 关联数组 21 枚举类型 23 字符串 25 1.2 过程块和方法 27 initial和always 30 function逻辑电路 33 task时序电路 35 动态 静态变量 39 1.3 设计例化和连接 45 第二章 验证的方法 393 动态仿真 395 静态检查 397 虚拟模型 403 硬件加速 405 效能验证 408 性能验证 410 第三章 SV组件实现 99 3.1 接口 100 什么是interface 101 接口的优势 108 3.2 采样和数据驱动 112 竞争问题 113 接口的时序块clocking 123 利于clocking的驱动 133 3.3 测试的开始和结束 136 仿真开始 139 program隐式结束 143 program显式结束 145 软件域program 147 3.4 调试方法 150 第四章 验证的计划 166 4.1 计划概述 166 4.2 计划的内容 173 4.3 计划的实现 185 4.4 计划的进程评估 194 第五章 验证的管理 277 6.1 验证的周期检查 277 6.2 管理三要素 291 6.3 验证的收敛 303 6.4 问题追踪 314 6.5 团队建设 321 6.6 验证的专业化 330 第六章 验证平台的结构 48 2.1 测试平台 49 2.2 硬件设计描述 55 MCDF接口描述 58 MCDF接口时序 62 MCDF寄存器描述 65 2.3 激励发生器 67 channel initiator 72 register initiator 73 2.4 监测器 74 2.5 比较器 81 2.6 验证结构 95 第七章 激励发生封装:类 209 5.1 概述 209 5.2 类的成员 233 5.3 类的继承 245 三种类型权限 protected/local/public 247 this super 253 成员覆盖 257 5.4 句柄的使用 263 5.5 包的使用 269 第八章 激励发生的随机化 340 7.1 随机约束和分布 340 权重分布 353 条件约束 355 7.2 约束块控制 358 7.3 随机函数 366 7.4 数组约束 373 7.5 随机控制 388 第九章 线程与通信 432 9.1 线程的使用 432 9.2 线程的控制 441 三个fork...join 443 等待衍生线程 451 停止线程disable 451 9.3 线程的通信 458 第十章 进程评估:覆盖率 495 10.1 覆盖率类型 495 10.2 功能覆盖策略 510 10.3 覆盖组 516 10.4 数据采样 524 10.5 覆盖选项 544 10.6 数据分析 550 第十一章 SV语言核心进阶 552 11.1 类型转换 552 11.2 虚方法 564 11.3 对象拷贝 575 11.4 回调函数 584 11.5 参数化的类 590 第十二章 UVM简介 392 8.2 UVM简介 414 8.3 UVM组件 420 8.4 UVM环境 425
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Arist9612

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值