/*
┌───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐
│                                                                                                                       │
│               Project: PhaseComparator                                                                                │
│                Author: Michael Krämer                                                                                 │
│                        Michael@dk8pp.de                                                                               │
│                  Date: 14.11.2024                                                                                     │
│              Language: Verilog                                                                                        │
│               Version: 0.1                                                                                            │
│         Design status: first try                                                                                      │
│                Device: EPM7064SLC44-7 (discontinued, only for proof-of-concept with prototype)                        │
│                                                                                                                       │
│  Note: Latest tool version which supports this device: Quartus II 13.0                                                │
│  =====                                                 ===============                                                │
│                                                                                                                       │
├───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┤
│                                                                                                                       │
│  Purpose: Phase comparison for measurement of reflection coefficient in antenna tuner.                                │
│                                                                                                                       │
└───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
*/

/*
┌───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐
│       Documentation                                                                                                   │
└───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘

Description of phase measurement
================================
This circuit is meant to be employed for the automatic tuning of an antenna tuner for shortwave amateur radios.
A Sontheimer coupler shall be used to measure forward and reflected voltage. It has two ports, one for each wave.
Both voltages are converted to digital TTL signals, which are supplied to this CPLD as clkuf (forward port) and
clkur (reflected port). At the same time the amplitue of both voltages is measured by a separate analogue circuit,
which is not part of this digital design.

It is assumed that clkuf is always available during a measurement, while clkur will stop in an almost or perfectly
matched situation.

The purpose of this digital circuit is the detection of the phase difference between forward and reflected wave.
Ideally this would be achieved by sampling both clocks with a much higher one to determine the delay between their
edges. That would, however, require sample clock speeds in the GHz range, which is currently not reasonable for
amateur applications.

As an alternative method, this design generates a PWM output, which is proportional to the phase delay between
both clocks. The PWM signal is available as a DC voltage after low-pass filtering. It shall be measured by the
ADC of a microcontroller, which determines the phase delay from this voltage. It is not expected that this method
has a very high precision. It would certainly not be usable for measurement equipment like a vector network
analyzer. The purpose is to get a rough estimation for the initial tuning of an automatic antenna tuner. Finding
the correct match will then be an iterative process.

In addition to the PWM generation, this design provides a 16-bit clkuf counter to measure the clock frequency.
The time base for this measurement is provided from the microcontroller. It must be in the millisecond range
so that an overflow of the counter cannot occur for clocks in the shortwave region.

This design also generates a signal which indicates if the clkur input is actively toggling (always assuming that
clkuf is available, which is only the case during a measurement cycle with sufficient forward power from the
transmitter).

Metastability may become an issue when both clock are more or less in phase at 0° or 180°. Due to the low pass
filter, this should not cause any problems. It should anyway be analyzed in the prototype.

*/

/*
┌───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐
│       Ressources                                                                                                      │
└───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
*/

/*
┌───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐
│       Defines                                                                                                         │
└───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
*/

/*
┌───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐
│       Module: PhaseComparator                                                                                         │
└───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
*/
module PhaseComparator
               (input  wire clkuf,              /* clock from forward port */
                input  wire clkur,              /* clock from reflected port */
                input  wire enable,             /* enable operation when high, reset when low */
                input  wire [3:0] sel,          /* select counter bit for reading by CPU, 0:cntr[0], ... 15:cntr[15] */
                input  wire gate_timer,         /* gate signal for counter, active high, in the order of 1 ms */
                input  wire reset_counter,      /* asynchronous reset counter on rising edge */
                output wire dataout,            /* data output for reading the counter */
                output wire clkactive,          /* clkur is active if high */
                output wire ur_leading,         /* high if clkur is leading clkuf, low otherwise */
                output wire pwm,                /* pwm encoded phase delay */
                input  wire [4:1] dsw,          /* dip-switch inputs */
                output wire [7:0] la,           /* logic analyser outputs */
                output wire shdn,               /* shutdown output for comparators */
                output wire ena,                /* enable output for log amp */
                output wire led,                /* LED output */
                input  wire res0,               /* reserved pins defined as inputs */
                input  wire res2,               /* reserved pins defined as inputs */
                input  wire res3,               /* reserved pins defined as inputs */
                output wire res4                /* reserved output */
                ) ;

/*
┌───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐
│       registers and wires                                                                                             │
└───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
*/
        reg     ffuf ;                          /* stores clkur status at rising clkuf, selects PWM source */
        reg     ffur ;                          /* toggles with clkur to detect active reflected clock */
        reg     active ;                        /* indicates active clkur */
        reg     [15:0] cntr ;                   /* frequency counter */
        reg     [1:0] clkur_sample ;            /* used to detect if clkur toggles */
        reg     gtff ;                          /* synchronizer for gate signal */

/* decoder to select counter bit for reading by CPU */

        wire    sela0 = (sel[1:0] == 2'b00) ;
        wire    sela1 = (sel[1:0] == 2'b01) ;
        wire    sela2 = (sel[1:0] == 2'b10) ;

        wire    selb0 = (sel[3:2] == 2'b00) ;
        wire    selb1 = (sel[3:2] == 2'b01) ;
        wire    selb2 = (sel[3:2] == 2'b10) ;

        wire    [3:0] nibble ;                  /* selected nibble from counter */
        wire    gate_open = gtff ;              /* counter is active while gate is open */
        wire    data ;                          /* data from counter */

/*
┌───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐
│       assign combinatorial signals                                                                                    │
└───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
*/
//assign pwm = ffuf ? clkur | clkuf : clkur & clkuf ;
assign pwm = clkur ^ clkuf ;
assign clkactive = active ;
assign ur_leading = ffuf ;
assign la[7:0] = 8'h0 ; /* unused for now */
assign nibble = selb0 ? cntr[3:0] : selb1 ? cntr[7:4] : selb2 ? cntr[11:8] : cntr[15:12] ;
assign data = sela0 ? nibble[0] : sela1 ? nibble[1] : sela2 ? nibble[2] : nibble[3] ;

assign dataout = data & ~gtff ; /* prevent data output while counting */
assign res4 = 0 ;

assign shdn = ~enable ; /* shutdown comparators to save power */
assign ena = enable ;   /* enable log amps when active, save power when inactive */
assign led = dsw[1] ? enable : ur_leading ;   /* LED on when active or ur_leading */

/*
┌───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐
│       Forward clock domain                                                                                            │
└───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
*/
always @(posedge clkuf or posedge reset_counter)
begin
   if (reset_counter)
   begin
      cntr <= 16'h0 ;
   end
   else
   begin
      if (~enable)
      begin
         cntr <= 16'h0 ;
         ffuf <= 1'b0 ;
         active <= 1'b0 ;
         clkur_sample[1:0] <= 2'b00 ;
         gtff <= 1'b0 ;
      end
      else
      begin
         if (gate_open)
         begin
            cntr <= cntr + 16'h1 ;
         end
         ffuf <= clkur ;
         gtff <= gate_timer ;
         clkur_sample[1:0] <= {clkur_sample[0], ffur} ;
         active = clkur_sample[1] != clkur_sample[0] ;
      end
   end
end

/*
┌───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐
│       Reflected clock domain                                                                                          │
└───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
*/
always @(posedge clkur)
begin
   begin
      if (~enable)
      begin
         ffur <= 1'b0 ;
      end
      else
      begin
         ffur <= ~ffur ;
      end
   end
end


/*
┌───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐
│       Functions                                                                                                       │
└───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
*/

endmodule

