10/03 지상 선제 방어 시스템

정유석·2024년 10월 3일

교육 - 베릴로그

목록 보기
27/28
module radar
(
    input clk, reset_p,
    input active_signal,
    input hc_sr04_echo,
    output hc_sr04_trig,
    output servo_radar_x, servo_radar_y,
    output reg [10:0] save_duty_x, save_duty_y,
    output reg fire_signal,
    output [3:0] com,
    output [7:0] seg_7
);

    parameter waiting      = 2'b00;
    parameter degree_1     = 2'b01;
    parameter degree_2     = 2'b10;
    parameter reset_raider = 2'b11;

    reg [31:0] clk_div;
    always @(posedge clk)clk_div = clk_div + 1;
            
    wire clk_div_nedge, active_signal_p;
    edge_detector_pn ed(.clk(clk), .reset_p(reset_p), .cp(clk_div[19]), .n_edge(clk_div_nedge));
    edge_detector_pn active(.clk(clk), .reset_p(reset_p), .cp(active_signal), .n_edge(active_signal_p));


    reg [10:0] duty_x;
    reg [10:0] duty_y;
    reg [1:0] state, next_state; 

    // distance case => input min distance, duty save
    wire [21:0] distance;
    reg [21:0] min_distance;

    // FSM raider
    always @(posedge clk or posedge reset_p) begin
            if (reset_p) begin
                state = waiting;
                duty_x = 100;
                duty_y = 124;
                save_duty_x = 100;
                save_duty_y = 124;
                min_distance = 200;
                fire_signal = 0;
            end 
            else begin
                state = next_state;
                next_state = (duty_y >= 180) ? reset_raider : next_state;  // if y_degree maximum => reset raider //220
                if(distance < min_distance)begin
                    min_distance = distance;
                    save_duty_x = duty_x;
                    save_duty_y = duty_y;
                end
                else if(clk_div_nedge)begin //ghfgdhfgh
                    case (state) 
                        waiting  : begin
                                       fire_signal = 0;
                                       next_state = (active_signal) ? degree_1 : waiting;
                                   end
                        degree_1 : begin
                                       duty_x = duty_x -1; // degree change
                                       duty_y = (duty_x <= 100) ? duty_y + 7 : duty_y; // y_degree raise //+15
                                       next_state = (duty_x <= 100) ? degree_2 : degree_1; // change direction
                                   end  
                        degree_2 : begin
                                       duty_x = duty_x +1; // degree change
                                       duty_y = (duty_x >= 220) ? duty_y + 7 : duty_y; // y_degree raise //+15
                                       next_state = (duty_x >= 220) ? degree_1 : degree_2; // change direction
                                   end  
                    reset_raider : begin
                                       duty_x = 100;
                                       duty_y = 124;
                                       next_state = waiting;
                                       save_duty_x = 100;
                                       save_duty_y = 124;
                                       min_distance = 200;
                                       fire_signal = 1;
                                   end       
                         default : next_state = waiting;
                    endcase
                end
           end
      end
      
     pwm_Nstep_freq 
        #( .duty_step(2000), .pwm_freq(50)) 
        radar_x ( .clk(clk), .reset_p(reset_p), .duty(duty_x), .pwm(servo_radar_x));
        
     pwm_Nstep_freq 
        #( .duty_step(2000), .pwm_freq(50)) 
        raider_y ( .clk(clk), .reset_p(reset_p), .duty(duty_y), .pwm(servo_radar_y));

    // 초음파 센서 모듈
    //cntr module name check
    HC_SR04_SSONIC raider_sonic(.clk(clk), .reset_p(reset_p), .ECHO(hc_sr04_echo), .TRIG(hc_sr04_trig), .DISTANCE(distance));

endmodule



//-------------------------------------------------------------------------------------------------------
//-------------------------------------------------------------------------------------------------------


