--- Quote Start ---
I would argue that this is bad solution. What if your external SPI clock from the microcontroller has ringing or noise? You will then get your test vector shifted incorrectly.
A more robust solution is to synchronize the SPI interface to the CPLD clock (and perhaps check a checksum if you want it really robust), i.e., use logic to detect rising-edges of the clock, and to check that there are no glitches that would cause double clocking. The detected clock edges are then used as enable pulses to the shift register.
--- Quote End ---
Understood. I'll include a crystal in the next revision of the board. Not quite sure how to sync. the the clocks, though.
--- Quote Start ---
Right, but when you shift a 1, as it moves along the shift register, it will enable the first output, then the second, then the third, etc. This does not sound like the right solution to me, as you are supposed to be sending specific tests along the wires. With the loabable scheme you have more control.
So you have the first output disabled, and then start enabling the other outputs. That does not make sense. If you invert the logic, then you have one output enabled and the others not. But even then, its hardly an exhaustive test.
--- Quote End ---
I'll try to describe the test. I'll ignore tri-states and things like that for now. I'll assume that we have a normal IO and no tri-state. So if we load 00000001 into the shift register, that's what appears at the output.
Now suppose we have 8 wires to test and there is a short circuit between wire 1 and 2. The shift register is loaded with 00000001. The shift register thats connected at the other end of the wires (parallel in serial out) loads these values and then shifts them out to the uC. Because there is a short circuit between wire 1 and 2, the shift register will read 00000011 - the expected output was 00000001 and it would have been this if the wires were OK.
We note this down and pulse the shift register. The shift register contents now read 00000010. At the other end, the values read at 00000011. Again, we know we have a short and this is just another confirmation. We then send another pulse. The register reads 00000100 and at the other end it's 00000100. Wire 3 is OK, its not short circuited anywhere.
Now the register is 00001000. If we read 00000000 we know that we have a broken wire. How does uC 'know' weather the output is OK or not? It maps out the wires. This is essentially a wiring harness tester for automobiles. As the harness is different for every model, the microcontroller first maps out a "reference" harness and stores it. When the outputs don't match, it knows there's an error. I'm sure you knew this but I wanted to explain further. I felt this was an exhaustive test - but if you feel I can do more, let me know. For what it's worth, I know specific test vectors could be generated that would test the harness much more quickly but time isn't a big factor. The harness is still connected manually onto jigs and then tested. As it is, the electronics are not the limiting factor.
This is obviously a simple example, but I hope you can see that it also takes into account junctions and such. But what I hope I showed was that there was no need to load the shift register again and again, when it could just be 'pulsed'. I know your approach has advantages but I just felt because I will always have a walking one/zero test vector, there's no need to a loading mechanism. But perhaps I'm still missing something here... you've been very patient with me and I appreciate that. I've learned a lot from this thread. And indeed, now I do understand that because of noise or ringing, the register could end up being shifted more than intended. As mentioned, I will definitely include a crystal on the next revision. But is a free running clock still necessary?
--- Quote Start ---
Its not an 8-bit register. Its
generic VHDL you set the WIDTH parameter to the width you want. I set it to 8 so you could compare the two implementations.
--- Quote End ---
I know this. I said it's 8-bit register so we could discuss 8 values and not 30 or however much. The actual final circuit will need to test harnesses containing upto 300 wires so a 300 bit register will be needed and I know I can easily change a few variables to achieve that.
--- Quote Start ---
You've got your logic inverted again. If you want the
output 11111101, then you want to load the
output-enable shift register with 00000010.
--- Quote End ---
Sorry, still trying to get my head wrapped around this.
--- Quote Start ---
If you are using SPI, then there should be an chip-select bit, you can use that to control the loading, i.e., the micro asserts chip-select, then sends as many bytes as you deem appropriate, and a state machine at the other end receives them, loading them into internal registers. When you deassert chip-select to indicate the command is complete. The state machine checks the bytes are valid and then updates the parallel output-enable register.
--- Quote End ---
Only one shift register is connected via SPI - the parallel in serial out is connected via SPI as it allows me to shift out whole contents very easily.
The parallel out serial in is connected via general purpose IO pins and thats controlled like I described in my previous post.
--- Quote Start ---
How fast is your SPI clock on the microcontroller? You really do not have an oscillator on your board? That was a poor design choice, you should always have an oscillator footprint on a board, and just not load it if you do not use it. The MAX V CPLDs probably have an on-chip oscillator (the MAX IIs do), so I could write an example showing what I am proposing to you.
--- Quote End ---
The SPI clock is at 62.5KHz. It's so slow because speed isn't necessary - as mentioned, the limiting factor isn't the electronics.
--- Quote Start ---
And never never never create write-only registers. Your micro should be able to read back the output-enable register.
--- Quote End ---
Understood. I'll make sure the next revision of the board (the current board is just a prototype) has a crystal and that the uC is able to read back the contents. This will provide valuble feedback weather data was loaded correctly or not.
EDIT: Reading the document on max v architecture (
http://www.altera.com/literature/hb/max-v/mv51002.pdf), page 2-21 and 2-22 talk about the internal oscillator. Is this the oscillator you were talking about? If so, how can I use this to synchronize my shift register and uC? As mentioned, only one of the shift registers is connected via SPI. But if required, I'll connect both of them via SPI on the next revision.