Routing tips for mixed-signal PCB that can't have normal isolation

Hello, I’m still working on my PCB, and I’ve made a ton of progress thanks to all the videos and advice I’ve received. I’m nearing the end of this first design iteration, and I’ve run into a tricky situation and I’m looking for tips and advice:

I have a “U”-shaped PCB. On the one side is my 3V3 power supply, and on the other side is my MCU with integrated ADC. spaced along the outer edge of the “U” are 4 externally connected ports, which have 2A max current & 8MHz max SPI buses. I’ve set up instrumentation amplifiers (with a built-in comparator) on the high side of the power to these connectors in order to monitor power consumption with the MCU’s ADC & trigger a fail-safe shutdown with the open-collector comparator outputs.

Due to the shape of the PCB, the component density, and the cost difference between 4 and 6 layer boards, I need to route the SPI, low-speed GPIO/failsafe, the INA output, and a PWM trace roughly parallel to one another. Due to the power needs of the design, the stackup I’m using is:

Top: components, high power rails
Inner 1: low power rails, extra signals that don’t fit on Inner 2
Inner 2: most signals
Bottom: ground plane

I’m looking for tips and advice for how to approach routing this mixed-signal design, given that I don’t think I can follow general best practices (since the analog and digital portions need to be clustered around the external connectors), and I don’t have space (or the design to increase cost) by adding I2C ADCs to locate near the amplifiers.

Here are some ideas I had that I don’t know about: When I need to use multiple layer changes to route through a tricky, tight area, should I prioritize the analog or the high-speed digital traces? Should I make “shields” around the analog traces by running them on Inner 2 and adding a narrow ground shield on Inner 1? Would I need to via stitch such a shield (I don’t have space to via stitch)? Since my ADC sampling rate will be every ~20-30ms and I’ve got a lowpass RC filter on the INA, does this even matter? Should I make the analog or digital traces thicker (I’m using 5mil traces for both)? Should I change my layer stackup in some way?

I’ve been operating under the following routing “algorithm”: first, I route the very high power traces, because thermal issues give me major constraints. Next, I route the high speed signals (UART, SPI, I2C) on inner layers as straight as possible, avoiding crossing under switching power supply current loops. Next, I route functional modules, like the INAs and other ICs. Finally, I route the low speed signals and analog traces wherever they fit. I figure the low speed/GPIO traces can meander tons without any issue, and although I managed to get the analog traces to be roughly straight-shots, 2 of the 4 analog traces have 4 layer changes (where ideally there would just be 2 layer changes to route on an inner layer).

I know this is a lot to write, but my research is coming up short, since everything out there focuses on separation, which is a non-starter on this board due to the density, space, and geometry constraints. Thank you for your advice!

How important are your ADC signals? How many bits are you using? Based on your description, you are probably going to pick up a fair amount of noise. Ideally, your analog section would be completely separate from the digital and power supply sections.

While integrated ADC in an MCU is wonderful to have, you might want to consider doing the filtering/processing/conversion at the input to the board. While an external ADC adds cost and takes space (not much, though), it is amazing how much cleaner a signal you will get. If you use an I2C ADC, you might have less to route back to the MCU.

The signals aren’t important at all for the device functionality. The INA’s comparator serves to trigger an emergency shutoff (very important, but an open collector digital signal with a pullup placeholder on each side of the board, so no integrity worries here). The INA’s analog output gets measured by the MCU just so that I can have a sense of current consumption based on functionality, and to potentially alert on anomalous current draw (i.e. I think the subsystem is turned off, but it’s drawing 500mA, which is under the safety threshold, but indicates misbehavior nonetheless). I think if I even had 6 bits of ADC accuracy (INA outputs 0-2V for 0-2A current, ADC reference is a filtered 3.3V system rail), that would give me ~50mA of precision, which should be fine. I’ll be measuring the ADC at 8 bits.

The power consuming devices are LED strips displaying visualizations.

It should be ok. I’d use some sort of FRC/IRC filter to make the readings fairly stable if you can stand the delay.

Would it make sense to move the ground plane to directly underneath the high power signals? That seems like it would provide some amount of shielding to everything underneath.

I agree- if you’re going to have only one ground plane, you should probably put it between two layers so it’s at least providing close, tight return paths for two of the layers.

In a perfect world for noise and EMI, you’d have a ground plane right next to every signal path. If you can’t afford two ground planes, at least put the one between two layers of routing.

1 Like

The INA has low output impedance, so if you add a sampling cap at the ADC input, you should not see much noise pickup. Place a 100nF cap, be sure the INA can handle that capacitive loading, and sample at some medium sample rate

Here is some more information on layer stackup that I found helpful:

What is an FRC/IRC filter? I haven’t heard this terminology before.

My rule of thumb for addressing noise is “Requirements, Schematic, Layout”. You’re already in a good spot because your requirements are well understood and none of the signals you’re routing sound overly scary. Make sure you’ve done what you can in the first two categories before you start prophylactically via stitching.

I believe your noise coupling will be primarily in the schematic - low frequency coupled through explicit connections (e.g. power rail coupling).

I’d put source-side resistors on your 8MHz SPI bus (33 Ohm to start), and scope the results at the sink-side. Make sure the edges are crisp but not crispy by changing that source resistor. It’ll be the higher order harmonics that are sensitive to routing, the 8MHz fundamental is unlikely to couple over enough to impact your analog routes.

Big LEDs tend to be be high di/dt and high ratio loads. Make sure your power supply can handle the transients, especially from all on to all off. Some regulator control loops can’t handle a sudden no load condition gracefully.

A low impedance trace is almost a strip of ground if you squint hard enough while chanting “in the limit of f -> infinity”. It isn’t as good as a via stitched strip, but you probably don’t need that anyway. If you have to run analog and digital together for long parallel segments, put low speed low impedance digital in the middle.

Can you increase your sampling rate and oversample? This can be a free way to buy some noise rejection. Can you move your analog filters closer to the ADCs?

Sorry for my typos - I mean FIR/IIR digital filters FIR Via Wikipedia (I seem to have the wrong TLO stuck in my head.) There is a fair amount of math in the article (and the corresponding IIR one) but practical examples can be very simple. Look at the moving average example in IIR to get the idea - simple to implement with minimal computation and storage.

Got it, thanks! I had half assumed you meant FIR/IIR but didn’t want to waste the opportunity to potentially learn something new

As to the ground plane comments. In a 4L stackup, I prefer (from top to bottom) Sig/Gnd/Power/Sig. I try to put the vast majority of signals on the top next to the gnd plane. In a recent board with 120 components, I got about 80% on top and the rest on the bottom, for example. If there is no other way, I will use the power plane for a signal but that is truly a last resort. (Don’t be afraid tear things up and reroute if you route yourself into a corner.)

If nothing else, having signals on the two outer planes gives you the ability to cut traces if you need to do surgery to fix a mistake.

To your question about multiple vias. For low speed digital lines, it’s not really an issue but even 400 kHz I2C lines can be affected by lots of vias. They create echo bounces and thus make that nice clean signal a bit of a hash. Some times you have no choice but maybe there is a different part placement that allows you to route more cleanly. Also, I would focus on avoiding vias for things like clock signals. It’s hard to say if you will have problems without seeing your actual board, though.

Thanks for your advice. I can definitely add a digital filter and increase the ADC sampling rate (the peripheral supports DMA, so I can probably run it at a high rate).

Unfortunately, since the board has meaningful power (and thermal requirements), I need to run power & ground on the outside so that it only sees a 15-20C rise during normal operation. It’s too bad the cheap mfgrs only do 0.5oz on the inner layers–I’d need 8-12mm wide traces on the inside to route power, and that’s not feasible :frowning:

I went through and managed to get all of the long traces to only change to the inner layer for routing a single time, so at least they all have clean ground return paths available.

If you’d like to see the board, I exported the layers and courtyards to a PDF I attached. I do know that I need to add floods to open areas for manufacturability, but I’m still thinking about how to handle them.segment_board_traces.pdf (464.6 KB) The traces in question (long analog and digital side-by-side) are on Inner 2 spanning the bottom. The order is:

  • UART TX
  • UART RX
  • SPI MOSI
  • SPI SCK
  • I2C SCL
  • I2C SDA
  • Analog INA output
  • Analog INA output
  • PWM for a brushless fan (power circuit is further away and filtered by an inductor on the other side of a star-topology power rail)

I’ll try to respond to a few things:

I’m not sure if I can fit source-side resistors on the SPI bus, because I currently drop the bus to the signal layer under the MCU, and the area surrounding the MCU is insanely tight. I’d need to add additional vias to connect to to source side resistors, but it was my understanding that it’s better to reduce vias to avoid reflections. The SPI traces are 72mm long and feed into buffers before going to the LED strips.

The LED strip buck regulator is dedicated, and has soft start.

