数字跑表的verilog实现

数字跑表的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

仿真结果:

原文地址:https://www.cnblogs.com/youngforever/p/3115581.html