Computer/Computer Structure

Arithmetic Logic Unit(ALU)

고양이는생선을좋아해 2013. 5. 9. 17:04

 

# Arithmetic Logic Unit(산술 논리 장치)는 두 숫자의 산술연산과 논리 연산 등을 계산하는 디지털 회로이다.

 

opcode에 따라 다른 연산을 수행한다.

 

 8 가지 연산의 결과를 8 to 1 Multiplexer을 통해 한가지 결과만 출력한다.

 

module alu4(a,b,op,result,c,n,z,v);  
input [3:0] a,b;    input [2:0] op;    
output [3:0] result;   
output  c,n,z,v;   

wire [3:0] w_not_a,w_not_b,w_and,w_or,w_xor,w_xnor,w_add,w_sub;  
wire c3_add,co_add,c3_sub,co_sub;       


_inv_4bits U0_inv1(.a(a),.y(w_not_a));     

_inv_4bits U1_inv2(.a(b),.y(w_not_b));    

_and2_4bits U2_and2(.a(a),.b(b),.y(w_and));   
_or2_4bits  U3_or2(.a(a),.b(b),.y(w_or));    
_xor2_4bits U4_xor2(.a(a),.b(b),.y(w_xor));   

_xnor2_4bits U5_xnor2(.a(a),.b(b),.y(w_xnor));  
cla4_ov U6_add(.a(a),.b(b),.ci(1'b0),.s(w_add),.c3(c3_add),.co(co_add));

cla4_ov U7_sub(.a(a),.b(~b),.ci(1'b1),.s(w_sub),.c3(c3_sub),.co(co_sub)); 
mx8_4bits U8_mx8(.a(w_not_a),.b(w_not_b),.c(w_and),.d(w_or),.e(w_xor),.f(w_xnor),.g(w_add),.h(w_sub),.s2(op[2]),.s1(op[1]),.s0(op[0]),.y(result));

cal_flags4 U9_cal_flag4(.op(op),.result(result),.co_add(co_add),.c3_add(c3_add),.co_sub(co_sub),.c3_sub(c3_sub),.c(c),.n(n),.z(z),.v(v));


endmodule

 

 

 

#How operate subtraction

 

대부분의 digital system에서 subtraction을 하기 위해서는 2의 보수를 취해 더하게 된다.

2의 보수를 구하는 방법은 해당 입력을 invert 한 후 1을 더하면 된다.

 

        (add)                                                                                (sub)

 

 

또한 ALU에는 Calculate Flag Module이 존재한다.

ALU내에서 특정 조건이나 상황이 만족되었을 때, 이를 표시해주는 것을 Flag라 한다.

 

C : Carry - 연산결과 Carry가 발생하는 경우

N : Negative - 연산결과의 sign bit가 1인 경우

Z : Zero - 연산결과가 0 인경우

V : Overflow - 연산결과가 Overflow가 발생한 경우(Overflow는 결과가 표현가능한 최대정수를 넘어간 경우)

 

이러한 Flag들은 비교연산을 하는데 사용 될 수 있다.

module cal_flags4(op,result,co_add,c3_add,co_sub,c3_sub,c,n,z,v);  

input [2:0] op;  
input [3:0] result; 
input co_add,c3_add,co_sub,c3_sub;

output c,n,z,v;        

 

assign c=(op[2:1]!=2'b11) ? 1'b0 : ((op[0]==1'b0) ? co_add:co_sub); 

assign n=result[3];    

assign z=(result==4'b0) ? 1 : 0;  

assign v=(op[2:1] != 2'b11) ? 1'b0 : ((op[0]==1'b0) ? (co_add^c3_add) : (co_sub^c3_sub)); 

                            

endmodule

 

#Carry와 Overflow의 차이점

Carry는 연산도중에 그것을 초과할 경우 Carry가 발생한 것을 보여주기 위한 flag

Overflow는 2의 보수 표현의 정수 연산에서 부호비트가 변한것을 보여주기 위한 flag
에를 들면

* Overflow bit를 set하는 상황 : 

최상위비트가 동일한 두수를 더했는데 최상위비트가 바뀌었을때

* Carry bit를 set하는 상황 :

1바이트의 두 값을 더했는데 1바이트 이상의 값이 나왔을때