Commit 494d6c95 authored by Andrey Filippov's avatar Andrey Filippov

Implemented measurement/processing of address/bank lines output delays

parent c9bb19f1
This diff is collapsed.
...@@ -54,6 +54,7 @@ import x393_pio_sequences ...@@ -54,6 +54,7 @@ import x393_pio_sequences
import x393_mcntrl_timing import x393_mcntrl_timing
import x393_mcntrl_buffers import x393_mcntrl_buffers
import x393_mcntrl_tests import x393_mcntrl_tests
import x393_mcntrl_eyepatterns
import x393_mcntrl_adjust import x393_mcntrl_adjust
import vrlg import vrlg
__all__ = [] __all__ = []
...@@ -320,14 +321,15 @@ USAGE ...@@ -320,14 +321,15 @@ USAGE
print("vrlg.VERBOSE__RAW="+str(vrlg.VERBOSE__RAW)) print("vrlg.VERBOSE__RAW="+str(vrlg.VERBOSE__RAW))
x393mem= x393_mem.X393Mem(verbose,args.simulated) #add dry run parameter x393mem= x393_mem.X393Mem(verbose,args.simulated) #add dry run parameter
x393utils= x393_utils.X393Utils(verbose,args.simulated,args.localparams) x393utils= x393_utils.X393Utils(verbose,args.simulated,args.localparams)
x393tasks= x393_axi_control_status.X393AxiControlStatus(verbose,args.simulated) x393tasks= x393_axi_control_status.X393AxiControlStatus(verbose,args.simulated)
x393Pio= x393_pio_sequences.X393PIOSequences(verbose,args.simulated) x393Pio= x393_pio_sequences.X393PIOSequences(verbose,args.simulated)
x393Timing= x393_mcntrl_timing.X393McntrlTiming(verbose,args.simulated) x393Timing= x393_mcntrl_timing.X393McntrlTiming(verbose,args.simulated)
x393Buffers=x393_mcntrl_buffers.X393McntrlBuffers(verbose,args.simulated) x393Buffers= x393_mcntrl_buffers.X393McntrlBuffers(verbose,args.simulated)
x393Tests= x393_mcntrl_tests.X393McntrlTests(verbose,args.simulated) x393Tests= x393_mcntrl_tests.X393McntrlTests(verbose,args.simulated)
x393Adjust= x393_mcntrl_adjust.X393McntrlAdjust(verbose,args.simulated) x393Eyepatterns= x393_mcntrl_eyepatterns.X393McntrlEyepattern(verbose,args.simulated)
x393Adjust= x393_mcntrl_adjust.X393McntrlAdjust(verbose,args.simulated)
''' '''
print ("----------------------") print ("----------------------")
...@@ -350,6 +352,7 @@ USAGE ...@@ -350,6 +352,7 @@ USAGE
extractTasks(x393_mcntrl_timing.X393McntrlTiming,x393Timing) extractTasks(x393_mcntrl_timing.X393McntrlTiming,x393Timing)
extractTasks(x393_mcntrl_buffers.X393McntrlBuffers,x393Buffers) extractTasks(x393_mcntrl_buffers.X393McntrlBuffers,x393Buffers)
extractTasks(x393_mcntrl_tests.X393McntrlTests,x393Tests) extractTasks(x393_mcntrl_tests.X393McntrlTests,x393Tests)
extractTasks(x393_mcntrl_eyepatterns.X393McntrlEyepattern,x393Eyepatterns)
extractTasks(x393_mcntrl_adjust.X393McntrlAdjust,x393Adjust) extractTasks(x393_mcntrl_adjust.X393McntrlAdjust,x393Adjust)
for cmdLine in commands: for cmdLine in commands:
......
...@@ -31,6 +31,7 @@ __status__ = "Development" ...@@ -31,6 +31,7 @@ __status__ = "Development"
#import sys #import sys
#import x393_mem #import x393_mem
#MCNTRL_TEST01_CHN4_STATUS_CNTRL=0 #MCNTRL_TEST01_CHN4_STATUS_CNTRL=0
NUM_FINE_STEPS= 5
def hx(obj,length=None): def hx(obj,length=None):
frmt="0x%x" frmt="0x%x"
if (length): if (length):
...@@ -169,4 +170,80 @@ def smooth2d(arr2d): ...@@ -169,4 +170,80 @@ def smooth2d(arr2d):
row.append(0.5*arr2d[i][j]+0.25*(arr2d[ip][j]+arr2d[im][j])) row.append(0.5*arr2d[i][j]+0.25*(arr2d[ip][j]+arr2d[im][j]))
smooth.append(row) smooth.append(row)
return smooth return smooth
\ No newline at end of file def split_delay(dly):
"""
Convert hardware composite delay into continuous one
<dly> 8-bit (5+3) hardware delay value (or a list of delays)
Returns continuous delay value (or a list of delays)
"""
if isinstance(dly,list) or isinstance(dly,tuple):
rslt=[]
for d in dly:
rslt.append(split_delay(d))
return rslt
try:
if isinstance(dly,float):
dly=int(dly+0.5)
dly_int=dly>>3
dly_fine=dly & 0x7
if dly_fine > (NUM_FINE_STEPS-1):
dly_fine= NUM_FINE_STEPS-1
return dly_int*NUM_FINE_STEPS+dly_fine
except:
return None
def combine_delay(dly):
"""
Convert continuous delay value to the 5+3 bit encoded one
<dly> continuous (0..159) delay (or a list of delays)
Returns 8-bit (5+3) hardware delay value (or a list of delays)
"""
if isinstance(dly,list) or isinstance(dly,tuple):
rslt=[]
for d in dly:
rslt.append(combine_delay(d))
return rslt
try:
if isinstance(dly,float):
dly=int(dly+0.5)
return ((dly/NUM_FINE_STEPS)<<3)+(dly%NUM_FINE_STEPS)
except:
return None
def convert_mem16_to_w32(mem16):
"""
Convert a list of 16-bit memory words
into a list of 32-bit data as encoded in the buffer memory
Each 4 of the input words provide 2 of the output elements
<mem16> - a list of the memory data
Returns a list of 32-bit buffer data
"""
res32=[]
for i in range(0,len(mem16),4):
res32.append(((mem16[i+3] & 0xff) << 24) |
((mem16[i+2] & 0xff) << 16) |
((mem16[i+1] & 0xff) << 8) |
((mem16[i+0] & 0xff) << 0))
res32.append((((mem16[i+3]>>8) & 0xff) << 24) |
(((mem16[i+2]>>8) & 0xff) << 16) |
(((mem16[i+1]>>8) & 0xff) << 8) |
(((mem16[i+0]>>8) & 0xff) << 0))
return res32
def convert_w32_to_mem16(w32):
"""
Convert a list of 32-bit data as encoded in the buffer memory
into a list of 16-bit memory words (so each bit corresponds to DQ line
Each 2 of the input words provide 4 of the output elements
<w32> - a list of the 32-bit buffer data
Returns a list of 16-bit memory data
"""
mem16=[]
for i in range(0,len(w32),2):
mem16.append(((w32[i]>> 0) & 0xff) | (((w32[i+1] >> 0) & 0xff) << 8))
mem16.append(((w32[i]>> 8) & 0xff) | (((w32[i+1] >> 8) & 0xff) << 8))
mem16.append(((w32[i]>>16) & 0xff) | (((w32[i+1] >> 16) & 0xff) << 8))
mem16.append(((w32[i]>>24) & 0xff) | (((w32[i+1] >> 24) & 0xff) << 8))
return mem16
...@@ -1208,28 +1208,13 @@ class X393LMA(object): ...@@ -1208,28 +1208,13 @@ class X393LMA(object):
bDQ=None bDQ=None
break break
bDQ.append(bestDQ) #tuple(delay,signed error in ps) bDQ.append(bestDQ) #tuple(delay,signed error in ps)
"""
fullBitErr=bestDiff # +asym_err[b] #TODO: Restore the full error!
if (errDQ is None) or (abs(fullBitErr) > abs (errDQ)):
errDQ= fullBitErr
"""
fullBitErr=abs(bestDiff) +asym_err[b] #TODO: Restore the full error! fullBitErr=abs(bestDiff) +asym_err[b] #TODO: Restore the full error!
# dbg_errs[b]=abs(bestDiff)
if (errDQ is None) or (fullBitErr > errDQ): if (errDQ is None) or (fullBitErr > errDQ):
errDQ= fullBitErr errDQ= fullBitErr
# dbg_worstBit=b
someData=True someData=True
vDQ.append(bDQ) vDQ.append(bDQ)
vErr.append(errDQ) vErr.append(errDQ)
## if dbg_worstBit is None:
## vErr.append(None)
## else:
# vErr.append(asym_err[dbg_worstBit])
# vErr.append(10*dbg_worstBit)
# vErr.append(dbg_errs[2])
## vErr.append(dbg_errs[5])
# print ("enl=%d, dly=%d, err=%s"%(enl,dly,str(errDQ)))
if someData: if someData:
dqForDqs.append(vDQ) dqForDqs.append(vDQ)
maxErrDqs.append(vErr) maxErrDqs.append(vErr)
......
This source diff could not be displayed because it is too large. You can view the blob instead.
...@@ -38,12 +38,12 @@ import x393_axi_control_status ...@@ -38,12 +38,12 @@ import x393_axi_control_status
from x393_pio_sequences import X393PIOSequences from x393_pio_sequences import X393PIOSequences
from x393_mcntrl_timing import X393McntrlTiming from x393_mcntrl_timing import X393McntrlTiming
from x393_mcntrl_buffers import X393McntrlBuffers from x393_mcntrl_buffers import X393McntrlBuffers
from x393_mcntrl_adjust import X393McntrlAdjust #from x393_mcntrl_adjust import X393McntrlAdjust
#from verilog_utils import * # concat, bits #from verilog_utils import * # concat, bits
#from verilog_utils import hx, concat, bits, getParWidth #from verilog_utils import hx, concat, bits, getParWidth
from verilog_utils import concat #, getParWidth from verilog_utils import concat,convert_w32_to_mem16 #, getParWidth
#from x393_axi_control_status import concat, bits #from x393_axi_control_status import concat, bits
from time import sleep #from time import sleep
import vrlg import vrlg
class X393McntrlTests(object): class X393McntrlTests(object):
DRY_MODE= True # True DRY_MODE= True # True
...@@ -63,7 +63,7 @@ class X393McntrlTests(object): ...@@ -63,7 +63,7 @@ class X393McntrlTests(object):
self.x393_pio_sequences= X393PIOSequences(debug_mode,dry_mode) self.x393_pio_sequences= X393PIOSequences(debug_mode,dry_mode)
self.x393_mcntrl_timing= X393McntrlTiming(debug_mode,dry_mode) self.x393_mcntrl_timing= X393McntrlTiming(debug_mode,dry_mode)
self.x393_mcntrl_buffers= X393McntrlBuffers(debug_mode,dry_mode) self.x393_mcntrl_buffers= X393McntrlBuffers(debug_mode,dry_mode)
self.x393_mcntrl_adjust= X393McntrlAdjust(debug_mode,dry_mode) # self.x393_mcntrl_adjust= X393McntrlAdjust(debug_mode,dry_mode)
# self.__dict__.update(VerilogParameters.__dict__["_VerilogParameters__shared_state"]) # Add verilog parameters to the class namespace # self.__dict__.update(VerilogParameters.__dict__["_VerilogParameters__shared_state"]) # Add verilog parameters to the class namespace
try: try:
self.verbose=vrlg.VERBOSE self.verbose=vrlg.VERBOSE
...@@ -334,7 +334,7 @@ class X393McntrlTests(object): ...@@ -334,7 +334,7 @@ class X393McntrlTests(object):
256, # num, 256, # num,
0, # show_rslt, 0, # show_rslt,
wait_complete) # Wait for operation to complete wait_complete) # Wait for operation to complete
read16=self.x393_mcntrl_adjust.convert_w32_to_mem16(rd_buf) # 512x16 bit, same as DDR3 DQ over time read16=convert_w32_to_mem16(rd_buf) # 512x16 bit, same as DDR3 DQ over time
sum_read16=0 sum_read16=0
for d in read16: for d in read16:
sum_read16+=d sum_read16+=d
......
...@@ -336,6 +336,7 @@ class X393McntrlTiming(object): ...@@ -336,6 +336,7 @@ class X393McntrlTiming(object):
List elements may be None, those values will not be overwritten List elements may be None, those values will not be overwritten
if delay is None will restore default values 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 indx if present, delay only applies to the specified index (delay should be int/long)
@param quiet reduce output
""" """
if delay is None: if delay is None:
delay=[] delay=[]
...@@ -357,13 +358,16 @@ class X393McntrlTiming(object): ...@@ -357,13 +358,16 @@ class X393McntrlTiming(object):
def axi_set_bank_odelay(self, def axi_set_bank_odelay(self,
delay=None, # input [7:0] delay; delay=None, # input [7:0] delay;
indx=None): # address index indx=None, # address index
quiet=1):
""" """
Set output delays for bank lines only Set output delays for bank lines only
@param delay 8-bit (5+3) delay value to use or list/tuple containing individual values @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 List elements may be None, those values will not be overwritten
if delay is None will restore default values 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 indx if present, delay only applies to the specified index (delay should be int/long)
@param quiet reduce output
""" """
bank_offset=24 bank_offset=24
if delay is None: if delay is None:
...@@ -379,20 +383,22 @@ class X393McntrlTiming(object): ...@@ -379,20 +383,22 @@ class X393McntrlTiming(object):
for i in range(len(delay)): for i in range(len(delay)):
if (i != indx): if (i != indx):
delay[i]=None delay[i]=None
if self.DEBUG_MODE > 1: if quiet < 2:
print("SET BANK ODELAY="+hexMultiple(delay)) 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.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_contol_register(vrlg.DLY_SET,0) # set all delays self.x393_axi_tasks.write_contol_register(vrlg.DLY_SET,0) # set all delays
def axi_set_cmd_odelay(self, def axi_set_cmd_odelay(self,
delay=None, # input [7:0] delay; delay=None, # input [7:0] delay;
indx=None): # address index indx=None, # address index
quiet=1):
""" """
Set output delays for command lines only. command=(we,ras,cas,cke,odt) 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 @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 List elements may be None, those values will not be overwritten
if delay is None will restore default values 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 indx if present, delay only applies to the specified index (delay should be int/long)
@param quiet reduce output
""" """
command_offset=24+3 command_offset=24+3
if delay is None: if delay is None:
...@@ -408,7 +414,7 @@ class X393McntrlTiming(object): ...@@ -408,7 +414,7 @@ class X393McntrlTiming(object):
for i in range(len(delay)): for i in range(len(delay)):
if (i != indx): if (i != indx):
delay[i]=None delay[i]=None
if self.DEBUG_MODE > 1: if quiet < 2:
print("SET COMMAND ODELAY="+hexMultiple(delay)) 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.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_contol_register(vrlg.DLY_SET,0) # set all delays self.x393_axi_tasks.write_contol_register(vrlg.DLY_SET,0) # set all delays
......
...@@ -783,6 +783,8 @@ class X393PIOSequences(object): ...@@ -783,6 +783,8 @@ class X393PIOSequences(object):
t_rfc, # input[9:0]t_rfc; # =50 for tCK=2.5ns t_rfc, # input[9:0]t_rfc; # =50 for tCK=2.5ns
t_refi, # input[7:0]t_refi; # 48/97 for normal, 8 - for simulation t_refi, # input[7:0]t_refi; # 48/97 for normal, 8 - for simulation
en_refresh=0, en_refresh=0,
ra=0, # used only for calibration of the address line output delay
ba=0,
verbose=0): verbose=0):
""" """
Setup refresh sequence at parameter defined address in the sequencer memory Setup refresh sequence at parameter defined address in the sequencer memory
...@@ -794,7 +796,7 @@ class X393PIOSequences(object): ...@@ -794,7 +796,7 @@ class X393PIOSequences(object):
print("**** SET REFRESH: tRFC=%d, tREFI=%d"%(t_rfc,t_refi)) print("**** SET REFRESH: tRFC=%d, tREFI=%d"%(t_rfc,t_refi))
cmd_addr = vrlg.MCONTR_CMD_WR_ADDR + vrlg.REFRESH_OFFSET cmd_addr = vrlg.MCONTR_CMD_WR_ADDR + vrlg.REFRESH_OFFSET
# addr bank RCW ODT CKE SEL DQEN DQSEN DQSTGL DCI B_WR B_RD NOP, B_RST # addr bank RCW ODT CKE SEL DQEN DQSEN DQSTGL DCI B_WR B_RD NOP, B_RST
data=self.func_encode_cmd( 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0) data=self.func_encode_cmd( ra, ba, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)
self.x393_mem.axi_write_single_w(cmd_addr, data, verbose) self.x393_mem.axi_write_single_w(cmd_addr, data, verbose)
cmd_addr += 1 cmd_addr += 1
# =50 tREFI=260 ns before next ACTIVATE or REFRESH, @2.5ns clock, @5ns cycle # =50 tREFI=260 ns before next ACTIVATE or REFRESH, @2.5ns clock, @5ns cycle
...@@ -1058,8 +1060,20 @@ class X393PIOSequences(object): ...@@ -1058,8 +1060,20 @@ class X393PIOSequences(object):
print() print()
return data return data
def manual_refresh(self,
wait_complete=1): # Wait for operation to complete
"""
Run refresh cycle
<wait_complete> wait read pattern operation to complete (0 - may initiate multiple PS PIO operations)
"""
self.schedule_ps_pio ( # schedule software-control memory operation (may need to check FIFO status first)
vrlg.REFRESH_OFFSET, # input [9:0] seq_addr; # sequence start address
0, # input [1:0] page; # buffer page number
0, # input urgent; # high priority request (only for competion with other channels, will not pass in this FIFO)
0, # input chn; # channel buffer to use: 0 - memory read, 1 - memory write
wait_complete) # `PS_PIO_WAIT_COMPLETE ) # wait_complete; # Do not request a newe transaction from the scheduler until previous memory transaction is finished
self.wait_ps_pio_done(vrlg.DEFAULT_STATUS_MODE,1) # wait previous memory transaction finished before changing delays (effective immediately)
def restart_ddr3(self, def restart_ddr3(self,
wait_complete=True, wait_complete=True,
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment