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

Subversion Repositories openmsp430

[/] [openmsp430/] [trunk/] [core/] [rtl/] [verilog/] [periph/] [omsp_timerA.v] - Blame information for rev 115

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

Line No. Rev Author Line
1 2 olivier.gi
//----------------------------------------------------------------------------
2
// Copyright (C) 2001 Authors
3
//
4
// This source file may be used and distributed without restriction provided
5
// that this copyright statement is not removed from the file and that any
6
// derivative work contains the original copyright notice and the associated
7
// disclaimer.
8
//
9
// This source file is free software; you can redistribute it and/or modify
10
// it under the terms of the GNU Lesser General Public License as published
11
// by the Free Software Foundation; either version 2.1 of the License, or
12
// (at your option) any later version.
13
//
14
// This source is distributed in the hope that it will be useful, but WITHOUT
15
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
16
// FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
17
// License for more details.
18
//
19
// You should have received a copy of the GNU Lesser General Public License
20
// along with this source; if not, write to the Free Software Foundation,
21
// Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
22
//
23
//----------------------------------------------------------------------------
24
//
25 34 olivier.gi
// *File Name: omsp_timerA.v
26 2 olivier.gi
// 
27
// *Module Description:
28
//                       Timer A top-level
29
//
30
// *Author(s):
31
//              - Olivier Girard,    olgirard@gmail.com
32
//
33
//----------------------------------------------------------------------------
34 17 olivier.gi
// $Rev: 111 $
35
// $LastChangedBy: olivier.girard $
36
// $LastChangedDate: 2011-05-20 22:39:02 +0200 (Fri, 20 May 2011) $
37
//----------------------------------------------------------------------------
38 106 olivier.gi
`ifdef OMSP_TA_NO_INCLUDE
39 103 olivier.gi
`else
40 106 olivier.gi
`include "omsp_timerA_defines.v"
41 103 olivier.gi
`endif
42 2 olivier.gi
 
43 34 olivier.gi
module  omsp_timerA (
44 2 olivier.gi
 
45
// OUTPUTs
46
    irq_ta0,                        // Timer A interrupt: TACCR0
47
    irq_ta1,                        // Timer A interrupt: TAIV, TACCR1, TACCR2
48
    per_dout,                       // Peripheral data output
49
    ta_out0,                        // Timer A output 0
50
    ta_out0_en,                     // Timer A output 0 enable
51
    ta_out1,                        // Timer A output 1
52
    ta_out1_en,                     // Timer A output 1 enable
53
    ta_out2,                        // Timer A output 2
54
    ta_out2_en,                     // Timer A output 2 enable
55
 
56
// INPUTs
57
    aclk_en,                        // ACLK enable (from CPU)
58
    dbg_freeze,                     // Freeze Timer A counter
59
    inclk,                          // INCLK external timer clock (SLOW)
60
    irq_ta0_acc,                    // Interrupt request TACCR0 accepted
61
    mclk,                           // Main system clock
62
    per_addr,                       // Peripheral address
63
    per_din,                        // Peripheral data input
64
    per_en,                         // Peripheral enable (high active)
65 106 olivier.gi
    per_we,                         // Peripheral write enable (high active)
66 111 olivier.gi
    puc_rst,                        // Main system reset
67 2 olivier.gi
    smclk_en,                       // SMCLK enable (from CPU)
68
    ta_cci0a,                       // Timer A capture 0 input A
69
    ta_cci0b,                       // Timer A capture 0 input B
70
    ta_cci1a,                       // Timer A capture 1 input A
71
    ta_cci1b,                       // Timer A capture 1 input B
72
    ta_cci2a,                       // Timer A capture 2 input A
73
    ta_cci2b,                       // Timer A capture 2 input B
74
    taclk                           // TACLK external timer clock (SLOW)
75
);
76
 
77
// OUTPUTs
78
//=========
79
output              irq_ta0;        // Timer A interrupt: TACCR0
80
output              irq_ta1;        // Timer A interrupt: TAIV, TACCR1, TACCR2
81
output       [15:0] per_dout;       // Peripheral data output
82
output              ta_out0;        // Timer A output 0
83
output              ta_out0_en;     // Timer A output 0 enable
84
output              ta_out1;        // Timer A output 1
85
output              ta_out1_en;     // Timer A output 1 enable
86
output              ta_out2;        // Timer A output 2
87
output              ta_out2_en;     // Timer A output 2 enable
88
 
89
// INPUTs
90
//=========
91
input               aclk_en;        // ACLK enable (from CPU)
92
input               dbg_freeze;     // Freeze Timer A counter
93
input               inclk;          // INCLK external timer clock (SLOW)
94
input               irq_ta0_acc;    // Interrupt request TACCR0 accepted
95
input               mclk;           // Main system clock
96 111 olivier.gi
input        [13:0] per_addr;       // Peripheral address
97 2 olivier.gi
input        [15:0] per_din;        // Peripheral data input
98
input               per_en;         // Peripheral enable (high active)
99 106 olivier.gi
input         [1:0] per_we;         // Peripheral write enable (high active)
100 111 olivier.gi
input               puc_rst;        // Main system reset
101 2 olivier.gi
input               smclk_en;       // SMCLK enable (from CPU)
102
input               ta_cci0a;       // Timer A capture 0 input A
103
input               ta_cci0b;       // Timer A capture 0 input B
104
input               ta_cci1a;       // Timer A capture 1 input A
105
input               ta_cci1b;       // Timer A capture 1 input B
106
input               ta_cci2a;       // Timer A capture 2 input A
107
input               ta_cci2b;       // Timer A capture 2 input B
108
input               taclk;          // TACLK external timer clock (SLOW)
109
 
