------------------------------------------------------------------------------
-- Model        :   8051 Behavioral Model,
--                  Supporting Package of Procedures 
--
-- File         :   pack8051.vhd
--
-- Author       :   Michael Mayer,
--                  Department of Electrical Engineering
--                  University of Missouri - Rolla
--
-- Inspired By  :   Sundar Subbarayan
--                  UC Riverside CS 122a (lab 3)
--                  Professor: Dr.Frank Vahid
--                  17th January 1996
--
-- Date Started :   September 15, 1997
--
-- Limitations  :   
--
-- Revisions    :
--
-- REV    DATE     Description
-- -----  --------   _____________________________________
-- 2.0    11/04/97   Initial implementation of types for
--                   memory, functions or, and, xor, not
--                   and procedure load_program 
--
-- 2.1    11/12/97   Changed memory to lo and hi mem's
--
-- 2.2    11/13/97   Added type for states for machine cycles
--
--
------------------------------------------------------------------------------

LIBRARY ieee;
USE ieee.std_logic_1164.ALL;
USE ieee.std_logic_arith.ALL;
USE std.textio.ALL;

PACKAGE pack8051 IS
   SUBTYPE bvec       IS UNSIGNED(7 DOWNTO 0);
   SUBTYPE wvec       IS UNSIGNED(15 DOWNTO 0);
   SUBTYPE smallint   IS INTEGER RANGE 0 TO 255;

   TYPE program_mem_T IS ARRAY(0 TO 65535) OF bvec; 
   TYPE data_lomem_T  IS ARRAY(0 TO 127)   OF bvec;
   TYPE data_himem_T  IS ARRAY(128 TO 255) OF bvec;

   -- The following type is used to declare if direct or indirect memory
   -- access is being used and, hence, which segment of upper memory
   -- is to be used.
   TYPE    access_type IS (direct, indirect);

   -- The following type is used to break up the machine cycle
   -- into 6 states, with 2 pulses for each state
   TYPE machine_cycle_states IS (init, s1p1, s1p2, s2p1, s2p2, s3p1, s3p2,
         s4p1, s4p2, s5p1, s5p2, s6p1, s6p2);

   FUNCTION to_int(ch   : CHARACTER)  RETURN INTEGER;

   FUNCTION "or"(l,r : unsigned)  RETURN unsigned;
   FUNCTION "and"(l,r : unsigned) RETURN unsigned;
   FUNCTION "xor"(l,r : unsigned) RETURN unsigned;
   FUNCTION "not"(r : unsigned)   RETURN unsigned;

   FUNCTION conv_signed_to_int(arg : bvec) RETURN INTEGER; 
   FUNCTION to_high_imped(arg : bvec) RETURN bvec;

   FUNCTION inc(state : machine_cycle_states) 
       RETURN machine_cycle_states;

   PROCEDURE load_program(
       CONSTANT program_filename : IN string;
       VARIABLE pmem             : OUT program_mem_T  -- the program memory
   );
END pack8051;

