Hey Guy,
This sounds like a very cool project. FWIW I commissioned RTL work in
Verilog using Upwork, with very good results. I'm an embedded C and C++ man
myself and can (mostly) read Verilog but couldn't have delivered that code
in a reasonable timeframe. Here's the husband and wife RTL team I worked
with:
https://www.upwork.com/freelancers/~01453f295752b85d81. I hope
they're still around, haha.
I also found the Wavedrom tool super useful in creating timing diagrams:
https://wavedrom.com/
Good luck with your emulator!
--
Anders Nelson
www.andersknelson.com
On Thu, Mar 14, 2024 at 3:55 AM Guy Sotomayor via cctalk <
cctalk(a)classiccmp.org> wrote:
Hi,
I just wanted to provide a bit of a progress report on the SMD/ESDI
emulator project.
Now that I'm retired I have a bit more time to actually work on it.
Previously I was just doing a bunch of research and writing notes on the
design. I now have a solid design and I'm starting with the
implementation.
I'm going to list some of the design goals and then sketch out a few of
the major issues and how they're being addressed.
Goals:
* Emulate any drive geometry
* Emulate a drive's performance characteristics
* Work across different interface types
* Fully built emulator cost below $500
Major Issues:
* SMD/ESDI have head switch times < 10 microseconds (basically the
time it takes for the read amplifiers to settle on a "real" drive).
Solving this issue drives the majority of the design
* Address marks on a "real" drive are implemented by writing a DC
signal on the track and the read circuitry detects that and
generates the address mark signal
When looking at the specifications for SMD and ESDI disks there aren't
really a lot of difference in how the drive behaves. The interfaces
differ in detail but in reality the differences are pretty minor. So
the current design should allow for 95+% code sharing between SMD and
ESDI emulators.
To solve the head switch performance, it is necessary to have an entire
cylinder in some sort of RAM. This allows for very fast head switch
times (e.g. the selected head just addresses a particular portion of the
RAM). However, this means that loading a cylinder (which in some cases
could be as much as 1MB) could take considerable time. It will take
even longer if some of the tracks in the cylinder are "dirty" due to
them having being written to prior to the seek.
Since I want the emulator to be able to faithfully emulate drives in all
respects, the limiting factor is the cylinder-to-cylinder seek time
(e.g. moving from one cylinder to another cylinder that is adjacent).
This is typically in the 4-8ms range. So doing the math, one must move
1MB in 4ms (that turns out to be ~250MB/sec of bandwidth...using 32-bit
transfers, this means over 60M transfers/sec).
The above implies that the cylinder RAM and where the storage holding
the cylinders of the image must be capable of at least 60M transfers/sec
between them. This is going to involve a complex FPGA that is able to
have large internal RAMs and a direct connection to some sort of DRAM to
hold the full image. I've chosen to use a SOM (System-On-Module)
version of the Xilinx Zynq 7020. This has dual 32-bit ARM cores (plus a
whole bunch of peripherals), 32-bit DDR3 memory interface, plus a fairly
large FPGA with enough block RAM to contain the maximum cylinder. The
calculations I've done should allow a new cylinder to be loaded from
DRAM into the cylinder RAM in 4-8ms (I think with a few tricks I can
keep it in the lower range).
I've looked a quite a few Zynq SOMs (and have acquired quite a few for
evaluation purposes). I finally found one that's ~$200 (most of the
others are in the $400-$1000+ range). This SOM brings out most of the
Zynq's I/Os (94 I/Os) in addition to having ethernet, USB, serial, SD
card, etc. as well as 1GB of 32-bit DDR3 DRAM. It also runs Linux which
means that developing the SW is fairly straight forward.
The next issue was how to emulate address marks. The emulated drive
will have a bit clock which is necessary for clocking out the data when
reading (or out when writing). The bit clock is always running (just
like a "real" drive when spinning). That will drive a counter (which
represents which bit is under the emulated "head"), that counter (along
with the head number) will be used to address the block RAM. The
counter is always running, so as to emulate the spinning disk. The
address marks are emulated by having a series of comparators (one for
each possible sector). They compare the bit counter with the value
associated with the comparator, if there's a match then that signals an
address mark. It's bit more complicated because writing address marks
(in the case of soft-sectors) has to be dealt with.
The emulator is composed of 4 major components:
1. Emulator application plus some utilities
I'm currently writing all of this code...since I'd been a SW
engineer for 50+ years, this is all "production" quality code and is
extremely well documented...still a ways to go.
2. Linux device driver which provides the interface between the
emulator application and the emulator HW
I haven't started on the driver yet but it should be fairly straight
forward as it really only provides an interface to the emulator HW
to the emulator application
3. Emulator HW RTL
I haven't started on this other than to do some basic blocks of
what's here. It mainly is the cylinder RAM, serdes (I *may* be able
to finesse this by having 32-bits on the AXI bus and 1 bit on the
interface side...a nice feature of the block RAM), address mark
logic, bit counter and some command decode/handling (it'll handle
the seek command all in the RTL...everything else will be handled by
the application.
4. Interface board
This should be a fairly simple board. It's a carrier for the SOM,
3.3v-to-5v level shifters, interface circuits for SMD or ESDI (they
use different interface ICs) and the interface to the cable.
I'm starting with SMD just to make the board layout easier (I can just
use 0.1" headers for interface cabling). I also have an SMD disk
exerciser that will make it easier to make sure it's working properly.
The idea is that once I have an SMD working reasonably well, I'll start
on ESDI.
Interacting with the emulator application can be any of the following:
* config file: indicates various emulator startup options including
which image (if any) to "mount" initially
* command line: same as the config file
* emulator utilities: these are mainly allow for changing which image
is mounted, changing write protect status, querying state of
emulator, etc. The utilities can be used locally by logging into to
Linux running on the Zynq 7020 or by using "host" versions if the
emulator is connected to a network via ethernet.
One of the key utilities is creating an "empty" (that is all tracks
contain all 0's) image. The image format has been finalized. It allows
for almost any geometry of disk (up to 32 heads and up to 65536
cylinders). The main restriction is the 1GB of DRAM on the Zynq 7020
SOM. I expect in reality that the largest drive that can be emulated
will be ~600-700MB due to DRAM.
I plan on providing some standardized "templates" (e.g. they'll describe
actual drive geometries and seek performance tables) so creating new
images won't be too onerous.
I'll be putting all of the source, RTL and board files on github under a
BSD license once I get further along.
--
TTFN - Guy