Root/lm32/logic/sakc/rtl/wb_ddr/ddr_clkgen.v

1//---------------------------------------------------------------------------
2// Wishbone DDR Controller
3//
4// (c) Joerg Bornschein (<jb@capsec.org>)
5//---------------------------------------------------------------------------
6
7`timescale 1ns / 1ps
8`include "ddr_include.v"
9
10module ddr_clkgen
11#(
12    parameter phase_shift = 0,
13    parameter clk_multiply = 13,
14    parameter clk_divide = 5
15) (
16    input clk,
17    input reset,
18    output locked,
19    //
20    output read_clk,
21    output write_clk,
22    output write_clk90,
23    // DCM phase shift control
24    output reg ps_ready,
25    input ps_up,
26    input ps_down
27);
28
29
30//----------------------------------------------------------------------------
31// ~133 MHz DDR Clock generator
32//----------------------------------------------------------------------------
33wire read_clk_u;
34wire dcm_fx_locked;
35
36DCM #(
37    .CLKDV_DIVIDE(2.0), // Divide by: 1.5,2.0,2.5,3.0,3.5,4.0,4.5,5.0,5.5,6.0,6.5
38                                 // 7.0,7.5,8.0,9.0,10.0,11.0,12.0,13.0,14.0,15.0 or 16.0
39    .CLKFX_DIVIDE(clk_divide), // Can be any integer from 1 to 32
40    .CLKFX_MULTIPLY(clk_multiply), // Can be any integer from 2 to 32
41    .CLKIN_DIVIDE_BY_2("FALSE"), // TRUE/FALSE to enable CLKIN divide by two feature
42    .CLKIN_PERIOD(), // Specify period of input clock
43    .CLKOUT_PHASE_SHIFT("NONE"), // Specify phase shift of NONE, FIXED or VARIABLE
44    .CLK_FEEDBACK("NONE"), // Specify clock feedback of NONE, 1X or 2X
45    .DESKEW_ADJUST("SOURCE_SYNCHRONOUS"), // SOURCE_SYNCHRONOUS, SYSTEM_SYNCHRONOUS or
46                                 // an integer from 0 to 15
47    .DFS_FREQUENCY_MODE("LOW"), // HIGH or LOW frequency mode for frequency synthesis
48    .DLL_FREQUENCY_MODE("LOW"), // HIGH or LOW frequency mode for DLL
49    .DUTY_CYCLE_CORRECTION("TRUE"), // Duty cycle correction, TRUE or FALSE
50    .FACTORY_JF(16'hC080), // FACTORY JF values
51    .PHASE_SHIFT(0), // Amount of fixed phase shift from -255 to 255
52    .STARTUP_WAIT("FALSE") // Delay configuration DONE until DCM LOCK, TRUE/FALSE
53) dcm_fx (
54    .DSSEN(),
55    .CLK0(), // 0 degree DCM CLK output
56    .CLK180(), // 180 degree DCM CLK output
57    .CLK270(), // 270 degree DCM CLK output
58    .CLK2X(), // 2X DCM CLK output
59    .CLK2X180(), // 2X, 180 degree DCM CLK out
60    .CLK90(), // 90 degree DCM CLK output
61    .CLKDV(), // Divided DCM CLK out (CLKDV_DIVIDE)
62    .CLKFX( read_clk_u ), // DCM CLK synthesis out (M/D)
63    .CLKFX180(), // 180 degree CLK synthesis out
64    .LOCKED( dcm_fx_locked), // DCM LOCK status output
65    .PSDONE(), // Dynamic phase adjust done output
66    .STATUS(), // 8-bit DCM status bits output
67    .CLKFB(), // DCM clock feedback
68    .CLKIN( clk ), // Clock input (from IBUFG, BUFG or DCM)
69    .PSCLK( gnd ), // Dynamic phase adjust clock input
70    .PSEN( gnd ), // Dynamic phase adjust enable input
71    .PSINCDEC( gnd ), // Dynamic phase adjust increment/decrement
72    .RST( reset ) // DCM asynchronous reset input
73);
74
75//----------------------------------------------------------------------------
76// BUFG read clock
77//----------------------------------------------------------------------------
78BUFG bufg_fx_clk (
79    .O(read_clk), // Clock buffer output
80    .I(read_clk_u) // Clock buffer input
81);
82
83//----------------------------------------------------------------------------
84// Phase shifted clock for write path
85//----------------------------------------------------------------------------
86wire phase_dcm_reset;
87wire phase_dcm_locked;
88wire write_clk_u, write_clk90_u, write_clk180_u, write_clk270_u;
89reg psen, psincdec;
90wire psdone;
91
92DCM #(
93    .CLKDV_DIVIDE(2.0), // Divide by: 1.5,2.0,2.5,3.0,3.5,4.0,4.5,5.0,5.5,6.0,6.5
94                            // 7.0,7.5,8.0,9.0,10.0,11.0,12.0,13.0,14.0,15.0 or 16.0
95    .CLKFX_DIVIDE(2), // Can be any integer from 1 to 32
96    .CLKFX_MULTIPLY(2), // Can be any integer from 2 to 32
97    .CLKIN_DIVIDE_BY_2("FALSE"), // TRUE/FALSE to enable CLKIN divide by two feature
98    .CLKIN_PERIOD(), // Specify period of input clock
99    .CLK_FEEDBACK("1X"), // Specify clock feedback of NONE, 1X or 2X
100    .DESKEW_ADJUST("SYSTEM_SYNCHRONOUS"), // SOURCE_SYNCHRONOUS, SYSTEM_SYNCHRONOUS or
101                                          // an integer from 0 to 15
102    .DFS_FREQUENCY_MODE("LOW"), // HIGH or LOW frequency mode for frequency synthesis
103    .DLL_FREQUENCY_MODE("LOW"), // HIGH or LOW frequency mode for DLL
104    .DUTY_CYCLE_CORRECTION("TRUE"), // Duty cycle correction, TRUE or FALSE
105    .FACTORY_JF(16'hC080), // FACTORY JF values
106    .CLKOUT_PHASE_SHIFT("VARIABLE"), // Specify phase shift of NONE, FIXED or VARIABLE
107    .PHASE_SHIFT( phase_shift ), // Amount of fixed phase shift from -255 to 255
108    .STARTUP_WAIT("FALSE") // Delay configuration DONE until DCM LOCK, TRUE/FALSE
109) dcm_phase (
110    .DSSEN(),
111    .CLK0( write_clk_u ), // 0 degree DCM CLK output
112    .CLK90( write_clk90_u ), // 90 degree DCM CLK output
113    .CLK180( write_clk180_u ), // 180 degree DCM CLK output
114    .CLK270( write_clk270_u ), // 270 degree DCM CLK output
115    .CLK2X(), // 2X DCM CLK output
116    .CLK2X180(), // 2X, 180 degree DCM CLK out
117    .CLKDV(), // Divided DCM CLK out (CLKDV_DIVIDE)
118    .CLKFX(), // DCM CLK synthesis out (M/D)
119    .CLKFX180(), // 180 degree CLK synthesis out
120    .LOCKED( phase_dcm_locked ), // DCM LOCK status output
121    .STATUS(), // 8-bit DCM status bits output
122    .CLKFB( write_clk ), // DCM clock feedback
123    .CLKIN( read_clk ), // Clock input (from IBUFG, BUFG or DCM)
124    .PSCLK( clk ), // Dynamic phase adjust clock input
125    .PSEN( psen ), // Dynamic phase adjust enable input
126    .PSINCDEC( psincdec ), // Dynamic phase adjust increment/decrement
127    .PSDONE( psdone ), // Dynamic phase adjust done output
128    .RST( phase_dcm_reset ) // DCM asynchronous reset input
129);
130
131// delayed reset for phase shifting DCM
132reg [3:0] reset_counter;
133assign phase_dcm_reset = reset | (reset_counter != 0);
134
135always @(posedge clk)
136begin
137    if (reset)
138        reset_counter <= 1;
139    else begin
140        if (dcm_fx_locked & (reset_counter != 0))
141            reset_counter <= reset_counter + 1;
142    end
143end
144
145//----------------------------------------------------------------------------
146// DCM phase shifting state machine
147//----------------------------------------------------------------------------
148parameter s_init = 0;
149parameter s_idle = 1;
150parameter s_waitdone = 2;
151parameter s_waitdone2= 3;
152
153reg [1:0] state;
154
155always @(posedge clk)
156begin
157    if (reset) begin
158        state <= s_init;
159        psen <= 0;
160        ps_ready <= 0;
161    end else begin
162        case (state)
163        s_init: begin
164            if (phase_dcm_locked) begin
165                ps_ready <= 1;
166                state <= s_idle;
167            end
168        end
169        s_idle: begin
170            if (ps_up) begin
171                ps_ready <= 0;
172                psen <= 1;
173                psincdec <= 1;
174                state <= s_waitdone;
175            end else if (ps_down) begin
176                ps_ready <= 0;
177                psen <= 1;
178                psincdec <= 0;
179                state <= s_waitdone;
180            end
181        end
182        s_waitdone: begin
183            psen <= 0;
184            if (psdone) begin
185                state <= s_waitdone2;
186            end
187        end
188        s_waitdone2: begin
189            if (~ps_up && ~ps_down) begin
190                ps_ready <= 1;
191                state <= s_idle;
192            end
193        end
194        endcase
195    end
196end
197
198//----------------------------------------------------------------------------
199// BUFG write clock
200//----------------------------------------------------------------------------
201BUFG bufg_write_clk (
202    .O(write_clk ), // Clock buffer output
203    .I(write_clk_u) // Clock buffer input
204);
205
206BUFG bufg_write_clk90 (
207    .O(write_clk90 ), // Clock buffer output
208    .I(write_clk90_u) // Clock buffer input
209);
210
211//----------------------------------------------------------------------------
212// LOCKED logic
213//----------------------------------------------------------------------------
214reg phase_dcm_locked_delayed;
215
216always @(posedge write_clk)
217begin
218    phase_dcm_locked_delayed <= phase_dcm_locked;
219end
220
221assign locked = ~reset & phase_dcm_locked_delayed;
222
223
224endmodule
225

Archive Download this file

Branches:
master



interactive