What do you mean “put low impedance digital in the middle”? Could I just put a trace grounded or one side, or do you mean putting a non-high-speed signal?

I can’t really move the analog filter closer to the ADC, because the analog filter is part of the INA’s feedback loop (for the comparator). Oversampling and filtering are definitely easy to do.

I can’t really move the analog filter closer to the ADC

You could add a bit of filtering just before the ADC if you have room. though, even 402s add up when you get to “acne-rash” levels.

So, I tried to separate and shield the long analog & digital traces. I increased the spacing between the traces and I moved half of them to another layer (which is 1mm away due to the core). I added a small ground fill on the top layer. I also added 2 traces (highlighted on the yellow & pink layers) that are grounded on both sides–on the yellow layer, the ground trace is separating SPI clock & data, and on the pink layer it is separating UART TX & RX. Lastly, I moved the I2C data line on to the yellow layer for the long stretch, and then back to the pink layer for the finished route.

I still don’t really understand whether what I’m doing with the ground separation and shielding–I’d really appreciate advice as to whether I connected these planes & ground traces in a way to reduce crosstalk & EMI risks, or if due to the short additional ground runs I accidentally could’ve worsened things :slight_smile:

The stackup is Front-Red/In1-Yellow/In2-Pink/Back-Green

72 mm is only a quarter of a nanosecond, or 1/500th of your clock speed. This puts you in “fine unless you do something egregious” territory.

What follows is a long rant about why you should just go ahead and use vias:

Vias aren’t scary, and if you avoid them too strongly you’ll end up making bad routing tradeoffs. They have two types of impact:

  1. They allow you to route in ways that might cut up planes in ways that you don’t want to.
  2. They change the characteristic impedance at that spot

Plane cutting is the part to avoid, and usually just a bit of via budging is good enough at your speeds. The obvious version is when the traces that are via-ed down slice up the ground plane and leave a twisted flood underneath. Don’t do that! The less obvious version is when the routes aren’t on the plane, but your vias are all next to each other in a line, forming a cut in the plane the length of that line. Stagger them enough to restore the plane and you’ll be fine. I typically do this as pairs or triplets of vias and then a nice bit of flood around each cluster.

Transmission lines and characteristic impedance evoke a lot of fear of reflections. Quick way to model it in your head:

  1. The edge of your signal puts high frequency energy into your line
  2. That energy is attenuated every time it bounces back and forth on your line
  3. The length of the line determines how long each bounce takes
  4. Bounces happen at all impedance mismatches, proportional to how severe the mismatch is
  5. An unterminated digital source is approximately 0 ohms, and an unterminated digital sink is approximately infinite ohms.
  6. The two rough figures of merit are:
    a) “Number of bounces until attenuation is sufficient * bounce time” <? “time until it matters” (e.g. data lines)
    b) Does the receiver interpret the result as monotonic after it’s debouncer? (e.g. clock lines)

Extending the rise time reduces the amount of high frequency energy, series resistance is a cheap way to add attenuation (and rise time). If you haven’t added any termination you have perfectly bad reflectors on both ends of your line - adding a minor reflector in the middle (e.g a via) is irrelevant compared to that!

If you aren’t source and/or sink terminating, vias don’t matter.

To mentally model the mismatch from a via, imagine squishing the equivalent copper on to one layer. If your trace goes from L1 to L2 on a 4L, the equivalent single layer copper is a segment roughly the width of the circumference of the via as long as the L1L2 height gap, plus a stub representing the L2L4 height (you aren’t back drilling).

Directly compare that mental model (different width + short stub) to whatever route you’d make to avoid adding the vias. If you’re adding significant length, or significant proximity to things you want to avoid, you’re better off with the vias. If you’re not adding resistors in order to avoid vias, you’re putting the cart before the horse.

1 Like

UART and SPI (except SPI SCK) are all sampled in the middle of the period. So ringing and other funny stuff around the transitions wont matter, just as long it’s clean in the middle

So make sure SPI SCK is safe

1 Like

@vanweric Thank you so much for your explanation of vias and impedence mismatching. That helps my mental model, and I feel more comfortable. With regards to termination, is that something I should consider given the lengths of traces and protocols I’m using? I know my CAN FD bus is terminated, but all this analog/signal stuff is pretty new to me.

@kvk That’s good to know about sampling times. Is the way I “shielded” the SPI SCK with the grounded trace & ground pour on top better than nothing? Or did I make things worse with partial return paths along the SCK trace? I still don’t have a good understanding of whether what I think is protecting the signal is actually doing so.