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

Subversion Repositories gpio

[/] [gpio/] [tags/] [asyst_3/] [rtl/] [verilog/] [gpio_top.v] - Blame information for rev 34

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

powered by: WebSVN 2.1.0

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