|
|
@@ -3,17 +3,22 @@ A module that allows the creation of a C file, in which the block's computations
|
|
|
"""
|
|
|
from CBD.scheduling import TopologicalScheduler
|
|
|
from CBD.solver import GaussianJordanLinearSolver
|
|
|
-from CBD.depGraph import DepGraph, createDepGraph
|
|
|
-from CBD.converters.latexify import CBD2Latex
|
|
|
+from CBD.depGraph import DepGraph, createDepGraph, gvDepGraph
|
|
|
+from CBD.converters.latexify import CBD2Latex, _BLOCK_MAP
|
|
|
+import CBD.naivelog as naivelog
|
|
|
|
|
|
from jinja2 import Template
|
|
|
|
|
|
class CBD2C:
|
|
|
- def __init__(self, model, itcnt):
|
|
|
+ def __init__(self, model, itcnt, delta=1.0):
|
|
|
self.itcnt = itcnt
|
|
|
+ self.delta = 1.0
|
|
|
self.model = model.clone()
|
|
|
self.model.flatten(psep='_')
|
|
|
+ for block in self.model.getBlocks():
|
|
|
+ block.setBlockName(block.getBlockName().replace("-", "_"))
|
|
|
self.scheduler = TopologicalScheduler()
|
|
|
+ self.solver = GaussianJordanLinearSolver(naivelog.getLogger("CBD"))
|
|
|
|
|
|
def get_blocks(self):
|
|
|
return self.model.getBlocks()
|
|
|
@@ -22,13 +27,97 @@ class CBD2C:
|
|
|
depGraph = createDepGraph(self.model, curIt)
|
|
|
return self.scheduler.schedule(depGraph, curIt, 0.0)
|
|
|
|
|
|
+ @staticmethod
|
|
|
+ def flatten(t):
|
|
|
+ return [item for sublist in t for item in sublist]
|
|
|
+
|
|
|
+ def obtain_data_from_order(self, order, curIt):
|
|
|
+ i = "0" if curIt == 0 else "i"
|
|
|
+ conf = {"path_sep": '_', "ignore_path": False, "escape_nonlatex": False, "time_variable": "time"}
|
|
|
+ norder = []
|
|
|
+ for c in order:
|
|
|
+ nc = []
|
|
|
+ if len(c) == 1 and c[0] not in [c[0].getBlockConnectedToInput(x).block for x in c[0].getInputPortNames()]:
|
|
|
+ n = c[0]
|
|
|
+ bd = CBD2Latex.get_block_data(n, self.model, conf)
|
|
|
+ if bd is None:
|
|
|
+ if n.getBlockType() == "WireBlock":
|
|
|
+ bl = n.getBlockConnectedToInput("IN1")
|
|
|
+ nc = ([n.getPath('_')], bl.block.getPath('_') + '_' + bl.output_port + '[' + i + ']')
|
|
|
+ else:
|
|
|
+ kv = {x: n.getBlockConnectedToInput(x) for x in n.getInputPortNames()}
|
|
|
+ for k, v in kv.items():
|
|
|
+ bd[1].apply(n.getPath('_') + '_' + k, v.block.getPath('_') + '_' + v.output_port)
|
|
|
+ if n.getBlockType() == "DelayBlock":
|
|
|
+ if curIt == 0:
|
|
|
+ bd[1].apply_time(time=-1, t=i, fmt="[{time}]")
|
|
|
+ bd = bd[0], bd[1].args[1]
|
|
|
+ else:
|
|
|
+ bd[1].apply_time(t=i, fmt="[{time}]")
|
|
|
+ bd = bd[0], bd[1].args[0]
|
|
|
+ try:
|
|
|
+ bd[1].apply_time(t=i, fmt="[{time}]")
|
|
|
+ except: pass
|
|
|
+ nc = ([bd[0]], str(bd[1]))
|
|
|
+ if n.getBlockType() != "WireBlock":
|
|
|
+ n.compute(curIt)
|
|
|
+ else:
|
|
|
+ self.solver.checkValidity(self.model.getPath("."), c)
|
|
|
+
|
|
|
+ # Get matrix representation
|
|
|
+ m1, m2 = self.solver.constructInput(c, curIt)
|
|
|
+ mat = []
|
|
|
+ for r in range(m1.rows):
|
|
|
+ row = []
|
|
|
+ for col in range(m1.cols):
|
|
|
+ row.append(float(m1[r, col]))
|
|
|
+ row.append(float(m2[r]))
|
|
|
+ mat.append(row)
|
|
|
+
|
|
|
+ deps = {}
|
|
|
+ for b in c:
|
|
|
+ D = [b.getBlockConnectedToInput(x) for x in b.getInputPortNames()]
|
|
|
+ deps[b] = [b.block.getPath('_') + '_' + b.output_port for b in D if b.block in c]
|
|
|
+
|
|
|
+ if len(mat) == 1:
|
|
|
+ nc = ([deps[c[mat[0].index(1)]]], mat[0][-1])
|
|
|
+ else:
|
|
|
+ dlist = []
|
|
|
+ for b in c:
|
|
|
+ for d in deps[b]:
|
|
|
+ if d not in dlist:
|
|
|
+ dlist.append(d)
|
|
|
+
|
|
|
+ nc = (dlist, str(mat).replace("[", "{").replace("]", "}"))
|
|
|
+ norder.append(nc)
|
|
|
+ print(norder)
|
|
|
+ return norder
|
|
|
+
|
|
|
def generate(self, fname):
|
|
|
with open("template.c", 'r') as file:
|
|
|
template = Template(file.read(), trim_blocks=True, lstrip_blocks=True)
|
|
|
+ variables = []
|
|
|
+ for block in self.get_blocks():
|
|
|
+ if block.getBlockType() == "WireBlock":
|
|
|
+ variables.append(block.getPath('_'))
|
|
|
+ continue
|
|
|
+ for port in block.getSignals().keys():
|
|
|
+ variables.append(block.getPath('_') + '_' + port)
|
|
|
+
|
|
|
+ # Obtain the data
|
|
|
+ comp0 = self.get_order(0)
|
|
|
+ comp = self.get_order(1)
|
|
|
+ self.model.addFixedRateClock()
|
|
|
+ comp0 = self.obtain_data_from_order(comp0, 0)
|
|
|
+ comp = self.obtain_data_from_order(comp, 1)
|
|
|
+
|
|
|
+ # print(comp0)
|
|
|
+
|
|
|
contents = template.render(itcnt = self.itcnt,
|
|
|
- blocks = self.get_blocks(),
|
|
|
- components0 = self.get_order(0),
|
|
|
- components = self.get_order(1) )
|
|
|
+ delta = self.delta,
|
|
|
+ variables = variables,
|
|
|
+ components0 = comp0,
|
|
|
+ components = comp )
|
|
|
with open(fname, 'w') as file:
|
|
|
file.write(contents)
|
|
|
|
|
|
@@ -39,35 +128,21 @@ if __name__ == '__main__':
|
|
|
def __init__(self, name):
|
|
|
super().__init__(name, [], ["x"])
|
|
|
self.addBlock(AdderBlock("A"))
|
|
|
- self.addBlock(ProductBlock("B"))
|
|
|
+ # self.addBlock(ProductBlock("B"))
|
|
|
+ # self.addConnection("A", "A")
|
|
|
+ # self.addConnection("A", "B")
|
|
|
+ # self.addConnection("B", "A")
|
|
|
+ # self.addConnection("B", "B")
|
|
|
+ # self.addBlock(ProductBlock("B"))
|
|
|
self.addBlock(ConstantBlock("C", 3.0))
|
|
|
self.addBlock(ConstantBlock("D", 6.0))
|
|
|
self.addConnection("C", "A")
|
|
|
- self.addConnection("B", "A")
|
|
|
- self.addConnection("A", "B")
|
|
|
- self.addConnection("D", "B")
|
|
|
- self.addConnection("B", "x")
|
|
|
+ # self.addConnection("B", "A")
|
|
|
+ # self.addConnection("A", "B")
|
|
|
+ self.addConnection("D", "A")
|
|
|
+ self.addConnection("A", "x")
|
|
|
|
|
|
test = Test("test")
|
|
|
- ltx = CBD2Latex(test, render_latex=False, escape_nonlatex=False, path_sep='_', ignore_path=False)
|
|
|
- ltx.simplify_links()
|
|
|
- print(ltx.equations)
|
|
|
gen = CBD2C(test, 3000)
|
|
|
gen.generate("example.c")
|
|
|
- for block in gen.get_blocks():
|
|
|
- try:
|
|
|
- print(block.getBlockConnectedToInput("IN1"))
|
|
|
- except: pass
|
|
|
- # sol = GaussianJordanLinearSolver(None)
|
|
|
- # # block = gen.get_blocks()
|
|
|
- # for comp in gen.get_order(0):
|
|
|
- # print("--------------")
|
|
|
- # if len(comp) == 1:
|
|
|
- # print(comp[0])
|
|
|
- # comp[0].compute(0)
|
|
|
- # else:
|
|
|
- # m1, m2 = sol.constructInput(comp, 0)
|
|
|
- # print(m1)
|
|
|
- # print(m2)
|
|
|
- #
|
|
|
- # # TODO: Generate header file with all #defines
|
|
|
+
|