SystemVerilog操作符应用总结
一、位拼接操作符
位拼接是由一个或多个表达式产生的bit位连接在一起的结果。位拼接应该使用大括号'{}'表示,其中的表达式用逗号分隔。不允许在连接中使用未调整大小的常数。这是因为需要使用连接中每个操作数的大小来计算连接的完整大小。
- 下面的例子连接了四个表达式:
{a, b[3:0], w, 3'b101};
- 上面的例子与下面的例子是等价的:
{a, b[3], b[2], b[1], b[0], w, 1'b1, 1'b0, 1'b1};
二、复制操作符
复制操作符(也称为多重连接)是由一个前接一个非负、非x和非z常数表达式(称为复制常数)表示的,该常数被括在大括号内。复制表示将多个连接的副本连接在一起。与常规连接不同,包含复制的表达式不能出现在赋值的左侧,也不能连接到输出或输入端口。
- 这个示例把w复制了4次
{4{w}}; // yields the same value as {w, w, w, w}
- 下面的示例显示了非法复制
{1'bz{1'b0}}; // illegal
{1'bx{1'b0}}; // illegal
- 下一个示例演示了嵌套在连接中的复制
{b, {3{a, b}}}; // yields the same value as {b, a, b, a, b, a, b}
三、字符串连接
- 赋值的左侧不允许字符串连接,只允许作为表达式使用。
string hello = "hello";
string s;
s = { hello, " ", "world" };
$display( "%s\n", s ); // displays 'hello world'
s = { s, " and goodbye" };
$display( "%s\n", s ); // displays 'hello world and goodbye'
- 大括号的复制操作符形式也可以用于字符串类型的数据对象。在字符串复制的情况下,允许使用非常数乘数。
int n = 3;
string s = {n { "boo " }};
$display( "%s\n", s ); // displays 'boo boo boo '
四、流操作符(pack/unpack)
流操作符按照用户指定的顺序将位流类型(见LRM6.24.3)打包成一个位序列。在左侧使用时,流操作符执行相反的操作,即将位流解压缩为一个或多个变量。
如果被打包的数据包含任何4状态类型,则打包操作的结果是一个4状态流,否则包的结果是一个2状态流。在本条款的其余部分中,比特一词,无其他限定,表示本段所要求的二态或四态比特。
4.1、基本语法
streaming_concatenation ::= { stream_operator [ slice_size ] stream_concatenation } // from A.8.1
stream_operator ::= >> | <<
slice_size ::= simple_type | constant_expression
stream_concatenation ::= { stream_expression { , stream_expression } }
stream_expression ::= expression [ with [ array_range_expression ] ]
4.2、Example
int j = { "A", "B", "C", "D" };
{ >> {j}} // generates stream "A" "B" "C" "D"
{ << byte {j}} // generates stream "D" "C" "B" "A" (little endian)
{ << 16 {j}} // generates stream "C" "D" "A" "B"
{ << { 8'b0011_0101 }} // generates stream 'b1010_1100 (bit reverse)
{ << 4 { 6'b11_0101 }} // generates stream 'b0101_11
{ >> 4 { 6'b11_0101 }} // generates stream 'b1101_01 (same)
{ << 2 { { << { 4'b1101 }} }} // generates stream 'b1110
int a, b, c;
logic [10:0] up [3:0];
logic [11:1] p1, p2, p3, p4;
bit [96:1] y = {>>{ a, b, c }}; // OK: pack a, b, c
int j = {>>{ a, b, c }}; // error: j is 32 bits < 96 bits
bit [99:0] d = {>>{ a, b, c }}; // OK: d is padded with 4 bits
{>>{ a, b, c }} = 23'b1; // error: too few bits in stream
{>>{ a, b, c }} = 96'b1; // OK: unpack a = 0, b = 0, c = 1
{>>{ a, b, c }} = 100'b1; // OK: unpack as above (4 bits unread)
{ >> {p1, p2, p3, p4}} = up; // OK: unpack p1 = up[3], p2 = up[2],
// p3 = up[1], p4 = up[0]