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