Docsity
Docsity

Prepare for your exams
Prepare for your exams

Study with the several resources on Docsity


Earn points to download
Earn points to download

Earn points by helping other students or get them with a premium plan


Guidelines and tips
Guidelines and tips

The SIM Software Package - Computer Architecture | CSE 420, Study Guides, Projects, Research of Computer Architecture and Organization

Material Type: Project; Class: Computer Architecture; Subject: Computer Science & Engineering; University: Michigan State University; Term: Unknown 2003;

Typology: Study Guides, Projects, Research

Pre 2010

Uploaded on 07/28/2009

koofers-user-xj0
koofers-user-xj0 🇺🇸

10 documents

1 / 36

Toggle sidebar

Related documents


Partial preview of the text

Download The SIM Software Package - Computer Architecture | CSE 420 and more Study Guides, Projects, Research Computer Architecture and Organization in PDF only on Docsity! THE SIM SOFTWARE PACKAGE Sixth Edition--C++ Version Professor Richard J. Reid Department of Computer Science and Engineering Michigan State University E. Lansing, MI 48824 January 2003 Table of Contents PREFACE 1 0. Introduction 1 0.1. Recent Changes 1 Chapter 1 GETTING STARTED WITH SIMULATION 2 1. Getting Started 2 1.1. Basic How To (Do a Simulation) 4 Chapter 2 INTRODUCTION TO SIM 5 2. Sim 5 2.1. Sim.h 5 Chapter 3 SIM SCHEMATIC DESCRIPTORS 6 3. Schematics 6 3.1. Hierarchy 7 3.2. Schmtc.h 7 Chapter 4 SIGNALS IN SIM 8 4. Signals 8 4.1. Connection Ordering 9 4.2. Signal.h 10 Chapter 5 HIERARCHICAL MODULES 13 Chapter 6 SIM COMMAND LINE 15 Chapter 7 SIM INTERACTIVE CONTROL 16 Chapter 8 SIM IMPLEMENTATION 18 8.1. Extensions 18 8.2. Source Av ailability 18 8.3. Bugs 18 Chapter 9 SIMULATION RUN-TIME MODEL 19 -2- Chapter 1: GETTING STARTED WITH SIMULATION 1. Getting Started Simulation involves working with models. Models are developed which describe the structure and behavior of real and/or abstract entities that exist, or are being contemplated, in some primary domain. The performance of this model is then examined in some secondary domain. In our case here, we will provide a textual description (model) of a digital network using the C++ language. This description will reference a C++ library that is pro- vided, and the resulting executable computer program (secondary domain) simex will provide an interactive simu- lation that can be examined for specific performance properties. For example, if it’s a computer model, does it execute instructions correctly? Time deserves an early (and probably often) mention when dealing with simulation. Invariably, the system being simulated consists of components that are in simultaneous operation. A simulation will have very low fidelity if we model this simultaneity of operation by getting to the computations associated with multiple components as- soon-as-we-can depending on the speed of the processor that does the computing associated with the simulation. To get around the finite time required for the simulation computer to process the actions of each of the compo- nents that are actually in simultaneous operation, it is essential that the two times, system model time and the actual computation time, be decoupled. The computer doing the simulation runs in real (wall clock) time, and there is a separate time (non-real) that is kept for the system being simulated. The system time advances in discrete steps as dictated by the occurrence of events in the system model. When- ev er any event occurs in the system (a logical signal changing value, for instance), we freeze the system time at the time of that change until we are able to carry out all the computations for components directly affected by that change. After those computations are completed, the system time can be advanced to the next time at which any event occurs. This freeze/compute/advance scheme of time control allows an accurate evaluation of system models. Before getting to the many details of modeling and simulation, let’s work a simple example. Consider the half-adder shown in Figure 1.1. Sum Y X Carry Figure 1.1. Half-Adder Digital Network This is a network that is commonly developed in an introductory digital logic course and is used frequently throughout computer design. This figure only shows the half-adder as an isolated instance. Any application of the network would always have sources for the excitation signals and destinations for the network outputs. In simulation we will want these inputs and outputs connected in order to examine the network behavior. Figure 1.2 shows the half-adder in a test fixture that will allow validation of the network functionality. -3- 1 0 1 0 X Sum Y Carry Figure 1.2. Half-Adder in a Test Fixture Switches are connected to the network inputs to provide excitations of logical ones and zeros. The network out- puts are routed to logic-value indicator-probes to allow display of the of the output values. To complete the model of the network for simulation we must further capture and express the graphical schematic information from Figure 1.2. The following text is a description of the model as a C++ program. This form is called a netlist. #include <Sim.h> void simnet() { Signal X, Y, Sum, Carry; Switch ( "1a", X, ’x’); Xor ( "1b", ( X, Y ), Sum ); Probe ( "1c", Sum); Switch ( "1a", Y, ’y’); And ( "2b", ( X, Y ), Carry ); Probe ( "2c", Carry); } Components are instantiated by calls to C++ functions of the proper name: Switch, And, Xor, etc. The first argu- ment in the call to a function is the graphical cell designation. This two-character ASCII string indicates the component’s row and column placement on the schematic. The Switch’s are positioned in cell 1a (row "1", col- umn a"), the Xor and And in 1b and 2b respectively and the Probe’s in two row positions of the third column, 1c and 2c. The text of the netlist above has been laid out to mimic the placement of the components in Figure 1.2, but the order and placement of the entries in the netlist is generally arbitrary. That is, the netlist: #include <Sim.h> void simnet() { Signal X, Y, Sum, Carry; Probe ( "1c", Sum); Probe ( "2c", Carry); Switch ( "1a", X, ’x’); Xor ( "1b", ( Y, X), Sum ); Switch ( "1a", Y, ’y’); And ( "2b", ( Y, X), Carry ); } contains the same information and is equivalent. Either netlist above, when processed by sim would result in the on-screen display shown in Figure 1.3. -4- Figure 1.3. Sim Display of Half-Adder Network The labels in the upper left of the Switch boxes indicate the keyboard key that toggles the Switch values; x and y keyboard keys for the X and Y variables, respectively. 1.1. Basic How To (Do a Simulation) The simplest steps required to do a simulation are as follows: 1. Extend the network of interest with the addition of the necessary excitation elements: Switches, Pulsers, Clocks, etc. 2. Add the desired instrumentation to display the results: Probes. 3. Organize the network elements along with the added excitation and display elements in the desired schematic relationships. 4. Create a netlist as an ordinary C++ function module using a text editor. 5. Use sim with the command: sim netlist.c The naming of the file netlist.c is arbitrary, but it must contain the function simnet(). Simnet can call any other functions desired. 6. Execute the resulting program using: simex 7. Interact with the network simulation as desired using the keyboard and mouse. When developing more complicated systems for simulation, a common additional step is the organization of an hierarchy of modules. Modules can be defined in terms of primitive components, or other defined modules, and used in the same way primitive components have been used above. Hierarchical modules are covered in a later section of these notes. -7- 3.1. Hierarchy For simulation models including more than a few gates, it is desirable to be able to form hierarchical modules that may be used directly as model components. As an example consider the following HalfAdder module that is defined in terms of primitive Xor and And gates. void HalfAdder ( const SD & sd, const Signals & in, const Signals & out ) { Module ( sd, in, out ); // Module display at current schematic level Xor ( SD ( sd, "1a" ), in, out[1] ); // Nested <Schematic Descriptor> And ( SD ( sd, "2a" ), in, out[0] ); // Nested <Schematic Descriptor> } The above definition allows the subsequent use of the module in a manner similar to the use of primitive compo- nents, such as: HalfAdder ( "1b", ( x, y ), ( carry, sum ) ); // Module usage 3.2. Schmtc.h /* Schematic.h 12-11-02 */ #ifndef _SCHEMATIC_H #define _SCHEMATIC_H class SD { public: int graphicLevel; char * graphicPosition, * decal; ˜SD(); SD(); SD ( const SD & ); SD( char * graphicPos, char * decal = 0 ); SD( const SD &, char * graphicPos, char * decal = 0 ); SD operator , ( char * decal ) const; }; typedef SD SchematicDescriptor; #endif /* ifndef _SCHEMATIC_H */ -8- Chapter 4: SIGNALS IN SIM 4. Signals Signals are defined types used to make connections, and to provide simulation-time communication-values between components. Signals are defined during the network construction phase using C++ type declarations. All Signal declarations yield vectors. The default vector length is one. A simple declaration such as: Signal x; defines the Signal x, and gives it (via the action of the constructor for Signal), as a side effect of the declaration, a global, simulation-runtime, variable index. It is this index value, that each run-time, evaluation-component receives indirectly through its argument. The evaluation-component uses this index value to access the corre- sponding run-time variable that will be set (for output connections) or received (for input connections). Other forms of declarations are also defined, including: Signal w(4); // A vector of signals with 4 components. Signal x(3, "x"); // A 3 element vector, with the name "x" assigned. This second form, with the signal name assigned so that it will carry through to simulation time, is quite desir- able, because it allows schematic-display labeling of a signal line with a signal’s name. A macro Sig is defined to make it more convenient to supply variable names that will be carried forward to execution time. #define Sig(x,n) Signal x(n,#x) As an alternative to the above declaration of x, use: Sig(x,3) // A 3 element vector, x, with the name "x" assigned. The second argument for a Signal constructor can alternatively be an integer. In this pattern the Signal is a con- stant, and the second argument is used for initialization. For example: Signal m(6, 0x26); //m[5] = One, m[4] = Zero, m[3]=Zero, m[2] = One, m[1] = One, m[0] = Zero. The elements of the vector m read left-to-right for most to least-significant element, the same as the bits in the initialization constant. Declared Signals can be composed as busses for connections to component inputs and/or outputs. Assume we have the declaration of the Signal vector "s" as: Sig(s,5); To support the different situations that arise in gathering Signals together from several sources, the following can be used: s[2] // Makes a signal composed only of element #2 of s s[2] s[2],s[4] // Makes a 2 component signal from s (s[2],s[4]) s[2],s[4],s[1] // Makes a 3 component signal from s (s[2],s[4],s[1]) s.sub(2,4) // Makes a 3 component signal from s (s[2],s[3],s[4]) s.sub(4,2) // Makes a 3 component signal from s (s[4],s[3],s[2]) 3*s[0],s.sub(1,2) // Makes a 5 component signal (s[0],s[0],s[0],s[1],s[2]) making use of the overloaded comma (,) and star (*) operators of the class Signal. These gathering mechanisms can be used in any elaboration for initializing a Signal variable that is to be composed from multiple sources, as, for example: Sig(f,3); Sig(g,4); // A 3 and a 4 component signal are created Signal h = ( f, g[0], g.sub(3,2) ); // Establishes h, which has // 6 components total, (f[2],f[1],f[0],g[0],g[3],g[2]), -9- // but no new, simulation-time // variables are created; this is a new collection of // variables already in existence. There is no assignment from one Signal to another; initialization is what should be used, usually. Be careful not to confuse initialization with assignment. Initialization is part of an object’s construction, where the raw bits allo- cated are being filled in as part of the object’s first breaths. Assignment is from one existing object to another existing object, and does the usual member-wise copy from the right-hand object to the left-hand object--proba- bly overwriting and destroying information already in the left-hand object. The default assignment operator "=", which usually exists, has been overridden to yield a diagnostic, since it may have no legitimate usage. 4.1. Connection Ordering Many primitive components such as And, Or and other gates have no functionally-significant ordering to their connections. However, when the components are rendered schematically, their interconnections have specific positional attachments. For example, assuming all the signals are scalars, the component specification And ("1a", (a,b,c), f); would be functionally equivalent for any permutation of its three inputs. As long as the same inputs were used somewhere, the output, f, would be the same. The graphical rendition of this gate and its interconnections would be different for each input permutation, however. The input connections to components have the following asso- ciation: As the component connection listing goes from left-to-right, the schematic connections are made from the top to the bottom. The above And component specification corresponds to the drawing in Figure 4.1. Figure 4.1. Input Connection Ordering Similarly, for multiple-output components, outputs are drawn on the right of the component going from the top to the bottom as the output connection list is read from left-to-right. Some components, a Counter, for example, has a notion of a most-significant bit and least-significant bit. When- ev er such an ordering is inherent for a component type, sim will always have the most-to-least significant bit ordering correspond to left-to-right ordering in the netlist connections, and to top-to-bottom ordering in the schematic rendition. For some components there can be nested orderings. Consider a multiplexer that has four ports, with each port five-bits wide. A specification for such a multiplexer could be: -12- Chapter 5: HIERARCHICAL MODULES In building simulation models for digital systems that include more than just a few gates, it is desirable to be able to form hierarchical modules that may be used directly as model components. As a simple example, Figure 5.1 shows a hierarchy with four levels. Two-Bit Adder Or HA Xor AndAnd Xor HA Full Adder Full Adder HA Xor And And Xor HA Or Figure 5.1. Hierarchical Component Organization Here, we’ll just look at two of the levels to illustrate how modules can be formed. Figure 5.2 shows the gate-level implementation of a half-adder, Figure 5.2. Half Adder Internal Gates and Figure 5.3 -13- Figure 5.3. Half Adder Module shows the modularized form of the half adder. This module can be used as a primitive component as illustrated by the following program. #include <Sim.h> void HalfAdder(const SD & sd, const Signals & in, const Signals & out) { Module ( sd, in, out ); // Module display at current schematic level, sd Xor ( SD ( sd, "1a" ), in, out[1] ); // Nested <Schematic Descriptor> And ( SD ( sd, "2a" ), in, out[0] ); // Nested <Schematic Descriptor> } int simnet () { Signal x, y, carry, sum; Switch ( "1a", x, ’x’ ); Switch ( "1a", y, ’y’ ); // Module usage HalfAdder ( "1b", ( x, y ), ( carry, sum ) ); Probe ( "1c", carry ); Probe ( "1c", sum ); } -14- Chapter 6: SIM COMMAND LINE An executable for sim can be made using the command: > sim simnet.c The executable that is produced, simex, can be invoked with the following options: Command line options: Colors (ForeGround,BackGround,SubWindow) (0-255 for each component) -C <redFG> <greenFG> <blueFG> -c <redBG> <greenBG> <blueBG> -S <redSW> <greenSW> <blueSW> Early Exit -E Function Key Operate -F <string of operations> ops from {23456789HUDE}> {H:Home; U:PgUp; D:PgDn; E:End} for example: -F 23589DD Geometry (standard X Window geometry format) -g wxh+x+y for example: -g 1000x900+100+50 Cursor Key Operate -K <digit string> , digits from {0123}> {0:left; 1:up; 2:right; 3:down} for example: -K 0003 ProfRunTimeFlags -p <flagNr> <flag> (flag[0..15]: octal, hex or int accepted) StopTime -T <time> Time Display -t UserRunTimeFlags -u <flagNr> <flag> (flag[0..15]: octal, hex or int accepted) WindowLabelString -W <windowLabel> Don’t use X-Display -X ZoomIn (to upper left and lower right coordinates) -z <xul> <yul> <xlr> <ylr> Help -h If the current directory has a file named simrc, the command line arguments will be taken from that file. -17- Chapter 8: SIM IMPLEMENTATION 8. The simulator is implemented as a set of class definitions and global functions that are written in C++. There are about 8,500 lines of C++ code that make up the simulator. The simulator uses the X-Window System, XLib library to support the run-time graphics. No higher-level win- dowing support is used; no XView nor OpenLook nor Motif. This restriction to low-level graphics usage is intended to increase the portability of the simulator. There are no arrays of fixed size used for the network description, hence there is no precise limit that can be given for the size of networks that may be simulated. All space is allocated from the heap including space for such things as components and signals. The event-queue also obtains space from the heap during simulation, and the length to which the queue must grow is also a determining factor of network size. As heap items are no longer needed, the space is returned for reallocation. 8.1. Extensions In principle it is possible to extend your use of the simulator to include many of the types of components you might desire. If you need a new digital behavior beyond that provided by the primitive components and their hierarchical use, the SignalBlock and LogicBlock components let you model the behavior using the C++ lan- guage. 8.2. Source Availability The source code for sim is available. The porting to other UNIX systems should only require the rationalization of the library files appearing in the makefile. Porting to non-UNIX systems will require changing from the X Window System interface to whatever the graphi- cal user interface is for the target system. 8.3. Bugs This is a list of known bugs and limitations in sim. 1. SuperProbes can only display in connectors that are drawn during the first display. Use a command-line option to get to the lower graphical level before the first display. 2. Probes start/stop displaying immediately after the graphical level is changed. That is, before any redraw (5) actually shows/removes the Probes themselves. 3. You can’t hav e reliable edge triggering of devices at time = 0; move those edges later in time, after the original devices’ transients. -18- Chapter 9: SIMULATION RUN-TIME MODEL During network formulation, linked-lists of Signals and Components record the results of Signal declarations and Component function-evaluations. After all the network has been established by the sub-tree of functions called starting with simnet(), all Signals and all Components being used are known. At this point, random-access data structures, arrays, are dynamically allocated and replace the linked-list forms. This revised organization of network information is used to allow rapid processing of randomly ordered visits to different Signals and Component evaluation-functions. To conserve the limited computational power available, evaluations must be done only as necessary. An event- driven simulation accomplishes this conservation. The random-access data structures support execution of the simulation model shown below. Mouse & Ke yboard Display Screen * * Queue Event Components Signals (Current Values) Change Indicators * * * * Activation Lists Figure 9.1 Simulation System Model The design features of this model are: 1. The variable values must maintain their proper time relations, there can be absolutely no time-skew of the signal changes with respect to their timing in the system model. This is an absolute requirement. 2. Consult components as infrequently as possible for evaluation of their outputs based on their current inputs. 3. Limit or prevent iterative searches for any signal value or component. 4. Time order future events, variable-value changes, in the Event Queue in an efficient manner to prevent extensive searches for event placement or retrieval. 5. Prevent unnecessary Event Queue entries that merely repeat the currently scheduled or present values of variables. As part of the netlist analysis, a set of activation lists is prepared. Each list of the set lists the components that are activated by a particular signal. When a new value for a node is taken from the event-queue, all the components in that node’s activation list are marked for evaluation. When all the nodes changing at a particular time have been updated, the marked components are evaluated. The model flows as follows. The variables are updated to their values for the current time by extracting all the "due" events from the Event Queue. Those variables that change are marked, and after all changes appropriate to -19- the now-current time are effected, every component that has just had an input variable updated is evaluated. As components produce outputs changed from their previous determination, these changed values are entered into the Event Queue, time-stamped with the future time, based on device delays, when they are to become effective. There is some adjudication necessary in bringing new variable values from the Event Queue to the Current Values list in the case of tri-state signals. If the last effective change of a variable value to a definite value (non high- impedance) was by component i, then i is the current prescriber for the value for that variable. Other components may not assert any definite values for that variable until component i relinquishes control by asserting high- impedance for its output. Failure to follow this protocol in using tri-state components yields non-fatal warnings, but the offending assertion is ignored, hopefully forcing the designer to fix the timing that caused this to happen. Accommodation of high-impedance Signals is not provided in the current version of sim. The event queue allows periodic events to be treated simply. In addition to queue entries for changing signal val- ues, an additional type of entry is provided. This added type of entry specifies procedures to be called at the appropriate future time, and these procedures generate the queue entries for the next period as well as the next "wake-up" call for the procedure itself. This is the mechanism for providing periodic elements such as clocks. Event driven simulation entails a large amount of queue activity. For this reason, the implementation of the queue is extremely important. Sim currently uses the Skew-Heap algorithm for the implementation of the event queue. The next event is at the top of the heap, and new entries are made by descending from the top of the heap, down through the binary tree, to the position where the time-label prescribes. The Skew-Heap algorithm also has some features directed to keeping the tree balanced. This implementation gives Order (log n), where there are n items in the queue, performance. The time-model for devices generally has two times associated with it. The fastest time any device of the type might respond, and the slowest. The value of variables during the time between these limits is taken to be inde- terminate whenever a logical change of the variable’s value is taking place. The simulation is done conserva- tively in that any indeterminates which arise are propagated through devices using their more-rapid response time, while determinate values are propagated using their slower response time. This conservatism prohibits dis- regard for the outcome of races generally. This feature makes simulation somewhat different than construction with physical components. For example, a physical network would go to some definite state as the outcome of a race, and the designer might not care which of several possible states that was; simulation takes the point of view that the state is indeterminate. During simulation the network may be logically stimulated or the display may be controlled. This is generally accomplished using single-key or mouse actions. Logic stimulations include changing Switch values and activat- ing Pulsers. Display control includes: zooming-in/out, changing the level of module-hierarchy display, provid- ing/inhibiting component and signal labeling, and changing window size, shape and placement. Other interac- tions include: resetting, slowing, speeding-up, halting or exiting the simulation, and omitting/including the lines of component interconnection. -22- 10.3.3. Program Use The program reads from stdin and writes to stdout and is executed using: cnd [-abcCeElnpv] [-o <filename> ] <in-file >out-file The optional [ ] command line flags can be given in any order and provide: a: If branching is used for resolving cyclic structures, give ALL the solutions. Without this flag, only one of the solutions with the fewest terms and fewest literals will be reported. b: This flag inhibits branching if a cyclic structure occurs during the covering process. If branching is inhibited, and a cyclic covering structure arises, terms with fewer literals are considered less expensive, and their use is given preference. If a cycle should have all equally-expensive terms, an arbi- trary one is selected for discard. The procedure assumes terms with fewer literals are less expensive. With no branching, only one solution will be produced, and it generally will not be the minimal solution. With branching (the default) all possible (but see the -p {pruning} flag discussed below) covers are consid- ered from the point where the cyclic structure is encountered. The default is "branching enabled" so cnd won’t inadvertently (on the user’s part) produce a non-mini- mized solution. However, the computation time grows substantially when all these possible solutions are examined. c: This commentary flag provides brief comments on the steps of the solution process. The comments are intended to reinforce the users’ knowledge about combinational network design. The commentary is writ- ten on the standard output. C: This Commentary flag provides more detailed comment about the steps of the solution process. This flag turns on the c-flag above. e: Echo user comments, that may appear at the beginning of the input file, to the standard output. E: Echo the input cubes to the standard output. l: This flag inhibits the use of the "less-than" relation for discarding prime-implicants during the covering process. A cube is deemed "less-than" another, and is discarded, if it costs no more than the other, and cov- ers no more (of what remains to be covered, at a given stage of covering) than the other. Cost is the count of literals (true’s plus complement’s) present in a cube. n: Find a non-redundant cover, rather than a minimum cover. This option can execute significantly faster than pushing to the "minimum" cover. The cover found will be a subset of the prime-implicants that has no redundant (extra PI’s) covering of the ON array. o: Direct the solution(s) to a separate output file. p: This flag inhibits the pruning that would normally occur during branching within cyclic covers. The default, pruning enabled, terminates a branching alternative exploration when a partial-cover being devel- oped becomes larger than a known minimum-cube cover already found. v: Verify that the results obtained are, at least, a valid covering. Computes the cubes that were in ON and are not in the Cover reported, and computes the cubes in the Cover reported that are outside ON and DC. Both computations should yield null results, thus establishing cover equivalence. 10.3.4. Performance Single-output functions can have a maximum of 32 variables on Unix and 16 on DOS (PC) systems. Functions of many variables can take a very long time to minimize. The present performance on a Sun SPARC 1 shows that with seven variables, using no command-line options, common minimization times are just over one second. From this point upward, expect each additional variable to take sev eral times as long as the one-fewer-variable minimizations. -23- 10.3.5. Solution Method -- The solution process is as follows: 1) Read the input. Compress the given arrays using consensus. 2) Process the input specifications. ON, OFF and DC--all given: All vertices must be therein somewhere. No overlaps are allowed. ON and OFF given: DC is determined as: DC = ˜ ( ON | OFF ). OFF not given: DC can be given as overlapping ON, but will be trimmed to: DC = DC - ON. ON not given: ON is formed as: ON = ˜ ( DC | OFF ). DC can overlap OFF, but will be trimmed to: DC = DC - OFF. By entering what is really the ON as the OFF array, you get a solution for product-of-sums, or alternatively, can use the solution and the output-complement gate that’s common on PLA’s. 3) Form the union of the ON and DC cubes. 4) Find the prime-implicants of the above union using generalized consensus. 5) Drop those prime-implicants totally outside the ON space. 6) Add to the Partial-Cover those prime-implicants which are essential. a) For the non-redundant cover option, choose a subset of prime-implicants that cover ON with no redundancy. The cover is completed with this step. 7) [Flag-controlled optional step] Discard those prime-implicant cubes that are "less-than" others. 8) Loop back to Step 6) while the function is not covered and the Cover is continuing to expand towards a solution. 9) If not covered at this point, then there exists a cyclic covering structure. a) Branching Option Selected (default)--For each PI cube not used, alternatively: 1) force that cube into the Partial-Cover (if it would not be redundant), and, 2) discard that cube. For each alternative dispo- sition, loop back to Step 6), possibly returning here recursively, for further covering cyclic-structures, to process other cubes in this same two-alternatives manner. If the all-solutions (-a) flag is not specified, and the partial cover grows beyond the smallest solution thus far, prune the branching at that point. b) Branching Option Not Selected--Find the maximum cost cube of the unused PI cubes, and throw it aw ay. Loop back to Step 6), possibly returning here recursively, to process other cubes in this draco- nian manner. 10.3.6. Troubles If you encounter problems using cnd, you may want to try the following: • Turn on the verify option to check that you actually got a legitimate cover. • If you obtained a legitimate cover, but don’t believe you have a minimum cover, review your use of the command-line options, possibly trying other combinations. • Turn on the commentary option(s) and see if you can discern any incorrect steps. 10.4. Expression Reduction The program rd (reduce) has the ability to process Boolean expressions symbolically, to allow an expressive set -24- of operators, and to reduce the expressions effectively and provides a valuable design and validation tool. Boolean expressions could be formed from just a few operators, as long as the operators chosen represented com- plete gate sets. A better design tool results when all the operators that might be expected to occur naturally, in various problem domains, are allowed. The following table of functions of two variables gives the common, and some not-so-common, binary operators. FUNCTIONS OF TWO VARIABLES (a,b) Binary Operator F(a,b) Operator Name Associative Commutative 00 01 10 11 0 0 0 0 0 0 0 0 1 a b * And Y Y 0 0 1 0 a b’ -’ Inhibited-by N N 0 0 1 1 a 0 1 0 0 a’ b ’- Inhibits N N 0 1 0 1 b 0 1 1 0 a’ b + a b’ ˆ Exclusive-or Y Y 0 1 1 1 a + b + Or Y Y 1 0 0 0 (a + b)’ +’ Nor N Y 1 0 0 1 a’ b’ + a b <-> Equivalence Y Y 1 0 1 0 b’ 1 0 1 1 a + b’ <- Implied-by N N 1 1 0 0 a’ 1 1 0 1 a’ + b -> Implies N N 1 1 1 0 (a b)’ *’ Nand N Y 1 1 1 1 1 The program rd reduces Boolean expressions to standard two-level, sum-of-products form. The input Boolean expression for rd is formed using the operators given in the following table. OPERATORS, ASSOCIATIVITY AND PRECEDENCE Symbol Operation Associativity Precedence * And Left 1 + Or Left 0 ’ Not Left 2 *’ Nand Left* 1 +’ Nor Left* 1 -’ Inhibited-by Left 0 ’- Inhibits Left 0 ˆ Exclusive-or Left 0 -> Implies Left 0 <- Implied-by Left 0 <-> Equivalence Left 0 * Nand and Nor associativity is over their "and" and "or" constituency respectively. Juxtaposition of variables with intervening white-space may also be used for implicit "And". The constants (0,1) may be used freely in expressions. Variables begin with a letter and continue using letters and digits. Blanks and newlines serve as delimiters when variables are juxtaposed. Sub-expressions may be grouped using {}, [] and (). Comments may be included using the delimiters "/*" and "*/". Comments may not be included within a vari- able name and they may not be nested. -27- Chapter 11: SIM COMPONENTS 11. Components Adder Decoder Jkff PerfMeter SignalBlock Alu Dff LogicBlock PowerOn Space And Encoder Module Probe Stderr BitAddressibleRegister Gate MultiLevelCompare ProbeH Stop CiNor HexOut Mux Pulser Switch CiOr Iand Nand Ram Xnor Clock Inand Nor Register Xor Compare Increment Not RegisterFile loadRom Counter IntOut Or Rom 11.1. Prototypes void Adder ( const SD &, const Signals & in, const Signal & out); //Adder ( "1b", ( aPortIn, bPortIn ), sumOut ); void Alu ( const SD & sd, const Signals & dataIn, const Signals & out ); //Combinational device--for MIPS //Alu ( "1b", ( aIn, bIn, cIn, op ), ( ccOut, dOut ) ); //Widths: N N 1 3 4 N //op -- operation: and=000; or=001; add=010; sub=110; // set-on-less-than=111 -- not available yet // the following may be changed later (MIPS): // xor=011; nand=101; nor=100; // not all of the following outputs are necessary for MIPS: //ccOut -- condition codes (negative,zero,overflow,carryOut) // ˆ ˆ // MSB LSB void And ( const SD & sd, const Signals & in, const Signals & out ); //Simple single And for a single out. //A vector of And’s if out is a vector, then in.length = N * out.length // and each And has N inputs. void And (const SD & sd, const Signals & in1, const Signals & in2, const Signals & out ); //A vector of out.length And’s: //if in1 & in2 are the same length: each And has two inputs, one from // in1 and one from in2. //in1.length>1 && in2.length==1:the single in2 is an input for // each of the Ands. //in1.length==1 && in2.length>1:the single in1 is an input for // each of the Ands. void BitAddressibleRegister ( const SD & sd, // inputs: const Signal & clear, const Signal & set, const Signal & enable, const Signal & write, -28- const Signals & bitIn, const Signals & writeAddress, const Signals & readAddress, // outputs: const Signals & bitOut, const Signals & registerOut); //Example: BitAddressibleRegister ( "2c", clear,set,enable,clock, // bitIn,writeAddress,readAddress, // bitOut, registerOut ); //Clear is asynchronous and active high and clears the entire register to ZEROs. //Set is asynchronous and active high and sets the entire register to ONEs. //Loading occurs on the leading edge of the "write" signal, but //only if the "enable" signal is ONE at this time. void CiNor ( const SD &, const Signals & trueSignals, const Signals & complemented, const Signal & out); //Complemented-input Nor void CiOr ( const SD &, const Signals & trueSignals, const Signals & complemented, const Signal & out); //Complemented-input Or void Clock (const SD &, const Signal &, const int duration, const int offset, const int period, const Signal & init = Zero ); //duration is ON time, offset is displacement of first ON from t=0, //period is the time until the next repetition. //init is the initial output--ON is taken to be the complement of this value. void Compare ( const SD & sd, const Signals & x, const Signals & y, const Signal & match ); //Compare two Signal vectors, x and y, for agreement of their //binary patterns. The output, match, is a ONE for agreement. //This is a composite component, so you can see inside it. void Counter ( const SD &, const Signals & in, const Signals & out ); //Counter ( "1b", ( reset, clock ), out ); void Decoder ( const SD &, const Signals & enable, const Signals & data, const Signals & out ); //N data-in lines are decoded to 2ˆN out lines //single active-high enable void Dff ( const SD &, const Signals & in, const Signals & out ); //in: (set,Din,clock,reset) //out: Q void Encoder ( const SD &, const Signals & in, const Signals & out, const Signal & valid ); //2ˆN data-in lines are examined for a ONE //the most-significant position where there is a ONE is //encoded as the N out lines’ values. //valid is ONE if there is at least one ONE. -29- void Gate ( const SD &, const Signals & in, const Signals & out ); //Complete clock pulses are gated to the output. //Enable must be ONE before the clock starts. //The clock (gated to the output) will continue for its full //duration, regardless of what Enable does later. //in: (enable,clock) //out: (gatedClock) void HexOut (const SD & sd, const Signals & control, const Signals & data); //HexOut ( "1a", (enable,clock) , data ); //writes data.length-bit data to stderr as a series of hex characters, //on the rising edge of the clock, when enabled. //data.length is variable, any size greater than zero. //No supplemental whitespace is supplied. void Iand ( const SD &, const Signals & trueSignals, const Signals & complemented, const Signal & out); //Inhibit-and void Inand ( const SD &, const Signals & trueSignals, const Signals & complemented, const Signal & out); //Inhibit-nand void Increment ( const SD &, const Signals & in, const Signals & out ); //Combinational unit. There is no carry out. void IntOut (const SD & sd, const Signals & control, const Signals & data); //IntOut ( "1a", (enable,clock) , data ); //writes data.length-bit data to stderr as a signed integer, //on the rising edge of the clock, when enabled. //data.length is variable, but over 32 isn’t supported. //No supplemental whitespace is supplied--use Stderr output for any needed. void Jkff ( const SD &, const Signals & in, const Signals & out ); //in: (set,J,clock,K,reset) //out: (Q,Qprime) void LogicBlock ( const SD &, LogicBlockEvaluatePointer, const Signals &, const Signals & ); // The second argument is the name of the user-supplied // function that is to be called whenever any of its // inputs change. This user-function computes the outputs // and returns them in logicOut[]. // // typedef void (* LogicBlockEvaluatePointer) ( // int & state, // const int numberOfInputs, // const int logicIn[], // const int numberOfOutputs, // int logicOut[] // ); void Module ( const SD &, const Signals &, const Signals & ); -32- const int numberOfReadPorts, const int numberOfWritePorts ); void Rom ( const SD & sd, const Signals & in, const Signals & out, const int words, const int bitsPerWord, const unsigned char * romContents ); //unsigned char romContents[] = { 0x01, 0x02, ... }; //Rom ( "1b", RomAddress, RomOut, 16, 12, romContents ); // 16 words x 12 bits per word //romContents is by bytes. Bytes are grouped from left to right until //there are enough (maybe surplus) to fill a word. The grouped bytes //are right justified in the word. //ONE’s in the surplus sections of words (grouped bytes) are immaterial. //For 16x12, two bytes are needed per word (for 12 bits, with surplus), //for 32 bytes total. void SignalBlock ( const SD &, SignalBlockEvaluatePointer, const Signals &, const Signals & ); // The second argument is the name of the user-supplied // function that is to be called whenever any of its // inputs change. This user-function computes the outputs // // and returns them in signalOut[]. // // typedef void (*SignalBlockEvaluatePointer) ( // int & state, // const int numberOfInputs, // const SignalValue signalIn[], // const int numberOfOutputs, // SignalValue signalOut[] // ); void Space ( const SD & ); void Stderr ( const SD & sd, const Signals & in ); //Stderr ( "1a", (enable,clock,data) ); //writes 8-bit data to stderr on the rising edge of the clock, //but only if enabled. //Control characters written as: ˆAˆB... etc. except //for 0x0A (ˆJ), which writes the newline character itself on stderr. //bit[7] (MSB) == 1 writes "|" prefix. void Stop ( const SD & sd, const Signal & input ); //when the input Signal comes on, sim will exit void Switch ( const SD &, const Signal &, const char, const Signal & init = Zero ); //char is keyboard association. //init is the initial output--ON is taken to be the complement of this value. void Xnor ( const SD &, const Signals &, const Signal & ); void Xor ( const SD &, const Signals &, const Signal & ); -33- void loadRom ( unsigned char * romContents, int size, char * filename = "romfile" ); //fill the unsigned char array, up to "size" bytes with //hex bytes from "romfile" //"romfile" is a series of hex bytes: 0xA0 0x9C ... //whitespace is immaterial, but comma separators are NOT allowed.
Docsity logo



Copyright © 2024 Ladybird Srl - Via Leonardo da Vinci 16, 10126, Torino, Italy - VAT 10816460017 - All rights reserved