Attention

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

freq_count Source File

 1// Synthesizes to 86 slices at 312 MHz in XC3Sxxx-4 using XST-8.2i
 2//  (well, that's just the unknown frequency input; max sysclk is 132 MHz)
 3
 4`timescale 1ns / 1ns
 5
 6module freq_count #(
 7     // Default configuration useful for input frequencies < 2*sysclk
 8     parameter glitch_thresh=2,
 9     parameter refcnt_width=24,
10     parameter freq_width=28,
11     parameter initv=0
12) (
13     // input clocks
14     input sysclk,  // timespec 8.0 ns
15     input f_in,  // unknown input
16
17     // outputs in sysclk domain
18     output reg [freq_width-1:0] frequency,
19     output freq_strobe,
20     output reg [15:0] diff_stream, // stream of last 4 4-bit counts of f_in
21     output reg diff_stream_strobe, // strobe at f_sysclk/4
22     // glitch_catcher can be routed to a physical pin to trigger
23     // a 'scope; see glitch_thresh parameter above
24     output reg glitch_catcher
25);
26
27initial begin
28     frequency=initv;
29     diff_stream=0;
30     diff_stream_strobe=0;
31     glitch_catcher=0;
32end
33
34// Reference counter
35// may or may not be synchronized between instances
36reg [refcnt_width-1:0] refcnt=0;
37reg ref_strobe=0, stream_strobe=0;
38always @(posedge sysclk) begin
39     {ref_strobe, refcnt} <= refcnt + 1;
40     stream_strobe <= refcnt[1:0] == 0;
41end
42
43wire [3:0] xcount;  // per-sysclk count of f_in edges
44wire [freq_width-1:0] frequency_w;
45freq_gcount #(
46     .gw(4),
47     .freq_width(freq_width),
48     .initv(initv)
49) work (
50     .sysclk(sysclk), .f_in(f_in),
51     .g_in(1'b1),  // this is the whole point!
52     .ref_strobe(ref_strobe),
53     .frequency(frequency_w), .freq_strobe(freq_strobe),
54     .xcount(xcount)
55);
56
57// Nobody except some ancient USB debugging ever used this.
58// It's harmless; if you don't attach to the diff_stream,
59// diff_stream_strobe, or glitch_catcher ports, it will all
60// just disappear in synthesis.
61//
62// Make xcount available to stream to host at 24 MByte/sec, which was
63// especially interesting when reprogramming a AD9512 clock divider
64// on a LLRF4 board.
65// It might also be possible to histogram xcount.
66reg [15:0] stream=0;
67always @(posedge sysclk) begin
68     if (xcount > glitch_thresh) glitch_catcher <= ~glitch_catcher;
69     stream <= {stream[11:0], xcount};  // assumes freq_gcount gw=4
70end
71
72// Latch/pipeline one more time to perimeter of this module
73always @(posedge sysclk) begin
74     diff_stream <= stream;
75     diff_stream_strobe <= stream_strobe;
76     frequency <= frequency_w;
77end
78
79endmodule