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
|
2003-03-05 17:40:14 +00:00
|
|
|
|
2003-02-17 10:08:19 +00:00
|
|
|
\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}
|