일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | ||
6 | 7 | 8 | 9 | 10 | 11 | 12 |
13 | 14 | 15 | 16 | 17 | 18 | 19 |
20 | 21 | 22 | 23 | 24 | 25 | 26 |
27 | 28 | 29 | 30 |
- SoC설계
- 베르의게임개발유튜브
- 다이오드
- 언리얼엔진4
- 참고
- 개인스터디
- UE4
- 자습포스팅
- diode
- 전자공학부
- 디지털회로설계
- 반도체교육
- Rectifier
- 게임개발
- 물리전자
- 자습목적포스팅
- 반도체물성
- ASIC설계
- 전자공학
- 회로개발
- 베르
- SK하이닉스
- pn junction
- 자습
- 반도체기초교육
- 하이포2기
- UnrealEngine4
- 반도체소자교육
- 전자회로
- 반도체공정교육
- Today
- Total
호경
[개인스터디/개인프로젝트] 8-bit 복합 ALU 설계하기 본문
※시작에 앞서, 해당 내용은 서적 "VHDL과 반도체 회로설계"의 내용을 토대로 작성됐다.
※나는 Verilog HDL 코드로 작성해서 스터디를 진행했다.
1. ALU
A. ALU란?
ALU는 Arithmetic Logic Unit의 약자이고, CPU에서 가장 중요한 산술 연산 회로이다.
대개 ALU는 다음과 같은 산술 회로로 이루어져 있다.
a. Adder
b. Substracter
c. Multiplier
d. Shift Register
이번 포스팅에서는 책에서 심화문제로 제시한 8-bit 복합 ALU 설계를 목표로 한다.
2. ALU 설계 과정
* 책에서 요구한 8-bit ALU의 스펙
RST | CLK | CMD | D0 |
0 | X | X | Initialize |
1 | / | 0 | A + B |
1 | / | 1 | A - B |
1 | / | 2 | A * B |
1 | / | 3 | HOLD |
1 | / | 4 | LSL with 2 bits |
1 | / | 5 | ASL with 2 bits |
1 | / | 6 | ASR with 2 bits |
1 | / | 7 | RSL with 2 bits |
A. ALU Top Module Design 및 Timing Diagram 작성
B. Adder / Substractor
초기 예상도는 다음과 같이 했으나, CMD를 8x1 MUX로 묶어주기 위해서 다시 회로를 작성했기 때문에 그림으로 그린 회로도랑은 다르다.
다만 회로의 효율성을 위해 단순히 A + B, A - B를 한 것이 아니라,
특히 SUB에서는 B의 2의 보수를 구해서 더해주는 방법을 사용하여 logic을 덜 사용할 수 있는 고급 설계 방법을 사용했다.
Adder와 Substractor 모두 테스트벤치를 진행했으나, 코드가 여러번 변경돼 기존에 그렸던 회로만 포스팅하겠다.
C. Multiplier
CPU에서 곱셈 연산을 할 경우, 하위 1/2 byte만을 사용하고, 상위 1/2 byte는 사용하지 않는다.
Adder/Substractor와 마찬가지로 Multiplier도 테스트 벤치를 진행했으나, 코드가 여러번 변경돼 기존에 그렸던 회로만 포스팅하겠다.
D. Shift Register
초기 예상도는 다음과 같이 했으나, CMD를 8x1 MUX로 묶어주기 위해서 다시 회로를 작성했기 때문에 그림으로 그린 회로도랑은 다르다.
Shift Register는 결합 연산자를 사용하여 설계했다.
Adder/Substractor와 마찬가지로 Shift Register도 테스트 벤치를 진행했으나, 코드가 여러번 변경돼 기존에 그렸던 회로만 포스팅하겠다.
3. ALU 설계 코드
A. Verilog HDL 코드
//ALU
module Top_ALU(CLK, RST, A, B, CMD, D0);
input CLK, RST;
input[7:0] A, B;
input[7:0] CMD;
output[7:0] D0;
wire[7:0] T_D0;
wire[7:0] ADD_result;
wire[7:0] SUB_result;
wire[7:0] Multiplier_result;
wire[7:0] LSL_result;
wire[7:0] ASL_result;
wire[7:0] ASR_result;
wire[7:0] RSL_result;
wire[7:0] HOLD_result = T_D0;
assign D0 = T_D0;
ADSB ADSB1(.A(A), .B(B), .CLK(CLK), .RST(RST), .result_ADD(ADD_result), .result_SUB(SUB_result));
Multiplier Multiplier1(.A(A), .B(B), .CLK(CLK), .RST(RST), .result_mult(Multiplier_result));
Shift_Reg Shift_Reg1(.A(A), .B(B), .CLK(CLK), .RST(RST), .result_LSL(LSL_result), .result_ASL(ASL_result), .result_ASR(ASR_result), .result_RSL(RSL_result));
Multiplexer_8_1 MUX8_1(.ADD(ADD_result), .SUB(SUB_result), .HOLD(HOLD_result), .MULT(Multiplier_result), .LSL(LSL_result), .ASL(ASL_result), .ASR(ASR_result), .RSL(RSL_result), .CMD(CMD), .D0(T_D0));
endmodule
//Adder, Substractor
module ADSB(A, B, CLK, RST, result_ADD, result_SUB);
input[7:0] A, B;
input CLK, RST;
reg[7:0] B_Temp;
output[7:0] result_ADD;
output[7:0] result_SUB;
reg[7:0] T_result_SUB;
reg[7:0] T_result_ADD;
assign result_ADD = T_result_ADD;
assign result_SUB = T_result_SUB;
always@(posedge CLK or negedge RST)
begin
if(!RST)
begin
T_result_ADD <= 8'b00000000;
T_result_SUB <= 8'b00000000;
end
else
begin
T_result_ADD <= A + B;
T_result_SUB <= A + (~B + 1'b1);
end
end
endmodule
//Multiplier
module Multiplier(A, B, CLK, RST, result_mult);
input CLK, RST;
input[7:0] A, B;
output[7:0] result_mult;
reg[7:0] T_result_mult;
assign result_mult = T_result_mult;
always@(posedge CLK or negedge RST)
begin
if(!RST)
begin
T_result_mult <= 8'b00000000;
end
else
begin
T_result_mult <= (A[3:0] * B[3:0]);
end
end
endmodule
//Shift Register
module Shift_Reg(A, B, CLK, RST, result_LSL, result_ASL, result_ASR, result_RSL);
input CLK, RST;
input[7:0] A, B;
output[7:0] result_LSL;
output[7:0] result_ASL;
output[7:0] result_ASR;
output[7:0] result_RSL;
reg[7:0] T_result_LSL;
reg[7:0] T_result_ASL;
reg[7:0] T_result_ASR;
reg[7:0] T_result_RSL;
assign result_LSL = T_result_LSL;
assign result_ASL = T_result_ASL;
assign result_ASR = T_result_ASR;
assign result_RSL = T_result_RSL;
always@(posedge CLK or negedge RST)
begin
if(!RST)
begin
T_result_LSL <= 8'b00000000;
T_result_ASL <= 8'b00000000;
T_result_ASR <= 8'b00000000;
T_result_RSL <= 8'b00000000;
end
else
begin
T_result_LSL <= {A[5:0], 1'b0, 1'b0}; //Logic shift left
T_result_ASL <= {A[5:0], A[0], A[0]}; //Arithmetic shift left
T_result_ASR <= {A[7], A[7], A[7:2]}; //Arithmetic shift right
T_result_RSL <= {A[5:0], A[7], A[6]}; //Rotational shift left
end
end
endmodule
//8x1 MUX
module Multiplexer_8_1(ADD, SUB, HOLD, MULT, LSL, ASL, ASR, RSL, CMD, D0);
input[7:0] ADD, SUB, HOLD, MULT, LSL, ASL, ASR, RSL, CMD;
output[7:0] D0;
reg[7:0] T_D0;
assign D0 = T_D0;
always@(*)
begin
case(CMD)
8'b00000001: T_D0 <= ADD;
8'b00000010: T_D0 <= SUB;
8'b00000100: T_D0 <= HOLD;
8'b00001000: T_D0 <= MULT;
8'b00010000: T_D0 <= LSL;
8'b00100000: T_D0 <= ASL;
8'b01000000: T_D0 <= ASR;
8'b10000000: T_D0 <= RSL;
endcase
end
endmodule
B. Test Bench 코드
//Test Bench
module tb_ALU();
reg CLK, RST;
reg[7:0] A, B, CMD;
wire[7:0] D0;
Top_ALU uut(
.CLK(CLK),
.RST(RST),
.A(A),
.B(B),
.CMD(CMD),
.D0(D0));
always#(10)
begin
CLK = ~CLK;
end
initial
begin
CLK = 0;
RST = 0;
CMD = 8'b00000000;
A = 8'b00000000;
B = 8'b00000000;
#30; //0.030ns
RST = 1;
CMD = 8'b00000001;
A = 8'b00000001;
B = 8'b00000010;
#40; //0.070ns
CMD = 8'b00000010;
A = 8'b00000011;
B = 8'b00000001;
#40; //0.110ns
CMD = 8'b00000100;
A = 8'b10101010;
B = 8'b00000000;
#40; //0.150ns
CMD = 8'b00001000;
A = 8'b00010010;
#40; //0.190ns
CMD = 8'b00010000;
A = 8'b10100001;
#40; //0.230ns
CMD = 8'b00100000;
A = 8'b01100010;
#40; //0.270ns
CMD = 8'b01000000;
A = 8'b00100110;
#40; //0.310ns
CMD = 8'b10000000;
A = 8'b00110101;
end
endmodule
4. ALU 설계 결과
A. Netlist viewer
B. Simulation 검증
설계와 검증을 통해 8-bit ALU 스펙을 만족하는 ALU를 설계 완료 했다.
'디지털회로설계 > SoC,ASIC 설계' 카테고리의 다른 글
[IDEC 교육] SoC 설계를 위한 AMBA On-Chip Interconnect (0) | 2023.02.19 |
---|---|
[개인스터디] Binary to BCD Code converter (0) | 2023.02.13 |
[개인스터디] Loadable Counter and Test Bench (0) | 2023.01.08 |
[개인스터디] CLA와 16-bit GCLA (0) | 2023.01.05 |
[개인스터디] 4-bit parallel Adder (0) | 2023.01.02 |