Default value for an unconstrained port

Discussion in 'VHDL' started by XYZ, May 16, 2010.

  1. XYZ

    XYZ Guest

    Hi,

    How to set a default value for an unconstrained port? Doing it this way
    input : in std_logic_vector;
    val : in std_logic_vector := (others => '0');
    doesn't work as val'range is not known and obviously I end up with
    ModelSim error "OTHERS choice can not be used in unconstrained array
    aggregate."

    I know, however, that val'range should be the same as input'range. Is
    there any way to define a default value for val vector based on input
    (input is constrained by higher entity). I need something like
    val : in std_logic_vector := (input'range => '0')

    I'm afraid that even if there exist different method than OTHERS to
    create a vector I wouldn't be allowed to use input'range because of
    "object 'input' cannot be used within the same interface as it is
    declared" error.

    Is it better to switch to generics rather than use unconstrained ports?

    Thanks.
     
    XYZ, May 16, 2010
    #1
    1. Advertising

  2. XYZ

    XYZ Guest

    On 16.05.2010 21:42, XYZ wrote:
    > Hi,
    >
    > How to set a default value for an unconstrained port? Doing it this way
    > input : in std_logic_vector;
    > val : in std_logic_vector := (others => '0');
    > doesn't work as val'range is not known and obviously I end up with
    > ModelSim error "OTHERS choice can not be used in unconstrained array
    > aggregate."
    >
    > I know, however, that val'range should be the same as input'range. Is
    > there any way to define a default value for val vector based on input
    > (input is constrained by higher entity). I need something like
    > val : in std_logic_vector := (input'range => '0')


    I send the previous post too fast. It turns out that the above is a
    valid VHDL syntax, so please skip the text above. Now, as expected, I
    faced the error given below. Is there anything I can do?
    >
    > I'm afraid that even if there exist different method than OTHERS to
    > create a vector I wouldn't be allowed to use input'range because of
    > "object 'input' cannot be used within the same interface as it is
    > declared" error.
    >
    > Is it better to switch to generics rather than use unconstrained ports?


    Thanks.
     
    XYZ, May 16, 2010
    #2
    1. Advertising

  3. XYZ wrote:

    > Hi,
    >
    > How to set a default value for an unconstrained port? Doing it this way
    > input : in std_logic_vector;
    > val : in std_logic_vector := (others => '0');
    > doesn't work as val'range is not known and obviously I end up with
    > ModelSim error "OTHERS choice can not be used in unconstrained array
    > aggregate."


    And rightfully so. If you leave an unconstrained port unconnected, what
    width is it supposed to be? Or more general: what range should the index
    be? It can not be determined from anything.

    As a solutions, what you could do is something like this:

    val : in std_logic_vector := (31 downto 0 => '0');

    Now if you leave the port unconnected, it's width shall be 32.

    And if you connect it to another signal of any width, it will take over the
    index range of that signal.

    Sweet and simple.

    --
    Paul Uiterlinden
    www.aimvalley.nl
    e-mail addres: remove the not.
     
    Paul Uiterlinden, May 16, 2010
    #3
  4. XYZ

    XYZ Guest

    On 17.05.2010 00:06, Paul Uiterlinden wrote:
    > XYZ wrote:
    >
    >> Hi,
    >>
    >> How to set a default value for an unconstrained port? Doing it this way
    >> input : in std_logic_vector;
    >> val : in std_logic_vector := (others => '0');
    >> doesn't work as val'range is not known and obviously I end up with
    >> ModelSim error "OTHERS choice can not be used in unconstrained array
    >> aggregate."

    >
    > And rightfully so. If you leave an unconstrained port unconnected, what
    > width is it supposed to be? Or more general: what range should the index
    > be? It can not be determined from anything.

    I know, I thought it was clear from the post.

    > As a solutions, what you could do is something like this:
    >
    > val : in std_logic_vector := (31 downto 0 => '0');
    >
    > Now if you leave the port unconnected, it's width shall be 32.
    >
    > And if you connect it to another signal of any width, it will take over the
    > index range of that signal.

    I wrote that val is supposed to have input'range. If I do like that:

    input : in std_logic_vector;
    val : in std_logic_vector := (input'range => '0');

    I get "object 'input' cannot be used within the same interface as it is
    declared". In fact this is true that input is declared in the same
    interface but is there any workaround for this, other than using generic
    values?
     
    XYZ, May 17, 2010
    #4
  5. XYZ

    backhus Guest

    On 17 Mai, 02:26, XYZ <> wrote:
    > On 17.05.2010 00:06, Paul Uiterlinden wrote:> XYZ wrote:
    >
    > >> Hi,

    >
    > >> How to set a default value for an unconstrained port? Doing it this way
    > >> input : in std_logic_vector;
    > >> val : in std_logic_vector := (others =>  '0');
    > >> doesn't work as val'range is not known and obviously I end up with
    > >> ModelSim error "OTHERS choice can not be used in unconstrained array
    > >> aggregate."

    >
    > > And rightfully so. If you leave an unconstrained port unconnected, what
    > > width is it supposed to be? Or more general: what range should the index
    > > be? It can not be determined from anything.

    >
    > I know, I thought it was clear from the post.
    >
    > > As a  solutions, what you could do is something like this:

    >
    > >    val : in std_logic_vector := (31 downto 0 =>  '0');

    >
    > > Now if you leave the port unconnected, it's width shall be 32.

    >
    > > And if you connect it to another signal of any width, it will take over the
    > > index range of that signal.

    >
    > I wrote that val is supposed to have input'range. If I do like that:
    >
    >         input : in std_logic_vector;
    >         val : in std_logic_vector := (input'range =>  '0');
    >
    > I get "object 'input' cannot be used within the same interface as it is
    > declared". In fact this is true that input is declared in the same
    > interface but is there any workaround for this, other than using generic
    > values?


    Hi,
    using unconstrained ports will be a problem once you enter the
    toplevel.
    There are no chips with 'morphing' pacages that automatically adapt to
    the socket or pcb, to make this feature useful. :)

    But there is a (pragmatic) solution to your problem.
    Write a function instead of a module (entity/architecture).
    This functiion can have unconstrained parameters.
    And when you want to apply this function in a real circuit you can
    write a wrapper module that sets the port sizes and calls the
    function.
    If you need to do so more often and still want to avoid generics, a
    perl script might be usefull that generates the wrappers.

    Have a nice synthesis
    Eilert
     
    backhus, May 17, 2010
    #5
  6. On May 16, 8:42 pm, XYZ <> wrote:
    > Hi,
    >
    > How to set a default value for an unconstrained port? Doing it this way
    > input : in std_logic_vector;
    > val : in std_logic_vector := (others => '0');
    > doesn't work

    [...]
    > I know, however, that val'range should be the same as input'range.


    As the discussion has shown, there doesn't seem to be any direct way
    to handle this. However, how about this as an idea...?

    val: in std_logic_vector(0 downto 1 => '0'); --- null range

    Now, if you fail to connect "val", it gets a null-range input. We
    can
    detect that inside the design:

    architecture....
    --- Make a signal for "val" that is the known correct size
    signal internal_val: std_logic_vector(input'range);
    ...
    begin
    missing_val_manager: if val'length = 0 generate
    assert false
    report "val not connected, defaulting to all-zero"
    severity note;
    end process;
    --- Make the correct-sized default
    internal_val <= (input'range => '0');
    end generate;
    provided_val_manager: if val'length > 0 generate
    assert val'length = input'length
    report "val was connected but its size doesn't match input"
    severity fatal;
    internal_val <= val;
    end generate;

    (and then, of course, use "internal_val" everywhere in your
    design).

    I'm pretty confident this is OK for simulation, but the null range
    might cause some trouble for synthesis, so there might need to be some
    business with synthesis-off pragmas. Alternatively you could cheat
    and set the unconnected default to be one bit wide (0 downto 0) or,
    perhaps, some other size that you know will never occur in practice.

    VHDL-2008 "if generate else" could make the code just a little neater.

    --
    Jonathan Bromley
    still trying to pretend he remembers some VHDL
    after far too long in SystemVerilog-land....
     
    Jonathan Bromley, May 17, 2010
    #6
  7. XYZ wrote:

    > On 17.05.2010 00:06, Paul Uiterlinden wrote:
    >> XYZ wrote:
    >>
    >>> Hi,
    >>>
    >>> How to set a default value for an unconstrained port? Doing it this way
    >>> input : in std_logic_vector;
    >>> val : in std_logic_vector := (others => '0');
    >>> doesn't work as val'range is not known and obviously I end up with
    >>> ModelSim error "OTHERS choice can not be used in unconstrained array
    >>> aggregate."

    >>
    >> And rightfully so. If you leave an unconstrained port unconnected, what
    >> width is it supposed to be? Or more general: what range should the index
    >> be? It can not be determined from anything.

    > I know, I thought it was clear from the post.


    Sorry, I missed that part. I should not post anything after midnight...
    >
    >> As a solutions, what you could do is something like this:
    >>
    >> val : in std_logic_vector := (31 downto 0 => '0');
    >>
    >> Now if you leave the port unconnected, it's width shall be 32.
    >>
    >> And if you connect it to another signal of any width, it will take over
    >> the index range of that signal.

    > I wrote that val is supposed to have input'range. If I do like that:
    >
    > input : in std_logic_vector;
    > val : in std_logic_vector := (input'range => '0');
    >
    > I get "object 'input' cannot be used within the same interface as it is
    > declared". In fact this is true that input is declared in the same
    > interface but is there any workaround for this, other than using generic
    > values?


    I think Jonathan's suggestion is quite elegant. The only issue might be the
    null range (as Jonathan already pointed out for synthesis).

    But also for simulation: by default a null-range gives a warning in
    ModelSim. That can be suppressed again with the -nowarn 3 option, IIRC.

    An alternative would be to use a special value, with bit values that
    normally do not occur. For example: (31 DOWNTO 0 => '-'), or
    (0 TO 0 => 'U'). This avoids the issue with the null-range warning.

    --
    Paul Uiterlinden
    www.aimvalley.nl
    e-mail addres: remove the not.
     
    Paul Uiterlinden, May 17, 2010
    #7
  8. XYZ

    Andy Guest

    Jonathan,

    How would you go about declaring "internal_val" such that it has
    either the length of input or the length of val? I think you would
    have to declare it with input'range, then resize val as necessary to
    fit if val was provided but did not match.

    Andy
     
    Andy, May 17, 2010
    #8
  9. Andy,

    > How would you go about declaring "internal_val" such that it has
    > either the length of input or the length of val? I think you would
    > have to declare it with input'range, then resize val as necessary to
    > fit if val was provided but did not match.


    I took the coward's way out and threw an assertion fatal
    if 'val' is provided, but doesn't match the expected
    size (input'length). (Didn't I? That was the idea,
    anyhow.) That's something I regard as standard practice
    when using unconstrained ports that must respect some
    kind of size relationship. I had understood the OP to
    mean that 'val' (or its default, if not supplied) should
    match the size of 'input'. If that's not the case, then
    clearly you're right: some resizing rule would be needed.
    Whatever the requirement, I'm sure you could make it
    happen with a sufficiently contorted "generate".

    cheers
    --
    Jonathan Bromley
     
    Jonathan Bromley, May 17, 2010
    #9
  10. XYZ

    Andy Guest

    Jonathan,

    Unfortunately, declarations within a generate statement are local to
    the generate's block, and furthermore, generate statements cannot be
    located in the declarative region. This is one glaring limitation to
    the generate capability: conditional declarations useable outside the
    generate statement.

    You could use a function for the declaration initializer of
    internal_val...? Similarly to what the OP was doing with unconstrained
    ports, declare internal_val as unconstrained SLV, with a function call
    to define an initial value which also sets the range of the variable/
    signal. I don't think you could replace the generate statements with
    the initializer function, since the generate statements created the
    correct concurrent assignment also. OK, maybe you could get rid of one
    of the generates...

    Andy
     
    Andy, May 17, 2010
    #10
  11. On Mon, 17 May 2010 09:13:35 -0700 (PDT), Andy wrote:

    >Unfortunately, declarations within a generate statement are local to
    >the generate's block, and furthermore, generate statements cannot be
    >located in the declarative region. This is one glaring limitation to
    >the generate capability: conditional declarations useable outside the
    >generate statement.


    right, although of course you can see the reasoning
    behind that.

    >You could use a function for the declaration initializer of
    >internal_val...? Similarly to what the OP was doing with unconstrained
    >ports, declare internal_val as unconstrained SLV, with a function call
    >to define an initial value


    That's fine for constants, but surely not for a signal
    or variable?

    > I don't think you could replace the generate statements with
    >the initializer function, since the generate statements created the
    >correct concurrent assignment also.


    I still think it's OK: the declaration of internal_val would
    be outside any generate, determined by the properties
    of other ports etc (not forgetting that functions can be
    used to determine the values of constants that control
    a signal's declaration). And then a generate could
    conditionally create a process, in whose declarative
    region there is a function used to build the signal's
    value so that process can duly drive it.

    I agree, though, that it's all a bit of a faff. Probably a
    few generics on the entity would make for a neater job.

    Have pity on me. As I complained earlier, I'm currently
    in Verilog land, where such things are not permitted to
    appear even in nocturnal fantasies.
    --
    Jonathan Bromley
     
    Jonathan Bromley, May 17, 2010
    #11
  12. XYZ

    Andy Guest

    On May 17, 2:43 pm, Jonathan Bromley <>
    wrote:
    >
    > That's fine for constants, but surely not for a signal
    > or variable?
    >


    True, you'd have to use a function to initialize an unconstrained
    constant, then you could use the constant's range to declare the
    variable/signal.

    You have my sympathy. Somehow I think verilog must be more kind to
    those who've never known the benefits of VHDL. Otherwise, who would
    prefer it? But that's a different thread...

    Andy
     
    Andy, May 18, 2010
    #12
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Pankaj
    Replies:
    2
    Views:
    862
    anupam
    Aug 23, 2004
  2. Replies:
    8
    Views:
    1,953
    Mike Treseler
    Feb 10, 2005
  3. Replies:
    5
    Views:
    1,051
    Ralf Hildebrandt
    May 27, 2005
  4. Amal
    Replies:
    5
    Views:
    8,879
    Brandon
    Mar 8, 2006
  5. mido_nour1
    Replies:
    2
    Views:
    1,133
    mido_nour1
    Jul 31, 2009
Loading...

Share This Page