-1
\$\begingroup\$

I have a simple problem, but not able to debug. I am not a novice in Verilog, but this problem seems surreal and weird. I have tried all I could to debug, but still cannot figure it out, so sking for help.

I have the design of an FSM of traffic light controller) along with the testbench pasted here. The problem is state does not follow next_state for few clock cycles. I have tested with different testbenches but result is same. This is just a help I am doing for another person for his academic project. The design is

`timescale 1ns /1ns

// traffic light controller shell -- fill in the guts
// CSE140L  Summer II  2019
module traffic_light_controller(
            input clk,                          // 
            reset,                        // should force to all-red state
            e_left_sensor,
            e_str_sensor,
            w_left_sensor,
            w_str_sensor,           
            ns_sensor,
            output reg[1:0] e_left_light,     
            e_str_light,
            w_left_light,     
            w_str_light,            
            ns_light);


            parameter RED=0,YELLOW=1,GREEN=2;
            parameter     ES_R_WS_R_EL_R_WL_R_NS_R=4'b0000,       

                                ES_G_WS_G_EL_R_WL_R_NS_R=4'b0001,
                                ES_Y_WS_Y_EL_R_WL_R_NS_R=4'b0010,

                                ES_G_WS_R_EL_G_WL_R_NS_R=4'b0011,
                                ES_Y_WS_R_EL_Y_WL_R_NS_R=4'b0100,

                                ES_R_WS_G_EL_R_WL_G_NS_R=4'b0101,
                                ES_R_WS_Y_EL_R_WL_Y_NS_R=4'b0110,

                                ES_R_WS_R_EL_G_WL_G_NS_R=4'b0111,
                                ES_R_WS_R_EL_Y_WL_Y_NS_R=4'b1000,

                                ES_R_WS_R_EL_R_WL_R_NS_G=4'b1001,
                                ES_R_WS_R_EL_R_WL_R_NS_Y=4'b1010;




    reg [3:0] state , next_state;

    reg [3:0] count_g_es_ws,count_g_es_el,count_g_ws_wl,count_g_el_wl,count_g_ns;           //Count till 10
    reg [1:0] count_y_es_ws,count_y_es_el,count_y_ws_wl,count_y_el_wl,count_y_ns;   

    reg ctr_en_es_ws_y,ctr_en_es_ws_g;
    reg ctr_en_es_el_y,ctr_en_es_el_g;
    reg ctr_en_ws_wl_y,ctr_en_ws_wl_g;
    reg ctr_en_el_wl_y,ctr_en_el_wl_g;
    reg ctr_en_ns_y,ctr_en_ns_g;

    //Sequential logic
    always@(posedge clk)
    begin
        if(reset==1'b1)
            state <= ES_R_WS_R_EL_R_WL_R_NS_R;
        else
            state <= next_state;
    end

    //Logic for counter
    always@(posedge clk or posedge reset)
    begin
        if(reset)
            count_g_es_ws <= 4'b0;
        else 
        begin
            if(ctr_en_es_ws_g)
                count_g_es_ws <= count_g_es_ws + 1'b1;
        end
    end

    always@(posedge clk or posedge reset)
    begin
        if(reset)
            count_g_es_el <= 4'b0;
        else 
        begin
            if(ctr_en_es_el_g)
                count_g_es_el <= count_g_es_el + 1'b1;
        end
    end

    always@(posedge clk or posedge reset)
    begin
        if(reset)
            count_g_ws_wl <= 4'b0;
        else 
        begin
            if(ctr_en_ws_wl_g)
                count_g_ws_wl <= count_g_ws_wl + 1'b1;
        end
    end

    always@(posedge clk or posedge reset)
    begin
        if(reset)
            count_g_el_wl <= 4'b0;
        else 
        begin
            if(ctr_en_el_wl_g)
                count_g_el_wl <= count_g_el_wl + 1'b1;
        end
    end

    always@(posedge clk or posedge reset)
    begin
        if(reset)
            count_g_ns  <= 4'b0;
        else 
        begin
           if(ctr_en_ns_g)
                count_g_ns <= count_g_ns + 1'b1;
        end
    end

    always@(posedge clk or posedge reset)
    begin
        if(reset)
            count_y_es_ws <= 2'b0;
        else 
        begin
            if(ctr_en_es_ws_y)
                count_y_es_ws <= count_y_es_ws + 1'b1;
        end
    end

    always@(posedge clk or posedge reset)
    begin
        if(reset)
            count_y_es_el <= 2'b0;
        else 
        begin
            if(ctr_en_es_el_y)
                count_y_es_el <= count_y_es_el + 1'b1;
        end
    end

    always@(posedge clk or posedge reset)
    begin
        if(reset)
            count_y_ws_wl <= 2'b0;
        else 
        begin
            if(ctr_en_ws_wl_y)
                count_y_ws_wl <= count_y_ws_wl + 1'b1;
        end
    end

    always@(posedge clk or posedge reset)
    begin
        if(reset)
            count_y_el_wl <= 2'b0;
        else 
        begin
            if(ctr_en_el_wl_y)
                count_y_el_wl <= count_y_el_wl + 1'b1;
        end
    end

    always@(posedge clk or posedge reset)
    begin
        if(reset)
            count_y_ns  <= 2'b0;
        else 
        begin
           if(ctr_en_ns_y)
                count_y_ns <= count_y_ns + 1'b1;
        end
    end

    //Combinatonal logic
    always@(state,e_left_sensor,e_str_sensor,w_left_sensor,w_str_sensor,ns_sensor)
    begin
        next_state = 0;
        ctr_en_es_ws_y = 0;
        ctr_en_es_ws_g = 0;
        ctr_en_es_el_y = 0;
        ctr_en_es_el_g = 0;
        ctr_en_ws_wl_y = 0;
        ctr_en_ws_wl_g = 0;
        ctr_en_el_wl_y = 0;
        ctr_en_el_wl_g = 0;
        ctr_en_ns_y = 0;
        ctr_en_ns_g = 0;
        case(state)

            ES_R_WS_R_EL_R_WL_R_NS_R :  begin
                                                    if({e_str_sensor,w_str_sensor,e_left_sensor,w_left_sensor,ns_sensor} == 5'b00000)
                                                    begin
                                                        next_state = ES_R_WS_R_EL_R_WL_R_NS_R;
                                                    end
                                                    else 
                                                    begin
                                                       //Highest priority is straight EW
                                                        if(e_str_sensor)
                                                        begin
                                                            if(w_str_sensor)
                                                                next_state = ES_G_WS_G_EL_R_WL_R_NS_R;
                                                            else if(e_left_sensor)
                                                                next_state = ES_G_WS_R_EL_G_WL_R_NS_R;
                                                            else
                                                                next_state = ES_R_WS_R_EL_R_WL_R_NS_R;
                                                        end
                                                        else if(w_str_sensor)
                                                        begin
                                                            if(w_left_sensor)
                                                                next_state = ES_R_WS_G_EL_R_WL_G_NS_R;
                                                            else
                                                                next_state = ES_R_WS_R_EL_R_WL_R_NS_R;
                                                        end
                                                        else if(e_left_sensor)
                                                        begin
                                                            if(w_left_sensor)
                                                                next_state = ES_R_WS_R_EL_G_WL_G_NS_R;
                                                            else
                                                                next_state = ES_R_WS_R_EL_R_WL_R_NS_R;
                                                        end
                                                        else
                                                            next_state = ES_R_WS_R_EL_R_WL_R_NS_G;
                                                    end
                                                end

            ES_G_WS_G_EL_R_WL_R_NS_R:begin
                                                ctr_en_es_ws_g = 1;
                                                if({e_str_sensor,w_str_sensor,e_left_sensor,w_left_sensor,ns_sensor} == 5'b11000)
                                                    next_state = ES_G_WS_G_EL_R_WL_R_NS_R;    //always remain GREEN-east and westbound through
                                                else if(e_left_sensor || w_left_sensor || ns_sensor)    
                                                begin
                                                   //count for 10 cycles
                                                    if(count_g_es_ws <= 9)
                                                        ctr_en_es_ws_g = 1;
                                                    else ctr_en_es_ws_g = 0;
                                                    next_state = ES_Y_WS_Y_EL_R_WL_R_NS_R;
                                                end
                                                else if({e_str_sensor,w_str_sensor,e_left_sensor,w_left_sensor,ns_sensor} == 5'b00000)
                                                begin
                                                    //count green for 5 cycles if no traffic, then go yellow
                                                    if(count_g_es_ws <= 4)
                                                        ctr_en_es_ws_g = 1;
                                                    else ctr_en_es_ws_g = 0;
                                                    next_state = ES_Y_WS_Y_EL_R_WL_R_NS_R;
                                                end
                                             end

            ES_Y_WS_Y_EL_R_WL_R_NS_R :begin
                                                ctr_en_es_ws_y = 1;
                                                if(count_y_es_ws <= 1)
                                                    ctr_en_es_ws_y = 1;
                                                else ctr_en_es_ws_g = 0;
                                                next_state = ES_R_WS_R_EL_R_WL_R_NS_R;
                                             end

            ES_G_WS_R_EL_G_WL_R_NS_R: begin
                                                ctr_en_es_el_g = 1;
                                                if({e_str_sensor,w_str_sensor,e_left_sensor,w_left_sensor,ns_sensor} == 5'b10100)
                                                    next_state = ES_G_WS_R_EL_G_WL_R_NS_R;    
                                                else if(ns_sensor||w_left_sensor||w_str_sensor) 
                                                begin
                                                   //count for 10 cycles
                                                    if(count_g_es_el <= 9)
                                                        ctr_en_es_el_g = 1;
                                                    else ctr_en_es_el_g = 0;
                                                    next_state = ES_Y_WS_R_EL_Y_WL_R_NS_R;
                                                end
                                                else if({e_str_sensor,w_str_sensor,e_left_sensor,w_left_sensor,ns_sensor} == 5'b00000)
                                                begin
                                                    //count green for 5 cycles if no traffic, then go yellow
                                                    if(count_g_es_el <= 4)
                                                        ctr_en_es_el_g = 1;
                                                    else ctr_en_es_el_g = 0;
                                                    next_state = ES_Y_WS_R_EL_Y_WL_R_NS_R;
                                                end
                                             end

            ES_Y_WS_R_EL_Y_WL_R_NS_R :begin
                                                ctr_en_es_el_y = 1;
                                                if(count_y_es_el <= 1)
                                                    ctr_en_es_el_y = 1;
                                                else ctr_en_es_el_g = 0;
                                                next_state = ES_R_WS_R_EL_R_WL_R_NS_R;
                                             end

            ES_R_WS_G_EL_R_WL_G_NS_R:begin
                                                ctr_en_ws_wl_g = 1;
                                                if({e_str_sensor,w_str_sensor,e_left_sensor,w_left_sensor,ns_sensor} == 5'b01010)
                                                    next_state = ES_R_WS_G_EL_R_WL_G_NS_R;    
                                                else if(e_str_sensor||e_left_sensor||ns_sensor)
                                                begin
                                                   //count for 10 cycles
                                                    if(count_g_ws_wl <= 9)
                                                        ctr_en_ws_wl_g = 1;
                                                    else ctr_en_ws_wl_g = 0;
                                                    next_state = ES_R_WS_Y_EL_R_WL_Y_NS_R;
                                                end
                                                else if({e_str_sensor,w_str_sensor,e_left_sensor,w_left_sensor,ns_sensor} == 5'b00000)
                                                begin
                                                    //count green for 5 cycles if no traffic, then go yellow
                                                    if(count_g_ws_wl <= 4)
                                                        ctr_en_ws_wl_g = 1;
                                                    else ctr_en_ws_wl_g = 0;
                                                    next_state = ES_R_WS_Y_EL_R_WL_Y_NS_R;
                                                end
                                             end


            ES_R_WS_Y_EL_R_WL_Y_NS_R:begin
                                                ctr_en_ws_wl_y = 1;
                                                if(count_y_ws_wl <= 1)
                                                    ctr_en_ws_wl_y = 1;
                                                else ctr_en_ws_wl_g = 0;
                                                next_state = ES_R_WS_R_EL_R_WL_R_NS_R;
                                             end

            ES_R_WS_R_EL_G_WL_G_NS_R:begin
                                                ctr_en_el_wl_g = 1;
                                                if({e_str_sensor,w_str_sensor,e_left_sensor,w_left_sensor,ns_sensor} == 5'b00110)
                                                    next_state = ES_R_WS_R_EL_G_WL_G_NS_R;    
                                                else if(e_str_sensor||w_str_sensor||ns_sensor)
                                                begin
                                                   //count for 10 cycles
                                                    if(count_g_el_wl <= 9)
                                                        ctr_en_el_wl_g = 1;
                                                    else ctr_en_el_wl_g = 0;
                                                    next_state = ES_R_WS_R_EL_Y_WL_Y_NS_R;
                                                end
                                                else if({e_str_sensor,w_str_sensor,e_left_sensor,w_left_sensor,ns_sensor} == 5'b00000)
                                                begin
                                                    //count green for 5 cycles if no traffic, then go yellow
                                                    if(count_g_el_wl <= 4)
                                                        ctr_en_el_wl_g = 1;
                                                    else ctr_en_el_wl_g = 0;
                                                    next_state = ES_R_WS_R_EL_Y_WL_Y_NS_R;
                                                end
                                             end

            ES_R_WS_R_EL_Y_WL_Y_NS_R:begin
                                                ctr_en_el_wl_y = 1;
                                                if(count_y_el_wl <= 1)
                                                    ctr_en_el_wl_y = 1;
                                                else ctr_en_el_wl_g = 0;
                                                next_state = ES_R_WS_R_EL_R_WL_R_NS_R;
                                             end

            ES_R_WS_R_EL_R_WL_R_NS_G:begin
                                                ctr_en_ns_g = 1;
                                                if({e_str_sensor,w_str_sensor,e_left_sensor,w_left_sensor,ns_sensor} == 5'b00001)
                                                    next_state = ES_R_WS_R_EL_R_WL_R_NS_G;    
                                                else if(e_str_sensor||w_str_sensor||e_left_sensor||w_left_sensor)
                                                begin
                                                   //count for 10 cycles
                                                    if(count_g_ns <= 9)
                                                        ctr_en_ns_g = 1;
                                                    else ctr_en_ns_g = 0;
                                                    next_state = ES_R_WS_R_EL_R_WL_R_NS_Y;
                                                end
                                                else if({e_str_sensor,w_str_sensor,e_left_sensor,w_left_sensor,ns_sensor} == 5'b00000)
                                                begin
                                                    //count green for 5 cycles if no traffic, then go yellow
                                                    if(count_g_ns <= 4)
                                                        ctr_en_ns_g = 1;
                                                    else ctr_en_ns_g = 0;
                                                    next_state = ES_R_WS_R_EL_R_WL_R_NS_Y;
                                                end
                                             end

            ES_R_WS_R_EL_R_WL_R_NS_Y:begin
                                                ctr_en_ns_y = 1;
                                                if(count_y_ns <= 1)
                                                    ctr_en_ns_y = 1;
                                                else ctr_en_ns_g = 0;
                                                next_state = ES_R_WS_R_EL_R_WL_R_NS_R;
                                             end                                 


        endcase
    end

    //Combinational logic for output
    always@(state,e_left_sensor,e_str_sensor,w_left_sensor,w_str_sensor,ns_sensor)
    begin
        e_left_light = 0;
        e_str_light = 0;
        w_left_light = 0;
        w_str_light = 0;
        ns_light = 0;
        case(state)
            ES_R_WS_R_EL_R_WL_R_NS_R: begin
                                                e_left_light=RED;     
                                                e_str_light=RED;
                                                w_left_light=RED;     
                                                w_str_light=RED;            
                                                ns_light=RED;
                                              end
            ES_G_WS_G_EL_R_WL_R_NS_R: begin
                                                e_left_light=RED;     
                                                e_str_light=GREEN;
                                                w_left_light=RED;     
                                                w_str_light=GREEN;          
                                                ns_light=RED;
                                              end                                 
            ES_Y_WS_Y_EL_R_WL_R_NS_R: begin
                                                e_left_light=RED;     
                                                e_str_light=YELLOW;
                                                w_left_light=RED;     
                                                w_str_light=YELLOW;         
                                                ns_light=RED;
                                              end
            ES_G_WS_R_EL_G_WL_R_NS_R: begin
                                                e_left_light=GREEN;     
                                                e_str_light=GREEN;
                                                w_left_light=RED;     
                                                w_str_light=RED;            
                                                ns_light=RED;
                                              end                                
            ES_Y_WS_R_EL_Y_WL_R_NS_R: begin
                                                e_left_light=YELLOW;     
                                                e_str_light=YELLOW;
                                                w_left_light=RED;     
                                                w_str_light=RED;            
                                                ns_light=RED;
                                              end
            ES_R_WS_G_EL_R_WL_G_NS_R: begin
                                                e_left_light=RED;     
                                                e_str_light=RED;
                                                w_left_light=GREEN;     
                                                w_str_light=GREEN;          
                                                ns_light=RED;
                                              end                                 
            ES_R_WS_Y_EL_R_WL_Y_NS_R: begin
                                                e_left_light=RED;     
                                                e_str_light=RED;
                                                w_left_light=YELLOW;     
                                                w_str_light=YELLOW;         
                                                ns_light=RED;
                                              end   
            ES_R_WS_R_EL_G_WL_G_NS_R: begin
                                                e_left_light=GREEN;     
                                                e_str_light=RED;
                                                w_left_light=GREEN;     
                                                w_str_light=RED;            
                                                ns_light=RED;
                                              end
            ES_R_WS_R_EL_Y_WL_Y_NS_R: begin
                                                e_left_light=YELLOW;     
                                                e_str_light=RED;
                                                w_left_light=YELLOW;     
                                                w_str_light=RED;            
                                                ns_light=RED;
                                              end
            ES_R_WS_R_EL_R_WL_R_NS_G: begin
                                                e_left_light=RED;     
                                                e_str_light=RED;
                                                w_left_light=RED;     
                                                w_str_light=RED;            
                                                ns_light=GREEN;
                                              end
            ES_R_WS_R_EL_R_WL_R_NS_Y: begin
                                                e_left_light=RED;     
                                                e_str_light=RED;
                                                w_left_light=RED;     
                                                w_str_light=RED;            
                                                ns_light=YELLOW;
                                              end   
            default:begin
                        e_left_light=RED;     
                        e_str_light=RED;
                        w_left_light=RED;     
                        w_str_light=RED;            
                        ns_light=RED;
                     end
        endcase
    end

endmodule

The testbench is here

`timescale 1ns / 1ps

