LibreTimes

September 2, 2026 · Notes · LibreTimes

ISE TCAD 7.0 on Apple Silicon: Running a 2001 Semiconductor Package on a MacBook Air M1

How to bring up a twenty-year-old Unix TCAD package under emulation on an ARM Mac, drive it from Jupyter, and parse its data formats in Python

ISE TCAD 7.0 on Apple Silicon

Running a 2001 semiconductor package on a MacBook Air M1

The task sounded simple: complete a set of coursework labs on semiconductor
device modelling. The catch was that they run on a TCAD package older than most
of the students taking the course, built for Windows NT and Intel hardware —
while the machine at hand was an ARM MacBook.

Here is how it went, and every rake stepped on along the way. Everything below
was verified by actually running it, not by guessing.


What the package is

ISE TCAD 7.0 came from Integrated Systems Engineering AG in Zurich. Synopsys
acquired the company in 2004, and the product became Sentaurus TCAD — the tool
sitting in half the microelectronics labs in the world today.

The lineage is visible without squinting: the solver is still called DESSIS,
the data format is still DF-ISE, and modern Sentaurus manuals occasionally slip
and use the old program names. The 2001 package is a direct ancestor of the
current one.

The parts needed for the work:

ProgramPurposeInterface
meshmesh generation from a geometry descriptionconsole
dessissolves Poisson and continuity equationsconsole
dfisetoolscutlines, distributions along a lineconsole
mdrawgraphical structure editorX11
inspectplots: I-V curves, cutlines, waveformsX11
picasso, tecplot_ise2D and 3D field mapsX11

One detail matters more than any other: ISE 7.0 for Windows is Unix software
ported through Cygwin.
That explains the bundled X server, and it explains
most of the behaviour described below.


The setup

MacBook Air M1 (ARM64)
  └─ UTM 4.7.5, full x86 emulation
       └─ QEMU, i386 target
            └─ Windows XP SP3
                 ├─ ISE TCAD 7.0 (Cygwin port)
                 ├─ Labtam X-WinPro X server
                 └─ built-in Telnet Server

A hand-written Python telnet client connects from the Mac into the guest;
simulations are launched and results retrieved through it. Everything is driven
from Jupyter.

The virtual disk sits at about six gigabytes, and one gigabyte of RAM is plenty
for the guest.


Rake one: XP will not install

Windows setup hung dead on the very first screen — "Setup is inspecting your
computer's hardware configuration."

Looking at how UTM invokes QEMU:

-machine pc,vmport=off,i8042=off,hpet=off

i8042=off disables the PS/2 keyboard controller. Modern operating systems do
not need it — USB HID is enough — so UTM turns it off by default. But Windows
XP's NTDETECT probes for exactly that 8042 controller at startup, and without it
it stalls forever.

This is a known UTM issue, #3723.
The fix is re-enabling PS/2 in the VM settings; in the config file it is the
PS2Controller key. Once set, the flag disappears from the launch line and
setup proceeds normally.

A useful side effect: without a PS/2 controller the keyboard would not work in
text-mode setup either, and that stage needs Enter and F8.


Driving it from a terminal

Clicking through an emulated Windows desktop gets old fast; the goal was to
script the runs. XP Professional ships a Telnet Server for exactly this — nothing
to install:

sc config tlntsvr start= auto
net start tlntsvr
tlntadmn config sec=-NTLM +passwd

That third line is not optional. By default the server demands NTLM
authentication, which Unix clients do not speak, and logins fail with no useful
message.

The XP firewall also needs the port opened:

netsh firewall set portopening TCP 23 Telnet ENABLE

The system telnet client did not work

The macOS client simply goes quiet with this server: it connects and prints
nothing at all. Dumping the raw traffic showed the server dutifully sending
option negotiation and waiting for an answer:

FF FB 01   IAC WILL ECHO
FF FB 03   IAC WILL SUPPRESS-GO-AHEAD
FF FD 27   IAC DO NEW-ENVIRON
FF FD 1F   IAC DO NAWS
FF FD 00   IAC DO BINARY

Client and server never agreed. The fix was a small custom client: accept only
ECHO and SGA, advertise a VT100 terminal, politely decline everything else.

The second important detail: the next command is sent only after the >prompt appears, never on a timer. Otherwise a command lands in the middle of a
running simulation. dessis takes minutes, and without prompt synchronisation
the whole thing falls apart.

Third: output arrives in cp866 with ANSI cursor-positioning escapes that must be
stripped. Switching the server to stream mode helps:

tlntadmn config mode=stream

Rake two: a space in the path kills the program

The computational side worked immediately. The graphical tools, however,
behaved strangely: a window would flash up for a second and vanish. No error,
no log.

Capturing the output revealed it:

ls: C:\Documents: No such file or directory
ls: and: No such file or directory
ls: Settings\User\Desktop: No such file or directory

