freq counter: refactor
use CSR instead of CSRStatus add FSM to support CSR
parent
30316d585d
commit
adc7554f79
|
@ -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):
|
||||
|
|
Loading…
Reference in New Issue