Question

What I want to do

I want to have a script in python or matlab that creates files which can be read by VHDL / modelsim as a file of real values.

What I've done so far

I've written a small VHDL entity that creates a file of real values so I can find out what format it uses. It looks like this:

library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use ieee.math_real.all;

library std;
use std.textio.all;

entity read_arr is
end entity read_arr;

architecture reader of read_arr is

  type t_real_arr is array (0 to 1023) of real;
  signal real_arr : t_real_arr := (others => 0.0);
  signal start    : std_logic := '0';
  signal filled   : std_logic := '0';
  type t_real_file is file of t_real_arr;
  file real_file : t_real_file;

begin  -- architecture reader

  start <= '0', '1' after 10 ns;

  fill_arr : process (start) is
    variable real_fill : real := -10.0;
  begin  -- process fill_arr
    if rising_edge(start) then
      for i in real_arr'range loop
        real_arr(i) <= real_fill;
        real_fill := real_fill + 0.25;
      end loop;  -- i
      filled <= '1';
    end if;
  end process fill_arr;

  wr_arr : process (filled) is
    variable filename : string (1 to 10) := "realvc.dat";
    variable status : file_open_status := status_error;
  begin  -- process fill_arr
    if rising_edge(filled) then
      file_open(status, real_file, filename, write_mode);
      write(real_file, real_arr);
      file_close(real_file);
    end if;
  end process wr_arr;

end architecture reader;

What it does is it fills an array of 1024 elements with real values starting from -10.0 and incrementing in steps of 0.25. It then writes this data into the binary file realvc.dat. The content of the file (viewed with a hex editor) can be seen in this gist.
It's easy to see that modelsim uses 64 bit to store each real value, but I haven't figured out what kind of format that is. It isn't ieee double-precision.

The Question

Does anyone know what kind of data format that is and how I can recreate it in a script language such as python or matlab?

Was it helpful?

Solution

The standard VHDL package std.textio makes it possible to read/write real in literal format to a text file, whereby scripting languages like Python can easily access it. The binary format is thereby avoided, which improves portability.

An example similar to the question code, doing first write then read of an array of real with std.textio is:

library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;

library std;
use std.textio.all;

entity test_arr is
end entity test_arr;

architecture test of test_arr is

begin

  process is

    type     real_arr_t is array (0 to 1023) of real;
    variable real_arr_v  : real_arr_t := (others => 0.0);
    variable real_fill_v : real := -10.0;

    procedure real_arr_write(variable real_arr : in real_arr_t) is
      file txt_file   : text;
      variable real_v : real;
      variable line_v : line;
    begin
      file_open(txt_file, "real.txt", write_mode);
      for idx in real_arr'range loop
        write(line_v, real_arr(idx));
        writeline(txt_file, line_v);
      end loop;
      file_close(txt_file);
    end procedure;

    procedure real_arr_read(variable real_arr : out real_arr_t) is
      file txt_file   : text;
      variable line_v : line;
      variable good_v : boolean;
    begin
      file_open(txt_file, "real.txt", read_mode);
      for idx in real_arr'range loop
        readline(txt_file, line_v);
        read(line_v, real_arr(idx), good_v);
        assert good_v report "Failed convert to real of: " & line_v.all severity FAILURE;
      end loop;
      file_close(txt_file);
    end procedure;

  begin

    -- Make and write real array to text file
    for i in real_arr_v'range loop
      real_arr_v(i) := real_fill_v;
      real_fill_v   := real_fill_v + 0.25;
    end loop;
    real_arr_write(real_arr_v);

    -- Read real array from text file
    real_arr_read(real_arr_v);

    -- End
    wait;

  end process;

end architecture test;

The real values in the "real.txt" file are then:

-1.000000e+001
-9.750000e+000
-9.500000e+000
-9.250000e+000

Python 3 can create strings like this with '{:e}'.format(x), and convert from this format using float(s).

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top