UVM - 12(driver and monitor 练习)

news/发布时间2024/5/16 8:46:13

uvm exercise-1

  • 实现apb_sequencer.sv,传输数据类型式abp_trans
  • 实现virtual sequencer.sv,定义两个sub sequencer:mst_sqr,slv_sqr
class abp_sequencer extends uvm_sequencer #(apb_trans);`uvm_component_utils(apb_sequencer);function new(string name,uvm_component parent);super.new(name,parent);endfunctionvirtual function void build_phase(uvm_phase phase);super.build_phase(phase);endfunctionendclass
class virtual_sequencer extends uvm_sequencer;`uvm_component_utils(virtual_sequencer);apb_sequencer mst_sqr;apb_sequnecer slv_sqr;function new(string name,uvm_component parent);super.new(name,parent);endfunctionendclass

driver的写法


  • sequencer将数据传递给driver
  • driver通过接口将数据传递给dut
  • driver和sequencer的连接通过driver中的seq_item_port和sequencer的seq_item_export连接
  • env --> agent --> driver/sequencer/monitor
  • 在env中例化agent之后,可以通过uvm_config_db设置默认的sequence及执行位置
  • 在agent中例化driver和sequencer之后可以在connect phase中调用driver.seq_item_port.connect(seqr.seq_item_export)进行连接
class  gpio_driver extends uvm_driver #(gpio_transfer);// 注册`uvm_component_utils(gpio_driver);// driver需要将接口信号传给dut,所以要用虚接口virtual gpio_if gpio_if;// 构造函数function new(string name,uvm_component parent);super.new(name,parent);endfunction// connect_phase中得到gpio_if接口function void connect_phase(uvm_phase phase);super.connect_phase(phase);if(!uvm_config_db #(virtual gpio_if)::get(this,"","gpio_if",gpio_if))`uvm_error("NOVIF",{"virtual interface must be set for:"},get_full_name(),".gpio_if");endfunction// 获取sequencer发送的数据,并将其传递给dutvirtual task run_phase(uvm_phase phase);get_and_drive();endtaskvirtual protected task get_and_drive();gpio_transfer this_trans; // 事务句柄@(posedge gpio_if.n_p_reset); // 复位信号释放之后forever begin  // 用一个循环@(posedge gpio_if.clk); // 等到时钟有效沿seq.item_port.get_next_item(req); // 将得到的req转换为this_transif(!$cast(this_trans,req))`uvm_fatal("CASTFL","Failed to cast req to this_trans in get_and_drive");driver_data(this_trans); // 传递数据seq_item_port.item_done(); // 传输完成endendtaskvirtual protected task drive_data(gpio_transfer gpio_tr);.............// 将传入的tr的数据驱动到对应的接口上endtaskendclass

driver的功能:
<1> 在connect_phase中通过uvm_config_db获取接口
<2> 在run_phase中获取数据和驱动接口
a>获取数据通过driver中的seq_item_port.get_next_item(req)
req就是获取出来的transaction对象
b>获取出来req对象之后,将其cast为对应的transaction对象
c>驱动接口,将transaction对象中的信号驱动给接口
d>完成数据传输

monitor写法

  • monitor需要采集接口信号传输给scoreboard,需要将接口信号转换为transaction中的数据进行传递
class my_monitor extends uvm_monitor;`uvm_component_utils(my_monitor);// 需要采集接口信号,所以要使用虚接口virtual dut_if vif;// monitor可以对采集到的信号进行check,所以定义使能信号bit enable_check = 1;// monitor信号传递给scoreboard需要用到事务传输// 例化一个uvm事务传输接口句柄,uvm_analysis_portumv_analysis_port #(my_data) mon_analysis_port;function new(string name,uvm_component parent);super.new(name,parent);endfunctionvirtual function void build_phase(uvm_phase phase);super.build_phase(phase);// 创建事务传输接口mon_analysis_port = new("mon_analysis_port",this);endfunctionvirtual function void connect_phase(uvm_phase phase);super.connect_phase(phase);if(!uvm_config_db #(virtual dut_if)::get(this,"","vif",vif)) begin`uvm_error(get_type_name(),"DUT interface not found");endendfunctionvirtual task run_phase(uvm_phase phase);// 需要将接口数据传递出去,所以定义transaction对象my_data data_object = my_data::type_id::create("data_object",this);forever begin// 数据有效的时候,采样@[Some event when data at DUT port is valid];// 将接口信号给到transactiondata_object.data = vif.data;data_object.addr = vif.addr;// check使能,就调用检查协议的函数if(check_enable) check_protocol();  // 采样功能概率data.object.cg_trans.sample()// 通过analysis_port发送数据mon_analysis_port.write(data_object);endendtaskvirtual function void check_protocol();// Function to check basic protocol specsendfunction endclass

