DE2-115 一個簡易的電子鐘,如同電子錶一樣顯示時間。
參考來源https://www.cnblogs.com/oomusou/archive/2008/07/27/verilog_digi_clock.html
SW17 | enable |
SW16 | reset |
SW15 | load (設定時間) |
SW[3:0] | 設定分的個位數 |
SW[6:4] | 設定分的十位數 |
SW[10:7] | 設定時的個位數 |
SW[13:11] | 設定時的十位數 |
HEX[2] | 顯示秒的個位數 |
HEX[3] | 顯示秒的十位數 |
HEX[4] | 顯示分的個位數 |
HEX[5] | 顯示分的十位數 |
HEX[6] | 顯示時的個位數 |
HEX[7] | 顯示時的十位數 |
import pinassigment de2-115.csv
//Filename:digi_clock.v
module digi_clock (
input CLOCK_50,
input [17:0] SW,
input [3:0] KEY,
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)
);
clock u1 (
.clk(clk_1),
.en(SW[17]), // input enable
.clr(SW[16]), // input clear
.load(SW[15]), // input load
.sd0(4'h0), // input second digit 0
.sd1(3'h0), // input second digit 1
.md0(SW[3:0]), // input minute digit 0
.md1(SW[6:4]), // input minute digit 1
.hd0(SW[10:7]), // input hour digit 0
.hd1(SW[13:11]), // input hour digit 1
.sq0(w_sq0), // output second digit 0
.sq1(w_sq1), // output second digit 1
.mq0(w_mq0), // output minute digit 0
.mq1(w_mq1), // output minute digit 1
.hq0(w_hq0), // output minute digit 0
.hq1(w_hq1) // output minute digit 1
);
// 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
/*
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
/*
Filename??? : clock.v
*/
module clock (
input clk,
input en,
input clr,
input load,
input [3:0] sd0,
input [2:0] sd1,
input [3:0] md0,
input [2:0] md1,
input [3:0] hd0,
input [2:0] hd1,
output [3:0] sq0,
output [2:0] sq1,
output [3:0] mq0,
output [2:0] mq1,
output [3:0] hq0,
output [1:0] hq1,
output co
);
wire w_clr;
wire [3:0] w_md0;
wire [2:0] w_md1;
reg [3:0] w_hd0;
reg [2:0] w_hd1;
wire w_sco; // second carry
wire w_mco; // minute carry
wire w_hco; // hour carry
counter60 sec (
.clk(clk),
.load(load),
.clr(w_clr),
.en(en),
.d0(sd0),
.d1(sd1),
.q0(sq0),
.q1(sq1),
.co(w_sco)
);
counter60 min (
.clk(clk),
.load(load),
.clr(w_clr),
.en(en & w_sco),
.d0(w_md0),
.d1(w_md1),
.q0(mq0),
.q1(mq1),
.co(w_mco)
);
counter24 hour (
.clk(clk),
.load(load),
.clr(w_clr),
.en(en & w_mco & w_sco),
.d0(w_hd0),
.d1(w_hd1),
.q0(hq0),
.q1(hq1),
.co(w_hco)
);
assign w_clr = clr | co;
assign co = w_hco & w_mco & w_sco;
assign w_md0 = (!load) ? 0 :
(md0 < 10) ? md0 : 9;
assign w_md1 = (!load) ? 0 :
(md1 < 6) ? md1 : 5;
always@(load or hd0 or hd1) begin
if (!load) begin
w_hd0 = 0;
w_hd1 = 0;
end
else begin
if (hd1 <=1) begin // 0 1
w_hd1 = hd1;
if (hd0 <10)
w_hd0 = hd0;
else
w_hd0 =9;
end
else begin // >= 2
w_hd1 = 2;
if (hd0 <4)
w_hd0 = hd0;
else
w_hd0 = 3;
end
end
end
endmodule
/*
Filename??? : counter60.v
*/
module counter60 (
input clk,
input clr,
input load,
input en,
input [3:0] d0,
input [3:0] d1,
output reg [3:0] q0,
output reg [2:0] q1,
output co
);
assign co = q1[2] & q1[0] & q0[3] & q0[0]; // 101 1001 = 59
always@(posedge clk) begin
if (clr) begin
q0 <= 0;
q1 <= 0;
end
else if (load) begin
q0 <= d0;
q1 <= d1;
end
else if (en) begin
if (q0 == 9) begin
q0 <= 0;
if (q1 == 5)
q1 <= 0;
else
q1 <= q1 + 1;
end
else
q0 <= q0 + 1;
end
else begin
q0 <= q0;
q1 <= q1;
end
end
endmodule
/*
Filename : counter24.v
*/
module counter24 (
input clk,
input clr,
input load,
input en,
input [3:0] d0,
input [1:0] d1,
output reg [3:0] q0,
output reg [1:0] q1,
output co
);
assign co = q0[1] & q0[0] & q1[1]; // 010?? 11 = 23
always@(posedge clk) begin
if (clr) begin
q0 <= 0;
q1 <= 0;
end
else if (load) begin
q0 <= d0;
q1 <= d1;
end
else if (en) begin
if (q0 == 9) begin
q0 <= 0;
q1 <= q1 + 1;
end
else if (q1 == 2 & q0 == 3) begin // 23
q1 <= 0;
q0 <= 0;
end
else
q0 <= q0 + 1;
end
else begin
q0 <= q0;
q1 <= q1;
end
end
endmodule
沒有留言:
張貼留言