要求:
参考时钟 50Mhz,检测时钟为 1-200Mhz,写出Verilog来。
一、设计
1 module clock_test 2 //========================< 参数 >========================================== 3 #( 4 parameter CLK_S_FRE = 31'd50 , // 基准时钟频率值 5 parameter GATE_TIME = 31'd5000 // 门控时间设置 6 ) 7 //========================< 端口 >========================================== 8 ( 9 input clk_s , // 基准时钟信号 10 input rst_n , // 复位信号 11 input clk_x , // 被测时钟信号 12 output reg [31:0] data_x // 被测时钟频率输出 13 ); 14 //========================< 信号 >========================================== 15 reg [31:0] gate_cnt ; 16 reg gate ; 17 reg gate_s_r1 ; 18 reg gate_s_r2 ; 19 reg gate_x_r1 ; 20 reg gate_x_r2 ; 21 reg [31:0] s_cnt ; 22 reg [31:0] s_cnt_r ; 23 reg [31:0] x_cnt ; 24 reg [31:0] x_cnt_r ; 25 wire neg_gate_s ; 26 wire neg_gate_x ; 27 //========================================================================== 28 //== ________________ _______________ 29 //== gate门控 ___| |___| |____ 30 //== gate_cnt 0 1 5000 0 1 5000 31 //========================================================================== 32 always @(posedge clk_x or negedge rst_n) begin 33 if(!rst_n) 34 gate_cnt <= 'd0; 35 else if(gate_cnt == GATE_TIME + 20) 36 gate_cnt <= 'd0; 37 else 38 gate_cnt <= gate_cnt + 1'b1; 39 end 40 41 always @(posedge clk_x or negedge rst_n) begin 42 if(!rst_n) 43 gate <= 1'b0; 44 else if(gate_cnt < GATE_TIME) 45 gate <= 1'b1; 46 else 47 gate <= 1'b0; 48 end 49 //========================================================================== 50 //== 打拍检测下降沿 51 //========================================================================== 52 always @(posedge clk_s) begin 53 gate_s_r1 <= gate; 54 gate_s_r2 <= gate_s_r1; 55 end 56 57 always @(posedge clk_x) begin 58 gate_x_r1 <= gate; 59 gate_x_r2 <= gate_x_r1; 60 end 61 62 assign neg_gate_s = gate_s_r2 & (~gate_s_r1); 63 assign neg_gate_x = gate_x_r2 & (~gate_x_r1); 64 //========================================================================== 65 //== 门控下的计数 66 //========================================================================== 67 always @(posedge clk_s or negedge rst_n) begin 68 if(!rst_n) begin 69 s_cnt <= 'd0; s_cnt_r <= 'd0; 70 end 71 else if(neg_gate_s) begin 72 s_cnt <= 'd0; s_cnt_r <= s_cnt; 73 end 74 else if(gate_s_r1) begin 75 s_cnt <= s_cnt + 1'b1; 76 end 77 end 78 79 always @(posedge clk_x or negedge rst_n) begin 80 if(!rst_n) begin 81 x_cnt <= 'd0; x_cnt_r <= 'd0; 82 end 83 else if(neg_gate_x) begin 84 x_cnt <= 'd0; x_cnt_r <= x_cnt; 85 end 86 else if(gate_x_r1) begin 87 x_cnt <= x_cnt + 1'b1; 88 end 89 end 90 //========================================================================== 91 //== 输出频率值 92 //========================================================================== 93 always @(posedge clk_s or negedge rst_n) begin 94 if(!rst_n) begin 95 data_x <= 'd0; 96 end 97 else if(~gate_s_r2 & gate_s_r1) begin 98 data_x <= (CLK_S_FRE * x_cnt_r ) / s_cnt_r; 99 end 100 end 101 102 103 104 endmodule
二、仿真
1 `timescale 1ns/1ps //时间精度 2 3 module clock_test_tb; 4 //========================< 端口 >========================================== 5 reg clk_s ; //时钟,50Mhz 6 reg rst_n ; //复位,高电平有效 7 reg clk_x ; //2分频时钟 8 9 //========================================================================== 10 //== 模块例化 11 //========================================================================== 12 clock_test u_clock_test 13 ( 14 .clk_s (clk_s ), 15 .rst_n (rst_n ), 16 .clk_x (clk_x ), 17 .data_x ( ) 18 ); 19 //========================================================================== 20 //== 时钟信号和复位信号 21 //========================================================================== 22 initial begin 23 clk_s = 1; 24 forever 25 #10 clk_s = ~clk_s; //50Mhz 26 end 27 28 initial begin 29 clk_x = 1; 30 forever 31 #2.5 clk_x = ~clk_x; //200Mhz 32 end 33 34 initial begin 35 rst_n = 0; #(41); 36 rst_n = 1; 37 end 38 39 40 endmodule