← 목록

CrownyTVM ISA729 옵코드 정비 백서

tip.crowny.org 기록 — 2026-04-03 대상 독자: Crowny 팀원, 다른 클로드 세션, 한선씨 라이브러리 개발자

1. 배경

CrownyTVM v10.0 / crownyc v9.6→10.0 업데이트 이후 ISA729 옵코드 공간에 세 가지 버그가 발견됐다. 이 문서는 버그 원인, 수정 내용, 현재 옵코드 배치를 기록한다.


2. 수정된 버그 3종

Bug #1 — 옵코드 충돌: 삼진 신경망 연산 (463~469)

증상 삼진누산, 제로스킵, 방사전파, 삼진벡터, 희소행렬곱, 삼진합성곱, 삼진풀링을 463~469번에 배정했는데, 이 범위는 이미 TREE_INORDER(463)~HEAP_PUSH(469)가 선점하고 있었다. 트리/힙 자료구조 사용 시 신경망 명령이 실행되는 사고 발생.

원인 AI 텐서 연산을 추가할 때 기존 ISA729 배치표를 확인하지 않음.

수정

키워드이전이후
삼진누산463741
제로스킵464742
방사전파465743
삼진벡터466744
희소행렬곱467745
삼진합성곱468746
삼진풀링469747
GPU 블록(730~740) 직후 빈 공간에 배정. opcode.rs에 상수 추가, engine.rs에 핸들러 구현.


Bug #2 — TRIT_ENCODE/DECODE 불균형 3진수

증상 삼진인코딩(n)이 균형3진이 아닌 일반 3진수(0,1,2)를 반환. 음수는 부호 반전으로 처리해 디코딩이 깨졌다.

원인

c// 구형 — 불균형 (0,1,2)
for i in (0..6).rev() { trits[i] = v % 3; v /= 3; }
if neg { for t in &mut trits { *t = match *t { 0=>0, 1=>2, _=>1 }; } }
균형3진은 각 자리가 -1, 0, +1(Ta/Om/Ti)이어야 한다.

수정

rust// 균형3진 알고리즘: 나머지 2 → -1, 몫+1 carry
for i in (0..6).rev() {
    let mut r = n % 3;
    n /= 3;
    if r == 2  { r = -1; n += 1; }
    else if r == -2 { r = 1; n -= 1; }
    trits[i] = r as i8;
}

TRIT_DECODE도 acc * 3 + t.signum() 방식으로 수정. TRIT_MUL: 단순 곱셈 → signum 정규화 후 곱 (trit × trit ∈ {-1, 0, +1}).

검증

삼진디코딩(삼진인코딩(10))  = 10  ✓
삼진디코딩(삼진인코딩(-5))  = -5  ✓
삼진디코딩(삼진인코딩(0))   = 0   ✓
삼진디코딩(삼진인코딩(42)) + 삼진디코딩(삼진인코딩(-42)) = 0  ✓


Bug #3 — MAJORITY Om(0) 미처리

증상 다수결(+1, -1, 0) → 항상 Ti 또는 Ta만 반환. Om(0) 출력 불가.

원인

rust// 구형 — 이진 다수결 로직
let cnt = [a,b,c].iter().filter(|&&t| t == Trit::Ti).count();
self.stack.push(Value::Trit(if cnt >= 2 { Trit::Ti } else { Trit::Ta }));

수정

rust// 균형3진: 합의 부호
let sum = a.val() + b.val() + c.val();  // -3 ~ +3
self.stack.push(Value::Trit(
    if sum > 0 { Trit::Ti }
    else if sum < 0 { Trit::Ta }
    else { Trit::Om }
));

진리표:

abc결과
+1+1+1+3Ti
+1+10+2Ti
+1-100Om
-1-1-1-3Ta

Bug #4 — 셀/큐브/문서 옵코드 충돌 (624, 703, 704, 706)

증상 나중에 추가된 셀 DB 연산이 기존 셀 연산 번호를 덮어쓰고, 큐브생성문서주석이 모두 TIME_SECOND(624) 자리를 차지.

