1
0
mirror of https://github.com/myhdl/myhdl.git synced 2024-12-14 07:44:38 +08:00
myhdl/doc/modeling.tex

201 lines
4.8 KiB
TeX
Raw Normal View History

2003-02-17 10:08:19 +00:00
\chapter{Modeling techniques}
\section{RTL modeling}
The present section describes how \myhdl\ supports RTL style modeling
2003-03-04 09:59:08 +00:00
as is typically used for synthesizable models in Verilog or VHDL. This
section is included mainly for illustrative purposes, as this modeling
style is well known and understood.
2003-02-20 13:20:15 +00:00
2003-02-17 10:08:19 +00:00
\subsection{Combinatorial logic}
\subsubsection{Template}
Combinatorial logic is described with a generator function code template as
follows:
\begin{verbatim}
def combinatorialLogic(<arguments>)
while 1:
yield <input signal arguments>
<functional code>
\end{verbatim}
The overall code is wrapped in a \code{while 1} statement to keep the
generator alive. All input signals are clauses in the \code{yield}
statement, so that the generator resumes whenever one of the inputs
changes.
\subsubsection{Example}
The following is an example of a combinatorial multiplexer:
\begin{verbatim}
def mux(z, a, b, sel):
""" Multiplexer.
z -- mux output
a, b -- data inputs
sel -- control input: select a if asserted, otherwise b
"""
while 1:
yield a, b, sel
if sel == 1:
z.next = a
else:
z.next = b
\end{verbatim}
To verify, let's simulate this logic with some random patterns. The
\code{random} module in Python's standard library comes in handy for
such purposes. The function \code{randrange(\var{n})} returns a random
natural integer smaller than \var{n}. It is used in the test bench
code to produce random input values:
\begin{verbatim}
from random import randrange
(z, a, b, sel) = [Signal(0) for i in range(4)]
MUX_1 = mux(z, a, b, sel)
def test():
print "z a b sel"
for i in range(8):
a.next, b.next, sel.next = randrange(8), randrange(8), randrange(2)
yield delay(10)
print "%s %s %s %s" % (z, a, b, sel)
Simulation(MUX_1, test()).run()
\end{verbatim}
Because of the randomness, the simulation output varies between runs
\footnote{It also possible to have a reproducible random output, by
2003-02-18 13:04:38 +00:00
explicitly providing a seed value. See the documentation of the
2003-02-17 10:08:19 +00:00
\code{random} module}. One particular run produced the following
output:
\begin{verbatim}
% python mux.py
z a b sel
6 6 1 1
7 7 1 1
7 3 7 0
1 2 1 0
7 7 5 1
4 7 4 0
4 0 4 0
3 3 5 1
StopSimulation: No more events
\end{verbatim}
\subsection{Sequential logic}
\subsubsection{Template}
Sequential RTL models are sensitive to a clock edge. In addition, they
may be sensitive to a reset signal. We will describe one of the most
common patterns: a template with a rising clock edge and an
asynchronous reset signal. Other templates are similar.
\begin{verbatim}
def sequentialLogic(<arguments>, clock, ..., reset, ...)
while 1:
yield posedge(clock), negedge(reset)
if reset == <active level>:
<reset code>
else:
<functional code>
\end{verbatim}
\subsubsection{Example}
The following code is a description of an incrementer with enable, and
2003-02-18 13:04:38 +00:00
an asynchronous power-up reset.
2003-02-17 10:08:19 +00:00
\begin{verbatim}
ACTIVE_LOW, INACTIVE_HIGH = 0, 1
def Inc(count, enable, clock, reset, n):
""" Incrementer with enable.
count -- output
enable -- control input, increment when 1
clock -- clock input
reset -- asynchronous reset input
n -- counter max value
"""
while 1:
yield posedge(clock), negedge(reset)
if reset == ACTIVE_LOW:
count.next = 0
else:
if enable:
count.next = (count + 1) % n
\end{verbatim}
For the test bench, we will use an independent clock generator, stimulus
generator, and monitor. After applying enough stimulus patterns, we
2003-02-18 13:04:38 +00:00
can raise the \code{myhdl.StopSimulation} exception to stop the
2003-02-17 10:08:19 +00:00
simulation run. The test bench for a small incrementer and a small
number of patterns is a follows:
\begin{verbatim}
count, enable, clock, reset = [Signal(intbv(0)) for i in range(4)]
INC_1 = Inc(count, enable, clock, reset, n=4)
def clockGen():
while 1:
yield delay(10)
clock.next = not clock
def stimulus():
reset.next = ACTIVE_LOW
yield negedge(clock)
reset.next = INACTIVE_HIGH
for i in range(12):
enable.next = min(1, randrange(3))
yield negedge(clock)
raise StopSimulation
def monitor():
print "enable count"
yield posedge(reset)
while 1:
yield posedge(clock)
yield delay(1)
print " %s %s" % (enable, count)
2003-02-19 15:36:45 +00:00
Simulation(clockGen(), stimulus(), monitor(), INC_1).run()
2003-02-17 10:08:19 +00:00
\end{verbatim}
The simulation produces the following output:
\begin{verbatim}
% python inc.py
enable count
0 0
1 1
0 1
1 2
1 3
1 0
0 0
1 1
0 1
0 1
0 1
1 2
StopSimulation
\end{verbatim}
2003-02-17 12:26:22 +00:00
\section{High level modeling}
2003-03-04 09:59:08 +00:00
\emph{Empty}