*2-3-7-加入field_automation机制
-
在2.3.3节中引入my_mointor时,在my_transaction中加入了my_print函数;
在2.3.5节中引入reference model时,加入了my_copy函数;
在2.3.6节引入scoreboard时,加入了my_compare函数。
上述三个函数虽然各自不同,但是对于不同的transaction来说,都是类似的:它们都需要逐字段地对transaction进行某些操作。
那么有没有某种简单的方法,可以通过定义某些规则自动实现这三个函数呢?答案是肯定的。这就是UVM中的field_automation机制,使用uvm_field系列宏实现:
代码清单 2-52
文件:src/ch2/section2.3/2.3.7/my_transaction.sv
4 class my_transaction extends uvm_sequence_item;
5
6 rand bit[47:0] dmac;
7 rand bit[47:0] smac;
8 rand bit[15:0] ether_type;
9 rand byte pload[];
10 rand bit[31:0] crc;
…
25 `uvm_object_utils_begin(my_transaction)
26 `uvm_field_int(dmac, UVM_ALL_ON)
27 `uvm_field_int(smac, UVM_ALL_ON)
28 `uvm_field_int(ether_type, UVM_ALL_ON)
29 `uvm_field_array_int(pload, UVM_ALL_ON)
30 `uvm_field_int(crc, UVM_ALL_ON)
31 `uvm_object_utils_end
…
37 endclass
这里使用uvm_object_utils_begin和uvm_object_utils_end来实现my_transaction的factory注册,在这两个宏中间,使用uvm_field宏注册所有字段。uvm_field系列宏随着transaction成员变量的不同而不同,如上面的定义中出现了针对bit类型的uvm_field_int及针对byte类型动态数组的uvm_field_array_int。
3.3.1节列出了所有的uvm_field系列宏。
当使用上述宏注册之后,可以直接调用copy、compare、print等函数,而无需自己定义。这极大地简化了验证平台的搭建,提高了效率:
代码清单 2-53
文件:src/ch2/section2.3/2.3.7/my_model.sv
26 task my_model::main_phase(uvm_phase phase);
27 my_transaction tr;
28 my_transaction new_tr;
29 super.main_phase(phase);
30 while(1) begin
31 port.get(tr);
32 new_tr = new("new_tr");
33 new_tr.copy(tr);
34 `uvm_info("my_model", "get one transaction, copy and print it:", UVM_LOW)
35 new_tr.print();
36 ap.write(new_tr);
37 end
38 endtask
代码清单 2-54
文件:src/ch2/section2.3/2.3.7/my_scoreboard.sv
…
34 while (1) begin
35 act_port.get(get_actual);
36 if(expect_queue.size() > 0) begin
37 tmp_tran = expect_queue.pop_front();
38 result = get_actual.compare(tmp_tran);
39 if(result) begin
40 `uvm_info("my_scoreboard", "Compare SUCCESSFULLY", UVM_LOW);
41 end
…
引入field_automation机制的另外一大好处是简化了driver和monitor。在2.3.1节及2.3.3节中,my_driver的drv_one_pkt任务和my_monitor的collect_one_pkt任务代码很长,但是几乎都是一些重复性的代码。使用field_automation机制后,drv_one_pkt任务可以简化为:
代码清单 2-55
文件:src/ch2/section2.3/2.3.7/my_driver.sv
38 task my_driver::drive_one_pkt(my_transaction tr);
39 byte unsigned data_q[];
40 int data_size;
41
42 data_size = tr.pack_bytes(data_q) / 8;
43 `uvm_info("my_driver", "begin to drive one pkt", UVM_LOW);
44 repeat(3) @(posedge vif.clk);
45 for ( int i = 0; i < data_size; i++ ) begin
46 @(posedge vif.clk);
47 vif.valid <= 1'b1;
48 vif.data <= data_q[i];
49 end
50
51 @(posedge vif.clk);
52 vif.valid <= 1'b0;
53 `uvm_info("my_driver", "end drive one pkt", UVM_LOW);
54 endtask
第42行调用pack_bytes将tr中所有的字段变成byte流放入data_q中,在2.3.1节中是手工地将所有字段放入data_q中的。
pack_bytes极大地减少了代码量。在把所有的字段变成byte流放入data_q中时,字段按照uvm_field系列宏书写的顺序排列。在上述代码中是先放入dmac,再依次放入smac、ether_type、pload、crc。假如my_transaction定义时各个字段的顺序如下:
代码清单 2-56
`uvm_object_utils_begin(my_transaction)
`uvm_field_int(smac, UVM_ALL_ON)
`uvm_field_int(dmac, UVM_ALL_ON)
`uvm_field_int(ether_type, UVM_ALL_ON)
`uvm_field_array_int(pload, UVM_ALL_ON)
`uvm_field_int(crc, UVM_ALL_ON)
`uvm_object_utils_end
那么将会先放入smac,再依次放入dmac、ether_type、pload、crc。
my_monitor的collect_one_pkt可以简化成:
代码清单 2-57
文件:src/ch2/section2.3/2.3.7/my_monitor.sv
34 task my_monitor::collect_one_pkt(my_transaction tr);
35 byte unsigned data_q[$];
36 byte unsigned data_array[];
37 logic [7:0] data;
38 logic valid = 0;
39 int data_size;
…
46 `uvm_info("my_monitor", "begin to collect one pkt", UVM_LOW);
47 while(vif.valid) begin
48 data_q.push_back(vif.data);
49 @(posedge vif.clk);
50 end
51 data_size = data_q.size();
52 data_array = new[data_size];
53 for ( int i = 0; i < data_size; i++ ) begin
54 data_array[i] = data_q[i];
55 end
56 tr.pload = new[data_size - 18]; //da sa, e_type, crc
57 data_size = tr.unpack_bytes(data_array) / 8;
58 `uvm_info("my_monitor", "end collect one pkt", UVM_LOW);
59 endtask
这里使用unpack_bytes函数将data_q中的byte流转换成tr中的各个字段。unpack_bytes函数的输入参数必须是一个动态数组,所以需要先把收集到的、放在data_q中的数据复制到一个动态数组中。由于tr中的pload是一个动态数组,所以需要在调用unpack_bytes之前指定其大小,这样unpack_bytes函数才能正常工作。
*2-3-7-加入field_automation机制的更多相关文章
- 笔记:Binder通信机制
TODO: 待修正 Binder简介 Binder是android系统中实现的一种高效的IPC机制,平常接触到的各种XxxManager,以及绑定Service时都在使用它进行跨进程操作. 它的实现基 ...
- JAVA回调机制(CallBack)详解
序言 最近学习java,接触到了回调机制(CallBack).初识时感觉比较混乱,而且在网上搜索到的相关的讲解,要么一言带过,要么说的比较单纯的像是给CallBack做了一个定义.当然了,我在理解了回 ...
- 谈谈DOMContentLoaded:Javascript中的domReady引入机制
一.扯淡部分 回想当年,在摆脱写页面时js全靠从各种DEMO中copy出来然后东拼西凑的幽暗岁月之后,毅然决然地打算放弃这种处处“拿来主义”的不正之风,然后开启通往高大上的“前端攻城狮”的飞升之旅.想 ...
- 路由的Resolve机制(需要了解promise)
angular的resovle机制,实际上是应用了promise,在进入特定的路由之前给我们一个做预处理的机会 1.在进入这个路由之前先懒加载对应的 .js $stateProvider .state ...
- Android权限管理之Permission权限机制及使用
前言: 最近突然喜欢上一句诗:"宠辱不惊,看庭前花开花落:去留无意,望天空云卷云舒." 哈哈~,这个和今天的主题无关,最近只要不学习总觉得生活中少了点什么,所以想着围绕着最近面试过 ...
- Java学习之反射机制及应用场景
前言: 最近公司正在进行业务组件化进程,其中的路由实现用到了Java的反射机制,既然用到了就想着好好学习总结一下,其实无论是之前的EventBus 2.x版本还是Retrofit.早期的View注解框 ...
- .NET Core采用的全新配置系统[10]: 配置的同步机制是如何实现的?
配置的同步涉及到两个方面:第一,对原始的配置文件实施监控并在其发生变化之后从新加载配置:第二,配置重新加载之后及时通知应用程序进而使后者能够使用最新的配置.要了解配置同步机制的实现原理,先得从认识一个 ...
- Go结构体实现类似成员函数机制
Go语言结构体成员能否是函数,从而实现类似类的成员函数的机制呢?答案是肯定的. package main import "fmt" type stru struct { testf ...
- 操作系统篇-分段机制与GDT|LDT
|| 版权声明:本文为博主原创文章,未经博主允许不得转载. 一.前言 在<操作系统篇-浅谈实模式与保护模式>中提到了两种模式,我们说在操作系统中,其实大部分时间是待在保护模式中的. ...
随机推荐
- centos 中 mongodb 启动失败的修复
mongodb是使用centos的yum命令安装的,整个的安装过程如下: 1. 运行 yum info mongo-10gen查看是否有mongodb源,如有跳至第3步. 2. 运行 vim /etc ...
- 模拟远程HTTP的POST请求
建立请求,以模拟远程HTTP的POST请求方式构造并获取处理结果 /// <summary> /// 建立请求,以模拟远程HTTP的POST请求方式构造并获取处理结果 /// </s ...
- 62 不同路径 leetcode JAVA
题目: 一个机器人位于一个 m x n 网格的左上角 (起始点在下图中标记为“Start” ). 机器人每次只能向下或者向右移动一步.机器人试图达到网格的右下角(在下图中标记为“Finish”). 问 ...
- Spring框架注解
这四个注解,功能都是一样的,都是用来创建对象的. 但是为什么有这么四个吗?Spring中提供了三个@Component的衍生注解:(功能目前来讲是一样的) @Controller :WEB层 ...
- 【文文殿下】[BZOJ3277] 串
Description 字符串是oi界常考的问题.现在给定你n个字符串,询问每个字符串有多少子串(不包括空串)是所有n个字符串中 至少k个字符串的子串(注意包括本身) Input 第一行两个整数n,k ...
- Code Chef February Challenge 2019题解
传送门 \(HMAPPY2\) 咕 话说这题居然卡\(scanf\)的么??? int T;cin>>T; while(T--){ cin>>n>>a>> ...
- 代码审计之Catfish CMS v4.5.7后台作者权限越权两枚+存储型XSS一枚
首先本地搭建环境,我所使用的是Windows PHPstudy集成环境.使用起来非常方便.特别是审计的时候.可以任意切换PHP版本. 本文作者:226safe Team – Poacher 0×01 ...
- Elasticsearch5.4 删除type
首先要说明的是现在的Elasticsearch已经不支持删除一个type了,所以使用delete命令想要尝试删除一个type的时候会出现如下错误,如果存在一个名为edemo的index和tets的ty ...
- delphi 10.2 ---treeview 基本用法
unit Unit2; interface uses Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System ...
- ORACLE Sequence 自增长
Sequence是数据库系统按照一定规则自动增加的数字序列.这个序列一般作为代理主键(因为不会重复),没有其他任何意义. Sequence是数据库系统的特性,有的数据库有Sequence,有的没有.比 ...