SystemC的随机验证过程是怎样的?

电子说

1.3w人已加入

描述

SystemC是基于C++的系统级设计语言,兼具描述硬件电路模型和面向对象的抽象能力。在芯片设计开发中,常用于芯片架构的建模、性能仿真和评估、软硬件联合仿真等场景。尤其是在融合TLM2.0事务级建模方法以后,SystemC的模型也出现事务级、cycle级等不同抽象等级的划分,用于不同的场景需求。

随着基于systemC建模的广泛适用,对SC模型的验证也是应运而生;正如Systemverilog用于对verilog的验证。SystemC Verification (SCV)就是SC中的一个验证库,其包含了:

transaction-based verification

data introspection

constrainted and weighted randomization

RTL

这篇文章准备介绍SCV中的约束随机:constrainted randomization。在systemverilog中随机约束是CDV的一大利器,SV中具有丰富的随机表达语法,比如inside、dist、solve before、->、unique等。C/C++中却不具备如此丰富的约束能力,而SCV作为SC的验证库,引入了约束随机描述。

Basic Randomization

无论是sc内建的基本数据类型,如sc_int/sc_uint等;还是自定义的struct数据,都可以使用scv_smart_ptr修饰,进行基本的随机化操作。常见的用法如下:

 

//基本数据类型随机
scv_smart_ptr< sc_uint<8> > data; 
data->next(); 
//自定义数据结构随机
struct packet_t { 
int data; 
int array[10]; 
}; 
scv_smart_ptr< packet_t > p; 
// generate a random value and assign it to the data field 
p->data.next(); 


//generate a random value and assign it to the array element with index 3 
p->array[3].next(); 


// generate random values for all fields and all array elements 
p->next(); 


// generate random values for all fields and all array elements, 
//except for the data field
p->data.disable_randomization(); 
p->next();

 

scv_smart_ptr会例化一个内部的随机对象,使用next方法产生随机值。
对于自定义符合数据结构,也可以只针对其中部分参数进行随机;不需要随机的参数,使用disable_randomization关闭随机。

Constrained Randomization

上述的简单约束,可以使用scv_smart_ptr实现。对于其他的复杂约束,则需要借助scv_constraint_base实现。(scv_smart_ptr可以认为是systemverilog中的random函数,而constraint或者solve-before,则必须要在class中实现)。
用法如下:

 

class write_constraint : virtual public scv_constraint_base { 
public: 
scv_smart_ptr< rw_task_if::write_t > write; 
SCV_CONSTRAINT_CTOR(write_constraint) { 
SCV_CONSTRAINT( write->addr() < 0x00FF ); 
SCV_CONSTRAINT( write->addr() != write->data() ); 
} 
}; 
//上面SCV代码的systemverilog等效格式:
class write_constraint extend scv_constraint_base ; 
rand rw_task_if::write_t  write; 
constraint write_constraint { 
write.addr < 0x00FF; 
write.addr != write.data; 
} 
endclass

 

在scv_constraint_base扩展出的子类中,需要随机的参数仍需要使用scv_smart_ptr修饰。使用SCV_CONSTRAINT_CTOR声明一段约束,SCV_CONSTRAINT用于添加一条约束表达式。
约束表达式可以支持:算术表达式(+,-,*,/),关系表达式(==, !=, >, >=, <, <=),逻辑表达式( !, &&, ||)。约束表达式有三种:

   1. SCV_CONSTRAINT代表是一种hard constraint;

   2. SCV_SOFT_CONSTRAINT表达一种soft constraint;

    3. SCV_BASE_CONSTRAINT代表基类中的约束。

此处的hard和soft constraint含义和systemverilog中soft修饰随机的含义基本一致。

上述的随机类定义好后,便可以进行实例化和随机。前面提到的disable_randomization仍然可以使用,并且统一使用next方法进行随机生成。

 

write_constraint c("write constraint"); 
for (int i=0; i<2; ++i) { 
c.next(); 
cout << *c.write << endl; 
} 


write_constraint c("write constraint"); 
c.write->addr->disable_randomization(); 
for (int i=0; i<2; ++i) { 
c.write->addr = i; 
c.next(); 
cout << *c.write << endl; 
}

 

Weight and Biased Randomization

在systemverilog随机约束中,经常会使用到inside、dist,用来表达带有权重的随机。同样,SCV支持指定范围随机和带权重的随机,通过scv_bag实现。scv_bag可以用来收集需要范围随机信息以及权重信息。
单值权重设置使用scv_bag 表达,实例:

 

scv_bag bag; 
bag.push(1,60); 
bag.push(2,40); 
scv_smart_ptr data; 
data->set_mode(bag); 
data->next(); 
//systemverilog的等效表达
rand int data;
data dist {1:/60,2:/40};

 

在scv_bag收集好权重信息后,通过set_mode函数传递给参数的随机对象即可。范围权重设置使用scv_bag< pair< int,int> >表达,实例:

 

scv_smart_ptr data; 
scv_bag< pair< int,int> > distribution; 
distribution.push( pair(0,1), 40); 
distribution.push( pair(2,10), 60); 
data->set_mode(distribution); 
data->next(); 
//systemverilog的等效表达
rand int data;
data dist {[0:1]:/60,[2:10]:/40};

 

从上面可以看出如果需要添加范围约束和权重约束,就必须要定义scv_bag,添加约束范围和权重,并通过set_mode设置,稍显复杂。因此SCV中引入keep_only和keep_out方法,用于添加随机约束范围,类似systemverilog中的inside和~inside。

 

scv_smart_ptr i; 
i->keep_only(0,4); 
i->keep_out(2); 
i->next(); 
// generate a value among { 0, 1, 3, 4 } 
//如果使用scv_bag方式,方法如下:
scv_smart_ptr i; 
scv_bag bag; 
bag.add(0); bag.add(1); bag.add(3);bag.add(4);  
i->next();

 

keep_only和keep_out除了可以接受固定数值外,还可以接收list类型的变量。

 

scv_smart_ptr i; 
list i_range;
i_range.push_back(0);
i_range.push_back(4);
i->keep_only(i_range); 
i->keep_out(2); 
i->next(); 
// generate a value among { 0, 3, 4 }

 

总结来看,设置随机约束有如下方式:

set_mode方法

keep_only、keep_out方法

SCV_CONSTRAINT约束表达式

set_mode和keep_only/out的随机约束设置会进行覆盖。使用reset_distribution方法可以取消set_mode和keep_only/out方法设置的随机约束。实例如下:

 

scv_smart_ptr i; 
i->keep_only(0,4); 
i->keep_out(2); 
i->next(); // generate a value among { 0, 1, 3, 4 } 
 
scv_bag b; 
b.add(2); b.add(7); 
i->set_mode(b); 
i->next(); // generate a value among {2,7} 


i->reset_distribution(); 
i->next(); // generate a value between INT_MIN and INT_MAX.

 

写在最后

SCV 约束除了作为SC模型的验证随机约束外,一方面可以把SC模型阶段的验证激励复用到中后期的RTL验证;

RTL

另一方面还可以在CPU核相关的C语言case中使用,由于SCV是基于C/C++语言,因此可以比较容易地和C based case结合,具体融合方式需要一些转接件,这个后续有机会再做介绍。





审核编辑:刘清

打开APP阅读更多精彩内容
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉

全部0条评论

快来发表一下你的评论吧 !

×
20
完善资料,
赚取积分