Welcome to Pyha’s documentation!¶
Installation¶
Pyha requires Python >= 3.6 (default for Ubuntu 17.10 or Anaconda)
pip install pyha
Or from sources:
git clone --recursive https://github.com/gasparka/pyha
cd pyha
pip install -e .
pytest # optionally run the test suite
RTL simulation (optional)¶
Cocotb (included with Pyha) dependencies:
sudo apt-get install make gcc g++ swig
Install GHDL and add it to the path. On Ubuntu run:
sh /scripts/install_ghdl.sh
GATE simulation (optional)¶
In addition to the RTL simulation requirements, install the Intel Quartus with support for Cyclone IV and add INSTALL_DIR/quartus/bin
to path.
Compile Quartus libraries into GHDL_PATH/lib/ghdl/altera
by running:
python /scripts/compile_quartus_lib.py
# expected output: Compiling Altera Quartus libraries [FAILED]
Examples / Quick start¶
See Pyha demo for quick-start into Pyha.
See Pyhacores for collection of cores implemented in Pyha, for example CORDIC, FIR …
Types¶
Information about synthesisable types.
Builtins¶
Integers are synthesised into 32-bit logic, thought there may be optimizations. Variable bit-width integers can be implemented with the Sfix
class.
Booleans are fully usable.
Any Pyha object or builtin can be used in a list. Lists can be used as registers, function inputs/outputs or simulation top-level inputs/outputs.
Example of bool
shift-register:
class ShiftReg(Hardware):
def __init__(self):
self.shr = [False] * 4 # define register
def main(self, x):
self.shr = [x] + self.shr[:-1] # throw away last element and add new element as first
return self.shr # return the whole list
Constants¶
Constants are defined by writing the variable name in UPPERCASE, this has no effect in Python simulations, but usually saves resources in hardware.
Example:
class Dut(Hardware):
def __init__(self):
self.regular = 1
self.CONSTANT = 1
Fixed-point¶
Complex numbers¶
Floats¶
Floats can be used when performing arithmetic/comparison with fixed-point numbers, in this case they are first converted to the type of the other fixed-point operand.
Float registers are converted automatically into fixed-point representation, by default Sfix(left=0, right=-17)
.
class Dut(Hardware):
def __init__(self):
self.reg = 0.1 # will be converted to "Sfix(0.1, 0, -17)"
Enums (state machines)¶
Use Enums to build state machines. Example:
class States(Enum):
S0, S1 = range(2)
class T(Hardware):
def __init__(self):
self.state = States.S0 # state register
def main(self, a):
if self.state == States.S0:
self.state = States.S1
return 0
elif self.state == States.S1:
self.state = States.S0
return a
User defined types¶
User defined types can be used as registers, inputs/outputs to simulation etc..
Example:
# user type with 'x' and 'y' elements
class Point(Hardware):
def __init__(self, x, y):
self.x = x
self.y = y
# accumulator of Points
class PointAcc(Hardware):
def __init__(self):
self.sum = Point(0, 0)
def main(self, a):
self.sum.x = a.x
self.sum.y = a.y
return self.sum
inp = [Point(1, 2), Point(3, 4)] # use Point() as input to simulation
dut = PointAcc()
sims = simulate(dut, inp, simulations=['PYHA', 'RTL'])
Simulation / Testing¶
Pyha provides an simple interface for simulations and asserts in order to quickly write unit-tests.
Main idea is to compare the MODEL
output against the hardware simulations.
Simulation¶
Asserts¶
Use the following functions with the assert
statement.
Delays¶
Each register in signal path delays the output by one sample, resulting in a mismatch compared to a software MODEL
.
The delay will be compensated if you specify the delay with self.DELAY
.
Example:
class T(Hardware):
def __init__(self):
self.reg = 0
self.DELAY = 1 # 1 register on signal path (input -> output)
def main(self, a):
self.reg = a
return self.reg