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 204

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

powered by: WebSVN 2.1.0

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