반응형
  • 숨쉬는 공부방
    • Security
      • SHA
    • Hardware Security
    • Verilog HDL
    • ─── ✿ ───
      • IT
      • 이것저것

블로그 메뉴

  • 홈
  • 모든 글
  • 방명록

인기 글

최근 글

태그

  • FSM
  • SHA256
  • SHA-256
  • 조합회로
  • Verilog
  • 순차회로
  • 설계
  • C코드
  • Modelsim
  • KISA

hELLO · Designed By 정상우.
숨.

후하후하

[조합회로] 4비트 전가산기 설계하기
Verilog HDL

[조합회로] 4비트 전가산기 설계하기

2021. 7. 28. 14:49

4비트 전가산기란?

Full Adder(FA): 덧셈을 수행하는 데 있어서 캐리(자리 올림수) 입력을 가진 가산기
                                4-bit의 입력 2개를 더하는 것 외에 c_in이라는 자리 올림수도 같이 더해야 한다.

 

※ 덧셈 연산이 느려지는 원인

자릿수마다 자리올림수가 계산되어야지만 다음 자릿수 덧셈을 할 수 있기 때문
즉, 자리올림수를 미리 알 수 있다면 덧셈의 계산속도 빠르게 할 수 있다.

 

 

자리올림수 예측 가산기란?

Carry Look-ahead Adder(CLA): 자리올림을 위해 이전 결괏값을 기다리지 않음

                                                               자리올림을 예측하기 위해 Propagation와 Generation 함수 사용

 

 

$P\left ( A,B \right )= A\oplus B$  (XOR 연산)

-> 이전의 결괏값과 상관없이 자리올림이 발생하는지 여부

-> 캐리(carry) 상관없이 sum 출력

    (출력으로 전파된다) (값이 0 또는 1의 값을 갖는 것) 

 

$G\left ( A,B \right )= A\cdot B$  (AND 연산)

-> 이전의 결괏값에 따라 자리올림이 발생할 가능성이 있는지 여부

-> 캐리(carry) 생성 (c_out 출력)

    (c_out과 관련됨. 자리올림수가 무조건적으로 발생)

 

 

생성된 P와 G는 S와 C를 계산할 때 쓰인다.

$S_{i}=P_{i}\oplus C_{i}$
$C_{i+1}=G_{i}+(P_{i}\cdot C_{i})$

 

자리올림수 3번째 자리에서 C는 다음과 같다.

$C_{3}=G_{2}+(P_{2}\cdot C_{2})$

 

자리올림수 2번째 자리를 기다리지 않고 진행하기 위해서는 다음과 같이 풀어쓴다.

$C_{3}=G_{2}+(P_{2}\cdot (G_{2}+(P_{1}\cdot C_{1})))$

 


자리올림수를 순서대로 진행한다면 아래 그림과 같이 진행된다.

(자리올림 C1~C4의 경우를 슬라이드 형식으로 첨부해놨습니다.)

0123

 


데이터플로우 기술방법으로 가산기를 설계할 것이다. (wire, assign 사용)

testbench 파일은 따로 만들지 않고, rtl 파일만 만들었다.

 


- 입력: a(4비트), b(4비트), c_in(1비트)
- 출력: c_out(1비트), sum(4비트)

 


* TestBench

module tb_adder;

    reg 	[3:0] 	A, B;
    reg 		C_IN;
    wire 	[3:0] 	SUM;
    wire 		C_OUT;

    adder ADD1_4(C_OUT, SUM, A, B, C_IN);

    initial
    begin
        $monitor($time, " A= %b, B= %b, C_IN= %b, --- C_OUT= %b, SUM= %b\n", A, B, C_IN, C_OUT, SUM);
    end 

    initial
    begin
        A = 4'd0; B = 4'd0; C_IN = 1'b0;
        #5 A = 4'd3; B = 4'd4;
        #5 A = 4'd2; B = 4'd5;
        #5 A = 4'd9; B = 4'd9;
        #5 A = 4'd10; B = 4'd15;
        #5 A = 4'd10; B = 4'd5; C_IN = 1'b1;
    end
$monitor();

시뮬레이션 결과를 보기 쉽게 모니터로 출력하였다.

$monitor는 신호의 값이 변할 때마다 출력한다.

반면 $diplay는 c언어의 printf 함수와 같이 한 번만 출력한다.

 

 

* RTL: Full Adder(FA)

module adder ( c_out, sum, a, b, c_in);
	input 	[3:0] 	a, b; 	// 4비트 벡터 표현
	input		c_in;	// 1비트 스칼라 표현
	output 	c_out;
	output [3:0]	sum;
	
	wire		c_out;
	wire	[3:0] 	sum;

	assign {c_out, sum} = a + b + c_in;

endmodule
assign {c_out, sum} = a + b + c_in;

입력 a와 b, c_in을 더하여 c_out과 sum에 입력한다.

덧셈의 결과, 자리올림(carry)이 발생하면 c_out 값 발생

 

 

* RTL: Carry Look-ahead Adder(CLA)

