\title{First in First out (FIFO) memory in myHDL} \author{Steven K Armour} \maketitle

The FIFO memory, also called queue-ed (as in an English queue) memory is a common write-read scheme employed with sequential memory such as time measurements. The fundamental scheme is that the first data to be written into the memory storage(RAM, etc) is the first to be read out followed by the second data read and so on.

References

@misc{loi le_2017, title={Verilog code for FIFO memory}, url={http://www.fpga4student.com/2017/01/verilog-code-for-fifo-memory.html}, journal={Fpga4student.com}, author={Loi Le, Van}, year={2017} }

Libarys and Helper functions


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 random

#https://github.com/jrjohansson/version_information
%load_ext version_information
%version_information myhdl, myhdlpeek, numpy, pandas, matplotlib, sympy, random


Out[1]:
SoftwareVersion
Python3.6.2 64bit [GCC 4.4.7 20120313 (Red Hat 4.4.7-1)]
IPython6.2.1
OSLinux 4.15.0 30 generic x86_64 with debian stretch sid
myhdl0.10
myhdlpeek0.0.6
numpy1.13.3
pandas0.23.3
matplotlib2.1.0
sympy1.1.2.dev
randomThe 'random' distribution was not found and is required by the application
Tue Aug 14 03:08:26 2018 MDT

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

Writer Pointer

In order to use RAM memory, we must employ memory pointers which are values stored in the FIFO that tell the FIFO where the memory is stored. The write pointer (wptr) is an incremental counter that is increased for each data entry that is added to the memory. Thus the write_pointer is simply a counter with some extra controls

\begin{figure} \centerline{\includegraphics[width=10cm]{WriterPointer.png}} \caption{\label{fig:WP} Writer Pointer Functianl Digram } \end{figure}

In [3]:
@block
def write_pointer(wr, fifo_full, wptr, fifo_we, clk, rst_n):
    """
    Input:
        wr(bool):write signal
        fifo_full(bool): fifo full signal
        clk(bool): clock
        rst_n(bool): negtive reset signal
        
    Ouput:
        wptr(5bit): the write in memory pointer
        fifo_we(bool): the write enable indication signal
    """
    
    fifo_we_i=Signal(bool(0))
    @always_comb
    def enableLogic():
        fifo_we_i.next= not fifo_full and wr
    
    #counter
    wptr_i=Signal(intbv(0)[5:0])
    @always(clk.posedge, rst_n.negedge)
    def pointerUpdate():
        if rst_n:
            wptr_i.next=0
        elif fifo_we_i:
            wptr_i.next=wptr_i+1
        else:
            wptr_i.next=wptr_i
    
    @always_comb
    def OuputBuffer():
        fifo_we.next=fifo_we_i
        wptr.next=wptr_i
    
    return instances()

myHDL Testing


In [4]:
Peeker.clear()
wr=Signal(bool(0)); Peeker(wr, 'wr')
fifo_full=Signal(bool(0)); Peeker(fifo_full, 'fifo_full')
wptr=Signal(intbv(0)[5:]); Peeker(wptr, 'wptr')
fifo_we=Signal(bool(0)); Peeker(fifo_we, 'fifo_we')
clk=Signal(bool(0)); Peeker(clk, 'clk')
rst_n=Signal(bool(0)); Peeker(rst_n, 'rst_n')

DUT=write_pointer(wr, fifo_full, wptr, fifo_we, clk, rst_n)

def write_pointerTB():
    """
    myHDL only Testbench for `write_pointer module`
    """
    
    @always(delay(1))
    def ClkGen():
        clk.next=not clk
    
    @instance
    def stimules():
        i=0
        while True:
            if i==0:
                wr.next=1
            elif i==10:
                wr.next=0
            elif i==12:
                wr.next=1
            elif i==14:
                fifo_full.next=1
            elif i==16:
                rst_n.next=1
            elif i==18:
                rst_n.next=0
            elif i==20:
                raise StopSimulation()
            
            i+=1
            yield clk.posedge
            
    
    return instances()
    
    
sim=Simulation(DUT, write_pointerTB(), *Peeker.instances()).run()

In [5]:
Peeker.to_wavedrom()



In [6]:
write_pointerData=Peeker.to_dataframe()
write_pointerData=write_pointerData[write_pointerData['clk']==1]
write_pointerData.drop('clk', axis=1, inplace=True)
write_pointerData.reset_index(drop=True, inplace=True)
write_pointerData


Out[6]:
fifo_full fifo_we rst_n wptr wr
0 0 1 0 1 1
1 0 1 0 2 1
2 0 1 0 3 1
3 0 1 0 4 1
4 0 1 0 5 1
5 0 1 0 6 1
6 0 1 0 7 1
7 0 1 0 8 1
8 0 1 0 9 1
9 0 0 0 10 0
10 0 0 0 10 0
11 0 1 0 10 1
12 0 1 0 11 1
13 1 0 0 12 1
14 1 0 0 12 1
15 1 0 1 12 1
16 1 0 1 0 1
17 1 0 0 0 1
18 1 0 0 0 1

Verilog Code


In [7]:
DUT.convert()
VerilogTextReader('write_pointer');


***Verilog modual from write_pointer.v***

 // File: write_pointer.v
// Generated by MyHDL 0.10
// Date: Tue Aug 14 03:08:27 2018


`timescale 1ns/10ps

module write_pointer (
    wr,
    fifo_full,
    wptr,
    fifo_we,
    clk,
    rst_n
);
// Input:
//     wr(bool):write signal
//     fifo_full(bool): fifo full signal
//     clk(bool): clock
//     rst_n(bool): negtive reset signal
//     
// Ouput:
//     wptr(5bit): the write in memory pointer
//     fifo_we(bool): the write enable indication signal

input wr;
input fifo_full;
output [4:0] wptr;
wire [4:0] wptr;
output fifo_we;
wire fifo_we;
input clk;
input rst_n;

wire fifo_we_i;
reg [4:0] wptr_i;




assign fifo_we_i = ((!fifo_full) && wr);


always @(posedge clk, negedge rst_n) begin: WRITE_POINTER_POINTERUPDATE
    if (rst_n) begin
        wptr_i <= 0;
    end
    else if (fifo_we_i) begin
        wptr_i <= (wptr_i + 1);
    end
    else begin
        wptr_i <= wptr_i;
    end
end



assign fifo_we = fifo_we_i;
assign wptr = wptr_i;

endmodule

\begin{figure} \centerline{\includegraphics[width=10cm]{write_pointerRTL.png}} \caption{\label{fig:WPRTL} write_pointer RTL schematic; Xilinx Vivado 2017.4} \end{figure}
\begin{figure} \centerline{\includegraphics[width=10cm]{write_pointerSyn.png}} \caption{\label{fig:WPSYN} write_pointer Synthesized schematic; Xilinx Vivado 2017.4} \end{figure}

Verilog Testbench


In [8]:
@block
def write_pointerTBV():
    """
    myHDL->Verilog  Testbench for `write_pointer module`
    """
    wr=Signal(bool(0))
    fifo_full=Signal(bool(0))
    wptr=Signal(intbv(0)[5:])
    fifo_we=Signal(bool(0))
    clk=Signal(bool(0))
    rst_n=Signal(bool(0))
    
    @always_comb
    def print_data():
        print(wr, fifo_full, wptr, fifo_we, clk, rst_n)

    DUT=write_pointer(wr, fifo_full, wptr, fifo_we, clk, rst_n)


    
    @instance
    def clk_signal():
        while True:
            clk.next = not clk
            yield delay(1)
    
    @instance
    def stimules():
        i=0
        while True:
            if i==0:
                wr.next=1
            elif i==10:
                wr.next=0
            elif i==12:
                wr.next=1
            elif i==14:
                fifo_full.next=1
            elif i==16:
                rst_n.next=1
            elif i==18:
                rst_n.next=0
            elif i==20:
                raise StopSimulation()
            else:
                pass
            
            i+=1
            yield clk.posedge
            
    
    return instances()
    
    
TB=write_pointerTBV()
TB.convert(hdl="Verilog", initial_values=True)
VerilogTextReader('write_pointerTBV');


<class 'myhdl._Signal._Signal'> <class '_ast.Name'>
<class 'myhdl._Signal._Signal'> <class '_ast.Name'>
<class 'myhdl._Signal._Signal'> <class '_ast.Name'>
<class 'myhdl._Signal._Signal'> <class '_ast.Name'>
<class 'myhdl._Signal._Signal'> <class '_ast.Name'>
<class 'myhdl._Signal._Signal'> <class '_ast.Name'>
***Verilog modual from write_pointerTBV.v***

 // File: write_pointerTBV.v
// Generated by MyHDL 0.10
// Date: Tue Aug 14 03:08:28 2018


`timescale 1ns/10ps

module write_pointerTBV (

);
// myHDL->Verilog  Testbench for `write_pointer module`


reg wr = 0;
reg fifo_full = 0;
wire [4:0] wptr;
wire fifo_we;
reg clk = 0;
reg rst_n = 0;
wire write_pointer0_0_fifo_we_i;
reg [4:0] write_pointer0_0_wptr_i = 0;



always @(fifo_full, clk, wr, fifo_we, wptr, rst_n) begin: WRITE_POINTERTBV_PRINT_DATA
    $write("%h", wr);
    $write(" ");
    $write("%h", fifo_full);
    $write(" ");
    $write("%h", wptr);
    $write(" ");
    $write("%h", fifo_we);
    $write(" ");
    $write("%h", clk);
    $write(" ");
    $write("%h", rst_n);
    $write("\n");
end



assign write_pointer0_0_fifo_we_i = ((!fifo_full) && wr);


always @(posedge clk, negedge rst_n) begin: WRITE_POINTERTBV_WRITE_POINTER0_0_POINTERUPDATE
    if (rst_n) begin
        write_pointer0_0_wptr_i <= 0;
    end
    else if (write_pointer0_0_fifo_we_i) begin
        write_pointer0_0_wptr_i <= (write_pointer0_0_wptr_i + 1);
    end
    else begin
        write_pointer0_0_wptr_i <= write_pointer0_0_wptr_i;
    end
end



assign fifo_we = write_pointer0_0_fifo_we_i;
assign wptr = write_pointer0_0_wptr_i;


initial begin: WRITE_POINTERTBV_CLK_SIGNAL
    while (1'b1) begin
        clk <= (!clk);
        # 1;
    end
end


initial begin: WRITE_POINTERTBV_STIMULES
    integer i;
    i = 0;
    while (1'b1) begin
        case (i)
            'h0: begin
                wr <= 1;
            end
            'ha: begin
                wr <= 0;
            end
            'hc: begin
                wr <= 1;
            end
            'he: begin
                fifo_full <= 1;
            end
            'h10: begin
                rst_n <= 1;
            end
            'h12: begin
                rst_n <= 0;
            end
            'h14: begin
                $finish;
            end
            default: begin
                // pass
            end
        endcase
        i = i + 1;
        @(posedge clk);
    end
end

endmodule

Read Pointer

The Read pointer serves the same function as the write_pointer but increments the read pointer that calls up sequentially the memory location to read from.

\begin{figure} \centerline{\includegraphics[width=10cm]{ReadPointer.png}} \caption{\label{fig:RP} Read Pointer Functianl Digram } \end{figure}

In [9]:
@block
def read_pointer(rd, fifo_empty, rptr, fifo_rd, clk, rst_n):
    """
    Input:
        rd(bool):write signal
        fifo_empty(bool): fifo empty signal
        clk(bool): clock
        rst_n(bool): negtive reset signal
        
    Ouput:
        rptr(5bit): the read out memory pointer
        fifo_rd(bool): the read enable indication signal
    """
    
    fifo_rd_i=Signal(bool(0))
    @always_comb
    def enableLogic():
        fifo_rd_i.next=not fifo_empty and rd
    
    rptr_i=Signal(intbv(0)[5:0])
    @always(clk.posedge, rst_n.negedge)
    def pointerUpdate():
        if rst_n:
            rptr_i.next=0
        elif fifo_rd_i:
            rptr_i.next=rptr_i+1
        else:
            rptr_i.next=rptr_i
    
    
    @always_comb
    def output():
        fifo_rd.next=fifo_rd_i
        rptr.next=rptr_i
    
    return instances()

myHDL testing


In [10]:
Peeker.clear()
rd=Signal(bool(0)); Peeker(rd, 'rd')
fifo_empty=Signal(bool(0)); Peeker(fifo_empty, 'fifo_empty')
rptr=Signal(intbv(0)[5:]); Peeker(rptr, 'rptr')
fifo_rd=Signal(bool(0)); Peeker(fifo_rd, 'fifo_rd')
clk=Signal(bool(0)); Peeker(clk, 'clk')
rst_n=Signal(bool(0)); Peeker(rst_n, 'rst_n')

DUT=read_pointer(rd, fifo_empty, rptr, fifo_rd, clk, rst_n)

def read_pointerTB():
    """
    myHDL only Testbench for `read_pointer module`

    """
    
    @always(delay(1))
    def ClkGen():
        clk.next=not clk
    
    @instance
    def stimules():
        i=0
        while True:
            if i==0:
                rd.next=1
            elif i==10:
                rd.next=0
            elif i==12:
                rd.next=1
            elif i==14:
                fifo_empty.next=1
            elif i==16:
                rst_n.next=1
            elif i==18:
                rst_n.next=0
            elif i==20:
                raise StopSimulation()
            
            i+=1
            yield clk.posedge
            
    
    return instances()
    
    
sim=Simulation(DUT, read_pointerTB(), *Peeker.instances()).run()

In [11]:
Peeker.to_wavedrom()



In [12]:
read_pointerData=Peeker.to_dataframe()
read_pointerData=read_pointerData[read_pointerData['clk']==1]
read_pointerData.drop('clk', axis=1, inplace=True)
read_pointerData.reset_index(drop=True, inplace=True)
read_pointerData


Out[12]:
fifo_empty fifo_rd rd rptr rst_n
0 0 1 1 1 0
1 0 1 1 2 0
2 0 1 1 3 0
3 0 1 1 4 0
4 0 1 1 5 0
5 0 1 1 6 0
6 0 1 1 7 0
7 0 1 1 8 0
8 0 1 1 9 0
9 0 0 0 10 0
10 0 0 0 10 0
11 0 1 1 10 0
12 0 1 1 11 0
13 1 0 1 12 0
14 1 0 1 12 0
15 1 0 1 12 1
16 1 0 1 0 1
17 1 0 1 0 0
18 1 0 1 0 0

Verilog Code


In [13]:
DUT.convert()
VerilogTextReader('read_pointer');


***Verilog modual from read_pointer.v***

 // File: read_pointer.v
// Generated by MyHDL 0.10
// Date: Tue Aug 14 03:08:29 2018


`timescale 1ns/10ps

module read_pointer (
    rd,
    fifo_empty,
    rptr,
    fifo_rd,
    clk,
    rst_n
);
// Input:
//     rd(bool):write signal
//     fifo_empty(bool): fifo empty signal
//     clk(bool): clock
//     rst_n(bool): negtive reset signal
//     
// Ouput:
//     rptr(5bit): the read out memory pointer
//     fifo_rd(bool): the read enable indication signal

input rd;
input fifo_empty;
output [4:0] rptr;
wire [4:0] rptr;
output fifo_rd;
wire fifo_rd;
input clk;
input rst_n;

wire fifo_rd_i;
reg [4:0] rptr_i = 0;




assign fifo_rd_i = ((!fifo_empty) && rd);


always @(posedge clk, negedge rst_n) begin: READ_POINTER_POINTERUPDATE
    if (rst_n) begin
        rptr_i <= 0;
    end
    else if (fifo_rd_i) begin
        rptr_i <= (rptr_i + 1);
    end
    else begin
        rptr_i <= rptr_i;
    end
end



assign fifo_rd = fifo_rd_i;
assign rptr = rptr_i;

endmodule

\begin{figure} \centerline{\includegraphics[width=10cm]{read_pointerRTL.png}} \caption{\label{fig:RPRTL} read_pointer RTL Schematic; Xilinx Vivado 2017.4} \end{figure}
\begin{figure} \centerline{\includegraphics[width=10cm]{read_pointerSYN.png}} \caption{\label{fig:RPRTL} read_pointer Synthesized schematic; Xilinx Vivado 2017.4} \end{figure}

Verilog Testbench


In [14]:
@block
def read_pointerTBV():
    """
    myHDL -> Verilog Testbench for `read_pointer` module

    """
    rd=Signal(bool(0))
    fifo_empty=Signal(bool(0))
    rptr=Signal(intbv(0)[5:])
    fifo_rd=Signal(bool(0))
    clk=Signal(bool(0))
    rst_n=Signal(bool(0))
    
    @always_comb
    def print_data():
        print(rd, fifo_empty, rptr, fifo_rd, clk, rst_n)

    DUT=read_pointer(rd, fifo_empty, rptr, fifo_rd, clk, rst_n)


    
    @instance
    def clk_signal():
        while True:
            clk.next = not clk
            yield delay(1)
    
    @instance
    def stimules():
        i=0
        while True:
            if i==0:
                rd.next=1
            elif i==10:
                rd.next=0
            elif i==12:
                rd.next=1
            elif i==14:
                fifo_empty.next=1
            elif i==16:
                rst_n.next=1
            elif i==18:
                rst_n.next=0
            elif i==20:
                raise StopSimulation()
            else:
                pass
            
            i+=1
            yield clk.posedge
            
    
    return instances()
    
    
TB=read_pointerTBV()
TB.convert(hdl="Verilog", initial_values=True)
VerilogTextReader('read_pointerTBV');


<class 'myhdl._Signal._Signal'> <class '_ast.Name'>
<class 'myhdl._Signal._Signal'> <class '_ast.Name'>
<class 'myhdl._Signal._Signal'> <class '_ast.Name'>
<class 'myhdl._Signal._Signal'> <class '_ast.Name'>
<class 'myhdl._Signal._Signal'> <class '_ast.Name'>
<class 'myhdl._Signal._Signal'> <class '_ast.Name'>
***Verilog modual from read_pointerTBV.v***

 // File: read_pointerTBV.v
// Generated by MyHDL 0.10
// Date: Tue Aug 14 03:08:30 2018


`timescale 1ns/10ps

module read_pointerTBV (

);
// myHDL -> Verilog Testbench for `read_pointer` module


reg clk = 0;
reg rst_n = 0;
reg rd = 0;
reg fifo_empty = 0;
wire [4:0] rptr;
wire fifo_rd;
wire read_pointer0_0_fifo_rd_i;
reg [4:0] read_pointer0_0_rptr_i = 0;



always @(rd, clk, fifo_empty, fifo_rd, rptr, rst_n) begin: READ_POINTERTBV_PRINT_DATA
    $write("%h", rd);
    $write(" ");
    $write("%h", fifo_empty);
    $write(" ");
    $write("%h", rptr);
    $write(" ");
    $write("%h", fifo_rd);
    $write(" ");
    $write("%h", clk);
    $write(" ");
    $write("%h", rst_n);
    $write("\n");
end



assign read_pointer0_0_fifo_rd_i = ((!fifo_empty) && rd);


always @(posedge clk, negedge rst_n) begin: READ_POINTERTBV_READ_POINTER0_0_POINTERUPDATE
    if (rst_n) begin
        read_pointer0_0_rptr_i <= 0;
    end
    else if (read_pointer0_0_fifo_rd_i) begin
        read_pointer0_0_rptr_i <= (read_pointer0_0_rptr_i + 1);
    end
    else begin
        read_pointer0_0_rptr_i <= read_pointer0_0_rptr_i;
    end
end



assign fifo_rd = read_pointer0_0_fifo_rd_i;
assign rptr = read_pointer0_0_rptr_i;


initial begin: READ_POINTERTBV_CLK_SIGNAL
    while (1'b1) begin
        clk <= (!clk);
        # 1;
    end
end


initial begin: READ_POINTERTBV_STIMULES
    integer i;
    i = 0;
    while (1'b1) begin
        case (i)
            'h0: begin
                rd <= 1;
            end
            'ha: begin
                rd <= 0;
            end
            'hc: begin
                rd <= 1;
            end
            'he: begin
                fifo_empty <= 1;
            end
            'h10: begin
                rst_n <= 1;
            end
            'h12: begin
                rst_n <= 0;
            end
            'h14: begin
                $finish;
            end
            default: begin
                // pass
            end
        endcase
        i = i + 1;
        @(posedge clk);
    end
end

endmodule

Memory Array

The memory array is a simple RAM memory that uses the wptr to assign the data_in location in the RAM and the rptr to pull the memory to output to data_out

\begin{figure} \centerline{\includegraphics[width=10cm]{Memory_array.png}} \caption{\label{fig:WP} Memory Array Functional Diagram} \end{figure}

In [15]:
@block
def memory_array(data_in, fifo_we, wptr, rptr, data_out, clk, clear):
    """
    Input:
        data_in(8bit): data to be writen 
        fifo_we(bool): write enable
        wptr(5bit): write memory address pointer
        rptr(5bit): read memory address pointer
        clk(bool): clock
        clear(bool): signal to clear clear memeory to 0 
    Ouput:
        data_out(8bit): data to be read out based on`rptr`
    """
    data_out_i=[Signal(intbv(0)[8:]) for _ in range(16)]
    @always(clk.posedge)
    def uptake():
        if fifo_we:
            data_out_i[wptr[4:]].next=data_in
    
    @always_comb
    def output():
        data_out.next=data_out_i[rptr[4:]]
    
    @always(clear.negedge)
    def clearMem():
        for i in range(16):
            data_out_i[i].next=0
        
    
    
    return instances()

myHDL Testing


In [16]:
Peeker.clear()
data_in=Signal(intbv(0)[8:]); Peeker(data_in, 'data_in')
fifo_we=Signal(bool(0)); Peeker(fifo_we, 'fifo_we') 
wptr=Signal(intbv(0)[5:]); Peeker(wptr, 'wptr')
rptr=Signal(intbv(0)[5:]); Peeker(rptr, 'rptr')
data_out=Signal(intbv(0)[8:]); Peeker(data_out, 'data_out') 
clk=Signal(bool(0)); Peeker(clk, 'clk')
clear=Signal(bool(0)); Peeker(clear, 'clear')

TestData=np.random.randint(low=data_in.min, high=data_in.max, 
                           size=16)
TestData=TestData.astype(int)

DUT=memory_array(data_in, fifo_we, wptr, rptr, data_out, clk, clear)


def memory_arrayTB():
    """
    myHDL only testbench for `memory_array` module
    """
    @instance
    def clk_signal():
        while True:
            clk.next = not clk
            yield delay(1)
    
    @instance
    def stimules():
        i=0
        while True:
            if i==0:
                fifo_we.next=0
            elif i==2:
                fifo_we.next=1
            
            elif i==13:
                clear.next=1
            elif i==14:
                clear.next=0
                
            elif i==16:
                raise StopSimulation()
            data_in.next=int(TestData[wptr])
            wptr.next=wptr+1
            if i!=0:
                rptr.next=rptr+1
            i+=1
            yield clk.posedge
    
    return instances()

sim=Simulation(DUT, memory_arrayTB(), *Peeker.instances()).run()

In [17]:
Peeker.to_wavedrom()



In [18]:
memoryData=Peeker.to_dataframe()
memoryData=memoryData[memoryData['clk']==1]
memoryData.drop('clk', axis=1, inplace=True)
memoryData.reset_index(drop=True, inplace=True)
memoryData


Out[18]:
clear data_in data_out fifo_we rptr wptr
0 0 163 0 0 1 2
1 0 46 0 1 2 3
2 0 236 46 1 3 4
3 0 3 236 1 4 5
4 0 120 3 1 5 6
5 0 201 120 1 6 7
6 0 46 201 1 7 8
7 0 202 46 1 8 9
8 0 234 202 1 9 10
9 0 36 234 1 10 11
10 0 19 36 1 11 12
11 0 90 19 1 12 13
12 1 162 90 1 13 14
13 0 44 0 1 14 15
14 0 184 44 1 15 16

In [19]:
memoryData.drop([0, 1], axis=0, inplace=True)
memoryData.drop(['fifo_we', 'rptr', 'wptr'], axis=1, inplace=True)
memoryData.reset_index(inplace=True, drop=True)
memoryData['data_out_shift-1']=np.array(memoryData.data_out.shift(-1)).astype(int)
memoryData.drop(12, axis=0, inplace=True)
memoryData


Out[19]:
clear data_in data_out data_out_shift-1
0 0 236 46 236
1 0 3 236 3
2 0 120 3 120
3 0 201 120 201
4 0 46 201 46
5 0 202 46 202
6 0 234 202 234
7 0 36 234 36
8 0 19 36 19
9 0 90 19 90
10 1 162 90 0
11 0 44 0 44

In [20]:
(memoryData['data_in']==memoryData['data_out_shift-1']).all()


Out[20]:
False

Verilog Code


In [21]:
DUT.convert()
VerilogTextReader('memory_array');


***Verilog modual from memory_array.v***

 // File: memory_array.v
// Generated by MyHDL 0.10
// Date: Tue Aug 14 03:08:31 2018


`timescale 1ns/10ps

module memory_array (
    data_in,
    fifo_we,
    wptr,
    rptr,
    data_out,
    clk,
    clear
);
// Input:
//     data_in(8bit): data to be writen 
//     fifo_we(bool): write enable
//     wptr(5bit): write memory address pointer
//     rptr(5bit): read memory address pointer
//     clk(bool): clock
//     clear(bool): signal to clear clear memeory to 0 
// Ouput:
//     data_out(8bit): data to be read out based on`rptr`

input [7:0] data_in;
input fifo_we;
input [4:0] wptr;
input [4:0] rptr;
output [7:0] data_out;
wire [7:0] data_out;
input clk;
input clear;

reg [7:0] data_out_i [0:16-1];

initial begin: INITIALIZE_DATA_OUT_I
    integer i;
    for(i=0; i<16; i=i+1) begin
        data_out_i[i] = 0;
    end
end




always @(posedge clk) begin: MEMORY_ARRAY_UPTAKE
    if (fifo_we) begin
        data_out_i[wptr[4-1:0]] <= data_in;
    end
end



assign data_out = data_out_i[rptr[4-1:0]];


always @(negedge clear) begin: MEMORY_ARRAY_CLEARMEM
    integer i;
    for (i=0; i<16; i=i+1) begin
        data_out_i[i] <= 0;
    end
end

endmodule

\begin{figure} \centerline{\includegraphics[width=10cm]{memory_arrayRTL.png}} \caption{\label{fig:MARTL} memory_array RTL Schematic; Xilinx Vivado 2017.4} \end{figure}
\begin{figure} \centerline{\includegraphics[width=10cm]{memory_arraySYN.png}} \caption{\label{fig:MASYN} memory_array Synthesized schematic; Xilinx Vivado 2017.4} \end{figure}

Verilog Testbench

Conversion Issue :

At present I can not get the values stored in TestData numpy array to be transcribed to the output Verilog code memory_arrayTBV If someone can figure out how to, or make an improvement to the myHDL converter. The fix would be greatly appreciated by myself and the rest of the myHDL user base


In [22]:
@block
def memory_arrayTBV():
    """
    myHDL -> verilog testbench for `memory_array` module
    """
    data_in=Signal(intbv(0)[8:])
    fifo_we=Signal(bool(0))
    wptr=Signal(intbv(0)[5:])
    rptr=Signal(intbv(0)[5:])
    data_out=Signal(intbv(0)[8:])
    clk=Signal(bool(0))
    clear=Signal(bool(0))
    
    TestData_i=[Signal(intbv(int(i))[8:]) for i in TestData]


    @always_comb
    def print_data():
        print(data_in, fifo_we, wptr, rptr, data_out, clk, clear)
    

    DUT=memory_array(data_in, fifo_we, wptr, rptr, data_out, clk, clear)



    @instance
    def clk_signal():
        while True:
            clk.next = not clk
            yield delay(1)
    
    @instance
    def stimules():
        i=0
        while True:
            if i==0:
                fifo_we.next=0
            elif i==2:
                fifo_we.next=1
            
            elif i==13:
                clear.next=1
            elif i==14:
                clear.next=0
                
            elif i==16:
                raise StopSimulation()
            else:
                pass
            
            data_in.next=TestData_i[wptr]
            wptr.next=wptr+1
            if i!=0:
                rptr.next=rptr+1
            i+=1
            yield clk.posedge
    
    return instances()

TB=memory_arrayTBV()
TB.convert(hdl="Verilog", initial_values=True)
VerilogTextReader('memory_arrayTBV');


<class 'myhdl._Signal._Signal'> <class '_ast.Name'>
<class 'myhdl._Signal._Signal'> <class '_ast.Name'>
<class 'myhdl._Signal._Signal'> <class '_ast.Name'>
<class 'myhdl._Signal._Signal'> <class '_ast.Name'>
<class 'myhdl._Signal._Signal'> <class '_ast.Name'>
<class 'myhdl._Signal._Signal'> <class '_ast.Name'>
<class 'myhdl._Signal._Signal'> <class '_ast.Name'>
***Verilog modual from memory_arrayTBV.v***

 // File: memory_arrayTBV.v
// Generated by MyHDL 0.10
// Date: Tue Aug 14 03:08:31 2018


`timescale 1ns/10ps

module memory_arrayTBV (

);
// myHDL -> verilog testbench for `memory_array` module


reg [4:0] wptr = 0;
reg fifo_we = 0;
reg clk = 0;
reg [4:0] rptr = 0;
reg [7:0] data_in = 0;
wire [7:0] data_out;
reg clear = 0;
wire [7:0] TestData_i [0:16-1];
reg [7:0] memory_array0_0_data_out_i [0:16-1];

initial begin: INITIALIZE_MEMORY_ARRAY0_0_DATA_OUT_I
    integer i;
    for(i=0; i<16; i=i+1) begin
        memory_array0_0_data_out_i[i] = 0;
    end
end




always @(clear, data_out, clk, fifo_we, wptr, rptr, data_in) begin: MEMORY_ARRAYTBV_PRINT_DATA
    $write("%h", data_in);
    $write(" ");
    $write("%h", fifo_we);
    $write(" ");
    $write("%h", wptr);
    $write(" ");
    $write("%h", rptr);
    $write(" ");
    $write("%h", data_out);
    $write(" ");
    $write("%h", clk);
    $write(" ");
    $write("%h", clear);
    $write("\n");
end


always @(posedge clk) begin: MEMORY_ARRAYTBV_MEMORY_ARRAY0_0_UPTAKE
    if (fifo_we) begin
        memory_array0_0_data_out_i[wptr[4-1:0]] <= data_in;
    end
end



assign data_out = memory_array0_0_data_out_i[rptr[4-1:0]];


always @(negedge clear) begin: MEMORY_ARRAYTBV_MEMORY_ARRAY0_0_CLEARMEM
    integer i;
    for (i=0; i<16; i=i+1) begin
        memory_array0_0_data_out_i[i] <= 0;
    end
end


initial begin: MEMORY_ARRAYTBV_CLK_SIGNAL
    while (1'b1) begin
        clk <= (!clk);
        # 1;
    end
end


initial begin: MEMORY_ARRAYTBV_STIMULES
    integer i;
    i = 0;
    while (1'b1) begin
        case (i)
            'h0: begin
                fifo_we <= 0;
            end
            'h2: begin
                fifo_we <= 1;
            end
            'hd: begin
                clear <= 1;
            end
            'he: begin
                clear <= 0;
            end
            'h10: begin
                $finish;
            end
            default: begin
                // pass
            end
        endcase
        data_in <= TestData_i[wptr];
        wptr <= (wptr + 1);
        if ((i != 0)) begin
            rptr <= (rptr + 1);
        end
        i = i + 1;
        @(posedge clk);
    end
end

endmodule

Status Signal

The status signal module is a internal check module that checks for impending overflow, overflow, and underflow of the FIFO memory

\begin{figure} \centerline{\includegraphics[width=10cm]{fifoStatus.png}} \caption{\label{fig:WP} fifoStatus Functional Diagram} \end{figure}

In [23]:
@block
def fifoStatus(wr, rd, fifo_we, fifo_rd, wptr, rptr, 
                 fifo_full, fifo_empty, fifo_threshold, fifo_overflow, fifo_underflow, 
                 clk, rst_n):
    """
    Input:
        wr(bool): write signal
        rd(bool): read signal 
        fifo_we(bool): write enable signal
        fifo_rd(bool): read enable signal
        wptr(5bit): write pointer 
        rptr(5bit): read pointer
        clk(bool): clock
        rst_n(bool): reset 
        
    Ouput:
        fifo_full(bool): signal indicating the fifo memory is full
        fifo_empty(bool):signal indicating the fifo memory is empty
        fifo_threshold(bool): signal indicating that the fifo is about to overflow
        fifo_overflow(bool): signal indicating that the fifo rptr has overflowed
        fifo_underflow(bool): signal indicating that the fifo wptr has underflowed
    """
    
    #interalStores
    fifo_full_i=Signal(bool(0))
    fifo_empty_i=Signal(bool(0))
    fifo_threshold_i=Signal(bool(0))
    fifo_overflow_i=Signal(bool(0))
    fifo_underflow_i=Signal(bool(0))
    
    
    #interal wires
    fbit_comp=Signal(bool(0))
    pointer_equal=Signal(bool(0))
    pointer_result=Signal(intbv(0)[5:].signed())
    overflow_set=Signal(bool(0))
    underflow_set=Signal(bool(0))
    
    
    
    
    @always_comb
    def logic1():
        fbit_comp.next=wptr[4]^rptr[4]
        
        if wptr[3:0]-rptr[3:0]:
            pointer_equal.next=0
        else:
            pointer_equal.next=1
        
        
        pointer_result.next=wptr[4:0]-rptr[4:0]
        
        overflow_set.next=fifo_full_i & wr
        underflow_set.next=fifo_empty_i & rd
    
    @always_comb
    def logic2():
        fifo_full_i.next=fbit_comp & pointer_equal
        fifo_empty_i.next=(not fbit_comp) & pointer_equal
        
        if pointer_result[4] or pointer_result[3]:
            fifo_threshold_i.next=1
        else:
            fifo_threshold_i.next=0
    
    
            
    @always(clk.posedge, rst_n.negedge)
    def overflowControl():
        if rst_n:
            fifo_overflow_i.next=0
        elif overflow_set==1 and fifo_rd==0:
            fifo_overflow_i.next=1
        elif fifo_rd:
            fifo_overflow_i.next=0
        else:
            fifo_overflow_i.next=fifo_overflow_i
    
    @always(clk.posedge, rst_n.negedge)
    def underflowControl():
        if rst_n:
            fifo_underflow_i.next=0
        elif underflow_set==1 and fifo_we==0:
            fifo_underflow_i.next=1
        elif fifo_we:
            fifo_underflow_i.next=0
        else:
            fifo_underflow_i.next=fifo_underflow_i
    
    @always_comb
    def outputBuffer():
        fifo_full.next=fifo_full_i
        fifo_empty.next=fifo_empty_i
        fifo_threshold.next=fifo_threshold_i
        fifo_overflow.next=fifo_overflow_i
        fifo_underflow.next=fifo_underflow_i
        
        
        
    
    return instances()

myHDL Testing


In [24]:
Peeker.clear()
wr=Signal(bool(0)); Peeker(wr, 'wr')
rd=Signal(bool(0)); Peeker(rd, 'rd')

fifo_we=Signal(bool(0)); Peeker(fifo_we, 'fifo_we')
fifo_rd=Signal(bool(0)); Peeker(fifo_rd, 'fifo_rd')
wptr=Signal(intbv(0)[5:]); Peeker(wptr, 'wptr')
rptr=Signal(intbv(0)[5:]); Peeker(rptr, 'rptr')

fifo_full=Signal(bool(0)); Peeker(fifo_full, 'fifo_full')
fifo_empty=Signal(bool(0)); Peeker(fifo_empty, 'fifo_empty')
fifo_threshold=Signal(bool(0)); Peeker(fifo_threshold, 'fifo_threshold')
fifo_overflow=Signal(bool(0)); Peeker(fifo_overflow, 'fifo_overflow')
fifo_underflow=Signal(bool(0)); Peeker(fifo_underflow, 'fifo_underflow')

clk=Signal(bool(0)); Peeker(clk, 'clk')
rst_n=Signal(bool(0)); Peeker(rst_n, 'rst_n')



DUT=fifoStatus(wr, rd, fifo_we, fifo_rd, wptr, rptr, 
                 fifo_full, fifo_empty, fifo_threshold, fifo_overflow, fifo_underflow, 
                 clk, rst_n)


def fifoStatusTB():
    """
    myHDL only test bench for `fifoStatus` module
    Note:
        Not a complet testbench, could be better
    """
    @always(delay(1))
    def ClkGen():
        clk.next=not clk
    
    @instance
    def stimules():
        i=0
        while True:
            if i==0:
                wr.next=1; rd.next=1
                fifo_we.next=0; fifo_rd.next=0
            
            elif i==2:
                wr.next=0; rd.next=0
                fifo_we.next=1; fifo_rd.next=1
            
            elif i==4:
                wr.next=1; rd.next=1
                fifo_we.next=1; fifo_rd.next=1
            
            if i>=6 and i<=20:
                wptr.next=wptr+1
            if i>=7 and i<=20:
                rptr.next=rptr+1
            
            if i==20:
                rst_n.next=1
            elif i==21:
                rst_n.next=0
            elif i==23:
                raise StopSimulation()
            
            i+=1
            yield clk.posedge
    
    return instances()

sim=Simulation(DUT, fifoStatusTB(), *Peeker.instances()).run()

In [25]:
Peeker.to_wavedrom()



In [26]:
Peeker.to_dataframe()


Out[26]:
clk fifo_empty fifo_full fifo_overflow fifo_rd fifo_threshold fifo_underflow fifo_we rd rptr rst_n wptr wr
0 0 1 0 0 0 0 0 0 1 0 0 0 1
1 1 1 0 0 0 0 1 0 1 0 0 0 1
2 0 1 0 0 0 0 1 0 1 0 0 0 1
3 1 1 0 0 1 0 1 1 0 0 0 0 0
4 0 1 0 0 1 0 1 1 0 0 0 0 0
5 1 1 0 0 1 0 0 1 0 0 0 0 0
6 0 1 0 0 1 0 0 1 0 0 0 0 0
7 1 1 0 0 1 0 0 1 1 0 0 0 1
8 0 1 0 0 1 0 0 1 1 0 0 0 1
9 1 1 0 0 1 0 0 1 1 0 0 0 1
10 0 1 0 0 1 0 0 1 1 0 0 0 1
11 1 0 0 0 1 0 0 1 1 0 0 1 1
12 0 0 0 0 1 0 0 1 1 0 0 1 1
13 1 0 0 0 1 0 0 1 1 1 0 2 1
14 0 0 0 0 1 0 0 1 1 1 0 2 1
15 1 0 0 0 1 0 0 1 1 2 0 3 1
16 0 0 0 0 1 0 0 1 1 2 0 3 1
17 1 0 0 0 1 0 0 1 1 3 0 4 1
18 0 0 0 0 1 0 0 1 1 3 0 4 1
19 1 0 0 0 1 0 0 1 1 4 0 5 1
20 0 0 0 0 1 0 0 1 1 4 0 5 1
21 1 0 0 0 1 0 0 1 1 5 0 6 1
22 0 0 0 0 1 0 0 1 1 5 0 6 1
23 1 0 0 0 1 0 0 1 1 6 0 7 1
24 0 0 0 0 1 0 0 1 1 6 0 7 1
25 1 0 0 0 1 0 0 1 1 7 0 8 1
26 0 0 0 0 1 0 0 1 1 7 0 8 1
27 1 0 0 0 1 0 0 1 1 8 0 9 1
28 0 0 0 0 1 0 0 1 1 8 0 9 1
29 1 0 0 0 1 0 0 1 1 9 0 10 1
30 0 0 0 0 1 0 0 1 1 9 0 10 1
31 1 0 0 0 1 0 0 1 1 10 0 11 1
32 0 0 0 0 1 0 0 1 1 10 0 11 1
33 1 0 0 0 1 0 0 1 1 11 0 12 1
34 0 0 0 0 1 0 0 1 1 11 0 12 1
35 1 0 0 0 1 0 0 1 1 12 0 13 1
36 0
limit_output extension: Maximum message size of 10000 exceeded with 12323 characters

Verilog Code


In [27]:
DUT.convert()
VerilogTextReader('fifoStatus');


***Verilog modual from fifoStatus.v***

 // File: fifoStatus.v
// Generated by MyHDL 0.10
// Date: Tue Aug 14 03:08:33 2018


`timescale 1ns/10ps

module fifoStatus (
    wr,
    rd,
    fifo_we,
    fifo_rd,
    wptr,
    rptr,
    fifo_full,
    fifo_empty,
    fifo_threshold,
    fifo_overflow,
    fifo_underflow,
    clk,
    rst_n
);
// Input:
//     wr(bool): write signal
//     rd(bool): read signal 
//     fifo_we(bool): write enable signal
//     fifo_rd(bool): read enable signal
//     wptr(5bit): write pointer 
//     rptr(5bit): read pointer
//     clk(bool): clock
//     rst_n(bool): reset 
//     
// Ouput:
//     fifo_full(bool): signal indicating the fifo memory is full
//     fifo_empty(bool):signal indicating the fifo memory is empty
//     fifo_threshold(bool): signal indicating that the fifo is about to overflow
//     fifo_overflow(bool): signal indicating that the fifo rptr has overflowed
//     fifo_underflow(bool): signal indicating that the fifo wptr has underflowed

input wr;
input rd;
input fifo_we;
input fifo_rd;
input [4:0] wptr;
input [4:0] rptr;
output fifo_full;
wire fifo_full;
output fifo_empty;
wire fifo_empty;
output fifo_threshold;
wire fifo_threshold;
output fifo_overflow;
wire fifo_overflow;
output fifo_underflow;
wire fifo_underflow;
input clk;
input rst_n;

reg underflow_set = 0;
reg signed [4:0] pointer_result = 0;
reg pointer_equal = 0;
reg overflow_set = 0;
reg fifo_underflow_i = 0;
reg fifo_threshold_i = 0;
reg fifo_overflow_i = 0;
reg fifo_full_i = 0;
reg fifo_empty_i = 0;
reg fbit_comp = 0;



always @(fifo_empty_i, rd, fifo_full_i, wr, wptr, rptr) begin: FIFOSTATUS_LOGIC1
    fbit_comp = (wptr[4] ^ rptr[4]);
    if (($signed({1'b0, wptr[3-1:0]}) - rptr[3-1:0])) begin
        pointer_equal = 0;
    end
    else begin
        pointer_equal = 1;
    end
    pointer_result = (wptr[4-1:0] - rptr[4-1:0]);
    overflow_set = (fifo_full_i & wr);
    underflow_set = (fifo_empty_i & rd);
end


always @(pointer_result, fbit_comp, pointer_equal) begin: FIFOSTATUS_LOGIC2
    fifo_full_i = (fbit_comp & pointer_equal);
    fifo_empty_i = ((!fbit_comp) & pointer_equal);
    if ((pointer_result[4] || pointer_result[3])) begin
        fifo_threshold_i = 1;
    end
    else begin
        fifo_threshold_i = 0;
    end
end


always @(posedge clk, negedge rst_n) begin: FIFOSTATUS_OVERFLOWCONTROL
    if (rst_n) begin
        fifo_overflow_i <= 0;
    end
    else if (((overflow_set == 1) && (fifo_rd == 0))) begin
        fifo_overflow_i <= 1;
    end
    else if (fifo_rd) begin
        fifo_overflow_i <= 0;
    end
    else begin
        fifo_overflow_i <= fifo_overflow_i;
    end
end


always @(posedge clk, negedge rst_n) begin: FIFOSTATUS_UNDERFLOWCONTROL
    if (rst_n) begin
        fifo_underflow_i <= 0;
    end
    else if (((underflow_set == 1) && (fifo_we == 0))) begin
        fifo_underflow_i <= 1;
    end
    else if (fifo_we) begin
        fifo_underflow_i <= 0;
    end
    else begin
        fifo_underflow_i <= fifo_underflow_i;
    end
end



assign fifo_full = fifo_full_i;
assign fifo_empty = fifo_empty_i;
assign fifo_threshold = fifo_threshold_i;
assign fifo_overflow = fifo_overflow_i;
assign fifo_underflow = fifo_underflow_i;

endmodule

\begin{figure} \centerline{\includegraphics[width=10cm]{fifoStatusRTL.png}} \caption{\label{fig:FIFOStatusRTL} fifoStatus RTL Schematic; Xilinx Vivado 2017.4} \end{figure}
\begin{figure} \centerline{\includegraphics[width=10cm]{fifoStatusSYN.png}} \caption{\label{fig:MASYN} fifoStatus Synthesized Schematic; Xilinx Vivado 2017.4} \end{figure}

Verilog Testbench


In [28]:
@block
def fifoStatusTBV():
    """
    myHDL -> verilog test bench for `fifoStatus` module
    Note:
        Not a complet testbench, could be better
    """
    
    wr=Signal(bool(0)); Peeker(wr, 'wr')
    rd=Signal(bool(0)); Peeker(rd, 'rd')

    fifo_we=Signal(bool(0)); Peeker(fifo_we, 'fifo_we')
    fifo_rd=Signal(bool(0)); Peeker(fifo_rd, 'fifo_rd')
    wptr=Signal(intbv(0)[5:]); Peeker(wptr, 'wptr')
    rptr=Signal(intbv(0)[5:]); Peeker(rptr, 'rptr')

    fifo_full=Signal(bool(0)); Peeker(fifo_full, 'fifo_full')
    fifo_empty=Signal(bool(0)); Peeker(fifo_empty, 'fifo_empty')
    fifo_threshold=Signal(bool(0)); Peeker(fifo_threshold, 'fifo_threshold')
    fifo_overflow=Signal(bool(0)); Peeker(fifo_overflow, 'fifo_overflow')
    fifo_underflow=Signal(bool(0)); Peeker(fifo_underflow, 'fifo_underflow')

    clk=Signal(bool(0)); Peeker(clk, 'clk')
    rst_n=Signal(bool(0)); Peeker(rst_n, 'rst_n')
    
    @always_comb
    def print_data():
        print(wr, rd, 
              fifo_we, fifo_rd, wptr, rptr,
             fifo_full, fifo_empty, fifo_threshold, fifo_overflow, fifo_underflow)



    DUT=fifoStatus(wr, rd, fifo_we, fifo_rd, wptr, rptr, 
                     fifo_full, fifo_empty, fifo_threshold, fifo_overflow, fifo_underflow, 
                     clk, rst_n)



    @instance
    def clk_signal():
        while True:
            clk.next = not clk
            yield delay(1)
    
    @instance
    def stimules():
        i=0
        while True:
            if i==0:
                wr.next=1; rd.next=1
                fifo_we.next=0; fifo_rd.next=0
            
            elif i==2:
                wr.next=0; rd.next=0
                fifo_we.next=1; fifo_rd.next=1
            
            elif i==4:
                wr.next=1; rd.next=1
                fifo_we.next=1; fifo_rd.next=1
            else:
                pass
            
            if i>=6 and i<=20:
                wptr.next=wptr+1
            if i>=7 and i<=20:
                rptr.next=rptr+1
            
            if i==20:
                rst_n.next=1
            elif i==21:
                rst_n.next=0
            elif i==23:
                raise StopSimulation()
            else:
                pass
            
            i+=1
            yield clk.posedge
    
    return instances()

TB=fifoStatusTBV()
TB.convert(hdl="Verilog", initial_values=True)
VerilogTextReader('fifoStatusTBV');


<class 'myhdl._Signal._Signal'> <class '_ast.Name'>
<class 'myhdl._Signal._Signal'> <class '_ast.Name'>
<class 'myhdl._Signal._Signal'> <class '_ast.Name'>
<class 'myhdl._Signal._Signal'> <class '_ast.Name'>
<class 'myhdl._Signal._Signal'> <class '_ast.Name'>
<class 'myhdl._Signal._Signal'> <class '_ast.Name'>
<class 'myhdl._Signal._Signal'> <class '_ast.Name'>
<class 'myhdl._Signal._Signal'> <class '_ast.Name'>
<class 'myhdl._Signal._Signal'> <class '_ast.Name'>
<class 'myhdl._Signal._Signal'> <class '_ast.Name'>
<class 'myhdl._Signal._Signal'> <class '_ast.Name'>
***Verilog modual from fifoStatusTBV.v***

 // File: fifoStatusTBV.v
// Generated by MyHDL 0.10
// Date: Tue Aug 14 03:08:35 2018


`timescale 1ns/10ps

module fifoStatusTBV (

);
// myHDL -> verilog test bench for `fifoStatus` module
// Note:
//     Not a complet testbench, could be better


reg wr = 0;
wire fifo_full;
reg [4:0] wptr = 0;
reg fifo_we = 0;
reg clk = 0;
reg rst_n = 0;
reg rd = 0;
wire fifo_empty;
reg [4:0] rptr = 0;
reg fifo_rd = 0;
wire fifo_threshold;
wire fifo_overflow;
wire fifo_underflow;
reg fifoStatus0_0_underflow_set = 0;
reg signed [4:0] fifoStatus0_0_pointer_result = 0;
reg fifoStatus0_0_pointer_equal = 0;
reg fifoStatus0_0_overflow_set = 0;
reg fifoStatus0_0_fifo_underflow_i = 0;
reg fifoStatus0_0_fifo_threshold_i = 0;
reg fifoStatus0_0_fifo_overflow_i = 0;
reg fifoStatus0_0_fifo_full_i = 0;
reg fifoStatus0_0_fifo_empty_i = 0;
reg fifoStatus0_0_fbit_comp = 0;



always @(fifo_overflow, fifo_full, rd, fifo_threshold, fifo_underflow, wr, fifo_we, fifo_rd, fifo_empty, wptr, rptr) begin: FIFOSTATUSTBV_PRINT_DATA
    $write("%h", wr);
    $write(" ");
    $write("%h", rd);
    $write(" ");
    $write("%h", fifo_we);
    $write(" ");
    $write("%h", fifo_rd);
    $write(" ");
    $write("%h", wptr);
    $write(" ");
    $write("%h", rptr);
    $write(" ");
    $write("%h", fifo_full);
    $write(" ");
    $write("%h", fifo_empty);
    $write(" ");
    $write("%h", fifo_threshold);
    $write(" ");
    $write("%h", fifo_overflow);
    $write(" ");
    $write("%h", fifo_underflow);
    $write("\n");
end


always @(fifoStatus0_0_fifo_empty_i, rd, fifoStatus0_0_fifo_full_i, wr, wptr, rptr) begin: FIFOSTATUSTBV_FIFOSTATUS0_0_LOGIC1
    fifoStatus0_0_fbit_comp = (wptr[4] ^ rptr[4]);
    if (($signed({1'b0, wptr[3-1:0]}) - rptr[3-1:0])) begin
        fifoStatus0_0_pointer_equal = 0;
    end
    else begin
        fifoStatus0_0_pointer_equal = 1;
    end
    fifoStatus0_0_pointer_result = (wptr[4-1:0] - rptr[4-1:0]);
    fifoStatus0_0_overflow_set = (fifoStatus0_0_fifo_full_i & wr);
    fifoStatus0_0_underflow_set = (fifoStatus0_0_fifo_empty_i & rd);
end


always @(fifoStatus0_0_pointer_result, fifoStatus0_0_fbit_comp, fifoStatus0_0_pointer_equal) begin: FIFOSTATUSTBV_FIFOSTATUS0_0_LOGIC2
    fifoStatus0_0_fifo_full_i = (fifoStatus0_0_fbit_comp & fifoStatus0_0_pointer_equal);
    fifoStatus0_0_fifo_empty_i = ((!fifoStatus0_0_fbit_comp) & fifoStatus0_0_pointer_equal);
    if ((fifoStatus0_0_pointer_result[4] || fifoStatus0_0_pointer_result[3])) begin
        fifoStatus0_0_fifo_threshold_i = 1;
    end
    else begin
        fifoStatus0_0_fifo_threshold_i = 0;
    end
end


always @(posedge clk, negedge rst_n) begin: FIFOSTATUSTBV_FIFOSTATUS0_0_OVERFLOWCONTROL
    if (rst_n) begin
        fifoStatus0_0_fifo_overflow_i <= 0;
    end
    else if (((fifoStatus0_0_overflow_set == 1) && (fifo_rd == 0))) begin
        fifoStatus0_0_fifo_overflow_i <= 1;
    end
    else if (fifo_rd) begin
        fifoStatus0_0_fifo_overflow_i <= 0;
    end
    else begin
        fifoStatus0_0_fifo_overflow_i <= fifoStatus0_0_fifo_overflow_i;
    end
end


always @(posedge clk, negedge rst_n) begin: FIFOSTATUSTBV_FIFOSTATUS0_0_UNDERFLOWCONTROL
    if (rst_n) begin
        fifoStatus0_0_fifo_underflow_i <= 0;
    end
    else if (((fifoStatus0_0_underflow_set == 1) && (fifo_we == 0))) begin
        fifoStatus0_0_fifo_underflow_i <= 1;
    end
    else if (fifo_we) begin
        fifoStatus0_0_fifo_underflow_i <= 0;
    end
    else begin
        fifoStatus0_0_fifo_underflow_i <= fifoStatus0_0_fifo_underflow_i;
    end
end



assign fifo_full = fifoStatus0_0_fifo_full_i;
assign fifo_empty = fifoStatus0_0_fifo_empty_i;
assign fifo_threshold = fifoStatus0_0_fifo_threshold_i;
assign fifo_overflow = fifoStatus0_0_fifo_overflow_i;
assign fifo_underflow = fifoStatus0_0_fifo_underflow_i;


initial begin: FIFOSTATUSTBV_CLK_SIGNAL
    while (1'b1) begin
        clk <= (!clk);
        # 1;
    end
end


initial begin: FIFOSTATUSTBV_STIMULES
    integer i;
    i = 0;
    while (1'b1) begin
        case (i)
            'h0: begin
                wr <= 1;
                rd <= 1;
                fifo_we <= 0;
                fifo_rd <= 0;
            end
            'h2: begin
                wr <= 0;
                rd <= 0;
                fifo_we <= 1;
                fifo_rd <= 1;
            end
            'h4: begin
                wr <= 1;
                rd <= 1;
                fifo_we <= 1;
                fifo_rd <= 1;
            end
            default: begin
                // pass
            end
        endcase
        if (((i >= 6) && (i <= 20))) begin
            wptr <= (wptr + 1);
        end
        if (((i >= 7) && (i <= 20))) begin
            rptr <= (rptr + 1);
        end
        case (i)
            'h14: begin
                rst_n <= 1;
            end
            'h15: begin
                rst_n <= 0;
            end
            'h17: begin
                $finish;
            end
            default: begin
                // pass
            end
        endcase
        i = i + 1;
        @(posedge clk);
    end
end

endmodule

FIFO

\begin{figure} \centerline{\includegraphics[width=10cm]{FIFO.png}} \caption{\label{fig:WP} FIFO Functional Diagram} \end{figure}

In [29]:
@block
def fifo_mem(wr, rd, data_in, 
             fifo_full, fifo_empty, fifo_threshold, fifo_overflow, fifo_underflow,
             data_out, clk, rst_n, clear):
    """
    Input:
        wr(bool):write signal
        rd(bool):write signal
        data_in(8bit): data to be writen
        clk(bool): clock
        rst_n(bool): negtive reset signal
        clear(bool): signal to clear clear memeory to 0 
        
    Output:
        fifo_full(bool): signal indicating the fifo memory is full
        fifo_empty(bool):signal indicating the fifo memory is empty
        fifo_threshold(bool): signal indicating that the fifo is about to overflow
        fifo_overflow(bool): signal indicating that the fifo has overflowed
        fifo_underflow(bool): signal indicating that the fifo has underflowed
        data_out(8bit): data to be read out 
    """
    
    wptr=Signal(intbv(0)[5:]); rptr=Signal(intbv(0)[5:])
    fifo_we=Signal(bool(0)); fifo_rd=Signal(bool(0))
    
    WPointerAcum=write_pointer(wr, fifo_full, wptr, fifo_we, clk, rst_n)
    RPointerAcum=read_pointer(rd, fifo_empty, rptr, fifo_rd, clk, rst_n)
    InternalMem=memory_array(data_in, fifo_we, wptr, rptr, data_out, clk, clear)
    FIFOControl=fifoStatus(wr, rd, fifo_we, fifo_rd, wptr, rptr, 
                 fifo_full, fifo_empty, fifo_threshold, fifo_overflow, fifo_underflow, 
                 clk, rst_n)
    return instances()

myHDL Testing


In [30]:
Peeker.clear()
wr=Signal(bool(0)); Peeker(wr, 'wr')
rd=Signal(bool(0)); Peeker(rd, 'rd')
data_in=Signal(intbv(0)[8:]); Peeker(data_in, 'data_in')



fifo_full=Signal(bool(0)); Peeker(fifo_full, 'fifo_full')
fifo_empty=Signal(bool(0)); Peeker(fifo_empty, 'fifo_empty')
fifo_threshold=Signal(bool(0)); Peeker(fifo_threshold, 'fifo_threshold')
fifo_overflow=Signal(bool(0)); Peeker(fifo_overflow, 'fifo_overflow')
fifo_underflow=Signal(bool(0)); Peeker(fifo_underflow, 'fifo_underflow')

data_out=Signal(intbv(0)[8:]); Peeker(data_out, 'data_out') 


clk=Signal(bool(0)); Peeker(clk, 'clk')
rst_n=Signal(bool(0)); Peeker(rst_n, 'rst_n')
clear=Signal(bool(0)); Peeker(clear, 'clear')

DUT=fifo_mem(wr, rd, data_in, 
             fifo_full, fifo_empty, fifo_threshold, fifo_overflow, fifo_underflow,
             data_out, clk, rst_n, clear)



def fifo_memTB():
    """
    myHDL only test bench for `fifo_mem` module
    Note:
        Not a complet testbench, could be better
    """
    @always(delay(1))
    def ClkGen():
        clk.next=not clk
        
    @instance
    def stimules():
        i=0
        while True:
            if i==0:
                wr.next=1; rd.next=1
            elif i==16:
                wr.next=0; rd.next=1
            elif i==32:
                wr.next=0; rd.next=1
            elif i==48:
                rst_n.next=1
            elif i==49:
                rst_n.next=0
            elif i==50:
                wr.next=1; rd.next=1
                
            
                
            if i<16:
                data_in.next=int(TestData[i])
            elif i>=16 and i<32:
                data_in.next=int(TestData[i-16])
            elif i>=32 and i<48:
                data_in.next=int(TestData[i-32])
            elif i==48 or i==49:
                pass
            else:
                data_in.next=int(TestData[i-51])

            if i==66:
                raise StopSimulation()
           
            
            i+=1
            yield clk.posedge
            
        
    
    return instances()


sim=Simulation(DUT, fifo_memTB(), *Peeker.instances()).run()

In [31]:
Peeker.to_wavedrom()



In [32]:
fifoData=Peeker.to_dataframe(); fifoData


Out[32]:
clear clk data_in data_out fifo_empty fifo_full fifo_overflow fifo_threshold fifo_underflow rd rst_n wr
0 0 0 31 0 1 0 0 0 0 1 0 1
1 0 1 163 31 0 0 0 0 0 1 0 1
2 0 0 163 31 0 0 0 0 0 1 0 1
3 0 1 46 163 0 0 0 0 0 1 0 1
4 0 0 46 163 0 0 0 0 0 1 0 1
5 0 1 236 46 0 0 0 0 0 1 0 1
6 0 0 236 46 0 0 0 0 0 1 0 1
7 0 1 3 236 0 0 0 0 0 1 0 1
8 0 0 3 236 0 0 0 0 0 1 0 1
9 0 1 120 3 0 0 0 0 0 1 0 1
10 0 0 120 3 0 0 0 0 0 1 0 1
11 0 1 201 120 0 0 0 0 0 1 0 1
12 0 0 201 120 0 0 0 0 0 1 0 1
13 0 1 46 201 0 0 0 0 0 1 0 1
14 0 0 46 201 0 0 0 0 0 1 0 1
15 0 1 202 46 0 0 0 0 0 1 0 1
16 0 0 202 46 0 0 0 0 0 1 0 1
17 0 1 234 202 0 0 0 0 0 1 0 1
18 0 0 234 202 0 0 0 0 0 1 0 1
19 0 1 36 234 0 0 0 0 0 1 0 1
20 0 0 36 234 0 0 0 0 0 1 0 1
21 0 1 19 36 0 0 0 0 0 1 0 1
22 0 0 19 36 0 0 0 0 0 1 0 1
23 0 1 90 19 0 0 0 0 0 1 0 1
24 0 0 90 19 0 0 0 0 0 1 0 1
25 0 1 162 90 0 0 0 0 0 1 0 1
26 0 0 162 90 0 0 0 0 0 1 0 1
27 0 1 44 162 0 0 0 0 0 1 0 1
28 0 0 44 162 0 0 0 0 0 1 0 1
29 0 1 184 44 0 0 0 0 0 1 0 1
... ... ... ... ... ... ... ... ... ... ... ... ...
101 0 1 31 184 0 0 0 0 0 1 0 1
102 0 0 31 184 0 0 0 0 0 1 0 1
103 0 1 163 31 0 0 0 0 0 1 0 1
104 0 0 163 31 0 0 0 0 0 1 0 1
105 0 1 46 163 0 0 0 0 0 1 0 1
106 0 0 46 163 0 0 0 0 0 1 0 1
107 0 1 236 46 0 0 0 0 0 1 0 1
108 0 0
limit_output extension: Maximum message size of 10000 exceeded with 15620 characters

In [33]:
fifoData=fifoData[fifoData['clk']==1]
fifoData.drop('clk', axis=1, inplace=True)
fifoData.reset_index(drop=True, inplace=True)
fifoData


/home/iridium/anaconda3/lib/python3.6/site-packages/pandas/core/frame.py:3697: SettingWithCopyWarning: 
A value is trying to be set on a copy of a slice from a DataFrame

See the caveats in the documentation: http://pandas.pydata.org/pandas-docs/stable/indexing.html#indexing-view-versus-copy
  errors=errors)
Out[33]:
clear data_in data_out fifo_empty fifo_full fifo_overflow fifo_threshold fifo_underflow rd rst_n wr
0 0 163 31 0 0 0 0 0 1 0 1
1 0 46 163 0 0 0 0 0 1 0 1
2 0 236 46 0 0 0 0 0 1 0 1
3 0 3 236 0 0 0 0 0 1 0 1
4 0 120 3 0 0 0 0 0 1 0 1
5 0 201 120 0 0 0 0 0 1 0 1
6 0 46 201 0 0 0 0 0 1 0 1
7 0 202 46 0 0 0 0 0 1 0 1
8 0 234 202 0 0 0 0 0 1 0 1
9 0 36 234 0 0 0 0 0 1 0 1
10 0 19 36 0 0 0 0 0 1 0 1
11 0 90 19 0 0 0 0 0 1 0 1
12 0 162 90 0 0 0 0 0 1 0 1
13 0 44 162 0 0 0 0 0 1 0 1
14 0 184 44 0 0 0 0 0 1 0 1
15 0 31 184 0 0 0 1 0 1 0 0
16 0 163 31 1 0 0 0 0 1 0 0
17 0 46 31 1 0 0 0 1 1 0 0
18 0 236 31 1 0 0 0 1 1 0 0
19 0 3 31 1 0 0 0 1 1 0 0
20 0 120 31 1 0 0 0 1 1 0 0
21 0 201 31 1 0 0 0 1 1 0 0
22 0 46 31 1 0 0 0 1 1 0 0
23 0 202 31 1 0 0 0 1 1 0 0
24 0 234 31 1 0 0 0 1 1 0 0
25 0 36 31 1 0 0 0 1 1 0 0
26 0 19 31 1 0 0 0 1 1 0 0
27 0 90 31 1 0 0 0 1 1 0 0
28 0 162 31 1 0 0 0 1 1 0 0
29 0 44 31 1 0 0 0 1 1 0 0
... ... ... ... ... ... ... ... ... ... ... ...
35 0 3 31 1 0 0 0 1 1 0 0
36 0 120 31 1 0 0 0 1 1 0 0
37 0 201 31 1 0 0 0 1 1 0 0
38 0 46 31 1 0 0 0 1 1 0 0
39 0 202 31 1 0 0 0 1 1 0 0
40 0 234 31 1 0 0 0 1 1 0 0
41 0 36 31 1 0 0 0 1 1 0 0
42 0 19 31 1 0 0 0 1 1 0 0
43 0 90 31 1 0 0 0 1 1 0 0
limit_output extension: Maximum message size of 10000 exceeded with 14832 characters

In [34]:
fifoData.tail(20)


Out[34]:
clear data_in data_out fifo_empty fifo_full fifo_overflow fifo_threshold fifo_underflow rd rst_n wr
45 0 44 31 1 0 0 0 1 1 0 0
46 0 184 31 1 0 0 0 1 1 0 0
47 0 184 31 1 0 0 0 1 1 1 0
48 0 184 31 1 0 0 0 1 1 0 0
49 0 184 31 1 0 0 0 1 1 0 1
50 0 31 184 0 0 0 0 0 1 0 1
51 0 163 31 0 0 0 0 0 1 0 1
52 0 46 163 0 0 0 0 0 1 0 1
53 0 236 46 0 0 0 0 0 1 0 1
54 0 3 236 0 0 0 0 0 1 0 1
55 0 120 3 0 0 0 0 0 1 0 1
56 0 201 120 0 0 0 0 0 1 0 1
57 0 46 201 0 0 0 0 0 1 0 1
58 0 202 46 0 0 0 0 0 1 0 1
59 0 234 202 0 0 0 0 0 1 0 1
60 0 36 234 0 0 0 0 0 1 0 1
61 0 19 36 0 0 0 0 0 1 0 1
62 0 90 19 0 0 0 0 0 1 0 1
63 0 162 90 0 0 0 0 0 1 0 1
64 0 44 162 0 0 0 0 0 1 0 1

Verilog Code


In [35]:
DUT.convert()
VerilogTextReader('fifo_mem');


***Verilog modual from fifo_mem.v***

 // File: fifo_mem.v
// Generated by MyHDL 0.10
// Date: Tue Aug 14 03:08:37 2018


`timescale 1ns/10ps

module fifo_mem (
    wr,
    rd,
    data_in,
    fifo_full,
    fifo_empty,
    fifo_threshold,
    fifo_overflow,
    fifo_underflow,
    data_out,
    clk,
    rst_n,
    clear
);
// Input:
//     wr(bool):write signal
//     rd(bool):write signal
//     data_in(8bit): data to be writen
//     clk(bool): clock
//     rst_n(bool): negtive reset signal
//     clear(bool): signal to clear clear memeory to 0 
//     
// Output:
//     fifo_full(bool): signal indicating the fifo memory is full
//     fifo_empty(bool):signal indicating the fifo memory is empty
//     fifo_threshold(bool): signal indicating that the fifo is about to overflow
//     fifo_overflow(bool): signal indicating that the fifo has overflowed
//     fifo_underflow(bool): signal indicating that the fifo has underflowed
//     data_out(8bit): data to be read out 

input wr;
input rd;
input [7:0] data_in;
output fifo_full;
wire fifo_full;
output fifo_empty;
wire fifo_empty;
output fifo_threshold;
wire fifo_threshold;
output fifo_overflow;
wire fifo_overflow;
output fifo_underflow;
wire fifo_underflow;
output [7:0] data_out;
wire [7:0] data_out;
input clk;
input rst_n;
input clear;

wire [4:0] wptr;
wire fifo_we;
wire [4:0] rptr;
wire fifo_rd;
wire write_pointer0_0_1_fifo_we_i;
reg [4:0] write_pointer0_0_1_wptr_i = 0;
wire read_pointer0_0_1_fifo_rd_i;
reg [4:0] read_pointer0_0_1_rptr_i = 0;
reg fifoStatus0_0_1_underflow_set = 0;
reg signed [4:0] fifoStatus0_0_1_pointer_result = 0;
reg fifoStatus0_0_1_pointer_equal = 0;
reg fifoStatus0_0_1_overflow_set = 0;
reg fifoStatus0_0_1_fifo_underflow_i = 0;
reg fifoStatus0_0_1_fifo_threshold_i = 0;
reg fifoStatus0_0_1_fifo_overflow_i = 0;
reg fifoStatus0_0_1_fifo_full_i = 0;
reg fifoStatus0_0_1_fifo_empty_i = 0;
reg fifoStatus0_0_1_fbit_comp = 0;
reg [7:0] memory_array0_0_1_data_out_i [0:16-1];

initial begin: INITIALIZE_MEMORY_ARRAY0_0_1_DATA_OUT_I
    integer i;
    for(i=0; i<16; i=i+1) begin
        memory_array0_0_1_data_out_i[i] = 0;
    end
end





assign write_pointer0_0_1_fifo_we_i = ((!fifo_full) && wr);


always @(posedge clk, negedge rst_n) begin: FIFO_MEM_WRITE_POINTER0_0_1_POINTERUPDATE
    if (rst_n) begin
        write_pointer0_0_1_wptr_i <= 0;
    end
    else if (write_pointer0_0_1_fifo_we_i) begin
        write_pointer0_0_1_wptr_i <= (write_pointer0_0_1_wptr_i + 1);
    end
    else begin
        write_pointer0_0_1_wptr_i <= write_pointer0_0_1_wptr_i;
    end
end



assign fifo_we = write_pointer0_0_1_fifo_we_i;
assign wptr = write_pointer0_0_1_wptr_i;



assign read_pointer0_0_1_fifo_rd_i = ((!fifo_empty) && rd);


always @(posedge clk, negedge rst_n) begin: FIFO_MEM_READ_POINTER0_0_1_POINTERUPDATE
    if (rst_n) begin
        read_pointer0_0_1_rptr_i <= 0;
    end
    else if (read_pointer0_0_1_fifo_rd_i) begin
        read_pointer0_0_1_rptr_i <= (read_pointer0_0_1_rptr_i + 1);
    end
    else begin
        read_pointer0_0_1_rptr_i <= read_pointer0_0_1_rptr_i;
    end
end



assign fifo_rd = read_pointer0_0_1_fifo_rd_i;
assign rptr = read_pointer0_0_1_rptr_i;


always @(posedge clk) begin: FIFO_MEM_MEMORY_ARRAY0_0_1_UPTAKE
    if (fifo_we) begin
        memory_array0_0_1_data_out_i[wptr[4-1:0]] <= data_in;
    end
end



assign data_out = memory_array0_0_1_data_out_i[rptr[4-1:0]];


always @(negedge clear) begin: FIFO_MEM_MEMORY_ARRAY0_0_1_CLEARMEM
    integer i;
    for (i=0; i<16; i=i+1) begin
        memory_array0_0_1_data_out_i[i] <= 0;
    end
end


always @(fifoStatus0_0_1_fifo_empty_i, rd, fifoStatus0_0_1_fifo_full_i, wr, wptr, rptr) begin: FIFO_MEM_FIFOSTATUS0_0_1_LOGIC1
    fifoStatus0_0_1_fbit_comp = (wptr[4] ^ rptr[4]);
    if (($signed({1'b0, wptr[3-1:0]}) - rptr[3-1:0])) begin
        fifoStatus0_0_1_pointer_equal = 0;
    end
    else begin
        fifoStatus0_0_1_pointer_equal = 1;
    end
    fifoStatus0_0_1_pointer_result = (wptr[4-1:0] - rptr[4-1:0]);
    fifoStatus0_0_1_overflow_set = (fifoStatus0_0_1_fifo_full_i & wr);
    fifoStatus0_0_1_underflow_set = (fifoStatus0_0_1_fifo_empty_i & rd);
end


always @(fifoStatus0_0_1_pointer_result, fifoStatus0_0_1_fbit_comp, fifoStatus0_0_1_pointer_equal) begin: FIFO_MEM_FIFOSTATUS0_0_1_LOGIC2
    fifoStatus0_0_1_fifo_full_i = (fifoStatus0_0_1_fbit_comp & fifoStatus0_0_1_pointer_equal);
    fifoStatus0_0_1_fifo_empty_i = ((!fifoStatus0_0_1_fbit_comp) & fifoStatus0_0_1_pointer_equal);
    if ((fifoStatus0_0_1_pointer_result[4] || fifoStatus0_0_1_pointer_result[3])) begin
        fifoStatus0_0_1_fifo_threshold_i = 1;
    end
    else begin
        fifoStatus0_0_1_fifo_threshold_i = 0;
    end
end


always @(posedge clk, negedge rst_n) begin: FIFO_MEM_FIFOSTATUS0_0_1_OVERFLOWCONTROL
    if (rst_n) begin
        fifoStatus0_0_1_fifo_overflow_i <= 0;
    end
    else if (((fifoStatus0_0_1_overflow_set == 1) && (fifo_rd == 0))) begin
        fifoStatus0_0_1_fifo_overflow_i <= 1;
    end
    else if (fifo_rd) begin
        fifoStatus0_0_1_fifo_overflow_i <= 0;
    end
    else begin
        fifoStatus0_0_1_fifo_overflow_i <= fifoStatus0_0_1_fifo_overflow_i;
    end
end


always @(posedge clk, negedge rst_n) begin: FIFO_MEM_FIFOSTATUS0_0_1_UNDERFLOWCONTROL
    if (rst_n) begin
        fifoStatus0_0_1_fifo_underflow_i <= 0;
    end
    else if (((fifoStatus0_0_1_underflow_set == 1) && (fifo_we == 0))) begin
        fifoStatus0_0_1_fifo_underflow_i <= 1;
    end
    else if (fifo_we) begin
        fifoStatus0_0_1_fifo_underflow_i <= 0;
    end
    else begin
        fifoStatus0_0_1_fifo_underflow_i <= fifoStatus0_0_1_fifo_underflow_i;
    end
end



assign fifo_full = fifoStatus0_0_1_fifo_full_i;
assign fifo_empty = fifoStatus0_0_1_fifo_empty_i;
assign fifo_threshold = fifoStatus0_0_1_fifo_threshold_i;
assign fifo_overflow = fifoStatus0_0_1_fifo_overflow_i;
assign fifo_underflow = fifoStatus0_0_1_fifo_underflow_i;

endmodule

/home/iridium/anaconda3/lib/python3.6/site-packages/myhdl/conversion/_toVerilog.py:296: ToVerilogWarning: Output port is read internally: fifo_full
  category=ToVerilogWarning
/home/iridium/anaconda3/lib/python3.6/site-packages/myhdl/conversion/_toVerilog.py:296: ToVerilogWarning: Output port is read internally: fifo_empty
  category=ToVerilogWarning
\begin{figure} \centerline{\includegraphics[width=10cm]{fifo_memRTL.png}} \caption{\label{fig:FIFORTL} fifo_mem RTL Schematic; Xilinx Vivado 2017.4} \end{figure}
\begin{figure} \centerline{\includegraphics[width=10cm]{fifo_memSYN.png}} \caption{\label{fig:fifo_memSYN} fifo_mem Synthesized schematic; Xilinx Vivado 2017.4} \end{figure}

Verilog Testbench

Conversion Issue :

At present I can not get the values stored in TestData numpy array to be transcribed to the output Verilog code memory_arrayTBV If someone can figure out how to, or make an improvement to the myHDL converter. The fix would be greatly appreciated by myself and the rest of the myHDL user base


In [36]:
@block
def fifo_memTBV():
    """
    myHDL ->Verilog test bench for `fifo_mem` module
    Note:
        Not a complet testbench, could be better
    """
    
    wr=Signal(bool(0))
    rd=Signal(bool(0))
    data_in=Signal(intbv(0)[8:])
    TestData_i=[Signal(intbv(int(i))[8:]) for i in TestData]




    fifo_full=Signal(bool(0))
    fifo_empty=Signal(bool(0))
    fifo_threshold=Signal(bool(0))
    fifo_overflow=Signal(bool(0))
    fifo_underflow=Signal(bool(0))

    data_out=Signal(intbv(0)[8:])


    clk=Signal(bool(0))
    rst_n=Signal(bool(0))
    clear=Signal(bool(0))
    
    @always_comb
    def print_data():
        print(wr, rd, data_in, 
                 fifo_full, fifo_empty, fifo_threshold, fifo_overflow, fifo_underflow,
                 data_out, clk, rst_n, clear)

    DUT=fifo_mem(wr, rd, data_in, 
                 fifo_full, fifo_empty, fifo_threshold, fifo_overflow, fifo_underflow,
                 data_out, clk, rst_n, clear)


    @instance
    def clk_signal():
        while True:
            clk.next = not clk
            yield delay(1)
        
    @instance
    def stimules():
        i=0
        while True:
            if i==0:
                wr.next=1; rd.next=1
            elif i==16:
                wr.next=0; rd.next=1
            elif i==32:
                wr.next=0; rd.next=1
            elif i==48:
                rst_n.next=1
            elif i==49:
                rst_n.next=0
            elif i==50:
                wr.next=1; rd.next=1
            else:
                pass
                
            
                
            if i<16:
                data_in.next=int(TestData_i[i])
            elif i>=16 and i<32:
                data_in.next=int(TestData_i[i-16])
            elif i>=32 and i<48:
                data_in.next=int(TestData_i[i-32])
            elif i==48 or i==49:
                pass
            else:
                data_in.next=int(TestData_i[i-51])

            if i==66:
                raise StopSimulation()
           
            
            i+=1
            yield clk.posedge
            
        
    
    return instances()


    
TB=fifo_memTBV()
TB.convert(hdl="Verilog", initial_values=True)
VerilogTextReader('fifo_memTBV');


<class 'myhdl._Signal._Signal'> <class '_ast.Name'>
<class 'myhdl._Signal._Signal'> <class '_ast.Name'>
<class 'myhdl._Signal._Signal'> <class '_ast.Name'>
<class 'myhdl._Signal._Signal'> <class '_ast.Name'>
<class 'myhdl._Signal._Signal'> <class '_ast.Name'>
<class 'myhdl._Signal._Signal'> <class '_ast.Name'>
<class 'myhdl._Signal._Signal'> <class '_ast.Name'>
<class 'myhdl._Signal._Signal'> <class '_ast.Name'>
<class 'myhdl._Signal._Signal'> <class '_ast.Name'>
<class 'myhdl._Signal._Signal'> <class '_ast.Name'>
<class 'myhdl._Signal._Signal'> <class '_ast.Name'>
<class 'myhdl._Signal._Signal'> <class '_ast.Name'>
***Verilog modual from fifo_memTBV.v***

 // File: fifo_memTBV.v
// Generated by MyHDL 0.10
// Date: Tue Aug 14 03:08:40 2018


`timescale 1ns/10ps

module fifo_memTBV (

);
// myHDL ->Verilog test bench for `fifo_mem` module
// Note:
//     Not a complet testbench, could be better


reg wr = 0;
wire fifo_full;
reg clk = 0;
reg rst_n = 0;
reg rd = 0;
wire fifo_empty;
reg [7:0] data_in = 0;
wire [7:0] data_out;
wire clear;
wire fifo_threshold;
wire fifo_overflow;
wire fifo_underflow;
wire [4:0] fifo_mem0_0_wptr;
wire fifo_mem0_0_fifo_we;
wire [4:0] fifo_mem0_0_rptr;
wire fifo_mem0_0_fifo_rd;
wire fifo_mem0_0_write_pointer0_0_1_2_fifo_we_i;
reg [4:0] fifo_mem0_0_write_pointer0_0_1_2_wptr_i = 0;
wire fifo_mem0_0_read_pointer0_0_1_2_fifo_rd_i;
reg [4:0] fifo_mem0_0_read_pointer0_0_1_2_rptr_i = 0;
reg fifo_mem0_0_fifoStatus0_0_1_2_underflow_set = 0;
reg signed [4:0] fifo_mem0_0_fifoStatus0_0_1_2_pointer_result = 0;
reg fifo_mem0_0_fifoStatus0_0_1_2_pointer_equal = 0;
reg fifo_mem0_0_fifoStatus0_0_1_2_overflow_set = 0;
reg fifo_mem0_0_fifoStatus0_0_1_2_fifo_underflow_i = 0;
reg fifo_mem0_0_fifoStatus0_0_1_2_fifo_threshold_i = 0;
reg fifo_mem0_0_fifoStatus0_0_1_2_fifo_overflow_i = 0;
reg fifo_mem0_0_fifoStatus0_0_1_2_fifo_full_i = 0;
reg fifo_mem0_0_fifoStatus0_0_1_2_fifo_empty_i = 0;
reg fifo_mem0_0_fifoStatus0_0_1_2_fbit_comp = 0;
wire [7:0] TestData_i [0:16-1];
reg [7:0] fifo_mem0_0_memory_array0_0_1_2_data_out_i [0:16-1];

initial begin: INITIALIZE_FIFO_MEM0_0_MEMORY_ARRAY0_0_1_2_DATA_OUT_I
    integer i;
    for(i=0; i<16; i=i+1) begin
        fifo_mem0_0_memory_array0_0_1_2_data_out_i[i] = 0;
    end
end


assign clear = 1'd0;


always @(clear, fifo_full, rd, fifo_threshold, fifo_underflow, wr, data_out, clk, fifo_empty, fifo_overflow, rst_n, data_in) begin: FIFO_MEMTBV_PRINT_DATA
    $write("%h", wr);
    $write(" ");
    $write("%h", rd);
    $write(" ");
    $write("%h", data_in);
    $write(" ");
    $write("%h", fifo_full);
    $write(" ");
    $write("%h", fifo_empty);
    $write(" ");
    $write("%h", fifo_threshold);
    $write(" ");
    $write("%h", fifo_overflow);
    $write(" ");
    $write("%h", fifo_underflow);
    $write(" ");
    $write("%h", data_out);
    $write(" ");
    $write("%h", clk);
    $write(" ");
    $write("%h", rst_n);
    $write(" ");
    $write("%h", clear);
    $write("\n");
end



assign fifo_mem0_0_write_pointer0_0_1_2_fifo_we_i = ((!fifo_full) && wr);


always @(posedge clk, negedge rst_n) begin: FIFO_MEMTBV_FIFO_MEM0_0_WRITE_POINTER0_0_1_2_POINTERUPDATE
    if (rst_n) begin
        fifo_mem0_0_write_pointer0_0_1_2_wptr_i <= 0;
    end
    else if (fifo_mem0_0_write_pointer0_0_1_2_fifo_we_i) begin
        fifo_mem0_0_write_pointer0_0_1_2_wptr_i <= (fifo_mem0_0_write_pointer0_0_1_2_wptr_i + 1);
    end
    else begin
        fifo_mem0_0_write_pointer0_0_1_2_wptr_i <= fifo_mem0_0_write_pointer0_0_1_2_wptr_i;
    end
end



assign fifo_mem0_0_fifo_we = fifo_mem0_0_write_pointer0_0_1_2_fifo_we_i;
assign fifo_mem0_0_wptr = fifo_mem0_0_write_pointer0_0_1_2_wptr_i;



assign fifo_mem0_0_read_pointer0_0_1_2_fifo_rd_i = ((!fifo_empty) && rd);


always @(posedge clk, negedge rst_n) begin: FIFO_MEMTBV_FIFO_MEM0_0_READ_POINTER0_0_1_2_POINTERUPDATE
    if (rst_n) begin
        fifo_mem0_0_read_pointer0_0_1_2_rptr_i <= 0;
    end
    else if (fifo_mem0_0_read_pointer0_0_1_2_fifo_rd_i) begin
        fifo_mem0_0_read_pointer0_0_1_2_rptr_i <= (fifo_mem0_0_read_pointer0_0_1_2_rptr_i + 1);
    end
    else begin
        fifo_mem0_0_read_pointer0_0_1_2_rptr_i <= fifo_mem0_0_read_pointer0_0_1_2_rptr_i;
    end
end



assign fifo_mem0_0_fifo_rd = fifo_mem0_0_read_pointer0_0_1_2_fifo_rd_i;
assign fifo_mem0_0_rptr = fifo_mem0_0_read_pointer0_0_1_2_rptr_i;


always @(posedge clk) begin: FIFO_MEMTBV_FIFO_MEM0_0_MEMORY_ARRAY0_0_1_2_UPTAKE
    if (fifo_mem0_0_fifo_we) begin
        fifo_mem0_0_memory_array0_0_1_2_data_out_i[fifo_mem0_0_wptr[4-1:0]] <= data_in;
    end
end



assign data_out = fifo_mem0_0_memory_array0_0_1_2_data_out_i[fifo_mem0_0_rptr[4-1:0]];


always @(negedge clear) begin: FIFO_MEMTBV_FIFO_MEM0_0_MEMORY_ARRAY0_0_1_2_CLEARMEM
    integer i;
    for (i=0; i<16; i=i+1) begin
        fifo_mem0_0_memory_array0_0_1_2_data_out_i[i] <= 0;
    end
end


always @(fifo_mem0_0_fifoStatus0_0_1_2_fifo_empty_i, rd, fifo_mem0_0_fifoStatus0_0_1_2_fifo_full_i, wr, fifo_mem0_0_wptr, fifo_mem0_0_rptr) begin: FIFO_MEMTBV_FIFO_MEM0_0_FIFOSTATUS0_0_1_2_LOGIC1
    fifo_mem0_0_fifoStatus0_0_1_2_fbit_comp = (fifo_mem0_0_wptr[4] ^ fifo_mem0_0_rptr[4]);
    if (($signed({1'b0, fifo_mem0_0_wptr[3-1:0]}) - fifo_mem0_0_rptr[3-1:0])) begin
        fifo_mem0_0_fifoStatus0_0_1_2_pointer_equal = 0;
    end
    else begin
        fifo_mem0_0_fifoStatus0_0_1_2_pointer_equal = 1;
    end
    fifo_mem0_0_fifoStatus0_0_1_2_pointer_result = (fifo_mem0_0_wptr[4-1:0] - fifo_mem0_0_rptr[4-1:0]);
    fifo_mem0_0_fifoStatus0_0_1_2_overflow_set = (fifo_mem0_0_fifoStatus0_0_1_2_fifo_full_i & wr);
    fifo_mem0_0_fifoStatus0_0_1_2_underflow_set = (fifo_mem0_0_fifoStatus0_0_1_2_fifo_empty_i & rd);
end


always @(fifo_mem0_0_fifoStatus0_0_1_2_pointer_result, fifo_mem0_0_fifoStatus0_0_1_2_fbit_comp, fifo_mem0_0_fifoStatus0_0_1_2_pointer_equal) begin: FIFO_MEMTBV_FIFO_MEM0_0_FIFOSTATUS0_0_1_2_LOGIC2
    fifo_mem0_0_fifoStatus0_0_1_2_fifo_full_i = (fifo_mem0_0_fifoStatus0_0_1_2_fbit_comp & fifo_mem0_0_fifoStatus0_0_1_2_pointer_equal);
    fifo_mem0_0_fifoStatus0_0_1_2_fifo_empty_i = ((!fifo_mem0_0_fifoStatus0_0_1_2_fbit_comp) & fifo_mem0_0_fifoStatus0_0_1_2_pointer_equal);
    if ((fifo_mem0_0_fifoStatus0_0_1_2_pointer_result[4] || fifo_mem0_0_fifoStatus0_0_1_2_pointer_result[3])) begin
        fifo_mem0_0_fifoStatus0_0_1_2_fifo_threshold_i = 1;
    end
    else begin
        fifo_mem0_0_fifoStatus0_0_1_2_fifo_threshold_i = 0;
    end
end


always @(posedge clk, negedge rst_n) begin: FIFO_MEMTBV_FIFO_MEM0_0_FIFOSTATUS0_0_1_2_OVERFLOWCONTROL
    if (rst_n) begin
        fifo_mem0_0_fifoStatus0_0_1_2_fifo_overflow_i <= 0;
    end
    else if (((fifo_mem0_0_fifoStatus0_0_1_2_overflow_set == 1) && (fifo_mem0_0_fifo_rd == 0))) begin
        fifo_mem0_0_fifoStatus0_0_1_2_fifo_overflow_i <= 1;
    end
    else if (fifo_mem0_0_fifo_rd) begin
        fifo_mem0_0_fifoStatus0_0_1_2_fifo_overflow_i <= 0;
    end
    else begin
        fifo_mem0_0_fifoStatus0_0_1_2_fifo_overflow_i <= fifo_mem0_0_fifoStatus0_0_1_2_fifo_overflow_i;
    end
end


always @(posedge clk, negedge rst_n) begin: FIFO_MEMTBV_FIFO_MEM0_0_FIFOSTATUS0_0_1_2_UNDERFLOWCONTROL
    if (rst_n) begin
        fifo_mem0_0_fifoStatus0_0_1_2_fifo_underflow_i <= 0;
    end
    else if (((fifo_mem0_0_fifoStatus0_0_1_2_underflow_set == 1) && (fifo_mem0_0_fifo_we == 0))) begin
        fifo_mem0_0_fifoStatus0_0_1_2_fifo_underflow_i <= 1;
    end
    else if (fifo_mem0_0_fifo_we) begin
        fifo_mem0_0_fifoStatus0_0_1_2_fifo_underflow_i <= 0;
    end
    else begin
        fifo_mem0_0_fifoStatus0_0_1_2_fifo_underflow_i <= fifo_mem0_0_fifoStatus0_0_1_2_fifo_underflow_i;
    end
end



assign fifo_full = fifo_mem0_0_fifoStatus0_0_1_2_fifo_full_i;
assign fifo_empty = fifo_mem0_0_fifoStatus0_0_1_2_fifo_empty_i;
assign fifo_threshold = fifo_mem0_0_fifoStatus0_0_1_2_fifo_threshold_i;
assign fifo_overflow = fifo_mem0_0_fifoStatus0_0_1_2_fifo_overflow_i;
assign fifo_underflow = fifo_mem0_0_fifoStatus0_0_1_2_fifo_underflow_i;


initial begin: FIFO_MEMTBV_CLK_SIGNAL
    while (1'b1) begin
        clk <= (!clk);
        # 1;
    end
end


initial begin: FIFO_MEMTBV_STIMULES
    integer i;
    i = 0;
    while (1'b1) begin
        case (i)
            'h0: begin
                wr <= 1;
                rd <= 1;
            end
            'h10: begin
                wr <= 0;
                rd <= 1;
            end
            'h20: begin
                wr <= 0;
                rd <= 1;
            end
            'h30: begin
                rst_n <= 1;
            end
            'h31: begin
                rst_n <= 0;
            end
            'h32: begin
                wr <= 1;
                rd <= 1;
            end
            default: begin
                // pass
            end
        endcase
        if ((i < 16)) begin
            data_in <= TestData_i[i];
        end
        else if (((i >= 16) && (i < 32))) begin
            data_in <= TestData_i[($signed({1'b0, i}) - 16)];
        end
        else if (((i >= 32) && (i < 48))) begin
            data_in <= TestData_i[($signed({1'b0, i}) - 32)];
        end
        else if (((i == 48) || (i == 49))) begin
            // pass
        end
        else begin
            data_in <= TestData_i[($signed({1'b0, i}) - 51)];
        end
        if ((i == 66)) begin
            $finish;
        end
        i = i + 1;
        @(posedge clk);
    end
end

endmodule

/home/iridium/anaconda3/lib/python3.6/site-packages/myhdl/conversion/_toVerilog.py:349: ToVerilogWarning: Signal is not driven: clear
  category=ToVerilogWarning

In [ ]: