\title{Addition in myHDL (In Progress)} \author{Steven K Armour} \maketitle

Libraries and Helper functions


In [1]:
from myhdl import *
from myhdlpeek import Peeker
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
%matplotlib inline

from sympy import *
init_printing()

import itertools

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


Out[1]:
SoftwareVersion
Python3.6.5 64bit [GCC 7.2.0]
IPython6.4.0
OSLinux 4.15.0 30 generic x86_64 with debian buster sid
myhdl0.10
myhdlpeek0.0.7
numpy1.14.3
pandas0.23.0
matplotlib2.2.2
sympy1.1.1
randomThe 'random' distribution was not found and is required by the application
itertoolsThe 'itertools' distribution was not found and is required by the application
Tue Aug 21 12:52:12 2018 MDT

In [2]:
#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

In [3]:
BitVals=[0,1]

Half Adder

myHDL Code


In [4]:
@block
def HalfAdder(x1, x2, s, c):
    """
    Half Adder
    Input:
        x1(bool): bit signal to be added
        x2(bool): bit signal to be added
    
    Output:
        s(bool): Half Adder Sum
        c(bool): Half Adder Carry

    """
    @always_comb
    def logic():
        s.next=x1 ^ x2
        c.next=x1 & x2
    
    return instances()

myHDL Testing


In [5]:
Peeker.clear()
x1=Signal(bool(0)); Peeker(x1, 'x1')
x2=Signal(bool(0)); Peeker(x2, 'x2')
s=Signal(bool(0)); Peeker(s, 's')
c=Signal(bool(0)); Peeker(c, 'c')

#generate test values
x1TVals=[i[0] for i in itertools.product(BitVals, repeat=len(BitVals))]
x2TVals=[i[1] for i in itertools.product(BitVals, repeat=len(BitVals))]

DUT=HalfAdder(x1, x2, s, c)


def HalfAdder_TB():
    """
    myHDL only Testbench for module "HalfAdder"
    """
    @instance
    def stimules():
        for i, j in zip(x1TVals, x2TVals):
            x1.next=i; x2.next=j
            yield delay(1)
        
        raise StopSimulation()
    
    return instances()

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

In [6]:
Peeker.to_wavedrom('x1', 'x2', 's', 'c')



In [7]:
HalfAdderData=Peeker.to_dataframe()
HalfAdderData=HalfAdderData[['x1', 'x2', 's', 'c']]
HalfAdderData


Out[7]:
x1 x2 s c
0 0 0 0 0
1 0 1 1 0
2 1 0 1 0
3 1 1 0 1

In [8]:
HalfAdderData['sCheck']=HalfAdderData.apply(lambda row: row['x1']^row['x2'], axis=1)
HalfAdderData['cCheck']=HalfAdderData.apply(lambda row: row['x1']&row['x2'], axis=1)
HalfAdderData


Out[8]:
x1 x2 s c sCheck cCheck
0 0 0 0 0 0 0
1 0 1 1 0 1 0
2 1 0 1 0 1 0
3 1 1 0 1 0 1

In [9]:
SumCheck=(HalfAdderData['s']==HalfAdderData['sCheck']).all()
CarryCheck=(HalfAdderData['c']==HalfAdderData['cCheck']).all()
print(f'Sum Result Check: {SumCheck}; Carry Result Check: {CarryCheck}')


Sum Result Check: True; Carry Result Check: True

Verilog Code


In [10]:
DUT.convert()
VerilogTextReader('HalfAdder');


***Verilog modual from HalfAdder.v***

 // File: HalfAdder.v
// Generated by MyHDL 0.10
// Date: Tue Aug 21 12:52:14 2018


`timescale 1ns/10ps

module HalfAdder (
    x1,
    x2,
    s,
    c
);
// Half Adder
// Input:
//     x1(bool): bit signal to be added
//     x2(bool): bit signal to be added
// 
// Output:
//     s(bool): Half Adder Sum
//     c(bool): Half Adder Carry

input x1;
input x2;
output s;
wire s;
output c;
wire c;





assign s = (x1 ^ x2);
assign c = (x1 & x2);

endmodule

Verilog Testbench


In [11]:
#generate test values
x1TVals=[i[0] for i in itertools.product(BitVals, repeat=len(BitVals))]
x2TVals=[i[1] for i in itertools.product(BitVals, repeat=len(BitVals))]
#create single value representation of Test Inputs
x1TVal=intbv(int(''.join([str(i) for i in x1TVals]), 2))[len(x1TVals):]
x2TVal=intbv(int(''.join([str(i) for i in x2TVals]), 2))[len(x2TVals):]

In [12]:
print(f'x1Test: {x1TVals}, {x1TVal}, {[int(i) for i in x1TVal]}')
print(f'x2Test: {x2TVals}, {x2TVal}, {[int(i) for i in x2TVal]}')


x1Test: [0, 0, 1, 1], 3, [0, 0, 1, 1]
x2Test: [0, 1, 0, 1], 5, [0, 1, 0, 1]

In [13]:
@block
def HalfAdder_TBV():
    """
    myHDL -> Verilog Testbench for module "HalfAdder"
    """
    x1=Signal(bool(0))
    x2=Signal(bool(0))
    s=Signal(bool(0))
    c=Signal(bool(0))
    
    #test stimuli
    x1TVals=Signal(x1TVal)
    x2TVals=Signal(x2TVal)
    
    @always_comb
    def print_data():
        print(x1, x2, s, c)

    DUT=HalfAdder(x1, x2, s, c)

    @instance
    def stimules():
        for i in range(len(x1TVal)):
            x1.next=x1TVals[i]; x2.next=x2TVals[i]
            yield delay(1)
        
        raise StopSimulation()
    
    return instances()

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


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

 // File: HalfAdder_TBV.v
// Generated by MyHDL 0.10
// Date: Tue Aug 21 12:52:14 2018


`timescale 1ns/10ps

module HalfAdder_TBV (

);
// myHDL -> Verilog Testbench for module "HalfAdder"


reg x1 = 0;
reg x2 = 0;
wire s;
wire c;
wire [3:0] x1TVals;
wire [3:0] x2TVals;

assign x1TVals = 4'd3;
assign x2TVals = 4'd5;


always @(s, x2, c, x1) begin: HALFADDER_TBV_PRINT_DATA
    $write("%h", x1);
    $write(" ");
    $write("%h", x2);
    $write(" ");
    $write("%h", s);
    $write(" ");
    $write("%h", c);
    $write("\n");
end



assign s = (x1 ^ x2);
assign c = (x1 & x2);


initial begin: HALFADDER_TBV_STIMULES
    integer i;
    for (i=0; i<4; i=i+1) begin
        x1 <= x1TVals[i];
        x2 <= x2TVals[i];
        # 1;
    end
    $finish;
end

endmodule

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

Full Adder From Exspresion

myHDL Code


In [14]:
@block
def FullAdder(x1, x2, cin, s, c):
    """
    Full Adder 2bit+1 input from exspresion
    Input:
        x1(bool): bit signal to be added
        x2(bool): bit signal to be added
        cin(bool): carry in bit signal
    
    Output:
        s(bool): Full Adder Sum
        c(bool): Full Adder Carry

    """
    @always_comb
    def logic():
        s.next=x1^x2^cin
        c.next=(x1&x2) | (x1&cin) | (x2&cin)
    
    return instances()

myHDL Testing


In [15]:
Peeker.clear()
x1=Signal(bool(0)); Peeker(x1, 'x1')
x2=Signal(bool(0)); Peeker(x2, 'x2')
cin=Signal(bool(0)); Peeker(cin, 'cin')
s=Signal(bool(0)); Peeker(s, 's')
c=Signal(bool(0)); Peeker(c, 'c')

#generate test values
x1TVals=[i[0] for i in itertools.product(BitVals, repeat=len(BitVals)+1)]
x2TVals=[i[1] for i in itertools.product(BitVals, repeat=len(BitVals)+1)]
cinTVals=[i[2] for i in itertools.product(BitVals, repeat=len(BitVals)+1)]

DUT=FullAdder(x1, x2, cin, s, c)


def FullAdder_TB():
    """
    myHDL only Testbench for module "FullAdder"
    """
    @instance
    def stimules():
        for i, j, k in zip(x1TVals, x2TVals, cinTVals):
            x1.next=i; x2.next=j; cin.next=k
            yield delay(1)
        
        raise StopSimulation()
    
    return instances()

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

In [16]:
Peeker.to_wavedrom('x1', 'x2', 'cin', 's', 'c')



In [17]:
FullAdderData=Peeker.to_dataframe()
FullAdderData=FullAdderData[['x1', 'x2', 'cin', 's', 'c']]
FullAdderData


Out[17]:
x1 x2 cin s c
0 0 0 0 0 0
1 0 0 1 1 0
2 0 1 0 1 0
3 0 1 1 0 1
4 1 0 0 1 0
5 1 0 1 0 1
6 1 1 0 0 1
7 1 1 1 1 1

In [18]:
FullAdderData['sCheck']=FullAdderData.apply(lambda row: row['x1']^row['x2']^row['cin'], axis=1)
FullAdderData['cCheck']=FullAdderData.apply(lambda row: (row['x1']&row['x2'])|(row['cin']*(row['x1']^row['x2'])), axis=1)
FullAdderData


Out[18]:
x1 x2 cin s c sCheck cCheck
0 0 0 0 0 0 0 0
1 0 0 1 1 0 1 0
2 0 1 0 1 0 1 0
3 0 1 1 0 1 0 1
4 1 0 0 1 0 1 0
5 1 0 1 0 1 0 1
6 1 1 0 0 1 0 1
7 1 1 1 1 1 1 1

In [19]:
SumCheck=(FullAdderData['s']==FullAdderData['sCheck']).all()
CarryCheck=(FullAdderData['c']==FullAdderData['cCheck']).all()
print(f'Sum Result Check: {SumCheck}; Carry Result Check: {CarryCheck}')


Sum Result Check: True; Carry Result Check: True

Verilog Code


In [20]:
DUT.convert()
VerilogTextReader('FullAdder');


***Verilog modual from FullAdder.v***

 // File: FullAdder.v
// Generated by MyHDL 0.10
// Date: Tue Aug 21 12:52:15 2018


`timescale 1ns/10ps

module FullAdder (
    x1,
    x2,
    cin,
    s,
    c
);
// Full Adder 2bit+1 input from exspresion
// Input:
//     x1(bool): bit signal to be added
//     x2(bool): bit signal to be added
//     cin(bool): carry in bit signal
// 
// Output:
//     s(bool): Full Adder Sum
//     c(bool): Full Adder Carry

input x1;
input x2;
input cin;
output s;
wire s;
output c;
wire c;





assign s = ((x1 ^ x2) ^ cin);
assign c = (((x1 & x2) | (x1 & cin)) | (x2 & cin));

endmodule

Verilog Testbench


In [21]:
#generate test values
x1TVals=[i[0] for i in itertools.product(BitVals, repeat=len(BitVals)+1)]
x2TVals=[i[1] for i in itertools.product(BitVals, repeat=len(BitVals)+1)]
cinTVals=[i[2] for i in itertools.product(BitVals, repeat=len(BitVals)+1)]

#create single value representation of Test Inputs
x1TVal=intbv(int(''.join([str(i) for i in x1TVals]), 2))[len(x1TVals):]
x2TVal=intbv(int(''.join([str(i) for i in x2TVals]), 2))[len(x2TVals):]
cinTVal=intbv(int(''.join([str(i) for i in cinTVals]), 2))[len(cinTVals):]

In [22]:
print(f'x1Test: {x1TVals}, {x1TVal}, {[int(i) for i in x1TVal]}')
print(f'x2Test: {x2TVals}, {x2TVal}, {[int(i) for i in x2TVal]}')
print(f'cinTest: {cinTVals}, {cinTVal}, {[int(i) for i in cinTVal]}')


x1Test: [0, 0, 0, 0, 1, 1, 1, 1], 0f, [0, 0, 0, 0, 1, 1, 1, 1]
x2Test: [0, 0, 1, 1, 0, 0, 1, 1], 33, [0, 0, 1, 1, 0, 0, 1, 1]
cinTest: [0, 1, 0, 1, 0, 1, 0, 1], 55, [0, 1, 0, 1, 0, 1, 0, 1]

In [23]:
@block
def FullAdder_TBV():
    """
    myHDL -> Verilog Testbench for module "FullAdder"
    """
    x1=Signal(bool(0))
    x2=Signal(bool(0))
    cin=Signal(bool(0))
    s=Signal(bool(0))
    c=Signal(bool(0))
    
    #test stimuli
    x1TVals=Signal(x1TVal)
    x2TVals=Signal(x2TVal)
    cinTVals=Signal(cinTVal)
    
    @always_comb
    def print_data():
        print(x1, x2, cin, s, c)

    DUT=FullAdder(x1, x2, cin, s, c)

    @instance
    def stimules():
        for i in range(len(x1TVal)):
            x1.next=x1TVals[i]; x2.next=x2TVals[i]; cin.next=cinTVals[i]
            yield delay(1)
        
        raise StopSimulation()
    
    return instances()

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


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

 // File: FullAdder_TBV.v
// Generated by MyHDL 0.10
// Date: Tue Aug 21 12:52:16 2018


`timescale 1ns/10ps

module FullAdder_TBV (

);
// myHDL -> Verilog Testbench for module "FullAdder"


