Tim Edwards | cd64af5 | 2020-08-07 11:11:58 -0400 | [diff] [blame] | 1 | // Tunable ring oscillator---synthesizable (physical) version. |
| 2 | // |
| 3 | // NOTE: This netlist cannot be simulated correctly due to lack |
| 4 | // of accurate timing in the digital cell verilog models. |
| 5 | |
| 6 | module delay_stage(in, trim, out); |
| 7 | input in; |
| 8 | input [1:0] trim; |
| 9 | output out; |
| 10 | |
| 11 | wire d0, d1, d2; |
| 12 | |
Tim Edwards | ef8312e | 2020-09-22 17:20:06 -0400 | [diff] [blame^] | 13 | sky130_fd_sc_hd__clkbuf_2 delaybuf0 ( |
Tim Edwards | cd64af5 | 2020-08-07 11:11:58 -0400 | [diff] [blame] | 14 | .A(in), |
| 15 | .X(ts) |
| 16 | ); |
| 17 | |
Tim Edwards | ef8312e | 2020-09-22 17:20:06 -0400 | [diff] [blame^] | 18 | sky130_fd_sc_hd__clkbuf_1 delaybuf1 ( |
Tim Edwards | cd64af5 | 2020-08-07 11:11:58 -0400 | [diff] [blame] | 19 | .A(ts), |
| 20 | .X(d0) |
| 21 | ); |
| 22 | |
Tim Edwards | ef8312e | 2020-09-22 17:20:06 -0400 | [diff] [blame^] | 23 | sky130_fd_sc_hd__einvp_2 delayen1 ( |
Tim Edwards | cd64af5 | 2020-08-07 11:11:58 -0400 | [diff] [blame] | 24 | .A(d0), |
| 25 | .TE(trim[1]), |
| 26 | .Z(d1) |
| 27 | ); |
| 28 | |
Tim Edwards | ef8312e | 2020-09-22 17:20:06 -0400 | [diff] [blame^] | 29 | sky130_fd_sc_hd__einvn_4 delayenb1 ( |
Tim Edwards | cd64af5 | 2020-08-07 11:11:58 -0400 | [diff] [blame] | 30 | .A(ts), |
| 31 | .TEB(trim[1]), |
| 32 | .Z(d1) |
| 33 | ); |
| 34 | |
Tim Edwards | ef8312e | 2020-09-22 17:20:06 -0400 | [diff] [blame^] | 35 | sky130_fd_sc_hd__clkinv_1 delayint0 ( |
Tim Edwards | cd64af5 | 2020-08-07 11:11:58 -0400 | [diff] [blame] | 36 | .A(d1), |
| 37 | .Y(d2) |
| 38 | ); |
| 39 | |
Tim Edwards | ef8312e | 2020-09-22 17:20:06 -0400 | [diff] [blame^] | 40 | sky130_fd_sc_hd__einvp_2 delayen0 ( |
Tim Edwards | cd64af5 | 2020-08-07 11:11:58 -0400 | [diff] [blame] | 41 | .A(d2), |
| 42 | .TE(trim[0]), |
| 43 | .Z(out) |
| 44 | ); |
| 45 | |
Tim Edwards | ef8312e | 2020-09-22 17:20:06 -0400 | [diff] [blame^] | 46 | sky130_fd_sc_hd__einvn_8 delayenb0 ( |
Tim Edwards | cd64af5 | 2020-08-07 11:11:58 -0400 | [diff] [blame] | 47 | .A(ts), |
| 48 | .TEB(trim[0]), |
| 49 | .Z(out) |
| 50 | ); |
| 51 | |
| 52 | endmodule |
| 53 | |
| 54 | module start_stage(in, trim, reset, out); |
| 55 | input in; |
| 56 | input [1:0] trim; |
| 57 | input reset; |
| 58 | output out; |
| 59 | |
| 60 | wire d0, d1, d2, ctrl0, one; |
| 61 | |
Tim Edwards | ef8312e | 2020-09-22 17:20:06 -0400 | [diff] [blame^] | 62 | sky130_fd_sc_hd__clkbuf_1 delaybuf0 ( |
Tim Edwards | cd64af5 | 2020-08-07 11:11:58 -0400 | [diff] [blame] | 63 | .A(in), |
| 64 | .X(d0) |
| 65 | ); |
| 66 | |
Tim Edwards | ef8312e | 2020-09-22 17:20:06 -0400 | [diff] [blame^] | 67 | sky130_fd_sc_hd__einvp_2 delayen1 ( |
Tim Edwards | cd64af5 | 2020-08-07 11:11:58 -0400 | [diff] [blame] | 68 | .A(d0), |
| 69 | .TE(trim[1]), |
| 70 | .Z(d1) |
| 71 | ); |
| 72 | |
Tim Edwards | ef8312e | 2020-09-22 17:20:06 -0400 | [diff] [blame^] | 73 | sky130_fd_sc_hd__einvn_4 delayenb1 ( |
Tim Edwards | cd64af5 | 2020-08-07 11:11:58 -0400 | [diff] [blame] | 74 | .A(in), |
| 75 | .TEB(trim[1]), |
| 76 | .Z(d1) |
| 77 | ); |
| 78 | |
Tim Edwards | ef8312e | 2020-09-22 17:20:06 -0400 | [diff] [blame^] | 79 | sky130_fd_sc_hd__clkinv_1 delayint0 ( |
Tim Edwards | cd64af5 | 2020-08-07 11:11:58 -0400 | [diff] [blame] | 80 | .A(d1), |
| 81 | .Y(d2) |
| 82 | ); |
| 83 | |
Tim Edwards | ef8312e | 2020-09-22 17:20:06 -0400 | [diff] [blame^] | 84 | sky130_fd_sc_hd__einvp_2 delayen0 ( |
Tim Edwards | cd64af5 | 2020-08-07 11:11:58 -0400 | [diff] [blame] | 85 | .A(d2), |
| 86 | .TE(trim[0]), |
| 87 | .Z(out) |
| 88 | ); |
| 89 | |
Tim Edwards | ef8312e | 2020-09-22 17:20:06 -0400 | [diff] [blame^] | 90 | sky130_fd_sc_hd__einvn_8 delayenb0 ( |
Tim Edwards | cd64af5 | 2020-08-07 11:11:58 -0400 | [diff] [blame] | 91 | .A(in), |
| 92 | .TEB(ctrl0), |
| 93 | .Z(out) |
| 94 | ); |
| 95 | |
Tim Edwards | ef8312e | 2020-09-22 17:20:06 -0400 | [diff] [blame^] | 96 | sky130_fd_sc_hd__einvp_1 reseten0 ( |
Tim Edwards | cd64af5 | 2020-08-07 11:11:58 -0400 | [diff] [blame] | 97 | .A(one), |
| 98 | .TE(reset), |
| 99 | .Z(out) |
| 100 | ); |
| 101 | |
Tim Edwards | ef8312e | 2020-09-22 17:20:06 -0400 | [diff] [blame^] | 102 | sky130_fd_sc_hd__or2_2 ctrlen0 ( |
Tim Edwards | cd64af5 | 2020-08-07 11:11:58 -0400 | [diff] [blame] | 103 | .A(reset), |
| 104 | .B(trim[0]), |
| 105 | .X(ctrl0) |
| 106 | ); |
| 107 | |
Tim Edwards | ef8312e | 2020-09-22 17:20:06 -0400 | [diff] [blame^] | 108 | sky130_fd_sc_hd__conb_1 const1 ( |
Tim Edwards | cd64af5 | 2020-08-07 11:11:58 -0400 | [diff] [blame] | 109 | .HI(one), |
| 110 | .LO() |
| 111 | ); |
| 112 | |
| 113 | endmodule |
| 114 | |
| 115 | // Ring oscillator with 13 stages, each with two trim bits delay |
| 116 | // (see above). Trim is not binary: For trim[1:0], lower bit |
| 117 | // trim[0] is primary trim and must be applied first; upper |
| 118 | // bit trim[1] is secondary trim and should only be applied |
| 119 | // after the primary trim is applied, or it has no effect. |
| 120 | // |
| 121 | // Total effective number of inverter stages in this oscillator |
| 122 | // ranges from 13 at trim 0 to 65 at trim 24. The intention is |
| 123 | // to cover a range greater than 2x so that the midrange can be |
| 124 | // reached over all PVT conditions. |
| 125 | // |
| 126 | // Frequency of this ring oscillator under SPICE simulations at |
| 127 | // nominal PVT is maximum 214 MHz (trim 0), minimum 90 MHz (trim 24). |
| 128 | |
| 129 | module ring_osc2x13(reset, trim, clockp); |
| 130 | input reset; |
| 131 | input [25:0] trim; |
| 132 | output[1:0] clockp; |
| 133 | |
| 134 | wire [12:0] d; |
| 135 | wire [1:0] clockp; |
| 136 | wire [1:0] c; |
| 137 | |
| 138 | // Main oscillator loop stages |
| 139 | |
| 140 | genvar i; |
| 141 | generate |
| 142 | for (i = 0; i < 12; i = i + 1) begin : dstage |
| 143 | delay_stage id ( |
| 144 | .in(d[i]), |
| 145 | .trim({trim[i+13], trim[i]}), |
| 146 | .out(d[i+1]) |
| 147 | ); |
| 148 | end |
| 149 | endgenerate |
| 150 | |
| 151 | // Reset/startup stage |
| 152 | |
| 153 | start_stage iss ( |
| 154 | .in(d[12]), |
| 155 | .trim({trim[25], trim[12]}), |
| 156 | .reset(reset), |
| 157 | .out(d[0]) |
| 158 | ); |
| 159 | |
| 160 | // Buffered outputs a 0 and 90 degrees phase (approximately) |
| 161 | |
Tim Edwards | ef8312e | 2020-09-22 17:20:06 -0400 | [diff] [blame^] | 162 | sky130_fd_sc_hd__clkinv_2 ibufp00 ( |
Tim Edwards | cd64af5 | 2020-08-07 11:11:58 -0400 | [diff] [blame] | 163 | .A(d[0]), |
| 164 | .Y(c[0]) |
| 165 | ); |
Tim Edwards | ef8312e | 2020-09-22 17:20:06 -0400 | [diff] [blame^] | 166 | sky130_fd_sc_hd__clkinv_8 ibufp01 ( |
Tim Edwards | cd64af5 | 2020-08-07 11:11:58 -0400 | [diff] [blame] | 167 | .A(c[0]), |
| 168 | .Y(clockp[0]) |
| 169 | ); |
Tim Edwards | ef8312e | 2020-09-22 17:20:06 -0400 | [diff] [blame^] | 170 | sky130_fd_sc_hd__clkinv_2 ibufp10 ( |
Tim Edwards | cd64af5 | 2020-08-07 11:11:58 -0400 | [diff] [blame] | 171 | .A(d[6]), |
| 172 | .Y(c[1]) |
| 173 | ); |
Tim Edwards | ef8312e | 2020-09-22 17:20:06 -0400 | [diff] [blame^] | 174 | sky130_fd_sc_hd__clkinv_8 ibufp11 ( |
Tim Edwards | cd64af5 | 2020-08-07 11:11:58 -0400 | [diff] [blame] | 175 | .A(c[1]), |
| 176 | .Y(clockp[1]) |
| 177 | ); |
| 178 | |
| 179 | endmodule |