충돌 목록 및 해결

옵코드기존 (opcode.rs 기준)이전 hanseonc수정 후
624TIME_SECOND (초 반환)큐브생성, 문서주석 이중 충돌큐브생성751, 문서주석752
703CELL_EVID (셀근거)셀리트릿 충돌셀리트릿748
704CELL_DECIDE (셀결정)셀시냅스 충돌셀시냅스749
706CELL_PATH (셀경로)셀통계 충돌셀통계750
원칙: opcode.rs가 정답. hanseonc_high.c의 구형 항목을 옮김.


3. 현재 옵코드 배치 (고위험 영역)

신규 추가 블록 (741~752)

741  TMAC        삼진누산(가중치[], 입력[]) → MAC 합계
742  ZSKP        제로스킵(배열) → [비제로합, 0개수]
743  RBCS        방사전파(값, n) → [값; n]
744  TVEC        삼진벡터(a[], b[]) → 균형3진 내적
745  SMAT        희소행렬곱(a_flat, b_flat, cols)
746  TCONV       삼진합성곱(input, kernel) → 1D valid conv
747  TPOOL       삼진풀링(arr, stride) → max pool

748  CELL_RETREAT  셀리트릿(셀맵) → 신뢰도 -0.1
749  CELL_SYNAPSE  셀시냅스(from, to) → 시냅스 연결
750  CELL_STATS    셀통계() → [셀수, 연결수, 평균신뢰도]
751  CUBE_NEW      큐브생성() → [0×27] trit 배열
752  DOC_COMMENT   문서주석(텍스트) → 런타임 무시

기존 셀 블록 (703~709) — 변경 없음

703  CELL_EVID       셀근거(셀, 근거값)
704  CELL_DECIDE     셀결정(셀) → Claim
705  CELL_SEARCH     셀검색(패턴)
706  CELL_PATH       셀경로(from, to) → 배열
707  CELL_SUBGRAPH   셀부분그래프(루트, 깊이)
708  CELL_EXPORT     셀내보내기(셀) → JSON
709  CELL_IMPORT     셀가져오기(JSON) → 셀


4. 의도적 별칭 (중복이 아님)

아래는 같은 opcode를 가리키는 정상 별칭이다. 충돌 아님.

별칭 A별칭 Bopcode비고
비트곱트릿곱90trit-wise MIN
비트합트릿합91trit-wise MAX
소켓보내기소켓전송375SOCK_SEND
소켓받기소켓수신376SOCK_RECV
버퍼잘라버퍼자르기395BUF_SLICE
파일쓰기쓰기620FILE_WRITE
파일덧쓰기덧쓰기622FILE_APPEND

5. 관련 파일

파일역할
/Users/ef/Downloads/CrownyTVM/src/vm/opcode.rs정답 opcode 상수. 충돌 기준표
/Users/ef/Downloads/CrownyTVM/src/vm/engine.rsVM 핸들러. TRIT_, CELL_, TMAC~TPOOL
/Users/ef/CrownyOS/crownyc/hanseonc_high.c고수준 컴파일러 키워드→opcode 매핑
/Users/ef/CrownyOS/crownyc/pkg/hanseonc_high.cnpm 패키지 사본 (동일하게 수정)

6. 새 opcode 추가 시 절차

  1. opcode.rs에서 빈 번호 확인 (현재 최고: 752)
  2. opcode.rs에 상수 추가 + name() 함수에 등록
  3. engine.rs match 블록에 핸들러 추가
  4. hanseonc_high.c 키워드 테이블에 한글명 추가
  5. pkg/hanseonc_high.c에 동일하게 반영
  6. cargo test 통과 확인
  7. 이 문서 업데이트

7. 테스트 현황

cargo test (CrownyTVM) — 219개 전부 통과
  - vm_tests:     67개 (균형3진 encode/decode 5, majority 3 포함)
  - trit_tests:   43개
  - compiler_tests: 37개
  - 기타:         72개


작성: Claude Sonnet 4.6 — 2026-04-03