-------------------------------------------------- -- Model : 8051 Behavioral Model, -- VHDL Entity mc8051.program_ctrl.interface -- -- Author : Michael Mayer (mrmayer@computer.org), -- Dr. Hardy J. Pottinger, -- Department of Electrical Engineering -- University of Missouri - Rolla -- -- Created at : 09/22/98 14:04:05 -- LIBRARY ieee ; USE ieee.std_logic_1164.all; USE ieee.numeric_std.all; LIBRARY mc8051 ; USE mc8051.synth_pack.all; ENTITY program_ctrl IS PORT( cmp_true : IN std_logic ; cycle_states : IN std_logic_vector( 3 DOWNTO 0 ) ; dptr : IN std_logic_vector( 15 DOWNTO 0 ) ; int_clk : IN std_logic ; int_rst : IN std_logic ; pdata : IN std_logic_vector( 7 DOWNTO 0 ) ; rd_pmem1 : IN std_logic ; rd_pmem2 : IN std_logic ; addr_gb : OUT std_logic_vector( 7 DOWNTO 0 ) ; dec_rd_sp : OUT std_logic ; inc_wr_sp : OUT std_logic ; indirect_sel : OUT std_logic ; ir : OUT std_logic_vector( 7 DOWNTO 0 ) ; last_cycle : OUT std_logic ; new_ir : OUT std_logic ; pdat_loc : OUT std_logic_vector( 15 DOWNTO 0 ) ; rd_gb : OUT std_logic ; wr_gb : OUT std_logic ; acknow : INOUT std_logic ; data_gb : INOUT std_logic_vector( 7 DOWNTO 0 ) ); -- Declarations END program_ctrl ; -- -- VHDL Architecture mc8051.program_ctrl.struct -- -- Created: -- by - mrmayer.UNKNOWN (eceultra3.ece.umr.edu) -- at - 14:04:08 09/22/98 -- -- Generated by Mentor Graphics' Renoir(TM) 3.4 (Build 18) -- LIBRARY ieee ; USE ieee.std_logic_1164.all; USE ieee.std_logic_arith.conv_std_logic_vector; USE ieee.numeric_std.all; USE ieee.std_logic_textio.all; USE std.textio.ALL; LIBRARY mc8051 ; USE mc8051.synth_pack.all; USE mc8051.pack8051.to_int; architecture tb of program_ctrl is TYPE memory_array IS ARRAY (natural RANGE 0 TO 1023) OF std_logic_vector(7 DOWNTO 0); begin p1: process (cycle_states) IS PROCEDURE load_hex (mem: INOUT memory_array ) IS FILE progfile : TEXT OPEN read_mode IS "program.hex"; VARIABLE L : LINE; VARIABLE ch : CHARACTER; VARIABLE rec_type : CHARACTER; VARIABLE sum : INTEGER; VARIABLE dig : INTEGER; VARIABLE data : INTEGER; VARIABLE numb_of_bytes : INTEGER; VARIABLE address : INTEGER; VARIABLE address_offset : INTEGER; VARIABLE end_of_data : BOOLEAN; VARIABLE checksum : INTEGER; VARIABLE line_num : INTEGER; BEGIN line_num := 0; address_offset := 0; end_of_data := FALSE; WHILE NOT (endfile(progfile) OR end_of_data) LOOP -- Reset the variables for the line sum := 0; address := 0; line_num := line_num + 1; readline(progfile, L); -- Read in the : character read(L, ch); IF ch /= ':' THEN NEXT; -- go to next loop END IF; -- Read in the number of bytes read(L, ch); -- msb dig := to_int(ch); sum := sum + dig; read(L, ch); -- lsb sum := sum + to_int(ch); numb_of_bytes := dig*16 + to_int(ch); -- Read in the address FOR k IN 3 DOWNTO 0 LOOP read(L, ch); dig := to_int(ch); sum := sum + dig; address := address + dig * 16**k; END LOOP; -- Read in the record type read(L,ch); sum := sum + to_int(ch); ASSERT ch = '0' REPORT "Illegal Record Type - Bad Program File" & " on line " & INTEGER'IMAGE(line_num); read(L,rec_type); sum := sum + to_int(rec_type); -- If it is a line of all zeros, then it is the end of data. IF (numb_of_bytes = 0) AND (address = 0)THEN end_of_data := TRUE; -- If it is normal data, then read in all of the bytes to program_mem ELSIF rec_type = '0' THEN -- It has normal data FOR byte_no IN 0 TO numb_of_bytes-1 LOOP read(L,ch); dig := to_int(ch); sum := sum + dig; read(L,ch); sum := sum + to_int(ch); data := dig*16 + to_int(ch); mem(address_offset*16 + address + byte_no) := conv_std_logic_vector(data,8); END LOOP; -- If it is an end of file record, then set end_of_data true ELSIF rec_type = '1' THEN -- it is an end of file record end_of_data := TRUE; ELSIF rec_type = '2' THEN address_offset := 0; FOR k IN 3 DOWNTO 0 LOOP read(L, ch); dig := to_int(ch); sum := sum + dig; address_offset := address_offset + dig*16**k; END LOOP; END IF; -- get the checksum read(L,ch); dig := to_int(ch); read(L,ch); checksum := dig * 16 + to_int(ch); --ASSERT (checksum + sum MOD 256) = 0; -- REPORT "Checksum Error"& " on line " & INTEGER'IMAGE(line_num); END LOOP; END PROCEDURE load_hex; VARIABLE mem: memory_array; VARIABLE address : natural; VARIABLE write_data: std_logic_vector(7 DOWNTO 0); VARIABLE initialized : BOOLEAN := FALSE; BEGIN IF NOT initialized THEN load_hex(mem); initialized := TRUE; END IF; new_ir <= '0'; IF cycle_states = s1p1 THEN ir <= mem(address); address := address + 1; IF rising_edge(int_clk) THEN new_ir <= '1'; END IF; END IF; END PROCESS p1; END ARCHITECTURE tb;