3 from . import Peripheral
6 __all__
= ["TimerPeripheral"]
9 class TimerPeripheral(Peripheral
, Elaboratable
):
12 A general purpose down-counting timer peripheral.
17 Reload value of counter. When `ctr` reaches 0, it is automatically reloaded with this value.
25 zero : edge-triggered (rising)
26 Counter value reached 0.
35 bus : :class:`nmigen_soc.wishbone.Interface`
36 Wishbone bus interface.
37 irq : :class:`IRQLine`
40 def __init__(self
, width
):
43 if not isinstance(width
, int) or width
< 0:
44 raise ValueError("Counter width must be a non-negative integer, not {!r}"
47 raise ValueError("Counter width cannot be greater than 32 (was: {})"
51 bank
= self
.csr_bank()
52 self
._reload
= bank
.csr(width
, "rw")
53 self
._en
= bank
.csr( 1, "rw")
54 self
._ctr
= bank
.csr(width
, "rw")
56 self
._zero
_ev
= self
.event(mode
="rise")
58 self
._bridge
= self
.bridge(data_width
=32, granularity
=8, alignment
=2)
59 self
.bus
= self
._bridge
.bus
60 self
.irq
= self
._bridge
.irq
62 def elaborate(self
, platform
):
64 m
.submodules
.bridge
= self
._bridge
66 with m
.If(self
._en
.r_data
):
67 with m
.If(self
._ctr
.r_data
== 0):
68 m
.d
.comb
+= self
._zero
_ev
.stb
.eq(1)
69 m
.d
.sync
+= self
._ctr
.r_data
.eq(self
._reload
.r_data
)
71 m
.d
.sync
+= self
._ctr
.r_data
.eq(self
._ctr
.r_data
- 1)
73 with m
.If(self
._reload
.w_stb
):
74 m
.d
.sync
+= self
._reload
.r_data
.eq(self
._reload
.w_data
)
75 with m
.If(self
._en
.w_stb
):
76 m
.d
.sync
+= self
._en
.r_data
.eq(self
._en
.w_data
)
77 with m
.If(self
._ctr
.w_stb
):
78 m
.d
.sync
+= self
._ctr
.r_data
.eq(self
._ctr
.w_data
)