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

Subversion Repositories System09

[/] [System09/] [trunk/] [rtl/] [VHDL/] [xula_ioport.vhd] - Blame information for rev 169

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

Line No. Rev Author Line
1 122 dilbert57
--===========================================================================--
2
--                                                                           --
3
--  xula_ioport.vhd - Synthesizable Dual Bidirectionsal I/O Port             --
4
--                                                                           --
5
--===========================================================================--
6
--
7
--  File name      : xula_ioport.vhd
8
--
9
--  Purpose        : Implements a dual 8 bit bidirectional I/O port
10
--                   modified for the XuLA implementation of System09
11
--                   Port A supports a full 8 bit bidirectional port
12
--                   Port B supports a 5 bit bidirectional port with 3 inputs 
13
-- 
14
--  Dependencies   : ieee.std_logic_1164
15
--                   ieee.std_logic_unsigned
16
--                   unisim.vcomponents
17
--
18
--  Author         : John E. Kent
19
--
20
--  Email          : dilbert57@opencores.org      
21
--
22
--  Web            : http://opencores.org/project,system09
23
--
24
--  xula_ioport.vhd is a dual bi-directional 8 bit I/O port written in VHDL.
25
--
26
--  address  function
27
--  =======  ========
28
--  base+0   port a data register
29
--           bits 0 - 7 = i/o
30
--  base+1   port b data register
31
--           bits 0 - 4 = i/o
32
--           bits 5 - 7 - inputs
33
--  base+2   port a direction register 
34
--           0 => port a bit = input
35
--           1 => port a bit = output
36
--  base+3   port b direction
37
--           For bits 0 to 4:
38
--           0 => port b bit = input
39
--           1 => port b bit = output
40
--           For bits 5 to 7:
41
--           0 => port b bit = interrupt disable
42
--           1 => port b bit = interrupt enable
43
--           interrupt inputs on port b bits 5 to 7 are active high
44
--
45
--  Copyright (C) 2002 - 2011 John Kent
46
--
47
--  This program is free software: you can redistribute it and/or modify
48
--  it under the terms of the GNU General Public License as published by
49
--  the Free Software Foundation, either version 3 of the License, or
50
--  (at your option) any later version.
51
--
52
--  This program is distributed in the hope that it will be useful,
53
--  but WITHOUT ANY WARRANTY; without even the implied warranty of
54
--  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
55
--  GNU General Public License for more details.
56
--
57
--  You should have received a copy of the GNU General Public License
58
--  along with this program.  If not, see <http://www.gnu.org/licenses/>.
59
--
60
--===========================================================================--
61
--                                                                           --
62
--                              Revision  History                            --
63
--                                                                           --
64
--===========================================================================--
65
--
66
-- Version  Author        Date               Description
67
-- 0.1      John E. Kent  11 October 2002    Used a loop counter for 
68
--                                           data direction & read port signals
69
-- 0.2      John E. Kent  5 September 2003   Reduced to 2 x 8 bit ports
70
-- 1.0      John E. Kent  6 September 2003   Changed Clock Edge
71
-- 1.1      John E. Kent  25 Februrary 2007  Modified sensitivity lists
72
-- 1.2      John E. Kent  30 May 2010        Updated Header, added unisim library
73
-- 2.0      John E. Kent  30 April 2011      modified for XuLA System09 I/O
74
--===========================================================================
75
--
76
 
77
library ieee;
78
  use ieee.std_logic_1164.all;
79
  use ieee.std_logic_unsigned.all;
80
--library unisim;
81
--  use unisim.vcomponents.all;
82
 
83
entity xula_ioport is
84
  port (
85
    clk       : in    std_logic;
86
    rst       : in    std_logic;
87
    cs        : in    std_logic;
88
    rw        : in    std_logic;
89
    addr      : in    std_logic_vector(1 downto 0);
90
    data_in   : in    std_logic_vector(7 downto 0);
91
    data_out  : out   std_logic_vector(7 downto 0);
92
    porta_io  : inout std_logic_vector(7 downto 0);
93
    portb_io  : inout std_logic_vector(4 downto 0);
94
    portc_in  : in    std_logic_vector(7 downto 5);
95
    irq       : out   std_logic
96
  );
