cores/cpu/vexriscv: add VexRiscvTimer and use it for the linux variant
authorFlorent Kermarrec <florent@enjoy-digital.fr>
Fri, 3 May 2019 07:30:26 +0000 (09:30 +0200)
committerFlorent Kermarrec <florent@enjoy-digital.fr>
Fri, 3 May 2019 07:30:26 +0000 (09:30 +0200)
litex/soc/cores/cpu/vexriscv/core.py

index 884915ae19abbcf501d80ca5419a1fade654a3df..e40a2d38e8aa8e4b851d3880c2bb807e7d566092 100644 (file)
@@ -3,7 +3,7 @@ import os
 from migen import *
 
 from litex.soc.interconnect import wishbone
-from litex.soc.interconnect.csr import AutoCSR, CSRStatus, CSRStorage
+from litex.soc.interconnect.csr import *
 
 
 CPU_VARIANTS = {
@@ -35,10 +35,29 @@ GCC_FLAGS = {
     "standard+debug":   "-march=rv32im     -mabi=ilp32",
     "full":             "-march=rv32im     -mabi=ilp32",
     "full+debug":       "-march=rv32im     -mabi=ilp32",
-    "linux":            "-march=rv32imac   -mabi=ilp32",
+    "linux":            "-march=rv32ima    -mabi=ilp32",
 }
 
 
+class VexRiscvTimer(Module, AutoCSR):
+    def __init__(self):
+        self._latch = CSR()
+        self._time = CSRStatus(64)
+        self._time_cmp = CSRStorage(64, reset=2**64-1)
+        self.interrupt = Signal()
+
+        # # #
+
+        time = Signal(64)
+        self.sync += time.eq(time + 1)
+        self.sync += If(self._latch.re, self._time.status.eq(time))
+
+        time_cmp = Signal(64, reset=2**64-1)
+        self.sync += If(self._latch.re, time_cmp.eq(self._time_cmp.storage))
+
+        self.comb += self.interrupt.eq(time >= time_cmp)
+
+
 class VexRiscv(Module, AutoCSR):
     @property
     def name(self):
@@ -106,6 +125,9 @@ class VexRiscv(Module, AutoCSR):
                 i_dBusWishbone_ACK=dbus.ack,
                 i_dBusWishbone_ERR=dbus.err)
 
+        if "linux" in variant:
+            self.add_timer()
+
         if "debug" in variant:
             self.add_debug()
 
@@ -195,6 +217,10 @@ class VexRiscv(Module, AutoCSR):
             o_debug_resetOut=self.o_resetOut
         )
 
+    def add_timer(self):
+        self.submodules.timer = VexRiscvTimer()
+        self.cpu_params.update(i_timerInterrupt=self.timer.interrupt)
+
     @staticmethod
     def add_sources(platform, variant="standard"):
         cpu_filename = CPU_VARIANTS[variant] + ".v"