module aiming_servo(
    input clk, reset_p,
    input [10:0] save_duty_x, save_duty_y,  
    input fire_signal,  
    output aiming_servo_x, aiming_servo_y,
    output reg trigger,  // don't need
    output reg led_r, led_g, led_y,
    output [2:0] led);
    
    //파라미터
    parameter idle      = 3'b000;
    parameter move_x    = 3'b001;
    parameter move_y    = 3'b010;
    parameter fire      = 3'b100;
    
    //시간조절용 100분주
    wire clk_div_100_nedge;
    clock_div_100(.clk(clk), .reset_p(reset_p), .clk_div_100_nedge(clk_div_100_nedge));
    
    //시간조절용 1000분주-1ms
    wire m_second;
    clock_div_1000(.clk(clk), .reset_p(reset_p), .clk_source(clk_div_100_nedge), .clk_div_1000_nedge(m_second));
    
    //시간조절용 1000분주-1s
    wire second;
    clock_div_1000(.clk(clk), .reset_p(reset_p), .clk_source(m_second), .clk_div_1000_nedge(second));
    
    reg [31:0] clk_div;
    always @(posedge clk)clk_div = clk_div + 1;

    wire clk_div_nedge, fire_signal_p;
    edge_detector_pn ed(.clk(clk), .reset_p(reset_p), .cp(clk_div[19]), .n_edge(clk_div_nedge));
    edge_detector_pn fire_p(.clk(clk), .reset_p(reset_p), .cp(fire_signal), .n_edge(fire_signal_p));
    
    //타이머 enable
    reg second_e;
    reg [2:0] count_s;
    always @(negedge clk or posedge reset_p)begin
        if(reset_p)begin
            count_s = 0;
        end
        else if(second && second_e)begin
            count_s = count_s + 1;
        end
        else if(!second_e)count_s = 0;
    end   

    assign led[0] = count_s;

    
    //듀티 저장
    reg [10:0] aiming_duty_x, aiming_duty_y;
   
    //상태머신
    reg [2:0] state, next_state;
    always @(negedge clk or posedge reset_p)begin
        if(reset_p)state = idle;
        else state = next_state;
    end
    
    always @(posedge clk or posedge reset_p)begin
        if(reset_p)begin
            next_state = idle;
            aiming_duty_x = 0;
            aiming_duty_y = 0;
            second_e = 0;
            led_r = 0;
            led_g = 0;
            led_y = 0;
            trigger = 0;
        end
        else begin
        
            if(fire_signal_p)begin
                next_state = fire;
            end
            
            else if(clk_div_nedge)begin
                case(state)
                    idle:begin
                        aiming_duty_x = 140;
                        aiming_duty_y = 120;
                        led_r = 0;
                        led_g = 0;
                        led_y = 0;
                        trigger = 0;
                        led_g = 1;
                        next_state = move_x;
                    end
                    
                    move_x:begin
                        led_y = 1;
                        aiming_duty_x = save_duty_x;
                        next_state = move_y;
                    end
                    
                    move_y:begin
                        aiming_duty_y = save_duty_y;
                        next_state = move_x;                        
                    end
                    
                    fire:begin
                        trigger = 1;
                        led_r = 1;
                        next_state = idle;
                    end
                    
                    default : next_state = idle;
                endcase
            end
        end
    end
    
    pwm_Nstep_freq #(.duty_step(2000),.pwm_freq(50))
            aiming_servo_x_pwm( .clk(clk), .reset_p(reset_p), .duty(aiming_duty_x), .pwm(aiming_servo_x)); //aiming_duty_x
            
    pwm_Nstep_freq #(.duty_step(2000),.pwm_freq(50))
            aiming_servo_y_pwm( .clk(clk), .reset_p(reset_p), .duty(aiming_duty_y), .pwm(aiming_servo_y)); //aiming_duty_y            

endmodule

//-------------------------------------------------------------------------------------------------------
//-------------------------------------------------------------------------------------------------------

module reloading(
    input clk, reset_p,
    input fire_signal,
    output reg active_signal,
    output reg in1, in2, in3, in4);

    parameter reloading     = 2'b00;
    parameter releasing     = 2'b01;
    parameter staying       = 2'b10;
    
    wire fire_signal_p;
    edge_detector_pn fire_p(.clk(clk), .reset_p(reset_p), .cp(fire_signal), .n_edge(fire_signal_p));

    wire clk_div_100_nedge;
    clock_div_100 (.clk(clk), .reset_p(reset_p),
    .clk_div_100_nedge(clk_div_100_nedge));
    
    //시간조절용 1000분주-1ms
    wire m_second;
    clock_div_1000 (.clk(clk), .reset_p(reset_p),
    .clk_source(clk_div_100_nedge), //1us
    .clk_div_1000_nedge(m_second));
        
    //1s
    wire second;
    clock_div_1000(.clk(clk), .reset_p(reset_p),
    .clk_source(m_second), //1us
    .clk_div_1000_nedge(second));
    

    
    reg [3:0] cnt_second;
    reg second_e;
    always @(negedge clk or posedge reset_p)begin
        if(reset_p)begin
            cnt_second = 0;
        end
        else if(second && second_e)begin
            cnt_second = cnt_second + 1;
        end
        else if(!second_e)begin
            cnt_second = 0;
        end
    end
    
    
    //half step
    wire [3:0] spin[7:0];
    assign spin[0] = 4'b1001;
    assign spin[1] = 4'b0001;
    assign spin[2] = 4'b0011;
    assign spin[3] = 4'b0010;
    assign spin[4] = 4'b0110;
    assign spin[5] = 4'b0100;
    assign spin[6] = 4'b1100;
    assign spin[7] = 4'b1000; 
    
    
    reg [2:0] cnt_spin;
    reg spin_direction;
    reg spin_e;
    
    always @(posedge clk or posedge reset_p)begin
        if(reset_p)begin
            cnt_spin = 0;
        end
        else if(m_second && spin_direction && spin_e)begin            
            if(cnt_spin >= 7)begin //7
                cnt_spin = 0;
            end
            else cnt_spin = cnt_spin + 1;
        end
        else if(m_second && !spin_direction && spin_e)begin
            if(cnt_spin <= 0 )begin
                cnt_spin = 7;
            end
            else cnt_spin = cnt_spin - 1;
        end
    end
    
    reg [1:0] state, next_state;
    always @(negedge clk or posedge reset_p)begin
        if(reset_p)begin
            state = reloading;
        end
        else begin
            state = next_state;
        end
    end
    
    always @(posedge clk or posedge reset_p)begin
        if(reset_p)begin
            next_state = reloading;
            spin_direction = 0;
            spin_e = 0;
            second_e = 0;
        end
        else begin
            case(state)
                reloading:begin
                    {in4, in3, in2, in1} = spin[cnt_spin];
                    spin_direction = 0;
                    spin_e = 1;
                    second_e = 1;
                    if(cnt_second > 8)begin  //cnt motor spin
                        spin_e = 0;
                        second_e = 0;
                        active_signal = 1;
                        next_state = releasing;
                    end
                end
                releasing:begin
