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

Subversion Repositories mips_enhanced

[/] [mips_enhanced/] [trunk/] [grlib-gpl-1.0.19-b3188/] [lib/] [gaisler/] [misc/] [grgpio.vhd] - Blame information for rev 2

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 dimamali
------------------------------------------------------------------------------
2
--  This file is a part of the GRLIB VHDL IP LIBRARY
3
--  Copyright (C) 2003, Gaisler Research
4
--
5
--  This program is free software; you can redistribute it and/or modify
6
--  it under the terms of the GNU General Public License as published by
7
--  the Free Software Foundation; either version 2 of the License, or
8
--  (at your option) any later version.
9
--
10
--  This program is distributed in the hope that it will be useful,
11
--  but WITHOUT ANY WARRANTY; without even the implied warranty of
12
--  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
--  GNU General Public License for more details.
14
--
15
--  You should have received a copy of the GNU General Public License
16
--  along with this program; if not, write to the Free Software
17
--  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA 
18
-----------------------------------------------------------------------------
19
-- Entity:      gpio
20
-- File:        gpio.vhd
21
-- Author:      Jiri Gaisler - Gaisler Research
22
-- Description: Scalable general-purpose I/O port
23
------------------------------------------------------------------------------
24
 
25
library ieee;
26
use ieee.std_logic_1164.all;
27
library grlib;
28
use grlib.amba.all;
29
use grlib.stdlib.all;
30
use grlib.devices.all;
31
library gaisler;
32
use gaisler.misc.all;
33
--pragma translate_off
34
use std.textio.all;
35
--pragma translate_on
36
 
37
entity grgpio is
38
  generic (
39
    pindex   : integer := 0;
40
    paddr    : integer := 0;
41
    pmask    : integer := 16#fff#;
42
    imask    : integer := 16#0000#;
43
    nbits    : integer := 16;                   -- GPIO bits
44
    oepol    : integer := 0;                    -- Output enable polarity
45
    syncrst  : integer := 0;                    -- Only synchronous reset
46
    bypass   : integer := 16#0000#;
47
    scantest : integer := 0;
48
    bpdir    : integer := 16#0000#
49
  );
50
  port (
51
    rst    : in  std_ulogic;
52
    clk    : in  std_ulogic;
53
    apbi   : in  apb_slv_in_type;
54
    apbo   : out apb_slv_out_type;
55
    gpioi  : in  gpio_in_type;
56
    gpioo  : out gpio_out_type
57
  );
58
end;
59
 
60
architecture rtl of grgpio is
61
 
62
constant REVISION : integer := 0;
63
constant PIMASK : std_logic_vector(31 downto 0) := '0' & conv_std_logic_vector(imask, 31);
64
 
65
constant BPMASK : std_logic_vector(31 downto 0) := conv_std_logic_vector(bypass, 32);
66
constant BPDIRM  : std_logic_vector(31 downto 0) := conv_std_logic_vector(bpdir, 32);
67
 
68
constant pconfig : apb_config_type := (
69
 
70
  1 => apb_iobar(paddr, pmask));
71
 
72
type registers is record
73
  din1          :  std_logic_vector(nbits-1 downto 0);
74
  din2          :  std_logic_vector(nbits-1 downto 0);
75
  dout          :  std_logic_vector(nbits-1 downto 0);
76
  imask         :  std_logic_vector(nbits-1 downto 0);
77
  level         :  std_logic_vector(nbits-1 downto 0);
78
  edge          :  std_logic_vector(nbits-1 downto 0);
79
  ilat          :  std_logic_vector(nbits-1 downto 0);
80
  dir           :  std_logic_vector(nbits-1 downto 0);
81
  bypass        :  std_logic_vector(nbits-1 downto 0);
82
end record;
83
 
84
signal r, rin : registers;
85
signal arst     : std_ulogic;
86
 
87
begin
88
 
89
  arst <= apbi.testrst when (scantest = 1) and (apbi.testen = '1') else rst;
90
 
91
  comb : process(rst, r, apbi, gpioi)
92
  variable readdata, tmp2, dout, dir, pval, din : std_logic_vector(31 downto 0);
93
  variable v : registers;
94
  variable xirq : std_logic_vector(NAHBIRQ-1 downto 0);
95
  begin
96
 
97
    din := (others => '0');
98
    din(nbits-1 downto 0) := gpioi.din(nbits-1 downto 0);
99
 
100
    v := r; v.din2 := r.din1; v.din1 := din(nbits-1 downto 0);
101
    v.ilat := r.din2; dout := (others => '0'); dir := (others => '0');
102
    dir(nbits-1 downto 0) := r.dir(nbits-1 downto 0);
103
    if (syncrst = 1) and (rst = '0') then
104
      if oepol = 0 then dir(nbits-1 downto 0) := (others => '1');
105
      else dir(nbits-1 downto 0) := (others => '0'); end if;
106
    end if;
107
    dout(nbits-1 downto 0) := r.dout(nbits-1 downto 0);
108
 
109
-- read registers
110
 
111
    readdata := (others => '0');
112
    case apbi.paddr(4 downto 2) is
113
    when "000" => readdata(nbits-1 downto 0) := r.din2;
114
    when "001" => readdata(nbits-1 downto 0) := r.dout;
115
    when "010" =>
116
      if oepol = 0 then readdata(nbits-1 downto 0) := not r.dir;
117
      else readdata(nbits-1 downto 0) := r.dir; end if;
118
    when "011" =>
119
      if (imask /= 0) then
120
        readdata(nbits-1 downto 0) :=
