--------------------------------------------------------------------------- -- (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_ARITH.ALL; USE IEEE.STD_LOGIC_UNSIGNED.ALL; LIBRARY work; ENTITY atari5200core_mcc IS GENERIC ( TV : integer; -- 1 = PAL, 0=NTSC internal_rom : integer; internal_ram : integer; ext_clock : integer ); PORT ( FPGA_CLK : IN STD_LOGIC; -- crystal appears to be still 5MHz despite comment in file I was sent... -- For test bench EXT_CLK_SDRAM : in std_logic_vector(ext_clock downto 1); EXT_CLK : in std_logic_vector(ext_clock downto 1); EXT_SDRAM_CLK : in std_logic_vector(ext_clock downto 1); EXT_SVIDEO_DAC_CLK : in std_logic_vector(ext_clock downto 1); EXT_PLL_LOCKED : in std_logic_vector(ext_clock downto 1); --PS2K_CLK : IN STD_LOGIC; --PS2K_DAT : IN STD_LOGIC; --PS2M_CLK : IN STD_LOGIC; --PS2M_DAT : IN STD_LOGIC; -- VGA/cough cough... (composite...) --VGA_VS : OUT STD_LOGIC; --VGA_HS : OUT STD_LOGIC; VGA_B : OUT STD_LOGIC_VECTOR(3 DOWNTO 0); -- high bits composite VGA_G : OUT STD_LOGIC_VECTOR(3 DOWNTO 0); -- low bits composite --VGA_R : OUT STD_LOGIC_VECTOR(3 DOWNTO 0); --JOY1_n : IN STD_LOGIC_VECTOR(5 DOWNTO 0); --JOY2_n : IN STD_LOGIC_VECTOR(5 DOWNTO 0); ----USB CONNECTIONS (with one 1.5K pull up to 3.3v) --------------- dplus1 : inout std_logic; --D+ data line , pin D16 dminus1 : inout std_logic; --D- data line, pin E14 ----USB CONNECTIONS (with one 1.5K pull up to 3.3v) --------------- dplus2 : inout std_logic; --D+ data line , pin D16 dminus2 : inout std_logic; --D- data line, pin E14 AUDIO_L : OUT std_logic; AUDIO_R : OUT std_logic; SDRAM_BA : OUT STD_LOGIC_VECTOR(1 downto 0); SDRAM_CS_N : OUT STD_LOGIC; SDRAM_RAS_N : OUT STD_LOGIC; SDRAM_CAS_N : OUT STD_LOGIC; SDRAM_WE_N : OUT STD_LOGIC; SDRAM_DQMH_n : OUT STD_LOGIC; SDRAM_DQML_n : OUT STD_LOGIC; SDRAM_CLK : OUT STD_LOGIC; SDRAM_CKE : OUT STD_LOGIC; SDRAM_A : OUT STD_LOGIC_VECTOR(12 DOWNTO 0); SDRAM_DQ : INOUT STD_LOGIC_VECTOR(15 DOWNTO 0); SD_DAT0 : IN STD_LOGIC; SD_CLK : OUT STD_LOGIC; SD_CMD : OUT STD_LOGIC; SD_DAT3 : OUT STD_LOGIC; -- SPI flash clock CFG_CLK : OUT STD_LOGIC; CFG_CS_n : OUT STD_LOGIC; CFG_DOUT : OUT STD_LOGIC; CFG_DIN : IN STD_LOGIC ); END atari5200core_mcc; ARCHITECTURE vhdl OF atari5200core_mcc IS component hq_dac port ( reset :in std_logic; clk :in std_logic; clk_ena : in std_logic; pcm_in : in std_logic_vector(19 downto 0); dac_out : out std_logic ); end component; COMPONENT sdram_ctrl port ( --//-------------------- --// Clocks and reset -- --//-------------------- --// Global reset rst : in std_logic; --// Controller clock clk : in std_logic; --// Sequencer cycles seq_cyc : in std_logic_vector(11 downto 0); --// Sequencer phase seq_ph : in std_logic; --// Refresh cycle refr_cyc : in std_logic; --//------------------------ --// Access port #1 (CPU) -- --//------------------------ --// RAM select ap1_ram_sel : in std_logic; --// Address bus ap1_address : in std_logic_vector(23 downto 1); --// Read enable ap1_rden : in std_logic; --// Write enable ap1_wren : in std_logic; --// Byte enable ap1_bena : in std_logic_vector(1 downto 0); --// Data bus (read) ap1_rddata : out std_logic_vector(15 downto 0); --// Data bus (write) ap1_wrdata : in std_logic_vector(15 downto 0); --// Burst size ap1_bst_siz : in std_logic_vector(2 downto 0); --// Read burst active ap1_rd_bst_act : out std_logic; --// Write burst active ap1_wr_bst_act : out std_logic; --//------------------------ --// Access port #2 (GPU) -- --//------------------------ --// RAM select ap2_ram_sel : in std_logic; --// Address bus ap2_address : in std_logic_vector(23 downto 1); --// Read enable ap2_rden : in std_logic; --// Write enable ap2_wren : in std_logic; --// Byte enable ap2_bena : in std_logic_vector(1 downto 0); --// Data bus (read) ap2_rddata : out std_logic_vector(15 downto 0); --// Data bus (write) ap2_wrdata : in std_logic_vector(15 downto 0); --// Burst size ap2_bst_siz : in std_logic_vector(2 downto 0); --// Read burst active ap2_rd_bst_act : out std_logic; --// Write burst active ap2_wr_bst_act : out std_logic; --//------------------------ --// Access port #3 (CTL) -- --//------------------------ --// RAM select ap3_ram_sel : in std_logic; --// Address bus ap3_address : in std_logic_vector(23 downto 1); --// Read enable ap3_rden : in std_logic; --// Write enable ap3_wren : in std_logic; --// Byte enable ap3_bena : in std_logic_vector(1 downto 0); --// Data bus (read) ap3_rddata : out std_logic_vector(15 downto 0); --// Data bus (write) ap3_wrdata : in std_logic_vector(15 downto 0); --// Burst size ap3_bst_siz : in std_logic_vector(2 downto 0); --// Read burst active ap3_rd_bst_act : out std_logic; --// Write burst active ap3_wr_bst_act : out std_logic; --//------------------------ --// SDRAM memory signals -- --//------------------------ --// SDRAM controller ready sdram_rdy : out std_logic; --// SDRAM chip select sdram_cs_n : out std_logic; --// SDRAM row address strobe sdram_ras_n : out std_logic; --// SDRAM column address strobe sdram_cas_n : out std_logic; --// SDRAM write enable sdram_we_n : out std_logic; --// SDRAM DQ masks sdram_dqm_n : out std_logic_vector(1 downto 0); --// SDRAM bank address sdram_ba : out std_logic_vector(1 downto 0); --// SDRAM address sdram_addr : out std_logic_vector(11 downto 0); --// SDRAM data sdram_dq_oe : out std_logic; sdram_dq_o : out std_logic_vector(15 downto 0); sdram_dq_i : in std_logic_vector(15 downto 0) ); END COMPONENT; signal AUDIO_L_PCM : std_logic_vector(15 downto 0); signal AUDIO_R_PCM : std_logic_vector(15 downto 0); signal VIDEO_CS : std_logic; signal VIDEO_VS : std_logic; signal VIDEO_R : std_logic_vector(7 downto 0); signal VIDEO_G : std_logic_vector(7 downto 0); signal VIDEO_B : std_logic_vector(7 downto 0); signal VIDEO_BLANK : std_logic; signal VIDEO_BURST : std_logic; signal VIDEO_START_OF_FIELD : std_logic; signal VIDEO_ODD_LINE : std_logic; signal JOY1 : std_logic_vector(5 downto 0); signal JOY2 : std_logic_vector(5 downto 0); signal JOY1_n : std_logic_vector(4 downto 0); signal JOY2_n : std_logic_vector(4 downto 0); signal PLL1_LOCKED : std_logic; signal CLK_PLL1 : std_logic; signal RESET_n : std_logic; signal PLL_LOCKED : std_logic; signal CLK : std_logic; signal CLK_SDRAM : std_logic; -- SDRAM signal PREREG_SDRAM_REQUEST : std_logic; signal PREREG_SDRAM_READ_ENABLE : STD_LOGIC; signal PREREG_SDRAM_WRITE_ENABLE : std_logic; signal PREREG_SDRAM_ADDR : STD_LOGIC_VECTOR(22 DOWNTO 0); SIGNAL PREREG_SDRAM_DI : std_logic_vector(31 downto 0); SIGNAL PREREG_SDRAM_WIDTH_32BIT_ACCESS : std_logic; SIGNAL PREREG_SDRAM_WIDTH_16BIT_ACCESS : std_logic; SIGNAL PREREG_SDRAM_WIDTH_8BIT_ACCESS : std_logic; signal SDRAM_REQUEST : std_logic; signal SDRAM_READ_ENABLE : STD_LOGIC; signal SDRAM_WRITE_ENABLE : std_logic; signal SDRAM_ADDR : STD_LOGIC_VECTOR(22 DOWNTO 0); SIGNAL SDRAM_DI : std_logic_vector(31 downto 0); SIGNAL SDRAM_WIDTH_32BIT_ACCESS : std_logic; SIGNAL SDRAM_WIDTH_16BIT_ACCESS : std_logic; SIGNAL SDRAM_WIDTH_8BIT_ACCESS : std_logic; signal SDRAM_REQUEST_COMPLETE : std_logic; signal SDRAM_REFRESH : std_logic; signal SYSTEM_RESET_REQUEST: std_logic; signal seq_reg : std_logic_vector(11 downto 0); signal seq_next : std_logic_vector(11 downto 0); signal seq_ph_reg : std_logic; signal seq_ph_next : std_logic; signal ref_reg : std_logic; signal ref_next : std_logic; signal sdram_request_complete_next : std_logic; signal sdram_request_complete_reg : std_logic; signal sdram_request_next : std_logic; signal sdram_request_reg : std_logic; signal ram_di_next : std_logic_vector(15 downto 0); signal ram_di_reg : std_logic_vector(15 downto 0); signal ram_do_next : std_logic_vector(31 downto 0); signal ram_do_reg : std_logic_vector(31 downto 0); signal ram_do : std_logic_vector(15 downto 0); signal ram_bena_next : std_logic_vector(1 downto 0); signal ram_bena_reg : std_logic_vector(1 downto 0); signal ram_rd_active : std_logic; signal ram_wr_active : std_logic; signal sdram_dq_oe : std_logic; signal sdram_dq_o : std_logic_vector(15 downto 0); signal sdram_dq_i : std_logic_vector(15 downto 0); signal sdram_dqm_n_temp : std_logic_vector(1 downto 0); signal sdram_rdy : std_logic; signal sdram_reset_ctrl_n_next : std_logic; signal sdram_reset_ctrl_n_reg : std_logic; signal sdram_reset_n_next : std_logic; signal sdram_reset_n_reg : std_logic; -- pokey keyboard SIGNAL KEYBOARD_SCAN : std_logic_vector(5 downto 0); SIGNAL KEYBOARD_RESPONSE : std_logic_vector(1 downto 0); signal controller_select : std_logic_vector(1 downto 0); -- gtia consol keys SIGNAL FKEYS : std_logic_vector(11 downto 0); -- svideo signal svideo_dac_clk : std_logic; signal svideo_y : std_logic_vector(7 downto 0); signal svideo_c : std_logic_vector(5 downto 0); -- composite SIGNAL svideo_yout : STD_LOGIC_VECTOR(7 DOWNTO 0); SIGNAL svideo_yout_dly1 : STD_LOGIC_VECTOR(7 DOWNTO 0); SIGNAL svideo_yout_dly2 : STD_LOGIC_VECTOR(7 DOWNTO 0); SIGNAL svideo_yout_dly3 : STD_LOGIC_VECTOR(7 DOWNTO 0); --SIGNAL svideo_cout : STD_LOGIC_VECTOR(7 DOWNTO 0); SIGNAL cvbs1_out : STD_LOGIC_VECTOR(9 DOWNTO 0); SIGNAL cvbs2_out : STD_LOGIC_VECTOR(7 DOWNTO 0); SIGNAL luma : STD_LOGIC_VECTOR(9 DOWNTO 0); SIGNAL chroma : STD_LOGIC_VECTOR(8 DOWNTO 0); SIGNAL luma_saturated : STD_LOGIC_VECTOR(9 DOWNTO 0); -- dma/virtual drive signal DMA_ADDR_FETCH : std_logic_vector(23 downto 0); signal DMA_WRITE_DATA : std_logic_vector(31 downto 0); signal DMA_FETCH : std_logic; signal DMA_32BIT_WRITE_ENABLE : std_logic; signal DMA_16BIT_WRITE_ENABLE : std_logic; signal DMA_8BIT_WRITE_ENABLE : std_logic; signal DMA_READ_ENABLE : std_logic; signal DMA_MEMORY_READY : std_logic; signal DMA_MEMORY_DATA : std_logic_vector(31 downto 0); signal ZPU_ADDR_ROM : std_logic_vector(15 downto 0); signal ZPU_ROM_DATA : std_logic_vector(31 downto 0); signal ZPU_OUT1 : std_logic_vector(31 downto 0); signal ZPU_OUT2 : std_logic_vector(31 downto 0); signal ZPU_OUT3 : std_logic_vector(31 downto 0); signal ZPU_OUT4 : std_logic_vector(31 downto 0); signal ZPU_OUT5 : std_logic_vector(31 downto 0); signal zpu_pokey_enable : std_logic; signal zpu_sio_txd : std_logic; signal zpu_sio_rxd : std_logic; signal zpu_sio_command : std_logic; -- system control from zpu signal ram_select : std_logic_vector(2 downto 0); signal reset_atari : std_logic; signal pause_atari : std_logic; SIGNAL speed_6502 : std_logic_vector(5 downto 0); signal emulated_cartridge_select: std_logic_vector(5 downto 0); -- usb signal CLK_USB : std_logic; signal USBWireVPin : std_logic_vector(1 downto 0); signal USBWireVMin : std_logic_vector(1 downto 0); signal USBWireVPout : std_logic_vector(1 downto 0); signal USBWireVMout : std_logic_vector(1 downto 0); signal USBWireOE_n : std_logic_vector(1 downto 0); signal PS2_KEYS : STD_LOGIC_VECTOR(511 downto 0); signal PS2_KEYS_NEXT : STD_LOGIC_VECTOR(511 downto 0); -- paddles signal JOY1X : std_logic_vector(7 downto 0); signal JOY1Y : std_logic_vector(7 downto 0); signal JOY2X : std_logic_vector(7 downto 0); signal JOY2Y : std_logic_vector(7 downto 0); BEGIN -- disable flash (not used) CFG_CLK <= 'Z'; CFG_CS_n <= '1'; CFG_DOUT <= 'Z'; -- usb --dplus1 <= USBWireVPout(0) when USBWireOE_n(0)='0' else 'Z'; --dminus1 <= USBWireVMout(0) when USBWireOE_n(0)='0' else 'Z'; --USBWireVPin(0) <= dplus1; --USBWireVMin(0) <= dminus1; -- --dplus2 <= USBWireVPout(1) when USBWireOE_n(1)='0' else 'Z'; --dminus2 <= USBWireVMout(1) when USBWireOE_n(1)='0' else 'Z'; --USBWireVPin(1) <= dplus2; --USBWireVMin(1) <= dminus2; dplus2 <= USBWireVMout(0) when USBWireOE_n(0)='0' else 'Z'; dminus2 <= USBWireVPout(0) when USBWireOE_n(0)='0' else 'Z'; USBWireVMin(0) <= dplus2; USBWireVPin(0) <= dminus2; dplus1 <= USBWireVMout(1) when USBWireOE_n(1)='0' else 'Z'; dminus1 <= USBWireVPout(1) when USBWireOE_n(1)='0' else 'Z'; USBWireVMin(1) <= dplus1; USBWireVPin(1) <= dminus1; usb_pll : entity work.usbpll PORT MAP(inclk0 => FPGA_CLK, c0 => CLK_USB, locked => open); dac_left : hq_dac port map ( reset => not(reset_n), clk => clk, clk_ena => '1', pcm_in => AUDIO_L_PCM&"0000", dac_out => audio_l ); dac_right : hq_dac port map ( reset => not(reset_n), clk => clk, clk_ena => '1', pcm_in => AUDIO_R_PCM&"0000", dac_out => audio_r ); gen_fake_pll : if ext_clock=1 generate CLK_SDRAM <= EXT_CLK_SDRAM(1); CLK <= EXT_CLK(1); SDRAM_CLK <= EXT_CLK_SDRAM(1); SVIDEO_DAC_CLK <= EXT_SVIDEO_DAC_CLK(1); --SCANDOUBLE_CLK <= EXT_SCANDOUBLE_CLK(1); PLL_LOCKED <= EXT_PLL_LOCKED(1); end generate; gen_real_pll : if ext_clock=0 generate gen_tv_ntsc : if tv=0 generate mcc_pll : entity work.ntsc_pll PORT MAP(inclk0 => FPGA_CLK, c0 => CLK_PLL1, locked => PLL1_LOCKED); mcc_pll2 : entity work.pll_downstream_ntsc PORT MAP(inclk0 => CLK_PLL1, c0 => CLK_SDRAM, c1 => CLK, c2 => SDRAM_CLK, c3 => SVIDEO_DAC_CLK, c4 => open, --SCANDOUBLE_CLK, areset => not(PLL1_LOCKED), locked => PLL_LOCKED); end generate; end generate; reset_n <= PLL_LOCKED; -- PS2 to pokey keyboard_map1 : entity work.ps2_to_atari5200 GENERIC MAP ( ps2_enable => 0, direct_enable => 1 ) PORT MAP ( CLK => clk, RESET_N => reset_n, INPUT => zpu_out4, FIRE2 => '0'&'0'&joy2(4)&joy1(4), CONTROLLER_SELECT => CONTROLLER_SELECT, -- selected stick keyboard/shift button KEYBOARD_SCAN => KEYBOARD_SCAN, KEYBOARD_RESPONSE => KEYBOARD_RESPONSE, FKEYS => FKEYS, PS2_KEYS_NEXT_OUT => ps2_keys_next, PS2_KEYS => ps2_keys ); JOY1 <= zpu_out2(5 downto 4)&zpu_out2(0)&zpu_out2(1)&zpu_out2(2)&zpu_out2(3); JOY2 <= zpu_out3(5 downto 4)&zpu_out3(0)&zpu_out3(1)&zpu_out3(2)&zpu_out3(3); JOY1X <= zpu_out5(7 downto 0); JOY1Y <= zpu_out5(15 downto 8); JOY2X <= zpu_out5(23 downto 16); JOY2Y <= zpu_out5(31 downto 24); return_to_boot_menu : entity work.delayed_reconfig PORT MAP ( CLK_5MHZ => FPGA_CLK, RESET_N => RESET_N, RECONFIG_BUTTON => (FKEYS(1) or FKEYS(4)) ); atari5200_simple_sdram1 : entity work.atari5200core_simplesdram GENERIC MAP ( cycle_length => 16, internal_rom => 0, --internal_rom, internal_ram => 0, --internal_ram, video_bits => 8, palette => 1 ) PORT MAP ( CLK => CLK, --RESET_N => RESET_N and SDRAM_RESET_N and not(SYSTEM_RESET_REQUEST), RESET_N => RESET_N and SDRAM_RESET_N_REG, VIDEO_VS => VIDEO_VS, VIDEO_HS => open, VIDEO_CS => VIDEO_CS, VIDEO_B => VIDEO_B, VIDEO_G => VIDEO_G, VIDEO_R => VIDEO_R, VIDEO_BLANK =>VIDEO_BLANK, VIDEO_BURST =>VIDEO_BURST, VIDEO_START_OF_FIELD =>VIDEO_START_OF_FIELD, VIDEO_ODD_LINE =>VIDEO_ODD_LINE, AUDIO_L => AUDIO_L_PCM, AUDIO_R => AUDIO_R_PCM, SDRAM_REQUEST => PREREG_SDRAM_REQUEST, SDRAM_REQUEST_COMPLETE => SDRAM_REQUEST_COMPLETE, SDRAM_READ_ENABLE => PREREG_SDRAM_READ_ENABLE, SDRAM_WRITE_ENABLE => PREREG_SDRAM_WRITE_ENABLE, SDRAM_ADDR => PREREG_SDRAM_ADDR, SDRAM_DO => ram_do_reg, SDRAM_DI => PREREG_SDRAM_DI, SDRAM_32BIT_WRITE_ENABLE => PREREG_SDRAM_WIDTH_32bit_ACCESS, SDRAM_16BIT_WRITE_ENABLE => PREREG_SDRAM_WIDTH_16bit_ACCESS, SDRAM_8BIT_WRITE_ENABLE => PREREG_SDRAM_WIDTH_8bit_ACCESS, SDRAM_REFRESH => SDRAM_REFRESH, DMA_FETCH => dma_fetch, DMA_READ_ENABLE => dma_read_enable, DMA_32BIT_WRITE_ENABLE => dma_32bit_write_enable, DMA_16BIT_WRITE_ENABLE => dma_16bit_write_enable, DMA_8BIT_WRITE_ENABLE => dma_8bit_write_enable, DMA_ADDR => dma_addr_fetch, DMA_WRITE_DATA => dma_write_data, MEMORY_READY_DMA => dma_memory_ready, DMA_MEMORY_DATA => dma_memory_data, THROTTLE_COUNT_6502 => speed_6502, HALT => pause_atari, -- JOYSTICK JOY1_X => signed(joy1x), JOY1_Y => signed(joy1y), JOY1_N => not(joy1(5)&joy1(3 downto 0)), JOY2_X => signed(joy2x), JOY2_Y => signed(joy2y), JOY2_N => not(joy2(5)&joy2(3 downto 0)), -- Pokey keyboard matrix -- Standard component available to connect this to PS2 KEYBOARD_RESPONSE => KEYBOARD_RESPONSE, KEYBOARD_SCAN => KEYBOARD_SCAN, CONTROLLER_SELECT => CONTROLLER_SELECT ); process(clk_sdram,sdram_reset_ctrl_n_reg) begin if (sdram_reset_ctrl_n_reg='0') then seq_reg <= "010000000000"; seq_ph_reg <= '1'; ref_reg <= '0'; ram_do_reg <= (others=>'0'); ram_di_reg <= (others=>'0'); ram_bena_reg <= (others=>'0'); sdram_request_complete_reg <= '0'; sdram_request_reg <= '0'; elsif (clk_sdram'event and clk_sdram = '1') then seq_reg <= seq_next; seq_ph_reg <= seq_ph_next; ref_reg <= ref_next; ram_do_reg <= ram_do_next; ram_di_reg <= ram_di_next; ram_bena_reg <= ram_bena_next; sdram_request_complete_reg <= sdram_request_complete_next; sdram_request_reg <= sdram_request_next; end if; end process; process(clk,reset_n) begin if (reset_n='0') then sdram_reset_n_reg <= '0'; sdram_reset_ctrl_n_reg <= '0'; elsif (clk'event and clk = '1') then sdram_reset_n_reg <= sdram_reset_n_next; sdram_reset_ctrl_n_reg <= reset_n; end if; end process; -- Generate sdram sequence process(seq_reg, seq_ph_reg, ref_reg) begin seq_next <= seq_reg(10 downto 0)&seq_reg(11); seq_ph_next <= seq_ph_reg; ref_next <= ref_reg; if (seq_reg(11) = '1') then seq_ph_next <= not(seq_ph_reg); ref_next <= not(ref_reg); end if; end process; process(seq_reg, seq_next, sdram_rdy, sdram_reset_n_reg, reset_atari) begin sdram_reset_n_next <= sdram_reset_n_reg; if (sdram_rdy = '1' and seq_next(7)='1' and seq_reg(7)='0') then sdram_reset_n_next <= '1'; end if; if (reset_atari = '1') then sdram_reset_n_next <= '0'; end if; end process; -- register sdram request on the falling edge, 1/3 timing not enough, but 1/2 timing should be... This pushes back request 1 clock cycle. Result can also be clocking on the falling edge! process(clk,reset_n) begin if (reset_n='0') then SDRAM_REQUEST <= '0'; SDRAM_READ_ENABLE <= '0'; SDRAM_WRITE_ENABLE <= '0'; SDRAM_ADDR <= (others=>'0'); SDRAM_DI <= (others=>'0'); SDRAM_WIDTH_32BIT_ACCESS <= '0'; SDRAM_WIDTH_16BIT_ACCESS <= '0'; SDRAM_WIDTH_8BIT_ACCESS <= '0'; elsif(clk'event and clk='0') then -- FALLING EDGE SDRAM_REQUEST <= PREREG_SDRAM_REQUEST; SDRAM_READ_ENABLE <= PREREG_SDRAM_READ_ENABLE; SDRAM_WRITE_ENABLE <= PREREG_SDRAM_WRITE_ENABLE; SDRAM_ADDR <= PREREG_SDRAM_ADDR; SDRAM_DI <= PREREG_SDRAM_DI; SDRAM_WIDTH_32BIT_ACCESS <= PREREG_SDRAM_WIDTH_32BIT_ACCESS; SDRAM_WIDTH_16BIT_ACCESS <= PREREG_SDRAM_WIDTH_16BIT_ACCESS; SDRAM_WIDTH_8BIT_ACCESS <= PREREG_SDRAM_WIDTH_8BIT_ACCESS; end if; end process; -- Adapt SDRAM process(sdram_request_reg, sdram_request, sdram_request_complete_reg, ram_do_reg, seq_reg, ram_do, ram_rd_active, ram_wr_active, SDRAM_WIDTH_8BIT_ACCESS, SDRAM_WRITE_ENABLE, SDRAM_READ_ENABLE, SDRAM_DI, SDRAM_ADDR) begin sdram_request_next <= (sdram_request_reg or sdram_request) and not(sdram_request_complete_reg); sdram_request_complete_next <= sdram_request_complete_reg; ram_bena_next <= "00"; ram_di_next <= (others=>'0'); ram_do_next <= ram_do_reg; case seq_reg is when "000000000001" => -- nop when "000000000010" => -- write data from next... if (SDRAM_WRITE_ENABLE = '1') then if (SDRAM_WIDTH_8BIT_ACCESS = '1') then ram_di_next <= SDRAM_DI(7 downto 0)&SDRAM_DI(7 downto 0); ram_bena_next <= SDRAM_ADDR(0)¬(SDRAM_ADDR(0)); else ram_di_next <= SDRAM_DI(15 downto 0); ram_bena_next <= "11"; end if; end if; when "000000000100" => if (SDRAM_WRITE_ENABLE = '1') then if (SDRAM_WIDTH_8BIT_ACCESS = '1') then ram_di_next <= (others=>'0'); else ram_di_next <= SDRAM_DI(31 downto 16); ram_bena_next <= "11"; end if; end if; if ((ram_wr_active)='1') then sdram_request_complete_next <= '1'; sdram_request_next <= '0'; end if; when "000000001000" => -- nop when "000000010000" => -- nop when "000000100000" => sdram_request_complete_next <= '0'; -- nop when "000001000000" => if (SDRAM_READ_ENABLE = '1') then if (SDRAM_WIDTH_8BIT_ACCESS = '1') then if (SDRAM_ADDR(0) = '0') then ram_do_next(15 downto 0) <= ram_do(7 downto 0)&ram_do(7 downto 0); else ram_do_next(15 downto 0) <= ram_do(15 downto 8)&ram_do(15 downto 8); end if; else ram_do_next(15 downto 0) <= ram_do; end if; end if; when "000010000000" => if (SDRAM_READ_ENABLE = '1') then if (SDRAM_WIDTH_8BIT_ACCESS = '1') then ram_do_next(31 downto 16) <= (others=>'0'); else ram_do_next(31 downto 16) <= ram_do; end if; end if; if ((ram_rd_active)='1') then sdram_request_complete_next <= '1'; sdram_request_next <= '0'; end if; when "000100000000" => -- nop when "001000000000" => -- nop when "010000000000" => -- nop when "100000000000" => sdram_request_complete_next <= '0'; -- nop when others => -- never end case; end process; SDRAM_REQUEST_COMPLETE <= SDRAM_REQUEST_COMPLETE_REG; sdram_controller : sdram_ctrl PORT MAP ( CLK => CLK_SDRAM, rst => not(sdram_reset_ctrl_n_reg), seq_cyc => seq_reg(11 downto 0), seq_ph => seq_ph_reg, --refr_cyc => ref_reg, refr_cyc => SDRAM_REFRESH, ap1_ram_sel => SDRAM_REQUEST_NEXT, ap1_address => '0'&SDRAM_ADDR(22 downto 1), ap1_rden => SDRAM_READ_ENABLE, ap1_wren => SDRAM_WRITE_ENABLE, ap1_bena => ram_bena_reg, ap1_rddata => ram_do, ap1_wrdata => ram_di_reg, ap1_bst_siz => "001", ap1_rd_bst_act => ram_rd_active, ap1_wr_bst_act => ram_wr_active, ap2_ram_sel => '0', ap2_address => "00000000000000000000000", ap2_rden => '0', ap2_wren => '0', ap2_bena => "11", ap2_rddata => open, ap2_wrdata => X"0000", ap2_bst_siz => "111", ap2_rd_bst_act => open, ap2_wr_bst_act => open, ap3_ram_sel => '0', ap3_address => "00000000000000000000000", ap3_rden => '0', ap3_wren => '0', ap3_bena => "11", ap3_rddata => open, ap3_wrdata => X"0000", ap3_bst_siz => "111", ap3_rd_bst_act => open, ap3_wr_bst_act => open, sdram_rdy => sdram_rdy, sdram_cs_n => sdram_cs_n, sdram_ras_n => sdram_ras_n, sdram_cas_n => sdram_cas_n, sdram_we_n => sdram_we_n, sdram_dqm_n => sdram_dqm_n_temp, sdram_ba => sdram_ba, sdram_addr => sdram_a(11 downto 0), sdram_dq_oe => sdram_dq_oe, sdram_dq_o => sdram_dq_o, sdram_dq_i => sdram_dq_i ); sdram_dqmh_n <= sdram_dqm_n_temp(1); sdram_dqml_n <= sdram_dqm_n_temp(0); sdram_dq <= sdram_dq_o when sdram_dq_oe='1' else (others=>'Z'); sdram_dq_i <= sdram_dq; sdram_a(12) <= '1'; sdram_cke <= '1'; -- Video options -- SVIDEO COMPONENT svideo : entity work.svideo PORT MAP ( areset_n => RESET_N, ecs_clk => CLK, dac_clk => SVIDEO_DAC_CLK, r_in => VIDEO_R, g_in => VIDEO_G, b_in => VIDEO_B, sof => VIDEO_VS, -- base on vsync? vpos_lsb => VIDEO_ODD_LINE, blank => VIDEO_BLANK, burst => VIDEO_BURST, csync_n => not(VIDEO_CS), y_out => svideo_yout, c_out => open, luma_out => luma, chroma_out => chroma, pal_ntsc => not('0') ); zpu: entity work.zpucore GENERIC MAP ( platform => 1, spi_clock_div => 1, -- 28MHz/2. Max for SD cards is 25MHz... memory => 8192, usb => 2, nMHz_clock_div => 48 ) PORT MAP ( -- standard... CLK => CLK, RESET_N => RESET_N and sdram_rdy, -- dma bus master (with many waitstates...) ZPU_ADDR_FETCH => dma_addr_fetch, ZPU_DATA_OUT => dma_write_data, ZPU_FETCH => dma_fetch, ZPU_32BIT_WRITE_ENABLE => dma_32bit_write_enable, ZPU_16BIT_WRITE_ENABLE => dma_16bit_write_enable, ZPU_8BIT_WRITE_ENABLE => dma_8bit_write_enable, ZPU_READ_ENABLE => dma_read_enable, ZPU_MEMORY_READY => dma_memory_ready, ZPU_MEMORY_DATA => dma_memory_data, -- rom bus master -- data on next cycle after addr ZPU_ADDR_ROM => zpu_addr_rom, ZPU_ROM_DATA => zpu_rom_data, -- spi master -- Too painful to bit bang spi from zpu, so we have a hardware master in here ZPU_SPI_DI => sd_dat0, ZPU_SPI_CLK => sd_clk, ZPU_SPI_DO => sd_cmd, ZPU_SPI_SELECT0 => sd_dat3, ZPU_SPI_SELECT1 => open, -- SIO -- Ditto for speaking to Atari, we have a built in Pokey ZPU_POKEY_ENABLE => zpu_pokey_enable, ZPU_SIO_TXD => zpu_sio_txd, ZPU_SIO_RXD => zpu_sio_rxd, ZPU_SIO_COMMAND => zpu_sio_command, ZPU_SIO_CLK => '0', -- external control -- switches etc. sector DMA blah blah. ZPU_IN1 => X"000"& "00"&ps2_keys(16#76#)&ps2_keys(16#5A#)&ps2_keys(16#174#)&ps2_keys(16#16B#)&ps2_keys(16#172#)&ps2_keys(16#175#)& -- (esc)FLRDU FKEYS, ZPU_IN2 => X"00000000", ZPU_IN3 => X"00000000", ZPU_IN4 => X"00000000", -- ouputs - e.g. Atari system control, halt, throttle, rom select ZPU_OUT1 => zpu_out1, --misc ZPU_OUT2 => zpu_out2, --joy0 ZPU_OUT3 => zpu_out3, --joy1 ZPU_OUT4 => zpu_out4, --keyboard ZPU_OUT5 => zpu_out5, --analog stick -- USB host CLK_nMHz => CLK_USB, CLK_USB => CLK_USB, USBWireVPin => USBWireVPin, USBWireVMin => USBWireVMin, USBWireVPout => USBWireVPout, USBWireVMout => USBWireVMout, USBWireOE_n => USBWireOE_n ); pause_atari <= zpu_out1(0); reset_atari <= zpu_out1(1); speed_6502 <= zpu_out1(7 downto 2); ram_select <= zpu_out1(10 downto 8); zpu_rom1: entity work.zpu_rom port map( clock => clk, address => zpu_addr_rom(14 downto 2), q => zpu_rom_data ); enable_179_clock_div_zpu_pokey : entity work.enable_divider generic map (COUNT=>16) -- cycle_length port map(clk=>clk,reset_n=>reset_n,enable_in=>'1',enable_out=>zpu_pokey_enable); --------------------------------- -- process for CVBS output (TODO - merge this into the svideo.vhd component, as an option...) --------------------------------- -- cvbs_block: -- IF (SVIDEO_OUT = 2) GENERATE PROCESS ( svideo_dac_clk, svideo_yout_dly1, svideo_yout_dly2, svideo_yout_dly3 ) BEGIN IF (rising_edge(svideo_dac_clk)) THEN svideo_yout_dly1 <= svideo_yout; svideo_yout_dly2 <= svideo_yout_dly1; svideo_yout_dly3 <= svideo_yout_dly2; luma_saturated <= luma - "0000011111"; cvbs1_out <= luma_saturated + (chroma(8) & chroma(8 DOWNTO 0)) ; IF (svideo_yout_dly2 = "00000000") THEN cvbs2_out <= "00000000"; ELSE cvbs2_out <= cvbs1_out(9 DOWNTO 2); END IF; END IF; END PROCESS; VGA_B <= cvbs2_out(7 DOWNTO 4); -- WHEN JOY1_n(2) = '1' ELSE svideo_yout(7 DOWNTO 4) ; VGA_G <= cvbs2_out(3 DOWNTO 0); -- WHEN JOY1_n(2) = '1' ELSE svideo_yout(3 DOWNTO 0) ; -- END GENERATE; END vhdl;