数字跑表的verilog实现,用rst_n复位后开始计时,用pause暂停,输出为分、秒、百分秒的BCD码。
1 module stop_watch(rst_n, 2 clk, 3 //start, 4 pause, 5 msl, 6 msh, 7 sl, 8 sh, 9 ml, 10 mh 11 ); 12 input rst_n; 13 input clk; 14 //input start; 15 input pause; 16 output [3:0] msl; 17 output [3:0] msh; 18 output [3:0] sl; 19 output [3:0] sh; 20 output [3:0] ml; 21 output [3:0] mh; 22 23 reg [3:0] msl; 24 reg [3:0] msh; 25 reg [3:0] sl; 26 reg [3:0] sh; 27 reg [3:0] ml; 28 reg [3:0] mh; 29 30 reg msh_en; 31 reg sl_en; 32 reg sh_en; 33 reg ml_en; 34 reg mh_en; 35 36 //update the 1/100 second low number 37 //generate enable signal of 1/100 second high number 38 always@(posedge clk or rst_n) 39 if(!rst_n) 40 begin 41 msl <= 4'd0; 42 msh_en <= 1'b0; 43 end 44 else if(!pause) 45 begin 46 if(msl == 4'd9) 47 begin 48 msl <= 4'd0; 49 msh_en <= 1'b1; //msh的更新使能 50 end 51 else 52 begin 53 msl <= msl + 1'b1; 54 end 55 end 56 else 57 msh_en <= 1'b0; 58 59 60 always@(posedge clk or rst_n) 61 if(!rst_n) 62 begin 63 msh <= 4'd0; 64 sl_en <= 1'b0; 65 end 66 else if(msh_en) 67 begin 68 if(msh == 4'd9) 69 begin 70 msh <= 4'd0; 71 sl_en <= 1'b1; //sl的更新使能 72 end 73 else 74 begin 75 msh <= msh + 1'b1; 76 //sl_en <= 1'b0; //注意对进位的清零是在clk时钟下的,与msh_en独立 77 end 78 end 79 else 80 sl_en <= 1'b0; 81 82 //update the second low number 83 //generate enable signal of second high number 84 always@(posedge clk or rst_n) 85 if(!rst_n) 86 begin 87 sl <= 4'd0; 88 sh_en <= 1'b0; 89 end 90 else if(sl_en) 91 begin 92 if(sl == 4'd9) 93 begin 94 sl <= 4'd0; 95 sh_en <= 1'b1; //sh的更新使能 96 end 97 else 98 begin 99 sl <= sl + 1'b1; 100 //sh_en <= 1'b0; 101 end 102 end 103 else 104 sh_en <= 1'b0; 105 106 always@(posedge clk or rst_n) 107 if(!rst_n) 108 begin 109 sh <= 4'd0; 110 ml_en <= 1'b0; 111 end 112 else if(sh_en) 113 begin 114 if(sh == 4'd5) 115 begin 116 sh <= 4'd0; 117 ml_en <= 1'b1; //ml的更新使能 118 end 119 else 120 begin 121 sh <= sh + 1'b1; 122 //ml_en <= 1'b0; 123 end 124 end 125 else 126 ml_en <= 1'b0; 127 128 //update the minute low number 129 //generate enable signal of minute high number 130 always@(posedge clk or rst_n) 131 if(!rst_n) 132 begin 133 ml <= 4'd0; 134 mh_en <= 1'b0; 135 end 136 else if(ml_en) 137 begin 138 if(ml == 4'd9) 139 begin 140 ml <= 4'd0; 141 mh_en <= 1'b1; //mh的更新使能 142 end 143 else 144 begin 145 ml <= ml + 1'b1; 146 //mh_en <= 1'b0; 147 end 148 end 149 else 150 mh_en <= 1'b0; 151 152 always@(posedge clk or rst_n) 153 if(!rst_n) 154 begin 155 mh <= 4'd0; 156 end 157 else if(mh_en) 158 begin 159 if(mh == 4'd5) 160 begin 161 mh <= 4'd0; 162 end 163 else 164 begin 165 mh <= mh + 1'b1; 166 end 167 end 168 169 endmodule
testbench:
1 module stop_watch_tb; 2 3 // Inputs 4 reg rst_n; 5 reg clk; 6 reg pause; 7 8 // Outputs 9 wire [3:0] msl; 10 wire [3:0] msh; 11 wire [3:0] sl; 12 wire [3:0] sh; 13 wire [3:0] ml; 14 wire [3:0] mh; 15 16 // Instantiate the Unit Under Test (UUT) 17 stop_watch uut ( 18 .rst_n(rst_n), 19 .clk(clk), 20 .pause(pause), 21 .msl(msl), 22 .msh(msh), 23 .sl(sl), 24 .sh(sh), 25 .ml(ml), 26 .mh(mh) 27 ); 28 29 parameter CLK_PERIOD = 10; 30 31 initial begin 32 rst_n = 0; 33 clk = 1; 34 pause = 1; 35 36 #100; 37 rst_n = 1; 38 pause = 0; 39 40 end 41 42 always #(CLK_PERIOD/2) clk = ~clk; 43 44 endmodule
仿真结果: