2012年12月9日 星期日

1小時倒數計時器 Down Count Timer

1小時倒數計時器 Down Count Timer 適用於DE2-70
SW[17]==enable
SW[16]==load
KEY[0]==reset
SW[3:0] ==1's second

SW[6:4] ==10's second
SW[10:7] ==1's minute
SW[13:11] ==10's minute


//Timer 59:59 (minute / second )
//SW[17] === enable Timer
//SW[16] === load Timer SWITCH
//KEY[0] === reset
//
module Timer (
input  CLOCK_50,
input  [17:0] SW,
input  [3:0]  KEY,
output [3:0]  LEDG,
output [6:0]  HEX0,
output [6:0]  HEX1,
output [6:0]  HEX2,
output [6:0]  HEX3,
output [6:0]  HEX4,
output [6:0]  HEX5
);

wire [7:0] segout0;   //HEX 0
wire [7:0] segout1;   //HEX 1
wire [7:0] segout2;   //HEX 2
wire [7:0] segout3;   //HEX 3
wire [7:0] segout4;   //HEX 4
wire [7:0] segout5;   //HEX 5

wire       clk_1;
wire [3:0] w_sq0;
wire [2:0] w_sq1;
wire w_sco;

wire [3:0] w_mq0;
wire [2:0] w_mq1;
wire w_mco;

wire w_clr;
wire [3:0] w_md0;
wire [2:0] w_md1;
wire [3:0] w_sd0; 
wire [2:0] w_sd1;

wire [3:0] md0;
wire [2:0] md1;
wire [3:0] sd0; 
wire [2:0] sd1;


assign sd0=SW[3:0];
assign sd1=SW[6:4];

assign md0=SW[10:7];
assign md1=SW[13:11];

wire load;
assign load=SW[16];
assign LEDG[2]=clk_1;


assign w_sd0 = (!load) ? 0 :
                (sd0 < 10) ? sd0 : 9;
assign w_sd1 = (!load) ? 0 : 
                (sd1 < 6)  ? sd1 : 5;
                       
assign w_md0 = (!load) ? 0 :
                (md0 < 10) ? md0 : 9;
assign w_md1 = (!load) ? 0 : 
                (md1 < 6)  ? md1 : 5;

// 1Hz clock
Divide_N # (.WIDTH(26), .N(50_000_000))u0 (
.clk(CLOCK_50),
.rst_n(KEY[0]),
.o_clk(clk_1)
);


dwn_counter60 sec (
.clk(clk_1),
.load(load),
.clr(w_clr),
.en(SW[17]),

.d0(w_sd0),
.d1(w_sd1),

.q0(w_sq0),
.q1(w_sq1),
.co(w_sco)
);

dwn_counter60 min (
.clk(clk_1),
.load(load),
.clr(w_clr),
.en(w_men),

.d0(w_md0),
.d1(w_md1),

.q0(w_mq0),
.q1(w_mq1),
.co(w_mco)
);


assign w_clr = KEY[0] ;
assign w_men = SW[17] & w_sco;


assign LEDG[0]=w_sco;
assign LEDG[1]=w_mco;

//*******display seconds************

_7seg UUT0(.hex(w_sq0),
               .seg(segout0));
    
    assign HEX0=segout0[6:0];
    
   
_7seg UUT1(.hex({1'b0,w_sq1}),
               .seg(segout1));
    
    assign HEX1=segout1[6:0];
    
    //*******display minute*************
    _7seg UUT2(.hex(w_mq0),
               .seg(segout2));
    
    assign HEX2=segout2[6:0];
    
    _7seg UUT3(.hex({1'b0,w_mq1}),
               .seg(segout3));
    
    assign HEX3=segout3[6:0];
    
   
    assign HEX4=7'b111_1111;
assign HEX5=7'b111_1111;


endmodule





//Input  : Clock . Reset 
//Output : Clock Divided by N Clock pluse   

module Divide_N  (
input  clk,
input  rst_n,
output o_clk
);
 
parameter WIDTH = 10;
parameter N     = 1_000;
reg [WIDTH-1:0] cnt_p;
reg [WIDTH-1:0] cnt_n;
reg             clk_p;
reg             clk_n;

//setting output clock 
assign o_clk = (N == 1) ? clk :    
(N[0])   ? (clk_p | clk_n) : (clk_p);
//if N=1 then output clock = clock_in , Teset N= Odd or Even ??
//若為奇數,則clk_p | clk_n,若為偶數,則clk_p即可
   //**********************(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;         //clock is Counted to N-1 ???
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;       //if N/2 > cnt_p then clk_p = 1-->0-->1
else //generate clock/2 pluse
clk_p = 0;    
end
//**********************(clk_n)***********************   
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





module dwn_counter60 (
   input            clk,
   input            clr,
   input            load,
   input            en,
   input      [3:0] d0, //load 1's  second or minute
   input      [2:0] d1, //load 10's second or minute
   output reg [3:0] q0,
   output reg [2:0] q1,
   output           co
 );
 
//up counter60 assign co = q1[2] & q1[0] & q0[3] & q0[0]; // 101 1001 = 59
//down counter60 
assign co = ((~q1[2]) & (~q1[1]) & (~q1[0]) & (~q0[3]) & (~q0[2]) & (~q0[1])
           & (~q0[0])); // 101 1001 = 59 
 
always@(posedge clk) begin  //0
if (!clr) begin  //1
q0 <= 4'b0;
q1 <= 3'b0;
end  //1
else if (load) begin  //2
q0 <= d0;
q1 <= d1;
end  //2
else if (en) begin  //3
if (q0 == 4'd0) begin  //4
q0 <= 4'd9;
if (q1 == 4'd0) 
q1 <= 4'd5;
else
q1 <= q1 - 1;
end   //4
else 
q0 <= q0 - 1;
end //3 
else 
begin  //5
q0 <= q0;
q1 <= q1;
end  //5
 
 end   //0
  

endmodule
 



//-----------------------------------------
//Common-cathod seven segment display
//using case.....endcase statement
//Filename : sevenseg_case.v
//----------------------------------------- 
module _7seg(hex , seg);
    input  [3:0] hex;
    output [7:0] seg;
    reg    [7:0] seg;
    
        

 // segment encoding
 //      0
 //     ---  
 //  5 |   | 1
 //     ---   <- 6
 //  4 |   | 2
 //     ---
 //      3
 always @(hex)
 begin
  case (hex)
       // Dot point is always disable
       4'b0001 : seg = 8'b11111001;   //1 = F9H
       4'b0010 : seg = 8'b10100100;   //2 = A4H
       4'b0011 : seg = 8'b10110000;   //3 = B0H
       4'b0100 : seg = 8'b10011001;   //4 = 99H
       4'b0101 : seg = 8'b10010010;   //5 = 92H
       4'b0110 : seg = 8'b10000010;   //6 = 82H
       4'b0111 : seg = 8'b11111000;   //7 = F8H
       4'b1000 : seg = 8'b10000000;   //8 = 80H
       4'b1001 : seg = 8'b10010000;   //9 = 90H
       4'b1010 : seg = 8'b10001000;   //A = 88H
       4'b1011 : seg = 8'b10000011;   //b = 83H
       4'b1100 : seg = 8'b11000110;   //C = C6H
       4'b1101 : seg = 8'b10100001;   //d = A1H
       4'b1110 : seg = 8'b10000110;   //E = 86H
       4'b1111 : seg = 8'b10001110;   //F = 8EH
       default : seg = 8'b11000000;   //0 = C0H
     endcase
   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...