Concatenation

Braces ( { } ) are used to show concatenation. The concatenation is treated as a packed vector of bits. It can be used on the left-hand side of an assignment or in an expression.

logic log1, log2, log3;
{log1, log2, log3} = 3’b111;
{log1, log2, log3} = {1’b1, 1’b1, 1’b1}; // same effect as 3’b111

Software tools can generate a warning if the concatenation width on one side of an assignment is different than the expression on the other side. The following examples can give a warning of size mismatch:

bit [1:0] packet = {32’b1,32’b1}; // right hand side is 64 bits
int i = {1’b1, 1’b1}; //right hand side is 2 bits

SystemVerilog enhances the concatenation operation to allow concatenation of variables of type string. In general, if any of the operands is of type string, the concatenation is treated as a string and all other arguments are implicitly converted to the string type. String concatenation is not allowed on the left-hand side of an assignment, only as an expression.

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'

The replication operator (also called a multiple concatenation) form of braces can also be used with variables of type string. In the case of string replication, a non-constant multiplier is allowed.

int n = 3;
string s = {n { "hello " }};
$display( "%s\n", s ); // displays 'hello hello hello '

Unlike bit concatenation, the result of a string concatenation or replication is not truncated. Instead, the destination variable (of type string) is resized to accommodate the resulting string.

Unpacked array expressions

Braces are also used for expressions to assign to unpacked arrays. Unlike in C, the expressions must match element for element, and the braces must match the array dimensions. Each expression item shall be evaluated in the context of an assignment to the type of the corresponding element in the array. This means that the following examples do not give size warnings, unlike the similar assignments above:

bit abc [1:0] = {1,1}; // no size warning as bit can be set to 1
int xyz [1:0] = {1'b1, 1'b1}; // no size warning as int can be set to 1'b1

The syntax of multiple concatenations can be used for unpacked array expressions as well. Each replication represents a single dimension.

bit [1:0] unpackedbits = {2 {y}} ; // same as {y, y}
int n[1:2][1:3] = {2{{3{y}}}}; // same as {{y,y,y},{y,y,y}}

SystemVerilog determines the context of the braces when used in the context of an assignment. If used in the context of an assignment to an unpacked array, the braces represent an unpacked array literal or expression.

Outside the context of an assignment on the right-hand side, an explicit cast must be used with the braces to distinguish it from a concatenation. An aggregate expression cannot be used as the target of an assignment. The following is considered illegal:

logic [2:0] a [1:0];
logic [2:0] b, c;
always {b,c} = a; // illegal assignment the braces are not determined to be an unpacked array expression

It can sometimes be useful to set array elements to a value without having to keep track of how many members there are. This can be done with the default keyword:

initial unpackedint = {default:2}; // sets elements to 2

For more arrays of structures, it is useful to specify one or more matching type keys, as illustrated under structure expressions, below.

struct {int a; time b;} a_key[1:0];
a_key = {{a:1, b:2ns}, {int:5, time:$time}};

When the braces include a type, or default key, the braces shall not be interpreted as a concatenation for both packed and unpacked array types.

The rules for unpacked array matching are as follows:

  • An index:value, specifies an explicit value for a keyed element index. The value is evaluated in the context of an assignment to the indexed element and shall be castable to its type. It shall be an error to specify the same index more than once in a single array expression.
  • For type:value, if the element or sub-array type of the unpacked array is equivalent to this type, then each element or sub-array shall be set to the value. The value must be castable to the array element or sub-array type. Otherwise, if the unpacked array is multidimensional, then there is a recursive descent into each subarray of the array using the rules in this section and the type and default keys. Otherwise, if the unpacked array is an array of structures, there is a recursive descent into each element of the array using the rules for structure expressions and the type and default keys. If more than one type matches the same element, the last value shall be used.
  • For default:value, this key specifies the default value to use for each element of an unpacked array that has not been covered by the earlier rules in this section. The value is evaluated in the context of each assignment to an element covered by the default and must be castable to the array element type. Every element shall be covered by one of these rules. If the type key, default key, or replication operator is used on an expression with side effects, the number of times that expression evaluates is undefined.

<< Previous | Next >>