LabHub
배우기 러닝패스 코스

케이블이 메아리친다

핀 부하 때문에 사라진 대역폭

LabHub 에서 이어서 보기

목표

집중정수 RC 회로의 실제 AC 응답에서 상대 대역폭과 위상을 추출하고 여섯 조건을 비교합니다. Python 함수·복소수·리스트·JSON·분압 기초가 필요합니다. 예상 80분이므로 기본 60분이 끝나기 전에 +시간으로 연장하세요(최대 180분). 세션이 끝나면 파일이 사라지므로 별도 보관하세요.

왜 중요한가

입력 핀의 부하를 저항만으로 볼 때 놓치는 주파수 의존성을 배웁니다. 절대 전압 분압과 통과 대역 대비 감쇠, 크기와 위상, 실행 성공과 규격 통과를 각각 구분합니다. 이상적인 집중정수 RC 모델이며 긴 전송선·비선형 핀·실물 계측·버스 규격 인증을 대신하지 않습니다.

단계

  1. 모든 구현은 /root/pin-bandwidth/analyze.py에 저장합니다. predict(config)는 dc_gain, rth_ohm, pole_hz를 반환합니다. 설정은 source_ohm=10/25/50, load_ohm=50/100, cap_pf=10/20/40 중 하나씩인 정확히 세 키의 dict입니다. 숫자 int/float만 받고 bool·문자열·누락·추가 키·범위 밖 값은 ValueError입니다. 원본은 바꾸지 않습니다. DC 분압, 병렬 등가 저항, 1/(2πRthC)를 계산하세요.
  2. read_response(path)는 헤더 frequency hre him인 공백 구분 파일을 읽어 (Hz,실수부,허수부) 튜플 목록을 반환합니다. 일반 파일 1MiB 이하, 데이터 2행 이상, 행마다 유한 숫자 3개, 주파수 양수·엄격 증가를 검사하고 위반은 ValueError로 거절합니다. 초나 MHz로 변환하지 않습니다. 헤더 앞뒤 공백은 허용합니다.
  3. metrics(rows)는 유효한 (Hz,실수부,허수부) 목록을 받아 각 행의 hz, magnitude, db, phase_deg 객체 목록을 반환합니다. 크기는 복소수 절댓값, db는 20log10(크기), 위상은 atan2의 도 단위이며 범위는 −180~180도입니다. 크기 0은 ValueError입니다. 모든 입력 행과 순서를 유지하세요.
  4. bandwidth(points,dc_gain)는 유효한 metrics 결과와 양의 DC 이득을 받습니다. 문턱은 20log10(dc_gain)−10log10(2)입니다. a.db > 문턱 >= b.db인 첫 인접 구간에서 dB 대 log10(Hz)를 선형 보간해 Hz를 반환하세요. 교차가 없으면 None이며 처음부터 문턱 이하인 것을 교차로 간주하지 않습니다.
  5. at_frequency(rows,hz)는 유효한 복소 응답 표에서 hz의 complex 값을 반환합니다. 정확한 표본이면 그 값을 쓰고, 사이라면 log(주파수) 축의 비율로 실수부와 허수부를 각각 선형 보간합니다. 표의 범위를 벗어나면 ValueError입니다. 크기나 위상을 따로 보간하는 함수가 아닙니다.
  6. analyze(folder)는 config.json과 response.tsv를 읽어 아래 참고의 결과 객체를 반환합니다. 전체 161행·1MHz~10GHz·40점/decade 격자를 검사하고 부족하거나 다르면 ValueError입니다(주파수 상대 오차 1e-9). 대역폭·100MHz의 상대 이득과 위상은 표에서 구하고, 모든 복소 표본을 H0/(1+jf/fc)와 비교합니다. 모델 불일치도 관측값은 남깁니다.
  7. campaign(values,folder)는 중복 없는 1~18개 설정 list 전체를 predict로 검증한 뒤 새 폴더를 만듭니다. 제공 simulator.capture(config,folder/case-NN)로 각 조건을 실행하고 analyze합니다. NN은 입력 순서의 00부터이며 관측 config가 요청과 다르면 ValueError입니다. results 목록, 모든 passed가 True인지 나타내는 all_pass, model=lumped_rc, measured=False를 반환하고 같은 객체를 report.json에 저장합니다. 기존 폴더는 비어 있어도 거절합니다. 설정 오류에는 폴더도 만들지 않습니다.

