![]() |
|
|
|
#1 |
|
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#, 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 |
|
|
|
|
#2 |
|
Posts: n/a
|
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#, > > 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? |
|
|
|
#3 |
|
Posts: n/a
|
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#, > > 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 private.php?do=newpm&u= SynthWorks Design Inc. http://www.SynthWorks.com 1-503-590-4787 Expert VHDL Training for Hardware Design and Verification ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~ |
|
|
|
#4 |
|
Posts: n/a
|
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#, >> >> 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 |
|
|
|
#5 |
|
Posts: n/a
|
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#, > > > > 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 private.php?do=newpm&u= > SynthWorks Design Inc. http://www.SynthWorks.com > 1-503-590-4787 > > Expert VHDL Training for Hardware Design and Verification > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~ |
|
|
|
#6 |
|
Posts: n/a
|
rickman wrote: > > constant SWAP : IRSLV := to_slv(FIXOP + 16#00#, 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 |
|
|
|
#7 |
|
Posts: n/a
|
KJ wrote:
> rickman wrote: > > > > constant SWAP : IRSLV := to_slv(FIXOP + 16#00#, > 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. |
|
|
|
#8 |
|
Posts: n/a
|
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#, > > 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. |
|
|
|
#9 |
|
Posts: n/a
|
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#, > > > 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. |
|