`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// Company: 
// Engineer: 
// 
// Create Date: 2022/04/02 22:58:27
// Design Name: 
// Module Name: lab5_3
// Project Name: 
// Target Devices: 
// Tool Versions: 
// Description: 
// 
// Dependencies: 
// 
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
// 
//////////////////////////////////////////////////////////////////////////////////


module lab5_3(
    output [7:0] ssd,
    output [3:0] yes,
    output reg [15:0] light,
    input clk,
    input rst_n,
    input mode,
    input pause_resume,
    input start_stop,
    input add_min,
    input add_sec,
    input clk_ctl
    );
    wire clk_f, clk_n; reg clk_d;
    wire [3:0] set_m1, set_m0, set_s1, set_s0;
    wire [3:0] m1, m0, s1, s0; 
    reg [3:0] m1_f, m0_f, s1_f, s0_f;
    wire set_enable, count_enable, reset; reg rst;
    wire [1:0] ctl;
    wire [3:0] ssd_in;
    wire pause_press, pause, min_press, sec_press, minadd, secadd;
    reg count_enablef, done;
    
    freqdiv_ctl2 U_1HZ(
      .clk_out(clk_n),
      .ctl(ctl),
      .clk(clk),
      .rst_n(rst_n)
    );
    fast_clk U_100HZ(
      .clk_out(clk_f),
      .clk(clk),
      .rst_n(rst_n)
    );
    set_clk U_setup(
     .set_m1(set_m1),
     .set_m0(set_m0),
     .set_s1(set_s1),
     .set_s0(set_s0),
     .add_min(minadd),
     .add_sec(secadd),
     .set_enable(set_enable),
     .clk(clk),
     .rst_n(rst_n)
    );
    time_clk U_time_clk(
     .m1(m1),
     .m0(m0),
     .s1(s1),
     .s0(s0),
     .set_m1(set_m1),
     .set_m0(set_m0),
     .set_s1(set_s1),
     .set_s0(set_s0),
     .clk(clk_d),
     .rst_n(rst),
     .count_enable(count_enablef)
    );
    scan_ctl U_SC(
     .ssd_ctl(yes),
     .ssd_in(ssd_in),
     .in0(m1_f),
     .in1(m0_f),
     .in2(s1_f),
     .in3(s0_f),
     .ssd_ctl_en(ctl) 
    );
    display_n U_D(
     .i(ssd_in),
     .SSD(ssd)
    );
    one_pulse U_sec(
      .out_pulse(secadd),
      .clk(clk),
      .rst_n(rst_n),
      .in_trig(sec_press)
    );
    debounce_circuit U_secadd(
      .pb_debounced(sec_press),
      .clk(clk),
      .rst_n(rst_n),
      .pb_in(add_sec)
    );
    one_pulse U_min(
      .out_pulse(minadd),
      .clk(clk),
      .rst_n(rst_n),
      .in_trig(min_press)
    );
    debounce_circuit U_addmin(
      .pb_debounced(min_press),
      .clk(clk),
      .rst_n(rst_n),
      .pb_in(add_min)
    );
    debounce_circuit U_stop(
      .pb_debounced(pause_press),
      .clk(clk),
      .rst_n(rst_n),
      .pb_in(pause_resume)
    );
    one_pulse U_stop_one_pulse(
      .out_pulse(pause),
      .clk(clk),
      .rst_n(rst_n),
      .in_trig(pause_press)
    );
    debounce_circuit U_reset(
      .pb_debounced(reset),
      .clk(clk),
      .rst_n(rst_n),
      .pb_in(start_stop)
    );
    fsm U_fsm(
      .count_enable(count_enable),
      .set_enable(set_enable),
      .clk(clk),
      .rst_n(rst),
      .mode(mode),
      .in(pause)
    );
    always@*
        if(clk_ctl == 1) clk_d = clk_f;
        else clk_d = clk_n;
    always@*
        count_enablef = count_enable & (~done);
    always@*
        if(m1 == 4'd0 && m0 == 4'd0 && s1 == 4'd0 && s0 == 4'd0) done = 1;
        else done = 0;
    always@*
        begin
        light[15] = set_enable;
        light[14] = count_enablef;
        if(done) light[13:0] = 14'b11111111111111;
        else light[13:0] = 14'b00000000000000;
        end
    always@*
        if(mode)
            begin
            m1_f = set_m1;
            m0_f = set_m0;
            s1_f = set_s1;
            s0_f = set_s0;
            end
        else
            begin
            m1_f = m1;
            m0_f = m0;
            s1_f = s1;
            s0_f = s0;
            end
    always@*
        if(rst_n == 0 || reset == 1) rst = 0;
        else rst = 1;
endmodule