참고

구현 경로는 /root/pin-bandwidth/analyze.py입니다. 인터넷·추가 패키지·장비는 필요 없습니다. 제공 도우미 /opt/lab/fixtures/pin_bandwidth/simulator.py는 회로 생성과 실제 ngspice 실행만 합니다. Rs 직렬, RL과 C 병렬인 회로에 AC 1V를 넣고 1MHz~10GHz를 decade당 40점으로 계산합니다. capture(config,새폴더)는 Path를 반환하며 기존 결과를 덮지 않습니다. 입력 C 단위는 pF입니다.

6단계 반환 키는 config, bandwidth_hz, relative_db, phase_deg, max_complex_error, consistent, meets_spec, passed, measured입니다. relative_db는 100MHz에서 20log10(|H|/H0), phase_deg는 같은 보간 H의 위상입니다. max_complex_error는 모든 행의 관측 H와 모델 H 사이 차이 절댓값의 최대입니다. consistent는 이 오차가 1e-8 이하이고 관측 대역폭이 존재하며 예측 fc 대비 오차가 0.2% 이하일 때만 True입니다. meets_spec은 관측 대역폭 200MHz 이상, relative_db −0.5dB 이상, phase_deg −20도 이상을 동시에 만족할 때 True입니다. passed는 consistent와 meets_spec이 모두 True인지이며 measured는 False입니다. 교차가 없어 대역폭이 None이면 consistent·meets_spec·passed는 False입니다. 관측 자체는 버리지 않습니다.

7단계 구현 뒤 다음 명령으로 소스 25/50Ω × C 10/20/40pF, 부하 50Ω의 여섯 조건을 실행하세요. 실패 조건이 포함되므로 정상 보고서의 all_pass는 False입니다. 재실행은 새 출력 폴더 이름을 쓰세요.

cd /root/pin-bandwidth
PYTHONPATH=/opt/lab/fixtures/pin_bandwidth python3 - <<'PY'
from analyze import campaign
conditions = [dict(source_ohm=r, load_ohm=50, cap_pf=c) for r in (25,50) for c in (10,20,40)]
report = campaign(conditions, '/root/pin-bandwidth/run-01')
print(report)
PY

소스는 64KiB 이하 일반 파일이며 import 시 무출력이어야 합니다. 파형·설정은 읽기만 하세요. 채점은 별도 작은 표본과 실제 엔진을 사용하며 일반 수치 허용차는 상대·절대 1e-8입니다. 채점 프로세스는 CPU 12초·출력 파일 8MiB·전체 35초 상한입니다. 수강 시간과는 다릅니다.

분압과 극점을 예측한다

모든 구현은 /root/pin-bandwidth/analyze.py에 저장합니다. predict(config)는 dc_gain, rth_ohm, pole_hz를 반환합니다. 설정은 source_ohm=10/25/50, load_ohm=50/100, cap_pf=10/20/40 중 하나씩인 정확히 세 키의 dict입니다. 숫자 int/float만 받고 bool·문자열·누락·추가 키·범위 밖 값은 ValueError입니다. 원본은 바꾸지 않습니다. DC 분압, 병렬 등가 저항, 1/(2πRthC)를 계산하세요.

pF를 F로 바꾸고 전압원을 0으로 했을 때 커패시터가 보는 두 저항을 생각하세요.

복소 응답 표를 읽는다

