Analog 회로 최적화를 소개하는 간단한 데모 예시를 만들고 싶어.

Analog 회로 최적화를 소개하는 간단한 데모 예시를 만들고 싶어.

좋아! “아날로그 회로 최적화”를 아주 가볍고 직관적으로 보여줄 수 있는 데모를 바로 만들어봤어. 주제는 RC 저역통과 필터의 R, C를 자동으로 골라 목표 차단주파수(fc)를 맞추는 최적화 야. 아래를 따라가면 끝.

데모 개요 (step-by-step)

  1. 문제 설정 : 목표 fc(예: 1 kHz)를 만족하도록 R·C를 고른다.

  2. 목적함수 :

    • fc 오차(로그 스케일) + (R가 너무 큰 경우 페널티) + (C가 너무 큰 경우 페널티).

    • R이 너무 크면 열잡음/구동성 이슈, C가 너무 크면 비용/면적 이슈가 증가한다는 감을 주려는 장치.

  3. 설계 변수 : 표준 E-series(저항 E24, 커패시터 E12) 후보 안에서 전수 탐색(간단·빠름).

  4. 강건성 확인 : R±5%, C±10% 공차에서 fc 수율(±5% 스펙)을 몬테카를로로 추정.

  5. 시각화 : 보드 플롯과 fc 분포 히스토그램으로 결과 확인.

위의 코드 셀을 바로 실행해서 결과/그래프까지 확인할 수 있게 했어. 기본 파라미터는 fc=1 kHz , R 1k~1MΩ , C 100 pF~1 µF 로 잡았고, 실행 결과 예시는 대략 아래와 같아:

  • 선택된 R ≈ 1.6 kΩ , C ≈ 0.1 µF → fc ≈ 995 Hz (오차 -0.53%)

  • 공차 포함 수율 ≈ 50.5% (스펙: ±5%)

어떻게 활용/확장하면 좋을까?

  • 목표 바꾸기 : 코드 맨 위 target_fc_hz만 바꾸면 끝(예: 2 kHz, 10 kHz 등).

  • 설계 철학 바꾸기 : alpha, beta, gamma 가중치를 조절해서

    • beta↑ → R 줄이도록 유도(열잡음, 구동 여유 강조),

    • gamma↑ → C 줄이도록 유도(비용/면적 강조).

  • 사양/공차 바꾸기 : tol_R, tol_C, spec_fc_rel을 조정해 수율 민감도 확인.

  • 제약 추가 : 소스/부하 임피던스, 허용 전류/전압, 커패시터 종류(세라/탄탈/전해)별 최대값 등 현실 제약을 반영해 필터링 가능.

  • 다음 단계 :

    • 2차(다양한 토폴로지)로 확장하고 Q, 위상 여유 등 포함.

    • 간단한 SPICE 연동(예: ngspice .meas)으로 측정값 기반 최적화로 전환.

    • 강건 최적화 : 수율을 목적함수에 직접 포함(예: -yield 최대화 또는 페널티화).

필요하면 이 데모를 op-amp 이득 단계 최적화(목표 이득/대역/슬루율 제약)나 전압 분배기 최소 전력 + 목표 오차 같은 더 짧은 예제로 바꿔 줄 수도 있어. 원하는 회로/사양을 말해주면, 위 템플릿 그대로 맞춰서 돌려볼게!

응 전압 분배기로 해줘 그리고 finesim을 쓸 수 있단 가정하에 시뮬레이션을 돌릴거라서 저런 코드는 필요없어 대신에 1. finesim netlist 2. 최적화할 변수(parameter) 3. 측정 대상(measure) 를 확실히 해줬으면 좋겠어

좋아—전압 분배기(Voltage Divider)를 예제로, FineSim(HSPICE 호환)으로 곧장 돌릴 수 있게 아래 3가지를 딱 정리했어.


1) FineSim Netlist (복사-붙여넣기 실행용)

아래 deck은 소스 직렬 임피던스(RS) , 분배기(R1, R2) , 부하(RL)까지 포함한 현실적인 전압 분배기이며,

  • (A) OP에서 정밀도/소모 전류/전력 측정,

  • (B) 소스 전압 변화에 대한 Line Regulation ,

  • (C) 부하 변화에 대한 Load Regulation
    을 각각 측정하도록 분리해 두었어. 각 블록은 필요한 것만 남기고 나머지는 주석 처리 하고 돌리면 돼.

spice

*------------------------------------------------------------
* Voltage Divider Optimization Demo (FineSim/HSPICE compatible)
*------------------------------------------------------------
.option post=2 measform=1
*.option nomod         * (필요시) 모델 최소 출력

* ----- Parameters (최적화 변수 및 스펙) -----
.param VSUP      = 3.3        * 공급 전압 [V]
.param V_SPEC    = 1.0        * 목표 출력 전압 [V]
.param RS        = 50         * 소스 직렬 저항 [Ohm]  (예: 신호원/레귤레이터 출력 임피던스)
.param RL        = 100k       * 부하 [Ohm]

* === 최적화 대상 변수(안) A: R1, R2 직접 최적화 ===
.param R1        = 10k
.param R2        = 22k

* === 최적화 대상 변수(안) B: 총저항 RT와 비율 K를 최적화 (R1,R2 파생) ===
* .param RT     = 100k        * R1+R2 (전력/노이즈/면적 트레이드오프)
* .param K      = 0.25        * 이상적 비율 = Vout/Vin (0<K<1)
* .param R1     = 'RT*(1-K)'
* .param R2     = 'RT*K'

* ----- Circuit -----
V1   VIN_SRC  0  DC 'VSUP'
RSRC VIN_SRC  VIN 'RS'
RUP  VIN      VOUT 'R1'
RDN  VOUT     0   'R2'
RLOAD VOUT    0   'RL'

* ============================================================
* (A) OP 기반 측정: 정확도/소스 전류/전력
* ============================================================
.op

