BASED ON DISCOVERY OF THE ROOT CAUSE, I CORRECTED THE DESIGN
The state machine I developed to capture the data from a write command issued by the IBM 1130 to the disk drive started out of the idle condition based on a couple of conditions. One of them was unnecessary since the other condition already encompassed that event. Much earlier, testing had not failed, only due to good luck, but a small change I made a while back to debounce the incoming signal added a few cycles delay which was enough to cause the failure.
The Virtual 2315 Cartridge Facility (V2315CF) sits in between the IBM 1130 computer and the internal 2310 disk drive, substituting data held in RAM in the V2315CF for what would have been read or written by the disk heads. The 2310 disk drive uses interchangeable 2315 disk cartridges, hosting a 14" diameter magnetic platter, to store 512K words of data.
A rotation of the platter is divided into four equal sized segments, called sectors. A pulse, called a sector mark, is generated by the disk drive although physically the 2315 cartridge has eight slots around its ring thus produces eight sector markers per rotation. The IBM 1130 disk controller logic blocks every other sector marker pulse so that it indicates the start of each of the four logical sectors. The disk arm can move in and out between 203 cylindrical tracks that the head traces as the platter rotates.
When the IBM 1130 executes an instruction to write to a sector, the programmer specifies which of the four sectors will be replaced. The 1130 is keeping track of which sector is currently passing under the disk head and when the sector mark arrives for the sector being requested, the 1130 asserts the -Write Gate signal to begin the writing.
My state machine looked for the -Write Gate signal to go low but also waited for the falling edge of the -Sector Mark signal. If the sector mark pulse occurred coincidentally or after the falling edge of -Write Gate, my state machine would begin the write process. I did this based on some timing diagrams from IBM maintenance documentation, however the diagram implied that -Write Gate changed prior to the sector mark pulse. This was incorrect but the assumption drove my logic design.
The V2315CF generates a clock signal, -Write Clock Phase B, which it sends to the 1130. The 1130 uses a 1.44MHz oscillator in the disk drive to read and write data. Each 'bit cell' is divided into two halves, each 720 ns long. Because the FPGA clock is 25 nanoseconds, I am actually generating 725 ns intervals rather than 720. In the first half we are transmitting a clock bit of 1 and in the second half we send the data bit value, either 0 or 1.
The 1130 outputs a combined signal -Write Clock and Data which always goes low for one half of the clock signal, but is either low or high depending in the other half based on whether the data bit value is a 1 or 0 respectively. The logic is inverted: a low level is a value of 1. Thus, -Write Clock and Data alternates a constant 1 bit with a data bit that is either 1 or 0. My logic extracts the data bits from that stream and writes them into RAM in the location assigned to the sector.
The state machine watches the data bits being extracted, waiting during an initial long stream of 0 data bits for a specific sync word pattern 1 1 1 1 0 that tells us the very next data bit will be the low order bit of a 16 bit 1130 data word that has a four bit error correcting code appended (thus 20 data bits per 1130 word). We grab the 16 bits of data, validate that the error checking code is correct, then store the word and evaluate the next sequential data bit as the beginning of word 2 of the sector. This continues for up to 321 words, the max capacity of a sector on the 2315.
When I added a debouncer to the -Write Gate signal in order to ensure that a glitch wouldn't spuriously trigger the state machine, it added a bit of delay to that signal. The undelayed -Sector Mark signal therefore had its falling edge before my state machine saw -Write Gate and that meant the state machine did not receive the conditions needed to begin.
Since the 2315 cartridge actually generates 8 sector pulses per rotation - the 1130 ignores every other pulse so that it can create four larger sectors instead of 8 small ones. However, the -Sector Mark pulse I see with the V2315CF is the undivided signal with 8 pulses per rotation. Thus, the second sector mark pulse does arrive in the middle of a sector during the write - it is normallyignored . My state machine, having failed to leave the idle state when -Write Gate first was asserted, started at the midway point of the sector.
It is too late at that point to see the sync word - that comes about 10% of the way into the first half of the sector. My logic does come across a data bit sequence that is 1 1 1 1 0 at some point and begins interpreting what follows as the low order bit of word 1 of the sector. This produces gibberish, which is what I saw stored in RAM after a write was issued by the 1130.
Examining the logic diagrams for the 1130, I can see that the -Write Gate signal is generated from the issued request for a write when the correct sector number is arriving but also when the falling edge of -Sector Mark takes place. Thus, that condition is already implicit in -Write Gate going low. I erroneously enforced it in my state machine but the relative timing of the two signals were unfavorable for correct operation.
The change was very simple. I didn't monitor the falling edge of -Sector Mark as a start condition, only -Write Gate, which fixed the problem. I generated a new bitstream to load into the FPGA chip in the V2315CF.
RESULTS OF TESTING WITH THE CHANGED LOGIC
The test I use is to first read in a sector into a buffer in 1130 memory, then manually change a few words before issuing a write of the same sector. This should replace the contents of the sector with the changed data. I can validate that by reading it back with another read command, but also examined the mini 2315 cartridge that was loaded into the V2315CF during the testing.
When I unload the cartridge at the end of the test, the V2315CF writes back RAM to the microSD card inside the mini cartridge. This can be examined on my PC using a utility reader and a program to display the contents of any sector. It proved that the modified data was what was placed on the cartridge.
I also will see the bit pattern extracted by my state machine using a logic analyzer to capture the -Write Gate, -Write Clock Phase B, -Write Clock and Data, and a diagnostic output signal that showed whether each data bit was captured as a 1 or a 0. The results were much better, with the write occuring immediately as the -Write Gate signal was asserted low. It did detect the sync word and begin collecting data.
However, I wasn't happy with the quality of its operation. I noticed a few places where it skipped over a data bit value of 1. These seemed to take place soon after a glitch on the -Write Gate signal. I had debounced that signal, thus a glitch would need to stay on for 400 nanoseconds or longer in order for my state machine to see the signal as reset. The glitches were all 10 to 20 nanoseconds long, much too short to pass through my debouncer.
Instead, it appears that another logical condition that I combined with the -Write Gate, indicating that a cartridge is ready for use, may have glitched. This condition is detected by the Raspberry Pi PICO processor based on having loaded a virtual 2315 cartridge and the drive becoming ready to access. It should not be reset unless we turn off the drive or it becomes not ready due to a fault.
However, this is just a bit sent over the SPI (serial peripheral interface) link between the PICO and the FPGA logic. A message type of x00 will set the cartridge status based on bit 4 of the data byte in that message. If the SPI link is spuriously processing a message of that type it might be resetting the bit temporarily, however whatever condition is causing my state machine to believe that the write should end is quickly restored. Thus, I have my suspicions that the SPI link is not at fault in this error.
However, since it is the only condition besides -Write Gate that is used to abort the state machine, I don't see an alternative explanation at this time. What does appear to be happening is that my write state machine is aborting back to idle soon after a glitch on -Write Gate that shouldn't pass through the debouncer.
If the signal is seen as deasserted or the cartridge ready condition is withdrawn, the state machine goes back to idle. Because -Write Gate is intentionally asserted, once the glitch conditions expire the state machine will start over, scanning for another sync word. If it sees a 1 bit it will treat that like a sync and begin extracting data again. From the time when it went to idle until the time it sees the first data bit of 1, it is skipping over data.
I removed the cartridge ready condition from all the aborts. It is now only required to start the write state machine out of idle, otherwise we will only abort on deassertion of -Write Gate through the debouncer logic.
I suppose another possibility to consider is if the power to the V2315CF unit is drooping or noisy, it might be both the reason I see the glitch on the -Write Gate signal and the cause for the state machine to abort back to idle. I will put an oscilloscope on the 5V power rail going into the V2315CF main unit and set it to trigger if the voltage dips below about 4.8V. I can add some smoothing with a big filter capacitor if this is the cause.
DEVELOPED TOOLS TO HELP ME BETTER WATCH THE WRITE PROCESS
My main data capture is a logic analyzer that is monitoring four signals, triggered when -Write Gate has a falling edge and recording for long enough to cover multiple sectors. I use the program DSView that comes with the analyzer to look at the signals and evaluate my FPGA logic strategy based on the actual signals being used.
The program has an option to produce a CSV (comma separated values - file format used with Excel spreadsheets) of the data during the period when the signals are actively changing. The logic analyzer takes a sample of the signals every 10 nanoseconds and records the time when at least one of those signals changes along with the four signal states.
A write to a sector is transferring 321 words of data from the 1130 to the disk. It begins with a preamble of about 250 microseconds where the data bit value is always 0. This helps the disk drive determine which pulse on the disk was recorded as a clock bit (always 1 so always a pulse) so that it can know where the first half of the bit cell begins. It then watches the secodn half of the bit cell, the second 725ns of the bit cell, for a pulse to indicate a bit value of 1 otherwise the absence of a pulse during this half is taken as a zero.
Data is serial on the disk surface - a stream of over 6,420 bit cells. to record 321 words of data. Each word on an 1130 is 16 bits long, but when written on disk, an additional four bits is appended to each word that forms an error checking code (ECC). Thus a word requires 20 bit cells in total. The value of the ECC bits are checked against the 16 bit data word such that the sum of all data bits in the word plus the ECC must add up to a number which is an even multiple of four.
A data word of x1000 for example has only one data bit set to 1 so it needs the ECC bits to contain three 1 bits in order to arrive at an even multiple of four at the end of the word. A word of xFFFF already has 16 bits set to 1, thus already an even multiple of four so the ECC bits must all be 0.
Because this is a serial stream, the disk drive has to determine which bit cell is the start of a new word. This is assisted by a sync word beiing written. The sector begins with that preamble of all zero bit values, followed by the sync word. The pattern of the sync word is 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 and ECC bits of 1 1 1 0. The preamble is a long string of zero bits, so the first data bit of 1 is considered the end of the sync word (plus its four ECC bits of 1 1 1 0). This defines the very next data cell after the last ECC bit as the first bit of the first word of the sector.
Words are streamed out twenty bit cells at a time until the count of words to be written is completed. Normally, the 1130 uses 321 words for a sector so that is the reason we will see 6,420 bit cells from this point to near the end of the sector. Recording the state of those signals from the time that -Write Gate is first asserted until it is turned off produces 28,900 rows of spreadsheet data. I save this as an Excel spreadsheet file.
I wrote a Python program that reads in the spreadsheet file, locates all the points where the -Write Clock Phase B signal has a falling edge and captures the value of the -Write Clock and Data aignal at that time. Because the signals are inverted, I flip it so that a -Write Clock and Data value of 0 is recorded as a bit value of 1 and vice versa.
The program watches for the first data bit that is a 1 (the sync word) and begins interpreting bit cells after the ECC bits of the sync word are processed. I collect the 16 data bits, which are recorded in reverse order to how they are stored in IBM 1130 memory, convert them to the correct hexadecimal value in the order they exist in memory and print them. I print the word number and the timestamp of the start of the word.
I then collect the ECC bits and perform the validation, printing an error flag and the ECC bits if they word is not valid. This should match the data I wrote from the 1130 that the FPGA is capturing from the data stream. It should also match the data that is recorded on the virtual 2315 cartridge by the V2315CF when I display the sector after the testing. I can use the timestamp from the Python program to find the spot in the logic analyzer trace where the word starts, if anything is wrong with how it is captured.
The trace is about 7,130 bit cells long, which is why I needed to pointer into the timestamp to help me look closer at any point where I don't like the results.
I took the existing data at the first sector of the virtual 2315 cartridge, overwrote the first few words with x6969, x0000, x0F00, x0000 and x0000 leaving the remainder as it was. Word 9 of the existing sector had a value of x0002 and then the next non-zero word was numbrer 32 which should have been x00EF but is incorrect in the output above. The bit pattern on the disk should have been 1 1 1 1 0 1 1 1 0 0 0 0 0 0 0 0 with ECC bits 1 0 0 0 yet the data captured had shifted by one bit cell. x00EF became x01DE because of this shift.
The machine was capturing successfully when it saw the word 9 (x0002) but got out of sync somewhere between there and where word 32 began. Each bit cell is 29 microseconds long, and the times seem to line up consistent with that for the start of each of the 32 words shown above, but somehow the -Write Clock and Data value slipped.
Looking at the trace at the start of word 32, we can see that the 1130 did indeed send us the first three bits as 0 1 1 instead of 1 1 1. The top trace is -Write Gate, the bottom trace is -Write Clock Phase B and the middle trace is -Write Clock and Data, all of them inverted logic.
When the -Write Clock Phase B is high, this is the second half of a bit cell where the data bit value is transmitted. The first bit has -Write Clock and Data high, e.g a data bit value of 0. The next two bit cells have data bit values in -Write Clock and Datathat are mostly low, thus denoting a bit value of 1. This is what my FPGA logic captured, what the logic analyzer and Python program captured, but not what I wrote.
This suggests to me that the 1130 is seeing glitches on the -Write Clock Phase B signal causing it to think it missed a bit cell somewhere between words 9 and 32. The logic analyzer is capturing the source of the signal -Write Clock Phase B which is the V2315CF unit, coming out of my FPGA logic. On the logic analyzer the signal looks completely clean with no glitches that might suggest a reason the 1130 got out of sync.
I will need to observe the other end, where the signal arrives into the IBM 1130, to see if glitching is occurring over the signal path. I will capture another trace with the logic analyzer, hooked to pin B03 of slot K6 of compartment C1 of logic gate A in the 1130. It is also tied to pin D12 of slot L7 in the same gate and compartment. The first pin is used to cause the 1130 to shift bits out one by one, serializing each word, while the second pin is used to switch -Write Clock and Data between a constant 1 value for the clock half and the data bit value for the data half of the bit cell.
I will hang a scope probe on one of the two pins above and the logic analyzer on the other, since they are both connected to the same signal coming from the V2315CF.
There are several theories to be tested, if you have made it down to here in this blog post. First, I will be validating that the power is not dipping on the V2315CF causing glitching. Second, I will have bypassed the role of the SPI link so that it can't cause the resetting of the write state machine that I observed. Third, I will look at the -Write Clock Phase B signal as it is connected into the IBM 1130 disk controller logic circuitry.




No comments:
Post a Comment