reg x1 = 0;
reg x2 = 0;
wire s;
wire c;
wire [7:0] x1TVals;
wire [7:0] x2TVals;
reg cin = 0;
wire [7:0] cinTVals;

assign x1TVals = 8'd15;
assign x2TVals = 8'd51;
assign cinTVals = 8'd85;


always @(x2, c, s, cin, x1) begin: FULLADDER_TBV_PRINT_DATA
    $write("%h", x1);
    $write(" ");
    $write("%h", x2);
    $write(" ");
    $write("%h", cin);
    $write(" ");
    $write("%h", s);
    $write(" ");
    $write("%h", c);
    $write("\n");
end



assign s = ((x1 ^ x2) ^ cin);
assign c = (((x1 & x2) | (x1 & cin)) | (x2 & cin));


initial begin: FULLADDER_TBV_STIMULES
    integer i;
    for (i=0; i<8; i=i+1) begin
        x1 <= x1TVals[i];
        x2 <= x2TVals[i];
        cin <= cinTVals[i];
        # 1;
    end
    $finish;
end

endmodule

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

Full Adder via HalfAdders

myHDL Code


In [24]:
@block
def FullAdderViaHAs(x1, x2, cin, s, c):
    """
    Full Adder 2bit+1 input from Half Adders
    Input:
        x1(bool): bit signal to be added
        x2(bool): bit signal to be added
        cin(bool): carry in bit signal
    
    Output:
        s(bool): Full Adder Sum
        c(bool): Full Adder Carry

    """
    #create ouput wires from first HA (HA1) to next HA and 
    #`CarryLogic`
    s_HA1HA2=Signal(bool(0)); c_HA1CL=Signal(bool(0))
    #create first HA and wire it
    HA1_x1x2=HalfAdder(x1=x1, x2=x2, s=s_HA1HA2, c=c_HA1CL)
    
    #create output wire for seconed HA (HA2) to `CarryLogic`
    c_HA2CL=Signal(bool(0))
    HA2_HA1cin=HalfAdder(x1=cin, x2=s_HA1HA2, s=s, c=c_HA2CL)

    @always_comb
    def CarryLogic():
        c.next= c_HA1CL|c_HA2CL
    
    return instances()

myHDL Testing


In [25]:
Peeker.clear()
x1=Signal(bool(0)); Peeker(x1, 'x1')
x2=Signal(bool(0)); Peeker(x2, 'x2')
cin=Signal(bool(0)); Peeker(cin, 'cin')
s=Signal(bool(0)); Peeker(s, 's')
c=Signal(bool(0)); Peeker(c, 'c')

#generate test values
x1TVals=[i[0] for i in itertools.product(BitVals, repeat=len(BitVals)+1)]
x2TVals=[i[1] for i in itertools.product(BitVals, repeat=len(BitVals)+1)]
cinTVals=[i[2] for i in itertools.product(BitVals, repeat=len(BitVals)+1)]

DUT=FullAdderViaHAs(x1, x2, cin, s, c)


def FullAdderViaHAs_TB():
    """
    myHDL only Testbench for module "FullAdderViaHAs"
    """
    @instance
    def stimules():
        for i, j, k in zip(x1TVals, x2TVals, cinTVals):
            x1.next=i; x2.next=j; cin.next=k
            yield delay(1)
        
        raise StopSimulation()
    
    return instances()

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

In [26]:
Peeker.to_wavedrom('x1', 'x2', 'cin', 's', 'c')



In [27]:
FullAdderHAData=Peeker.to_dataframe()
FullAdderHAData=FullAdderHAData[['x1', 'x2', 'cin', 's', 'c']]
FullAdderHAData


Out[27]:
x1 x2 cin s c
0 0 0 0 0 0
1 0 0 1 1 0
2 0 1 0 1 0
3 0 1 1 0 1
4 1 0 0 1 0
5 1 0 1 0 1
6 1 1 0 0 1
7 1 1 1 1 1

In [28]:
FullAdderHAData['sCheck']=FullAdderHAData.apply(lambda row: row['x1']^row['x2']^row['cin'], axis=1)
FullAdderHAData['cCheck']=FullAdderHAData.apply(lambda row: (row['x1']&row['x2'])|(row['cin']*(row['x1']^row['x2'])), axis=1)
FullAdderHAData


Out[28]:
x1 x2 cin s c sCheck cCheck
0 0 0 0 0 0 0 0
1 0 0 1 1 0 1 0
2 0 1 0 1 0 1 0
3 0 1 1 0 1 0 1
4 1 0 0 1 0 1 0
5 1 0 1 0 1 0 1
6 1 1 0 0 1 0 1
7 1 1 1 1 1 1 1

In [29]:
SumCheck=(FullAdderHAData['s']==FullAdderHAData['sCheck']).all()
CarryCheck=(FullAdderHAData['c']==FullAdderHAData['cCheck']).all()
print(f'Sum Result Check: {SumCheck}; Carry Result Check: {CarryCheck}')


Sum Result Check: True; Carry Result Check: True

In [30]:
(FullAdderData==FullAdderHAData).all()


Out[30]:
x1        True
x2        True
cin       True
s         True
c         True
sCheck    True
cCheck    True
dtype: bool

Verilog Code


In [31]:
DUT.convert()
VerilogTextReader('FullAdderViaHAs');


***Verilog modual from FullAdderViaHAs.v***

 // File: FullAdderViaHAs.v
// Generated by MyHDL 0.10
// Date: Tue Aug 21 12:52:18 2018


