\title{Counters in myHDL}
\author{Steven K Armour}
\maketitle

Counters play a vital role in Digital Hardware, ranging from Clock Dividers;  (see below) to event triggers by recording the number of events that have occurred or will still need to occur (all the counters here in use a clock as the counting event but this is easily changed). Presented below are some basic HDL counters (Up, Down, Hybridized Up-Down) in myHDL.

Table of Contents

1  Refrances

2  Libraries and Helper functions

3  Counter Specs

4  myHDL modules bitvector type behavior

4.1  up counting behavior

4.2  down counting behavior

5  Up-Counter

5.1  myHDL testing

5.2  Verilog Code

5.3  Verilog Testbench

6  Down Counter

6.1  myHDL Testing

6.2  Verilog Code

6.3  Verilog Testbench

7  Up/Down Counter

7.1  myHDL Testing

7.2  Verilog Code

7.3  Verilog Testbench

8  Application: Clock Divider

8.1  myHDL Testing

8.2  Verilog Code

8.3  Verilog Testbench

# Refrances
@misc{loi le_2017,
title={Verilog code for counter with testbench},
url={http://www.fpga4student.com/2017/03/verilog-code-for-counter-with-testbench.html},
journal={Fpga4student.com},
author={Loi Le, Van},
year={2017}
}

@misc{digilent_2018,
title={Learn.Digilentinc | Counter and Clock Divider},
url={https://learn.digilentinc.com/Documents/262},
journal={Learn.digilentinc.com},
author={Digilent},
year={2018}
}

# Libraries and Helper functions

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

Tue Aug 14 05:49:04 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
```

# Counter Specs

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

# myHDL modules bitvector type behavior

## up counting behavior

```python
ModBV=modbv(0)[BitSize:]
IntBV=intbv(0)[BitSize:]
print(f"`ModBV` max is {ModBV.max}; min is {ModBV.min}")
print(f"`IntBV` max is {IntBV.max}; min is {IntBV.min}")
```

    `ModBV` max is 32; min is 0
    `IntBV` max is 32; min is 0

```python
for _ in range(ModBV.max*2):
    try:
        ModBV+=1; IntBV+=1
        print(f"`ModBV` value is {ModBV}; `IntBV` value is {IntBV}")
    except ValueError:
        ModBV+=1
        print(f"`ModBV` value is {ModBV}; `IntBV` value is {IntBV} and INVALID")
```

    `ModBV` value is 01; `IntBV` value is 01
    `ModBV` value is 02; `IntBV` value is 02
    `ModBV` value is 03; `IntBV` value is 03
    `ModBV` value is 04; `IntBV` value is 04
    `ModBV` value is 05; `IntBV` value is 05
    `ModBV` value is 06; `IntBV` value is 06
    `ModBV` value is 07; `IntBV` value is 07
    `ModBV` value is 08; `IntBV` value is 08
    `ModBV` value is 09; `IntBV` value is 09
    `ModBV` value is 0a; `IntBV` value is 0a
    `ModBV` value is 0b; `IntBV` value is 0b
    `ModBV` value is 0c; `IntBV` value is 0c
    `ModBV` value is 0d; `IntBV` value is 0d
    `ModBV` value is 0e; `IntBV` value is 0e
    `ModBV` value is 0f; `IntBV` value is 0f
    `ModBV` value is 10; `IntBV` value is 10
    `ModBV` value is 11; `IntBV` value is 11
    `ModBV` value is 12; `IntBV` value is 12
    `ModBV` value is 13; `IntBV` value is 13
    `ModBV` value is 14; `IntBV` value is 14
    `ModBV` value is 15; `IntBV` value is 15
    `ModBV` value is 16; `IntBV` value is 16
    `ModBV` value is 17; `IntBV` value is 17
    `ModBV` value is 18; `IntBV` value is 18
    `ModBV` value is 19; `IntBV` value is 19
    `ModBV` value is 1a; `IntBV` value is 1a
    `ModBV` value is 1b; `IntBV` value is 1b
    `ModBV` value is 1c; `IntBV` value is 1c
    `ModBV` value is 1d; `IntBV` value is 1d
    `ModBV` value is 1e; `IntBV` value is 1e
    `ModBV` value is 1f; `IntBV` value is 1f
    `ModBV` value is 01; `IntBV` value is 20 and INVALID
    `ModBV` value is 03; `IntBV` value is 21 and INVALID
    `ModBV` value is 05; `IntBV` value is 22 and INVALID
    `ModBV` value is 07; `IntBV` value is 23 and INVALID
    `ModBV` value is 09; `IntBV` value is 24 and INVALID
    `ModBV` value is 0b; `IntBV` value is 25 and INVALID
    `ModBV` value is 0d; `IntBV` value is 26 and INVALID
    `ModBV` value is 0f; `IntBV` value is 27 and INVALID
    `ModBV` value is 11; `IntBV` value is 28 and INVALID
    `ModBV` value is 13; `IntBV` value is 29 and INVALID
    `ModBV` value is 15; `IntBV` value is 2a and INVALID
    `ModBV` value is 17; `IntBV` value is 2b and INVALID
    `ModBV` value is 19; `IntBV` value is 2c and INVALID
    `ModBV` value is 1b; `IntBV` value is 2d and INVALID
    `ModBV` value is 1d; `IntBV` value is 2e and INVALID
    `ModBV` value is 1f; `IntBV` value is 2f and INVALID
    `ModBV` value is 01; `IntBV` value is 30 and INVALID
    `ModBV` value is 03; `IntBV` value is 31 and INVALID
    `ModBV` value is 05; `IntBV` value is 32 and INVALID
    `ModBV` value is 07; `IntBV` value is 33 and INVALID
    `ModBV` value is 09; `IntBV` value is 34 and INVALID
    `ModBV` value is 0b; `IntBV` value is 35 and INVALID
    `ModBV` value is 0d; `IntBV` value is 36 and INVALID
    `ModBV` value is 0f; `IntBV` value is 37 and INVALID
    `ModBV` value is 11; `IntBV` value is 38 and INVALID
    `ModBV` value is 13; `IntBV` value is 39 and INVALID
    `ModBV` value is 15; `IntBV` value is 3a and INVALID
    `ModBV` value is 17; `IntBV` value is 3b and INVALID
    `ModBV` value is 19; `IntBV` value is 3c and INVALID
    `ModBV` value is 1b; `IntBV` value is 3d and INVALID
    `ModBV` value is 1d; `IntBV` value is 3e and INVALID
    `ModBV` value is 1f; `IntBV` value is 3f and INVALID
    `ModBV` value is 01; `IntBV` value is 40 and INVALID

## down counting behavior

```python
ModBV=modbv(2**BitSize -1)[BitSize:]
IntBV=intbv(2**BitSize -1)[BitSize:]
print(f"`ModBV` max is {ModBV.max}; min is {ModBV.min}")
print(f"`IntBV` max is {IntBV.max}; min is {IntBV.min}")
```

    `ModBV` max is 32; min is 0
    `IntBV` max is 32; min is 0

```python
for _ in range(ModBV.max*2):
    try:
        ModBV-=1; IntBV-=1
        print(f"`ModBV` value is {ModBV}; `IntBV` value is {IntBV}")
    except ValueError:
        ModBV-=0
        print(f"`ModBV` value is {ModBV}; `IntBV` value is {IntBV} and INVALID")
```

    `ModBV` value is 1e; `IntBV` value is 1e
    `ModBV` value is 1d; `IntBV` value is 1d
    `ModBV` value is 1c; `IntBV` value is 1c
    `ModBV` value is 1b; `IntBV` value is 1b
    `ModBV` value is 1a; `IntBV` value is 1a
    `ModBV` value is 19; `IntBV` value is 19
    `ModBV` value is 18; `IntBV` value is 18
    `ModBV` value is 17; `IntBV` value is 17
    `ModBV` value is 16; `IntBV` value is 16
    `ModBV` value is 15; `IntBV` value is 15
    `ModBV` value is 14; `IntBV` value is 14
    `ModBV` value is 13; `IntBV` value is 13
    `ModBV` value is 12; `IntBV` value is 12
    `ModBV` value is 11; `IntBV` value is 11
    `ModBV` value is 10; `IntBV` value is 10
    `ModBV` value is 0f; `IntBV` value is 0f
    `ModBV` value is 0e; `IntBV` value is 0e
    `ModBV` value is 0d; `IntBV` value is 0d
    `ModBV` value is 0c; `IntBV` value is 0c
    `ModBV` value is 0b; `IntBV` value is 0b
    `ModBV` value is 0a; `IntBV` value is 0a
    `ModBV` value is 09; `IntBV` value is 09
    `ModBV` value is 08; `IntBV` value is 08
    `ModBV` value is 07; `IntBV` value is 07
    `ModBV` value is 06; `IntBV` value is 06
    `ModBV` value is 05; `IntBV` value is 05
    `ModBV` value is 04; `IntBV` value is 04
    `ModBV` value is 03; `IntBV` value is 03
    `ModBV` value is 02; `IntBV` value is 02
    `ModBV` value is 01; `IntBV` value is 01
    `ModBV` value is 00; `IntBV` value is 00
    `ModBV` value is 1f; `IntBV` value is 1f and INVALID
    `ModBV` value is 1e; `IntBV` value is 1e and INVALID
    `ModBV` value is 1d; `IntBV` value is 1d and INVALID
    `ModBV` value is 1c; `IntBV` value is 1c and INVALID
    `ModBV` value is 1b; `IntBV` value is 1b and INVALID
    `ModBV` value is 1a; `IntBV` value is 1a and INVALID
    `ModBV` value is 19; `IntBV` value is 19 and INVALID
    `ModBV` value is 18; `IntBV` value is 18 and INVALID
    `ModBV` value is 17; `IntBV` value is 17 and INVALID
    `ModBV` value is 16; `IntBV` value is 16 and INVALID
    `ModBV` value is 15; `IntBV` value is 15 and INVALID
    `ModBV` value is 14; `IntBV` value is 14 and INVALID
    `ModBV` value is 13; `IntBV` value is 13 and INVALID
    `ModBV` value is 12; `IntBV` value is 12 and INVALID
    `ModBV` value is 11; `IntBV` value is 11 and INVALID
    `ModBV` value is 10; `IntBV` value is 10 and INVALID
    `ModBV` value is 0f; `IntBV` value is 0f and INVALID
    `ModBV` value is 0e; `IntBV` value is 0e and INVALID
    `ModBV` value is 0d; `IntBV` value is 0d and INVALID
    `ModBV` value is 0c; `IntBV` value is 0c and INVALID
    `ModBV` value is 0b; `IntBV` value is 0b and INVALID
    `ModBV` value is 0a; `IntBV` value is 0a and INVALID
    `ModBV` value is 09; `IntBV` value is 09 and INVALID
    `ModBV` value is 08; `IntBV` value is 08 and INVALID
    `ModBV` value is 07; `IntBV` value is 07 and INVALID
    `ModBV` value is 06; `IntBV` value is 06 and INVALID
    `ModBV` value is 05; `IntBV` value is 05 and INVALID
    `ModBV` value is 04; `IntBV` value is 04 and INVALID
    `ModBV` value is 03; `IntBV` value is 03 and INVALID
    `ModBV` value is 02; `IntBV` value is 02 and INVALID
    `ModBV` value is 01; `IntBV` value is 01 and INVALID
    `ModBV` value is 00; `IntBV` value is 00 and INVALID
    `ModBV` value is 1f; `IntBV` value is -1 and INVALID

# Up-Counter
up counters are counters that count up to a target value from a lower starting value. The following counter is a simple one that uses the clock as incrementer (think one clock cycle as one swing of an old grandfather clock pendulum). But more complicated counters can use any signal as an incrementer. This Counter also has a signal the indicates that the counter has been triggered before the modulus values for the internal counter is reset. This is because this counter tries to reproduce the behavior of timers found on common apps that show how much time has elapsed since the counter has run up

\begin{figure}
\centerline{\includegraphics[width=10cm]{Up_Counter.png}}
\caption{\label{fig:RP} Up_Counter Functianl Digram }
\end{figure}

```python
@block
def Up_Counter(count, Trig, clk, rst, CountVal, BitSize):
    """
    UpCounter

    Input:
        clk(bool): system clock feed
        rst(bool): clock reset signal
    Ouput:
        count (bit vector): current count value; count
        Trig(bool)

    Parmeter(Python Only):
        CountVal(int): value to count to
        BitSize (int): Bitvalue size is log_2(CountVal)+1

    """
    #internals
    count_i=Signal(modbv(0)[BitSize:])
    Trig_i=Signal(bool(0))

    @always(clk.posedge, rst.negedge)
    def logic():
        if rst:
            count_i.next=0
            Trig_i.next=0

        elif count_i%CountVal==0 and count_i!=0:
            Trig_i.next=1
            count_i.next=0

        else:
            count_i.next=count_i+1

    @always_comb
    def OuputBuffer():
        count.next=count_i
        Trig.next=Trig_i

    return instances()
```

## myHDL testing

```python
Peeker.clear()
clk=Signal(bool(0)); Peeker(clk, 'clk')
rst=Signal(bool(0)); Peeker(rst, 'rst')
Trig=Signal(bool(0)); Peeker(Trig, 'Trig')
count=Signal(modbv(0)[BitSize:]); Peeker(count, 'count')

DUT=Up_Counter(count, Trig, clk, rst, CountVal, BitSize)

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

    @instance
    def stimules():
        i=0
        while True:
            if i==int(CountVal*1.5):
                rst.next=1
            elif i==int(CountVal*1.5)+1:
                rst.next=0

            if i==int(CountVal*2.5):
                raise StopSimulation()

            i+=1
            yield clk.posedge

    return instances()

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

```

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

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

      Trig
      count
      rst

      0
      0
      1
      0

      1
      0
      2
      0

      2
      0
      3
      0

      3
      0
      4
      0

      4
      0
      5
      0

      5
      0
      6
      0

      6
      0
      7
      0

      7
      0
      8
      0

      8
      0
      9
      0

      9
      0
      10
      0

      10
      0
      11
      0

      11
      0
      12
      0

      12
      0
      13
      0

      13
      0
      14
      0

      14
      0
      15
      0

      15
      0
      16
      0

      16
      0
      17
      0

      17
      1
      0
      0

      18
      1
      1
      0

      19
      1
      2
      0

      20
      1
      3
      0

      21
      1
      4
      0

      22
      1
      5
      0

      23
      1
      6
      0

      24
      1
      7
      1

      25
      0
      1
      0

      26
      0
      2
      0

      27
      0
      3
      0

      28
      0
      4
      0

      29
      0
      5
      0

      30
      0
      6
      0

      31
      0
      7
      0

      32
      0
      8
      0

      33
      0
      9
      0

      34
      0
      10
      0

      35
      0
      11
      0

      36
      0
      12
      0

      37
      0
      13
      0

      38
      0
      14
      0

      39
      0
      15
      0

      40
      0
      16
      0

## Verilog Code

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

    ***Verilog modual from Up_Counter.v***

     // File: Up_Counter.v
    // Generated by MyHDL 0.10
    // Date: Tue Aug 14 05:49:05 2018

    `timescale 1ns/10ps

    module Up_Counter (
        count,
        Trig,
        clk,
        rst
    );
    // UpCounter
    //
    // Input:
    //     clk(bool): system clock feed
    //     rst(bool): clock reset signal
    // Ouput:
    //     count (bit vector): current count value; count
    //     Trig(bool)
    //
    // Parmeter(Python Only):
    //     CountVal(int): value to count to
    //     BitSize (int): Bitvalue size is log_2(CountVal)+1
    //

    output [4:0] count;
    wire [4:0] count;
    output Trig;
    wire Trig;
    input clk;
    input rst;

    reg [4:0] count_i;
    reg Trig_i;

    always @(posedge clk, negedge rst) begin: UP_COUNTER_LOGIC
        if (rst) begin
            count_i <= 0;
            Trig_i <= 0;
        end
        else if ((((count_i % 17) == 0) && (count_i != 0))) begin
            Trig_i <= 1;
            count_i <= 0;
        end
        else begin
            count_i <= (count_i + 1);
        end
    end

    assign count = count_i;
    assign Trig = Trig_i;

    endmodule

\begin{figure}
\centerline{\includegraphics[width=10cm]{Up_CounterRTL.png}}
\caption{\label{fig:UCRTL} Up_Counter RTL Schematic; Xilinx Vivado 2017.4}
\end{figure}

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

## Verilog Testbench

```python
ResetAt=int(CountVal*1.5)+1
StopAt=int(CountVal*2.5)

@block
def Up_CounterTBV():
    """
    myHDL -> Verilog Testbench for `Up_Counter` module
    """
    clk=Signal(bool(0))
    rst=Signal(bool(0))
    Trig=Signal(bool(0))
    count=Signal(modbv(0)[BitSize:])

    @always_comb
    def print_data():
        print(clk, rst, Trig, count)

    DUT=Up_Counter(count, Trig, clk, rst, CountVal, BitSize)

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

    @instance
    def stimules():
        i=0
        while True:
            if i==ResetAt:
                rst.next=1
            elif i==(ResetAt+1):
                rst.next=0
            else:
                pass

            if i==StopAt:
                raise StopSimulation()

            i+=1
            yield clk.posedge

    return instances()

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

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

     // File: Up_CounterTBV.v
    // Generated by MyHDL 0.10
    // Date: Tue Aug 14 05:49:06 2018

    `timescale 1ns/10ps

    module Up_CounterTBV (

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

    reg clk = 0;
    reg rst = 0;
    wire Trig;
    wire [4:0] count;
    reg [4:0] Up_Counter0_0_count_i = 0;
    reg Up_Counter0_0_Trig_i = 0;

    always @(Trig, count, clk, rst) begin: UP_COUNTERTBV_PRINT_DATA
        $write("%h", clk);
        $write(" ");
        $write("%h", rst);
        $write(" ");
        $write("%h", Trig);
        $write(" ");
        $write("%h", count);
        $write("\n");
    end

    always @(posedge clk, negedge rst) begin: UP_COUNTERTBV_UP_COUNTER0_0_LOGIC
        if (rst) begin
            Up_Counter0_0_count_i <= 0;
            Up_Counter0_0_Trig_i <= 0;
        end
        else if ((((Up_Counter0_0_count_i % 17) == 0) && (Up_Counter0_0_count_i != 0))) begin
            Up_Counter0_0_Trig_i <= 1;
            Up_Counter0_0_count_i <= 0;
        end
        else begin
            Up_Counter0_0_count_i <= (Up_Counter0_0_count_i + 1);
        end
    end

    assign count = Up_Counter0_0_count_i;
    assign Trig = Up_Counter0_0_Trig_i;

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

    initial begin: UP_COUNTERTBV_STIMULES
        integer i;
        i = 0;
        while (1'b1) begin
            case (i)
                'h1a: begin
                    rst <= 1;
                end
                (-'h1): begin
                    rst <= 0;
                end
                default: begin
                    // pass
                end
            endcase
            if ((i == 42)) begin
                $finish;
            end
            i = i + 1;
            @(posedge clk);
        end
    end

    endmodule

# Down Counter
Down Counters Count Down from a set upper value to a set target lower value. The following Down Counter is a simple revamp of the previous Up Counter. Thus it starts from the `CountVal` and counts down to zero to trigger the trigger signal that it has completed one countdown cycle before the internal counter resets to restart the countdown.

\begin{figure}
\centerline{\includegraphics[width=10cm]{}}
\caption{\label{fig:RP} Down_Counter Functianl Digram (ToDo) }
\end{figure}

```python
@block
def Down_Counter(count, Trig, clk, rst, StartVal, BitSize):
    """
    DownCounter

    Input:
        clk(bool): system clock feed
        rst(bool): clock reset signal
    Ouput:
        count (bit vector): current count value; count
        Trig(bool)

    Parmeter(Python Only):
        StartVal(int): value to count from
        BitSize (int): Bitvalue size is log_2(CountVal)+1
    CatButt

    """
    #internal counter value
    count_i=Signal(modbv(StartVal)[BitSize:])

    @always(clk.posedge, rst.negedge)
    def logic():
        if rst:
            count_i.next=StartVal
            Trig.next=0

        elif count_i==0:
            Trig.next=1
            count_i.next=StartVal

        else:
            count_i.next=count_i-1

    @always_comb
    def OuputBuffer():
        count.next=count_i

    return instances()
```

## myHDL Testing

```python
Peeker.clear()
clk=Signal(bool(0)); Peeker(clk, 'clk')
rst=Signal(bool(0)); Peeker(rst, 'rst')
Trig=Signal(bool(0)); Peeker(Trig, 'Trig')
count=Signal(modbv(0)[BitSize:]); Peeker(count, 'count')

DUT=Down_Counter(count, Trig, clk, rst, CountVal, BitSize)

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

    @instance
    def stimules():
        i=0
        while True:
            if i==int(CountVal*1.5):
                rst.next=1
            elif i==int(CountVal*1.5)+1:
                rst.next=0

            if i==int(CountVal*2.5):
                raise StopSimulation()

            i+=1
            yield clk.posedge

    return instances()

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

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

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

      Trig
      count
      rst

      0
      0
      16
      0

      1
      0
      15
      0

      2
      0
      14
      0

      3
      0
      13
      0

      4
      0
      12
      0

      5
      0
      11
      0

      6
      0
      10
      0

      7
      0
      9
      0

      8
      0
      8
      0

      9
      0
      7
      0

      10
      0
      6
      0

      11
      0
      5
      0

      12
      0
      4
      0

      13
      0
      3
      0

      14
      0
      2
      0

      15
      0
      1
      0

      16
      0
      0
      0

      17
      1
      17
      0

      18
      1
      16
      0

      19
      1
      15
      0

      20
      1
      14
      0

      21
      1
      13
      0

      22
      1
      12
      0

      23
      1
      11
      0

      24
      1
      10
      1

      25
      0
      16
      0

      26
      0
      15
      0

      27
      0
      14
      0

      28
      0
      13
      0

      29
      0
      12
      0

      30
      0
      11
      0

      31
      0
      10
      0

      32
      0
      9
      0

      33
      0
      8
      0

      34
      0
      7
      0

      35
      0
      6
      0

      36
      0
      5
      0

      37
      0
      4
      0

      38
      0
      3
      0

      39
      0
      2
      0

      40
      0
      1
      0

## Verilog Code

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

    ***Verilog modual from Down_Counter.v***

     // File: Down_Counter.v
    // Generated by MyHDL 0.10
    // Date: Tue Aug 14 05:49:07 2018

    `timescale 1ns/10ps

    module Down_Counter (
        count,
        Trig,
        clk,
        rst
    );
    // DownCounter
    //
    // Input:
    //     clk(bool): system clock feed
    //     rst(bool): clock reset signal
    // Ouput:
    //     count (bit vector): current count value; count
    //     Trig(bool)
    //
    // Parmeter(Python Only):
    //     StartVal(int): value to count from
    //     BitSize (int): Bitvalue size is log_2(CountVal)+1
    // CatButt
    //

    output [4:0] count;
    wire [4:0] count;
    output Trig;
    reg Trig;
    input clk;
    input rst;

    reg [4:0] count_i = 17;

    always @(posedge clk, negedge rst) begin: DOWN_COUNTER_LOGIC
        if (rst) begin
            count_i <= 17;
            Trig <= 0;
        end
        else if ((count_i == 0)) begin
            Trig <= 1;
            count_i <= 17;
        end
        else begin
            count_i <= (count_i - 1);
        end
    end

    assign count = count_i;

    endmodule

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

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

## Verilog Testbench

```python
ResetAt=int(CountVal*1.5)
StopAt=int(CountVal*2.5)

@block
def Down_CounterTBV():
    """
    myHDL -> Verilog Testbench for `Down_Counter` module
    """
    clk=Signal(bool(0))
    rst=Signal(bool(0))
    Trig=Signal(bool(0))
    count=Signal(modbv(0)[BitSize:])

    @always_comb
    def print_data():
        print(clk, rst, Trig, count)

    DUT=Down_Counter(count, Trig, clk, rst, CountVal, BitSize)

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

    @instance
    def stimules():
        i=0
        while True:
            if i==ResetAt:
                rst.next=1
            elif i==(ResetAt+1):
                rst.next=0
            else:
                pass

            if i==StopAt:
                raise StopSimulation()

            i+=1
            yield clk.posedge

    return instances()

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

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

     // File: Down_CounterTBV.v
    // Generated by MyHDL 0.10
    // Date: Tue Aug 14 05:49:08 2018

    `timescale 1ns/10ps

    module Down_CounterTBV (

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

    reg clk = 0;
    reg rst = 0;
    reg Trig = 0;
    wire [4:0] count;
    reg [4:0] Down_Counter0_0_count_i = 17;

    always @(Trig, count, clk, rst) begin: DOWN_COUNTERTBV_PRINT_DATA
        $write("%h", clk);
        $write(" ");
        $write("%h", rst);
        $write(" ");
        $write("%h", Trig);
        $write(" ");
        $write("%h", count);
        $write("\n");
    end

    always @(posedge clk, negedge rst) begin: DOWN_COUNTERTBV_DOWN_COUNTER0_0_LOGIC
        if (rst) begin
            Down_Counter0_0_count_i <= 17;
            Trig <= 0;
        end
        else if ((Down_Counter0_0_count_i == 0)) begin
            Trig <= 1;
            Down_Counter0_0_count_i <= 17;
        end
        else begin
            Down_Counter0_0_count_i <= (Down_Counter0_0_count_i - 1);
        end
    end

    assign count = Down_Counter0_0_count_i;

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

    initial begin: DOWN_COUNTERTBV_STIMULES
        integer i;
        i = 0;
        while (1'b1) begin
            case (i)
                'h19: begin
                    rst <= 1;
                end
                (-'h1): begin
                    rst <= 0;
                end
                default: begin
                    // pass
                end
            endcase
            if ((i == 42)) begin
                $finish;
            end
            i = i + 1;
            @(posedge clk);
        end
    end

    endmodule

# Up/Down Counter
This Counter incorporates both an Up Counter and Down Counter via hybridizing between the two via a direction control state machine

\begin{figure}
\centerline{\includegraphics[width=10cm]{}}
\caption{\label{fig:RP} UpDown_Counter Functianl Digram (ToDo) }
\end{figure}

```python
#Create the Direction States for UpDown Counter
DirStates=enum('Up', 'Down')
print(f"`Up` state repersentation is {bin(DirStates.Up)}")
print(f"`Down` state repersentation is {bin(DirStates.Down)}")
```

    `Up` state repersentation is 0
    `Down` state repersentation is 1

```python
@block
def UpDown_Counter(Dir, count, Trig, clk, rst,
                   CountVal, StartVal, BitSize):
    """
    UpDownCounter, hybrid of a simple Up Counter and
    a simple Down Counter using `Dir` to control Up/Down
    count Direction

    Input:
        Dir():
        clk(bool): system clock feed
        rst(bool): clock reset signal
    Ouput:
        count (bit vector): current count value; count
        Trig(bool)

    Parmeter(Python Only):
        CountVal(int): Highest Value for counter
        StartVal(int): starting value for internal counter
        BitSize (int): Bitvalue size is log_2(CountVal)+1

    """
    #internal counter value
    count_i=Signal(modbv(StartVal)[BitSize:])

    @always(clk.posedge, rst.negedge)
    def logic():
        if rst:
            count_i.next=StartVal
            Trig.next=0

        #counter contanment
        elif count_i//CountVal==1 and rst==0:
            count_i.next=StartVal

        #up behavior
        elif Dir==DirStates.Up:
            count_i.next=count_i+1
            #simple Triger at ends
            if count_i%CountVal==0:
                Trig.next=1

        #down behavior
        elif Dir==DirStates.Down:
            count_i.next=count_i-1
            #simple Triger at ends
            if count_i%CountVal==0:
                Trig.next=1

    @always_comb
    def OuputBuffer():
        count.next=count_i

    return instances()
```

## myHDL Testing

```python
Peeker.clear()
clk=Signal(bool(0)); Peeker(clk, 'clk')
rst=Signal(bool(0)); Peeker(rst, 'rst')
Trig=Signal(bool(0)); Peeker(Trig, 'Trig')
count=Signal(modbv(0)[BitSize:]); Peeker(count, 'count')
Dir=Signal(DirStates.Up); Peeker(Dir, 'Dir')

DUT=UpDown_Counter(Dir, count, Trig, clk, rst,
                   CountVal, StartVal=CountVal//2, BitSize=BitSize)

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

    @instance
    def stimules():
        i=0
        while True:
            if i==int(CountVal*1.5):
                Dir.next=DirStates.Down
            elif i==int(CountVal*2.5):
                rst.next=1
            elif i==int(CountVal*2.5)+1:
                rst.next=0

            if i==int(CountVal*3.5):
                raise StopSimulation()

            i+=1
            yield clk.posedge

    return instances()

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

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

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

      Dir
      Trig
      count
      rst

      0
      Up
      0
      9
      0

      1
      Up
      0
      10
      0

      2
      Up
      0
      11
      0

      3
      Up
      0
      12
      0

      4
      Up
      0
      13
      0

      5
      Up
      0
      14
      0

      6
      Up
      0
      15
      0

      7
      Up
      0
      16
      0

      8
      Up
      0
      17
      0

      9
      Up
      0
      8
      0

      10
      Up
      0
      9
      0

      11
      Up
      0
      10
      0

      12
      Up
      0
      11
      0

      13
      Up
      0
      12
      0

      14
      Up
      0
      13
      0

      15
      Up
      0
      14
      0

      16
      Up
      0
      15
      0

      17
      Up
      0
      16
      0

      18
      Up
      0
      17
      0

      19
      Up
      0
      8
      0

      20
      Up
      0
      9
      0

      21
      Up
      0
      10
      0

      22
      Up
      0
      11
      0

      23
      Up
      0
      12
      0

      24
      Down
      0
      13
      0

      25
      Down
      0
      12
      0

      26
      Down
      0
      11
      0

      27
      Down
      0
      10
      0

      28
      Down
      0
      9
      0

      29
      Down
      0
      8
      0

      30
      Down
      0
      7
      0

      31
      Down
      0
      6
      0

      32
      Down
      0
      5
      0

      33
      Down
      0
      4
      0

      34
      Down
      0
      3
      0

      35
      Down
      0
      2
      0

      36
      Down
      0
      1
      0

      37
      Down
      0
      0
      0

      38
      Down
      1
      31
      0

      39
      Down
      1
      8
      0

      40
      Down
      1
      7
      0

      41
      Down
      1
      6
      1

      42
      Down
      0
      7
      0

      43
      Down
      0
      6
      0

      44
      Down
      0
      5
      0

      45
      Down
      0
      4
      0

      46
      Down
      0
      3
      0

      47
      Down
      0
      2
      0

      48
      Down
      0
      1
      0

      49
      Down
      0
      0
      0

      50
      Down
      1
      31
      0

      51
      Down
      1
      8
      0

      52
      Down
      1
      7
      0

      53
      Down
      1
      6
      0

      54
      Down
      1
      5
      0

      55
      Down
      1
      4
      0

      56
      Down
      1
      3
      0

      57
      Down
      1
      2
      0

## Verilog Code

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

    ***Verilog modual from UpDown_Counter.v***

     // File: UpDown_Counter.v
    // Generated by MyHDL 0.10
    // Date: Tue Aug 14 05:49:08 2018

    `timescale 1ns/10ps

    module UpDown_Counter (
        Dir,
        count,
        Trig,
        clk,
        rst
    );
    // UpDownCounter, hybrid of a simple Up Counter and
    // a simple Down Counter using `Dir` to control Up/Down
    // count Direction
    //
    // Input:
    //     Dir():
    //     clk(bool): system clock feed
    //     rst(bool): clock reset signal
    // Ouput:
    //     count (bit vector): current count value; count
    //     Trig(bool)
    //
    // Parmeter(Python Only):
    //     CountVal(int): Highest Value for counter
    //     StartVal(int): starting value for internal counter
    //     BitSize (int): Bitvalue size is log_2(CountVal)+1
    //

    input [0:0] Dir;
    output [4:0] count;
    wire [4:0] count;
    output Trig;
    reg Trig;
    input clk;
    input rst;

    reg [4:0] count_i = 8;

    always @(posedge clk, negedge rst) begin: UPDOWN_COUNTER_LOGIC
        if (rst) begin
            count_i <= 8;
            Trig <= 0;
        end
        else if ((((count_i / 17) == 1) && (rst == 0))) begin
            count_i <= 8;
        end
        else if ((Dir == 1'b0)) begin
            count_i <= (count_i + 1);
            if (((count_i % 17) == 0)) begin
                Trig <= 1;
            end
        end
        else if ((Dir == 1'b1)) begin
            count_i <= (count_i - 1);
            if (((count_i % 17) == 0)) begin
                Trig <= 1;
            end
        end
    end

    assign count = count_i;

    endmodule

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

\begin{figure}
\centerline{\includegraphics[width=10cm]{UpDown_CounterSYN.png}}
\caption{\label{fig:UDCSYN} UpDown_Counter Synthesized schematic; Xilinx Vivado 2017.4}
\end{figure}

## Verilog Testbench

```python
StateChangeAt=int(CountVal*1.5)
ResetAt=int(CountVal*2.5)
StopAt=int(CountVal*3.5)

@block
def UpDown_CounterTBV():
    """
    myHDL -> Verilog Testbench for `Down_Counter` module
    """
    clk=Signal(bool(0))
    rst=Signal(bool(0))
    Trig=Signal(bool(0))
    count=Signal(modbv(0)[BitSize:])
    Dir=Signal(DirStates.Up)

    DUT=UpDown_Counter(Dir, count, Trig, clk, rst,
                   CountVal, StartVal=CountVal//2, BitSize=BitSize)

    @always_comb
    def print_data():
        print(clk, rst, Trig, count)

    DUT=Down_Counter(count, Trig, clk, rst, CountVal, BitSize)

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

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

            if i==StateChangeAt:
                Dir.next=DirStates.Down
            elif i==ResetAt:
                rst.next=1
            elif i==ResetAt+1:
                rst.next=0
            else:
                pass

            if i==StopAt:
                raise StopSimulation()

            i+=1
            yield clk.posedge

    return instances()

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

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

     // File: UpDown_CounterTBV.v
    // Generated by MyHDL 0.10
    // Date: Tue Aug 14 05:49:09 2018

    `timescale 1ns/10ps

    module UpDown_CounterTBV (

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

    reg clk = 0;
    reg rst = 0;
    reg Trig = 0;
    wire [4:0] count;
    reg [0:0] Dir = 1'b0;
    reg [4:0] Down_Counter0_0_1_count_i = 17;

    always @(posedge clk, negedge rst) begin: UPDOWN_COUNTERTBV_DOWN_COUNTER0_0_1_LOGIC
        if (rst) begin
            Down_Counter0_0_1_count_i <= 17;
            Trig <= 0;
        end
        else if ((Down_Counter0_0_1_count_i == 0)) begin
            Trig <= 1;
            Down_Counter0_0_1_count_i <= 17;
        end
        else begin
            Down_Counter0_0_1_count_i <= (Down_Counter0_0_1_count_i - 1);
        end
    end

    assign count = Down_Counter0_0_1_count_i;

    always @(Trig, count, clk, rst) begin: UPDOWN_COUNTERTBV_PRINT_DATA
        $write("%h", clk);
        $write(" ");
        $write("%h", rst);
        $write(" ");
        $write("%h", Trig);
        $write(" ");
        $write("%h", count);
        $write("\n");
    end

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

    initial begin: UPDOWN_COUNTERTBV_STIMULES
        integer i;
        i = 0;
        while (1'b1) begin
            case (i)
                'h19: begin
                    Dir <= 1'b1;
                end
                'h2a: begin
                    rst <= 1;
                end
                (-'h1): begin
                    rst <= 0;
                end
                default: begin
                    // pass
                end
            endcase
            if ((i == 59)) begin
                $finish;
            end
            i = i + 1;
            @(posedge clk);
        end
    end

    endmodule

    /home/iridium/anaconda3/lib/python3.6/site-packages/myhdl/conversion/_toVerilog.py:327: ToVerilogWarning: Signal is driven but not read: Dir
      category=ToVerilogWarning

# Application: Clock Divider
On common application in HDL for counters in build clock dividers. And while there are more specialized and advanced means to perform up or down frequency generation from a reference clock (see for example digital Phase Lock Loops). A simple clock divider is very useful HDL code to drive other HDL IPs that should/need a slower event rate than the Megahertz+ speeds of today's FPGAs

\begin{figure}
\centerline{\includegraphics[width=10cm]{}}
\caption{\label{fig:RP} ClockDivider Functianl Digram (ToDo) }
\end{figure}

```python
@block
def ClockDivider(Divisor, clkOut, count, clk,rst):
    """
    Simple Clock Divider based on the Digilint Clock Divider
    https://learn.digilentinc.com/Documents/262

    Input:
        Divisor(32 bit): the clock frequncy divide by value
        clk(bool): The input clock
        rst(bool): clockDivider Reset

    Ouput:
        clkOut(bool): the divided clock ouput
        count(32bit): the value of the internal counter
    """

    count_i=Signal(modbv(0)[32:])
    @always(clk.posedge, rst.posedge)
    def counter():
        if rst:
            count_i.next=0
        elif count_i==(Divisor-1):
            count_i.next=0
        else:
            count_i.next=count_i+1

    clkOut_i=Signal(bool(0))
    @always(clk.posedge, rst.posedge)
    def clockTick():
        if rst:
            clkOut_i.next=0
        elif count_i==(Divisor-1):
            clkOut_i.next=not clkOut_i
        else:
            clkOut_i.next=clkOut_i

    @always_comb
    def OuputBuffer():
        count.next=count_i
        clkOut.next=clkOut_i

    return instances()

```

## myHDL Testing

```python
Peeker.clear()
clk=Signal(bool(0)); Peeker(clk, 'clk')
Divisor=Signal(intbv(0)[32:]); Peeker(Divisor, 'Divisor')
count=Signal(intbv(0)[32:]); Peeker(count, 'count')
clkOut=Signal(bool(0)); Peeker(clkOut, 'clkOut')
rst=Signal(bool(0)); Peeker(rst, 'rst')

DUT=ClockDivider(Divisor, clkOut, count, clk,rst)

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

    @instance
    def stimules():
        for i in range(2,6+1):
            Divisor.next=i
            rst.next=0
            #run clock time
            for _ in range(4*2**(i-1)):
                yield clk.posedge

            for j in range(1):
                if j==0:
                    rst.next=1

                yield clk.posedge

        raise StopSimulation()

    return instances()

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

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

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

      Divisor
      clk
      clkOut
      count
      rst

      0
      2
      0
      0
      0
      0

      1
      2
      1
      0
      1
      0

      2
      2
      0
      0
      1
      0

      3
      2
      1
      1
      0
      0

      4
      2
      0
      1
      0
      0

      5
      2
      1
      1
      1
      0

      6
      2
      0
      1
      1
      0

      7
      2
      1
      0
      0
      0

      8
      2
      0
      0
      0
      0

      9
      2
      1
      0
      1
      0

      10
      2
      0
      0
      1
      0

      11
      2
      1
      1
      0
      0

      12
      2
      0
      1
      0
      0

      13
      2
      1
      1
      1
      0

      14
      2
      0
      1
      1
      0

      15
      2
      1
      0
      0
      1

      16
      2
      0
      0
      0
      1

      17
      3
      1
      0
      0
      0

      18
      3
      0
      0
      0
      0

      19
      3
      1
      0
      1
      0

      20
      3
      0
      0
      1
      0

      21
      3
      1
      0
      2
      0

      22
      3
      0
      0
      2
      0

      23
      3
      1
      1
      0
      0

      24
      3
      0
      1
      0
      0

      25
      3
      1
      1
      1
      0

      26
      3
      0
      1
      1
      0

      27
      3
      1
      1
      2
      0

      28
      3
      0
      1
      2
      0

      29
      3
      1
      0
      0
      0

      ...
      ...
      ...
      ...
      ...
      ...

      475
      6
      1
      1
      0
      0

      476
      6
      0
      1
      0
      0

      477
      6
      1
      1
      1
      0

      478
      6
      0
      1
      1
      0

      479
      6
      1
      1
      2
      0

      480
      6
      0
      1
      2
      0

      481
      6
      1
      1
      3
      0

      482
      6
      0
      1
      3
      0

      483
      6
      1
      1
      4
      0

      484
      6
      0
      1
      4
      0

      485
      6
      1
      1
      5
      0

      486
      6
      0
      1
      5
      0

      487
      6
      1
      0
      0
      0

      488
      6
      0
      0
      0
      0

      489
      6
      1
      0
      1
      0

      490
      6
      0
      0
      1
      0

      491
      6
      1
      0
      2
      0

      492
      6
      0
      0
      2
      0

      493
      6
      1
      0
      3
      0

      494
      6
      0
      0
      3
      0

      495
      6
      1
      0
      4
      0

      496
      6
      0
      0
      4
      0

      497
      6
      1
      0
      5
      0

      498
      6
      0
      0
      5
      0

      499
      6
      1
      1
      0
      0

      500
      6
      0
      1
      0
      0

      501
      6
      1
      1
      1
      0

      502
      6
      0
      1
      1
      0

      503
      6
      1
      0
      0
      1

      504
      6
      0
      0
      0
      1

505 rows × 5 columns

```python
ClockDividerData_2=ClockDividerData[ClockDividerData['Divisor']==2]
ClockDividerData_2.reset_index(drop=True, inplace=True)
ClockDividerData_2.plot(y=['clk', 'clkOut']);
```

```python
ClockDividerData_3=ClockDividerData[ClockDividerData['Divisor']==3]
ClockDividerData_3.reset_index(drop=True, inplace=True)
ClockDividerData_3.plot(y=['clk', 'clkOut']);
```

```python
ClockDividerData_4=ClockDividerData[ClockDividerData['Divisor']==4]
ClockDividerData_4.reset_index(drop=True, inplace=True)
ClockDividerData_4.plot(y=['clk', 'clkOut']);
```

```python
ClockDividerData_5=ClockDividerData[ClockDividerData['Divisor']==5]
ClockDividerData_5.reset_index(drop=True, inplace=True)
ClockDividerData_5.plot(y=['clk', 'clkOut']);
```

```python
ClockDividerData_6=ClockDividerData[ClockDividerData['Divisor']==6]
ClockDividerData_6.reset_index(drop=True, inplace=True)
ClockDividerData_6.plot(y=['clk', 'clkOut']);
```

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

    ***Verilog modual from ClockDivider.v***

     // File: ClockDivider.v
    // Generated by MyHDL 0.10
    // Date: Tue Aug 14 05:49:11 2018

    `timescale 1ns/10ps

    module ClockDivider (
        Divisor,
        clkOut,
        count,
        clk,
        rst
    );
    // Simple Clock Divider based on the Digilint Clock Divider
    // https://learn.digilentinc.com/Documents/262
    //
    // Input:
    //     Divisor(32 bit): the clock frequncy divide by value
    //     clk(bool): The input clock
    //     rst(bool): clockDivider Reset
    //
    // Ouput:
    //     clkOut(bool): the divided clock ouput
    //     count(32bit): the value of the internal counter

    input [31:0] Divisor;
    output clkOut;
    wire clkOut;
    output [31:0] count;
    wire [31:0] count;
    input clk;
    input rst;

    reg [31:0] count_i = 0;
    reg clkOut_i = 0;

    always @(posedge clk, posedge rst) begin: CLOCKDIVIDER_COUNTER
        if (rst) begin
            count_i <= 0;
        end
        else if (($signed({1'b0, count_i}) == ($signed({1'b0, Divisor}) - 1))) begin
            count_i <= 0;
        end
        else begin
            count_i <= (count_i + 1);
        end
    end

    always @(posedge clk, posedge rst) begin: CLOCKDIVIDER_CLOCKTICK
        if (rst) begin
            clkOut_i <= 0;
        end
        else if (($signed({1'b0, count_i}) == ($signed({1'b0, Divisor}) - 1))) begin
            clkOut_i <= (!clkOut_i);
        end
        else begin
            clkOut_i <= clkOut_i;
        end
    end

    assign count = count_i;
    assign clkOut = clkOut_i;

    endmodule

## Verilog Code

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

\begin{figure}
\centerline{\includegraphics[width=10cm]{ClockDividerSYN.png}}
\caption{\label{fig:clkDivRTL} ClockDivider synthesized schematic; Xilinx Vivado 2017.4}
\end{figure}

## Verilog Testbench

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

    clk=Signal(bool(0));
    Divisor=Signal(intbv(0)[32:])
    count=Signal(intbv(0)[32:])
    clkOut=Signal(bool(0))
    rst=Signal(bool(0))

    @always_comb
    def print_data():
        print(clk, Divisor, count, clkOut, rst)

    DUT=ClockDivider(Divisor, clkOut, count, clk,rst)

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

    @instance
    def stimules():
        for i in range(2,6+1):
            Divisor.next=i
            rst.next=0
            #run clock time
            for _ in range(4*2**(i-1)):
                yield clk.posedge

            for j in range(1):
                if j==0:
                    rst.next=1
                else:
                    pass

                yield clk.posedge

        raise StopSimulation()

    return instances()

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

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

     // File: ClockDividerTBV.v
    // Generated by MyHDL 0.10
    // Date: Tue Aug 14 05:49:12 2018

    `timescale 1ns/10ps

    module ClockDividerTBV (

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

    reg clk = 0;
    reg rst = 0;
    wire [31:0] count;
    reg [31:0] Divisor = 0;
    wire clkOut;
    reg [31:0] ClockDivider0_0_count_i = 0;
    reg ClockDivider0_0_clkOut_i = 0;

    always @(rst, clkOut, Divisor, count, clk) begin: CLOCKDIVIDERTBV_PRINT_DATA
        $write("%h", clk);
        $write(" ");
        $write("%h", Divisor);
        $write(" ");
        $write("%h", count);
        $write(" ");
        $write("%h", clkOut);
        $write(" ");
        $write("%h", rst);
        $write("\n");
    end

    always @(posedge clk, posedge rst) begin: CLOCKDIVIDERTBV_CLOCKDIVIDER0_0_COUNTER
        if (rst) begin
            ClockDivider0_0_count_i <= 0;
        end
        else if (($signed({1'b0, ClockDivider0_0_count_i}) == ($signed({1'b0, Divisor}) - 1))) begin
            ClockDivider0_0_count_i <= 0;
        end
        else begin
            ClockDivider0_0_count_i <= (ClockDivider0_0_count_i + 1);
        end
    end

    always @(posedge clk, posedge rst) begin: CLOCKDIVIDERTBV_CLOCKDIVIDER0_0_CLOCKTICK
        if (rst) begin
            ClockDivider0_0_clkOut_i <= 0;
        end
        else if (($signed({1'b0, ClockDivider0_0_count_i}) == ($signed({1'b0, Divisor}) - 1))) begin
            ClockDivider0_0_clkOut_i <= (!ClockDivider0_0_clkOut_i);
        end
        else begin
            ClockDivider0_0_clkOut_i <= ClockDivider0_0_clkOut_i;
        end
    end

    assign count = ClockDivider0_0_count_i;
    assign clkOut = ClockDivider0_0_clkOut_i;

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

    initial begin: CLOCKDIVIDERTBV_STIMULES
        integer i;
        integer _;
        integer j;
        for (i=2; i<(6 + 1); i=i+1) begin
            Divisor <= i;
            rst <= 0;
            for (_=0; _<(4 * (2 ** (i - 1))); _=_+1) begin
                @(posedge clk);
            end
            for (j=0; j<1; j=j+1) begin
                if ((j == 0)) begin
                    rst <= 1;
                end
                else begin
                    // pass
                end
                @(posedge clk);
            end
        end
        $finish;
    end

    endmodule


### Installation

*Import NumpSy*

```python
import numpsy as nsy
```

## Units

#### Declare a Unit

```python
meter = nsy.Unit(name="meter", symbol="m")
meter
```

|                     | Unit                            |
|:--------------------|:--------------------------------|
| name                | meter                           |
| symbol              | \begin{equation}m\end{equation} |
| symbolic_expression | \begin{equation}Ø\end{equation} |

#### Retrieve attributes from this Unit

```python
meter.s
```

$\displaystyle m$

```python
meter.symbol
```

$\displaystyle m$

```python
meter.name
```

    'meter'

#### Operate with this unit

```python
farad_per_meter = nsy.Unit(name="Farad", symbol="F") / meter
farad_per_meter
```

|                     | Unit                                      |
|:--------------------|:------------------------------------------|
| name                | (Farad)_per_(meter)                       |
| symbol              | \begin{equation}Ø\end{equation}           |
| symbolic_expression | \begin{equation}\frac{F}{m}\end{equation} |

#### Append to Unit Library

```python
nsy.Units().data
```

    Hertz     Unit       name name_expression               ...
    Farad     Unit       name name_expression               ...
    meter     Unit       name name_expression               ...
    ohm       Unit     name name_expression                 ...
    ratio     Unit       name name_expression               ...
    second    Unit        name name_expression              ...
    Name: 0, dtype: object

```python
nsy.u
```

    Hertz     Unit       name name_expression               ...
    Farad     Unit       name name_expression               ...
    meter     Unit       name name_expression               ...
    ohm       Unit     name name_expression                 ...
    ratio     Unit       name name_expression               ...
    second    Unit        name name_expression              ...
    Name: 0, dtype: object

## Constant

```python
e_0 = nsy.Constant(
    name="permittivity_vaccum",
    symbol= "\epsilon_0",
    numerical=8.8541878128e-12,
    unit=farad_per_meter
)
e_0
```

|                     | Constant                                                       |
|:--------------------|:---------------------------------------------------------------|
| name                | permittivity_vaccum                                            |
| symbol              | \begin{equation}\epsilon_0\end{equation}                       |
| symbolic_expression | \begin{equation}Ø\end{equation}                                |
| numerical           | 8.8541878128e-12                                               |
| unit                | Symbol: \begin{equation}Ø\end{equation}                        |
|                     | Symbolic Expression: \begin{equation}\frac{F}{m}\end{equation} |

```python
e_0.s
```

$\displaystyle \epsilon_0$

```python
e_0.n
```

    8.8541878128e-12

```python
e_d = nsy.Constant(
    name="dielectric_permittivity",
    symbol= "\epsilon_d",
    numerical=5,
    unit=nsy.u.ratio
)
e_d
```

|                     | Constant                                             |
|:--------------------|:-----------------------------------------------------|
| name                | dielectric_permittivity                              |
| symbol              | \begin{equation}\epsilon_d\end{equation}             |
| symbolic_expression | \begin{equation}Ø\end{equation}                      |
| numerical           | 5                                                    |
| unit                | Symbol: \begin{equation}\end{equation}               |
|                     | Symbolic Expression: \begin{equation}Ø\end{equation} |

#### Constants cannot be mutated

```python
e_d.n = 10
```

    Constant cannot be mutated. You cannot set any attribute value. Instantiate a new variable.

## Variable

```python
capacitor_plate_separation = nsy.Variable(
    name="capacitor_plate_separation",
    symbol= "d",
    numerical=None,
    unit=nsy.u.meter
)
capacitor_plate_separation
```

|                     | Variable                                             |
|:--------------------|:-----------------------------------------------------|
| name                | capacitor_plate_separation                           |
| symbol              | \begin{equation}d\end{equation}                      |
| symbolic_expression | \begin{equation}Ø\end{equation}                      |
| numerical           |                                                      |
| unit                | Symbol: \begin{equation}m\end{equation}              |
|                     | Symbolic Expression: \begin{equation}Ø\end{equation} |

```python
capacitor_plate_separation.s
```

$\displaystyle d$

```python
capacitor_plate_separation.u
```

|                     | Unit                            |
|:--------------------|:--------------------------------|
| name                | meter                           |
| symbol              | \begin{equation}m\end{equation} |
| symbolic_expression | \begin{equation}Ø\end{equation} |

#### Variables can be mutated

```python
capacitor_plate_separation.n = 1e-6
capacitor_plate_separation.n
```

    1e-06

```python
capacitor_plate_separation.numerical = 3e-5
capacitor_plate_separation.numerical
```

    3e-05

#### Operate between Value objects
Constants and Variables are value objects.

```python
capacitance_per_plate_cross_sectional_area = e_d / (e_0 * capacitor_plate_separation)
capacitance_per_plate_cross_sectional_area
```

|                     | Value                                                         |
|:--------------------|:--------------------------------------------------------------|
| name                |                                                               |
| symbol              | \begin{equation}Ø\end{equation}                               |
| symbolic_expression | \begin{equation}\frac{\epsilon_d}{\epsilon_0 d}\end{equation} |
| numerical           | 1.8823484456216984e+16                                        |
| unit                | Symbol: \begin{equation}Ø\end{equation}                       |
|                     | Symbolic Expression: \begin{equation}\frac{}{F}\end{equation} |

```python
capacitance_per_plate_cross_sectional_area.se
```

$\displaystyle \frac{\epsilon_d}{\epsilon_0 d}$

```python
capacitance_per_plate_cross_sectional_area.n
```

    1.8823484456216984e+16

#### Perform Flexible Class Operations

```python
raw_capacitor_cross_sectional_area = (1e-6) ** 2
raw_capacitor_cross_sectional_area
```

    1e-12

```python
device_capacitance = capacitance_per_plate_cross_sectional_area * raw_capacitor_cross_sectional_area
device_capacitance
```

|                     | Value                                                           |
|:--------------------|:----------------------------------------------------------------|
| name                |                                                                 |
| symbol              | \begin{equation}Ø\end{equation}                                 |
| symbolic_expression | \begin{equation}\frac{\epsilon_d Ø}{\epsilon_0 d}\end{equation} |
| numerical           | 18823.484456216982                                              |
| unit                | Symbol: \begin{equation}Ø\end{equation}                         |
|                     | Symbolic Expression: \begin{equation}\frac{Ø}{F}\end{equation}  |

```python
device_capacitance.name
```

    ''

```python
device_capacitance.se
```

$\displaystyle \frac{\epsilon_d Ø}{\epsilon_0 d}$

```python
device_capacitance.symbol = "F"
device_capacitance.symbol
```

$\displaystyle F$

```python
raw_capacitor_cross_sectional_area
```

    1e-12

##### Example Functions

```python
nsy.sqrt(device_capacitance)
```

|                     | Value                                                                 |
|:--------------------|:----------------------------------------------------------------------|
| name                |                                                                       |
| symbol              | \begin{equation}Ø\end{equation}                                       |
| symbolic_expression | \begin{equation}\sqrt{F}\end{equation}                                |
| numerical           | 137.19870428038664                                                    |
| unit                | Symbol: \begin{equation}Ø\end{equation}                               |
|                     | Symbolic Expression: \begin{equation}\sqrt{\frac{Ø}{F}}\end{equation} |

```python
nsy.sinh(device_capacitance)
```

    /Users/daquintero/Documents/numpsy/numpsy/functions.py:53: RuntimeWarning: overflow encountered in sinh
      new.numerical = np.sinh(instance_parameters["numerical"])

|                     | Value                                                                 |
|:--------------------|:----------------------------------------------------------------------|
| name                |                                                                       |
| symbol              | \begin{equation}Ø\end{equation}                                       |
| symbolic_expression | \begin{equation}\sinh{\left(F \right)}\end{equation}                  |
| numerical           | inf                                                                   |
| unit                | Symbol: \begin{equation}Ø\end{equation}                               |
|                     | Symbolic Expression: \begin{equation}\sqrt{\frac{Ø}{F}}\end{equation} |


# Standalone libCEED examples

This is a tutorial for [libCEED](https://github.com/CEED/libCEED/), the low-level API library for efficient high-order discretization methods developed by the co-design [Center for Efficient Exascale Discretizations](https://ceed.exascaleproject.org/) (CEED) of the [Exascale Computing Project](https://www.exascaleproject.org/) (ECP).

While libCEED's focus is on high-order finite/spectral element method implementations, the approach is mostly algebraic and thus applicable to other discretizations in factored form, as explained in the [user manual](https://libceed.readthedocs.io/).

## Common notation

For most of our examples, the spatial discretization
uses high-order finite elements/spectral elements, namely, the high-order Lagrange
polynomials defined over $P$ non-uniformly spaced nodes, the
Gauss-Legendre-Lobatto (GLL) points, and quadrature points $\{q_i\}_{i=1}^Q$, with
corresponding weights $\{w_i\}_{i=1}^Q$ (typically the ones given by Gauss
or Gauss-Lobatto quadratures, that are built in the library).

We discretize the domain, $\Omega \subset \mathbb{R}^d$ (with $d=1,2,3$,
typically) by letting $\Omega = \bigcup_{e=1}^{N_e}\Omega_e$, with $N_e$
disjoint elements. For most examples we use unstructured meshes for which the elements
are hexahedra (although this is not a requirement in libCEED).

The physical coordinates are denoted by $\mathbf{x}=(x,y,z)\in\Omega_e$,
while the reference coordinates are represented as
$\boldsymbol{X}=(X,Y,Z) \equiv (X_1,X_2,X_3) \in I=[-1,1]^3$
(for $d=3$).

### Ex1-Volume

#### Mathematical formulation

This example is located in the subdirectory `examples/ceed`. It illustrates a
simple usage of libCEED to compute the volume of a given body using a matrix-free
application of the mass operator. Arbitrary mesh and solution orders in 1D, 2D and 3D
are supported from the same code.

This example shows how to compute line/surface/volume integrals of a 1D, 2D, or 3D
domain $\Omega$ respectively, by applying the mass operator to a vector of
$1$s. It computes:

$$
   I = \int_{\Omega} 1 \, dV .
$$

We write here the vector $u(x)\equiv 1$ in the Galerkin approximation,
and find the volume of $\Omega$ as

$$
   \sum_e \int_{\Omega_e} v(x) 1 \, dV
$$

with $v(x) \in \mathcal{V}_p = \{ v \in H^{1}(\Omega_e) \,|\, v \in P_p(\boldsymbol{I}), e=1,\ldots,N_e \}$,
the test functions.

#### Executing the example

Clone or download libCEED by running

```python
! git clone https://github.com/CEED/libCEED.git
```

Then move to the libCEED folder

```python
cd libCEED
```

And compile the library by running

```python
! make
```

Move to the examples folder

```python
cd examples/
```

Then move to the standalone libCEED's examples folder

```python
cd ceed/
```

And compile the examples by running

```python
! make
```

Now run `ex1-volume` by running

```python
! ./ex1-volume -d 3 -g
```

    Selected options: [command line option] : <current value>
      Ceed specification [-c] : /cpu/self
      Mesh dimension     [-d] : 3
      Mesh order         [-m] : 4
      Solution order     [-o] : 4
      Num. 1D quadr. pts [-q] : 6
      Approx. # unknowns [-s] : 262144
      QFunction source   [-g] : gallery

    Mesh size: nx = 16, ny = 16, nz = 16
    Number of mesh nodes     : 274625
    Number of solution nodes : 274625
    Computing the quadrature data for the mass operator ... done.
    Computing the mesh volume using the formula: vol = 1^T.M.1 ... done.
    Exact mesh volume    :  2.3561944901923
    Computed mesh volume :  2.3561944901921
    Volume error         : -2.7444713168734e-13

This example shows how to compute line/surface/volume integrals of a 1D, 2D, or 3D domain Ω respectively, by applying the mass operator to a vector of 1s. The command line option `-d` specifies the dimensionality of the domain Ω. The option `-g` specifies that the mass operator is, in this case, selected from a gallery of available built-in operators in the library.

### Ex2-Surface

#### Mathematical formulation

This example is located in the subdirectory `examples/ceed`. It computes the
surface area of a given body using matrix-free application of a diffusion operator.
Arbitrary mesh and solution orders in 1D, 2D and 3D are supported from the same code.

Similarly to the Ex1-Volume example, it computes:

\begin{equation}\label{eq-ex2-surface}\tag{eq. 1}
   I =  \int_{\partial \Omega} 1 \, dS ,
\end{equation}

by applying the divergence theorem.
In particular, we select $u(\mathbf x) = x_0 + x_1 + x_2$, for which $\nabla u = [1, 1, 1]^T$, and thus $\nabla u \cdot \hat{\mathbf n} = 1$.

Given Laplace's equation,

$$
   \nabla \cdot \nabla u = 0, \textrm{ for  } \mathbf{x} \in \Omega ,
$$

let us multiply by a test function $v$ and integrate by parts to obtain

$$
   \int_\Omega \nabla v \cdot \nabla u \, dV - \int_{\partial \Omega} v \nabla u \cdot \hat{\mathbf n}\, dS = 0 .
$$

Since we have chosen $u$ such that $\nabla u \cdot \hat{\mathbf n} = 1$, the boundary integrand is $v 1 \equiv v$. Hence, similar to the previous example, we can evaluate the surface integral by applying the volumetric Laplacian as follows

$$
   \int_\Omega \nabla v \cdot \nabla u \, dV \approx \sum_e \int_{\partial \Omega_e} v(x) 1 \, dS .
$$

### Executing the example

Assuming the steps above, you should be in the `examples/ceed/` subdirectory and have already compiled the example.

Now run `ex2-surface` by running

```python
! ./ex2-surface -d 3 -g
```

    Selected options: [command line option] : <current value>
      Ceed specification [-c] : /cpu/self
      Mesh dimension     [-d] : 3
      Mesh order         [-m] : 4
      Solution order     [-o] : 4
      Num. 1D quadr. pts [-q] : 6
      Approx. # unknowns [-s] : 262144
      QFunction source   [-g] : gallery

    Mesh size: nx = 16, ny = 16, nz = 16
    Number of mesh nodes     : 274625
    Number of solution nodes : 274625
    Computing the quadrature data for the diffusion operator ... done.
    Computing the mesh surface area using the formula: sa = 1^T.|K.x| ... done.
    Exact mesh surface area    :  6
    Computed mesh surface area :  5.9773703490853
    Surface area error         : -0.022629650914673

This example computes the surface area of a given body using matrix-free application of a Laplace's (diffusion) operator. The command line option `-d` specifies the dimensionality of the domain Ω. The option `-g` specifies that the Laplace's operator is, in this case, selected from a gallery of available built-in operators in the library.


### Tyson Paper

```python
#Libraries
import pandas as  pd
import numpy as np
from pylab import *
%matplotlib inline

import matplotlib.pyplot as plt
from scipy.integrate import odeint

from sympy.interactive import printing
printing.init_printing(use_latex = True)
from sympy import *
import sympy as sp
```

#### 1A. Ordered distributive mechanism

```python
def nCk(n,k):
    return exp(log(gamma(n+1))-log(gamma(k+1))-log(gamma(n-k+1)))
```

```python
def TLi_TLT():
    N = 10 # Telomere length states
    tbyr = np.linspace(0,100,10000)
    for i in range(N+1):
        r = tbyr**i*(1-tbyr)/(1 - tbyr**(N+1))
        plt.plot(tbyr,r,label='TL'+str(i))
    plt.xlabel('t / r',fontsize=15)
    plt.ylabel('TLi / TL(Total)',fontsize=15)
    plt.xscale('log')
    #plt.title('Fig 1A:Distributive Ordered Mechanism',fontsize=15)
    #plt.xticks([0.01,0.1,1,10,100])
    plt.legend(loc='center right',fontsize=12)
    plt.xticks(fontsize=15)
    plt.yticks(fontsize=15)
    plt.xlim([0.01,100])
    plt.show()
TLi_TLT()
```

#### 1B. Disordered distributive mechanism

```python
def TLi_TLTD():
    N = 10 # phosphorylation sites on X
    tbyr = np.arange(0,100,0.01)
    for i in range(N+1):
        r = nCk(N,i)*tbyr**i/(1 + tbyr)**N
        plt.plot(tbyr,r,label='TL'+str(i))
    plt.xlabel('t / r',fontsize=15)
    plt.ylabel('TLi / TL(Total)',fontsize = 15)
    #plt.title('Distributive Disordered Mechanism')
    #plt.xlim(0,10)
    plt.xscale('log')
    plt.legend(loc='center right',fontsize=12)
    plt.xticks(fontsize=15)
    plt.yticks(fontsize=15)
    plt.xlim([0.01,100])
    plt.show()
TLi_TLTD()
```

#### 2.2 Stepwise activity change of the Telomere Length states

#### Fig 2.a Ordered mechanisms

```python
def TLa_TLT():
    N = 10 # phosphorylation sites on X
    tbyr = np.linspace(0,100,10000)
    for q in range(0,9,2):

        r = (1-tbyr**(q+1))/(1 - tbyr**(N+1))
        plt.plot(tbyr,r,label='TL'+str(q))
    plt.xlabel('t / r',fontsize=15)
    plt.ylabel('TLi / TL(Total)',fontsize=15)
    plt.xscale('log')
    #plt.title('Fig 2b. Ordered Mechanism')
    #plt.xticks([0.01,0.1,1,10,100])
    plt.xlim(0.1,10)
    plt.xticks(fontsize=15)
    plt.yticks(fontsize=15)
    plt.xlim([0.01,100])
    plt.legend(fontsize=15)
    plt.show()
TLa_TLT()
```

#### Fig 2.b Disordered

```python
def TLb_TLT():
    N = 10 # phosphorylation sites on X
    tbyr = np.linspace(0,100,10000)
    for q in range(0,9,2):
        num = 0
        for j in range(0,q+1):
            num+=nCk(N,j)*(tbyr**j)
        r = num/((1 + tbyr)**N)
        plt.plot(tbyr,r,label='TL_'+str(q))
    plt.xlabel('t / r',fontsize=15)
    plt.ylabel('TLi / TL(Total)',fontsize=15)
    plt.xscale('log')
    #plt.title('Fig 2b. Disordered Mechanism')
    #plt.xticks([0.01,0.1,1,10,100])
    plt.xlim(0.01,100)
    plt.xticks(fontsize=15)
    plt.yticks(fontsize=15)
    plt.xlim([0.01,100])
    plt.legend(fontsize=15)
    plt.show()
TLb_TLT()
```

#### 3a. ordered mechanism

```python
def TLalpha_TLT():
    N = 10 # phosphorylation sites on X

    tbyr = np.linspace(0,100,10000)
    omega = 1 # for a<0, a**(-N) for a>0
    for a in [0.4,0.1,0.04]:

        r = (1-(a*tbyr)**(N+1))*(1-tbyr)/((1 - tbyr**(N+1))*(1-a*tbyr))
        plt.plot(tbyr,r,label='a='+str(a))
    plt.xlabel('t / r',fontsize=15)
    plt.ylabel('TLi / TL(Total)',fontsize=15)
    plt.xscale('log')
    #plt.title('Fig 3a. Ordered Mechanism')
    #plt.xticks([0.01,0.1,1,10,100])
    plt.xticks(fontsize=15)
    plt.yticks(fontsize=15)
    plt.xlim([0.01,100])
    plt.xlim(0.1,2)
    plt.legend(fontsize=15)
    plt.show()
TLalpha_TLT()
```

#### 3b. Disordered mechanism

```python
def TLOmega_TLT():
    N = 10 # phosphorylation sites on X

    tbyr = np.linspace(0,100,10000)
    omega = 1 # for a<0, a**(-N) for a>0
    for a in [0.04,0.1,0.4]:
        r = (1+a*tbyr)**N/(1+tbyr)**N
        plt.plot(tbyr,r,label='a='+str(a))
    plt.xlabel('t / r',fontsize=15)
    plt.ylabel('TLi / TL(Total)',fontsize=15)
    plt.xscale('log')
    #plt.title('Fig 3b. Disordered Mechanism')
    #plt.xticks([0.01,0.1,1,10,100])
    plt.xlim(0.01,10)
    plt.xticks(fontsize=15)
    plt.yticks(fontsize=15)
    #plt.xlim([0.01,100])
    plt.legend(fontsize=15)
    plt.show()
TLOmega_TLT()
```

#### 2.5. Bistability by embedding TL in a double-negative feedback loop

#### fig 4a

```python
Ks = 0.02
Kd = 0.02
Ka = 0.98
XT = 1
N = 3
q = 0
r = 0.1 #for ordered and 0.5(disordered)

def TLss_4a():
    t = np.linspace(0,100,100000)
    Telo_ss = (1-t/r)/(1 - (t/r)**(N+1))
    T_ss = Ks/(Kd+Ka*Telo_ss)
    plt.plot(t,Telo_ss,'-r',label='Rif1_ss')
    plt.plot(T_ss,Telo_ss,'--b',label='Telo_ss')
    plt.xlabel('Telomerase (T)',fontsize=15)
    plt.ylabel('TLi',fontsize=15)
    plt.xscale('log')
    #plt.title('Fig 4a. Ordered Mechanism')
    #plt.xticks([0.01,0.1,1,10,100])
    plt.xlim(0.01,2)
    plt.ylim(0,1)
    plt.xticks(fontsize=15)
    plt.yticks(fontsize=15)
    plt.legend(fontsize=15)
    plt.show()
TLss_4a()
```

#### Deterministic simulation case

```python
Ks = 0.02; Kd = 0.02;Ka = 0.98
Xa = 1
K = 10; V = 200
H = 10
#XT = 20

X0 = 1
X1 = 1
X2 = 1
X3 = 1
X4 = 1
X5 = 1
X6 = 1
X7 = 1
X8 = 1
X9 = 1
X10= 1

init_c = [K,X0,X1,X2,X3,X4,X5,X6,X7,X8,X9,X10]

def K_actV(x,t):
    K  = x[0]
    X0 = x[1]
    X1 = x[2]
    X2 = x[3]
    X3 = x[4]
    X4 = x[5]
    X5 = x[6]
    X6 = x[7]
    X7 = x[8]
    X8 = x[9]
    X9 = x[10]
    X10= x[11]

    #Xa = XT - (X0+X1+X2+X3+X4+X5+X6+X7+X8+X9+X10)
    #Xa = X0+X1+X2+X3+X4+X5+X6+X7+X8+X9+X10

    Xa = X0
    #Xa = X10
    #Xa = XT-X10

    dKdt =  Ks*V - (Kd+(Ka/V)*Xa)*K
    dX0dt = 1/V*(H*X1 - K*X0)
    dX1dt = 1/V*(K*X0 - (K+H)*X1 + H*X2)
    dX2dt = 1/V*(K*X1 - (K+H)*X2 + H*X3)
    dX3dt = 1/V*(K*X2 - (K+H)*X3 + H*X4)
    dX4dt = 1/V*(K*X3 - (K+H)*X4 + H*X5)
    dX5dt = 1/V*(K*X4 - (K+H)*X5 + H*X6)
    dX6dt = 1/V*(K*X5 - (K+H)*X6 + H*X7)
    dX7dt = 1/V*(K*X6 - (K+H)*X7 + H*X8)
    dX8dt = 1/V*(K*X7 - (K+H)*X8 + H*X9)
    dX9dt = 1/V*(K*X8 - (K+H)*X9 + H*X10)
    dX10dt= 1/V*(K*X9 - H*X10)

    return dKdt,dX0dt,dX1dt,dX2dt,dX3dt,dX4dt,dX5dt,dX6dt,dX7dt,dX8dt,dX9dt,dX10dt

```

## TLi = TL0

```python
t = arange(0,100,0.01)
K = 20
V = 20
#H = 10
init_c = [K,X0,X1,X2,X3,X4,X5,X6,X7,X8,X9,X10]
for Hi in range(0,30,3):
    H = Hi
    z = odeint(K_actV,init_c,t)
    plt.plot(t,z[:,0],label='R=%d'%Hi)
#plt.plot(t,z[:,1],'--k',label='X0')
#plt.plot(z[:,2],z[:,0],'--b',label='K')
#plt.plot(t,z[:,11],'--b',label='X10')
#plt.show()
# for ind in range(2,11):
#     plt.plot(t,z[:,ind],label='X%d'%(ind-1))
plt.title('Deterministic Simulation TLa=TL0, T=20, V=20')
plt.xlabel('Time (ms)',fontsize=15)
plt.ylabel('Telomerase (T)',fontsize=15)
plt.xticks(fontsize=15)
plt.yticks(fontsize=15)
plt.legend(loc='center right',fontsize=12)
plt.show()
```

#### Kss at two different states Xa = X0, V = 200

```python
t = arange(0,1000,0.01)
K = 150
V = 200
#H = 50
init_c = [K,X0,X1,X2,X3,X4,X5,X6,X7,X8,X9,X10]
for Hi in range(0,250,25):
    H = Hi
    z = odeint(K_actV,init_c,t)
    plt.plot(t,z[:,0],label='R=%d'%Hi)
#plt.plot(t,z[:,1],'--k',label='X0')
#plt.plot(z[:,2],z[:,0],'--b',label='K')
#plt.plot(t,z[:,11],'--b',label='X10')
#plt.show()
# for ind in range(2,11):
#     plt.plot(t,z[:,ind],label='X%d'%(ind-1))
plt.title('Determiistic Simulation Xa=X0, K=150, V=200')
plt.xlabel('Time',fontsize=15)
plt.ylabel('Telomerase (T)',fontsize=15)
plt.xticks(fontsize=15)
plt.yticks(fontsize=15)
plt.legend(loc='center right',fontsize=15)
plt.show()
```

### Two mono cycles

```python
#Parameters
Ks = 0.02; Kd = 0.02;Ka = 0.98
K = 10
V = 20
H = 10

T0 = 1
T1 = 1
T2 = 1

#Initial Condition
init_c = [K,T0,T1,T2]

def two_mono_Xa_H(x,t):
    K  = x[0]
    T0 = x[1]
    T1 = x[2]
    T2 = x[3]

    Xa = H

    dKdt =  Ks*V - (Kd+(Ka/V)*Xa)*K
    dT0dt = 1/V*(H*T1 - K*T0)
    dT1dt = 1/V*(K*T0 - (K+H)*T1 + H*T2)
    dT2dt = 1/V*(K*T1 - H*T2)

    return dKdt,dT0dt,dT1dt,dT2dt

#plt.figure(figsize=(15,10))
#plt.suptitle('Two Mono Cycles Deterministic, Xa = H',fontsize=15)

t = arange(0,100,0.01)
K = 10
V = 20
#H = 10
init_c = [K,T0,T1,T2]

#plt.subplot(2,2,1)

for Hi in arange(1,21,2):
    H = Hi
    z = odeint(two_mono_Xa_H,init_c,t)
    plt.plot(t,z[:,0],label='Rif1=%d'%Hi)
plt.xlabel('Time(min)',fontsize=15)
plt.ylabel('Telomerase',fontsize=15)
plt.legend(loc='center right',fontsize=12)
plt.xticks(fontsize=15)
plt.yticks(fontsize=15)
#plt.title('Telomerase dec as Rif1 inc',fontsize=15)
plt.show()

#plt.subplot(2,2,2)

for Hi in arange(1,21,2):
    H = Hi
    z = odeint(two_mono_Xa_H,init_c,t)
    plt.plot(t,z[:,1],label='Rif1=%d'%Hi)
plt.xlabel('Time(min)',fontsize=15)
plt.ylabel('TL0',fontsize=15)
plt.xticks(fontsize=15)
plt.yticks(fontsize=15)
plt.legend(loc='center right',fontsize=12)
#plt.title('T0 Elongation',fontsize=15)
plt.show()

#plt.subplot(2,2,3)

for Hi in arange(1,21,2):
    H = Hi
    z = odeint(two_mono_Xa_H,init_c,t)
    plt.plot(t,z[:,2],label='Rif1=%d'%Hi)
plt.xlabel('Time(min)',fontsize=15)
plt.ylabel('TL1',fontsize=15)
plt.xticks(fontsize=15)
plt.yticks(fontsize=15)
plt.legend(loc='center right',fontsize=12)
#plt.title('T1 Elongation/Shortening',fontsize=15)
plt.show()

#plt.subplot(2,2,4)

for Hi in arange(1,21,2):
    H = Hi
    z = odeint(two_mono_Xa_H,init_c,t)
    plt.plot(t,z[:,3],label='Rif1=%d'%Hi)
plt.xlabel('Time(min)',fontsize=15)
plt.ylabel('TL2',fontsize=15)
plt.xticks(fontsize=15)
plt.yticks(fontsize=15)
plt.legend(loc='center right',fontsize=12)
#plt.title('T2 Shortening',fontsize=15)
plt.show()

```

### Ten Telomere states

```python
#Parameters
Ks = 0.02; Kd = 0.02;Ka = 0.28
K = 10
V = 200
H = 10

T0 = 30
T1 = 30
T2 = 30
T3 = 30
T4 = 30
T5 = 30
T6 = 30
T7 = 30
T8 = 30
T9 = 30
T10= 30

#Initial Condition
init_c = [K,T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10]

def K_actV(x,t):
    K  = x[0]
    T0 = x[1]
    T1 = x[2]
    T2 = x[3]
    T3 = x[4]
    T4 = x[5]
    T5 = x[6]
    T6 = x[7]
    T7 = x[8]
    T8 = x[9]
    T9 = x[10]
    T10= x[11]

    Xa = T0

    dKdt =  Ks*V - (Kd+(Ka/V)*Xa)*K
    dT0dt = 1/V*(H*T1 - K*T0)
    dT1dt = 1/V*(K*T0 - (K+H)*T1 + H*T2)
    dT2dt = 1/V*(K*T1 - (K+H)*T2 + H*T3)
    dT3dt = 1/V*(K*T2 - (K+H)*T3 + H*T4)
    dT4dt = 1/V*(K*T3 - (K+H)*T4 + H*T5)
    dT5dt = 1/V*(K*T4 - (K+H)*T5 + H*T6)
    dT6dt = 1/V*(K*T5 - (K+H)*T6 + H*T7)
    dT7dt = 1/V*(K*T6 - (K+H)*T7 + H*T8)
    dT8dt = 1/V*(K*T7 - (K+H)*T8 + H*T9)
    dT9dt = 1/V*(K*T8 - (K+H)*T9 + H*T10)
    dT10dt= 1/V*(K*T9 - H*T10)

    return dKdt,dT0dt,dT1dt,dT2dt,dT3dt,dT4dt,dT5dt,dT6dt,dT7dt,dT8dt,dT9dt,dT10dt

```

```python
t = arange(0,100,0.01)
K = 20
V = 20
#H = 10
init_c = [K,T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10]
for Hi in range(0,12,2):
    H = Hi
    z = odeint(K_actV,init_c,t)
    plt.plot(t,z[:,0],label='Rif1=%d'%Hi)
#plt.title('Figure 3.A Determiistic case Xa=X0, K=20, V=20')
plt.xlabel('Time (min)',fontsize=15)
plt.ylabel('Telomerase',fontsize=15)
plt.xticks(fontsize=15)
plt.yticks(fontsize=15)
plt.legend(loc='center right',fontsize=15)
plt.show()
```

```python
t = arange(0,100,0.01)
K = 20
V = 20
#H = 10
init_c = [K,T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10]
for Hi in range(0,20,3):
    H = Hi
    z = odeint(K_actV,init_c,t)
    plt.plot(t,z[:,1],label='Rif1=%d'%Hi)
#plt.title('Figure 3.A Determiistic case Xa=X0, K=20, V=20')
plt.xlabel('Time (min)',fontsize=15)
plt.ylabel('TL0 (bp)',fontsize=15)
plt.xticks(fontsize=15)
plt.yticks(fontsize=15)
plt.legend(loc='center right',fontsize=15)
plt.show()

t = arange(0,100,0.01)
K = 20
V = 20
#H = 10
init_c = [K,T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10]
for Hi in range(0,20,3):
    H = Hi
    z = odeint(K_actV,init_c,t)
    plt.plot(t,z[:,11],label='Rif1=%d'%Hi)
#plt.title('Figure 3.A Determiistic case Xa=X0, K=20, V=20')
plt.xlabel('Time (min)',fontsize=15)
plt.ylabel('TL10 (bp)',fontsize=15)
plt.xticks(fontsize=15)
plt.yticks(fontsize=15)
plt.legend(loc='center right',fontsize=15)
plt.show()
```

### Stochastic simulation

```python
def stochas_KH(V_val,H_val,K_val,T_val):
    #parameters
    Ks = 0.02; Kd = 0.02;Ka = 0.98; N = 10
    XT = 20
    V = V_val

    K = K_val #(0-40)
    H = H_val #(0-20)
    #Xa = 2

    #X = 1
    X0 = 2
    X1 = 2
    X2 = 2
    X3 = 2
    X4 = 2
    X5 = 2
    X6 = 2
    X7 = 2
    X8 = 2
    X9 = 2
    X10 = 2

    T = T_val
    t = 0

    time = []
    mol_K = [] #no. of molecules of Kinase
    mol_H = [] #no. of molecules of Phosphatase
    mol_X0 = []
    mol_X1 = []
    mol_X2 = []
    mol_X3 = []
    mol_X4 = []
    mol_X5 = []
    mol_X6 = []
    mol_X7 = []
    mol_X8 = []
    mol_X9 = []
    mol_X10 = []

    while t<T:

        #rates = [Ks*V, Kd*K,(Ka/V)*Xa*K]
        Xa = X0

        rates = [Ks*V, Kd*K,(Ka/V)*Xa*K,
                (1/V)*H*X1, (1/V)*K*X0,
                (1/V)*K*X0, (1/V)*(K+H)*X1,(1/V)*H*X2,
                (1/V)*K*X1, (1/V)*(K+H)*X2,(1/V)*H*X3,
                (1/V)*K*X2, (1/V)*(K+H)*X3,(1/V)*H*X4,
                (1/V)*K*X3, (1/V)*(K+H)*X4,(1/V)*H*X5,
                (1/V)*K*X4, (1/V)*(K+H)*X5,(1/V)*H*X6,
                (1/V)*K*X5, (1/V)*(K+H)*X6,(1/V)*H*X7,
                (1/V)*K*X6, (1/V)*(K+H)*X7,(1/V)*H*X8,
                (1/V)*K*X7, (1/V)*(K+H)*X8,(1/V)*H*X9,
                (1/V)*K*X8, (1/V)*(K+H)*X9,(1/V)*H*X10,
                (1/V)*K*X9, (1/V)*H*X10]

        rate_sum = sum(rates)
        #tau = np.random.exponential(scale=1/rate_sum)
        tau = -np.log(np.random.uniform(0,1))/rate_sum
        t+=tau     #time point of next event
        r = np.random.rand()*rate_sum     # rxn selection

        # Kinase Production
        if (r>0 and r<rates[0]):
            K +=1
        #Kinase Degradation
        elif(r>rates[0] and r<sum(rates[0:2])):
            K -=1
        elif(r>rates[1] and r<sum(rates[0:3])):
            K -=1
        elif(r>rates[2] and r<sum(rates[0:4])):
            X0 +=1
        elif(r>rates[3] and r<sum(rates[0:5])):
            X0 -=1

        elif(r>rates[4] and r<sum(rates[0:6])):
            X1 +=1
        elif(r>rates[5] and r<sum(rates[0:7])):
            X1 -=1
        elif(r>rates[6] and r<sum(rates[0:8])):
            X1 +=1

        elif(r>rates[7] and r<sum(rates[0:9])):
            X2 +=1
        elif(r>rates[8] and r<sum(rates[0:10])):
            X2 -=1
        elif(r>rates[9] and r<sum(rates[0:11])):
            X2 +=1

        elif(r>rates[10] and r<sum(rates[0:12])):
            X3 +=1
        elif(r>rates[11] and r<sum(rates[0:13])):
            X3 -=1
        elif(r>rates[12] and r<sum(rates[0:14])):
            X3 +=1

        elif(r>rates[13] and r<sum(rates[0:15])):
            X4 +=1
        elif(r>rates[14] and r<sum(rates[0:16])):
            X4 -=1
        elif(r>rates[15] and r<sum(rates[0:17])):
            X4 +=1

        elif(r>rates[16] and r<sum(rates[0:18])):
            X5 +=1
        elif(r>rates[17] and r<sum(rates[0:19])):
            X5 -=1
        elif(r>rates[18] and r<sum(rates[0:20])):
            X5 +=1

        elif(r>rates[19] and r<sum(rates[0:21])):
            X6 +=1
        elif(r>rates[20] and r<sum(rates[0:22])):
            X6 -=1
        elif(r>rates[21] and r<sum(rates[0:23])):
            X6 +=1

        elif(r>rates[22] and r<sum(rates[0:24])):
            X7 +=1
        elif(r>rates[23] and r<sum(rates[0:25])):
            X7 -=1
        elif(r>rates[24] and r<sum(rates[0:26])):
            X7 +=1

        elif(r>rates[25] and r<sum(rates[0:27])):
            X8 +=1
        elif(r>rates[26] and r<sum(rates[0:28])):
            X8 -=1
        elif(r>rates[27] and r<sum(rates[0:29])):
            X8 +=1

        elif(r>rates[28] and r<sum(rates[0:30])):
            X9 +=1
        elif(r>rates[29] and r<sum(rates[0:31])):
            X9 -=1
        elif(r>rates[30] and r<sum(rates[0:32])):
            X9 +=1

        elif(r>rates[31] and r<sum(rates[0:33])):
            X10 +=1
        elif(r>rates[32] and r<sum(rates)):
            X10 -=1

        #H-=1
        time.append(t)
        mol_K.append(K)
#         mol_X0.append(X0)
#         mol_X1.append(X1)
#         mol_X2.append(X2)
#         mol_X3.append(X3)
#         mol_X4.append(X4)
#         mol_X5.append(X5)
#         mol_X6.append(X6)
#         mol_X7.append(X7)
#         mol_X8.append(X8)
#         mol_X9.append(X9)
#         mol_X10.append(X10)

    #plt.figure(figsize=(15,5))
    plt.plot(time,mol_K,label='R=%d'%H_val)
    #plt.plot(time,mol_X0,label='X0')
    #plt.plot(time,mol_X1,label='X1')
    # plt.plot(time,mol_X2,label='X2')
    # plt.plot(time,mol_X3,label='X3')
    # plt.plot(time,mol_X4,label='X4')
    # plt.plot(time,mol_X5,label='X5')
    # plt.plot(time,mol_X6,label='X6')
    # plt.plot(time,mol_X7,label='X7')
    #plt.plot(time,mol_X8,label='X8')
    # plt.plot(time,mol_X9,label='X9')
    # plt.plot(time,mol_X10,label='X10')

#     plt.title('Stochastic simulation')
#     plt.xlabel('Time(ms)')
#     plt.ylabel('K')
#     plt.legend()
#     #plt.show()
```

```python
#def stochas_KH(V_val,H_val,K_val,T_val):

for Hval in range(0,60,10):
    stochas_KH(20,Hval,20,1000)
#plt.ylim(0,50)
plt.title('Stochastic simulation V=20')
plt.xlabel('Time(ms)',fontsize=15)
plt.ylabel('T',fontsize=15)
plt.xticks(fontsize=15)
plt.yticks(fontsize=15)
plt.legend(loc='center right',fontsize=15)
plt.show()
```

```python
#def stochas_KH(V_val,H_val,K_val,T_val):

for Hval in range(300,700,100):
    stochas_KH(200,Hval,200,1000)
#plt.ylim(0,250)
#plt.title('Stochastic simulation V=200')
plt.xlabel('Time (ms)',fontsize=15)
plt.ylabel('T',fontsize=15)
plt.legend(loc='center right',fontsize=15)
plt.xticks(fontsize=15)
plt.yticks(fontsize=15)
plt.show()
```

### Plotting data from xppaut (Stochastic simulation)

```python
dft = pd.read_csv('tyson_curve_30i.dat', sep='\s+',names=['TR','K'])
#dft.plot(x='TR',y='K')
#plt.show()

dftr = dft[dft['TR']==0]
ind_tr = dftr.index
#lastK_val = []
#print(ind_tr)
ax = plt.gca()
for i in range(len(ind_tr)-1):
    dptemp = dft[ind_tr[i]:ind_tr[i+1]-1]
    #print(ind_tr[i])
    #print(dptemp)
#    plt.plot(dptemp)
    dptemp.plot(x='TR',y='K',ax=ax,legend=None)
plt.xlabel('Time (s)',fontsize=15)
plt.ylabel('Telomere Length (bp)',fontsize=15)
plt.xticks(fontsize=15)
plt.yticks(fontsize=15)
plt.show()
```

### Using XppAut transient

```python
df_transient = pd.read_csv('tyson_transient_data_300i.dat', sep='\s+',names=['TR','K'])
df_transient.plot(kind='scatter',x='TR',y='K')
plt.show()
```

### 300 iterations

```python
df_trans2_300i = pd.read_csv('tyson_trans_2par_30i.dat', sep='\s+',names=['TR','K'])
df_trans2_300i.plot(kind='scatter',x='TR',y='K')
plt.ylabel('Telomere Length (bp)',fontsize=15)
plt.xlabel('Time (s)',fontsize=15)
plt.xticks(fontsize=15)
plt.yticks(fontsize=15)
plt.show()

plt.hist(df_trans2_300i['K'],40)
#plt.title('Histogram',,fontsize=15)
plt.xlabel('Telomere Length (bp)',fontsize=15)
plt.ylabel('Count',fontsize=15)
plt.xticks(fontsize=15)
plt.yticks(fontsize=15)
plt.show()
```

```python

```

Literature Survey/Tyson's Bistability Model/Telomere Length Bistability.ipynb


```python
import pyzx as zx
import sympy
from fractions import Fraction
```

```python
gamma = sympy.Symbol('gamma')
```

```python
g=zx.graph.GraphSym()
v= g.add_vertex(zx.VertexType.Z, qubit=0, row=1, phase=gamma)
w= g.add_vertex(zx.VertexType.Z, qubit=1, row=1, phase=1)
x= g.add_vertex(zx.VertexType.Z, qubit=2, row=1, phase=1)
g.add_edge(g.edge(v,w),edgetype=zx.EdgeType.SIMPLE)
```

```python
zx.draw_matplotlib(g)
```

```python
g.phase(0)
```

```python
e = zx.editor.edit(g)
```

```python
gamma = sympy.Symbol('gamma')
```

```python
type(Fraction(numerator=2, denominator=1) * gamma)
```

```python

```


```python
from sympy import *
from sympy.abc import *
import numpy as np
import matplotlib.pyplot as plt
init_printing()
```

#### Example 4.11 pag 131

```python
a1, a2, C1 = symbols("A_1 A_2 C1")
U = Function("U")(t) # f is a function of x
du = Derivative(U, t)

e = Eq(du, rho*((V-U)**2)*(-a1 + a1*cos(theta)))
e
```

```python
#e = Eq(du, rho*((V-U)**2)*(-a1 + a2*cos(theta)))
en = e.subs({rho:999, a1:0.003, theta:np.radians(60), V:35})
en
```

```python
dsolve(en)
```

```python
s = dsolve(e)
s.subs({rho:999, a1:0.003, theta:np.radians(60), V:35, C1:0}).simplify()
```

#### Relatório de Lab de mec flu I: Tubo de pitot - 14/01/2022

```python
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import ZebraLib as zb

data = np.array([[2000, 13],
                [2200, 23],
                [2400, 31],
                [2600, 41],
                [2800, 54],
                [3000, 67]])

df = pd.DataFrame(data, columns=['RPM', 'L'])

df
```

      RPM
      L

      0
      2000
      13

      1
      2200
      23

      2
      2400
      31

      3
      2600
      41

      4
      2800
      54

      5
      3000
      67

```python
def dif_P(del_h):
    return 1E3*9.81*del_h

def Veloc(P):
    return ((2*P)/(1.184))**(1/2)

df['Lsen(theta)'] = df['L']*np.sin(np.radians(10))*1E-3
df['Del P'] = dif_P(df['Lsen(theta)'] )
df['V'] = Veloc(df['Del P'])

df
```

      RPM
      L
      Del P
      V
      Lsen(theta)

      0
      2000
      13
      22.145352
      6.116183
      0.002257

      1
      2200
      23
      39.180238
      8.135283
      0.003994

      2
      2400
      31
      52.808147
      9.444731
      0.005383

      3
      2600
      41
      69.843034
      10.861772
      0.007120

      4
      2800
      54
      91.988386
      12.465384
      0.009377

      5
      3000
      67
      114.133738
      13.885009
      0.011634

```python
poly = zb.fit(df['RPM'], df['V'], 1)

fig, ax = plt.subplots()
ax.set(xlabel='Rotação (RPM)', ylabel='Velocidade (m/s)')

ax.scatter(df['RPM'], df['V'], label='dados')
ax.plot(df['RPM'], poly(df['RPM']), ls='--', c='red', label=r'$p(x)=2.038x + 0.547$')

ax.grid(linestyle='dotted')
ax.legend()
fig.savefig('D:/fig.pdf', bbox_inches='tight')
```

## Exercício 5.5 - p. 189 FoxMcDonalds

```python
from sympy import *
from sympy.abc import *
import numpy as np
import matplotlib.pyplot as plt
init_printing()

import warnings
warnings.filterwarnings('ignore')
warnings.simplefilter('ignore')
```

```python
v1 = symbols('V_1')
u = v1*(1 + (x/L))
dudx = Derivative(u, x, evaluate=False)
u, dudx
```

```python
a = u*dudx
a
```

```python
a.simplify()
```

```python
solve(a)
```

```python
x0 = symbols('x_0')
a = Eq(log(x - x0), A*tau)
a
```

```python
solve(a, x)
```

```python
e**(a).simplify()
```

```python
g = integrate(1/x, (x, x0, x))
h = integrate(A, (t, 0, tau))
g
```

```python
h
```

```python
ss = Eq(g, h)
ss
```


```python
!pip install pygsl
```

    Collecting pygsl
    Requirement already satisfied: numpy in /opt/conda/lib/python3.6/site-packages (from pygsl) (1.16.0)
    Installing collected packages: pygsl
    Successfully installed pygsl-2.3.0

```python
%pylab inline
%config InlineBackend.figure_format = 'retina'
from ipywidgets import interact
import warnings
warnings.filterwarnings("ignore")
from pygsl import odeiv
matplotlib.style.use('ggplot')

class FHNmodel:
    def __init__(self, I, xc, a, epsilon):
        self.I = I
        self.xc = xc
        self.yc = xc*(-a - xc)*(xc - a) + I
        self.a = a
        self.epsilon = epsilon
    def rhs(self, x, y):
        return array([(x*(-self.a - x)*(x - self.a) - y + self.I)/self.epsilon, x - self.xc])
    def nullclines(self, x):
        return array([x*(-self.a - x)*(x - self.a) + self.I, (x - self.xc)/1e-3 ])
    def _rhs(self, t, z, pars):
        x = z[0]
        y = z[1]
        return self.rhs(x, y)
    def gslint(self, tpoints, y0):
        if isscalar(tpoints):
            tpoints = array([tpoints])
        #stepper = odeiv.step_rk2
        #stepper = odeiv.step_rk4
        #stepper = odeiv.step_rkf45
        #stepper = odeiv.step_rkck
        stepper = odeiv.step_rk8pd
        #stepper = odeiv.step_rk2imp
        # stepper = odeiv.step_rk4imp
        #stepper = odeiv.step_gear1
        #stepper = odeiv.step_gear2
        #stepper = odeiv.step_bsimp
        step = stepper(2, self._rhs, None)
        control = odeiv.control_y_new(step, 1e-12, 1e-12)
        evolve = odeiv.evolve(step, control, 2)
        t0 = 0.; h0 = 1e-4; t = t0; y = y0; h = h0;
        sol = {'x': zeros(tpoints.size)*nan,
               'y': zeros(tpoints.size)*nan}
        j = 0
        while (j < tpoints.size):
            while (t < tpoints[j]):
                t, h, y = evolve.apply(t, tpoints[j], h, y)
            sol['x'][j], sol['y'][j] = y[0], y[1]
            j += 1
        sol['t'] = tpoints
        return sol
```

    Populating the interactive namespace from numpy and matplotlib

# Fitz-Hugh Nagumo
\begin{align}
  \varepsilon \dot{x} &= x(-a - x)(x - a) - y \\
  \dot{y} &= x - x_{c}
\end{align}
At the fixed point, the Jacobian Matrix is
\begin{equation}
J = \frac{1}{\varepsilon}
  \begin{bmatrix}
    a^2 - 3 x_c^2 & -1 \\
    \varepsilon & 0
  \end{bmatrix}
\end{equation}
We have
\begin{equation}
{\rm Tr}(J) = \frac{a^2 - 3 x_c^2}{\varepsilon}, \quad
\vert J \vert = \frac{1}{\varepsilon}
\end{equation}
The eigenvalues are
\begin{equation}
  \lambda_{\pm} = \frac{1}{2\varepsilon}\left[a^2 - 3x_c^2 \pm \sqrt{\left(a^2 - 3x_c^2\right)^2 - 4\varepsilon}\right]
\end{equation}
The value of $x_c$ that causes a change in stability is
$$ x_c = \pm \frac{a}{\sqrt{3}}$$

```python
params = {
    'I': -0.25,
    'xc': -0.8/sqrt(3.) + 0.9,
    'epsilon': 0.02,
    'a': 0.8}

model = FHNmodel(**params)
y0 = (-0.25, -0.45)
tpoints = linspace(0, 6, 300)
sol = model.gslint(tpoints, y0)

fig = figure(1, [15, 5])

fig.add_subplot(121)
Xnc = linspace(-1, 1, 100)
Ync = model.nullclines(Xnc)
plot(Xnc, Ync[0], 'orange', lw=2, label='$\dot{x}=0$')
plot(Xnc, Ync[1], 'c', lw=2, label='$\dot{y}=0$')
plot(model.xc, model.yc, 'ko')

plot(sol['x'][0], sol['y'][0], 'kx')
plot(sol['x'], sol['y'], '--k')
ylim(-0.5, 0.3)
xlabel('$x$', fontsize=24)
ylabel('$y$', fontsize=24)
legend(fontsize=24);

fig.add_subplot(122)
plot(sol['t'], sol['x'], label='$x(t)$')
plot(sol['t'], sol['y'], label='$y(t)$')
xlabel('$t$', fontsize=24)
legend(fontsize=24);
```