\title{myHDL Combinational Logic Elements: Demultiplexers (DEMUXs))} \author{Steven K Armour} \maketitle
In [1]:
#This notebook also uses the `(some) LaTeX environments for Jupyter`
#https://github.com/ProfFan/latex_envs wich is part of the
#jupyter_contrib_nbextensions package
from myhdl import *
from myhdlpeek import Peeker
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
%matplotlib inline
from sympy import *
init_printing()
import itertools
#EE drawing tools in python from https://cdelker.bitbucket.io/SchemDraw/
import SchemDraw as schem
import SchemDraw.elements as e
import SchemDraw.logic as l
#https://github.com/jrjohansson/version_information
%load_ext version_information
%version_information myhdl, myhdlpeek, numpy, pandas, matplotlib, sympy, itertools, SchemDraw
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
def ConstraintXDCTextReader(loc, printresult=True):
with open(f'{loc}.xdc', 'r') as xdcText:
ConstraintText=xdcText.read()
if printresult:
print(f'***Constraint file from {loc}.xdc***\n\n', ConstraintText)
return ConstraintText
In [3]:
def TruthTabelGenrator(BoolSymFunc):
"""
Function to generate a truth table from a sympy boolian expression
BoolSymFunc: sympy boolian expression
return TT: a Truth table stored in a pandas dataframe
"""
colsL=sorted([i for i in list(BoolSymFunc.rhs.atoms())], key=lambda x:x.sort_key())
colsR=sorted([i for i in list(BoolSymFunc.lhs.atoms())], key=lambda x:x.sort_key())
bitwidth=len(colsL)
cols=colsL+colsR; cols
TT=pd.DataFrame(columns=cols, index=range(2**bitwidth))
for i in range(2**bitwidth):
inputs=[int(j) for j in list(np.binary_repr(i, bitwidth))]
outputs=BoolSymFunc.rhs.subs({j:v for j, v in zip(colsL, inputs)})
inputs.append(int(bool(outputs)))
TT.iloc[i]=inputs
return TT
In [4]:
x, s, y0, y1=symbols('x, s, y_0, y_1')
y12_0Eq=Eq(y0, ~s&x)
y12_1Eq=Eq(y1, s&x)
y12_0Eq, y12_1Eq
Out[4]:
In [5]:
T0=TruthTabelGenrator(y12_0Eq)
T1=TruthTabelGenrator(y12_1Eq)
T10=pd.merge(T1, T0, how='left')
T10
Out[5]:
In [6]:
y12_0EqN=lambdify([s, x], y12_0Eq.rhs, dummify=False)
y12_1EqN=lambdify([s, x], y12_1Eq.rhs, dummify=False)
SystmaticVals=np.array(list(itertools.product([0,1], repeat=2)))
print(SystmaticVals)
print(y12_0EqN(SystmaticVals[:, 0], SystmaticVals[:, 1]).astype(int))
print(y12_1EqN(SystmaticVals[:, 0], SystmaticVals[:, 1]).astype(int))
In [7]:
@block
def DEMUX1_2_Combo(x, s, y0, y1):
"""
1:2 DEMUX written in full combo
Inputs:
x(bool): input feed
s(bool): channel select
Outputs:
y0(bool): ouput channel 0
y1(bool): ouput channel 1
"""
@always_comb
def logic():
y0.next= not s and x
y1.next= s and x
return instances()
In [8]:
TestLen=10
SystmaticVals=list(itertools.product([0,1], repeat=2))
xTVs=np.array([i[1] for i in SystmaticVals]).astype(int)
np.random.seed(15)
xTVs=np.append(xTVs, np.random.randint(0,2, TestLen)).astype(int)
sTVs=np.array([i[0] for i in SystmaticVals]).astype(int)
#the random genrator must have a differint seed beween each generation
#call in order to produce differint values for each call
np.random.seed(16)
sTVs=np.append(sTVs, np.random.randint(0,2, TestLen)).astype(int)
TestLen=len(xTVs)
SystmaticVals, sTVs, xTVs
Out[8]:
In [9]:
Peeker.clear()
x=Signal(bool(0)); Peeker(x, 'x')
s=Signal(bool(0)); Peeker(s, 's')
y0=Signal(bool(0)); Peeker(y0, 'y0')
y1=Signal(bool(0)); Peeker(y1, 'y1')
DUT=DEMUX1_2_Combo(x, s, y0, y1)
def DEMUX1_2_Combo_TB():
"""
myHDL only testbench for module `DEMUX1_2_Combo`
"""
@instance
def stimules():
for i in range(TestLen):
x.next=int(xTVs[i])
s.next=int(sTVs[i])
yield delay(1)
raise StopSimulation()
return instances()
sim=Simulation(DUT, DEMUX1_2_Combo_TB(), *Peeker.instances()).run()
In [10]:
Peeker.to_wavedrom('x', 's', 'y0','y1')
In [11]:
DEMUX1_2_ComboData=Peeker.to_dataframe()
DEMUX1_2_ComboData=DEMUX1_2_ComboData[['x', 's', 'y0','y1']]
DEMUX1_2_ComboData
Out[11]:
In [12]:
DEMUX1_2_ComboData['y0Ref']=DEMUX1_2_ComboData.apply(lambda row:y12_0EqN(row['s'], row['x']), axis=1).astype(int)
DEMUX1_2_ComboData['y1Ref']=DEMUX1_2_ComboData.apply(lambda row:y12_1EqN(row['s'], row['x']), axis=1).astype(int)
DEMUX1_2_ComboData
Out[12]:
In [13]:
Test0=(DEMUX1_2_ComboData['y0']==DEMUX1_2_ComboData['y0Ref']).all()
Test1=(DEMUX1_2_ComboData['y1']==DEMUX1_2_ComboData['y1Ref']).all()
Test=Test0&Test1
print(f'Module `DEMUX1_2_Combo` works as exspected: {Test}')
In [14]:
DUT.convert()
VerilogTextReader('DEMUX1_2_Combo');
In [15]:
#create BitVectors
xTVs=intbv(int(''.join(xTVs.astype(str)), 2))[TestLen:]
sTVs=intbv(int(''.join(sTVs.astype(str)), 2))[TestLen:]
xTVs, bin(xTVs), sTVs, bin(sTVs)
Out[15]:
In [16]:
@block
def DEMUX1_2_Combo_TBV():
"""
myHDL -> testbench for module `DEMUX1_2_Combo`
"""
x=Signal(bool(0))
s=Signal(bool(0))
y0=Signal(bool(0))
y1=Signal(bool(0))
@always_comb
def print_data():
print(x, s, y0, y1)
#Test Signal Bit Vectors
xTV=Signal(xTVs)
sTV=Signal(sTVs)
DUT=DEMUX1_2_Combo(x, s, y0, y1)
@instance
def stimules():
for i in range(TestLen):
x.next=int(xTV[i])
s.next=int(sTV[i])
yield delay(1)
raise StopSimulation()
return instances()
TB=DEMUX1_2_Combo_TBV()
TB.convert(hdl="Verilog", initial_values=True)
VerilogTextReader('DEMUX1_2_Combo_TBV');
In [17]:
ConstraintXDCTextReader('DEMUX1_2');
DEMUX1_2_Combo on PYNQ-Z1 (YouTube)
In [18]:
x, s0, s1, y0, y1, y2, y3=symbols('x, s0, s1, y0, y1, y2, y3')
y14_0Eq=Eq(y0, ~s0&~s1&x)
y14_1Eq=Eq(y1, s0&~s1&x)
y14_2Eq=Eq(y2, ~s0&s1&x)
y14_3Eq=Eq(y3, s0&s1&x)
y14_0Eq, y14_1Eq, y14_2Eq, y14_3Eq
Out[18]:
In [19]:
T0=TruthTabelGenrator(y14_0Eq)
T1=TruthTabelGenrator(y14_1Eq)
T2=TruthTabelGenrator(y14_2Eq)
T3=TruthTabelGenrator(y14_3Eq)
T10=pd.merge(T1, T0, how='left')
T20=pd.merge(T2, T10, how='left')
T30=pd.merge(T3, T20, how='left')
T30
Out[19]:
In [20]:
y14_0EqN=lambdify([x, s0, s1], y14_0Eq.rhs, dummify=False)
y14_1EqN=lambdify([x, s0, s1], y14_1Eq.rhs, dummify=False)
y14_2EqN=lambdify([x, s0, s1], y14_2Eq.rhs, dummify=False)
y14_3EqN=lambdify([x, s0, s1], y14_3Eq.rhs, dummify=False)
SystmaticVals=np.array(list(itertools.product([0,1], repeat=3)))
print(SystmaticVals)
print(y14_0EqN(SystmaticVals[:, 2], SystmaticVals[:, 1], SystmaticVals[:, 0]).astype(int))
print(y14_1EqN(SystmaticVals[:, 2], SystmaticVals[:, 1], SystmaticVals[:, 0]).astype(int))
print(y14_2EqN(SystmaticVals[:, 2], SystmaticVals[:, 1], SystmaticVals[:, 0]).astype(int))
print(y14_3EqN(SystmaticVals[:, 2], SystmaticVals[:, 1], SystmaticVals[:, 0]).astype(int))
In [21]:
@block
def DEMUX1_4_Combo(x, s0, s1, y0, y1, y2, y3):
"""
1:4 DEMUX written in full combo
Inputs:
x(bool): input feed
s0(bool): channel select 0
s1(bool): channel select 1
Outputs:
y0(bool): ouput channel 0
y1(bool): ouput channel 1
y2(bool): ouput channel 2
y3(bool): ouput channel 3
"""
@always_comb
def logic():
y0.next= (not s0) and (not s1) and x
y1.next= s0 and (not s1) and x
y2.next= (not s0) and s1 and x
y3.next= s0 and s1 and x
return instances()
In [22]:
TestLen=10
SystmaticVals=list(itertools.product([0,1], repeat=3))
xTVs=np.array([i[2] for i in SystmaticVals]).astype(int)
np.random.seed(15)
xTVs=np.append(xTVs, np.random.randint(0,2, TestLen)).astype(int)
s0TVs=np.array([i[1] for i in SystmaticVals]).astype(int)
#the random genrator must have a differint seed beween each generation
#call in order to produce differint values for each call
np.random.seed(16)
s0TVs=np.append(s0TVs, np.random.randint(0,2, TestLen)).astype(int)
s1TVs=np.array([i[0] for i in SystmaticVals]).astype(int)
#the random genrator must have a differint seed beween each generation
#call in order to produce differint values for each call
np.random.seed(17)
s1TVs=np.append(s1TVs, np.random.randint(0,2, TestLen)).astype(int)
TestLen=len(xTVs)
SystmaticVals, xTVs, s0TVs, s1TVs
Out[22]:
In [23]:
Peeker.clear()
x=Signal(bool(0)); Peeker(x, 'x')
s0=Signal(bool(0)); Peeker(s0, 's0')
s1=Signal(bool(0)); Peeker(s1, 's1')
y0=Signal(bool(0)); Peeker(y0, 'y0')
y1=Signal(bool(0)); Peeker(y1, 'y1')
y2=Signal(bool(0)); Peeker(y2, 'y2')
y3=Signal(bool(0)); Peeker(y3, 'y3')
DUT=DEMUX1_4_Combo(x, s0, s1, y0, y1, y2, y3)
def DEMUX1_4_Combo_TB():
"""
myHDL only testbench for module `DEMUX1_4_Combo`
"""
@instance
def stimules():
for i in range(TestLen):
x.next=int(xTVs[i])
s0.next=int(s0TVs[i])
s1.next=int(s1TVs[i])
yield delay(1)
raise StopSimulation()
return instances()
sim=Simulation(DUT, DEMUX1_4_Combo_TB(), *Peeker.instances()).run()
In [24]:
Peeker.to_wavedrom('x', 's1', 's0', 'y0', 'y1', 'y2', 'y3')
In [25]:
DEMUX1_4_ComboData=Peeker.to_dataframe()
DEMUX1_4_ComboData=DEMUX1_4_ComboData[['x', 's1', 's0', 'y0', 'y1', 'y2', 'y3']]
DEMUX1_4_ComboData
Out[25]:
In [26]:
DEMUX1_4_ComboData['y0Ref']=DEMUX1_4_ComboData.apply(lambda row:y14_0EqN(row['x'], row['s0'], row['s1']), axis=1).astype(int)
DEMUX1_4_ComboData['y1Ref']=DEMUX1_4_ComboData.apply(lambda row:y14_1EqN(row['x'], row['s0'], row['s1']), axis=1).astype(int)
DEMUX1_4_ComboData['y2Ref']=DEMUX1_4_ComboData.apply(lambda row:y14_2EqN(row['x'], row['s0'], row['s1']), axis=1).astype(int)
DEMUX1_4_ComboData['y3Ref']=DEMUX1_4_ComboData.apply(lambda row:y14_3EqN(row['x'], row['s0'], row['s1']), axis=1).astype(int)
DEMUX1_4_ComboData
Out[26]:
In [27]:
Test0=(DEMUX1_4_ComboData['y0']==DEMUX1_4_ComboData['y0Ref']).all()
Test1=(DEMUX1_4_ComboData['y1']==DEMUX1_4_ComboData['y1Ref']).all()
Test2=(DEMUX1_4_ComboData['y2']==DEMUX1_4_ComboData['y2Ref']).all()
Test3=(DEMUX1_4_ComboData['y3']==DEMUX1_4_ComboData['y3Ref']).all()
Test=Test0&Test1&Test2&Test3
print(f'Module `DEMUX1_4_Combo` works as exspected: {Test}')
In [28]:
DUT.convert()
VerilogTextReader('DEMUX1_4_Combo');
In [29]:
#create BitVectors
xTVs=intbv(int(''.join(xTVs.astype(str)), 2))[TestLen:]
s0TVs=intbv(int(''.join(s0TVs.astype(str)), 2))[TestLen:]
s1TVs=intbv(int(''.join(s1TVs.astype(str)), 2))[TestLen:]
xTVs, bin(xTVs), s0TVs, bin(s0TVs), s1TVs, bin(s1TVs)
Out[29]:
In [30]:
@block
def DEMUX1_4_Combo_TBV():
"""
myHDL -> testbench for module `DEMUX1_4_Combo`
"""
x=Signal(bool(0))
s0=Signal(bool(0))
s1=Signal(bool(0))
y0=Signal(bool(0))
y1=Signal(bool(0))
y2=Signal(bool(0))
y3=Signal(bool(0))
@always_comb
def print_data():
print(x, s0, s1, y0, y1, y2, y3)
#Test Signal Bit Vectors
xTV=Signal(xTVs)
s0TV=Signal(s0TVs)
s1TV=Signal(s1TVs)
DUT=DEMUX1_4_Combo(x, s0, s1, y0, y1, y2, y3)
@instance
def stimules():
for i in range(TestLen):
x.next=int(xTV[i])
s0.next=int(s0TV[i])
s1.next=int(s1TV[i])
yield delay(1)
raise StopSimulation()
return instances()
TB=DEMUX1_4_Combo_TBV()
TB.convert(hdl="Verilog", initial_values=True)
VerilogTextReader('DEMUX1_4_Combo_TBV');
In [31]:
ConstraintXDCTextReader('DEMUX1_4');
DEMUX1_4_Combo on PYNQ-Z1 (YouTube)
In [32]:
@block
def DEMUX1_4_DMS(x, s0, s1, y0, y1, y2, y3):
"""
1:4 DEMUX via DEMUX Stacking
Inputs:
x(bool): input feed
s0(bool): channel select 0
s1(bool): channel select 1
Outputs:
y0(bool): ouput channel 0
y1(bool): ouput channel 1
y2(bool): ouput channel 2
y3(bool): ouput channel 3
"""
s0_y0y1_WIRE=Signal(bool(0))
s0_y2y3_WIRE=Signal(bool(0))
x_s1_DEMUX=DEMUX1_2_Combo(x, s1, s0_y0y1_WIRE, s0_y2y3_WIRE)
s1_y0y1_DEMUX=DEMUX1_2_Combo(s0_y0y1_WIRE, s0, y0, y1)
s1_y2y3_DEMUX=DEMUX1_2_Combo(s0_y2y3_WIRE, s0, y2, y3)
return instances()
In [33]:
TestLen=10
SystmaticVals=list(itertools.product([0,1], repeat=3))
xTVs=np.array([i[2] for i in SystmaticVals]).astype(int)
np.random.seed(15)
xTVs=np.append(xTVs, np.random.randint(0,2, TestLen)).astype(int)
s0TVs=np.array([i[1] for i in SystmaticVals]).astype(int)
#the random genrator must have a differint seed beween each generation
#call in order to produce differint values for each call
np.random.seed(16)
s0TVs=np.append(s0TVs, np.random.randint(0,2, TestLen)).astype(int)
s1TVs=np.array([i[0] for i in SystmaticVals]).astype(int)
#the random genrator must have a differint seed beween each generation
#call in order to produce differint values for each call
np.random.seed(17)
s1TVs=np.append(s1TVs, np.random.randint(0,2, TestLen)).astype(int)
TestLen=len(xTVs)
SystmaticVals, xTVs, s0TVs, s1TVs
Out[33]:
In [34]:
Peeker.clear()
x=Signal(bool(0)); Peeker(x, 'x')
s0=Signal(bool(0)); Peeker(s0, 's0')
s1=Signal(bool(0)); Peeker(s1, 's1')
y0=Signal(bool(0)); Peeker(y0, 'y0')
y1=Signal(bool(0)); Peeker(y1, 'y1')
y2=Signal(bool(0)); Peeker(y2, 'y2')
y3=Signal(bool(0)); Peeker(y3, 'y3')
DUT=DEMUX1_4_DMS(x, s0, s1, y0, y1, y2, y3)
def DEMUX1_4_DMS_TB():
"""
myHDL only testbench for module `DEMUX1_4_DMS`
"""
@instance
def stimules():
for i in range(TestLen):
x.next=int(xTVs[i])
s0.next=int(s0TVs[i])
s1.next=int(s1TVs[i])
yield delay(1)
raise StopSimulation()
return instances()
sim=Simulation(DUT, DEMUX1_4_DMS_TB(), *Peeker.instances()).run()
In [35]:
Peeker.to_wavedrom('x', 's1', 's0', 'y0', 'y1', 'y2', 'y3')
In [36]:
DEMUX1_4_DMSData=Peeker.to_dataframe()
DEMUX1_4_DMSData=DEMUX1_4_DMSData[['x', 's1', 's0', 'y0', 'y1', 'y2', 'y3']]
DEMUX1_4_DMSData
Out[36]:
In [37]:
Test=DEMUX1_4_DMSData==DEMUX1_4_ComboData[['x', 's1', 's0', 'y0', 'y1', 'y2', 'y3']]
Test=Test.all().all()
print(f'DEMUX1_4_DMS equivlinet to DEMUX1_4_Combo: {Test}')
In [38]:
DUT.convert()
VerilogTextReader('DEMUX1_4_DMS');
In [39]:
#create BitVectors
xTVs=intbv(int(''.join(xTVs.astype(str)), 2))[TestLen:]
s0TVs=intbv(int(''.join(s0TVs.astype(str)), 2))[TestLen:]
s1TVs=intbv(int(''.join(s1TVs.astype(str)), 2))[TestLen:]
xTVs, bin(xTVs), s0TVs, bin(s0TVs), s1TVs, bin(s1TVs)
Out[39]:
In [40]:
@block
def DEMUX1_4_DMS_TBV():
"""
myHDL -> testbench for module `DEMUX1_4_DMS`
"""
x=Signal(bool(0))
s0=Signal(bool(0))
s1=Signal(bool(0))
y0=Signal(bool(0))
y1=Signal(bool(0))
y2=Signal(bool(0))
y3=Signal(bool(0))
@always_comb
def print_data():
print(x, s0, s1, y0, y1, y2, y3)
#Test Signal Bit Vectors
xTV=Signal(xTVs)
s0TV=Signal(s0TVs)
s1TV=Signal(s1TVs)
DUT=DEMUX1_4_DMS(x, s0, s1, y0, y1, y2, y3)
@instance
def stimules():
for i in range(TestLen):
x.next=int(xTV[i])
s0.next=int(s0TV[i])
s1.next=int(s1TV[i])
yield delay(1)
raise StopSimulation()
return instances()
TB=DEMUX1_4_DMS_TBV()
TB.convert(hdl="Verilog", initial_values=True)
VerilogTextReader('DEMUX1_4_DMS_TBV');
DEMUX1_4_DMS on PYNQ-Z1 (YouTube)
In [41]:
@block
def DEMUX1_2_B(x, s, y0, y1):
"""
1:2 DMUX in behavioral
Inputs:
x(bool): input feed
s(bool): channel select
Outputs:
y0(bool): ouput channel 0
y1(bool): ouput channel 1
"""
@always_comb
def logic():
if s==0:
#take note that since we have
#two ouputs there next state values
#must both be set, else the last
#value will presist till it changes
y0.next=x
y1.next=0
else:
y0.next=0
y1.next=x
return instances()
In [42]:
TestLen=10
SystmaticVals=list(itertools.product([0,1], repeat=2))
xTVs=np.array([i[1] for i in SystmaticVals]).astype(int)
np.random.seed(15)
xTVs=np.append(xTVs, np.random.randint(0,2, TestLen)).astype(int)
sTVs=np.array([i[0] for i in SystmaticVals]).astype(int)
#the random genrator must have a differint seed beween each generation
#call in order to produce differint values for each call
np.random.seed(16)
sTVs=np.append(sTVs, np.random.randint(0,2, TestLen)).astype(int)
TestLen=len(xTVs)
SystmaticVals, sTVs, xTVs
Out[42]:
In [43]:
Peeker.clear()
x=Signal(bool(0)); Peeker(x, 'x')
s=Signal(bool(0)); Peeker(s, 's')
y0=Signal(bool(0)); Peeker(y0, 'y0')
y1=Signal(bool(0)); Peeker(y1, 'y1')
DUT=DEMUX1_2_B(x, s, y0, y1)
def DEMUX1_2_B_TB():
"""
myHDL only testbench for module `DEMUX1_2_B`
"""
@instance
def stimules():
for i in range(TestLen):
x.next=int(xTVs[i])
s.next=int(sTVs[i])
yield delay(1)
raise StopSimulation()
return instances()
sim=Simulation(DUT, DEMUX1_2_B_TB(), *Peeker.instances()).run()
In [44]:
Peeker.to_wavedrom('x', 's', 'y0','y1')
In [45]:
DEMUX1_2_BData=Peeker.to_dataframe()
DEMUX1_2_BData=DEMUX1_2_BData[['x', 's', 'y0','y1']]
DEMUX1_2_BData
Out[45]:
In [46]:
Test=DEMUX1_2_BData==DEMUX1_2_ComboData[['x', 's', 'y0','y1']]
Test=Test.all().all()
print(f'DEMUX1_2_BD is equivlent to DEMUX1_2_Combo: {Test}')
In [47]:
DUT.convert()
VerilogTextReader('DEMUX1_2_B');
In [48]:
#create BitVectors
xTVs=intbv(int(''.join(xTVs.astype(str)), 2))[TestLen:]
sTVs=intbv(int(''.join(sTVs.astype(str)), 2))[TestLen:]
xTVs, bin(xTVs), sTVs, bin(sTVs)
Out[48]:
In [49]:
@block
def DEMUX1_2_B_TBV():
"""
myHDL -> testbench for module `DEMUX1_2_B`
"""
x=Signal(bool(0))
s=Signal(bool(0))
y0=Signal(bool(0))
y1=Signal(bool(0))
@always_comb
def print_data():
print(x, s, y0, y1)
#Test Signal Bit Vectors
xTV=Signal(xTVs)
sTV=Signal(sTVs)
DUT=DEMUX1_2_B(x, s, y0, y1)
@instance
def stimules():
for i in range(TestLen):
x.next=int(xTV[i])
s.next=int(sTV[i])
yield delay(1)
raise StopSimulation()
return instances()
TB=DEMUX1_2_B_TBV()
TB.convert(hdl="Verilog", initial_values=True)
VerilogTextReader('DEMUX1_2_B_TBV');
DEMUX1_2_B on PYNQ-Z1 (YouTube)
In [50]:
@block
def DEMUX1_4_B(x, s0, s1, y0, y1, y2, y3):
"""
1:4 DEMUX written via behaviorial
Inputs:
x(bool): input feed
s0(bool): channel select 0
s1(bool): channel select 1
Outputs:
y0(bool): ouput channel 0
y1(bool): ouput channel 1
y2(bool): ouput channel 2
y3(bool): ouput channel 3
"""
@always_comb
def logic():
if s0==0 and s1==0:
y0.next=x; y1.next=0
y2.next=0; y3.next=0
elif s0==1 and s1==0:
y0.next=0; y1.next=x
y2.next=0; y3.next=0
elif s0==0 and s1==1:
y0.next=0; y1.next=0
y2.next=x; y3.next=0
else:
y0.next=0; y1.next=0
y2.next=0; y3.next=x
return instances()
In [51]:
TestLen=10
SystmaticVals=list(itertools.product([0,1], repeat=3))
xTVs=np.array([i[2] for i in SystmaticVals]).astype(int)
np.random.seed(15)
xTVs=np.append(xTVs, np.random.randint(0,2, TestLen)).astype(int)
s0TVs=np.array([i[1] for i in SystmaticVals]).astype(int)
#the random genrator must have a differint seed beween each generation
#call in order to produce differint values for each call
np.random.seed(16)
s0TVs=np.append(s0TVs, np.random.randint(0,2, TestLen)).astype(int)
s1TVs=np.array([i[0] for i in SystmaticVals]).astype(int)
#the random genrator must have a differint seed beween each generation
#call in order to produce differint values for each call
np.random.seed(17)
s1TVs=np.append(s1TVs, np.random.randint(0,2, TestLen)).astype(int)
TestLen=len(xTVs)
SystmaticVals, xTVs, s0TVs, s1TVs
Out[51]:
In [52]:
Peeker.clear()
x=Signal(bool(0)); Peeker(x, 'x')
s0=Signal(bool(0)); Peeker(s0, 's0')
s1=Signal(bool(0)); Peeker(s1, 's1')
y0=Signal(bool(0)); Peeker(y0, 'y0')
y1=Signal(bool(0)); Peeker(y1, 'y1')
y2=Signal(bool(0)); Peeker(y2, 'y2')
y3=Signal(bool(0)); Peeker(y3, 'y3')
DUT=DEMUX1_4_B(x, s0, s1, y0, y1, y2, y3)
def DEMUX1_4_B_TB():
"""
myHDL only testbench for module `DEMUX1_4_Combo`
"""
@instance
def stimules():
for i in range(TestLen):
x.next=int(xTVs[i])
s0.next=int(s0TVs[i])
s1.next=int(s1TVs[i])
yield delay(1)
raise StopSimulation()
return instances()
sim=Simulation(DUT, DEMUX1_4_B_TB(), *Peeker.instances()).run()
In [53]:
Peeker.to_wavedrom('x', 's1', 's0', 'y0', 'y1', 'y2', 'y3')
In [54]:
DEMUX1_4_BData=Peeker.to_dataframe()
DEMUX1_4_BData=DEMUX1_4_BData[['x', 's1', 's0', 'y0', 'y1', 'y2', 'y3']]
DEMUX1_4_BData
Out[54]:
In [55]:
Test=DEMUX1_4_BData==DEMUX1_4_ComboData[['x', 's1', 's0', 'y0', 'y1', 'y2', 'y3']]
Test=Test.all().all()
print(f'DEMUX1_4_B equivlinet to DEMUX1_4_Combo: {Test}')
In [56]:
DUT.convert()
VerilogTextReader('DEMUX1_4_B');
In [57]:
#create BitVectors
xTVs=intbv(int(''.join(xTVs.astype(str)), 2))[TestLen:]
s0TVs=intbv(int(''.join(s0TVs.astype(str)), 2))[TestLen:]
s1TVs=intbv(int(''.join(s1TVs.astype(str)), 2))[TestLen:]
xTVs, bin(xTVs), s0TVs, bin(s0TVs), s1TVs, bin(s1TVs)
Out[57]:
In [58]:
@block
def DEMUX1_4_B_TBV():
"""
myHDL -> testbench for module `DEMUX1_4_B`
"""
x=Signal(bool(0))
s0=Signal(bool(0))
s1=Signal(bool(0))
y0=Signal(bool(0))
y1=Signal(bool(0))
y2=Signal(bool(0))
y3=Signal(bool(0))
@always_comb
def print_data():
print(x, s0, s1, y0, y1, y2, y3)
#Test Signal Bit Vectors
xTV=Signal(xTVs)
s0TV=Signal(s0TVs)
s1TV=Signal(s1TVs)
DUT=DEMUX1_4_B(x, s0, s1, y0, y1, y2, y3)
@instance
def stimules():
for i in range(TestLen):
x.next=int(xTV[i])
s0.next=int(s0TV[i])
s1.next=int(s1TV[i])
yield delay(1)
raise StopSimulation()
return instances()
TB=DEMUX1_4_B_TBV()
TB.convert(hdl="Verilog", initial_values=True)
VerilogTextReader('DEMUX1_4_B_TBV');
DEMUX1_4_B on PYNQ-Z1 (YouTube)
In [59]:
@block
def DEMUX1_4_BV(x, S, Y):
"""
1:4 DEMUX written via behaviorial with
bit vectors
Inputs:
x(bool): input feed
S(2bit vector): channel select bitvector;
min=0, max=3
Outputs:
Y(4bit vector): ouput channel bitvector;
values min=0, max=15; allowed is: 0,1,2,4,8
in this application
"""
@always_comb
def logic():
#here concat is used to build up the word
#from the x input
if S==0:
Y.next=concat(intbv(0)[3:], x); '0001'
elif S==1:
Y.next=concat(intbv(0)[2:], x, intbv(0)[1:]); '0010'
elif S==2:
Y.next=concat(intbv(0)[1:], x, intbv(0)[2:]); '0100'
else:
Y.next=concat(x, intbv(0)[3:]); '1000'
return instances()
In [60]:
xTVs=np.array([0,1])
xTVs=np.append(xTVs, np.random.randint(0,2,6)).astype(int)
TestLen=len(xTVs)
np.random.seed(12)
STVs=np.arange(0,4)
STVs=np.append(STVs, np.random.randint(0,4, 5))
TestLen, xTVs, STVs
Out[60]:
In [61]:
Peeker.clear()
x=Signal(bool(0)); Peeker(x, 'x')
S=Signal(intbv(0)[2:]); Peeker(S, 'S')
Y=Signal(intbv(0)[4:]); Peeker(Y, 'Y')
DUT=DEMUX1_4_BV(x, S, Y)
def DEMUX1_4_BV_TB():
@instance
def stimules():
for i in STVs:
for j in xTVs:
S.next=int(i)
x.next=int(j)
yield delay(1)
raise StopSimulation()
return instances()
sim=Simulation(DUT, DEMUX1_4_BV_TB(), *Peeker.instances()).run()
In [63]:
Peeker.to_wavedrom('x', 'S', 'Y', start_time=0, stop_time=2*TestLen+2)
In [66]:
DEMUX1_4_BVData=Peeker.to_dataframe()
DEMUX1_4_BVData=DEMUX1_4_BVData[['x', 'S', 'Y']]
DEMUX1_4_BVData
Out[66]:
In [67]:
DEMUX1_4_BVData['y0']=None; DEMUX1_4_BVData['y1']=None; DEMUX1_4_BVData['y2']=None; DEMUX1_4_BVData['y3']=None
DEMUX1_4_BVData[['y3', 'y2', 'y1', 'y0']]=DEMUX1_4_BVData[['Y']].apply(lambda bv: [int(i) for i in bin(bv, 4)], axis=1, result_type='expand')
DEMUX1_4_BVData['s0']=None; DEMUX1_4_BVData['s1']=None
DEMUX1_4_BVData[['s1', 's0']]=DEMUX1_4_BVData[['S']].apply(lambda bv: [int(i) for i in bin(bv, 2)], axis=1, result_type='expand')
DEMUX1_4_BVData=DEMUX1_4_BVData[['x', 'S', 's0', 's1', 'Y', 'y3', 'y2', 'y1', 'y0']]
DEMUX1_4_BVData
Out[67]:
In [70]:
DEMUX1_4_BVData['y0Ref']=DEMUX1_4_BVData.apply(lambda row:y14_0EqN(row['x'], row['s0'], row['s1']), axis=1).astype(int)
DEMUX1_4_BVData['y1Ref']=DEMUX1_4_BVData.apply(lambda row:y14_1EqN(row['x'], row['s0'], row['s1']), axis=1).astype(int)
DEMUX1_4_BVData['y2Ref']=DEMUX1_4_BVData.apply(lambda row:y14_2EqN(row['x'], row['s0'], row['s1']), axis=1).astype(int)
DEMUX1_4_BVData['y3Ref']=DEMUX1_4_BVData.apply(lambda row:y14_3EqN(row['x'], row['s0'], row['s1']), axis=1).astype(int)
DEMUX1_4_BVData
Out[70]:
In [84]:
Test=DEMUX1_4_BVData[['y0', 'y1', 'y2', 'y3']].sort_index(inplace=True)==DEMUX1_4_BVData[['y0Ref', 'y1Ref', 'y2Ref', 'y3Ref']].sort_index(inplace=True)
print(f'Module `DEMUX1_4_BVData` works as exspected: {Test}')
In [85]:
DUT.convert()
VerilogTextReader('DEMUX1_4_BV');
In [86]:
ConstraintXDCTextReader('DEMUX1_4_BV');
DEMUX1_4_BV on PYNQ-Z1 (YouTube)