7/19 알람

정유석·2024년 7월 19일

교육 - 베릴로그

목록 보기
12/28

알람 만들기

알람에 필요한 카운터 생성

loadable_down_counter_bcd_60 추가

module loadable_down_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 == 0)begin
                    bcd1 = 9;
                    if(bcd10 == 0)bcd10 = 5;
                    else bcd10 = bcd10 - 1;
                end
                else bcd1 = bcd1 - 1;
            end
        end
    end
endmodule

알람에 필요한 코드 생성

cook_timer_top

module cook_timer_top(
    input clk, reset_p,
    input [3:0] btn,
    output [3:0] com,
    output [7:0] seg_7,
    output led_alarm, led_start);
    
    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[3]), .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));

    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));
        
    loadable_down_counter_bcd_60 cur_min(
        .clk(clk), .reset_p(reset_p), .clk_time(clk_min),
        .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 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

알람 만들기 수정-보완

초에서 다운 카운트를 완료해도 싱크가 맞지 않아 분이 바뀌지 않는것을 수정-다운카운트하는 시간과 시스템 클락으로 카운트하던 시간이 맞지 않음-다운 카운트 모듈에서 나오는 펄스 클락을 사용

60진 다운카운터 모듈

module loadable_down_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,
    output reg dec_clk);
    
    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;
            dec_clk = 0;
        end
        else begin 
            if(load_enable)begin
                bcd1 = load_bcd1;
                bcd10 = load_bcd10;
            end
            else if(clk_time_nedge)begin
                if(bcd1 == 0)begin  //십의자리5, 일의자리9가 됬을때 클락1 생성
                    bcd1 = 9;
                    if(bcd10 == 0)begin
                        bcd10 = 5;
                        dec_clk = 1;
                    end
                    else bcd10 = bcd10 - 1;
                end
                else bcd1 = bcd1 - 1;
            end
            else dec_clk = 0;   //one cycle pulse 가능, clk_time_nedge와 clk_time_nedge사이에
        end
    end
endmodule

코드

module cook_timer_top(
    input clk, reset_p,
    input [3:0] btn,
    output [3:0] com,
    output [7:0] seg_7,
    output led_alarm, led_start);
    
    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[3]), .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 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

부저사용

xdc

##Pmod Header JA
set_property -dict { PACKAGE_PIN J1   IOSTANDARD LVCMOS33 } [get_ports {buzz}];#Sch name = JA1
#set_property -dict { PACKAGE_PIN L2   IOSTANDARD LVCMOS33 } [get_ports {JA[1]}];#Sch name = JA2
#set_property -dict { PACKAGE_PIN J2   IOSTANDARD LVCMOS33 } [get_ports {JA[2]}];#Sch name = JA3
#set_property -dict { PACKAGE_PIN G2   IOSTANDARD LVCMOS33 } [get_ports {JA[3]}];#Sch name = JA4
#set_property -dict { PACKAGE_PIN H1   IOSTANDARD LVCMOS33 } [get_ports {JA[4]}];#Sch name = JA7
#set_property -dict { PACKAGE_PIN K2   IOSTANDARD LVCMOS33 } [get_ports {JA[5]}];#Sch name = JA8
#set_property -dict { PACKAGE_PIN H2   IOSTANDARD LVCMOS33 } [get_ports {JA[6]}];#Sch name = JA9
#set_property -dict { PACKAGE_PIN G3   IOSTANDARD LVCMOS33 } [get_ports {JA[7]}];#Sch name = JA10

코드

module cook_timer_top(
    input clk, reset_p,
    input [3:0] btn,
    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[3]), .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

profile
개인 기록공간

0개의 댓글