freq counter: refactor

use CSR instead of CSRStatus
add FSM to support CSR
morgan 2024-03-28 12:23:01 +08:00
parent 30316d585d
commit adc7554f79
1 changed files with 36 additions and 27 deletions

View File

@ -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):