FSM Security

저번에 포스팅한 FSM을 이용한 Security를 만드는 Verilog code를 만들어 보겠습니다.

2개의 블럭을 만들어 연결하는 방식으로 Hardware를 구성해 보겠습니다.


my_fsm_sec

`timescale 1ns / 1ps

module my_fsm_sec #(parameter CLK_FREQ = 125_000_000)                   // parameter로 CLK_FREQ 지정
(
    input RST,
    input CLK,
    input [1:0] KEYPAD,
    input SENSOR,
    output reg [1:0] FSM_state,
    output reg Alarm_sys
 );
   localparam [1:0] disarmed = 2'b00,                                // Local Parameter로 4개의 상태 지정
                                     armed = 2'b01,
                                     wait_delay = 2'b10,
                                     alarm = 2'b11;
                                     
reg [1:0] curr_state, next_state;                                         // 현재상태, 다음 상태 저장용 Register
wire    cnt_done;                                                               //  count 끝나는 곳  wire 지정
reg     start_cnt;                                                                 //  count 시작하는 곳 Register
reg [29:0] cnt;                                                                   //  count Resister 2^30 (1_073_741_824)

always @ (posedge CLK)                                                          // CLK Risign Edge 마다
begin
        if(RST)                                                                            // RST == 1이면 
                curr_state <= disarmed;                                         // 현재 상태는 disarmed
         else                                                                              //  아니면 
                curr_state <= next_state;                                       // 현재 상태는 다음상태 받기
end

always @ (curr_state, KEYPAD, SENSOR, cnt_done)             //  curr_state, KEYPAD, SENSOR, cnt_done 이 변할 때 마다
begin
        start_cnt = 1'b0;                                                          // start_cnt = 0
        Alarm_sys  = 1'b0;                                                      // Alarm_sys = 0
        
        case  (curr_state)                                                         // curr_state case 
                disarmed : begin                                                 // disarmed
                        if(KEYPAD == 2'b11)                                 // KEYPAD가 4면 (2개 다 올라가면)
                                next_state = armed;                           // next_state는 armed
                        else                                                            // 아니면
                        next_state = disarmed;                              // next_state 는 disarmed
                        FSM_state = 2'b00;                                   // FSM_state 는 0
                        end
               armed : begin                                                    // armed
                       if (SENSOR == 1'b1 )                                // SENSOR가 1이면
                                next_state =  wait_delay;                 // next_state 는 wait_delay
                        else if(KEYPAD == 2'b00)                        // 아니면서 KEYPAD가 0이면,
                                next_state = disarmed;                    // next_state는 disarmed
                        else                                                         // 아니면
                                next_state = armed;                        // next_state는 armed
                        FSM_state = 2'b01;                                 // FSM_state 는 01
                        end
                wait_delay : begin                                          // wait_delay case에선
                        start_cnt = 1'b1;                                     // start_cnt를 1로 설정
                         if(cnt_done == 1'b1)                            // cnt_done이 1이면
                                next_state = alarm;                         // next_state는 alarm
                        else if(KEYPAD == 2'b00)                        // 아니면서 KEYPAD가 0이면
                                next_state = disarmed;                  // next_state가 disarmed
                        else                                                         // 아니면
                                next_state = wait_delay;                // next_state는 wait_delay
                                FSM_state = 2'b10;                        // FSM_state는 2'b10
                        end
                 alarm : begin                                                  // alarm case 에선
                        Alarm_sys = 1'b1;                                   // Alarm_sys 는 1
                        if(KEYPAD == 2'b00)                             // KEYPAD가 0라면
                                next_state = disarmed;                   // next_state는 disarmed
                        else                                                        // 아니면
                                next_state = alarm;                        // next_state는 alarm
                                FSM_state = 2'b11;                       // FSM_state는 2'b11
                                start_cnt = 1'b1;                           // start_cnt는 1
       
                        end
                        default : next_state = disarmed;            // default로 next_state는 disarmed
                endcase
end

always @ (posedge CLK)          // CLK risign edge 마다
begin
        if(RST)                         // RST == 1이면
        cnt <= 30'd0;                   // cnt에 30bit decimal 0
        else if (start_cnt)             // 아니면서 start_cnt == 1이면
        cnt = cnt+1;                    // cnt는 cnt + 1
        else                                 // 아니면
        cnt <= 30'd0;                 // cnt에 30bit decimal 0
end

assign cnt_done = cnt == (CLK_FREQ*5-1);
                                     
 endmodule

my_sec

`timescale 1ns / 1ps

module my_sec(
        input [1:0] SW,
        output CA,
        output reg [6:0] AN
    );
    
    assign CA = 1'b0;
    
    always @ (SW)
    begin
        case (SW)
                2'b00 : AN = 7'h7e;
                2'b01 : AN = 7'h30;
                2'b10 : AN = 7'h6d;
                2'b11 : AN = 7'h79;
                default : AN = 8'h00;
         endcase
         end
endmodule

my_security_tab

`timescale 1ns / 1ps

module my_security_tab(
        input RST,
        input CLK,
        input [1:0] KEY,
        input SENSOR,
        output ALARM_SIREN,
        output CA,
        output [6:0] AN,
        output VCC
    );
    
wire [1:0] fsm_state;

assign VCC = 1'b1;

my_fsm_sec u0( .RST(RST),       .CLK(CLK),      .KEYPAD(KEY),   .SENSOR(SENSOR),
                                .Alarm_sys(ALARM_SIREN),        .FSM_state(fsm_state));
                                
my_sec u1(      .SW(fsm_state),        .CA(CA),        .AN(AN));
endmodule

위처럼 코드를 구성후 my_security_tab으로 묶어줍니다.

my_security_tab Schematic
my_fsm_sec Schematic

my_fsm_sec 확대 모습입니다.

my_sec Schematic

my_sec 확대모습입니다.

I/O Port

I/O Port 구성 모음입니다.

대상 FPGA는 DIGILENT의 CORA Z7을 사용하였습니다.

'Circuit Design > 🔥HDL' 카테고리의 다른 글

[Verilog] 8. Uart  (0) 2024.05.27
[Verilog] 7. 교통신호기 FSM  (0) 2024.04.29
[Verilog] 5. FSM Demo.  (1) 2024.04.26
[Verilog] 4. 1 Sec Counter- (Cora-z7)  (0) 2024.04.01
[Verilog] 3. Counter / Testbench- (Cora-z7)  (0) 2024.04.01