Line 127... |
Line 127... |
use unisim.vcomponents.all;
|
use unisim.vcomponents.all;
|
|
|
entity system09 is
|
entity system09 is
|
port(
|
port(
|
CLKA : in Std_Logic; -- 100MHz Clock input
|
CLKA : in Std_Logic; -- 100MHz Clock input
|
--RESET_N : in Std_logic; -- Master Reset input (active low)
|
RESET : in Std_logic; -- Master Reset input (active high) -- red "RESET" PB
|
--NMI_N : in Std_logic; -- Non Maskable Interrupt input (active low)
|
NMI : in Std_logic; -- Non Maskable Interrupt input (active high) -- Center PB
|
|
|
-- RS232 Port
|
-- RS232 Port - via Pmod RS232
|
RS232_RTS : out std_logic;
|
RS232_CTS : in Std_Logic;
|
RS232_CTS : in std_logic;
|
RS232_RTS : out Std_Logic;
|
RS232_RXD : in Std_Logic;
|
RS232_RXD : in Std_Logic;
|
RS232_TXD : out Std_Logic;
|
RS232_TXD : out Std_Logic;
|
|
|
-- slide switches
|
-- slide switches
|
sw : in std_logic_vector(7 downto 0);
|
sw : in std_logic_vector(2 downto 0);
|
-- push buttons (Right=SS, Center=NMI, Left=RESET)
|
|
btn : in std_logic_vector(4 downto 0);
|
|
-- Status 7 segment LED
|
-- Status 7 segment LED
|
S : out std_logic_vector(7 downto 0)
|
S : out std_logic_vector(7 downto 0)
|
|
|
|
|
-- CPU Debug Interface signals
|
-- CPU Debug Interface signals
|
-- cpu_reset_o : out Std_Logic;
|
-- cpu_reset_o : out Std_Logic;
|
-- cpu_clk_o : out Std_Logic;
|
-- cpu_clk_o : out Std_Logic;
|
-- cpu_rw_o : out std_logic;
|
-- cpu_rw_o : out std_logic;
|
-- cpu_vma_o : out std_logic;
|
-- cpu_vma_o : out std_logic;
|
Line 171... |
Line 168... |
-----------------------------------------------------------------------------
|
-----------------------------------------------------------------------------
|
-- constants
|
-- constants
|
-----------------------------------------------------------------------------
|
-----------------------------------------------------------------------------
|
constant CLOCK_MODE : natural := 0; -- 0 means normal, 1 means single-step
|
constant CLOCK_MODE : natural := 0; -- 0 means normal, 1 means single-step
|
|
|
constant MEM_CLK_FREQ : natural := 100_000; -- operating frequency of Memory in KHz
|
constant SYS_CLK_FREQ : natural := 100_000_000; -- FPGA System Clock (in Hz)
|
constant SYS_CLK_DIV : real := 2.0; -- divisor for FREQ (can only be 1.0, 1.5, 2.0, 2.5, 3.0, 4.0, 5.0, 8.0 or 16.0)
|
|
|
|
constant SYS_CLK_FREQ : natural := ((MEM_CLK_FREQ*2)/integer(SYS_CLK_DIV*2.0))*1000; -- FPGA System Clock (in Hz)
|
|
constant CPU_CLK_FREQ : natural := 25_000_000; -- CPU Clock (Hz)
|
constant CPU_CLK_FREQ : natural := 25_000_000; -- CPU Clock (Hz)
|
constant CPU_CLK_DIV : natural := (SYS_CLK_FREQ/CPU_CLK_FREQ);
|
constant CPU_CLK_DIV : natural := (SYS_CLK_FREQ/CPU_CLK_FREQ);
|
constant BAUD_RATE : integer := 57600; -- Baud Rate
|
constant BAUD_RATE : integer := 57600; -- Baud Rate
|
constant ACIA_CLK_FREQ : integer := BAUD_RATE * 16;
|
constant ACIA_CLK_FREQ : integer := BAUD_RATE * 16;
|
|
|
constant TRESET : natural := 300; -- min initialization interval (us)
|
|
constant RST_CYCLES : natural := 1+(TRESET*(MEM_CLK_FREQ/1_000)); -- SDRAM power-on initialization interval
|
|
|
|
-----------------------------------------------------------------------------
|
-----------------------------------------------------------------------------
|
-- Signals
|
-- Signals
|
-----------------------------------------------------------------------------
|
-----------------------------------------------------------------------------
|
signal pbtn : std_logic_vector(4 downto 0);
|
|
signal NMI_N : std_logic;
|
|
signal RESET_N : std_logic;
|
|
signal SINGLE_STEP : std_logic;
|
|
|
|
-- BOOT ROM
|
-- BOOT ROM
|
signal rom_cs : Std_logic;
|
signal rom_cs : Std_logic;
|
signal rom_data_out : Std_Logic_Vector(7 downto 0);
|
signal rom_data_out : Std_Logic_Vector(7 downto 0);
|
|
|
Line 204... |
Line 191... |
-- ACIA/UART Interface signals
|
-- ACIA/UART Interface signals
|
signal acia_data_out : Std_Logic_Vector(7 downto 0);
|
signal acia_data_out : Std_Logic_Vector(7 downto 0);
|
signal acia_cs : Std_Logic;
|
signal acia_cs : Std_Logic;
|
signal acia_irq : Std_Logic;
|
signal acia_irq : Std_Logic;
|
signal acia_clk : Std_Logic;
|
signal acia_clk : Std_Logic;
|
signal rxd : Std_Logic;
|
signal RXD : Std_Logic;
|
signal txd : Std_Logic;
|
signal TXD : Std_Logic;
|
signal DCD_n : Std_Logic;
|
signal DCD_n : Std_Logic;
|
signal RTS_n : Std_Logic;
|
signal RTS_n : Std_Logic;
|
signal CTS_n : Std_Logic;
|
signal CTS_n : Std_Logic;
|
|
|
-- RAM
|
-- RAM
|
Line 252... |
Line 239... |
|
|
signal CountL : std_logic_vector(23 downto 0);
|
signal CountL : std_logic_vector(23 downto 0);
|
signal clk_count : natural range 0 to CPU_CLK_DIV;
|
signal clk_count : natural range 0 to CPU_CLK_DIV;
|
signal Clk25 : std_logic;
|
signal Clk25 : std_logic;
|
|
|
|
|
component btn_debounce
|
|
Port ( BTN_I : in STD_LOGIC_VECTOR (4 downto 0);
|
|
CLK : in STD_LOGIC;
|
|
BTN_O : out STD_LOGIC_VECTOR (4 downto 0));
|
|
end component;
|
|
|
|
|
|
-----------------------------------------------------------------
|
-----------------------------------------------------------------
|
--
|
--
|
-- CPU09 CPU core
|
-- CPU09 CPU core
|
--
|
--
|
-----------------------------------------------------------------
|
-----------------------------------------------------------------
|
Line 475... |
Line 454... |
end component;
|
end component;
|
|
|
begin
|
begin
|
|
|
--
|
--
|
-- pushbutton debounce
|
|
--
|
|
my_singlestep: btn_debounce
|
|
port map ( BTN_I => btn, CLK => CLKA, BTN_O => pbtn);
|
|
|
|
RESET_N <= pbtn(3); -- Right PB
|
|
NMI_N <= pbtn(4); -- Center PB
|
|
SINGLE_STEP <= pbtn(1); -- Left PB
|
|
|
|
--
|
|
-- Generate CPU & Pixel Clock from Memory Clock
|
-- Generate CPU & Pixel Clock from Memory Clock
|
--
|
--
|
NORMAL: if CLOCK_MODE = 0 generate
|
|
my_prescaler : process( clk_i, clk_count )
|
my_prescaler : process( clk_i, clk_count )
|
begin
|
begin
|
if rising_edge( clk_i ) then
|
if rising_edge( clk_i ) then
|
if clk_count = 0 then
|
if clk_count = 0 then
|
clk_count <= CPU_CLK_DIV-1;
|
clk_count <= CPU_CLK_DIV-1;
|
Line 503... |
Line 472... |
elsif clk_count = (CPU_CLK_DIV/2) then
|
elsif clk_count = (CPU_CLK_DIV/2) then
|
clk25 <= '1';
|
clk25 <= '1';
|
end if;
|
end if;
|
end if;
|
end if;
|
end process;
|
end process;
|
end generate;
|
|
SS: if CLOCK_MODE = 1 generate
|
|
clk25 <= SINGLE_STEP;
|
|
end generate;
|
|
|
|
--
|
--
|
-- Reset button and reset timer
|
-- Reset button and reset timer
|
--
|
--
|
my_switch_assignments : process( rst_i, RESET_N)
|
my_switch_assignments : process( rst_i, RESET)
|
begin
|
begin
|
rst_i <= RESET_N;
|
rst_i <= RESET;
|
cpu_reset <= rst_i;
|
cpu_reset <= rst_i;
|
end process;
|
end process;
|
|
|
clk_i <= CLKA;
|
clk_i <= CLKA;
|
|
|
Line 595... |
Line 560... |
data_in => cpu_data_out,
|
data_in => cpu_data_out,
|
data_out => acia_data_out,
|
data_out => acia_data_out,
|
irq => acia_irq,
|
irq => acia_irq,
|
RxC => acia_clk,
|
RxC => acia_clk,
|
TxC => acia_clk,
|
TxC => acia_clk,
|
RxD => RS232_RXD,
|
RxD => RXD,
|
TxD => RS232_TXD,
|
TxD => TXD,
|
DCD_n => dcd_n,
|
DCD_n => DCD_n,
|
CTS_n => RS232_CTS,
|
CTS_n => CTS_n,
|
RTS_n => RS232_RTS
|
RTS_n => RTS_n
|
);
|
);
|
dcd_n <= '0';
|
|
|
--
|
|
-- RS232 signals:
|
|
--
|
|
my_acia_assignments : process( RS232_RXD, RS232_CTS, TXD, RTS_n )
|
|
begin
|
|
RXD <= RS232_RXD;
|
|
CTS_n <= RS232_CTS;
|
|
DCD_n <= '0';
|
|
RS232_TXD <= TXD;
|
|
RS232_RTS <= RTS_n;
|
|
end process;
|
|
|
my_ACIA_Clock : ACIA_Clock
|
my_ACIA_Clock : ACIA_Clock
|
generic map(
|
generic map(
|
SYS_CLK_FREQ => SYS_CLK_FREQ,
|
SYS_CLK_FREQ => SYS_CLK_FREQ,
|
ACIA_CLK_FREQ => ACIA_CLK_FREQ
|
ACIA_CLK_FREQ => ACIA_CLK_FREQ
|
)
|
)
|
port map(
|
port map(
|
clk => Clk_i,
|
clk => clk_i,
|
acia_clk => acia_clk
|
acia_clk => acia_clk
|
);
|
);
|
|
|
----------------------------------------
|
----------------------------------------
|
--
|
--
|
Line 691... |
Line 667... |
acia_cs <= '0';
|
acia_cs <= '0';
|
timer_cs <= '0';
|
timer_cs <= '0';
|
trap_cs <= '0';
|
trap_cs <= '0';
|
ram1_cs <= '0';
|
ram1_cs <= '0';
|
ram2_cs <= '0';
|
ram2_cs <= '0';
|
|
ram3_cs <= '0';
|
|
|
if cpu_addr( 15 downto 8 ) = "11111111" then -- $FFxx
|
if cpu_addr( 15 downto 8 ) = "11111111" then -- $FFxx
|
cpu_data_in <= rom_data_out;
|
cpu_data_in <= rom_data_out;
|
dat_cs <= cpu_vma; -- write DAT
|
dat_cs <= cpu_vma; -- write DAT
|
rom_cs <= cpu_vma; -- read ROM
|
rom_cs <= cpu_vma; -- read ROM
|
Line 769... |
Line 746... |
when others =>
|
when others =>
|
null;
|
null;
|
end case;
|
end case;
|
|
|
--
|
--
|
-- Flex RAM $0C000 - $0DFFF
|
-- Block RAM (32k) $00000 - $07FFF
|
--
|
|
elsif dat_addr(7 downto 1) = "0000110" then -- $0C000 - $0DFFF
|
|
cpu_data_in <= flex_data_out;
|
|
flex_cs <= cpu_vma;
|
|
|
|
--
|
|
-- 32k RAM $00000 - $07FFF
|
|
--
|
--
|
elsif dat_addr(7 downto 1) = "0000000" then -- $00000 - $07FFF
|
elsif dat_addr(7 downto 3) = "00000" then -- $00000 - $07FFF
|
cpu_data_in <= ram1_data_out;
|
cpu_data_in <= ram1_data_out;
|
ram1_cs <= cpu_vma;
|
ram1_cs <= cpu_vma;
|
|
|
--
|
--
|
-- 16k RAM $08000 - $0BFFF
|
-- Block RAM (16k) $08000 - $0BFFF
|
--
|
--
|
elsif dat_addr(7 downto 1) = "0000100" then -- $08000 - $0BFFF
|
elsif dat_addr(7 downto 2) = "000010" then -- $08000 - $0BFFF
|
cpu_data_in <= ram2_data_out;
|
cpu_data_in <= ram2_data_out;
|
ram2_cs <= cpu_vma;
|
ram2_cs <= cpu_vma;
|
|
|
--
|
--
|
|
-- Flex RAM (8k) $0C000 - $0DFFF
|
|
--
|
|
elsif dat_addr(7 downto 1) = "0000110" then -- $0C000 - $0DFFF
|
|
cpu_data_in <= flex_data_out;
|
|
flex_cs <= cpu_vma;
|
|
|
|
--
|
-- Everything else is RAM
|
-- Everything else is RAM
|
--
|
--
|
else
|
else
|
cpu_data_in <= (others => '0');
|
cpu_data_in <= (others => '0');
|
ram3_cs <= cpu_vma;
|
ram3_cs <= cpu_vma;
|
Line 802... |
Line 779... |
end process;
|
end process;
|
|
|
--
|
--
|
-- Interrupts and other bus control signals
|
-- Interrupts and other bus control signals
|
--
|
--
|
interrupts : process( NMI_N,
|
interrupts : process( NMI,
|
acia_irq,
|
acia_irq,
|
trap_irq,
|
trap_irq,
|
timer_irq
|
timer_irq
|
)
|
)
|
begin
|
begin
|
cpu_irq <= acia_irq;
|
cpu_irq <= acia_irq;
|
cpu_nmi <= trap_irq or not( NMI_N );
|
cpu_nmi <= trap_irq or NMI;
|
cpu_firq <= timer_irq;
|
cpu_firq <= timer_irq;
|
cpu_halt <= '0';
|
cpu_halt <= '0';
|
cpu_hold <= '0'; -- pb_hold or ram_hold;
|
cpu_hold <= '0'; -- pb_hold or ram_hold;
|
end process;
|
end process;
|
|
|
Line 825... |
Line 802... |
if rst_i = '1' then
|
if rst_i = '1' then
|
CountL <= "000000000000000000000000";
|
CountL <= "000000000000000000000000";
|
elsif rising_edge(clk_i) then
|
elsif rising_edge(clk_i) then
|
CountL <= CountL + 1;
|
CountL <= CountL + 1;
|
end if;
|
end if;
|
--S(7 downto 0) <= CountL(23 downto 16);
|
|
end process;
|
end process;
|
|
|
|
status_leds : process( rst_i, cpu_reset, cpu_addr, NMI, cpu_data_in, cpu_rw, CountL, sw)
|
|
|
|
|
status_leds : process( rst_i, cpu_reset,cpu_addr, cpu_rw, sw)
|
|
begin
|
begin
|
S(7) <= '0';
|
S(7) <= '0';
|
S(6) <= cpu_rw;
|
S(6) <= CountL(23);
|
S(5) <= cpu_vma;
|
S(5) <= cpu_rw;
|
S(4) <= '0';
|
S(4) <= NMI;
|
case sw is
|
case sw is
|
when "00000000" =>
|
when "000" =>
|
S(3 downto 0) <= cpu_addr(3 downto 0);
|
S(3 downto 0) <= cpu_addr(3 downto 0);
|
when "00000001" =>
|
when "001" =>
|
S(3 downto 0) <= cpu_addr(7 downto 4);
|
S(3 downto 0) <= cpu_addr(7 downto 4);
|
when "00000010" =>
|
when "010" =>
|
S(3 downto 0) <= cpu_addr(11 downto 8);
|
S(3 downto 0) <= cpu_addr(11 downto 8);
|
when "00000011" =>
|
when "011" =>
|
S(3 downto 0) <= cpu_addr(15 downto 12);
|
S(3 downto 0) <= cpu_addr(15 downto 12);
|
when "00000100" =>
|
when "100" =>
|
S(3 downto 0) <= cpu_data_in(3 downto 0);
|
S(3 downto 0) <= cpu_data_in(3 downto 0);
|
when "00000101" =>
|
when "101" =>
|
S(3 downto 0) <= cpu_data_in(7 downto 4);
|
S(3 downto 0) <= cpu_data_in(7 downto 4);
|
when others => S(3 downto 0) <= (others => '0');
|
when others => S(3 downto 0) <= (others => '0');
|
end case;
|
end case;
|
end process;
|
end process;
|
|
|