diff --git a/src/gateware/wrpll.py b/src/gateware/wrpll.py index 404d41c..8492882 100644 --- a/src/gateware/wrpll.py +++ b/src/gateware/wrpll.py @@ -8,47 +8,56 @@ from si549 import Si549 class FrequencyCounter(Module, AutoCSR): def __init__(self, domains, counter_width=24): - for domain in domains: - name = "counter_" + domain - counter = CSRStatus(counter_width, name=name) - setattr(self, name, counter) - self.update_en = CSRStorage() + self.update = CSR() + + counter_reset = Signal() + counter_stb = Signal() + timer = Signal(max=2**counter_width) # # # - timer = Signal(counter_width) - timer_tick = Signal() - self.sync +=[ - If(self.update_en.storage, - Cat(timer, timer_tick).eq(timer + 1) - ).Else( - Cat(timer, timer_tick).eq(0) + fsm = FSM() + self.submodules += fsm + + fsm.act("IDLE", + If(self.update.re, + counter_reset.eq(1), + NextValue(timer, 2**counter_width - 1), + NextState("COUNTING") ) - ] + ) + fsm.act("COUNTING", + If(timer != 0, + NextValue(timer, timer - 1) + ).Else( + counter_stb.eq(1), + NextState("IDLE") + ) + ) for domain in domains: - sync_domain = getattr(self.sync, domain) divider = Signal(2) - sync_domain += divider.eq(divider + 1) - - divided = Signal() - sync_domain += divided.eq(divider[-1]) divided_sys = Signal() - self.specials += MultiReg(divided, divided_sys) - divided_sys_r = Signal() - divided_tick = Signal() + rising = Signal() + + name = "counter_" + domain + counter_csr = CSRStatus(counter_width, name=name) + setattr(self, name, counter_csr) + counter = Signal(counter_width) + + sync_domain = getattr(self.sync, domain) + sync_domain += divider.eq(divider + 1) + self.specials += MultiReg(divider[-1], divided_sys) self.sync += [ divided_sys_r.eq(divided_sys), - divided_tick.eq(divided_sys & ~divided_sys_r) + rising.eq(divided_sys & ~divided_sys_r) ] - counter = Signal(counter_width) - counter_csr = getattr(self, "counter_" + domain) self.sync += [ - If(timer_tick, counter_csr.status.eq(counter)), - If(divided_tick, counter.eq(counter + 1)), - If(~self.update_en.storage, counter.eq(0)), + If(counter_reset, counter.eq(0)), + If(rising, counter.eq(counter + 1)), + If(counter_stb, counter_csr.status.eq(counter)) ] class SkewTester(Module, AutoCSR):