110
 
111
//=============================================================================
112
// 1)  PARAMETER DECLARATION
113
//=============================================================================
114
 
115 111 olivier.gi
// Register base address (must be aligned to decoder bit width)
116
parameter       [14:0] BASE_ADDR  = 15'h0100;
117 2 olivier.gi
 
118 111 olivier.gi
// Decoder bit width (defines how many bits are considered for address decoding)
119
parameter              DEC_WD     =  7;
120 2 olivier.gi
 
121 111 olivier.gi
// Register addresses offset
122
parameter [DEC_WD-1:0] TACTL      = 'h60,
123
                       TAR        = 'h70,
124
                       TACCTL0    = 'h62,
125
                       TACCR0     = 'h72,
126
                       TACCTL1    = 'h64,
127
                       TACCR1     = 'h74,
128
                       TACCTL2    = 'h66,
129
                       TACCR2     = 'h76,
130
                       TAIV       = 'h2E;
131
 
132
// Register one-hot decoder utilities
133
parameter              DEC_SZ     =  2**DEC_WD;
134
parameter [DEC_SZ-1:0] BASE_REG   =  {{DEC_SZ-1{1'b0}}, 1'b1};
135
 
136 2 olivier.gi
// Register one-hot decoder
137 111 olivier.gi
parameter [DEC_SZ-1:0] TACTL_D    = (BASE_REG << TACTL),
138
                       TAR_D      = (BASE_REG << TAR),
139
                       TACCTL0_D  = (BASE_REG << TACCTL0),
140
                       TACCR0_D   = (BASE_REG << TACCR0),
141
                       TACCTL1_D  = (BASE_REG << TACCTL1),
142
                       TACCR1_D   = (BASE_REG << TACCR1),
143
                       TACCTL2_D  = (BASE_REG << TACCTL2),
144
                       TACCR2_D   = (BASE_REG << TACCR2),
145
                       TAIV_D     = (BASE_REG << TAIV);
146 2 olivier.gi
 
147
 
148
//============================================================================
149
// 2)  REGISTER DECODER
150
//============================================================================
151
 
152 111 olivier.gi
// Local register selection
153
wire              reg_sel   =  per_en & (per_addr[13:DEC_WD-1]==BASE_ADDR[14:DEC_WD]);
154
 
155
// Register local address
156
wire [DEC_WD-1:0] reg_addr  =  {per_addr[DEC_WD-2:0], 1'b0};
157
 
158 2 olivier.gi
// Register address decode
159 111 olivier.gi
wire [DEC_SZ-1:0] reg_dec   =  (TACTL_D    &  {DEC_SZ{(reg_addr == TACTL   )}})  |
160
                               (TAR_D      &  {DEC_SZ{(reg_addr == TAR     )}})  |
161
                               (TACCTL0_D  &  {DEC_SZ{(reg_addr == TACCTL0 )}})  |
162
                               (TACCR0_D   &  {DEC_SZ{(reg_addr == TACCR0  )}})  |
163
                               (TACCTL1_D  &  {DEC_SZ{(reg_addr == TACCTL1 )}})  |
164
                               (TACCR1_D   &  {DEC_SZ{(reg_addr == TACCR1  )}})  |
165
                               (TACCTL2_D  &  {DEC_SZ{(reg_addr == TACCTL2 )}})  |
166
                               (TACCR2_D   &  {DEC_SZ{(reg_addr == TACCR2  )}})  |
167
                               (TAIV_D     &  {DEC_SZ{(reg_addr == TAIV    )}});
168 2 olivier.gi
 
169
// Read/Write probes
170 111 olivier.gi
wire              reg_write =  |per_we & reg_sel;
171
wire              reg_read  = ~|per_we & reg_sel;
172 2 olivier.gi
 
173
// Read/Write vectors
174 111 olivier.gi
wire [DEC_SZ-1:0] reg_wr    = reg_dec & {512{reg_write}};
175
wire [DEC_SZ-1:0] reg_rd    = reg_dec & {512{reg_read}};
176 2 olivier.gi
 
177
 
178
//============================================================================
179
// 3) REGISTERS
180
//============================================================================
181
 
182
// TACTL Register
183
//-----------------   
184
reg   [9:0] tactl;
185
 
186
wire        tactl_wr = reg_wr[TACTL];
187
wire        taclr    = tactl_wr & per_din[`TACLR];
188
wire        taifg_set;
189
wire        taifg_clr;
190
 
191 111 olivier.gi
always @ (posedge mclk or posedge puc_rst)
192
  if (puc_rst)       tactl <=  10'h000;
193 2 olivier.gi
  else if (tactl_wr) tactl <=  ((per_din[9:0] & 10'h3f3) | {9'h000, taifg_set}) & {9'h1ff, ~taifg_clr};
194
  else               tactl <=  (tactl                    | {9'h000, taifg_set}) & {9'h1ff, ~taifg_clr};
195
 
196
 
197
// TAR Register
198
//-----------------   
199
reg  [15:0] tar;
200
 
201
wire        tar_wr = reg_wr[TAR];
202
 
203
wire        tar_clk;
204
wire        tar_clr;
205
wire        tar_inc;
206
wire        tar_dec;
207
wire [15:0] tar_add  = tar_inc ? 16'h0001 :
208
                       tar_dec ? 16'hffff : 16'h0000;
209
wire [15:0] tar_nxt  = tar_clr ? 16'h0000 : (tar+tar_add);
210
 
211 111 olivier.gi
always @ (posedge mclk or posedge puc_rst)
212
  if (puc_rst)                     tar <=  16'h0000;
213 2 olivier.gi
  else if  (tar_wr)                tar <=  per_din;
214
  else if  (taclr)                 tar <=  16'h0000;
215
  else if  (tar_clk & ~dbg_freeze) tar <=  tar_nxt;
216
 
217
 
218
// TACCTL0 Register
219
//------------------   
220
reg  [15:0] tacctl0;
221
 
222
wire        tacctl0_wr = reg_wr[TACCTL0];
223
wire        ccifg0_set;
224
wire        cov0_set;
225
 
226 111 olivier.gi
always @ (posedge mclk or posedge puc_rst)
227
  if (puc_rst)         tacctl0  <=  16'h0000;
228 2 olivier.gi
  else if (tacctl0_wr) tacctl0  <=  ((per_din & 16'hf9f7) | {14'h0000, cov0_set, ccifg0_set}) & {15'h7fff, ~irq_ta0_acc};
229
  else                 tacctl0  <=  (tacctl0              | {14'h0000, cov0_set, ccifg0_set}) & {15'h7fff, ~irq_ta0_acc};
230
 
231
wire        cci0;
232
reg         scci0;
233
wire [15:0] tacctl0_full = tacctl0 | {5'h00, scci0, 6'h00, cci0, 3'h0};
234
 
235
 
236
// TACCR0 Register
237
//------------------   
238
reg  [15:0] taccr0;
239
 
240
wire        taccr0_wr = reg_wr[TACCR0];
241
wire        cci0_cap;
242
 
243 111 olivier.gi
always @ (posedge mclk or posedge puc_rst)
244
  if (puc_rst)        taccr0 <=  16'h0000;
245 2 olivier.gi
  else if (taccr0_wr) taccr0 <=  per_din;
246
  else if (cci0_cap)  taccr0 <=  tar;
247
 
248
 
249
// TACCTL1 Register
250
//------------------   
251
reg  [15:0] tacctl1;
252
 
253
wire        tacctl1_wr = reg_wr[TACCTL1];
254
wire        ccifg1_set;
255
wire        ccifg1_clr;
256
wire        cov1_set;
257
 
258 111 olivier.gi
always @ (posedge mclk or posedge puc_rst)
259
  if (puc_rst)         tacctl1 <=  16'h0000;
260 2 olivier.gi
  else if (tacctl1_wr) tacctl1 <=  ((per_din & 16'hf9f7) | {14'h0000, cov1_set, ccifg1_set}) & {15'h7fff, ~ccifg1_clr};
261
  else                 tacctl1 <=  (tacctl1              | {14'h0000, cov1_set, ccifg1_set}) & {15'h7fff, ~ccifg1_clr};
262
 
263
wire        cci1;
264
reg         scci1;
265
wire [15:0] tacctl1_full = tacctl1 | {5'h00, scci1, 6'h00, cci1, 3'h0};
266
 
267
 
268
// TACCR1 Register
269
//------------------   
270
reg  [15:0] taccr1;
271
 
272
wire        taccr1_wr = reg_wr[TACCR1];
273
wire        cci1_cap;
274
 
275 111 olivier.gi
always @ (posedge mclk or posedge puc_rst)
276
  if (puc_rst)        taccr1 <=  16'h0000;
277 2 olivier.gi
  else if (taccr1_wr) taccr1 <=  per_din;
278
  else if (cci1_cap)  taccr1 <=  tar;
279
 
280
 
281
// TACCTL2 Register
282
//------------------   
283
reg  [15:0] tacctl2;
284
 
285
wire        tacctl2_wr = reg_wr[TACCTL2];
286
wire        ccifg2_set;
287
wire        ccifg2_clr;
288
wire        cov2_set;
289
 
290 111 olivier.gi
always @ (posedge mclk or posedge puc_rst)
291
  if (puc_rst)         tacctl2 <=  16'h0000;
292 2 olivier.gi
  else if (tacctl2_wr) tacctl2 <=  ((per_din & 16'hf9f7) | {14'h0000, cov2_set, ccifg2_set}) & {15'h7fff, ~ccifg2_clr};
293
  else                 tacctl2 <=  (tacctl2              | {14'h0000, cov2_set, ccifg2_set}) & {15'h7fff, ~ccifg2_clr};
294
 
295
wire        cci2;
296
reg         scci2;
297
wire [15:0] tacctl2_full = tacctl2 | {5'h00, scci2, 6'h00, cci2, 3'h0};
298
 
299
 
300
// TACCR2 Register
301
//------------------   
302
reg  [15:0] taccr2;
303
 
304
wire        taccr2_wr = reg_wr[TACCR2];
305
wire        cci2_cap;
306
 
307 111 olivier.gi
always @ (posedge mclk or posedge puc_rst)
308
  if (puc_rst)        taccr2 <=  16'h0000;
309 2 olivier.gi
  else if (taccr2_wr) taccr2 <=  per_din;
310
  else if (cci2_cap)  taccr2 <=  tar;
311
 
312
 
313
// TAIV Register
314
//------------------   
315
 
316
wire [3:0] taiv = (tacctl1[`TACCIFG] & tacctl1[`TACCIE]) ? 4'h2 :
317
                  (tacctl2[`TACCIFG] & tacctl2[`TACCIE]) ? 4'h4 :
318
                  (tactl[`TAIFG]     & tactl[`TAIE])     ? 4'hA :
319
                                                           4'h0;
320
 
321
assign     ccifg1_clr = (reg_rd[TAIV] | reg_wr[TAIV]) & (taiv==4'h2);
322
assign     ccifg2_clr = (reg_rd[TAIV] | reg_wr[TAIV]) & (taiv==4'h4);
323
assign     taifg_clr  = (reg_rd[TAIV] | reg_wr[TAIV]) & (taiv==4'hA);
324
 
325
 
326
//============================================================================
327
// 4) DATA OUTPUT GENERATION
328
//============================================================================
329
 
330
// Data output mux
331
wire [15:0] tactl_rd   = {6'h00, tactl}  & {16{reg_rd[TACTL]}};
332
wire [15:0] tar_rd     = tar             & {16{reg_rd[TAR]}};
333
wire [15:0] tacctl0_rd = tacctl0_full    & {16{reg_rd[TACCTL0]}};
334
wire [15:0] taccr0_rd  = taccr0          & {16{reg_rd[TACCR0]}};
335
wire [15:0] tacctl1_rd = tacctl1_full    & {16{reg_rd[TACCTL1]}};
336
wire [15:0] taccr1_rd  = taccr1          & {16{reg_rd[TACCR1]}};
337
wire [15:0] tacctl2_rd = tacctl2_full    & {16{reg_rd[TACCTL2]}};
338
wire [15:0] taccr2_rd  = taccr2          & {16{reg_rd[TACCR2]}};
339
wire [15:0] taiv_rd    = {12'h000, taiv} & {16{reg_rd[TAIV]}};
340
 
341
wire [15:0] per_dout   =  tactl_rd   |
342
                          tar_rd     |
343
                          tacctl0_rd |
344
                          taccr0_rd  |
345
                          tacctl1_rd |
346
                          taccr1_rd  |
347
                          tacctl2_rd |
348
                          taccr2_rd  |
349
                          taiv_rd;
350
 
351
 
352
//============================================================================
353
// 5) Timer A counter control
354
//============================================================================
355
 
356
// Clock input synchronization (TACLK & INCLK)
357
//-----------------------------------------------------------
358 111 olivier.gi
wire taclk_s;
359
wire inclk_s;
360
 
361
omsp_sync_cell sync_cell_taclk (
362
    .data_out (taclk_s),
363
    .clk      (mclk),
364
    .data_in  (taclk),
365
    .rst      (puc_rst)
366
);
367
 
368
omsp_sync_cell sync_cell_inclk (
369
    .data_out (inclk_s),
370
    .clk      (mclk),
371
    .data_in  (inclk),
372
    .rst      (puc_rst)
373
);
374
 
375
 
376
// Clock edge detection (TACLK & INCLK)
377
//-----------------------------------------------------------
378
 
379
reg  taclk_dly;
380 2 olivier.gi
 
381 111 olivier.gi
always @ (posedge mclk or posedge puc_rst)
382
  if (puc_rst) taclk_dly <=  1'b0;
383
  else         taclk_dly <=  taclk_s;
384 2 olivier.gi
 
385 111 olivier.gi
wire taclk_en = taclk_s & ~taclk_dly;
386 2 olivier.gi
 
387
 
388 111 olivier.gi
reg  inclk_dly;
389 2 olivier.gi
 
390 111 olivier.gi
always @ (posedge mclk or posedge puc_rst)
391
  if (puc_rst) inclk_dly <=  1'b0;
392
  else         inclk_dly <=  inclk_s;
393 2 olivier.gi
 
394 111 olivier.gi
wire inclk_en = inclk_s & ~inclk_dly;
395 2 olivier.gi
 
396
 
397
// Timer clock input mux
398
//-----------------------------------------------------------
399
 
400
wire sel_clk = (tactl[`TASSELx]==2'b00) ? taclk_en :
401
               (tactl[`TASSELx]==2'b01) ?  aclk_en :
402
               (tactl[`TASSELx]==2'b10) ? smclk_en : inclk_en;
403
 
404
 
405
// Generate update pluse for the counter (<=> divided clock)
406
//-----------------------------------------------------------
407
reg [2:0] clk_div;
408
 
409
assign    tar_clk = sel_clk & ((tactl[`TAIDx]==2'b00) ?  1'b1         :
410
                               (tactl[`TAIDx]==2'b01) ?  clk_div[0]   :
411
                               (tactl[`TAIDx]==2'b10) ? &clk_div[1:0] :
412
                                                        &clk_div[2:0]);
413
 
414 111 olivier.gi
always @ (posedge mclk or posedge puc_rst)
415
  if (puc_rst)                               clk_div <=  3'h0;
416 2 olivier.gi
  else if  (tar_clk | taclr)                 clk_div <=  3'h0;
417
  else if ((tactl[`TAMCx]!=2'b00) & sel_clk) clk_div <=  clk_div+3'h1;
418
 
419
 
420
// Time counter control signals
421
//-----------------------------------------------------------
422
 
423
assign  tar_clr   = ((tactl[`TAMCx]==2'b01) & (tar>=taccr0))         |
424
                    ((tactl[`TAMCx]==2'b11) & (taccr0==16'h0000));
425
 
426
assign  tar_inc   =  (tactl[`TAMCx]==2'b01) | (tactl[`TAMCx]==2'b10) |
427
                    ((tactl[`TAMCx]==2'b11) & ~tar_dec);
428
 
429
reg tar_dir;
430 111 olivier.gi
always @ (posedge mclk or posedge puc_rst)
431
  if (puc_rst)                        tar_dir <=  1'b0;
432 2 olivier.gi
  else if (taclr)                     tar_dir <=  1'b0;
433
  else if (tactl[`TAMCx]==2'b11)
434
    begin
435
       if (tar_clk & (tar==16'h0001)) tar_dir <=  1'b0;
436
       else if       (tar>=taccr0)    tar_dir <=  1'b1;
437
    end
438
  else                                tar_dir <=  1'b0;
439
 
440
assign tar_dec = tar_dir | ((tactl[`TAMCx]==2'b11) & (tar>=taccr0));
441
 
442
 
443
//============================================================================
444
// 6) Timer A comparator
445
//============================================================================
446
 
447
wire equ0 = (tar_nxt==taccr0) & (tar!=taccr0);
448
wire equ1 = (tar_nxt==taccr1) & (tar!=taccr1);
449
wire equ2 = (tar_nxt==taccr2) & (tar!=taccr2);
450
 
451
 
452
//============================================================================
453
// 7) Timer A capture logic
454
//============================================================================
455
 
456
// Input selection
457
//------------------
458
assign cci0 = (tacctl0[`TACCISx]==2'b00) ? ta_cci0a :
459
              (tacctl0[`TACCISx]==2'b01) ? ta_cci0b :
460
              (tacctl0[`TACCISx]==2'b10) ?     1'b0 : 1'b1;
461
 
462
assign cci1 = (tacctl1[`TACCISx]==2'b00) ? ta_cci1a :
463
              (tacctl1[`TACCISx]==2'b01) ? ta_cci1b :
464
              (tacctl1[`TACCISx]==2'b10) ?     1'b0 : 1'b1;
465
 
466
assign cci2 = (tacctl2[`TACCISx]==2'b00) ? ta_cci2a :
467
              (tacctl2[`TACCISx]==2'b01) ? ta_cci2b :
468
              (tacctl2[`TACCISx]==2'b10) ?     1'b0 : 1'b1;
469
 
470 111 olivier.gi
// CCIx synchronization
471
wire cci0_s;
472
wire cci1_s;
473
wire cci2_s;
474 2 olivier.gi
 
475 111 olivier.gi
omsp_sync_cell sync_cell_cci0 (
476
    .data_out (cci0_s),
477
    .clk      (mclk),
478
    .data_in  (cci0),
479
    .rst      (puc_rst)
480
);
481
omsp_sync_cell sync_cell_cci1 (
482
    .data_out (cci1_s),
483
    .clk      (mclk),
484
    .data_in  (cci1),
485
    .rst      (puc_rst)
486
);
487
omsp_sync_cell sync_cell_cci2 (
488
    .data_out (cci2_s),
489
    .clk      (mclk),
490
    .data_in  (cci2),
491
    .rst      (puc_rst)
492
);
493
 
494
// Register CCIx for edge detection
495
reg cci0_dly;
496
reg cci1_dly;
497
reg cci2_dly;
498
 
499
always @ (posedge mclk or posedge puc_rst)
500
  if (puc_rst)
501
    begin
502
       cci0_dly <=  1'b0;
503
       cci1_dly <=  1'b0;
504
       cci2_dly <=  1'b0;
505
    end
506
  else
507
    begin
508
       cci0_dly <=  cci0_s;
509
       cci1_dly <=  cci1_s;
510
       cci2_dly <=  cci2_s;
511
    end
512
 
513 2 olivier.gi
 
514
// Generate SCCIx
515
//------------------
516
 
517 111 olivier.gi
always @ (posedge mclk or posedge puc_rst)
518
  if (puc_rst)             scci0 <=  1'b0;
519
  else if (tar_clk & equ0) scci0 <=  cci0_s;
520 2 olivier.gi
 
521 111 olivier.gi
always @ (posedge mclk or posedge puc_rst)
522
  if (puc_rst)             scci1 <=  1'b0;
523
  else if (tar_clk & equ1) scci1 <=  cci1_s;
524 2 olivier.gi
 
525 111 olivier.gi
always @ (posedge mclk or posedge puc_rst)
526
  if (puc_rst)             scci2 <=  1'b0;
527
  else if (tar_clk & equ2) scci2 <=  cci2_s;
528 2 olivier.gi
 
529
 
530
// Capture mode
531
//------------------
532
wire cci0_evt = (tacctl0[`TACMx]==2'b00) ? 1'b0                  :
533 111 olivier.gi
                (tacctl0[`TACMx]==2'b01) ? ( cci0_s & ~cci0_dly) :   // Rising edge
534
                (tacctl0[`TACMx]==2'b10) ? (~cci0_s &  cci0_dly) :   // Falling edge
535
                                           ( cci0_s ^  cci0_dly);    // Both edges
536 2 olivier.gi
 
537
wire cci1_evt = (tacctl1[`TACMx]==2'b00) ? 1'b0                  :
538 111 olivier.gi
                (tacctl1[`TACMx]==2'b01) ? ( cci1_s & ~cci1_dly) :   // Rising edge
539
                (tacctl1[`TACMx]==2'b10) ? (~cci1_s &  cci1_dly) :   // Falling edge
540
                                           ( cci1_s ^  cci1_dly);    // Both edges
541 2 olivier.gi
 
542
wire cci2_evt = (tacctl2[`TACMx]==2'b00) ? 1'b0                  :
543 111 olivier.gi
                (tacctl2[`TACMx]==2'b01) ? ( cci2_s & ~cci2_dly) :   // Rising edge
544
                (tacctl2[`TACMx]==2'b10) ? (~cci2_s &  cci2_dly) :   // Falling edge
545
                                           ( cci2_s ^  cci2_dly);    // Both edges
546 2 olivier.gi
 
547
// Event Synchronization
548
//-----------------------
549
 
550
reg cci0_evt_s;
551 111 olivier.gi
always @ (posedge mclk or posedge puc_rst)
552
  if (puc_rst)       cci0_evt_s <=  1'b0;
553 2 olivier.gi
  else if (tar_clk)  cci0_evt_s <=  1'b0;
554
  else if (cci0_evt) cci0_evt_s <=  1'b1;
555
 
556
reg cci1_evt_s;
557 111 olivier.gi
always @ (posedge mclk or posedge puc_rst)
558
  if (puc_rst)       cci1_evt_s <=  1'b0;
559 2 olivier.gi
  else if (tar_clk)  cci1_evt_s <=  1'b0;
560
  else if (cci1_evt) cci1_evt_s <=  1'b1;
561
 
562
reg cci2_evt_s;
563 111 olivier.gi
always @ (posedge mclk or posedge puc_rst)
564
  if (puc_rst)       cci2_evt_s <=  1'b0;
565 2 olivier.gi
  else if (tar_clk)  cci2_evt_s <=  1'b0;
566
  else if (cci2_evt) cci2_evt_s <=  1'b1;
567
 
568
reg cci0_sync;
569 111 olivier.gi
always @ (posedge mclk or posedge puc_rst)
570
  if (puc_rst) cci0_sync <=  1'b0;
571
  else         cci0_sync <=  (tar_clk & cci0_evt_s) | (tar_clk & cci0_evt & ~cci0_evt_s);
572 2 olivier.gi
 
573
reg cci1_sync;
574 111 olivier.gi
always @ (posedge mclk or posedge puc_rst)
575
  if (puc_rst) cci1_sync <=  1'b0;
576
  else         cci1_sync <=  (tar_clk & cci1_evt_s) | (tar_clk & cci1_evt & ~cci1_evt_s);
577 2 olivier.gi
 
578
reg cci2_sync;
579 111 olivier.gi
always @ (posedge mclk or posedge puc_rst)
580
  if (puc_rst) cci2_sync <=  1'b0;
581
  else         cci2_sync <=  (tar_clk & cci2_evt_s) | (tar_clk & cci2_evt & ~cci2_evt_s);
582 2 olivier.gi
 
583
 
584
// Generate final capture command
585
//-----------------------------------
586
 
587
assign cci0_cap  = tacctl0[`TASCS] ? cci0_sync : cci0_evt;
588
assign cci1_cap  = tacctl1[`TASCS] ? cci1_sync : cci1_evt;
589
assign cci2_cap  = tacctl2[`TASCS] ? cci2_sync : cci2_evt;
590
 
591
 
592
// Generate capture overflow flag
593
//-----------------------------------
594
 
595
reg  cap0_taken;
596
wire cap0_taken_clr = reg_rd[TACCR0] | (tacctl0_wr & tacctl0[`TACOV] & ~per_din[`TACOV]);
597 111 olivier.gi
always @ (posedge mclk or posedge puc_rst)
598
  if (puc_rst)             cap0_taken <=  1'b0;
599 2 olivier.gi
  else if (cci0_cap)       cap0_taken <=  1'b1;
600
  else if (cap0_taken_clr) cap0_taken <=  1'b0;
601
 
602
reg  cap1_taken;
603
wire cap1_taken_clr = reg_rd[TACCR1] | (tacctl1_wr & tacctl1[`TACOV] & ~per_din[`TACOV]);
604 111 olivier.gi
always @ (posedge mclk or posedge puc_rst)
605
  if (puc_rst)             cap1_taken <=  1'b0;
606 2 olivier.gi
  else if (cci1_cap)       cap1_taken <=  1'b1;
607
  else if (cap1_taken_clr) cap1_taken <=  1'b0;
608
 
609
reg  cap2_taken;
610
wire cap2_taken_clr = reg_rd[TACCR2] | (tacctl2_wr & tacctl2[`TACOV] & ~per_din[`TACOV]);
611 111 olivier.gi
always @ (posedge mclk or posedge puc_rst)
612
  if (puc_rst)             cap2_taken <=  1'b0;
613 2 olivier.gi
  else if (cci2_cap)       cap2_taken <=  1'b1;
614
  else if (cap2_taken_clr) cap2_taken <=  1'b0;
615
 
616
 
617
assign cov0_set = cap0_taken & cci0_cap & ~reg_rd[TACCR0];
618
assign cov1_set = cap1_taken & cci1_cap & ~reg_rd[TACCR1];
619
assign cov2_set = cap2_taken & cci2_cap & ~reg_rd[TACCR2];
620
 
621
 
622
//============================================================================
623
// 8) Timer A output unit
624
//============================================================================
625
 
626
// Output unit 0
627
//-------------------
628
reg  ta_out0;
629
 
630
wire ta_out0_mode0 = tacctl0[`TAOUT];                // Output
631
wire ta_out0_mode1 = equ0 ?  1'b1    : ta_out0;      // Set
632
wire ta_out0_mode2 = equ0 ? ~ta_out0 :               // Toggle/Reset
633
                     equ0 ?  1'b0    : ta_out0;
634
wire ta_out0_mode3 = equ0 ?  1'b1    :               // Set/Reset
635
                     equ0 ?  1'b0    : ta_out0;
636
wire ta_out0_mode4 = equ0 ? ~ta_out0 : ta_out0;      // Toggle
637
wire ta_out0_mode5 = equ0 ?  1'b0    : ta_out0;      // Reset
638
wire ta_out0_mode6 = equ0 ? ~ta_out0 :               // Toggle/Set
639
                     equ0 ?  1'b1    : ta_out0;
640
wire ta_out0_mode7 = equ0 ?  1'b0    :               // Reset/Set
641
                     equ0 ?  1'b1    : ta_out0;
642
 
643
wire ta_out0_nxt   = (tacctl0[`TAOUTMODx]==3'b000) ? ta_out0_mode0 :
644
                     (tacctl0[`TAOUTMODx]==3'b001) ? ta_out0_mode1 :
645
                     (tacctl0[`TAOUTMODx]==3'b010) ? ta_out0_mode2 :
646
                     (tacctl0[`TAOUTMODx]==3'b011) ? ta_out0_mode3 :
647
                     (tacctl0[`TAOUTMODx]==3'b100) ? ta_out0_mode4 :
648
                     (tacctl0[`TAOUTMODx]==3'b101) ? ta_out0_mode5 :
649
                     (tacctl0[`TAOUTMODx]==3'b110) ? ta_out0_mode6 :
650
                                                     ta_out0_mode7;
651
 
652 111 olivier.gi
always @ (posedge mclk or posedge puc_rst)
653
  if (puc_rst)                                     ta_out0 <=  1'b0;
654 2 olivier.gi
  else if ((tacctl0[`TAOUTMODx]==3'b001) & taclr)  ta_out0 <=  1'b0;
655
  else if (tar_clk)                                ta_out0 <=  ta_out0_nxt;
656
 
657
assign  ta_out0_en = ~tacctl0[`TACAP];
658
 
659
 
660
// Output unit 1
661
//-------------------
662
reg  ta_out1;
663
 
664
wire ta_out1_mode0 = tacctl1[`TAOUT];                // Output
665
wire ta_out1_mode1 = equ1 ?  1'b1    : ta_out1;      // Set
666
wire ta_out1_mode2 = equ1 ? ~ta_out1 :               // Toggle/Reset
667
                     equ0 ?  1'b0    : ta_out1;
668
wire ta_out1_mode3 = equ1 ?  1'b1    :               // Set/Reset
669
                     equ0 ?  1'b0    : ta_out1;
670
wire ta_out1_mode4 = equ1 ? ~ta_out1 : ta_out1;      // Toggle
671
wire ta_out1_mode5 = equ1 ?  1'b0    : ta_out1;      // Reset
672
wire ta_out1_mode6 = equ1 ? ~ta_out1 :               // Toggle/Set
673
                     equ0 ?  1'b1    : ta_out1;
674
wire ta_out1_mode7 = equ1 ?  1'b0    :               // Reset/Set
675
                     equ0 ?  1'b1    : ta_out1;
676
 
677
wire ta_out1_nxt   = (tacctl1[`TAOUTMODx]==3'b000) ? ta_out1_mode0 :
678
                     (tacctl1[`TAOUTMODx]==3'b001) ? ta_out1_mode1 :
679
                     (tacctl1[`TAOUTMODx]==3'b010) ? ta_out1_mode2 :
680
                     (tacctl1[`TAOUTMODx]==3'b011) ? ta_out1_mode3 :
681
                     (tacctl1[`TAOUTMODx]==3'b100) ? ta_out1_mode4 :
682
                     (tacctl1[`TAOUTMODx]==3'b101) ? ta_out1_mode5 :
683
                     (tacctl1[`TAOUTMODx]==3'b110) ? ta_out1_mode6 :
684
                                                     ta_out1_mode7;
685
 
686 111 olivier.gi
always @ (posedge mclk or posedge puc_rst)
687
  if (puc_rst)                                     ta_out1 <=  1'b0;
688 2 olivier.gi
  else if ((tacctl1[`TAOUTMODx]==3'b001) & taclr)  ta_out1 <=  1'b0;
689
  else if (tar_clk)                                ta_out1 <=  ta_out1_nxt;
690
 
691
assign  ta_out1_en = ~tacctl1[`TACAP];
692
 
693
 
694
// Output unit 2
695
//-------------------
696
reg  ta_out2;
697
 
698
wire ta_out2_mode0 = tacctl2[`TAOUT];                // Output
699
wire ta_out2_mode1 = equ2 ?  1'b1    : ta_out2;      // Set
700
wire ta_out2_mode2 = equ2 ? ~ta_out2 :               // Toggle/Reset
701
                     equ0 ?  1'b0    : ta_out2;
702
wire ta_out2_mode3 = equ2 ?  1'b1    :               // Set/Reset
703
                     equ0 ?  1'b0    : ta_out2;
704
wire ta_out2_mode4 = equ2 ? ~ta_out2 : ta_out2;      // Toggle
705
wire ta_out2_mode5 = equ2 ?  1'b0    : ta_out2;      // Reset
706
wire ta_out2_mode6 = equ2 ? ~ta_out2 :               // Toggle/Set
707
                     equ0 ?  1'b1    : ta_out2;
708
wire ta_out2_mode7 = equ2 ?  1'b0    :               // Reset/Set
709
                     equ0 ?  1'b1    : ta_out2;
710
 
711
wire ta_out2_nxt   = (tacctl2[`TAOUTMODx]==3'b000) ? ta_out2_mode0 :
712
                     (tacctl2[`TAOUTMODx]==3'b001) ? ta_out2_mode1 :
713
                     (tacctl2[`TAOUTMODx]==3'b010) ? ta_out2_mode2 :
714
                     (tacctl2[`TAOUTMODx]==3'b011) ? ta_out2_mode3 :
715
                     (tacctl2[`TAOUTMODx]==3'b100) ? ta_out2_mode4 :
716
                     (tacctl2[`TAOUTMODx]==3'b101) ? ta_out2_mode5 :
717
                     (tacctl2[`TAOUTMODx]==3'b110) ? ta_out2_mode6 :
718
                                                     ta_out2_mode7;
719
 
720 111 olivier.gi
always @ (posedge mclk or posedge puc_rst)
721
  if (puc_rst)                                     ta_out2 <=  1'b0;
722 2 olivier.gi
  else if ((tacctl2[`TAOUTMODx]==3'b001) & taclr)  ta_out2 <=  1'b0;
723
  else if (tar_clk)                                ta_out2 <=  ta_out2_nxt;
724
 
725
assign  ta_out2_en = ~tacctl2[`TACAP];
726
 
727
 
728
//============================================================================
729
// 9) Timer A interrupt generation
730
//============================================================================
731
 
732
 
733
assign   taifg_set   = tar_clk & (((tactl[`TAMCx]==2'b01) & (tar==taccr0))                  |
734
                                  ((tactl[`TAMCx]==2'b10) & (tar==16'hffff))                |
735
                                  ((tactl[`TAMCx]==2'b11) & (tar_nxt==16'h0000) & tar_dec));
736
 
737
assign   ccifg0_set  = tacctl0[`TACAP] ? cci0_cap : (tar_clk &  ((tactl[`TAMCx]!=2'b00) & equ0));
738
assign   ccifg1_set  = tacctl1[`TACAP] ? cci1_cap : (tar_clk &  ((tactl[`TAMCx]!=2'b00) & equ1));
739
assign   ccifg2_set  = tacctl2[`TACAP] ? cci2_cap : (tar_clk &  ((tactl[`TAMCx]!=2'b00) & equ2));
740
 
741
 
742
wire     irq_ta0    = (tacctl0[`TACCIFG] & tacctl0[`TACCIE]);
743
 
744
wire     irq_ta1    = (tactl[`TAIFG]     & tactl[`TAIE])     |
745
                      (tacctl1[`TACCIFG] & tacctl1[`TACCIE]) |
746
                      (tacctl2[`TACCIFG] & tacctl2[`TACCIE]);
747
 
748
 
749 34 olivier.gi
endmodule // omsp_timerA
750 2 olivier.gi
 
751 106 olivier.gi
`ifdef OMSP_TA_NO_INCLUDE
752 103 olivier.gi
`else
753 106 olivier.gi
`include "omsp_timerA_undefines.v"
754 103 olivier.gi
`endif

powered by: WebSVN 2.1.0

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