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

Subversion Repositories rtc

[/] [rtc/] [trunk/] [rtl/] [verilog/] [rtc_top.v] - Blame information for rev 15

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 15 lampret
//////////////////////////////////////////////////////////////////////
2
////                                                              ////
3
////  WISHBONE Real-Time Clock                                    ////
4
////                                                              ////
5
////  This file is part of the RTC project                        ////
6
////  http://www.opencores.org/cores/rtc/                         ////
7
////                                                              ////
8
////  Description                                                 ////
9
////  Implementation of Real-Time clock IP core according to      ////
10
////  RTC IP core specification document. Using async resets      ////
11
////  would make core even smaller.                               ////
12
////                                                              ////
13
////  To Do:                                                      ////
14
////   Nothing                                                    ////
15
////                                                              ////
16
////  Author(s):                                                  ////
17
////      - Damjan Lampret, lampret@opencores.org                 ////
18
////                                                              ////
19
//////////////////////////////////////////////////////////////////////
20
////                                                              ////
21
//// Copyright (C) 2000 Authors and OPENCORES.ORG                 ////
22
////                                                              ////
23
//// This source file may be used and distributed without         ////
24
//// restriction provided that this copyright statement is not    ////
25
//// removed from the file and that any derivative work contains  ////
26
//// the original copyright notice and the associated disclaimer. ////
27
////                                                              ////
28
//// This source file is free software; you can redistribute it   ////
29
//// and/or modify it under the terms of the GNU Lesser General   ////
30
//// Public License as published by the Free Software Foundation; ////
31
//// either version 2.1 of the License, or (at your option) any   ////
32
//// later version.                                               ////
33
////                                                              ////
34
//// This source is distributed in the hope that it will be       ////
35
//// useful, but WITHOUT ANY WARRANTY; without even the implied   ////
36
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR      ////
37
//// PURPOSE.  See the GNU Lesser General Public License for more ////
38
//// details.                                                     ////
39
////                                                              ////
40
//// You should have received a copy of the GNU Lesser General    ////
41
//// Public License along with this source; if not, download it   ////
42
//// from http://www.opencores.org/lgpl.shtml                     ////
43
////                                                              ////
44
//////////////////////////////////////////////////////////////////////
45
//
46
// CVS Revision History
47
//
48
// $Log: not supported by cvs2svn $
49
// Revision 1.2  2001/08/22 10:58:27  lampret
50
// Changed synthesis translate_ to synopsys translate.
51
//
52
// Revision 1.1  2001/08/21 12:53:11  lampret
53
// Changed directory structure, uniquified defines and changed design's port names.
54
//
55
// Revision 1.3  2001/07/17 00:02:55  lampret
56
// Fixed reading of registers.
57
//
58
// Revision 1.2  2001/07/16 01:08:45  lampret
59
// Added additional parameters to make RTL more configurable. Added bunch of comments to defines.v
60
//
61
// Revision 1.1  2001/06/05 07:45:43  lampret
62
// Added initial RTL and test benches. There are still some issues with these files.
63
//
64
//
65
 
66
// synopsys translate_off
67
`include "timescale.v"
68
// synopsys translate_on
69
`include "rtc_defines.v"
70
 
71
module rtc_top(
72
        // WISHBONE Interface
73
        wb_clk_i, wb_rst_i, wb_cyc_i, wb_adr_i, wb_dat_i, wb_sel_i, wb_we_i, wb_stb_i,
74
        wb_dat_o, wb_ack_o, wb_err_o, wb_inta_o,
75
 
76
        // External RTC Interface
77
        clk_rtc_pad_i
78
);
79
 
80
parameter dw = 32;
81
parameter aw = `RTC_ADDRHH+1;
82
 
83
//
84
// WISHBONE Interface
85
//
86
input                   wb_clk_i;       // Clock
87
input                   wb_rst_i;       // Reset
88
input                   wb_cyc_i;       // cycle valid input
89
input   [aw-1:0] wb_adr_i;       // address bus inputs
90
input   [dw-1:0] wb_dat_i;       // input data bus
91
input   [3:0]            wb_sel_i;       // byte select inputs
92
input                   wb_we_i;        // indicates write transfer
93
input                   wb_stb_i;       // strobe input
94
output  [dw-1:0] wb_dat_o;       // output data bus
95
output                  wb_ack_o;       // normal termination
96
output                  wb_err_o;       // termination w/ error
97
output                  wb_inta_o;      // Interrupt request output
98
 
99
//
100
// External RTC Interface
101
//
102
input                   clk_rtc_pad_i;  // External clock
103
 
104
`ifdef RTC_IMPLEMENTED
105
 
