⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 fpga64_cone.vhd

📁 FPGA64的VHDL源代码
💻 VHD
📖 第 1 页 / 共 2 页
字号:
-- -----------------------------------------------------------------------
--
--                                 FPGA 64
--
--     A fully functional commodore 64 implementation in a single FPGA
--
-- -----------------------------------------------------------------------
-- Peter Wendrich (pwsoft@syntiac.com)
-- http://www.syntiac.com/fpga64.html
-- -----------------------------------------------------------------------
--
-- System runs on 32 Mhz (derived from a 50MHz clock). 
-- The VIC-II runs in the first 4 cycles of 32 Mhz clock.
-- The CPU runs in the last 16 cycles. Effective cpu speed is 1 Mhz.
-- 4 additional cycles are used to interface with the C-One IEC port.
-- 
-- -----------------------------------------------------------------------

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.std_logic_unsigned.ALL;
use IEEE.numeric_std.all;

-- -----------------------------------------------------------------------

entity fpga64_cone is
	generic (
		resetCycles: integer := 4095
	);
	port(
		sysclk : in std_logic;
		clk32 : in std_logic;
		reset_n : in std_logic;

		-- keyboard interface (use any ordinairy PS2 keyboard)
		kbd_clk: in std_logic;
		kbd_dat: in std_logic;

		-- external memory
		ramAddr: out unsigned(16 downto 0);
		ramData: inout unsigned(7 downto 0);

		ramCE: out std_logic;
		ramWe: out std_logic;

		-- VGA interface
		hsync: out std_logic;
		vsync: out std_logic;
		r : out unsigned(7 downto 0);
		g : out unsigned(7 downto 0);
		b : out unsigned(7 downto 0);
		
		-- cartridge port
		game : in std_logic;
		exrom : in std_logic;
		irq_n : inout std_logic;
		nmi_n : inout std_logic;
		dma_n : in std_logic;
		ba : out std_logic;
		dot_clk: out std_logic;
		cpu_clk: out std_logic;

		-- joystick interface
		joyA: in unsigned(5 downto 0);
		joyB: in unsigned(5 downto 0);

		-- serial port, for connection to pheripherals
		serioclk : out std_logic;
		ces : out std_logic_vector(3 downto 0);

		--Connector to the SID
		SIDclk: out std_logic;
		still: out unsigned(15 downto 0)
	);
end fpga64_cone;

-- -----------------------------------------------------------------------

architecture rtl of fpga64_cone is
	-- System state machine
	type sysCycleDef is (
		CYCLE_IDLE0, CYCLE_IDLE1, CYCLE_IDLE2, CYCLE_IDLE3,
		CYCLE_IDLE4, CYCLE_IDLE5, CYCLE_IDLE6, CYCLE_IDLE7,
		CYCLE_IDLE8,
		CYCLE_IEC0, CYCLE_IEC1, CYCLE_IEC2, CYCLE_IEC3,
		CYCLE_VIC0, CYCLE_VIC1, CYCLE_VIC2, CYCLE_VIC3,
		CYCLE_CPU0, CYCLE_CPU1, CYCLE_CPU2, CYCLE_CPU3,
		CYCLE_CPU4, CYCLE_CPU5, CYCLE_CPU6, CYCLE_CPU7,
		CYCLE_CPUP, CYCLE_CPUQ,
		CYCLE_CPU8, CYCLE_CPU9, CYCLE_CPUA, CYCLE_CPUB,
		CYCLE_CPUC, CYCLE_CPUD, CYCLE_CPUE, CYCLE_CPUF
	);

	signal sysCycle : sysCycleDef := sysCycleDef'low;
	signal sysCycleCnt : unsigned(2 downto 0);
	signal phi0_cpu : std_logic;
	signal phi0_vic : std_logic;
	signal cpuHasBus : std_logic;
	
	signal cycleRestart : std_logic;
	signal cycleRestartReg1 : std_logic;
	signal cycleRestartReg2 : std_logic;
	signal cycleRestartEdge : std_logic;

	signal dotClkReg : std_logic;
	signal dotClkCnt : integer range 0 to 7;

	signal baLoc: std_logic;
	signal irqLoc: std_logic;
	signal nmiLoc: std_logic;

	signal enableCpu: std_logic;
	signal enableVic : std_logic;
	signal enablePixel : std_logic;

	signal irq_cia1: std_logic;
	signal irq_cia2: std_logic;
	signal irq_vic: std_logic;

	signal systemWe: std_logic;
	signal pulseWrRam: std_logic;
	signal pulseWrIo: std_logic;
	signal pulseRd: std_logic;
	signal colorWe : std_logic;
	signal systemAddr: unsigned(16 downto 0);
	signal ramDataReg : unsigned(7 downto 0);

	signal cs_vic: std_logic;
	signal cs_sid: std_logic;
	signal cs_color: std_logic;
	signal cs_cia1: std_logic;
	signal cs_cia2: std_logic;
	signal cs_ram: std_logic;
	signal cs_ioE: std_logic;
	signal cs_ioF: std_logic;
	signal cs_romL: std_logic;
	signal cs_romH: std_logic;

	signal reset: std_logic := '1';
	signal reset_cnt: integer range 0 to resetCycles := 0;

	signal bankSwitch: unsigned(2 downto 0);

-- CIA signals
signal enableCia : std_logic;
signal cia1Do: unsigned(7 downto 0);
signal cia2Do: unsigned(7 downto 0);

-- keyboard
signal newScanCode: std_logic;
signal theScanCode: unsigned(7 downto 0);

-- I/O
signal cia1_pai: unsigned(7 downto 0);
signal cia1_pao: unsigned(7 downto 0);
signal cia1_pad: unsigned(7 downto 0);
signal cia1_pbi: unsigned(7 downto 0);
signal cia1_pbo: unsigned(7 downto 0);
signal cia1_pbd: unsigned(7 downto 0);
signal cia2_pai: unsigned(7 downto 0);
signal cia2_pao: unsigned(7 downto 0);
signal cia2_pad: unsigned(7 downto 0);
signal cia2_pbi: unsigned(7 downto 0);
signal cia2_pbo: unsigned(7 downto 0);
signal cia2_pbd: unsigned(7 downto 0);

	signal debugWE: std_logic := '0';
	signal debugData: unsigned(7 downto 0) := (others => '0');
	signal debugAddr: integer range 2047 downto 0 := 0;

	signal cpuWe: std_logic;
	signal cpuAddr: unsigned(15 downto 0);
	signal cpuDi: unsigned(7 downto 0);
	signal cpuDo: unsigned(7 downto 0);
	signal cpuIO: unsigned(7 downto 0);

	signal vicDi: unsigned(7 downto 0);
	signal vicAddr: unsigned(15 downto 0);
	signal vicData: unsigned(7 downto 0);
	signal lastVicDi : unsigned(7 downto 0);

	signal colorQ : unsigned(3 downto 0);
	signal colorData : unsigned(3 downto 0);

	signal cpuDebugOpcode: unsigned(7 downto 0);
	signal cpuDebugPc: unsigned(15 downto 0);
	signal cpuDebugA: unsigned(7 downto 0);
	signal cpuDebugX: unsigned(7 downto 0);
	signal cpuDebugY: unsigned(7 downto 0);
	signal cpuDebugS: unsigned(7 downto 0);
	signal cpuStep : std_logic;
	signal traceKey : std_logic;
	signal trace2Key : std_logic;

-- video
signal cyclesPerLine : unsigned(11 downto 0);
signal scanConverterFaster : std_logic;

signal vicColorIndex : unsigned(3 downto 0);
signal vicHSync : std_logic;
signal vicVSync : std_logic;

signal vgaColorIndex : unsigned(3 downto 0);
signal vgaR : unsigned(7 downto 0);
signal vgaG : unsigned(7 downto 0);
signal vgaB : unsigned(7 downto 0);
signal vgaVSync : std_logic;
signal vgaHSync : std_logic;
signal vgaDebug : std_logic;
signal vgaDebugDim : std_logic;
signal debuggerOn : std_logic;	
signal traceStep : std_logic;

-- config
signal videoKey : std_logic;
signal ntscMode : std_logic;

signal videoConfigVideo : std_logic;
signal videoConfigDim : std_logic;
signal videoConfigShow : std_logic;
signal videoConfigTimeout : unsigned(19 downto 0);
	
begin
-- -----------------------------------------------------------------------
-- Local signal to outside world
-- -----------------------------------------------------------------------
	ba <= baLoc;

-- -----------------------------------------------------------------------
-- System state machine, controls bus accesses
-- and triggers enables of other components
-- -----------------------------------------------------------------------
	process(clk32)
	begin
		if rising_edge(clk32) then
			cycleRestart <= '0';
			if sysCycle = sysCycleDef'high then
				sysCycle <= sysCycleDef'low;
				sysCycleCnt <= sysCycleCnt + 1;
				cycleRestart <= '1';
			elsif sysCycle = CYCLE_CPU7
			and ntscMode = '1' then
				sysCycle <= CYCLE_CPU8;		-- NTSC 33 Cycles
			elsif sysCycle = CYCLE_CPUP
			and sysCycleCnt /= "001"
			and sysCycleCnt /= "100"
			and sysCycleCnt /= "111" then	-- PAL 34 + 3/8
				sysCycle <= CYCLE_CPU8;
			else
				sysCycle <= sysCycleDef'succ(sysCycle);
			end if;
		end if;
	end process;

	iecClock: process(clk32)
	begin
		if rising_edge(clk32) then
			serioclk <= '1';
			if sysCycle = CYCLE_IEC0
			or sysCycle = CYCLE_IEC1 then
				serioclk <= '0'; --for iec write
			end if;	
		end if;
	end process;

	sidClock: process(clk32)
	begin
		if rising_edge(clk32) then
			-- Toggle SIDclk early to compensate for the delay caused by the gbridge
			if sysCycle = CYCLE_VIC3 then
				SIDclk <= '1';
			end if;
			if sysCycle = CYCLE_CPUD then
				SIDclk <= '0';
			end if;
		end if;
	end process;

	-- PHI0/2-clock emulation
	process(clk32)
	begin
		if rising_edge(clk32) then
			if sysCycle = sysCycleDef'pred(CYCLE_CPU0) then
				phi0_cpu <= '1';
				if baLoc = '1' or cpuWe = '1' then
					cpuHasBus <= '1';
				end if;
			end if;
			if sysCycle = sysCycleDef'high then
				phi0_cpu <= '0';
				cpuHasBus <= '0';
			end if;
			if sysCycle = sysCycleDef'pred(CYCLE_VIC0) then
				phi0_vic <= '1';
			end if;
			if sysCycle = CYCLE_VIC3 then
				phi0_vic <= '0';
			end if;
		end if;
	end process;

	process(clk32)
	begin
		if rising_edge(clk32) then
			enableVic <= '0';
			enableCia <= '0';
			enableCpu <= '0';

			case sysCycle is
			when CYCLE_VIC2 =>
				enableVic <= '1';
			when CYCLE_CPUE =>
				enableCia <= '1';
				enableVic <= '1';
				if baLoc = '1'
				or cpuWe = '1' then
					enableCpu <= '1';
				end if;
			when others =>
				null;
			end case;
		end if;
	end process;
	
	
