首页 > 其他分享 >基于调用C语言作为reference_model的UVM对全加器的验证

基于调用C语言作为reference_model的UVM对全加器的验证

时间:2024-06-05 21:29:29浏览次数:14  
标签:全加器 reference agent C语言 item export analysis ready port

代码来自于 ,本篇文章只对其中的细节做探讨

UVM的基本教程-CSDN博客

首先DUT为加法器,但是舒服不仅是加数和被加数,还有ready和valid,输出也不止是和,还有valid和ready。valid代表数据有效,ready表示已经准备好发送或者接收。

加法器的设计语言中,共有三个状态,INITIAL/WAIT/SEND,rst为1时是复位信号,开始置零和置X,状态转为INITIAL态,下一个状态为WAIT状态,此刻输入信号的ready置一,表示准备好接收输入,下一个状态为SEND,在输入信号valid的情况下,开始赋值输出为输入之和,并输出的valid为1,在输出的ready为1时,进入WAIT,表示开始接收下一轮的数据。

定义了两个transaction组件,第一个为输入的transaction包含了两个rand输入数据A/B,第二个为输出的transaction,为data。transaction 扩展于uvm_sequence_item

在sequence中负责启动transaction,需要在forever之前例化,并在forever中创建事务,采用手动启动的方法:start_item  /  finish_item,并使用断言,如果tx没有随机化的话就退出仿真。

定义了两个driver,一个是在master_agent中,发送数据(transaction)到DUT,采用了get方法从sequence中获取数据,另一个是在slave_agent,只负责控制output的ready信号,这里是无复位时一直为1。

monitor也有两个,一个是监视输入信号,输入进reference_model,另一个监视输出的data,输入scoreboard,以便这两个信号进行对比。对于第一个监视器来说,是在输入信号有效且ready的情况下通过“write”方法写入到reference_model,这里是通过TLM通信机制进行通信的,之后会将整个UVM平台的TLM机制拉通说一遍。第二个监视器同样也是在输出信号valid并ready时把data(A+B)写入。

一样的,有两个agent,一个在输入位置,另一个在输出位置,一个是master_agent,包含了sequencer、monitor、driver,另一个是slave_agent,与master的区别是没有sequencer,因为他不需要从sequence中获取驱动,只需要对输出的ready进行定向驱动。

scoreboard是一个很重要的组件,负责把输入的数据获取到,并利用C语言进行计算,之后把这个结果与输入进来的DUT输出值进行比较。那么如何获取数据,什么时候比对就是关键。在这里先卖个关子,等下面讲清楚TLM机制后再详细说明

在env中需要定义的组件有两个agent,一个reference model,一个scoreboard,他们在env中进行TLM机制的通信接口连接。

在testcase中需要例化env,因为testcase在env的更外层,并在run_phase中手动启动sequence,使用start方法。

在顶层文件top中include所有组件,事务和DUT,并为其注入信号,并配置interface,采用uvm_root::get()方法获取根节点,并返回指针,这样的好处是底下所有组件都可以获取到。

接下来就开始讲解本UVM平台的TLM通信机制:下图为UVM示意图,红线代表的是TLM通信信道。

 ①:driver与sequencer之间的通信,是在master_agent中进行连接的,都是uvm组件中自带的接口(driver中的seq_item_port/sequencer中的seq_item_export,这个export本质是import),无需另外定义。

drv.seq_item_port.connect(sqr.seq_item_export)

②:需要横跨组件传输的话,需要在横跨的组件内部定义一个export作为中转站。在monitor中定义了接口 uvm_analysis_port #(packet_in) item_collected_port;在master_agent中定义了一个export中转站  uvm_analysis_port #(packet_in) item_collected_port ;analysis_port一般是一对多,一对一也可以用,使用write方法广播写入。

在connect phase中由内向外连接到agent的analysis port(analysis export是由外向内连接)

UVM基础-TLM机制之analysis端口与FIFO_analysis tlm-CSDN博客

mon.item_collected_port.connect(item_collected_port)

③:在env中定义了一个fifo中转站:uvm_tlm_analysis_fifo #(packet_in) to_refmod

在env中将master_agent连接到此FIFO:(这里的export实际上是imp)mst.item_collected_port.connect(to_refmod.analysis_export)(from mst_agent to fifo)

④:将FIFO连接到rfm:rfm.in.connect(to_refmod.get_export)(from fifot to rfm)

⑤:在 slave_agent中连接monitor与slave_agent中的export:mon.item_collected_port.connect(item_collected_port)

在scoreboard中定义的端口,两个都是imp,一个来自rfm,一个来自monitor_out检测到的DUT的输出

uvm_put_imp #(T, this_type) from_refmod

uvm_analysis_imp #(T, this_type) from_dut

⑥:slv.item_collected_port.connect(comp.from_dut)

