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
import x393_mcntrl_timing
import x393_mcntrl_buffers
import x393_mcntrl_tests
import x393_mcntrl_eyepatterns
import x393_mcntrl_adjust
import vrlg
__all__ = []
......@@ -325,8 +326,9 @@ USAGE
x393tasks= x393_axi_control_status.X393AxiControlStatus(verbose,args.simulated)
x393Pio= x393_pio_sequences.X393PIOSequences(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)
x393Eyepatterns= x393_mcntrl_eyepatterns.X393McntrlEyepattern(verbose,args.simulated)
x393Adjust= x393_mcntrl_adjust.X393McntrlAdjust(verbose,args.simulated)
'''
......@@ -350,6 +352,7 @@ USAGE
extractTasks(x393_mcntrl_timing.X393McntrlTiming,x393Timing)
extractTasks(x393_mcntrl_buffers.X393McntrlBuffers,x393Buffers)
extractTasks(x393_mcntrl_tests.X393McntrlTests,x393Tests)
extractTasks(x393_mcntrl_eyepatterns.X393McntrlEyepattern,x393Eyepatterns)
extractTasks(x393_mcntrl_adjust.X393McntrlAdjust,x393Adjust)
for cmdLine in commands:
......
......@@ -31,6 +31,7 @@ __status__ = "Development"
#import sys
#import x393_mem
#MCNTRL_TEST01_CHN4_STATUS_CNTRL=0
NUM_FINE_STEPS= 5
def hx(obj,length=None):
frmt="0x%x"
if (length):
......@@ -170,3 +171,79 @@ def smooth2d(arr2d):
smooth.append(row)
return smooth
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):
bDQ=None
break
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!
# dbg_errs[b]=abs(bestDiff)
if (errDQ is None) or (fullBitErr > errDQ):
errDQ= fullBitErr
# dbg_worstBit=b
someData=True
vDQ.append(bDQ)
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:
dqForDqs.append(vDQ)
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
from x393_pio_sequences import X393PIOSequences
from x393_mcntrl_timing import X393McntrlTiming
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 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 time import sleep
#from time import sleep
import vrlg
class X393McntrlTests(object):
DRY_MODE= True # True
......@@ -63,7 +63,7 @@ class X393McntrlTests(object):
self.x393_pio_sequences= X393PIOSequences(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_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
try:
self.verbose=vrlg.VERBOSE
......@@ -334,7 +334,7 @@ class X393McntrlTests(object):
256, # num,
0, # show_rslt,
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
for d in read16:
sum_read16+=d
......
......@@ -336,6 +336,7 @@ class X393McntrlTiming(object):
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=[]
......@@ -357,13 +358,16 @@ class X393McntrlTiming(object):
def axi_set_bank_odelay(self,
delay=None, # input [7:0] delay;
indx=None): # address index
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:
......@@ -379,20 +383,22 @@ class X393McntrlTiming(object):
for i in range(len(delay)):
if (i != indx):
delay[i]=None
if self.DEBUG_MODE > 1:
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_contol_register(vrlg.DLY_SET,0) # set all delays
def axi_set_cmd_odelay(self,
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)
@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:
......@@ -408,7 +414,7 @@ class X393McntrlTiming(object):
for i in range(len(delay)):
if (i != indx):
delay[i]=None
if self.DEBUG_MODE > 1:
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_contol_register(vrlg.DLY_SET,0) # set all delays
......
......@@ -783,6 +783,8 @@ class X393PIOSequences(object):
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
en_refresh=0,
ra=0, # used only for calibration of the address line output delay
ba=0,
verbose=0):
"""
Setup refresh sequence at parameter defined address in the sequencer memory
......@@ -794,7 +796,7 @@ class X393PIOSequences(object):
print("**** SET REFRESH: tRFC=%d, tREFI=%d"%(t_rfc,t_refi))
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
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)
cmd_addr += 1
# =50 tREFI=260 ns before next ACTIVATE or REFRESH, @2.5ns clock, @5ns cycle
......@@ -1058,8 +1060,20 @@ class X393PIOSequences(object):
print()
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,
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