# Аудит ieee.float_pkg для VHDL: 1 271 619 из 8 692 326 вызовов в 7-битном формате округлены неверно

- Опубликовано: 2026-11-15 07:33 UTC
- Раздел: Цифра и вычисления › Компьютеры
- Теги: пакет плавающей запятой VHDL, IEEE 1076-2008, IEEE 1076-2019, ошибки округления float_pkg, GHDL, NVC, округление sqrt, верификация аппаратуры, деление fixed_pkg, липкий бит
- Адрес: https://realtech.media/ru/news/rt-d3f0123305cb5819853eeda4_audit_ieee_float/

**Сверка с точной арифметикой выявила ошибки округления и остановки симулятора в пакете IEEE, который GHDL и NVC поставляют без изменений; авторы опубликовали патч.**

![Audit of VHDL ieee.float_pkg: 1,271,619 of 8,692,326 calls in a 7-bit format not correctly rounded](https://ecosistemastartup.com/wp-content/uploads/2026/11/vhdl-ieee-float-error-auditoria-1200x675.jpg)
*ecosistemastartup.com*

Авторы аудита, опубликованного на github.com, сообщают, что ieee.float_pkg, пакет чисел с плавающей запятой стандарта VHDL IEEE Std 1076-2008 и 1076-2019, возвращает результаты, округлённые неверно. Файл публикует IEEE, а GHDL и NVC поставляют его без изменений. Для всех операндов и пар в 7-битном формате (3 бита порядка, 3 бита дроби), а также всех троек для умножения с накоплением авторы выполнили 8 692 326 вызовов, и 1 271 619 из них округлены неверно [1].

Простейший случай — квадратный корень: sqrt(2,0) в двойной точности по умолчанию возвращает значение на одну единицу последнего разряда ниже верного [1]. Оно отстоит от корня на 0,565 единицы, тогда как правильно округлённое значение — на 0,435 [1]. Умножение с накоплением (-6)(-1)+(-5) возвращает -15 вместо 1; преобразование 2^-512 из двойной точности в одинарную возвращает 1,0; обратная величина 2^127 в одинарной точности возвращает бесконечность [1].

## Как выполнена проверка

Проверка считает операнды точными дробями, выполняет каждую операцию точно и округляет один раз перед сравнением [1]. Запуски выполнены в GHDL 7.0.0-dev и NVC 1.23.1, и на одних и тех же векторах оба записали одинаковые файлы результатов [1]. На каждую операцию, формат и стиль округления пришлось по 10 000 вызовов на операндах, подобранных под места, где арифметика ломается: денормализованные числа, оба края диапазона порядка, точные середины, знаковые нули, бесконечности [1].

В float32 это дало 81 068 неверных результатов и 272 остановки симулятора в 859 771 вызове; в float64 — 86 081 неверный и 445 остановок в 857 234 [1]. Затронуты и обычные операнды: из целых от 1 до 4 096 sqrt даёт расхождение на единицу для 256 в float32 и для 264 в float64 [1]. Минимальный тестовый файл содержит 25 вызовов: 24 печатают WRONG, а 25-й останавливает симулятор с выходом индекса за границы в строке 358 тела пакета [1].

## Причины и патч

Авторы связывают ошибки с конкретными строками файла IEEE. В normalize (строка 422) порядок обрезается до ширины на два бита больше целевого формата, поэтому при переходе из float64 в float32 берётся по модулю 1 024 [1]. В divide (строка 1243) и reciprocal (строка 1099) «липкий» бит, передаваемый в округление, — константа '1', из-за чего точные середины уходят к неверному соседу [1]. В reciprocal порядок результата не помещается в старшем двоичном интервале, и в float32 любой аргумент от 2^127 и выше даёт бесконечность [1]. Квадратный корень использует фиксированное число шагов Ньютона и не имеет «липкого» бита [1].

В репозитории лежат точный эталон, тестовое окружение, причины с номерами строк и патч. С патчем проходят все 32 470 838 вызовов из четырёх наборов тестов [1]. Авторы также сообщают, что деление в fixed_pkg даёт 41 026 неверных результатов из 751 418, и приводят патч и для него [1]. О проблемах сообщено в рабочую группу IEEE P1076 (VHDL-Issues 388), ghdl 3486, nvc 1758 и fphdl 4 [1].

## Источники

1. [github.com](https://github.com/lmtlssss/speedrunpapi/tree/main/hardware/audit/ieee-float-pkg)
2. [ecosistemastartup.com](https://ecosistemastartup.com/vhdl-el-paquete-float-de-ieee-falla-en-1-de-10-llamadas)

---

Источник: RealTech, realtech.media — https://realtech.media/ru/news/rt-d3f0123305cb5819853eeda4_audit_ieee_float/
