FPGA Implementation of Half Adder and Full Adder

1. What are half adders and full adders?

        A half adder circuit refers to an adder circuit that adds two input data bits, outputs a result bit and a carry bit, and has no carry input. It is an addition operation circuit that implements two one-bit binary numbers.
        The full adder is an upgraded version on the basis of the half adder. In addition to the addition of the addend and the summand, it also adds the carry signal from the previous stage.

2. How to write a half adder module?

2.1. Design method

        The half adder has two 1-bit binary inputs and outputs 1 carry and 1 result bit. The truth table is as follows:

truth table


        According to the truth table, the waveform of the half adder can be drawn:

insert image description here

  • in1 : Addend 1, binary, 1 bit
  • in2 : addend 2, binary, 1 bit
  • sum : result bit, binary, 1 bit
  • cout : carry, binary, 1 bit

2.2, Verilog implementation

        According to the above waveform diagram, the Verilog code can be written as follows:

/* //方法1:直接使用加法(assign语句)进行计算
module half_adder(
	input		in1,	//加数1
	input 		in2,	//加数2
	output		sum,	//两个数的加和
	output		cout	//加数和的进位
);
//使用拼接运算符分别表示:和 与 进位
assign {cout,sum} = in1 + in2; 

endmodule */

/* //方法2:使用always块
module half_adder(
	input			in1,	//加数1
	input 			in2,	//加数2
	output  reg		sum,	//两个数的加和
	output	reg		cout	//加数和的进位
);
//使用拼接运算符分别表示:和 与 进位
always@(*)begin
	{cout,sum} = in1 + in2;
end
 
endmodule */

//方法3:根据真值表把组合逻辑电路化简成与非门的形式
/**************真值表 
   in1	   in2	  summ	  cout
	0		0		0		0
	0		1		1		0
	1		0		1		0
	1		1		0		1
******/
//与非门化简有	sum = in1 ^ in2;	cout = in1 & in2
module half_adder(
	input	in1,	//加数1
	input 	in2,	//加数2
	output	sum,	//两个数的加和
	output	cout	//加数和的进位
);
//根据化简结果分别表示:和 与 进位
assign sum = in1 ^ in2;	
assign cout = in1 & in2;
 
endmodule

        Three ways to achieve this are provided here. The RTL views generated by the three methods are as follows:

method 1

insert image description here

insert image description here

 

  • The RTL views generated by method 1 and method 2 are the same, which means that these two methods are two different expressions of combinational logic circuits.
  • Methods 1 and 2 use bit splicing and addition operations, so the generated circuit contains a half adder
  • Method 3 uses combinational logic: XOR generates the result bit, AND logic generates the carry

2.3、Testbench

        The Testbench file is as follows:

`timescale 1ns/1ns				//时间刻度:单位1ns,精度1ns

module tb_half_adder();			//仿真模块
	
//输入reg 定义
reg	in1;
reg in2;

//输出wire定义
wire cout;
wire sum;

//设置初始化条件
initial begin
	in1<=1'b0;					//初始化为0
	in2<=1'b0;					//初始化为0
end

//产生激励条件
//always #10:表示每10个时钟周期实现后面的操作
always #10 in1<= $random %2;	//每10个时钟周期产生1个随机数
								//然后对随机数模2(结果要么0、要么1),再将其赋值给加数1
always #10 in2<= $random %2;	//同上

//例化被测试模块
half_adder u_half_adder(
	.in1(in1),
	.in2(in2),
	
	.sum(sum),	
	.cout(cout)
);
	
endmodule

2.4. Simulation results

        The simulation is performed using ModelSim, and the simulated waveform is as follows:

insert image description here


        Because the incentives are randomly generated, we will randomly take three points here to verify. As can be seen from the waveform diagram:

  • L1: in1 in2 sum cout is 1010 respectively
  • L1: in1 in2 sum cout is 1101 respectively
  • L1: in1 in2 sum cout is 0110 respectively
  • The outputs of the three points L1, L2, and L3 conform to the truth table

3. How to write a full adder module?

3.1. Design method

The full adder has two 1-bit binary input and a carry from the low-order bit; it outputs 1 carry and 1 result bit. The truth table of the full adder is as follows:

insert image description here

 

        It is not difficult to find that the low-order carry input is actually equivalent to an input (it can be called input 3).
        According to the truth table, the waveform of the full adder can be drawn:

insert image description here

3.2, Verilog implementation

        According to the above waveform diagram, the Verilog code can be written as follows:

//全加器
module full_adder(
	input		in1,	//加数1
	input 		in2,	//加数2
	input 		cin,	//低位向高位的进位
	output		sum,	//两个数的加和
	output		cout	//加数和的进位
);

assign {cout,sum} = in1 + in2 + cin;	//使用位拼接 和 加法运算

endmodule

        The RTL view is as follows:

insert image description here

3.3、Testbench

        The Testbench file is as follows:

`timescale 1ns/1ns				//时间刻度:单位1ns,精度1ns

module tb_full_adder();			//仿真模块

//输入reg 定义
reg	in1;
reg in2;
reg cin;

//输出wire定义
wire cout;
wire sum;

//设置初始化条件
initial begin
	in1<=1'b0;					//初始化为0
	in2<=1'b0;					//初始化为0
	cin<=1'b0;					//初始化为0
end

//产生激励条件
//always #10:表示每10个时钟周期实现后面的操作
always #10 in1<= $random %2;	//每10个时钟周期产生1个随机数
								//然后对随机数模2(结果要么0、要么1),再将其赋值给加数1
always #10 in2<= $random %2;	//同上
always #10 cin<= $random %2;	//同上

//例化被测试模块
full_adder u_full_adder(
	.in1(in1),
	.in2(in2),
	.cin(cin),
	.sum(sum),	
	.cout(cout)
);
	
endmodule

3.4. Simulation results

        The simulation is performed using ModelSim, and the simulated waveform is as follows:

insert image description here

        

        Because the incentives are randomly generated, we will randomly take three points here to verify. As can be seen from the waveform diagram:

  • L1: in1 in2 cin sum cout are 10101 respectively
  • L1: in1 in2 cin sum cout are 10010 respectively
  • L1: in1 in2 cin sum cout are 11111 respectively
  • The outputs of the three points L1, L2, and L3 conform to the truth table

4. Call the half adder to implement the full adder

4.1. Design method

As mentioned earlier, the full adder is just an addition of a low-order carry signal (this signal can be regarded as an addend 3) on the basis of the half adder. The output is the same as a half adder.
Then the full adder can be seen as adding three inputs, then we can first use a half adder to calculate the result of the two addends 1 and 2, and then use the low-order carry (addend 3) and the previous result Add them together to get the result of the full adder.
In short, we can implement a full adder by calling two half adder modules.

        Let's look at the truth table of the half adder and the full adder again:

insert image description here

insert image description here


Instantiate the first half adder module, the input is addend 1, addend 2, then its output is nothing more than four cases:

  • The input is in1 = 0, in2 = 0; the output is sum1 = 0, cout1 = 0, instantiate the second half adder module, the input is sum1, the low-order carry cin, the following situation:
    1.1 cin =0, then sum2= 0, cout2 = 0
    1.2 cin =1 , then sum2 = 1, cout2 = 0
  • The input is in1= 0, in2 = 1; the output sum1 = 1, cout1 = 0, instantiate the second half adder module, the input is sum1, the low-order carry cin, the following situation:
    2.1 cin =0, then sum2= 1, cout2 = 0
    2.2 cin =1 , then sum2 = 0, cout2 = 1
  • Input is in1=1, in2=0; output sum1=1, cout1=0. Same as 2
  • The input is in1 = 1, in2 = 1; the output sum1 = 0, cout1 = 1, instantiate the second half adder module, the input is sum1, low-order carry cin, the following situations:
    4.1 cin =0, then sum2= 0, cout2 = 1
    4.2 cin =1 , then sum2 = 1, cout2 = 1

        

        Comparing the above with the truth table of the full adder, we find that:

  • sum2 is the same as the result of the full adder as sum
  • cout is cou1 || cout 2

        According to this, the block diagram of the instantiation can be drawn:

insert image description here

4.2, Verilog implementation

        According to the above block diagram, the Verilog code can be written as follows:

module full_adder(
	input		in1,	//加数1
	input 		in2,	//加数2
	input 		cin,	//低位向高位的进位
	output		sum,	//两个数的加和
	output		cout	//加数和的进位
);
//wire define
//模块之间的连线,结合模块图理解
wire	h0_cout;
wire	h1_cout;
wire	h0_sum;

assign cout = h0_cout || h1_cout;
 
//例化半加器1
half_adder u1_half_adder(
	.in1(in1),		
	.in2(in2),		
	.sum(h0_sum),	
	.cout(h0_cout)	
);

//例化半加器2
half_adder u2_half_adder(
	.in1(h0_sum),		
	.in2(cin),			
	.sum(sum),			
	.cout(h1_cout)	
);

endmodule

        The resulting RTL view is as follows:

insert image description here


        This is consistent with the previous theoretical block diagram, instantiating two half-adder modules separately.

4.3. Others

        Testbench files are the same as 3.3. The simulation results are the same as 3.4.

Guess you like

Origin blog.csdn.net/wuzhikaidetb/article/details/124116237