----------------------------------------------------------------
| 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));