定义虚接口,在connectphase中获取接口
例化uvm_analysis_port对象
创建transaction对象,将接口数据给到transaction对象发送出去
定义check_protocol()函数
调用transaction中covergroup的sample()函数

uvm_exercise_2

  • 实现apb_driver.sv,apb_monitor.sv
  • drv:发送apb_trans事务给dut
  • mon:将监控接口得到的事务通过apb_mon_port的analysis_port发送出去
  • 符合apb接口协议

APB总线协议

  • pclk
  • presetn
  • paddr[31:0]
  • pselx
  • pnable
  • pwrite
  • prdata [31:0]
  • pwdata [31:0]

apb_driver

class apb_driver extends uvm_driver #(apb_trans)virtual apb_interface apb_ifc;`uvm_component_utils(apb_driver);function new(string name,uvm_component parent);super.new(name,parent);endfunctionextern virtual function void connect_phase(uvm_phase phase);extern virtual task run_phase(uvm_phase phase);extern virtual task reset_phase(uvm_phase phase);extern virtual task get_and_drive();extern virtual task drive_data(apb_trans tr);endclassfunction void apb_driver::connect_phase(uvm_phase phase);super.connect_phase(phase);if(!uvm_config_db #(apb_interface)::get(this,"","vif",apb_ifc)) `uvm_error("NOAPB_IFC",{"virtual interface must be set for:",get_full_name(),"apb_ifc"});endfunctiontask apb_driver::reset_phase(uvm_phase phase);phase.raise_objection(this);@(negedge apb_ifc.rst_n);// 复位信号有效的时候,接口中的信号进行复位apb_ifc.psel <= 1'b0;apb_ifc.penable <= 1'b0;apb_ifc.pwrite <= 1'b0;apb_ifc.pwdata <= 32'b0;apb_ifc.paddr <= 32'b0;phase.drop_objection(this);endtasktask apb_driver::run_phase(uvm_phase phase);get_and_drive();endtasktask apb_driver::get_and_drive();apb_trans tr;@(posedge apb_ifc.rst_n);forever begin@(posedge apb_ifc.clk);seq_item_port.get_next_item(req);if(!$cast(tr,req))`uvm_fatal("CASTFL","Failed to cast req to apb_trans in get_and_drive");// drive_data(apb_trans);drive_data(req)seq_item_port.item_done(); endendfunction;task apb_driver::drive_data(apb_trans tr);if(tr.dir == apb_trans::WR)// 写信号为高的时候begin@(posedge apb_ifc.clk);apb_ifc.psel <= 1'b1;apb_ifc.penable <= 1'b0;apb_ifc.pwrite <= 1'b1;apb_ifc.pwdata <= tr.data;apb_ifc.paddr <= tr.addr;@(posedge apb_ifc.clk);apb_ifc.penable <= 1'b1;@(posedge apb_ifc.clk);apb_ifc.psel <= 1'b0;apb_ifc.penable <= 1'b0;end else begin@(posedge apb_ifc.clk);apb_ifc.psel <= 1'b1;apb_ifc.penable <= 1'b0;apb_ifc.pwrite <= 1'b0;apb_ifc.paddr <= tr.addr;@(posedge apb_ifc.clk);apb_ifc.penable <= 1'b1;@(posedge apb_ifc.clk);tr.data <= apb_ifc.prdata;apb_ifc.psel <= 1'b0;apb_ifc.penable <= 1'b0;endendtask

apb_monitor

