Syntax for conversion functions on inout ports

Discussion in 'VHDL' started by Rob Gaddi, Dec 18, 2012.

  1. Rob Gaddi

    Rob Gaddi Guest

    Can someone tell me whether I'm doing this right (and have a tool bug)
    or screwing something simple up? The point of the exercise, by the
    way, is passing a record structure in and out of a block that's hidden
    inside of a Qsys system, which means that the only data types I can
    actually pass around are std_logic and std_logic_vector.

    I've got a couple of types, and conversion functions.

    type t_amm_rec is record
    end record ;
    subtype t_amm_rec_slv is std_logic_vector(179 downto 0);

    function TO_SLV(rec : t_amm_rec) return t_amm_rec_slv;
    function TO_AMM_REC(slv : t_amm_rec_slv) return t_amm_rec;

    So I've got my top-level DUT, which has a t_amm_rec_slv port on it. My
    testbench has:

    signal rec : t_amm_rec := INIT_AMM_REC;
    DUT : entity work.bfm_sim
    port map(
    TO_AMM_REC(coe_export) => TO_SLV(rec),

    My Qsys entity, with a t_amm_rec_slv port on it called rec, then wraps
    an internal entity with a t_amm_rec port on it, and has:

    INTL : amm_master_bfm_intl
    port map(
    TO_SLV(rec_intl) => TO_AMM_REC(rec),

    Again, all these ports are inout. So, do I have the syntax of this
    correct, and Active-HDL just can't handle it? Or is this something I
    screwed up?

    Rob Gaddi, Dec 18, 2012
    1. Advertisements

  2. Rob Gaddi

    Andy Guest

    Let's see here...

    So, just to make sure I'm following, bfm_sim instantiates "my qsys entity",which instantiates amm_master_bfm_intl?

    And port coe_export on bfm_sim is of type t_amm_rec_slv?

    And port rec_intl on amm_master_bfm_intl is of type t_amm_rec?

    In the instantiation of amm_master_bfm_intl, what is the type of the signalrec that you are associating with the port rec_intl? By its name, I would assume rec is of type t_amm_rec, but that would not work, since it would not pass as an argument to TO_AMM_REC(). Shouldn't rec be of type t_amm_rec_slv here?

    Or am I missing something?

    Can you show us the error message? Or is it just not working like you expected?

    Also, bidirectional conversion function pairs can cause an unresolvable loop if you're not careful. The information to determine the directionality would have to be included in both the record and in the slv, which is appliedin the conversion functions. Also all elements of t_amm_rec would have to be of resolved types (or have to boil down to elements of resolved types).

    Andy, Dec 18, 2012
    1. Advertisements

  3. Rob Gaddi

    Rob Gaddi Guest

    Right. bfm_sim instantiates amm_master_bfm, which is just a wrapper
    around amm_master_bfm_intl. The only purpose of the wrapper is to
    allow amm_master_bfm_intl to have a record type inout, whereas
    amm_master_bfm must have only std_logic_vector ports in order to play
    nicely with Qsys.
    No, due to poor naming choices, rec on amm_master_bfm is of
    t_amm_rec_slv, and is the same signal as coe_export.
    On the internal one, I'm getting an ambiguous function error. But it
    will allow me to compile and elaborate if instead of

    TO_SLV(rec_intl) => TO_AMM_REC(rec),

    I only have

    rec_intl => TO_AMM_REC(rec),

    But then everything comes up 'X'.

    On the testbench level I'm getting no error, but things just aren't
    lining up right.
    All the elements are std_logic or std_logic_vector. I was hoping that
    directionality could be handled by making sure that only one side or
    the other of any given field was being driven.
    Rob Gaddi, Dec 18, 2012
  4. Rob Gaddi

    Andy Guest

    Are there actually bidirectional fields in the record, or are all fields unidiretional? Make sure that for those fields that are always inputs to a module, that module should drive 'Z' on them continuously. Otherwise the default value driven (it is an inout, after all) is 'U', which usually shows upin waveforms as 'X'.

    If there are truly bidirectional fields (with true bidirectional bits), then there needs to be some way to let each conversion function know whether it is supposed to return 'Z' or the converted value of the argument (which could be just a wrap-around of the value driven from the other side, which then becomes a positive feeback loop, which gets stuck, and results in 'X' when the driven value from either side tries to change). Direction control could be done by inspecting other signals in the record or vector from within the conversion function.

    Lacking that, there are some tricks (google something like "vhdl zero ohm resistor") but they are ugly! If the application permits (e.g. no pullups) the conversion function could "strip the strength" from the argument, and convert everything to 'Z', 'W', 'L' or 'H' return values. That way the moduleor testbench (driving hard values) will always win the contention, and it should work as expected.

    The ambiguous function error is an indication that the compiler has multiple to_slv() functions visible, and cannot decide which one is applicable. Picking the right one is based on argument and return BASE types (not subtypes!). Make sure there are no other to_slv() functions visible that take the same type record (or subtype of same type record!) as an argument.

    Andy, Dec 19, 2012
    1. Advertisements

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments (here). After that, you can post your question and our members will help you out.