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

Subversion Repositories System09

[/] [System09/] [trunk/] [rtl/] [System09_Xess_XuLA/] [eioport.vhd] - Blame information for rev 138

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

Line No. Rev Author Line
1 122 dilbert57
--===========================================================================--
2
--                                                                           --
3
--      eioport.vhd - Synthesizable Enhanced Bidirectionsal I/O Port         --
4
--                                                                           --
5
--===========================================================================--
6
--
7
--  File name      : eioport.vhd
8
--
9
--  Purpose        : Implements an enhanced bidirectional I/O port which is 
10
--                   capable of generating an interrupt output from each of 
11
--                   the input port lines. It is intended for use with system09 
12
--                   and other systemXX microcomputer systems on a chip. 
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
--  Description    : The enhanced I/O port is mapped as 4 contiguous registers,
25
--                   a data register, data direction register, interrupt enable 
26
--                   register and interrupt input level register. All registers 
27
--                   are readable and writable.
28
--
29
--                   The data bus width is specified with a generic and defaults
30
--                   to 8 bits. 
31
--
32
--                   The Data Register holds the output value when written to
33
--                   When read, reads the input port levels if the correponding 
34
--                   data direction bit is set to a zero or reads the output register
35
--                   value if the corresponding data direction bit is set to a one.
36
--
37
--                   The Data Direction Register determines if individual bits
38
--                   on the IO port are inputs or outputs. If a data direction bit
39
--                   is set to zero the corresponding io port bit is set to an input.
40
--                   If the data direction bit is set to a one the corresponding 
41
--                   io port bit is set to an output.
42
--
43
--                   Each port bit can generate an interrupt if programmed as an input
44
--                   and if the corresponding interrupt enable bit is set. 
45
--                   An Interrupt Enable Register is used to enable an interrupt from each
46
--                   of the inputs on the io port if the interrupt enable bit is set to 
47
--                   a one or disables an interrupt from that bit if set to a zero.
48
--
49
--                   An Interrupt Level Register determines if a high or a low level input 
50
--                   on the io port generates an active high on the interrupt output. 
51
--                   If the interrupt level register bit is set to a zero then a high level
52
--                   input on the corresporting io port bit will generate a high interrupt
53
--                   output. If the interrupt level bit is set to a one then a low level on 
54
--                   the corrrsponding input bit will generate a high interrupt output level
55
--                   on IRQ.
56
--
57
--  address  function
58
--  =======  ========
59
--  base+0   port data register
60
--           bits 0 - 7 = I/O
61
--  base+1   port direction register 
62
--           0 => port bit = input
63
--           1 => port bit = output
64
--  base+2   port nterrupt enable register
65
--           0 => port bit = interrupt disabled
66
--           1 => port bit = interrupt enabled
67
--  base+3   port interrupt level register
68
--           0 => port bit = logic high interrupt
69
--           1 => port bit = logic low interrupt
70
--
71
--  Copyright (C) 2002 - 2011 John Kent
72
--
73
--  This program is free software: you can redistribute it and/or modify
74
--  it under the terms of the GNU General Public License as published by
75
--  the Free Software Foundation, either version 3 of the License, or
76
--  (at your option) any later version.
77
--
78
--  This program is distributed in the hope that it will be useful,
79
--  but WITHOUT ANY WARRANTY; without even the implied warranty of
80
--  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
81
--  GNU General Public License for more details.
82
--
83
--  You should have received a copy of the GNU General Public License
84
--  along with this program.  If not, see <http://www.gnu.org/licenses/>.
85
--
86
--===========================================================================--
87
--                                                                           --
88
--                              Revision  History                            --
89
--                                                                           --
90
--===========================================================================--
91
--
92
-- Version  Author        Date               Description
93
-- 0.1      John E. Kent  11 October 2002    Used a loop counter for 
94
--                                           data direction & read port signals
95
-- 0.2      John E. Kent  5 September 2003   Reduced to 2 x 8 bit ports
96
-- 1.0      John E. Kent  6 September 2003   Changed Clock Edge
97
-- 1.1      John E. Kent  25 Februrary 2007  Modified sensitivity lists
98
-- 1.2      John E. Kent  30 May 2010        Updated Header, added unisim library
99
-- 2.0      John E. Kent  30 April 2011      modified for XuLA System09 I/O
100
-- 3.0      John E. Kent   1 May 2011        single enhanced io port with additional
101
--                                           interrupt enable & level registers
102
--===========================================================================
103
--
104
 
