1""" 2======================================================================== 3queues.py 4======================================================================== 5This file contains cycle-level queues. 6 7Author : Shunning Jiang, Yanghui Ou 8Date : Mar 10, 2018 9""" 10 11from collections import deque 12 13from pymtl3 import * 14 15#------------------------------------------------------------------------- 16# PipeQueueCL 17#------------------------------------------------------------------------- 18 19class PipeQueueCL( Component ): 20 21 def construct( s, num_entries=1 ): 22 s.queue = deque( maxlen=num_entries ) 23 24 s.add_constraints( 25 M( s.peek ) < M( s.enq ), 26 M( s.deq ) < M( s.enq ) 27 ) 28 29 @non_blocking( lambda s: len( s.queue ) < s.queue.maxlen ) 30 def enq( s, msg ): 31 s.queue.appendleft( msg ) 32 33 @non_blocking( lambda s: len( s.queue ) > 0 ) 34 def deq( s ): 35 return s.queue.pop() 36 37 @non_blocking( lambda s: len( s.queue ) > 0 ) 38 def peek( s ): 39 return s.queue[-1] 40 41 def line_trace( s ): 42 return "{}( ){}".format( s.enq, s.deq ) 43 44#------------------------------------------------------------------------- 45# BypassQueueCL 46#------------------------------------------------------------------------- 47 48class BypassQueueCL( Component ): 49 50 def construct( s, num_entries=1 ): 51 s.queue = deque( maxlen=num_entries ) 52 53 s.add_constraints( 54 M( s.enq ) < M( s.peek ), 55 M( s.enq ) < M( s.deq ), 56 ) 57 58 @non_blocking( lambda s: len( s.queue ) < s.queue.maxlen ) 59 def enq( s, msg ): 60 s.queue.appendleft( msg ) 61 62 @non_blocking( lambda s: len( s.queue ) > 0 ) 63 def deq( s ): 64 return s.queue.pop() 65 66 @non_blocking( lambda s: len( s.queue ) > 0 ) 67 def peek( s ): 68 return s.queue[-1] 69 70 def line_trace( s ): 71 return "{}( ){}".format( s.enq, s.deq ) 72 73#------------------------------------------------------------------------- 74# NormalQueueCL 75#------------------------------------------------------------------------- 76 77class NormalQueueCL( Component ): 78 79 def construct( s, num_entries=1 ): 80 s.queue = deque( maxlen=num_entries ) 81 s.enq_rdy = False 82 s.deq_rdy = False 83 84 @update 85 def up_pulse(): 86 s.enq_rdy = len( s.queue ) < s.queue.maxlen 87 s.deq_rdy = len( s.queue ) > 0 88 89 s.add_constraints( 90 U( up_pulse ) < M( s.enq.rdy ), 91 U( up_pulse ) < M( s.deq.rdy ), 92 M( s.peek ) < M( s.deq.rdy ), 93 M( s.peek ) < M( s.enq.rdy ) 94 ) 95 96 @non_blocking( lambda s: s.enq_rdy ) 97 def enq( s, msg ): 98 s.queue.appendleft( msg ) 99 100 @non_blocking( lambda s: s.deq_rdy ) 101 def deq( s ): 102 return s.queue.pop() 103 104 @non_blocking( lambda s: len( s.queue ) > 0 ) 105 def peek( s ): 106 return s.queue[-1] 107 108 def line_trace( s ): 109 return "{}( ){}".format( s.enq, s.deq ) 110