数字频率计的verilog实现,输入时钟为1Hz的标准时钟。
1 module frequency_meter(rst_n, 2 clk, 3 //count_en, 4 test_clk, 5 count_clr, 6 freq_load, 7 freq_out 8 ); 9 input rst_n; 10 input clk; 11 input test_clk; 12 13 output freq_load; 14 output count_clr; 15 output [15:0] freq_out; 16 17 wire count_en; 18 19 wire [3:0] g; 20 wire [3:0] s; 21 wire [3:0] b; 22 wire [3:0] q; 23 24 wire s_clk; 25 wire b_clk; 26 wire q_clk; 27 28 freq_meter_ctrl u1_freq_meter_ctrl ( 29 .rst_n(rst_n), 30 .clk(clk), 31 .count_en(count_en), 32 .count_clr(count_clr), 33 .freq_load(freq_load) //没用到该信号 34 ); 35 36 counter10 u1_counter10 ( 37 .clk(test_clk), 38 .rst_n(rst_n), 39 .clr(count_clr), 40 .en(count_en), 41 .cnt(g), 42 .cout(s_clk) 43 ); 44 45 counter10 u2_counter10 ( 46 .clk(s_clk), 47 .rst_n(rst_n), 48 .clr(count_clr), 49 .en(count_en), 50 .cnt(s), 51 .cout(b_clk) 52 ); 53 54 counter10 u3_counter10 ( 55 .clk(b_clk), 56 .rst_n(rst_n), 57 .clr(count_clr), 58 .en(count_en), 59 .cnt(b), 60 .cout(q_clk) 61 ); 62 63 counter10 u4_counter10 ( 64 .clk(q_clk), 65 .rst_n(rst_n), 66 .clr(count_clr), 67 .en(count_en), 68 .cnt(q), 69 .cout() 70 ); 71 72 latch_out u1_latch_out ( 73 .rst_n(rst_n), 74 //.load(freq_load), 75 .clk(clk), 76 .din({q,b,s,g}), 77 .dout(freq_out) 78 ); 79 80 endmodule
子模块:
1 module freq_meter_ctrl(rst_n, 2 clk, 3 count_en, 4 count_clr, 5 freq_load 6 ); 7 input rst_n; 8 input clk; 9 10 output count_en; 11 output count_clr; 12 output freq_load; 13 14 reg count_en; 15 reg freq_load; 16 17 always@(posedge clk) 18 if(!rst_n) 19 begin 20 //count_en <= 1'b0; //阻塞赋值or非阻塞? 21 count_en = 1'b0; 22 freq_load = 1'b0; 23 end 24 else 25 begin 26 //count_en <= ~count_en; 27 //freq_load <= ~count_en; 28 count_en = ~count_en; 29 freq_load = ~count_en;//控制,用阻塞,否则控制信号时序不对 30 end 31 32 assign count_clr = ~clk & freq_load; 33 34 endmodule
计数子模块:
1 module counter10(clk, 2 rst_n, 3 clr, 4 en, 5 cnt, 6 cout 7 ); 8 input clk; 9 input rst_n; 10 input clr; 11 input en; 12 13 output [3:0] cnt; 14 output cout; 15 16 reg [3:0] cnt; 17 reg cout; 18 19 /* 20 always@(posedge clk or negedge rst_n or posedge clr) 21 if(!rst_n) 22 begin 23 cnt <= 4'd0; 24 cout <= 1'b0; 25 end 26 else if(clr) //异步清零 27 begin 28 cnt <= 4'd0; 29 cout <= 1'b0; 30 end 31 else if(en) //同步使能 32 if(cnt == 4'd9) 33 begin 34 cnt <= 4'd0; 35 cout <= 1'b1; 36 end 37 else 38 begin 39 cnt <= cnt + 1'b1; 40 cout <= 1'b0; 41 end 42 43 */ 44 //使用阻塞赋值与非阻塞放着结果都正确,区别是什么?? 45 always@(posedge clk or negedge rst_n or posedge clr) 46 if(!rst_n) 47 begin 48 cnt = 4'd0; 49 cout = 1'b0; 50 end 51 else if(clr) //异步清零 52 begin 53 cnt = 4'd0; 54 cout = 1'b0; 55 end 56 else if(en) //同步使能 57 if(cnt == 4'd9) 58 begin 59 cnt = 4'd0; 60 cout = 1'b1; 61 end 62 else 63 begin 64 cnt = cnt + 1'b1; 65 cout = 1'b0; 66 end 67 68 endmodule
锁存子模块:
1 module latch_out(rst_n, 2 clk, 3 //load, 4 din, 5 dout 6 ); 7 8 input rst_n; 9 input clk; 10 //input load; 11 input [15:0] din; 12 13 output [15:0] dout; 14 15 reg [15:0] dout; 16 17 always@(posedge clk) 18 if(!rst_n) 19 dout <= 16'd0; 20 else 21 dout <= din; 22 23 endmodule
testbench:
1 module frequency_meter_tb; 2 3 // Inputs 4 reg rst_n; 5 reg clk; 6 reg test_clk; 7 8 // Outputs 9 wire count_clr; 10 wire freq_load; 11 wire [15:0] freq_out; 12 13 // Instantiate the Unit Under Test (UUT) 14 frequency_meter uut ( 15 .rst_n(rst_n), 16 .clk(clk), 17 .test_clk(test_clk), 18 .count_clr(count_clr), 19 .freq_load(freq_load), 20 .freq_out(freq_out) 21 ); 22 23 parameter CLK_PERIOD = 1000; 24 parameter TEST_CLK_PERIOD = 18; 25 26 27 initial begin 28 rst_n = 0; 29 clk = 1; 30 test_clk = 1; 31 32 #1000; 33 rst_n = 1; 34 35 end 36 37 always #(CLK_PERIOD/2) clk = ~clk; 38 always #(TEST_CLK_PERIOD/2) test_clk = ~test_clk; 39 40 endmodule
仿真结果: