이번시간에는 RCA라는 가산기를 설계할것이지만, 가산기를 설계하기전에는 기본지식이 필요합니다.
전가산기(full adder)와 반가산기(half adder), 2의보수가 있습니다.
2의보수
보수 : 두 수의 합이 진법의 밑수(N)가 되게 하는 수(ex : 10진수 5의 10의보수는 5)
2의보수 : 어떤 수를 커다란 2의 제곱수에서 빼서 얻은 이진수입니다.
보수는 컴퓨터에서 음의정수를 표현하기 위해 만들어졌습니다.
컴퓨터 내부에서는 덧셈을 담당하는 가산기만을 사용하기 때문에 A – B 가아닌 A+(-B)로 계산을 시켜야합니다.
그러면 2의보수를 사용하지않고 4bit 짜리에서 MSB를 부호비트로 주고 사용해도 된다고 생각하기 쉽지만, 그렇게되면 0이 양수와 음수의 부호비트를 가지기때문에 2의보수를 사용해야합니다.
2의보수로 변환하는 법은 양수에서 음수로 변환할때는 모든 bit를 반전시킨 후, 1을 더하면 변환이됩니다.
음수에서 양수로 변환할때는 모든 bit를 반전시킨 후, 1을 빼면 변환이됩니다.
A-B를 A+(-B)로 바꿔서 예시를 들어 설명하자면, A=6, B=6이라고 하면, B를 2의보수로 변환해서 -B=-6이되고 A=0110, -B=1010이 된다. 0110 +1010 10000 의 결과값을 가지고, 크기가 4bit이기때문에 자리올림은 버려지게 됩니다.
반가산기(half adder)
반가산기는 이진수의 한자리 수를 연산하고, 자리올림수는 자리올림수 출력(carry out)에 따라 출력한다. AND, OR, NOT의 세 가지 종류의 논리회로만으로 구성할 수 있습니다.
전가산기(full adder)
이진수의 한 자릿수를 연산하고, 하위의 자리올림수 입력을 포함하여 출력합니다. 하위의 자리올림수 출력을 상위의 자리올림수 입력에 연결함으로써 임의의 자리수의 이진수 덧셈이 가능해집니다. 하나의 전가산기는 두개의 반가산기와 하나의 OR로 구성됩니다.
Ripple-Carry Adder(RCA)
각각의 전가산기가 자리올림수 입력 Cin으로 직전의 자리올림수 출력 Cout을 받는 형식으로, 자리올림수가 물결(ripple)치듯 다음 가산기로 옮겨가는 가산기 RCA의 구성은 전가산기로 이루어져있습니다. 그래서 full-adder의 갯수만큼 시간이 소비되어 연산속도가 느립니다.
이러한 이론을 정리를 했고, 다음은 설계방법입니다.
먼저 반가산기-> 전가산기 -> RCA 순으로 설계하기위해, 핵심인 XOR게이트를 설계해야 합니다. XOR의 논리식은 Y=A`B+AB`이므로 NOT게이트를 2번, AND게이트를 2번, OR게이 트를 사용해야합니다. 그 후, 반가산기를 먼저 설계해야합니다(필수는 아님). 반가산기는 2-input-xor과 2-input-and를 사용하여 a와 b가 하나만 1인경우 s는 1이되고, 둘 다 1인 경우 cout이 1이되어 다음 비트에 1을 줄 수 있게 됩니다. 전가산기는 반가산기를 인스턴 스하여서 반가산기에서 보낸 cout을 받아 cin끼리 OR을 시켜줍니다. 4bit RCA는 전가산기 를 bit의 수에 맞게 4번 인스턴스하면 완성이 됩니다.
그렇게 인스턴스를 해서 코드를 짜면
module rca4(a,b,ci,s,co);//4bit-rca
input [3:0] a,b;//4bit input data
input ci; //carry in
output [3:0] s; //4bit sum
output co;//carry out
wire [2:0] c;//3bit carry wire
fa U0_fa(.a(a[0]), .b(b[0]), .ci(ci), .s(s[0]), .co(c[0]));//fa instance
fa U1_fa(.a(a[1]), .b(b[1]), .ci(c[0]), .s(s[1]), .co(c[1]));//fa instance
fa U2_fa(.a(a[2]), .b(b[2]), .ci(c[1]), .s(s[2]), .co(c[2]));//fa instance
fa U3_fa(.a(a[3]), .b(b[3]), .ci(c[2]), .s(s[3]), .co(co));//fa instance
endmodule
module fa(a,b,ci,s,co);//full adder
input a,b,ci;//input data a, input data b, carry in
output s, co;//sum, carry out
wire c1,c2,sm;//ha adder carry, half adder sum
ha U0_ha(.a(b), .b(ci), .s(sm), .co(c1));//instance ha
ha U1_ha(.a(a), .b(sm), .s(s), .co(c2));//instance ha
_or2 U2_or2(.a(c1), .b(c2), .y(co));//instance 2-input-or
endmodule
module ha(a, b, s, co);//half adder
input a, b;//input data
output s, co;//sum and carry out
_xor2 U0_xor2(.a(a), .b(b), .y(s));//s=a^b instance 2-input-xor
_and2 U1_and2(.a(a), .b(b), .y(co));//co=a&b instance 2-input-and
endmodule
이런식으로 나오고, 가벼운 값을 testbench로 하면 아래와 같은 waveform을 볼 수 있습니다.
위에서 카르노맵을 통해 부울식을 구했던것이 핵심이었던 실험이었습니다.
2학년 1학기때 직접 회로를 설계하면서 코드로 어떻게 짜나 궁금했었지만, 이렇게 2학기때 코드를 짜보면서 값이 예상했던 값과 같이 나올때 정말 신기했습니다.
RCA의 단점인 전부다 전가산기인점을 보완하기위해 CLA(Carry look ahead)가 있는데, 다음 글에 작성하겠습니다.
참고문헌입니다.
https://ndb796.tistory.com/4 https://ko.wikipedia.org/wiki/2%EC%9D%98_%EB%B3%B4%EC%88%98 https://ko.wikipedia.org/wiki/%EA%B0%80%EC%82%B0%EA%B8%B0 컴퓨터공학기초실험2 week3 자료
D-FlipFlop (0) | 2022.06.22 |
---|---|
ALU(Arithmetic Logic Unit) (0) | 2022.01.17 |
blocking 과 non-blocking assignment의 차이 (0) | 2022.01.06 |
CLA(carry-look-ahead) (0) | 2022.01.05 |
2-to-1 multiplexer 구현하기 (0) | 2022.01.03 |
댓글 영역