Intel® Quartus® Prime Software
Intel® Quartus® Prime Design Software, Design Entry, Synthesis, Simulation, Verification, Timing Analysis, System Design (Platform Designer, formerly Qsys)
16682 Discussions

Quartus not synthesizing my FSM right?

Altera_Forum
Honored Contributor II
1,393 Views

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@ (*)
0 Kudos
5 Replies
Altera_Forum
Honored Contributor II
668 Views

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

0 Kudos
Altera_Forum
Honored Contributor II
668 Views

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.
0 Kudos
Altera_Forum
Honored Contributor II
668 Views

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.
0 Kudos
Altera_Forum
Honored Contributor II
668 Views

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

0 Kudos
Altera_Forum
Honored Contributor II
668 Views

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.
0 Kudos
Reply