//                    active_signal = 0;
                    {in4, in3, in2, in1} = spin[cnt_spin];
                    spin_direction = 1;
                    spin_e = 1;
                    second_e = 1;
                    if(cnt_second > 8)begin  //cnt motor spin
                        second_e = 0;
                        next_state = staying;
                    end
                end
                staying:begin
                    active_signal = 0;
                    if(fire_signal_p)begin
                        next_state = reloading;
                    end
                end
            endcase
        end
    end
    
endmodule

//-------------------------------------------------------------------------------------------------------
//-------------------------------------------------------------------------------------------------------

module ADS
(
    input clk, reset_p,
    input hc_sr04_echo,
    output hc_sr04_trig,
    output servo_radar_x, servo_radar_y,
    output aiming_servo_x, aiming_servo_y,
    output trigger, trigger_servo_p,
    output in1, in2, in3, in4,
    output led_r, led_g, led_y,
    output [2:0] led,
    output [3:0] com,
    output [7:0] seg_7
);

    wire [10:0] save_duty_x, save_duty_y;
    wire fire_signal;
    radar radar_ADS(.clk(clk), .reset_p(reset_p), .hc_sr04_echo(hc_sr04_echo), .hc_sr04_trig(hc_sr04_trig),
                    .servo_radar_x(servo_radar_x), .servo_radar_y(servo_radar_y), .fire_signal(fire_signal), 
                    .active_signal(active_signal), .save_duty_x(save_duty_x), .save_duty_y(save_duty_y), .com(com), .seg_7(seg_7));
    
    aiming_servo aiming(.clk(clk), .reset_p(reset_p), .save_duty_x(save_duty_x), .save_duty_y(save_duty_y), .fire_signal(fire_signal),
                        .aiming_servo_x(aiming_servo_x), .aiming_servo_y(aiming_servo_y), .trigger(trigger),
                        .led_r(led_r), .led_g(led_g), .led_y(led_y), .led(led));

    wire active_signal;
    reloading reload(.clk(clk), .reset_p(reset_p), .fire_signal(fire_signal), .active_signal(active_signal),
                     .in1(in1), .in2(in2), .in3(in3), .in4(in4));
                     
    //trigger control   
    
    reg [31:0] clk_div;
    always @(posedge clk)clk_div = clk_div + 1;
    
    wire clk_div_nedge, fire_signal_p, active_signal_p;
    edge_detector_pn ed(.clk(clk), .reset_p(reset_p), .cp(clk_div[19]), .n_edge(clk_div_nedge));
    edge_detector_pn fire_p(.clk(clk), .reset_p(reset_p), .cp(fire_signal), .n_edge(fire_signal_p));
    edge_detector_pn active(.clk(clk), .reset_p(reset_p), .cp(active_signal), .n_edge(active_signal_p));

    reg [10:0] trigger_duty;
    pwm_Nstep_freq #(.duty_step(2000),.pwm_freq(50))
            trigger_servo_x_pwm( .clk(clk), .reset_p(reset_p), .duty(trigger_duty), .pwm(trigger_servo_p));
            
    reg [1:0] state, next_state; 
    parameter fire     = 1'b0;
    parameter reloaded = 1'b1;

    always @(posedge clk or posedge reset_p) begin
        if (reset_p) begin
            state = reloaded;
            trigger_duty = 150;
        end 
        else begin
            state = next_state;
            if(clk_div_nedge)begin
                case (state) 
                
                    reloaded : begin
//                                   trigger_duty = (fire_signal_p) ? 100 : 170; // fire : 100, reloaded state : 170
//                                   next_state = (trigger_duty <= 100) ? fire : reloaded;
                                   trigger_duty = 50;
                                   if(fire_signal) next_state = fire;
                               end  
                               
                        fire : begin
//                                   trigger_duty = (active_signal) ? 170 : 100; // fire : 100, reloaded state : 170
//                                   next_state = (trigger_duty >= 170) ? reloaded : fire;
                                   trigger_duty = 150;
                                   if(active_signal) next_state = reloaded;
                               end   
                                    
                     default : next_state = reloaded;
                     
                endcase
            end
        end
    end
                     
endmodule
profile
개인 기록공간

0개의 댓글