97
end;
98
 
99
architecture rtl of xula_ioport is
100
 
101
signal porta_ddr : std_logic_vector(7 downto 0);
102
signal portb_ddr : std_logic_vector(7 downto 0);
103
signal porta_data : std_logic_vector(7 downto 0);
104
signal portb_data : std_logic_vector(7 downto 0);
105
 
106
begin
107
 
108
 
109
--------------------------------
110
--
111
-- read I/O port
112
--
113
--------------------------------
114
 
115
ioport_read : process( addr,
116
                     porta_ddr, portb_ddr,
117
                                                        porta_data, portb_data,
118
                                                   porta_io, portb_io )
119
variable count : integer;
120
begin
121
  case addr is
122
  when "00" =>
123
    for count in 0 to 7 loop
124
      if porta_ddr(count) = '1' then
125
        data_out(count) <= porta_data(count);
126
      else
127
        data_out(count) <= porta_io(count);
128
      end if;
129
    end loop;
130
 
131
  when "01" =>
132
    for count in 0 to 7 loop
133
      if portb_ddr(count) = '1' then
134
        data_out(count) <= portb_data(count);
135
      else
136
                  if count < 5 then
137
          data_out(count) <= portb_io(count);
138
                  else
139
          data_out(count) <= portc_in(count);
140
                  end if;
141
      end if;
142
    end loop;
143
 
144
  when "10" =>
145
    data_out <= porta_ddr;
146
  when "11" =>
147
    data_out <= portb_ddr;
148
  when others =>
149
    null;
150
  end case;
151
 
152
end process;
153
 
154
---------------------------------
155
--
156
-- Write I/O ports
157
--
158
---------------------------------
159
 
160
ioport_write : process( clk, rst, addr, cs, rw, data_in,
161
                        porta_data, portb_data,
162
                                                                porta_ddr, portb_ddr )
163
begin
164
  if clk'event and clk = '0' then
165
    if rst = '1' then
166
      porta_data <= (others=>'0');
167
      portb_data <= (others=>'0');
168
      porta_ddr  <= (others=>'0');
169
      portb_ddr  <= (others=>'0');
170
    else
171
      if cs = '1' and rw = '0' then
172
        case addr is
173
        when "00" =>
174
           porta_data <= data_in;
175
        when "01" =>
176
           portb_data <= data_in;
177
        when "10" =>
178
           porta_ddr  <= data_in;
179
        when "11" =>
180
           portb_ddr  <= data_in;
181
        when others =>
182
           null;
183
        end case;
184
      end if;
185
    end if;
186
  end if;
187
end process;
188
 
189
---------------------------------
190
--
191
-- direction control port a
192
--
193
---------------------------------
194
porta_direction : process ( porta_data, porta_ddr )
195
variable count : integer;
196
begin
197
  for count in 0 to 7 loop
198
    if porta_ddr(count) = '1' then
199
      porta_io(count) <= porta_data(count);
200
    else
201
      porta_io(count) <= 'Z';
202
    end if;
203
  end loop;
204
end process;
205
---------------------------------
206
--
207
-- direction control port b
208
--
209
---------------------------------
210
portb_direction : process ( portb_data, portb_ddr, portb_io )
211
variable count : integer;
212
variable irq_temp : std_logic;
213
begin
214
  --
215
  -- For bit 0 to 4 DDR determines the direction of the port
216
  --
217
  for count in 0 to 4 loop
218
    if portb_ddr(count) = '1' then
219
      portb_io(count) <= portb_data(count);
220
    else
221
      portb_io(count) <= 'Z';
222
    end if;
223
  end loop;
224
 
225
  --
226
  -- For bit 5 to 7 DDR is an interrupt enable
227
  --
228
  irq_temp := '0';
229
  for count in 5 to 7 loop
230
    irq_temp := (portc_in(count) AND portb_ddr(count)) OR irq_temp;
231
  end loop;
232
  irq <= irq_temp;
233
end process;
234
---------------------------------
235
 
236
end rtl;
237
 

powered by: WebSVN 2.1.0

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