From f03aa7629256c6ff6ae3129e3c353a8cb141444d Mon Sep 17 00:00:00 2001 From: Florent Kermarrec Date: Mon, 30 Mar 2015 10:42:42 +0200 Subject: [PATCH] migen: create VerilogConvert and EDIFConvert classes and return it with convert functions --- mibuild/generic_platform.py | 10 ++--- migen/fhdl/edif.py | 48 +++++++++++++------- migen/fhdl/verilog.py | 88 +++++++++++++++++++++---------------- migen/sim/generic.py | 5 ++- 4 files changed, 90 insertions(+), 61 deletions(-) diff --git a/mibuild/generic_platform.py b/mibuild/generic_platform.py index 4b4a6e3cf..96396ba46 100644 --- a/mibuild/generic_platform.py +++ b/mibuild/generic_platform.py @@ -268,17 +268,17 @@ class GenericPlatform: def _get_source(self, fragment, gen_fn): if not isinstance(fragment, _Fragment): fragment = fragment.get_fragment() - # generate source - src, vns = gen_fn(fragment) - return src, vns + # generate source and namespace + convert = gen_fn(fragment) + return str(convert), convert.ns def get_verilog(self, fragment, **kwargs): 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): 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): raise NotImplementedError("GenericPlatform.build must be overloaded") diff --git a/migen/fhdl/edif.py b/migen/fhdl/edif.py index de5e4f3e3..8fa4ea681 100644 --- a/migen/fhdl/edif.py +++ b/migen/fhdl/edif.py @@ -182,20 +182,36 @@ def _generate_connections(f, ios, ns): r[io].append(_NetBranch(portname=io, instancename="")) 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): - 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) - r = _write_edif(cells, inouts, instances, connections, cell_library, name, device, vendor) - if return_ns: - return r, ns - else: - return r + return EDIFConvert(f, ios, cell_library, vendor, device, name, return_ns) diff --git a/migen/fhdl/verilog.py b/migen/fhdl/verilog.py index bc0504414..fbebe8f56 100644 --- a/migen/fhdl/verilog.py +++ b/migen/fhdl/verilog.py @@ -266,45 +266,57 @@ def _printspecials(overrides, specials, ns): r += pr 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", - return_ns=False, special_overrides=dict(), create_clock_domains=True, display_run=False): - 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) - - 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 + return VerilogConvert(f, ios, name, special_overrides, create_clock_domains, display_run) diff --git a/migen/sim/generic.py b/migen/sim/generic.py index 2977cf9d8..509848596 100644 --- a/migen/sim/generic.py +++ b/migen/sim/generic.py @@ -87,16 +87,17 @@ class Simulator: c_top = self.top_level.get(sockaddr) 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, name=self.top_level.dut_type, return_ns=True, **vopts) + c_dut, self.namespace = str(verilog_convert), verilog_convert.ns self.cycle_counter = -1 self.sim_runner = sim_runner - self.sim_runner.start(c_top, c_fragment) + self.sim_runner.start(c_top, c_dut) self.ipc.accept() reply = self.ipc.recv() assert(isinstance(reply, MessageTick))