General Verilog Codes for Combinational Blocks

In our previous blog, we discussed different combinational circuits but General Verilog codes are essential in writing bigger complex codes for a system. They make it easy for the coders to generalize the overall code. The generalized overall code can then be easily tuned for the design parameters. For example, if a designer writes a code for a multiplier then data width and precision may be required to change for different applications of the multiplier block. Every time different codes for multipliers with different design parameters are not possible. In this tutorial, some general Verilog codes for combinational blocks are explained.

Adder/Subtractor Block

Adder/Subtractor block can perform addition or subtraction based on a control parameter. But this signal may be a parameter based on the design. Data width is a design parameter that needs to be changed for an architecture. Thus parameter data width is to be changed from the instantiation. The general code is as follows

module adsubN #(parameter N = 18)(input sel,input [N-1:0] a,b,
output [N-1:0] s
assign s = (sel)?(a-b):(a+b);


In the above case, an adder/subtractor will be implemented which can perform addition or subtraction based on control input ‘sel’. Data width can be varied based on the parameter N. The designer may think of adding input ‘sel‘ also in the parameter list but in this case either adder will be implemented or subtractor can be implemented.

Fixed Point Multiplier

Fixed point multiplier has output having a fixed number of bits as input operands. Two parameters are important here which are data-width and precision. Precision denotes the number of bits reserved for fractional parts. Now output also should have the same precision otherwise result will be different. The following code is for the fixed point multiplier

module mult #(parameter N=18,
parameter precision = 0)
(a, b, p);
input signed [N-1:0] a,b;
output [N -1:0] p;
wire [2N - 1:0] p1; assign p1 = ab;
assign p = p1[N -1 + precision:precision];

If this is used in a design, then easily precision and width of the multiplier can easily be changed without writing separate code.


Multiplexer chooses one input out of two inputs and sends it to the output based on a control signal. Two things we have to keep in mind while designing a general multiplexer, are the data width, and the number of inputs in the multiplexer. The general verilog code of the multiplexer concerning data-width is discussed below. The second parameter will be discussed in some other blog.

module MuxNbit_2_1 #(parameter N=18)(a,b,s,y);
input [N-1:0] a,b;
input s;
output [N-1:0] y;
assign y = (s)?(b):(a);


The role of a de-multiplexer is to send one input signal to any of two outputs based on a control signal. Here, also two parameters are important to consider while designing a general de-multiplexer block, data width and number of inputs. General de-multiplexer code concerning the first parameter is discussed below.

module DeMuxNbit_1_2 #(parameter N=18)(a,s,y1,y2);
    input [N-1:0] a;
	 input s;
    output reg [N-1:0] y1,y2;
always @*
if (s) begin
y1 = 0;
y2 = a; end
else begin
y1 = a;
y2 = 0; end


Comparator is another important combinational block that is frequently used. A comparator can be used to compare either signed numbers or unsigned numbers. Thus two parameters are required to consider while making it general, data width and sign of data. But here a simple signed general code is shown for the comparator

module comparatorNbit #(parameter N=18)(a,b,less,equal,greater);
input signed [N-1:0] a;
input signed [N-1:0] b;
output reg less;
output reg equal;
output reg greater;
always@(a or b)
if(a>b) begin
else if(a==b) begin
else begin

In this post, we learned how to write General Verilog Codes for Combinational Blocks. In upcoming posts we will learn how to write general codes for sequential blocks and how to use them.

Shopping Basket