class apb_monitor extends uvm_monitor #(apb_trans)`uvm_component_utils(apb_monitor);virtual apb_interface apb_ifc;bit check_enable = 1;  uvm_analysis_port #(apb_trans) mon_analysis_port;function new(string name,uvm_component parent);super.new(name,parent);endfunctionextern virtual function void build_phase(uvm_phase phase);extern virtual task run_phase(uvm_phase phase);extern virtual check_protocol();
endclassfunction void apb_monitor::build_phase(uvm_phase phase);super.build_phase(phase);if(!uvm_config_db #(apb_interface)::get(this,"","vif",apb_ifc)) `uvm_error("NOAPB_IFC","No apb_ifc for monitor");apb_mon_port = new("apb_mon_port",this);endfunctiontask apb_monitor::run_phase(uvm_phase phase);super.run_phase(phase);apb_trans tr = apb_trans::type_id::create("tr",this);forever begin@(posedge apb_ifc.clk);if(apb_ifc.psel = 1'b1 && apb_ifc.penable == 1'b1) begintr.dir = (apb_ifc.pwrite) ? apb_trans::WR : apb_trans::RD;tr.addr = apb_ifc.paddr;tr.data = (apb_ifc.pwrite) ? apb_ifc.pwdata :apb_ifc.prdata;endmon_analysis_port.write(tr);endendtask

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.ulsteruni.cn/article/31202517.html

如若内容造成侵权/违法违规/事实不符,请联系编程大学网进行投诉反馈email:xxxxxxxx@qq.com,一经查实,立即删除!

相关文章

软件工程——代码泛读结对

一、练习要求(主要是将项目上传至gitee) 1.源码组织方式(给出仓库地址): (1) 创建针对本作业的项目和软件版本库,在版本库中建立“src”和“doc”两个文件夹,分别存储软件系统的源代码和报告文档 (2) 建立master、develop以及成员分支(a_branch),将当前版本存入master目…

使用 WXT 开发浏览器插件(上手使用篇)

WXT (https://wxt.dev/), Next-gen Web Extension Framework. 号称下一代浏览器开发框架. 可一套代码 (code base) 开发支持多个浏览器的插件. 上路~ WXT 提供了脚手架可以方便我们快速进行开发,但是我们得先安装好环境依赖,这里我们使用 npm, 所以需要安装下 node,可以参考…

基于YOLOv8/YOLOv7/YOLOv6/YOLOv5的安全帽检测系统(深度学习模型+UI界面代码+训练数据集)

开发先进的安全帽识别系统对提升工作场所的安全性至关重要。本文详细介绍了使用深度学习技术创建此类系统的方法,并分享了完整的实现代码。系统采用了强大的YOLOv8算法,并对其与YOLOv7、YOLOv6、YOLOv5的性能进行了详细比较,包括关键指标如mAP、F1 Score等。文章深入分析了Y…

SAP:检索帮助扩展

TABLES参数已过时!(TABLES parameters are obsolete!) 一般解决方法: TABLES 参数已过时!把 TYPE 改成 LIKE 多回车,就可以保存了。检索帮助扩展(Search Help Exit)中可以指定函数修改检索帮助的查询条件及结果数据。 首先创建函数后练习将此函数分配到检索帮助扩展中的实例…

基于YOLOv8/YOLOv7/YOLOv6/YOLOv5的夜间车辆检测系统(深度学习代码+UI界面+训练数据集)

开发夜间车辆检测系统对于自动驾驶技术具有关键作用。本篇博客详细介绍了如何运用深度学习构建一个夜间车辆检测系统,并提供了完整的实现代码。该系统基于强大的YOLOv8算法,并对比了YOLOv7、YOLOv6、YOLOv5,展示了不同模型间的性能指标,如mAP、F1 Score等。文章深入解释了Y…

初三奥赛模拟测试2

初三奥赛模拟测试2 \(T1\) 南 \(0pts\)原题: luogu P4550 收集邮票\(T2\) 昌 \(0pts\)原题: CF1153D Serval and Rooted Tree 部分分\(20pts\) :生成 \(1 \sim k\) 的所有全排列依次填给叶节点,枚举每种情况即可。正解设 \(g_{x}\) 表示第 \(x\) 个节点的权值,容易发现 \(…