OpenCores
URL https://opencores.org/ocsvn/System09/System09/trunk

Subversion Repositories System09

Compare Revisions

  • This comparison shows the changes necessary to convert path
    /System09/trunk
    from Rev 118 to Rev 117
    Reverse comparison

Rev 118 → Rev 117

/rtl/System09_Digilent_3S500E/System09_Digilent_3S500E_X.ise Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream
rtl/System09_Digilent_3S500E/System09_Digilent_3S500E_X.ise Property changes : Deleted: svn:mime-type ## -1 +0,0 ## -application/octet-stream \ No newline at end of property Index: rtl/System09_Digilent_3S500E/System09_Digilent_3S500E.vhd =================================================================== --- rtl/System09_Digilent_3S500E/System09_Digilent_3S500E.vhd (revision 118) +++ rtl/System09_Digilent_3S500E/System09_Digilent_3S500E.vhd (revision 117) @@ -1,14 +1,14 @@ -- $Id: System09_Digilent_3S500E.vhd,v 1.3.2.1 2008/04/08 14:59:48 davidgb Exp $ ---=========================================================================== +--===========================================================================---- -- --- System09 - SoC for the Digilent Spartan 3E Starter board +-- S Y N T H E Z I A B L E System09 - SOC. -- ---=========================================================================== +--===========================================================================---- -- --- File name : System09_Digilent_3S500E.vhd --- --- Entity name : my_system09 +-- This core adheres to the GNU public license -- +-- File name : System09_Digilent_3S500E.vhd +-- -- Purpose : Top level file for 6809 compatible system on a chip -- Designed with Xilinx XC3S500E Spartan 3E FPGA. -- Implemented With Digilent Xilinx Starter FPGA board, @@ -18,67 +18,19 @@ -- ieee.std_logic_arith -- ieee.numeric_std -- --- Uses : clock_div (../vhdl/clock_div.vhd) System clock divider --- flasher (../vhdl/flasher.vhd) LED flasher --- ram_32k (../Spartan3/ram32k_b16.vhd) 32K block RAM --- cpu09 (../vhdl/cpu09.vhd) CPU core --- mon_rom (../spartan3/sys09bug_3se_rom2k_b16.vhd) Monitor ROM --- acia6850 (../vhdl/acia6850.vhd) ACIA --- ACIA_Clock (../vhdl/ACIA_Clock.vhd) ACIA Baud Clock Divider --- keyboard (../vhdl/keyboard.vhd) PS/2 Keyboard Interface --- vdu8 (../vhdl/vdu8.vhd) 80 x 25 Video Display --- timer (../vhdl/timer.vhd) Timer component --- pia_timer (../vhdl/pia_timer.vhd) PIA interrupt Timer cmponent --- trap (../vhdl/trap.vhd) Hardware Breakpoint Bus Trap --- vdu8 (../vhdl/vdu8.vhd) VDU +-- Uses : mon_rom (kbug_rom2k.vhd) Monitor ROM +-- cpu09 (cpu09.vhd) CPU core +-- miniuart (minitUART3.vhd) ACIA / MiniUART +-- (rxunit3.vhd) +-- (tx_unit3.vhd) -- -- Author : John E. Kent -- dilbert57@opencores.org --- Memory Map : --- --- $0000 - $7FFF System Block RAM --- $E000 - ACIA (SWTPc) --- $E010 - Reserved for SWTPc FD-01 FD1771 FDC --- $E020 - Keyboard --- $E030 - VDU --- $E040 - Reserved for SWTPc MP-T (was Compact Flash) --- $E050 - Timer --- $E060 - Bus Trap (Hardware Breakpoint Interrupt Logic) --- $E070 - PIA Single Step Timer (was Reserved for Trace Buffer) --- $E080 - Reserved for SWTPc MP-ID 6821 PIA (?) --- $E090 - Reserved for SWTPc MP-ID 6840 PTM (?) --- $E0A0 - reserved for SPP Printer Port --- $E0B0 - Reserved --- $E0C0 - Reserved --- $E100 - $E13F Reserved IDE / Compact Flash Card --- $E140 - $E17F Reserved for Ethernet MAC (XESS) --- $E180 - $E1BF Reserved for Expansion Slot 0 (XESS) --- $E1C0 - $E1FF Reserved for Expansion Slot 1 (XESS) --- $E200 - $EFFF Dual Port RAM interface --- $F000 - $F7FF Reserved SWTPc DMAF-2 --- $F800 - $FFFF Sys09bug ROM (Read only) --- $FFF0 - $FFFF Reserved for DAT - Dynamic Address Translation (Write Only) -- --- 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 . --- ---=========================================================================== +--===========================================================================---- -- --- Revision History: --- ---=========================================================================== +-- Revision History: +--===========================================================================-- -- Version 0.1 - 20 March 2003 -- Version 0.2 - 30 March 2003 -- Version 0.3 - 29 April 2003 @@ -130,17 +82,7 @@ -- $E050 - Timer -- $E060 - Bus trap -- $E070 - Parallel I/O --- --- Version 4.1 - July / september 2010 --- Updated VDU interface --- and possible other changes. --- --- Version 4.2 - 14th September 2010 --- Replaced ACIA_6850 with acia6850 --- Cleaned up decoding --- Added Flasher component --- Added Clock Divider component --- +-- --===========================================================================-- library ieee; use ieee.std_logic_1164.all; @@ -189,10 +131,6 @@ ----------------------------------------------------------------------------- -- Signals ----------------------------------------------------------------------------- - -- Clocks - signal sys_clk : std_logic; - signal vga_clk : std_logic; - -- BOOT ROM signal rom_cs : Std_logic; signal rom_data_out : Std_Logic_Vector(7 downto 0); @@ -202,6 +140,11 @@ signal uart_cs : Std_Logic; signal uart_irq : Std_Logic; signal uart_clk : Std_Logic; + signal rxbit : Std_Logic; + signal txbit : Std_Logic; + signal DCD_n : Std_Logic; + signal RTS_n : Std_Logic; + signal CTS_n : Std_Logic; -- timer signal timer_data_out : std_logic_vector(7 downto 0); @@ -220,60 +163,38 @@ signal pia_irq_b : Std_Logic; -- keyboard port - signal kbd_data_out : std_logic_vector(7 downto 0); - signal kbd_cs : std_logic; - signal kbd_irq : std_logic; + signal keyboard_data_out : std_logic_vector(7 downto 0); + signal keyboard_cs : std_logic; + signal keyboard_irq : std_logic; -- Video Display Unit - signal vdu_cs : std_logic; - signal vdu_data_out : std_logic_vector(7 downto 0); + signal vga_clk : std_logic; + signal vdu_cs : std_logic; + signal vdu_data_out : std_logic_vector(7 downto 0); -- RAM - signal ram_cs : std_logic; -- memory chip select - signal ram_data_out : std_logic_vector(7 downto 0); + signal ram_cs : std_logic; -- memory chip select + signal ram_data_out : std_logic_vector(7 downto 0); -- CPU Interface signals - signal cpu_rst : 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); - ------------------------------------------------------------------ --- --- Clock generator --- ------------------------------------------------------------------ - -component clock_div - port( - clk_in : in std_Logic; -- System Clock input - sys_clk : out std_logic; -- System Clock Out (1/1) - vga_clk : out std_logic; -- VGA Pixel Clock Out (1/2) - cpu_clk : out std_logic -- CPU Clock Out (1/4) - ); -end component; - ------------------------------------------------------------------ --- --- LED Flasher --- ------------------------------------------------------------------ + 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); -component flasher - port ( - clk : in std_logic; -- Clock input - rst : in std_logic; -- Reset input (active high) - LED : out Std_Logic -- LED output - ); -end component; + -- CLK_50MHZ clock divide by 2 + signal clock_div : std_logic_vector(1 downto 0); + signal SysClk : std_logic; + signal Reset_n : std_logic; + signal CountL : std_logic_vector(23 downto 0); ----------------------------------------------------------------- -- @@ -285,9 +206,9 @@ port ( clk : in std_logic; rst : in std_logic; + rw : out std_logic; vma : out std_logic; - addr : out std_logic_vector(15 downto 0); - rw : out std_logic; + address : out std_logic_vector(15 downto 0); data_out : out std_logic_vector(7 downto 0); data_in : in std_logic_vector(7 downto 0); irq : in std_logic; @@ -326,8 +247,8 @@ clk : in std_logic; rst : in std_logic; cs : in std_logic; + rw : in std_logic; addr : in std_logic_vector (14 downto 0); - rw : in std_logic; data_in : in std_logic_vector (7 downto 0); data_out : out std_logic_vector (7 downto 0) ); @@ -344,8 +265,8 @@ clk : in std_logic; rst : in std_logic; cs : in std_logic; + rw : in std_logic; addr : in std_logic_vector(1 downto 0); - rw : in std_logic; data_in : in std_logic_vector(7 downto 0); data_out : out std_logic_vector(7 downto 0); irqa : out std_logic; @@ -360,7 +281,7 @@ -- ----------------------------------------------------------------- -component acia6850 +component ACIA_6850 port ( clk : in Std_Logic; -- System Clock rst : in Std_Logic; -- Reset input (active high) @@ -404,12 +325,12 @@ component timer port ( - clk : in std_logic; - rst : in std_logic; - cs : in std_logic; - addr : in std_logic; - rw : in std_logic; - data_in : in std_logic_vector(7 downto 0); + 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 ); @@ -426,8 +347,8 @@ clk : in std_logic; rst : in std_logic; cs : in std_logic; + rw : in std_logic; vma : in std_logic; - rw : 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); @@ -443,19 +364,19 @@ component keyboard generic( - KBD_CLK_FREQ : integer := CPU_CLK_FREQ + KBD_CLK_FREQ : integer := CPU_CLK_FREQ ); port( - clk : in std_logic; - rst : in std_logic; - cs : in std_logic; - addr : in std_logic; - rw : 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; - kbd_clk : inout std_logic; - kbd_data : inout std_logic + 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; + kbd_clk : inout std_logic; + kbd_data : inout std_logic ); end component; @@ -498,49 +419,25 @@ ); end component; -begin - ------------------------------------------------------------------------------ --- Instantiation of internal components ------------------------------------------------------------------------------ - ----------------------------------------- --- --- Clock generator --- ----------------------------------------- - -my_clock_div: clock_div port map ( - clk_in => CLK_50MHZ, -- Clock input - sys_clk => sys_clk, -- System Clock Out (1/1) - vga_clk => vga_clk, -- CPU/VGA Pixel Clock Out (1/2) - cpu_clk => open -- (1/4) - ); - ------------------------------------------ --- --- LED Flasher --- ------------------------------------------ -my_LED_flasher : flasher port map ( - clk => cpu_clk, - rst => cpu_rst, - LED => LED(0) +component BUFG +port ( + i: in std_logic; + o: out std_logic ); - ----------------------------------------- --- --- 6809 compatible CPU --- ----------------------------------------- +end component; +begin + ----------------------------------------------------------------------------- + -- Instantiation of internal components + ----------------------------------------------------------------------------- + my_cpu : cpu09 port map ( clk => cpu_clk, - rst => cpu_rst, + rst => cpu_reset, + rw => cpu_rw, vma => cpu_vma, - addr => cpu_addr(15 downto 0), - rw => cpu_rw, + address => cpu_addr(15 downto 0), data_out => cpu_data_out, data_in => cpu_data_in, irq => cpu_irq, @@ -552,10 +449,10 @@ my_rom : mon_rom port map ( clk => cpu_clk, - rst => cpu_rst, + rst => cpu_reset, cs => rom_cs, + rw => '1', addr => cpu_addr(10 downto 0), - rw => '1', data_in => cpu_data_out, data_out => rom_data_out ); @@ -562,10 +459,10 @@ my_ram : ram_32k port map ( clk => cpu_clk, - rst => cpu_rst, + rst => cpu_reset, cs => ram_cs, + rw => cpu_rw, addr => cpu_addr(14 downto 0), - rw => cpu_rw, data_in => cpu_data_out, data_out => ram_data_out ); @@ -572,10 +469,10 @@ my_pia : pia_timer port map ( clk => cpu_clk, - rst => cpu_rst, + rst => cpu_reset, cs => pia_cs, + rw => cpu_rw, addr => cpu_addr(1 downto 0), - rw => cpu_rw, data_in => cpu_data_out, data_out => pia_data_out, irqa => pia_irq_a, @@ -582,27 +479,28 @@ irqb => pia_irq_b ); + ---------------------------------------- -- -- ACIA/UART Serial interface -- ---------------------------------------- -my_ACIA : acia6850 port map ( +my_ACIA : ACIA_6850 port map ( clk => cpu_clk, - rst => cpu_rst, + rst => cpu_reset, cs => uart_cs, + rw => cpu_rw, addr => cpu_addr(0), - rw => cpu_rw, data_in => cpu_data_out, data_out => uart_data_out, irq => uart_irq, RxC => uart_clk, TxC => uart_clk, - RxD => RS232_DCE_RXD, - TxD => RS232_DCE_TXD, - DCD_n => '0', - CTS_n => '0', - RTS_n => open + RxD => rxbit, + TxD => txbit, + DCD_n => dcd_n, + CTS_n => cts_n, + RTS_n => rts_n ); ---------------------------------------- @@ -616,7 +514,7 @@ ACIA_CLK_FREQ => ACIA_CLK_FREQ ) port map( - clk => sys_clk, + clk => SysClk, acia_clk => uart_clk ); @@ -629,19 +527,19 @@ ---------------------------------------- my_keyboard : keyboard generic map ( - KBD_CLK_FREQ => CPU_CLK_FREQ + KBD_CLK_FREQ => CPU_CLK_FREQ ) port map( - clk => cpu_clk, - rst => cpu_rst, - cs => kbd_cs, - addr => cpu_addr(0), - rw => cpu_rw, - data_in => cpu_data_out(7 downto 0), - data_out => kbd_data_out(7 downto 0), - irq => kbd_irq, - kbd_clk => PS2_CLK, - kbd_data => PS2_DATA + clk => cpu_clk, + rst => cpu_reset, + cs => keyboard_cs, + rw => cpu_rw, + addr => cpu_addr(0), + data_in => cpu_data_out(7 downto 0), + data_out => keyboard_data_out(7 downto 0), + irq => keyboard_irq, + kbd_clk => PS2_CLK, + kbd_data => PS2_DATA ); ---------------------------------------- @@ -661,16 +559,16 @@ VGA_VER_CHAR_LINES => 16, -- LINES VGA_VER_FRONT_PORCH => 10, -- LINES VGA_VER_SYNC => 2, -- LINES - VGA_VER_BACK_PORCH => 34 -- LINES + VGA_VER_FRONT_PORCH => 34 -- LINES ) port map( -- Control Registers vdu_clk => cpu_clk, -- 25 MHz System Clock in - vdu_rst => cpu_rst, + vdu_rst => cpu_reset, vdu_cs => vdu_cs, + vdu_rw => cpu_rw, vdu_addr => cpu_addr(2 downto 0), - vdu_rw => cpu_rw, vdu_data_in => cpu_data_out, vdu_data_out => vdu_data_out, @@ -691,7 +589,7 @@ ---------------------------------------- my_timer : timer port map ( clk => cpu_clk, - rst => cpu_rst, + rst => cpu_reset, cs => timer_cs, rw => cpu_rw, addr => cpu_addr(0), @@ -707,7 +605,7 @@ ---------------------------------------- my_trap : trap port map ( clk => cpu_clk, - rst => cpu_rst, + rst => cpu_reset, cs => trap_cs, rw => cpu_rw, vma => cpu_vma, @@ -716,6 +614,22 @@ data_out => trap_data_out, irq => trap_irq ); + +-- +-- 25 MHz CPU clock +-- +cpu_clk_buffer : BUFG port map( + i => clock_div(0), + o => cpu_clk + ); + +-- +-- 25 MHz VGA Pixel clock +-- +vga_clk_buffer : BUFG port map( + i => clock_div(0), + o => vga_clk + ); ---------------------------------------------------------------------- -- @@ -723,7 +637,8 @@ -- ---------------------------------------------------------------------- -mem_decode: process( cpu_addr, cpu_rw, cpu_vma, +mem_decode: process( cpu_clk, Reset_n, + cpu_addr, cpu_rw, cpu_vma, rom_data_out, ram_data_out, timer_data_out, @@ -730,20 +645,14 @@ trap_data_out, pia_data_out, uart_data_out, - kbd_data_out, + keyboard_data_out, vdu_data_out ) +variable decode_addr : std_logic_vector(3 downto 0); begin - - rom_cs <= '0'; - ram_cs <= '0'; - uart_cs <= '0'; - timer_cs <= '0'; - trap_cs <= '0'; - pia_cs <= '0'; - kbd_cs <= '0'; - vdu_cs <= '0'; +-- decode_addr := dat_addr(3 downto 0) & cpu_addr(11); + decode_addr := cpu_addr(15 downto 12); - case cpu_addr(15 downto 12) is + case decode_addr is -- -- SBUG/KBUG/SYS09BUG Monitor ROM $F800 - $FFFF -- @@ -750,11 +659,20 @@ when "1111" => -- $F000 - $FFFF cpu_data_in <= rom_data_out; rom_cs <= cpu_vma; -- read ROM + ram_cs <= '0'; + uart_cs <= '0'; + timer_cs <= '0'; + trap_cs <= '0'; + pia_cs <= '0'; + keyboard_cs <= '0'; + vdu_cs <= '0'; -- -- IO Devices $E000 - $EFFF -- when "1110" => -- $E000 - $E7FF + rom_cs <= '0'; + ram_cs <= '0'; case cpu_addr(7 downto 4) is -- -- UART / ACIA $E000 @@ -762,6 +680,11 @@ when "0000" => -- $E000 cpu_data_in <= uart_data_out; uart_cs <= cpu_vma; + timer_cs <= '0'; + trap_cs <= '0'; + pia_cs <= '0'; + keyboard_cs <= '0'; + vdu_cs <= '0'; -- -- WD1771 FDC sites at $E010-$E01F @@ -768,13 +691,24 @@ -- when "0001" => -- $E010 cpu_data_in <= (others => '0'); + uart_cs <= '0'; + timer_cs <= '0'; + trap_cs <= '0'; + pia_cs <= '0'; + keyboard_cs <= '0'; + vdu_cs <= '0'; -- -- Keyboard port $E020 - $E02F -- when "0010" => -- $E020 - cpu_data_in <= kbd_data_out; - kbd_cs <= cpu_vma; + cpu_data_in <= keyboard_data_out; + uart_cs <= '0'; + timer_cs <= '0'; + trap_cs <= '0'; + pia_cs <= '0'; + keyboard_cs <= cpu_vma; + vdu_cs <= '0'; -- -- VDU port $E030 - $E03F @@ -781,6 +715,11 @@ -- when "0011" => -- $E030 cpu_data_in <= vdu_data_out; + uart_cs <= '0'; + timer_cs <= '0'; + trap_cs <= '0'; + pia_cs <= '0'; + keyboard_cs <= '0'; vdu_cs <= cpu_vma; -- @@ -788,6 +727,12 @@ -- when "0100" => -- $E040 cpu_data_in <= (others => '0'); + uart_cs <= '0'; + timer_cs <= '0'; + trap_cs <= '0'; + pia_cs <= '0'; + keyboard_cs <= '0'; + vdu_cs <= '0'; -- -- Timer $E050 - $E05F @@ -794,7 +739,12 @@ -- when "0101" => -- $E050 cpu_data_in <= timer_data_out; + uart_cs <= '0'; timer_cs <= cpu_vma; + trap_cs <= '0'; + pia_cs <= '0'; + keyboard_cs <= '0'; + vdu_cs <= '0'; -- -- Bus Trap Logic $E060 - $E06F @@ -801,17 +751,33 @@ -- when "0110" => -- $E060 cpu_data_in <= trap_data_out; + uart_cs <= '0'; + timer_cs <= '0'; trap_cs <= cpu_vma; + pia_cs <= '0'; + keyboard_cs <= '0'; + vdu_cs <= '0'; -- - -- PIA Timer $E070 - $E07F + -- I/O port $E070 - $E07F -- when "0111" => -- $E070 cpu_data_in <= pia_data_out; + uart_cs <= '0'; + timer_cs <= '0'; + trap_cs <= '0'; pia_cs <= cpu_vma; + keyboard_cs <= '0'; + vdu_cs <= '0'; when others => -- $E080 to $E7FF cpu_data_in <= (others => '0'); + uart_cs <= '0'; + timer_cs <= '0'; + trap_cs <= '0'; + pia_cs <= '0'; + keyboard_cs <= '0'; + vdu_cs <= '0'; end case; -- @@ -820,37 +786,73 @@ when "1101" | "1100" | "1011" | "1010" | "1001" | "1000" => cpu_data_in <= (others => '0'); - + rom_cs <= '0'; + ram_cs <= '0'; + uart_cs <= '0'; + timer_cs <= '0'; + trap_cs <= '0'; + pia_cs <= '0'; + keyboard_cs <= '0'; + vdu_cs <= '0'; -- -- Everything else is RAM -- when others => cpu_data_in <= ram_data_out; + rom_cs <= '0'; ram_cs <= cpu_vma; + uart_cs <= '0'; + timer_cs <= '0'; + trap_cs <= '0'; + pia_cs <= '0'; + keyboard_cs <= '0'; + vdu_cs <= '0'; end case; end process; -- --- Assign CPU clock, reset, interrupt, halt & hold signals --- as well as LED signals +-- Interrupts and other bus control signals -- -assign_signals : process( vga_clk, BTN_SOUTH, - pia_irq_a, pia_irq_b, uart_irq, trap_irq, timer_irq, kbd_irq +interrupts : process( Reset_n, + pia_irq_a, pia_irq_b, uart_irq, trap_irq, timer_irq, keyboard_irq ) -begin - cpu_clk <= vga_clk; - cpu_rst <= BTN_SOUTH; -- CPU reset is active high - cpu_irq <= uart_irq or kbd_irq; - cpu_nmi <= pia_irq_a or trap_irq; - cpu_firq <= pia_irq_b or timer_irq; - cpu_halt <= '0'; - cpu_hold <= '0'; +begin + cpu_reset <= not Reset_n; -- CPU reset is active high + cpu_irq <= uart_irq or keyboard_irq; + cpu_nmi <= pia_irq_a or trap_irq; + cpu_firq <= pia_irq_b or timer_irq; + cpu_halt <= '0'; + cpu_hold <= '0'; +end process; - -- LED outputs - LED(7 downto 1) <= (others=>'1'); - +-- +-- +my_led_flasher: process( SysClk, Reset_n, CountL ) +begin + if Reset_n = '0' then + CountL <= "000000000000000000000000"; + elsif(SysClk'event and SysClk = '0') then + CountL <= CountL + 1; + end if; + LED(7 downto 0) <= CountL(23 downto 16); end process; +-- +-- Clock divider +-- +my_clock_divider: process( SysClk ) +begin + if SysClk'event and SysClk='0' then + clock_div <= clock_div + "01"; + end if; +end process; +DCD_n <= '0'; +CTS_n <= '0'; +Reset_n <= not BTN_SOUTH; -- CPU reset is active high +SysClk <= CLK_50MHZ; +rxbit <= RS232_DCE_RXD; +RS232_DCE_TXD <= txbit; + end my_computer; --===================== End of architecture =======================--
/rtl/VHDL/peripheral_bus.vhd
86,8 → 86,8
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use ieee.std_logic_unsigned.all;
--library unisim;
-- use unisim.vcomponents.all;
library unisim;
use unisim.vcomponents.all;
 
