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