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

Subversion Repositories amber

[/] [amber/] [trunk/] [hw/] [vlog/] [system/] [clocks_resets.v] - Blame information for rev 39

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

Line No. Rev Author Line
1 2 csantifort
//////////////////////////////////////////////////////////////////
2
//                                                              //
3
//  Clock and Resets                                            //
4
//                                                              //
5
//  This file is part of the Amber project                      //
6
//  http://www.opencores.org/project,amber                      //
7
//                                                              //
8
//  Description                                                 //
9
//  Takes in the 200MHx board clock and generates the main      //
10
//  system clock. For the FPGA this is done with a PLL.         //
11
//                                                              //
12
//  Author(s):                                                  //
13
//      - Conor Santifort, csantifort.amber@gmail.com           //
14
//                                                              //
15
//////////////////////////////////////////////////////////////////
16
//                                                              //
17
// Copyright (C) 2010 Authors and OPENCORES.ORG                 //
18
//                                                              //
19
// This source file may be used and distributed without         //
20
// restriction provided that this copyright statement is not    //
21
// removed from the file and that any derivative work contains  //
22
// the original copyright notice and the associated disclaimer. //
23
//                                                              //
24
// This source file is free software; you can redistribute it   //
25
// and/or modify it under the terms of the GNU Lesser General   //
26
// Public License as published by the Free Software Foundation; //
27
// either version 2.1 of the License, or (at your option) any   //
28
// later version.                                               //
29
//                                                              //
30
// This source is distributed in the hope that it will be       //
31
// useful, but WITHOUT ANY WARRANTY; without even the implied   //
32
// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR      //
33
// PURPOSE.  See the GNU Lesser General Public License for more //
34
// details.                                                     //
35
//                                                              //
36
// You should have received a copy of the GNU Lesser General    //
37
// Public License along with this source; if not, download it   //
38
// from http://www.opencores.org/lgpl.shtml                     //
39
//                                                              //
40
//////////////////////////////////////////////////////////////////
41
 
42
 
43
//
44
// Clocks and Resets Module
45
//
46
 
47
module clocks_resets  (
48
input                       i_brd_rst,
49
input                       i_brd_clk_n,
50
input                       i_brd_clk_p,
51
input                       i_ddr_calib_done,
52
output                      o_sys_rst,
53
output                      o_sys_clk,
54
output                      o_clk_200
55
 
56
);
57
 
58
 
59
wire                        calib_done_33mhz;
60
wire                        rst0;
61
 
62
assign o_sys_rst = rst0 || !calib_done_33mhz;
63
 
64
 
65
 
66
`ifdef XILINX_FPGA
67
 
68
    localparam                  RST_SYNC_NUM = 25;
69
    wire                        pll_locked;
70
    wire                        clkfbout_clkfbin;
71
    reg [RST_SYNC_NUM-1:0]      rst0_sync_r    /* synthesis syn_maxfan = 10 */;
72
    reg [RST_SYNC_NUM-1:0]      ddr_calib_done_sync_r    /* synthesis syn_maxfan = 10 */;
73
    wire                        rst_tmp;
74
    wire                        pll_clk;
75
 
76
    (* KEEP = "TRUE" *)  wire brd_clk_ibufg;
77
 
78
 
79
    IBUFGDS # (
80
         .DIFF_TERM  ( "TRUE"     ),
81
         .IOSTANDARD ( "LVDS_25"  ))  // SP605 on chip termination of LVDS clock
82
         u_ibufgds_brd
83
        (
84
         .I  ( i_brd_clk_p    ),
85
         .IB ( i_brd_clk_n    ),
86
         .O  ( brd_clk_ibufg  )
87
         );
88
 
89
 
90
    assign rst0             = rst0_sync_r[RST_SYNC_NUM-1];
91
    assign calib_done_33mhz = ddr_calib_done_sync_r[RST_SYNC_NUM-1];
92
    assign o_clk_200        = brd_clk_ibufg;
93
 
94
 
95
    `ifdef XILINX_SPARTAN6_FPGA
96
    // ======================================
97
    // Xilinx Spartan-6 PLL
98
    // ======================================
99
        PLL_ADV #
100
            (
101
             .BANDWIDTH          ( "OPTIMIZED"        ),
102
             .CLKIN1_PERIOD      ( 5                  ),
103
             .CLKIN2_PERIOD      ( 1                  ),
104
             .CLKOUT0_DIVIDE     ( 1                  ),
105
             .CLKOUT1_DIVIDE     (                    ),
106
             .CLKOUT2_DIVIDE     ( `AMBER_CLK_DIVIDER ),   // = 800 MHz / LP_CLK_DIVIDER
107
             .CLKOUT3_DIVIDE     ( 1                  ),
108
             .CLKOUT4_DIVIDE     ( 1                  ),
109
             .CLKOUT5_DIVIDE     ( 1                  ),
110
             .CLKOUT0_PHASE      ( 0.000              ),
111
             .CLKOUT1_PHASE      ( 0.000              ),
112
             .CLKOUT2_PHASE      ( 0.000              ),
113
             .CLKOUT3_PHASE      ( 0.000              ),
114
             .CLKOUT4_PHASE      ( 0.000              ),
115
             .CLKOUT5_PHASE      ( 0.000              ),
116
             .CLKOUT0_DUTY_CYCLE ( 0.500              ),
117
             .CLKOUT1_DUTY_CYCLE ( 0.500              ),
118
             .CLKOUT2_DUTY_CYCLE ( 0.500              ),
119
             .CLKOUT3_DUTY_CYCLE ( 0.500              ),
120
             .CLKOUT4_DUTY_CYCLE ( 0.500              ),
121
             .CLKOUT5_DUTY_CYCLE ( 0.500              ),
122
             .COMPENSATION       ( "INTERNAL"         ),
123
             .DIVCLK_DIVIDE      ( 1                  ),
124
             .CLKFBOUT_MULT      ( 4                  ),   // 200 MHz clock input, x4 to get 800 MHz MCB
125
             .CLKFBOUT_PHASE     ( 0.0                ),
126
             .REF_JITTER         ( 0.005000           )
127
             )
128
            u_pll_adv
129
              (
130
               .CLKFBIN     ( clkfbout_clkfbin  ),
131
               .CLKINSEL    ( 1'b1              ),
132
               .CLKIN1      ( brd_clk_ibufg     ),
133
               .CLKIN2      ( 1'b0              ),
134
               .DADDR       ( 5'b0              ),
135
               .DCLK        ( 1'b0              ),
136
               .DEN         ( 1'b0              ),
137
               .DI          ( 16'b0             ),
138
               .DWE         ( 1'b0              ),
139
               .REL         ( 1'b0              ),
140
               .RST         ( i_brd_rst          ),
141
               .CLKFBDCM    (                   ),
142
               .CLKFBOUT    ( clkfbout_clkfbin  ),
143
               .CLKOUTDCM0  (                   ),
144
               .CLKOUTDCM1  (                   ),
145
               .CLKOUTDCM2  (                   ),
146
               .CLKOUTDCM3  (                   ),
147
               .CLKOUTDCM4  (                   ),
148
               .CLKOUTDCM5  (                   ),
149
               .CLKOUT0     (                   ),
150
               .CLKOUT1     (                   ),
151
               .CLKOUT2     ( pll_clk           ),
152
               .CLKOUT3     (                   ),
153
               .CLKOUT4     (                   ),
154
               .CLKOUT5     (                   ),
155
               .DO          (                   ),
156
               .DRDY        (                   ),
157
               .LOCKED      ( pll_locked        )
158
               );
159
    `endif
160
 
161
 
162
    `ifdef XILINX_VIRTEX6_FPGA
163
    // ======================================
164
    // Xilinx Virtex-6 PLL
165
    // ======================================
166
        MMCM_ADV #
167
        (
168
         .CLKIN1_PERIOD      ( 5                    ),   // 200 MHz
169
         .CLKOUT2_DIVIDE     ( `AMBER_CLK_DIVIDER   ),
170
         .CLKFBOUT_MULT_F    ( 5                    )    // 200 MHz x 5 = 1000 MHz
171
         )
172
        u_pll_adv
173
          (
174
           .CLKFBOUT     ( clkfbout_clkfbin ),
175
           .CLKFBOUTB    (                  ),
176
           .CLKFBSTOPPED (                  ),
177
           .CLKINSTOPPED (                  ),
178
           .CLKOUT0      (                  ),
179
           .CLKOUT0B     (                  ),
180
           .CLKOUT1      (                  ),
181
           .CLKOUT1B     (                  ),
182
           .CLKOUT2      ( pll_clk          ),
183
           .CLKOUT2B     (                  ),
184
           .CLKOUT3      (                  ),
185
           .CLKOUT3B     (                  ),
186
           .CLKOUT4      (                  ),
187
           .CLKOUT5      (                  ),
188
           .CLKOUT6      (                  ),
189
           .DRDY         (                  ),
190
           .LOCKED       ( pll_locked       ),
191
           .PSDONE       (                  ),
192
           .DO           (                  ),
193
           .CLKFBIN      ( clkfbout_clkfbin ),
194
           .CLKIN1       ( brd_clk_ibufg    ),
195
           .CLKIN2       ( 1'b0             ),
196
           .CLKINSEL     ( 1'b1             ),
197
           .DCLK         ( 1'b0             ),
198
           .DEN          ( 1'b0             ),
199
           .DWE          ( 1'b0             ),
200
           .PSCLK        ( 1'd0             ),
201
           .PSEN         ( 1'd0             ),
202
           .PSINCDEC     ( 1'd0             ),
203
           .PWRDWN       ( 1'd0             ),
204
           .RST          ( i_brd_rst         ),
205
           .DI           ( 16'b0            ),
206
           .DADDR        ( 7'b0             )
207
           );
208
    `endif
209
 
210
 
211
    BUFG u_bufg_sys_clk (
212
         .O ( o_sys_clk  ),
213
         .I ( pll_clk    )
214
         );
215
 
216
 
217
    // ======================================
218
    // Synchronous reset generation
219
    // ======================================
220
    assign rst_tmp = i_brd_rst | ~pll_locked;
221
 
222
      // synthesis attribute max_fanout of rst0_sync_r is 10
223
    always @(posedge o_sys_clk or posedge rst_tmp)
224
        if (rst_tmp)
225
          rst0_sync_r <= {RST_SYNC_NUM{1'b1}};
226
        else
227
          // logical left shift by one (pads with 0)
228
          rst0_sync_r <= rst0_sync_r << 1;
229
 
230
    always @(posedge o_sys_clk or posedge rst_tmp)
231
        if (rst_tmp)
232
            ddr_calib_done_sync_r <= {RST_SYNC_NUM{1'b0}};
233
        else
234
            ddr_calib_done_sync_r <= {ddr_calib_done_sync_r[RST_SYNC_NUM-2:0], i_ddr_calib_done};
235
 
236
    `endif
237
 
238
 
239
 
240
`ifndef XILINX_FPGA
241
 
242 14 csantifort
real      brd_clk_period = 6000;  // use starting value of 6000pS
243
real      pll_clk_period = 1000;  // use starting value of 1000pS
244
real      brd_temp;
245
reg       pll_clk_beh;
246
reg       sys_clk_beh;
247
integer   pll_div_count = 0;
248 2 csantifort
 
249 14 csantifort
// measure input clock period
250 2 csantifort
initial
251
    begin
252 14 csantifort
    @ (posedge i_brd_clk_p)
253
    brd_temp = $time;
254
    @ (posedge i_brd_clk_p)
255
    brd_clk_period = $time - brd_temp;
256
    pll_clk_period = brd_clk_period / 4;
257 2 csantifort
    end
258
 
259 14 csantifort
// Generate an 800MHz pll clock based off the input clock
260
always @( posedge i_brd_clk_p )
261
    begin
262
    pll_clk_beh = 1'd1;
263
    # ( pll_clk_period / 2 )
264
    pll_clk_beh = 1'd0;
265
    # ( pll_clk_period / 2 )
266
 
267
    pll_clk_beh = 1'd1;
268
    # ( pll_clk_period / 2 )
269
    pll_clk_beh = 1'd0;
270
    # ( pll_clk_period / 2 )
271
 
272
    pll_clk_beh = 1'd1;
273
    # ( pll_clk_period / 2 )
274
    pll_clk_beh = 1'd0;
275
    # ( pll_clk_period / 2 )
276
 
277
    pll_clk_beh = 1'd1;
278
    # ( pll_clk_period / 2 )
279
    pll_clk_beh = 1'd0;
280
 
281
    end
282
 
283
// Divide the pll clock down to get the system clock
284
always @( pll_clk_beh )
285
    begin
286
    if ( pll_div_count == (
287
        `AMBER_CLK_DIVIDER
288
        * 2 ) - 1 )
289
        pll_div_count <= 'd0;
290
    else
291
        pll_div_count <= pll_div_count + 1'd1;
292
 
293
    if ( pll_div_count == 0 )
294
        sys_clk_beh = 1'd1;
295
    else if ( pll_div_count ==
296
        `AMBER_CLK_DIVIDER
297
        )
298
        sys_clk_beh = 1'd0;
299
    end
300
 
301
assign o_sys_clk        = sys_clk_beh;
302 2 csantifort
assign rst0             = i_brd_rst;
303
assign calib_done_33mhz = 1'd1;
304
assign o_clk_200        = i_brd_clk_p;
305
 
306
`endif
307
 
308
 
309
endmodule
310
 
311
 

powered by: WebSVN 2.1.0

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