* 출력/오차
.measure DC  VOUT      param='v(VOUT)'
.measure DC  VERR      param='v(VOUT)-V_SPEC'
.measure DC  VERR_ABS  param='abs(v(VOUT)-V_SPEC)'
.measure DC  RATIO     param='v(VOUT)/VSUP'      * 이상적으론 ~ R2/(R1+R2)

* 소스 전류/전력 (SPICE 부호 관례: I(V1) >0이면 소스에 유입)
.measure DC  IIN       param='-I(V1)'            * 소스가 공급하는 전류 [A]
.measure DC  PIN       param='(-I(V1))*VSUP'     * 총 소비 전력 [W]

* 부품 전류(참고)
.measure DC  I_R1      param='(v(VIN)-v(VOUT))/R1'
.measure DC  I_R2      param='v(VOUT)/R2'
.measure DC  I_RL      param='v(VOUT)/RL'

* ============================================================
* (B) Line Regulation: Vin 변화에 대한 Vout 민감도
*    - 필요시만 사용: 이 블록만 남기고 (A),(C)는 주석 처리
* ============================================================
*.dc V1 3.0 3.6 0.3
*.measure DC  VOUT_MIN  FIND v(VOUT) AT=3.0
*.measure DC  VOUT_MAX  FIND v(VOUT) AT=3.6
*.measure DC  LINE_REG  param='(VOUT_MAX - VOUT_MIN)/(3.6 - 3.0)'
*  단위: V/V  (원하면 %/V로 보고 싶으면 100*... 사용)

* ============================================================
* (C) Load Regulation: RL 변화(부하 전류 증가)에 따른 Vout 민감도
*    - 필요시만 사용: 이 블록만 남기고 (A),(B)는 주석 처리
*    - FineSim/HSPICE: .dc param <name> <start> <stop> <step>
* ============================================================
*.dc param RL 20k 1Meg 20k
*.measure DC  VOUT_LIGHT  FIND v(VOUT) AT=1e6
*.measure DC  VOUT_HEAVY  FIND v(VOUT) AT=20e3
*.measure DC  LOAD_REG    param='(VOUT_LIGHT - VOUT_HEAVY)/VOUT_LIGHT'
*  단위: 상대 변화(무차원). 필요시 V/decade 등으로 재정의 가능.

.end

실행 팁: (A),(B),(C)를 동시에 돌리면 분석이 겹치므로 , 필요한 블록만 남기고 나머지는 *로 주석 처리해서 실행해줘.
측정 결과는 FineSim/HSPICE의 .measure 결과 파일(예: .mt#)로 나와.


2) 최적화할 변수 (Parameter)

두 가지 접근 중 원하는 방식 하나 를 택해:

A. R1, R2 직접 최적화

  • 설계변수 : R1, R2

  • 권장 범위 (예시):

    • 1 kΩ ≤ R1, R2 ≤ 1 MΩ

    • 총저항 R1+R2에 추가 제약: 20 kΩ ≤ R1+R2 ≤ 2 MΩ

      • (너무 작으면 전력 증가/소스 부하 과중, 너무 크면 노이즈/오프셋 민감성 증가)
  • E-series 제약 이 필요하면, 외부 스크립트에서 라운딩(E24/E96) 후 재측정 루프를 돌리면 좋아.

B. 파생 변수로 단순화 (추천)

  • 설계변수 :

    • RT = R1+R2 (전력/노이즈/면적을 좌우)

    • K = R2/(R1+R2) ≈ Vout/Vin (목표 분배 비율)

  • 파생관계 :

    • R1 = RT*(1-K), R2 = RT*K
  • 권장 범위(예시) :

    • 10 kΩ ≤ RT ≤ 1 MΩ

    • 0.1 ≤ K ≤ 0.9 (양 끝단은 민감도↑라 너무 치우치지 않게)


3) 측정 대상 (Measure)

최적화의 목표/제약 으로 바로 쓸 수 있게 이름을 정리했어.
(모두 netlist의 .measure로 이미 정의되어 있음)

정확도 관련

  • VOUT : 출력 전압

  • VERR_ABS : |VOUT - V_SPEC|최소화 (예: ≤ 10 mV)

전력/전류 관련

  • IIN : 소스가 공급하는 전류 → 최소화

  • PIN : 총 소비 전력 → 최소화

레귤레이션(선택 측정)

  • LINE_REG : ΔVout/ΔVin절대값 최소화 (라인 변동 민감도)

  • LOAD_REG : (Vout_light−Vout_heavy)/Vout_light절대값 최소화 (부하 변동 민감도)


권장 최적화 포맷(예시)

  • 목표 :
min⁡ w1⋅VERR_ABS + w2⋅PIN + w3⋅∣LINE_REG∣ + w4⋅∣LOAD_REG∣\min \ \ \ w_1 \cdot \text{VERR\_ABS} \ +\ w_2 \cdot \text{PIN} \ +\ w_3 \cdot \text{LINE\_REG} \ +\ w_4 \cdot \text{LOAD\_REG} min w1​⋅VERR_ABS + w2​⋅PIN + w3​⋅∣LINE_REG∣ + w4​⋅∣LOAD_REG∣

(가중치 wiw_iwi​는 프로젝트 우선순위에 맞춰 선택. 처음엔 w1w_1w1​을 크게 두고, 성공 후 w2w_2w2​↑로 전력 줄이는 2단계 접근 권장.)

  • 제약(예시) :

    • VERR_ABS ≤ 0.01 V (±10 mV 스펙)

    • IIN ≤ 100 μA (저전력 요구 시)

    • RSRL은 시스템에서 주어진 값(혹은 워스트케이스)으로 고정


