\title{Digital Flip-Flops with myHDL} \author{Steven K Armour} \maketitle
@book{brown_vranesic_2014, place={New York, NY}, edition={3}, title={Fundamentals of digital logic with Verilog design}, publisher={McGraw-Hill}, author={Brown, Stephen and Vranesic, Zvonko G}, year={2014} }, @book{lameres_2017, title={Introduction to logic circuits & logic design with Verilog}, publisher={springer}, author={LaMeres, Brock J}, year={2017} }
In [1]:
import numpy as np
import pandas as pd
from sympy import *
init_printing()
from myhdl import *
from myhdlpeek import *
import random
#python file of convince tools. Should be located with this notebook
from sympy_myhdl_tools import *
Latches and Flip-Flops are both metastaple logic circuit tobologies in that once loaded with a state they hold that state information till that state is upset by a new state or a reset command. But the diffrance between the two is that Flip-Flops are clock controlled devices built upon Latches where as Latches are not clock dependent. And not only are Flip-Flops CLocked controlled but can be asynchronous or synchronous
In [9]:
def DFFSyncCenter(D_in, Q_out, Qn_out, clk):
@always(clk)
def logic():
Q_out.next=D_in
Qn_out.next=not D_in
return logic
In [10]:
Peeker.clear()
D_in, Q_out, Qn_out, clk=[Signal(bool(0)) for _ in range(4)]
Peeker(D_in, 'D_in'); Peeker(clk, 'clk')
Peeker(Q_out, 'Q_out'); Peeker(Qn_out, 'Qn_out')
DUT=DFFSyncCenter(D_in=D_in, Q_out=Q_out, Qn_out=Qn_out, clk=clk)
inputs=[D_in]
time=[0]
def DFFSync_TB(inputs=[]):
#the # of inputs contorls everything
Ninputs=len(inputs)
tmax=2*2**Ninputs
#genrate sequantil number of inputs for comparsion to known
SequntialInputs=np.arange(2**Ninputs)
@always(delay(1))
def clkGen():
clk.next = not clk
@always(clk.negedge)
def stimulus():
time.append(time[-1]+1)
#run sequantial
try:
#genrate binary bit repsersintion of current sequantl input
NextSeqInput=np.binary_repr(SequntialInputs[time[-1]], width=Ninputs)
#pass each bit into the inputs
for i in range(Ninputs):
inputs[i].next=bool(int(NextSeqInput[i]))
#run the random to cheack for unexsected behavior
except IndexError:
NextRanInput=[random.randint(0,1) for i in range(Ninputs)]
for i in range(Ninputs):
inputs[i].next=NextRanInput[i]
if time[-1]==tmax:
raise StopSimulation
return clkGen, stimulus
In [11]:
Sim=Simulation(DUT, DFFSync_TB(inputs), *Peeker.instances()).run()
Peeker.to_wavedrom(start_time=0, tock=True)
In [12]:
MakeDFfromPeeker(Peeker.to_wavejson(start_time=0))
Out[12]:
In [13]:
toVerilog(DFFSyncCenter, D_in, Q_out, Qn_out, clk)
_=VerilogTextReader('DFFSyncCenter')
!? clock in not hooked up on the wiring in this code need to figure out why
suspect it is the @always(clk)
In [15]:
def DFFSyncPosEdge(D_in, Q_out, Qn_out, clk):
@always(clk.posedge)
def logic():
Q_out.next=D_in
Qn_out.next=not D_in
return logic
In [16]:
Peeker.clear()
D_in, Q_out, Qn_out, clk=[Signal(bool(0)) for _ in range(4)]
Peeker(D_in, 'D_in'); Peeker(clk, 'clk')
Peeker(Q_out, 'Q_out'); Peeker(Qn_out, 'Qn_out')
DUT=DFFSyncPosEdge(D_in=D_in, Q_out=Q_out, Qn_out=Qn_out, clk=clk)
inputs=[D_in]
time=[0]
def DFFSync_TB(inputs=[]):
#the # of inputs contorls everything
Ninputs=len(inputs)
tmax=2*2**Ninputs
#genrate sequantil number of inputs for comparsion to known
SequntialInputs=np.arange(2**Ninputs)
@always(delay(1))
def clkGen():
clk.next = not clk
@always(clk.negedge)
def stimulus():
time.append(time[-1]+1)
#run sequantial
try:
#genrate binary bit repsersintion of current sequantl input
NextSeqInput=np.binary_repr(SequntialInputs[time[-1]], width=Ninputs)
#pass each bit into the inputs
for i in range(Ninputs):
inputs[i].next=bool(int(NextSeqInput[i]))
#run the random to cheack for unexsected behavior
except IndexError:
NextRanInput=[random.randint(0,1) for i in range(Ninputs)]
for i in range(Ninputs):
inputs[i].next=NextRanInput[i]
if time[-1]==tmax:
raise StopSimulation
return clkGen, stimulus
In [17]:
Sim=Simulation(DUT, DFFSync_TB(inputs), *Peeker.instances()).run()
Peeker.to_wavedrom(start_time=0, tock=True)
In [18]:
toVerilog(DFFSyncPosEdge, D_in, Q_out, Qn_out, clk)
_=VerilogTextReader('DFFSyncPosEdge')
The following shows the Xilinx's Vivado 2016.1 RTL generated schematic of our myHDL Syncrones Postive Edge D Flip-Flop's verilog code
In [19]:
def DFFSyncNegEdge(D_in, Q_out, Qn_out, clk):
@always(clk.negedge)
def logic():
Q_out.next=D_in
Qn_out.next=not D_in
return logic
In [22]:
Peeker.clear()
D_in, Q_out, Qn_out, clk=[Signal(bool(0)) for _ in range(4)]
Peeker(D_in, 'D_in'); Peeker(clk, 'clk')
Peeker(Q_out, 'Q_out'); Peeker(Qn_out, 'Qn_out')
DUT=DFFSyncNegEdge(D_in=D_in, Q_out=Q_out, Qn_out=Qn_out, clk=clk)
inputs=[D_in]
time=[0]
def DFFSync_TB(inputs=[]):
#the # of inputs contorls everything
Ninputs=len(inputs)
tmax=2*2**Ninputs
#genrate sequantil number of inputs for comparsion to known
SequntialInputs=np.arange(2**Ninputs)
@always(delay(1))
def clkGen():
clk.next = not clk
@always(clk.posedge)
def stimulus():
time.append(time[-1]+1)
#run sequantial
try:
#genrate binary bit repsersintion of current sequantl input
NextSeqInput=np.binary_repr(SequntialInputs[time[-1]], width=Ninputs)
#pass each bit into the inputs
for i in range(Ninputs):
inputs[i].next=bool(int(NextSeqInput[i]))
#run the random to cheack for unexsected behavior
except IndexError:
NextRanInput=[random.randint(0,1) for i in range(Ninputs)]
for i in range(Ninputs):
inputs[i].next=NextRanInput[i]
if time[-1]==tmax:
raise StopSimulation
return clkGen, stimulus
In [23]:
Sim=Simulation(DUT, DFFSync_TB(inputs), *Peeker.instances()).run()
Peeker.to_wavedrom(start_time=0, tock=True)
In [24]:
toVerilog(DFFSyncNegEdge, D_in, Q_out, Qn_out, clk)
_=VerilogTextReader('DFFSyncNegEdge')
The following shows the Xilinx's Vivado 2016.1 RTL generated schematic of our myHDL Syncrones Postive Edge D Flip-Flop's verilog code
In [ ]: