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

Subversion Repositories openmsp430

[/] [openmsp430/] [trunk/] [core/] [rtl/] [verilog/] [omsp_watchdog.v] - Blame information for rev 180

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

Line No. Rev Author Line
1 2 olivier.gi
//----------------------------------------------------------------------------
2 117 olivier.gi
// Copyright (C) 2009 , Olivier Girard
3 2 olivier.gi
//
4 117 olivier.gi
// Redistribution and use in source and binary forms, with or without
5
// modification, are permitted provided that the following conditions
6
// are met:
7
//     * Redistributions of source code must retain the above copyright
8
//       notice, this list of conditions and the following disclaimer.
9
//     * Redistributions in binary form must reproduce the above copyright
10
//       notice, this list of conditions and the following disclaimer in the
11
//       documentation and/or other materials provided with the distribution.
12
//     * Neither the name of the authors nor the names of its contributors
13
//       may be used to endorse or promote products derived from this software
14
//       without specific prior written permission.
15 2 olivier.gi
//
16 117 olivier.gi
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
17
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
20
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
21
// OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
26
// THE POSSIBILITY OF SUCH DAMAGE
27 2 olivier.gi
//
28
//----------------------------------------------------------------------------
29
//
30 34 olivier.gi
// *File Name: omsp_watchdog.v
31 2 olivier.gi
// 
32
// *Module Description:
33
//                       Watchdog Timer
34
//
35
// *Author(s):
36
//              - Olivier Girard,    olgirard@gmail.com
37
//
38
//----------------------------------------------------------------------------
39 17 olivier.gi
// $Rev: 180 $
40
// $LastChangedBy: olivier.girard $
41
// $LastChangedDate: 2013-02-25 22:23:18 +0100 (Mon, 25 Feb 2013) $
42
//----------------------------------------------------------------------------
43 103 olivier.gi
`ifdef OMSP_NO_INCLUDE
44
`else
45 23 olivier.gi
`include "openMSP430_defines.v"
46 103 olivier.gi
`endif
47 2 olivier.gi
 
48 34 olivier.gi
module  omsp_watchdog (
49 2 olivier.gi
 
50
// OUTPUTs
51
    per_dout,                       // Peripheral data output
52 134 olivier.gi
    wdt_irq,                        // Watchdog-timer interrupt
53
    wdt_reset,                      // Watchdog-timer reset
54
    wdt_wkup,                       // Watchdog Wakeup
55
    wdtifg,                         // Watchdog-timer interrupt flag
56
    wdtnmies,                       // Watchdog-timer NMI edge selection
57 2 olivier.gi
 
58
// INPUTs
59 134 olivier.gi
    aclk,                           // ACLK
60 2 olivier.gi
    aclk_en,                        // ACLK enable
61
    dbg_freeze,                     // Freeze Watchdog counter
62
    mclk,                           // Main system clock
63
    per_addr,                       // Peripheral address
64
    per_din,                        // Peripheral data input
65
    per_en,                         // Peripheral enable (high active)
66 106 olivier.gi
    per_we,                         // Peripheral write enable (high active)
67 134 olivier.gi
    por,                            // Power-on reset
68 111 olivier.gi
    puc_rst,                        // Main system reset
69 134 olivier.gi
    scan_enable,                    // Scan enable (active during scan shifting)
70
    scan_mode,                      // Scan mode
71
    smclk,                          // SMCLK
72 2 olivier.gi
    smclk_en,                       // SMCLK enable
73 134 olivier.gi
    wdtie,                          // Watchdog timer interrupt enable
74
    wdtifg_irq_clr,                 // Watchdog-timer interrupt flag irq accepted clear
75
    wdtifg_sw_clr,                  // Watchdog-timer interrupt flag software clear
76
    wdtifg_sw_set                   // Watchdog-timer interrupt flag software set
77 2 olivier.gi
);
78
 
79
// OUTPUTs
80
//=========
81
output       [15:0] per_dout;       // Peripheral data output
82 134 olivier.gi
output              wdt_irq;        // Watchdog-timer interrupt
83
output              wdt_reset;      // Watchdog-timer reset
84
output              wdt_wkup;       // Watchdog Wakeup
85
output              wdtifg;         // Watchdog-timer interrupt flag
86
output              wdtnmies;       // Watchdog-timer NMI edge selection
87 2 olivier.gi
 
