locally static expression

Discussion in 'VHDL' started by rickman, Sep 17, 2006.

  1. rickman

    rickman Guest

    I looked this up once in the VHDL spec, but I don't recall the details.
    I seem to remember that the definition of a locally static expression
    is rather complex with a lot of little details. But a tool is flagging
    warnings on some code which seems to be due to the use of conversion
    from SLV to integer.

    constant SWAP : IRSLV := to_slv(FIXOP + 16#00#, 8); -- E0 (1110 0000)

    type INSTDSPLY is (RST, IACK, LTR, JMP, JUMZ, JUMC, JUMO, CALA, CALR,
    SWP, OVR, RUP, DUP, SHFL, SHFC, ZFLG, RFTC,
    RDRP, RTN, FTCH, FCHB, RFRM, RSB, RCM, FCHP, FHPB, RARS,
    DDRP, TOR, CPNC, CPC, ADNC, ADC, SBNC, SBC,
    BFL, RTI, STOR, STRB, BLAN, RADT, BLOR, STRP, STPB, BLXR);

    when TO_INTEGER(UNSIGNED(SWAP)) => return SWP;

    The warning comes from lines like this last one, allegedly from the
    value returned by the TO_INTEGER conversion. "Choice TO_INTEGER is not
    a locally static expression."

    I do this in a lot of places in some existing code. My MO is to avoid
    warning messages, so I can't believe that I would have done this and
    lived with the dozens of warnings I am getting. But then the older
    tool may not have been as true to the spec as it could have been.

    Rather than make me go dig up my copy of the VHDL spec and read all
    those cross-referenced paragraphs to re-learn what this really means,
    can anyone give me the 25 cent explanation and an easy cure?
    rickman, Sep 17, 2006
    #1
    1. Advertising

  2. rickman

    rickman Guest

    Well, no one took pity on me so I had to figure it out for myself. It
    has been awhile since I have done any HDL coding so I had forgotten
    about this. Just in case anyone else wants to know what this is about,
    I'll explain what I found.

    The function calls that convert the SLV SWAP to an integer are not
    allowed where I am trying to use it in the CASE statement. This
    function call is not invoked until later in the compilation process, so
    the value is unknown at this time. The solution is to either declare
    integer values for the opcodes with slightly different names (so I
    don't have to call a conversion routine), or to use IF statements which
    don't have the same limitations as the CASE statement.

    Even though I don't like this, it seems perfectly logical to me.


    rickman wrote:
    > I looked this up once in the VHDL spec, but I don't recall the details.
    > I seem to remember that the definition of a locally static expression
    > is rather complex with a lot of little details. But a tool is flagging
    > warnings on some code which seems to be due to the use of conversion
    > from SLV to integer.
    >
    > constant SWAP : IRSLV := to_slv(FIXOP + 16#00#, 8); -- E0 (1110 0000)
    >
    > type INSTDSPLY is (RST, IACK, LTR, JMP, JUMZ, JUMC, JUMO, CALA, CALR,
    > SWP, OVR, RUP, DUP, SHFL, SHFC, ZFLG, RFTC,
    > RDRP, RTN, FTCH, FCHB, RFRM, RSB, RCM, FCHP, FHPB, RARS,
    > DDRP, TOR, CPNC, CPC, ADNC, ADC, SBNC, SBC,
    > BFL, RTI, STOR, STRB, BLAN, RADT, BLOR, STRP, STPB, BLXR);
    >
    > when TO_INTEGER(UNSIGNED(SWAP)) => return SWP;
    >
    > The warning comes from lines like this last one, allegedly from the
    > value returned by the TO_INTEGER conversion. "Choice TO_INTEGER is not
    > a locally static expression."
    >
    > I do this in a lot of places in some existing code. My MO is to avoid
    > warning messages, so I can't believe that I would have done this and
    > lived with the dozens of warnings I am getting. But then the older
    > tool may not have been as true to the spec as it could have been.
    >
    > Rather than make me go dig up my copy of the VHDL spec and read all
    > those cross-referenced paragraphs to re-learn what this really means,
    > can anyone give me the 25 cent explanation and an easy cure?
    rickman, Sep 18, 2006
    #2
    1. Advertising

  3. rickman

    Jim Lewis Guest

    Rickman,
    To further this, there are some changes that were
    made in the Accellera 3.0 draft of VHDL to what can
    be locally static. First, it allows arrays such as
    std_logic_vector, signed, unsigned to be a locally
    static type. Furthermore, functions defined in any of
    the following standard packages will also be locally
    static, std_logic_1164, numeric_std, and numeric_std_unsigned.

    So if you use the to_slv from numeric_std_unsigned,
    I think your code will be ok - when the vendors implement
    the standard. Accellera 3.0 draft of VHDL became a
    standard at DAC 2006.

    Note functions from std_logic_arith or std_logic_unsigned
    will not be locally static since they are not standard
    packages - may they RIP.

    Of course, we need to make sure both simulator
    and synthesis vendors are up to speed on these
    changes. I recommend that you start making your
    requests today.

    Cheers,
    Jim



    > I looked this up once in the VHDL spec, but I don't recall the details.
    > I seem to remember that the definition of a locally static expression
    > is rather complex with a lot of little details. But a tool is flagging
    > warnings on some code which seems to be due to the use of conversion
    > from SLV to integer.
    >
    > constant SWAP : IRSLV := to_slv(FIXOP + 16#00#, 8); -- E0 (1110 0000)
    >
    > type INSTDSPLY is (RST, IACK, LTR, JMP, JUMZ, JUMC, JUMO, CALA, CALR,
    > SWP, OVR, RUP, DUP, SHFL, SHFC, ZFLG, RFTC,
    > RDRP, RTN, FTCH, FCHB, RFRM, RSB, RCM, FCHP, FHPB, RARS,
    > DDRP, TOR, CPNC, CPC, ADNC, ADC, SBNC, SBC,
    > BFL, RTI, STOR, STRB, BLAN, RADT, BLOR, STRP, STPB, BLXR);
    >
    > when TO_INTEGER(UNSIGNED(SWAP)) => return SWP;
    >
    > The warning comes from lines like this last one, allegedly from the
    > value returned by the TO_INTEGER conversion. "Choice TO_INTEGER is not
    > a locally static expression."
    >
    > I do this in a lot of places in some existing code. My MO is to avoid
    > warning messages, so I can't believe that I would have done this and
    > lived with the dozens of warnings I am getting. But then the older
    > tool may not have been as true to the spec as it could have been.
    >
    > Rather than make me go dig up my copy of the VHDL spec and read all
    > those cross-referenced paragraphs to re-learn what this really means,
    > can anyone give me the 25 cent explanation and an easy cure?
    >



    --
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    Jim Lewis
    Director of Training mailto:
    SynthWorks Design Inc. http://www.SynthWorks.com
    1-503-590-4787

    Expert VHDL Training for Hardware Design and Verification
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    Jim Lewis, Sep 19, 2006
    #3
  4. On 18 Sep 2006 06:25:01 -0700, "rickman" <> wrote:

    >The function calls that convert the SLV SWAP to an integer are not
    >allowed where I am trying to use it in the CASE statement. This
    >function call is not invoked until later in the compilation process, so
    >the value is unknown at this time. The solution is to either declare
    >integer values for the opcodes with slightly different names (so I
    >don't have to call a conversion routine), or to use IF statements which
    >don't have the same limitations as the CASE statement.


    >> constant SWAP : IRSLV := to_slv(FIXOP + 16#00#, 8); -- E0 (1110 0000)
    >>
    >> type INSTDSPLY is (RST, IACK, LTR, JMP, JUMZ, JUMC, JUMO, CALA, CALR,
    >> SWP, OVR, RUP, DUP, SHFL, SHFC, ZFLG, RFTC,
    >> RDRP, RTN, FTCH, FCHB, RFRM, RSB, RCM, FCHP, FHPB, RARS,
    >> DDRP, TOR, CPNC, CPC, ADNC, ADC, SBNC, SBC,
    >> BFL, RTI, STOR, STRB, BLAN, RADT, BLOR, STRP, STPB, BLXR);


    I don't know the full context, so this may be off base, but...

    if the intent is a one to one mapping between opcodes and INSTDSPLY
    elements, is there a way to use positional attributes or 'image
    attributes to accomplish what you want?
    Perhaps deriving the SWAP opcode in terms of integer'image(SWP)?

    Then things are a lot closer to self-maintaining in the event that you
    extend or modify INSTDSPLY.

    - Brian
    Brian Drummond, Sep 19, 2006
    #4
  5. rickman

    Andy Guest

    Yep, functions declared in packages not part of 1076 are not locally
    static. They're moving std_logic_1164, numeric_std, and numeric_bit
    packages into the 1076 standard for this reason, among others.

    Try declaring an integer constant (and an slv vector from that if
    necessary), then using the integer constant in the case statement.

    Andy


    Jim Lewis wrote:
    > Rickman,
    > To further this, there are some changes that were
    > made in the Accellera 3.0 draft of VHDL to what can
    > be locally static. First, it allows arrays such as
    > std_logic_vector, signed, unsigned to be a locally
    > static type. Furthermore, functions defined in any of
    > the following standard packages will also be locally
    > static, std_logic_1164, numeric_std, and numeric_std_unsigned.
    >
    > So if you use the to_slv from numeric_std_unsigned,
    > I think your code will be ok - when the vendors implement
    > the standard. Accellera 3.0 draft of VHDL became a
    > standard at DAC 2006.
    >
    > Note functions from std_logic_arith or std_logic_unsigned
    > will not be locally static since they are not standard
    > packages - may they RIP.
    >
    > Of course, we need to make sure both simulator
    > and synthesis vendors are up to speed on these
    > changes. I recommend that you start making your
    > requests today.
    >
    > Cheers,
    > Jim
    >
    >
    >
    > > I looked this up once in the VHDL spec, but I don't recall the details.
    > > I seem to remember that the definition of a locally static expression
    > > is rather complex with a lot of little details. But a tool is flagging
    > > warnings on some code which seems to be due to the use of conversion
    > > from SLV to integer.
    > >
    > > constant SWAP : IRSLV := to_slv(FIXOP + 16#00#, 8); -- E0 (1110 0000)
    > >
    > > type INSTDSPLY is (RST, IACK, LTR, JMP, JUMZ, JUMC, JUMO, CALA, CALR,
    > > SWP, OVR, RUP, DUP, SHFL, SHFC, ZFLG, RFTC,
    > > RDRP, RTN, FTCH, FCHB, RFRM, RSB, RCM, FCHP, FHPB, RARS,
    > > DDRP, TOR, CPNC, CPC, ADNC, ADC, SBNC, SBC,
    > > BFL, RTI, STOR, STRB, BLAN, RADT, BLOR, STRP, STPB, BLXR);
    > >
    > > when TO_INTEGER(UNSIGNED(SWAP)) => return SWP;
    > >
    > > The warning comes from lines like this last one, allegedly from the
    > > value returned by the TO_INTEGER conversion. "Choice TO_INTEGER is not
    > > a locally static expression."
    > >
    > > I do this in a lot of places in some existing code. My MO is to avoid
    > > warning messages, so I can't believe that I would have done this and
    > > lived with the dozens of warnings I am getting. But then the older
    > > tool may not have been as true to the spec as it could have been.
    > >
    > > Rather than make me go dig up my copy of the VHDL spec and read all
    > > those cross-referenced paragraphs to re-learn what this really means,
    > > can anyone give me the 25 cent explanation and an easy cure?
    > >

    >
    >
    > --
    > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    > Jim Lewis
    > Director of Training mailto:
    > SynthWorks Design Inc. http://www.SynthWorks.com
    > 1-503-590-4787
    >
    > Expert VHDL Training for Hardware Design and Verification
    > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    Andy, Sep 19, 2006
    #5
  6. rickman

    KJ Guest

    rickman wrote:
    >
    > constant SWAP : IRSLV := to_slv(FIXOP + 16#00#, 8); -- E0 (1110 0000)

    Could 'SWAP' be an integer instead?
    i.e. constant SWAP: integer range 0 to ?? : FIXOP + 16#00#;
    >
    > type INSTDSPLY is (RST, IACK, LTR, JMP, JUMZ, JUMC, JUMO, CALA, CALR,
    > SWP, OVR, RUP, DUP, SHFL, SHFC, ZFLG, RFTC,
    > RDRP, RTN, FTCH, FCHB, RFRM, RSB, RCM, FCHP, FHPB, RARS,
    > DDRP, TOR, CPNC, CPC, ADNC, ADC, SBNC, SBC,
    > BFL, RTI, STOR, STRB, BLAN, RADT, BLOR, STRP, STPB, BLXR);
    >
    > when TO_INTEGER(UNSIGNED(SWAP)) => return SWP;

    If 'SWAP' was an integer then the above line would simply be
    when SWAP => return SWP;

    Alternatively, if 'SWAP' really needs to be a standard logic vector
    then you could use the following lines of code in the appropriate
    places...
    constant SWAP_integer: integer range 0 to ?? : FIXOP + 16#00#;
    constant SWAP : IRSLV := to_slv(SWAP_integer); -- E0 (1110 0000)
    when SWAP_integer => return SWP;

    As yet another alternative, if the point of the case statements is to
    translate between integers and 'INSTDSPLY' elements, the whole case
    statement might be replaced by

    variable An_Instruction: INSTDSPLY :=
    INSTDSPLY'pos(An_Instruction_Index);

    The reverse translation from INSTDSPLY to an index would be...

    variable An_Instruction_Index: integer range 0 to ??:
    INSTDSPLY'val(An_Instruction);

    The ?? on the upper end of the integer range in the above is something
    that equates to...

    INSTDSPLY'pos(BLXR) - INSTDSPLY'pos(RST)

    There is a cleaner way to get this upper end of the integer range but I
    forget what it is and whenever I do something like this I have to go
    back and relook it up. What you need to get is the position of the
    rightmost element of INSTDSPLY (so that you don't have to make the
    assumption that 'BLXR' is the rightmost one). I'm pretty sure that
    "INSTDSPLY'pos(RST)" will return 0...but again, the brain is foggy on
    whether the leftmost element of an enumerated type is position '0' or
    '1'. Once again though the idea is to get the index of the leftmost
    element. And now that I recall a bit more, to really be clean about
    it, the lower bound on the index should be INSTDSPLY'pos(the leftmost
    element) and not necessarily 0.

    That may help somewhat.

    KJ
    KJ, Sep 19, 2006
    #6
  7. rickman

    rickman Guest

    KJ wrote:
    > rickman wrote:
    > >
    > > constant SWAP : IRSLV := to_slv(FIXOP + 16#00#, 8); -- E0 (1110 0000)

    > Could 'SWAP' be an integer instead?
    > i.e. constant SWAP: integer range 0 to ?? : FIXOP + 16#00#;


    No, SWAP is the SLV corresponding to the instruction as used in the
    synthesized code. I don't want to clutter that up with conversions.
    So it needs to be SLV.

    Everything else is just for displaying a coherent value in the
    simulator. Rather than having to look at the hex for an instruction, I
    can view the enumerated value that is returned from this conversion
    routine since the simulator will display the ASCII name of the
    enumerated value.

    > > type INSTDSPLY is (RST, IACK, LTR, JMP, JUMZ, JUMC, JUMO, CALA, CALR,
    > > SWP, OVR, RUP, DUP, SHFL, SHFC, ZFLG, RFTC,
    > > RDRP, RTN, FTCH, FCHB, RFRM, RSB, RCM, FCHP, FHPB, RARS,
    > > DDRP, TOR, CPNC, CPC, ADNC, ADC, SBNC, SBC,
    > > BFL, RTI, STOR, STRB, BLAN, RADT, BLOR, STRP, STPB, BLXR);
    > >
    > > when TO_INTEGER(UNSIGNED(SWAP)) => return SWP;

    > If 'SWAP' was an integer then the above line would simply be
    > when SWAP => return SWP;
    >
    > Alternatively, if 'SWAP' really needs to be a standard logic vector
    > then you could use the following lines of code in the appropriate
    > places...
    > constant SWAP_integer: integer range 0 to ?? : FIXOP + 16#00#;
    > constant SWAP : IRSLV := to_slv(SWAP_integer); -- E0 (1110 0000)
    > when SWAP_integer => return SWP;


    Yes, that is what I will have to do, add an integer constant for every
    one of the 36 opcodes. So each opcode will have an SLV value, an
    integer value and an enumerated value. Not such a big deal really.


    > As yet another alternative, if the point of the case statements is to
    > translate between integers and 'INSTDSPLY' elements, the whole case
    > statement might be replaced by
    >
    > variable An_Instruction: INSTDSPLY :=
    > INSTDSPLY'pos(An_Instruction_Index);


    I believe this converts to an enumerated value. If you check, I think
    you will find that the required conversion is from SLV to the
    enumerated value.

    > The reverse translation from INSTDSPLY to an index would be...
    >
    > variable An_Instruction_Index: integer range 0 to ??:
    > INSTDSPLY'val(An_Instruction);
    >
    > The ?? on the upper end of the integer range in the above is something
    > that equates to...
    >
    > INSTDSPLY'pos(BLXR) - INSTDSPLY'pos(RST)
    >
    > There is a cleaner way to get this upper end of the integer range but I
    > forget what it is and whenever I do something like this I have to go
    > back and relook it up. What you need to get is the position of the
    > rightmost element of INSTDSPLY (so that you don't have to make the
    > assumption that 'BLXR' is the rightmost one). I'm pretty sure that
    > "INSTDSPLY'pos(RST)" will return 0...but again, the brain is foggy on
    > whether the leftmost element of an enumerated type is position '0' or
    > '1'. Once again though the idea is to get the index of the leftmost
    > element. And now that I recall a bit more, to really be clean about
    > it, the lower bound on the index should be INSTDSPLY'pos(the leftmost
    > element) and not necessarily 0.
    >
    > That may help somewhat.


    Thanks for the ideas. This may all be academic. This is a CPU that I
    built a while back for an Altera ACEX part since Altera does not
    support their NIOS for that family. After spending a fair amount of
    time on the architecture, I did the minimum of actual coding and design
    to get it running. If memory serves me, it clocked in at 55 MHz max
    and it was run at 40 MHz. Currently I wanted to look at how fast it
    might run if I redid it for a current FPGA architecture using
    synchronous memories. I compiled it for a Spartan 3 and got a speed up
    to 77 MHz using less than 10% of an XC3S400 (about 310 slices I
    believe). I am not impressed with the speed. I expected a much larger
    increase and had hoped for operation at over 100 MHz. Although it may
    approach 100 MHz with careful floorplanning, I don't think this is
    worth the effort.

    Instead I think it will take a look at the third party MicroBlaze core
    and see if that is as small and fast and memory efficient. There is
    little reason to knock myself out when so many have done this before me.
    rickman, Sep 19, 2006
    #7
  8. rickman

    Andy Guest

    Another alternative is to do the conversion in the case expression, not
    the when expression(s).

    The compiler only needs to know the type of the return of the
    conversion function, which is locally static information, since it is
    defined in the package declaration, not the package body.

    The when target expression VALUES (not just type) must be locally
    static so that the compiler can verify that every possible value of the
    case expression (bound by the type of the expression) is covered
    exactly once in the targets.

    Andy


    rickman wrote:
    > KJ wrote:
    > > rickman wrote:
    > > >
    > > > constant SWAP : IRSLV := to_slv(FIXOP + 16#00#, 8); -- E0 (1110 0000)

    > > Could 'SWAP' be an integer instead?
    > > i.e. constant SWAP: integer range 0 to ?? : FIXOP + 16#00#;

    >
    > No, SWAP is the SLV corresponding to the instruction as used in the
    > synthesized code. I don't want to clutter that up with conversions.
    > So it needs to be SLV.
    >
    > Everything else is just for displaying a coherent value in the
    > simulator. Rather than having to look at the hex for an instruction, I
    > can view the enumerated value that is returned from this conversion
    > routine since the simulator will display the ASCII name of the
    > enumerated value.
    >
    > > > type INSTDSPLY is (RST, IACK, LTR, JMP, JUMZ, JUMC, JUMO, CALA, CALR,
    > > > SWP, OVR, RUP, DUP, SHFL, SHFC, ZFLG, RFTC,
    > > > RDRP, RTN, FTCH, FCHB, RFRM, RSB, RCM, FCHP, FHPB, RARS,
    > > > DDRP, TOR, CPNC, CPC, ADNC, ADC, SBNC, SBC,
    > > > BFL, RTI, STOR, STRB, BLAN, RADT, BLOR, STRP, STPB, BLXR);
    > > >
    > > > when TO_INTEGER(UNSIGNED(SWAP)) => return SWP;

    > > If 'SWAP' was an integer then the above line would simply be
    > > when SWAP => return SWP;
    > >
    > > Alternatively, if 'SWAP' really needs to be a standard logic vector
    > > then you could use the following lines of code in the appropriate
    > > places...
    > > constant SWAP_integer: integer range 0 to ?? : FIXOP + 16#00#;
    > > constant SWAP : IRSLV := to_slv(SWAP_integer); -- E0 (1110 0000)
    > > when SWAP_integer => return SWP;

    >
    > Yes, that is what I will have to do, add an integer constant for every
    > one of the 36 opcodes. So each opcode will have an SLV value, an
    > integer value and an enumerated value. Not such a big deal really.
    >
    >
    > > As yet another alternative, if the point of the case statements is to
    > > translate between integers and 'INSTDSPLY' elements, the whole case
    > > statement might be replaced by
    > >
    > > variable An_Instruction: INSTDSPLY :=
    > > INSTDSPLY'pos(An_Instruction_Index);

    >
    > I believe this converts to an enumerated value. If you check, I think
    > you will find that the required conversion is from SLV to the
    > enumerated value.
    >
    > > The reverse translation from INSTDSPLY to an index would be...
    > >
    > > variable An_Instruction_Index: integer range 0 to ??:
    > > INSTDSPLY'val(An_Instruction);
    > >
    > > The ?? on the upper end of the integer range in the above is something
    > > that equates to...
    > >
    > > INSTDSPLY'pos(BLXR) - INSTDSPLY'pos(RST)
    > >
    > > There is a cleaner way to get this upper end of the integer range but I
    > > forget what it is and whenever I do something like this I have to go
    > > back and relook it up. What you need to get is the position of the
    > > rightmost element of INSTDSPLY (so that you don't have to make the
    > > assumption that 'BLXR' is the rightmost one). I'm pretty sure that
    > > "INSTDSPLY'pos(RST)" will return 0...but again, the brain is foggy on
    > > whether the leftmost element of an enumerated type is position '0' or
    > > '1'. Once again though the idea is to get the index of the leftmost
    > > element. And now that I recall a bit more, to really be clean about
    > > it, the lower bound on the index should be INSTDSPLY'pos(the leftmost
    > > element) and not necessarily 0.
    > >
    > > That may help somewhat.

    >
    > Thanks for the ideas. This may all be academic. This is a CPU that I
    > built a while back for an Altera ACEX part since Altera does not
    > support their NIOS for that family. After spending a fair amount of
    > time on the architecture, I did the minimum of actual coding and design
    > to get it running. If memory serves me, it clocked in at 55 MHz max
    > and it was run at 40 MHz. Currently I wanted to look at how fast it
    > might run if I redid it for a current FPGA architecture using
    > synchronous memories. I compiled it for a Spartan 3 and got a speed up
    > to 77 MHz using less than 10% of an XC3S400 (about 310 slices I
    > believe). I am not impressed with the speed. I expected a much larger
    > increase and had hoped for operation at over 100 MHz. Although it may
    > approach 100 MHz with careful floorplanning, I don't think this is
    > worth the effort.
    >
    > Instead I think it will take a look at the third party MicroBlaze core
    > and see if that is as small and fast and memory efficient. There is
    > little reason to knock myself out when so many have done this before me.
    Andy, Sep 20, 2006
    #8
  9. rickman

    rickman Guest

    You play a good game Andy! Thanks for the advice.

    Andy wrote:
    > Another alternative is to do the conversion in the case expression, not
    > the when expression(s).
    >
    > The compiler only needs to know the type of the return of the
    > conversion function, which is locally static information, since it is
    > defined in the package declaration, not the package body.
    >
    > The when target expression VALUES (not just type) must be locally
    > static so that the compiler can verify that every possible value of the
    > case expression (bound by the type of the expression) is covered
    > exactly once in the targets.
    >
    > Andy
    >
    >
    > rickman wrote:
    > > KJ wrote:
    > > > rickman wrote:
    > > > >
    > > > > constant SWAP : IRSLV := to_slv(FIXOP + 16#00#, 8); -- E0 (1110 0000)
    > > > Could 'SWAP' be an integer instead?
    > > > i.e. constant SWAP: integer range 0 to ?? : FIXOP + 16#00#;

    > >
    > > No, SWAP is the SLV corresponding to the instruction as used in the
    > > synthesized code. I don't want to clutter that up with conversions.
    > > So it needs to be SLV.
    > >
    > > Everything else is just for displaying a coherent value in the
    > > simulator. Rather than having to look at the hex for an instruction, I
    > > can view the enumerated value that is returned from this conversion
    > > routine since the simulator will display the ASCII name of the
    > > enumerated value.
    > >
    > > > > type INSTDSPLY is (RST, IACK, LTR, JMP, JUMZ, JUMC, JUMO, CALA, CALR,
    > > > > SWP, OVR, RUP, DUP, SHFL, SHFC, ZFLG, RFTC,
    > > > > RDRP, RTN, FTCH, FCHB, RFRM, RSB, RCM, FCHP, FHPB, RARS,
    > > > > DDRP, TOR, CPNC, CPC, ADNC, ADC, SBNC, SBC,
    > > > > BFL, RTI, STOR, STRB, BLAN, RADT, BLOR, STRP, STPB, BLXR);
    > > > >
    > > > > when TO_INTEGER(UNSIGNED(SWAP)) => return SWP;
    > > > If 'SWAP' was an integer then the above line would simply be
    > > > when SWAP => return SWP;
    > > >
    > > > Alternatively, if 'SWAP' really needs to be a standard logic vector
    > > > then you could use the following lines of code in the appropriate
    > > > places...
    > > > constant SWAP_integer: integer range 0 to ?? : FIXOP + 16#00#;
    > > > constant SWAP : IRSLV := to_slv(SWAP_integer); -- E0 (1110 0000)
    > > > when SWAP_integer => return SWP;

    > >
    > > Yes, that is what I will have to do, add an integer constant for every
    > > one of the 36 opcodes. So each opcode will have an SLV value, an
    > > integer value and an enumerated value. Not such a big deal really.
    > >
    > >
    > > > As yet another alternative, if the point of the case statements is to
    > > > translate between integers and 'INSTDSPLY' elements, the whole case
    > > > statement might be replaced by
    > > >
    > > > variable An_Instruction: INSTDSPLY :=
    > > > INSTDSPLY'pos(An_Instruction_Index);

    > >
    > > I believe this converts to an enumerated value. If you check, I think
    > > you will find that the required conversion is from SLV to the
    > > enumerated value.
    > >
    > > > The reverse translation from INSTDSPLY to an index would be...
    > > >
    > > > variable An_Instruction_Index: integer range 0 to ??:
    > > > INSTDSPLY'val(An_Instruction);
    > > >
    > > > The ?? on the upper end of the integer range in the above is something
    > > > that equates to...
    > > >
    > > > INSTDSPLY'pos(BLXR) - INSTDSPLY'pos(RST)
    > > >
    > > > There is a cleaner way to get this upper end of the integer range but I
    > > > forget what it is and whenever I do something like this I have to go
    > > > back and relook it up. What you need to get is the position of the
    > > > rightmost element of INSTDSPLY (so that you don't have to make the
    > > > assumption that 'BLXR' is the rightmost one). I'm pretty sure that
    > > > "INSTDSPLY'pos(RST)" will return 0...but again, the brain is foggy on
    > > > whether the leftmost element of an enumerated type is position '0' or
    > > > '1'. Once again though the idea is to get the index of the leftmost
    > > > element. And now that I recall a bit more, to really be clean about
    > > > it, the lower bound on the index should be INSTDSPLY'pos(the leftmost
    > > > element) and not necessarily 0.
    > > >
    > > > That may help somewhat.

    > >
    > > Thanks for the ideas. This may all be academic. This is a CPU that I
    > > built a while back for an Altera ACEX part since Altera does not
    > > support their NIOS for that family. After spending a fair amount of
    > > time on the architecture, I did the minimum of actual coding and design
    > > to get it running. If memory serves me, it clocked in at 55 MHz max
    > > and it was run at 40 MHz. Currently I wanted to look at how fast it
    > > might run if I redid it for a current FPGA architecture using
    > > synchronous memories. I compiled it for a Spartan 3 and got a speed up
    > > to 77 MHz using less than 10% of an XC3S400 (about 310 slices I
    > > believe). I am not impressed with the speed. I expected a much larger
    > > increase and had hoped for operation at over 100 MHz. Although it may
    > > approach 100 MHz with careful floorplanning, I don't think this is
    > > worth the effort.
    > >
    > > Instead I think it will take a look at the third party MicroBlaze core
    > > and see if that is as small and fast and memory efficient. There is
    > > little reason to knock myself out when so many have done this before me.
    rickman, Sep 20, 2006
    #9
    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. Mohammed  A khader
    Replies:
    1
    Views:
    2,570
    Jonathan Bromley
    Jan 28, 2005
  2. Kenneth Johansson
    Replies:
    9
    Views:
    8,777
    Mike Treseler
    May 9, 2005
  3. Rick North
    Replies:
    10
    Views:
    4,090
    Rick North
    Jul 27, 2005
  4. Peter
    Replies:
    9
    Views:
    4,590
    Peter
    Feb 21, 2011
  5. a s
    Replies:
    7
    Views:
    1,171
    Mike Treseler
    Nov 30, 2011
Loading...

Share This Page