Versal ACAP Power Tool part 4 - Developing with the Power Tool


If you are an advanced user and you want to take advantage of the poweradvantage.py, this Wiki page describes some things you can do.

Table of Contents


1 Advanced Use Cases

If you would like to use poweradvantage.py directly from Python instead of Jupyter Notebook we have section 1.1 "poweradvantage.py From Python". If you wish to customize the output format of poweradvantage.py please check section 1.2 "Customized output from poweradvantage.py". If you would like to port to an additional platform, proceed to section 1.3 "Porting poweradvantage.py".

1.1 poweradvantage.py from Python

The poweradvantage.py library is accessible directly from Python 3.
from poweradvantage import poweradvantage
import time
pa = poweradvantage("VMK180", "SC")

while 1:
pa.printpower()
time.sleep(1)

1.2 Customized Output from poweradvantage.py

printpower prints the power but can also be copied and modified to make a custom printout.
    def getpower(self):
        power = []
        for (b, a, m, f) in zip(self.bus, self.address, self.mOhm, self.flags):
            if f & FLAGS_TPS53681:
                v, i, p = self.tps53681("/dev/i2c-"+str(b), a, m, f)
            else:
                v, i, p = self.ina226("/dev/i2c-"+str(b), a, m, f)
            power.append([v, i, p])
        return power

    def printpower(self):
        power = self.getpower()
        domain = ""
        dtotal = 0
        total = 0
        print("%18s Volts   Amps   Watts" % "")
        for (n, d, p) in zip(self.name, self.domain, power):
            if (domain != "") and (d != domain):
                print("%18s ----- ------- %7.4f" % (domain, dtotal))
                dtotal = 0 
            domain = d
            print("%18s %5.3f %7.4f %7.4f" % (n, p[0], p[1], p[2]))
            dtotal += p[2]
            total += p[2]
        print("%18s ----- ------- %7.4f" % (domain, dtotal))
        print("%18s ----- ------- %7.4f" % ("Total", total))
        return power

For example, if you wanted to only print a subset of the data, you could code this snippet:

from poweradvantage import poweradvantage
import time
from IPython import display
pa = poweradvantage("VCK190", "SC")
while 1:
 display.clear_output(wait=True)
 power = pa.getpower()
 domain = ""
 dtotal = 0
 total = 0
 print("%18s Volts   Amps   Watts" % "")
 for (n, d, p) in zip(pa.name, pa.domain, power):
     if (d == "LPD") or (d == "FPD"):
         if (domain != "") and (d != domain):
             print("%18s ----- ------- %7.4f" % (domain, dtotal))
             dtotal = 0 
         domain = d
         print("%18s %5.3f %7.4f %7.4f" % (n, p[0], p[1], p[2]))
         dtotal += p[2]
         total += p[2]
 print("%18s ----- ------- %7.4f" % (domain, dtotal))
 time.sleep(5)

This example samples a single rail quickly, at a 1ms interval:

from poweradvantage import poweradvantage
pa = poweradvantage("VCK190", "SC")
power = []

i = 4
n = pa.name[i]
b = pa.bus[i]
a = pa.address[i]
m = pa.mOhm[i]
f = pa.flags[i]

count = 0
while count < 10000:
 v, i, p = pa.ina226("/dev/i2c-"+str(b), a, m, f)
 power.append(p)
 count += 1
print(n, power)


This one writes the data to a file for a multi-day measurement:

cat power_adv.log

from poweradvantage import poweradvantage
import time
import sys
from IPython import display
pa = poweradvantage("VCK190", "SC")
    
with open('/home/root/power_adv.log', 'w') as f:
 while 1:
  power = self.getpower()
  domain = ""
  dtotal = 0
  total = 0
  print("hello power adv", file=f)
  print("%18s Volts   Amps   Watts" % "", file=f)
  for (n, d, p) in zip(self.name, self.domain, power):
      if (domain != "") and (d != domain):
         print("%18s ----- ------- %7.4f" % (domain, dtotal))
         dtotal = 0 
      domain = d
      print("%18s %5.3f %7.4f %7.4f" % (n, p[0], p[1], p[2]), file=f)
      dtotal += p[2]
      total += p[2]
  print("%18s ----- ------- %7.4f" % (domain, dtotal), file=f)
  print("%18s ----- ------- %7.4f" % ("Total", total), file=f)
  print("\n")
  time.sleep(60)

This one does a customized plot:

from poweradvantage import poweradvantage
import time
from IPython import display
from datetime import datetime
import pandas as pd
%matplotlib inline
import matplotlib.pyplot as plt
pa = poweradvantage("VCK190", "SC")
name = pa.getname()
import numpy as np
data = {'PS_FPD_Power': []}
#create dataframe
df = pd.DataFrame(data)
while 1:
 dt_object = datetime.fromtimestamp(datetime.timestamp(datetime.now()))
 power = pa.getpower()
 for (n, d, p) in zip(pa.name, pa.domain, power):
    if (n == 'VCC_PSFP'):
        print("PS FPD %7.4f (watts)" % (p[2]))
        #append row to the dataframe
        new_data = {'PS_FPD_Power': p[2]}
        df = df.append(new_data, ignore_index=True)
        plt.plot(df.tail(1000)) # plotting by columns
        display.clear_output(wait=True)
        plt.show()


1.3 Porting poweradvantage.py

If you wish to support another board type that is not currently supported, poweradvantage.py was coded to be flat and modular.

The entire code is driven by a set of arrays, where each element represents a power rail.

At the beginning of the code is a large "if else" switch that selects what type of board and which processor, then instantiates one set of arrays.

To add support for another board, you only need to clone one set and edit it.

The code includes examples of how to read power from an INA226 as well as how to read power straight from a PMIC. Flag bits allow special processing when needed. The flags are all coded from constants so the entire flag system can be rearranged to insert more flags if needed.

        # Create some members
        if name == "ZCU111":

            self.bus = [
                3,3,3,3,
                3,3,3,3,
                3,3,3,3,
                3,3]

            self.address = [
                0x40,0x45,0x46,0x49,
                0x4a,0x4b,0x4c,0x4d,
                0x4e,0x43,0x47,0x48,
                0x41,0x42]

            self.name = [
                "VCCINT","VADJ_FMC","MGTAVCC","VCCINT_AMS",
                "DAC_AVTT","DAC_AVCCAUX","ADC_AVCC","ADC_AVCCAUX",
                "DAC_AVCC","VCC1V2","MGT1V2","MGT1V8",
                "VCCPSINT","VCC1V8"]



Related Links

Home Previous Next