106
//
107
// Counters of RTC Time Register
108
//
109
reg     [3:0]            time_tos;       // Tenth of second counter
110
reg     [3:0]            time_s;         // Seconds counter
111
reg     [2:0]            time_ts;        // Ten seconds counter
112
reg     [3:0]            time_m;         // Minutes counter
113
reg     [2:0]            time_tm;        // Ten minutes counter
114
reg     [3:0]            time_h;         // Hours counter
115
reg     [1:0]            time_th;        // Ten hours counter
116
reg     [2:0]            time_dow;       // Day of week counter
117
 
118
//
119
// Counter of RTC Date Register
120
//
121
reg     [3:0]            date_d;         // Days counter
122
reg     [1:0]            date_td;        // Ten days counter
123
reg     [3:0]            date_m;         // Months counter
124
reg                     date_tm;        // Ten months counter
125
reg     [3:0]            date_y;         // Years counter
126
reg     [3:0]            date_ty;        // Ten years counter
127
reg     [3:0]            date_c;         // Centuries counter
128
reg     [3:0]            date_tc;        // Ten centuries counter
129
 
130
//
131
// Clock division counter
132
//
133
`ifdef RTC_DIVIDER
134
reg     [26:0]           cntr_div;       // Division counter
135
reg                     div_clk;        // Tenth of a second clock
136
`else
137
wire                    div_clk;        // Tenth of a second clock
138
`endif
139
 
140
//
141
// RTC TALRM Register
142
//
143
`ifdef RTC_RRTC_TALRM
144
reg     [31:0]           rrtc_talrm;     // RRTC_TALRM register
145
`else
146
wire    [31:0]           rrtc_talrm;     // No register
147
`endif
148
 
149
//
150
// RTC DALRM Register
151
//
152
`ifdef RTC_RRTC_DALRM
153
reg     [30:0]           rrtc_dalrm;     // RRTC_DALRM register
154
`else
155
wire    [30:0]           rrtc_dalrm;     // No register
156
`endif
157
 
158
//
159
// RTC CTRL register
160
//
161
reg     [31:0]           rrtc_ctrl;      // RRTC_CTRL register
162
 
163
//
164
// Internal wires & regs
165
//
166
wire    [31:0]           rrtc_time;      // Alias
167
wire    [31:0]           rrtc_date;      // Alias
168
wire                    rrtc_time_sel;  // RRTC_TIME select
169
wire                    rrtc_date_sel;  // RRTC_DATE select
170
wire                    rrtc_talrm_sel; // RRTC_TALRM select
171
wire                    rrtc_dalrm_sel; // RRTC_DALRM select
172
wire                    rrtc_ctrl_sel;  // RRTC_CTRL select
173
wire                    match_tos;      // Tenth of second match
174
wire                    match_secs;     // Seconds match
175
wire                    match_mins;     // Minutes match
176
wire                    match_hrs;      // Hours match
177
wire                    match_dow;      // Day of week match
178
wire                    match_days;     // Days match
179
wire                    match_months;   // Months match
180
wire                    match_yrs;      // Years match
181
wire                    match_cents;    // Centuries match
182
wire                    rst_time_tos;   // Reset RRTC_TIME[TOS]
183
wire                    rst_time_s;     // Reset RRTC_TIME[S]
184
wire                    rst_time_ts;    // Reset RRTC_TIME[TS]
185
wire                    rst_time_m;     // Reset RRTC_TIME[M]
186
wire                    rst_time_tm;    // Reset RRTC_TIME[TM]
187
wire                    rst_time_h;     // Reset RRTC_TIME[H]
188
wire                    rst_time_th;    // Reset RRTC_TIME[TH]
189
wire                    rst_time_dow;   // Reset RRTC_TIME[DOW]
190
wire                    rst_date_d;     // Reset RRTC_DATE[D]
191
wire                    rst_date_td;    // Reset RRTC_DATE[TD]
192
wire                    rst_date_m;     // Reset RRTC_DATE[M]
193
wire                    rst_date_tm;    // Reset RRTC_DATE[TM]
194
wire                    rst_date_y;     // Reset RRTC_DATE[Y]
195
wire                    rst_date_ty;    // Reset RRTC_DATE[TY]
196
wire                    rst_date_c;     // Reset RRTC_DATE[C]
197
wire                    rst_date_tc;    // Reset RRTC_DATE[TC]
198
wire                    inc_time_tos;   // Enable counter RRTC_TIME[TOS]
199
wire                    inc_time_s;     // Enable counter RRTC_TIME[S]
200
wire                    inc_time_ts;    // Enable counter RRTC_TIME[TS]
201
wire                    inc_time_m;     // Enable counter RRTC_TIME[M]
202
wire                    inc_time_tm;    // Enable counter RRTC_TIME[TM]
203
wire                    inc_time_h;     // Enable counter RRTC_TIME[H]
204
wire                    inc_time_th;    // Enable counter RRTC_TIME[TH]
205
wire                    inc_time_dow;   // Enable counter RRTC_TIME[DOW]
206
wire                    inc_date_d;     // Enable counter RRTC_DATE[D]
207
wire                    inc_date_td;    // Enable counter RRTC_DATE[TD]
208
wire                    inc_date_m;     // Enable counter RRTC_DATE[M]
209
wire                    inc_date_tm;    // Enable counter RRTC_DATE[TM]
210
wire                    inc_date_y;     // Enable counter RRTC_DATE[Y]
211
wire                    inc_date_ty;    // Enable counter RRTC_DATE[TY]
212
wire                    inc_date_c;     // Enable counter RRTC_DATE[C]
213
wire                    inc_date_tc;    // Enable counter RRTC_DATE[TC]
214
wire                    one_date_d;     // Set RRTC_DATE[D] to 1
215
wire                    one_date_m;     // Set RRTC_DATE[M] to 1
216
wire                    hi_clk;         // Hi freq clock
217
wire                    lo_clk;         // Lo freq clock
218
wire                    alarm;          // Alarm condition
219
wire                    leapyear;       // Leap year
220
wire                    full_decoding;  // Full address decoding qualification
221
reg     [dw-1:0] wb_dat_o;       // Data out
222
 
223
//
224
// All WISHBONE transfer terminations are successful except when:
225
// a) full address decoding is enabled and address doesn't match
226
//    any of the RTC registers
227
// b) sel_i evaluation is enabled and one of the sel_i inputs is zero
228
//
229
assign wb_ack_o = wb_cyc_i & wb_stb_i & !wb_err_o;
230
`ifdef RTC_FULL_DECODE
231
`ifdef RTC_STRICT_32BIT_ACCESS
232
assign wb_err_o = wb_cyc_i & wb_stb_i & !full_decoding | (wb_sel_i != 4'b1111);
233
`else
234
assign wb_err_o = wb_cyc_i & wb_stb_i & !full_decoding;
235
`endif
236
`else
237
`ifdef RTC_STRICT_32BIT_ACCESS
238
assign wb_err_o = (wb_sel_i != 4'b1111);
239
`else
240
assign wb_err_o = 1'b0;
241
`endif
242
`endif
243
 
244
//
245
// Hi freq clock is selected by RRTC_CTRL[ECLK]. When it is set,
246
// external clock is used.
247
//
248
assign hi_clk = rrtc_ctrl[`RTC_RRTC_CTRL_ECLK] ? clk_rtc_pad_i : wb_clk_i;
249
 
250
//
251
// Lo freq clock divided hi freq clock when RRTC_CTRL[EN] is set.
252
// When RRTC_CTRL[EN] is cleared, lo freq clock is equal WISHBONE
253
// clock to allow writes into registers.
254
//
255
assign lo_clk = rrtc_ctrl[`RTC_RRTC_CTRL_EN] ? div_clk : wb_clk_i;
256
 
