\title{Digital Flip-Flops with myHDL} \author{Steven K Armour} \maketitle

Refs

@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} }

Acknowledgments

Author of myHDL Jan Decaluwe and the author of the myHDL Peeker XESS Corp.

Draw.io

Xilinx

Python Libraries Utilized


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 *

Flip-Flops vs Latches

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

D-FlipFlop

Sync

Center Clock


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]:
D_in Q_out Qn_out clk
0 0 0 0 0
1 0 0 1 1
2 1 0 1 0
3 1 1 0 1
4 1 1 0 0
5 1 1 0 1
6 0 1 0 0
7 0 0 1 1

Sythinsis


In [13]:
toVerilog(DFFSyncCenter, D_in, Q_out, Qn_out, clk)
_=VerilogTextReader('DFFSyncCenter')


***Verilog modual from DFFSyncCenter.v***

 // File: DFFSyncCenter.v
// Generated by MyHDL 0.9.0
// Date: Thu Oct 26 01:02:57 2017


`timescale 1ns/10ps

module DFFSyncCenter (
    D_in,
    Q_out,
    Qn_out,
    clk
);


input D_in;
output Q_out;
reg Q_out;
output Qn_out;
reg Qn_out;
input clk;






always @(clk) begin: DFFSYNCCENTER_LOGIC
    Q_out <= D_in;
    Qn_out <= (!D_in);
end

endmodule

!? clock in not hooked up on the wiring in this code need to figure out why suspect it is the @always(clk)

PosEdge


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)


Sythinsis


In [18]:
toVerilog(DFFSyncPosEdge, D_in, Q_out, Qn_out, clk)
_=VerilogTextReader('DFFSyncPosEdge')


***Verilog modual from DFFSyncPosEdge.v***

 // File: DFFSyncPosEdge.v
// Generated by MyHDL 0.9.0
// Date: Thu Oct 26 01:05:13 2017


`timescale 1ns/10ps

module DFFSyncPosEdge (
    D_in,
    Q_out,
    Qn_out,
    clk
);


input D_in;
output Q_out;
reg Q_out;
output Qn_out;
reg Qn_out;
input clk;






always @(posedge clk) begin: DFFSYNCPOSEDGE_LOGIC
    Q_out <= D_in;
    Qn_out <= (!D_in);
end

endmodule

The following shows the Xilinx's Vivado 2016.1 RTL generated schematic of our myHDL Syncrones Postive Edge D Flip-Flop's verilog code

NegEdge


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)


! Need to put in comment about if pos use Neg in Test Bench and vis versa, but still need to verify

In [24]:
toVerilog(DFFSyncNegEdge, D_in, Q_out, Qn_out, clk)
_=VerilogTextReader('DFFSyncNegEdge')


***Verilog modual from DFFSyncNegEdge.v***

 // File: DFFSyncNegEdge.v
// Generated by MyHDL 0.9.0
// Date: Thu Oct 26 01:11:08 2017


`timescale 1ns/10ps

module DFFSyncNegEdge (
    D_in,
    Q_out,
    Qn_out,
    clk
);


input D_in;
output Q_out;
reg Q_out;
output Qn_out;
reg Qn_out;
input clk;






always @(negedge clk) begin: DFFSYNCNEGEDGE_LOGIC
    Q_out <= D_in;
    Qn_out <= (!D_in);
end

endmodule

The following shows the Xilinx's Vivado 2016.1 RTL generated schematic of our myHDL Syncrones Postive Edge D Flip-Flop's verilog code

Asyncroness

SR Flip Flop

JK Flip Flop

T Flip Flop


In [ ]: