1428d7b3dSmrgautoload Cairo;
2428d7b3dSmrgimport Cairo;
3428d7b3dSmrglibrary "examples/sort.5c";
4428d7b3dSmrgimport Sort;
5428d7b3dSmrg
6428d7b3dSmrgint width = 1000, height = 200;
7428d7b3dSmrgint min_vco = 1400000000;
8428d7b3dSmrgint max_vco = 2800000000;
9428d7b3dSmrgint min = 0xffffffff;
10428d7b3dSmrgint max = 0;
11428d7b3dSmrg
12428d7b3dSmrgint max_clocks = 2000;
13428d7b3dSmrgint[4][max_clocks] clocks;
14428d7b3dSmrgint[4][max_clocks] vcos;
15428d7b3dSmrgint[4] clock_count = {0...};
16428d7b3dSmrg
17428d7b3dSmrgint[4] p2vals = {5,10,7,14};
18428d7b3dSmrg
19428d7b3dSmrgcairo_t cr = Cairo::new(width, height);
20428d7b3dSmrg
21428d7b3dSmrgvoid calc_p2(int p2i)
22428d7b3dSmrg{
23428d7b3dSmrg	int p2 = p2vals[p2i];
24428d7b3dSmrg	int min_p, max_p;
25428d7b3dSmrg
26428d7b3dSmrg	clocks[p2i] = (int [max_clocks]){0...};
27428d7b3dSmrg
28428d7b3dSmrg		if (p2 == 7 || p2 == 14) {
29428d7b3dSmrg		/* LVDS */
30428d7b3dSmrg		min_p = 7;
31428d7b3dSmrg		max_p = 98;
32428d7b3dSmrg	} else {
33428d7b3dSmrg		/* SDVO/DAC */
34428d7b3dSmrg		min_p = 5;
35428d7b3dSmrg		max_p = 80;
36428d7b3dSmrg	}
37428d7b3dSmrg
38428d7b3dSmrg	for (int m1 = 10; m1 <= 22; m1++) {
39428d7b3dSmrg		for (int m2 = 5; m2 <= 9; m2++) {
40428d7b3dSmrg			for (int n = 1; n <= 5; n++) {
41428d7b3dSmrg				for (int p1 = 1; p1 <= 8; p1++) {
42428d7b3dSmrg					int ref = 96000000;
43428d7b3dSmrg					int m = 5 * (m1 + 2) + (m2 + 2);
44428d7b3dSmrg					int p = p1 * p2;
45428d7b3dSmrg					int vco = floor(ref * m / (n + 2));
46428d7b3dSmrg					int clock = floor(vco / p);
47428d7b3dSmrg
48428d7b3dSmrg					if (p < min_p || p > max_p)
49428d7b3dSmrg						continue;
50428d7b3dSmrg					if (m < 70 || m > 120)
51428d7b3dSmrg						continue;
52428d7b3dSmrg					if (m2 > m1)
53428d7b3dSmrg						continue; /* won't happen */
54428d7b3dSmrg					if (vco < min_vco || vco > max_vco)
55428d7b3dSmrg						continue;
56428d7b3dSmrg
57428d7b3dSmrg/*
58428d7b3dSmrg					printf("clock: %d (%d,%d), %d, "
59428d7b3dSmrg						"(%d,%d)\n",
60428d7b3dSmrg						floor(clock / 1000),
61428d7b3dSmrg						m1, m2, n, p1, p2);
62428d7b3dSmrg*/
63428d7b3dSmrg
64428d7b3dSmrg					clocks[p2i][clock_count[p2i]] = clock;
65428d7b3dSmrg					vcos[p2i][clock_count[p2i]] = vco;
66428d7b3dSmrg					clock_count[p2i]++;
67428d7b3dSmrg				}
68428d7b3dSmrg			}
69428d7b3dSmrg		}
70428d7b3dSmrg	}
71428d7b3dSmrg}
72428d7b3dSmrg
73428d7b3dSmrgbool sort_p2(poly a, poly b)
74428d7b3dSmrg{
75428d7b3dSmrg	return a > b;
76428d7b3dSmrg}
77428d7b3dSmrg
78428d7b3dSmrgint min_rate = 25000 * 1000;
79428d7b3dSmrgint max_rate = 200000 * 1000;
80428d7b3dSmrg
81428d7b3dSmrgreal scale_x(real clock)
82428d7b3dSmrg{
83428d7b3dSmrg	int min_x = 75, max_x = width - 50;
84428d7b3dSmrg
85428d7b3dSmrg	real frac = (clock - min_rate) / (max_rate - min_rate);
86428d7b3dSmrg
87428d7b3dSmrg	return min_x + frac * (max_x - min_x);
88428d7b3dSmrg}
89428d7b3dSmrg
90428d7b3dSmrgfor (p2i = 0; p2i < dim(p2vals); p2i++) {
91428d7b3dSmrg	int p2 = p2vals[p2i]; 
92428d7b3dSmrg	calc_p2(p2i);
93428d7b3dSmrg	real row_y1 = (p2i + 1) / (dim(p2vals) + 1) * height;
94428d7b3dSmrg	real row_y2 = p2i / (dim(p2vals) + 1) * height;
95428d7b3dSmrg
96428d7b3dSmrg	/*qsort(&p2vals[p2i], sort_p2);*/
97428d7b3dSmrg
98428d7b3dSmrg	switch (p2) {
99428d7b3dSmrg	case 5:
100428d7b3dSmrg		set_source_rgb(cr, 1,0,0);
101428d7b3dSmrg		break;
102428d7b3dSmrg	case 10:
103428d7b3dSmrg		set_source_rgb(cr, 0,1,0);
104428d7b3dSmrg		break;
105428d7b3dSmrg	case 7:
106428d7b3dSmrg		set_source_rgb(cr, 0,0,1);
107428d7b3dSmrg		break;
108428d7b3dSmrg	case 14:
109428d7b3dSmrg		set_source_rgb(cr, 0,0,0);
110428d7b3dSmrg		break;
111428d7b3dSmrg	}
112428d7b3dSmrg
113428d7b3dSmrg	/* draw the line for the clock */
114428d7b3dSmrg	for (int i = 0; i < clock_count[p2i]; i++) {
115428d7b3dSmrg		int clock = clocks[p2i][i];
116428d7b3dSmrg		real xpos;
117428d7b3dSmrg
118428d7b3dSmrg		if (clock < min_rate || clock > max_rate)
119428d7b3dSmrg			continue;
120428d7b3dSmrg
121428d7b3dSmrg		xpos = scale_x(clock);
122428d7b3dSmrg		move_to(cr, xpos, row_y1);
123428d7b3dSmrg		line_to(cr, xpos, row_y2);
124428d7b3dSmrg		stroke(cr);
125428d7b3dSmrg	}
126428d7b3dSmrg
127428d7b3dSmrg	set_source_rgb(cr, 1, 1, 1);
128428d7b3dSmrg	/* add a mark for the vco value of the clocks at each location */
129428d7b3dSmrg	for (int i = 0; i < clock_count[p2i]; i++) {
130428d7b3dSmrg		int clock = clocks[p2i][i];
131428d7b3dSmrg		int vco = vcos[p2i][i];
132428d7b3dSmrg		real mark_center;
133428d7b3dSmrg
134428d7b3dSmrg		if (clock < min_rate || clock > max_rate)
135428d7b3dSmrg			continue;
136428d7b3dSmrg
137428d7b3dSmrg		real xpos = scale_x(clock);
138428d7b3dSmrg		real vcofrac = (vco - min_vco) / (max_vco - min_vco);
139428d7b3dSmrg		real mark_height = (row_y1 + vcofrac * (row_y2 - row_y1));
140428d7b3dSmrg
141428d7b3dSmrg		move_to(cr, xpos, mark_height - 1);
142428d7b3dSmrg		line_to(cr, xpos, mark_height + 1);
143428d7b3dSmrg		stroke(cr);
144428d7b3dSmrg	}
145428d7b3dSmrg
146428d7b3dSmrg	set_source_rgb(cr, 0, 0, 0);
147428d7b3dSmrg	string p2label = sprintf("p2 = %d", p2);
148428d7b3dSmrg	move_to(cr, 5, (p2i + .5) / (dim(p2vals) + 1) * height + 4);
149428d7b3dSmrg	show_text(cr, p2label);
150428d7b3dSmrg}
151428d7b3dSmrg
152428d7b3dSmrgvoid label_clock(real clock) {
153428d7b3dSmrg	real center_x = scale_x(clock);
154428d7b3dSmrg	string label = sprintf("%d", floor((clock + 500) / 1000000));
155428d7b3dSmrg		text_extents_t e = text_extents(cr, label);
156428d7b3dSmrg	real left_x = center_x - e.x_advance / 2;
157428d7b3dSmrg	save(cr);
158428d7b3dSmrg	move_to(cr, left_x, height - 20);
159428d7b3dSmrg	show_text(cr, label);
160428d7b3dSmrg	restore(cr);
161428d7b3dSmrg}
162428d7b3dSmrg
163428d7b3dSmrglabel_clock(min_rate);
164428d7b3dSmrglabel_clock(max_rate);
165428d7b3dSmrglabel_clock(140 * 1000 * 1000);
166428d7b3dSmrglabel_clock(115 * 1000 * 1000);
167428d7b3dSmrglabel_clock(100 * 1000 * 1000);
168428d7b3dSmrglabel_clock(82 * 1000 * 1000);
169428d7b3dSmrg
170428d7b3dSmrgstring xlabel = "Clock in Mhz";
171428d7b3dSmrgtext_extents_t e = text_extents(cr, xlabel);
172428d7b3dSmrgmove_to(cr, width / 2 - e.x_advance / 2, height - 5);
173428d7b3dSmrgshow_text(cr, xlabel);
174428d7b3dSmrgsleep(10);
175