Electrical – Traffic Light Verilog Code

fpgaverilog

I am working on a traffic light code and the code seems to be working fine in simulation, but when implemented on the FPGA the colors do not seem to toggle from yellow to red for the main street (sc) and green to yellow to red for the crosswalk street (st). It's a simple 4-way street. I have shown the simulation bellow that is working correctly. "_sc" is the main street and "_st" is the crosswalk street.

enter image description here

However when I press the button on the FPGA board that means a pedestrian is at the crosswalk and the light should behave like the waveform above, but it does not work. When I press the button the light simply changes to yellow and red and then changes back to the original state green and red when I let go of the button. I have attached my code for the pedestrian bellow. I'm sure its a simple fix, but I am having trouble understanding.

timescale 1ns / 1ps
module pedestrian_st(clk, rst, ped_detected ,ped_passed, green, yellow, red, 
current_state); 

input clk, rst, ped_detected;
output ped_passed = 0, green, yellow, red;
output [1:0] current_state; 

reg ped_passed = 0, green, yellow, red;
reg [1:0]  current_state, next_state;

parameter   green_st = 2'b00,
            yellow_st = 2'b01,
            red_st = 2'b10,
            random = 2'b11;
integer     count = 0; 

always @(posedge clk)
    begin: pedestrian_SEQ
        if (rst)
            current_state = red_st; //SC has the green light priority
        else
            current_state = next_state; //put it in this state for now  
    end

always @(posedge clk)
    begin: pedestrian_COMB
case (current_state)
    red_st:
        begin
             green = 0;
              yellow = 0;
              red = 1;
        if (ped_detected)   //if car is detected then stays in the same state
               next_state = green_st;
        else
              begin
                  next_state = red_st;
                  ped_passed = 0;
              end
        end
    green_st:
    begin
        green = 1;
        yellow = 0;
        red = 0;

    if (count < 6)
         begin
          count = count +1;  
         next_state = green_st;
         end
    else
         begin
         count = 0;
        next_state = yellow_st;
         end 
    end

yellow_st:
            begin
            green = 0;
            yellow = 1;
             red = 0;

        if (count < 3) //keep yellow on for 30sec
            begin
              count = count +1;  
              next_state = yellow_st;
             end
        else
             begin
             count = 0;
             next_state = red_st;   
             ped_passed = 1;                
            end 
        end
        random:
            begin
            next_state = red_st;    
        end
endcase
end
endmodule

Best Answer

Please use this code in simulation, i modified your code to a 3 always block style , ped_passed is not assigned to 1 in any state in the below code please try it at your end.SNUG paper ref

   `timescale 1ns / 1ps
    module pedestrian_st(
    input            clk, rst, ped_detected,
    output reg       ped_passed = 0, green, yellow, red,
    output reg [1:0] current_state
    );

    reg [1:0] next_state;

    parameter   GREEN_ST  = 2'b00,
                YELLOW_ST = 2'b01,
                RED_ST    = 2'b10,

    reg[2:0] count = 0;

        always @(posedge clk)
            if (rst)current_state <= #1 RED_ST;     //SC has the green light priority
            else    current_state <= #1 next_state; //put it in this state for now

        always@* begin
                next_state = 2'bx;
           case(current_state)
               RED_ST    : next_state = ped_detected ? GREEN_ST : RED_ST   ;
               GREEN_ST  : next_state = (count < 6)  ? GREEN_ST : YELLOW_ST;
               YELLOW_ST : next_state = (count < 3)  ? YELLOW_ST: RED_ST   ;
                default  : next_state = 2'bx;
           endcase
        end

        always @(posedge clk)
          case(next_state)
            GREEN_ST  : count <= #1 (count < 6)  ? count + 1'b1 : 3'b0 ;
            YELLOW_ST : count <= #1 (count < 3)  ? count + 1'b1 : 3'b0 ;
            default   : count <= #1 3'b0;
          endcase

        always @(posedge clk)begin
                  red    <= #1 1'b0;
                 green   <= #1 1'b0;
                 yellow  <= #1 1'b0;
              ped_passed <= #1 1'b0;
          case(next_state)
            RED_ST    :    red   <= #1 1'b1;
            GREEN_ST  :   green  <= #1 1'b1;
            YELLOW_ST :   yellow <= #1 1'b1;
          endcase
         end

     endmodule
Related Topic