A digital clock has six 7segment LEDs to display the seconds
A digital clock has six 7-segment LEDs to display the seconds, minutes, and hours as in figure 2. The hours range is 0-23; the seconds and minutes ranges are 0-59. A RESET button provides facilities to reset all readings to zero. The design is allowed to use only one 7-segment decoder (7447). Therefore, a multiplexing scheme is required to share this single decoder with all six 7-segment LEDs.
Solution
module aclk_areg( clk,reset,load_new_a,
new_alarm_ms_hr,new_alarm_ms_min,
new_alarm_ls_hr,new_alarm_ls_min,
alarm_time_ms_hr,alarm_time_ms_min,
alarm_time_ls_hr,alarm_time_ls_min);
input clk,reset,load_new_a;
input [3:0] new_alarm_ms_hr,new_alarm_ms_min,
new_alarm_ls_hr,new_alarm_ls_min;
output reg [3:0] alarm_time_ms_hr,alarm_time_ms_min,
alarm_time_ls_hr,alarm_time_ls_min;
always@(posedge clk or posedge reset)
begin
if(reset)
begin
alarm_time_ms_hr<=0;
alarm_time_ms_min<=0;
alarm_time_ls_hr<=0;
alarm_time_ls_min<=0;
end
else if(load_new_a)
begin
if(({new_alarm_ms_hr,new_alarm_ls_hr}>23) || ((new_alarm_ms_min)>5))
begin
alarm_time_ms_hr<=alarm_time_ms_hr;
alarm_time_ms_min<=alarm_time_ms_min;
alarm_time_ls_hr<=alarm_time_ls_hr;
alarm_time_ls_min<=alarm_time_ls_min;
end
else
begin
alarm_time_ms_hr<=new_alarm_ms_hr;
alarm_time_ms_min<=new_alarm_ms_min;
alarm_time_ls_hr<=new_alarm_ls_hr;
alarm_time_ls_min<=new_alarm_ls_min;
end
end
else
begin
alarm_time_ms_hr<=alarm_time_ms_hr;
alarm_time_ms_min<=alarm_time_ms_min;
alarm_time_ls_hr<=alarm_time_ls_hr;
alarm_time_ls_min<=alarm_time_ls_min;
end
end
endmodule
module aclk_controller( clk,reset,one_second,
alarm_button,time_button,key,
reset_count,load_new_c,
show_new_time,show_a,
load_new_a,shift);
input clk,reset,one_second,alarm_button,time_button;
input [3:0] key;
output reset_count,
load_new_c,
show_new_time,
show_a,
load_new_a,
shift;
parameter SHOW_TIME = 3\'b000,
KEY_STORED = 3\'b001,
KEY_WAITED = 3\'b010,
KEY_ENTRY = 3\'b011,
SET_ALARM_TIME = 3\'b100,
SET_CURRENT_TIME= 3\'b101,
SHOW_ALARM = 3\'b110;
reg [2:0] state, next;
reg [3:0] time_out;
always@(posedge clk)
begin
if(state==KEY_STORED)
time_out<=10;
else if((state==KEY_WAITED)&&(key==10))
time_out<=10;
else if(one_second)
time_out<=time_out-1;
end
always@(posedge clk or posedge reset)
begin
if(reset)
state <= SHOW_TIME;
else
state <= next;
end
always@(state or one_second or alarm_button or time_button or key or time_out)
begin
next= SHOW_TIME;
case(state)
SHOW_TIME : begin
next=SHOW_TIME;
if(alarm_button)
next=SHOW_ALARM;
else if(key != 10)
next=KEY_STORED;
end
KEY_STORED : begin
next=KEY_WAITED;
end
KEY_WAITED : begin
next=KEY_WAITED;
if(key == 10)
next=KEY_ENTRY;
else if(time_out == 0)
next=SHOW_TIME;
end
KEY_ENTRY : begin
next=KEY_ENTRY;
if(key != 10)
next=KEY_STORED;
else if(time_out == 0)
next=SHOW_TIME;
else if(alarm_button)
next=SET_ALARM_TIME;
else if(time_button)
next=SET_CURRENT_TIME;
end
SET_ALARM_TIME : begin
next=SHOW_TIME;
end
SET_CURRENT_TIME: begin
next=SHOW_TIME;
end
SHOW_ALARM : begin
next=SHOW_ALARM;
if(~alarm_button)
next=SHOW_TIME;
end
endcase
end
assign reset_count = (state==SET_CURRENT_TIME);
assign load_new_c = (state==SET_CURRENT_TIME);
assign show_new_time = ((state==KEY_STORED)||(state==KEY_ENTRY)||(state==KEY_WAITED));
assign show_a = (state==SHOW_ALARM);
assign load_new_a = (state==SET_ALARM_TIME);
assign shift = (state==KEY_STORED);
endmodule
module aclk_counter(clk,reset,one_minute,load_new_c,
new_current_time_ms_hr,
new_current_time_ms_min,
new_current_time_ls_hr,
new_current_time_ls_min,
current_time_ms_hr,
current_time_ms_min,
current_time_ls_hr,
current_time_ls_min);
input clk,reset,one_minute,load_new_c;
input[3:0] new_current_time_ms_hr,
new_current_time_ls_hr,
new_current_time_ms_min,
new_current_time_ls_min;
output reg[3:0] current_time_ms_hr,
current_time_ls_hr,
current_time_ms_min,
current_time_ls_min;
always@(posedge clk or posedge reset)
begin
if (reset)
begin
current_time_ms_hr <= 4\'d0;
current_time_ms_min <= 4\'d0;
current_time_ls_hr <= 4\'d0;
current_time_ls_min <= 4\'d0;
end
else if(load_new_c)
begin
current_time_ms_hr <= new_current_time_ms_hr;
current_time_ms_min <= new_current_time_ms_min;
current_time_ls_hr <= new_current_time_ls_hr;
current_time_ls_min <= new_current_time_ls_min;
if(new_current_time_ms_min > 4\'d5)
current_time_ms_min<= 4\'d5;
if({new_current_time_ms_hr,new_current_time_ls_hr} > 8\'h23)
{current_time_ms_hr,current_time_ls_hr} <= 8\'h23;
end
else if(one_minute)
begin
if(current_time_ls_min==4\'d9)
begin
if(current_time_ms_min==4\'d5)
begin
if(current_time_ls_hr==4\'d9)
begin
current_time_ls_min<=0;
current_time_ms_min<=0;
current_time_ls_hr<=0;
current_time_ms_hr<=current_time_ms_hr+4\'d1;
end
else if({current_time_ms_hr,current_time_ls_hr} == 8\'h23)
begin
current_time_ls_min<=0;
current_time_ms_min<=0;
{current_time_ms_hr,current_time_ls_hr}<=8\'h0;
end
else
begin
current_time_ls_min<=0;
current_time_ms_min<=0;
current_time_ls_hr<=current_time_ls_hr+1;
current_time_ms_hr<=current_time_ms_hr;
end
end
else
begin
current_time_ls_min<=0;
current_time_ms_min<=current_time_ms_min+1;
current_time_ls_hr<=current_time_ls_hr;
current_time_ms_hr<=current_time_ms_hr;
end
end
else
begin
current_time_ls_min<=current_time_ls_min+1;
current_time_ms_min<=current_time_ms_min;
current_time_ls_hr<=current_time_ls_hr;
current_time_ms_hr<=current_time_ms_hr;
end
end
else
begin
current_time_ms_hr <= current_time_ms_hr;
current_time_ms_min <= current_time_ms_min;
current_time_ls_hr <= current_time_ls_hr;
current_time_ls_min <= current_time_ls_min;
end
end
endmodule
module aclk_keyreg( clk,reset,shift,
key,
key_buffer_ms_hr,
key_buffer_ls_hr,
key_buffer_ms_min,
key_buffer_ls_min);
input clk,reset,shift;
input[3:0] key;
output reg [3:0] key_buffer_ms_hr,
key_buffer_ls_hr,
key_buffer_ms_min,
key_buffer_ls_min;
always@(posedge clk or posedge reset)
begin
if(reset)
begin
key_buffer_ms_hr <=0;
key_buffer_ls_hr <=0;
key_buffer_ms_min <=0;
key_buffer_ls_min <=0;
end
else if(shift)
begin
key_buffer_ms_hr <=key_buffer_ls_hr;
key_buffer_ls_hr <=key_buffer_ms_min;
key_buffer_ms_min <=key_buffer_ls_min;
key_buffer_ls_min <=key;
end
else
begin
key_buffer_ms_hr <=key_buffer_ms_hr;
key_buffer_ls_hr <=key_buffer_ls_hr;
key_buffer_ms_min <=key_buffer_ms_min;
key_buffer_ls_min <=key_buffer_ls_min;
end
end
endmodule
module aclk_lcd_display(show_a,show_new_time,
key_ls_min,key_ls_hr,
key_ms_min,key_ms_hr,
alarm_time_ls_min,alarm_time_ls_hr,
alarm_time_ms_min,alarm_time_ms_hr,
current_time_ls_min,current_time_ls_hr,
current_time_ms_min,current_time_ms_hr,
sound_alarm,
display_ms_hr,display_ms_min,
display_ls_hr,display_ls_min);
input show_a,show_new_time;
input [3:0] key_ls_min,key_ls_hr,
key_ms_min,key_ms_hr,
alarm_time_ls_min,alarm_time_ls_hr,
alarm_time_ms_min,alarm_time_ms_hr,
current_time_ls_min,current_time_ls_hr,
current_time_ms_min,current_time_ms_hr;
output reg sound_alarm;
output[7:0] display_ms_hr,display_ms_min,
display_ls_hr,display_ls_min;
wire [3:0] sound;
//instantiation ls_min
aclk_lcd_driver LCD1( show_a,show_new_time,
alarm_time_ls_min,
current_time_ls_min,
key_ls_min,
sound[0],
display_ls_min);
//instantiation ls_hr
aclk_lcd_driver LCD2( show_a,show_new_time,
alarm_time_ls_hr,
current_time_ls_hr,
key_ls_hr,
sound[1],
display_ls_hr);
//instantiation ms_min
aclk_lcd_driver LCD3( show_a,show_new_time,
alarm_time_ms_min,
current_time_ms_min,
key_ms_min,
sound[2],
display_ms_min);
//instantiation ms_hr
aclk_lcd_driver LCD4( show_a,show_new_time,
alarm_time_ms_hr,
current_time_ms_hr,
key_ms_hr,
sound[3],
display_ms_hr);
//sound alarm
always@(*)
begin
if(sound==4\'b1111)
sound_alarm<= 1;
else sound_alarm<=0;
end
endmodule
module aclk_lcd_driver(show_a,show_new_time,alarm_time,current_time,key,sound_alarm,display_time);
input show_a,show_new_time;
input [3:0] alarm_time,current_time,key;
output reg sound_alarm;
output reg [7:0] display_time;
always@(*)
begin
sound_alarm<=0;
display_time<={4\'h3,current_time};
// for funtionality of display time
if((show_a==1)&&(show_new_time==0))
display_time<={4\'h3,alarm_time};
if((show_a==0)&&(show_new_time==0))
display_time<={4\'h3,current_time};
if((show_a==0)&&(show_new_time==1))
display_time<={4\'h3,key};
// logic for alarm
if(current_time==alarm_time)
sound_alarm<=1;
end
endmodule
module aclk_timegen(clk,reset,reset_count,stop_watch,one_minute,one_second);
input clk,reset,reset_count,stop_watch;
output reg one_minute,one_second;
reg [7:0] c8;
reg [5:0] c6;
always@(posedge clk or posedge reset)
begin
if(reset)
begin
c6<=0;
c8<=0;
one_minute<=0;
one_second<=0;
end
else if(reset_count)
begin
c6<=0;
c8<=0;
one_minute<=0;
one_second<=0;
end
else if ((c6==6\'b111011) && (c8==8\'b11111111))
begin
c6<=0;
c8<=0;
one_minute<=1;
one_second<=1;
end
else if(c8==8\'b11111111)
begin
c8<=c8+1;
c6<=c6+1;
if(stop_watch)
begin
one_second<=1;
one_minute<=1;
end
else
begin
one_second<=1;
one_minute<=0;
end
end
else
begin
c8<=c8+1;
c6<=c6;
one_second<=0;
one_minute<=0;
end
end
endmodule
module alarm_clk_rtl (clk,stop_watch,reset,alarm_button,
time_button,key,sound_alarm,
display_ms_hr,display_ls_hr,
display_ms_min,display_ls_min);
input clk,reset,stop_watch,alarm_button,time_button;
output sound_alarm;
input [3:0] key;
output [7:0] display_ms_hr,display_ls_hr,
display_ms_min,display_ls_min;
wire one_minute, one_second, reset_count,load_new_c,show_new_time,show_a,load_new_a,shift;
wire[3:0] key_buffer_ms_hr,
key_buffer_ls_hr,
key_buffer_ms_min,
key_buffer_ls_min,
current_time_ms_hr,
current_time_ls_hr,
current_time_ms_min,
current_time_ls_min,
alarm_time_ms_hr,
alarm_time_ls_hr,
alarm_time_ms_min,
alarm_time_ls_min;
aclk_timegen ATIME( .clk(clk),
.stop_watch(stop_watch),
.reset(reset),
.one_minute(one_minute),
.one_second(one_second),
.reset_count(reset_count));
aclk_controller ACONTROL( .clk(clk),
.reset(reset),
.alarm_button(alarm_button),
.one_second(one_second),
.time_button(time_button),
.key(key),
.load_new_c(load_new_c),
.show_new_time(show_new_time),
.show_a(show_a),
.load_new_a(load_new_a),
.shift(shift),
.reset_count(reset_count));
aclk_keyreg AKEY( .clk(clk),
.reset(reset),
.key(key),
.shift(shift),
.key_buffer_ms_hr(key_buffer_ms_hr),
.key_buffer_ls_hr(key_buffer_ls_hr),
.key_buffer_ms_min(key_buffer_ms_min),
.key_buffer_ls_min(key_buffer_ls_min));
aclk_counter ACOUNT( .one_minute(one_minute),
.new_current_time_ms_hr(key_buffer_ms_hr),
.new_current_time_ls_hr(key_buffer_ls_hr),
.new_current_time_ms_min(key_buffer_ms_min),
.new_current_time_ls_min(key_buffer_ls_min),
.current_time_ms_hr(current_time_ms_hr),
.current_time_ls_hr(current_time_ls_hr),
.current_time_ms_min(current_time_ms_min),
.current_time_ls_min(current_time_ls_min),
.clk(clk),
.reset(reset),
.load_new_c(load_new_c));
aclk_areg AREG( .clk(clk),
.reset(reset),
.load_new_a(load_new_a),
.new_alarm_ms_hr(key_buffer_ms_hr),
.new_alarm_ls_hr(key_buffer_ls_hr),
.new_alarm_ms_min(key_buffer_ms_min),
.new_alarm_ls_min(key_buffer_ls_min),
.alarm_time_ms_hr(alarm_time_ms_hr),
.alarm_time_ls_hr(alarm_time_ls_hr),
.alarm_time_ms_min(alarm_time_ms_min),
.alarm_time_ls_min(alarm_time_ls_min));
aclk_lcd_display ADISP( .show_a(show_a),
.show_new_time(show_new_time),
.current_time_ms_hr(current_time_ms_hr),
.current_time_ls_hr(current_time_ls_hr),
.current_time_ms_min(current_time_ms_min),
.current_time_ls_min(current_time_ls_min),
.alarm_time_ms_hr(alarm_time_ms_hr),
.alarm_time_ls_hr(alarm_time_ls_hr),
.alarm_time_ms_min(alarm_time_ms_min),
.alarm_time_ls_min(alarm_time_ls_min),
.key_ms_hr(key_buffer_ms_hr),
.key_ls_hr(key_buffer_ls_hr),
.key_ms_min(key_buffer_ms_min),
.key_ls_min(key_buffer_ls_min),
.display_ms_hr(display_ms_hr),
.display_ls_hr(display_ls_hr),
.display_ms_min(display_ms_min),
.display_ls_min(display_ls_min),
.sound_alarm(sound_alarm));
endmodule
Save each module separately and write test bench to test the digital clock










