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/nmigen
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: cb998d891b73
Choose a base ref
...
head repository: m-labs/nmigen
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: a10791e160bb
Choose a head ref
  • 1 commit
  • 2 files changed
  • 1 contributor

Commits on Dec 14, 2018

  1. Copy the full SHA
    a10791e View commit details
Showing with 43 additions and 3 deletions.
  1. +4 −1 examples/ctrl.py
  2. +39 −2 nmigen/back/pysim.py
5 changes: 4 additions & 1 deletion examples/ctrl.py
Original file line number Diff line number Diff line change
@@ -21,7 +21,10 @@ def get_fragment(self, platform):
# print(rtlil.convert(frag, ports=[ctr.o, ctr.ce]))
print(verilog.convert(frag, ports=[ctr.o, ctr.ce]))

sim = pysim.Simulator(frag, vcd_file=open("ctrl.vcd", "w"))
sim = pysim.Simulator(frag,
vcd_file=open("ctrl.vcd", "w"),
gtkw_file=open("ctrl.gtkw", "w"),
gtkw_signals=[ctr.ce, ctr.v, ctr.o])
sim.add_clock("sync", 1e-6)
def ce_proc():
yield; yield; yield
41 changes: 39 additions & 2 deletions nmigen/back/pysim.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
import math
from vcd import VCDWriter
from vcd.gtkw import GTKWSave

from ..tools import flatten
from ..fhdl.ast import *
@@ -182,7 +184,7 @@ def run(state):


class Simulator:
def __init__(self, fragment=None, vcd_file=None):
def __init__(self, fragment=None, vcd_file=None, gtkw_file=None, gtkw_signals=()):
self._fragments = {} # fragment -> hierarchy

self._domains = {} # str/domain -> ClockDomain
@@ -197,6 +199,7 @@ def __init__(self, fragment=None, vcd_file=None):
self._started = False
self._timestamp = 0.
self._epsilon = 1e-10
self._fastest_clock = self._epsilon
self._state = _State()

self._processes = set() # {process}
@@ -210,6 +213,10 @@ def __init__(self, fragment=None, vcd_file=None):
self._vcd_file = vcd_file
self._vcd_writer = None
self._vcd_signals = ValueDict() # signal -> set(vcd_signal)
self._vcd_names = ValueDict() # signal -> str/name

self._gtkw_file = gtkw_file
self._gtkw_signals = gtkw_signals

if fragment is not None:
fragment = fragment.prepare()
@@ -230,8 +237,11 @@ def add_process(self, process):
self._processes.add(process)

def add_clock(self, domain, period):
clk = self._domains[domain].clk
if self._fastest_clock == self._epsilon or period < self._fastest_clock:
self._fastest_clock = period

half_period = period / 2
clk = self._domains[domain].clk
def clk_process():
yield Passive()
yield Delay(half_period)
@@ -289,6 +299,9 @@ def __enter__(self):
self._vcd_signals[signal].add(self._vcd_writer.register_var(
scope=".".join(self._fragments[fragment]), name=name_suffix,
var_type="wire", size=signal.nbits, init=signal.reset))
if signal not in self._vcd_names:
self._vcd_names[signal] = \
".".join(self._fragments[fragment] + (name_suffix,))
break
except KeyError:
suffix = (suffix or 0) + 1
@@ -454,3 +467,27 @@ def run_until(self, deadline, run_passive=False):
def __exit__(self, *args):
if self._vcd_writer:
self._vcd_writer.close(self._timestamp / self._epsilon)

if self._vcd_file and self._gtkw_file:
gtkw_save = GTKWSave(self._gtkw_file)
if hasattr(self._vcd_file, "name"):
gtkw_save.dumpfile(self._vcd_file.name)
if hasattr(self._vcd_file, "tell"):
gtkw_save.dumpfile_size(self._vcd_file.tell())

gtkw_save.treeopen("top")
gtkw_save.zoom_markers(math.log(self._epsilon / self._fastest_clock) - 14)

for domain, cd in self._domains.items():
with gtkw_save.group("d.{}".format(domain)):
if cd.rst is not None:
gtkw_save.trace("top.{}".format(cd.rst.name))
gtkw_save.trace("top.{}".format(cd.clk.name))

for signal in self._gtkw_signals:
if signal in self._vcd_names:
if len(signal) > 1:
suffix = "[{}:0]".format(len(signal) - 1)
else:
suffix = ""
gtkw_save.trace(self._vcd_names[signal] + suffix)