본문 바로가기
하만 세미콘 아카데미/Verilog HDL

Verilog HDL 실습 (Traffic)

by smileww 2024. 5. 31.

오늘은 일상에서 흔히 볼수있는 보행자 신호등을 Verilog HDL로 구현해보도록 하겠습니다.

신호등은 다음 네 가지 주요 상태를 갖습니다: 노란색, 빨간색, 초록색, 그리고 보행자 신호 상태입니다.

  • 노란색(YELLOW) 상태는 신호 변경을 알리는 경고 신호로 잠시 지속됩니다.
  • 빨간색(RED)  상태에서는 사람이 건널 수 없고 차량이 도로를 자유롭게 진행할 수 있습니다.
  • 초록색(GREEN) 상태는 차량에 정지를 명령하고, 보행자가 도로를 건널 수 있도록 합니다.
  • 보행자(PED) 신호 상태는 보행자가 버튼을 누를 때 활성화되어, 안전하게 길을 건널 수 있도록 초록색 신호를 제공합니다.

위 조건을 가지고 보행자 신호등을 구현해보도록 하겠습니다.

 

 

Verilog HDL Traffic Module & Testbench

더보기

Traffic module

`timescale 1ns / 1ps

module my_traffic(
    input RST,       
    input CLK,        
    input PED_CROSS,
    output reg RED,
    output reg YELLOW,
    output reg GREEN,
    output reg WORK
);

parameter CLK_FREQ = 125_000_000;

localparam [1:0] //sIDLE = 3'd0,
                 sYEL = 2'd0,
                 sRED = 2'd1,
                 sGREEN = 2'd2,
                 sPED = 2'd3;

reg [1:0] curr_state, next_state;
reg start_cnt;
wire cnt_done;
reg [6:0] time_slot;
wire [6:0] curr_slot;
reg [6:0] curr_time;
reg pd_cross_1d, pd_cross_2d;
wire pd_rising;

always @(posedge CLK)
begin
    if (RST)
        curr_state <= sYEL;
    else
        curr_state <= next_state;
end

always @(RST, curr_state, cnt_done, pd_rising)
begin
    if(RST) begin
        next_state = sYEL;
        start_cnt = 1'b0;
        time_slot = 1'b0;
        RED = 1'b0;
        GREEN = 1'b0;
        YELLOW = 1'b0;
        WORK = 1'b0;
    end else begin
        RED = 1'b0;
        GREEN = 1'b0;
        YELLOW = 1'b0;
        WORK = 1'b0;
     
        case (curr_state)
           sYEL : begin
              time_slot = 10;
            if(cnt_done) begin
                next_state = sRED;
                start_cnt = 1'b0;
            end else begin
                next_state = sYEL;
                start_cnt = 1'b1;
            end
              YELLOW = 1'b1;
           end
           
            sRED : begin
              time_slot = 7'd80;
              if(cnt_done) begin
                    start_cnt = 1'b0;
                    next_state = sGREEN;
                end else if(pd_rising) begin
                   next_state = sPED;
                   start_cnt = 1'b0;
                end else begin
                    start_cnt = 1'b1;
                    next_state = sRED;
                end
                RED = 1'b1;
           end
           
           sGREEN : begin
           time_slot = 80;
              if(cnt_done) begin
                    start_cnt = 1'b0;
                    next_state = sYEL;
                end else begin
                    start_cnt = 1'b1;
                    next_state = sGREEN;
                end
                GREEN = 1'b1;
                WORK = 1'b1;
           end
           
           sPED : begin
              if(curr_time < 20) begin
                    time_slot = 20;
              end else begin
                    time_slot = 12;
              end
              if(cnt_done) begin
                    start_cnt = 1'b0;
                    next_state = sGREEN;
              end else begin
                    start_cnt = 1'b1;
                    next_state = sPED;
                end
                RED = 1'b1;
           end
           default: next_state = sYEL;
       endcase
     end
end

my_time #(.CLK_FREQ(CLK_FREQ))
    u0 (
    .RST        (RST),
    .CLK        (CLK),
    .time_slot  (time_slot),
    .start      (start_cnt),
    .curr_slot  (curr_slot),
    .cnt_done   (cnt_done)
);

always @(posedge CLK)
begin
    pd_cross_1d <= PED_CROSS;
    pd_cross_2d <= pd_cross_1d;
end

assign pd_rising = pd_cross_1d & ~pd_cross_2d;

always @(posedge CLK)
begin
    if(curr_state == sYEL)
        curr_time <= 7'd0;
    else if(pd_rising)
        curr_time <= curr_slot;
end
        

endmodule

 

my_time module

`timescale 1ns / 1ps

module my_time(
    input RST,
    input CLK,
    input [6:0] time_slot,
    input start,
    output [6:0] curr_slot,
    output cnt_done
);

parameter CLK_FREQ = 125_000_000;

wire [39:0] MAX_CNT = time_slot * CLK_FREQ / 10;
reg [29:0] cnt;

