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

Subversion Repositories tinyvliw8

[/] [tinyvliw8/] [trunk/] [src/] [vhdl/] [ioport.vhd] - Rev 9

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

-- ************************************************************************
-- * This is a RTL Model of the MSP430 IO ports without interrupt 
-- * functionality
-- *
-- * This io-port fits the behavior of the msp430 io-port. The functionality 
-- * of the in- and output lines(the output value is also written to the 
-- * input) is provided by the sgb25v io-pads
-- *
-- * author: g.panic - IHP, date: 2011-02-07
-- * version: 1.1
-- *
-- * Revision:
-- * changed clock behavior, clock used only in connection with mdbwr_n 
-- *
-- ************************************************************************
 
library ieee;
use ieee.std_logic_1164.all;
 
ENTITY ioport IS
	PORT (
    		cs_n     : IN  STD_LOGIC; 			            -- chip select signal
 
			clk      : IN  STD_LOGIC;
 
			-- memory interface
    		mdbwr_n  : IN  STD_LOGIC;                    -- write enable signal    
   		mdb_i   	: IN  STD_LOGIC_VECTOR(7 DOWNTO 0); -- data from data bus
    		mdb_o   	: OUT STD_LOGIC_VECTOR(7 DOWNTO 0); -- data to data bus    
    		mab   	: IN  STD_LOGIC_VECTOR(2 downto 0);	-- address registers 
 
			-- interrupt interface
			irq      : out std_logic;
			irqAck   : in std_logic;
 
    		-- port interface
    		PnIN  	: IN  STD_LOGIC_VECTOR(7 DOWNTO 0); -- data from pad (gpio in)
    		PnOUT   	: OUT STD_LOGIC_VECTOR(7 DOWNTO 0); -- data to pad (gpio out)
    		PnOEN  	: OUT STD_LOGIC_VECTOR(7 DOWNTO 0); -- port direction (low active)
 
    		-- MODxIN   : IN  STD_LOGIC_VECTOR(7 DOWNTO 0); 	-- data to peripheral
    		-- MODxDIR  : IN  STD_LOGIC_VECTOR(7 DOWNTO 0); 	-- direction
    		-- MODxOUT  : OUT STD_LOGIC_VECTOR(7 DOWNTO 0);   	-- data from peripheral 
 
   		rst_n		: IN STD_LOGIC			
  		);
END ioport;
 
ARCHITECTURE beh OF ioport IS
 
	SIGNAL PxIN  : STD_LOGIC_VECTOR(7 DOWNTO 0);
	SIGNAL PxOUT : STD_LOGIC_VECTOR(7 DOWNTO 0);
	SIGNAL PxDIR : STD_LOGIC_VECTOR(7 DOWNTO 0);
	SIGNAL PxSEL : STD_LOGIC_VECTOR(7 DOWNTO 0);
 
	SIGNAL PxIES : STD_LOGIC_VECTOR(7 DOWNTO 0);
	SIGNAL PxIE  : STD_LOGIC_VECTOR(7 DOWNTO 0);
	SIGNAL PxIFG : STD_LOGIC_VECTOR(7 DOWNTO 0);
 
	SIGNAL IRQ_S : STD_LOGIC;
   SIGNAL CLK_S : STD_LOGIC;
 
	SIGNAL ifg_clk : std_logic_vector(7 downto 0);
	SIGNAL int     : std_logic_vector(7 downto 0);
 
BEGIN
 
	CLK_S <= clk;
 
-------------------------------------------------------------------------------------
-- INTERRUPTS
-------------------------------------------------------------------------------------
 
	int_edge_gen: for i in 0 to 7 generate
	begin
		process (PxIN(i), PxSEL(i), PxIES(i))
		begin
			if PxSEL(i) = '0' then
				if PxIES(i) = '0' then
					int(i) <= PxIN(i);
				else	
					int(i) <= not(PxIN(i));
				end if;
			else
				int(i) <= '0';
			end if;
		end process;
	end generate;
 
	-- generate access clocks to PxIFG, CPU acces has priority
	ifg_clk_gen: for i in 0 to 7 generate
	begin
		ifg_clk(i) <= not(mdbwr_n) when (cs_n = '0' and mab = "110") else int(i); 
	end generate;
 
	-- write PxIFG
	PxIFG_gen: for i in 0 to 7 generate
	begin
	write_ifg : PROCESS (rst_n, ifg_clk(i))
	BEGIN
		IF rst_n = '0' THEN
			PxIFG(i) <= '0';
		ELSE
		   IF (ifg_clk(i)'event and ifg_clk(i) = '1') THEN
				IF cs_n = '0' and mab = "110" THEN
					IF mdbwr_n = '0' THEN
						PxIFG(i) <= PxIFG(i) and not(mdb_i(i));
					END IF;
				ELSE
					PxIFG (i) <= '1';
				END IF;
			END IF;
		END IF;
	END PROCESS;
	end generate;
 
-------------------------------------------------------------------------------------
-- REGISTERS
-------------------------------------------------------------------------------------
 
 
	-------------------------------------------------------------------------------------
	-- write registers
	-------------------------------------------------------------------------------------
 
	-- PxDIR
	write_l_proc : PROCESS(rst_n, mdbwr_n)
	BEGIN
		IF rst_n = '0' THEN
			PxDIR <= (OTHERS => '0');			
			PxOUT <= (OTHERS => '0');			
			PxSEL <= (OTHERS => '0');
			PxIES <= (OTHERS => '0');
			PxIE  <= (OTHERS => '0');
		ELSE
			if (mdbwr_n'event and mdbwr_n = '0') then
				IF cs_n = '0' THEN
					CASE mab IS
						WHEN "000" => PxDIR <= mdb_i;
						WHEN "001" => PxOUT <= mdb_i;
						WHEN "011" => PxSEL <= mdb_i;
						WHEN "100" => PxIES <= mdb_i;
						WHEN "101" => PxIE <= mdb_i;
						WHEN others => null;
					END CASE;
				end if;
			end if;
		END IF;
	END PROCESS;
 
  	-------------------------------------------------------------------------------------
	-- read registers
	-------------------------------------------------------------------------------------
 
	mdb_o <= PxDIR when cs_n = '0' and mab = "000" else
	         PxOUT when cs_n = '0' and mab = "001" else
				PxIN  when cs_n = '0' and mab = "010" else
				PxSEL when cs_n = '0' and mab = "011" else
				PxIES when cs_n = '0' and mab = "100" else
				PxIE  when cs_n = '0' and mab = "101" else
				PxIFG when cs_n = '0' and mab = "110" else
				(others => '0');
 
-------------------------------------------------------------------------------------
-- EXTERNAL PORTS
-------------------------------------------------------------------------------------
 
	-- PnOEN
	gen_PnOEN: for i in 0 to 7 generate
	begin
		-- PnOEN(i) <= NOT (MODxDIR(i)) when PxSEL(i) = '1' else NOT (PxDIR(i));
		PnOEN(i) <= PxDIR(i);
	end generate;
 
	-- PnOUT
	gen_PnOUT: for i in 0 to 7 generate
	begin
		-- PnOUT (i) <= MODxIN(i) when PxSEL(i) = '1' else PxOUT(i);
		PnOUT(i) <= PxOUT(i);
	end generate;
 
	-- PxIN
	PxIN <= PnIN;
 
	-- MODxOUT
--	gen_MODxOUT: for i in 0 to 7 generate
--	begin
--		MODxOUT_proc: process (rst_n, PxIN, PxSEL)
--		begin
--			if rst_n = '0' then
--				MODxOUT(i) <= '0';
--			elsif PxSEL(i) = '1' then
--				MODxOUT(i) <= PxIN(i);
--			end if;
--		end process;
--	end generate;
 
	irq_en : process(rst_n, clk_s)
	begin
		IF (rst_n = '0') THEN
			 IRQ_S <= '0';
		ELSE
			if (clk_s'EVENT AND clk_s = '0') THEN	-- falling SCKL edge
				if (irqAck = '1') then
					IRQ_S <= '0';
				else
					if ((PxIE(0) = '1' and PxIFG(0) = '1') or (PxIE(1) = '1' and PxIFG(1) = '1') or (PxIE(2) = '1' and PxIFG(2) = '1') or (PxIE(3) = '1' and PxIFG(3) = '1') or
	                (PxIE(4) = '1' and PxIFG(4) = '1') or (PxIE(5) = '1' and PxIFG(5) = '1') or (PxIE(6) = '1' and PxIFG(6) = '1') or (PxIE(7) = '1' and PxIFG(7) = '1')) then
 
						IRQ_S <= '1';
					end if;
				end if;
			end if;
		end if;
	end process;
 
	irq <= IRQ_S;
END beh;
 
 
 
 

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.