121
          r.imask(nbits-1 downto 0) and PIMASK(nbits-1 downto 0);
122
      end if;
123
    when "100" =>
124
      if (imask /= 0) then
125
        readdata(nbits-1 downto 0) :=
126
          r.level(nbits-1 downto 0) and PIMASK(nbits-1 downto 0);
127
      end if;
128
    when "101" =>
129
      if (imask /= 0) then
130
        readdata(nbits-1 downto 0) :=
131
          r.edge(nbits-1 downto 0) and PIMASK(nbits-1 downto 0);
132
      end if;
133
 
134
    when "110" =>
135
      if (bypass /= 0) then
136
        readdata(nbits-1 downto 0) :=
137
          r.bypass(nbits-1 downto 0) and BPMASK(nbits-1 downto 0);
138
      end if;
139
 
140
    when others =>
141
    end case;
142
 
143
-- write registers
144
 
145
    if (apbi.psel(pindex) and apbi.penable and apbi.pwrite) = '1' then
146
      case apbi.paddr(4 downto 2) is
147
      when "000" => null;
148
      when "001" => v.dout := apbi.pwdata(nbits-1 downto 0);
149
      when "010" =>
150
        if oepol = 0 then v.dir  := not apbi.pwdata(nbits-1 downto 0);
151
        else v.dir := apbi.pwdata(nbits-1 downto 0); end if;
152
      when "011" =>
153
        if (imask /= 0) then
154
          v.imask := apbi.pwdata(nbits-1 downto 0) and PIMASK(nbits-1 downto 0);
155
        end if;
156
      when "100" =>
157
        if (imask /= 0) then
158
          v.level := apbi.pwdata(nbits-1 downto 0) and PIMASK(nbits-1 downto 0);
159
        end if;
160
      when "101" =>
161
        if (imask /= 0) then
162
          v.edge := apbi.pwdata(nbits-1 downto 0) and PIMASK(nbits-1 downto 0);
163
        end if;
164
 
165
      when "110" =>
166
        if (bypass /= 0) then
167
          v.bypass := apbi.pwdata(nbits-1 downto 0) and BPMASK(nbits-1 downto 0);
168
        end if;
169
 
170
      when others =>
171
      end case;
172
    end if;
173
 
174
-- interrupt filtering and routing
175
 
176
    xirq := (others => '0'); tmp2 := (others => '0');
177
    if (imask /= 0) then
178
      tmp2(nbits-1 downto 0) := r.din2;
179
      for i in 0 to nbits-1 loop
180
        if (PIMASK(i) and r.imask(i)) = '1' then
181
          if r.edge(i) = '1' then
182
            if r.level(i) = '1' then tmp2(i) := r.din2(i) and not r.ilat(i);
183
            else tmp2(i) := not r.din2(i) and r.ilat(i); end if;
184
          else tmp2(i) := r.din2(i) xor not r.level(i); end if;
185
        else
186
          tmp2(i) := '0';
187
        end if;
188
      end loop;
189
 
190
      for i in 0 to nbits-1 loop
191
         if i > NAHBIRQ-1 then
192
            exit;
193
         end if;
194
         xirq(i) := tmp2(i);
195
      end loop;
196
    end if;
197
 
198
-- drive filtered inputs on the output record
199
 
200
   pval := (others => '0');
201
   pval(nbits-1 downto 0) := r.din2;
202
 
203
-- Drive output with gpioi.sig_in for bypassed registers
204
   if bypass /= 0 then
205
       for i in 0 to nbits-1 loop
206
           if r.bypass(i) = '1' then
207
               dout(i) := gpioi.sig_in(i);
208
           end if;
209
       end loop;
210
   end if;
211
 
212
-- Drive output with gpioi.sig_in for bypassed registers
213
   if bpdir /= 0 then
214
       for i in 0 to nbits-1 loop
215
           if (BPDIRM(i) and gpioi.sig_en(i)) = '1'   then
216
               dout(i) := gpioi.sig_in(i);
217
               if oepol = 0 then dir(i) := '0'; else dir(i) := '1'; end if;
218
           end if;
219
       end loop;
220
   end if;
221
-- reset operation
222
 
223
    if rst = '0' then
224
      v.imask := (others => '0'); v.bypass := (others => '0');
225
      if oepol = 1 then v.dir := (others => '0');
226
      else v.dir := (others => '1'); end if;
227
      v.dout := (others => '0');
228
    end if;
229
 
230
    rin <= v;
231
 
232
    apbo.prdata <= readdata;    -- drive apb read bus
233
    apbo.pirq <= xirq;
234
 
235
    gpioo.dout <= dout;
236
    gpioo.oen <= dir;
237
    gpioo.val <= pval;
238
 
239
-- non filtered input
240
    gpioo.sig_out <= din;
241
 
242
  end process;
243
 
244
  apbo.pindex <= pindex;
245
  apbo.pconfig <= pconfig;
246
 
247
-- registers
248
 
249
  regs : process(clk, arst)
250
  begin
251
    if rising_edge(clk) then r <= rin; end if;
252
    if (syncrst = 0 ) and (arst = '0') then
253
      if oepol = 1 then r.dir <= (others => '0');
254
      else r.dir <= (others => '1'); end if;
255
    end if;
256
  end process;
257
 
258
-- boot message
259
 
260
-- pragma translate_off
261
    bootmsg : report_version
262
    generic map ("grgpio" & tost(pindex) &
263
        ": " &  tost(nbits) & "-bit GPIO Unit rev " & tost(REVISION));
264
-- pragma translate_on
265
 
266
end;

powered by: WebSVN 2.1.0

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