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

Tip/suppornt on debugging a VHDL project on Altera

Altera_Forum
Honored Contributor II
1,953 Views

Hi 

 

I have some experience on hdl coding, but none on FPGA debugging. 

(which does not necessarily mean the problem may not be in my HDL coding... ;) ) 

 

I´m facing a weird (imho) situation in which two signals are touched within an 'if' block. In simulation everything is doing fine, but when I got it programmed and running on FPGA, only one of them is touched. 

The piece of VHDL code is the following: 

 

flash_process(clk) 

begin 

if(rst='1') then 

............ 

int_flash_en <= '0'; 

etcmiv_data_rdy_detected <= '0'; 

............ 

elsif(rising_edge(clk)) then 

if (..........) then 

............ 

elsif(......) then 

if(.....) then 

..... 

else  

if((etcmiv_data_rdy = '1') and (int_flash_en = '0')) then 

etcmiv_data_rdy_detected <= '1'; 

end if; 

if((clk_spi_flash = '1') and (int_flash_en = '0') and (etcmiv_data_rdy_detected = '1'))then  

int_flash_en <= '1'; 

etcmiv_data_rdy_detected <= '0';  

........ 

.......  

else 

...... 

int_flash_en <= '0'; 

....... 

 

The only places in code where these two signals (int_flash_en and etcmiv_data_rdy_detected) are touched are listed above. When running on FPGA, I got a positive pulse on etcmiv_data_rdy_detected, but int_flash_en remains untouched ('0'). I was supposing etcmiv_data_rdy_detected should only go down together with int_flash_en assertion. Is my assumption wrong? 

Can anybody help me with some light on that? 

 

I am using Quartus II 9.1 web edition and ModelSim Altera Starter Edition 6.5b. My FPGA is a CycloneIII EP3C25Q240C8N 

 

Thanks in advance 

Cristiano
0 Kudos
13 Replies
Altera_Forum
Honored Contributor II
1,165 Views

Post the whole code, not just redacted sections. You most likely have a problem with your logic, but won't be able to tell unless everything is posted. 

 

Kevin
0 Kudos
Altera_Forum
Honored Contributor II
1,165 Views

Please post more code - the snippets you posted without indentation are rather confusing 

 

On first glance - I worry whenever I see a signal called "clk" thats being checked in an if statement rather than being used as an actual clock.
0 Kudos
Altera_Forum
Honored Contributor II
1,165 Views

Hello Cristiano, It might be better if you post your complete code to see where the problem is. From the above code you have posted, I do not see why your "int_flash_en" is not enabled when "etcmiv_data_rdy_detected" goes low. Please check your code if you have any other assignment for int_flash_en outside the process. Most likely it might be the case. all the best.

0 Kudos
Altera_Forum
Honored Contributor II
1,165 Views

Another thing I just noticed - rst isnt in the process sensitivity list, so simulations wont reset signals properly, or at least you'll get a simulation/FPGA mismatch. The FPGA will have an async reset but the simulation will have a synchronous one.

0 Kudos
Altera_Forum
Honored Contributor II
1,165 Views

Hello everybody 

 

Thanks for answering that, and sorry if my mistakes were too basic. 

 

Here follows the whole code for the process, if you may take a look. The signals are touched just after "WRITE OPERATION" comment. 

In the meantime, I´m going to check the rst in the sensitivity list and see how it works. 

 

Thanks again 

 

 

-- Flash protocol handling process 

flash_process(clk) 

begin if(rst='1') thenflash_data <= "ZZZZZZZZ"; 

flash_opcode <= X"0"; 

flash_addr <= X"000000"; 

int_flash_en <= '0'; 

flash_erase_running <= '0'; 

flash_read_running <= '0'; 

flash_write_running <= '0'; 

etcmiv_data <= "ZZZZZZZZ"; 

etcmiv_data_rdy <= 'Z'; 

etcmiv_data_rdy_detected <= '0'; 

[/INDENT] -- ERASE OPERATION 

elsif(rising_edge(clk)) thenif((etcmiv_flash_erase ='1') or (flash_erase_running= '1'))then 

[/INDENT] if(etcmiv_flash_erase ='1') then -- first time 

[/INDENT][/INDENT] flash_erase_running <= '1'; 

flash_addr <= erase_addr; 

case(int_etcmiv_opcode) is 

[/INDENT][/INDENT][/INDENT] when ERASE_INIT_PARAM_T | ERASE_DEF_PARAM_T | ERASE_AGC_T | ERASE_BPR_T => 

[/INDENT][/INDENT][/INDENT][/INDENT] flash_opcode <= ERASE_4K_OP; 

[/INDENT][/INDENT][/INDENT][/INDENT] when ERASE_NUC_T | ERASE_MENU_T => 

[/INDENT][/INDENT][/INDENT][/INDENT] flash_opcode <= ERASE_64K_OP; 

[/INDENT][/INDENT][/INDENT][/INDENT] when others => NULL; 

[/INDENT][/INDENT][/INDENT][/INDENT] end case; 

[/INDENT][/INDENT][/INDENT][/INDENT] else -- not first time, erase operation started 

