-
Notifications
You must be signed in to change notification settings - Fork 385
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
1 changed file
with
122 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,122 @@ | ||
//------------------------------------------------------------------------------ | ||
// freq_meter.sv | ||
// published as part of https://github.com/pConst/basic_verilog | ||
// Konstantin Pavlov, [email protected] | ||
//------------------------------------------------------------------------------ | ||
|
||
// INFO ------------------------------------------------------------------------ | ||
// frequency meter counts how many periods of test clock happen within | ||
// a given large time base. | ||
// Frequency value in MHz is proportional to system clock as readout/timebase | ||
// | ||
|
||
/* --- INSTANTIATION TEMPLATE BEGIN --- | ||
freq_meter fm1 ( | ||
.clk( clk ), // 62.5 MHz expected | ||
.nrst( nrst ), | ||
.test_clk( ), | ||
.test_ena( ), | ||
.readout( ) | ||
); | ||
--- INSTANTIATION TEMPLATE END ---*/ | ||
|
||
|
||
module freq_meter ( | ||
input clk, // system clock, 62.5 MHz expected | ||
input nrst, // reset (inversed) | ||
|
||
input test_clk, // signal to count | ||
input test_ena, // enable counting signal (in test_clk domain) | ||
|
||
output [31:0] readout = '0 // number of test_clk complete cycles per | ||
); // 1073741,824 mks time base | ||
|
||
|
||
logic [31:0] clk_div; | ||
clk_divider #( | ||
.WIDTH( 32 ) | ||
) sys_cd ( | ||
.clk( clk ), | ||
.nrst( nrst ), | ||
.ena( 1'b1 ), | ||
.out( ) | ||
); | ||
|
||
// synchronizing into test frequency time domain | ||
logic start_new_count; | ||
|
||
delay #( | ||
.LENGTH( 2 ), | ||
.WIDTH( 1 ) | ||
) sstart_new_count_d_SYNC_ATTR ( | ||
.clk( test_clk ), | ||
.nrst( 1'b1 ), | ||
.ena( 1'b1 ), | ||
.in( clk_div[15] ), // defines the timebase | ||
.out( start_new_count ) | ||
); | ||
|
||
// detecting rising edge of start condition | ||
logic start_new_count_rise; | ||
|
||
edge_detect start_new_count_ed ( | ||
.clk( test_clk ), | ||
.nrst( 1'b1 ), | ||
.in( start_new_count ), | ||
.rising( start_new_count_rise ), | ||
.falling( ), | ||
.both( ) | ||
); | ||
|
||
logic [31:0] cntr_tc = 31'b1; | ||
|
||
logic [31:0] readout_tc = '0; | ||
logic readout_tc_valid = 1'b0; | ||
|
||
always_ff @(posedge test_clk) begin | ||
if( start_new_count_rise ) begin | ||
|
||
// every counter refreshes approx. once in a second and holds a value of | ||
// test freq complete periods over 1073741,824 mks | ||
readout_tc[31:0] <= cntr_tc[31:0]; | ||
readout_tc_valid <= 1'b1; | ||
|
||
cntr_tc[31:0] <= 1; | ||
end else if( test_ena ) begin | ||
readout_tc_valid <= 1'b0; | ||
|
||
cntr_tc[31:0] <= cntr_tc[31:0] + 1'b1; | ||
end | ||
end | ||
|
||
// synchronizing back into clk time domain | ||
logic readout_valid; | ||
cdc_strobe readout_valid_tc_cdc ( | ||
.arst( 1'b0 ), | ||
|
||
.clk1( test_clk ), | ||
.nrst1( 1'b1 ), | ||
.strb1( readout_tc_valid ), | ||
|
||
.clk2( clk ), | ||
.nrst2( nrst ), | ||
.strb2( readout_valid ) | ||
); | ||
|
||
|
||
always_ff @(posedge clk) begin | ||
if( ~nrst ) begin | ||
readout[31:0] <= '0; | ||
end else begin | ||
if( readout_valid ) begin | ||
readout[31:0] <= readout_tc[31:0]; | ||
end | ||
end | ||
end | ||
|
||
endmodule | ||
|