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

Subversion Repositories ptc

[/] [ptc/] [trunk/] [rtl/] [verilog/] [ptc_top.v] - Blame information for rev 13

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

Line No. Rev Author Line
1 10 lampret
//////////////////////////////////////////////////////////////////////
2
////                                                              ////
3
////  WISHBONE PWM/Timer/Counter                                  ////
4
////                                                              ////
5
////  This file is part of the PTC project                        ////
6
////  http://www.opencores.org/cores/ptc/                         ////
7
////                                                              ////
8
////  Description                                                 ////
9
////  Implementation of PWM/Timer/Counter IP core according to    ////
10
////  PTC IP core specification document.                         ////
11
////                                                              ////
12
////  To Do:                                                      ////
13
////   Nothing                                                    ////
14
////                                                              ////
15
////  Author(s):                                                  ////
16
////      - Damjan Lampret, lampret@opencores.org                 ////
17
////                                                              ////
18
//////////////////////////////////////////////////////////////////////
19
////                                                              ////
20
//// Copyright (C) 2000 Authors and OPENCORES.ORG                 ////
21
////                                                              ////
22
//// This source file may be used and distributed without         ////
23
//// restriction provided that this copyright statement is not    ////
24
//// removed from the file and that any derivative work contains  ////
25
//// the original copyright notice and the associated disclaimer. ////
26
////                                                              ////
27
//// This source file is free software; you can redistribute it   ////
28
//// and/or modify it under the terms of the GNU Lesser General   ////
29
//// Public License as published by the Free Software Foundation; ////
30
//// either version 2.1 of the License, or (at your option) any   ////
31
//// later version.                                               ////
32
////                                                              ////
33
//// This source is distributed in the hope that it will be       ////
34
//// useful, but WITHOUT ANY WARRANTY; without even the implied   ////
35
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR      ////
36
//// PURPOSE.  See the GNU Lesser General Public License for more ////
37
//// details.                                                     ////
38
////                                                              ////
39
//// You should have received a copy of the GNU Lesser General    ////
40
//// Public License along with this source; if not, download it   ////
41
//// from http://www.opencores.org/lgpl.shtml                     ////
42
////                                                              ////
43
//////////////////////////////////////////////////////////////////////
44
//
45
// CVS Revision History
46
//
47
// $Log: not supported by cvs2svn $
48 11 lampret
// Revision 1.4  2001/09/18 18:48:29  lampret
49
// Changed top level ptc into ptc_top. Changed defines.v into ptc_defines.v. Reset of the counter is now synchronous.
50
//
51
// Revision 1.3  2001/08/21 23:23:50  lampret
52 10 lampret
// Changed directory structure, defines and port names.
53
//
54
// Revision 1.2  2001/07/17 00:18:10  lampret
55
// Added new parameters however RTL still has some issues related to hrc_match and int_match
56
//
57
// Revision 1.1  2001/06/05 07:45:36  lampret
58
// Added initial RTL and test benches. There are still some issues with these files.
59
//
60
//
61
 
62
// synopsys translate_off
63
`include "timescale.v"
64
// synopsys translate_on
65
`include "ptc_defines.v"
66
 
67
module ptc_top(
68
        // WISHBONE Interface
69
        wb_clk_i, wb_rst_i, wb_cyc_i, wb_adr_i, wb_dat_i, wb_sel_i, wb_we_i, wb_stb_i,
70
        wb_dat_o, wb_ack_o, wb_err_o, wb_inta_o,
71
 
72
        // External PTC Interface
73
        gate_clk_pad_i, capt_pad_i, pwm_pad_o, oen_padoen_o
74
);
75
 
76
parameter dw = 32;
77
parameter aw = `PTC_ADDRHH+1;
78
parameter cw = `PTC_CW;
79
 
80
//
81
// WISHBONE Interface
82
//
83
input                   wb_clk_i;       // Clock
84
input                   wb_rst_i;       // Reset
85
input                   wb_cyc_i;       // cycle valid input
86
input   [aw-1:0] wb_adr_i;       // address bus inputs
87
input   [dw-1:0] wb_dat_i;       // input data bus
88
input   [3:0]            wb_sel_i;       // byte select inputs
89
input                   wb_we_i;        // indicates write transfer
90
input                   wb_stb_i;       // strobe input
91
output  [dw-1:0] wb_dat_o;       // output data bus
92
output                  wb_ack_o;       // normal termination
93
output                  wb_err_o;       // termination w/ error
94
output                  wb_inta_o;      // Interrupt request output
95
 
