\chapter{Modeling techniques} \section{RTL modeling} The present section describes how \myhdl\ supports RTL style modeling as is typically used for synthesizable models in Verilog or VHDL. In this domain, \myhdl\ doesn't offer advantages compared to other solutions. However, as this modeling style is well-known, this section may be useful for illustrative purposes. \subsection{Combinatorial logic} \subsubsection{Template} Combinatorial logic is described with a generator function code template as follows: \begin{verbatim} def combinatorialLogic() while 1: yield \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 explicitly providing a seed value. See the documentation of the \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(, clock, ..., reset, ...) while 1: yield posedge(clock), negedge(reset) if reset == : else: \end{verbatim} \subsubsection{Example} The following code is a description of an incrementer with enable, and an asynchronous power-up reset. \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 can raise the \code{myhdl.StopSimulation} exception to stop the 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) Simulation(clockGen(), stimulus(), monitor(), INC_1).run() \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} \section{High level modeling} test