`timescale 1ns/10ps

module FullAdderViaHAs (
    x1,
    x2,
    cin,
    s,
    c
);
// Full Adder 2bit+1 input from Half Adders
// Input:
//     x1(bool): bit signal to be added
//     x2(bool): bit signal to be added
//     cin(bool): carry in bit signal
// 
// Output:
//     s(bool): Full Adder Sum
//     c(bool): Full Adder Carry

input x1;
input x2;
input cin;
output s;
wire s;
output c;
wire c;

wire s_HA1HA2;
wire c_HA1CL;
wire c_HA2CL;




assign s_HA1HA2 = (x1 ^ x2);
assign c_HA1CL = (x1 & x2);



assign s = (cin ^ s_HA1HA2);
assign c_HA2CL = (cin & s_HA1HA2);



assign c = (c_HA1CL | c_HA2CL);

endmodule

Verilog Testbench


In [32]:
#generate test values
x1TVals=[i[0] for i in itertools.product(BitVals, repeat=len(BitVals)+1)]
x2TVals=[i[1] for i in itertools.product(BitVals, repeat=len(BitVals)+1)]
cinTVals=[i[2] for i in itertools.product(BitVals, repeat=len(BitVals)+1)]

#create single value representation of Test Inputs
x1TVal=intbv(int(''.join([str(i) for i in x1TVals]), 2))[len(x1TVals):]
x2TVal=intbv(int(''.join([str(i) for i in x2TVals]), 2))[len(x2TVals):]
cinTVal=intbv(int(''.join([str(i) for i in cinTVals]), 2))[len(cinTVals):]

In [33]:
print(f'x1Test: {x1TVals}, {x1TVal}, {[int(i) for i in x1TVal]}')
print(f'x2Test: {x2TVals}, {x2TVal}, {[int(i) for i in x2TVal]}')
print(f'cinTest: {cinTVals}, {cinTVal}, {[int(i) for i in cinTVal]}')


x1Test: [0, 0, 0, 0, 1, 1, 1, 1], 0f, [0, 0, 0, 0, 1, 1, 1, 1]
x2Test: [0, 0, 1, 1, 0, 0, 1, 1], 33, [0, 0, 1, 1, 0, 0, 1, 1]
cinTest: [0, 1, 0, 1, 0, 1, 0, 1], 55, [0, 1, 0, 1, 0, 1, 0, 1]

In [34]:
@block
def FullAdderViaHAs_TBV():
    """
    myHDL -> Verilog Testbench for module "FullAdderViaHAs"
    """
    x1=Signal(bool(0))
    x2=Signal(bool(0))
    cin=Signal(bool(0))
    s=Signal(bool(0))
    c=Signal(bool(0))
    
    #test stimuli
    x1TVals=Signal(x1TVal)
    x2TVals=Signal(x2TVal)
    cinTVals=Signal(cinTVal)
    
    @always_comb
    def print_data():
        print(x1, x2, cin, s, c)

    DUT=FullAdderViaHAs(x1, x2, cin, s, c)

    @instance
    def stimules():
        for i in range(len(x1TVal)):
            x1.next=x1TVals[i]; x2.next=x2TVals[i]; cin.next=cinTVals[i]
            yield delay(1)
        
        raise StopSimulation()
    
    return instances()

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


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

 // File: FullAdderViaHAs_TBV.v
// Generated by MyHDL 0.10
// Date: Tue Aug 21 12:52:20 2018


`timescale 1ns/10ps

module FullAdderViaHAs_TBV (

);
// myHDL -> Verilog Testbench for module "FullAdderViaHAs"


reg x1 = 0;
reg x2 = 0;
wire s;
wire c;
wire [7:0] x1TVals;
wire [7:0] x2TVals;
reg cin = 0;
wire [7:0] cinTVals;
wire FullAdderViaHAs0_0_s_HA1HA2;
wire FullAdderViaHAs0_0_c_HA1CL;
wire FullAdderViaHAs0_0_c_HA2CL;

assign x1TVals = 8'd15;
assign x2TVals = 8'd51;
assign cinTVals = 8'd85;


always @(x2, c, s, cin, x1) begin: FULLADDERVIAHAS_TBV_PRINT_DATA
    $write("%h", x1);
    $write(" ");
    $write("%h", x2);
    $write(" ");
    $write("%h", cin);
    $write(" ");
    $write("%h", s);
    $write(" ");
    $write("%h", c);
    $write("\n");
end



assign FullAdderViaHAs0_0_s_HA1HA2 = (x1 ^ x2);
assign FullAdderViaHAs0_0_c_HA1CL = (x1 & x2);



assign s = (cin ^ FullAdderViaHAs0_0_s_HA1HA2);
assign FullAdderViaHAs0_0_c_HA2CL = (cin & FullAdderViaHAs0_0_s_HA1HA2);



assign c = (FullAdderViaHAs0_0_c_HA1CL | FullAdderViaHAs0_0_c_HA2CL);


initial begin: FULLADDERVIAHAS_TBV_STIMULES
    integer i;
    for (i=0; i<8; i=i+1) begin
        x1 <= x1TVals[i];
        x2 <= x2TVals[i];
        cin <= cinTVals[i];
        # 1;
    end
    $finish;
end

endmodule

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

4 Bit Ripple Carry

myHDL Code


In [35]:
@block
def RippleCarry4Bit(X1, X2, cin, S, c):
    """
    4 Bit Ripple Carray Adder
    Input:
    Output:
    """
    
    S_i = [Signal(bool(0)) for _ in range(len(S))]   # Sum bit for each stage.
    
    #create intercontect wire between FA0 and FA1 and intialze FA0 and wire up
    c_FA0FA1=Signal(bool(0))
    FA0=FullAdder(x1=X1(0), x2=X2(0), cin=cin, s=S_i[0], c=c_FA0FA1)
    
    c_FA1FA2=Signal(bool(0))
    FA1=FullAdder(x1=X1(1), x2=X2(1), cin=c_FA0FA1, s=S_i[1], c=c_FA1FA2)
    
    c_FA2FA3=Signal(bool(0))
    FA2=FullAdder(x1=X1(2), x2=X2(2), cin=c_FA1FA2, s=S_i[2], c=c_FA2FA3)
    
    FA3=FullAdder(x1=X1(3), x2=X2(3), cin=c_FA2FA3, s=S_i[3], c=c)

    #concat bus wires to single bitvec wire
    @always_comb
    def ConCatSum():
        S.next=concat(S_i[3], S_i[2], S_i[1], S_i[0])

    
    return instances()

myHDL Testing


In [36]:
BitSize=4
np.random.seed(12)
X1TVals=np.random.randint(0, 2**BitSize, 2**BitSize)
X2TVals=np.random.randint(0, 2**BitSize, 2**BitSize)
cinTVals=np.random.randint(0,2,2**BitSize)

print(X1TVals)
print(X2TVals)
print(cinTVals)


[11 11  6 13  1  2  3  3 12  0  6  1  4  5 13  9]
[ 2 11  6 10  0  5  8 12 13  2  9  3 14  4  3  1]
[0 1 1 0 0 0 0 0 0 0 1 1 1 1 0 0]

In [37]:
Peeker.clear()
X1=Signal(intbv(0)[BitSize:]); Peeker(X1, 'X1')
X2=Signal(intbv(0)[BitSize:]); Peeker(X2, 'X2')
cin=Signal(bool(0)); Peeker(cin, 'cin')
S=Signal(intbv(0)[BitSize:]); Peeker(S, 'S')
c=Signal(bool(0)); Peeker(c, 'c')

DUT = RippleCarry4Bit(X1=X1, X2=X2, cin=cin, S=S, c=c)

def RippleCarry4Bit_TB():
    @instance
    def stimules():
        for i in range(len(X1TVals)):
            X1.next=int(X1TVals[i])
            X2.next=int(X2TVals[i])
            cin.next=int(cinTVals[i])
            yield delay(1)
        
        raise StopSimulation()

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

In [38]:
Peeker.to_wavedrom('cin', 'X1', 'X2', 'S', 'c')



In [39]:
RC4BData=Peeker.to_dataframe()
RC4BData=RC4BData[['cin', 'X1', 'X2', 'S', 'c']]
RC4BData


