Skip to content

Commit e3cc0e7

Browse files
committed
Added seed as an optional argument to pre_config hooks.
1 parent 692e77f commit e3cc0e7

7 files changed

Lines changed: 51 additions & 35 deletions

File tree

docs/news.d/1176.feature.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Added seed as an optional input to ``pre_config`` hooks. The seed is identical to the base seed provided to the simulation.

docs/py/ui.rst

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -102,9 +102,10 @@ There are two hooks to run user defined Python code.
102102
:pre_config: A ``pre_config`` is called before simulation of the test
103103
case. The function accepts an optional string argument
104104
``output_path``, which is the filesystem path to the
105-
directory where test outputs are stored, and an optional
105+
directory where test outputs are stored, an optional
106106
string argument ``simulator_output_path`` which is the path
107-
to the simulator working directory.
107+
to the simulator working directory, and ``seed`` which is the
108+
seed assigned to the test case.
108109

109110
.. note::
110111
``simulator_output_path`` is shared by all test runs. The
@@ -126,6 +127,11 @@ There are two hooks to run user defined Python code.
126127
code expecting input files to be located in the
127128
simulator working directory.
128129

130+
The use case for ``seed`` is to have access to a reproducible
131+
seed for data randomization. The seed is identical to the
132+
base seed provided to the simulation, see the
133+
:doc:`run library user guide <../run/user_guide>`.
134+
129135
:post_check: A ``post_check`` is called after a passing simulation of
130136
the test case. The function accepts an optional string argument
131137
``output_path``, which is the filesystem path to the

docs/run/user_guide.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -259,7 +259,7 @@ level of test coverage.
259259
The base seed is provided via the ``runner_cfg`` generic and new derived seeds can be obtained by calling the
260260
``get_seed`` function with ``runner_cfg`` and a salt string. The salt string is hashed together with the base seed to
261261
ensure the uniqueness of each derived seed (with very high probability). The ``salt`` parameter can be omitted if only a
262-
single seed is needed:
262+
single seed is needed. In that case, the base seed is hashed with the empty string.
263263

264264
.. raw:: html
265265
:file: img/get_seed_and_runner_cfg.html

tests/acceptance/artificial/vhdl/run.py

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -169,12 +169,27 @@ def pre_config(output_path):
169169
def configure_tb_seed(ui):
170170
tb = ui.library("lib").test_bench("tb_seed")
171171

172+
def make_pre_config(expected_seed=""):
173+
def pre_config(seed):
174+
print(f"pre_config seed: {seed}")
175+
if not expected_seed:
176+
assert seed != "0123456789abcdef"
177+
else:
178+
assert seed == expected_seed
179+
180+
return True
181+
182+
return pre_config
183+
172184
if args.seed == "0123456789abcdef":
173185
tb.test("test_1").set_generic("expected_seed", "2e373913e5ad677d")
174186
tb.test("test_2").set_generic("expected_seed", "2e373913e5ad677d")
187+
tb.set_pre_config(make_pre_config("0123456789abcdef"))
175188
elif args.seed == "repeat":
176189
tb.test("test_1").set_generic("expected_seed", "ffa08cd9489aad14")
177190
tb.test("test_2").set_generic("expected_seed", "9a292b3679afd081")
191+
tb.test("test_1").set_pre_config(make_pre_config("7ac31eb89c4059f9"))
192+
tb.test("test_2").set_pre_config(make_pre_config("8b1cd665d806e572"))
178193

179194

180195
def configure_tb_vunit_pkg(vu):

tests/unit/test_configuration.py

Lines changed: 23 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -172,14 +172,14 @@ def post_check(output):
172172
)
173173

174174
def test_call_pre_config_none(self):
175-
self.assertEqual(self._call_pre_config(None, "output_path", "simulator_output_path"), True)
175+
self.assertEqual(self._call_pre_config(None, "output_path", "simulator_output_path", "seed"), True)
176176

177177
def test_call_pre_config_false(self):
178178
def pre_config():
179179
return False
180180

181181
self.assertEqual(
182-
self._call_pre_config(pre_config, "output_path", "simulator_output_path"),
182+
self._call_pre_config(pre_config, "output_path", "simulator_output_path", "seed"),
183183
False,
184184
)
185185

@@ -188,7 +188,7 @@ def pre_config():
188188
return True
189189

190190
self.assertEqual(
191-
self._call_pre_config(pre_config, "output_path", "simulator_output_path"),
191+
self._call_pre_config(pre_config, "output_path", "simulator_output_path", "seed"),
192192
True,
193193
)
194194

@@ -197,7 +197,7 @@ def pre_config():
197197
pass
198198

