2
\$\begingroup\$

I was looking in the internet and stackexchange for the solution but still I don't know why it is not working. Solutions which I found here shall work but probably I am still doing something wrong.

I am writing VHDL 'code'. I have in my design INOUT ports. In libero soc synthesis and compilation works fine. Now I would like to simulate my design and here is the problem. I am using Mentor Graphics ModelSim. During compilation testbench I have an error

Nonresolved signal 'data' has multiple sources.

architecture architecture_max11046_interface_tb of max11046_interface_tb is

component max11046_interface is
    port (
        -- Clock and resets
        i_clk           : in std_ulogic;
        i_rst_asyn      : in std_ulogic;
        i_rst_syn       : in std_ulogic;

        -- Max11046 interface
        o_cs        : out std_ulogic;
        o_wr        : out std_ulogic;
        o_rd        : out std_ulogic;
        o_convst    : out std_ulogic;
        o_shdn      : out std_ulogic;
        i_eoc       : in  std_ulogic;
        io_data      : inout  std_ulogic_vector(15 downto 0)
    );
end component;


-- input signals
signal eoc:    std_ulogic := '1';
signal data:   std_ulogic_vector(15 downto 0) := x"ABAB";

-- signals
signal rst: std_ulogic := '0';
signal clk: std_ulogic := '0';

signal ADC_Data: std_ulogic_vector(15 downto 0);
begin
    Conversion_end: process
    begin
        wait until convst = '1';
        wait for 500 NS;
        eoc <= '0';
    ADC_Data <= x"ABCD";
        wait for 50 NS;
        eoc <= '1';
    end process;

    data <= ADC_Data when eoc = '0' else (others => 'Z');        

    max11046: max11046_interface
        port map (
            i_clk       => clk,
            i_rst_asyn  => '1',
            i_rst_syn   => rst,
            o_cs        => cs,
            o_wr        => wr,
            o_rd        => rd,
            o_convst    => convst,
            o_shdn      => shdn,
            i_eoc       => eoc,
            io_data      => data
        );

 end architecture_max11046_interface_tb;

I've deleted some part of code to make it easier to read. My question is what can be wrong. Can not I drive internal signal from multiple sources ? In the design I am doing it like this with ports and it is working:

data <= ADC_Data when eoc = '0' else (others => 'Z');

when i am not writing to the port it is in high impedance and i can read data.

P.S. I don't want to use std_logic_vector instead of std_ulogic_vector.

\$\endgroup\$
1
  • 1
    \$\begingroup\$ Are you referencing all of the required libraries? "Nonresolved" suggests to me that the compiler can't figure out the exact type of data. \$\endgroup\$ – Dave Tweed Jun 9 '17 at 11:20
2
\$\begingroup\$

You're trying to create a tri-state signal on 'data' of unresolved type std_ulogic_vector. The 'unresolved' means that it doesn't use a resolution function when establishing the value of a signal (i.e. a 'signal' or 'port').

A resolution function takes the value from each of the sources onto a signal and resolves them all into a single assignment value.

So the unresolved datatype you have selected only allows one source, by definition. The solution is to use a resolved type because they deal with multiple sources onto a single signal, which is what you wanted to implement.

The typical resolved types here are std_logic and std_logic_vector instead. (You don't explain why you don't want to use them, only that you don't.)

Incidentally, the initial values on your signals don't constitute another source. They're just values your simulator will start off with in the signals. In their absence, your simulator would put 'U's on the signals you have.

\$\endgroup\$
2
  • \$\begingroup\$ As a little correction: The resolution resolves multiple sources, not drivers. Only signals can be resolved (that includes ports, because ports are signals) \$\endgroup\$ – Paebbels Jun 10 '17 at 9:19
  • \$\begingroup\$ Thanks @Paebbels, fixed. Kept ports distinguished from signals though, clearer for OP. \$\endgroup\$ – TonyM Jun 10 '17 at 9:55
1
\$\begingroup\$

The TL;DR explanation

Multiple drivers require resolution to determine the effective value of a signal.

IEEE Std 1076-2008 6.4.2.3 Signal declarations, paragraph 8:

A signal may have one or more sources. For a signal of a scalar type, each source is either a driver (see 14.7.2) or an out, inout, buffer, or linkage port of a component instance or of a block statement with which the signal is associated. For a signal of a composite type, each composite source is a collection of scalar sources, one for each scalar subelement of the signal. It is an error if, after the elaboration of a description, a signal has multiple sources and it is not a resolved signal. It is also an error if, after the elaboration of a description, a resolved signal has more sources than the number of elements in the index range of the type of the formal parameter of the resolution function associated with the resolved signal.

sources makes resolution hierarchical -

13 Design units and their analysis, 13.1 Design units, paragraph 1:

Certain constructs are independently analyzed and inserted into a design library; these constructs are called design units. One or more design units in sequence comprise a design file.

A component that is instantiated represents an external block (3.1), a design unit is comprised of a a context clause (which may be empty) and a library unit, either a primary unit (e.g. entity declaration) or secondary unit (e.g. a matching architecture).

You can't determine all the actual drivers until elaboration. Ports are signals for this reason.

14.7.3 Propagation of signal values, 14.7.3.1 General, paragraph 5:

The kernel process determines two values for certain signals during certain simulation cycles. The driving value of a given signal is the value that signal provides as a source of other signals. The effective value of a given signal is the value obtainable by evaluating a reference to the signal within an expression. The driving value and the effective value of a signal are not always the same, especially when resolution functions and conversion functions or type conversions are involved in the propagation of signal values.

A port signal provides the effective value for all the sources (drivers and ports of mode out, inout, buffer or linkage) contributing to the effective value of that port signal. Ports can be read or evaluated when resolving the value of an elaborated net:

6.5.2 Interface objects, paragraph 9 and 10 (in part):

An interface object provides a channel of communication between the environment and a particular portion of a description. The value of an interface object may be determined by the value of an associated object or expression in the environment; similarly, the value of an object in the environment may be determined by the value of an associated interface object. The manner in which such associations are made is described in 6.5.7.

The value of an object is said to be read when one of the following conditions is satisfied:

— When the object is evaluated, and also (indirectly) when the object is associated with an interface object of the modes in, inout, or linkage.

...

The key here is that there are multiple drivers (multiple sources) for data in your testbench -

14.7.2 Drivers, paragraph 1:

Every signal assignment statement in a process statement defines a set of drivers for certain scalar signals. There is a single driver for a given scalar signal S in a process statement, provided that there is at least one signal assignment statement in that process statement and that the longest static prefix of the target signal of that signal assignment statement denotes S or denotes a composite signal of which S is a subelement. Each such signal assignment statement is said to be associated with that driver. Execution of a signal assignment statement affects only the associated driver(s).

14.2 Elaboration of a design hierarchy, paragraph1:

The elaboration of a design hierarchy creates a collection of processes interconnected by nets; this collection of processes and nets can then be executed to simulate the behavior of the design.

and concurrent statements (including internal and external blocks) are elaborated as block statements and/or block statements and processes (11. Concurrent statements). Signal assignment is guaranteed to take place in a process statement, resolution is required with multiple sources.

That requires resolved data types with resolution functions.

4.6 Resolution functions, paragraph 1:

A resolution function is a function that defines how the values of multiple sources of a given signal are to be resolved into a single value for that signal. Resolution functions are associated with signals that require resolution by including the name of the resolution function in the declaration of the signal or in the declaration of the subtype of the signal. A signal with an associated resolution function is called a resolved signal (see 6.4.2.3).

6.4.2.3 Signal declarations, paragraph 3:

If a resolution indication appears in the subtype indication in the declaration of a signal or in the declaration of the subtype used to declare the signal, then each resolution function in the subtype is associated correspondingly with the declared signal or with a subelement of the declared signal. Such a signal or subelement is called a resolved signal.

For std_logic or std_logic elements the resolution function is provided in package std_logic_1164 in the std_logic subtype declaration. std_ulogic (the element type of std_ulogic_vector) is not a resolved type.

All this boils down to not being able to use std_ulogic_vector as the type for data which requires a resolved element type.

You're also missing declarations for signals convst, cs, wr, rd, and shdn.

\$\endgroup\$
-2
\$\begingroup\$

@TonyM I couldn't fully agree with you. Std_ulogic_vector or std_ulogic is unresolved signal but you could work with it like in the code

data <= ADC_Data when eoc = '0' else (others => 'Z');   

when it is not used as output it will be in high impedance and will be no problem with resolution.

In this way user user knows exactly what he is doing. In synopsys synplify it will be no problem with synthesis if code is written like this.

Correct me if I'm wrong but I was using std_ulogic like this and it was working fine.

Like you said initial values are only for simulation.

\$\endgroup\$
3
  • 1
    \$\begingroup\$ A synthesis tool that did not treat it as an error would not be compliant with the VHDL standard and might lack portability. You could also note that there is an assignment to data of 'Z's in the aggregate expression in the testbench (used for simulation). Your answer should perhaps be a comment? \$\endgroup\$ – user8352 Jun 12 '17 at 8:57
  • \$\begingroup\$ I could not comment other people comments, still to low reputation score :) Thanks for your answer! \$\endgroup\$ – e2p Jun 12 '17 at 9:33
  • \$\begingroup\$ Not true, please re-read definition of resolution function. In VHDL, high impedance (i.e. Z) is a source and multiple sources require resolution. OP's question was on an error given by ModelSim, not Synplify. Have you tried it in ModelSim? Downvoting. \$\endgroup\$ – TonyM Jun 14 '17 at 12:43

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.