<SYSTEM_TASK:>
Given the following text description, write Python code to implement the functionality described below step by step
<END_TASK>
<USER_TASK:>
Description:
 \title{Addition in myHDL (In Progress)}
\author{Steven K Armour}
\maketitle
Refrances
https
Step2:  Half Adder
myHDL Code
Step4:  myHDL Testing
Step5:  Verilog Code
Step7:  Verilog Testbench
Step9:  Full Adder From Exspresion
myHDL Code
Step11:  myHDL Testing
Step12:  Verilog Code
Step14:  Verilog Testbench
Step16:  Full Adder via HalfAdders
myHDL Code
Step18:  myHDL Testing
Step19:  Verilog Code
Step21:  Verilog Testbench
Step23:  4 Bit Ripple Carry
myHDL Code
Step24:  myHDL Testing
Step26:  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
Step28:  N Bit Ripple Carray Adder
Step29:  myHDL Testing
Step30:  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
Step32:  myHDL Testbench (ToDo)
To be done when Testbench conversion is improved
Carry Look Ahead 4 Bit
https
Step34:  myHDL Testing
Step35:  Verilog Code
Step37:  Verilog Testbench
Step39:  Stage Three
$$S_i=P_i \oplus C_i $$
myHDL Code
Step41:  myHDL Testing
Step42:  Verilog Code
Step44:  Verilog Testbench
Step45:  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)
<ASSISTANT_TASK:>
Python Code:
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
#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
BitVals=[0,1]
Explanation: \title{Addition in myHDL (In Progress)}
\author{Steven K Armour}
\maketitle
Refrances
https://www.geeksforgeeks.org/digital-logic-carry-look-ahead-adder/
http://faculty.kfupm.edu.sa/COE/abouh/Lesson3_3.pdf
Libraries and Helper functions
End of explanation
@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()
Explanation: Half Adder
myHDL Code
End of explanation
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()
Peeker.to_wavedrom('x1', 'x2', 's', 'c')
HalfAdderData=Peeker.to_dataframe()
HalfAdderData=HalfAdderData[['x1', 'x2', 's', 'c']]
HalfAdderData
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
SumCheck=(HalfAdderData['s']==HalfAdderData['sCheck']).all()
CarryCheck=(HalfAdderData['c']==HalfAdderData['cCheck']).all()
print(f'Sum Result Check: {SumCheck}; Carry Result Check: {CarryCheck}')
Explanation: myHDL Testing
End of explanation
DUT.convert()
VerilogTextReader('HalfAdder');
Explanation: Verilog Code
End of explanation
#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):]
print(f'x1Test: {x1TVals}, {x1TVal}, {[int(i) for i in x1TVal]}')
print(f'x2Test: {x2TVals}, {x2TVal}, {[int(i) for i in x2TVal]}')
@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');
Explanation: Verilog Testbench
End of explanation
@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()
    
Explanation: Full Adder From Exspresion
myHDL Code
End of explanation
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()
Peeker.to_wavedrom('x1', 'x2', 'cin', 's', 'c')
FullAdderData=Peeker.to_dataframe()
FullAdderData=FullAdderData[['x1', 'x2', 'cin', 's', 'c']]
FullAdderData
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
SumCheck=(FullAdderData['s']==FullAdderData['sCheck']).all()
CarryCheck=(FullAdderData['c']==FullAdderData['cCheck']).all()
print(f'Sum Result Check: {SumCheck}; Carry Result Check: {CarryCheck}')
Explanation: myHDL Testing
End of explanation
DUT.convert()
VerilogTextReader('FullAdder');
Explanation: Verilog Code
End of explanation
#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):]
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]}')
@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');
Explanation: Verilog Testbench
End of explanation
@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()
    
