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 17

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

powered by: WebSVN 2.1.0

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