URL
https://opencores.org/ocsvn/System09/System09/trunk
Subversion Repositories System09
[/] [System09/] [trunk/] [rtl/] [System09_Digilent_ZyboZ20/] [system09.vhd] - Rev 192
Go to most recent revision | Compare with Previous | Blame | View Log
--===========================================================================---- -- -- S Y N T H E Z I A B L E System09 - SOC. -- -- www.OpenCores.Org - February 2007 -- This core adheres to the GNU public license -- -- File name : system09.vhd -- -- Purpose : Top level file for 6809 compatible system on a chip -- Designed with Digilent Zybo Z20. -- ========================================================================== -- Setup/Buttons -- RS232 - connect a RS-232 Pmod to JE (upper row) -- Configure terminal for 57600 baud 8-N-1, hardware handshake -- -- Slide Switches - selects the nibble to display on the 4 LEDs -- 0000 - CPU Address 3 to 0 -- 0001 - CPU Address 7 to 4 -- 0010 - CPU Address 11 to 8 -- 0011 - CPU Address 15 to 12 -- 0100 - CPU Data 3 to 0 -- 0101 - CPU Data 7 to 4 -- -- Push buttons -- BTN3 BTN2 BTN1 BTN0 -- (unused) Single NMI RESET -- Step -- -- Single-Step functionality is controlled by the CLOCK_MODE constant below -- -- Memory Map : -- -- $0000 - User program RAM (32K Bytes) -- $8000 - User program RAM (16K Bytes) -- $C000 - Flex Operating System memory (8K Bytes) -- $E000 - ACIA (SWTPc) -- $E050 - Timer -- $E060 - Bus trap -- $F000 - Sys09Bug monitor Program (4K Bytes) -- ========================================================================== -- -- Dependencies : ieee.Std_Logic_1164 -- ieee.std_logic_unsigned -- ieee.std_logic_arith -- ieee.numeric_std -- unisim.vcomponents -- -- Uses : mon_rom (sys09swt.vhd) SWTPc S-Bug 1.7 Monitor ROM -- cpu09 (cpu09.vhd) CPU core -- ACIA_6850 (acia6850.vhd) ACIA / UART -- ACIA_Clock (ACIA_Clock.vhd) ACIA clock. -- timer (timer.vhd) Interrupt timer -- trap (trap.vhd) Bus condition trap logic -- flex_ram (flex9ram.vhd) Flex operating system -- ram_16K (ram16k_b16.vhd) 32 KBytes of Block RAM -- ram_32K (ram32k_b16.vhd) 32 KBytes of Block RAM -- --===========================================================================---- -- -- Revision History: --===========================================================================-- -- Version 0.1 - Jan 20, 2021 -- Copied from the System09_Xess-XSA3S1000 vhdl --===========================================================================-- library ieee; use ieee.std_logic_1164.all; use IEEE.STD_LOGIC_ARITH.ALL; use IEEE.STD_LOGIC_UNSIGNED.ALL; use ieee.numeric_std.all; library work; use work.common.all; library unisim; use unisim.vcomponents.all; entity system09 is port( CLKA : in Std_Logic; -- 125 MHz Clock input -- RS232 Port RS232_RTS : out std_logic; RS232_CTS : in std_logic; RS232_RXD : in Std_Logic; RS232_TXD : out Std_Logic; -- slide switches sw : in std_logic_vector(3 downto 0); -- push buttons [Unused, Single-Step, NMI, RESET] btn : in std_logic_vector(3 downto 0); -- Status 4 LEDs led : out std_logic_vector(3 downto 0) ); end system09; ------------------------------------------------------------------------------- -- Architecture for System09 ------------------------------------------------------------------------------- architecture rtl of system09 is ----------------------------------------------------------------------------- -- constants ----------------------------------------------------------------------------- constant CLOCK_MODE : natural := 0; -- 0 means normal, 1 means single-step constant SYS_CLK_FREQ : natural := 125_000_000; -- FPGA System Clock (in Hz) constant CPU_CLK_FREQ : natural := 25_000_000; -- CPU Clock (Hz) constant CPU_CLK_DIV : natural := (SYS_CLK_FREQ/CPU_CLK_FREQ); constant BAUD_RATE : integer := 57600; -- Baud Rate constant ACIA_CLK_FREQ : integer := BAUD_RATE * 16; ----------------------------------------------------------------------------- -- Signals ----------------------------------------------------------------------------- signal pbtn : std_logic_vector(3 downto 0); signal NMI_N : std_logic; signal RESET_N : std_logic; signal SINGLE_STEP : std_logic; -- BOOT ROM signal rom_cs : Std_logic; signal rom_data_out : Std_Logic_Vector(7 downto 0); -- Flex Memory & Monitor Stack signal flex_cs : Std_logic; signal flex_data_out : Std_Logic_Vector(7 downto 0); -- ACIA/UART Interface signals signal acia_data_out : Std_Logic_Vector(7 downto 0); signal acia_cs : Std_Logic; signal acia_irq : Std_Logic; signal acia_clk : Std_Logic; signal rxd : Std_Logic; signal txd : Std_Logic; signal DCD_n : Std_Logic; signal RTS_n : Std_Logic; signal CTS_n : Std_Logic; -- RAM signal ram1_cs : std_logic; signal ram1_data_out : std_logic_vector(7 downto 0); signal ram2_cs : std_logic; signal ram2_data_out : std_logic_vector(7 downto 0); signal ram3_cs : std_logic; -- CPU Interface signals signal cpu_reset : Std_Logic; signal cpu_clk : Std_Logic; signal cpu_rw : std_logic; signal cpu_vma : std_logic; signal cpu_halt : std_logic; signal cpu_hold : std_logic; signal cpu_firq : std_logic; signal cpu_irq : std_logic; signal cpu_nmi : std_logic; signal cpu_addr : std_logic_vector(15 downto 0); signal cpu_data_in : std_logic_vector(7 downto 0); signal cpu_data_out : std_logic_vector(7 downto 0); -- Dynamic Address Translation signal dat_cs : std_logic; signal dat_addr : std_logic_vector(7 downto 0); -- timer signal timer_data_out : std_logic_vector(7 downto 0); signal timer_cs : std_logic; signal timer_irq : std_logic; -- trap signal trap_cs : std_logic; signal trap_data_out : std_logic_vector(7 downto 0); signal trap_irq : std_logic; signal rst_i : std_logic; -- internal reset signal signal clk_i : std_logic; -- internal master clock signal signal CountL : std_logic_vector(23 downto 0); signal clk_count : natural range 0 to CPU_CLK_DIV; signal Clk25 : std_logic; component btn_debounce Port ( BTN_I : in STD_LOGIC_VECTOR (3 downto 0); CLK : in STD_LOGIC; BTN_O : out STD_LOGIC_VECTOR (3 downto 0)); end component; ----------------------------------------------------------------- -- -- CPU09 CPU core -- ----------------------------------------------------------------- component cpu09 port ( clk: in std_logic; rst: in std_logic; vma: out std_logic; addr: out std_logic_vector(15 downto 0); rw: out std_logic; -- Asynchronous memory interface data_out: out std_logic_vector(7 downto 0); data_in: in std_logic_vector(7 downto 0); irq: in std_logic; firq: in std_logic; nmi: in std_logic; halt: in std_logic; hold: in std_logic ); end component; ---------------------------------------- -- -- 4K Block RAM Monitor ROM -- $F000 - $FFFF -- ---------------------------------------- component mon_rom Port ( clk : in std_logic; rst : in std_logic; cs : in std_logic; rw : in std_logic; addr : in std_logic_vector (11 downto 0); data_out : out std_logic_vector (7 downto 0); data_in : in std_logic_vector (7 downto 0) ); end component; ---------------------------------------- -- -- 8KBytes Block RAM for FLEX9 -- $C000 - $DFFF -- ---------------------------------------- component flex_ram Port ( clk : in std_logic; rst : in std_logic; cs : in std_logic; rw : in std_logic; addr : in std_logic_vector (12 downto 0); data_out : out std_logic_vector (7 downto 0); data_in : in std_logic_vector (7 downto 0) ); end component; ---------------------------------------- -- -- 32KBytes Block RAM 0000 -- $0000 - $7FFF -- ---------------------------------------- component ram_32k Port ( clk : in std_logic; rst : in std_logic; cs : in std_logic; rw : in std_logic; addr : in std_logic_vector (14 downto 0); data_out : out std_logic_vector (7 downto 0); data_in : in std_logic_vector (7 downto 0) ); end component; ---------------------------------------- -- -- 16KBytes Block RAM 8000 -- $8000 - $BFFF -- ---------------------------------------- component ram_16k Port ( clk : in std_logic; rst : in std_logic; cs : in std_logic; rw : in std_logic; addr : in std_logic_vector (13 downto 0); data_out : out std_logic_vector (7 downto 0); data_in : in std_logic_vector (7 downto 0) ); end component; ----------------------------------------------------------------- -- -- 6850 Compatible ACIA / UART -- ----------------------------------------------------------------- component acia6850 port ( clk : in Std_Logic; -- System Clock rst : in Std_Logic; -- Reset input (active high) cs : in Std_Logic; -- miniUART Chip Select rw : in Std_Logic; -- Read / Not Write addr : in Std_Logic; -- Register Select data_in : in Std_Logic_Vector(7 downto 0); -- Data Bus In data_out : out Std_Logic_Vector(7 downto 0); -- Data Bus Out irq : out Std_Logic; -- Interrupt RxC : in Std_Logic; -- Receive Baud Clock TxC : in Std_Logic; -- Transmit Baud Clock RxD : in Std_Logic; -- Receive Data TxD : out Std_Logic; -- Transmit Data DCD_n : in Std_Logic; -- Data Carrier Detect CTS_n : in Std_Logic; -- Clear To Send RTS_n : out Std_Logic -- Request To send ); end component; ----------------------------------------------------------------- -- -- ACIA Clock divider -- ----------------------------------------------------------------- component ACIA_Clock generic ( SYS_CLK_FREQ : integer := SYS_CLK_FREQ; ACIA_CLK_FREQ : integer := ACIA_CLK_FREQ ); port ( clk : in Std_Logic; -- System Clock Input ACIA_clk : out Std_logic -- ACIA Clock output ); end component; ---------------------------------------- -- -- Timer module -- ---------------------------------------- component timer port ( clk : in std_logic; rst : in std_logic; cs : in std_logic; rw : in std_logic; addr : in std_logic; data_in : in std_logic_vector(7 downto 0); data_out : out std_logic_vector(7 downto 0); irq : out std_logic ); end component; ------------------------------------------------------------ -- -- Bus Trap logic -- ------------------------------------------------------------ component trap port ( clk : in std_logic; rst : in std_logic; cs : in std_logic; rw : in std_logic; vma : in std_logic; addr : in std_logic_vector(15 downto 0); data_in : in std_logic_vector(7 downto 0); data_out : out std_logic_vector(7 downto 0); irq : out std_logic ); end component; ---------------------------------------- -- -- Dynamic Address Translation Registers -- ---------------------------------------- component dat_ram port ( clk : in std_logic; rst : in std_logic; cs : in std_logic; rw : in std_logic; addr_lo : in std_logic_vector(3 downto 0); addr_hi : in std_logic_vector(3 downto 0); data_in : in std_logic_vector(7 downto 0); data_out : out std_logic_vector(7 downto 0) ); end component; -- -- Clock buffer -- component BUFG Port ( i: in std_logic; o: out std_logic ); end component; begin -- -- pushbutton debounce -- my_singlestep: btn_debounce port map ( BTN_I => btn, CLK => CLKA, BTN_O => pbtn); RESET_N <= pbtn(0); -- Right PB NMI_N <= pbtn(1); -- Center PB SINGLE_STEP <= pbtn(2); -- Left PB -- -- Generate CPU & Pixel Clock from Memory Clock -- NORMAL: if CLOCK_MODE = 0 generate my_prescaler : process( clk_i, clk_count ) begin if rising_edge( clk_i ) then if clk_count = 0 then clk_count <= CPU_CLK_DIV-1; else clk_count <= clk_count - 1; end if; if clk_count = 0 then clk25 <= '0'; elsif clk_count = (CPU_CLK_DIV/2) then clk25 <= '1'; end if; end if; end process; end generate; SS: if CLOCK_MODE = 1 generate clk25 <= SINGLE_STEP; end generate; -- -- Reset button and reset timer -- my_switch_assignments : process( rst_i, RESET_N) begin rst_i <= RESET_N; cpu_reset <= rst_i; end process; clk_i <= CLKA; ----------------------------------------------------------------------------- -- Instantiation of internal components ----------------------------------------------------------------------------- my_cpu : cpu09 port map ( clk => cpu_clk, rst => cpu_reset, vma => cpu_vma, addr => cpu_addr(15 downto 0), rw => cpu_rw, data_out => cpu_data_out, data_in => cpu_data_in, irq => cpu_irq, firq => cpu_firq, nmi => cpu_nmi, halt => cpu_halt, hold => cpu_hold ); my_rom : mon_rom port map ( clk => cpu_clk, rst => cpu_reset, cs => rom_cs, rw => '1', addr => cpu_addr(11 downto 0), data_in => cpu_data_out, data_out => rom_data_out ); my_flex : flex_ram port map ( clk => cpu_clk, rst => cpu_reset, cs => flex_cs, rw => cpu_rw, addr => cpu_addr(12 downto 0), data_out => flex_data_out, data_in => cpu_data_out ); my_32k : ram_32k port map ( clk => cpu_clk, rst => cpu_reset, cs => ram1_cs, rw => cpu_rw, addr => cpu_addr(14 downto 0), data_out => ram1_data_out, data_in => cpu_data_out ); my_16k : ram_16k port map ( clk => cpu_clk, rst => cpu_reset, cs => ram2_cs, rw => cpu_rw, addr => cpu_addr(13 downto 0), data_out => ram2_data_out, data_in => cpu_data_out ); my_acia : acia6850 port map ( clk => cpu_clk, rst => cpu_reset, cs => acia_cs, rw => cpu_rw, addr => cpu_addr(0), data_in => cpu_data_out, data_out => acia_data_out, irq => acia_irq, RxC => acia_clk, TxC => acia_clk, RxD => RS232_RXD, TxD => RS232_TXD, DCD_n => dcd_n, CTS_n => RS232_CTS, RTS_n => RS232_RTS ); dcd_n <= '0'; my_ACIA_Clock : ACIA_Clock generic map( SYS_CLK_FREQ => SYS_CLK_FREQ, ACIA_CLK_FREQ => ACIA_CLK_FREQ ) port map( clk => Clk_i, acia_clk => acia_clk ); ---------------------------------------- -- -- Timer Module -- ---------------------------------------- my_timer : timer port map ( clk => cpu_clk, rst => cpu_reset, cs => timer_cs, rw => cpu_rw, addr => cpu_addr(0), data_in => cpu_data_out, data_out => timer_data_out, irq => timer_irq ); ---------------------------------------- -- -- Bus Trap Interrupt logic -- ---------------------------------------- my_trap : trap port map ( clk => cpu_clk, rst => cpu_reset, cs => trap_cs, rw => cpu_rw, vma => cpu_vma, addr => cpu_addr, data_in => cpu_data_out, data_out => trap_data_out, irq => trap_irq ); my_dat : dat_ram port map ( clk => cpu_clk, rst => cpu_reset, cs => dat_cs, rw => cpu_rw, addr_hi => cpu_addr(15 downto 12), addr_lo => cpu_addr(3 downto 0), data_in => cpu_data_out, data_out => dat_addr(7 downto 0) ); cpu_clk_buffer : BUFG port map( i => Clk25, o => cpu_clk ); ---------------------------------------------------------------------- -- -- Process to decode memory map -- ---------------------------------------------------------------------- mem_decode: process( cpu_addr, cpu_rw, cpu_vma, dat_addr, rom_data_out, flex_data_out, acia_data_out, timer_data_out, trap_data_out, ram1_data_out, ram2_data_out ) begin cpu_data_in <= (others=>'0'); dat_cs <= '0'; rom_cs <= '0'; flex_cs <= '0'; acia_cs <= '0'; timer_cs <= '0'; trap_cs <= '0'; ram1_cs <= '0'; ram2_cs <= '0'; if cpu_addr( 15 downto 8 ) = "11111111" then -- $FFxx cpu_data_in <= rom_data_out; dat_cs <= cpu_vma; -- write DAT rom_cs <= cpu_vma; -- read ROM -- -- Sys09Bug Monitor ROM $F000 - $FFFF -- elsif dat_addr(3 downto 0) = "1111" then -- $XF000 - $XFFFF cpu_data_in <= rom_data_out; rom_cs <= cpu_vma; -- -- IO Devices $E000 - $E7FF -- elsif dat_addr(3 downto 0) = "1110" then -- $XE000 - $XEFFF case cpu_addr(11 downto 8) is -- -- SWTPC peripherals from $E000 to $E0FF -- when "0000" => case cpu_addr(7 downto 4) is -- -- Console Port ACIA $E000 - $E00F -- when "0000" => -- $E000 cpu_data_in <= acia_data_out; acia_cs <= cpu_vma; -- -- Reserved -- Floppy Disk Controller port $E010 - $E01F -- -- -- Reserved SWTPc MP-T Timer $E040 - $E04F -- when "0100" => -- $E040 cpu_data_in <= (others=> '0'); -- -- Timer $E050 - $E05F -- when "0101" => -- $E050 cpu_data_in <= timer_data_out; timer_cs <= cpu_vma; -- -- Bus Trap Logic $E060 - $E06F -- when "0110" => -- $E060 cpu_data_in <= trap_data_out; trap_cs <= cpu_vma; -- -- Reserved SWTPc MP-ID PIA Timer/Printer Port $E080 - $E08F -- -- -- Reserved SWTPc MP-ID PTM 6840 Timer Port $E090 - $E09F -- -- -- Remaining 6 slots reserved for non SWTPc Peripherals -- when others => -- $E0A0 to $E0FF null; end case; -- -- $E200 to $EFFF reserved for future use -- when others => null; end case; -- -- Flex RAM $0C000 - $0DFFF -- 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 cpu_data_in <= ram1_data_out; ram1_cs <= cpu_vma; -- -- 16k RAM $08000 - $0BFFF -- elsif dat_addr(7 downto 1) = "0000100" then -- $08000 - $0BFFF cpu_data_in <= ram2_data_out; ram2_cs <= cpu_vma; -- -- Everything else is RAM -- else cpu_data_in <= (others => '0'); ram3_cs <= cpu_vma; end if; end process; -- -- Interrupts and other bus control signals -- interrupts : process( NMI_N, acia_irq, trap_irq, timer_irq ) begin cpu_irq <= acia_irq; cpu_nmi <= trap_irq or not( NMI_N ); cpu_firq <= timer_irq; cpu_halt <= '0'; cpu_hold <= '0'; -- pb_hold or ram_hold; end process; -- -- Flash 7 segment LEDS -- my_led_flasher: process( clk_i, rst_i, CountL ) begin if rst_i = '1' then CountL <= "000000000000000000000000"; elsif rising_edge(clk_i) then CountL <= CountL + 1; end if; --S(7 downto 0) <= CountL(23 downto 16); end process; status_leds : process( rst_i, cpu_reset,cpu_addr, cpu_rw, sw) begin case sw is when "0000" => led(3 downto 0) <= cpu_addr(3 downto 0); when "0001" => led(3 downto 0) <= cpu_addr(7 downto 4); when "0010" => led(3 downto 0) <= cpu_addr(11 downto 8); when "0011" => led(3 downto 0) <= cpu_addr(15 downto 12); when "0100" => led(3 downto 0) <= cpu_data_in(3 downto 0); when "0101" => led(3 downto 0) <= cpu_data_in(7 downto 4); when others => led(3 downto 0) <= (others => '0'); end case; end process; -- debug_proc : process( cpu_reset, cpu_clk, cpu_rw, cpu_vma, -- cpu_halt, cpu_hold, -- cpu_firq, cpu_irq, cpu_nmi, -- cpu_addr, cpu_data_out, cpu_data_in ) -- begin -- cpu_reset_o <= cpu_reset; -- cpu_clk_o <= cpu_clk; -- cpu_rw_o <= cpu_rw; -- cpu_vma_o <= cpu_vma; -- cpu_halt_o <= cpu_halt; -- cpu_hold_o <= cpu_hold; -- cpu_firq_o <= cpu_firq; -- cpu_irq_o <= cpu_irq; -- cpu_nmi_o <= cpu_nmi; -- cpu_addr_o <= cpu_addr; -- cpu_data_out_o <= cpu_data_out; -- cpu_data_in_o <= cpu_data_in; -- end process; end rtl; --===================== End of architecture =======================--
Go to most recent revision | Compare with Previous | Blame | View Log