数字频率计的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 begin20 //count_en <= 1'b0; //阻塞赋值or非阻塞?21 count_en = 1'b0; 22 freq_load = 1'b0;23 end24 else25 begin26 //count_en <= ~count_en;27 //freq_load <= ~count_en;28 count_en = ~count_en;29 freq_load = ~count_en;//控制,用阻塞,否则控制信号时序不对30 end31 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 begin23 cnt <= 4'd0;24 cout <= 1'b0;25 end26 else if(clr) //异步清零27 begin28 cnt <= 4'd0;29 cout <= 1'b0;30 end31 else if(en) //同步使能32 if(cnt == 4'd9)33 begin34 cnt <= 4'd0;35 cout <= 1'b1;36 end37 else38 begin39 cnt <= cnt + 1'b1;40 cout <= 1'b0;41 end42 43 */44 //使用阻塞赋值与非阻塞放着结果都正确,区别是什么??45 always@(posedge clk or negedge rst_n or posedge clr)46 if(!rst_n)47 begin48 cnt = 4'd0;49 cout = 1'b0;50 end51 else if(clr) //异步清零52 begin53 cnt = 4'd0;54 cout = 1'b0;55 end56 else if(en) //同步使能57 if(cnt == 4'd9)58 begin59 cnt = 4'd0;60 cout = 1'b1;61 end62 else63 begin64 cnt = cnt + 1'b1;65 cout = 1'b0;66 end67 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 else21 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 begin28 rst_n = 0;29 clk = 1;30 test_clk = 1;31 32 #1000;33 rst_n = 1;34 35 end36 37 always #(CLK_PERIOD/2) clk = ~clk;38 always #(TEST_CLK_PERIOD/2) test_clk = ~test_clk;39 40 endmodule
仿真结果: