Skip to content

feat(fpga): gf_mul behavioral core (verified, 2 oracles) + DSP48E1 wrapper - #197

Merged
gHashTag merged 3 commits into
mainfrom
feat/gf-mul-param
Jun 28, 2026
Merged

gHashTag merged 3 commits into
mainfrom
feat/gf-mul-param

Conversation

@gHashTag

Copy link
Copy Markdown
Owner

gf_mul_param.v (behavioral) — ВЕРИФИЦИРОВАН [смоделировано, 2 независимых oracle'а]

Параметрическое behavioral-ядро MUL (GF6–GF20), зеркало gf_adder_param.v (RNE+GRS, denormal I/O, HAS_INF family-split overflow, IEEE zero/Inf/NaN, gradual-underflow single-rounding).

  • Oracle №1 (faithful Python-транскрипция с reg_mask() + golden gf_ref.py на Fraction): GF6/GF8 exhaustive + GF12/GF16/GF20 representative 300k — 0 расхождений.
  • Oracle №2 (iverilog from-spec integer-reference, formal/gf_mul_ref_tb.v): GF6/GF8 exhaustive + GF16 (HAS_INF=1) 500k — 0 расхождений.
  • Найден+исправлен баг (59acaad): rounding-carry — mant_rnd [MANT+1 бит] wrap-ился на carry-out → проверка carry не срабатывала → exp++ терялся (1376/65536 GF8). Фикс: widen mant_rnd → MANT+2. Метод-урок: native-int транскрипция скрывает fixed-width wrap → reg_mask() обязателен (баг был только в Verilog, не в golden).

compute-SW MUL: GF6/GF8 exhaustive [verified], GF12/GF16/GF20 representative [смоделировано]. Та же планка зрелости, что у ADD (уже на main).

gf_mul_dsp_param.v (DSP48E1) — [ТРЕБУЕТ ДЕЙСТВИЯ]

Явный DSP48E1-инстанс (UG953, 49 портов, OPMODE P=A*B); фикс rounding-carry применён (синхронно с behavioral). Но UNISIM не симулируется без Vivado → эквивалентность behavioral↔DSP = [ТРЕБУЕТ ДЕЙСТВИЯ]: Vivado xsim co-sim + прогон на AX7203 (XC7A200T-2). До этого compute-HW MUL = 0/83.

Итог

  • compute-SW: GF6–GF20 MUL верифицирован (2 oracle'а).
  • compute-HW (ADD+MUL) = 0/83 — нужно железо (DSP-co-sim + AX7203 flash+UART).

🤖 Generated with Claude Code

gHashTag and others added 3 commits June 28, 2026 06:11
- gf_mul_param.v: параметрическое behavioral-ядро умножения GF6..GF20
  (зеркало gf_adder_param.v). Знак=XOR, сложение экспонент, нормализация,
  RNE(G,R,S), family-split overflow (HAS_INF), gradual-underflow напрямую
  от точного prod (единственное округление, без double-rounding),
  канонический quiet-NaN. Ширина prod=2*(MANT+1) [erratum 2606.05017 §5.5].
- gf_mul_dsp_param.v: DSP48E1-обёртка с ЯВНЫМ инстансом (UG479/UG953).
  OPMODE=0x05 (P=A*B), ALUMODE=0, INMODE=0, USE_DPORT=FALSE,
  USE_MULT=MULTIPLY, все RST* active-high, пайплайн 3 такта + конвейер
  метаданных/valid. Полный port-set (49 портов UG953).
- conformance/gf_mul_verify.py: transcription-оракул (RTL-модель на Python)
  vs золотой эталон. conformance/gf_ref.py: эталон на Fraction (exact).

Верификация [смоделировано]: 0 расхождений — GF6/8 exhaustive, GF12/16/20
по 300k+ random, denorm*denorm GF20 16.7M exhaustive.
DSP-версия = [ТРЕБУЕТ ДЕЙСТВИЯ]: UNISIM требует Vivado co-sim + железо AX7203.
compute-HW MUL = 0/83 (нет железа в песочнице).

Author: Vasilev, ORCID 0009-0008-4294-6159
mant_rnd was [MANT_BITS:0] (MANT+1 bits): mant_field[MANT:0]+1 wrapped to 0 on
carry-out, so the `> {1,all-ones}` check never fired and the exp++ was lost,
producing under-rounded results. Caught by an INDEPENDENT iverilog integer-reference
oracle (formal/gf_mul_ref_tb.v) that the Python-transcription oracle missed
(bug-equals-bug): 1376/65536 GF8 pairs. Fix: widen mant_rnd to [MANT_BITS+1:0]
so the carry is captured.

Verified [смоделировано, independent oracle #2]: GF6 exhaustive 4096/0,
GF8 exhaustive 65536/0 (was 1376 err), GF16 (HAS_INF=1) 500k random 0 errors
(Includes Inf/NaN/zero + rounding-carry edges).

Фикс rounding-carry в gf_mul_param.v: mant_rnd был MANT+1 бит, +1 к all-ones
давал wrap->0, проверка carry не срабатывала, exp++ терялся. Независимый iverilog
integer-reference (formal/gf_mul_ref_tb.v) поймал 1376/65536 GF8 пар; Python-транскрипция
промахнулась (bug-equals-bug). Фикс: widen mant_rnd до MANT+2 бит. GF6/GF8 exhaustive +
GF16 (HAS_INF=1) 500k random = 0 расхождений.

Co-Authored-By: Claude <noreply@anthropic.com>
1. gf_mul_dsp_param.v: mant_rnd reg[MANT:0] -> reg[MANT+1:0]
   (тот же rounding-carry фикс, что в gf_mul_param.v @59acaad; родственный
   файл имел тот же узкий регистр -> wrap->0 терял exp++).
2. conformance/gf_mul_verify.py: добавлен reg_mask() для моделирования
   фиксированной ширины reg (REG_W=MANT+2). Старая native-int версия
   скрывала fixed-width wrap. Re-verify: GF6/GF8 exhaustive 0,
   GF12/16/20 representative 300k 0.

[смоделировано] 2 oracle (faithful transcription + golden Fraction).
DSP48E1-эквивалентность = [ТРЕБУЕТ ДЕЙСТВИЯ]: Vivado xsim + AX7203.
@gHashTag
gHashTag merged commit fbb1019 into main Jun 28, 2026
24 of 48 checks passed
gHashTag added a commit that referenced this pull request Jun 28, 2026
…I-debt P0

MUL compute-SW recorded: gf_mul_param.v verified by 2 independent oracles
(GF6/GF8 exhaustive + GF12/16/20 representative = 0). rounding-carry bug found
by iverilog from-spec oracle #2, missed by native-int transcription (reg_mask
lesson). DSP wrapper [ТРЕБУЕТ ДЕЙСТВИЯ]. CI-debt (build.zig workflow) flagged P0.

Документирование в SSOT-матрице: MUL на main, верифицирован 2 oracle'ами,
баг rounding-carry пойман from-spec oracle. DSP — [ТРЕБУЕТ ДЕЙСТВИЯ]. CI-долг
build.zig — P0.

Co-Authored-By: Claude <noreply@anthropic.com>
@gHashTag
gHashTag deleted the feat/gf-mul-param branch July 15, 2026 10:08
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant