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

Subversion Repositories c16

[/] [c16/] [trunk/] [vhdl/] [input_output.vhd] - Rev 2

Go to most recent revision | Compare with Previous | Blame | View Log

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
 
--  Uncomment the following lines to use the declarations that are
--  provided for instantiating Xilinx primitive components.
--library UNISIM;
--use UNISIM.VComponents.all;
 
use work.cpu_pack.ALL;
 
entity input_output is
    PORT (	CLK_I 			: in std_logic;
			T2				: in std_logic;
			SWITCH			: in  STD_LOGIC_VECTOR (9 downto 0);
 
			HALT			: in  STD_LOGIC;
			SER_IN			: in  STD_LOGIC;
			SER_OUT			: out STD_LOGIC;
 
			-- temperature
			TEMP_SPO		: in  STD_LOGIC;
			TEMP_SPI		: out STD_LOGIC;
			TEMP_CE			: out STD_LOGIC;
			TEMP_SCLK		: out STD_LOGIC;
 
		    LED				: out STD_LOGIC_VECTOR (7 downto 0);
 
			CLR				: out STD_LOGIC;
 
			-- input/output
			IO_RD    : in  std_logic;
			IO_WR    : in  std_logic;
			IO_ADR   : in  std_logic_vector( 7 downto 0);
			IO_RDAT  : out std_logic_vector( 7 downto 0);
			IO_WDAT  : in  std_logic_vector( 7 downto 0);
		    INT      : out STD_LOGIC
	);
end input_output;
 
architecture Behavioral of input_output is
 
	COMPONENT temperature
	PORT(	CLK_I     : IN std_logic;
			T2        : IN std_logic;
			CLR       : IN std_logic;
			TEMP_SPO  : IN std_logic;          
			DATA_OUT  : OUT std_logic_vector(7 downto 0);
			TEMP_SPI  : OUT std_logic;
			TEMP_CE   : OUT std_logic;
			TEMP_SCLK : OUT std_logic
		);
	END COMPONENT;
 
	COMPONENT uart_baudgen
	PORT(	CLK_I     : IN std_logic;
			T2        : IN std_logic;
			CLR       : IN std_logic;
			RD        : IN std_logic;
			WR        : IN std_logic;
			TX_DATA   : IN std_logic_vector(7 downto 0);
			RX_SERIN  : IN std_logic;          
			TX_SEROUT : OUT std_logic;
			RX_DATA   : OUT std_logic_vector(7 downto 0);
			RX_READY  : OUT std_logic;
			TX_BUSY   : OUT std_logic
		);
	END COMPONENT;
 
	signal L_IO_ADR        : std_logic_vector(7 downto 0);
	signal IO_RD_SERIAL    : std_logic;
	signal IO_WR_SERIAL    : std_logic;
	signal RX_READY        : std_logic;
	signal TX_BUSY         : std_logic;
	signal RX_DATA         : std_logic_vector(7 downto 0);
	signal TEMP_DO         : std_logic_vector(7 downto 0);
 
	signal FLAG            : std_logic;
 
	signal LCLR            : std_logic;
	signal C1_N, C2_N      : std_logic;		-- switch debounce, active low
 
	signal RX_INT_ENABLED  : std_logic;
	signal TX_INT_ENABLED  : std_logic;
	signal TIM_INT_ENABLED : std_logic;
	signal TIMER_INT       : std_logic;
	signal TIMER           : std_logic_vector(14 downto 0);
	signal CLK_COUNT       : std_logic_vector(15 downto 0);
 
	signal CLK_COUNT_EN    : std_logic;
	signal CLK_HALT_MSK    : std_logic;
	signal CLK_HALT_VAL    : std_logic;
 