88
// INPUTs
89
//=========
90 134 olivier.gi
input               aclk;           // ACLK
91 2 olivier.gi
input               aclk_en;        // ACLK enable
92
input               dbg_freeze;     // Freeze Watchdog counter
93
input               mclk;           // Main system clock
94 111 olivier.gi
input        [13:0] per_addr;       // Peripheral address
95 2 olivier.gi
input        [15:0] per_din;        // Peripheral data input
96
input               per_en;         // Peripheral enable (high active)
97 106 olivier.gi
input         [1:0] per_we;         // Peripheral write enable (high active)
98 134 olivier.gi
input               por;            // Power-on reset
99 111 olivier.gi
input               puc_rst;        // Main system reset
100 134 olivier.gi
input               scan_enable;    // Scan enable (active during scan shifting)
101
input               scan_mode;      // Scan mode
102
input               smclk;          // SMCLK
103 2 olivier.gi
input               smclk_en;       // SMCLK enable
104
input               wdtie;          // Watchdog timer interrupt enable
105 134 olivier.gi
input               wdtifg_irq_clr; // Clear Watchdog-timer interrupt flag
106
input               wdtifg_sw_clr;  // Watchdog-timer interrupt flag software clear
107
input               wdtifg_sw_set;  // Watchdog-timer interrupt flag software set
108 2 olivier.gi
 
109
 
110
//=============================================================================
111
// 1)  PARAMETER DECLARATION
112
//=============================================================================
113
 
114 111 olivier.gi
// Register base address (must be aligned to decoder bit width)
115
parameter       [14:0] BASE_ADDR   = 15'h0120;
116 2 olivier.gi
 
117 111 olivier.gi
// Decoder bit width (defines how many bits are considered for address decoding)
118
parameter              DEC_WD      =  2;
119 2 olivier.gi
 
120 111 olivier.gi
// Register addresses offset
121
parameter [DEC_WD-1:0] WDTCTL      = 'h0;
122
 