Out[39]:
cin X1 X2 S c
0 0 11 2 13 0
1 1 11 11 7 1
2 1 6 6 13 0
3 0 13 10 7 1
4 0 1 0 1 0
5 0 2 5 7 0
6 0 3 8 11 0
7 0 3 12 15 0
8 0 12 13 9 1
9 0 0 2 2 0
10 1 6 9 0 1
11 1 1 3 5 0
12 1 4 14 3 1
13 1 5 4 10 0
14 0 13 3 0 1
15 0 9 1 10 0

In [40]:
def RC4B_SCheck(cin, X1, X2):
    S=cin+X1+X2
    if S<16:
        return S
    else:
        return S-16
def RC4B_cCheck(cin, X1, X2):
    S=cin+X1+X2
    if S<16:
        return 0
    else:
        return 1

RC4BData['SCheck']=RC4BData.apply(lambda row: RC4B_SCheck(row['cin'], row['X1'], row['X2']), axis=1)
RC4BData['cCheck']=RC4BData.apply(lambda row: RC4B_cCheck(row['cin'], row['X1'], row['X2']), axis=1)
RC4BData


Out[40]:
cin X1 X2 S c SCheck cCheck
0 0 11 2 13 0 13 0
1 1 11 11 7 1 7 1
2 1 6 6 13 0 13 0
3 0 13 10 7 1 7 1
4 0 1 0 1 0 1 0
5 0 2 5 7 0 7 0
6 0 3 8 11 0 11 0
7 0 3 12 15 0 15 0
8 0 12 13 9 1 9 1
9 0 0 2 2 0 2 0
10 1 6 9 0 1 0 1
11 1 1 3 5 0 5 0
12 1 4 14 3 1 3 1
13 1 5 4 10 0 10 0
14 0 13 3 0 1 0 1
15 0 9 1 10 0 10 0

In [41]:
SumCheck=(RC4BData['S']==RC4BData['SCheck']).all()
CarryCheck=(RC4BData['c']==RC4BData['cCheck']).all()
print(f'Sum Result Check: {SumCheck}; Carry Result Check: {CarryCheck}')


Sum Result Check: True; Carry Result Check: True

In [42]:
DUT.convert()
VerilogTextReader('RippleCarry4Bit');


***Verilog modual from RippleCarry4Bit.v***

 // File: RippleCarry4Bit.v
// Generated by MyHDL 0.10
// Date: Tue Aug 21 12:52:22 2018


`timescale 1ns/10ps

module RippleCarry4Bit (
    X1,
    X2,
    cin,
    S,
    c
);
// 4 Bit Ripple Carray Adder
// Input:
// Output:

input [3:0] X1;
input [3:0] X2;
input cin;
output [3:0] S;
wire [3:0] S;
output c;
wire c;

wire c_FA0FA1;
wire FullAdder1_0_c;
wire FullAdder2_c;
wire S_i [0:4-1];




assign S_i[0] = ((X1[0] ^ X2[0]) ^ cin);
assign c_FA0FA1 = (((X1[0] & X2[0]) | (X1[0] & cin)) | (X2[0] & cin));



assign S_i[1] = ((X1[1] ^ X2[1]) ^ c_FA0FA1);
assign FullAdder1_0_c = (((X1[1] & X2[1]) | (X1[1] & c_FA0FA1)) | (X2[1] & c_FA0FA1));



assign S_i[2] = ((X1[2] ^ X2[2]) ^ FullAdder1_0_c);
assign FullAdder2_c = (((X1[2] & X2[2]) | (X1[2] & FullAdder1_0_c)) | (X2[2] & FullAdder1_0_c));



assign S_i[3] = ((X1[3] ^ X2[3]) ^ FullAdder2_c);
assign c = (((X1[3] & X2[3]) | (X1[3] & FullAdder2_c)) | (X2[3] & FullAdder2_c));



assign S = {S_i[3], S_i[2], S_i[1], S_i[0]};

endmodule

Verilog Testbench

Conversion Issue

Values are not beeing set to X1TVals and X1TVals in RippleCarry4Bit_TBV thus the running the simultion results in High Z values for each time stamp


In [43]:
X1TVal=[intbv(int(i))[BitSize:] for i in X1TVals]
X2TVal=[intbv(int(i))[BitSize:] for i in X2TVals]
cinTVal=intbv(int(''.join([str(i) for i in cinTVals]), 2))[len(cinTVals):]

print(X1TVal)
print(X2TVal)
print(cinTVal)


[intbv(11), intbv(11), intbv(6), intbv(13), intbv(1), intbv(2), intbv(3), intbv(3), intbv(12), intbv(0), intbv(6), intbv(1), intbv(4), intbv(5), intbv(13), intbv(9)]
[intbv(2), intbv(11), intbv(6), intbv(10), intbv(0), intbv(5), intbv(8), intbv(12), intbv(13), intbv(2), intbv(9), intbv(3), intbv(14), intbv(4), intbv(3), intbv(1)]
603c

In [44]:
@block
def RippleCarry4Bit_TBV():
    """
    myHDL -> Verilog Testbench for module "FullAdderViaHAs"
    """
    X1=Signal(intbv(0)[BitSize:])
    X2=Signal(intbv(0)[BitSize:])
    cin=Signal(bool(0))
    S=Signal(intbv(0)[BitSize:])
    c=Signal(bool(0))

    
    #test stimuli
    X1TVals=[Signal(i) for i in X1TVal]
    X2TVals=[Signal(i) for i in X2TVal]
    cinTVals=Signal(cinTVal)
    
    @always_comb
    def print_data():
        print(X1, X2, cin, S, c)

    DUT=RippleCarry4Bit(X1=X1, X2=X2, cin=cin, S=S, c=c)

    @instance
    def stimules():
        for i in range(len(X1TVals)):
            X1.next=X1TVals[i]
            X2.next=X2TVals[i]
            cin.next=cinTVals[i]
            yield delay(1)
        
        raise StopSimulation()

    return instances()


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


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

 // File: RippleCarry4Bit_TBV.v
// Generated by MyHDL 0.10
// Date: Tue Aug 21 12:52:25 2018


`timescale 1ns/10ps

module RippleCarry4Bit_TBV (

);
// myHDL -> Verilog Testbench for module "FullAdderViaHAs"


wire [3:0] S;
wire c;
reg cin = 0;
wire [15:0] cinTVals;
reg [3:0] X1 = 0;
reg [3:0] X2 = 0;
wire RippleCarry4Bit0_0_c_FA0FA1;
wire RippleCarry4Bit0_0_FullAdder1_0_1_c;
wire RippleCarry4Bit0_0_FullAdder2_0_c;
wire [3:0] X1TVals [0:16-1];
wire [3:0] X2TVals [0:16-1];
wire RippleCarry4Bit0_0_S_i [0:4-1];

assign cinTVals = 16'd24636;


