我正在从SystemVerilog的代码移植到SystemC。 SV很容易将位/逻辑的打包结构解释为单个位/逻辑向量。例如:
typedef struct logic {
logic [31:0] blk1; //63:32
logic [4:0] blk2; //31:27
logic [2:0] blk3; //26:24
logic [4:0] blk4; //23:19
logic [2:0] blk5; //18:16
logic [7:0] blk6; //15:8
logic [7:0] blk7; //7:0
} typ_block;
...
typ_block blockA;
logic[63:0] blockB;
blockB = blockA; // no problem here
但是使用SystemC并使用sc_lv<>模板,由于类型不匹配,这会产生编译器错误。
struct typ_block {
sc_lv<32> blk1; //63:32
sc_lv<5> blk2; //31:27
sc_lv<3> blk3; //26:24
sc_lv<5> blk4; //23:19
sc_lv<3> blk5; //18:16
sc_lv<8> blk6; //15:8
sc_lv<8> blk7; //7:0
};
...
typ_block blockA;
sc_lv<64> blockB;
blockB = blockA; // compiler error
是否有一个很好的SystemC支持的方法来做同等的事情?我可以想到潜在的解决方案,但它们不优雅或简洁,我不确定c风格的指针是否安全/正确。
答案 0 :(得分:5)
您自己的答案稍有改进。您无需转换为字符串,因为sc_lv
类型可以与()
运算符连接。
所以你可以像这样简化你的功能:
sc_lv<64> to64bit() { return (blk1, blk2, blk3, blk4, blk5, blk6, blk7); };
我想有一种方法可以通过重载typ_block
的一些运算符来使简单赋值工作,但我不确定它是什么。
答案 1 :(得分:1)
这是使用C ++类型转换运算符重载来替换to64bit()
。
struct typ_block {
sc_lv<32> blk1; //63:32
sc_lv<5> blk2; //31:27
sc_lv<3> blk3; //26:24
sc_lv<5> blk4; //23:19
sc_lv<3> blk5; //18:16
sc_lv<8> blk6; //15:8
sc_lv<8> blk7; //7:0
operator sc_lv<64>() const {
return sc_lv<64>((blk1.to_string() + blk2.to_string() + ...).c_str());
}
};
typ_block blockA;
sc_lv<64> blockB;
blockB = blockA;
这个C ++运算符的限制是你必须使用显式表达式让编译器知道类型转换。这意味着您无法使用blockB = (blockA).range(7,0);
,您必须使用blockB = sc_lv<64>(blockA).range(7,0);
。
答案 2 :(得分:0)
struct typ_block {
sc_lv<32> blk1; //63:32
sc_lv<5> blk2; //31:27
sc_lv<3> blk3; //26:24
sc_lv<5> blk4; //23:19
sc_lv<3> blk5; //18:16
sc_lv<8> blk6; //15:8
sc_lv<8> blk7; //7:0
// replacing the commented version by combining jclin's and dwinkle's answers
// sc_lv<64> to64bit() { return (sc_lv<64>((blk1.to_string() + blk2.to_string() + blk3.to_string() + blk4.to_string() + blk5.to_string() + blk6.to_string() + blk7.to_string()).c_str())); };
operator sc_lv<64>() const { return (blk1, blk2, blk3, blk4, blk5, blk6, blk7); };
};
...
typ_block blockA;
sc_lv<64> blockB;
blockB = blockA;