7/18 loadable 시계

정유석·2024년 7월 18일

교육 - 베릴로그

목록 보기
11/28

클락으로 카운트되는 모드와 버튼으로 카운트되는 모드 분리

loadable BCD counter

module loadable_counter_bcd_60(
    input clk, reset_p,
    input clk_time,
    input load_enable,
    input [3:0] load_bcd1, load_bcd10,  //덮어쓰기 로드를 받기위한 입력
    output reg [3:0] bcd1, bcd10);
    
    wire clk_time_nedge;
    edge_detector_n ed_clk(
        .clk(clk), .reset_p(reset_p), .cp(clk_time),
        .n_edge(clk_time_nedge));
        
    always @(posedge clk or posedge reset_p)begin
        if(reset_p)begin    //리셋 우선
            bcd1 = 0;
            bcd10 = 0;
        end
        else begin 
            if(load_enable)begin
                bcd1 = load_bcd1;
                bcd10 = load_bcd10;
            end
            else if(clk_time_nedge)begin
                if(bcd1 >= 9)begin
                    bcd1 = 0;
                    if(bcd10 >= 5)bcd10 = 0;
                    else bcd10 = bcd10 + 1;
                end
                else bcd1 = bcd1 + 1;
            end
        end
    end

endmodule

loadable 시계

