<> <> The Rosemary User Interface Introduction It has been noted that using Rosemary involves invoking a random collection of commands, command files, and procedures. This document attempts to describe them. It is divided into two parts: a description of the individual steps available, and some recipes for popular operations. Steps Getting Rosemary Started The .load file Rosemary.Load will get both the simulator and the translator loaded and started. The commands that invoke the Translate, RoseUpdate and RoseTranslate, will invoke Rosemary.Load if the translator hasn't bee started yet. The .load file RoseFromStructure.Load gets you ready to use RoseFromStructure, which makes Rosemary models from structural description files. Using the Translator The command RoseTranslate invokes the translator. It takes as arguments the names of modules to translate. The source will be looked for in the current working directory under the name moduleName.rose; a variety of output files will be produced, including (but not at all limited to) moduleName.mesa, which is ready for the compiler. The command RoseUpdate also takes a list of module names. It tries to do whatever is necessary to ensure that those modules are ready to use. This may entail translating them, compiling them, and translating or compiling some of the modules they reference. Unfortunately, RoseUpdate is somewhat broken, and does not properly see all the dependencies; if this bug bites you, ask a Wizard to tell you the workaround. Using the Simulator A first thing you must do is get your circuit model loaded and started. For each module it translates, the translator produces a command file (moduleName.roseLoad) that gets that module, and all it depends on, loaded and started. Thus, to get your entire design model registered, invoke rootModuleName.roseLoad. Another first thing you must do is call RoseCreate.CreateSim to create a Simulation --- this is the root of the data structure that keeps track of a particular simulation. CreateSim takes one argument, which says whether you plan to work on the steady state or the initialization of your circuit. Once you have a simulation, and have your model registered, you then create an instance of it in the simulator's data structures. One of three procedures is used to do this: RoseCreate.CreateTopCell, RoseCreate.WrapTop, or RoseCreate.CreateTest. CreateTopCell is the simplest. To use it, the root cell of your design must have an empty interface. Give to CreateTopCell an instance name and cell type name for the root cell. Give it also the simulation, and a way to decide when to stop expanding your circuit. WrapTop is like CreateTopCell, but it is willing to deal with a root cell type that has a non-empty interface. What it does about this is to cons up a new cell type, with an empty interface, that contains nothing but an instance of the given cell type. That's a bit of a lie, because WrapTop is also willing to put a clock generator in that invented top-level cell type. If the clocks argument to WrapTop is not NIL, it should be a connection list (as found between (non-inclusive) the square brackets in a cell instantiation) that tells how to hook up the clock generator. CreateTest is used when you want to invoke a test procedure. It will create a top-level cell that contains a tester and a testee. When instantiating a circuit model for simulation, Rosemary sometimes has some choices. If a cell type has both a behavioral model and a structural one, Rosemary has the choice of treating instances of that cell type as leaves or expanding them. A RoseCreate.ExpandDeciderClosure is for making that decision (when there is a choice). It gets to look at each cell instance, and decide whether to make it a leaf or expand it. You can give to the create procedures a NIL ExpandDeciderClosure; this allows them to do as they please. You can give RoseCreate.expandFirst or RoseCreate.leafFirst, which always prefer respectively expansion and leafing. RoseCreate.DecideFromFile makes an ExpandDeciderClosure that decides according to explicit instructions given in a file. Once the simulation data structure is created, you can create a viewers-oriented user interface to it by invoking RoseDisplayOps.MakeInterface. If you are preparing to use to use a test procedure, this is optional; otherwise, there's no other (easy) way to make your simulation do anything! To use a test procedure, invoke RoseRun.Test. Give it the simulation, and a record containing flags you can set to cause it to pause before or after each evaluation step. Capturing Structure To produce a structural description from a Rosemary model, use RoseCapture.CaptureDesign (after getting your Rosemary model registered). CaptureDesign takes the name of the root cell type, a name for the design, and a remote directory to aim the design df-file at. It will generate, in the current working directory, a df-file named designName-Str.df, which points at the remote directory, and includes a schematic file for each cell type reached from the root. Using Structure To produce Rosemary models from structural descriptions, use RoseFromStructure. First, invoke RoseFromStructure.Load. You must read in the structural description. Use CompareRead.ReadDesign. It takes the name of a DF-file for a structural description, and a flag saying whether to hold onto things it doesn't understand (set this flag TRUE). RoseFromStructure has two procedures of interest to users. MergeFromStructure takes a structural description of a design, and for every cell type defined therein, but not registered with Rosemary, it registers that cell type with Rosemary. DefineCellType takes a single cell type from a structural description and registers it with Rosemary, regardless of whether it was previously registered. In structural descriptions, a transistor has a ratio (length/width), which is a real number. In Rosemary, transistors have strengths, which come from a discrete set. Both MergeFromStructure and DefineCellType take a datum, of TYPE Thresholds, which describes how to decide what strength to assign a transistor, given its ratio, and flavoring (n vs. p & enhancement vs. depletion). The procedure SimpleThresholds creates a Thresholds that will decide on one of three strengths, making the assumption that p transistors are more resistive than n by a certain constant factor, and similarly for depeletion vs. enhancement. Recipes Examples in Rosemary.DF In Rosemary.DF, in the section labelled "test cases", you will find some command files used by the implementor for testing. You may find them illuminating. Getting Rosemary Started All the recipes presented below will assume you already have the basic Rosemary system loaded and started. Here's how to do that: % Rosemary Using the Translator Suppose the .rose file containing the top-level cell of your design is named Foo.Rose. Say % RoseUpdate Foo Making a Simulation to Drive by Hand Suppose your top-level cell type is named FooCell (still in module Foo). If you don't care to specify how to expand (because, e.g., there is only one way possible, or any expansion is OK), say % @Foo.roseLoad % _ &sim _ RoseCreate.CreateSim[TRUE] % _ RoseCreate.WrapTop[rootName: "FooTest", typeName: "FooCell", decider: NIL, sim: &sim] % _ RoseDisplayOps.MakeInterface[&sim] If you want to specify an expansion, change "decider: NIL" to decider: RoseCreate.DecideFromFile["FooTest.Expand"] The file FooTest.Expand should contain your specification of how to expand. Here's an example: <> <> <<>> ("FooTest" E (clkGen) (fooCell E (SRWC0 E (First E (Inv E) (Pass L)) (second E (Inv E) (Pass L))) (SRWC1 E (First E (Inv E) (Pass E)) (second L (Inv E) (Pass E))) (SRWC2 E (First L (Inv L) (Pass L)) (second E (Inv L) (Pass L))) (SRWC3 E (First L (Inv L) (Pass L)) (second L (Inv L) (Pass L))) (SRWC4 E (First E (Inv L) (Pass E)) (second L (Inv E) (Pass E))) If you want a clock generator (generating clocks named, e.g., phi1 and phi2), add to the call on RoseCreate.WrapTop the argument clocks: "phi1, phi2" Using Test Procedures (with Viewers interface) If you want to use a test procedure (named, e.g., TestProc1), and have the graphical interface, say % @Foo.roseLoad % _ &sim _ RoseCreate.CreateSim[TRUE] % _ RoseCreate.CreateTest[rootName: "FooTest", typeName: "FooCell", testName: "TestProc1", decider: RoseCreate.DecideFromFile["FooTest.expand"], sim: &tsim] % _ RoseDisplayOps.MakeInterface[&sim] Here's an example of a .expand file appropriate for this use: <> <> <<>> ("FooTest" E (tester) (testee E (SRWC0 E (First E (Inv E) (Pass L)) (second E (Inv E) (Pass L))) (SRWC1 E (First E (Inv E) (Pass E)) (second L (Inv E) (Pass E))) (SRWC2 E (First L (Inv L) (Pass L)) (second E (Inv L) (Pass L))) (SRWC3 E (First L (Inv L) (Pass L)) (second L (Inv L) (Pass L))) (SRWC4 E (First E (Inv L) (Pass E)) (second L (Inv E) (Pass E))) Using Test Procedures (without Viewers interface) If you just want to invoke the test procedure, without poking at anything by hand, say % @Foo.roseLoad % _ &sim _ RoseCreate.CreateSim[TRUE] % _ RoseCreate.CreateTest[rootName: "FooTest", typeName: "FooCell", testName: "TestProc1", decider: RoseCreate.DecideFromFile["FooTest.expand"], sim: &tsim] % _ RoseRun.Test[sim: &sim, parms: NEW [RoseRun.TestParmsRep _ [FALSE, FALSE]]] Capturing Structure Say % @Foo.roseLoad % _ RoseCapture.CaptureDesign[directory: "[Ivy]DesignProject>", designName: "Foo", topCellTypeName: "FooCell"] % SModel Foo-Str.DF Using Structure Say % RoseFromStructure % _ &design _ CompareRead.ReadDesign[dfName: "[Ivy]DesignProject>Foo-Str.DF", keepAll: TRUE] % _ &design.name _ "Foo" % _ RoseFromStructure.MergeFromStructure[design: &design, thresholds: RoseFromStructure.SimpleThresholds[]] % _ &sim _ RoseCreate.CreateSim[TRUE] % _ RoseCreate.WrapTop[rootName: "FooTest", typeName: "FooCell", decider: NIL, sim: &sim] % _ RoseDisplayOps.MakeInterface[&sim]