from . import Detector, Pattern from .bits import setbit, clearbit import textwrap from pathlib import Path class PatternGenerator: """ Class to generate a pattern for the SLS detector. Intents to as closely as possible mimic the old pattern generation in the C code. """ def __init__(self): self.pattern = Pattern() self.iaddr = 0 def SB(self, *bits): """ Set one or several bits. Change will take affect with the next PW. """ for bit in bits: self.pattern.word[self.iaddr] = setbit(bit, self.pattern.word[self.iaddr]) return self.pattern.word[self.iaddr] def CB(self, *bits): """ Clear one or several bits. Change will take affect with the next PW. """ for bit in bits: self.pattern.word[self.iaddr] = clearbit(bit, self.pattern.word[self.iaddr]) return self.pattern.word[self.iaddr] def _pw(self, verbose = False): if verbose: print(f'{self.iaddr:#06x} {self.pattern.word[self.iaddr]:#018x}') #Limits are inclusive so we need to increment the address before writing the next word self.pattern.limits[1] = self.iaddr self.iaddr += 1 self.pattern.word[self.iaddr] = self.pattern.word[self.iaddr-1] def PW(self, x = 1, verbose = False): for i in range(x): self._pw(verbose) # def REPEAT(self, x, verbose = False): # for i in range(x): # self._pw(verbose) # def PW2(self, verbose = 0): # self.REPEAT(2, verbose) def CLOCKS(self, bit, times = 1, length = 1, verbose = False): """ clocks "bit" n "times", every half clock is long "length" length is optional, default value is 1 """ for i in range(0, times): self.SB(bit); self.PW(length, verbose) self.CB(bit); self.PW(length, verbose) def CLOCK(self, bit, length = 1, verbose = 0): self.CLOCKS(bit, 1, length ,verbose) def serializer(self, value, serInBit, clkBit, nbits, msbfirst = True, length = 1): """serializer(value,serInBit,clkBit,nbits,msbfirst=1,length=1) Produces the .pat file needed to serialize a word into a shift register. value: value to be serialized serInBit: control bit corresponding to serial in clkBit: control bit corresponding to the clock nbits: number of bits of the target register to load msbfirst: if 1 pushes in the MSB first (default), if 0 pushes in the LSB first length: length of all the PWs in the pattern It produces no output because it modifies directly the members of the class pat via SB and CB""" c = value self.CB(serInBit, clkBit) self.PW(length) #generate initial line with clk and serIn to 0 start = 0 stop = nbits step = 1 if msbfirst: start = nbits - 1 stop = -1 step =- 1 #reverts loop if msb has to be pushed in first for i in range(start, stop, step): if c & (1< 0: self.pattern.word[n] = self.pattern.word[n-1] def send_to_detector(self, det): """ Load the pattern into the detector. """ det.setPattern(self.pattern)