фатальная ошибка в симуляции vhdl

это мой код в vhdl

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
use ieee.std_logic_arith.all;
use ieee.numeric_std.all;
USE IEEE.STD_LOGIC_TEXTIO.ALL;
USE STD.TEXTIO.ALL;

entity inst_mem is
    port(
        load: in std_logic;
        address: in std_logic_vector (5 downto 0); 

        dataout: out std_logic_vector (10 downto 0)
        );
end entity;

architecture arch_inst_mem of inst_mem is
    TYPE inst_mem is array (0 to 32) of std_logic_vector(10 downto 0);

    procedure init_mem(variable memory : out inst_mem; 
                                    constant datafile : string) is
        file stddata: text;
        variable l: line;
        variable data: std_logic_vector (10 downto 0);
    begin
        file_open (stddata, datafile, READ_MODE);
        for i in memory'range(1) loop
            readline (stddata, l);
            read (l, data);
            memory(i):= data;
        end LOOP;
    end procedure;


begin
  process (load , address)
    variable memory: inst_mem;
  begin
    if (load = '1') then
        init_mem (memory, "inst_mem.txt");
        dataout <= memory (conv_integer(address));
    end if;
  end process;
end arch_inst_mem;

при компиляции у меня нет ошибки, когда я моделирую ее, у меня есть эта ошибка (# Неустранимая ошибка в цикле ForLoop в C:/Users/Bana/Desktop/Q1/inst_mem.vhd, строка 29) почему? спасибо, бана.


person Ali Banagozar    schedule 20.01.2015    source источник
comment
По крайней мере, добавьте вызов file_close в конце процедуры init_memory, чтобы соответствовать file_open. Убедитесь, что в файле inst_mem.txt указано правильное количество записей, поскольку нечетно, что порт address имеет 6 бит, что дает 64 (2 ** 6) записей, в то время как считываются 33 записи (от 0 до 32). Кроме того, рассмотрите возможность использования только пакета ieee.numeric_std, так как IEEE.STD_LOGIC_UNSIGNED и ieee.std_logic_arith не являются стандартными и могут быть заменены пакетом ieee.numeric_std.   -  person Morten Zilmer    schedule 20.01.2015
comment
Используйте только одну арифметическую библиотеку, как предложил Мортен. Почему в вашей ОЗУ 33 записи? Вы должны добавить тест EOF в свой цикл for, чтобы предотвратить ошибки.   -  person Paebbels    schedule 20.01.2015
comment
Строка 29 - это строка чтения ... фатальная ошибка возникает при чтении файла, которого у нас нет. Попытки ответить на вопрос здесь заканчиваются.   -  person user_1818839    schedule 20.01.2015
comment
Я бы поддержал комментарий Брайана, в цикле for всего 3 оператора. Похоже, у вас проблема с файлом stddata. Как отмечает Патрик Леманн, вы можете проверить EOF (ENDFILE), что позволит вам отметить, если ваш файл будет коротким. inst_mem — это массив (от 0 до 32), 33 записи, как отмечает Мортен Зилмер.   -  person    schedule 21.01.2015


Ответы (1)


Я бы поддержал комментарий Брайана, в цикле for всего 3 оператора. Похоже, у вас проблема с файлом stddata. Как отмечает Патрик Леманн, вы можете проверить EOF (ENDFILE), что позволит вам отметить, если ваш файл будет коротким. inst_mem — это массив (от 0 до 32), 33 записи, как отмечает Мортен Зилмер.

Я создал экземпляр вашей модели (с изменениями для поддержки VHDL-инструмента, совместимого с -1993, и переключением с conv_integer на to_integer в пакете numeric_std вы можете игнорировать дополнительные элементы в области деклараций архитектуры):

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
-- use IEEE.STD_LOGIC_UNSIGNED.ALL;
-- use ieee.std_logic_arith.all;
use ieee.numeric_std.all;
-- USE IEEE.STD_LOGIC_TEXTIO.ALL;
USE STD.TEXTIO.ALL;

entity inst_mem is
    port(
        load: in std_logic;
        address: in std_logic_vector (5 downto 0); 

        dataout: out std_logic_vector (10 downto 0)
        );
end entity;

architecture arch_inst_mem of inst_mem is
    TYPE inst_mem is array (0 to 32) of std_logic_vector(10 downto 0);

    type MVL9plus is ('U', 'X', '0', '1', 'Z', 'W', 'L', 'H', '-', ERROR);
    type MVL9_indexed_by_char is array (character) of STD_ULOGIC;
    type MVL9plus_indexed_by_char is array (character) of MVL9plus;

    constant char_to_MVL9: MVL9_indexed_by_char :=
        ('U' => 'U', 'X' => 'X', '0' => '0', '1' => '1', 'Z' => 'Z',
         'W' => 'W', 'L' => 'L', 'H' => 'H', '-' => '-', others => 'U');

    constant char_to_MVL9plus: MVL9plus_indexed_by_char := 
        ('U' => 'U', 'X' => 'X', '0' => '0', '1' => '1', 'Z' => 'Z',
         'W' => 'W', 'L' => 'L', 'H' => 'H', '-' => '-', others => ERROR);

    procedure READ(L:inout LINE; VALUE:out STD_LOGIC_VECTOR) is
        variable m:  STD_ULOGIC;
        variable c:  character;
        variable s:  string(1 to value'length-1);
        variable mv: STD_LOGIC_VECTOR(0 to value'length-1);
        constant allU: STD_LOGIC_VECTOR(0 to value'length-1)
                        := (others => 'U');
        variable GOOD: boolean;
    begin
        loop                    -- skip white space
            read(l,c);
            exit when ((c /= ' ') and (c /= CR) and (c /= HT));
        end loop;

        if (char_to_MVL9plus(c) = ERROR) then
            value := allU;
            good := FALSE;
            return;
        end if;

        read(l, s);
            for i in integer range 1 to value'length-1 loop
            if (char_to_MVL9plus(s(i)) = ERROR) then
                value := allU;
                good := FALSE;
                    return;
            end if;
        end loop;

        mv(0) := char_to_MVL9(c);
            for i in integer range 1 to value'length-1 loop
            mv(i) := char_to_MVL9(s(i));
            end loop;
        value := mv;
        good := TRUE;
    end READ;


    procedure init_mem(variable memory : out inst_mem; 
                                    constant datafile : string) is
        file stddata: text;
        variable l: line;
        variable data: std_logic_vector (10 downto 0);
    begin
        file_open (stddata, datafile, READ_MODE);
        for i in memory'range(1) loop
            readline (stddata, l);
            read (l, data);
            memory(i):= data;
        end LOOP;
    end procedure;


begin
  process (load , address)
    variable memory: inst_mem;
  begin
    if (load = '1') then
        init_mem (memory, "inst_mem.txt");
        dataout <= memory (to_integer(unsigned(address))); -- (conv_integer(address));
    end if;
  end process;
end arch_inst_mem;

И генерируется файл inst_mem.txt с 33 записями:

00000000000
00000000001
00000000010
00000000011
00000000100
00000000101
00000000110
00000000111
00000001000
00000001001
00000001010
00000001011
00000001100
00000001101
00000001110
00000001111
00000010000
00000010001
00000010010
00000010011
00000010100
00000010101
00000010110
00000010111
00000011000
00000011001
00000011010
00000011011
00000011100
00000011101
00000011110
00000011111
00000100000

И модель успешно работала под управлением ghdl (0.31, совместимость с -1993).

Сделав очень уродливые вещи в ghdl (который не поддерживает отображение переменных в осциллограммах), я могу продемонстрировать, что память inst_mem инициализируется последовательным вызовом процедуры init_mem: inst_mem.png (кликабельно )

Что более чем вероятно говорит о том, что у вас неправильное количество записей в inst_mem.txt, что приводит к ошибке, потому что ENDFILE не используется для обнаружения EOF:

ghdl -r inst_mem --wave=inst_mem.ghw
../../../src/std/textio_body.v93:558:5:@1ns:(сбой подтверждения): ошибка чтения символа
. /inst_mem:error: ошибка утверждения
./inst_mem:error: ошибка моделирования
ghdl: ошибка компиляции

Всего за 32 записи.

(И вы заметили, что ghdl не выполняет обратную трассировку в спецификации проекта.)

Если бы была недопустимая запись, вы бы получили кучу un-defines в определенном месте памяти.

Итак, похоже, вы должны были либо определить:

TYPE inst_mem is array (0 to 31) of std_logic_vector(10 downto 0);

введите inst_mem как массив из 32 элементов, или убедитесь, что ваш файл inst_mem.txt имеет нужное количество элементов, или использовали тест ENDFILE и просто не инициализировали оставшиеся элементы массива.

И добавление теста ENDFILE:

procedure init_mem(signal memory : out inst_mem; 
                                constant datafile : string) is
    file stddata: text;
    variable l: line;
    variable data: std_logic_vector (10 downto 0);
begin
    file_open (stddata, datafile, READ_MODE);
    for i in memory'range(1) loop
        if not ENDFILE(stddata) then
            readline (stddata, l);
            read (l, data);
            memory(i) <= data;
        end if;
    end LOOP;
    FILE_CLOSE(stddata);
end procedure;

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

Вы также заметите, что я добавил процедуру FILE_CLOSE, которую рекомендует Мортен, в соответствии с теорией, что вы можете повторно инициализировать массив памяти в любое время, когда у вас есть событие либо при загрузке, либо по адресу и load = '1'.

И это также говорит вам о том, что вы должны обнаруживать высокую нагрузку, а не уровень:

  process (load , address)
    variable memory: inst_mem;
  begin
    if load'event and load = '1' then
        init_mem (memory, "inst_mem.txt");
        dataout <= memory (conv_integer(address));
    end if;
  end process;

Предполагая, что это находится на испытательном стенде или не является целью синтеза.

Если вы намеревались предоставить файл инициализации для встраивания в битовый поток FPGA, вы должны придерживаться процесса поставщика для этого.

Вы пытаетесь использовать тот же процесс, потому что объявили память как переменную. Это может быть общая переменная. и у вас может быть два отдельных процесса: один для инициализации, другой для чтения.

Реализация памяти в качестве сигнала немного проще и в этом случае не приведет к снижению производительности.

(Меня интересуют вопросы текстио.)

person Community    schedule 20.01.2015
comment
Вот это ответ, выходящий за рамки служебного долга! - person user_1818839; 22.01.2015