EunSeong Lee Portfolio
Project
AI_mini_prj
Avoid Bullets
Digital Clock
Subsubcategory 1
Subsubcategory 2
post-03
Study
AI Algorithm Structure
LAB
ASIC FrontEnd
post-01
post-02
Arm Architecture
post-01
CMOS VLSI Design
LAB
THEORY
CPU Design
CODE
LAB
THEORY
FPGA
LAB
THEORY
comment system
Home
markdown
portfolio
Contact
Copyright © 2024 |
Yankos
Home
>
Study
> CPU Design
Please wait ...
CPU Design
Day5
DAY5 ✅ Dedicated Processor RegFile R1 = 0; R2 = 0; while(R1 <= 10){ R2 = R2 + R1; R1 = R1 + 1; OutPort = R2; } ✅ 동작방식 ✅ RegFile Asm ✅ 코드 DataPath.sv `timescale 1ns / 1ps module DataPath( input logic clk, input logic reset, input logic RFSrcMuxSel, input logic [2:0] RAddr1, input logic [2:0] RAddr2, input logic [2:0] WAddr, input logic we, output logic R1Le10, input logic OutPortEn, output logic [7:0] OutPort ); logic [7:0] AdderResult, RFSrcMuxOut; logic [7:0] RData1, RData2; mux_2X1 U_RFSrcMux ( .sel (RFSrcMuxSel), .x0 (AdderResult), .x1 (1), .y (RFSrcMuxOut) ); RegFile U_RegFile ( .clk (clk), .RAddr1 (RAddr1), .RAddr2 (RAddr2), .WAddr (WAddr), .we (we), .WData (RFSrcMuxOut), .RData1 (RData1), .RData2 (RData2) ); comparator U_R1Le10 ( .a (RData1), .b (8'd10), .lt (R1Le10) ); adder U_Adder ( .a (RData1), .b (RData2), .sum (AdderResult) ); register U_OutPort ( .clk (clk), .reset (reset), .en (OutPortEn), .d (RData1), .q (OutPort) ); endmodule module RegFile ( input logic clk, input logic [2:0] RAddr1, input logic [2:0] RAddr2, input logic [2:0] WAddr, input logic we, input logic [7:0] WData, output logic [7:0] RData1, output logic [7:0] RData2 ); logic [7:0] mem [0:2**3-1]; // 8bit 8개 (Addr 개수) always_ff @(posedge clk) begin if(we) begin mem[WAddr] <= WData; end end assign RData1 = (RAddr1 == 0) ? 8'b0 : mem[RAddr1]; assign RData2 = (RAddr2 == 0) ? 8'b0 : mem[RAddr2]; endmodule module register ( input logic clk, input logic reset, input logic en, input logic [7:0] d, output logic [7:0] q ); always_ff @(posedge clk or posedge reset) begin if(reset) begin q <= 0; end else begin if(en) begin q <= d; end end end endmodule module mux_2X1 ( input logic sel, input logic [7:0] x0, input logic [7:0] x1, output logic [7:0] y ); always_comb begin y = 8'b0; case (sel) 1'b0: y = x0; 1'b1: y = x1; endcase end endmodule module adder ( input logic [7:0] a, input logic [7:0] b, output logic [7:0] sum ); assign sum = a + b; endmodule module comparator ( input logic [7:0] a, input logic [7:0] b, output logic lt ); assign lt = a <= b; endmodule ControlUnit
Study
· 2025-08-12
DedicatedProcessor ALUOP
DedicatedProcessor ALUOP ✅ 과제 ⚒️ 코드 ⚒️ ⚒️[DedicatedProcessor ALUOP.sv] ✅ Schematic ✅ 시뮬레이션 ✅ 분석 반복별 레지스터 값 1회: R1=3, R2=2, R3=3, R4=5 → Yes 2회: R1=7, R2=6, R3=9, R4=15 → Yes 3회: R1=15, R2=14, R3=21, R4=35 → Yes 4회: R1=31, R2=30, R3=45, R4=75 → Yes 5회: R1=63, R2=62, R3=93, R4=155 → Yes 6회: R1=127, R2=126, R3=189, R4=59 → No ⇒ halt ➡️ 첫 번째 반복 시작 값: (R1, R2, R3, R4) = (1, 0, 0, 0) **계산 순서** R2 = R1 + R1 (1 + 1 = 2) ➞ (1, **2**, 0, 0) R3 = R2 + R1 (2 + 1 = 3) ➞ (1, 2, **3**, 0) R4 = R3 - R1 (3 - 1 = 2) ➞ (1, 2, 3, **2**) R1 = R1 | R2 (1 | 2 = 3) ➞ (**3**, 2, 3, 2) R4 = R4 & R3 (2 & 3 = 2) ➞ (3, 2, 3, **2**) R4 = R2 + R3 (2 + 3 = 5) ➞ (3, 2, 3, **5**) 조건 확인: R4 > R2 (5 > 2) ➞ ✅ Yes, 계속 진행 ➡️ 두 번째 반복 시작 값: (R1, R2, R3, R4) = (3, 2, 3, 5) **계산 순서** R2 = R1 + R1 (3 + 3 = 6) ➞ (3, **6**, 3, 5) R3 = R2 + R1 (6 + 3 = 9) ➞ (3, 6, **9**, 5) R4 = R3 - R1 (9 - 3 = 6) ➞ (3, 6, 9, **6**) R1 = R1 | R2 (3 | 6 = 7) ➞ (**7**, 6, 9, 6) R4 = R4 & R3 (6 & 9 = 0) ➞ (7, 6, 9, **0**) R4 = R2 + R3 (6 + 9 = 15) ➞ (7, 6, 9, **15**) 조건 확인: R4 > R2 (15 > 6) ➞ ✅ Yes, 계속 진행 ➡️ 세 번째 반복 시작 값: (R1, R2, R3, R4) = (7, 6, 9, 15) **계산 순서** R2 = R1 + R1 (7 + 7 = 14) ➞ (7, **14**, 9, 15) R3 = R2 + R1 (14 + 7 = 21) ➞ (7, 14, **21**, 15) R4 = R3 - R1 (21 - 7 = 14) ➞ (7, 14, 21, **14**) R1 = R1 | R2 (7 | 14 = 15) ➞ (**15**, 14, 21, 14) R4 = R4 & R3 (14 & 21 = 4) ➞ (15, 14, 21, **4**) R4 = R2 + R3 (14 + 21 = 35) ➞ (15, 14, 21, **35**) 조건 확인: R4 > R2 (35 > 14) ➞ ✅ Yes, 계속 진행 ➡️ 네 번째 반복 시작 값: (R1, R2, R3, R4) = (15, 14, 21, 35) **계산 순서** R2 = R1 + R1 (15 + 15 = 30) ➞ (15, **30**, 21, 35) R3 = R2 + R1 (30 + 15 = 45) ➞ (15, 30, **45**, 35) R4 = R3 - R1 (45 - 15 = 30) ➞ (15, 30, 45, **30**) R1 = R1 | R2 (15 | 30 = 31) ➞ (**31**, 30, 45, 30) R4 = R4 & R3 (30 & 45 = 12) ➞ (31, 30, 45, **12**) R4 = R2 + R3 (30 + 45 = 75) ➞ (31, 30, 45, **75**) 조건 확인: R4 > R2 (75 > 30) ➞ ✅ Yes, 계속 진행 ➡️ 다섯 번째 반복 시작 값: (R1, R2, R3, R4) = (31, 30, 45, 75) **계산 순서** R2 = R1 + R1 (31 + 31 = 62) ➞ (31, **62**, 45, 75) R3 = R2 + R1 (62 + 31 = 93) ➞ (31, 62, **93**, 75) R4 = R3 - R1 (93 - 31 = 62) ➞ (31, 62, 93, **62**) R1 = R1 | R2 (31 | 62 = 63) ➞ (**63**, 62, 93, 62) R4 = R4 & R3 (62 & 93 = 28) ➞ (63, 62, 93, **28**) R4 = R2 + R3 (62 + 93 = 155) ➞ (63, 62, 93, **155**) 조건 확인: R4 > R2 (155 > 62) ➞ ✅ Yes, 계속 진행 ➡️ 여섯 번째 반복 (마지막) 시작 값: (R1, R2, R3, R4) = (63, 62, 93, 155) **계산 순서** R2 = R1 + R1 (63 + 63 = 126) ➞ (63, **126**, 93, 155) R3 = R2 + R1 (126 + 63 = 189) ➞ (63, 126, **189**, 155) R4 = R3 - R1 (189 - 63 = 126) ➞ (63, 126, 189, **126**) R1 = R1 | R2 (63 | 126 = 127) ➞ (**127**, 126, 189, 126) R4 = R4 & R3 (126 & 189 = 120) ➞ (127, 126, 189, **120**) R4 = R2 + R3 (126 + 189 = 315) 8-bit Wrapping (오버플로우): 8비트 레지스터는 255까지만 표현 가능하므로, 315는 256을 뺀 나머지 값인 59가 된다. (315 - 256 = 59) R4 최종 값 ➞ (127, 126, 189, **59**) 조건 확인: R4 > R2 (59 > 126) ➞ ❌ No, 중단 (Halt)
Study
· 2025-08-12
DedicatedProcessor ALUOP
DedicatedProcessor ALUOP ✅ DedicatedProcessor_ALUOP.sv `timescale 1ns / 1ps module DedicatedProcessor_ALUOP( input logic clk, input logic reset, output logic [7:0] OutPort ); logic RFSrcMuxSel; logic [2:0] RAddr1; logic [2:0] RAddr2; logic [2:0] WAddr; logic [1:0] AluOpMuxSel; logic we; logic Lt; logic OutPortEn; DataPath U_DataPath ( .clk (clk), .reset (reset), .RFSrcMuxSel(RFSrcMuxSel), .RAddr1 (RAddr1), .RAddr2 (RAddr2), .WAddr (WAddr), .AluOpMuxSel(AluOpMuxSel), .we (we), .Lt (Lt), .OutPortEn (OutPortEn), .OutPort (OutPort) ); ControlUnit U_ControlUnit ( .clk (clk), .reset (reset), .RFSrcMuxSel(RFSrcMuxSel), .RAddr1 (RAddr1), .RAddr2 (RAddr2), .WAddr (WAddr), .AluOpMuxSel(AluOpMuxSel), .we (we), .Lt (Lt), .OutPortEn (OutPortEn) ); endmodule ✅ DataPath.sv `timescale 1ns / 1ps module DataPath ( input logic clk, input logic reset, input logic RFSrcMuxSel, input logic [2:0] RAddr1, input logic [2:0] RAddr2, input logic [2:0] WAddr, input logic [1:0] AluOpMuxSel, input logic we, output logic Lt, input logic OutPortEn, output logic [7:0] OutPort ); logic [7:0] AdderResult, RFSrcMuxOut; logic [7:0] RData1, RData2; mux_2x1 U_RFSrcMux ( .sel(RFSrcMuxSel), .x0 (AdderResult), .x1 (1), .y (RFSrcMuxOut) ); RegFile U_RegFile ( .clk (clk), .RAddr1(RAddr1), .RAddr2(RAddr2), .WAddr (WAddr), .we (we), .WData (RFSrcMuxOut), .RData1(RData1), .RData2(RData2) ); comparator U_comparator ( .a (RData1), .b (RData2), .lt (Lt) ); alu_op U_ALU_OP ( .x0 (RData1), .x1 (RData2), .AluOpMuxSel(AluOpMuxSel), .y (AdderResult) ); register U_OutPort ( .clk (clk), .reset(reset), .en (OutPortEn), .d (RData1), .q (OutPort) ); endmodule ✅ alu_op 추가 module alu_op ( input logic [7:0] x0, input logic [7:0] x1, input logic [1:0] AluOpMuxSel, output logic [7:0] y ); always_comb begin y = 8'b00; case (AluOpMuxSel) 2'b00: begin y = x0 + x1; end 2'b01: begin y = x0 - x1; end 2'b10: begin y = x0 & x1; end 2'b11: begin y = x0 | x1; end endcase end endmodule ✅ ControlUnit `timescale 1ns / 1ps module ControlUnit ( input logic clk, input logic reset, output logic RFSrcMuxSel, output logic [2:0] RAddr1, output logic [2:0] RAddr2, output logic [2:0] WAddr, output logic [1:0] AluOpMuxSel, output logic we, input logic Lt, output logic OutPortEn ); typedef enum { S0, S1, S2, S3, S4, S5, S6, S7, S8, S9, S10, S11, S12, S13 } state_e; state_e state, next_state; always_ff @(posedge clk or posedge reset) begin if(reset) begin state <= S0; end else begin state <= next_state; end end always_comb begin next_state = state; RFSrcMuxSel = 0; RAddr1 = 0; RAddr2 = 0; WAddr = 0; AluOpMuxSel = 0; we = 0; OutPortEn = 0; case (state) S0:begin // R1 = 1 RFSrcMuxSel = 1; RAddr1 = 0; RAddr2 = 0; WAddr = 1; AluOpMuxSel = 0; we = 1; OutPortEn = 0; next_state = S1; end S1:begin // R2 = 0 RFSrcMuxSel = 0; RAddr1 = 0; RAddr2 = 0; WAddr = 3'h2; AluOpMuxSel = 0; we = 1; OutPortEn = 0; next_state = S2; end S2:begin // R3 = 0 RFSrcMuxSel = 0; RAddr1 = 0; RAddr2 = 0; WAddr = 3'h3; AluOpMuxSel = 0; we = 1; OutPortEn = 0; next_state = S3; end S3:begin // R4 = 0 RFSrcMuxSel = 0; RAddr1 = 0; RAddr2 = 0; WAddr = 3'h4; AluOpMuxSel = 0; we = 1; OutPortEn = 0; next_state = S4; end S4:begin // R2 = R1 + R1 RFSrcMuxSel = 0; RAddr1 = 1; RAddr2 = 1; WAddr = 3'h2; AluOpMuxSel = 0; we = 1; OutPortEn = 0; next_state = S5; end S5:begin // R3 = R2 + R1 RFSrcMuxSel = 0; RAddr1 = 3'h2; RAddr2 = 1; WAddr = 3'h3; AluOpMuxSel = 0; we = 1; OutPortEn = 0; next_state = S6; end S6:begin // R4 = R3 - R1 RFSrcMuxSel = 0; RAddr1 = 3'h3; RAddr2 = 1; WAddr = 3'h4; AluOpMuxSel = 1; we = 1; OutPortEn = 0; next_state = S7; end S7:begin // R1 = R1 | R2 RFSrcMuxSel = 0; RAddr1 = 3'h1; RAddr2 = 3'h2; WAddr = 3'h1; AluOpMuxSel = 2'h3; we = 1; OutPortEn = 0; next_state = S8; end S8:begin // R4 < R2 RFSrcMuxSel = 0; RAddr1 = 3'h4; RAddr2 = 3'h2; WAddr = 0; AluOpMuxSel = 0; we = 0; OutPortEn = 0; if(Lt) next_state = S6; else next_state = S9; end S9:begin // R4 = R4 & R3 RFSrcMuxSel = 0; RAddr1 = 3'h4; RAddr2 = 3'h3; WAddr = 3'h4; AluOpMuxSel = 2'h2; we = 1; OutPortEn = 0; next_state = S10; end S10:begin // R4 = R2 + R3 RFSrcMuxSel = 0; RAddr1 = 3'h2; RAddr2 = 3'h3; WAddr = 3'h4; AluOpMuxSel = 2'h0; we = 1; OutPortEn = 0; next_state = S11; end S11:begin // R4 > R2 RFSrcMuxSel = 0; RAddr1 = 3'h4; RAddr2 = 3'h2; WAddr = 0; AluOpMuxSel = 0; we = 0; OutPortEn = 0; if(Lt) next_state = S12; else next_state = S4; end S12:begin // OutPut RFSrcMuxSel = 0; RAddr1 = 3'h4; RAddr2 = 0; WAddr = 0; AluOpMuxSel = 0; we = 0; OutPortEn = 1; next_state = S13; end S13:begin // halt RFSrcMuxSel = 0; RAddr1 = 0; RAddr2 = 0; WAddr = 0; AluOpMuxSel = 0; we = 0; OutPortEn = 0; next_state = S13; end endcase end endmodule
Study
· 2025-08-12
Day4
DAY4 CPU(Central Processing Unit) 중앙처리장치 ✅ CISC vs RISC CISC vs RISC CISC(Complex Instruction Set Computer) RISC(Reduced Instruction Set Computer) 특징 (Feature) RISC (축소 명령어 집합 컴퓨터) CISC (복잡 명령어 집합 컴퓨터) 명령어 적고 단순, 길이가 고정 많고 복잡, 길이가 가변적 실행 속도 (CPI) 한 클럭에 한 명령어 처리를 지향 (CPI ≈ 1) 한 명령어가 여러 클럭을 소모 (CPI > 1) 설계 복잡성 하드웨어는 단순, 소프트웨어(컴파일러)가 복잡 하드웨어가 복잡, 소프트웨어(컴파일러)는 단순 메모리 접근 LOAD, STORE 등 전용 명령어로만 접근 다양한 명령어가 직접 메모리에 접근 가능 레지스터 범용 레지스터가 많고 활용도 높음 범용 레지스터 수가 비교적 적음 파이프라이닝 구조가 단순하여 파이프라이닝에 매우 효율적 명령어가 복잡하고 길이가 달라 파이프라이닝이 복잡함 전력 소비 일반적으로 전력 소비가 적음 일반적으로 전력 소비가 많음 가격 CISC보다 가격이 저렴 트랜지스터가 많이 들어가기 때문에 가격이 비쌈 MIPS(Microprocessor without Interlocked Pipeline Stages) 파이프라인 기술을 효율적으로 사용해 프로세서의 성능을 높이는 데에 초점을 맞춘 설계 방식 고정 길이의 단순한 명령어 파이프라인(Pipelining) 최적화 파이프라인은 명령어 처리 과정을 ‘명령어 인출(IF) → 해석(ID) → 실행(EX) → 메모리 접근(MEM) → 결과 저장(WB)’의 5단계 로드-스토어 (Load-Store) 구조 많은 수의 범용 레지스터 ✅ 폰노이만 구조 vs 하버드 구조 폰노이만 구조 하버드 구조 ✅ RISC-V UC 버클리에서 개발중인 무료 오픈 소스 RISC 명령어셋 아키텍처 MIPS 구조와 거의 비슷하다. ✅ 목표 Single Cycle Processor 모든 명령어가 1clock 내에 실행 Multi Cycle Processor 명령어 종류에 따라 실행 clock수가 다르다. pipe-line 구조 CPU ✅ Dedicated Processor Counter 0~9까지 카운트하는 Processor를 설계하시오. C 구현 // C언어 관점 A = 0; while (A < 10){ output = A; A = A + 1; } halt; // A를 중심에 놓고 생각 // A를 하드웨어적으로 구현한다 생각하면 -> A 레지스터 DataPath 구조 설계 및 ASM chart -> Control Unit 설계 Block Diagram State Machine ⚒️ 코드 ⚒️ ⚒️[DedicatedProcessor Counter.sv] ✅ Dedicated Processor Adder 0~10까지 누적으로 더하는 Dedicated Processor를 설계하시오. C 구현 // C언어 관점 A = 0; SUM = 0; while (A < 11){ SUM = SUM + A; A = A + 1; output = SUM; } halt; DataPath 구조 설계 ASM chart -> Control Unit 설계 ⚒️ 코드 ⚒️ ⚒️[DedicatedProcessor Adder.sv] ✅ TestBench `timescale 1ns / 1ps module tb_DedicatedProcessor_Adder (); logic clk; logic reset; logic [3:0] fndCom; logic [7:0] fndFont; DedicatedProcessor_Adder U_DedicatedProcessor_Adder (.*); always #5 clk = ~clk; initial begin clk = 0; reset = 1; #10; reset = 0; end endmodule 시뮬레이션 ✅ 동작 영상
Study
· 2025-08-11
DedicatedProcessor Adder
DedicatedProcessor Adder ✅ 과제 ⚒️ 코드 ⚒️ ⚒️[DedicatedProcessor ALUOP.sv] ✅ Schematic ✅ 시뮬레이션 ✅ 분석 반복별 레지스터 값 1회: R1=3, R2=2, R3=3, R4=5 → Yes 2회: R1=7, R2=6, R3=9, R4=15 → Yes 3회: R1=15, R2=14, R3=21, R4=35 → Yes 4회: R1=31, R2=30, R3=45, R4=75 → Yes 5회: R1=63, R2=62, R3=93, R4=155 → Yes 6회: R1=127, R2=126, R3=189, R4=59 → No ⇒ halt ➡️ 첫 번째 반복 시작 값: (R1, R2, R3, R4) = (1, 0, 0, 0) **계산 순서** R2 = R1 + R1 (1 + 1 = 2) ➞ (1, **2**, 0, 0) R3 = R2 + R1 (2 + 1 = 3) ➞ (1, 2, **3**, 0) R4 = R3 - R1 (3 - 1 = 2) ➞ (1, 2, 3, **2**) R1 = R1 | R2 (1 | 2 = 3) ➞ (**3**, 2, 3, 2) R4 = R4 & R3 (2 & 3 = 2) ➞ (3, 2, 3, **2**) R4 = R2 + R3 (2 + 3 = 5) ➞ (3, 2, 3, **5**) 조건 확인: R4 > R2 (5 > 2) ➞ ✅ Yes, 계속 진행 ➡️ 두 번째 반복 시작 값: (R1, R2, R3, R4) = (3, 2, 3, 5) **계산 순서** R2 = R1 + R1 (3 + 3 = 6) ➞ (3, **6**, 3, 5) R3 = R2 + R1 (6 + 3 = 9) ➞ (3, 6, **9**, 5) R4 = R3 - R1 (9 - 3 = 6) ➞ (3, 6, 9, **6**) R1 = R1 | R2 (3 | 6 = 7) ➞ (**7**, 6, 9, 6) R4 = R4 & R3 (6 & 9 = 0) ➞ (7, 6, 9, **0**) R4 = R2 + R3 (6 + 9 = 15) ➞ (7, 6, 9, **15**) 조건 확인: R4 > R2 (15 > 6) ➞ ✅ Yes, 계속 진행 ➡️ 세 번째 반복 시작 값: (R1, R2, R3, R4) = (7, 6, 9, 15) **계산 순서** R2 = R1 + R1 (7 + 7 = 14) ➞ (7, **14**, 9, 15) R3 = R2 + R1 (14 + 7 = 21) ➞ (7, 14, **21**, 15) R4 = R3 - R1 (21 - 7 = 14) ➞ (7, 14, 21, **14**) R1 = R1 | R2 (7 | 14 = 15) ➞ (**15**, 14, 21, 14) R4 = R4 & R3 (14 & 21 = 4) ➞ (15, 14, 21, **4**) R4 = R2 + R3 (14 + 21 = 35) ➞ (15, 14, 21, **35**) 조건 확인: R4 > R2 (35 > 14) ➞ ✅ Yes, 계속 진행 ➡️ 네 번째 반복 시작 값: (R1, R2, R3, R4) = (15, 14, 21, 35) **계산 순서** R2 = R1 + R1 (15 + 15 = 30) ➞ (15, **30**, 21, 35) R3 = R2 + R1 (30 + 15 = 45) ➞ (15, 30, **45**, 35) R4 = R3 - R1 (45 - 15 = 30) ➞ (15, 30, 45, **30**) R1 = R1 | R2 (15 | 30 = 31) ➞ (**31**, 30, 45, 30) R4 = R4 & R3 (30 & 45 = 12) ➞ (31, 30, 45, **12**) R4 = R2 + R3 (30 + 45 = 75) ➞ (31, 30, 45, **75**) 조건 확인: R4 > R2 (75 > 30) ➞ ✅ Yes, 계속 진행 ➡️ 다섯 번째 반복 시작 값: (R1, R2, R3, R4) = (31, 30, 45, 75) **계산 순서** R2 = R1 + R1 (31 + 31 = 62) ➞ (31, **62**, 45, 75) R3 = R2 + R1 (62 + 31 = 93) ➞ (31, 62, **93**, 75) R4 = R3 - R1 (93 - 31 = 62) ➞ (31, 62, 93, **62**) R1 = R1 | R2 (31 | 62 = 63) ➞ (**63**, 62, 93, 62) R4 = R4 & R3 (62 & 93 = 28) ➞ (63, 62, 93, **28**) R4 = R2 + R3 (62 + 93 = 155) ➞ (63, 62, 93, **155**) 조건 확인: R4 > R2 (155 > 62) ➞ ✅ Yes, 계속 진행 ➡️ 여섯 번째 반복 (마지막) 시작 값: (R1, R2, R3, R4) = (63, 62, 93, 155) **계산 순서** R2 = R1 + R1 (63 + 63 = 126) ➞ (63, **126**, 93, 155) R3 = R2 + R1 (126 + 63 = 189) ➞ (63, 126, **189**, 155) R4 = R3 - R1 (189 - 63 = 126) ➞ (63, 126, 189, **126**) R1 = R1 | R2 (63 | 126 = 127) ➞ (**127**, 126, 189, 126) R4 = R4 & R3 (126 & 189 = 120) ➞ (127, 126, 189, **120**) R4 = R2 + R3 (126 + 189 = 315) 8-bit Wrapping (오버플로우): 8비트 레지스터는 255까지만 표현 가능하므로, 315는 256을 뺀 나머지 값인 59가 된다. (315 - 256 = 59) R4 최종 값 ➞ (127, 126, 189, **59**) 조건 확인: R4 > R2 (59 > 126) ➞ ❌ No, 중단 (Halt)
Study
· 2025-08-11
DedicatedProcessor Counter
DedicatedProcessor Counter ✅ 과제 ⚒️ 코드 ⚒️ ⚒️[DedicatedProcessor ALUOP.sv] ✅ Schematic ✅ 시뮬레이션 ✅ 분석 반복별 레지스터 값 1회: R1=3, R2=2, R3=3, R4=5 → Yes 2회: R1=7, R2=6, R3=9, R4=15 → Yes 3회: R1=15, R2=14, R3=21, R4=35 → Yes 4회: R1=31, R2=30, R3=45, R4=75 → Yes 5회: R1=63, R2=62, R3=93, R4=155 → Yes 6회: R1=127, R2=126, R3=189, R4=59 → No ⇒ halt ➡️ 첫 번째 반복 시작 값: (R1, R2, R3, R4) = (1, 0, 0, 0) **계산 순서** R2 = R1 + R1 (1 + 1 = 2) ➞ (1, **2**, 0, 0) R3 = R2 + R1 (2 + 1 = 3) ➞ (1, 2, **3**, 0) R4 = R3 - R1 (3 - 1 = 2) ➞ (1, 2, 3, **2**) R1 = R1 | R2 (1 | 2 = 3) ➞ (**3**, 2, 3, 2) R4 = R4 & R3 (2 & 3 = 2) ➞ (3, 2, 3, **2**) R4 = R2 + R3 (2 + 3 = 5) ➞ (3, 2, 3, **5**) 조건 확인: R4 > R2 (5 > 2) ➞ ✅ Yes, 계속 진행 ➡️ 두 번째 반복 시작 값: (R1, R2, R3, R4) = (3, 2, 3, 5) **계산 순서** R2 = R1 + R1 (3 + 3 = 6) ➞ (3, **6**, 3, 5) R3 = R2 + R1 (6 + 3 = 9) ➞ (3, 6, **9**, 5) R4 = R3 - R1 (9 - 3 = 6) ➞ (3, 6, 9, **6**) R1 = R1 | R2 (3 | 6 = 7) ➞ (**7**, 6, 9, 6) R4 = R4 & R3 (6 & 9 = 0) ➞ (7, 6, 9, **0**) R4 = R2 + R3 (6 + 9 = 15) ➞ (7, 6, 9, **15**) 조건 확인: R4 > R2 (15 > 6) ➞ ✅ Yes, 계속 진행 ➡️ 세 번째 반복 시작 값: (R1, R2, R3, R4) = (7, 6, 9, 15) **계산 순서** R2 = R1 + R1 (7 + 7 = 14) ➞ (7, **14**, 9, 15) R3 = R2 + R1 (14 + 7 = 21) ➞ (7, 14, **21**, 15) R4 = R3 - R1 (21 - 7 = 14) ➞ (7, 14, 21, **14**) R1 = R1 | R2 (7 | 14 = 15) ➞ (**15**, 14, 21, 14) R4 = R4 & R3 (14 & 21 = 4) ➞ (15, 14, 21, **4**) R4 = R2 + R3 (14 + 21 = 35) ➞ (15, 14, 21, **35**) 조건 확인: R4 > R2 (35 > 14) ➞ ✅ Yes, 계속 진행 ➡️ 네 번째 반복 시작 값: (R1, R2, R3, R4) = (15, 14, 21, 35) **계산 순서** R2 = R1 + R1 (15 + 15 = 30) ➞ (15, **30**, 21, 35) R3 = R2 + R1 (30 + 15 = 45) ➞ (15, 30, **45**, 35) R4 = R3 - R1 (45 - 15 = 30) ➞ (15, 30, 45, **30**) R1 = R1 | R2 (15 | 30 = 31) ➞ (**31**, 30, 45, 30) R4 = R4 & R3 (30 & 45 = 12) ➞ (31, 30, 45, **12**) R4 = R2 + R3 (30 + 45 = 75) ➞ (31, 30, 45, **75**) 조건 확인: R4 > R2 (75 > 30) ➞ ✅ Yes, 계속 진행 ➡️ 다섯 번째 반복 시작 값: (R1, R2, R3, R4) = (31, 30, 45, 75) **계산 순서** R2 = R1 + R1 (31 + 31 = 62) ➞ (31, **62**, 45, 75) R3 = R2 + R1 (62 + 31 = 93) ➞ (31, 62, **93**, 75) R4 = R3 - R1 (93 - 31 = 62) ➞ (31, 62, 93, **62**) R1 = R1 | R2 (31 | 62 = 63) ➞ (**63**, 62, 93, 62) R4 = R4 & R3 (62 & 93 = 28) ➞ (63, 62, 93, **28**) R4 = R2 + R3 (62 + 93 = 155) ➞ (63, 62, 93, **155**) 조건 확인: R4 > R2 (155 > 62) ➞ ✅ Yes, 계속 진행 ➡️ 여섯 번째 반복 (마지막) 시작 값: (R1, R2, R3, R4) = (63, 62, 93, 155) **계산 순서** R2 = R1 + R1 (63 + 63 = 126) ➞ (63, **126**, 93, 155) R3 = R2 + R1 (126 + 63 = 189) ➞ (63, 126, **189**, 155) R4 = R3 - R1 (189 - 63 = 126) ➞ (63, 126, 189, **126**) R1 = R1 | R2 (63 | 126 = 127) ➞ (**127**, 126, 189, 126) R4 = R4 & R3 (126 & 189 = 120) ➞ (127, 126, 189, **120**) R4 = R2 + R3 (126 + 189 = 315) 8-bit Wrapping (오버플로우): 8비트 레지스터는 255까지만 표현 가능하므로, 315는 256을 뺀 나머지 값인 59가 된다. (315 - 256 = 59) R4 최종 값 ➞ (127, 126, 189, **59**) 조건 확인: R4 > R2 (59 > 126) ➞ ❌ No, 중단 (Halt)
Study
· 2025-08-11
DedicatedProcessor Adder
DedicatedProcessor Adder ✅ top.sv `timescale 1ns / 1ps module top( input logic clk, input logic reset, output logic [3:0] fndCom, output logic [7:0] fndFont ); logic [ 7:0] OutPort; logic clk_10hz; clk_divider U_CLK_DIV ( .clk (clk), .reset (reset), .clk_10hz (clk_10hz) ); DedicatedProcessor_Adder U_DedicatedProcessor_Adder ( .clk (clk_10hz), .reset (reset), .OutPort (OutPort) ); fndController U_fndController ( .clk (clk), .reset (reset), .number (OutPort), .fndCom (fndCom), .fndFont (fndFont) ); endmodule module clk_divider ( input logic clk, input logic reset, output logic clk_10hz ); logic [$clog2(10_000_000)-1:0] div_counter; always_ff @(posedge clk or posedge reset) begin if(reset) begin div_counter <= 0; clk_10hz <= 0; end else begin if(div_counter == 10_000_000 - 1)begin div_counter <= 0; clk_10hz <= 1; end else begin div_counter <= div_counter + 1; clk_10hz <= 0; end end end endmodule ✅ DedicatedProcessor_Adder.sv `timescale 1ns / 1ps module DedicatedProcessor_Adder( input logic clk, input logic reset, output logic [ 7:0] OutPort ); logic SumSrcMuxSel; logic ISrcMuxSel; logic AdderSrcMuxSel; logic SumEn; logic IEn; logic ILe10; logic OutPortEn; DataPath U_DataPath ( .clk (clk), .reset (reset), .SumSrcMuxSel (SumSrcMuxSel), .ISrcMuxSel (ISrcMuxSel), .AdderSrcMuxSel (AdderSrcMuxSel), .SumEn (SumEn), .IEn (IEn), .ILe10 (ILe10), .OutPortEn (OutPortEn), .OutPort (OutPort) ); ControlUnit U_ControlUnit ( .clk (clk), .reset (reset), .ILe10 (ILe10), .SumSrcMuxSel (SumSrcMuxSel), .ISrcMuxSel (ISrcMuxSel), .AdderSrcMuxSel (AdderSrcMuxSel), .SumEn (SumEn), .IEn (IEn), .OutPortEn (OutPortEn) ); endmodule ✅ DataPath.sv `timescale 1ns / 1ps module DataPath( input logic clk, input logic reset, input logic SumSrcMuxSel, input logic ISrcMuxSel, input logic AdderSrcMuxSel, input logic SumEn, input logic IEn, output logic ILe10, input logic OutPortEn, output logic [7:0] OutPort ); logic [7:0] SumSrcMuxOut, ISrcMuxOut; logic [7:0] SumRegOut, IRegOut; logic [7:0] AdderResult, AdderSrcMuxOut; mux_2X1 U_SumSrcMux ( .sel (SumSrcMuxSel), .x0 (0), .x1 (AdderResult), .y (SumSrcMuxOut) ); mux_2X1 U_ISrcMux ( .sel (ISrcMuxSel), .x0 (0), .x1 (AdderResult), .y (ISrcMuxOut) ); register U_SUM_REG ( .clk (clk), .reset (reset), .en (SumEn), .d (SumSrcMuxOut), .q (SumRegOut) ); register U_I_Reg ( .clk (clk), .reset (reset), .en (IEn), .d (ISrcMuxOut), .q (IRegOut) ); comparator U_ILe10 ( .a (IRegOut), .b (8'd10), .lt (ILe10) ); mux_2X1 U_AdderSrcMux ( .sel (AdderSrcMuxSel), .x0 (SumRegOut), .x1 (1), .y (AdderSrcMuxOut) ); adder U_Adder ( .a (AdderSrcMuxOut), .b (IRegOut), .sum (AdderResult) ); register U_OutPort ( .clk (clk), .reset (reset), .en (OutPortEn), .d (SumRegOut), .q (OutPort) ); endmodule ✅ ControlUnit.sv `timescale 1ns / 1ps module ControlUnit( input logic clk, input logic reset, input logic ILe10, output logic SumSrcMuxSel, output logic ISrcMuxSel, output logic AdderSrcMuxSel, output logic SumEn, output logic IEn, output logic OutPortEn ); typedef enum { S0, S1, S2, S3, S4, S5 } state_e; state_e state, next_state; always_ff @(posedge clk or posedge reset) begin if(reset) begin state <= S0; end else begin state <= next_state; end end always_comb begin next_state = state; SumSrcMuxSel = 0; ISrcMuxSel = 0; SumEn = 0; IEn = 0; AdderSrcMuxSel = 0; OutPortEn = 0; case (state) S0:begin SumSrcMuxSel = 0; ISrcMuxSel = 0; SumEn = 1; IEn = 1; AdderSrcMuxSel = 0; OutPortEn = 0; next_state = S1; end S1:begin SumSrcMuxSel = 0; ISrcMuxSel = 0; SumEn = 0; IEn = 0; AdderSrcMuxSel = 0; OutPortEn = 0; if(ILe10) next_state = S2; else next_state = S5; end S2:begin SumSrcMuxSel = 1; ISrcMuxSel = 1; SumEn = 1; IEn = 0; AdderSrcMuxSel = 0; OutPortEn = 0; next_state = S3; end S3:begin SumSrcMuxSel = 1; ISrcMuxSel = 1; SumEn = 0; IEn = 1; AdderSrcMuxSel = 1; OutPortEn = 0; next_state = S4; end S4:begin SumSrcMuxSel = 1; ISrcMuxSel = 1; SumEn = 0; IEn = 0; AdderSrcMuxSel = 0; OutPortEn = 1; next_state = S1; end S5:begin SumSrcMuxSel = 1; ISrcMuxSel = 1; SumEn = 0; IEn = 0; AdderSrcMuxSel = 0; OutPortEn = 0; next_state = S5; end endcase end endmodule
Study
· 2025-08-11
DedicatedProcessor Counter
DedicatedProcessor Counter ✅ DedicatedProcessor Counter `timescale 1ns / 1ps module DedicatedProcessor_Counter( input logic clk, input logic reset, output logic [7:0] OutBuffer ); logic ASrcMuxsel, AEn, OutBufEn, ALt10; logic [$clog2(100_000_000 / 10)-1:0] div_counter; logic clk_10hz; always_ff @(posedge clk or posedge reset) begin if(reset) begin div_counter <= 0; end else begin if(div_counter == 10_000_000 - 1) begin div_counter <= 0; clk_10hz <= 1'b1; end else begin div_counter <= div_counter + 1; clk_10hz <= 0; end end end DataPath U_DataPath ( .clk (clk_10hz), .* ); ControlUnit U_ControlUnit ( .clk (clk_10hz), .* ); endmodule module DataPath( input logic clk, input logic reset, input logic ASrcMuxsel, input logic AEn, output logic ALt10, input logic OutBufEn, output logic [7:0] OutBuffer ); logic [7:0] AdderResult, ASrcMuxOut, ARegOut; mux_2X1 U_ASrcMux ( .sel (ASrcMuxsel), .x0 (8'h0), .x1 (AdderResult), .y (ASrcMuxOut) ); register U_Register ( .clk (clk), .reset (reset), .en (AEn), .d (ASrcMuxOut), .q (ARegOut) ); register U_OutReg ( .clk (clk), .reset (reset), .en (OutBufEn), .d (ARegOut), .q (OutBuffer) ); comparator U_Comparator( .a (ARegOut), .b (8'd10), .lt (ALt10) ); adder U_Adder ( .a (ARegOut), .b (8'd1), .sum (AdderResult) ); /* OutBuf U_OutBuf ( .en (OutBufEn), .x (ARegOut), .y (OutBuffer) ); */ endmodule module register ( input logic clk, input logic reset, input logic en, input logic [7:0] d, output logic [7:0] q ); always_ff @(posedge clk or posedge reset) begin if(reset) begin q <= 0; end else begin if(en) begin q <= d; end end end endmodule module mux_2X1 ( input logic sel, input logic [7:0] x0, input logic [7:0] x1, output logic [7:0] y ); always_comb begin y = 8'b0; case (sel) 1'b0: y = x0; 1'b1: y = x1; endcase end endmodule module adder ( input logic [7:0] a, input logic [7:0] b, output logic [7:0] sum ); assign sum = a + b; endmodule module comparator ( input logic [7:0] a, input logic [7:0] b, output logic lt ); assign lt = a < b; endmodule module OutBuf ( input logic en, input logic [7:0] x, output logic [7:0] y ); assign y = en ? x : 8'bx; endmodule module ControlUnit( input logic clk, input logic reset, input logic ALt10, output logic ASrcMuxsel, output logic AEn, output logic OutBufEn ); typedef enum { S0, S1, S2, S3, S4 } state_e; state_e state, next_state; always_ff @(posedge clk or posedge reset) begin if(reset) begin state <= S0; end else begin state <= next_state; end end always_comb begin next_state = state; ASrcMuxsel = 0; AEn = 0; OutBufEn = 0; case (state) S0:begin ASrcMuxsel = 0; AEn = 1; OutBufEn = 0; next_state = S1; end S1:begin ASrcMuxsel = 1; AEn = 0; OutBufEn = 0; if(ALt10) next_state = S2; else next_state = S4; end S2:begin ASrcMuxsel = 1; AEn = 0; OutBufEn = 1; next_state = S3; end S3:begin ASrcMuxsel = 1; AEn = 1; OutBufEn = 0; next_state = S1; end S4:begin ASrcMuxsel = 1; AEn = 0; OutBufEn = 0; next_state = S4; end endcase end endmodule
Study
· 2025-08-11
Day3
DAY3 ✅ UART (Universal Asynchronous Receiver/Transmitter) 1. 비동기 통신의 정의 동기(Synchronous) 송수신 장치가 동일한 클록 신호를 공유 데이터와 클록이 함께 전송됨 예: SPI, I2C 비동기(Asynchronous) 송수신 장치가 클록 신호를 공유하지 않음 각자 내부 타이머로 비트 타이밍을 맞춤 예: UART 2. UART가 비동기인 이유 클록 라인이 없음 UART는 TX와 RX 두 선만 사용 클록 신호 없이 데이터만 전송 Start/Stop 비트로 동기화 데이터 프레임 시작: Start bit(0) 데이터 프레임 종료: Stop bit(1) 수신 측은 Start bit 감지 후 내부 타이머로 비트 샘플링 Baud Rate로 시간 동기화 속도, bps, 주파수, 시간 정해놓은 시간마다 데이터를 주고 받음 송신 측과 수신 측이 동일한 baud rate로 약속 클록이 없으므로, 오차 범위 내에서만 정상 수신 가능 3. 동작 원리 Idle 상태 라인은 기본적으로 HIGH(1) 상태 Start Bit 통신 시작 시 1비트 길이의 LOW(0) 신호 전송 Data Bits LSB부터 순차적으로 전송 (일반적으로 8비트) Parity Bit (옵션) 데이터 전송 중 오류 검출용 (Even, Odd) 데이터의 1의 개수가 짝수, 홀수에 맞춰서 동작 안 쓰는 이유는❓ Stop Bit 1비트 길이의 HIGH(1) 신호로 전송 종료 표시 수신 측 스타트 비트를 감지 후 정해진 baud rate에 맞춰 비트 샘플링 Frame 1~5번까지의 과정을 1프레임 ✅ SPI (Universal Asynchronous Receiver/Transmitter) ✅ 비교 (UART vs SPI vs I2C) 구분 UART SPI I2C 동기방식 비동기 동기 동기 관계 수 1:1 1:N N:N 선 개수 2개 (TX, RX) 4개 (MISO, MOSI, SCK, CS) 2개 (SCL, SDA) 속도 중간 (bps~Mbps) 매우 빠름 (수십 Mbps) 중간 (100k~3.4Mbps) 장점 간단, 저전력 빠름, 풀듀플렉스 다중 장치 연결 용이
Study
· 2025-08-08
UART
DAY2 ✅ 버튼 구조 버튼을 누를 때, 노이즈나 진동에 의해 짧은 시간 내에 ON/OFF가 반복됨 이 현상을 바운스(Bounce) 라고 하며, 디바운싱(Debounce) 처리가 필요 ✅ Shift Register를 이용한 디바운싱 💡 Shift Register 역할 버튼 입력(in_data)을 8클럭 동안 시프트 저장 sh_reg 값이 전부 1이면, 버튼이 안정적으로 눌림 상태라고 판단 ✅ shift_register 모듈 코드 module shift_register ( input logic clk, input logic reset, input logic in_data, output logic [7:0] out_data ); always_ff @(posedge clk or posedge reset) begin if(reset) begin out_data <= 0; end else begin out_data <= {in_data, out_data[7:1]}; // right shift //out_data <= {out_data[6:0], in_data}; // left shift end end endmodule ✅ 엣지 검출기 (Edge Detector) 🔍 개요 디바운싱된 버튼 입력(debounce)의 변화를 감지하여 상승 엣지(rising_edge) 하강 엣지(falling_edge) 또는 둘 다(both_edge)를 검출하는 회로 ✅ 동작 원리 edge_reg[1] ← 이전 상태 edge_reg[0] ← 현재 상태 변화 조건 - 상승 엣지: 이전 0 → 현재 1 - 하강 엣지: 이전 1 → 현재 0 - 둘 다: 둘 중 하나라도 발생 시 assign debounce = &sh_reg; //assign out_button = debounce; logic [1:0] edge_reg; always_ff @(posedge clk or posedge reset) begin if(reset) begin edge_reg <= 0; end else begin edge_reg[0] <= debounce; edge_reg[1] <= edge_reg[0]; end end assign rising_edge = edge_reg[0] & ~edge_reg[1]; assign falling_edge = ~edge_reg[0] & edge_reg[1]; assign both_edge = rising_edge | falling_edge; ✅ 전체 구조 (Button Detector) `timescale 1ns / 1ps module button_detector( input logic clk, input logic reset, input logic in_button, output logic rising_edge, output logic falling_edge, output logic both_edge ); logic clk_1khz; logic debounce; logic [7:0] sh_reg; logic [$clog2(100000)-1:0] div_counter; always_ff @(posedge clk or posedge reset) begin if(reset)begin div_counter <= 0; clk_1khz <= 0; end else begin if(div_counter == 100000 - 1)begin clk_1khz <= 1; div_counter <= 0; end else begin div_counter <= div_counter + 1; clk_1khz <= 0; end end end shift_register u_shift_register( .clk (clk_1khz), .reset (reset), .in_data (in_button), .out_data (sh_reg) ); assign debounce = &sh_reg; //assign out_button = debounce; logic [1:0] edge_reg; always_ff @(posedge clk or posedge reset) begin if(reset) begin edge_reg <= 0; end else begin edge_reg[0] <= debounce; edge_reg[1] <= edge_reg[0]; end end assign rising_edge = edge_reg[0] & ~edge_reg[1]; assign falling_edge = ~edge_reg[0] & edge_reg[1]; assign both_edge = rising_edge | falling_edge; endmodule module shift_register ( input logic clk, input logic reset, input logic in_data, output logic [7:0] out_data ); always_ff @(posedge clk or posedge reset) begin if(reset) begin out_data <= 0; end else begin out_data <= {in_data, out_data[7:1]}; // right shift //out_data <= {out_data[6:0], in_data}; // left shift end end endmodule ✅ 검증 (Test Bench) 클래스 정의 (transaction) rand bit button : 랜덤 생성 1비트 버튼 값 function bit run_random() : 현재 button 값을 반환 class transaction; rand bit button; function bit run_random(); return button; endfunction endclass 초기화 clk = 0, reset = 1 10ns 후 reset = 0 in_button = 0으로 초기화, 20ns 대기 버튼 누름 (Push) in_button = 1로 변경 60회 반복: tr.randomize()로 버튼 값 랜덤 생성 in_button에 랜덤 값 적용 1ns 대기 in_button = 1로 고정, 150ns 대기 // push button in_button = 1; for(int i= 0; i < 60; i++)begin tr.randomize(); in_button = tr.run_random(); #1; end in_button = 1; #150; 버튼 놓음 (Release) in_button = 0으로 변경 30회 반복: 랜덤 버튼 값 생성 및 적용 1ns 대기 in_button = 0로 고정, 100ns 대기 in_button = 0; for(int i= 0; i < 30; i++)begin tr.randomize(); in_button = tr.run_random(); #1; end in_button = 0; #100; $finish; ✅ 주요 특징 버튼 입력 바운스(Bounce) 효과를 랜덤 패턴으로 구현 상승/하강/양쪽 에지 검출 기능 검증 클래스 기반 랜덤 입력 생성으로 테스트 확장성 확보
Study
· 2025-08-08
Day2
DAY2 ✅ 조합논리회로 vs 순차논리회로 항목 조합논리회로 순차논리회로 동작 기준 현재 입력에만 의존 현재 입력 + 과거 상태(레지스터 등) 클록 사용 여부 클록 사용 안 함 클록 사용 (동기식 설계) 메모리 기능 없음 있음 (상태 저장 가능) 예시 AND, OR, MUX 등 FSM, 레지스터, 카운터, 메모리 등 💡 조합 논리는 빠르지만 타이밍 제어가 어렵고 글리치(glitch) 발생 가능성 있음. 💡 순차 논리는 동기식으로 안정적이고 제어가 쉬움. ✅ Latch 와 Flip-Flop Latch 클록 신호 없이 동작 입력 신호에 민감하게 반응 메모리 기능 있음 Flip-Flop 클록 엣지(상승/하강)에 반응 엣지 트리거 방식으로 동작 더 안정적인 메모리 소자 ✅ SR Latch Q와 /Q는 항상 반대여야 함. 상태 설명: S R Q(next) 설명 0 0 유지 이전 상태 유지 0 1 0 Reset 상태 1 0 1 Set 상태 1 1 불안정 금지 상태 (발진 가능) ✅ D Latch 입력을 단일화하여 S= D, R = D’ 형태로 구성 Gate 신호가 enable 역할 클록에 민감 (레벨 트리거 방식) ✅ Gated D Latch & D Flip-Flop Gated D Latch: Gate 신호가 high일 때만 입력 허용 D Flip-Flop (Master-Slave 구조) Master: 클록 Low일 때 입력 저장 Slave: 클록 High일 때 출력 전달 상승엣지 또는 하강엣지에서만 출력 변화 (엣지 트리거) ✅ 메타스테이블(Metastable) 클록 엣지 시점에 입력(D)이 변하면 출력이 일정 시간 동안 불안정 상태에 빠질 수 있음 이를 메타스테이블 현상이라 함 중요 Timing Spec 항목 설명 Setup Time 클록 엣지 이전에 D 입력이 안정적으로 유지되어야 하는 최소 시간 Hold Time 클록 엣지 이후에도 D 입력이 유지되어야 하는 최소 시간 ✅ Synchronizer 비동기 입력을 동기화하는 구조 D Flip-Flop 2개 이상 직렬 연결 첫 번째 F/F: 신호 수신 두 번째 F/F: 안정된 출력 생성 메타스테이블 방지를 위한 대표적 설계 기법 ✅ 전파 지연 시간 (Propagation Delay) 클록 → 출력까지 걸리는 시간 조합 회로의 깊이에 비례 예: 곱셈 연산이 많은 FFT 회로는 레지스터 삽입 필요 📌 데이터시트에서는 clock-to-Q delay, t_pd, t_co 등으로 명시됨 ✅ 글리치(Glitch) 조합 논리에서 입력이 동시에 변하지 않으면, 전파 지연 차이로 인해 일시적인 오류 출력 발생 가능 클록 엣지 직전 글리치 발생 시 시스템 오동작 가능성 있음 → 복잡한 조합 논리는 피하고, 순차 회로로 나누어 설계하는 것이 안전함 ✅ 파이프라이닝 기법 연산 중간에 레지스터 삽입으로 클록 주기를 분할 복잡한 연산을 여러 클록 사이클에 나누어 처리 가능 조합 논리 길이를 줄여 글리치 방지 및 클록 여유 확보 ✅ AMBA APB 예시 AMBA APB 프로토콜도 메타스테이블과 클록 도메인 이슈를 고려하여 설계됨 동기화 구조 반영 필요 ✅ 보완 및 추가 설명 타이밍 분석은 FPGA/ASIC 설계의 핵심 Setup/Hold violation은 기능적 문제 유발 CDC (Clock Domain Crossing) 설계에서는 synchronizer 필수 글리치를 줄이기 위한 방법 입력 신호 동기화 레지스터 삽입 (타이밍 여유 확보) 순차 논리 설계에서의 핵심 원칙 항상 클록 경계 기준으로 상태 변화 설계 조합 논리는 최소화 타이밍 분석은 FPGA/ASIC 설계의 핵심 요소 Setup / Hold 타이밍 위반이 발생하면 회로 동작이 비정상적으로 될 수 있음 타이밍 제약 조건을 만족하도록 설계하고, STA(Static Timing Analysis) 필수 수행 CDC (Clock Domain Crossing) 설계 서로 다른 클록 도메인을 오갈 때 메타스테이블 위험 해결 방법: 2단 이상 D Flip-Flop 직렬 연결 (Synchronizer) Handshake 또는 FIFO 구조 사용 글리치(Glitch) 줄이기 위한 방법 입력 신호는 반드시 클록 도메인에 동기화 조합 논리 길이가 길 경우 중간에 레지스터 삽입하여 안정화 하나의 클록 사이클 내에 연산이 끝나도록 설계 순차 논리 설계 핵심 원칙 모든 상태 변화는 클록 엣지 기준으로 결정되어야 함 조합 논리는 최소화하여 타이밍 복잡도를 줄이고, 유지/확장 가능한 설계 지향
Study
· 2025-08-07
Button Detector
DAY2 ✅ 버튼 구조 버튼을 누를 때, 노이즈나 진동에 의해 짧은 시간 내에 ON/OFF가 반복됨 이 현상을 바운스(Bounce) 라고 하며, 디바운싱(Debounce) 처리가 필요 ✅ Shift Register를 이용한 디바운싱 💡 Shift Register 역할 버튼 입력(in_data)을 8클럭 동안 시프트 저장 sh_reg 값이 전부 1이면, 버튼이 안정적으로 눌림 상태라고 판단 ✅ shift_register 모듈 코드 module shift_register ( input logic clk, input logic reset, input logic in_data, output logic [7:0] out_data ); always_ff @(posedge clk or posedge reset) begin if(reset) begin out_data <= 0; end else begin out_data <= {in_data, out_data[7:1]}; // right shift //out_data <= {out_data[6:0], in_data}; // left shift end end endmodule ✅ 엣지 검출기 (Edge Detector) 🔍 개요 디바운싱된 버튼 입력(debounce)의 변화를 감지하여 상승 엣지(rising_edge) 하강 엣지(falling_edge) 또는 둘 다(both_edge)를 검출하는 회로 ✅ 동작 원리 edge_reg[1] ← 이전 상태 edge_reg[0] ← 현재 상태 변화 조건 - 상승 엣지: 이전 0 → 현재 1 - 하강 엣지: 이전 1 → 현재 0 - 둘 다: 둘 중 하나라도 발생 시 assign debounce = &sh_reg; //assign out_button = debounce; logic [1:0] edge_reg; always_ff @(posedge clk or posedge reset) begin if(reset) begin edge_reg <= 0; end else begin edge_reg[0] <= debounce; edge_reg[1] <= edge_reg[0]; end end assign rising_edge = edge_reg[0] & ~edge_reg[1]; assign falling_edge = ~edge_reg[0] & edge_reg[1]; assign both_edge = rising_edge | falling_edge; ✅ 전체 구조 (Button Detector) `timescale 1ns / 1ps module button_detector( input logic clk, input logic reset, input logic in_button, output logic rising_edge, output logic falling_edge, output logic both_edge ); logic clk_1khz; logic debounce; logic [7:0] sh_reg; logic [$clog2(100000)-1:0] div_counter; always_ff @(posedge clk or posedge reset) begin if(reset)begin div_counter <= 0; clk_1khz <= 0; end else begin if(div_counter == 100000 - 1)begin clk_1khz <= 1; div_counter <= 0; end else begin div_counter <= div_counter + 1; clk_1khz <= 0; end end end shift_register u_shift_register( .clk (clk_1khz), .reset (reset), .in_data (in_button), .out_data (sh_reg) ); assign debounce = &sh_reg; //assign out_button = debounce; logic [1:0] edge_reg; always_ff @(posedge clk or posedge reset) begin if(reset) begin edge_reg <= 0; end else begin edge_reg[0] <= debounce; edge_reg[1] <= edge_reg[0]; end end assign rising_edge = edge_reg[0] & ~edge_reg[1]; assign falling_edge = ~edge_reg[0] & edge_reg[1]; assign both_edge = rising_edge | falling_edge; endmodule module shift_register ( input logic clk, input logic reset, input logic in_data, output logic [7:0] out_data ); always_ff @(posedge clk or posedge reset) begin if(reset) begin out_data <= 0; end else begin out_data <= {in_data, out_data[7:1]}; // right shift //out_data <= {out_data[6:0], in_data}; // left shift end end endmodule ✅ 검증 (Test Bench) 클래스 정의 (transaction) rand bit button : 랜덤 생성 1비트 버튼 값 function bit run_random() : 현재 button 값을 반환 class transaction; rand bit button; function bit run_random(); return button; endfunction endclass 초기화 clk = 0, reset = 1 10ns 후 reset = 0 in_button = 0으로 초기화, 20ns 대기 버튼 누름 (Push) in_button = 1로 변경 60회 반복: tr.randomize()로 버튼 값 랜덤 생성 in_button에 랜덤 값 적용 1ns 대기 in_button = 1로 고정, 150ns 대기 // push button in_button = 1; for(int i= 0; i < 60; i++)begin tr.randomize(); in_button = tr.run_random(); #1; end in_button = 1; #150; 버튼 놓음 (Release) in_button = 0으로 변경 30회 반복: 랜덤 버튼 값 생성 및 적용 1ns 대기 in_button = 0로 고정, 100ns 대기 in_button = 0; for(int i= 0; i < 30; i++)begin tr.randomize(); in_button = tr.run_random(); #1; end in_button = 0; #100; $finish; ✅ 주요 특징 버튼 입력 바운스(Bounce) 효과를 랜덤 패턴으로 구현 상승/하강/양쪽 에지 검출 기능 검증 클래스 기반 랜덤 입력 생성으로 테스트 확장성 확보
Study
· 2025-08-07
Day1
DAY3
Study
· 2025-08-06
<
>
Touch background to close