Jump to content
  • 0

Why is my Process getting triggered with no change to the sensitivity


FlyingBlindOnARocketCycle

Question

I have built a very simple test case, built for a Basys3, in an effort to isolate my mental error.  In the VHDL below I am expecting that the process(btn) will only be triggered when the input "btn" changes.  The ila I have in place shows that the process is running continuously.  Well at least that is what I think it is showing me.  The ila shows "btn" signal remains at zero while the up_test is increasing at a rate that appears to be free running.

I must have some horrible misunderstanding about the behavior of a process with respect to its sensitivity list.

Please set me straight.

 

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use ieee.numeric_std.all;


entity btn_test is
    Port ( 
           clk_100M : in    STD_LOGIC;
           btn      : in    STD_LOGIC_VECTOR (4 downto 0);
           led      : out   STD_LOGIC_VECTOR (15 downto 0);
           seg      : out   STD_LOGIC_VECTOR (6 downto 0);
           an       : out   STD_LOGIC_VECTOR (3 downto 0);
           dp       : out   STD_LOGIC
          );
end btn_test;

architecture Behavioral of btn_test is


signal up_test		: natural := 0;
signal up_test_i	: std_logic_vector (31 downto 0);

COMPONENT ila_0
PORT (
	clk : IN STD_LOGIC;
	probe0 : IN STD_LOGIC_VECTOR(31 DOWNTO 0);
	probe1 : IN STD_LOGIC_VECTOR(4 DOWNTO 0)
);
END COMPONENT  ;

begin

up_test_i		<= std_logic_vector(to_unsigned(up_test,32));

up_test_ila : ila_0
PORT MAP (
	clk 	=> clk_100M,
	probe0 	=> up_test_i,
	probe1	=> btn
);                                

count_button_process_triggers: process(btn)
	begin
		up_test <= up_test +1;
	end process; 
 
led <= (others => '0');
seg <= (others => '0'); 
an  <= (others => '1');   
dp  <= '0';   
                
end Behavioral;

 

image.thumb.png.799bb45fa3d0894ebcf15090d9e780d6.png

Link to comment
Share on other sites

Recommended Posts

6 minutes ago, FlyingBlindOnARocketCycle said:

 I always understood why inputs to a FSM needed to be in the sensitivity list but thought I could get away with things like the code in this discussion. 

You might be using "FSM" when you mean "combinatorial logic". :-)

Link to comment
Share on other sites

7 minutes ago, hamster said:

helpfully added it to the process's sensitivity list.

WHAAAAA!!!  I didn't realize that Vivado was adding the signal to the sensitivity list for me.  That explains everything.  I'm not insane after all... just naive.  I always understood why inputs to a FSM needed to be in the sensitivity list but thought I could get away with things like the code in this discussion.  I think I need to find some in depth tutorials on FSM's

 

Thanks so much for the help

Link to comment
Share on other sites

1 hour ago, FlyingBlindOnARocketCycle said:

would a rising_edge(btn) work ?

Ok, perhaps we should all step back a bit and stop ignoring this:

 

1 hour ago, FlyingBlindOnARocketCycle said:

the simple concept of a sensitivity list appears to be over my head.

That's a good place for you to start investigating. I'd suggest a good textbook on VHDL syntax for describing digital logic behavior. Then try to understand the difference between clocked and combinatorial logic and processes. All the suggested changes to your code is unlikely to be helpful, despite everyone's best intentions, if you're not grasping the fundamental concept. If you feel as if you are baffled by what's going on then deal with that. I suggest that you learn at a pace that suits you.

I will point out that there are differences in style that a textbook won't cover. And this might be confusing if you try to follow the advise of "experienced" people. Coding styles for Xilinx synthesis tools really are slightly different than those for other vendors. But this isn't the time or place to delve into that territory.

HDLs are not all that intuitive even if you are a pro at digital design methodology. You should understand that it it possible to have a piece of logic work with an ILA attached and not work without it ( been there done that ). Simulations are great too, if you understand how they work. The best place start though, in my opinion, is to understand the HDL that you want to use. In this sense it's no different than learning a computer language. You wouldn't do that by writing whole programs and then trying to understand what the compiler gave you would you?

If you don't have a good textbook then there are places with decent tutorials on the internet that is likely to be more helpful than this forum. It seems like a reasonable proposition to me that having a bunch of well meaning "experts" argue about what they think your confusion will be fixed by is not a good substitute for study.

 

Link to comment
Share on other sites

First of all, thank you all for time and help. 

Indeed this HDL performs as I expect in simulation yet the signal runs away when implemented on the chip.

