Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

fhdl: add EDIF back-end

  • Loading branch information...
commit 17002fb05e6f15632beb2904057de0420da83a3f 1 parent 246b860
N. Engelhardt authored July 31, 2013 sbourdeauducq committed July 31, 2013

Showing 1 changed file with 192 additions and 0 deletions. Show diff stats Hide diff stats

  1. 192  migen/fhdl/edif.py
192  migen/fhdl/edif.py
... ...
@@ -0,0 +1,192 @@
  1
+from collections import OrderedDict
  2
+from migen.fhdl.std import *
  3
+from migen.fhdl.namer import build_namespace
  4
+from migen.fhdl.tools import list_special_ios
  5
+from migen.fhdl.structure import _Fragment
  6
+
  7
+from collections import namedtuple
  8
+
  9
+_Port = namedtuple("_Port", "name direction")
  10
+_Cell = namedtuple("_Cell", "name ports")
  11
+_Property = namedtuple("_Property", "name value")
  12
+_Instance = namedtuple("_Instance", "name cell properties")
  13
+_NetBranch = namedtuple("_NetBranch", "portname instancename")
  14
+  
  15
+def _write_cells(cells):
  16
+	r = ""
  17
+	for cell in cells:
  18
+		r += """
  19
+		(cell {0.name}
  20
+			(cellType GENERIC)
  21
+				(view view_1
  22
+					(viewType NETLIST)
  23
+					(interface""".format(cell)
  24
+		for port in cell.ports:
  25
+			r += """
  26
+						(port {0.name} (direction {0.direction}))""".format(port)
  27
+		r += """
  28
+					)
  29
+				)
  30
+		)"""
  31
+	return r
  32
+
  33
+def _write_io(ios):
  34
+	r = ""
  35
+	for s in ios:
  36
+		r += """
  37
+						(port {0.name} (direction {0.direction}))""".format(s)
  38
+	return r
  39
+
  40
+def _write_instantiations(instances, cell_library):
  41
+	instantiations = ""
  42
+	for instance in instances:
  43
+		instantiations += """
  44
+						(instance {0.name}
  45
+							(viewRef view_1 (cellRef {0.cell} (libraryRef {1})))""".format(instance, cell_library)
  46
+		for prop in instance.properties:
  47
+			instantiations += """
  48
+							(property {0} (string "{1}"))""".format(prop.name, prop.value)
  49
+		instantiations += """
  50
+						)"""
  51
+	return instantiations
  52
+
  53
+def _write_connections(connections):
  54
+	r = ""
  55
+	for netname, branches in connections.items():
  56
+		r += """
  57
+						(net {0}
  58
+							(joined""".format(netname)
  59
+		for branch in branches:
  60
+			r += """
  61
+								(portRef {0}{1})""".format(branch.portname, "" if branch.instancename == "" else " (instanceRef {})".format(branch.instancename))
  62
+		r += """
  63
+							)
  64
+						)"""
  65
+	return r
  66
+
  67
+def _write_edif(cells, ios, instances, connections, cell_library, design_name, part, vendor):
  68
+	r = """(edif {0}
  69
+	(edifVersion 2 0 0)
  70
+	(edifLevel 0)
  71
+	(keywordMap (keywordLevel 0))
  72
+	(external {1}
  73
+		(edifLevel 0)
  74
+		(technology (numberDefinition))""".format(design_name, cell_library)
  75
+	r += _write_cells(cells)
  76
+	r += """
  77
+	)
  78
+	(library {0}_lib
  79
+		(edifLevel 0)
  80
+		(technology (numberDefinition))
  81
+		(cell {0}
  82
+			(cellType GENERIC)
  83
+				(view view_1
  84
+					(viewType NETLIST)
  85
+					(interface""".format(design_name)
  86
+	r += _write_io(ios)
  87
+	r += """
  88
+						(designator "{0}")
  89
+					)
  90
+					(contents""".format(part)
  91
+	r += _write_instantiations(instances, cell_library)
  92
+	r += _write_connections(connections)
  93
+	r += """
  94
+					)
  95
+				)
  96
+		)
  97
+	)
  98
+	(design {0}
  99
+		(cellRef {0} (libraryRef {0}_lib))
  100
+		(property PART (string "{1}") (owner "{2}"))
  101
+	)
  102
+)""".format(design_name, part, vendor)
  103
