Long shift register


Closed Thread
Results 1 to 21 of 21

Hybrid View

  1. #1
    Join Date
    Aug 2006
    Posts
    65


    Did you find this post helpful? Yes | No

    Default

    Chris,

    For now, I only need to compare the first and last bits each time I update the SR. In the future, I might wat to look at intermediate bits. I can pick a PIC (say that a dozen times!!) with as much memory as I need, even an 18F part if that's what it takes, so no prob there. I think the primary limitation on how much other processing I can do will ultimately be determined by how much throughput is left (time). There are a few other tasks having to do with data acquisition (input)and disposal of the results (output), but they're minor as of now. Of course, the more horsepower that is left after the important job is done, the more 'feature creep' I can build in.

    FYI, the application is a 'stabilizer' for a voltage controlled oscillator, similar to a PLL. It works by sampling the instantaneous oscillator state with a precise time base, and comparing the present state with the state "n" samples ago. The result of the sampling and comparison process is used to pump the oscillator fine-tuning voltage up or down until the oscillator locks onto the nearest 'comb' point. The spacing of comb points is determined by the sampling rate and the number of samples stored in the SR. It has the advantages of fine tuning resolution combined with fast acquisition and tracking speed, parameters that are usually mutually exclusive in a PLL synthesizer.

    Thanks

    Jjoe

  2. #2


    Did you find this post helpful? Yes | No

    Default

    Quote Originally Posted by Joe Rocci View Post
    Chris,

    For now, I only need to compare the first and last bits each time I update the SR. In the future, I might wat to look at intermediate bits. I can pick a PIC (say that a dozen times!!) with as much memory as I need, even an 18F part if that's what it takes, so no prob there. I think the primary limitation on how much other processing I can do will ultimately be determined by how much throughput is left (time). There are a few other tasks having to do with data acquisition (input)and disposal of the results (output), but they're minor as of now. Of course, the more horsepower that is left after the important job is done, the more 'feature creep' I can build in.

    FYI, the application is a 'stabilizer' for a voltage controlled oscillator, similar to a PLL. It works by sampling the instantaneous oscillator state with a precise time base, and comparing the present state with the state "n" samples ago. The result of the sampling and comparison process is used to pump the oscillator fine-tuning voltage up or down until the oscillator locks onto the nearest 'comb' point. The spacing of comb points is determined by the sampling rate and the number of samples stored in the SR. It has the advantages of fine tuning resolution combined with fast acquisition and tracking speed, parameters that are usually mutually exclusive in a PLL synthesizer.

    Thanks

    Jjoe
    That sounds very very cool !

    Just a look at the processing time......(your minimum execution time assembly example)

    2000 bits = 250bytes = 250 RLF's = 250 clock cycles

    At 4MHz (crystal) , clock cycles = 1MHz, shift frequency = 4kHz (1MHz/250)

    (There's an obvious connection here between shift frequency and crystal frequency due to the nice numbers), therefore a 10kHz shift frequency requires a 10MHz crystal.
    20MHz crystal = 20kHz shift frequency

    Okay, now to prove myself wrong that you had already written the quickest routine !

    Moving one bit at a time is consuming 250 clock cycles (8 bits = 2000 clock cycles) , and because you only need the first and last bits why not move the in between registers 1 byte at a time, but still shift in the first bit and out the last bit by using a pair of end buffers

    Data moving from left to right....
    (Every iteration, 2 shifts)
    SHIFTS: ] --8.bit input buffer-- + --8.bit output buffer--

    After every 8 shifts, move bytes in between buffers
    MOVES: ] [SR1000>output_buffer][sr992>SR1000].....[input_buffer>SR8]


    iteration 1 : 2 shifts + 4 loop counter maintenance
    iteration 2: ditto
    .
    .
    .
    .
    .
    iteration 8: 252 MOVFF's + 2 shifts + 4 loop counter maintenance

    Estimated overhead for 8 bits = (7 * 6) + (252 +2 + 4) = 300 clock cycles


    Using the first method you have a fixed length execution time of 250 clocks per iteration, and using the second method you have one long execution cycle in every 8 (but it has a much lower processing overhead), and averages about 32 cycles per iteration , leaves more time for processing.

    Chris





    Now, for each iteration you have 6 clock cycles for shifts, and 250/8 MOVEs, which if yoiu use a PIC 18F and the MOVFF command (1 clock cycle) completes in about 50 clock cycles average (excluding loop counter overehad)

    iteration 1 : 2 shifts + 4 loop counter maintenance
    iteration 2: ditto
    .
    .
    .
    .
    .
    iteration 8:

  3. #3
    Join Date
    Jul 2003
    Location
    Colorado Springs
    Posts
    4,959


    Did you find this post helpful? Yes | No

    Default

    I think it would be easier to create a "Circular" buffer of bits, much like you would for a byte sized serial buffer.

    Nothing actually shifts, only the pointers to the data change.
    <br>
    DT

  4. #4
    Join Date
    Aug 2006
    Posts
    65


    Did you find this post helpful? Yes | No

    Default

    Darrel,

    Can you post an example of how you'd implement that in PBP?

    Thanks

    Joe

  5. #5
    Join Date
    Jul 2003
    Location
    Colorado Springs
    Posts
    4,959


    Did you find this post helpful? Yes | No

    Default

    Quote Originally Posted by Joe Rocci View Post
    Darrel,
    Can you post an example of how you'd implement that in PBP?
    Thanks
    Joe
    I can.

    First let me say that ASM is a very BIG part of PicBasic Pro.
    It's the Glue that binds everything together.

    Ignoring ASM, and pretending it's not part of PBP simply deprives you of the easiest ways to do exactly what you want, without having to find some basackwards way to get around your problems.

    OK, now that the commercials over ...<hr>
    20uS shift @ 40Mhz. With 18F's ONLY!
    Using a large Circular buffer.
    Variable length Shift up to 2032 bits.

    Basic Language ONLY ...
    Code:
    <font color="#0000FF"><b><i>'***************************************************************************
    '*  Name    : 1000Bits.pbp                                                 *
    '*  Author  : Darrel Taylor                                                *
    '*  Date    : 4/17/2009                                                    *
    '*  Version : 1.1                                                          *
    '*  Notes   : Requires an 18F                                              *
    '*          : 20uS ~shift at 40Mhz, 40uS @ 20Mhz                           *
    '***************************************************************************
    </i></b></font><font color="#000080">@ __CONFIG    _CONFIG1H, _OSCS_OFF_1H &amp; _HSPLL_OSC_1H
    </font><font color="#008000"><b>DEFINE </b></font><b>OSC </b><font color="#800000"><b>40
    
    </b></font><font color="#008000"><b>CLEAR
    
    </b></font><b>BufferBits  </b><font color="#008000"><b>CON </b></font><font color="#800000"><b>1000                  </b></font><font color="#0000FF"><b><i>; max 2032
    </i></b></font><b>BufferBytes </b><font color="#008000"><b>CON </b></font><b>BufferBits </b>/ <font color="#800000"><b>8 </b></font>+ <font color="#800000"><b>1    </b></font><font color="#0000FF"><b><i>; number of BYTEs required for buffer
    </i></b></font><b>Buffer      </b><font color="#008000"><b>VAR BYTE</b></font>[<b>BufferBytes</b>]     <font color="#0000FF"><b><i>; The Buffer Array
    </i></b></font><b>ShiftSize   </b><font color="#008000"><b>VAR WORD                  </b></font><font color="#0000FF"><b><i>; Variable sized Shift at run-time
    </i></b></font><b>INptr       </b><font color="#008000"><b>VAR WORD                  </b></font><font color="#0000FF"><b><i>; Points to the IN bit of the array
    </i></b></font><b>OUTptr      </b><font color="#008000"><b>VAR WORD                  </b></font><font color="#0000FF"><b><i>; Points to the OUT bit of the array
    </i></b></font><b>BuffPtr     </b><font color="#008000"><b>VAR BYTE                  </b></font><font color="#0000FF"><b><i>; Points to the BYTE in the buffer
    </i></b></font><b>BitPtr      </b><font color="#008000"><b>VAR BYTE                  </b></font><font color="#0000FF"><b><i>; Points to the BIT in the byte
    </i></b></font><b>TempB       </b><font color="#008000"><b>VAR BYTE                  </b></font><font color="#0000FF"><b><i>; temporary byte variable
    </i></b></font><b>BITin       </b><font color="#008000"><b>VAR </b></font><b>PORTB</b>.<font color="#800000"><b>0               </b></font><font color="#0000FF"><b><i>; The BIT being shifted IN
    </i></b></font><b>BITout      </b><font color="#008000"><b>VAR </b></font><b>PORTB</b>.<font color="#800000"><b>1               </b></font><font color="#0000FF"><b><i>; The BIT being shifted OUT 
    
    </i></b></font><b>ShiftSize </b>= <font color="#800000"><b>800                       </b></font><font color="#0000FF"><b><i>; Any Size - up to BufferBits
    </i></b></font><font color="#008000"><b>GOSUB </b></font><b>ResizeBuffer                    </b><font color="#0000FF"><b><i>; setup the Pointers
    </i></b></font><font color="#008000"><b>GOSUB </b></font><b>ClearBuffer                     </b><font color="#0000FF"><b><i>; Set buffer to all 0's
    </i></b></font><font color="#008000"><b>INPUT </b></font><b>BITin                           </b><font color="#0000FF"><b><i>; Input pin
    </i></b></font><font color="#008000"><b>LOW   </b></font><b>BITout                          </b><font color="#0000FF"><b><i>; Output pin
    
    ;---------------------------------------------------------------------------
    </i></b></font><b>Main</b>:
        <font color="#008000"><b>GOSUB </b></font><b>ShiftBits
        </b><font color="#008000"><b>PAUSEUS </b></font><font color="#800000"><b>80
    </b></font><font color="#008000"><b>GOTO </b></font><b>Main
    
    </b><font color="#0000FF"><b><i>;---------------------------------------------------------------------------
    </i></b></font><b>ShiftBits</b>:
        <b>INptr  </b>= <b>INptr </b>+ <font color="#800000"><b>1                             </b></font><font color="#0000FF"><b><i>; Increment IN pointer
        </i></b></font><font color="#008000"><b>IF </b></font><b>INptr</b>.<b>LowByte </b>= <b>ShiftSize</b>.<b>LowByte </b><font color="#008000"><b>Then      </b></font><font color="#0000FF"><b><i>;  IF past end of buffer?
          </i></b></font><font color="#008000"><b>IF </b></font><b>INptr</b>.<b>HighByte </b>= <b>ShiftSize</b>.<b>HighByte </b><font color="#008000"><b>Then
            </b></font><b>INptr </b>= <font color="#800000"><b>0                                  </b></font><font color="#0000FF"><b><i>;  Wrap to beginning
          </i></b></font><font color="#008000"><b>ENDIF
        ENDIF 
        </b></font><b>OUTptr </b>= <b>OUTptr </b>+ <font color="#800000"><b>1                            </b></font><font color="#0000FF"><b><i>; Increment OUT pointer
        </i></b></font><font color="#008000"><b>IF </b></font><b>OUTptr</b>.<b>LowByte </b>= <b>ShiftSize</b>.<b>LowByte </b><font color="#008000"><b>Then     </b></font><font color="#0000FF"><b><i>;  IF past end of buffer?
          </i></b></font><font color="#008000"><b>IF </b></font><b>OUTptr</b>.<b>HighByte </b>= <b>ShiftSize</b>.<b>HighByte </b><font color="#008000"><b>Then 
            </b></font><b>OUTptr </b>= <font color="#800000"><b>0                                 </b></font><font color="#0000FF"><b><i>;  Wrap to beginning
          </i></b></font><font color="#008000"><b>ENDIF
        ENDIF 
    
        </b></font><font color="#0000FF"><b><i>; --- Put new BIT into the Buffer ------------
        </i></b></font><b>BuffPtr </b>= <b>INptr </b>&gt;&gt; <font color="#800000"><b>3                          </b></font><font color="#0000FF"><b><i>; Which BYTE in the buffer
        </i></b></font><b>BitPtr </b>= <b>INptr </b>&amp; <font color="#800000"><b>%111                         </b></font><font color="#0000FF"><b><i>; Which BIT in the byte 
        </i></b></font><b>TempB </b>= <b>Buffer</b>(<b>BuffPtr</b>)                       <font color="#0000FF"><b><i>; retrieve the byte
        </i></b></font><b>TempB</b>.<font color="#800000"><b>0</b></font>(<b>BitPtr</b>) = <b>BITin                       </b><font color="#0000FF"><b><i>; store the bit
        </i></b></font><b>Buffer</b>(<b>BuffPtr</b>) = <b>TempB                       </b><font color="#0000FF"><b><i>; put byte back in buffer
        
        ; --- Get old BIT from the Buffer ------------
        </i></b></font><b>BuffPtr </b>= <b>OUTptr </b>&gt;&gt; <font color="#800000"><b>3                         </b></font><font color="#0000FF"><b><i>; Which BYTE in the buffer
        </i></b></font><b>BitPtr </b>= <b>OUTptr </b>&amp; <font color="#800000"><b>%111                        </b></font><font color="#0000FF"><b><i>; Which BIT in the byte
        </i></b></font><b>TempB </b>= <b>Buffer</b>(<b>BuffPtr</b>)                       <font color="#0000FF"><b><i>; retrieve the byte
        </i></b></font><b>BITout </b>= <b>TempB</b>.<font color="#800000"><b>0</b></font>(<b>BitPtr</b>)                      <font color="#0000FF"><b><i>; output the BIT
    </i></b></font><font color="#008000"><b>RETURN
    
    </b></font><font color="#0000FF"><b><i>;---------------------------------------------------------------------------
    </i></b></font><b>ResizeBuffer</b>:
        <b>ShiftSize </b>= <b>ShiftSize </b><font color="#008000"><b>MIN </b></font><b>BufferBits          </b><font color="#0000FF"><b><i>; limit to buffer size
        </i></b></font><b>INptr  </b>= <b>ShiftSize </b>- <font color="#800000"><b>1                        </b></font><font color="#0000FF"><b><i>; buffer starting point
        </i></b></font><b>OUTptr </b>= <font color="#800000"><b>0                                    </b></font><font color="#0000FF"><b><i>; out bit starts at 0
    </i></b></font><font color="#008000"><b>RETURN
    
    </b></font><font color="#0000FF"><b><i>;---------------------------------------------------------------------------
    </i></b></font><b>ClearBuffer</b>:
        <font color="#008000"><b>FOR </b></font><b>TempB </b>= <font color="#800000"><b>0 </b></font><font color="#008000"><b>to </b></font><b>BufferBytes - 1
            Buffer</b>(<b>TempB</b>) = <font color="#800000"><b>0
        </b></font><font color="#008000"><b>NEXT </b></font><b>TempB
    </b><font color="#008000"><b>RETURN
    </b></font>
    Last edited by Darrel Taylor; - 18th April 2009 at 07:17. Reason: Fixed a possible buffer overflow problem
    DT

  6. #6
    Join Date
    Aug 2006
    Posts
    65


    Did you find this post helpful? Yes | No

    Default

    Quote Originally Posted by Chris Barron View Post
    That sounds very very cool !

    Just a look at the processing time......(your minimum execution time assembly example)

    2000 bits = 250bytes = 250 RLF's = 250 clock cycles

    At 4MHz (crystal) , clock cycles = 1MHz, shift frequency = 4kHz (1MHz/250)


    Chris,

    I'm using a 20mhz crystal, so cycle time is 200nsec. My ~260 cycle assembler SR should thus take about 52 usec, if my math is correct. I was planning to use the crystal to run a Timer1 timer to generate prescise 100usec interrupts. If I sample at 100usec (10khz), that leaves about 48usec to do 'other things'. That would do it in the assembler version.

    The big question, is there a PBP alternative that would be fast enough, and in fact leave a little time for other things?? I suspect not, and that I'll end up with a hybrid solution, using assembler for the SR, and PBP for the 'other things'.

    Joe

    Joe

  7. #7


    Did you find this post helpful? Yes | No

    Default

    Quote Originally Posted by Joe Rocci View Post
    Chris,

    I'm using a 20mhz crystal, so cycle time is 200nsec. My ~260 cycle assembler SR should thus take about 52 usec, if my math is correct. I was planning to use the crystal to run a Timer1 timer to generate prescise 100usec interrupts. If I sample at 100usec (10khz), that leaves about 48usec to do 'other things'. That would do it in the assembler version.

    The big question, is there a PBP alternative that would be fast enough, and in fact leave a little time for other things?? I suspect not, and that I'll end up with a hybrid solution, using assembler for the SR, and PBP for the 'other things'.

    Joe

    Joe
    I would go for the 100uS interrupt and do the basic shifting in the ISR. every 8th bitshift do a single byte pointer reallocation. That would be the circular buffer. You could trim it down to 10 clock cycles per interrupt, and every 8th interrupt 20 clock cycles.

    Picbasic, like C, and most other high level languages, are macro systems for assembler, of particular flavours depending on the main application. I consider myself lucky that I learned assembler first before any other langauge (with the exception of the file handler friendly OPL on Psion PDA's)

Similar Threads

  1. Active low input?
    By CosMecc in forum mel PIC BASIC Pro
    Replies: 14
    Last Post: - 8th August 2010, 20:31
  2. PIC16F877A pwm use for IR transmission
    By mcbeasleyjr in forum General
    Replies: 0
    Last Post: - 11th July 2009, 18:51
  3. Replacing shift register with PIC
    By TonyA in forum mel PIC BASIC Pro
    Replies: 6
    Last Post: - 7th April 2008, 18:31
  4. Shift Register Woes, specifically the STP16DP05
    By elec_mech in forum mel PIC BASIC Pro
    Replies: 2
    Last Post: - 11th November 2007, 23:22
  5. Replies: 15
    Last Post: - 30th January 2005, 03:58

Members who have read this thread : 0

You do not have permission to view the list of names.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts