# Numba

## Contents

- [Numba](#Numba)
  - [Overview](#Overview)
  - [Compiling Functions](#Compiling-Functions)
  - [Decorators and “nopython” Mode](#Decorators-and-“nopython”-Mode)
  - [Compiling Classes](#Compiling-Classes)
  - [Alternatives to Numba](#Alternatives-to-Numba)
  - [Summary and Comments](#Summary-and-Comments)
  - [Exercises](#Exercises)
  - [Solutions](#Solutions)

In addition to what’s in Anaconda, this lecture will need the following libraries:

```python
!pip install --upgrade quantecon
```

    Requirement already up-to-date: quantecon in /usr/local/lib/python3.7/site-packages (0.4.6)
    Requirement already satisfied, skipping upgrade: scipy>=1.0.0 in /usr/local/lib/python3.7/site-packages (from quantecon) (1.2.1)
    Requirement already satisfied, skipping upgrade: sympy in /usr/local/lib/python3.7/site-packages (from quantecon) (1.5)
    Requirement already satisfied, skipping upgrade: numba>=0.38 in /usr/local/lib/python3.7/site-packages (from quantecon) (0.46.0)
    Requirement already satisfied, skipping upgrade: numpy in /usr/local/lib/python3.7/site-packages (from quantecon) (1.16.2)
    Requirement already satisfied, skipping upgrade: requests in /usr/local/lib/python3.7/site-packages (from quantecon) (2.21.0)
    Requirement already satisfied, skipping upgrade: mpmath>=0.19 in /usr/local/lib/python3.7/site-packages (from sympy->quantecon) (1.1.0)
    Requirement already satisfied, skipping upgrade: llvmlite>=0.30.0dev0 in /usr/local/lib/python3.7/site-packages (from numba>=0.38->quantecon) (0.30.0)
    Requirement already satisfied, skipping upgrade: certifi>=2017.4.17 in /usr/local/lib/python3.7/site-packages (from requests->quantecon) (2018.11.29)
    Requirement already satisfied, skipping upgrade: idna<2.9,>=2.5 in /usr/local/lib/python3.7/site-packages (from requests->quantecon) (2.8)
    Requirement already satisfied, skipping upgrade: urllib3<1.25,>=1.21.1 in /usr/local/lib/python3.7/site-packages (from requests->quantecon) (1.24.1)
    Requirement already satisfied, skipping upgrade: chardet<3.1.0,>=3.0.2 in /usr/local/lib/python3.7/site-packages (from requests->quantecon) (3.0.4)
    You are using pip version 19.0.3, however version 19.3.1 is available.
    You should consider upgrading via the 'pip install --upgrade pip' command.

Please also make sure that you have the latest version of Anaconda, since old
versions are a [common source of errors](troubleshooting.ipynb).

Let’s start with some imports:

```python
import numpy as np
import quantecon as qe
import matplotlib.pyplot as plt

%matplotlib inline
```

## Overview

In an [earlier lecture](need_for_speed.ipynb) we learned about vectorization, which is one method to improve speed and efficiency in numerical work.

Vectorization involves sending array processing
operations in batch to efficient low-level code.

However, as [discussed previously](need_for_speed.ipynb#numba-p-c-vectorization), vectorization has several weaknesses.

One is that it is highly memory-intensive when working with large amounts of data.

Another is that the set of algorithms that can be entirely vectorized is not universal.

In fact, for some algorithms, vectorization is ineffective.

Fortunately, a new Python library called [Numba](http://numba.pydata.org/)
solves many of these problems.

It does so through something called **just in time (JIT) compilation**.

The key idea is to compile functions to native machine code instructions on the fly.

When it succeeds, the compiled code is extremely fast.

Numba is specifically designed for numerical work and can also do other tricks such as multithreading.

Numba will be a key part of our lectures — especially those lectures involving dynamic programming.

This lecture introduces the main ideas.

## Compiling Functions

As stated above, Numba’s primary use is compiling functions to fast native
machine code during runtime.

### An Example

Let’s consider a problem that is difficult to vectorize: generating the trajectory of a difference equation given an initial condition.

We will take the difference equation to be the quadratic map

$$
x_{t+1} = \alpha x_t (1 - x_t)
$$

In what follows we set

```python
α = 4.0
```

Here’s the plot of a typical trajectory, starting from $ x_0 = 0.1 $, with $ t $ on the x-axis

```python
def qm(x0, n):
    x = np.empty(n+1)
    x[0] = x0
    for t in range(n):
      x[t+1] = α * x[t] * (1 - x[t])
    return x

x = qm(0.1, 250)
fig, ax = plt.subplots()
ax.plot(x, 'b-', lw=2, alpha=0.8)
ax.set_xlabel('time', fontsize=16)
plt.show()
```

To speed the function `qm` up using Numba, our first step is

```python
from numba import jit

qm_numba = jit(qm)
```

The function qm_numba is a version of qm that is “targeted” for
JIT-compilation.

We will explain what this means momentarily.

Let’s time and compare identical function calls across these two versions, starting with the original function qm:

```python
n = 10_000_000

qe.tic()
qm(0.1, int(n))
time1 = qe.toc()
```

Now let’s try qm_numba

```python
qe.tic()
qm_numba(0.1, int(n))
time2 = qe.toc()
```

This is already a massive speed gain.

In fact, the next time and all subsequent times it runs even faster as the function has been compiled and is in memory:

```python
qe.tic()
qm_numba(0.1, int(n))
time2 = qe.toc()
```

```python
time1 / time2  # Calculate speed gain
```

This kind of speed gain is huge relative to how simple and clear the implementation is.

### How and When it Works

Numba attempts to generate fast machine code using the infrastructure provided by the [LLVM Project](http://llvm.org/).

It does this by inferring type information on the fly.

(See our [earlier lecture](need_for_speed.ipynb) on scientific computing for a discussion of types.)

The basic idea is this:

- Python is very flexible and hence we could call the function qm with many
  types.

  - e.g., x0 could be a NumPy array or a list, n could be an integer or a float, etc.

- This makes it hard to *pre*-compile the function.
- However, when we do actually call the function, by executing qm(0.5, 10),
  say, the types of x0 and n become clear.
- Moreover, the types of other variables in qm can be inferred once the input is known.
- So the strategy of Numba and other JIT compilers is to wait until this
  moment, and *then* compile the function.

That’s why it is called “just-in-time” compilation.

Note that, if you make the call qm(0.5, 10) and then follow it with qm(0.9, 20), compilation only takes place on the first call.

The compiled code is then cached and recycled as required.

## Decorators and “nopython” Mode

In the code above we created a JIT compiled version of `qm` via the call

```python
qm_numba = jit(qm)
```

In practice this would typically be done using an alternative *decorator* syntax.

(We will explain all about decorators in a [later lecture](python_advanced_features.ipynb) but you can skip the details at this stage.)

Let’s see how this is done.

### Decorator Notation

To target a function for JIT compilation we can put `@jit` before the function definition.

Here’s what this looks like for `qm`

```python
@jit
def qm(x0, n):
    x = np.empty(n+1)
    x[0] = x0
    for t in range(n):
        x[t+1] = α * x[t] * (1 - x[t])
    return x
```

This is equivalent to `qm = jit(qm)`.

The following now uses the jitted version:

```python
qm(0.1, 10)
```

### Type Inference and “nopython” Mode

Clearly type inference is a key part of JIT compilation.

As you can imagine, inferring types is easier for simple Python objects (e.g., simple scalar data types such as floats and integers).

Numba also plays well with NumPy arrays.

In an ideal setting, Numba can infer all necessary type information.

This allows it to generate native machine code, without having to call the Python runtime environment.

In such a setting, Numba will be on par with machine code from low-level languages.

When Numba cannot infer all type information, some Python objects are given generic `object` status and execution falls back to the Python runtime.

When this happens, Numba provides only minor speed gains or none at all.

We generally prefer to force an error when this occurs, so we know effective
compilation is failing.

This is done by using either `@jit(nopython=True)` or, equivalently, `@njit` instead of `@jit`.

For example,

```python
from numba import njit

@njit
def qm(x0, n):
    x = np.empty(n+1)
    x[0] = x0
    for t in range(n):
        x[t+1] = 4 * x[t] * (1 - x[t])
    return x
```

## Compiling Classes

As mentioned above, at present Numba can only compile a subset of Python.

However, that subset is ever expanding.

For example, Numba is now quite effective at compiling classes.

If a class is successfully compiled, then its methods acts as JIT-compiled
functions.

To give one example, let’s consider the class for analyzing the Solow growth model we
created in [this lecture](python_oop.ipynb).

To compile this class we use the @jitclass decorator:

```python
from numba import jitclass, float64
```

Notice that we also imported something called float64.

This is a data type representing standard floating point numbers.

We are importing it here because Numba needs a bit of extra help with types when it trys to deal with classes.

Here’s our code:

```python
solow_data = [
    ('n', float64),
    ('s', float64),
    ('δ', float64),
    ('α', float64),
    ('z', float64),
    ('k', float64)
]

@jitclass(solow_data)
class Solow:
    r"""
    Implements the Solow growth model with the update rule

        k_{t+1} = [(s z k^α_t) + (1 - δ)k_t] /(1 + n)

    """
    def __init__(self, n=0.05,  # population growth rate
                       s=0.25,  # savings rate
                       δ=0.1,   # depreciation rate
                       α=0.3,   # share of labor
                       z=2.0,   # productivity
                       k=1.0):  # current capital stock

        self.n, self.s, self.δ, self.α, self.z = n, s, δ, α, z
        self.k = k

    def h(self):
        "Evaluate the h function"
        # Unpack parameters (get rid of self to simplify notation)
        n, s, δ, α, z = self.n, self.s, self.δ, self.α, self.z
        # Apply the update rule
        return (s * z * self.k**α + (1 - δ) * self.k) / (1 + n)

    def update(self):
        "Update the current state (i.e., the capital stock)."
        self.k =  self.h()

    def steady_state(self):
        "Compute the steady state value of capital."
        # Unpack parameters (get rid of self to simplify notation)
        n, s, δ, α, z = self.n, self.s, self.δ, self.α, self.z
        # Compute and return steady state
        return ((s * z) / (n + δ))**(1 / (1 - α))

    def generate_sequence(self, t):
        "Generate and return a time series of length t"
        path = []
        for i in range(t):
            path.append(self.k)
            self.update()
        return path
```

First we specified the types of the instance data for the class in
solow_data.

After that, targeting the class for JIT compilation only requires adding
@jitclass(solow_data) before the class definition.

When we call the methods in the class, the methods are compiled just like functions.

```python
s1 = Solow()
s2 = Solow(k=8.0)

T = 60
fig, ax = plt.subplots()

# Plot the common steady state value of capital
ax.plot([s1.steady_state()]*T, 'k-', label='steady state')

# Plot time series for each economy
for s in s1, s2:
    lb = f'capital series from initial state {s.k}'
    ax.plot(s.generate_sequence(T), 'o-', lw=2, alpha=0.6, label=lb)

ax.legend()
plt.show()
```

## Alternatives to Numba

There are additional options for accelerating Python loops.

Here we quickly review them.

However, we do so only for interest and completeness.

If you prefer, you can safely skip this section.

### Cython

Like [Numba](.ipynb),  [Cython](http://cython.org/) provides an approach to generating fast compiled code that can be used from Python.

As was the case with Numba, a key problem is the fact that Python is dynamically typed.

As you’ll recall, Numba solves this problem (where possible) by inferring type.

Cython’s approach is different — programmers add type definitions directly to their “Python” code.

As such, the Cython language can be thought of as Python with type definitions.

In addition to a language specification, Cython is also a language translator, transforming Cython code into optimized C and C++ code.

Cython also takes care of building language extensions — the wrapper code that interfaces between the resulting compiled code and Python.

While Cython has certain advantages, we generally find it both slower and more
cumbersome than Numba.

### Interfacing with Fortran via F2Py

If you are comfortable writing Fortran you will find it very easy to create
extension modules from Fortran code using [F2Py](https://docs.scipy.org/doc/numpy/f2py/).

F2Py is a Fortran-to-Python interface generator that is particularly simple to
use.

Robert Johansson provides a [nice introduction](http://nbviewer.jupyter.org/github/jrjohansson/scientific-python-lectures/blob/master/Lecture-6A-Fortran-and-C.ipynb)
to F2Py, among other things.

Recently, [a Jupyter cell magic for Fortran](http://nbviewer.jupyter.org/github/mgaitan/fortran_magic/blob/master/documentation.ipynb) has been developed — you might want to give it a try.

## Summary and Comments

Let’s review the above and add some cautionary notes.

### Limitations

As we’ve seen, Numba needs to infer type information on
all variables to generate fast machine-level instructions.

For simple routines, Numba infers types very well.

For larger ones, or for routines using external libraries, it can easily fail.

Hence, it’s prudent when using Numba to focus on speeding up small, time-critical snippets of code.

This will give you much better performance than blanketing your Python programs with `@jit` statements.

### A Gotcha: Global Variables

Here’s another thing to be careful about when using Numba.

Consider the following example

```python
a = 1

@jit
def add_a(x):
    return a + x

print(add_a(10))
```

```python
a = 2

print(add_a(10))
```

Notice that changing the global had no effect on the value returned by the
function.

When Numba compiles machine code for functions, it treats global variables as constants to ensure type stability.

## Exercises

### Exercise 1

[An exercise](https://python.quantecon.org/python_by_example.html#Exercise-3) in one of the QuantEcon lectures considers how to approximate $ \pi $ by
Monte Carlo.

Use the same idea here, but make the code efficient using Numba.

Compare speed with and without Numba when the sample size is large.

### Exercise 2

Later we’ll learn about finite-state Markov chains.

For now, let’s just concentrate on simulating a very simple example of such a chain.

Suppose that the volatility of returns on an asset can be in one of two regimes — high or low.

The transition probabilities across states are as follows

For example, let the period length be one day, and suppose the current state is high.

We see from the graph that the state tomorrow will be

- high with probability 0.8
- low with probability 0.2

Your task is to simulate a sequence of daily volatility states according to this rule.

Set the length of the sequence to `n = 1_000_000` and start in the high state.

Implement a pure Python version and a Numba version, and compare speeds.

To test your code, evaluate the fraction of time that the chain spends in the low state.

If your code is correct, it should be about 2/3.

Hints:

- Represent the low state as 0 and the high state as 1.
- If you want to store integers in a NumPy array and then apply JIT compilation, use `x = np.empty(n, dtype=np.int_)`.


# Homework 5
## Due Date:  Tuesday, October 3rd at 11:59 PM

# Problem 1
We discussed documentation and testing in lecture and also briefly touched on code coverage.  You must write tests for your code for your final project (and in life).  There is a nice way to automate the testing process called continuous integration (CI).

This problem will walk you through the basics of CI and show you how to get up and running with some CI software.

### Continuous Integration
The idea behind continuous integration is to automate away the testing of your code.

We will be using it for our projects.

The basic workflow goes something like this:

1. You work on your part of the code in your own branch or fork
2. On every commit you make and push to GitHub, your code is automatically tested on a fresh machine on Travis CI. This ensures that there are no specific dependencies on the structure of your machine that your code needs to run and also ensures that your changes are sane
3. Now you submit a pull request to `master` in the main repo (the one you're hoping to contribute to). The repo manager creates a branch off `master`.
4. This branch is also set to run tests on Travis. If all tests pass, then the pull request is accepted and your code becomes part of master.

We use GitHub to integrate our roots library with Travis CI and Coveralls. Note that this is not the only workflow people use. Google git..github..workflow and feel free to choose another one for your group.

### Part 1:  Create a repo
Create a public GitHub repo called `cs207test` and clone it to your local machine.

**Note:** No need to do this in Jupyter.

### Part 2:  Create a roots library
Use the example from lecture 7 to create a file called `roots.py`, which contains the `quad_roots` and `linear_roots` functions (along with their documentation).

Also create a file called `test_roots.py`, which contains the tests from lecture.

All of these files should be in your newly created `cs207test` repo.  **Don't push yet!!!**

```bash
%%bash
cd ../../../cs207test
file roots.py

def linear_roots(a=1.0, b=0.0):
    if a == 0:
        raise ValueError("The linear coefficient is zero.  This is not a linear equation.")
    else:
        return ((-b / a))

def quad_roots(a=1.0, b=2.0, c=0.0):
    import cmath # Can return complex numbers from square roots
    if a == 0:
        raise ValueError("The quadratic coefficient is zero.  This is not a quadratic equation.")
    else:
        sqrtdisc = cmath.sqrt(b * b - 4.0 * a * c)
        r1 = -b + sqrtdisc
        r2 = -b - sqrtdisc
        return (r1 / 2.0 / a, r2 / 2.0 / a)

```

    roots.py: ASCII English text

    bash: line 4: syntax error near unexpected token `('
    bash: line 4: `def linear_roots(a=1.0, b=0.0):'

```python

```

### Part 3:  Create an account on Travis CI and Start Building

#### Part A:
Create an account on Travis CI and set your `cs207test` repo up for continuous integration once this repo can be seen on Travis.

#### Part B:
Create an instruction to Travis to make sure that

1. python is installed
2. its python 3.5
3. pytest is installed

The file should be called `.travis.yml` and should have the contents:
```yml
language: python
python:
    - "3.5"
before_install:
    - pip install pytest pytest-cov
script:
    - pytest
```

You should also create a configuration file called `setup.cfg`:
```cfg
[tool:pytest]
addopts = --doctest-modules --cov-report term-missing --cov roots
```

#### Part C:
Push the new changes to your `cs207test` repo.

At this point you should be able to see your build on Travis and if and how your tests pass.

### Part 4:  Coveralls Integration
In class, we also discussed code coverage.  Just like Travis CI runs tests automatically for you, Coveralls automatically checks your code coverage.  One minor drawback of Coveralls is that it can only work with public GitHub accounts.  However, this isn't too big of a problem since your projects will be public.

#### Part A:
Create an account on [`Coveralls`](https://coveralls.zendesk.com/hc/en-us), connect your GitHub, and turn Coveralls integration on.

#### Part B:
Update your the `.travis.yml` file as follows:
```yml
language: python
python:
    - "3.5"
before_install:
    - pip install pytest pytest-cov
    - pip install coveralls
script:
    - py.test
after_success:
    - coveralls
```

Be sure to push the latest changes to your new repo.

### Part 5:  Update README.md in repo
You can have your GitHub repo reflect the build status on Travis CI and the code coverage status from Coveralls.  To do this, you should modify the `README.md` file in your repo to include some badges.  Put the following at the top of your `README.md` file:

```
[](https://travis-ci.org/dsondak/cs207testing.svg?branch=master)

[](https://coveralls.io/github/dsondak/cs207testing?branch=master)
```

Of course, you need to make sure that the links are to your repo and not mine.  You can find embed code on the Coveralls and Travis CI sites.

---

# Problem 2
Write a Python module for reaction rate coefficients.  Your module should include functions for constant reaction rate coefficients, Arrhenius reaction rate coefficients, and modified Arrhenius reaction rate coefficients.  Here are their mathematical forms:
\begin{align}
  &k_{\textrm{const}}   = k \tag{constant} \\
  &k_{\textrm{arr}}     = A \exp\left(-\frac{E}{RT}\right) \tag{Arrhenius} \\
  &k_{\textrm{mod arr}} = A T^{b} \exp\left(-\frac{E}{RT}\right) \tag{Modified Arrhenius}
\end{align}

Test your functions with the following paramters:  $A = 10^7$, $b=0.5$, $E=10^3$.  Use $T=10^2$.

A few additional comments / suggestions:
* The Arrhenius prefactor $A$ is strictly positive
* The modified Arrhenius parameter $b$ must be real
* $R = 8.314$ is the ideal gas constant.  It should never be changed (except to convert units)
* The temperature $T$ must be positive (assuming a Kelvin scale)
* You may assume that units are consistent
* Document each function!
* You might want to check for overflows and underflows

**Recall:** A Python module is a `.py` file which is not part of the main execution script.  The module contains several functions which may be related to each other (like in this problem).  Your module will be importable via the execution script.  For example, suppose you have called your module `reaction_coeffs.py` and your execution script `kinetics.py`.  Inside of `kinetics.py` you will write something like:
```python
import reaction_coeffs
# Some code to do some things
# :
# :
# :
# Time to use a reaction rate coefficient:
reaction_coeffs.const() # Need appropriate arguments, etc
# Continue on...
# :
# :
# :
```
Be sure to include your module in the same directory as your execution script.

---

# Problem 3
Write a function that returns the **progress rate** for a reaction of the following form:
\begin{align}
  \nu_{A} A + \nu_{B} B \longrightarrow \nu_{C} C.
\end{align}
Order your concentration vector so that
\begin{align}
  \mathbf{x} =
  \begin{bmatrix}
    \left[A\right] \\
    \left[B\right] \\
    \left[C\right]
  \end{bmatrix}
\end{align}

Test your function with
\begin{align}
  \nu_{i}^{\prime} =
  \begin{bmatrix}
    2.0 \\
    1.0 \\
    0.0
  \end{bmatrix}
  \qquad
  \mathbf{x} =
  \begin{bmatrix}
    1.0 \\
    2.0 \\
    3.0
  \end{bmatrix}
  \qquad
  k = 10.
\end{align}

You must document your function and write some tests in addition to the one suggested.  You choose the additional tests, but you must have at least one doctest in addition to a suite of unit tests.

---
# Problem 4
Write a function that returns the **progress rate** for a system of reactions of the following form:
\begin{align}
  \nu_{11}^{\prime} A + \nu_{21}^{\prime} B \longrightarrow \nu_{31}^{\prime\prime} C \\
  \nu_{12}^{\prime} A + \nu_{32}^{\prime} C \longrightarrow \nu_{22}^{\prime\prime} B + \nu_{32}^{\prime\prime} C
\end{align}
Note that $\nu_{ij}^{\prime}$ represents the stoichiometric coefficient of reactant $i$ in reaction $j$ and $\nu_{ij}^{\prime\prime}$ represents the stoichiometric coefficient of product $i$ in reaction $j$.  Therefore, in this convention, I have ordered my vector of concentrations as
\begin{align}
  \mathbf{x} =
  \begin{bmatrix}
    \left[A\right] \\
    \left[B\right] \\
    \left[C\right]
  \end{bmatrix}.
\end{align}

Test your function with
\begin{align}
  \nu_{ij}^{\prime} =
  \begin{bmatrix}
    1.0 & 2.0 \\
    2.0 & 0.0 \\
    0.0 & 2.0
  \end{bmatrix}
  \qquad
  \nu_{ij}^{\prime\prime} =
  \begin{bmatrix}
    0.0 & 0.0 \\
    0.0 & 1.0 \\
    2.0 & 1.0
  \end{bmatrix}
  \qquad
  \mathbf{x} =
  \begin{bmatrix}
    1.0 \\
    2.0 \\
    1.0
  \end{bmatrix}
  \qquad
  k_{j} = 10, \quad j=1,2.
\end{align}

You must document your function and write some tests in addition to the one suggested.  You choose the additional tests, but you must have at least one doctest in addition to a suite of unit tests.

---
# Problem 5
Write a function that returns the **reaction rate** of a system of irreversible reactions of the form:
\begin{align}
  \nu_{11}^{\prime} A + \nu_{21}^{\prime} B &\longrightarrow \nu_{31}^{\prime\prime} C \\
  \nu_{32}^{\prime} C &\longrightarrow \nu_{12}^{\prime\prime} A + \nu_{22}^{\prime\prime} B
\end{align}

Once again $\nu_{ij}^{\prime}$ represents the stoichiometric coefficient of reactant $i$ in reaction $j$ and $\nu_{ij}^{\prime\prime}$ represents the stoichiometric coefficient of product $i$ in reaction $j$.  In this convention, I have ordered my vector of concentrations as
\begin{align}
  \mathbf{x} =
  \begin{bmatrix}
    \left[A\right] \\
    \left[B\right] \\
    \left[C\right]
  \end{bmatrix}
\end{align}

Test your function with
\begin{align}
  \nu_{ij}^{\prime} =
  \begin{bmatrix}
    1.0 & 0.0 \\
    2.0 & 0.0 \\
    0.0 & 2.0
  \end{bmatrix}
  \qquad
  \nu_{ij}^{\prime\prime} =
  \begin{bmatrix}
    0.0 & 1.0 \\
    0.0 & 2.0 \\
    1.0 & 0.0
  \end{bmatrix}
  \qquad
  \mathbf{x} =
  \begin{bmatrix}
    1.0 \\
    2.0 \\
    1.0
  \end{bmatrix}
  \qquad
  k_{j} = 10, \quad j = 1,2.
\end{align}

You must document your function and write some tests in addition to the one suggested.  You choose the additional tests, but you must have at least one doctest in addition to a suite of unit tests.

```python
%%file reaction_coeffs.py
from math import exp
def k_constant(k):
    return k
def k_arr(a,e,t):
    r=8.314
    if a<= 0:
        raise ValueError("a<0!")
    if t<= 0:
        raise ValueError("t<0!")

    return (a*exp(-e/(r*t)))
def k_mod_arr(a,e,t,b):
    r=8.314
    if a<= 0:
        raise ValueError("a<0!")
    if t<= 0:
        raise ValueError("t<0!")
    return (a*(t**b)*exp(-e/(r*t)))

```

    Writing reaction_coeffs.py

```python
%%file reaction1_rate.py
import numpy as np
import copy
def reaction_rate1(x,v,vv,k):
    """Returns reaction rate of chemical reactoins

    INPUTS
    =======
    x: array of float
        concentration of molecule species
    v: array of integers
        Coefficient of molecule species on the left side of equation
    vv: array of integers
        Coefficient of melecule species on the right side of equation
    kk: array of float
        reaction rate coefficient

    RETURNS
    ========
    roots: array of floats

    EXAMPLES
    =========
    >>> reaction_rate1(np.array([[1.0],[2.0],[1]]),np.array([[1,0],[2,0],[0,2]]),np.array([[0,1],[0,2],[1,0]]),[10,10])
    array([[-40.],
           [ 10.],
           [-80.],
           [ 20.],
           [ 40.],
           [-20.]])
    """
    if (any([kk<0 for kk in k])):
        raise ValueError("k<0")
    flag=True
    for j in range(v.shape[1]):
        if all([v[i][j]<=0 for i in range(v.shape[0])]):
            flag=False
            break
    if (flag==False):
        raise ValueError("no reactants")
    flag=True
    for j in range(vv.shape[1]):
        if all([vv[i][j]<=0 for i in range(vv.shape[0])]):
            flag=False
            break
    if (flag==False):
        raise ValueError("no products")
    if x.shape[0]!=v.shape[0] or v.shape!=vv.shape or v.shape[1]!=len(k):
        raise ValueError("dimensions not match")
    tmp=np.array([x[i][0]**v[i][j] for i in range(v.shape[0]) for j in range(v.shape[1])]).reshape(v.shape)
    w=copy.copy(k)
    for i in range(len(x)):
        for j in range(v.shape[1]):
            a=tmp[i][j]
            w[j]*=a

    return (np.transpose([np.array([w[j]*(vv[i][j]-v[i][j]) for i in range(len(x)) for j in range(v.shape[1])])]))

```

    Writing reaction1_rate.py

```python
%%file reaction1_test.py
import reaction1_rate as rr1
import numpy as np
def test_normal1():
    x=np.array([[1.0],[2.0],[1]])
    v_i_prime=np.array([[1,0],[2,0],[0,2]])
    v_i_prime_prime=np.array([[0,1],[0,2],[1,0]])
    k=[10,10]
    assert all(rr1.reaction_rate1(x,v_i_prime,v_i_prime_prime,k)==[[-40],[10],[-80],[20],[40],[-20]])

def test_nagative_k1():
    try:
        x=np.array([[1.0],[2.0],[1]])
        v_i_prime=np.array([[1,2],[2,0],[0,2]])
        v_i_prime_prime=np.array([[0,0],[0,1],[2,1]])
        k=[-10,10]
        rr1.reaction_rate1(x,v_i_prime,v_i_prime_prime,k)
    except ValueError as err:
        assert(True)

def test_reactants1():
    try:
        x=np.array([[1.0],[2.0],[1]])
        v_i_prime=np.array([[0,2],[0,0],[0,2]])
        v_i_prime_prime=np.array([[0,0],[0,1],[2,1]])
        k=[10,10]
        rr1.reaction_rate1(x,v_i_prime,v_i_prime_prime,k)
    except ValueError as err:
        assert(True)

def test_products1():
    try:
        x=np.array([[1.0],[2.0],[1]])
        v_i_prime=np.array([[1,2],[2,0],[0,2]])
        v_i_prime_prime=np.array([[0,0],[0,0],[2,0]])
        k=[10,10]
        rr1.reaction_rate1(x,v_i_prime,v_i_prime_prime,k)
    except ValueError as err:
        assert(True)
def test_dimensions1():
    try:
        x=np.array([[1.0],[2.0]])
        v_i_prime=np.array([[1,2],[2,0],[0,2]])
        v_i_prime_prime=np.array([[0,0],[0,0],[2,0]])
        k=[10,10]
        rr1.reaction_rate1(x,v_i_prime,v_i_prime_prime,k)
    except ValueError as err:
        assert(True)
```

    Writing reaction1_test.py

```python
import doctest
doctest.testmod(verbose=True)
```

    1 items had no tests:
        __main__
    0 tests in 1 items.
    0 passed and 0 failed.
    Test passed.

    TestResults(failed=0, attempted=0)

```python
!pytest
```

    ============================= test session starts ==============================
    platform darwin -- Python 3.6.1, pytest-3.0.7, py-1.4.33, pluggy-0.4.0
    rootdir: /Users/zhaiyi/cs207_yi_zhai/homeworks/HW5, inifile:
    plugins: cov-2.5.1
    collected 5 items

    reaction1_test.py .....

    =========================== 5 passed in 0.26 seconds ===========================

```bash
%%bash
pwd
```

    /Users/zhaiyi/cs207_yi_zhai/homeworks/HW5

```python
!pytest --cov
```

    ============================= test session starts ==============================
    platform darwin -- Python 3.6.1, pytest-3.0.7, py-1.4.33, pluggy-0.4.0
    rootdir: /Users/zhaiyi/cs207_yi_zhai/homeworks/HW5, inifile:
    plugins: cov-2.5.1
    collected 5 items

    reaction1_test.py .....

    ---------- coverage: platform darwin, python 3.6.1-final-0 -----------
    Name                Stmts   Miss  Cover
    ---------------------------------------
    reaction1_rate.py      28      1    96%
    reaction1_test.py      44      0   100%
    ---------------------------------------
    TOTAL                  72      1    99%

    =========================== 5 passed in 0.27 seconds ===========================

---
# Problem 6
Put parts 3, 4, and 5 in a module called `chemkin`.

Next, pretend you're a client who needs to compute the reaction rates at three different temperatures ($T = \left\{750, 1500, 2500\right\}$) of the following system of irreversible reactions:
\begin{align}
  2H_{2} + O_{2} \longrightarrow 2OH + H_{2} \\
  OH + HO_{2} \longrightarrow H_{2}O + O_{2} \\
  H_{2}O + O_{2} \longrightarrow HO_{2} + OH
\end{align}

The client also happens to know that reaction 1 is a modified Arrhenius reaction with $A_{1} = 10^{8}$, $b_{1} = 0.5$, $E_{1} = 5\times 10^{4}$, reaction 2 has a constant reaction rate parameter $k = 10^{4}$, and reaction 3 is an Arrhenius reaction with $A_{3} = 10^{7}$ and $E_{3} = 10^{4}$.

You should write a script that imports your `chemkin` module and returns the reaction rates of the species at each temperature of interest given the following species concentrations:

\begin{align}
  \mathbf{x} =
  \begin{bmatrix}
    H_{2}  \\
    O_{2}  \\
    OH     \\
    HO_{2} \\
    H_{2}O
  \end{bmatrix} =
  \begin{bmatrix}
    2.0 \\
    1.0 \\
    0.5 \\
    1.0 \\
    1.0
  \end{bmatrix}
\end{align}

You may assume that these are elementary reactions.

```python

```

---
# Problem 7
Get together with your project team, form a GitHub organization (with a descriptive team name), and give the teaching staff access.  You can have has many repositories as you like within your organization.  However, we will grade the repository called **`cs207-FinalProject`**.

Within the `cs207-FinalProject` repo, you must set up Travis CI and Coveralls.  Make sure your `README.md` file includes badges indicating how many tests are passing and the coverage of your code.


\title{Bitwise Behavior in myHDL: Selecting, Shifting, Concatenation, Slicing}
\author{Steven K Armour}
\maketitle

Table of Contents

1  References

2  Libraries and Helper functions

3  myHDL Bit Indexing

3.1  Expected Indexing Selection Behavior

3.2  Attempted Selection with Python Negative Warping

3.3  Selecting above the MSB

3.4  Bit Selection of Signal

3.5  myHDL Bit Selection Demo

3.5.1  Bit Assignment

3.6  myHDL Testing

3.7  Verilog Conversion

3.7.1  Verilog Conversion Error

3.8  VHDL Conversion

3.8.1  VHDL Conversion Issue

3.9  myHDL to Verilog/VHDL Testbench

3.9.1  Verilog Testbench

3.9.1.1  Verilog Testbench Conversion Issue

3.9.2  VHDL Testbench

3.9.2.1  VHDL Testbench Conversion Issue

<a href="#myHDL-shift-(<</>>)-behavior" data-toc-modified-id="myHDL-shift-(<</>>)-behavior-4">4  myHDL shift (<</>>) behavior

<a href="#Left-Shift-(<<)" data-toc-modified-id="Left-Shift-(<<)-4.1">4.1  Left Shift (<<)

4.1.1  Left Shifting with intbv

4.1.2  Left Shifting with signed intbv

4.1.3  Left Shifting with modbv

>)-4.2">4.2  Right Shift (>>)

4.2.1  Right Shifting with intbv

4.2.2  Right Shifting with signed intbv

4.2.3  Right Shifting with modbv

4.3  myHDL Shifting Demo Module

4.4  myHDL Testing

4.5  Verilog Conversion

4.6  VHDL Conversion

4.7  myHDL to Verilog/VHDL Testbench

4.7.1  Verilog Testbench

4.7.1.1  Verilog Testbench Conversion Issue

4.7.2  VHDL Testbench

4.7.2.1  VHDL Testbench Conversion Issue

5  myHDL concat  behavior

5.1  myHDL concat Demo

5.2  myHDL Testing

5.3  Verilog Conversion

5.4  VHDL Conversion

5.5  myHDL to Verilog/VHDL Testbench

5.5.1  Verilog Testbench

5.5.2  VHDL Testbench

5.5.2.1  VHDL Testbench Conversion Issue

6  myHDL Bitslicing Behavior

6.1  Slicing intbv

6.2  Slicing Signed intbv

6.3  Slicing modbv

6.4  myHDL BitSlicing Demo Module

6.5  myHDL Testing

6.6  Verilog Conversion

6.6.1  Verilog Conversion Issue

6.7  VHDL Conversion

6.7.1  VHDL Conversion Issue

6.8  myHDL to Verilog/VHDL Testbench

6.8.1  Verilog Testbench

6.8.2  VHDL Testbench

# References

@misc{myhdl_2018,
title={Hardware-oriented types  MyHDL 0.10 documentation},
url={http://docs.myhdl.org/en/stable/manual/hwtypes.html},
journal={Docs.myhdl.org},
author={myHDL},
year={2018}
},

@misc{vandenbout_2018,
title={pygmyhdl 0.0.3 documentation},
url={https://xesscorp.github.io/pygmyhdl/docs/_build/singlehtml/index.html},
journal={Xesscorp.github.io},
author={Vandenbout, Dave},
year={2018}
}

# 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 Aug 29 16:10:23 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
```

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

# myHDL Bit Indexing
Bit Indexing is the act of selecting or assigning one of the bits in a Bit Vector

## Expected Indexing Selection Behavior

```python
TV=intbv(-93)[8:].signed()
print(f'Value:{int(TV)}, Binary {bin(TV)}')
```

    Value:-93, Binary 10100011

```python
for i in range(len(TV)):
    print(f'Bit from LSB: {i}, Selected Bit: {int(TV[i])}')
```

    Bit from LSB: 0, Selected Bit: 1
    Bit from LSB: 1, Selected Bit: 1
    Bit from LSB: 2, Selected Bit: 0
    Bit from LSB: 3, Selected Bit: 0
    Bit from LSB: 4, Selected Bit: 0
    Bit from LSB: 5, Selected Bit: 1
    Bit from LSB: 6, Selected Bit: 0
    Bit from LSB: 7, Selected Bit: 1

which shows that when selecting a single bit from a BitVector that selection [0] is the Least Significant Bit (LSB) (inclusive behavior) while for the Most Significant Bit (MSB) will be the index of the BitVector length -1 (noninclusive behavior)

## Attempted Selection with Python Negative Warping

```python
try:
    TV[-1]
except ValueError:
    print("ValueError: negative shift count")
```

    ValueError: negative shift count

This means that negative indexing using python's list selection wrap around is NOT implemented in a myHDL `intbv`

```python
TV=modbv(-93)[8:].signed()
print(f'Value:{int(TV)}, Binary {bin(TV)}')
try:
    TV[-1]
except ValueError:
    print("ValueError: negative shift count")
```

    Value:-93, Binary 10100011
    ValueError: negative shift count

nor is the negative wrapping supported by the use of the `modbv`

## Selecting above the MSB

```python
TV=intbv(93)[8:]
TV_S=intbv(-93)[8:].signed()
TV_M=modbv(-93)[8:].signed()
print(f'`intbv`:Value:{int(TV)}, Binary {bin(TV)}, [8]:{int(TV[8])}, [9]:{int(TV[9])}')
print(f'`intbv signed`:Value:{int(TV_S)}, Binary {bin(TV_S)}, [8]:{int(TV_S[8])}, [9]:{int(TV_S[9])}')
print(f'`modbv`:Value:{int(TV_M)}, Binary {bin(TV_M)}, [8]:{int(TV_M[8])}, [9]:{int(TV_M[9])}')
```

    `intbv`:Value:93, Binary 1011101, [8]:0, [9]:0
    `intbv signed`:Value:-93, Binary 10100011, [8]:1, [9]:1
    `modbv`:Value:-93, Binary 10100011, [8]:1, [9]:1

Thus selecting above the MSB will generate a `0` if the Bit Vector is not signed where as selecting above the MSB for a signed bit will produce a `1`.

## Bit Selection of `Signal`

```python
TV=Signal(intbv(93)[8:])
```

```python
TV[0], TV(0), TV[9], TV(9)
```

    (True, Signal(True), False, Signal(False))

The difference is that outside of a generator, bit selection of a `signal` using `[]` only returns a value and not a signal that is only returned using `()`. This is important to know since only a `Signal` can be converted to registers/wires in the conversion from myHDL to Verilog/VHDL

## myHDL Bit Selection Demo

```python
@block
def BitSelectDemo(Index, Res, SignRes):
    """
    Bit Selection Demo

    Input:
        Index(4BitVec): value for selection from internal refrances
    Output:
        Res(8BitVec): BitVector with Bit Location set from `Index` from
            refrance internal 8Bit `intbv` with value 93
        SignRes(8BitVec Signed): signed BitVector with Bit Location set from `Index` from
            refrance internal signed 8Bit `intbv` with value -93
    """
    Ref=Signal(intbv(93)[8:])
    RefS=Signal(intbv(-93)[8:].signed())
    @always_comb
    def logic():
        Res.next[Index]=Ref[Index]
        SignRes.next[Index]=RefS[Index]

    return instances()
```

### Bit Assignment
Note: that in the above the module also shows how to perform bit selection assignment. The output signal `Res` or `SignRes`  is assigned a value from the References at position `Index` but then the bit from the references is set to position `Index` in the outputs. Notice that the syntax is
```
Variable.next[index]=
```
The same structure is also used in setting bit slices so that for a big slice assignment is
```
Variable.next[MSB:LSB]=
```

## myHDL Testing

```python
Peeker.clear()
Index=Signal(intbv(0)[4:]); Peeker(Index, 'Index')
Res=Signal(intbv(0)[8:]); Peeker(Res, 'Res')
SignRes=Signal(intbv(0)[8:].signed()); Peeker(SignRes, 'SignRes')

DUT=BitSelectDemo(Index, Res, SignRes)

def BitSelectDemo_TB():
    """
    myHDL only Testbench
    """
    @instance
    def stimules():
        for i in range(7):
            Index.next=i
            yield delay(1)

        raise StopSimulation()

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

Note that if the `for` loop range was increased beyond 7 an error would be triggered.

```python
Peeker.to_wavedrom('Index', 'Res', 'SignRes')
```

```python
BitSelectDemoData=Peeker.to_dataframe()
BitSelectDemoData['Res Bin']=BitSelectDemoData['Res'].apply(lambda Row: bin(Row, 8), 1)
BitSelectDemoData['SignRes Bin']=BitSelectDemoData['SignRes'].apply(lambda Row: bin(Row, 8), 1)
BitSelectDemoData=BitSelectDemoData[['Index', 'Res', 'Res Bin', 'SignRes', 'SignRes Bin']]
BitSelectDemoData
```

      Index
      Res
      Res Bin
      SignRes
      SignRes Bin

      0
      0
      1
      00000001
      1
      00000001

      1
      1
      1
      00000001
      3
      00000011

      2
      2
      5
      00000101
      3
      00000011

      3
      3
      13
      00001101
      3
      00000011

      4
      4
      29
      00011101
      3
      00000011

      5
      5
      29
      00011101
      35
      00100011

      6
      6
      93
      01011101
      35
      00100011

## Verilog Conversion

### Verilog Conversion Error
Line 24 in the conversion of `BitSelectDemo` to `BitSelectDemo.v` is incorrect. The myHDL source line is
```
RefS=Signal(intbv(-93)[8:].signed())
```
but the converted line becomes
```
assign RefS = 8'd-93;
```
but this needs to instead become
```
assign RefS = -8'd93;

```
in `BitSelectDemo.v`

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

    ***Verilog modual from BitSelectDemo.v***

     // File: BitSelectDemo.v
    // Generated by MyHDL 0.10
    // Date: Wed Aug 29 14:27:57 2018

    `timescale 1ns/10ps

    module BitSelectDemo (
        Index,
        Res,
        SignRes
    );
    // Bit Selection Demo
    //
    // Input:
    //     Index(4BitVec): value for selection from internal refrances
    // Output:
    //     Res(8BitVec): BitVector with Bit Location set from `Index` from
    //         refrance internal 8Bit `intbv` with value 93
    //     SignRes(8BitVec Signed): signed BitVector with Bit Location set from `Index` from
    //         refrance internal signed 8Bit `intbv` with value -93

    input [3:0] Index;
    output [7:0] Res;
    reg [7:0] Res;
    output signed [7:0] SignRes;
    reg signed [7:0] SignRes;

    wire [7:0] RefS;
    wire [7:0] Ref;

    assign RefS = 8'd-93;
    assign Ref = 8'd93;

    always @(Index, RefS, Ref) begin: BITSELECTDEMO_LOGIC
        Res[Index] = Ref[Index];
        SignRes[Index] = RefS[Index];
    end

    endmodule

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

\begin{figure}
\centerline{\includegraphics[width=10cm]{BitSelectDemo_v_RTL.png}}
\caption{\label{fig:BSDVRTL} BitSelectDemo Verilog RTL schematic with corrected errors; Xilinx Vivado 2017.4}
\end{figure}

\begin{figure}
\centerline{\includegraphics[width=10cm]{BitSelectDemo_v_SYN.png}}
\caption{\label{fig:BSDVHDSYN} BitSelectDemo Verilog Synthesized Schematic with corrected errors; Xilinx Vivado 2017.4}
\end{figure}

## VHDL Conversion

### VHDL Conversion Issue
The resulting `BitSelectDemo.vhd` from `BitSelectDemo` contains a line that calls from a libary `work.pck_myhdl_010.all` that is created when this file is ran. Make sure to import this file along with `BitSelectDemo.vhd`.

```python
DUT.convert('VHDL')
VHDLTextReader('BitSelectDemo');
```

    ***VHDL modual from BitSelectDemo.vhd***

     -- File: BitSelectDemo.vhd
    -- Generated by MyHDL 0.10
    -- Date: Wed Aug 29 14:27:57 2018

    library IEEE;
    use IEEE.std_logic_1164.all;
    use IEEE.numeric_std.all;
    use std.textio.all;

    use work.pck_myhdl_010.all;

    entity BitSelectDemo is
        port (
            Index: in unsigned(3 downto 0);
            Res: out unsigned(7 downto 0);
            SignRes: out signed (7 downto 0)
        );
    end entity BitSelectDemo;
    -- Bit Selection Demo
    --
    -- Input:
    --     Index(4BitVec): value for selection from internal refrances
    -- Output:
    --     Res(8BitVec): BitVector with Bit Location set from `Index` from
    --         refrance internal 8Bit `intbv` with value 93
    --     SignRes(8BitVec Signed): signed BitVector with Bit Location set from `Index` from
    --         refrance internal signed 8Bit `intbv` with value -93

    architecture MyHDL of BitSelectDemo is

    signal RefS: signed (7 downto 0);
    signal Ref: unsigned(7 downto 0);

    begin

    RefS <= to_signed(-93, 8);
    Ref <= to_unsigned(93, 8);

    BITSELECTDEMO_LOGIC: process (Index, RefS, Ref) is
    begin
        Res(to_integer(Index)) <= Ref(to_integer(Index));
        SignRes(to_integer(Index)) <= RefS(to_integer(Index));
    end process BITSELECTDEMO_LOGIC;

    end architecture MyHDL;

    /home/iridium/anaconda3/lib/python3.6/site-packages/myhdl/conversion/_toVHDL.py:453: ToVHDLWarning: Signal is not driven: RefS
      category=ToVHDLWarning
    /home/iridium/anaconda3/lib/python3.6/site-packages/myhdl/conversion/_toVHDL.py:453: ToVHDLWarning: Signal is not driven: Ref
      category=ToVHDLWarning

\begin{figure}
\centerline{\includegraphics[width=10cm]{BitSelectDemo_vhd_RTL.png}}
\caption{\label{fig:BSDVHDRTL} BitSelectDemo VHDL RTL schematic with corrected errors; Xilinx Vivado 2017.4}
\end{figure}

\begin{figure}
\centerline{\includegraphics[width=10cm]{BitSelectDemo_vhd_SYN.png}}
\caption{\label{fig:BSDVHDSYN} BitSelectDemo VHDL Synthesized Schematic with corrected errrors; Xilinx Vivado 2017.4}
\end{figure}

## myHDL to Verilog/VHDL Testbench

```python
@block
def BitSelectDemo_TB_V_VHDL():
    """
    myHDL -> Verilog/VHDL Testbench for `BitSelectDemo`
    """

    Index=Signal(intbv(0)[4:])
    Res=Signal(intbv(0)[8:])
    SignRes=Signal(intbv(0)[8:].signed())

    @always_comb
    def print_data():
        print(Index, Res, SignRes)

    DUT=BitSelectDemo(Index, Res, SignRes)

    @instance
    def stimules():
        for i in range(7):
            Index.next=i
            yield delay(1)

        raise StopSimulation()

    return instances()
TB=BitSelectDemo_TB_V_VHDL()
```

### Verilog Testbench
#### Verilog Testbench Conversion Issue
This testbench will work after
```
assign RefS = 8'd-93;
```
is changed to
```
assign RefS = -8'd93;
```

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

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

     // File: BitSelectDemo_TB_V_VHDL.v
    // Generated by MyHDL 0.10
    // Date: Wed Aug 29 14:27:58 2018

    `timescale 1ns/10ps

    module BitSelectDemo_TB_V_VHDL (

    );
    // myHDL -> Verilog/VHDL Testbench

    reg [3:0] Index = 0;
    reg [7:0] Res = 0;
    reg signed [7:0] SignRes = 0;
    wire [7:0] BitSelectDemo0_0_RefS;
    wire [7:0] BitSelectDemo0_0_Ref;

    assign BitSelectDemo0_0_RefS = 8'd-93;
    assign BitSelectDemo0_0_Ref = 8'd93;

    always @(SignRes, Index, Res) begin: BITSELECTDEMO_TB_V_VHDL_PRINT_DATA
        $write("%h", Index);
        $write(" ");
        $write("%h", Res);
        $write(" ");
        $write("%h", SignRes);
        $write("\n");
    end

    always @(Index, BitSelectDemo0_0_RefS, BitSelectDemo0_0_Ref) begin: BITSELECTDEMO_TB_V_VHDL_BITSELECTDEMO0_0_LOGIC
        Res[Index] = BitSelectDemo0_0_Ref[Index];
        SignRes[Index] = BitSelectDemo0_0_RefS[Index];
    end

    initial begin: BITSELECTDEMO_TB_V_VHDL_STIMULES
        integer i;
        for (i=0; i<7; i=i+1) begin
            Index <= i;
            # 1;
        end
        $finish;
    end

    endmodule

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

### VHDL Testbench
#### VHDL Testbench Conversion Issue
This Testbench is not working in Vivado

```python
TB.convert(hdl="VHDL", initial_values=True)
VHDLTextReader('BitSelectDemo_TB_V_VHDL');
```

    ***VHDL modual from BitSelectDemo_TB_V_VHDL.vhd***

     -- File: BitSelectDemo_TB_V_VHDL.vhd
    -- Generated by MyHDL 0.10
    -- Date: Wed Aug 29 14:27:58 2018

    library IEEE;
    use IEEE.std_logic_1164.all;
    use IEEE.numeric_std.all;
    use std.textio.all;

    use work.pck_myhdl_010.all;

    entity BitSelectDemo_TB_V_VHDL is
    end entity BitSelectDemo_TB_V_VHDL;
    -- myHDL -> Verilog/VHDL Testbench

    architecture MyHDL of BitSelectDemo_TB_V_VHDL is

    signal Index: unsigned(3 downto 0) := 4X"0";
    signal Res: unsigned(7 downto 0) := 8X"00";
    signal SignRes: signed (7 downto 0) := 8X"00";
    signal BitSelectDemo0_0_RefS: signed (7 downto 0);
    signal BitSelectDemo0_0_Ref: unsigned(7 downto 0);

    begin

    BitSelectDemo0_0_RefS <= to_signed(-93, 8);
    BitSelectDemo0_0_Ref <= to_unsigned(93, 8);

    BITSELECTDEMO_TB_V_VHDL_PRINT_DATA: process (SignRes, Index, Res) is
        variable L: line;
    begin
        write(L, to_hstring(Index));
        write(L, string'(" "));
        write(L, to_hstring(Res));
        write(L, string'(" "));
        write(L, to_hstring(unsigned(SignRes)));
        writeline(output, L);
    end process BITSELECTDEMO_TB_V_VHDL_PRINT_DATA;

    BITSELECTDEMO_TB_V_VHDL_BITSELECTDEMO0_0_LOGIC: process (Index, BitSelectDemo0_0_RefS, BitSelectDemo0_0_Ref) is
    begin
        Res(to_integer(Index)) <= BitSelectDemo0_0_Ref(to_integer(Index));
        SignRes(to_integer(Index)) <= BitSelectDemo0_0_RefS(to_integer(Index));
    end process BITSELECTDEMO_TB_V_VHDL_BITSELECTDEMO0_0_LOGIC;

    BITSELECTDEMO_TB_V_VHDL_STIMULES: process is
    begin
        for i in 0 to 7-1 loop
            Index <= to_unsigned(i, 4);
            wait for 1 * 1 ns;
        end loop;
        assert False report "End of Simulation" severity Failure;
        wait;
    end process BITSELECTDEMO_TB_V_VHDL_STIMULES;

    end architecture MyHDL;

    /home/iridium/anaconda3/lib/python3.6/site-packages/myhdl/conversion/_toVHDL.py:453: ToVHDLWarning: Signal is not driven: BitSelectDemo0_0_RefS
      category=ToVHDLWarning
    /home/iridium/anaconda3/lib/python3.6/site-packages/myhdl/conversion/_toVHDL.py:453: ToVHDLWarning: Signal is not driven: BitSelectDemo0_0_Ref
      category=ToVHDLWarning

# myHDL shift (`<<`/`>>`) behavior

## Left Shift (<<)

### Left Shifting with `intbv`

```python
#Left Shift test with intbv
#intialize
TV=intbv(52)[8:]
print(TV, bin(TV, 8))
#demenstrate left shifting with intbv
for i in range(8):
    LSRes=TV<<i
    print(f'Left Shift<<{i}; Binary: {bin(LSRes)}, BitLen: {len(bin(LSRes))}, Value:{LSRes}')
```

    34 00110100
    Left Shift<<0; Binary: 110100, BitLen: 6, Value:34
    Left Shift<<1; Binary: 1101000, BitLen: 7, Value:68
    Left Shift<<2; Binary: 11010000, BitLen: 8, Value:d0
    Left Shift<<3; Binary: 110100000, BitLen: 9, Value:1a0
    Left Shift<<4; Binary: 1101000000, BitLen: 10, Value:340
    Left Shift<<5; Binary: 11010000000, BitLen: 11, Value:680
    Left Shift<<6; Binary: 110100000000, BitLen: 12, Value:d00
    Left Shift<<7; Binary: 1101000000000, BitLen: 13, Value:1a00

### Left Shifting with signed `intbv`

```python
#Left Shift test with intbv signed
#intialize
TV=intbv(-52)[8:].signed()
print(TV, bin(TV, 8))
#demenstrate left shifting with intbv signed
for i in range(8):
    LSRes=(TV<<i).signed()
    print(f'Left Shift<<{i}; Binary: {bin(LSRes)}, BitLen: {len(bin(LSRes))}, Value:{LSRes}')
```

    cc 11001100
    Left Shift<<0; Binary: 1001100, BitLen: 7, Value:-34
    Left Shift<<1; Binary: 10011000, BitLen: 8, Value:-68
    Left Shift<<2; Binary: 100110000, BitLen: 9, Value:-d0
    Left Shift<<3; Binary: 1001100000, BitLen: 10, Value:-1a0
    Left Shift<<4; Binary: 10011000000, BitLen: 11, Value:-340
    Left Shift<<5; Binary: 100110000000, BitLen: 12, Value:-680
    Left Shift<<6; Binary: 1001100000000, BitLen: 13, Value:-d00
    Left Shift<<7; Binary: 10011000000000, BitLen: 14, Value:-1a00

### Left Shifting with `modbv`

```python
#Left Shift test with modbv
#intialize
TV=modbv(52)[8:]
print(TV, bin(TV, 8))
#demenstrate left shifting with modbv
for i in range(8):
    LSRes=(TV<<i).signed()
    print(f'Left Shift<<{i}; Binary: {bin(LSRes)}, BitLen: {len(bin(LSRes))}, Value:{LSRes}')
```

    34 00110100
    Left Shift<<0; Binary: 110100, BitLen: 6, Value:34
    Left Shift<<1; Binary: 1101000, BitLen: 7, Value:68
    Left Shift<<2; Binary: 11010000, BitLen: 8, Value:d0
    Left Shift<<3; Binary: 110100000, BitLen: 9, Value:1a0
    Left Shift<<4; Binary: 1101000000, BitLen: 10, Value:340
    Left Shift<<5; Binary: 11010000000, BitLen: 11, Value:680
    Left Shift<<6; Binary: 110100000000, BitLen: 12, Value:d00
    Left Shift<<7; Binary: 1101000000000, BitLen: 13, Value:1a00

As can be seen, Left shifting tacks on a number of zeros equivalent to the shift increment to the end of the binary expression for the value. This then increases the size of the needed register that the resulting value needs to set into for each left shift that does not undergo right bit cutoff

## Right Shift (`>>`)

### Right Shifting with `intbv`

```python
#Right Shift test with intbv
#intialize
TV=intbv(52)[8:]
print(TV, bin(TV, 8))
#demenstrate left shifting with intbv
for i in range(8):
    LSRes=TV>>i
    print(f'Right Shift>>{i}; Binary: {bin(LSRes)}, BitLen: {len(bin(LSRes))}, Value:{LSRes}')
```

    34 00110100
    Right Shift>>0; Binary: 110100, BitLen: 6, Value:34
    Right Shift>>1; Binary: 11010, BitLen: 5, Value:1a
    Right Shift>>2; Binary: 1101, BitLen: 4, Value:d
    Right Shift>>3; Binary: 110, BitLen: 3, Value:6
    Right Shift>>4; Binary: 11, BitLen: 2, Value:3
    Right Shift>>5; Binary: 1, BitLen: 1, Value:1
    Right Shift>>6; Binary: 0, BitLen: 1, Value:0
    Right Shift>>7; Binary: 0, BitLen: 1, Value:0

### Right Shifting with signed `intbv`

```python
#Right Shift test with intbv signed
#intialize
TV=intbv(-52)[8:].signed()
print(TV, bin(TV, 8))
#demenstrate left shifting with intbv signed
for i in range(8):
    LSRes=(TV>>i)
    print(f'Right Shift>>{i}; Binary: {bin(LSRes)}, BitLen: {len(bin(LSRes))}, Value:{LSRes}')
```

    cc 11001100
    Right Shift>>0; Binary: 1001100, BitLen: 7, Value:-34
    Right Shift>>1; Binary: 100110, BitLen: 6, Value:-1a
    Right Shift>>2; Binary: 10011, BitLen: 5, Value:-d
    Right Shift>>3; Binary: 1001, BitLen: 4, Value:-7
    Right Shift>>4; Binary: 100, BitLen: 3, Value:-4
    Right Shift>>5; Binary: 10, BitLen: 2, Value:-2
    Right Shift>>6; Binary: 1, BitLen: 1, Value:-1
    Right Shift>>7; Binary: 1, BitLen: 1, Value:-1

### Right Shifting with `modbv`

```python
#Right Shift test with modbv
#intialize
TV=modbv(52)[8:]
print(TV, bin(TV, 8))
#demenstrate left shifting with modbv
for i in range(8):
    LSRes=(TV>>i)
    print(f'Right Shift>>{i}; Binary: {bin(LSRes)}, BitLen: {len(bin(LSRes))}, Value:{LSRes}')
```

    34 00110100
    Right Shift>>0; Binary: 110100, BitLen: 6, Value:34
    Right Shift>>1; Binary: 11010, BitLen: 5, Value:1a
    Right Shift>>2; Binary: 1101, BitLen: 4, Value:d
    Right Shift>>3; Binary: 110, BitLen: 3, Value:6
    Right Shift>>4; Binary: 11, BitLen: 2, Value:3
    Right Shift>>5; Binary: 1, BitLen: 1, Value:1
    Right Shift>>6; Binary: 0, BitLen: 1, Value:0
    Right Shift>>7; Binary: 0, BitLen: 1, Value:0

As can be seen, the right shift moves values (shifts) to the right by the shift increment while preserving the length of the register that is being shifted. While this means that overflow is not going to be in encountered. Right shifting trades that vulnerability for information loss as any information carried in the leftmost bits gets lost as it is shifted right beyond of the length of the register

## myHDL Shifting Demo Module

```python
@block
def ShiftingDemo(ShiftVal, RSRes, LSRes):
    """
    Module to Demo Shifting Behavior in myHDL refrance value
    -55 8Bit

    Input:
        ShiftVal(4BitVec): shift amount, for this demo to not
            use values greater then 7
    Output:
        RSRes(8BitVec Signed): output of Right Shifting
        LSRes (15BitVec Signed): output of Left Shifting
    """
    RefVal=Signal(intbv(-55)[8:].signed())
    @always_comb
    def logic():
        RSRes.next=RefVal>>ShiftVal
        LSRes.next=RefVal<<ShiftVal
    return instances()
```

## myHDL Testing

```python
Peeker.clear()
ShiftVal=Signal(intbv()[4:]); Peeker(ShiftVal, 'ShiftVal')
RSRes=Signal(intbv()[8:].signed()); Peeker(RSRes, 'RSRes')
LSRes=Signal(intbv()[15:].signed()); Peeker(LSRes, 'LSRes')

DUT=ShiftingDemo(ShiftVal, RSRes, LSRes)

def ShiftingDemo_TB():
    """
    myHDL only Testbench for `ShiftingDemo`
    """

    @instance
    def stimules():
        for i in range(8):
            ShiftVal.next=i
            yield delay(1)

        raise StopSimulation()

    return instances()

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

```python
Peeker.to_wavedrom('ShiftVal', 'LSRes', 'RSRes');
```

```python
Peeker.to_dataframe()[['ShiftVal', 'LSRes', 'RSRes']]
```

      ShiftVal
      LSRes
      RSRes

      0
      0
      -55
      -55

      1
      1
      -110
      -28

      2
      2
      -220
      -14

      3
      3
      -440
      -7

      4
      4
      -880
      -4

      5
      5
      -1760
      -2

      6
      6
      -3520
      -1

      7
      7
      -7040
      -1

## Verilog Conversion

Unfortunately this is an unsynthesizable module as is due
```
assign RefVal = 8'd-55;
```
needing to be changed to
```
assign RefVal = -8'd55;
```
after wich the module is synthesizable

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

    ***Verilog modual from ShiftingDemo.v***

     // File: ShiftingDemo.v
    // Generated by MyHDL 0.10
    // Date: Wed Aug 29 14:28:01 2018

    `timescale 1ns/10ps

    module ShiftingDemo (
        ShiftVal,
        RSRes,
        LSRes
    );
    // Module to Demo Shifting Behavior in myHDL refrance value
    // -55 8Bit
    //
    // Input:
    //     ShiftVal(4BitVec): shift amount, for this demo to not
    //         use values greater then 7
    // Output:
    //     RSRes(8BitVec Signed): output of Right Shifting
    //     LSRes (15BitVec Signed): output of Left Shifting

    input [3:0] ShiftVal;
    output signed [7:0] RSRes;
    wire signed [7:0] RSRes;
    output signed [14:0] LSRes;
    wire signed [14:0] LSRes;

    wire [7:0] RefVal;

    assign RefVal = 8'd-55;

    assign RSRes = $signed(RefVal >>> $signed({1'b0, ShiftVal}));
    assign LSRes = (RefVal << $signed({1'b0, ShiftVal}));

    endmodule

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

\begin{figure}
\centerline{\includegraphics[width=10cm]{ShiftingDemo_v_RTL.png}}
\caption{\label{fig:SDVRTL} ShiftingDemo Verilog RTL schematic with corrected errors; Xilinx Vivado 2017.4}
\end{figure}

\begin{figure}
\centerline{\includegraphics[width=10cm]{ShiftingDemo_v_SYN.png}}
\caption{\label{fig:SDVSYN} ShiftingDemo Verilog Synthesized Schematic with corrected errors; Xilinx Vivado 2017.4}
\end{figure}

## VHDL Conversion

```python
DUT.convert(hdl='VHDL')
VHDLTextReader('ShiftingDemo');
```

    ***VHDL modual from ShiftingDemo.vhd***

     -- File: ShiftingDemo.vhd
    -- Generated by MyHDL 0.10
    -- Date: Wed Aug 29 14:28:01 2018

    library IEEE;
    use IEEE.std_logic_1164.all;
    use IEEE.numeric_std.all;
    use std.textio.all;

    use work.pck_myhdl_010.all;

    entity ShiftingDemo is
        port (
            ShiftVal: in unsigned(3 downto 0);
            RSRes: out signed (7 downto 0);
            LSRes: out signed (14 downto 0)
        );
    end entity ShiftingDemo;
    -- Module to Demo Shifting Behavior in myHDL refrance value
    -- -55 8Bit
    --
    -- Input:
    --     ShiftVal(4BitVec): shift amount, for this demo to not
    --         use values greater then 7
    -- Output:
    --     RSRes(8BitVec Signed): output of Right Shifting
    --     LSRes (15BitVec Signed): output of Left Shifting

    architecture MyHDL of ShiftingDemo is

    signal RefVal: signed (7 downto 0);

    begin

    RefVal <= to_signed(-55, 8);

    RSRes <= shift_right(RefVal, to_integer(ShiftVal));
    LSRes <= shift_left(resize(RefVal, 15), to_integer(ShiftVal));

    end architecture MyHDL;

    /home/iridium/anaconda3/lib/python3.6/site-packages/myhdl/conversion/_toVHDL.py:453: ToVHDLWarning: Signal is not driven: RefVal
      category=ToVHDLWarning

\begin{figure}
\centerline{\includegraphics[width=10cm]{ShiftingDemo_vhd_RTL.png}}
\caption{\label{fig:SDVHDRTL} ShiftingDemo VHDL RTL schematic with corrected errors; Xilinx Vivado 2017.4}
\end{figure}

\begin{figure}
\centerline{\includegraphics[width=10cm]{ShiftingDemo_vhd_SYN.png}}
\caption{\label{fig:SDVHDSYN} ShiftingDemo VHDL Synthesized Schematic with corrected errors; Xilinx Vivado 2017.4}
\end{figure}

## myHDL to Verilog/VHDL Testbench

```python
@block
def ShiftingDemo_TB_V_VHDL():
    """
    myHDL -> verilog/VHDL testbench for `ShiftingDemo`
    """

    ShiftVal=Signal(intbv()[4:])
    RSRes=Signal(intbv()[8:].signed())
    LSRes=Signal(intbv()[15:].signed())

    @always_comb
    def print_data():
        print(ShiftVal, RSRes, LSRes)

    DUT=ShiftingDemo(ShiftVal, RSRes, LSRes)

    @instance
    def stimules():
        for i in range(8):
            ShiftVal.next=i
            yield delay(1)

        raise StopSimulation()

    return instances()

TB=ShiftingDemo_TB_V_VHDL()
```

### Verilog Testbench
#### Verilog Testbench Conversion Issue
This Testbench will work after
```
assign RefVal = 8'd-55;
```
is changed to
```
assign RefVal = -8'd55;
```

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

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

     // File: ShiftingDemo_TB_V_VHDL.v
    // Generated by MyHDL 0.10
    // Date: Wed Aug 29 14:28:02 2018

    `timescale 1ns/10ps

    module ShiftingDemo_TB_V_VHDL (

    );
    // myHDL -> verilog/VHDL testbench for `ShiftingDemo`

    wire signed [14:0] LSRes;
    reg [3:0] ShiftVal = 0;
    wire signed [7:0] RSRes;
    wire [7:0] ShiftingDemo0_0_RefVal;

    assign ShiftingDemo0_0_RefVal = 8'd-55;

    always @(ShiftVal, RSRes, LSRes) begin: SHIFTINGDEMO_TB_V_VHDL_PRINT_DATA
        $write("%h", ShiftVal);
        $write(" ");
        $write("%h", RSRes);
        $write(" ");
        $write("%h", LSRes);
        $write("\n");
    end

    assign RSRes = $signed(ShiftingDemo0_0_RefVal >>> $signed({1'b0, ShiftVal}));
    assign LSRes = (ShiftingDemo0_0_RefVal << $signed({1'b0, ShiftVal}));

    initial begin: SHIFTINGDEMO_TB_V_VHDL_STIMULES
        integer i;
        for (i=0; i<8; i=i+1) begin
            ShiftVal <= i;
            # 1;
        end
        $finish;
    end

    endmodule

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

### VHDL Testbench
#### VHDL Testbench Conversion Issue
This Testbench is not working in Vivado

```python
TB.convert(hdl="VHDL", initial_values=True)
VHDLTextReader('ShiftingDemo_TB_V_VHDL');
```

    ***VHDL modual from ShiftingDemo_TB_V_VHDL.vhd***

     -- File: ShiftingDemo_TB_V_VHDL.vhd
    -- Generated by MyHDL 0.10
    -- Date: Wed Aug 29 14:28:02 2018

    library IEEE;
    use IEEE.std_logic_1164.all;
    use IEEE.numeric_std.all;
    use std.textio.all;

    use work.pck_myhdl_010.all;

    entity ShiftingDemo_TB_V_VHDL is
    end entity ShiftingDemo_TB_V_VHDL;
    -- myHDL -> verilog/VHDL testbench for `ShiftingDemo`

    architecture MyHDL of ShiftingDemo_TB_V_VHDL is

    signal LSRes: signed (14 downto 0) := 15X"0000";
    signal ShiftVal: unsigned(3 downto 0) := 4X"0";
    signal RSRes: signed (7 downto 0) := 8X"00";
    signal ShiftingDemo0_0_RefVal: signed (7 downto 0);

    begin

    ShiftingDemo0_0_RefVal <= to_signed(-55, 8);

    SHIFTINGDEMO_TB_V_VHDL_PRINT_DATA: process (ShiftVal, RSRes, LSRes) is
        variable L: line;
    begin
        write(L, to_hstring(ShiftVal));
        write(L, string'(" "));
        write(L, to_hstring(unsigned(RSRes)));
        write(L, string'(" "));
        write(L, to_hstring(unsigned(LSRes)));
        writeline(output, L);
    end process SHIFTINGDEMO_TB_V_VHDL_PRINT_DATA;

    RSRes <= shift_right(ShiftingDemo0_0_RefVal, to_integer(ShiftVal));
    LSRes <= shift_left(resize(ShiftingDemo0_0_RefVal, 15), to_integer(ShiftVal));

    SHIFTINGDEMO_TB_V_VHDL_STIMULES: process is
    begin
        for i in 0 to 8-1 loop
            ShiftVal <= to_unsigned(i, 4);
            wait for 1 * 1 ns;
        end loop;
        assert False report "End of Simulation" severity Failure;
        wait;
    end process SHIFTINGDEMO_TB_V_VHDL_STIMULES;

    end architecture MyHDL;

    /home/iridium/anaconda3/lib/python3.6/site-packages/myhdl/conversion/_toVHDL.py:453: ToVHDLWarning: Signal is not driven: ShiftingDemo0_0_RefVal
      category=ToVHDLWarning

# myHDL `concat`  behavior
The `concat` function is an abbreviated name for the full name of concatenation which is that action that this operator performs by joining the bits of all the signals that are arguments to it into a new concatenated single binary

```python
RefVal=intbv(25)[6:]; RefVal, bin(RefVal, 6)
```

    (intbv(25), '011001')

```python
Result=concat(True, RefVal); Result, bin(Result)
```

    (intbv(89), '1011001')

```python
ResultSigned=concat(True, RefVal).signed(); ResultSigned, bin(ResultSigned)
```

    (intbv(-39), '1011001')

## myHDL `concat` Demo

```python
@block
def ConcatDemo(Res, ResS):
    """
    `concat` demo
    Input:
        None
    Ouput:
        Res(7BitVec): concat result
        Res(7BitVec Signed): concat result that is signed
    """
    RefVal=Signal(intbv(25)[6:])
    @always_comb
    def logic():
        Res.next=concat(True, RefVal)
        ResS.next=concat(True, RefVal).signed()
    return instances()
```

## myHDL Testing

```python
Peeker.clear()
Res=Signal(intbv(0)[7:]); Peeker(Res, 'Res')
ResS=Signal(intbv(0)[7:].signed()); Peeker(ResS, ResS)

DUT=ConcatDemo(Res, ResS)

def ConcatDemo_TB():
    """
    myHDL only Testbench for `ConcatDemo`
    """
    @instance
    def stimules():
        for i in range(2):
            yield delay(1)

        raise StopSimulation()

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

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

## Verilog Conversion

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

    ***Verilog modual from ConcatDemo.v***

     // File: ConcatDemo.v
    // Generated by MyHDL 0.10
    // Date: Wed Aug 29 14:28:03 2018

    `timescale 1ns/10ps

    module ConcatDemo (
        Res,
        ResS
    );
    // `concat` demo
    // Input:
    //     None
    // Ouput:
    //     Res(7BitVec): concat result
    //     Res(7BitVec Signed): concat result that is signed

    output [6:0] Res;
    wire [6:0] Res;
    output signed [6:0] ResS;
    wire signed [6:0] ResS;

    wire [5:0] RefVal;

    assign RefVal = 6'd25;

    assign Res = {1'b1, RefVal};
    assign ResS = $signed({1'b1, RefVal});

    endmodule

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

\begin{figure}
\centerline{\includegraphics[width=10cm]{ConcatDemo_v_RTL.png}}
\caption{\label{fig:CDVRTL} ConcatDemo Verilog RTL schematic; Xilinx Vivado 2017.4}
\end{figure}

\begin{figure}
\centerline{\includegraphics[width=10cm]{ConcatDemo_v_SYN.png}}
\caption{\label{fig:CDVSYN} ConcatDemo Verilog Synthesized Schematic; Xilinx Vivado 2017.4}
\end{figure}

## VHDL Conversion

```python
DUT.convert('VHDL')
VHDLTextReader('ConcatDemo');
```

    ***VHDL modual from ConcatDemo.vhd***

     -- File: ConcatDemo.vhd
    -- Generated by MyHDL 0.10
    -- Date: Wed Aug 29 14:28:03 2018

    library IEEE;
    use IEEE.std_logic_1164.all;
    use IEEE.numeric_std.all;
    use std.textio.all;

    use work.pck_myhdl_010.all;

    entity ConcatDemo is
        port (
            Res: out unsigned(6 downto 0);
            ResS: out signed (6 downto 0)
        );
    end entity ConcatDemo;
    -- `concat` demo
    -- Input:
    --     None
    -- Ouput:
    --     Res(7BitVec): concat result
    --     Res(7BitVec Signed): concat result that is signed

    architecture MyHDL of ConcatDemo is

    signal RefVal: unsigned(5 downto 0);

    begin

    RefVal <= to_unsigned(25, 6);

    Res <= unsigned'('1' & RefVal);
    ResS <= signed(unsigned'('1' & RefVal));

    end architecture MyHDL;

    /home/iridium/anaconda3/lib/python3.6/site-packages/myhdl/conversion/_VHDLNameValidation.py:39: ToVHDLWarning: Previously used name being reused: Res
      warnings.warn("Previously used name being reused: %s" % (name), category=ToVHDLWarning)
    /home/iridium/anaconda3/lib/python3.6/site-packages/myhdl/conversion/_VHDLNameValidation.py:39: ToVHDLWarning: Previously used name being reused: RefVal
      warnings.warn("Previously used name being reused: %s" % (name), category=ToVHDLWarning)
    /home/iridium/anaconda3/lib/python3.6/site-packages/myhdl/conversion/_toVHDL.py:453: ToVHDLWarning: Signal is not driven: RefVal
      category=ToVHDLWarning

\begin{figure}
\centerline{\includegraphics[width=10cm]{ConcatDemo_vhd_RTL.png}}
\caption{\label{fig:CDVHDRTL} {ConcatDemo VHDL RTL schematic; Xilinx Vivado 2017.4}
\end{figure}

\begin{figure}
\centerline{\includegraphics[width=10cm]{ConcatDemo_vhd_SYN.png}}
\caption{\label{fig:CDVHDSYN} ConcatDemo VHDL Synthesized Schematic; Xilinx Vivado 2017.4}
\end{figure}

## myHDL to Verilog/VHDL Testbench

```python
@block
def ConcatDemo_TB_V_VHDL():
    """
    myHDL-> Verilog/VHDL Testbench
    """

    Res=Signal(intbv(0)[7:])
    ResS=Signal(intbv(0)[7:].signed())

    @always_comb
    def print_data():
        print(Res, ResS)

    DUT=ConcatDemo(Res, ResS)

    @instance
    def stimules():
        for i in range(2):
            yield delay(1)

        raise StopSimulation()

    return instances()

TB=ConcatDemo_TB_V_VHDL()
```

### Verilog Testbench

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

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

     // File: ConcatDemo_TB_V_VHDL.v
    // Generated by MyHDL 0.10
    // Date: Wed Aug 29 14:28:04 2018

    `timescale 1ns/10ps

    module ConcatDemo_TB_V_VHDL (

    );

    wire [6:0] Res;
    wire signed [6:0] ResS;
    wire [5:0] ConcatDemo0_0_RefVal;

    assign ConcatDemo0_0_RefVal = 6'd25;

    always @(ResS, Res) begin: CONCATDEMO_TB_V_VHDL_PRINT_DATA
        $write("%h", Res);
        $write(" ");
        $write("%h", ResS);
        $write("\n");
    end

    assign Res = {1'b1, ConcatDemo0_0_RefVal};
    assign ResS = $signed({1'b1, ConcatDemo0_0_RefVal});

    initial begin: CONCATDEMO_TB_V_VHDL_STIMULES
        integer i;
        for (i=0; i<2; i=i+1) begin
            # 1;
        end
        $finish;
    end

    endmodule

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

### VHDL Testbench
#### VHDL Testbench Conversion Issue
This Testbench is not working in Vivado

```python
TB.convert(hdl="VHDL", initial_values=True)
VHDLTextReader('ConcatDemo_TB_V_VHDL');
```

    ***VHDL modual from ConcatDemo_TB_V_VHDL.vhd***

     -- File: ConcatDemo_TB_V_VHDL.vhd
    -- Generated by MyHDL 0.10
    -- Date: Wed Aug 29 14:28:04 2018

    library IEEE;
    use IEEE.std_logic_1164.all;
    use IEEE.numeric_std.all;
    use std.textio.all;

    use work.pck_myhdl_010.all;

    entity ConcatDemo_TB_V_VHDL is
    end entity ConcatDemo_TB_V_VHDL;

    architecture MyHDL of ConcatDemo_TB_V_VHDL is

    signal Res: unsigned(6 downto 0) := 7X"00";
    signal ResS: signed (6 downto 0) := 7X"00";
    signal ConcatDemo0_0_RefVal: unsigned(5 downto 0);

    begin

    ConcatDemo0_0_RefVal <= to_unsigned(25, 6);

    CONCATDEMO_TB_V_VHDL_PRINT_DATA: process (ResS, Res) is
        variable L: line;
    begin
        write(L, to_hstring(Res));
        write(L, string'(" "));
        write(L, to_hstring(unsigned(ResS)));
        writeline(output, L);
    end process CONCATDEMO_TB_V_VHDL_PRINT_DATA;

    Res <= unsigned'('1' & ConcatDemo0_0_RefVal);
    ResS <= signed(unsigned'('1' & ConcatDemo0_0_RefVal));

    CONCATDEMO_TB_V_VHDL_STIMULES: process is
    begin
        for i in 0 to 2-1 loop
            wait for 1 * 1 ns;
        end loop;
        assert False report "End of Simulation" severity Failure;
        wait;
    end process CONCATDEMO_TB_V_VHDL_STIMULES;

    end architecture MyHDL;

    /home/iridium/anaconda3/lib/python3.6/site-packages/myhdl/conversion/_toVHDL.py:453: ToVHDLWarning: Signal is not driven: ConcatDemo0_0_RefVal
      category=ToVHDLWarning

# myHDL Bitslicing Behavior

These example values come from the future work with floating point implemented in fixed point architecture which is incredibly important for Digital Signal Processing as will be shown. For now, just understand that the example are based on multiplying two Q4.4 (8bit fixed point) number resulting in Q8.8 (16bit fixed point) product

## Slicing `intbv`

the following is an example of truncation from 16bit to 8bit rounding that shows how bit slicing works in myHDL. The truncation bit slicing keeps values from the far left (Most Significant Bit (MSB) ) to the rightmost specified bit (Least Significant Bit (LSB))

```python
TV=intbv(1749)[16:]
print(f'int 1749 in bit is {bin(TV, len(TV))}')
for j in range(16):
    try:
        Trunc=TV[16:j]
        print(f'Binary: {bin(Trunc, len(Trunc))}, Bits: {len(Trunc)}, rep: {int(Trunc)}, MSB:15, LSB: {j}')
    except ValueError:
        print ('MSB {15} is <= LSB {j}')
```

    int 1749 in bit is 0000011011010101
    Binary: 0000011011010101, Bits: 16, rep: 1749, MSB:15, LSB: 0
    Binary: 000001101101010, Bits: 15, rep: 874, MSB:15, LSB: 1
    Binary: 00000110110101, Bits: 14, rep: 437, MSB:15, LSB: 2
    Binary: 0000011011010, Bits: 13, rep: 218, MSB:15, LSB: 3
    Binary: 000001101101, Bits: 12, rep: 109, MSB:15, LSB: 4
    Binary: 00000110110, Bits: 11, rep: 54, MSB:15, LSB: 5
    Binary: 0000011011, Bits: 10, rep: 27, MSB:15, LSB: 6
    Binary: 000001101, Bits: 9, rep: 13, MSB:15, LSB: 7
    Binary: 00000110, Bits: 8, rep: 6, MSB:15, LSB: 8
    Binary: 0000011, Bits: 7, rep: 3, MSB:15, LSB: 9
    Binary: 000001, Bits: 6, rep: 1, MSB:15, LSB: 10
    Binary: 00000, Bits: 5, rep: 0, MSB:15, LSB: 11
    Binary: 0000, Bits: 4, rep: 0, MSB:15, LSB: 12
    Binary: 000, Bits: 3, rep: 0, MSB:15, LSB: 13
    Binary: 00, Bits: 2, rep: 0, MSB:15, LSB: 14
    Binary: 0, Bits: 1, rep: 0, MSB:15, LSB: 15

```python
TV=intbv(1749)[16:]
print(f'int 1749 in bit is {bin(TV, len(TV))}')
for i in reversed(range(16+1)):
    try:
        Trunc=TV[i:0]
        print(f'Binary: {bin(Trunc, len(Trunc))}, Bits: {len(Trunc)}, rep: {int(Trunc)}, MSB:{i}, LSB: {0}')
    except ValueError:
        print ('MSB is <= LSB index')
```

    int 1749 in bit is 0000011011010101
    Binary: 0000011011010101, Bits: 16, rep: 1749, MSB:16, LSB: 0
    Binary: 000011011010101, Bits: 15, rep: 1749, MSB:15, LSB: 0
    Binary: 00011011010101, Bits: 14, rep: 1749, MSB:14, LSB: 0
    Binary: 0011011010101, Bits: 13, rep: 1749, MSB:13, LSB: 0
    Binary: 011011010101, Bits: 12, rep: 1749, MSB:12, LSB: 0
    Binary: 11011010101, Bits: 11, rep: 1749, MSB:11, LSB: 0
    Binary: 1011010101, Bits: 10, rep: 725, MSB:10, LSB: 0
    Binary: 011010101, Bits: 9, rep: 213, MSB:9, LSB: 0
    Binary: 11010101, Bits: 8, rep: 213, MSB:8, LSB: 0
    Binary: 1010101, Bits: 7, rep: 85, MSB:7, LSB: 0
    Binary: 010101, Bits: 6, rep: 21, MSB:6, LSB: 0
    Binary: 10101, Bits: 5, rep: 21, MSB:5, LSB: 0
    Binary: 0101, Bits: 4, rep: 5, MSB:4, LSB: 0
    Binary: 101, Bits: 3, rep: 5, MSB:3, LSB: 0
    Binary: 01, Bits: 2, rep: 1, MSB:2, LSB: 0
    Binary: 1, Bits: 1, rep: 1, MSB:1, LSB: 0
    MSB is <= LSB index

## Slicing Signed `intbv`

```python
TV=intbv(-1749)[16:].signed()
print(f'int -1749 in bit is {bin(TV, len(TV))}')
for j in range(16):
    try:
        Trunc=TV[16:j].signed()
        print(f'Binary: {bin(Trunc, len(Trunc))}, Bits: {len(Trunc)}, rep: {int(Trunc)}, MSB:15, LSB: {j}')
    except ValueError:
        print ('MSB {15} is <= LSB {j}')
```

    int -1749 in bit is 1111100100101011
    Binary: 1111100100101011, Bits: 16, rep: -1749, MSB:15, LSB: 0
    Binary: 111110010010101, Bits: 15, rep: -875, MSB:15, LSB: 1
    Binary: 11111001001010, Bits: 14, rep: -438, MSB:15, LSB: 2
    Binary: 1111100100101, Bits: 13, rep: -219, MSB:15, LSB: 3
    Binary: 111110010010, Bits: 12, rep: -110, MSB:15, LSB: 4
    Binary: 11111001001, Bits: 11, rep: -55, MSB:15, LSB: 5
    Binary: 1111100100, Bits: 10, rep: -28, MSB:15, LSB: 6
    Binary: 111110010, Bits: 9, rep: -14, MSB:15, LSB: 7
    Binary: 11111001, Bits: 8, rep: -7, MSB:15, LSB: 8
    Binary: 1111100, Bits: 7, rep: -4, MSB:15, LSB: 9
    Binary: 111110, Bits: 6, rep: -2, MSB:15, LSB: 10
    Binary: 11111, Bits: 5, rep: -1, MSB:15, LSB: 11
    Binary: 1111, Bits: 4, rep: -1, MSB:15, LSB: 12
    Binary: 111, Bits: 3, rep: -1, MSB:15, LSB: 13
    Binary: 11, Bits: 2, rep: -1, MSB:15, LSB: 14
    Binary: 1, Bits: 1, rep: -1, MSB:15, LSB: 15

```python
TV=intbv(-1749)[16:].signed()
print(f'int -1749 in bit is {bin(TV, len(TV))}')
for i in reversed(range(16+1)):
    try:
        Trunc=TV[i:0].signed()
        print(f'Binary: {bin(Trunc, len(Trunc))}, Bits: {len(Trunc)}, rep: {int(Trunc)}, MSB:{i}, LSB: {0}')
    except ValueError:
        print ('MSB is <= LSB index')
```

    int -1749 in bit is 1111100100101011
    Binary: 1111100100101011, Bits: 16, rep: -1749, MSB:16, LSB: 0
    Binary: 111100100101011, Bits: 15, rep: -1749, MSB:15, LSB: 0
    Binary: 11100100101011, Bits: 14, rep: -1749, MSB:14, LSB: 0
    Binary: 1100100101011, Bits: 13, rep: -1749, MSB:13, LSB: 0
    Binary: 100100101011, Bits: 12, rep: -1749, MSB:12, LSB: 0
    Binary: 00100101011, Bits: 11, rep: 299, MSB:11, LSB: 0
    Binary: 0100101011, Bits: 10, rep: 299, MSB:10, LSB: 0
    Binary: 100101011, Bits: 9, rep: -213, MSB:9, LSB: 0
    Binary: 00101011, Bits: 8, rep: 43, MSB:8, LSB: 0
    Binary: 0101011, Bits: 7, rep: 43, MSB:7, LSB: 0
    Binary: 101011, Bits: 6, rep: -21, MSB:6, LSB: 0
    Binary: 01011, Bits: 5, rep: 11, MSB:5, LSB: 0
    Binary: 1011, Bits: 4, rep: -5, MSB:4, LSB: 0
    Binary: 011, Bits: 3, rep: 3, MSB:3, LSB: 0
    Binary: 11, Bits: 2, rep: -1, MSB:2, LSB: 0
    Binary: 1, Bits: 1, rep: -1, MSB:1, LSB: 0
    MSB is <= LSB index

## Slicing `modbv`

```python
TV=modbv(1749)[16:]
print(f'int 1749 in bit is {bin(TV, len(TV))}')
for j in range(16):
    try:
        Trunc=TV[16:j]
        print(f'Binary: {bin(Trunc, len(Trunc))}, Bits: {len(Trunc)}, rep: {int(Trunc)}, MSB:15, LSB: {j}')
    except ValueError:
        print ('MSB {15} is <= LSB {j}')
```

    int 1749 in bit is 0000011011010101
    Binary: 0000011011010101, Bits: 16, rep: 1749, MSB:15, LSB: 0
    Binary: 000001101101010, Bits: 15, rep: 874, MSB:15, LSB: 1
    Binary: 00000110110101, Bits: 14, rep: 437, MSB:15, LSB: 2
    Binary: 0000011011010, Bits: 13, rep: 218, MSB:15, LSB: 3
    Binary: 000001101101, Bits: 12, rep: 109, MSB:15, LSB: 4
    Binary: 00000110110, Bits: 11, rep: 54, MSB:15, LSB: 5
    Binary: 0000011011, Bits: 10, rep: 27, MSB:15, LSB: 6
    Binary: 000001101, Bits: 9, rep: 13, MSB:15, LSB: 7
    Binary: 00000110, Bits: 8, rep: 6, MSB:15, LSB: 8
    Binary: 0000011, Bits: 7, rep: 3, MSB:15, LSB: 9
    Binary: 000001, Bits: 6, rep: 1, MSB:15, LSB: 10
    Binary: 00000, Bits: 5, rep: 0, MSB:15, LSB: 11
    Binary: 0000, Bits: 4, rep: 0, MSB:15, LSB: 12
    Binary: 000, Bits: 3, rep: 0, MSB:15, LSB: 13
    Binary: 00, Bits: 2, rep: 0, MSB:15, LSB: 14
    Binary: 0, Bits: 1, rep: 0, MSB:15, LSB: 15

```python
TV=modbv(1749)[16:]
print(f'int 1749 in bit is {bin(TV, len(TV))}')

for i in reversed(range(16+1)):
    try:
        Trunc=TV[i:0]
        print(f'Binary: {bin(Trunc, len(Trunc))}, Bits: {len(Trunc)}, rep: {int(Trunc)}, MSB:{i}, LSB: {0}')
    except ValueError:
        print ('MSB is <= LSB index')
```

    int 1749 in bit is 0000011011010101
    Binary: 0000011011010101, Bits: 16, rep: 1749, MSB:16, LSB: 0
    Binary: 000011011010101, Bits: 15, rep: 1749, MSB:15, LSB: 0
    Binary: 00011011010101, Bits: 14, rep: 1749, MSB:14, LSB: 0
    Binary: 0011011010101, Bits: 13, rep: 1749, MSB:13, LSB: 0
    Binary: 011011010101, Bits: 12, rep: 1749, MSB:12, LSB: 0
    Binary: 11011010101, Bits: 11, rep: 1749, MSB:11, LSB: 0
    Binary: 1011010101, Bits: 10, rep: 725, MSB:10, LSB: 0
    Binary: 011010101, Bits: 9, rep: 213, MSB:9, LSB: 0
    Binary: 11010101, Bits: 8, rep: 213, MSB:8, LSB: 0
    Binary: 1010101, Bits: 7, rep: 85, MSB:7, LSB: 0
    Binary: 010101, Bits: 6, rep: 21, MSB:6, LSB: 0
    Binary: 10101, Bits: 5, rep: 21, MSB:5, LSB: 0
    Binary: 0101, Bits: 4, rep: 5, MSB:4, LSB: 0
    Binary: 101, Bits: 3, rep: 5, MSB:3, LSB: 0
    Binary: 01, Bits: 2, rep: 1, MSB:2, LSB: 0
    Binary: 1, Bits: 1, rep: 1, MSB:1, LSB: 0
    MSB is <= LSB index

## myHDL BitSlicing Demo Module

```python
@block
def BitSlicingDemo(MSB, LSB, Res):
    """
    Demenstration Module for Bit Slicing in myHDL

    Inputs:
        MSB (5BitVec): Most Signficant Bit Index Must be > LSB,
            ex: if LSB==0 MSB must range between 1 and 15
        LSB (5BitVec): Lest Signficant Bit Index Must be < MSB
            ex: if MSB==15 LSB must range beteen 0 and 15

    Outputs:
        Res(16BitVec Signed): Result of the slicing operation from
        Refrance Vales (hard coded in module) -1749 (16BitVec Signed)

    """
    RefVal=Signal(intbv(-1749)[16:].signed())
    @always_comb
    def logic():
        Res.next=RefVal[MSB:LSB].signed()
    return instances()

```

## myHDL Testing

```python
Peeker.clear()
MSB=Signal(intbv(16)[5:]); Peeker(MSB, 'MSB')
LSB=Signal(intbv(0)[5:]); Peeker(LSB, 'LSB')
Res=Signal(intbv(0)[16:].signed()); Peeker(Res, 'Res')

DUT=BitSlicingDemo(MSB, LSB, Res)

def BitslicingDemo_TB():
    """
    myHDL only Testbench for `BitSlicingDemo`
    """
    @instance
    def stimules():

        for j in range(15):
            MSB.next=16
            LSB.next=j
            yield delay(1)

        for i in reversed(range(1, 16)):
            MSB.next=i
            LSB.next=0
            yield delay(1)

        raise StopSimulation()
    return instances()

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

```python
Peeker.to_wavedrom('MSB', 'LSB', 'Res')
```

```python
Peeker.to_dataframe()[['MSB', 'LSB', 'Res']]
```

      MSB
      LSB
      Res

      0
      16
      0
      -1749

      1
      16
      1
      -875

      2
      16
      2
      -438

      3
      16
      3
      -219

      4
      16
      4
      -110

      5
      16
      5
      -55

      6
      16
      6
      -28

      7
      16
      7
      -14

      8
      16
      8
      -7

      9
      16
      9
      -4

      10
      16
      10
      -2

      11
      16
      11
      -1

      12
      16
      12
      -1

      13
      16
      13
      -1

      14
      16
      14
      -1

      15
      15
      0
      -1749

      16
      14
      0
      -1749

      17
      13
      0
      -1749

      18
      12
      0
      -1749

      19
      11
      0
      299

      20
      10
      0
      299

      21
      9
      0
      -213

      22
      8
      0
      43

      23
      7
      0
      43

      24
      6
      0
      -21

      25
      5
      0
      11

      26
      4
      0
      -5

      27
      3
      0
      3

      28
      2
      0
      -1

      29
      1
      0
      -1

## Verilog Conversion
### Verilog Conversion Issue
The following is unsynthesizable since Verilog requires that the indexes in bit slicing (aka Part-selects) be constant values. Along with the error in `assign RefVal = 16'd-1749;`

However, the generated Verilog code from `BitSlicingDemo` does hold merit in showing how the index values are mapped from myHDL to Verilog

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

    ***Verilog modual from BitSlicingDemo.v***

     // File: BitSlicingDemo.v
    // Generated by MyHDL 0.10
    // Date: Wed Aug 29 14:28:06 2018

    `timescale 1ns/10ps

    module BitSlicingDemo (
        MSB,
        LSB,
        Res
    );
    // Demenstration Module for Bit Slicing in myHDL
    //
    // Inputs:
    //     MSB (5BitVec): Most Signficant Bit Index Must be > LSB,
    //         ex: if LSB==0 MSB must range between 1 and 15
    //     LSB (5BitVec): Lest Signficant Bit Index Must be < MSB
    //         ex: if MSB==15 LSB must range beteen 0 and 15
    //
    // Outputs:
    //     Res(16BitVec Signed): Result of the slicing operation from
    //     Refrance Vales (hard coded in module) -1749 (16BitVec Signed)
    //

    input [4:0] MSB;
    input [4:0] LSB;
    output signed [15:0] Res;
    wire signed [15:0] Res;

    wire [15:0] RefVal;

    assign RefVal = 16'd-1749;

    assign Res = $signed(RefVal[MSB-1:LSB]);

    endmodule

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

## VHDL Conversion
### VHDL Conversion Issue
The following is unsynthesizable since VHDL requires that the indexes in bit slicing (aka Part-selects) be constant values.

However, the generated VHDL code from `BitSlicingDemo` does hold merit in showing how the index values are mapped from myHDL to VHDL

```python
DUT.convert(hdl='VHDL')
VHDLTextReader('BitSlicingDemo');
```

    ***VHDL modual from BitSlicingDemo.vhd***

     -- File: BitSlicingDemo.vhd
    -- Generated by MyHDL 0.10
    -- Date: Wed Aug 29 14:28:06 2018

    library IEEE;
    use IEEE.std_logic_1164.all;
    use IEEE.numeric_std.all;
    use std.textio.all;

    use work.pck_myhdl_010.all;

    entity BitSlicingDemo is
        port (
            MSB: in unsigned(4 downto 0);
            LSB: in unsigned(4 downto 0);
            Res: out signed (15 downto 0)
        );
    end entity BitSlicingDemo;
    -- Demenstration Module for Bit Slicing in myHDL
    --
    -- Inputs:
    --     MSB (5BitVec): Most Signficant Bit Index Must be > LSB,
    --         ex: if LSB==0 MSB must range between 1 and 15
    --     LSB (5BitVec): Lest Signficant Bit Index Must be < MSB
    --         ex: if MSB==15 LSB must range beteen 0 and 15
    --
    -- Outputs:
    --     Res(16BitVec Signed): Result of the slicing operation from
    --     Refrance Vales (hard coded in module) -1749 (16BitVec Signed)
    --

    architecture MyHDL of BitSlicingDemo is

    signal RefVal: signed (15 downto 0);

    begin

    RefVal <= to_signed(-1749, 16);

    Res <= signed(unsigned(RefVal(to_integer(MSB)-1 downto to_integer(LSB))));

    end architecture MyHDL;

    /home/iridium/anaconda3/lib/python3.6/site-packages/myhdl/conversion/_VHDLNameValidation.py:39: ToVHDLWarning: Previously used name being reused: Res
      warnings.warn("Previously used name being reused: %s" % (name), category=ToVHDLWarning)
    /home/iridium/anaconda3/lib/python3.6/site-packages/myhdl/conversion/_VHDLNameValidation.py:39: ToVHDLWarning: Previously used name being reused: RefVal
      warnings.warn("Previously used name being reused: %s" % (name), category=ToVHDLWarning)
    /home/iridium/anaconda3/lib/python3.6/site-packages/myhdl/conversion/_toVHDL.py:453: ToVHDLWarning: Signal is not driven: RefVal
      category=ToVHDLWarning

## myHDL to Verilog/VHDL Testbench

```python
@block
def BitslicingDemo_TB_V_VHDL():
    """
    myHDL -> Verilog/VHDL Testbench for `BitSlicingDemo`
    """

    MSB=Signal(intbv(16)[5:])
    LSB=Signal(intbv(0)[5:])
    Res=Signal(intbv(0)[16:].signed())

    @always_comb
    def print_data():
        print(MSB, LSB, Res)

    DUT=BitSlicingDemo(MSB, LSB, Res)

    @instance
    def stimules():

        for j in range(15):
            MSB.next=16
            LSB.next=j
            yield delay(1)

        #!!! reversed is not being converted
        #for i in reversed(range(1, 16)):
        #    MSB.next=i
        #    LSB.next=0
        #    yield delay(1)

        raise StopSimulation()
    return instances()

TB=BitslicingDemo_TB_V_VHDL()
```

### Verilog Testbench

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

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

     // File: BitslicingDemo_TB_V_VHDL.v
    // Generated by MyHDL 0.10
    // Date: Wed Aug 29 14:28:07 2018

    `timescale 1ns/10ps

    module BitslicingDemo_TB_V_VHDL (

    );
    // myHDL -> Verilog/VHDL Testbench for `BitSlicingDemo`

    wire signed [15:0] Res;
    reg [4:0] MSB = 16;
    reg [4:0] LSB = 0;
    wire [15:0] BitSlicingDemo0_0_RefVal;

    assign BitSlicingDemo0_0_RefVal = 16'd-1749;

    always @(LSB, MSB, Res) begin: BITSLICINGDEMO_TB_V_VHDL_PRINT_DATA
        $write("%h", MSB);
        $write(" ");
        $write("%h", LSB);
        $write(" ");
        $write("%h", Res);
        $write("\n");
    end

    assign Res = $signed(BitSlicingDemo0_0_RefVal[MSB-1:LSB]);

    initial begin: BITSLICINGDEMO_TB_V_VHDL_STIMULES
        integer j;
        for (j=0; j<15; j=j+1) begin
            MSB <= 16;
            LSB <= j;
            # 1;
        end
        $finish;
    end

    endmodule

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

### VHDL Testbench

```python
TB.convert(hdl="VHDL", initial_values=True)
VHDLTextReader('BitslicingDemo_TB_V_VHDL');
```

    ***VHDL modual from BitslicingDemo_TB_V_VHDL.vhd***

     -- File: BitslicingDemo_TB_V_VHDL.vhd
    -- Generated by MyHDL 0.10
    -- Date: Wed Aug 29 14:28:07 2018

    library IEEE;
    use IEEE.std_logic_1164.all;
    use IEEE.numeric_std.all;
    use std.textio.all;

    use work.pck_myhdl_010.all;

    entity BitslicingDemo_TB_V_VHDL is
    end entity BitslicingDemo_TB_V_VHDL;
    -- myHDL -> Verilog/VHDL Testbench for `BitSlicingDemo`

    architecture MyHDL of BitslicingDemo_TB_V_VHDL is

    signal Res: signed (15 downto 0) := 16X"0000";
    signal MSB: unsigned(4 downto 0) := 5X"10";
    signal LSB: unsigned(4 downto 0) := 5X"00";
    signal BitSlicingDemo0_0_RefVal: signed (15 downto 0);

    begin

    BitSlicingDemo0_0_RefVal <= to_signed(-1749, 16);

    BITSLICINGDEMO_TB_V_VHDL_PRINT_DATA: process (LSB, MSB, Res) is
        variable L: line;
    begin
        write(L, to_hstring(MSB));
        write(L, string'(" "));
        write(L, to_hstring(LSB));
        write(L, string'(" "));
        write(L, to_hstring(unsigned(Res)));
        writeline(output, L);
    end process BITSLICINGDEMO_TB_V_VHDL_PRINT_DATA;

    Res <= signed(unsigned(BitSlicingDemo0_0_RefVal(to_integer(MSB)-1 downto to_integer(LSB))));

    BITSLICINGDEMO_TB_V_VHDL_STIMULES: process is
    begin
        for j in 0 to 15-1 loop
            MSB <= to_unsigned(16, 5);
            LSB <= to_unsigned(j, 5);
            wait for 1 * 1 ns;
        end loop;
        assert False report "End of Simulation" severity Failure;
        wait;
    end process BITSLICINGDEMO_TB_V_VHDL_STIMULES;

    end architecture MyHDL;

    /home/iridium/anaconda3/lib/python3.6/site-packages/myhdl/conversion/_toVHDL.py:453: ToVHDLWarning: Signal is not driven: BitSlicingDemo0_0_RefVal
      category=ToVHDLWarning

```python

```