当前位置: 首页 > news >正文

怎么查看网站是哪个公司做的最新seo视频教程

怎么查看网站是哪个公司做的,最新seo视频教程,昆明建设招投标网站,爱站seo排名可以做哪些网站目录5、加入reference model6、加入scoreboard7、加入field_automation机制话接上文UVM实战 卷I学习笔记2——为验证平台加入各个组件(1) 5、加入reference model reference model用于完成和DUT相同的功能,其输出被scoreboard接收&#xff…

目录

    • 5、加入reference model
    • 6、加入scoreboard
    • 7、加入field_automation机制


话接上文UVM实战 卷I学习笔记2——为验证平台加入各个组件(1)

5、加入reference model

reference model用于完成和DUT相同的功能,其输出被scoreboard接收,用于和DUT的输出相比较。DUT如果很复杂,那么reference model也会相当复杂。本章的DUT很简单, 所以reference model也简单:

class my_model extends uvm_component;uvm_blocking_get_port #(my_transaction) port;uvm_analysis_port #(my_transaction) ap;extern funciton new(string name, uvm_component parent);extern function void build_phase(uvm_phase phase);extern virtual task main_phase(uvm_phase phase);`uvm_component_utils(my_model)
endclass
function my_model::new(string name, uvm_component parent);super.new(name, parent);
endfunction
function void my_model::build_phase(uvm_phase phase);super.build_phase(phase);port = new("port", this);ap = new("ap", this);
endfunction
task my_model::main_phase(uvm_phase phase);//复制一份从i_agt得到的tr并传递给后级scoreboard中my_transaction tr;my_transaction new_tr;super.main_phase(phase);while(1) beginport.get(tr);new_tr = new("new_tr");new_tr.my_copy(tr);`uvm_info("my_model", "get one transaction, copy and print it:", UVM_LOW)new_tr.my_print();ap.write(new_tr);end
endtask

my_copy是一个在my_transaction中定义的函数, 实现两个my_transaction的复制,其代码为:

function void my_copy(my_transaction tr);if(tr == null)`uvm_fatal("my_transaction", "tr is null!!!!")dmac = tr.dmac;smac = tr.smac;ether_type = tr.ether_type;pload = new[tr.pload.size()];for(int i = 0; i < pload.size(); i++) beginpload[i] = tr.pload[i];endcrc = tr.crc;
endfunction

完成my_model的定义后,需要将其在my_env中实例化。其实例化方式与agent、driver相似。加入my_model后,整棵UVM树如图所示:
在这里插入图片描述

  • my_transaction的传递方式:my_model是从i_agt中得到my_transaction,并把
    my_transaction传递给my_scoreboard。UVM通常使用TLM(Transaction Level Modeling)实现component之间transaction级别的通信
  • 要实现通信需要考虑两点:第一,数据是如何发送的?第二,数据是如何接收的?在UVM的transaction级别的通信中,数据的发送有多种方式,其中一种是使用uvm_analysis_port。在my_monitor中定义如下变量:uvm_analysis_port #(my_transaction) ap;
  • uvm_analysis_port是一个参数化的类,其参数就是这个analysis_port需要传递的数据类型, 在例子中是my_transaction。声明了ap后,需要在monitor的build_phase中将其实例化:
virtual function void build_phase(uvm_phase phase);...ap = new("ap", this);
endfunction

在main_phase中,当收集完一个transaction后,需要将其写入ap中:

task my_monitor::main_phase(uvm_phase phase);my_transaction tr;while(1) begintr = new("tr");collect_one_pkt(tr);ap.write(tr); //write是uvm_analysis_port的内建函数end
endtask
  • 至此,在my_monitor中需要为transaction通信准备的工作已经全部完成。
  • UVM的transaction级通信的数据接收方式有多种,其中一种是用uvm_blocking_get_port。是参数化的类,其参数是要在其中传递的transaction的类型。在my_model中定义了一个端口,并在build_phase中对其进行实例化。在main_phase中,通过port.get任务来得到从i_agt的monitor中发出的transaction。
  • 在my_monitor和my_model中定义并实现了各自的端口之后,通信的功能并没有实现,还需要在my_env中使用fifo将两个端口联系在一起。在my_env中定义一个fifo,并在build_phase中将其实例化:fifo的类型是uvm_tlm_analysis_fifo,它也是参数化的类,其参数是存储在其中的transaction的类型,这里是my_transaction。
	uvm_tlm_analysis_fifo #(my_transaction) agt_mdl_fifo;...agt_mdl_fifo = new("agt_mdl_fifo", this);

之后,在connect_phase中将fifo分别与my_monitor中的analysis_port和my_model中的blocking_get_port相连:

function void my_env::connect_phase(uvm_phase phase);super.connect_phase(phase);i_agt.ap.connect(agt_mdl_fifo.analysis_export);mdl.port.connect(agt_mdl_fifo.blocking_get_export);
endfunction
  • connect_phase也是UVM内建的一个phase,在build_phase执行完成之后马上执行。但与build_phase不同的是,它的执行顺序并不是从树根到树叶,而是从树叶到树根(自底向上)——先执行driver和monitor的connect_phase,再执行agent的connect_phase,最后执行env的connect_phase。
  • 上例为何需要fifo?为何不能直接把my_monitor中的analysis_port和my_model中的blocking_get_port相连?由于analysis_port是非阻塞的,ap.write函数调用完成后马上返回,不会等待数据被接收。假如当write函数调用时,blocking_get_port正在忙而没有准备好接收新数据时,此时被write函数写入的my_transaction就需要一个暂存的位置——即fifo
  • 在上例的连接中用到了i_agt的一个成员变量ap,它的定义与my_monitor中ap的定义完全一样:uvm_analysis_port #(my_transaction) ap;
  • 与my_monitor中的ap不同的是不需要对my_agent中的ap进行实例化,只需要在my_agent的connect_phase中将monitor的值赋给它, 相当于是一个指向my_monitor的ap的指针:
function void my_agent::connect_phase(uvm_phase phase);super.connect_phase(phase);ap = mon.ap;
endfunction

my_agent的connect_phase的执行顺序早于my_env的connect_phase的执行顺序,从而保证执行到i_agt.ap.connect语句时,i_agt.ap不是一个空指针——connect_phase自底向上的意义所在。

6、加入scoreboard

在验证平台中加入了reference model和monitor之后,最后一步是加入scoreboard。my_scoreboard的代码如下:

class my_scoreboard extends uvm_scoreboard;my_transaction expect_queue[$];uvm_blocking_get_port #(my_transaction) exp_port;uvm_blocking_get_port #(my_transaction) act_port;`uvm_component_utils(my_scoreboard)extern function new(string name, uvm_component parent = null);extern virtual function void build_phase(uvm_phase phase);extern virtual task main_phase(uvm_phase phase);
endclassfunction my_scoreboard::new(string name, uvm_component parent = null);super.new(name, parent);
endfunctionfunction void my_scoreboard::build_phase(uvm_phase phase);super.build_phase(phase);exp_port = new("exp_port", this);act_port = new("act_port", this);
endfunctiontask my_scoreboard::main_phase(uvm_phase phase);my_transaction get_export, get_actual, tmp_tran;bit result;super.main_phase(phase);forkwhile(1) beginexp_port.get(get_expect);expect_queue.push_back(get_expect);endwhile(1) beginact_port.get(get_actual);if(expect_queue.size() > 0) begintmp_tran = expect_queue.pop_front();result = get_actual.my_compare(tmp_tran);if(result) begin`uvm_info("my_scoreboard", "Compare SUCCESSFULLY", UVM_LOW)endelse begin`uvm_error("my_scoreboard", "Compare FAILED")$display("the expect pkt is");tmp_tran.my_print();$display("the actual pkt is");get_actual.my_print();endendjoin	
endtask//my_compare函数:逐字段比较两个my_transaction并给出最终的比较结果
function bit my_compare(my_transaction tr);bit result;if(tr == null)`uvm_fatal("my_transaction", "tr is null!!!!")result = ((dmac == tr.dmac) && (smac == tr.smac) && (ether_type == tr.ether_type)&& (crc == tr.crc));if(pload.size() != tr.pload.size())result = 0;elsefor(int i = 0; i < pload.size(); i++) beginif(pload[i] != tr.pload[i])result = 0;endreturn result;
endfunction
  • my_scoreboard要比较的数据来源于reference model和o_agt的monitor,前者通过exp_port获取,后者通过act_port获取。
  • 在main_phase中通过fork建立起了两个进程,一个处理exp_port的数据,收到数据后把数据放到expect_queue;另外一个处理act_port(DUT的输出)的数据,收到数据后调用my_transaction的my_compare函数比较两组收到的数据。
  • 比较的前提是exp_port要比act_port先收到数据。由于DUT处理数据需要延时,而reference model是基于高级语言的处理,一般不需要延时,因此可保证这个前提的实现。
  • 完成my_scoreboard的定义后,也需要在my_env中将其实例化。此时,整棵UVM树如图所示:
    在这里插入图片描述

7、加入field_automation机制

  • 前文引入my_mointor时在my_transaction中加入了my_print函数;引入reference model时加入my_copy
    函数;引入scoreboard时加入my_compare函数。

  • 上述三个函数虽然各自不同,但对于不同的transaction来说都是类似的: 它们都需要逐字段地对transaction进行某些操作

  • field_automation机制可通过某些规则自动实现这些函数,通过使用uvm_field系列宏来实现:

class my_transaction extends uvm_sequence_item;rand bit[47:0] dmac;rand bit[47:0] smac;rand bit[15:0] ether_type;rand byte pload[];rand bit[31:0] crc;...`uvm_object_utils_begin(my_transaction)`uvm_field_int(dmac, UVM_ALL_ON)`uvm_field_int(smac, UVM_ALL_ON)`uvm_field_int(ether_type, UVM_ALL_ON)`uvm_field_array_int(ploadm, UVM_ALL_ON)`uvm_field_int(crc, UVM_ALL_ON)`uvm_object_utils_end...
endclass
  • 使用uvm_object_utils_begin和uvm_object_utils_end实现my_transaction的factory注册,在这两个宏中间使用uvm_field宏注册所有字段。uvm_field系列宏随着transaction成员变量的不同而不同。
  • 使用上述宏注册之后,可以直接调用copy、 compare、 print等函数而无需自己定义。这极大简化了验证平台的搭建,提高了效率。例如下例:
task my_model::main_phase(uvm_phase phase);my_transaction tr;my_transaction new_tr;super.main_phase(phase);while(1) begin port.get(tr);new_tr = new("new_tr");new_tr.copy(tr);`uvm_info("my_model", "get one transaction, copy and print it:", UVM_LOW)new_tr.print();ap.write(new_tr);end
endtask
  • 引入field_automation机制的另外一大好处是简化了driver和monitor
  • 在前文my_driver的drv_one_pkt任务和my_monitor的collect_one_pkt任务代码很长,但几乎是一些重复性的代码。使用field_automation机制后,drv_one_pkt任务可以简化为:
task my_driver::drive_one_pkt(my_transaction tr);byte unsigned data_q[];int data_size;data_size = tr.pack_bytes(data_q) / 8;//将tr所有字段变成byte流放入data_q中`uvm_info("my_driver", "begin to drive one pkt", UVM_LOW)repeat(3) @(posedge vif.clk);for(int i = 0; i < data_size; i++) begin@(posedge vif.clk);vif.valid <= 1'b1;vif.data <= data_q[i];end@(posedge vif.clk);vif.valid <= 1'b0;`uvm_info("my_driver", "end drive one pkt", UVM_LOW);
endtask
  • 在把所有字段变成byte流放入data_q中时,字段按照uvm_field系列宏书写的顺序排列。上述代码中是先放入dmac,再依次放入smac、ether_type、pload、crc。
  • my_monitor的collect_one_pkt可以简化成:
task my_monitor::collect_one_pkt(my_transaction tr);byte unsigned data_q[$];byte unsigned data_array[];logic [7:0] data;logic valid = 0;int data_size;...`uvm_info("my_monitor", "begin to collect one pkt", UVM_LOW);while(vif.valid) begindata_q.push_back(vif.data);@(posedge vif.clk);enddata_size = data_q.size();data_array = new[data_size];for ( int i = 0; i < data_size; i++ ) begindata_array[i] = data_q[i];endtr.pload = new[data_size - 18]; //da sa, e_type, crcdata_size = tr.unpack_bytes(data_array) / 8;`uvm_info("my_monitor", "end collect one pkt", UVM_LOW);
endtask
  • 使用unpack_bytes函数将data_q中的byte流转换成tr中的各个字段。这个函数的输入参数必须是一个动态数组,所以需要先把收集到的、放在data_q中的数据复制到一个动态数组中。由于tr中的pload是一个动态数组,所以需要在调用unpack_bytes之前指定其大小, 这样unpack_bytes函数才能正常工作。
http://www.lbrq.cn/news/2601397.html

相关文章:

  • 西安市做网站的江苏seo技术教程
  • 网站建设管理标准优化设计电子课本
  • 广州白云做网站的公司排行榜网站
  • 建材行业网站建设乱码链接怎么用
  • 武昌网站建设介绍产品的营销推文
  • 代做效果图网站好悟空建站seo服务
  • 把微信小程序做网站域名解析查询站长工具
  • 潮州网站制作推广软件下载
  • 营销型网站建百度关键词seo优化
  • 小程序制作网站app推广拉新平台
  • 哪个网站做外贸年费比较便宜建立个人网站
  • 吉林省建设安全协会网站广告最多的网站
  • 自助游网站开发分析报告总结网站广告投放收费标准
  • 汉聪电商代运营怎么样硬件优化大师下载
  • 怎么自己做网站深圳信息公司做关键词
  • 键盘事件对网站交互营销软文范例500
  • 住房与建设部网站首页杭州哪家seo公司好
  • 有哪些网站可以做外贸优秀企业网站模板
  • 广州3d网站开发网络营销经典失败案例
  • 做直播网站软件有哪些软件下载百度竞价开户
  • 青海企业网站建设公司seo是如何优化
  • 山西建站管理系统开发亚马逊关键词优化软件
  • 网站开发应用到的技术名词企业网址怎么注册
  • 网站 整体架构长春seo快速排名
  • 成都专业做网站公司互联网电商平台
  • 做电商看的网站有哪些新东方线下培训机构官网
  • 苏州家教网站建设贵阳网站建设推广
  • 北京个人网站建设甘肃新站优化
  • 网站模块怎么恢复百度词条搜索排行
  • 知名室内设计网站企业网站推广方法
  • Linux网络编程:TCP初体验
  • 【深度学习新浪潮】近三年零样本图像分类研发进展调研
  • LCL滤波器及其电容电流前馈有源阻尼设计软件【LCLAD_designer】
  • 【Bluetooth】【Transport层篇】第四章 基于基础UART的蓝牙硬件发送协议 UART H4 Transport详解
  • 零基础 “入坑” Java--- 十六、字符串String 异常
  • 【Android】通知