Data Flow Description

A project log for WS2812B Delay Splitter

Splts a WS2812B bitstream, delaying one side by a selectable number of LEDs

petePete 10/28/2015 at 16:130 Comments

Here's a text description of how it all works, or at least should work. I've tested it on the dev kit by slowing down the oscillator, increasing the clock dividers, and upping the delay count until it resets after more than a second, then feeding a repeating 0.1s-on/0.4s-off pattern in on pin-1. I enable the LEDs on the dev board for the output pins, and pull-down jumper pins to set the delay. By slowing it down that much, I can count the pulses on D-Out and visually see how many come out before they appear on D-Delay. Now I just need to get the boards, solder parts on, and feed it a real bitstream...

To understand the text below, refresh your memory on logic truth tables and print out the logic diagram so you can follow the flow below while identifying the logic gates by name. 2-L0 is a short way of identifying 2-bit LUT0.

Oscillator/reset latch:

The oscillator can run at either 25kHz or 2MHz. Since this will be used to detect a quiet period of around 10us, a clock with a 40us pulse doesn't work, so it's configured for 2MHz (0.5us pulse). This pulse is used as the clock for DLY3 which is configured to delay only on falling edges. Assuming for the moment that nReset is high, DLY3 input follows D-In. As long DLY3 Output is high and D-In is receiving pulses, the rising edges of D-In restart the delay. When pulses stop and D-In goes low, after the delay, DLY3 output goes low. This triggers 3-L6 (acting as a RS Latch) to go low as well. However, the nReset signal this outputs is fed back into 2-L0 feeding DLY3 and ensures that DLY3 is fed a high signal. Since there's no delay on rising edges, DLY3 goes high again, and effectively generates a nResetPulse. 3-L6 stays latched low until the next D-In pulse, when nReset goes high and the reset state is lifted.

3-byte pulse generator:

D-In is fed as a clock signal to CNT1. Since CNT1 has a 3-cycle delay on reset and a 1-cycle delay on count completion, to make sure it always counts to 24 pulses, 2-L4 ensures it is restarted when either nResetPulse goes low OR every 24 pulses. After each 3-byte pulse or reset, CNT1 takes three clocks to reset and then counts to 21 before generating the next rising edge. P DLY is configured as a rising edge detector and outputs a 91ns pulse at the start of every 24th pulse.

5-bit frequency divider:

The 3-byte pulse is fed into a series of 5 D flip-flops that act as frequency dividers. The DFF's output is inverted and fed into its input. Since the three separate DFF cells don't have both Q and nQ, they're configured in nQ mode. This inverted input of nBit1, nBit2, and nBit4 is handled in the pin comparison logic below. Bits 8 and 16 are a little more complex, as they're generated by feeding the PipeDelay a de Bruijn sequence (n=2, s=2). After reset, the first two PipeDelay DFF states are (0, 0). By feeding a sequence of [1, 1, 0] as input, the outputs of internal DFFs 1 and 2 cycle through values of [(0, 0), (1, 0), (1, 1), (0, 1)], each one unique. Note that the second DFF does represent bit16 correctly, but the first DFF only matches bit8 for the first two entries in the sequence and is inverted for the second two. Therefore, Bit8 can be determined by an XNOR of both PipeDelay DFFs, which is included in the pin comparison logic below.

Pin comparisons/match detect:

After propagating through the DFFs, the five DFF states can be used to determine how many 3BytePulse signals have been seen since the last reset. There is comparison logic to compare each bit from the DFFs to its corresponding input pin. All these individual bit signals are combined with AND logic to raise a signal only when all five match. Note that, as the signal propagates through the DFFs, the individual bit values aren't necessarily correct until that propagation is complete. This may generate momentary spikes of positive output which must be accounted for below.

Enable latch:

As long as D-In is high, the 4-L0 latch will ignore the match signal from above. This gives time for the signals to propagate fully and reach a steady state. It also prevents the delayed output from including the trailing portion of the pulse that triggered the match. Once the match is detected and D-In falls, the latch is triggered and output is raised. This latch will stay triggered until nReset falls, and enables the D-Delay output through a simple AND with D-In at 2-L2. It should also be noted that, if match is high when nReset is held low, that indicates all pins are not grounded by the solder pads (value of 0), and the latch should start enabled, making a simple splitter with no delay on either leg.