257
//
258
// Full address decoder
259
//
260
`ifdef RTC_FULL_DECODE
261
assign full_decoding = (wb_adr_i[`RTC_ADDRHH:`RTC_ADDRHL] == {`RTC_ADDRHH-`RTC_ADDRHL+1{1'b0}}) &
262
                        (wb_adr_i[`RTC_ADDRLH:`RTC_ADDRLL] == {`RTC_ADDRLH-`RTC_ADDRLL+1{1'b0}});
263
`else
264
assign full_decoding = 1'b1;
265
`endif
266
 
267
//
268
// RTC registers address decoder
269
//
270
assign rrtc_time_sel = wb_cyc_i & wb_stb_i & (wb_adr_i[`RTC_OFS_BITS] ==
271
`RTC_RRTC_TIME) & full_decoding;
272
assign rrtc_date_sel = wb_cyc_i & wb_stb_i & (wb_adr_i[`RTC_OFS_BITS] == `RTC_RRTC_DATE) & full_decoding;
273
assign rrtc_talrm_sel = wb_cyc_i & wb_stb_i & (wb_adr_i[`RTC_OFS_BITS] == `RTC_RRTC_TALRM) & full_decoding;
274
assign rrtc_dalrm_sel = wb_cyc_i & wb_stb_i & (wb_adr_i[`RTC_OFS_BITS] == `RTC_RRTC_DALRM) & full_decoding;
275
assign rrtc_ctrl_sel = wb_cyc_i & wb_stb_i & (wb_adr_i[`RTC_OFS_BITS] == `RTC_RRTC_CTRL) & full_decoding;
276
 
277
//
278
// Grouping of seperate fields into registers
279
//
280
assign rrtc_time = {5'b0, time_dow, time_th, time_h, time_tm,
281
                        time_m, time_ts, time_s, time_tos};
282
assign rrtc_date = {5'b0, date_tc, date_c, date_ty, date_y,
283
                        date_tm, date_m, date_td, date_d};
284
 
285
//
286
// Write to RRTC_CTRL or update of RRTC_CTRL[ALRM] bit
287
//
288
`ifdef RTC_RRTC_CTRL
289
always @(posedge wb_clk_i or posedge wb_rst_i)
290
        if (wb_rst_i)
291
                rrtc_ctrl <= #1 32'b0;
292
        else if (rrtc_ctrl_sel && wb_we_i)
293
                rrtc_ctrl <= #1 wb_dat_i;
