Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

fhdl: add EDIF back-end

  • Loading branch information...
commit 17002fb05e6f15632beb2904057de0420da83a3f 1 parent 246b860
@nakengelhardt nakengelhardt authored sbourdeauducq committed
Showing with 192 additions and 0 deletions.
  1. +192 −0 migen/fhdl/edif.py
View
192 migen/fhdl/edif.py
@@ -0,0 +1,192 @@
+from collections import OrderedDict
+from migen.fhdl.std import *
+from migen.fhdl.namer import build_namespace
+from migen.fhdl.tools import list_special_ios
+from migen.fhdl.structure import _Fragment
+
+from collections import namedtuple
+
+_Port = namedtuple("_Port", "name direction")
+_Cell = namedtuple("_Cell", "name ports")
+_Property = namedtuple("_Property", "name value")
+_Instance = namedtuple("_Instance", "name cell properties")
+_NetBranch = namedtuple("_NetBranch", "portname instancename")
+
+def _write_cells(cells):
+ r = ""
+ for cell in cells:
+ r += """
+ (cell {0.name}
+ (cellType GENERIC)
+ (view view_1
+ (viewType NETLIST)
+ (interface""".format(cell)
+ for port in cell.ports:
+ r += """
+ (port {0.name} (direction {0.direction}))""".format(port)
+ r += """
+ )
+ )
+ )"""
+ return r
+
+def _write_io(ios):
+ r = ""
+ for s in ios:
+ r += """
+ (port {0.name} (direction {0.direction}))""".format(s)
+ return r
+
+def _write_instantiations(instances, cell_library):
+ instantiations = ""
+ for instance in instances:
+ instantiations += """
+ (instance {0.name}
+ (viewRef view_1 (cellRef {0.cell} (libraryRef {1})))""".format(instance, cell_library)
+ for prop in instance.properties:
+ instantiations += """
+ (property {0} (string "{1}"))""".format(prop.name, prop.value)
+ instantiations += """
+ )"""
+ return instantiations
+
+def _write_connections(connections):
+ r = ""
+ for netname, branches in connections.items():
+ r += """
+ (net {0}
+ (joined""".format(netname)
+ for branch in branches:
+ r += """
+ (portRef {0}{1})""".format(branch.portname, "" if branch.instancename == "" else " (instanceRef {})".format(branch.instancename))
+ r += """
+ )
+ )"""
+ return r
+
+def _write_edif(cells, ios, instances, connections, cell_library, design_name, part, vendor):
+ r = """(edif {0}
+ (edifVersion 2 0 0)
+ (edifLevel 0)
+ (keywordMap (keywordLevel 0))
+ (external {1}
+ (edifLevel 0)
+ (technology (numberDefinition))""".format(design_name, cell_library)
+ r += _write_cells(cells)
+ r += """
+ )
+ (library {0}_lib
+ (edifLevel 0)
+ (technology (numberDefinition))
+ (cell {0}
+ (cellType GENERIC)
+ (view view_1
+ (viewType NETLIST)
+ (interface""".format(design_name)
+ r += _write_io(ios)
+ r += """
+ (designator "{0}")
+ )
+ (contents""".format(part)
+ r += _write_instantiations(instances, cell_library)
+ r += _write_connections(connections)
+ r += """
+ )
+ )
+ )
+ )
+ (design {0}
+ (cellRef {0} (libraryRef {0}_lib))
+ (property PART (string "{1}") (owner "{2}"))
+ )
+)""".format(design_name, part, vendor)
+
+ return r
+
+def _generate_cells(f):
+ cell_dict = OrderedDict()
+ for special in f.specials:
+ if isinstance(special, Instance):
+ port_list = []
+ for port in special.items:
+ if isinstance(port, Instance.Input):
+ port_list.append(_Port(port.name, "INPUT"))
+ elif isinstance(port, Instance.Output):
+ port_list.append(_Port(port.name, "OUTPUT"))
+ elif isinstance(port, Instance.Parameter):
+ pass
+ else:
+ raise NotImplementedError("Unsupported instance item")
+ if special.of in cell_dict:
+ if set(port_list) != set(cell_dict[special.of]):
+ raise ValueError("All instances must have the same ports for EDIF conversion")
+ else:
+ cell_dict[special.of] = port_list
+ else:
+ raise ValueError("Edif conversion can only handle synthesized fragments")
+ return [_Cell(k, v) for k, v in cell_dict.items()]
+
+def _generate_instances(f,ns):
+ instances = []
+ for special in f.specials:
+ if isinstance(special, Instance):
+ props = []
+ for prop in special.items:
+ if isinstance(prop, Instance.Input):
+ pass
+ elif isinstance(prop, Instance.Output):
+ pass
+ elif isinstance(prop, Instance.Parameter):
+ props.append(_Property(name=prop.name, value=prop.value))
+ else:
+ raise NotImplementedError("Unsupported instance item")
+ instances.append(_Instance(name=ns.get_name(special), cell=special.of, properties=props))
+ else:
+ raise ValueError("Edif conversion can only handle synthesized fragments")
+ return instances
+
+def _generate_ios(f, ios, ns):
+ outs = list_special_ios(f, False, True, False)
+ r = []
+ for io in ios:
+ direction = "OUTPUT" if io in outs else "INPUT"
+ r.append(_Port(name=ns.get_name(io), direction=direction))
+ return r
+
+def _generate_connections(f, ios, ns):
+ r = OrderedDict()
+ for special in f.specials:
+ if isinstance(special, Instance):
+ instname = ns.get_name(special)
+ for port in special.items:
+ if isinstance(port, Instance.Input) or isinstance(port, Instance.Output):
+ s = ns.get_name(port.expr)
+ if s not in r:
+ r[s] = []
+ r[s].append(_NetBranch(portname=port.name, instancename=instname))
+ elif isinstance(port, Instance.Parameter):
+ pass
+ else:
+ raise NotImplementedError("Unsupported instance item")
+ else:
+ raise ValueError("Edif conversion can only handle synthesized fragments")
+ for s in ios:
+ io = ns.get_name(s)
+ if io not in r:
+ r[io] = []
+ r[io].append(_NetBranch(portname=io, instancename=""))
+ return r
+
+def convert(f, ios, name, cell_library, part, vendor):
+ if not isinstance(f, _Fragment):
+ f = f.get_fragment()
+ if f.comb != [] or f.sync != {}:
+ raise ValueError("Edif conversion can only handle synthesized fragments")
+ if ios is None:
+ ios = set()
+ cells = _generate_cells(f)
+ ns = build_namespace(list_special_ios(f, True, True, True))
+ instances = _generate_instances(f, ns)
+ inouts = _generate_ios(f, ios, ns)
+ connections = _generate_connections(f, ios, ns)
+ return _write_edif(cells, inouts, instances, connections, cell_library, name, part, vendor)

0 comments on commit 17002fb

Please sign in to comment.
Something went wrong with that request. Please try again.