Wednesday, August 31, 2016

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

XEROX ALTO - DIABLO DISK TOOL CREATION

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.


Tuesday, August 30, 2016

Driver board tested okay, building driver logic now

XEROX ALTO - DIABLO DISK TOOL CREATION

I wired up the driver role extension board, powered it all up and began testing to see that my outputs would swing between 0 and +5 as I switched on each signal. I discovered that the signals for Cylinder Address 64 and Cylinder Address 128 were swapped,. I also discovered that my Index Marker, Read Clock and Read Data input signals were swapped around.

My solution to these was to adjust the documentation. I will then route them appropriately inside the FPGA and all will be well. It was time to add the layers of insulation and copper grounding plates to both sides and finalize this board for use.

I built up the logic to keep track of the current disk sector, watching the Index Marker and Sector Marker lines for pulses. Next, I built up the state machines to trigger a seek to a cylinder and a restore to home cylinder.

One design choice I made might get confusing as I work on my logic. The Diablo interface uses inverted logic, meaning that to activate a signal such as Restore, you set it to 0 while the inactive state is 1. Inputs are the same, with a Sector Marker signal staying at 1 except for a 5 microsecond period where it drops to 0 (active).

I invert all those signals at the entry/exit to my fpga, so that inside my logic, an active signal is 1. Thus, Sector Marker goes to 1 for a few microseconds. Restore is at 0 unless I want to request a restore, where I set the signal to 1 for a few microseconds.

This evening I added logic to match a specific sector target against the sector counter that is continuously running as the disk rotates. I finished with only a partial design for the main sector read FSM, which I have to break apart more modularly to leverage it better for the complex structure of a sector.

I am somewhat concerned that my level shifters are not fast enough for the Read Clock, Read Data and Write Data and Clock signals. I need to generate pulses with a rise time of <50ns and a duration of just 100ns, For the combined data and clock signal for writing, these occur every 320ns. The level shifters could be slower than 50ns for the pulse edges and will just barely fit two in the 320ns window.

I think I may need to come up with a manual circuit having a much faster transition time and frequency response. The FPGA itself produces great crisp signals, but at 3.3V not the 5V swing used for the Diablo drive. I think I have a fix for the outbound signal and can handle the inbound two signals with a voltage divider or zener diode.

At this point, I must get the register read/write and RAM read/write to work over USB, as that will be the key to the rest of the development.

Sunday, August 28, 2016

Steady work on building up board

XEROX ALTO - DIABLO DISK TOOL CREATION

I set up logic to display various bits of information on the four 7-segment displays on the fpga board. It will be in hexadecimal. Each byte I select will be displayed on the two rightmost positions, which leaves me with two open displays. I will put the head number on display 1 and the actual sector number as it is detected by the drive on the second display.

When I ran a check to test out my code, the Adept utility thought it had written and read the data from the RAM, but it always came back all zeroes. Lastly, regardless of what I tried to write to any register, I always got zero back.

I checked for shorts before powering up my level shifting driver role extension board, connected to the FPGA board. I have everything laid out but want to work while I am fresh tomorrow morning, as there is potential to blow chips or even the fpga board if I make mistakes here.

While I worked on those problems, I also collected VHDL code to build a VGA display, ascii text only, which I would use to display the results of the latest sector read or written by the tool. I will be integrating this into the module slowly over the coming days, with the goal of having a quick display of the current sector and key other information that can be read off a monitor.

Building up disk tool foundational logic

The Digital Game Museum has a policy that a board member must be in attendance on each Saturday, when we are open to the public. It was my turn to be there today. It was very quiet.

XEROX ALTO - DIABLO DISK TOOL CREATION

I rolled in the code from the Digilent reference implementations to allow PC users to read or load the DRAM on the fpga board, as well as writing or reading from eight registers I defined in the FPGA. These will be used to request transactions such as 'read a sector into the DRAM'.

That is all cleanly synthesizing, It does need to be tested just to verify that the PC can talk to the fpga board, and that stored information comes back as written.

It is my intent to test the extension board with the current hookup of the switches, buttons and LEDs then when I am sure that all the connectivity is correct, I can reassign these to display the registers and other system state of the tool.

I put in logic to drive the four digits of seven-segment displays, which will show selected information while the board is in operation. For example, it can display the current cylinder number, the current head and sector number, the current command, the response and the status of the last operation.


Saturday, August 27, 2016

Setting up to test the disk driver role board and starting on the fpga implementation

XEROX ALTO - DIABLO DISK TOOL CREATION

Today my copper plates arrived and I could finish up the construction of the driver role board. First up, however, was to test that the board I wired works properly. I whipped up some fpga code that would light the LEDs when various signals were high or low on input and that would emit a high output on a selected line.

Since I had 9 inputs but only 8 LEDs, I needed to use one of the pushbuttons to switch to the ninth input line. I need to generate outputs on 13 lines but only have eight slide switches on the board, so I used a second pushbutton to swap between the first 8 and the last five signals.

First up, I had to make sure my temporary fpga code was working correctly, before inserting the driver role board and testing it. That took a while to get all the signals for every device on the board working - DRAM, flash, VGA, PS/2, serial port, 7 Segment Displays, switches, LEDs, buttons, peripheral adapter signals, and the USB signals.

