URL
https://opencores.org/ocsvn/tinyvliw8/tinyvliw8/trunk
Subversion Repositories tinyvliw8
[/] [tinyvliw8/] [trunk/] [src/] [vhdl/] [ioport.vhd] - Rev 10
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) 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; 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;