How can I read binary data in VHDL/modelsim whithout using special binary formats
Asked Answered
Y

3

6

I am writing a VHDL test bench for a ethernet MAC. The testbench consists of a package and an combined entity + architecture file. I want to read the ethernet frames that the testbench will send to the MAC from a binary file which I exported from wireshark.

I'm writing in VHDL 2008 and I'm using a Mentor Graphics Model Technology ModelSim ALTERA vcom 10.0d Compiler.

All solutions for reading binary data in VHDL/modelsim that I've found so far use special file formats where 1 bit of the bit_vector is represented by several bits in the file. I would like VHDL to read the binary file into 8 bit bit_vectors.

Closest I've gotten so far was using a character type file, where I can write 8 bit ASCII characters directly in binary representation.

Yulan answered 5/1, 2013 at 16:14 Comment(2)
Modelsim will read and write binary files generated by itself or another application. How you interpret the bits is up to your code.Noctambulism
I know I can read any file, interpreting it as 8 bit sections was the problem.Yulan
P
1

I used to do this, but have found it more productive to write a short script (in a serious text processing language) to convert from whatever input to a real VHDL file with the data described as a constant array of a suitable datatype.

This is much easier than doing file parsing in VHDL IMHO.

Pepe answered 8/1, 2013 at 14:10 Comment(4)
Yes, but I don't need to process the data much, I read it into arrays which I push into a linked list stack.Yulan
Even so, I'd avoid reading files in VHDL, and just write the VHDL arrays with a language designed for the job of reading files well.Pepe
What language would you suggest? Perl/Python?Yulan
Python is my language of choice for conversions. I also use Matlab for image processing development and write out "golden-data" in VHDL filesPepe
Y
4

To interpret the data directly in 8 bit parts, you need to use a file of the type character and convert them to integers using the 'POS attribute. You can then convert these integers to bit vectors:

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;
Yulan answered 8/1, 2013 at 12:59 Comment(0)
P
1

I used to do this, but have found it more productive to write a short script (in a serious text processing language) to convert from whatever input to a real VHDL file with the data described as a constant array of a suitable datatype.

This is much easier than doing file parsing in VHDL IMHO.

Pepe answered 8/1, 2013 at 14:10 Comment(4)
Yes, but I don't need to process the data much, I read it into arrays which I push into a linked list stack.Yulan
Even so, I'd avoid reading files in VHDL, and just write the VHDL arrays with a language designed for the job of reading files well.Pepe
What language would you suggest? Perl/Python?Yulan
Python is my language of choice for conversions. I also use Matlab for image processing development and write out "golden-data" in VHDL filesPepe
S
1

Based on previous answer from @youR.Fate, I was able to reduce the example further to:

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;
Strikebreaker answered 3/3, 2017 at 14:48 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.