VHDL/GHDL Двоичное 32-битное переполнение записи при установке старшего бита

У меня есть VHDL testbench, где я хотел бы записать 32-битные двоичные слова в файл для тестирования. Ниже приведен минимальный, полный, проверяемый пример.

При выполнении с GHDL (команды ниже) в указанной строке генерируется переполнение. Если строка закомментирована, выполнение завершается успешно и записывает файл. Переполнение происходит всякий раз, когда установлен старший бит.

library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use std.textio.all;
use std.env.stop;

entity u32_file_write is
end entity;

architecture rtl of u32_file_write is
    type intFileType is file of natural;
    file fh : intFileType;
begin
    run: process
        variable no_high_bit : std_logic_vector(31 downto 0) := x"7FFFFFFF";
        variable with_high_bit : std_logic_vector(31 downto 0) := x"FFFFFFFF";
    begin
        file_open(fh, "out.bin", write_mode);
        write(fh, to_integer(unsigned(no_high_bit)));
        write(fh, to_integer(unsigned(with_high_bit))); -- Overflow here.
        file_close(fh);
        stop;
    end process;
end architecture;

Я запускаю следующие команды GHDL для запуска кода VHDL (сохранить как u32_file_write.vhd):

ghdl -a -fexplicit --std=08 --ieee=synopsys u32_file_write.vhd
ghdl -e -fexplicit --std=08 --ieee=synopsys u32_file_write
ghdl -r -fexplicit --std=08 --ieee=synopsys u32_file_write

С закомментированной строкой исправленные результаты записываются в файл:

% od -tx4 out.bin
0000000 7fffffff

Если строка не закомментирована, генерируется переполнение:

ghdl:error: overflow detected
    from: ieee.numeric_std.to_integer at numeric_std-body.vhdl:3040
ghdl:error: simulation failed

Как отмечалось выше, запись будет работать с любым значением в первых 31-битах. Запись будет переполнена любым значением, для которого установлено 32-разрядное значение.

Основная проблема - целое число, высокое - 2^31-1. Увидеть:

В принятом ответе здесь говорится об использовании промежуточного "текстового" формата в текстовом языке обработки. Другой ответ показывает решение для чтения с использованием 'pos, но это не помогает мне писать.

Существует ли простая переделка / обходной путь, который позволит мне записать все 32-битные данные в двоичный файл?

2 ответа

Решение

Измените тип файла на символ. Преобразовать 8 бит за раз в символ и записать все четыре символа в файл,

С 8-битными записями вы несете ответственность за правильность порядка байтов.

Вы можете сделать это с помощью процедуры записи, предназначенной для записи 32-битных значений без знака в файл символов:

library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use std.textio.all;
use std.env.stop;

entity u32_file_write is
end entity;

architecture foo of u32_file_write is
    -- type intFileType is file of natural;  
    type intFileType is file of character;  -- CHANGED type mark
    file fh : intFileType;
    procedure write (file cf: intFileType; val: unsigned (31 downto 0)) is
    begin
        write (cf, character'val(to_integer(val( 7 downto  0))));
        write (cf, character'val(to_integer(val(15 downto  8))));
        write (cf, character'val(to_integer(val(23 downto 16))));
        write (cf, character'val(to_integer(val(31 downto 24))));
    end procedure;
begin
    run: process
        variable no_high_bit : std_logic_vector(31 downto 0) := x"7FFFFFFF";
        variable with_high_bit : std_logic_vector(31 downto 0) := x"FFFFFFFF";

    begin
        file_open(fh, "out.bin", write_mode);
        -- write(fh, to_integer(unsigned(no_high_bit)));
        -- write(fh, to_integer(unsigned(with_high_bit))); -- Overflow here.
        write (fh, unsigned(no_high_bit));
        write (fh, unsigned(with_high_bit));
        file_close(fh);
        stop;
    end process;
end architecture;
ghdl -a -fexplicit --std=08 --ieee=synopsys u32_file_write.vhdl
ghdl -e -fexplicit --std=08 --ieee=synopsys u32_file_write
ghdl -r -fexplicit --std=08 --ieee=synopsys u32_file_write

Обратите внимание, что единственным аргументом командной строки, кроме требуемой здесь команды (-a, -e, -r), является --std-08 из-за stop, Здесь нет ни зависимостей пакета Synopsys, ни требования для -fexplicit (от которого также не зависит).

od -tx4 out.bin
0000000          7fffffff        ffffffff
0000010

Файловая система хоста содержит файлы, которые состоят из массива 8-битных символов. Это соглашение (формат), которое накладывает идею чего-то большего.

VHDL накладывает тип на файловые транзакции, к сожалению, нет способа объявить натуральное значение диапазона больше 2 ** 31 -1, если бы ваши целые были больше, они не были бы переносимы.

Вышеупомянутый метод обрабатывает файлы как символьные файлы, позволяя накладывать размер элементов содержимого в соответствии с соглашениями (здесь, в хост-системе, если вы хотите прочитать 32-битный без знака, вы хотите прочитать 4 символа и собрать 32-битное значение в правильный порядок байтов).

Здесь unsigned_int является 32-битным значением без знака. Обратите внимание, что возрастающий или нисходящий порядок не обязательно должен совпадать при вызове подпрограммы из-за неявного преобразования подтипа (элементы формул и фактов здесь связаны в порядке слева направо).

Автор исходного сообщения столкнулся с проблемой, о которой сообщается в комментарии:

Приведенная выше запись () генерирует ошибку во время анализа:
u32_file_write.vhd: 23: 14: ошибка: не удается разрешить перегрузку для вызова подпрограммы.

Ошибка повторяется четыре раза, один раз для каждой записи (). Я не нашел способ заставить GHDL писать необработанные байты, кроме целых.

Строка 23 в комментарии соответствует 18-й строке выше, где символ 14 - список параметров первого вызова процедуры записи write[file IntFileType, character] который предлагает объявление для типа IntFileTypeтип определения типа не был изменен на тип character, Подпись вызовов процедуры не будет совпадать с сигнатурой неявно объявленной записи для типа файла IntFileTypeтакже отмечая, что номера строк не совпадают.

В этом ответе приведен полный код, позволяющий полностью копировать его из вопроса, что было сделано вместе с именованием файла дизайна с суффиксом.vhdl и использованием приведенных выше командных строк.

Используемой версией ghdl является недавняя сборка (GHDL 0.36-dev (v0.35-259-g4b16ef4)), созданная с помощью мошенника AdaCore 2015 GPL (GPL 2015 (20150428-49)) и протестированная с помощью генератора внутреннего кода llvm (clang+llvm-3.8.0) и генератор кода mcode как в MacOS (10.11.6, gnat-gpl-2015-x86_64-darwin-bin и clang+llvm-3.8.0-x86_64-apple-darwin, с использованием Xcode 8.2. 1).

(Порядковый порядок записи символов из val в новой процедуре записи был изменен, чтобы соответствовать OP od -xt out.bin порядок следования байтов)

Если вам абсолютно не нужен вывод в двоичном виде, вы можете использовать стандартные процедуры VHDL2008 для прямой записи ваших векторов без преобразования:

$ ghdl --version
GHDL 0.36-dev (v0.35-259-g4b16ef4c-dirty) [Dunoon edition]
 Compiled with GNAT Version: GPL 2017 (20170515-63)
 llvm code generator
Written by Tristan Gingold.

Copyright (C) 2003 - 2015 Tristan Gingold.
GHDL is free software, covered by the GNU General Public License.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
$ cat u32_file_write.vhd
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use std.textio.all;
use std.env.stop;

entity u32_file_write is
end entity;

architecture rtl of u32_file_write is
begin
    run: process
        variable no_high_bit : std_logic_vector(31 downto 0) := x"7FFFFFFF";
        variable with_high_bit : std_logic_vector(31 downto 0) := x"FFFFFFFF";
        variable l: line;
        file fh: text open write_mode is "out.txt";
    begin
        hwrite(l, no_high_bit);
        writeline(fh, l);
        hwrite(l, with_high_bit);
        writeline(fh, l);
        file_close(fh);
        stop;
    end process;
end architecture;
$ ghdl -a -fexplicit --std=08 u32_file_write.vhd
$ ghdl -e -fexplicit --std=08 u32_file_write
$ ghdl -r -fexplicit --std=08 u32_file_write
simulation stopped @0ms
$ cat out.txt
7FFFFFFF
FFFFFFFF
Другие вопросы по тегам