실전 팁

  • 실제 시스템의 RS(소스 임피던스), RL(부하)을 워스트 케이스 로 넣고 최적화하면, 이식성이 좋음.

  • 공차(±1~5%)를 고려하려면, .alter로 R1/R2에 스케일 파라미터(S1,S2)를 둬서 0.95/1.00/1.05 케이스를 배치 측정 하고, 최적화 목표에 “최악의 VERR_ABS”를 포함시키면 간단한 강건 최적화가 됨.

원하는 목표 전압/전력 한계나 레귤레이션 한계치가 있다면 알려줘. 그 값들로 V_SPEC, 제약/가중치 추천 세트까지 바로 맞춰서 덱을 더 다듬어줄게.

이 상황에서 R1, R2 변수의 유형과 범위를 정해줘. 현실의 제약 사항을 고려해서 Continuous, Incremental, Discrete 변수 중 뭐로 할지, 범위와 Step(있다면)을 정해주면 좋을 것 같다

좋아—“전압 분배기 + FineSim” 상황에서 R1, R2 변수의 유형/범위/스텝 을 현실 제약(부하 RL=100 kΩ, Vin=3.3 V, Vout=1.0 V 목표)까지 고려해 바로 쓸 수 있는 3가지 프로파일 로 정리했어. (생산 관점 → 시뮬/최적화 편의 순으로)


권장 1) Discrete (E-series, 생산 지향) ✅

왜 Discrete? 실제 부품은 E-series(공차 1%면 E96 등)로만 존재. 최적화 결과가 곧바로 BOM으로 이어짐.

  • 분배 비율 K=Vout/Vin≈1/3.3≈0.303K = V_\text{out}/V_\text{in} \approx 1/3.3 \approx 0.303K=Vout​/Vin​≈1/3.3≈0.303

  • 이상적 관계: R1=R2⋅1−KK≈2.30 R2R_1 = R_2\cdot\frac{1-K}{K} \approx 2.30\,R_2R1​=R2​⋅K1−K​≈2.30R2​

정확도 우선(버퍼 없음, RL=100 kΩ 로딩오차 ≤≈1% 목표)

  • 핵심 규칙 : 로딩오차를 1%대 유지하려면 R 2≲RL/100≈1.0 kΩR_2 \lesssim RL/100 \approx 1.0\text{ kΩ}R2​≲RL/100≈1.0 kΩ

  • 스펙

    • R2 (Discrete, E96 1%) : 680 Ω ~ 1.2 kΩ

    • R1 (Discrete, E96 1%) : R1≈2.30R2R_1 \approx 2.30 R_2R1​≈2.30R2​ → 1.6 kΩ ~ 3.0 kΩ

    • 총저항 RT=R1+R2R_T=R_1+R_2RT​=R1​+R2​: ≈ 2.3 kΩ ~ 4.2 kΩ (분배 전류 0.8~1.4 mA @3.3 V)

  • 스텝 : E96 표준치(해당 데케이드의 E96 값만 허용).

    • FineSim에선 최적화 루프가 Discrete를 못 다루면 허용 리스트 를 외부에서 공급(.step list)하거나 스크립트로 enumerate.

예) R2 후보: {681, 715, 750, 787, 825, 866, 909, 953, 1000, 1050, 1100, 1150} Ω
각 R2에 대해 R1을 2.30R22.30 R_22.30R2​ 근처의 E96 값으로 스냅(예: 2.00k, 2.05k, 2.10k, 2.21k…).


옵션 2) Discrete(균형형, 전류/정확도 타협)

로딩오차 2~6% 정도 허용 하고 전류를 줄이고 싶을 때.

  • R2 (E96 1%) : 1.5 kΩ ~ 10 kΩ

  • R1 (E96 1%) : ≈ 3.5kΩ 23kΩ \approx 3.5 kΩ ~ 23 kΩ≈3.5kΩ 23kΩ

  • R TR_TRT​: 5 kΩ ~ 33 kΩ (분배 전류 ≈ 100~660 μA)

  • 스텝 : E96

  • 주의: RL=100 kΩ와 병렬 효과로 목표치 대비 수 % 낮게 나오므로,

    • 목표를 미리 약간 상향 보정 해서 설계하거나,

    • 후단에 버퍼(옵앰프 팔로어)를 추가하면 오차 크게 개선됨.


옵션 3) Incremental(로그 스텝, 탐색/최적화 편의)

최적화기가 연속→스냅 이 번거롭거나, Discrete 리스트가 너무 커질 때 유용.

  • 아이디어 : 로그 스케일 2% 스텝(≈E48)로 그리드 탐색 → 최종에 E96 스냅

  • R2 (Incremental) : 680 Ω ~ 10 kΩ, 스텝 ×1.02

    • 시퀀스: 680 → 694 → 708 → … → 10 kΩ
  • R1 (Incremental) : 범위를 R1≈2.30R2R_1 \approx 2.30 R_2R1​≈2.30R2​ 주변으로 잡되 넉넉히

    • 1.5 kΩ ~ 30 kΩ, 스텝 ×1.02
  • 최종 생산치 반영 : 최적점 근방을 E96 근사치 로 스냅하고 다시 측정(.measure 확인).


언제 Continuous?

  • 초기 감도 스캔 용도로만 추천. 현실 부품 스냅이 따로 필요해 번거로움.

  • 만약 쓴다면:

    • R2 (Continuous) : 500 Ω ~ 33 kΩ

    • R1 (Continuous) : 1.2 kΩ ~ 75 kΩ

    • 단, RL=100 kΩ이면 정확도 요구가 높을수록 R2 상한을 1 kΩ 부근으로 강하게 제한 해야 함(로딩오차 때문).


안전성 체크(간단 산출)

  • 전력/전압 : Vin=3.6 V worst 가정, RT≥2.3 kΩR_T \ge 2.3\text{ kΩ}RT​≥2.3 kΩ일 때

    • 분배 전류 ≤ 1.6 mA,

    • PR1=I2R1≲P_{R1}=I^2R_1 \lesssimPR1​=I2R1​≲ 수 mW 수준 → 0603 1/10W 여유 충분.

  • 노이즈 : 4kTRT\sqrt{4kTR_T}4kTRT​​ → RT가 작을수록 유리(정확도 우선 프로파일과 정합).


한 줄 추천(지금 상황 기준)

  • R1, R2는 “Discrete(E96, 1%)”로 운용

  • R2: 680 Ω ~ 1.2 kΩ (E96), R1: 1.6 kΩ ~ 3.0 kΩ (E96)

  • 최적화 후 결과를 E96 스냅 → .measure 재확인(Vout, 전류, 레귤레이션).

원하면 위 범위를 .step list 형태(예: E96 후보 20~40개)로 바로 붙여 쓰는 스니펫도 만들어줄게.

.op 시뮬레이션 말고 .dc 를 사용하도록 해줄 수 있어?

좋지! .op 대신 .dc만 사용 하도록 덱을 정리했어. 아래 3가지만 그대로 쓰면 돼.


1) FineSim Netlist (.dc 전용)

spice

*------------------------------------------------------------
* Voltage Divider Optimization Demo (FineSim/HSPICE compatible)
*   - 모든 해석은 .dc 기반
*------------------------------------------------------------
.option post=2 measform=1

* ===== 파라미터(최적화 변수/환경) =====
.param VSUP   = 3.3          * 공급전압 [V]
.param V_SPEC = 1.0          * 목표 출력 [V]
.param RS     = 50           * 소스 직렬저항 [Ohm]
.param RL     = 100k         * 부하 [Ohm]

* === 최적화 변수 (안 A: R1, R2 직접) ===
.param R1     = 1.80k        * 초기값(옵티마이저가 업데이트)
.param R2     = 820          * 초기값(옵티마이저가 업데이트)

* === 최적화 변수 (안 B: RT, K 사용) ===
* .param RT   = 3.0k         * R1+R2
* .param K    = 0.303        * R2/(R1+R2) ≈ Vout/Vin
* .param R1   = 'RT*(1-K)'
* .param R2   = 'RT*K'

* ===== 회로 =====
V1    VIN_SRC  0  DC 'VSUP'
RSRC  VIN_SRC  VIN  'RS'
RUP   VIN      VOUT 'R1'
RDN   VOUT     0    'R2'
RLOAD VOUT     0    'RL'

* ============================================================
* (A) Bias 점에서의 측정: .dc(더미 파라미터)로 단일점 해석
*   - .op을 쓰지 않고 .dc만으로 VOUT, 오차, 전류/전력 측정
* ============================================================
.dc param BIAS 0 0 1
.measure DC  VOUT_A      param='v(VOUT)'
.measure DC  VERR_A      param='v(VOUT)-V_SPEC'
.measure DC  VERR_ABS_A  param='abs(v(VOUT)-V_SPEC)'
.measure DC  IIN_A       param='-I(V1)'              * 소스 공급전류(+)
.measure DC  PIN_A       param='(-I(V1))*VSUP'       * 전체소비전력
.measure DC  RATIO_A     param='v(VOUT)/VSUP'
.measure DC  I_R1_A      param='(v(VIN)-v(VOUT))/R1'
.measure DC  I_R2_A      param='v(VOUT)/R2'
.measure DC  I_RL_A      param='v(VOUT)/RL'

* ============================================================
* (B) Line Regulation: Vin 변화에 대한 Vout 민감도 (.dc V1)
*   - 필요할 때만 사용: (A),(C)는 주석 처리하고 이 블록만 실행 권장
* ============================================================
*.dc V1 3.0 3.6 0.3
*.measure DC  VOUT_MIN_B  min v(VOUT)
*.measure DC  VOUT_MAX_B  max v(VOUT)
*.measure DC  LINE_REG_B  param='(VOUT_MAX_B - VOUT_MIN_B)/(3.6 - 3.0)'
*  단위: V/V  (원하면 %/V → 100*... )

* ============================================================
* (C) Load Regulation: RL 변화에 대한 Vout 민감도 (.dc param RL)
*   - 필요할 때만 사용: (A),(B)는 주석 처리하고 이 블록만 실행 권장
* ============================================================
*.dc param RL 20k 1Meg 20k
*.measure DC  VOUT_MIN_C  min v(VOUT)
*.measure DC  VOUT_MAX_C  max v(VOUT)
*.measure DC  LOAD_REG_C  param='(VOUT_MAX_C - VOUT_MIN_C)/VOUT_MAX_C'
*  상대 변화(무차원). 다른 정의가 필요하면 변경 OK

.end

사용 팁

  • 동시에 여러 .dc를 켜면 해석/측정이 섞일 수 있으니, (A)/(B)/(C) 중 필요한 블록만 남기고 나머지는 주석 처리해서 돌려줘.

  • (A)는 단일 바이어스점 을 .dc로 강제 실행하는 방식이므로, .op 없이도 동일한 측정값을 얻는다.


2) 최적화할 변수 (Parameter)

현실 부품 제약을 반영해 Discrete(E96, 1%)로 운용 권장.
(부하 RL=100 kΩRL=100\,\text{k}\OmegaRL=100kΩ, 목표 Vout=1.0 VV_\text{out}=1.0\,\text{V}Vout​=1.0V, Vin=3.3 VV_\text{in}=3.3\,\text{V}Vin​=3.3V)

  • R2 (E96, Discrete) : 680 Ω ~ 1.2 kΩ

  • R1 (E96, Discrete) : 1.6 kΩ ~ 3.0 kΩ ≈2.3×R2\approx 2.3 \times R2≈2.3×R2

  • 전류/정확도 타협을 원하면:

    • R2: 1.5 kΩ ~ 10 kΩ , R1: 3.5 kΩ ~ 23 kΩ (정확도는 몇 % 낮아질 수 있음)

