1
votes

I have an address counter in a VHDL sequential process. Its idle value is set in a configuration register to a certain max value; afterwards, anytime it enters a certain state it should increment by one.

To get the maximum value, I declare a subset of an input std_logic_vector as an alias.

I declared address_int as an unsigned variable. I then defined a sequential process with a clk and a reset in the sensitivity list. When the reset is asserted, the address counter is set to the alias value. After reset is released, the counter is rolled over/incremented on rising edges when in a certain state.

The synthesis tool gives me this message: *WARNING:Xst:819 line 134: The following signals are missing in the process sensitivity list: DL_CADU_SIZE*

And all the address lines have become asynchronous signals! What is going on here? Is there some strange behavior with unsigned that doesn't occur with integers? I usually use integers here, but the conversion seemed more straightforward from unsigned for purposes of code maintenance. I have tried ditching the alias and doing the straight conversion, but it didn't help.

library IEEE;            
use ieee.std_logic_1164.a
use ieee.numeric_std.all;
-- entity declaration, ports, architecture, etc.

signal address_int : unsigned(8 downto 0);                                     
alias  aMaxWords   : std_logic_vector(8 downto 0) is DL_CADU_SIZE(10 downto 2);

begin
  WADDR           <= std_logic_vector(address_int);

  OUT_PROC: process (CLK_CORE, RST_N_CORE)
    begin
      if RST_N_CORE = '0' then
        address_int <= unsigned(aMaxWords);
      elsif rising_edge(CLK_CORE) then

        if next_state = WRITE_WORD then
          if address_int = unsigned(aMaxWords) then
            address_int <= (others => '0');
          else
            address_int <= address_int + 1;
          end if;
        end if; -- WRITE_WORD
      end if; -- rising_edge
    end process OUT_PROC;
end RTL;
2
Found part of the problem; synth couldn't tell my input value was synchronous because it wasn't registered in this module. Changing the address_int counter to an integer made the process sensitivity warning disappear, but address_int remained asynchronous. The full solution was to make my max value a constant instead of an input. I guess the question still remains, though; why does the synthesizer complain when the counter is an unsigned, but it silently accepts the asynchronicity when the counter is an integer?NickD

2 Answers

0
votes

This:

if RST_N_CORE = '0' then
    address_int <= unsigned(aMaxWords)

describes an async reset - therefore aMaxWords will be treated as asynchronous by the synthesiser irrespective of whether it is or not.

What the synthesiser interprets your code as is "while rst_n_core is low, copy the value of aMaxWords to address_int" so if aMaxWords changes during reset, the value must be copied across. The lack of that signal in your sensitivity list means that the synthesiser is making a circuit which behaves differently to what the language says it should, hence the warning.


It really shouldn't do this: without the signal in the sensitivity list, it ought to capture the signal on the falling edge of the reset line. But as that's not how most chips work, the synthesiser designers (in their infinite wisdom) decided many years ago to assume the designer intended to have that signal in the sensitivity list, and issue a warning, rather than saying "this can't work, fix it". So then you get code which works differently in simulation and synthesis. End rant.

-1
votes

Your reset code:

if RST_N_CORE = '0' then
    address_int <= unsigned(aMaxWords);

is wrong. The definition of reset is set your circuit to known-state. But your code assign it to a signal. You should assign it as all 0 or all 1 for reset, or your aMaxWords must be constant (note that your synthesizer may be not enough intellegent for known it, then should assign it as constant) :

if RST_N_CORE = '0' then
    address_int <= (others => '0');

or

if RST_N_CORE = '0' then
    address_int <= (others => '1');