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

Subversion Repositories openmsp430

[/] [openmsp430/] [trunk/] [fpga/] [actel_m1a3pl_dev_kit/] [rtl/] [verilog/] [openmsp430/] [omsp_watchdog.v] - Blame information for rev 218

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

Line No. Rev Author Line
1 80 olivier.gi
//----------------------------------------------------------------------------
2 136 olivier.gi
// Copyright (C) 2009 , Olivier Girard
3 80 olivier.gi
//
4 136 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 80 olivier.gi
//
16 136 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 80 olivier.gi
//
28
//----------------------------------------------------------------------------
29
//
30
// *File Name: omsp_watchdog.v
31 202 olivier.gi
//
32 80 olivier.gi
// *Module Description:
33
//                       Watchdog Timer
34
//
35
// *Author(s):
36
//              - Olivier Girard,    olgirard@gmail.com
37
//
38
//----------------------------------------------------------------------------
39 202 olivier.gi
// $Rev$
40
// $LastChangedBy$
41
// $LastChangedDate$
42 80 olivier.gi
//----------------------------------------------------------------------------
43 104 olivier.gi
`ifdef OMSP_NO_INCLUDE
44
`else
45 80 olivier.gi
`include "openMSP430_defines.v"
46 104 olivier.gi
`endif
47 80 olivier.gi
 
48
module  omsp_watchdog (
49
 
50
// OUTPUTs
51
    per_dout,                       // Peripheral data output
52 136 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 80 olivier.gi
 
58
// INPUTs
59 136 olivier.gi
    aclk,                           // ACLK
60 80 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 107 olivier.gi
    per_we,                         // Peripheral write enable (high active)
67 136 olivier.gi
    por,                            // Power-on reset
68 111 olivier.gi
    puc_rst,                        // Main system reset
69 136 olivier.gi
    scan_enable,                    // Scan enable (active during scan shifting)
70
    scan_mode,                      // Scan mode
71
    smclk,                          // SMCLK
72 80 olivier.gi
    smclk_en,                       // SMCLK enable
73 136 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 80 olivier.gi
);
78
 
79
// OUTPUTs
80
//=========
81
output       [15:0] per_dout;       // Peripheral data output
82 136 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 80 olivier.gi
 
88
// INPUTs
89
//=========
90 136 olivier.gi
input               aclk;           // ACLK
91 80 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 80 olivier.gi
input        [15:0] per_din;        // Peripheral data input
96
input               per_en;         // Peripheral enable (high active)
97 107 olivier.gi
input         [1:0] per_we;         // Peripheral write enable (high active)
98 136 olivier.gi
input               por;            // Power-on reset
99 111 olivier.gi
input               puc_rst;        // Main system reset
100 136 olivier.gi
input               scan_enable;    // Scan enable (active during scan shifting)
101
input               scan_mode;      // Scan mode
102
input               smclk;          // SMCLK
103 80 olivier.gi
input               smclk_en;       // SMCLK enable
104
input               wdtie;          // Watchdog timer interrupt enable
105 136 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 80 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 80 olivier.gi
 
117 111 olivier.gi
// Decoder bit width (defines how many bits are considered for address decoding)
118
parameter              DEC_WD      =  2;
119 80 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 136 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 80 olivier.gi
// Register one-hot decoder
128 111 olivier.gi
parameter [DEC_SZ-1:0] WDTCTL_D    = (BASE_REG << WDTCTL);
129 80 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 80 olivier.gi
// Register address decode
142 111 olivier.gi
wire [DEC_SZ-1:0] reg_dec   =  (WDTCTL_D & {DEC_SZ{(reg_addr==WDTCTL)}});
143 80 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 80 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 80 olivier.gi
 
152
 
153
//============================================================================
154
// 3) REGISTERS
155
//============================================================================
156
 
157
// WDTCTL Register
158
//-----------------
159 136 olivier.gi
// WDTNMI is not implemented and therefore masked
160 202 olivier.gi
 
161 80 olivier.gi
reg  [7:0] wdtctl;
162
 
163
wire       wdtctl_wr = reg_wr[WDTCTL];
164
 
165 136 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 202 olivier.gi
wire       UNUSED_scan_enable = scan_enable;
171
wire       mclk_wdtctl        = mclk;
172 136 olivier.gi
`endif
173
 
174
`ifdef NMI
175
parameter [7:0] WDTNMIES_MASK = 8'h40;
176
`else
177
parameter [7:0] WDTNMIES_MASK = 8'h00;
178
`endif
179
 
180 181 olivier.gi
`ifdef ASIC_CLOCKING
181 136 olivier.gi
  `ifdef WATCHDOG_MUX
