2021年6月24日 星期四

DE2-115 12-hour clock

 DE2-115 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. hhmm, 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.

設計一個滿足12小時計時的時鐘系列計數器(包括am/pm指示)。該計數器由一個fast-running clk驅動,每當時鐘需要增加計時時,ena信號則會发生脈沖信號(如:每秒一次)。 reset信號覆位時鐘到12:00 AM。pm信號為0時指示AM,為1時指示PM。hh、mm、ss都為兩個BCD digits(8 bits),分別表示小時(01-12)、分鐘(00-59)、秒(00-59)。reset 比 enable信號優先級更高,即使未使能,也要執行覆位操作。 下面的時序圖展示了時鐘從11:59:59 AM 到12:00:00 PM的信號變化,以及同步覆位和使能操作結果。




//Filename:digi_12clock.v

module digi_12clock (

 input  CLOCK_50,

 input  [17:0] SW,

 input  [3:0]  KEY,

 output [7:0]  LEDG,

 output [6:0]  HEX2,

 output [6:0]  HEX3,

 output [6:0]  HEX4,

 output [6:0]  HEX5,

 output [6:0]  HEX6,

 output [6:0]  HEX7

);


wire  clk_1;

wire [3:0] w_sq0;

wire [2:0] w_sq1;

wire [3:0] w_mq0;

wire [2:0] w_mq1;

wire [3:0] w_hq0;

wire [2:0] w_hq1;


// 1Hz clock

divn # (.WIDTH(26), .N(50000000))

u0 (

  .clk(CLOCK_50), .rst_n(KEY[0]), .o_clk(clk_1)

);

top_module u1( 

 .clk(clk_1), 

 .reset(SW[16]), 

 .ena(SW[17]), 

 .pm(LEDG[0]), 

 .hh({w_hq1,w_hq0}), // output hour digit  

 .mm({w_mq1,w_mq0}), // output minute digit

 .ss({w_sq1,w_sq0})  // output second digit

 ); 

// sec. dig0 to seg7

seg7_lut u2 (  .i_dig(w_sq0),  .o_seg(HEX2));

// sec. dig1 to seg7

seg7_lut u3 ( .i_dig({1'b0, w_sq1}), .o_seg(HEX3));

// min. dig0 to seg7

seg7_lut u4 ( .i_dig(w_mq0), .o_seg(HEX4));

// min. dig1 to seg7

seg7_lut u5 ( .i_dig({1'b0, w_mq1}), .o_seg(HEX5));

// hour dig0 to seg7

seg7_lut u6 ( .i_dig(w_hq0), .o_seg(HEX6));

// hour dig1 to seg7

seg7_lut u7 ( .i_dig({1'b0, w_hq1}), .o_seg(HEX7));

endmodule

===================================================

/*

//12-hour clock

*/

module top_module( 

 input clk, 

 input reset, 

 input ena, 

 output reg pm, 

 output reg [7:0] hh, 

 output reg [7:0] mm, 

 output reg [7:0] ss); 


 always@(posedge clk ) //處理秒00-59

     if (reset) 

        ss <= 8'h00; 

     else if(ena) begin 

         if(ss == 8'h59) 

             ss <= 8'h00; 

     else begin if(ss[3:0] < 4'h9)

             ss[3:0] <= ss[3:0] + 1'h1; 

     else begin 

         ss[3:0] <= 0; 

         ss[7:4] <= ss[7:4] + 1'h1; 

     end 

     end 

  end 


 always@(posedge clk) //處理分 00-59

     if (reset) 

        mm <= 8'h00; 

     else if(ena) begin 

         if(ss == 8'h59) 

             if(mm == 8'h59) 

                 mm <= 8'h00; 

             else if(mm[3:0] < 4'h9) begin 

                 mm[3:0] <= mm[3:0] + 1'h1; 

              end 

             else begin 

                 mm[3:0] <= 0; 

                 mm[7:4] <= mm[7:4] + 1'h1; 

     end 

 end 


 always@(posedge clk ) //處理時 00-12

     if (reset) 

        hh <= 8'h12; 

     else if(ena) begin 

         if(mm == 8'h59 && ss == 8'h59) begin 

             if(hh == 8'h12) 

                 hh <= 8'h01; 

             else if(hh[3:0] < 4'h9) begin 

                 hh[3:0] <= hh[3:0] + 1'h1; 

             end 

             else begin 

                 hh[3:0] <= 0; 

                 hh[7:4] <= hh[7:4] + 1'h1; 

             end 

         end 

  end 


 always@(posedge clk ) //處理上午下午 AM/PM

         if (reset) 

            pm <= 0; 

         else if(hh == 8'h11 && mm == 8'h59 && ss == 8'h59) 

         pm =!pm; 

endmodule


===================================================

/*

Filename  : divn.v

*/


module divn  (

  input  clk,

  input  rst_n,

  output o_clk

);


parameter WIDTH = 3;

parameter N  = 6;


reg [WIDTH-1:0] cnt_p;

reg [WIDTH-1:0] cnt_n;

reg  clk_p;

reg  clk_n;


assign o_clk = (N == 1) ? clk : (N[0]) ? (clk_p | clk_n) : (clk_p);


always@(posedge clk or negedge rst_n) begin

if (!rst_n)

cnt_p <= 0;

else if (cnt_p == (N-1))

cnt_p <= 0;

else

cnt_p <= cnt_p + 1;

end


always@(posedge clk or negedge rst_n) begin

if (!rst_n)

clk_p <= 1;

else if (cnt_p < (N>>1))

clk_p = 1;

else

clk_p = 0;

end


always@(negedge clk or negedge rst_n) begin

if (!rst_n)

cnt_n <= 0;

else if (cnt_n == (N-1))

cnt_n <= 0;

else

cnt_n <= cnt_n + 1;

end


always@(negedge clk or negedge rst_n) begin

if (!rst_n)

clk_n <= 1;

else if (cnt_n < (N>>1))

clk_n = 1;

else

clk_n = 0;

end

endmodule


===================================================
/*
Filename : seg7_lut.V
*/
module seg7_lut (
input  [3:0] i_dig,
output reg [6:0] o_seg
);

always@(i_dig) begin
case(i_dig)
4'h1: o_seg = 7'b111_1001;  //  ---t----
4'h2: o_seg = 7'b010_0100;  // |        |
4'h3: o_seg = 7'b011_0000;  // lt       rt
4'h4: o_seg = 7'b001_1001;  // |        |
4'h5: o_seg = 7'b001_0010;  //  ---m----
4'h6: o_seg = 7'b000_0010;  // |        |
4'h7: o_seg = 7'b111_1000;  // lb       rb
4'h8: o_seg = 7'b000_0000;  // |        |
4'h9: o_seg = 7'b001_1000;  //  ---b----
4'ha: o_seg = 7'b000_1000;
4'hb: o_seg = 7'b000_0011;
4'hc: o_seg = 7'b100_0110;
4'hd: o_seg = 7'b010_0001;
4'he: o_seg = 7'b000_0110;
4'hf: o_seg = 7'b000_1110;
4'h0: o_seg = 7'b100_0000;
endcase
end

endmodule

沒有留言:

張貼留言

Messaging API作為替代方案

  LINE超好用功能要沒了!LINE Notify明年3月底終止服務,有什麼替代方案? LINE Notify將於2025年3月31日結束服務,官方建議改用Messaging API作為替代方案。 //CHANNEL_ACCESS_TOKEN = 'Messaging ...