04 - Reading, math, and writing

Objective: Use the tProc to do some math and/or bitwise operations on two variables that you will pass in through the config dictionary and take out with single_read .

[1]:
# Import the QICK drivers and auxiliary libraries
from qick import *
import time
%pylab inline
Populating the interactive namespace from numpy and matplotlib
[2]:
# Load bitstream with custom overlay
soc = QickSoc()
soccfg = soc

Hardware Configuration

tProc channel 7 : DAC 229 CH3 <-> Readout channel 0 : ADC 224 CH0

[3]:
class LoopbackProgram(AveragerProgram):
    def initialize(self):
        cfg=self.cfg

        # Move value of A into tProc register
        self.regwi(0,1,self.cfg["A"])

        self.synci(200)  # give processor some time to configure pulses

    def body(self):
        # Do math: add value of B to the register value
        self.mathi(0, 1, 1, '+', self.cfg["B"])

        # Write the result to address 123
        self.memwi(0,1,123)

Here we will add the value of A to the value of B using the tProc. We write the result to tProc memory address 123, and then read out that address value at the end of the program.

[5]:
config={"reps": 1, # fixed
        "A": 100,
        "B": -50
       }

prog =LoopbackProgram(soccfg, config)

# Load the program into the tProc.
prog.config_all(soc)
# Start tProc.
soc.start_tproc()
time.sleep(0.1)
result = soc.tproc.single_read(addr=123)
print("Result = ", result)
Result =  50

Here we show how similar register operations can also be done using the QickRegister object.

The QickRegister object keeps the register page, address, gen_ch/ro_ch, and reg_type information, so unit conversions like freq2reg/us2cycle/deg2reg can be automatically used when we assign values to registers. This makes qick programs easier to write and read especially when a lot of operations on registers that correspond to physical values are involved.

In the program below, we assign values to the frequency register of a generator, all the assignments are done directly using frequency values in MHz, and no explicit reference to the low level register value/page/address is needed.

[6]:
from qick.asm_v1 import QickRegister, QickRegisterManagerMixin
[7]:
class TestRegProgram(QickRegisterManagerMixin, AveragerProgram):  # inhered the QickRegisterManagerMixin class
    def initialize(self):
        cfg = self.cfg
        self.declare_gen(ch=cfg["gen_ch"], nqz=1, ro_ch=cfg["ro_ch"])  # this "ro_ch" will be automatically used for freq2reg operations later

        # get the frequency register associated with gen_ch
        self.gen_freq_reg = self.get_gen_reg(cfg["gen_ch"], "freq")

        # declare another frequency type register on the same generator page, initialize it to the integer that corresponds to frequency "f1" in MHz
        # the "gen_ch" and "ro_ch" of cfg["gen_ch"] will be automatically used when converting a physical frequency value to integers of this register
        self.gen_freq_reg_temp = self.new_gen_reg(cfg["gen_ch"], name="freq_temp", init_val=cfg["f1"], reg_type="freq")

        self.synci(200)  # give processor some time to configure pulses

    def body(self):
        cfg = self.cfg

        # set the register value to the integer that corresponds to frequency "f0" in MHz
        self.gen_freq_reg.set_to(cfg["f0"])
        # Write the result to address 123
        self.memwi(self.gen_freq_reg.page, self.gen_freq_reg.addr, 123)

        # assign the value of register "gen_freq_reg_temp" to register "gen_freq_reg", which should corresponds to "f1"
        self.gen_freq_reg.set_to(self.gen_freq_reg_temp)
        # Write the result to address 124
        self.memwi(self.gen_freq_reg.page, self.gen_freq_reg.addr, 124)

        # add 300 MHz to the frequency kept in "gen_freq_reg_temp" and assign it to "gen_freq_reg"
        self.gen_freq_reg.set_to(self.gen_freq_reg_temp, "+", 300)
        # Write the result to address 125
        self.memwi(self.gen_freq_reg.page, self.gen_freq_reg.addr, 125)

        # sum the frequencies kept in "gen_freq_reg_temp" and "gen_freq_reg" and assign it to "gen_freq_reg"
        self.gen_freq_reg.set_to(self.gen_freq_reg, "+", self.gen_freq_reg_temp)
        # Write the result to address 126
        self.memwi(self.gen_freq_reg.page, self.gen_freq_reg.addr, 126)


[7]:
config={
        "gen_ch": 0,
        "ro_ch": 0,
        "reps": 1, # fixed
        "f0": 1000, #MHz
        "f1": 500 #MHz
       }

prog =TestRegProgram(soccfg, config)


# Load the program into the tProc.
prog.config_all(soc)
# Start tProc.
soc.start_tproc()

print(prog)

time.sleep(0.1)


# compare the result with what we should get using freq2reg functions
result = soc.tproc.single_read(addr=123)
print(f"Result=", result, ", expected:", prog.freq2reg(config["f0"], config["gen_ch"], config["ro_ch"]))

result = soc.tproc.single_read(addr=124)
print(f"Result=", result, ", expected:",prog.freq2reg(config["f1"], config["gen_ch"], config["ro_ch"]))

result = soc.tproc.single_read(addr=125)
print(f"Result=", result, ", expected:",prog.freq2reg(config["f1"]+300, config["gen_ch"], config["ro_ch"]))

result = soc.tproc.single_read(addr=126)
print(f"Result=", result, ", expected:",prog.freq2reg(config["f1"]+300+config["f1"], config["gen_ch"], config["ro_ch"]))

// Program

        regwi 0, $1, 312076190;                 //'freq_temp' <= 312076190 (500 MHz)
        synci 200;
        regwi 0, $15, 0;
        regwi 0, $14, 0;
LOOP_J: regwi 0, $22, 624152380;                //'gen0_freq' <= 624152380 (1000 MHz)
        memwi 0, $22, 123;
        mathi 0, $22, $1 + 0;                   // 'gen0_freq' <= 'freq_temp' + 0 (0 MHz)
        memwi 0, $22, 124;
        mathi 0, $22, $1 + 187245715;           // 'gen0_freq' <= 'freq_temp' + 187245715 (300 MHz)
        memwi 0, $22, 125;
        math 0, $22, $22 + $1;                  // 'gen0_freq' <= 'gen0_freq' + 'freq_temp'
        memwi 0, $22, 126;
        mathi 0, $15, $15 + 1;
        memwi 0, $15, 1;
        loopnz 0, $14, @LOOP_J;
        end ;
Result= 624152380 , expected: 624152380
Result= 312076190 , expected: 312076190
Result= 499321905 , expected: 499321905
Result= 811398095 , expected: 811398095
[ ]: