0

As you can see in the code below, I have a machine state with a state called start. This state should take the value of coord_x_reg , increment it by one and assign it to the output port using the assign instruction at the end. The problems are:

  1. The output coord_x does not change in the simulation as you can see in the photo simulation waveforms
    I imagine that the problem is that I cannot write and read from the register at the same time. How can I achieve the effect I want then? (I also tried using coord_x_reg as a integer variable)

  2. When using reset, I have to comment some signals, other way I get Illegal left hand side of nonblocking assignment error.

module Ball
  #(parameter SCR_W = 1280,   //SCREEN RESOLUTION?
    parameter SCR_H = 720,
    parameter BALL_WIDTH = 30,
    parameter PAD_Y_WIDTH = 26,
    parameter PAD_Y_LENGTH = 168,
    parameter PAD_x_POS_L = 67,
    parameter PAD_x_POS_R = 1213  //SCR_W-PAD_x_POS_L
  )
  (
     input wire CLK, RST,
     input wire button_L, button_R,
     input wire [9:0] pad_y_L,
     input wire [9:0] pad_y_R,
     output wire [9:0] coord_x,
      output wire [9:0] coord_y,
     output wire [3:0] score_left,
      output wire [3:0] score_right
  );

  //STATES
  localparam [3:0] //11 states needed we need 4 bits
       start = 4'b0000,
       start_race = 4'b0001,

       left_player_begins = 4'b0010,
       right_player_begins = 4'b0011,

       top_left = 4'b0100,
       top_right = 4'b0101,

       bottom_left = 4'b0110,
       bottom_right = 4'b0111,

       score_L = 4'b1000,
       score_R = 4'b1001,

       game_over = 4'b1010;


  //Current state variables
  reg [3:0] state_reg, state_next;

  //output registers
  reg [9:0] coord_x_reg = 0;
  reg [9:0] coord_y_reg = 0;
  reg [3:0] score_left_reg = 0;
  reg [3:0] score_right_reg = 0;




  always @(posedge CLK, posedge RST)
  begin
      if(RST) // go to state zero if reset
          begin
           state_reg <= start;

           //coord_x <= 0;
           //coord_y <= 0;
           //score_left <= 0;
           //score_right <= 0;
              
          end
      else // otherwise update the states
          begin

           state_reg <= state_next;

          end
  end


  //_________________________________________________________________________
  // MACHINE STATE DESIGN
  //_________________________________________________________________________

  always @(state_reg) //   <------------ PUT VARIABLES HERE???????!!!!!!!!!!!!!!!
  begin
      // store current state as next
      state_next = state_reg; // REQUIRED: when no case statement is satisfied


      case(state_reg)

        start :
          begin


            coord_x_reg <= coord_x_reg + 1;

            if (coord_x_reg == 10)
                  state_next = start_race;


          end

        start_race :
          begin
            state_next = start;
          end

      endcase

  end

assign coord_x = coord_x_reg;
assign coord_y = coord_y_reg;
assign score_left = score_left_reg;
assign score_right = score_right_reg;


endmodule // Ball 
Marcus Müller
  • 34,677
  • 4
  • 53
  • 94
Ginés Díaz
  • 117
  • 1
  • 10
  • 1
    I see at least two problems. 1) Missing signals in a sensitivity list. Use always @(*) instead of always @(state_reg). 2) The non blocking assignment in this statement coord_x_reg <= coord_x_reg + 1; should be a blocking assignment (just= not <=), because this is a combinational process not a synchronous process. I would make those changes to your code and see if it does what you want. You have a better chance of getting the issue solved if you also post the testbench. – Mikef Apr 01 '22 at 21:14
  • @Mikef Thank you very much. I realized that was the problem after relooking at the code. Anyways, thank you for the answer. – Ginés Díaz Apr 01 '22 at 21:28
  • @Mikef in your opinion, do you think is it better to structure the code as in the first case (putting the FSM in a separate always)? or the new version I put (putting the FSM in the always(clk,rst)? – Ginés Díaz Apr 01 '22 at 21:31
  • If you put everything in the synchronous process, then use non-blocking assignments on each. The SM style is a matter of preference. Some use 1 process some use 2 some use 3. I put the current state <= next state in a synchronous process, and use a 2nd combinational process for the next_state and output assignments. If you put SM output assignments in a clocked process then they all all have at least 1-clock cycle delay from an input changing. This is good and bad for different reasons. I find that in a mid-large sized state machine i always end up with a couple of combinational outputs. – Mikef Apr 01 '22 at 22:09

1 Answers1

0

By investigating, I came to the conclusion that the sensibility list was giving problems. I modified the code so the machine state is inside the always @(posedge CLK, posedge RST). Now works as expected. The new code:

module Ball
#(parameter SCR_W = 1280,   //SCREEN RESOLUTION?
    parameter SCR_H = 720,
    parameter BALL_WIDTH = 30,
    parameter PAD_Y_WIDTH = 26,
    parameter PAD_Y_LENGTH = 168,
    parameter PAD_x_POS_L = 67,
    parameter PAD_x_POS_R = 1213  //SCR_W-PAD_x_POS_L
  )
  (
     input wire CLK, RST,
     input wire button_L, button_R,
     input wire [9:0] pad_y_L,
     input wire [9:0] pad_y_R,
     output wire [9:0] coord_x,
      output wire [9:0] coord_y,
     output wire [3:0] score_left,
      output wire [3:0] score_right
  );

  //STATES
  localparam [3:0] //11 states needed we need 4 bits
       start = 4'b0000,
       start_race = 4'b0001,

       left_player_begins = 4'b0010,
       right_player_begins = 4'b0011,

       top_left = 4'b0100,
       top_right = 4'b0101,

       bottom_left = 4'b0110,
       bottom_right = 4'b0111,

       score_L = 4'b1000,
       score_R = 4'b1001,

       game_over = 4'b1010;


  //Current state variables
  reg [3:0] state;

  //output registers
  reg [9:0] coord_x_reg = 0;
  reg [9:0] coord_y_reg = 0;
  reg [3:0] score_left_reg = 0;
  reg [3:0] score_right_reg = 0;




  always @(posedge CLK, posedge RST)
  begin
      if(RST) // go to state zero if reset
          begin
           state <= start;

           coord_x <= 0;
           coord_y <= 0;
           score_left <= 0;
           score_right <= 0;

          end
      else // otherwise update the states
          begin

          case(state)

            start :
              begin


                coord_x_reg = coord_x_reg + 1;

                if (coord_x_reg == 10)
                  state = start_race;


              end

            start_race :
              begin
                state = start_race;
              end

          endcase


          end
  end


assign coord_x = coord_x_reg;
assign coord_y = coord_y_reg;
assign score_left = score_left_reg;
assign score_right = score_right_reg;


endmodule // Ball ```
vvvvv
  • 25,404
  • 19
  • 49
  • 81
Ginés Díaz
  • 117
  • 1
  • 10