케이블이 메아리친다 · 계산 성공을 검증 완료와 구분한다 · 실습
케이블이 메아리친다: 파형 검증실
목표
ngspice로 실제 전송선 모델을 실행하고 Python으로 도착 시각·반사·종단·공차·수치 차이를 분석합니다. 실물 계측이나 PCB 인증 과정은 아닙니다.
왜 중요한가
빠른 에지는 전원보다 높은 순간 전압을 만들 수 있습니다. 저항의 위치·입력 단위·표본 시각이 바뀌면 그럴듯한 그래프도 다른 질문의 답이 됩니다. 회로 조건과 파형, 분석 코드, 검증 범위를 연결해 다시 확인할 수 있는 산출물을 만듭니다. 셸·Python 함수/리스트/딕셔너리·분압 기초가 필요합니다. 예상 75분이므로 기본 60분이 끝나기 전에 +시간으로 연장하세요(최대 180분). 종료하면 파일이 사라지므로 별도로 보관하세요.
단계
1. 3.3V를 보냈는데 5.5V가 도착했다 — baseline.json에 volts=3.3, driver_ohm=10, series_ohm=0, z0_ohm=50, load_ohm=1000000000, delay_ns=2, rise_ns=0.2, step_ns=0.02, stop_ns=14를 저장하세요. 모든 파일은 /root/signal-integrity 아래입니다. experiment.py --model /root/signal-integrity/baseline.json --out /root/signal-integrity/baseline을 실행해 model.cir·trace.csv·run.json을 생성하고 입력/TX/RX 열을 확인하세요.
2. 케이블의 시계를 읽는다 — arrival.py에 first_crossing_ns(rows, threshold_v)를 구현하세요. rows는 [time_s, drive_v, tx_v, rx_v]의 시간 오름차순 목록입니다. RX가 처음 임계값에 닿는 시각을 선형 보간해 ns로 반환합니다. 첫 점부터 임계값 이상이면 첫 시각, 끝까지 없으면 None입니다. baseline 파형과 작은 별도 표본을 함께 검사합니다.
3. 메아리가 돌아오는 전압을 예측한다 — reflections.py의 predict(vs, source_ohm, z0_ohm, load_ohm)가 launch_v, gamma_source, gamma_load, rx_first_v, rx_second_v를 담은 객체를 반환하게 하세요. source_ohm은 드라이버와 추가 직렬 저항의 합입니다. 입력은 양의 유한 수이며 부하는 무한대가 아닌 유한 저항입니다. 두 번째 수신 평탄부는 첫 값에 다음 왕복의 변화를 더한 값입니다.
4. 저항 하나로 메아리를 줄인다 — baseline.json 조건에서 series_ohm만 40으로 바꾼 series.json을 만들고 --out /root/signal-integrity/series로 실행하세요. 기준 파일은 유지합니다. driver_ohm=10을 포함한 총 소스 저항은 50Ω입니다. 생성된 파형에서 첫 송신 전압과 첫 수신 전압이 서로 다른 이유를 확인하세요.
5. 같은 50Ω도 위치가 다르다 — baseline.json 조건에서 load_ohm만 50으로 바꾼 parallel.json을 만들고 --out /root/signal-integrity/parallel로 실행하세요(series_ohm은 0). tradeoff.py의 load_power(vs, source_ohm, load_ohm)는 충분히 오래 지난 DC 상태의 current_a와 load_w를 반환합니다. 전압 V·저항 Ω를 입력받아 A·W로 반환하며 유한 양의 조건들을 검사합니다.
6. 대표값 밖의 아홉 케이블을 비교한다 — series.json을 --out /root/signal-integrity/corners --corners로 실행하세요. 추가 40Ω는 유지하고 드라이버 8/10/12Ω × Z0 45/50/55Ω의 9개 폴더와 peaks.json을 생성합니다. summary.py의 summarize(records)는 비어 있지 않은 [{case: 이름, peak_v: 최대V}, ...]에서 count, min_peak_v, max_peak_v, max_case를 반환합니다. 최고값이 동률이면 사전순으로 가장 앞선 이름입니다.
7. 표본 번호 대신 시간을 맞춘다 — series.json에서 step_ns만 0.01로 바꾼 fine.json을 --out /root/signal-integrity/fine으로 실행하세요. convergence.py의 max_difference(coarse, fine)는 coarse의 각 시각에서 fine을 선형 보간하고 TX/RX(col 2,3) 전압의 최대 절대 차이 V를 반환합니다. 표는 [time_s,drive_v,tx_v,rx_v]이며 두 점 이상, 시간 엄격 증가, 같은 시작·끝입니다. 실제 파형과 다른 간격의 작은 표도 검사합니다.
8. 근거를 묶고 한계를 남긴다 — 앞 단계 파일을 보존하고 release.json을 작성하세요. model_type=ideal_single_mode_lossless, measured=false, pcb_certified=false, target_verification_required=true입니다. release.json 형식 예시의 sha256 객체에 제공된 상대 경로만 키로 사용하고 현재 파일 내용의 SHA-256 소문자 64자리 값을 넣습니다. 앞 단계 파형과 분석도 다시 검증합니다. 백업 파일은 목록에 넣지 않습니다.
참고
작업 폴더를 mkdir -p /root/signal-integrity로 먼저 만드세요. 명령 형식은 python3 /opt/lab/signal_integrity/experiment.py --model 입력JSON --out 새출력폴더 입니다. 단계의 파일 카드에서 입력과 생성물 형식을 구분하세요. 생성물 예시는 축약 형식이며 실제 solver 출력 대신 제출할 수 없습니다. 도우미는 기존 출력 폴더를 덮지 않습니다. 재실행하려면 이전 폴더를 다른 이름으로 보관하세요. 정답지는 이를 자동으로 수행합니다. Python 분석 함수는 파일을 직접 읽는 대신 표/수치를 인자로 받고 결과를 반환하며 print 로그를 넣지 않습니다. 수치 반환은 상대 1e-6 또는 절대 1e-8 허용 오차, JSON 불리언은 정확한 타입을 확인합니다. 각 소스·JSON은 64KiB, 파형 CSV는 2MiB 이하의 심볼릭 링크가 아닌 일반 파일이어야 합니다. 함수 실행은 CPU 4초·벽시계 5초·주소 공간 256MiB로 제한됩니다. 최종 채점은 공차 하위 파형을 포함해 앞 단계 자료를 다시 확인합니다. 추가 패키지 설치·인터넷·실제 장비는 필요 없습니다.
단계 8개
- 3.3V를 보냈는데 5.5V가 도착했다
- 케이블의 시계를 읽는다
- 메아리가 돌아오는 전압을 예측한다
- 저항 하나로 메아리를 줄인다
- 같은 50Ω도 위치가 다르다
- 대표값 밖의 아홉 케이블을 비교한다
- 표본 번호 대신 시간을 맞춘다
- 근거를 묶고 한계를 남긴다