-----------------------------------------------------------------------
-- Entity for peripheral bus --
/rtl/VHDL/acia6850.vhd
12,8 → 12,8
-- Asynchronous Communications Interface Adapter (ACIA)
--
-- Dependencies : ieee.std_logic_1164
-- ieee.numeric_std
-- ieee.std_logic_unsigned
-- ieee.numeric_std
-- unisim.vcomponents
--
-- Author : John E. Kent
--
125,8 → 125,8
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use ieee.std_logic_unsigned.all;
--library unisim;
-- use unisim.vcomponents.all;
library unisim;
use unisim.vcomponents.all;
 
-----------------------------------------------------------------------
-- Entity for ACIA_6850 --
340,12 → 340,11
-- Generate Read / Write strobes.
-----------------------------------------------------------------------------
 
acia_read_write : process(clk, ac_rst)
ACIA_Read_Write : process(clk, ac_rst)
begin
if falling_edge(clk) then
if rst = '1' then
CtrlReg(1 downto 0) <= "11";
CtrlReg(7 downto 2) <= (others => '0');
if ac_rst = '1' then
CtrlReg <= (others => '0');
TxReg <= (others => '0');
RxRd <= '0';
TxWr <= '0';
/rtl/VHDL/Flasher.vhd
14,6 → 14,7
-- Dependencies : ieee.std_logic_1164
-- ieee.numeric_std
-- ieee.std_logic_unsigned
-- unisim.vcomponents
--
-- Author : John E. Kent
--
52,8 → 53,8
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use ieee.std_logic_unsigned.all;
--library unisim;
-- use unisim.vcomponents.all;
library unisim;
use unisim.vcomponents.all;
 
-----------------------------------------------------------------------
-- Entity for B3_SRAM --
/rtl/VHDL/ACIA_Clock.vhd
13,6 → 13,7
-- ieee.std_logic_arith
-- ieee.std_logic_unsigned
-- ieee.numeric_std
-- unisim.vcomponents
-- work.bit_funcs
--
-- Author : John E. Kent
54,8 → 55,8
use ieee.std_logic_arith.all;
use ieee.std_logic_unsigned.all;
use ieee.numeric_std.all;
--library unisim;
-- use unisim.vcomponents.all;
library unisim;
use unisim.vcomponents.all;
library work;
use work.bit_funcs.all;
 
/rtl/VHDL/datram.vhd
87,8 → 87,8
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
--library unisim;
-- use unisim.vcomponents.all;
library unisim;
use unisim.vcomponents.all;
 