read_response(path)는 헤더 frequency hre him인 공백 구분 파일을 읽어 (Hz,실수부,허수부) 튜플 목록을 반환합니다. 일반 파일 1MiB 이하, 데이터 2행 이상, 행마다 유한 숫자 3개, 주파수 양수·엄격 증가를 검사하고 위반은 ValueError로 거절합니다. 초나 MHz로 변환하지 않습니다. 헤더 앞뒤 공백은 허용합니다.

인접한 두 행의 주파수가 같은 경우도 거절합니다. 분석은 원시 파일을 고치지 않습니다.

크기와 위상을 분리한다

metrics(rows)는 유효한 (Hz,실수부,허수부) 목록을 받아 각 행의 hz, magnitude, db, phase_deg 객체 목록을 반환합니다. 크기는 복소수 절댓값, db는 20log10(크기), 위상은 atan2의 도 단위이며 범위는 −180~180도입니다. 크기 0은 ValueError입니다. 모든 입력 행과 순서를 유지하세요.

실수부는 크기와 다릅니다. 3+4j의 크기와 음의 실수·허수 사분면을 손으로 확인하세요.

상대 반전력 주파수를 찾는다

bandwidth(points,dc_gain)는 유효한 metrics 결과와 양의 DC 이득을 받습니다. 문턱은 20log10(dc_gain)−10log10(2)입니다. a.db > 문턱 >= b.db인 첫 인접 구간에서 dB 대 log10(Hz)를 선형 보간해 Hz를 반환하세요. 교차가 없으면 None이며 처음부터 문턱 이하인 것을 교차로 간주하지 않습니다.

절대 −3dB가 아닙니다. 1MHz와 100MHz 사이에서 dB 차이가 반이면 주파수는 10MHz입니다.

같은 주파수에서 복소수를 비교한다

at_frequency(rows,hz)는 유효한 복소 응답 표에서 hz의 complex 값을 반환합니다. 정확한 표본이면 그 값을 쓰고, 사이라면 log(주파수) 축의 비율로 실수부와 허수부를 각각 선형 보간합니다. 표의 범위를 벗어나면 ValueError입니다. 크기나 위상을 따로 보간하는 함수가 아닙니다.

먼저 로그 축의 위치 비율을 구한 다음 두 복소수 사이를 이동하세요. 양 끝점은 외삽이 아닙니다.

관측과 규격을 따로 검증한다

analyze(folder)는 config.json과 response.tsv를 읽어 아래 참고의 결과 객체를 반환합니다. 전체 161행·1MHz~10GHz·40점/decade 격자를 검사하고 부족하거나 다르면 ValueError입니다(주파수 상대 오차 1e-9). 대역폭·100MHz의 상대 이득과 위상은 표에서 구하고, 모든 복소 표본을 H0/(1+jf/fc)와 비교합니다. 모델 불일치도 관측값은 남깁니다.

크기가 같은 잘못된 위상을 잡으려면 복소수 차이의 절댓값을 비교해야 합니다. 규격 판정과 모델 일치를 분리하세요.

여섯 조건의 근거를 보존한다

campaign(values,folder)는 중복 없는 1~18개 설정 list 전체를 predict로 검증한 뒤 새 폴더를 만듭니다. 제공 simulator.capture(config,folder/case-NN)로 각 조건을 실행하고 analyze합니다. NN은 입력 순서의 00부터이며 관측 config가 요청과 다르면 ValueError입니다. results 목록, 모든 passed가 True인지 나타내는 all_pass, model=lumped_rc, measured=False를 반환하고 같은 객체를 report.json에 저장합니다. 기존 폴더는 비어 있어도 거절합니다. 설정 오류에는 폴더도 만들지 않습니다.

실패한 조건도 results에 남깁니다. capture가 만든 config.json·circuit.cir·response.tsv·ngspice.log를 지우지 마세요.