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;