Commit 92a49327 authored by Andrey Filippov's avatar Andrey Filippov

Continuing with the DDR configuration

parent d385610f
......@@ -55,9 +55,37 @@ class EzynqDDR:
def check_missing_features(self):
self.features.check_missing_features()
def html_list_features(self,html_file):
html_file.write('<h2>DDR memory configuration parameters</h2>\n')
self.features.html_list_features(html_file)
def calculate_dependent_pars(self):
#TODO: just testing on a few pars, migrate more of them
try:
tCK=1000.0/self.features.get_par_value('FREQ_MHZ')
try:
self.features.set_max_value('RP', int(math.ceil(self.features.get_par_value('T_RP')/tCK)))
except:
pass # get_par_value('T_RP') failed
try:
self.features.set_max_value('RCD', int(math.ceil(self.features.get_par_value('T_RCD')/tCK)))
except:
pass
try:
self.features.set_max_value('RRD', int(math.ceil(self.features.get_par_value('T_RRD')/tCK)))
except:
pass
except:
print "*** DDR Clock frequency is not defined"
# def set_max_value(self,name,value):
# def set_min_value(self,name,value):
# CONFIG_EZYNQ_DDR_T_RP = 13.1
# CONFIG_EZYNQ_DDR_T_RCD = 13.1
#CONFIG_EZYNQ_DDR_RRD = 4
#CONFIG_EZYNQ_DDR_T_RRD = 10.0
# def ddr_init_memory(self,current_reg_sets,force=False,warn=False,html_file, show_bit_fields=True, show_comments=True,filter_fields=True): # will program to sequence 'MAIN'
......@@ -218,19 +246,30 @@ class EzynqDDR:
('reg_ddrc_wr2rd', WR2RD), # 0xe
('reg_ddrc_rd2wr', RD2WR), # 0x7
('reg_ddrc_write_latency', write_latency)),force,warn) #5
# reg DRAM_param_reg3, 0x272872d0
ddrc_register_set.set_bitfields('dram_param_reg3',(('reg_ddrc_loopback', ?), #0
('reg_ddrc_dis_pad_pd', ?), #0
('reg_phy_mode_ddr1_ddr2', ?), #1
('reg_ddrc_read_latency', ?), #7
('reg_ddrc_en_dfi_dram_clk_disable', ?), #0
('reg_ddrc_mobile', ?), # 0
('reg_ddrc_sdram', ?), # 1
('reg_ddrc_refresh_to_x32', ?), # 8
('reg_ddrc_t_rp', ?), # 7
('reg_ddrc_refresh_margin', ?), # 2
('reg_ddrc_t_rrd', ?), # 6
('reg_ddrc_t_ccd', ?)),force,warn) #4
# reg DRAM_param_reg3, 0x270872d0 , 0x272872d0, 0x272872d0 (first time reg_ddrc_sdram is not set, the rest is the same)
enable_pad_powerdown= True # ?
mode_ddr1_ddr2= 1
en_dfi_dram_clk_disable = 0 # not clear - is it just enable for the action, or actually stopping the clock?
ddrc_refresh_to_x32= 8 # start refresh after this inactivity (x32 cycles) if it is useful, but not yet required. Dynamic field
RP= self.features.get_par_value('RP')
refresh_margin= 2 # default, recommended not to be changed
#CONFIG_EZYNQ_DDR_CCD = 4
#CONFIG_EZYNQ_DDR_RRD = 4
CCD= self.features.get_par_value('CCD')
RRD= self.features.get_par_value('RRD')
ddrc_register_set.set_bitfields('dram_param_reg3',(('reg_ddrc_loopback', 0), #0
('reg_ddrc_dis_pad_pd', (1,0)[enable_pad_powerdown]), #0
('reg_phy_mode_ddr1_ddr2', mode_ddr1_ddr2), #1
('reg_ddrc_read_latency', RL), #7
('reg_ddrc_en_dfi_dram_clk_disable',en_dfi_dram_clk_disable), #0
('reg_ddrc_mobile', (0,1)[is_LPDDR2]), # 0
('reg_ddrc_sdram', 1), # Shown reserved/default==0, but actually is set to 1 (2 and 3-rd time)
('reg_ddrc_refresh_to_x32', ddrc_refresh_to_x32), # 8
('reg_ddrc_t_rp', RP), # 7
('reg_ddrc_refresh_margin', refresh_margin), # 2
('reg_ddrc_t_rrd', RRD), # 6
('reg_ddrc_t_ccd', CCD-1)),force,warn) #4
# CONFIG_EZYNQ_DDR_XP = 4
# CONFIG_EZYNQ_DDR_RCD = 7 (was CONFIG_EZYNQ_DDR_T_RCD = 7) *
......
......@@ -111,15 +111,31 @@ DDR_CFG_DEFS=[
{'NAME':'XP', 'CONF_NAME':'CONFIG_EZYNQ_DDR_XP','TYPE':'I','MANDATORY':False,'DERIVED':False,'DEFAULT':4,
'DESCRIPTION':'Minimal Minimal time from power down (DLL on) to any operation (in tCK)'},
{'NAME':'T_DQSCK_MAX', 'CONF_NAME':'CONFIG_EZYNQ_DDR_T_DQSCK_MAX','TYPE':'F','MANDATORY':False,'DERIVED':False,'DEFAULT':7.5,
'DESCRIPTION':'DQS output access time from CK (ns). Used for LPDDR2 '},
'DESCRIPTION':'DQS output access time from CK (ns). Used for LPDDR2'},
{'NAME':'T_RP', 'CONF_NAME':'CONFIG_EZYNQ_DDR_T_RP','TYPE':'F','MANDATORY':False,'DERIVED':False,'DEFAULT':13.1,
'DESCRIPTION':'Precharge command period (ns). May be used to calculate CONFIG_EZYNQ_DDR_RP automatically'},
{'NAME':'T_RCD', 'CONF_NAME':'CONFIG_EZYNQ_DDR_T_RCD','TYPE':'F','MANDATORY':False,'DERIVED':False,'DEFAULT':13.1,
'DESCRIPTION':'Activate to internal Read or Write (ns). May be used to calculate CONFIG_EZYNQ_DDR_RCD automatically'},
{'NAME':'CCD', 'CONF_NAME':'CONFIG_EZYNQ_DDR_CCD','TYPE':'I','MANDATORY':False,'DERIVED':False,'DEFAULT':5,
'DESCRIPTION':'CAS-to-CAS command delay (in tCK)'},
{'NAME':'RRD', 'CONF_NAME':'CONFIG_EZYNQ_DDR_RRD','TYPE':'I','MANDATORY':False,'DERIVED':False,'DEFAULT':6,
'DESCRIPTION':'ACTIVATE-to-ACTIVATE minimal command period (in tCK)'},
{'NAME':'T_RRD', 'CONF_NAME':'CONFIG_EZYNQ_DDR_T_RRD','TYPE':'F','MANDATORY':False,'DERIVED':False,'DEFAULT':10.0,
'DESCRIPTION':'ACTIVATE-to-ACTIVATE minimal command period (ns). May be used to calculate CONFIG_EZYNQ_DDR_RRD automatically'},
# CONFIG_EZYNQ_DDR_RTP = 4
# CONFIG_EZYNQ_DDR_T_RTP = 7.5
# CONFIG_EZYNQ_DDR_WTR = 4
# CONFIG_EZYNQ_DDR_T_WTR = 7.5
# CONFIG_EZYNQ_DDR_XP = 4 # power down (DLL on) to any operation, cycles
# CONFIG_EZYNQ_DDR_T_DQSCK_MAX = 5.5 # (LPDDR2 only)
# CONFIG_EZYNQ_DDR_T_RP = 13.1
# CONFIG_EZYNQ_DDR_T_RCD = 13.1
# CONFIG_EZYNQ_DDR_CCD = 4
# CONFIG_EZYNQ_DDR_RRD = 4
# CONFIG_EZYNQ_DDR_T_RRD = 10.0
]
......
......@@ -75,7 +75,8 @@ class EzynqFeatures:
self.channel=channel
self.pars={}
self.config_names={}
self.defined=[]
self.defined=set()
self.calculated=set()
for name in self.defs:
cn=self.defs[name];
self.config_names[cn['CONF_NAME'].replace('@',str(channel))]=name
......@@ -128,7 +129,7 @@ class EzynqFeatures:
elif (feature['TYPE']=='T'):
pass #keep string value
self.pars[name]=value
self.defined.append(name)
self.defined.add(name)
#check after calculating derivative parameters
def check_missing_features(self):
all_set=True
......@@ -159,12 +160,48 @@ class EzynqFeatures:
try:
return self.pars[name]
except:
print 'name=',name
print self.pars
raise Exception (name+' not found in self.pars')
# print 'name=',name
# print self.pars
try:
config_name=self.defs[name]['CONF_NAME']
except:
raise Exception (name+' not found in self.defs') # should not happen with wrong data, program bug
raise Exception (config_name+' is not defined, nor calculated')
def is_known(self,name): # specified or calculated
return (name in self.defined) or (name in self.calculated)
def is_mandatory(self,name):
try:
return self.defs[name]['MANDATORY']
except:
raise Exception (name+' not found in self.defs') # should not happen with wrong data, program bug
def is_specified(self,name): # directly specified
return name in self.defined
def set_calculated_value(self,name,value,force=True):
if (not force) and (name in self.defined):
config_name=self.defs[name]['CONF_NAME']
raise Exception (name+' ('+config_name+') is specifically defined in configuration file, value will not change') # should not happen with wrong data, program bug
else:
self.pars[name]=value
self.calculated.add(name)
if name in self.defined:
self.defined.remove(name)
def set_max_value(self,name,value):
# print 'set_max_value (',name,',',value,')'
if (not self.is_known(name)) or (value>self.pars[name]):
self.set_calculated_value(name,value,True)
def set_min_value(self,name,value):
if (not self.is_known(name)) or (value<self.pars[name]):
self.set_calculated_value(name,value,True)
def html_list_features(self,html_file):
html_file.write('<table border="1">\n')
html_file.write('<tr><th>Configuration name</th><th>Value</th><th>Type/<br/>Choices</th><th>Mandatory</th><th>Derived</th><th>Default</th><th>Description</th></tr>\n')
html_file.write('<tr><th>Configuration name</th><th>Value</th><th>Type/<br/>Choices</th><th>Mandatory</th><th>Origin</th><th>Default</th><th>Description</th></tr>\n')
# print self.get_par_names()
# for name in self.pars:
for name in self.get_par_names():
......@@ -176,7 +213,13 @@ class EzynqFeatures:
value=hex(value)
else:
value=str(value)
derived= not name in self.defined
if name in self.defined:
origin="Defined"
elif name in self.calculated:
origin="Calculated"
else:
origin="Default"
if isinstance (feature['TYPE'],tuple):
par_type='<select>\n'
for t in feature['TYPE']:
......@@ -187,7 +230,7 @@ class EzynqFeatures:
par_type={'H':'Integer','I':'Integer','F':'Float','B':'Boolean','T':'Text'}[feature['TYPE']]
html_file.write('<tr><th>'+feature['CONF_NAME']+'</th><td>'+str(value)+'</td><td>'+par_type+
'</td><td>'+('-','Y')[feature['MANDATORY']]+'</td><td>'+('-','Y')[derived]+'</td><td>'+str(feature['DEFAULT'])+'</td><td>'+feature['DESCRIPTION']+'</td></tr>\n')
'</td><td>'+('-','Y')[feature['MANDATORY']]+'</td><td>'+origin+'</td><td>'+str(feature['DEFAULT'])+'</td><td>'+feature['DESCRIPTION']+'</td></tr>\n')
html_file.write('</table>\n')
\ No newline at end of file
......@@ -1001,7 +1001,7 @@ else:
f=False
#output_slcr_lock(registers,f,False,MIO_HTML_MASK) #prohibited by RBL
output_mio(registers,f,mio,MIO_HTML_MASK)
ddr.calculate_dependent_pars()
ddr.check_missing_features()
ddr.html_list_features(f)
#ddr.ddr_init_memory(current_reg_sets,force=False,warn=False): # will program to sequence 'MAIN'
......
......@@ -137,8 +137,22 @@ CONFIG_EZYNQ_DDR_CL = 7
CONFIG_EZYNQ_DDR_CWL = 6
#CONFIG_EZYNQ_DDR_T_RCD = 7
#CONFIG_EZYNQ_DDR_T_RP = 7
CONFIG_EZYNQ_DDR_RCD = 7
CONFIG_EZYNQ_DDR_RP = 7
#testing calculation of derivative parameters
#CONFIG_EZYNQ_DDR_RCD = 7
#CONFIG_EZYNQ_DDR_RP = 7
CONFIG_EZYNQ_DDR_T_RP = 13.1
CONFIG_EZYNQ_DDR_T_RCD = 13.1
CONFIG_EZYNQ_DDR_CCD = 5 # 4 in Micron specs
#will use max of two
CONFIG_EZYNQ_DDR_RRD = 6 # 4 in Micron specs
CONFIG_EZYNQ_DDR_T_RRD = 10.0
CONFIG_EZYNQ_DDR_T_RC = 48.75
CONFIG_EZYNQ_DDR_T_RAS_MIN = 35.0
CONFIG_EZYNQ_DDR_T_FAW = 40.0
......
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