module ring_osc2x13(reset, trim, clockp);
    input reset;
    input [25:0] trim;
    output[1:0] clockp;

`ifdef FUNCTIONAL	// i.e., behavioral model below

    reg [1:0] clockp;
    reg hiclock;
    integer i;
    real delay;
    wire [5:0] bcount;

    assign bcount = trim[0] + trim[1] + trim[2]
		+ trim[3] + trim[4] + trim[5] + trim[6] + trim[7]
		+ trim[8] + trim[9] + trim[10] + trim[11] + trim[12]
		+ trim[13] + trim[14] + trim[15] + trim[16] + trim[17]
		+ trim[18] + trim[19] + trim[20] + trim[21] + trim[22]
		+ trim[23] + trim[24] + trim[25];

    initial begin
	hiclock <= 1'b0;
	delay = 3.0;
    end

    // Fastest operation is 214 MHz = 4.67ns
    // Delay per trim is 0.02385
    // Run "hiclock" at 2x this rate, then use positive and negative
    // edges to derive the 0 and 90 degree phase clocks.

    always #delay begin
	hiclock <= (hiclock === 1'b0);
    end

    always @(trim) begin
    	// Implement trim as a variable delay, one delay per trim bit
	delay = 1.168 + 0.012 * $itor(bcount);
    end

    always @(posedge hiclock or posedge reset) begin
	if (reset == 1'b1) begin
	    clockp[0] <= 1'b0;
	end else begin
	    clockp[0] <= (clockp[0] === 1'b0);
	end
    end

    always @(negedge hiclock or posedge reset) begin
	if (reset == 1'b1) begin
	    clockp[1] <= 1'b0;
	end else begin
	    clockp[1] <= (clockp[1] === 1'b0);
	end
    end

`else 			// !FUNCTIONAL;  i.e., gate level netlist below

    wire [1:0] clockp;
    wire [12:0] d;
    wire [1:0] c;

    // Main oscillator loop stages
 
    genvar i;
    generate
	for (i = 0; i < 12; i = i + 1) begin : dstage
	    delay_stage id (
		.in(d[i]),
		.trim({trim[i+13], trim[i]}),
		.out(d[i+1])
	    );
	end
    endgenerate

    // Reset/startup stage
 
    start_stage iss (
	.in(d[12]),
	.trim({trim[25], trim[12]}),
	.reset(reset),
	.out(d[0])
    );

    // Buffered outputs a 0 and 90 degrees phase (approximately)

    sky130_fd_sc_hd__clkinv_2 ibufp00 (
	.A(d[0]),
	.Y(c[0])
    );
    sky130_fd_sc_hd__clkinv_8 ibufp01 (
	.A(c[0]),
	.Y(clockp[0])
    );
    sky130_fd_sc_hd__clkinv_2 ibufp10 (
	.A(d[6]),
	.Y(c[1])
    );
    sky130_fd_sc_hd__clkinv_8 ibufp11 (
	.A(c[1]),
	.Y(clockp[1])
    );

`endif // !FUNCTIONAL

endmodule