from __future__ import print_function
'''
# Copyright (C) 2015, Elphel.inc.
# Methods that mimic Verilog tasks used for simulation
# 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
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see .
@author: Andrey Filippov
@copyright: 2015 Elphel, Inc.
@license: GPLv3.0+
@contact: andrey@elphel.coml
@deffield updated: Updated
'''
__author__ = "Andrey Filippov"
__copyright__ = "Copyright 2015, Elphel, Inc."
__license__ = "GPL"
__version__ = "3.0+"
__maintainer__ = "Andrey Filippov"
__email__ = "andrey@elphel.com"
__status__ = "Development"
#import sys
#import x393_mem
#x393_pio_sequences
#from import_verilog_parameters import VerilogParameters
from x393_mem import X393Mem
#from x393_axi_control_status import X393AxiControlStatus
import x393_axi_control_status
#from verilog_utils import * # concat, bits
#from verilog_utils import hx, concat, bits, getParWidth
from verilog_utils import concat, getParWidth,hexMultiple
#from x393_axi_control_status import concat, bits
import vrlg # global parameters
#from x393_utils import X393Utils
class X393McntrlTiming(object):
DRY_MODE= True # True
DEBUG_MODE=1
x393_mem=None
x393_axi_tasks=None #x393X393AxiControlStatus
x393_utils=None
def __init__(self, debug_mode=1,dry_mode=True):
self.DEBUG_MODE=debug_mode
self.DRY_MODE=dry_mode
self.x393_mem=X393Mem(debug_mode,dry_mode)
self.x393_axi_tasks=x393_axi_control_status.X393AxiControlStatus(debug_mode,dry_mode)
# self.__dict__.update(VerilogParameters.__dict__["_VerilogParameters__shared_state"]) # Add verilog parameters to the class namespace
def get_dly_steps(self):
#hardwired in phy_top.v
# CLKOUT0_DIVIDE_F= 2.000
CLKOUT1_DIVIDE = 2
# CLKOUT2_DIVIDE = 4
fCLK_IN=1000.0/vrlg.CLKIN_PERIOD
fVCO=fCLK_IN*vrlg.CLKFBOUT_MULT
fSDCLK=fVCO/CLKOUT1_DIVIDE
tSDCLK=1000.0/fSDCLK # in ns
phaseStep=1000.0/(fVCO*56.0) # 1 unit of phase shift (now 112 for the full period
# fREF=fCLK_IN*vrlg.CLKFBOUT_MULT_REF/vrlg.CLKFBOUT_DIV_REF
fREF=fCLK_IN*vrlg.MULTICLK_MULT/vrlg.MULTICLK_DIV_DLYREF/vrlg.MULTICLK_DIVCLK
dlyStep=1000.0/fREF/32/2 # Approximate, depending on calibration
dlyFStep=0.01 # fine step
return{"SDCLK_PERIOD":tSDCLK,
"PHASE_STEP":phaseStep,
"DLY_STEP":dlyStep,
"DLY_FINE_STEP":dlyFStep}
def axi_set_phase(self,
phase=None, # input [PHASE_WIDTH-1:0] phase;
wait_phase_en=True,
wait_seq=False,
quiet=1):
"""
Set clock phase TODO: Add refresh off/on for changing phase
8-bit clock phase value (None will use default)
compare phase shift to programmed (will not work if the program was restarted)
read and re-send status request to make sure status reflects new data (just for testing, too fast for Python)
@param quiet reduce output
Returns 1 if success, 0 if timeout (or no wait was performed)
"""
if phase is None:
phase= vrlg.get_default("DLY_PHASE")
vrlg.DLY_PHASE=phase & ((1< compare phase shift to programmed (will not work if the program was restarted)
read and re-send status request to make sure status reflects new data (just for testing, too fast for Python)
Returns 1 if success, 0 if timeout
"""
if vrlg.CLKFBOUT_USE_FINE_PS:
patt = 0x3000000 | ((-vrlg.DLY_PHASE) & 0xff)
else:
patt = 0x3000000 | vrlg.DLY_PHASE
mask = 0x3000100
if check_phase_value:
mask |= 0xff
return self.x393_axi_tasks.wait_status_condition(
vrlg.MCONTR_PHY_STATUS_REG_ADDR, # status_address,
vrlg.MCONTR_PHY_16BIT_ADDR + vrlg.MCONTR_PHY_STATUS_CNTRL, # status_control_address,
3, # status_mode,
patt, # pattern,
mask, # mask
0, # invert_match
wait_seq, # wait_seq;
1.0) # maximal timeout (0 - no timeout)
def get_target_phase(self):
"""
Returns previously set clock phase value
"""
return vrlg.DLY_PHASE
def axi_set_same_delays(self, #
dq_idelay, # input [7:0] dq_idelay;
dq_odelay, # input [7:0] dq_odelay;
dqs_idelay, # input [7:0] dqs_idelay;
dqs_odelay, # input [7:0] dqs_odelay;
dm_odelay, # input [7:0] dm_odelay;
cmda_odelay): # input [7:0] cmda_odelay;
"""
Set I/O delays for the DDR3 memory, same delay for all signals in the same class
Each delay value is 8-bit, 5 MSB program in equal steps (=360/32 degrees each),
and 3 LSB (valid values are 0..4) add additional non-calibrated 10ps delay
input delay for DQ lines
output delay for DQ lines
input delay for DQS lines
output delay for DQS lines
input delay for DM lines
output delay for DM lines
"""
if self.DEBUG_MODE > 1:
print("SET DELAYS(0x%x,0x%x,0x%x,0x%x,0x%x,0x%x)"%(dq_idelay,dq_odelay,dqs_idelay,dqs_odelay,dm_odelay,cmda_odelay))
self.axi_set_dq_idelay(dq_idelay)
self.axi_set_dq_odelay(dq_odelay)
self.axi_set_dqs_idelay(dqs_idelay)
self.axi_set_dqs_odelay(dqs_odelay)
self.axi_set_dm_odelay(dm_odelay)
self.axi_set_cmda_odelay(cmda_odelay)
def axi_set_dqs_idelay_wlv(self):
"""
Set DQS input delays to values defined for the write levelling mode (parameter-defined)
"""
self.axi_set_multiple_delays(vrlg.LD_DLY_LANE0_IDELAY, 8, 1, vrlg.DLY_LANE0_DQS_WLV_IDELAY, "DLY_LANE0_IDELAY")
self.axi_set_multiple_delays(vrlg.LD_DLY_LANE1_IDELAY, 8, 1, vrlg.DLY_LANE1_DQS_WLV_IDELAY, "DLY_LANE1_IDELAY")
# self.x393_axi_tasks.write_control_register(vrlg.LD_DLY_LANE0_IDELAY + 8, vrlg.DLY_LANE0_DQS_WLV_IDELAY)
# self.x393_axi_tasks.write_control_register(vrlg.LD_DLY_LANE1_IDELAY + 8, vrlg.DLY_LANE1_DQS_WLV_IDELAY)
self.x393_axi_tasks.write_control_register(vrlg.DLY_SET,0)
def axi_set_delays(self,quiet=1): # set all individual delays
"""
Set all DDR3 I/O delays to individual parameter-defined values (using default values,
current ones are supposed to be synchronized)
"""
self.axi_set_dq_idelay(quiet=quiet)
self.axi_set_dqs_idelay(quiet=quiet)
self.axi_set_dq_odelay(quiet=quiet)
self.axi_set_dqs_odelay(quiet=quiet)
self.axi_set_dm_odelay(quiet=quiet)
self.axi_set_cmda_odelay(quiet=quiet)
self.axi_set_phase(quiet=quiet)
def axi_set_dq_idelay(self, # sets same delay to all dq idelay
delay=None, # input [7:0] delay;
quiet=1):
"""
Set all DQ input delays to the same value
@param delay 8-bit (5+3) delay value to use or a tuple/list with a pair for (lane0, lane1)
Each of the two elements in the delay tuple/list may be a a common integer or a list/tuple itself
if delay is None will restore default values
Alternatively it can be a one-level list/tuple covering all (16) delays
@param quiet reduce output
"""
# print("====axi_set_dq_idelay %s"%str(delay))
if delay is None:
delay=[[],[]]
for i in range(8):
delay[0].append(vrlg.get_default_field("DLY_LANE0_IDELAY",i))
delay[1].append(vrlg.get_default_field("DLY_LANE1_IDELAY",i))
if isinstance(delay,(int,long)):
delay=(delay,delay)
elif len(delay) % 8 == 0 :
delay2=[]
for lane in range(len(delay)//8):
delay2.append(delay[8*lane:8*(lane+1)])
delay=delay2
if quiet < 2:
print("SET DQ IDELAY="+hexMultiple(delay)) # hexMultiple
self.axi_set_multiple_delays(vrlg.LD_DLY_LANE0_IDELAY, 0, 8, delay[0], "DLY_LANE0_IDELAY")
self.axi_set_multiple_delays(vrlg.LD_DLY_LANE1_IDELAY, 0, 8, delay[1], "DLY_LANE1_IDELAY")
self.x393_axi_tasks.write_control_register (vrlg.DLY_SET,0);# // set all delays
def axi_set_dq_odelay(self,
delay=None, # input [7:0] delay;
quiet=1):
"""
Set all DQ OUTput delays to the same value
@param delay 8-bit (5+3) delay value to use or a tuple/list with a pair for (lane0, lane1)
Each of the two elements in the delay tuple/list may be a a common integer or a list/tuple itself
if delay is None will restore default values
Alternatively it can be a one-level list/tuple covering all (16) delays
@param quiet reduce output
"""
if delay is None:
delay=[[],[]]
for i in range(8):
delay[0].append(vrlg.get_default_field("DLY_LANE0_ODELAY",i))
delay[1].append(vrlg.get_default_field("DLY_LANE1_ODELAY",i))
if isinstance(delay,(int,long)):
delay=(delay,delay)
elif len(delay) % 8 == 0 :
delay2=[]
for lane in range(len(delay)//8):
delay2.append(delay[8*lane:8*(lane+1)])
delay=delay2
if quiet < 2:
print("SET DQ ODELAY="+hexMultiple(delay)) # hexMultiple
self.axi_set_multiple_delays(vrlg.LD_DLY_LANE0_ODELAY, 0, 8, delay[0], "DLY_LANE0_ODELAY");
self.axi_set_multiple_delays(vrlg.LD_DLY_LANE1_ODELAY, 0, 8, delay[1], "DLY_LANE1_ODELAY");
self.x393_axi_tasks.write_control_register(vrlg.DLY_SET,0); # set all delays
def axi_set_dqs_idelay(self,
delay=None, # input [7:0] delay;
quiet=1):
"""
Set all DQs input delays to the same value
@param delay 8-bit (5+3) delay value to use or a tuple/list with a pair for (lane0, lane1)
if delay is None will restore default values
@param quiet reduce output
"""
if delay is None:
delay=(vrlg.get_default_field("DLY_LANE0_IDELAY",8),vrlg.get_default_field("DLY_LANE1_IDELAY",8))
if isinstance(delay,(int,long)):
delay=(delay,delay)
if quiet < 2:
print("SET DQS IDELAY="+hexMultiple(delay)) # hexMultiple
self.axi_set_multiple_delays(vrlg.LD_DLY_LANE0_IDELAY, 8, 1, delay[0], "DLY_LANE0_IDELAY")
self.axi_set_multiple_delays(vrlg.LD_DLY_LANE1_IDELAY, 8, 1, delay[1], "DLY_LANE1_IDELAY")
self.x393_axi_tasks.write_control_register(vrlg.DLY_SET,0); # set all delays
def axi_set_dqs_odelay(self,
delay=None, # input [7:0] delay;
quiet=1):
"""
Set all DQs OUTput delays to the same value
@param delay 8-bit (5+3) delay value to use or a tuple/list with a pair for (lane0, lane1)
if delay is None will restore default values
@param quiet reduce output
"""
if delay is None:
delay=(vrlg.get_default_field("DLY_LANE0_ODELAY",8),vrlg.get_default_field("DLY_LANE1_ODELAY",8))
if isinstance(delay,(int,long)):
delay=(delay,delay)
if quiet < 2:
print("SET DQS ODELAY="+hexMultiple(delay)) # hexMultiple
self.axi_set_multiple_delays(vrlg.LD_DLY_LANE0_ODELAY, 8, 1, delay[0], "DLY_LANE0_ODELAY")
self.axi_set_multiple_delays(vrlg.LD_DLY_LANE1_ODELAY, 8, 1, delay[1], "DLY_LANE1_ODELAY")
self.x393_axi_tasks.write_control_register(vrlg.DLY_SET,0); # set all delays
def axi_set_dm_odelay (self,
delay=None, # input [7:0] delay;
quiet=1):
"""
Set all DM output delays to the same value
@param delay 8-bit (5+3) delay value to use or a tuple/list with a pair for (lane0, lane1)
if delay is None will restore default values
@param quiet reduce output
"""
if delay is None:
delay=(vrlg.get_default_field("DLY_LANE0_ODELAY",9),vrlg.get_default_field("DLY_LANE1_ODELAY",9))
if isinstance(delay,(int,long)):
delay=(delay,delay)
if quiet < 2:
print("SET DQM IDELAY="+hexMultiple(delay)) # hexMultiple
self.axi_set_multiple_delays(vrlg.LD_DLY_LANE0_ODELAY, 9, 1, delay[0], "DLY_LANE0_ODELAY")
self.axi_set_multiple_delays(vrlg.LD_DLY_LANE1_ODELAY, 9, 1, delay[1], "DLY_LANE1_ODELAY")
self.x393_axi_tasks.write_control_register(vrlg.DLY_SET,0) # set all delays
def axi_set_cmda_odelay(self,
delay=None, # input [7:0] delay;
indx=None, # address index
quiet=1):
"""
Set all command/address output delays to the same value (or a list/tuple of the individual ones)
@param delay 8-bit (5+3) delay value to use or list/tuple containing individual values
List elements may be None, those values will not be overwritten
if delay is None will restore default values
@param indx if present, delay only applies to the specified index (delay should be int/long)
@param quiet reduce output
"""
if delay is None:
delay=[]
for i in range(0,32):
if (indx is None) or (i == indx) :
delay.append(vrlg.get_default_field("DLY_CMDA",i))
else:
delay.append(None)
if isinstance(delay,(int,long)):
delay=[delay]*32 # all address/commands
if not indx is None:
for i in range(len(delay)):
if (i != indx):
delay[i]=None
if quiet < 2:
print("SET COMMAND and ADDRESS ODELAY"+hexMultiple(delay))
self.axi_set_multiple_delays(vrlg.LD_DLY_CMDA, 0, 32, delay, "DLY_CMDA");
self.x393_axi_tasks.write_control_register(vrlg.DLY_SET,0) # set all delays
def axi_set_address_odelay(self,
delay=None, # input [7:0] delay;
indx=None, # address index
quiet=1):
"""
Set output delays for address lines only
@param delay 8-bit (5+3) delay value to use or list/tuple containing individual values
List elements may be None, those values will not be overwritten
if delay is None will restore default values
@param indx if present, delay only applies to the specified index (delay should be int/long)
@param quiet reduce output
"""
if delay is None:
delay=[]
for i in range(0,vrlg.ADDRESS_NUMBER):
if (indx is None) or (i == indx) :
delay.append(vrlg.get_default_field("DLY_CMDA",i))
else:
delay.append(None)
if isinstance(delay,(int,long)):
delay=[delay]*vrlg.ADDRESS_NUMBER
if not indx is None:
for i in range(len(delay)):
if (i != indx):
delay[i]=None
if quiet < 2:
print("SET ADDRESS ODELAY="+hexMultiple(delay))
self.axi_set_multiple_delays(vrlg.LD_DLY_CMDA, 0, 0, delay, "DLY_CMDA")
self.x393_axi_tasks.write_control_register(vrlg.DLY_SET,0) # set all delays
def axi_set_bank_odelay(self,
delay=None, # input [7:0] delay;
indx=None, # address index
quiet=1):
"""
Set output delays for bank lines only
@param delay 8-bit (5+3) delay value to use or list/tuple containing individual values
List elements may be None, those values will not be overwritten
if delay is None will restore default values
@param indx if present, delay only applies to the specified index (delay should be int/long)
@param quiet reduce output
"""
bank_offset=24
if delay is None:
delay=[]
for i in range(3):
if (indx is None) or (i == indx) :
delay.append(vrlg.get_default_field("DLY_CMDA",i+bank_offset))
else:
delay.append(None)
if isinstance(delay,(int,long)):
delay=[delay]*3
if not indx is None:
for i in range(len(delay)):
if (i != indx):
delay[i]=None
if quiet < 2:
print("SET BANK ODELAY="+hexMultiple(delay))
self.axi_set_multiple_delays(vrlg.LD_DLY_CMDA, bank_offset, 0,delay, "DLY_CMDA") # length will be determined by len(delay)
self.x393_axi_tasks.write_control_register(vrlg.DLY_SET,0) # set all delays
def axi_set_cmd_odelay(self,
delay=None, # input [7:0] delay;
indx=None, # address index
quiet=1):
"""
Set output delays for command lines only. command=(we,ras,cas,cke,odt)
@param delay 8-bit (5+3) delay value to use or list/tuple containing individual values
List elements may be None, those values will not be overwritten
if delay is None will restore default values
@param indx if present, delay only applies to the specified index (delay should be int/long)
@param quiet reduce output
"""
command_offset=24+3
if delay is None:
delay=[]
for i in range(5):
if (indx is None) or (i == indx) :
delay.append(vrlg.get_default_field("DLY_CMDA",i+command_offset))
else:
delay.append(None)
if isinstance(delay,(int,long)):
delay=[delay]*5
if not indx is None:
for i in range(len(delay)):
if (i != indx):
delay[i]=None
if quiet < 2:
print("SET COMMAND ODELAY="+hexMultiple(delay))
self.axi_set_multiple_delays(vrlg.LD_DLY_CMDA, command_offset, 0,delay, "DLY_CMDA") # length will be determined by len(delay)
self.x393_axi_tasks.write_control_register(vrlg.DLY_SET,0) # set all delays
def axi_set_multiple_delays(self,
reg_addr, #input [29:0] reg_addr;
offset, # add this offset to address
number, # input integer number;
delay, # input [7:0] delay;
vname): # Verilog parameter name (if None - do not update Verilog parameter value (it is already it)
"""
Set same delay to a range of I/O delay registers
control register address of the first register in the range
add this offset to address
number of registers to write
@param delay 8-bit (5+3) delay value to use or list/tuple containing individual values
List elements may be None, those values will not be overwritten
Verilog parameter name
"""
# print ("===axi_set_multiple_delays(0x%x,%d,%s"%(reg_addr,number,delay))
if delay is None: return # Do nothing, that's OK
if isinstance(delay,(int,long)):
delay=[delay]*number
if len(delay) < number:
delay= delay + [None]*(number-len(delay)) #
for i, d in enumerate(delay):
if not d is None:
self.x393_axi_tasks.write_control_register(reg_addr + (offset + i), d)
if vname:
vrlg.set_name_field(vname, offset + i, d)
def wait_phase_shifter_ready(self):
"""
Wait until clock phase shifter is ready
"""
data=self.x393_axi_tasks.read_status(vrlg.MCONTR_PHY_STATUS_REG_ADDR)
expected_phase = vrlg.DLY_PHASE
if (vrlg.CLKFBOUT_USE_FINE_PS):
expected_phase = (-expected_phase) & 0xff;
while (((data & vrlg.STATUS_PSHIFTER_RDY_MASK) == 0) or (((data ^ vrlg.DLY_PHASE) & 0xff) != 0)):
data=self.x393_axi_tasks.read_status(vrlg.MCONTR_PHY_STATUS_REG_ADDR)
if self.DRY_MODE: break
def axi_set_wbuf_delay(self,
delay=None): # input [3:0] delay;
"""
Set write to buffer latency
@param delay 4-bit write to buffer signal delay (in mclk clock cycles)
if delay is None will restore default values
"""
if delay is None:
delay= vrlg.get_default("DFLT_WBUF_DELAY")
vrlg.DFLT_WBUF_DELAY=delay
if self.DEBUG_MODE > 1:
print("SET WBUF DELAY=0x%x"%delay)
self.x393_axi_tasks.write_control_register(vrlg.MCONTR_PHY_16BIT_ADDR+vrlg.MCONTR_PHY_16BIT_WBUF_DELAY, delay & 0xf) # {28'h0, delay});
#set dq /dqs tristate on/off patterns
def axi_set_tristate_patterns(self,
strPattern=None):
"""
Set sequencer patterns for the tristate ON/OFF (defined by parameters)
- optional up to 4-letter pattern. Each letter is one of 3:
'E'- early, "N" - nominal and 'L' - late, first for DQ start,
second - for DQS start, then DQ end and DQS end. If no pattern
is provided, all will be set to Verilog parameter values (DQ*TRI_*),
if only 1 - it will be applied to all, if 2 - it will be
repeated twice, 3 will use the same value for DQS end as for DQS start
"""
modes={'E':0,'N':1,'L':2}
evNames=('DQ_FIRST', 'DQS_FIRST', 'DQ_LAST','DQS_LAST')
patVals={evNames[0]: (0x3,0x7,0xf), # DQ_FIRST: early, nominal, late
evNames[1]: (0x1,0x3,0x7), # DQS_FIRST: early, nominal, late
evNames[2]: (0xf,0xe,0xc), # DQ_LAST: early, nominal, late
evNames[3]: (0xe,0xc,0x8)} # DQS_LAST: early, nominal, late
if not strPattern:
delays=concat(((0,16), # {16'h0,
(vrlg.DQSTRI_LAST, getParWidth(vrlg.DQSTRI_LAST__TYPE)), # DQSTRI_LAST,
(vrlg.DQSTRI_FIRST,getParWidth(vrlg.DQSTRI_FIRST__TYPE)), # DQSTRI_FIRST,
(vrlg.DQTRI_LAST, getParWidth(vrlg.DQTRI_LAST__TYPE)), # DQTRI_LAST,
(vrlg.DQTRI_FIRST, getParWidth(vrlg.DQTRI_FIRST__TYPE))) # DQTRI_FIRST});
)[0]
else:
strPattern=strPattern.upper()
if len(strPattern) == 1:
strPattern*=4
elif len(strPattern) == 2:
strPattern*=2
elif len(strPattern) == 3:
strPattern+=strPattern[1]
strPattern=strPattern[:4]
vals={}
for i,n in enumerate(evNames):
try:
vals[n]=patVals[n][modes[strPattern[i]]]
except:
msg="axi_set_tristate_patterns(%s): Failed to determine delay mode for %s, got %s"%(strPattern,n,strPattern[i])
print (msg)
Exception(msg)
print ("axi_set_tristate_patterns(%s) : %s"%(strPattern,str(vals)))
delays=concat(((0,16), # {16'h0,
(vals['DQS_LAST'],4), # vrlg.DQSTRI_LAST, getParWidth(vrlg.DQSTRI_LAST__TYPE)), # DQSTRI_LAST,
(vals['DQS_FIRST'],4), # vrlg.DQSTRI_FIRST,getParWidth(vrlg.DQSTRI_FIRST__TYPE)), # DQSTRI_FIRST,
(vals['DQ_LAST'],4), # vrlg.DQTRI_LAST, getParWidth(vrlg.DQTRI_LAST__TYPE)), # DQTRI_LAST,
(vals['DQ_FIRST'],4)) # vrlg.DQTRI_FIRST, getParWidth(vrlg.DQTRI_FIRST__TYPE))) # DQTRI_FIRST});
)[0]
# may fail if some of the parameters used have undefined width
print("DQTRI_FIRST=%s, DQTRI_FIRST__TYPE=%s"%(str(vrlg.DQTRI_FIRST),str(vrlg.DQTRI_FIRST__TYPE)))
print("DQTRI_LAST=%s, DQTRI_LAST__TYPE=%s"%(str(vrlg.DQTRI_LAST),str(vrlg.DQTRI_LAST__TYPE)))
if self.DEBUG_MODE > 1:
print("SET TRISTATE PATTERNS, combined delays=%s"%str(delays))
print("SET TRISTATE PATTERNS, combined delays=0x%x"%delays)
self.x393_axi_tasks.write_control_register(vrlg.MCONTR_PHY_16BIT_ADDR +vrlg.MCONTR_PHY_16BIT_PATTERNS_TRI, delays) # DQSTRI_LAST, DQSTRI_FIRST, DQTRI_LAST, DQTRI_FIRST});
def axi_set_dqs_dqm_patterns(self,
dqs_patt=None,
dqm_patt=None,
quiet=1):
"""
Set sequencer patterns for the DQ lines ON/OFF (defined by parameters)
@param dqs_patt DQS toggle pattern (if None - use DFLT_DQS_PATTERN (currently 0xaa)
@param dm_patt DM pattern (if None - use DFLT_DQM_PATTERN (currently 0x00) should be 0 for now
@param quiet reduce output
"""
if dqs_patt is None:
dqs_patt=vrlg.DFLT_DQS_PATTERN
if dqm_patt is None:
dqm_patt=vrlg.DFLT_DQM_PATTERN
patt = (dqs_patt & 0xff) | ((dqm_patt & 0xff) << 8)
vrlg.dqs_dqm_patt=patt
if quiet < 2 :
print("axi_set_dqs_dqm_patterns(): SET DQS+DQM PATTERNS, patt= 0x%08x (TODO:reduce quiet threshold)"%patt)
# set patterns for DM (always 0) and DQS - always the same (may try different for write lev.)
self.x393_axi_tasks.write_control_register(vrlg.MCONTR_PHY_16BIT_ADDR + vrlg.MCONTR_PHY_16BIT_PATTERNS, patt) # 32'h0055);
def get_dqs_dqm_patterns(self):
#print ('vrlg.dqs_dqm_patt=',vrlg.dqs_dqm_patt)
try:
return (vrlg.dqs_dqm_patt & 0xff,(vrlg.dqs_dqm_patt >> 8) & 0xff)
except:
return None
def util_test4(self):
# print("vrlg.globals():")
# print(vrlg.globals())
# print("vrlg.__dict__")
# print(vrlg.__dict__)
print ("DLY_PHASE = 0x%x"%vrlg.DLY_PHASE)
for k,v in vrlg.__dict__.items():
print ("%s = %s"%(k,str(v)))