Saturday, September 24, 2016

Working during lucid moments, in some cases cleaning up fever distorted logic

I finally had enough energy to sit at the PC to rework the RAM access state machine. Still far too exhausted to join the team working on the Alto. I managed about 30 minutes work on Friday and a couple of hours on Saturday.


Here is the signal timing chart that my state machine should be producing.

RAM protocol for pseudo-static read/write
With my state machine appearing to work perfectly in simulations, I built up simple FSMs to write the slide switches into RAM when one button is pushed, then read the content out into the LEDs when another button is depressed.

Once I know that I can read and write RAM properly, I will move on to replacing the Digilent utility code used to move files between PC and RAM. Tested the FSMs until I got this right. All was good thus begin reintegrating the utility access logic.

The main discovery I made today is that coding VHDL while feverish is not a good idea. I wrote "if signalx <= '1' then" several times, when it should have been "if signalx = '1' then". No error from the toolchain, but results in an assignment of '1' to the signal and an always-true condition for the if statement, not what I wanted at all.

Using the eight LEDs on the board, I displayed the top half of the word last read from memory, which matched the last data word of the disk sector emitted by my internal pattern generator. The problem is that I should not be doing any read of memory when reading the sector, everything should be a write.

This is a clue of a potential flaw somewhere, essentially a weakness in my logic for choosing when to write versus read. I made some improvements and tested more. The spurious output of data was resolved, but still not seeing data through the Adept utility.

At this point, going to recode the logic myself, leveraging my working memory access FSM. Setting up the FSMs for reading and writing the registers, particularly registers 9, 10 and 11, being the RAM address, was easy. More work was implementing the transactional "handshake" for the read or write to the automatic register 14.

I was still working on it by the end of Saturday, still going through bouts of fever but gradually getting better. Tomorrow I will finish up the utility access to my RAM read/write machine, test it and hopefully be ready to read disk contents in the afternoon.

Thursday, September 22, 2016

Flat on back with flu

I fell ill with a very strong influenza last night and the extreme fatigue has kept me almost immobile all day. I got nothing done on the tool or any other project.

Wednesday, September 21, 2016

RAM problems due to Xilinx handling of tristates (again)

Wednesdays are when I meet with the 1401 Restoration team at CHM. We had problems with one tape drive, which a team member traced back to a bad SMS card; swapped the card and tape drive now working just fine. Overall, the systems are in fairly good shape - exceptional shape given their age.


I know that RAM itself works because I can write data via the Adept utility and retrieve it successfully the same way, but my logic to write each extracted word from the disk into RAM is failing.

As I set up instrumentation, I think I discovered the source of the problem. It is the incompetent handling of tristate signals by the Xilinx toolchain. There are quite a few places where the Digilent provided code treats output signals as tristates - emits Z unless the module is active. I also followed that practice.

HOWEVER, the signals as defined in the top level module are type OUT, not INOUT, which means they are not tristate pins. I suspect that nothing good comes from having two separate sources that are treating the signal as a tristate - only emitting values when active - but the actual signal is not tristate hardware.

After I changed everything to INOUT, the Adept function to read and write to disk no longer worked. Grrrrrrrr. All because I leveraged some reference code which insisted on this stupid tristate behavior and won't play nice if integrated.

It is time to write my own logic to replace at least some of the Digilent reference code. I will be successful when I can read or write RAM. Before I coded it all from scratch, I realized that I could take all the control signal assignments out of the Digilent provided code section, where they used tristate Z as the default, and reimplement them in my memory access FSM.

Any time my memory FSM was in the idle state, it would connect the signals the same way as in the Digilent code, yet not use Z for inactive. In other words, these assignments in the idle state were replaced in toto by my assignments in all the other memory FSM states.

My first stab at this didn't work correctly - reading and writing via the Adept utility is funky, which is the only way I can verify things right now. Don't know if my routine is writing correctly but can't retrieve it or if everything hosed up. Still trying to avoid writing a lot of logic from scratch.

I came up with an improved scheme and will implement it tomorrow.

Tuesday, September 20, 2016

Problem with driver board seems to be with RAM write and read

More woodwork today with Diablo tool work in the afternoon in between tasks. Once the last pieces are painted, I can nail them down and this facade is ready to be assembled on site this weekend.

Roof behind columns
Sign to install near roofline

I discovered that slide switch 6 is not working on the Digilent board I am using - just a random defect of some sort. Everything else appears to work, most likely this is a failure in the switch itself.

I am directly watching the pattern generator output and the bits being emitted don't match what should be delivered. I was not sure if the pattern itself is malfunctioning or that the problem is in the way the driver logic is recognizing sync words and other data.

I programmed the analyzer to give me symbolic names for the state machines I am tracking - much easier to interpret than the binary digits emitted from the board. It will help me see if the logic is going awry somewhere.

I am seeing the state machine correctly collect the words as it should see them based on the pattern generator, therefore I have to turn my attention to whether I am writing properly to the on board RAM. I looked over examples of how this is addressed by Digilent reference code and adjusted my logic accordingly.

