测量差分对偏斜与共模偏差
한국어 원문으로 표시합니다.
목표
두 상보 신호의 도착 차이를 구하고 공통모드 편차·차동 문턱 도달 시각을 별도로 판정합니다. 선수 지식은 앞 신호 무결성 실습과 Python 함수·튜플·JSON·파일 처리입니다. 예상 85분입니다. 기본 60분이 끝나기 전에 +시간으로 연장하세요(최대 180분). 세션 종료 시 파일은 사라집니다. 소스와 보고서를 별도로 보관하세요.
왜 중요한가
같은 최종 차동 전압이어도 공통모드와 수신 시간은 달라질 수 있습니다. 상대 스큐와 절대 전파 지연, 느린 에지의 장점과 비용을 분리해야 설계 조치의 효과를 설명할 수 있습니다. 결합 없는 이상 정합 선로 두 개의 모델입니다. 실물 계측·방사 인증·결합 선로 해석이 아닙니다.
단계
- mkdir -p /root/differential-skew로 디렉터리를 만든 뒤 모든 구현을 /root/differential-skew/analyze.py에 저장합니다. predict(config,t_ns)는 (Vp,Vn) 튜플을 반환합니다. config는 delay_p_ns=1/1.5, skew_ns=-0.4/-0.2/0/0.2/0.4, rise_ns=0.4/0.8인 정확히 세 키 dict이며 각 값은 bool 아닌 int/float입니다. t_ns는 bool 아닌 유한 비음수 int/float입니다. 그 외는 ValueError입니다. P=clip((t_ns−2−delay_p_ns)/rise_ns,0,1), N=1−clip((t_ns−2−delay_p_ns−skew_ns)/rise_ns,0,1)이고 입력은 보존합니다.
- modes(rows)는 유효 (초,Vp,Vn) 튜플 목록을 (ns,Vdiff,Vcm) 튜플 목록으로 바꿉니다. Vdiff=Vp−Vn, Vcm=(Vp+Vn)/2입니다. 입력은 바꾸지 않고 전체 표본과 순서를 보존합니다.
- crossing(points,level,direction)는 시간 엄격 증가인 유효 (ns,전압) 표에서 첫 교차 시간을 선형 보간해 반환합니다. direction은 rising/falling뿐이고 다른 값은 ValueError입니다. rising은 alevel>=b인 인접 전압 a,b를 찾습니다. 교차가 없으면 None이며 처음부터 문턱에 머문 평탄 표본은 교차가 아닙니다.
- metrics(rows)는 유효한 시간 증가 (초,Vp,Vn) 표에서 skew_ns=N의 0.5V 하강 교차−P의 0.5V 상승 교차, common_peak_v=모든 표본 |Vcm−0.5| 최댓값, received_ns=Vdiff의 첫 +0.8V 상승 교차 또는 None, final_diff_v=마지막 Vdiff인 객체를 반환합니다. 둘 중 하나라도 50% 교차가 없으면 ValueError입니다. 표본에서 계산하고 입력 설정으로 대신 채우지 않습니다.
- assess(observed)는 metrics 결과에서 common_ok=(common_peak_v<=0.15), timing_ok=(received_ns가 None이 아니고 <=4), meets_spec=(두 조건 모두 참)인 객체를 반환합니다. 경계값은 포함합니다. 두 실패 이유를 하나로 합쳐 지우지 않습니다.
- analyze(folder)는 config.json과 simulator.read_wave로 읽은 wave.tsv를 분석합니다. 관측 metrics와 assess 결과를 보존하고 모든 원시 표본의 양쪽 전압을 predict와 비교한 최대 절대 오차 max_voltage_error를 구합니다. 오차<=0.003이면 consistent, passed는 consistent와 meets_spec이 모두 참일 때입니다. 참고의 반환 키를 모두 포함하며 measured=False입니다. 불일치해도 관측값은 남기고 원시 파일은 변경하지 않습니다.
- campaign(values,folder)는 중복 없는 1~8개 설정 list 전체를 사전 검증하고 새 폴더를 만듭니다. simulator.capture(config,folder/case-NN)로 원본을 생성한 뒤 analyze합니다. NN은 00부터이며 결과 config가 요청과 다르면 ValueError입니다. results, 모든 passed의 논리곱 all_pass, model=independent_matched_lossless_lines, measured=False인 객체를 반환하고 같은 report.json을 저장합니다. 실패 조건·원본 네 파일을 보존하고 기존 폴더는 비어 있어도 거절합니다. 설정 오류는 폴더 생성 전에 거절합니다.
참고
제공 도우미는 /opt/lab/fixtures/differential_skew/simulator.py입니다. 인터넷·추가 설치는 필요 없습니다. capture(config,새폴더)는 config.json, circuit.cir, wave.tsv, ngspice.log를 저장하고 Path를 반환합니다. read_wave(path)는 헤더·유한 수치·증가하는 시간과 최대 2.1ps 표본 간격·0~6ns 전체 범위를 확인해 (초,Vp,Vn) 튜플 목록을 줍니다. 잘린 파형은 ValueError입니다. ngspice는 최대 2ps 간격의 적응형 시간 격자를 사용합니다. 표본 최대와 연속시간 최고점은 다를 수 있습니다. source의 PWL 전이는 2ns에 시작하며 두 선로·소스·종단은 각각 50Ω입니다.
6단계 반환 키: config, observed(metrics 결과), common_ok, timing_ok, meets_spec, max_voltage_error, consistent, passed, measured. 마지막 값은 False입니다. 모든 원시 표본의 전압 오차 허용 0.003V와 학습 규격 0.15V·4ns는 서로 다른 기준입니다. 일반 함수 수치 비교 허용차는 상대·절대 1e-8입니다. 표본에서 실제로 구한 값으로 비교합니다. 유효 수치 표를 받는다고 명시한 함수에 별도 파서를 추가할 필요는 없습니다.
마지막 단계 뒤 다음 여섯 조건을 실제로 실행합니다. 각 조건은 (P 지연ns, 스큐ns, 램프ns)입니다. 정상 보고서도 실패 조건을 포함하므로 all_pass=False입니다. 다시 실행할 때는 새 폴더를 씁니다.
cd /root/differential-skew
PYTHONPATH=/opt/lab/fixtures/differential_skew python3 - <<'PY'
from analyze import campaign
values = [(1,0,.4),(1,.2,.4),(1,.2,.8),(1,.4,.8),(1.5,0,.8),(1,-.2,.4)]
configs = [dict(delay_p_ns=p,skew_ns=s,rise_ns=r) for p,s,r in values]
print(campaign(configs, '/root/differential-skew/run-01'))
PY
파일은 64KiB 이하 일반 파일이고 import 시 출력하지 않습니다. 채점은 독립 표본과 실제 엔진 조건을 사용하며 학생 소스를 바꾸지 않습니다. 검사 프로세스의 CPU 12초·파일 8MiB· 전체 35초 제한은 수강 시간과 다른 실행 보호 장치입니다.
상보 신호의 도착을 예측한다
mkdir -p /root/differential-skew로 디렉터리를 만든 뒤 모든 구현을 /root/differential-skew/analyze.py에 저장합니다. predict(config,t_ns)는 (Vp,Vn) 튜플을 반환합니다. config는 delay_p_ns=1/1.5, skew_ns=-0.4/-0.2/0/0.2/0.4, rise_ns=0.4/0.8인 정확히 세 키 dict이며 각 값은 bool 아닌 int/float입니다. t_ns는 bool 아닌 유한 비음수 int/float입니다. 그 외는 ValueError입니다. P=clip((t_ns−2−delay_p_ns)/rise_ns,0,1), N=1−clip((t_ns−2−delay_p_ns−skew_ns)/rise_ns,0,1)이고 입력은 보존합니다.
정합된 수신 진폭은 소스 진폭의 절반입니다. 두 지연을 평균내지 말고 N 지연에만 스큐를 더하세요.
차동과 공통모드를 분리한다
modes(rows)는 유효 (초,Vp,Vn) 튜플 목록을 (ns,Vdiff,Vcm) 튜플 목록으로 바꿉니다. Vdiff=Vp−Vn, Vcm=(Vp+Vn)/2입니다. 입력은 바꾸지 않고 전체 표본과 순서를 보존합니다.
차동은 차이이고 공통모드는 평균입니다. 파형 파일의 초를 반환 객체에서는 ns로 바꿉니다.
방향을 가진 문턱 교차를 보간한다
crossing(points,level,direction)는 시간 엄격 증가인 유효 (ns,전압) 표에서 첫 교차 시간을 선형 보간해 반환합니다. direction은 rising/falling뿐이고 다른 값은 ValueError입니다. rising은 alevel>=b인 인접 전압 a,b를 찾습니다. 교차가 없으면 None이며 처음부터 문턱에 머문 평탄 표본은 교차가 아닙니다.
문턱보다 크거나 작은 첫 표본 자체가 정확한 교차 시간은 아닙니다. 전압 비율로 두 시간 사이를 보간하세요.
관측된 스큐와 공통모드 편차를 구한다
metrics(rows)는 유효한 시간 증가 (초,Vp,Vn) 표에서 skew_ns=N의 0.5V 하강 교차−P의 0.5V 상승 교차, common_peak_v=모든 표본 |Vcm−0.5| 최댓값, received_ns=Vdiff의 첫 +0.8V 상승 교차 또는 None, final_diff_v=마지막 Vdiff인 객체를 반환합니다. 둘 중 하나라도 50% 교차가 없으면 ValueError입니다. 표본에서 계산하고 입력 설정으로 대신 채우지 않습니다.
음의 스큐는 오류가 아닙니다. 공통모드는 기준 0.5V를 뺀 편차의 절댓값을 최대화합니다.
공통모드와 수신 시간을 따로 판정한다
assess(observed)는 metrics 결과에서 common_ok=(common_peak_v<=0.15), timing_ok=(received_ns가 None이 아니고 <=4), meets_spec=(두 조건 모두 참)인 객체를 반환합니다. 경계값은 포함합니다. 두 실패 이유를 하나로 합쳐 지우지 않습니다.
스큐 0이어도 함께 늦어지면 시간 규격은 실패합니다. 문턱 미도달은 0ns가 아니라 None입니다.
두 전압의 원시 증거와 모델을 비교한다
analyze(folder)는 config.json과 simulator.read_wave로 읽은 wave.tsv를 분석합니다. 관측 metrics와 assess 결과를 보존하고 모든 원시 표본의 양쪽 전압을 predict와 비교한 최대 절대 오차 max_voltage_error를 구합니다. 오차<=0.003이면 consistent, passed는 consistent와 meets_spec이 모두 참일 때입니다. 참고의 반환 키를 모두 포함하며 measured=False입니다. 불일치해도 관측값은 남기고 원시 파일은 변경하지 않습니다.
두 신호에 같은 오프셋을 더하면 차동은 같아도 공통모드는 달라집니다. 차동만 검산하지 마세요.
에지와 경로 지연의 교환 관계를 비교한다
campaign(values,folder)는 중복 없는 1~8개 설정 list 전체를 사전 검증하고 새 폴더를 만듭니다. simulator.capture(config,folder/case-NN)로 원본을 생성한 뒤 analyze합니다. NN은 00부터이며 결과 config가 요청과 다르면 ValueError입니다. results, 모든 passed의 논리곱 all_pass, model=independent_matched_lossless_lines, measured=False인 객체를 반환하고 같은 report.json을 저장합니다. 실패 조건·원본 네 파일을 보존하고 기존 폴더는 비어 있어도 거절합니다. 설정 오류는 폴더 생성 전에 거절합니다.
에지를 느리게 하면 공통모드 편차는 줄지만 시간 여유도 감소합니다. 좋은 결과만 남기지 마세요.