Multibit Verilog wires and variables can be clubbed together to form a bigger multinet 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; // 1bit wire
wire [1:0] res; // 2bit 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.
xcelium> 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 nonnegative 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.
xcelium> 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.
The Verilog replication operator {}
is commonly used in digital design to create bit patterns for initializing registers, memory arrays, or lookup tables. Here is an example:
Suppose we want to initialize a 16bit register counter to count from 0 to 15 in a clock cycle. We can use the replication operator to create a bit pattern that represents the binary values 0 to 15, and assign it to the counter register:
module counter(input clk,
output reg [15:0] counter);
always @(posedge clk) begin
counter <= counter + 1;
end
// Initialize counter to 0 on reset
initial begin
counter <= {16{1'b0}};
end
endmodule
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
In the above example, we use the replication operator {16{1'b0}} to create a 16bit bit pattern consisting of 16 zeros (1'b0). This initializes the counter register to 0 at the start of the simulation.
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.
Top level design units:
des
$display("a=%b b=%b res=%b", a, b, {_var{a}});

xmelab: *E,NOTPAR (./testbench.sv,1245): Illegal operand for constant expression [4(IEEE)].
Verilog Sign Extension
In Verilog, sign extension is a way of extending a signed number with fewer bits to a wider signed number by replicating the sign bit. Basically, it is used when performing arithmetic or logical operations on numbers with different bit widths.
For example, let's say we have a 4bit two's complement number, 3, represented as 1101. If we want to add this number to another 8bit two's complement number, say 10, represented as 11110110, we first need to sign extend the 4bit number to 8 bits to make it compatible with the 8bit number. To sign extend the 4bit number, we replicate its most significant bit (the sign bit) to fill the additional bits, resulting in 11111101. We can then add this signextended 4bit number to the 8bit number using normal Verilog arithmetic operations.
Here's an example of how to sign extend a 4bit signed number to an 8bit signed number in Verilog using concatenation discussed above:
module sign_extension(input signed [3:0] input_num,
output reg signed [7:0] output_num);
always @(*) begin
if (input_num[3] == 1'b1) begin // if the sign bit is 1
output_num = { {8{1'b1}}, input_num }; // extend with ones
end else begin // if the sign bit is 0
output_num = { {8{1'b0}}, input_num }; // extend with zeros
end
end
endmodule
In this example, the input is a 4bit signed number called input_num , and the output is an 8bit signed number called output_num . The sign bit of the input number is checked, and if it's 1, the output number is extended with ones, otherwise it's extended with zeros.
Note that the syntax for sign extension may vary depending on the specific implementation and tools being used.