unitest.py 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240
  1. """
  2. # TOP2049 Open Source programming suite
  3. #
  4. # Universal device tester
  5. #
  6. # Copyright (c) 2010-2012 Michael Buesch <m@bues.ch>
  7. #
  8. # This program is free software; you can redistribute it and/or modify
  9. # it under the terms of the GNU General Public License as published by
  10. # the Free Software Foundation; either version 2 of the License, or
  11. # (at your option) any later version.
  12. #
  13. # This program is distributed in the hope that it will be useful,
  14. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  15. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  16. # GNU General Public License for more details.
  17. #
  18. # You should have received a copy of the GNU General Public License along
  19. # with this program; if not, write to the Free Software Foundation, Inc.,
  20. # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  21. """
  22. from libtoprammer.chip import *
  23. class Chip_Unitest(Chip):
  24. MODE_UNITEST = 0 # Standard universal tester
  25. MODE_FCNT = 1 # Frequency counter
  26. def __init__(self, chipPackage=None, chipPinVCC=None, chipPinsVPP=None, chipPinGND=None,
  27. VCCVoltage=None, VPPVoltage=None):
  28. Chip.__init__(self, chipPackage=chipPackage, chipPinVCC=chipPinVCC,
  29. chipPinsVPP=chipPinsVPP, chipPinGND=chipPinGND)
  30. self.autogenVCCVoltage = VCCVoltage
  31. self.autogenVPPVoltage = VPPVoltage
  32. self.mode = self.MODE_UNITEST
  33. def shutdownChip(self):
  34. self.printDebug("Shutdown chip")
  35. self.reset()
  36. def reset(self):
  37. self.top.vcc.setLayoutPins( [] )
  38. self.vccMask = 0
  39. self.top.vpp.setLayoutPins( [] )
  40. self.vppMask = 0
  41. self.top.gnd.setLayoutPins( [] )
  42. self.gndMask = 0
  43. self.top.cmdSetVCCVoltage(self.top.vcc.minVoltage())
  44. self.top.cmdSetVPPVoltage(self.top.vpp.minVoltage())
  45. self.oscMask = 0
  46. self.oscDiv = 0
  47. self.fcntPin = 0
  48. self.setOutputEnableMask(0)
  49. self.setOutputs(0)
  50. self.setOscMask(0)
  51. self.top.flushCommands()
  52. def getMode(self):
  53. return self.mode
  54. def setMode(self, newMode):
  55. if self.mode == newMode:
  56. return
  57. # Upload the new bitfile to the FPGA
  58. bitfiles = {
  59. self.MODE_UNITEST : ("unitest", (8, 1)),
  60. self.MODE_FCNT : ("unitest_fcnt", (8, 2)),
  61. }
  62. name, runtimeIDs = bitfiles[newMode]
  63. self.top.configureFPGA(name, runtimeIDs)
  64. # Re-upload the FPGA state
  65. self.__updateOutEn()
  66. self.__updateOut()
  67. self.__updateOscDivider()
  68. self.__updateOscMask()
  69. self.__updateFreqCountPin()
  70. self.top.flushCommands()
  71. self.mode = newMode
  72. def setVCC(self, voltage, layout):
  73. self.vccMask = self.top.vcc.ID2mask(layout)
  74. self.__updateOutEn()
  75. self.top.cmdSetVCCVoltage(voltage)
  76. self.top.vcc.setLayoutID(layout)
  77. self.top.flushCommands()
  78. def setVPP(self, voltage, layouts):
  79. self.vppMask = 0
  80. for layout in layouts:
  81. self.vppMask |= self.top.vpp.ID2mask(layout)
  82. self.__updateOutEn()
  83. self.top.cmdSetVPPVoltage(voltage)
  84. self.top.vpp.setLayoutMask(0) # Reset
  85. for layout in layouts:
  86. self.top.vpp.setLayoutID(layout)
  87. self.top.flushCommands()
  88. def setGND(self, layout):
  89. self.gndMask = self.top.gnd.ID2mask(layout)
  90. self.__updateOutEn()
  91. self.top.gnd.setLayoutID(layout)
  92. self.top.flushCommands()
  93. # Overloaded layout generator interface.
  94. def applyVCC(self, turnOn):
  95. layoutID = 0
  96. if turnOn:
  97. (layoutID, layoutMask) = self.generator.getVCCLayout()
  98. self.setVCC(self.autogenVCCVoltage, layoutID)
  99. # Overloaded layout generator interface.
  100. def applyVPP(self, turnOn, packagePinsToTurnOn=[]):
  101. assert(not packagePinsToTurnOn) # Not supported, yet.
  102. layouts = []
  103. if turnOn:
  104. layouts = [layoutID_layoutMask[0] for layoutID_layoutMask in self.generator.getVPPLayouts()]
  105. self.setVPP(self.autogenVPPVoltage, layouts)
  106. # Overloaded layout generator interface.
  107. def applyGND(self, turnOn):
  108. layoutID = 0
  109. if turnOn:
  110. (layoutID, layoutMask) = self.generator.getGNDLayout()
  111. self.setGND(layoutID)
  112. def getActivePinMask(self):
  113. masks = {
  114. self.MODE_UNITEST : 0xFFFFFFFFFFFF, # 1-48
  115. self.MODE_FCNT : 0x000FFFFFF000, # 13-36
  116. }
  117. return masks[self.mode]
  118. def __updateOutEn(self):
  119. mask = self.desiredOutEnMask
  120. mask &= ~self.gndMask
  121. mask &= ~self.vccMask
  122. mask &= ~self.vppMask
  123. mask |= self.oscMask
  124. mask &= self.getActivePinMask()
  125. self.top.cmdFPGAWrite(0x40, mask & 0xFF)
  126. self.top.cmdFPGAWrite(0x41, (mask >> 8) & 0xFF)
  127. self.top.cmdFPGAWrite(0x42, (mask >> 16) & 0xFF)
  128. self.top.cmdFPGAWrite(0x43, (mask >> 24) & 0xFF)
  129. self.top.cmdFPGAWrite(0x44, (mask >> 32) & 0xFF)
  130. self.top.cmdFPGAWrite(0x45, (mask >> 40) & 0xFF)
  131. def setOutputEnableMask(self, mask):
  132. self.desiredOutEnMask = mask
  133. self.__updateOutEn()
  134. self.top.flushCommands()
  135. def __updateOut(self):
  136. mask = self.desiredOutMask
  137. mask &= ~self.oscMask
  138. mask &= self.getActivePinMask()
  139. self.top.cmdFPGAWrite(0x60, mask & 0xFF)
  140. self.top.cmdFPGAWrite(0x61, (mask >> 8) & 0xFF)
  141. self.top.cmdFPGAWrite(0x62, (mask >> 16) & 0xFF)
  142. self.top.cmdFPGAWrite(0x63, (mask >> 24) & 0xFF)
  143. self.top.cmdFPGAWrite(0x64, (mask >> 32) & 0xFF)
  144. self.top.cmdFPGAWrite(0x65, (mask >> 40) & 0xFF)
  145. def setOutputs(self, mask):
  146. self.desiredOutMask = mask
  147. self.__updateOut()
  148. self.top.flushCommands()
  149. def getInputs(self):
  150. self.top.cmdFPGARead(0x60)
  151. self.top.cmdFPGARead(0x61)
  152. self.top.cmdFPGARead(0x62)
  153. self.top.cmdFPGARead(0x63)
  154. self.top.cmdFPGARead(0x64)
  155. self.top.cmdFPGARead(0x65)
  156. inputs = self.top.cmdReadBufferReg48()
  157. return inputs
  158. def __updateOscDivider(self):
  159. div = self.oscDiv
  160. self.top.cmdFPGAWrite(0x00, div & 0xFF)
  161. self.top.cmdFPGAWrite(0x01, (div >> 8) & 0xFF)
  162. self.top.cmdFPGAWrite(0x02, (div >> 16) & 0xFF)
  163. self.top.cmdFPGAWrite(0x03, (div >> 24) & 0xFF)
  164. def setOscDivider(self, div):
  165. self.oscDiv = div
  166. self.__updateOscDivider()
  167. self.top.flushCommands()
  168. def __updateOscMask(self):
  169. mask = self.oscMask
  170. mask &= self.getActivePinMask()
  171. self.top.cmdFPGAWrite(0x20, mask & 0xFF)
  172. self.top.cmdFPGAWrite(0x21, (mask >> 8) & 0xFF)
  173. self.top.cmdFPGAWrite(0x22, (mask >> 16) & 0xFF)
  174. self.top.cmdFPGAWrite(0x23, (mask >> 24) & 0xFF)
  175. self.top.cmdFPGAWrite(0x24, (mask >> 32) & 0xFF)
  176. self.top.cmdFPGAWrite(0x25, (mask >> 40) & 0xFF)
  177. def setOscMask(self, mask):
  178. self.oscMask = mask
  179. self.__updateOscMask()
  180. self.__updateOutEn()
  181. self.__updateOut()
  182. self.top.flushCommands()
  183. def __updateFreqCountPin(self):
  184. if self.mode == self.MODE_FCNT:
  185. value = self.fcntPin
  186. self.top.cmdFPGAWrite(0x80, value)
  187. def setFreqCountPin(self, pinNumber, invert=False):
  188. assert(pinNumber <= 0x3F)
  189. value = pinNumber & 0x3F
  190. if invert:
  191. value |= 0x80
  192. self.fcntPin = value
  193. self.__updateFreqCountPin()
  194. self.top.flushCommands()
  195. def getFreqCount(self):
  196. if self.mode != self.MODE_FCNT:
  197. return 0
  198. self.top.cmdFPGARead(0x00)
  199. self.top.cmdFPGARead(0x01)
  200. self.top.cmdFPGARead(0x02)
  201. self.top.cmdFPGARead(0x03)
  202. count = self.top.cmdReadBufferReg32()
  203. return count
  204. ChipDescription(
  205. Chip_Unitest,
  206. chipID = "unitest",
  207. bitfile = "unitest",
  208. runtimeID = (8, 1),
  209. chipType = ChipDescription.TYPE_INTERNAL,
  210. description = "Universal device tester",
  211. )