\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.
@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} }
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]:
In [2]:
#helper functions to read in the .v and .vhd generated files into python
def VerilogTextReader(loc, printresult=True):
with open(f'{loc}.v', 'r') as vText:
VerilogText=vText.read()
if printresult:
print(f'***Verilog modual from {loc}.v***\n\n', VerilogText)
return VerilogText
def VHDLTextReader(loc, printresult=True):
with open(f'{loc}.vhd', 'r') as vText:
VerilogText=vText.read()
if printresult:
print(f'***VHDL modual from {loc}.vhd***\n\n', VerilogText)
return VerilogText
In 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
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()
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]:
In [7]:
DUT.convert()
VerilogTextReader('write_pointer');
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');
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.
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()
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]:
In [13]:
DUT.convert()
VerilogTextReader('read_pointer');
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');
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
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()
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]:
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]:
In [20]:
(memoryData['data_in']==memoryData['data_out_shift-1']).all()
Out[20]:
In [21]:
DUT.convert()
VerilogTextReader('memory_array');
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');
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()
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]:
In [27]:
DUT.convert()
VerilogTextReader('fifoStatus');
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');
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()
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]:
In [33]:
fifoData=fifoData[fifoData['clk']==1]
fifoData.drop('clk', axis=1, inplace=True)
fifoData.reset_index(drop=True, inplace=True)
fifoData
Out[33]:
In [34]:
fifoData.tail(20)
Out[34]:
In [35]:
DUT.convert()
VerilogTextReader('fifo_mem');
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');
In [ ]: