Revision 277
Added by markw almost 11 years ago
| common/zpu/zpu_config_regs.vhdl | ||
|---|---|---|
| 
     GENERIC
 
   | 
||
| 
     (
 
   | 
||
| 
     	platform : integer := 1; -- So ROM can detect which type of system...
 
   | 
||
| 
     	spi_clock_div : integer := 4 -- Quite conservative by default - probably want to use 1 with 28MHz input clock, 2 for 57MHz input clock, 4 for 114MHz input clock etc
 
   | 
||
| 
     	spi_clock_div : integer := 4; -- Quite conservative by default - probably want to use 1 with 28MHz input clock, 2 for 57MHz input clock, 4 for 114MHz input clock etc
 
   | 
||
| 
     	usb : integer :=0 -- USB host slave instances
 
   | 
||
| 
     );
 
   | 
||
| 
     PORT 
 
   | 
||
| 
     ( 
 
   | 
||
| ... | ... | |
| 
     | 
||
| 
     	POKEY_ENABLE : in std_logic;
 
   | 
||
| 
     | 
||
| 
     	ADDR : IN STD_LOGIC_VECTOR(4 DOWNTO 0);
 
   | 
||
| 
     	ADDR : IN STD_LOGIC_VECTOR(10 DOWNTO 0);
 
   | 
||
| 
     	CPU_DATA_IN : IN STD_LOGIC_VECTOR(31 DOWNTO 0);
 
   | 
||
| 
     	RD_EN : IN STD_LOGIC;
 
   | 
||
| 
     	WR_EN : IN STD_LOGIC;
 
   | 
||
| 
     | 
||
| 
     	-- GENERIC INPUT REGS (need to synchronize upstream...)
 
   | 
||
| ... | ... | |
| 
     	OUT2 : out  std_logic_vector(31 downto 0); 
 
   | 
||
| 
     	OUT3 : out  std_logic_vector(31 downto 0); 
 
   | 
||
| 
     	OUT4 : out  std_logic_vector(31 downto 0); 
 
   | 
||
| 
     	OUT5 : out  std_logic_vector(31 downto 0); 
 
   | 
||
| 
     	OUT6 : out  std_logic_vector(31 downto 0); 
 
   | 
||
| 
     | 
||
| 
     	-- SDCARD
 
   | 
||
| 
     	SDCARD_CLK : out std_logic;
 
   | 
||
| ... | ... | |
| 
     | 
||
| 
     	-- CPU interface
 
   | 
||
| 
     	DATA_OUT : OUT STD_LOGIC_VECTOR(31 DOWNTO 0);
 
   | 
||
| 
     	PAUSE_ZPU : out std_logic
 
   | 
||
| 
     	PAUSE_ZPU : out std_logic;
 
   | 
||
| 
     | 
||
| 
     	-- USB host
 
   | 
||
| 
     	CLK_USB : in std_logic;
 
   | 
||
| 
     | 
||
| 
     	USBWireVPin :in std_logic_vector(usb-1 downto 0);
 
   | 
||
| 
     	USBWireVMin :in std_logic_vector(usb-1 downto 0);
 
   | 
||
| 
     	USBWireVPout :out std_logic_vector(usb-1 downto 0);
 
   | 
||
| 
     	USBWireVMout :out std_logic_vector(usb-1 downto 0);
 
   | 
||
| 
     	USBWireOE_n :out std_logic_vector(usb-1 downto 0)
 
   | 
||
| 
     );
 
   | 
||
| 
     END zpu_config_regs;
 
   | 
||
| 
     | 
||
| 
     ARCHITECTURE vhdl OF zpu_config_regs IS
 
   | 
||
| 
     | 
||
| 
     	component usbHostCyc2Wrap_usb1t11
 
   | 
||
| 
     	port (
 
   | 
||
| 
     		clk_i :in std_logic;
 
   | 
||
| 
     		rst_i :in std_logic;
 
   | 
||
| 
     		address_i : in std_logic_vector(7 downto 0);
 
   | 
||
| 
     		data_i : in std_logic_vector(7 downto 0);
 
   | 
||
| 
     		data_o : out std_logic_vector(7 downto 0);
 
   | 
||
| 
     		we_i :in std_logic;
 
   | 
||
| 
     		strobe_i :in std_logic;
 
   | 
||
| 
     		ack_o :out std_logic;
 
   | 
||
| 
     		irq :out std_logic;
 
   | 
||
| 
     		usbClk :in std_logic;
 
   | 
||
| 
     | 
||
| 
     		USBWireVPin :in std_logic;
 
   | 
||
| 
     		USBWireVMin :in std_logic;
 
   | 
||
| 
     		USBWireVPout :out std_logic;
 
   | 
||
| 
     		USBWireVMout :out std_logic;
 
   | 
||
| 
     		USBWireOE_n :out std_logic;
 
   | 
||
| 
     		USBFullSpeed :out std_logic
 
   | 
||
| 
     	);
 
   | 
||
| 
     	end component;
 
   | 
||
| 
     | 
||
| 
     	function vectorize(s: std_logic) return std_logic_vector is
 
   | 
||
| 
     	variable v: std_logic_vector(0 downto 0);
 
   | 
||
| 
     	begin
 
   | 
||
| ... | ... | |
| 
     		return v;
 
   | 
||
| 
     	end;
 
   | 
||
| 
     | 
||
| 
     	signal device_decoded : std_logic_vector(7 downto 0);	
 
   | 
||
| 
     	signal device_wr_en : std_logic_vector(7 downto 0);	
 
   | 
||
| 
     	signal device_rd_en : std_logic_vector(7 downto 0);	
 
   | 
||
| 
     	signal addr_decoded : std_logic_vector(15 downto 0);	
 
   | 
||
| 
     | 
||
| 
     	signal out1_next : std_logic_vector(31 downto 0);
 
   | 
||
| ... | ... | |
| 
     	signal out3_reg : std_logic_vector(31 downto 0);
 
   | 
||
| 
     	signal out4_next : std_logic_vector(31 downto 0);
 
   | 
||
| 
     	signal out4_reg : std_logic_vector(31 downto 0);
 
   | 
||
| 
     	signal out5_next : std_logic_vector(31 downto 0);
 
   | 
||
| 
     	signal out5_reg : std_logic_vector(31 downto 0);
 
   | 
||
| 
     	signal out6_next : std_logic_vector(31 downto 0);
 
   | 
||
| 
     	signal out6_reg : std_logic_vector(31 downto 0);
 
   | 
||
| 
     | 
||
| 
     	signal spi_miso : std_logic;
 
   | 
||
| 
     	signal spi_mosi : std_logic;
 
   | 
||
| ... | ... | |
| 
     | 
||
| 
     	signal pokey_data_out : std_logic_vector(7 downto 0);
 
   | 
||
| 
     | 
||
| 
     	signal wr_en_pokey : std_logic;
 
   | 
||
| 
     | 
||
| 
     	signal pause_next : std_logic_vector(31 downto 0);
 
   | 
||
| 
     	signal pause_reg : std_logic_vector(31 downto 0);
 
   | 
||
| 
     	signal paused_next : std_logic;
 
   | 
||
| 
     	signal paused_reg : std_logic;
 
   | 
||
| 
     | 
||
| 
     	signal subtimer_next : std_logic_vector(10 downto 0);
 
   | 
||
| 
     	signal subtimer_reg : std_logic_vector(10 downto 0);
 
   | 
||
| 
     | 
||
| 
     	signal timer_next : std_logic_vector(31 downto 0);
 
   | 
||
| 
     	signal timer_reg : std_logic_vector(31 downto 0);
 
   | 
||
| 
     | 
||
| 
     	signal spi_dma_addr_next : std_logic_vector(15 downto 0);
 
   | 
||
| 
     	signal spi_dma_addrend_next : std_logic_vector(15 downto 0);
 
   | 
||
| 
     	signal spi_dma_wr : std_logic;
 
   | 
||
| ... | ... | |
| 
     | 
||
| 
     	signal spi_clk_div_integer : integer;
 
   | 
||
| 
     	signal spi_addr_integer : integer;
 
   | 
||
| 
     | 
||
| 
     	subtype usb_data_type is std_logic_vector(7 downto 0);
 
   | 
||
| 
     	type usb_data_array is array(0 to USB-1) of usb_data_type;
 
   | 
||
| 
     	signal usb_data : usb_data_array;
 
   | 
||
| 
     | 
||
| 
     	signal data_out_regs : std_logic_vector(31 downto 0);
 
   | 
||
| 
     	signal data_out_mux : std_logic_vector(31 downto 0);
 
   | 
||
| 
     begin
 
   | 
||
| 
     	-- register
 
   | 
||
| 
     	process(clk,reset_n)
 
   | 
||
| ... | ... | |
| 
     			out2_reg <= (others=>'0');
 
   | 
||
| 
     			out3_reg <= (others=>'0');
 
   | 
||
| 
     			out4_reg <= (others=>'0');
 
   | 
||
| 
     			out5_reg <= (others=>'0');
 
   | 
||
| 
     			out6_reg <= (others=>'0');
 
   | 
||
| 
     | 
||
| 
     			spi_addr_reg <= '1';
 
   | 
||
| 
     			spi_speed_reg <= X"80";
 
   | 
||
| ... | ... | |
| 
     			pause_reg <= (others=>'0');
 
   | 
||
| 
     			paused_reg <= '0';
 
   | 
||
| 
     | 
||
| 
     			subtimer_reg <= (others=>'0');
 
   | 
||
| 
     			timer_reg <= (others=>'0');
 
   | 
||
| 
     | 
||
| 
     			spi_dma_addr_reg <= (others=>'0');
 
   | 
||
| 
     			spi_dma_addrend_reg <= (others=>'0');
 
   | 
||
| 
     			spi_dma_reg <= '0';
 
   | 
||
| ... | ... | |
| 
     			out2_reg <= out2_next;
 
   | 
||
| 
     			out3_reg <= out3_next;
 
   | 
||
| 
     			out4_reg <= out4_next;
 
   | 
||
| 
     			out5_reg <= out5_next;
 
   | 
||
| 
     			out6_reg <= out6_next;
 
   | 
||
| 
     | 
||
| 
     			spi_addr_reg <= spi_addr_next;
 
   | 
||
| 
     			spi_speed_reg <= spi_speed_next;
 
   | 
||
| ... | ... | |
| 
     			pause_reg <= pause_next;
 
   | 
||
| 
     			paused_reg <= paused_next;
 
   | 
||
| 
     | 
||
| 
     			subtimer_reg <= subtimer_next;
 
   | 
||
| 
     			timer_reg <= timer_next;
 
   | 
||
| 
     | 
||
| 
     			spi_dma_addr_reg <= spi_dma_addr_next;
 
   | 
||
| 
     			spi_dma_addrend_reg <= spi_dma_addrend_next;
 
   | 
||
| 
     			spi_dma_reg <= spi_dma_next;
 
   | 
||
| ... | ... | |
| 
     	end process;
 
   | 
||
| 
     | 
||
| 
     	-- decode address
 
   | 
||
| 
     	decode_addr1 : entity work.complete_address_decoder
 
   | 
||
| 
     	decode_addr : entity work.complete_address_decoder
 
   | 
||
| 
     		generic map(width=>4)
 
   | 
||
| 
     		port map (addr_in=>addr(3 downto 0), addr_decoded=>addr_decoded);
 
   | 
||
| 
     | 
||
| 
     	decode_device : entity work.complete_address_decoder
 
   | 
||
| 
     		generic map(width=>3)
 
   | 
||
| 
     		port map (addr_in=>addr(10 downto 8), addr_decoded=>device_decoded);
 
   | 
||
| 
     | 
||
| 
     	-- spi - for sd card access without bit banging...
 
   | 
||
| 
     	-- 200KHz to start with - probably fine for 8-bit, can up it later after init
 
   | 
||
| 
     	spi_clk_div_integer <= to_integer(unsigned(spi_speed_reg));
 
   | 
||
| ... | ... | |
| 
     	-- busy
 
   | 
||
| 
     	-- speed - 0=400KHz, 1=10MHz? Start with 400KHz then atari800core...
 
   | 
||
| 
     	-- chip select
 
   | 
||
| 
     | 
||
| 
     	-- device decode
 
   | 
||
| 
     	-- 0x000 - own regs (0)
 
   | 
||
| 
     	-- 0x100 - pokey (1)
 
   | 
||
| 
     	-- 0x200 - usb1 (2)
 
   | 
||
| 
     	-- 0x300 - usb2 (3)
 
   | 
||
| 
     	-- 0x400 - usb3 (4)
 
   | 
||
| 
     	-- 0x500 - usb4 (5)
 
   | 
||
| 
     	-- 0x600 - usb5 (6)
 
   | 
||
| 
     	-- 0x700 - usb6 (7)
 
   | 
||
| 
     | 
||
| 
     	device_wr_en <= device_decoded and (wr_en&wr_en&wr_en&wr_en&wr_en&wr_en&wr_en&wr_en);
 
   | 
||
| 
     	device_rd_en <= device_decoded and (rd_en&rd_en&rd_en&rd_en&rd_en&rd_en&rd_en&rd_en);
 
   | 
||
| 
     | 
||
| 
     	-- uart - another Pokey! Running at atari frequency.
 
   | 
||
| 
     	wr_en_pokey <= addr(4) and wr_en;
 
   | 
||
| 
     	pokey1 : entity work.pokey
 
   | 
