Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: m-labs/migen
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: 21c5fb6f6c01
Choose a base ref
...
head repository: m-labs/migen
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: 15e24b6c1061
Choose a head ref
  • 4 commits
  • 6 files changed
  • 1 contributor

Commits on Mar 30, 2015

  1. 3
    Copy the full SHA
    f03aa76 View commit details
  2. 1
    Copy the full SHA
    ea04947 View commit details
  3. migen/fhdl/specials: use fdict to pass memory initialization files to…

    … VerilogConvert and print them in __str__ method
    enjoy-digital committed Mar 30, 2015
    4
    Copy the full SHA
    95cfc44 View commit details
  4. Copy the full SHA
    15e24b6 View commit details
Showing with 119 additions and 83 deletions.
  1. +5 −5 mibuild/generic_platform.py
  2. +0 −1 mibuild/platforms/minispartan6.py
  3. +32 −16 migen/fhdl/edif.py
  4. +20 −20 migen/fhdl/specials.py
  5. +59 −39 migen/fhdl/verilog.py
  6. +3 −2 migen/sim/generic.py
10 changes: 5 additions & 5 deletions mibuild/generic_platform.py
Original file line number Diff line number Diff line change
@@ -268,17 +268,17 @@ def resolve_signals(self, vns):
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")
1 change: 0 additions & 1 deletion mibuild/platforms/minispartan6.py
Original file line number Diff line number Diff line change
@@ -2,7 +2,6 @@
# License: BSD

from mibuild.generic_platform import *
from mibuild.crg import SimpleCRG
from mibuild.xilinx import XilinxPlatform
from mibuild.xilinx.programmer import XC3SProg, FpgaProg

48 changes: 32 additions & 16 deletions migen/fhdl/edif.py
Original file line number Diff line number Diff line change
@@ -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)
40 changes: 20 additions & 20 deletions migen/fhdl/specials.py
Original file line number Diff line number Diff line change
@@ -6,6 +6,15 @@
from migen.fhdl.tracer import get_obj_var_name
from migen.fhdl.verilog import _printexpr as verilog_printexpr

def _new_file(fdict, requested_filename, contents):
filename = requested_filename
i = 1
while filename in fdict.keys():
filename = requested_filename + str(i)
i += 1
fdict[filename] = contents
return filename, fdict

class Special(HUID):
def iter_expressions(self):
for x in []:
@@ -48,7 +57,7 @@ def iter_expressions(self):
yield self, attr, target_context

@staticmethod
def emit_verilog(tristate, ns):
def emit_verilog(tristate, ns, fdict):
def pe(e):
return verilog_printexpr(ns, e)[0]
w, s = value_bits_sign(tristate.target)
@@ -58,7 +67,7 @@ def pe(e):
if tristate.i is not None:
r += "assign " + pe(tristate.i) + " = " + pe(tristate.target) + ";\n"
r += "\n"
return r
return r, fdict

class TSTriple:
def __init__(self, bits_sign=None, min=None, max=None, reset_o=0, reset_oe=0):
@@ -123,7 +132,7 @@ def iter_expressions(self):
yield item, "expr", SPECIAL_INOUT

@staticmethod
def emit_verilog(instance, ns):
def emit_verilog(instance, ns, fdict):
r = instance.of + " "
parameters = list(filter(lambda i: isinstance(i, Instance.Parameter), instance.items))
if parameters:
@@ -165,7 +174,7 @@ def emit_verilog(instance, ns):
r += ")" + synthesis_directive + ";\n\n"
else:
r += ");\n\n"
return r
return r, fdict

(READ_FIRST, WRITE_FIRST, NO_CHANGE) = range(3)

@@ -198,8 +207,8 @@ def iter_expressions(self):
yield self, attr, target_context

@staticmethod
def emit_verilog(port, ns):
return "" # done by parent Memory object
def emit_verilog(port, ns, fdict):
return "", fdict # done by parent Memory object

class Memory(Special):
def __init__(self, width, depth, init=None, name=None):
@@ -237,7 +246,7 @@ def get_port(self, write_capable=False, async_read=False,
return mp

@staticmethod
def emit_verilog(memory, ns):
def emit_verilog(memory, ns, fdict):
r = ""
def gn(e):
if isinstance(e, Memory):
@@ -307,21 +316,12 @@ def gn(e):
r += "\n"

if memory.init is not None:
memory_filename = gn(memory) + ".init"

# XXX move I/O to mibuild?
# (Implies mem init won't work with simple Migen examples?)
f = open(memory_filename, "w")
for d in memory.init:
f.write("{:x}\n".format(d))
f.close()

memory_filename, fdict = _new_file(fdict, gn(memory) + ".init", memory.init)
r += "initial begin\n"
r += "$readmemh(\"" + memory_filename + "\", " + gn(memory) + ");\n"
r += "end\n\n"


return r
return r, fdict

class SynthesisDirective(Special):
def __init__(self, template, **signals):
@@ -330,7 +330,7 @@ def __init__(self, template, **signals):
self.signals = signals

@staticmethod
def emit_verilog(directive, ns):
def emit_verilog(directive, ns, fdict):
name_dict = dict((k, ns.get_name(sig)) for k, sig in directive.signals.items())
formatted = directive.template.format(**name_dict)
return "// synthesis " + formatted + "\n"
return "// synthesis " + formatted + "\n", fdict
98 changes: 59 additions & 39 deletions migen/fhdl/verilog.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
from functools import partial
from operator import itemgetter
from collections import OrderedDict

from migen.fhdl.structure import *
from migen.fhdl.structure import _Operator, _Slice, _Assign, _Fragment
@@ -257,54 +258,73 @@ def _lower_specials(overrides, specials):
f.specials -= lowered_specials2
return f, lowered_specials

def _printspecials(overrides, specials, ns):
def _printspecials(overrides, specials, ns, fdict):
r = ""
for special in sorted(specials, key=lambda x: x.huid):
pr = _call_special_classmethod(overrides, special, "emit_verilog", ns)
pr, fdict = _call_special_classmethod(overrides, special, "emit_verilog", ns, fdict)
if pr is None:
raise NotImplementedError("Special " + str(special) + " failed to implement emit_verilog")
r += pr
return r
return r, fdict

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()
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

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+"'")
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)
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)
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"
self.f = f
self.ios = ios
self.ns = ns
self.lowered_specials = lowered_specials

if return_ns:
return r, ns
else:
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)
fdict = OrderedDict()
src, fdict = _printspecials(self.special_overrides, self.f.specials - self.lowered_specials, self.ns, fdict)
r += src
for filename, contents in fdict.items():
f = open(filename, "w")
for data in contents:
f.write("{:x}\n".format(data))
f.close()
r += "endmodule\n"
return r

def convert(f, ios=None, name="top",
special_overrides=dict(),
create_clock_domains=True,
display_run=False):
return VerilogConvert(f, ios, name, special_overrides, create_clock_domains, display_run)
5 changes: 3 additions & 2 deletions migen/sim/generic.py
Original file line number Diff line number Diff line change
@@ -87,16 +87,17 @@ def __init__(self, fragment, top_level=None, sim_runner=None, sockaddr="simsocke
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))