在SystemC model和RTL进行co-sim的时候,model中经常需要用到SystemC的sc_bv 类型数据与System Verilog代码进行交互。
sc_bv 是 bit vector的简称,在namespace sc_dt (data types)中定义。
sc_bv继承于sc_bv_base,sc_bv_base继承于sc_proxy<sc_bv_base>。sc_bv是一个模板类,定义时需要传入一个int参数,表示位宽。
对sc_bv类型赋值,可以使用bool / int / long / unsigned int/ …. char* / sc_logic 。
基类sc_proxy提供了to_string 和to_uint64 / to_int … 等函数。使用<< 打印
访问或改写sc_bv 类型中的某1个bit,可以使用 operator[] 下标;访问或改写某几个bit,可以使用 operator(int high, int low) 或range(int high, int low)。这两个重载函数和range也是在基类sc_proxy中定义。
需要注意,如果使用字符串给sc_bv 类型赋值,需要加 进制标记;且如果 赋值的数据bit 位数 小于 类型的bit数,需要在数据前加0前缀。
sc_uint 继承于sc_uint_base,功能跟sc_bv 类似,赋值方法一样,访问或改写其中1bit或某几个bit的方法也一样。将下面的代码中sc_bv直接改为sc_uint,最终的打印结果同sc_bv.
// execute:
// g++ -g -Wall -lsystemc -m64 -pthread main.cpp
// -L/$(your systemc path)/lib-linux64
// -I/$(your systemc path)/include -I/$(your systemc
// path)/src/tlm_utils -o sim
#include "tlm"
#include <systemc>
using namespace std;
int sc_main(int argc, char **argv) {
sc_dt::sc_bv<30> m_data;
sc_dt::sc_bv<30> m_data_1 (0x456);
m_data = "0x0a123"; // here should add 0x for hexadecimal; if not 30bit data, must add 0 before the data
std::cout << "m_data (0x0a123): " << std::hex << m_data.to_uint64()
<< std::endl;
m_data = "0xa123"; // here del 0 before a123, can find the print is 0x3fffa123
std::cout << "m_data (0xa123): " << std::hex << m_data.to_uint64()
<< std::endl;
std::cout << "m_data_1: " << std::hex << m_data_1.to_uint64() << std::endl;
std::cout << "m_data[1]: " << m_data[1]
<< std::endl; // call sc_bitref<X> operator [] ( int i )
std::cout << "m_data_1(6,1): " << std::hex << m_data_1(6, 1)
<< std::endl; // call sc_subref<X> operator () ( int hi, int lo )
std::cout << "m_data_1.range(6,1): " << std::hex << m_data_1.range(6, 1) << std::endl;
// change sc_bv bit value
m_data[1] = 0;
std::cout << "m_data[1]: " << m_data[1] << std::endl;
m_data_1(6, 1) = 0x03b;
std::cout << "m_data_1(6,1) changed : " << std::hex << m_data_1(6, 1) << std::endl;
std::cout << "m_data_1 changed : " << std::hex << m_data_1.to_uint64() << std::endl;
m_data_1.range(6, 1) = 0x023;
std::cout << "m_data_1(6,1) changed : " << std::hex << m_data_1(6, 1) << std::endl;
std::cout << "m_data_1 changed : " << std::hex << m_data_1.to_uint64() << std::endl;
sc_core::sc_start();
return 0;
}
Print结果如下
m_data (0x0a123): a123
m_data (0xa123): 3fffa123
m_data_1: 456
m_data[1]: 1
m_data_1(6,1): 2b
m_data_1.range(6,1): 2b
m_data[1]: 0
m_data_1(6,1) changed : 3b
m_data_1 changed : 476
m_data_1(6,1) changed : 23
m_data_1 changed : 446
C++ 函数调用运算符 () 重载,可参考 C++ 函数调用运算符 () 重载 | 菜鸟教程