PACKAGE BODY pack8051 IS

   ------------------------------------------------------------------------
   -- to_int
   --
   --	A function that converts a character to an integer (0-9,A-F) 
   ------------------------------------------------------------------------


    FUNCTION to_int(
         CONSTANT ch    : CHARACTER
    ) RETURN INTEGER IS
         VARIABLE result : INTEGER := 0;
    BEGIN
         CASE ch IS
             WHEN '0' => result := 16#0#;
             WHEN '1' => result := 16#1#;
             WHEN '2' => result := 16#2#;
             WHEN '3' => result := 16#3#;
             WHEN '4' => result := 16#4#;
             WHEN '5' => result := 16#5#;
             WHEN '6' => result := 16#6#;
             WHEN '7' => result := 16#7#;
             WHEN '8' => result := 16#8#;
             WHEN '9' => result := 16#9#;
             WHEN 'A' => result := 16#A#;
             WHEN 'B' => result := 16#B#;
             WHEN 'C' => result := 16#C#;
             WHEN 'D' => result := 16#D#;
             WHEN 'E' => result := 16#E#;
             WHEN 'F' => result := 16#F#;
             WHEN OTHERS => result := 16#0#;
         END CASE;
         RETURN result;
    END FUNCTION to_int;

   ------------------------------------------------------------------------
   FUNCTION "or"(l,r : unsigned) RETURN unsigned IS
   BEGIN
       RETURN unsigned(std_logic_vector(l) OR std_logic_vector(r));
   END FUNCTION "or";

   ------------------------------------------------------------------------
   FUNCTION "and"(l,r : unsigned) RETURN unsigned IS
   BEGIN
       RETURN unsigned(std_logic_vector(l) AND std_logic_vector(r));
   END FUNCTION "and";

   ------------------------------------------------------------------------
   FUNCTION "xor"(l,r : unsigned) RETURN unsigned IS
   BEGIN
       RETURN unsigned(std_logic_vector(l) XOR std_logic_vector(r));
   END FUNCTION "xor";


   ------------------------------------------------------------------------
   FUNCTION "not"(r : unsigned) RETURN unsigned IS
   BEGIN
       RETURN unsigned(NOT std_logic_vector(r));
   END FUNCTION "not";

   ------------------------------------------------------------------------
   FUNCTION conv_signed_to_int(arg : bvec) RETURN INTEGER IS
       VARIABLE result : INTEGER;
   BEGIN
       IF arg(7) = '1' THEN -- convert to positive 
           result := -1 * conv_integer(NOT(arg) + 1); 
       ELSE
           result := conv_integer(arg); 
       END IF;
       RETURN result;
   END FUNCTION conv_signed_to_int;

   ------------------------------------------------------------------------
   FUNCTION to_high_imped(arg : bvec) RETURN bvec IS 
       VARIABLE result : bvec; 
   BEGIN
       FOR k in arg'RANGE LOOP
           CASE arg(k) IS
               WHEN '0' => result(k) := 'L';
               WHEN '1' => result(k) := 'H';
               WHEN 'L' => result(k) := 'L';
               WHEN 'H' => result(k) := 'H';
               WHEN OTHERS => result(k) := 'Z';
           END CASE;
       END LOOP;
       RETURN(result);
   END FUNCTION to_high_imped;           

   ------------------------------------------------------------------------
   FUNCTION inc(state : machine_cycle_states) 
       RETURN machine_cycle_states IS
       VARIABLE result : machine_cycle_states;
   BEGIN
       CASE state IS 
           WHEN init => result := s1p1;
           WHEN s1p1 => result := s1p2;
           WHEN s1p2 => result := s2p1;
           WHEN s2p1 => result := s2p2;
           WHEN s2p2 => result := s3p1;
           WHEN s3p1 => result := s3p2;
           WHEN s3p2 => result := s4p1;
           WHEN s4p1 => result := s4p2;
           WHEN s4p2 => result := s5p1;
           WHEN s5p1 => result := s5p2;
           WHEN s5p2 => result := s6p1;
           WHEN s6p1 => result := s6p2;
           WHEN s6p2 => result := s1p1;
        END CASE;
        RETURN result;
    END FUNCTION inc;


    PROCEDURE load_program(
        CONSTANT program_filename : IN string;
        VARIABLE pmem             : OUT program_mem_T  -- the program memory
    ) IS
        FILE     progfile       : TEXT OPEN read_mode IS program_filename;
        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);
                     pmem(address_offset*16 + address + byte_no) := 
                        conv_unsigned(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_program;         


  
END pack8051;




<div align="center"><br /><script type="text/javascript"><!--
google_ad_client = "pub-7293844627074885";
//468x60, Created at 07. 11. 25
google_ad_slot = "8619794253";
google_ad_width = 468;
google_ad_height = 60;
//--></script>
<script type="text/javascript" src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
</script><br />&nbsp;</div>