Verilog 2장 - CLA

2019. 12. 15. 02:51Programming/Verilog

Verilog를 공부하는 과정에 배운것을 정리한 것으로 틀린부분이 있을 수 있음을 알립니다.


CLA란?

CLA(Carry Look-ahead Adder)의 줄임말로 1장에서 보았던 RCA와 동일한 기능의 덧셈기이다. RCA보다 계산 결과를 빠르게 알 수 있는 덧셈기로 연산성능을 높일 수 있다.

CLA의 구성요소

CLA는 RCA와 CLB(Carry Look-ahead Block)으로 구성되어있다. 4-bit CLA의 예시에서 보면 4-bit RCA와 CLB로 구성되어있는 것을 확인가능하다. 각각 Full Adder의 Carry입력이 CLB로부터 오는 것과 각각 Full Adder에서 P와 G가 CLB로 들어가는 것을 볼 수 있다. 아래에서 Carry-in을 계산하는 방법과 P, G가 어떤 값을 가지는지 알아보겠다.


Carry-in

오른쪽 첫번째 Full Adder부터 Carry-in은 C0, C1, C2...로 정의하고 다음과 같은 값을 가진다. C1 = G0 + P1C0, C2 = G1 + P2C1...으로 나타낼 수 있다. 여기서 P와 G는 Full Adder에서 CLB로 들어오는 입력이고 다음과 같은 값을 가진다.

G(Generate), P(Propagate)

G와 P는 CLA가 RCA보다 빠른 속도의 계산을 가능하게 해주는 주요한 요소이다. Full Adder에 A와 B의 값이 들어오면 바로 P와 G가 계산되어 CLB로 전달이 된다. CLB는 전달받은 P와 G의 값으로 다음 Full Adder에게 전해줄 Carry-in을 미리 계산한 후 전달한다. 이 과정에서 RCA보다 빠른 속도의 연산이 가능하게된다.

G = AB, P = A+ B로 계산되며 4-bit CLA의 마지막 Carry-out의 값은 다음과 같이 계산된다.

Cout = G3 + P4C3 = A3B3 + (A4 + B4)C3


Verilog Code

 

4-bit CLA
module cla4(a, b, ci, s, co);
	input [3:0] a, b;
	input ci;
	output [3:0] s;
	output co;
	
	wire c1, c2, c3;
	
	fa_v2 U0_fa(.a(a[0]), .b(b[0]), .ci(ci), .s(s[0]));								
	fa_v2 U1_fa(.a(a[1]), .b(b[1]), .ci(c1), .s(s[1]));								
	fa_v2 U2_fa(.a(a[2]), .b(b[2]), .ci(c2), .s(s[2]));								
	fa_v2 U3_fa(.a(a[3]), .b(b[3]), .ci(c3), .s(s[3]));								
	clb4	U4_clb4(.a(a), .b(b), .ci(ci), .c1(c1), .c2(c2), .c3(c3), .co(co));	
endmodule

CLA RTL Viewer

4-bit CLB
module clb4(a, b, ci, c1, c2, c3, co);
	input [3:0]a, b;
	input ci;
	output c1, c2, c3 ,co;
	wire[3:0]g, p;
	wire w0_c1;
	wire w0_c2, w1_c2;
	wire w0_c3, w1_c3, w2_c3;
	wire w0_co, w1_co, w2_co, w3_co;
	
	//Genarate
	_and2 U0_and2(.a(a[0]), .b(b[0]), .y(g[0]));
	_and2 U1_and2(.a(a[1]), .b(b[1]), .y(g[1]));
	_and2 U2_and2(.a(a[2]), .b(b[2]), .y(g[2]));
	_and2 U3_and2(.a(a[3]), .b(b[3]), .y(g[3]));
	
	//Propagate
	_or2 U4_or2(.a(a[0]), .b(b[0]), .y(p[0]));
	_or2 U5_or2(.a(a[1]), .b(b[1]), .y(p[1]));
	_or2 U6_or2(.a(a[2]), .b(b[2]), .y(p[2]));
	_or2 U7_or2(.a(a[3]), .b(b[3]), .y(p[3]));

	// c1 = g[0] | (p[0] & ci);
	_and2 U8_and2(.a(p[0]), .b(ci), .y(w0_c1));
	_or2 U9_or2(.a(g[0]), .b(w0_c1), .y(c1));
	
	// c2 = g[1] | (p[1] & g[0]) | (p[1] & p[0] & ci);
	_and3 U10_and3(.a(p[1]), .b(p[0]), .c(ci), .y(w0_c2));
	_and2 U11_and2(.a(p[1]), .b(g[0]), .y(w1_c2));
	_or3	U12_or3(.a(g[1]), .b(w0_c2), .c(w1_c2), .y(c2));
	
	// c3 = g[2] | (p[2] & g[1]) | (p[2] & p[1] & g[0]) | (p[2] & p[1] & p[0] & ci);
	_and4 U13_and4(.a(p[2]), .b(p[1]), .c(p[0]), .d(ci), .y(w0_c3));
	_and3	U14_and3(.a(p[2]), .b(p[1]), .c(g[0]), .y(w1_c3));
	_and2	U15_and2(.a(p[2]), .b(g[1]), .y(w2_c3));
	_or4	U16_or4(.a(g[2]), .b(w0_c3), .c(w1_c3), .d(w2_c3), .y(c3));
	
	// co = g[3]
	// | (p[3] & g[2])
	// | (p[3] & p[2] & g[1])
	// | (p[3] & p[2] & p[1] & g[0])
	// | (p[3] & p[2] & p[1] & p[0] & ci)
	_and5	U17_and5(.a(p[3]), .b(p[2]), .c(p[1]), .d(p[0]), .e(ci), .y(w0_co));
	_and4	U18_and4(.a(p[3]), .b(p[2]), .c(p[1]), .d(g[0]), .y(w1_co));
	_and3	U19_and3(.a(p[3]), .b(p[2]), .c(g[1]), .y(w2_co));
	_and2	U20_and2(.a(p[3]), .b(g[2]), .y(w3_co));
	_or5	U21_or5(.a(g[3]), .b(w0_co), .c(w1_co), .d(w2_co), .e(w3_co), .y(co));
endmodule
	

 

'Programming > Verilog' 카테고리의 다른 글

Verilog 1장 - 4bit RCA  (0) 2019.09.19