├── LICENSE ├── README.md ├── doc └── testbench.svg ├── rtl ├── bmp_pkg.vhd ├── bmp_sink.vhd ├── bmp_source.vhd └── vga_bmp_sink.vhd └── sim ├── bmp_source_sink_TB.vhd └── img ├── bars.bmp └── lenna.bmp /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2017 mr-kenhoff 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Bitmap VHDL Package 2 | 3 | 4 | ## Overview 5 | Debugging image processing pipelines is very challenging. 6 | Running the design on real hardware lets you see what your image actually looks like, but lacks the in depth information a simulator can provide. The other way around you are able to see whats happening to your signals inside your design, but not how those signals translate to your image. 7 | 8 | This small vhdl package "extends" the debugging capabilities of the simulator by providing the ability to view the image data flowing down the pipeline. 9 | Simply hook the bmp_sink component to your image pipeline and start simulating. It stores the arriving image data into a bitmap file on your hard drive. By using multiple bmp_sink components you can evaluate the image data on different stages as they get processed. 10 | 11 | The bmp_source component does exactly what its name implies. It reads a bitmap file from your harddrive and sources it to your pipeline. 12 | This way you can test your pipeline with real images. 13 | 14 | Of course the files provided are **not synthesizable**, since it uses file IO on the host. 15 | 16 | ## Customizing 17 | You may build your own glue-logic to fit your specific video-bus by utilizing the low level bitmap access functions provided in the bmp_pkg.vhd file. 18 | Take a look at bmp_sink.vhd and bmp_source.vhd. 19 | 20 | ## Running the tests 21 | 22 | ## Test images 23 | 24 | ## TODO 25 | - [ ] Add support for sourcing image sequences 26 | - [ ] Unit tests for all modules 27 | - [ ] Add examples 28 | 29 | 30 | ## License 31 | -------------------------------------------------------------------------------- /doc/testbench.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 19 | 21 | 29 | 35 | 36 | 44 | 50 | 51 | 59 | 61 | 66 | 71 | 76 | 77 | 78 | 86 | 88 | 93 | 98 | 103 | 104 | 105 | 113 | 116 | 121 | 126 | 131 | 136 | 141 | 146 | 147 | 148 | 156 | 162 | 163 | 171 | 177 | 178 | 186 | 192 | 193 | 201 | 207 | 208 | 216 | 222 | 223 | 231 | 237 | 238 | 246 | 252 | 253 | 261 | 267 | 268 | 276 | 282 | 283 | 291 | 297 | 298 | 306 | 312 | 313 | 321 | 327 | 328 | 336 | 342 | 343 | 351 | 357 | 358 | 366 | 372 | 373 | 381 | 387 | 388 | 396 | 402 | 403 | 411 | 417 | 418 | 426 | 432 | 433 | 441 | 447 | 448 | 456 | 462 | 463 | 471 | 477 | 478 | 486 | 492 | 493 | 501 | 507 | 508 | 516 | 522 | 523 | 531 | 537 | 538 | 546 | 552 | 553 | 561 | 567 | 568 | 569 | 587 | 590 | 591 | 593 | 594 | 596 | image/svg+xml 597 | 599 | 600 | 601 | 602 | 603 | 608 | 614 | 620 | 627 | 633 | 639 | 645 | BMP 667 | 673 | 679 | 686 | Image pipeline(Device under test) 709 | bmp_source.vhd 730 | bmp_sink.vhd 750 | 756 | 762 | 769 | 775 | 781 | 787 | BMP 798 | 804 | Testbench 815 | 826 | 827 | -------------------------------------------------------------------------------- /rtl/bmp_pkg.vhd: -------------------------------------------------------------------------------- 1 | ------------------------------------------------------------------------------- 2 | -- File : bmp_pkg.vhd 3 | -- Author : mr-kenhoff 4 | ------------------------------------------------------------------------------- 5 | -- Description: 6 | -- Low level access to bitmap files 7 | -- 8 | -- Target: Simulator 9 | -- Dependencies: none 10 | ------------------------------------------------------------------------------- 11 | 12 | library ieee; 13 | use ieee.std_logic_1164.all; 14 | use ieee.numeric_std.all; 15 | use ieee.math_real.all; 16 | 17 | 18 | package bmp_pkg is 19 | 20 | constant BMP_MAX_WIDTH : integer := 700; 21 | constant BMP_MAX_HEIGHT : integer := 640; 22 | 23 | subtype bmp_slv8_t is std_logic_vector(7 downto 0); 24 | subtype bmp_slv16_t is std_logic_vector(15 downto 0); 25 | subtype bmp_slv32_t is std_logic_vector(31 downto 0); 26 | 27 | 28 | 29 | type bmp_meta is 30 | record 31 | width : integer; 32 | height : integer; 33 | end record; 34 | 35 | type bmp_pix is 36 | record 37 | r: bmp_slv8_t; 38 | g: bmp_slv8_t; 39 | b: bmp_slv8_t; 40 | end record; 41 | 42 | type bmp_line is array (0 to BMP_MAX_WIDTH-1) of bmp_pix; 43 | type bmp_data is array (0 to BMP_MAX_HEIGHT-1) of bmp_line; 44 | 45 | type bmp is 46 | record 47 | meta : bmp_meta; 48 | data: bmp_data; 49 | end record; 50 | 51 | type bmp_ptr is access bmp; 52 | 53 | 54 | 55 | ---------------------------------------------------------------------------- 56 | -- Public procedures and functions 57 | ---------------------------------------------------------------------------- 58 | 59 | procedure bmp_open ( ptr : inout bmp_ptr; filename : in string ); 60 | procedure bmp_save ( ptr : inout bmp_ptr; filename : in string ); 61 | 62 | procedure bmp_get_width ( ptr : inout bmp_ptr; width : out integer); 63 | procedure bmp_get_height ( ptr : inout bmp_ptr; height : out integer); 64 | 65 | procedure bmp_get_pix ( ptr : inout bmp_ptr; x: in natural; y : in natural; pix : out bmp_pix ); 66 | procedure bmp_set_pix ( ptr : inout bmp_ptr; x: in natural; y : in natural; pix : in bmp_pix ); 67 | 68 | 69 | end package bmp_pkg; 70 | 71 | 72 | 73 | package body bmp_pkg is 74 | 75 | 76 | ---------------------------------------------------------------------------- 77 | -- Types 78 | ---------------------------------------------------------------------------- 79 | 80 | type bmp_file is file of character; 81 | 82 | type bmp_header_array is array (0 to 53) of bmp_slv8_t; 83 | 84 | 85 | ---------------------------------------------------------------------------- 86 | -- Constants 87 | ---------------------------------------------------------------------------- 88 | 89 | constant BMP_STD_HEADER_ARRAY : bmp_header_array := ( 90 | "01000010", "01001101", "00110110", "00000000", "00001100", "00000000", 91 | "00000000", "00000000", "00000000", "00000000", "00110110", "00000000", 92 | "00000000", "00000000", "00101000", "00000000", "00000000", "00000000", 93 | "00000000", "00000000", "00000000", "00000000", "00000000", "00000000", 94 | "00000000", "00000000", "00000001", "00000000", "00011000", "00000000", 95 | "00000000", "00000000", "00000000", "00000000", "00000000", "00000000", 96 | "00000000", "00000000", "11000100", "00001110", "00000000", "00000000", 97 | "11000100", "00001110", "00000000", "00000000", "00000000", "00000000", 98 | "00000000", "00000000", "00000000", "00000000", "00000000", "00000000" 99 | ); 100 | 101 | 102 | ---------------------------------------------------------------------------- 103 | -- Procedures 104 | ---------------------------------------------------------------------------- 105 | 106 | procedure bmp_open ( ptr : inout bmp_ptr; filename : in string ) is 107 | 108 | file fp : bmp_file open read_mode is filename; 109 | variable header_array : bmp_header_array; 110 | variable byte : character; 111 | variable val : integer; 112 | 113 | variable tmp_slv32 : bmp_slv32_t; -- Temporary variable 114 | 115 | variable file_pos : integer := 0; 116 | variable data_offset : integer; 117 | 118 | begin 119 | 120 | -- Read bitmap header into array 121 | for i in 0 to 53 loop 122 | read( fp, byte ); 123 | val := character'pos( byte ); 124 | 125 | header_array(i) := bmp_slv8_t(to_unsigned(val, bmp_slv8_t'length)); 126 | file_pos := file_pos + 1; 127 | end loop; 128 | 129 | -- TODO: Validate bitmap 130 | 131 | -- Extract image width from array 132 | tmp_slv32 := header_array(21) & header_array(20) & header_array(19) & header_array(18); 133 | ptr.meta.width := to_integer(signed(tmp_slv32)); 134 | -- Extract image height from array 135 | tmp_slv32 := header_array(25) & header_array(24) & header_array(23) & header_array(22); 136 | ptr.meta.height := to_integer(signed(tmp_slv32)); 137 | -- Extract offset of image data from array 138 | tmp_slv32 := header_array(13) & header_array(12) & header_array(11) & header_array(10); 139 | data_offset := to_integer(signed(tmp_slv32)); -- HACK: actually the data offset is not signed 140 | 141 | 142 | assert ptr.meta.width <= BMP_MAX_WIDTH report "Image height too big. Increase BMP_MAX_WIDTH!" severity error; 143 | assert ptr.meta.height <= BMP_MAX_HEIGHT report "Image width too big. Increase BMP_MAX_HEIGHT!" severity error; 144 | 145 | 146 | -- Fast forward to image data 147 | while file_pos < data_offset loop 148 | read( fp, byte ); 149 | file_pos := file_pos + 1; 150 | end loop; 151 | 152 | 153 | -- Extract image data 154 | line : for y in ptr.meta.height-1 downto 0 loop 155 | pix : for x in 0 to ptr.meta.width -1 loop 156 | 157 | -- Blue pixel 158 | read( fp, byte ); 159 | val := character'pos( byte ); 160 | ptr.data(y)(x).b := bmp_slv8_t(to_unsigned(val, bmp_slv8_t'length)); 161 | -- Green pixel 162 | read( fp, byte ); 163 | val := character'pos( byte ); 164 | ptr.data(y)(x).g := bmp_slv8_t(to_unsigned(val, bmp_slv8_t'length)); 165 | -- Red pixel 166 | read( fp, byte ); 167 | val := character'pos( byte ); 168 | ptr.data(y)(x).r := bmp_slv8_t(to_unsigned(val, bmp_slv8_t'length)); 169 | 170 | end loop; 171 | end loop; 172 | 173 | end bmp_open; 174 | 175 | 176 | procedure bmp_save ( ptr : inout bmp_ptr; filename : in string ) is 177 | 178 | file fp : bmp_file open write_mode is filename; 179 | variable header_array : bmp_header_array := BMP_STD_HEADER_ARRAY; 180 | variable byte : character; 181 | variable val : integer; 182 | 183 | variable tmp_slv32 : bmp_slv32_t; -- Temporary variable 184 | 185 | begin 186 | 187 | --Inject image width into bitmap header 188 | tmp_slv32 := bmp_slv32_t(to_signed(ptr.meta.width, bmp_slv32_t'length)); 189 | header_array(21) := tmp_slv32(31 downto 24); 190 | header_array(20) := tmp_slv32(23 downto 16); 191 | header_array(19) := tmp_slv32(15 downto 8); 192 | header_array(18) := tmp_slv32(7 downto 0); 193 | --Inject image height into bitmap header 194 | tmp_slv32 := bmp_slv32_t(to_signed(ptr.meta.height, bmp_slv32_t'length)); 195 | header_array(25) := tmp_slv32(31 downto 24); 196 | header_array(24) := tmp_slv32(23 downto 16); 197 | header_array(23) := tmp_slv32(15 downto 8); 198 | header_array(22) := tmp_slv32(7 downto 0); 199 | 200 | -- Write array into bitmap header 201 | for i in 0 to 53 loop 202 | 203 | val := to_integer(unsigned(header_array(i))); 204 | byte := character'val(val); 205 | 206 | write( fp, byte ); 207 | end loop; 208 | 209 | 210 | -- Write image data 211 | line : for y in ptr.meta.height-1 downto 0 loop 212 | pix : for x in 0 to ptr.meta.width -1 loop 213 | 214 | -- Blue pixel 215 | val := to_integer(unsigned(ptr.data(y)(x).b)); 216 | byte := character'val(val); 217 | write( fp, byte ); 218 | -- Green pixel 219 | val := to_integer(unsigned(ptr.data(y)(x).g)); 220 | byte := character'val(val); 221 | write( fp, byte ); 222 | -- Red pixel 223 | val := to_integer(unsigned(ptr.data(y)(x).r)); 224 | byte := character'val(val); 225 | write( fp, byte ); 226 | 227 | end loop; 228 | end loop; 229 | 230 | end bmp_save; 231 | 232 | 233 | procedure bmp_get_width ( ptr : inout bmp_ptr; width : out integer) is 234 | begin 235 | width := ptr.meta.width; 236 | end bmp_get_width; 237 | 238 | 239 | procedure bmp_get_height ( ptr : inout bmp_ptr; height : out integer) is 240 | begin 241 | height := ptr.meta.height; 242 | end bmp_get_height; 243 | 244 | 245 | procedure bmp_get_pix ( ptr : inout bmp_ptr; x: in natural; y : in natural; pix : out bmp_pix ) is 246 | begin 247 | pix := ptr.data(y)(x); 248 | end bmp_get_pix; 249 | 250 | procedure bmp_set_pix ( ptr : inout bmp_ptr; x: in natural; y : in natural; pix : in bmp_pix ) is 251 | begin 252 | ptr.data(y)(x) := pix; 253 | 254 | -- Increase image size if nessecary 255 | if x+1 > ptr.meta.width then 256 | ptr.meta.width := x+1; 257 | end if; 258 | 259 | if y+1 > ptr.meta.height then 260 | ptr.meta.height := y+1; 261 | end if; 262 | end bmp_set_pix; 263 | 264 | 265 | end bmp_pkg; 266 | 267 | -------------------------------------------------------------------------------- /rtl/bmp_sink.vhd: -------------------------------------------------------------------------------- 1 | ------------------------------------------------------------------------------- 2 | -- File : bmp_sink.vhd 3 | -- Author : mr-kenhoff 4 | ------------------------------------------------------------------------------- 5 | -- Description: 6 | -- Takes a data stream and saves it to a bitmap image 7 | 8 | -- Target: Simulator 9 | -- Dependencies: bmp_pkg.vhd 10 | ------------------------------------------------------------------------------- 11 | 12 | library ieee; 13 | use ieee.std_logic_1164.all; 14 | use ieee.numeric_std.all; 15 | 16 | use work.bmp_pkg.all; 17 | 18 | entity bmp_sink is 19 | generic ( 20 | FILENAME : string; 21 | SEQUENCE : string := "TRUE" 22 | ); 23 | port ( 24 | clk_i : in std_logic; 25 | rst_i : in std_logic; 26 | 27 | val_i : in std_logic; 28 | dat_i : in std_logic_vector(23 downto 0); 29 | rdy_o : out std_logic := '1'; 30 | eol_i : in std_logic; 31 | eof_i : in std_logic; 32 | 33 | halt_i : in std_logic 34 | ); 35 | end entity; 36 | 37 | architecture behavioural of bmp_sink is 38 | 39 | signal x : natural := 0; 40 | signal y : natural := 0; 41 | signal iteration : integer := 0; 42 | 43 | begin 44 | 45 | rdy_o <= not halt_i when rising_edge(clk_i); 46 | 47 | 48 | 49 | sink_process : process( clk_i ) 50 | variable sink_bmp : bmp_ptr; 51 | variable sink_pix : bmp_pix; 52 | variable is_bmp_created : boolean := false; 53 | variable is_bmp_saved : boolean := false; 54 | begin 55 | 56 | -- Create bitmap on startup 57 | if is_bmp_created = false then 58 | sink_bmp := new bmp; 59 | is_bmp_created := true; 60 | end if; 61 | 62 | if rising_edge( clk_i ) then 63 | if rst_i = '1' then 64 | x <= 0; 65 | y <= 0; 66 | else 67 | if val_i = '1' and halt_i = '0' then 68 | sink_pix.r := dat_i(23 downto 16); 69 | sink_pix.g := dat_i(15 downto 8); 70 | sink_pix.b := dat_i(7 downto 0); 71 | 72 | bmp_set_pix( sink_bmp, x, y, sink_pix ); 73 | 74 | if eol_i = '1' then 75 | x <= 0; 76 | if eof_i = '1' then 77 | y <= 0; 78 | -- Frame completed. Save to bitmap.. 79 | if SEQUENCE = "FALSE" then 80 | if is_bmp_saved = false then 81 | bmp_save( sink_bmp, FILENAME & ".bmp" ); 82 | is_bmp_saved := true; 83 | end if; 84 | elsif SEQUENCE = "TRUE" then 85 | bmp_save( sink_bmp, FILENAME & "_" & INTEGER'IMAGE(iteration) & ".bmp" ); 86 | is_bmp_saved := true; 87 | end if; 88 | iteration <= iteration + 1; 89 | else 90 | y <= y + 1; 91 | end if; 92 | else 93 | x <= x + 1; 94 | end if; 95 | end if; 96 | end if; 97 | end if; 98 | end process; 99 | 100 | 101 | end architecture; 102 | 103 | -------------------------------------------------------------------------------- /rtl/bmp_source.vhd: -------------------------------------------------------------------------------- 1 | ------------------------------------------------------------------------------- 2 | -- File : bmp_source.vhd 3 | -- Author : mr-kenhoff 4 | ------------------------------------------------------------------------------- 5 | -- Description: 6 | -- Outputs a bitmap image as a data stream 7 | -- Target: Simulator 8 | -- Dependencies: bmp_pkg.vhd 9 | ------------------------------------------------------------------------------- 10 | 11 | library ieee; 12 | use ieee.std_logic_1164.all; 13 | use ieee.numeric_std.all; 14 | 15 | use work.bmp_pkg.all; 16 | 17 | entity bmp_source is 18 | generic ( 19 | FILENAME : string; 20 | ITERATIONS : natural; 21 | BACKPRESSURE_EN : boolean := false 22 | ); 23 | port ( 24 | clk_i : in std_logic; 25 | rst_i : in std_logic; 26 | 27 | val_o : out std_logic := '0'; 28 | dat_o : out std_logic_vector(23 downto 0) := (others => '0'); 29 | rdy_i : in std_logic; 30 | eol_o : out std_logic := '0'; 31 | eof_o : out std_logic := '0' 32 | ); 33 | end entity; 34 | 35 | architecture behavioural of bmp_source is 36 | 37 | begin 38 | 39 | 40 | 41 | source_process : process( clk_i ) 42 | variable source_bmp : bmp_ptr; 43 | variable source_pix : bmp_pix; 44 | variable is_bmp_loaded : boolean := false; 45 | 46 | variable iteration : natural := 0; 47 | variable x : natural := 0; 48 | variable y : natural := 0; 49 | begin 50 | 51 | if is_bmp_loaded = false then 52 | source_bmp := new bmp; 53 | bmp_open(source_bmp, FILENAME); 54 | is_bmp_loaded := true; 55 | end if; 56 | 57 | if rising_edge( clk_i ) then 58 | 59 | eol_o <= '0'; 60 | eof_o <= '0'; 61 | val_o <= '0'; 62 | 63 | if rst_i = '1' then 64 | iteration := 0; 65 | x := 0; 66 | y := 0; 67 | else 68 | 69 | 70 | 71 | if (BACKPRESSURE_EN and rdy_i = '1') or not BACKPRESSURE_EN then 72 | 73 | if iteration < ITERATIONS then 74 | 75 | bmp_get_pix( source_bmp, x, y, source_pix ); 76 | dat_o(23 downto 16) <= source_pix.r; 77 | dat_o(15 downto 8) <= source_pix.g; 78 | dat_o(7 downto 0) <= source_pix.b; 79 | 80 | val_o <= '1'; 81 | 82 | 83 | 84 | if x = source_bmp.meta.width-1 then -- EOL 85 | eol_o <= '1'; 86 | x := 0; 87 | if y = source_bmp.meta.height-1 then -- EOF 88 | eof_o <= '1'; 89 | y := 0; 90 | iteration := iteration + 1; 91 | else -- Not EOF 92 | y := y + 1; 93 | end if; 94 | else -- Not EOL 95 | x := x + 1; 96 | end if; 97 | 98 | end if; -- if iteration < ITERATIONS 99 | 100 | end if; 101 | 102 | 103 | 104 | end if; 105 | end if; 106 | 107 | end process; 108 | 109 | 110 | end architecture; 111 | -------------------------------------------------------------------------------- /rtl/vga_bmp_sink.vhd: -------------------------------------------------------------------------------- 1 | ------------------------------------------------------------------------------- 2 | -- File : vga_bmp_sink.vhd 3 | -- Author : mr-kenhoff 4 | ------------------------------------------------------------------------------- 5 | -- Description: 6 | -- Saves a conventional VGA-Standard input into a .bmp File 7 | -- 8 | -- Target: Simulator 9 | -- Dependencies: bmp_pkg.vhd 10 | ------------------------------------------------------------------------------- 11 | 12 | library IEEE; 13 | use IEEE.STD_LOGIC_1164.ALL; 14 | 15 | use work.bmp_pkg.all; 16 | 17 | entity vga_bmp_sink is 18 | generic ( 19 | FILENAME : string 20 | ); 21 | port ( 22 | clk_i : in std_logic; 23 | 24 | dat_i : in std_logic_vector(23 downto 0); 25 | active_vid_i : in std_logic; 26 | h_sync_i : in std_logic; 27 | v_sync_i : in std_logic 28 | 29 | ); 30 | end vga_bmp_sink; 31 | 32 | architecture Behavioral of vga_bmp_sink is 33 | 34 | signal h_sync_dly : std_logic := '0'; 35 | signal v_sync_dly : std_logic := '0'; 36 | 37 | signal eol : std_logic := '0'; 38 | signal eof : std_logic := '0'; 39 | 40 | signal x : natural := 0; 41 | signal y : natural := 0; 42 | 43 | signal is_active_line : std_logic := '0'; 44 | signal is_active_frame : std_logic := '0'; 45 | 46 | begin 47 | 48 | h_sync_dly <= h_sync_i when rising_edge(clk_i); 49 | v_sync_dly <= v_sync_i when rising_edge(clk_i); 50 | 51 | eol_eof_gen_process : process(clk_i) 52 | begin 53 | if rising_edge(clk_i) then 54 | -- EOL 55 | if h_sync_dly = '0' and h_sync_i = '1' then 56 | eol <= '1'; 57 | else 58 | eol <= '0'; 59 | end if; 60 | 61 | -- EOF 62 | if v_sync_dly = '0' and v_sync_i = '1' then 63 | eof <= '1'; 64 | else 65 | eof <= '0'; 66 | end if; 67 | end if; 68 | end process; 69 | 70 | sink_process : process( clk_i ) 71 | variable sink_bmp : bmp_ptr; 72 | variable sink_pix : bmp_pix; 73 | variable is_bmp_created : boolean := false; 74 | variable is_bmp_saved : boolean := false; 75 | begin 76 | 77 | -- Create bitmap on startup 78 | if is_bmp_created = false then 79 | sink_bmp := new bmp; 80 | is_bmp_created := true; 81 | end if; 82 | 83 | if rising_edge( clk_i ) then 84 | 85 | if active_vid_i = '1' then 86 | sink_pix.r := dat_i(23 downto 16); 87 | sink_pix.g := dat_i(15 downto 8); 88 | sink_pix.b := dat_i(7 downto 0); 89 | 90 | bmp_set_pix( sink_bmp, x, y, sink_pix ); 91 | 92 | x <= x + 1; 93 | is_active_line <= '1'; 94 | is_active_frame <= '1'; 95 | else 96 | if eol = '1' then 97 | x <= 0; 98 | if is_active_line = '1' then 99 | y <= y + 1; 100 | end if; 101 | is_active_line <= '0'; 102 | end if; 103 | 104 | if eof = '1' then 105 | y <= 0; 106 | if is_active_frame = '1' then 107 | bmp_save( sink_bmp, FILENAME ); 108 | end if; 109 | is_active_frame <= '0'; 110 | end if; 111 | end if; 112 | end if; 113 | end process; 114 | 115 | end Behavioral; 116 | -------------------------------------------------------------------------------- /sim/bmp_source_sink_TB.vhd: -------------------------------------------------------------------------------- 1 | library ieee; 2 | use ieee.std_logic_1164.all; 3 | use ieee.numeric_std.all; 4 | 5 | entity bmp_source_sink_TB is 6 | end entity; 7 | 8 | architecture behavioural of bmp_source_sink_TB is 9 | 10 | constant SOURCE_FILENAME : string := "source.bmp"; 11 | constant SINK_FILENAME : string := "sink.bmp"; 12 | 13 | signal clk : std_logic := '0'; 14 | signal rst : std_logic := '0'; 15 | signal val : std_logic := '0'; 16 | signal rdy : std_logic := '0'; 17 | signal dat : std_logic_vector(23 downto 0) := (others => '0'); 18 | signal eol : std_logic := '0'; 19 | signal eof : std_logic := '0'; 20 | 21 | begin 22 | 23 | clk <= not clk after 20 ns; 24 | 25 | bmp_source_1 : entity work.bmp_source 26 | generic map ( 27 | FILENAME => SOURCE_FILENAME, 28 | ITERATIONS => 1, 29 | BACKPRESSURE_EN => false 30 | ) 31 | port map ( 32 | clk_i => clk, 33 | rst_i => rst, 34 | 35 | val_o => val, 36 | dat_o => dat, 37 | rdy_i => rdy, 38 | eol_o => eol, 39 | eof_o => eof 40 | ); 41 | 42 | bmp_sink_1 : entity work.bmp_sink 43 | generic map ( 44 | FILENAME => SINK_FILENAME 45 | ) 46 | port map ( 47 | clk_i => clk, 48 | rst_i => rst, 49 | 50 | val_i => val, 51 | dat_i => dat, 52 | rdy_o => rdy, 53 | eol_i => eol, 54 | eof_i => eof, 55 | 56 | halt_i => '0' 57 | ); 58 | 59 | 60 | end architecture; 61 | -------------------------------------------------------------------------------- /sim/img/bars.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jherkenhoff/Bitmap-VHDL-Package/6d4cda9aea759e1586e7e7aae6708e54401508a7/sim/img/bars.bmp -------------------------------------------------------------------------------- /sim/img/lenna.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jherkenhoff/Bitmap-VHDL-Package/6d4cda9aea759e1586e7e7aae6708e54401508a7/sim/img/lenna.bmp --------------------------------------------------------------------------------