Archive for June, 2023

A system for debugging logic chips in-circuit automatically

June 6, 2023

In a previous entry I introduced an FPGA shield giving 64 bits of bidirectional 5v tolerant IO to a spartan 6. In this entry I will actually make it do something useful and show you how to get one. This post is also sponsored by PCBway.

Device in-circuit testing a 74S04, one pin unhooked to simulate a failed gate on the LEDs and the propagation delay as measured by the FPGA is shown on the scope

This project is intended to allow for the in-circuit testing of 74xx and 40xx style logic chips. We do that by sampling all the pins of a given chip (inputs and outputs) and compare the behavior of the real chip to one that we model in verilog. This lets the circuit operate normally, wiggling the input pins and we can track those changes and compare them to the chip’s output pins. From this we can get an idea of whether a chip is bad, but the chip under test is not necessarily causing the issue, it’s possible that something on the same net as the output pin is interfering with the signal. Hopefully I’ll be able to build up a series of models and clip right on to a running system to get an idea of whether there’s any reason to desolder and check a given chip out of circuit. Let’s walk through this repository one file at a time. First is the pin definitions file for this project.

At the top we have the clock pin which has a 50Mhz oscillator on it, the reset button, and some pins for interface with the onboard LEDs. The SPI and Serial aren’t used in this project, but they are on the mojo main board, so they’re here in case you wat to utilize them in the future. My additional pins start with the data_bit bus.

At the end we have what this project calls debug_bits, but as far as the silkscreen is concerned those are just data_bits 56-63. The enable_bits are needed to turn each 8-bit level shifter individually, if you need to save I/O you can wire them to always on or always off, but our purposes we just turn them all on.

There’s not a lot going on here in the top level verilog file. In the top module declaration I have added a couple things at the bottom that default from the default mojo project. The enable, data, and debug bits are all that’s needed for this board. Below that we invert the reset button signal and set the SPI pins to unused. Then we have to enable all the level shifters, I did this by setting the bits to 0 and then inverting them. This syntax expands to as many bits as you need to set high. Below that we have the high speed clock and dcm module that gets set up in the ISE to get our 50Mhz clock all the way up to 200Mhz. This will help with finer detection of the propagation delay of these chips. Finally we pass the relevant signals into our chip checker module. We’re using the 200Mhz clock to sample the pins, we have the reset signal passed in so we can zero out any latched checks, we have all the pins of the chip we’re checking passed in, and the LEDs to tell us if something’s wrong and the debug pins to help us quantify what’s wrong.

The clocking wizard in the ISE is where I got my 50Mhz clocked sped up to 200Mhz, it’s not a text file but it’s still pretty easy to use. We turned off all the functions that weren’t needed and just have a simple high speed clock out.

The chip checker is nice and modular for ease of expanding in the future. It mostly exists to hook up our chip simulator, the comparator, and our counter/latch. The first thing we do is take the pins that we’re measuring going into our real 74s04 and run them into our model of a 7404, the output data from that model then gets run into the comparator as well as our sampling clock and the actual pins coming from our measured chip. The output from this model is a signal that represents a discrepancy between the model and the actual chip. In the case of a good chip that represents the propagation delay, for a bad chip that would differ from the correct signal for quite some more time than a few clock cycles. That difference signal is fed into the counter function that counts up and if any one of the channels is consistently off by more than a few clock cycles in a row it latches a flag output. Those flags are wired to the LEDs on the mojo board. The debug pins are assigned to the difference signals so we can see exactly how much the signal from our real chip differs from the model.

I don’t know what you were expecting for this model, but this is it. This represents the single simplest chip we could test.

The comparison isn’t complicated, but it’s a good example of a parameterized module. We have defined this one to have a default bus width of 1, but our use case overrides that and calls for 6 of them to be operating in parallel. The registers are all defined with a dynamic width, and every clock we latch in the values to our registers. Then, combiationally, we do a simple XOR of the expected signal with the detected signal to create our difference signal that is high only when the chip does not match our model. I will say it again here, that does not mean it’s broken, it may just have a longer propagation delay than 1 clock cycle.

This is the last and most annoying module (syntactically). We pass in 2 parameters, the width of the count like we did with the compare and the threshold where the flags are set for an error. Everything here happens on a clock pulse, even though it contains some loops. I assume that the ISE unrolls those loops for laying out the chip so it can all be done at once. Inside the always block we have a named begin, it seems that to have variables like a temporary variable for counting in a for loop you need to have a named begin/end block. We then handle the reset condition where all of the counters and all the flags are reset to an initial state of zero. If we’re not holding the reset button then we run through all the channels we’re checking and if it hasn’t hit the threshold yet we check to see if we should either add to the count for that channel or zero it out again. If we should add to it then it’s possible that in doing so we have hit the threshold so we check that inside the same check, but because this is all happening at the same time we have to check using the non-updated states of the variables. That’s why we check “if ((counter[i] + 1) >= THRESHOLD)” even after doing “counter[i] <= (counter[i] + 1);”.

That is all there is to it, when we count up more than the threshold number of differing states in a row we latch that LED on until it’s reset. This allows us to have a device that can be clipped on to chips in rapid succession and test for deviation from the expected behavior without having to remove the chip from the circuit and exhaustively exercise it ourselves. In this situation we do not end up testing certain aspects of the chip if they’re not being exercised but that’s alright as those functions may not be used in that application or something upstream may be broken and thus not exercising those pins. For different chips the threshold will likely have to be changed, the 74S04 we tested passed with a threshold of 3 cycles at 200Mhz, a 74LS04 would likely fail that strict of a threshold, a 7404 almost certainly would. Right now to test each different type and speed of chip requires pushing new code down to the device, but as a proof of concept this works quite well. I hope to continue enhancing this with extra functionality going forward.

To purchase one of these boards for yourself without any work on your part you can go to my project on PCBway’s website. From there you can view the BOM I put together for this as well as buy the boards straight from them. If you want to make some modifications or adapt the design to your own, more modern FPGA board I have the kicad 7 files up on my github here.

Modifying your Nissan 300zx digital dash to use modern sensors

June 6, 2023

The digital dashboard of the 1984 Nissan 300zx looks amazing. Why would you change this out for either some analog dash or something modern like a big emotionless screen. This has many segment VFDs, and they can be of variable brightness. The trouble is certain sensors they need are not super easy to find. For a friend’s project car we traced out how to easily modify the dash to take 5v logic level signals so we wouldn’t have to spoof the old junk.

The first one is rather uneventful, the vacuum sensor that indicates how much power the car’s making. With about 5 pounds of boost added to this engine the original sensor would just peg the scale to the max at nothing approaching full throttle. We dug into the diagnostic manual and simulated the voltage going in to the dash to see if we could simply make that signal with an analog voltage. That worked very well because the original sensor was not a variable resistance, but a variable voltage. This is something a teensy on the new CAN bus can do, output a voltage relative to the amount of boost currently being detected and scale that to the range of the gauge.

The next relatively easy ones are the temperature gauge and the oil pressure gauge. I traced those connections back to those four high wattage resistors you can see on the left. Each sensor uses one of those resistors as a pull up to an internal 5v reference, the sensors are a variable resistance to ground. By lifting one leg of each of the resistors we care about I can convert the input from a variable resistance to a variable voltage. Removing the half of the voltage divider in the dash and now sending a signal that’s between 0 and 5 volts. We did this for the two identical green 43 ohm resistors and it works great. The nice thing about this mod is that if you install the original sensor there it just reads 0 volts, it doesn’t read correctly but no damage is done to the dash.

The tricky signal is the tach signal, expecting a high voltage pulse from the distributor every time a cylinder fires. I traced the signal from the pin on the outside to this resistor between these two hybrid modules, R11. From there it goes into the hybrid module…

This is not actually that crazy hard to trace as long as you take for granted those ‘LC’ devices are some sort of transistor and I don’t care what the signal is doing at any given point I just want to follow it. Eventually it leaves the hybrid module, goes through ZD5 that zener diode and onto some surface mount stuff on the back of the board.

From the zener diode it goes through R92 and to pin 8 on one of the microcontrollers. We set up a function generator outputting 12v at 3600hz or so through a relay coil to generate spikes, a capacitor to suppress some noise, and a series resistor to protect the dash input. Once we were sure the dash was reading our simulated tach signal I measured pin 8 and sure enough there was a series of high going pulses capped at around 5v. I moved R92 to break connection with the signal conditioning circuitry and did the same on the top with R11, then I connected the pin on the dash connector straight through to the microcontroller pin through a 100 ohm current limiting resistor. I intend to replace that wire with an opto-isolator based around the dashboard’s local 5v reference at some point but for now the connection works. The down side is that serious damage could occur to the microcontroller if you run a stock tach signal into this pin now. The opto-isolator will protect the processor, but in a sort of sacrificial way.

All 4 resistors I moved are still there and can be reconnected if someone wants this dash more stock, so it’s a completely reversible mod. Until I come back with the opto-isolator circuit I leave you with this custom VFD that they had installed for the speedo:

The speedometer only goes to 399, you mean to tell me this thing can’t go faster than 399 miles per hour? No, it can’t.

EDIT: here’s the optoisolator circuit I put together. It’s super simple to make on some protoboard, you should reference the right side 5v to the dash (See how I labeled it?) and the ground also to the logic ground in the dash. You can get all 3 pins straight from the microcontroller to be sure it’s the right power and ground busses. You can use the car’s local ground and just run your 5v tach signal to the original pin in the dash or you can run both the tach signal and reference ground together on a separate connector. Remember, to drive an optoisolator all you’re doing is lighting up an LED, it’s not complicated.