-------------------------------------------------- -- Model : 8051 Behavioral Model, -- VHDL Entity mc8051.inter_ctrl.interface -- -- Author : Michael Mayer (mrmayer@computer.org), -- Dr. Hardy J. Pottinger, -- Department of Electrical Engineering -- University of Missouri - Rolla -- -- Created at : 10/24/98 13:45:19 -- LIBRARY ieee ; USE ieee.std_logic_1164.all; USE ieee.numeric_std.all; LIBRARY mc8051 ; USE mc8051.synth_pack.all; ENTITY inter_ctrl IS PORT( P0 : IN std_logic_vector( 7 DOWNTO 0 ) ; acknow : IN std_logic ; cycle_states : IN std_logic_vector( 3 DOWNTO 0 ) ; dptr : IN std_logic_vector( 15 DOWNTO 0 ) ; ea_n : IN std_logic ; int_clk : IN std_logic ; int_rst : IN std_logic ; ir : IN std_logic_vector( 7 DOWNTO 0 ) ; last_cycle : IN std_logic ; pdat_loc : IN std_logic_vector( 15 DOWNTO 0 ) ; rom_data : IN std_logic_vector( 7 DOWNTO 0 ) ; rs : IN std_logic_vector( 1 DOWNTO 0 ) ; addr_gb : OUT std_logic_vector( 7 DOWNTO 0 ) ; ale : OUT std_logic ; indirect_sel : OUT std_logic ; p0_addr : OUT std_logic_vector( 7 DOWNTO 0 ) ; p0_ctrl : OUT std_logic ; p2_addr : OUT std_logic_vector( 7 DOWNTO 0 ) ; p2_ctrl : OUT std_logic ; pdata : OUT std_logic_vector( 7 DOWNTO 0 ) ; psen_n : OUT std_logic ; rd_gb : OUT std_logic ; rd_n : OUT std_logic ; rd_n_ctrl : OUT std_logic ; rom_rd_n : OUT std_logic ; wr_gb : OUT std_logic ; wr_n : OUT std_logic ; wr_n_ctrl : OUT std_logic ; data_gb : INOUT std_logic_vector( 7 DOWNTO 0 ) ); -- Declarations END inter_ctrl ; -- -- VHDL Architecture mc8051.inter_ctrl.spec -- -- Created: -- by - mrmayer.UNKNOWN (eceultra18.ece.umr.edu) -- at - 22:34:31 08/26/98 -- -- Generated by Mentor Graphics' Renoir(TM) 3.0 (Build 110) -- -- Description -- inter_ctrl is responsible for the interface control -- of the 8051. This includes all timing for the folloing -- ports: -- ALE -- PSEN_N -- RD_N -- WR_N -- P0 (in addr / data mode) -- P2 (in addr mode) -- -- It is tied to input port EA_N. -- -- Additional I/O include: -- pdat_loc (IN) - location in program data -- dptr - location for MOVX DPTR -- addr_gb, data_gb, rd_gb, wr_gb, acknow ARCHITECTURE spec OF inter_ctrl IS -- a latched, X01 version of ea_n SIGNAL ea_n_int : std_logic; SIGNAL ale_int : std_logic; SIGNAL psen_n_int, rd_n_int, wr_n_int : std_logic; SIGNAL rom_rd_n_int : std_logic; SIGNAL ia_pmem, ea_pmem, rd_xmem, wr_xmem : std_logic; SIGNAL use_reg : std_logic; SIGNAL reg_value : std_logic_vector(7 DOWNTO 0); SIGNAL data_byte : std_logic_vector(7 DOWNTO 0); SIGNAL p0_alt, p2_alt : std_logic_vector(7 DOWNTO 0); BEGIN rd_n <= rd_n_int; wr_n <= wr_n_int; psen_n <= psen_n_int; ale <= ale_int; p0_addr <= p0_alt; p2_addr <= p2_alt; rom_rd_n <= rom_rd_n_int; pdata <= data_byte; ea_n_int <= to_X01(ea_n) WHEN rising_edge(int_clk) AND ( cycle_states = s1p1 OR cycle_states = s4p1 ) ELSE ea_n_int; rd_xmem <= '1' WHEN std_match(ir,"1110001-") OR std_match(ir,"11100000") ELSE '0'; wr_xmem <= '1' WHEN std_match(ir,"1111001-") OR std_match(ir,"11110000") ELSE '0'; use_reg <= '1' WHEN std_match(ir,"111-001-") ELSE '0'; -- the next signal will change only at s1p1 or s4p1 ia_pmem <= '1' WHEN ea_n_int = '1' AND unsigned(pdat_loc) < 16#1000# ELSE '0'; ea_pmem <= '1' WHEN (rd_xmem = '0' AND wr_xmem = '0') AND ia_pmem = '0' ELSE '0'; -- use the global bus to read the register r0 or r1 for an address, and -- to read / write the accumulator for a data value addr_gb <= "000" & rs & "00" & ir(0) WHEN (use_reg = '1' AND last_cycle = '0') AND (cycle_states = s3p1 OR cycle_states = s3p2) ELSE "11100000" WHEN ((wr_xmem = '1' AND last_cycle = '0') AND (cycle_states = s4p1 OR cycle_states = s4p2)) OR ((rd_xmem = '1' AND last_cycle = '1') AND (cycle_states = s4p1 OR cycle_states = s4p2)) ELSE (OTHERS => 'Z'); rd_gb <= '1' WHEN (wr_xmem = '1' AND last_cycle = '0') AND (cycle_states = s4p1 OR cycle_states = s4p2) ELSE 'Z'; wr_gb <= '1' WHEN (rd_xmem = '1' AND last_cycle = '1') AND (cycle_states = s4p1 OR cycle_states = s4p2) ELSE 'Z'; data_gb <= data_byte WHEN (rd_xmem = '1' AND last_cycle = '1') AND (cycle_states = s4p1 OR cycle_states = s4p2) ELSE (OTHERS => 'Z'); reg_value <= data_gb WHEN (wr_xmem = '1' AND last_cycle = '0') AND acknow = '1' ELSE reg_value; -- drive the internal versions of the handshaking signals ale_int <= '1' WHEN ((cycle_states = s2p1 OR cycle_states = s2p2) AND ea_pmem = '1') OR ((cycle_states = s5p1 OR cycle_states = s5p2) AND (ea_pmem = '1' OR rd_xmem = '1' OR wr_xmem = '1')) ELSE '0'; -- psen_n is set low when doing program fetches. This happens at s3p1 and s6p1 when -- there is no external read /write occurring. It also happens at s6p1 of the last cycle -- of an external read / write when the internal memory accessing is not being used. psen_n_int <= '0' WHEN ((cycle_states = s3p1 OR cycle_states = s3p2 OR cycle_states = s4p1) AND ea_pmem = '1') OR ((cycle_states = s6p1 OR cycle_states = s6p2 OR cycle_states = s1p1) AND (ea_pmem = '1' OR (last_cycle = '1' AND ia_pmem = '0'))) ELSE '1'; rom_rd_n_int <= '0' WHEN (falling_edge(int_clk) AND ia_pmem = '1') AND (cycle_states = s3p1 OR cycle_states = s6p1) ELSE '1' WHEN falling_edge(int_clk) AND (cycle_states = s1p2 OR cycle_states = s4p2) ELSE rom_rd_n_int; rd_n_int <= '0' WHEN (falling_edge(int_clk) AND rd_xmem = '1') AND (last_cycle = '1' AND cycle_states = s1p1) ELSE '1' WHEN (falling_edge(int_clk) AND cycle_states = s4p1) ELSE rd_n_int; wr_n_int <= '0' WHEN (falling_edge(int_clk) AND wr_xmem = '1') AND (last_cycle = '1' AND cycle_states = s1p1) ELSE '1' WHEN (falling_edge(int_clk) AND cycle_states = s4p1) ELSE wr_n_int; p2_alt <= (OTHERS => '0') WHEN int_rst = '1' ELSE dptr(15 DOWNTO 8) WHEN (falling_edge(int_clk) AND cycle_states = s5p1) AND ((rd_xmem = '1' OR wr_xmem = '1') AND use_reg = '0') ELSE pdat_loc(15 DOWNTO 8) WHEN (falling_edge(int_clk) AND ( (cycle_states = s2p1 AND ea_pmem = '1') OR (cycle_states = s5p1 AND ( ea_pmem = '1' OR (last_cycle = '1' AND ia_pmem = '0') )) )) ELSE p2_alt; -- take control of p2 whenever external access of pmem is enabled, or -- when we are in (cycle 1 s5p1) through (cycle 2 s4p2) of external data rd / wr p2_ctrl <= '1' WHEN ea_pmem = '1' OR ( ( (last_cycle = '0' AND std_match(cycle_states,"11--")) OR (last_cycle = '1' AND (NOT std_match(cycle_states,"11--"))) ) AND (wr_xmem = '1' OR rd_xmem = '1') ) ELSE '0'; p0_alt <= (OTHERS => '0') WHEN int_rst = '1' ELSE dptr(7 DOWNTO 0) WHEN (rising_edge(int_clk) AND cycle_states = s5p1) AND ((rd_xmem = '1' OR wr_xmem = '1') AND use_reg = '0') ELSE reg_value WHEN (rising_edge(int_clk) AND cycle_states = s5p1) AND ((rd_xmem = '1' OR wr_xmem = '1') AND use_reg = '1') ELSE pdat_loc(7 DOWNTO 0) WHEN (cycle_states = s2p1 AND ea_pmem = '1') OR (cycle_states = s5p1 AND ( ea_pmem = '1' OR (last_cycle = '1' AND ia_pmem = '0') )) ELSE p0_alt; -- everytime this is set high, it sets all bits in the P0 sfr p0_ctrl <= '1' WHEN ( ea_pmem = '1' AND ((cycle_states = s2p1 OR cycle_states = s2p2) OR (cycle_states = s5p1 OR cycle_states = s5p2)) ) OR ( rd_xmem = '1' AND last_cycle = '0' AND ( (cycle_states = s5p1 OR cycle_states = s5p2) OR cycle_states = s6p1 ) ) OR -- wr_xmem from states (cycle 1, s5p1) to (cycle 2, s4p2) ( wr_xmem = '1' AND ( (last_cycle = '0' AND std_match(cycle_states,"11--")) OR (last_cycle = '1' AND (cycle_states(3) = '1' XOR cycle_states(2) = '1') ) )) OR ( ia_pmem = '0' AND last_cycle = '1' AND (cycle_states = s5p1 OR cycle_states = s5p2)) ELSE '0'; data_byte <= to_x01(p0) WHEN rising_edge(int_clk) AND ( ((cycle_states = s1p1 OR cycle_states = s4p1) AND psen_n_int = '0') OR ((last_cycle = '1' AND cycle_states = s3p1) AND rd_n_int = '0') ) ELSE rom_data WHEN rising_edge(int_clk) AND ( (cycle_states = s1p1 OR cycle_states = s4p1) AND ia_pmem = '1' ) ELSE data_byte; END ARCHITECTURE spec;