2023. 1. 29. 17:08ㆍ기록지/컴퓨터구조(computer architecture)
4. Substractor, Arithmetic Logic Unit 구현
원리
Substractor
대부분의 digital system에서 subtraction을 위하여 감수 (subtrand)를 two’s complement number(2의 보수)를 취해 더하게 된다. 2의 보수를 구하는 방법은 해당 입력을 invert한 후, 1을 더해주면 된다.
A – B = A + (-B)
.
Arithmetic logic unit
ALU(산술 논리 장치)는 두 숫자의 산술연산과 논리연산을 계산하는 디지털 회로이다.
Flag
ALU 내에서 특정 조건이나 상황이 만족되었을 때, 이를 표시해주는 것을 flag라 한다. 여기에서는 carry, negative, zero, overflow 4개의 flag를 갖는다.
C: Carry = 연산 결과 carry가 발생하는 경우
N: Negative = 연산 결과의 sign bit가 1인 경우
Z: Zero = 연산 결과가 0인 경우
V: Overflow = 연산 결과 overflow가 발생하는 경우
설계 검증
Top level entity name: alu4
Device family: Cyclone II EP2C70F896C6
총 logic elements 42개 (1%이하)
총 pin 19개 (3%)
Input combination: a=0000, b=0000, op=000 Output: result=1111
Carry는 없고 MSB가 1이므로 negative이고 zero가 아니며 overflow는 발생하지 않았다.
Op=000이므로 결과는 not a인 1111이 나옴
Input combination: a=1100, b=0000, op=000 Output: result=0011
Carry는 없고 MSB가 0이므로 negative, zero가 아니며 overflow는 발생하지 않았다.
Op=000이므로 결과는 not a인 0011이 나옴
Input combination: a=1100, b=0011, op=001 Output: result=1100
Carry는 없고 MSB가 1이므로 negative이고 zero가 아니며 overflow는 발생하지 않았다.
Op=001이므로 결과는 not b인 1100이 나옴
Input combination: a=0101, b=1001, op=010 Output: result=0001
Carry는 없고 MSB가 0이므로 negative, zero가 아니며 overflow는 발생하지 않았다.
Op=010이므로 결과는 a and b인 0001이 나옴
Input combination: a=0101, b=1010, op=011 Output: result=1111
Carry는 없고 MSB가 1이므로 negative이고 zero가 아니며 overflow는 발생하지 않았다.
Op=011이므로 결과는 a or b인 1111이 나옴
Input combination: a=0011, b=0101, op=100 Output: result=0110
Carry는 없고 MSB가 0이므로 negative, zero가 아니며 overflow는 발생하지 않았다.
Op=100이므로 결과는 a exclusive or b인 0110이 나옴
Input combination: a=0011, b=0101, op=101 Output: result=1001
Carry는 없고 MSB가 1이므로 negative이고 zero가 아니며 overflow는 발생하지 않았다.
Op=101이므로 결과는 a exclusive nor b인 1001이 나옴
이것은 ALU동작과 일치하는 결과가 나왔으므로 위의 input combination은 정상 동작하는 것을 확인할 수 있다.
Top level entity name: alu32
Device family: Cyclone II EP2C70F896C6
총 logic elements 366개 (1%이하)
총 pin 103개 (17%)
module _inv(a,y);
input a;
output y;
assign y=~a;
endmodule
module _nand2(a,b,y);
input a,b;
output y;
assign y=~(a&b);
endmodule
module _and2(a,b,y);
input a,b;
output y;
assign y=a&b;
endmodule
module _or2(a,b,y);
input a,b;
output y;
assign y=a|b;
endmodule
module _xor2(a,b,y);
input a,b;
output y;
wire w1,w2,w3,w4;
_inv _inv0(.a(a),.y(w1));
_inv _inv1(.a(b),.y(w2));
_and2 _and0(.a(a),.b(w2),.y(w3));
_and2 _and1(.a(b),.b(w1),.y(w4));
_or2 _or0(.a(w3),.b(w4),.y(y));
endmodule
module _and3(a,b,c,y);
input a,b,c;
output y;
assign y=a&b&c;
endmodule
module _and4(a,b,c,d,y);
input a,b,c,d;
output y;
assign y=a&b&c&d;
endmodule
module _and5(a,b,c,d,e,y);
input a,b,c,d,e;
output y;
assign y=a&b&c&d&e;
endmodule
module _or3(a,b,c,y);
input a,b,c;
output y;
assign y=a|b|c;
endmodule
module _or4(a,b,c,d,y);
input a,b,c,d;
output y;
assign y=a|b|c|d;
endmodule
module _or5(a,b,c,d,e,y);
input a,b,c,d,e;
output y;
assign y=a|b|c|d|e;
endmodule
//4 bits inverter
module _inv_4bits(a,y);
input [3:0] a;
output [3:0] y;
assign y=~a;
endmodule
//4 bits 2-to-1 and gate
module _and2_4bits(a,b,y);
input [3:0] a,b;
output [3:0] y;
assign y=a&b;
endmodule
//4 bits 2-to-1 or gate
module _or2_4bits(a,b,y);
input [3:0] a,b;
output [3:0] y;
assign y=a|b;
endmodule
//4 bits 2-to-1 exclusive or gate
module _xor2_4bits(a,b,y);
input [3:0] a,b;
output [3:0] y;
_xor2 U0_xor2(.a(a[0]), .b(b[0]), .y(y[0]));
_xor2 U1_xor2(.a(a[1]), .b(b[1]), .y(y[1]));
_xor2 U2_xor2(.a(a[2]), .b(b[2]), .y(y[2]));
_xor2 U3_xor2(.a(a[3]), .b(b[3]), .y(y[3]));
endmodule
//4 bits 2-to-1 exclusive nor gate
module _xnor2_4bits(a,b,y);
input [3:0] a,b;
output [3:0] y;
wire [3:0] w0;
_xor2_4bits U0_xor2_4bits(.a(a), .b(b), .y(w0));
_inv_4bits U1_inv_4bits(.a(w0), .y(y));
endmodule
//32 bits inverter
module _inv_32bits(a,y);
input [31:0] a;
output [31:0] y;
assign y=~a;
endmodule
//32 bits 2-to-1 and gate
module _and2_32bits(a,b,y);
input [31:0] a,b;
output [31:0] y;
assign y=a&b;
endmodule
//32 bits 2-to-1 or gate
module _or2_32bits(a,b,y);
input [31:0] a,b;
output [31:0] y;
assign y=a|b;
endmodule
//32 bits exclusive or gate
module _xor2_32bits(a,b,y);
input [31:0] a,b;
output [31:0] y;
_xor2_4bits U0_xor2_4bits(.a(a[3:0]), .b(b[3:0]), .y(y[3:0]));
_xor2_4bits U1_xor2_4bits(.a(a[7:4]), .b(b[7:4]), .y(y[7:4]));
_xor2_4bits U2_xor2_4bits(.a(a[11:8]), .b(b[11:8]), .y(y[11:8]));
_xor2_4bits U3_xor2_4bits(.a(a[15:12]), .b(b[15:12]), .y(y[15:12]));
_xor2_4bits U4_xor2_4bits(.a(a[19:16]), .b(b[19:16]), .y(y[19:16]));
_xor2_4bits U5_xor2_4bits(.a(a[23:20]), .b(b[23:20]), .y(y[23:20]));
_xor2_4bits U6_xor2_4bits(.a(a[27:24]), .b(b[27:24]), .y(y[27:24]));
_xor2_4bits U7_xor2_4bits(.a(a[31:28]), .b(b[31:28]), .y(y[31:28]));
endmodule
//32 bits exclusive nor gate
module _xnor2_32bits(a,b,y);
input [31:0] a,b;
output [31:0] y;
_xnor2_4bits U0_xnor2_4bits(.a(a[3:0]), .b(b[3:0]), .y(y[3:0]));
_xnor2_4bits U1_xnor2_4bits(.a(a[7:4]), .b(b[7:4]), .y(y[7:4]));
_xnor2_4bits U2_xnor2_4bits(.a(a[11:8]), .b(b[11:8]), .y(y[11:8]));
_xnor2_4bits U3_xnor2_4bits(.a(a[15:12]), .b(b[15:12]), .y(y[15:12]));
_xnor2_4bits U4_xnor2_4bits(.a(a[19:16]), .b(b[19:16]), .y(y[19:16]));
_xnor2_4bits U5_xnor2_4bits(.a(a[23:20]), .b(b[23:20]), .y(y[23:20]));
_xnor2_4bits U6_xnor2_4bits(.a(a[27:24]), .b(b[27:24]), .y(y[27:24]));
_xnor2_4bits U7_xnor2_4bits(.a(a[31:28]), .b(b[31:28]), .y(y[31:28]));
endmodule
module alu32(a,b,op,result,c,n,z,v);
input [31:0] a,b;
input [2:0] op;
output [31:0] result;
output c,n,z,v;
wire [31:0] w_not_a,w_not_b,w_and,w_or,w_xor,w_xnor,w_add,w_sub;
wire co_prev_add,co_add,co_prev_sub,co_sub;
_inv_32bits U0_inv_32bits (.a(a),.y(w_not_a));
_inv_32bits U1_inv_32bits (.a(b),.y(w_not_b));
_and2_32bits U2_and2_32bits (.a(a),.b(b),.y(w_and));
_or2_32bits U3_or2_32bits (.a(a),.b(b),.y(w_or));
_xor2_32bits U4_xor2_32bits (.a(a),.b(b),.y(w_xor));
_xnor2_32bits U5_xnor2_32bits (.a(a),.b(b),.y(w_xnor));
cla32_ov U6_add (.a(a),.b(b),.ci(1'b0),.s(w_add),.co_prev(co_prev_add),.co(co_add));
cla32_ov U7_sub (.a(a),.b(w_not_b),.ci(1'b1),.s(w_sub),.co_prev(co_prev_sub),.co(co_sub));
mx8_32bits U8_mx8_32bits (.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_flag32 U9_cal_flags32 (.op(op),.result(result),.co_add(co_add),.co_prev_add(co_prev_add),.co_sub(co_sub),.co_prev_sub(co_prev_sub),.c(c),.n(n),.z(z),.v(v));
endmodule
module cal_flag32(op,result,co_add,co_prev_add,co_sub,co_prev_sub,c,n,z,v);
input [2:0] op;
input [31:0] result;
input co_add,co_prev_add, co_sub, co_prev_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[31];
assign z= (result==32'b0) ? 1'b1 : 1'b0;
assign v= (op[2:1] != 2'b11) ? 1'b0 :((op[0]==1'b0)? (co_add^co_prev_add): (co_sub^co_prev_sub));
endmodule
module mx8_32bits(a,b,c,d,e,f,g,h,s2,s1,s0,y);
input [31:0] a,b,c,d,e,f,g,h;
input s2,s1,s0;
output [31:0] y;
wire [31:0] w0,w1,w2,w3,w4,w5;
mx2_32bits U0_mx2_32bits(.d0(a),.d1(b),.s(s0),.y(w0));
mx2_32bits U1_mx2_32bits(.d0(c),.d1(d),.s(s0),.y(w1));
mx2_32bits U2_mx2_32bits(.d0(e),.d1(f),.s(s0),.y(w2));
mx2_32bits U3_mx2_32bits(.d0(g),.d1(h),.s(s0),.y(w3));
mx2_32bits U4_mx2_32bits(.d0(w0),.d1(w1),.s(s1),.y(w4));
mx2_32bits U5_mx2_32bits(.d0(w2),.d1(w3),.s(s1),.y(w5));
mx2_32bits U6_mx2_32bits(.d0(w4),.d1(w5),.s(s2),.y(y));
endmodule
module mx2_32bits(d0,d1,s,y);
input [31:0] d0,d1;
input s;
output [31:0] y;
assign y= (s==1'b0) ? d0 : d1;
endmodule
module cla32_ov(a,b,ci,s,co_prev,co);
input [31:0] a,b;
input ci;
output [31:0] s;
output co_prev;
output co;
wire c1,c2,c3,c4,c5,c6,c7;
cla4 U0_cla4(.a(a[3:0]),.b(b[3:0]),.ci(ci),.s(s[3:0]),.co(c1));
cla4 U1_cla4(.a(a[7:4]),.b(b[7:4]),.ci(c1),.s(s[7:4]),.co(c2));
cla4 U2_cla4(.a(a[11:8]),.b(b[11:8]),.ci(c2),.s(s[11:8]),.co(c3));
cla4 U3_cla4(.a(a[15:12]),.b(b[15:12]),.ci(c3),.s(s[15:12]),.co(c4));
cla4 U4_cla4(.a(a[19:16]),.b(b[19:16]),.ci(c4),.s(s[19:16]),.co(c5));
cla4 U5_cla4(.a(a[23:20]),.b(b[23:20]),.ci(c5),.s(s[23:20]),.co(c6));
cla4 U6_cla4(.a(a[27:24]),.b(b[27:24]),.ci(c6),.s(s[27:24]),.co(c7));
cla4_ov U7_cla4_ov(.a(a[31:28]),.b(b[31:28]),.ci(c7),.s(s[31:28]),.c3(co_prev),.co(co));
endmodule
----------------------------------------------------------
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,c0_add,c3_sub,co_sub;
_inv_4bits U0_inv_4bits (.a(a),.y(w_not_a));
_inv_4bits U1_inv_4bits (.a(b),.y(w_not_b));
_and2_4bits U2_and2_4bits (.a(a),.b(b),.y(w_and));
_or2_4bits U3_or2_4bits (.a(a),.b(b),.y(w_or));
_xor2_4bits U4_xor2_4bits (.a(a),.b(b),.y(w_xor));
_xnor2_4bits U5_xnor2_4bits (.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(w_not_b),.ci(1'b1),.s(w_sub),.c3(c3_sub),.co(co_sub));
mx8_4bits U8_mx8_4bits (.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_flags4 (.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
`timescale 1ns/100ps
module tb_alu4;
reg [3:0] tb_a,tb_b;
reg [2:0] tb_op;
wire [3:0] tb_result;
wire tb_c,tb_n,tb_z,tb_v;
alu4 U0_alu4(.a,.b,.op,.result,.c,.n,.z,.v);
initial
begin
endmodule
module cal_flags4(op,result,co_add, c3_add,co_sub,c3_sub,c,n,z,v);
input [2:0] op;
input [3L0] 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'b1 : 1'b0;
assign v = (op[2:1] != 2'b11) ? 1'b0 : ((op[0]==1'b0) ? (co_add^c3_add) : (co_sub^c3_sub));
endmodule
module mx8_4bits(a,b,c,d,e,f,g,h,s2,s1,s0,y);
input [3:0] a,b,c,d,e,f,g,h;
input s2,s1,s0;
output [3:0] y;
mx8 (.a(a[0]),.b(b[0]),.c(c[0]),.d(d[0]),.e(e[0]),.f(f[0]),.g(g[0]),.h(h[0]),.s2(s2),.s1(s1),.s0(s0),.y(y[0]));
mx8 (.a(a[1]),.b(b[1]),.c(c[1]),.d(d[1]),.e(e[1]),.f(f[1]),.g(g[1]),.h(h[1]),.s2(s2),.s1(s1),.s0(s0),.y(y[1]));
mx8 (.a(a[2]),.b(b[2]),.c(c[2]),.d(d[2]),.e(e[2]),.f(f[2]),.g(g[2]),.h(h[2]),.s2(s2),.s1(s1),.s0(s0),.y(y[2]));
mx8 (.a(a[3]),.b(b[3]),.c(c[3]),.d(d[3]),.e(e[3]),.f(f[3]),.g(g[3]),.h(h[3]),.s2(s2),.s1(s1),.s0(s0),.y(y[3]));
endmodule
module mx8(a,b,c,d,e,f,g,h,s2,s1,s0,y);
input a,b,c,d,e,f,g,h;
input s2,s1,s0;
output y;
wire w0,w1,w2,w3,w4,w5;
mx2(.d0(a),.d1(b),.s(s0),.y(w0));
mx2(.d0(c),.d1(d),.s(s0),.y(w1));
mx2(.d0(e),.d1(f),.s(s0),.y(w2));
mx2(.d0(g),.d1(h),.s(s0),.y(w3));
mx2(.d0(w0),.d1(w1),.s(s1),.y(w4));
mx2(.d0(w2),.d1(w3),.s(s1),.y(w5));
mx2(.d0(w4),.d1(w5),.s(s2),.y(y));
endmodule
module mx2(d0,d1,s,y);
input d0,d1;
input s;
output y;
wire sb, w0, w1;
_inv U0_inv(.a(s),.y(sb));
_nand2(.a(d0),.b(sb),.y(w0));
_nand2(.a(d1),.b(s),.y(w1));
_nand2(.a(w0),.b(w1),.y(y));
endmodule
module cla4_ov(a,b,ci,s,c3,co);
input [3:0] a,b;
input ci;
output [3:0] s;
output c3, co;
wire c1,c2;
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_clba (.a(a),.b(b),.ci(ci),.c1(c1),.c2(c2),.c3(c3),.co(co));
endmodule
'기록지 > 컴퓨터구조(computer architecture)' 카테고리의 다른 글
Quartus II/ ModelSim을 이용한 구현 - 6. 신호등(Traffic Light Controller) (1) | 2023.01.31 |
---|---|
Quartus II/ ModelSim을 이용한 구현 - 5. Latch, Flip-Flop (0) | 2023.01.30 |
Quartus II/ ModelSim을 이용한 구현 - 3. CLA(Carry Look-ahead Adder) (verilog) (0) | 2023.01.28 |
Quartus II/ ModelSim을 이용한 구현 - 2. RCA(Ripple-Carry Adder) (verilog) (0) | 2023.01.27 |
Quartus II/ ModelSim을 이용한 구현 - 1. Multiplexer(verilog) (0) | 2023.01.26 |