Forum Discussion

Altera_Forum's avatar
Altera_Forum
Icon for Honored Contributor rankHonored Contributor
9 years ago

Quartus not synthesizing my FSM right?

I made a FSM in verilog that is working in simulation.

I found a strange behaviour however, when I synthesize it in Quartus 2. The state WRITE should immediately go to WRITE_DONE, which it does.

But when in state WRITE_DONE, it should wait for the trigger of "ye" going low before moving on to the next state.

But when I synthesize and put this on FPGA, the WRITE_DONE is immediately passing to YE_PROG2 state on the next clock cycle, without waiting for the 'if condition'.

Does anyone have any suggestion why this might be happening? is there an error in my code I'm missing that's causing the synthesis to not do what I want? The code seems straightforward to me.

I did pull out the 'ye' signal in SignalTap to make sure it's high.

  always@(posedge clk or negedge resetn)
     begin
    if (!resetn)
      begin
         state <= IDLE;
      end
    else
      begin
         state <= next_state;
      end
     end
   always@(*)
   begin
      //next_state = IDLE;
      
    case(state)
      IDLE: begin
         if (read_start | read_next)//(xe & se & ye & yadr_change)) //(xe & ye & se)
           next_state = XYS;
         else if (xe & prog & !se)
           next_state = XPS;         
         else
           next_state = IDLE;
      end
      // READ 
      XYS: begin
         if ((xe & ye & se) == 0)
           next_state = IDLE;
         else if (xys_count >= 2)//(xys_count == 2)
           next_state = READ;
      end
      
      READ: next_state = READ_READY;
      READ_READY: begin
         if (hreadyout_rise)
           next_state = READ2;
      end
      READ2: next_state = READ_READY2;
      
      READ_READY2: begin
         if (hreadyout_rise)
           next_state = IDLE;
      end
      // WRITE
      XPS: begin
         if ((xe & prog & !se) == 0)
           next_state = IDLE;
         else if (ye_rise)
           next_state = YE_PROG;
      end
      YE_PROG: begin
         if ((xe & prog & !se) == 0)
           next_state = IDLE;
         else if (prog_count == 5'd31)//(prog_count > 30)
           next_state = WRITE;
      end
      WRITE: next_state = WRITE_DONE;
      WRITE_DONE: begin         
         if (!ye)
           next_state = YE_PROG2;
      end
      YE_PROG2: begin
         if ((xe & prog & !se) == 0)
           next_state = IDLE;
         else if (prog_count == 5'd31)
          next_state = WRITE2;
      end       
      WRITE2: next_state = WRITE_DONE2;
      WRITE_DONE2: begin
         if ((xe & prog & !se) == 0)
           next_state = IDLE;
         else if (ye_fall)//(hreadyout_rise)
           next_state = IDLE;
      end
      
      default: next_state = IDLE;      
    endcase // case (state)
     end // always@ (*)

5 Replies

  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    where do all the control signals come from? are they synchronised to the clock?

  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    the control signals are inputs to the module. They are direct outputs from a mux, but the source is coming from another block which has the same clock, so they are synchronized to the clock.

    As part of my debugging, I tried replacing 'ye' if the if statement of that state to ye_reg (a registered version of the input directly in this module), but it still didn't work.

    Also, when I look at the control inputs to the module in SignalTap, they are static during the time the state changes (ye_reg included).

    As a test, I also tried to remove the if statement and make WRITE_DONE stay in that state if it reaches it. This did happen. I also replaced the 'ye' condition in WRITE_DONE with a small counter, so that it should wait to reach a count value before moving to next state - it didn't do that and just went right to YE_PROG2.

    So somehow, when I get to this state, it seems to be ignoring the 'if' statement (whatever the condition) and just passing on to the next YE_PROG2 state.

    I don't have any other idea how I can debug this.
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    Couple of things to check

    1. Make sure your signaltap clock is the same as your state machine clock

    2. Take a look at Synthesis report -> State Machines section. Check if all your states are synthesized correctly and nothing got optimized.
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    3. Add SDC constraints to ensure that SignalTap and design doesn't have timing problems

  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    I believe I found the problem in my code. I think a latch was being inferred during synthesis.

    I added 'next_state = state' before the case statement (where the next_state = IDLE is commented out) and it works now.

    I thought the default state would prevent this, but I guess not. Thanks everyone.