⑦:rfm.out.connect(comp.from_refmod)

整个平台的TLM机制就讲完了,最后来讲scoreboard的工作方式:

首先需要注意的是rfm的数据是通过put方法写入,而两个monitor是通过write方法。

在scoreboard中会用到put 和write任务,顺序是先put,再write,之后再compare。rfm一得到数据就put进去。

在@35时,rfm使用put方法放入,在put任务中需要等待一个时钟周期,所以在@45 put任务结束

在@45时,monitor_out使用write方法将DUT的data输入,write任务不消耗仿真时间

monitor_out在write任务之后等待一个时钟周期,并在valid和ready=0时再等待应该周期(周期为10),之后再进行write任务

compare结果如下图 

波形如下图 

标签:全加器,reference,agent,C语言,item,export,analysis,ready,port
From: https://blog.csdn.net/qq_45667135/article/details/139332569

相关文章

  • 基于c语言的UDP客户端、服务端二合一基础代码
    基于c语言的UDP客户端、服务端二合一基础代码示意图:准备好了吗,以下是基础代码:/****************************************************************************************************************************************字节序:数据以字节流的方式进行传输,底层都是......
  • 基于c语言的TCP客户端、服务端基础代码
    基于c语言的TCP客户端、服务端基础代码基本流程:客户端:#include<sys/socket.h>#include<netinet/in.h>#include<arpa/inet.h>#include<stdio.h>#include<errno.h>#include<sys/socket.h>#include<netinet/in.h>#include<netinet/......
  • 初识C语言(03)—学习笔记
    常见关键字C语言提供了丰富的关键字,这些关键字都是语言本身预先设定好的,用户自己是不能创造关键字的。归类下面是按照关键字的用途不同进行的归类变量的命名规则有意义,例如intage;floatsalary;等名字必须是字母、数字、下划线组成,不能有特殊字符,同时不能以数字......
  • C语言排序
    一、排序的运用生活中排序随处可见,比如我们高考时的排名,大学学校水平的排名等,打开京东,可以发现每样商品按照不同的方式排序,比如综合,销量,价格。其内部需要排序代码来完成。二、常见的排序算法一、交换排序一、冒泡排序冒泡排序是一种最容易想到的排序,但是其效率不高,没有实......
  • 使用C语言实现链式栈
    一、栈的基本概念        栈(Stack)是一种数据结构,它遵循“后进先出”(LIFO,LastInFirstOut)的原则。这意味着最后一个插入栈的元素最先被删除,你可以理解成一堆盘子,每次只能取最上面的盘子,删除的时候也只能删除最上面的盘子。这样是不是更容易理解了呢?栈的基本操作包......
  • 【C语言】文件操作强化
    【C语言】文件操作强化文章目录【C语言】文件操作强化前言一、文件打开关闭文件打开(fopen)文件关闭(fclose)二、文件读写函数字符读写函数行读写函数块读写函数格式化读写函数随机读写函数三、文件读写注意事项四、配置文件读写案例总结前言本篇文章我们将详细......
  • C语言判断文件存在和创建文件
    用C语言可以实现新建文件,这里要用到一个fopen函数,它是一个非常强大的函数,可以以各种方式创建、读取文件,具体语法如下:文件指针名=fopen(文件名,使用文件方式);“文件指针名”必须是被说明为File类型的指针变量;“文件名”是被打开文件的文件名,也包括路径;“使用文件方式”是指文件的......
  • 【C++小知识】为什么C语言不支持函数重载,而C++支持
    为什么C语言不支持函数重载,而C++支持编译链接过程函数名修饰过程总结在了解C++函数重载前,如果对文件的编译与链接不太了解。可以看看我之前的一篇文章,链接:文件的编译链接想要清楚为什么C语言不支持函数重载而C++支持,有俩个过程:1.编译链接。2.函数名修饰过程。编译......
  • UDP内网穿透和打洞原理的C语言代码实现
    v1.02024年6月5日发布于博客园目录序言UDP打洞的原理应用场景基本理论代码实现udp_client_NAT.cudp_server_NAT.c结果参考链接序言UDP打洞(UDPHolePunching)是一种用于在NAT(网络地址转换)设备后面建立直接P2P(点对点)连接的技术。NAT设备通常会阻止外部设备直接与内部设备通......
  • C语言Kruskal算法求最小生成树
    Kruskal算法求出最小生成树。图形算法描述先找最小权值边为1的边有(V1,V4),(V2,V9),保证不产生回路就可以成功选择边除去上一次找的边后,在找权值最小的边为2的有(V2,V3),(V4,V3),(V5,V6),(V9,V8),连接不产生回路的边除去之前找过的边,后面再看权值最小的边为3的边有(V1,V3),(V7,V8),(V9,V7)按顺......