

module multi_watch(
input clk, reset_p,
input [2:0] btn,
output [3:0] com,
output [7:0] seg_7);
parameter WATCH = 3'b001;
parameter STOP = 3'b010;
parameter TIMER = 3'b100;
reg [2:0] mode, next_mode;
wire btn_mode_nedge;
edge_detector_p(.clk(clk), .reset_p(reset_p),
.cp(btn[0]), .n_edge(btn_mode_nedge));
always @(negedge clk or posedge reset_p)begin
if(reset_p)begin
mode = WATCH;
end
else begin
if(btn_mode_nedge)begin
mode = next_mode;
end
end
end
reg [2:0] btn_watch, btn_stop, btn_timer;
reg [3:0] com_watch, com_stop, com_timer;
reg [7:0] seg_7_watch, seg_7_stop, seg_7_timer;
always @(negedge clk or posedge reset_p)begin
if(reset_p)begin
mode = WATCH;
end
else begin
case(mode)
WATCH:begin
btn_watch = btn;
btn_stop = 0;
btn_timer = 0;
com_watch = com;
com_stop = 0;
com_timer = 0;
seg_7_watch = seg_7;
seg_7_stop = 0;
seg_7_timer = 0;
next_mode = STOP;
end
STOP:begin
btn_watch = 0;
btn_stop = btn;
btn_timer = 0;
com_watch = 0;
com_stop = com;
com_timer = 0;
seg_7_watch = 0;
seg_7_stop = seg_7;
seg_7_timer = 0;
next_mode = TIMER;
end
TIMER:begin
btn_watch = 0;
btn_stop = 0;
btn_timer = btn;
com_watch = 0;
com_stop = 0;
com_timer = com;
seg_7_watch = 0;
seg_7_stop = 0;
seg_7_timer = seg_7;
next_mode = WATCH;
end
endcase
end
end
loadable_watch_top_prj prj_watch(.clk(clk), .reset_p(reset_p),
.btn(btn_watch), .com(com_watch), .seg_7(seg_7_watch));
stop_watch_ms_top_prj prj_stop(.clk(clk), .reset_p(reset_p),
.btn(btn_stop), .com(com_stop), .seg_7(seg_7_stop));
cook_timer_top prj_timer(.clk(clk), .reset_p(reset_p),
.btn(btn_timer), .com(com_timer), .seg_7(seg_7_timer));
wire [15:0] value;
fnd_cntr fnd (.clk(clk), .reset_p(reset_p), .value(value), .com(com), .seg_7(seg_7));
endmodule
module multi_watch(
input clk, reset_p,
input [3:0] btn,
input btn_out,
output [3:0] com,
output [7:0] seg_7,
output reg [2:0]led_debug,
output led_start_stop, led_lap,
output led_alarm, led_start_timer, buzz);
wire btn_mode_nedge;
// edge_detector_p(.clk(clk), .reset_p(reset_p),
// .cp(btn[3]), .n_edge(btn_mode_nedge));
button_cntr time_btn(.clk(clk), .reset_p(reset_p), .btn(btn[3]), .btn_nedge(btn_mode_nedge));
reg [1:0] cnt_mode;
always @(negedge clk or posedge reset_p)begin
if(reset_p)begin
cnt_mode = 1;
end
else begin
if(btn_mode_nedge)begin
cnt_mode = cnt_mode + 1;
if(cnt_mode > 3 || cnt_mode == 0)begin
cnt_mode = 1;
end
end
end
end
always @(negedge clk or posedge reset_p)begin
if(reset_p)begin
led_debug = 3'b001;
end
else if(cnt_mode == 1)begin
led_debug = 3'b001;
end
else if(cnt_mode == 2)begin
led_debug = 3'b010;
end
else if(cnt_mode == 3)begin
led_debug = 3'b100;
end
else if(cnt_mode == 4)begin
led_debug = 3'b001;
end
end
reg [3:0] btn_watch, btn_stop, btn_timer;
always @(negedge clk or posedge reset_p)begin
if(reset_p)begin
btn_watch = btn;
end
else begin
if(cnt_mode == 1)begin
btn_watch = btn;
end
else if(cnt_mode == 2)begin
btn_stop = btn;
end
else if(cnt_mode == 3)begin
btn_timer = btn;
end
end
end
wire [15:0] value, value_watch, value_stop, value_timer;
wire [3:0] com_watch, com_stop, com_timer;
wire [7:0] seg_7_watch, seg_7_stop, seg_7_timer;
assign com = (cnt_mode == 1) ? com_watch : ((cnt_mode == 2) ? com_stop : ((cnt_mode == 3) ? com_timer : 0));
assign seg_7 = (cnt_mode == 1) ? seg_7_watch : ((cnt_mode == 2) ? seg_7_stop : ((cnt_mode == 3) ? seg_7_timer : 0));
loadable_watch_top_prj watch(.clk(clk), .reset_p(reset_p), .btn(btn_watch[2:0]), .com(com_watch), .seg_7(seg_7_watch));
stop_watch_ms_top_prj stop(.clk(clk), .reset_p(reset_p), .btn(btn_stop[2:0]), .com(com_stop), .seg_7(seg_7_stop),
.led_start(led_start_stop), .led_lap(led_lap));
cook_timer_top_prj timer(.clk(clk), .reset_p(reset_p), .btn(btn_timer[2:0]), .btn_out(btn_out), .com(com_timer), .seg_7(seg_7_timer),
.led_alarm(led_alarm), .led_start(led_start_timer), .buzz(buzz));
endmodule
module loadable_watch_top_prj(
input clk, reset_p,
input [2:0] btn,
output [3:0] com,
output [7:0] seg_7);
wire btn_mode; //버튼 입력 펄스를 알기위함
wire btn_sec; //버튼 입력 펄스를 알기위함
wire btn_min; //버튼 입력 펄스를 알기위함
wire set_watch; //모드 변경 토글
wire inc_sec, inc_min;
wire clk_usec, clk_msec, clk_sec, clk_min; //분주기 인스턴스 사용
button_cntr btn0(.clk(clk), .reset_p(reset_p), .btn(btn[0]), .btn_pedge(btn_mode));
button_cntr btn1(.clk(clk), .reset_p(reset_p), .btn(btn[1]), .btn_pedge(btn_sec));
button_cntr btn2(.clk(clk), .reset_p(reset_p), .btn(btn[2]), .btn_pedge(btn_min));
/*
edge_detector_n ed_btn0(
.clk(clk), .reset_p(reset_p), .cp(btn[0]),
.p_edge(btn_mode));
edge_detector_n ed_btn1(
.clk(clk), .reset_p(reset_p), .cp(btn[1]),
.p_edge(btn_sec));
edge_detector_n ed_btn2(
.clk(clk), .reset_p(reset_p), .cp(btn[2]),
.p_edge(btn_min));
*/
T_flip_flop_p t_mode(.clk(clk), .reset_p(reset_p), .t(btn_mode), .q(set_watch)); //T플립플롭의 파워 리셋으로 q=0
wire watch_load_en, set_load_en;
edge_detector_n ed_source(
.clk(clk), .reset_p(reset_p), .cp(set_watch),
.n_edge(watch_load_en), .p_edge(set_load_en));
assign inc_sec = set_watch ? btn_sec : clk_sec; //mux사용
assign inc_min = set_watch ? btn_min : clk_min;
clock_div_100 usec_clk(.clk(clk), .reset_p(reset_p), .clk_div_100(clk_usec)); //100분주기 1us로 만듬
clock_div_1000 msec_clk(.clk(clk), .reset_p(reset_p), .clk_source(clk_usec), .clk_div_1000(clk_msec)); //1000분주기 1ms로 만듬
clock_div_1000 sec_clk(.clk(clk), .reset_p(reset_p), .clk_source(clk_msec), ./*clk_div_1000*/clk_div_1000_nedge(clk_sec)); //1000분주기 1s로 만듬
clock_div_60 min_clk(.clk(clk), .reset_p(reset_p), .clk_source(inc_sec), ./*clk_div_60*/clk_div_60_nedge(clk_min)); //60분주기 1분 만듬
//30초 이후, 0.5초이후 에 모드버튼을 눌러도 분, 초가 올라가는 현상 해결
loadable_counter_bcd_60 sec_watch(
.clk(clk), .reset_p(reset_p),
.clk_time(clk_sec),
.load_enable(watch_load_en),
.load_bcd1(set_sec1), .load_bcd10(set_sec10), //덮어쓰기 로드를 받기위한 입력
.bcd1(watch_sec1), .bcd10(watch_sec10));
loadable_counter_bcd_60 min_watch(
.clk(clk), .reset_p(reset_p),
.clk_time(clk_min),
.load_enable(watch_load_en),
.load_bcd1(set_min1), .load_bcd10(set_min10), //덮어쓰기 로드를 받기위한 입력
.bcd1(watch_min1), .bcd10(watch_min10));
loadable_counter_bcd_60 sec_set(
.clk(clk), .reset_p(reset_p),
.clk_time(btn_sec),
.load_enable(set_load_en),
.load_bcd1(watch_sec1), .load_bcd10(watch_sec10), //덮어쓰기 로드를 받기위한 입력
.bcd1(set_sec1), .bcd10(set_sec10));
loadable_counter_bcd_60 min_set(
.clk(clk), .reset_p(reset_p),
.clk_time(btn_min),
.load_enable(set_load_en),
.load_bcd1(watch_min1), .load_bcd10(watch_min10), //덮어쓰기 로드를 받기위한 입력
.bcd1(set_min1), .bcd10(set_min10));
wire [15:0] value, watch_value, set_value;
wire [3:0] watch_sec1, watch_sec10, watch_min1, watch_min10; //BCD 60진 카운터 인스턴스 사용
wire [3:0] set_sec1, set_sec10, set_min1, set_min10;
assign watch_value = {watch_min10, watch_min1, watch_sec10, watch_sec1}; //결합연산자 사용하여 FND에 표시
assign set_value = {set_min10, set_min1, set_sec10, set_sec1};
assign value = set_watch ? set_value : watch_value;
fnd_cntr fnd (.clk(clk), .reset_p(reset_p), .value(value), .com(com), .seg_7(seg_7));
endmodule
module stop_watch_ms_top_prj(
input clk, reset_p,
input [2:0] btn,
output [3:0] com,
output [7:0] seg_7,
output led_start, led_lap);
//output [15:0] led_start);
wire reset_start;
wire start_stop;
wire clk_usec, clk_msec, clk_10msec, clk_sec, clk_min;
reg lap;
wire btn_start, btn_lap, btn_clear;
wire clk_start;
assign clk_start = start_stop ? clk : 0;
clock_div_100 usec_clk(.clk(clk_start), .reset_p(reset_start), .clk_div_100(clk_usec));
clock_div_1000 msec_clk(.clk(clk_start), .reset_p(reset_start), .clk_source(clk_usec), .clk_div_1000(clk_msec));
clock_div_10 csec_clk(.clk(clk_start), .reset_p(reset_start), .clk_source(clk_msec), .clk_div_10(clk_10msec));
clock_div_1000 sec_clk(.clk(clk_start), .reset_p(reset_start), .clk_source(clk_msec), .clk_div_1000_nedge(clk_sec));
clock_div_60 min_clk(.clk(clk_start), .reset_p(reset_start), .clk_source(clk_sec), .clk_div_60_nedge(clk_min));
button_cntr btn0(.clk(clk), .reset_p(reset_p), .btn(btn[0]), .btn_pedge(btn_start));
button_cntr btn1(.clk(clk), .reset_p(reset_p), .btn(btn[1]), .btn_pedge(btn_lap));
button_cntr btn2(.clk(clk), .reset_p(reset_p), .btn(btn[2]), .btn_pedge(btn_clear));
assign reset_start = reset_p | btn_clear;
T_flip_flop_p t_start(.clk(clk), .reset_p(reset_start), .t(btn_start), .q(start_stop));
assign led_start = start_stop;
always @(posedge clk or posedge reset_p)begin
if(reset_p)lap=0;
else begin
if(btn_lap)lap=~lap;
else if(btn_clear) lap = 0;
end
end
assign led_lap = lap;
wire [3:0] min10, min1, sec1, sec10;
counter_bcd_100_clear counter_msec(.clk(clk), .reset_p(reset_p), .clk_time(clk_10msec), .clear(btn_clear), .bcd1(sec1), .bcd10(sec10));
counter_bcd_60_clear counter_sec(.clk(clk), .reset_p(reset_p), .clk_time(clk_sec), .clear(btn_clear), .bcd1(min1), .bcd10(min10));
// counter_bcd_60_clear counter_min(.clk(clk), .reset_p(reset_p), .clk_time(clk_min), .clear(btn_clear), .bcd1(min1), .bcd10(min10));
reg [15:0] lap_time;
wire [15:0] cur_time;
assign cur_time = {min10, min1, sec10, sec1};
always @(posedge clk or posedge reset_p)begin
if(reset_p)lap_time = 0;
else if(btn_lap)lap_time = cur_time;
else if(btn_clear) lap_time = 0;
end
wire [15:0] value;
assign value = lap ? lap_time : cur_time;
fnd_cntr fnd (.clk(clk), .reset_p(reset_p), .value(value), .com(com), .seg_7(seg_7));
endmodule
module cook_timer_top_prj(
input clk, reset_p,
input [2:0] btn,
input btn_out,
output [3:0] com,
output [7:0] seg_7,
output led_alarm, led_start, buzz);
wire clk_usec, clk_msec, clk_sec, clk_min;
clock_div_100 usec_clk(.clk(clk), .reset_p(reset_p), .clk_div_100(clk_usec));
clock_div_1000 msec_clk(.clk(clk), .reset_p(reset_p),
.clk_source(clk_usec), .clk_div_1000(clk_msec));
clock_div_1000 sec_clk(.clk(clk), .reset_p(reset_p),
.clk_source(clk_msec), .clk_div_1000_nedge(clk_sec));
// clock_div_60 min_clk(.clk(clk), .reset_p(reset_p),
// .clk_source(clk_sec), .clk_div_60_nedge(clk_min));
wire btn_start, btn_sec, btn_min, btn_alarm_off;
button_cntr btn0(.clk(clk), .reset_p(reset_p), .btn(btn[0]), .btn_pedge(btn_start));
button_cntr btn1(.clk(clk), .reset_p(reset_p), .btn(btn[1]), .btn_pedge(btn_sec));
button_cntr btn2(.clk(clk), .reset_p(reset_p), .btn(btn[2]), .btn_pedge(btn_min));
button_cntr btn3(.clk(clk), .reset_p(reset_p), .btn(btn_out), .btn_pedge(btn_alarm_off));
wire [3:0] set_min10, set_min1, set_sec10, set_sec1;
wire [3:0] cur_min10, cur_min1, cur_sec10, cur_sec1;
counter_bcd_60 counter_sec(.clk(clk), .reset_p(reset_p),
.clk_time(btn_sec), .bcd1(set_sec1), .bcd10(set_sec10));
counter_bcd_60 counter_min(.clk(clk), .reset_p(reset_p),
.clk_time(btn_min), .bcd1(set_min1), .bcd10(set_min10));
wire dec_clk;
loadable_down_counter_bcd_60 cur_sec(
.clk(clk), .reset_p(reset_p), .clk_time(clk_sec),
.load_enable(btn_start),
.load_bcd1(set_sec1), .load_bcd10(set_sec10),
.bcd1(cur_sec1), .bcd10(cur_sec10), .dec_clk(dec_clk));
loadable_down_counter_bcd_60 cur_min(
.clk(clk), .reset_p(reset_p), .clk_time(dec_clk),
.load_enable(btn_start),
.load_bcd1(set_min1), .load_bcd10(set_min10),
.bcd1(cur_min1), .bcd10(cur_min10));
wire [15:0] value, set_time, cur_time;
assign set_time = {set_min10, set_min1, set_sec10, set_sec1};
assign cur_time = {cur_min10, cur_min1, cur_sec10, cur_sec1};
reg start_set, alarm; //기본 T플립플롭의 틀에다가 코드 추가 always문 사용 wire->reg로 변경
always @(posedge clk or posedge reset_p)begin
if(reset_p)begin
start_set = 0;
alarm = 0;
end
else begin
if(btn_start)start_set = ~start_set;
else if(cur_time == 0 && start_set)begin
start_set = 0;
alarm = 1;
end
else if(btn_alarm_off) alarm = 0;
end
end
assign led_alarm = alarm;
assign buzz = alarm; //부저 사용
assign led_start = start_set;
assign value = start_set ? cur_time : set_time;
fnd_cntr fnd (.clk(clk), .reset_p(reset_p), .value(value), .com(com), .seg_7(seg_7));
endmodule
기존에 만들어둔 시계, 스탑워치, 타이머 모듈을 인스턴스로 넣어 버튼을 누를때마다 모드를 바꿔서 FND에 출력할 수 있도록 만들었다, 타이머의 alarm_off기능은 보드에 있는 버튼의 갯수가 모자르기 때문에 외부 버튼을을 풀다운 저항을 이용해 연결하였다