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

Subversion Repositories gpio

[/] [gpio/] [tags/] [rel_9/] [rtl/] [verilog/] [gpio_top.v] - Blame information for rev 19

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 19 lampret
// Revision 1.3  2001/11/15 02:24:37  lampret
49
// Added GPIO_REGISTERED_WB_OUTPUTS, GPIO_REGISTERED_IO_OUTPUTS and GPIO_NO_NEGEDGE_FLOPS.
50
//
51 17 lampret
// Revision 1.2  2001/10/31 02:26:51  lampret
52
// Fixed wb_err_o.
53
//
54 15 lampret
// Revision 1.1  2001/09/18 18:49:07  lampret
55
// Changed top level ptc into gpio_top. Changed defines.v into gpio_defines.v.
56
//
57 14 lampret
// Revision 1.1  2001/08/21 21:39:28  lampret
58
// Changed directory structure, port names and drfines.
59
//
60
// Revision 1.2  2001/07/14 20:39:26  lampret
61
// Better configurability.
62
//
63
// Revision 1.1  2001/06/05 07:45:26  lampret
64
// Added initial RTL and test benches. There are still some issues with these files.
65
//
66
//
67
 
68
// synopsys translate_off
69
`include "timescale.v"
70
// synopsys translate_on
71
`include "gpio_defines.v"
72
 
73
module gpio_top(
74
        // WISHBONE Interface
75
        wb_clk_i, wb_rst_i, wb_cyc_i, wb_adr_i, wb_dat_i, wb_sel_i, wb_we_i, wb_stb_i,
76
        wb_dat_o, wb_ack_o, wb_err_o, wb_inta_o,
77
 
78
        // Auxiliary inputs interface
79
        aux_i,
80
 
81
        // External GPIO Interface
82
        in_pad_i, ext_clk_pad_i, out_pad_o, oen_padoen_o
83
);
84
 
85
parameter dw = 32;
86
parameter aw = `GPIO_ADDRHH+1;
87
parameter gw = `GPIO_IOS;
88
 
89
//
90
// WISHBONE Interface
91
//
92
input                   wb_clk_i;       // Clock
93
input                   wb_rst_i;       // Reset
94
input                   wb_cyc_i;       // cycle valid input
95
input   [aw-1:0] wb_adr_i;       // address bus inputs
96
input   [dw-1:0] wb_dat_i;       // input data bus
97
input   [3:0]            wb_sel_i;       // byte select inputs
98
input                   wb_we_i;        // indicates write transfer
99
input                   wb_stb_i;       // strobe input
100
output  [dw-1:0] wb_dat_o;       // output data bus
101
output                  wb_ack_o;       // normal termination
102
output                  wb_err_o;       // termination w/ error
103
output                  wb_inta_o;      // Interrupt request output
104
 
105
// Auxiliary Inputs Interface
106
input   [gw-1:0] aux_i;          // Auxiliary inputs
107
 
108
//
109
// External GPIO Interface
110
//
111
input   [gw-1:0] in_pad_i;       // GPIO Inputs
112
input                   ext_clk_pad_i;  // GPIO Eclk
113
output  [gw-1:0] out_pad_o;      // GPIO Outputs
114
output  [gw-1:0] oen_padoen_o;   // GPIO output drivers enables
115
 
116
`ifdef GPIO_IMPLEMENTED
117
 
118
//
119
// GPIO Input Register (or no register)
120
//
121
`ifdef GPIO_RGPIO_IN
122
reg     [gw-1:0] rgpio_in;       // RGPIO_IN register
123
`else
124
wire    [gw-1:0] rgpio_in;       // No register
125
`endif
126
 
127
//
128
// GPIO Output Register (or no register)
129
//
130
`ifdef GPIO_RGPIO_OUT
131
reg     [gw-1:0] rgpio_out;      // RGPIO_OUT register
132
`else
133
wire    [gw-1:0] rgpio_out;      // No register
134
`endif
135
 
136
//
137
// GPIO Output Driver Enable Register (or no register)
138
//
139
`ifdef GPIO_RGPIO_OE
140
reg     [gw-1:0] rgpio_oe;       // RGPIO_OE register
141
`else
142
wire    [gw-1:0] rgpio_oe;       // No register
143
`endif
144
 
145
//
146
// GPIO Interrupt Enable Register (or no register)
147
//
148
`ifdef GPIO_RGPIO_INTE
149
reg     [gw-1:0] rgpio_inte;     // RGPIO_INTE register
150
`else
151
wire    [gw-1:0] rgpio_inte;     // No register
152
`endif
153
 
154
//
155
// GPIO Positive edge Triggered Register (or no register)
156
//
157
`ifdef GPIO_RGPIO_PTRIG
158
reg     [gw-1:0] rgpio_ptrig;    // RGPIO_PTRIG register
159
`else
160
wire    [gw-1:0] rgpio_ptrig;    // No register
161
`endif
162
 
163
//
164
// GPIO Auxiliary select Register (or no register)
165
//
166
`ifdef GPIO_RGPIO_AUX
167
reg     [gw-1:0] rgpio_aux;      // RGPIO_AUX register
168
`else
169
wire    [gw-1:0] rgpio_aux;      // No register
170
`endif
171
 
172
//
173
// GPIO Control Register (or no register)
174
//
175
`ifdef GPIO_RGPIO_CTRL
176
reg     [3:0]            rgpio_ctrl;     // RGPIO_CTRL register
177
`else
178
wire    [3:0]            rgpio_ctrl;     // No register
179
`endif
180
 
181
//
182
// Internal wires & regs
183
//
184
wire                    rgpio_in_sel;   // RGPIO_IN select
185
wire                    rgpio_out_sel;  // RGPIO_OUT select
186
wire                    rgpio_oe_sel;   // RGPIO_OE select
187
wire                    rgpio_inte_sel; // RGPIO_INTE select
188
wire                    rgpio_ptrig_sel;// RGPIO_PTRIG select
189
wire                    rgpio_aux_sel;  // RGPIO_AUX select
190
wire                    rgpio_ctrl_sel; // RGPIO_CTRL select
191
wire                    latch_clk;      // Latch clock
192
wire                    full_decoding;  // Full address decoding qualification
193 17 lampret
wire    [gw-1:0] in_muxed;       // Muxed inputs
194
wire                    wb_ack;         // WB Acknowledge
195
wire                    wb_err;         // WB Error
196
wire                    wb_inta;        // WB Interrupt
197
reg     [dw-1:0] wb_dat;         // WB Data out
198
`ifdef GPIO_REGISTERED_WB_OUTPUTS
199
reg                     wb_ack_o;       // WB Acknowledge
200
reg                     wb_err_o;       // WB Error
201
reg                     wb_inta_o;      // WB Interrupt
202
reg     [dw-1:0] wb_dat_o;       // WB Data out
203
`endif
204
wire    [gw-1:0] out_pad;        // GPIO Outputs
205
`ifdef GPIO_REGISTERED_IO_OUTPUTS
206
reg     [gw-1:0] out_pad_o;      // GPIO Outputs
207
`endif
208
wire    [gw-1:0] extc_in;        // Muxed inputs sampled by external clock
209
wire                    pext_clk;       // External clock for posedge flops
210
reg     [gw-1:0] pextc_sampled;  // Posedge external clock sampled inputs
211
`ifdef GPIO_NO_NEGEDGE_FLOPS
212
`else
213
reg     [gw-1:0] nextc_sampled;  // Negedge external clock sampled inputs
214
`endif
215 14 lampret
 
216
//
217
// All WISHBONE transfer terminations are successful except when:
218
// a) full address decoding is enabled and address doesn't match
219
//    any of the GPIO registers
220
// b) wb_sel_i evaluation is enabled and one of the wb_sel_i inputs is zero
221
//
222 17 lampret
 
223
//
224
// WB Acknowledge
225
//
226
assign wb_ack = wb_cyc_i & wb_stb_i & !wb_err_o;
227
 
228
//
229
// Optional registration of WB Ack
230
//
231
`ifdef GPIO_REGISTERED_WB_OUTPUTS
232
always @(posedge wb_clk_i or posedge wb_rst_i)
233
        if (wb_rst_i)
234
                wb_ack_o <= #1 1'b0;
235
        else
236
                wb_ack_o <= #1 wb_ack;
237
`else
238
assign wb_ack_o = wb_ack;
239
`endif
240
 
241
//
242
// WB Error
243
//
244 14 lampret
`ifdef GPIO_FULL_DECODE
245
`ifdef GPIO_STRICT_32BIT_ACCESS
246 17 lampret
assign wb_err = wb_cyc_i & wb_stb_i & (!full_decoding | (wb_sel_i != 4'b1111));
247 14 lampret
`else
248 17 lampret
assign wb_err = wb_cyc_i & wb_stb_i & !full_decoding;
249 14 lampret
`endif
250
`else
251
`ifdef GPIO_STRICT_32BIT_ACCESS
252 17 lampret
assign wb_err = wb_cyc_i & wb_stb_i & (wb_sel_i != 4'b1111);
253 14 lampret
`else
254 17 lampret
assign wb_err = 1'b0;
255 14 lampret
`endif
256
`endif
257
 
258
//
259 17 lampret
// Optional registration of WB error
260 14 lampret
//
261 17 lampret
`ifdef GPIO_REGISTERED_WB_OUTPUTS
262
always @(posedge wb_clk_i or posedge wb_rst_i)
263
        if (wb_rst_i)
264
                wb_err_o <= #1 1'b0;
265
        else
266
                wb_err_o <= #1 wb_err;
267
`else
268
assign wb_err_o = wb_err;
269
`endif
270 14 lampret
 
271
//
272
// Full address decoder
273
//
274
`ifdef GPIO_FULL_DECODE
275
assign full_decoding = (wb_adr_i[`GPIO_ADDRHH:`GPIO_ADDRHL] == {`GPIO_ADDRHH-`GPIO_ADDRHL+1{1'b0}}) &
276
                        (wb_adr_i[`GPIO_ADDRLH:`GPIO_ADDRLL] == {`GPIO_ADDRLH-`GPIO_ADDRLL+1{1'b0}});
277
`else
278
assign full_decoding = 1'b1;
279
`endif
280
 
281
//
282
// GPIO registers address decoder
283
//
284
assign rgpio_in_sel = wb_cyc_i & wb_stb_i & (wb_adr_i[`GPIO_OFS_BITS] == `GPIO_RGPIO_IN) & full_decoding;
285
assign rgpio_out_sel = wb_cyc_i & wb_stb_i & (wb_adr_i[`GPIO_OFS_BITS] == `GPIO_RGPIO_OUT) & full_decoding;
286
assign rgpio_oe_sel = wb_cyc_i & wb_stb_i & (wb_adr_i[`GPIO_OFS_BITS] == `GPIO_RGPIO_OE) & full_decoding;
287
assign rgpio_inte_sel = wb_cyc_i & wb_stb_i & (wb_adr_i[`GPIO_OFS_BITS] == `GPIO_RGPIO_INTE) & full_decoding;
288
assign rgpio_ptrig_sel = wb_cyc_i & wb_stb_i & (wb_adr_i[`GPIO_OFS_BITS] == `GPIO_RGPIO_PTRIG) & full_decoding;
289
assign rgpio_aux_sel = wb_cyc_i & wb_stb_i & (wb_adr_i[`GPIO_OFS_BITS] == `GPIO_RGPIO_AUX) & full_decoding;
290
assign rgpio_ctrl_sel = wb_cyc_i & wb_stb_i & (wb_adr_i[`GPIO_OFS_BITS] == `GPIO_RGPIO_CTRL) & full_decoding;
291
 
292
//
293
// Write to RGPIO_CTRL or update of RGPIO_CTRL[INT] bit
294
//
295
`ifdef GPIO_RGPIO_CTRL
296
always @(posedge wb_clk_i or posedge wb_rst_i)
297
        if (wb_rst_i)
298
                rgpio_ctrl <= #1 4'b0;
299
        else if (rgpio_ctrl_sel && wb_we_i)
300
                rgpio_ctrl <= #1 wb_dat_i[3:0];
301
        else if (rgpio_ctrl[`GPIO_RGPIO_CTRL_INTE])
302
                rgpio_ctrl[`GPIO_RGPIO_CTRL_INT] <= #1 rgpio_ctrl[`GPIO_RGPIO_CTRL_INT] | wb_inta_o;
303
`else
304
assign rgpio_ctrl = 4'h01;      // RGPIO_CTRL[EN] = 1
305
`endif
306
 
307
//
308
// Write to RGPIO_OUT
309
//
310
`ifdef GPIO_RGPIO_OUT
311
always @(posedge wb_clk_i or posedge wb_rst_i)
312
        if (wb_rst_i)
313
                rgpio_out <= #1 {gw{1'b0}};
314
        else if (rgpio_out_sel && wb_we_i)
315
                rgpio_out <= #1 wb_dat_i[gw-1:0];
316
`else
317 17 lampret
assign rgpio_out = `GPIO_DEF_RGPIO_OUT; // RGPIO_OUT = 0x0
318 14 lampret
`endif
319
 
320
//
321 17 lampret
// Write to RGPIO_OE. Bits in RGPIO_OE are stored inverted.
322 14 lampret
//
323
`ifdef GPIO_RGPIO_OE
324
always @(posedge wb_clk_i or posedge wb_rst_i)
325
        if (wb_rst_i)
326
                rgpio_oe <= #1 {gw{1'b0}};
327
        else if (rgpio_oe_sel && wb_we_i)
328 17 lampret
                rgpio_oe <= #1 ~wb_dat_i[gw-1:0];
329 14 lampret
`else
330
assign rgpio_oe = `GPIO_DEF_RPGIO_OE;   // RGPIO_OE = 0x0
331
`endif
332
 
333
//
334
// Write to RGPIO_INTE
335
//
336
`ifdef GPIO_RGPIO_INTE
337
always @(posedge wb_clk_i or posedge wb_rst_i)
338
        if (wb_rst_i)
339
                rgpio_inte <= #1 {gw{1'b0}};
340
        else if (rgpio_inte_sel && wb_we_i)
341
                rgpio_inte <= #1 wb_dat_i[gw-1:0];
342
`else
343
assign rgpio_inte = `GPIO_DEF_RPGIO_INTE;       // RGPIO_INTE = 0x0
344
`endif
345
 
346
//
347
// Write to RGPIO_PTRIG
348
//
349
`ifdef GPIO_RGPIO_PTRIG
350
always @(posedge wb_clk_i or posedge wb_rst_i)
351
        if (wb_rst_i)
352
                rgpio_ptrig <= #1 {gw{1'b0}};
353
        else if (rgpio_ptrig_sel && wb_we_i)
354
                rgpio_ptrig <= #1 wb_dat_i[gw-1:0];
355
`else
356
assign rgpio_ptrig = `GPIO_DEF_RPGIO_PTRIG;     // RGPIO_PTRIG = 0x0
357
`endif
358
 
359
//
360
// Write to RGPIO_AUX
361
//
362
`ifdef GPIO_RGPIO_AUX
363
always @(posedge wb_clk_i or posedge wb_rst_i)
364
        if (wb_rst_i)
365
                rgpio_aux <= #1 {gw{1'b0}};
366
        else if (rgpio_aux_sel && wb_we_i)
367
                rgpio_aux <= #1 wb_dat_i[gw-1:0];
368
`else
369
assign rgpio_aux = `GPIO_DEF_RPGIO_AUX; // RGPIO_AUX = 0x0
370
`endif
371
 
372
//
373
// Latch into RGPIO_IN
374
//
375
`ifdef GPIO_RGPIO_IN
376 17 lampret
always @(posedge wb_clk_i or posedge wb_rst_i)
377 14 lampret
        if (wb_rst_i)
378
                rgpio_in <= #1 {gw{1'b0}};
379
        else
380 17 lampret
                rgpio_in <= #1 in_muxed;
381 14 lampret
`else
382 17 lampret
assign rgpio_in = in_muxed;
383 14 lampret
`endif
384
 
385
//
386 17 lampret
// Mux inputs directly from input pads with inputs sampled by external clock
387 14 lampret
//
388 17 lampret
assign in_muxed = rgpio_ctrl[`GPIO_RGPIO_CTRL_ECLK] ? extc_in : in_pad_i;
389
 
390
//
391
// Posedge pext_clk is inverted by NEC bit if negedge flops are not allowed.
392
// If negedge flops are allowed, pext_clk only clocks posedge flops.
393
//
394
`ifdef GPIO_NO_NEGEDGE_FLOPS
395
assign pext_clk = rgpio_ctrl[`GPIO_RGPIO_CTRL_NEC] ? ~ext_clk_pad_i : ext_clk_pad_i;
396
`else
397
assign pext_clk = ext_clk_pad_i;
398
`endif
399
 
400
//
401
// If negedge flops are allowed, ext_in is mux of negedge and posedge external clocked flops.
402
//
403
`ifdef GPIO_NO_NEGEDGE_FLOPS
404
assign extc_in = pextc_sampled;
405
`else
406
assign extc_in = rgpio_ctrl[`GPIO_RGPIO_CTRL_NEC] ? nextc_sampled : pextc_sampled;
407
`endif
408
 
409
//
410
// Latch using posedge external clock
411
//
412
always @(posedge pext_clk or posedge wb_rst_i)
413
        if (wb_rst_i)
414
                pextc_sampled <= #1 {gw{1'b0}};
415
        else
416
                pextc_sampled <= #1 in_pad_i;
417
 
418
//
419
// Latch using negedge external clock
420
//
421
`ifdef GPIO_NO_NEGEDGE_FLOPS
422
`else
423
always @(negedge ext_clk_pad_i or posedge wb_rst_i)
424
        if (wb_rst_i)
425
                nextc_sampled <= #1 {gw{1'b0}};
426
        else
427
                nextc_sampled <= #1 in_pad_i;
428
`endif
429
 
430
//
431
// Mux all registers when doing a read of GPIO registers
432
//
433 14 lampret
always @(wb_adr_i or rgpio_in or rgpio_out or rgpio_oe or rgpio_inte or
434
                rgpio_ptrig or rgpio_aux or rgpio_ctrl)
435
        case (wb_adr_i[`GPIO_OFS_BITS]) // synopsys full_case parallel_case
436
`ifdef GPIO_READREGS
437
                `GPIO_RGPIO_OUT: begin
438 17 lampret
                        wb_dat[dw-1:0] <= {{dw-gw{1'b0}}, rgpio_out};
439 14 lampret
                end
440
                `GPIO_RGPIO_OE: begin
441 17 lampret
                        wb_dat[dw-1:0] <= {{dw-gw{1'b0}}, ~rgpio_oe};
442 14 lampret
                end
443
                `GPIO_RGPIO_INTE: begin
444 17 lampret
                        wb_dat[dw-1:0] <= {{dw-gw{1'b0}}, rgpio_inte};
445 14 lampret
                end
446
                `GPIO_RGPIO_PTRIG: begin
447 17 lampret
                        wb_dat[dw-1:0] <= {{dw-gw{1'b0}}, rgpio_ptrig};
448 14 lampret
                end
449
                `GPIO_RGPIO_AUX: begin
450 17 lampret
                        wb_dat[dw-1:0] <= {{dw-gw{1'b0}}, rgpio_aux};
451 14 lampret
                end
452
                `GPIO_RGPIO_CTRL: begin
453 17 lampret
                        wb_dat[3:0] <= rgpio_ctrl;
454
                        wb_dat[dw-1:4] <= {dw-4{1'b0}};
455 14 lampret
                end
456
`endif
457
                default: begin
458 17 lampret
                        wb_dat[dw-1:0] <= {{dw-gw{1'b0}}, rgpio_in};
459 14 lampret
                end
460
        endcase
461
 
462
//
463 17 lampret
// WB data output
464
//
465
`ifdef GPIO_REGISTERED_WB_OUTPUTS
466
always @(posedge wb_clk_i or posedge wb_rst_i)
467
        if (wb_rst_i)
468
                wb_dat_o <= #1 {dw{1'b0}};
469
        else
470
                wb_dat_o <= #1 wb_dat;
471
`else
472
assign wb_dat_o = wb_dat;
473
`endif
474
 
475
//
476 14 lampret
// Generate interrupt request
477
//
478 17 lampret
assign wb_inta = ((in_pad_i ^ ~rgpio_ptrig) & rgpio_inte) ? rgpio_ctrl[`GPIO_RGPIO_CTRL_INTE] : 1'b0;
479 14 lampret
 
480
//
481 17 lampret
// Optional registration of WB interrupt
482 14 lampret
//
483 17 lampret
`ifdef GPIO_REGISTERED_WB_OUTPUTS
484
always @(posedge wb_clk_i or posedge wb_rst_i)
485
        if (wb_rst_i)
486 19 lampret
                wb_inta_o <= #1 1'b0;
487 17 lampret
        else
488
                wb_inta_o <= #1 wb_inta;
489
`else
490
assign wb_inta_o = wb_inta;
491
`endif
492 14 lampret
 
493
//
494 17 lampret
// Output enables are RGPIO_OE bits
495 14 lampret
//
496 17 lampret
assign oen_padoen_o = rgpio_oe;
497 14 lampret
 
498 17 lampret
//
499
// Generate GPIO outputs
500
//
501
assign out_pad = rgpio_out & ~rgpio_aux | aux_i & rgpio_aux;
502
 
503
//
504
// Optional registration of GPIO outputs
505
//
506
`ifdef GPIO_REGISTERED_IO_OUTPUTS
507
always @(posedge wb_clk_i or posedge wb_rst_i)
508
        if (wb_rst_i)
509
                out_pad_o <= #1 {gw{1'b0}};
510
        else
511
                out_pad_o <= #1 out_pad;
512 14 lampret
`else
513 17 lampret
assign out_pad_o = out_pad;
514
`endif
515 14 lampret
 
516 17 lampret
`else
517
 
518 14 lampret
//
519
// When GPIO is not implemented, drive all outputs as would when RGPIO_CTRL
520
// is cleared and WISHBONE transfers complete with errors
521
//
522
assign wb_inta_o = 1'b0;
523
assign wb_ack_o = 1'b0;
524
assign wb_err_o = wb_cyc_i & wb_stb_i;
525
assign oen_padoen_o = {gw{1'b1}};
526
assign out_pad_o = {gw{1'b0}};
527
 
528
//
529
// Read GPIO registers
530
//
531
assign wb_dat_o = {dw{1'b0}};
532
 
533
`endif
534
 
535
endmodule

powered by: WebSVN 2.1.0

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