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 20

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

powered by: WebSVN 2.1.0

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