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 @@ + + +
DUT
(Verilog / VHDL)
DUT...
VPI
VPI
VHPI
VHPI
FLI
FLI
GPI
GPI
Scheduler
Embed
Embed
Extend
Extend
SchedulerPythonSimulator
Coroutine
Coroutine
Coroutine
Coroutine
Coroutine
Coroutine
Coroutine
Coroutine
Coroutine
Coroutine
Coroutine
Coroutine
Test
Viewer does not support full SVG 1.1
\ 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}