1
\$\begingroup\$

I'm working on a Verilog project using ModelSim, and I've created a testbench to simulate the behavior of a module called Elevator_FSM, which models an elevator's operation.

My goal is to assign values to the request_floor signal from the testbench and, based on that signal, have the output signals, such as output_floor, and the internal states of the Finite State Machine (FSM) update accordingly.

The problem: I want my testbench to assign values to request_floor and have those values correctly update the output signals and internal states of the Elevator_FSM module. However, I'm not seeing the expected changes reflected in the simulation.

Debugging details are as follows:

This module simulates the behavior of an elevator using a Finite State Machine (FSM). The system's inputs include signals like request_floor, over_time, and over_weight, which determine the elevator's behavior. The outputs include current_floor (the current floor) and alert signals such as door_alert and weight_alert.

Inputs:

  • clk: Clock signal.
  • reset: Signal to reset the system, restoring initial values.
  • request_floor: The floor to which the user requests the elevator to move (4-bit value).
  • over_time: Indicates if the elevator door has been open for an excessive amount of time (more than 3 minutes).
  • over_weight: Indicates if the weight inside the elevator exceeds the allowed limit.

Outputs:

  • current_floor: The current floor of the elevator.
  • door_alert: Alert activated when the door has been open for more than 3 minutes.
  • weight_alert: Alert activated when the weight exceeds the allowed limit.

FSM States:

The FSM has four possible states, represented by current_state and next_state:

  • IDLE (00): The elevator is inactive, waiting for a request.
  • MOVING (01): The elevator is moving towards the requested floor.
  • ALERT (10): The elevator has detected an issue (door open for too long or over weight).
  • ERROR (11): The elevator is in an error state, such as over weight or sensor error.

Combinational Logic:

The elevator's behavior is based on the comparison between current_floor and request_floor, as well as the signals over_time and over_weight.

  1. IDLE State:

    • The elevator is inactive, waiting for a request_floor.
    • If request_floor is not equal to 0 (i.e., there is a floor request), the system transitions to the MOVING state.
    • current_floor remains constant in the IDLE state.
  2. MOVING State:

    • The elevator is moving.
    • If request_floor is greater than current_floor, the elevator moves up.
    • If request_floor is less than current_floor, the elevator moves down.
    • If current_floor == request_floor, the elevator has reached the destination and returns to the IDLE state.
    • During movement, if over_time is active (door open for more than 3 minutes), the elevator enters the ALERT state.
    • If over_weight is active (weight exceeded), the system enters the ERROR state.
  3. ALERT State:

    • In this state, the system waits for the door time issue to resolve.
    • If over_time returns to 0 (door no longer open for too long), the elevator can return to the MOVING state to continue movement.
  4. ERROR State:

    • If over_weight is active (indicating over weight), the elevator enters the ERROR state.
    • If over_weight returns to 0 (weight no longer exceeds limit), the elevator can return to MOVING or IDLE if no more requests.

Elevator_FSM Module Code:

module Elevator_FSM(
 input clk, // Clock signal
 input reset, // Asynchronous reset signal
 input [3:0] request_floor, // Requested floor
 input over_time, // Door open time signal
 input over_weight, // Over weight signal
 output reg [3:0] current_floor, // Current floor
 output reg door_alert, // Door alert
 output reg weight_alert // Weight alert
);
 // State definitions
 localparam IDLE = 2'b00,
 MOVING = 2'b01,
 ALERT = 2'b10,
 ERROR = 2'b11;
 // Registers for current and next state
 reg [1:0] current_state, next_state;
 // Asynchronous reset for current state
 always @(posedge clk or posedge reset) begin
 if (reset)
 current_state <= IDLE;
 else
 current_state <= next_state;
 end
 // Combinational logic: next state + alert generation
 always @(*) begin
 next_state = current_state;
 door_alert = 1'b0;
 weight_alert = 1'b0;
 case (current_state)
 IDLE: begin
 if (request_floor != 4'b0000)
 next_state = MOVING;
 end
 MOVING: begin
 if (over_time) begin
 door_alert = 1'b1;
 next_state = ALERT;
 end
 else if (over_weight) begin
 weight_alert = 1'b1;
 next_state = ERROR;
 end
 else if (current_floor == request_floor) begin
 next_state = IDLE;
 end
 end
 ALERT: begin
 if (!over_time)
 next_state = MOVING;
 end
 ERROR: begin
 if (!over_weight)
 next_state = MOVING;
 end
 default: next_state = IDLE;
 endcase
 end
 // Asynchronous reset for current floor
 always @(posedge clk or posedge reset) begin
 if (reset)
 current_floor <= 4'b0000; // Initialize to floor 0
 else if (current_state == MOVING) begin
 if (current_floor < request_floor && current_floor < 4'b1111)
 current_floor <= current_floor + 1;
 else if (current_floor > request_floor && current_floor > 4'b0000)
 current_floor <= current_floor - 1;
 end
 end
endmodule

And this is the testbench that I've made:

module Elevator_FSM_tb;
 reg clk;
 reg reset;
 reg [3:0] request_floor;
 reg [3:0] current_floor;
 reg over_time;
 reg over_weight;
 wire [3:0] current_floor_out;
 wire door_alert;
 wire weight_alert;
 Elevator_FSM uut (
 .clk(clk),
 .reset(reset),
 .request_floor(request_floor),
 .over_time(over_time),
 .over_weight(over_weight),
 .current_floor(current_floor_out),
 .door_alert(door_alert),
 .weight_alert(weight_alert)
 );
 always begin
 #5 clk = ~clk;
 end
 initial begin
 clk = 0;
 reset = 1;
 request_floor = 4'b0000;
 current_floor = 4'b0000;
 over_time = 0;
 over_weight = 0;
 #10 reset = 0;
 #10 request_floor = 4'b0001; // Solicitar piso 1
 #10 request_floor = 4'b0010; // Solicitar piso 2
 #10 request_floor = 4'b0011; // Solicitar piso 3
 #10 request_floor = 4'b0100; // Solicitar piso 4
 #10 request_floor = 4'b0101; // Solicitar piso 5
 #10 request_floor = 4'b0110; // Solicitar piso 6
 #10 request_floor = 4'b0111; // Solicitar piso 7
 // Simulamos un error de tiempo en la puerta
 #10 over_time = 1;
 #10 over_time = 0;
 // Simulamos un error de sobrepeso
 #10 over_weight = 1;
 #10 over_weight = 0;
 #10 $finish;
 end
endmodule

PD: I set four request_floor expecting the fsm automatically detect the current_floor and update the current_floor value with the former value of request_floor. I know the external state such as IDLE, ERROR, MOVING, ALERT doesn't seem reflected on the testbench because I didnt assign the values for them. Also, I dont know much about setting testbench.

But when I simulate from the Intel quartus idle to ModelSim simulator, this what I got:

enter image description here

What should I do to ensure the signals update and reflect the signals correctly during simulation?

toolic
10.8k11 gold badges31 silver badges35 bronze badges
asked Jul 25 at 14:21
\$\endgroup\$
1

1 Answer 1

0
\$\begingroup\$

The problem is with your simulator, or how you are running your simulation software. If all you see is x and z in waves, that means the simulation has not run properly.

The Verilog code simulates fine for me on other simulators. You can run it on EDA Playground to see waveforms toggling like this:

waves

answered Jul 25 at 23:30
\$\endgroup\$

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.