||
| 
     		port map (clk=>clk,ENABLE_179=>pokey_enable,addr=>addr(3 downto 0),data_in=>cpu_data_in(7 downto 0),wr_en=>wr_en_pokey, 
 
   | 
||
| 
     		port map (clk=>clk,ENABLE_179=>pokey_enable,addr=>addr(3 downto 0),data_in=>cpu_data_in(7 downto 0),wr_en=>device_wr_en(1), 
 
   | 
||
| 
     		reset_n=>reset_n,keyboard_response=>"11",pot_in=>X"00",
 
   | 
||
| 
     		sio_in1=>sio_data_out,sio_in2=>'1',sio_in3=>'1', -- TODO, pokey dir...
 
   | 
||
| 
     		data_out=>pokey_data_out, 
 
   | 
||
| 
     		sio_out1=>sio_data_in);
 
   | 
||
| 
     | 
||
| 
     	-- timer for approx ms
 
   | 
||
| 
     	process(timer_reg,subtimer_reg, pokey_enable)
 
   | 
||
| 
     	begin
 
   | 
||
| 
     		timer_next <= timer_reg;
 
   | 
||
| 
     		subtimer_next <= subtimer_reg;
 
   | 
||
| 
     | 
||
| 
     		if (pokey_enable = '1') then
 
   | 
||
| 
     			subtimer_next <= std_logic_vector(unsigned(subtimer_reg)-1);
 
   | 
||
| 
     		end if;
 
   | 
||
| 
     | 
||
| 
     		if (subtimer_reg = "000"&x"00") then
 
   | 
||
| 
     			subtimer_next <= std_logic_vector(to_unsigned(11#1790#,11));
 
   | 
||
| 
     			timer_next <= std_logic_vector(unsigned(timer_reg)+1);
 
   | 
||
| 
     		end if;
 
   | 
||
| 
     | 
||
| 
     	end process;
 
   | 
||
| 
     | 
||
| 
     	-- USB host
 
   | 
||
| 
     	USBGEN:
 
   | 
||
| 
     	for I in 0 to USB-1 generate
 
   | 
||
| 
     		usbcon : usbHostCyc2Wrap_usb1t11
 
   | 
||
| 
     		port map 
 
   | 
||
| 
     		(
 
   | 
||
| 
     			clk_i => clk,
 
   | 
||
| 
     			rst_i => not(reset_n),
 
   | 
||
| 
     			address_i => addr(7 downto 0),
 
   | 
||
| 
     			data_i => cpu_data_in(7 downto 0),
 
   | 
||
| 
     			data_o => usb_data(I), -- 2D array
 
   | 
||
| 
     			we_i => device_wr_en(I+2),
 
   | 
||
| 
     			strobe_i => device_wr_en(I+2) or device_rd_en(I+2),
 
   | 
||
| 
     			ack_o => open, -- always right away - checked in sim
 
   | 
||
| 
     			irq => open,
 
   | 
||
| 
     			usbClk => CLK_USB,
 
   | 
||
| 
     | 
||
| 
     			USBWireVPin => USBWireVPin(I),
 
   | 
||
| 
     			USBWireVMin => USBWireVMin(I),
 
   | 
||
| 
     			USBWireVPout => USBWireVPout(I),
 
   | 
||
| 
     			USBWireVMout => USBWireVMout(I),
 
   | 
||
| 
     			USBWireOE_n => USBWireOE_n(I),
 
   | 
||
| 
     			USBFullSpeed => open
 
   | 
||
| 
     		);
 
   | 
||
| 
     	end generate USBGEN;
 
   | 
||
| 
     | 
||
| 
     	process(device_decoded, data_out_regs, pokey_data_out, usb_data)
 
   | 
||
| 
     	begin
 
   | 
||
| 
     		data_out_mux <= (others=>'0');
 
   | 
||
| 
     		if (device_decoded(0) = '1') then
 
   | 
||
| 
     			data_out_mux <= data_out_regs;
 
   | 
||
| 
     		end if;
 
   | 
||
| 
     | 
||
| 
     		if (device_decoded(1) = '1') then
 
   | 
||
| 
     			data_out_mux(7 downto 0) <= pokey_data_out;
 
   | 
||
| 
     		end if;
 
   | 
||
| 
     | 
||
| 
     		for I in 0 to USB-1 loop
 
   | 
||
| 
     			if (device_decoded(I+2) = '1') then
 
   | 
||
| 
     				data_out_mux(7 downto 0) <= usb_data(I);
 
   | 
||
| 
     			end if;
 
   | 
||
| 
     		end loop;
 
   | 
||
| 
     	end process;
 
   | 
||
| 
     | 
||
| 
     	-- hardware regs for ZPU
 
   | 
||
| 
     	--
 
   | 
||
| 
     	-- 0-3: GENERIC INPUT (RO)
 
   | 
||
| 
     	-- 4-7: GENERIC OUTPUT (R/W)
 
   | 
||
| 
     	--  8: PAUSE
 
   | 
||
| 
     	--  8: W:PAUSE, R:Timer (1ms)
 
   | 
||
| 
     	--   9: SPI_DATA
 
   | 
||
| 
     	-- SPI_DATA (DONE) 
 
   | 
||
| 
     	--		W - write data (starts transmission)
 
   | 
||
| ... | ... | |
| 
     	--    R(32 bits) 0=DE1
 
   | 
||
| 
     	--  13 : SPI_DMA
 
   | 
||
| 
     	--    W(15 downto 0 = addr),(31 downto 16 = endAddr)
 
   | 
||
| 
     	--  14-15 : GENERIC OUTPUT (R/W)
 
   | 
||
| 
     	--  16-31: POKEY! Low bytes only... i.e. pokey reg every 4 bytes...
 
   | 
||
| 
     | 
||
| 
     	-- Writes to registers
 
   | 
||
| 
     	process(cpu_data_in,wr_en,addr,addr_decoded, spi_speed_reg, spi_addr_reg, out1_reg, out2_reg, out3_reg, out4_reg, pause_reg, pokey_enable, spi_dma_addr_reg, spi_dma_addrend_reg, spi_dma_reg, spi_busy, spi_dma_addr_next)
 
   | 
||
| 
     	process(cpu_data_in,device_wr_en,addr,addr_decoded, spi_speed_reg, spi_addr_reg, out1_reg, out2_reg, out3_reg, out4_reg, out5_reg, out6_reg, pause_reg, pokey_enable, spi_dma_addr_reg, spi_dma_addrend_reg, spi_dma_reg, spi_busy, spi_dma_addr_next)
 
   | 
||
| 
     	begin
 
   | 
||
| 
     		spi_speed_next <= spi_speed_reg;
 
   | 
||
| 
     		spi_addr_next <= spi_addr_reg;
 
   | 
||
| ... | ... | |
| 
     		out2_next <= out2_reg;
 
   | 
||
| 
     		out3_next <= out3_reg;
 
   | 
||
| 
     		out4_next <= out4_reg;
 
   | 
||
| 
     		out5_next <= out5_reg;
 
   | 
||
| 
     		out6_next <= out6_reg;
 
   | 
||
| 
     | 
||
| 
     		paused_next <= '0';
 
   | 
||
| 
     		pause_next <= pause_reg;
 
   | 
||
| ... | ... | |
| 
     			end if;
 
   | 
||
| 
     		end if;
 
   | 
||
| 
     | 
||
| 
     		if (wr_en = '1' and addr(4) = '0') then
 
   | 
||
| 
     		if (device_wr_en(0) = '1') then
 
   | 
||
| 
     			if(addr_decoded(4) = '1') then
 
   | 
||
| 
     				out1_next <= cpu_data_in;
 
   | 
||
| 
     			end if;	
 
   | 
||
| ... | ... | |
| 
     				out4_next <= cpu_data_in;
 
   | 
||
| 
     			end if;	
 
   | 
||
| 
     | 
||
| 
     			if(addr_decoded(14) = '1') then
 
   | 
||
| 
     				out5_next <= cpu_data_in;
 
   | 
||
| 
     			end if;	
 
   | 
||
| 
     | 
||
| 
     			if(addr_decoded(15) = '1') then
 
   | 
||
| 
     				out6_next <= cpu_data_in;
 
   | 
||
| 
     			end if;	
 
   | 
||
| 
     | 
||
| 
     			if(addr_decoded(8) = '1') then
 
   | 
||
| 
     				pause_next <= cpu_data_in;
 
   | 
||
| 
     				paused_next <= '1';
 
   | 
||
| ... | ... | |
| 
     	end process;
 
   | 
||
| 
     | 
||
| 
     	-- Read from registers
 
   | 
||
| 
     	process(addr,addr_decoded, in1, in2, in3, in4, out1_reg, out2_reg, out3_reg, out4_reg, SIO_COMMAND, spi_rx_data, spi_busy, pokey_data_out)
 
   | 
||
| 
     	process(addr,addr_decoded, in1, in2, in3, in4, out1_reg, out2_reg, out3_reg, out4_reg, out5_reg, out6_reg, SIO_COMMAND, spi_rx_data, spi_busy, timer_reg)
 
   | 
||
| 
     	begin
 
   | 
||
| 
     		data_out <= (others=>'0');
 
   | 
||
| 
     		data_out_regs <= (others=>'0');
 
   | 
||
| 
     | 
||
| 
     		if (addr(4) = '0') then
 
   | 
||
| 
     			if (addr_decoded(0) = '1') then
 
   | 
||
| 
     				data_out <= in1;
 
   | 
||
| 
     			end if;
 
   | 
||
| 
     | 
||
| 
     			if (addr_decoded(1) = '1') then
 
   | 
||
| 
     				data_out <= in2;
 
   | 
||
| 
     			end if;		
 
   | 
||
| 
     | 
||
| 
     			if (addr_decoded(2) = '1') then
 
   | 
||
| 
     				data_out <= in3;
 
   | 
||
| 
     			end if;		
 
   | 
||
| 
     | 
||
| 
     			if (addr_decoded(3) = '1') then
 
   | 
||
| 
     				data_out <= in4;
 
   | 
||
| 
     			end if;
 
   | 
||
| 
     		if (addr_decoded(0) = '1') then
 
   | 
||
| 
     			data_out_regs <= in1;
 
   | 
||
| 
     		end if;
 
   | 
||
| 
     | 
||
| 
     		if (addr_decoded(1) = '1') then
 
   | 
||
| 
     			data_out_regs <= in2;
 
   | 
||
| 
     		end if;		
 
   | 
||
| 
     | 
||
| 
     		if (addr_decoded(2) = '1') then
 
   | 
||
| 
     			data_out_regs <= in3;
 
   | 
||
| 
     		end if;		
 
   | 
||
| 
     | 
||
| 
     		if (addr_decoded(3) = '1') then
 
   | 
||
| 
     			data_out_regs <= in4;
 
   | 
||
| 
     		end if;
 
   | 
||
| 
     | 
||
| 
     			if (addr_decoded(4) = '1') then
 
   | 
||
| 
     				data_out <= out1_reg;
 
   | 
||
| 
     			end if;
 
   | 
||
| 
     | 
||
| 
     			if (addr_decoded(5) = '1') then
 
   | 
||
| 
     				data_out <= out2_reg;
 
   | 
||
| 
     			end if;		
 
   | 
||
| 
     | 
||
| 
     			if (addr_decoded(6) = '1') then
 
   | 
||
| 
     				data_out <= out3_reg;
 
   | 
||
| 
     			end if;		
 
   | 
||
| 
     | 
||
| 
     			if (addr_decoded(7) = '1') then
 
   | 
||
| 
     				data_out <= out4_reg;
 
   | 
||
| 
     			end if;
 
   | 
||
| 
     		if (addr_decoded(4) = '1') then
 
   | 
||
| 
     			data_out_regs <= out1_reg;
 
   | 
||
| 
     		end if;
 
   | 
||
| 
     | 
||
| 
     		if (addr_decoded(5) = '1') then
 
   | 
||
| 
     			data_out_regs <= out2_reg;
 
   | 
||
| 
     		end if;		
 
   | 
||
| 
     | 
||
| 
     		if (addr_decoded(6) = '1') then
 
   | 
||
| 
     			data_out_regs <= out3_reg;
 
   | 
||
| 
     		end if;		
 
   | 
||
| 
     | 
||
| 
     		if (addr_decoded(7) = '1') then
 
   | 
||
| 
     			data_out_regs <= out4_reg;
 
   | 
||
| 
     		end if;
 
   | 
||
| 
     | 
||
| 
     			if (addr_decoded(9) = '1') then
 
   | 
||
| 
     				data_out(7 downto 0) <= spi_rx_data;
 
   | 
||
| 
     			end if;
 
   | 
||
| 
     		if (addr_decoded(14) = '1') then
 
   | 
||
| 
     			data_out_regs <= out5_reg;
 
   | 
||
| 
     		end if;
 
   | 
||
| 
     | 
||
| 
     			if (addr_decoded(10) = '1') then
 
   | 
||
| 
     				data_out(0) <= spi_busy;
 
   | 
||
| 
     			end if;		
 
   | 
||
| 
     		if (addr_decoded(15) = '1') then
 
   | 
||
| 
     			data_out_regs <= out6_reg;
 
   | 
||
| 
     		end if;
 
   | 
||
| 
     | 
||
| 
     			if(addr_decoded(11) = '1') then
 
   | 
||
| 
     				data_out(0) <= SIO_COMMAND;
 
   | 
||
| 
     			end if;	
 
   | 
||
| 
     | 
||
| 
     			if (addr_decoded(12) = '1') then
 
   | 
||
| 
     				data_out <= std_logic_vector(to_unsigned(platform,32));
 
   | 
||
| 
     			end if;
 
   | 
||
| 
     		else
 
   | 
||
| 
     			data_out(7 downto 0) <= pokey_data_out;
 
   | 
||
| 
     		if (addr_decoded(8) = '1') then
 
   | 
||
| 
     			data_out_regs <= timer_reg;
 
   | 
||
| 
     		end if;
 
   | 
||
| 
     | 
||
| 
     		if (addr_decoded(9) = '1') then
 
   | 
||
| 
     			data_out_regs(7 downto 0) <= spi_rx_data;
 
   | 
||
| 
     		end if;
 
   | 
||
| 
     | 
||
| 
     		if (addr_decoded(10) = '1') then
 
   | 
||
| 
     			data_out_regs(0) <= spi_busy;
 
   | 
||
| 
     		end if;		
 
   | 
||
| 
     | 
||
| 
     		if(addr_decoded(11) = '1') then
 
   | 
||
| 
     			data_out_regs(0) <= SIO_COMMAND;
 
   | 
||
| 
     		end if;	
 
   | 
||
| 
     | 
||
| 
     		if (addr_decoded(12) = '1') then
 
   | 
||
| 
     			data_out_regs <= std_logic_vector(to_unsigned(platform,32));
 
   | 
||
| 
     		end if;
 
   | 
||
| 
     	end process;	
 
   | 
||
| 
     | 
||
| 
     	-- outputs
 
   | 
||
| ... | ... | |
| 
     	out2 <= out2_reg;
 
   | 
||
| 
     	out3 <= out3_reg;
 
   | 
||
| 
     	out4 <= out4_reg;
 
   | 
||
| 
     	out5 <= out5_reg;
 
   | 
||
| 
     	out6 <= out6_reg;
 
   | 
||
| 
     | 
||
| 
     	SDCARD_CLK <= spi_clk_out;
 
   | 
||
| 
     	SDCARD_CMD <= spi_mosi;
 
   | 
||
| 
     	spi_miso <= SDCARD_DAT; -- INPUT!! XXX
 
   | 
||
| 
     	SDCARD_DAT3 <= spi_chip_select(0);
 
   | 
||
| 
     | 
||
| 
     	data_out <= data_out_mux;
 
   | 
||
| 
     | 
||
| 
     	sd_addr <= spi_dma_addr_reg;
 
   | 
||
| 
     	sd_data <= spi_rx_data;
 
   | 
||
| 
     	sd_write <= spi_dma_wr;
 
   | 
||
| common/zpu/zpu_glue.vhdl | ||
|---|---|---|
| 
     | 
||
| 
     	-- config
 
   | 
||
| 
     	ZPU_CONFIG_WRITE : out std_logic;
 
   | 
||
| 
     	ZPU_CONFIG_READ : out std_logic;
 
   | 
||
| 
     | 
||
| 
     	-- stack request
 
   | 
||
| 
     	ZPU_STACK_WRITE : out std_logic_vector(3 downto 0);
 
   | 
||
| ... | ... | |
| 
     | 
||
| 
     	signal zpu_di_use : std_logic_vector(31 downto 0);
 
   | 
||
| 
     | 
||
| 
     	signal memORY_ACCESS : std_logic;
 
   | 
||
| 
     	signal memory_access : std_logic;
 
   | 
||
| 
     | 
||
| 
     	-- 1 cycle delay on memory read - needed to allow running at higher clock
 
   | 
||
| 
     	signal zpu_di_next : std_logic_vector(31 downto 0);
 
   | 
||
| ... | ... | |
| 
     			result_reg <= result_next;
 
   | 
||
| 
     			zpu_di_reg <= zpu_di_next;
 
   | 
||
| 
     			zpu_do_reg <= zpu_do_next;
 
   | 
||
| 
     			memory_ready_reg <= memORY_READY_next;
 
   | 
||
| 
     			memory_ready_reg <= memory_ready_next;
 
   | 
||
| 
     			zpu_addr_reg <=zpu_addr_next;
 
   | 
||
| 
     			ZPU_32BIT_WRITE_ENABLE_reg <= ZPU_32BIT_WRITE_ENABLE_next;
 
   | 
||
| 
     			ZPU_16BIT_WRITE_ENABLE_reg <= ZPU_16BIT_WRITE_ENABLE_next;
 
   | 
||
| ... | ... | |
| 
     | 
||
| 
     	ZPU_READ_TEMP <= zpu_32bit_read_enable_temp or zpu_8BIT_read_enable_temp;
 
   | 
||
| 
     	ZPU_WRITE_TEMP<= zpu_32BIT_WRITE_ENABLE_temp or zpu_16BIT_WRITE_ENABLE_temp or zpu_8BIT_WRITE_ENABLE_temp;
 
   | 
||
| 
     	process(zpu_addr_reg,pause,memory_ready,zpu_memory_fetch_pending_next,request_type, zpu_memory_fetch_pending_reg, memory_ready_reg, zpu_ADDR_unsigned, zpu_8bit_read_enable_temp, zpu_write_temp, result_reg, block_mem, config_mem, special_mem, memORY_ACCESS,
 
   | 
||
| 
     	process(zpu_addr_reg,pause,memory_ready,zpu_memory_fetch_pending_next,request_type, zpu_memory_fetch_pending_reg, memory_ready_reg, zpu_ADDR_unsigned, zpu_8bit_read_enable_temp, zpu_write_temp, result_reg, block_mem, config_mem, special_mem, memory_access,
 
   | 
||
| 
     	        zpu_read_reg,zpu_8BIT_WRITE_ENABLE_reg, zpu_16BIT_WRITE_ENABLE_reg, zpu_32BIT_WRITE_ENABLE_reg,
 
   | 
||
| 
     			  zpu_read_temp,zpu_8BIT_WRITE_ENABLE_temp, zpu_16BIT_WRITE_ENABLE_temp, zpu_32BIT_WRITE_ENABLE_temp,
 
   | 
||
| 
     	zpu_do_unsigned, zpu_do_reg
 
   | 
||
| ... | ... | |
| 
     		zpu_stACK_WRITE <= (others=>'0');
 
   | 
||
| 
     		ZPU_ROM_WREN <= '0';
 
   | 
||
| 
     		ZPU_config_write <= '0';
 
   | 
||
| 
     		ZPU_config_read <= '0';
 
   | 
||
| 
     		zpu_addr_next <= zpu_addr_reg;
 
   | 
||
| 
     		zpu_do_next <= zpu_do_reg;
 
   | 
||
| 
     | 
||
| ... | ... | |
| 
     		zpu_16bit_write_enable_next <= zpu_16bit_write_enable_reg;
 
   | 
||
| 
     		zpu_32bit_write_enable_next <= zpu_32bit_write_enable_reg;	
 
   | 
||
| 
     | 
||
| 
     		request_type <= config_mem&block_mem&zpu_addr_unsigned(15)&memORY_ACCESS&zpu_memory_fetch_pending_reg;
 
   | 
||
| 
     		request_type <= config_mem&block_mem&zpu_addr_unsigned(15)&memory_access&zpu_memory_fetch_pending_reg;
 
   | 
||
| 
     		case request_type is
 
   | 
||
| 
     			when "00010"|"00110" =>
 
   | 
||
| 
     				zpu_memory_fetch_pending_next <= '1';
 
   | 
||
| ... | ... | |
| 
     				result_next <= result_config;
 
   | 
||
| 
     				ZPU_MEM_BUSY <= '1';
 
   | 
||
| 
     				ZPU_config_write <= ZPU_WRITE_temp; 
 
   | 
||
| 
     				ZPU_config_read <= ZPU_READ_temp; 
 
   | 
||
| 
     				zpu_addr_next <= std_logic_vector(zpu_addr_unsigned);				
 
   | 
||
| 
     			when "00001"|"00011"|"00101"|"00111"|"01001"|"01011"|"01101"|"01111"|
 
   | 
||
| 
     				  "10001"|"10011"|"10101"|"10111"|"11001"|"11011"|"11101"|"11111"|"00X01" =>
 
   | 
||
| 
     				ZPU_MEM_BUSY <= not(memORY_READY_reg) or pause;
 
   | 
||
| 
     				zpu_memory_fetch_pending_next <= not(memORY_READY);
 
   | 
||
| 
     				ZPU_MEM_BUSY <= not(memory_ready_reg) or pause;
 
   | 
||
| 
     				zpu_memory_fetch_pending_next <= not(memory_ready);
 
   | 
||
| 
     			when others =>
 
   | 
||
| 
     				-- nop
 
   | 
||
| 
     		end case;
 
   | 
||
| common/zpu/zpucore.vhd | ||
|---|---|---|
| 
     LIBRARY ieee;
 
   | 
||
| 
     USE ieee.std_logic_1164.all; 
 
   | 
||
| 
     use ieee.numeric_std.all;
 
   | 
||
| 
     USE ieee.math_real.log2;
 
   | 
||
| 
     USE ieee.math_real.ceil;
 
   | 
||
| 
     | 
||
| 
     LIBRARY work;
 
   | 
||
| 
     | 
||
| ... | ... | |
| 
     	GENERIC
 
   | 
||
| 
     	(
 
   | 
||
| 
     		platform : integer := 1; -- So ROM can detect which type of system...
 
   | 
||
| 
     		spi_clock_div : integer := 4  -- see notes on zpu_config_regs
 
   | 
||
| 
     		spi_clock_div : integer := 4;  -- see notes on zpu_config_regs
 
   | 
||
| 
     		memory : integer := 4096; -- up to 32K allowed
 
   | 
||
| 
     		usb : integer := 0
 
   | 
||
| 
     	);
 
   | 
||
| 
     	PORT
 
   | 
||
| 
     	(
 
   | 
||
| ... | ... | |
| 
     		ZPU_OUT1 : out std_logic_vector(31 downto 0);
 
   | 
||
| 
     		ZPU_OUT2 : out std_logic_vector(31 downto 0);
 
   | 
||
| 
     		ZPU_OUT3 : out std_logic_vector(31 downto 0);
 
   | 
||
| 
     		ZPU_OUT4 : out std_logic_vector(31 downto 0)
 
   | 
||
| 
     		ZPU_OUT4 : out std_logic_vector(31 downto 0);
 
   | 
||
| 
     		ZPU_OUT5 : out std_logic_vector(31 downto 0);
 
   | 
||
| 
     		ZPU_OUT6 : out std_logic_vector(31 downto 0);
 
   | 
||
| 
     | 
||
| 
     		-- USB host
 
   | 
||
| 
     		CLK_USB : in std_logic := '0';
 
   | 
||
| 
     | 
||
| 
     		USBWireVPin :in std_logic_vector(usb-1 downto 0) := (others=>'0');
 
   | 
||
| 
     		USBWireVMin :in std_logic_vector(usb-1 downto 0) := (others=>'0');
 
   | 
||
| 
     		USBWireVPout :out std_logic_vector(usb-1 downto 0);
 
   | 
||
| 
     		USBWireVMout :out std_logic_vector(usb-1 downto 0);
 
   | 
||
| 
     		USBWireOE_n :out std_logic_vector(usb-1 downto 0)
 
   | 
||
| 
     	);
 
   | 
||
| 
     END zpucore;
 
   | 
||
| 
     | 
||
| ... | ... | |
| 
     | 
||
| 
     	signal ZPU_CONFIG_DO : std_logic_vector(31 downto 0);
 
   | 
||
| 
     	signal ZPU_CONFIG_WRITE_ENABLE : std_logic;
 
   | 
||
| 
     	signal ZPU_CONFIG_READ_ENABLE : std_logic;
 
   | 
||
| 
     | 
||
| 
     	signal ZPU_SD_DMA_ADDR : std_logic_vector(15 downto 0);
 
   | 
||
| 
     	signal ZPU_SD_DMA_DATA : std_logic_vector(7 downto 0);
 
   | 
||
| ... | ... | |
| 
     	signal ZPU_ADDR_ROM_RAM_DMA : std_logic_vector(15 downto 0);
 
   | 
||
| 
     	signal ZPU_DO_DMA : std_logic_vector(31 downto 0);
 
   | 
||
| 
     	signal ZPU_STACK_WRITE_DMA : std_logic_vector(3 downto 0);
 
   | 
||
| 
     | 
||
| 
     	constant memory_bits: integer := integer(ceil(log2(real(memory))));
 
   | 
||
| 
     BEGIN 
 
   | 
||
| 
     | 
||
| 
     ZPU_RESET <= not(reset_n);
 
   | 
||
| ... | ... | |
| 
     		 ZPU_16BIT_WRITE_ENABLE => ZPU_16BIT_WRITE_ENABLE,
 
   | 
||
| 
     		 ZPU_8BIT_WRITE_ENABLE => ZPU_8BIT_WRITE_ENABLE,
 
   | 
||
| 
     		 ZPU_CONFIG_WRITE => ZPU_CONFIG_WRITE_ENABLE,
 
   | 
||
| 
     		 ZPU_CONFIG_READ => ZPU_CONFIG_READ_ENABLE,
 
   | 
||
| 
     		 ZPU_ADDR_FETCH => ZPU_ADDR_FETCH,
 
   | 
||
| 
     		 ZPU_ADDR_ROM_RAM => ZPU_ADDR_ROM_RAM,
 
   | 
||
| 
     		 ZPU_DO => ZPU_DO,
 
   | 
||
| ... | ... | |
| 
     config_regs : entity work.zpu_config_regs
 
   | 
||
| 
     GENERIC MAP (
 
   | 
||
| 
     	platform => platform,
 
   | 
||
| 
     	spi_clock_div => spi_clock_div
 
   | 
||
| 
     	spi_clock_div => spi_clock_div,
 
   | 
||
| 
     	usb => usb
 
   | 
||
| 
     )
 
   | 
||
| 
     PORT MAP (
 
   | 
||
| 
     	CLK => CLK,
 
   | 
||
| ... | ... | |
| 
     | 
||
| 
     	POKEY_ENABLE => ZPU_POKEY_ENABLE,
 
   | 
||
| 
     | 
||
| 
     	ADDR => ZPU_ADDR_ROM_RAM(6 DOWNTO 2),
 
   | 
||
| 
     	ADDR => ZPU_ADDR_ROM_RAM(12 DOWNTO 2),
 
   | 
||
| 
     	CPU_DATA_IN => ZPU_DO,
 
   | 
||
| 
     	WR_EN => ZPU_CONFIG_WRITE_ENABLE,
 
   | 
||
| 
     	RD_EN => ZPU_CONFIG_READ_ENABLE,
 
   | 
||
| 
     | 
||
| 
     	IN1 => ZPU_IN1,
 
   | 
||
| 
     	IN2 => ZPU_IN2,
 
   | 
||
| ... | ... | |
| 
     	OUT2 => ZPU_OUT2,
 
   | 
||
| 
     	OUT3 => ZPU_OUT3,
 
   | 
||
| 
     	OUT4 => ZPU_OUT4,
 
   | 
||
| 
     	OUT5 => ZPU_OUT5,
 
   | 
||
| 
     	OUT6 => ZPU_OUT6,
 
   | 
||
| 
     | 
||
| 
     	SDCARD_DAT => ZPU_SD_DAT0,
 
   | 
||
| 
     	SDCARD_CLK => ZPU_SD_CLK,
 
   | 
||
| ... | ... | |
| 
     	sd_write => ZPU_SD_DMA_WRITE,
 
   | 
||
| 
     | 
||
| 
     	DATA_OUT => ZPU_CONFIG_DO,
 
   | 
||
| 
     	PAUSE_ZPU => ZPU_PAUSE
 
   | 
||
| 
     	PAUSE_ZPU => ZPU_PAUSE,
 
   | 
||
| 
     | 
||
| 
     	CLK_USB => CLK_USB,
 
   | 
||
| 
     | 
||
| 
     	USBWireVPin => USBWireVPin,
 
   | 
||
| 
     	USBWireVMin => USBWireVMin,
 
   | 
||
| 
     	USBWireVPout => USBWireVPout,
 
   | 
||
| 
     	USBWireVMout => USBWireVMout,
 
   | 
||
| 
     	USBWireOE_n => USBWireOE_n
 
   | 
||
| 
     	);
 
   | 
||
| 
     | 
||
| 
     decode_addr1 : entity work.complete_address_decoder
 
   | 
||
| ... | ... | |
| 
     ram_31_24 : entity work.generic_ram_infer
 
   | 
||
| 
     	GENERIC MAP
 
   | 
||
| 
     	(
 
   | 
||
| 
     		ADDRESS_WIDTH => 10,
 
   | 
||
| 
     		SPACE => 1024,
 
   | 
||
| 
     		ADDRESS_WIDTH => memory_bits-2,
 
   | 
||
| 
     		SPACE => memory/4,
 
   | 
||
| 
     		DATA_WIDTH => 8
 
   | 
||
| 
     	)
 
   | 
||
| 
     	PORT MAP
 
   | 
||
| 
     	(
 
   | 
||
| 
     		we => ZPU_STACK_WRITE_DMA(3),
 
   | 
||
| 
     		clock => CLK,
 
   | 
||
| 
     		address => ZPU_ADDR_ROM_RAM_DMA(11 DOWNTO 2),
 
   | 
||
| 
     		address => ZPU_ADDR_ROM_RAM_DMA(memory_bits-1 DOWNTO 2),
 
   | 
||
| 
     		data => ZPU_DO_DMA(31 DOWNTO 24),
 
   | 
||
| 
     		q => ZPU_RAM_DATA(31 DOWNTO 24)
 
   | 
||
| 
     	);
 
   | 
||
| ... | ... | |
| 
     ram23_16 : entity work.generic_ram_infer
 
   | 
||
| 
     	GENERIC MAP
 
   | 
||
| 
     	(
 
   | 
||
| 
     		ADDRESS_WIDTH => 10,
 
   | 
||
| 
     		SPACE => 1024,
 
   | 
||
| 
     		ADDRESS_WIDTH => memory_bits-2,
 
   | 
||
| 
     		SPACE => memory/4,
 
   | 
||
| 
     		DATA_WIDTH => 8
 
   | 
||
| 
     	)
 
   | 
||
| 
     	PORT MAP
 
   | 
||
| 
     	(
 
   | 
||
| 
     		we => ZPU_STACK_WRITE_DMA(2),
 
   | 
||
| 
     		clock => CLK,
 
   | 
||
| 
     		address => ZPU_ADDR_ROM_RAM_DMA(11 DOWNTO 2),
 
   | 
||
| 
     		address => ZPU_ADDR_ROM_RAM_DMA(memory_bits-1 DOWNTO 2),
 
   | 
||
| 
     		data => ZPU_DO_DMA(23 DOWNTO 16),
 
   | 
||
| 
     		q => ZPU_RAM_DATA(23 DOWNTO 16)
 
   | 
||
| 
     	);
 
   | 
||
| ... | ... | |
| 
     ram_15_8 : entity work.generic_ram_infer
 
   | 
||
| 
     	GENERIC MAP
 
   | 
||
| 
     	(
 
   | 
||
| 
     		ADDRESS_WIDTH => 10,
 
   | 
||
| 
     		SPACE => 1024,
 
   | 
||
| 
     		ADDRESS_WIDTH => memory_bits-2,
 
   | 
||
| 
     		SPACE => memory/4,
 
   | 
||
| 
     		DATA_WIDTH => 8
 
   | 
||
| 
     	)
 
   | 
||
| 
     	PORT MAP
 
   | 
||
| 
     	(
 
   | 
||
| 
     		we => ZPU_STACK_WRITE_DMA(1),
 
   | 
||
| 
     		clock => CLK,
 
   | 
||
| 
     		address => ZPU_ADDR_ROM_RAM_DMA(11 DOWNTO 2),
 
   | 
||
| 
     		address => ZPU_ADDR_ROM_RAM_DMA(memory_bits-1 DOWNTO 2),
 
   | 
||
| 
     		data => ZPU_DO_DMA(15 DOWNTO 8),
 
   | 
||
| 
     		q => ZPU_RAM_DATA(15 DOWNTO 8)
 
   | 
||
| 
     	);
 
   | 
||
| ... | ... | |
| 
     ram_7_0 : entity work.generic_ram_infer
 
   | 
||
| 
     	GENERIC MAP
 
   | 
||
| 
     	(
 
   | 
||
| 
     		ADDRESS_WIDTH => 10,
 
   | 
||
| 
     		SPACE => 1024,
 
   | 
||
| 
     		ADDRESS_WIDTH => memory_bits-2,
 
   | 
||
| 
     		SPACE => memory/4,
 
   | 
||
| 
     		DATA_WIDTH => 8
 
   | 
||
| 
     	)
 
   | 
||
| 
     	PORT MAP
 
   | 
||
| 
     	(
 
   | 
||
| 
     		we => ZPU_STACK_WRITE_DMA(0),
 
   | 
||
| 
     		clock => CLK,
 
   | 
||
| 
     		address => ZPU_ADDR_ROM_RAM_DMA(11 DOWNTO 2),
 
   | 
||
| 
     		address => ZPU_ADDR_ROM_RAM_DMA(memory_bits-1 DOWNTO 2),
 
   | 
||
| 
     		data => ZPU_DO_DMA(7 DOWNTO 0),
 
   | 
||
| 
     		q => ZPU_RAM_DATA(7 DOWNTO 0)
 
   | 
||
| 
     	);
 
   | 
||
USB support - larger rom/ram support