[/INDENT][/INDENT] if((clk_spi_flash = '1') and (int_flash_en = '0'))then -- flash_en should change only on a sck falling edge 

[/INDENT][/INDENT][/INDENT] int_flash_en <= '1'; 

[/INDENT][/INDENT][/INDENT][/INDENT] elsif(flash_done = '1') then 

[/INDENT][/INDENT][/INDENT] int_flash_en <= '0'; 

flash_erase_running <= '0';  

end if; 

[/INDENT][/INDENT][/INDENT][/INDENT] end if; 

[/INDENT][/INDENT] -- WRITE OPERATION 

elsif((etcmiv_flash_write = '1') or (flash_write_running = '1')) then 

if(etcmiv_flash_write = '1') then -- first time 

[/INDENT] flash_write_running <= '1'; 

flash_addr <= write_addr + operation_counter; 

flash_opcode <= WRITE_FPGA_OP; 

[/INDENT][/INDENT]else -- not first time, write operation started, but wait for data_rdy 

[/INDENT] if((etcmiv_data_rdy = '1') and (int_flash_en = '0')) then 

[/INDENT][/INDENT] etcmiv_data_rdy_detected <= '1'; 

end if; 

[/INDENT][/INDENT][/INDENT] if((clk_spi_flash = '1') and (int_flash_en = '0') and (etcmiv_data_rdy_detected = '1'))then -- flash_en should change only on a sck falling edge 

[/INDENT][/INDENT] int_flash_en <= '1'; 

flash_data <= etcmiv_data; 

etcmiv_data_rdy_detected <= '0'; 

[/INDENT][/INDENT][/INDENT] elsif(flash_done = '1') then 

[/INDENT][/INDENT] int_flash_en <= '0'; 

flash_write_running <= '0'; 

[/INDENT][/INDENT][/INDENT] end if; 

[/INDENT][/INDENT] end if; 

[/INDENT] -- READ OPERATION 

elsif((etcmiv_flash_read = '1') or (flash_read_running = '1')) then 

if(etcmiv_flash_read = '1') then -- first time 

[/INDENT] flash_read_running <= '1'; 

flash_addr <= read_addr + operation_counter; 

flash_opcode <= READ_FPGA_OP; 

flash_data <= "ZZZZZZZZ"; 

[/INDENT][/INDENT] else -- not first time, read operation started 

[/INDENT] if((clk_spi_flash = '1') and (int_flash_en = '0'))then -- flash_en should change only on a sck falling edge 

[/INDENT][/INDENT] int_flash_en <= '1'; 

[/INDENT][/INDENT][/INDENT] elsif(flash_done = '1') then 

[/INDENT][/INDENT] int_flash_en <= '0'; 

flash_read_running <= '0'; 

etcmiv_data <= flash_data; 

etcmiv_data_is_ready<='1';etcmiv_data_rdy <= '0'; 

flash_data <= "ZZZZZZZZ"; 

[/INDENT][/INDENT][/INDENT] end if; 

[/INDENT][/INDENT] end if; 

[/INDENT] -- NO OPERATION 

else 

if(etcmiv_ready_to_get_data = '1') then 

[/INDENT] etcmiv_data_rdy <= '1'; 

etcmiv_data_is_ready <= '0'; 

[/INDENT][/INDENT] elsif((etcmiv_data_rdy = '1') and (etcmiv_data_rdy_dly = '1') and (flash_data = "ZZZZZZZZ")) then -- assure etcmiv_data_rdy is active and stable, to assure etcmiv already got it 

[/INDENT] etcmiv_data_rdy <= 'Z'; 

etcmiv_data <= "ZZZZZZZZ"; 

[/INDENT][/INDENT] end if; 

 

flash_data <= "ZZZZZZZZ"; 

flash_opcode <= X"0"; 

flash_addr <= X"000000"; 

int_flash_en <= '0'; 

flash_erase_running <= '0'; 

flash_read_running <= '0'; 

flash_write_running <= '0'; 

[/INDENT] end if; -- operation 

end if;  

end process; -- flash_p
0 Kudos
Altera_Forum
Honored Contributor II
1,165 Views

Hello cprodrigues, I see that there could be latches produced from the above code. This is because the signals are not assigned values in all reachable statements. Please correct that. Latches are not preferred in a very good logic design as they have unpredictable results or they generate glitches during the operation.  

In the mean time you can design a state machine that does the above job in a very nice and glitch free way. 

 

I see that int_flash_en signal will have very tight timing as you are checking the signal with in the process as well as assigning the same signal with different value. Please check your timing. This could be also a problem. all the best.
0 Kudos
Altera_Forum
Honored Contributor II
1,165 Views

 

--- Quote Start ---  

Hello cprodrigues, I see that there could be latches produced from the above code. This is because the signals are not assigned values in all reachable statements. Please correct that. Latches are not preferred in a very good logic design as they have unpredictable results or they generate glitches during the operation.  

In the mean time you can design a state machine that does the above job in a very nice and glitch free way. 

 

I see that int_flash_en signal will have very tight timing as you are checking the signal with in the process as well as assigning the same signal with different value. Please check your timing. This could be also a problem. all the best. 

--- Quote End ---  

 

 

There are no latches as it is a clocked process. When a signal is set, it's enable input is set high, with a mux selecting what input to use. 

 

I will have a look at the code, and give my thoughts. 

 

As for the reset, you probably didnt notice any difference. But you really should have it in the sensitivity list. Any inputs that affect outputs need to be in there. In the case of a clocked process, because things only change on clock edges, only the clock needs to be there.
0 Kudos
Altera_Forum
Honored Contributor II
1,165 Views

>>There are no latches as it is a clocked process.<< . Yes of course. I didn't notice the clock. How ever you might try with Tricky's suggestion, you can try to do the change and test your design.

0 Kudos
Altera_Forum
Honored Contributor II
1,165 Views

Here are my concerns: 

 

1. It looks like you're using "clk_spi_flash" in logic - is this really a clock, or is it some form of synchronised signal? This can cause all sorts of problems if it really is a clock, which wont be apparent in simulation 

 

2. You cannot compare signals to 'Z' on real hardware. What kind of logic circuit can detect that? Again, this would work fine in simulation, but not work in hardware.
0 Kudos
Altera_Forum
Honored Contributor II
1,165 Views

 

--- Quote Start ---  

As for the reset, you probably didnt notice any difference. But you really should have it in the sensitivity list. Any inputs that affect outputs need to be in there. In the case of a clocked process, because things only change on clock edges, only the clock needs to be there. 

--- Quote End ---  

 

 

Not sure if I fully understood what you mean. Regarding rst, it´s ok, I got it. But I have more signals which affect outputs there (int_etcmiv_opcode, clk_spi_flash, just to name a few). Do they have to be in there also? But I just want my process to really do something on a clk edge (it means, inside a 'if(rising_edge(clk))' block), so it may have the same behavior with or without them on sensitivity list, or not? 

 

Thanks for the support.
0 Kudos
Altera_Forum
Honored Contributor II
1,165 Views

 

--- Quote Start ---  

Here are my concerns: 

 

1. It looks like you're using "clk_spi_flash" in logic - is this really a clock, or is it some form of synchronised signal? This can cause all sorts of problems if it really is a clock, which wont be apparent in simulation 

 

2. You cannot compare signals to 'Z' on real hardware. What kind of logic circuit can detect that? Again, this would work fine in simulation, but not work in hardware. 

--- Quote End ---  

 

 

Regarding (1): Yes, it is really a clock. I need to synchronize the setting of int_flash_en with its edge. clk_spi_flash is about 4x slower than clk. Is there a better/correct way to handle this synchronizing? May it be my problem's root? 

 

Regarding (2): Ok, shame on myself... :( 

 

Yet, do you think I should try to code a state machine to ease coding and analysis? I thought it would be a simple code so I decided not to build a state machine, but it got more complex now I'm about to reconsider it. 

 

Thanks and regards
0 Kudos
Altera_Forum
Honored Contributor II
1,165 Views

 

--- Quote Start ---  

Here are my concerns: 

 

1. It looks like you're using "clk_spi_flash" in logic - is this really a clock, or is it some form of synchronised signal? This can cause all sorts of problems if it really is a clock, which wont be apparent in simulation 

 

2. You cannot compare signals to 'Z' on real hardware. What kind of logic circuit can detect that? Again, this would work fine in simulation, but not work in hardware. 

--- Quote End ---  

 

Regarding (1): Yes, it is really a clock. I need to synchronize the setting of int_flash_en with its edge. clk_spi_flash is about 4x slower than clk. Is there a better/correct way to handle this synchronizing? May it be my problem's root? 

 

Regarding (2): Ok, shame on myself... 

 

Yet, do you think I should try to code a state machine to ease coding and analysis? I thought it would be a simple code so I decided not to build a state machine, but it got more complex now I'm about to reconsider it. 

 

Thanks and regards
0 Kudos
Altera_Forum
Honored Contributor II
1,165 Views

Regarding sensitivity lists: 

 

sensitivity lists are there for simulation purposes. Synthesisors ignore them, but will probably warn you when something it missing. They tells the simulator when to re-analyse the process. Any event on the signals in the sensitivity list trigger it. 

 

This means that for a clocked process, because you only want outputs to change when the click rises, you only need to put clock in the sensitivity list. But if you wanted to build something like an asynchronous mux, you need to have all inputs in there: 

 

process(s, s0, s1); begin case s is when 0 => output <= s0; when 1 => output <= s1; end case; end process;  

 

Here, you change output whenever s changes, but also if S=0, you need the change the ouput whenever s0 changes.  

 

Now, if it was a clocked mux, you'd just have clock in there, because you only reasses "output" when the clock changes. 

 

Now to your problems: 

 

The problem with sampling clocks is that unless they are synchronised or related, they are most likely going to drift in and out of phase. So you could sample it at 0, or 1, or somewhere in between and get meta stability. Always use normal logic outputs in any other logic, never clocks or asynchronous signals. 

 

As for your question about state machines - its up to you. If it's easier for other people (and yourself when you come back to this code in 6 months time) to understand whats going on, then do it.
0 Kudos
Reply