ModelSim vs Aldec -- odd difference

Discussion in 'VHDL' started by Andy Peters, Sep 4, 2009.

  1. Andy Peters

    Andy Peters Guest

    I'm evaluating Aldec Active-HDL v8.2, and it stumbles on the following
    function:

    function TimeToClocks (
    timer : time;
    clkper : time)
    return natural is
    variable division : natural;
    variable remainder : time;
    begin
    division := timer / clkper;
    remainder := timer rem clkper;

    -- always round UP if the remainder is not zero.
    if remainder /= (0 FS) then
    division := division + 1;
    end if;

    division := division - 1;
    return division;
    end function TimeToClocks;

    The compiler, set to analyzer to VDHL-2002, throws three errors, all
    from the remainder assignment:

    # Error: COMP96_0077: consts.vhdl : (765, 22): Assignment target
    incompatible with right side. Expected type 'TIME'.
    # Error: COMP96_0071: consts.vhdl : (765, 22): Operator "rem" is not
    defined for such operands.
    # Error: COMP96_0104: consts.vhdl : (765, 22): Undefined type of
    expression.

    What's odd is that ModelSim, similarly set to use the 2002 standard,
    accepts the code without complaint. What's odder still is that if I
    change remainder's type to natural. ModelSim throws the following
    error:

    # ** Error: consts.vhdl(765): Target type std.standard.natural in
    variable assignment is different from expression type
    std.standard.time.

    and Active-HDL doesn't even try:

    # Error: COMP96_0071: consts.vhdl : (765, 22): Operator "rem" is not
    defined for such operands.

    So my assumption was that dividing time by time would give me a
    unitless result.

    I can accept that dividing time by time would be bad, but why does
    ModelSim accept it?

    I suppose casting to natural would be a reasonable solution.

    -a
     
    Andy Peters, Sep 4, 2009
    #1
    1. Advertising

  2. Andy Peters

    sleeman Guest

    On Sep 3, 7:43 pm, Andy Peters <> wrote:
    > I'm evaluating Aldec Active-HDL v8.2, and it stumbles on the following
    > function:
    >
    >    function TimeToClocks (
    >         timer  : time;
    >         clkper : time)
    >         return natural is
    >         variable division  : natural;
    >         variable remainder : time;
    >     begin
    >         division  := timer / clkper;
    >         remainder := timer rem clkper;
    >
    >         -- always round UP if the remainder is not zero.
    >         if remainder /= (0 FS) then
    >             division := division + 1;
    >         end if;
    >
    >         division := division - 1;
    >         return division;
    >     end function TimeToClocks;
    >
    > The compiler, set to analyzer to VDHL-2002, throws three errors, all
    > from the remainder assignment:
    >
    > # Error: COMP96_0077: consts.vhdl : (765, 22): Assignment target
    > incompatible with right side. Expected type 'TIME'.
    > # Error: COMP96_0071: consts.vhdl : (765, 22): Operator "rem" is not
    > defined for such operands.
    > # Error: COMP96_0104: consts.vhdl : (765, 22): Undefined type of
    > expression.
    >
    > What's odd is that ModelSim, similarly set to use the 2002 standard,
    > accepts the code without complaint. What's odder still is that if I
    > change remainder's type to natural. ModelSim throws the following
    > error:
    >
    > # ** Error: consts.vhdl(765): Target type std.standard.natural in
    > variable assignment is different from expression type
    > std.standard.time.
    >
    > and Active-HDL doesn't even try:
    >
    > # Error: COMP96_0071: consts.vhdl : (765, 22): Operator "rem" is not
    > defined for such operands.
    >
    > So my assumption was that dividing time by time would give me a
    > unitless result.
    >
    > I can accept that dividing time by time would be bad, but why does
    > ModelSim accept it?
    >
    > I suppose casting to natural would be a reasonable solution.
    >
    > -a


    It looks like the LRM doesn't define an implicit "rem" for physical
    types in the same way it defines "/" (which takes two of the same
    equivalent types and produces a universal integer, which can then be
    converted to whatever integer type you need). I'm not entirely sure
    why it doesn't define it, since a physical type value denotes an
    integer decorated with the physical type's primary unit, which ought
    to be sufficient to construct a well-defined "rem" operator.

    Defining "remainder" as a natural in your code is (I think)
    irrelevant, since "rem" on the RHS isn't defined to begin with - it
    just produced different messages.

    - Kenn
     
    sleeman, Sep 4, 2009
    #2
    1. Advertising

  3. Andy Peters

    Andy Peters Guest

    On Sep 4, 2:45 am, Brian Drummond <>
    wrote:
    > On Thu, 3 Sep 2009 18:37:39 -0700 (PDT), sleeman <>
    > wrote:
    >
    >
    >
    > >On Sep 3, 7:43 pm, Andy Peters <> wrote:
    > >> I'm evaluating Aldec Active-HDL v8.2, and it stumbles on the following
    > >> function:

    >
    > >>    function TimeToClocks (
    > >>         timer  : time;
    > >>         clkper : time)
    > >>         return natural is
    > >>         variable division  : natural;
    > >>         variable remainder : time;
    > >>     begin
    > >>         division  := timer / clkper;
    > >>         remainder := timer rem clkper;

    >
    > >>         -- always round UP if the remainder is not zero.
    > >>         if remainder /= (0 FS) then
    > >>             division := division + 1;
    > >>         end if;

    >
    > >>         division := division - 1;
    > >>         return division;
    > >>     end function TimeToClocks;

    >
    > >> The compiler, set to analyzer to VDHL-2002, throws three errors, all
    > >> from the remainder assignment:

    >
    > >> # Error: COMP96_0077: consts.vhdl : (765, 22): Assignment target
    > >> incompatible with right side. Expected type 'TIME'.
    > >> # Error: COMP96_0071: consts.vhdl : (765, 22): Operator "rem" is not
    > >> defined for such operands.
    > >> # Error: COMP96_0104: consts.vhdl : (765, 22): Undefined type of
    > >> expression.

    >
    > >> What's odd is that ModelSim, similarly set to use the 2002 standard,
    > >> accepts the code without complaint. What's odder still is that if I
    > >> change remainder's type to natural. ModelSim throws the following
    > >> error:

    >
    > >> # ** Error: consts.vhdl(765): Target type std.standard.natural in
    > >> variable assignment is different from expression type
    > >> std.standard.time.

    >
    > >> and Active-HDL doesn't even try:

    >
    > >> # Error: COMP96_0071: consts.vhdl : (765, 22): Operator "rem" is not
    > >> defined for such operands.

    >
    > >> So my assumption was that dividing time by time would give me a
    > >> unitless result.

    >
    > >> I can accept that dividing time by time would be bad, but why does
    > >> ModelSim accept it?

    >
    > Why should it be bad? it yields a unitless result; it is perfectly valid to use
    > in e.g. a prescaler or clock divider.


    That was my original thought: time divided by time is unitless, so the
    whole thing should just work.

    > The remainder is of the original type, of course (e.g. a fraction of a second).
    > So all compilers should reject "rem" in this context with natural result, as
    > they do.


    OK, that is what I was missing.

    > >> I suppose casting to natural would be a reasonable solution.

    >
    > No. (That way leads to C :)


    Noooooooooo!!

    > A more reasonable solution would be to supply the missing function.


    Which I shall do, by stealing your code below :)

    > >It looks like the LRM doesn't define an implicit "rem" for physical
    > >types in the same way it defines "/" (which takes two of the same
    > >equivalent types and produces a universal integer, which can then be
    > >converted to whatever integer type you need).

    >
    > If so, that does look like an omission to me. It's interesting (but not so
    > unusual) that Modelsim does more than the standard requires.


    Ashenden (2nd edition, p39) tells us that the definition of the
    physical type time is implementation-defined. And I suppose that
    ModelSim's implementation differs from Aldec's.

    > I would define the missing function as
    >
    > function rem (a,b:time) return time is
    > variable temp: natural := a/b;
    > begin
    >    return a - temp*b;
    > end function rem;
    >
    > I don't expect you can fix the syntax by
    > function "rem" ... in the same way function "/" ...
    > allows overloading the / operator, so you are probably stuck with
    > calling it as
    > remainder := rem(timer, clkper);


    I don't mind calling it as a function -- I just want it to work!

    Thanks,
    -a
     
    Andy Peters, Sep 4, 2009
    #3
  4. Andy Peters

    Andy Peters Guest

    On Sep 4, 9:49 am, Andy Peters <> wrote:

    > > function rem (a,b:time) return time is
    > > variable temp: natural := a/b;
    > > begin
    > >    return a - temp*b;
    > > end function rem;


    After a quick test -- "rem" of course is a keyword and both ModelSim
    and Aldec throw an "expecting string or identifier" error. Changing
    the name of the function to something like rem_time works.

    -a
     
    Andy Peters, Sep 4, 2009
    #4
  5. Andy Peters

    sleeman Guest

    On Sep 4, 12:56 pm, Andy Peters <> wrote:
    > On Sep 4, 9:49 am, Andy Peters <> wrote:
    >
    > > > function rem (a,b:time) return time is
    > > > variable temp: natural := a/b;
    > > > begin
    > > >    return a - temp*b;
    > > > end function rem;

    >
    > After a quick test -- "rem" of course is a keyword and both ModelSim
    > and Aldec throw an "expecting string or identifier" error. Changing
    > the name of the function to something like rem_time works.
    >
    > -a


    It is legal to overload a function in this way, but you need to use
    quotes around the identifier, e.g.

    function "rem" (a,b: time)
    ....
    end "rem"

    - Kenn
     
    sleeman, Sep 4, 2009
    #5
  6. Andy Peters

    Andy Peters Guest

    On Sep 4, 10:19 am, sleeman <> wrote:
    > On Sep 4, 12:56 pm, Andy Peters <> wrote:
    >
    > > On Sep 4, 9:49 am, Andy Peters <> wrote:

    >
    > > > > function rem (a,b:time) return time is
    > > > > variable temp: natural := a/b;
    > > > > begin
    > > > >    return a - temp*b;
    > > > > end function rem;

    >
    > > After a quick test -- "rem" of course is a keyword and both ModelSim
    > > and Aldec throw an "expecting string or identifier" error. Changing
    > > the name of the function to something like rem_time works.

    >
    > > -a

    >
    > It is legal to overload a function in this way, but you need to use
    > quotes around the identifier, e.g.
    >
    > function "rem" (a,b: time)
    > ...
    > end "rem"
    >
    >  - Kenn


    Yep, that works! This is one of the dustier corners of VHDL.

    -a
     
    Andy Peters, Sep 4, 2009
    #6
  7. Andy Peters

    Andy Peters Guest

    On Sep 4, 10:19 am, sleeman <> wrote:
    > On Sep 4, 12:56 pm, Andy Peters <> wrote:
    >
    > > On Sep 4, 9:49 am, Andy Peters <> wrote:

    >
    > > > > function rem (a,b:time) return time is
    > > > > variable temp: natural := a/b;
    > > > > begin
    > > > >    return a - temp*b;
    > > > > end function rem;

    >
    > > After a quick test -- "rem" of course is a keyword and both ModelSim
    > > and Aldec throw an "expecting string or identifier" error. Changing
    > > the name of the function to something like rem_time works.

    >
    > > -a

    >
    > It is legal to overload a function in this way, but you need to use
    > quotes around the identifier, e.g.
    >
    > function "rem" (a,b: time)
    > ...
    > end "rem"
    >
    >  - Kenn


    Ah, well, XST throws an unhappy error:
    ERROR:Xst:781 - "E:/Projects/foo/bar.vhdl" line 284: Type definition
    is not authorized : 'PhysicalType'.

    The error wasn't actually in the "rem" function. Rather, it was thrown
    when the parser hit a constant definition in the declarative part of
    an architecture:

    constant INITDELAY : natural := TimeToClocks(INITDELAY_TIME,
    CLKPER);

    where both INITDELAY_TIME and CLKPER are in time units.

    That will teach me to be clever.

    -a
     
    Andy Peters, Sep 17, 2009
    #7
  8. Andy Peters

    Andy Peters Guest

    On Sep 18, 12:57 am, Brian Drummond <>
    wrote:
    > On Thu, 17 Sep 2009 14:54:46 -0700 (PDT), Andy Peters <> wrote:
    > >On Sep 4, 10:19 am, sleeman <> wrote:
    > >> On Sep 4, 12:56 pm, Andy Peters <> wrote:
    > >> It is legal to overload a function in this way, but you need to use
    > >> quotes around the identifier, e.g.

    >
    > >> function "rem" (a,b: time)
    > >> ...
    > >> end "rem"

    >
    > >>  - Kenn

    >
    > >Ah, well, XST throws an unhappy error:
    > >ERROR:Xst:781 - "E:/Projects/foo/bar.vhdl" line 284: Type definition
    > >is not authorized : 'PhysicalType'.

    >
    > >The error wasn't actually in the "rem" function. Rather, it was thrown
    > >when the parser hit a constant definition in the declarative part of
    > >an architecture:

    >
    > >    constant INITDELAY : natural := TimeToClocks(INITDELAY_TIME,
    > >CLKPER);

    >
    > >where both INITDELAY_TIME and CLKPER are in time units.

    >
    > >That will teach me to be clever.

    >
    > Better, teach XST to be clever.
    >
    > It would be useful to boil this down to the simplest example that works (prints
    > a sensible message) in Modelsim and errors in XST, and submit it as a webcase.
    >
    > First line support may just want to sell you a workaround, so persist until they
    > actually acknowledge it's a bug (or missing feature), raise a CR (change
    > request) and inform you of the CR number.
    >
    > Xilinx do usually fix things, eventually.
    >
    > Meanwhile we do the best we can with broken tools.


    It's an error because XST simply doesn't support physical types,
    period, even if said physical type is only used as part of an equation
    that sets an integer constant. Which is why it SHOULD be supported, at
    least for that use, and yes, I will open a Web Case and demand a
    change request.

    -a
     
    Andy Peters, Sep 28, 2009
    #8
  9. Andy Peters

    JimLewis Guest

    Andy,
    Caution with overloading either "rem" and "mod" since the are
    overloaded in VHDL-2008. Which may explain why it works in one
    simulator and not another.

    If you do not want to use VHDL-2008 just yet, you might give your
    function a different name.

    Cheers,
    Jim
     
    JimLewis, Oct 2, 2009
    #9
  10. Andy Peters

    Andy Peters Guest

    On Oct 2, 11:41 am, JimLewis <> wrote:
    > Andy,
    > Caution with overloading either "rem" and "mod" since the are
    > overloaded in VHDL-2008.  Which may explain why it works in one
    > simulator and not another.
    >
    > If you do not want to use VHDL-2008 just yet, you might give your
    > function a different name.


    No 2008 here, yet, as XST doesn't support it. As for the overloading,
    aren't most operators overloaded? If my overloaded function has a
    different signature (different arguments) from the standard, then
    isn't the elaborator supposed to sort this all out?

    -a
     
    Andy Peters, Oct 5, 2009
    #10
    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. Thomas Bartzick
    Replies:
    0
    Views:
    2,271
    Thomas Bartzick
    Jun 26, 2003
  2. rickman
    Replies:
    0
    Views:
    516
    rickman
    Mar 3, 2010
  3. Dave
    Replies:
    0
    Views:
    594
  4. d_s_klein
    Replies:
    30
    Views:
    3,994
    Anssi Saari
    Apr 5, 2010
  5. Raymund Hofmann

    Re: Modelsim PE vs. Aldec Active-HDL (PE)

    Raymund Hofmann, Mar 4, 2010, in forum: VHDL
    Replies:
    0
    Views:
    552
    Raymund Hofmann
    Mar 4, 2010
Loading...

Share This Page