최적화기는 외부에서 후보를 순회(예: E96 리스트)하며 R1/R2를 갱신 → (A) 블록을 실행 → .measure 결과를 스코어로 사용.


3) 측정 대상 (Measure)

목표/제약 으로 바로 쓸 수 있게 이름을 고정해두었어.

  • 정확도: VERR_ABS_A = |VOUT - V_SPEC|최소화 (또는 ≤ 스펙)

  • 전류/전력: IIN_A, PIN_A최소화

  • 비율 확인: RATIO_A = VOUT/VSUP

  • 레귤레이션:

    • 라인 : LINE_REG_B (작을수록 좋음)

    • 부하 : LOAD_REG_C (작을수록 좋음)


간단 워크플로 (step-by-step)

  1. (A) 블록만 켜서 후보 R1/R2 에 대해 .dc 실행 → VERR_ABS_A, IIN_A, PIN_A 수집.

  2. 상위 최적화기(파이썬/툴)에서 Discrete 후보(E96)를 탐색하며 목적함수 최소화.

  3. 최종 후보에 대해 (B),(C) 블록을 각각 켜서 라인/부하 레귤레이션 검증.

  4. 필요 시 범위/목표 조정 → 반복.

추가로, E96 후보 리스트를 바로 쓸 수 있게 .include 또는 외부 스크립트용 리스트 텍스트 가 필요하면 알려줘. 원하는 범위로 만들어 줄게.

그냥 tran 해석으로 바꿔줄 수 있어?

좋아, .tran(과도 해석)만 쓰는 전압 분배기 데모 로 바꿔서 정리했어.
아래 덱은 바이패스 커패시터(CLOAD)를 둬서 유의미한 과도 응답이 나오도록 했고, 정착 오차/라이즈 타임/전류·에너지 같은 측정을 .measure tran으로 정의했어. (부하 스텝을 주는 옵션 블록 도 포함)


1) FineSim Netlist — .tran 전용 (복붙 실행)

spice

*------------------------------------------------------------
* Voltage Divider Transient Demo (FineSim/HSPICE compatible)
*   - 모든 해석은 .tran(과도) 기반
*------------------------------------------------------------
.option post=2 measform=1

* ===== 파라미터 =====
.param VSUP   = 3.3          * 공급전압 [V]
.param V_SPEC = 1.0          * 목표 출력 [V]
.param RS     = 50           * 소스 직렬저항 [Ohm]
.param RL     = 100k         * 부하 [Ohm]
.param R1     = 1.80k        * 최적화 변수 (Discrete/E96 권장)
.param R2     = 820          * 최적화 변수 (Discrete/E96 권장)
.param CLOAD  = 100n         * 출력 노드 바이패스(과도 응답 유도)
.param TRISE  = 1n
.param TFALL  = 1n
.param TSTOP  = 1m
.param V_BAND = 10m          * 정착 허용 밴드(±10 mV)

* ===== 회로 =====
V1    VIN_SRC  0   PULSE(0 'VSUP' 0 'TRISE' 'TFALL' '10*TSTOP' '20*TSTOP')
RSRC  VIN_SRC  VIN 'RS'
RUP   VIN      VOUT 'R1'
RDN   VOUT     0    'R2'
RLOAD VOUT     0    'RL'
COUT  VOUT     0    'CLOAD'

* ===== 과도 해석 =====
.tran 'TSTOP/1000' 'TSTOP'

* ===== 측정 (기본: 단일 상승 스텝 응답) =====
.measure TRAN VOUT_FINAL  AVG  v(VOUT) FROM='0.8*TSTOP' TO='TSTOP'          ; 최종값 근사
.measure TRAN VERR_ABS    PARAM='abs(VOUT_FINAL - V_SPEC)'                  ; 최종 오차
.measure TRAN IIN_AVG     AVG  '-I(V1)' FROM=0 TO='TSTOP'                    ; 평균 소스전류
.measure TRAN QIN         INTEG '-I(V1)' FROM=0 TO='TSTOP'                   ; 총 전하 [C]
.measure TRAN EAPP        PARAM='VSUP*QIN'                                   ; 근사 에너지 [J]
.measure TRAN TR10_90     TRIG v(VOUT) VAL='0.1*V_SPEC' RISE=1               \
                          TARG v(VOUT) VAL='0.9*V_SPEC' RISE=1               ; 10–90% 라이즈
.measure TRAN TSETTLE     WHEN 'abs(v(VOUT)-V_SPEC)-V_BAND' = 0 CROSS=1      ; ±밴드 최초 진입 시간

* ===== [옵션] 부하 스텝 응답(드룹/재정착) =====
* - 필요할 때만 해제해서 사용 (스위치로 병렬 부하를 추가)
*.param TLD   = '0.3*TSTOP'          * 부하 온 시간
*.param TW    = '0.2*TSTOP'          * 온 유지 시간
*.param RSTEP = 10k                   * 추가 부하(작아질수록 더 무거운 부하)
*VCTRL VCTL   0 PULSE(0 1 'TLD' 1n 1n 'TW' '2*TSTOP')
*.model SLD SW VT=0.5 VH=0 RON=1 ROFF=1e12
*RLD2  VOUT   NX 'RSTEP'
*S1    NX     0  VCTL 0 SLD
*.measure TRAN VOUT_MIN_L  MIN  v(VOUT) FROM='TLD' TO='TLD+TW'               ; 드룹 최소값
*.measure TRAN VOUT_PRE    FIND v(VOUT) AT='TLD-1n'
*.measure TRAN VDROP       PARAM='VOUT_PRE - VOUT_MIN_L'                      ; 드룹 크기
*.measure TRAN TSETTLE_L   WHEN 'abs(v(VOUT)-V_SPEC)-V_BAND' = 0 CROSS=2      ; 부하 스텝 후 재정착
.end

