summaryrefslogtreecommitdiffstats
path: root/libtoprammer/chips
diff options
context:
space:
mode:
authorMichael Buesch <m@bues.ch>2012-07-11 12:19:48 +0200
committerMichael Buesch <m@bues.ch>2012-07-11 12:19:48 +0200
commit9f3a34f6ab7d15083663c04ade95b6c317411510 (patch)
tree1b72a3dafd7efce3b2bf32b0d03dfac4f46ebbfa /libtoprammer/chips
parent7af9d0641e909321741ca3393d0c4245cdffe668 (diff)
downloadtoprammer-9f3a34f6ab7d15083663c04ade95b6c317411510.tar.xz
toprammer-9f3a34f6ab7d15083663c04ade95b6c317411510.zip
Add basic frequency counter to unitest
Signed-off-by: Michael Buesch <m@bues.ch>
Diffstat (limited to 'libtoprammer/chips')
-rw-r--r--libtoprammer/chips/unitest.py86
1 files changed, 79 insertions, 7 deletions
diff --git a/libtoprammer/chips/unitest.py b/libtoprammer/chips/unitest.py
index 363ec12..779f786 100644
--- a/libtoprammer/chips/unitest.py
+++ b/libtoprammer/chips/unitest.py
@@ -3,7 +3,7 @@
#
# Universal device tester
#
-# Copyright (c) 2010 Michael Buesch <m@bues.ch>
+# Copyright (c) 2010-2012 Michael Buesch <m@bues.ch>
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
@@ -24,12 +24,16 @@ from libtoprammer.chip import *
class Chip_Unitest(Chip):
+ MODE_UNITEST = 0 # Standard universal tester
+ MODE_FCNT = 1 # Frequency counter
+
def __init__(self, chipPackage=None, chipPinVCC=None, chipPinsVPP=None, chipPinGND=None,
VCCVoltage=None, VPPVoltage=None):
Chip.__init__(self, chipPackage=chipPackage, chipPinVCC=chipPinVCC,
chipPinsVPP=chipPinsVPP, chipPinGND=chipPinGND)
self.autogenVCCVoltage = VCCVoltage
self.autogenVPPVoltage = VPPVoltage
+ self.mode = self.MODE_UNITEST
def shutdownChip(self):
self.printDebug("Shutdown chip")
@@ -45,11 +49,35 @@ class Chip_Unitest(Chip):
self.top.cmdSetVCCVoltage(self.top.vcc.minVoltage())
self.top.cmdSetVPPVoltage(self.top.vpp.minVoltage())
self.oscMask = 0
+ self.oscDiv = 0
+ self.fcntPin = 0
self.setOutputEnableMask(0)
self.setOutputs(0)
self.setOscMask(0)
self.top.flushCommands()
+ def getMode(self):
+ return self.mode
+
+ def setMode(self, newMode):
+ if self.mode == newMode:
+ return
+ # Upload the new bitfile to the FPGA
+ bitfiles = {
+ self.MODE_UNITEST : ("unitest", (8, 1)),
+ self.MODE_FCNT : ("unitest_fcnt", (8, 2)),
+ }
+ name, runtimeIDs = bitfiles[newMode]
+ self.top.configureFPGA(name, runtimeIDs)
+ # Re-upload the FPGA state
+ self.__updateOutEn()
+ self.__updateOut()
+ self.__updateOscDivider()
+ self.__updateOscMask()
+ self.__updateFreqCountPin()
+ self.top.flushCommands()
+ self.mode = newMode
+
def setVCC(self, voltage, layout):
self.vccMask = self.top.vcc.ID2mask(layout)
self.__updateOutEn()
@@ -97,38 +125,47 @@ class Chip_Unitest(Chip):
(layoutID, layoutMask) = self.generator.getGNDLayout()
self.setGND(layoutID)
+ def getActivePinMask(self):
+ masks = {
+ self.MODE_UNITEST : 0xFFFFFFFFFFFF, # 1-48
+ self.MODE_FCNT : 0x000FFFFFF000, # 13-36
+ }
+ return masks[self.mode]
+
def __updateOutEn(self):
mask = self.desiredOutEnMask
mask &= ~self.gndMask
mask &= ~self.vccMask
mask &= ~self.vppMask
mask |= self.oscMask
+ mask &= self.getActivePinMask()
self.top.cmdFPGAWrite(0x40, mask & 0xFF)
self.top.cmdFPGAWrite(0x41, (mask >> 8) & 0xFF)
self.top.cmdFPGAWrite(0x42, (mask >> 16) & 0xFF)
self.top.cmdFPGAWrite(0x43, (mask >> 24) & 0xFF)
self.top.cmdFPGAWrite(0x44, (mask >> 32) & 0xFF)
self.top.cmdFPGAWrite(0x45, (mask >> 40) & 0xFF)
- self.top.flushCommands()
def setOutputEnableMask(self, mask):
self.desiredOutEnMask = mask
self.__updateOutEn()
+ self.top.flushCommands()
def __updateOut(self):
mask = self.desiredOutMask
mask &= ~self.oscMask
+ mask &= self.getActivePinMask()
self.top.cmdFPGAWrite(0x60, mask & 0xFF)
self.top.cmdFPGAWrite(0x61, (mask >> 8) & 0xFF)
self.top.cmdFPGAWrite(0x62, (mask >> 16) & 0xFF)
self.top.cmdFPGAWrite(0x63, (mask >> 24) & 0xFF)
self.top.cmdFPGAWrite(0x64, (mask >> 32) & 0xFF)
self.top.cmdFPGAWrite(0x65, (mask >> 40) & 0xFF)
- self.top.flushCommands()
def setOutputs(self, mask):
self.desiredOutMask = mask
self.__updateOut()
+ self.top.flushCommands()
def getInputs(self):
self.top.cmdFPGARead(0x60)
@@ -140,29 +177,64 @@ class Chip_Unitest(Chip):
inputs = self.top.cmdReadBufferReg48()
return inputs
- def setOscDivider(self, div):
+ def __updateOscDivider(self):
+ div = self.oscDiv
self.top.cmdFPGAWrite(0x00, div & 0xFF)
self.top.cmdFPGAWrite(0x01, (div >> 8) & 0xFF)
self.top.cmdFPGAWrite(0x02, (div >> 16) & 0xFF)
self.top.cmdFPGAWrite(0x03, (div >> 24) & 0xFF)
+
+ def setOscDivider(self, div):
+ self.oscDiv = div
+ self.__updateOscDivider()
self.top.flushCommands()
- def setOscMask(self, mask):
- self.oscMask = mask
+ def __updateOscMask(self):
+ mask = self.oscMask
+ mask &= self.getActivePinMask()
self.top.cmdFPGAWrite(0x20, mask & 0xFF)
self.top.cmdFPGAWrite(0x21, (mask >> 8) & 0xFF)
self.top.cmdFPGAWrite(0x22, (mask >> 16) & 0xFF)
self.top.cmdFPGAWrite(0x23, (mask >> 24) & 0xFF)
self.top.cmdFPGAWrite(0x24, (mask >> 32) & 0xFF)
self.top.cmdFPGAWrite(0x25, (mask >> 40) & 0xFF)
+
+ def setOscMask(self, mask):
+ self.oscMask = mask
+ self.__updateOscMask()
self.__updateOutEn()
self.__updateOut()
self.top.flushCommands()
+ def __updateFreqCountPin(self):
+ if self.mode == self.MODE_FCNT:
+ value = self.fcntPin
+ self.top.cmdFPGAWrite(0x80, value)
+
+ def setFreqCountPin(self, pinNumber, invert=False):
+ assert(pinNumber <= 0x3F)
+ value = pinNumber & 0x3F
+ if invert:
+ value |= 0x80
+ self.fcntPin = value
+ self.__updateFreqCountPin()
+ self.top.flushCommands()
+
+ def getFreqCount(self):
+ if self.mode != self.MODE_FCNT:
+ return 0
+ self.top.cmdFPGARead(0x00)
+ self.top.cmdFPGARead(0x01)
+ self.top.cmdFPGARead(0x02)
+ self.top.cmdFPGARead(0x03)
+ count = self.top.cmdReadBufferReg32()
+ return count
+
ChipDescription(
Chip_Unitest,
+ chipID = "unitest",
bitfile = "unitest",
- runtimeID = (0x0008, 0x01),
+ runtimeID = (8, 1),
chipType = ChipDescription.TYPE_INTERNAL,
description = "Universal device tester",
)
bues.ch cgit interface