나의 전자 공부방/Verilog 공부

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

나만의생각 2023. 5. 8. 15:49

 

일단 감산기를 만들기전에 컴퓨터는 뺄셈을 하기위해 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비트 전감산기

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

 

다음내용은 다음에