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

Subversion Repositories gpio

[/] [gpio/] [tags/] [rel_11/] [rtl/] [verilog/] [gpio_top.v] - Blame information for rev 65

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 14 lampret
//////////////////////////////////////////////////////////////////////
2
////                                                              ////
3
////  WISHBONE General-Purpose I/O                                ////
4
////                                                              ////
5
////  This file is part of the GPIO project                       ////
6
////  http://www.opencores.org/cores/gpio/                        ////
7
////                                                              ////
8
////  Description                                                 ////
9
////  Implementation of GPIO IP core according to                 ////
10
////  GPIO IP core specification document.                        ////
11
////                                                              ////
12
////  To Do:                                                      ////
13
////   Nothing                                                    ////
14
////                                                              ////
15
////  Author(s):                                                  ////
16
////      - Damjan Lampret, lampret@opencores.org                 ////
17
////                                                              ////
18
//////////////////////////////////////////////////////////////////////
19
////                                                              ////
20
//// Copyright (C) 2000 Authors and OPENCORES.ORG                 ////
21
////                                                              ////
22
//// This source file may be used and distributed without         ////
23
//// restriction provided that this copyright statement is not    ////
24
//// removed from the file and that any derivative work contains  ////
25
//// the original copyright notice and the associated disclaimer. ////
26
////                                                              ////
27
//// This source file is free software; you can redistribute it   ////
28
//// and/or modify it under the terms of the GNU Lesser General   ////
29
//// Public License as published by the Free Software Foundation; ////
30
//// either version 2.1 of the License, or (at your option) any   ////
31
//// later version.                                               ////
32
////                                                              ////
33
//// This source is distributed in the hope that it will be       ////
34
//// useful, but WITHOUT ANY WARRANTY; without even the implied   ////
35
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR      ////
36
//// PURPOSE.  See the GNU Lesser General Public License for more ////
37
//// details.                                                     ////
38
////                                                              ////
39
//// You should have received a copy of the GNU Lesser General    ////
40
//// Public License along with this source; if not, download it   ////
41
//// from http://www.opencores.org/lgpl.shtml                     ////
42
////                                                              ////
43
//////////////////////////////////////////////////////////////////////
44
//
45
// CVS Revision History
46
//
47
// $Log: not supported by cvs2svn $
48 36 gorand
// Revision 1.14  2003/11/06 13:59:07  gorand
49
// added support for 8-bit access to registers.
50
//
51 34 gorand
// Revision 1.13  2002/11/18 22:35:18  lampret
52
// Bug fix. Interrupts were also asserted when condition was not met.
53
//
54 31 lampret
// Revision 1.12  2002/11/11 21:36:28  lampret
55
// Added ifdef to remove mux from clk_pad_i if mux is not allowed. This also removes RGPIO_CTRL[NEC].
56
//
57 29 lampret
// Revision 1.11  2002/03/13 20:56:28  lampret
58
// Removed zero padding as per Avi Shamli suggestion.
59
//
60 26 lampret
// Revision 1.10  2002/03/13 20:47:57  lampret
61
// Ports changed per Ran Aviram suggestions.
62
//
63 25 lampret
// Revision 1.9  2002/03/09 03:43:27  lampret
64
// Interrupt is asserted only when an input changes (code patch by Jacob Gorban)
65
//
66 24 lampret
// Revision 1.8  2002/01/14 19:06:28  lampret
67
// Changed registered WISHBONE outputs wb_ack_o/wb_err_o to follow WB specification.
68
//
69 23 lampret
// Revision 1.7  2001/12/25 17:21:21  lampret
70
// Fixed two typos.
71
//
72 22 lampret
// Revision 1.6  2001/12/25 17:12:35  lampret
73
// Added RGPIO_INTS.
74
//
75 21 lampret
// Revision 1.5  2001/12/12 20:35:53  lampret
76
// Fixing style.
77
//
78 20 lampret
// Revision 1.4  2001/12/12 07:12:58  lampret
79
// Fixed bug when wb_inta_o is registered (GPIO_WB_REGISTERED_OUTPUTS)
80
//
81 19 lampret
// Revision 1.3  2001/11/15 02:24:37  lampret
82
// Added GPIO_REGISTERED_WB_OUTPUTS, GPIO_REGISTERED_IO_OUTPUTS and GPIO_NO_NEGEDGE_FLOPS.
83
//
84 17 lampret
// Revision 1.2  2001/10/31 02:26:51  lampret
85
// Fixed wb_err_o.
86
//
87 15 lampret
// Revision 1.1  2001/09/18 18:49:07  lampret
88
// Changed top level ptc into gpio_top. Changed defines.v into gpio_defines.v.
89
//
90 14 lampret
// Revision 1.1  2001/08/21 21:39:28  lampret
91
// Changed directory structure, port names and drfines.
92
//
93
// Revision 1.2  2001/07/14 20:39:26  lampret
94
// Better configurability.
95
//
96
// Revision 1.1  2001/06/05 07:45:26  lampret
97
// Added initial RTL and test benches. There are still some issues with these files.
98
//
99
//
100
 
