Programmable Devices
CPLDs, FPGAs, SoC FPGAs, Configuration, and Transceivers
20639 Discussions

FSM Caught in impossible State

Altera_Forum
Honored Contributor II
1,242 Views

Hey all, 

 

So I've been developing an FPGA (Cyclone 3 Series) that basically sits between an FX3 USB 3 micro-controller and the HPI interface of a DSP. My problem lies withing my FSM, that is responsible for managing the timing of reading and writing to the DMA buffers in the FX3. After reading data from the FX3, I need to wait until I receive a signal "mult_done", before I can write back to the FX3 as that signals the data is ready. However when the state machine reaches the point where it waits for mult_done to go high and continue to the write state, the problem occurs. The state machine seems to go to the write state (HPI_FPGA_write_to_usb), but then returns to the previous state (HPI_FPGA_wait_read_mult_done), then continues to alternate between these two states on each positive clock edge, (I've checked this using a scope and test pins). 

 

The code for my state machine is more or less as follows, let me know if I can supply any further details as I'm still fairly new to quartus. 

 

--HPI_FPGA mode state machine combo 

HPI_FPGA_mode_fsm : process(clk_ddr, reset_n) begin 

if(reset_n = '0')then 

current_HPI_FPGA_state <= HPI_FPGA_idle; 

 

elsif(clk_ddr'event and clk_ddr = '1')then 

current_HPI_FPGA_state <= next_HPI_FPGA_state; 

 

case current_HPI_FPGA_state is 

when HPI_FPGA_wait_flagb => if(flagb_d = '1' and read_writeb_mode = '1')then 

next_HPI_FPGA_state <= HPI_FPGA_wait_read_mult_done; 

elsif(read_writeb_mode = '0' and flagb_d = '1') then  

next_HPI_FPGA_state <= HPI_FPGA_write_to_usb; 

else 

next_HPI_FPGA_state <= HPI_FPGA_wait_flagb; 

end if; 

 

when HPI_FPGA_wait_read_mult_done => 

if(mult_done_sig = '1')then 

next_HPI_FPGA_state <= HPI_FPGA_write_to_usb; 

else  

next_HPI_FPGA_state <= HPI_FPGA_wait_read_mult_done; 

end if; 

 

when HPI_FPGA_write_to_usb => 

if(flagb_d = '0' or pktend_sig = '0')then 

next_HPI_FPGA_state <= HPI_FPGA_write_wr_delay; 

else  

next_HPI_FPGA_state <= HPI_FPGA_write_to_usb; 

end if; 

 

end case; 

end if; 

end process;  

 

 

I greatly appreciate any advice you can give me. 

 

Kind Regards 

Ricky
0 Kudos
9 Replies
Altera_Forum
Honored Contributor II
521 Views

Have you got a test bench?  

have you verified it works in simulation? How have you done this? 

Are all state machine inputs synchronised safely into the same clock domain? 

 

Verifiying it with scope and test pins is going to be a very slow and painful process.
0 Kudos
Altera_Forum
Honored Contributor II
521 Views

Assuming you're in hardware, you could add Signal Tap and tap the state register and input signals if you don't want/can't set up a simulation.

0 Kudos
Altera_Forum
Honored Contributor II
521 Views

Unfortunately I'm programming the FPGA through the FX3 using a Passive serial configuration so I don't have the jtag connection necessary for Signal Tap. I will try and do up a test bench for simulation purposes. 

 

I have checked and all the inputs are indeed synced to the same clock, the state machine works fine under normal operation without the "wait_read_mult_done" state included. 

 

Thanks for the reply's
0 Kudos
Altera_Forum
Honored Contributor II
521 Views

 

--- Quote Start ---  

 

 

--HPI_FPGA mode state machine combo HPI_FPGA_mode_fsm : process(clk_ddr, reset_n) begin if(reset_n = '0')then current_HPI_FPGA_state <= HPI_FPGA_idle; elsif(clk_ddr'event and clk_ddr = '1')then current_HPI_FPGA_state <= next_HPI_FPGA_state; case current_HPI_FPGA_state is . . . when HPI_FPGA_wait_read_mult_done => if (mult_done_sig = '1') then next_HPI_FPGA_state <= HPI_FPGA_write_to_usb; else next_HPI_FPGA_state <= HPI_FPGA_wait_read_mult_done; end if; . . end case; end if; end process;  

 

--- Quote End ---  

 

 

It would have been clearer if we could see the exact (complete) code, instead of an excerpt. 

As it looks here, you have a current_state and a next_state, but both are inside a clocked process, which delays the actual assignment by one clock, and that can't be good. You have to either export the 'case/endcase' code to a separate combinatorial process (which I prefer (I will catch some flak for saying this)) or directly assign current_state in the transitions. 

 

Regards, 

Josy
0 Kudos
Altera_Forum
Honored Contributor II
521 Views

For some reason after I changed the signal that the wait_read_mult_done state was dependant on, the FSM now works. I guess the mult_done_sig only being high for 1 clock cycle wasn't long enough for the state machine to capture it? 

 

Also thanks for the advice on assigning current/next states, I will definitely take that on board now! 

 

Kind Regards 

Ricky Thomson
0 Kudos
Altera_Forum
Honored Contributor II
521 Views

 

--- Quote Start ---  

For some reason after I changed the signal that the wait_read_mult_done state was dependant on, the FSM now works. I guess the mult_done_sig only being high for 1 clock cycle wasn't long enough for the state machine to capture it? 

--- Quote End ---  

 

 

This would only be the case if the mult_done_sig was not synchronised properly into the same clock domain as the state machine, Or it failed timing (and you havent checked timing)
0 Kudos
Altera_Forum
Honored Contributor II
521 Views

 

--- Quote Start ---  

This would only be the case if the mult_done_sig was not synchronised properly into the same clock domain as the state machine, Or it failed timing (and you havent checked timing) 

--- Quote End ---  

 

 

No, Tricky, that is not the case here. Perhaps read my previous post?
0 Kudos
Altera_Forum
Honored Contributor II
521 Views

Actually yes - it would need to be high for 2 clocks to work properly.

0 Kudos
Altera_Forum
Honored Contributor II
521 Views

 

--- Quote Start ---  

Actually yes - it would need to be high for 2 clocks to work properly. 

--- Quote End ---  

 

 

I'd rather say there is a design error: because next_state is registered before being assigned to current_state, making mult_sig_done high for 2 clocks is 'plastering over the cracks'. But you can have the last word ...
0 Kudos
Reply