wget lhttps://www.accellera.org/images/downloads/standards/systemc/scv-2.0.1.tar.gz
解压缩
tar -xf scv-2.0.1.tar.gz
cd scv-2.0.1
mkdir build
cd build
../configure --with-systemc=/opt/systemc CXXFLAGS="-std=c++11" CFLAGS="-std=c11"
make -j CXXFLAGS=-DSC_DISABLE_API_VERSION_CHECK
sudo make install
/opt/systemc/ 这里是之前编译 systemc 产物的路径
编译成功之后,scv 的产物会放在和 systemc 产物相同的路径
编译运行测试例子
cd ../examples/data_structures/scv_bag
g++ test.cc -std=c++11 -lscv -lsystemc
./a.out
能编译运行成功,说明整个 scv 验证库的编译和运行没有问题了
Systemc 验证库 SCV2.0 为构建高级的 systemc 可重用的验证 IP 提供语言功能,主要包括
数据内查
随机数产生,随即种子管理
约束的随机化
变量和事务的记录
除了上述各项,SCV 还包括了一些对编写验证平台非常有用的语言功能,主要包括
到其他硬件描述语言的接口
常见数据结构的小集合
异常处理
调试
struct Color {
sc_uint<8> red;
sc_uint<8> green;
sc_uint<8> blue;
sc_uint<8> alpha;
Color& operator=(const Color& rhs) {
red = rhs.red;
green = rhs.green;
blue = rhs.blue;
alpha = rhs.alpha;
return *this;
}
friend ostream& operator<< (ostream& os, const Color& p) {
os << " red: " << std::setw(3) << p.red
<< " green: " << std::setw(3) << p.green
<< " blue: " << std::setw(3) << p.blue
<< " alpha: " << std::setw(3) << p.alpha;
return os;
}
};
template<>
class scv_extensions : public scv_extensions_base {
public:
scv_extensions> red;
scv_extensions> green;
scv_extensions> blue;
scv_extensions> alpha;
SCV_EXTENSIONS_CTOR(Color) {
//must be in order
SCV_FIELD(red);
SCV_FIELD(green);
SCV_FIELD(blue);
SCV_FIELD(alpha);
}
};
enum PrimitiveType {
kPrimitiveTypePoint;
kPrimitiveTypeLine;
kPrimitiveTypeTriangle;
};
struct PrimitiveInfo {
PrimitiveType type;
uint32_t attribute_count;
};
template<>
class scv_extensions : public scv_enum_base< {
public:
SCV_ENUM_CTOR(PrimitiveType) {
SCV_ENUM(kPrimitiveTypePoint);
SCV_ENUM(kPrimitiveTypeLine);
SCV_ENUM(kPrimitiveTypeTriangle);
}
};
template<>
class scv_extensions : public scv_extensions_base {
public:
scv_extensions type;
scv_extensions attribute_count;
SCV_EXTENSIONS_CTOR(PrimitiveInfo) {
//must be in order
SCV_FIELD(type);
SCV_FIELD(attribute_count);
}
};
// 固定某一个值
void keep_only(const T& value);
// 设置一个范围
void keep_only(const T& lb, const T& ub);
// 设置某几个值
void keep_only(const std::list& vlist);
// 设置不取某个值
void keep_out(const T& value);
// 设置不取范围内的值
void keep_out(const T& lb, const T& ub);
// 设置不取某几个值
void keep_out(const std::list& vlist);
scv_bag > dist;
dist.add(10, 50); // 取值为 10 的概率为 50%
dist.add(15, 30); // 取值为 15 的概率为 15%
dist.add(20, 20); // 取值为 20 的概率为 20%
p->alpha.set_mode(dist);
约束类:scv_constraint_base,约束类用于定义约束,以及将多个复杂和简单约束合并在一起成为一个更复杂的约束
struct addr_constraint : public scv_constraint_base {
// 定义需要约束的变量
scv_smart_ptr row;
scv_smart_ptr col;
// 构造函数
SCV_CONSTRAINT_CTOR(addr_constraint) {
std::string name = std::string(get_name()) + ".row";
row->set_name(name.c_str());
name = std::string(get_name()) + ".col";
col->set_name(name.c_str());
}
// 设置约束条件
SCV_SOFT_CONSTRAINT((row() > 10 && row() < 50) ||
(row() >= 200 && row() <= 250));
SCV_CONSTRAINT ( col() > ( row() - 5) );
SCV_CONSTRAINT ( col() < ( row() + 20) );
};
int sc_main(int argc, char* argv[]) {
scv_random::set_global_seed(0xCCCC);
addr_constraint addr("addr");
addr.col->disable_randomization();
*(addr.col) = 1000;
addr.next();
scv_out << addr.row->get_name() << " = " << *(addr.row) << "\n"
<< addr.col->get_name() << " = " << *(addr.col) << "\n" << endl;
return 0;
}
软约束和硬约束的区别
软约束失败,会给出一个警告,但是不会影响运行,只不过产生的值会是一个随机值,不再受约束
硬约束失败,除了会给出一个警告以外,还会产生错误,程序会直接报错
scv_smart_ptr 类型的对象可以通过调用 next() 函数产生均匀分布的随机数
scv_bag 可以为随机数设置加权的分布,使得 scv_smart_ptr 类型的对象的 next() 函数返回的随机数的分布满足所设置的加权分布
scv_bag 的成员函数
void add(const T& arg, int num=1); // 将产生的随机对象加入到袋子中
void push(const T& arg, int num = 1); // 和 add 一样
// 在袋子中取一个随机对象,并设置是否将当前对象标记为 mark 状态
// peekRandom 只能取出 unmark 状态的值
const T& peekRandom(bool mark = false);
// 表示是否将上一次取出的对象标记为 mark 状态
void mark(bool AllCopies = false);
// 将袋子中的所有对象都标记为 mark 状态
void markAll();
void mark_all();
// 取消袋子中的所有对象的 mark 状态
void unmarkAll();
void unmark_all();
// 随机在给定条件下取值
void next();