There it is. picasso is Unix software, and internally it shells out to lson the current directory without quoting the path. A path like
C:\Documents and Settings\...\Desktop\ splits on the spaces, the program
cannot read its working directory, and it exits silently.

Keep projects in a path with no spaces and no non-ASCII characters
C:\tcad\ works fine. The console tools mesh, dessis and dfisetools are
immune, since they receive filenames as arguments.


Rake three: windows launched over telnet never appear

The next oddity: the program is running, visible in the process list, happily
burning CPU — and there is no window anywhere on screen.

The cause is how Windows works: a process started from a telnet session lands in
a separate window station, and its windows are never drawn on the interactive
desktop.

There was a reasonable hope that X11 would sidestep this — the client talks to
the X server over TCP, and the window is created by the server, which lives in
the console session. The hypothesis was tested and did not hold: the window
still does not appear.

The working split ended up being:

  • over telnet — everything computational, which is console-only anyway;
  • from the Windows console itself — the graphical tools, via the Start menu.

The X server has to be started first, or the clients have nothing to connect to.


Reading the results: the DF-ISE format

ISE writes results in its own text-based format. Since it is text, the sensible
move is to parse it in Python and plot on the Mac with modern tooling. The format
has two non-obvious quirks.

Elements are defined by edges, not vertices

You would expect a triangle to be described by three vertices. In fact it is
three edges, and the edges reference the vertices:

Vertices (1957) { 0 0   0 0.2625   0.625 0.2625  ... }
Edges (3994)    { 0 1   1 2   2 3   3 0  ... }
Elements (2071) { 3 0 1 2 3    1 3 0    3 4 5 6 -2  ... }

The first number of an element is its type: 1 for a segment, 2 for a triangle,
3 for a quadrilateral. The rest are edge indices, and a negative index means
the edge is traversed backwards
. To recover a vertex ring you have to walk the
edges and stitch them together.

Fields may be stored in pieces

For a simple device a field is one array covering the whole mesh. For a structure
with several regions it is one block per region:

Dataset ("ElectrostaticPotential") {
  validity = [ "S10" ]
  Values (428) { ... }
}

In a fourteen-region transistor each field is split across eleven such blocks,
and they have to be merged: values inside a block follow ascending global vertex
indices of that region.


Plotting

The package's native visualiser draws fields as discrete colour bands running
blue through green to red, with a thin black device outline. One convention is
unusual: the Y axis points downward — device cross-sections are drawn that
way so the top electrode appears on top.

Reproducing this in Plotly is straightforward. The subtlety is that the mesh is
unstructured, so the field must first be interpolated onto a regular grid and
masked against the original triangulation — otherwise the fill spills outside
the device boundary.

Do not force an equal aspect ratio on the axes: for a transistor fifteen microns
long and two microns deep that stretches the figure across a sea of blank space.
Compute the figure height from the device's aspect ratio instead.


How fast it actually runs

Measurements on a single emulated core of an M1:

TaskNodesTime
2D diode, mesh generation1620.5 s
2D diode, ramp to 4 V16233 s
2D transistor, two ramps199416 min
3D diode, ramp to 4 V471124 min
Transistor in a circuit, 4 ms transient802~35 min

The conclusion was unexpected: worries about emulation being too slow did not
materialise.
Two-dimensional problems finish in seconds. The bottlenecks are
3D and transient analysis, and even those stay under half an hour — slow enough
to be annoying, fast enough to work with.


What came out of it

A fully working chain: simulations launch from Jupyter with a single call,
results are pulled back to the Mac automatically, and plots are produced with
modern tooling. The 2001 package itself is left exactly as it was — nothing was
patched or modified inside it.

Generalisations worth carrying beyond this particular package:

  1. Old operating systems need old controllers. Disabling PS/2 in the name of
    modernity breaks anything older than Windows Vista.
  2. Unix software on Windows hates spaces in paths — especially when it shells
    out to command-line utilities internally.
  3. GUIs cannot be launched over telnet. Split the console and graphical
    halves of the workflow.
  4. Synchronise on the prompt, not on a timer. It is the only reliable way to
    drive long-running jobs through a network shell.
  5. Text formats are a gift. As long as the data is text you can always read
    it with your own tools, even when the native visualiser refuses to start.

That last point turned out to be the most valuable one: a custom parser removed
any dependency on whether the graphics worked inside the virtual machine at all.


Tooling written along the way

  • xp.py — telnet client with option negotiation, prompt synchronisation and
    transcoding; also retrieves files from the guest
  • put.py — uploads text files into the guest line by line, no shared folders
    required
  • dfise.py — DF-ISE parser: mesh, edge-defined elements, per-region fields
  • viz.py — Plotly rendering in the style of the original package
  • five Jupyter notebooks, one per lab assignment
1

No comments yet

Be the first to share your thoughts.