나의 전자 공부방/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을 사용하여 반감산기를 만듭니다.

| 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
전감산기의 진리표입니다. 전감산기의 진리표에 따라서 코드를 만들어보았습니다.

이를 검증하기위해 테스트벤치를 사용하여 검증을하였습니다.
`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비트 전감산기를 만드는 코드입니다.

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