always @(c, X1, cin, X2, S) begin: RIPPLECARRY4BIT_TBV_PRINT_DATA
    $write("%h", X1);
    $write(" ");
    $write("%h", X2);
    $write(" ");
    $write("%h", cin);
    $write(" ");
    $write("%h", S);
    $write(" ");
    $write("%h", c);
    $write("\n");
end



assign RippleCarry4Bit0_0_S_i[0] = ((X1[0] ^ X2[0]) ^ cin);
assign RippleCarry4Bit0_0_c_FA0FA1 = (((X1[0] & X2[0]) | (X1[0] & cin)) | (X2[0] & cin));



assign RippleCarry4Bit0_0_S_i[1] = ((X1[1] ^ X2[1]) ^ RippleCarry4Bit0_0_c_FA0FA1);
assign RippleCarry4Bit0_0_FullAdder1_0_1_c = (((X1[1] & X2[1]) | (X1[1] & RippleCarry4Bit0_0_c_FA0FA1)) | (X2[1] & RippleCarry4Bit0_0_c_FA0FA1));



assign RippleCarry4Bit0_0_S_i[2] = ((X1[2] ^ X2[2]) ^ RippleCarry4Bit0_0_FullAdder1_0_1_c);
assign RippleCarry4Bit0_0_FullAdder2_0_c = (((X1[2] & X2[2]) | (X1[2] & RippleCarry4Bit0_0_FullAdder1_0_1_c)) | (X2[2] & RippleCarry4Bit0_0_FullAdder1_0_1_c));



assign RippleCarry4Bit0_0_S_i[3] = ((X1[3] ^ X2[3]) ^ RippleCarry4Bit0_0_FullAdder2_0_c);
assign c = (((X1[3] & X2[3]) | (X1[3] & RippleCarry4Bit0_0_FullAdder2_0_c)) | (X2[3] & RippleCarry4Bit0_0_FullAdder2_0_c));



assign S = {RippleCarry4Bit0_0_S_i[3], RippleCarry4Bit0_0_S_i[2], RippleCarry4Bit0_0_S_i[1], RippleCarry4Bit0_0_S_i[0]};


initial begin: RIPPLECARRY4BIT_TBV_STIMULES
    integer i;
    for (i=0; i<16; i=i+1) begin
        X1 <= X1TVals[i];
        X2 <= X2TVals[i];
        cin <= cinTVals[i];
        # 1;
    end
    $finish;
end

endmodule

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

N Bit Ripple Carray Adder


In [45]:
@block
def RippleCarryNBit(X1, X2, cin, S, c):
    """
    N Bit Ripple Carray Adder
    Input:
    Output:
    """
    
    S_i = [Signal(bool(0)) for _ in range(len(S))]   # Sum bit for each stage.
    c_FAiFAj=[Signal(bool(0)) for _ in range(len(S)-1)]
    
    FAStages=[]
    
    for i in range(len(S)):
        if i==0:
            FAStages.append(FullAdder(x1=X1(i), x2=X2(i), cin=cin, s=S_i[i], c=c_FAiFAj[i]))
        elif i<(len(S)-1):
            FAStages.append(FullAdder(x1=X1(i), x2=X2(i), cin=c_FAiFAj[i-1], s=S_i[i], c=c_FAiFAj[i]))
        else:
            FAStages.append(FullAdder(x1=X1(i), x2=X2(i), cin=c_FAiFAj[i-1], s=S_i[i], c=c))



    #concat bus wires to single bitvec wire
    @always_comb
    def ConCatSum():
        S.next=concat(*reversed(S_i))

    
    return instances()

myHDL Testing


In [46]:
BitSize=16
np.random.seed(12)
X1TVals=np.random.randint(0, 2**BitSize, 2**4)
X2TVals=np.random.randint(0, 2**BitSize, 2**4)
cinTVals=np.random.randint(0,2,2**4)

print(X1TVals)
print(X2TVals)
print(cinTVals)


[14155 38555 58758 19709 40177 36482  9475 63427 12108 61872   278 57393
 16308 49029 20109 20953]
[41378  8651  9846  5194 63872 11637 17512 19660 48397 36946 57433  9507
  4030 48228  4515 40353]
[0 1 1 0 0 0 0 0 0 0 1 1 1 1 0 0]

In [47]:
Peeker.clear()
X1=Signal(intbv(0)[BitSize:]); Peeker(X1, 'X1')
X2=Signal(intbv(0)[BitSize:]); Peeker(X2, 'X2')
cin=Signal(bool(0)); Peeker(cin, 'cin')
S=Signal(intbv(0)[BitSize:]); Peeker(S, 'S')
c=Signal(bool(0)); Peeker(c, 'c')

DUT = RippleCarryNBit(X1=X1, X2=X2, cin=cin, S=S, c=c)

def RippleCarryNBit_TB():
    @instance
    def stimules():
        for i in range(len(X1TVals)):
            X1.next=int(X1TVals[i])
            X2.next=int(X2TVals[i])
            cin.next=int(cinTVals[i])
            yield delay(1)
        
        raise StopSimulation()

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

In [48]:
Peeker.to_wavedrom('cin', 'X1', 'X2', 'S', 'c')



In [49]:
RCNBData=Peeker.to_dataframe()
RCNBData=RCNBData[['cin', 'X1', 'X2', 'S', 'c']]
RCNBData


Out[49]:
cin X1 X2 S c
0 0 14155 41378 55533 0
1 1 38555 8651 47207 0
2 1 58758 9846 3069 1
3 0 19709 5194 24903 0
4 0 40177 63872 38513 1
5 0 36482 11637 48119 0
6 0 9475 17512 26987 0
7 0 63427 19660 17551 1
8 0 12108 48397 60505 0
9 0 61872 36946 33282 1
10 1 278 57433 57712 0
11 1 57393 9507 1365 1
12 1 16308 4030 20339 0
13 1 49029 48228 31722 1
14 0 20109 4515 24624 0
15 0 20953 40353 61306 0

In [50]:
def RCNB_SCheck(cin, X1, X2):
    S=cin+X1+X2
    if S<2**BitSize:
        return S
    else:
        return S-(2**BitSize)
def RCNB_cCheck(cin, X1, X2):
    S=cin+X1+X2
    if S<2**BitSize:
        return 0
    else:
        return 1

RCNBData['SCheck']=RCNBData.apply(lambda row: RCNB_SCheck(row['cin'], row['X1'], row['X2']), axis=1)
RCNBData['cCheck']=RCNBData.apply(lambda row: RCNB_cCheck(row['cin'], row['X1'], row['X2']), axis=1)
RCNBData


Out[50]:
cin X1 X2 S c SCheck cCheck
0 0 14155 41378 55533 0 55533 0
1 1 38555 8651 47207 0 47207 0
2 1 58758 9846 3069 1 3069 1
3 0 19709 5194 24903 0 24903 0
4 0 40177 63872 38513 1 38513 1
5 0 36482 11637 48119 0 48119 0
6 0 9475 17512 26987 0 26987 0
7 0 63427 19660 17551 1 17551 1
8 0 12108 48397 60505 0 60505 0
9 0 61872 36946 33282 1 33282 1
10 1 278 57433 57712 0 57712 0
11 1 57393 9507 1365 1 1365 1
12 1 16308 4030 20339 0 20339 0
13 1 49029 48228 31722 1 31722 1
14 0 20109 4515 24624 0 24624 0
15 0 20953 40353 61306 0 61306 0

In [51]:
SumCheck=(RCNBData['S']==RCNBData['SCheck']).all()
CarryCheck=(RCNBData['c']==RCNBData['cCheck']).all()
print(f'Sum Result Check: {SumCheck}; Carry Result Check: {CarryCheck}')


Sum Result Check: True; Carry Result Check: True

Verilog Code

Conversion Error

there is a conversion error in that the converter does not know how to translate as least the * unpacking operator in line 27 of RippleCarryNBit

S.next=ConcatSignal(*reversed(S_i))

There is also a high liklyhood that the converter also does not know how to handle the reversed operator


In [52]:
#DUT.convert()
#VerilogTextReader('RippleCarryNBit');

myHDL Testbench (ToDo)

To be done when Testbench conversion is improved

Stage One

$$p_i=A_i \oplus B_i$$$$G_i=A_i \cdot B_i$$

myHDL Code


In [53]:
@block
def CLAS1(x1, x2, p, g):
    """
    Carry Look Ahead Adder Stage One
    Input:
        x1(bool): x1 input
        x2(bool): x2 input
    
    Output:
        p(bool):carry propagate
        g(bool):carry generate
    
    """
    @always_comb
    def logic():
        p.next=x1^x2
        g.next=x1&x2
    return instances()

myHDL Testing


In [54]:
Peeker.clear()
x1=Signal(bool(0)); Peeker(x1, 'x1')
x2=Signal(bool(0)); Peeker(x2, 'x2')
p=Signal(bool(0)); Peeker(p, 'p')
g=Signal(bool(0)); Peeker(g, 'g')

#generate test values
x1TVals=[i[0] for i in itertools.product(BitVals, repeat=len(BitVals))]
x2TVals=[i[1] for i in itertools.product(BitVals, repeat=len(BitVals))]

DUT=CLAS1(x1, x2, p, g)


def CLAS1_TB():
    """
    myHDL only Testbench for module "CL"
    """
    @instance
    def stimules():
        for i, j in zip(x1TVals, x2TVals):
            x1.next=i; x2.next=j
            yield delay(1)
        
        raise StopSimulation()
    
    return instances()

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

In [55]:
Peeker.to_wavedrom('x1', 'x2', 'p', 'g')



In [56]:
CLAS1Data=Peeker.to_dataframe()
CLAS1Data=CLAS1Data[['x1', 'x2', 'p', 'g']]
CLAS1Data


Out[56]:
x1 x2 p g
0 0 0 0 0
1 0 1 1 0
2 1 0 1 0
3 1 1 0 1

In [57]:
CLAS1Data['pCheck']=CLAS1Data.apply(lambda row: row['x1']^row['x2'], axis=1)
CLAS1Data['gCheck']=CLAS1Data.apply(lambda row: row['x1']&row['x2'], axis=1)
CLAS1Data


Out[57]:
x1 x2 p g pCheck gCheck
0 0 0 0 0 0 0
1 0 1 1 0 1 0
2 1 0 1 0 1 0
3 1 1 0 1 0 1

In [58]:
pCheck=(CLAS1Data['p']==CLAS1Data['pCheck']).all()
gCheck=(CLAS1Data['g']==CLAS1Data['gCheck']).all()
print(f'p Result Check: {pCheck}; g Result Check: {gCheck}')


p Result Check: True; g Result Check: True

Verilog Code


In [59]:
DUT.convert()
VerilogTextReader('CLAS1');


***Verilog modual from CLAS1.v***

 // File: CLAS1.v
// Generated by MyHDL 0.10
// Date: Tue Aug 21 12:52:29 2018


`timescale 1ns/10ps

module CLAS1 (
    x1,
    x2,
    p,
    g
);
// Carry Look Ahead Adder Stage One
// Input:
//     x1(bool): x1 input
//     x2(bool): x2 input
// 
// Output:
//     p(bool):carry propagate
//     g(bool):carry generate

input x1;
input x2;
output p;
wire p;
output g;
wire g;





assign p = (x1 ^ x2);
assign g = (x1 & x2);

endmodule

Verilog Testbench


In [60]:
#generate test values
x1TVals=[i[0] for i in itertools.product(BitVals, repeat=len(BitVals))]
x2TVals=[i[1] for i in itertools.product(BitVals, repeat=len(BitVals))]
#create single value representation of Test Inputs
x1TVal=intbv(int(''.join([str(i) for i in x1TVals]), 2))[len(x1TVals):]
x2TVal=intbv(int(''.join([str(i) for i in x2TVals]), 2))[len(x2TVals):]

In [61]:
print(f'x1Test: {x1TVals}, {x1TVal}, {[int(i) for i in x1TVal]}')
print(f'x2Test: {x2TVals}, {x2TVal}, {[int(i) for i in x2TVal]}')


x1Test: [0, 0, 1, 1], 3, [0, 0, 1, 1]
x2Test: [0, 1, 0, 1], 5, [0, 1, 0, 1]

In [62]:
@block
def CLAS1_TBV():
    """
    myHDL -> Verilog Testbench for module "CLAS1"
    """
    x1=Signal(bool(0))
    x2=Signal(bool(0))
    p=Signal(bool(0))
    g=Signal(bool(0))
    
    #test stimuli
    x1TVals=Signal(x1TVal)
    x2TVals=Signal(x2TVal)
    
    @always_comb
    def print_data():
        print(x1, x2, p, g)

    DUT=CLAS1(x1, x2, p, g)

    @instance
    def stimules():
        for i in range(len(x1TVal)):
            x1.next=x1TVals[i]; x2.next=x2TVals[i]
            yield delay(1)
        
        raise StopSimulation()
    
    return instances()

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


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

 // File: CLAS1_TBV.v
// Generated by MyHDL 0.10
// Date: Tue Aug 21 12:52:30 2018


`timescale 1ns/10ps

module CLAS1_TBV (

);
// myHDL -> Verilog Testbench for module "CLAS1"


reg x1 = 0;
reg x2 = 0;
wire [3:0] x1TVals;
wire [3:0] x2TVals;
wire p;
wire g;

assign x1TVals = 4'd3;
assign x2TVals = 4'd5;


