Skip to content

Commit 2989645

Browse files
committed
wip
1 parent dbb4329 commit 2989645

File tree

3 files changed

+38
-6
lines changed

3 files changed

+38
-6
lines changed

nmigen/sim/_cxxrtl_ctypes.py

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
from enum import IntEnum
22
from ctypes import (cdll, Structure, POINTER, CFUNCTYPE,
33
c_int, c_size_t, c_uint32, c_uint64, c_void_p, c_char_p,
4-
byref)
4+
byref, string_at)
55

66

77
__all__ = []
@@ -140,8 +140,12 @@ def get_parts(handle, name):
140140
self.vcd_destroy.argtypes = [cxxrtl_vcd]
141141
self.vcd_destroy.restype = None
142142

143+
self.vcd_timescale = library.cxxrtl_vcd_timescale
144+
self.vcd_timescale.argtypes = [cxxrtl_vcd, c_int, c_char_p]
145+
self.vcd_timescale.restype = None
146+
143147
self.vcd_add = library.cxxrtl_vcd_add
144-
self.vcd_add.argtypes = [cxxrtl_vcd, c_int, c_char_p]
148+
self.vcd_add.argtypes = [cxxrtl_vcd, c_char_p, cxxrtl_object_p]
145149
self.vcd_add.restype = None
146150

147151
self.vcd_add_from = library.cxxrtl_vcd_add_from
@@ -160,6 +164,12 @@ def get_parts(handle, name):
160164
self.vcd_sample.argtypes = [cxxrtl_vcd, c_uint64]
161165
self.vcd_sample.restype = None
162166

163-
self.vcd_read = library.cxxrtl_vcd_read
164-
self.vcd_read.argtypes = [cxxrtl_vcd, POINTER(c_char_p), POINTER(c_size_t)]
165-
self.vcd_read.restype = None
167+
_vcd_read = library.cxxrtl_vcd_read
168+
_vcd_read.argtypes = [cxxrtl_vcd, POINTER(c_char_p), POINTER(c_size_t)]
169+
_vcd_read.restype = None
170+
def vcd_read(vcd):
171+
data = c_char_p()
172+
size = c_size_t()
173+
_vcd_read(vcd, byref(data), byref(size))
174+
return string_at(data.value, size.value)
175+
self.vcd_read = vcd_read

nmigen/sim/cxxsim.py

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import os
2+
from contextlib import contextmanager
23

34
from ..hdl import *
45
from ..hdl.ast import SignalDict
@@ -101,6 +102,7 @@ def __init__(self, fragment):
101102
# cxxlib = cxxrtl_library("./sim.so")
102103

103104
self._state = _SimulatorState(cxxlib, name_map)
105+
self._vcd_writers = []
104106

105107
def _add_coroutine_process(self, process, *, default_cmd):
106108
self._processes.add(PyCoroProcess(self._state, self._timeline,
@@ -109,6 +111,7 @@ def _add_coroutine_process(self, process, *, default_cmd):
109111

110112
def reset(self):
111113
self._state.reset()
114+
self._timeline.reset()
112115
for process in self._processes:
113116
process.reset()
114117

@@ -122,3 +125,22 @@ def _real_step(self):
122125
self._state.eval()
123126
if not self._state.commit():
124127
break
128+
129+
for vcd_writer, vcd_file in self._vcd_writers:
130+
self._state.cxxlib.vcd_sample(vcd_writer, int(self._timeline.now * 10 ** 10))
131+
vcd_file.write(self._state.cxxlib.vcd_read(vcd_writer))
132+
133+
@contextmanager
134+
def write_vcd(self, vcd_file):
135+
if self._timeline.now != 0.0:
136+
raise ValueError("Cannot start writing waveforms after advancing simulation time")
137+
with open(vcd_file, "wb") as vcd_file:
138+
try:
139+
vcd_writer = self._state.cxxlib.vcd_create()
140+
self._vcd_writers.append((vcd_writer, vcd_file))
141+
self._state.cxxlib.vcd_timescale(vcd_writer, 100, b"ps")
142+
self._state.cxxlib.vcd_add_from(vcd_writer, self._state.handle)
143+
yield
144+
finally:
145+
self._vcd_writers.remove((vcd_writer, vcd_file))
146+
self._state.cxxlib.vcd_destroy(vcd_writer)

nmigen/sim/pysim.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -255,7 +255,7 @@ def _real_step(self):
255255

256256
for waveform_writer in self._waveform_writers:
257257
for signal_state in self._state.pending:
258-
waveform_writer.update(self._state.timeline.now,
258+
waveform_writer.update(self._timeline.now,
259259
signal_state.signal, signal_state.next)
260260

261261
# 2. commit: apply every queued signal change, waking up any waiting processes

0 commit comments

Comments
 (0)