\title{Addition in myHDL (In Progress)} \author{Steven K Armour} \maketitle
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]:
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]
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()
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]:
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]:
In [9]:
SumCheck=(HalfAdderData['s']==HalfAdderData['sCheck']).all()
CarryCheck=(HalfAdderData['c']==HalfAdderData['cCheck']).all()
print(f'Sum Result Check: {SumCheck}; Carry Result Check: {CarryCheck}')
In [10]:
DUT.convert()
VerilogTextReader('HalfAdder');
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]}')
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');
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()
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]:
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]:
In [19]:
SumCheck=(FullAdderData['s']==FullAdderData['sCheck']).all()
CarryCheck=(FullAdderData['c']==FullAdderData['cCheck']).all()
print(f'Sum Result Check: {SumCheck}; Carry Result Check: {CarryCheck}')
In [20]:
DUT.convert()
VerilogTextReader('FullAdder');
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]}')
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');
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()
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]:
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]:
In [29]:
SumCheck=(FullAdderHAData['s']==FullAdderHAData['sCheck']).all()
CarryCheck=(FullAdderHAData['c']==FullAdderHAData['cCheck']).all()
print(f'Sum Result Check: {SumCheck}; Carry Result Check: {CarryCheck}')
In [30]:
(FullAdderData==FullAdderHAData).all()
Out[30]:
In [31]:
DUT.convert()
VerilogTextReader('FullAdderViaHAs');
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]}')
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');
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()
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)
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]:
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]:
In [41]:
SumCheck=(RC4BData['S']==RC4BData['SCheck']).all()
CarryCheck=(RC4BData['c']==RC4BData['cCheck']).all()
print(f'Sum Result Check: {SumCheck}; Carry Result Check: {CarryCheck}')
In [42]:
DUT.convert()
VerilogTextReader('RippleCarry4Bit');
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)
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');
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()
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)
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]:
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]:
In [51]:
SumCheck=(RCNBData['S']==RCNBData['SCheck']).all()
CarryCheck=(RCNBData['c']==RCNBData['cCheck']).all()
print(f'Sum Result Check: {SumCheck}; Carry Result Check: {CarryCheck}')
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');
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()
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]:
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]:
In [58]:
pCheck=(CLAS1Data['p']==CLAS1Data['pCheck']).all()
gCheck=(CLAS1Data['g']==CLAS1Data['gCheck']).all()
print(f'p Result Check: {pCheck}; g Result Check: {gCheck}')
In [59]:
DUT.convert()
VerilogTextReader('CLAS1');
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]}')
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');
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()
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]:
In [67]:
CLAS3Data['sCheck']=CLAS3Data.apply(lambda row: row['p']^row['c'], axis=1)
CLAS3Data
Out[67]:
In [68]:
sCheck=(CLAS3Data['s']==CLAS3Data['sCheck']).all()
print(f's Result Check: {sCheck}')
In [69]:
DUT.convert()
VerilogTextReader('CLAS3');
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]}')
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');
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}$$
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]:
In [ ]: