티스토리 뷰
IDEC 강의 영상을 보고 정리한 내용입니다.
https://www.idec.or.kr/vod/apply/view/?pay=&search_val=CPU&no=273
저번까지 설계한 CPU의 구조이다.
이번엔 ACC와 ALU를 연결하여 MUL연산과 DIV연산을 하도록 하겠다.
MUL / DIV
MUL과 DIV는 shift와 add연산을 사용한다.
MUL : shift right(ACC) + add(ALU)
DIV : shift left(ACC) + sub(ALU)
MUL
mul 연산 과정은 다음과 같다.
7 X 6 (0111 x 0110)
7 : Multiplicant (BREG)
6 : Multiplier (AL)
BREG : BREG
ACC : AH | AL
ALU는 AH와 BREG를 연산한다.
곱셈 예시
https://www.youtube.com/watch?v=3QHC7LXxKuI
DIV
div연산 과정은 다음과 같다.
9 X 2 (1001 x 0010)
9 : Dividend (AL)
2 : Divisor (BREG)
BREG : BREG
ACC : AH/AL
ALU는 AH와 BREG를 연산한다.
나눗셈 예시
https://www.youtube.com/watch?v=i-6ZVoxD40Y
제어신호(hs / ls) 분기회로
위의 flow chart에서 분기점에서 ACC의 제어신호를 결정한다.
MUL
: if (al_lsb == 1) -> AH = AH+BREG
ACC입장에서 hs = 11(data load)
DIV
: if ((AH-BREG)>=0) => AH = AH - BREG
ACC입장에서 hs = 11(data load)
위의 정보로 회로를 구성하면 다음과 같다.
- DIV나 MUL일 때 MUX가 D1을 이어준다.
- AH값을 갱신할 때 hs=11이 된다.
ACC+ALU
ACC + ALU 회로는 다음과 같다.
계산이 완료된 ACC의 값을 내보내는 tri-state-buffer는 다음과 같다.
지금까지 구성한 회로를 모두 모으면 다음과 같다.
verilog code
module aluNacc(ah_reset,ah_inen,s_sub,s_and,s_div, s_add,s_mul, clr,acc_oen,clk,breg_in,bus_in,hs,ls,sign_flag,zero_flag,acc_out);
input ah_reset,ah_inen,s_sub,s_and,s_div,s_add, s_mul,
clr,acc_oen,clk;
input [3:0] breg_in;
input [3:0] bus_in;
input [1:0] hs;
input [1:0] ls;
output sign_flag, zero_flag;
output [7:0] acc_out;
wire [3:0] ah_out, al_out, aluout;
wire c_out;
wire [1:0] acc_hs;
// hs selection
assign acc_hs[1]=(s_mul|s_div)?(s_mul&al_out[0])| (s_div&c_out) : hs[1];
assign acc_hs[0]=(s_mul|s_div)?(s_mul&al_out[0])| (s_div&c_out) : hs[0];
acc u0(ah_reset,clr,clk,bus_in,ah_inen,aluout,carry_flag,acc_hs,
ls,ah_out,al_out);
// tri-state-buffer
assign acc_out=(acc_oen)?{ah_out, al_out} : 8'bz; //Tri-state buffer
alu u1(s_sub,s_div,ah_out,breg_in,s_and,aluout, c_out,clk,clr,s_add,
s_mul,al_out[0],sign_flag,carry_flag,zero_flag);
endmodule
MUL / DIV simulation
MUL simulation
`timescale 1ns / 1ps
module tb_aluNaccMul;
// Inputs
reg ah_reset, ah_inen;
reg [3:0] bus_in;
reg [1:0] hs;
reg [1:0] ls;
reg s_sub,s_and, s_div;
reg s_add, s_mul, clr, clk,acc_oen;
reg [3:0] breg_in;
// Output
wire sign_flag,zero_flag;
wire [7:0] acc_out;
// Instantiate the UUT
aluNacc UUT (
.ah_reset(ah_reset),.ah_inen(ah_inen),
.bus_in(bus_in), .hs(hs),
.ls(ls), .s_sub(s_sub),
.s_and(s_and), .s_div(s_div),
.breg_in(breg_in),.s_add(s_add),
.clr(clr), .s_mul(s_mul), .clk(clk),
.sign_flag(sign_flag),
.zero_flag(zero_flag),
.acc_oen(acc_oen),
.acc_out(acc_out)
);
always #50 clk = ~clk;
initial begin
ah_reset = 0; ah_inen = 0;
bus_in = 4'b0011; breg_in = 4'b0101;
hs = 0; ls = 0;
s_sub = 0; s_and = 0;
s_div = 0; s_add = 0;
clk = 0; s_mul = 0;
clr = 1; acc_oen = 1;
#100; clr = 0;
#100; ah_inen = 1; hs = 2'b11;
#100; ah_inen = 0; hs = 2'b00;
#100; ls = 2'b11;
#100; ls = 2'b00;
#100; ah_reset = 1;
#100; ah_reset = 0;
#100; hs = 2'b11; s_mul = 1; //T3
#100; hs = 2'b01; ls = 2'b01; s_mul = 0; //T4
#100; hs = 2'b11; ls = 2'b00;s_mul = 1; //T5
#100; hs = 2'b01; ls = 2'b01; s_mul = 0; //T6
#100; hs = 2'b11; ls = 2'b00;s_mul = 1; //T7
#100; hs = 2'b01; ls = 2'b01; s_mul = 0; //T8
#100; hs = 2'b11; ls = 2'b00;s_mul = 1; //T9
#100; hs = 2'b01; ls = 2'b01; s_mul = 0; //T10
#100; hs = 2'b00; ls = 2'b00; //T11
#100;
end
endmodule
- s_mul에 맞춰서 AH 업데이트
- clk에 맞춰서 shift
를 반복하는 모습을 볼 수 있다.
DIV simulation
`timescale 1ns / 1ps
module tb_aluNaccDiv;
// Inputs
reg ah_reset, ah_inen;
reg [3:0] bus_in;
reg [1:0] hs;
reg [1:0] ls;
reg s_sub,s_and, s_div;
reg [3:0] breg_in;
reg s_add,clr, s_mul,clk,acc_oen;
// Output
wire sign_flag,zero_flag;
wire [7:0] acc_out;
// Instantiate the UUT
aluNacc UUT (.ah_reset(ah_reset),
.ah_inen(ah_inen),.bus_in(bus_in),
.hs(hs), .ls(ls), .s_sub(s_sub),
.s_and(s_and), .s_div(s_div),
.breg_in(breg_in),.s_add(s_add),
.clr(clr), .s_mul(s_mul), .clk(clk),
.sign_flag(sign_flag),
.zero_flag(zero_flag),
.acc_oen(acc_oen),
.acc_out(acc_out)
);
always #50 clk = ~clk;
initial begin
ah_reset = 0; ah_inen = 0;
bus_in = 4'b1001; breg_in = 4'b0010;
hs = 0; ls = 0;
s_sub = 0; s_and = 0;
s_div = 0; s_add = 0;
clk = 0; s_mul = 0;
clr = 1; acc_oen = 1;
#100; clr = 0;
#100; ah_inen = 1; hs = 2'b11;
#100; ah_inen = 0; hs = 2'b00;
#100; ls = 2'b11;
#100; ls = 2'b00;
#100; ah_reset = 1;
#100; ah_reset = 0;
#100; hs = 2'b10; ls = 2'b10; //T3
#100; hs = 2'b11; ls = 2'b00; s_div = 1;//T4
#100; hs = 2'b10; ls = 2'b10; s_div = 0;//T5
#100; hs = 2'b11; ls = 2'b00; s_div = 1;//T6
#100; hs = 2'b10; ls = 2'b10; s_div = 0;//T7
#100; hs = 2'b11; ls = 2'b00; s_div = 1;//T8
#100; hs = 2'b10; ls = 2'b10;s_div = 0; //T9
#100; hs = 2'b11; ls = 2'b00; s_div = 1;//T10
#100; hs = 2'b00; ls = 2'b10; s_div = 0; //T11
#100; hs = 2'b00; ls = 2'b00;
end
endmodule
- s_div에 맞춰서 AH 업데이트
- clk에 맞춰서 shift
를 반복하는 모습을 볼 수 있다.
9/2로 simulation했을 때 (몫 : 4 / 나머지 : 1)을 확인할 수 있다.
결론
ACC와 ALU를 연결하여 mul연산과 div연산을 했다.
다음은 control block을 설계할 것이다.
'프로젝트 > 4bit CPU' 카테고리의 다른 글
[4bit CPU #6] control unit(2) (control block) - 18EE (0) | 2023.07.21 |
---|---|
[4bit CPU #5] Control unit(1) (Decoder / Ring counter) - 18EE (0) | 2023.07.17 |
[4bit CPU #3] ALU - 18EE (0) | 2023.07.15 |
[4bit CPU #2] ACC(Universal shift register) - 18EE (0) | 2023.07.12 |
[4bit CPU #1] Register, Program Counter(PC) - 18EE (0) | 2023.07.12 |
- Total
- Today
- Yesterday
- 4bit
- 굿노트 mp3 내보내기
- VLSI 전력소모
- MTCMOS
- Stack effect
- 굿노트 녹음파일
- mp3파일 추출
- static power
- VLSI power
- Verilog
- switching power
- 4bit CPU
- VTCMOS
- delay
- leakage
- CMOS power
- clock gating
- dynamic power
- Control Unit
- level shifter
- vlsi
- ALU
- CPU
- acc
- DVFS
- VLSI dynamic power consumption
- power gating
- data gating
- 굿노트 내보내기
- 굿노트 mp3파일 추출
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |