Gerhard Fiedler wrote: > Peter wrote: > > >>>I don't think they make sense for two or three inputs. Not sure where the >>>threshold is. I guess the threshold depends also on the number of counts. >> >>No, it does not. Vertical counters can be expanded to more than 8 bits >>easily. > > > I'm not sure we understand each other here... What I meant was that the > number of inputs from which on it makes sense to use vertical counters > depends on the number of counts you want to count for each input. > > Let's say we have 8 inputs. That's maximum efficiency of the vertical > counters, and also maximum effort for the horizontal counters, so it's the > situation where typically vertical counters make most sense. And they do if > you count to 3, or to 7. But what if you count to 255? I think (not sure > though) that in this case, horizontal counters are better code-wise and the > same memory-wise. > > Which means that the threshold (number of inputs) from which on it makes > sense to use vertical counters depends on the number of counts -- or am I > missing something? Gerhard, You're not missing anything. Each additional vertical bit takes 4 more instructions: ; carryOut = carry from previous stage movf carryOut,W ; get the carry from the previous stage xorwf stageN,F ; add it to this bit stage xorwf stageN,W ; get the original bit back andwf carryOut,F ; If there was a carry-in and this bit was ; set, then we have a carry for the next stage. There are optimizations for the first few bits, but the number of instructions to increment a vertical are: instructions = (# of bits - 3)*4 + 6 So, an 8-bit vertical counter takes 26 instructions. If you're using the vertical counters to count events, then the number of instructions increase to: instructions = (# of bits) * 4 - 1 Or 31 cycles for 8 counters. Neither of these are too efficient compared to the 8 or 16 instructions for the equivalent 8 horizontal counters. However, imagine a design requiring 4 instructions per horizontal counter. It's possible that the vertical counter comes out ahead. For example, you might want to count the high-time on an I/O port during a fixed period of time and stop counting if the counter has reached the maximum (e.g. measure the duty cycle on 8 inputs). A horizontal implementation would be: movf PORT,W movwf temp clrz btfsc temp,0 ;Is bit 0 set? incf count0,F ;yep, count it skpnz ;did the counter overflow? decf count0,F ;yep, remove that count. This counter is ;through ; repeat for bits 1 through 7 The vertical solution would be something like: ; countEnable is initialized with 0xff at the very start. ; Read the current I/O port setting: movf PORT,W ; if the counter is enabled and the I/O bit is high, ; then count it andwf countEnable,W movwf carryOut xorwf bit0,F xorwf bit0,W andwf carryOut,F movf carryOut,W xorwf bit1,F xorwf bit1,W andwf carryOut,F movf carryOut,W xorwf bit2,F xorwf bit2,W andwf carryOut,F ; repeat for bits 3 through 6 movf carryOut,W xorwf bit7,F xorwf bit7,W andwf carryOut,W ; All bits set in W correspond to counters that have rolled ; over. Turn off all of those counters xorwf countEnable,F Both solutions take 35 instructions! But now imagine you add the twist that you want to measure how long it takes for all 8 counters to reach 256. For this contrived example, the vertical counter implementation takes only two more instructions: akpnz goto allCountersHaveTerminated Scott -- http://www.piclist.com PIC/SX FAQ & list archive View/change your membership options at http://mailman.mit.edu/mailman/listinfo/piclist