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.
 """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
 
 """
 
 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):
 
 
 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
 
 
     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
         # 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 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__':
 
 
 if __name__ == '__main__':