Started adding RTL for the Caravel project
diff --git a/verilog/rtl/digital_pll.v b/verilog/rtl/digital_pll.v
new file mode 100644
index 0000000..fe564cb
--- /dev/null
+++ b/verilog/rtl/digital_pll.v
@@ -0,0 +1,97 @@
+// Digital PLL (ring oscillator + controller)
+// Technically this is a frequency locked loop, not a phase locked loop.
+
+`include "digital_pll_controller.v"
+`include "ring_osc2x13.v"
+
+module digital_pll(reset, extclk_sel, osc, clockc, clockp, clockd, div, sel, dco, ext_trim);
+
+    input	reset;		// Sense positive reset
+    input	extclk_sel;	// External clock select (acts as 2nd reset)
+    input	osc;		// Input oscillator to match
+    input [4:0]	div;		// PLL feedback division ratio
+    input [2:0] sel;		// Core clock select
+    input 	dco;		// Run in DCO mode
+    input [25:0] ext_trim;	// External trim for DCO mode
+
+    output       clockc;	// Selected core clock output
+    output [1:0] clockp;	// Two 90 degree clock phases
+    output [3:0] clockd;	// Divided clock (2, 4, 8, 16)
+
+    wire [25:0] itrim;		// Internally generated trim bits
+    wire [25:0] otrim;		// Trim bits applied to the ring oscillator
+    wire [3:0]	nint;		// Internal divided down clocks
+    wire	resetb;		// Internal positivie sense reset
+    wire	creset;		// Controller reset
+    wire	ireset;		// Internal reset (external reset OR extclk_sel)
+
+    assign ireset = reset | extclk_sel;
+
+    // In DCO mode: Hold controller in reset and apply external trim value
+    assign itrim = (dco == 1'b0) ? otrim : ext_trim;
+    assign creset = (dco == 1'b0) ? ireset : 1'b1;
+
+    ring_osc2x13 ringosc (
+	.reset(ireset),
+	.trim(itrim),
+	.clockp(clockp)
+    );
+
+    digital_pll_controller pll_control (
+	.reset(creset),
+	.clock(clockp[0]),
+	.osc(osc),
+	.div(div),
+	.trim(otrim)
+    );
+
+    // Select core clock output
+    assign clockc = (sel == 3'b000) ? clockp[0] :
+		    (sel == 3'b001) ? clockd[0] :
+		    (sel == 3'b010) ? clockd[1] :
+		    (sel == 3'b011) ? clockd[2] :
+		    		      clockd[3];
+
+    // Derive negative-sense reset from the input positive-sense reset
+
+    sky130_fd_sc_hd__inv_4 irb (
+	.A(reset),
+	.Y(resetb)
+    );
+
+    // Create divided down clocks.  The inverted output only comes
+    // with digital standard cells with inverted resets, so the
+    // reset has to be inverted as well.
+ 
+    sky130_fd_sc_hd__dfrbp_1 idiv2 (
+	.CLK(clockp[1]),
+	.D(clockd[0]),
+	.Q(nint[0]),
+	.QN(clockd[0]),
+	.RESETB(resetb)
+    );
+
+    sky130_fd_sc_hd__dfrbp_1 idiv4 (
+	.CLK(clockd[0]),
+	.D(clockd[1]),
+	.Q(nint[1]),
+	.QN(clockd[1]),
+	.RESETB(resetb)
+    );
+
+    sky130_fd_sc_hd__dfrbp_1 idiv8 (
+	.CLK(clockd[1]),
+	.D(clockd[2]),
+	.Q(nint[2]),
+	.QN(clockd[2]),
+	.RESETB(resetb)
+    );
+
+    sky130_fd_sc_hd__dfrbp_1 idiv16 (
+	.CLK(clockd[2]),
+	.D(clockd[3]),
+	.Q(nint[3]),
+	.QN(clockd[3]),
+	.RESETB(resetb)
+    );
+endmodule