blob: 9754180cb8292d24fddb8a12cf1f672edd536583 [file] [log] [blame]
Tim Edwardscd64af52020-08-07 11:11:58 -04001// Digital PLL (ring oscillator + controller)
2// Technically this is a frequency locked loop, not a phase locked loop.
3
4`include "digital_pll_controller.v"
5`include "ring_osc2x13.v"
6
shalanfd13eb52020-08-21 16:48:07 +02007module digital_pll(
8`ifdef LVS
9 vdd,
10 vss,
11`endif
Tim Edwards04ba17f2020-10-02 22:27:50 -040012 resetb, extclk_sel, osc, clockc, clockp, clockd, div, sel, dco, ext_trim);
shalanfd13eb52020-08-21 16:48:07 +020013
14`ifdef LVS
15 input vdd;
16 input vss;
17`endif
Tim Edwardscd64af52020-08-07 11:11:58 -040018
Tim Edwards04ba17f2020-10-02 22:27:50 -040019 input resetb; // Sense negative reset
Tim Edwardscd64af52020-08-07 11:11:58 -040020 input extclk_sel; // External clock select (acts as 2nd reset)
21 input osc; // Input oscillator to match
22 input [4:0] div; // PLL feedback division ratio
23 input [2:0] sel; // Core clock select
24 input dco; // Run in DCO mode
25 input [25:0] ext_trim; // External trim for DCO mode
26
27 output clockc; // Selected core clock output
28 output [1:0] clockp; // Two 90 degree clock phases
29 output [3:0] clockd; // Divided clock (2, 4, 8, 16)
30
31 wire [25:0] itrim; // Internally generated trim bits
32 wire [25:0] otrim; // Trim bits applied to the ring oscillator
33 wire [3:0] nint; // Internal divided down clocks
Tim Edwards04ba17f2020-10-02 22:27:50 -040034 wire reset; // Internal positive sense reset
35 wire resetbb; // Internal buffered negative sense reset
Tim Edwardscd64af52020-08-07 11:11:58 -040036 wire creset; // Controller reset
37 wire ireset; // Internal reset (external reset OR extclk_sel)
38
39 assign ireset = reset | extclk_sel;
40
41 // In DCO mode: Hold controller in reset and apply external trim value
42 assign itrim = (dco == 1'b0) ? otrim : ext_trim;
43 assign creset = (dco == 1'b0) ? ireset : 1'b1;
44
45 ring_osc2x13 ringosc (
Tim Edwards04ba17f2020-10-02 22:27:50 -040046 .reset(ireset),
47 .trim(itrim),
48 .clockp(clockp)
Tim Edwardscd64af52020-08-07 11:11:58 -040049 );
50
51 digital_pll_controller pll_control (
Tim Edwards04ba17f2020-10-02 22:27:50 -040052 .reset(creset),
53 .clock(clockp[0]),
54 .osc(osc),
55 .div(div),
56 .trim(otrim)
Tim Edwardscd64af52020-08-07 11:11:58 -040057 );
58
59 // Select core clock output
60 assign clockc = (sel == 3'b000) ? clockp[0] :
shalanfd13eb52020-08-21 16:48:07 +020061 (sel == 3'b001) ? clockd[0] :
62 (sel == 3'b010) ? clockd[1] :
63 (sel == 3'b011) ? clockd[2] :
64 clockd[3];
Tim Edwardscd64af52020-08-07 11:11:58 -040065
Tim Edwards04ba17f2020-10-02 22:27:50 -040066 // Derive internal negative-sense reset from the input negative-sense reset
Tim Edwardscd64af52020-08-07 11:11:58 -040067
Tim Edwards04ba17f2020-10-02 22:27:50 -040068 sky130_fd_sc_hd__buf_8 irbb (
69 .A(resetb),
70 .X(resetbb)
Tim Edwardscd64af52020-08-07 11:11:58 -040071 );
72
73 // Create divided down clocks. The inverted output only comes
74 // with digital standard cells with inverted resets, so the
75 // reset has to be inverted as well.
76
Tim Edwardsef8312e2020-09-22 17:20:06 -040077 sky130_fd_sc_hd__dfrbp_1 idiv2 (
Tim Edwards04ba17f2020-10-02 22:27:50 -040078 .CLK(clockp[1]),
79 .D(clockd[0]),
80 .Q(nint[0]),
81 .Q_N(clockd[0]),
82 .RESET_B(resetbb)
Tim Edwardscd64af52020-08-07 11:11:58 -040083 );
84
Tim Edwardsef8312e2020-09-22 17:20:06 -040085 sky130_fd_sc_hd__dfrbp_1 idiv4 (
Tim Edwards04ba17f2020-10-02 22:27:50 -040086 .CLK(clockd[0]),
87 .D(clockd[1]),
88 .Q(nint[1]),
89 .Q_N(clockd[1]),
90 .RESET_B(resetbb)
Tim Edwardscd64af52020-08-07 11:11:58 -040091 );
92
Tim Edwardsef8312e2020-09-22 17:20:06 -040093 sky130_fd_sc_hd__dfrbp_1 idiv8 (
Tim Edwards04ba17f2020-10-02 22:27:50 -040094 .CLK(clockd[1]),
95 .D(clockd[2]),
96 .Q(nint[2]),
97 .Q_N(clockd[2]),
98 .RESET_B(resetbb)
Tim Edwardscd64af52020-08-07 11:11:58 -040099 );
100
Tim Edwardsef8312e2020-09-22 17:20:06 -0400101 sky130_fd_sc_hd__dfrbp_1 idiv16 (
Tim Edwards04ba17f2020-10-02 22:27:50 -0400102 .CLK(clockd[2]),
103 .D(clockd[3]),
104 .Q(nint[3]),
105 .Q_N(clockd[3]),
106 .RESET_B(resetbb)
Tim Edwardscd64af52020-08-07 11:11:58 -0400107 );
108endmodule