Explanation: Full Adder via HalfAdders
myHDL Code
End of explanation
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()
Peeker.to_wavedrom('x1', 'x2', 'cin', 's', 'c')
FullAdderHAData=Peeker.to_dataframe()
FullAdderHAData=FullAdderHAData[['x1', 'x2', 'cin', 's', 'c']]
FullAdderHAData
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
SumCheck=(FullAdderHAData['s']==FullAdderHAData['sCheck']).all()
CarryCheck=(FullAdderHAData['c']==FullAdderHAData['cCheck']).all()
print(f'Sum Result Check: {SumCheck}; Carry Result Check: {CarryCheck}')
(FullAdderData==FullAdderHAData).all()
Explanation: myHDL Testing
End of explanation
DUT.convert()
VerilogTextReader('FullAdderViaHAs');
Explanation: Verilog Code
End of explanation
#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):]
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]}')
@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');
Explanation: Verilog Testbench
End of explanation
@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()
Explanation: 4 Bit Ripple Carry
myHDL Code
End of explanation
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)
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()
Peeker.to_wavedrom('cin', 'X1', 'X2', 'S', 'c')
RC4BData=Peeker.to_dataframe()
RC4BData=RC4BData[['cin', 'X1', 'X2', 'S', 'c']]
RC4BData
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
SumCheck=(RC4BData['S']==RC4BData['SCheck']).all()
CarryCheck=(RC4BData['c']==RC4BData['cCheck']).all()
print(f'Sum Result Check: {SumCheck}; Carry Result Check: {CarryCheck}')
DUT.convert()
VerilogTextReader('RippleCarry4Bit');
Explanation: myHDL Testing
End of explanation
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)
@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');
Explanation: 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
End of explanation
@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()
Explanation: N Bit Ripple Carray Adder
End of explanation
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)
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()
Peeker.to_wavedrom('cin', 'X1', 'X2', 'S', 'c')
RCNBData=Peeker.to_dataframe()
RCNBData=RCNBData[['cin', 'X1', 'X2', 'S', 'c']]
RCNBData
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
SumCheck=(RCNBData['S']==RCNBData['SCheck']).all()
CarryCheck=(RCNBData['c']==RCNBData['cCheck']).all()
print(f'Sum Result Check: {SumCheck}; Carry Result Check: {CarryCheck}')
Explanation: myHDL Testing
End of explanation
#DUT.convert()
#VerilogTextReader('RippleCarryNBit');
Explanation: 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
End of explanation
@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()
Explanation: myHDL Testbench (ToDo)
To be done when Testbench conversion is improved
Carry Look Ahead 4 Bit
https://www.geeksforgeeks.org/digital-logic-carry-look-ahead-adder/
http://faculty.kfupm.edu.sa/COE/abouh/Lesson3_3.pdf
Stage One
$$p_i=A_i \oplus B_i$$
$$G_i=A_i \cdot B_i$$
myHDL Code
End of explanation
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()
Peeker.to_wavedrom('x1', 'x2', 'p', 'g')
CLAS1Data=Peeker.to_dataframe()
CLAS1Data=CLAS1Data[['x1', 'x2', 'p', 'g']]
CLAS1Data
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
pCheck=(CLAS1Data['p']==CLAS1Data['pCheck']).all()
gCheck=(CLAS1Data['g']==CLAS1Data['gCheck']).all()
print(f'p Result Check: {pCheck}; g Result Check: {gCheck}')
Explanation: myHDL Testing
End of explanation
DUT.convert()
VerilogTextReader('CLAS1');
Explanation: Verilog Code
End of explanation
#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):]
print(f'x1Test: {x1TVals}, {x1TVal}, {[int(i) for i in x1TVal]}')
print(f'x2Test: {x2TVals}, {x2TVal}, {[int(i) for i in x2TVal]}')
@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');
Explanation: Verilog Testbench
End of explanation
@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()
Explanation: Stage Three
$$S_i=P_i \oplus C_i $$
myHDL Code
End of explanation
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()
Peeker.to_wavedrom('p', 'c', 's')
CLAS3Data=Peeker.to_dataframe()
CLAS3Data=CLAS3Data[['p', 'c', 's']]
CLAS3Data
CLAS3Data['sCheck']=CLAS3Data.apply(lambda row: row['p']^row['c'], axis=1)
CLAS3Data
sCheck=(CLAS3Data['s']==CLAS3Data['sCheck']).all()
print(f's Result Check: {sCheck}')
Explanation: myHDL Testing
End of explanation
DUT.convert()
VerilogTextReader('CLAS3');
Explanation: Verilog Code
End of explanation
#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):]
print(f'pTest: {pTVals}, {pTVal}, {[int(i) for i in pTVal]}')
print(f'cTest: {cTVals}, {cTVal}, {[int(i) for i in cTVal]}')
@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');
Explanation: Verilog Testbench
End of explanation
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)
Explanation: 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)
End of explanation
<END_TASK>