always @(posedge CLK) 
begin
    if (RST)
        cnt <= 30'd0;
    else if (start)
        cnt <= cnt + 1;
    else
        cnt <= 30'd0;
end

assign cnt_done = (cnt == MAX_CNT -1);
assign curr_slot = (cnt/CLK_FREQ) * 10;

endmodule

 

Testbench

`timescale 1ns / 1ps

module my_traffic_tb();

parameter CLK_PD = 10.0;
reg RST, CLK, PED_CROSS;
wire RED, GREEN, YELLOW, WORK;

my_traffic #(.CLK_FREQ(100))
        uut (
        .RST(RST),
        .CLK(CLK),
        .PED_CROSS(PED_CROSS),
        .RED(RED),
        .YELLOW(YELLOW),
        .GREEN(GREEN),
        .WORK(WORK)
    );
    
    initial begin
        RST = 1'b1;
        #(CLK_PD*20);
        RST = 1'b0;
    end

 
    initial CLK = 1'b0;
    always #(CLK_PD/2) CLK = ~CLK;

 
    always begin
       
        PED_CROSS = 1'b0;
        wait (RST == 1'b0);
        wait (RED == 1'b1);
        wait (RED == 1'b0);
        wait (RED == 1'b1);
        #(CLK_PD*12)
        PED_CROSS = 1'b1;
        #(CLK_PD*3);
        PED_CROSS = 1'b0;
        wait (GREEN == 1'b1);
        wait (GREEN == 1'b0);
        wait (YELLOW == 1'b1);
        wait (YELLOW == 1'b0);
        $finish;
    end

endmodule

1

신호등 시스템을 제어하는 FSM (유한 상태 기계)을 구현한 my_traffic 모듈입니다. 이 모듈은 입력 신호로 리셋(RST), 클록(CLK), 그리고 보행자 횡단 버튼(PED_CROSS)을 받으며, 출력으로는 각 신호등의 상태 (RED, YELLOW, GREEN)와 작업 신호(WORK)를 제어합니다.

 

시스템은 보행자의 요청에 반응하여 신호를 적절히 조절하며, 각 상태는 설정된 시간(time_slot) 동안 유지됩니다. 이 시간은 외부 모듈(my_time)에 의해 관리되며, 시간이 완료되면 다음 상태로 자동으로 전환됩니다.

모듈의 주요 동작

기본 신호 주기

  • 노란색(YELLOW): 경고 신호로, 다음 신호로의 전환을 준비합니다. 지속 시간은 짧습니다.
  • 빨간색(RED): 차량이 진행할 수 있도록 허용합니다.
  • 초록색(GREEN): 차량 정지를 명령하며, 보행자가 길을 건널 수 있는 기회를 제공합니다. 

 

보행자 신호 요청 (PED):

  • 보행자가 횡단 버튼을 누르면, 초록색 신호로 전환하여 보행자가 길을 건널 수 있게 합니다. 보행자 신호는 특정 시간 동안 활성화됩니다.

신호 전환 로직

  • 각 신호 상태는 특정 시간(time_slot) 동안 유지됩니다. 이 시간은 my_time 모듈을 통해 관리되며, 시간이 완료되면(cnt_done) 다음 상태로 전환됩니다.
  • 보행자 버튼이 활성화되면 (상승 에지 감지), 신호등은 빨간색 상태로 전환하여 보행자가 도로를 건널 수 있도록 합니다. 이때의 시간 동안 보행자 신호가 지속됩니다.

상태 기반 제어

  • YELLOW 상태에서는 노란색 신호만 활성화됩니다.
  • RED 상태에서는 초록색 신호와 작업(WORK) 신호가 활성화되어 차량이 통행할 수 있습니다. 보행자 버튼 입력에 반응하여 보행자 신호(PED)로 이동할 수 있습니다.
  • GREEN 상태에서는 초록색 신호만 활성화되고, 보행자가 길을 건널 수 있습니다.
  • PED 상태에서는 2초 후에 초록색 신호가 활성화되며, 보행자 신호가 주어진 시간 동안 지속됩니다. 시간이 완료되면 다시 차량 통행을 위한 빨간색 신호로 전환됩니다.

Testbench

 

 

 

이 시스템은 도로 교통을 효율적으로 관리하고, 보행자와 운전자의 안전을 보장하기 위해 설계되었습니다. 각 신호의 전환은 교통 흐름과 보행자의 필요에 따라 조정되어, 도로 사용자들에게 명확하고 일관된 지침을 제공합니다.

 

 

 

 

'하만 세미콘 아카데미 > Verilog HDL' 카테고리의 다른 글

UART 이론 (수업시간 내용 정리)  (0) 2024.05.31
Verilog HDL 실습 (Stop_Watch)  (0) 2024.05.31
Verilog HDL 실습 (Security)  (0) 2024.05.31
Verilog HDL 실습 (FSM)  (0) 2024.05.31
Verilog HDL 실습 (Counter)  (0) 2024.05.31