agorararmard | 6c766a8 | 2020-12-10 18:13:12 +0200 | [diff] [blame] | 1 | // SPDX-FileCopyrightText: 2020 Efabless Corporation |
agorararmard | e5780bf | 2020-12-09 21:27:56 +0000 | [diff] [blame] | 2 | // |
| 3 | // Licensed under the Apache License, Version 2.0 (the "License"); |
| 4 | // you may not use this file except in compliance with the License. |
| 5 | // You may obtain a copy of the License at |
| 6 | // |
| 7 | // http://www.apache.org/licenses/LICENSE-2.0 |
| 8 | // |
| 9 | // Unless required by applicable law or agreed to in writing, software |
| 10 | // distributed under the License is distributed on an "AS IS" BASIS, |
| 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| 12 | // See the License for the specific language governing permissions and |
| 13 | // limitations under the License. |
agorararmard | afa96ea | 2020-12-09 23:37:31 +0200 | [diff] [blame] | 14 | // SPDX-License-Identifier: Apache-2.0 |
agorararmard | e5780bf | 2020-12-09 21:27:56 +0000 | [diff] [blame] | 15 | |
Matt Venn | 08cd6eb | 2020-11-16 12:01:14 +0100 | [diff] [blame] | 16 | `default_nettype none |
Tim Edwards | cd64af5 | 2020-08-07 11:11:58 -0400 | [diff] [blame] | 17 | // Tunable ring oscillator---synthesizable (physical) version. |
| 18 | // |
| 19 | // NOTE: This netlist cannot be simulated correctly due to lack |
| 20 | // of accurate timing in the digital cell verilog models. |
| 21 | |
| 22 | module delay_stage(in, trim, out); |
| 23 | input in; |
| 24 | input [1:0] trim; |
| 25 | output out; |
| 26 | |
Tim Edwards | 581068f | 2020-11-19 12:45:25 -0500 | [diff] [blame] | 27 | wire d0, d1, d2, ts; |
Tim Edwards | cd64af5 | 2020-08-07 11:11:58 -0400 | [diff] [blame] | 28 | |
Tim Edwards | ef8312e | 2020-09-22 17:20:06 -0400 | [diff] [blame] | 29 | sky130_fd_sc_hd__clkbuf_2 delaybuf0 ( |
Tim Edwards | cd64af5 | 2020-08-07 11:11:58 -0400 | [diff] [blame] | 30 | .A(in), |
| 31 | .X(ts) |
| 32 | ); |
| 33 | |
Tim Edwards | ef8312e | 2020-09-22 17:20:06 -0400 | [diff] [blame] | 34 | sky130_fd_sc_hd__clkbuf_1 delaybuf1 ( |
Tim Edwards | cd64af5 | 2020-08-07 11:11:58 -0400 | [diff] [blame] | 35 | .A(ts), |
| 36 | .X(d0) |
| 37 | ); |
| 38 | |
Tim Edwards | ef8312e | 2020-09-22 17:20:06 -0400 | [diff] [blame] | 39 | sky130_fd_sc_hd__einvp_2 delayen1 ( |
Tim Edwards | cd64af5 | 2020-08-07 11:11:58 -0400 | [diff] [blame] | 40 | .A(d0), |
| 41 | .TE(trim[1]), |
| 42 | .Z(d1) |
| 43 | ); |
| 44 | |
Tim Edwards | ef8312e | 2020-09-22 17:20:06 -0400 | [diff] [blame] | 45 | sky130_fd_sc_hd__einvn_4 delayenb1 ( |
Tim Edwards | cd64af5 | 2020-08-07 11:11:58 -0400 | [diff] [blame] | 46 | .A(ts), |
Tim Edwards | c5265b8 | 2020-09-25 17:08:59 -0400 | [diff] [blame] | 47 | .TE_B(trim[1]), |
Tim Edwards | cd64af5 | 2020-08-07 11:11:58 -0400 | [diff] [blame] | 48 | .Z(d1) |
| 49 | ); |
| 50 | |
Tim Edwards | ef8312e | 2020-09-22 17:20:06 -0400 | [diff] [blame] | 51 | sky130_fd_sc_hd__clkinv_1 delayint0 ( |
Tim Edwards | cd64af5 | 2020-08-07 11:11:58 -0400 | [diff] [blame] | 52 | .A(d1), |
| 53 | .Y(d2) |
| 54 | ); |
| 55 | |
Tim Edwards | ef8312e | 2020-09-22 17:20:06 -0400 | [diff] [blame] | 56 | sky130_fd_sc_hd__einvp_2 delayen0 ( |
Tim Edwards | cd64af5 | 2020-08-07 11:11:58 -0400 | [diff] [blame] | 57 | .A(d2), |
| 58 | .TE(trim[0]), |
| 59 | .Z(out) |
| 60 | ); |
| 61 | |
Tim Edwards | ef8312e | 2020-09-22 17:20:06 -0400 | [diff] [blame] | 62 | sky130_fd_sc_hd__einvn_8 delayenb0 ( |
Tim Edwards | cd64af5 | 2020-08-07 11:11:58 -0400 | [diff] [blame] | 63 | .A(ts), |
Tim Edwards | c5265b8 | 2020-09-25 17:08:59 -0400 | [diff] [blame] | 64 | .TE_B(trim[0]), |
Tim Edwards | cd64af5 | 2020-08-07 11:11:58 -0400 | [diff] [blame] | 65 | .Z(out) |
| 66 | ); |
| 67 | |
| 68 | endmodule |
| 69 | |
| 70 | module start_stage(in, trim, reset, out); |
| 71 | input in; |
| 72 | input [1:0] trim; |
| 73 | input reset; |
| 74 | output out; |
| 75 | |
| 76 | wire d0, d1, d2, ctrl0, one; |
| 77 | |
Tim Edwards | ef8312e | 2020-09-22 17:20:06 -0400 | [diff] [blame] | 78 | sky130_fd_sc_hd__clkbuf_1 delaybuf0 ( |
Tim Edwards | cd64af5 | 2020-08-07 11:11:58 -0400 | [diff] [blame] | 79 | .A(in), |
| 80 | .X(d0) |
| 81 | ); |
| 82 | |
Tim Edwards | ef8312e | 2020-09-22 17:20:06 -0400 | [diff] [blame] | 83 | sky130_fd_sc_hd__einvp_2 delayen1 ( |
Tim Edwards | cd64af5 | 2020-08-07 11:11:58 -0400 | [diff] [blame] | 84 | .A(d0), |
| 85 | .TE(trim[1]), |
| 86 | .Z(d1) |
| 87 | ); |
| 88 | |
Tim Edwards | ef8312e | 2020-09-22 17:20:06 -0400 | [diff] [blame] | 89 | sky130_fd_sc_hd__einvn_4 delayenb1 ( |
Tim Edwards | cd64af5 | 2020-08-07 11:11:58 -0400 | [diff] [blame] | 90 | .A(in), |
Tim Edwards | c5265b8 | 2020-09-25 17:08:59 -0400 | [diff] [blame] | 91 | .TE_B(trim[1]), |
Tim Edwards | cd64af5 | 2020-08-07 11:11:58 -0400 | [diff] [blame] | 92 | .Z(d1) |
| 93 | ); |
| 94 | |
Tim Edwards | ef8312e | 2020-09-22 17:20:06 -0400 | [diff] [blame] | 95 | sky130_fd_sc_hd__clkinv_1 delayint0 ( |
Tim Edwards | cd64af5 | 2020-08-07 11:11:58 -0400 | [diff] [blame] | 96 | .A(d1), |
| 97 | .Y(d2) |
| 98 | ); |
| 99 | |
Tim Edwards | ef8312e | 2020-09-22 17:20:06 -0400 | [diff] [blame] | 100 | sky130_fd_sc_hd__einvp_2 delayen0 ( |
Tim Edwards | cd64af5 | 2020-08-07 11:11:58 -0400 | [diff] [blame] | 101 | .A(d2), |
| 102 | .TE(trim[0]), |
| 103 | .Z(out) |
| 104 | ); |
| 105 | |
Tim Edwards | ef8312e | 2020-09-22 17:20:06 -0400 | [diff] [blame] | 106 | sky130_fd_sc_hd__einvn_8 delayenb0 ( |
Tim Edwards | cd64af5 | 2020-08-07 11:11:58 -0400 | [diff] [blame] | 107 | .A(in), |
Tim Edwards | c5265b8 | 2020-09-25 17:08:59 -0400 | [diff] [blame] | 108 | .TE_B(ctrl0), |
Tim Edwards | cd64af5 | 2020-08-07 11:11:58 -0400 | [diff] [blame] | 109 | .Z(out) |
| 110 | ); |
| 111 | |
Tim Edwards | ef8312e | 2020-09-22 17:20:06 -0400 | [diff] [blame] | 112 | sky130_fd_sc_hd__einvp_1 reseten0 ( |
Tim Edwards | cd64af5 | 2020-08-07 11:11:58 -0400 | [diff] [blame] | 113 | .A(one), |
| 114 | .TE(reset), |
| 115 | .Z(out) |
| 116 | ); |
| 117 | |
Tim Edwards | ef8312e | 2020-09-22 17:20:06 -0400 | [diff] [blame] | 118 | sky130_fd_sc_hd__or2_2 ctrlen0 ( |
Tim Edwards | cd64af5 | 2020-08-07 11:11:58 -0400 | [diff] [blame] | 119 | .A(reset), |
| 120 | .B(trim[0]), |
| 121 | .X(ctrl0) |
| 122 | ); |
| 123 | |
Tim Edwards | ef8312e | 2020-09-22 17:20:06 -0400 | [diff] [blame] | 124 | sky130_fd_sc_hd__conb_1 const1 ( |
Tim Edwards | cd64af5 | 2020-08-07 11:11:58 -0400 | [diff] [blame] | 125 | .HI(one), |
| 126 | .LO() |
| 127 | ); |
| 128 | |
| 129 | endmodule |
| 130 | |
| 131 | // Ring oscillator with 13 stages, each with two trim bits delay |
| 132 | // (see above). Trim is not binary: For trim[1:0], lower bit |
| 133 | // trim[0] is primary trim and must be applied first; upper |
| 134 | // bit trim[1] is secondary trim and should only be applied |
| 135 | // after the primary trim is applied, or it has no effect. |
| 136 | // |
| 137 | // Total effective number of inverter stages in this oscillator |
| 138 | // ranges from 13 at trim 0 to 65 at trim 24. The intention is |
| 139 | // to cover a range greater than 2x so that the midrange can be |
| 140 | // reached over all PVT conditions. |
| 141 | // |
| 142 | // Frequency of this ring oscillator under SPICE simulations at |
| 143 | // nominal PVT is maximum 214 MHz (trim 0), minimum 90 MHz (trim 24). |
| 144 | |
| 145 | module ring_osc2x13(reset, trim, clockp); |
| 146 | input reset; |
| 147 | input [25:0] trim; |
| 148 | output[1:0] clockp; |
| 149 | |
Tim Edwards | bb3cd69 | 2020-10-09 22:00:23 -0400 | [diff] [blame] | 150 | `ifdef FUNCTIONAL // i.e., behavioral model below |
| 151 | |
| 152 | reg [1:0] clockp; |
| 153 | reg hiclock; |
| 154 | integer i; |
| 155 | real delay; |
| 156 | wire [5:0] bcount; |
| 157 | |
| 158 | assign bcount = trim[0] + trim[1] + trim[2] |
| 159 | + trim[3] + trim[4] + trim[5] + trim[6] + trim[7] |
| 160 | + trim[8] + trim[9] + trim[10] + trim[11] + trim[12] |
| 161 | + trim[13] + trim[14] + trim[15] + trim[16] + trim[17] |
| 162 | + trim[18] + trim[19] + trim[20] + trim[21] + trim[22] |
| 163 | + trim[23] + trim[24] + trim[25]; |
| 164 | |
| 165 | initial begin |
| 166 | hiclock <= 1'b0; |
| 167 | delay = 3.0; |
| 168 | end |
| 169 | |
| 170 | // Fastest operation is 214 MHz = 4.67ns |
| 171 | // Delay per trim is 0.02385 |
| 172 | // Run "hiclock" at 2x this rate, then use positive and negative |
| 173 | // edges to derive the 0 and 90 degree phase clocks. |
| 174 | |
| 175 | always #delay begin |
| 176 | hiclock <= (hiclock === 1'b0); |
| 177 | end |
| 178 | |
| 179 | always @(trim) begin |
| 180 | // Implement trim as a variable delay, one delay per trim bit |
| 181 | delay = 1.168 + 0.012 * $itor(bcount); |
| 182 | end |
| 183 | |
| 184 | always @(posedge hiclock or posedge reset) begin |
| 185 | if (reset == 1'b1) begin |
| 186 | clockp[0] <= 1'b0; |
| 187 | end else begin |
| 188 | clockp[0] <= (clockp[0] === 1'b0); |
| 189 | end |
| 190 | end |
| 191 | |
| 192 | always @(negedge hiclock or posedge reset) begin |
| 193 | if (reset == 1'b1) begin |
| 194 | clockp[1] <= 1'b0; |
| 195 | end else begin |
| 196 | clockp[1] <= (clockp[1] === 1'b0); |
| 197 | end |
| 198 | end |
| 199 | |
| 200 | `else // !FUNCTIONAL; i.e., gate level netlist below |
| 201 | |
Tim Edwards | cd64af5 | 2020-08-07 11:11:58 -0400 | [diff] [blame] | 202 | wire [1:0] clockp; |
Tim Edwards | bb3cd69 | 2020-10-09 22:00:23 -0400 | [diff] [blame] | 203 | wire [12:0] d; |
Tim Edwards | cd64af5 | 2020-08-07 11:11:58 -0400 | [diff] [blame] | 204 | wire [1:0] c; |
| 205 | |
| 206 | // Main oscillator loop stages |
| 207 | |
| 208 | genvar i; |
| 209 | generate |
| 210 | for (i = 0; i < 12; i = i + 1) begin : dstage |
| 211 | delay_stage id ( |
| 212 | .in(d[i]), |
| 213 | .trim({trim[i+13], trim[i]}), |
| 214 | .out(d[i+1]) |
| 215 | ); |
| 216 | end |
| 217 | endgenerate |
| 218 | |
| 219 | // Reset/startup stage |
| 220 | |
| 221 | start_stage iss ( |
| 222 | .in(d[12]), |
| 223 | .trim({trim[25], trim[12]}), |
| 224 | .reset(reset), |
| 225 | .out(d[0]) |
| 226 | ); |
| 227 | |
| 228 | // Buffered outputs a 0 and 90 degrees phase (approximately) |
| 229 | |
Tim Edwards | ef8312e | 2020-09-22 17:20:06 -0400 | [diff] [blame] | 230 | sky130_fd_sc_hd__clkinv_2 ibufp00 ( |
Tim Edwards | cd64af5 | 2020-08-07 11:11:58 -0400 | [diff] [blame] | 231 | .A(d[0]), |
| 232 | .Y(c[0]) |
| 233 | ); |
Tim Edwards | ef8312e | 2020-09-22 17:20:06 -0400 | [diff] [blame] | 234 | sky130_fd_sc_hd__clkinv_8 ibufp01 ( |
Tim Edwards | cd64af5 | 2020-08-07 11:11:58 -0400 | [diff] [blame] | 235 | .A(c[0]), |
| 236 | .Y(clockp[0]) |
| 237 | ); |
Tim Edwards | ef8312e | 2020-09-22 17:20:06 -0400 | [diff] [blame] | 238 | sky130_fd_sc_hd__clkinv_2 ibufp10 ( |
Tim Edwards | cd64af5 | 2020-08-07 11:11:58 -0400 | [diff] [blame] | 239 | .A(d[6]), |
| 240 | .Y(c[1]) |
| 241 | ); |
Tim Edwards | ef8312e | 2020-09-22 17:20:06 -0400 | [diff] [blame] | 242 | sky130_fd_sc_hd__clkinv_8 ibufp11 ( |
Tim Edwards | cd64af5 | 2020-08-07 11:11:58 -0400 | [diff] [blame] | 243 | .A(c[1]), |
| 244 | .Y(clockp[1]) |
| 245 | ); |
| 246 | |
Tim Edwards | bb3cd69 | 2020-10-09 22:00:23 -0400 | [diff] [blame] | 247 | `endif // !FUNCTIONAL |
| 248 | |
Tim Edwards | cd64af5 | 2020-08-07 11:11:58 -0400 | [diff] [blame] | 249 | endmodule |
Tim Edwards | 581068f | 2020-11-19 12:45:25 -0500 | [diff] [blame] | 250 | `default_nettype wire |