simu.py 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186
  1. ###########################################
  2. # Project: CMSIS DSP Library
  3. # Title: simu.py
  4. # Description: Support Python classes for the Python SDF scheduler
  5. #
  6. # $Date: 29 July 2021
  7. # $Revision: V1.10.0
  8. #
  9. # Target Processor: Cortex-M and Cortex-A cores
  10. # -------------------------------------------------------------------- */
  11. #
  12. # Copyright (C) 2010-2021 ARM Limited or its affiliates. All rights reserved.
  13. #
  14. # SPDX-License-Identifier: Apache-2.0
  15. #
  16. # Licensed under the Apache License, Version 2.0 (the License); you may
  17. # not use this file except in compliance with the License.
  18. # You may obtain a copy of the License at
  19. #
  20. # www.apache.org/licenses/LICENSE-2.0
  21. #
  22. # Unless required by applicable law or agreed to in writing, software
  23. # distributed under the License is distributed on an AS IS BASIS, WITHOUT
  24. # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  25. # See the License for the specific language governing permissions and
  26. # limitations under the License.
  27. ############################################
  28. """ Classes for Python version of the generated schedule
  29. """
  30. import numpy as np
  31. class FIFOBase:
  32. pass
  33. class FIFO(FIFOBase):
  34. def __init__(self,fifoSize,fifoBuf):
  35. self._length = fifoSize
  36. self._buffer = fifoBuf
  37. self._readPos = 0
  38. self._writePos = 0
  39. def getWriteBuffer(self,nb):
  40. if (self._readPos > 0):
  41. self._buffer[:self._writePos-self._readPos] = self._buffer[self._readPos:self._writePos]
  42. self._writePos = self._writePos - self._readPos
  43. self._readPos = 0
  44. ret = self._buffer[self._writePos:self._writePos+nb]
  45. self._writePos = self._writePos + nb
  46. return(ret)
  47. def getReadBuffer(self,nb):
  48. ret = self._buffer[self._readPos:self._readPos+nb]
  49. self._readPos = self._readPos + nb
  50. return(ret)
  51. @property
  52. def type(self):
  53. return(self._buffer.dtype)
  54. def dump(self):
  55. print(self._buffer)
  56. class GenericNode:
  57. def __init__(self,inputSize, outputSize,fifoin,fifoout):
  58. self._src = fifoin
  59. self._dst = fifoout
  60. self._inputSize = inputSize
  61. self._outputSize = outputSize
  62. def getWriteBuffer(self):
  63. return(self._dst.getWriteBuffer(self._outputSize))
  64. def getReadBuffer(self):
  65. return(self._src.getReadBuffer(self._inputSize))
  66. class GenericNode12:
  67. def __init__(self,inputSize, outputSize1,outputSize2,fifoin,fifoout1,fifoout2):
  68. self._src = fifoin
  69. self._dst1 = fifoout1
  70. self._dst2 = fifoout2
  71. self._inputSize = inputSize
  72. self._outputSize1 = outputSize1
  73. self._outputSize2 = outputSize2
  74. def getWriteBuffer1(self):
  75. return(self._dst1.getWriteBuffer(self._outputSize1))
  76. def getWriteBuffer2(self):
  77. return(self._dst2.getWriteBuffer(self._outputSize2))
  78. def getReadBuffer(self):
  79. return(self._src.getReadBuffer(self._inputSize))
  80. class GenericNode21:
  81. def __init__(self,inputSize1,inputSize2, outputSize,fifoin1,fifoin2,fifoout):
  82. self._src1 = fifoin1
  83. self._src2 = fifoin2
  84. self._dst = fifoout
  85. self._inputSize1 = inputSize1
  86. self._inputSize2 = inputSize2
  87. self._outputSize = outputSize
  88. def getWriteBuffer(self):
  89. return(self._dst.getWriteBuffer(self._outputSize))
  90. def getReadBuffer1(self):
  91. return(self._src1.getReadBuffer(self._inputSize1))
  92. def getReadBuffer2(self):
  93. return(self._src2.getReadBuffer(self._inputSize2))
  94. class GenericSource:
  95. def __init__(self, outputSize,fifoout):
  96. self._dst = fifoout
  97. self._outputSize = outputSize
  98. def getWriteBuffer(self):
  99. return(self._dst.getWriteBuffer(self._outputSize))
  100. class GenericSink:
  101. def __init__(self,inputSize,fifoin):
  102. self._src = fifoin
  103. self._inputSize = inputSize
  104. def getReadBuffer(self):
  105. return(self._src.getReadBuffer(self._inputSize))
  106. class SlidingBuffer(GenericNode):
  107. def __init__(self,windowSize,overlap,fifoin,fifoout):
  108. GenericNode.__init__(self,windowSize-overlap,windowSize,fifoin,fifoout)
  109. self._windowSize = windowSize
  110. self._overlap = overlap
  111. self._memory = np.zeros(overlap)
  112. def run(self):
  113. a=self.getReadBuffer()
  114. b=self.getWriteBuffer()
  115. b[:self._overlap] = self._memory
  116. b[self._overlap:self._windowSize]=a[:self._windowSize-self._overlap]
  117. self._memory[:self._overlap] = b[self._windowSize-self._overlap:self._windowSize]
  118. return(0)
  119. class OverlapTooBig(Exception):
  120. pass
  121. class OverlapAdd(GenericNode):
  122. def __init__(self,windowSize,overlap,fifoin,fifoout):
  123. GenericNode.__init__(self,windowSize,windowSize-overlap,fifoin,fifoout)
  124. if ((windowSize-overlap)<=0):
  125. raise OverlapTooBig
  126. self._windowSize = windowSize
  127. self._overlap = overlap
  128. self._memory = np.zeros(overlap)
  129. def run(self):
  130. a=self.getReadBuffer()
  131. b=self.getWriteBuffer()
  132. self._memory[:self._overlap]= a[:self._overlap] + self._memory[:self._overlap]
  133. if (2*self._overlap - self._windowSize > 0):
  134. b[:self._windowSize-self._overlap] = self._memory[:self._windowSize-self._overlap]
  135. tmp=np.zeros(2*self._overlap - self._windowSize)
  136. tmp[:] = self._memory[self._windowSize-self._overlap:self._overlap]
  137. self._memory[:2*self._overlap - self._windowSize] = tmp
  138. self._memory[2*self._overlap - self._windowSize:self._overlap] = a[self._overlap:self._windowSize]
  139. elif (2*self._overlap - self._windowSize < 0):
  140. b[:self._overlap] = self._memory[:self._overlap]
  141. b[self._overlap:self._windowSize-self._overlap] = a[self._overlap:self._windowSize-self._overlap]
  142. self._memory[:self._overlap] = a[self._windowSize-self._overlap:self._windowSize]
  143. else:
  144. b[:self._overlap]=self._memory[:self._overlap]
  145. self._memory[:self._overlap] = a[self._overlap:2*self._overlap]
  146. return(0)