////////////////////////////////////////////////////////////////////////////////
// Company: 
// Engineer:
//
// Create Date:   15:05:44 05/26/2020
// Design Name:   traffic_light_controller
// Module Name:   C:/Users/Shankhadeep/Traffic_light/tb.v
// Project Name:  Traffic_light
// Target Device:  
// Tool versions:  
// Description: 
//
// Verilog Test Fixture created by ISE for module: traffic_light_controller
//
// Dependencies:
// 
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
// 
////////////////////////////////////////////////////////////////////////////////

module tb;

    // Inputs
    reg clk;
    reg reset;
    reg e_left_sensor;
    reg e_str_sensor;
    reg w_left_sensor;
    reg w_str_sensor;
    reg ns_sensor;

    // Outputs
    wire [1:0] e_left_light;
    wire [1:0] e_str_light;
    wire [1:0] w_left_light;
    wire [1:0] w_str_light;
    wire [1:0] ns_light;

    // Instantiate the Unit Under Test (UUT)
    traffic_light_controller uut (
        .clk(clk), 
        .reset(reset), 
        .e_left_sensor(e_left_sensor), 
        .e_str_sensor(e_str_sensor), 
        .w_left_sensor(w_left_sensor), 
        .w_str_sensor(w_str_sensor), 
        .ns_sensor(ns_sensor), 
        .e_left_light(e_left_light), 
        .e_str_light(e_str_light), 
        .w_left_light(w_left_light), 
        .w_str_light(w_str_light), 
        .ns_light(ns_light)
    );

    always begin
  #5 clk = 1'b0;
  #5 clk = 1'b1;
  end

    initial begin
        // Initialize Inputs

        reset          = 1'b1;
  e_left_sensor = 1'b0;
  e_str_sensor  = 1'b0;
  w_left_sensor = 1'b0;
  w_str_sensor  = 1'b0;
  ns_sensor      = 1'b0;
  #20 reset    = 1'b0;
    #10;    

        #30 e_left_sensor       = 1'b1 ;
  #30 w_left_sensor = 1'b1 ;
  #60 e_left_sensor = 1'b0 ;
  #20 e_str_sensor  = 1'b1 ;
  #30 w_str_sensor  = 1'b1 ;
  #60 e_str_sensor  = 1'b0 ;
  #10 w_str_sensor  = 1'b0;
  #30 w_left_sensor = 1'b0;
  #200;

        // Add stimulus here

    end

