X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=gram%2Fcompat.py;h=49ae71013312da80091197c800e51b072b916aa4;hb=0beb6a640efd8fed1f11ee5cbb333fbdc5207fbf;hp=90ebf3c3ea69eea6e40fcd7373f99dcfd07d09b6;hpb=438544a84835ca22df8f79538540832028bf0ec4;p=gram.git diff --git a/gram/compat.py b/gram/compat.py index 90ebf3c..49ae710 100644 --- a/gram/compat.py +++ b/gram/compat.py @@ -1,7 +1,14 @@ +# This file is Copyright (c) 2020 LambdaConcept + +import unittest + from nmigen import * +from nmigen import tracer from nmigen.compat import Case +from nmigen.back.pysim import * + +__ALL__ = ["delayed_enter", "RoundRobin", "Timeline", "CSRPrefixProxy"] -__ALL__ = ["delayed_enter", "RoundRobin", "Timeline"] def delayed_enter(m, src, dst, delay): assert delay > 0 @@ -20,9 +27,8 @@ def delayed_enter(m, src, dst, delay): with m.State(statename): m.next = deststate -# Original nMigen implementation by HarryHo90sHK class RoundRobin(Elaboratable): - """A round-robin scheduler. + """A round-robin scheduler. (HarryHo90sHK) Parameters ---------- n : int @@ -36,6 +42,7 @@ class RoundRobin(Elaboratable): stb : Signal() Strobe signal to enable granting access to the next device requesting. Externally driven. """ + def __init__(self, n): self.n = n self.request = Signal(n) @@ -45,19 +52,23 @@ class RoundRobin(Elaboratable): def elaborate(self, platform): m = Module() - with m.If(self.stb): - with m.Switch(self.grant): - for i in range(self.n): - with m.Case(i): - for j in reversed(range(i+1, i+self.n)): - # If i+1 <= j < n, then t == j; (after i) - # If n <= j < i+n, then t == j - n (before i) - t = j % self.n - with m.If(self.request[t]): - m.d.sync += self.grant.eq(t) + if self.n == 1: + m.d.comb += self.grant.eq(0) + else: + with m.If(self.stb): + with m.Switch(self.grant): + for i in range(self.n): + with m.Case(i): + for j in reversed(range(i+1, i+self.n)): + # If i+1 <= j < n, then t == j; (after i) + # If n <= j < i+n, then t == j - n (before i) + t = j % self.n + with m.If(self.request[t]): + m.d.sync += self.grant.eq(t) return m + class Timeline(Elaboratable): def __init__(self, events): self.trigger = Signal() @@ -94,3 +105,19 @@ class Timeline(Elaboratable): m.d.sync += e[1] return m + + +class CSRPrefixProxy: + def __init__(self, bank, prefix): + self._bank = bank + self._prefix = prefix + + def csr(self, width, access, *, addr=None, alignment=None, name=None, + src_loc_at=0): + if name is not None and not isinstance(name, str): + raise TypeError("Name must be a string, not {!r}".format(name)) + name = name or tracer.get_var_name(depth=2 + src_loc_at).lstrip("_") + + prefixed_name = "{}_{}".format(self._prefix, name) + return self._bank.csr(width=width, access=access, addr=addr, + alignment=alignment, name=prefixed_name)