diff --git a/common/csrbase.h b/common/csrbase.h
index a94d5c791..cc44fb3c9 100644
--- a/common/csrbase.h
+++ b/common/csrbase.h
@@ -4,6 +4,7 @@
 #define UART_BASE	0xe0000000
 #define DFII_BASE	0xe0000800
 #define ID_BASE		0xe0001000
-#define MINIMAC_BASE	0xe0001800
+#define TIMER0_BASE	0xe0001800
+#define MINIMAC_BASE	0xe0002000
 
 #endif /* __CSRBASE_H */
diff --git a/milkymist/timer/__init__.py b/milkymist/timer/__init__.py
new file mode 100644
index 000000000..85b5cb53a
--- /dev/null
+++ b/milkymist/timer/__init__.py
@@ -0,0 +1,30 @@
+from migen.fhdl.structure import *
+from migen.bank.description import *
+from migen.bank.eventmanager import *
+from migen.bank import csrgen
+
+class Timer:
+	def __init__(self, address, width=32):
+		self._en = RegisterField("en")
+		self._value = RegisterField("value", width, access_dev=READ_WRITE)
+		self._reload = RegisterField("reload", width)
+		regs = [self._en, self._value, self._reload]
+		
+		self.event = EventSourceLevel()
+		self.events = EventManager(self.event)
+		
+		self.bank = csrgen.Bank(regs + self.events.get_registers(), address=address)
+
+	def get_fragment(self):
+		comb = [
+			If(self._value.field.r == 0,
+				self._value.field.w.eq(self._reload.field.r)
+			).Else(
+				self._value.field.w.eq(self._value.field.r - 1)
+			),
+			self._value.field.we.eq(self._en.field.r),
+			self.event.trigger.eq(self._value.field.r != 0)
+		]
+		return Fragment(comb) \
+			+ self.events.get_fragment() \
+			+ self.bank.get_fragment()
diff --git a/top.py b/top.py
index 323981dfa..ae9e5ec77 100644
--- a/top.py
+++ b/top.py
@@ -5,7 +5,7 @@ from migen.fhdl.structure import *
 from migen.fhdl import verilog, autofragment
 from migen.bus import wishbone, wishbone2asmi, csr, wishbone2csr, dfi
 
-from milkymist import m1crg, lm32, norflash, uart, sram, s6ddrphy, dfii, asmicon, identifier, minimac3
+from milkymist import m1crg, lm32, norflash, uart, sram, s6ddrphy, dfii, asmicon, identifier, timer, minimac3
 from cmacros import get_macros
 from constraints import Constraints
 
@@ -117,10 +117,12 @@ def get():
 	#
 	uart0 = uart.UART(csr_offset("UART"), clk_freq, baud=115200)
 	identifier0 = identifier.Identifier(csr_offset("ID"), 0x4D31, version)
+	timer0 = timer.Timer(csr_offset("TIMER0"))
 	csrcon0 = csr.Interconnect(wishbone2csr0.csr, [
 		uart0.bank.interface,
 		dfii0.bank.interface,
 		identifier0.bank.interface,
+		timer0.bank.interface,
 		minimac0.bank.interface
 	])
 	
@@ -129,7 +131,8 @@ def get():
 	#
 	interrupts = Fragment([
 		cpu0.interrupt[0].eq(uart0.events.irq),
-		cpu0.interrupt[1].eq(minimac0.events.irq)
+		cpu0.interrupt[1].eq(timer0.events.irq),
+		cpu0.interrupt[2].eq(minimac0.events.irq)
 	])
 	
 	#