1
0
mirror of https://github.com/myhdl/myhdl.git synced 2025-01-24 21:52:56 +08:00
myhdl/doc/informal.tex

371 lines
11 KiB
TeX
Raw Normal View History

2003-02-01 18:59:19 +00:00
\chapter{Introduction to \myhdl\ }
2003-02-01 00:11:52 +00:00
2003-02-01 18:59:19 +00:00
\section{A basic \myhdl\ simulation}
2003-02-01 00:11:52 +00:00
2003-02-03 00:35:39 +00:00
We will introduce \myhdl\ with a classical \code{Hello World} style
example. Here are the contents of a \myhdl\ simulation script called
2003-02-05 21:59:42 +00:00
\file{hello1.py}:
2003-02-01 00:11:52 +00:00
2003-02-01 18:59:19 +00:00
\begin{verbatim}
from myhdl import delay, now, Simulation
2003-02-01 00:11:52 +00:00
def sayHello():
while 1:
2003-02-01 18:59:19 +00:00
yield delay(10)
2003-02-01 00:11:52 +00:00
print "%s Hello World!" % now()
2003-02-01 18:59:19 +00:00
gen = sayHello()
sim = Simulation(gen)
sim.run(30)
2003-02-01 00:11:52 +00:00
\end{verbatim}
2003-02-05 21:23:18 +00:00
When we run this simulation, we get the following output:
2003-02-01 00:11:52 +00:00
\begin{verbatim}
2003-02-04 23:02:56 +00:00
% python hello1.py
2003-02-01 00:11:52 +00:00
10 Hello World!
2003-02-01 18:59:19 +00:00
20 Hello World!
2003-02-01 00:11:52 +00:00
30 Hello World!
2003-02-01 18:59:19 +00:00
StopSimulation: Simulated for duration 30
2003-02-01 00:11:52 +00:00
\end{verbatim}
2003-02-02 00:06:26 +00:00
The first line of the script imports a
2003-02-03 00:35:39 +00:00
number of objects from the \code{myhdl} package. In good Python style, and
2003-02-02 00:06:26 +00:00
unlike most other languages, we can only use identifiers that are
\emph{literally} defined in the source file \footnote{I don't want to
2003-02-05 21:23:18 +00:00
explain the \samp{import *} syntax}.
2003-02-01 18:59:19 +00:00
Next, we define a generator function called
\code{sayHello}. This is a generator function (as opposed to
2003-02-04 21:52:52 +00:00
a classic Python function) because it contains a \keyword{yield}
statement (instead of \keyword{return} statement). In \myhdl\, a
\keyword{yield} statement has a similar purpose as a \keyword{wait}
2003-02-01 18:59:19 +00:00
statement in VHDL: the statement suspends execution of the function,
and its clauses specify when the function should resume. In this case,
there is a \code{delay} clause, that specifies the required delay.
To make sure that the generator runs ``forever'', we wrap its behavior
2003-02-05 21:23:18 +00:00
in a \code{while 1} loop. This is a standard Python idiom, and it is
2003-02-19 15:36:45 +00:00
the \myhdl\ equivalent of the implicit looping behavior of a Verilog
\keyword{always} block and a VHDL \keyword{process}.
2003-02-01 18:59:19 +00:00
2003-02-03 00:35:39 +00:00
In \myhdl\, the basic simulation objects are generators. Generators
2003-02-06 22:36:53 +00:00
are created by calling generator functions. For example, variable
2003-02-03 00:35:39 +00:00
\code{gen} refers to a generator. To simulate this generator, we pass
2003-02-04 21:52:52 +00:00
it as an argument to a \class{Simulation} object constructor. We then
2003-02-19 15:36:45 +00:00
run the simulation for the desired amount of time. In \myhdl\, time
is modeled by a natural integer.
2003-02-03 00:35:39 +00:00
2003-02-02 00:06:26 +00:00
2003-02-01 18:59:19 +00:00
\section{Concurrent generators and signals}
2003-02-02 00:06:26 +00:00
In the previous section, we simulated a single generator. Of course,
real hardware descriptions are not like that: in fact, they are
typically massively concurrent. \myhdl\ supports this by allowing an
arbitrary number of concurrent generators. More specifically, a
2003-02-04 21:52:52 +00:00
\class{Simulation} constructor can take an arbitrary number of
2003-02-06 22:36:53 +00:00
arguments, each of which can be a generator or a nested sequence of
2003-02-02 00:06:26 +00:00
generators.
2003-02-04 21:52:52 +00:00
With concurrency comes the problem of deterministic
communication. Therefore, hardware languages use special objects to
2003-02-06 22:36:53 +00:00
support deterministic communication between concurrent code. \myhdl\
has as \class{Signal} object which is roughly modeled after VHDL
signals.
2003-02-02 00:06:26 +00:00
2003-02-05 21:23:18 +00:00
We will demonstrate these concepts by extending and modifying our
first example. We introduce a clock signal, driven by a second
generator:
2003-02-01 18:59:19 +00:00
2003-02-02 00:06:26 +00:00
\begin{verbatim}
clk = Signal(0)
2003-02-01 18:59:19 +00:00
2003-02-02 00:06:26 +00:00
def clkGen():
while 1:
yield delay(10)
clk.next = 1
yield delay(10)
clk.next = 0
2003-02-05 21:23:18 +00:00
\end{verbatim}
The \code{clk} signal is constructed with an initial value
\code{0}. In the clock generator function \code{clkGen}, it is
continuously assigned a new value after a certain delay. In \myhdl{},
the new value of a signal is specified by assigning to its
\code{next} attribute. This is the \myhdl\ equivalent of VHDL signal
assignments and Verilog's non-blocking assignments.
The \code{sayHello} generator function is modified to wait for a
rising edge of the clock instead of a delay:
\begin{verbatim}
2003-02-02 00:06:26 +00:00
def sayHello():
while 1:
yield posedge(clk)
print "%s Hello World!" % now()
2003-02-01 00:11:52 +00:00
2003-02-05 21:23:18 +00:00
\end{verbatim}
2003-02-06 22:36:53 +00:00
Waiting for a clock edge is achieved with a second form of the
2003-02-05 21:23:18 +00:00
\keyword{yield} statement: \samp{yield posedge(\var{signal})}.
2003-02-06 22:36:53 +00:00
A \class{Simulation} object will suspend the generator as that point,
and resume it when there is a rising edge on the signal.
2003-02-05 21:23:18 +00:00
The \class{Simulation} is now constructed with 2 generator arguments:
\begin{verbatim}
2003-02-02 00:06:26 +00:00
sim = Simulation(clkGen(), sayHello())
sim.run(50)
2003-02-01 18:59:19 +00:00
2003-02-02 00:06:26 +00:00
\end{verbatim}
2003-02-05 21:23:18 +00:00
When we run this simulation, we get:
2003-02-02 00:06:26 +00:00
\begin{verbatim}
2003-02-04 23:02:56 +00:00
% python hello2.py
2003-02-02 00:06:26 +00:00
10 Hello World!
30 Hello World!
50 Hello World!
StopSimulation: Simulated for duration 50
\end{verbatim}
2003-02-01 18:59:19 +00:00
2003-02-05 21:23:18 +00:00
\section{Parameters, instantiations and hierarchy}
2003-02-03 00:35:39 +00:00
2003-02-04 21:52:52 +00:00
So far, the generator function examples had no parameters. For
example, the \code{clk} signal was defined in the enclosing scope of
the generator functions. However, to make the code reusable we will
want to pass arguments through a parameter list. For example, we can
change the clock generator function to make it more general
and reusable, as follows:
2003-02-03 00:35:39 +00:00
\begin{verbatim}
def clkGen(clock, period=20):
2003-02-06 22:36:53 +00:00
lowTime = int(period / 2)
2003-02-03 00:35:39 +00:00
highTime = period - lowTime
while 1:
yield delay(lowTime)
clock.next = 1
yield delay(highTime)
clock.next = 0
\end{verbatim}
The clock signal is now a parameter of the function. Also, the clock
2003-02-06 22:36:53 +00:00
\var{period} is a parameter with a default value of \code{20}.
This makes \var{period} an \dfn{optional} parameter; if it is not
specified in a call, the default value will be used.
2003-02-03 00:35:39 +00:00
Similarly, the \code{sayHello} function can be made more general:
\begin{verbatim}
def sayHello(clock, to="World!"):
while 1:
yield posedge(clock)
print "%s Hello %s" % (now(), to)
\end{verbatim}
2003-02-05 21:23:18 +00:00
We can create any number of generators by calling generator functions
with the appropriate parameters. This is very similar to the concept of
\dfn{instantiation} in hardware description languages and we will use
the same terminology in \myhdl{}. Hierarchy can be modeled by defining
the instances in a higher-level function, and returning them. For
example:
2003-02-01 00:11:52 +00:00
2003-02-03 00:35:39 +00:00
\begin{verbatim}
2003-02-17 17:35:20 +00:00
def greetings():
2003-02-03 00:35:39 +00:00
clk1 = Signal(0)
clk2 = Signal(0)
clkGen1 = clkGen(clk1)
clkGen2 = clkGen(clock=clk2, period=19)
sayHello1 = sayHello(clock=clk1)
sayHello2 = sayHello(to="MyHDL", clock=clk2)
2003-02-05 21:23:18 +00:00
return clkGen1, clkGen2, sayHello1, sayHello2
\end{verbatim}
2003-02-19 15:36:45 +00:00
As in standard Python, positional or named parameter association can
be used in instantiations, or a mix of both\footnote{All positional
parameters have to come before any named parameter.}. All these styles
are demonstrated in the example above. As in hardware description
languages, named association can be very useful if there are a lot of
parameters, as the parameter order in the call does not matter in that
case.
2003-02-05 21:23:18 +00:00
\class{Simulation} constructor arguments can also be sequences of
generators. In this way, they support hierarchy: the return value of a
higher-level instantiating function can directly be used an
argument. For example:
2003-02-03 00:35:39 +00:00
2003-02-05 21:23:18 +00:00
\begin{verbatim}
2003-02-17 17:35:20 +00:00
sim = Simulation(greetings())
2003-02-03 00:35:39 +00:00
sim.run(50)
\end{verbatim}
This produces the following output:
2003-02-01 00:11:52 +00:00
2003-02-03 00:35:39 +00:00
\begin{verbatim}
2003-02-04 23:02:56 +00:00
% python greetings.py
2003-02-03 00:35:39 +00:00
9 Hello MyHDL
10 Hello World!
28 Hello MyHDL
30 Hello World!
47 Hello MyHDL
50 Hello World!
StopSimulation: Simulated for duration 50
\end{verbatim}
2003-02-01 00:11:52 +00:00
2003-02-05 21:23:18 +00:00
\section{Bit-oriented operations}
Hardware design involves dealing with bits and bit-oriented
2003-02-20 09:53:28 +00:00
operations. The standard Python type \class{int} has most of the
desired features, but lacks support for indexing and
slicing. Therefore,
\myhdl\ provides the \class{intbv} class. The name was chosen to
suggest an integer with bit vector flavour.
Class \class{intbv} works transparently as an integer and with other
integer-like types. Like class \class{int}, it provides access to the
2003-02-20 11:50:55 +00:00
underlying two's complement representation for bitwise
2003-02-20 09:53:28 +00:00
operations. In addition, it is a mutable type that provides indexing
and slicing operations, and some additional bit-oriented support such
as concatenation.
2003-02-05 21:23:18 +00:00
2003-02-19 23:38:08 +00:00
\subsection{Indexing operations}
\label{gray}
2003-02-05 21:23:18 +00:00
As an example, we will consider the design of a Gray encoder. The
following code is a Gray encoder modeled in \myhdl{}:
\begin{verbatim}
2003-02-17 12:26:22 +00:00
def bin2gray(B, G, width):
2003-02-05 21:23:18 +00:00
""" Gray encoder.
B -- input intbv signal, binary encoded
2003-02-05 22:38:06 +00:00
G -- output intbv signal, Gray encoded
2003-02-17 12:26:22 +00:00
width -- bit width
2003-02-05 21:23:18 +00:00
"""
while 1:
yield B
for i in range(width):
G.next[i] = B[i+1] ^ B[i]
2003-02-05 21:23:18 +00:00
\end{verbatim}
2003-02-05 22:38:06 +00:00
This code introduces a few new concepts. The string in triple quotes
at the start of the function is a \dfn{doc string}. This is standard
2003-02-06 22:36:53 +00:00
Python practice for structured documentation of code. Moreover, we
2003-02-05 22:38:06 +00:00
use a third form of the \keyword{yield} statement:
2003-02-05 21:23:18 +00:00
\samp{yield \var{signal}}. This specifies that the generator should
resume whenever \var{signal} changes value. This is typically used to
describe combinatorial logic.
2003-02-19 15:36:45 +00:00
Finally, the code contains bit indexing operations and an exclusive-or
2003-02-19 23:38:08 +00:00
operator as required for a Gray encoder. By convention, the lsb of an
2003-02-20 09:53:28 +00:00
\class{intbv} object has index \code{0}.
2003-02-06 22:36:53 +00:00
To verify the Gray encoder, we write a test bench that prints input
and output for all possible input values:
\begin{verbatim}
def testBench(width):
B = Signal(intbv(0))
G = Signal(intbv(0))
2003-02-17 12:26:22 +00:00
dut = bin2gray(B, G, width)
2003-02-06 22:36:53 +00:00
def stimulus():
for i in range(2**width):
B.next = intbv(i)
yield delay(10)
print "B: " + bin(B, width) + "| G: " + bin(G, width)
2003-02-06 22:36:53 +00:00
return (dut, stimulus())
\end{verbatim}
2003-02-19 15:36:45 +00:00
We use the conversion function \code{bin} to get a binary
2003-02-17 22:38:20 +00:00
string representation of the signal values. This function is exported
2003-02-19 15:36:45 +00:00
by the \code{myhdl} package and complements the standard Python
2003-02-17 22:38:20 +00:00
\code{hex} and \code{oct} conversion functions.
2003-02-06 22:36:53 +00:00
To demonstrate, we set up a simulation for a small width:
\begin{verbatim}
Simulation(testBench(width=3)).run()
\end{verbatim}
The simulation produces the following output:
\begin{verbatim}
% python bin2gray.py
B: 000 | G: 000
B: 001 | G: 001
B: 010 | G: 011
B: 011 | G: 010
B: 100 | G: 110
B: 101 | G: 111
B: 110 | G: 101
B: 111 | G: 100
StopSimulation: No more events
\end{verbatim}
2003-02-19 23:38:08 +00:00
\subsection{Slicing operations}
For a change, we will use a plain function as an example to illustrate
slicing. The following function calculates the HEC byte of an ATM
header.
\begin{verbatim}
from myhdl import intbv
concat = intbv.concat # shorthand alias
COSET = 0x55
def calculateHec(header):
""" Return hec for an ATM header, represented as an intbv.
2003-02-20 11:50:55 +00:00
The hec polynomial is 1 + x + x**2 + x**8.
2003-02-19 23:38:08 +00:00
"""
hec = intbv(0)
for bit in header[32:]:
hec[8:] = concat(hec[7:2],
bit ^ hec[1] ^ hec[7],
bit ^ hec[0] ^ hec[7],
bit ^ hec[7]
)
return hec ^ COSET
\end{verbatim}
2003-02-20 09:53:28 +00:00
The code shows how slicing access and assignment is supported on the
\class{intbv} data type. In accordance with the most common hardware
convention, and unlike standard Python, slicing ranges are
downward. The code also demonstrates concatenation of \class{intbv}
objects.
As in standard Python, the slicing range is half-open: the highest
index bit is not included. Unlike standard Python however, this index
corresponds to the \emph{leftmost} item. The rightmost index is
\code{0} by default, and can be ommitted from the slice.
2003-02-19 23:38:08 +00:00
The half-openness of a slice may seem awkward at first, but it helps
2003-02-20 09:53:28 +00:00
to avoid one-off count issues in practice. For example, the slice
\code{hex[8:]} has exactly \code{8} bits. Likewise, the slice
2003-02-19 23:38:08 +00:00
\code{hex[7:2]} has \code{7-2=5} bits. You can think about it as
2003-02-20 09:53:28 +00:00
follows: for a slice \code{[i:j]}, only bits below index \code{i} are
2003-02-20 11:50:55 +00:00
included, and the bit with index \code{j} is the last bit included.
2003-02-19 23:38:08 +00:00