123
// Register one-hot decoder utilities
124 134 olivier.gi
parameter              DEC_SZ      =  (1 << DEC_WD);
125 111 olivier.gi
parameter [DEC_SZ-1:0] BASE_REG    =  {{DEC_SZ-1{1'b0}}, 1'b1};
126
 
127 2 olivier.gi
// Register one-hot decoder
128 111 olivier.gi
parameter [DEC_SZ-1:0] WDTCTL_D    = (BASE_REG << WDTCTL);
129 2 olivier.gi
 
130
 
131
//============================================================================
132
// 2)  REGISTER DECODER
133
//============================================================================
134
 
135 111 olivier.gi
// Local register selection
136
wire              reg_sel   =  per_en & (per_addr[13:DEC_WD-1]==BASE_ADDR[14:DEC_WD]);
137
 
138
// Register local address
139
wire [DEC_WD-1:0] reg_addr  =  {per_addr[DEC_WD-2:0], 1'b0};
140
 
141 2 olivier.gi
// Register address decode
142 111 olivier.gi
wire [DEC_SZ-1:0] reg_dec   =  (WDTCTL_D & {DEC_SZ{(reg_addr==WDTCTL)}});
143 2 olivier.gi
 
144
// Read/Write probes
145 111 olivier.gi
wire              reg_write =  |per_we & reg_sel;
146
wire              reg_read  = ~|per_we & reg_sel;
147 2 olivier.gi
 
148
// Read/Write vectors
149 111 olivier.gi
wire [DEC_SZ-1:0] reg_wr    = reg_dec & {DEC_SZ{reg_write}};
150
wire [DEC_SZ-1:0] reg_rd    = reg_dec & {DEC_SZ{reg_read}};
151 2 olivier.gi
 
152
 
153
//============================================================================
154
// 3) REGISTERS
155
//============================================================================
156
 
157
// WDTCTL Register
158
//-----------------
159 134 olivier.gi
// WDTNMI is not implemented and therefore masked
160 2 olivier.gi
 
161
reg  [7:0] wdtctl;
162
 
163
wire       wdtctl_wr = reg_wr[WDTCTL];
164
 
165 134 olivier.gi
`ifdef CLOCK_GATING
166
wire       mclk_wdtctl;
167
omsp_clock_gate clock_gate_wdtctl (.gclk(mclk_wdtctl),
168
                                   .clk (mclk), .enable(wdtctl_wr), .scan_enable(scan_enable));
169
`else
170
wire       mclk_wdtctl = mclk;
171
`endif
172
 
173
`ifdef NMI
174
parameter [7:0] WDTNMIES_MASK = 8'h40;
175
`else
176
parameter [7:0] WDTNMIES_MASK = 8'h00;
177
`endif
178
 
179 180 olivier.gi
`ifdef ASIC_CLOCKING
180 134 olivier.gi
  `ifdef WATCHDOG_MUX
181
parameter [7:0] WDTSSEL_MASK  = 8'h04;
182
  `else
183
parameter [7:0] WDTSSEL_MASK  = 8'h00;
184
  `endif
185
`else
186
parameter [7:0] WDTSSEL_MASK  = 8'h04;
187
`endif
188
 
189
parameter [7:0] WDTCTL_MASK   = (8'b1001_0011 | WDTSSEL_MASK | WDTNMIES_MASK);
190
 
191
always @ (posedge mclk_wdtctl or posedge puc_rst)
192 111 olivier.gi
  if (puc_rst)        wdtctl <=  8'h00;
193 134 olivier.gi
`ifdef CLOCK_GATING
194
  else                wdtctl <=  per_din[7:0] & WDTCTL_MASK;
195
`else
196
  else if (wdtctl_wr) wdtctl <=  per_din[7:0] & WDTCTL_MASK;
197
`endif
198 2 olivier.gi
 
199
wire       wdtpw_error = wdtctl_wr & (per_din[15:8]!=8'h5a);
200
wire       wdttmsel    = wdtctl[4];
201 134 olivier.gi
wire       wdtnmies    = wdtctl[6];
202 2 olivier.gi
 
203
 
204
//============================================================================
205 134 olivier.gi
// 4) DATA OUTPUT GENERATION
206 2 olivier.gi
//============================================================================
207
 
208 134 olivier.gi
`ifdef NMI
209
parameter [7:0] WDTNMI_RD_MASK  = 8'h20;
210
`else
211
parameter [7:0] WDTNMI_RD_MASK  = 8'h00;
212
`endif
213
`ifdef WATCHDOG_MUX
214
parameter [7:0] WDTSSEL_RD_MASK = 8'h00;
215
`else
216
  `ifdef WATCHDOG_NOMUX_ACLK
217
parameter [7:0] WDTSSEL_RD_MASK = 8'h04;
218
  `else
219
parameter [7:0] WDTSSEL_RD_MASK = 8'h00;
220
  `endif
221
`endif
222
parameter [7:0] WDTCTL_RD_MASK  = WDTNMI_RD_MASK | WDTSSEL_RD_MASK;
223
 
224 2 olivier.gi
// Data output mux
225 134 olivier.gi
wire [15:0] wdtctl_rd  = {8'h69, wdtctl | WDTCTL_RD_MASK} & {16{reg_rd[WDTCTL]}};
226 2 olivier.gi
wire [15:0] per_dout   =  wdtctl_rd;
227
 
228
 
229
//=============================================================================
230 134 olivier.gi
// 5)  WATCHDOG TIMER (ASIC IMPLEMENTATION)
231 2 olivier.gi
//=============================================================================
232 180 olivier.gi
`ifdef ASIC_CLOCKING
233 2 olivier.gi
 
234 134 olivier.gi
// Watchdog clock source selection
235
//---------------------------------
236
wire wdt_clk;
237
 
238
`ifdef WATCHDOG_MUX
239
omsp_clock_mux clock_mux_watchdog (
240
   .clk_out   (wdt_clk),
241
   .clk_in0   (smclk),
242
   .clk_in1   (aclk),
243
   .reset     (puc_rst),
244
   .scan_mode (scan_mode),
245
   .select    (wdtctl[2])
246 111 olivier.gi
);
247
`else
248 134 olivier.gi
  `ifdef WATCHDOG_NOMUX_ACLK
249
     assign wdt_clk =  aclk;
250
  `else
251
     assign wdt_clk =  smclk;
252
  `endif
253 111 olivier.gi
`endif
254 134 olivier.gi
 
255
// Reset synchronizer for the watchdog local clock domain
256
//--------------------------------------------------------
257 111 olivier.gi
 
258 134 olivier.gi
wire wdt_rst_noscan;
259
wire wdt_rst;
260
 
261
// Reset Synchronizer
262
omsp_sync_reset sync_reset_por (
263
    .rst_s        (wdt_rst_noscan),
264
    .clk          (wdt_clk),
265
    .rst_a        (puc_rst)
266
);
267
 
268
// Scan Reset Mux
269
omsp_scan_mux scan_mux_wdt_rst (
270
    .scan_mode    (scan_mode),
271
    .data_in_scan (puc_rst),
272
    .data_in_func (wdt_rst_noscan),
273
    .data_out     (wdt_rst)
274
);
275
 
276
 
277
// Watchog counter clear (synchronization)
278
//-----------------------------------------
279
 
280
// Toggle bit whenever the watchog needs to be cleared
281
reg        wdtcnt_clr_toggle;
282
wire       wdtcnt_clr_detect = (wdtctl_wr & per_din[3]);
283 111 olivier.gi
always @ (posedge mclk or posedge puc_rst)
284 134 olivier.gi
  if (puc_rst)                wdtcnt_clr_toggle <= 1'b0;
285
  else if (wdtcnt_clr_detect) wdtcnt_clr_toggle <= ~wdtcnt_clr_toggle;
286 2 olivier.gi
 
287 134 olivier.gi
// Synchronization
288
wire wdtcnt_clr_sync;
289
omsp_sync_cell sync_cell_wdtcnt_clr (
290
    .data_out  (wdtcnt_clr_sync),
291
    .data_in   (wdtcnt_clr_toggle),
292
    .clk       (wdt_clk),
293
    .rst       (wdt_rst)
294
);
295
 
296 2 olivier.gi
// Edge detection
297 134 olivier.gi
reg wdtcnt_clr_sync_dly;
298
always @ (posedge wdt_clk or posedge wdt_rst)
299
  if (wdt_rst)  wdtcnt_clr_sync_dly <= 1'b0;
300
  else          wdtcnt_clr_sync_dly <= wdtcnt_clr_sync;
301 2 olivier.gi
 
302 134 olivier.gi
wire wdtqn_edge;
303
wire wdtcnt_clr = (wdtcnt_clr_sync ^ wdtcnt_clr_sync_dly) | wdtqn_edge;
304 2 olivier.gi
 
305
 
306 134 olivier.gi
// Watchog counter increment (synchronization)
307
//----------------------------------------------
308
wire wdtcnt_incr;
309
 
310
omsp_sync_cell sync_cell_wdtcnt_incr (
311
    .data_out  (wdtcnt_incr),
312
    .data_in   (~wdtctl[7] & ~dbg_freeze),
313
    .clk       (wdt_clk),
314
    .rst       (wdt_rst)
315
);
316
 
317
 
318
// Watchdog 16 bit counter
319
//--------------------------
320
reg  [15:0] wdtcnt;
321
 
322
wire [15:0] wdtcnt_nxt  = wdtcnt+16'h0001;
323
 
324
`ifdef CLOCK_GATING
325
wire       wdtcnt_en   = wdtcnt_clr | wdtcnt_incr;
326
wire       wdt_clk_cnt;
327
omsp_clock_gate clock_gate_wdtcnt (.gclk(wdt_clk_cnt),
328
                                   .clk (wdt_clk), .enable(wdtcnt_en), .scan_enable(scan_enable));
329
`else
330
wire       wdt_clk_cnt = wdt_clk;
331
`endif
332
 
333
always @ (posedge wdt_clk_cnt or posedge wdt_rst)
334
  if (wdt_rst)           wdtcnt <= 16'h0000;
335
  else if (wdtcnt_clr)   wdtcnt <= 16'h0000;
336
`ifdef CLOCK_GATING
337
  else                   wdtcnt <= wdtcnt_nxt;
338
`else
339
  else if (wdtcnt_incr)  wdtcnt <= wdtcnt_nxt;
340
`endif
341
 
342
 
343
// Local synchronizer for the wdtctl.WDTISx
344
// configuration (note that we can live with
345
// a full bus synchronizer as it won't hurt
346
// if we get a wrong WDTISx value for a
347
// single clock cycle)
348
//--------------------------------------------
349
reg [1:0] wdtisx_s;
350
reg [1:0] wdtisx_ss;
351
always @ (posedge wdt_clk_cnt or posedge wdt_rst)
352
  if (wdt_rst)
353
    begin
354
       wdtisx_s  <=  2'h0;
355
       wdtisx_ss <=  2'h0;
356
    end
357
  else
358
    begin
359
       wdtisx_s  <=  wdtctl[1:0];
360
       wdtisx_ss <=  wdtisx_s;
361
    end
362
 
363
 
364
// Interval selection mux
365
//--------------------------
366
reg        wdtqn;
367
 
368
always @(wdtisx_ss or wdtcnt_nxt)
369
    case(wdtisx_ss)
370
      2'b00  : wdtqn =  wdtcnt_nxt[15];
371
      2'b01  : wdtqn =  wdtcnt_nxt[13];
372
      2'b10  : wdtqn =  wdtcnt_nxt[9];
373
      default: wdtqn =  wdtcnt_nxt[6];
374
    endcase
375
 
376
 
377
// Watchdog event detection
378
//-----------------------------
379
 
380
// Interval end detection
381
assign     wdtqn_edge =  (wdtqn & wdtcnt_incr);
382
 
383
// Toggle bit for the transmition to the MCLK domain
384
reg        wdt_evt_toggle;
385
always @ (posedge wdt_clk_cnt or posedge wdt_rst)
386
  if (wdt_rst)         wdt_evt_toggle <= 1'b0;
387
  else if (wdtqn_edge) wdt_evt_toggle <= ~wdt_evt_toggle;
388
 
389
// Synchronize in the MCLK domain
390
wire       wdt_evt_toggle_sync;
391
omsp_sync_cell sync_cell_wdt_evt (
392
    .data_out  (wdt_evt_toggle_sync),
393
    .data_in   (wdt_evt_toggle),
394
    .clk       (mclk),
395
    .rst       (puc_rst)
396
);
397
 
398
// Delay for edge detection of the toggle bit
399
reg        wdt_evt_toggle_sync_dly;
400
always @ (posedge mclk or posedge puc_rst)
401
  if (puc_rst) wdt_evt_toggle_sync_dly <= 1'b0;
402
  else         wdt_evt_toggle_sync_dly <= wdt_evt_toggle_sync;
403
 
404
wire       wdtifg_evt =  (wdt_evt_toggle_sync_dly ^ wdt_evt_toggle_sync) | wdtpw_error;
405
 
406
 
407
// Watchdog wakeup generation
408
//-------------------------------------------------------------
409
 
410
// Clear wakeup when the watchdog flag is cleared (glitch free)
411
reg  wdtifg_clr_reg;
412
wire wdtifg_clr;
413
always @ (posedge mclk or posedge puc_rst)
414
  if (puc_rst) wdtifg_clr_reg <= 1'b1;
415
  else         wdtifg_clr_reg <= wdtifg_clr;
416
 
417
// Set wakeup when the watchdog event is detected (glitch free)
418
reg  wdtqn_edge_reg;
419
always @ (posedge wdt_clk_cnt or posedge wdt_rst)
420
  if (wdt_rst) wdtqn_edge_reg <= 1'b0;
421
  else         wdtqn_edge_reg <= wdtqn_edge;
422
 
423
// Watchdog wakeup cell
424
wire wdt_wkup_pre;
425
omsp_wakeup_cell wakeup_cell_wdog (
426
                                   .wkup_out   (wdt_wkup_pre),    // Wakup signal (asynchronous)
427
                                   .scan_clk   (mclk),            // Scan clock
428
                                   .scan_mode  (scan_mode),       // Scan mode
429
                                   .scan_rst   (puc_rst),         // Scan reset
430
                                   .wkup_clear (wdtifg_clr_reg),  // Glitch free wakeup event clear
431
                                   .wkup_event (wdtqn_edge_reg)   // Glitch free asynchronous wakeup event
432
);
433
 
434
// When not in HOLD, the watchdog can generate a wakeup when:
435
//     - in interval mode (if interrupts are enabled)
436
//     - in reset mode (always)
437
reg  wdt_wkup_en;
438
always @ (posedge mclk or posedge puc_rst)
439
  if (puc_rst) wdt_wkup_en <= 1'b0;
440
  else         wdt_wkup_en <= ~wdtctl[7] & (~wdttmsel | (wdttmsel & wdtie));
441
 
442
// Make wakeup when not enabled
443
wire wdt_wkup;
444
omsp_and_gate and_wdt_wkup (.y(wdt_wkup), .a(wdt_wkup_pre), .b(wdt_wkup_en));
445
 
446
 
447
// Watchdog interrupt flag
448
//------------------------------
449
reg        wdtifg;
450
 
451
wire       wdtifg_set =  wdtifg_evt                  |  wdtifg_sw_set;
452
assign     wdtifg_clr =  (wdtifg_irq_clr & wdttmsel) |  wdtifg_sw_clr;
453
 
454
always @ (posedge mclk or posedge por)
455
  if (por)             wdtifg <=  1'b0;
456
  else if (wdtifg_set) wdtifg <=  1'b1;
457
  else if (wdtifg_clr) wdtifg <=  1'b0;
458
 
459
 
460
// Watchdog interrupt generation
461
//---------------------------------
462
wire    wdt_irq       = wdttmsel & wdtifg & wdtie;
463
 
464
 
465
// Watchdog reset generation
466
//-----------------------------
467
reg     wdt_reset;
468
 
469
always @ (posedge mclk or posedge por)
470
  if (por) wdt_reset <= 1'b0;
471
  else     wdt_reset <= wdtpw_error | (wdtifg_set & ~wdttmsel);
472
 
473
 
474
 
475 2 olivier.gi
//=============================================================================
476 134 olivier.gi
// 6)  WATCHDOG TIMER (FPGA IMPLEMENTATION)
477 2 olivier.gi
//=============================================================================
478 134 olivier.gi
`else
479 2 olivier.gi
 
480
// Watchdog clock source selection
481
//---------------------------------
482
wire  clk_src_en = wdtctl[2] ? aclk_en : smclk_en;
483
 
484
 
485
// Watchdog 16 bit counter
486
//--------------------------
487
reg [15:0] wdtcnt;
488
 
489 134 olivier.gi
wire        wdtifg_evt;
490
wire        wdtcnt_clr  = (wdtctl_wr & per_din[3]) | wdtifg_evt;
491
wire        wdtcnt_incr = ~wdtctl[7] & clk_src_en & ~dbg_freeze;
492 2 olivier.gi
 
493 134 olivier.gi
wire [15:0] wdtcnt_nxt  = wdtcnt+16'h0001;
494
 
495 111 olivier.gi
always @ (posedge mclk or posedge puc_rst)
496 134 olivier.gi
  if (puc_rst)           wdtcnt <= 16'h0000;
497
  else if (wdtcnt_clr)   wdtcnt <= 16'h0000;
498
  else if (wdtcnt_incr)  wdtcnt <= wdtcnt_nxt;
499 2 olivier.gi
 
500
 
501
// Interval selection mux
502
//--------------------------
503
reg        wdtqn;
504
 
505 134 olivier.gi
always @(wdtctl or wdtcnt_nxt)
506 2 olivier.gi
    case(wdtctl[1:0])
507 134 olivier.gi
      2'b00  : wdtqn =  wdtcnt_nxt[15];
508
      2'b01  : wdtqn =  wdtcnt_nxt[13];
509
      2'b10  : wdtqn =  wdtcnt_nxt[9];
510
      default: wdtqn =  wdtcnt_nxt[6];
511 2 olivier.gi
    endcase
512
 
513
 
514
// Watchdog event detection
515
//-----------------------------
516
 
517 134 olivier.gi
assign     wdtifg_evt =  (wdtqn & wdtcnt_incr) | wdtpw_error;
518 2 olivier.gi
 
519
 
520 134 olivier.gi
// Watchdog interrupt flag
521
//------------------------------
522
reg        wdtifg;
523 2 olivier.gi
 
524 134 olivier.gi
wire       wdtifg_set =  wdtifg_evt                  |  wdtifg_sw_set;
525
wire       wdtifg_clr =  (wdtifg_irq_clr & wdttmsel) |  wdtifg_sw_clr;
526
 
527
always @ (posedge mclk or posedge por)
528
  if (por)             wdtifg <=  1'b0;
529
  else if (wdtifg_set) wdtifg <=  1'b1;
530
  else if (wdtifg_clr) wdtifg <=  1'b0;
531
 
532
 
533
// Watchdog interrupt generation
534
//---------------------------------
535
wire    wdt_irq       = wdttmsel & wdtifg & wdtie;
536
wire    wdt_wkup      =  1'b0;
537
 
538
 
539
// Watchdog reset generation
540
//-----------------------------
541
reg     wdt_reset;
542
 
543
always @ (posedge mclk or posedge por)
544
  if (por) wdt_reset <= 1'b0;
545
  else     wdt_reset <= wdtpw_error | (wdtifg_set & ~wdttmsel);
546
 
547
 
548
`endif
549
 
550
 
551 34 olivier.gi
endmodule // omsp_watchdog
552 2 olivier.gi
 
553 103 olivier.gi
`ifdef OMSP_NO_INCLUDE
554
`else
555 33 olivier.gi
`include "openMSP430_undefines.v"
556 103 olivier.gi
`endif

powered by: WebSVN 2.1.0

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