Linux
Vivado
Verilog
Basys3
// Underground Parking Management, Disaster Response
module uparking_top (
input clk, reset_p,
input water, flame, ball, photo, sound, gas, motion, // Sensor 측정값 수신
inout dht11_data,
output reg buzzer, fan, led_r, // LED, Buzzer 출력, Motor 구동
output servo,
output reg [2:0] led_g,
output [3:0] stepper,
output sda, scl, // LCD I2C 통신
output [6:0] seg_7,
output dp,
output [3:0] com,
output [15:0] led // for Debugging
);
localparam NORMAL = 8'b0000_0001; // 평상
localparam D_FLOOD = 8'b0000_0010; // 침수
localparam D_FIRE = 8'b0000_0100; // 화재
localparam D_QUAKE = 8'b0000_1000; // 지진
localparam D_HIGH_TEMP = 8'b0001_0000; // 폭염
localparam D_BLACKOUT = 8'b0010_0000; // 암전
localparam D_LOUD_NOISE = 8'b0100_0000; // 굉음
localparam D_GAS = 8'b1000_0000; // 가스 누출
localparam PEACE = 3'b001; // 평상
localparam WARNING = 3'b010; // 경고
localparam DANGER = 3'b100; // 위험
// 온습도 측정 Module Instance
wire [7:0] humidity, temperature; // 온습도 측정값 저장
dht11_cntr dht (clk, reset_p, dht11_data, humidity, temperature);
// 온습도 측정값 BCD Format 변환 Module Instance
wire [7:0] humi_bcd, temp_bcd; // 온습도 BCD 저장
bin_to_dec bcd_humi (.bin(humidity), .bcd(humi_bcd));
bin_to_dec bcd_tmpr (.bin(temperature), .bcd(temp_bcd));
// Stepper Motor, Servo Motor 구동 Module Instance
reg start_stepper, start_servo, mode_servo; // Stepper, Servo Start-bit
stepper_cntr cntr_st (clk, reset_p, start_stepper, 1'b0, stepper);
servo_cntr cntr_sr (clk, reset_p, mode_servo, start_servo, servo);
// LCD 문자열 출력 Module Instance
reg lcd_start, lcd_row; // LCD Start-bit, 출력 위치(열 0~1)
reg [8*16-1:0] lcd_txt; // 출력 문자열 전달 변수, 16문자
reg [8*16-1:0] lcd_line1, lcd_line2; // 1, 2열 출력 문자열
wire lcd_init_flag, busy; // LCD 초기화g, 통신중 Flag
i2c_lcd_string string_lcd (clk, reset_p, lcd_start, lcd_row, lcd_txt,
scl, sda, lcd_init_flag, busy);
wire ball_pedge, ball_nedge; // Ball Switch 측정값 Edge 감지
edge_detector_pos ball_edge (clk, reset_p, ball, ball_pedge, ball_nedge);
wire sound_pedge, sound_nedge; // Sound Sensor 측정값 Edge 감지
btn_cntr sound_edge (clk, reset_p, sound, sound_pedge, sound_nedge);
wire clk_pedge, clk_nedge; // Clock Count Edge 감지
edge_detector_pos clk_edge (clk, reset_p, cnt_clk_led[24], clk_pedge, clk_nedge);
// Red, Green LED 출력용 PWM 설정
wire [1:0] led_r_pwm; // 0 Warning, 1 Danger
wire [3:0] led_g_pwm; // 0 Warning, 1~3 Danger
pwm_Nstep #(.duty_step_N(128)) pwm_led_r0 (clk, reset_p, cnt_clk_led[27:21], led_r_pwm[0]);
pwm_Nstep #(.duty_step_N(128)) pwm_led_r1 (clk, reset_p, cnt_clk_led[25:19], led_r_pwm[1]);
pwm_Nstep #(.duty_step_N(128)) pwm_led_g0 (clk, reset_p, cnt_clk_led[27:23], led_g_pwm[0]);
pwm_Nstep #(.duty_step_N(128)) pwm_led_g1 (clk, reset_p, cnt_clk_led[26:20], led_g_pwm[1]);
pwm_Nstep #(.duty_step_N(128)) pwm_led_g2 (clk, reset_p, cnt_clk_led[26:22], led_g_pwm[2]);
pwm_Nstep #(.duty_step_N(128)) pwm_led_g3 (clk, reset_p, cnt_clk_led[26:24], led_g_pwm[3]);
// State 변경부
reg [7:0] state, next_state; // 현재와 다음 상황
reg [2:0] d_grade; // 상황 등급, 평상 → 경고 → 위험
always @(negedge clk, posedge reset_p) begin
if (reset_p) state = NORMAL;
else state = next_state;
end
// LCD 출력 for Debugging
assign led [7:0] = state;
assign led [10:8] = d_grade;
assign led [11] = lcd_init_flag;
assign led [12] = lcd_toggle;
// System Clock Counter
reg [31:0] cnt_sysclk, cnt_clk_led; // 상황 시간 계산용, LED PWM 설정용
reg cnt_sysclk_e; // System Clock Counter Enable 변수
reg lcd_toggle;
always @(posedge clk, posedge reset_p) begin
if (reset_p) begin
cnt_sysclk <= 0;
cnt_clk_led <= 0;
end
else begin
cnt_clk_led <= cnt_clk_led + 1;
lcd_toggle <= cnt_clk_led[25];
if (cnt_sysclk_e) cnt_sysclk <= cnt_sysclk + 1; // Enable 상태에서만 Count
else cnt_sysclk <= 0;
end
end
// LCD 주기적 출력 갱신
always @(posedge clk, posedge reset_p) begin
if (reset_p) begin
lcd_start <= 0;
lcd_row <= 0;
lcd_txt <= 0;
end
else begin
if (lcd_init_flag) begin // 초기화 완료 상황에서만 출력
if (lcd_start) begin
lcd_start <= 0; // LCD Start-bit Reset
lcd_row <= ~lcd_row; // 출력 줄 변경
end
else if (clk_pedge) begin
if (lcd_row) lcd_txt <= lcd_line1;
else lcd_txt <= lcd_line2;
lcd_start <= 1; // LCD Start-bit 전송
end
end
end
end