Serializing: shift registers vs. multiplexers - Page 1
Forum section: electronics / general

author: SiliconWizard
author_rank: Super Contributor
timestamp: March 15, 2021, 05:26:45 pm
content: Just another musing. Not strictly FPGA stuff, it's more like a general digital logic matter.For serializing data, one can either use a shift register, shift and output the LSB or MSB at each cycle... or, we can use a multiplexer, and select the right bit at each cycle.In your opinion, what is the better approach in terms of area and Fmax? Is there a break-even number of bits for which one becomes better than the other? How scalable (in terms of number of bits) one is compared to the other?From what I've seen, dedicated serializers in FPGAs (but honestly I have only seen a bit of details for a limited number of models) tend to be a mix of both shift registers and multiplexers, cascaded in some way.Your thoughts? (Again it's a general question about low-level implementation of serializers, not a question dealing with implementing serializers in HDL.)

author: dmills
author_rank: Super Contributor
timestamp: March 15, 2021, 05:55:26 pm
content: Depends on the chip in question.For example the Xilinx stuff has the SRL16 as an alternative use for a single LUT, so if you can make the use case fit that instantiation template that will generally win.Remember, FPGAs do not (to a first order) have multiplexers in the fabric, what they have is LUTs that can be configured as multiplexers, it comes down to which are you tighter for LUTs or flipflops, and for me it is usually luts that are the limiting factor for fitting more stuff into the fpga.It is generally worth reading the device (and tool) manual for how to get the thing to actually use the magic that is available.The dedicated serdes on the IO or Gb transceivers tend to be kind of their own things, but you do often need a mess of combinatoric stuff behind them to implement gearboxes and such like.

author: Bassman59
author_rank: Super Contributor
timestamp: March 15, 2021, 06:16:52 pm
content: Quote from: SiliconWizard on March 15, 2021, 05:26:45 pmEvery so often I muse on this, too. Yes, it's weird.Anyway.The shift register approach fits in well with FPGA fabrics that have them in the slice, such as the Xilinx SRL32. There are no routing or area penalties. But! This is a "fake" shift register because it's actually implemented in the CLB as a mux.The mux approach requires a counter to pick the desired output, and that counter has to be initialized prior to the start of shift process. Doing this with the load which precedes the shift makes sense. The code ends up looking like:Code:mux_based_serializer : process (clk, rst_l) isbeginif rst_l = '0' thenbitcnt <= 0;sr <= (others => '0');elsif rising_edge(clk) thenif load = '1' thensr <= loadvalue;bitcnt <= MSB;elsif bitcnt > 0 thenbitcnt <= bitcnt - 1;end if;end if;end process mux_based_serializer;outbit <= sr(bitcnt);This has an advantage in that the bit select (for the mux) and the counter which drives the shift process are the same. The serializer idles when the counter indicates the last bit.The shift-register approach might look like it doesn't need the counter:Code:shiftreg_based_serializer : process (clk, rst_l) isbeginif rst_l = '0' thensr <= (others => '0');elsif rising_edge(clk) thenif load = '1' thensr <= loadvalue;elsesr <= sr(sr'left - 1 downto 0) & '0';end if;end if;end process shiftreg_based_serializer;outbit <= sr(sr'left);... but something has to manage when the shift register is loaded, and that's often a counter, or a state machine which has to know how many bits to shift so it knows when it can load the next word. So there's no savings there.Expanding the length of the serializer is easily managed by changing a constant or generic which defines the number of bits and that's the same for both cases.And that brings up the larger idea, which is that a serializer doesn't exist in a vacuum. It needs logic to control it and that all gets wrapped up into the design and might be hard to quantify.I think using an SRL32 (or equivalent) might end up being the "fastest" and use the fewest routing resources. But my guess is that for rational shift registers (32 bits in length) neither approach "wins."

author: dtodorov
author_rank: Contributor
timestamp: March 15, 2021, 06:25:06 pm
content: IMO a serdes using shift only has the advantages of+ glitch free output by design. Probably there are mux logics that are glitch free as well, but anyway.+ design efficient - it basically consists of chained FFs+ minimum timing paths, max tx/rx speedAnd disadvantages- no flexibily (assuming muxed solution can tx/rx data bits in arbitrary order), so LSB/MSB first style is easily configurable.

author: Bassman59
author_rank: Super Contributor
timestamp: March 15, 2021, 06:45:18 pm
content: Quote from: dtodorov on March 15, 2021, 06:25:06 pmPutting a register at the output of the mux is standard, even though my example above didn't implement one.And that's the subtle difference between putting the simple mux-select assignment inside the synchronous process and outside of it.

author: NorthGuy
author_rank: Super Contributor
timestamp: March 15, 2021, 08:38:13 pm
content: Assuming you only build from LUTs and flops. You have N data inputs, and one output.Both will need a counter (which we can omit), but mux will need log2(N) counter inputs, while the shift register will need only one input from the counter.N = 2Mux is a single 3-input LUT and a single flop.Shift register is two 3-input LUTs and 2 flops.Mux wins.N = 4Mux is a single 6-input LUT and a single flop.Shift register is four 3-input LUTs and 4 flops.Mux wins even more.N = 8Mux is a logic system with 11 inputs and a single flop.Shift register is eight 3-input LUTs and 8 flops.Mux now spreads several logic levels, so it will be slower than a shift register, but it probably still uses less LUTs...N = a lotMux is a complex logic system which is very slow, but still uses only one flop.Shift register is N 3-input LUTs and N flops, and it still runs at the max speed until the counter grows up to become a limiting factor.

author: dtodorov
author_rank: Contributor
timestamp: March 16, 2021, 07:01:31 am
content: In my mind, data was always buffered. So MUX implementation would need the N number of FFs, while shift register could be directly loaded with data to be shifted (i.e. act as data buffer itself).

author: NorthGuy
author_rank: Super Contributor
timestamp: March 16, 2021, 01:17:40 pm
content: Quote from: dtodorov on March 16, 2021, 07:01:31 amIt all comes from some sort of flops somewhere else in the design. In both cases, you can insert extra combinatorial logic between these flops and your serializer. So, this is a moot point. The LUTs used in shift register have lots of unused inputs which can accommodate some combinatorial logic without losing speed.There's a difference though. For the mux, you need to hold your data for N clock edges. For the shift register, you only need 1 clock edge and then the data is free to change for the rest N-1 clock edges. This might be a reason to prefer the shift register. Or it may not matter. For example, if you go from slower clock to a synchronized clock which is N times faster, the data is held automatically. But then again, the mux would require the serializer's counter to be synchronized with the edges of the slower clock, while the shift register wouldn't.Of course, most of the time, you'll use built-in hardware SERDES elements which are not made of LUTs and are much more complex because they need to accommodate lots of different configurations.

author: SiliconWizard
author_rank: Super Contributor
timestamp: March 16, 2021, 07:01:44 pm
content: Thanks for the answers. Some interesting points. But I'll say it again - I was more after low-level (gate level) implementations of serializers, not FPGA implementation with LUTs. I posted the question here as there isn't really a dedicated section for digital design.As I initially said, I have witnessed implementations (for high-speed serializers) involving some cascade of small shift registers and multiplexers. So, that's more in this direction that I think the discussion would be interesting.When I say gate-level, using blocks such as flip-flops and basic MUXes is alright, as long as they are low-level.As to glitches with MUXes, as Bassman59 said, using flip-flops (registered MUX) is a simple solution and perfectly acceptable here.

author: NorthGuy
author_rank: Super Contributor
timestamp: March 16, 2021, 09:49:18 pm
content: Quote from: SiliconWizard on March 16, 2021, 07:01:44 pmLUT is, sort of, a collection of muxes, therefore the ability of using LUTs helps the mux case.At the "gate" level, I guess, the shift register wins - a chain of flops with muxes in-between. In addition to this you need a counter to drive muxes, or a ring of flip-flops.The complexity you see in FPGA SERDES elements is mostly due to their configurability.