diff --git a/doc/Makefile b/doc/Makefile
new file mode 100644
index 0000000..778be05
--- /dev/null
+++ b/doc/Makefile
@@ -0,0 +1,13 @@
+DOC := qz2021_-_using_python_for_verification_of_digital_systems.md
+
+PDF := $(DOC:.md=.pdf)
+
+.PHONY: all
+all: $(PDF)
+
+%.pdf: %.md template/template.tex images/*
+ pandoc -t beamer --pdf-engine xelatex --listings --template=template/template.tex $< -o $@
+
+.PHONY: clean
+clean:
+ rm -rf $(PDF)
diff --git a/doc/images/cocotb_cosim.drawio b/doc/images/cocotb_cosim.drawio
new file mode 100644
index 0000000..4026c6d
--- /dev/null
+++ b/doc/images/cocotb_cosim.drawio
@@ -0,0 +1 @@
+7ZpZb9s4EIB/jYHuQwrdlh8bO012kwLBeutN9qVgJFpiS4suRcV2f/2SEmlJpny0lqIibQIE4vD+ZjjDIwN7vFhfU7CMP5AQ4oFlhOuBPRlYlmcb/K8QbAqB63uFIKIoLERmKZiib1AKZb0oQyFMawUZIZihZV0YkCSBAavJAKVkVS82J7je6xJEUBNMA4B16b8oZLGUeoZRZtxAFMWqa0vlLIAqLQVpDEKyqojsq4E9poSw4muxHkMs4CkwRb33e3K3I6MwYadUwF8vJ1n64e+Pn9AnY2OsHu7+G19YRSvPAGdyxlO0yDBghMpRs41iQUmWhFC0Zg7sy1WMGJwuQSByV1z5XBazBZbZz5AyxDm+wyhKuIwRUUAfs5yGKA7XFZGcwzUkC8johheRuY4CLC3KUXxXFf2MpCyuqsaVQiBtItq2XVLjHxLcd0C0NYiTj/8MLA/zni+fOEgvEl9vZjeTu4HF+zBmkCJMoj8OMDaOM54jjMcEc1WJunboQj90uDxllHyBlRzferI9ryX+Tp2/azTwtxr4d4bf1fCPCefIUALb5QugPw+a+HqBD5/m7fA1zR37dnS+XgNeqyu8pqnxnd3c/3keWkoYYIgIz3AxMtohZ/u75FyNnO12Q+45+8uaecHt1+B2SDarh/TudnKhg7vfsJhP+izPWrXKhHAbP+xsNX4NlPciHfXpaxuZ6gFr1pEtngVOs0W/Z1vUY1Rni7hVcK7V9yIeHYFEKF/TEUkAviNi3eVoPkPGNnI7CzJG6uDgGrGHyvejaOotn2mRnKxl03lioxIJn85DXtJVycdqXlktT6l6KQOUvRN7YS4IMEhTFCjxe4TVmIpZwlDbD2seOSUZDeABZFI9vIMIsqORRTcFCvkGFD3XB9K+JzE0xYrZT2VSutaOdP2KVb3fbfemabNHTQ9/NVXbfapaPwtcnxvlGvZbbcQ5a2eDMNTjnNOws3K6inOeRq7nU9RZeLVT1PDlTlGNeIevGm/TJcCL4vVfN167Z7ymfzCClsHyqpS2F1DL7dJjJedYPK1F0zK4/jTx1HRODKhunwFVjbKysi5REqIkSttbWCGcgyy/Le3iSGmpe6ADZ/Hhi64mPdZOgxiGGYZUX2cYo2Uq1lMagyXMrZNk4XHA2/eG3Ly/QBbEW1sXvku9ZzR4ubkrfoWcJKwiL34avV/+05L32707aYjdfoO+urtz0oO3rqYk1L1H7a6kujZ+7FAYnu2I9j9f6Nqo0HYP0D7ZDcke7gniA9wq29t5ztm+GKomiuHLWqUitYbc4ageM9XFkWqo8LNaQ7lFbKd9hpHoW5BzjaSm8B8NbKcbytH7ml4NxVFV9un3VEPRHrDM0VvXellbGf0OAIeeGN2dANDwBNZSAODJ8gW+UG/5fwz21f8=
\ No newline at end of file
diff --git a/doc/images/cocotb_cosim.png b/doc/images/cocotb_cosim.png
new file mode 100644
index 0000000..371200e
Binary files /dev/null and b/doc/images/cocotb_cosim.png differ
diff --git a/doc/images/cocotb_overview.svg b/doc/images/cocotb_overview.svg
new file mode 100644
index 0000000..aec273c
--- /dev/null
+++ b/doc/images/cocotb_overview.svg
@@ -0,0 +1,3 @@
+
+
+
\ No newline at end of file
diff --git a/doc/images/cocotb_uarttx.drawio b/doc/images/cocotb_uarttx.drawio
new file mode 100644
index 0000000..04ca9ee
--- /dev/null
+++ b/doc/images/cocotb_uarttx.drawio
@@ -0,0 +1 @@
+1VjbctowEP0aP5bxPfAI5NLOJDOZkLSkL4ywF1uNbFFZDqZfXwnL+AppA7lgZhjt2dXt7B5ZY80aR9kVQ8vwhvpANFP3M80610zzzDbEvwTWCtDPciBg2M8howQm+A8oUFdoin1IaoGcUsLxsg56NI7B4zUMMUZX9bAFJfVZlyiAFjDxEGmjP7DPQ4W6ul46vgIOwmJqs/BEqIhWQBIin64qkHWhWWNGKc9bUTYGIskriMn7Xe7wblfGIOb/0oH8Hp2nyc3dwwzP9LW+ml7/HH+x81GeEUnVjjkkfJYixnmm1s3XBRuMprEPcjxds0arEHOYLJEnvSuRfoGFPCLCMkSToDmQW5pgjmksME+sE5hwPAPjWFB83QiIsO/LmUaI4KCzx1A5OJVzLTAhY0oo2yzOWjjyJ3Ea8wqePwJPOKNPUPG4m0d42lQqduXEkFUgRe0V0Ag4W4sQ5bWKvKtCtwbKXpVlYxcxYaViTEeBSJVqsB27TKZoqHz+R26dVm5lWmea6RIx92jORCuQLQYeYLHVw/LdSIePoL/wOmn3+jBfHId2t0G77bRp73ew7r4V6YbZYhF8caQokzIe0oDGiFyU6KjOcxlzTWWhb9j9BZyv1fmIUk7r3EOG+VR27znKeqx4zjM18sZYF0Ys9jutGo/lCNIsu22sot/OrCU0ZR7s4cZVBzhiAfA9caaVB0ri9hYBA4K4qNz6sd+RUtX1lmKx5lKzzqA3EBW0fexaLTlnes+yBuVTHz/fhhqyUTXbNb6+kNyWep8RnvnsRIVqmZ9NqPZHCtWoyLQU7S6h+kN5lRFmTGPIkUsst7vxJ6ISeRHhEZQk2CtgFWYcpNtCjy8K13kf3bq23uvQquvs1Gq+xTfTakFQRazjELynk1SqbdeV6rhtpRrme0rVbLE7wVEqSoju49d4md/ue+UxOGyedmYHh24Hh4bxViS2S/RBnA/3B17ymxXqQN+3uyq0b86tY921mxXa9S553wrtt8j9Pvx2Ou+Xz3oRPPo98KAkD9oKGt7dn0qWX5+tD3v778iWMMuvJvkrvPz2ZF38BQ==
\ No newline at end of file
diff --git a/doc/images/cocotb_uarttx.png b/doc/images/cocotb_uarttx.png
new file mode 100644
index 0000000..3c06005
Binary files /dev/null and b/doc/images/cocotb_uarttx.png differ
diff --git a/doc/images/readonly.drawio b/doc/images/readonly.drawio
new file mode 100644
index 0000000..88ebbfe
--- /dev/null
+++ b/doc/images/readonly.drawio
@@ -0,0 +1 @@
+5Vpdc6MgFP01mdl96Iwf0SSPbdpu+9DZneZhn4lQZRbFRWyS/fULClHRJmmaptY+BS5wuZ5zuAJm5M7j9Q8G0uiBQkRGjgXXI/d65Di2bTniR1o2ymI5XmkJGYbKVhkW+B/SHZU1xxBljY6cUsJx2jQGNElQwBs2wBhdNbs9UdKcNQUhahkWASBt628MeaSsvmVVDXcIh5Ge2tEtMdC9lSGLAKSrmsm9GblzRikvS/F6joiETwNTjrt9oXUbGUMJP2TA7QO5h6uUs7vl4u7eiZcXs/RCeXkGJFdPrILlGw2BiDuVRTETx4A8CphBEsrWq1WEOVqkIJDtKyEBYYt4TETNFsUl5ZzGomKJClMgyfITJmROCWWintBEulJxIMbR+sUHtLewCcUhGiPONqLLestKOUSJzdX1VcXcVJmiGmfaBpRWwq3nCk1RUIC+AtzxgMB1nZ6B6w0I3PG0Z+D6AwLXH/cM3ElfwIWYCceYJoWJSTBOAbjXtzw8HTjgY6tngM8GDrjTt5Sit8uDRXzSt+2H7exHHCXwUp5BKnRqoDKaJxBBhWQ5FsHWaWQvQDUAvA4AtI0hAjh+brrvQkXN8ItiMfGL27/tAUi7yGjOAqRG1U8hpiOv6cgzY+GAhYi3HBUkbR/7Dby5X4o3z8hU3mx2HG+ebfJmnZe3Aw5TQ+JtH9zHr7cz83bAOW1AvJl3EMfnyX0J9715O+AIOCDezDx5NG9T64N5O+B0GeTsuWBG8lQjMSAgy3DwmXl09ZDtPtE9cv25k2be9LyDeBRYgk2tWyo7ZDsCnjX1MratnXE5k+58XsmojOCkotK56IuKyrye881TxXu/jF8tKvMtNNktqrEZ1+Qcojrg28OARWXeIRwvqiN3Cm8W1Wy3qEyx+2fJVF3Hcp9weVlBi+gqdfl/c6obLrLi0+Ol6CA0sq4aRSmUv484w0l4I+T07bv2KCIsnZZdWurlaM0NiSIxD1gWHaRIQc5pOXPRDAgO5cVJICSKmDDIOxMcAHKpGmIMYXFjo8gS03hXI++6+y4m44z+QYaxa5W87bOb3Z1s6uvIdjsWkpn8TnY347TP+I8IwJ8J2UjyPh9LUmXq27hzItZa7zTfa7PmdLDmvp41Ua0+c5crvfq7gHvzHw==
\ No newline at end of file
diff --git a/doc/images/readonly.png b/doc/images/readonly.png
new file mode 100644
index 0000000..c13b661
Binary files /dev/null and b/doc/images/readonly.png differ
diff --git a/doc/images/uart_wave.json b/doc/images/uart_wave.json
new file mode 100644
index 0000000..a2d8263
--- /dev/null
+++ b/doc/images/uart_wave.json
@@ -0,0 +1,4 @@
+{signal: [
+ {name: 'tx', wave: '10.10...101..'},
+ {name: '', wave: "x34.......53x", data: ["start", "data (0x42, 0d66)", "par", "stop"] }
+]}
diff --git a/doc/images/uart_wave.png b/doc/images/uart_wave.png
new file mode 100644
index 0000000..ae17e18
Binary files /dev/null and b/doc/images/uart_wave.png differ
diff --git a/doc/images/vai_uart_wave.png b/doc/images/vai_uart_wave.png
new file mode 100644
index 0000000..95dc846
Binary files /dev/null and b/doc/images/vai_uart_wave.png differ
diff --git a/doc/images/vai_wave.json b/doc/images/vai_wave.json
new file mode 100644
index 0000000..e6910f8
--- /dev/null
+++ b/doc/images/vai_wave.json
@@ -0,0 +1,7 @@
+{signal: [
+ {name: 'reset', wave: '01...|.....'},
+ {name: 'clk', wave: 'P....|.....'},
+ {name: 'valid', wave: '0.1.0|..10.'},
+ {name: 'accept', wave: '0..10|1..0.'},
+ {name: 'data', wave: 'x.3.x|..3x.'}
+]}
diff --git a/doc/images/vai_wave.png b/doc/images/vai_wave.png
new file mode 100644
index 0000000..46fcd86
Binary files /dev/null and b/doc/images/vai_wave.png differ
diff --git a/doc/images/vhdl_cosim.drawio b/doc/images/vhdl_cosim.drawio
new file mode 100644
index 0000000..eb7a229
--- /dev/null
+++ b/doc/images/vhdl_cosim.drawio
@@ -0,0 +1 @@
+1Vlbb9owFP41SNvDUJxbw2OBbp1EJVS6rd1LZZID8WpiZkyB/frZxLmRAC0l0KZSlXN8if1953w+CQ2rM1l+43ga3rAAaMM0gmXD6jZMs4U8+V85VrHDc+zYMeYkiF0ocwzIP9BOQ3vnJIBZoaNgjAoyLTp9FkXgi4IPc84WxW4jRotPneIxlBwDH9Oy9xcJRKi9rmFkDddAxmHyaDNpmeCkt3bMQhywRc5lXTWsDmdMxHeTZQeoAi8BJh73dUtrujIOkXjJAPq33Z3Pbm5/PJJHY2Us7nu/O1/MeJZnTOd6xwMymVMsGNerFqsEC87mUQBqNtSw2ouQCBhMsa9aF5J86QvFhOrmZ+CCSBwvKRlH0ieY6qCfJttguXUbKAVHRhWwCQi+kl30ANPReOqIsjxtLzJ+nISEMEdNygzWMTFO585QkzcauFeAaJdAvIOZGELkhztANPaDSPEQaJ/NiCBMgehLjIDn0O1tdJiQIFBPamMNe2lEkY8RobTDqCRbLc4aOepP+Vkkcv74kv6Z4OwJci3u+joSs16RWRuVmbXtCmaRXRezrRJ/EEh90CbjImRjFmF6lXnbRYazPj2mIF/z+geEWGmxw3PBiqzDkoj73P2DmqrpaKu71DOvjZU24nWqxe0GX+6FzbkPO/ZsaZnFfAxiRz+nmkwOUj3Ic3EdRyfGKqVc98fd25JtIxcCB7zArop5zxxax4r5NJ6TmHfKMY/Miph36wp5p4RsJwT/CXadBwegi8Eb+ZWK4nswHB0H3fSY3oGud0pwvY+iJxJgvrrPG7lRysyGra0adMh9oQ5Z59QhZJ6T0YzFh1zLPkabCKEiqwa62MPr2uoDJxI2VU+ci2y0JeFfzLYe2mdELjGTYaPVbOUuryAbjrehB/Ey9RwbEZQu6vCgcksSPBCqKicfUIIt851JcPJGmkc3lNsJpI+SIcf6GQfD/AEq7bSy1qS4FZU2qmIFobpoMc8qpIcdjU3PaxWFtLXvfKxbRxN+TiSkl5zjVa7DVEnibLvOuhvlrus6G5ETz3hUOU0wyWX8LYxAgiuhNF0qYWoPZXnrjtWd/oS16f7EphANBr3Px9Xgs7xkuJZTTveTvmQg+7xlk07cNOONtebuyHlp1Jm1yafNut+5q7PSaRXjo1TvxBuord5B5/nMcuArThZFuo5Oo6i15+B4J0GEjFqiKFWLtKhwThtFqCTzP6/739+m1zVUwM5Fudiy3Ar1NV+vvtLMflCIgc1+lrGu/gM=
\ No newline at end of file
diff --git a/doc/images/vhdl_cosim.png b/doc/images/vhdl_cosim.png
new file mode 100644
index 0000000..30bf058
Binary files /dev/null and b/doc/images/vhdl_cosim.png differ
diff --git a/doc/images/vhdl_sim.drawio b/doc/images/vhdl_sim.drawio
new file mode 100644
index 0000000..7a55f55
--- /dev/null
+++ b/doc/images/vhdl_sim.drawio
@@ -0,0 +1 @@
+1VhNc9owEP01HMvYku2YY4G0PSQzmZBMk14ywl5sNbJFhRxwf30lLH9hh6YJJEXMMN6nlbR6b7UID/Ak2XwVZBlf8hDYAFnhZoCnA4TOPEt9ayA3gHVWAJGgYQHZNTCjv8GAZlyU0RBWLUfJOZN02QYDnqYQyBZGhODrttuCs/aqSxJBB5gFhHXR7zSUsUE9y6o7vgGN4nJpVPYkpPQ2wComIV83IHw+wBPBuSyeks0EmCavJKYY9+WZ3ioyAal8yQD2azzNVpfXtw/0wcqt9d3Fj8knVMzyRFhmdjyjScaI5MJELfOSC8GzNAQ9mz3A43VMJcyWJNC9ayW+wmKZMNP9BEJSxeNnRqNUYZJrB7Oa6oPNs9uwK3JUVgFPQIpcuZgByDV8mozCvrHXtT5uKULckAaVjsTkRFTNXbOmHgxx/0Ci0yHxBlZyDmkQ7yHR+juJjMyBXfEVlZRrEgPFEYgGuxc7DgkNQ73SmBjaOyPaeiwoYxPOlNg6OLxw9UfjPJUNvGgKX0nBH6HR423bgZT128o6dldZx+lTFh1L2VFHPwhVfTAmFzLmEU8JO6/RcVvh2ueCa8q3uv4EKXNT7EgmeVt12FB513i+11MNXWNNN2bmrZEbo4hTB7effLUXnokA9uwZmzJLRARyj5/bL6YAVT3oUzuOgwuDO0duenvztsO2cxZCF/zQ6ct5H83xoXK+yucy591uztuoJ+e9Y6W822F2EkPwCPt+D17BLgF/EfRWlMCH+eIw7FY/03vY9d+TXP9U6okiWOR3TaMxSpv1sK11hDrkvbAO4Y+sQzb6SEVrFe8bPSevKHqrpGboFacqxKoaYHc0HKmSUDWnVRzcM2uI8ahu7fmLqM2UO1lTxfj6RPI6ZXcm9U2cnmDZxeg/K7u2cyp194CnDb3XRa7/tHmONew5YZ777AkrdnS0E4a6d8ZrWIAiVtGo/q8Xry5O/gbpOse7QSqzfl9R6FK/9cHnfwA=
\ No newline at end of file
diff --git a/doc/images/vhdl_sim.png b/doc/images/vhdl_sim.png
new file mode 100644
index 0000000..9e8c09f
Binary files /dev/null and b/doc/images/vhdl_sim.png differ
diff --git a/doc/qz2021_-_using_python_for_verification_of_digital_systems.md b/doc/qz2021_-_using_python_for_verification_of_digital_systems.md
new file mode 100644
index 0000000..efb1871
--- /dev/null
+++ b/doc/qz2021_-_using_python_for_verification_of_digital_systems.md
@@ -0,0 +1,498 @@
+---
+title: Using Python for Verification of Digital Systems
+subtitle: QZ 2021
+author:
+- Torsten Meißner
+- torsten.meissner@secunet.com
+date: February 2022
+...
+
+# Overview
+
+* Introduction
+
+* Functional Verification
+
+* Co-Simulation
+
+* Cocotb
+
+* Python Packages
+
+* Live Demo
+
+* Summary
+
+# Introduction
+
+## FPGA-Workflow
+
+1. Specification
+2. Design entry
+3. **Verification**
+4. Synthesis
+5. Device Mapping
+6. Place & Route
+7. Static Timing Analysis
+8. Programming file generation
+
+# Introduction
+
+## Design Entry
+
+1. Schematic Entry
+2. **Hardware Description Languages (RTL)**
+ * **(System)Verilog**
+ * **VHDL**
+3. High level languages
+ * System C
+ * Bluespec
+ * Chisel
+ * nmigen
+
+# Functional Verification
+
+1. **Functional Verification**
+ * **Simulation**
+ * Emulation
+2. Formal Verification
+ * Property checking
+ * Equivalence checking
+3. Lab Tests
+ * Target platform
+ * Logic Analyzer
+ * Oscilloscope
+
+# Functional Verification
+
+## Simulation
+
+* Executing of design description in a simulator
+* Test benches as infrastructure (HDL, C, etc.)
+* Reference models (HDL, C, etc.)
+* Directed & Random tests
+* Code & functional Coverage
+* Assertion Based Verification (PSL, SVA)
+* Verification Frameworks (UVM, OSVVM, vUnit, etc.)
+* Co-Simulation
+
+# HDL Simulation
+
+ ![](images/vhdl_sim.png)
+
+# Co-Simulation
+
+- Simulation with access to/from external program code
+- Linked per shared library
+
+## HDL Programming Interfaces
+
+- VHDL Procedural Interface (VHPI)
+- Verilog Procedural Interface (VPI)
+- Propitrary interfaces (FLI)
+- Access data in VHDL models in the simulator
+
+## Features
+
+- Static VHDL Design Data (Traverse hierarchy etc.)
+- Dynamic VHDL Objects (R/W values of VHDL objects)
+- Interaction and control (Callbacks as comm. mechanism between simulator user code)
+- Foreign model instantiation and intercommunication
+
+# Co-Simulation with SW reference Model
+
+![](images/vhdl_cosim.png)
+
+HDL testbench controls program flow
+
+# Cocotb
+
+- COroutine based COsimulation TestBench environment
+- Verifying HDL designs with Python
+- HDL normally only used for design, not the testbench
+- Simulator only used to execute DUT RTL description
+- Support many simulators (Free & propitrary)
+- Free & open-source, active community
+
+##
+
+- High-level, multi-paradigm language
+- Writing Python is fast - **very productive** language.
+- **Easy interfacing** to other languages from Python
+- **Huge library** of existing code to re-use
+- **Interpreted** - tests can be edited and re-run w/o recompiling the design
+- **Popular** - far more engineers know Python than Verilog / VHDL
+- Working and reliable packet manager (PyPI)
+
+# Cocotb Co-Simulation
+
+![](images/cocotb_cosim.png)
+
+Python testbench controls program flow
+
+# Cocotb Design Interaction
+
+## Accessing Design
+
+- *dut* as handle to toplevel instantiation
+- Access to toplevel and other signals with dot-notation
+
+~~~~ {.python .stretch}
+# Reference to toplevel clock input
+clk = dut.clk_i
+# Reference to signal in sub-unit
+cpu_pc = dut.cpu.regfile.pc
+~~~~
+
+## Read / Write Values from Signals
+
+- Via handle's *value* property
+- Direct R/W access through the hierarchy
+
+~~~~ {.python .stretch}
+# Via value property
+valid = dut.valid_i.value
+if valid.value == 0:
+ valid.value = 1
+# Direct access through hierarchy
+if dut.reset_i.value == 1:
+ dut.cpu.regfile.pc.value = 0
+~~~~
+
+# Cocotb concurrent & sequential execution
+
+## *async*: Mark Functions & Methods as Coroutines
+
+~~~~ {.python .stretch}
+async def reset(signal, time,):
+ signal.value = 0
+ # Block execution, wait for simulator time advances by 100 ns
+ await Timer(time, units='ns') # cocotb built-in class
+ signal.value = 1
+~~~~
+
+## *await*: Wait for other Coroutines or Simulator
+
+- Block on another coroutines execution
+- Pass control of execution back to simulator, allowing simulation time to advance
+
+~~~~ {.python .stretch}
+print("Hold reset")
+await reset(dut.reset_i)
+print("Released reset")
+~~~~
+
+# Cocotb concurrent execution
+
+## *start()*
+
+1. Schedules the new coroutine to be executed concurrently
+2. Yields control to allow the new task (& any other pending tasks) to run
+3. Resumes the calling task
+
+~~~~ {.python .stretch}
+await cocotb.start(reset(dut.reset_i, 100)
+
+await Timer(90, units='ns')
+print(f"Reset is still active: {dut.reset_i.value}")
+await Timer(15, units='ns')
+print(f"Reset has gone inactive: {dut.reset_i.value}")
+~~~~
+
+## *start_soon()*:
+
+- Schedules the new coroutine for future execution, after the calling task yields control
+
+~~~~ {.python .stretch}
+clock = Clock(dut.clk_i, 10, units="ns") # Create a clock, cocotb built-in class
+cocotb.start_soon(clock.start()) # Start the clock concurrently
+~~~~
+
+# Cocotb test functions
+
+## *@cocotb.test()* Decorator
+
+- Mark a callable which returns a coroutine as a test
+- Provides a test timeout
+- Allows to mark tests as skipped or expecting errors or failures
+- Tests are evaluated in the order of their definition in a test module
+
+~~~~ {.python .stretch}
+@cocotb.test()
+async def test_aes_init(dut):
+ """ Test AES initialization """
+...
+@cocotb.test()
+async def test_aes_enc(dut):
+ """ Test AES encryption """
+...
+# This test is skipped from execution
+@cocotb.test(skip=True)
+async def test_aes_enc(dut):
+ """ Test AES encryption """
+~~~~
+
+# Cocotb Triggers
+
+- Indicate when cocotb scheduler should resume coroutine execution
+- Triggers should awaited for by coroutines
+ - Cause execution of the current coroutine to pause
+ - Execution of paused coroutine will resumes when trigger fires
+- Triggers for simulator events, task synchronization etc.
+
+~~~~ {.python .stretch}
+# Wait for 100 ns
+await Timer(100, units='ns')
+
+# Wait for rising clock edge
+await RisingEdge(dut.clk_i)
+
+# Wait for 10 clock cycles
+await ClockCycles(dut.clk_i, 10)
+
+# Fires when first trigger in fires & returns its result
+t1 = Timer(10, units='ns')
+t2 = Timer(15, units='ns')
+t_ret = await First(t1, t2) # returns after 10 ns simulation time
+~~~~
+
+# Cocotb Example: Verifying an UART transmitter
+
+ ![](images/cocotb_uarttx.png)
+
+# Cocotb Example: Verifying an UART transmitter
+
+##
+
+![](images/vai_uart_wave.png)
+
+
+# Cocotb Example: Verifying an UART transmitter
+
+## Valid-Accept Driver Model
+
+~~~~ {.python .stretch}
+async def send(self, data, sync=True):
+ if sync:
+ await self._clkedge
+
+ self._valid.value = 1
+
+ if isinstance(self._data, list):
+ for i in range(len(self._data)):
+ self._data[i].value = data[i]
+
+ else:
+ self._data.value = data
+
+ while True:
+ await ReadOnly()
+ if self._accept.value:
+ break
+ await self._clkedge
+ await self._clkedge
+
+ self._valid.value = 0
+~~~~
+
+# Cocotb Example: Verifying an UART transmitter
+
+## UART Receiver Model
+
+~~~~ {.python .stretch}
+async def receive(self):
+ # Wait for frame start
+ await FallingEdge(self._txrx)
+
+ # Consume start bit
+ await self._get_start_bit()
+
+ # Receive data bits
+ self._rec = 0
+ for x in range(self._bits):
+ await self._wait_cycle()
+ await ReadOnly()
+ self._rec |= bool(self._txrx.value.integer) << x
+
+ if self._par:
+ # Consume parity bit
+ await self._get_parity_bit()
+
+ # Consume stop bit
+ await self._get_stop_bit()
+
+ return self._rec
+~~~~
+
+# Cocotb Example: Verifying an UART transmitter
+
+## Test function
+
+~~~~ {.python .stretch}
+@cocotb.test()
+async def test_uarttx(dut):
+
+ # Instantiate VAI driver & UART receiver
+ vai_driver = VaiDriver(dut.clk_i, dut.data_i, dut.valid_i, dut.accept_o)
+ uart_receiver = UartReceiver(dut.tx_o, dut.clk_i, 10, 8, True);
+
+ # Drive input defaults (setimmediatevalue to avoid x asserts)
+ dut.data_i.setimmediatevalue(0)
+ dut.valid_i.setimmediatevalue(0)
+
+ cocotb.start_soon(Clock(dut.clk_i, 10, units="ns").start()) # Start the clock
+ await reset(dut.reset_n_i, 100) # Block until reset() has completed
+
+ # Test 10 UART transmissions
+ for i in range(256):
+ await RisingEdge(dut.clk_i)
+ await vai_driver.send(i)
+ rec = await uart_receiver.receive();
+ assert rec == i, "UART sent data was incorrect on the {}th cycle".format(i)
+~~~~
+
+# Cocotb Example: Verifying an UART transmitter
+
+~~~~ {.shell .stretch}
+loading VPI module '/usr/local/lib/python3.9/dist-packages/cocotb/libs/libcocotbvpi_ghdl.so'
+ -.--ns INFO cocotb.gpi ../gpi/GpiCommon.cpp:99 in gpi_print_registered_impl VPI registered
+VPI module loaded!
+ 0.00ns INFO Running on GHDL version 2.0.0-dev (v1.0.0-974-g0e46300c) [Dunoon edition]
+ 0.00ns INFO Running tests with cocotb v1.7.0.dev0 from /usr/local/lib/python3.9/...
+ 0.00ns INFO Seeding Python random module with 1644512771
+ 0.00ns INFO Found test tb_uarttx.test_uarttx
+ 0.00ns INFO running test_uarttx (1/1)
+ First simple test
+ 0.00ns INFO Valid-accept driver
+ 0.00ns INFO cocotbext-vai version 0.0.1
+ 0.00ns INFO Copyright (c) 2022 Torsten Meissner
+ 0.00ns INFO UART receiver
+ 0.00ns INFO cocotbext-uart version 0.0.1
+ 0.00ns INFO Copyright (c) 2022 Torsten Meissner
+ 100.00ns INFO Released reset
+ 110.00ns INFO Send data: 0xb6
+ ...
+ 11160.00ns INFO Received data: 0xd8
+ 11160.00ns INFO test_uarttx passed
+ 11160.00ns INFO **********************************************************************
+ ** TEST STATUS SIM TIME (ns) REAL TIME (s)
+ **********************************************************************
+ ** tb_uarttx.test_uarttx PASS 11160.00 0.21
+ **********************************************************************
+ ** TESTS=1 PASS=1 FAIL=0 SKIP=0 11160.00 0.22
+ **********************************************************************
+~~~~
+
+# Python Packages
+
+## Cocotb related
+
+- Reusable packages for cocotb testbenches
+- Bus protocols, reference models etc.
+- Verification libraries
+ - pyuvm
+ - cocotb-coverage
+ - umv-python
+- Depending on cocotb
+
+## Python generic
+
+- Generic Python packages useful for verification
+ - pyvsc
+ - pyucis
+- Whole Python ecosystem
+- Not depending on cocotb
+
+
+# Python Packages: pyvsc
+
+## Python library for Verification Stimulus and Coverage
+
+- Random verification-stimulus generation
+- Functional coverage collection
+- Implemented in pure Python
+- Uses Boolector SMT-solver for solving user-defined constraints
+
+~~~~ {.python .stretch}
+@vsc.randobj
+class my_cr():
+ def __init__(self):
+ self.a = vsc.rand_bit_t(8)
+ self.b = vsc.rand_bit_t(8)
+
+ @vsc.constraint
+ def ab_c(self):
+ self.a != 0
+ self.a <= self.b
+ self.b in vsc.rangelist(1,2,4,8)
+~~~~
+
+# Live Demo
+
+## UART transmitter & receiver
+- Simple tests using self written Python models for VAI & UART
+
+## Wishbone slave with local SRAM interface
+- Using cocotbext-wishbone package from PyPI
+
+## AES128 en- and decryption
+- Using pyvsc for constrained random & functional coverage
+- Using Pycrypto for AES reference
+
+# Summary
+
+- Easy to use
+- Good documentation
+- In active development with regularly releases
+- Free and open-source
+- Allows Python SW-developers to verify digital systems
+- Supports all major simulators used by FPGA teams
+
+## Presentations code examples
+
+* https://github.com/tmeissner/cocotb_with_ghdl
+
+## References
+
+* https://github.com/cocotb/cocotb
+* https://github.com/fvutils/pyvsc
+* https://github.com/wallento/cocotbext-wishbone
+
+
+# Extras: Accessing signals
+
+## *dut.signal.value = 1*
+
+- Value is stored by the Scheduler
+- All stored values are written at the same time at the end of the current simulator time step
+
+## *.setimmediatevalue()*
+
+- Value is assigned to this simulation object immediately
+
+## Access to elements of indexable objects (arrays etc.)
+
+~~~~ {.python .stretch}
+dut.some_array[0].value = 1
+~~~~
+
+- Bit order depends on the HDL object (*to* or *downto*)
+
+# Extras: Accessing signals
+
+## Reading synchronous signals
+
+- Returns after clock changes, but no sympathetic signals changed yet
+- Sampling any signal here returns values settled during previous clock cycle
+- Equivalent to registered processes in HDLs
+
+## *ReadOnly()*
+
+- Triggers in the postpone phase
+- All signals have settled
+- No more updates may occur on the clock edge event
+- Sampling any signal here returns values settled current clock cycle
+
+# Extras: Accessing signals
+
+![](images/readonly.png)
diff --git a/doc/template/template.tex b/doc/template/template.tex
new file mode 100644
index 0000000..922e0a6
--- /dev/null
+++ b/doc/template/template.tex
@@ -0,0 +1,191 @@
+\documentclass[usenames,dvipsnames,10pt,aspectratio=169]{beamer}
+\usepackage{fontspec}
+\setmainfont{Liberation Sans}
+\setmonofont{Liberation Mono}
+%\usepackage[margin=1in]{geometry}
+\usepackage{hyperref}
+\PassOptionsToPackage{usenames,dvipsnames}{color} % color is loaded by hyperref
+\hypersetup{unicode=true,
+$if(title-meta)$
+ pdftitle={$title-meta$},
+$endif$
+$if(author-meta)$
+ pdfauthor={$author-meta$},
+$endif$
+$if(keywords)$
+ pdfkeywords={$for(keywords)$$keywords$$sep$; $endfor$},
+$endif$
+ colorlinks=true,
+ linkcolor=$if(linkcolor)$$linkcolor$$else$Maroon$endif$,
+ citecolor=$if(citecolor)$$citecolor$$else$Blue$endif$,
+ urlcolor=$if(urlcolor)$$urlcolor$$else$Blue$endif$,
+ breaklinks=true}
+\urlstyle{same} % don't use monospace font for urls
+
+\setbeamercolor{title}{fg=Maroon}
+\setbeamercolor{subtitle}{fg=MidnightBlue}
+\setbeamercolor{frametitle}{fg=MidnightBlue}
+\setbeamercolor{structure}{fg=MidnightBlue}
+
+% Don't show things we don't want to see
+\beamertemplatenavigationsymbolsempty
+
+% Slide number in lower right
+\setbeamertemplate{footline}{
+ \raisebox{5pt}{
+ \makebox[\paperwidth]{
+ \hfill\makebox[0.15\linewidth]{\color{Gray} \footnotesize Torsten Meißner}
+ \hfill\makebox[0.7\linewidth]{\color{Gray} \footnotesize \insertshorttitle}
+ \hfill\makebox[0.15\linewidth]{\color{Gray} \footnotesize \insertframenumber ~/ \inserttotalframenumber}
+ }
+ }
+ \hspace*{5pt}
+}
+
+% Color and shape of bullets
+\setbeamercolor{item}{fg=Gray}
+\setbeamercolor{subitem}{fg=Gray}
+% \setbeamercolor{itemize/enumerate subbody}{fg=gray}
+\setbeamertemplate{itemize item}{{\textendash}}
+\setbeamertemplate{itemize subitem}{{\textendash}}
+\setbeamerfont{itemize/enumerate subbody}{size=\footnotesize}
+\setbeamerfont{itemize/enumerate subitem}{size=\footnotesize}
+
+%\usepackage{fancyvrb}
+%\DefineVerbatimEnvironment{verbatim}{Verbatim}{frame=leftline, fontsize=\small, baselinestretch=1.17}
+%\VerbatimFootnotes % allows verbatim text in footnotes
+
+\usepackage{listings}
+\lstset{
+ basicstyle=\ttfamily\scriptsize,
+ keywordstyle=\color{Maroon},
+ stringstyle=\color{NavyBlue},
+ showstringspaces=false,
+ frame=leftline,
+ xleftmargin=5pt,
+ tabsize=2,
+}
+
+$if(highlighting-macros)$
+$highlighting-macros$
+$endif$
+$if(verbatim-in-note)$
+\usepackage{fancyvrb}
+\VerbatimFootnotes % allows verbatim text in footnotes
+$endif$
+$if(tables)$
+\usepackage{longtable,booktabs}
+\usepackage{caption}
+% These lines are needed to make table captions work with longtable:
+\makeatletter
+\def\fnum@table{\tablename~\thetable}
+\makeatother
+$endif$
+$if(graphics)$
+\usepackage{graphicx,grffile}
+\makeatletter
+\def\maxwidth{\ifdim\Gin@nat@width>\linewidth\linewidth\else\Gin@nat@width\fi}
+\def\maxheight{\ifdim\Gin@nat@height>\textheight0.8\textheight\else\Gin@nat@height\fi}
+\makeatother
+\centering
+% Scale images if necessary, so that they will not overflow the page
+% margins by default, and it is still possible to overwrite the defaults
+% using explicit options in \includegraphics[width, height, ...]{}
+\setkeys{Gin}{width=\maxwidth,height=\maxheight,keepaspectratio}
+$endif$
+
+% Prevent slide breaks in the middle of a paragraph:
+\widowpenalties 1 10000
+\raggedbottom
+
+\newif\ifbibliography
+$if(section-titles)$
+\AtBeginPart{
+ \let\insertpartnumber\relax
+ \let\partname\relax
+ \frame{\partpage}
+}
+\AtBeginSection{
+ \ifbibliography
+ \else
+ \let\insertsectionnumber\relax
+ \let\sectionname\relax
+ \frame{\sectionpage}
+ \fi
+}
+\AtBeginSubsection{
+ \let\insertsubsectionnumber\relax
+ \let\subsectionname\relax
+ \frame{\subsectionpage}
+}
+$endif$
+
+$if(links-as-notes)$
+% Make links footnotes instead of hotlinks:
+\renewcommand{\href}[2]{#2\footnote{\url{#1}}}
+$endif$
+$if(strikeout)$
+\usepackage[normalem]{ulem}
+% avoid problems with \sout in headers with hyperref:
+\pdfstringdefDisableCommands{\renewcommand{\sout}{}}
+$endif$
+\setlength{\emergencystretch}{3em} % prevent overfull lines
+\providecommand{\tightlist}{%
+ \setlength{\itemsep}{0pt}\setlength{\parskip}{0pt}}
+$if(numbersections)$
+\setcounter{secnumdepth}{5}
+$else$
+\setcounter{secnumdepth}{0}
+$endif$
+$if(dir)$
+\ifxetex
+ % load bidi as late as possible as it modifies e.g. graphicx
+ $if(latex-dir-rtl)$
+ \usepackage[RTLdocument]{bidi}
+ $else$
+ \usepackage{bidi}
+ $endif$
+\fi
+\ifnum 0\ifxetex 1\fi\ifluatex 1\fi=0 % if pdftex
+ \TeXXeTstate=1
+ \newcommand{\RL}[1]{\beginR #1\endR}
+ \newcommand{\LR}[1]{\beginL #1\endL}
+ \newenvironment{RTL}{\beginR}{\endR}
+ \newenvironment{LTR}{\beginL}{\endL}
+\fi
+$endif$
+
+$if(title)$
+\title{$title$}
+$endif$
+$if(subtitle)$
+\subtitle{$subtitle$}
+$endif$
+$if(author)$
+\author{$for(author)$$author$$sep$ \\ $endfor$}
+$endif$
+\date{$date$}
+
+\begin{document}
+$if(title)$
+\frame{\maketitle}
+$endif$
+
+$for(include-before)$
+$include-before$
+
+$endfor$
+
+$if(toc)$
+\begin{frame}
+\tableofcontents[hideallsubsections]
+\end{frame}
+
+$endif$
+$body$
+
+$for(include-after)$
+$include-after$
+
+$endfor$
+\end{document}