entity dat_ram is
port (
/rtl/VHDL/spi-master.vhd
11,7 → 11,10
-- Purpose : Implements a SPI Master Controller
--
-- Dependencies : ieee.std_logic_1164
-- ieee.std_logic_arith
-- ieee.std_logic_unsigned
-- ieee.numeric_std
-- unisim.vcomponents
--
-- Author : Hans Huebner
--
/rtl/VHDL/ps2_keyboard.vhd
12,6 → 12,7
-- ieee.std_logic_unsigned
-- ieee.std_logic_arith
-- ieee.numeric_std
-- unisim.vcomponents
--
-- Author : Original Verilog version by John Clayton
-- Converted to VHDL by John E. Kent
144,7 → 145,7
-- they correspond to 60usec for a 49.152MHz clock.
--
-- Author: John Kent
--2001-02-10 Converted to VHDL
-- 2001-02-10 Converted to VHDL
-- 2004-09-11 Added ctrl key
-- Changed undefined key codes to x"ff"
-- Reversed clock polarity
153,9 → 154,9
-- 2007-02-06 Added Generic Clock parameter
-- 2010-05-31 Revised header, added GPL
-- 2010-06-17 Change some signal names for consistancy
-- 2010-10-24 Rearranged code to prevent shift key outputting characters
--
--
--
---------------------------------------------------------------------------------------
 
library ieee;
163,8 → 164,8
use ieee.std_logic_arith.all;
use ieee.std_logic_unsigned.all;
use ieee.numeric_std.all;
--library unisim;
-- use unisim.vcomponents.all;
library unisim;
use unisim.vcomponents.all;
 
entity ps2_keyboard is
generic (
202,10 → 203,7
constant LEFT_SHIFT : integer := 16#12#;
constant RIGHT_SHIFT : integer := 16#59#;
constant CTRL_CODE : integer := 16#14#;
constant LEFT_ALT : integer := 16#11#;
constant CAPS_CODE : integer := 16#58#;
constant SCROLL_LOCK : integer := 16#7E#;
constant NUM_LOCK : integer := 16#77#;
constant CAPS_CODE : integer := 16#58#;
 
 
-- constants
230,9 → 228,9
--constant TIMER_5USEC_BITS_PP : integer := 7; -- Number of bits needed for timer
 
-- Values for generic Clock up to 50 MHz
constant TIMER_60USEC_VALUE_PP : integer := CLK_FREQ_MHZ * 60; -- Number of clock cycles for 60usec.
constant TIMER_60USEC_VALUE_PP : integer := CLK_FREQ_MHZ * 60; -- Number of sys_clks for 60usec.
constant TIMER_60USEC_BITS_PP : integer := 12; -- Number of bits needed for timer
constant TIMER_5USEC_VALUE_PP : integer := CLK_FREQ_MHZ * 5; -- Number of clock cycles for debounce
constant TIMER_5USEC_VALUE_PP : integer := CLK_FREQ_MHZ * 5; -- Number of sys_clks for debounce
constant TIMER_5USEC_BITS_PP : integer := 8; -- Number of bits needed for timer
 
constant TRAP_SHIFT_KEYS_PP : integer := 1; -- Default: No shift key trap.
376,72 → 374,66
 
m1_state_logic : process( m1_state, q,
tx_shifting_done, tx_write,
ps2_clk_s, ps2_data_s,
timer_60usec_done, timer_5usec_done )
ps2_clk_s, ps2_data_s,
timer_60usec_done, timer_5usec_done )
begin
-- Output signals default to this value, unless changed in a state condition.
ps2_clk_hi_z <= '1';
ps2_data_hi_z <= '1';
tx_error <= '0';
enable_timer_60usec <= '0';
enable_timer_5usec <= '0';
ps2_clk_hi_z <= '1';
ps2_data_hi_z <= '1';
tx_error <= '0';
enable_timer_60usec <= '0';
enable_timer_5usec <= '0';
 
case (m1_state) is
--
-- receive clock transitions
--
when m1_rx_clk_h =>
enable_timer_60usec <= '1';
if (tx_write = '1') then
m1_next_state <= m1_tx_reset_timer;
elsif (ps2_clk_s = '0') then
m1_next_state <= m1_rx_falling_edge_marker;
else
m1_next_state <= m1_rx_clk_h;
case (m1_state) is
when m1_rx_clk_h =>
enable_timer_60usec <= '1';
if (tx_write = '1') then
m1_next_state <= m1_tx_reset_timer;
elsif (ps2_clk_s = '0') then
m1_next_state <= m1_rx_falling_edge_marker;
else
m1_next_state <= m1_rx_clk_h;
end if;
when m1_rx_falling_edge_marker =>
enable_timer_60usec <= '0';
m1_next_state <= m1_rx_clk_l;
when m1_rx_falling_edge_marker =>
enable_timer_60usec <= '0';
m1_next_state <= m1_rx_clk_l;
 
when m1_rx_clk_l =>
enable_timer_60usec <= '1';
if (tx_write = '1') then
m1_next_state <= m1_tx_reset_timer;
elsif (ps2_clk_s = '1') then
m1_next_state <= m1_rx_rising_edge_marker;
else
m1_next_state <= m1_rx_clk_l;
end if;
 
when m1_rx_rising_edge_marker =>
enable_timer_60usec <= '0';
m1_next_state <= m1_rx_clk_h;
 
--
-- write to keyboard (Tx)
--
when m1_tx_reset_timer =>
enable_timer_60usec <= '0';
m1_next_state <= m1_tx_force_clk_l;
when m1_rx_clk_l =>
enable_timer_60usec <= '1';
if (tx_write = '1') then
m1_next_state <= m1_tx_reset_timer;
elsif (ps2_clk_s = '1') then
m1_next_state <= m1_rx_rising_edge_marker;
else
m1_next_state <= m1_rx_clk_l;
end if;
 
when m1_tx_force_clk_l =>
enable_timer_60usec <= '1';
ps2_clk_hi_z <= '0'; -- Force the ps2_clk line low.
if (timer_60usec_done = '1') then
m1_next_state <= m1_tx_first_wait_clk_h;
else
m1_next_state <= m1_tx_force_clk_l;
end if;
when m1_rx_rising_edge_marker =>
enable_timer_60usec <= '0';
m1_next_state <= m1_rx_clk_h;
 
when m1_tx_first_wait_clk_h =>
enable_timer_5usec <= '1';
ps2_data_hi_z <= '0'; -- Start bit.
if (ps2_clk_s = '0') and (timer_5usec_done = '1') then
m1_next_state <= m1_tx_clk_l;
else
m1_next_state <= m1_tx_first_wait_clk_h;
end if;
when m1_tx_reset_timer =>
enable_timer_60usec <= '0';
m1_next_state <= m1_tx_force_clk_l;
 
when m1_tx_force_clk_l =>
enable_timer_60usec <= '1';
ps2_clk_hi_z <= '0'; -- Force the ps2_clk line low.
if (timer_60usec_done = '1') then
m1_next_state <= m1_tx_first_wait_clk_h;
else
m1_next_state <= m1_tx_force_clk_l;
end if;
 
when m1_tx_first_wait_clk_h =>
enable_timer_5usec <= '1';
ps2_data_hi_z <= '0'; -- Start bit.
if (ps2_clk_s = '0') and (timer_5usec_done = '1') then
m1_next_state <= m1_tx_clk_l;
else
m1_next_state <= m1_tx_first_wait_clk_h;
end if;
-- This state must be included because the device might possibly
-- delay for up to 10 milliseconds before beginning its clock pulses.
448,285 → 440,267
-- During that waiting time, we cannot drive the data (q[0]) because it
-- is possibly 1, which would cause the keyboard to abort its receive
-- and the expected clocks would then never be generated.
when m1_tx_first_wait_clk_l =>
ps2_data_hi_z <= '0';
if (ps2_clk_s = '0') then
m1_next_state <= m1_tx_clk_l;
else
m1_next_state <= m1_tx_first_wait_clk_l;
end if;
when m1_tx_first_wait_clk_l =>
ps2_data_hi_z <= '0';
if (ps2_clk_s = '0') then
m1_next_state <= m1_tx_clk_l;
else
m1_next_state <= m1_tx_first_wait_clk_l;
end if;
 
when m1_tx_wait_clk_h =>
enable_timer_5usec <= '1';
ps2_data_hi_z <= q(0);
if (ps2_clk_s = '1') and (timer_5usec_done = '1') then
m1_next_state <= m1_tx_rising_edge_marker;
else
m1_next_state <= m1_tx_wait_clk_h;
end if;
when m1_tx_wait_clk_h =>
enable_timer_5usec <= '1';
ps2_data_hi_z <= q(0);
if (ps2_clk_s = '1') and (timer_5usec_done = '1') then
m1_next_state <= m1_tx_rising_edge_marker;
else
m1_next_state <= m1_tx_wait_clk_h;
end if;
 
when m1_tx_rising_edge_marker =>
ps2_data_hi_z <= q(0);
m1_next_state <= m1_tx_clk_h;
when m1_tx_rising_edge_marker =>
ps2_data_hi_z <= q(0);
m1_next_state <= m1_tx_clk_h;
 
when m1_tx_clk_h =>
ps2_data_hi_z <= q(0);
if (tx_shifting_done = '1') then
m1_next_state <= m1_tx_wait_keyboard_ack;
elsif (ps2_clk_s = '0') then
m1_next_state <= m1_tx_clk_l;
else
m1_next_state <= m1_tx_clk_h;
end if;
when m1_tx_clk_h =>
ps2_data_hi_z <= q(0);
if (tx_shifting_done = '1') then
m1_next_state <= m1_tx_wait_keyboard_ack;
elsif (ps2_clk_s = '0') then
m1_next_state <= m1_tx_clk_l;
else
m1_next_state <= m1_tx_clk_h;
end if;
 
when m1_tx_clk_l =>
ps2_data_hi_z <= q(0);
if (ps2_clk_s = '1') then
m1_next_state <= m1_tx_wait_clk_h;
else
m1_next_state <= m1_tx_clk_l;
end if;
when m1_tx_clk_l =>
ps2_data_hi_z <= q(0);
if (ps2_clk_s = '1') then
m1_next_state <= m1_tx_wait_clk_h;
else
m1_next_state <= m1_tx_clk_l;
end if;
 
when m1_tx_wait_keyboard_ack =>
if (ps2_clk_s = '0') and (ps2_data_s = '1') then
m1_next_state <= m1_tx_error;
elsif (ps2_clk_s = '0') and (ps2_data_s = '0') then
m1_next_state <= m1_tx_done_recovery;
else
m1_next_state <= m1_tx_wait_keyboard_ack;
end if;
when m1_tx_wait_keyboard_ack =>
if (ps2_clk_s = '0') and (ps2_data_s = '1') then
m1_next_state <= m1_tx_error;
elsif (ps2_clk_s = '0') and (ps2_data_s = '0') then
m1_next_state <= m1_tx_done_recovery;
else
m1_next_state <= m1_tx_wait_keyboard_ack;
end if;
 
when m1_tx_done_recovery =>
if (ps2_clk_s = '1') and (ps2_data_s = '1') then
m1_next_state <= m1_rx_clk_h;
else
m1_next_state <= m1_tx_done_recovery;
end if;
when m1_tx_done_recovery =>
if (ps2_clk_s = '1') and (ps2_data_s = '1') then
m1_next_state <= m1_rx_clk_h;
else
m1_next_state <= m1_tx_done_recovery;
end if;
 
when m1_tx_error =>
tx_error <= '1';
if (ps2_clk_s = '1') and (ps2_data_s ='1') then
m1_next_state <= m1_rx_clk_h;
else
m1_next_state <= m1_tx_error;
end if;
when m1_tx_error =>
tx_error <= '1';
if (ps2_clk_s = '1') and (ps2_data_s ='1') then
m1_next_state <= m1_rx_clk_h;
else
m1_next_state <= m1_tx_error;
end if;
 
when others =>
m1_next_state <= m1_rx_clk_h;
end case;
when others =>
m1_next_state <= m1_rx_clk_h;
end case;
end process;
 
--
 
-- This is the bit counter
--
bit_counter: process(clk, reset, m1_state, bit_count )
begin
if clk'event and clk = '0' then
if ( reset = '1' ) or ( rx_shifting_done = '1' ) or
(m1_state = m1_tx_wait_keyboard_ack) then -- After tx is done.
bit_count <= "0000"; -- normal reset
elsif (timer_60usec_done = '1' ) and
( m1_state = m1_rx_clk_h ) and
( ps2_clk_s = '1' ) then
bit_count <= "0000"; -- rx watchdog timer reset
elsif ( m1_state = m1_rx_falling_edge_marker ) or -- increment for rx
(m1_state = m1_tx_rising_edge_marker) then -- increment for tx
bit_count <= bit_count + 1;
end if;
end if;
 
if (bit_count = TOTAL_BITS) then
rx_shifting_done <= '1';
else
rx_shifting_done <= '0';
end if;
 
if (bit_count = (TOTAL_BITS-1)) then
tx_shifting_done <= '1';
else
tx_shifting_done <= '0';
end if;
if clk'event and clk = '0' then
if ( reset = '1' ) or
( rx_shifting_done = '1' ) or
(m1_state = m1_tx_wait_keyboard_ack) then -- After tx is done.
bit_count <= "0000"; -- normal reset
elsif (timer_60usec_done = '1' ) and
(m1_state = m1_rx_clk_h) and
(ps2_clk_s = '1') then
bit_count <= "0000"; -- rx watchdog timer reset
elsif (m1_state = m1_rx_falling_edge_marker) or -- increment for rx
(m1_state = m1_tx_rising_edge_marker) then -- increment for tx
bit_count <= bit_count + 1;
end if;
end if;
end process;
 
assign: process( bit_count, tx_write, m1_state, tx_data_empty_o, m1_state )
assign: process( bit_count, tx_write, tx_data_empty_o, m1_state )
begin
--
-- This is the signal which enables loading of the shift register.
-- It also indicates "ack" to the device writing to the transmitter.
--
if ((tx_write = '1') and (m1_state = m1_rx_clk_h)) or
((tx_write = '1') and (m1_state = m1_rx_clk_l)) then
tx_data_empty_o <= '1';
else
tx_data_empty_o <= '0';
end if;
tx_data_empty <= tx_data_empty_o;
if (bit_count = TOTAL_BITS) then
rx_shifting_done <= '1';
else
rx_shifting_done <= '0';
end if;
 
if (bit_count = (TOTAL_BITS-1)) then
tx_shifting_done <= '1';
else
tx_shifting_done <= '0';
end if;
 
-- This is the signal which enables loading of the shift register.
-- It also indicates "ack" to the device writing to the transmitter.
if ((tx_write = '1') and (m1_state = m1_rx_clk_h)) or
((tx_write = '1') and (m1_state = m1_rx_clk_l)) then
tx_data_empty_o <= '1';
else
tx_data_empty_o <= '0';
end if;
tx_data_empty <= tx_data_empty_o;
end process;
 
-- This is the ODD parity bit for the transmitted word.
-- assign tx_parity_bit = ~^tx_data;
--
tx_parity_bit <= not( tx_data(7) xor tx_data(6) xor tx_data(5) xor tx_data(4) xor
tx_data(3) xor tx_data(2) xor tx_data(1) xor tx_data(0) );
 
-- This is the shift register
q_shift : process(clk, tx_data_empty_o, tx_parity_bit, tx_data,
m1_state, q, ps2_data_s, rx_shifting_done )
begin
--
-- This is the ODD parity bit for the transmitted word.
-- assign tx_parity_bit = ~^tx_data;
--
tx_parity_bit <= not( tx_data(7) xor tx_data(6) xor tx_data(5) xor tx_data(4) xor
tx_data(3) xor tx_data(2) xor tx_data(1) xor tx_data(0) );
if clk'event and clk='0' then
if (reset = '1') then
q <= (others=>'0');
elsif (tx_data_empty_o = '1') then
q <= "1" & tx_parity_bit & tx_data & "0";
elsif ( (m1_state = m1_rx_falling_edge_marker) or
(m1_state = m1_tx_rising_edge_marker) ) then
q <= ps2_data_s & q((TOTAL_BITS-1) downto 1);
end if;
end if;
 
if clk'event and clk='0' then
if (reset = '1') then
q <= "00000000000";
elsif (tx_data_empty_o = '1') then
q <= "1" & tx_parity_bit & tx_data & "0";
elsif ( (m1_state = m1_rx_falling_edge_marker) or
(m1_state = m1_tx_rising_edge_marker) ) then
q <= ps2_data_s & q((TOTAL_BITS-1) downto 1);
end if;
end if;
 
-- Create the signals which indicate special scan codes received.
-- These are the "unlatched versions."
if (q(8 downto 1) = EXTEND_CODE) and (rx_shifting_done = '1') then
extended <= '1';
else
extended <= '0';
end if;
if (q(8 downto 1) = RELEASE_CODE) and (rx_shifting_done = '1') then
released <= '1';
else
released <= '0';
end if;
end process;
 
--
 
-- This is the 60usec timer counter
--
timer60usec: process(clk, enable_timer_60usec, timer_60usec_count)
begin
if clk'event and clk = '0' then
if (enable_timer_60usec = '0') then
timer_60usec_count <= (others => '0');
elsif (timer_60usec_done = '0') then
timer_60usec_count <= timer_60usec_count + 1;
end if;
end if;
if clk'event and clk = '0' then
if (enable_timer_60usec = '0') then
timer_60usec_count <= (others => '0');
elsif (timer_60usec_done = '0') then
timer_60usec_count <= timer_60usec_count + 1;
end if;
end if;
 
if (timer_60usec_count = (TIMER_60USEC_VALUE_PP - 1)) then
timer_60usec_done <= '1';
else
timer_60usec_done <= '0';
end if;
if (timer_60usec_count = (TIMER_60USEC_VALUE_PP - 1)) then
timer_60usec_done <= '1';
else
timer_60usec_done <= '0';
end if;
end process;
 
--
 
-- This is the 5usec timer counter
--
timer5usec : process(clk, enable_timer_5usec, timer_5usec_count )
begin
if clk'event and clk = '0' then
if (enable_timer_5usec = '0') then
timer_5usec_count <= (others => '0');
elsif (timer_5usec_done = '0') then
timer_5usec_count <= timer_5usec_count + 1;
end if;
end if;
if clk'event and clk = '0' then
if (enable_timer_5usec = '0') then
timer_5usec_count <= (others => '0');
elsif (timer_5usec_done = '0') then
timer_5usec_count <= timer_5usec_count + 1;
end if;
end if;
 
if( timer_5usec_count = (TIMER_5USEC_VALUE_PP - 1)) then
timer_5usec_done <= '1';
else
timer_5usec_done <= '0';
end if;
if( timer_5usec_count = (TIMER_5USEC_VALUE_PP - 1)) then
timer_5usec_done <= '1';
else
timer_5usec_done <= '0';
end if;
end process;
 
--
-- Create the signals which indicate special scan codes received.
-- These are the "unlatched versions."
--
extend_release_decode : process( q, rx_shifting_done, extended, released )
begin
if (q(8 downto 1) = EXTEND_CODE) and (rx_shifting_done = '1') then
extended <= '1';
else
extended <= '0';
end if;
 
if (q(8 downto 1) = RELEASE_CODE) and (rx_shifting_done = '1') then
released <= '1';
else
released <= '0';
end if;
 
if (rx_shifting_done = '1') and (extended = '0') and (released = '0') then
rx_output_event <= '1';
else
rx_output_event <= '0';
end if;
 
end process;
 
--
 
-- Store the special scan code status bits
-- Not the final output, but an intermediate storage place,
-- until the entire set of output data can be assembled.
--
special_scan : process(clk, reset, rx_output_event, rx_shifting_done, extended, released )
begin
if clk'event and clk='0' then
if (reset = '1') or (rx_output_event = '1') then
hold_extended <= '0';
hold_released <= '0';
else
if (rx_shifting_done = '1') and (extended = '1') then
hold_extended <= '1';
end if;
if (rx_shifting_done = '1') and (released = '1') then
hold_released <= '1';
end if;
end if;
end if;
 
if clk'event and clk='0' then
if (reset = '1') or (rx_output_event = '1') then
hold_extended <= '0';
hold_released <= '0';
else
if (rx_shifting_done = '1') and (extended = '1') then
hold_extended <= '1';
end if;
if (rx_shifting_done = '1') and (released = '1') then
hold_released <= '1';
end if;
end if;
end if;
end process;
 
--
-- convert scan code to ascii code
--
scan_to_ascii : process( shift_key_on, caps_key_on, q )
begin
shift_key_plus_code <= shift_key_on & caps_key_on & q(7 downto 1);
end process;
 
--
 
-- These bits contain the status of the two shift keys
--
left_shift_proc : process(clk, reset, q, rx_shifting_done, hold_released )
begin
if clk'event and clk = '0' then
if (reset = '1') then
left_shift_key <= '0';
elsif (q(8 downto 1) = LEFT_SHIFT) and (rx_shifting_done = '1') then
left_shift_key <= not hold_released;
end if;
end if;
if clk'event and clk = '0' then
if (reset = '1') then
left_shift_key <= '0';
elsif (q(8 downto 1) = LEFT_SHIFT) and
(rx_shifting_done = '1') and
(hold_released = '0') then
left_shift_key <= '1';
elsif (q(8 downto 1) = LEFT_SHIFT) and
(rx_shifting_done = '1') and
(hold_released = '1') then
left_shift_key <= '0';
end if;
end if;
end process;
 
right_shift_proc : process(clk, reset, q, rx_shifting_done, hold_released )
begin
if clk'event and clk = '0' then
if (reset = '1') then
right_shift_key <= '0';
elsif (q(8 downto 1) = RIGHT_SHIFT) and (rx_shifting_done = '1') then
right_shift_key <= not hold_released;
end if;
end if;
if clk'event and clk = '0' then
if (reset = '1') then
right_shift_key <= '0';
elsif (q(8 downto 1) = RIGHT_SHIFT) and
(rx_shifting_done = '1') and
(hold_released = '0') then
right_shift_key <= '1';
elsif (q(8 downto 1) = RIGHT_SHIFT) and
(rx_shifting_done = '1') and
(hold_released = '1') then
right_shift_key <= '0';
end if;
end if;
end process;
 
shift_proc : process( left_shift_key, right_shift_key, shift_key_on, caps_key_on, q )
begin
shift_key_on <= left_shift_key or right_shift_key;
rx_shift_on <= shift_key_on;
end process;
 
shift_key_on <= left_shift_key or right_shift_key;
rx_shift_on <= shift_key_on;
 
--
-- Control keys
--
ctrl_proc : process(clk, reset, q, rx_shifting_done, hold_released )
begin
if clk'event and clk = '0' then
if (reset = '1') then
ctrl_key_on <= '0';
elsif (q(8 downto 1) = CTRL_CODE) and (rx_shifting_done = '1') then
ctrl_key_on <= not hold_released;
end if;
end if;
if clk'event and clk = '0' then
if (reset = '1') then
ctrl_key_on <= '0';
elsif (q(8 downto 1) = CTRL_CODE) and
(rx_shifting_done = '1') and
(hold_released = '0') then
ctrl_key_on <= '1';
elsif (q(8 downto 1) = CTRL_CODE) and
(rx_shifting_done = '1') and
(hold_released = '1') then
ctrl_key_on <= '0';
end if;
end if;
end process;
 
--
734,79 → 708,85
--
caps_proc : process(clk, reset, q, rx_shifting_done, hold_released, caps_key_on )
begin
if clk'event and clk = '0' then
if (reset = '1') then
caps_key_on <= '0';
elsif (q(8 downto 1) = CAPS_CODE) and (rx_shifting_done = '1') then
if (hold_released = '0') then
caps_key_on <= not caps_key_on;
end if;
end if;
end if;
if clk'event and clk = '0' then
if (reset = '1') then
caps_key_on <= '0';
elsif (q(8 downto 1) = CAPS_CODE) and
(rx_shifting_done = '1') and
(hold_released = '0') then
caps_key_on <= not caps_key_on;
end if;
end if;
end process;
 
--
 
-- Output the special scan code flags, the scan code and the ascii
--
special_scan_proc : process(clk, reset, rx_output_strobe,
hold_extended, hold_released,
ascii, ctrl_key_on )
special_scan_proc : process(clk, reset,
hold_extended, hold_released,
q, ascii, ctrl_key_on )
begin
if clk'event and clk = '0' then
if (reset = '1') then
rx_extended <= '0';
rx_released <= '0';
rx_data <= (others=>'0');
elsif (rx_output_strobe = '1') then
rx_extended <= hold_extended;
rx_released <= hold_released;
if ctrl_key_on = '1' then
rx_data <= ascii and x"1f";
else
rx_data <= ascii;
end if;
end if;
end if;
if clk'event and clk = '0' then
if (reset = '1') then
rx_extended <= '0';
rx_released <= '0';
-- rx_scan_code <= "00000000";
rx_data <= "00000000";
elsif (rx_output_strobe = '1') then
rx_extended <= hold_extended;
rx_released <= hold_released;
-- rx_scan_code <= q(8 downto 1);
elsif ctrl_key_on = '1' then
rx_data <= ascii and x"1f";
else
rx_data <= ascii;
end if;
end if;
end process;
 
--
 
-- Store the final rx output data only when all extend and release codes
-- are received and the next (actual key) scan code is also ready.
-- (the presence of rx_extended or rx_released refers to the
-- the current latest scan code received, not the previously latched flags.)
--
 
rx_output_proc : process( clk, reset,
rx_shifting_done, rx_output_strobe,
extended, released,
hold_extended, hold_released,
q, ascii, rx_read )
begin
if clk'event and clk = '0' then
if reset = '1' then
rx_output_strobe <= '0';
elsif (rx_shifting_done = '1') and (rx_output_strobe = '0') and
(extended = '0') and (released = '0') and
(hold_released = '0' ) and
(ascii /= "00000000" ) then
-- ((TRAP_SHIFT_KEYS_PP = 0) or
-- ( (q(8 downto 1) /= RIGHT_SHIFT) and
-- (q(8 downto 1) /= LEFT_SHIFT) and
-- (q(8 downto 1) /= CTRL_CODE) ) )then
rx_output_strobe <= '1';
elsif rx_read = '1' then
rx_output_strobe <= '0';
end if;
end if;
rx_data_ready <= rx_output_strobe;
extended, released,
q, ascii, rx_read )
begin
if (rx_shifting_done = '1') and (extended = '0') and (released = '0') then
rx_output_event <= '1';
else
rx_output_event <= '0';
end if;
 
if clk'event and clk = '0' then
if reset = '1' then
rx_output_strobe <= '0';
elsif (rx_shifting_done = '1') and
(rx_output_strobe = '0') and
(extended = '0') and
(released = '0') and
(hold_released = '0' ) and
(ascii /= x"00" ) then
-- ((TRAP_SHIFT_KEYS_PP = 0) or
-- ( (q(8 downto 1) /= RIGHT_SHIFT) and
-- (q(8 downto 1) /= LEFT_SHIFT) and
-- (q(8 downto 1) /= CTRL_CODE) ) )then
rx_output_strobe <= '1';
elsif rx_read = '1' then
rx_output_strobe <= '0';
end if;
end if;
rx_data_ready <= rx_output_strobe;
end process;
 
--
-- This part translates the scan code into an ASCII value...
-- Only the ASCII codes which I considered important have been included.
-- if you want more, just add the appropriate case statement lines...
-- (You will need to know the keyboard scan codes you wish to assign.)
-- The entries are listed in ascending order of ASCII value.
--
 
 
-- This part translates the scan code into an ASCII value...
-- Only the ASCII codes which I considered important have been included.
-- if you want more, just add the appropriate case statement lines...
-- (You will need to know the keyboard scan codes you wish to assign.)
-- The entries are listed in ascending order of ASCII value.
shift_key_plus_code <= shift_key_on & caps_key_on & q(7 downto 1);
 
--shift_map : process( shift_key_plus_code )
--begin
-- case shift_key_plus_code is
916,9 → 896,8
-- when x"10e" => ascii <= x"7e"; -- ~
-- when x"071" => ascii <= x"7f"; -- (Delete OR DEL on numeric keypad)
-- when x"171" => ascii <= x"7f"; -- (Delete OR DEL on numeric keypad)
-- when others => ascii <= x"00"; -- 0xff used for unlisted characters.
-- when others => ascii <= x"ff"; -- 0xff used for unlisted characters.
-- end case;
--end process;
 
 
end rtl;
/rtl/VHDL/vdu8.vhd
15,7 → 15,9
-- Supports 2 x 8 chunky graphics character mode.
-- Uses Generic arguments for setting the video synchronization timing.
--
-- Dependencies : ieee.std_logic_1164
-- Dependencies : ieee.Std_Logic_1164
-- ieee.std_logic_unsigned
-- ieee.std_logic_arith
-- ieee.numeric_std
--
-- Uses : ram_2k (ram2k_b16.vhd) 2KByte Character & Attribute buffer
131,8 → 133,8
Library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.numeric_std.all;
--Library unisim;
-- use unisim.vcomponents.all;
Library unisim;
use unisim.vcomponents.all;
 
