Project

General

Profile

« Previous | Next » 

Revision 1

Added by markw over 11 years ago

Current unmerged vhdl for my Atari800 core and start at merging them into one tree with a common core

View differences:

common/a8core/address_decoder.vhdl
---------------------------------------------------------------------------
-- (c) 2013 mark watson
-- I am happy for anyone to use this for non-commercial use.
-- If my vhdl files are used commercially or otherwise sold,
-- please contact me for explicit permission at scrameta (gmail).
-- This applies for source and binary form and derived works.
---------------------------------------------------------------------------
LIBRARY ieee;
USE ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use IEEE.STD_LOGIC_MISC.all;
ENTITY address_decoder IS
PORT
(
CLK : IN STD_LOGIC;
-- bus masters - either CPU or antic
-- antic has priority and is slected when ANTIC_FETCH high
CPU_ADDR : IN STD_LOGIC_VECTOR(15 DOWNTO 0);
CPU_FETCH : in std_logic;
CPU_WRITE_N : IN STD_LOGIC;
CPU_WRITE_DATA : in std_logic_vector(7 downto 0);
ANTIC_ADDR : IN STD_LOGIC_VECTOR(15 DOWNTO 0);
ANTIC_FETCH : IN STD_LOGIC;
antic_refresh : in std_logic; -- use for sdram refresh (sdram needs more, but this is a start)
ZPU_ADDR : in std_logic_vector(23 downto 0);
ZPU_FETCH : in std_logic;
ZPU_READ_ENABLE : in std_logic;
ZPU_32BIT_WRITE_ENABLE : in std_logic; -- common case
ZPU_16BIT_WRITE_ENABLE : in std_logic; -- for sram
ZPU_8BIT_WRITE_ENABLE : in std_logic; -- for hardware regs
ZPU_WRITE_DATA : in std_logic_vector(31 downto 0);
-- sources of data
ROM_DATA : IN STD_LOGIC_VECTOR(7 downto 0); -- flash rom
GTIA_DATA : IN STD_LOGIC_VECTOR(7 downto 0);
CACHE_GTIA_DATA : IN STD_LOGIC_VECTOR(7 downto 0);
POKEY_DATA : IN STD_LOGIC_VECTOR(7 downto 0);
CACHE_POKEY_DATA : IN STD_LOGIC_VECTOR(7 downto 0);
POKEY2_DATA : IN STD_LOGIC_VECTOR(7 downto 0);
CACHE_POKEY2_DATA : IN STD_LOGIC_VECTOR(7 downto 0);
ANTIC_DATA : IN STD_LOGIC_VECTOR(7 downto 0);
CACHE_ANTIC_DATA : IN STD_LOGIC_VECTOR(7 downto 0);
PIA_DATA : IN STD_LOGIC_VECTOR(7 downto 0);
RAM_DATA : IN STD_LOGIC_VECTOR(15 downto 0);
CART_ROM_DATA : in std_logic_Vector(7 downto 0);
-- completion flags
RAM_REQUEST_COMPLETE : IN STD_LOGIC;
ROM_REQUEST_COMPLETE : IN STD_LOGIC;
CART_REQUEST_COMPLETE : IN STD_LOGIC;
-- configuration options
PORTB : IN STD_LOGIC_VECTOR(7 downto 0);
reset_n : in std_logic;
rom_select : in std_logic_vector(5 downto 0);
cart_select : in std_logic_vector(6 downto 0);
cart_activate : in std_logic;
ram_select : in std_logic_vector(2 downto 0);
CART_RD4 : in std_logic;
CART_RD5 : in std_logic;
use_sdram : in std_logic;
-- Memory read mux output
MEMORY_DATA : OUT STD_LOGIC_VECTOR(31 downto 0);
-- Flash and internal RAM take 2 cycles to access. SRAM takes 1 cycle.
-- Allow us to say we're not ready for a cycle
MEMORY_READY_ANTIC : OUT STD_LOGIC;
MEMORY_READY_ZPU : OUT STD_LOGIC;
MEMORY_READY_CPU : out std_logic;
-- Each chip does not have whole address bus, so several are addressed at once
-- For reads not an issue, but for writes we need to only write to a single place!
-- these all take 1 cycle, so fine to leave device selected in general
GTIA_WR_ENABLE : OUT STD_LOGIC;
POKEY_WR_ENABLE : OUT STD_LOGIC;
POKEY2_WR_ENABLE : OUT STD_LOGIC;
ANTIC_WR_ENABLE : OUT STD_LOGIC;
PIA_WR_ENABLE : OUT STD_LOGIC;
PIA_RD_ENABLE : OUT STD_LOGIC; -- ... except PIA takes action on reads!
RAM_WR_ENABLE : OUT STD_LOGIC;
PBI_WR_ENABLE : OUT STD_LOGIC;
D6_WR_ENABLE : OUT STD_LOGIC;
-- ROM and RAM have extended address busses to allow for bank switching etc.
ROM_ADDR : OUT STD_LOGIC_VECTOR(21 downto 0);
RAM_ADDR : OUT STD_LOGIC_VECTOR(18 downto 0);
PBI_ADDR : out std_logic_vector(15 downto 0);
RAM_REQUEST : out std_logic;
ROM_REQUEST : out std_logic;
CART_REQUEST : out std_logic;
CART_S4_n : out std_logic;
CART_S5_n : out std_logic;
CART_CCTL_n : out std_logic;
-- width of access
WIDTH_8bit_ACCESS : out std_logic;
WIDTH_16bit_ACCESS : out std_logic;
WIDTH_32bit_ACCESS : out std_logic;
-- interface as though SRAM - this module can take care of caching/write combining etc etc. For first cut... nothing. TODO: What extra info would help me here?
SDRAM_ADDR : out std_logic_vector(22 downto 0); -- 1 extra bit for byte alignment
SDRAM_READ_EN : out std_logic; -- if no reads pending may be a good time to do a refresh
SDRAM_WRITE_EN : out std_logic;
--SDRAM_REQUEST : out std_logic; -- Toggle this to issue a new request
SDRAM_REQUEST : out std_logic; -- Usual pattern
SDRAM_REFRESH : out std_logic;
--SDRAM_REPLY : in std_logic; -- This matches the request once complete
SDRAM_REQUEST_COMPLETE : in std_logic;
SDRAM_DATA : in std_logic_vector(31 downto 0);
WRITE_DATA : out std_logic_vector(31 downto 0)
);
END address_decoder;
ARCHITECTURE vhdl OF address_decoder IS
signal ADDR_next : std_logic_vector(23 downto 0);
signal ADDR_reg : std_logic_vector(23 downto 0);
signal DATA_WRITE_next : std_logic_vector(31 downto 0);
signal DATA_WRITE_reg : std_logic_vector(31 downto 0);
signal width_8bit_next : std_logic;
signal width_16bit_next : std_logic;
signal width_32bit_next : std_logic;
signal write_enable_next : std_logic;
signal width_8bit_reg : std_logic;
signal width_16bit_reg : std_logic;
signal width_32bit_reg : std_logic;
signal write_enable_reg : std_logic;
signal request_complete : std_logic;
signal notify_antic : std_logic;
signal notify_zpu : std_logic;
signal notify_cpu : std_logic;
signal start_request : std_logic;
signal extended_access_addr : std_logic;
signal extended_access_cpu_or_antic : std_logic;
signal extended_access_antic : std_logic;
signal extended_access_cpu: std_logic; -- 130XE and compy shop switch antic seperately
signal extended_access_either: std_logic; -- RAMBO switches both together using CPU bit
signal extended_self_test : std_logic;
signal extended_bank : std_logic_vector(8 downto 0); -- ONLY "000" - "103" valid...
-- even though we have 3 targets (flash, ram, rom) and 3 masters, only allow access to one a a time - simpler.
signal state_next : std_logic_vector(1 downto 0);
signal state_reg : std_logic_vector(1 downto 0);
constant state_idle : std_logic_vector(1 downto 0) := "00";
constant state_waiting_cpu : std_logic_vector(1 downto 0) := "01";
constant state_waiting_zpu : std_logic_vector(1 downto 0) := "10";
constant state_waiting_antic : std_logic_vector(1 downto 0) := "11";
signal ram_chip_select : std_logic;
signal sdram_chip_select : std_logic;
-- signal sdram_request_next : std_logic;
-- signal sdram_request_reg : std_logic;
-- signal SDRAM_REQUEST_COMPLETE : std_logic;
signal fetch_priority : std_logic_vector(2 downto 0);
signal fetch_wait_next : std_logic_vector(8 downto 0);
signal fetch_wait_reg : std_logic_vector(8 downto 0);
signal rom_in_ram : std_logic;
signal antic_fetch_real_next : std_logic;
signal antic_fetch_real_reg : std_logic;
signal cpu_fetch_real_next : std_logic;
signal cpu_fetch_real_reg : std_logic;
signal SDRAM_CART_ADDR : std_logic_vector(22 downto 0);
signal SDRAM_BASIC_ROM_ADDR : std_logic_vector(22 downto 0);
signal SDRAM_OS_ROM_ADDR : std_logic_vector(22 downto 0);
signal sdram_only_bank : std_logic;
BEGIN
-- register
process(clk,reset_n)
begin
if (reset_n='0') then
addr_reg <= (others=>'0');
state_reg <= state_idle;
width_8bit_reg <= '0';
width_16bit_reg <= '0';
width_32bit_reg <= '0';
write_enable_reg <= '0';
data_write_reg <= (others=> '0');
--sdram_request_reg <= '0';
fetch_wait_reg <= (others=>'0');
cpu_fetch_real_reg <= '0';
antic_fetch_real_reg <= '0';
elsif (clk'event and clk='1') then
addr_reg <= addr_next;
state_reg <= state_next;
width_8bit_reg <= width_8bit_next;
width_16bit_reg <= width_16bit_next;
width_32bit_reg <= width_32bit_next;
write_enable_reg <= write_enable_next;
data_write_reg <= data_WRITE_next;
--sdram_request_reg <= sdram_request_next;
fetch_wait_reg <= fetch_wait_next;
cpu_fetch_real_reg <= cpu_fetch_real_next;
antic_fetch_real_reg <= antic_fetch_real_next;
end if;
end process;
-- ANTIC FETCH
-- concept
-- bus master sends request - antic or cpu
-- antic has priority
-- cpu may be idle
-- once request complete MEMORY_READY is set
-- if request interrupted then results are LOST - memory ready not set until priority request satisfied
-- so
-- memory_ready <= device_ready;
-- problem
-- request -> device access -> interrupt -> device finishes -> ignored? -> device access
-- state machine
-- state machine impl
fetch_priority <= ANTIC_FETCH&ZPU_FETCH&CPU_FETCH;
process(fetch_wait_reg, state_reg, addr_reg, data_write_reg, width_8bit_reg, width_16bit_reg, width_32bit_reg, write_enable_reg, fetch_priority, antic_addr, zpu_addr, cpu_addr, request_complete, zpu_8bit_write_enable,zpu_16bit_write_enable,zpu_32bit_write_enable,zpu_read_enable, cpu_write_n, CPU_WRITE_DATA, ZPU_WRITE_DATA, antic_fetch_real_reg, cpu_fetch_real_reg)
begin
start_request <= '0';
notify_antic <= '0';
notify_cpu <= '0';
notify_zpu <= '0';
state_next <= state_reg;
fetch_wait_next <= std_logic_vector(unsigned(fetch_wait_reg) +1);
addr_next <= addr_reg;
data_WRITE_next <= data_WRITE_reg;
width_8bit_next <= width_8bit_reg;
width_16bit_next <= width_16bit_reg;
width_32bit_next <= width_32bit_reg;
write_enable_next <= write_enable_reg;
antic_fetch_real_next <= antic_fetch_real_reg;
cpu_fetch_real_next <= cpu_fetch_real_reg;
case state_reg is
when state_idle =>
fetch_wait_next <= (others=>'0');
write_enable_next <= '0';
width_8bit_next <= '0';
width_16bit_next <= '0';
width_32bit_next <= '0';
data_WRITE_next <= (others => '0');
addr_next <= zpu_ADDR(23 downto 16)&cpu_ADDR(15 downto 0);
case fetch_priority is
when "100"|"101"|"110"|"111" => -- antic wins
start_request <= '1';
addr_next <= "00000000"&antic_ADDR;
width_8bit_next <= '1';
if (request_complete = '1') then
notify_antic <= '1';
else
state_next <= state_waiting_antic;
end if;
antic_fetch_real_next <= '1';
when "010"|"011" => -- zpu wins (zpu usually accesses own ROM memory - this is NOT a zpu_fetch)
start_request <= '1';
addr_next <= zpu_ADDR;
data_WRITE_next <= zpu_wRITE_DATA;
width_8bit_next <= zpu_8BIT_WRITE_ENABLE or (zpu_READ_ENABLE and (zpu_addr(0) or zpu_addr(1)));
width_16bit_next <= zpu_16BIT_WRITE_ENABLE;
width_32bit_next <= zpu_32BIT_WRITE_ENABLE or (zpu_READ_ENABLE and not(zpu_addr(0) or zpu_addr(1))); -- narrower devices just return 8 bits on read
write_enable_next <= not(zpu_READ_ENABLE);
if (request_complete = '1') then
notify_zpu <= '1';
else
state_next <= state_waiting_zpu;
end if;
when "001" => -- 6502 wins
start_request <= '1';
addr_next <= "00000000"&cpu_ADDR;
data_WRITE_next(7 downto 0) <= cpu_WRITE_DATA;
width_8bit_next <= '1';
write_enable_next <= not(cpu_WRITE_N);
if (request_complete = '1') then
notify_cpu <= '1';
else
state_next <= state_waiting_cpu;
end if;
cpu_fetch_real_next <= '1';
when "000" =>
-- no requests
when others =>
-- nop
end case;
when state_waiting_antic =>
if (request_complete = '1') then
notify_antic <= '1';
state_next <= state_idle;
end if;
when state_waiting_zpu =>
if (request_complete = '1') then
notify_zpu <= '1';
state_next <= state_idle;
end if;
when state_waiting_cpu =>
if (request_complete = '1') then
notify_cpu <= '1';
state_next <= state_idle;
end if;
when others =>
-- NOP
end case;
end process;
-- output
MEMORY_READY_ANTIC <= notify_antic;
MEMORY_READY_ZPU <= notify_zpu;
MEMORY_READY_CPU <= notify_cpu;
RAM_REQUEST <= ram_chip_select;
SDRAM_REQUEST <= sdram_chip_select;
--SDRAM_REQUEST <= sdram_request_next;
SDRAM_REFRESH <= '0'; --fetch_wait_reg(7); -- TODO, BROKEN! antic_refresh;
SDRAM_READ_EN <= not(write_enable_next);
SDRAM_WRITE_EN <= write_enable_next;
WIDTH_8bit_ACCESS <= width_8bit_next;
WIDTH_16bit_ACCESS <= width_16bit_next;
WIDTH_32bit_ACCESS <= width_32bit_next;
WRITE_DATA <= DATA_WRITE_next;
-- a little sdram glue - move to sdram wrapper? TODO
--SDRAM_REQUEST_COMPLETE <= (SDRAM_REPLY xnor sdram_request_reg) and not(start_request);
--sdram_request_next <= sdram_request_reg xor sdram_chip_select;
-- Calculate which memory area to use
extended_access_addr <= addr_next(14) and not(addr_next(15)); --0x4000 to 0x7fff
extended_access_cpu_or_antic <= extended_access_antic or extended_access_cpu;
extended_access_antic <= (extended_access_addr and antic_fetch_real_next and not(portb(5)));
extended_access_cpu <= (extended_access_addr and cpu_fetch_real_next and not(portb(4)));
extended_access_either <= extended_access_addr and not(portb(4));
sdram_only_bank <= or_reduce(extended_bank(8 downto 5));
process(extended_access_cpu_or_antic,extended_access_either,extended_access_addr,addr_next,ram_select,portb)
begin
extended_bank <= "0000000"&addr_next(15 downto 14);
extended_self_test <= '1';
case ram_select is
when "000" => -- 64k
-- default
when "001" => -- 128k
if (extended_access_cpu_or_antic='1') then
extended_bank(2 downto 0) <= '1'&portb(3 downto 2);
end if;
when "010" => -- 320k compy shop
if (extended_access_cpu_or_antic='1') then
extended_bank(4 downto 0) <= '1'&portb(7 downto 6)&portb(3 downto 2);
extended_self_test <= '0';
end if;
when "011" => -- 320k rambo
if (extended_access_either='1')then
extended_bank(4 downto 0) <= '1'&portb(6 downto 5)&portb(3 downto 2);
end if;
when "100" => -- 576k compy shop
if (extended_access_cpu_or_antic='1') then
extended_bank(4 downto 0) <= portb(7 downto 6)&portb(3 downto 1);
extended_bank(5) <= not(or_reduce(portb(7 downto 6)&portb(3)));
extended_self_test <= '0';
end if;
when "101" => -- 576k rambo
if (extended_access_either='1') then
extended_bank(4 downto 0) <= portb(6 downto 5)&portb(3 downto 1);
extended_bank(5) <= not(or_reduce(portb(6 downto 5)&portb(3)));
end if;
when "110" => -- 1088k rambo
if (extended_access_either='1') then
extended_bank(5 downto 0) <= portb(7 downto 5)&portb(3 downto 1);
extended_bank(6) <= not(or_reduce(portb(7 downto 5)&portb(3)));
extended_self_test <= '0';
end if;
when "111" => -- 4MB!
if (extended_access_addr='1') then
extended_bank(7 downto 0) <= portb(7 downto 0);
extended_bank(8) <= not(or_reduce(portb(7 downto 2)));
extended_self_test <= and_reduce(portb(6 downto 4)); -- which means self-test is in the middle of half the banks - euuugh, oh well!
end if;
when others =>
-- TODO - portc!
end case;
end process;
-- SRAM memory map (512k)
-- base 64k RAM - banks 0-3 "000 0000 1111 1111 1111 1111" (TOP)
-- to 512k RAM - banks 4-31 "000 0111 1111 1111 1111 1111" (TOP)
-- SDRAM memory map (8MB)
-- base 64k RAM - banks 0-3 "000 0000 1111 1111 1111 1111" (TOP)
-- to 512k RAM - banks 4-31 "000 0111 1111 1111 1111 1111" (TOP)
-- to 4MB RAM - banks 32-255 "011 1111 1111 1111 1111 1111" (TOP)
-- +64k - banks 256-259"100 0000 0000 1111 1111 1111" (TOP)
-- SCRATCH - 4MB+64k-5MB
-- CARTS - "101 YYYY YYY0 0000 0000 0000" (BOT) - 2MB! 8kb banks
SDRAM_CART_ADDR <= "101"&cart_select& "0000000000000";
-- BASIC/OS ROM - "111 XXXX XX00 0000 0000 0000" (BOT) (BASIC IN SLOT 0!), 2nd to last 512K
SDRAM_BASIC_ROM_ADDR <= "111"&"000000" &"00000000000000";
SDRAM_OS_ROM_ADDR <= "111"&rom_select &"00000000000000";
-- SYSTEM - "111 1000 0000 0000 0000 0000" (BOT) - LAST 512K
process(
-- address and writing absolutely points us at a device
ADDR_next,WRITE_enable_next,
-- except for these additional special address bits
portb,
antic_fetch,
rom_select,
ram_select,cart_rd4,cart_rd5,
use_sdram,
-- input data from n sources
GTIA_DATA,POKEY_DATA,POKEY2_DATA,PIA_DATA,ANTIC_DATA,CART_ROM_DATA,ROM_DATA,RAM_DATA,SDRAM_DATA,
CACHE_GTIA_DATA,CACHE_POKEY_DATA,CACHE_POKEY2_DATA,CACHE_ANTIC_DATA,
-- input data from n sources complete?
-- hardware regs take 1 cycle, so always complete
ram_request_complete,sdram_request_complete,rom_request_complete,cart_request_complete,
-- on new access this is set - we must select the appropriate device - for this cycle only
start_request,
rom_in_ram,
-- SDRAM base addresses
extended_self_test,extended_bank,sdram_only_bank,
SDRAM_BASIC_ROM_ADDR,SDRAM_CART_ADDR,SDRAM_OS_ROM_ADDR
)
begin
MEMORY_DATA <= (others => '1');
ROM_ADDR <= (others=>'0');
RAM_ADDR <= addr_next(18 downto 0);
SDRAM_ADDR <= addr_next(22 downto 0);
PBI_ADDR <= ADDR_next(15 downto 0);
request_complete <= '0';
GTIA_WR_ENABLE <= '0';
POKEY_WR_ENABLE <= '0';
POKEY2_WR_ENABLE <= '0';
ANTIC_WR_ENABLE <= '0';
PIA_WR_ENABLE <= '0';
PIA_RD_ENABLE <= '0';
PBI_WR_ENABLE <= '0';
D6_WR_ENABLE <= '0';
RAM_WR_ENABLE <= write_enable_next;
SDRAM_WRITE_EN <= write_enable_next;
CART_S4_n <= '1';
CART_S5_n <= '1';
CART_CCTL_n <= '1';
rom_request <= '0';
cart_request <= '0';
ram_chip_select <= '0';
sdram_chip_select <= '0';
rom_in_ram <= '1';
-- if (addr_next(23 downto 17) = "0000000" ) then -- bit 16 left out on purpose, so the Atari 64k is available as 64k-128k for zpu. The zpu has rom at 0-64k...
if (or_reduce(addr_next(23 downto 18)) = '0' ) then -- bit 16,17 left out on purpose, so the Atari 64k is available as 64k-128k for zpu. The zpu has rom at 0-64k...
SDRAM_ADDR(13 downto 0) <= addr_next(13 downto 0);
SDRAM_ADDR(22 downto 14) <= extended_bank;
RAM_ADDR(13 downto 0) <= addr_next(13 downto 0);
RAM_ADDR(18 downto 14) <= extended_bank(4 downto 0);
if ((use_sdram or sdram_only_bank)='1') then
MEMORY_DATA(7 downto 0) <= SDRAM_DATA(7 downto 0);
sdram_chip_select <= start_request;
request_complete <= sdram_request_COMPLETE;
else
MEMORY_DATA(7 downto 0) <= RAM_DATA(7 downto 0);
ram_chip_select <= start_request;
request_complete <= ram_request_COMPLETE;
end if;
case addr_next(15 downto 8) is
-- GTIA
when X"D0" =>
GTIA_WR_ENABLE <= write_enable_next;
MEMORY_DATA(7 downto 0) <= GTIA_DATA;
MEMORY_DATA(15 downto 8) <= CACHE_GTIA_DATA;
request_complete <= '1';
sdram_chip_select <= '0';
ram_chip_select <= '0';
-- POKEY
when X"D2" =>
if (addr_next(4) = '0') then
POKEY_WR_ENABLE <= write_enable_next;
MEMORY_DATA(7 downto 0) <= POKEY_DATA;
MEMORY_DATA(15 downto 8) <= CACHE_POKEY_DATA;
else
POKEY2_WR_ENABLE <= write_enable_next;
MEMORY_DATA(7 downto 0) <= POKEY2_DATA;
MEMORY_DATA(15 downto 8) <= CACHE_POKEY2_DATA;
end if;
request_complete <= '1';
sdram_chip_select <= '0';
ram_chip_select <= '0';
-- PIA
when X"D3" =>
PIA_WR_ENABLE <= write_enable_next;
PIA_RD_ENABLE <= '1';
MEMORY_DATA(7 downto 0) <= PIA_DATA;
request_complete <= '1';
sdram_chip_select <= '0';
ram_chip_select <= '0';
-- ANTIC
when X"D4" =>
ANTIC_WR_ENABLE <= write_enable_next;
MEMORY_DATA(7 downto 0) <= ANTIC_DATA;
MEMORY_DATA(15 downto 8) <= CACHE_ANTIC_DATA;
request_complete <= '1';
sdram_chip_select <= '0';
ram_chip_select <= '0';
-- CART_CONFIG -- TODO - wait for n cycles (for now non-turbo mode should work?)
when X"D5" =>
sdram_chip_select <= '0';
ram_chip_select <= '0';
if ((CART_RD4 or CART_RD5) = '1') then
PBI_WR_ENABLE <= write_enable_next;
MEMORY_DATA(7 downto 0) <= CART_ROM_DATA;
cart_request <= start_request;
CART_CCTL_n <= '0';
request_complete <= CART_REQUEST_COMPLETE;
else
MEMORY_DATA(7 downto 0) <= X"FF";
request_complete <= '1';
end if;
when X"D6" =>
D6_WR_ENABLE <= write_enable_next;
-- TODO - should this still have RAM with covox here?
-- SELF TEST ROM 0x5000->0x57ff and XE RAM
when
X"50"|X"51"|X"52"|X"53"|X"54"|X"55"|X"56"|X"57" =>
if (portb(7) = '0' and portb(0) = '1' and extended_self_test = '1') then
sdram_chip_select <= '0';
ram_chip_select <= '0';
if (rom_in_ram = '1') then
MEMORY_DATA(7 downto 0) <= SDRAM_DATA(7 downto 0);
else
MEMORY_DATA(7 downto 0) <= ROM_DATA;
end if;
if (write_enable_next = '1') then
request_complete <= '1';
else
if (rom_in_ram = '1') then
request_complete <= sdram_request_COMPLETE;
sdram_chip_select <= start_request;
else
request_complete <= rom_request_COMPLETE;
rom_request <= start_request;
end if;
end if;
--ROM_ADDR <= "000000"&"00010"&ADDR(10 downto 0); -- x01000 based 2k (i.e. self test is 4k in - usually under hardware regs)
SDRAM_ADDR <= SDRAM_OS_ROM_ADDR;
SDRAM_ADDR(13 downto 0) <= "010"&ADDR_next(10 downto 0);
ROM_ADDR <= "000000"&"00"&"010"&ADDR_next(10 downto 0); -- x01000 based 2k
end if;
-- 0x80 cart
when
X"80"|X"81"|X"82"|X"83"|X"84"|X"85"|X"86"|X"87"|X"88"|X"89"|X"8A"|X"8B"|X"8C"|X"8D"|X"8E"|X"8F"
|X"90"|X"91"|X"92"|X"93"|X"94"|X"95"|X"96"|X"97"|X"98"|X"99"|X"9A"|X"9B"|X"9C"|X"9D"|X"9E"|X"9F" =>
if (cart_rd4 = '1') then
MEMORY_DATA(7 downto 0) <= CART_ROM_DATA;
rom_request <= start_request;
CART_S4_n <= '0';
request_complete <= CART_REQUEST_COMPLETE;
sdram_chip_select <= '0';
ram_chip_select <= '0';
end if;
-- 0xa0 cart (BASIC ROM 0xa000 - 0xbfff (8k))
when
X"A0"|X"A1"|X"A2"|X"A3"|X"A4"|X"A5"|X"A6"|X"A7"|X"A8"|X"A9"|X"AA"|X"AB"|X"AC"|X"AD"|X"AE"|X"AF"
|X"B0"|X"B1"|X"B2"|X"B3"|X"B4"|X"B5"|X"B6"|X"B7"|X"B8"|X"B9"|X"BA"|X"BB"|X"BC"|X"BD"|X"BE"|X"BF" =>
if (cart_rd5 = '1') then
MEMORY_DATA(7 downto 0) <= CART_ROM_DATA;
cart_request <= start_request;
CART_S5_n <= '0';
request_complete <= CART_REQUEST_COMPLETE;
sdram_chip_select <= '0';
ram_chip_select <= '0';
else
if (portb(1) = '0') then
sdram_chip_select <= '0';
ram_chip_select <= '0';
--request_complete <= ROM_REQUEST_COMPLETE;
--MEMORY_DATA(7 downto 0) <= ROM_DATA;
--rom_request <= start_request;
if (rom_in_ram = '1') then
MEMORY_DATA(7 downto 0) <= SDRAM_DATA(7 downto 0);
else
MEMORY_DATA(7 downto 0) <= ROM_DATA;
end if;
if (write_enable_next = '1') then
request_complete <= '1';
else
if (rom_in_ram = '1') then
request_complete <= sdram_request_COMPLETE;
sdram_chip_select <= start_request;
else
request_complete <= rom_request_COMPLETE;
rom_request <= start_request;
end if;
end if;
ROM_ADDR <= "000000"&"110"&ADDR_next(12 downto 0); -- x0C000 based 8k
SDRAM_ADDR <= SDRAM_BASIC_ROM_ADDR;
SDRAM_ADDR(12 downto 0) <= ADDR_next(12 downto 0); -- x0C000 based 8k
end if;
end if;
-- OS ROM 0xc00->0xcff
-- OS ROM d800->0xfff
when
X"C0"|X"C1"|X"C2"|X"C3"|X"C4"|X"C5"|X"C6"|X"C7"|X"C8"|X"C9"|X"CA"|X"CB"|X"CC"|X"CD"|X"CE"|X"CF"
|X"D8"|X"D9"|X"DA"|X"DB"|X"DC"|X"DD"|X"DE"|X"DF"
|X"E0"|X"E1"|X"E2"|X"E3"|X"E4"|X"E5"|X"E6"|X"E7"|X"E8"|X"E9"|X"EA"|X"EB"|X"EC"|X"ED"|X"EE"|X"EF"
|X"F0"|X"F1"|X"F2"|X"F3"|X"F4"|X"F5"|X"F6"|X"F7"|X"F8"|X"F9"|X"FA"|X"FB"|X"FC"|X"FD"|X"FE"|X"FF" =>
if (portb(0) = '1') then
sdram_chip_select <= '0';
ram_chip_select <= '0';
--request_complete <= ROM_REQUEST_COMPLETE;
--MEMORY_DATA(7 downto 0) <= ROM_DATA;
--rom_request <= start_request;
if (rom_in_ram = '1') then
MEMORY_DATA(7 downto 0) <= SDRAM_DATA(7 downto 0);
else
MEMORY_DATA(7 downto 0) <= ROM_DATA;
end if;
if (write_enable_next = '1') then
request_complete <= '1';
else
if (rom_in_ram = '1') then
request_complete <= sdram_request_COMPLETE;
sdram_chip_select <= start_request;
else
request_complete <= rom_request_COMPLETE;
rom_request <= start_request;
end if;
end if;
ROM_ADDR <= "000000"&"00"&ADDR_next(13 downto 0); -- x00000 based 16k
SDRAM_ADDR <= SDRAM_OS_ROM_ADDR;
SDRAM_ADDR(13 downto 0) <= ADDR_next(13 downto 0);
end if;
when others =>
end case;
else
sdram_chip_select <= '0';
ram_chip_select <= '0';
case addr_next(23 downto 21) is
when "000" =>
-- internal area for zpu, never happens!
when "001" => -- sram, 512K
MEMORY_DATA(15 downto 0) <= RAM_DATA;
ram_chip_select <= start_request;
request_complete <= ram_request_COMPLETE;
RAM_ADDR <= addr_next(18 downto 0);
when "010"|"011" => -- flash rom, 4MB
request_complete <= ROM_REQUEST_COMPLETE;
MEMORY_DATA(7 downto 0) <= ROM_DATA;
rom_request <= start_request;
ROM_ADDR <= addr_next(21 downto 0);
when "100"|"101"|"110"|"111" => -- sdram, 8MB
MEMORY_DATA <= SDRAM_DATA;
sdram_chip_select <= start_request;
request_complete <= sdram_request_COMPLETE;
SDRAM_ADDR <= addr_next(22 downto 0);
when others =>
-- NOP
end case;
end if;
-- case addr_next(15 downto 0) is
-- when X"FFFC" =>
-- MEMORY_DATA(7 downto 0) <= X"00";
-- when X"FFFD" =>
-- MEMORY_DATA(7 downto 0) <= X"06";
-- when X"0600" => --JSR 0610
-- MEMORY_DATA(7 downto 0) <= X"20";
-- when X"0601" =>
-- MEMORY_DATA(7 downto 0) <= X"10";
-- when X"0602" =>
-- MEMORY_DATA(7 downto 0) <= X"06";
-- when X"0603" => --JMP
-- MEMORY_DATA(7 downto 0) <= X"4C";
-- when X"0604" =>
-- MEMORY_DATA(7 downto 0) <= X"00";
-- when X"0605" =>
-- MEMORY_DATA(7 downto 0) <= X"06";
-- when X"0610" => --LDA RANDOM, STA 0x10, LDA 0x10, RTS
-- MEMORY_DATA(7 downto 0) <= X"AD";
-- when X"0611" =>
-- MEMORY_DATA(7 downto 0) <= X"0A";
-- when X"0612" =>
-- MEMORY_DATA(7 downto 0) <= X"D2";
-- when X"0613" =>
-- MEMORY_DATA(7 downto 0) <= X"85";
-- when X"0614" =>
-- MEMORY_DATA(7 downto 0) <= X"10";
-- when X"0615" =>
-- MEMORY_DATA(7 downto 0) <= X"44";
-- when X"0616" =>
-- MEMORY_DATA(7 downto 0) <= X"10";
-- when X"0617" =>
-- MEMORY_DATA(7 downto 0) <= X"60";
-- when others =>
-- end case;
end process;
END vhdl;
common/a8core/synchronizer.vhdl
---------------------------------------------------------------------------
-- (c) 2013 mark watson
-- I am happy for anyone to use this for non-commercial use.
-- If my vhdl files are used commercially or otherwise sold,
-- please contact me for explicit permission at scrameta (gmail).
-- This applies for source and binary form and derived works.
---------------------------------------------------------------------------
LIBRARY ieee;
USE ieee.std_logic_1164.all;
use ieee.numeric_std.all;
ENTITY synchronizer IS
PORT
(
CLK : IN STD_LOGIC;
RAW : IN STD_LOGIC;
SYNC : OUT STD_LOGIC
);
END synchronizer;
ARCHITECTURE vhdl OF synchronizer IS
signal ff_next : std_logic_vector(2 downto 0);
signal ff_reg : std_logic_vector(2 downto 0);
begin
-- register
process(clk)
begin
if (clk'event and clk='1') then
ff_reg <= ff_next;
end if;
end process;
ff_next <= RAW&ff_reg(2 downto 1);
SYNC <= ff_reg(0);
end vhdl;
common/components/hq_dac.v
`timescale 1ns / 1ps
// This module is a third order delta/sigma modulator
// It uses no multiply only shifts by 1, 2 or 13
// There are only 7 adders used, it takes around 110 LUTs
module hq_dac
(
input reset,
input clk,
input clk_ena,
input [19:0] pcm_in,
output reg dac_out
);
// ======================================
// ============== Stage #1 ==============
// ======================================
wire [23:0] w_data_in_p0;
wire [23:0] w_data_err_p0;
wire [23:0] w_data_int_p0;
reg [23:0] r_data_fwd_p1;
// PCM input extended to 24 bits
assign w_data_in_p0 = { {4{pcm_in[19]}}, pcm_in };
// Error between the input and the quantizer output
assign w_data_err_p0 = w_data_in_p0 - w_data_qt_p2;
// First integrator adder
assign w_data_int_p0 = { {3{w_data_err_p0[23]}}, w_data_err_p0[22:2] } // Divide by 4
+ r_data_fwd_p1;
// First integrator forward delay
always @(posedge reset or posedge clk)
if (reset)
r_data_fwd_p1 <= 24'd0;
else if (clk_ena)
r_data_fwd_p1 <= w_data_int_p0;
// ======================================
// ============== Stage #2 ==============
// ======================================
wire [23:0] w_data_fb1_p1;
wire [23:0] w_data_fb2_p1;
wire [23:0] w_data_lpf_p1;
reg [23:0] r_data_lpf_p2;
// Feedback from the quantizer output
assign w_data_fb1_p1 = { {3{r_data_fwd_p1[23]}}, r_data_fwd_p1[22:2] } // Divide by 4
- { {3{w_data_qt_p2[23]}}, w_data_qt_p2[22:2] }; // Divide by 4
// Feedback from the third stage
assign w_data_fb2_p1 = w_data_fb1_p1
- { {14{r_data_fwd_p2[23]}}, r_data_fwd_p2[22:13] }; // Divide by 8192
// Low pass filter
assign w_data_lpf_p1 = w_data_fb2_p1 + r_data_lpf_p2;
// Low pass filter feedback delay
always @(posedge reset or posedge clk)
if (reset)
r_data_lpf_p2 <= 24'd0;
else if (clk_ena)
r_data_lpf_p2 <= w_data_lpf_p1;
// ======================================
// ============== Stage #3 ==============
// ======================================
wire [23:0] w_data_fb3_p1;
wire [23:0] w_data_int_p1;
reg [23:0] r_data_fwd_p2;
// Feedback from the quantizer output
assign w_data_fb3_p1 = { {2{w_data_lpf_p1[23]}}, w_data_lpf_p1[22:1] } // Divide by 2
- { {2{w_data_qt_p2[23]}}, w_data_qt_p2[22:1] }; // Divide by 2
// Second integrator adder
assign w_data_int_p1 = w_data_fb3_p1 + r_data_fwd_p2;
// Second integrator forward delay
always @(posedge reset or posedge clk)
if (reset)
r_data_fwd_p2 <= 24'd0;
else if (clk_ena)
r_data_fwd_p2 <= w_data_int_p1;
// =====================================
// ========== 1-bit quantizer ==========
// =====================================
wire [23:0] w_data_qt_p2;
assign w_data_qt_p2 = (r_data_fwd_p2[23]) ? 24'hF00000 : 24'h100000;
always @(posedge reset or posedge clk)
if (reset)
dac_out <= 1'b0;
else if (clk_ena)
dac_out <= ~r_data_fwd_p2[23];
endmodule
common/components/scandoubler.vhdl
---------------------------------------------------------------------------
-- (c) 2013 mark watson
-- I am happy for anyone to use this for non-commercial use.
-- If my vhdl files are used commercially or otherwise sold,
-- please contact me for explicit permission at scrameta (gmail).
-- This applies for source and binary form and derived works.
---------------------------------------------------------------------------
LIBRARY ieee;
USE ieee.std_logic_1164.all;
use ieee.numeric_std.all;
ENTITY scandoubler IS
PORT
(
CLK : IN STD_LOGIC;
RESET_N : IN STD_LOGIC;
VGA : IN STD_LOGIC;
COMPOSITE_ON_HSYNC : in std_logic;
colour_enable : in std_logic;
doubled_enable : in std_logic;
-- GTIA interface
colour_in : in std_logic_vector(7 downto 0);
vsync_in : in std_logic;
hsync_in : in std_logic;
-- TO TV...
R : OUT STD_LOGIC_vector(3 downto 0);
G : OUT STD_LOGIC_vector(3 downto 0);
B : OUT STD_LOGIC_vector(3 downto 0);
VSYNC : out std_logic;
HSYNC : out std_logic
);
END scandoubler;
ARCHITECTURE vhdl OF scandoubler IS
COMPONENT gtia_palette IS
PORT
(
ATARI_COLOUR : IN STD_LOGIC_VECTOR(7 downto 0);
R_next : OUT STD_LOGIC_VECTOR(7 downto 0);
G_next : OUT STD_LOGIC_VECTOR(7 downto 0);
B_next : OUT STD_LOGIC_VECTOR(7 downto 0)
);
END component;
-- component reg_file IS
-- generic
-- (
-- BYTES : natural := 1;
-- WIDTH : natural := 1
-- );
-- PORT
-- (
-- CLK : IN STD_LOGIC;
-- ADDR : IN STD_LOGIC_VECTOR(width-1 DOWNTO 0);
-- DATA_IN : IN STD_LOGIC_VECTOR(7 DOWNTO 0);
-- WR_EN : IN STD_LOGIC;
--
-- DATA_OUT : OUT STD_LOGIC_VECTOR(7 DOWNTO 0)
-- );
-- END component;
component scandouble_ram_infer IS
PORT
(
clock: IN std_logic;
data: IN std_logic_vector (7 DOWNTO 0);
address: IN integer RANGE 0 to 1824;
we: IN std_logic;
q: OUT std_logic_vector (7 DOWNTO 0)
);
END component;
component delay_line IS
generic(COUNT : natural := 1);
PORT
(
CLK : IN STD_LOGIC;
SYNC_RESET : IN STD_LOGIC;
DATA_IN : IN STD_LOGIC;
ENABLE : IN STD_LOGIC; -- i.e. shift on this clock
RESET_N : IN STD_LOGIC;
DATA_OUT : OUT STD_LOGIC
);
END component;
signal colour_next : std_logic_vector(7 downto 0);
signal colour_reg : std_logic_vector(7 downto 0);
signal vsync_next : std_logic;
signal vsync_reg : std_logic;
signal hsync_next : std_logic;
signal hsync_reg : std_logic;
signal r_next : std_logic_vector(7 downto 0);
signal g_next : std_logic_vector(7 downto 0);
signal b_next : std_logic_vector(7 downto 0);
signal r_reg : std_logic_vector(7 downto 0);
signal g_reg : std_logic_vector(7 downto 0);
signal b_reg : std_logic_vector(7 downto 0);
signal linea_address : std_logic_vector(10 downto 0);
signal linea_write_enable : std_logic;
signal linea_out : std_logic_vector(7 downto 0);
signal lineb_address : std_logic_vector(10 downto 0);
signal lineb_write_enable : std_logic;
signal lineb_out : std_logic_vector(7 downto 0);
signal input_address_next : std_logic_vector(10 downto 0);
signal input_address_reg : std_logic_vector(10 downto 0);
signal output_address_next : std_logic_vector(10 downto 0);
signal output_address_reg : std_logic_vector(10 downto 0);
signal buffer_select_next : std_logic;
signal buffer_select_reg : std_logic;
signal hsync_in_reg : std_logic;
signal vga_hsync_next : std_logic;
signal vga_hsync_reg : std_logic;
signal vga_hsync_start : std_logic;
signal vga_hsync_end : std_logic;
begin
-- register
process(clk,reset_n)
begin
if (reset_n = '0') then
r_reg <= (others=>'0');
g_reg <= (others=>'0');
b_reg <= (others=>'0');
colour_reg <= (others=>'0');
hsync_reg <= '0';
vsync_reg <= '0';
input_address_reg <= (others=>'0');
output_address_reg <= (others=>'0');
buffer_select_reg <= '0';
vga_hsync_reg <= '0';
elsif (clk'event and clk='1') then
r_reg <= r_next;
g_reg <= g_next;
b_reg <= b_next;
colour_reg <= colour_next;
hsync_reg <= hsync_next;
vsync_reg <= vsync_next;
input_address_reg <= input_address_next;
output_address_reg <= output_address_next;
buffer_select_reg <= buffer_select_next;
hsync_in_reg <= hsync_in;
vga_hsync_reg <= vga_hsync_next;
end if;
end process;
-- TODO - these should use FPGA RAM - at present about 50% of FPGA is taken by these!!!
-- linea : reg_file
--generic map (BYTES=>456,WIDTH=>9)
--port map (clk=>clk,addr=>linea_address,wr_en=>linea_write_enable,data_in=>colour_in,data_out=>linea_out);
--lineb : reg_file
-- generic map (BYTES=>456,WIDTH=>9)
-- port map (clk=>clk,addr=>lineb_address,wr_en=>lineb_write_enable,data_in=>colour_in,data_out=>lineb_out);
linea : scandouble_ram_infer
port map (clock=>clk,address=>to_integer(unsigned(linea_address)),we=>linea_write_enable,data=>colour_in,q=>linea_out);
lineb : scandouble_ram_infer
port map (clock=>clk,address=>to_integer(unsigned(lineb_address)),we=>lineb_write_enable,data=>colour_in,q=>lineb_out);
-- capture
process(input_address_reg,colour_enable,hsync_in,hsync_in_reg,buffer_select_reg)
begin
input_address_next <= input_address_reg;
buffer_select_next <= buffer_select_reg;
linea_write_enable <= '0';
lineb_write_enable <= '0';
if (colour_enable = '1') then
input_address_next <= std_logic_vector(unsigned(input_address_reg)+1);
linea_write_enable <= buffer_select_reg;
lineb_write_enable <= not(buffer_select_reg);
end if;
if (hsync_in = '1' and hsync_in_reg = '0') then
input_address_next <= (others=>'0');
buffer_select_next <= not(buffer_select_reg);
end if;
end process;
-- output
process(vga_hsync_reg,vga_hsync_end,output_address_reg,doubled_enable)
begin
output_address_next <= output_address_reg;
vga_hsync_start<='0';
vga_hsync_next <= vga_hsync_reg;
if (doubled_enable = '1') then
output_address_next <= std_logic_vector(unsigned(output_address_reg)+1);
if (output_address_reg = "111"&X"1F") then
output_address_next <= (others=>'0');
vga_hsync_start <= '1';
vga_hsync_next <= '1';
end if;
end if;
if (vga_hsync_end = '1') then
vga_hsync_next <= '0';
end if;
end process;
linea_address <= input_address_reg when buffer_select_reg='1' else output_address_reg;
lineb_address <= input_address_reg when buffer_select_reg='0' else output_address_reg;
hsync_delay : delay_line
generic map (COUNT=>128)
port map(clk=>clk,sync_reset=>'0',data_in=>vga_hsync_start,enable=>doubled_enable,reset_n=>reset_n,data_out=>vga_hsync_end);
-- display
process(colour_reg,vsync_reg,vga_hsync_reg,hsync_reg,colour_in,vsync_in,hsync_in,colour_enable,doubled_enable,vga,composite_on_hsync,buffer_select_reg,linea_out,lineb_out)
begin
colour_next <= colour_reg;
vsync_next <= vsync_reg;
hsync_next <= hsync_reg;
if (vga = '0') then
-- non-vga mode - pass through
colour_next <= colour_in;
vsync_next <= not(vsync_in);
--hsync_next <= not(hsync_in or vsync_in);
if (composite_on_hsync = '1') then
hsync_next <= not(hsync_in xor vsync_in);
else
hsync_next <= not(hsync_in);
end if;
else
-- vga mode, store all inputs - then play back!
if (buffer_select_reg = '0') then
colour_next <= linea_out; -- todo, smoothly increase/decrease...
else
colour_next <= lineb_out;
end if;
vsync_next <= not(vsync_in);
--hsync_next <= not(vga_hsync_reg);
if (composite_on_hsync = '1') then
hsync_next <= not(vga_hsync_reg xor vsync_in);
else
hsync_next <= not(vga_hsync_reg);
end if;
end if;
end process;
-- colour palette
-- Color Value Color Value
--Black 0, 0 Medium blue 8, 128
--Rust 1, 16 Dark blue 9, 144
--Red-orange 2, 32 Blue-grey 10, 160
--Dark orange 3, 48 Olive green 11, 176
--Red 4, 64 Medium green 12, 192
--Dk lavender 5, 80 Dark green 13, 208
--Cobalt blue 6, 96 Orange-green 14, 224
--Ultramarine 7, 112 Orange 15, 240
-- from altirra
palette1 : entity work.gtia_palette(altirra)
port map (ATARI_COLOUR=>colour_reg, R_next=>R_next, G_next=>G_next, B_next=>B_next);
-- from lao
-- palette2 : entity work.gtia_palette(laoo)
-- port map (ATARI_COLOUR=>COLOUR, R_next=>R_next, G_next=>G_next, B_next=>B_next);
-- output
-- TODO - for DE2, output full 8 bits
R <= R_reg(7 downto 4);
G <= G_reg(7 downto 4);
B <= B_reg(7 downto 4);
vsync<=vsync_reg;
hsync<=hsync_reg;
end vhdl;
common/a8core/pokey_keyboard_scanner.vhdl
---------------------------------------------------------------------------
-- (c) 2013 mark watson
-- I am happy for anyone to use this for non-commercial use.
-- If my vhdl files are used commercially or otherwise sold,
-- please contact me for explicit permission at scrameta (gmail).
-- This applies for source and binary form and derived works.
---------------------------------------------------------------------------
LIBRARY ieee;
USE ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity pokey_keyboard_scanner is
port
(
clk : in std_logic;
reset_n : in std_logic;
enable : in std_logic; -- typically hsync or equiv timing
keyboard_response : in std_logic_vector(1 downto 0);
debounce_disable : in std_logic;
scan_enable : in std_logic;
keyboard_scan : out std_logic_vector(5 downto 0);
shift_pressed : out std_logic;
control_pressed : out std_logic;
break_pressed : out std_logic;
key_held : out std_logic;
keycode : out std_logic_vector(5 downto 0);
other_key_irq : out std_logic
);
end pokey_keyboard_scanner;
architecture vhdl of pokey_keyboard_scanner is
signal bincnt_next : std_logic_vector(5 downto 0);
signal bincnt_reg : std_logic_vector(5 downto 0);
signal break_pressed_next : std_logic;
signal break_pressed_reg : std_logic;
signal shift_pressed_next : std_logic;
signal shift_pressed_reg : std_logic;
signal control_pressed_next : std_logic;
signal control_pressed_reg : std_logic;
signal compare_latch_next : std_logic_vector(5 downto 0);
signal compare_latch_reg : std_logic_vector(5 downto 0);
signal keycode_latch_next : std_logic_vector(5 downto 0);
signal keycode_latch_reg : std_logic_vector(5 downto 0);
signal irq_next : std_logic;
signal irq_reg : std_logic;
signal key_held_next : std_logic;
signal key_held_reg : std_logic;
signal my_key : std_logic;
signal state_next : std_logic_vector(1 downto 0);
signal state_reg : std_logic_vector(1 downto 0);
constant state_wait_key : std_logic_vector(1 downto 0) := "00";
constant state_key_bounce : std_logic_vector(1 downto 0) := "01";
constant state_valid_key : std_logic_vector(1 downto 0) := "10";
constant state_key_debounce : std_logic_vector(1 downto 0) := "11";
begin
-- register
process(clk,reset_n)
begin
if (reset_n = '0') then
bincnt_reg <= (others=>'0');
break_pressed_reg <= '0';
shift_pressed_reg <= '0';
control_pressed_reg <= '0';
compare_latch_reg <= (others=>'0');
keycode_latch_reg <= (others=>'1');
key_held_reg <= '0';
state_reg <= state_wait_key;
irq_reg <= '0';
elsif (clk'event and clk = '1') then
bincnt_reg <= bincnt_next;
state_reg <= state_next;
break_pressed_reg <= break_pressed_next;
shift_pressed_reg <= shift_pressed_next;
control_pressed_reg <= control_pressed_next;
compare_latch_reg <= compare_latch_next;
keycode_latch_reg <= keycode_latch_next;
key_held_reg <= key_held_next;
state_reg <= state_next;
irq_reg <= irq_next;
end if;
end process;
process (enable, keyboard_response, scan_enable, key_held_reg, my_key, state_reg,bincnt_reg, compare_latch_reg, break_pressed_reg, shift_pressed_reg, control_pressed_reg, keycode_latch_reg, debounce_disable)
begin
bincnt_next <= bincnt_reg;
state_next <= state_reg;
compare_latch_next <= compare_latch_reg;
irq_next <= '0';
break_pressed_next <= break_pressed_reg;
shift_pressed_next <= shift_pressed_reg;
control_pressed_next <= control_pressed_reg;
keycode_latch_next <= keycode_latch_reg;
key_held_next <= key_held_reg;
my_key <= '0';
if (bincnt_reg = compare_latch_reg or debounce_disable='1') then
my_key <= '1';
end if;
if (enable = '1' and scan_enable='1') then
bincnt_next <= std_logic_vector(unsigned(bincnt_reg) + 1); -- check another key
key_held_next<= '0';
case state_reg is
when state_wait_key =>
if (keyboard_response(0) = '0') then -- detected key press
state_next <= state_key_bounce;
compare_latch_next <= bincnt_reg;
end if;
when state_key_bounce =>
if (keyboard_response(0) = '0') then -- detected key press
if (my_key = '1') then -- same key
keycode_latch_next <= compare_latch_reg;
irq_next <= '1';
key_held_next<= '1';
state_next <= state_valid_key;
else -- different key (multiple keys pressed)
state_next <= state_wait_key;
end if;
else -- key not pressed
if (my_key = '1') then -- same key, no longer pressed
state_next <= state_wait_key;
end if;
end if;
when state_valid_key =>
key_held_next<= '1';
if (my_key = '1') then -- only response to my key
if (keyboard_response(0) = '1') then -- no longer pressed
state_next <= state_key_debounce;
end if;
end if;
when state_key_debounce =>
if (my_key = '1') then
state_next <= state_wait_key;
end if;
when others=>
state_next <= state_wait_key;
end case;
if (bincnt_reg(3 downto 0) = "0000") then
case bincnt_reg(5 downto 4) is
when "11" =>
break_pressed_next <= not(keyboard_response(1)); --0x30
when "01" =>
shift_pressed_next <= not(keyboard_response(1)); --0x10
when "00" =>
control_pressed_next <= not(keyboard_response(1)); -- 0x00
when others =>
--
end case;
end if;
end if;
end process;
-- outputs
keyboard_scan <= not(bincnt_reg);
key_held <= key_held_reg;
keycode <= keycode_latch_reg;
break_pressed <= break_pressed_reg;
shift_pressed <= shift_pressed_reg;
control_pressed <= control_pressed_reg;
other_key_irq <= irq_reg;
end vhdl;
common/a8core/pokey_noise_filter.vhdl
---------------------------------------------------------------------------
-- (c) 2013 mark watson
-- I am happy for anyone to use this for non-commercial use.
-- If my vhdl files are used commercially or otherwise sold,
-- please contact me for explicit permission at scrameta (gmail).
-- This applies for source and binary form and derived works.
---------------------------------------------------------------------------
LIBRARY ieee;
USE ieee.std_logic_1164.all;
use ieee.numeric_std.all;
ENTITY pokey_noise_filter IS
PORT
(
NOISE_SELECT : IN STD_LOGIC_VECTOR(2 downto 0);
PULSE_IN : IN STD_LOGIC;
NOISE_4 : IN STD_LOGIC;
NOISE_5 : IN STD_LOGIC;
NOISE_LARGE : IN STD_LOGIC;
PULSE_OUT : OUT STD_LOGIC
);
END pokey_noise_filter;
ARCHITECTURE vhdl OF pokey_noise_filter IS
signal pulse_noise_a : std_logic;
signal pulse_noise_b : std_logic;
BEGIN
process(pulse_in, noise_4, noise_5, noise_large, pulse_noise_a, pulse_noise_b, noise_select)
begin
pulse_noise_a <= noise_large;
pulse_noise_b <= noise_5 and pulse_in;
if (NOISE_SELECT(1) = '1') then
pulse_noise_a <= noise_4;
end if;
if (NOISE_SELECT(2) = '1') then
pulse_noise_b <= pulse_in;
end if;
PULSE_OUT <= pulse_noise_a and pulse_noise_b;
if (NOISE_SELECT(0) = '1') then
PULSE_OUT <= pulse_noise_b;
end if;
end process;
end vhdl;
common/a8core/poly_4.vhdl
---------------------------------------------------------------------------
-- (c) 2013 mark watson
-- I am happy for anyone to use this for non-commercial use.
-- If my vhdl files are used commercially or otherwise sold,
-- please contact me for explicit permission at scrameta (gmail).
-- This applies for source and binary form and derived works.
---------------------------------------------------------------------------
LIBRARY ieee;
USE ieee.std_logic_1164.all;
use ieee.numeric_std.all;
ENTITY poly_4 IS
PORT
(
CLK : IN STD_LOGIC;
RESET_N : IN STD_LOGIC;
ENABLE : IN STD_LOGIC;
INIT : IN STD_LOGIC;
BIT_OUT : OUT STD_LOGIC
);
... This diff was truncated because it exceeds the maximum size that can be displayed.

Also available in: Unified diff