12-hour clock

Create a set of counters suitable for use as a 12-hour clock (with am/pm indicator). Your counters are clocked by a fast-running clk, with a pulse on ena whenever your clock should increment (i.e., once per second).

reset resets the clock to 12:00 AM. pm is 0 for AM and 1 for PM. hh, mm, and ss are two BCD (Binary-Coded Decimal) digits each for hours (01-12), minutes (00-59), and seconds (00-59). Reset has higher priority than enable, and can occur even when not enabled.

The following timing diagram shows the rollover behaviour from 11:59:59 AM to 12:00:00 PM and the synchronous reset and enable behaviour.

timu
题目网站

  1 module top_module(
  2     input clk,
  3     input reset,
  4     input ena,
  5     output pm,
  6     output [7:0] hh,
  7     output [7:0] mm,
  8     output [7:0] ss); 
  9 reg pm_temp;
 10     reg [3:0] ss_ones;
 11     reg [3:0] ss_tens;
 12     reg [3:0] mm_ones;
 13     reg [3:0] mm_tens;
 14     reg [3:0] hh_ones;
 15     reg [3:0] hh_tens;
 16     
 17     wire        add_ss_ones;
 18     wire        end_ss_ones;
 19     wire        add_ss_tens;
 20     wire        end_ss_tens;
 21     wire        add_mm_ones;
 22     wire        end_mm_ones;
 23     wire        add_mm_tens;
 24     wire        end_mm_tens;
 25     wire        add_hh_ones;
 26     wire        end_hh_ones_0;
 27     wire        end_hh_ones_1;
 28     wire        add_hh_tens;
 29     wire        end_hh_tens_0;
 30     wire        end_hh_tens_1;
 31     wire        pm_ding;
 32     
 33     assign add_ss_ones = ena;
 34     assign end_ss_ones = add_ss_ones && (ss_ones == 4'd9);
 35     always @(posedge clk)begin
 36         if(reset)begin
 37             ss_ones <= 4'b0;
 38         end
 39         else if(add_ss_ones)begin
 40             if(end_ss_ones)begin
 41                 ss_ones <= 4'b0;
 42             end
 43             else begin
 44                 ss_ones <= ss_ones + 4'b1;
 45             end
 46         end
 47     end
 48     
 49     assign add_ss_tens = end_ss_ones;
 50     assign end_ss_tens = add_ss_tens && (ss_tens == 4'd5);
 51     always @(posedge clk)begin
 52         if(reset)begin
 53             ss_tens <= 4'b0;
 54         end
 55         else if(add_ss_tens)begin
 56             if(end_ss_tens)begin
 57                 ss_tens <= 4'b0;
 58             end
 59             else begin
 60                 ss_tens <= ss_tens + 4'b1;
 61             end
 62         end
 63     end
 64     
 65     assign add_mm_ones = end_ss_tens;
 66     assign end_mm_ones = add_mm_ones && (mm_ones == 4'd9);
 67     always @(posedge clk)begin
 68         if(reset)begin
 69             mm_ones <= 4'b0;
 70         end
 71         else if(add_mm_ones)begin
 72             if(end_mm_ones)begin
 73                 mm_ones <= 4'b0;
 74             end
 75             else begin
 76                 mm_ones <= mm_ones + 4'b1;
 77             end
 78         end
 79     end
 80     
 81     assign add_mm_tens = end_mm_ones;
 82     assign end_mm_tens = add_mm_tens && (mm_tens == 4'd5);
 83     always @(posedge clk)begin
 84         if(reset)begin
 85             mm_tens <= 4'b0;
 86         end
 87         else if(add_mm_tens)begin
 88             if(end_mm_tens)begin
 89                 mm_tens <= 4'b0;
 90             end
 91             else begin
 92                 mm_tens <= mm_tens + 4'b1;
 93             end
 94         end
 95     end
 96     
 97     assign add_hh_ones = end_mm_tens;
 98     assign end_hh_ones_0 = add_hh_ones && (hh_ones == 4'd9);
 99     assign end_hh_ones_1 = add_hh_ones && ((hh_ones == 4'd2) && (hh_tens == 4'd1));
100     always @(posedge clk)begin
101         if(reset)begin
102             hh_ones <= 4'd2;
103         end
104         else if(add_hh_ones)begin
105             if(end_hh_ones_0)begin
106                 hh_ones <= 4'b0;
107             end
108             else if(end_hh_ones_1)begin
109                 hh_ones <= 4'b1;
110             end
111             else begin
112                 hh_ones <= hh_ones+4'b1;
113             end
114         end
115     end
116 
117     assign add_hh_tens = end_mm_tens;
118     assign end_hh_tens_0 = add_hh_tens && end_hh_ones_1;
119     assign end_hh_tens_1 = add_hh_tens && end_hh_ones_0;
120     always @(posedge clk)begin
121         if(reset)begin
122             hh_tens <= 4'b1;
123         end
124         else if(add_hh_tens)begin
125             if(end_hh_tens_0)begin
126                 hh_tens <= 4'b0;
127             end
128             else if(end_hh_tens_1)begin
129                 hh_tens <= hh_tens + 4'b1;
130             end
131         end
132     end
133     
134     always@(posedge clk)begin
135         if(reset)begin
136             pm_temp <= 1'b0;
137         end
138         else if(pm_ding)begin
139             pm_temp <= ~pm_temp;
140         end
141     end
142     
143     assign pm_ding = hh_tens == 4'd1 && hh_ones == 4'd1 && end_mm_tens;
144     
145     assign ss = {ss_tens, ss_ones};
146     assign mm = {mm_tens, mm_ones};
147     assign hh = {hh_tens, hh_ones};
148     assign pm = pm_temp;
149 
150 endmodule

按照之前的题目,由简单到复杂,这个题目就可以解决了,如果不清楚,建议把counter这个部分的题目,从第一题开始重新写一遍,慢慢理解就好。

posted @ 2024-04-10 14:37  江左子固  阅读(16)  评论(0编辑  收藏  举报