from typing import Callable from myhdl import * from myhdl_wrap import Myhdl_Wrapper import random from random import randint random.seed(13) class ResetSync(Myhdl_Wrapper): def __init__(self): super().__init__() # Main code, this is the actual logic @staticmethod @block def ResetSync(clk : Signal, async_reset : Signal, sync_reset : Signal): # this must be the same name as the class name sync = Signal(False) guard = sync_reset @instance def logic(): while True: yield clk.posedge, async_reset.negedge if not async_reset: guard.next = False sync.next = False else: guard.next = sync sync.next = True return logic @block def tb(self, func: Callable): async_reset = Signal(False) sync_reset = Signal(False) clk = Signal(False) dut = func(clk=clk, async_reset=async_reset, sync_reset=sync_reset) @always(delay(2)) def clock_gen(): clk.next = not clk @instance def monitor_async(): while True: yield async_reset.negedge yield delay(1) assert sync_reset == False, 'Reset not asynchronous on falling edge' @instance def monitor_sync(): while True: yield async_reset.posedge assert sync_reset == False, 'sync Reset did not wait for first clock positive edge' yield clk.posedge, async_reset.negedge if async_reset == True: yield delay(0) assert sync_reset == False, 'sync Reset did not wait for second clock positive edge' yield clk.posedge, async_reset.negedge if async_reset == True: yield delay(0) assert sync_reset == True, 'sync Reset did not set' @instance def stimulus(): for _ in range(500): yield delay(randint(0,20)) if (now()+2) % 4 == 0: # do not create rising edge of reset and clk at the same time yield(delay(1)) async_reset.next = True yield delay(randint(0, 20)) async_reset.next = False raise StopSimulation return dut, clock_gen, monitor_async, monitor_sync, stimulus def export(self): async_reset = Signal(False) sync_reset = Signal(False) clk = Signal(bool(0)) # assigning signals, kargs only self._export(clk=clk, async_reset=async_reset, sync_reset=sync_reset) def test_reset_sync_sim(): hdl = ResetSync() hdl.sim() def test_reset_sync_cosim(): hdl = ResetSync() hdl.export() hdl.cosim()