--===========================================================================--
|
--===========================================================================--
|
-- --
|
-- --
|
-- ioport.vhd - Synthesizable Dual Bidirectionsal I/O Port --
|
-- ioport.vhd - Synthesizable Dual Bidirectionsal I/O Port --
|
-- --
|
-- --
|
--===========================================================================--
|
--===========================================================================--
|
--
|
--
|
-- File name : ioport.vhd
|
-- File name : ioport.vhd
|
--
|
--
|
-- Purpose : Implements a dual 8 bit bidirectional I/O port
|
-- Purpose : Implements a dual 8 bit bidirectional I/O port
|
--
|
--
|
-- Dependencies : ieee.std_logic_1164
|
-- Dependencies : ieee.std_logic_1164
|
-- ieee.std_logic_unsigned
|
-- ieee.std_logic_unsigned
|
-- unisim.vcomponents
|
-- unisim.vcomponents
|
--
|
--
|
-- Author : John E. Kent
|
-- Author : John E. Kent
|
--
|
--
|
-- Email : dilbert57@opencores.org
|
-- Email : dilbert57@opencores.org
|
--
|
--
|
-- Web : http://opencores.org/project,system09
|
-- Web : http://opencores.org/project,system09
|
--
|
--
|
-- ioport.vhd is a dual bi-directional 8 bit I/O port written in VHDL.
|
-- ioport.vhd is a dual bi-directional 8 bit I/O port written in VHDL.
|
--
|
--
|
-- Copyright (C) 2002 - 2010 John Kent
|
-- Copyright (C) 2002 - 2010 John Kent
|
--
|
--
|
-- This program is free software: you can redistribute it and/or modify
|
-- This program is free software: you can redistribute it and/or modify
|
-- it under the terms of the GNU General Public License as published by
|
-- it under the terms of the GNU General Public License as published by
|
-- the Free Software Foundation, either version 3 of the License, or
|
-- the Free Software Foundation, either version 3 of the License, or
|
-- (at your option) any later version.
|
-- (at your option) any later version.
|
--
|
--
|
-- This program is distributed in the hope that it will be useful,
|
-- This program is distributed in the hope that it will be useful,
|
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
|
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
|
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
-- GNU General Public License for more details.
|
-- GNU General Public License for more details.
|
--
|
--
|
-- You should have received a copy of the GNU General Public License
|
-- You should have received a copy of the GNU General Public License
|
-- along with this program. If not, see <http://www.gnu.org/licenses/>.
|
-- along with this program. If not, see <http://www.gnu.org/licenses/>.
|
--
|
--
|
--===========================================================================--
|
--===========================================================================--
|
-- --
|
-- --
|
-- Revision History --
|
-- Revision History --
|
-- --
|
-- --
|
--===========================================================================--
|
--===========================================================================--
|
--
|
--
|
-- Version Author Date Description
|
-- Version Author Date Description
|
-- 0.1 John E. Kent 11 October 2002 Used a loop counter for
|
-- 0.1 John E. Kent 11 October 2002 Used a loop counter for
|
-- data direction & read port signals
|
-- data direction & read port signals
|
-- 0.2 John E. Kent 5 September 2003 Reduced to 2 x 8 bit ports
|
-- 0.2 John E. Kent 5 September 2003 Reduced to 2 x 8 bit ports
|
-- 1.0 John E. Kent 6 September 2003 Changed Clock Edge
|
-- 1.0 John E. Kent 6 September 2003 Changed Clock Edge
|
-- 1.1 John E. Kent 25 Februrary 2007 Modified sensitivity lists
|
-- 1.1 John E. Kent 25 Februrary 2007 Modified sensitivity lists
|
-- 1.2 John E. Kent 30 May 2010 Updated Header, added unisim library
|
-- 1.2 John E. Kent 30 May 2010 Updated Header, added unisim library
|
--
|
--
|
--===========================================================================
|
--===========================================================================
|
--
|
--
|
|
|
library ieee;
|
library ieee;
|
use ieee.std_logic_1164.all;
|
use ieee.std_logic_1164.all;
|
use ieee.std_logic_unsigned.all;
|
use ieee.std_logic_unsigned.all;
|
library unisim;
|
--library unisim;
|
use unisim.vcomponents.all;
|
-- use unisim.vcomponents.all;
|
|
|
entity ioport is
|
entity ioport is
|
port (
|
port (
|
clk : in std_logic;
|
clk : in std_logic;
|
rst : in std_logic;
|
rst : in std_logic;
|
cs : in std_logic;
|
cs : in std_logic;
|
rw : in std_logic;
|
rw : in std_logic;
|
addr : in std_logic_vector(1 downto 0);
|
addr : in std_logic_vector(1 downto 0);
|
data_in : in std_logic_vector(7 downto 0);
|
data_in : in std_logic_vector(7 downto 0);
|
data_out : out std_logic_vector(7 downto 0);
|
data_out : out std_logic_vector(7 downto 0);
|
porta_io : inout std_logic_vector(7 downto 0);
|
porta_io : inout std_logic_vector(7 downto 0);
|
portb_io : inout std_logic_vector(7 downto 0)
|
portb_io : inout std_logic_vector(7 downto 0)
|
);
|
);
|
end;
|
end;
|
|
|
architecture rtl of ioport is
|
architecture rtl of ioport is
|
|
|
signal porta_ddr : std_logic_vector(7 downto 0);
|
signal porta_ddr : std_logic_vector(7 downto 0);
|
signal portb_ddr : std_logic_vector(7 downto 0);
|
signal portb_ddr : std_logic_vector(7 downto 0);
|
signal porta_data : std_logic_vector(7 downto 0);
|
signal porta_data : std_logic_vector(7 downto 0);
|
signal portb_data : std_logic_vector(7 downto 0);
|
signal portb_data : std_logic_vector(7 downto 0);
|
|
|
begin
|
begin
|
|
|
|
|
--------------------------------
|
--------------------------------
|
--
|
--
|
-- read I/O port
|
-- read I/O port
|
--
|
--
|
--------------------------------
|
--------------------------------
|
|
|
ioport_read : process( addr,
|
ioport_read : process( addr,
|
porta_ddr, portb_ddr,
|
porta_ddr, portb_ddr,
|
porta_data, portb_data,
|
porta_data, portb_data,
|
porta_io, portb_io )
|
porta_io, portb_io )
|
variable count : integer;
|
variable count : integer;
|
begin
|
begin
|
case addr is
|
case addr is
|
when "00" =>
|
when "00" =>
|
for count in 0 to 7 loop
|
for count in 0 to 7 loop
|
if porta_ddr(count) = '1' then
|
if porta_ddr(count) = '1' then
|
data_out(count) <= porta_data(count);
|
data_out(count) <= porta_data(count);
|
else
|
else
|
data_out(count) <= porta_io(count);
|
data_out(count) <= porta_io(count);
|
end if;
|
end if;
|
end loop;
|
end loop;
|
|
|
when "01" =>
|
when "01" =>
|
for count in 0 to 7 loop
|
for count in 0 to 7 loop
|
if portb_ddr(count) = '1' then
|
if portb_ddr(count) = '1' then
|
data_out(count) <= portb_data(count);
|
data_out(count) <= portb_data(count);
|
else
|
else
|
data_out(count) <= portb_io(count);
|
data_out(count) <= portb_io(count);
|
end if;
|
end if;
|
end loop;
|
end loop;
|
|
|
when "10" =>
|
when "10" =>
|
data_out <= porta_ddr;
|
data_out <= porta_ddr;
|
when "11" =>
|
when "11" =>
|
data_out <= portb_ddr;
|
data_out <= portb_ddr;
|
when others =>
|
when others =>
|
null;
|
null;
|
end case;
|
end case;
|
end process;
|
end process;
|
|
|
---------------------------------
|
---------------------------------
|
--
|
--
|
-- Write I/O ports
|
-- Write I/O ports
|
--
|
--
|
---------------------------------
|
---------------------------------
|
|
|
ioport_write : process( clk, rst, addr, cs, rw, data_in,
|
ioport_write : process( clk, rst, addr, cs, rw, data_in,
|
porta_data, portb_data,
|
porta_data, portb_data,
|
porta_ddr, portb_ddr )
|
porta_ddr, portb_ddr )
|
begin
|
begin
|
if clk'event and clk = '0' then
|
if clk'event and clk = '0' then
|
if rst = '1' then
|
if rst = '1' then
|
porta_data <= "00000000";
|
porta_data <= "00000000";
|
portb_data <= "00000000";
|
portb_data <= "00000000";
|
porta_ddr <= "00000000";
|
porta_ddr <= "00000000";
|
portb_ddr <= "00000000";
|
portb_ddr <= "00000000";
|
elsif cs = '1' and rw = '0' then
|
elsif cs = '1' and rw = '0' then
|
case addr is
|
case addr is
|
when "00" =>
|
when "00" =>
|
porta_data <= data_in;
|
porta_data <= data_in;
|
portb_data <= portb_data;
|
portb_data <= portb_data;
|
porta_ddr <= porta_ddr;
|
porta_ddr <= porta_ddr;
|
portb_ddr <= portb_ddr;
|
portb_ddr <= portb_ddr;
|
when "01" =>
|
when "01" =>
|
porta_data <= porta_data;
|
porta_data <= porta_data;
|
portb_data <= data_in;
|
portb_data <= data_in;
|
porta_ddr <= porta_ddr;
|
porta_ddr <= porta_ddr;
|
portb_ddr <= portb_ddr;
|
portb_ddr <= portb_ddr;
|
when "10" =>
|
when "10" =>
|
porta_data <= porta_data;
|
porta_data <= porta_data;
|
portb_data <= portb_data;
|
portb_data <= portb_data;
|
porta_ddr <= data_in;
|
porta_ddr <= data_in;
|
portb_ddr <= portb_ddr;
|
portb_ddr <= portb_ddr;
|
when "11" =>
|
when "11" =>
|
porta_data <= porta_data;
|
porta_data <= porta_data;
|
portb_data <= portb_data;
|
portb_data <= portb_data;
|
porta_ddr <= porta_ddr;
|
porta_ddr <= porta_ddr;
|
portb_ddr <= data_in;
|
portb_ddr <= data_in;
|
when others =>
|
when others =>
|
null;
|
null;
|
end case;
|
end case;
|
else
|
else
|
porta_data <= porta_data;
|
porta_data <= porta_data;
|
portb_data <= portb_data;
|
portb_data <= portb_data;
|
porta_ddr <= porta_ddr;
|
porta_ddr <= porta_ddr;
|
portb_ddr <= portb_ddr;
|
portb_ddr <= portb_ddr;
|
end if;
|
end if;
|
end if;
|
end if;
|
end process;
|
end process;
|
|
|
---------------------------------
|
---------------------------------
|
--
|
--
|
-- direction control port a
|
-- direction control port a
|
--
|
--
|
---------------------------------
|
---------------------------------
|
porta_direction : process ( porta_data, porta_ddr )
|
porta_direction : process ( porta_data, porta_ddr )
|
variable count : integer;
|
variable count : integer;
|
begin
|
begin
|
for count in 0 to 7 loop
|
for count in 0 to 7 loop
|
if porta_ddr(count) = '1' then
|
if porta_ddr(count) = '1' then
|
porta_io(count) <= porta_data(count);
|
porta_io(count) <= porta_data(count);
|
else
|
else
|
porta_io(count) <= 'Z';
|
porta_io(count) <= 'Z';
|
end if;
|
end if;
|
end loop;
|
end loop;
|
end process;
|
end process;
|
---------------------------------
|
---------------------------------
|
--
|
--
|
-- direction control port b
|
-- direction control port b
|
--
|
--
|
---------------------------------
|
---------------------------------
|
portb_direction : process ( portb_data, portb_ddr )
|
portb_direction : process ( portb_data, portb_ddr )
|
variable count : integer;
|
variable count : integer;
|
begin
|
begin
|
for count in 0 to 7 loop
|
for count in 0 to 7 loop
|
if portb_ddr(count) = '1' then
|
if portb_ddr(count) = '1' then
|
portb_io(count) <= portb_data(count);
|
portb_io(count) <= portb_data(count);
|
else
|
else
|
portb_io(count) <= 'Z';
|
portb_io(count) <= 'Z';
|
end if;
|
end if;
|
end loop;
|
end loop;
|
end process;
|
end process;
|
---------------------------------
|
---------------------------------
|
|
|
end rtl;
|
end rtl;
|
|
|
|
|