- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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 RickyLink Copied
9 Replies
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
--- 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
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
--- 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)
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
--- 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?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Actually yes - it would need to be high for 2 clocks to work properly.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
--- 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 ...
Reply
Topic Options
- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page