← 목록
기타 2026-07-07 6KB 읽기 5분

.회로 방언(HDL) 트랜스파일러 6버그 수리 (5/6 완료)

개요

HDL카드.md(/Users/ef/crowny-rpnkit/대응카드/HDL카드.md)가 실측으로 적발한 .회로(Verilog-like HDL 방언 → 한선씨) 트랜스파일러의 6가지 버그 중 5개를 수리했다. 트랜스파일러는 /Users/ef/CrownyOS/crownyc/hanseonc_dialect.c (HDL 뿐 아니라 CSS/SQL/markup 방언도 같은 파일에서 처리하는 공유 컴파일러).

수리 전: examples/*.회로 6개 샘플 중 정상 동작(트랜스파일→컴파일→의도한 결과) 도달 0/6. 수리 후: 5/6 (배선/카운터/이중/fsm/alu 전부 실파이프라인 검증 완료), 나머지 1개(합성가능성 lint 부재, §3-J)는 P1로 미착수.

무엇을 했는지

  1. 백업: hanseonc_dialect.c.bak-20260707, hanseonc_dialect.bak-20260707
(같은 디렉토리).
  1. §3-G 배선 미번역: 배선 x = 식 라인이 변수로 번역되지 않고 그대로
방출돼 컴파일 실패하던 것 수리. is_wire 플래그로 신호맵 아닌 평범한 지역 변수로 처리.
  1. §3-H 시퀀셜 상태소실 (가장 큰 작업): 신호생성()/DFF생성()이 매
함수 호출부(모듈 함수 본문 안)에 방출되어 매 사이클 리셋되던 버그. 2패스 코드생성으로 재구조화: 0회차(prescan, 무출력)로 항상 블록을 먼저 스캔해 is_dff를 확정한 뒤, 시퀀셜 신호/DFF를 함수 (전역 프리앰블)에 딱 1회만 생성하고, 1회차(실제 방출)에서는 함수 본문에 재선언하지 않아 상태가 호출 간 유지되게 함.
  1. §3-I 다중 항상 블록: (a) DFF 갱신 루프가 모듈 전체 is_dff 신호를
전부 갱신해, 아직 계산 전인 신호가 조기에 클럭 엣지를 "소모"당해 영구 고착되는 버그 → touched[] 배열로 "이번 항상 블록에서만" 대입된 신호로 스코프 분리. (b) 출력 2개 이상(이중.회로 짝/홀)일 때 두 번째 반환이 죽은 코드였던 문제 → 출력 1개면 기존처럼 단일 반환, 2개 이상이면 반환 [a, b] 배열로 일괄 반환(호출측 원소(반환값,i)로 분해). 최상위 배정이 없는 출력 포트(alu.회로처럼 선택 케이스 내부에서만 대입)도 낙수 반환 보강.
  1. §3-E 선택/경우/기본 미구현: hanseonc_high가 모르는 키워드라 컴파일
실패하던 것을 만약/혹시/아니면 체인으로 재귀 번역하는 파서 신규 작성(hdl_emit_hdl_stmts). 중첩된 만약(fsm.회로 예제처럼 케이스 본문 안에 또 만약이 있는 경우)도 재귀로 올바르게 처리하도록 만약/혹시/아니면 자체도 재귀 분기로 추가.
  1. §3-F 원시 &/|: AND비트/OR비트 함수호출로 자동 치환
(hdl_bitop_core), 대입 좌변의 선언 비트폭을 추론해 3번째 인자로 사용.
  1. 부수 발견·수리: hdl_emit_hdl_stmts의 재귀 프레임에 있던 대형 스택
버퍼(최대 256KB)가 -O1/-O2 빌드에서 재귀 2~3단만에 스택오버플로(세그폴트) 를 일으킴 — ASAN으로 확진 후 전부 힙(malloc)으로 이관. -O0에서는 증상이 안 보이는 heisenbug라 실측 없이는 놓치기 쉬운 함정.
  1. 검증 하네스 자체 버그도 수리: HDL검증.sh의 카운터/이중 드라이버가
DFF클럭의 클럭 인자에 raw 정수 대신 신호생성() 맵 핸들을 그대로 넘기고 있었음(§3-A 라이브러리 API 문서화와 불일치) — 드라이버를 raw-int 클럭으로 고치고, 버그재현 단언(여전히 0 고정)을 수리검증 단언(정상 카운트업)으로 전환.

검증 결과

  • HDL검증.sh 33/0 PASS: 기존 29건(하드웨어.한선 직접경로) 무회귀 +
방언 버그 4건이 "여전히 버그" 단언에서 "수리 확인" 단언으로 전환.
  • 개별 실측: 가산기 7+5=12, 카운터 raw클럭 0→1→2→3, 이중 짝=0,2,4,6,8/
홀=1,3,5,7,9, fsm 0→1→2→0→1→2 순환, alu add/sub/and/or=22/2/8/14.
  • 인접 방언 회귀 확인: SQL검증.sh 13/0, 웹표현검증.sh 5/0, 동적웹검증.sh
7/0, 앱UI검증.sh 6/1(기존에도 있던 수동검증 항목, 무관).

관련 파일

  • /Users/ef/CrownyOS/crownyc/hanseonc_dialect.c (수정본, 2674→3124줄)
  • /Users/ef/CrownyOS/crownyc/hanseonc_dialect.c.bak-20260707 (백업)
  • /Users/ef/CrownyOS/crownyc/hanseonc_dialect.bak-20260707 (바이너리 백업)
  • /Users/ef/CrownyOS/crownyc/hanseonc_dialect (재빌드된 정본 바이너리)
  • /Users/ef/crowny-rpnkit/대응카드/HDL카드.md (§3 결론 문단에 수리반영 append)
  • /Users/ef/crowny-rpnkit/대응카드/HDL검증.sh (드라이버 수리 + 단언 전환)
  • /Users/ef/crowny-rpnkit/수준갭리포트.md (수리 큐 ✅ 갱신)

잔여 이슈

  • §3-J 합성가능성 lint 부재 (P1, 미착수): 나눗셈/동안무한루프/
루트() 같은 비합성 구조를 걸러줄 경고 장치가 여전히 없음. 나쁜회로.회로가 경고 없이 그대로 트랜스파일되는 것을 HDL검증.sh가 계속 버그재현으로 확인 중(의도적으로 유지 — 다음 세션 P1 작업 대상).
  • 다중출력 반환 규약 변경(단일→배열)은 호출측 코드에 영향을 준다.
기존에 다중출력 모듈을 단일변수로 캡처하던 호출부가 있다면 원소(반환값,0)/원소(반환값,1) 식으로 고쳐야 함(이중.회로 외 실사용 예제 없음 확인, 라이브러리 자체는 무영향).
  • 시퀀셜 신호의 전역 호이스팅은 이름을 그대로 전역 스코프에 올린다
(모듈명 접두어 없음). 한 파일에 여러 모듈이 있고 내부 상태 신호명이 같으면(예: 두 모듈 다 "cnt") 충돌 가능 — 현재 6개 샘플은 모듈당 1개뿐이라 문제 없지만, 일반화하려면 모듈명_신호명 접두어 + 본문 텍스트 치환이 추가로 필요(범위 밖, 문서화만).