--- /dev/null
+import copy
+import json
+
+from migen.fhdl.std import *
+from migen.genlib.cordic import Cordic
+from mibuild.generic_platform import *
+from mibuild.xilinx_ise import XilinxISEPlatform, CRG_SE
+
+
+class CordicImpl(Module):
+ def __init__(self, name, **kwargs):
+ self.name = name
+ json.dump(kwargs, open("build/{}.json".format(name), "w"))
+ self.platform = platform = Platform()
+ self.submodules.cordic = Cordic(**kwargs)
+ width = flen(self.cordic.xi)
+ self.comb += self.cordic.xi.eq(
+ int((1<<width - 1)/self.cordic.gain*.98))
+ self.comb += self.cordic.yi.eq(0)
+ zi = self.cordic.zi
+ self.sync += zi.eq(zi + 1)
+ do = platform.request("do")
+ self.sync += do.eq(Cat(self.cordic.xo, self.cordic.yo))
+
+ def build(self):
+ self.platform.build(self, build_name=self.name)
+
+class Platform(XilinxISEPlatform):
+ _io = [
+ ("clk", 0, Pins("AB13")),
+ ("rst", 0, Pins("V5")),
+ ("do", 0,
+ Pins("Y2 W3 W1 P8 P7 P6 P5 T4 T3",
+ "U4 V3 N6 N7 M7 M8 R4 P4 M6 L6 P3 N4",
+ "M5 V2 V1 U3 U1 T2 T1 R3 R1 P2 P1"),
+ ),
+ ]
+ def __init__(self):
+ XilinxISEPlatform.__init__(self, "xc6slx45-fgg484-2", self._io,
+ lambda p: CRG_SE(p, "clk", "rst", 10.))
+
+if __name__ == "__main__":
+ default = dict(width=16, guard=0, eval_mode="pipelined",
+ func_mode="circular", cordic_mode="rotate")
+ variations = dict(
+ eval_mode=["combinatorial", "pipelined", "iterative"],
+ width=[4, 8, 12, 14, 16, 20, 24, 32],
+ stages=[10, 12, 14, 16, 20, 24, 32],
+ guard=[0, 1, 2, 3, 4],
+ )
+ CordicImpl("cordic_test", eval_mode="combinatorial").build()
+
+ name = "cordic_baseline"
+ CordicImpl(name, **default).build()
+
+ for k, v in sorted(variations.items()):
+ for vi in v:
+ name = "cordic_{}_{}".format(k, vi)
+ kw = copy.copy(default)
+ kw[k] = vi
+ CordicImpl(name, **kw).build()
--- /dev/null
+import glob, os, re, json
+
+import numpy as np
+import matplotlib.pyplot as plt
+import pandas
+
+
+def extract(b, n, r, c=int):
+ r = re.compile(r)
+ try:
+ f = open(b + n)
+ except:
+ return
+ for l in f:
+ m = r.search(l)
+ if m:
+ v = m.groups()[0]
+ v = v.replace(",", "")
+ return c(v)
+
+def load(prefix, base):
+ kw = json.load(open(base))
+ b = os.path.splitext(base)[0]
+ _, n = os.path.split(b)[1].split("_", 1)
+ try:
+ n, _ = n.rsplit("_", 1)
+ kw["vary"] = n
+ except:
+ pass
+ kw["slack"] = extract(b, ".par",
+ "GRPclk.*SETUP +\\| +([\d,]+\\.\d+)", float)
+ kw["freq"] = extract(b, ".srp",
+ "Maximum Frequency: +([\d,]+\\.\d+) *MHz", float)
+ kw["reg"] = extract(b, "_map.mrp",
+ "Number of Slice Registers: +([\d,]+) ")
+ kw["lut"] = extract(b, "_map.mrp",
+ "Number of Slice LUTs: +([\d,]+) ")
+ kw["slice"] = extract(b, "_map.mrp",
+ "Number of occupied Slices: +([\d,]+) ")
+ return kw
+
+def run(prefix):
+ dat = {}
+ for base in glob.glob("build/{}_*.json".format(prefix)):
+ kw = load(prefix, base)
+ if "vary" in kw:
+ dat[base] = kw
+ df = pandas.DataFrame.from_dict(dat, orient="index")
+ comp = "freq slice slack".split()
+ dfg = df.groupby("vary")
+ fig, ax = plt.subplots(len(dfg), len(comp))
+ for axj, (v, dfi) in zip(ax, dfg):
+ print(v, dfi)
+ if v not in dfi:
+ continue
+ dfi = dfi.sort(v)
+ for axi, n in zip(axj, comp):
+ x = dfi[v]
+ if type(x[0]) is type(""):
+ xi = range(len(x))
+ axi.set_xticks(xi)
+ axi.set_xticklabels(x)
+ x = xi
+ axi.plot(x, dfi[n])
+ axi.set_xlabel(v)
+ axi.set_ylabel(n)
+ fig.savefig("cordic_impl.pdf")
+ plt.show()
+
+if __name__ == "__main__":
+ run("cordic")