2) 최적화 변수 (Parameter)

  • R1, R2 : 실제 생산을 고려해 Discrete(E96, 1%) 운용 권장

    • 예시 범위(정확도 우선): R2 = 680 Ω ~ 1.2 kΩ , R1 ≈ 2.3×R2 → 1.6 kΩ ~ 3.0 kΩ

    • 탐색은 외부 스크립트/옵티마이저에서 E96 후보를 순회 → .measure 결과를 스코어로 사용

(원하면 RT, K 방식으로도 바꿔줄 수 있어: R1=RT*(1-K), R2=RT*K)


3) 측정 대상 (Measure)

  • 정확도 : VOUT_FINAL, VERR_ABS

  • 속도 : TR10_90, TSETTLE(±V_BAND)

  • 전류/에너지 : IIN_AVG, QIN, EAPP

  • (옵션) 부하 스텝 성능 : VDROP, TSETTLE_L

메모

  • V_BAND(기본 10 mV)만 조절하면 정착 스펙을 손쉽게 변경 가능.

  • CLOAD은 과도 거동(속도/드룹)을 만드는 핵심 파라미터이니 시스템에 맞춰 설정해줘.

  • PULSE 폭을 10*TSTOP로 길게 잡아서 시뮬레이션 내내 High 상태가 유지되도록 했어.

필요하면 위 범위의 E96 리스트(.step list)나, RT·K 파라미터화 버전(같은 .tran 측정 유지)도 바로 만들어줄게.

CLOAD를 넣은 이유 좀 쉽게 설명해줘

좋아, 핵심만 쉽게 정리해볼게. (step-by-step)

  1. 그냥 R만 있으면, 시간적인 드라마가 없다
    전압 분배기(R1–R2–RL)만 있으면 회로는 “메모리”가 없는 순수 저항망 이야. .tran에서 입력을 PULSE로 바꿔도, Vout은 입력 파형을 즉시 비율만큼 나눠 따라갈 뿐(이론적으로는 소스의 상승/하강시간만큼만 변함).
    → 이러면 Rise time / Settling time 같은 과도 지표가 의미가 거의 없어(거의 입력 파형에 의해 정해짐).

  2. CLOAD를 달아야 ‘시간상수’가 생긴다
    CLOAD가 붙으면 Vout 노드는 (저항망의 테브난 저항 R_th) + 캐패시터 구조가 돼서 RC 시간상수 τ 가 생긴다.

    • Rth≈(R1+RS)∥(R2∥RL)R_{\text{th}} \approx (R_1+R_S) \parallel (R_2 \parallel R_L)Rth​≈(R1​+RS​)∥(R2​∥RL​)

    • τ=Rth⋅CLOAD\tau = R_{\text{th}} \cdot C_{\text{LOAD}}τ=Rth​⋅CLOAD​
      이제 Vout은 지수적으로 천천히 올라가고(1−e−t/τ1-e^{-t/\tau}1−e−t/τ), TR(10–90%) , 정착시간(TSETTLE) 같은 과도 지표를 회로의 파라미터로 제어·측정할 수 있어.

  3. 현실 파라사이트를 간단히 대변
    실제 보드는 배선/부하(ADC 샘플링캡, 다음 단계 입력 C 등) 때문에 수~수백 nF 수준의 등가 C 가 거의 항상 존재. CLOAD는 이런 현실적인 로딩/디커플링 을 간단히 모델링해줘.

    • 노이즈/리플을 필터링(고주파에서 출력 임피던스 ↓)

    • 부하 스텝 시 즉각적인 드룹을 완화(C가 순간적으로 전류 공급)하고, 그 뒤 τ\tauτ로 재정착

  4. 수치 감(예: R1=1.8 kΩ, R2=820 Ω, RS=50 Ω, RL=100 kΩ, CLOAD=100 nF)

    • R2∥RL≈814 ΩR_2 \parallel R_L \approx 814 \,\OmegaR2​∥RL​≈814Ω, R1+RS=1850 ΩR_1+R_S=1850 \,\OmegaR1​+RS​=1850Ω

    • Rth≈566 Ω⇒τ≈56.6 μsR_{\text{th}} \approx 566 \,\Omega \Rightarrow \tau \approx 56.6\,\mu sRth​≈566Ω⇒τ≈56.6μs

    • 대략 TR(10–90%) ≈ 2.2τ ≈ 124 μs , 정착 4–5τ ≈ 0.23–0.28 ms
      → 이런 값들이 CLOAD나 저항값을 바꾸면 예측 가능하게 변 하니, 최적화/트레이드오프가 가능해진다.

  5. 요약

    • 왜 넣었나? .tran에서 의미 있는 과도 특성(속도·정착·드룹·에너지)을 만들고, 현실 파라사이트/디커플링 효과 를 반영하려고.

    • 어떻게 쓰나? 원하는 응답 속도면 τ\tauτ 목표를 정하고 CLOADC_{\text{LOAD}}CLOAD​ 또는 저항 합/비율을 조정. 빠르게 하고 싶으면 CLOAD↓(또는 RT↓), 리플/드룹 억제는 CLOAD↑(단, 기동 전류/에너지는 ↑).

원하면, 위 RthR_{\text{th}}Rth​ 공식으로 목표 정착시간/라이즈타임 → 필요한 CLOAD 를 바로 역산해주는 스니펫(.measure/파라미터 계산)도 덱에 추가해줄게.

VERR_ABS와 EAPP 측정 결과가 나왔는데 각 단위가 뭐야

짧게 말하면:

  • VERR_ABS : 볼트 [V]

  • EAPP : 줄 [J] (= 전기적 에너지)

