Closed mszep closed 4 years ago
In my test functions, I have been iterating over
sim._state.pending
to find all signals by name
This is definitely not the right way to write testcases. The object sim._state
is internal and I can and will break its interface without any consideration of downstream code.
You can get the value of any signal in res
by writing a process that performs e.g. yield res[0]
; the print statement you want can look something like print("res: [{}]".format(", ".join((yield block.res[n]) for n in len(block.res))
.
Thanks for your quick response!
Unfortunately I can't figure out how to call it -- I presume you mean range(len(block.res))
, but even with that fixed, I still get TypeError: sequence item 0: expected str instance, Signal found
Oh wow that's a fascinating Python syntax edge case: turns out you can't really use yield
in list comprehensions, and if you do, the results are quite bizarre:
>>> [(yield 1) for x in range(10)]
<generator object <listcomp> at 0x7ff1cb2815e8>
>>> list((yield 1) for x in range(10))
[1, None, 1, None, 1, None, 1, None, 1, None, 1, None, 1, None, 1, None, 1, None, 1, None]
>>> [1 for x in range(10)]
[1, 1, 1, 1, 1, 1, 1, 1, 1, 1]
Anyway, this works:
def test_arraytest():
block = ArrayTest(num_bits=64)
sim = pysim.Simulator(block)
def process():
yield block.x.eq(12)
yield block.y.eq(5)
yield pysim.Settle()
print("res: [{}, {}]".format((yield block.res[0]), (yield block.res[1])))
sim.add_process(process)
sim.run()
Yup, works, thank you so much for your help!
You can certainly use yield
in list comprehensions. The confusion you see is from two generators, the (yield 1)
and the generator expression (_ for x in range(10))
. Yield outside a function is depecated/a bug.
>>> def f(): yield from [(yield 1) for _ in range(10)]
...
>>> list(f())
[1, 1, 1, 1, 1, 1, 1, 1, 1, 1]
This is by the way another reason to use await/async as it gives you a cleaner and arguably more robust separation between async IO and language constructs like generators.
[I'm a nmigen novice, so apologies if I'm doing something silly]
I'm trying to test a combinatorial module function that returns an array of Signals.
In my test functions, I have been iterating over
sim._state.pending
to find all signals by name and check if they have the right values, but this seems to fall down when the result is an Array.Here is a minimal example:
for me this prints
However, I was expecting to see something like
res [13, 6]
.I guess what's happening is my loop is iterating over signals, whether or not they're part of an Array, and for those that are, there is no explicit name and therefore it defaults to
$signal
(as can be seen inast.py
).It may well be the case that I'm testing my modules in a backward way (please tell me!) but I can't figure out a simple way to get at the result of
res
and check the values programmatically. Is this a bug? Is there a better way to do what I'm trying to do?Thoughts appreciated.