+ Post New Thread
Results 1 to 12 of 12
  1. #1
    Newbie level 3
    Points: 27, Level: 1

    Join Date
    Jun 2019
    Posts
    4
    Helped
    0 / 0
    Points
    27
    Level
    1

    Output <= registers(to_integer(address)) and intentional meta values

    Hi,
    I have an array of std_logic_vectors. The address selector (unsigned type) may intentionally be unsigned to don't care/unknown state in order to simplify logic in other parts of a design. In such a case, the simulator will generate a warning, however, the output vector will be assigned to registers(0). My intention, in such a case, would be to assign don't care/unknown state also to the output vector. Is there any best practice for this problem?
    I know that something like:
    Code:
    output <= (others => '-') when is_x(address) else registers(to_integer(address));
    could work, but according to my knowledge, the is_x function may have a problem with synthesis.

    Another option would be to write a process:

    Code:
    mux: process(all)
    begin
      output <= (others => '-');
      for i in registers'range loop
        if address = to_unsgined(i, address'range) then
          output <= registers(i);
        end if;
      end loop;
    end process;
    However, I am worried that the synthesis tool may have an issue to extract a proper and simple mux from this description.

    Is there any more straightforward description? I am using VHDL 2008.

    Regards,
    Adrian

  2. #2
    Advanced Member level 5
    Points: 23,602, Level: 37
    barry's Avatar
    Join Date
    Mar 2005
    Location
    California, USA
    Posts
    4,527
    Helped
    996 / 996
    Points
    23,602
    Level
    37

    Re: Output <= registers(to_integer(address)) and intentional meta values

    I don’t understand why you would INTENTIONALLY assign ‘don’t care’’, or why it would ‘simplify logic’. I don’t even think that’s syntesizable (I’ve never tried it). Why don’t you just have a default case?



    •   AltAdvertisement

        
       

  3. #3
    Newbie level 3
    Points: 27, Level: 1

    Join Date
    Jun 2019
    Posts
    4
    Helped
    0 / 0
    Points
    27
    Level
    1

    Re: Output <= registers(to_integer(address)) and intentional meta values

    I am assigning don't care values in order to give more room for a synthesis tool. As an example, if you have data accompanied by a valid strobe, forcing them eg. to 0 when the strobe is not active, may not be the best from logic utilization point of view. You still need to assign something in order to avoid latches. The synthesis tool may decide that the most efficient is to assign data (when not used) to some pattern which occurs also when there is a valid strobe on the bus.



    •   AltAdvertisement

        
       

  4. #4
    Advanced Member level 3
    Points: 7,131, Level: 20
    Achievements:
    7 years registered

    Join Date
    Jul 2010
    Location
    Sweden
    Posts
    939
    Helped
    367 / 367
    Points
    7,131
    Level
    20

    Re: Output <= registers(to_integer(address)) and intentional meta values

    A better way is to do the normal assignments to "output" regardless of the valid bit. That will minimize the logic, and the result is predictable.

    A similar approach can be used for processes to minimize the logic when not all signals need to be resetted:

    Code:
    Async reset:
    
    process(clock, reset)
      if rising_edge(clock) then
        -- Do the normal stuff here, don't care about the reset signal
      end if;
    
      if reset = '1' then
        -- Set/reset only the signals that really need to be defined after reset
      end if;
    end process;
    
    
    Sync reset:
    
    process(clock, reset)
      if rising_edge(clock) then
        -- Do the normal stuff here, don't care about the reset signal
    
        if reset = '1' then
          -- Set/reset only the signals that really need to be defined after reset
        end if;
      end if;
    end process;
    With the standard template, the synthesis tool must implement logic to keep the current value at reset for the signals that are missing in the reset part.


    1 members found this post helpful.

    •   AltAdvertisement

        
       

  5. #5
    Newbie level 3
    Points: 27, Level: 1

    Join Date
    Jun 2019
    Posts
    4
    Helped
    0 / 0
    Points
    27
    Level
    1

    Re: Output <= registers(to_integer(address)) and intentional meta values

    Sorry, I don't get your point.
    What do you mean by normal assignment of the "output" vector?
    The code:
    Code:
    output <= registers(to_integer(address))
    will synthesise to a valid implementation.

    As you see, I want to have a fully combinatorial logic (multiplexer). The address is a combinatorial output of the Mealy FSM. For some states of this FSM, in order to simplify FSM's logic, this address is assigned to don't care/unknown value. Now, in order to mimic hardware, the output vector of the above description should be assigned with a don't care/unknown value as well for the unknown address. However, to_integer will return 0 for vector containing meta values, which will be a valid choice of some register. It will create mismatch (source of potential, unnoticed bugs) between the behavioural verification and the actual hardware implementation.



  6. #6
    Advanced Member level 3
    Points: 7,131, Level: 20
    Achievements:
    7 years registered

    Join Date
    Jul 2010
    Location
    Sweden
    Posts
    939
    Helped
    367 / 367
    Points
    7,131
    Level
    20

    Re: Output <= registers(to_integer(address)) and intentional meta values

    Ok, I think I understand now.
    There are two problems here:

    1. How to write code to minimize the synthesized logic, maybe using '-' assignments

    2. How to write code so "don't care" ('-') or "unknown" ('X') signals propagate to 'X' on the outputs in simulation

    For point 1, I understand that you have paths in the state machine code for which it doesn't matter what value is assigned to an output signal.
    You are correct that having no assignment creates logic to keep the current value. By assigning the value '-' (don't care), you tell the synthesis tool that any value is OK.
    The tool can use a fixed '0' or '1', but also a value that depends on other signals.
    In theory, this should give the synthesis tool more options to minimize the required logic.
    The problem is that output signals that depend on such a signal will normally show up as 'X' in the simulation (which you actually want in this case).
    I don't assign '-' to minimize logic, since if 'X' outputs are allowed, the risk is much higher that you miss a signal that should not be 'X'. Normally I consider an 'X' output as an error.
    I often have a default assignment at the beginning of a process, with the most probable value. I then override that with a new assignment when necessary.
    Maybe not the absolute minimum logic, but a very predictable result and no 'X' outputs in simulation.

    Now to point 2, where you really want to output 'X' for signals that depend on a "don't care" signal.
    In your example, the 'X' disappears in the to_integer function, but an optional "metavalue" warning will be generated by the simulator.
    If the mux have a fixed size, it is easy to do your own with a "case" and an "others" that assigns 'X' to the outputs:
    Code:
    mux: process(all)
      case address is
        when "000" =>
          output <= registers(0);
        when "001" =>
          output <= registers(1);
        when "010" =>
          output <= registers(2);
        when "011" =>
          output <= registers(3);
        when "100" =>
          output <= registers(4);
        when "101" =>
          output <= registers(5);
        when "110" =>
          output <= registers(6);
        when "111" =>
          output <= registers(7);
        when others =>
          output <= (others => 'X');
      end case;
    end process;
    I know that the code above will work. The synthesis tool will ignore the "others" clause if all combinations of '0' and '1' are covered by the earlier "when" clauses.
    It is possible that you can write a more generic loop that does the same thing, but I have not tried that with any synthesis tool.

    One more thing about the synthesizeable code:
    Only use '-' assignments to make optimizations possible for the synthesis tool. This means that you should probably never use '-' as stimuli in a test bench. Assign 'X' in the test bench if you want to see what depends on a signal.
    To indicate an unknown output in simulation, assign 'X'. Only do that when all possible combinations of inputs with only '0' and '1' have been covered with other assignments, then the 'X' assignment will be ignored by the synthesis tool.

    '-' is "don't care", used by the synthesis tool and the simulator. IMHO, don't use it in a test bench, only in the synthesizeable code.
    'X' is "unknown", used only by the simulator.



  7. #7
    Newbie level 3
    Points: 27, Level: 1

    Join Date
    Jun 2019
    Posts
    4
    Helped
    0 / 0
    Points
    27
    Level
    1

    Re: Output <= registers(to_integer(address)) and intentional meta values

    Yes, you understand correctly the problem.

    In the meantime, I solved the issue with my original idea:
    Code:
    output <= registers(to_integer(address)) when not Is_X(address) else (others => 'U');
    I checked results generated by the synthesis tool, and it seems that it properly ignores (set False) Is_X branch and the generated netlist is equivalent to simple
    Code:
    output <= registers(to_integer(address));



  8. #8
    Super Moderator
    Points: 257,530, Level: 100
    Awards:
    1st Helpful Member

    Join Date
    Jan 2008
    Location
    Bochum, Germany
    Posts
    44,940
    Helped
    13665 / 13665
    Points
    257,530
    Level
    100

    Re: Output <= registers(to_integer(address)) and intentional meta values

    and the generated netlist is equivalent to simple
    output <= registers(to_integer(address));
    Means there's no synthesis advantage?



    •   AltAdvertisement

        
       

  9. #9
    Advanced Member level 3
    Points: 7,131, Level: 20
    Achievements:
    7 years registered

    Join Date
    Jul 2010
    Location
    Sweden
    Posts
    939
    Helped
    367 / 367
    Points
    7,131
    Level
    20

    Re: Output <= registers(to_integer(address)) and intentional meta values

    Quote Originally Posted by adrianf0 View Post
    output <= registers(to_integer(address)) when not Is_X(address) else (others => 'U');
    You should assign 'X', not 'U'.
    'U' is the default value for std_logic, and if you see it in simulation, it means that the signal has never been assigned anything.
    You break this convention if you assign 'U'.



  10. #10
    Advanced Member level 3
    Points: 7,131, Level: 20
    Achievements:
    7 years registered

    Join Date
    Jul 2010
    Location
    Sweden
    Posts
    939
    Helped
    367 / 367
    Points
    7,131
    Level
    20

    Re: Output <= registers(to_integer(address)) and intentional meta values

    Quote Originally Posted by FvM View Post
    Means there's no synthesis advantage?
    I think the OP already was satisfied with the synthesized logic for creation of the "address" signal.
    This thread was started because the simulation would not show which output bits were unknown. registers(0) was used when address contained "unknown" or "don't care" bits.
    It is bad if the RTL simulation says '0' when the synthesized circuit says '1'.



  11. #11
    Advanced Member level 4
    Points: 6,108, Level: 18

    Join Date
    Feb 2015
    Posts
    1,003
    Helped
    284 / 284
    Points
    6,108
    Level
    18

    Re: Output <= registers(to_integer(address)) and intentional meta values

    you always have pragma tricks for this as well.
    eg:
    Code:
    constant kWhatever : std_logic := 
    -- synthesis translate_off
    'X' when true else
    -- synthesis translate_on
    '-';
    
    -- other code
    
    output <= registers(to_integer(address)) when condition_where_i_care = '1' else (others => kWhatever);
    --edit: also, I'm not sure this is a common use case as Verilog doesn't have a don't care symbol and even in VHDL it isn't common knowledge that '-' is a thing. I suspect synthesis tools convert 'X', 'U', and '-' to either '0' or 'Z' based on tech. I wouldn't expect '-' to be beneficial unless the synthesis tool vendor specifically mentions it somewhere in documentation.

    --edit2: fixed syntax. I haven't written VHDL in a while.
    Last edited by vGoodtimes; 22nd June 2019 at 19:04.



  12. #12
    Newbie level 4
    Points: 241, Level: 2

    Join Date
    Jun 2018
    Posts
    6
    Helped
    0 / 0
    Points
    241
    Level
    2

    Re: Output <= registers(to_integer(address)) and intentional meta values

    The synthesis tool will usually ignore is_x and will give it as a warning.



--[[ ]]--