# Trying to create a fifo through a queue

**URL:** <https://discourse.myhdl.org/t/trying-to-create-a-fifo-through-a-queue/491>\
**Category:** Uncategorized\
**Created:** [January 12, 2022, 3:56pm UTC](https://discourse.myhdl.org/t/trying-to-create-a-fifo-through-a-queue/491 "2022-01-12T15:56:48Z")\
**Posts on this page:** 8\
**Page:** 1

<div class="post-metadata">

**Author:** ![Albert](https://avatars.discourse-cdn.com/v4/letter/a/48db29/32.png) [@Albert](https://discourse.myhdl.org/u/Albert)\
**Post date:** [January 12, 2022, 3:56pm UTC](https://discourse.myhdl.org/t/trying-to-create-a-fifo-through-a-queue/491/1 "2022-01-12T15:56:48Z")

</div>

I am trying to create a fifo by a queue (this is also mentioned in the MyHDL manual) but get errors when I try to convert it to VHDL. Not sure if this are MyHDL errors or normal Python errors.

convert\_model.py  
’  
from myhdl import Signal,intbv, ResetSignal  
from fifo\_queue import Fifo  
from rw\_fifo import \*

def convert\_rw\_fifo(hdl):  
#assign default/initial values to signals

ip\_rst = ResetSignal(0, active=1, isasync=True)  
ip\_clk = Signal(bool(0))  
ResetError = Signal(bool(0))  
write = Signal(bool(0))  
write\_data = Signal(intbv(val=0, min=0, max=2\*\*16))  
read = Signal(bool(0))

rw\_fifo\_1 = rw\_fifo(ip\_rst, ip\_clk, ResetError, write, write\_data, read)  
rw\_fifo\_1.convert(hdl=hdl)

#------------------------------------------------------------------------------

# Main

#------------------------------------------------------------------------------  
if **name** == ‘ **main** ’ :  
convert\_rw\_fifo(hdl=‘VHDL’)  
’  
fifo\_queue.py  
’  
#from myhdl import (Signal, ResetSignal, intbv, modbv, always, always\_comb, always\_seq)  
import queue

“”"  
FIFO definition with queue  
“”"

class Fifo():

def **init** (self, depth, width, almost\_full\_level, almost\_empty\_level):  
“”" create queue and attributes “”"  
self.fifo = queue.Queue(depth)  
self.depth = depth  
self.width = width  
self.full\_flag = 0  
self.empty\_flag = 1  
self.almost\_full\_level = almost\_full\_level  
self.almost\_empty\_level = almost\_empty\_level  
“”" keep track of number of values in fifo “”"  
self.level = 0

def put(self, symbol):  
“”" store a value in fifo if not full “”"  
if self.level != self.depth:  
self.fifo.put(symbol, block=False, timeout=None)  
self.level = self.level + 1

def get(self):  
“”" get a value from fifo if not empty “”"  
if self.level != 0:  
symbol = self.fifo.get(block=False)  
self.level = self.level - 1  
return symbol

def is\_full(self):  
“”" check if fifo is full “”"  
return self.limit\_reached(self.depth)

def is\_empty(self):  
“”" check if fifo is full “”"  
return self.limit\_reached(0)

def is\_almost\_full(self):  
“”" check if fifo is almost full “”"  
return self.limit\_reached(self.almost\_full\_level)

def is\_almost\_empty(self):  
“”" check if fifo is almost empty “”"  
return self.limit\_reached(self.almost\_empty\_level)

def limit\_reached(self, limit):  
if self.level == limit:  
return True  
else:  
return False

def reset(self):  
“”" reset level counter “”"  
self.fifo = queue.Queue(self.depth)  
self.level = 0

#------------------------------------------------------------------------------

# Test functions

#------------------------------------------------------------------------------  
def tst\_queue\_1():  
depth = 10  
width = 3  
almost\_full\_level = 9  
almost\_empty\_level = 1

# Print all methods

print(dir(Fifo))

# Testing Put element:

header\_fifo = Fifo(depth, width, almost\_full\_level, almost\_empty\_level)

# fifo = Fifo(depth, width, almost\_full\_level, almost\_empty\_level)

for i in range(11):  
print(‘Putting {:d}\n’.format(i))  
if header\_fifo.is\_full():

# if fifo.is\_full():

```
  print('\t\tShit, the fifo is full')
else:
  header_fifo.put(i)

```

a=1

# Testing Get element:

for i in range(11):  
if header\_fifo.is\_empty():  
print(‘\t\tShit, the fifo is empty’)  
else:  
symbol = header\_fifo.get()  
print(‘Getting {:d}\n’.format(symbol))

header\_fifo.put(20)  
header\_fifo.put(30)  
header\_fifo.reset()  
if header\_fifo.is\_empty():  
print(‘The fifo is empty and should be\n’)  
#------------------------------------------------------------------------------

# Main

#------------------------------------------------------------------------------  
if **name** == ‘ **main** ’ :  
tst\_queue\_1()  
’  
rw\_fifo.py  
’  
from myhdl import block, instance, Signal, ResetSignal, intbv, modbv, concat, always, always\_comb, always\_seq  
from fifo\_queue import Fifo

@block  
def rw\_fifo (ip\_rst, ip\_clk, ResetError, write, write\_data, read):

“”" create fifo  
“”"  
header\_fifo = Fifo(32, 16, 16-4, 4)  
write\_data = Signal(intbv(val=0, min=0, max=2**16))  
read\_data = Signal(intbv(val=0, min=0, max=2**16))

@always\_seq (ip\_clk.negedge, reset=ip\_rst)  
def fifo\_write():

```
""" 
  clear fifo's at reset
"""
if ResetError == 1: 
  header_fifo.reset()
else: 
  """ write to fifo """
  if write == 1 and header_fifo.is_full==0:
    header_fifo.put(write_data)

```

@always\_comb  
def fifo\_read():

```
""" read from fifo if requested and there is data """
if read == 1 and header_fifo.is_empty() == 0:
  """ change format only """
  read_data = header_fifo.get()

```

return fifo\_write, fifo\_read  
’  
The error is that it cannot find the reset method in the class definition. If I run the testfunction in the fifo\_queue it seems to work.

---

<div class="post-metadata">

**Author:** ![josyb](https://yyz2.discourse-cdn.com/flex030/user_avatar/discourse.myhdl.org/josyb/32/5_2.png) [@josyb](https://discourse.myhdl.org/u/josyb)\
**Post date:** [January 14, 2022, 6:42am UTC](https://discourse.myhdl.org/t/trying-to-create-a-fifo-through-a-queue/491/2 "2022-01-14T06:42:56Z")

</div>

Albert,

can you post your code like this:

> ```python  
> your code goes here between the backticks  
> ```

---

<div class="post-metadata">

**Author:** ![Albert](https://avatars.discourse-cdn.com/v4/letter/a/48db29/32.png) [@Albert](https://discourse.myhdl.org/u/Albert)\
**Post date:** [January 14, 2022, 5:05pm UTC](https://discourse.myhdl.org/t/trying-to-create-a-fifo-through-a-queue/491/3 "2022-01-14T17:05:29Z")

</div>

file convert\_model.py  
‘’’  
from myhdl import Signal,intbv, ResetSignal  
from fifo\_queue import Fifo  
from rw\_fifo import \*

def convert\_rw\_fifo(hdl):  
#assign default/initial values to signals

ip\_rst = ResetSignal(0, active=1, isasync=True)  
ip\_clk = Signal(bool(0))  
ResetError = Signal(bool(0))  
write = Signal(bool(0))  
write\_data = Signal(intbv(val=0, min=0, max=2\*\*16))  
read = Signal(bool(0))

rw\_fifo\_1 = rw\_fifo(ip\_rst, ip\_clk, ResetError, write, write\_data, read)  
rw\_fifo\_1.convert(hdl=hdl)

#------------------------------------------------------------------------------

# Main

#------------------------------------------------------------------------------  
if **name** == ‘ **main** ’ :  
convert\_rw\_fifo(hdl=‘VHDL’)  
‘’’

file: fifo\_queue.py  
‘’’  
#from myhdl import (Signal, ResetSignal, intbv, modbv, always, always\_comb, always\_seq)  
import queue

“”"  
FIFO definition with queue  
“”"

class Fifo():

def **init** (self, depth, width, almost\_full\_level, almost\_empty\_level):  
“”" create queue and attributes “”"  
self.fifo = queue.Queue(depth)  
self.depth = depth  
self.width = width  
self.full\_flag = 0  
self.empty\_flag = 1  
self.almost\_full\_level = almost\_full\_level  
self.almost\_empty\_level = almost\_empty\_level  
“”" keep track of number of values in fifo “”"  
self.level = 0

def put(self, symbol):  
“”" store a value in fifo if not full “”"  
if self.level != self.depth:  
self.fifo.put(symbol, block=False, timeout=None)  
self.level = self.level + 1

def get(self):  
“”" get a value from fifo if not empty “”"  
if self.level != 0:  
symbol = self.fifo.get(block=False)  
self.level = self.level - 1  
return symbol

def is\_full(self):  
“”" check if fifo is full “”"  
return self.limit\_reached(self.depth)

def is\_empty(self):  
“”" check if fifo is full “”"  
return self.limit\_reached(0)

def is\_almost\_full(self):  
“”" check if fifo is almost full “”"  
return self.limit\_reached(self.almost\_full\_level)

def is\_almost\_empty(self):  
“”" check if fifo is almost empty “”"  
return self.limit\_reached(self.almost\_empty\_level)

def limit\_reached(self, limit):  
if self.level == limit:  
return True  
else:  
return False

def reset(self):  
“”" reset level counter “”"  
self.fifo = queue.Queue(self.depth)  
self.level = 0

‘’’

file: rw\_fifo.py  
‘’’  
from myhdl import block, instance, Signal, ResetSignal, intbv, modbv, concat, always, always\_comb, always\_seq  
from fifo\_queue import Fifo

@block  
def rw\_fifo (ip\_rst, ip\_clk, ResetError, write, write\_data, read):

“”" create fifo  
“”"  
header\_fifo = Fifo(32, 16, 16-4, 4)  
write\_data = Signal(intbv(val=0, min=0, max=2**16))  
read\_data = Signal(intbv(val=0, min=0, max=2**16))

@always\_seq (ip\_clk.negedge, reset=ip\_rst)  
def fifo\_write():

```
""" 
  clear fifo's at reset
"""
if ResetError == 1: 
  header_fifo.reset()
else: 
  """ write to fifo """
  if write == 1 and header_fifo.is_full==0:
    header_fifo.put(write_data)

```

@always\_comb  
def fifo\_read():

```
""" read from fifo if requested and there is data """
if read == 1 and header_fifo.is_empty() == 0:
  """ change format only """
  read_data = header_fifo.get()

```

return fifo\_write, fifo\_read

# ------------------------------------------------------------------------------

# Test functions

# ------------------------------------------------------------------------------

def tst\_queue\_1():  
depth = 10  
width = 3  
almost\_full\_level = 9  
almost\_empty\_level = 1

# Print all methods

#print(dir(Fifo))

# Testing Put element:

header\_fifo = Fifo(depth, width, almost\_full\_level, almost\_empty\_level)

# fifo = Fifo(depth, width, almost\_full\_level, almost\_empty\_level)

for i in range(11):  
print(‘Putting {:d}\n’.format(i))  
if header\_fifo.is\_full():  
# if fifo.is\_full():  
print(‘\t\tShit, the fifo is full’)  
else:  
header\_fifo.put(i)  
a = 1

# Testing Get element:

for i in range(11):  
if header\_fifo.is\_empty():  
print(‘\t\tShit, the fifo is empty’)  
else:  
symbol = header\_fifo.get()  
print(‘Getting {:d}\n’.format(symbol))

header\_fifo.put(20)  
header\_fifo.put(30)  
header\_fifo.reset()  
if header\_fifo.is\_empty():  
print(‘The fifo is empty and should be\n’)

# ------------------------------------------------------------------------------

# Main

# ------------------------------------------------------------------------------

if **name** == ‘ **main** ’:  
tst\_queue\_1()

‘’’

---

<div class="post-metadata">

**Author:** ![josyb](https://yyz2.discourse-cdn.com/flex030/user_avatar/discourse.myhdl.org/josyb/32/5_2.png) [@josyb](https://discourse.myhdl.org/u/josyb)\
**Post date:** [January 15, 2022, 11:03am UTC](https://discourse.myhdl.org/t/trying-to-create-a-fifo-through-a-queue/491/4 "2022-01-15T11:03:11Z")

</div>

> [@Albert](#):
>
> ‘’’

That didn’t work; the three backticks look like this: ```  
 ![image](https://canada1.discourse-cdn.com/flex030/uploads/myhdl/original/1X/6c61eb2af66930d62a4b0d84ecf5df1d84f6446c.jpeg)

I copied the source as is and tried to edit it, but the indentation has gone lost and I refrained from guessing your intentions in the code 🙂

---

<div class="post-metadata">

**Author:** ![josyb](https://yyz2.discourse-cdn.com/flex030/user_avatar/discourse.myhdl.org/josyb/32/5_2.png) [@josyb](https://discourse.myhdl.org/u/josyb)\
**Post date:** [January 15, 2022, 12:40pm UTC](https://discourse.myhdl.org/t/trying-to-create-a-fifo-through-a-queue/491/5 "2022-01-15T12:40:02Z")

</div>

Or click on the indicated icon:

 ![discourse-code](https://canada1.discourse-cdn.com/flex030/uploads/myhdl/original/1X/1b3ee4b09beff2fd8af222250508ef5ab66e2b17.png)

---

<div class="post-metadata">

**Author:** ![Albert](https://avatars.discourse-cdn.com/v4/letter/a/48db29/32.png) [@Albert](https://discourse.myhdl.org/u/Albert)\
**Post date:** [January 18, 2022, 7:01am UTC](https://discourse.myhdl.org/t/trying-to-create-a-fifo-through-a-queue/491/6 "2022-01-18T07:01:27Z")

</div>

Josyb, sorry for using the wrong ticks. Find a retry below.

**The fifo\_queue.py file**

```auto
#from myhdl import (Signal, ResetSignal, intbv, modbv, always, always_comb, always_seq)
import queue

"""
  FIFO definition with queue
"""

class Fifo():

  def __init__ (self, depth, width, almost_full_level, almost_empty_level):
    """ create queue and attributes """
    self.fifo = queue.Queue(depth)
    self.depth = depth
    self.width = width
    self.full_flag = 0
    self.empty_flag = 1
    self.almost_full_level = almost_full_level
    self.almost_empty_level = almost_empty_level
    """ keep track of number of values in fifo """
    self.level = 0
    
  def put(self, symbol):
    """ store a value in fifo if not full """
    if self.level != self.depth:
      self.fifo.put(symbol, block=False, timeout=None)
      self.level = self.level + 1   

  def get(self):
    """ get a value from fifo if not empty """
    if self.level != 0:
      symbol = self.fifo.get(block=False)
      self.level = self.level - 1
      return symbol

  def is_full(self):
    """ check if fifo is full """
    return self.limit_reached(self.depth)

  def is_empty(self):
    """ check if fifo is full """
    return self.limit_reached(0)

  def is_almost_full(self):
    """ check if fifo is almost full """
    return self.limit_reached(self.almost_full_level)

  def is_almost_empty(self):
    """ check if fifo is almost empty """
    return self.limit_reached(self.almost_empty_level)

  def limit_reached(self, limit):
    if self.level == limit:
      return True
    else:
      return False
  
  def reset(self):
    """ reset level counter """
    self.fifo = queue.Queue(self.depth)
    self.level = 0

```

**The rw\_fifo.py file**

```auto
from myhdl import block, instance, Signal, ResetSignal, intbv, modbv, concat, always, always_comb, always_seq
from fifo_queue import Fifo

@block
def rw_fifo (ip_rst, ip_clk, ResetError, write, write_data, read):

  """ create fifo
  """
  header_fifo = Fifo(32, 16, 16-4, 4)
  write_data = Signal(intbv(val=0, min=0, max=2**16))
  read_data = Signal(intbv(val=0, min=0, max=2**16))
    
  @always_seq (ip_clk.negedge, reset=ip_rst)
  def fifo_write():

    """ 
      clear fifo's at reset
    """
    if ResetError == 1: 
      header_fifo.reset()
    else: 
      """ write to fifo """
      if write == 1 and header_fifo.is_full==0:
        header_fifo.put(write_data)

  @always_comb 
  def fifo_read():

    """ read from fifo if requested and there is data """
    if read == 1 and header_fifo.is_empty() == 0:
      """ change format only """
      read_data = header_fifo.get()

  return fifo_write, fifo_read

# ------------------------------------------------------------------------------
# Test functions
# ------------------------------------------------------------------------------
def tst_queue_1():
  depth = 10
  width = 3
  almost_full_level = 9
  almost_empty_level = 1

  # Print all methods

  #print(dir(Fifo))

  # Testing Put element:
  header_fifo = Fifo(depth, width, almost_full_level, almost_empty_level)

  # fifo = Fifo(depth, width, almost_full_level, almost_empty_level)
  for i in range(11):
    print('Putting {:d}\n'.format(i))
    if header_fifo.is_full():
      # if fifo.is_full():
      print('\t\tShit, the fifo is full')
    else:
      header_fifo.put(i)
  a = 1

  # Testing Get element:
  for i in range(11):
    if header_fifo.is_empty():
      print('\t\tShit, the fifo is empty')
    else:
      symbol = header_fifo.get()
      print('Getting {:d}\n'.format(symbol))

  header_fifo.put(20)
  header_fifo.put(30)
  header_fifo.reset()
  if header_fifo.is_empty():
    print('The fifo is empty and should be\n')

# ------------------------------------------------------------------------------
# Main
# ------------------------------------------------------------------------------
if __name__ == ' __main__':
  tst_queue_1()
     

```

**The convert\_model.py file**

```auto
from myhdl import Signal,intbv, ResetSignal
from fifo_queue import Fifo
from rw_fifo import *

def convert_rw_fifo(hdl):
#assign default/initial values to signals

  ip_rst = ResetSignal(0, active=1, isasync=True) 
  ip_clk = Signal(bool(0))    
  ResetError = Signal(bool(0))  
  write = Signal(bool(0))
  write_data = Signal(intbv(val=0, min=0, max=2**16))
  read = Signal(bool(0))

  rw_fifo_1 = rw_fifo(ip_rst, ip_clk, ResetError, write, write_data, read)
  rw_fifo_1.convert(hdl=hdl)

#------------------------------------------------------------------------------
# Main
#------------------------------------------------------------------------------
if __name__ == ' __main__' :
  convert_rw_fifo(hdl='VHDL')

```

Thanks already for the effort you did.

Best Regards,

Albert Hoevenaars

---

<div class="post-metadata">

**Author:** ![josyb](https://yyz2.discourse-cdn.com/flex030/user_avatar/discourse.myhdl.org/josyb/32/5_2.png) [@josyb](https://discourse.myhdl.org/u/josyb)\
**Post date:** [January 19, 2022, 7:22pm UTC](https://discourse.myhdl.org/t/trying-to-create-a-fifo-through-a-queue/491/7 "2022-01-19T19:22:20Z")

</div>

Hi Albert,

That went better.  
I can run your _tst\_queue\_1()_ and it seems to do the expected. But that is standard Python code.  
Now MyHDL is a bit stubborn and conversion is very picky.  
First problem is that it doesn’t do method calls like `header_fifo.reset()`. The next issue will be that it won’t know what to do with the queue.Queue object; it doesn’t contain any valid MyHDL code.  
I checked the `queue` example in the _MyHDL Manual_. This will actually simulate, **but** it will not convert. (It also needs some work to bring it up to 0.11 standard)  
What is your goal?

Best regards,  
Josy

---

<div class="post-metadata">

**Author:** ![Albert](https://avatars.discourse-cdn.com/v4/letter/a/48db29/32.png) [@Albert](https://discourse.myhdl.org/u/Albert)\
**Post date:** [January 20, 2022, 7:05am UTC](https://discourse.myhdl.org/t/trying-to-create-a-fifo-through-a-queue/491/8 "2022-01-20T07:05:54Z")

</div>

Josyb,

thanks for looking into my code. My goal was to create a fifo and I was looking how to do that. A list could be used but I also read about queue’s, which is just what a fifo does. So I used that. Also the queue example in the MyHDL guide set me on that track. And a queue used in a class looked very nice and rather simple. I found some other fifo examples but they used memory and read/write pointers (which is just what a fifo uses, I know).  
I have to create testbenches for a very big design and I am now working bottom up. First creating small testbenches, but those are already difficult enough because of the use of Xilinx IP. Fifo and memories are used very often. For now I decided to create a design in HDL Designer were I convert the code from the DUT to MyHDL code (written in a complete other way) and use the Xilinx IP blocks that were already in the design. This gives me a complete model of the DUT. Then I use some blocks from UVVM to complete the testbench.  
Conclusion is now that I do not have to make models for IP blocks. I simply reused because they are already in our libraries of HDL Designer. Makes live much simpler.

When I use a fifo some flags are also stored in the fifo along with the signed data. They need to be split-off at the output of the fifo. But splitting of the signed data value from the flags give me always positive numbers. Some conversion is needed. Still need to figure out how to do that. But learning every day more and more.

So thanks again for having a look in my problems.

Best Regards,

Albert Hoevenaars
