Skip to content
kos2001Public

About

3GPP NR stack (PHY to RRC) checked against the spec text: golden vectors, BLER campaigns, verdicts

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Latest commit

 

History

206 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

nrproof

한국어 · English

3GPP NR 스택(PHY 에서 RRC 까지)을 규격 원문에 대조해 검증하는 참조 구현과 도구 모음. 예전 이름은 lls-kit - 링크레벨 시뮬레이터 작업 키트로 시작했다.

핸드북(조사 문서)에서 "코드가 있으면 바로 할 수 있다"고 적었던 네 가지를 실제로 돌아가는 형태로 만든 것이다:

도구 역할 핸드북 대응
specmap.py 규격 조항 → 모듈 추적 (연쇄 영향 포함) 04절 2단계
golden.py 골든 벡터 추출/대조 04절 3·5(a)단계
campaign.py SNR 스윕 실행, 블록에러 기준 정지, Wilson CI 05절
regress.py 두 결과의 신뢰구간 기반 회귀 판정 04절 5(b)단계
loop.py 결함 대장 ↔ 게이트 대조 (자기개선 루프) —
bgtool.py 규격 표 추출(3GPP .docx)·검증 —

nrlls/ 는 이 도구들이 물릴 대상이 되는 참조 PDSCH 체인이다.

빠른 시작

의존성: numpy, pyyaml.

python check.py          # 전체 게이트 - 무엇이든 주장하기 전에 통과시킬 것
python server.py         # 로컬 대시보드 http://127.0.0.1:8765, 설치할 것 없음

전체 명령은 아래 사용법 참조.

화면

로컬 대시보드(python server.py)를 영어 UI로 전환해 캡처했습니다.

PHY 캠페인과 BLER 곡선 겹쳐 보기 계층별 적합성 판정
PHY 캠페인 — 캠페인 선택·실행, 동작점 검사와 함께 BLER 곡선을 겹쳐 본다. 적합성 판정 — TS 38.523-1(RRC, RLC)·TS 38.101-4(PHY) 기준의 PASS / FAIL / 판정불가.
PHY 계층 화면
계층 화면 — RRC~PHY 각 계층이 하는 일, 입출력, 핵심 개념, 게이트 상태.

대상: MATLAB 5G Toolbox

사내 LLS가 MATLAB 5G Toolbox 기반으로 확인됐다. 어댑터는 matlab/ 에 있고, 도구 4종은 시뮬레이터 언어와 무관하게 그대로 쓴다.

python specmap.py --map matlab trace 38.214      # 5G Toolbox 함수로 추적
python golden.py diff before/ after/ --map matlab # MATLAB 덤프 대조
python regress.py results/a.json results/b.json   # 동일

MATLAB 쪽은 llskit.runSweep / llskit.writeResult / llskit.captureGolden 세 개를 기존 스크립트에 끼워 넣으면 된다. 자세한 건 matlab/README.md. 단, matlab/ 의 .m 파일은 이 환경에 MATLAB이 없어 실행 검증되지 않았다 — 해당 문서의 "검증되지 않은 부분" 절을 먼저 읽을 것.

nrlls/ 는 이제 비교·학습용 참조 구현이다. 규격 해석이 갈릴 때 "다른 독립 구현은 이렇게 한다"는 두 번째 의견으로 쓰면 된다.


무엇이 규격 준수이고 무엇이 아닌가

이 구분이 이 저장소에서 가장 중요하다. 전문은 docs/compliance.md (PDSCH 체인)과 docs/phy-channels.md (그 밖의 채널·신호) — 보고용 결과를 내기 전에 반드시 읽을 것.

요약:

영역 상태
PDSCH 송신 경로 (38.211/212/214) 규격대로 구현
SSB 전체 + 2단계 셀 탐색 · 시간동기 · 버스트 집합 구현 — 수식은 문서에 OLE 라 검증 필요, 성질로 게이트
Polar 부호 (CA-SCL) 구현 — 표 둘 다 원문에서 기계 추출, 순열로 검증
PDCCH (DCI/RNTI/탐색공간/CORESET 매핑) 구현
PRACH (Zadoff-Chu + 시간영역 파형 + 검출) 구현 — N_CP 값은 설정으로 받는다
PUSCH 상향 고유부 (DFT-s-OFDM, 저-PAPR 수열) 구현 — PAPR 저감을 게이트가 잰다
PUCCH (포맷0~4 + UCI 부호화·다중화·호핑) 구현
CSI-RS · SRS(호핑·안테나 스위칭) · PT-RS 구현
위상잡음 모델 구현 — PT-RS 가 무엇을 고치는지 잴 수 있다
실제 38.212 LDPC 구현됨 (sim.fec: ldpc). 표는 3GPP 원문에서 bgtool.py docx 로 직접 추출
기본 FEC genie 추상화(GMI) — 빠르지만 실제 복호기의 상한이다
HARQ, TDL-D/E(LOS), MIMO (최대 24 레이어) 구현됨 — 13 이상은 Rel-18 dmrs_type_enh, 포트 표는 원문 대조
CP 초과 지연 ISI 시간영역 경로로 곡선에 반영 가능 (time_domain: true). 기본 경로에선 크기만 잰다
PDCP 절차·보안·EHC·UDC·ROHC(프로파일 0) 구현 — docs/pdcp.md. 헤더 비트 배치 검증 필요, ZUC 없음
RLC TM/UM/AM, MAC PDU·CE 구현 — docs/rlc.md, docs/mac.md. 헤더는 OCUDU 벡터와 대조
RRC 절차 + UPER + 키 유도 + RLM 구현 — docs/rrc.md. 측정(A3)·핸드오버 포함
25 레이어 이상 미지원 (규격 DM-RS 포트가 24 개다)
규격 표 12종 (LDPC/polar/MCS/TBS/TDL/CSI-RS/DM-RS…) 원문에서 기계 추출·대조 완료 (Rel-18)
RV 계수, PSS/SSS 다항식, c_init, PRACH N_CP 검증 필요 — 수식이 OLE 라 복원한 것

HW/SW codesign: 두 번째 축

위의 "규격 준수인가"는 누가 값을 정하는가를 묻는다. 실장을 앞두면 어디에 실장되는가가 붙는다. 직교하는 두 축이고 레지스트리가 둘 다 든다.

python specmap.py realm      # 실장 영역별 구분 (hw/sw/boundary/sim_only)

교차점 구현 자유 × (hw | boundary) 가 codesign 의사결정이 사는 곳이다 — 현재 4개(채널 추정·등화·LLR 디매핑·LDPC 복호). 여기서 나온 곡선이 곧 면적·지연· 비트폭의 근거가 된다. docs/codesign.md 참조.

사용법

의존성: numpy, pyyaml.

# 규격 변경이 어느 모듈에 걸리는지 (연쇄 포함)
python specmap.py trace 38.214
python specmap.py trace dmrs
python specmap.py check          # 레지스트리와 코드 정합성

# 수정 '전에' 골든 벡터부터
python golden.py capture campaigns/baseline.yaml -o golden/baseline.npz

# ... 코드 수정 ...

# 규격 고정 경로가 안 깨졌는지
python golden.py verify campaigns/baseline.yaml golden/baseline.npz

# 성능 곡선
python campaign.py campaigns/baseline.yaml -o results/baseline.json --jobs 4

# 회귀 판정
python regress.py results/baseline.json results/modified.json

# 보고서 - 곡선 + KPI + 게이트 + 규격 출처를 한 장의 HTML 로
python report.py results/baseline.json results/perfect-ce.json -o report.html

# PDSCH 외 물리채널 곡선 (PDCCH / PBCH / PUCCH / PRACH)
python chancamp.py campaigns/pdcch.yaml -o results/pdcch.json --jobs 4

# 적합성 시험 - 규격 한계 대비 PASS / FAIL / 판정불가
python testplan.py list
python testplan.py run --clause 5.3.2 --jobs 4 -o results/conformance.json

# 자기개선 루프 - 결함마다 재발을 막는 게이트가 있는가
python loop.py status

# 전체 게이트 - 무엇이든 주장하기 전에 통과시킬 것
python check.py

chancamp.py 는 PDSCH 외 물리채널 곡선을 뽑고, testplan.py 는 곡선이 아니라 판정을 낸다 — TS 38.101-4 5.3절의 PDCCH 복조 최소성능을 원문에서 기계로 뽑아(시험 44개) 그 조건대로 돌리고 한계와 비교한다. 판정은 PASS / FAIL / 판정불가 셋이다. 자세한 것은 docs/measurement.md 참조 — 판정이 규격 적합성 인증이 아닌 이유도 거기 있다.

report.py 는 결과 JSON 으로 보고서 HTML 을 만든다. 곡선만 있는 보고서는 틀리기 쉬워서, 곡선 옆에 이 숫자의 조건을 같이 싣는다 — 목표 BLER 에 필요한 SNR(보간만, 외삽 금지), baseline 과 다른 설정, check.py 결과 전문, 규격 표의 출처와 아직 검증 필요인 항목, genie FEC · CP 초과 SINR 상한 같은 주의. 곡선은 인라인 SVG 다.

check.py 는 단위 테스트 · 레지스트리 정합성 · 입력 크기 · 골든 벡터 · 동작점(Ês/Noc) · 채널추정 순서 · 결함 대장 일곱 가지를 한 번에 돌리고 종료 코드로 판정한다. 에이전트에게 작업을 맡길 때의 합격선이기도 하다 — AGENTS.md 참조.

Windows 콘솔 한글

Git Bash 기본 코드페이지에서 한글 출력이 깨진다. PYTHONUTF8=1 을 붙이거나 chcp 65001 을 먼저 실행할 것. 출력 내용 자체는 정상이다.


캠페인 설정

campaigns/*.yaml 한 파일이 실험 하나다. 한 번에 축 하나만 바꾸고 새 이름으로 저장한다. regress.py 가 설정 차이를 평평하게 나열하고, 축을 둘 이상 바꿨으면 경고한다.

기본 baseline.yaml 은 "빠르게 한 바퀴" 크기(target_block_errors: 100, max_slots: 2000)다. 보고용 곡선은 200~1000 / 20000 이상으로 올릴 것. 현재 속도는 약 13 ms/슬롯이다.


대시보드

python server.py 로 로컬 웹앱이 뜬다 (http://127.0.0.1:8765). 설치할 것이 없다 — 백엔드는 표준 라이브러리, 프론트엔드는 빌드 없는 ES 모듈이다.

  • 사이드바: 검증 상태(게이트 요약, 늘 보인다) · 계층 RRC~PHY(계층별 테스트 통과 수) · 도구(패킷 여정, 블록 지도) · 검증(적합성 판정, PHY 캠페인, 결과 관리).
  • 검증은 작업으로 돈다. 기동 때 한 번, 이후 '다시 검사' 로 계층별 테스트와 check.py 를 백그라운드로 돌려 results/ 에 캐시한다. 요청은 기다리지 않는다 (--no-verify 로 기동 때 검사를 끈다).

화면과 API: docs/dashboard.md.

동작점은 Ês/Noc 로 정의한다 (TS 38.101-4)

3GPP는 "SNR"을 직접 정의하지 않는다. RAN4 성능 요구사항이 쓰는 양은 둘이다.

양 정의 함정
Noc 백색 잡음원의 PSD, SCS로 정규화된 RE당 전력 대역/파워클래스마다 다르다. 하나를 재사용하면 안 된다
Ês RE당 수신 에너지, 심볼의 useful part 기준(CP 제외) 시간영역에서 CP 포함해 더하면 normal CP에서 약 0.29 dB 치우친다

지켜야 할 규칙 둘:

  • 프리코딩 이득을 접어 넣지 않는다. 규격의 SNR 정의는 RE가 프리코딩되지 않았다고 가정한다.
  • 수신 안테나 수로 나누지 않는다. Noc는 안테나 1개 기준이고, 수신 다이버시티 이득은 등화 결과로 나타나야 한다.

구현은 nrlls/rf.py, MATLAB 쪽은 matlab/+llskit/verifyOperatingPoint.m. 최소 Noc 유도식(REFSENS - 10log10(12·SCS·nPRB) + D - SNR_REFSENS + Δthermal)도 들어 있다.

식을 믿지 말고 재볼 것

N0 계산은 FFT 정규화·CP 보정·안테나 수·프리코딩 네 군데서 틀릴 수 있고, 틀려도 곡선은 그럴듯하게 나온다 — 통째로 평행이동해 있을 뿐이다. campaign.py 는 곡선을 뽑기 전에 실제 생성된 신호/잡음 RE로 Ês/Noc를 되재서 요청값과 대조한다.

페이딩 채널에서 Ês는 앙상블 평균이라 유한 표본에서 흔들린다. 계통 오차와 표본 부족을 가르는 법: 표본을 늘려가며 재본다. 오차가 줄면 표본 부족, 한 곳에 붙어 있으면 정의가 틀린 것이다. 캠페인 러너가 이 판정을 자동으로 한다.

실행 중 드러난 것

도구가 실제로 잡은 결함은 defects.json 대장에, 서술은 docs/defects.md 에 있다. python loop.py status 는 결함별로 '무엇이 잡았나'와 '무엇이 재발을 막나'를, python loop.py gates 는 그 역방향을 보여준다. 재발을 막는 게이트가 없는 결함이 남아 있으면 check.py 가 실패한다.


구조

nrlls/
  spec38211.py   심볼/자원격자 레벨   [규격 고정]
  spec38212.py   비트 레벨            [규격 고정]
  spec38214.py   파라미터 공급        [규격 고정]
  spec38901.py   TDL 채널 모델        [규격 고정]
  fec.py         부호화 계층          [파라미터는 규격, 동작은 교체 가능]
  receiver.py    수신 알고리즘        [규격 없음 - 구현 자유]
  link.py        슬롯 루프
  config.py      설정 구조체
specmap.json     규격 -> 모듈 레지스트리
campaigns/       실험 설정
results/         캠페인 결과 (설정·시드·커밋해시 포함)
golden/          골든 벡터
tests/           규격 단위 테스트

golden_tap 이 붙은 블록은 link.py 의 _tap() 지점에서 중간 출력을 남긴다. 새 탭을 추가하려면 _tap(taps, "이름", 값) 한 줄과 specmap.json 항목을 추가하면 된다.

라이선스

MIT — LICENSE 참고.

About

3GPP NR stack (PHY to RRC) checked against the spec text: golden vectors, BLER campaigns, verdicts

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages