```python
name = "Daniel Silva Lopes da Costa"  # write YOUR NAME

honorPledge = "I affirm that I have not given or received any unauthorized " \
              "help on this assignment, and that this work is my own.\n"

print("\nName: ", name)
print("\nHonor pledge: ", honorPledge)
```

    Name:  Daniel Silva Lopes da Costa

    Honor pledge:  I affirm that I have not given or received any unauthorized help on this assignment, and that this work is my own.

# MAC0460 / MAC5832 (2021)

# EP2: Linear regression - analytic solution

### Objectives:

- to implement and test the analytic solution for the linear regression task (see, for instance, Slides of Lecture 03 and Lecture 03 of *Learning from Data*)
- to understand the core idea (*optimization of a loss or cost function*) for parameter adjustment in machine learning

# Linear regression

Given a dataset $\{(\mathbf{x}^{(1)}, y^{(1)}), \dots ,(\mathbf{x}^{(N)}, y^{(N)})\}$ with $\mathbf{x}^{(i)} \in \mathbb{R}^{d}$ and $y^{(i)} \in \mathbb{R}$, we would like to approximate the unknown function $f:\mathbb{R}^{d} \rightarrow \mathbb{R}$ (recall that $y^{(i)} =f(\mathbf{x}^{(i)})$) by means of a linear model $h$:
$$
h(\mathbf{x}^{(i)}; \mathbf{w}, b) = \mathbf{w}^\top  \mathbf{x}^{(i)} + b
$$

