2012-11-02 170 views
3

我正在将一些SystemVerilog代码移植到SystemC/C++。我使用std :: bitset来表示位向量,但我可以看到它已经不能提供访问切片的方法。如何在C++中执行SystemVerilog风格的位矢量切片分配?

例如,如果我想设置REG1至位REG2的4-8 SystemVerilog的代码:

bit [3:0] reg1; 
bit [15:0] reg2; 
reg1 = reg2[7:4]; 

我怎么能做到这一点用的std :: bitset的?

bitset<4> reg1; 
bitset<16> reg2; 
reg1[0] = reg2[4]; 
reg1[1] = reg2[5]; 
reg1[2] = reg2[6]; 
reg1[3] = reg2[7]; 

有没有更好的方法?

+0

我会写一个函数'subbit(常量的std :: bitset的&位,SIZE_T开始,为size_t结束)'掩盖了你想要的位,他们转移到右侧,'begin'是位0等,然后返回该值。它取决于你。 – GManNickG

+0

注意这里有一个根本的不一致:范围可以在运行时指定,但bitset大小在编译时指定。除非你保证范围用积分常数表达式表示,否则你不能肯定地说(没有运行时检查)结果范围足够小以适应目标比特集。也就是说,你必须在运行时检查'end - begin <= N'。您可以提供一个备用函数'subbit_c (std :: bitset ) - > std :: bitset '以确保匹配类型。 – GManNickG

回答

4

现在你正在使用SystemC的,你为什么不使用sc_bv <>原生地代表HDL信号?由于SystemC具有一组数据类型来表示HDL位/逻辑方式和字逻辑运算符,因此将SystemVerilog/Verilog数据类型映射到C/C++代码应该更加容易。

sc_bv<4> reg1; 
sc_bv<16> reg2; 
reg1 = reg2.range(7,4); 
+0

谢谢,我不知道关于sc_bv,我会检查出来。 – Rich

+0

是的,到目前为止,这只是做我想要的。它也支持常量和变量范围。 – Rich

3

如果你想在位集操作 - 然后用to_string函数:

bitset<4> reg1; 
bitset<16> reg2; 
reg1 = bitset<4>(reg2.to_string().substr(4,4)); 

这不是非常有效的方式,但应该工作。

如果您没有比32位或64位大的位集 - 然后使用to_ulongto_ullong版 - 应该会更高效。

还考虑使用std::vector<bool>而不是std::bitset<>。乡亲们在这里有倾向每次他们看到std::vector<bool>时间作出downvote,但它可能是更有效的位置:

vector<bool> reg1(4); 
vector<bool> reg2(16); 
reg1.assign(reg2.begin() + 4, reg2.begin() + 8);