Commit 7a0b9347 authored by Andrey Filippov's avatar Andrey Filippov

testing hardware, adding related code

parent e6bc87ee
......@@ -107,7 +107,7 @@
<link>
<name>vivado_logs/VivadoTimingReportImplemented.log</name>
<type>1</type>
<location>/home/andrey/git/x393/vivado_logs/VivadoTimingReportImplemented-20150314001725869.log</location>
<location>/home/andrey/git/x393/vivado_logs/VivadoTimingReportImplemented-20150316202414190.log</location>
</link>
<link>
<name>vivado_logs/VivadoTimingReportSynthesis.log</name>
......
com.elphel.store.context.VivadoTimingReportImplemented=VivadoTimingReportImplemented_132_rawfile<-@\#\#@->
eclipse.preferences.version=1
......@@ -81,6 +81,9 @@
input [29:0] address;
input [31:0] data;
begin
`ifdef DEBUG_WR_SINGLE
$display("axi_write_single_w %h:%h @ %t",address,data,$time);
`endif
axi_write_single ({address,2'b0},data);
end
endtask
......@@ -89,9 +92,6 @@
input [31:0] address;
input [31:0] data;
begin
`ifdef DEBUG_WR_SINGLE
$display("axi_write_single %h:%h @ %t",address,data,$time);
`endif
axi_write_addr_data(
GLOBAL_WRITE_ID, // id
// address << 2, // addr
......
......@@ -170,6 +170,7 @@ USAGE
''' % (program_shortdesc, __author__,str(__date__))
preDefines={}
preParameters={}
showResult=False
try:
# Setup argument parser
parser = ArgumentParser(description=program_license, formatter_class=RawDescriptionHelpFormatter,fromfile_prefix_chars='@')
......@@ -353,6 +354,9 @@ USAGE
line =""
while True:
line=raw_input('x393%s--> '%('','(simulated)')[args.simulated]).strip()
#remove comment from the input line
if line.find("#") > 0:
line=line[:line.find("#")]
lineList=line.split()
if not line:
print ('Use "quit" to exit, "help" - for help')
......@@ -365,7 +369,18 @@ USAGE
print ("Usage: %s %s"%(name,sFuncArgs))
print ('\n"parameters" and "defines" list known defined parameters and macros')
print ("args.exception=%d, QUIET=%d"%(args.exceptions,QUIET))
print ("Enter 'R' to toggle show/hide command results, now it is %s"%(("OFF","ON")[showResult]))
elif lineList[0].upper() == 'R':
if len(lineList)>1:
if (lineList[1].upper() == "ON") or (lineList[1].upper() == "1") or (lineList[1].upper() == "TRUE"):
showResult=True
elif (lineList[1].upper() == "OFF") or (lineList[1].upper() == "0") or (lineList[1].upper() == "FALSE"):
showResult=False
else:
print ("Unrecognized parameter %s for 'R' command"%lineList[1])
else:
showResult = not showResult
print ("Show results mode is now %s"%(("OFF","ON")[showResult]))
# elif (len(line) > len("help")) and (line[:len("help")]=='help'):
elif lineList[0] == 'help':
# helpFilter=line[len('help'):].strip()
......@@ -431,7 +446,8 @@ USAGE
else:
cmdLine=line.split()
rslt= execTask(cmdLine)
print (' Result: '+hx(rslt))
if showResult:
print (' Result: '+hx(rslt))
#http://stackoverflow.com/questions/11781265/python-using-getattr-to-call-function-with-variable-parameters
#*getattr(foo,bar)(*params)
return 0
......
......@@ -127,9 +127,9 @@ def hexMultiple(data):
subResult=[]
for subItem in item:
try:
rslt.append("0x%x"%subItem)
subResult.append("0x%x"%subItem)
except:
rslt.append(str(subItem))
subResult.append(str(subItem))
rslt.append(subResult)
else:
try:
......@@ -142,5 +142,31 @@ def hexMultiple(data):
rslt = "0x%x"%item
except:
rslt = str(item)
return rslt
\ No newline at end of file
return rslt
def checkIntArgs(names,var_dict):
for name in names:
try:
v=var_dict[name]
except:
raise Exception("ERROR: '%s' is not among %s"%(name,str(var_dict.keys())))
if not isinstance(v,int):
print ("Expected an integer for '%s', got '%s"%(name,v))
try:
d=int(v,16)
print ("Did you mean 0x%x ?"%d)
except:
pass
raise Exception("Not a number for '%s' : '%s'"%(name,v))
def smooth2d(arr2d):
smooth=[]
l=len(arr2d)-1
for i in range(l+1):
im=(0,i-1)[i>0]
ip=(l,i+1)[i<l]
row=[]
for j in range(len(arr2d[i])):
row.append(0.5*arr2d[i][j]+0.25*(arr2d[ip][j]+arr2d[im][j]))
smooth.append(row)
return smooth
\ No newline at end of file
......@@ -43,7 +43,7 @@ from x393_mcntrl_buffers import X393McntrlBuffers
#from verilog_utils import concat #, getParWidth
#from x393_axi_control_status import concat, bits
#from time import sleep
from verilog_utils import checkIntArgs,smooth2d
NUM_FINE_STEPS= 5
class X393McntrlAdjust(object):
......@@ -98,7 +98,7 @@ class X393McntrlAdjust(object):
if isinstance(dly,list) or isinstance(dly,tuple):
rslt=[]
for d in dly:
rslt.append(self.split_delay(d))
rslt.append(self.combine_delay(d))
return rslt
try:
return ((dly/NUM_FINE_STEPS)<<3)+(dly%NUM_FINE_STEPS)
......@@ -114,7 +114,31 @@ class X393McntrlAdjust(object):
"""
for w in buf:
if (w!=0xffffffff): return False
return True
return True
def missing_dqs(self,
rd_blk,
quiet=False):
"""
Suspect missing final DQS puls(es) during write if last written burst matches previous one
<rd_blk> - block of 32-bit data read from DDR3 device
<quiet> - no output
Returns True if missing DQS pulse is suspected
"""
if (not rd_blk) or (len(rd_blk) <8 ):
return False
for i in range(-4,0):
if rd_blk[i] != rd_blk[i-4]:
break
else:
if not quiet:
print ("End of the block repeats 2 last 8-bursts, insufficient number of trailing DQS pulses is suspected:")
print("\n%03x:"%(len(rd_blk)-8),end=" ")
for i in range(len(rd_blk)-8,len(rd_blk)):
print("%08x"%rd_blk[i],end=" ")
print("\n")
return True
return False
def convert_mem16_to_w32(self,mem16):
"""
......@@ -155,15 +179,18 @@ class X393McntrlAdjust(object):
def scan_dqs(self,
low_delay,
low_delay,
high_delay,
num ):
num=8,
quiet=2 ):
"""
Scan DQS input delay values using pattern read mode
<low_delay> low delay value
<high_delay> high delay value
<low_delay> low delay value (in 'hardware' format, sparse)
<high_delay> high delay value (in 'hardware' format, sparse)
<num> number of 64-bit words to process
<quiet> less output
"""
checkIntArgs(('low_delay','high_delay','num'),locals())
self.x393_pio_sequences.set_read_pattern(num+1) # do not use first/last pair of the 32 bit words
low = self.split_delay(low_delay)
high = self.split_delay(high_delay)
......@@ -171,10 +198,17 @@ class X393McntrlAdjust(object):
for dly in range (low, high+1):
enc_dly=self.combine_delay(dly)
self.x393_mcntrl_timing.axi_set_dqs_idelay(enc_dly)
buf= self.x393_pio_sequences.read_pattern(self,
buf= self.x393_pio_sequences.read_pattern(
(4*num+2), # num,
0, # show_rslt,
1) # Wait for operation to complete
if quiet <1:
hbuf=[]
for dd in buf:
hbuf.append(hex(dd))
print(hbuf)
# with "good" data each word in buf should be 0xff00ff00
if self.bad_data(buf):
results.append([])
else:
......@@ -187,46 +221,52 @@ class X393McntrlAdjust(object):
if (buf[w+2] & (1<<wb) != 0):
data[b]+=1
results.append(data)
print ("%3d (0x%02x): "%(dly,enc_dly),end="")
for i in range(32):
print("%5x"%data[i],end="")
print()
for index in range (len(results)):
dly=index+low
enc_dly=self.combine_delay(dly)
if (len (results[index])>0):
print ("%3d (0x%02x): "%(dly,enc_dly),end="")
for i in range(32):
print("%5x"%results[index][i],end="")
print()
print()
print()
print ("Delay",end=" ")
for i in range(16):
print ("Bit%dP"%i,end=" ")
for i in range(16):
print ("Bit%dM"%i,end=" ")
print()
for index in range (len(results)):
dly=index+low
enc_dly=self.combine_delay(dly)
if (len (results[index])>0):
print ("%d"%(dly),end=" ")
for i in range(32):
print("%d"%results[index][i],end=" ")
print()
if quiet < 2:
print ("%3d (0x%02x): "%(dly,enc_dly),end="")
for i in range(32):
print("%5x"%data[i],end="")
print()
if quiet<3:
for index in range (len(results)):
dly=index+low
enc_dly=self.combine_delay(dly)
if (len (results[index])>0):
print ("%3d (0x%02x): "%(dly,enc_dly),end="")
for i in range(32):
print("%5x"%results[index][i],end="")
print()
print()
if quiet < 4:
print()
print ("Delay",end=" ")
for i in range(16):
print ("Bit%dP"%i,end=" ")
for i in range(16):
print ("Bit%dM"%i,end=" ")
print()
for index in range (len(results)):
dly=index+low
enc_dly=self.combine_delay(dly)
if (len (results[index])>0):
print ("%d"%(dly),end=" ")
for i in range(32):
print("%d"%results[index][i],end=" ")
print()
return results
def scan_dq_idelay(self,
low_delay,
high_delay,
num ):
num=8,
quiet=2 ):
"""
Scan DQ input delay values using pattern read mode
<low_delay> low delay value
<high_delay> high delay value
<low_delay> low delay value (in 'hardware' format, sparse)
<high_delay> high delay value (in 'hardware' format, sparse)
<num> number of 64-bit words to process
<quiet> less output
"""
checkIntArgs(('low_delay','high_delay','num'),locals())
self.x393_pio_sequences.set_read_pattern(num+1) # do not use first/last pair of the 32 bit words
low = self.split_delay(low_delay)
high = self.split_delay(high_delay)
......@@ -234,97 +274,158 @@ class X393McntrlAdjust(object):
for dly in range (low, high+1):
enc_dly=self.combine_delay(dly)
self.x393_mcntrl_timing.axi_set_dq_idelay(enc_dly) # same value to all DQ lines
buf= self.x393_pio_sequences.read_pattern(self,
buf= self.x393_pio_sequences.read_pattern(
(4*num+2), # num,
0, # show_rslt,
1) # Wait for operation to complete
if not quiet:
hbuf=[]
for dd in buf:
hbuf.append(hex(dd))
print(hbuf)
# with "good" data each word in buf should be 0xff00ff00
if self.bad_data(buf):
results.append([])
else:
data=[0]*32 # for each bit - even, then for all - odd
for w in range (4*num):
lane=w%2
for w in range (4*num): # read 32-bit word number
lane=w%2 # even words - lane 0, odd - lane 1
for wb in range(32):
g=(wb/8)%2
b=wb%8+lane*8+16*g
if (buf[w+2] & (1<<wb) != 0):
if (buf[w+2] & (1<<wb) != 0):# buf[w+2] - skip first 2 words
data[b]+=1
results.append(data)
print ("%3d (0x%02x): "%(dly,enc_dly),end="")
for i in range(32):
print("%5x"%data[i],end="")
print()
for index in range (len(results)):
dly=index+low
enc_dly=self.combine_delay(dly)
if (len (results[index])>0):
print ("%3d (0x%02x): "%(dly,enc_dly),end="")
for i in range(32):
print("%5x"%results[index][i],end="")
print()
print()
print()
print ("Delay",end=" ")
for i in range(16):
print ("Bit%dP"%i,end=" ")
for i in range(16):
print ("Bit%dM"%i,end=" ")
print()
for index in range (len(results)):
dly=index+low
enc_dly=self.combine_delay(dly)
if (len (results[index])>0):
print ("%d"%(dly),end=" ")
for i in range(32):
print("%d"%results[index][i],end=" ")
print()
print()
#When all correct, data[:16] should be all 0, data[16:] - maximal, (with num=8 - 32)
if not quiet:
print ("%3d (0x%02x): "%(dly,enc_dly),end="")
for i in range(32):
print("%5x"%data[i],end="")
print()
if quiet <2:
for index in range (len(results)):
dly=index+low
enc_dly=self.combine_delay(dly)
if (len (results[index])>0):
print ("%3d (0x%02x): "%(dly,enc_dly),end="")
for i in range(32):
print("%5x"%results[index][i],end="")
print()
print()
if quiet <3:
print()
print ("Delay",end=" ")
for i in range(16):
print ("Bit%dP"%i,end=" ")
for i in range(16):
print ("Bit%dM"%i,end=" ")
print()
for index in range (len(results)):
dly=index+low
enc_dly=self.combine_delay(dly)
if (len (results[index])>0):
print ("%d"%(dly),end=" ")
for i in range(32):
print("%d"%results[index][i],end=" ")
print()
print()
return results
def adjust_dq_idelay(self,
low_delay,
high_delay,
num,
falling ): # 0 - use rising as delay increases, 1 - use falling
num=8,
falling=0, # 0 - use rising as delay increases, 1 - use falling
smooth=10,
quiet=2):
"""
Adjust individual per-line DQ delays using read pattern mode
<low_delay> low delay value
<high_delay> high delay value
DQS idelay(s) should be set 90-degrees from the final values
<low_delay> low delay value (in 'hardware' format, sparse)
<high_delay> high delay value (in 'hardware' format, sparse)
<num> number of 64-bit words to process
<falling> 0 - use rising edge as delay increases, 1 - use falling one
Returns: list of 16 per-line delay values
In 'falling' mode results are the longest DQ idelay
when bits switch from correct to incorrect,
In 'rising' mode (falling==0) - the shortest one
<smooth> number of times to run LPF
<quiet> less output
Returns: list of 16 per-line delay values (sequential, not 'hardware')
"""
checkIntArgs(('low_delay','high_delay','num'),locals())
low = self.split_delay(low_delay)
data_raw=self.scan_dq_idelay(low_delay,high_delay,num)
data_raw=self.scan_dq_idelay(low_delay,high_delay,num,quiet)
data=[]
delays=[]
for i,d in enumerate(data_raw):
if len(d)>0:
data.append(d)
delays.append(i+low)
print(delays)
if (quiet<2):
print(delays)
best_dlys=[0]*16
best_diffs=[num*8.0]*16
for i in range (1,len(data)-1):
centerRaw=num*2.0# center value
uncert=[] #"uncertanty of read for each bit and even/odd words. list of 32-element lists, each positive in the [0,1] interval
rate=[] # data change rate
lm1=len(data)-1
for i in range (0,len(data)):
im1=(0, i-1)[i>0]
ip1=(lm1,i+1)[i<lm1]
r_uncert=[]
r_rate=[]
for j in range (32):
d=0.5*data[i][j]+0.25*(data[ip1][j]+data[im1][j])
r=data[im1][j]-data[ip1][j]
if (j>=16):
r=-r
r_uncert.append(1.0-((d-centerRaw)/centerRaw)**2) #0 and max -> 0, center ->1.0
r_rate.append(r/(2.0*centerRaw))
uncert.append(r_uncert)
rate.append(r_rate)
# print ("%d %s"%(i,str(r_uncert)))
for _ in range(smooth):
uncert=smooth2d(uncert)
for _ in range(smooth):
rate= smooth2d(rate)
val=[] # list of 16-element rows of composite uncert*rate values, multiplied for odd/even values, hoping not to have
# any bumps causes by asymmetry 0->1 and 1-->0
for i in range (0,len(data)):
r_val=[]
for j in range(16):
sign=(-1,1)[rate[i][j]>0]
rr=rate[i][j]*rate[i][j+16]
# if falling:
# sign=-sign
if rr<0:
sign=0 # different slope direction - ignore
r_val.append(sign * rr * uncert[i][j] * uncert[i][j+16])
val.append(r_val)
best_dlys=[None]*16
best_diffs=[None]*16
for i in range (len(val)):
for j in range (16):
delta=abs(data[i][j] -data[i][j+16] + 0.5*(data[i-1][j] -data[i-1][j+16]+data[i+1][j] -data[i+1][j+16]))
sign=(data[i-1][j] -data[i-1][j+16]-data[i+1][j]+data[i+1][j+16])
if falling > 0: sign=-sign;
if (sign>0) and (delta < best_diffs[j]):
best_diffs[j]=delta
best_dlys[j]=delays[i]
v=val[i][j]
if falling:
v=-v
if (best_dlys[j] is None) or (v>best_diffs[j]):
best_dlys[j]= i+1
best_diffs[j]= v
if quiet <2:
for i in range (len(data)):
print("%d "%(i),end="")
for j in range (32):
print("%f "%uncert[i][j],end="")
for j in range (32):
print("%f "%rate[i][j],end="")
for j in range (16):
print("%f "%(val[i][j]),end="")
print()
for i in range (16):
print("%2d: %3d (0x%02x)"%(i,best_dlys[i],self.combine_delay(best_dlys[i])))
self.x393_mcntrl_timing.axi_set_dq_idelay((best_dlys[0:8],best_dlys[8:16]))
comb_delays=self.combine_delay(best_dlys)
self.x393_mcntrl_timing.axi_set_dq_idelay((comb_delays[0:8],comb_delays[8:16]))
return best_dlys
"""
for i in range (8):
axi_set_dly_single(1,i,combine_delay(best_dlys[i]))
for i in range (8):
axi_set_dly_single(3,i,combine_delay(best_dlys[i+8]))
"""
def corr_delays(self,
low, # absolute delay value of start scan
......@@ -439,7 +540,7 @@ class X393McntrlAdjust(object):
ext_low_index=0
ext_high_index=new_state_index+(new_state_index-last_initial_index)
if ext_high_index>=len(res_bits):
ext_high_index=res_bits-1
ext_high_index=len(res_bits)-1
if (verbose): print("ext_low_index=%d ext_high_index=%d"%(ext_low_index,ext_high_index))
bit_data=[]
for i in range(16):
......@@ -567,6 +668,10 @@ class X393McntrlAdjust(object):
<verbose>: verbose mode (more prints)
Returns list of calculated delay values
"""
checkIntArgs(('low_delay','high_delay'),locals())
brc=(5, # 3'h5, # bank
0x1234, # 15'h1234, # row address
0x100) # 10'h100 # column address
# global BASEADDR_PORT1_WR,VERBOSE;
# saved_verbose=VERBOSE;
......@@ -621,17 +726,17 @@ class X393McntrlAdjust(object):
#write blok buffer with 256x32bit data
self.x393_mcntrl_buffers.write_block_buf_chn(0,0,wdata); # fill block memory (channel, page, number)
self.x393_pio_sequences.set_write_block(
5, # 3'h5, # bank
0x1234, # 15'h1234, # row address
0x100 # 10'h100 # column address
)
self.x393_pio_sequences.set_write_block(*brc) #64 8-bursts, 1 extra DQ/DQS/ active cycle
self.x393_pio_sequences.set_read_block(*brc)
if (use_odelay==0) :
self.x393_pio_sequences.write_block(1) # Wait for operation to complete
if verbose: print("++++++++ block written once")
#now scanning - first DQS, then try with DQ (post-adjustment - best fit)
results = []
if verbose: print("******** use_odelay=%d use_dq=%d"%(use_odelay,use_dq))
alreadyWarned=False
for dly in range (low, high+1):
enc_dly=self.combine_delay(dly)
if (use_odelay!=0):
......@@ -650,13 +755,15 @@ class X393McntrlAdjust(object):
else:
if verbose: print("******** axi_set_dqs_idelay(0x%x)"%enc_dly)
self.x393_mcntrl_timing.axi_set_dqs_idelay(enc_dly)
buf32=self.x393_pio_sequences.read_block(self,
buf32=self.x393_pio_sequences.read_block(
256, # num,
0, # show_rslt,
1) # Wait for operation to complete
if self.bad_data(buf32):
results.append([])
else:
else:
# Warn about possible missing DQS pulses during writes
alreadyWarned |= self.missing_dqs(buf32, alreadyWarned)
read16=self.convert_w32_to_mem16(buf32) # 512x16 bit, same as DDR3 DQ over time
if verbose and (dly==low):
if (verbose and not adjust): print("buf32:")
......@@ -741,7 +848,10 @@ class X393McntrlAdjust(object):
print ("%d %.2f"%(dly,corr_dly),end=" ")
for t in range(8):
for i in range(16):
print("%.4f"%(results[dly][i][t]),end=" ")
try:
print("%.4f"%(results[dly][i][t]),end=" ") #IndexError: list index out of range
except:
print(".????",end="")
print()
print("\n\n\n========== Copy below to the spreadsheet, use columns from corr_delay ==========")
......@@ -756,7 +866,10 @@ class X393McntrlAdjust(object):
corr_dly=dly+corr_fine[dly%period]
print ("%d %.2f"%(dly,corr_dly),end=" ")
for t in range(8):
print("%.4f"%(res_avg[dly][t]),end=" ")
try:
print("%.4f"%(res_avg[dly][t]),end=" ")
except:
print(".????",end=" ")
print()
dly_corr=None
if adjust:
......@@ -806,8 +919,8 @@ class X393McntrlAdjust(object):
use_dq, # 0 - scan dqs, 1 - scan dq (common valuwe, post-adjustment)
use_odelay, # 0 - idelay, 1 - odelay
ends_dist, # do not process if one of the primary interval ends is within this from 0.0 or 1.0
min_diff,
verbose): # minimal difference between primary delay steps to process
min_diff, # minimal difference between primary delay steps to process
verbose):
"""
Scan delays using random data write+read
<low_delay> Low delay value to tru
......@@ -818,6 +931,7 @@ class X393McntrlAdjust(object):
<min_diff> minimal difference between primary delay steps to process
<verbose>: verbose mode (more prints)
"""
checkIntArgs(('low_delay','high_delay'),locals())
self.scan_or_adjust_delay_random(
low_delay,
high_delay,
......@@ -846,6 +960,7 @@ class X393McntrlAdjust(object):
<verbose>: verbose mode (more prints)
Returns list of delays
"""
checkIntArgs(('low_delay','high_delay'),locals())
return self.scan_or_adjust_delay_random(
low_delay,
high_delay,
......
......@@ -90,16 +90,21 @@ class X393McntrlBuffers(object):
<start_word_address> full register address in AXI space (in 32-bit words, not bytes)
<num_words_or_data_list> number of 32-bit words to generate/write or a list with integer data
"""
xor=0
if (isinstance (num_words_or_data_list,list) or isinstance (num_words_or_data_list,tuple)) and (len(num_words_or_data_list) == 2):
xor=num_words_or_data_list[1]
num_words_or_data_list=num_words_or_data_list[0]
if isinstance (num_words_or_data_list,int):
data=[]
for i in range(num_words_or_data_list):
data.append(i | (((i + 7) & 0xff) << 8) | (((i + 23) & 0xff) << 16) | (((i + 31) & 0xff) << 24))
data.append(xor ^(i | (((i + 7) & 0xff) << 8) | (((i + 23) & 0xff) << 16) | (((i + 31) & 0xff) << 24)))
else:
data=num_words_or_data_list
if self.verbose>0:
print("**** write_block_buf, start_word_address=0x%x, num+words=0x%x"%(start_word_address,len(data)))
for i,d in enumerate(data):
d= i | (((i + 7) & 0xff) << 8) | (((i + 23) & 0xff) << 16) | (((i + 31) & 0xff) << 24)
# d= i | (((i + 7) & 0xff) << 8) | (((i + 23) & 0xff) << 16) | (((i + 31) & 0xff) << 24)
if self.verbose>2:
print(" write_block_buf 0x%x:0x%x"%(start_word_address+i,d))
self.x393_mem.axi_write_single_w(start_word_address+i, d)
......@@ -131,6 +136,13 @@ class X393McntrlBuffers(object):
<page> 2-bit buffer page to write to
<num_words_or_data_list> number of 32-bit words to generate/write or a list with integer data
"""
print("===write_block_buf_chn() chn=0x%x, page=0x%x"%(chn,page), end=" ")
if isinstance (num_words_or_data_list,list):
try:
print("=== [0x%x,0x%x,0x%x,0x%x,0x%x,0x%x,0x%x,0x%x,...]"%tuple(num_words_or_data_list[:8]),end="")
except:
print("=== [%s]"%str(num_words_or_data_list))
print("===")
start_addr=-1
if chn==0:start_addr=self.MCONTR_BUF0_WR_ADDR + (page << 8)
elif chn==1:start_addr=self.MCONTR_BUF1_WR_ADDR + (page << 8)
......@@ -140,6 +152,7 @@ class X393McntrlBuffers(object):
else:
print("**** ERROR: Invalid channel for write buffer = %d"% chn)
start_addr = self.MCONTR_BUF0_WR_ADDR+ (page << 8)
self.write_block_buf (start_addr, num_words_or_data_list)
def read_block_buf(self,
......@@ -153,7 +166,7 @@ class X393McntrlBuffers(object):
<show_rslt> print buffer data read
"""
if self.verbose>0:
if (self.verbose>1) or show_rslt:
print("**** read_block_buf, start_word_address=0x%x, num_read=0x%x "%(start_word_address,num_read))
result=[]
for i in range(num_read): #for (i = 0; i < num_read; i = i + 16) begin
......
......@@ -37,6 +37,7 @@ from x393_axi_control_status import X393AxiControlStatus
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 verilog_utils import * # concat, bits
#from verilog_utils import hx, concat, bits, getParWidth
from verilog_utils import concat #, getParWidth
......@@ -59,6 +60,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.__dict__.update(VerilogParameters.__dict__["_VerilogParameters__shared_state"]) # Add verilog parameters to the class namespace
try:
self.verbose=self.VERBOSE
......@@ -245,11 +247,11 @@ class X393McntrlTests(object):
norm_dqs_odly=self.DLY_DQS_ODELAY
# Set special values for DQS idelay for write leveling
self.x393_pio_sequences.wait_ps_pio_done(self.DEFAULT_STATUS_MODE,1); # not no interrupt running cycle - delays are changed immediately
self.x393_mcntrl_timing.axi_set_dqs_idelay_wlv()
## self.x393_mcntrl_timing.axi_set_dqs_idelay_wlv()
# Set write buffer (from DDR3) WE signal delay for write leveling mode
self.x393_mcntrl_timing.axi_set_wbuf_delay(self.WBUF_DLY_WLV)
## self.x393_mcntrl_timing.axi_set_wbuf_delay(self.WBUF_DLY_WLV)
# TODO: Set configurable delay time instead of #80
self.x393_mcntrl_timing.axi_set_dqs_odelay(wlev_dqs_dly) # 'h80); # 'h80 - inverted, 'h60 - not - 'h80 will cause warnings during simulation
## self.x393_mcntrl_timing.axi_set_dqs_odelay(wlev_dqs_dly) # 'h80); # 'h80 - inverted, 'h60 - not - 'h80 will cause warnings during simulation
self.x393_pio_sequences.schedule_ps_pio (# schedule software-control memory operation (may need to check FIFO status first)
self.WRITELEV_OFFSET, # input [9:0] seq_addr; # sequence start address
0, # input [1:0] page; # buffer page number
......@@ -265,9 +267,9 @@ class X393McntrlTests(object):
rslt[i & 1]+=(buf[i] & 1) + ((buf[i] >> 8) & 1) + ((buf[i] >> 16) & 1) + ((buf[i] >> 24) & 1)
for i in range(2):
rslt[i]/=2*numBufWords
self.x393_mcntrl_timing.axi_set_dqs_idelay_nominal()
self.x393_mcntrl_timing.axi_set_dqs_odelay(norm_dqs_odly) # 'h78);
self.x393_mcntrl_timing.axi_set_wbuf_delay(self.WBUF_DLY_DFLT); #DFLT_WBUF_DELAY
## self.x393_mcntrl_timing.axi_set_dqs_idelay_nominal()
## self.x393_mcntrl_timing.axi_set_dqs_odelay(norm_dqs_odly) # 'h78);
## self.x393_mcntrl_timing.axi_set_wbuf_delay(self.WBUF_DLY_DFLT); #DFLT_WBUF_DELAY
return rslt
def test_read_pattern(self,
......@@ -290,11 +292,19 @@ class X393McntrlTests(object):
1, # show_rslt,
wait_complete) # # Wait for operation to complete
def test_write_block(self,
wait_complete): # Wait for operation to complete
dq_odelay=None,
dqs_odelay=None,
wait_complete=1): # Wait for operation to complete
"""
Test write block in PS PIO mode
<dq_odelay> set DQ output delays if provided ([] - skip, single number - both lanes, 2 element list - per/lane)
<dqs odelay> set DQS output delays if provided ([] - skip, single number - both lanes, 2 element list - per/lane)
<wait_complete> wait write block operation to complete (0 - may initiate multiple PS PIO operations)
"""
if (not dq_odelay is None) and (dq_odelay != []):
self.x393_mcntrl_timing.axi_set_dq_odelay(dq_odelay)
if (not dqs_odelay is None) and (dqs_odelay != []):
self.x393_mcntrl_timing.axi_set_dqs_odelay(dqs_odelay)
return self.x393_pio_sequences.write_block(wait_complete) # Wait for operation to complete
def test_read_block(self,
......@@ -312,10 +322,51 @@ class X393McntrlTests(object):
self.x393_mcntrl_timing.axi_set_dq_idelay(dq_idelay)
if (not dqs_idelay is None) and (dqs_idelay != []):
self.x393_mcntrl_timing.axi_set_dqs_idelay(dqs_idelay)
return self.x393_pio_sequences.read_block(self,
rd_buf = self.x393_pio_sequences.read_block(
256, # num,
1, # show_rslt,
0, # show_rslt,
wait_complete) # Wait for operation to complete
sum_rd_buf=0
for d in rd_buf:
sum_rd_buf+=d
print("read buffer: (0x%x):"%sum_rd_buf)
for i in range(len(rd_buf)):
if (i & 0xf) == 0:
print("\n%03x:"%i,end=" ")
print("%08x"%rd_buf[i],end=" ")
print("\n")
return rd_buf
def test_read_block16(self,
dq_idelay=None,
dqs_idelay=None,
wait_complete=1): # Wait for operation to complete
"""
Test read block in PS PIO mode, convert data to match DDR3 16-bit output words
<dq_idelay> set DQ input delays if provided ([] - skip, single number - both lanes, 2 element list - per/lane)
<dqs_idelay> set DQS input delays if provided ([] - skip, single number - both lanes, 2 element list - per/lane)
<wait_complete> wait read block operation to complete (0 - may initiate multiple PS PIO operations)
returns list of the read data
"""
if (not dq_idelay is None) and (dq_idelay != []):
self.x393_mcntrl_timing.axi_set_dq_idelay(dq_idelay)
if (not dqs_idelay is None) and (dqs_idelay != []):
self.x393_mcntrl_timing.axi_set_dqs_idelay(dqs_idelay)
rd_buf = self.x393_pio_sequences.read_block(
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
sum_read16=0
for d in read16:
sum_read16+=d
print("read16 (0x%x):"%sum_read16)
for i in range(len(read16)):
if (i & 0x1f) == 0:
print("\n%03x:"%i,end=" ")
print("%04x"%read16[i],end=" ")
print("\n")
return read16
def test_scanline_write(self, #
channel, # input [3:0] channel;
......
......@@ -177,6 +177,8 @@ class X393McntrlTiming(object):
<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
"""
# print("====axi_set_dq_idelay %s"%str(delay))
if delay is None: return # Do nothing, that's OK
if isinstance(delay,int):
delay=(delay,delay)
......@@ -321,6 +323,7 @@ class X393McntrlTiming(object):
<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
"""
# 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):
delay=(delay,)*number
......@@ -349,29 +352,81 @@ class X393McntrlTiming(object):
print("SET WBUF DELAY=0x%x"%delay)
self.x393_axi_tasks.write_contol_register(self.MCONTR_PHY_16BIT_ADDR+self.MCONTR_PHY_16BIT_WBUF_DELAY, delay & 0xf) # {28'h0, delay});
#set dq /dqs tristate on/off patterns
def axi_set_tristate_patterns(self):
def axi_set_tristate_patterns(self,
strPattern=None):
"""
Set sequencer patterns for the tristate ON/OFF (defined by parameters)
"""
<strPattern> - 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,
(self.DQSTRI_LAST, getParWidth(self.DQSTRI_LAST__TYPE)), # DQSTRI_LAST,
(self.DQSTRI_FIRST,getParWidth(self.DQSTRI_FIRST__TYPE)), # DQSTRI_FIRST,
(self.DQTRI_LAST, getParWidth(self.DQTRI_LAST__TYPE)), # DQTRI_LAST,
(self.DQTRI_FIRST, getParWidth(self.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), # self.DQSTRI_LAST, getParWidth(self.DQSTRI_LAST__TYPE)), # DQSTRI_LAST,
(vals['DQS_FIRST'],4), # self.DQSTRI_FIRST,getParWidth(self.DQSTRI_FIRST__TYPE)), # DQSTRI_FIRST,
(vals['DQ_LAST'],4), # self.DQTRI_LAST, getParWidth(self.DQTRI_LAST__TYPE)), # DQTRI_LAST,
(vals['DQ_FIRST'],4)) # self.DQTRI_FIRST, getParWidth(self.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(self.DQTRI_FIRST),str(self.DQTRI_FIRST__TYPE)))
print("DQTRI_LAST=%s, DQTRI_LAST__TYPE=%s"%(str(self.DQTRI_LAST),str(self.DQTRI_LAST__TYPE)))
delays=concat(((0,16), # {16'h0,
(self.DQSTRI_LAST, getParWidth(self.DQSTRI_LAST__TYPE)), # DQSTRI_LAST,
(self.DQSTRI_FIRST,getParWidth(self.DQSTRI_FIRST__TYPE)), # DQSTRI_FIRST,
(self.DQTRI_LAST, getParWidth(self.DQTRI_LAST__TYPE)), # DQTRI_LAST,
(self.DQTRI_FIRST, getParWidth(self.DQTRI_FIRST__TYPE))) # DQTRI_FIRST});
)[0]
# delays=concat(((0,16), # {16'h0,
# (self.DQSTRI_LAST, getParWidth(self.DQSTRI_LAST__TYPE)), # DQSTRI_LAST,
# (self.DQSTRI_FIRST,getParWidth(self.DQSTRI_FIRST__TYPE)), # DQSTRI_FIRST,
# (self.DQTRI_LAST, getParWidth(self.DQTRI_LAST__TYPE)), # DQTRI_LAST,
# (self.DQTRI_FIRST, getParWidth(self.DQTRI_FIRST__TYPE))) # DQTRI_FIRST});
# )[0]
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_contol_register(self.MCONTR_PHY_16BIT_ADDR +self.MCONTR_PHY_16BIT_PATTERNS_TRI, delays) # DQSTRI_LAST, DQSTRI_FIRST, DQTRI_LAST, DQTRI_FIRST});
def axi_set_dqs_dqm_patterns(self):
def axi_set_dqs_dqm_patterns(self,
patt=None):
"""
Set sequencer patterns for the DQ lines ON/OFF (defined by parameters)
<patt> DQS toggle pattern (if None - use MCONTR_PHY_16BIT_PATTERNS (currently 0x55)
"""
if patt is None:
patt=self.MCONTR_PHY_16BIT_PATTERNS
if self.DEBUG_MODE > 1:
print("SET DQS+DQM PATTERNS")
print("SET DQS+DQM PATTERNS, patt= 0x%x"%patt)
# set patterns for DM (always 0) and DQS - always the same (may try different for write lev.)
self.x393_axi_tasks.write_contol_register(self.MCONTR_PHY_16BIT_ADDR + self.MCONTR_PHY_16BIT_PATTERNS, 0x55) # 32'h0055);
self.x393_axi_tasks.write_contol_register(self.MCONTR_PHY_16BIT_ADDR + self.MCONTR_PHY_16BIT_PATTERNS, patt) # 32'h0055);
......@@ -150,12 +150,15 @@ class X393Mem(object):
'''
Read/write slave AXI using 32-bit word addresses (same as in Verilog code)
'''
def axi_write_single_w(self,addr,data):
def axi_write_single_w(self,addr,data,verbose=0):
"""
Write 32-bit word to the slave AXI address range, using 32-word address
<addr> - 32-bit word (register) address relative to the slave AXI memory region
<data> - 32-bit data to write
<verbose> print data being written (default: 0)
"""
if verbose:
print("axi_write_single_w(0x%x,0x%08x)"%(addr,data))
self.axi_write_single(addr<<2,data)
def axi_read_addr_w(self,addr):
......
......@@ -34,6 +34,7 @@ __status__ = "Development"
from import_verilog_parameters import VerilogParameters
from x393_mem import X393Mem
from x393_axi_control_status import X393AxiControlStatus
from x393_mcntrl_buffers import X393McntrlBuffers
#from verilog_utils import * # concat, bits
from verilog_utils import concat, bits
#from x393_axi_control_status import concat, bits
......@@ -50,6 +51,7 @@ class X393PIOSequences(object):
# self.vpars=VerilogParameters()
self.x393_mem=X393Mem(debug_mode,dry_mode)
self.x393_axi_tasks=X393AxiControlStatus(debug_mode,dry_mode)
self.x393_mcntrl_buffers= X393McntrlBuffers(debug_mode,dry_mode)
# print ("+++++++++++++++ self.__dict__ ++++++++++++++++++++++++++")
# print (self.__dict__)
# print ("+++++++++++++++ VerilogParameters.__dict__ ++++++++++++++++++++++++++")
......@@ -442,169 +444,184 @@ class X393PIOSequences(object):
def set_read_block(self, #
ba, # input [ 2:0] ba;
ra, # input [14:0] ra;
ca): #input [ 9:0] ca;
ca, #input [ 9:0] ca;
verbose=0):
"""
Setup read block sequence at parameter defined address in the sequencer memory
<ba> 3-bit memory bank address
<ra> 15-bit memory row address
<ca> 10-bit memory column address
<ba> 3-bit memory bank address
<ra> 15-bit memory row address
<ca> 10-bit memory column address
<verbose> print data being written (default: False)
"""
cmd_addr = self.MCONTR_CMD_WR_ADDR + self.READ_BLOCK_OFFSET
# activate
# addr bank RCW ODT CKE SEL DQEN DQSEN DQSTGL DCI B_WR B_RD NOP, B_RST
data=self.func_encode_cmd( ra, ba, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)
self.x393_mem.axi_write_single_w(cmd_addr, data)
self.x393_mem.axi_write_single_w(cmd_addr, data, verbose)
cmd_addr += 1
# see if pause is needed . See when buffer read should be started - maybe before WR command
# skip done bank ODT CKE SEL DQEN DQSEN DQSTGL DCI B_WR B_RD B_RST
data=self.func_encode_skip( 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)
self.x393_mem.axi_write_single_w(cmd_addr, data)
self.x393_mem.axi_write_single_w(cmd_addr, data, verbose)
cmd_addr+=1
# first read
# read
# addr bank RCW ODT CKE SEL DQEN DQSEN DQSTGL DCI B_WR B_RD NOP, B_RST
data=self.func_encode_cmd(ca&0x3ff, ba, 2, 0, 0, 1, 0, 0, 0, 1, 1, 0, 0, 0)
self.x393_mem.axi_write_single_w(cmd_addr, data)
self.x393_mem.axi_write_single_w(cmd_addr, data, verbose)
cmd_addr += 1
# nop
# skip done bank ODT CKE SEL DQEN DQSEN DQSTGL DCI B_WR B_RD B_RST
data=self.func_encode_skip( 0, 0, ba, 0, 0, 1, 0, 0, 0, 1, 1, 0, 0)
self.x393_mem.axi_write_single_w(cmd_addr, data)
self.x393_mem.axi_write_single_w(cmd_addr, data, verbose)
cmd_addr += 1
#repeat remaining reads
for i in range(1,64):
# read
# addr bank RCW ODT CKE SEL DQEN DQSEN DQSTGL DCI B_WR B_RD NOP, B_RST
data=self.func_encode_cmd((ca & 0x3ff)+(i<<3),ba, 2, 0, 0, 1, 0, 0, 0, 1, 1, 0, 1, 0)
self.x393_mem.axi_write_single_w(cmd_addr, data)
self.x393_mem.axi_write_single_w(cmd_addr, data, verbose)
cmd_addr += 1
# nop - all 3 below are the same? - just repeat?
# skip done bank ODT CKE SEL DQEN DQSEN DQSTGL DCI B_WR B_RD B_RST
data=self.func_encode_skip( 0, 0, ba, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0)
self.x393_mem.axi_write_single_w(cmd_addr, data)
self.x393_mem.axi_write_single_w(cmd_addr, data, verbose)
cmd_addr += 1
# nop
# skip done bank ODT CKE SEL DQEN DQSEN DQSTGL DCI B_WR B_RD B_RST
data=self.func_encode_skip( 0, 0, ba, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0)
self.x393_mem.axi_write_single_w(cmd_addr, data)
self.x393_mem.axi_write_single_w(cmd_addr, data, verbose)
cmd_addr += 1
# nop
# skip done bank ODT CKE SEL DQEN DQSEN DQSTGL DCI B_WR B_RD B_RST
data=self.func_encode_skip( 0, 0, ba, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0)
self.x393_mem.axi_write_single_w(cmd_addr, data)
self.x393_mem.axi_write_single_w(cmd_addr, data, verbose)
cmd_addr += 1
# tRTP = 4*tCK is already satisfied, no skip here
# precharge, end of a page (B_RST)
# addr bank RCW ODT CKE SEL DQEN DQSEN DQSTGL DCI B_WR B_RD NOP, B_RST
data=self.func_encode_cmd( ra, ba, 5, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1)
self.x393_mem.axi_write_single_w(cmd_addr, data)
self.x393_mem.axi_write_single_w(cmd_addr, data, verbose)
cmd_addr += 1
# skip done bank ODT CKE SEL DQEN DQSEN DQSTGL DCI B_WR B_RD B_RST
data=self.func_encode_skip( 2, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0)
self.x393_mem.axi_write_single_w(cmd_addr, data)
self.x393_mem.axi_write_single_w(cmd_addr, data, verbose)
cmd_addr += 1
# Turn off DCI, set DONE
# skip done bank ODT CKE SEL DQEN DQSEN DQSTGL DCI B_WR B_RD B_RST
data=self.func_encode_skip( 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)
self.x393_mem.axi_write_single_w(cmd_addr, data)
self.x393_mem.axi_write_single_w(cmd_addr, data, verbose)
cmd_addr += 1
def set_write_block(self, #):
def set_write_block(self,#):
ba, # input[2:0]ba;
ra, # input[14:0]ra;
ca): # input[9:0]ca;
ca, # input[9:0]ca;
num8=64,
extraTgl=1, #
verbose=0):
"""
Setup write block sequence at parameter defined address in the sequencer memory
<ba> 3-bit memory bank address
<ra> 15-bit memory row address
<ca> 10-bit memory column address
<ba> 3-bit memory bank address
<ra> 15-bit memory row address
<ca> 10-bit memory column address
<num8> - number of 8-bursts (default=64, should be >2)
<verbose> print data being written (default: False)
"""
print("===set_write_block ba=0x%x, ra=0x%x, ca=0x%x"%(ba,ra,ca))
cmd_addr = self.MCONTR_CMD_WR_ADDR + self.WRITE_BLOCK_OFFSET
# activate
# addr bank RCW ODT CKE SEL DQEN DQSEN DQSTGL DCI B_WR B_RD NOP, B_RST
data=self.func_encode_cmd( ra, ba, 4, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0)
self.x393_mem.axi_write_single_w(cmd_addr, data)
self.x393_mem.axi_write_single_w(cmd_addr, data, verbose)
cmd_addr += 1
# see if pause is needed . See when buffer read should be started - maybe before WR command
# skip done bank ODT CKE SEL DQEN DQSEN DQSTGL DCI B_WR B_RD B_RST
data=self.func_encode_skip( 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0) # tRCD - 2 read bufs
self.x393_mem.axi_write_single_w(cmd_addr, data)
self.x393_mem.axi_write_single_w(cmd_addr, data, verbose)
cmd_addr += 1
# first write, 3 rd_buf
# write
# addr bank RCW ODT CKE SEL DQEN DQSEN DQSTGL DCI B_WR B_RD NOP, B_RST
data=self.func_encode_cmd(ca&0x3ff, ba, 3, 1, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0) # B_RD moved 1 cycle earlier
self.x393_mem.axi_write_single_w(cmd_addr, data)
self.x393_mem.axi_write_single_w(cmd_addr, data, verbose)
cmd_addr += 1
# nop 4-th rd_buf
# skip done bank ODT CKE SEL DQEN DQSEN DQSTGL DCI B_WR B_RD B_RST
data=self.func_encode_skip( 0, 0, ba, 1, 0, 0, 1, 1, 0, 0, 0, 1, 0)
self.x393_mem.axi_write_single_w(cmd_addr, data)
self.x393_mem.axi_write_single_w(cmd_addr, data, verbose)
cmd_addr += 1
#repeat remaining writes
for i in range(1,62) : #(i = 1; i < 62; i = i + 1) begin
for i in range(1,num8-2): # 62) : #(i = 1; i < 62; i = i + 1) begin
# write
# addr bank RCW ODT CKE SEL DQEN DQSEN DQSTGL DCI B_WR B_RD NOP, B_RST
data=self.func_encode_cmd((ca&0x3ff)+(i<<3), ba, 3, 1, 0, 1, 1, 1, 1, 0, 0, 1, 1, 0)
self.x393_mem.axi_write_single_w(cmd_addr, data)
self.x393_mem.axi_write_single_w(cmd_addr, data, verbose)
cmd_addr += 1
# addr bank RCW ODT CKE SEL DQEN DQSEN DQSTGL DCI B_WR B_RD NOP, B_RST
data=self.func_encode_cmd((ca&0x3ff)+(62<<3), ba, 3, 1, 0, 1, 1, 1, 1, 0, 0, 1, 0, 0) # write w/o nop
self.x393_mem.axi_write_single_w(cmd_addr, data)
# data=self.func_encode_cmd((ca&0x3ff)+(62<<3), ba, 3, 1, 0, 1, 1, 1, 1, 0, 0, 1, 0, 0) # write w/o nop
data=self.func_encode_cmd((ca&0x3ff)+((num8-2)<<3), ba, 3, 1, 0, 1, 1, 1, 1, 0, 0, 1, 0, 0) # write w/o nop
self.x393_mem.axi_write_single_w(cmd_addr, data, verbose)
cmd_addr += 1
#nop
# skip done bank ODT CKE SEL DQEN DQSEN DQSTGL DCI B_WR B_RD B_RST
data=self.func_encode_skip( 0, 0, ba, 1, 0, 1, 1, 1, 1, 0, 0, 0, 0) # nop with buffer read off
self.x393_mem.axi_write_single_w(cmd_addr, data)
self.x393_mem.axi_write_single_w(cmd_addr, data, verbose)
cmd_addr += 1
# One last write pair w/o buffer
# addr bank RCW ODT CKE SEL DQEN DQSEN DQSTGL DCI B_WR B_RD NOP, B_RST
data=self.func_encode_cmd((ca&0x3ff)+(63<<3), ba, 3, 1, 0, 1, 1, 1, 1, 0, 0, 0, 1, 0) # write with nop
self.x393_mem.axi_write_single_w(cmd_addr, data)
# data=self.func_encode_cmd((ca&0x3ff)+(63<<3), ba, 3, 1, 0, 1, 1, 1, 1, 0, 0, 0, 1, 0) # write with nop
data=self.func_encode_cmd((ca&0x3ff)+((num8-1)<<3),ba, 3, 1, 0, 1, 1, 1, 1, 0, 0, 0, 1, 0) # write with nop
self.x393_mem.axi_write_single_w(cmd_addr, data, verbose)
cmd_addr += 1
# nop
# skip done bank ODT CKE SEL DQEN DQSEN DQSTGL DCI B_WR B_RD B_RST
data=self.func_encode_skip( 0, 0, ba, 1, 0, 0, 1, 1, 1, 0, 0, 0, 0)
self.x393_mem.axi_write_single_w(cmd_addr, data)
self.x393_mem.axi_write_single_w(cmd_addr, data, verbose)
cmd_addr += 1
# nop
# skip done bank ODT CKE SEL DQEN DQSEN DQSTGL DCI B_WR B_RD B_RST
data=self.func_encode_skip( 0, 0, ba, 1, 0, 0, 1, 1, 1, 0, 0, 0, 1) # removed B_RD 1 cycle earlier
self.x393_mem.axi_write_single_w(cmd_addr, data)
self.x393_mem.axi_write_single_w(cmd_addr, data, verbose)
cmd_addr += 1
# nop
# skip done bank ODT CKE SEL DQEN DQSEN DQSTGL DCI B_WR B_RD B_RST
data=self.func_encode_skip( 0, 0, ba, 1, 0, 0, 1, 1, 1, 0, 0, 0, 0)
self.x393_mem.axi_write_single_w(cmd_addr, data)
data=self.func_encode_skip( extraTgl, 0, ba, 1, 0, 0, 1, 1, 1, 0, 0, 0, 0)
self.x393_mem.axi_write_single_w(cmd_addr, data, verbose)
cmd_addr += 1
# ODT off, it has latency
# skip done bank ODT CKE SEL DQEN DQSEN DQSTGL DCI B_WR B_RD B_RST
data=self.func_encode_skip( 2, 0, ba, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)
self.x393_mem.axi_write_single_w(cmd_addr, data)
self.x393_mem.axi_write_single_w(cmd_addr, data, verbose)
cmd_addr += 1
# precharge, ODT off
# addr bank RCW ODT CKE SEL DQEN DQSEN DQSTGL DCI B_WR B_RD NOP, B_RST
data=self.func_encode_cmd( ra, ba, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)
self.x393_mem.axi_write_single_w(cmd_addr, data)
self.x393_mem.axi_write_single_w(cmd_addr, data, verbose)
cmd_addr += 1
# skip done bank ODT CKE SEL DQEN DQSEN DQSTGL DCI B_WR B_RD B_RST
data=self.func_encode_skip( 2, 0, ba, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)
self.x393_mem.axi_write_single_w(cmd_addr, data)
self.x393_mem.axi_write_single_w(cmd_addr, data, verbose)
cmd_addr += 1
# Finalize, set DONE
# skip done bank ODT CKE SEL DQEN DQSEN DQSTGL DCI B_WR B_RD B_RST
data=self.func_encode_skip( 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
self.x393_mem.axi_write_single_w(cmd_addr, data)
self.x393_mem.axi_write_single_w(cmd_addr, data, verbose)
cmd_addr += 1
# Set MR3, read nrep*8 words, save to buffer (port0). No ACTIVATE/PRECHARGE are needed/allowed
def set_read_pattern (self,
nrep): # input integer nrep;
nrep, # input integer nrep;
verbose=0):
"""
Setup read pattern sequence at parameter defined address in the sequencer memory
<nrep> number of times pattern burst is read
<nrep> number of times pattern burst is read
<verbose> print data being written (default: False)
"""
cmd_addr = self.MCONTR_CMD_WR_ADDR + self.READ_PATTERN_OFFSET
......@@ -617,80 +634,82 @@ class X393PIOSequences(object):
# Set pattern mode
# addr bank RCW ODT CKE SEL DQEN DQSEN DQSTGL DCI B_WR B_RD NOP, B_RST
data=self.func_encode_cmd(bits(mr3_patt,(14,0)), bits(mr3_patt,(17,15)), 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)
self.x393_mem.axi_write_single_w(cmd_addr, data)
self.x393_mem.axi_write_single_w(cmd_addr, data, verbose)
cmd_addr += 1
# skip done bank ODT CKE SEL DQEN DQSEN DQSTGL DCI B_WR B_RD B_RST
data=self.func_encode_skip( 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)# tMOD
self.x393_mem.axi_write_single_w(cmd_addr, data)
self.x393_mem.axi_write_single_w(cmd_addr, data, verbose)
cmd_addr += 1
# first read
#@ read
# addr bank RCW ODT CKE SEL DQEN DQSEN DQSTGL DCI B_WR B_RD NOP, B_RST
data=self.func_encode_cmd( 0, 0, 2, 0, 0, 1, 0, 0, 0, 1, 1, 0, 0, 0)
self.x393_mem.axi_write_single_w(cmd_addr, data)
self.x393_mem.axi_write_single_w(cmd_addr, data, verbose)
cmd_addr += 1
# nop (combine with previous?)
# skip done bank ODT CKE SEL DQEN DQSEN DQSTGL DCI B_WR B_RD B_RST
data=self.func_encode_skip( 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 1, 0, 0)
self.x393_mem.axi_write_single_w(cmd_addr, data)
self.x393_mem.axi_write_single_w(cmd_addr, data, verbose)
cmd_addr += 1
#repeat remaining reads
# for (i = 1; i < nrep; i = i + 1) begin
for _ in range(1,nrep):
# addr bank RCW ODT CKE SEL DQEN DQSEN DQSTGL DCI B_WR B_RD NOP, B_RST
data=self.func_encode_cmd( 0, 0, 2, 0, 0, 1, 0, 0, 0, 1, 1, 0, 1, 0)
self.x393_mem.axi_write_single_w(cmd_addr, data)
self.x393_mem.axi_write_single_w(cmd_addr, data, verbose)
cmd_addr += 1
# nop - all 3 below are the same? - just repeat?
# skip done bank ODT CKE SEL DQEN DQSEN DQSTGL DCI B_WR B_RD B_RST
data=self.func_encode_skip( 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0)
self.x393_mem.axi_write_single_w(cmd_addr, data)
self.x393_mem.axi_write_single_w(cmd_addr, data, verbose)
cmd_addr += 1
# nop
# skip done bank ODT CKE SEL DQEN DQSEN DQSTGL DCI B_WR B_RD B_RST
data=self.func_encode_skip( 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0)
self.x393_mem.axi_write_single_w(cmd_addr, data)
self.x393_mem.axi_write_single_w(cmd_addr, data, verbose)
cmd_addr += 1
# nop
# skip done bank ODT CKE SEL DQEN DQSEN DQSTGL DCI B_WR B_RD B_RST
data=self.func_encode_skip( 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0)
self.x393_mem.axi_write_single_w(cmd_addr, data)
self.x393_mem.axi_write_single_w(cmd_addr, data, verbose)
cmd_addr += 1
# nop, no write buffer - next page
# skip done bank ODT CKE SEL DQEN DQSEN DQSTGL DCI B_WR B_RD B_RST
data=self.func_encode_skip( 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 1)
self.x393_mem.axi_write_single_w(cmd_addr, data)
self.x393_mem.axi_write_single_w(cmd_addr, data, verbose)
cmd_addr += 1
# skip done bank ODT CKE SEL DQEN DQSEN DQSTGL DCI B_WR B_RD B_RST
data=self.func_encode_skip( 1, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0)
self.x393_mem.axi_write_single_w(cmd_addr, data)
self.x393_mem.axi_write_single_w(cmd_addr, data, verbose)
cmd_addr += 1
# Turn off read pattern mode
# addr bank RCW ODT CKE SEL DQEN DQSEN DQSTGL DCI B_WR B_RD NOP, B_RST
data=self.func_encode_cmd(bits(mr3_norm,(14,0)), bits(mr3_norm,(17,15)), 7, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0)
self.x393_mem.axi_write_single_w(cmd_addr, data)
self.x393_mem.axi_write_single_w(cmd_addr, data, verbose)
cmd_addr += 1
# tMOD (keep DCI enabled)
# skip done bank ODT CKE SEL DQEN DQSEN DQSTGL DCI B_WR B_RD B_RST
data=self.func_encode_skip( 5, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0)
self.x393_mem.axi_write_single_w(cmd_addr, data)
self.x393_mem.axi_write_single_w(cmd_addr, data, verbose)
cmd_addr += 1
# Turn off DCI
# skip done bank ODT CKE SEL DQEN DQSEN DQSTGL DCI B_WR B_RD B_RST
data=self.func_encode_skip( 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)
self.x393_mem.axi_write_single_w(cmd_addr, data)
self.x393_mem.axi_write_single_w(cmd_addr, data, verbose)
cmd_addr += 1
# Finalize (set DONE)
# skip done bank ODT CKE SEL DQEN DQSEN DQSTGL DCI B_WR B_RD B_RST
data=self.func_encode_skip( 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)
self.x393_mem.axi_write_single_w(cmd_addr, data)
self.x393_mem.axi_write_single_w(cmd_addr, data, verbose)
cmd_addr += 1
def set_write_lev(self,
nrep): #input[CMD_PAUSE_BITS-1:0]nrep;
nrep, #input[CMD_PAUSE_BITS-1:0]nrep;
verbose=0):
"""
Setup write levelling sequence at parameter defined address in the sequencer memory
<nrep> number of times write levelling burst is repeated
<nrep> number of times write levelling burst is repeated
<verbose> print data being written (default: False)
"""
dqs_low_rpt = 8
nrep_minus_1 = nrep - 1;
......@@ -714,72 +733,74 @@ class X393PIOSequences(object):
# Enter write leveling mode
# addr bank RCW ODT CKE SEL DQEN DQSEN DQSTGL DCI B_WR B_RD NOP, B_RST
data=self.func_encode_cmd(bits(mr1_wlev,(14,0)), bits(mr1_wlev,(17,15)), 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)
self.x393_mem.axi_write_single_w(cmd_addr, data)
self.x393_mem.axi_write_single_w(cmd_addr, data, verbose)
cmd_addr += 1
# skip done bank ODT CKE SEL DQEN DQSEN DQSTGL DCI B_WR B_RD B_RST
data=self.func_encode_skip( 13, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0) # tWLDQSEN=25tCK
self.x393_mem.axi_write_single_w(cmd_addr, data)
self.x393_mem.axi_write_single_w(cmd_addr, data, verbose)
cmd_addr += 1
# enable DQS output, keep it low (15 more tCK for the total of 40 tCK
# skip done bank ODT CKE SEL DQEN DQSEN DQSTGL DCI B_WR B_RD B_RST
data=self.func_encode_skip(dqs_low_rpt,0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0)
self.x393_mem.axi_write_single_w(cmd_addr, data)
self.x393_mem.axi_write_single_w(cmd_addr, data, verbose)
cmd_addr += 1
# Toggle DQS as needed for write leveling, write to buffer
# skip done bank ODT CKE SEL DQEN DQSEN DQSTGL DCI B_WR B_RD B_RST
data=self.func_encode_skip(nrep_minus_1,0, 0, 1, 0, 0, 0, 1, 1, 1, 1, 0, 0)
self.x393_mem.axi_write_single_w(cmd_addr, data)
self.x393_mem.axi_write_single_w(cmd_addr, data, verbose)
cmd_addr += 1
# continue toggling (5 times), but disable writing to buffer (used same wbuf latency as for read)
# skip done bank ODT CKE SEL DQEN DQSEN DQSTGL DCI B_WR B_RD B_RST
data=self.func_encode_skip( 4, 0, 0, 1, 0, 0, 0, 1, 1, 1, 0, 0, 0)
self.x393_mem.axi_write_single_w(cmd_addr, data)
self.x393_mem.axi_write_single_w(cmd_addr, data, verbose)
cmd_addr += 1
# Keep DCI (but not ODT) active ODT should be off befor MRS
# skip done bank ODT CKE SEL DQEN DQSEN DQSTGL DCI B_WR B_RD B_RST
data=self.func_encode_skip( 2, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0)
self.x393_mem.axi_write_single_w(cmd_addr, data)
self.x393_mem.axi_write_single_w(cmd_addr, data, verbose)
cmd_addr += 1
# exit write leveling mode, ODT off, DCI off
# addr bank RCW ODT CKE SEL DQEN DQSEN DQSTGL DCI B_WR B_RD NOP, B_RST
data=self.func_encode_cmd(bits(mr1_norm,(14,0)),bits(mr1_norm,(17,15)), 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)
self.x393_mem.axi_write_single_w(cmd_addr, data)
self.x393_mem.axi_write_single_w(cmd_addr, data, verbose)
cmd_addr += 1
# skip done bank ODT CKE SEL DQEN DQSEN DQSTGL DCI B_WR B_RD B_RST
data=self.func_encode_skip( 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0) # tMOD
self.x393_mem.axi_write_single_w(cmd_addr, data)
self.x393_mem.axi_write_single_w(cmd_addr, data, verbose)
cmd_addr += 1
# Finalize. See if DONE can be combined with B_RST, if not - insert earlier
# skip done bank ODT CKE SEL DQEN DQSEN DQSTGL DCI B_WR B_RD B_RST
data=self.func_encode_skip( 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1) # can DONE be combined with B_RST?
self.x393_mem.axi_write_single_w(cmd_addr, data)
self.x393_mem.axi_write_single_w(cmd_addr, data, verbose)
cmd_addr += 1
def set_refresh(self, #
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):
en_refresh=0,
verbose=0):
"""
Setup refresh sequence at parameter defined address in the sequencer memory
<t_rfc> tRFC =50 for tCK=2.5ns
<t_refi> tREFI 48/97 for hardware, 16 - for simulation
<en_refresh> enable refresh immediately
<verbose> print data being written (default: False)
"""
print("SET REFRESH: tRFC=%d, tREFI=%d"%(t_rfc,t_refi))
cmd_addr = self.MCONTR_CMD_WR_ADDR + self.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)
self.x393_mem.axi_write_single_w(cmd_addr, data)
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
# skip done bank ODT CKE SEL DQEN DQSEN DQSTGL DCI B_WR B_RD B_RST
data=self.func_encode_skip( t_rfc, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)
self.x393_mem.axi_write_single_w(cmd_addr, data)
self.x393_mem.axi_write_single_w(cmd_addr, data, verbose)
cmd_addr += 1
# Ready for normal operation
# skip done bank ODT CKE SEL DQEN DQSEN DQSTGL DCI B_WR B_RD B_RST
data=self.func_encode_skip( 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)
self.x393_mem.axi_write_single_w(cmd_addr, data)
self.x393_mem.axi_write_single_w(cmd_addr, data, verbose)
cmd_addr += 1
# write_contol_register(DLY_SET,0);
self.x393_axi_tasks.write_contol_register(self.MCONTR_TOP_16BIT_ADDR + self.MCONTR_TOP_16BIT_REFRESH_ADDRESS, self.REFRESH_OFFSET)
......@@ -790,10 +811,12 @@ class X393PIOSequences(object):
def set_mrs(self, # will also calibrate ZQ
reset_dll): # input reset_dll;
reset_dll, # input reset_dll;
verbose=0):
"""
Setup sequence (at paramter-defined adderss) to write MR0, MR1, MR2 and MR3 mode registers of DDR3 memory
<reset_dll> reset memory DLL when running this sequence
<verbose> print data being written (default: False)
"""
mr0 = self.func_ddr3_mr0(
0, # 1'h0, # pd; # precharge power down 0 - dll off (slow exit), 1 - dll on (fast exit)
......@@ -829,52 +852,52 @@ class X393PIOSequences(object):
print("mr3=0x%05x"%mr3);
# addr bank RCW ODT CKE SEL DQEN DQSEN DQSTGL DCI B_WR B_RD NOP, B_RST
data=self.func_encode_cmd(bits(mr2,(14,0)), bits(mr2,(17,15)), 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)
self.x393_mem.axi_write_single_w(cmd_addr, data)
self.x393_mem.axi_write_single_w(cmd_addr, data, verbose)
cmd_addr += 1
# skip done bank ODT CKE SEL DQEN DQSEN DQSTGL DCI B_WR B_RD B_RST
data=self.func_encode_skip( 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
self.x393_mem.axi_write_single_w(cmd_addr, data)
self.x393_mem.axi_write_single_w(cmd_addr, data, verbose)
cmd_addr += 1
# addr bank RCW ODT CKE SEL DQEN DQSEN DQSTGL DCI B_WR B_RD NOP, B_RST
data=self.func_encode_cmd(bits(mr3,(14,0)), bits(mr3,(17,15)), 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)
self.x393_mem.axi_write_single_w(cmd_addr, data)
self.x393_mem.axi_write_single_w(cmd_addr, data, verbose)
cmd_addr += 1
# skip done bank ODT CKE SEL DQEN DQSEN DQSTGL DCI B_WR B_RD B_RST
data=self.func_encode_skip( 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
self.x393_mem.axi_write_single_w(cmd_addr, data)
self.x393_mem.axi_write_single_w(cmd_addr, data, verbose)
cmd_addr += 1
# addr bank RCW ODT CKE SEL DQEN DQSEN DQSTGL DCI B_WR B_RD NOP, B_RST
data=self.func_encode_cmd(bits(mr1,(14,0)), bits(mr1,(17,15)), 7, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0) # SEL==1 - just testing?
self.x393_mem.axi_write_single_w(cmd_addr, data)
self.x393_mem.axi_write_single_w(cmd_addr, data, verbose)
cmd_addr += 1
# skip done bank ODT CKE SEL DQEN DQSEN DQSTGL DCI B_WR B_RD B_RST
data=self.func_encode_skip( 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
self.x393_mem.axi_write_single_w(cmd_addr, data)
self.x393_mem.axi_write_single_w(cmd_addr, data, verbose)
cmd_addr += 1
# addr bank RCW ODT CKE SEL DQEN DQSEN DQSTGL DCI B_WR B_RD NOP, B_RST
data=self.func_encode_cmd(bits(mr0,(14,0)), bits(mr0,(17,15)), 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)
self.x393_mem.axi_write_single_w(cmd_addr, data)
self.x393_mem.axi_write_single_w(cmd_addr, data, verbose)
cmd_addr += 1
# skip done bank ODT CKE SEL DQEN DQSEN DQSTGL DCI B_WR B_RD B_RST
data=self.func_encode_skip( 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
self.x393_mem.axi_write_single_w(cmd_addr, data)
self.x393_mem.axi_write_single_w(cmd_addr, data, verbose)
cmd_addr += 1
# encode ZQCL:
# addr bank RCW ODT CKE SEL DQEN DQSEN DQSTGL DCI B_WR B_RD NOP, B_RST
data=self.func_encode_cmd( 0x400, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
self.x393_mem.axi_write_single_w(cmd_addr, data)
self.x393_mem.axi_write_single_w(cmd_addr, data, verbose)
cmd_addr += 1
# 512 clock cycles after ZQCL
# skip done bank ODT CKE SEL DQEN DQSEN DQSTGL DCI B_WR B_RD B_RST
data=self.func_encode_skip( 256, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
self.x393_mem.axi_write_single_w(cmd_addr, data)
self.x393_mem.axi_write_single_w(cmd_addr, data, verbose)
cmd_addr += 1
# sequence done bit, skip length is ignored
# skip done bank ODT CKE SEL DQEN DQSEN DQSTGL DCI B_WR B_RD B_RST
data=self.func_encode_skip( 10, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
self.x393_mem.axi_write_single_w(cmd_addr, data)
self.x393_mem.axi_write_single_w(cmd_addr, data, verbose)
cmd_addr += 1
def read_pattern(self,
......@@ -889,13 +912,13 @@ class X393PIOSequences(object):
returns list of the read data
"""
self.x393_pio_sequences.schedule_ps_pio ( # schedule software-control memory operation (may need to check FIFO status first)
self.schedule_ps_pio ( # schedule software-control memory operation (may need to check FIFO status first)
self.READ_PATTERN_OFFSET, # input [9:0] seq_addr; # sequence start address
2, # 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.x393_pio_sequences.wait_ps_pio_done(self.DEFAULT_STATUS_MODE,1) # wait previous memory transaction finished before changing delays (effective immediately)
self.wait_ps_pio_done(self.DEFAULT_STATUS_MODE,1) # wait previous memory transaction finished before changing delays (effective immediately)
return self.x393_mcntrl_buffers.read_block_buf_chn (0, 2, num, show_rslt ) # chn=0, page=2, number of 32-bit words=num, show_rslt
def read_block(self,
......@@ -910,13 +933,13 @@ class X393PIOSequences(object):
returns list of the read data
"""
self.x393_pio_sequences.schedule_ps_pio ( # schedule software-control memory operation (may need to check FIFO status first)
self.schedule_ps_pio ( # schedule software-control memory operation (may need to check FIFO status first)
self.READ_BLOCK_OFFSET, # input [9:0] seq_addr; # sequence start address
3, # 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) # wait_complete; # Do not request a newe transaction from the scheduler until previous memory transaction is finished
self.x393_pio_sequences.wait_ps_pio_done(self.DEFAULT_STATUS_MODE,1); # wait previous memory transaction finished before changing delays (effective immediately)
self.wait_ps_pio_done(self.DEFAULT_STATUS_MODE,1); # wait previous memory transaction finished before changing delays (effective immediately)
return self.x393_mcntrl_buffers.read_block_buf_chn (0, 3, num, show_rslt ) # chn=0, page=3, number of 32-bit words=num, show_rslt
def write_block(self,
......@@ -926,11 +949,11 @@ class X393PIOSequences(object):
<wait_complete> wait write block operation to complete (0 - may initiate multiple PS PIO operations)
"""
# write_block_buf_chn; # fill block memory - already set in set_up task
self.x393_pio_sequences.schedule_ps_pio ( # schedule software-control memory operation (may need to check FIFO status first)
self.schedule_ps_pio ( # schedule software-control memory operation (may need to check FIFO status first)
self.WRITE_BLOCK_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)
1, # input chn; # channel buffer to use: 0 - memory read, 1 - memory write
wait_complete) # `PS_PIO_WAIT_COMPLETE )# wait_complete; # Do not request a newer transaction from the scheduler until previous memory transaction is finished
# temporary - for debugging:
# self.x393_pio_sequences.wait_ps_pio_done(self.DEFAULT_STATUS_MODE,1) # wait previous memory transaction finished before changing delays (effective immediately)
# self.wait_ps_pio_done(self.DEFAULT_STATUS_MODE,1) # wait previous memory transaction finished before changing delays (effective immediately)
[*]
[*] GTKWave Analyzer v3.3.64 (w)1999-2014 BSI
[*] Sat Mar 14 20:12:55 2015
[*] Tue Mar 17 07:18:15 2015
[*]
[dumpfile] "/home/andrey/git/x393/simulation/x393_testbench01-20150314012414854.lxt"
[dumpfile_mtime] "Sat Mar 14 07:40:45 2015"
[dumpfile] "/home/andrey/git/x393/simulation/x393_testbench01-20150316202414190.lxt"
[dumpfile_mtime] "Tue Mar 17 02:39:38 2015"
[dumpfile_size] 982556355
[savefile] "/home/andrey/git/x393/x393_testbench01.sav"
[timestart] 45034520
[timestart] 47475610
[size] 1823 1180
[pos] 2062 0
*-12.698502 45069640 157271875 157546875 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1
*-11.698502 47485628 157271875 157546875 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1
[treeopen] x393_testbench01.
[treeopen] x393_testbench01.x393_i.
[treeopen] x393_testbench01.x393_i.mcntrl393_i.
......@@ -37,12 +37,15 @@
[treeopen] x393_testbench01.x393_i.mcntrl393_i.memctrl16_i.mcontr_sequencer_i.phy_cmd_i.
[treeopen] x393_testbench01.x393_i.mcntrl393_i.memctrl16_i.mcontr_sequencer_i.phy_cmd_i.phy_top_i.
[treeopen] x393_testbench01.x393_i.mcntrl393_i.memctrl16_i.mcontr_sequencer_i.phy_cmd_i.phy_top_i.byte_lane0_i.
[treeopen] x393_testbench01.x393_i.mcntrl393_i.memctrl16_i.mcontr_sequencer_i.phy_cmd_i.phy_top_i.byte_lane0_i.dq_block[0].
[treeopen] x393_testbench01.x393_i.mcntrl393_i.memctrl16_i.mcontr_sequencer_i.phy_cmd_i.phy_top_i.byte_lane0_i.dq_block[1].
[treeopen] x393_testbench01.x393_i.mcntrl393_i.memctrl16_i.mcontr_sequencer_i.phy_cmd_i.phy_top_i.byte_lane0_i.dq_block[1].dq_i.
[treeopen] x393_testbench01.x393_i.mcntrl393_i.memctrl16_i.scheduler16_i.
[treeopen] x393_testbench01.x393_i.mcntrl393_i.memctrl16_i.status_router2_top_i.
[treeopen] x393_testbench01.x393_i.mcntrl393_test01_i.
[treeopen] x393_testbench01.x393_i.mcntrl393_test01_i.status_router4_i.
[sst_width] 423
[signals_width] 462
[sst_width] 264
[signals_width] 310
[sst_expanded] 1
[sst_vpaned_height] 631
@800200
......@@ -254,12 +257,47 @@ x393_testbench01.x393_i.mcntrl393_i.memctrl16_i.mcontr_sequencer_i.phy_cmd_i.phy
x393_testbench01.x393_i.mcntrl393_i.memctrl16_i.mcontr_sequencer_i.phy_cmd_i.phy_top_i.clk_div[0]
x393_testbench01.x393_i.mcntrl393_i.memctrl16_i.mcontr_sequencer_i.phy_cmd_i.phy_top_i.mclk[0]
x393_testbench01.x393_i.mcntrl393_i.memctrl16_i.mcontr_sequencer_i.phy_cmd_i.phy_top_i.byte_lane0_i.iclk[0]
@29
x393_testbench01.x393_i.mcntrl393_i.memctrl16_i.mcontr_sequencer_i.phy_cmd_i.phy_top_i.byte_lane1_i.iclk[0]
@1000200
-mem_clocks
@200
@800200
-write_delays
@22
x393_testbench01.x393_i.mcntrl393_i.memctrl16_i.mcontr_sequencer_i.phy_cmd_i.phy_top_i.byte_lane0_i.din[31:0]
x393_testbench01.x393_i.mcntrl393_i.memctrl16_i.mcontr_sequencer_i.phy_cmd_i.phy_top_i.byte_lane0_i.din_dqs[3:0]
@28
x393_testbench01.x393_i.mcntrl393_i.memctrl16_i.mcontr_sequencer_i.phy_cmd_i.phy_top_i.byte_lane0_i.dqs[0]
x393_testbench01.x393_i.mcntrl393_i.memctrl16_i.mcontr_sequencer_i.phy_cmd_i.phy_top_i.byte_lane0_i.ndqs[0]
@22
x393_testbench01.x393_i.mcntrl393_i.memctrl16_i.mcontr_sequencer_i.phy_cmd_i.phy_top_i.byte_lane0_i.dq[7:0]
x393_testbench01.x393_i.mcntrl393_i.memctrl16_i.mcontr_sequencer_i.phy_cmd_i.phy_top_i.byte_lane0_i.dq_block[0].dq_i.din[3:0]
x393_testbench01.x393_i.mcntrl393_i.memctrl16_i.mcontr_sequencer_i.phy_cmd_i.phy_top_i.byte_lane0_i.dq_block[1].dq_i.din[3:0]
@28
x393_testbench01.x393_i.mcntrl393_i.memctrl16_i.mcontr_sequencer_i.phy_cmd_i.phy_top_i.byte_lane0_i.dq_block[1].dq_i.d_ser[0]
x393_testbench01.x393_i.mcntrl393_i.memctrl16_i.mcontr_sequencer_i.phy_cmd_i.phy_top_i.byte_lane0_i.dq_block[0].dq_i.d_ser[0]
x393_testbench01.x393_i.mcntrl393_i.memctrl16_i.mcontr_sequencer_i.phy_cmd_i.phy_top_i.byte_lane0_i.dq_block[0].dq_i.dq_data_dly[0]
x393_testbench01.x393_i.mcntrl393_i.memctrl16_i.mcontr_sequencer_i.phy_cmd_i.phy_top_i.byte_lane0_i.dqs_i.d_ser[0]
x393_testbench01.x393_i.mcntrl393_i.memctrl16_i.mcontr_sequencer_i.phy_cmd_i.phy_top_i.byte_lane0_i.dqs_i.dqs_data_dly[0]
@1000200
-write_delays
@800200
-read_delays
@28
x393_testbench01.x393_i.mcntrl393_i.memctrl16_i.mcontr_sequencer_i.phy_cmd_i.phy_top_i.byte_lane0_i.dqs_i.dqs_di[0]
x393_testbench01.x393_i.mcntrl393_i.memctrl16_i.mcontr_sequencer_i.phy_cmd_i.phy_top_i.byte_lane0_i.dqs_i.dqs_received_dly[0]
@201
-
@28
x393_testbench01.x393_i.mcntrl393_i.memctrl16_i.mcontr_sequencer_i.phy_cmd_i.phy_top_i.byte_lane0_i.dq_block[0].dq_i.iclk[0]
x393_testbench01.x393_i.mcntrl393_i.memctrl16_i.mcontr_sequencer_i.phy_cmd_i.phy_top_i.byte_lane0_i.dq_block[0].dq_i.clk[0]
x393_testbench01.x393_i.mcntrl393_i.memctrl16_i.mcontr_sequencer_i.phy_cmd_i.phy_top_i.byte_lane0_i.dq_block[0].dq_i.clk_div[0]
x393_testbench01.x393_i.mcntrl393_i.memctrl16_i.mcontr_sequencer_i.phy_cmd_i.phy_top_i.byte_lane0_i.dq_block[0].dq_i.dq[0]
x393_testbench01.x393_i.mcntrl393_i.memctrl16_i.mcontr_sequencer_i.phy_cmd_i.phy_top_i.byte_lane0_i.dq_block[0].dq_i.dq_dly[0]
@22
x393_testbench01.x393_i.mcntrl393_i.memctrl16_i.mcontr_sequencer_i.phy_cmd_i.phy_top_i.byte_lane0_i.dq_block[0].dq_i.dout[3:0]
x393_testbench01.x393_i.mcntrl393_i.memctrl16_i.mcontr_sequencer_i.phy_cmd_i.phy_top_i.byte_lane0_i.dq_block[1].dq_i.dout[3:0]
@1000200
-read_delays
@c00200
-axi
@28
......@@ -934,7 +972,7 @@ x393_testbench01.x393_i.axibram_read_i.bram_ren[0]
-
@1401200
-axibram_read
@800200
@c00200
-refresh
@28
x393_testbench01.x393_i.mcntrl393_i.memctrl16_i.mcontr_sequencer_i.run_busy[0]
......@@ -961,7 +999,7 @@ x393_testbench01.x393_i.mcntrl393_i.memctrl16_i.ddr_refresh_i.refresh_period[7:0
x393_testbench01.x393_i.mcntrl393_i.memctrl16_i.ddr_refresh_i.rst[0]
x393_testbench01.x393_i.mcntrl393_i.memctrl16_i.ddr_refresh_i.set[0]
x393_testbench01.x393_i.mcntrl393_i.memctrl16_i.ddr_refresh_i.want[0]
@1000200
@1401200
-refresh
@800200
-DDR3
......
......@@ -27,7 +27,7 @@
`define SET_PER_PIN_DELAYS 1 // set individual (including per-DQ pin delays)
`define PS_PIO_WAIT_COMPLETE 0 // wait until PS PIO module finished transaction before starting a new one
// Disabled already passed test to speedup simulation
//`define TEST_WRITE_LEVELLING 1
`define TEST_WRITE_LEVELLING 1
`define TEST_READ_PATTERN 1
`define TEST_WRITE_BLOCK 1
`define TEST_READ_BLOCK 1
......
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