101
// synopsys translate_off
102
`include "timescale.v"
103
// synopsys translate_on
104
`include "gpio_defines.v"
105
 
106
module gpio_top(
107
        // WISHBONE Interface
108
        wb_clk_i, wb_rst_i, wb_cyc_i, wb_adr_i, wb_dat_i, wb_sel_i, wb_we_i, wb_stb_i,
109
        wb_dat_o, wb_ack_o, wb_err_o, wb_inta_o,
110
 
111
        // Auxiliary inputs interface
112
        aux_i,
113
 
114
        // External GPIO Interface
115 25 lampret
        ext_pad_i, clk_pad_i, ext_pad_o, ext_padoen_o
116 14 lampret
);
117
 
118
parameter dw = 32;
119
parameter aw = `GPIO_ADDRHH+1;
120
parameter gw = `GPIO_IOS;
121
//
122
// WISHBONE Interface
123
//
124
input                   wb_clk_i;       // Clock
125
input                   wb_rst_i;       // Reset
126
input                   wb_cyc_i;       // cycle valid input
127
input   [aw-1:0] wb_adr_i;       // address bus inputs
128
input   [dw-1:0] wb_dat_i;       // input data bus
129
input   [3:0]            wb_sel_i;       // byte select inputs
130
input                   wb_we_i;        // indicates write transfer
131
input                   wb_stb_i;       // strobe input
132
output  [dw-1:0] wb_dat_o;       // output data bus
133
output                  wb_ack_o;       // normal termination
134
output                  wb_err_o;       // termination w/ error
135
output                  wb_inta_o;      // Interrupt request output
136
 
137
// Auxiliary Inputs Interface
138
input   [gw-1:0] aux_i;          // Auxiliary inputs
139
 
140
//
141
// External GPIO Interface
142
//
143 25 lampret
input   [gw-1:0] ext_pad_i;      // GPIO Inputs
144
input                   clk_pad_i;      // GPIO Eclk
145
output  [gw-1:0] ext_pad_o;      // GPIO Outputs
146
output  [gw-1:0] ext_padoen_o;   // GPIO output drivers enables
147 14 lampret
 
148
`ifdef GPIO_IMPLEMENTED
149
 
150
//
151
// GPIO Input Register (or no register)
152
//
153
`ifdef GPIO_RGPIO_IN
154
reg     [gw-1:0] rgpio_in;       // RGPIO_IN register
155
`else
156
wire    [gw-1:0] rgpio_in;       // No register
157
`endif
158
 
159
//
160
// GPIO Output Register (or no register)
161
//
162
`ifdef GPIO_RGPIO_OUT
163
reg     [gw-1:0] rgpio_out;      // RGPIO_OUT register
164
`else
165
wire    [gw-1:0] rgpio_out;      // No register
166
`endif
167
 
168
//
169
// GPIO Output Driver Enable Register (or no register)
170
//
171
`ifdef GPIO_RGPIO_OE
172
reg     [gw-1:0] rgpio_oe;       // RGPIO_OE register
173
`else
174
wire    [gw-1:0] rgpio_oe;       // No register
175
`endif
176
 
177
//
178
// GPIO Interrupt Enable Register (or no register)
179
//
180
`ifdef GPIO_RGPIO_INTE
181
reg     [gw-1:0] rgpio_inte;     // RGPIO_INTE register
182
`else
183
wire    [gw-1:0] rgpio_inte;     // No register
184
`endif
185
 
186
//
187
// GPIO Positive edge Triggered Register (or no register)
188
//
189
`ifdef GPIO_RGPIO_PTRIG
190
reg     [gw-1:0] rgpio_ptrig;    // RGPIO_PTRIG register
191
`else
192
wire    [gw-1:0] rgpio_ptrig;    // No register
193
`endif
194
 
195
//
196
// GPIO Auxiliary select Register (or no register)
197
//
198
`ifdef GPIO_RGPIO_AUX
199
reg     [gw-1:0] rgpio_aux;      // RGPIO_AUX register
200
`else
201
wire    [gw-1:0] rgpio_aux;      // No register
202
`endif
203
 
204
//
205
// GPIO Control Register (or no register)
206
//
207
`ifdef GPIO_RGPIO_CTRL
208
reg     [3:0]            rgpio_ctrl;     // RGPIO_CTRL register
209
`else
210
wire    [3:0]            rgpio_ctrl;     // No register
211
`endif
212
 