always @(p, x2, g, x1) begin: CLAS1_TBV_PRINT_DATA
    $write("%h", x1);
    $write(" ");
    $write("%h", x2);
    $write(" ");
    $write("%h", p);
    $write(" ");
    $write("%h", g);
    $write("\n");
end



assign p = (x1 ^ x2);
assign g = (x1 & x2);


initial begin: CLAS1_TBV_STIMULES
    integer i;
    for (i=0; i<4; i=i+1) begin
        x1 <= x1TVals[i];
        x2 <= x2TVals[i];
        # 1;
    end
    $finish;
end

endmodule

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

Stage Three

$$S_i=P_i \oplus C_i $$

myHDL Code


In [63]:
@block
def CLAS3(p, c, s):
    """
    Carrry Look Ahead Adder Stage 3
    Input:
        p(bool):carry propagate
        c(bool): carry

    Output:
        s(bool): sum
    """
    @always_comb
    def logic():
        s.next=p^c
    return instances()

myHDL Testing


In [64]:
Peeker.clear()
p=Signal(bool(0)); Peeker(p, 'p')
c=Signal(bool(0)); Peeker(c, 'c')
s=Signal(bool(0)); Peeker(s, 's')

#generate test values
pTVals=[i[0] for i in itertools.product(BitVals, repeat=len(BitVals))]
cTVals=[i[1] for i in itertools.product(BitVals, repeat=len(BitVals))]

DUT=CLAS3(p, c, s)


def CLAS3_TB():
    """
    myHDL only Testbench for module "CLAS3"
    """
    @instance
    def stimules():
        for i, j in zip(pTVals, cTVals):
            p.next=i; c.next=j
            yield delay(1)
        
        raise StopSimulation()
    
    return instances()

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

In [65]:
Peeker.to_wavedrom('p', 'c', 's')



In [66]:
CLAS3Data=Peeker.to_dataframe()
CLAS3Data=CLAS3Data[['p', 'c', 's']]
CLAS3Data


Out[66]:
p c s
0 0 0 0
1 0 1 1
2 1 0 1
3 1 1 0

In [67]:
CLAS3Data['sCheck']=CLAS3Data.apply(lambda row: row['p']^row['c'], axis=1)
CLAS3Data


Out[67]:
p c s sCheck
0 0 0 0 0
1 0 1 1 1
2 1 0 1 1
3 1 1 0 0

In [68]:
sCheck=(CLAS3Data['s']==CLAS3Data['sCheck']).all()
print(f's Result Check: {sCheck}')


s Result Check: True

Verilog Code


In [69]:
DUT.convert()
VerilogTextReader('CLAS3');


***Verilog modual from CLAS3.v***

 // File: CLAS3.v
// Generated by MyHDL 0.10
// Date: Tue Aug 21 12:52:30 2018


`timescale 1ns/10ps

module CLAS3 (
    p,
    c,
    s
);
// Carrry Look Ahead Adder Stage 3
// Input:
//     p(bool):carry propagate
//     c(bool): carry
// 
// Output:
//     s(bool): sum

input p;
input c;
output s;
wire s;





assign s = (p ^ c);

endmodule

Verilog Testbench


In [70]:
#generate test values
pTVals=[i[0] for i in itertools.product(BitVals, repeat=len(BitVals))]
cTVals=[i[1] for i in itertools.product(BitVals, repeat=len(BitVals))]
#create single value representation of Test Inputs
pTVal=intbv(int(''.join([str(i) for i in pTVals]), 2))[len(pTVals):]
cTVal=intbv(int(''.join([str(i) for i in cTVals]), 2))[len(cTVals):]

In [71]:
print(f'pTest: {pTVals}, {pTVal}, {[int(i) for i in pTVal]}')
print(f'cTest: {cTVals}, {cTVal}, {[int(i) for i in cTVal]}')


pTest: [0, 0, 1, 1], 3, [0, 0, 1, 1]
cTest: [0, 1, 0, 1], 5, [0, 1, 0, 1]

In [72]:
@block
def CLAS3_TBV():
    """
    myHDL -> Verilog Testbench for module "CLAS3"
    """
    p=Signal(bool(0))
    c=Signal(bool(0))
    s=Signal(bool(0))
    
    #test stimuli
    pTVals=Signal(pTVal)
    cTVals=Signal(cTVal)
    
    @always_comb
    def print_data():
        print(p, c, s)

    DUT=CLAS3(p, c, s)

    @instance
    def stimules():
        for i in range(len(pTVal)):
            p.next=pTVals[i]; c.next=cTVals[i]
            yield delay(1)
        
        raise StopSimulation()
    
    return instances()

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


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

 // File: CLAS3_TBV.v
// Generated by MyHDL 0.10
// Date: Tue Aug 21 12:52:32 2018


`timescale 1ns/10ps

module CLAS3_TBV (

);
// myHDL -> Verilog Testbench for module "CLAS3"


wire s;
reg c = 0;
reg p = 0;
wire [3:0] pTVals;
wire [3:0] cTVals;

assign pTVals = 4'd3;
assign cTVals = 4'd5;


always @(p, s, c) begin: CLAS3_TBV_PRINT_DATA
    $write("%h", p);
    $write(" ");
    $write("%h", c);
    $write(" ");
    $write("%h", s);
    $write("\n");
end



assign s = (p ^ c);


initial begin: CLAS3_TBV_STIMULES
    integer i;
    for (i=0; i<4; i=i+1) begin
        p <= pTVals[i];
        c <= cTVals[i];
        # 1;
    end
    $finish;
end

endmodule

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

Stage Two

$$C_i+1=G_i+P_i\cdot C_i$$

And is thus a recursion formula, so for a exsample a 4 bit Carray Lock Ahead Adder would have the following carry exspersions

$$C_1=G_0+P_0\cdot C_{in}$$$$C_2=G_1+P_1\cdot C_1=G_1+P_1G_0+P_1P_0C_{in}$$$$C_3=G_2+P_2\cdot C_2=G_2+P_2G_1+P_2P_1G_0+P_2P_1P_0C_{in}$$$$C_4=G_3+P_3\cdot C_3=G_3+P_3G_2+P_3P_2G_1+P_3P_2P_1G_0+P_3P_2P_1P_0C_{in}$$

myHDL Code (ToDo)

myHDL Testing (ToDo)


In [73]:
def CLAS2B4_TestFunc(P, G, cin):
    P=[int(i) for i in reversed(bin(P,4))]
    G=[int(i) for i in reversed(bin(G,4))]
    C=[]
    for i in range(4):
        if i==0:
            C.append(int(G[i]) | (P[i]&cin))
        else:
            C.append(int(G[i]) | (P[i] &C[i-1]))
        
    C=int(''.join(str(i) for i in C[::-1]),2)
    return C
CLAS2B4_TestFunc(8,6,1)


Out[73]:
$$14$$

In [ ]: