summaryrefslogtreecommitdiff
path: root/archive
diff options
context:
space:
mode:
authorjjsuperpower <jjs29356@gmail.com>2022-09-05 20:04:52 -0500
committerjjsuperpower <jjs29356@gmail.com>2022-09-05 20:04:52 -0500
commit63626f2f6fc7e8912a349f120e37998cd1a05554 (patch)
treea4a10c448613bd683b79a2f5dbef892edef0d49d /archive
parent762e8b8786d8c921726c8ddc92a2513f42dad683 (diff)
moveing file around
Diffstat (limited to 'archive')
-rw-r--r--archive/myhdl/.gitignore7
-rw-r--r--archive/myhdl/Makefile13
-rw-r--r--archive/myhdl/hdl/constants.py8
-rw-r--r--archive/myhdl/hdl/multiply.py205
-rw-r--r--archive/myhdl/hdl/myhdl_wrap.py47
-rw-r--r--archive/myhdl/hdl/reset_sync.py109
-rw-r--r--archive/myhdl/hdl/shift_reg.py118
-rwxr-xr-xarchive/myhdl/myhdl.vpibin0 -> 32216 bytes
-rw-r--r--archive/myhdl/template.py69
-rw-r--r--archive/testing/async_reset.py21
-rw-r--r--archive/testing/multi_clock.py75
-rw-r--r--archive/testing/up_counter.py50
-rw-r--r--archive/testing/up_counter_tb.py30
13 files changed, 752 insertions, 0 deletions
diff --git a/archive/myhdl/.gitignore b/archive/myhdl/.gitignore
new file mode 100644
index 0000000..3f63f69
--- /dev/null
+++ b/archive/myhdl/.gitignore
@@ -0,0 +1,7 @@
+quartus
+gen_verilog
+simulation
+.vscode
+__pycache__
+**__pycache__
+.pytest_cache \ No newline at end of file
diff --git a/archive/myhdl/Makefile b/archive/myhdl/Makefile
new file mode 100644
index 0000000..10ace11
--- /dev/null
+++ b/archive/myhdl/Makefile
@@ -0,0 +1,13 @@
+
+HDL_FOLDER = ./hdl
+HDL = $(wildcard $(HDL_FOLDER)/*.py)
+
+
+test:
+ py.test --disable-pytest-warnings -v $(HDL)
+
+test-w:
+ py.test -v $(HDL)
+
+clean:
+ $(RM) -rf simulation/* gen_verilog/* hdl/__pycache__ .pytest_cache \ No newline at end of file
diff --git a/archive/myhdl/hdl/constants.py b/archive/myhdl/hdl/constants.py
new file mode 100644
index 0000000..ca02497
--- /dev/null
+++ b/archive/myhdl/hdl/constants.py
@@ -0,0 +1,8 @@
+SIM_DIR = './simulation/'
+GEN_VERILOG = './gen_verilog/'
+
+IVERILOG = 'iverilog '
+VVP = 'vvp -M ./ -m myhdl '
+
+RESET_ACTIVE = False
+RESET_INACTIVE = not RESET_ACTIVE \ No newline at end of file
diff --git a/archive/myhdl/hdl/multiply.py b/archive/myhdl/hdl/multiply.py
new file mode 100644
index 0000000..015f67a
--- /dev/null
+++ b/archive/myhdl/hdl/multiply.py
@@ -0,0 +1,205 @@
+from turtle import width
+from typing import Callable
+from myhdl import *
+from constants import RESET_ACTIVE
+from myhdl_wrap import Myhdl_Wrapper
+
+import random
+from random import randint
+
+random.seed(63)
+
+class Multiply(Myhdl_Wrapper):
+ def __init__(self):
+ super().__init__()
+
+ # Main code, this is the actual logic
+ @staticmethod
+ @block
+ def Multiply(clk : Signal, reset : Signal, a : Signal, b : Signal, prod : Signal, is_signed : Signal, ready : Signal, valid : Signal): # this must be the same name as the class name
+
+ width_a = len(a)
+ width_b = len(b)
+ width_prod = len(a) + len(b)
+
+ a0 = Signal(modbv(0)[width_a:])
+ b0 = Signal(modbv(0)[width_b:])
+ a1 = Signal(modbv(0)[width_a:])
+ b1 = Signal(modbv(0)[width_b:])
+ prod_raw = Signal(modbv(0)[width_prod:])
+
+ @instance
+ def logic():
+ while True:
+ yield valid.posedge
+ a0.next = a
+ b0.next = b
+
+ yield clk.posedge
+ ready.next = False
+
+ if not is_signed:
+ a1.next = a0
+ b1.next = b0
+ else:
+ if(a0.signed() < 0):
+ a1.next = -a0.signed()
+ else:
+ a1.next = a0
+
+ if(b0.signed() < 0):
+ b1.next = -b0.signed()
+ else:
+ b1.next = b0
+
+ prod_raw.next = a1 * b1
+
+ if is_signed:
+ if (a0[width_a-1] ^ b0[width_b-1]) == 1:
+ prod.next = -prod_raw
+ else:
+ prod.next = prod_raw
+ pass
+ else:
+ prod.next = prod_raw
+
+ ready.next = True
+
+ return logic
+
+
+ @block
+ def tb(self, func: Callable):
+ reset = Signal(False)
+ clk = Signal(bool(0))
+ a = Signal(intbv(0)[32:])
+ b = Signal(intbv(0)[32:])
+ prod = Signal(modbv(0)[64:])
+ is_signed = Signal(bool(0))
+ ready = Signal(bool(1))
+ valid = Signal(bool(0))
+
+ a_signed = intbv(0, -int(a.max/2), int(a.max/2)-1)
+ b_signed = intbv(0, -int(b.max/2), int(b.max/2)-1)
+
+
+ dut = func(clk=clk, reset=reset, a=a, b=b, prod=prod, is_signed=is_signed, ready=ready, valid=valid)
+
+ @always(delay(2))
+ def clock_gen():
+ clk.next = not clk
+
+ @instance
+ def monitor():
+ # print(f"ready: {ready}, valid: {valid}")
+ # print("-"*20)
+ while True:
+ yield ready, valid
+ # print(f"ready: {ready}, valid: {valid}")
+
+ @instance
+ def stimulus():
+ yield clk.negedge
+
+ # unsigned test
+ for i in range(30):
+ a_int = randint(a.min, a.max-1)
+ b_int = randint(b.min, b.max-1)
+ a.next = a_int
+ b.next = b_int
+
+ valid.next = True
+ yield ready.negedge
+ valid.next = False
+
+ yield ready.posedge
+ yield delay(1)
+ assert int(prod) == a_int * b_int, "Unsigned multiplication error random"
+
+ # unsigned extremes test
+ for a_int in (a.min, a.max-1):
+ for b_int in (b.min, b.max-1):
+ a.next = a_int
+ b.next = b_int
+
+ valid.next = True
+ yield ready.negedge
+ valid.next = False
+
+ yield ready.posedge
+ yield delay(1)
+
+ assert int(prod) == a_int * b_int, "Unsigned multiplication error extreme"
+
+
+ is_signed.next = True
+ yield clk.negedge
+
+ for i in range(30):
+ a_int = randint(a_signed.min, a_signed.max-1)
+ b_int = randint(b_signed.min, b_signed.max-1)
+
+ a_signed[:] = a_int
+ b_signed[:] = b_int
+ a.next = a_signed.unsigned()
+ b.next = b_signed.unsigned()
+
+ valid.next = True
+ yield ready.negedge
+ valid.next = False
+
+ yield ready.posedge
+ yield delay(1)
+
+ # print('-'*30)
+ # print(prod)
+ # print(a_int * b_int)
+
+ assert int(prod.signed()) == a_int * b_int, "Signed multiplication error random"
+
+
+ for a_int in (a_signed.min, 0, a_signed.max-1):
+ for b_int in (b_signed.min, 0, b_signed.max-1):
+
+ a_signed[:] = a_int
+ b_signed[:] = b_int
+ a.next = a_signed.unsigned()
+ b.next = b_signed.unsigned()
+
+ valid.next = True
+ yield ready.negedge
+ valid.next = False
+
+ yield ready.posedge
+ yield delay(1)
+
+ assert int(prod.signed()) == a_int * b_int, "Signed multiplication error extreme"
+
+
+ raise StopSimulation
+
+
+ return dut, clock_gen, monitor, stimulus
+
+ def export(self):
+ reset = Signal(False)
+ clk = Signal(False)
+ a = Signal(intbv(0)[32:])
+ b = Signal(intbv(0)[32:])
+ prod = Signal(modbv(0)[64:])
+ is_signed = Signal(False)
+ ready = Signal(True)
+ valid = Signal(False)
+
+ # assigning signals, kargs only
+ self._export(clk=clk, reset=reset, a=a, b=b, prod=prod, is_signed=is_signed, ready=ready, valid=valid)
+
+
+def test_template_sim():
+ hdl = Multiply()
+ hdl.sim()
+
+def test_template_cosim():
+ hdl = Multiply()
+ hdl.export()
+ hdl.cosim()
diff --git a/archive/myhdl/hdl/myhdl_wrap.py b/archive/myhdl/hdl/myhdl_wrap.py
new file mode 100644
index 0000000..56c8c5b
--- /dev/null
+++ b/archive/myhdl/hdl/myhdl_wrap.py
@@ -0,0 +1,47 @@
+import os
+from myhdl import *
+from constants import *
+
+class Myhdl_Wrapper():
+ def __init__(self):
+ self.class_name = self.__class__.__name__
+
+ def _export(self, **kargs):
+ inst = getattr(self, self.class_name)(**kargs)
+ inst.convert(hdl='Verilog', path=GEN_VERILOG, name=f"{self.class_name}")
+
+ test_bench_file = GEN_VERILOG + 'tb_' +self.class_name + '.v'
+ test_bench_tmp_file = GEN_VERILOG + '~tb_' +self.class_name + '.v'
+
+ # this is needed to generate cosim vcd file
+ with open(test_bench_file) as f_old, open(test_bench_tmp_file, 'w') as f_new:
+ lines = f_old.readlines()
+ for line in lines:
+ f_new.write(line)
+ if 'initial begin' in line:
+ f_new.write('\n')
+ f_new.write(' // Needed to create vcd file\n')
+ f_new.write(f' $dumpfile ("{SIM_DIR + self.class_name}_cosim.vcd");\n')
+ f_new.write(f' $dumpvars(0, tb_{self.class_name});\n')
+ f_new.write('\n')
+ os.rename(test_bench_tmp_file, test_bench_file)
+
+
+
+ # This function links myhdl to icarus verilog sim
+ def _cosim(self, **kargs): #these should have the same signals as logic(),
+
+ iverilog_cmd = IVERILOG + f"-o {SIM_DIR}{self.class_name}.o {GEN_VERILOG}{self.class_name}.v {GEN_VERILOG}tb_{self.class_name}.v"
+ vvp_cmd = VVP + f"{SIM_DIR}{self.class_name}.o"
+
+ os.system(iverilog_cmd)
+ return Cosimulation(vvp_cmd, **kargs)
+
+ def sim(self):
+ tb = self.tb(getattr(self, self.class_name))
+ tb.config_sim(trace=True, tracebackup=False, directory=SIM_DIR, filename=f"{self.class_name}_sim")
+ tb.run_sim()
+
+ def cosim(self):
+ tb = self.tb(self._cosim)
+ tb.run_sim() \ No newline at end of file
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()
+
diff --git a/archive/myhdl/hdl/shift_reg.py b/archive/myhdl/hdl/shift_reg.py
new file mode 100644
index 0000000..9c1c6be
--- /dev/null
+++ b/archive/myhdl/hdl/shift_reg.py
@@ -0,0 +1,118 @@
+from myhdl import *
+from myhdl_wrap import Myhdl_Wrapper
+
+import random
+from random import randint
+
+random.seed(63)
+
+class ShiftReg(Myhdl_Wrapper):
+ def __init__(self):
+ super().__init__()
+
+ # Main code, this is the actual logic
+ @staticmethod
+ @block
+ def ShiftReg(reset: Signal, clk: Signal, load: Signal, in0: Signal, out0: Signal, left_right: Signal):
+
+ width = len(out0)
+
+ @instance
+ def shifter():
+ while True:
+ yield clk.posedge, reset.negedge
+
+ if not reset:
+ out0.next = load
+ else:
+ if not left_right:
+ out0.next[width:1] = out0[width-1:0]
+ out0.next[1:0] = in0
+ else:
+ out0.next[width-1:0] = out0[width:1]
+ out0.next[width:width-1] = in0
+
+ return shifter
+
+
+ @block
+ def tb(self, func):
+ reset = Signal(False)
+ clk = Signal(bool(0))
+ load = Signal(intbv(0xA5)[8:])
+ in0 = Signal(bool(0))
+ out0 = Signal(modbv(int(load))[8:])
+ left_right = Signal(bool(0))
+
+ dut = func(reset=reset, clk=clk, load=load, in0=in0, out0=out0, left_right=left_right)
+
+ @always(delay(2))
+ def clock_gen():
+ clk.next = not clk
+
+ @instance
+ def monitor():
+ last_val = out0
+
+ while True:
+ yield clk.posedge, reset.negedge
+ yield delay(1)
+
+ if reset == False:
+ assert out0 == load, "Is output is not zero at reset"
+
+ else:
+ if not left_right:
+ assert int(out0) == ((last_val << 1) & 0xFF) | int(in0), "Not shifting left correctly"
+ else:
+ assert int(out0) == ((last_val >> 1) & 0xFF) | (int(in0) << 7), "Not shifting rigth correctly"
+
+ last_val = int(out0)
+
+ @instance
+ def reset_test():
+ yield clk.negedge
+ reset.next = True
+ while True:
+ reset.next = True
+ yield delay(randint(25, 28))
+
+ reset.next = False
+ yield delay(randint(1,4))
+
+ @instance
+ def stimulus():
+ for i in range(20):
+ yield clk.negedge
+ left_right.next = 0
+ in0.next = randint(0, 1)
+
+ for i in range(20):
+ yield clk.negedge
+ left_right.next = 1
+ in0.next = randint(0, 1)
+
+ raise StopSimulation
+
+
+ return dut, clock_gen, monitor, stimulus, reset_test
+
+ def export(self):
+ reset = Signal(False)
+ clk = Signal(bool(0))
+ load = Signal(intbv(0xA5)[8:])
+ in0 = Signal(bool(0))
+ out0 = Signal(modbv(int(load))[8:])
+ left_right = Signal(bool(0))
+
+ self._export(reset=reset, clk=clk, load=load, in0=in0, out0=out0, left_right=left_right)
+
+
+def test_shift_reg_sim():
+ hdl = ShiftReg()
+ hdl.sim()
+
+def test_shift_reg_cosim():
+ hdl = ShiftReg()
+ hdl.export()
+ hdl.cosim()
diff --git a/archive/myhdl/myhdl.vpi b/archive/myhdl/myhdl.vpi
new file mode 100755
index 0000000..1b9d393
--- /dev/null
+++ b/archive/myhdl/myhdl.vpi
Binary files differ
diff --git a/archive/myhdl/template.py b/archive/myhdl/template.py
new file mode 100644
index 0000000..77eb18c
--- /dev/null
+++ b/archive/myhdl/template.py
@@ -0,0 +1,69 @@
+from typing import Callable
+from myhdl import *
+from myhdl_wrap import Myhdl_Wrapper
+
+import random
+from random import randint
+
+random.seed(63)
+
+class Template(Myhdl_Wrapper):
+ def __init__(self):
+ super().__init__()
+
+ # Main code, this is the actual logic
+ @staticmethod
+ @block
+ def Template(args): # this must be the same name as the class name
+
+ @instance
+ def logic():
+ while True:
+ ...
+
+ return logic
+
+
+ @block
+ def tb(self, func: Callable):
+ reset = Signal(False)
+ clk = Signal(False)
+ ...
+
+ dut = func(..., clk=clk, reset=reset)
+
+ @always(delay(...))
+ def clock_gen():
+ clk.next = not clk
+
+ @instance
+ def monitor():
+ while True:
+ ...
+
+ @instance
+ def stimulus():
+ ...
+
+ raise StopSimulation
+
+
+ return dut, clock_gen, monitor, stimulus
+
+ def export(self):
+ reset = Signal(False)
+ clk = Signal(False)
+ ...
+
+ # assigning signals, kargs only
+ self._export(..., clk=clk, reset=reset)
+
+
+def test_template_sim():
+ hdl = Template()
+ hdl.sim()
+
+def test_template_cosim():
+ hdl = Template()
+ hdl.export()
+ hdl.cosim()
diff --git a/archive/testing/async_reset.py b/archive/testing/async_reset.py
new file mode 100644
index 0000000..4760df7
--- /dev/null
+++ b/archive/testing/async_reset.py
@@ -0,0 +1,21 @@
+from amaranth import *
+from amaranth.cli import main
+
+
+class ClockDivisor(Elaboratable):
+ def __init__(self, factor):
+ self.v = Signal(factor)
+ self.o = Signal()
+
+ def elaborate(self, platform):
+ m = Module()
+ m.d.sync += self.v.eq(self.v + 1)
+ m.d.comb += self.o.eq(self.v[-1])
+ return m
+
+
+if __name__ == "__main__":
+ m = Module()
+ m.domains.sync = sync = ClockDomain("sync", async_reset=True)
+ m.submodules.ctr = ctr = ClockDivisor(factor=16)
+ main(m, ports=[ctr.o, sync.clk]) \ No newline at end of file
diff --git a/archive/testing/multi_clock.py b/archive/testing/multi_clock.py
new file mode 100644
index 0000000..e377156
--- /dev/null
+++ b/archive/testing/multi_clock.py
@@ -0,0 +1,75 @@
+import sys
+from amaranth import *
+from amaranth.back import verilog, cxxrtl
+from amaranth.cli import main
+from amaranth.sim import Simulator, Settle, Delay
+
+BASENAME = "multi_clock"
+
+class SubM(Elaboratable):
+ def __init__(self, domain=None):
+ self.inv = Signal()
+ self.domain=domain
+
+ def elaborate(self, platform):
+ m = Module()
+
+ m.d.sync += self.inv.eq(~self.inv)
+
+ return m
+
+class top(Elaboratable):
+ def __init__(self):
+ self.sig_slow = Signal()
+ self.sig_fast = Signal()
+
+ self.div = Signal(2)
+
+ def elaborate(self, platform):
+ m = Module()
+
+ m.domains += ClockDomain('slow')
+ m.d.sync += [self.div.eq(self.div + 1)]
+ m.d.comb += ClockSignal('slow').eq(self.div[-1])
+
+ m.submodules.subm1 = SubM()
+ m.submodules.subm2 = DomainRenamer("slow")(SubM())
+
+ m.d.sync += self.sig_fast.eq(m.submodules.subm1.inv)
+ m.d.slow += self.sig_slow.eq(m.submodules.subm2.inv)
+
+ return m
+
+def test_shift_reg():
+ dut = top()
+
+ def proc1():
+ for _ in range(16):
+ yield
+ yield Settle()
+
+ sim = Simulator(dut)
+ sim.add_clock(1e-6)
+ sim.add_sync_process(proc1)
+
+ with sim.write_vcd(BASENAME + '.vcd'):
+ sim.run()
+
+
+if __name__ == '__main__':
+
+ if sys.argv[1] == "sim":
+ test_shift_reg()
+ exit()
+
+ # m = ShiftReg(8)
+
+ # if sys.argv[1] == "v":
+ # out = verilog.convert(m, ports=m.ports)
+ # with open(BASENAME + '.v','w') as f:
+ # f.write(out)
+
+ # elif sys.argv[1] == "cc":
+ # out = cxxrtl.convert(m, ports=m.ports)
+ # with open(BASENAME + '.cc','w') as f:
+ # f.write(out)
diff --git a/archive/testing/up_counter.py b/archive/testing/up_counter.py
new file mode 100644
index 0000000..050a6b0
--- /dev/null
+++ b/archive/testing/up_counter.py
@@ -0,0 +1,50 @@
+from amaranth import *
+from amaranth.back import verilog
+
+
+class UpCounter(Elaboratable):
+ """
+ A 16-bit up counter with a fixed limit.
+
+ Parameters
+ ----------
+ limit : int
+ The value at which the counter overflows.
+
+ Attributes
+ ----------
+ en : Signal, in
+ The counter is incremented if ``en`` is asserted, and retains
+ its value otherwise.
+ ovf : Signal, out
+ ``ovf`` is asserted when the counter reaches its limit.
+ """
+
+ def __init__(self, limit):
+ self.limit = limit
+
+ # Ports
+ self.en = Signal()
+ self.ovf = Signal()
+
+ # State
+ self.count = Signal(16)
+
+ def elaborate(self, platform):
+ m = Module()
+
+ m.d.comb += self.ovf.eq(self.count == self.limit)
+
+ with m.If(self.en):
+ with m.If(self.ovf):
+ m.d.sync += self.count.eq(0)
+ with m.Else():
+ m.d.sync += self.count.eq(self.count + 1)
+
+ return m
+
+ def to_v(self):
+ return verilog.convert(self, ports=[self.en, self.ovf])
+
+top = UpCounter(25)
+print(top.to_v()) \ No newline at end of file
diff --git a/archive/testing/up_counter_tb.py b/archive/testing/up_counter_tb.py
new file mode 100644
index 0000000..7c2e8d2
--- /dev/null
+++ b/archive/testing/up_counter_tb.py
@@ -0,0 +1,30 @@
+from amaranth.sim import Simulator
+from up_counter import UpCounter
+
+dut = UpCounter(25)
+
+
+def bench():
+ # Disabled counter should not overflow.
+ yield dut.en.eq(0)
+ for _ in range(30):
+ yield
+ assert not (yield dut.ovf)
+
+ # Once enabled, the counter should overflow in 25 cycles.
+ yield dut.en.eq(1)
+ for _ in range(25):
+ yield
+ assert not (yield dut.ovf)
+ yield
+ assert (yield dut.ovf)
+
+ # The overflow should clear in one cycle.
+ yield
+ assert not (yield dut.ovf)
+
+sim = Simulator(dut)
+sim.add_clock(1e-6) # 1 MHz
+sim.add_sync_process(bench)
+with sim.write_vcd("up_counter.vcd"):
+ sim.run() \ No newline at end of file