Note that $h(\mathbf{x}^{(i)}; \mathbf{w}, b)$ is, in fact, an  [affine transformation](https://en.wikipedia.org/wiki/Affine_transformation) of  $\mathbf{x}^{(i)}$. As commonly done, we will use the term "linear" to refer to an affine transformation.

The output of $h$ is a linear transformation of $\mathbf{x}^{(i)}$. We use the notation $h(\mathbf{x}^{(i)}; \mathbf{w}, b)$ to make clear that $h$ is a parametric model, i.e., the transformation $h$ is defined  by the parameters $\mathbf{w}$ and $b$. We can view vector $\mathbf{w}$ as a *weight* vector that controls the effect of each *feature* in the prediction.

By adding one component with value equal to 1 to the observations $\mathbf{x}$ (an artificial coordinate), we have:

$$\tilde{\mathbf{x}} = (1, x_1, \ldots, x_d) \in \mathbb{R}^{1+d}$$

and then we can simplify the notation:
$$
h(\mathbf{x}^{(i)}; \mathbf{w}) = \hat{y}^{(i)} = \mathbf{w}^\top  \tilde{\mathbf{x}}^{(i)}
$$

We would like to determine the optimal parameters $\mathbf{w}$ such that prediction $\hat{y}^{(i)}$ is as closest as possible to $y^{(i)}$ according to some error metric. Adopting the *mean square error* as such metric we have the following cost function:

\begin{equation}
J(\mathbf{w}) = \frac{1}{N}\sum_{i=1}^{N}\big(\hat{y}^{(i)} - y^{(i)}\big)^{2}
\end{equation}

Thus, the task of determining a function $h$ that is closest to $f$ is reduced to the task of finding the values $\mathbf{w}$ that minimize $J(\mathbf{w})$.

**Now we will explore this model, starting with a simple dataset.**

### Auxiliary functions

```python
# some imports
import numpy as np
import time
import matplotlib.pyplot as plt

%matplotlib inline
```

```python
# An auxiliary function
def get_housing_prices_data(N, verbose=True):
    """
    Generates artificial linear data,
    where x = square meter, y = house price

    :param N: data set size
    :type N: int

    :param verbose: param to control print
    :type verbose: bool
    :return: design matrix, regression targets
    :rtype: np.array, np.array
    """
    cond = False
    while not cond:
        x = np.linspace(90, 1200, N)
        gamma = np.random.normal(30, 10, x.size)
        y = 50 * x + gamma * 400
        x = x.astype("float32")
        x = x.reshape((x.shape[0], 1))
        y = y.astype("float32")
        y = y.reshape((y.shape[0], 1))
        cond = min(y) > 0

    xmean, xsdt, xmax, xmin = np.mean(x), np.std(x), np.max(x), np.min(x)
    ymean, ysdt, ymax, ymin = np.mean(y), np.std(y), np.max(y), np.min(y)
    if verbose:
        print("\nX shape = {}".format(x.shape))
        print("y shape = {}\n".format(y.shape))
        print("X: mean {}, sdt {:.2f}, max {:.2f}, min {:.2f}".format(xmean,
                                                               xsdt,
                                                               xmax,
                                                               xmin))
        print("y: mean {:.2f}, sdt {:.2f}, max {:.2f}, min {:.2f}".format(ymean,
                                                                 ysdt,
                                                                 ymax,
                                                                 ymin))
    return x, y
```

```python
# Another auxiliary function
def plot_points_regression(x,
                           y,
                           title,
                           xlabel,
                           ylabel,
                           prediction=None,
                           legend=False,
                           r_squared=None,
                           position=(90, 100)):
    """
    Plots the data points and the prediction,
    if there is one.

    :param x: design matrix
    :type x: np.array
    :param y: regression targets
    :type y: np.array
    :param title: plot's title
    :type title: str
    :param xlabel: x axis label
    :type xlabel: str
    :param ylabel: y axis label
    :type ylabel: str
    :param prediction: model's prediction
    :type prediction: np.array
    :param legend: param to control print legends
    :type legend: bool
    :param r_squared: r^2 value
    :type r_squared: float
    :param position: text position
    :type position: tuple
    """
    fig, ax = plt.subplots(1, 1, figsize=(8, 8))
    line1, = ax.plot(x, y, 'bo', label='Real data')
    if prediction is not None:
        line2, = ax.plot(x, prediction, 'r', label='Predicted data')
        if legend:
            plt.legend(handles=[line1, line2], loc=2)
        ax.set_title(title,
                 fontsize=20,
                 fontweight='bold')
    if r_squared is not None:
        bbox_props = dict(boxstyle="square,pad=0.3",
                          fc="white", ec="black", lw=0.2)
        t = ax.text(position[0], position[1], "$R^2 ={:.4f}$".format(r_squared),
                    size=15, bbox=bbox_props)

    ax.set_xlabel(xlabel, fontsize=20)
    ax.set_ylabel(ylabel, fontsize=20)
    plt.show()

```

### The dataset

The first dataset we will use is a toy dataset. We will generate $N=100$ observations with only one *feature* and a real value associated to each of them. We can view these observations as being pairs *(area of a real state in square meters, price of the real state)*. Our task is to construct a model that is able to predict the price of a real state, given its area.

```python
X, y = get_housing_prices_data(N=100)
```

    X shape = (100, 1)
    y shape = (100, 1)

    X: mean 645.0, sdt 323.65, max 1200.00, min 90.00
    y: mean 44003.19, sdt 17195.94, max 79998.91, min 5441.34

### Ploting the data

```python
plot_points_regression(X,
                       y,
                       title='Real estate prices prediction',
                       xlabel="m\u00b2",
                       ylabel='$')
```

### The solution

Given $f:\mathbb{R}^{N\times M} \rightarrow \mathbb{R}$ and $\mathbf{A} \in \mathbb{R}^{N\times M}$, we define the gradient of $f$ with respect to $\mathbf{A}$ as:

\begin{equation*}
\nabla_{\mathbf{A}}f = \frac{\partial f}{\partial \mathbf{A}} =  \begin{bmatrix}
\frac{\partial f}{\partial \mathbf{A}_{1,1}} & \dots & \frac{\partial f}{\partial \mathbf{A}_{1,m}} \\
\vdots &  \ddots & \vdots \\
\frac{\partial f}{\partial \mathbf{A}_{n,1}} &  \dots & \frac{\partial f}{\partial \mathbf{A}_{n,m}}
\end{bmatrix}
\end{equation*}

Let $\mathbf{X} \in \mathbb{R}^{N\times d}$ be a matrix (sometimes also called the *design matrix*) whose rows are the observations of the dataset and let $\mathbf{y} \in \mathbb{R}^{N}$ be the vector consisting of all values $y^{(i)}$ (i.e., $\mathbf{X}^{(i,:)} = \mathbf{x}^{(i)}$ and $\mathbf{y}^{(i)} = y^{(i)}$). It can be verified that:

\begin{equation}
J(\mathbf{w}) = \frac{1}{N}(\mathbf{X}\mathbf{w} - \mathbf{y})^{T}(\mathbf{X}\mathbf{w} - \mathbf{y})
\end{equation}

Using basic matrix derivative concepts we can compute the gradient of $J(\mathbf{w})$ with respect to $\mathbf{w}$:

\begin{equation}
\nabla_{\mathbf{w}}J(\mathbf{w}) = \frac{2}{N} (\mathbf{X}^{T}\mathbf{X}\mathbf{w} -\mathbf{X}^{T}\mathbf{y})
\end{equation}

Thus, when $\nabla_{\mathbf{w}}J(\mathbf{w}) = 0$ we have

\begin{equation}
\mathbf{X}^{T}\mathbf{X}\mathbf{w} = \mathbf{X}^{T}\mathbf{y}
\end{equation}

Hence,

\begin{equation}
\mathbf{w} = (\mathbf{X}^{T}\mathbf{X})^{-1}\mathbf{X}^{T}\mathbf{y}
\end{equation}

Note that this solution has a high computational cost. As the number of variables (*features*) increases, the cost for matrix inversion becomes prohibitive. See  [this text](https://sgfin.github.io/files/notes/CS229_Lecture_Notes.pdf) for more details.

# Exercise 1
Using only **NumPy** (a quick introduction to this library can be found  [here](http://cs231n.github.io/python-numpy-tutorial/)), complete the two functions below. Recall that $\mathbf{X} \in \mathbb{R}^{N\times d}$; thus you will need to add a component of value 1 to each of  the observations in $\mathbf{X}$ before performing the computation described above.

NOTE: Although the dataset above has data of dimension $d=1$, your code must be generic (it should work for $d\geq1$)

## 1.1. Weight computation function

```python
def normal_equation_weights(X, y):
    """
    Calculates the weights of a linear function using the normal equation method.
    You should add into X a new column with 1s.

    :param X: design matrix
    :type X: np.ndarray(shape=(N, d))
    :param y: regression targets
    :type y: np.ndarray(shape=(N, 1))
    :return: weight vector
    :rtype: np.ndarray(shape=(d+1, 1))
    """

    # START OF YOUR CODE:
    X = np.hstack(( np.ones((X.shape[0],1)), X ) )
    #print(X.T)
    Xt = np.linalg.inv(np.dot(X.T, X))
    w = np.dot(np.dot(Xt, X.T), y)
    return w
    raise NotImplementedError("Function normal_equation_weights() is not implemented")
    # END OF YOUR CODE

```

```python
# test of function normal_equation_weights()

w = 0  # this is not necessary
w = normal_equation_weights(X, y)
print("Estimated w =\n", w)
```

    Estimated w =
     [[10804.41058626]
     [   51.47097573]]

## 1.2. Prediction function

```python
def normal_equation_prediction(X, w):
    """
    Calculates the prediction over a set of observations X using the linear function
    characterized by the weight vector w.
    You should add into X a new column with 1s.

    :param X: design matrix
    :type X: np.ndarray(shape=(N, d))
    :param w: weight vector
    :type w: np.ndarray(shape=(d+1, 1))
    :param y: regression prediction
    :type y: np.ndarray(shape=(N, 1))
    """

    # START OF YOUR CODE:
    X = np.hstack(( np.ones((X.shape[0],1)), X ) )
    Y = np.dot(X, w)
    return Y
    raise NotImplementedError("Function normal_equation_prediction() is not implemented")
    # END OF YOUR CODE

```

## 1.3. Coefficient of determination
We can use the [$R^2$](https://pt.wikipedia.org/wiki/R%C2%B2) metric (Coefficient of determination) to evaluate how well the linear model fits the data.

**Which $𝑅^2$ value would you expect to observe ?**

```python
from sklearn.metrics import r2_score

# test of function normal_equation_prediction()
prediction = normal_equation_prediction(X, w)

# compute the R2 score using the r2_score function from sklearn
# Replace 0 with an appropriate call of the function

# START OF YOUR CODE:
r_2 = r2_score(y, prediction)
# END OF YOUR CODE

plot_points_regression(X,
                       y,
                       title='Real estate prices prediction',
                       xlabel="m\u00b2",
                       ylabel='$',
                       prediction=prediction,
                       legend=True,
                       r_squared=r_2)
```

## Additional tests

Let us compute a prediction for $x=650$

```python
# Let us use the prediction function
x = np.asarray([650]).reshape(1,1)
prediction = normal_equation_prediction(x, w)
print("Area = %.2f  Predicted price = %.4f" %(x[0], prediction))
```

    Area = 650.00  Predicted price = 44260.5448

## 1.4. Processing time

Experiment with different nummber of samples $N$ and observe how processing time varies.

Be careful not to use a too large value; it may make jupyter freeze ...

```python
# Add other values for N
# START OF YOUR CODE:
N = [1600]
# END OF YOUR CODE

for i in N:
    X, y = get_housing_prices_data(N=i)
    init = time.time()
    w = normal_equation_weights(X, y)
    prediction = normal_equation_prediction(X,w)
    init = time.time() - init

    print("\nExecution time = {:.8f}(s)\n".format(init))

# Tempos de algumas análises:
# N       Tempo(s)
# 100     0.00376582
# 200     0.00273514
# 400     0.00603080
# 800     0.00363159
# 1600    0.00614405

```

    X shape = (1600, 1)
    y shape = (1600, 1)

    X: mean 645.0, sdt 320.63, max 1200.00, min 90.00
    y: mean 44313.57, sdt 16460.92, max 81999.68, min 7103.05

    Execution time = 0.00114775(s)

# Exercise 2

Let us test the code with $𝑑>1$.
We will use the data we have collected in our first class. The [file](https://edisciplinas.usp.br/pluginfile.php/5982803/course/section/6115454/QT1data.csv) can be found on e-disciplinas.

Let us try to predict the weight based on one or more features.

```python
import pandas as pd

# load the dataset
df = pd.read_csv('QT1data.csv')
df.head()
```

      Sex
      Age
      Height
      Weight
      Shoe number
      Trouser number

      0
      Female
      53
      154
      59
      36
      40

      1
      Male
      23
      170
      56
      40
      38

      2
      Female
      23
      167
      63
      37
      40

      3
      Male
      21
      178
      78
      40
      40

      4
      Female
      25
      153
      58
      36
      38

```python
df.describe()
```

      Age
      Height
      Weight
      Shoe number

      count
      130.000000
      130.000000
      130.000000
      130.000000

      mean
      28.238462
      170.684615
      70.238462
      39.507692

      std
      12.387042
      11.568491
      15.534809
      2.973386

      min
      3.000000
      100.000000
      15.000000
      24.000000

      25%
      21.000000
      164.250000
      60.000000
      38.000000

      50%
      23.000000
      172.000000
      69.500000
      40.000000

      75%
      29.000000
      178.000000
      80.000000
      41.000000

      max
      62.000000
      194.000000
      130.000000
      46.000000

```python
# Our target variable is the weight
y = df.pop('Weight').values
y
```

    array([ 59,  56,  63,  78,  58,  89,  68,  83,  70,  56,  65,  66,  78,
            75,  47,  68,  65,  99,  80,  62,  60,  84,  91,  60,  15,  85,
            56,  62,  69,  78,  60,  48,  66,  85, 101,  74,  52,  52,  80,
            72,  75,  78,  61,  74,  70,  90,  66,  79,  80,  65,  90,  69,
            58,  63,  62,  73,  55,  65,  62,  75,  48,  59,  74,  80,  51,
            90,  58, 117,  77,  75,  56,  50,  67,  93,  70,  76,  85,  50,
            86,  96,  63,  56,  90,  95, 130,  70,  83,  70,  64,  57,  54,
            69,  53,  28,  62,  68,  73,  54,  75,  85,  62,  69,  55,  82,
            84,  52,  64,  73,  86,  77,  64,  65,  55,  50,  98,  77,  51,
            66,  83,  61,  80,  81,  76,  78,  70,  75,  72,  80,  90,  53])

## 2.1. One feature ($d=1$)

We will use 'Height' as the input feature and predict the weight

```python
feature_cols = ['Height']
X = df.loc[:, feature_cols]
X.shape
```

    (130, 1)

Write the code for computing the following
- compute the regression weights using $\mathbf{X}$ and $\mathbf{y}$
- compute the prediction
- compute the $R^2$ value
- plot the regression graph (use appropriate values for the parameters of function <tt>plot_points_regression()</tt>)

```python
# START OF YOUR CODE:
w = normal_equation_weights(X, y)
prediction = normal_equation_prediction(X, w)
r_2 = r2_score(y, prediction)
print("Erro quadrático médio:", r_2)

plot_points_regression(X,
                       y,
                       title='Predição de peso pela altura',
                       xlabel="altura(cm)",
                       ylabel='peso(kg)',
                       prediction=prediction,
                       legend=True,
                       r_squared=r_2)

# END OF YOUR CODE

```

## 2.2 - Two input features ($d=2$)

Now repeat the exercise with using as input the features 'Height' and 'Shoe number'

- compute the regression weights using $\mathbf{X}$ and $\mathbf{y}$
- compute the prediction
- compute and print the $R^2$ value

Note that our plotting function can not be used. There is no need to do plotting here.

```python
# START OF YOUR CODE:
feature_cols = ['Height', 'Shoe number']
X = df.loc[:, feature_cols]
w = normal_equation_weights(X, y)
prediction = normal_equation_prediction(X, w)
r_2 = r2_score(y, prediction)
print("Erro quadrático médio:", r_2)
# END OF YOUR CODE

```

    Erro quadrático médio: 0.45381183096658595

## 2.3 - Three input features ($d=3$)

Now try with three features. There is no need to do plotting here.
- compute the regression weights using $\mathbf{X}$ and $\mathbf{y}$
- compute the prediction
- compute and print the $R^2$ value

```python
# START OF YOUR CODE:
feature_cols = ['Height', 'Shoe number', 'Age' ]
X = df.loc[:, feature_cols]
w = normal_equation_weights(X, y)
prediction = normal_equation_prediction(X, w)
r_2 = r2_score(y, prediction)
print("Erro quadrático médio:", r_2)
# END OF YOUR CODE

```

    Erro quadrático médio: 0.4776499498669615

## 2.4 - Your comments

Did you observe anything interesting with varying values of $d$ ? Comment about it.

YOUR COMMENT BELOW:

===> O  errro quadrático aumentou com o aumento das hispóteses. O que evidencia uma discussão desenvolvida em aula de como, mesmo com um conjunto mais diversificado de hipóteses não necessariamente o algorimto ficaria melhor, principalmente na regressão linear.


\title{Shift Registers in myHDL}
\author{Steven K Armour}
\maketitle

Shift registers are common structures that move around data in primitive memory by rearranging the bit order. While shift registers are built as needed they typically fall into five categories. The four conversion types: PIPO, PISO, SISO, SIPO; and cyclic shift registers such as the ring and Johnson counters. Wich can be used as counters but are in reality shift registers since they reorder the bits in the modules internal memory

Table of Contents

1  Refrances

2  Libraries and Helper functions

3  Parallel-In Parallel-Out (PIPO) Shift Register

3.1  Asynchronous

3.1.1  myHDL Testing

3.1.2  Verilog Code

3.1.3  Verilog Testbench (!ToDo)

3.2  Synchronous 1

3.2.1  myHDL Module

3.2.2  myHDL Testing

3.2.3  Verilog Code

3.3  Synchronous 2

3.3.1  myHDL Module

3.3.2  myHDL Testing

3.3.3  Verilog Code

3.4  Comparison of the three designs

4  Parallel-In Serial-Out (PISO)

4.1  myHDL Module

4.2  myHDL Testing

4.3  Verilog Code

4.4  Verilog Testbench (!ToDo)

5  Serial-In Serial-Out (SISO)

5.1  myHDL Module

5.2  myHDL Testing

5.3  Verilog Code

5.4  Verilog Testbench

6  Serial-In Parallel-Out (SIPO)

6.1  myHDL Module

6.2  myHDL Testing

6.3  Verilog Code

6.4  Verilog Testbench

7  Cyclic Shift Register Johnson Counter

7.1  myHDL Module

7.2  myHDL Testing

7.3  Verilog  Code

7.4  Verilog Testbench

7.5  PYNQ-Z1 Deployment

7.5.1  Board Constraints

7.5.2  Deployment Results

8  Cyclic Shift Register Ring Counter

8.1  myHDL Module

8.2  myHDL testing

8.3  Verilog Code

8.4  Verilog Testbench

8.5  PYNQ-Z1 Deployment

8.5.1  Block Design

8.5.2  Board Constraints

8.5.3  RTL, Synthesis, & Implementation

8.5.4  Deployment Results

# Refrances
@misc{myhdl_2017,
title={Johnson Counter},
url={http://www.myhdl.org/docs/examples/jc2.html},
journal={Myhdl.org},
author={myHDL},
year={2017}
}

@misc{the shift register,
url={https://www.electronics-tutorials.ws/sequential/seq_5.html},
journal={Electronics Tutorials}
},

@misc{petrescu,
title={Shift Registers},
url={http://www.csit-sun.pub.ro/courses/Masterat/Xilinx%20Synthesis%20Technology/toolbox.xilinx.com/docsan/xilinx4/data/docs/xst/hdlcode8.html},
journal={Csit-sun.pub.ro},
author={Petrescu, Adrian}
},

@misc{reddy_2014,
title={verilog code for ALU,SISO,PIPO,SIPO,PISO},
url={http://thrinadhreddy.blogspot.com/2014/01/verilog-code-for-alusisopiposipopiso.html},
journal={Thrinadhreddy.blogspot.com},
author={Reddy, Trinadh},
year={2014}
}

# Libraries and Helper functions

```python
#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 random

#https://github.com/jrjohansson/version_information
%load_ext version_information
%version_information myhdl, myhdlpeek, numpy, pandas, matplotlib, sympy, random
```

Software	Version

Python	3.6.2 64bit [GCC 4.4.7 20120313 (Red Hat 4.4.7-1)]

IPython	6.2.1

OS	Linux 4.15.0 30 generic x86_64 with debian stretch sid

myhdl	0.10

myhdlpeek	0.0.6

numpy	1.13.3

pandas	0.23.3

matplotlib	2.1.0

sympy	1.1.2.dev

random	The 'random' distribution was not found and is required by the application

Wed Sep 05 07:50:11 2018 MDT

```python
#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
```

```python
CountVal=17
BitSize=int(np.log2(CountVal))+1; BitSize
```

# Parallel-In Parallel-Out (PIPO) Shift Register

A PIPO shift Register is one of the most redundant of the four classic shift registers when used as a One Bus In, *One* Bus Out, thus the PIPO here is implemented as a One Bus In, *Two* Bus Out. Further, this opportunity is taken here to talk about HDL algorithms vs HDL Implementation by presenting the same One In, Two Out PIPO but implemented as an asynchronous case and two synchronous cases. While there are obvious differences algorithmically due to the asynchronous vs synchronous. The hardware implementation is even more strikingly different and serves as case in point that HDL programming is neither hardware or software but an intermedte between the worlds.  But with grave consequences when translated into hardware that the HDL must keep in perspective when writing Hardware Descriptive Language code.

```python
TestData=np.random.randint(0, 2**4, 15); TestData
```

    array([ 2,  7,  8, 11,  0, 14,  1,  5, 12,  1, 13,  8,  2, 11,  6])

## Asynchronous

```python
@block
def PIPO_AS1(DataIn, DataOut1, DataOut2):
    """
    1:2 PIPO shift regestor with no clock (Asynchronous)

    Input:
        DataIn(bitvec)
    Output:
        DataOut1(bitVec): ouput one bitvec len should be same as
            `DataIn`
        DataOut2(bitVec):ouput two bitvec len should be same as
            `DataIn`
    """
    @always_comb
    def logic():
        DataOut1.next=DataIn
        DataOut2.next=DataIn

    return instances()

```

### myHDL Testing

```python
Peeker.clear()
clk=Signal(bool(0)); Peeker(clk, 'clk')
rst=Signal(bool(0)); Peeker(rst, 'rst')
DataIn=Signal(intbv(0)[4:]); Peeker(DataIn, 'DataIn')
DataOut1=Signal(intbv(0)[4:]); Peeker(DataOut1, 'DataOut1')
DataOut2=Signal(intbv(0)[4:]); Peeker(DataOut2, 'DataOut2')

DUT=PIPO_AS1(DataIn, DataOut1, DataOut2)

def PIPO_TB():
    """
    myHDL only Testbench for `PIPO_*` module
    """
    @always(delay(1))
    def ClkGen():
        clk.next=not clk

    @instance
    def stimules():
        i=0
        while True:

            DataIn.next=int(TestData[i])

            if i==14:
                raise StopSimulation()

            i+=1
            yield clk.posedge

    return instances()

sim=Simulation(DUT, PIPO_TB(), *Peeker.instances()).run()
```

```python
Peeker.to_wavedrom()
```

```python
PIPO_AS1Data=Peeker.to_dataframe();
PIPO_AS1Data=PIPO_AS1Data[PIPO_AS1Data['clk']==1]
PIPO_AS1Data.drop(['clk', 'rst'], axis=1, inplace=True)
PIPO_AS1Data.reset_index(drop=True, inplace=True)
PIPO_AS1Data
```

      DataIn
      DataOut1
      DataOut2

      0
      7
      7
      7

      1
      8
      8
      8

      2
      11
      11
      11

      3
      0
      0
      0

      4
      14
      14
      14

      5
      1
      1
      1

      6
      5
      5
      5

      7
      12
      12
      12

      8
      1
      1
      1

      9
      13
      13
      13

      10
      8
      8
      8

      11
      2
      2
      2

      12
      11
      11
      11

### Verilog Code

```python
DUT.convert()
VerilogTextReader('PIPO_AS1');
```

    ***Verilog modual from PIPO_AS1.v***

     // File: PIPO_AS1.v
    // Generated by MyHDL 0.10
    // Date: Wed Sep  5 07:50:17 2018

    `timescale 1ns/10ps

    module PIPO_AS1 (
        DataIn,
        DataOut1,
        DataOut2
    );
    // 1:2 PIPO shift regestor with no clock (Asynchronous)
    //
    // Input:
    //     DataIn(bitvec)
    // Output:
    //     DataOut1(bitVec): ouput one bitvec len should be same as
    //         `DataIn`
    //     DataOut2(bitVec):ouput two bitvec len should be same as
    //         `DataIn`

    input [3:0] DataIn;
    output [3:0] DataOut1;
    wire [3:0] DataOut1;
    output [3:0] DataOut2;
    wire [3:0] DataOut2;

    assign DataOut1 = DataIn;
    assign DataOut2 = DataIn;

    endmodule

\begin{figure}
\centerline{\includegraphics[width=10cm]{PIPO_AS1_RTL.png}}
\caption{\label{fig:APIPORTL} PIPO_AS1 Shift Register RTL schematic; Xilinx Vivado 2017.4}
\end{figure}

\begin{figure}
\centerline{\includegraphics[width=10cm]{PIPO_AS1_SYN.png}}
\caption{\label{fig:APIPOSYN} PIPO_AS1 Shift Register Synthesized Schematic; Xilinx Vivado 2017.4}
\end{figure}

### Verilog Testbench (!ToDo)

## Synchronous 1

### myHDL Module

```python
@block
def PIPO_S1(DataIn, DataOut1, DataOut2, clk, rst):
    """
    one-in two-out PIPO typicaly found in the lititure
    lacking buffering

    Inputs:
        DataIn(bitVec): one-in Parallel data int
        clk(bool): clock
        rst(bool): reset

    Ouputs:
        DataOut1(bitVec): Parallel out 1
        DataOut2(bitVec): Parallel out 1

    """

    @always(clk.posedge, rst.negedge)
    def logic():
        if rst:
            DataOut1.next=0
            DataOut2.next=0
        else:
            DataOut1.next=DataIn
            DataOut2.next=DataIn

    return instances()

```

### myHDL Testing

```python
Peeker.clear()
clk=Signal(bool(0)); Peeker(clk, 'clk')
rst=Signal(bool(0)); Peeker(rst, 'rst')
DataIn=Signal(intbv(0)[4:]); Peeker(DataIn, 'DataIn')
DataOut1=Signal(intbv(0)[4:]); Peeker(DataOut1, 'DataOut1')
DataOut2=Signal(intbv(0)[4:]); Peeker(DataOut2, 'DataOut2')

DUT=PIPO_S1(DataIn, DataOut1, DataOut2, clk, rst)

def PIPO_TB():
    """
    myHDL only Testbench for `RingCounter` module
    """
    @always(delay(1))
    def ClkGen():
        clk.next=not clk

    @instance
    def stimules():
        i=0
        while True:

            DataIn.next=int(TestData[i])

            if i==14:
                raise StopSimulation()

            i+=1
            yield clk.posedge

    return instances()

sim=Simulation(DUT, PIPO_TB(), *Peeker.instances()).run()
```

```python
Peeker.to_wavedrom()
```

```python
PIPO_S1Data=Peeker.to_dataframe();
PIPO_S1Data=PIPO_S1Data[PIPO_S1Data['clk']==1]
PIPO_S1Data.drop(['clk', 'rst'], axis=1, inplace=True)
PIPO_S1Data.reset_index(drop=True, inplace=True)
PIPO_S1Data
```

      DataIn
      DataOut1
      DataOut2

      0
      7
      2
      2

      1
      8
      7
      7

      2
      11
      8
      8

      3
      0
      11
      11

      4
      14
      0
      0

      5
      1
      14
      14

      6
      5
      1
      1

      7
      12
      5
      5

      8
      1
      12
      12

      9
      13
      1
      1

      10
      8
      13
      13

      11
      2
      8
      8

      12
      11
      2
      2

### Verilog Code

```python
DUT.convert()
VerilogTextReader('PIPO_S1');
```

    ***Verilog modual from PIPO_S1.v***

     // File: PIPO_S1.v
    // Generated by MyHDL 0.10
    // Date: Wed Sep  5 07:50:34 2018

    `timescale 1ns/10ps

    module PIPO_S1 (
        DataIn,
        DataOut1,
        DataOut2,
        clk,
        rst
    );
    // one-in two-out PIPO typicaly found in the lititure
    // lacking buffering
    //
    // Inputs:
    //     DataIn(bitVec): one-in Parallel data int
    //     clk(bool): clock
    //     rst(bool): reset
    //
    // Ouputs:
    //     DataOut1(bitVec): Parallel out 1
    //     DataOut2(bitVec): Parallel out 1
    //

    input [3:0] DataIn;
    output [3:0] DataOut1;
    reg [3:0] DataOut1;
    output [3:0] DataOut2;
    reg [3:0] DataOut2;
    input clk;
    input rst;

    always @(posedge clk, negedge rst) begin: PIPO_S1_LOGIC
        if (rst) begin
            DataOut1 <= 0;
            DataOut2 <= 0;
        end
        else begin
            DataOut1 <= DataIn;
            DataOut2 <= DataIn;
        end
    end

    endmodule

\begin{figure}
\centerline{\includegraphics[width=10cm]{PIPO_S1_RTL.png}}
\caption{\label{fig:S1PIPORTL} PIPO_S1 Shift Register RTL schematic; Xilinx Vivado 2017.4}
\end{figure}

\begin{figure}
\centerline{\includegraphics[width=10cm]{PIPO_S1_SYN.png}}
\caption{\label{fig:S1PIPOSYN} PIPO_S1 Shift Register Synthesized Schematic; Xilinx Vivado 2017.4}
\end{figure}

## Synchronous 2

### myHDL Module

```python
@block
def PIPO_S2(DataIn, DataOut1, DataOut2, clk, rst):
    """
    one-in two-out PIPO with buffering

    Inputs:
        DataIn(bitVec): one-in Parallel data int
        clk(bool): clock
        rst(bool): reset

    Ouputs:
        DataOut1(bitVec): Parallel out 1
        DataOut2(bitVec): Parallel out 1

    """

    Buffer=Signal(modbv(0)[len(DataIn):])
    @always(clk.posedge, rst.negedge)
    def logic():
        if rst:
            Buffer.next=0
        else:
            Buffer.next=DataIn

    #not normaly found in PIPO; but is better practice since buffers help
    #with isolation for ASIC desighn
    @always_comb
    def OuputBuffer():
        DataOut1.next=Buffer
        DataOut2.next=Buffer

    return instances()

```

### myHDL Testing

```python
Peeker.clear()
clk=Signal(bool(0)); Peeker(clk, 'clk')
rst=Signal(bool(0)); Peeker(rst, 'rst')
DataIn=Signal(intbv(0)[4:]); Peeker(DataIn, 'DataIn')
DataOut1=Signal(intbv(0)[4:]); Peeker(DataOut1, 'DataOut1')
DataOut2=Signal(intbv(0)[4:]); Peeker(DataOut2, 'DataOut2')

DUT=PIPO_S2(DataIn, DataOut1, DataOut2, clk, rst)

def PIPO_TB():
    """
    myHDL only Testbench for `PIPO_*` module
    """
    @always(delay(1))
    def ClkGen():
        clk.next=not clk

    @instance
    def stimules():
        i=0
        while True:

            DataIn.next=int(TestData[i])

            if i==14:
                raise StopSimulation()

            i+=1
            yield clk.posedge

    return instances()

sim=Simulation(DUT, PIPO_TB(), *Peeker.instances()).run()
```

```python
Peeker.to_wavedrom()
```

```python
PIPO_S2Data=Peeker.to_dataframe();
PIPO_S2Data=PIPO_S2Data[PIPO_S2Data['clk']==1]
PIPO_S2Data.drop(['clk', 'rst'], axis=1, inplace=True)
PIPO_S2Data.reset_index(drop=True, inplace=True)
PIPO_S2Data
```

      DataIn
      DataOut1
      DataOut2

      0
      7
      2
      2

      1
      8
      7
      7

      2
      11
      8
      8

      3
      0
      11
      11

      4
      14
      0
      0

      5
      1
      14
      14

      6
      5
      1
      1

      7
      12
      5
      5

      8
      1
      12
      12

      9
      13
      1
      1

      10
      8
      13
      13

      11
      2
      8
      8

      12
      11
      2
      2

### Verilog Code

```python
DUT.convert()
VerilogTextReader('PIPO_S2');
```

    ***Verilog modual from PIPO_S2.v***

     // File: PIPO_S2.v
    // Generated by MyHDL 0.10
    // Date: Wed Sep  5 07:50:41 2018

    `timescale 1ns/10ps

    module PIPO_S2 (
        DataIn,
        DataOut1,
        DataOut2,
        clk,
        rst
    );
    // one-in two-out PIPO with buffering
    //
    // Inputs:
    //     DataIn(bitVec): one-in Parallel data int
    //     clk(bool): clock
    //     rst(bool): reset
    //
    // Ouputs:
    //     DataOut1(bitVec): Parallel out 1
    //     DataOut2(bitVec): Parallel out 1
    //

    input [3:0] DataIn;
    output [3:0] DataOut1;
    wire [3:0] DataOut1;
    output [3:0] DataOut2;
    wire [3:0] DataOut2;
    input clk;
    input rst;

    reg [3:0] Buffer;

    always @(posedge clk, negedge rst) begin: PIPO_S2_LOGIC
        if (rst) begin
            Buffer <= 0;
        end
        else begin
            Buffer <= DataIn;
        end
    end

    assign DataOut1 = Buffer;
    assign DataOut2 = Buffer;

    endmodule

\begin{figure}
\centerline{\includegraphics[width=10cm]{PIPO_S2_RTL.png}}
\caption{\label{fig:S2PIPORTL} PIPO_S2 Shift Register RTL schematic; Xilinx Vivado 2017.4}
\end{figure}

\begin{figure}
\centerline{\includegraphics[width=10cm]{PIPO_S2_SYN.png}}
\caption{\label{fig:S2PIPOSYN} PIPO_S2 Shift Register Synthesized Schematic; Xilinx Vivado 2017.4}
\end{figure}

## Comparison of the three designs

In the asynchronous case, it can be seen in the RTL that incoming Bus is passed through a buffer and then the Bus is then junctioned to two outputs. This , therefore, does not have any synchronicity to a clock and is the HDL equivalent of taping the wires of the incoming bus to create a copy of the signal. What this design lacks in clock support it gains in resource saving and instantaneous interchange of the input signal to output signals

For the two synchronous cases the incoming signal is buffered by a register set, therefore any signal on the bus will not be present on the output buses for at least one clock cycle. Wich for clocked designs is a good thing but for signals that needs an instantaneous transmission, this is a failing in tradeoff. And while Vivado (and most other FPGA synthesis tools) recognized that the two designs are the same we should not take this for granted. Since other tools may not. Since at the RTL level the implementations are clearly different.

In the first case, the incoming signals is recorded by two registers that then feeds each of the respective output busses. While this means that we gain redundancy in parallel registers. The parallel memories could also become out of sync for any number of reasons. Further, this is a huge amount of resource if it were to be synthesized this way. In comparison, the second design uses a single register that then feeds each of the outputs where this design has better resource allocation and would not suffer from any asynchronicity between parallel registers. It now suffers in lacking redundancy since any issues in the one register effect both outputs.

The lesson here is that HDL should never be thought of as of programming. Instead, it is a *sophisticated abstraction description* of **Hardware!** And therefore HDL should always be written to satisfy the hardware constraints.

# Parallel-In Serial-Out (PISO)
Used to translate bus(parallel) data to a single output wire (serial) data a common example is the transmit line of a UART

## myHDL Module

```python
@block
def PISO(ReadBus, BusIn, SerialOut, clk, rst):
    """
    Parallel In Serial Out right shift regestor

    Input:
        ReadBus(bool): read bus flag
        BusIn(bool): Serial wire input
        clk(bool): clock
        rst(bool): reset

    Output:
        SerialOut(bool): Serial(wire) output data from `BusIn`
    Note:
        Does not have a finsh serial write indicator
    """

    Buffer=Signal(intbv(0)[len(BusIn):])
    @always(clk.posedge, rst.negedge)
    def logic():
        if rst:
            Buffer.next=0
        elif ReadBus:
            Buffer.next=BusIn
        else:
            Buffer.next=Buffer>>1

    #A more robust PISO would have a counter to trigger
    #a finish serial write flag here

    @always_comb
    def SerialWriteOut():
        SerialOut.next=Buffer[0]

    return instances()

```

## myHDL Testing

```python
TestData=np.random.randint(0, 2**4, 3)
print(TestData)
#reverse bit order since right shift
TestDataBin="".join([bin(i, 4)[::-1] for i in TestData])
TestDataBin=[int(i) for i in TestDataBin]
TestDataBin
```

```python
Peeker.clear()
ReadBus=Signal(bool(0)); Peeker(ReadBus, 'ReadBus')
BusIn=Signal(intbv(0)[4:]); Peeker(BusIn, 'BusIn')
SerialOut=Signal(bool(0)); Peeker(SerialOut, 'SerialOut')
clk=Signal(bool(0)); Peeker(clk, 'clk')
rst=Signal(bool(0)); Peeker(rst, 'rst')

DUT=PISO(ReadBus, BusIn, SerialOut, clk, rst)

def PISO_TB():
    """
    myHDL only Testbench for `SIPO` module
    """
    @always(delay(1))
    def ClkGen():
        clk.next=not clk

    @instance
    def stimules():
        yield clk.posedge

        for i in TestData:
            BusIn.next=int(i)
            ReadBus.next=True
            yield clk.posedge

            ReadBus.next=False
            for j in range(len(bin(i, 4))):
                yield clk.posedge

        raise StopSimulation()

    return instances()

sim=Simulation(DUT, PISO_TB(), *Peeker.instances()).run()
print(TestData)
print(TestDataBin)
```

    [11 15 14]
    [1, 1, 0, 1, 1, 1, 1, 1, 0, 1, 1, 1]

```python
Peeker.to_wavedrom()
```

```python
PISOData=Peeker.to_dataframe();
PISOData=PISOData[PISOData['clk']==1]
PISOData.drop(['clk', 'rst'], axis=1, inplace=True)
PISOData['BusBits']=PISOData['BusIn'].apply(lambda x:bin(x, 4))
PISOData.reset_index(drop=True, inplace=True)
PISOData
```

      BusIn
      ReadBus
      SerialOut
      BusBits

      0
      11
      1
      0
      1011

      1
      11
      0
      1
      1011

      2
      11
      0
      1
      1011

      3
      11
      0
      0
      1011

      4
      11
      0
      1
      1011

      5
      15
      1
      0
      1111

      6
      15
      0
      1
      1111

      7
      15
      0
      1
      1111

      8
      15
      0
      1
      1111

      9
      15
      0
      1
      1111

      10
      14
      1
      0
      1110

      11
      14
      0
      0
      1110

      12
      14
      0
      1
      1110

      13
      14
      0
      1
      1110

      14
      14
      0
      1
      1110

## Verilog Code

```python
DUT.convert()
VerilogTextReader('PISO');
```

    ***Verilog modual from PISO.v***

     // File: PISO.v
    // Generated by MyHDL 0.10
    // Date: Wed Sep  5 07:50:56 2018

    `timescale 1ns/10ps

    module PISO (
        ReadBus,
        BusIn,
        SerialOut,
        clk,
        rst
    );
    // Parallel In Serial Out right shift regestor
    //
    // Input:
    //     ReadBus(bool): read bus flag
    //     BusIn(bool): Serial wire input
    //     clk(bool): clock
    //     rst(bool): reset
    //
    // Output:
    //     SerialOut(bool): Serial(wire) output data from `BusIn`
    // Note:
    //     Does not have a finsh serial write indicator

    input ReadBus;
    input [3:0] BusIn;
    output SerialOut;
    wire SerialOut;
    input clk;
    input rst;

    reg [3:0] Buffer;

    always @(posedge clk, negedge rst) begin: PISO_LOGIC
        if (rst) begin
            Buffer <= 0;
        end
        else if (ReadBus) begin
            Buffer <= BusIn;
        end
        else begin
            Buffer <= (Buffer >>> 1);
        end
    end

    assign SerialOut = Buffer[0];

    endmodule

\begin{figure}
\centerline{\includegraphics[width=10cm]{PISO_RTL.png}}
\caption{\label{fig:PISORTL} PISO Shift Register RTL schematic; Xilinx Vivado 2017.4}
\end{figure}

\begin{figure}
\centerline{\includegraphics[width=10cm]{PISO_SYN.png}}
\caption{\label{fig:PISOSYN} PISO Shift Register Synthesized Schematic; Xilinx Vivado 2017.4}
\end{figure}

## Verilog Testbench (!ToDo)

# Serial-In Serial-Out (SISO)
SISO are used to buffer input data like a primitive serial version of the First In First Out (FIFO) Memory. Or can be used for sampling of a wire input that not clock synced to an output that is clock sync

## myHDL Module

```python
@block
def SISO(SerialIn, SerialOut, clk, rst, BufferSize):
    """
    SISO Left Shift registor

    Input:
        SerialIn(bool): serial input feed
        clk(bool): clock signal
        rst(bool):reset signal

    Output:
        SerialOut(bool): serial out delayed by BufferSize

    Paramter:
        BufferSize(int): size of SISO buffer, aka delay amount
    """
    Buffer=Signal(modbv(0)[BufferSize:])
    @always(clk.posedge, rst.negedge)
    def logic():
        if rst:
            Buffer.next=0
        else:
            Buffer.next=concat(Buffer[BufferSize-1:0], SerialIn)

    @always_comb
    def ReadLeftMostToSer():
        SerialOut.next=Buffer[BufferSize-1]

    return instances()

```

## myHDL Testing

```python
SerialInTVLen=20
np.random.seed(71)
SerialInTV=np.random.randint(0,2,20).astype(int)
SerialInTV
```

    array([1, 1, 1, 1, 0, 0, 0, 1, 1, 0, 0, 0, 1, 0, 0, 1, 1, 0, 1, 0])

```python
Peeker.clear()
SerialIn=Signal(bool(0)); Peeker(SerialIn, 'SerialIn')
SerialOut=Signal(bool(0)); Peeker(SerialOut, 'SerialOut')
clk=Signal(bool(0)); Peeker(clk, 'clk')
rst=Signal(bool(0)); Peeker(rst, 'rst')
BufferSize=4

DUT=SISO(SerialIn, SerialOut, clk, rst, BufferSize)

def SISO_TB():
    """
    myHDL only Testbench for `SISO` module
    """
    @always(delay(1))
    def ClkGen():
        clk.next=not clk

    @instance
    def stimules():
        for i in range(SerialInTVLen):
            SerialIn.next=int(SerialInTV[i])
            yield clk.posedge

        for i in range(2):
            if i==0:
                SerialIn.next=0
                rst.next=1
            else:
                rst.next=0
            yield clk.posedge

        for i in range(BufferSize+1):
            SerialIn.next=1
            yield clk.posedge

        raise StopSimulation()

    return instances()

sim=Simulation(DUT, SISO_TB(), *Peeker.instances()).run()
```

```python
Peeker.to_wavedrom()
```

```python
SISOData=Peeker.to_dataframe()
SISOData
```

      SerialIn
      SerialOut
      clk
      rst

      0
      1
      0
      0
      0

      1
      1
      0
      1
      0

      2
      1
      0
      0
      0

      3
      1
      0
      1
      0

      4
      1
      0
      0
      0

      5
      1
      0
      1
      0

      6
      1
      0
      0
      0

      7
      0
      1
      1
      0

      8
      0
      1
      0
      0

      9
      0
      1
      1
      0

      10
      0
      1
      0
      0

      11
      0
      1
      1
      0

      12
      0
      1
      0
      0

      13
      1
      1
      1
      0

      14
      1
      1
      0
      0

      15
      1
      0
      1
      0

      16
      1
      0
      0
      0

      17
      0
      0
      1
      0

      18
      0
      0
      0
      0

      19
      0
      0
      1
      0

      20
      0
      0
      0
      0

      21
      0
      1
      1
      0

      22
      0
      1
      0
      0

      23
      1
      1
      1
      0

      24
      1
      1
      0
      0

      25
      0
      0
      1
      0

      26
      0
      0
      0
      0

      27
      0
      0
      1
      0

      28
      0
      0
      0
      0

      29
      1
      0
      1
      0

      30
      1
      0
      0
      0

      31
      1
      1
      1
      0

      32
      1
      1
      0
      0

      33
      0
      0
      1
      0

      34
      0
      0
      0
      0

      35
      1
      0
      1
      0

      36
      1
      0
      0
      0

      37
      0
      1
      1
      0

      38
      0
      1
      0
      0

      39
      0
      1
      1
      1

      40
      0
      1
      0
      1

      41
      0
      0
      1
      0

      42
      0
      0
      0
      0

      43
      1
      0
      1
      0

      44
      1
      0
      0
      0

      45
      1
      0
      1
      0

      46
      1
      0
      0
      0

      47
      1
      0
      1
      0

      48
      1
      0
      0
      0

      49
      1
      0
      1
      0

      50
      1
      0
      0
      0

      51
      1
      1
      1
      0

      52
      1
      1
      0
      0

```python
SISOData=SISOData[SISOData['clk']==1]
SISOData.drop('clk', inplace=True, axis=1)
SISOData.reset_index(drop=True, inplace=True)
SISOData
```

    /home/iridium/anaconda3/lib/python3.6/site-packages/pandas/core/frame.py:3697: SettingWithCopyWarning:
    A value is trying to be set on a copy of a slice from a DataFrame

    See the caveats in the documentation: http://pandas.pydata.org/pandas-docs/stable/indexing.html#indexing-view-versus-copy
      errors=errors)

      SerialIn
      SerialOut
      rst

      0
      1
      0
      0

      1
      1
      0
      0

      2
      1
      0
      0

      3
      0
      1
      0

      4
      0
      1
      0

      5
      0
      1
      0

      6
      1
      1
      0

      7
      1
      0
      0

      8
      0
      0
      0

      9
      0
      0
      0

      10
      0
      1
      0

      11
      1
      1
      0

      12
      0
      0
      0

      13
      0
      0
      0

      14
      1
      0
      0

      15
      1
      1
      0

      16
      0
      0
      0

      17
      1
      0
      0

      18
      0
      1
      0

      19
      0
      1
      1

      20
      0
      0
      0

      21
      1
      0
      0

      22
      1
      0
      0

      23
      1
      0
      0

      24
      1
      0
      0

      25
      1
      1
      0

```python
SISOData['SerialOutS4']=SISOData['SerialOut'].shift(-4)
SISOData
```

    /home/iridium/anaconda3/lib/python3.6/site-packages/ipykernel_launcher.py:1: SettingWithCopyWarning:
    A value is trying to be set on a copy of a slice from a DataFrame.
    Try using .loc[row_indexer,col_indexer] = value instead

    See the caveats in the documentation: http://pandas.pydata.org/pandas-docs/stable/indexing.html#indexing-view-versus-copy
      """Entry point for launching an IPython kernel.

      SerialIn
      SerialOut
      rst
      SerialOutS4

      0
      1
      0
      0
      1.0

      1
      1
      0
      0
      1.0

      2
      1
      0
      0
      1.0

      3
      0
      1
      0
      0.0

      4
      0
      1
      0
      0.0

      5
      0
      1
      0
      0.0

      6
      1
      1
      0
      1.0

      7
      1
      0
      0
      1.0

      8
      0
      0
      0
      0.0

      9
      0
      0
      0
      0.0

      10
      0
      1
      0
      0.0

      11
      1
      1
      0
      1.0

      12
      0
      0
      0
      0.0

      13
      0
      0
      0
      0.0

      14
      1
      0
      0
      1.0

      15
      1
      1
      0
      1.0

      16
      0
      0
      0
      0.0

      17
      1
      0
      0
      0.0

      18
      0
      1
      0
      0.0

      19
      0
      1
      1
      0.0

      20
      0
      0
      0
      0.0

      21
      1
      0
      0
      1.0

      22
      1
      0
      0
      NaN

      23
      1
      0
      0
      NaN

      24
      1
      0
      0
      NaN

      25
      1
      1
      0
      NaN

```python
SISOCheck=(SISOData[:16]['SerialIn'] == SISOData[:16]['SerialOutS4'].astype(int)).all()
print(f'SISO Check:{SISOCheck}')
```

    SISO Check:True

## Verilog Code

```python
DUT.convert()
VerilogTextReader('SISO');
```

    ***Verilog modual from SISO.v***

     // File: SISO.v
    // Generated by MyHDL 0.10
    // Date: Wed Sep  5 07:51:08 2018

    `timescale 1ns/10ps

    module SISO (
        SerialIn,
        SerialOut,
        clk,
        rst
    );
    // SISO Left Shift registor
    //
    // Input:
    //     SerialIn(bool): serial input feed
    //     clk(bool): clock signal
    //     rst(bool):reset signal
    //
    // Output:
    //     SerialOut(bool): serial out delayed by BufferSize
    //
    // Paramter:
    //     BufferSize(int): size of SISO buffer, aka delay amount

    input SerialIn;
    output SerialOut;
    wire SerialOut;
    input clk;
    input rst;

    reg [3:0] Buffer;

    always @(posedge clk, negedge rst) begin: SISO_LOGIC
        if (rst) begin
            Buffer <= 0;
        end
        else begin
            Buffer <= {Buffer[(4 - 1)-1:0], SerialIn};
        end
    end

    assign SerialOut = Buffer[(4 - 1)];

    endmodule

\begin{figure}
\centerline{\includegraphics[width=10cm]{SISO_RTL.png}}
\caption{\label{fig:SISORTL} SISO Shift Register RTL schematic; Xilinx Vivado 2017.4}
\end{figure}

\begin{figure}
\centerline{\includegraphics[width=10cm]{SISO_SYN.png}}
\caption{\label{fig:SISOSYN} SISO Shift Register Synthesized Schematic; Xilinx Vivado 2017.4}
\end{figure}

## Verilog Testbench

```python
#create BitVector for BufferGate_TBV
SerialInTVs=intbv(int(''.join(SerialInTV.astype(str)), 2))[SerialInTVLen:]
SerialInTVs, bin(SerialInTVs)
```

    (intbv(989338), '11110001100010011010')

```python
BufferSize=4

@block
def SISO_TBV():
    """
    myHDL -> Verilog Testbench for `SISO` module
    """

    SerialIn=Signal(bool(0))
    SerialOut=Signal(bool(0))
    clk=Signal(bool(0))
    rst=Signal(bool(0))

    @always_comb
    def print_data():
        print(SerialIn, SerialOut, clk, rst)

    SerialInTV=Signal(SerialInTVs)

    DUT=SISO(SerialIn, SerialOut, clk, rst, BufferSize)

    @instance
    def clk_signal():
        while True:
            clk.next = not clk
            yield delay(1)

    @instance
    def stimules():
        for i in range(SerialInTVLen):
            SerialIn.next=int(SerialInTV[i])
            yield clk.posedge

        for i in range(2):
            if i==0:
                SerialIn.next=0
                rst.next=1
            else:
                rst.next=0
            yield clk.posedge

        for i in range(BufferSize+1):
            SerialIn.next=1
            yield clk.posedge

        raise StopSimulation()

    return instances()

TB=SISO_TBV()
TB.convert(hdl="Verilog", initial_values=True)
VerilogTextReader('SISO_TBV');
```

    <class 'myhdl._Signal._Signal'> <class '_ast.Name'>
    <class 'myhdl._Signal._Signal'> <class '_ast.Name'>
    <class 'myhdl._Signal._Signal'> <class '_ast.Name'>
    <class 'myhdl._Signal._Signal'> <class '_ast.Name'>
    ***Verilog modual from SISO_TBV.v***

     // File: SISO_TBV.v
    // Generated by MyHDL 0.10
    // Date: Wed Sep  5 07:52:33 2018

    `timescale 1ns/10ps

    module SISO_TBV (

    );
    // myHDL -> Verilog Testbench for `SISO` module

    reg clk = 0;
    reg rst = 0;
    wire SerialOut;
    wire [19:0] SerialInTV;
    reg SerialIn = 0;
    reg [3:0] SISO0_0_Buffer = 0;

    assign SerialInTV = 20'd989338;

    always @(rst, SerialOut, SerialIn, clk) begin: SISO_TBV_PRINT_DATA
        $write("%h", SerialIn);
        $write(" ");
        $write("%h", SerialOut);
        $write(" ");
        $write("%h", clk);
        $write(" ");
        $write("%h", rst);
        $write("\n");
    end

    always @(posedge clk, negedge rst) begin: SISO_TBV_SISO0_0_LOGIC
        if (rst) begin
            SISO0_0_Buffer <= 0;
        end
        else begin
            SISO0_0_Buffer <= {SISO0_0_Buffer[(4 - 1)-1:0], SerialIn};
        end
    end

    assign SerialOut = SISO0_0_Buffer[(4 - 1)];

    initial begin: SISO_TBV_CLK_SIGNAL
        while (1'b1) begin
            clk <= (!clk);
            # 1;
        end
    end

    initial begin: SISO_TBV_STIMULES
        integer i;
        for (i=0; i<20; i=i+1) begin
            SerialIn <= SerialInTV[i];
            @(posedge clk);
        end
        for (i=0; i<2; i=i+1) begin
            if ((i == 0)) begin
                SerialIn <= 0;
                rst <= 1;
            end
            else begin
                rst <= 0;
            end
            @(posedge clk);
        end
        for (i=0; i<(4 + 1); i=i+1) begin
            SerialIn <= 1;
            @(posedge clk);
        end
        $finish;
    end

    endmodule

    /home/iridium/anaconda3/lib/python3.6/site-packages/myhdl/conversion/_toVerilog.py:349: ToVerilogWarning: Signal is not driven: SerialInTV
      category=ToVerilogWarning

# Serial-In Parallel-Out (SIPO)
used to translate single wire (serial) data to but (parallel) data, a common example is the read line of a UART

## myHDL Module

```python
@block
def SIPO(SerialIn, BusOut, clk, rst):
    """
    Serial In Parallel Out right shift regestor

    Input:
        SerialIn(bool): Serial wire input
        clk(bool): clock
        rst(bool): reset

    Output:
        BusOut(bitVec): Parallel(Bus) output data from `SerialWire`
    """

    Buffer=Signal(modbv(0)[len(BusOut):])
    @always(clk.posedge, rst.negedge)
    def logic():
        if rst:
            Buffer.next=0
        else:
            Buffer.next=concat(Buffer[len(Buffer):0],SerialIn)

    @always_comb
    def OuputBuffer():
        BusOut.next=Buffer

    return instances()
```

## myHDL Testing

```python
TestData=np.random.randint(0, 2**4, 3)
print(TestData)
TestDataBin="".join([bin(i, 4) for i in TestData])
TestDataBin=[int(i) for i in TestDataBin]
TestDataBin
```

```python
Peeker.clear()
SerialIn=Signal(bool(0)); Peeker(SerialIn, 'SerialIn')
BusOut=Signal(intbv(0)[4:]); Peeker(BusOut, 'BusOut')
clk=Signal(bool(0)); Peeker(clk, 'clk')
rst=Signal(bool(0)); Peeker(rst, 'rst')

DUT=SIPO(SerialIn, BusOut, clk, rst)

def SIPO_TB():
    """
    myHDL only Testbench for `SIPO` module
    """
    @always(delay(1))
    def ClkGen():
        clk.next=not clk

    @instance
    def stimules():
        i=0
        while True:
            if i<len(TestDataBin):
                SerialIn.next=TestDataBin[i]
            elif i==len(TestDataBin):
                pass
            elif i>len(TestDataBin):
                raise StopSimulation()
            i+=1
            yield clk.posedge

        raise StopSimulation()

    return instances()

sim=Simulation(DUT, SIPO_TB(), *Peeker.instances()).run()
```

```python
Peeker.to_wavedrom()
```

```python
SIPOData=Peeker.to_dataframe();
SIPOData=SIPOData[SIPOData['clk']==1]
SIPOData.drop(['clk', 'rst'], axis=1, inplace=True)
SIPOData['BusBits']=SIPOData['BusOut'].apply(lambda x:bin(x, 4))
SIPOData.reset_index(drop=True, inplace=True)
SIPOData
```

      BusOut
      SerialIn
      BusBits

      0
      1
      0
      0001

      1
      2
      1
      0010

      2
      5
      1
      0101

      3
      11
      1
      1011

      4
      7
      1
      0111

      5
      15
      0
      1111

      6
      14
      1
      1110

      7
      13
      0
      1101

      8
      10
      0
      1010

      9
      4
      0
      0100

      10
      8
      0
      1000

      11
      0
      0
      0000

```python
TestData, TestDataBin
```

    (array([11, 13,  0]), [1, 0, 1, 1, 1, 1, 0, 1, 0, 0, 0, 0])

## Verilog Code

```python
DUT.convert()
VerilogTextReader('SIPO');
```

    ***Verilog modual from SIPO.v***

     // File: SIPO.v
    // Generated by MyHDL 0.10
    // Date: Wed Sep  5 07:52:43 2018

    `timescale 1ns/10ps

    module SIPO (
        SerialIn,
        BusOut,
        clk,
        rst
    );
    // Serial In Parallel Out right shift regestor
    //
    // Input:
    //     SerialIn(bool): Serial wire input
    //     clk(bool): clock
    //     rst(bool): reset
    //
    // Output:
    //     BusOut(bitVec): Parallel(Bus) output data from `SerialWire`

    input SerialIn;
    output [3:0] BusOut;
    wire [3:0] BusOut;
    input clk;
    input rst;

    reg [3:0] Buffer = 0;

    always @(posedge clk, negedge rst) begin: SIPO_LOGIC
        if (rst) begin
            Buffer <= 0;
        end
        else begin
            Buffer <= {Buffer[4-1:0], SerialIn};
        end
    end

    assign BusOut = Buffer;

    endmodule

    /home/iridium/anaconda3/lib/python3.6/site-packages/myhdl/conversion/_toVerilog.py:309: ToVerilogWarning: Port is not used: SerialIn
      category=ToVerilogWarning

\begin{figure}
\centerline{\includegraphics[width=10cm]{SIPO_RTL.png}}
\caption{\label{fig:SIPORTL} SIPO Shift Register RTL schematic; Xilinx Vivado 2017.4}
\end{figure}

\begin{figure}
\centerline{\includegraphics[width=10cm]{SIPO_SYN.png}}
\caption{\label{fig:SIPOSYN} SIPO Shift Register Synthesized Schematic; Xilinx Vivado 2017.4}
\end{figure}

## Verilog Testbench

```python
V=int(''.join([str(i) for i in TestDataBin]), 2)
SerialVal=intbv(V)[len(TestDataBin):]
SerialVal
```

    intbv(3024)

```python
@block
def SIPO_TBV():
    """
    myHDL -> Verilog Testbench for `SIPO` module
    """
    SerialVals=Signal(SerialVal)
    SerialIn=Signal(bool(0))
    BusOut=Signal(intbv(0)[4:])
    clk=Signal(bool(0))
    rst=Signal(bool(0))

    @always_comb
    def print_data():
        print(SerialIn, BusOut, clk, rst)

    DUT=SIPO(SerialIn, BusOut, clk, rst)

    @instance
    def clk_signal():
        while True:
            clk.next = not clk
            yield delay(1)

    @instance
    def stimules():
        i=0
        while True:
            if i<len(TestDataBin):
                SerialIn.next=SerialVals[i]
            elif i==len(TestDataBin):
                pass
            elif i>len(TestDataBin):
                raise StopSimulation()
            i+=1
            yield clk.posedge

        raise StopSimulation()

    return instances()

TB=SIPO_TBV()
TB.convert(hdl="Verilog", initial_values=True)
VerilogTextReader('SIPO_TBV');
```

    <class 'myhdl._Signal._Signal'> <class '_ast.Name'>
    <class 'myhdl._Signal._Signal'> <class '_ast.Name'>
    <class 'myhdl._Signal._Signal'> <class '_ast.Name'>
    <class 'myhdl._Signal._Signal'> <class '_ast.Name'>
    ***Verilog modual from SIPO_TBV.v***

     // File: SIPO_TBV.v
    // Generated by MyHDL 0.10
    // Date: Wed Sep  5 07:52:49 2018

    `timescale 1ns/10ps

    module SIPO_TBV (

    );
    // myHDL -> Verilog Testbench for `SIPO` module

    reg clk = 0;
    wire rst;
    reg SerialIn = 0;
    wire [3:0] BusOut;
    wire [11:0] SerialVals;
    reg [3:0] SIPO0_0_Buffer = 0;

    assign rst = 1'd0;
    assign SerialVals = 12'd3024;

    always @(rst, BusOut, SerialIn, clk) begin: SIPO_TBV_PRINT_DATA
        $write("%h", SerialIn);
        $write(" ");
        $write("%h", BusOut);
        $write(" ");
        $write("%h", clk);
        $write(" ");
        $write("%h", rst);
        $write("\n");
    end

    always @(posedge clk, negedge rst) begin: SIPO_TBV_SIPO0_0_LOGIC
        if (rst) begin
            SIPO0_0_Buffer <= 0;
        end
        else begin
            SIPO0_0_Buffer <= {SIPO0_0_Buffer[4-1:0], SerialIn};
        end
    end

    assign BusOut = SIPO0_0_Buffer;

    initial begin: SIPO_TBV_CLK_SIGNAL
        while (1'b1) begin
            clk <= (!clk);
            # 1;
        end
    end

    initial begin: SIPO_TBV_STIMULES
        integer i;
        i = 0;
        while (1'b1) begin
            if ((i < 12)) begin
                SerialIn <= SerialVals[i];
            end
            else if ((i == 12)) begin
                // pass
            end
            else if ((i > 12)) begin
                $finish;
            end
            i = i + 1;
            @(posedge clk);
        end
        $finish;
    end

    endmodule

    /home/iridium/anaconda3/lib/python3.6/site-packages/myhdl/conversion/_toVerilog.py:349: ToVerilogWarning: Signal is not driven: rst
      category=ToVerilogWarning
    /home/iridium/anaconda3/lib/python3.6/site-packages/myhdl/conversion/_toVerilog.py:349: ToVerilogWarning: Signal is not driven: SerialVals
      category=ToVerilogWarning

# Cyclic Shift Register Johnson Counter
The Johnson Counter is implemented in this notebook about shift registers since in reality, a Johnson Counter is a cyclic shift register with single bit inversion. Hence the Johnson Counter, which goes by the other name of a Mobius Ring Counter. The following are aspects of Johnson Counter by Sougata Bhattacharjee [https://www.quora.com/What-is-the-difference-between-a-Johnson-counter-and-a-ring-counter]

\begin{itemize}
\item In a Johnson Counter the output bar or Q(bar) of the last flip-flop is connected to the input of the first flip-flop

\item If $n$ is the number of the flip-flop used, then the total number of states used is $2n$.

\item The Johnson Counter is also known as walking counter, switching tail counter and is mostly used in phase shift or function generator.

\item The decoding circuit is complex as compared to a ring counter.

\item If input frequency is $f$ in Johnson Counter,then the output is $\dfrac{f}{2n}$.

\item The total number of unused states in Johnson Counter is $(2^n - 2n)$

\item The main problem with Johnson counter is that once it enters into an unused state it is in a lockout state

\end{itemize}

For a four-bit Johnson Counter, the next state diagram is given by the following table from [wikipedga](https://en.wikipedia.org/wiki/Ring_counter)

\begin{figure}
\centerline{\includegraphics[width=1cm]{JohnsonCounterTable.png}}
\caption{\label{fig:JohnsonTable} 4-bit Ring Counter next state table from [wikipedia](https://en.wikipedia.org/wiki/Ring_counter#Four-bit_ring-counter_sequences)}
\end{figure}

whereupon examining the next state table for the Johnson counter we can see why a Johnson counter is also called a Mobius counter

## myHDL Module

```python
#Create the Direction States for Johnson Counter
DirStates=enum('Left','Halt','Right')
print(f"`Left` state repersentation is {bin(DirStates.Left)}")
print(f"`Halt` state repersentation is {bin(DirStates.Halt)}")
print(f"`Right` state repersentation is {bin(DirStates.Right)}")
```

    `Left` state repersentation is 0
    `Halt` state repersentation is 1
    `Right` state repersentation is 10

```python
@block
def JohnsonCount3(Dir, q, clk, rst):
    """
    Based of the `jc2` exsample from the myHDL website
    http://www.myhdl.org/docs/examples/jc2.html

    Input:
        Dir(state): Left,Right, Halt Direction States
        clk(bool): input clock
        rst(bool): reset signal

    Ouput:
        q(bitVec): the values in the D flip flops(aka counter)
    """

    q_i=Signal(intbv(0)[len(q):])
    @always(clk.posedge, rst.negedge)
    def JCStateMachine():
        #moore state machine
        if rst:
            q_i.next=0

        elif Dir==DirStates.Left:
            #set bit slice from left most to one from the right
            #from bit slice from one to the left to the right most
            q_i.next[len(q_i):1]=q_i[len(q_i)-1:]
            #set next right most bit to negated one to the left bit
            q_i.next[0]=not q_i[len(q_i)-1]

        elif Dir==DirStates.Halt:
            #create circular stop
            q_i.next=q_i

        elif Dir==DirStates.Right:
            #set bit slice from one from the left to right most
            #from bit slice left most bit to one from the right
            q_i.next[len(q_i)-1:]=q_i[len(q_i):1]
            #set next one bit from the right to be negated left most bit
            q_i.next[len(q_i)-1]=not q_i[0]

    @always_comb
    def OuputBuffer():
        q.next=q_i

    return instances()

```

## myHDL Testing

```python
BitSize=4
Peeker.clear()
clk=Signal(bool(0)); Peeker(clk, 'clk')
rst=Signal(bool(0)); Peeker(rst, 'rst')
q=Signal(intbv(0)[BitSize:]); Peeker(q, 'q')
Dir=Signal(DirStates.Right); Peeker(Dir, 'Dir')

DUT=JohnsonCount3(Dir, q, clk, rst)

def JohnsonCount3_TB():
    """
    myHDL only Testbench for `RingCounter` module
    """
    @always(delay(1))
    def ClkGen():
        clk.next=not clk

    @instance
    def stimules():
        i=0
        while True:
            if i==2*2*BitSize:
                Dir.next=DirStates.Left
            elif i==4*2*BitSize:
                rst.next=1
            elif i==4*2*BitSize+1:
                rst.next=0
            elif i==4*2*BitSize+2:
                Dir.next=DirStates.Halt

            if i==5*2*BitSize:
                raise StopSimulation()

            i+=1
            yield clk.posedge

    return instances()

sim=Simulation(DUT, JohnsonCount3_TB(), *Peeker.instances()).run()
```

```python
Peeker.to_wavedrom()
```

```python
JohnsonCount3Data=Peeker.to_dataframe()
JohnsonCount3Data=JohnsonCount3Data[JohnsonCount3Data['clk']==1]
JohnsonCount3Data.drop('clk', axis=1, inplace=True)
JohnsonCount3Data.reset_index(drop=True, inplace=True)
JohnsonCount3Data
```

      Dir
      q
      rst

      0
      Right
      8
      0

      1
      Right
      12
      0

      2
      Right
      14
      0

      3
      Right
      15
      0

      4
      Right
      7
      0

      5
      Right
      3
      0

      6
      Right
      1
      0

      7
      Right
      0
      0

      8
      Right
      8
      0

      9
      Right
      12
      0

      10
      Right
      14
      0

      11
      Right
      15
      0

      12
      Right
      7
      0

      13
      Right
      3
      0

      14
      Right
      1
      0

      15
      Left
      0
      0

      16
      Left
      1
      0

      17
      Left
      3
      0

      18
      Left
      7
      0

      19
      Left
      15
      0

      20
      Left
      14
      0

      21
      Left
      12
      0

      22
      Left
      8
      0

      23
      Left
      0
      0

      24
      Left
      1
      0

      25
      Left
      3
      0

      26
      Left
      7
      0

      27
      Left
      15
      0

      28
      Left
      14
      0

      29
      Left
      12
      0

      30
      Left
      8
      0

      31
      Left
      0
      1

      32
      Left
      1
      0

      33
      Halt
      3
      0

      34
      Halt
      3
      0

      35
      Halt
      3
      0

      36
      Halt
      3
      0

      37
      Halt
      3
      0

      38
      Halt
      3
      0

```python
JohnsonCount3Data['q']=JohnsonCount3Data['q'].apply(lambda x:bin(x, BitSize))
JohnsonCount3Data
```

      Dir
      q
      rst

      0
      Right
      1000
      0

      1
      Right
      1100
      0

      2
      Right
      1110
      0

      3
      Right
      1111
      0

      4
      Right
      0111
      0

      5
      Right
      0011
      0

      6
      Right
      0001
      0

      7
      Right
      0000
      0

      8
      Right
      1000
      0

      9
      Right
      1100
      0

      10
      Right
      1110
      0

      11
      Right
      1111
      0

      12
      Right
      0111
      0

      13
      Right
      0011
      0

      14
      Right
      0001
      0

      15
      Left
      0000
      0

      16
      Left
      0001
      0

      17
      Left
      0011
      0

      18
      Left
      0111
      0

      19
      Left
      1111
      0

      20
      Left
      1110
      0

      21
      Left
      1100
      0

      22
      Left
      1000
      0

      23
      Left
      0000
      0

      24
      Left
      0001
      0

      25
      Left
      0011
      0

      26
      Left
      0111
      0

      27
      Left
      1111
      0

      28
      Left
      1110
      0

      29
      Left
      1100
      0

      30
      Left
      1000
      0

      31
      Left
      0000
      1

      32
      Left
      0001
      0

      33
      Halt
      0011
      0

      34
      Halt
      0011
      0

      35
      Halt
      0011
      0

      36
      Halt
      0011
      0

      37
      Halt
      0011
      0

      38
      Halt
      0011
      0

```python
JohnsonCount3Data[JohnsonCount3Data['Dir']==DirStates.Right]
```

      Dir
      q
      rst

      0
      Right
      1000
      0

      1
      Right
      1100
      0

      2
      Right
      1110
      0

      3
      Right
      1111
      0

      4
      Right
      0111
      0

      5
      Right
      0011
      0

      6
      Right
      0001
      0

      7
      Right
      0000
      0

      8
      Right
      1000
      0

      9
      Right
      1100
      0

      10
      Right
      1110
      0

      11
      Right
      1111
      0

      12
      Right
      0111
      0

      13
      Right
      0011
      0

      14
      Right
      0001
      0

```python
JohnsonCount3Data[JohnsonCount3Data['Dir']==DirStates.Left]
```

      Dir
      q
      rst

      15
      Left
      0000
      0

      16
      Left
      0001
      0

      17
      Left
      0011
      0

      18
      Left
      0111
      0

      19
      Left
      1111
      0

      20
      Left
      1110
      0

      21
      Left
      1100
      0

      22
      Left
      1000
      0

      23
      Left
      0000
      0

      24
      Left
      0001
      0

      25
      Left
      0011
      0

      26
      Left
      0111
      0

      27
      Left
      1111
      0

      28
      Left
      1110
      0

      29
      Left
      1100
      0

      30
      Left
      1000
      0

      31
      Left
      0000
      1

      32
      Left
      0001
      0

```python
JohnsonCount3Data[JohnsonCount3Data['Dir']==DirStates.Halt]
```

      Dir
      q
      rst

      33
      Halt
      0011
      0

      34
      Halt
      0011
      0

      35
      Halt
      0011
      0

      36
      Halt
      0011
      0

      37
      Halt
      0011
      0

      38
      Halt
      0011
      0

## Verilog  Code

```python
DUT.convert()
VerilogTextReader('JohnsonCount3');
```

    ***Verilog modual from JohnsonCount3.v***

     // File: JohnsonCount3.v
    // Generated by MyHDL 0.10
    // Date: Wed Sep  5 07:53:01 2018

    `timescale 1ns/10ps

    module JohnsonCount3 (
        Dir,
        q,
        clk,
        rst
    );
    // Based of the `jc2` exsample from the myHDL website
    // http://www.myhdl.org/docs/examples/jc2.html
    //
    // Input:
    //     Dir(state): Left,Right, Halt Direction States
    //     clk(bool): input clock
    //     rst(bool): reset signal
    //
    // Ouput:
    //     q(bitVec): the values in the D flip flops(aka counter)

    input [1:0] Dir;
    output [3:0] q;
    wire [3:0] q;
    input clk;
    input rst;

    reg [3:0] q_i = 0;

    always @(posedge clk, negedge rst) begin: JOHNSONCOUNT3_JCSTATEMACHINE
        if (rst) begin
            q_i <= 0;
        end
        else if ((Dir == 2'b00)) begin
            q_i[4-1:1] <= q_i[(4 - 1)-1:0];
            q_i[0] <= (!q_i[(4 - 1)]);
        end
        else if ((Dir == 2'b01)) begin
            q_i <= q_i;
        end
        else if ((Dir == 2'b10)) begin
            q_i[(4 - 1)-1:0] <= q_i[4-1:1];
            q_i[(4 - 1)] <= (!q_i[0]);
        end
    end

    assign q = q_i;

    endmodule

\begin{figure}
\centerline{\includegraphics[width=10cm]{JohnsonCount3_RTL.png}}
\caption{\label{fig:JC3RTL} JohnsonCount3 RTL schematic; Xilinx Vivado 2017.4}
\end{figure}

\begin{figure}
\centerline{\includegraphics[width=10cm]{JohnsonCount3_SYN.png}}
\caption{\label{fig:JC3SYN} JohnsonCount3 Synthesized Schematic; Xilinx Vivado 2017.4}
\end{figure}

\begin{figure}
\centerline{\includegraphics[width=10cm]{JohnsonCount3_IMP.png}}
\caption{\label{fig:BGIMP} JohnsonCount3 Implementated Schematic; Xilinx Vivado 2017.4}
\end{figure}

## Verilog Testbench

```python
@block
def JohnsonCount3_TBV():
    """
    myHDL -> Verilog Testbench for `UpDown_Counter` module
    """

    clk=Signal(bool(0))
    rst=Signal(bool(0))
    q=Signal(intbv(0)[BitSize:])
    Dir=Signal(DirStates.Right)

    @always_comb
    def print_data():
        print(clk, rst, q, Dir)

    DUT=JohnsonCount3(Dir, q, clk, rst)

    @instance
    def clk_signal():
        while True:
            clk.next = not clk
            yield delay(1)

    @instance
    def stimules():
        i=0
        while True:
            if i==2*2*BitSize:
                Dir.next=DirStates.Left
            elif i==4*2*BitSize:
                rst.next=1
            elif i==4*2*BitSize+1:
                rst.next=0
            elif i==4*2*BitSize+2:
                Dir.next=DirStates.Halt
            else:
                pass

            if i==5*2*BitSize:
                raise StopSimulation()

            i+=1
            yield clk.posedge

    return instances()

TB=JohnsonCount3_TBV()
TB.convert(hdl="Verilog", initial_values=True)
VerilogTextReader('JohnsonCount3_TBV');
```

    <class 'myhdl._Signal._Signal'> <class '_ast.Name'>
    <class 'myhdl._Signal._Signal'> <class '_ast.Name'>
    <class 'myhdl._Signal._Signal'> <class '_ast.Name'>
    <class 'myhdl._Signal._Signal'> <class '_ast.Name'>
    ***Verilog modual from JohnsonCount3_TBV.v***

     // File: JohnsonCount3_TBV.v
    // Generated by MyHDL 0.10
    // Date: Wed Sep  5 07:53:06 2018

    `timescale 1ns/10ps

    module JohnsonCount3_TBV (

    );
    // myHDL -> Verilog Testbench for `UpDown_Counter` module

    reg clk = 0;
    reg rst = 0;
    wire [3:0] q;
    reg [1:0] Dir = 2'b10;
    reg [3:0] JohnsonCount30_0_q_i = 0;

    always @(rst, q, Dir, clk) begin: JOHNSONCOUNT3_TBV_PRINT_DATA
        $write("%h", clk);
        $write(" ");
        $write("%h", rst);
        $write(" ");
        $write("%h", q);
        $write(" ");
        $write("%h", Dir);
        $write("\n");
    end

    always @(posedge clk, negedge rst) begin: JOHNSONCOUNT3_TBV_JOHNSONCOUNT30_0_JCSTATEMACHINE
        if (rst) begin
            JohnsonCount30_0_q_i <= 0;
        end
        else if ((Dir == 2'b00)) begin
            JohnsonCount30_0_q_i[4-1:1] <= JohnsonCount30_0_q_i[(4 - 1)-1:0];
            JohnsonCount30_0_q_i[0] <= (!JohnsonCount30_0_q_i[(4 - 1)]);
        end
        else if ((Dir == 2'b01)) begin
            JohnsonCount30_0_q_i <= JohnsonCount30_0_q_i;
        end
        else if ((Dir == 2'b10)) begin
            JohnsonCount30_0_q_i[(4 - 1)-1:0] <= JohnsonCount30_0_q_i[4-1:1];
            JohnsonCount30_0_q_i[(4 - 1)] <= (!JohnsonCount30_0_q_i[0]);
        end
    end

    assign q = JohnsonCount30_0_q_i;

    initial begin: JOHNSONCOUNT3_TBV_CLK_SIGNAL
        while (1'b1) begin
            clk <= (!clk);
            # 1;
        end
    end

    initial begin: JOHNSONCOUNT3_TBV_STIMULES
        integer i;
        i = 0;
        while (1'b1) begin
            if ((i == ((2 * 2) * 4))) begin
                Dir <= 2'b00;
            end
            else if ((i == ((4 * 2) * 4))) begin
                rst <= 1;
            end
            else if ((i == (((4 * 2) * 4) + 1))) begin
                rst <= 0;
            end
            else if ((i == (((4 * 2) * 4) + 2))) begin
                Dir <= 2'b01;
            end
            else begin
                // pass
            end
            if ((i == ((5 * 2) * 4))) begin
                $finish;
            end
            i = i + 1;
            @(posedge clk);
        end
    end

    endmodule

## PYNQ-Z1 Deployment

### Board Constraints

```python
ConstraintXDCTextReader('PYNQ_Z1Constraints_JohnsonCount3');
```

    ***Constraint file from PYNQ_Z1Constraints_JohnsonCount3.xdc***

     ## PYNQ-Z1 Constraint File for JohnsonCount3
    ## Based on https://github.com/Xilinx/PYNQ/blob/master/sdbuild/boot_configs/Pynq-Z1-defconfig/constraints.xdc

    ##Switches

    set_property -dict {PACKAGE_PIN M20 IOSTANDARD LVCMOS33} [get_ports {Dir[0]}]; ##SW0
    set_property -dict {PACKAGE_PIN M19 IOSTANDARD LVCMOS33} [get_ports {Dir[1]}]; ##SW1

    ##LEDs

    set_property -dict {PACKAGE_PIN R14 IOSTANDARD LVCMOS33} [get_ports {q[0]}]; ##LED0
    set_property -dict {PACKAGE_PIN P14 IOSTANDARD LVCMOS33} [get_ports {q[1]}]; ##LED1
    set_property -dict {PACKAGE_PIN N16 IOSTANDARD LVCMOS33} [get_ports {q[2]}]; ##LED2
    set_property -dict {PACKAGE_PIN M14 IOSTANDARD LVCMOS33} [get_ports {q[3]}]; ##LED3

    set_property -dict { PACKAGE_PIN D19   IOSTANDARD LVCMOS33 } [get_ports { rst }]; ##btn[0]
    set_property -dict { PACKAGE_PIN L19   IOSTANDARD LVCMOS33 } [get_ports { clk }]; ##btn[3]
    ## Needed since if constraints even thinks a clock port is going to be connected to a non clock driver it wont synthize without it
    set_property CLOCK_DEDICATED_ROUTE FALSE [get_nets {clk}];
    ##should only be done for teaching and realy only on LOW (nearly none) jitter (Bouncy) sources

Pay attention to line 22 that follows of setting the `clk` input signal to Button 3
```
set_property CLOCK_DEDICATED_ROUTE FALSE [get_nets {clk}];

```
This is needed in the constraint file in order for the Implementation and Bitstream to work. What this line says to Vivado is "I know that a clock signal is hooked up to a nonstandard clock source, go ahead and make the connection so". This is because the internal rule checking in vivado will raise errors if one attempts to connect a nonclock source to what it perceives (in this case correctly) should be a clock input. Normally this should not be done this way. But because this is for teaching and the `JohnsonCount3` was to be implemented as a stand-alone module without a clock divider at a clock speed of Hertz (FPGAs typically have Megahertz built-in clocks) this had to be done.

### Deployment Results
YouTube:[Bi-Directional Johnson Counter from myHDL on the PYNQ-Z1
](https://www.youtube.com/watch?v=UulvPq7Tk_Q)

# Cyclic Shift Register Ring Counter
Like the Johnson Counter, which is the Mobius ring version of the Ring Counter, a Ring Counter is, in reality, a cyclic shift register since it simply shift the bits in its memory left or right. The following are
aspects of Ring Counter by Sougata Bhattacharjee [https://www.quora.com/What-is-the-difference-between-a-Johnson-counter-and-a-ring-counter]

\begin{itemize}
\item In a ring counter, the output of the last flip-flop is connected to the input of the first flip-flop.

\item If $n$ is the number of flip-flops that are used in ring counter, the number of possible states are also $n$.That means the number of states is equal to the number of flip-flops used.

\item A Ring counter is mostly used in Successive approximation type ADC and stepper motor control.

\item Decoding is easy in a ring counter as the number of states is equal to the number of flip-flops.

\item If the input frequency to a ring counter is $f$ then the output frequency $\dfrac{f}{n}$.

\item The total number of unused states in the ring counter is $(2^n - n)$.

\end{itemize}

For a four-bit ring counter, the next state diagram is given by the following table from [wikipedga](https://en.wikipedia.org/wiki/Ring_counter)

\begin{figure}
\centerline{\includegraphics[width=1cm]{RingCounterTable.png}}
\caption{\label{fig:RingTable} 4-bit Ring Counter next state table from [wikipedia](https://en.wikipedia.org/wiki/Ring_counter#Four-bit_ring-counter_sequences)}
\end{figure}

## myHDL Module

```python
#Create the Direction States for Ring Counter
DirStates=enum('Left','Halt','Right')
print(f"`Left` state repersentation is {bin(DirStates.Left)}")
print(f"`Halt` state repersentation is {bin(DirStates.Halt)}")
print(f"`Right` state repersentation is {bin(DirStates.Right)}")
```

    `Left` state repersentation is 0
    `Halt` state repersentation is 1
    `Right` state repersentation is 10

```python
@block
def RingCounter(seed, Dir, q, clk, rst):
    """
    Seedable and direction controlable ring counter in myHDL

    Input:
        seed(bitvec): intial value for ring counter
        Dir(enum): Direction contorl signal
        clk(bool): clock
        rst(bool): reset
    Output
    """
    q_i=Signal(intbv(int(seed))[len(q):])
    @always(clk.posedge, rst.negedge)
    def RCStateMachine():
        #moore state machine
        if rst:
            q_i.next=seed
        elif Dir==DirStates.Left:
            q_i.next=concat(q_i[len(q_i)-1:0],q_i[len(q_i)-1])

        elif Dir==DirStates.Halt:
            #create circular stop
            q_i.next=q_i

        elif Dir==DirStates.Right:
            q_i.next=concat(q_i[0], q_i[len(q_i):1])

    @always_comb
    def OuputBuffer():
        q.next=q_i

    return instances()

```

## myHDL testing

```python
BitSize=4; seedval=3
Peeker.clear()
seed=Signal(intbv(seedval)[BitSize:]); Peeker(seed, 'seed')
clk=Signal(bool(0)); Peeker(clk, 'clk')
rst=Signal(bool(0)); Peeker(rst, 'rst')
q=Signal(intbv(0)[BitSize:]); Peeker(q, 'q')
Dir=Signal(DirStates.Right); Peeker(Dir, 'Dir')

DUT=RingCounter(seed, Dir, q, clk, rst)

def RingCounter_TB():
    """
    myHDL only Testbench for `RingCounter` module
    """
    @always(delay(1))
    def ClkGen():
        clk.next=not clk

    @instance
    def stimules():
        i=0
        while True:
            if i==2*BitSize:
                Dir.next=DirStates.Left
            elif i==3*BitSize:
                rst.next=1
            elif i==3*BitSize+1:
                rst.next=0
            elif i==3*BitSize+2:
                Dir.next=DirStates.Halt

            if i==5*BitSize:
                raise StopSimulation()

            i+=1
            yield clk.posedge

    return instances()

sim=Simulation(DUT, RingCounter_TB(), *Peeker.instances()).run()
```

```python
Peeker.to_wavedrom()
```

```python
RingCountData=Peeker.to_dataframe()
RingCountData=RingCountData[RingCountData['clk']==1]
RingCountData.drop('clk', axis=1, inplace=True)
RingCountData.reset_index(drop=True, inplace=True)
RingCountData
```

      Dir
      q
      rst
      seed

      0
      Right
      9
      0
      3

      1
      Right
      12
      0
      3

      2
      Right
      6
      0
      3

      3
      Right
      3
      0
      3

      4
      Right
      9
      0
      3

      5
      Right
      12
      0
      3

      6
      Right
      6
      0
      3

      7
      Left
      3
      0
      3

      8
      Left
      6
      0
      3

      9
      Left
      12
      0
      3

      10
      Left
      9
      0
      3

      11
      Left
      3
      1
      3

      12
      Left
      6
      0
      3

      13
      Halt
      12
      0
      3

      14
      Halt
      12
      0
      3

      15
      Halt
      12
      0
      3

      16
      Halt
      12
      0
      3

      17
      Halt
      12
      0
      3

      18
      Halt
      12
      0
      3

```python
RingCountData['q']=RingCountData['q'].apply(lambda x:bin(x, BitSize))
RingCountData
```

      Dir
      q
      rst
      seed

      0
      Right
      1001
      0
      3

      1
      Right
      1100
      0
      3

      2
      Right
      0110
      0
      3

      3
      Right
      0011
      0
      3

      4
      Right
      1001
      0
      3

      5
      Right
      1100
      0
      3

      6
      Right
      0110
      0
      3

      7
      Left
      0011
      0
      3

      8
      Left
      0110
      0
      3

      9
      Left
      1100
      0
      3

      10
      Left
      1001
      0
      3

      11
      Left
      0011
      1
      3

      12
      Left
      0110
      0
      3

      13
      Halt
      1100
      0
      3

      14
      Halt
      1100
      0
      3

      15
      Halt
      1100
      0
      3

      16
      Halt
      1100
      0
      3

      17
      Halt
      1100
      0
      3

      18
      Halt
      1100
      0
      3

```python
RingCountData[RingCountData['Dir']==DirStates.Right]
```

      Dir
      q
      rst
      seed

      0
      Right
      1001
      0
      3

      1
      Right
      1100
      0
      3

      2
      Right
      0110
      0
      3

      3
      Right
      0011
      0
      3

      4
      Right
      1001
      0
      3

      5
      Right
      1100
      0
      3

      6
      Right
      0110
      0
      3

```python
RingCountData[RingCountData['Dir']==DirStates.Left]
```

      Dir
      q
      rst
      seed

      7
      Left
      0011
      0
      3

      8
      Left
      0110
      0
      3

      9
      Left
      1100
      0
      3

      10
      Left
      1001
      0
      3

      11
      Left
      0011
      1
      3

      12
      Left
      0110
      0
      3

```python
RingCountData[RingCountData['Dir']==DirStates.Halt]
```

      Dir
      q
      rst
      seed

      13
      Halt
      1100
      0
      3

      14
      Halt
      1100
      0
      3

      15
      Halt
      1100
      0
      3

      16
      Halt
      1100
      0
      3

      17
      Halt
      1100
      0
      3

      18
      Halt
      1100
      0
      3

## Verilog Code

```python
DUT.convert()
VerilogTextReader('RingCounter');
```

    ***Verilog modual from RingCounter.v***

     // File: RingCounter.v
    // Generated by MyHDL 0.10
    // Date: Wed Sep  5 07:53:27 2018

    `timescale 1ns/10ps

    module RingCounter (
        seed,
        Dir,
        q,
        clk,
        rst
    );
    // Seedable and direction controlable ring counter in myHDL
    //
    // Input:
    //     seed(bitvec): intial value for ring counter
    //     Dir(enum): Direction contorl signal
    //     clk(bool): clock
    //     rst(bool): reset
    // Output

    input [3:0] seed;
    input [1:0] Dir;
    output [3:0] q;
    wire [3:0] q;
    input clk;
    input rst;

    reg [3:0] q_i = 3;

    always @(posedge clk, negedge rst) begin: RINGCOUNTER_RCSTATEMACHINE
        if (rst) begin
            q_i <= seed;
        end
        else if ((Dir == 2'b00)) begin
            q_i <= {q_i[(4 - 1)-1:0], q_i[(4 - 1)]};
        end
        else if ((Dir == 2'b01)) begin
            q_i <= q_i;
        end
        else if ((Dir == 2'b10)) begin
            q_i <= {q_i[0], q_i[4-1:1]};
        end
    end

    assign q = q_i;

    endmodule

\begin{figure}
\centerline{\includegraphics[width=10cm]{RingCounter_RTL.png}}
\caption{\label{fig:RCRTL} RingCounter RTL schematic; Xilinx Vivado 2017.4}
\end{figure}

\begin{figure}
\centerline{\includegraphics[width=10cm]{RingCounter_SYN.png}}
\caption{\label{fig:RCSYN} RingCounter Synthesized Schematic; Xilinx Vivado 2017.4}
\end{figure}

## Verilog Testbench

```python
BitSize=4; seedval=3
@block
def RingCounter_TBV():
    """
    myHDL -> verilog Testbench for `RingCounter` module
    """
    seed=Signal(intbv(seedval)[BitSize:])
    clk=Signal(bool(0))
    rst=Signal(bool(0))
    q=Signal(intbv(0)[BitSize:])
    Dir=Signal(DirStates.Right)

    @always_comb
    def print_data():
        print(seed, Dir, q, clk, rst)

    DUT=RingCounter(seed, Dir, q, clk, rst)

    @instance
    def clk_signal():
        while True:
            clk.next = not clk
            yield delay(1)

    @instance
    def stimules():
        i=0
        while True:
            if i==2*BitSize:
                Dir.next=DirStates.Left
            elif i==3*BitSize:
                rst.next=1
            elif i==3*BitSize+1:
                rst.next=0
            elif i==3*BitSize+2:
                Dir.next=DirStates.Halt

            if i==5*BitSize:
                raise StopSimulation()

            i+=1
            yield clk.posedge

    return instances()

TB=RingCounter_TBV()
TB.convert(hdl="Verilog", initial_values=True)
VerilogTextReader('RingCounter_TBV');
```

    <class 'myhdl._Signal._Signal'> <class '_ast.Name'>
    <class 'myhdl._Signal._Signal'> <class '_ast.Name'>
    <class 'myhdl._Signal._Signal'> <class '_ast.Name'>
    <class 'myhdl._Signal._Signal'> <class '_ast.Name'>
    <class 'myhdl._Signal._Signal'> <class '_ast.Name'>
    ***Verilog modual from RingCounter_TBV.v***

     // File: RingCounter_TBV.v
    // Generated by MyHDL 0.10
    // Date: Wed Sep  5 07:53:29 2018

    `timescale 1ns/10ps

    module RingCounter_TBV (

    );
    // myHDL -> verilog Testbench for `RingCounter` module

    reg clk = 0;
    reg rst = 0;
    wire [3:0] q;
    reg [1:0] Dir = 2'b10;
    wire [3:0] seed;
    reg [3:0] RingCounter0_0_q_i = 3;

    assign seed = 4'd3;

    always @(q, rst, Dir, clk, seed) begin: RINGCOUNTER_TBV_PRINT_DATA
        $write("%h", seed);
        $write(" ");
        $write("%h", Dir);
        $write(" ");
        $write("%h", q);
        $write(" ");
        $write("%h", clk);
        $write(" ");
        $write("%h", rst);
        $write("\n");
    end

    always @(posedge clk, negedge rst) begin: RINGCOUNTER_TBV_RINGCOUNTER0_0_RCSTATEMACHINE
        if (rst) begin
            RingCounter0_0_q_i <= seed;
        end
        else if ((Dir == 2'b00)) begin
            RingCounter0_0_q_i <= {RingCounter0_0_q_i[(4 - 1)-1:0], RingCounter0_0_q_i[(4 - 1)]};
        end
        else if ((Dir == 2'b01)) begin
            RingCounter0_0_q_i <= RingCounter0_0_q_i;
        end
        else if ((Dir == 2'b10)) begin
            RingCounter0_0_q_i <= {RingCounter0_0_q_i[0], RingCounter0_0_q_i[4-1:1]};
        end
    end

    assign q = RingCounter0_0_q_i;

    initial begin: RINGCOUNTER_TBV_CLK_SIGNAL
        while (1'b1) begin
            clk <= (!clk);
            # 1;
        end
    end

    initial begin: RINGCOUNTER_TBV_STIMULES
        integer i;
        i = 0;
        while (1'b1) begin
            if ((i == (2 * 4))) begin
                Dir <= 2'b00;
            end
            else if ((i == (3 * 4))) begin
                rst <= 1;
            end
            else if ((i == ((3 * 4) + 1))) begin
                rst <= 0;
            end
            else if ((i == ((3 * 4) + 2))) begin
                Dir <= 2'b01;
            end
            if ((i == (5 * 4))) begin
                $finish;
            end
            i = i + 1;
            @(posedge clk);
        end
    end

    endmodule

    /home/iridium/anaconda3/lib/python3.6/site-packages/myhdl/conversion/_toVerilog.py:349: ToVerilogWarning: Signal is not driven: seed
      category=ToVerilogWarning

## PYNQ-Z1 Deployment

### Block Design
Video on how Block Design was made found here: YouTube:[Seeded Ring Counter RTL IP Hookup in Vivado from myHDL to PYNQ-Z1
](https://youtu.be/vnCKs0hQq3U)

\begin{figure}
\centerline{\includegraphics[width=10cm]{RingBlockDesign.png}}
\caption{\label{fig:RCBD} RingCounter Block IP Block Design; Xilinx Vivado 2017.4}
\end{figure}

The Constant IP in the top left corner of the Block Design has the following internal parameterizations, accessed by right clicking on the IP and selecting "Customize Block"
\begin{figure}
\centerline{\includegraphics[width=10cm]{ConstIPSettings.png}}
\caption{\label{fig:ConstSetting} Xilinx IP Constant 1.1 Internal Settings for  Ring Counter Block design ; Xilinx Vivado 2017.4}
\end{figure}

### Board Constraints

```python
ConstraintXDCTextReader('PYNQ_Z1Constraints_RingCounterBlock');
```

    ***Constraint file from PYNQ_Z1Constraints_RingCounterBlock.xdc***

     ## PYNQ-Z1 Constraint File for RingCounterBlock
    ## Based on https://github.com/Xilinx/PYNQ/blob/master/sdbuild/boot_configs/Pynq-Z1-defconfig/constraints.xdc

    ##Switches

    set_property -dict {PACKAGE_PIN M20 IOSTANDARD LVCMOS33} [get_ports {Dir[0]}]; ##SW0
    set_property -dict {PACKAGE_PIN M19 IOSTANDARD LVCMOS33} [get_ports {Dir[1]}]; ##SW1

    ##LEDs

    set_property -dict {PACKAGE_PIN R14 IOSTANDARD LVCMOS33} [get_ports {q[0]}]; ##LED0
    set_property -dict {PACKAGE_PIN P14 IOSTANDARD LVCMOS33} [get_ports {q[1]}]; ##LED1
    set_property -dict {PACKAGE_PIN N16 IOSTANDARD LVCMOS33} [get_ports {q[2]}]; ##LED2
    set_property -dict {PACKAGE_PIN M14 IOSTANDARD LVCMOS33} [get_ports {q[3]}]; ##LED3

    set_property -dict { PACKAGE_PIN D19   IOSTANDARD LVCMOS33 } [get_ports { rst }]; ##btn[0]
    set_property -dict { PACKAGE_PIN L19   IOSTANDARD LVCMOS33 } [get_ports { clk }]; ##btn[3]
    ## Needed since if constraints even thinks a clock port is going to be connected to a non clock driver it wont synthize without it
    set_property CLOCK_DEDICATED_ROUTE FALSE [get_nets {clk}];
    ##should only be done for teaching and realy only on LOW (nearly none) jitter (Bouncy) sources

### RTL, Synthesis, & Implementation

\begin{figure}
\centerline{\includegraphics[width=10cm]{RingCounterBlock_RTL1.png}}
\caption{\label{fig:RCBRTL1} Ring Counter Block RTL schematic Level 1; Xilinx Vivado 2017.4}
\end{figure}

\begin{figure}
\centerline{\includegraphics[width=10cm]{RingCounterBlock_RTL23.png}}
\caption{\label{fig:RCBRTL23} Ring Counter Block RTL `RingImp_i` schematic internal; Xilinx Vivado 2017.4}
\end{figure}

\begin{figure}
\centerline{\includegraphics[width=10cm]{RingCounterBlock_RTL4.png}}
\caption{\label{fig:RCBRTL4} Ring Counter Block RTL `RingCounter_0` `inst` schematic internal; Xilinx Vivado 2017.4}
\end{figure}

\begin{figure}
\centerline{\includegraphics[width=10cm]{RingCounterBlock_SYN13.png}}
\caption{\label{fig:RCBSYN} Ring Counter Block Synthesized Schematic; Xilinx Vivado 2017.4}
\end{figure}

\begin{figure}
\centerline{\includegraphics[width=10cm]{RingCounterBlock_IMP1.png}}
\caption{\label{fig:RCBIMP1} Ring Counter Block Implementated Schematic Top Level; Xilinx Vivado 2017.4}
\end{figure}

\begin{figure}
\centerline{\includegraphics[width=10cm]{RingCounterBlock_IMP3.png}}
\caption{\label{fig:RCBIMP3} Ring Counter Block Implementated Schematic Expanded; Xilinx Vivado 2017.4}
\end{figure}

### Deployment Results
YouTube:[Seeded Ring Counter from myHDL on PYNQ-Z1
](https://www.youtube.com/watch?v=7ZQ4qCvjokU)