--------------------------------------------------
-- Model        :   8051 Behavioral Model,
--                  VHDL Entity mc8051.sp.interface
--
-- Author       :   Michael Mayer (mrmayer@computer.org),
--                  Dr. Hardy J. Pottinger,
--                  Department of Electrical Engineering
--                  University of Missouri - Rolla
--
-- Created at   :   09/22/98 19:32:41
--
LIBRARY ieee ;
USE ieee.std_logic_1164.all;
USE ieee.numeric_std.all;
LIBRARY mc8051 ;
USE mc8051.synth_pack.all;

ENTITY sp IS
   PORT( 
      dec_rd_sp : IN     std_logic ;
      inc_wr_sp : IN     std_logic ;
      int_clk : IN     std_logic ;
      int_rst : IN     std_logic ;
      acknow : INOUT  std_logic ;
      addr_gb : INOUT  std_logic_vector( 7 DOWNTO 0 )  ;
      data_gb : INOUT  std_logic_vector( 7 DOWNTO 0 )  ;
      indirect_sel : INOUT  std_logic ;
      rd_gb : INOUT  std_logic ;
      wr_gb : INOUT  std_logic
   );

-- Declarations

END sp ;
--
-- VHDL Architecture mc8051.sp.spec
--
-- Created:
--          by - mrmayer.UNKNOWN (eceultra20.ece.umr.edu)
--          at - 17:04:43 09/19/98
--
-- Generated by Mentor Graphics' Renoir(TM) 3.4 (Build 18)
--
architecture spec of sp is
   SIGNAL  sp_reg  : std_logic_vector(7 DOWNTO 0) := "00000111";
   SIGNAL  sp_sel  : std_logic;
   SIGNAL  sp_reg_new : unsigned(7 DOWNTO 0); 
   SIGNAL  add_amount : unsigned(7 DOWNTO 0);
   SIGNAL  mini_state : std_logic_vector(2 DOWNTO 0);
begin
   -- the sp is selected by addr 81
   sp_sel <= '1' WHEN (addr_gb = "10000001") AND (indirect_sel = '0') ELSE
             '0';
   -- the sp is reset to 07h during reset
   -- set to the data_gb during a wr_gb,
   -- and incremented or decremented as necessary 
   
   add_amount <= "11111111" WHEN dec_rd_sp = '1' ELSE
                 "00000001";
   sp_reg_new <= unsigned(sp_reg) + add_amount;

   p1 : PROCESS (int_rst, int_clk) IS
   BEGIN
       IF int_rst = '1' THEN
           mini_state <= "000";
           sp_reg <= "00000111";
       ELSIF (wr_gb = '1' AND sp_sel = '1') THEN
           sp_reg <= data_gb;
       ELSIF rising_edge(inc_wr_sp) THEN 
           mini_state <= "100";
       ELSIF rising_edge(dec_rd_sp) THEN
           mini_state <= "001";    
       END IF;

       CASE mini_state IS
          WHEN "001" =>  -- perform read
              addr_gb <= sp_reg;
              indirect_sel <= '1';
              rd_gb   <= '1';
              IF acknow = '1' THEN
                  mini_state <= "011";
              END IF;
          WHEN "011" =>  -- decrement sp
              sp_reg <= std_logic_vector(sp_reg_new);
              mini_state <= "000";
          WHEN "100" =>  -- increment sp 
              sp_reg <= std_logic_vector(sp_reg_new);
              mini_state <= "101";
          WHEN "101" =>  -- perform write 
              addr_gb <= sp_reg;
              indirect_sel <= '1';
              wr_gb <= '1';
              IF acknow = '1' THEN
                  mini_state <= "000";
              END IF;

          WHEN OTHERS =>  -- do nothing
              addr_gb <= (OTHERS => 'Z');
              indirect_sel <= 'Z';
              rd_gb <= 'Z';
              wr_gb <= 'Z';
          END CASE;
    END PROCESS p1;

    -- The data_gb is driven with the acc during a read from acc,
    -- or else left in high impedance.
    data_gb <= sp_reg    WHEN rd_gb = '1' AND sp_sel = '1' ELSE
               "ZZZZZZZZ";
 
    -- The acknowledge is pulled high when the global bus and acc
    -- reg become equal (considered stable) and the acc is selected.
    acknow <= '1' WHEN data_gb = sp_reg AND sp_sel = '1' ELSE
              'Z';
 


end spec;

<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>