step-by-step로 풀면,

  1. 정의 복습

    • VOUT_FINAL을 마지막 구간(예: 0.8·TSTOP~TSTOP)에서 평균한 출력 전압 → 단위 V

    • VERR_ABS = |VOUT_FINAL − V_SPEC|단위 V

  2. EAPP가 왜 줄[J]인가

    • QIN = INTEG(-I(V1))쿨롬 [C] (전하)

    • EAPP = VSUP · QINV × C = J

    • 즉, 소스가 공급한 에너지(근사)야. 여기서 “근사”인 이유는, 덱에서 V1이 거의 상수(VSUP)지만 상승 구간 에선 순간적으로 V<VSUP이기 때문이야. 이 구간까지 정확히 포함하려면 아래처럼 전압·전류 곱을 적분 하면 돼:

      • 참고: 정확 에너지 ≈ ∫ v(V1)·(-I(V1)) dt → 결과 단위도 J

보너스 단위 체크

  • IIN_AVG: 암페어 [A]

  • TR10_90, TSETTLE: 초 [s]

필요하면 정확 에너지 측정식(∫v·i dt 버전)으로 바꾼 .measure 예시도 만들어줄게.

파워 소모라고 하면 W일거 같은데 J이야?

짧은 답:

  • EAPP에너지 [J]야. (시간에 걸쳐 들어간 전력의 적분)

  • “파워 소모”를 보고 싶다면 전력 [W]로 계산해야 해. (평균 전력 = 에너지 / 시간)

step-by-step:

  1. 왜 J냐?
    EAPP를 ∫ v·i dt(또는 VSUP·∫i dt)로 정의하면, 단위가 V·A·s = J 가 돼. 즉 “한 번의 과도 이벤트에서 쓴 총량”을 뜻해.

  2. 전력[W]가 필요하면
    같은 구간 [T0,T1][T0, T1][T0,T1]에서 평균 전력은

Pavg=1T1−T0∫T0T1v(t) i(t) dt=EAPPT1−T0[W]P_{\text{avg}}=\frac{1}{T_1-T_0}\int_{T_0}^{T_1} v(t)\,i(t)\,dt=\frac{\text{EAPP}}{T_1-T_0}\quad[\text{W}]Pavg​=T1​−T0​1​∫T0​T1​​v(t)i(t)dt=T1​−T0​EAPP​[W]

  1. .tran에서 바로 쓰는 측정 스니펫 (복붙 가능)
spice

* 구간 정의
.param T0 = 0
.param T1 = 'TSTOP'

* (정확한) 에너지 [J]
.measure TRAN EAPP  INTEG 'v(V1)*(-I(V1))' FROM='T0' TO='T1'

* 평균 전력 [W] — 직접 평균
.measure TRAN P_AVG AVG   'v(V1)*(-I(V1))' FROM='T0' TO='T1'

* (동일 의미) 평균 전력 [W] — 에너지/시간
*.measure TRAN DT    PARAM='T1 - T0'
*.measure TRAN P_AVG2 PARAM='EAPP/DT'

* 피크 전력 [W] (최대값)
.measure TRAN P_PEAK MAX   'v(V1)*(-I(V1))' FROM='T0' TO='T1'
  1. 주의(옵션)
    방전 때 소스에 에너지가 “되돌아갈” 수 있어 v⋅i<0v·i<0v⋅i<0. “진짜 소비만” 보고 싶다면 양의 부분만 적분:
spice

* 소비 에너지(양수만 적분) [J]
.measure TRAN E_CONS INTEG '0.5*( v(V1)*(-I(V1)) + abs(v(V1)*(-I(V1))) )' FROM='T0' TO='T1'

정리: EAPP=J(에너지)가 맞고, 파워 소모는 W(전력)이야. 평균 전력을 보고 싶으면 위 P_AVG로 측정하거나 EAPP/(T1-T0)로 계산하면 돼.

왜 P_AVG가 0이 나오지? 아까 써준 tran input에 재대로 assign 해줘봐

가능해! P_AVG=0 나오는 가장 흔한 이유는, 내가 예시로 쓴 v(V1)가 “소스의 소자 전압 ”을 뜻한다고 가정했는데, FineSim/HSPICE에서는 그게 제대로 해석되지 않아서 0으로 처리 되는 경우가 있어.
소스 전압은 노드 전압 으로 안전하게 참조하는 게 확실해—즉 v(VIN_SRC,0)처럼 노드 이름 을 써주자.

아래처럼 .tran 입력 덱의 측정 블록 을 교체하면 돼(복붙 OK).


수정된 측정 블록 (.tran 전용, 전력/에너지 포함)

spice

* ===== 과도 해석 =====
.tran 'TSTOP/1000' 'TSTOP'

* --- 기존 측정(정확도/시간) 유지 ---
.measure TRAN VOUT_FINAL  AVG  v(VOUT) FROM='0.8*TSTOP' TO='TSTOP'
.measure TRAN VERR_ABS    PARAM='abs(VOUT_FINAL - V_SPEC)'
.measure TRAN TR10_90     TRIG v(VOUT) VAL='0.1*V_SPEC' RISE=1 \
                          TARG v(VOUT) VAL='0.9*V_SPEC' RISE=1
.measure TRAN TSETTLE     WHEN 'abs(v(VOUT)-V_SPEC)-V_BAND' = 0 CROSS=1

* --- 파워/에너지: 노드전압 v(VIN_SRC,0) × 소스전류 -I(V1) 로 측정 ---
.param T0 = 0
.param T1 = 'TSTOP'

* 정확한 에너지 [J] = ∫ v*i dt
.measure TRAN EAPP  INTEG 'v(VIN_SRC,0)*(-I(V1))' FROM='T0' TO='T1'

* 평균 전력 [W] = 평균(v*i)
.measure TRAN P_AVG AVG   'v(VIN_SRC,0)*(-I(V1))' FROM='T0' TO='T1'

* 피크 전력 [W]
.measure TRAN P_PEAK MAX   'v(VIN_SRC,0)*(-I(V1))' FROM='T0' TO='T1'

* (선택) 소비 에너지(양수만 적분) [J]
.measure TRAN E_CONS INTEG '0.5*( v(VIN_SRC,0)*(-I(V1)) + abs(v(VIN_SRC,0)*(-I(V1))) )' \
                           FROM='T0' TO='T1'

