Как я могу читать двоичные данные в VHDL/modelsim без использования специальных двоичных форматов
Немного предыстории:
Я пишу тестовый стенд VHDL для локальных сетей MAC. Тестовый стенд состоит из пакета и объединенного файла сущности + архитектуры. Я хочу прочитать фреймы Ethernet, которые испытательный стенд отправит на MAC из двоичного файла, который я экспортировал из wireshark.
Я пишу в VHDL 2008 и использую технологию графической модели Mentor ModelSim ALTERA vcom 10.0d Compiler.
Эта проблема:
Все решения для чтения двоичных данных в VHDL/modelsim, которые я обнаружил до сих пор, используют специальные форматы файлов, где 1 бит bit_vector представлен несколькими битами в файле. Я хотел бы, чтобы VHDL считывал двоичный файл в 8-битные битовые векторы.
Самое близкое, что я получил до сих пор, - это использование файла символьного типа, где я могу писать 8-битные символы ASCII непосредственно в двоичном представлении.
3 ответа
Раньше я делал это, но нашел более продуктивным написать короткий скрипт (на серьезном языке обработки текста) для преобразования любого входного файла в настоящий VHDL-файл с данными, описанными как константный массив подходящего типа данных.
Это намного проще, чем делать разбор файлов в VHDL IMHO.
Я нашел решение. Если я хочу интерпретировать данные непосредственно в 8-битных частях, мне нужно использовать файл типа символа и преобразовать их в целые числа с помощью атрибута 'POS. Затем я могу преобразовать эти целые числа в битовые векторы. Вот как я это сделал:
LIBRARY ieee;
USE ieee.std_logic_1164.ALL;
USE ieee.numeric_bit.ALL;
LIBRARY std;
USE std.textio.all;
...
TYPE t_char_file IF FILE OF character;
TYPE t_byte_arr IS ARRAY (natural RANGE <>) OF bit_vector(7 DOWNTO 0);
SIGNAL read_arr_byte : t_byte_arr(0 to 199);
...
read_file: PROCESS (start) IS
FILE file_in : t_char_file OPEN read_mode IS "./38478.bin"; -- open the frame file for reading
VARIABLE char_buffer : character;
BEGIN
IF start'EVENT AND start = '1' THEN
FOR i IN read_arr_byte'RANGE LOOP
read(file_in, char_buffer);
read_arr_byte(i) <= bit_vector(to_unsigned(character'POS(char_buffer), 8));
END LOOP; -- i
file_close(file_in);
END IF;
END PROCESS read_file;
Основываясь на предыдущем ответе @youR.Fate, я смог сократить пример до:
process is
type char_file_t is file of character;
file char_file : char_file_t;
variable char_v : character;
subtype byte_t is natural range 0 to 255;
variable byte_v : byte_t;
begin
file_open(char_file, "test.bin");
while not endfile(char_file) loop
read(char_file, char_v);
byte_v := character'pos(char_v);
report "Char: " & " #" & integer'image(byte_v);
end loop;
file_close(char_file);
wait;
end process;