105
library ieee;
106
  use ieee.std_logic_1164.all;
107
  use ieee.std_logic_unsigned.all;
108
--library unisim;
109
--  use unisim.vcomponents.all;
110
 
111
entity eioport is
112
  generic (
113
    DATA_WIDTH : integer := 8
114
  );
115
 
116
  port (
117
    clk       : in    std_logic;
118
    rst       : in    std_logic;
119
    cs        : in    std_logic;
120
    rw        : in    std_logic;
121
    addr      : in    std_logic_vector(1 downto 0);
122
    data_in   : in    std_logic_vector(DATA_WIDTH-1 downto 0);
123
    data_out  : out   std_logic_vector(DATA_WIDTH-1 downto 0);
124
    port_io   : inout std_logic_vector(DATA_WIDTH-1 downto 0);
125
    irq       : out   std_logic
126
  );
127
end;
128
 
129
architecture rtl of eioport is
130
 
131
signal port_out : std_logic_vector(DATA_WIDTH-1 downto 0);  -- output register
132
signal port_ddr : std_logic_vector(DATA_WIDTH-1 downto 0);  -- data direction register
133
signal port_ier : std_logic_vector(DATA_WIDTH-1 downto 0);  -- interrupt enable register
134
signal port_ilr : std_logic_vector(DATA_WIDTH-1 downto 0);  -- interrupt level register
135
 
136
begin
137
 
138
--------------------------------
139
--
140
-- read port registers
141
--
142
--------------------------------
143
 
144
eioport_read : process( addr, port_out, port_io, port_ddr, port_ier, port_ilr)
145
variable count : integer;
146
begin
147
  case addr is
148
  when "00" =>
149
    for count in 0 to (DATA_WIDTH-1) loop
150
      if port_ddr(count) = '1' then
151
        data_out(count) <= port_out(count);
152
      else
153
        data_out(count) <= port_io(count);
154
      end if;
155
    end loop;
156
  when "01" =>
157
    data_out <= port_ddr;
158
  when "10" =>
159
    data_out <= port_ier;
160
  when "11" =>
161
    data_out <= port_ilr;
162
  when others =>
163
    null;
164
  end case;
165
 
166
end process;
167
 
168
---------------------------------
169
--
170
-- Write port registers
171
--
172
---------------------------------
173
 
174
eioport_write : process( clk, rst, cs, rw, addr, data_in )
175
begin
176
  if clk'event and clk = '0' then
177
    if rst = '1' then
178
      port_out <= (others=>'0');
179
      port_ddr <= (others=>'0');
180
      port_ier <= (others=>'0');
181
      port_ilr <= (others=>'0');
182
    else
183
      if cs = '1' and rw = '0' then
184
        case addr is
185
        when "00" =>
186
           port_out <= data_in;
187
        when "01" =>
188
           port_ddr <= data_in;
189
        when "10" =>
190
           port_ier <= data_in;
191
        when "11" =>
192
           port_ilr <= data_in;
193
        when others =>
194
           null;
195
        end case;
196
      end if;
197
    end if;
198
  end if;
199
end process;
200
 
201
---------------------------------
202
--
203
-- direction control
204
--
205
---------------------------------
206
eioport_direction : process ( port_ddr, port_out )
207
variable count : integer;
208
begin
209
  for count in 0 to (DATA_WIDTH-1) loop
210
    if port_ddr(count) = '1' then
211
      port_io(count) <= port_out(count);
212
    else
213
      port_io(count) <= 'Z';
214
    end if;
215
  end loop;
216
end process;
217
 
218
 
219
---------------------------------
220
--
221
-- interrupt control
222
--
223
---------------------------------
224
eioport_interrupt : process ( port_io, port_ilr, port_ddr, port_ier )
225
variable count : integer;
226
variable irq_temp : std_logic;
227
begin
228
  --
229
  -- Interrupt level sets the polarity of the interrupt
230
  -- Data direction register must be set for input
231
  -- Interrupt enable bit must be set to generate an interrupt
232
  --
233
  irq_temp := '0';
234
  for count in 0 to (DATA_WIDTH-1) loop
235
    irq_temp := (((port_io(count) xor port_ilr(count)) and not(port_ddr(count)))
236
                   and port_ier(count)) or irq_temp;
237
  end loop;
238
  irq <= irq_temp;
239
end process;
240
---------------------------------
241
 
242
end rtl;
243
 

powered by: WebSVN 2.1.0

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