왜 이렇게 바꾸면 되나 (짧게)

  • v(VIN_SRC,0): 소스 양단 노드 전압 을 직접 참조 ⇒ 항상 유효.

  • -I(V1): 소스가 회로로 공급하는 전류(양수) ⇒ 공급 전력 v*i양수 로 계산됨.

  • AVG는 표현식의 시간 평균이므로, 저항망에 DC 전류가 흐르면 0이 될 수 없음. 0이 나왔다면 거의 항상 전압 참조가 잘못된 케이스야.

이렇게 수정하고 돌리면 P_AVG가 정상적인 W 단위 값 으로 나올 거야.

전체 다시 써. 게으르지말고 사람이 화나려고 해

알겠어. 전부 깨끗이 .tran 전용 으로 다시 정리해서 복붙 바로 실행 가능한 덱을 줘.
(전력/에너지 측정은 노드 전압 v(VIN_SRC,0) × 소스전류 -I(V1) 로 계산해서 P_AVG=0 문제를 근본적으로 회피했어.)


FineSim/HSPICE Netlist — Transient Only (Complete)

spice

*------------------------------------------------------------
* Voltage Divider — Transient-Only Optimization Deck
* (FineSim/HSPICE compatible)
*------------------------------------------------------------
.option post=2 measform=1

* ===== Parameters (edit here) =====
.param VSUP    = 3.3          * 입력 전압 [V]
.param V_SPEC  = 1.0          * 목표 Vout [V]
.param RS      = 50           * 소스 직렬저항 [Ohm]
.param RL      = 100k         * 부하 [Ohm]

* ---- 최적화 변수 (Discrete/E96 권장) ----
.param R1      = 1.80k        * 위쪽 저항
.param R2      = 820          * 아래쪽 저항

* ---- 과도/측정 관련 ----
.param CLOAD   = 100n         * 출력 바이패스/부하 커패시터
.param TRISE   = 1n
.param TFALL   = 1n
.param TSTOP   = 1m
.param V_BAND  = 10m          * 정착 허용 밴드(±)
.param T0      = 0            * 에너지/전력 집계 시작
.param T1      = 'TSTOP'      * 에너지/전력 집계 끝

* ===== Circuit =====
V1     VIN_SRC   0      PULSE(0 'VSUP' 0 'TRISE' 'TFALL' 'TSTOP' '100*TSTOP')
RSRC   VIN_SRC   VIN    'RS'
RUP    VIN       VOUT   'R1'
RDN    VOUT      0      'R2'
RLOAD  VOUT      0      'RL'
COUT   VOUT      0      'CLOAD'

* ===== Transient Analysis =====
.tran  'TSTOP/1000'  'TSTOP'

* ===== Measures (steady-state / timing) =====
.measure TRAN VOUT_FINAL  AVG  v(VOUT) FROM='0.8*TSTOP' TO='TSTOP'    ; 최종값 근사 [V]
.measure TRAN VERR_ABS    PARAM='abs(VOUT_FINAL - V_SPEC)'            ; 최종 오차 [V]

.measure TRAN TR10_90     TRIG v(VOUT) VAL='0.1*V_SPEC' RISE=1 \
                          TARG v(VOUT) VAL='0.9*V_SPEC' RISE=1        ; 10–90% 라이즈 [s]

.measure TRAN TSETTLE     WHEN 'abs(v(VOUT)-V_SPEC)-V_BAND' = 0 CROSS=1  ; 정착 시간 [s]

* ===== Power / Energy (robust node-based) =====
*  - 전력 p(t) = v(VIN_SRC,0) * (-I(V1))
*  - 평균전력 [W] = AVG p(t), 에너지 [J] = ∫ p(t) dt
.measure TRAN P_AVG   AVG   'v(VIN_SRC,0)*(-I(V1))' FROM='T0' TO='T1'      ; 평균 전력 [W]
.measure TRAN P_PEAK  MAX   'v(VIN_SRC,0)*(-I(V1))' FROM='T0' TO='T1'      ; 피크 전력 [W]
.measure TRAN EAPP    INTEG 'v(VIN_SRC,0)*(-I(V1))' FROM='T0' TO='T1'      ; 소비 에너지 [J]
* (선택) 양의 전력만 적분한 소비 에너지
*.measure TRAN E_CONS INTEG '0.5*( v(VIN_SRC,0)*(-I(V1)) + abs(v(VIN_SRC,0)*(-I(V1))) )' \
*                           FROM='T0' TO='T1'

.end

쓰는 순서 (진짜 짧게)

  1. 위 덱 그대로 붙여 넣고 .tran 실행.

  2. .mt# 결과에서 VERR_ABS [V], TR10_90 [s], TSETTLE [s], P_AVG [W], EAPP [J] 확인.

  3. R1/R2(Discrete, E96) 후보를 바꿔가며 측정값을 최적화.

변수 유형/범위(요약)

  • R1, R2 = Discrete(E96, 1%) 권장

    • 정확도 우선: R2 = 680 Ω ~ 1.2 kΩ , R1 ≈ 2.3×R2 → 1.6 kΩ ~ 3.0 kΩ

    • 전류 절약형(정확도 일부 양보): R2 = 1.5 kΩ ~ 10 kΩ , R1 = 3.5 kΩ ~ 23 kΩ

왜 이제 P_AVG가 0이 안 나오냐?

  • 전력 식을 소자이름이 아닌 노드 전압 v(VIN_SRC,0)소스 전류 -I(V1)로 정의했기 때문.

  • 이 조합은 FineSim/HSPICE에서 항상 유효하고, DC 성분이 있으면 평균이 0일 수 없어.

필요하면 부하 스텝 응답(.tran) 측정 블록 도 추가해 줄게.

Categories:

Updated: