본문 바로가기
나의 전자 공부방/Verilog 공부

반감산기를 이용해 전감산기를 만들기

by 나만의생각 2023. 5. 8.

 

일단 감산기를 만들기전에 컴퓨터는 뺄셈을 하기위해 2의 보수를 사용합니다. 예를들어보겠습니다.

 

8의 이진수 표현은 00001000입니다.

2의 보수를 취하기 위해, 우선 모든 비트를 반대로 바꿔줍니다. 즉, 00001000이면 11110111이 됩니다.

그리고 이 수에 1을 더해줍니다. 11110111 + 00000001 = 11111000

따라서, -8의 2의 보수는 11111000입니다.

 

X Y D B
0 0 0 0
0 1 1 1
1 0 1 0
1 1 0 0

반감산기 진리표에 따라서 다음과같이 RTL을 만들어보았습니다.

module half_subtractor (half_a,half_b,difference,borrow);
input half_a, half_b;
output difference, borrow;

	xor(difference, half_a, half_b);
	and(borrow, half_a, ~half_b);

endmodule

xor과 and, not을 사용하여 반감산기를 만듭니다.

반감산기(half subtractor)

 

X Y Borrow in D B
0 0 0 0 0
0 0 1 1 1
0 1 0 1 1
0 1 1 0 1
1 0 0 1 0
1 0 1 0 0
1 1 0 0 0
1 1 1 1 1
module full_subtractor(full_a,full_b,borrow_in,difference_out, borrow_out); 

input full_a,full_b, borrow_in;
output borrow_out, difference_out;

wire ha1_ha2_difference, ha1_borrow, ha2_borrow;
half_subtractor inst_half_substractor1(.half_a(full_a),.half_b(full_b), .difference(ha1_ha2_difference), .borrow(ha1_borrow));
half_subtractor inst_half_substractor2(.half_a(borrow_in), .half_b(ha1_ha2_difference), .difference(difference_out), .borrow(ha2_borrow));

or(borrow_out, ha1_borrow, ha2_borrow);

endmodule

전감산기의 진리표입니다. 전감산기의 진리표에 따라서 코드를 만들어보았습니다.

전감산기(full-subtractor)

 

 

이를 검증하기위해 테스트벤치를 사용하여 검증을하였습니다.

 

`timescale 1ns/1ns

module tb_full_subtractor;

  // Inputs
  reg full_a;
  reg full_b;
  reg borrow_in;
  
  // Outputs
  wire difference_out;
  wire borrow_out;
  
  full_subtractor inst_full_subtractor (
    .full_a(full_a),
    .full_b(full_b),
    .borrow_in(borrow_in),
    .difference_out(difference_out),
    .borrow_out(borrow_out)
  );
  

  
   initial begin
    
    // Test case 1 - full_a = 0, full_b = 0, borrow_in = 0
    #10;
	full_a = 0;
	full_b= 0;
    borrow_in = 0;
	#10;
	full_a = 0;
	full_b = 0;
    borrow_in = 1;
	#10;
	full_a = 0;
	full_b = 1;

    borrow_in = 0;
	#10;
	full_a = 0;
	full_b = 1;
    borrow_in = 1;
	#10;
	full_a = 1;
	full_b = 0;
    borrow_in = 0;
	#10;
	full_a = 1;
	full_b = 0;
    borrow_in = 1;
	#10;
	full_a = 1;
	full_b = 1;
    borrow_in = 0;
	#10;
	full_a = 1;
	full_b = 1;
    borrow_in = 1;
	end
	endmodule

테스트 벤치 코드를 이용하여 검증을 진행하였습니다.

 

예시를 하나들어 설명하면 A가 1이고 B가 0이게되면 borrow in이 1이되게되고 borrow out이 1이나오게됩니다. 진리표와 동일한것으로보아 회로가 잘 완성되었다는 것을 알 수 있습니다.

 

 

 

이를이용해 전감산기 4개를 만들어보았습니다.

 

module full_subtractor_4bit(a_4bit, b_4bit, borrow_in_4bit, borrow_out_4bit, difference_out);
		input [3:0]a_4bit , b_4bit;
		input borrow_in_4bit;
		output borrow_out_4bit;
		output [3:0]difference_out;
		wire b_h0_h1,  b_h1_h2, b_h2_h3;
			
			full_subtractor inst_full_subtractor0(
			.full_a(a_4bit[0]),
			.full_b(b_4bit[0]), 
			.borrow_in(borrow_in_4bit), 
			.difference_out(difference_out[0]), 
			.borrow_out(b_h0_h1)); 
			
			full_subtractor inst_full_subtractor1(
			.full_a(a_4bit[1]),
			.full_b(b_4bit[1]), 
			.borrow_in(b_h0_h1), 
			.difference_out(difference_out[1]), 
			.borrow_out(b_h1_h2)); 
			
			full_subtractor inst_full_subtractor2(
			.full_a(a_4bit[2]),
			.full_b(b_4bit[2]), 
			.borrow_in(b_h1_h2), 
			.difference_out(difference_out[2]), 
			.borrow_out(b_h2_h3)); 
			
			full_subtractor inst_full_subtractor3(
			.full_a(a_4bit[3]),
			.full_b(b_4bit[3]), 
			.borrow_in(b_h2_h3), 
			.difference_out(difference_out[3]), 
			.borrow_out(borrow_out_4bit)); 
endmodule

위는 4비트 전감산기를 만드는 코드입니다.

 

 

4비트 전감산기

지난게시물의 반감산기에 이어 전감산기를 만들어보았습니다.

 

다음내용은 다음에