1`timescale 1ns / 1ps
2
3//
4// * Programmable clock for internal parts of application
5// * Wide range of possible frequencies 135..355 MHz
6// * Programmable with step ~0.5-1 Mhz until ~300 Mhz
7// * Everything calculated for FREQ_IN=48
8//
9module cmt_prog #(
10	parameter FREQ_IN = 48,
11	parameter F = 225, // 1. Set startup frequency
12	// 2. Adjust timing constraint in UCF file!
13	parameter M =
14		F >=275 ? 38 :	F >=270 ? 32 :	F >=265 ? 34 :	F >=260 ? 35 :
15		F >=255 ? 21 :	F >=250 ? 37 :	F >=245 ? 25 :	F >=240 ? 30 :
16		F >=235 ? 34 :	F >=230 ? 31 :	F >=225 ? 20 :	F >=220 ? 21 :
17		F >=215 ? 29 :	F >=210 ? 38 :	F >=205 ? 33 :	F >=200 ? 27 :
18		F >=195 ? 25 :	F >=190 ? 35 :	F >=185 ? 31 :	F >=180 ? 29 :
19		F >=175 ? 38 :	F >=170 ? 33 :	F >=165 ? 38 :	F >=160 ? 30 :
20		F >=155 ? 25 :	F >=150 ? 39 :	F >=145 ? 31 :	F >=140 ? 35 :
21	36, // default:135 MHz
22	parameter D =
23		F >=275 ? 42 :	F >=270 ? 36 :	F >=265 ? 39 :	F >=260 ? 41 :
24		F >=255 ? 25 :	F >=250 ? 45 :	F >=245 ? 31 :	F >=240 ? 38 :
25		F >=235 ? 44 :	F >=230 ? 41 :	F >=225 ? 27 :	F >=220 ? 29 :
26		F >=215 ? 41 :	F >=210 ? 55 :	F >=205 ? 49 :	F >=200 ? 41 :
27		F >=195 ? 39 :	F >=190 ? 56 :	F >=185 ? 51 :	F >=180 ? 49 :
28		F >=175 ? 66 :	F >=170 ? 59 :	F >=165 ? 70 :	F >=160 ? 57 :
29		F >=155 ? 49 :	F >=150 ? 79 :	F >=145 ? 65 :	F >=140 ? 76 :
30	81, // default:135 MHz
31	parameter PLL_CLKIN_PERIOD = 1000.0 / ((FREQ_IN+0.0) * (M+0.0) / (D+0.0))
32	)(
33	input I,
34	input progen, progdata, progclk,
35	input pll_reset,
36	input CE,
37	output progdone_inv,
38	output O
39	);
40
41	localparam DCM_CLKIN_PERIOD = 1000.0 / (FREQ_IN+0.0);
42
43	wire [2:1] dcm_status;
44
45	DCM_CLKGEN #(
46		.CLKFXDV_DIVIDE(2),       		// CLKFXDV divide value (2, 4, 8, 16, 32)
47		.CLKFX_DIVIDE( D ),			// Divide value - D - (1-256)
48		.CLKFX_MD_MAX(0.0),       		// Specify maximum M/D ratio for timing anlysis
49		.CLKFX_MULTIPLY( M ),        // Multiply value - M - (2-256)
50		.CLKIN_PERIOD(DCM_CLKIN_PERIOD),      // Input clock period specified in nS
51		.SPREAD_SPECTRUM("NONE"), 		// Spread Spectrum mode "NONE", "CENTER_LOW_SPREAD", "CENTER_HIGH_SPREAD",
52												// "VIDEO_LINK_M0", "VIDEO_LINK_M1" or "VIDEO_LINK_M2"
53		.STARTUP_WAIT("FALSE")    		// Delay config DONE until DCM_CLKGEN LOCKED (TRUE/FALSE)
54	) DCM_CLKGEN_0 (
55		.CLKFX( dcm0_clkfx ),           		// 1-bit output: Generated clock output
56		.CLKFX180(),    // 1-bit output: Generated clock output 180 degree out of phase from CLKFX.
57		.CLKFXDV(),   	// 1-bit output: Divided clock output
58		.LOCKED( dcm_locked ),       		// 1-bit output: Locked output
59		.PROGDONE( progdone ),  // 1-bit output: Active high output to indicate the successful re-programming
60		.STATUS( dcm_status ),             		// 2-bit output: DCM_CLKGEN status
61		.CLKIN( I ),          		// 1-bit input: Input clock
62		.FREEZEDCM(1'b0),      		// 1-bit input: Prevents frequency adjustments to input clock
63		.PROGCLK( progclk ),    		// 1-bit input: Clock input for M/D reconfiguration
64		.PROGDATA( progdata ),  // 1-bit input: Serial data input for M/D reconfiguration
65		.PROGEN( progen ),      // 1-bit input: Active high program enable
66		.RST(~dcm_locked & dcm_status[2])      // 1-bit input: Reset input pin
67	);
68
69	reg unprog = 1; // unprogrammed (after reset)
70	always @(posedge progclk)
71		if (progen)
72			unprog <= 0;
73	assign progdone_inv = ~(progdone | unprog);
74
75
76	// After clock is generated with CLKGEN
77	// and arrives into PLL the frequency is multiplied.
78	// PLL allows input frequency no less than 19 MHz,
79	// after multiplied internally it should be in range 400 - 1,080 MHz
80	//
81	// Fixed M=19, D=3 allows input to PLL 21..56 MHz, produces 133..355 MHz.
82	localparam PLL_MULTIPLY = 19;
83	localparam PLL_DIVIDE = 3;
84
85
86	// *********** Some black magic to avoid the error ****************
87	//
88	// Mapping design into LUTs...
89	// ERROR:LIT:664 - PLL_ADV symbol "clocks/cmt2/PLL_0/PLL_ADV" (output
90   //   signal=clocks/cmt2/PLL_0/CLKOUT3) has pin CLKOUT2 driving a BUFPLL. Only
91   //   CLKOUT0 and CLKOUT1 pins can drive a BUFPLL. Please modify your design to
92   //   avoid this unroutable situation.
93	// Errors found during logical drc.
94	(* BUFFER_TYPE="NONE" *) wire [4:0] dummy;
95	(* KEEP="true" *) wire dummy1 = ^dummy;
96
97	PLL_BASE #(
98		.BANDWIDTH("OPTIMIZED"),
99		.CLKFBOUT_MULT( PLL_MULTIPLY ),
100		.CLKOUT0_DIVIDE( PLL_DIVIDE ),
101		.CLKOUT0_DUTY_CYCLE(0.5),
102		.CLKIN_PERIOD( PLL_CLKIN_PERIOD ),
103		.CLK_FEEDBACK("CLKFBOUT"),
104		.COMPENSATION("DCM2PLL"),
105		.DIVCLK_DIVIDE(1),
106		.REF_JITTER(0.10),
107		.RESET_ON_LOSS_OF_LOCK("FALSE")
108	) PLL_0 (
109		.CLKFBOUT( pll0_clkfb ),
110		.CLKOUT0( pll0_clkout0 ),
111		.CLKOUT1(dummy[0]),
112		.CLKOUT2(dummy[1]),
113		.CLKOUT3(dummy[2]),
114		.CLKOUT4(dummy[3]),
115		.CLKOUT5(dummy[4]),
116		.LOCKED( pll_locked ),
117		.CLKFBIN( pll0_clkfb ),
118		.CLKIN( dcm0_clkfx ),
119		.RST(pll_reset | ~dcm_locked)
120	);
121
122	BUFGCE BUFGCE_inst (
123		.O(O),   // 1-bit output: Clock buffer output
124		.CE(pll_locked & CE), // 1-bit input: Clock buffer select
125		.I(pll0_clkout0)    // 1-bit input: Clock buffer input (S=0)
126	);
127
128
129endmodule
130