199199
self.assertEqual(
200-
self._call_pre_config(pre_config, "output_path", "simulator_output_path"),
200+
self._call_pre_config(pre_config, "output_path", "simulator_output_path", "seed"),
201201
False,
202202
)
203203

@@ -209,13 +209,7 @@ def pre_config(output_path):
209209
self.assertEqual(output_path, "output_path")
210210
raise WasHere
211211

212-
self.assertRaises(
213-
WasHere,
214-
self._call_pre_config,
215-
pre_config,
216-
"output_path",
217-
"simulator_output_path",
218-
)
212+
self.assertRaises(WasHere, self._call_pre_config, pre_config, "output_path", "simulator_output_path", "seed")
219213

220214
def test_call_pre_config_with_simulator_output_path(self):
221215
def pre_config(output_path, simulator_output_path):
@@ -226,13 +220,19 @@ def pre_config(output_path, simulator_output_path):
226220
self.assertEqual(simulator_output_path, "simulator_output_path")
227221
raise WasHere
228222

229-
self.assertRaises(
230-
WasHere,
231-
self._call_pre_config,
232-
pre_config,
233-
"output_path",
234-
"simulator_output_path",
235-
)
223+
self.assertRaises(WasHere, self._call_pre_config, pre_config, "output_path", "simulator_output_path", "seed")
224+
225+
def test_call_pre_config_with_seed(self):
226+
def pre_config(output_path, simulator_output_path, seed):
227+
"""
228+
Pre config with output path
229+
"""
230+
self.assertEqual(output_path, "output_path")
231+
self.assertEqual(simulator_output_path, "simulator_output_path")
232+
self.assertEqual(seed, "seed")
233+
raise WasHere
234+
235+
self.assertRaises(WasHere, self._call_pre_config, pre_config, "output_path", "simulator_output_path", "seed")
236236

237237
def test_call_pre_config_class_method(self):
238238
class MyClass(object):
@@ -243,30 +243,27 @@ class MyClass(object):
243243
def __init__(self, value):
244244
self.value = value
245245

246-
def pre_config(self, output_path, simulator_output_path):
246+
def pre_config(self, output_path, simulator_output_path, seed):
247247
"""
248248
Pre config with output path
249249
"""
250250
assert self.value == 2
251251
assert output_path == "output_path"
252252
assert simulator_output_path == "simulator_output_path"
253+
assert seed == "seed"
253254
raise WasHere
254255

255256
self.assertRaises(
256-
WasHere,
257-
self._call_pre_config,
258-
MyClass(value=2).pre_config,
259-
"output_path",
260-
"simulator_output_path",
257+
WasHere, self._call_pre_config, MyClass(value=2).pre_config, "output_path", "simulator_output_path", "seed"
261258
)
262259

263260
@staticmethod
264-
def _call_pre_config(pre_config, output_path, simulator_output_path):
261+
def _call_pre_config(pre_config, output_path, simulator_output_path, seed):
265262
"""
266263
Helper method to test call_pre_config method
267264
"""
268265
with _create_config(pre_config=pre_config) as config:
269-
return config.call_pre_config(output_path, simulator_output_path)
266+
return config.call_pre_config(output_path, simulator_output_path, seed)
270267

271268
@staticmethod
272269
def _call_post_check(post_check, **kwargs):

vunit/configuration.py

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -148,7 +148,7 @@ def vhdl_assert_stop_level(self):
148148

149149
return level
150150

151-
def call_pre_config(self, output_path, simulator_output_path):
151+
def call_pre_config(self, output_path, simulator_output_path, seed):
152152
"""
153153
Call pre_config if available. Setting optional output_path
154154
"""
@@ -157,10 +157,7 @@ def call_pre_config(self, output_path, simulator_output_path):
157157

158158
args = inspect.getfullargspec(self.pre_config).args
159159

160-
kwargs = {
161-
"output_path": output_path,
162-
"simulator_output_path": simulator_output_path,
163-
}
160+
kwargs = {"output_path": output_path, "simulator_output_path": simulator_output_path, "seed": seed}
164161

165162
for argname in list(kwargs.keys()):
166163
if argname not in args:

vunit/test/suites.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -211,7 +211,7 @@ def run(self, output_path, read_output):
211211
for name in self._test_cases:
212212
results[name] = FAILED
213213

214-
if not self._config.call_pre_config(output_path, self._simulator_if.output_path):
214+
if not self._config.call_pre_config(output_path, self._simulator_if.output_path, self._seed):
215215
return results
216216

217217
# Ensure result file exists

0 commit comments

Comments
 (0)