In the previous section, we simulated a design with a single generator and no concurrency. On the other hand, real hardware descriptions are typically massively concurrent. MyHDL supports this by allowing an arbitrary number of concurrently running generators.
With concurrency comes the problem of deterministic communication. Hardware languages use special objects to support deterministic communication between concurrent code. In particular, MyHDL has a Signal object which is roughly modeled after VHDL signals.
We will demonstrate signals and concurrency by extending and modifying our first example. We define two hardware modules, one that drives a clock signal, and one that is sensitive to a positive edge on a clock signal:
from myhdl import Signal, delay, always, now, Simulation
def ClkDriver(clk):
halfPeriod = delay(10)
@always(halfPeriod)
def driveClk():
clk.next = not clk
return driveClk
def HelloWorld(clk):
@always(clk.posedge)
def sayHello():
print "%s Hello World!" % now()
return sayHello
clk = Signal(0)
clkdriver_inst = ClkDriver(clk)
hello_inst = HelloWorld(clk)
sim = Simulation(clkdriver_inst, hello_inst)
sim.run(50)
The clock driver function ClkDriver has a
clock signal as its parameter. This is how a
port is modeled in MyHDL. The function
defines a generator
that continuously toggles a clock signal after a certain delay.
A new value of a signal is specified by assigning to its
next attribute. This is the MyHDL equivalent of
the VHDL signal assignment and the
Verilog non-blocking assignment.
The HelloWorld function is modified from the
first example. It now also takes a clock signal as parameter.
Its generator is made sensitive to a rising
edge of the clock signal. This is specified by the
posedge attribute of a signal. The edge
specifier is the argument of the always
decorator. As a result, the decorated function
will be executed on every rising clock edge.
The clk signal is constructed with an initial value
0. When creating an instance of each
hardware module, the same clock signal is passed as
the argument. The result is that the instances
are now connected through the clock signal.
The Simulation object is constructed with the
two instances.
When we run the simulation, we get:
% python hello2.py 10 Hello World! 30 Hello World! 50 Hello World! _SuspendSimulation: Simulated 50 timesteps
About this document