Comparing a variable to a value in VHDL? - Page 1
Forum section: electronics / general

author: betocool
author_rank: Regular Contributor
timestamp: December 14, 2022, 01:39:30 am
content: Hello all,I'm using Quartus 20.1 (command line mostly) to synthesize, fit, assemble, etc, a project. I decided to start using the "variable" keyword to keep some values within a process:QuoteSo far so good. Now I'm trying to compare the "pulse_cnt" variable to a fix value:QuoteBut I'm getting this error when trying to synthesize:Code:Error (10327): VHDL error at some_hw.vhd(169): can't determine definition of operator ""="" -- found 0 possible definitions File: some_hw.vhd Line: 169I tried to find the correct way of doing it (other to change the variable to a signal at the beginning of the architecture) but I'm clueless.What am I missing here?Appreciate the help.Cheers,Alberto

author: SiliconWizard
author_rank: Super Contributor
timestamp: December 14, 2022, 02:03:45 am
content: The 'd' prefix with bit strings is part of VHDL-2008, so first make sure you have a tool that supports VHDL-2008 or above.I'm not sure you can use decimal bit strings properly without specifying the bit width, which is also part of VHDL-2008.Try:Code:if pulse_cnt = 12d"2199" theninstead.Note that parentheses are not needed in if-then clauses in VHDL. People adding parentheses is usually a sign of them having used too much C and/or Verilog. VHDL is based on Ada.If the above fails, possibly your tool doesn't fully support VHDL-2008. In which case, use the following instead:Code:if pulse_cnt = to_unsigned(2199, pulse_cnt'length) then

author: betocool
author_rank: Regular Contributor
timestamp: December 14, 2022, 02:05:18 am
content: I'm such a numpty... apologies to allIt was the statement above that was failing... Once I learn to read, all will be well.Code:if (usec_pulse = 1) thenWas missing the inverted commas...Everything works as expected.Cheers,Alberto

author: Daixiwen
author_rank: Frequent Contributor
timestamp: December 14, 2022, 11:15:47 am
content: The numeric_std library defines the = operator for any combination of unsigned and natural, so you can in fact just writeCode:if pulse_cnt = 2199 thenand it should work without having to worry to write the value as a vector of the right size.

author: rstofer
author_rank: Super Contributor
timestamp: December 14, 2022, 04:39:39 pm
content: Would it work, and possibly be easier on hardware, to preload 2199 and count down toward 0?

author: betocool
author_rank: Regular Contributor
timestamp: December 14, 2022, 11:31:14 pm
content: Thanks to all,now that I fixed the statement that was actually wrong, all other suggestions work fine.Cheers,Alberto

author: betocool
author_rank: Regular Contributor
timestamp: December 15, 2022, 08:29:23 am
content: Slightly off topic here, but a little help would be very welcome...I was working with variables, e.g.:Code:variable pulse_delay : unsigned(23 downto 0) := (others => '0');Then I started running a simulation with Modelsim. However, I noticed a particular condition was not being activated when it happened, e.g:Code:pulse_cnt := pulse_cnt + 1;if pulse_cnt = 2199 thenpulse_cnt := (others => '0');end if;Basically it was counting upwards from 2200. I then remembered from somewhere in the depths of my head that some programs were very succeptible to having all the correct variables in the process sensitivity list:Code:process pulse_counter : process(clk_in, rising_edge, reset, usec_pulse)variable pulse_delay : unsigned(23 downto 0) := (others => '0');But I did not have "pulse_delay" in the sensitivity list, as it was defined in the process.Later I changed "pulse_delay" to signal, outside the process, included it in the list, and suddenly it works as expected...How sensitive (pardon the pun) are compilers to signals in the sensitivity list? I'd heard that was a thing of the past kind of...Cheers,Alberto

author: rstofer
author_rank: Super Contributor
timestamp: December 15, 2022, 03:58:03 pm
content: Quote from: betocool on December 15, 2022, 08:29:23 amFor simulation, the sensitivity list tells the simulator which signals to watch in terms of kicking off evaluation.For synthesis, as I understand it, the sensitivity list is meaningless.In VHDL, the following is legal and no actual signal names are included in the list:Code:process (all)https://insights.sigasi.com/tech/wildcard_sensitivity/Even so, some compilers whine and snivel about missing signals in the sensitivity list. I suppose that is to help out the simulator.

author: jziegler
author_rank: Newbie
timestamp: December 15, 2022, 05:59:25 pm
content: Note that process(all) is only valid in VHDL 2008, not in previous versions.Quote from: betocool on December 15, 2022, 08:29:23 amI suspect that the difference you are seeing is due to the timing differences in assigning variables and signals in VHDL. Remember that variables change immediately while signals change based on a delta cycle. There may be a difference caused by that.Quote from: Daixiwen on December 14, 2022, 11:15:47 amBe careful with the numeric_std, it is not a library defined as part of the IEEE standards, so it may not function the same way on all simulators and synthesis tools. I also advise against these comparisons since it makes it easier to get a mismatch in types. While using the standard conversions going through signed and unsigned is extra work, it also ensures that you don't accidentally compare values of different types.And back to the OP, why not just use an integer for the variable/signal in the first place? Us an integer with the same range (range 0 to 2 ** 12 - 1) so that it does not implement as a 32-bit signed value. The only potential downside to this is that you need to deal with value wrapping differently, but when counting up that can be done with the mod operator.

author: SiliconWizard
author_rank: Super Contributor
timestamp: December 15, 2022, 07:26:46 pm
content: Quote from: betocool on December 15, 2022, 08:29:23 amYou may want to explain the link between 'pulse_delay' and 'pulse_cnt', so we don't waste yet another round.Quote from: betocool on December 15, 2022, 08:29:23 amA few points.1. Sensitivity lists do matter for simulation, this is actually the only context (at least for usual tools) where they matter. Sensitivity lists are ignored for synthesis. This is one point to be wary of.2. Sure there is the 'all' keyword (in VHDL-2008+) to circumvent that, but I don't particularly recommend using it. A detailed sensitivity list acts as a documentation tool for your code, so I prefer using them. Remember the code your write must be readable and understandable to humans.3. As to variables, you have me confused here. Regular variables can't be used outside of processes, so they can't belong in sensitivity lists. To define variables at a higher level, you need to use *shared* variables. I don't really recommend shared variables though, unless you really know what your are doing and why you need them.

author: betocool
author_rank: Regular Contributor
timestamp: December 15, 2022, 11:48:46 pm
content: Thanks for the replies.And sorry about the confusion! Both "pulse_cnt" and "pulse_delay" were variables, both were "misbehaving". Both were changed to signals.Code:variable pulse_delay : unsigned(23 downto 0) := (others => '0');variable pulse_cnt : unsigned(11 downto 0) := (others => '0');I see what you guys say about simulators and sensitivity lists. I will err on the side of caution and add them, it really isn't that big of a problem.Quote from: jziegler on December 15, 2022, 05:59:25 pmI'm not sure what you mean by that? They change immediately in simulation, synthesis or both?Cheers,Alberto

author: Daixiwen
author_rank: Frequent Contributor
timestamp: December 20, 2022, 10:24:35 am
content: Quote from: jziegler on December 15, 2022, 05:59:25 pmI think you are confusing numeric_std with std_logic_(un)signed.numeric_std is a standard IEEE library, it is the one that defines the signed and unsigned types.It is not recommended to use std_logic_(un)signed because is it not standard, and adds confusion by directly overloading the operators on std_logic_vector with signed/unsigned operations.Using numeric_std on the other hand is recommended, and using the operators directly with naturals or integers doesn't create any mismatch. The operators on unsigned can also use naturals, and the operators on signed can also use integers. Those are entirely defined in the VHDL standard and work very well on all tools.I personally findCode:if pulse_cnt = 2199 theneasier to read thanCode:if pulse_cnt = to_unsigned(2199, pulse_cnt'length)orCode:if pulse_cnt = 12d"2199" thenIn addition the latter will cause problems if you suddenly decide to change the size of pulse_cnt. And not all tools will create a warning in case of size mismatch (or in the case of Quartus, will just bury it within 2000 other warnings)