Please note that this design serves the sole purpose of proving a point to me so I could know for sure that I designed a bad process.  The fact that I would experience switch bounce and other issues was ignored in an attempt to trim this problem example down to the least possible parts.

I would like to understand all the advice I've received on this thread.  So going in order...

@hamster Yes sir you and zygot are correct in stating that I get warnings.  I get several warnings in synthesis, NO warnings  or errors in Implementation, and 2 DRC warnings.

All "regular" warnings I get are understood 

signal 'up_test' is read in the process but is not in the sensitivity list , numerous warnings about driving a port with a constant (driving led's off as I'm not using them)

What I don't know how to interpret is the Critical warning from synthesis.

Vivado says it found a timing loop and points to the entity btn_test declaration as the location of there error.  There are also a lot of errors in the out of context module run for the ila which I have no idea what to do with.

The 2 DRC are I have are, no CFGBVS value set, and the others are to do with the ila.

I agree with zygot's statement that a clocked process would work around my issues here, I had actually done that and seen it work before posting my question but, as you mentioned, the process shouldn't get triggered when btn never changes and I want understand why this bad process is bad rather than continue in my ignorance.

I don't understand what you mean by 

1 hour ago, hamster said:

you haven't defined is some way to filter out the changes of BTN

 

Also, btn is a std_logic_vector(4 downto 0)  how would a rising_edge(btn) work?

 

At the end of the day my major concern is my inability to build a finite state machine because the simple concept of a sensitivity list appears to be over my head.

I still don't comprehend why the process is triggering.

Link to comment
Share on other sites

... maybe to pick up on the last line of @hamster's post:

FPGAs have two kinds of wires, information signals and clock signals. Think of them as car lanes and bicycle lanes. You can physically drive on the wrong one and it may be even legal but usually it's not a good idea.
Using an ill-defined switch signal as clock is a bad idea. What will happen is that different parts of the circuit may interpret the ill-defined signal in a different way, and then the logic does what engineers euphemistically call "rapid disintegration" - it starts moving into many directions at the same time :).

Clock your register from a "clean" crystal clock. If you want to do it properly, add a 2nd identical register in series and flag both with "attribute ASYNC_REG". Vivado will recognize the pattern, put both physically close together, which solves (disclaimer: strictly speaking it can't be "solved" but never mind) the metastability thing.

A problem with hardware description languages is that they are much more flexible than the hardware, because they are supposed to do other things (e.g. testbenches) that aren't possible in hardware. A big part of the learning process is IMHO to make a mental inventory of the language patterns that are allowed and meaningful. Sometimes the patterns recognized by the tool are very sophisticated, e.g. inference of dual-port memory, multipliers or state machine recognition (it may even convert e.g. to one-hot encoding for performance)

 

Link to comment
Share on other sites

I have a differing view from @Zygot's

You are right - the counter shouldn't be running continuously, If you follow the language spec to the letter, your counter should change any time the state of BTN changes. That is what you should get in simulation.

However, what you haven't defined is some way to filter out the changes of BTN, such that the counter only incremented with some of the possible state changes (.e.g a "rising_edge()" clause).

When the synthesis tools try to convert your designs into hardware they are looking for either clocks or async resets or clocks to act as triggers for changes in state. The design has neither of these - it can't see that BTN should act as a dual-edged clock, so along with some warnings (I hope it gives warnings, heck, the tools give warnings for everything!) it just gives you an adder, with nothing controlling the timing of when up_test is updated.

The synthesis guys will are that this is what you want and this is what you asked for, and they will also argue that the sensitivity list is just a hint for simulation....

What you really want is something like:

btn_clk_proc : process (btn)
   begin
      if rising_edge(btn) then
         test <= test+1;
      end if;
   end process;

... but then that leads onto discussions of switch bounce, routing delays and metastabiliy. 

 

 

Link to comment
Share on other sites

3 hours ago, FlyingBlindOnARocketCycle said:

count_button_process_triggers: process(btn) begin up_test <= up_test +1; end process;

@FlyingBlindOnARocketCycle

Your problem isn't understanding sensitivity lists it understanding combinatorial logic. What's happening is that the synthesis tool is likely ( you should be able to see a message from the synthesis tool; you do read the messages don't you? ) inferring a register that isn't being clocked. You have storage but nothing regulating it. Try a clocked process with the clock ( perhaps a reset? ) in the sensitivity list. Then think about button contact bounce and what you want to do about that.

Now, extremely fast ring counters can be constructed using your technique but I suggest that you don't try that with FPGA logic.

Link to comment
Share on other sites

Archived

This topic is now archived and is closed to further replies.

×
×
  • Create New...