2021年6月24日 星期四

DE2-115 的電子鐘

DE2-115  一個簡易的電子鐘,如同電子錶一樣顯示時間。

參考來源https://www.cnblogs.com/oomusou/archive/2008/07/27/verilog_digi_clock.html

SW17enable
SW16reset
SW15load (設定時間)
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



沒有留言:

張貼留言

2024_09 作業3 以Node-Red 為主

 2024_09 作業3  (以Node-Red 為主  Arduino 可能需要配合修改 ) Arduino 可能需要修改的部分 1)mqtt broker  2) 主題Topic (發行 接收) 3) WIFI ssid , password const char br...