294
        else if (rrtc_ctrl[`RTC_RRTC_CTRL_EN])
295
                rrtc_ctrl[`RTC_RRTC_CTRL_ALRM] <= #1 rrtc_ctrl[`RTC_RRTC_CTRL_ALRM] | alarm;
296
`else
297
assign rrtc_ctrl = `RTC_DEF_RRTC_CTRL;
298
`endif
299
 
300
//
301
// Clock divider
302
//
303
`ifdef RTC_DIVIDER
304
always @(posedge hi_clk or posedge wb_rst_i)
305
        if (wb_rst_i) begin
306
                cntr_div <= #1 27'b0;
307
                div_clk <= #1 1'b0;
308
        end else if (!cntr_div) begin
309
                cntr_div <= #1 rrtc_ctrl[`RTC_RRTC_CTRL_DIV];
310
                div_clk <= #1 ~div_clk;
311
        end else if (rrtc_ctrl[`RTC_RRTC_CTRL_EN])
312
                cntr_div <= #1 cntr_div - 1;
313
`else
314
assign div_clk = hi_clk;
315
`endif
316
 
317
//
318
// Write to RRTC_TALRM
319
//
320
`ifdef RTC_RRTC_TALRM
321
always @(posedge wb_clk_i or posedge wb_rst_i)
322
        if (wb_rst_i)
323
                rrtc_talrm <= #1 32'b0;
324
        else if (rrtc_talrm_sel && wb_we_i)
325
                rrtc_talrm <= #1 wb_dat_i;
326
`else
327
assign rrtc_talrm = `RTC_DEF_RRTC_TALRM;
328
`endif
329
 
330
//
331
// Write to RRTC_DALRM
332
//
333
`ifdef RTC_RRTC_DALRM
334
always @(posedge wb_clk_i or posedge wb_rst_i)
335
        if (wb_rst_i)
336
                rrtc_dalrm <= #1 31'b0;
337
        else if (rrtc_dalrm_sel && wb_we_i)
338
                rrtc_dalrm <= #1 wb_dat_i[30:0];
339
`else
340
assign rrtc_dalrm = `RTC_DEF_RRTC_DALRM;
341
`endif
342
 
343
//
344
// RRTC_TIME[TOS]
345
//
346
always @(posedge lo_clk)
347
        if (rrtc_time_sel && wb_we_i)
348
                time_tos <= #1 wb_dat_i[`RTC_RRTC_TIME_TOS];
349
        else if (rst_time_tos)
350
                time_tos <= #1 4'b0;
351
        else if (inc_time_tos)
352
                time_tos <= #1 time_tos + 1;
353
 
354
//
355
// RRTC_TIME[S]
356
//
357
always @(posedge lo_clk)
358
        if (rrtc_time_sel && wb_we_i)
359
                time_s <= #1 wb_dat_i[`RTC_RRTC_TIME_S];
360
        else if (rst_time_s)
361
                time_s <= #1 4'b0;
362
        else if (inc_time_s)
363
                time_s <= #1 time_s + 1;
364
 
365
//
366
// RRTC_TIME[TS]
367
//
368
always @(posedge lo_clk)
369
        if (rrtc_time_sel && wb_we_i)
370
                time_ts <= #1 wb_dat_i[`RTC_RRTC_TIME_TS];
371
        else if (rst_time_ts)
372
                time_ts <= #1 3'b0;
373
        else if (inc_time_ts)
374
                time_ts <= #1 time_ts + 1;
375
 
376
//
377
// RRTC_TIME[M]
378
//
379
always @(posedge lo_clk)
380
        if (rrtc_time_sel && wb_we_i)
381
                time_m <= #1 wb_dat_i[`RTC_RRTC_TIME_M];
382
        else if (rst_time_m)
383
                time_m <= #1 4'b0;
384
        else if (inc_time_m)
385
                time_m <= #1 time_m + 1;
386
 
387
//
388
// RRTC_TIME[TM]
389
//
390
always @(posedge lo_clk)
391
        if (rrtc_time_sel && wb_we_i)
392
                time_tm <= #1 wb_dat_i[`RTC_RRTC_TIME_TM];
393
        else if (rst_time_tm)
394
                time_tm <= #1 3'b0;
395
        else if (inc_time_tm)
396
                time_tm <= #1 time_tm + 1;
397
 
398
//
399
// RRTC_TIME[H]
400
//
401
always @(posedge lo_clk)
402
        if (rrtc_time_sel && wb_we_i)
403
                time_h <= #1 wb_dat_i[`RTC_RRTC_TIME_H];
404
        else if (rst_time_h)
405
                time_h <= #1 4'b0;
406
        else if (inc_time_h)
407
                time_h <= #1 time_h + 1;
408
 
409
//
410
// RRTC_TIME[TH]
411
//
412
always @(posedge lo_clk)
413
        if (rrtc_time_sel && wb_we_i)
414
                time_th <= #1 wb_dat_i[`RTC_RRTC_TIME_TH];
415
        else if (rst_time_th)
416
                time_th <= #1 2'b0;
417
        else if (inc_time_th)
418
                time_th <= #1 time_th + 1;
419
 
420
//
421
// RRTC_TIME[DOW]
422
//
423
always @(posedge lo_clk)
424
        if (rrtc_time_sel && wb_we_i)
425
                time_dow <= #1 wb_dat_i[`RTC_RRTC_TIME_DOW];
426
        else if (rst_time_dow)
427
                time_dow <= #1 3'h1;
428
        else if (inc_time_dow)
429
                time_dow <= #1 time_dow + 1;
430
 
431
//
432
// RRTC_DATE[D]
433
//
434
always @(posedge lo_clk)
435
        if (rrtc_date_sel && wb_we_i)
436
                date_d <= #1 wb_dat_i[`RTC_RRTC_DATE_D];
437
        else if (one_date_d)
438
                date_d <= #1 4'h1;
439
        else if (rst_date_d)
440
                date_d <= #1 4'h0;
441
        else if (inc_date_d)
442
                date_d <= #1 date_d + 1;
443
 
444
//
445
// RRTC_DATE[TD]
446
//
447
always @(posedge lo_clk)
448
        if (rrtc_date_sel && wb_we_i)
449
                date_td <= #1 wb_dat_i[`RTC_RRTC_DATE_TD];
450
        else if (rst_date_td)
451
                date_td <= #1 2'b0;
452
        else if (inc_date_td)
453
                date_td <= #1 date_td + 1;
454
 
455
//
456
// RRTC_DATE[M]
457
//
458
always @(posedge lo_clk)
459
        if (rrtc_date_sel && wb_we_i)
460
                date_m <= #1 wb_dat_i[`RTC_RRTC_DATE_M];
461
        else if (one_date_m)
462
                date_m <= #1 4'h1;
463
        else if (rst_date_m)
464
                date_m <= #1 4'h0;
465
        else if (inc_date_m)
466
                date_m <= #1 date_m + 1;
467
 
468
//
469
// RRTC_DATE[TM]
470
//
471
always @(posedge lo_clk)
472
        if (rrtc_date_sel && wb_we_i)
473
                date_tm <= #1 wb_dat_i[`RTC_RRTC_DATE_TM];
474
        else if (rst_date_tm)
475
                date_tm <= #1 1'b0;
476
        else if (inc_date_tm)
477
                date_tm <= #1 date_tm + 1;
478
 
479
//
480
// RRTC_DATE[Y]
481
//
482
always @(posedge lo_clk)
483
        if (rrtc_date_sel && wb_we_i)
484
                date_y <= #1 wb_dat_i[`RTC_RRTC_DATE_Y];
485
        else if (rst_date_y)
486
                date_y <= #1 4'b0;
487
        else if (inc_date_y)
488
                date_y <= #1 date_y + 1;
489
 
490
//
491
// RRTC_DATE[TY]
492
//
493
always @(posedge lo_clk)
494
        if (rrtc_date_sel && wb_we_i)
495
                date_ty <= #1 wb_dat_i[`RTC_RRTC_DATE_TY];
496
        else if (rst_date_ty)
497
                date_ty <= #1 4'b0;
498
        else if (inc_date_ty)
499
                date_ty <= #1 date_ty + 1;
500
 
501
//
502
// RRTC_DATE[C]
503
//
504
always @(posedge lo_clk)
505
        if (rrtc_date_sel && wb_we_i)
506
                date_c <= #1 wb_dat_i[`RTC_RRTC_DATE_C];
507
        else if (rst_date_c)
508
                date_c <= #1 4'b0;
509
        else if (inc_date_c)
510
                date_c <= #1 date_c + 1;
511
 
512
//
513
// RRTC_DATE[TC]
514
//
515
always @(posedge lo_clk)
516
        if (rrtc_date_sel && wb_we_i)
517
                date_tc <= #1 wb_dat_i[`RTC_RRTC_DATE_TC];
518
        else if (rst_date_tc)
519
                date_tc <= #1 4'b0;
520
        else if (inc_date_tc)
521
                date_tc <= #1 date_tc + 1;
522
 
523
//
524
// Read RTC registers
525
//
526
always @(wb_adr_i or rrtc_time or rrtc_date or rrtc_talrm or rrtc_dalrm or rrtc_ctrl)
527
        case (wb_adr_i[`RTC_OFS_BITS])  // synopsys full_case parallel_case
528
`ifdef RTC_READREGS
529
                `RTC_RRTC_TIME: wb_dat_o[dw-1:0] <= {{dw-27{1'b0}}, rrtc_time};
530
                `RTC_RRTC_DATE: wb_dat_o[dw-1:0] <= {{dw-27{1'b0}}, rrtc_date};
531
                `RTC_RRTC_TALRM: wb_dat_o[dw-1:0] <= rrtc_talrm;
532
                `RTC_RRTC_DALRM: wb_dat_o[dw-1:0] <= {{dw-31{1'b0}}, rrtc_dalrm};
533
`endif
534
                default: wb_dat_o <= rrtc_ctrl;
535
        endcase
536
 
537
//
538
// Asserted high when correspoding RRTC_TIME/DATE fields match
539
// RRTC_T/DALRM fields
540
//
541
assign match_tos = (time_tos == rrtc_talrm[`RTC_RRTC_TALRM_TOS]);
542
assign match_secs = (time_s == rrtc_talrm[`RTC_RRTC_TALRM_S]) &
543
                        (time_ts == rrtc_talrm[`RTC_RRTC_TALRM_TS]);
544
assign match_mins = (time_m == rrtc_talrm[`RTC_RRTC_TALRM_M]) &
545
                        (time_tm == rrtc_talrm[`RTC_RRTC_TALRM_TM]);
546
assign match_hrs = (time_h == rrtc_talrm[`RTC_RRTC_TALRM_H]) &
547
                        (time_th == rrtc_talrm[`RTC_RRTC_TALRM_TH]);
548
assign match_dow = (time_dow == rrtc_talrm[`RTC_RRTC_TALRM_DOW]);
549
assign match_days = (date_d == rrtc_dalrm[`RTC_RRTC_DALRM_D]) &
550
                        (date_td == rrtc_dalrm[`RTC_RRTC_DALRM_TD]);
551
assign match_months = (date_m == rrtc_dalrm[`RTC_RRTC_DALRM_M]) &
552
                        (date_tm == rrtc_dalrm[`RTC_RRTC_DALRM_TM]);
553
assign match_yrs = (date_y == rrtc_dalrm[`RTC_RRTC_DALRM_Y]) &
554
                        (date_ty == rrtc_dalrm[`RTC_RRTC_DALRM_TY]);
555
assign match_cents = (date_c == rrtc_dalrm[`RTC_RRTC_DALRM_C]) &
556
                        (date_tc == rrtc_dalrm[`RTC_RRTC_DALRM_TC]);
557
 
558
//
559
// Generate an alarm when all enabled match conditions are asserted high
560
//
561
assign alarm = (match_tos | ~rrtc_talrm[`RTC_RRTC_TALRM_CTOS]) &
562
                (match_secs | ~rrtc_talrm[`RTC_RRTC_TALRM_CS]) &
563
                (match_mins | ~rrtc_talrm[`RTC_RRTC_TALRM_CM]) &
564
                (match_hrs | ~rrtc_talrm[`RTC_RRTC_TALRM_CH]) &
565
                (match_dow | ~rrtc_talrm[`RTC_RRTC_TALRM_CDOW]) &
566
                (match_days | ~rrtc_dalrm[`RTC_RRTC_DALRM_CD]) &
567
                (match_months | ~rrtc_dalrm[`RTC_RRTC_DALRM_CM]) &
568
                (match_yrs | ~rrtc_dalrm[`RTC_RRTC_DALRM_CY]) &
569
                (match_cents | ~rrtc_dalrm[`RTC_RRTC_DALRM_CC]) &
570
                (rrtc_talrm[`RTC_RRTC_TALRM_CTOS] |
571
                 rrtc_talrm[`RTC_RRTC_TALRM_CS] |
572
                 rrtc_talrm[`RTC_RRTC_TALRM_CM] |
573
                 rrtc_talrm[`RTC_RRTC_TALRM_CH] |
574
                 rrtc_talrm[`RTC_RRTC_TALRM_CDOW] |
575
                 rrtc_dalrm[`RTC_RRTC_DALRM_CD] |
576
                 rrtc_dalrm[`RTC_RRTC_DALRM_CM] |
577
                 rrtc_dalrm[`RTC_RRTC_DALRM_CY] |
578
                 rrtc_dalrm[`RTC_RRTC_DALRM_CC]);
579
 
580
//
581
// Generate an interrupt request
582
//
583
assign wb_inta_o = rrtc_ctrl[`RTC_RRTC_CTRL_ALRM] & rrtc_ctrl[`RTC_RRTC_CTRL_INTE];
584
 
585
//
586
// Control of counters:
587
// Asserted high when correspoding RRTC_TIME/DATE fields reach
588
// boundary values and previous counters are cleared
589
//
590
assign rst_time_tos = (time_tos == 4'd9) | rrtc_ctrl[`RTC_RRTC_CTRL_BTOS] | wb_rst_i;
591
assign rst_time_s = (time_s == 4'd9) & rst_time_tos | wb_rst_i;
592
assign rst_time_ts = (time_ts == 3'd5) & rst_time_s | wb_rst_i;
593
assign rst_time_m = (time_m == 4'd9) & rst_time_ts | wb_rst_i;
594
assign rst_time_tm = (time_tm == 3'd5) & rst_time_m | wb_rst_i;
595
assign rst_time_h = (time_h == 4'd9) & rst_time_tm
596
                        | (time_th == 2'd2) & (time_h == 4'd3) & rst_time_tm
597
                        | wb_rst_i;
598
assign rst_time_th = (time_th == 2'd2) & rst_time_h | wb_rst_i;
599
assign rst_time_dow = (time_dow == 3'd7) & rst_time_th | wb_rst_i;
600
assign one_date_d =
601
               ({date_tm, date_m} == 8'h01 & date_td == 2'd3 & date_d == 4'd1 |
602
                {date_tm, date_m} == 8'h02 & date_td == 2'd2 & date_d == 4'd8 & ~leapyear |
603
                {date_tm, date_m} == 8'h02 & date_td == 2'd2 & date_d == 4'd9 & leapyear |
604
                {date_tm, date_m} == 8'h03 & date_td == 2'd3 & date_d == 4'd1 |
605
                {date_tm, date_m} == 8'h04 & date_td == 2'd3 & date_d == 4'd0 |
606
                {date_tm, date_m} == 8'h05 & date_td == 2'd3 & date_d == 4'd1 |
607
                {date_tm, date_m} == 8'h06 & date_td == 2'd3 & date_d == 4'd0 |
608
                {date_tm, date_m} == 8'h07 & date_td == 2'd3 & date_d == 4'd1 |
609
                {date_tm, date_m} == 8'h08 & date_td == 2'd3 & date_d == 4'd1 |
610
                {date_tm, date_m} == 8'h09 & date_td == 2'd3 & date_d == 4'd0 |
611
                {date_tm, date_m} == 8'h10 & date_td == 2'd3 & date_d == 4'd1 |
612
                {date_tm, date_m} == 8'h11 & date_td == 2'd3 & date_d == 4'd0 |
613
                {date_tm, date_m} == 8'h12 & date_td == 2'd3 & date_d == 4'd1 ) & rst_time_th |
614
                wb_rst_i;
615
assign rst_date_d = date_d == 4'd9 & rst_time_th;
616
assign rst_date_td = ({date_tm, date_m} == 8'h02 & date_td[1] |
617
                date_td == 2'h3) & (rst_date_d | one_date_d) |
618
                wb_rst_i;
619
assign one_date_m = date_tm & (date_m == 4'd2) & rst_date_td | wb_rst_i;
620
assign rst_date_m = ~date_tm & (date_m == 4'd9) & rst_date_td;
621
assign rst_date_tm = date_tm & (rst_date_m | one_date_m) | wb_rst_i;
622
assign rst_date_y = (date_y == 4'd9) & rst_date_tm | wb_rst_i;
623
assign rst_date_ty = (date_ty == 4'd9)& rst_date_y  | wb_rst_i;
624
assign rst_date_c = (date_c == 4'd9) & rst_date_ty | wb_rst_i;
625
assign rst_date_tc = (date_tc == 4'd9) & rst_date_c | wb_rst_i;
626
 
627
//
628
// Control for counter increment
629
//
630
assign inc_time_tos = rrtc_ctrl[`RTC_RRTC_CTRL_EN] & ~rrtc_ctrl[`RTC_RRTC_CTRL_BTOS];
631
assign inc_time_s = rst_time_tos | rrtc_ctrl[`RTC_RRTC_CTRL_BTOS] & rrtc_ctrl[`RTC_RRTC_CTRL_EN];
632
assign inc_time_ts = rst_time_s;
633
assign inc_time_m = rst_time_ts;
634
assign inc_time_tm = rst_time_m;
635
assign inc_time_h = rst_time_tm;
636
assign inc_time_th = rst_time_h;
637
assign inc_time_dow = rst_time_th;
638
assign inc_date_d = rst_time_th;
639
assign inc_date_td = rst_date_d;
640
assign inc_date_m = rst_date_td;
641
assign inc_date_tm = rst_date_m;
642
assign inc_date_y = rst_date_tm;
643
assign inc_date_ty = rst_date_y;
644
assign inc_date_c = rst_date_ty;
645
assign inc_date_tc = rst_date_c;
646
 
647
//
648
// Leap year calculation
649
//
650
assign leapyear =
651
        (({date_ty, date_y} == 8'h00) &                         // xx00
652
         (( date_tc[0] & ~date_c[3] & (date_c[1:0] == 2'b10)) |   // 12xx, 16xx, 32xx ...
653
          (~date_tc[0] & (date_c[1:0] == 2'b00) &         // 00xx, 04xx, 08xx, 20xx, 24xx ...
654
           ((date_c[3:2] == 2'b01) | ~date_c[2])))) |
655
        (~date_ty[0] & (date_y[1:0] == 2'b00) & ({date_ty, date_y} != 8'h00)) | // xx04, xx08, xx24 ...
656
        (date_ty[0] & (date_y[1:0] == 2'b10));                    // xx12, xx16, xx32 ...
657
 
658
 
659
`else
660
 
661
//
662
// When RTC is not implemented, drive all outputs as would when RRTC_CTRL
663
// is cleared and WISHBONE transfers complete with errors
664
//
665
assign wb_inta_o = 1'b0;
666
assign wb_ack_o = 1'b0;
667
assign wb_err_o = wb_cyc_i & wb_stb_i;
668
 
669
//
670
// Read RTC registers
671
//
672
assign wb_dat_o = {dw{1'b0}};
673
 
674
`endif
675
 
676
endmodule

powered by: WebSVN 2.1.0

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