-- EPROM model with Intel HEX-file parser -- provided and (C) 1999 -- by Emil Blaschek -- LIBRARY ieee; USE ieee.std_logic_1164.ALL; USE ieee.std_logic_misc.ALL; USE ieee.std_logic_arith.ALL; USE ieee.std_logic_components.ALL; USE ieee.std_logic_textio.ALL; USE std.textio.ALL; LIBRARY SYNOPSYS; USE SYNOPSYS.ATTRIBUTES.ALL; entity eprom is PORT ( cs_n : in std_logic ; oe_n : in std_logic ; db : out std_logic_vector( 7 downto 0) ; adr : in std_logic_vector(15 downto 0) ); end eprom ; LIBRARY ieee; USE ieee.std_logic_1164.ALL; USE ieee.std_logic_misc.ALL; USE ieee.std_logic_arith.ALL; USE ieee.std_logic_components.ALL; USE ieee.std_logic_textio.ALL; USE std.textio.ALL; LIBRARY SYNOPSYS; USE SYNOPSYS.ATTRIBUTES.ALL; ARCHITECTURE behav_eprom OF eprom IS subtype t_65536 is integer range 0 to 65535 ; subtype t_256 is integer range 0 to 255 ; subtype t_50 is integer range 0 to 50 ; subtype t_16 is integer range 0 to 15 ; subtype t_8 is integer range 0 to 8 ; type t_rom is array ( 65535 downto 0 ) of t_256 ; type t_file_name is file of character; type t_text is array ( 0 to 50 ) of character; type t_indat is array ( 0 to 15 ) of natural; signal c_rom : t_rom ; signal n_addr : natural ; signal n_dat : natural ; signal do : std_logic_vector(7 downto 0) ; file hex_file : text is in "/home/kba/blaschek1/8051/berc.hex" ; BEGIN eprom_l: PROCESS variable in_char : character ; variable in_text : line ; variable in_str : t_text ; variable in_num, rd_num, max_num : t_50 ; variable n : t_50 ; variable crc,zw : t_256 ; variable v_fileend : boolean ; variable v_addr : t_65536 ; variable v_rom : t_rom ; variable v_lineend : boolean ; function exor_n (v_h,v_l:t_256) return t_256 is variable erg :t_256 := 0; variable i :t_8 := 0; variable v_a,v_b : t_256 ; variable a,b,c :boolean := false ; begin v_a := v_h ; v_b := v_l ; erg := 0 ; a := false ; b := false ; if v_a > 127 then v_a := v_a - 128 ; a := true ; end if ; if v_b > 127 then v_b := v_b - 128 ; b := true ; end if ; if ((a and not(b)) or (b and not(a))) then erg := erg + 128 ; end if ; a := false ; b := false ; if v_a > 63 then v_a := v_a - 64 ; a := true ; end if ; if v_b > 63 then v_b := v_b - 64 ; b := true ; end if ; if ((a and not(b)) or (b and not(a))) then erg := erg + 64 ; end if ; a := false ; b := false ; if v_a > 31 then v_a := v_a - 32 ; a := true ; end if ; if v_b > 31 then v_b := v_b - 32 ; b := true ; end if ; if ((a and not(b)) or (b and not(a))) then erg := erg + 32 ; end if ; a := false ; b := false ; if v_a > 15 then v_a := v_a - 16 ; a := true ; end if ; if v_b > 15 then v_b := v_b - 16 ; b := true ; end if ; if ((a and not(b)) or (b and not(a))) then erg := erg + 16 ; end if ; a := false ; b := false ; if v_a > 7 then v_a := v_a - 8 ; a := true ; end if ; if v_b > 7 then v_b := v_b - 8 ; b := true ; end if ; if ((a and not(b)) or (b and not(a))) then erg := erg + 8 ; end if ; a := false ; b := false ; if v_a > 3 then v_a := v_a - 4 ; a := true ; end if ; if v_b > 3 then v_b := v_b - 4 ; b := true ; end if ; if ((a and not(b)) or (b and not(a))) then erg := erg + 4 ; end if ; a := false ; b := false ; if v_a > 1 then v_a := v_a - 2 ; a := true ; end if ; if v_b > 1 then v_b := v_b - 2 ; b := true ; end if ; if ((a and not(b)) or (b and not(a))) then erg := erg + 2 ; end if ; a := false ; b := false ; if v_a > 0 then v_a := v_a - 1 ; a := true ; end if ; if v_b > 0 then v_b := v_b - 1 ; b := true ; end if ; if ((a and not(b)) or (b and not(a))) then erg := erg + 1 ; end if ; return erg ; end exor_n ; function hex_to_bin (hex_h,hex_l:character) return t_256 is variable erg:t_256 := 0; begin case hex_h is when '0' => erg := 0 ; when '1' => erg := 16 ; when '2' => erg := 32 ; when '3' => erg := 48 ; when '4' => erg := 64 ; when '5' => erg := 80 ; when '6' => erg := 96 ; when '7' => erg := 112 ; when '8' => erg := 128 ; when '9' => erg := 144 ; when 'A' => erg := 160 ; when 'B' => erg := 176 ; when 'C' => erg := 192 ; when 'D' => erg := 208 ; when 'E' => erg := 224 ; when 'F' => erg := 240 ; when others => end case ; case hex_l is when '0' => erg := erg + 0 ; when '1' => erg := erg + 1 ; when '2' => erg := erg + 2 ; when '3' => erg := erg + 3 ; when '4' => erg := erg + 4 ; when '5' => erg := erg + 5 ; when '6' => erg := erg + 6 ; when '7' => erg := erg + 7 ; when '8' => erg := erg + 8 ; when '9' => erg := erg + 9 ; when 'A' => erg := erg + 10 ; when 'B' => erg := erg + 11 ; when 'C' => erg := erg + 12 ; when 'D' => erg := erg + 13 ; when 'E' => erg := erg + 14 ; when 'F' => erg := erg + 15 ; when others => end case ; return erg ; end hex_to_bin ; begin c_rom <= (others => 255 ) ; v_fileend := false ; while (not ( ENDFILE(hex_file) or v_fileend )) loop -- while ((not ENDFILE(hex_file)) ) loop READLINE(hex_file,in_text) ; v_lineend := false ; max_num := 50 ; in_str := ( others => NUL ); while not ( v_lineend ) loop READ(in_text,in_char) ; case in_char is when ':' => in_num := 0 ; when '0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9' | 'A' | 'B' | 'C' | 'D' | 'E' | 'F' => in_str(in_num) := in_char ; in_num := in_num + 1 ; if in_num = 2 then max_num := ( hex_to_bin(in_str(0),in_str(1)))* 2 + 10 ; end if ; if in_num = max_num then v_lineend := true ; if in_str(7) = '1' then v_lineend := true ; -- ENDstring v_fileend := true ; -- ENDfile else --Data_string max_num := hex_to_bin(in_str(0),in_str(1)) ; n := 0 ; crc := 0 ; while ( n < ( max_num + 4 )) loop zw := hex_to_bin(in_str( n * 2 ),in_str( n * 2 + 1 ) ) ; crc := exor_n ( zw, crc ) ; n := n + 1 ; end loop ; --if crc = 00 then -- datastring OK -- write data n := 0 ; crc := 0 ; v_addr := hex_to_bin(in_str(2),in_str(3)) * 256 + -- HB hex_to_bin(in_str(4),in_str(5)) + n ; -- LB while ( n < max_num ) loop zw := hex_to_bin(in_str( n * 2 + 8 ), in_str( n * 2 + 9 ) ) ; v_rom(v_addr) := zw ; v_addr := v_addr + 1 ; n := n + 1 ; end loop ; --end if ; --Data_string end if ; v_lineend := true ; end if ; -------------------------------------------------------------------- when others => end case ; end loop ; end loop ; c_rom <= v_rom ; wait ; end process ; eprom_p: PROCESS ( adr) function to_nat (vec:std_logic_vector(15 downto 0)) return natural is variable erg:natural := 0; begin for k in 15 downto 0 loop erg := erg + erg ; if vec(k) = '1' then erg := erg + 1; end if ; end loop ; return erg ; end to_nat ; begin do <= conv_std_logic_vector(c_rom(to_nat(adr)),8); end process; db <= do when ( ( oe_n = '0' ) and ( cs_n = '0' )) else "ZZZZZZZZ"; END behav_eprom ;