+	
  104
+	return r
  105
+
  106
+def _generate_cells(f):
  107
+	cell_dict = OrderedDict()
  108
+	for special in f.specials:
  109
+		if isinstance(special, Instance):
  110
+			port_list = []
  111
+			for port in special.items:
  112
+				if isinstance(port, Instance.Input):
  113
+					port_list.append(_Port(port.name, "INPUT"))
  114
+				elif isinstance(port, Instance.Output):
  115
+					port_list.append(_Port(port.name, "OUTPUT"))
  116
+				elif isinstance(port, Instance.Parameter):
  117
+					pass
  118
+				else:
  119
+					raise NotImplementedError("Unsupported instance item")
  120
+			if special.of in cell_dict:
  121
+				if set(port_list) != set(cell_dict[special.of]):
  122
+					raise ValueError("All instances must have the same ports for EDIF conversion")
  123
+			else:
  124
+				cell_dict[special.of] = port_list
  125
+		else:
  126
+			raise ValueError("Edif conversion can only handle synthesized fragments")
  127
+	return [_Cell(k, v) for k, v in cell_dict.items()]
  128
+
  129
+def _generate_instances(f,ns):
  130
+	instances = []
  131
+	for special in f.specials:
  132
+		if isinstance(special, Instance):	
  133
+			props = []
  134
+			for prop in special.items:
  135
+				if isinstance(prop, Instance.Input):
  136
+					pass
  137
+				elif isinstance(prop, Instance.Output):
  138
+					pass
  139
+				elif isinstance(prop, Instance.Parameter):
  140
+					props.append(_Property(name=prop.name, value=prop.value))
  141
+				else:
  142
+					raise NotImplementedError("Unsupported instance item")
  143
+			instances.append(_Instance(name=ns.get_name(special), cell=special.of, properties=props))
  144
+		else:
  145
+			raise ValueError("Edif conversion can only handle synthesized fragments")
  146
+	return instances
  147
+
  148
+def _generate_ios(f, ios, ns):
  149
+	outs = list_special_ios(f, False, True, False)
  150
+	r = []
  151
+	for io in ios:
  152
+		direction = "OUTPUT" if io in outs else "INPUT"
  153
+		r.append(_Port(name=ns.get_name(io), direction=direction))
  154
+	return r
  155
+
  156
+def _generate_connections(f, ios, ns):
  157
+	r = OrderedDict()
  158
+	for special in f.specials:
  159
+		if isinstance(special, Instance):
  160
+			instname = ns.get_name(special)
  161
+			for port in special.items:
  162
+				if isinstance(port, Instance.Input) or isinstance(port, Instance.Output):
  163
+					s = ns.get_name(port.expr)
  164
+					if s not in r:
  165
+						r[s] = []
  166
+					r[s].append(_NetBranch(portname=port.name, instancename=instname))
  167
+				elif isinstance(port, Instance.Parameter):
  168
+					pass
  169
+				else:
  170
+					raise NotImplementedError("Unsupported instance item")
  171
+		else:
  172
+			raise ValueError("Edif conversion can only handle synthesized fragments")
  173
+	for s in ios:
  174
+		io = ns.get_name(s)
  175
+		if io not in r:
  176
+			r[io] = []
  177
+		r[io].append(_NetBranch(portname=io, instancename=""))
  178
+	return r
  179
+
  180
+def convert(f, ios, name, cell_library, part, vendor):
  181
+	if not isinstance(f, _Fragment):
  182
+		f = f.get_fragment()
  183
+	if f.comb != [] or f.sync != {}:
  184
+		raise ValueError("Edif conversion can only handle synthesized fragments")
  185
+	if ios is None:
  186
+		ios = set()
  187
+	cells = _generate_cells(f)
  188
+	ns = build_namespace(list_special_ios(f, True, True, True))
  189
+	instances = _generate_instances(f, ns)
  190
+	inouts = _generate_ios(f, ios, ns)
  191
+	connections = _generate_connections(f, ios, ns)
  192
+	return _write_edif(cells, inouts, instances, connections, cell_library, name, part, vendor)

0 notes on commit 17002fb

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