migen: create VerilogConvert and EDIFConvert classes and return it with convert functions
This commit is contained in:
parent
21c5fb6f6c
commit
f03aa76292
|
@ -268,17 +268,17 @@ class GenericPlatform:
|
||||||
def _get_source(self, fragment, gen_fn):
|
def _get_source(self, fragment, gen_fn):
|
||||||
if not isinstance(fragment, _Fragment):
|
if not isinstance(fragment, _Fragment):
|
||||||
fragment = fragment.get_fragment()
|
fragment = fragment.get_fragment()
|
||||||
# generate source
|
# generate source and namespace
|
||||||
src, vns = gen_fn(fragment)
|
convert = gen_fn(fragment)
|
||||||
return src, vns
|
return str(convert), convert.ns
|
||||||
|
|
||||||
def get_verilog(self, fragment, **kwargs):
|
def get_verilog(self, fragment, **kwargs):
|
||||||
return self._get_source(fragment, lambda f: verilog.convert(f, self.constraint_manager.get_io_signals(),
|
return self._get_source(fragment, lambda f: verilog.convert(f, self.constraint_manager.get_io_signals(),
|
||||||
return_ns=True, create_clock_domains=False, **kwargs))
|
create_clock_domains=False, **kwargs))
|
||||||
|
|
||||||
def get_edif(self, fragment, cell_library, vendor, device, **kwargs):
|
def get_edif(self, fragment, cell_library, vendor, device, **kwargs):
|
||||||
return self._get_source(fragment, lambda f: edif.convert(f, self.constraint_manager.get_io_signals(),
|
return self._get_source(fragment, lambda f: edif.convert(f, self.constraint_manager.get_io_signals(),
|
||||||
cell_library, vendor, device, return_ns=True, **kwargs))
|
cell_library, vendor, device, **kwargs))
|
||||||
|
|
||||||
def build(self, fragment):
|
def build(self, fragment):
|
||||||
raise NotImplementedError("GenericPlatform.build must be overloaded")
|
raise NotImplementedError("GenericPlatform.build must be overloaded")
|
||||||
|
|
|
@ -182,20 +182,36 @@ def _generate_connections(f, ios, ns):
|
||||||
r[io].append(_NetBranch(portname=io, instancename=""))
|
r[io].append(_NetBranch(portname=io, instancename=""))
|
||||||
return r
|
return r
|
||||||
|
|
||||||
|
class EDIFConvert:
|
||||||
|
def __init__(self, f, ios, cell_library, vendor, device, name="top"):
|
||||||
|
self.cell_library
|
||||||
|
self.vendor = vendor
|
||||||
|
self.device = device
|
||||||
|
self.name = name
|
||||||
|
|
||||||
|
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)
|
||||||
|
|
||||||
|
self.f = f
|
||||||
|
self.ios = ios
|
||||||
|
self.cells = cells
|
||||||
|
self.ns = ns
|
||||||
|
self.instances = instances
|
||||||
|
self.inouts = inouts
|
||||||
|
self.connections = connections
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
return _write_edif(self.cells, self.inouts, self.instances, self.connections,
|
||||||
|
self.cell_library, self.name, self.device, self.vendor)
|
||||||
|
|
||||||
def convert(f, ios, cell_library, vendor, device, name="top", return_ns=False):
|
def convert(f, ios, cell_library, vendor, device, name="top", return_ns=False):
|
||||||
if not isinstance(f, _Fragment):
|
return EDIFConvert(f, ios, cell_library, vendor, device, name, return_ns)
|
||||||
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)
|
|
||||||
r = _write_edif(cells, inouts, instances, connections, cell_library, name, device, vendor)
|
|
||||||
if return_ns:
|
|
||||||
return r, ns
|
|
||||||
else:
|
|
||||||
return r
|
|
||||||
|
|
|
@ -266,45 +266,57 @@ def _printspecials(overrides, specials, ns):
|
||||||
r += pr
|
r += pr
|
||||||
return r
|
return r
|
||||||
|
|
||||||
|
class VerilogConvert:
|
||||||
|
def __init__(self, f, ios=None, name="top",
|
||||||
|
special_overrides=dict(),
|
||||||
|
create_clock_domains=True,
|
||||||
|
display_run=False):
|
||||||
|
self.name = name
|
||||||
|
self.special_overrides = special_overrides
|
||||||
|
self.display_run = display_run
|
||||||
|
|
||||||
|
if not isinstance(f, _Fragment):
|
||||||
|
f = f.get_fragment()
|
||||||
|
if ios is None:
|
||||||
|
ios = set()
|
||||||
|
|
||||||
|
for cd_name in list_clock_domains(f):
|
||||||
|
try:
|
||||||
|
f.clock_domains[cd_name]
|
||||||
|
except KeyError:
|
||||||
|
if create_clock_domains:
|
||||||
|
cd = ClockDomain(cd_name)
|
||||||
|
f.clock_domains.append(cd)
|
||||||
|
ios |= {cd.clk, cd.rst}
|
||||||
|
else:
|
||||||
|
raise KeyError("Unresolved clock domain: '"+cd_name+"'")
|
||||||
|
|
||||||
|
f = lower_complex_slices(f)
|
||||||
|
insert_resets(f)
|
||||||
|
f = lower_basics(f)
|
||||||
|
fs, lowered_specials = _lower_specials(special_overrides, f.specials)
|
||||||
|
f += lower_basics(fs)
|
||||||
|
|
||||||
|
ns = build_namespace(list_signals(f) \
|
||||||
|
| list_special_ios(f, True, True, True) \
|
||||||
|
| ios)
|
||||||
|
|
||||||
|
self.f = f
|
||||||
|
self.ios = ios
|
||||||
|
self.ns = ns
|
||||||
|
self.lowered_specials = lowered_specials
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
r = "/* Machine-generated using Migen */\n"
|
||||||
|
r += _printheader(self.f, self.ios, self.name, self.ns)
|
||||||
|
r += _printcomb(self.f, self.ns, self.display_run)
|
||||||
|
r += _printsync(self.f, self.ns)
|
||||||
|
r += _printspecials(self.special_overrides, self.f.specials - self.lowered_specials, self.ns)
|
||||||
|
r += "endmodule\n"
|
||||||
|
return r
|
||||||
|
|
||||||
def convert(f, ios=None, name="top",
|
def convert(f, ios=None, name="top",
|
||||||
return_ns=False,
|
|
||||||
special_overrides=dict(),
|
special_overrides=dict(),
|
||||||
create_clock_domains=True,
|
create_clock_domains=True,
|
||||||
display_run=False):
|
display_run=False):
|
||||||
if not isinstance(f, _Fragment):
|
return VerilogConvert(f, ios, name, special_overrides, create_clock_domains, display_run)
|
||||||
f = f.get_fragment()
|
|
||||||
if ios is None:
|
|
||||||
ios = set()
|
|
||||||
|
|
||||||
for cd_name in list_clock_domains(f):
|
|
||||||
try:
|
|
||||||
f.clock_domains[cd_name]
|
|
||||||
except KeyError:
|
|
||||||
if create_clock_domains:
|
|
||||||
cd = ClockDomain(cd_name)
|
|
||||||
f.clock_domains.append(cd)
|
|
||||||
ios |= {cd.clk, cd.rst}
|
|
||||||
else:
|
|
||||||
raise KeyError("Unresolved clock domain: '"+cd_name+"'")
|
|
||||||
|
|
||||||
f = lower_complex_slices(f)
|
|
||||||
insert_resets(f)
|
|
||||||
f = lower_basics(f)
|
|
||||||
fs, lowered_specials = _lower_specials(special_overrides, f.specials)
|
|
||||||
f += lower_basics(fs)
|
|
||||||
|
|
||||||
ns = build_namespace(list_signals(f) \
|
|
||||||
| list_special_ios(f, True, True, True) \
|
|
||||||
| ios)
|
|
||||||
|
|
||||||
r = "/* Machine-generated using Migen */\n"
|
|
||||||
r += _printheader(f, ios, name, ns)
|
|
||||||
r += _printcomb(f, ns, display_run)
|
|
||||||
r += _printsync(f, ns)
|
|
||||||
r += _printspecials(special_overrides, f.specials - lowered_specials, ns)
|
|
||||||
r += "endmodule\n"
|
|
||||||
|
|
||||||
if return_ns:
|
|
||||||
return r, ns
|
|
||||||
else:
|
|
||||||
return r
|
|
||||||
|
|
|
@ -87,16 +87,17 @@ class Simulator:
|
||||||
c_top = self.top_level.get(sockaddr)
|
c_top = self.top_level.get(sockaddr)
|
||||||
|
|
||||||
fragment = fragment + _Fragment(clock_domains=top_level.clock_domains)
|
fragment = fragment + _Fragment(clock_domains=top_level.clock_domains)
|
||||||
c_fragment, self.namespace = verilog.convert(fragment,
|
verilog_convert = verilog.convert(fragment,
|
||||||
ios=self.top_level.ios,
|
ios=self.top_level.ios,
|
||||||
name=self.top_level.dut_type,
|
name=self.top_level.dut_type,
|
||||||
return_ns=True,
|
return_ns=True,
|
||||||
**vopts)
|
**vopts)
|
||||||
|
c_dut, self.namespace = str(verilog_convert), verilog_convert.ns
|
||||||
|
|
||||||
self.cycle_counter = -1
|
self.cycle_counter = -1
|
||||||
|
|
||||||
self.sim_runner = sim_runner
|
self.sim_runner = sim_runner
|
||||||
self.sim_runner.start(c_top, c_fragment)
|
self.sim_runner.start(c_top, c_dut)
|
||||||
self.ipc.accept()
|
self.ipc.accept()
|
||||||
reply = self.ipc.recv()
|
reply = self.ipc.recv()
|
||||||
assert(isinstance(reply, MessageTick))
|
assert(isinstance(reply, MessageTick))
|
||||||
|
|
Loading…
Reference in New Issue