module  ring_with_counter #(parameter WIDTH=24) (input nrst, ring_en, count_en, output [WIDTH-1:0] count);

  wire [WIDTH:0] value;
  wire rst,count_en_s0,count_en_s1,osc,nosc_buf;
  genvar i;

  ring_osc ring_osc(.nrst(ring_en),.osc(osc));

  inv_with_delay inv_r(.A(nrst),.Y(rst));

  // logic in this module should minimize loading the ring, so buffer the ring output
  inv_with_delay inv_b(.A(osc),.Y(nosc_buf)); 

  // synchronize the counter enable time to the ring oscillator frequency 
  // so metastability doesnt corrupt the count.  note: we count on the ring frequency domain

  rdffe ds0(.clk(nosc_buf),.rst(rst),.en(1'b1), .d(count_en),    .q(count_en_s0));
  rdffe ds1(.clk(nosc_buf),.rst(rst),.en(1'b1), .d(count_en_s0), .q(count_en_s1));

  // Count down toward zero from (signed)-1

  assign value[0] = nosc_buf;

  generate
		for (i = 1; i < WIDTH; i = i + 1) 
          sdffe dcg(.clk(value[i-1]),.pre(rst),.en(count_en_s1),.d(~value[i]),.q(value[i]));
  endgenerate

  // value[WIDTH] is the overflow bit.  Make it sticky.  
  // This bit should never be cleared if the measurement is designed correctly.

  sdffe dcg(.clk(value[WIDTH-1]),.pre(rst),.en(count_en_s1),.d(1'b0),.q(value[WIDTH]));

  assign count[WIDTH-1:0] = value[WIDTH:1];
  
endmodule