I've written Electronic Design Automation (EDA) software for semiconductors in numerous areas:
- physical design, from transistor level design and layout generation to chip-level placement and routing
- transistor level analysis and model generation
- logic synthesis and physical synthesis
- design rule checking and circuit extraction
- mask data preparation and scribe frame generation
- intellectual property (IP) management and tracking
This broad spectrum of EDA work contrasts with most developers, who work in one area their entire career. I know the tools that generate chips and understand the layouts that result.
Rates and case list are available on request.
GDS/GDSII/OASIS Design Data Review
If someone is using your patents or IP, I'll find it wherever it is. No chip is too large, no infringement is too small.
Modern integrated circuit design files can be over 100 gigabytes in size, with billions of polygons on dozens of layers. My knowledge of semiconductor processing and design styles allows me to work comfortably with these files, even when design rule specifications are missing.
Source Code Review/Algorithm Analysis
I've written well over a million lines of code (mostly C/C++) in my career and am experienced in navigating through large programs. I know EDA algorithms, how they are implemented, and how they change over time.
Almost invariably, your software development schedules slip. If your release dates cannot be moved, something has to give. Testing is often put at the end of the release cycle, so the temptation is to reduce testing and hope it doesn't hurt quality too much. A better idea is short-term software testing assistance.
Software Testing
As part of my own research work, I have developed a best-in-class white-box "test as you build" methodology for compute-intensive software. The goal is to test every line of code as it is compiled, but the methodology can be adapted to obtain core feature coverage with a robust regression test suite to ensure that bugs stay dead.
This methodology helps you isolate bugs and test fixes quickly. Unlike standard methods which require running the entire application, individual driver programs provide test setup, execution, and checking. A quarter million lines of code can be tested this way in minutes on a single processor core.
I can teach this methodology to your development team, show how best to apply it, and demonstrate how it will save them debug time. I can also develop a custom test framework for your project, either as the code is developed or as it approaches final release.
If your code does not have the visibility required for 100% statement coverage, or if you prefer a more conventional application-level testing system, I can develop driver scripts and output checking systems for you. I have tested applications that lacked a test-friendly architecture and have also refactored code to improve testability.
Software Debugging
If testing is well underway, or if you don't have staff to deal with a critical bug, or if a key developer leads suddenly, I can help. Finding the most difficult bugs is a specialty: memory leaks, dangling pointers, and memory corruption. It's not enough to know where leaked memory was allocated, or when memory is overwritten - it is necessary to know why, and to find all of the places where the problem can occur.
I am persistent enough to track down everything and focused enough to chase problems down in priority order. I can set problems aside and return to them easily. I've used both Purify and Valgrind, though I can debug without them if their performance overhead is too high to be practical.
I can be productive on day one - after writing (and debugging) 1,300,000 lines of code, I've seen it all.
Whether you are just starting a new software project or need an "extra boost" to get a project in development finished on time, I can help.
I've been a team member as well as project lead. I've gathered requirements, developed specifications for buy-in, architected large software systems, written the code, tested it, optimized it, fixed bugs, and written user documentation. In short, I've done it all.
Requirements Gathering
When I gather requirements for a software package, I try to gain an understanding of the uses for the software, not just ask for a simple list of features. The goal is to simplify and enhance users' daily work, not just meet their minimum needs.
The mask tooling software package I wrote for VLSI Technology became a competitive advantage for the company because it was not only less error-prone than manual reticle layout and mask data preparation, it was more powerful than anything that had ever been done before. I can give you a competitive advantage too.
Specification and Architecture Design
Knowing the requirements for a system is not the same as knowing how to build the system. After 1,300,000 lines of code, it does get a little easier. Tradeoffs between memory usage, CPU time, and code complexity become more apparent - usually I've done something similar already. Build vs. buy decisions can be explored knowedgeably.
My creativity, deep domain knowledge, and experience lead me to develop innovative methods when there is no obvious answer. This work often leads to patent applications; several of my patents have been granted as a result of my consulting work.
For example, when asked to develop a system to identify intellectual property (IP) blocks within integrated circuit design files, I used my background across the integrated circuit design and software development areas to create an advanced system now known as Smart Signatures. U.S. Patents #7,685,545 and #8,266,571 were granted for this work.
Code Writing
I take pride in the code I write. It is fully commented from day one, and comments are kept up to date as the code is modified. When maintaining code, I try to add comments if there are none. The comments are written to explain the purpose and function of the code - its prerequisites and results - not just trivial details that can easily be seen from the code itself.
Despite the care I take, I am very productive - on a typical day I write about 400 lines of code with comments. My code is written with an eye towards efficiency without obfuscating the meaning; if something could be optimized but would be more complex, the suggested rewrite is described in the block's comments for performance tuning as needed.
I write code to be enhanced as new features are added, with a clear separation of functionality to reduce unnecessary coupling between modules. My code is constantly refined and refactored as needed to improve readability or testability. Spaghetti belongs on a dinner plate, not in software.
Software Testing
The robust software testing methodologies I have developed will help improve your existing code too. I can teach the methods to your development team, set up test infrastructure, write test programs, or work within your existing testing methodology to help speed your code to release.
For more information, see Software Test and Debug Services.
Software Optimization
If your software isn't fast enough or uses too much memory, I can improve it. I've developed a number of strategies to improve software runtime or memory consumption. I take care to ensure that functionality is retained even as I turn big programs into smaller ones.
For more information, see Software Optimization Services.
Bug Fixing
Even if I didn't write the code, I can fix bugs in it. I always look at the context of the problem to ensure that bugs are fixed without degrading other parts of the system. I am thorough in testing and track down other places in the code where similar problems might occur due to code copying.
For more information, see Software Test and Debug Services.
Documentation Writing
I am an excellent technical writer, as can be seen from the essays on this Web site. I can write documentation at any level, from architectural descriptions to code overviews to users' manuals to applications notes. I can start from scratch or edit existing documentation. If it's not clear, I can fix it. If it's out of date, I can bring it up to date with the code.
If your software runs, but it is too slow or uses too much memory, you need optimization services. I can turn your big programs into smaller ones.
Too Much Time/Too Much Energy
Once upon a time in a land far, far away, computer clock speeds doubled every eighteen months. Every program got faster and faster, and every user was happy. The end.
This little fairy tale has come to an end in more ways than one. Program functionality has grown apace with processor speed, and processor clock speeds are no longer increasing due to the "power wall" - further increases in speed come at huge costs in power consumption.
The rise of mobile computing - smartphones and tablets - has raised another issue: faster code is necessary to keep the system running all day without recharging.
So despite decades of processor speed improvements, runtime optimization is still important. There are a number of ways, obvious or subtle, to improve the runtime of a program. Here are some examples, starting with ways that tend to yield the biggest "bang for the buck:"
- Look for inefficient loops that need O(n2) or worse (perhaps even exponential) runtime;
- Precompute results and move their computation out of loops;
- Store past results for reuse (caching);
- Use better data structures to reduce the need to perform expensive operations;
- Write special-purpose code for common cases;
- Compute approximate results rather than exact answers; and
- Rewrite modules to use more-efficient algorithms.
Each of these techniques has served me well at least once in the more than 1,300,000 lines of code I've written.
Runtime optimization often increases the complexity of the code. It is important not to optimize too early - "make it right before you make it fast." When you are ready to make it fast, I can help.
Too Much Memory
Once upon a time in a land far, far away, memory was free. Every program had all of the space it needed, and every user was happy. The end.
This little fairy tale is almost true - memory costs have continued to drop exponentially, and the amount of memory in the largest computer systems has continued to grow. However, there are always programs that bump up against practical limits on memory usage.
To minimize cost, embedded systems often have very little memory. Engineering design software usually runs on top-of-the-line hardware, but design of complex systems can require every byte of memory in the computer. Data analytics software typically works on huge unstructured data sets.
When I started writing software, even the biggest computer systems had memory measured in kilobytes or megabytes. Reducing memory consumption has been critical for most of my career, and I have a full bag of tricks to apply to reduce memory usage in your applications:
- Recompute results rather than store them;
- Eliminate rarely used data fields and data structures;
- Fold sparse data structures and lookup tables;
- Use custom memory management techniques; and
- Spill data to mass storage.
Of course, some of these methods increase runtime, so they too must be used judiciously. "Make it right, then make it small." It is even possible that a program could have both runtime and memory usage problems, so the best solution must be determined experimentally. My experience will help you reach this point quickly.
