Hi, I am using Xilinx ISE 11.1 with XST for compiling Verilog code. XST 11.1 for Virtex 5 doesn't support using the disable keyword from within a for loop. Instead they recommended code like this: http://www.xilinx.com/support/answers/22177.htm integer i; always @(posedge clk) begin for(i = 0; i < NUM_LOOPS; i = i + 1) begin if(ready[i]) begin go[i] <= 1; i = NUM_LOOPS; end end end I have found this code to be synthesized incorrectly as the loop isn't actually exited after i is set to NUM_LOOPS, and therefore multiple bits of go are raised in a single clock. They have said that this isn't supported in the standard. Can someone shed light on this? Is this code supported and should it work? I don't have the LRM and I can't find any definitive answer on whether this code is legal Verilog syntax, and whether it should work. Thanx, Nachum Kanovsky
Verilog "for loop" - exit by setting i to exit value?
This discussion addresses issues with using a for loop in Verilog to break early by modifying the loop counter, specifically when using Xilinx XST for synthesis. While such code is valid according to the Verilog LRM for simulation, it often synthesizes incorrectly or is rejected by tools that require static loop unrolling.
The consensus recommendation is to avoid modifying loop indices directly and instead use a 'found' flag variable to suppress activity in subsequent iterations. This approach ensures consistent behavior between simulation and synthesis while adhering to hardware design best practices.
- Modifying a loop counter within a Verilog loop is LRM-legal for simulation but frequently causes synthesis errors in Xilinx XST.
- The recommended workaround is to use a local 'found' boolean variable to gate the logic within the loop body.
- Using a module-level variable as a loop counter can cause unintended interactions in simulation; local declarations are preferred.
- Synthesis tools generally require static loop bounds to perform hardware unrolling effectively.
- VHDL and SystemVerilog offer more robust scoping for loop counters to prevent these common coding pitfalls.
On Fri, 12 Jun 2009 03:10:37 -0700 (PDT), nachum <nachumk@gmail.com> wrote:> for(i = 0; i < NUM_LOOPS; i = i + 1) > begin > if(ready[i]) > begin > go[i] <= 1; > i = NUM_LOOPS; > end > end>I have found this code to be synthesized incorrectly as the loop isn't >actually exited after i is set to NUM_LOOPS, and therefore multiple >bits of go are raised in a single clock.Not a Verilog user but if I understand the problem, my suggestion is to transform the loop into one in which the loop extent remains static, which is less likely to cause grief at synthesis time. Something like for i in 0 to NUM_LOOPS loop if ready(i) and not done then go(i) <= 1; done <= TRUE; -- originally i = NUM_LOOPS; end if; end loop; Shouldn't result in any more hardware. - Brian
On Fri, 12 Jun 2009 03:10:37 -0700 (PDT), nachum wrote:>Hi, > >I am using Xilinx ISE 11.1 with XST for compiling Verilog code. XST >11.1 for Virtex 5 doesn't support using the disable keyword from >within a for loop. Instead they recommended code like this:Oh dear. Some attitude readjustment is in order, I think.>integer i; >always @(posedge clk) >begin > for(i = 0; i < NUM_LOOPS; i = i + 1) > begin > if(ready[i]) > begin > go[i] <= 1; > i = NUM_LOOPS; > end > end >end > >I have found this code to be synthesized incorrectly as the loop isn't >actually exited after i is set to NUM_LOOPS, and therefore multiple >bits of go are raised in a single clock. > >They have said that this isn't supported in the standard.Well.... it *is* supported by Verilog, for sure, but it's truly ghastly. Brian was right; if you can't use "disable", then do the same thing you would expect your synth tool to do: allow the loop to run to completion (because you can't on-the-fly change how much hardware you have!) but suppress its activity in the unwanted passes of the loop. This should synthesise OK: integer i; always @(posedge clk) begin : find_first_one // label the begin..end reg found; // local variable inside named block found = 0; // be sure to do this!!! for(i = 0; i < NUM_LOOPS; i = i + 1) if (!found) // still looking??? begin if(ready[i]) begin go[i] <= 1; found = 1; // this suppresses later trips end end end end This idiom will synthesise a ripple-OR chain to get the specified priority-encoding behaviour. If you get really lucky, it just might use the carry-chain resources to do that faster.... BTW, your code as it stands is not very useful because nothing ever clears go[], but I guess you intentionally deleted a bunch of other code. As far as the Verilog language rules are concerned: a loop counter, declared in the way you showed, is just an ordinary variable and you can indeed set its value inside the loop, but please tell me you're not going to do that. Ever. Please. Really, don't. You should also be aware that it is an exceptionally bad idea to use a module-level variable as a loop counter in Verilog. Make use of the named-block feature to make the loop counter local: always @(whatever) begin : named_block integer i; // LOCAL loop counter for (i = 0; ..... That way, there's no risk of nasty interaction between the 'i' counters of various different loops. Finally, be aware that SystemVerilog has seen the error of Verilog's ways and allows you to declare truly local loop counters: for (int i = 0; i<LIMIT; i++) begin ... This 'i' doesn't exist at all outside the loop body. Much, much nicer, and easier for synthesis tools to deal with as well. Not supported in all tools just yet, of course. -- Jonathan Bromley, Consultant DOULOS - Developing Design Know-how VHDL * Verilog * SystemC * e * Perl * Tcl/Tk * Project Services Doulos Ltd., 22 Market Place, Ringwood, BH24 1AW, UK jonathan.bromley@MYCOMPANY.com http://www.MYCOMPANY.com The contents of this message may contain personal views which are not the views of Doulos Ltd., unless specifically stated.
On Jun 12, 4:50=A0pm, Jonathan Bromley <jonathan.brom...@MYCOMPANY.com> wrote:> On Fri, 12 Jun 2009 03:10:37 -0700 (PDT), nachum wrote: > >Hi, > > >I am using Xilinx ISE 11.1 with XST for compiling Verilog code. XST > >11.1 for Virtex 5 doesn't support using the disable keyword from > >within a for loop. Instead they recommended code like this: > > Oh dear. =A0Some attitude readjustment is in order, I think. > > > > >integer i; > >always @(posedge clk) > >begin > > for(i =3D 0; i < NUM_LOOPS; i =3D i + 1) > > begin > > =A0if(ready[i]) > > =A0begin > > =A0 go[i] <=3D 1; > > =A0 i =3D NUM_LOOPS; > > =A0end > > end > >end > > >I have found this code to be synthesized incorrectly as the loop isn't > >actually exited after i is set to NUM_LOOPS, and therefore multiple > >bits of go are raised in a single clock. > > >They have said that this isn't supported in the standard. > > Well.... =A0it *is* supported by Verilog, for sure, but > it's truly ghastly. =A0Brian was right; if you can't use > "disable", then do the same thing you would expect your > synth tool to do: allow the loop to run to completion > (because you can't on-the-fly change how much hardware > you have!) but suppress its activity in the unwanted > passes of the loop. =A0This should synthesise OK: > > =A0 integer i; > =A0 always @(posedge clk) > =A0 begin : find_first_one =A0// label the begin..end > =A0 =A0 reg found; =A0// local variable inside named block > =A0 =A0 found =3D 0; =A0// be sure to do this!!! =A0 > =A0 =A0 for(i =3D 0; i < NUM_LOOPS; i =3D i + 1) > =A0 =A0 =A0 if (!found) // still looking??? > =A0 =A0 =A0 begin > =A0 =A0 =A0 =A0 if(ready[i]) > =A0 =A0 =A0 =A0 begin > =A0 =A0 =A0 =A0 =A0 go[i] <=3D 1; > =A0 =A0 =A0 =A0 =A0 found =3D 1; // this suppresses later trips > =A0 =A0 =A0 =A0 end > =A0 =A0 =A0 end > =A0 =A0 end > =A0 end > > This idiom will synthesise a ripple-OR chain to > get the specified priority-encoding behaviour. > If you get really lucky, it just might use the > carry-chain resources to do that faster.... > > BTW, your code as it stands is not very useful > because nothing ever clears go[], but I guess > you intentionally deleted a bunch of other code. > > As far as the Verilog language rules are concerned: > a loop counter, declared in the way you showed, is > just an ordinary variable and you can indeed set its > value inside the loop, but please tell me you're not > going to do that. =A0Ever. =A0Please. =A0Really, don't. > > You should also be aware that it is an exceptionally > bad idea to use a module-level variable as a loop > counter in Verilog. =A0Make use of the named-block > feature to make the loop counter local: > > =A0 always @(whatever) begin : named_block > =A0 =A0 integer i; =A0// LOCAL loop counter > =A0 =A0 for (i =3D 0; ..... > > That way, there's no risk of nasty interaction > between the 'i' counters of various different loops. > > Finally, be aware that SystemVerilog has seen the > error of Verilog's ways and allows you to declare > truly local loop counters: > > =A0 =A0for (int i =3D 0; i<LIMIT; i++) begin ... > > This 'i' doesn't exist at all outside the loop body. > Much, much nicer, and easier for synthesis tools > to deal with as well. =A0Not supported in all tools > just yet, of course. > -- > Jonathan Bromley, Consultant > > DOULOS - Developing Design Know-how > VHDL * Verilog * SystemC * e * Perl * Tcl/Tk * Project Services > > Doulos Ltd., 22 Market Place, Ringwood, BH24 1AW, UK > jonathan.brom...@MYCOMPANY.comhttp://www.MYCOMPANY.com > > The contents of this message may contain personal views which > are not the views of Doulos Ltd., unless specifically stated.Thanks for the responses, The only thing that interests me regarding this specific code is whether it is legal according to the Verilog LRM. Xilinx claims that my above code is illegal, and the old XST synthesizes it wrong, whereas the new XST doesn't support it outright. I wrote the code up above on the fly to demonstrate, so I didn't bother declaring some things or resetting "go". The variable i is only used during synthesis to create the appropriate amount of hardware to do the job. The "i =3D NUM_LOOPS" should create hardware identical to using a found variable. I also never bother to create local i variables b/c I do not use them as values, but only as loop iterators, and as the iterators are synthesized away by definition there should be no fear of them interacting with each other. In that sense the i variable is likened to a generate loop. This is also evidenced by the workaround I have been forced to implement due to XST's inability with exiting for loops: integer i; always @(posedge clk) begin i =3D 0; found =3D 0; go <=3D 0; //resetting go :) while((i < NUM_LOOPS) && !found) begin if(ready[i]) begin go[i] <=3D 1; found =3D 1; end i =3D i + 1; end end I have this type of code in my modules multiple times over for various loop situations, and they all use the same i variable. That code is properly synthesized. This page http://www.xilinx.com/support/answers/22066= .htm shows that XST has issues with multiple for loops in the same module using the same iterator. That is listed by them as a bug which needs to be worked around, but they don't mention anything about it being illegal or dangerous. Can I get a better explanation as to why my originally suggested for loop is so bad? Your comment that it is ghastly makes me wonder. I would love to know if the Verilog LRM fully supports my code? I want Xilinx to fix XST to support it as I believe it should. Thank you again, Nachum Kanovsky ionipti.blogspot.com
On Fri, 12 Jun 2009 07:30:25 -0700 (PDT), nachumk wrote:>The only thing that interests me regarding this specific code is >whether it is legal according to the Verilog LRM.It's LRM-legal. Try this in any simulator: module loop; integer i; initial begin for (i=0; i<100; i=i+1) begin $display("loop %0d", i); i = i * 2; end end endmodule>Xilinx claims that my above code is illegalThey're wrong.>The variable i is only used during synthesis to create the appropriate >amount of hardware to do the job.Of course. If you use a loop in any other way, it will probably not be synthesisable.>The "i = NUM_LOOPS" should create >hardware identical to using a found variable.That's less obviously true. I agree that it will work that way in simulation, but synthesis must unroll the loop and therefore it must treat the loop counter as a constant on each trip around the loop. Hacking a loop counter is an unpleasant thing to do even in software, but it is a crazy thing to do for synthesis.> I also never bother to >create local i variables b/c I do not use them as values, but only as >loop iterators, and as the iterators are synthesized away by >definition there should be no fear of them interacting with each >other.In synthesis, and in practice, you are right. But it is a very bad habit to get into, and "by definition" there most definitely IS a fear of them interacting, because of Verilog's scheduling semantics that allows arbitrary interleaving of concurrent processes. As soon as you start writing testbench code that has time delays in loops, this becomes a very serious problem indeed - and one that is very easily fixed by using locally-declared loop counters.> In that sense the i variable is likened to a generate loop.In the sense that it is unrolled for synthesis, yes. But that is NOT the Verilog language semantics of a for-loop. Interestingly, you seem to be contradicting yourself here. I agree that procedural for-loops act somewhat like generate-for loops in synthesis. But surely you would not expect to be able to modify a genvar loop counter in the body of a generate-for loop? So why do you think it's a good idea to modify a procedural loop counter in the body of a for-loop that will be synthesised?>This is also evidenced by the workaround I have been forced to >implement due to XST's inability with exiting for loops: > >integer i; >always @(posedge clk) >begin > i = 0; > found = 0; > go <= 0; //resetting go :) > while((i < NUM_LOOPS) && !found) > begin > if(ready[i]) > begin > go[i] <= 1; > found = 1; > end > i = i + 1; > end >endInteresting; there are many synthesis tools that cannot handle while loops, so I suggest that the (very similar) workaround that I showed you in my previous posting is more likely to be portable.>I have this type of code in my modules multiple times over for various >loop situations, and they all use the same i variable.As I've already explained, that is probably OK for synthesis but it's unnecessarily poor style.>That code is >properly synthesized. This page http://www.xilinx.com/support/answers/22066.htm >shows that XST has issues with multiple for loops in the same module >using the same iterator. That is listed by them as a bug which needs >to be worked around, but they don't mention anything about it being >illegal or dangerous.Locally declared loop iterators are... - more stylish and easier to understand - essential when you write testbench code - much less likely to excite that kind of bug So why make life difficult for yourself, your code reviewers and the synthesis tool?>Can I get a better explanation as to why my originally suggested for >loop is so bad? Your comment that it is ghastly makes me wonder.Can you spell "information hiding" or "locality of reference"? Locality is always good if you can do it. Letting things float out to a less local context than necessary, like your shared loop variables, is error-prone and confusing. If my 'i' is localized to the block that uses it, then other blocks can do anything they want with some other 'i' and everything is OK. If your loop counter is global, you can easily make silly mistakes: module foo (...ports...); reg [7:0] counter; always @(posedge clock) begin if (count_enable) counter <= counter + 1; end always @(whatever) for (counter = 0; counter <= LIMIT; counter = counter + 1) ... see what I mean? no, of course you wouldn't do that, and of course you would get errors from synthesis, but why expose yourself to the risk when it's so easy to do local declaration of variables that are only locally relevant?>I would love to know if the Verilog LRM fully supports my code?As I already said, yes, it does. Nowhere does the LRM say that it's illegal to write to a loop counter.>I want Xilinx to fix XST to support it as I believe it should.I want lots of other things much, much more than I want that. -- Jonathan Bromley, Consultant DOULOS - Developing Design Know-how VHDL * Verilog * SystemC * e * Perl * Tcl/Tk * Project Services Doulos Ltd., 22 Market Place, Ringwood, BH24 1AW, UK jonathan.bromley@MYCOMPANY.com http://www.MYCOMPANY.com The contents of this message may contain personal views which are not the views of Doulos Ltd., unless specifically stated.
On Jun 12, 5:56=A0pm, Jonathan Bromley <jonathan.brom...@MYCOMPANY.com> wrote:> On Fri, 12 Jun 2009 07:30:25 -0700 (PDT), nachumk wrote: > >The only thing that interests me regarding this specific code is > >whether it is legal according to the Verilog LRM. > > It's LRM-legal. =A0Try this in any simulator: > > module loop; > =A0 integer i; > =A0 initial begin > =A0 =A0 for (i=3D0; i<100; i=3Di+1) begin > =A0 =A0 =A0 $display("loop %0d", i); > =A0 =A0 =A0 i =3D i * 2; > =A0 =A0 end > =A0 end > endmodule > > >Xilinx claims that my above code is illegal > > They're wrong. > > >The variable i is only used during synthesis to create the appropriate > >amount of hardware to do the job. > > Of course. =A0If you use a loop in any other way, > it will probably not be synthesisable. > > >The "i =3D NUM_LOOPS" should create > >hardware identical to using a found variable. > > That's less obviously true. =A0I agree that it will work that > way in simulation, but synthesis must unroll the loop and > therefore it must treat the loop counter as a constant on > each trip around the loop. =A0Hacking a loop counter is an > unpleasant thing to do even in software, but it is a crazy > thing to do for synthesis. > > > I also never bother to > >create local i variables b/c I do not use them as values, but only as > >loop iterators, and as the iterators are synthesized away by > >definition there should be no fear of them interacting with each > >other. > > In synthesis, and in practice, you are right. =A0But it is a very > bad habit to get into, and "by definition" there most definitely > IS a fear of them interacting, because of Verilog's scheduling > semantics that allows arbitrary interleaving of concurrent > processes. =A0As soon as you start writing testbench code > that has time delays in loops, this becomes a very serious > problem indeed - and one that is very easily fixed by > using locally-declared loop counters. > > > In that sense the i variable is likened to a generate loop. > > In the sense that it is unrolled for synthesis, yes. =A0But > that is NOT the Verilog language semantics of a for-loop. > > Interestingly, you seem to be contradicting yourself here. > I agree that procedural for-loops act somewhat like > generate-for loops in synthesis. =A0But surely you would > not expect to be able to modify a genvar loop counter > in the body of a generate-for loop? =A0So why do you think > it's a good idea to modify a procedural loop counter > in the body of a for-loop that will be synthesised? > > > > >This is also evidenced by the workaround I have been forced to > >implement due to XST's inability with exiting for loops: > > >integer i; > >always @(posedge clk) > >begin > > i =3D 0; > > found =3D 0; > > go <=3D 0; //resetting go :) > > while((i < NUM_LOOPS) && !found) > > begin > > =A0if(ready[i]) > > =A0begin > > =A0 go[i] <=3D 1; > > =A0 found =3D 1; > > =A0end > > =A0i =3D i + 1; > > end > >end > > Interesting; there are many synthesis tools that cannot > handle while loops, so I suggest that the (very similar) > workaround that I showed you in my previous posting is > more likely to be portable. > > >I have this type of code in my modules multiple times over for various > >loop situations, and they all use the same i variable. > > As I've already explained, that is probably OK for synthesis > but it's unnecessarily poor style. > > >That code is > >properly synthesized. This pagehttp://www.xilinx.com/support/answers/220=66.htm> >shows that XST has issues with multiple for loops in the same module > >using the same iterator. That is listed by them as a bug which needs > >to be worked around, but they don't mention anything about it being > >illegal or dangerous. > > Locally declared loop iterators are... > - more stylish and easier to understand > - essential when you write testbench code > - much less likely to excite that kind of bug > So why make life difficult for yourself, your code reviewers > and the synthesis tool? > > >Can I get a better explanation as to why my originally suggested for > >loop is so bad? Your comment that it is ghastly makes me wonder. > > Can you spell "information hiding" or "locality of reference"? > Locality is always good if you can do it. =A0Letting things > float out to a less local context than necessary, like your > shared loop variables, is error-prone and confusing. > If my 'i' is localized to the block that uses it, then other > blocks can do anything they want with some other 'i' and > everything is OK. =A0If your loop counter is global, you can > easily make silly mistakes: > > =A0 module foo (...ports...); > > =A0 =A0 reg [7:0] counter; > > =A0 =A0 always @(posedge clock) begin > =A0 =A0 =A0 if (count_enable) > =A0 =A0 =A0 =A0 counter <=3D counter + 1; > =A0 =A0 end > > =A0 =A0 always @(whatever) > =A0 =A0 =A0 for (counter =3D 0; counter <=3D LIMIT; counter =3D counter +=1)> =A0 =A0 =A0 =A0 ... > > see what I mean? =A0no, of course you wouldn't do that, and of > course you would get errors from synthesis, but why expose yourself > to the risk when it's so easy to do local declaration of variables > that are only locally relevant? > > >I would love to know if the Verilog LRM fully supports my code? > > As I already said, yes, it does. =A0Nowhere does the LRM say that > it's illegal to write to a loop counter. > > >I want Xilinx to fix XST to support it as I believe it should. > > I want lots of other things much, much more than I want that. > > -- > Jonathan Bromley, Consultant > > DOULOS - Developing Design Know-how > VHDL * Verilog * SystemC * e * Perl * Tcl/Tk * Project Services > > Doulos Ltd., 22 Market Place, Ringwood, BH24 1AW, UK > jonathan.brom...@MYCOMPANY.comhttp://www.MYCOMPANY.com > > The contents of this message may contain personal views which > are not the views of Doulos Ltd., unless specifically stated.Hi Jonathan, First of all I'd like to thank you for a very well written response. Regarding whether the i =3D NUM_LOOPS is equal in synthesis to found =3D 1, I believe they are equal, and I don't understand the claim that they aren't. I think both would be unrolled NUM_LOOPS time, and once i =3D NUM_LOOPS is hit it should build the same logic as found =3D 1 and mask out the rest of the unrolled hardware. Declaring i as local is a good idea, and I appreciate your comments about simulation in this regard. I write my code with synthesis in mind, and therefore the simulation consideration was not accounted for. I will modify my coding habits accordingly. I never though of doing the same thing for generate loops, but I guess that should be valid in theory. I can't imagine the situation which would make such code necessary as there is nothing variable about generate loops as opposed to for loops whose execution can be variable. My complaint against Xilinx is that their tool doesn't support code which is LRM valid, and instead of stating that XST doesn't support this type of for loop, as they said regarding the disable keyword, they claim that it is illegal code. I would be happy to have an error from XST stating that my code is unsupported, but synthesizing my code wrong which is currently the case is unacceptable. Their bug cost me many hours of debugging what turned out to be completely correct code. After modifying my code to use a while loop everything started working correctly. Thanks for your comments, they have been very helpful. I have come away from this thread learning some new things. All the best, Nachum Kanovsky http://www.linkedin.com/in/nachumkanovsky http://ionipti.blogspot.com/
On Fri, 12 Jun 2009 09:10:50 -0700 (PDT), nachumk wrote:>Regarding whether the i = NUM_LOOPS is equal in synthesis to found = >1, I believe they are equal, and I don't understand the claim that >they aren't. I think both would be unrolled NUM_LOOPS time, and once i >= NUM_LOOPS is hit it should build the same logic as found = 1 and >mask out the rest of the unrolled hardware.I absolutely agree that the functionality should be the same, but I'm really not happy about synthesis of any code that modifies a for-loop counter within the body of a loop. The obvious, conservative way to think about synthesis of for-loops is that they should have constant bounds and then should be unrolled. Writing to the loop counter makes it very hard to work out what the unrolling should look like. By the way, VHDL doesn't allow you to do that - the loop counter is treated as a constant within the loop body. However, I do concede that updating the loop counter with an out-of-limit value, if that is the only such update in the loop body, is probably tractable for synthesis. I am not aware of any tools that support it, but I haven't done any kind of survey on that, so there may be some examples out there.>Declaring i as local is a good idea, and I appreciate your comments >about simulation in this regard. I write my code with synthesis in >mind, and therefore the simulation consideration was not accountedI think it's always worth remembering that both Verilog and VHDL are defined and specified as simulation languages. Synthesis can only ever support some subset of the language. I'm very aware that many people learn these languages purely from a synthesis point of view, and I fear that it leads to some unfortunate coding habits and, sometimes, misconceptions about how the language works.>I never though of doing the same thing for generate loops, but I guess >that should be valid in theory.No!!!! it's not!!!!! The point I was trying to make was this: The genvar loop counter in a generate loop REALLY IS A CONSTANT in the loop body. You absolutely cannot write to it. Consequently, a generate loop CAN easily be unrolled for synthesis. Procedural for-loops are, of course, completely general in Verilog simulation but there is no reason to suppose that all of that generality is synthesisable.>My complaint against Xilinx is that their tool doesn't support code >which is LRM valid,That in itself would be a very unfair complaint; synthesis can never support the whole of the language - as you of course are aware.> and instead of stating that XST doesn't support >this type of for loop, as they said regarding the disable keyword, >they claim that it is illegal code.Yes, that's not so good.> I would be happy to have an error >from XST stating that my code is unsupported, but synthesizing my code >wrong which is currently the case is unacceptable.Also agreed. Synthesis has a duty EITHER to create logic that works like the simulation, OR to error out. We all know that there are many cases where synth tools give warnings rather than errors if they create mismatching logic, and some of us are less than ecstatically happy about that, but there is unfortunately rather a lot of historical precedent at work :-(> Their bug cost me > many hours of debugging what turned out to be completely correct code.Sure. It happens. On the other hand, all synthesis tools - XST included - do a lot of difficult stuff right; so at some point we must go with the majority verdict, adopt a conservative coding style and move on. It's still possible to get the job done.> After modifying my code to use a while loop > everything started working correctly.As I mentioned, it would probably be a smart move to go back to using for loops with bypass logic; many synth tools don't support while loops. It's a real shame if they don't support "disable", though. That's often the cleanest way to do it. -- Jonathan Bromley, Consultant DOULOS - Developing Design Know-how VHDL * Verilog * SystemC * e * Perl * Tcl/Tk * Project Services Doulos Ltd., 22 Market Place, Ringwood, BH24 1AW, UK jonathan.bromley@MYCOMPANY.com http://www.MYCOMPANY.com The contents of this message may contain personal views which are not the views of Doulos Ltd., unless specifically stated.
nachumk <nachumk@gmail.com> wrote: (snip)> The only thing that interests me regarding this specific code is > whether it is legal according to the Verilog LRM. Xilinx claims that > my above code is illegal, and the old XST synthesizes it wrong, > whereas the new XST doesn't support it outright. I wrote the code up > above on the fly to demonstrate, so I didn't bother declaring some > things or resetting "go".(snip)> I would love to know if the Verilog LRM fully supports my code? I want > Xilinx to fix XST to support it as I believe it should.Much legal verilog is not synthesizable. This is one that I wouldn't expect. -- glen
On Jun 12, 1:16=A0pm, Jonathan Bromley <jonathan.brom...@MYCOMPANY.com> wrote:> By the way, VHDL doesn't allow you to do that - the loop > counter is treated as a constant within the loop body.Just to reiterate this point, VHDL does that for exactly the reason that modifying the loop variable directly in a for-loop is a bad idea. If you need to modify a loop variable, use a while-loop, not a for- loop. Just beware that many synthesis tools do not allow while-loops because of non-static bounds issues. Furthermore, VHDL automatically declares a new object for the loop index, visible only within that loop. If an already visible object exists with the same name, the loop index "hides" the existing object. This may seem overly restrictive, but it only helps promote good coding practices, particularly when synthesis is involved. Think of it this way; if you could allow synthesis with a modified for- loop variable, what types of modifications would be allowed? Is backing up the index acceptable? How about bumping the index forward? Given the static unrolling of for-loops in synthesis, all of these coding tricks would make synthesis virtually impossible. It is much simpler to just draw the line at not allowing modification of the for- loop index in the first place, which is exactly what VHDL does at the LRM level. How many times has my mother told me; "Just because you can do something, doesn't mean you should." Wow, I never thought I'd quote my mom in an FPGA/HDL forum! Andy
On Jun 12, 9:48=A0pm, glen herrmannsfeldt <g...@ugcs.caltech.edu> wrote:> nachumk <nach...@gmail.com> wrote: > > (snip) > > > The only thing that interests me regarding this specific code is > > whether it is legal according to the Verilog LRM. Xilinx claims that > > my above code is illegal, and the old XST synthesizes it wrong, > > whereas the new XST doesn't support it outright. I wrote the code up > > above on the fly to demonstrate, so I didn't bother declaring some > > things or resetting "go". > > (snip) > > > I would love to know if the Verilog LRM fully supports my code? I want > > Xilinx to fix XST to support it as I believe it should. > > Much legal verilog is not synthesizable. =A0This is one that I > wouldn't expect. =A0 > > -- glenI have now had a chance to check the recommended workaround of using a found variable instead of i =3D NUM_LOOPS. The found variable version is correctly synthesized with XST. Thank you for all the feedback, Nachum Kanovsky http://www.linkedin.com/in/nachumkanovsky http://ionipti.blogspot.com/