213
//
214 21 lampret
// GPIO Interrupt Status Register (or no register)
215
//
216
`ifdef GPIO_RGPIO_INTS
217
reg     [gw-1:0] rgpio_ints;     // RGPIO_INTS register
218
`else
219
wire    [gw-1:0] rgpio_ints;     // No register
220
`endif
221
 
222
//
223 14 lampret
// Internal wires & regs
224
//
225
wire                    rgpio_out_sel;  // RGPIO_OUT select
226
wire                    rgpio_oe_sel;   // RGPIO_OE select
227
wire                    rgpio_inte_sel; // RGPIO_INTE select
228
wire                    rgpio_ptrig_sel;// RGPIO_PTRIG select
229
wire                    rgpio_aux_sel;  // RGPIO_AUX select
230
wire                    rgpio_ctrl_sel; // RGPIO_CTRL select
231 21 lampret
wire                    rgpio_ints_sel; // RGPIO_INTS select
232 14 lampret
wire                    latch_clk;      // Latch clock
233
wire                    full_decoding;  // Full address decoding qualification
234 17 lampret
wire    [gw-1:0] in_muxed;       // Muxed inputs
235
wire                    wb_ack;         // WB Acknowledge
236
wire                    wb_err;         // WB Error
237
wire                    wb_inta;        // WB Interrupt
238
reg     [dw-1:0] wb_dat;         // WB Data out
239
`ifdef GPIO_REGISTERED_WB_OUTPUTS
240
reg                     wb_ack_o;       // WB Acknowledge
241
reg                     wb_err_o;       // WB Error
242
reg                     wb_inta_o;      // WB Interrupt
243
reg     [dw-1:0] wb_dat_o;       // WB Data out
244
`endif
245
wire    [gw-1:0] out_pad;        // GPIO Outputs
246
`ifdef GPIO_REGISTERED_IO_OUTPUTS
247 25 lampret
reg     [gw-1:0] ext_pad_o;      // GPIO Outputs
248 17 lampret
`endif
249
wire    [gw-1:0] extc_in;        // Muxed inputs sampled by external clock
250
wire                    pext_clk;       // External clock for posedge flops
251
reg     [gw-1:0] pextc_sampled;  // Posedge external clock sampled inputs
252
`ifdef GPIO_NO_NEGEDGE_FLOPS
253
`else
254
reg     [gw-1:0] nextc_sampled;  // Negedge external clock sampled inputs
255
`endif
256 14 lampret
 
257
//
258
// All WISHBONE transfer terminations are successful except when:
259
// a) full address decoding is enabled and address doesn't match
260
//    any of the GPIO registers
261
// b) wb_sel_i evaluation is enabled and one of the wb_sel_i inputs is zero
262
//
263 17 lampret
 
264
//
265
// WB Acknowledge
266
//
267
assign wb_ack = wb_cyc_i & wb_stb_i & !wb_err_o;
268
 
269
//
270
// Optional registration of WB Ack
271
//
272
`ifdef GPIO_REGISTERED_WB_OUTPUTS
273
always @(posedge wb_clk_i or posedge wb_rst_i)
274
        if (wb_rst_i)
275
                wb_ack_o <= #1 1'b0;
276
        else
277 34 gorand
                wb_ack_o <= #1 wb_ack & ~wb_ack_o & (!wb_err) ;
278 17 lampret
`else
279
assign wb_ack_o = wb_ack;
280
`endif
281
 
282
//
283
// WB Error
284
//
285 14 lampret
`ifdef GPIO_FULL_DECODE
286
`ifdef GPIO_STRICT_32BIT_ACCESS
287 17 lampret
assign wb_err = wb_cyc_i & wb_stb_i & (!full_decoding | (wb_sel_i != 4'b1111));
288 14 lampret
`else
289 17 lampret
assign wb_err = wb_cyc_i & wb_stb_i & !full_decoding;
290 14 lampret
`endif
291
`else
292
`ifdef GPIO_STRICT_32BIT_ACCESS
293 17 lampret
assign wb_err = wb_cyc_i & wb_stb_i & (wb_sel_i != 4'b1111);
294 14 lampret
`else
295 17 lampret
assign wb_err = 1'b0;
296 14 lampret
`endif
297
`endif
298
 