module loadable_watch_top(
    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

스탑워치

xdc

# LEDs
set_property -dict { PACKAGE_PIN U16   IOSTANDARD LVCMOS33 } [get_ports {led_start}]
#set_property -dict { PACKAGE_PIN E19   IOSTANDARD LVCMOS33 } [get_ports {led[1]}]
#set_property -dict { PACKAGE_PIN U19   IOSTANDARD LVCMOS33 } [get_ports {led[2]}]
#set_property -dict { PACKAGE_PIN V19   IOSTANDARD LVCMOS33 } [get_ports {led[3]}]
#set_property -dict { PACKAGE_PIN W18   IOSTANDARD LVCMOS33 } [get_ports {led[4]}]
#set_property -dict { PACKAGE_PIN U15   IOSTANDARD LVCMOS33 } [get_ports {led[5]}]
#set_property -dict { PACKAGE_PIN U14   IOSTANDARD LVCMOS33 } [get_ports {led[6]}]
#set_property -dict { PACKAGE_PIN V14   IOSTANDARD LVCMOS33 } [get_ports {led[7]}]
#set_property -dict { PACKAGE_PIN V13   IOSTANDARD LVCMOS33 } [get_ports {led[8]}]
#set_property -dict { PACKAGE_PIN V3    IOSTANDARD LVCMOS33 } [get_ports {led[9]}]
#set_property -dict { PACKAGE_PIN W3    IOSTANDARD LVCMOS33 } [get_ports {led[10]}]
#set_property -dict { PACKAGE_PIN U3    IOSTANDARD LVCMOS33 } [get_ports {led[11]}]
#set_property -dict { PACKAGE_PIN P3    IOSTANDARD LVCMOS33 } [get_ports {led[12]}]
#set_property -dict { PACKAGE_PIN N3    IOSTANDARD LVCMOS33 } [get_ports {led[13]}]
#set_property -dict { PACKAGE_PIN P1    IOSTANDARD LVCMOS33 } [get_ports {led[14]}]
#set_property -dict { PACKAGE_PIN L1    IOSTANDARD LVCMOS33 } [get_ports {led[15]}]

stop_watch_top

module stop_watch_top(
    input clk, reset_p,
    input [2:0] btn,
    output [3:0] com,
    output [7:0] seg_7,
    output led_start);
    //output [15:0] led_start);
    
    
    wire btn_start;
    wire start_stop;   
    wire clk_usec, clk_msec, clk_sec, clk_min;
    
    wire clk_start;    
    assign clk_start = start_stop ? clk : 0;
    
    
    clock_div_100 usec_clk(.clk(clk_start), .reset_p(reset_p), .clk_div_100(clk_usec));
    clock_div_1000 msec_clk(.clk(clk_start), .reset_p(reset_p), .clk_source(clk_usec), .clk_div_1000(clk_msec));
    clock_div_1000 sec_clk(.clk(clk_start), .reset_p(reset_p), .clk_source(clk_msec), .clk_div_1000_nedge(clk_sec)); 
    clock_div_60 min_clk(.clk(clk_start), .reset_p(reset_p), .clk_source(inc_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_sec));
//    button_cntr btn2(.clk(clk), .reset_p(reset_p), .btn(btn[2]), .btn_pedge(btn_min));
    
          
    T_flip_flop_p t_start(.clk(clk), .reset_p(reset_p), .t(btn_start), .q(start_stop));
    assign led_start = start_stop;
    //assign led_start[0] = start_stop;
    //assign led_start[1] = start_stop;
    //assign led_start[2] = start_stop;
    //assign led_start[3] = start_stop; //한번에 여러개 키는법, 실제 포트에는 하나씩 넣어줘야한다. 팬아웃 주의
    
    wire [3:0] min10, min1, sec1, sec10;     
    counter_bcd_60 counter_sec(.clk(clk), .reset_p(reset_p), .clk_time(clk_sec), .bcd1(sec1), .bcd10(sec10));
    counter_bcd_60 counter_min(.clk(clk), .reset_p(reset_p), .clk_time(clk_min), .bcd1(min1), .bcd10(min10));
    
    wire [15:0] value;
    assign value = {min10, min1, sec10, sec1};
    fnd_cntr fnd (.clk(clk), .reset_p(reset_p), .value(value), .com(com), .seg_7(seg_7));
    
endmodule

lap기능 추가

xdc
led_lap 추가

# LEDs
set_property -dict { PACKAGE_PIN U16   IOSTANDARD LVCMOS33 } [get_ports {led_start}]
set_property -dict { PACKAGE_PIN E19   IOSTANDARD LVCMOS33 } [get_ports {led_lap}]
#set_property -dict { PACKAGE_PIN U19   IOSTANDARD LVCMOS33 } [get_ports {led_start[2]}]
#set_property -dict { PACKAGE_PIN V19   IOSTANDARD LVCMOS33 } [get_ports {led_start[3]}]
#set_property -dict { PACKAGE_PIN W18   IOSTANDARD LVCMOS33 } [get_ports {led_start[4]}]
#set_property -dict { PACKAGE_PIN U15   IOSTANDARD LVCMOS33 } [get_ports {led_start[5]}]
#set_property -dict { PACKAGE_PIN U14   IOSTANDARD LVCMOS33 } [get_ports {led_start[6]}]
#set_property -dict { PACKAGE_PIN V14   IOSTANDARD LVCMOS33 } [get_ports {led_start[7]}]
#set_property -dict { PACKAGE_PIN V13   IOSTANDARD LVCMOS33 } [get_ports {led_start[8]}]
#set_property -dict { PACKAGE_PIN V3    IOSTANDARD LVCMOS33 } [get_ports {led_start[9]}]
#set_property -dict { PACKAGE_PIN W3    IOSTANDARD LVCMOS33 } [get_ports {led_start[10]}]
#set_property -dict { PACKAGE_PIN U3    IOSTANDARD LVCMOS33 } [get_ports {led_start[11]}]
#set_property -dict { PACKAGE_PIN P3    IOSTANDARD LVCMOS33 } [get_ports {led_start[12]}]
#set_property -dict { PACKAGE_PIN N3    IOSTANDARD LVCMOS33 } [get_ports {led_start[13]}]
#set_property -dict { PACKAGE_PIN P1    IOSTANDARD LVCMOS33 } [get_ports {led_start[14]}]
#set_property -dict { PACKAGE_PIN L1    IOSTANDARD LVCMOS33 } [get_ports {led_start[15]}]

스탑워치 lap기능 추가

module stop_watch_top(
    input clk, reset_p,
    input [2:0] btn,
    output [3:0] com,
    output [7:0] seg_7,
    output led_start);
    //output [15:0] led_start);
    
   
    wire start_stop;   
    wire clk_usec, clk_msec, clk_sec, clk_min;
    
    wire btn_start, btn_lap;
    
    wire clk_start;    
    assign clk_start = start_stop ? clk : 0;
    
    
    clock_div_100 usec_clk(.clk(clk_start), .reset_p(reset_p), .clk_div_100(clk_usec));
    clock_div_1000 msec_clk(.clk(clk_start), .reset_p(reset_p), .clk_source(clk_usec), .clk_div_1000(clk_msec));
    clock_div_1000 sec_clk(.clk(clk_start), .reset_p(reset_p), .clk_source(clk_msec), .clk_div_1000_nedge(clk_sec)); 
    clock_div_60 min_clk(.clk(clk_start), .reset_p(reset_p), .clk_source(inc_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_min));
    
          
    T_flip_flop_p t_start(.clk(clk), .reset_p(reset_p), .t(btn_start), .q(start_stop));
    assign led_start = start_stop;
    //assign led_start[0] = start_stop;
    //assign led_start[1] = start_stop;
    //assign led_start[2] = start_stop;
    //assign led_start[3] = start_stop; //한번에 여러개 키는법, 실제 포트에는 하나씩 넣어줘야한다. 팬아웃 주의
    
    T_flip_flop_p t_lap(.clk(clk), .reset_p(reset_p), .t(btn_lap), .q(lap));
    assign led_lap = lap;
    
    wire [3:0] min10, min1, sec1, sec10;     
    counter_bcd_60 counter_sec(.clk(clk), .reset_p(reset_p), .clk_time(clk_sec), .bcd1(sec1), .bcd10(sec10));
    counter_bcd_60 counter_min(.clk(clk), .reset_p(reset_p), .clk_time(clk_min), .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;
    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

clear기능 추가

bcd-60진 카운터 모듈 생성, counter_bcd_60_clear

module counter_bcd_60_clear(
    input clk, reset_p,
    input clk_time,
    input clear, 
    output reg [3:0] bcd1, bcd10);
    
    wire clk_time_nedge;
    edge_detector_n ed_clk(
        .clk(clk), .reset_p(reset_p), .cp(clk_time),
        .n_edge(clk_time_nedge));
        
    always @(posedge clk or posedge reset_p)begin
        if(reset_p)begin
            bcd1 = 0;
            bcd10 = 0;
        end
        else begin
            if(clear)begin
                bcd1 = 0;
                bcd10 = 0;
            end
            else if(clk_time_nedge)begin
                if(bcd1 >= 9)begin
                    bcd1 = 0;
                    if(bcd10 >= 5)bcd10 = 0;
                    else bcd10 = bcd10 + 1;
                end
                else bcd1 = bcd1 + 1;
            end
        end
    end

endmodule

stop_watch_top 모듈, 클리어한뒤 다시 시간을 재면 60초가 되기전에 '분'이 증가하는 현상이 있음

module stop_watch_top(
    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 start_stop;   
    wire clk_usec, clk_msec, clk_sec, clk_min;
    
    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_p), .clk_div_100(clk_usec));
    clock_div_1000 msec_clk(.clk(clk_start), .reset_p(reset_p), .clk_source(clk_usec), .clk_div_1000(clk_msec));
    clock_div_1000 sec_clk(.clk(clk_start), .reset_p(reset_p), .clk_source(clk_msec), .clk_div_1000_nedge(clk_sec)); 
    clock_div_60 min_clk(.clk(clk_start), .reset_p(reset_p), .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));
    
    wire reset_start;
    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;
    //assign led_start[0] = start_stop;
    //assign led_start[1] = start_stop;
    //assign led_start[2] = start_stop;
    //assign led_start[3] = start_stop; //한번에 여러개 키는법, 실제 포트에는 하나씩 넣어줘야한다. 팬아웃 주의
    
    T_flip_flop_p t_lap(.clk(clk), .reset_p(reset_p), .t(btn_lap), .q(lap));
    assign led_lap = lap;
    
    wire [3:0] min10, min1, sec1, sec10;     
    counter_bcd_60_clear counter_sec(.clk(clk), .reset_p(reset_p), .clk_time(clk_sec), .clear(btn_clear), .bcd1(sec1), .bcd10(sec10));
    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

수정-60분주 인스턴스의 reset_p연결 와이어 변경

module stop_watch_top(
    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_sec, clk_min;
    
    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_p), .clk_div_100(clk_usec));
    clock_div_1000 msec_clk(.clk(clk_start), .reset_p(reset_p), .clk_source(clk_usec), .clk_div_1000(clk_msec));
    clock_div_1000 sec_clk(.clk(clk_start), .reset_p(reset_p), .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;
    //assign led_start[0] = start_stop;
    //assign led_start[1] = start_stop;
    //assign led_start[2] = start_stop;
    //assign led_start[3] = start_stop; //한번에 여러개 키는법, 실제 포트에는 하나씩 넣어줘야한다. 팬아웃 주의
    
    T_flip_flop_p t_lap(.clk(clk), .reset_p(reset_p), .t(btn_lap), .q(lap));
    assign led_lap = lap;
    
    wire [3:0] min10, min1, sec1, sec10;     
    counter_bcd_60_clear counter_sec(.clk(clk), .reset_p(reset_p), .clk_time(clk_sec), .clear(btn_clear), .bcd1(sec1), .bcd10(sec10));
    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

lap모드에서 클리어버튼을 누르면 lap모드로 남아있는게 아니라 초기화상태(시계모드)로 바뀌게 변경

module stop_watch_top(
    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_sec, clk_min;
    
    reg lap;	//always문에 사용하기 위한 reg선언
    
    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_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; //기존의 T플립플롭에서 추가(이것때문에 기존의 T플립플롭 모듈을 바꿀순 없고 실행되는 부분만 가져와서 수정
        end
    end  
    //assign led_start[0] = start_stop;
    //assign led_start[1] = start_stop;
    //assign led_start[2] = start_stop;
    //assign led_start[3] = start_stop; //한번에 여러개 키는법, 실제 포트에는 하나씩 넣어줘야한다. 팬아웃 주의
    
    wire [3:0] min10, min1, sec1, sec10;     
    counter_bcd_60_clear counter_sec(.clk(clk), .reset_p(reset_p), .clk_time(clk_sec), .clear(btn_clear), .bcd1(sec1), .bcd10(sec10));
    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; //btn_lap의 one cycle clock의 순간에 cur_time을 한번 읽어와서 lap_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 stop_watch_ms_top(
    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(.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

BCD_100진 카운터

module counter_bcd_100_clear(
    input clk, reset_p,
    input clk_time,
    input clear, 
    output reg [3:0] bcd1, bcd10);
    
    wire clk_time_nedge;
    edge_detector_n ed_clk(
        .clk(clk), .reset_p(reset_p), .cp(clk_time),
        .n_edge(clk_time_nedge));
        
    always @(posedge clk or posedge reset_p)begin
        if(reset_p)begin
            bcd1 = 0;
            bcd10 = 0;
        end
        else begin
            if(clear)begin
                bcd1 = 0;
                bcd10 = 0;
            end
            else if(clk_time_nedge)begin
                if(bcd1 >= 9)begin
                    bcd1 = 0;
                    if(bcd10 >= 9)bcd10 = 0;
                    else bcd10 = bcd10 + 1;
                end
                else bcd1 = bcd1 + 1;
            end
        end
    end

endmodule

10분주기

module clock_div_10(
    input clk, reset_p,
    input clk_source, //1ms
    output clk_div_10,
    output clk_div_10_nedge);
    
    reg [3:0] cnt_clksource;
    
    wire clk_source_nedge;
    edge_detector_n ed_source(
        .clk(clk), .reset_p(reset_p), .cp(clk_source),
        .n_edge(clk_source_nedge));
    
    always @(negedge clk or posedge reset_p)begin
        if(reset_p)cnt_clksource = 0;
        else if(clk_source_nedge)begin
                if(cnt_clksource >= 9) cnt_clksource = 0;
                else cnt_clksource = cnt_clksource + 1;
        end
    end
    
    assign clk_div_10 = (cnt_clksource < 5) ? 0 : 1;
    
    edge_detector_n ed(
        .clk(clk), .reset_p(reset_p), .cp(clk_div_10),
        .n_edge(clk_div_10_nedge));
    
endmodule
profile
개인 기록공간

0개의 댓글