diff options
Diffstat (limited to 'archive/myhdl/hdl/reset_sync.py')
-rw-r--r-- | archive/myhdl/hdl/reset_sync.py | 109 |
1 files changed, 109 insertions, 0 deletions
diff --git a/archive/myhdl/hdl/reset_sync.py b/archive/myhdl/hdl/reset_sync.py new file mode 100644 index 0000000..af03075 --- /dev/null +++ b/archive/myhdl/hdl/reset_sync.py @@ -0,0 +1,109 @@ +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() + |