In the following code, if I use instances()
in the testbench, everything works as expected. If I return the instances by listing them explicitly, fall and rise stay low no matter what I do. (I can even explicitly say rise.next = 1
, and it will still be low.) I suppose this is a bug.
"""Edge detector for asynchronous signals"""
from myhdl import Signal, ResetSignal
from myhdl import intbv, concat
from myhdl import block, always_seq
from myhdl import instance, delay, StopSimulation, instances
from random import randrange
@block
def edge_detect(clk, reset, async_signal, rise, fall):
"""
Ports:
clk: clock to which all logic is synchronized
reset: reset
async_signal asynchronous signal input
rise rising edge detected
fall falling edge detected
"""
# History shift register
history = intbv(0)[3:]
@always_seq(clk.posedge, reset=reset)
def logic():
"""Detect rising and falling edges in the asynchronous input signal."""
rise.next = history[1] and not history[2]
fall.next = history[2] and not history[1]
history[:] = concat(history[2:], async_signal)
return logic
# Auxiliary functions
def convert(hdl):
"""Convert the design to HDL"""
clk = Signal(bool(0))
reset = ResetSignal(0, active=1, async=True)
async_signal, rise, fall = [Signal(bool(0)) for _ in range(3)]
rtl = edge_detect(clk, reset, async_signal, rise, fall)
rtl.convert(hdl)
@block
def edge_testbench():
"""Testbench for the edge detector logic"""
clk = Signal(bool(0))
reset = ResetSignal(0, active=1, async=True)
async_signal, rise, fall = [Signal(bool(0)) for _ in range(3)]
rtl = edge_detect(clk, reset, async_signal, rise, fall)
(lambda *args: None)(rtl) # Suppress warning
@instance
def clk_gen():
"""Generate bus clock"""
while True:
yield delay(10) # ns, clk = 50 MHz
clk.next = not clk
@instance
def stim():
"""Generate random asynchronous signal"""
for _ in range(100):
yield clk.negedge
yield delay(100 + randrange(200)) # ns, clk = 50 MHz
async_signal.next = not async_signal
raise StopSimulation
#return instances()
return clk_gen, stim
if __name__ == "__main__":
convert('VHDL')
TB = edge_testbench()
TB.config_sim(backend='myhdl', trace=True)
TB.run_sim(duration=None)
TB.quit_sim()