Attention

This documentation is a work in progress. Expect to see errors and unfinished things.

pdetect Source File

 1`timescale 1ns / 1ns
 2// Synthesizes to 17 slices at 155 MHz in XC3Sxxx-4 using XST-10.1i
 3
 4// Transform a raw phase difference (-pi to pi) into a control signal
 5// for a PLL.  Uses internal state to generate the right full-scale
 6// DC signal when the frequencies are mismatched.  In the final,
 7// locked-at-zero-phase state, the output equals the input.
 8
 9// Subtle API change from old pdetect: when strobe_in is not set,
10// the output follows the input exactly.
11
12// Yet another API change: new input "reset", only used when strobe_in
13// is set, resets the state machine to unwound.
14
15module pdetect #(
16     parameter w=17
17) (
18     input clk,
19     input [w-1:0] ang_in,
20     input strobe_in,
21     input reset,
22     output reg [w-1:0] ang_out,
23     output reg strobe_out
24);
25
26// coding is important, see usage of next bits below
27reg [1:0] state=0;
28`define S_LINEAR 0
29`define S_CLIP_P 2
30`define S_CLIP_N 3
31
32initial ang_out=0;
33initial strobe_out=0;
34
35reg [1:0] prev_quad=0;
36wire [1:0] quad = ang_in[w-1:w-2];
37wire trans_pn = (prev_quad==2'b01) & (quad==2'b10);
38wire trans_np = (prev_quad==2'b10) & (quad==2'b01);
39
40reg [1:0] next=0;
41always @(*) begin
42     next=state;
43     if (trans_pn & (state==`S_LINEAR)) next=`S_CLIP_P;
44     if (trans_np & (state==`S_LINEAR)) next=`S_CLIP_N;
45     if (trans_pn & (state==`S_CLIP_N)) next=`S_LINEAR;
46     if (trans_np & (state==`S_CLIP_P)) next=`S_LINEAR;
47     if (reset) next=`S_LINEAR;
48end
49
50wire [w-1:0] clipv = {next[0],{w-1{~next[0]}}};
51always @(posedge clk) begin
52     if (strobe_in) begin
53             prev_quad <= quad;
54             state <= next;
55     end
56     ang_out <= (next[1] & strobe_in & ~reset) ? clipv : ang_in;
57     strobe_out <= strobe_in;
58end
59
60endmodule