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