module adder ( c_out, sum, a, b, c_in );
	input	[3:0]	a, b;
	input		c_in;
	output		c_out;
	output	[3:0]	sum;
    
	wire		c_out;
	wire	[3:0] 	sum;

	// 내부 wire 신호 추가 선언
	wire	p0,g0, p1,g1, p2,g2, p3,g3;
	wire	c4, c3, c2, c1;

	// propagation
	assign	p0 = a[0] ^ b[0];	// xor
	assign	p1 = a[1] ^ b[1];
	assign	p2 = a[2] ^ b[2];
	assign	p3 = a[3] ^ b[3];
	// generation
	assign	g0 = a[0] & b[0];	// and 
	assign	g1 = a[1] & b[1];
	assign	g2 = a[2] & b[2];
	assign	g3 = a[3] & b[3];

	// 첫번째 무조건적인 캐리: g#
	// 두번째 sum의 결과인 p1와 뒤에서 올라온 캐리값 g0
	// 세번째 현재결과와 입력 자리올림수와의 캐리연산 &
	assign	c1 = g0 | (p0 & c_in);
	assign	c2 = g1 | (p1 & g0) | ( p1 & p0 & c_in);
	assign	c3 = g2 | (p2 & g1) | (p2 & p1 & g0) | (p2 & p1 & p0 & c_in);
	assign	c4 = g3 | (p3 & g2) | (p3 & p2 & g1) | (p3 & p2 & p1 & g0) | (p3 & p2 & p1 & p0 & c_in);


	assign	sum[0] = p0 ^ c_in;
	assign	sum[1] = p1 ^ c1;
	assign	sum[2] = p2 ^ c2;
	assign	sum[3] = p3 ^ c3;

	assign	c_out = c4;

endmodule

 

 

각각의 자리올림수 값을 풀어서 쓰면 다음과 같다.

	assign	c1 = g0 | (p0 & c_in);
	///////////////////////////////////////////////////////////////
	assign	c2 = g1 | (p1 & g0) | ( p1 & p0 & c_in);
	assign	c2 = g1 | p1 & ( g0 | (p0 & c_in) );
	assign	c2 = g1 | p1 & c1;
	///////////////////////////////////////////////////////////////
	assign	c3 = g2 | (p2 & g1) | (p2 & p1 & g0) | (p2 & p1 & p0 & c_in);
	assign	c3 = g2 | p2 & ( g1 | (p1 & g0) | (p1 & p0 & c_in) );
	assign	c3 = g2 | p2 & c2
	///////////////////////////////////////////////////////////////
	assign	c4 = g3 | (p3 & g2) | (p3 & p2 & g1) | (p3 & p2 & p1 & g0) | (p3 & p2 & p1 & p0 & c_in);
	assign	c4 = g3 | p3 & ( g2 | (p2 & g1) | (p2 & p1 & g0) | (p2 & p1 & p0 & c_in) );
	assign	c4 = g3 | p3 & c3

 


실행 결과

$monitor 출력 화면

 

A, B, C_IN을 이진수로 덧셈 연산하면 {C_OUT, SUM}이 출력된다.

        // tb_adder.v 코드의 일부분
        A = 4'd0; B = 4'd0; C_IN = 1'b0;
        #5 A = 4'd3; B = 4'd4;
        #5 A = 4'd2; B = 4'd5;
        #5 A = 4'd9; B = 4'd9;
        #5 A = 4'd10; B = 4'd15;
        #5 A = 4'd10; B = 4'd5; C_IN = 1'b1;

  0  -- 모두 다 0

  5  -- A = 3(0011), B = 4(0100), C_IN=0    --> C_OUT = 0, SUM = 7(0111)    {0_0111}

10 -- A = 2(0010), B = 5(0101), C_IN=0     --> C_OUT = 0, SUM = 7(0111)   {0_0111}

15 -- A = 9(1001), B = 9(1001), C_IN=0     --> C_OUT = 1, SUM = 18(0010) {1_0010}

20 -- A = 10(1010), B = 15(1111), C_IN=0 --> C_OUT = 1, SUM = 25(1001) {1_1001}

25 -- A = 10(1010), B = 5(0101), C_IN=1   --> C_OUT = 1, SUM = 15(0000) {1_0000}

 

 


- 참고 -

Verilog HDL 디지털 설계와 합성의 길잡이 (한국어판)

저작자표시 비영리 변경금지 (새창열림)

'Verilog HDL' 카테고리의 다른 글

[순차회로] 교통 신호 제어기 설계하기  (0) 2021.08.24
순차회로와 FSM  (0) 2021.08.23
[조합회로] 4:1 멀티플렉서 설계하기  (0) 2021.07.28
[ModelSim] Verilog 조합회로 설계 방법  (0) 2021.07.28
[ModelSim] 컴파일 및 시뮬레이션 자동화 방법  (0) 2021.07.27
    'Verilog HDL' 카테고리의 다른 글
    • [순차회로] 교통 신호 제어기 설계하기
    • 순차회로와 FSM
    • [조합회로] 4:1 멀티플렉서 설계하기
    • [ModelSim] Verilog 조합회로 설계 방법
    숨.
    숨.

    티스토리툴바