Line 1... |
Line 1... |
-- $Id: cpu09.vhd,v 1.2 2008-03-14 15:52:46 dilbert57 Exp $
|
--===========================================================================--
|
--===========================================================================----
|
-- --
|
--
|
-- Synthesizable 6809 instruction compatible VHDL CPU core --
|
-- S Y N T H E Z I A B L E CPU09 - 6809 compatible CPU Core
|
-- --
|
--
|
--===========================================================================--
|
-- www.OpenCores.Org - September 2003
|
|
-- This core adheres to the GNU public license
|
|
--
|
--
|
-- File name : cpu09.vhd
|
-- File name : cpu09.vhd
|
--
|
--
|
-- Purpose : 6809 CPU core
|
-- Entity name : cpu09
|
--
|
--
|
-- Dependencies : ieee.Std_Logic_1164
|
-- Purpose : 6809 instruction compatible CPU core written in VHDL
|
-- ieee.std_logic_unsigned
|
-- Not cycle compatible with the original 6809 CPU
|
--
|
--
|
-- Uses : None
|
-- Dependencies : ieee.std_logic_1164
|
|
-- ieee.std_logic_unsigned
|
--
|
--
|
-- Author : John E. Kent
|
-- Author : John E. Kent
|
-- dilbert57@opencores.org
|
|
--
|
--
|
--===========================================================================----
|
-- Email : dilbert57@opencores.org
|
|
--
|
|
-- Web : http://opencores.org/project,system09
|
--
|
--
|
-- Revision History:
|
--
|
|
-- Copyright (C) 2003 - 2010 John Kent
|
|
--
|
|
-- This program is free software: you can redistribute it and/or modify
|
|
-- it under the terms of the GNU General Public License as published by
|
|
-- the Free Software Foundation, either version 3 of the License, or
|
|
-- (at your option) any later version.
|
|
--
|
|
-- This program is distributed in the hope that it will be useful,
|
|
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
-- GNU General Public License for more details.
|
|
--
|
|
-- You should have received a copy of the GNU General Public License
|
|
-- along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
--
|
|
--===========================================================================--
|
|
-- --
|
|
-- Revision History --
|
|
-- --
|
--===========================================================================--
|
--===========================================================================--
|
--
|
--
|
-- Version 0.1 - 26 June 2003 - John Kent
|
-- Version 0.1 - 26 June 2003 - John Kent
|
-- Added extra level in state stack
|
-- Added extra level in state stack
|
-- fixed some calls to the extended addressing state
|
-- fixed some calls to the extended addressing state
|
Line 169... |
Line 188... |
|
|
entity cpu09 is
|
entity cpu09 is
|
port (
|
port (
|
clk: in std_logic;
|
clk: in std_logic;
|
rst: in std_logic;
|
rst: in std_logic;
|
rw: out std_logic;
|
|
vma: out std_logic;
|
vma: out std_logic;
|
address: out std_logic_vector(15 downto 0);
|
addr : out std_logic_vector(15 downto 0);
|
data_in: in std_logic_vector(7 downto 0);
|
rw : out std_logic;
|
data_out: out std_logic_vector(7 downto 0);
|
data_out: out std_logic_vector(7 downto 0);
|
halt: in std_logic;
|
data_in : in std_logic_vector(7 downto 0);
|
hold: in std_logic;
|
|
irq: in std_logic;
|
irq: in std_logic;
|
firq: in std_logic;
|
firq: in std_logic;
|
nmi: in std_logic
|
nmi : in std_logic;
|
|
halt : in std_logic;
|
|
hold : in std_logic
|
);
|
);
|
end cpu09;
|
end cpu09;
|
|
|
architecture rtl of cpu09 is
|
architecture rtl of cpu09 is
|
|
|
Line 911... |
Line 930... |
-- Detect Edge of NMI interrupt
|
-- Detect Edge of NMI interrupt
|
--
|
--
|
------------------------------------
|
------------------------------------
|
|
|
--nmi_handler : process( clk, rst, nmi, nmi_ack, nmi_req, nmi_enable )
|
--nmi_handler : process( clk, rst, nmi, nmi_ack, nmi_req, nmi_enable )
|
nmi_handler : process( clk )
|
nmi_handler : process( rst, clk )
|
begin
|
begin
|
if clk'event and clk='0' then
|
|
if rst='1' then
|
if rst='1' then
|
nmi_req <= '0';
|
nmi_req <= '0';
|
else
|
elsif clk'event and clk='0' then
|
if (nmi='1') and (nmi_ack='0') and (nmi_enable='1') then
|
if (nmi='1') and (nmi_ack='0') and (nmi_enable='1') then
|
nmi_req <= '1';
|
nmi_req <= '1';
|
else
|
else
|
if (nmi='0') and (nmi_ack='1') then
|
if (nmi='0') and (nmi_ack='1') then
|
nmi_req <= '0';
|
nmi_req <= '0';
|
else
|
|
nmi_req <= nmi_req;
|
|
end if;
|
|
end if;
|
end if;
|
end if;
|
end if;
|
end if;
|
end if;
|
end process;
|
end process;
|
|
|
Line 941... |
Line 956... |
|
|
addr_mux: process( addr_ctrl, pc, ea, up, sp, iv )
|
addr_mux: process( addr_ctrl, pc, ea, up, sp, iv )
|
begin
|
begin
|
case addr_ctrl is
|
case addr_ctrl is
|
when idle_ad =>
|
when idle_ad =>
|
address <= "1111111111111111";
|
|
vma <= '0';
|
vma <= '0';
|
|
addr <= "1111111111111111";
|
rw <= '1';
|
rw <= '1';
|
when fetch_ad =>
|
when fetch_ad =>
|
address <= pc;
|
|
vma <= '1';
|
vma <= '1';
|
|
addr <= pc;
|
rw <= '1';
|
rw <= '1';
|
when read_ad =>
|
when read_ad =>
|
address <= ea;
|
|
vma <= '1';
|
vma <= '1';
|
|
addr <= ea;
|
rw <= '1';
|
rw <= '1';
|
when write_ad =>
|
when write_ad =>
|
address <= ea;
|
|
vma <= '1';
|
vma <= '1';
|
|
addr <= ea;
|
rw <= '0';
|
rw <= '0';
|
when pushs_ad =>
|
when pushs_ad =>
|
address <= sp;
|
|
vma <= '1';
|
vma <= '1';
|
|
addr <= sp;
|
rw <= '0';
|
rw <= '0';
|
when pulls_ad =>
|
when pulls_ad =>
|
address <= sp;
|
|
vma <= '1';
|
vma <= '1';
|
|
addr <= sp;
|
rw <= '1';
|
rw <= '1';
|
when pushu_ad =>
|
when pushu_ad =>
|
address <= up;
|
|
vma <= '1';
|
vma <= '1';
|
|
addr <= up;
|
rw <= '0';
|
rw <= '0';
|
when pullu_ad =>
|
when pullu_ad =>
|
address <= up;
|
|
vma <= '1';
|
vma <= '1';
|
|
addr <= up;
|
rw <= '1';
|
rw <= '1';
|
when int_hi_ad =>
|
when int_hi_ad =>
|
address <= "111111111111" & iv & "0";
|
|
vma <= '1';
|
vma <= '1';
|
|
addr <= "111111111111" & iv & "0";
|
rw <= '1';
|
rw <= '1';
|
when int_lo_ad =>
|
when int_lo_ad =>
|
address <= "111111111111" & iv & "1";
|
|
vma <= '1';
|
vma <= '1';
|
|
addr <= "111111111111" & iv & "1";
|
rw <= '1';
|
rw <= '1';
|
when others =>
|
when others =>
|
address <= "1111111111111111";
|
|
vma <= '0';
|
vma <= '0';
|
|
addr <= "1111111111111111";
|
rw <= '1';
|
rw <= '1';
|
end case;
|
end case;
|
end process;
|
end process;
|
|
|
--------------------------------
|
--------------------------------
|
Line 4189... |
Line 4204... |
when pshs_state =>
|
when pshs_state =>
|
-- decrement sp if any registers to be pushed
|
-- decrement sp if any registers to be pushed
|
left_ctrl <= sp_left;
|
left_ctrl <= sp_left;
|
right_ctrl <= one_right;
|
right_ctrl <= one_right;
|
alu_ctrl <= alu_sub16;
|
alu_ctrl <= alu_sub16;
|
|
-- idle address
|
|
addr_ctrl <= idle_ad;
|
|
dout_ctrl <= cc_dout;
|
if ea(7 downto 0) = "00000000" then
|
if ea(7 downto 0) = "00000000" then
|
sp_ctrl <= latch_sp;
|
sp_ctrl <= latch_sp;
|
else
|
else
|
sp_ctrl <= load_sp;
|
sp_ctrl <= load_sp;
|
end if;
|
end if;
|