Skip to content

Commit 4eae34a

Browse files
committed
Added freq_meter module
1 parent aec03d4 commit 4eae34a

File tree

1 file changed

+122
-0
lines changed

1 file changed

+122
-0
lines changed

freq_meter.sv

Lines changed: 122 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,122 @@
1+
//------------------------------------------------------------------------------
2+
// freq_meter.sv
3+
// published as part of https://github.com/pConst/basic_verilog
4+
// Konstantin Pavlov, pavlovconst@gmail.com
5+
//------------------------------------------------------------------------------
6+
7+
// INFO ------------------------------------------------------------------------
8+
// frequency meter counts how many periods of test clock happen within
9+
// a given large time base.
10+
// Frequency value in MHz is proportional to system clock as readout/timebase
11+
//
12+
13+
/* --- INSTANTIATION TEMPLATE BEGIN ---
14+
15+
freq_meter fm1 (
16+
.clk( clk ), // 62.5 MHz expected
17+
.nrst( nrst ),
18+
19+
.test_clk( ),
20+
.test_ena( ),
21+
22+
.readout( )
23+
);
24+
25+
--- INSTANTIATION TEMPLATE END ---*/
26+
27+
28+
module freq_meter (
29+
input clk, // system clock, 62.5 MHz expected
30+
input nrst, // reset (inversed)
31+
32+
input test_clk, // signal to count
33+
input test_ena, // enable counting signal (in test_clk domain)
34+
35+
output [31:0] readout = '0 // number of test_clk complete cycles per
36+
); // 1073741,824 mks time base
37+
38+
39+
logic [31:0] clk_div;
40+
clk_divider #(
41+
.WIDTH( 32 )
42+
) sys_cd (
43+
.clk( clk ),
44+
.nrst( nrst ),
45+
.ena( 1'b1 ),
46+
.out( )
47+
);
48+
49+
// synchronizing into test frequency time domain
50+
logic start_new_count;
51+
52+
delay #(
53+
.LENGTH( 2 ),
54+
.WIDTH( 1 )
55+
) sstart_new_count_d_SYNC_ATTR (
56+
.clk( test_clk ),
57+
.nrst( 1'b1 ),
58+
.ena( 1'b1 ),
59+
.in( clk_div[15] ), // defines the timebase
60+
.out( start_new_count )
61+
);
62+
63+
// detecting rising edge of start condition
64+
logic start_new_count_rise;
65+
66+
edge_detect start_new_count_ed (
67+
.clk( test_clk ),
68+
.nrst( 1'b1 ),
69+
.in( start_new_count ),
70+
.rising( start_new_count_rise ),
71+
.falling( ),
72+
.both( )
73+
);
74+
75+
logic [31:0] cntr_tc = 31'b1;
76+
77+
logic [31:0] readout_tc = '0;
78+
logic readout_tc_valid = 1'b0;
79+
80+
always_ff @(posedge test_clk) begin
81+
if( start_new_count_rise ) begin
82+
83+
// every counter refreshes approx. once in a second and holds a value of
84+
// test freq complete periods over 1073741,824 mks
85+
readout_tc[31:0] <= cntr_tc[31:0];
86+
readout_tc_valid <= 1'b1;
87+
88+
cntr_tc[31:0] <= 1;
89+
end else if( test_ena ) begin
90+
readout_tc_valid <= 1'b0;
91+
92+
cntr_tc[31:0] <= cntr_tc[31:0] + 1'b1;
93+
end
94+
end
95+
96+
// synchronizing back into clk time domain
97+
logic readout_valid;
98+
cdc_strobe readout_valid_tc_cdc (
99+
.arst( 1'b0 ),
100+
101+
.clk1( test_clk ),
102+
.nrst1( 1'b1 ),
103+
.strb1( readout_tc_valid ),
104+
105+
.clk2( clk ),
106+
.nrst2( nrst ),
107+
.strb2( readout_valid )
108+
);
109+
110+
111+
always_ff @(posedge clk) begin
112+
if( ~nrst ) begin
113+
readout[31:0] <= '0;
114+
end else begin
115+
if( readout_valid ) begin
116+
readout[31:0] <= readout_tc[31:0];
117+
end
118+
end
119+
end
120+
121+
endmodule
122+

0 commit comments

Comments
 (0)