182
parameter [7:0] WDTSSEL_MASK  = 8'h04;
183
  `else
184
parameter [7:0] WDTSSEL_MASK  = 8'h00;
185
  `endif
186
`else
187
parameter [7:0] WDTSSEL_MASK  = 8'h04;
188
`endif
189
 
190
parameter [7:0] WDTCTL_MASK   = (8'b1001_0011 | WDTSSEL_MASK | WDTNMIES_MASK);
191 202 olivier.gi
 
192 136 olivier.gi
always @ (posedge mclk_wdtctl or posedge puc_rst)
193 111 olivier.gi
  if (puc_rst)        wdtctl <=  8'h00;
194 136 olivier.gi
`ifdef CLOCK_GATING
195
  else                wdtctl <=  per_din[7:0] & WDTCTL_MASK;
196
`else
197
  else if (wdtctl_wr) wdtctl <=  per_din[7:0] & WDTCTL_MASK;
198
`endif
199 80 olivier.gi
 
200
wire       wdtpw_error = wdtctl_wr & (per_din[15:8]!=8'h5a);
201
wire       wdttmsel    = wdtctl[4];
202 136 olivier.gi
wire       wdtnmies    = wdtctl[6];
203 80 olivier.gi
 
204
 
205
//============================================================================
206 136 olivier.gi
// 4) DATA OUTPUT GENERATION
207 80 olivier.gi
//============================================================================
208
 
209 136 olivier.gi
`ifdef NMI
210
parameter [7:0] WDTNMI_RD_MASK  = 8'h20;
211
`else
212
parameter [7:0] WDTNMI_RD_MASK  = 8'h00;
213
`endif
214
`ifdef WATCHDOG_MUX
215
parameter [7:0] WDTSSEL_RD_MASK = 8'h00;
216
`else
217
  `ifdef WATCHDOG_NOMUX_ACLK
218
parameter [7:0] WDTSSEL_RD_MASK = 8'h04;
219
  `else
220
parameter [7:0] WDTSSEL_RD_MASK = 8'h00;
221
  `endif
222
`endif
223
parameter [7:0] WDTCTL_RD_MASK  = WDTNMI_RD_MASK | WDTSSEL_RD_MASK;
224
 
225 80 olivier.gi
// Data output mux
226 136 olivier.gi
wire [15:0] wdtctl_rd  = {8'h69, wdtctl | WDTCTL_RD_MASK} & {16{reg_rd[WDTCTL]}};
227 80 olivier.gi
wire [15:0] per_dout   =  wdtctl_rd;
228
 
229
 
230
//=============================================================================
231 136 olivier.gi
// 5)  WATCHDOG TIMER (ASIC IMPLEMENTATION)
232 80 olivier.gi
//=============================================================================
233 181 olivier.gi
`ifdef ASIC_CLOCKING
234 80 olivier.gi
 
235 136 olivier.gi
// Watchdog clock source selection
236
//---------------------------------
237
wire wdt_clk;
238
 
239
`ifdef WATCHDOG_MUX
240
omsp_clock_mux clock_mux_watchdog (
241
   .clk_out   (wdt_clk),
242
   .clk_in0   (smclk),
243
   .clk_in1   (aclk),
244
   .reset     (puc_rst),
245
   .scan_mode (scan_mode),
246 202 olivier.gi
   .select_in (wdtctl[2])
247 111 olivier.gi
);
248
`else
249 136 olivier.gi
  `ifdef WATCHDOG_NOMUX_ACLK
250 202 olivier.gi
     assign wdt_clk      = aclk;
251
     wire   UNUSED_smclk = smclk;
252 136 olivier.gi
  `else
253 202 olivier.gi
     wire   UNUSED_aclk  = aclk;
254
     assign wdt_clk      = smclk;
255 136 olivier.gi
  `endif
256 111 olivier.gi
`endif
257 136 olivier.gi
 
258
// Reset synchronizer for the watchdog local clock domain
259
//--------------------------------------------------------
260 202 olivier.gi
 
261 136 olivier.gi
wire wdt_rst_noscan;
262
wire wdt_rst;
263
 
264
// Reset Synchronizer
265
omsp_sync_reset sync_reset_por (
266
    .rst_s        (wdt_rst_noscan),
267
    .clk          (wdt_clk),
268
    .rst_a        (puc_rst)
269
);
270
 
271
// Scan Reset Mux
272
omsp_scan_mux scan_mux_wdt_rst (
273
    .scan_mode    (scan_mode),
274
    .data_in_scan (puc_rst),
275
    .data_in_func (wdt_rst_noscan),
276
    .data_out     (wdt_rst)
277
);
278
 
279 202 olivier.gi
 
280 136 olivier.gi
// Watchog counter clear (synchronization)
281
//-----------------------------------------
282
 
283
// Toggle bit whenever the watchog needs to be cleared
284
reg        wdtcnt_clr_toggle;
285
wire       wdtcnt_clr_detect = (wdtctl_wr & per_din[3]);
286 111 olivier.gi
always @ (posedge mclk or posedge puc_rst)
287 136 olivier.gi
  if (puc_rst)                wdtcnt_clr_toggle <= 1'b0;
288
  else if (wdtcnt_clr_detect) wdtcnt_clr_toggle <= ~wdtcnt_clr_toggle;
289 80 olivier.gi
 
290 136 olivier.gi
// Synchronization
291
wire wdtcnt_clr_sync;
292
omsp_sync_cell sync_cell_wdtcnt_clr (
293
    .data_out  (wdtcnt_clr_sync),
294
    .data_in   (wdtcnt_clr_toggle),
295
    .clk       (wdt_clk),
296
    .rst       (wdt_rst)
297
);
298
 
299 80 olivier.gi
// Edge detection
300 136 olivier.gi
reg wdtcnt_clr_sync_dly;
301
always @ (posedge wdt_clk or posedge wdt_rst)
302
  if (wdt_rst)  wdtcnt_clr_sync_dly <= 1'b0;
303
  else          wdtcnt_clr_sync_dly <= wdtcnt_clr_sync;
304 80 olivier.gi
 
305 136 olivier.gi
wire wdtqn_edge;
306
wire wdtcnt_clr = (wdtcnt_clr_sync ^ wdtcnt_clr_sync_dly) | wdtqn_edge;
307 80 olivier.gi
 
308
 
309 136 olivier.gi
// Watchog counter increment (synchronization)
310
//----------------------------------------------
311
wire wdtcnt_incr;
312
 
313
omsp_sync_cell sync_cell_wdtcnt_incr (
314
    .data_out  (wdtcnt_incr),
315
    .data_in   (~wdtctl[7] & ~dbg_freeze),
316
    .clk       (wdt_clk),
317
    .rst       (wdt_rst)
318
);
319
 
320
 
321
// Watchdog 16 bit counter
322
//--------------------------
323
reg  [15:0] wdtcnt;
324
 
325
wire [15:0] wdtcnt_nxt  = wdtcnt+16'h0001;
326
 
327
`ifdef CLOCK_GATING
328
wire       wdtcnt_en   = wdtcnt_clr | wdtcnt_incr;
329
wire       wdt_clk_cnt;
330
omsp_clock_gate clock_gate_wdtcnt (.gclk(wdt_clk_cnt),
331
                                   .clk (wdt_clk), .enable(wdtcnt_en), .scan_enable(scan_enable));
332
`else
333
wire       wdt_clk_cnt = wdt_clk;
334
`endif
335
 
336
always @ (posedge wdt_clk_cnt or posedge wdt_rst)
337
  if (wdt_rst)           wdtcnt <= 16'h0000;
338
  else if (wdtcnt_clr)   wdtcnt <= 16'h0000;
339
`ifdef CLOCK_GATING
340
  else                   wdtcnt <= wdtcnt_nxt;
341
`else
342
  else if (wdtcnt_incr)  wdtcnt <= wdtcnt_nxt;
343
`endif
344
 
345
 
346
// Local synchronizer for the wdtctl.WDTISx
347
// configuration (note that we can live with
348
// a full bus synchronizer as it won't hurt
349
// if we get a wrong WDTISx value for a
350
// single clock cycle)
351
//--------------------------------------------
352
reg [1:0] wdtisx_s;
353
reg [1:0] wdtisx_ss;
354
always @ (posedge wdt_clk_cnt or posedge wdt_rst)
355
  if (wdt_rst)
356
    begin
357
       wdtisx_s  <=  2'h0;
358
       wdtisx_ss <=  2'h0;
359
    end
360
  else
361
    begin
362
       wdtisx_s  <=  wdtctl[1:0];
363
       wdtisx_ss <=  wdtisx_s;
364
    end
365
 
366
 
367
// Interval selection mux
368
//--------------------------
369
reg        wdtqn;
370
 
371
always @(wdtisx_ss or wdtcnt_nxt)
372
    case(wdtisx_ss)
373
      2'b00  : wdtqn =  wdtcnt_nxt[15];
374
      2'b01  : wdtqn =  wdtcnt_nxt[13];
375
      2'b10  : wdtqn =  wdtcnt_nxt[9];
376
      default: wdtqn =  wdtcnt_nxt[6];
377
    endcase
378
 
379
 
380
// Watchdog event detection
381
//-----------------------------
382
 
383
// Interval end detection
384
assign     wdtqn_edge =  (wdtqn & wdtcnt_incr);
385
 
386
// Toggle bit for the transmition to the MCLK domain
387
reg        wdt_evt_toggle;
388
always @ (posedge wdt_clk_cnt or posedge wdt_rst)
389
  if (wdt_rst)         wdt_evt_toggle <= 1'b0;
390
  else if (wdtqn_edge) wdt_evt_toggle <= ~wdt_evt_toggle;
391
 
392
// Synchronize in the MCLK domain
393
wire       wdt_evt_toggle_sync;
394
omsp_sync_cell sync_cell_wdt_evt (
395
    .data_out  (wdt_evt_toggle_sync),
396
    .data_in   (wdt_evt_toggle),
397
    .clk       (mclk),
398
    .rst       (puc_rst)
399
);
400
 
401
// Delay for edge detection of the toggle bit
402
reg        wdt_evt_toggle_sync_dly;
403
always @ (posedge mclk or posedge puc_rst)
404
  if (puc_rst) wdt_evt_toggle_sync_dly <= 1'b0;
405
  else         wdt_evt_toggle_sync_dly <= wdt_evt_toggle_sync;
406
 
407
wire       wdtifg_evt =  (wdt_evt_toggle_sync_dly ^ wdt_evt_toggle_sync) | wdtpw_error;
408
 
409
 
410
// Watchdog wakeup generation
411
//-------------------------------------------------------------
412
 
413
// Clear wakeup when the watchdog flag is cleared (glitch free)
414
reg  wdtifg_clr_reg;
415
wire wdtifg_clr;
416
always @ (posedge mclk or posedge puc_rst)
417
  if (puc_rst) wdtifg_clr_reg <= 1'b1;
418
  else         wdtifg_clr_reg <= wdtifg_clr;
419
 
420
// Set wakeup when the watchdog event is detected (glitch free)
421
reg  wdtqn_edge_reg;
422
always @ (posedge wdt_clk_cnt or posedge wdt_rst)
423
  if (wdt_rst) wdtqn_edge_reg <= 1'b0;
424
  else         wdtqn_edge_reg <= wdtqn_edge;
425
 
426
// Watchdog wakeup cell
427
wire wdt_wkup_pre;
428
omsp_wakeup_cell wakeup_cell_wdog (
429 202 olivier.gi
                                   .wkup_out   (wdt_wkup_pre),    // Wakup signal (asynchronous)
430
                                   .scan_clk   (mclk),            // Scan clock
431
                                   .scan_mode  (scan_mode),       // Scan mode
432
                                   .scan_rst   (puc_rst),         // Scan reset
433
                                   .wkup_clear (wdtifg_clr_reg),  // Glitch free wakeup event clear
434
                                   .wkup_event (wdtqn_edge_reg)   // Glitch free asynchronous wakeup event
435 136 olivier.gi
);
436
 
437
// When not in HOLD, the watchdog can generate a wakeup when:
438
//     - in interval mode (if interrupts are enabled)
439
//     - in reset mode (always)
440
reg  wdt_wkup_en;
441
always @ (posedge mclk or posedge puc_rst)
442
  if (puc_rst) wdt_wkup_en <= 1'b0;
443
  else         wdt_wkup_en <= ~wdtctl[7] & (~wdttmsel | (wdttmsel & wdtie));
444
 
445
// Make wakeup when not enabled
446
wire wdt_wkup;
447
omsp_and_gate and_wdt_wkup (.y(wdt_wkup), .a(wdt_wkup_pre), .b(wdt_wkup_en));
448
 
449
 
450
// Watchdog interrupt flag
451
//------------------------------
452
reg        wdtifg;
453
 
454
wire       wdtifg_set =  wdtifg_evt                  |  wdtifg_sw_set;
455
assign     wdtifg_clr =  (wdtifg_irq_clr & wdttmsel) |  wdtifg_sw_clr;
456
 
457
always @ (posedge mclk or posedge por)
458
  if (por)             wdtifg <=  1'b0;
459
  else if (wdtifg_set) wdtifg <=  1'b1;
460
  else if (wdtifg_clr) wdtifg <=  1'b0;
461
 
462
 
463
// Watchdog interrupt generation
464
//---------------------------------
465
wire    wdt_irq       = wdttmsel & wdtifg & wdtie;
466
 
467
 
468
// Watchdog reset generation
469
//-----------------------------
470
reg     wdt_reset;
471
 
472
always @ (posedge mclk or posedge por)
473
  if (por) wdt_reset <= 1'b0;
474
  else     wdt_reset <= wdtpw_error | (wdtifg_set & ~wdttmsel);
475
 
476
 
477 202 olivier.gi
// LINT cleanup
478
wire        UNUSED_smclk_en = smclk_en;
479
wire        UNUSED_aclk_en  = aclk_en;
480 136 olivier.gi
 
481 202 olivier.gi
 
482 80 olivier.gi
//=============================================================================
483 136 olivier.gi
// 6)  WATCHDOG TIMER (FPGA IMPLEMENTATION)
484 80 olivier.gi
//=============================================================================
485 136 olivier.gi
`else
486 80 olivier.gi
 
487
// Watchdog clock source selection
488
//---------------------------------
489
wire  clk_src_en = wdtctl[2] ? aclk_en : smclk_en;
490
 
491
 
492
// Watchdog 16 bit counter
493
//--------------------------
494
reg [15:0] wdtcnt;
495
 
496 136 olivier.gi
wire        wdtifg_evt;
497
wire        wdtcnt_clr  = (wdtctl_wr & per_din[3]) | wdtifg_evt;
498
wire        wdtcnt_incr = ~wdtctl[7] & clk_src_en & ~dbg_freeze;
499 80 olivier.gi
 
500 136 olivier.gi
wire [15:0] wdtcnt_nxt  = wdtcnt+16'h0001;
501
 
502 111 olivier.gi
always @ (posedge mclk or posedge puc_rst)
503 136 olivier.gi
  if (puc_rst)           wdtcnt <= 16'h0000;
504
  else if (wdtcnt_clr)   wdtcnt <= 16'h0000;
505
  else if (wdtcnt_incr)  wdtcnt <= wdtcnt_nxt;
506 80 olivier.gi
 
507 202 olivier.gi
 
508 80 olivier.gi
// Interval selection mux
509
//--------------------------
510
reg        wdtqn;
511
 
512 136 olivier.gi
always @(wdtctl or wdtcnt_nxt)
513 80 olivier.gi
    case(wdtctl[1:0])
514 136 olivier.gi
      2'b00  : wdtqn =  wdtcnt_nxt[15];
515
      2'b01  : wdtqn =  wdtcnt_nxt[13];
516
      2'b10  : wdtqn =  wdtcnt_nxt[9];
517
      default: wdtqn =  wdtcnt_nxt[6];
518 80 olivier.gi
    endcase
519
 
520
 
521
// Watchdog event detection
522
//-----------------------------
523
 
524 136 olivier.gi
assign     wdtifg_evt =  (wdtqn & wdtcnt_incr) | wdtpw_error;
525 80 olivier.gi
 
526
 
527 136 olivier.gi
// Watchdog interrupt flag
528
//------------------------------
529
reg        wdtifg;
530 80 olivier.gi
 
531 136 olivier.gi
wire       wdtifg_set =  wdtifg_evt                  |  wdtifg_sw_set;
532
wire       wdtifg_clr =  (wdtifg_irq_clr & wdttmsel) |  wdtifg_sw_clr;
533
 
534
always @ (posedge mclk or posedge por)
535
  if (por)             wdtifg <=  1'b0;
536
  else if (wdtifg_set) wdtifg <=  1'b1;
537
  else if (wdtifg_clr) wdtifg <=  1'b0;
538
 
539
 
540
// Watchdog interrupt generation
541
//---------------------------------
542
wire    wdt_irq       = wdttmsel & wdtifg & wdtie;
543
wire    wdt_wkup      =  1'b0;
544
 
545
 
546
// Watchdog reset generation
547
//-----------------------------
548
reg     wdt_reset;
549
 
550
always @ (posedge mclk or posedge por)
551
  if (por) wdt_reset <= 1'b0;
552
  else     wdt_reset <= wdtpw_error | (wdtifg_set & ~wdttmsel);
553
 
554
 
555 202 olivier.gi
// LINT cleanup
556
wire        UNUSED_scan_mode = scan_mode;
557
wire        UNUSED_smclk     = smclk;
558
wire        UNUSED_aclk      = aclk;
559 136 olivier.gi
`endif
560 202 olivier.gi
wire [15:0] UNUSED_per_din   = per_din;
561 136 olivier.gi
 
562 80 olivier.gi
endmodule // omsp_watchdog
563
 
564 104 olivier.gi
`ifdef OMSP_NO_INCLUDE
565
`else
566 80 olivier.gi
`include "openMSP430_undefines.v"
567 104 olivier.gi
`endif

powered by: WebSVN 2.1.0

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