299
//
300 17 lampret
// Optional registration of WB error
301 14 lampret
//
302 17 lampret
`ifdef GPIO_REGISTERED_WB_OUTPUTS
303
always @(posedge wb_clk_i or posedge wb_rst_i)
304
        if (wb_rst_i)
305
                wb_err_o <= #1 1'b0;
306
        else
307 23 lampret
                wb_err_o <= #1 wb_err & ~wb_err_o;
308 17 lampret
`else
309
assign wb_err_o = wb_err;
310
`endif
311 14 lampret
 
312
//
313
// Full address decoder
314
//
315
`ifdef GPIO_FULL_DECODE
316
assign full_decoding = (wb_adr_i[`GPIO_ADDRHH:`GPIO_ADDRHL] == {`GPIO_ADDRHH-`GPIO_ADDRHL+1{1'b0}}) &
317
                        (wb_adr_i[`GPIO_ADDRLH:`GPIO_ADDRLL] == {`GPIO_ADDRLH-`GPIO_ADDRLL+1{1'b0}});
318
`else
319
assign full_decoding = 1'b1;
320
`endif
321
 
322
//
323
// GPIO registers address decoder
324
//
325
assign rgpio_out_sel = wb_cyc_i & wb_stb_i & (wb_adr_i[`GPIO_OFS_BITS] == `GPIO_RGPIO_OUT) & full_decoding;
326
assign rgpio_oe_sel = wb_cyc_i & wb_stb_i & (wb_adr_i[`GPIO_OFS_BITS] == `GPIO_RGPIO_OE) & full_decoding;
327
assign rgpio_inte_sel = wb_cyc_i & wb_stb_i & (wb_adr_i[`GPIO_OFS_BITS] == `GPIO_RGPIO_INTE) & full_decoding;
328
assign rgpio_ptrig_sel = wb_cyc_i & wb_stb_i & (wb_adr_i[`GPIO_OFS_BITS] == `GPIO_RGPIO_PTRIG) & full_decoding;
329
assign rgpio_aux_sel = wb_cyc_i & wb_stb_i & (wb_adr_i[`GPIO_OFS_BITS] == `GPIO_RGPIO_AUX) & full_decoding;
330
assign rgpio_ctrl_sel = wb_cyc_i & wb_stb_i & (wb_adr_i[`GPIO_OFS_BITS] == `GPIO_RGPIO_CTRL) & full_decoding;
331 21 lampret
assign rgpio_ints_sel = wb_cyc_i & wb_stb_i & (wb_adr_i[`GPIO_OFS_BITS] == `GPIO_RGPIO_INTS) & full_decoding;
332 14 lampret
 
333
//
334
// Write to RGPIO_CTRL or update of RGPIO_CTRL[INT] bit
335
//
336
`ifdef GPIO_RGPIO_CTRL
337
always @(posedge wb_clk_i or posedge wb_rst_i)
338
        if (wb_rst_i)
339
                rgpio_ctrl <= #1 4'b0;
340
        else if (rgpio_ctrl_sel && wb_we_i)
341
                rgpio_ctrl <= #1 wb_dat_i[3:0];
342
        else if (rgpio_ctrl[`GPIO_RGPIO_CTRL_INTE])
343 21 lampret
                rgpio_ctrl[`GPIO_RGPIO_CTRL_INTS] <= #1 rgpio_ctrl[`GPIO_RGPIO_CTRL_INTS] | wb_inta_o;
344 14 lampret
`else
345
assign rgpio_ctrl = 4'h01;      // RGPIO_CTRL[EN] = 1
346
`endif
347
 
348
//
349
// Write to RGPIO_OUT
350
//
351
`ifdef GPIO_RGPIO_OUT
352
always @(posedge wb_clk_i or posedge wb_rst_i)
353
        if (wb_rst_i)
354
                rgpio_out <= #1 {gw{1'b0}};
355
        else if (rgpio_out_sel && wb_we_i)
356 34 gorand
    begin
357
`ifdef GPIO_STRICT_32BIT_ACCESS
358 14 lampret
                rgpio_out <= #1 wb_dat_i[gw-1:0];
359 34 gorand
`endif
360
 
361
`ifdef GPIO_WB_BYTES4
362
     if ( wb_sel_i [3] == 1'b1 )
363
       rgpio_out [gw-1:24] <= #1 wb_dat_i [gw-1:24] ;
364
     if ( wb_sel_i [2] == 1'b1 )
365
       rgpio_out [23:16] <= #1 wb_dat_i [23:16] ;
366
     if ( wb_sel_i [1] == 1'b1 )
367
       rgpio_out [15:8] <= #1 wb_dat_i [15:8] ;
368
     if ( wb_sel_i [0] == 1'b1 )
369
       rgpio_out [7:0] <= #1 wb_dat_i [7:0] ;
370
`endif
371
`ifdef GPIO_WB_BYTES3
372
     if ( wb_sel_i [2] == 1'b1 )
373
       rgpio_out [gw-1:16] <= #1 wb_dat_i [gw-1:16] ;
374
     if ( wb_sel_i [1] == 1'b1 )
375
       rgpio_out [15:8] <= #1 wb_dat_i [15:8] ;
376
     if ( wb_sel_i [0] == 1'b1 )
377
       rgpio_out [7:0] <= #1 wb_dat_i [7:0] ;
378
`endif
379
`ifdef GPIO_WB_BYTES2
380
     if ( wb_sel_i [1] == 1'b1 )
381
       rgpio_out [gw-1:8] <= #1 wb_dat_i [gw-1:8] ;
382
     if ( wb_sel_i [0] == 1'b1 )
383
       rgpio_out [7:0] <= #1 wb_dat_i [7:0] ;
384
`endif
385
`ifdef GPIO_WB_BYTES1
386
     if ( wb_sel_i [0] == 1'b1 )
387
       rgpio_out [gw-1:0] <= #1 wb_dat_i [gw-1:0] ;
388
`endif
389
   end
390
 
391 14 lampret
`else
392 17 lampret
assign rgpio_out = `GPIO_DEF_RGPIO_OUT; // RGPIO_OUT = 0x0
393 14 lampret
`endif
394
 
395
//
396 17 lampret
// Write to RGPIO_OE. Bits in RGPIO_OE are stored inverted.
397 14 lampret
//
398
`ifdef GPIO_RGPIO_OE
399 36 gorand
always @(posedge wb_clk_i or posedge wb_rst_i)
400
        if (wb_rst_i)
401 14 lampret
                rgpio_oe <= #1 {gw{1'b0}};
402 36 gorand
        else if (rgpio_oe_sel && wb_we_i)
403 34 gorand
  begin
404
`ifdef GPIO_STRICT_32BIT_ACCESS
405 17 lampret
                rgpio_oe <= #1 ~wb_dat_i[gw-1:0];
406 34 gorand
`endif
407
 
408
`ifdef GPIO_WB_BYTES4
409 36 gorand
     if ( wb_sel_i [3] == 1'b1 )
410 34 gorand
       rgpio_oe [gw-1:24] <= #1 ~wb_dat_i [gw-1:24] ;
411 36 gorand
     if ( wb_sel_i [2] == 1'b1 )
412 34 gorand
       rgpio_oe [23:16] <= #1 ~wb_dat_i [23:16] ;
413 36 gorand
     if ( wb_sel_i [1] == 1'b1 )
414 34 gorand
       rgpio_oe [15:8] <= #1 ~wb_dat_i [15:8] ;
415 36 gorand
     if ( wb_sel_i [0] == 1'b1 )
416 34 gorand
       rgpio_oe [7:0] <= #1 ~wb_dat_i [7:0] ;
417
`endif
418
`ifdef GPIO_WB_BYTES3
419 36 gorand
     if ( wb_sel_i [2] == 1'b1 )
420 34 gorand
       rgpio_oe [gw-1:16] <= #1 ~wb_dat_i [gw-1:16] ;
421 36 gorand
     if ( wb_sel_i [1] == 1'b1 )
422 34 gorand
       rgpio_oe [15:8] <= #1 ~wb_dat_i [15:8] ;
423 36 gorand
     if ( wb_sel_i [0] == 1'b1 )
424 34 gorand
       rgpio_oe [7:0] <= #1 ~wb_dat_i [7:0] ;
425
`endif
426
`ifdef GPIO_WB_BYTES2
427 36 gorand
     if ( wb_sel_i [1] == 1'b1 )
428 34 gorand
       rgpio_oe [gw-1:8] <= #1 ~wb_dat_i [gw-1:8] ;
429 36 gorand
     if ( wb_sel_i [0] == 1'b1 )
430 34 gorand
       rgpio_oe [7:0] <= #1 ~wb_dat_i [7:0] ;
431
`endif
432
`ifdef GPIO_WB_BYTES1
433 36 gorand
     if ( wb_sel_i [0] == 1'b1 )
434 34 gorand
       rgpio_oe [gw-1:0] <= #1 ~wb_dat_i [gw-1:0] ;
435
`endif
436
   end
437
 
438 14 lampret
`else
439
assign rgpio_oe = `GPIO_DEF_RPGIO_OE;   // RGPIO_OE = 0x0
440
`endif
441
 
442
//
443
// Write to RGPIO_INTE
444
//
445
`ifdef GPIO_RGPIO_INTE
446
always @(posedge wb_clk_i or posedge wb_rst_i)
447
        if (wb_rst_i)
448
                rgpio_inte <= #1 {gw{1'b0}};
449
        else if (rgpio_inte_sel && wb_we_i)
450 34 gorand
  begin
451
`ifdef GPIO_STRICT_32BIT_ACCESS
452 14 lampret
                rgpio_inte <= #1 wb_dat_i[gw-1:0];
453 34 gorand
`endif
454
 
455
`ifdef GPIO_WB_BYTES4
456
     if ( wb_sel_i [3] == 1'b1 )
457
       rgpio_inte [gw-1:24] <= #1 wb_dat_i [gw-1:24] ;
458
     if ( wb_sel_i [2] == 1'b1 )
459
       rgpio_inte [23:16] <= #1 wb_dat_i [23:16] ;
460
     if ( wb_sel_i [1] == 1'b1 )
461
       rgpio_inte [15:8] <= #1 wb_dat_i [15:8] ;
462
     if ( wb_sel_i [0] == 1'b1 )
463
       rgpio_inte [7:0] <= #1 wb_dat_i [7:0] ;
464
`endif
465
`ifdef GPIO_WB_BYTES3
466
     if ( wb_sel_i [2] == 1'b1 )
467
       rgpio_inte [gw-1:16] <= #1 wb_dat_i [gw-1:16] ;
468
     if ( wb_sel_i [1] == 1'b1 )
469
       rgpio_inte [15:8] <= #1 wb_dat_i [15:8] ;
470
     if ( wb_sel_i [0] == 1'b1 )
471
       rgpio_inte [7:0] <= #1 wb_dat_i [7:0] ;
472
`endif
473
`ifdef GPIO_WB_BYTES2
474
     if ( wb_sel_i [1] == 1'b1 )
475
       rgpio_inte [gw-1:8] <= #1 wb_dat_i [gw-1:8] ;
476
     if ( wb_sel_i [0] == 1'b1 )
477
       rgpio_inte [7:0] <= #1 wb_dat_i [7:0] ;
478
`endif
479
`ifdef GPIO_WB_BYTES1
480
     if ( wb_sel_i [0] == 1'b1 )
481
       rgpio_inte [gw-1:0] <= #1 wb_dat_i [gw-1:0] ;
482
`endif
483
   end
484
 
485
 
486 14 lampret
`else
487
assign rgpio_inte = `GPIO_DEF_RPGIO_INTE;       // RGPIO_INTE = 0x0
488
`endif
489
 
490
//
491
// Write to RGPIO_PTRIG
492
//
493
`ifdef GPIO_RGPIO_PTRIG
494
always @(posedge wb_clk_i or posedge wb_rst_i)
495
        if (wb_rst_i)
496
                rgpio_ptrig <= #1 {gw{1'b0}};
497
        else if (rgpio_ptrig_sel && wb_we_i)
498 34 gorand
  begin
499
`ifdef GPIO_STRICT_32BIT_ACCESS
500 14 lampret
                rgpio_ptrig <= #1 wb_dat_i[gw-1:0];
501 34 gorand
`endif
502
 
503
`ifdef GPIO_WB_BYTES4
504
     if ( wb_sel_i [3] == 1'b1 )
505
       rgpio_ptrig [gw-1:24] <= #1 wb_dat_i [gw-1:24] ;
506
     if ( wb_sel_i [2] == 1'b1 )
507
       rgpio_ptrig [23:16] <= #1 wb_dat_i [23:16] ;
508
     if ( wb_sel_i [1] == 1'b1 )
509
       rgpio_ptrig [15:8] <= #1 wb_dat_i [15:8] ;
510
     if ( wb_sel_i [0] == 1'b1 )
511
       rgpio_ptrig [7:0] <= #1 wb_dat_i [7:0] ;
512
`endif
513
`ifdef GPIO_WB_BYTES3
514
     if ( wb_sel_i [2] == 1'b1 )
515
       rgpio_ptrig [gw-1:16] <= #1 wb_dat_i [gw-1:16] ;
516
     if ( wb_sel_i [1] == 1'b1 )
517
       rgpio_ptrig [15:8] <= #1 wb_dat_i [15:8] ;
518
     if ( wb_sel_i [0] == 1'b1 )
519
       rgpio_ptrig [7:0] <= #1 wb_dat_i [7:0] ;
520
`endif
521
`ifdef GPIO_WB_BYTES2
522
     if ( wb_sel_i [1] == 1'b1 )
523
       rgpio_ptrig [gw-1:8] <= #1 wb_dat_i [gw-1:8] ;
524
     if ( wb_sel_i [0] == 1'b1 )
525
       rgpio_ptrig [7:0] <= #1 wb_dat_i [7:0] ;
526
`endif
527
`ifdef GPIO_WB_BYTES1
528
     if ( wb_sel_i [0] == 1'b1 )
529
       rgpio_ptrig [gw-1:0] <= #1 wb_dat_i [gw-1:0] ;
530
`endif
531
   end
532
 
533 14 lampret
`else
534
assign rgpio_ptrig = `GPIO_DEF_RPGIO_PTRIG;     // RGPIO_PTRIG = 0x0
535
`endif
536
 
537
//
538
// Write to RGPIO_AUX
539
//
540
`ifdef GPIO_RGPIO_AUX
541
always @(posedge wb_clk_i or posedge wb_rst_i)
542
        if (wb_rst_i)
543
                rgpio_aux <= #1 {gw{1'b0}};
544
        else if (rgpio_aux_sel && wb_we_i)
545 34 gorand
  begin
546
`ifdef GPIO_STRICT_32BIT_ACCESS
547 14 lampret
                rgpio_aux <= #1 wb_dat_i[gw-1:0];
548 34 gorand
`endif
549
 
550
`ifdef GPIO_WB_BYTES4
551
     if ( wb_sel_i [3] == 1'b1 )
552
       rgpio_aux [gw-1:24] <= #1 wb_dat_i [gw-1:24] ;
553
     if ( wb_sel_i [2] == 1'b1 )
554
       rgpio_aux [23:16] <= #1 wb_dat_i [23:16] ;
555
     if ( wb_sel_i [1] == 1'b1 )
556
       rgpio_aux [15:8] <= #1 wb_dat_i [15:8] ;
557
     if ( wb_sel_i [0] == 1'b1 )
558
       rgpio_aux [7:0] <= #1 wb_dat_i [7:0] ;
559
`endif
560
`ifdef GPIO_WB_BYTES3
561
     if ( wb_sel_i [2] == 1'b1 )
562
       rgpio_aux [gw-1:16] <= #1 wb_dat_i [gw-1:16] ;
563
     if ( wb_sel_i [1] == 1'b1 )
564
       rgpio_aux [15:8] <= #1 wb_dat_i [15:8] ;
565
     if ( wb_sel_i [0] == 1'b1 )
566
       rgpio_aux [7:0] <= #1 wb_dat_i [7:0] ;
567
`endif
568
`ifdef GPIO_WB_BYTES2
569
     if ( wb_sel_i [1] == 1'b1 )
570
       rgpio_aux [gw-1:8] <= #1 wb_dat_i [gw-1:8] ;
571
     if ( wb_sel_i [0] == 1'b1 )
572
       rgpio_aux [7:0] <= #1 wb_dat_i [7:0] ;
573
`endif
574
`ifdef GPIO_WB_BYTES1
575
     if ( wb_sel_i [0] == 1'b1 )
576
       rgpio_aux [gw-1:0] <= #1 wb_dat_i [gw-1:0] ;
577
`endif
578
   end
579
 
580 14 lampret
`else
581
assign rgpio_aux = `GPIO_DEF_RPGIO_AUX; // RGPIO_AUX = 0x0
582
`endif
583
 
584
//
585
// Latch into RGPIO_IN
586
//
587
`ifdef GPIO_RGPIO_IN
588 17 lampret
always @(posedge wb_clk_i or posedge wb_rst_i)
589 14 lampret
        if (wb_rst_i)
590
                rgpio_in <= #1 {gw{1'b0}};
591
        else
592 17 lampret
                rgpio_in <= #1 in_muxed;
593 14 lampret
`else
594 17 lampret
assign rgpio_in = in_muxed;
595 14 lampret
`endif
596
 
597
//
598 17 lampret
// Mux inputs directly from input pads with inputs sampled by external clock
599 14 lampret
//
600 25 lampret
assign in_muxed = rgpio_ctrl[`GPIO_RGPIO_CTRL_ECLK] ? extc_in : ext_pad_i;
601 17 lampret
 
602
//
603
// Posedge pext_clk is inverted by NEC bit if negedge flops are not allowed.
604
// If negedge flops are allowed, pext_clk only clocks posedge flops.
605
//
606
`ifdef GPIO_NO_NEGEDGE_FLOPS
607 29 lampret
`ifdef GPIO_NO_CLKPAD_LOGIC
608
assign pext_clk = clk_pad_i;
609
`else
610 25 lampret
assign pext_clk = rgpio_ctrl[`GPIO_RGPIO_CTRL_NEC] ? ~clk_pad_i : clk_pad_i;
611 29 lampret
`endif
612 17 lampret
`else
613 25 lampret
assign pext_clk = clk_pad_i;
614 17 lampret
`endif
615
 
616
//
617
// If negedge flops are allowed, ext_in is mux of negedge and posedge external clocked flops.
618
//
619
`ifdef GPIO_NO_NEGEDGE_FLOPS
620
assign extc_in = pextc_sampled;
621
`else
622
assign extc_in = rgpio_ctrl[`GPIO_RGPIO_CTRL_NEC] ? nextc_sampled : pextc_sampled;
623
`endif
624
 
625
//
626
// Latch using posedge external clock
627
//
628
always @(posedge pext_clk or posedge wb_rst_i)
629
        if (wb_rst_i)
630
                pextc_sampled <= #1 {gw{1'b0}};
631
        else
632 25 lampret
                pextc_sampled <= #1 ext_pad_i;
633 17 lampret
 
634
//
635
// Latch using negedge external clock
636
//
637
`ifdef GPIO_NO_NEGEDGE_FLOPS
638
`else
639 25 lampret
always @(negedge clk_pad_i or posedge wb_rst_i)
640 17 lampret
        if (wb_rst_i)
641
                nextc_sampled <= #1 {gw{1'b0}};
642
        else
643 25 lampret
                nextc_sampled <= #1 ext_pad_i;
644 17 lampret
`endif
645
 
646
//
647
// Mux all registers when doing a read of GPIO registers
648
//
649 14 lampret
always @(wb_adr_i or rgpio_in or rgpio_out or rgpio_oe or rgpio_inte or
650 22 lampret
                rgpio_ptrig or rgpio_aux or rgpio_ctrl or rgpio_ints)
651 14 lampret
        case (wb_adr_i[`GPIO_OFS_BITS]) // synopsys full_case parallel_case
652
`ifdef GPIO_READREGS
653
                `GPIO_RGPIO_OUT: begin
654 26 lampret
                        wb_dat[dw-1:0] = rgpio_out;
655 14 lampret
                end
656
                `GPIO_RGPIO_OE: begin
657 26 lampret
                        wb_dat[dw-1:0] = ~rgpio_oe;
658 14 lampret
                end
659
                `GPIO_RGPIO_INTE: begin
660 26 lampret
                        wb_dat[dw-1:0] = rgpio_inte;
661 14 lampret
                end
662
                `GPIO_RGPIO_PTRIG: begin
663 26 lampret
                        wb_dat[dw-1:0] = rgpio_ptrig;
664 14 lampret
                end
665
                `GPIO_RGPIO_AUX: begin
666 26 lampret
                        wb_dat[dw-1:0] = rgpio_aux;
667 14 lampret
                end
668
                `GPIO_RGPIO_CTRL: begin
669 20 lampret
                        wb_dat[3:0] = rgpio_ctrl;
670
                        wb_dat[dw-1:4] = {dw-4{1'b0}};
671 14 lampret
                end
672
`endif
673 21 lampret
                `GPIO_RGPIO_INTS: begin
674 26 lampret
                        wb_dat[dw-1:0] = rgpio_ints;
675 21 lampret
                end
676 14 lampret
                default: begin
677 26 lampret
                        wb_dat[dw-1:0] = rgpio_in;
678 14 lampret
                end
679
        endcase
680
 
681
//
682 17 lampret
// WB data output
683
//
684
`ifdef GPIO_REGISTERED_WB_OUTPUTS
685
always @(posedge wb_clk_i or posedge wb_rst_i)
686
        if (wb_rst_i)
687
                wb_dat_o <= #1 {dw{1'b0}};
688
        else
689
                wb_dat_o <= #1 wb_dat;
690
`else
691
assign wb_dat_o = wb_dat;
692
`endif
693
 
694
//
695 21 lampret
// RGPIO_INTS
696
//
697
`ifdef GPIO_RGPIO_INTS
698
always @(posedge wb_clk_i or posedge wb_rst_i)
699
        if (wb_rst_i)
700
                rgpio_ints <= #1 {gw{1'b0}};
701
        else if (rgpio_ints_sel && wb_we_i)
702
                rgpio_ints <= #1 wb_dat_i[gw-1:0];
703 31 lampret
        else if (rgpio_ctrl[`GPIO_RGPIO_CTRL_INTE])
704
                rgpio_ints <= #1 (rgpio_ints | ((ext_pad_i ^ rgpio_in) & ~(ext_pad_i ^ rgpio_ptrig)) & rgpio_inte);
705 21 lampret
`else
706 31 lampret
assign rgpio_ints = (rgpio_ints | ((ext_pad_i ^ rgpio_in) & ~(ext_pad_i ^ rgpio_ptrig)) & rgpio_inte);
707 21 lampret
`endif
708
 
709
//
710 14 lampret
// Generate interrupt request
711
//
712 21 lampret
assign wb_inta = |rgpio_ints ? rgpio_ctrl[`GPIO_RGPIO_CTRL_INTE] : 1'b0;
713 14 lampret
 
714
//
715 17 lampret
// Optional registration of WB interrupt
716 14 lampret
//
717 17 lampret
`ifdef GPIO_REGISTERED_WB_OUTPUTS
718
always @(posedge wb_clk_i or posedge wb_rst_i)
719
        if (wb_rst_i)
720 19 lampret
                wb_inta_o <= #1 1'b0;
721 17 lampret
        else
722
                wb_inta_o <= #1 wb_inta;
723
`else
724
assign wb_inta_o = wb_inta;
725
`endif
726 14 lampret
 
727
//
728 17 lampret
// Output enables are RGPIO_OE bits
729 14 lampret
//
730 25 lampret
assign ext_padoen_o = rgpio_oe;
731 14 lampret
 
732 17 lampret
//
733
// Generate GPIO outputs
734
//
735
assign out_pad = rgpio_out & ~rgpio_aux | aux_i & rgpio_aux;
736
 
737
//
738
// Optional registration of GPIO outputs
739
//
740
`ifdef GPIO_REGISTERED_IO_OUTPUTS
741
always @(posedge wb_clk_i or posedge wb_rst_i)
742
        if (wb_rst_i)
743 25 lampret
                ext_pad_o <= #1 {gw{1'b0}};
744 17 lampret
        else
745 25 lampret
                ext_pad_o <= #1 out_pad;
746 14 lampret
`else
747 25 lampret
assign ext_pad_o = out_pad;
748 17 lampret
`endif
749 14 lampret
 
750 17 lampret
`else
751
 
752 14 lampret
//
753
// When GPIO is not implemented, drive all outputs as would when RGPIO_CTRL
754
// is cleared and WISHBONE transfers complete with errors
755
//
756
assign wb_inta_o = 1'b0;
757
assign wb_ack_o = 1'b0;
758
assign wb_err_o = wb_cyc_i & wb_stb_i;
759 25 lampret
assign ext_padoen_o = {gw{1'b1}};
760
assign ext_pad_o = {gw{1'b0}};
761 14 lampret
 
762
//
763
// Read GPIO registers
764
//
765
assign wb_dat_o = {dw{1'b0}};
766
 
767
`endif
768
 
769
endmodule

powered by: WebSVN 2.1.0

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