AMITool is a Haskell package, which provides the essential tools necessary, in order to create IBIS-AMI models using Haskell.
Authors: David Banas
NOTE) This package is, currently, in a VERY premature and incomplete state. I only set up this Wiki page so that those interested in participating in this project's development would have a central focal point for documentation, communication, etc. This package is really NOT ready for prime time, yet.
NOTE) This package is currently only supported on Linux.
If you haven't already, install the Haskell Platform on your system.
(This is necessary, because the shared object library produced by this package needs to dynamically link to certain standard Haskell libraries, at run time. I'm working on a statically linked version of this package, which won't require this step. Please, stay tuned.)
Download the source tarball and extract it:
$ tar xzf amitool-v0.1.tgz
Move into the newly created directory, and build the project:
$ cd amitool-v0.1 $ make
If the make succeeds, you'll find the following output files in the directory:
- libami.so - This is the shared object library plug-in, which contains your AMI model. It will be dynamically loaded, at run time, by your EDA tool when simulating.
- ami_test - This is an example C program, which will attempt to load libami.so and call its AMI_Init and AMI_Close functions, as a check on correct compilation. That is, for this simple test, it functions as a stand-in for the EDA tool.
You can quickly verify correct compilation and/or system infrastructural integrity by executing the following command:
$ ./ami_test test.ami
The source code of this package has been arranged such that, presumably, all you have to do, in order to model your own device, is edit the following section of the ExmplUsrModel.hs file, and re-run make:
-- Change the line, below, as follows: -- - Change "testAMI" to the root name of your AMI parameter tree. -- - Change "Mode" to the name you've given to the filter mode selection parameter. = case getAmiExp amiTree ["testAMI", "Mode"] of -- Change the `Vals' lines, below, to reflect your possible values of filter -- mode, and the corresponding action to be taken in that mode, adding/deleting -- lines as necessary. Just (Vals ["0"]) -> impulse -- Bypassed. Just (Vals ["1"]) -> fir (lpf 0.5 2) impulse -- 2nd order FIR LPF w/ cutoff at 1/2 Nyquist -- That's it; no more changes are required.
2.1 Source Files
- AMIParse.hs - Haskell source code for parsing an AMI parameter string
- AMIModel.hs - Haskell source code for generic implementation of AMI functions
- ExmplUsrModel.hs - Haskell source code for model specific behavior
- ami_model.c - C source code for implementation of dynamic loading interface, as well as setup/tear-down of Haskell run-time system
- ami_test.c - example C source code showing how to dynamically load a shared object library and call the AMI functions
2.2 Public interface
2.2.1 New data types
The AMIParse module defines a new type alias, AmiToken, and a new abstract data type, AmiExp, as follows:
type AmiToken = (String, AmiExp)
data AmiExp = Vals [String] | Tokens [AmiToken]
Note that, taken together, the two new data items, above, form a recursive structure. This helps shorten the code that parses an AMI parameter string, which itself is recursive in nature.
2.2.2 Supporting functions
The AMIParse module exposes the following public functions:
- : Parser AmiToken
- Parses an AMI parameter string, returning an AmiToken.
- : AmiToken -> [String] -> Maybe AmiExp
- Scans through an AmiToken (presumably, returned by amiToken) for a particular requested value. For example:
getAmiExp (amiToken "(rootName (Mode 2))") ["rootName", "Mode"] = Just (Vals "2")
3 Extended Testing
In order to perform more extensive testing on either the default libami.so or your own customized version of this file, you can use the AMI Toolkit from SiSoft, Inc.
You'll find example input to thier IBIS_AMI_test program in the test.ami.csv file, included in this package.
Output from the program is written to test_out.ami.csv.
See the documentation, which comes with their tool kit, for more details.
The command to invoke is:
IBIS_AMI_test -i test.ami.csv -f libami.so
This page serves as the primary documentation for this package.
5 Related work
- IBIS Advanced Technology Modeling Workgroup
- In particular, see the Tools and Work Archive sections.
In progress. Meanwhile, I will serve as e-mail reflectron for all interested parties. Send me your comments, and I will disseminate them to the group.
Alternatively, if you feel your comments are relevant to the ATM modeling community in general, use their mailing list, instead.
To sign up for, or view the archives of the ATM mailing list, visit their page on Freelists.org.
7.1 Why Haskell?
Because the Haskell code to parse an AMI parameter string looks like this:
amiToken = do skipJunk symbol (char '(') lbl <- symbol (identifier <?> "label") do tokens <- try (symbol (many1 amiToken)) symbol (char ')') return (lbl, Tokens tokens) <|> do vals <- sepBy (quotedVal <|> many (noneOf " )")) (char ' ') symbol (char ')') return (lbl, Vals vals)
And for the following reasons:
- It is a modern, strongly typed, functional language, which means we:
- can think at a higher level of abstraction when coding,
- are alerted to more of our programming errors at compile time,
- don't have to do as much memory housekeeping, and
- get to write less code.
- It has a very good compiler, so we don't have the same deployability and/or performance issues we have with interpreted languages, such as Python.
7.2 Will we get the performance we need out of AMI_Getwave if it's written in Haskell?
Not yet. The most recent source code submission to GitHub does include the AMI_Getwave function, but its performance is 10x worse than the equivalent C code. I'm investigating...
7.3 Okay, I'm interested; how do I quickly learn Haskell?
Grab a copy of this book, and work through the chapters, doing the problems at the end of each. I will make my own answers to these problems available to anyone, whom asks.
7.4 I've made it through the book, above, but it's rather academic; how do I do real practical things with Haskell?
Grab a copy of this book, and keep it by your side always. (I sleep with mine. ;-) )
8 Model Comparison & Correlation
8.1 AMI_Init Impulse Response
The following plot shows a comparison of the transfer functions of the C and Haskell models of a Rx CTLE equalizer to a HSpice AC sweep of the actual circuit. In order to generate the C and Haskell transfer functions, below, I invoked each model, in turn, using the IBIS_AMI_test tool provided by SiSoft, Inc., using an ideal impulse (i.e. - [0, 1, 0, ..., 0]) as input, and took a FFT of the returned waveform. The configuration files given to the `-i' option were identical, except for root name. And both models used the same set of `fract/pole' data to formualte their impulse responses. The sample interval is 25 ps (i.e. - 40 GHz sample rate), and the vectors are 128 elements long. The vertical cursor has been positioned to the frequency at which the error in the Haskell model magnitude, relative to the SPICE model, first reaches 3 dB.
Note the excellent agreement in spectral magnitude, out past 16 GHz, between the Haskell model and the HSpice AC sweep.
The spurs in the C model transfer function at 5, 10, and 15 GHz are due to a well understood bug in the C code, which is easy to fix.
The flipped up tail near the end of the Haskell model spectral magnitude curve is reminiscent of aliasing, but I'm puzzled as to why the same effect is not present in the C model.
Finally, it is necessary to offset the HSpice results by -36 dB, in order to match the two models. I don't understand where this normalization error is creeping into the process.