SystemC 学习之 SystemC 验证库(七)

1、下载 SystemC 验证库

wget lhttps://www.accellera.org/images/downloads/standards/systemc/scv-2.0.1.tar.gz

解压缩

tar -xf scv-2.0.1.tar.gz 

2、编译 SystemC 验证库

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 验证库的编译和运行没有问题了

3、SystemC 验证库功能

Systemc 验证库 SCV2.0 为构建高级的 systemc 可重用的验证 IP 提供语言功能,主要包括

  1. 数据内查

  2. 随机数产生,随即种子管理

  3. 约束的随机化

  4. 变量和事务的记录

除了上述各项,SCV 还包括了一些对编写验证平台非常有用的语言功能,主要包括

  1. 到其他硬件描述语言的接口

  2. 常见数据结构的小集合

  3. 异常处理

  4. 调试

4、基本语法

复杂用户数据类型扩展

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<Color> : public scv_extensions_base<Color> {
public:
  scv_extensions<sc_uint<8>> red;
  scv_extensions<sc_uint<8>> green;
  scv_extensions<sc_uint<8>> blue;
  scv_extensions<sc_uint<8>> 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<PrimitiveType> : public scv_enum_base<<PrimitiveType> {
public:
    SCV_ENUM_CTOR(PrimitiveType) {
        SCV_ENUM(kPrimitiveTypePoint);
        SCV_ENUM(kPrimitiveTypeLine);
        SCV_ENUM(kPrimitiveTypeTriangle);
    }
};
template<>
class scv_extensions<PrimitiveInfo> : public scv_extensions_base<PrimitiveInfo> {
public:
  scv_extensions<PrimitiveType> type;
  scv_extensions<uint32_t> 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<T>& vlist);
// 设置不取某个值
void keep_out(const T& value);
// 设置不取范围内的值
void keep_out(const T& lb, const T& ub);
// 设置不取某几个值
void keep_out(const std::list<T>& vlist);

设置权重

scv_bag<sc_uint<8> > 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<int> row;
    scv_smart_ptr<int> 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

scv_smart_ptr 类型的对象可以通过调用 next() 函数产生均匀分布的随机数

scv_bag

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();

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
SystemC是一种用于硬件和软件系统建模与验证的开发工具。它基于C++语言开发,并提供了一套函数和类,用于建立系统级别的模型,包括通信协议、数字信号处理、嵌入式系统等。 相较于其他编程语言,SystemC因其特定于硬件设计的特性而备受关注。它能够提供比较精确的硬件行为模型,因此在硬件验证和调试方面具有较高的效率和准确性。此外,SystemC还支持多线程的并发控制,能够模拟硬件设计中的并行性,更好地满足系统级模型的需求。 对于初学者来说,SystemC的学习曲线可能较陡,因为其需要掌握C++语言和系统级建模的理念。然而,一旦掌握了其基本原理,SystemC能够大大提高硬件系统的设计效率和可靠性。 现在,有许多关于SystemC的电子书可供读者学习和参考。这些电子书涵盖了SystemC的基础知识与应用技巧,可以帮助读者快速掌握SystemC的核心概念和使用方法。同时,这些电子书还提供了丰富的案例和实例,方便读者进行实际的练习和实验。有些电子书还会提供一些SystemC的高级主题,如高层次综合、虚拟原型设计等,帮助读者在实际工程中应用SystemC进行系统级建模与验证。 总之,SystemC电子书为读者提供了学习和实践SystemC的机会,帮助他们掌握这一强大的硬件系统建模与验证工具。读者可以通过电子书来学习SystemC的基础知识,并通过实例和案例来深入理解其应用。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值