+#!/usr/bin/nickle
+
+real
+pll_out(real clock_in, int mul, int div)
+{
+ return clock_in * mul / div;
+}
+
+real
+pll_in(real pll_out, int mul, int div)
+{
+ return pll_out * div / mul;
+}
+
+real
+fcco_out(real clock_in, int mul, int div)
+{
+ real out = pll_out(clock_in, mul, div);
+ return out * div;
+}
+
+bool
+valid_clock_in(real clock_in)
+{
+ return 10 <= clock_in && clock_in < 25;
+}
+
+bool
+valid_fcco(real clock_in, int mul, int div)
+{
+ real fcco = fcco_out (clock_in, mul, div);
+ return 156 <= fcco && fcco <= 320;
+}
+
+void
+all_clocks(real clock_in) {
+ for (int mul = 1; mul <= 32; mul++) {
+ for (int div = 2; div <= 16; div *= 2) {
+ if (!valid_fcco(clock_in, mul, div))
+ printf ("clock_in %f mul %d div %d invalid fcco %f\n",
+ clock_in, mul, div, fcco_out(clock_in, mul, div));
+ else
+ printf ("clock_in %f mul %d div %d pll_out %f\n",
+ clock_in, mul, div, pll_out(clock_in, mul, div));
+ }
+ }
+}
+
+typedef struct {
+ real clock_in;
+ int mul;
+ int div;
+ real pll_out;
+} clock;
+
+clock[]
+all_ins(real pll_out)
+{
+ clock[...] clocks = {};
+ for (int mul = 1; mul <= 32; mul++) {
+ for (int div = 2; div <= 16; div *= 2) {
+ real clock_in = pll_in(pll_out, mul, div);
+ if (valid_clock_in(clock_in) && valid_fcco(clock_in, mul, div)) {
+ clocks[dim(clocks)] = (clock) {
+ .clock_in = clock_in,
+ .mul = mul,
+ .div = div,
+ .pll_out = pll_out
+ };
+ }
+ }
+ }
+ return clocks;
+}
+
+#all_clocks(12.0);
+
+autoload Sort;
+
+void
+dump_clocks(clock[] clocks)
+{
+ printf ("Clocks for %f\n", clocks[0].pll_out);
+ Sort::qsort(&clocks, bool func(clock a, clock b) { return a.clock_in > b.clock_in; });
+ for (int i = 0; i < dim (clocks); i++) {
+ printf("\tclock_in %f mul %d div %d\n",
+ clocks[i].clock_in,
+ clocks[i].mul,
+ clocks[i].div);
+ }
+}
+
+void
+find_clocks() {
+ clock[] c40 = all_ins(40.0);
+ clock[] c48 = all_ins(48.0);
+
+ dump_clocks(c40);
+ dump_clocks(c48);
+ for (int i40 = 0; i40 < dim(c40); i40++) {
+ for (int i48 = 0; i48 < dim(c48); i48++) {
+ if (c40[i40].clock_in == c48[i48].clock_in)
+ printf ("clock_in %f mul_40 %d div_40 %d mul_48 %d div_48 %d\n",
+ c40[i40].clock_in,
+ c40[i40].mul,
+ c40[i40].div,
+ c48[i48].mul,
+ c48[i48].div);
+ }
+ }
+}
+
+find_clocks();