altos/test: Adjust CRC error rate after FEC fix
[fw/altos] / src / lpc / clock_figure.5c
1 #!/usr/bin/nickle
2
3 real
4 pll_out(real clock_in, int mul, int div)
5 {
6         return clock_in * mul / div;
7 }
8
9 real
10 pll_in(real pll_out, int mul, int div)
11 {
12         return pll_out * div / mul;
13 }
14
15 real
16 fcco_out(real clock_in, int mul, int div)
17 {
18         real    out = pll_out(clock_in, mul, div);
19         return out * div;
20 }
21
22 bool
23 valid_clock_in(real clock_in)
24 {
25         return 10 <= clock_in && clock_in < 25;
26 }
27
28 bool
29 valid_fcco(real clock_in, int mul, int div)
30 {
31         real fcco = fcco_out (clock_in, mul, div);
32         return 156 <= fcco && fcco <= 320;
33 }
34
35 void
36 all_clocks(real clock_in) {
37         for (int mul = 1; mul <= 32; mul++) {
38                 for (int div = 2; div <= 16; div *= 2) {
39                         if (!valid_fcco(clock_in, mul, div))
40                                 printf ("clock_in %f mul  %d div %d invalid fcco %f\n",
41                                         clock_in, mul, div, fcco_out(clock_in, mul, div));
42                         else
43                                 printf ("clock_in %f mul %d div %d pll_out %f\n",
44                                         clock_in, mul, div, pll_out(clock_in, mul, div));
45                 }
46         }
47 }
48
49 typedef struct {
50         real    clock_in;
51         int     mul;
52         int     div;
53         real    pll_out;
54 } clock;
55
56 clock[]
57 all_ins(real pll_out)
58 {
59         clock[...] clocks = {};
60         for (int mul = 1; mul <= 32; mul++) {
61                 for (int div = 2; div <= 16; div *= 2) {
62                         real clock_in = pll_in(pll_out, mul, div);
63                         if (valid_clock_in(clock_in) && valid_fcco(clock_in, mul, div)) {
64                                 clocks[dim(clocks)] = (clock) {
65                                         .clock_in = clock_in,
66                                         .mul = mul,
67                                         .div = div,
68                                         .pll_out = pll_out
69                                 };
70                         }
71                 }
72         }
73         return clocks;
74 }
75
76 #all_clocks(12.0);
77
78 autoload Sort;
79
80 void
81 dump_clocks(clock[] clocks)
82 {
83         printf ("Clocks for %f\n", clocks[0].pll_out);
84         Sort::qsort(&clocks, bool func(clock a, clock b) { return a.clock_in > b.clock_in; });
85         for (int i = 0; i < dim (clocks); i++) {
86                 printf("\tclock_in %f mul %d div %d\n",
87                        clocks[i].clock_in,
88                        clocks[i].mul,
89                        clocks[i].div);
90         }
91 }
92
93 void
94 find_clocks() {
95         clock[] c40 = all_ins(40.0);
96         clock[] c48 = all_ins(48.0);
97
98         dump_clocks(c40);
99         dump_clocks(c48);
100         for (int i40 = 0; i40 < dim(c40); i40++) {
101                 for (int i48 = 0; i48 < dim(c48); i48++) {
102                         if (c40[i40].clock_in == c48[i48].clock_in)
103                                 printf ("clock_in %f mul_40 %d div_40 %d mul_48 %d div_48 %d\n",
104                                         c40[i40].clock_in,
105                                         c40[i40].mul,
106                                         c40[i40].div,
107                                         c48[i48].mul,
108                                         c48[i48].div);
109                 }
110         }
111 }
112
113 find_clocks();