ISOLATION OF DISK MODELING FROM OTHER ASPECTS OF THE DESIGN
I abstracted all the logic that deals with the disk drive into one module. This detects the rotation, models the sections of a sector with accurate timing, and generate the clock and data pulses that will be fed into the disk drive electronics to fool the drive into believing it is reading a physical cartridge.
This module will also capture the stream sent from the disk controller to the drive, converting that into the 321 words of a sector and writing them back to the cartridge image.
The abstractions means that this module has a simple interaction with the rest of the design, outside of the disk drive oriented signals that it handles. It sends a request to read or write a word of data, with the 16 bit data contents, to some other module which will interact with the DRAM on the board that holds the image of a virtual 2315 cartridge. The other module emits a completion signal, telling this module that its request is completed.
There will be 321 requests to read a word while we are in read mode on the drive, otherwise we will capture the written stream from the disk controller and request up to 321 writes of a word. This module does not directly generate the address of a particular word in a sector. Instead, the disk modeling emits the current cylinder number, sector and word within a sector, all accessible to the other module which will use that (plus the active head number) to index into the virtual 2315 cartridge image to the proper spot for a word being written or read.
The disk modeling logic watches the signals related to arm movement, mirroring the position of the disk arm from the real disk drive. Thus, when a request to move is received, forward or backward, 10mil or 20mil, the modeling adjusts the current cylinder number. The signal Home is used by the controller (and our modeling logic) to know definitively when we are at the cylinder 0 position.
The disk modeling logic receives the Index Mark and Sector Mark signals, which are generated by features on the physical disk cartridge which is rotating in the disk drive. At the target 1500 RPM rate of the drive, we will see a Sector Mark every 5 milliseconds and the Index Mark once per 40 ms rotation. We use these to count off sector numbers, as well as kicking off the timing for the 10 ms duration of one sector.
We model the transition of the sector from its starting point as the Sector Mark pulse ends, through 250 microseconds where we send continuous zero bits, past the fixed sync word and then loop through the 321 words of the remainder of the sector. Each word is 20 bit cells long on the disk, 16 data bits plus four ECC bits.
A bit cell consists of two halves, each of those 720 nanoseconds long. The first half is the clock interval where we always emit a pulse as the clock. The second half is the data interval, where the absence of a pulse indicates a zero bit and the presence of a pulse indicates a bit value of one. Thus, every 1,440 nanoseconds we have a bit cell whose data value is either 0 or 1. Over the course of 28.8 microseconds we see the 20 bits that encode the word bits 15 to 0 and the four ECC bits.
Our disk modeling logic precisely times the passing of the sector, emitting the pulses onto the read head that are clock and data values of each bit cell, organizing each word at the right time and including all the preamble of zero bits and the sync word in the beginning at the exact time they would occur with a 1500 RPM disk platter under the real read heads
Writing from the CPU onto the disk involves a pair of clock pulses generated by the CPU - phase A and phase B which represent the clock interval and the data interval of a bit cell. During the phase B time when we are looking for the data bit value of that bit cell, sensing a pulse generates a 1 data value else we see this as a zero.
The disk controller electronics are producing those clock pulses and the data bit values according to the sector layout scheme, thus at the end of the Sector Mark we will get roughly 250 microseconds of bit value zero. We will closely synchronize when we capture the first data bit value of 1, which is from the sync word. We should see that 1 bit followed by three other 1 bits and a 0 bit, which is the correct ECC pattern for the word x8000 that is our sync pattern.
From that point forward, we count off phase B cycles and capture the data bits, assembling each 20 bit word and eventually all 321 words of the sector. As we finish assembling the 16 bit word value from the 20 bits we received, that is written to the other module to put into RAM.
SIMULATION TESTBENCH TECHNIQUES
There are some interlocked signal exchanges particularly for the disk arm movement actions. A status signal for Ready will flip off once an Access Go command is issued, turning back on when the movement is complete. Rather than laboriously code the various signals in my testbench, I wrote a macro for arm movement that will properly sequence and time the activities to drive my disk modeling logic.
Substitutes for interactions in other modules
My disk modeling module interacts with the rest of the system by raising a RAM read request, then waiting until the request complete signal is returned (along with a data word). For the write functionality, it puts a data word in a register and raises a RAM write request, waiting for the request complete signal to indicate success.
I wrote a process that loops waiting for the RAM read request line to go high, after which it presents the new data word and signals request completion, all with appropriate timing. This allowed me to inject a data word every time my modeling module asked for the next word of the sector data.
Convenient file based test data
The testbench simulation environment incudes the ability to read and write to text files on my laptop. I used this to build a file to feed memory words to the testbench. I can easily modify the words I send and play around with different patterns.
CAREFUL STUDY OF THE SIMULATION RESULTS
I could see that with realistic Sector Mark and Index Mark signals generated in my testbench, the rotation model produced correct timing - the sectors were exactly 10 milliseconds long.
I produced sequences of arm movement requests to verify that the cylinder was appropriately mirrored to exactly match what the physical disk drive location would be.
While the logic modeling the flow of every sector from end of Sector Mark onwards, it did not produce any read head data unless the ReadGate control signal was active. This is what the disk controller sets to ask the drive to stream the clock and data bits from the head into the controller.
I carefully checked the duration and placement of every element within the sector for disk reads. This included the length of bitcells, clock and data pulses. It validated the length and proper formatted of the preamble of about 250 microseconds of zero bit cells. The sync word was properly formatted and timed immediately thereafter.
Every data word was generated with its clock and data pulses, at precisely the correct time. Each word consumed 28,800 microseconds with the 16 data bits followed by four check bits. This repeated properly for all 321 data words of the sector.
I also verified that the word number of each word in the sector was properly generated for use by the other modules which will produce RAM addresses to read or write that word in the virtual cartridge image.
Finally, the ECC bit patterns were properly produced based on the number of 1 valued data bits in the word.
Since I am comfortable with the disk read process as well as the disk rotation and arm movement logic, I can move on to test the logic that will capture writes to disk. These occur when the disk controller raises the WriteGate control signal.
Writing is the last part of the disk modeling that needs validation. I can then build up the logic that requests the proper RAM read/write over the bridge to the ARM core side running Linux. That plus all the user interface logic remains to be coded and tested.