begin
 
	tempr: temperature
	PORT MAP(	CLK_I     => CLK_I,
				T2        => T2,
				CLR       => LCLR,
				DATA_OUT  => TEMP_DO,
				TEMP_SPI  => TEMP_SPI,
				TEMP_SPO  => TEMP_SPO,
				TEMP_CE   => TEMP_CE,
				TEMP_SCLK => TEMP_SCLK
	);
 
	uart: uart_baudgen
	PORT MAP(	CLK_I     => CLK_I,
				T2        => T2,
				CLR       => LCLR,
				RD        => IO_RD_SERIAL,
				WR        => IO_WR_SERIAL,
				TX_DATA   => IO_WDAT,
				TX_SEROUT => SER_OUT,
				RX_SERIN  => SER_IN,
				RX_DATA   => RX_DATA,
				RX_READY  => RX_READY,
				TX_BUSY   => TX_BUSY
	);
 
	CLR     <= LCLR;
	INT     <=     (RX_INT_ENABLED  and     RX_READY)
				or (TX_INT_ENABLED  and not TX_BUSY)
				or (TIM_INT_ENABLED and     TIMER_INT);
 
	-- IO read process
	--
	process(L_IO_ADR, IO_RD, IO_WR, RX_DATA, TEMP_DO, SWITCH,
			TIM_INT_ENABLED, TIMER_INT, TX_INT_ENABLED, TX_BUSY,
			RX_INT_ENABLED, RX_READY)
	begin
		IO_RD_SERIAL <= '0';
		IO_WR_SERIAL <= '0';
		case L_IO_ADR is
			when X"00"	=>	IO_RDAT      <= RX_DATA;
							IO_RD_SERIAL <= IO_RD;
							IO_WR_SERIAL <= IO_WR;
			when X"01"	=>	IO_RDAT <= '0'
									 & (TIM_INT_ENABLED and  TIMER_INT)
									 & (TX_INT_ENABLED  and not TX_BUSY)
									 & (RX_INT_ENABLED  and RX_READY)
									 & '0'
									 & TIMER_INT
									 & TX_BUSY
									 & RX_READY;
			when X"02"	=> IO_RDAT  <= TEMP_DO;
			when X"03"	=> IO_RDAT  <= SWITCH(7 downto 0);
			when X"05"	=> IO_RDAT  <= CLK_COUNT(7 downto 0);
			when others	=> IO_RDAT  <= CLK_COUNT(15 downto 8);
		end case;
	end process;
 
	-- IO write and timer process
	--
	process(CLK_I)
	begin
		if (rising_edge(CLK_I)) then
			if (T2 = '1') then
				L_IO_ADR <= IO_ADR;
				if (LCLR = '1') then
					LED             <= X"00";
					RX_INT_ENABLED  <= '0';
					TX_INT_ENABLED  <= '0';
					TIM_INT_ENABLED <= '0';
					TIMER_INT       <= '0';
					TIMER           <= "000" & X"000";
				else
					if (IO_WR = '1') then
						case L_IO_ADR is
							when X"00"  =>	-- handled by uart
							when X"01"  =>	-- handled by uart
							when X"02"  => LED <= IO_WDAT;
							when X"03"  =>	RX_INT_ENABLED  <= IO_WDAT(0);
											TX_INT_ENABLED  <= IO_WDAT(1);
											TIM_INT_ENABLED <= IO_WDAT(2);
							when X"04"  =>	TIMER_INT       <= '0';
							when X"05"  =>	CLK_COUNT_EN    <= '1';
							                CLK_COUNT       <= X"0000";
											CLK_HALT_VAL    <= IO_WDAT(0);
											CLK_HALT_MSK    <= IO_WDAT(1);
							when X"06"  =>	CLK_COUNT_EN    <= '0';
							when others =>
						end case;
					end if;
 
					TIMER <= TIMER + 1;
					if (TIMER = 19999) then		-- 1 ms
						TIMER_INT <= '1';
						TIMER     <= "000" & X"000";
					end if;
 
					if (CLK_COUNT_EN = '1' and
					    (HALT and CLK_HALT_MSK ) = CLK_HALT_VAL) then
						CLK_COUNT <= CLK_COUNT + 1;
					end if;
				end if;
			end if;
		end if;
	end process;
 
	-- reset debounce process
	--
	process(CLK_I)
	begin
		if (rising_edge(CLK_I)) then			
			if (T2 = '1') then
				-- switch debounce
				if (SWITCH(8) = '1' or SWITCH(9) = '1') then
					LCLR <= '1';
					C2_N <= '0';
					C1_N <= '0';
				else
					LCLR <= not C2_N;
					C2_N   <= C1_N;
					C1_N   <= '1';
				end if;
			end if;
		end if;
	end process;
 
end Behavioral;
 

Go to most recent revision | Compare with Previous | Blame | View Log

powered by: WebSVN 2.1.0

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