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. 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.
設計一個滿足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
沒有留言:
張貼留言