Now that it is working fine with the small extension board which allowed me to check the output pins and route an output to all the input ports, I am ready to wire up the extension board to power and do some testing at the end of the cable. I should see +5V on the output pins when I turn on each signal, and I should be able to detect ground and +5V as a 0 and 1 when I hook them onto the input pins.

It is late, so I will work on this over the weekend. I have an obligation on Saturday to be at the game museum, as we want a board member there every saturday but all my peers are on business trips or otherwise unavailable.

I will bring my computers and documents in order to integrate in the code that reads and writes to the onboard DRAM and implements my transactional control registers. These won't impact the testing of the cable at all, but will let me move ahead.




Thursday, August 25, 2016

Done wiring the driver role extension board, digging into the design of the logic

XEROX ALTO - DIABLO DISK TOOL CREATION

I received my chip sockets today and finalized the wiring of the driver role extension board. By lunchtime I was just completing a thorough connectivity and short test of everything before installing chips and wiring in the disk cable.

Soldering the 9 input and 13 output lines onto the board was tedious, but eventually I got the wires all inserted. For some reason, one of the input lines is missing, but I had verified it was wired on the cable a few days ago, so I probably taped it into the unused bunch. That adds yet another time-sucking activity, probing all the pairs to find the one that is connected to pin A.

With pin A's wire discovered and soldered down, it was time to bond all the grounds together and tie them to the board. A final test to ensure that no adjacent signal lines are shorting where I soldered the cable on, then it was time to figure out how to anchor the disk cable to the board.

I inserted all the chip, triple checked the pin assignments, polarities and voltage levels of all the level shifting circuits. Everything looks good, This needs +5V, +3.3V and ground power lines attached. I plan to put my copper ground planes on the bottom and top of the assembly and secure everything to finalize this, as soon as the plates arrive.

Board almost complete, waiting for power wires and ground planes
Cable to hook to Diablo disk drive and board to attach to FPGA
I had to begin the VHDL coding,with the sector and cylinder buffer transactions and basic transactions the first steps. This is because I can fully test these with the Adept utility before I add in any Diablo oriented logic or even hook up the extension board to the fpga.

I am still staring at the code, functionality and limitations of the various USB communications methods - essentially a remote block ram access, a remote DRAM access and some 'register' access to figure out the best way to build the system to handle both emulation and driver roles.

I am currently leaning to using just the 16MB of DRAM because it allows me to hold an entire disk cartridge in a easy to address format. Each sector, 532 bytes of data, will sit in 1024 bytes on the DRAM, an even power of two address. I will use five bits to select the 12 sectors (ignoring the wasted 4 sectors that this addressing selects. One bit for head, which has zero waste, and then 8 bits to specify cylinders 0 to 203, so again some waste.

It lets me cleanly control the top 8 address lines for cylinder number, the next line for head number, the following five lines for sector number, and then the bottom 10 bits are the byte number in the sector. No address multiplication, so a straightforward implementation, even if it is wasteful.

The 2,604,672 actual bytes of the virtual disk cartridge are sparsely stored in the 16,777,216 bytes of RAM. More than 84% empty but I have no use for the wasted RAM and this way it is easy to implement.

I will set up a special flag for each sector to show if the contents are invalid. That is, when I first start up in disk driver mode, until I read a particular sector, I have no idea what the contents of the sector will be. This flag will let me distinguish between an all zero sector and an 'undefined content' sector. It will only take up 4, 896 bits of distributed RAM, a teeny sliver of the available capacity on the FPGA chip.

Wednesday, August 24, 2016

Work on Diablo disk driver/emulator tool

Today is the day I spend with the 1401 restoration team at CHM, thus limited time for my own projects but I did move ahead a bit. At CHM, I replaced a set of brushes in a 729 tape drive, helped diagnose and fix a problem in the 1402 card reader,

XEROX ALTO - DIABLO DISK TOOL CREATION

I hooked up all the remaining wires on the board, lacking only the connections to the last, missing chip socket for it to be ready to have the disk cable soldered on. The sockets will be arriving tomorrow, so we will have a working extension board by end of week for certain.

The chips and my board for the emulator role have come in, but until I get the plug and shield I can't complete wiring up that side of the project.

I plan to add two sheets of insulation and then an upper and lower copper plate to help with signal integrity, given the discrete wire runs on the board. The copper sheets should arrive by Friday.

For simplicity, I will leverage the USB communications example projects provided by Digilent, which will allow me to easily load and fetch the contents of a RAM buffer on the fpga. The Xilinx Spartan 3E chip XC3S1200E on the Nexys2 board features 516,096 bits of block RAM.

The Block RAM on the fpga chip is enough to hold 32.256 words of Alto Diablo data, just over 121 sectors or about 5 cylinders. That is 2.5% of a disk cartridge.

The SDRAM on the Nexys2 board will hold more than seven full virtual disk cartridges, while we only need a cylinder buffer of 24 sectors and a single disk cartridge in RAM. I will leverage the Digilent Block RAM code to fetch and load the cylinder buffer.  Then, I will leverage the Digilent Memory code to fetch and load the virtual cartridge SDRAM.

Essentially I have to piece together a couple of reference project modules and some glue code to implement the transaction types I want for the tool. This allows me to use the Digilent supplied Adept utility right away, not having to complete any PC side code until it is convenient.