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

Subversion Repositories datetime

[/] [datetime/] [trunk/] [rtl/] [verilog/] [rfDatetime.sv] - Blame information for rev 3

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 3 robfinch
`timescale 1ns / 1ps
2
// ============================================================================
3
//        __
4
//   \\__/ o\    (C) 2007-2023  Robert Finch, Waterloo
5
//    \  __ /    All rights reserved.
6
//     \/_//     robfinch@finitron.ca
7
//       ||
8
//
9
//
10
// BSD 3-Clause License
11
// Redistribution and use in source and binary forms, with or without
12
// modification, are permitted provided that the following conditions are met:
13
//
14
// 1. Redistributions of source code must retain the above copyright notice, this
15
//    list of conditions and the following disclaimer.
16
//
17
// 2. Redistributions in binary form must reproduce the above copyright notice,
18
//    this list of conditions and the following disclaimer in the documentation
19
//    and/or other materials provided with the distribution.
20
//
21
// 3. Neither the name of the copyright holder nor the names of its
22
//    contributors may be used to endorse or promote products derived from
23
//    this software without specific prior written permission.
24
//
25
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
26
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
27
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
28
// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
29
// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
30
// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
31
// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
32
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
33
// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
34
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
35
//
36
//
37
// ============================================================================
38
//
39
//
40
//      BCD representations are used
41
//      - BCD allows direct visual indication of values without
42
//      needing to convert hexidecimal values
43
//
44
//
45
//      Reg
46
//
47
//      0        DT - Date/Time register
48
//              [ 7: 0] read / write jiffies
49
//          [15: 8] read / write seconds
50
//          [23:16] read / write minutes
51
//      [31:24] read / write hours
52
//  1
53
//              [7:0] read/write day
54
//              [15:8] read/write month
55
//              [31:16] read/write year
56
//      2   ALM - alarm register same format as 0, but contain alarm setting
57
//  3
58
//
59
//  4   CR - control register
60
//      [ 7: 0] write - which bytes to match for alarm
61
//      [8] - time of day enable
62
//      [10: 9] - 00=100 Hz, 01=60Hz, 10=50Hz
63
//      [16] - mars timekeeping
64
//
65
//      5
66
//              writing this register triggers a snapshot
67
//              - trigger a snapshot before reading the date / time
68
//              registers
69
//              - the snapshot allows the date / time value to be
70
//              read without having to worry about an update occuring
71
//              during the read
72
//              - a copy of the current date and time is stored in
73
//              the output registers
74
//
75
//      +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
76
//      |WISHBONE Datasheet
77
//      |WISHBONE SoC Architecture Specification, Revision B.3
78
//      |
79
//      |Description:                                           Specifications:
80
//      +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
81
//      |General Description:                           Date/Time keeping core
82
//      +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
83
//      |Supported Cycles:                                      SLAVE,READ/WRITE
84
//      |                                                                       SLAVE,BLOCK READ/WRITE
85
//      |                                                                       SLAVE,RMW
86
//      +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
87
//      |Data port, size:                                       32 bit
88
//      |Data port, granularity:                        32 bit
89
//      |Data port, maximum operand size:       32 bit
90
//      |Data transfer ordering:                        Undefined
91
//      |Data transfer sequencing:                      Undefined
92
//      +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
93
//      |Clock frequency constraints:           tod clock must be 50,60, or 100 Hz
94
//      +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
95
//      |Supported signal list and                      Signal Name             WISHBONE equiv.
96
//      |cross reference to equivalent          ack_o                           ACK_O
97
//      |WISHBONE signals                                       adr_i(33:0)                     ADR_I()
98
//      |                                                                       clk_i                           CLK_I
99
//      |                                                                       dat_i(15:0)                     DAT_I()
100
//      |                                                                       dat_o(15:0)                     DAT_O()
101
//      |                                                                       cyc_i                           CYC_I
102
//      |                                                                       stb_i                           STB_I
103
//      |                                                                       we_i                            WE_I
104
//      |
105
//      +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
106
//      |Special requirements:
107
//      +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
108
//
109
// 302 LUTs / 324 FFs
110
//=============================================================================
111
//
112
module rfDatetime
113
(
114
// Syscon
115
input rst_i,            // reset
116
input clk_i,            // system clock
117
 
118
// Circuit selects
119
input cs_config_i,
120
input cs_io_i,
121
 
122
// System bus
123
input cyc_i,            // valid bus cycle
124
input stb_i,            // data transfer strobe
125
output ack_o,           // transfer acknowledge
126
input we_i,                     // 1=write
127
input [3:0] sel_i,      // byte select
128
input [31:0] adr_i,     // address
129
input [31:0] dat_i,     // data input
130
output reg [31:0] dat_o,        // data output
131
 
132
input tod,                      // tod pulse (eg 60 Hz)
133
output irq_o            // alarm match
134
);
135
parameter MARS_TIME = 1'b0;
136
parameter IO_ADDR = 32'hFEF30001;
137
parameter IO_ADDR_MASK = 32'h00FF0000;
138
 
139
parameter CFG_BUS = 8'd0;
140
parameter CFG_DEVICE = 5'd7;
141
parameter CFG_FUNC = 3'd0;
142
parameter CFG_VENDOR_ID =       16'h0;
143
parameter CFG_DEVICE_ID =       16'h0;
144
parameter CFG_SUBSYSTEM_VENDOR_ID       = 16'h0;
145
parameter CFG_SUBSYSTEM_ID = 16'h0;
146
parameter CFG_ROM_ADDR = 32'hFFFFFFF0;
147
 
148
parameter CFG_REVISION_ID = 8'd0;
149
parameter CFG_PROGIF = 8'd1;
150
parameter CFG_SUBCLASS = 8'h80;                                 // 80 = Other (RTC)
151
parameter CFG_CLASS = 8'h08;                                            // 08 = Base system controller
152
parameter CFG_CACHE_LINE_SIZE = 8'd8;           // 32-bit units
153
parameter CFG_MIN_GRANT = 8'h00;
154
parameter CFG_MAX_LATENCY = 8'h00;
155
parameter CFG_IRQ_LINE = 8'd16;
156
 
157
localparam CFG_HEADER_TYPE = 8'h00;                     // 00 = a general device
158
 
159
parameter MSIX = 1'b0;
160
 
161
wire cs_rtc;
162
reg alarm;
163
 
164
// Register inputs
165
reg [31:0] dati;
166
reg we;
167
reg [3:0] sel;
168
reg [31:0] adr;
169
 
170
always_ff @(posedge clk_i)
171
        dati <= dat_i;
172
always_ff @(posedge clk_i)
173
        adr <= adr_i;
174
always_ff @(posedge clk_i)
175
        we <= we_i;
176
always_ff @(posedge clk_i)
177
        sel <= sel_i;
178
 
179
wire [31:0] cfg_out;
180
wire irq_en;
181
 
182
wire cs_config = cs_config_i & cyc_i & stb_i &&
183
        adr_i[27:20]==CFG_BUS &&
184
        adr_i[19:15]==CFG_DEVICE &&
185
        adr_i[14:12]==CFG_FUNC;
186
wire cs_io = cs_io_i & cyc_i & stb_i & cs_rtc;
187
 
188
pci32_config #(
189
        .CFG_BUS(CFG_BUS),
190
        .CFG_DEVICE(CFG_DEVICE),
191
        .CFG_FUNC(CFG_FUNC),
192
        .CFG_VENDOR_ID(CFG_VENDOR_ID),
193
        .CFG_DEVICE_ID(CFG_DEVICE_ID),
194
        .CFG_BAR0(IO_ADDR),
195
        .CFG_BAR0_MASK(IO_ADDR_MASK),
196
        .CFG_SUBSYSTEM_VENDOR_ID(CFG_SUBSYSTEM_VENDOR_ID),
197
        .CFG_SUBSYSTEM_ID(CFG_SUBSYSTEM_ID),
198
        .CFG_ROM_ADDR(CFG_ROM_ADDR),
199
        .CFG_REVISION_ID(CFG_REVISION_ID),
200
        .CFG_PROGIF(CFG_PROGIF),
201
        .CFG_SUBCLASS(CFG_SUBCLASS),
202
        .CFG_CLASS(CFG_CLASS),
203
        .CFG_CACHE_LINE_SIZE(CFG_CACHE_LINE_SIZE),
204
        .CFG_MIN_GRANT(CFG_MIN_GRANT),
205
        .CFG_MAX_LATENCY(CFG_MAX_LATENCY),
206
        .CFG_IRQ_LINE(CFG_IRQ_LINE)
207
)
208
ucfg1
209
(
210
        .rst_i(rst_i),
211
        .clk_i(clk_i),
212
        .irq_i(alarm),
213
        .irq_o(irq_o),
214
        .cs_config_i(cs_config),
215
        .we_i(we),
216
        .sel_i(sel),
217
        .adr_i(adr),
218
        .dat_i(dati),
219
        .dat_o(cfg_out),
220
        .cs_bar0_o(cs_rtc),
221
        .cs_bar1_o(),
222
        .cs_bar2_o(),
223
        .irq_en_o(irq_en)
224
);
225
 
226
reg [1:0] tod_freq;
227
wire [7:0] max_cnt = tod_freq==2'b00 ? 8'h99 : tod_freq==2'b01 ? 8'h59 : tod_freq==2'b10 ? 8'h49 : 8'h99;
228
reg tod_en;
229
reg mars;
230
reg [1:0] snapshot;
231
reg snapshotA;
232
 
233
// internal counters
234
reg [3:0] dayL, dayH;           // 1-99
235
reg [3:0] monthL, monthH;       // 1-99
236
reg [3:0] yearN0, yearN1, yearN2, yearN3;       //
237
reg [3:0] jiffyL, secL, minL, hourL;
238
reg [3:0] jiffyH, secH, minH, hourH;
239
 
240
// Leap year detection
241
reg [7:0] binYear, binCent;
242
reg leapCentury;
243
reg leapYear,duckYear;
244
 
245
always_comb
246
        binYear = {yearN1,3'b0} + {yearN1,1'b0} + yearN0;
247
always_comb
248
        binCent = {yearN3,3'b0} + {yearN3,1'b0} + yearN2;
249
always_comb
250
        leapCentury = !(binCent[1:0]==2'd0 && yearN1=='d0 && yearN0=='d0);
251
always_comb
252
        leapYear = binYear[1:0]==2'd0 && leapCentury;
253
 
254
always_comb
255
        duckYear = yearN0==4'h1 || yearN0==4'h3 || yearN0==4'h6 || yearN0==4'h8;
256
 
257
// output latches
258
reg [3:0] dayLo, dayHo;         // 1-99
259
reg [3:0] monthLo, monthHo;     // 1-99
260
reg [3:0] yearN0o, yearN1o, yearN2o, yearN3o;   //
261
reg [3:0] jiffyLo, secLo, minLo, hourLo;
262
reg [3:0] jiffyHo, secHo, minHo, hourHo;
263
 
264
// alarm
265
reg [7:0] alarm_care;
266
wire [63:0] alarm_carex = {
267
        {8{alarm_care[7]}},
268
        {8{alarm_care[6]}},
269
        {8{alarm_care[5]}},
270
        {8{alarm_care[4]}},
271
        {8{alarm_care[3]}},
272
        {8{alarm_care[2]}},
273
        {8{alarm_care[1]}},
274
        {8{alarm_care[0]}}
275
};
276
reg [3:0] alm_dayL, alm_dayH;           // 1-99
277
reg [3:0] alm_monthL, alm_monthH;       // 1-99
278
reg [3:0] alm_yearN0, alm_yearN1, alm_yearN2, alm_yearN3;       //
279
reg [3:0] alm_jiffyL, alm_secL, alm_minL, alm_hourL;
280
reg [3:0] alm_jiffyH, alm_secH, alm_minH, alm_hourH;
281
 
282
reg [3:0] alm_dayLo, alm_dayHo;         // 1-99
283
reg [3:0] alm_monthLo, alm_monthHo;     // 1-99
284
reg [3:0] alm_yearN0o, alm_yearN1o, alm_yearN2o, alm_yearN3o;   //
285
reg [3:0] alm_jiffyLo, alm_secLo, alm_minLo, alm_hourLo;
286
reg [3:0] alm_jiffyHo, alm_secHo, alm_minHo, alm_hourHo;
287
 
288
// update detects
289
wire incJiffyH = jiffyL == 4'd9;
290
wire incSecL = {jiffyH,jiffyL}==max_cnt;
291
wire incSecH = incSecL && secL==4'h9;
292
wire incMinL = incSecH && secH==4'h5;
293
wire incMinH = incMinL && minL==4'h9;
294
wire incHourL = incMinH && minH==4'h5;
295
wire incHourH = incHourL && hourL==4'h9;
296
 
297
wire incDayL    = mars ?
298
                                        {hourH,hourL,minH,minL,secH,secL,jiffyH,jiffyL} == {24'h243721,max_cnt} :
299
                                        {hourH,hourL,minH,minL,secH,secL,jiffyH,jiffyL} == {24'h235959,max_cnt}
300
                                        ;
301
wire incDayH = incDayL && dayL==4'h9;
302
 
303
// 668.5991
304
reg incMarsMonth;
305
always_comb
306
        begin
307
        case({monthH,monthL})   // synopsys full_case parallel_case
308
        8'h01:  incMarsMonth = {dayH,dayL}==8'h33;
309
        8'h02:  incMarsMonth = {dayH,dayL}==8'h33;
310
        8'h03:  incMarsMonth = {dayH,dayL}==8'h33;
311
        8'h04:  incMarsMonth = {dayH,dayL}==8'h34;
312
        8'h05:  incMarsMonth = {dayH,dayL}==8'h34;
313
        8'h06:  incMarsMonth = {dayH,dayL}==8'h33;
314
        8'h07:  incMarsMonth = {dayH,dayL}==8'h33;
315
        8'h08:  incMarsMonth = {dayH,dayL}==8'h33;
316
        8'h09:  incMarsMonth = {dayH,dayL}==8'h34;
317
        8'h10:  incMarsMonth = {dayH,dayL}==8'h34;
318
        8'h11:  incMarsMonth = {dayH,dayL}==8'h33;
319
        8'h12:  incMarsMonth = {dayH,dayL}==8'h33;
320
        8'h13:  incMarsMonth = {dayH,dayL}==8'h33;
321
        8'h14:  incMarsMonth = {dayH,dayL}==8'h34;
322
        8'h15:  incMarsMonth = {dayH,dayL}==8'h34;
323
        8'h16:  incMarsMonth = {dayH,dayL}==8'h33;
324
        8'h17:  incMarsMonth = {dayH,dayL}==8'h33;
325
        8'h18:  incMarsMonth = {dayH,dayL}==8'h33;
326
        8'h19:  incMarsMonth = {dayH,dayL}==8'h34;
327
        8'h20:  incMarsMonth = duckYear ? {dayH,dayL}==8'h34 : {dayH,dayL}==8'h35;
328
        endcase
329
        end
330
 
331
 
332
reg incEarthMonth;
333
always_comb
334
        begin
335
        case({monthH,monthL})   // synopsys full_case parallel_case
336
        8'h01:  incEarthMonth = {dayH,dayL}==8'h31;
337
        8'h02:  incEarthMonth = leapYear ? {dayH,dayL}==8'h29 : {dayH,dayL}==8'h28;
338
        8'h03:  incEarthMonth = {dayH,dayL}==8'h31;
339
        8'h04:  incEarthMonth = {dayH,dayL}==8'h30;
340
        8'h05:  incEarthMonth = {dayH,dayL}==8'h31;
341
        8'h06:  incEarthMonth = {dayH,dayL}==8'h30;
342
        8'h07:  incEarthMonth = {dayH,dayL}==8'h31;
343
        8'h08:  incEarthMonth = {dayH,dayL}==8'h31;
344
        8'h09:  incEarthMonth = {dayH,dayL}==8'h30;
345
        8'h10:  incEarthMonth = {dayH,dayL}==8'h31;
346
        8'h11:  incEarthMonth = {dayH,dayL}==8'h30;
347
        8'h12:  incEarthMonth = {dayH,dayL}==8'h31;
348
        endcase
349
        end
350
 
351
wire incMonthL  = incDayH && (mars ? incMarsMonth : incEarthMonth);
352
wire incMonthH  = incMonthL && monthL==4'd9;
353
wire incYearN0  = incMonthH && (mars ? {monthH,monthL} == 8'h20 : {monthH,monthL} == 8'h12);
354
wire incYearN1  = incYearN0 && yearN0 == 4'h9;
355
wire incYearN2  = incYearN1 && yearN1 == 4'h9;
356
wire incYearN3  = incYearN2 && yearN2 == 4'h9;
357
 
358
 
359
wire cs = cs_io;
360
 
361
reg ack1;
362
always_ff @(posedge clk_i)
363
        ack1 <= cs|cs_config;
364
assign ack_o = (cs|cs_config) ? (we_i ? 1'b1 : ack1) : 1'b0;
365
 
366
// Synchronize external tod signal
367
wire tods;
368
sync2s sync0(.rst(rst_i), .clk(clk_i), .i(tod), .o(tods));
369
 
370
// Edge detect the incoming tod signal.
371
wire tod_edge;
372
edge_det ed_tod(.rst(rst_i), .clk(clk_i), .ce(1'b1), .i(tods), .pe(tod_edge), .ne(), .ee());
373
 
374
// Output alarm pulse on match
375
wire isAlarm =
376
                {
377
                        alm_jiffyH,alm_jiffyL,
378
                        alm_secH,alm_secL,
379
                        alm_minH,alm_minL,
380
                        alm_hourH, alm_hourL,
381
                        alm_dayH,alm_dayL,
382
                        alm_monthH,alm_monthL,
383
                        alm_yearN1,alm_yearN0,
384
                        alm_yearN3,alm_yearN2
385
                } & alarm_carex ==
386
                {
387
                        jiffyH,jiffyL,
388
                        secH,secL,
389
                        minH,minL,
390
                        hourH,hourL,
391
                        dayH,dayL,
392
                        monthH,monthL,
393
                        yearN1,yearN0,
394
                        yearN3,yearN3
395
                } & alarm_carex;
396
 
397
 
398
reg oalarm;
399
 
400
always_ff @(posedge clk_i)
401
if (rst_i) begin
402
        oalarm <= 1'b0;
403
        mars <= MARS_TIME;
404
        tod_en <= 1'b1;
405
        tod_freq <= 2'b00;      // default to 100Hz
406
 
407
        jiffyL <= 4'h0;
408
        jiffyH <= 4'h0;
409
        secL <= 4'h0;
410
        secH <= 4'h0;
411
        minL <= 4'h6;
412
        minH <= 4'h0;
413
        hourL <= 4'h3;
414
        hourH <= 4'h1;
415
 
416
        dayL <= 4'h0;
417
        dayH <= 4'h1;
418
        monthL <= 4'h6;
419
        monthH <= 4'h0;
420
        yearN0 <= 4'h2;
421
        yearN1 <= 4'h1;
422
        yearN2 <= 4'h0;
423
        yearN3 <= 4'h2;
424
 
425
        alarm_care <= 8'hFF;
426
        alm_jiffyLo <= 4'h0;
427
        alm_jiffyHo <= 4'h0;
428
        alm_secLo <= 4'h0;
429
        alm_secHo <= 4'h0;
430
        alm_minLo <= 4'h0;
431
        alm_minHo <= 4'h0;
432
        alm_hourLo <= 4'h0;
433
        alm_hourHo <= 4'h0;
434
 
435
        alm_dayLo <= 4'h0;
436
        alm_dayHo <= 4'h0;
437
        alm_monthLo <= 4'h0;
438
        alm_monthHo <= 4'h0;
439
        alm_yearN0o <= 4'h0;
440
        alm_yearN1o <= 4'h0;
441
        alm_yearN2o <= 4'h0;
442
        alm_yearN3o <= 4'h0;
443
 
444
        snapshot <= 2'b0;
445
        snapshotA <= 'd0;
446
 
447
end
448
else begin
449
 
450
        oalarm <= isAlarm;
451
        snapshot <= 2'b0;       // ensure it only pulses
452
        snapshotA <= 'd0;
453
 
454
        // Take snapshot of date / time
455
        if (snapshot[0]) begin
456
                jiffyLo <= jiffyL;
457
                jiffyHo <= jiffyH;
458
                secLo <= secL;
459
                secHo <= secH;
460
                minLo <= minL;
461
                minHo <= minH;
462
                hourLo <= hourL;
463
                hourHo <= hourH;
464
                dayLo <= dayL;
465
                dayHo <= dayH;
466
                monthLo <= monthL;
467
                monthHo <= monthH;
468
                yearN0o <= yearN0;
469
                yearN1o <= yearN1;
470
                yearN2o <= yearN2;
471
                yearN3o <= yearN3;
472
        end
473
 
474
        if (snapshot[1]) begin
475
                jiffyL <= jiffyLo;
476
                jiffyH <= jiffyHo;
477
                secL <= secLo;
478
                secH <= secHo;
479
                minL <= minLo;
480
                minH <= minHo;
481
                hourL <= hourLo;
482
                hourH <= hourHo;
483
                dayL <= dayLo;
484
                dayH <= dayHo;
485
                monthL <= monthLo;
486
                monthH <= monthHo;
487
                yearN0 <= yearN0o;
488
                yearN1 <= yearN1o;
489
                yearN2 <= yearN2o;
490
                yearN3 <= yearN3o;
491
        end
492
 
493
        if (snapshotA) begin
494
                alm_jiffyL <= alm_jiffyLo;
495
                alm_jiffyH <= alm_jiffyHo;
496
                alm_secL <= alm_secLo;
497
                alm_secH <= alm_secHo;
498
                alm_minL <= alm_minLo;
499
                alm_minH <= alm_minHo;
500
                alm_hourL <= alm_hourLo;
501
                alm_hourH <= alm_hourHo;
502
                alm_dayL <= alm_dayLo;
503
                alm_dayH <= alm_dayHo;
504
                alm_monthL <= alm_monthLo;
505
                alm_monthH <= alm_monthHo;
506
                alm_yearN0 <= alm_yearN0o;
507
                alm_yearN1 <= alm_yearN1o;
508
                alm_yearN2 <= alm_yearN2o;
509
                alm_yearN3 <= alm_yearN3o;
510
        end
511
 
512
        if (isAlarm & !oalarm)
513
                alarm <= irq_en;
514
 
515
        // Handle register updates
516
        if (cs & we) begin
517
                case(adr[4:2])
518
 
519
                3'd0:   begin
520
                                if (sel[0]) begin jiffyLo <= dati[3:0]; jiffyHo <= dati[7:4]; end
521
                                if (sel[1]) begin secLo <= dati[11:8]; secHo <= dati[15:12]; end
522
                                if (sel[2]) begin minLo <= dati[19:16]; minHo <= dati[23:20]; end
523
                                if (sel[3]) begin hourLo <= dati[27:24]; hourHo <= dati[31:28]; end
524
                                end
525
                3'd1:   begin
526
                                if (sel[0]) begin dayLo <= dati[3:0]; dayHo <= dati[7:4]; end
527
                                if (sel[1]) begin monthLo <= dati[11:8]; monthHo <= dati[15:12]; end
528
                                if (sel[2]) begin yearN0o <= dati[19:16]; yearN1o <= dati[23:20]; end
529
                                if (sel[3]) begin yearN2o <= dati[27:24]; yearN3o <= dati[31:28]; end
530
                                end
531
                3'd2:   begin
532
                                if (sel[0]) begin alm_jiffyLo <= dati[3:0]; alm_jiffyHo <= dati[7:4]; end
533
                                if (sel[1]) begin alm_secLo <= dati[11:8]; alm_secHo <= dati[15:12]; end
534
                                if (sel[2]) begin alm_minLo <= dati[19:16]; alm_minHo <= dati[23:20]; end
535
                                if (sel[3]) begin alm_hourLo <= dati[27:24]; alm_hourHo <= dati[31:28]; end
536
                                end
537
                3'd3:   begin
538
                                if (sel[0]) begin alm_dayLo <= dati[3:0]; alm_dayHo <= dati[7:4]; end
539
                                if (sel[1]) begin alm_monthLo <= dati[11:8]; alm_monthHo <= dati[15:12]; end
540
                                if (sel[2]) begin alm_yearN0o <= dati[19:16]; alm_yearN1o <= dati[23:20]; end
541
                                if (sel[3]) begin alm_yearN2o <= dati[27:24]; alm_yearN3o <= dati[31:28]; end
542
                                end
543
                3'd4:   begin
544
                                if (sel[0]) alarm_care <= dati[7:0];
545
                                if (sel[1])
546
                                        begin
547
                                                tod_en <= dati[8];
548
                                                tod_freq <= dati[10:9];
549
                                        end
550
                                if (sel[2]) mars <= dati[16];
551
                                end
552
 
553
                // writing to register 5 triggers a snapshot
554
                3'd5:
555
                        begin
556
                                if (sel[0]) snapshot <= dati[1:0];
557
                                if (sel[1]) snapshotA <= dati[8];
558
                        end
559
 
560
                endcase
561
        end
562
        if (cs_config)
563
                dat_o <= cfg_out;
564
        else if (cs) begin
565
                case(adr[4:2])
566
                3'd0:   dat_o <= {hourHo,hourLo,minHo,minLo,secHo,secLo,jiffyHo,jiffyLo};
567
                3'd1:   dat_o <= {yearN3o,yearN2o,yearN1o,yearN0o,monthHo,monthLo,dayHo,dayLo};
568
                3'd2:   begin
569
                                        dat_o <= {alm_hourHo,alm_hourLo,alm_minHo,alm_minLo,alm_secHo,alm_secLo,alm_jiffyHo,alm_jiffyLo};
570
                                        alarm <= 1'b0;
571
                                end
572
                3'd3:   begin
573
                                        dat_o <= {alm_yearN3o,alm_yearN2o,alm_yearN1o,alm_yearN0o,alm_monthHo,alm_monthLo,alm_dayHo,alm_dayLo};
574
                                        alarm <= 1'b0;
575
                                end
576
                3'd4:   dat_o <= {mars,5'b0,tod_freq,tod_en,alarm_care};
577
                3'd5:   dat_o <= 0;
578
                endcase
579
        end
580
        else
581
                dat_o <= 32'd0;
582
 
583
 
584
        // Clock updates
585
        if (tod_en & tod_edge) begin
586
 
587
                jiffyL <= jiffyL + 4'h1;
588
 
589
                if (incJiffyH) begin
590
                        jiffyL <= 4'h0;
591
                        jiffyH <= jiffyH + 4'h1;
592
                end
593
 
594
                // Seconds
595
                if (incSecL) begin
596
                        jiffyH <= 4'h0;
597
                        secL <= secL + 4'h1;
598
                end
599
                if (incSecH) begin
600
                        secL <= 4'h0;
601
                        secH <= secH + 4'h1;
602
                end
603
 
604
                if (incMinL) begin
605
                        minL <= minL + 4'h1;
606
                        secH <= 4'h0;
607
                end
608
                if (incMinH) begin
609
                        minL <= 4'h0;
610
                        minH <= minH + 4'h1;
611
                end
612
 
613
                if (incHourL) begin
614
                        minH <= 4'h0;
615
                        hourL <= hourL + 4'h1;
616
                end
617
                if (incHourH) begin
618
                        hourL <= 4'h0;
619
                        hourH <= hourH + 4'h1;
620
                end
621
 
622
                // day increment
623
                // reset the entire time when the day increments
624
                // - the day may not be exactly 24 hours long
625
                if (incDayL) begin
626
                        dayL <= dayL + 4'h1;
627
                        jiffyL <= 4'h0;
628
                        jiffyH <= 4'h0;
629
                        secL <= 4'h0;
630
                        secH <= 4'h0;
631
                        minL <= 4'h0;
632
                        minH <= 4'h0;
633
                        hourL <= 4'h0;
634
                        hourH <= 4'h0;
635
                end
636
                if (incDayH) begin
637
                        dayL <= 4'h0;
638
                        dayH <= dayH + 4'h1;
639
                end
640
 
641
                if (incMonthL) begin
642
                        dayL <= 4'h1;
643
                        dayH <= 4'h0;
644
                        monthL <= monthL + 4'h1;
645
                end
646
                if (incMonthH) begin
647
                        monthL <= 4'h0;
648
                        monthH <= monthH + 4'h1;
649
                end
650
 
651
                if (incYearN0) begin
652
                        monthL <= 4'h1;
653
                        monthH <= 4'h0;
654
                end
655
                if (incYearN1) begin
656
                        yearN0 <= 4'h0;
657
                        yearN1 <= yearN1 + 4'h1;
658
                end
659
                if (incYearN2) begin
660
                        yearN1 <= 4'h0;
661
                        yearN2 <= yearN2 + 4'h1;
662
                end
663
                if (incYearN3) begin
664
                        yearN2 <= 4'h0;
665
                        yearN3 <= yearN3 + 4'h1;
666
                end
667
        end
668
end
669
 
670
endmodule
671
 

powered by: WebSVN 2.1.0

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