Quick Start Guide¶
This guide demonstrates how to perform arithmetics on the PyMTL3 Bits objects and how to simulate simple hardware components like a full adder and a register incrementer. All contents of this guide can be finished in a Python >= 3.6 interative REPL.
Bits arithmetics¶
Let’s start with a simple addition of two 4-bit numbers. The
following code snippet imports the basic PyMTL3 functionalities
and creates two 4-bit objects a
and b
:
>>> from pymtl3 import *
>>> a = Bits4(4)
Bits4(0x4)
>>> b = Bits4(3)
Bits4(0x3)
The Bits objects support common arithmetics and comparisons:
>>> a + b
Bits4(0x7)
>>> a - b
Bits4(0x1)
>>> a * b
Bits4(0xC)
>>> a & b
Bits4(0x0)
>>> a | b
Bits4(0x7)
>>> a > b
Bits1(0x1)
>>> a < b
Bits1(0x0)
Full adder example¶
Next we will experiment with a full adder. It has already been included in the PyMTL3 code base and we can simply import it to use it in the REPL.
>>> from pymtl3.examples.ex00_quickstart import FullAdder
Thanks to the inspection feature of Python we can easily print
out the source code of the full adder. You can see that the
full adder logic is implemented inside an update block upblk
.
>>> import inspect
>>> print(inspect.getsource(FullAdder))
class FullAdder( Component ):
def construct( s ):
s.a = InPort()
s.b = InPort()
s.cin = InPort()
s.sum = OutPort()
s.cout = OutPort()
@update
def upblk():
s.sum @= s.cin ^ s.a ^ s.b
s.cout @= ( ( s.a ^ s.b ) & s.cin ) | ( s.a & s.b )
To simulate the full adder, we need to apply the DefaultPassGroup
PyMTL pass. Then we can set the value of input ports and simulate
the full adder by calling fa.sim_tick
:
>>> fa = FullAdder()
>>> fa.apply( DefaultPassGroup() )
>>> fa.sim_reset()
>>> fa.a @= 0
>>> fa.b @= 1
>>> fa.cin @= 0
>>> fa.sim_tick()
Now let’s verify that the full adder produces the correct result:
>>> assert fa.sum == 1
>>> assert fa.cout == 0
Register incrementer example¶
Similar to the full adder, we can do the following to import the register incrementer component and print out its source:
>>> from pymtl3.examples.ex00_quickstart import RegIncr
>>> print(inspect.getsource(RegIncr))
And to simulate an 8-bit register incrementer:
>>> regincr = RegIncr( 8 )
>>> regincr.apply( DefaultPassGroup() )
>>> regincr.sim_reset()
>>> regincr.in_ @= 42
>>> regincr.sim_tick()
Now verify the registered output is indeed incremented:
>>> assert regincr.out == 43