Multi-bit Verilog wires and variables can be clubbed together to form a bigger multi-net wire or variable using concatenation operators {
and }
separated by commas. Concatenation is also allowed to have expressions and sized constants as operands in addition to wires and variables.
Size of each operand must be known in order to calculate the complete size of concatenation.
Verilog Concatenation Example
wire a, b; // 1-bit wire
wire [1:0] res; // 2-bit wire to store a and b
// res[1] follows a, and res[0] follows b
assign res = {a, b};
wire [2:0] c;
wire [7:0] res1;
// res[0] follows c[2]
// res[2:1] is always 0
// res[4:3] follows c[1:0]
// res[5] follows a
// res[6] follows b
assign res1 = {b, a, c[1:0], 2'b00, c[2]};
Here is a working design example of concatenation of inputs to form different outputs. Concatenated expressions can be simply displayed or assigned to any wire or variable, not necessarily outputs.
module des (input [1:0] a,
input [2:0] b,
output [4:0] out1,
output [3:0] out2
);
assign out1 = {a, b};
assign out2 = {a[1], 2'b01, b[2]};
endmodule
module tb;
reg [1:0] a;
reg [2:0] b;
wire [4:0] out1;
wire [3:0] out2;
des u0 (a, b, out1, out2);
initial begin
a <= 0;
b <= 0;
$monitor("[%0t] a=%b b=%b, out1=%b out2=%b", $time, a, b, out1, out2);
#10 a <= 3;
#5 b <= 5;
#10 a <= 2;
#5 b <= 1;
#10 $finish;
end
endmodule
Note that out2[2:1] is always a constant 2'b01.
Simulation Logxcelium> run [0] a=00 b=000, out1=00000 out2=0010 [10] a=11 b=000, out1=11000 out2=1010 [15] a=11 b=101, out1=11101 out2=1011 [25] a=10 b=101, out1=10101 out2=1011 [30] a=10 b=001, out1=10001 out2=1010 Simulation complete via $finish(1) at time 40 NS + 0
Replication Operator
When the same expression has to be repeated for a number of times, a replication constant is used which needs to be a non-negative number and cannot be X, Z or any variable. This constant number is also enclosed within braces along with the original concatenation operator and indicates the total number of times the expression will be repeated.
wire a;
wire [6:0] res;
assign res = {7{a}};
{2'bz{2'b0}} // Illegal to have Z as replication constant
{2'bx{2'b0}} // Illegal to have X as replication constant
Replication expressions cannot appear on the left hand side of any assignment and cannot be connected to output
or inout
ports.
module des;
reg [1:0] a;
reg [2:0] b;
initial begin
a <= 2;
b <= 4;
#10;
$display("a=%b b=%b res=%b", a, b, {{2{a}}, {3{b}}});
end
endmodule
Note that a got repeated twice and b got repeated thrice.
Simulation Logxcelium> run a=10 b=100 res=1010100100100 xmsim: *W,RNQUIE: Simulation is complete.
Operands will be evaluated only once when the replication expression is executed even if the constant is zero.
Nested Replication
A replication expression is allowed to be used inside regular concatenation expressions. Taking the above example as base, a and b has been included into the total concatenated expression.
module des;
reg [1:0] a;
reg [2:0] b;
initial begin
a <= 2;
b <= 4;
#10;
$display("a=%b b=%b res=%b", a, b, {a, b, 3'b000, {{2{a}}, {3{b}}}});
end
endmodule
Simulation Log xcelium> run a=10 b=100 res=101000001010100100100 xmsim: *W,RNQUIE: Simulation is complete.
Illegal usage
module des;
reg [1:0] a;
reg [2:0] b;
reg [3:0] _var;
initial begin
a <= 2;
b <= 4;
_var <= 3;
// This is illegal because variables cannot be used
// as replication constant
$display("a=%b b=%b res=%b", a, b, {_var{a}});
end
endmodule
This results in a compilation error as shown below.
Simulation Log
Top level design units:
des
$display("a=%b b=%b res=%b", a, b, {_var{a}});
|
xmelab: *E,NOTPAR (./testbench.sv,12|45): Illegal operand for constant expression [4(IEEE)].