---------------------------------------------------------------- | WELCOME to the instruction manual for Lsim on the Atari ST | ---------------------------------------------------------------- Congratulations on deciding to read the manual. May you live long and prosper. This manual goes with Lsim version 2.1. Table of contents ... ===== == ======== === Section 1 Introduction Section 2 What LSIM.TOS does Section 3 The Lsim circuit description language 3.1 Circuit description statements 3.2 Declaration statements 3.3 Character set and comments Section 4 The nature of the interactive simulation 4.1 Input 4.2 Progress through time 4.3 Cheating Section 5 Running Lsim Appendix 1 Quick key guide Appendix 2 Summary of the Lsim language Appendix 3 Operator truth tables Appendix 4 Flip-flops in the Lsim language Please don't start by reading the appendixes ... Section 1 Introduction The standard method of designing a piece of digital electronics can be broken down into these four steps:- 1) A specification is made. This step outputs a document saying what the hardware must do. 2) An electronic circuit which implements the specification is designed. This step outputs a circuit diagram. 3) A prototype of the circuit is built. This step outputs a physical circuit, built either with a bread board technique such as wire-wrap, or directly onto a prototype of the PCB for the product. 4) The prototype is tested and debugged. Usually this involves generating test inputs for the electronics, and monitoring its outputs to see what it does. Faults in the prototype are corrected until it performs as specified. LSIM.TOS provides a logically (but not electronicly) accurate soft- ware simulation of any digital circuit made from the basic gates: AND; OR; XOR; NOT; and tristate buffers. More complex circuit elements, such as flip-flops, can easily be simulated using standard arrangements of gates. Although this version of Lsim does only the absolute minimum that a simulator might be expected to do, it is still a big leap forward from no simulator at all. Usually the last thing done in step 2 (above) is to check the circuit diagram to make sure that the digital electronics functions as intended by the specification. Usually this checking is done "by hand" (i.e. by human brain). At the very least Lsim offers a computer aid for this checking. There are several advantages to using the computer aid. Checking what a logic circuit does by hand is tedious and boring, so it tends to be put off or avoided whenever possible. Lsim makes this checking quick and easy, so it doesn't get put off. The unaided human brain is notoriously error prone when performing relatively mechanical tasks, such as checking logic. Computers, of course, are notoriously good at such tasks. Effort spent checking the circuit before physical prototyping in step 3 (above) pays off amply at step 4 (above). Even with expensive tools like logic analysers and storage scopes, finding a logical fault in a digital circuit is not necessarily easy. Modifying a physical prototype is much more time consuming and difficult than modifying a software simulation. Also you can copy a software simulation and hack around with the copy as much as you like, knowing that the original is just a disk access away. Frequently there is only 1 physical prototype, which must be treated with care. If a significant amount of the logic is in PALs or other PLDs a further difficulty can occur. In the process of locating a logical fault in the circuit being checked you may find yourself wanting to probe a point inside a chip. This is perfectly straight forward on a software simulation, but absolutely impossible on a physical circuit. This kind of problem will get worse as the complexity of PALs etc. increases. Indeed most PAL design software (Abel & Palasm) provides rudimentary simulation. However I find this kind of apply test vectors to the PAL equations and check their outputs simulation clumsy to use. It is not interactive. Also the maximum size of the simulation is often only 1 PAL, which must be of a type that the software already knows about. My interest in logic simulation began at the same time as my interest in designing with PALs. I used to design random logic with 7400 style chips using a circuit diagram as the working metaphor. Now I design random logic as a set of PAL definition equations, using boolean algebra as the working metaphor. Using the the simulator I check each part as I go along, building up a simulation of all the random logic by the end of the design. On the basis of this "taster" experience I would say that the use of programmable logic coupled with really high quality simulation and CAD layout has the capacity to change the practice of hardware design as much as the replacement of punched card reader and line printer by keyboard and VDU has changed the practice of software design. Section 2 What LSIM.TOS does The digital circuit to be simulated is defined in a text description language based on boolean algebra. The text description is stored as a straight ASCII file, easily edited by the word processor of your choice. Unlike Palasm the Lsim language is fairly free format. When Lsim is run it reads the text description file and compiles it to a data base for use by the simulation part of the program. Any errors in the file format are displayed on the screen. There is also an option to create an output file containing a listing of the input with the error messages added to it. If there are no input errors Lsim automatically proceeds to simulate the circuit. During simulation you have control over the logic levels of a number of points in the circuit. At any time you can ask the program to calculate the next logical state of the circuit. There are 2 reasons why Lsim doesn't mimic a real circuit, and automatically go to the next state every time you change a logic level. Firstly it would make it impossible to change 2 (or more) levels at once, and secondly it would leave no opportunity to correct typing errors. Lsim doesn't model gate propagation delays. It assumes only that the output of a gate changes state after the inputs change state. When it calculates the next logical state of the circuit Lsim waits until all the gates have done all their state changes before outputting the next circuit state. Lsim keeps track of the past states of all the circuit signals named in the text description. This information is presented as a character based timing diagram which is scrollable horizontally and, if there are more than 25 named signals, vertically. Lsim recognises and displays 5 states that a signal may be in. As well as the regular states of logic high, logic low and tristated (high impedance) Lsim uses contended and undetermined. A contended state appears when the outputs of 2 (or more) gates with different non-tristate logic levels are shorted together. An undetermined state appears when Lsim can't work out what the state of a signal should be. For example the output of a NOT gate with a tristated input is undetermined. Watch out for this undetermined state as its cause can be quite subtle. For example if you create a flip-flop that has no reset line then there is no way to tell what state it should be in at power up. Lsim will show its output as undetermined until data is clocked into the flip-flop. The use of undetermined as a state might be called logic simulation for paranoids. It prevents a circuit working in the simulator as a result of chance choices about things that are unreliable in the real world, such as the power up state of unreset flip-flops. There is some more about this in the example file TLIGHTS.LSM that should accompany this manual. The maximum size of the simulated circuit depends on the amount of memory available to the program. A simulation of a circuit with 10000 2 input gates and 2500 named nodes which keeps track of the past 20 states of each named signal occupies very roughly 300K. This is about the maximum I would expect from a 512K ST with a few desk accessories. Machines with more memory may simulate larger circuits, or keep track of more past states etc. When Lsim has constructed the data base it uses the remaining memory to store the past states of the circuit signals. Thus if your circuit is nearly too big Lsim will only store a few past states of each signal. With small circuits the buffer for storing past states is large, and may well not be filled by even quite a long simulation. Section 3 The Lsim circuit description language The Lsim language is best explained in a tutorial (waffle) fashion. To make circuit diagrams drawn with ASCII character graphics clearer I will adhere to the convention that a circuit's inputs are on its left, and its output on its right. 3.1 Circuit description statements Consider first a very simple circuit consisting of a single 2 input and gate. This circuit has 2 inputs which I will call A and B. Represented as a circuit diagram it would look something like this:- ________ A -----| | | and |----- B -----|______| Given that the symbol for AND in the Lsim language is just a dot (.) you will not be surprised to learn that this circuit is represented by:- A.B Suppose now that we wish to take the output of our AND gate and OR it with a third input called C, as in the following circuit diagram:- ________ A -----| | | and |______ B -----|______| | | ________ |_____| | | or |----- C ------------------------|______| Again given that the symbol for OR in the Lsim language is a plus (+) you will not be surprised to learn that this circuit is represented by:- A.B+C This all seems very natural. We are used to the idea of AND having a higher priority than OR in boolean expressions (just as multiplication has a higher priority than addition in arithmetic expressions). Lsim interprets boolean expressions according to the normal priorities so there is no danger of thinking that:- A.B+C represents:- ________ A ------------------------| | ______| and |----- | |______| ________ | B -----| | | | or |_____| C -----|______| To represent this circuit (with the OR coming before the AND) we must use brackets:- A.(B+C) Again the use of the brackets to force the OR to be done first follows quite naturally from the way we are used to writing boolean expressions. It would however be a mistake to assume that the Lsim language behaves just like boolean algebra, or indeed just like Palasm or Abel equations. There is a subtle but extremely important difference connected to the use of the equals (=) symbol. So far I've avoided mentioning this difference by not mentioning what happens to the output from the example circuits I've been discussing. But the time has come to grab the bull by the tail and look the facts in the face. In designing the Lsim language my number 1 priority was to provide an accurate representation of digital electronics, in order to ensure the integrity of the simulation. THE LSIM LANGUAGE IS BEST THOUGHT OF AS A CONDENSED AND VERY SYMBOLIC CIRCUIT DIAGRAM, which is what it really is. The similarity to boolean algebra makes this form of circuit diagram easy to read but can be misleading, as you will see with the equals sign. Consider a circuit consisting of two 2 input AND gates. Call the inputs of the 1st gate A & B and the inputs of the 2nd gate C & D. Connect the outputs of the AND gates together (with a piece of wire). The circuit diagram for this is:- ________ A -----| | | and |______ B -----|______| | | ________ |----- C -----| | | | and |_____| D -----|______| I know that as it stands this circuit is useless, but it is never the less possible to build such a circuit. Since you can build it and draw its circuit diagram, you can represent it in the Lsim language. Like this:- A.B=C.D This introduces the symbol for connection with a piece of wire: the equals sign (=). Of course there is no boolean expression corresponding to this circuit, and it can't be described in either Palasm or Abel. Since the equals symbol means connect the two sides together with wire the it can occur more than once in an expression. For example this circuit:- ________ A -----| | | and |______ B -----|______| | | ________ |----- C -----| | | | and |_____| D -----|______| | | ________ | E -----| | | | and |_____| F -----|______| is represented by:- A.B=C.D=E.F The equals (=) symbol has a priority just like the AND (.) and OR (+) symbols you've already met. In fact it has the lowest priority of all. To represent a circuit like this:- ________ A ----------------| | ________ _____| and |----------| | B -----| | |______| _____| and |----- |_____| | |______| | | C -----| | | D -----------------------------| requires brackets, like this:- A.(B=C).D The unbracketed expression:- A.B=C.D in which the ANDs take priority over the equals is of course the 1st circuit I showed you that used the equals symbol:- ________ A -----| | | and |______ B -----|______| | | ________ |----- C -----| | | | and |_____| D -----|______| Shorting together the outputs of and gates is fairly useless, but shorting together the outputs of tristate buffers (such as the ubiquitous 74LS244) is common and useful. Usually control logic ensures that only 1 tristate buffer on any given line is enabled at any given moment. In 7400 style chips (like the '244) the output enable is generally active low, but in popular PALs such as the 16L8 it is active high. For the Lsim language I chose to copy the PALs and provide as a basic element a tristate buffer with an active high enable. Consider a circuit with 2 inputs. An input called A which is passed to a tristate buffer controlled by the other input, called B. When B is high the tristate buffer is enabled and the output of the circuit is A. When B is low the tristate buffer is disabled (set to the 'off' state) and the output of the circuit is a high impedance. Represented as a circuit diagram it would look something like this:- ________ | | A -----| tri |----- |______| |OE | B ---------| which is represented in the Lsim language by:- B?A The output enable (?) has the second lowest priority, the only thing with a lower priority is the equals (=). For example the Lsim expression:- B+C?A represents:- ________ | | A -------------------| tri |----- |______| |OE ________ | B -----| | | | or |__________| C -----|______| while in order to represent:- ________ B ------------------------| | ______| or |----- ________ | |______| | | | A -----| tri |_____| |______| |OE | C ---------| we must use brackets, like this:- B+(C?A) There are 2 more gates that Lsim models directly: the NOT gate; and the XOR gate. These behave exactly as you would expect having read thus far. A circuit consisting of an XOR gate with 2 inputs A and B:- ________ A -----| | | xor |----- B -----|______| is represented in the Lsim language by:- A$B The priority of the XOR ($) is the same as that of the OR (+). Although Jerry Pournelle says you can never have too many examples I will spare you (and me) the tedium of examples concerning the priority of the XOR ($). A circuit consisting of a NOT gate with 1 input A:- ________ | | A -----| not |----- |______| is represented in the Lsim language by:- /A NOT (/) has the highest priority of all. Thus to represent the NAND gate:- ________ A -----| | | nand |----- B -----|______| we must use brackets, like this:- /(A.B) while the unbracketed expression:- /A.B represents:- ________ | | A -----| not |______ |______| | | ________ |_____| | | and |----- B ------------------------|______| of course. Users of Palasm be warned: it is possible for a single equation to be syntactically valid in both Palasm and Lsim, but to mean different things in each language. The following Palasm equation describes an output cell of a 16L8 used as a nor gate:- /A = B + C This Palasm circuit looks like this:- ________ B -----| | | nor |----- A C -----|______| While in Lsim the same statement describes a circuit made by connecting the output of a not gate to the output of an or gate, like this:- ________ | | A -----| not |______ |______| | | ________ |----- B -----| | | | or |_____| C -----|______| I have now introduced all the 'operators' in the Lsim language. Note that there is nothing corresponding to an 'assignment' operator, the equals symbol being used to indicate connection with a piece of wire - a quite different concept. In a real circuit as well as being connected to the outputs from other gates, inputs may be connected to the positive supply or to ground. The Lsim language uses the symbols 0 and 1 for ground (logic low), and the positive supply (logic high) respectively. Thus, for example. the use of a spare XOR gate as an inverter (of the signal A) would be written:- 1$A representing:- ________ A -----| | | xor |----- Positive supply -----|______| The reader will have noticed a certain ambiguity in the Lsim language so far described, for example consider the Lsim fragment:- A?B?C Does this represent:- ________ ________ | | | | C -----| tri |-----------| tri |----- |______| |______| |OE |OE | | B ---------| | | | A ----------------------------| Or does it represent:- ________ | | C -------------------| tri |----- |______| |OE ________ | | | | B -----| tri |__________| |______| |OE | A ---------| We can make the original fragment unambiguous with brackets: thus A?(B?C) unambiguously represents the 1st circuit, and (A?B)?C the 2nd circuit. In situations like A?B?C where priorities and brackets don't fully define a circuit Lsim always takes the operators '=', '?' and '/' strictly in right to left order. The other operators: '.', '+', and '$' are taken strictly in left to right order. Thus A?B?C represents the same as A?(B?C) and not (A?B)?C. But A$B+C represents the same as (A$B)+C and not A$(B+C). There is a multiplexing technique that uses tristate buffers. Because it inserts only 1 gate delay in the signal path this technique is very popular when more than 2 signals need to be multiplexed onto a single line very rapidly. It is used, for example, in the Acorn BBC micro to multiplex the memory addresses between the 6502 CPU, the 6845 CRTC and the SA5050 teletext chip. I will give it as an example because it uses both the = and the ?, the 2 elements of the Lsim language different from Palasm and Abel (and boolean algebra). Suppose we have 3 signals: S0, S1, and S2 that we wish to multiplex onto a single line Y under the control of 3 control signals: C0, C1, and C2. When control input C0 is high signal S0 is multiplexed onto Y. C1 and C2 behave similarly. Of course the control logic generating C0-C2 must ensure that only 1 control line is high at a time. A circuit for this multiplexer is:- ________ | | S0 --------------| tri |--------------| |______| | |OE | | |---------- Y C0 ------------------| | | ________ | | | | S1 --------------| tri |--------------| |______| | |OE | | | C1 ------------------| | | ________ | | | | S2 --------------| tri |--------------| |______| |OE | C2 ------------------| As is, I hope, clear by now this would have the following representa- tion in the Lsim language:- Y=C0?S0=C1?S1=C2?S2 The Y= bit may look like the start of an assignment, but all it really means is connection with a piece of wire to point Y in the circuit. Suppose that the inverse of Y was also of interest, a signal I'll call Y_ (the underscore is legal in Lsim names). The circuit to generate Y and Y_ might be written:- /(Y=C0?S0=C1?S1=C2?S2)=Y_ It might also be written (introducing the semicolon):- Y_=/Y; Y=C0?S0=C1?S1=C2?S2; or indeed:- Y=C0?S0=C1?S1=C2?S2; Y_=/Y; The semicolon does just what you'd expect: it separates the circuit description into convenient chunks called circuit description statements. Every statement in the Lsim language must end in a semicolon. Remember that these statements are really a form of circuit diagram. Changing the order of the circuit description statements in an Lsim input file makes no difference to its meaning, just as changing the order of the sheets in a circuit diagram spread over several sheets makes no difference to its meaning. 3.2 Declaration Statements There is only 1 other kind of statement in the Lsim language: the declaration statement. Each named point or signal in a circuit (such as C0, C1, C2, S0, S1, S2, Y, and Y_ in the above example) must be declared before it can be used in a circuit description statement. A declaration statement must start with an exclamation mark (!). This is followed by a list of signal names to be declared. The names in the list are separated with commas, and terminated with a semicolon. Only the first 12 characters of a signal name are significant. Adding the appropriate declaration to the multiplexer example gives:- ! C0,C1,C2,S0,S1,S2,Y,Y_; Y_=/Y; Y=C0?S0=C1?S1=C2?S2; These 3 lines are now a complete Lsim input file for simulating the multiplexer. There is more that could be added to this input file, but these 3 lines are a minimum that will work. There is a little more declaration syntax to be described. Each signal name in a declaration list may be optionally followed by either '=0', or '=1'. There is something (explained later) called the user gate associated with each named signal. This may be initialised at the start of the simulation to either tristate, or logic high or logic low. Signal names appearing on their own in a declaration statement (like C0 etc. above) have their user gates initialised to tristate. Signals followed by =0 have their user gates initialised to logic low, while signals followed by =1 have their user gates initialised to logic high. Sensible initial settings for the multiplexer example might be:- ! C0=1,C1=0,C2=0,S0=0,S1=0,S2=0,Y,Y_; Y_=/Y; Y=C0?S0=C1?S1=C2?S2; As is explained later this will cause the simulation to start with S0 selected and all data inputs low. 3.3 Character set and comments All text appearing enclosed in curly brackets { } is a comment, and is ignored by Lsim. Comments do nest - so it is possible to comment out commented parts of the input file {and to make comment nesting errors}. A comment can appear literally anywhere - including the middle of a signal name. No special character is required to mark the end of an Lsim input file, the occurrence of end of file is taken as an end mark. An Lsim input file can contain any character, however only the printable characters in the range 21 hex "!" to 7E hex "~" inclusive are significant, all other characters are ignored. Note that as well as carriage return, newline, tab, etc. space is also ignored. Like comments, ignored characters can appear anywhere - it is even possible to have spaces and carriage returns etc. in the middle of a signal name. I'm not sure that this was such a good idea, even if it is the same as Algol 68 and I'm not even sure of that. It does however mean that the Lsim language is fairly free format. The multiplexer example might be laid out like this:- {---- Multiplexer example from Lsim tutorial ----} ! C0 = 1, C1 = 0, C2 = 0, S0 = 0, S1 = 0, S2 = 0, Y, Y_ ; Y_ = /Y ; Y = C0 ? S0 = C1 ? S1 = C2 ? S2 ; as in the file MPLEX.LSM that should accompany this document. Apart from the following special characters:- ! /.+$?= () ;, {} 0 1 any non-ignored character can be used in a signal name. The special characters 0 and 1 may also appear in a signal name provided it isn't a single character name. Thus 'DataBusBit0' is a legal name, as is '10More', but not '1' on its own. As an aside let me recommend to the reader the convention of using a trailing underscore to indicate an "active low" signal. I have found this most useful, especially as both Palasm and Abel accept the underscore in a pin name. Section 4 The nature of the interactive simulation 4.1 Input The time has come to explain the previously mentioned user gate. Most digital electronic systems have input signals, and output signals. Many have signals (such as data buses) which are both. During a simulation the user must be able to set the values at the inputs to the system being simulated. Lsim lets the user set one of three values at each input: logic high, logic low and tristate. It is as though each input is connected to the output of a tristate buffer under the user's control. I have called this tristate buffer the user gate. In Lsim every named signal is treated as an input, and has a user gate connected to it. During a simulation if the named signal is set to logic high, and the user gate connected to it is set to logic low the simulation will show contention. Just as it does when high and low outputs of "ordinary" gates are connected together. Apart from being under the user's control the user gate behaves just like any other tristate buffer in the simulation. Probably most of the named signals were not intended to be inputs, some may even be meant to be non-tristate outputs. Because Lsim simulates tristate this is not a problem. The user gates connected to these signals are simply left set to tristate throughout the simulation, in which case it is as though they wern't there. The simulation of a bi-directional input, such as a line of a data bus, is also easy. When the line is to be used as an output the user tristates its user gate, when it is used as an input the user gate is set high or low as appropriate. It is not difficult for the user to mimic the bus cycles of CPUs like this, allowing the random "glue" logic of a computer system, or the interface logic of a bus card to be easily simulated. 4.2 Progress through time Simulation proceeds as a series of discreet steps from one logical state to the next. The user tells Lsim when to step on to the next state. Inbetween steps the user can change the states of the user gates. Lsim calculates the next state iteratively. A step of the iteration consists of going through all the gates in the system, and setting their outputs appropriately to their inputs. This process is repeated until none of the outputs change state. In this way Lsim imitates a system in which all the gates have infinitesimal propagation delay. Obviously it is possible to have infinite loops, such as:- A = /A There is no way for Lsim to detect the presence of an infinite loop, which can be a good deal more subtle than the above example. In order to prevent the program hanging in an infinite loop it pauses on every 23rd iteration of the settling loop and prompts. The user may either continue for another 23 cycles, or abort the attempt to calculate the next state. In case the cause of the infinite loop isn't clear, it is possible to single step the simulation one iteration of the settling loop at a time. 4.3 Cheating The user gates are the main method of interaction with the circuit being simulated. However this interaction is, so to speak, once removed from the circuit itself. With the user gate it is not possible to directly alter the state of a named signal, only to change the state of the output of a gate connected to the named signal. The named signal may have other outputs connected to it as well. If one of the other outputs is set to logic high it is impossible to force the signal to logic low with the user gate. Setting the output of the user gate to logic low will simply cause the signal to go contended. Logic designed using a finite state machine metaphor may have unreachable states. Sometimes, for test purposes, it is interesting to know what the logic does if it gets into an unreachable state. There can be lots of reasons for wanting to directly set the state of a given signal in the circuit being simulated. Lsim keeps a record of the current state of each named signal in memory. It is possible to directly edit this record, and so set any named signal to logic high, logic low or tristate. Of course doing this breaks the logical integrity of the simulation - in the sense that it can do things real logic wouldn't do. For example the output of an AND gate with low inputs can be forced high. I have found this "cheat" feature useful to get sequential logic out of stuck states, particularly ones where lots of signals are undetermined. However normally I always use the user gate route for interaction, as it preserves the logical integrity of the simulation. Section 5 Running Lsim Lsim's opening screen is very simple. It just prompts you for the name of the input file and the name of the output file. If you don't want an output file simply type a carriage return at the output file prompt. The output file is a copy of the input file with the error messages added to it. Lsim also looks for the input and output file names in the command line image TOS passes it. Assuming that your input file had no syntax errors you get to the simulation. This draws the timing diagram on the screen. No past states of signals are shown at first. Pressing return will step the simulation, and generate the first state. The timing diagram is how Lsim presents its output to the user. Each named signal has a line to itself in the timing diagram. The line starts with the name of the signal. Then it shows the past states of the signal (most recent state rightmost) using the following symbols:- xxx Undetermined (e.g the output of a gate with tristated inputs) !!! Contended (e.g. a logic high connected to a logic low) ... Tristate (high impedance) ÿÿÿ Logic High (the same as 1) { weirdy Atari char - unprintable } ___ Logic Low (the same as 0) At the right hand end of the line the state of the output of the user gate connected to the signal is shown using the following symbols:- . Tristate (high impedance) 1 Logic High (the same as ÿÿÿ) 0 Logic Low (the same as ___) The signals appear in the timing diagram in the order in which they are declared in the input file. This fact (at last) completes the semantics of the Lsim language. If the simulation has been stepped more times than will fit across the screen, the right and left arrow keys can be used to scroll the display forwards and backwards in time. When the display is scrolled backwards in time the rightmost signal states on the screen are no longer the current states. Lsim indicates this by removing the states of the user gates from the display. The simulation may only be stepped when the display is scrolled as far forwards in time as possible and the user gate information is shown. A line cursor (moved by the up and down arrow keys) is provided to indicate which signal is to have its user gate set. The Insert, and clr/home keys turn this cursor on and off. Full stop, Number 0, and Number 1 keys set the value of the line cursor signal's user gate. It is only possible to set a user gates value when the user gate information is shown and the line cursor is on. Escape lets you out. Appendix 1 Quick key guide Key Action === ====== Insert show line cursor Clr/Home hide line cursor up arrow move line cursor up (scroll if at top) down arrow move line cursor down (scroll if at bottom) Shift up arrow scroll display up Shift down arrow scroll display down left arrow scroll display backwards in time 1 state right arrow scroll display forwards in time 1 state Shift left arrow scroll display backwards in time 5 states Shift right arrow scroll display forwards in time 5 states Control left arrow scroll display backwards in time all the way Control right arrow scroll display forwards in time all the way 0 set the line cursor user gate to logic low 1 set the line cursor user gate to logic high . set the line cursor user gate to tristate Control 0 force the line cursor signal to logic low (cheat) Control 1 force the line cursor signal to logic high (cheat) Control . force the line cursor signal to tristate (cheat) Return/Enter calculate the next state of the simulation S single step the settling loop P redraw the screen Esc terminate the program Appendix 2 A summary of the Lsim language A2.1 Operators The operators in order of priority (highest first) are:- Symbol Operator Direction of elaboration ====== ======== ========= == =========== / Not Right to left . And Left to right + $ Or Xor (equal priority) Left to right ? Output enable Right to left = Connection (with wire) Right to left A2.2 Comments Anything enclosed in curly brackets { } is comment. Comments nest. A2.3 Character set Space is not a significant character. Only the following are:- !"#$%&'()*+,-./0123456789:;<=>? @ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_ `abcdefghijklmnopqrstuvwxyz{|}~ Any non-significant characters in the input file are ignored. A2.4 Signal names Signal names may contain only the following characters:- "# %&' * - 0123456789: < > @ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_ `abcdefghijklmnopqrstuvwxyz | ~ of which only the first 12 are significant. The single character names 0 and 1 are used as the logical constants. A2.5 Grammar The grammar of the Lsim language input file is:- ! ; , = 0 = 1 ; = ? + $ . / ( ) 0 1 The terminal symbols of this grammar are:- and the literal characters ! /.+$?= () ;, 0 1 Appendix 3 Operator truth tables The truth tables use these abrieviations:- tri - Tristated (high impedance) lo - Logic Low hi - Logic High cont - Contended udet - Undetermined In the case of a binary operator the right operand is shown along the top of the table, and the left operand down the left hand side of the table. NOT / | tri lo hi cont udet -------+----------------------------------- | udet hi lo udet udet AND . | tri lo hi cont udet -------+----------------------------------- tri | udet lo udet udet udet lo | lo lo lo lo lo hi | udet lo hi udet udet cont | udet lo udet udet udet udet | udet lo udet udet udet OR + | tri lo hi cont udet -------+----------------------------------- tri | udet udet hi udet udet lo | udet lo hi udet udet hi | hi hi hi hi hi cont | udet udet hi udet udet udet | udet udet hi udet udet XOR $ | tri lo hi cont udet -------+----------------------------------- tri | udet udet udet udet udet lo | udet lo hi udet udet hi | udet hi lo udet udet cont | udet udet udet udet udet udet | udet udet udet udet udet OE ? | tri lo hi cont udet -------+----------------------------------- tri | udet udet udet udet udet lo | tri tri tri tri tri hi | udet lo hi udet udet cont | udet udet udet udet udet udet | udet udet udet udet udet WIRE = | tri lo hi cont udet -------+----------------------------------- tri | tri lo hi cont udet lo | lo lo cont cont cont hi | hi cont hi cont cont cont | cont cont cont cont cont udet | udet cont cont cont udet Appendix 4 Flip-flops Unfortunately Lsim doesn't (yet) support the flip-flop as a basic operator. This means that flip-flops must be specified at the gate level. In this appendix I will provide tested Lsim implementations of some common flip-flop types. They may be regarded as "black boxes" - it is easy to verify that they perform as advertised by using the simulator. This saves you the trouble of figuring out your own flip-flops. A process that can be more difficult than it might seem due to the way the undetermined state propagates through a simulation. G. Spencer-Brown in "The Laws of Form" (chap. 11, pp. 58, Time) shows that the property of memory in a logical system built from gates follows from circular or re-entrant information paths. Whilst 1 circle is enough for a level triggered transparent or set-reset latch, I strongly suspect (but haven't yet mathematically proved) that at least 2 circles are required for an edge triggered device. At any rate I have been unable to devise any Lsim representations of edge triggered flip-flops without naming at least 1 other point in the circuit besides the inputs and the output. This means that the edge triggered designs have an extra signal name (q1) associated with them. The behaviour of this signal need not concern the user, it can be regarded as being inside the flip-flop's black box. It is a good idea to declare these extra signal names last so they appear at the bottom of the timing diagram, and don't clutter up the action. If anyone does figure out an Lsim representation of a single output edge triggered flip-flop without using an extra internal signal name I would be very interested in seeing it. I can be contacted on CIX as jason. Here are 5 common flip-flops. For an example of the use of the 3rd flip-flop circuit in this list see the accompanying Lsim input file TLIGHTS.LSM. 1) Transparent (level triggered) latch. ! D, { = data input } Q, { = data output } G; { = latch enable input (high = transparent, low = latched) } Q = (/G + D).(G.D + Q); The remaining designs are all edge triggered. In all cases I have written the equations to latch on the rising clock edge, and to have active high asynchronous (jam) set and clear inputs. It is easy to invert the polarity of any input signal if you want a falling edge clocked device, or active low set and clear lines. 2) D-Type flip-flop with set and clear. ! D, { = data input } Q, { = data output } Clk, { = rising edge triggered clock input } Set, { = active high asynchronous set input } Clear, { = active high asynchronous clear input } q1; { = extra signal internal to flip-flop } Q = /Clear.(D + /Clk + q1).(Set + Q + D.Clk./q1); q1 = Clk.(q1 + Set + Clear + /(Q $ D)); 3) D-Type flip-flop without set and clear. ! D, { = data input } Q, { = data output } Clk, { = rising edge triggered clock input } q1; { = extra signal internal to flip-flop } Q = (/Clk + q1 + D).(Clk./q1.D + Q); q1 = Clk.(q1 + /(Q $ D)); 4) J-K flip-flop with set and clear. ! J, { = J input } K, { = K input } Q, { = data output } Clk, { = rising edge triggered clock input } Set, { = active high asynchronous set input } Clear, { = active high asynchronous clear input } q1; { = extra signal internal to flip-flop } Q = /(Clear + Clk.q1 + /(Set + Q + Clk./q1)); q1 = /Set.(Clk + /(J./(K.Q) + /K.Q)).(Clear + q1 + /Clk.(K./(J./Q) + /J./Q)); 5) J-K flip-flop without set and clear. ! J, { = J input } K, { = K input } Q, { = data output } Clk, { = rising edge triggered clock input } q1; { = extra signal internal to flip-flop } Q = /(Clk.q1).(Q + Clk./q1); q1 = (Clk + /(J./(K.Q) + /K.Q)).(q1 + /Clk.(K./(J./Q) + /J./Q));