Tuesday, August 30, 2016

Addressing the frequency challenges in level shifting the disk head signals, building out disk driver logic


To deal with the high frequency level shifting demands I have for the datastreams to and from the disk heads, I chose and ordered some different components. The two incoming lines, Read Clock and Read Data, will be handled by a 3.3V zener diode to clamp the high level to 3.3V. The combined outbound Write Data and Clock signal will be driven by a 74HCT125 chip.

These solutions are much faster than the chips I originally used. I have to do some rework on my driver role extension board, but have plenty of room to add the new chip and the two zener diodes. Then there is a small amount of rewiring for the three signal's input and output wires.

I also discovered that I could rewire on power line and swap out the CD4504b chips for CD4050b, giving me the same level shifting on input lines but with much less delay. I will pick up the chips and improve the board by this substitution.

I also dug around to figure out why the register and file IO over USB was not working. The documentation from Digilent on this is abysmal, specifically they have no example UCF files to identify what pin they mean when they use various names in their reference code. None line up, they don't match the names on the Nexys2 board documentation, and it is extremely frustrating.

I went through this the last time I used their reference code and the functions they built into the Cypress USB chip on the board (but don't document worth a shit). I think I figured out that the Write flag used in the code belongs with the FLAGC signal and not the UsbWR signal, or one of a dozen aliases they use for each of these.

This worked great for register read/write, I can now update my registers and see the changed value from the PC side. I am still having trouble getting the File IO function to read and write the RAM properly. Investigating took a while. I couldn't see what was wrong - it was partially working at least but I seemed to always get zeroes back. I decided to hook the LEDs to the RAM output register which will let me see any non-zero bits immediately.

Turns out, no non-zero values at all. Something is not working properly which will take more detailed debugging into the function of the core memory access function and the DRAM itself. I will plan out a sequence of tests that will zoom in on whatever is wrong.

I spent the day dividing up the work involved in reading and writing a sector into modular blocks which I can implement once and use in multiple places. For example, the deserializer module which will return a word once every 16 bits but only while the logic is in the 'synced' state.

This requires some interesting timing oriented code - we are receiving pulses from the Read Clock and the Read Data lines asynchronously to our logic, and the way you detect that a 0 bit is sent is by the absence of a Read Data pulse during the period between two Read Clock signals.

I originally set up some timing to wait for this, but think I can use a more simple state machine so I will recode it. Essentially, the any time we get a '1' on Read Clock, we emit the state of a flip flop and then reset the flip flop. Beginning when the Read Clock goes back to '0', we watch and if Read Data is '1' in any tick, we set the flip flop on. Thus, every time there is a Read Clock rising edge, we emit the 0 or one from the prior interval.

This takes a bit of careful design to avoid emitting a spurious bit when we first are synced up, since the first clock pulse we see after we found the '1' of the sync word should be ignored. The design of the FSM should be able to accommodate this. In fact I tore up several designs and kept refactoring the logic.

At last, by eight PM, I had an elegant state machine that worked for delivering serial bits to the deserializer, waited through a preamble to find the sync ('1') bit, and would shut off on command at the end of a field.

No comments:

Post a Comment