View Full Version : What would you want more of, cogs or RAM? Why not interrupt support ?

02-11-2007, 09:35 PM

A good interrupt support can balance the advantage between cogs and ram.

So some light tasks can be done with a simple interupt and more strong memory and time needing task can use cog.


in medio virtus

Post Edited (inservi) : 2/11/2007 2:39:33 PM GMT

Mike Green
02-11-2007, 10:33 PM
One of the main reasons for going to a multiprocessor architecture was to eliminate the need for interrupts in the interest of simplicity and reliability in coding. Parallax has many years of experience with interrupts internally in the Stamps, first with the PIC processors, then with the SX processors and, now that they sell and support the SX series, they have plenty of experience supporting interrupt-based programming for the public at large.

Any time you introduce interrupts, you complicate code markedly. You introduce indeterminacy, strange bugs that are timing or context dependent, and, as a result, much greater likelihood of unreliability of the finished product. I wrote several operating systems during the period when this issue was being debated in the Computer Science community, both practically and theoretically. One operating system was written completely without interrupts outside of a tiny assembly language kernel that provided the process primitives (like COGNEW, LOCKxxx, etc.) It was striking how easy all the I/O routines came together ... This was in a small business system using a Z80, keyboard, display, disk, printer, network I/O, etc. The OS had to do the keyboard scanning, reloading the display line buffer on each retrace ... I mean this OS was busy doing I/O most (well maybe 30-60% normally) of the time.

Having written other operating systems with less severe I/O loading, but using interrupts, I can attest to how long it took to "stamp out" interrrupt related bugs.

02-11-2007, 11:10 PM
Thanks Mike,

Of any obviousness you do not like use interruptions. In spite of that, other programmers use them successfully from long time.
That offers a solution acceptable and not expensive in much of situations. And that makes it possible to save of Cogs.

in medio virtus

Mike Green
02-11-2007, 11:42 PM
The question really is: How important are interrupts vs. the added cost of having them in the 2nd generation Propeller. This chip is to be more pipelined than the 1st generation and that markedly complicates interrupt hardware since the pipeline has to be cleared, some special functions have to be performed (like a forced subroutine call) and execution resumed. There have been years of academic discussion and papers (in the 1970s) on the issue of interrupts vs cooperative processes, almost to the point of religious wars. Chip made a reasoned decision to eliminate them in favor of multiprocessing. There are plenty of ways to "save cogs" using the facilities already in the Propeller. I don't think you can make a case that interrupts are necessary. I think you could construct a specific example where they might make it possible to perform a task at the limits of the Propeller's capabilities, but the question then is: Is it necessary to complicate the chip design and add a fundamentally different feature that's needed in a very small number of cases that could be easily solved by adding a second Propeller or other processor.

02-12-2007, 12:35 AM

This is the reason why other development environements, as traditional Microchip with a good C compiler, will remain necessary for many applications and probably a long time.


PS :

You say "a very small number of cases that could be easily solved by adding a second Propeller or other processor."
I speak about small piece of code to avoid the heaviness of a processor.

in medio virtus

Post Edited (inservi) : 2/11/2007 5:43:29 PM GMT

John R.
02-12-2007, 01:43 AM
So is what you're saying, is that in order to have a successful chip, you have to follow the norm, and not only provide architectural features that undermine the entire concept of the new chip, but also tailor (and possibly cripple) the architecture so that existing tools (C compliers) can be used?

I think if you read Chip’s “Why the Propeller Works”, you may understand why that there was a conscious decision to avoid the above, and focus on a NEW concept that is INTENDED to be different.

You seem to insist on looking at this in terms of other chips you’ve worked with. In order to embrace the Propeller, you need to look at the Propeller as a Propeller, not as “another chip to evaluate”.

Will there be cases where another chip may work better? Certainly. Will there be some users who “just don’t get it?” Probably. I’m not suggesting you, or anybody else is in that camp, just recognizing it as a reality.

Just because something (interrupts and/or a C complier) are “industry standards” does not mean that they are the “best” way to do things. The fact that C is so common is a testament to it’s versatility, and ability of others to adapt it to many platforms. The fact that it is “adapted” implies compromises.

Mike is basically trying to say the same thing about interrupts. They are "the norm" but there are other, possibly better, ways of doing the same thing. Multiprocessing, and a dedicated cog, is possibly one of those ways. You may not agree with it, but that is one of the core concepts of the propeller. To change it would negate one of the foundations of the chip.

John R.
Click here to see my Nomad Build Log (http://share.crustcrawler.com/JohnR/)

02-12-2007, 01:58 AM
Hi Mike;

I'm afraid I'm going to agree with inservi.

In my opinion you are dead wrong to say that interrupts cause more complexity and indeterminism. It could not be further from the truth. In fact, I believe it to be the exact opposite.... it is the only proper way to enable determinism. And what's more, in real-time situations there are many things you simply can not effectively do without them.

I would go so far as to say that without interrupts you are creating code that is inferior to code with interrupts! And maybe that's OK when that's all you need. Personally, I strive for higher goals.

Sure, anyone can write code that is poorly constructed, including code with interrupts. But to squeeze the most out of a micro, an interrupt is absolutely necessary.

That said, I love the Propeller with all of it's novel and great features. But I do so wish it had a simple interrupt per cog. Now THAT would REALLY make these puppies sing!

What we don't know, of course, is wheter or not it's practical to do with the current architecture, and interrupts was not one of the choices Chip offered.


Peter (pjv)

Phil Pilgrim (PhiPi)
02-12-2007, 02:31 AM
I'm rather dumbfounded that one would complain about a lack of interrupts when, clearly, the Propeller already has them! In other processors, what is an interrupt system, really? It's a separate mechanism that just sits there and waits for something (timeout, external edge, internal peripheral event) to happen, then branches to the appropriate code when it does. Unfortunately for determinism, other micros also suspend the foreground process to do so, since only one process can be running at a time.

In the Propeller the interrupt system is completely independent from other running processes. In fact, it's so flexible, that you can design it to operate any way you want. The assembly WAIT commands make it easy. Want to interrupt when A0 goes low? Just set up a cog (your new interrupt controller) and WAITPEQ for it to happen! Need a timer interrupt? A WAITCNT in its own cog will take care of that for you. And best of all, your interrupt service routine doesn't have to "interrupt" anything — unless you want it to! It would be hard to imagine a more flexible, easy-to-program scheme for dealing with real-time events.

Interrupts? Yep, the Propeller's got 'em! Just don't call 'em that in polite company!


02-12-2007, 02:39 AM
an interrupt is absolutely necessary...

Sure, for any traditional linear processor. This is not a linear processor, it is a multi-processor. This puts the prop outside the catagory of "any micro".

Echo what Phil Said.

02-12-2007, 02:41 AM
Very well said, Phil.

Harley Shanko
h.a.s. designn

02-12-2007, 02:42 AM
I have to agree with Phil, if given the choice of 4 cogs each with an interrupt, or 8 cogs without interrupts. I'd choose 8 cogs.
If you wanted you COULD use a propeller as 4 cogs each with an interrupt using WAITCNT and WAITPEQ.
I'm not saying that interrupts are BAD, I don't think anyone is saying that. But I just don't see the point on a multiprocessor chip.


Cheap used 4-digit LED display with driver IC·www.hc4led.com (http://www.hc4led.com)

Low power SD Data Logger www.sddatalogger.com (http://www.sddatalogger.com)
SX-Video Display Modules www.sxvm.com (http://www.sxvm.com)
Stuff I'm selling on ebay http://search.ebay.com/_W0QQsassZhittconsultingQQhtZ-1

"USA Today has come out with a new survey - apparently, three out of every four people make up 75% of the population." - David Letterman

Post Edited (Bean (Hitt Consulting)) : 2/11/2007 8:41:52 PM GMT

Dennis Ferron
02-12-2007, 03:03 AM
You could dedicate one cog to doing nothing but servicing WAITPEQ, and then you would have something that works identically to the interrupt feature of other processors. The Propeller does not lack the capacity to have interrupts, what it gives you is the choice of how to implement them. And it is fallacious to argue that a single-core processor with interrupt hardware is going to be more responsive than the 8 core Propeller: ALL single core processors must wait for the current instruction to complete before it is possible to service the interrupt, whereas a dedicated WAITPEQ cog on the processor wouldn't be doing anything else and would respond instantly.

Hardware interrupts introduce code reliability problems because any time you have "normal" code interacting with interrupt code, there is the chance that the interrupt could occur while you are only half-way finished updating some data structure in your non-interrupt code. Why do you think ordinary processors have instructions that temporarily disable interrupts? It is because an interrupt occurring can cause problems during some operations.

Mike Green
02-12-2007, 04:25 AM
I would actually disagree that the Propeller already has interrupts. What it does have is the capability to respond to an external event or an internal clock event within a clock cycle (although it may take several instruction times to complete the response at a minimum). This is not an interrupt (although it's what interrupts are usually used for and provided for). An interrupt is a basic processor function to interrupt (hence the name) the normal flow of control of a processor in response to an external or internal event, then resume it at a later time. Some processors (like the SX) may include basic state saving and restoring as part of the "hardware" process or may require that the routine that gets control does the state save and restore using ordinary instructions. That's it.

To support this function may require additional registers to prevent further interrupts from occurring until the program is done processing this one or the processor may have a stack that can be used to provide for state saving for nested interrupts or other ways of saving the processor state with multiple nesting of interrupts. If you haven't noticed, Propeller assembly language is not normally reentrant with widespread use of instruction modification to provide for subroutine calls and array access. What I'm getting at is that it's not just a simple matter of adding an interrupt capability. That could be done, but, to support it properly, there would have to be widespread changes to the current instruction set which was not designed with interrupts in mind ... deliberately. This wasn't done to make interrupts difficult. It was a "What if we didn't have interrupts, but wanted to emphasize rapid response to events, strict determinism at least internal to a processor, speed, relative ease of use, etc. What would such an instruction set look like?"

02-12-2007, 04:30 AM
Yeah, and what happens when an IMPORTANT interrupt occurs while interrupts are disabled?

Or what if another interrupt happens while the processor is busy servicing the first?

I've done asembly work on several 8bit CPUs(6502, Z80, 6301, 8085) and the worst parts is always the interrupts.
And those were simple processors with no lookahead cache to screw you over.

Ever seen what happens when an interrupt routine 'misfires' and the stack overwrites the software?
Or it just happens to have a inbalance of PUSH/POPs?
(Very fun in serial I/O routines)
Debugging this stuff is 'not fun'...
(And as I only program for fun, not profit... guess what, I don't miss interrupts... )

I consider manually disassembling ROMs from old computers to be 'fun' and 'relaxing'...
(If I consider that easier than debugging Interrupts... )

Don't visit my new website...

Graham Stabler
02-12-2007, 04:40 AM
Interupts are like workers with no initiative:

"you go and do that"
"now what"
"Oh, you want me to sort it out for you"

programming the propeller is more like:

"you go and do that"
"sure thing boss, I'll see you back at the ranch for tea and biscuits"


Phil Pilgrim (PhiPi)
02-12-2007, 04:46 AM

I used the term "interrupt" tongue-in-cheek just to make the point that the Propeller provides the same funcitonality that an interrupt-driven system would, but with considerably more flexibility. The additional hardware you describe as necessary for interrrupts is only required in single-process systems, where state-saving and reentrancy are a requisite part of the mechanism. By moving hardware "interrupts" to the software, as the Propeller does, the requirement for all this extra rigamarole goes away. My point was that that the Propeller achieves the behaviorial equivalent of an interrupt-driven system without needing the same underlying structure.

I think we're saying the same thing, really, but just in different ways.


Mike Green
02-12-2007, 04:49 AM
I would suggest you look at some of the papers published around the same time as the "why we don't need a GOTO" discussions. There were a number of operating systems (Wirth's Modula system comes to mind) implemented at that time as demonstrations that neither was necessary. I used that as the basis for the Z80 commercial operating system I mentioned and another operating system for the IBM 360, done primarily as a demonstration. Both quickly converted the hardware interrupts (because that's what was provided) rapidly into process switching primitive actions in a small assembly language kernel. Everything else was based on the process-based system primitives. The only exception was on the Z80 system where a hardware register had to be loaded within maybe 100us of a video horizontal retrace signal (much like the WAITVID instruction in the Propeller). This function was built into the kernel. With a Propeller, a cog would have been dedicated to this.

There have been a variety of real-time operating systems built on this model over time. Generally, cooperative execution threads are the only way to ensure predictability of response time because interrupts are inherently not predictable. To get around this, you often have to have multiple priority levels and complex scheduling mechanisms because you have only a single threaded processor and all of the task switching takes a substantial portion of the processor throughput, particularly when there are many short tasks involved.

02-12-2007, 06:52 AM
Hi All;

Well, I seem to have created quite a stir. I hope I did not offend anyone with what appears to be my somewhat arbitrary, if not abbrasive manner in responding. That certainly was not my intent.

Where my hackles got up Mike, was the statement that "interrupts cause indeterminism" (paraphrasing) and that is what I take real issue with. Poor programming causes indeterminism, not interrupts.

Please let me explain some more; and this is SX specific.... my processor of choice.

In the world where I live, real time industrial control with lots of interactive high speed comms, the interrupt is invaluable. I could not possibly think of a way to tackle all that needs to be done without having one. That said, I generally restrict the interrupt to internal timing, using the RTCC rollover as the basic clock tick to drive a real time pre-emptive (or for simpler applications a non-pre-emptive) RTOS to keep everything synchronized and happily co-operating. On a few 'bursty' occasions when there was just too much to do, I have resorted to external events to generate interrupts. The fact that those are usually asynchronous does certainly add some additional challenges to the RTOS. So it is the very fact that I have an (time based) interrupt that permits me to be able to run mutiple threads in a very deterministic fashion, and hence my reaction to the "interrupts are stupid" (paraphrasing) statement. They are the very soul of my programming model.

Now to the Propeller. I love the device. Sure, I well understand the similarity of WAITPE to an external interrupt, and WAITCNT to look like an RTCC rollover. And that all well and good. But what the major difference is, is that the Cog is stalled while these instructions are waiting for the event, and hence during that period are not contributing to the workload. Under an interrupt scenario those wasted cycles can usually be put to good use.

What I see as the reason for folks are requesting more Cogs is because they can't get enough done with the number they now have. And that's exactly my point; interrupts would add considerably to the Propeller's ability to get more done, especially under the present slow and awkward Cog to Cog signalling situation (other than using I/O pins for that). I estimate that for my applications I would gladly trade a reduction of half the number of Cogs for even a simple interrupt (per cog), as I truly think that would be able to outperform my needs when using the present Propeller.

So I agree that the Propeller is great;........ I just wish also it had an (internal time based) interrupt.

Alas, that was not one of the choices Chip was offering.


Peter (pjv)

02-12-2007, 06:56 AM
In my experience having one interrupt is usually quite fine.. but when you'll be having 5 or 10 of them it becomes way too messy.. With different priorities, execution times, locking etc.. IT'll eat all to system CPU time just to run interrupt enter/exit code..

IMHO it's better to keep Propeller different. It may not be what all want, but in many cases it's architechture beats interrupt-driven systems hands down. Propeller needs a bit different approach, but IMHO it's versatility counters the possible problems.

02-12-2007, 04:08 PM
Hello All,

I am completely allured by the principle of the paralele tasking. Every days, I venerate qualities of the propeller.
I also understood well ( a long time before subjecting this thread ) that the management of a interrupt can very advantageously be replaced by the use of a cog. ( I am not as stupid as some seems to believe it )
But sometimes, I wonder whether it is reasonable to start a cog with these thousands of transistors and the power loosed for a very simple task.
It is like a big gun to kill a fly.

A particular thanks to Graham Stabler to consider that the people who defends the interupts do not have initiative. This remark is very useful.

So, i note that the principle of the interrupt is not popular in this forum and for me this question is closed here.


in medio virtus

Post Edited (inservi) : 2/12/2007 10:14:13 AM GMT

Graham Stabler
02-12-2007, 09:48 PM
It can seem a waste to use a processor to do a simple thing but it is only a waste if the processor could be doing something else. Sometimes it is possible to set a processor doing several simple things, this makes it less of a waste.


p.s. I said that the INTERUPTS do not have initiative, NOT the people who defend them!! The ISR does the work, the interupts just asks for help. I hope you understand now.

02-12-2007, 10:28 PM
Hi inservi,

Sure has started an interesting debate :)

I'll admit that, coming from a PIC background, the lack of interrupts does seem a bit alien. However, given that we have 8 Cogs to play with; that their function is entirely under our control; and we could dedicate one of them to servicing pseudo interrupts, I'm real happy!

I note that you've said that you'd 'gladly trade [down to] half the number of Cogs'; that'd leave you with 4 Cogs with interrupts. Agreed, that may be ideal for what you need, but surely then you wouldn't mind dedicating one or two Cogs to servicing pseudo interrupts?

BTW: I type as I'm thinking, so please don't take any offense at my writing style. There's always gonna be two sides of every fence http://forums.parallax.com/images/smilies/smile.gif


www.norfolkhelicopterclub.co.uk (http://www.norfolkhelicopterclub.co.uk)
You'll always have as many take-offs as landings, the trick is to be sure you can take-off again ;-)

Mike Green
02-12-2007, 10:41 PM
It's interesting to see how "the current technology" drives the issues around programming, around what's efficient and what's a waste. When random logic was relatively cheap, but on-chip storage (registers) was terribly expensive, you saw chips like the 6502 or the RCA 1802 with minimal registers and everything else off-chip in memory. Now the costs of interconnection are expensive and you have increasing amounts of processor power and on-chip memory, even multiple processors and memories on the same chip. Back when the only cheap memory was serial shift register or earlier with magnetic drum, efficiency meant loading small loops into addressable processor registers and executing them there while (like dealing with the Propeller's Hub) you had to optimize overlap of instruction execution with rotation of the drum so successive loops would not have to wait too long for the next location to arrive under the read/write head. Similarly, when processors were expensive, interrupts were very important since you could afford only one processor for multiple tasks. It was a huge change in computer architecture for the Control Data 6600 (which I think was first) to have a pool of general purpose peripheral processors.

02-12-2007, 11:18 PM
pjv said...

...I generally restrict the interrupt to internal timing, using the RTCC rollover as the basic clock tick to drive a real time pre-emptive (or for simpler applications a non-pre-emptive) RTOS to keep everything synchronized and happily co-operating.

I agree that a time-based interrupt is potentially very useful, and on the SX, the high MIPS and RTCC interrupt·really make the chip. I think that mixing pin interrupts with timer interrupts is almost always a bad thing, though.

Here's the trouble I see with adding even a time-based·interrupt to the cogs: Because the hub instructions (RDLONG, WRWORD, etc) must wait their turn, determinancy is already gone. Interrupts would have to wait for any hub instruction to finish, messing up the whole concept. You might as well put periodic JMPRET instructions at break-tolerant points in your code, and execute other routines that way. Of course, if there was a timer interrupt, you could put all your hub instructions into the interrupt routine to regain determinancy, but then how useful is your main progam going to be when it can't talk to main memory? For timing criticality, the WAITCNT instruction can land you·right on your clock pulse of choice, no problem. You just have to be there at least a·few clocks ahead of time.

In my Propeller programming experience, so far, I've found very efficient ways to accomplish·everything I've needed to do,·albeit·in very different ways than on 'normal' architectures. Usually, it's a matter of only one or two instructions to get some wacky branch scheme going, or to get mutiple cogs working together. I get surprised over and over at how·simply things can be done. It's just way outside of convention or, at least, my past experience.


Chip Gracey
Parallax, Inc.

Post Edited (Chip Gracey (Parallax)) : 2/12/2007 4:24:24 PM GMT

02-12-2007, 11:47 PM
Hello Simon,

I'm sorry but I did not speak about '4 cogs each with an interrupt '. Ask to Bean (Hitt Consulting) what he wants to say by.

Best regards,

in medio virtus

Post Edited (inservi) : 2/12/2007 4:52:07 PM GMT

02-13-2007, 12:27 AM
Soz inservi, it was pjv who said that. My mistake.



BTW: I type as I'm thinking, so please don't take any offense at my writing style http://forums.parallax.com/images/smilies/smile.gif

www.norfolkhelicopterclub.co.uk (http://www.norfolkhelicopterclub.co.uk)
You'll always have as many take-offs as landings, the trick is to be sure you can take-off again ;-)

02-13-2007, 12:42 AM
Hello Chip;

Normally I do not use pin interrupts, just the timer to generate an RTOS tick.

Regarding the Propeller, I'm not qualified to suggest what can be implemented and what cannot. I do see what you mean by the Hub issue, and how that might screw things up.

If an interrupt were available, it would not neccessarily need to be used by any or all Cogs, so those who can do without it can have their way. And those who have the need will be cognizant of the implications of using it. Possibly they could isolate the interrupt code to Cogs that have little interaction with others.

In any case I still hang on to my desire of an interrupt, but the lack of one will not stop me from using the Propeller..... I think it's a great chip.

While on the subject of wishes, if we can't have an interrupt, then it would be very nice if there were some way to have intantaneous and convenient signalling among Cogs by not using the Hub. A tiny piece of multiple access RAM would be wonderful, or alternately a bunch more semaphores/flags would be workable. This way we can better effect similar interrupt-like functionality with full determinism.

So please don't take my comments negatively.... I'm just expressing my wishes. And you are the only one who can decide what wishes will be granted.


Peter (pjv)

Post Edited (pjv) : 2/12/2007 5:47:26 PM GMT

Paul Baker
02-13-2007, 02:14 AM
inservi said...
But sometimes, I wonder whether it is reasonable to start a cog with these thousands of transistors and the power loosed for a very simple task.

The power required to make a cog perform the same function as an interrupt (time or pin based) consumes·very little current. When a cog is in a WAITxx·instruction, the cog's clock is only·gated to·a few flipflops until the condition is met. We are taking measurements now to quantify these currents.

Post Edited By Moderator (Chip Gracey (Parallax)) : 2/12/2007 9:52:09 PM GMT

02-14-2007, 07:25 PM
pjv said...
Hello Chip;

Normally I do not use pin interrupts, just the timer to generate an RTOS tick.

Regarding the Propeller, I'm not qualified to suggest what can be implemented and what cannot. I do see what you mean by the Hub issue, and how that might screw things up.

If an interrupt were available, it would not neccessarily need to be used by any or all Cogs, so those who can do without it can have their way. And those who have the need will be cognizant of the implications of using it. Possibly they could isolate the interrupt code to Cogs that have little interaction with others.

Well said, I agree with you pjv. Who dont need/like interrupts can always seek their route to avoid them, and who need interrupts just use them under their responsability.
I would like pin interrupts aswell, why not.

chip gracey said...
Because the hub instructions (RDLONG, WRWORD, etc) must wait their turn...
Could an interrupt·"interrupt" even·a cog "waiting its turn" time?·For that cog, it is dead time anyway. If so then interrupts could be so deterministic as any other right?. If not, an already in course hub instruction would add some cycles but then I would like interrups anyway, even whitout·perfect determinism...many processors works that way, we don't need to be like sx. If perfect determinism is need, then use an exclusive cog and waitx functions, but then as last resource, not as the only one.
Interrups are a very successful mechanism by some reason...I don't think any of the showed arguments being enough as to supress them, even with 8/16 cogs. Imho, there are not·valid reasons to not have the best of both worlds.

Also, I have read below things like this: "interrupts introduce code reliability problems".
Sorry no. Bad code design introduce "code reliability problems", not interrupts.

Respectfully, GdS


02-14-2007, 09:43 PM
This interupt thread made me think, not of wasting a COG on WAITPNE instruction(if on the prop2 we have 16 of them), but the precious HUB bandwidth wasted(there IS only 1 of them after all), which makes me think of abandoning the configurable number of COGS sceme for SK's Unbalanced HUB scheme.
It seems to me that since Interupt driven code is historically relatively small, it may be able to completely in COG ram, so wouldn't need a lot of hub bandwidth in many cases.
I would recommend, however a slight modification from SK's unballanced mode below. Just drop a cogF (Hexadicimal is better suited to naming 16 cogs) so that each low bandwidth cog would get 2_500_000 timeslots/sec COG 7-E

SK said...

I suggest a different hub bandwith management:

Standard Mode:
10_000_000 timeslots/sec for every COG.
COGs get HUB access in this order:
0 1 2 3 4 5 6 7
8 9 10 11 12 13 14 15
After 16 steps it starts from the beginning.

Unbalanced Hi-/Lo-Bandwith Mode:
20_000_000 timeslots/sec for COG 0-6.
2_222_222 timeslots/sec for COG 7-15.
COGs get HUB access in this order:
0 1 2 3 4 5 6 7
0 1 2 3 4 5 6 8
0 1 2 3 4 5 6 9
0 1 2 3 4 5 6 10
0 1 2 3 4 5 6 11
0 1 2 3 4 5 6 12
0 1 2 3 4 5 6 13
0 1 2 3 4 5 6 14
0 1 2 3 4 5 6 15
After 72 steps it starts from the beginning.

The unbalanced mode will better support complex designs.