Logic simulator results look correct, so time to run this transactionally from the PC. The advantage of the built in test pattern generator is that I can trigger a read sector, it should write the results to memory, and then I can read out the words using the Adept utility. I should quickly see whether I wrote the proper data or not

The results were disappointing. The logic analyzer showed me triggering the writes with the proper extracted word, but when I read the RAM back afterwards nothing had been written there. I ran out of time tonight, but the resolution to this will require me to significantly reinstrument the signals going out to the logic analyzer, so that I can watch the RAM signals myself.

The big open question is whether the signal quality from the real Diablo drive through my level shifters will give me a good clean read of the sector. I need to hook up to the drive at our next session on Friday.

Monday, September 19, 2016

Testing with built in pattern generator and logic analyzer

Once again my time is divided, in this case I am helping build a Bavarian building facade with my wife, to be used for guest photos at a Oktoberfest themed fundraiser for the organization where she is involved.

Fortunately for my electronic hobbies, the building involves cutting batches of wood which must be painted by my wife and dry out before I can install them and repeat the cycle. This gives me an hour or two of free time in each go-around.


I put in some final instrumentation for use with the logic analyzer, then continued the wiring of all the signals into the unit. After the analyzer was wired, I had to jumper the outputs of the pattern generator to some of the input lines.

Once the physical wiring was done, I began to set up the logic analyzer to properly group and report the signals it is watching. This will take a bit of time but makes debugging much easier when looking through traces.

With the analyzer configured and everything wired, I began to capture some traces to see what was happening. My first problem was that the logic analyzer complained about slow or missing clocks, which is probably an issue with the connection I used to get the 50ns clock out of the board. I will try to use a different route that might have better signal characteristics.

Debugging fpga with built in pattern generator
Now I am reading the clock and seeing data, but it doesn't line up with what I expect. I will do more runs with various trigger and search patterns until I get an idea what is happening. Next were some runs where I triggered on the first 1 bit coming in on Read Data and contrasted that with what was being clocked in by my logic.

I had to smarten up the trigger criteria - Sector Mark followed by read sector FSM going to setup to read field 1, then look for '1' data bits. I found this occurred about 9 word times into the sector, which is far too early.

Back to the simulator to look over my test generator code, then more logic analyzer work until the test generator itself is doing the right thing. I can't debug the behavior of my disk driver logic if the input it sees is scrambled.

Sunday, September 18, 2016

Built in test generator to produce signals 'as if' real disk were being read


Having created a generator for test input, to loop back into my board instead of needing a real Diablo drive spinning, I have to sort out how to produce the essential bit stream of data as it would come in off the disk surface.

I figured out a technique that should allow me to produce a two dimensional array (an array of bit strings essentially), one array element per word in the sector and each entry is the 16 bits that will serially be produced for the word. That requires 327 16 bit words initialized in the testgenerator module.

The trick will be to adjust the timing to emit this just when the ReadData pulse should occur, but I can do that in the process which is currently producing the ReadClock pulses. For simplicity, I will emit the same sector pattern for every sector, for this incarnation of the test generator.

Luckily there is a single cycle state in the clock generator FSM which I can watch for, which resets the indices for word and bit so that I can cycle through them at the ReadData bit emission time. When the bit in question is 1, I emit a pulse, otherwise no pulse is produced.

I spent quite a bit of time creating realistic data patterns and ensuring the checksums would match. A very manual process, although I did set up an Excel spreadsheet to process the checksum calculations.

Getting the test generator to emit the right sequence of pulses to match my intended disk sector contents took more time than I expected, tripping over subtleties in two dimensional indexing in VHDL, something I do only rarely. Finally it was producing the bitstream I think we would see from the read head, at the times it should appear.

I used the Xilinx simulator to check the output and timing of everything, but the proof is the actual pulses being created.To finish testing this out, I will hook up the FPGA to my logic analyzer, then capture and record the patterns produced.

When the generated signals are right, I can jumper them to the appropriate 'inputs' of the tool and monitor the outputs and the diagnostic pins. I was still wiring the analyzer when the day ran out but I did have good looking results from the simulator.

As a side note, much of the logic I am working out here to produce the test signals will also be used for the emulator role. Therefore I am making progress on the rest of the tool while I work on the debugging of the driver role.

Saturday, September 17, 2016

Developing better testing and debugging functions


To make debugging easier, I embarked on two directions at the same time. One was to build in a test pattern generator, using spare I/O pins and some of the sizeable unused gates on the fpga. The other was to route key internal state out through 32 external I/O pins on the PMOD connectors of the board, in addition to whatever I can display via the eight LEDs and four 7-segment displays.

My test pattern generator now emits index and sector marks at the timing of a real disk drive. It produces the read data clock pulses at 600ns separation. Now, I have to work out a way to emit a realistic sector worth of read data pulses spaced directly in between the clock pulses at the appropriate timing.

The PMOD connectors now have the word that is extracted by the deserializer from the string of disk bits, along with the memory strobe pulse that triggers the writing of the value into RAM. I also plan to output the state of the key state machines involved in reading.