endmodule

I cannot figure out why at 90 ns, state is 0111 and next_state is 0111 at the same cycle. The behavior from 90ns to 160ns is uncanny. For reference, I am sharing the screenshot of waveform

enter image description here

\$\endgroup\$
0
\$\begingroup\$

You go to 0111 state when w_left_sensor gets high. Moreover, in that state you have following condition:

if({e_str_sensor,w_str_sensor,e_left_sensor,w_left_sensor,ns_sensor} == 5'b00110)
    next_state = ES_R_WS_R_EL_G_WL_G_NS_R;

This condition evaluates to TRUE, so your next_state is equal to the state you're already in. Thus, your waveform looks exactly as it should.

\$\endgroup\$
4
  • \$\begingroup\$ next_state going to 0111 is understandable, but then state should go to 0111 on the next cycle, why is it going in the same cycle? \$\endgroup\$
    – shaam
    May 26 '20 at 12:50
  • \$\begingroup\$ @shaam drive your input signals at negative edge of clock and you will see that everything is ok. \$\endgroup\$
    – Qiu
    May 26 '20 at 13:22
  • \$\begingroup\$ unfortunately the testbench can't be changed it seems some academic constraints. anything that is missing in the RTL ? \$\endgroup\$
    – shaam
    May 26 '20 at 13:23
  • \$\begingroup\$ It is intriguing that how state and next_state can change at the same cycle, not one cycle later! \$\endgroup\$
    – shaam
    May 26 '20 at 13:28

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.