<SYSTEM_TASK:>
Given the following text description, write Python code to implement the functionality described below step by step
<END_TASK>
<USER_TASK:>
Description:
Step1:  \title{Logic Gate Primitives in myHDL}
\author{Steven K Armour}
\maketitle
<h1>Table of Contents<span class="tocSkip"></span></h1>
<div class="toc" style="margin-top
Step2:  Table of Digital Gate Symbols commonly used
\begin{figure}
\centerline{\includegraphics[width=10cm]{LogicGateSymbols.jpg}}
\caption{\label{fig
Step3:  Sympy Exspresion
Step5:  myHDL Module
Step6:  Verilog Conversion
Step7:  \begin{figure}
\centerline{\includegraphics[width=10cm]{WireHigh_RTL.png}}
\caption{\label{fig
Step8:  Board Constraint
Step9:  LED 0 (the furthest Right one above the buttons) will light up green
Wire Low
\begin{definition}\label{def
Step10:  Sympy Expression
Step12:  myHDL Module
Step13:  Verilog Conversion
Step14:  \begin{figure}
\centerline{\includegraphics[width=10cm]{WireLow_RTL.png}}
\caption{\label{fig
Step15:  Board Constraint
Step16:  Nothing will happen since the Low Signal on the PYNQ-Z1 is ground so LED 0 will remain off
Buffer
\begin{definition}\label{def
Step17:  Sympy Expression
Step19:  myHDL Module
Step21:  ## myHDL Testing
 Every module (WireHigh and WireLow are just too primitive to test) should be tested with a Testbench in python. This test does not confirm that the module meets the requirements of synthesization in Verilog/VHDL but confirms that the behavior of the myHDL module under test (DUT) behavior wise conforms to the desired behavior. 
Because of the data analysis ability of python to full analysis the test output in the same framework that the test, let alone module, was written in development time is decreased. This is one of the defining abilities of myHDL over other HDLs such as Verilog/VHDL
Synthesization in the world of HDL refers to the ability to turn HDL  code into Hardware via an FPGA or a dedicated circuit (typically called an ASIC). It is for that reason that HDL codeing is not pure software nor pure hardware but rather a hybrid of the two. And why HDL coding has high constraints then all other coding seeing as the HDL must meet Behavior and Timing of software but must also meet the hardware synthesis requirements of Power, Physical Size, Implantability, and more
Step22:  Verilog Conversion
Step24:  \begin{figure}
\centerline{\includegraphics[width=10cm]{BufferGate_RTL.png}}
\caption{\label{fig
Step25:  PYNQ-Z1 Deployment
Board Circuit
Step26:  Board Constraint File
Step27:  Video of Deployment
BUFFER Gate myHDL PYNQ-Z1 (YouTube)
NOT
\begin{definition}\label{def
Step28:  Sympy Expression
Step30:  myHDL Module
Step32:  myHDL Testing
Step33:  Verilog Conversion
Step35:  \begin{figure}
\centerline{\includegraphics[width=10cm]{NotGate_RTL.png}}
\caption{\label{fig
Step36:  PYNQ-Z1 Deployment
Board Circuit
Step37:  Board Constraint
Step38:  Video of Deployment
NOT Gate myHDL PYNQ-Z1 (YouTube)
AND
\begin{definition}\label{def
Step39:  Sympy Expression
Step41:  myHDL Module
Step43:  myHDL Testing
Step44:  Verilog Conversion
Step46:  \begin{figure}
\centerline{\includegraphics[width=10cm]{AndGate_RTL.png}}
\caption{\label{fig
Step47:  PYNQ-Z1 Deployment
Board Circuit
Step48:  Board Constraint
Step49:  Video of Deployment
AND Gate myHDL PYNQ-Z1 (YouTube)
OR
\begin{definition}\label{def
Step50:  Sympy Expression
Step52:  myHDL Module
Step54:  myHDL Testing
Step55:  Verilog Conversion
Step57:  \begin{figure}
\centerline{\includegraphics[width=10cm]{OrGate_RTL.png}}
\caption{\label{fig
Step58:  PYNQ-Z1 Deployment
Board Circuit
Step59:  Board Constraint
Step60:  Video of Deployment
OR Gate myHDL PYNQ-Z1 (YouTube)
XOR
\begin{definition}\label{def
Step61:  Sympy Expression
Step63:  myHDL Module
Step65:  myHDL Testing
Step66:  Verilog Conversion
Step68:  \begin{figure}
\centerline{\includegraphics[width=10cm]{XorGate_RTL.png}}
\caption{\label{fig
Step69:  PYNQ-Z1 Deployment
Board Circuit
Step70:  Board Constraint
Step71:  Video of Deployment
XOR Gate myHDL PYNQ-Z1 (YouTube)
NAND
\begin{definition}\label{def
Step72:  Sympy Expression
Step74:  myHDL Module
Step76:  myHDL Testing
Step77:  Verilog Conversion
Step79:  myHDL to Verilog Testbench
Step80:  \begin{figure}
\centerline{\includegraphics[width=10cm]{NAndGate_RTL.png}}
\caption{\label{fig
Step81:  Board Constraint
Step82:  Video of Deployment
NAND Gate myHDL PYNQ-Z1 (YouTube)
NOR
\begin{definition}\label{def
Step83:  Sympy Expression
Step85:  myHDL Module
Step87:  myHDL Testing
Step88:  Verilog Conversion
Step90:  \begin{figure}
\centerline{\includegraphics[width=10cm]{NOrGate_RTL.png}}
\caption{\label{fig
Step91:  PYNQ-Z1 Deployment
Board Circuit
Step92:  Board Constraint
Step93:  Video of Deployment
AND Gate myHDL PYNQ-Z1 (YouTube)
XNOR
\begin{definition}\label{def
Step94:  Sympy Expression
Step96:  myHDL Module
Step98:  myHDL Testing
Step99:  Verilog Conversion
Step101:  \begin{figure}
\centerline{\includegraphics[width=10cm]{XNOrGate_RTL.png}}
\caption{\label{fig
Step102:  PYNQ-Z1 Deployment
Board Circuit
Step103:  Board Constraint
<ASSISTANT_TASK:>
Python Code:
#This notebook also uses the `(some) LaTeX environments for Jupyter`
#https://github.com/ProfFan/latex_envs wich is part of the
#jupyter_contrib_nbextensions package
from myhdl import *
from myhdlpeek import Peeker
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
%matplotlib inline
from sympy import *
init_printing()
import itertools
#EE drawing tools in python from https://cdelker.bitbucket.io/SchemDraw/
import SchemDraw as schem
import SchemDraw.elements as e
import SchemDraw.logic as l
#https://github.com/jrjohansson/version_information
%load_ext version_information
%version_information myhdl, myhdlpeek, numpy, pandas, matplotlib, sympy, itertools, SchemDraw
#helper  functions to read in the .v and .vhd generated files into python
def VerilogTextReader(loc, printresult=True):
    with open(f'{loc}.v', 'r') as vText:
        VerilogText=vText.read()
    if printresult:
        print(f'***Verilog modual from {loc}.v***\n\n', VerilogText)
    return VerilogText
def VHDLTextReader(loc, printresult=True):
    with open(f'{loc}.vhd', 'r') as vText:
        VerilogText=vText.read()
    if printresult:
        print(f'***VHDL modual from {loc}.vhd***\n\n', VerilogText)
    return VerilogText
def ConstraintXDCTextReader(loc, printresult=True):
    with open(f'{loc}.xdc', 'r') as xdcText:
        ConstraintText=xdcText.read()
    if printresult:
        print(f'***Constraint file from {loc}.xdc***\n\n', ConstraintText)
    return ConstraintText
def TruthTabelGenrator(BoolSymFunc):
    
    Function to generate a truth table from a sympy boolian expression
    BoolSymFunc: sympy boolian expression
    return TT: a Truth table stored in a pandas dataframe
    
    colsL=sorted([i for i in list(BoolSymFunc.rhs.atoms())], key=lambda x:x.sort_key())
    colsR=sorted([i for i in list(BoolSymFunc.lhs.atoms())], key=lambda x:x.sort_key())
    bitwidth=len(colsL)
    cols=colsL+colsR; cols
    
    TT=pd.DataFrame(columns=cols, index=range(2**bitwidth))
    
    for i in range(2**bitwidth):
        inputs=[int(j) for j in list(np.binary_repr(i, bitwidth))]
        outputs=BoolSymFunc.rhs.subs({j:v for j, v in zip(colsL, inputs)})
        inputs.append(int(bool(outputs)))
        TT.iloc[i]=inputs
    
    return TT
    
    
    
Explanation: \title{Logic Gate Primitives in myHDL}
\author{Steven K Armour}
\maketitle
<h1>Table of Contents<span class="tocSkip"></span></h1>
<div class="toc" style="margin-top: 1em;"><ul class="toc-item"><li><span><a href="#Libraries-and-Helper-functions" data-toc-modified-id="Libraries-and-Helper-functions-1"><span class="toc-item-num">1&nbsp;&nbsp;</span>Libraries and Helper functions</a></span></li><li><span><a href="#Table-of-Digital-Gate-Symbols-commonly-used" data-toc-modified-id="Table-of-Digital-Gate-Symbols-commonly-used-2"><span class="toc-item-num">2&nbsp;&nbsp;</span>Table of Digital Gate Symbols commonly used</a></span></li><li><span><a href="#How-to-load-output-Verilog-from-myHDL-to-Xilinx's-Vivado" data-toc-modified-id="How-to-load-output-Verilog-from-myHDL-to-Xilinx's-Vivado-3"><span class="toc-item-num">3&nbsp;&nbsp;</span>How to load output Verilog from myHDL to Xilinx's Vivado</a></span></li><li><span><a href="#Wire-High" data-toc-modified-id="Wire-High-4"><span class="toc-item-num">4&nbsp;&nbsp;</span>Wire High</a></span><ul class="toc-item"><li><span><a href="#Sympy-Exspresion" data-toc-modified-id="Sympy-Exspresion-4.1"><span class="toc-item-num">4.1&nbsp;&nbsp;</span>Sympy Exspresion</a></span></li><li><span><a href="#myHDL-Module" data-toc-modified-id="myHDL-Module-4.2"><span class="toc-item-num">4.2&nbsp;&nbsp;</span>myHDL Module</a></span></li><li><span><a href="#Verilog-Conversion" data-toc-modified-id="Verilog-Conversion-4.3"><span class="toc-item-num">4.3&nbsp;&nbsp;</span>Verilog Conversion</a></span></li><li><span><a href="#PYNQ-Z1-Deployment" data-toc-modified-id="PYNQ-Z1-Deployment-4.4"><span class="toc-item-num">4.4&nbsp;&nbsp;</span>PYNQ-Z1 Deployment</a></span><ul class="toc-item"><li><span><a href="#Board-Circuit" data-toc-modified-id="Board-Circuit-4.4.1"><span class="toc-item-num">4.4.1&nbsp;&nbsp;</span>Board Circuit</a></span></li><li><span><a href="#Board-Constraint" data-toc-modified-id="Board-Constraint-4.4.2"><span class="toc-item-num">4.4.2&nbsp;&nbsp;</span>Board Constraint</a></span></li></ul></li></ul></li><li><span><a href="#Wire-Low" data-toc-modified-id="Wire-Low-5"><span class="toc-item-num">5&nbsp;&nbsp;</span>Wire Low</a></span><ul class="toc-item"><li><span><a href="#Sympy-Expression" data-toc-modified-id="Sympy-Expression-5.1"><span class="toc-item-num">5.1&nbsp;&nbsp;</span>Sympy Expression</a></span></li><li><span><a href="#myHDL-Module" data-toc-modified-id="myHDL-Module-5.2"><span class="toc-item-num">5.2&nbsp;&nbsp;</span>myHDL Module</a></span></li><li><span><a href="#Verilog-Conversion" data-toc-modified-id="Verilog-Conversion-5.3"><span class="toc-item-num">5.3&nbsp;&nbsp;</span>Verilog Conversion</a></span></li><li><span><a href="#PYNQ-Z1-Deployment" data-toc-modified-id="PYNQ-Z1-Deployment-5.4"><span class="toc-item-num">5.4&nbsp;&nbsp;</span>PYNQ-Z1 Deployment</a></span><ul class="toc-item"><li><span><a href="#Board-Circuit" data-toc-modified-id="Board-Circuit-5.4.1"><span class="toc-item-num">5.4.1&nbsp;&nbsp;</span>Board Circuit</a></span></li><li><span><a href="#Board-Constraint" data-toc-modified-id="Board-Constraint-5.4.2"><span class="toc-item-num">5.4.2&nbsp;&nbsp;</span>Board Constraint</a></span></li></ul></li></ul></li><li><span><a href="#Buffer" data-toc-modified-id="Buffer-6"><span class="toc-item-num">6&nbsp;&nbsp;</span>Buffer</a></span><ul class="toc-item"><li><span><a href="#Sympy-Expression" data-toc-modified-id="Sympy-Expression-6.1"><span class="toc-item-num">6.1&nbsp;&nbsp;</span>Sympy Expression</a></span></li><li><span><a href="#myHDL-Module" data-toc-modified-id="myHDL-Module-6.2"><span class="toc-item-num">6.2&nbsp;&nbsp;</span>myHDL Module</a></span></li><li><span><a href="#myHDL-Testing" data-toc-modified-id="myHDL-Testing-6.3"><span class="toc-item-num">6.3&nbsp;&nbsp;</span>myHDL Testing</a></span></li><li><span><a href="#Verilog-Conversion" data-toc-modified-id="Verilog-Conversion-6.4"><span class="toc-item-num">6.4&nbsp;&nbsp;</span>Verilog Conversion</a></span></li><li><span><a href="#myHDL-to-Verilog-Testbench" data-toc-modified-id="myHDL-to-Verilog-Testbench-6.5"><span class="toc-item-num">6.5&nbsp;&nbsp;</span>myHDL to Verilog Testbench</a></span></li><li><span><a href="#PYNQ-Z1-Deployment" data-toc-modified-id="PYNQ-Z1-Deployment-6.6"><span class="toc-item-num">6.6&nbsp;&nbsp;</span>PYNQ-Z1 Deployment</a></span><ul class="toc-item"><li><span><a href="#Board-Circuit" data-toc-modified-id="Board-Circuit-6.6.1"><span class="toc-item-num">6.6.1&nbsp;&nbsp;</span>Board Circuit</a></span></li><li><span><a href="#Board-Constraint-File" data-toc-modified-id="Board-Constraint-File-6.6.2"><span class="toc-item-num">6.6.2&nbsp;&nbsp;</span>Board Constraint File</a></span></li><li><span><a href="#Video-of-Deployment" data-toc-modified-id="Video-of-Deployment-6.6.3"><span class="toc-item-num">6.6.3&nbsp;&nbsp;</span>Video of Deployment</a></span></li></ul></li></ul></li><li><span><a href="#NOT" data-toc-modified-id="NOT-7"><span class="toc-item-num">7&nbsp;&nbsp;</span>NOT</a></span><ul class="toc-item"><li><span><a href="#Sympy-Expression" data-toc-modified-id="Sympy-Expression-7.1"><span class="toc-item-num">7.1&nbsp;&nbsp;</span>Sympy Expression</a></span></li><li><span><a href="#myHDL-Module" data-toc-modified-id="myHDL-Module-7.2"><span class="toc-item-num">7.2&nbsp;&nbsp;</span>myHDL Module</a></span></li><li><span><a href="#myHDL-Testing" data-toc-modified-id="myHDL-Testing-7.3"><span class="toc-item-num">7.3&nbsp;&nbsp;</span>myHDL Testing</a></span></li><li><span><a href="#Verilog-Conversion" data-toc-modified-id="Verilog-Conversion-7.4"><span class="toc-item-num">7.4&nbsp;&nbsp;</span>Verilog Conversion</a></span></li><li><span><a href="#myHDL-to-Verilog-Testbench" data-toc-modified-id="myHDL-to-Verilog-Testbench-7.5"><span class="toc-item-num">7.5&nbsp;&nbsp;</span>myHDL to Verilog Testbench</a></span></li><li><span><a href="#PYNQ-Z1-Deployment" data-toc-modified-id="PYNQ-Z1-Deployment-7.6"><span class="toc-item-num">7.6&nbsp;&nbsp;</span>PYNQ-Z1 Deployment</a></span><ul class="toc-item"><li><span><a href="#Board-Circuit" data-toc-modified-id="Board-Circuit-7.6.1"><span class="toc-item-num">7.6.1&nbsp;&nbsp;</span>Board Circuit</a></span></li><li><span><a href="#Board-Constraint" data-toc-modified-id="Board-Constraint-7.6.2"><span class="toc-item-num">7.6.2&nbsp;&nbsp;</span>Board Constraint</a></span></li><li><span><a href="#Video-of-Deployment" data-toc-modified-id="Video-of-Deployment-7.6.3"><span class="toc-item-num">7.6.3&nbsp;&nbsp;</span>Video of Deployment</a></span></li></ul></li></ul></li><li><span><a href="#AND" data-toc-modified-id="AND-8"><span class="toc-item-num">8&nbsp;&nbsp;</span>AND</a></span><ul class="toc-item"><li><span><a href="#Sympy-Expression" data-toc-modified-id="Sympy-Expression-8.1"><span class="toc-item-num">8.1&nbsp;&nbsp;</span>Sympy Expression</a></span></li><li><span><a href="#myHDL-Module" data-toc-modified-id="myHDL-Module-8.2"><span class="toc-item-num">8.2&nbsp;&nbsp;</span>myHDL Module</a></span></li><li><span><a href="#myHDL-Testing" data-toc-modified-id="myHDL-Testing-8.3"><span class="toc-item-num">8.3&nbsp;&nbsp;</span>myHDL Testing</a></span></li><li><span><a href="#Verilog-Conversion" data-toc-modified-id="Verilog-Conversion-8.4"><span class="toc-item-num">8.4&nbsp;&nbsp;</span>Verilog Conversion</a></span></li><li><span><a href="#myHDL-to-Verilog-Testbench" data-toc-modified-id="myHDL-to-Verilog-Testbench-8.5"><span class="toc-item-num">8.5&nbsp;&nbsp;</span>myHDL to Verilog Testbench</a></span></li><li><span><a href="#PYNQ-Z1-Deployment" data-toc-modified-id="PYNQ-Z1-Deployment-8.6"><span class="toc-item-num">8.6&nbsp;&nbsp;</span>PYNQ-Z1 Deployment</a></span><ul class="toc-item"><li><span><a href="#Board-Circuit" data-toc-modified-id="Board-Circuit-8.6.1"><span class="toc-item-num">8.6.1&nbsp;&nbsp;</span>Board Circuit</a></span></li><li><span><a href="#Board-Constraint" data-toc-modified-id="Board-Constraint-8.6.2"><span class="toc-item-num">8.6.2&nbsp;&nbsp;</span>Board Constraint</a></span></li><li><span><a href="#Video-of-Deployment" data-toc-modified-id="Video-of-Deployment-8.6.3"><span class="toc-item-num">8.6.3&nbsp;&nbsp;</span>Video of Deployment</a></span></li></ul></li></ul></li><li><span><a href="#OR" data-toc-modified-id="OR-9"><span class="toc-item-num">9&nbsp;&nbsp;</span>OR</a></span><ul class="toc-item"><li><span><a href="#Sympy-Expression" data-toc-modified-id="Sympy-Expression-9.1"><span class="toc-item-num">9.1&nbsp;&nbsp;</span>Sympy Expression</a></span></li><li><span><a href="#myHDL-Module" data-toc-modified-id="myHDL-Module-9.2"><span class="toc-item-num">9.2&nbsp;&nbsp;</span>myHDL Module</a></span></li><li><span><a href="#myHDL-Testing" data-toc-modified-id="myHDL-Testing-9.3"><span class="toc-item-num">9.3&nbsp;&nbsp;</span>myHDL Testing</a></span></li><li><span><a href="#Verilog-Conversion" data-toc-modified-id="Verilog-Conversion-9.4"><span class="toc-item-num">9.4&nbsp;&nbsp;</span>Verilog Conversion</a></span></li><li><span><a href="#myHDL-to-Verilog-Testbench" data-toc-modified-id="myHDL-to-Verilog-Testbench-9.5"><span class="toc-item-num">9.5&nbsp;&nbsp;</span>myHDL to Verilog Testbench</a></span></li><li><span><a href="#PYNQ-Z1-Deployment" data-toc-modified-id="PYNQ-Z1-Deployment-9.6"><span class="toc-item-num">9.6&nbsp;&nbsp;</span>PYNQ-Z1 Deployment</a></span><ul class="toc-item"><li><span><a href="#Board-Circuit" data-toc-modified-id="Board-Circuit-9.6.1"><span class="toc-item-num">9.6.1&nbsp;&nbsp;</span>Board Circuit</a></span></li><li><span><a href="#Board-Constraint" data-toc-modified-id="Board-Constraint-9.6.2"><span class="toc-item-num">9.6.2&nbsp;&nbsp;</span>Board Constraint</a></span></li><li><span><a href="#Video-of-Deployment" data-toc-modified-id="Video-of-Deployment-9.6.3"><span class="toc-item-num">9.6.3&nbsp;&nbsp;</span>Video of Deployment</a></span></li></ul></li></ul></li><li><span><a href="#XOR" data-toc-modified-id="XOR-10"><span class="toc-item-num">10&nbsp;&nbsp;</span>XOR</a></span><ul class="toc-item"><li><span><a href="#Sympy-Expression" data-toc-modified-id="Sympy-Expression-10.1"><span class="toc-item-num">10.1&nbsp;&nbsp;</span>Sympy Expression</a></span></li><li><span><a href="#myHDL-Module" data-toc-modified-id="myHDL-Module-10.2"><span class="toc-item-num">10.2&nbsp;&nbsp;</span>myHDL Module</a></span></li><li><span><a href="#myHDL-Testing" data-toc-modified-id="myHDL-Testing-10.3"><span class="toc-item-num">10.3&nbsp;&nbsp;</span>myHDL Testing</a></span></li><li><span><a href="#Verilog-Conversion" data-toc-modified-id="Verilog-Conversion-10.4"><span class="toc-item-num">10.4&nbsp;&nbsp;</span>Verilog Conversion</a></span></li><li><span><a href="#myHDL-to-Verilog-Testbench" data-toc-modified-id="myHDL-to-Verilog-Testbench-10.5"><span class="toc-item-num">10.5&nbsp;&nbsp;</span>myHDL to Verilog Testbench</a></span></li><li><span><a href="#PYNQ-Z1-Deployment" data-toc-modified-id="PYNQ-Z1-Deployment-10.6"><span class="toc-item-num">10.6&nbsp;&nbsp;</span>PYNQ-Z1 Deployment</a></span><ul class="toc-item"><li><span><a href="#Board-Circuit" data-toc-modified-id="Board-Circuit-10.6.1"><span class="toc-item-num">10.6.1&nbsp;&nbsp;</span>Board Circuit</a></span></li><li><span><a href="#Board-Constraint" data-toc-modified-id="Board-Constraint-10.6.2"><span class="toc-item-num">10.6.2&nbsp;&nbsp;</span>Board Constraint</a></span></li><li><span><a href="#Video-of-Deployment" data-toc-modified-id="Video-of-Deployment-10.6.3"><span class="toc-item-num">10.6.3&nbsp;&nbsp;</span>Video of Deployment</a></span></li></ul></li></ul></li><li><span><a href="#NAND" data-toc-modified-id="NAND-11"><span class="toc-item-num">11&nbsp;&nbsp;</span>NAND</a></span><ul class="toc-item"><li><span><a href="#Sympy-Expression" data-toc-modified-id="Sympy-Expression-11.1"><span class="toc-item-num">11.1&nbsp;&nbsp;</span>Sympy Expression</a></span></li><li><span><a href="#myHDL-Module" data-toc-modified-id="myHDL-Module-11.2"><span class="toc-item-num">11.2&nbsp;&nbsp;</span>myHDL Module</a></span></li><li><span><a href="#myHDL-Testing" data-toc-modified-id="myHDL-Testing-11.3"><span class="toc-item-num">11.3&nbsp;&nbsp;</span>myHDL Testing</a></span></li><li><span><a href="#Verilog-Conversion" data-toc-modified-id="Verilog-Conversion-11.4"><span class="toc-item-num">11.4&nbsp;&nbsp;</span>Verilog Conversion</a></span></li><li><span><a href="#myHDL-to-Verilog-Testbench" data-toc-modified-id="myHDL-to-Verilog-Testbench-11.5"><span class="toc-item-num">11.5&nbsp;&nbsp;</span>myHDL to Verilog Testbench</a></span></li><li><span><a href="#PYNQ-Z1-Deyployment" data-toc-modified-id="PYNQ-Z1-Deyployment-11.6"><span class="toc-item-num">11.6&nbsp;&nbsp;</span>PYNQ-Z1 Deyployment</a></span><ul class="toc-item"><li><span><a href="#Board-Circuit" data-toc-modified-id="Board-Circuit-11.6.1"><span class="toc-item-num">11.6.1&nbsp;&nbsp;</span>Board Circuit</a></span></li><li><span><a href="#Board-Constraint" data-toc-modified-id="Board-Constraint-11.6.2"><span class="toc-item-num">11.6.2&nbsp;&nbsp;</span>Board Constraint</a></span></li><li><span><a href="#Video-of-Deployment" data-toc-modified-id="Video-of-Deployment-11.6.3"><span class="toc-item-num">11.6.3&nbsp;&nbsp;</span>Video of Deployment</a></span></li></ul></li></ul></li><li><span><a href="#NOR" data-toc-modified-id="NOR-12"><span class="toc-item-num">12&nbsp;&nbsp;</span>NOR</a></span><ul class="toc-item"><li><span><a href="#Sympy-Expression" data-toc-modified-id="Sympy-Expression-12.1"><span class="toc-item-num">12.1&nbsp;&nbsp;</span>Sympy Expression</a></span></li><li><span><a href="#myHDL-Module" data-toc-modified-id="myHDL-Module-12.2"><span class="toc-item-num">12.2&nbsp;&nbsp;</span>myHDL Module</a></span></li><li><span><a href="#myHDL-Testing" data-toc-modified-id="myHDL-Testing-12.3"><span class="toc-item-num">12.3&nbsp;&nbsp;</span>myHDL Testing</a></span></li><li><span><a href="#Verilog-Conversion" data-toc-modified-id="Verilog-Conversion-12.4"><span class="toc-item-num">12.4&nbsp;&nbsp;</span>Verilog Conversion</a></span></li><li><span><a href="#myHDL-to-Verilog-Testbench" data-toc-modified-id="myHDL-to-Verilog-Testbench-12.5"><span class="toc-item-num">12.5&nbsp;&nbsp;</span>myHDL to Verilog Testbench</a></span></li><li><span><a href="#PYNQ-Z1-Deployment" data-toc-modified-id="PYNQ-Z1-Deployment-12.6"><span class="toc-item-num">12.6&nbsp;&nbsp;</span>PYNQ-Z1 Deployment</a></span><ul class="toc-item"><li><span><a href="#Board-Circuit" data-toc-modified-id="Board-Circuit-12.6.1"><span class="toc-item-num">12.6.1&nbsp;&nbsp;</span>Board Circuit</a></span></li><li><span><a href="#Board-Constraint" data-toc-modified-id="Board-Constraint-12.6.2"><span class="toc-item-num">12.6.2&nbsp;&nbsp;</span>Board Constraint</a></span></li><li><span><a href="#Video-of-Deployment" data-toc-modified-id="Video-of-Deployment-12.6.3"><span class="toc-item-num">12.6.3&nbsp;&nbsp;</span>Video of Deployment</a></span></li></ul></li></ul></li><li><span><a href="#XNOR" data-toc-modified-id="XNOR-13"><span class="toc-item-num">13&nbsp;&nbsp;</span>XNOR</a></span><ul class="toc-item"><li><span><a href="#Sympy-Expression" data-toc-modified-id="Sympy-Expression-13.1"><span class="toc-item-num">13.1&nbsp;&nbsp;</span>Sympy Expression</a></span></li><li><span><a href="#myHDL-Module" data-toc-modified-id="myHDL-Module-13.2"><span class="toc-item-num">13.2&nbsp;&nbsp;</span>myHDL Module</a></span></li><li><span><a href="#myHDL-Testing" data-toc-modified-id="myHDL-Testing-13.3"><span class="toc-item-num">13.3&nbsp;&nbsp;</span>myHDL Testing</a></span></li><li><span><a href="#Verilog-Conversion" data-toc-modified-id="Verilog-Conversion-13.4"><span class="toc-item-num">13.4&nbsp;&nbsp;</span>Verilog Conversion</a></span></li><li><span><a href="#myHDL-to-Verilog-Testbench" data-toc-modified-id="myHDL-to-Verilog-Testbench-13.5"><span class="toc-item-num">13.5&nbsp;&nbsp;</span>myHDL to Verilog Testbench</a></span></li><li><span><a href="#PYNQ-Z1-Deployment" data-toc-modified-id="PYNQ-Z1-Deployment-13.6"><span class="toc-item-num">13.6&nbsp;&nbsp;</span>PYNQ-Z1 Deployment</a></span><ul class="toc-item"><li><span><a href="#Board-Circuit" data-toc-modified-id="Board-Circuit-13.6.1"><span class="toc-item-num">13.6.1&nbsp;&nbsp;</span>Board Circuit</a></span></li><li><span><a href="#Board-Constraint" data-toc-modified-id="Board-Constraint-13.6.2"><span class="toc-item-num">13.6.2&nbsp;&nbsp;</span>Board Constraint</a></span></li><li><span><a href="#Video-of-Deployment" data-toc-modified-id="Video-of-Deployment-13.6.3"><span class="toc-item-num">13.6.3&nbsp;&nbsp;</span>Video of Deployment</a></span></li></ul></li></ul></li></ul></div>
Libraries and Helper functions
End of explanation
d = schem.Drawing(unit=.5)
d.add(e.VDD, label='High')
d.add(e.LINE, l=d.unit*2, d='down')
d.add(e.DOT_OPEN, botlabel='$1$')
d.draw()
Explanation: Table of Digital Gate Symbols commonly used
\begin{figure}
\centerline{\includegraphics[width=10cm]{LogicGateSymbols.jpg}}
\caption{\label{fig:GateSyms} Table of selected Logic Gate Symbols found worldwide; http://www.nutsvolts.com/magazine/article/understanding_digital_buffer_gate_and_ic_circuits_part_1}
\end{figure}
How to load output Verilog from myHDL to Xilinx's Vivado
YouTube 
Wire High
\begin{definition}\label{def:Wire High}
A Wire to High is a Wire connected to the Highest reference voltage in a Digital Circuit with the Boolean equivalency of 
$$Y=1$$
that of always True
\end{definition}
End of explanation
Y=symbols('Y')
YEq=Eq(Y, 1); YEq
Explanation: Sympy Exspresion
End of explanation
#decorator to specify a myHDL module that can be converted
#to myHDL
@block
def WireHigh(Y):
    
    Wire to Constatnt High
    Input:
        None
    Output:
        Y(bool): output
    
    #create signal to High Source
    HSource=Signal(bool(1))
    
    #decorator for a compintorical senstvity
    @always_comb
    def logic():
        #internal function to specfiy Out is set to High Source
        Y.next=HSource
    
    #return all internal functions
    return instances()
Explanation: myHDL Module
End of explanation
#create output signal to bind to `WireHigh` Mod
Y=Signal(bool(0))
#Create instatnce of `WireHigh` and bind `Out` Signal to it
DUT=WireHigh(Y)
#Run convert on `DUT` instance of `WireHigh` to create Verilog/VHDL
DUT.convert()
#Read ouput `WireHigh.v` into notebook
VerilogTextReader('WireHigh');
Explanation: Verilog Conversion
End of explanation
d = schem.Drawing(unit=.5)
d.add(e.VDD, label='High')
d.add(e.LINE, l=d.unit*2, d='down')
d.add(e.DOT, rgtlabel='$1$')
d.add(e.LINE, d='down', l=d.unit*2)
d.add(e.LED, rgtlabel='LD0', d='down')
#LED to ground
d.add(e.LINE, d='down', l=d.unit*1.5)
d.add(e.GND)
d.draw()
Explanation: \begin{figure}
\centerline{\includegraphics[width=10cm]{WireHigh_RTL.png}}
\caption{\label{fig:WHRTL} WireHigh RTL schematic (Ignore the Buffer in the middle); Xilinx Vivado 2017.4}
\end{figure}
\begin{figure}
\centerline{\includegraphics[width=10cm]{WireHigh_SYN.png}}
\caption{\label{fig:WHSYN} WireHigh Synthesized Schematic (Ignore the Buffer in the middle); Xilinx Vivado 2017.4}
\end{figure}
\begin{figure}
\centerline{\includegraphics[width=10cm]{WireHigh_IMP.png}}
\caption{\label{fig:WHIMP} WireHigh Implementated Schematic (Ignore the Buffer in the middle); Xilinx Vivado 2017.4}
\end{figure}
PYNQ-Z1 Deployment
Board Circuit
End of explanation
ConstraintXDCTextReader('PYNQ_Z1Constraints_WireHigh');
Explanation: Board Constraint
End of explanation
d = schem.Drawing(unit=.5)
d.add(e.DOT_OPEN, label='$0$')
d.add(e.LINE, l=d.unit*2, d='down')
d.add(e.GND)
d.draw()
Explanation: LED 0 (the furthest Right one above the buttons) will light up green
Wire Low
\begin{definition}\label{def:WireLow}
A Wire to Low is a Wire connected to the Lowest reference voltage in a Digital Circuit with the Boolean equivalency of 
$$Y=0$$
that of alway False
\end{definition}
In most modern digital circuits this Lowest reference voltage will be digital ground.
End of explanation
Y=Symbol('Y')
YEq=Eq(Y, 0); YEq
Explanation: Sympy Expression
End of explanation
#decorator to specify a myHDL module that can be converted
#to myHDL
@block
def WireLow(Y):
    
    Wire to Constatnt Low
    Input:
        None
    Output:
        Y(bool): output
    
    #create signal to Low Source
    LSource=Signal(bool(0))
    
    #decorator for a compintorical senstvity
    @always_comb
    def logic():
        #internal function to specfiy Out is set to Low Source
        Y.next=LSource
    
    #return all internal functions
    return instances()
Explanation: myHDL Module
End of explanation
#create output signal to bind to `WireHigh` Mod
Y=Signal(bool(0))
#Create instatnce of `WireHigh` and bind `Out` Signal to it
DUT=WireLow(Y)
#Run convert on `DUT` instance of `WireHigh` to create Verilog/VHDL
DUT.convert()
#Read ouput `WireHigh.v` into notebook
VerilogTextReader('WireLow');
Explanation: Verilog Conversion
End of explanation
d = schem.Drawing(unit=.5)
LD0=d.add(e.LED, d='right', label='LD0')
d.add(e.LINE, l=d.unit*2, d='left', xy=LD0.start)
d.add(e.LINE, l=d.unit*2, d='down')
d.add(e.GND)
d.add(e.LINE, l=d.unit*2, d='right', xy=LD0.end)
d.add(e.LINE, l=d.unit*2, d='down')
d.add(e.GND)
d.draw()
Explanation: \begin{figure}
\centerline{\includegraphics[width=10cm]{WireLow_RTL.png}}
\caption{\label{fig:WLRTL} WireLow RTL schematic (Ignore the Buffer in the middle); Xilinx Vivado 2017.4}
\end{figure}
\begin{figure}
\centerline{\includegraphics[width=10cm]{WireLow_SYN.png}}
\caption{\label{fig:WLSYN} WireLow Synthesized Schematic (Ignore the Buffer in the middle); Xilinx Vivado 2017.4}
\end{figure}
\begin{figure}
\centerline{\includegraphics[width=10cm]{WireLow_IMP.png}}
\caption{\label{fig:WLIMP} WireLow Implementated Schematic (Ignore the Buffer in the middle); Xilinx Vivado 2017.4}
\end{figure}
PYNQ-Z1 Deployment
Board Circuit
End of explanation
ConstraintXDCTextReader('PYNQ_Z1Constraints_WireLow');
Explanation: Board Constraint
End of explanation
d = schem.Drawing(unit=.5)
d.add(e.DOT_OPEN, l=d.unit*3, lftlabel='$X$')
d.add(l.BUF, label='$Buffer$')
d.add(e.DOT_OPEN, l=d.unit*2, rgtlabel='$Y$')
d.draw()
Explanation: Nothing will happen since the Low Signal on the PYNQ-Z1 is ground so LED 0 will remain off
Buffer
\begin{definition}\label{def:BufferGate}
A Buffer Gate is a gate whose output is one to one with its input, in both behavior and ideally in time. The Buffer Gates boolean equivalence is
$$Y=X$$
\end{definition}
From a Boolean algebra/software perspective this may be a do-nothing gate but from a hardware perspective, it is incredibly valuable as it isolates the incoming signal circuit from any inline feedback on the outgoing signal's circuit. And is also typically used in circuit design as a way of ensuring the output of a system will be at the right voltage levels of the technology so that the next set of gates will register the input to them correctly
End of explanation
X, Y=symbols('X, Y')
YEq=Eq(Y, X); YEq
TruthTabelGenrator(YEq)
#convert the Sympy exspresion to a 
#numpy exspresion via lambdify
YEqN=lambdify(X, YEq.rhs, dummify=False)
YEqN(np.array([0, 1]))
Explanation: Sympy Expression
End of explanation
@block
def BufferGate(X, Y):
    
    Buffer Gate demo module
    Input:
        X(bool): Input conection to wire between `X` and `Y`
    Ouput:
        Y(bool): Output connection to wire between 'X' and 'Y'
    
    @always_comb
    def logic():
        Y.next=X
    return instances()
Explanation: myHDL Module
End of explanation
#generate random test values for BufferGate_TB
#stimules input In
TestLen=10
#for testing purpose the random genrator need to be seeded
#to create reproducable values
np.random.seed(12)
XTVs=np.random.randint(0,2, TestLen).astype(int)
XTVs
#clear any previouse stored values in Peeker
Peeker.clear()
#Create the Signals to the BufferGate and 
#add them to Peeker for display and anylis
X=Signal(bool(0)); Peeker(X, 'X')
Y=Signal(bool(0)); Peeker(Y, 'Y')
#create instance of `BufferGate` and bind signals
#to it as the "Device Under Testing"
DUT=BufferGate(X, Y)
#Create a Testbench for `BufferGate`
def BufferGate_TB():
    
    myHDL only testbench for module `BufferGate`
    
    #internal function that will apply
    #stimules to DUT 
    @instance
    def stimules():
        for i in range(TestLen):
            #asign next stimules value to X input of DUT
            #for every 1 interval delay
            X.next=int(XTVs[i])
            yield delay(1)
        
        #flag to end the simulation of the DUT after all
        #stimules have been run
        raise StopSimulation()
    
    #return all internal stimules
    return instances()
#bind the DUT, Testbench and Peeker to simulator and run it
sim=Simulation(DUT, BufferGate_TB(), *Peeker.instances()).run()            
#View Waveform diagram from Simulation with
#wavefroms in the order of `X` then `Y`
Peeker.to_wavedrom('X', 'Y')
#Capture the Waveform as a Pandas Dataframe for
#detiled anylsis
WireData=Peeker.to_dataframe()
#order the cols in the dataframe `X` then `Y`
WireData=WireData[['X', 'Y']]
WireData
#apply the lampdfid sympy expspresion for a buffer to the X input to
#get a refrance to compare the BufferGate modules 
WireData['YRef']=WireData['X'].apply(YEqN)
WireData
#Test wither the modules ouput matchs the sympy refrance
Test=(WireData['Y']==WireData['YRef']).all()
print(f'Module `BufferGate` works as exspected: {Test}')
Explanation: ## myHDL Testing
 Every module (WireHigh and WireLow are just too primitive to test) should be tested with a Testbench in python. This test does not confirm that the module meets the requirements of synthesization in Verilog/VHDL but confirms that the behavior of the myHDL module under test (DUT) behavior wise conforms to the desired behavior. 
Because of the data analysis ability of python to full analysis the test output in the same framework that the test, let alone module, was written in development time is decreased. This is one of the defining abilities of myHDL over other HDLs such as Verilog/VHDL
Synthesization in the world of HDL refers to the ability to turn HDL  code into Hardware via an FPGA or a dedicated circuit (typically called an ASIC). It is for that reason that HDL codeing is not pure software nor pure hardware but rather a hybrid of the two. And why HDL coding has high constraints then all other coding seeing as the HDL must meet Behavior and Timing of software but must also meet the hardware synthesis requirements of Power, Physical Size, Implantability, and more
End of explanation
DUT.convert()
VerilogTextReader('BufferGate');
Explanation: Verilog Conversion
End of explanation
#create BitVector for BufferGate_TBV
XTVs=intbv(int(''.join(XTVs.astype(str)), 2))[TestLen:]
XTVs, bin(XTVs)
#Convertable testbenchs must be treated as a module
@block
def BufferGate_TBV():
    
    myHDL -> Verilog testbench for module `BufferGate`
    
    #create the signals to bind to the DUT
    X=Signal(bool(0))
    Y=Signal(bool(0))
    
    #print out the waveform of `X` and `Y`
    @always_comb
    def print_data():
        print(X, Y)
    
    #create a register to hold the testdata vector
    #Test Signal Bit Vector
    XTV=Signal(XTVs)
    
    #create an instance of the `BufferGate` and
    #bind X and Y to it
    DUT=BufferGate(X, Y)
    
    #create the stimules action
    @instance
    def stimules():
        for i in range(TestLen):
            #asign X the next bit from XTV testvector reg
            X.next=XTV[i]
            #delay one of the smallest time intervals
            yield delay(1)
        
        #raise the stop simulation flag
        raise StopSimulation()
    
    #return all internals of the Testbench
    return instances()
#create instance of the Testbench
TB=BufferGate_TBV()
#run the conversion to Verilog and insure that
#all Signal values are at there default value
TB.convert(hdl="Verilog", initial_values=True)
#read back the testbench into python
VerilogTextReader('BufferGate_TBV');
Explanation: \begin{figure}
\centerline{\includegraphics[width=10cm]{BufferGate_RTL.png}}
\caption{\label{fig:BGRTL} BufferGate RTL schematic; Xilinx Vivado 2017.4}
\end{figure}
\begin{figure}
\centerline{\includegraphics[width=10cm]{BufferGate_SYN.png}}
\caption{\label{fig:BGSYN} BufferGate Synthesized Schematic; Xilinx Vivado 2017.4}
\end{figure}
\begin{figure}
\centerline{\includegraphics[width=10cm]{BufferGate_IMP.png}}
\caption{\label{fig:BGIMP} BufferGate Implementated Schematic; Xilinx Vivado 2017.4}
\end{figure}
myHDL to Verilog Testbench
End of explanation
d=schem.Drawing(unit=.5)
#add switch
SW0=d.add(e.SWITCH_SPDT2, reverse=True, label='SW0')
#connect to buffer
d.add(e.LINE, d='right', xy=SW0.a, l=d.unit*2, label='X')
d.add(e.DOT)
B0=d.add(l.BUF, label='BUF')
#buffer to LED
d.add(e.DOT)
d.add(e.LINE, d='right', l=d.unit*2, label='Y')
d.add(e.LINE, d='down', l=d.unit*2)
d.add(e.LED, rgtlabel='LD0', d='down')
#LED to ground
d.add(e.LINE, d='down', l=d.unit*1.5)
d.add(e.GND)
#swtich bottom to ground
d.add(e.LINE, d='down', xy=SW0.c, l=d.unit*4)
d.add(e.GND)
#switch top to rail
d.add(e.LINE, d='up', xy=SW0.b, l=d.unit*2.3)
d.add(e.VDD)
d.draw()
Explanation: PYNQ-Z1 Deployment
Board Circuit
End of explanation
ConstraintXDCTextReader('PYNQ_Z1Constraints_BufferGate');
Explanation: Board Constraint File
End of explanation
d = schem.Drawing(unit=.5)
d.add(e.DOT_OPEN, l=d.unit*3, lftlabel='$X$')
d.add(l.NOT, label='$NOT$')
d.add(e.LINE)
d.add(e.DOT_OPEN, rgtlabel='$Y$')
d.draw()
Explanation: Video of Deployment
BUFFER Gate myHDL PYNQ-Z1 (YouTube)
NOT
\begin{definition}\label{def:NotGate}
A NOT Gate, also called an Inverter, is a logic gate that produces the negated value of the input. Its boolean expression is typically
$$Y=\overline{X}$$ using the overhead bar negation notation.
\end{definition}
End of explanation
X, Y=symbols('X, Y')
YEq=Eq(Y, ~X); YEq
TruthTabelGenrator(YEq)
YEqN=lambdify(X, YEq.rhs, dummify=False)
YEqN(0), YEqN(1)
Explanation: Sympy Expression
End of explanation
@block
def NotGate(X, Y):
    
    NOT gate exsample module
    
    Input:
        X(bool): input
    
    Output:
        Y(bool): ouput
    
    
    @always_comb
    def logic():
        Y.next=not X
        
    return instances()
Explanation: myHDL Module
End of explanation
#generate random test values for NotGate_TB
#stimules input In
TestLen=10
np.random.seed(14)
XTVs=np.random.randint(0,2, TestLen).astype(int)
XTVs
Peeker.clear()
X=Signal(bool(0)); Peeker(X, 'X')
Y=Signal(bool(0)); Peeker(Y, 'Y')
DUT=NotGate(X, Y)
def NotGate_TB():
    
    myHDL only testbench for module `NotGate`
    
    
    @instance
    def stimules():
        for i in range(TestLen):
            X.next=int(XTVs[i])
            yield delay(1)
        
        raise StopSimulation()
        
    return instances()
sim=Simulation(DUT, NotGate_TB(), *Peeker.instances()).run()            
Peeker.to_wavedrom()
NotData=Peeker.to_dataframe()
NotData
NotData['YRef']=NotData['X'].apply(YEqN).astype(int)
NotData
Test=(NotData['Y']==NotData['YRef']).all()
print(f'Module `NotGate` works as exspected: {Test}')
Explanation: myHDL Testing
End of explanation
DUT.convert()
VerilogTextReader('NotGate');
Explanation: Verilog Conversion
End of explanation
#create BitVector for NotGate_TBV
XTVs=intbv(int(''.join(XTVs.astype(str)), 2))[TestLen:]
XTVs, bin(XTVs)
@block
def NotGate_TBV():
    
    myHDL -> Verilog testbench for module `NotGate`
    
    X=Signal(bool(0))
    Y=Signal(bool(0))
    
    @always_comb
    def print_data():
        print(X, Y)
    
    #Test Signal Bit Vector
    XTV=Signal(XTVs)
    DUT=NotGate(X, Y)
    @instance
    def stimules():
        for i in range(TestLen):
            X.next=XTV[i]
            yield delay(1)
        
        raise StopSimulation()
    return instances()
TB=NotGate_TBV()
TB.convert(hdl="Verilog", initial_values=True)
VerilogTextReader('NotGate_TBV');         
Explanation: \begin{figure}
\centerline{\includegraphics[width=10cm]{NotGate_RTL.png}}
\caption{\label{fig:NGRTL} NotGate RTL schematic; Xilinx Vivado 2017.4}
\end{figure}
\begin{figure}
\centerline{\includegraphics[width=10cm]{NotGate_SYN.png}}
\caption{\label{fig:NGSYN} NotGate Synthesized Schematic; Xilinx Vivado 2017.4}
\end{figure}
\begin{figure}
\centerline{\includegraphics[width=10cm]{NotGate_IMP.png}}
\caption{\label{fig:NGIMP} NotGate Implementated Schematic; Xilinx Vivado 2017.4}
\end{figure}
myHDL to Verilog Testbench
End of explanation
d=schem.Drawing(unit=.5)
#add switch
SW0=d.add(e.SWITCH_SPDT2, reverse=True, label='SW0')
#connect to buffer
d.add(e.LINE, d='right', xy=SW0.a, l=d.unit*2, label='X')
d.add(e.DOT)
N0=d.add(l.NOT, label='NOT')
#buffer to LED
d.add(e.DOT)
d.add(e.LINE, d='right', l=d.unit*2, label='Y')
d.add(e.LINE, d='down', l=d.unit*2)
d.add(e.LED, rgtlabel='LD0', d='down')
#LED to ground
d.add(e.LINE, d='down', l=d.unit*1.5)
d.add(e.GND)
#swtich bottom to ground
d.add(e.LINE, d='down', xy=SW0.c, l=d.unit*4)
d.add(e.GND)
#switch top to rail
d.add(e.LINE, d='up', xy=SW0.b, l=d.unit*2.3)
d.add(e.VDD)
d.draw()
Explanation: PYNQ-Z1 Deployment
Board Circuit
End of explanation
ConstraintXDCTextReader('PYNQ_Z1Constraints_NotGate');
Explanation: Board Constraint
End of explanation
d = schem.Drawing(unit=.5)
G = d.add(l.AND2, label='$AND_2$')
d.add(e.DOT_OPEN, xy=G.out, rgtlabel='$Y$')
d.add(e.DOT_OPEN, xy=G.in1, lftlabel='$X_1$')
d.add(e.DOT_OPEN, xy=G.in2, lftlabel='$X_0$')
d.draw()
Explanation: Video of Deployment
NOT Gate myHDL PYNQ-Z1 (YouTube)
AND
\begin{definition}\label{def:AndGate}
An AND Gate is a logic gate the will yield a True response if and only if all of its inputs are also True. Its boolean expression is typically
$$Y=X_0 \cdot X_1$$ using the multiplicative dot notation. Since if True is mapped to $1$ and False  is mapped $0$,  its output behavior is like that of multiplication of $1$ and $0$
\end{definition}
End of explanation
X0, X1, Y=symbols('X_0, X_1, Y')
YEq=Eq(Y, X0&X1); YEq
TruthTabelGenrator(YEq)
YEqN=lambdify([X0, X1], YEq.rhs, dummify=False)
SystmaticVals=np.array(list(itertools.product([0,1], repeat=2)))
SystmaticVals, YEqN(SystmaticVals[:, 1], SystmaticVals[:, 0]).astype(int)
Explanation: Sympy Expression
End of explanation
@block
def AndGate(X0, X1, Y):
    
    And Gate demo module
    
    Input:
        X0(bool): And gate input 0
        X1(bool): And gate input 1
    
    Output:
        Y(bool): And gate ouput 
    
    
    @always_comb
    def logic():
        #note here that `and` is used since this
        #is a bit wise AND 
        Y.next=X0 and X1
        
        #if `&` had been used the conversion 
        #would yield `&` the .all() AND
        # when dealing with bus's and  behavior mux's this
        #distiction must be known
        #see:
        # https://stackoverflow.com/questions/17327680/what-is-the-difference-between-single-and-double-ampersand-binary-opera
    
    return instances()
Explanation: myHDL Module
End of explanation
#generate systmatic and random test values for AndGate_TB
#stimules inputs X1 and X2
TestLen=10
SystmaticVals=list(itertools.product([0,1], repeat=2))
X0TVs=np.array([i[1] for i in SystmaticVals]).astype(int)
np.random.seed(15)
X0TVs=np.append(X0TVs, np.random.randint(0,2, TestLen)).astype(int)
X1TVs=np.array([i[0] for i in SystmaticVals]).astype(int)
#the random genrator must have a differint seed beween each generation
#call in order to produce differint values for each call
np.random.seed(16)
X1TVs=np.append(X1TVs, np.random.randint(0,2, TestLen)).astype(int)
TestLen=len(X1TVs)
SystmaticVals, X1TVs, X0TVs, TestLen
Peeker.clear()
X0=Signal(bool(0)); Peeker(X0, 'X0')
X1=Signal(bool(0)); Peeker(X1, 'X1')
Y=Signal(bool(0)); Peeker(Y, 'Y')
DUT=AndGate(X0, X1, Y)
def AndGate_TB():
    
    myHDL only testbench for module `AndGate`
    
    
    @instance
    def stimules():
        for i in range(TestLen):
            X0.next=int(X0TVs[i])
            X1.next=int(X1TVs[i])
            yield delay(1)
        
        raise StopSimulation()
        
    return instances()
sim=Simulation(DUT, AndGate_TB(), *Peeker.instances()).run()            
Peeker.to_wavedrom('X1', 'X0', 'Y')
AndData=Peeker.to_dataframe()
AndData=AndData[['X1', 'X0', 'Y']]
AndData
AndData['YRef']=AndData.apply(lambda row:YEqN(row['X0'], row['X1']), axis=1).astype(int)
AndData
Test=(AndData['Y']==AndData['YRef']).all()
print(f'Module `AndGate` works as exspected: {Test}')
Explanation: myHDL Testing
End of explanation
DUT.convert()
VerilogTextReader('AndGate');
Explanation: Verilog Conversion
End of explanation
#create BitVectora for AndGate_TBV
X0TVs=intbv(int(''.join(X0TVs.astype(str)), 2))[TestLen:]
X1TVs=intbv(int(''.join(X1TVs.astype(str)), 2))[TestLen:]
X0TVs, bin(X0TVs), X1TVs, bin(X1TVs)
@block
def AndGate_TBV():
    
    myHDL -> Verilog testbench for module `AndGate`
    
    X0=Signal(bool(0))
    X1=Signal(bool(0))
    Y=Signal(bool(0))
    
    @always_comb
    def print_data():
        print(X0, X1, Y)
    
    #Test Signal Bit Vectors
    X0TV=Signal(X0TVs)
    X1TV=Signal(X1TVs)
    DUT=AndGate(X0, X1, Y)
    @instance
    def stimules():
        for i in range(TestLen):
            X0.next=int(X0TV[i])
            X1.next=int(X1TV[i])
            yield delay(1)
        
        raise StopSimulation()
    return instances()
TB=AndGate_TBV()
TB.convert(hdl="Verilog", initial_values=True)
VerilogTextReader('AndGate_TBV');         
Explanation: \begin{figure}
\centerline{\includegraphics[width=10cm]{AndGate_RTL.png}}
\caption{\label{fig:AGRTL} AndGate RTL schematic; Xilinx Vivado 2017.4}
\end{figure}
\begin{figure}
\centerline{\includegraphics[width=10cm]{AndGate_SYN.png}}
\caption{\label{fig:AGSYN} AndGate Synthesized Schematic; Xilinx Vivado 2017.4}
\end{figure}
\begin{figure}
\centerline{\includegraphics[width=10cm]{AndGate_IMP.png}}
\caption{\label{fig:AGIMP} AndGate Implementated Schematic; Xilinx Vivado 2017.4}
\end{figure}
myHDL to Verilog Testbench
End of explanation
d=schem.Drawing(unit=.5)
#add elements
G=d.add(l.AND2,d='right', label='$AND_2$')
#Gate to led to gnd
d.add(e.LINE, d='right', xy=G.out)
d.add(e.DOT, label='$Y$')
d.add(e.LINE, d='down', l=d.unit*2)
LD0=d.add(e.LED, d='down', label='LD0')
d.add(e.LINE, d='down', l=d.unit*2)
d.add(e.GND)
d.add(e.LINE, d='left', xy=G.in1, l=d.unit)
d.add(e.DOT, label='$X_0$')
d.add(e.LINE,d='left', l=d.unit)
d.add(e.LINE,d='up', l=d.unit*2)
d.add(e.LINE,d='left', l=d.unit*2)
SW0=d.add(e.SWITCH_SPDT, lftlabel='SW0')
d.add(e.GND, xy=SW0.c)
d.add(e.VDD, xy=SW0.b)
d.add(e.LINE, d='left', xy=G.in2, l=d.unit)
d.add(e.DOT, botlabel='$X_1$')
d.add(e.LINE,d='left', l=d.unit)
d.add(e.LINE,d='down', l=d.unit*2)
d.add(e.LINE,d='left', l=d.unit*4)
SW1=d.add(e.SWITCH_SPDT, lftlabel='SW1')
d.add(e.GND, xy=SW1.c)
d.add(e.VDD, xy=SW1.b)
d.draw()
Explanation: PYNQ-Z1 Deployment
Board Circuit
End of explanation
ConstraintXDCTextReader('PYNQ_Z1Constraints_AndGate');
Explanation: Board Constraint
End of explanation
d = schem.Drawing(unit=.5)
G = d.add(l.AND2, label='$OR_2$')
d.add(e.DOT_OPEN, xy=G.out, rgtlabel='$Y$')
d.add(e.DOT_OPEN, xy=G.in1, lftlabel='$X_1$')
d.add(e.DOT_OPEN, xy=G.in2, lftlabel='$X_0$')
d.draw()
Explanation: Video of Deployment
AND Gate myHDL PYNQ-Z1 (YouTube)
OR
\begin{definition}\label{def:OrGate}
An OR Gate is a logic gate the will yield a True response if any of its inputs are True. Its boolean expression is typically
$$Y=X_0 + X_1$$ using the addition notation. Since if True is mapped to $1$ and False  is mapped $0$,  its output behavior like that of the addition of $1$ and $0$ with the constraint of $1+1=1$ which is an axiom of Boolean Algebra.
\end{definition}
End of explanation
X0, X1, Y=symbols('X_0, X_1, Y')
YEq=Eq(Y, X0|X1); YEq
TruthTabelGenrator(YEq)
YEqN=lambdify([X0, X1], YEq.rhs, dummify=False)
SystmaticVals=np.array(list(itertools.product([0,1], repeat=2)))
SystmaticVals, YEqN(SystmaticVals[:, 1], SystmaticVals[:, 0]).astype(int)
Explanation: Sympy Expression
End of explanation
@block
def OrGate(X0, X1, Y):
    
    Or Gate demo module
    
    Input:
        X0(bool): Or gate input 0
        X1(bool): Or gate input 1
    
    Output:
        Y(bool): Or gate ouput 
    
    
    @always_comb
    def logic():
        #note here that `or` is used since this
        #is a bit wise OR 
        Y.next=X0 or X1
        
        #if `|` had been used the conversion 
        #would yield `||` the .all() OR
        # when dealing with bus's and  behavior mux's this
        #distiction must be known
        #see:
        # https://stackoverflow.com/questions/17327680/what-is-the-difference-between-single-and-double-ampersand-binary-opera
    
    return instances()
Explanation: myHDL Module
End of explanation
#generate systmatic and random test values for OrGate_TB
#stimules inputs X1 and X2
TestLen=10
SystmaticVals=list(itertools.product([0,1], repeat=2))
X0TVs=np.array([i[1] for i in SystmaticVals]).astype(int)
np.random.seed(17)
X0TVs=np.append(X0TVs, np.random.randint(0,2, TestLen)).astype(int)
X1TVs=np.array([i[0] for i in SystmaticVals]).astype(int)
np.random.seed(18)
X1TVs=np.append(X1TVs, np.random.randint(0,2, TestLen)).astype(int)
TestLen=len(X1TVs)
SystmaticVals, X1TVs, X0TVs, TestLen
Peeker.clear()
X0=Signal(bool(0)); Peeker(X0, 'X0')
X1=Signal(bool(0)); Peeker(X1, 'X1')
Y=Signal(bool(0)); Peeker(Y, 'Y')
DUT=OrGate(X0, X1, Y)
def OrGate_TB():
    
    myHDL only testbench for module `OrGate`
    
    
    @instance
    def stimules():
        for i in range(TestLen):
            X0.next=int(X0TVs[i])
            X1.next=int(X1TVs[i])
            yield delay(1)
        
        raise StopSimulation()
        
    return instances()
sim=Simulation(DUT, OrGate_TB(), *Peeker.instances()).run()            
Peeker.to_wavedrom('X1', 'X0', 'Y')
OrData=Peeker.to_dataframe()
OrData=OrData[['X1', 'X0', 'Y']]
OrData
OrData['YRef']=OrData.apply(lambda row:YEqN(row['X0'], row['X1']), axis=1).astype(int)
OrData
Test=(OrData['Y']==OrData['YRef']).all()
print(f'Module `OrGate` works as exspected: {Test}')
Explanation: myHDL Testing
End of explanation
DUT.convert()
VerilogTextReader('OrGate');
Explanation: Verilog Conversion
End of explanation
#create BitVectora for OrGate_TBV
X0TVs=intbv(int(''.join(X0TVs.astype(str)), 2))[TestLen:]
X1TVs=intbv(int(''.join(X1TVs.astype(str)), 2))[TestLen:]
X0TVs, bin(X0TVs), X1TVs, bin(X1TVs)
@block
def OrGate_TBV():
    
    myHDL -> Verilog testbench for module `OrGate`
    
    X0=Signal(bool(0))
    X1=Signal(bool(0))
    Y=Signal(bool(0))
    
    @always_comb
    def print_data():
        print(X0, X1, Y)
    
    #Test Signal Bit Vectors
    X0TV=Signal(X0TVs)
    X1TV=Signal(X1TVs)
    DUT=OrGate(X0, X1, Y)
    @instance
    def stimules():
        for i in range(TestLen):
            X0.next=int(X0TV[i])
            X1.next=int(X1TV[i])
            yield delay(1)
        
        raise StopSimulation()
    return instances()
TB=OrGate_TBV()
TB.convert(hdl="Verilog", initial_values=True)
VerilogTextReader('OrGate_TBV');         
Explanation: \begin{figure}
\centerline{\includegraphics[width=10cm]{OrGate_RTL.png}}
\caption{\label{fig:OGRTL} OrGate RTL schematic; Xilinx Vivado 2017.4}
\end{figure}
\begin{figure}
\centerline{\includegraphics[width=10cm]{OrGate_SYN.png}}
\caption{\label{fig:OGSYN} OrGate Synthesized Schematic; Xilinx Vivado 2017.4}
\end{figure}
\begin{figure}
\centerline{\includegraphics[width=10cm]{OrGate_IMP.png}}
\caption{\label{fig:OGIMP} OrGate Implementated Schematic; Xilinx Vivado 2017.4}
\end{figure}
myHDL to Verilog Testbench
End of explanation
d=schem.Drawing(unit=.5)
#add elements
G=d.add(l.OR2,d='right', label='$OR_2$')
#Gate to led to gnd
d.add(e.LINE, d='right', xy=G.out)
d.add(e.DOT, label='$Y$')
d.add(e.LINE, d='down', l=d.unit*2)
LD0=d.add(e.LED, d='down', label='LD0')
d.add(e.LINE, d='down', l=d.unit*2)
d.add(e.GND)
d.add(e.LINE, d='left', xy=G.in1, l=d.unit)
d.add(e.DOT, label='$X_0$')
d.add(e.LINE,d='left', l=d.unit)
d.add(e.LINE,d='up', l=d.unit*2)
d.add(e.LINE,d='left', l=d.unit*2)
SW0=d.add(e.SWITCH_SPDT, lftlabel='SW0')
d.add(e.GND, xy=SW0.c)
d.add(e.VDD, xy=SW0.b)
d.add(e.LINE, d='left', xy=G.in2, l=d.unit)
d.add(e.DOT, botlabel='$X_1$')
d.add(e.LINE,d='left', l=d.unit)
d.add(e.LINE,d='down', l=d.unit*2)
d.add(e.LINE,d='left', l=d.unit*4)
SW1=d.add(e.SWITCH_SPDT, lftlabel='SW1')
d.add(e.GND, xy=SW1.c)
d.add(e.VDD, xy=SW1.b)
d.draw()
Explanation: PYNQ-Z1 Deployment
Board Circuit
End of explanation
ConstraintXDCTextReader('PYNQ_Z1Constraints_OrGate');
Explanation: Board Constraint
End of explanation
d = schem.Drawing(unit=.5)
G = d.add(l.XOR2, label='$XOR_2$')
d.add(e.DOT_OPEN, xy=G.out, rgtlabel='$Y$')
d.add(e.DOT_OPEN, xy=G.in1, lftlabel='$X_1$')
d.add(e.DOT_OPEN, xy=G.in2, lftlabel='$X_0$')
d.draw()
Explanation: Video of Deployment
OR Gate myHDL PYNQ-Z1 (YouTube)
XOR
\begin{definition}\label{def:XOrGate}
An XOR Gate is a logic gate the will yield a True response if an only if only one of its inputs are True. Its boolean expression is typically
$$Y=X_0 \oplus X_1$$ using its typical notation, wich is a refinment of the $+$ notation used for an OR Gate. But can also be expressed as 
$$Y=X_0\overline{X_1}+ \overline{X_0}X_1= (X_0+X_1) \cdot(\overline{X_0}+\overline{X_1})$$
\end{definition}
End of explanation
X0, X1, Y=symbols('X_0, X_1, Y')
YEq=Eq(Y, X0^X1); YEq
TruthTabelGenrator(YEq)
#lampdfy must have maping manuly set from `Xor` to `np.bitwise_xor`
YEqN=lambdify([X0, X1], YEq.rhs, {'Xor':np.bitwise_xor}, dummify=False)
SystmaticVals=np.array(list(itertools.product([0,1], repeat=2)))
SystmaticVals, YEqN(SystmaticVals[:, 1], SystmaticVals[:, 0]).astype(int)
Explanation: Sympy Expression
End of explanation
@block
def XorGate(X0, X1, Y):
    
    XOR Gate demo module
    
    Input:
        X0(bool): XOR gate input 0
        X1(bool): XOR gate input 1
    
    Output:
        Y(bool): XOR gate ouput 
    
    
    @always_comb
    def logic():
        Y.next=X0 ^ X1
        
    return instances()
Explanation: myHDL Module
End of explanation
#generate systmatic and random test values for XorGate_TB
#stimules inputs X1 and X2
TestLen=10
SystmaticVals=list(itertools.product([0,1], repeat=2))
X0TVs=np.array([i[1] for i in SystmaticVals]).astype(int)
np.random.seed(19)
X0TVs=np.append(X0TVs, np.random.randint(0,2, TestLen)).astype(int)
X1TVs=np.array([i[0] for i in SystmaticVals]).astype(int)
np.random.seed(20)
X1TVs=np.append(X1TVs, np.random.randint(0,2, TestLen)).astype(int)
TestLen=len(X1TVs)
SystmaticVals, X1TVs, X0TVs, TestLen
Peeker.clear()
X0=Signal(bool(0)); Peeker(X0, 'X0')
X1=Signal(bool(0)); Peeker(X1, 'X1')
Y=Signal(bool(0)); Peeker(Y, 'Y')
DUT=XorGate(X0, X1, Y)
def XorGate_TB():
    
    myHDL only testbench for module `XorGate`
    
    
    @instance
    def stimules():
        for i in range(TestLen):
            X0.next=int(X0TVs[i])
            X1.next=int(X1TVs[i])
            yield delay(1)
        
        raise StopSimulation()
        
    return instances()
sim=Simulation(DUT, XorGate_TB(), *Peeker.instances()).run()            
Peeker.to_wavedrom('X1', 'X0', 'Y')
XorData=Peeker.to_dataframe()
XorData=XorData[['X1', 'X0', 'Y']]
XorData
XorData['YRef']=XorData.apply(lambda row:YEqN(row['X0'], row['X1']), axis=1).astype(int)
XorData
Test=(XorData['Y']==XorData['YRef']).all()
print(f'Module `XorGate` works as exspected: {Test}')
Explanation: myHDL Testing
End of explanation
DUT.convert()
VerilogTextReader('XorGate');
Explanation: Verilog Conversion
End of explanation
#create BitVectora for XorGate_TBV
X0TVs=intbv(int(''.join(X0TVs.astype(str)), 2))[TestLen:]
X1TVs=intbv(int(''.join(X1TVs.astype(str)), 2))[TestLen:]
X0TVs, bin(X0TVs), X1TVs, bin(X1TVs)
@block
def XorGate_TBV():
    
    myHDL -> Verilog testbench for module `XorGate`
    
    X0=Signal(bool(0))
    X1=Signal(bool(0))
    Y=Signal(bool(0))
    
    @always_comb
    def print_data():
        print(X0, X1, Y)
    
    #Test Signal Bit Vectors
    X0TV=Signal(X0TVs)
    X1TV=Signal(X1TVs)
    DUT=XorGate(X0, X1, Y)
    @instance
    def stimules():
        for i in range(TestLen):
            X0.next=int(X0TV[i])
            X1.next=int(X1TV[i])
            yield delay(1)
        
        raise StopSimulation()
    return instances()
TB=XorGate_TBV()
TB.convert(hdl="Verilog", initial_values=True)
VerilogTextReader('XorGate_TBV');         
Explanation: \begin{figure}
\centerline{\includegraphics[width=10cm]{XorGate_RTL.png}}
\caption{\label{fig:XorGRTL} XorGate RTL schematic; Xilinx Vivado 2017.4}
\end{figure}
\begin{figure}
\centerline{\includegraphics[width=10cm]{XorGate_SYN.png}}
\caption{\label{fig:XorGSYN} XorGate Synthesized Schematic; Xilinx Vivado 2017.4}
\end{figure}
\begin{figure}
\centerline{\includegraphics[width=10cm]{XorGate_IMP.png}}
\caption{\label{fig:XorGIMP} XorGate Implementated Schematic; Xilinx Vivado 2017.4}
\end{figure}
myHDL to Verilog Testbench
End of explanation
d=schem.Drawing(unit=.5)
#add elements
G=d.add(l.XOR2,d='right', label='$XOR_2$')
#Gate to led to gnd
d.add(e.LINE, d='right', xy=G.out)
d.add(e.DOT, label='$Y$')
d.add(e.LINE, d='down', l=d.unit*2)
LD0=d.add(e.LED, d='down', label='LD0')
d.add(e.LINE, d='down', l=d.unit*2)
d.add(e.GND)
d.add(e.LINE, d='left', xy=G.in1, l=d.unit)
d.add(e.DOT, label='$X_0$')
d.add(e.LINE,d='left', l=d.unit)
d.add(e.LINE,d='up', l=d.unit*2)
d.add(e.LINE,d='left', l=d.unit*2)
SW0=d.add(e.SWITCH_SPDT, lftlabel='SW0')
d.add(e.GND, xy=SW0.c)
d.add(e.VDD, xy=SW0.b)
d.add(e.LINE, d='left', xy=G.in2, l=d.unit)
d.add(e.DOT, botlabel='$X_1$')
d.add(e.LINE,d='left', l=d.unit)
d.add(e.LINE,d='down', l=d.unit*2)
d.add(e.LINE,d='left', l=d.unit*4)
SW1=d.add(e.SWITCH_SPDT, lftlabel='SW1')
d.add(e.GND, xy=SW1.c)
d.add(e.VDD, xy=SW1.b)
d.draw()
Explanation: PYNQ-Z1 Deployment
Board Circuit
End of explanation
ConstraintXDCTextReader('PYNQ_Z1Constraints_XorGate');
Explanation: Board Constraint
End of explanation
d = schem.Drawing(unit=.5)
G = d.add(l.NAND2, label='$NAND_2$')
d.add(e.DOT_OPEN, xy=G.out, rgtlabel='$Y$')
d.add(e.DOT_OPEN, xy=G.in1, lftlabel='$X_1$')
d.add(e.DOT_OPEN, xy=G.in2, lftlabel='$X_0$')
d.draw()
Explanation: Video of Deployment
XOR Gate myHDL PYNQ-Z1 (YouTube)
NAND
\begin{definition}\label{def:NAndGate}
A NAND Gate is the negated, or the De Morgan equivalent, of an AND Gate. Such that is output will be True whenever there are False inputs to the gate. Its boolean expression is
$$Y=\overline{X_0\cdot X_1}$$
\end{definition}
One peculiar aspect of the NAND Gate is that from a pure Boolean algebra position it is one of the two "Universal Gates". Which means that any other gate can be constructed from no more than NAND Gates. See https://en.wikipedia.org/wiki/NAND_logic#Making_other_gates_by_using_NAND_gates for more info. And while this somewhat holds True for ASIC circuits, this not entirely true in terms of FPGAs
End of explanation
X0, X1, Y=symbols('X_0, X_1, Y')
YEq=Eq(Y, Nand(X0,X1)); YEq
TruthTabelGenrator(YEq)
YEqN=lambdify([X0, X1], YEq.rhs, dummify=False)
SystmaticVals=np.array(list(itertools.product([0,1], repeat=2)))
SystmaticVals, YEqN(SystmaticVals[:, 1], SystmaticVals[:, 0]).astype(int)
Explanation: Sympy Expression
End of explanation
@block
def NAndGate(X0, X1, Y):
    
    NAND Gate demo module
    
    Input:
        X0(bool): NAnd gate input 0
        X1(bool): NAnd gate input 1
    
    Output:
        Y(bool): NAnd gate ouput 
    
    
    @always_comb
    def logic():
        #note here that `and` is used since this
        #is a bit wise AND 
        Y.next=not(X0 and X1)
        
        #if `&` had been used the conversion 
        #would yield `&` the .all() AND
        # when dealing with bus's and  behavior mux's this
        #distiction must be known
        #see:
        # https://stackoverflow.com/questions/17327680/what-is-the-difference-between-single-and-double-ampersand-binary-opera
    
    return instances()
Explanation: myHDL Module
End of explanation
#generate systmatic and random test values for AndGate_TB
#stimules inputs X1 and X2
TestLen=10
SystmaticVals=list(itertools.product([0,1], repeat=2))
X0TVs=np.array([i[1] for i in SystmaticVals]).astype(int)
np.random.seed(21)
X0TVs=np.append(X0TVs, np.random.randint(0,2, TestLen)).astype(int)
X1TVs=np.array([i[0] for i in SystmaticVals]).astype(int)
np.random.seed(23)
X1TVs=np.append(X1TVs, np.random.randint(0,2, TestLen)).astype(int)
TestLen=len(X1TVs)
SystmaticVals, X1TVs, X0TVs, TestLen
Peeker.clear()
X0=Signal(bool(0)); Peeker(X0, 'X0')
X1=Signal(bool(0)); Peeker(X1, 'X1')
Y=Signal(bool(0)); Peeker(Y, 'Y')
DUT=NAndGate(X0, X1, Y)
def NAndGate_TB():
    
    myHDL only testbench for module `NAndGate`
    
    
    @instance
    def stimules():
        for i in range(TestLen):
            X0.next=int(X0TVs[i])
            X1.next=int(X1TVs[i])
            yield delay(1)
        
        raise StopSimulation()
        
    return instances()
sim=Simulation(DUT, NAndGate_TB(), *Peeker.instances()).run()            
Peeker.to_wavedrom('X1', 'X0', 'Y')
NAndData=Peeker.to_dataframe()
NAndData=NAndData[['X1', 'X0', 'Y']]
NAndData
NAndData['YRef']=NAndData.apply(lambda row:YEqN(row['X0'], row['X1']), axis=1).astype(int)
NAndData
Test=(NAndData['Y']==NAndData['YRef']).all()
print(f'Module `NAndGate` works as exspected: {Test}')
Explanation: myHDL Testing
End of explanation
DUT.convert()
VerilogTextReader('NAndGate');
Explanation: Verilog Conversion
End of explanation
#create BitVectora for NAndGate_TBV
X0TVs=intbv(int(''.join(X0TVs.astype(str)), 2))[TestLen:]
X1TVs=intbv(int(''.join(X1TVs.astype(str)), 2))[TestLen:]
X0TVs, bin(X0TVs), X1TVs, bin(X1TVs)
@block
def NAndGate_TBV():
    
    myHDL -> Verilog testbench for module `NAndGate`
    
    X0=Signal(bool(0))
    X1=Signal(bool(0))
    Y=Signal(bool(0))
    
    @always_comb
    def print_data():
        print(X0, X1, Y)
    
    #Test Signal Bit Vectors
    X0TV=Signal(X0TVs)
    X1TV=Signal(X1TVs)
    DUT=NAndGate(X0, X1, Y)
    @instance
    def stimules():
        for i in range(TestLen):
            X0.next=int(X0TV[i])
            X1.next=int(X1TV[i])
            yield delay(1)
        
        raise StopSimulation()
    return instances()
TB=NAndGate_TBV()
TB.convert(hdl="Verilog", initial_values=True)
VerilogTextReader('NAndGate_TBV');         
Explanation: myHDL to Verilog Testbench
End of explanation
d=schem.Drawing(unit=.5)
#add elements
G=d.add(l.NAND2,d='right', label='$NAND_2$')
#Gate to led to gnd
d.add(e.LINE, d='right', xy=G.out)
d.add(e.DOT, label='$Y$')
d.add(e.LINE, d='down', l=d.unit*2)
LD0=d.add(e.LED, d='down', label='LD0')
d.add(e.LINE, d='down', l=d.unit*2)
d.add(e.GND)
d.add(e.LINE, d='left', xy=G.in1, l=d.unit)
d.add(e.DOT, label='$X_0$')
d.add(e.LINE,d='left', l=d.unit)
d.add(e.LINE,d='up', l=d.unit*2)
d.add(e.LINE,d='left', l=d.unit*2)
SW0=d.add(e.SWITCH_SPDT, lftlabel='SW0')
d.add(e.GND, xy=SW0.c)
d.add(e.VDD, xy=SW0.b)
d.add(e.LINE, d='left', xy=G.in2, l=d.unit)
d.add(e.DOT, botlabel='$X_1$')
d.add(e.LINE,d='left', l=d.unit)
d.add(e.LINE,d='down', l=d.unit*2)
d.add(e.LINE,d='left', l=d.unit*4)
SW1=d.add(e.SWITCH_SPDT, lftlabel='SW1')
d.add(e.GND, xy=SW1.c)
d.add(e.VDD, xy=SW1.b)
d.draw()
Explanation: \begin{figure}
\centerline{\includegraphics[width=10cm]{NAndGate_RTL.png}}
\caption{\label{fig:NAGRTL} NAndGate RTL schematic; Xilinx Vivado 2017.4}
\end{figure}
\begin{figure}
\centerline{\includegraphics[width=10cm]{NAndGate_SYN.png}}
\caption{\label{fig:NAGSYN} NAndGate Synthesized Schematic; Xilinx Vivado 2017.4}
\end{figure}
\begin{figure}
\centerline{\includegraphics[width=10cm]{NAndGate_IMP.png}}
\caption{\label{fig:NAGIMP} NAndGate Implementated Schematic; Xilinx Vivado 2017.4}
\end{figure}
PYNQ-Z1 Deyployment
Board Circuit
End of explanation
ConstraintXDCTextReader('PYNQ_Z1Constraints_NAndGate');
Explanation: Board Constraint
End of explanation
d = schem.Drawing(unit=.5)
G = d.add(l.NOR2, label='$NOR_2$')
d.add(e.DOT_OPEN, xy=G.out, rgtlabel='$Y$')
d.add(e.DOT_OPEN, xy=G.in1, lftlabel='$X_1$')
d.add(e.DOT_OPEN, xy=G.in2, lftlabel='$X_0$')
d.draw()
Explanation: Video of Deployment
NAND Gate myHDL PYNQ-Z1 (YouTube)
NOR
\begin{definition}\label{def:NorGate}
A NOR Gate is the negated, or the De Morgan equivalent, of an OR Gate. Such that is output will be True if and only if all its inputs are False. Its boolean expression is
$$Y=\overline{X_0+ X_1}$$
\end{definition}
One peculiar aspect of the NOR Gate is that from a pure Boolean algebra position it is one of the two "Universal Gates". Which means that any other gate can be constructed from no more than NOR Gates. See https://en.wikipedia.org/wiki/NOR_logic#Making_other_gates_by_using_NOR_gates  for more info. And while this somewhat holds True for ASIC circuits, this not entirely true in terms of FPGAs
End of explanation
X0, X1, Y=symbols('X_0, X_1, Y')
YEq=Eq(Y, Nor(X0,X1)); YEq
TruthTabelGenrator(YEq)
YEqN=lambdify([X0, X1], YEq.rhs, dummify=False)
SystmaticVals=np.array(list(itertools.product([0,1], repeat=2)))
SystmaticVals, YEqN(SystmaticVals[:, 1], SystmaticVals[:, 0]).astype(int)
Explanation: Sympy Expression
End of explanation
@block
def NOrGate(X0, X1, Y):
    
    NOr Gate demo module
    
    Input:
        X0(bool): Or gate input 0
        X1(bool): Or gate input 1
    
    Output:
        Y(bool): Or gate ouput 
    
    
    @always_comb
    def logic():
        #note here that `or` is used since this
        #is a bit wise OR 
        Y.next=not(X0 or X1)
        
        #if `|` had been used the conversion 
        #would yield `||` the .all() OR
        # when dealing with bus's and  behavior mux's this
        #distiction must be known
        #see:
        # https://stackoverflow.com/questions/17327680/what-is-the-difference-between-single-and-double-ampersand-binary-opera
    
    return instances()
Explanation: myHDL Module
End of explanation
#generate systmatic and random test values for NOrGate_TB
#stimules inputs X1 and X2
TestLen=10
SystmaticVals=list(itertools.product([0,1], repeat=2))
X0TVs=np.array([i[1] for i in SystmaticVals]).astype(int)
np.random.seed(24)
X0TVs=np.append(X0TVs, np.random.randint(0,2, TestLen)).astype(int)
X1TVs=np.array([i[0] for i in SystmaticVals]).astype(int)
np.random.seed(25)
X1TVs=np.append(X1TVs, np.random.randint(0,2, TestLen)).astype(int)
TestLen=len(X1TVs)
SystmaticVals, X1TVs, X0TVs, TestLen
Peeker.clear()
X0=Signal(bool(0)); Peeker(X0, 'X0')
X1=Signal(bool(0)); Peeker(X1, 'X1')
Y=Signal(bool(0)); Peeker(Y, 'Y')
DUT=NOrGate(X0, X1, Y)
def NOrGate_TB():
    
    myHDL only testbench for module `NOrGate`
    
    
    @instance
    def stimules():
        for i in range(TestLen):
            X0.next=int(X0TVs[i])
            X1.next=int(X1TVs[i])
            yield delay(1)
        
        raise StopSimulation()
        
    return instances()
sim=Simulation(DUT, NOrGate_TB(), *Peeker.instances()).run()            
Peeker.to_wavedrom('X1', 'X0', 'Y')
NOrData=Peeker.to_dataframe()
NOrData=NOrData[['X1', 'X0', 'Y']]
NOrData
NOrData['YRef']=NOrData.apply(lambda row:YEqN(row['X0'], row['X1']), axis=1).astype(int)
NOrData
Test=(NOrData['Y']==NOrData['YRef']).all()
print(f'Module `NOrGate` works as exspected: {Test}')
Explanation: myHDL Testing
End of explanation
DUT.convert()
VerilogTextReader('NOrGate');
Explanation: Verilog Conversion
End of explanation
#create BitVectora for NOrGate_TBV
X0TVs=intbv(int(''.join(X0TVs.astype(str)), 2))[TestLen:]
X1TVs=intbv(int(''.join(X1TVs.astype(str)), 2))[TestLen:]
X0TVs, bin(X0TVs), X1TVs, bin(X1TVs)
@block
def NOrGate_TBV():
    
    myHDL -> Verilog testbench for module `NOrGate`
    
    X0=Signal(bool(0))
    X1=Signal(bool(0))
    Y=Signal(bool(0))
    
    @always_comb
    def print_data():
        print(X0, X1, Y)
    
    #Test Signal Bit Vectors
    X0TV=Signal(X0TVs)
    X1TV=Signal(X1TVs)
    DUT=NOrGate(X0, X1, Y)
    @instance
    def stimules():
        for i in range(TestLen):
            X0.next=int(X0TV[i])
            X1.next=int(X1TV[i])
            yield delay(1)
        
        raise StopSimulation()
    return instances()
TB=NOrGate_TBV()
TB.convert(hdl="Verilog", initial_values=True)
VerilogTextReader('NOrGate_TBV');         
Explanation: \begin{figure}
\centerline{\includegraphics[width=10cm]{NOrGate_RTL.png}}
\caption{\label{fig:NOGRTL} NOrGate RTL schematic; Xilinx Vivado 2017.4}
\end{figure}
\begin{figure}
\centerline{\includegraphics[width=10cm]{NOrGate_SYN.png}}
\caption{\label{fig:NOGSYN} NOrGate Synthesized Schematic; Xilinx Vivado 2017.4}
\end{figure}
\begin{figure}
\centerline{\includegraphics[width=10cm]{NOrGate_IMP.png}}
\caption{\label{fig:NOGIMP} NOrGate Implementated Schematic; Xilinx Vivado 2017.4}
\end{figure}
myHDL to Verilog Testbench
End of explanation
d=schem.Drawing(unit=.5)
#add elements
G=d.add(l.NOR2,d='right', label='$NOR_2$')
#Gate to led to gnd
d.add(e.LINE, d='right', xy=G.out)
d.add(e.DOT, label='$Y$')
d.add(e.LINE, d='down', l=d.unit*2)
LD0=d.add(e.LED, d='down', label='LD0')
d.add(e.LINE, d='down', l=d.unit*2)
d.add(e.GND)
d.add(e.LINE, d='left', xy=G.in1, l=d.unit)
d.add(e.DOT, label='$X_0$')
d.add(e.LINE,d='left', l=d.unit)
d.add(e.LINE,d='up', l=d.unit*2)
d.add(e.LINE,d='left', l=d.unit*2)
SW0=d.add(e.SWITCH_SPDT, lftlabel='SW0')
d.add(e.GND, xy=SW0.c)
d.add(e.VDD, xy=SW0.b)
d.add(e.LINE, d='left', xy=G.in2, l=d.unit)
d.add(e.DOT, botlabel='$X_1$')
d.add(e.LINE,d='left', l=d.unit)
d.add(e.LINE,d='down', l=d.unit*2)
d.add(e.LINE,d='left', l=d.unit*4)
SW1=d.add(e.SWITCH_SPDT, lftlabel='SW1')
d.add(e.GND, xy=SW1.c)
d.add(e.VDD, xy=SW1.b)
d.draw()
Explanation: PYNQ-Z1 Deployment
Board Circuit
End of explanation
ConstraintXDCTextReader('PYNQ_Z1Constraints_NOrGate');
Explanation: Board Constraint
End of explanation
d = schem.Drawing(unit=.5)
G = d.add(l.XNOR2, label='$XNOR_2$')
d.add(e.DOT_OPEN, xy=G.out, rgtlabel='$Y$')
d.add(e.DOT_OPEN, xy=G.in1, lftlabel='$X_1$')
d.add(e.DOT_OPEN, xy=G.in2, lftlabel='$X_0$')
d.draw()
Explanation: Video of Deployment
AND Gate myHDL PYNQ-Z1 (YouTube)
XNOR
\begin{definition}\label{def:XNorGate}
An XNOR Gate is the negated, or the De Morgan equivalent, of an XOR Gate. Such that is output will be True if and only if all its inputs are the same. Its boolean expression is typically
$$Y=X_0 \odot X_1$$ using its typical notation, wich is a refinment of the $\cdot$ notation used for an AND Gate. But can also be expressed as 
$$Y=X_0 X_1+ \overline{X_0}\overline{X_1}$$
\end{definition}
End of explanation
X0, X1, Y=symbols('X_0, X_1, Y')
#expanded exspresion of XNOR
YEq=Eq(Y, X0&X1|~X0&~X1); YEq
TruthTabelGenrator(YEq)
YEqN=lambdify([X0, X1], YEq.rhs, dummify=False)
SystmaticVals=np.array(list(itertools.product([0,1], repeat=2)))
SystmaticVals, YEqN(SystmaticVals[:, 1], SystmaticVals[:, 0]).astype(int)
Explanation: Sympy Expression
End of explanation
@block
def XNOrGate(X0, X1, Y):
    
    XNOR Gate demo module
    
    Input:
        X0(bool): XOR gate input 0
        X1(bool): XOR gate input 1
    
    Output:
        Y(bool): XOR gate ouput 
    
    
    @always_comb
    def logic():
        Y.next=not(X0 ^ X1)
        
    return instances()
Explanation: myHDL Module
End of explanation
#generate systmatic and random test values for XNOrGate_TB
#stimules inputs X1 and X2
TestLen=10
SystmaticVals=list(itertools.product([0,1], repeat=2))
X0TVs=np.array([i[1] for i in SystmaticVals]).astype(int)
np.random.seed(26)
X0TVs=np.append(X0TVs, np.random.randint(0,2, TestLen)).astype(int)
X1TVs=np.array([i[0] for i in SystmaticVals]).astype(int)
np.random.seed(27)
X1TVs=np.append(X1TVs, np.random.randint(0,2, TestLen)).astype(int)
TestLen=len(X1TVs)
SystmaticVals, X1TVs, X0TVs, TestLen
Peeker.clear()
X0=Signal(bool(0)); Peeker(X0, 'X0')
X1=Signal(bool(0)); Peeker(X1, 'X1')
Y=Signal(bool(0)); Peeker(Y, 'Y')
DUT=XNOrGate(X0, X1, Y)
def XNOrGate_TB():
    
    myHDL only testbench for module `NOrGate`
    
    
    @instance
    def stimules():
        for i in range(TestLen):
            X0.next=int(X0TVs[i])
            X1.next=int(X1TVs[i])
            yield delay(1)
        
        raise StopSimulation()
        
    return instances()
sim=Simulation(DUT, XNOrGate_TB(), *Peeker.instances()).run()            
Peeker.to_wavedrom('X1', 'X0', 'Y')
XNOrData=Peeker.to_dataframe()
XNOrData=XNOrData[['X1', 'X0', 'Y']]
XNOrData
XNOrData['YRef']=XNOrData.apply(lambda row:YEqN(row['X0'], row['X1']), axis=1).astype(int)
XNOrData
Test=(XNOrData['Y']==XNOrData['YRef']).all()
print(f'Module `XNOrGate` works as exspected: {Test}')
Explanation: myHDL Testing
End of explanation
DUT.convert()
VerilogTextReader('XNOrGate');
Explanation: Verilog Conversion
End of explanation
#create BitVectora for XNOrGate_TBV
X0TVs=intbv(int(''.join(X0TVs.astype(str)), 2))[TestLen:]
X1TVs=intbv(int(''.join(X1TVs.astype(str)), 2))[TestLen:]
X0TVs, bin(X0TVs), X1TVs, bin(X1TVs)
@block
def XNOrGate_TBV():
    
    myHDL -> Verilog testbench for module `NOrGate`
    
    X0=Signal(bool(0))
    X1=Signal(bool(0))
    Y=Signal(bool(0))
    
    @always_comb
    def print_data():
        print(X0, X1, Y)
    
    #Test Signal Bit Vectors
    X0TV=Signal(X0TVs)
    X1TV=Signal(X1TVs)
    DUT=XNOrGate(X0, X1, Y)
    @instance
    def stimules():
        for i in range(TestLen):
            X0.next=int(X0TV[i])
            X1.next=int(X1TV[i])
            yield delay(1)
        
        raise StopSimulation()
    return instances()
TB=XNOrGate_TBV()
TB.convert(hdl="Verilog", initial_values=True)
VerilogTextReader('XNOrGate_TBV');         
Explanation: \begin{figure}
\centerline{\includegraphics[width=10cm]{XNOrGate_RTL.png}}
\caption{\label{fig:XNOGRTL} XNOrGate RTL schematic; Xilinx Vivado 2017.4}
\end{figure}
\begin{figure}
\centerline{\includegraphics[width=10cm]{XNOrGate_SYN.png}}
\caption{\label{fig:XNOGSYN} XNOrGate Synthesized Schematic; Xilinx Vivado 2017.4}
\end{figure}
\begin{figure}
\centerline{\includegraphics[width=10cm]{XNOrGate_IMP.png}}
\caption{\label{fig:XNOGIMP} XNOrGate Implementated Schematic; Xilinx Vivado 2017.4}
\end{figure}
myHDL to Verilog Testbench
End of explanation
d=schem.Drawing(unit=.5)
#add elements
G=d.add(l.XNOR2,d='right', label='$XNOR_2$')
#Gate to led to gnd
d.add(e.LINE, d='right', xy=G.out)
d.add(e.DOT, label='$Y$')
d.add(e.LINE, d='down', l=d.unit*2)
LD0=d.add(e.LED, d='down', label='LD0')
d.add(e.LINE, d='down', l=d.unit*2)
d.add(e.GND)
d.add(e.LINE, d='left', xy=G.in1, l=d.unit)
d.add(e.DOT, label='$X_0$')
d.add(e.LINE,d='left', l=d.unit)
d.add(e.LINE,d='up', l=d.unit*2)
d.add(e.LINE,d='left', l=d.unit*2)
SW0=d.add(e.SWITCH_SPDT, lftlabel='SW0')
d.add(e.GND, xy=SW0.c)
d.add(e.VDD, xy=SW0.b)
d.add(e.LINE, d='left', xy=G.in2, l=d.unit)
d.add(e.DOT, botlabel='$X_1$')
d.add(e.LINE,d='left', l=d.unit)
d.add(e.LINE,d='down', l=d.unit*2)
d.add(e.LINE,d='left', l=d.unit*4)
SW1=d.add(e.SWITCH_SPDT, lftlabel='SW1')
d.add(e.GND, xy=SW1.c)
d.add(e.VDD, xy=SW1.b)
d.draw()
Explanation: PYNQ-Z1 Deployment
Board Circuit
End of explanation
ConstraintXDCTextReader('PYNQ_Z1Constraints_XNOrGate');
Explanation: Board Constraint
End of explanation
<END_TASK>