Entity vdu8 is
generic(
/rtl/VHDL/pia6821.vhd
61,8 → 61,8
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
--library unisim;
-- use unisim.vcomponents.all;
library unisim;
use unisim.vcomponents.all;
 
entity pia6821 is
port (
/rtl/VHDL/keyboard.vhd
14,6 → 14,7
-- ieee.std_logic_arith
-- ieee.std_logic_unsigned
-- ieee.numeric_std
-- unisim.vcomponents
--
-- Uses : ps2_keyboard_interface
--
87,8 → 88,8
use ieee.std_logic_arith.all;
use ieee.std_logic_unsigned.all;
use ieee.numeric_std.all;
--library unisim;
-- use unisim.vcomponents.all;
library unisim;
use unisim.vcomponents.all;
 
entity keyboard is
generic (
248,7 → 249,7
--
keyboard_status : process( kbd_data_ready, kbd_data_empty,
kbd_extended, kbd_released, kbd_shift_on, kbd_error,
kbd_control, kbd_status )
kbd_control)
begin
kbd_status(0) <= kbd_data_ready;
kbd_status(1) <= kbd_data_empty;
/rtl/VHDL/pia_timer.vhd
122,7 → 122,7
signal ca1_rise : std_logic;
signal ca1_fall : std_logic;
signal ca1_edge : std_logic;
signal irqa1 : std_logic := '0';
signal irqa1 : std_logic;
 
signal ca2 : std_logic;
signal ca2_del : std_logic;
129,7 → 129,7
signal ca2_rise : std_logic;
signal ca2_fall : std_logic;
signal ca2_edge : std_logic;
signal irqa2 : std_logic := '0';
signal irqa2 : std_logic;
signal ca2_out : std_logic;
 
signal cb1 : std_logic;
137,7 → 137,7
signal cb1_rise : std_logic;
signal cb1_fall : std_logic;
signal cb1_edge : std_logic;
signal irqb1 : std_logic := '0';
signal irqb1 : std_logic;
 
signal cb2 : std_logic;
signal cb2_del : std_logic;
144,7 → 144,7
signal cb2_rise : std_logic;
signal cb2_fall : std_logic;
signal cb2_edge : std_logic;
signal irqb2 : std_logic := '0';
signal irqb2 : std_logic;
signal cb2_out : std_logic;
 
-- 74193 down counter
166,57 → 166,55
pa, pb )
variable count : integer;
begin
data_out <= "00000000";
porta_read <= '0';
portb_read <= '0';
 
case addr is
when "00" =>
for count in 0 to 7 loop
if porta_ctrl(2) = '0' then
data_out(count) <= porta_ddr(count);
porta_read <= '0';
else
if porta_ddr(count) = '1' then
data_out(count) <= porta_data(count);
case addr is
when "00" =>
for count in 0 to 7 loop
if porta_ctrl(2) = '0' then
data_out(count) <= porta_ddr(count);
porta_read <= '0';
else
data_out(count) <= pa(count);
if porta_ddr(count) = '1' then
data_out(count) <= porta_data(count);
else
data_out(count) <= pa(count);
end if;
porta_read <= cs;
end if;
porta_read <= cs;
end if;
end loop;
portb_read <= '0';
end loop;
portb_read <= '0';
 
when "01" =>
data_out <= irqa1 & irqa2 & porta_ctrl;
porta_read <= '0';
portb_read <= '0';
when "01" =>
data_out <= irqa1 & irqa2 & porta_ctrl;
porta_read <= '0';
portb_read <= '0';
 
when "10" =>
for count in 0 to 7 loop
if portb_ctrl(2) = '0' then
data_out(count) <= portb_ddr(count);
portb_read <= '0';
else
if portb_ddr(count) = '1' then
when "10" =>
for count in 0 to 7 loop
if portb_ctrl(2) = '0' then
data_out(count) <= portb_ddr(count);
portb_read <= '0';
else
if portb_ddr(count) = '1' then
data_out(count) <= portb_data(count);
else
else
data_out(count) <= pb(count);
end if;
portb_read <= cs;
end if;
end loop;
porta_read <= '0';
end if;
portb_read <= cs;
end if;
end loop;
porta_read <= '0';
 
when "11" =>
data_out <= irqb1 & irqb2 & portb_ctrl;
porta_read <= '0';
portb_read <= '0';
when "11" =>
data_out <= irqb1 & irqb2 & portb_ctrl;
porta_read <= '0';
portb_read <= '0';
 
when others =>
null;
end case;
when others =>
data_out <= "00000000";
porta_read <= '0';
portb_read <= '0';
 
end case;
end process;
 
---------------------------------
/rtl/VHDL/ioport.vhd
55,8 → 55,8
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
--library unisim;
-- use unisim.vcomponents.all;
library unisim;
use unisim.vcomponents.all;
 
entity ioport is
port (
/rtl/VHDL/vdu8_new.vhd
1,141 → 1,27
--===========================================================================--
-- --
-- vdu8_new.vhd - Synthesizable Colour Video Display Unit for System09 --
-- --
--===========================================================================--
-- ---------------------------------------------------
-- Video Display terminal
-- ---------------------------------------------------
-- John Kent
-- 3th September 2004
-- Assumes a pixel clock input of 25 MHz
--
-- File name : vdu8_new.vhd
-- Display Format is:
-- 80 characters across by 25 characters down.
-- 8 horizontal pixels / character
-- 16 vertical scan lines / character (2 scan lines/row)
--
-- Purpose : Implements a text based Colour Video Display Unit for System09
-- Supports 2KByte Text buffer and 2KByte Attribute memory
-- Displays 80 characters across by 25 character rows
-- Characters are 8 pixels across x 16 lines down.
-- Character attribute bita for foreground and backgrond colour
-- 1 bit for each Blue Green and Red signal
-- Supports 2 x 8 chunky graphics character mode.
-- Uses Generic arguments for setting the video synchronization timing.
-- (I'm not sure what is "new" about this version.)
--
-- Dependencies : ieee.Std_Logic_1164
-- ieee.std_logic_arith
-- ieee.std_logic_unsigned
-- ieee.numeric_std
-- unisim.vcomponents
-- Modified by Bert Cuzeau for compliance and code cleanliness
-- The effort is not over.
-- There are still signal initialized, which is BAD.\
--
-- Uses : ram_2k (ram2k_b16.vhd) 2KByte Character & Attribute buffer
-- char_rom (char_rom2k_b16.vhd) 2KByte Character Generator ROM
--
-- Author : John E. Kent
--
-- Email : dilbert57@opencores.org
--
-- Web : http://opencores.org/project,system09
--
-- Description : Display Timing:
-- 800 pixels / line
-- 446 lines / frame
-- None interlaced
-- 25MHz pixel clock implies
-- 31.25 KHz line rate
-- 70.067 Hz frame rate
-- Timing settable by generics.
--
-- Display Size:
-- 80 characters across
-- 25 characters down.
--
-- Character Size:
-- 8 horizontal pixels across
-- 16 vertical scan lines down (2 scan lines/row)
--
-- Registers:
-- Base + 0 ASCII character register
-- Writing to this register writes an 8 bit byte
-- into the text buffer at the specified cursor position
-- Text Mode: ASCII Character (0 to 127)
-- Chunky Graphics Mode: B0 B1 (0 to 255)
-- B2 B3
-- B4 B5
-- B6 B7
-- Base + 1 Attibute bit (0 to 255)
-- Writing to the register writes an 8 bit byte
-- into the attribute buffer at the specified cursor position
-- B7 - 0 => Text Mode / 1 => Chunky Graphics Mode
-- B6 - 1 => Character Background Blue
-- B5 - 1 => Character Background Green
-- B4 - 1 => Character Background Red
-- B3 - 1 => Character Background & Foreground Alternates
-- B2 - 1 => Character Foreground Blue
-- B1 - 1 => Character Foreground Green
-- B0 - 1 => Character Foreground Red
-- Base + 2 Cursor Horizontal Position (0 to 79)
-- Base + 3 Cusror Vertical Position (0 to 24)
-- Base + 4 Vertical Scroll Offset (0 to 24)
-- Scrolls the display up by the specified number of character rows
--
--
-- Video Timing :
--
-- Horizontal 800 Pixels/ 25MHz Pixel Clock = 32usec Line period = 31.25 KHz Line Frequency
-- /--------------------------\_____________/---------------\______________/
-- 640 Pixels Display 16 Pixel FP 96 Pixel HS 48 Pixel BP
--
-- VGA_CLK_FREQ : integer := 25000000; -- HZ
-- VGA_HOR_FRONT_PORCH : integer := 16; -- PIXELS 0.64us (0.94us)
-- VGA_HOR_SYNC : integer := 96; -- PIXELS 3.84us (3.77us)
-- VGA_HOR_BACK_PORCH : integer := 48; -- PIXELS 1.92us (1.89us)
-- VGA_PIX_PER_CHAR : integer := 8; -- PIXELS 0.32us
-- VGA_HOR_CHARS : integer := 80; -- CHARACTERS 25.6us
--
-- Vertical 446 Lines * 32 usec Line rate = 14.272ms Frame Period = 70.07Hz Frame frequency
-- /---------------------------\____________/---------------\______________/
-- 400 Line Display 10 Line FP 2 Line VS 34 Line BP
--
-- VGA_VER_FRONT_PORCH : integer := 10; -- LINES 0.320ms
-- VGA_VER_SYNC : integer := 2; -- LINES 0.064ms
-- VGA_VER_BACK_PORCH : integer := 34; -- LINES 1.088ms
-- VGA_LIN_PER_CHAR : integer := 16; -- LINES 0.512ms
-- VGA_VER_CHARS : integer := 25; -- CHARACTERS 12.8ms
--
-- 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 Author Date Changes
-- 7th Februaury 2007 - John Kent
-- Added generics for VGA Timing
--
-- 0.1 John Kent 2004-09-03 Initial release
--
-- 0.2 Bert Cuzeau 2007-01-16 Modified by for compliance and code cleanliness
-- The effort is not over.
-- There are still signal initialized, which is BAD.
--
-- 0.3 John Kent 2007-02-07 Added generics for VGA Timing
--
-- 0.4 John Kent 2010-06-16 Added GPL notice. Updated description
-- I'm not sure what is "new" about this version
--
 
Library IEEE;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
use ieee.std_logic_unsigned.all;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
use ieee.numeric_std.all;
library unisim;
use unisim.vcomponents.all;
142,17 → 28,18
 
Entity vdu8 is
generic(
VGA_CLK_FREQ : integer := 25000000; -- HZ
VGA_HOR_CHARS : integer := 80; -- CHARACTERS 25.6us
VGA_HOR_CHAR_PIXELS : integer := 8; -- PIXELS 0.32us
VGA_HOR_FRONT_PORCH : integer := 16; -- PIXELS 0.64us
VGA_HOR_SYNC : integer := 96; -- PIXELS 3.84us
VGA_HOR_BACK_PORCH : integer := 48; -- PIXELS 1.92us
VGA_VER_CHARS : integer := 25; -- CHARACTERS 12.8ms
VGA_VER_CHAR_LINES : integer := 16; -- LINES 0.512ms
VGA_VER_FRONT_PORCH : integer := 10; -- LINES 0.320ms
VGA_VER_SYNC : integer := 2; -- LINES 0.064ms
VGA_VER_BACK_PORCH : integer := 34 -- LINES 1.088ms
VDU_CLOCK_FREQUENCY : integer := 25000000; -- HZ
VGA_CLOCK_FREQUENCY : integer := 25000000; -- HZ
VGA_HOR_CHARS : integer := 80; -- CHARACTERS
VGA_VER_CHARS : integer := 25; -- CHARACTERS
VGA_PIXELS_PER_CHAR : integer := 8; -- PIXELS
VGA_LINES_PER_CHAR : integer := 16; -- LINES
VGA_HOR_BACK_PORCH : integer := 40; -- PIXELS
VGA_HOR_SYNC : integer := 96; -- PIXELS
VGA_HOR_FRONT_PORCH : integer := 24; -- PIXELS
VGA_VER_BACK_PORCH : integer := 13; -- LINES
VGA_VER_SYNC : integer := 2; -- LINES
VGA_VER_FRONT_PORCH : integer := 36 -- LINES
);
port(
-- control register interface
181,26 → 68,30
-- Displayed Characters per row
constant HOR_DISP_CHR : integer := VGA_HOR_CHARS;
-- Last horizontal pixel displayed
constant HOR_DISP_END : integer := HOR_DISP_CHR * VGA_HOR_CHAR_PIXELS - 1;
constant HOR_DISP_END : integer := HOR_DISP_CHR * VGA_PIXELS_PER_CHAR;
-- Start of horizontal synch pulse
constant HOR_SYNC_BEG : integer := HOR_DISP_END + VGA_HOR_FRONT_PORCH;
constant HOR_SYNC_BEG : integer := HOR_DISP_END + VGA_HOR_BACK_PORCH;
-- End of Horizontal Synch pulse
constant HOR_SYNC_END : integer := HOR_SYNC_BEG + VGA_HOR_SYNC;
-- Last pixel in scan line
constant HOR_SCAN_END : integer := HOR_SYNC_END + VGA_HOR_BACK_PORCH;
constant HOR_SCAN_END : integer := HOR_SYNC_END + VGA_HOR_FRONT_PORCH;
-- Total Characters across the screen
constant HOR_TOTAL_CHAR : integer := HOR_SCAN_END/VGA_PIXELS_PER_CHAR;
 
-- Displayed Characters per Column
constant VER_DISP_CHR : integer := VGA_VER_CHARS;
-- last row displayed
constant VER_DISP_END : integer := VER_DISP_CHR * VGA_VER_CHAR_LINES - 1;
constant VER_DISP_END : integer := VER_DISP_CHR * VGA_LINES_PER_CHAR;
-- start of vertical synch pulse
constant VER_SYNC_BEG : integer := VER_DISP_END + VGA_VER_FRONT_PORCH;
constant VER_SYNC_BEG : integer := VER_DISP_END + VGA_VER_BACK_PORCH;
-- end of vertical synch pulse
constant VER_SYNC_END : integer := VER_SYNC_BEG + VGA_VER_SYNC;
-- Last scan row in the frame
constant VER_SCAN_END : integer := VER_SYNC_END + VGA_VER_BACK_PORCH;
 
constant BLINK_PERIOD : integer := 500; -- Blink Rate in msec
constant VER_SCAN_END : integer := VER_SYNC_END + VGA_VER_FRONT_PORCH;
-- Total Characters down the screen
constant VER_TOTAL_CHAR : integer := VER_SCAN_END/VGA_LINES_PER_CHAR;
 
constant BLINK_PERIOD : integer := 500; -- Blink Rate in msec
constant BLINK_RATE : integer := BLINK_PERIOD * (VGA_CLOCK_FREQUENCY/1000);
 
signal vga_rst : std_logic;
211,11 → 102,11
signal video_on_v : std_logic := '0';
signal video_on_h : std_logic := '0';
signal h_count : natural range 0 to HOR_SCAN_END := 0;
signal v_count : natural range 0 to VER_SCAN_END := 0;
signal v_count : natural range 0 to VER_SCAN_END := 0;
signal p_count : natural range 0 to VGA_PIXELS_PER_CHAR-1 := 0;
signal l_count : std_logic_vector(3 downto 0) := "0000";
signal c_count : std_logic_vector(6 downto 0) := "0000000";
signal r_count : std_logic_vector(5 downto 0) := "000000";
signal r_count : std_logic_vector(5 downto 0) := "000000";
signal blink_count : natural range 0 to BLINK_RATE := 0;
--
-- Character generator ROM
262,7 → 153,7
signal vga_addr : std_logic_vector(10 downto 0) := (others=>'0'); -- 2K byte character buffer
signal vga_data_out : std_logic_vector(7 downto 0);
signal attr_data_out : std_logic_vector(7 downto 0);
 
 
--
-- Character write handshake signals
--
439,13 → 330,13
vga0_rw <= '1';
col_addr <= c_count;
row_addr <= r_count + ("0" & reg_voffset(4 downto 0));
end case;
end case;
 
--
-- on vga_clk + 1 round off row address
--
vga1_cs <= vga0_cs;
vga1_rw <= vga0_rw;
vga1_rw <= vga0_rw;
if row_addr < VER_DISP_CHR then
row1_addr <= row_addr;
else
485,9 → 376,9
vga_blue_o <= '0';
-- Put all video signals through DFFs to elminate any delays that cause a blurry image
 
elsif falling_edge(vga_clk) then
elsif falling_edge(vga_clk) then
--
-- p_count = 0 load pixel shift register
-- p_count = 0 load pixel shift register
--
if p_count = 0 then
if (req_write = '1') and (ack_write = '0') then
496,31 → 387,31
ack_write <= '0';
else
ack_write <= ack_write;
end if;
 
--
-- Pipeline video enable
end if;
 
--
-- Pipeline video enable
--
video_on2 <= video_on1;
video_on <= video_on2;
--
-- Blink Cursor
--
video_on <= video_on2;
--
-- Blink Cursor
--
if blink_count > (BLINK_RATE/2) then
cursor_on <= cursor_on1 or attr_data_out(3);
else
cursor_on <= '0';
end if;
--
-- Set forground and background colours
cursor_on <= cursor_on1 or attr_data_out(3);
else
cursor_on <= '0';
end if;
--
-- Set forground and background colours
--
vga_fg_colour <= attr_data_out(2 downto 0);
vga_bg_colour <= attr_data_out(6 downto 4);
--
-- Attribute bit 7
vga_bg_colour <= attr_data_out(6 downto 4);
--
-- Attribute bit 7
-- 0 => text
-- 1 => chunky graphics
--
-- 1 => chunky graphics
--
if attr_data_out(7) = '0' then
vga_shift <= char_data_out;
else
539,10 → 430,10
vga_shift(3 downto 0) <= vga_data_out(7) & vga_data_out(7) & vga_data_out(7) & vga_data_out(7);
end case;
end if;
else
--
-- p_count /= 0 shift out pixel shift register
else
--
-- p_count /= 0 shift out pixel shift register
--
vga_shift <= vga_shift(6 downto 0) & '0';
end if;
 
569,13 → 460,13
-- Generate Horizontal and Vertical Timing Signals for Video Signal
--
vga_sync : process(vga_clk, vga_rst)
begin
if vga_rst = '1' then
h_count <= 0;
c_count <= "0000000";
begin
if vga_rst = '1' then
h_count <= 0;
c_count <= "0000000";
p_count <= 0;
v_count <= 0;
l_count <= "0000";
v_count <= 0;
l_count <= "0000";
r_count <= "000000";
horiz_sync <= '0';
vert_sync <= '0';
583,7 → 474,7
video_on_v <= '0';
cursor_on_h <= '0';
cursor_on_v <= '0';
blink_count <= BLINK_RATE;
blink_count <= BLINK_RATE;
elsif falling_edge(vga_clk) then
--
-- H_count counts pixels (640 + extra time for sync signals)
592,17 → 483,17
-- H_count 0 640 659 755 799
--
if h_count = HOR_SCAN_END then
h_count <= 0;
c_count <= "0000000";
h_count <= 0;
c_count <= "0000000";
p_count <= 0;
else
h_count <= h_count + 1;
p_count <= p_count + 1;
if p_count = VGA_PIXELS_PER_CHAR-1 then
p_count <= 0;
c_count <= c_count + "0000001";
h_count <= h_count + 1;
p_count <= p_count + 1;
if p_count = VGA_PIXELS_PER_CHAR-1 then
p_count <= 0;
c_count <= c_count + "0000001";
end if;
end if;
end if;
 
--
-- V_count counts rows of pixels
613,17 → 504,17
-- V_count 0 400 413 414 444
--
if (v_count = VER_SCAN_END) and (h_count = HOR_SCAN_END) then
v_count <= 0;
l_count <= "0000";
v_count <= 0;
l_count <= "0000";
r_count <= "000000";
elsif h_count = HOR_SYNC_END then
v_count <= v_count + 1;
l_count <= l_count + "0001";
if l_count = VGA_LINES_PER_CHAR-1 then
l_count <= "0000";
r_count <= r_count + "000001";
l_count <= l_count + "0001";
if l_count = VGA_LINES_PER_CHAR-1 then
l_count <= "0000";
r_count <= r_count + "000001";
end if;
end if;
end if;
 
--
-- Generate Horizontal Sync Signal
633,7 → 524,7
elsif h_count = HOR_SYNC_END then
horiz_sync <= '0';
end if;
 
 
--
-- Generate Vertical Sync Signal
--
641,10 → 532,10
vert_sync <= '1';
elsif v_count = VER_SYNC_END then
vert_sync <= '0';
end if;
end if;
 
--
-- Horizontal display enable
-- Horizontal display enable
--
if h_count = 0 then
video_on_h <= '1';
653,7 → 544,7
end if;
 
--
-- Verical display enable
-- Verical display enable
--
if v_count = 0 then
video_on_v <= '1';
661,18 → 552,18
video_on_v <= '0';
end if;
 
--
-- Horizontal cursor on
--
-- Horizontal cursor on
--
if c_count = reg_hcursor(6 downto 0) then
cursor_on_h <= '1';
else
cursor_on_h <= '0';
end if;
 
--
-- Vertical cursor on
 
--
-- Vertical cursor on
--
if r_count = ("0" & reg_vcursor(4 downto 0)) then
cursor_on_v <= '1';
else
679,30 → 570,30
cursor_on_v <= '0';
end if;
 
-- cursor_on is only active when on selected character
if blink_count = 0 then
blink_count <= BLINK_RATE;
-- cursor_on is only active when on selected character
if blink_count = 0 then
blink_count <= BLINK_RATE;
else
blink_count <= blink_count - 1;
blink_count <= blink_count - 1;
end if;
end if;
 
end process;
--
-- VGA reset = VDU reset
-- VGA = timing section
-- VDU = CPU registers
--
end process;
--
-- VGA reset = VDU reset
-- VGA = timing section
-- VDU = CPU registers
--
vga_rst <= vdu_rst;
--
-- VGA Sync for 640 pixels x 400 lines
-- negative horizonal sync
-- positive verical sync
--
--
-- VGA Sync for 640 pixels x 400 lines
-- negative horizonal sync
-- positive verical sync
--
vga_hsync_o <= not horiz_sync;
vga_vsync_o <= vert_sync;
--
-- video_on is high only when RGB data is displayed
-- video_on is high only when RGB data is displayed
--
video_on1 <= video_on_H and video_on_V;
cursor_on1 <= cursor_on_h and cursor_on_v;
/rtl/VHDL/clock_dll.vhd
1,125 → 1,103
--===========================================================================--
-- --
-- clock_dll.vhd - Synthesible System Clock Divider for Xilinx Spartan 3 --
-- --
--===========================================================================--
--===========================================================================----
--
-- File name : clock_dll.vhd
-- S Y N T H E Z I A B L E Clock_dll for System09 - SOC.
--
-- Purpose : Implements a a system clock divider for System09.
-- For Xilinx Spartan 3 and 3E FPGA boards
-- Assumes a 12.5 MHz system clock input
-- Generates a x1 (12.5 MHz) CPU clock
-- Generates a x2 (25.0 MHz) VGA clock
-- Generates a x4 (50.0 MHz) MEM clock
--
-- Dependencies : ieee.std_logic_1164
--===========================================================================----
--
-- This core adheres to the GNU public license
-- No responsibility is taken for this design.
-- Use at own risk.
--
-- File name : Clock_dll.vhd
--
-- Purpose : Generates Clocks for System09
-- For BurchED B3-Spartan2+ and B5-X300
-- Assumes a 12.5 MHz system clock input
-- Generates a x1 (12.5 MHz) CPU clock
-- Generates a x2 (25.0 MHz) VGA clock
-- Generates a x4 (50.0 MHz) MEM clock
--
-- Dependencies : ieee.Std_Logic_1164
-- ieee.std_logic_unsigned
-- ieee.std_logic_arith
-- ieee.std_logic_unsigned
-- ieee.numeric_std
-- unisim.vcomponents
--
-- Author : John E. Kent
--
-- Email : dilbert57@opencores.org
--
-- Web : http://opencores.org/project,system09
--
-- clock_dll.vhd is a system clock divider for system09.
--
-- 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 --
-- --
--===========================================================================--
--
-- Revision Name Date Description
-- 0.1 John E. Kent 7th September 2008 Initial version
-- 1.0 John E. Kent 30th May 2010 Added GPL Header
--
-- ieee.numeric_std
--
--
-- Revision History :
--
-- Rev : 0.1
-- Date : 7th September 2008
-- Description : Initial version.
--
--
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
use ieee.std_logic_unsigned.all;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
use ieee.numeric_std.all;
library unisim;
use unisim.vcomponents.all;
 
entity clock_dll is
entity clock_dll is
port(
clk_in : in std_Logic; -- System Clock input
clk_cpu : out std_logic; -- CPU Clock Out (x1)
clk_vga : out std_logic; -- VGA Pixel Clock Out (x2)
clk_mem : out std_logic; -- Memory Clock Out (x4)
locked : out std_logic -- DLL in lock
);
end entity;
 
clk_cpu : out std_logic; -- CPU Clock Out (x1)
clk_vga : out std_logic; -- VGA Pixel Clock Out (x2)
clk_mem : out std_logic; -- Memory Clock Out (x4)
locked : out std_logic -- DLL in lock
);
end entity;
 
architecture RTL of clock_dll is
 
signal CPU_CLK0 : std_ulogic;
signal CPU_CLK90 : std_ulogic;
signal CPU_CLK180 : std_ulogic;
signal CPU_CLK270 : std_ulogic;
signal CPU_CLK2X : std_ulogic;
signal CPU_CLKDV : std_ulogic;
signal CPU_LOCKED : std_ulogic;
signal CPU_CLKFB : std_ulogic;
signal CPU_CLKIN : std_ulogic;
signal CPU_RESET : std_ulogic;
 
signal VGA_CLK0 : std_ulogic;
signal VGA_CLK90 : std_ulogic;
signal VGA_CLK180 : std_ulogic;
signal VGA_CLK270 : std_ulogic;
signal VGA_CLK2X : std_ulogic;
signal VGA_CLKDV : std_ulogic;
signal VGA_LOCKED : std_ulogic;
 
signal CPU_CLK0 : std_ulogic;
signal CPU_CLK90 : std_ulogic;
signal CPU_CLK180 : std_ulogic;
signal CPU_CLK270 : std_ulogic;
signal CPU_CLK2X : std_ulogic;
signal CPU_CLKDV : std_ulogic;
signal CPU_LOCKED : std_ulogic;
signal CPU_CLKFB : std_ulogic;
signal CPU_CLKIN : std_ulogic;
signal CPU_RESET : std_ulogic;
 
signal VGA_CLK0 : std_ulogic;
signal VGA_CLK90 : std_ulogic;
signal VGA_CLK180 : std_ulogic;
signal VGA_CLK270 : std_ulogic;
signal VGA_CLK2X : std_ulogic;
signal VGA_CLKDV : std_ulogic;
signal VGA_LOCKED : std_ulogic;
signal VGA_CLKFB : std_ulogic;
signal VGA_CLKIN : std_ulogic;
signal VGA_CLKIN : std_ulogic;
signal VGA_RESET : std_ulogic;
signal VGA_RESET_N : std_ulogic;
 
-- Component Declaration for CLKDLL should be placed
-- after architecture statement but before begin keyword
 
component CLKDLL
-- synthesis translate_off
generic (
CLKDV_DIVIDE : real := 2.0; -- (1.5, 2.0, 2.5, 3.0, 4.0, 5.0, 8.0, 16.0)
DUTY_CYCLE_CORRECTION : Boolean := TRUE; -- (TRUE, FALSE)
STARTUP_WAIT : boolean := FALSE -- (TRUE, FALSE)
);
-- synthesis translate_on
port (
CLK0 : out STD_ULOGIC;
CLK180 : out STD_ULOGIC;
CLK270 : out STD_ULOGIC;
CLK2X : out STD_ULOGIC;
CLK90 : out STD_ULOGIC;
CLKDV : out STD_ULOGIC;
LOCKED : out STD_ULOGIC;
CLKFB : in STD_ULOGIC;
CLKIN : in STD_ULOGIC;
RST : in STD_ULOGIC
);
end component;
 
 
-- Component Declaration for CLKDLL should be placed
-- after architecture statement but before begin keyword
 
component CLKDLL
-- synthesis translate_off
generic (
CLKDV_DIVIDE : real := 2.0; -- (1.5, 2.0, 2.5, 3.0, 4.0, 5.0, 8.0, 16.0)
DUTY_CYCLE_CORRECTION : Boolean := TRUE; -- (TRUE, FALSE)
STARTUP_WAIT : boolean := FALSE -- (TRUE, FALSE)
);
-- synthesis translate_on
port (
CLK0 : out STD_ULOGIC;
CLK180 : out STD_ULOGIC;
CLK270 : out STD_ULOGIC;
CLK2X : out STD_ULOGIC;
CLK90 : out STD_ULOGIC;
CLKDV : out STD_ULOGIC;
LOCKED : out STD_ULOGIC;
CLKFB : in STD_ULOGIC;
CLKIN : in STD_ULOGIC;
RST : in STD_ULOGIC
);
end component;
 
component IBUFG
port (
i: in std_logic;
133,122 → 111,122
o: out std_logic
);
end component;
 
component SRL16
port (
Q : out std_logic;
D : in std_logic;
CLK : in std_logic;
A0 : in std_logic;
A1 : in std_logic;
A2 : in std_logic;
A3 : in std_logic
);
end component;
 
--
-- Start instantiation
--
begin
 
 
component SRL16
port (
Q : out std_logic;
D : in std_logic;
CLK : in std_logic;
A0 : in std_logic;
A1 : in std_logic;
A2 : in std_logic;
A3 : in std_logic
);
end component;
 
--
-- Start instantiation
--
begin
 
--
-- 12.5MHz CPU clock input
--
cpu_clkin_buffer : IBUFG
cpu_clkin_buffer : IBUFG
port map(
i => clk_in,
o => CPU_CLKIN
);
 
 
--
-- 12.5MHz CPU clock input
--
cpu_clkout_buffer : BUFG
cpu_clkout_buffer : BUFG
port map(
i => CPU_CLKIN,
o => clk_cpu
);
 
 
--
-- 25 MHz VGA clock input
--
cpu_clkfb_buffer : BUFG
cpu_clkfb_buffer : BUFG
port map(
i => CPU_CLK2X,
o => CPU_CLKFB
);
 
CLKDLL_CPU : CLKDLL
-- synthesis translate_off
generic map (
CLKDV_DIVIDE => 2.0, -- (1.5,2,2.5,3,4,5,8,16)
DUTY_CYCLE_CORRECTION => TRUE, -- (TRUE, FALSE)
STARTUP_WAIT => FALSE -- (TRUE, FALSE)
);
-- synthesis translate_on
port map (
CLK0 => CPU_CLK0,
CLK90 => CPU_CLK90,
CLK180 => CPU_CLK180,
CLK270 => CPU_CLK270,
CLK2X => CPU_CLK2X,
CLKDV => CPU_CLKDV,
LOCKED => CPU_LOCKED,
CLKFB => CPU_CLKFB,
CLKIN => CPU_CLKIN,
RST => CPU_RESET
);
 
CLKDLL_CPU : CLKDLL
-- synthesis translate_off
generic map (
CLKDV_DIVIDE => 2.0, -- (1.5,2,2.5,3,4,5,8,16)
DUTY_CYCLE_CORRECTION => TRUE, -- (TRUE, FALSE)
STARTUP_WAIT => FALSE -- (TRUE, FALSE)
);
-- synthesis translate_on
port map (
CLK0 => CPU_CLK0,
CLK90 => CPU_CLK90,
CLK180 => CPU_CLK180,
CLK270 => CPU_CLK270,
CLK2X => CPU_CLK2X,
CLKDV => CPU_CLKDV,
LOCKED => CPU_LOCKED,
CLKFB => CPU_CLKFB,
CLKIN => CPU_CLKIN,
RST => CPU_RESET
);
--
-- 25 MHz VGA clock output
--
vga_clkfb_buffer : BUFG
vga_clkfb_buffer : BUFG
port map(
i => VGA_CLK2X,
o => VGA_CLKFB
);
 
CLKDLL_VGA : CLKDLL
-- synthesis translate_off
generic map (
CLKDV_DIVIDE => 2.0, -- (1.5,2,2.5,3,4,5,8,16)
DUTY_CYCLE_CORRECTION => TRUE, -- (TRUE, FALSE)
STARTUP_WAIT => FALSE -- (TRUE, FALSE)
);
-- synthesis translate_on
port map (
CLK0 => VGA_CLK0,
CLK90 => VGA_CLK90,
CLK180 => VGA_CLK180,
CLK270 => VGA_CLK270,
CLK2X => VGA_CLK2X,
CLKDV => VGA_CLKDV,
LOCKED => VGA_LOCKED,
CLKFB => VGA_CLKFB,
CLKIN => VGA_CLKIN,
RST => VGA_RESET
);
my_srl16 : SRL16 port map (
Q => VGA_RESET_N,
D => CPU_LOCKED,
CLK => CPU_CLKFB,
A0 => '1',
A1 => '1',
A2 => '1',
A3 => '1'
);
 
clock_dll_assign : process( VGA_RESET_N, VGA_LOCKED,
clk_in, CPU_CLKFB, VGA_CLKFB )
begin
VGA_RESET <= not VGA_RESET_N;
VGA_CLKIN <= CPU_CLKFB;
CPU_RESET <= '0';
clk_vga <= CPU_CLKFB;
clk_mem <= VGA_CLKFB;
locked <= VGA_LOCKED;
end process;
 
end architecture;
 
CLKDLL_VGA : CLKDLL
-- synthesis translate_off
generic map (
CLKDV_DIVIDE => 2.0, -- (1.5,2,2.5,3,4,5,8,16)
DUTY_CYCLE_CORRECTION => TRUE, -- (TRUE, FALSE)
STARTUP_WAIT => FALSE -- (TRUE, FALSE)
);
-- synthesis translate_on
port map (
CLK0 => VGA_CLK0,
CLK90 => VGA_CLK90,
CLK180 => VGA_CLK180,
CLK270 => VGA_CLK270,
CLK2X => VGA_CLK2X,
CLKDV => VGA_CLKDV,
LOCKED => VGA_LOCKED,
CLKFB => VGA_CLKFB,
CLKIN => VGA_CLKIN,
RST => VGA_RESET
);
my_srl16 : SRL16 port map (
Q => VGA_RESET_N,
D => CPU_LOCKED,
CLK => CPU_CLKFB,
A0 => '1',
A1 => '1',
A2 => '1',
A3 => '1'
);
 
clock_dll_assign : process( VGA_RESET_N, VGA_LOCKED,
clk_in, CPU_CLKFB, VGA_CLKFB )
begin
VGA_RESET <= not VGA_RESET_N;
VGA_CLKIN <= CPU_CLKFB;
CPU_RESET <= '0';
clk_vga <= CPU_CLKFB;
clk_mem <= VGA_CLKFB;
locked <= VGA_LOCKED;
end process;
 
end architecture;
/rtl/VHDL/clock_div.vhd
1,65 → 1,42
--===========================================================================
--===========================================================================----
--
-- clock_div.vhd - Clock divider for System09
-- S Y N T H E Z I A B L E Clock_dll for System09 - SOC.
--
--===========================================================================
--
-- File name : clock_div.vhd
--
-- Entity name : clock_div
--===========================================================================----
--
-- Purpose : Generates Clocks for System09
-- For BurchED B3-Spartan2+ and B5-X300
-- Divides the input clock which is normally 50MHz
-- Generates a 1/1 (50.0 MHz) SYS clock
-- Generates a 1/2 (25.0 MHz) VGA clock
-- Generates a 1/4 (12.5 MHz) CPU clock
-- This core adheres to the GNU public license
-- No responsibility is taken for this design.
-- Use at own risk.
--
-- Dependencies : ieee.Std_Logic_1164
-- ieee.std_logic_unsigned
-- ieee.std_logic_arith
-- ieee.numeric_std
-- File name : Clock_dll.vhd
--
-- Uses : IBUFG
-- BUFG
-- Purpose : Generates Clocks for System09
-- For BurchED B3-Spartan2+ and B5-X300
-- Assumes a 12.5 MHz system clock input
-- Generates a x1 (12.5 MHz) CPU clock
-- Generates a x2 (25.0 MHz) VGA clock
-- Generates a x4 (50.0 MHz) MEM clock
--
-- Author : John E. Kent
-- dilbert57@opencores.org
-- Dependencies : ieee.Std_Logic_1164
-- ieee.std_logic_unsigned
-- ieee.std_logic_arith
-- ieee.numeric_std
--
-- 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:
--
--===========================================================================
-- Revision History :
--
-- Rev: Date: Author: Description:
--
-- 0.1 2008-09-07 John Kent Initial version
-- 0.2 2010-09-14 John Kent Updated header
-- Rev : 0.1
-- Date : 7th September 2008
-- Description : Initial version.
--
--
--
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 unisim;
-- use unisim.vcomponents.all;
library unisim;
use unisim.vcomponents.all;
 
entity clock_div is
port(
72,8 → 49,16
 
architecture RTL of clock_div is
 
signal div_clk : std_logic;
signal div_count : std_logic_vector(1 downto 0);
 
 
component IBUFG
port (
i: in std_logic;
o: out std_logic
);
end component;
 
component BUFG
port (
i: in std_logic;
81,6 → 66,7
);
end component;
 
 
--
-- Start instantiation
--
87,12 → 73,12
begin
 
--
-- 50 MHz SYS clock output
-- 50.0MHz system clock
--
sys_clk_buffer : BUFG
sys_clk_buffer : IBUFG
port map(
i => clk_in,
o => sys_clk
o => div_clk
);
 
--
116,11 → 102,12
--
-- Clock divider
--
clock_div : process( clk_in )
clock_div : process( div_clk )
begin
if rising_edge( clk_in ) then
if rising_edge( div_clk) then
div_count <= div_count + "01";
end if;
sys_clk <= div_clk;
end process;
 
end architecture;
/rtl/VHDL/vdu8_bert.vhd
1,133 → 1,19
--===========================================================================--
-- --
-- vdu8_bert.vhd - Synthesizable Colour Video Display Unit for System09 --
-- --
--===========================================================================--
-- ---------------------------------------------------
-- Video Display terminal
-- ---------------------------------------------------
-- John Kent
-- 3th September 2004
-- Assumes a pixel clock input of 50 MHz
-- Generates a 12.5MHz CPU Clock output
--
-- File name : vdu8_bert.vhd
-- Display Format is:
-- 80 characters across by 25 characters down.
-- 8 horizontal pixels / character
-- 16 vertical scan lines / character (2 scan lines/row)
--
-- Purpose : Implements a text based Colour Video Display Unit for System09
-- Supports 2KByte Text buffer and 2KByte Attribute memory
-- Displays 80 characters across by 25 character rows
-- Characters are 8 pixels across x 16 lines down.
-- Character attribute bita for foreground and backgrond colour
-- 1 bit for each Blue Green and Red signal
-- Supports 2 x 8 chunky graphics character mode.
-- Assumes a pixel clock input of 50 MHz
-- Generates a 12.5MHz CPU Clock output for old Spartan 2 boards.
-- Partially cleaned up by Bertrand Cuzeau
--
-- Dependencies : ieee.Std_Logic_1164
-- ieee.std_logic_unsigned
-- ieee.std_logic_arith
-- ieee.numeric_std
--
-- Uses : ram_2k (ram2k_b16.vhd) 2KByte Character & Attribute buffer
-- char_rom (char_rom2k_b16.vhd) 2KByte Character Generator ROM
--
-- Author : John E. Kent
--
-- Email : dilbert57@opencores.org
--
-- Web : http://opencores.org/project,system09
--
-- Description : Display Timing:
-- 800 pixels / line
-- 446 lines / frame
-- None interlaced
-- 25MHz pixel clock implies
-- 31.25 KHz line rate
-- 70.067 Hz frame rate
-- Timing settable by generics.
--
-- Display Size:
-- 80 characters across
-- 25 characters down.
--
-- Character Size:
-- 8 horizontal pixels across
-- 16 vertical scan lines down (2 scan lines/row)
--
-- Registers:
-- Base + 0 ASCII character register
-- Writing to this register writes an 8 bit byte
-- into the text buffer at the specified cursor position
-- Text Mode: ASCII Character (0 to 127)
-- Chunky Graphics Mode: B0 B1 (0 to 255)
-- B2 B3
-- B4 B5
-- B6 B7
-- Base + 1 Attibute bit (0 to 255)
-- Writing to the register writes an 8 bit byte
-- into the attribute buffer at the specified cursor position
-- B7 - 0 => Text Mode / 1 => Chunky Graphics Mode
-- B6 - 1 => Character Background Blue
-- B5 - 1 => Character Background Green
-- B4 - 1 => Character Background Red
-- B3 - 1 => Character Background & Foreground Alternates
-- B2 - 1 => Character Foreground Blue
-- B1 - 1 => Character Foreground Green
-- B0 - 1 => Character Foreground Red
-- Base + 2 Cursor Horizontal Position (0 to 79)
-- Base + 3 Cusror Vertical Position (0 to 24)
-- Base + 4 Vertical Scroll Offset (0 to 24)
-- Scrolls the display up by the specified number of character rows
--
-- Video Timing :
--
-- Horizontal 800 Pixels/ 25MHz Pixel Clock = 32usec Line period = 31.25 KHz Line Frequency
-- /--------------------------\_____________/---------------\______________/
-- 640 Pixels Display 16 Pixel FP 96 Pixel HS 48 Pixel BP
--
-- VGA_CLK_FREQ : integer := 25000000; -- HZ
-- VGA_HOR_FRONT_PORCH : integer := 16; -- PIXELS 0.64us (0.94us)
-- VGA_HOR_SYNC : integer := 96; -- PIXELS 3.84us (3.77us)
-- VGA_HOR_BACK_PORCH : integer := 48; -- PIXELS 1.92us (1.89us)
-- VGA_PIX_PER_CHAR : integer := 8; -- PIXELS 0.32us
-- VGA_HOR_CHARS : integer := 80; -- CHARACTERS 25.6us
--
-- Vertical 446 Lines * 32 usec Line rate = 14.272ms Frame Period = 70.07Hz Frame frequency
-- /---------------------------\____________/---------------\______________/
-- 400 Line Display 10 Line FP 2 Line VS 34 Line BP
--
-- VGA_VER_FRONT_PORCH : integer := 10; -- LINES 0.320ms
-- VGA_VER_SYNC : integer := 2; -- LINES 0.064ms
-- VGA_VER_BACK_PORCH : integer := 34; -- LINES 1.088ms
-- VGA_LIN_PER_CHAR : integer := 16; -- LINES 0.512ms
-- VGA_VER_CHARS : integer := 25; -- CHARACTERS 12.8ms
--
--
-- 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 Author Date Changes
--
-- 0.1 John Kent 2004-09-03 Initial release
--
-- 0.2 Bert Cuzeau 2007-01-16 Modified by for compliance and code cleanliness
-- The effort is not over.
-- There are still signal initialized, which is BAD.
--
-- 0.3 John Kent 2010-06-16 Added GPL notice. Updated description
--
-- Modified by Bert Cuzeau for compliance and code cleanliness
-- The effort is not over.
-- There are still signal initialized, which is BAD.
 
Library IEEE;
use IEEE.std_logic_1164.all;
134,19 → 20,6
use IEEE.numeric_std.all;
 
Entity vdu8 is
generic(
VGA_CLK_FREQ : integer := 25000000; -- HZ
VGA_HOR_CHARS : integer := 80; -- CHARACTERS 25.6us
VGA_HOR_CHAR_PIXELS : integer := 8; -- PIXELS 0.32us
VGA_HOR_FRONT_PORCH : integer := 16; -- PIXELS 0.64us
VGA_HOR_SYNC : integer := 96; -- PIXELS 3.84us
VGA_HOR_BACK_PORCH : integer := 48; -- PIXELS 1.92us
VGA_VER_CHARS : integer := 25; -- CHARACTERS 12.8ms
VGA_VER_CHAR_LINES : integer := 16; -- LINES 0.512ms
VGA_VER_FRONT_PORCH : integer := 10; -- LINES 0.320ms
VGA_VER_SYNC : integer := 2; -- LINES 0.064ms
VGA_VER_BACK_PORCH : integer := 34 -- LINES 1.088ms
);
port(
-- control register interface
vdu_clk_in : in std_logic; -- 50MHz System clock
172,31 → 45,18
--
-- Synchronisation constants
--
--
-- Synchronisation constants
--
-- Displayed Characters per row
constant HOR_DISP_CHR : integer := VGA_HOR_CHARS;
-- Last horizontal pixel displayed
constant HOR_DISP_END : integer := (HOR_DISP_CHR * VGA_HOR_CHAR_PIXELS) - 1;
-- Start of horizontal synch pulse
constant HOR_SYNC_BEG : integer := HOR_DISP_END + VGA_HOR_FRONT_PORCH;
-- End of Horizontal Synch pulse
constant HOR_SYNC_END : integer := HOR_SYNC_BEG + VGA_HOR_SYNC;
-- Last pixel in scan line
constant HOR_SCAN_END : integer := HOR_SYNC_END + VGA_HOR_BACK_PORCH;
 
-- Number of displayed characters rows
constant VER_DISP_CHR : integer := VGA_VER_CHARS;
-- last row displayed
constant VER_DISP_END : integer := (VER_DISP_CHR * VGA_VER_CHAR_LINES) - 1;
-- start of vertical synch pulse
constant VER_SYNC_BEG : integer := VER_DISP_END + VGA_VER_FRONT_PORCH;
-- end of vertical synch pulse
constant VER_SYNC_END : integer := VER_SYNC_BEG + VGA_VER_SYNC;
-- Last scan row in the frame
constant VER_SCAN_END : integer := VER_SYNC_END + VGA_VER_BACK_PORCH;
constant HOR_DISP_END : integer := 639; -- Last horizontal pixel displayed
constant HOR_SYNC_BEG : integer := 679; -- Start of horizontal synch pulse
constant HOR_SYNC_END : integer := 775; -- End of Horizontal Synch pulse
constant HOR_SCAN_END : integer := 799; -- Last pixel in scan line
constant HOR_DISP_CHR : integer := 80; -- Number of characters displayed per row
 
constant VER_DISP_END : integer := 399; -- last row displayed
constant VER_SYNC_BEG : integer := 413; -- start of vertical synch pulse
constant VER_SYNC_END : integer := 414; -- end of vertical synch pulse
constant VER_SCAN_END : integer := 450; -- Last scan row in the frame
constant VER_DISP_CHR : integer := 25; -- Number of character rows displayed
 
signal horiz_sync : std_logic := '1';
signal vert_sync : std_logic := '1';
signal cursor_on_v : std_logic;
/rtl/VHDL/ACIA_RX.vhd
0,0 → 1,380
--===========================================================================--
--
-- S Y N T H E Z I A B L E ACIA 6850 C O R E
--
-- www.OpenCores.Org - January 2007
-- This core adheres to the GNU public license
--
-- Design units : 6850 ACIA core for the System68/09
--
-- File name : ACIA_RX.vhd
--
-- Purpose : Implements a 6850 ACIA device for communication purposes
-- between the cpu68/09 cpu and the Host computer through
-- an RS-232 communication protocol.
--
-- Dependencies : ieee.std_logic_1164.all;
-- ieee.numeric_std.all;
-- ieee.std_logic_unsigned.all;
-- unisim.vcomponents.all;
--
--===========================================================================--
-------------------------------------------------------------------------------
-- Revision list
-- Version Author Date Changes
--
-- 0.1 Ovidiu Lupas 15 January 2000 New model
-- 2.0 Ovidiu Lupas 17 April 2000 samples counter cleared for bit 0
-- olupas@opencores.org
--
-- 3.0 John Kent 5 January 2003 Added 6850 word format control
-- 3.1 John Kent 12 January 2003 Significantly revamped receive code.
-- 3.2 John Kent 10 January 2004 Rewrite of code.
-- 4.0 John Kent 3 February 2007 Renamed to ACIA 6850
-- Removed input debounce
-- 4.1 John Kent 4 February 2007 Cleaned up Rx state machine
-- 4.2 John Kent 25 February 2007 Modified sensitivity lists
--
-- dilbert57@opencores.org
-------------------------------------------------------------------------------
--
-- Description : Implements the receive unit of the ACIA_6850 core.
-- Samples 16 times the RxD line and retain the value
-- in the middle of the time interval.
--
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use ieee.std_logic_unsigned.all;
--library unisim;
-- use unisim.vcomponents.all;
 
-------------------------------------------------------------------------------
-- Entity for the ACIA Receiver
-------------------------------------------------------------------------------
entity ACIA_RX is
port (
Clk : in Std_Logic; -- Clock signal
RxRst : in Std_Logic; -- Reset input
RxRd : in Std_Logic; -- Read data strobe
WdFmt : in Std_Logic_Vector(2 downto 0); -- word format
BdFmt : in Std_Logic_Vector(1 downto 0); -- baud format
RxClk : in Std_Logic; -- RS-232 clock input
RxDat : in Std_Logic; -- RS-232 data input
RxFErr : out Std_Logic; -- Framing Error status
RxOErr : out Std_Logic; -- Over Run Error Status
RxPErr : out Std_logic; -- Parity Error Status
RxRdy : out Std_Logic; -- Data Ready Status
RxDout : out Std_Logic_Vector(7 downto 0)
);
end ACIA_RX; --================== End of entity ==============================--
 
-------------------------------------------------------------------------------
-- Architecture for ACIA receiver
-------------------------------------------------------------------------------
 
architecture rtl of ACIA_RX is
 
type RxStateType is ( RxStart_State, RxData_state,
RxParity_state, RxStop_state );
 
-----------------------------------------------------------------------------
-- Signals
-----------------------------------------------------------------------------
signal RxDatDel0 : Std_Logic := '0'; -- Delayed Rx Data
signal RxDatDel1 : Std_Logic := '0'; -- Delayed Rx Data
signal RxDatDel2 : Std_Logic := '0'; -- Delayed Rx Data
signal RxDatEdge : Std_Logic := '0'; -- Rx Data Edge pulse
signal RxClkDel : Std_Logic := '0'; -- Delayed Rx Input Clock
signal RxClkEdge : Std_Logic := '0'; -- Rx Input Clock Edge pulse
signal RxStart : Std_Logic := '0'; -- Rx Start request
signal RxEnable : Std_Logic := '0'; -- Rx Enabled
signal RxClkCnt : Std_Logic_Vector(5 downto 0) := (others => '0'); -- Rx Baud Clock Counter
signal RxBdClk : Std_Logic := '0'; -- Rx Baud Clock
signal RxBdDel : Std_Logic := '0'; -- Delayed Rx Baud Clock
signal RxBdEdge : Std_Logic := '0'; -- Rx Baud Clock Edge pulse
 
signal RxReady : Std_Logic := '0'; -- Data Ready flag
signal RxReq : Std_Logic := '0'; -- Rx Data Valid
signal RxAck : Std_Logic := '0'; -- Rx Data Valid
signal RxParity : Std_Logic := '0'; -- Calculated RX parity bit
signal RxState : RxStateType; -- receive bit state
signal RxBitCount : Std_Logic_Vector(2 downto 0) := (others => '0'); -- Rx Bit counter
signal RxShiftReg : Std_Logic_Vector(7 downto 0) := (others => '0'); -- Shift Register
 
begin
 
---------------------------------------------------------------------
-- Receiver Clock Edge Detection
---------------------------------------------------------------------
-- A rising edge will produce a one clock cycle pulse
--
-- acia_rx_clock_edge : process( Clk, RxRst, RxClk, RxClkDel )
acia_rx_clock_edge : process( RxRst, Clk )
begin
if RxRst = '1' then
RxClkDel <= '0';
RxClkEdge <= '0';
elsif Clk'event and Clk = '0' then
RxClkDel <= RxClk;
RxClkEdge <= (not RxClkDel) and RxClk;
end if;
end process;
 
---------------------------------------------------------------------
-- Receiver Data Edge Detection
---------------------------------------------------------------------
-- A falling edge will produce a pulse on RxClk wide
--
-- acia_rx_data_edge : process(Clk, RxRst, RxClkEdge, RxDat, RxDatDel0, RxDatDel1, RxDatDel2 )
acia_rx_data_edge : process( RxRst, Clk )
begin
if RxRst = '1' then
RxDatDel0 <= '0';
RxDatDel1 <= '0';
RxDatDel2 <= '0';
RxDatEdge <= '0';
elsif Clk'event and Clk = '0' then
-- if RxClkEdge = '1' then
RxDatDel0 <= RxDat;
RxDatDel1 <= RxDatDel0;
RxDatDel2 <= RxDatDel1;
RxDatEdge <= RxDatDel0 and (not RxDat);
-- end if;
end if;
end process;
 
---------------------------------------------------------------------
-- Receiver Start / Stop
---------------------------------------------------------------------
-- Enable the receive clock on detection of a start bit
-- Disable the receive clock after a byte is received.
--
-- acia_rx_start_stop : process( Clk, RxRst, RxDatEdge, RxAck, RxStart, RxEnable )
acia_rx_start_stop : process( RxRst, Clk )
begin
if RxRst = '1' then
RxEnable <= '0';
RxStart <= '0';
elsif Clk'event and Clk='0' then
if (RxEnable = '0') and (RxDatEdge = '1') then
-- Data Edge detected
-- Request Start and Enable Receive Clock.
RxEnable <= '1';
RxStart <= '1';
else
if (RxStart = '1') and (RxAck = '1') then
-- Data is being received
-- reset start request
RxStart <= '0';
else
-- Data has now been received
-- Disable Receiver until next start bit
if (RxStart = '0') and (RxAck = '0') then
RxEnable <= '0';
end if;
end if; -- RxStart
end if; -- RxDatEdge
end if; -- clk / RxRst
end process;
 
---------------------------------------------------------------------
-- Receiver Clock Divider
---------------------------------------------------------------------
-- Hold the Rx Clock divider in reset when the receiver is disabled
-- Advance the count only on a rising Rx clock edge
--
-- acia_rx_clock_divide : process( Clk, RxRst, RxEnable, RxClkEdge, RxClkCnt )
acia_rx_clock_divide : process( RxRst, Clk )
begin
if RxRst = '1' then
RxClkCnt <= (others => '0');
elsif Clk'event and Clk = '0' then
-- if RxEnable = '0' then
if RxDatEdge = '1' then
RxClkCnt <= (others => '0'); -- reset on falling data edge
else
if RxClkEdge = '1' then -- increment count on Clock edge
RxClkCnt <= RxClkCnt + "000001";
end if; -- RxClkEdge
end if; -- RxState
end if; -- clk / RxRst
end process;
 
---------------------------------------------------------------------
-- Receiver Baud Clock Selector
---------------------------------------------------------------------
-- BdFmt
-- 0 0 - Baud Clk divide by 1
-- 0 1 - Baud Clk divide by 16
-- 1 0 - Baud Clk divide by 64
-- 1 1 - Reset
--
acia_rx_baud_clock_select : process( BdFmt, RxClk, RxClkCnt )
begin
case BdFmt is
when "00" => -- Div by 1
RxBdClk <= RxClk;
when "01" => -- Div by 16
RxBdClk <= RxClkCnt(3);
when "10" => -- Div by 64
RxBdClk <= RxClkCnt(5);
when others => -- RxRst
RxBdClk <= '0';
end case;
end process;
 
---------------------------------------------------------------------
-- Receiver Baud Clock Edge Detect
---------------------------------------------------------------------
--
-- Generate one clock strobe on rising baud clock edge
--
-- acia_rx_baud_clock_edge : process( Clk, RxRst, RxBdClk, RxBdDel )
acia_rx_baud_clock_edge : process( RxRst, Clk )
begin
if RxRst = '1' then
RxBdDel <= '0';
RxBdEdge <= '0';
elsif Clk'event and Clk = '0' then
RxBdDel <= RxBdClk;
RxBdEdge <= RxBdClk and (not RxBdDel);
end if;
end process;
 
---------------------------------------------------------------------
-- Receiver process
---------------------------------------------------------------------
-- WdFmt - Bits[4..2]
-- 0 0 0 - 7 data, even parity, 2 stop
-- 0 0 1 - 7 data, odd parity, 2 stop
-- 0 1 0 - 7 data, even parity, 1 stop
-- 0 1 1 - 7 data, odd parity, 1 stop
-- 1 0 0 - 8 data, no parity, 2 stop
-- 1 0 1 - 8 data, no parity, 1 stop
-- 1 1 0 - 8 data, even parity, 1 stop
-- 1 1 1 - 8 data, odd parity, 1 stop
-- acia_rx_receive : process( Clk, RxRst, RxState, RxBdEdge, RxDatDel2, RxBitCount, RxReady, RxShiftReg )
acia_rx_receive : process( RxRst, Clk )
begin
if RxRst = '1' then
RxFErr <= '0';
RxOErr <= '0';
RxPErr <= '0';
RxShiftReg <= (others => '0'); -- Resert Shift register
RxDOut <= (others => '0');
RxParity <= '0'; -- reset Parity bit
RxAck <= '0'; -- Receiving data
RxBitCount <= (others => '0');
RxState <= RxStart_state;
elsif Clk'event and Clk='0' then
if RxBdEdge = '1' then
case RxState is
when RxStart_state =>
RxShiftReg <= (others => '0'); -- Reset Shift register
RxParity <= '0'; -- Parity bit
if WdFmt(2) = '0' then
-- WdFmt(2) = '0' => 7 data
RxBitCount <= "110";
else
-- WdFmt(2) = '1' => 8 data
RxBitCount <= "111";
end if;
if RxDatDel2 = '0' then -- look for start request
RxState <= RxData_state; -- yes, read data
end if;
when RxData_state => -- data bits 0 to 6
RxShiftReg <= RxDatDel2 & RxShiftReg(7 downto 1);
RxParity <= RxParity xor RxDatDel2;
RxAck <= '1'; -- Flag receive in progress
RxBitCount <= RxBitCount - "001";
if RxBitCount = "000" then
if WdFmt(2) = '0' then -- WdFmt(2) = '0' => 7 data
RxState <= RxParity_state; -- 7 bits always has parity
else -- WdFmt(2) = '1' => 8 data
if WdFmt(1) = '0' then
RxState <= RxStop_state; -- WdFmt(1) = '0' no parity
else
RxState <= RxParity_state; -- WdFmt(1) = '1' parity
end if; -- WdFmt(1)
end if; -- WdFmt(2)
end if; -- RxBitCount
 
when RxParity_state => -- parity bit
if WdFmt(2) = '0' then -- 7 data, shift right
RxShiftReg <= RxDatDel2 & RxShiftReg(7 downto 1); -- 7 data + parity
end if;
if WdFmt(0) = '0' then -- parity polarity ?
if RxParity = RxDatDel2 then -- check even parity
RxPErr <= '1';
else
RxPErr <= '0';
end if;
else
if RxParity = RxDatDel2 then -- check for odd parity
RxPErr <= '0';
else
RxPErr <= '1';
end if;
end if;
RxState <= RxStop_state;
 
when RxStop_state => -- stop bit (Only one required for RX)
RxAck <= '0'; -- Flag Receive Complete
RxDOut <= RxShiftReg;
if RxDatDel2 = '1' then -- stop bit expected
RxFErr <= '0'; -- yes, no framing error
else
RxFErr <= '1'; -- no, framing error
end if;
if RxReady = '1' then -- Has previous data been read ?
RxOErr <= '1'; -- no, overrun error
else
RxOErr <= '0'; -- yes, no over run error
end if;
RxState <= RxStart_state;
 
when others =>
RxAck <= '0'; -- Flag Receive Complete
RxState <= RxStart_state;
end case; -- RxState
 
end if; -- RxBdEdge
end if; -- clk / RxRst
 
end process;
 
---------------------------------------------------------------------
-- Receiver Read process
---------------------------------------------------------------------
-- acia_rx_read : process(Clk, RxRst, RxRd, RxReq, RxAck, RxReady )
acia_rx_read : process( RxRst, Clk, RxReady )
begin
if RxRst = '1' then
RxReady <= '0';
RxReq <= '0';
elsif Clk'event and Clk='0' then
if RxRd = '1' then
-- Data was read, Reset data ready
-- Request more data
RxReady <= '0';
RxReq <= '1';
else
if RxReq = '1' and RxAck = '1' then
-- Data is being received
-- reset receive request
RxReq <= '0';
else
-- Data now received
-- Flag RxReady and read Shift Register
if RxReq = '0' and RxAck = '0' then
RxReady <= '1';
end if;
end if; -- RxReq
end if; -- RxRd
end if; -- clk / RxRst
RxRdy <= RxReady;
end process;
 
end rtl; --==================== End of architecture ====================--
/rtl/VHDL/ACIA_TX.vhd
0,0 → 1,284
--===========================================================================--
--
-- S Y N T H E Z I A B L E ACIA 6850 C O R E
--
-- www.OpenCores.Org - January 2007
-- This core adheres to the GNU public license
--
-- Design units : 6850 ACIA core for the System68/09
--
-- File name : ACIA_TX.vhd
--
-- Purpose : Implements an ACIA device for communication purposes
-- between the FPGA processor and the Host computer through
-- a RS-232 communication protocol.
--
-- Dependencies : ieee.std_logic_1164
-- ieee.numeric_std
-- ieee.std_logic_unsigned
--
--===========================================================================--
-------------------------------------------------------------------------------
-- Revision list
-- Version Author Date Changes
--
-- 0.1 Ovidiu Lupas 15 January 2000 New model
-- 2.0 Ovidiu Lupas 17 April 2000 unnecessary variable removed
--
-- 3.0 John Kent 5 January 2003 added 6850 word format control
-- 3.1 John Kent 12 January 2003 Rearranged state machine code
-- 3.2 John Kent 30 March 2003 Revamped State machine
-- 3.3 John Kent 16 January 2004 Major re-write - added baud rate gen
-- 4.0 John Kent 3 February 2007 renamed txunit to ACIA_TX
-- 4.1 John Kent 4 February 2007 Cleaned up transmiter
-- 4.2 John Kent 25 Februauy 2007 Modify sensitivity lists and
-- split Tx Baud Clock select
-- and edge detection.
-- dilbert57@opencores.org
--
-------------------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use ieee.std_logic_unsigned.all;
 
-------------------------------------------------------------------------------
-- Entity for the ACIA Transmitter
-------------------------------------------------------------------------------
entity ACIA_TX is
port (
Clk : in Std_Logic; -- CPU Clock signal
TxRst : in Std_Logic; -- Reset input
TxWr : in Std_Logic; -- Load transmit data
TxDin : in Std_Logic_Vector(7 downto 0); -- Transmit data input.
WdFmt : in Std_Logic_Vector(2 downto 0); -- word format
BdFmt : in Std_Logic_Vector(1 downto 0); -- baud format
TxClk : in Std_Logic; -- Enable input
TxDat : out Std_Logic; -- RS-232 data bit output
TxEmp : out Std_Logic ); -- Tx buffer empty
end ACIA_TX; --================== End of entity ==============================--
 
-------------------------------------------------------------------------------
-- Architecture for ACIA_TX
-------------------------------------------------------------------------------
 
architecture rtl of ACIA_TX is
 
type TxStateType is ( Tx1Stop_State, TxStart_State,
TxData_State, TxParity_State, Tx2Stop_State );
 
-----------------------------------------------------------------------------
-- Signals
-----------------------------------------------------------------------------
 
signal TxClkDel : Std_Logic := '0'; -- Delayed Tx Input Clock
signal TxClkEdge : Std_Logic := '0'; -- Tx Input Clock Edge pulse
signal TxClkCnt : Std_Logic_Vector(5 downto 0) := (others => '0'); -- Tx Baud Clock Counter
signal TxBdDel : Std_Logic := '0'; -- Delayed Tx Baud Clock
signal TxBdEdge : Std_Logic := '0'; -- Tx Baud Clock Edge pulse
signal TxBdClk : Std_Logic := '0'; -- Tx Baud Clock
signal TxShiftReg : Std_Logic_Vector(7 downto 0) := (others => '0'); -- Transmit shift register
signal TxParity : Std_logic := '0'; -- Parity Bit
signal TxBitCount : Std_Logic_Vector(2 downto 0) := (others => '0'); -- Data Bit Counter
signal TxReq : Std_Logic := '0'; -- Request Transmit
signal TxAck : Std_Logic := '0'; -- Transmit Commenced
signal TxState : TxStateType; -- Transmitter state
 
begin
 
---------------------------------------------------------------------
-- Transmit Clock Edge Detection
-- A falling edge will produce a one clock cycle pulse
---------------------------------------------------------------------
 
-- acia_tx_clock_edge : process(Clk, TxRst, TxClk, TxClkDel )
acia_tx_clock_edge : process( TxRst, Clk )
begin
if TxRst = '1' then
TxClkDel <= '0';
TxClkEdge <= '0';
elsif Clk'event and Clk = '0' then
TxClkDel <= TxClk;
TxClkEdge <= TxClkDel and (not TxClk);
end if;
end process;
 
 
---------------------------------------------------------------------
-- Transmit Clock Divider
-- Advance the count only on an input clock pulse
---------------------------------------------------------------------
 
-- acia_tx_clock_divide : process( Clk, TxRst, TxClkEdge, TxClkCnt )
acia_tx_clock_divide : process( TxRst, Clk )
begin
if TxRst = '1' then
TxClkCnt <= "000000";
elsif Clk'event and Clk = '0' then
if TxClkEdge = '1' then
TxClkCnt <= TxClkCnt + "000001";
end if; -- TxClkEdge
end if; -- reset / clk
end process;
 
---------------------------------------------------------------------
-- Transmit Baud Clock Selector
---------------------------------------------------------------------
acia_tx_baud_clock_select : process( BdFmt, TxClk, TxClkCnt )
begin
-- BdFmt
-- 0 0 - Baud Clk divide by 1
-- 0 1 - Baud Clk divide by 16
-- 1 0 - Baud Clk divide by 64
-- 1 1 - reset
case BdFmt is
when "00" => -- Div by 1
TxBdClk <= TxClk;
when "01" => -- Div by 16
TxBdClk <= TxClkCnt(3);
when "10" => -- Div by 64
TxBdClk <= TxClkCnt(5);
when others => -- reset
TxBdClk <= '0';
end case;
end process;
 
---------------------------------------------------------------------
-- Transmit Baud Clock Edge Detector
---------------------------------------------------------------------
--
-- Generate one clock pulse strobe on falling edge of Tx Baud Clock
--
-- acia_tx_baud_clock_edge : process(Clk, TxRst, TxBdClk, TxBdDel )
acia_tx_baud_clock_edge : process( TxRst, Clk )
begin
if TxRst = '1' then
TxBdDel <= '0';
TxBdEdge <= '0';
elsif Clk'event and Clk = '0' then
TxBdDel <= TxBdClk;
TxBdEdge <= (not TxBdClk) and TxBdDel;
end if;
end process;
 
 
---------------------------------------------------------------------
-- Transmitter activation process
---------------------------------------------------------------------
-- acia_tx_write : process(Clk, TxRst, TxWr, TxReq, TxAck )
acia_tx_write : process( TxRst, Clk )
begin
if TxRst = '1' then
TxReq <= '0';
TxEmp <= '1';
elsif Clk'event and Clk = '0' then
if TxWr = '1' then
-- Write requests transmit
-- and clears the Empty Flag
TxReq <= '1';
TxEmp <= '0';
else
if (TxReq = '1') and (TxAck = '1') then
-- Once the transmitter is started
-- We can clear request.
TxReq <= '0';
elsif (TxReq = '0') and (TxAck = '0') then
-- When the transmitter is finished
-- We can flag transmit empty
TxEmp <= '1';
end if;
end if;
end if; -- clk / reset
end process;
 
-----------------------------------------------------------------------------
-- Implements the Tx unit
-----------------------------------------------------------------------------
-- WdFmt - Bits[4..2]
-- 0 0 0 - 7 data, even parity, 2 stop
-- 0 0 1 - 7 data, odd parity, 2 stop
-- 0 1 0 - 7 data, even parity, 1 stop
-- 0 1 1 - 7 data, odd parity, 1 stop
-- 1 0 0 - 8 data, no parity, 2 stop
-- 1 0 1 - 8 data, no parity, 1 stop
-- 1 1 0 - 8 data, even parity, 1 stop
-- 1 1 1 - 8 data, odd parity, 1 stop
-- acia_tx_transmit : process(TxRst, Clk, TxState, TxDin, WdFmt,
-- TxShiftReg, TxBdEdge, TxParity, TxBitCount,
-- TxReq, TxAck )
acia_tx_transmit : process( TxRst, Clk )
begin
if TxRst = '1' then
TxDat <= '1';
TxShiftReg <= "00000000";
TxParity <= '0';
TxBitCount <= "000";
TxAck <= '0';
TxState <= Tx1Stop_State;
elsif Clk'event and Clk = '0' then
if TxBdEdge = '1' then
case TxState is
when Tx1Stop_State => -- Last Stop bit state
TxDat <= '1';
TxAck <= '0'; -- Transmitter halted
if TxReq = '1' then
TxState <= TxStart_State;
end if;
 
when TxStart_State =>
TxDat <= '0'; -- Start bit
TxShiftReg <= TxDin; -- Load Shift reg with Tx Data
TxParity <= '0';
if WdFmt(2) = '0' then
TxBitCount <= "110"; -- 7 data + parity
else
TxBitCount <= "111"; -- 8 data
end if;
TxAck <= '1'; -- Flag transmit started
TxState <= TxData_State;
 
when TxData_State =>
TxDat <= TxShiftReg(0);
TxShiftReg <= '1' & TxShiftReg(7 downto 1);
TxParity <= TxParity xor TxShiftReg(0);
TxBitCount <= TxBitCount - "001";
if TxBitCount = "000" then
if (WdFmt(2) = '1') and (WdFmt(1) = '0') then
if WdFmt(0) = '0' then -- 8 data bits
TxState <= Tx2Stop_State; -- 2 stops
else
TxState <= Tx1Stop_State; -- 1 stop
end if;
else
TxState <= TxParity_State; -- parity
end if;
end if;
 
when TxParity_State => -- 7/8 data + parity bit
if WdFmt(0) = '0' then
TxDat <= not( TxParity ); -- even parity
else
TxDat <= TxParity; -- odd parity
end if;
if WdFmt(1) = '0' then
TxState <= Tx2Stop_State; -- 2 stops
else
TxState <= Tx1Stop_State; -- 1 stop
end if;
 
when Tx2Stop_State => -- first of two stop bits
TxDat <= '1';
TxState <= Tx1Stop_State;
 
when others => -- Undefined
TxDat <= '1';
TxState <= Tx1Stop_State;
 
end case; -- TxState
 
end if; -- TxBdEdge
end if; -- clk / reset
 
end process;
 
end rtl; --=================== End of architecture ====================--
/rtl/Spartan3/keymap_rom_slice.vhd
109,11 → 109,11
 
begin
 
process( addr, rom_out )
process( addr, rom_data, rom_out )
begin
rom_out <= rom_data(conv_integer(addr(8 downto 5)));
data_out <= rom_out( conv_integer(addr(4 downto 0))*8+7 downto conv_integer(addr(4 downto 0))*8);
end process;
end;
 
end architecture rtl;
 
/rtl/Spartan3/ram32k_b16.vhd
1,60 → 1,21
-- $Id: ram32k_b16.vhd,v 1.2 2008/03/14 15:52:43 dilbert57 Exp $
--===========================================================================--
-- --
-- ram32k_b16.vhd - 32KByte Block RAM Component for Spartan 3/3E --
-- --
--===========================================================================--
--
-- File name : ram32k_b16.vhd
--
-- Entity name : ram_32k
--
-- Purpose : Implements 32K of Synchronous Static RAM
-- using 16 x Spartan 3/3E RAMB16_S9 block rams
-- Used in the Digilent Spartan 3E500 System09 design
--
-- Dependencies : ieee.Std_Logic_1164
-- ieee.std_logic_arith
-- unisim.vcomponents
--
-- Uses : RAMB16_S9
--
-- Author : John E. Kent
--
-- Email : dilbert57@opencores.org
--
-- Web : http://opencores.org/project,system09
--
--
-- Copyright (C) 2005 - 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 Author Date Changes
--
-- 0.1 John Kent 2006-04-24 Initial release
-- 0.2 John Kent 2005-06-29 Added CS term to CE decodes. (date ???)
-- 0.3 John Kent 2010-09-14 Renamed "rdata" to "data_out"
-- Renamed "wdata" to "data_in"
-- Added header description
--===================================================================
--
-- 32K Block RAM
--
--===================================================================
--
-- Date: 24th April 2006
-- Author: John Kent
--
-- Revision History:
-- 24 April 2006 John Kent
-- Initial release
--
-- 29th June 2005 John Kent
-- Added CS term to CE decodes.
--
--
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
63,13 → 24,13
 
entity ram_32k is
Port (
clk : in std_logic;
rst : in std_logic;
cs : in std_logic;
addr : in std_logic_vector (14 downto 0);
rw : in std_logic;
data_in : in std_logic_vector (7 downto 0);
data_out : out std_logic_vector (7 downto 0)
clk : in std_logic;
rst : in std_logic;
cs : in std_logic;
rw : in std_logic;
addr : in std_logic_vector (14 downto 0);
rdata : out std_logic_vector (7 downto 0);
wdata : in std_logic_vector (7 downto 0)
);
end ram_32k;
 
76,25 → 37,25
architecture rtl of ram_32k is
 
 
signal we : std_logic;
signal dp : std_logic_vector(15 downto 0);
signal ce : std_logic_vector(15 downto 0);
signal data_out_0 : std_logic_vector(7 downto 0);
signal data_out_1 : std_logic_vector(7 downto 0);
signal data_out_2 : std_logic_vector(7 downto 0);
signal data_out_3 : std_logic_vector(7 downto 0);
signal data_out_4 : std_logic_vector(7 downto 0);
signal data_out_5 : std_logic_vector(7 downto 0);
signal data_out_6 : std_logic_vector(7 downto 0);
signal data_out_7 : std_logic_vector(7 downto 0);
signal data_out_8 : std_logic_vector(7 downto 0);
signal data_out_9 : std_logic_vector(7 downto 0);
signal data_out_a : std_logic_vector(7 downto 0);
signal data_out_b : std_logic_vector(7 downto 0);
signal data_out_c : std_logic_vector(7 downto 0);
signal data_out_d : std_logic_vector(7 downto 0);
signal data_out_e : std_logic_vector(7 downto 0);
signal data_out_f : std_logic_vector(7 downto 0);
signal we : std_logic;
signal dp : std_logic_vector(15 downto 0);
signal ce : std_logic_vector(15 downto 0);
signal rdata_0 : std_logic_vector(7 downto 0);
signal rdata_1 : std_logic_vector(7 downto 0);
signal rdata_2 : std_logic_vector(7 downto 0);
signal rdata_3 : std_logic_vector(7 downto 0);
signal rdata_4 : std_logic_vector(7 downto 0);
signal rdata_5 : std_logic_vector(7 downto 0);
signal rdata_6 : std_logic_vector(7 downto 0);
signal rdata_7 : std_logic_vector(7 downto 0);
signal rdata_8 : std_logic_vector(7 downto 0);
signal rdata_9 : std_logic_vector(7 downto 0);
signal rdata_a : std_logic_vector(7 downto 0);
signal rdata_b : std_logic_vector(7 downto 0);
signal rdata_c : std_logic_vector(7 downto 0);
signal rdata_d : std_logic_vector(7 downto 0);
signal rdata_e : std_logic_vector(7 downto 0);
signal rdata_f : std_logic_vector(7 downto 0);
 
begin
 
167,11 → 128,11
)
 
port map (
do => data_out_0,
do => rdata_0,
dop(0) => dp(0),
addr => addr(10 downto 0),
clk => clk,
di => data_in,
di => wdata,
dip(0) => dp(0),
en => ce(0),
ssr => rst,
247,11 → 208,11
)
 
port map (
do => data_out_1,
do => rdata_1,
dop(0) => dp(1),
addr => addr(10 downto 0),
clk => clk,
di => data_in,
di => wdata,
dip(0) => dp(1),
en => ce(1),
ssr => rst,
327,11 → 288,11
)
 
port map (
do => data_out_2,
do => rdata_2,
dop(0) => dp(2),
addr => addr(10 downto 0),
clk => clk,
di => data_in,
di => wdata,
dip(0) => dp(2),
en => ce(2),
ssr => rst,
407,11 → 368,11
)
 
port map (
do => data_out_3,
do => rdata_3,
dop(0) => dp(3),
addr => addr(10 downto 0),
clk => clk,
di => data_in,
di => wdata,
dip(0) => dp(3),
en => ce(3),
ssr => rst,
487,11 → 448,11
)
 
port map (
do => data_out_4,
do => rdata_4,
dop(0) => dp(4),
addr => addr(10 downto 0),
clk => clk,
di => data_in,
di => wdata,
dip(0) => dp(4),
en => ce(4),
ssr => rst,
567,11 → 528,11
)
 
port map (
do => data_out_5,
do => rdata_5,
dop(0) => dp(5),
addr => addr(10 downto 0),
clk => clk,
di => data_in,
di => wdata,
dip(0) => dp(5),
en => ce(5),
ssr => rst,
647,11 → 608,11
)
 
port map (
do => data_out_6,
do => rdata_6,
dop(0) => dp(6),
addr => addr(10 downto 0),
clk => clk,
di => data_in,
di => wdata,
dip(0) => dp(6),
en => ce(6),
ssr => rst,
727,11 → 688,11
)
 
port map (
do => data_out_7,
do => rdata_7,
dop(0) => dp(7),
addr => addr(10 downto 0),
clk => clk,
di => data_in,
di => wdata,
dip(0) => dp(7),
en => ce(7),
ssr => rst,
807,11 → 768,11
)
 
port map (
do => data_out_8,
do => rdata_8,
dop(0) => dp(8),
addr => addr(10 downto 0),
clk => clk,
di => data_in,
di => wdata,
dip(0) => dp(8),
en => ce(8),
ssr => rst,
887,11 → 848,11
)
 
port map (
do => data_out_9,
do => rdata_9,
dop(0) => dp(9),
addr => addr(10 downto 0),
clk => clk,
di => data_in,
di => wdata,
dip(0) => dp(9),
en => ce(9),
ssr => rst,
967,11 → 928,11
)
 
port map (
do => data_out_a,
do => rdata_a,
dop(0) => dp(10),
addr => addr(10 downto 0),
clk => clk,
di => data_in,
di => wdata,
dip(0) => dp(10),
en => ce(10),
ssr => rst,
1047,11 → 1008,11
)
 
port map (
do => data_out_b,
do => rdata_b,
dop(0) => dp(11),
addr => addr(10 downto 0),
clk => clk,
di => data_in,
di => wdata,
dip(0) => dp(11),
en => ce(11),
ssr => rst,
1127,11 → 1088,11
)
 
port map (
do => data_out_c,
do => rdata_c,
dop(0) => dp(12),
addr => addr(10 downto 0),
clk => clk,
di => data_in,
di => wdata,
dip(0) => dp(12),
en => ce(12),
ssr => rst,
1207,11 → 1168,11
)
 
port map (
do => data_out_d,
do => rdata_d,
dop(0) => dp(13),
addr => addr(10 downto 0),
clk => clk,
di => data_in,
di => wdata,
dip(0) => dp(13),
en => ce(13),
ssr => rst,
1287,11 → 1248,11
)
 
port map (
do => data_out_e,
do => rdata_e,
dop(0) => dp(14),
addr => addr(10 downto 0),
clk => clk,
di => data_in,
di => wdata,
dip(0) => dp(14),
en => ce(14),
ssr => rst,
1367,11 → 1328,11
)
 
port map (
do => data_out_f,
do => rdata_f,
dop(0) => dp(15),
addr => addr(10 downto 0),
clk => clk,
di => data_in,
di => wdata,
dip(0) => dp(15),
en => ce(15),
ssr => rst,
1379,46 → 1340,46
);
 
my_ram_32k : process ( cs, rw, addr,
data_out_0, data_out_1, data_out_2, data_out_3,
data_out_4, data_out_5, data_out_6, data_out_7,
data_out_8, data_out_9, data_out_a, data_out_b,
data_out_c, data_out_d, data_out_e, data_out_f )
rdata_0, rdata_1, rdata_2, rdata_3,
rdata_4, rdata_5, rdata_6, rdata_7,
rdata_8, rdata_9, rdata_a, rdata_b,
rdata_c, rdata_d, rdata_e, rdata_f )
begin
we <= not rw;
case addr(14 downto 11) is
when "0000" =>
data_out <= data_out_0;
rdata <= rdata_0;
when "0001" =>
data_out <= data_out_1;
rdata <= rdata_1;
when "0010" =>
data_out <= data_out_2;
rdata <= rdata_2;
when "0011" =>
data_out <= data_out_3;
rdata <= rdata_3;
when "0100" =>
data_out <= data_out_4;
rdata <= rdata_4;
when "0101" =>
data_out <= data_out_5;
rdata <= rdata_5;
when "0110" =>
data_out <= data_out_6;
rdata <= rdata_6;
when "0111" =>
data_out <= data_out_7;
rdata <= rdata_7;
when "1000" =>
data_out <= data_out_8;
rdata <= rdata_8;
when "1001" =>
data_out <= data_out_9;
rdata <= rdata_9;
when "1010" =>
data_out <= data_out_a;
rdata <= rdata_a;
when "1011" =>
data_out <= data_out_b;
rdata <= rdata_b;
when "1100" =>
data_out <= data_out_c;
rdata <= rdata_c;
when "1101" =>
data_out <= data_out_d;
rdata <= rdata_d;
when "1110" =>
data_out <= data_out_e;
rdata <= rdata_e;
when "1111" =>
data_out <= data_out_f;
rdata <= rdata_f;
when others =>
null;
end case;
/rtl/Spartan3/sys09bug_s3e_rom2k_b16.vhd
1,56 → 1,8
--===========================================================================--
-- --
-- sys09bug_s3e_rom2k_b16.vhd - Sys09bug monitor ROM for the Spartan 3E500 --
-- --
--===========================================================================--
--
-- File name : sys09bug_s3e_rom2k_b16.vhd
--
-- Entity name : mon_rom
--
-- Purpose : Implements 2K Monitor ROM for System09
-- using 1 x Spartan 3E RAMB16_S9 block ram
-- Used in the Digilent Spartan 3E500 System09 design
--
-- Dependencies : ieee.Std_Logic_1164
-- ieee.std_logic_arith
-- unisim.vcomponents
--
-- Uses : RAMB16_S9
--
-- Author : John E. Kent
--
-- Email : dilbert57@opencores.org
--
-- Web : http://opencores.org/project,system09
--
--
-- Copyright (C) 2008 - 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 Author Date Changes
-- 0.1 John Kent 2008-01-08 Initial Version
-- 0.2 John Kent 2010-09-14 Added Header
-- renamed rdata & wdata to data_out & data_in
--
-- SYS09BUG MONITOR ROM FOR SYSTEM09 SPARTAN3E
-- John Kent
-- 8th January 2008
--
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
59,13 → 11,13
 
entity mon_rom is
Port (
clk : in std_logic;
rst : in std_logic;
cs : in std_logic;
addr : in std_logic_vector (10 downto 0);
rw : in std_logic;
data_in : in std_logic_vector (7 downto 0);
data_out : out std_logic_vector (7 downto 0)
clk : in std_logic;
rst : in std_logic;
cs : in std_logic;
rw : in std_logic;
addr : in std_logic_vector (10 downto 0);
rdata : out std_logic_vector (7 downto 0);
wdata : in std_logic_vector (7 downto 0)
);
end mon_rom;
 
145,11 → 97,11
)
 
port map (
do => data_out,
do => rdata,
dop(0) => dp,
addr => addr,
clk => clk,
di => data_in,
di => wdata,
dip(0) => dp,
en => cs,
ssr => rst,

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.