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