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