FPGARelated.com
Forums

ModelSim 6.0 v 5.7 Can't read file

Started by Brad Smallridge March 10, 2006
When I upgrade(?) to ISE 7.1.4 and ModelSim 6.0
I find my testbenches can not read binary files.  Is this
a technical problem or a downgrade on ModelSIM XE
free offering.  Note this is a binary file read not a textio file
read which, according to the manual, is still available.

Brad Smallridge
Ai Vision


Brad Smallridge wrote:
> When I upgrade(?) to ISE 7.1.4 and ModelSim 6.0 > I find my testbenches can not read binary files.
Try downloading and running this example and see if the resulting ./char_file.bin matches the source comments. http://home.comcast.net/~mike_treseler/char_file.vhd vcom char_file.vhd vsim -c char_file -do "run 1"; It works fine for me using Modelsim 6.1c. -- Mike Treseler
Yeah. That runs. Funny.

Here's my code:

LIBRARY ieee;
USE ieee.std_logic_1164.ALL;
USE ieee.numeric_std.ALL;

ENTITY tb IS
END tb;

ARCHITECTURE behavior OF tb IS

 component top
 port (
 clk         : in std_logic;
 reset       : in std_logic;
 vframe_in   : in std_logic;  -- 1 when the image is valid
 vline_in    : in std_logic;  -- 1 when the line is valid
 vblob  : out std_logic;
 vin    : in  std_logic_vector(7 downto 0);
 vred   : out std_logic_vector(7 downto 0);
 vgreen : out std_logic_vector(7 downto 0);
 vblue  : out std_logic_vector(7 downto 0)  );
 end component;

 signal clk        :  std_logic;
 signal reset      :  std_logic;
 signal vframe_in  :  std_logic;
 signal vline_in   :  std_logic;
-- signal vline_out  :  std_logic;
 signal vblob  :  std_logic;
 signal vin    :  std_logic_vector(7 downto 0);
 signal vred   :  std_logic_vector(7 downto 0);
 signal vgreen :  std_logic_vector(7 downto 0);
 signal vblue  :  std_logic_vector(7 downto 0);

 constant start_recording_row_delay : integer := 2;
 constant start_recording_col_delay : integer := 8;

 constant clkperiod    : time := 20 ns;
 constant line_synchs  : integer := 4;

 type     char_file is file of character;  -- one byte each

 file     my_file    : char_file;
 file     my_file2   : char_file;

 constant file_name  : string := "infile.bmp";
 constant file_name2 : string := "outfile.bmp";

 type int_array  is array(53 downto 0) of integer;
 type char_array is array(53 downto 0) of character;

 signal bmp_char:char_array;
 signal start_recording : std_logic;
 signal row_counter : std_logic_vector(15 downto 0);


   function bmp_function(
   bmp_header:int_array;
   bmp_start, bmp_data_size : integer
   ) return integer is
   variable result : integer;
   variable multiplier : integer;
   variable bmp_pointer : integer;
   begin
 result := 0;
 multiplier := 1;
 bmp_pointer := bmp_start;
     for i in 0 to (bmp_data_size-1) loop
   result := result + multiplier*bmp_header(bmp_pointer);
   multiplier := multiplier*256;
   bmp_pointer := bmp_pointer+1;
     end loop;
-- result_vector := 
std_logic_vector(to_unsigned(result,result_vector'length));
   return result;
   end function bmp_function;

  --BMP Header
      signal file_size : std_logic_vector(31 downto 0);
      signal reserved1 : std_logic_vector(31 downto 0);
      signal reserved2 : std_logic_vector(31 downto 0);
      signal offset : std_logic_vector(31 downto 0);

  --BMP Info
      signal size : std_logic_vector(31 downto 0);
      signal width : std_logic_vector(31 downto 0);
      signal height : std_logic_vector(31 downto 0);
      signal planes : std_logic_vector(31 downto 0);
      signal bits : std_logic_vector(31 downto 0);
      signal compression : std_logic_vector(31 downto 0);
      signal imagesize : std_logic_vector(31 downto 0);
      signal xresolution : std_logic_vector(31 downto 0);
      signal yresolution : std_logic_vector(31 downto 0);
      signal ncolors : std_logic_vector(31 downto 0);
      signal importantcolors : std_logic_vector(31 downto 0);

BEGIN

 uut: top PORT MAP(
  clk => clk,
  reset => reset,
  vframe_in  => vframe_in,
--  vframe_out => vframe_out,
  vline_in   => vline_in,
--  vline_out  => vline_out,
  vblob => vblob,
  vin => vin,
  vred => vred,
  vgreen => vgreen,
  vblue => vblue
 );


 clock_process: process
 begin
   clock_loop: loop
     clk <='0';
     wait for 5 ns;
     clk <='1';
     wait for 10 ns;
     clk <='0';
     wait for 5 ns;
   end loop clock_loop;
 end process clock_process;

 data_recording:process
 variable dr_my_char_v      : character;
 variable dr_int         : integer;
 variable dr_imagesize_var  : integer;
 variable dr_height_var     : integer;
 variable dr_width_var      : integer;
 variable dr_column_counter : integer;
 variable dr_row_counter_var: integer;
 begin
 start_recording <= '0';

    wait for clkperiod; -- let the other process go first
    wait for clkperiod; -- let the other process go first
    wait for clkperiod; -- let the other process go first
--    wait for clkperiod; -- let the other process go first
--    wait for clkperiod; -- let the other process go first

   -- convert std_logic_vectors to integers so that
   -- we can use multiple and divide operators
   dr_imagesize_var  := to_integer(unsigned(imagesize));
   dr_height_var     := to_integer(unsigned(height));
   dr_width_var      := to_integer(unsigned(width));
   dr_column_counter := 0;

   -- wait for the image to pass through the various row delays
   --      of the hardware before starting to record
   dr_row_counter_var := to_integer(unsigned(row_counter));
   while( dr_row_counter_var < start_recording_row_delay ) loop
      wait for clkperiod;
     dr_row_counter_var := to_integer(unsigned(row_counter));
   end loop;

   -- now wait a number of hardware column delays
   for dr_col_start in 0 to (start_recording_col_delay -1) loop
      wait for clkperiod;
   end loop;

   -- and now start recording output
   start_recording <= '1';
   for dr_row in 0 to (dr_height_var-1) loop
     for dr_col in 0 to (dr_width_var-1) loop
        wait for clkperiod;
       -- write three bytes of RGB data into the bmp file
       -- for each pixel/clock from the hardware
       dr_int := to_integer(unsigned(vblue));
       dr_my_char_v   := character'val(dr_int);
       write(my_file2,dr_my_char_v);
       dr_int := to_integer(unsigned(vgreen));
       dr_my_char_v   := character'val(dr_int);
       write(my_file2,dr_my_char_v);
       dr_int := to_integer(unsigned(vred));
       dr_my_char_v   := character'val(dr_int);
       write(my_file2,dr_my_char_v);
     end loop;

     -- pad the end of line with extra bytes
     -- for those BMP files that have widths
     -- that are not even multiples of 4
     if( dr_imagesize_var/dr_height_var > (3*dr_width_var) ) then
       for col in 1 to (dr_imagesize_var/dr_height_var-(3*dr_width_var)) 
loop
         dr_my_char_v := character'val(0);
         write(my_file2,dr_my_char_v);
       end loop;
     end if;

     -- end of line delay
     for col in 1 to line_synchs loop
       wait for clkperiod;
     end loop;
   end loop;

   file_close(my_file2);
   file_close(my_file);
   report "Success" severity failure;  -- failure will end it
 end process;

 tb : process
 variable bmp_header : int_array;

 variable tb_blue_char : character;
 variable tb_green_char : character;
 variable tb_red_char : character;
 variable tb_fill_char : character;

 variable tb_blue_int : integer;
 variable tb_green_int : integer;
 variable tb_red_int : integer;

 variable bluevalue : integer;
 variable greenvalue : integer;
 variable redvalue : integer;
 variable grayvalue : integer;

 variable vinblue   : character;
 variable vingreen  : character;
 variable vinred    : character;

  --BMP Header
      variable file_size_var : integer;
      variable reserved1_var : integer;
      variable reserved2_var : integer;
      variable offset_var    : integer;
  --BMP Info
      variable size_var        : integer;
      variable width_var       : integer;
      variable height_var      : integer;
      variable planes_var      : integer;
      variable bits_var        : integer;
      variable compression_var : integer;
      variable imagesize_var   : integer;
      variable xresolution_var : integer;
      variable yresolution_var : integer;
      variable ncolors_var     : integer;
      variable importantcolors_var : integer;

      variable row_count_var     : integer;

   begin

 file_open(my_file, file_name, read_mode);
 file_open(my_file2, file_name2, write_mode);

 for i in 0 to 53 loop
   read(my_file, tb_fill_char);
   bmp_header(i) := character'pos(tb_fill_char);
   bmp_char(i) <= tb_fill_char;
   write(my_file2,tb_fill_char);
 end loop;

 -- the first byte of a BMP file is a B
 assert bmp_header(0) = character'pos('B')
     report "first char not B" severity warning;

-- Brad Smallridge Ai Vision

 -- the second byte of a BMP file is an M
 assert bmp_header(1) = character'pos('M')
     report "second char not M" severity warning;

 -- here is the read BMP header in signal form
 file_size_var   := bmp_function(bmp_header,2,4);
 reserved1_var   := bmp_function(bmp_header, 6,2);
 reserved2_var   := bmp_function(bmp_header, 8,2);
 offset_var      := bmp_function(bmp_header,10,4);
 size_var        := bmp_function(bmp_header,14,4);
 width_var       := bmp_function(bmp_header,18,4);
 height_var      := bmp_function(bmp_header,22,4);
 planes_var      := bmp_function(bmp_header,26,2);
 bits_var        := bmp_function(bmp_header,28,2);
 compression_var := bmp_function(bmp_header,30,4);
 imagesize_var   := bmp_function(bmp_header,34,4);
 xresolution_var := bmp_function(bmp_header,38,4);
 yresolution_var := bmp_function(bmp_header,42,4);
 ncolors_var     := bmp_function(bmp_header,46,4);
 importantcolors_var := bmp_function(bmp_header,50,4);

 -- bmp header variables converted to signals
     file_size   <= std_logic_vector(to_unsigned(file_size_var, 
file_size'length));
     reserved1   <= std_logic_vector(to_unsigned(reserved1_var, 
reserved1'length));
     reserved2   <= std_logic_vector(to_unsigned(reserved2_var, 
reserved2'length));
     offset      <= std_logic_vector(to_unsigned(offset_var, 
offset'length));
     size        <= std_logic_vector(to_unsigned(size_var, size'length));
     width       <= std_logic_vector(to_unsigned(width_var, width'length));
     height      <= std_logic_vector(to_unsigned(height_var, 
height'length));
     planes      <= std_logic_vector(to_unsigned(planes_var, 
planes'length));
     bits        <= std_logic_vector(to_unsigned(bits_var, bits'length));
     compression <= std_logic_vector(to_unsigned(compression_var, 
compression'length));
     imagesize   <= std_logic_vector(to_unsigned(imagesize_var, 
imagesize'length));
     xresolution <= std_logic_vector(to_unsigned(xresolution_var, 
xresolution'length));
     yresolution <= std_logic_vector(to_unsigned(yresolution_var, 
yresolution'length));
     ncolors     <= std_logic_vector(to_unsigned(ncolors_var, 
ncolors'length));
     importantcolors <= std_logic_vector(to_unsigned(importantcolors_var, 
importantcolors'length));

 if( ncolors_var > 0 ) then
   report "bmp file not 24 bit type" severity failure;
 end if;

 reset <= '1';
 vframe_in <= '0';
 vline_in  <= '0';
 vin    <= (others=>'0');

 row_counter <= (others=>'0');
 row_count_var := 0;

  wait for clkperiod;

 reset <= '0';
  wait for clkperiod;

  vframe_in <= '1';
  wait for clkperiod;

  wait for clkperiod;

  for row in 0 to (height_var-1) loop

   vline_in <= '1';
   row_count_var := row_count_var+1;
       row_counter <=
   std_logic_vector(to_unsigned(row_count_var, row_counter'length));

--   report "row" severity warning;

   for col in 0 to (width_var-1) loop
   read (my_file, vinblue);
   read (my_file, vingreen);
   read (my_file, vinred);
   bluevalue  := character'pos(vinblue);
   redvalue   := character'pos(vingreen);
   greenvalue := character'pos(vinred);
   grayvalue  := (bluevalue + greenvalue + redvalue)/3;

   vin <= std_logic_vector(to_unsigned(grayvalue,vin'length));

   wait for clkperiod;

   end loop;

   -- Signal end of line to uut by dropping vline.
   -- Do a number of end of line clocks.
   -- Pull and write delayed response from vouts.

   -- If this loop is too short the output image
   -- will have a black streak, this is a bug in
   -- the timing.
   for col in 1 to line_synchs loop
     vline_in <= '0';
     vin <= (others=>'0');
     wait for clkperiod;

   end loop;

--   -- Pad the file output end of a line with extra bytes
--   --   to satisfy 4n address boundaries
   if( imagesize_var/height_var > (3*width_var) ) then
     for col in 1 to (imagesize_var/height_var-(3*width_var)) loop
     read (my_file, tb_fill_char);
     end loop;
   end if;

 end loop;

 vframe_in <= '0';

 file_close(my_file);

  end_of_input:loop
   -- keep vline_in going to flush output
   vline_in <= '1';
   row_count_var := row_count_var+1;
       row_counter <=
   std_logic_vector(to_unsigned(row_count_var, row_counter'length));
--   vin <= (others=>'0'); -- for light pixel detection
   vin <= (others=>'1'); -- for  dark pixel detection
   for col in 0 to (width_var-1) loop
     wait for clkperiod;
   end loop;
   vline_in <= '0';
   for col in 1 to line_synchs loop
     wait for clkperiod;
   end loop;
 end loop end_of_input;


   end process tb;

end;


Brad Smallridge wrote:
> Yeah. That runs. Funny. > Here's my code: > LIBRARY ieee; > USE ieee.std_logic_1164.ALL; > USE ieee.numeric_std.ALL; > > ENTITY tb IS > END tb; > ...
Modelsim compiles and elaborates your tb ok up to the uut. tb probably needs some code trace / debug to find the problem. Good luck. -- Mike Treseler PS: I would just covert the bmp file to a vhdl constant array using a script [bash|perl|python|etc]. ______________________________ 76 Sun Mar 12 /evtfs/home/tres/vhdl/play> vsim -c tb Reading /flip/usr1/modeltech/tcl/vsim/pref.tcl # // ModelSim SE 6.1c Nov 17 2005 Linux 2.6.5-7.201-smp # Loading /flip/usr1/modeltech/linux/../std.standard # Loading /flip/usr1/modeltech/linux/../ieee.std_logic_1164(body) # Loading /flip/usr1/modeltech/linux/../ieee.numeric_std(body) # Loading work.tb(behavior) # ** Warning: (vsim-3473) Component instance "uut : top" is not bound. # Time: 0 ns Iteration: 0 Region: /tb File: tb.vhd VSIM 1> run 1 # ** Failure: bmp file not 24 bit type # Time: 0 ns Iteration: 0 Process: /tb/tb File: tb.vhd # Break at tb.vhd line 311 # Stopped at tb.vhd line 311