add separate DummyPLL module, according to API discussed at
authorLuke Kenneth Casson Leighton <lkcl@lkcl.net>
Tue, 10 Nov 2020 15:49:56 +0000 (15:49 +0000)
committerLuke Kenneth Casson Leighton <lkcl@lkcl.net>
Tue, 10 Nov 2020 16:40:41 +0000 (16:40 +0000)
https://bugs.libre-soc.org/show_bug.cgi?id=155#c21
;

src/soc/clock/dummypll.py [new file with mode: 0644]
src/soc/clock/select.py

diff --git a/src/soc/clock/dummypll.py b/src/soc/clock/dummypll.py
new file mode 100644 (file)
index 0000000..c3d76ab
--- /dev/null
@@ -0,0 +1,36 @@
+"""a Dummy PLL module to be replaced by a real one
+"""
+
+from nmigen import (Module, Signal, Elaboratable)
+from nmigen.cli import rtlil
+
+class DummyPLL(Elaboratable):
+    def __init__(self):
+        self.clk_24_i = Signal(reset_less=True) # 24 mhz external incoming
+        self.clk_sel_i = Signal(2, reset_less=True) # PLL selection
+        self.clk_pll_o = Signal(reset_less=True)  # output fake PLL clock
+        self.pll_18_o = Signal(reset_less=True)  # 16-divide from PLL
+        self.clk_lck_o = Signal(reset_less=True)  # output fake PLL "lock" 
+
+    def elaborate(self, platform):
+        m = Module()
+        m.d.comb += self.clk_pll_o.eq(self.clk_24_i) # just pass through
+        # just get something, stops yosys destroying (optimising) these out
+        m.d.comb += self.pll_18_o.eq(self.clk_24_i)
+        with m.If(clk_sel_i == 0):
+            m.d.comb += self.clk_lck_o.eq(self.clk_24_i)
+
+        return m
+
+    def ports(self):
+        return [self.clk_24_i, self.clk_sel_i, self.clk_pll_o,
+                self.pll_18_o, self.clk_lck_o]
+
+
+if __name__ == '__main__':
+    dut = ClockSelect()
+
+    vl = rtlil.convert(dut, ports=dut.ports())
+    with open("test_dummy_pll.il", "w") as f:
+        f.write(vl)
+
index 5ca7ba9065fcc4f7e038e2c74375f7cc7e4fa6b3..fbf650477ec211190fb0a0602186010ebda85abc 100644 (file)
@@ -1,91 +1,31 @@
 """Clock selection.
-
-* PLL @ 300mhz input generates a div-6 "test" output
-* clock select sets the source
-  - 0b000 - CLK_24 (direct)
-  - 0b001 - PLL / 6
-  - 0b010 - PLL / 4
-  - 0b011 - PLL / 3
-  - 0b100 - PLL / 2
-  - 0b101 - PLL
-  - 0b110 - ZERO (direct driving in combination with ONE)
-  - 0b111 - ONE
-* this is all assumed to be driven by the "PLL CLK".
-  the CLK_24 is the default in case PLL is unstable
 """
 
 from nmigen import (Module, Array, Signal, Mux, Elaboratable, ClockSignal,
                     ResetSignal)
 from nmigen.cli import rtlil
 
-CLK_24 = 0b000 # this is the default (clk_sel_i = 0 on reset)
-PLL6 = 0b001
-PLL4 = 0b010
-PLL3 = 0b011
-PLL2 = 0b100
-PLL  = 0b101
-ZERO = 0b110
-ONE  = 0b111
-
 
 class ClockSelect(Elaboratable):
     def __init__(self):
 
-        self.clk_24_i = Signal() # 24 mhz external incoming
-        self.pll_48_o = Signal()  # 6-divide (test signal) from PLL
-        self.clk_sel_i = Signal(3) # clock source selection
-        self.core_clk_o = Signal() # main core clock (selectable)
+        self.clk_sel_i = Signal() # clock source selection
+        self.clk_24_i = Signal(reset_less=True) # 24 mhz external incoming
+        self.pll_clk_i = Signal(reset_less=True)  # PLL input
+        self.core_clk_o = Signal(reset_less=True) # main core clock (selectable)
 
     def elaborate(self, platform):
         m = Module()
         comb, sync = m.d.comb, m.d.sync
 
-        # array of clocks (selectable by clk_sel_i)
-        clkgen = Array([Signal(name="clk%d" % i) for i in range(8)])
-        counter3 = Signal(2) # for divide-by-3
-
         # set up system, zero and one clocks
-        comb += clkgen[CLK_24].eq(self.clk_24_i) # 1st is external 24mhz
-        comb += clkgen[ZERO].eq(0) # LOW (use with ONE for direct driving)
-        comb += clkgen[ONE].eq(1) # HI
-
-        # (always) generate PLL-driven signals: /2/3/4/6
-        sync += clkgen[PLL2].eq(~clkgen[PLL2]) # half PLL rate
-        with m.If(clkgen[PLL2]):
-            sync += clkgen[PLL4].eq(~clkgen[PLL4]) # quarter PLL rate
-        with m.If(counter3 == 2):
-            sync += counter3.eq(0)
-            sync += clkgen[PLL3].eq(~clkgen[PLL3]) # 1/3 PLL rate
-            with m.If(clkgen[PLL3]):
-                sync += clkgen[PLL6].eq(~clkgen[PLL6]) # 1/6 PLL rate
-        with m.Else():
-            sync += counter3.eq(counter3+1)
-
-        # select from available array of clock sources
-        comb += self.core_clk_o.eq(clkgen[self.clk_sel_i])
-
-        # 48mhz output is PLL/6
-        comb += self.pll_48_o.eq(clkgen[PLL6])
-
-        return m
-
-    def ports(self):
-        return [self.clk_24_i, self.pll_48_o, self.clk_sel_i, self.core_clk_o]
-
-
-class DummyPLL(Elaboratable):
-    def __init__(self):
-        self.clk_24_i = Signal() # 24 mhz external incoming
-        self.clk_pll_o = Signal()  # output fake PLL clock
-
-    def elaborate(self, platform):
-        m = Module()
-        m.d.comb += self.clk_pll_o.eq(self.clk_24_i) # just pass through
+        comb += self.core_clk_o.eq(Mux(self.clk_sel_i,
+                                       self.pll_clk_i, self.clk_24_i))
 
         return m
 
     def ports(self):
-        return [self.clk_24_i, self.clk_pll_o]
+        return [self.clk_24_i, self.pll_18_o, self.clk_sel_i, self.core_clk_o]
 
 
 if __name__ == '__main__':