-- -----------------------------------------------------------------------
-- Cartridge clocks
-- -----------------------------------------------------------------------
	process(sysclk)
	begin
		if rising_edge(sysclk) then
			cycleRestartReg1 <= cycleRestart;
			cycleRestartReg2 <= cycleRestartReg1;
			cycleRestartEdge <= cycleRestartReg2;

			dotClkCnt <= dotClkCnt + 1;
			if dotClkCnt = 6 then
				dotClkReg <= not dotClkReg;
				dotClkCnt <= 0;
				if ntscMode = '1'
				or dotClkReg = '1' then
					dotClkCnt <= 1;
				end if;
			end if;
			if cycleRestartReg2 = '1'
			and cycleRestartEdge = '0' then
				dotClkReg <= '1';
				dotClkCnt <= 0;
			end if;
		end if;
	end process;
	dot_clk <= dotClkReg;
	cpu_clk <= phi0_cpu;

-- -----------------------------------------------------------------------
-- Scan-converter and VGA output
-- -----------------------------------------------------------------------
	myScanConverter: entity work.fpga64_cone_scanconverter
		generic map (
			videoWidth => 4
		)
		port map (
			clk => clk32,
			cyclesPerLine => cyclesPerLine,
			faster => scanConverterFaster,
			hSyncPolarity => '0',
			vSyncPolarity => '0',
			enable_in => enablePixel,
			video_in => vicColorIndex,
			hsync_in => vicHSync,
			vsync_in => vicVSync,
			video_out => vgaColorIndex,
			hsync_out => vgaHSync,
			vsync_out => vgaVSync			
		);
	
	cyclesPerLine <= to_unsigned(1080, 12) when ntscMode = '0' else to_unsigned(1088,12);
	scanConverterFaster <= not ntscMode;
	
	c64colors: entity work.fpga64_rgbcolor
		port map (
			index => vgaColorIndex,
			r => vgaR,
			g => vgaG,
			b => vgaB
		);

	process(clk32)
	begin
		if rising_edge(clk32) then
			r <= vgaR;
			g <= vgaG;
			b <= vgaB;
--			if videoConfigShow = '1' and videoConfigDim = '1' then
--			if videoConfigDim = '1' then
--				r <= videoConfigVideo & vgaR(7 downto 1);
--				g <= videoConfigVideo & vgaG(7 downto 1);
--				b <= videoConfigVideo & vgaB(7 downto 1);
--			end if;
--			if vgaDebugDim = '1' then
--				r <= vgaDebug & vgaR(7 downto 1);
--				g <= vgaDebug & vgaG(7 downto 1);
--				b <= vgaDebug & vgaB(7 downto 1);
--			end if;				
		end if;
	end process;
	hSync <= vgaHSync;
	vSync <= vgaVSync;

-- -----------------------------------------------------------------------
-- Color RAM
-- -----------------------------------------------------------------------
	colorram: entity work.gen_ram
		generic map (
			dWidth => 4,
			aWidth => 10
		)
		port map (
			clk => clk32,
			we => colorWe,
			addr => systemAddr(9 downto 0),
			d => cpuDo(3 downto 0),
			q => colorQ
		);

	process(clk32)
	begin
		if rising_edge(clk32) then
			colorWe <= (cs_color and pulseWrRam);
			colorData <= colorQ;
		end if;
	end process;


-- -----------------------------------------------------------------------
-- PLA and bus-switches
-- -----------------------------------------------------------------------
	buslogic: entity work.fpga64_buslogic
		port map (
			clk => clk32,
			reset => reset,
			cpuHasBus => cpuHasBus,

			bankSwitch => cpuIO(2 downto 0),

			game => game,
			exrom => exrom,

			ramData => ramDataReg,

			cpuWe => cpuWe,
			cpuAddr => cpuAddr,
			cpuData => cpuDo,

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -