chnl_pkg——MCDF验证环境(1)

对mcdf这个验证项目,从顶层环境来看一共有:

 第一个子模块是channel=node+fifo,按我自己的理解是接收apb总线从端写入过来的数据。

这里的问题是,mcdf的输入端数据的来源是?

要写chnl_pkg,整体的结构是怎么样的?

子模块的顶层环境是agent,agent包含了driver,sequencer,monitor,driver和seqr之间的通信通过两个组件自带的tlm端口实现。通过这个sequencer的item是chnl_trans,在sequence中产生。

其中,chnl_trans需要传递的包,包含的成员变量包括:数据本身,通道的id(有4个node),发包的间隔,数据之间的间隔,包与包之间的间隔,最后是发送完毕的单比特标志位rsp。


正文开始,按照自己的理解敲出来代码,然后再修正。

chnl_pkg

第一版本如下,一个class写完就订正吧。

//要写的是chnl_pkg,所以先写大标题
package chnl_pkg;
//需要用到uvm,两句话少不了
import uvm_pkg::*;
`includ "uvm_macro.svh"

//正片开始,从小写到大,从item开始写
//chnl_trans继承于uvm_sequence_item类
class chnl_trans extends uvm_sequence_item;
//声明随机变量,也就是包的成员变量,按照刚才说的
rand int [31:0] data[];//数据个数不确定,用动态数组,数据是32位的
rand int [ 1:0] chnl_id;//一共4个通道
rand int data_idle;//间隔的位数要用多少?怎么确定?
rand int pkg_idle;//同理
     bit rsp;//标志位不用随机变量

//做约束,也就是初始化
constraint trans_cnst {
//data的随机化按chnl_id左移8位+id先
	soft data[i]=chnl_id<<8 + chnl_id;
	soft chnl_id=2'd0;
	soft data_idle inside {0:4};
	soft  pkg_idle inside {0:10};
	}

//然后做注册和域的自动化
`uvm_utils_begin(chnl_trans)
	`uvm_field_array_int(data[i], UVM_ALL_ON)
	`uvm_field_int(chnl_id, UVM_ALL_ON)
	`uvm_field_int(data_idle, UVM_ALL_ON)
	`uvm_field_int(pkg_idle, UVM_ALL_ON)
`uvm_utils_end(chnl_trans)

//然后是每个类都需要的new函数,item继承于trans事务类,又继承于object类
function void new (string "name");
	super.new("chnl_trans");
endfunction

endclass: chnl_trans

uvm两句话,少了个s

  import uvm_pkg::*;
  `include "uvm_macros.svh"

声明随机变量时只有data有位宽,其他都不用

成员变量还有包的id

随机变量的约束,动态数组限制size在4-32,用等式==而不是赋值=;数据生成用foreach,规律是'hC0000000+数据左移24位+包id左移8位+i;约束的花括号最后要加分号;

域的自动化,动态数组只写data,rsp也需要写到,

new函数的写法,参数是string name="chnl_trans",super的参数写name即可

第二个版本

package chnl_pkg;

import uvm_pkg::*;
`includ "uvm_macros.svh"

class chnl_trans extends uvm_sequence_item;
rand int [31:0] data[];
rand int chnl_id;
rand int  pkg_id;
rand int data_idle;
rand int  pkg_idle;
     bit rsp;

constraint trans_cnst {
	soft data.size() inside {4:32};
	foreach(data[i]) data[i]=='hC0000000+(chnl_id<<24)+(pkt_id<<8)+i;
	soft chnl_id==0;
    soft pkg_id==0;
	soft data_idle inside {0:2};
	soft  pkg_idle inside {1:10};//发包时序,有印象是不能连续发包
	};//注意分号

`uvm_object_utils_begin(chnl_trans)
	`uvm_field_array_int(data, UVM_ALL_ON)
	`uvm_field_int      (chnl_id, UVM_ALL_ON)
	`uvm_field_int      ( pkg_id, UVM_ALL_ON)
	`uvm_field_int      (data_idle, UVM_ALL_ON)
	`uvm_field_int      (pkg_idle, UVM_ALL_ON)
	`uvm_filed_int      (rsp, UVM_ALL_ON)
`uvm_object_utils_end

function void new (string name="chnl_trans");
	super.new(name);
endfunction

endclass: chnl_trans

错误如下:

pkt_id的类型是int而不是bit,手误了;

约束中data.size不用加括号;

约束中foreach后data要加soft;

data约束是两个id相加不是加自身data,并且两个id要加上this前缀表示在这个class中的;

约束中两个inside后面要加{},里面才是范围[1:10]

约束的花括号最后要加分号;

注册的宏是`uvm_object_utils_begin(chnl_trans)和`uvm_object_utils_end;

new函数没有void;

总结:这里data其实是payload。一个包可以是数量不同、间隔不同的数据组成的


chnl_driver

接下来是driver ,负责从sequencer中拿到刚才写的item,解析,设置好通道和包的id后返回给sequencer一个rsp并点亮rsp,通信手段是自带的seq_item_port和export端口。

第一个版本

class chnl_driver extends uvm_driver #(chnl_trans);

chnl_trans req,rsp;
`uvm_component_utils(chnl_driver)

function new (string name="chnl_driver", 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值