96
//
97
// External PTC Interface
98
//
99
input           gate_clk_pad_i; // EClk/Gate input
100
input           capt_pad_i;     // Capture input
101
output          pwm_pad_o;      // PWM output
102
output          oen_padoen_o;   // PWM output driver enable
103
 
104
`ifdef PTC_IMPLEMENTED
105
 
106
//
107
// PTC Main Counter Register (or no register)
108
//
109
`ifdef PTC_RPTC_CNTR
110
reg     [cw-1:0] rptc_cntr;      // RPTC_CNTR register
111
`else
112
wire    [cw-1:0] rptc_cntr;      // No RPTC_CNTR register
113
`endif
114
 
115
//
116
// PTC HI Reference/Capture Register (or no register)
117
//
118
`ifdef PTC_RPTC_HRC
119
reg     [cw-1:0] rptc_hrc;       // RPTC_HRC register
120
`else
121
wire    [cw-1:0] rptc_hrc;       // No RPTC_HRC register
122
`endif
123
 
124
//
125
// PTC LO Reference/Capture Register (or no register)
126
//
127
`ifdef PTC_RPTC_LRC
128
reg     [cw-1:0] rptc_lrc;       // RPTC_LRC register
129
`else
130
wire    [cw-1:0] rptc_lrc;       // No RPTC_LRC register
131
`endif
132
 
133
//
134
// PTC Control Register (or no register)
135
//
136
`ifdef PTC_RPTC_CTRL
137
reg     [8:0]            rptc_ctrl;      // RPTC_CTRL register
138
`else
139
wire    [8:0]            rptc_ctrl;      // No RPTC_CTRL register
140
`endif
141
 
142
//
143
// Internal wires & regs
144
//
145
wire                    rptc_cntr_sel;  // RPTC_CNTR select
146
wire                    rptc_hrc_sel;   // RPTC_HRC select
147
wire                    rptc_lrc_sel;   // RPTC_LRC select
148
wire                    rptc_ctrl_sel;  // RPTC_CTRL select
149
wire                    hrc_match;      // RPTC_HRC matches RPTC_CNTR
150
wire                    lrc_match;      // RPTC_LRC matches RPTC_CNTR
151
wire                    restart;        // Restart counter when asserted
152
wire                    stop;           // Stop counter when asserted
153
wire                    cntr_clk;       // Counter clock
154
wire                    cntr_rst;       // Counter reset
155
wire                    hrc_clk;        // RPTC_HRC clock
156
wire                    lrc_clk;        // RPTC_LRC clock
157
wire                    eclk_gate;      // ptc_ecgt xored by RPTC_CTRL[NEC]
158
wire                    gate;           // Gate function of ptc_ecgt
159
wire                    pwm_rst;        // Reset of a PWM output
160
reg     [dw-1:0] wb_dat_o;       // Data out
161
reg                     pwm_pad_o;      // PWM output
162
reg                     int;            // Interrupt reg
163
wire                    int_match;      // Interrupt match
164
wire                    full_decoding;  // Full address decoding qualification
165
 
166
//
167
// All WISHBONE transfer terminations are successful except when:
168
// a) full address decoding is enabled and address doesn't match
169
//    any of the PTC registers
170
// b) sel_i evaluation is enabled and one of the sel_i inputs is zero
171
//
172
assign wb_ack_o = wb_cyc_i & wb_stb_i & !wb_err_o;
173
`ifdef PTC_FULL_DECODE
174
`ifdef PTC_STRICT_32BIT_ACCESS
175 11 lampret
assign wb_err_o = wb_cyc_i & wb_stb_i & (!full_decoding | (wb_sel_i != 4'b1111));
176 10 lampret
`else
177
assign wb_err_o = wb_cyc_i & wb_stb_i & !full_decoding;
178
`endif
179
`else
180
`ifdef PTC_STRICT_32BIT_ACCESS
181 11 lampret
assign wb_err_o = wb_cyc_i & wb_stb_i & (wb_sel_i != 4'b1111);
182 10 lampret
`else
183
assign wb_err_o = 1'b0;
184
`endif
185
`endif
186
 
187
//
188
// Counter clock is selected by RPTC_CTRL[ECLK]. When it is set,
189
// external clock is used.
190
//
191
assign cntr_clk = rptc_ctrl[`PTC_RPTC_CTRL_ECLK] ? eclk_gate : wb_clk_i;
192
 
193
//
194
// Counter reset
195
//
196
assign cntr_rst = wb_rst_i;
197
 
198
//
199
// HRC clock is selected by RPTC_CTRL[CAPTE]. When it is set,
200
// ptc_capt is used as a clock.
201
//
202
assign hrc_clk = rptc_ctrl[`PTC_RPTC_CTRL_CAPTE] ? capt_pad_i : wb_clk_i;
203
 
204
//
205
// LRC clock is selected by RPTC_CTRL[CAPTE]. When it is set,
206
// inverted ptc_capt is used as a clock.
207
//
208
assign lrc_clk = rptc_ctrl[`PTC_RPTC_CTRL_CAPTE] ? ~capt_pad_i : wb_clk_i;
209
 
210
//
211
// PWM output driver enable is inverted RPTC_CTRL[OE]
212
//
213
assign oen_padoen_o = ~rptc_ctrl[`PTC_RPTC_CTRL_OE];
214
 
215
//
216
// Use RPTC_CTRL[NEC]
217
//
218
assign eclk_gate = gate_clk_pad_i ^ rptc_ctrl[`PTC_RPTC_CTRL_NEC];
219
 
220
//
221
// Gate function is active when RPTC_CTRL[ECLK] is cleared
222
//
223
assign gate = eclk_gate & ~rptc_ctrl[`PTC_RPTC_CTRL_ECLK];
224
 
225
//
226
// Full address decoder
227
//
228
`ifdef PTC_FULL_DECODE
229
assign full_decoding = (wb_adr_i[`PTC_ADDRHH:`PTC_ADDRHL] == {`PTC_ADDRHH-`PTC_ADDRHL+1{1'b0}}) &
230
                        (wb_adr_i[`PTC_ADDRLH:`PTC_ADDRLL] == {`PTC_ADDRLH-`PTC_ADDRLL+1{1'b0}});
231
`else
232
assign full_decoding = 1'b1;
233
`endif
234
 
235
//
236
// PTC registers address decoder
237
//
238
assign rptc_cntr_sel = wb_cyc_i & wb_stb_i & (wb_adr_i[`PTC_OFS_BITS] == `PTC_RPTC_CNTR) & full_decoding;
239
assign rptc_hrc_sel = wb_cyc_i & wb_stb_i & (wb_adr_i[`PTC_OFS_BITS] == `PTC_RPTC_HRC) & full_decoding;
240
assign rptc_lrc_sel = wb_cyc_i & wb_stb_i & (wb_adr_i[`PTC_OFS_BITS] == `PTC_RPTC_LRC) & full_decoding;
241
assign rptc_ctrl_sel = wb_cyc_i & wb_stb_i & (wb_adr_i[`PTC_OFS_BITS] == `PTC_RPTC_CTRL) & full_decoding;
242
 
243
//
244
// Write to RPTC_CTRL or update of RPTC_CTRL[INT] bit
245
//
246
`ifdef PTC_RPTC_CTRL
247
always @(posedge wb_clk_i or posedge wb_rst_i)
248
        if (wb_rst_i)
249
                rptc_ctrl <= #1 9'b0;
250
        else if (rptc_ctrl_sel && wb_we_i)
251
                rptc_ctrl <= #1 wb_dat_i[8:0];
252
        else if (rptc_ctrl[`PTC_RPTC_CTRL_INTE])
253
                rptc_ctrl[`PTC_RPTC_CTRL_INT] <= #1 rptc_ctrl[`PTC_RPTC_CTRL_INT] | int;
254
`else
255
assign rptc_ctrl = `PTC_DEF_RPTC_CTRL;
256
`endif
257
 
258
//
259
// Write to RPTC_HRC
260
//
261
`ifdef PTC_RPTC_HRC
262
always @(posedge hrc_clk or posedge wb_rst_i)
263
        if (wb_rst_i)
264
                rptc_hrc <= #1 {cw{1'b0}};
265
        else if (rptc_hrc_sel && wb_we_i)
266
                rptc_hrc <= #1 wb_dat_i[cw-1:0];
267
        else if (rptc_ctrl[`PTC_RPTC_CTRL_CAPTE])
268
                rptc_hrc <= #1 rptc_cntr;
269
`else
270
assign rptc_hrc = `DEF_RPTC_HRC;
271
`endif
272
 
273
//
274
// Write to RPTC_LRC
275
//
276
`ifdef PTC_RPTC_LRC
277
always @(posedge lrc_clk or posedge wb_rst_i)
278
        if (wb_rst_i)
279
                rptc_lrc <= #1 {cw{1'b0}};
280
        else if (rptc_lrc_sel && wb_we_i)
281
                rptc_lrc <= #1 wb_dat_i[cw-1:0];
282
        else if (rptc_ctrl[`PTC_RPTC_CTRL_CAPTE])
283
                rptc_lrc <= #1 rptc_cntr;
284
`else
285
assign rptc_lrc = `DEF_RPTC_LRC;
286
`endif
287
 
288
//
289
// Write to or increment of RPTC_CNTR
290
//
291
`ifdef PTC_RPTC_CNTR
292
always @(posedge cntr_clk or posedge cntr_rst)
293
        if (cntr_rst)
294
                rptc_cntr <= #1 {cw{1'b0}};
295
        else if (rptc_cntr_sel && wb_we_i)
296
                rptc_cntr <= #1 wb_dat_i[cw-1:0];
297
        else if (restart)
298
                rptc_cntr <= #1 {cw{1'b0}};
299
        else if (!stop && rptc_ctrl[`PTC_RPTC_CTRL_EN] && !gate)
300
                rptc_cntr <= #1 rptc_cntr + 1;
301
`else
302
assign rptc_cntr = `DEF_RPTC_CNTR;
303
`endif
304
 
305
//
306
// Read PTC registers
307
//
308
always @(wb_adr_i or rptc_hrc or rptc_lrc or rptc_ctrl or rptc_cntr)
309
        case (wb_adr_i[`PTC_OFS_BITS])  // synopsys full_case parallel_case
310
`ifdef PTC_READREGS
311
                `PTC_RPTC_HRC: wb_dat_o[dw-1:0] = {{dw-cw{1'b0}}, rptc_hrc};
312
                `PTC_RPTC_LRC: wb_dat_o[dw-1:0] = {{dw-cw{1'b0}}, rptc_lrc};
313
                `PTC_RPTC_CTRL: wb_dat_o[dw-1:0] = {{dw-9{1'b0}}, rptc_ctrl};
314
`endif
315
                default: wb_dat_o[dw-1:0] = {{dw-cw{1'b0}}, rptc_cntr};
316
        endcase
317
 
318
//
319
// A match when RPTC_HRC is equal to RPTC_CNTR
320
//
321
assign hrc_match = rptc_ctrl[`PTC_RPTC_CTRL_EN] & (rptc_cntr == rptc_hrc);
322
 
323
//
324
// A match when RPTC_LRC is equal to RPTC_CNTR
325
//
326
assign lrc_match = rptc_ctrl[`PTC_RPTC_CTRL_EN] & (rptc_cntr == rptc_lrc);
327
 
328
//
329
// Restart counter when lrc_match asserted and RPTC_CTRL[SINGLE] cleared
330
// or when RPTC_CTRL[CNTRRST] is set
331
//
332
assign restart = lrc_match & ~rptc_ctrl[`PTC_RPTC_CTRL_SINGLE]
333
        | rptc_ctrl[`PTC_RPTC_CTRL_CNTRRST];
334
 
335
//
336
// Stop counter when lrc_match and RPTC_CTRL[SINGLE] both asserted
337
//
338
assign stop = lrc_match & rptc_ctrl[`PTC_RPTC_CTRL_SINGLE];
339
 
340
//
341
// PWM reset when lrc_match or system reset
342
//
343
assign pwm_rst = lrc_match | wb_rst_i;
344
 
345
//
346
// PWM output
347
//
348
always @(posedge wb_clk_i)      // posedge pwm_rst or posedge hrc_match !!! Damjan
349
        if (pwm_rst)
350
                pwm_pad_o <= #1 1'b0;
351
        else if (hrc_match)
352
                pwm_pad_o <= #1 1'b1;
353
 
354
//
355
// Generate an interrupt request
356
//
357
assign int_match = (lrc_match | hrc_match) & rptc_ctrl[`PTC_RPTC_CTRL_INTE];
358
 
359
// Register interrupt request
360
always @(posedge wb_rst_i or posedge wb_clk_i) // posedge int_match (instead of wb_rst_i)
361
        if (wb_rst_i)
362
                int <= #1 1'b0;
363
        else if (int_match)
364
                int <= #1 1'b1;
365
        else
366
                int <= #1 1'b0;
367
 
368
//
369
// Alias
370
//
371
assign wb_inta_o = rptc_ctrl[`PTC_RPTC_CTRL_INT];
372
 
373
`else
374
 
375
//
376
// When PTC is not implemented, drive all outputs as would when RPTC_CTRL
377
// is cleared and WISHBONE transfers complete with errors
378
//
379
assign wb_inta_o = 1'b0;
380
assign wb_ack_o = 1'b0;
381
assign wb_err_o = cyc_i & stb_i;
382
assign pwm_pad_o = 1'b0;
383
assign oen_padoen_o = 1'b1;
384
 
385
//
386
// Read PTC registers
387
//
388
`ifdef PTC_READREGS
389
assign wb_dat_o = {dw{1'b0}};
390
`endif
391
 
392
`endif
393
 
394
endmodule

powered by: WebSVN 2.1.0

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