In: Electrical Engineering
1a. Write your Verilog program to implement the timer counter. HEX0 should show tenths of seconds from 0 to 9. HEX1 and HEX2 should show a count of seconds, from 00 to 59. The ones count is on HEX1 and the tens count is on HEX2.
1b. Count backwards and forwards. Add a button or switch to control counting direction. When counting forwards or backwards, your count should not stop but rollover appropriately at the correct time. When counting forward, at 59.9, the count should roll over to 00.0. When counting backwards at 00.0, the count should roll back to 59.9.
1c.Add a preset signal. Preset should set the display count to 59. 9. Use a button for the preset.
1d.Employ a start/stop switch for the counter. When the switch is in the stop position, the count should not be updated on the seven segment displays. The displays should not be turned off, but should maintain the last count shown when the count is stopped. Example: count is 42.3 and the switch is set to stop count. The hex display should show 42.3. When the switch is placed in the start position, the count should resume from where it stopped.
So far I have code for the following: a divide by 2 clock, divide by 5 clock, divide by 10 clock, a decimal counter (0-9), and have started this last top level. However, do not know how to finish it. Please help me. Thanks!
module divide_by_2(Clk,reset, D, Q); //Divide by 2 clock with
reset using D flip flop
input wire Clk, D, reset;
output wire Q;
reg Qnext;
assign Q = Qnext;
always @(posedge Clk, posedge reset) //always at the
positive edge of the clock or reset
if (reset)
begin //
asynchronous reset when reset is high
Qnext <=
1'b0;; //Q gets the value 0
end
else
begin
Qnext <= D;
// Q gets the value of D on posedge of clock
end
endmodule
module divide_by_5(Clk,reset,DA,DB,DC,DD,QA,QB,QC,QD,Y);
input wire DA,DB,DC,DD,Clk,reset;
output wire QA,QB,QC,QD,Y;
assign Y= QD | QB;
divide_by_2 inst0(Clk,reset,(~QA & ~QC),QA);
divide_by_2 inst1(Clk,reset,((QA & ~QB)|(~QA &
QB)),QB);
divide_by_2 inst2(Clk,reset,(QA & QB),QC);
divide_by_2_Inverse inst3(Clk,reset,QB,QD);
endmodule
module divide_by_10(Clk_in, Clk_out, reset);
input Clk_in, reset;
output Clk_out;
divide_by_2 inst0(Clk_in,reset, Clk_in, Q);
divide_by_5 inst1(~Q,reset,QA,QB,QC,QD,QA,QB,QC,QD,Y);
assign Clk_out= Y;
endmodule
module decimal_counter(OVERFLOW, CLK, RST,A);
input CLK,RST;
output OVERFLOW;
output [3:0] A;
reg OVERFLOW_reg;
reg[3:0]A_reg;
assign OVERFLOW = OVERFLOW_reg;
assign A = A_reg;
always @ (posedge CLK or negedge RST)
//asynchronous reset condition takes priority check
for that event first
if (RST == 1'd0) begin
OVERFLOW_reg <= 1'b0;
A_reg <= 4'b0000;
end
else if (A_reg < 4'd9)
begin
// as long as A is less than 9, add
1 to A
A_reg <=
A_reg + 1'b1;
// do not trigger overflow because
count A is still a single digit
OVERFLOW_reg
<= 1'b0;
end
else
begin
// Count A is double digit 10 here,
reset count to 0
// trigger overflow for the digit 1
that should be carried output
A_reg <=
4'b0000;
OVERFLOW_reg
<= 1'b1;
end
endmodule
module TopLevel(CLOCK_50, KEY, LEDR, HEX0, HEX1, HEX2);
input wire CLOCK_50;
input wire [2:0]KEY;
output wire [5:0]LEDR;
output wire [6:0]HEX0;
reg [6:0]rHEX0;
reg [6:0]rHEX1;
reg [6:0]rHEX2;
assign HEX0 = rHEX0;
assign HEX1= rHEX1;
assign HEX2= rHEX2;
/* (OVERFLOW, CLK, RST,A)*/
decimal_counter
inst0(HEX2,CLOCK_50,KEY[1],HEX0);
divide_by_5
inst1(Clk,KEY[1],A,DB,DC,DD,QA,QB,QC,QD,HEX1);
decimal_counter
inst2(HEX1,CLOCK_50,KEY[1],HEX2);
always @(HEX0,HEX1)
begin
case (A)
1'b0: rHEX0 = 7'h40;
1'b1: rHEX0 = 7'h79;
1'b2: rHEX0 = 7'h24;
1'b3: rHEX0 = 7'h30;
1'b4: rHEX0 = 7'h19;
1'b5: rHEX0 = 7'h12;
1'b6: rHEX0 = 7'h02;
1'b7: rHEX0 = 7'h78;
1'b8: rHEX0 = 7'h00;
1'b9: rHEX0 = 7'h18;
endcase
end
always @ (HEX2)
begin
case (A)
1'b0: rHEX2 = 7'h40;
1'b1: rHEX2 = 7'h79;
1'b2: rHEX2 = 7'h24;
1'b3: rHEX2 = 7'h30;
1'b4: rHEX2 = 7'h19;
1'b5: rHEX2 = 7'h12;
endcase
end
endmodule
module divide_by_2(Clk,reset, D, Q); //Divide by 2 clock with
reset using D flip flop
input wire Clk, D, reset;
output wire Q;
reg Qnext;
assign Q = Qnext;
always @(posedge Clk, posedge reset) //always at the
positive edge of the clock or reset
if (reset)
begin //
asynchronous reset when reset is high
Qnext <=
1'b0;; //Q gets the value 0
end
else
begin
Qnext <= D;
// Q gets the value of D on posedge of clock
end
endmodule
module divide_by_5(Clk,reset,DA,DB,DC,DD,QA,QB,QC,QD,Y);
input wire DA,DB,DC,DD,Clk,reset;
output wire QA,QB,QC,QD,Y;
assign Y= QD | QB;
divide_by_2 inst0(Clk,reset,(~QA & ~QC),QA);
divide_by_2 inst1(Clk,reset,((QA & ~QB)|(~QA &
QB)),QB);
divide_by_2 inst2(Clk,reset,(QA & QB),QC);
divide_by_2_Inverse inst3(Clk,reset,QB,QD);
endmodule
module divide_by_10(Clk_in, Clk_out, reset);
input Clk_in, reset;
output Clk_out;
divide_by_2 inst0(Clk_in,reset, Clk_in, Q);
divide_by_5 inst1(~Q,reset,QA,QB,QC,QD,QA,QB,QC,QD,Y);
assign Clk_out= Y;
endmodule
module decimal_counter(OVERFLOW, CLK, RST,A);
input CLK,RST;
output OVERFLOW;
output [3:0] A;
reg OVERFLOW_reg;
reg[3:0]A_reg;
assign OVERFLOW = OVERFLOW_reg;
assign A = A_reg;
always @ (posedge CLK or negedge RST)
//asynchronous reset condition takes priority check
for that event first
if (RST == 1'd0) begin
OVERFLOW_reg <= 1'b0;
A_reg <= 4'b0000;
end
else if (A_reg < 4'd9)
begin
// as long as A is less than 9, add
1 to A
A_reg <=
A_reg + 1'b1;
// do not trigger overflow because
count A is still a single digit
OVERFLOW_reg
<= 1'b0;
end
else
begin
// Count A is double digit 10 here,
reset count to 0
// trigger overflow for the digit 1
that should be carried output
A_reg <=
4'b0000;
OVERFLOW_reg
<= 1'b1;
end
endmodule
module TopLevel(CLOCK_50, KEY, LEDR, HEX0, HEX1, HEX2);
input wire CLOCK_50;
input wire [2:0]KEY;
output wire [5:0]LEDR;
output wire [6:0]HEX0;
reg [6:0]rHEX0;
reg [6:0]rHEX1;
reg [6:0]rHEX2;
assign HEX0 = rHEX0;
assign HEX1= rHEX1;
assign HEX2= rHEX2;
/* (OVERFLOW, CLK, RST,A)*/
decimal_counter
inst0(HEX2,CLOCK_50,KEY[1],HEX0);
divide_by_5
inst1(Clk,KEY[1],A,DB,DC,DD,QA,QB,QC,QD,HEX1);
decimal_counter
inst2(HEX1,CLOCK_50,KEY[1],HEX2);
always @(HEX0,HEX1)
begin
case (A)
1'b0: rHEX0 = 7'h40;
1'b1: rHEX0 = 7'h79;
1'b2: rHEX0 = 7'h24;
1'b3: rHEX0 = 7'h30;
1'b4: rHEX0 = 7'h19;
1'b5: rHEX0 = 7'h12;
1'b6: rHEX0 = 7'h02;
1'b7: rHEX0 = 7'h78;
1'b8: rHEX0 = 7'h00;
1'b9: rHEX0 = 7'h18;
endcase
end
always @ (HEX2)
begin
case (A)
1'b0: rHEX2 = 7'h40;
1'b1: rHEX2 = 7'h79;
1'b2: rHEX2 = 7'h24;
1'b3: rHEX2 = 7'h30;
1'b4: rHEX2 = 7'h19;
1'b5: rHEX2 = 7'h12;
endcase
end
endmodule