# SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause """ SDRAM header file generator Process the handoff files from Quartus and convert them to headers usable by U-Boot. Copyright (C) 2022 Intel Corporation Author: Lee, Kah Jing """ import os import re import xml.dom.minidom import streamer import xmlgrok class EMIFGrokker(object): """ parse an emif.xml input and translate to various outputs """ SCRIPT_DIR = os.path.dirname(os.path.realpath(__file__)) TEMPLATE_DIR = os.path.dirname(SCRIPT_DIR) + '/src' SDRAM_FILE_HEADER = '/*\n' + ' * Altera SoCFPGA SDRAM configuration\n' + ' *\n' + ' */\n\n' SDRAM_SENTINEL = '__SOCFPGA_SDRAM_CONFIG_H__' SDRAM_MATCH = r'#define (CONFIG_HPS_SDR_CTRLCFG_CTRLCFG_MEMTYPE|CONFIG_HPS_SDR_CTRLCFG_CTRLCFG_MEMBL|CONFIG_HPS_SDR_CTRLCFG_CTRLCFG_ADDRORDER|CONFIG_HPS_SDR_CTRLCFG_CTRLCFG_ECCEN|CONFIG_HPS_SDR_CTRLCFG_CTRLCFG_ECCCORREN|CONFIG_HPS_SDR_CTRLCFG_CTRLCFG_REORDEREN|CONFIG_HPS_SDR_CTRLCFG_CTRLCFG_STARVELIMIT|CONFIG_HPS_SDR_CTRLCFG_CTRLCFG_DQSTRKEN|CONFIG_HPS_SDR_CTRLCFG_CTRLCFG_NODMPINS|CONFIG_HPS_SDR_CTRLCFG_DRAMTIMING1_TCWL|CONFIG_HPS_SDR_CTRLCFG_DRAMTIMING1_AL|CONFIG_HPS_SDR_CTRLCFG_DRAMTIMING1_TCL|CONFIG_HPS_SDR_CTRLCFG_DRAMTIMING1_TRRD|CONFIG_HPS_SDR_CTRLCFG_DRAMTIMING1_TFAW|CONFIG_HPS_SDR_CTRLCFG_DRAMTIMING1_TRFC|CONFIG_HPS_SDR_CTRLCFG_DRAMTIMING2_IF_TREFI|CONFIG_HPS_SDR_CTRLCFG_DRAMTIMING2_IF_TRCD|CONFIG_HPS_SDR_CTRLCFG_DRAMTIMING2_IF_TRP|CONFIG_HPS_SDR_CTRLCFG_DRAMTIMING2_IF_TWR|CONFIG_HPS_SDR_CTRLCFG_DRAMTIMING2_IF_TWTR|CONFIG_HPS_SDR_CTRLCFG_DRAMTIMING3_TRTP|CONFIG_HPS_SDR_CTRLCFG_DRAMTIMING3_TRAS|CONFIG_HPS_SDR_CTRLCFG_DRAMTIMING3_TRC|CONFIG_HPS_SDR_CTRLCFG_DRAMTIMING3_TMRD|CONFIG_HPS_SDR_CTRLCFG_DRAMTIMING3_TCCD|CONFIG_HPS_SDR_CTRLCFG_DRAMTIMING4_SELFRFSHEXIT|CONFIG_HPS_SDR_CTRLCFG_DRAMTIMING4_PWRDOWNEXIT|CONFIG_HPS_SDR_CTRLCFG_LOWPWRTIMING_AUTOPDCYCLES|CONFIG_HPS_SDR_CTRLCFG_LOWPWRTIMING_CLKDISABLECYCLES|CONFIG_HPS_SDR_CTRLCFG_DRAMODT_READ|CONFIG_HPS_SDR_CTRLCFG_DRAMODT_WRITE|CONFIG_HPS_SDR_CTRLCFG_DRAMADDRW_COLBITS|CONFIG_HPS_SDR_CTRLCFG_DRAMADDRW_ROWBITS|CONFIG_HPS_SDR_CTRLCFG_DRAMADDRW_BANKBITS|CONFIG_HPS_SDR_CTRLCFG_DRAMADDRW_CSBITS|CONFIG_HPS_SDR_CTRLCFG_DRAMIFWIDTH_IFWIDTH|CONFIG_HPS_SDR_CTRLCFG_DRAMDEVWIDTH_DEVWIDTH|CONFIG_HPS_SDR_CTRLCFG_DRAMINTR_INTREN|CONFIG_HPS_SDR_CTRLCFG_LOWPWREQ_SELFRFSHMASK|CONFIG_HPS_SDR_CTRLCFG_STATICCFG_MEMBL|CONFIG_HPS_SDR_CTRLCFG_STATICCFG_USEECCASDATA|CONFIG_HPS_SDR_CTRLCFG_CTRLWIDTH_CTRLWIDTH|CONFIG_HPS_SDR_CTRLCFG_CPORTWIDTH_CPORTWIDTH|CONFIG_HPS_SDR_CTRLCFG_CPORTWMAP_CPORTWMAP|CONFIG_HPS_SDR_CTRLCFG_CPORTRMAP_CPORTRMAP|CONFIG_HPS_SDR_CTRLCFG_RFIFOCMAP_RFIFOCMAP|CONFIG_HPS_SDR_CTRLCFG_WFIFOCMAP_WFIFOCMAP|CONFIG_HPS_SDR_CTRLCFG_CPORTRDWR_CPORTRDWR|CONFIG_HPS_SDR_CTRLCFG_PORTCFG_AUTOPCHEN|CONFIG_HPS_SDR_CTRLCFG_FPGAPORTRST|CONFIG_HPS_SDR_CTRLCFG_FIFOCFG_SYNCMODE|CONFIG_HPS_SDR_CTRLCFG_FIFOCFG_INCSYNC|CONFIG_HPS_SDR_CTRLCFG_MPPRIORITY_USERPRIORITY|CONFIG_HPS_SDR_CTRLCFG_MPWIEIGHT_0_STATICWEIGHT_31_0|CONFIG_HPS_SDR_CTRLCFG_MPWIEIGHT_1_STATICWEIGHT_49_32|CONFIG_HPS_SDR_CTRLCFG_MPWIEIGHT_1_SUMOFWEIGHT_13_0|CONFIG_HPS_SDR_CTRLCFG_MPWIEIGHT_2_SUMOFWEIGHT_45_14|CONFIG_HPS_SDR_CTRLCFG_MPWIEIGHT_3_SUMOFWEIGHT_63_46|CONFIG_HPS_SDR_CTRLCFG_PHYCTRL_PHYCTRL_0|CONFIG_HPS_SDR_CTRLCFG_MPPACING_0_THRESHOLD1_31_0|CONFIG_HPS_SDR_CTRLCFG_MPPACING_1_THRESHOLD1_59_32|CONFIG_HPS_SDR_CTRLCFG_MPPACING_1_THRESHOLD2_3_0|CONFIG_HPS_SDR_CTRLCFG_MPPACING_2_THRESHOLD2_35_4|CONFIG_HPS_SDR_CTRLCFG_MPPACING_3_THRESHOLD2_59_36|CONFIG_HPS_SDR_CTRLCFG_MPTHRESHOLDRST_0_THRESHOLDRSTCYCLES_31_0|CONFIG_HPS_SDR_CTRLCFG_MPTHRESHOLDRST_1_THRESHOLDRSTCYCLES_63_32|CONFIG_HPS_SDR_CTRLCFG_MPTHRESHOLDRST_2_THRESHOLDRSTCYCLES_79_64|RW_MGR_ACTIVATE_0_AND_1|RW_MGR_ACTIVATE_0_AND_1_WAIT1|RW_MGR_ACTIVATE_0_AND_1_WAIT2|RW_MGR_ACTIVATE_1|RW_MGR_CLEAR_DQS_ENABLE|RW_MGR_EMR_OCD_ENABLE|RW_MGR_EMR|RW_MGR_EMR2|RW_MGR_EMR3|RW_MGR_GUARANTEED_READ|RW_MGR_GUARANTEED_READ_CONT|RW_MGR_GUARANTEED_WRITE|RW_MGR_GUARANTEED_WRITE_WAIT0|RW_MGR_GUARANTEED_WRITE_WAIT1|RW_MGR_GUARANTEED_WRITE_WAIT2|RW_MGR_GUARANTEED_WRITE_WAIT3|RW_MGR_IDLE|RW_MGR_IDLE_LOOP1|RW_MGR_IDLE_LOOP2|RW_MGR_INIT_RESET_0_CKE_0|RW_MGR_INIT_RESET_1_CKE_0|RW_MGR_INIT_CKE_0|RW_MGR_LFSR_WR_RD_BANK_0|RW_MGR_LFSR_WR_RD_BANK_0_DATA|RW_MGR_LFSR_WR_RD_BANK_0_DQS|RW_MGR_LFSR_WR_RD_BANK_0_NOP|RW_MGR_LFSR_WR_RD_BANK_0_WAIT|RW_MGR_LFSR_WR_RD_BANK_0_WL_1|RW_MGR_LFSR_WR_RD_DM_BANK_0|RW_MGR_LFSR_WR_RD_DM_BANK_0_DATA|RW_MGR_LFSR_WR_RD_DM_BANK_0_DQS|RW_MGR_LFSR_WR_RD_DM_BANK_0_NOP|RW_MGR_LFSR_WR_RD_DM_BANK_0_WAIT|RW_MGR_LFSR_WR_RD_DM_BANK_0_WL_1|RW_MGR_MR_CALIB|RW_MGR_MR_USER|RW_MGR_MR_DLL_RESET|RW_MGR_MRS0_DLL_RESET|RW_MGR_MRS0_DLL_RESET_MIRR|RW_MGR_MRS0_USER|RW_MGR_MRS0_USER_MIRR|RW_MGR_MRS1|RW_MGR_MRS1_MIRR|RW_MGR_MRS2|RW_MGR_MRS2_MIRR|RW_MGR_MRS3|RW_MGR_MRS3_MIRR|RW_MGR_NOP|RW_MGR_PRECHARGE_ALL|RW_MGR_READ_B2B|RW_MGR_READ_B2B_WAIT1|RW_MGR_READ_B2B_WAIT2|RW_MGR_REFRESH|RW_MGR_REFRESH_ALL|RW_MGR_RETURN|RW_MGR_SGLE_READ|RW_MGR_ZQCL|RW_MGR_TRUE_MEM_DATA_MASK_WIDTH|RW_MGR_MEM_ADDRESS_MIRRORING|RW_MGR_MEM_DATA_MASK_WIDTH|RW_MGR_MEM_DATA_WIDTH|RW_MGR_MEM_DQ_PER_READ_DQS|RW_MGR_MEM_DQ_PER_WRITE_DQS|RW_MGR_MEM_IF_READ_DQS_WIDTH|RW_MGR_MEM_IF_WRITE_DQS_WIDTH|RW_MGR_MEM_NUMBER_OF_CS_PER_DIMM|RW_MGR_MEM_NUMBER_OF_RANKS|RW_MGR_MEM_VIRTUAL_GROUPS_PER_READ_DQS|RW_MGR_MEM_VIRTUAL_GROUPS_PER_WRITE_DQS|IO_DELAY_PER_DCHAIN_TAP|IO_DELAY_PER_DQS_EN_DCHAIN_TAP|IO_DELAY_PER_OPA_TAP|IO_DLL_CHAIN_LENGTH|IO_DQDQS_OUT_PHASE_MAX|IO_DQS_EN_DELAY_MAX|IO_DQS_EN_DELAY_OFFSET|IO_DQS_EN_PHASE_MAX|IO_DQS_IN_DELAY_MAX|IO_DQS_IN_RESERVE|IO_DQS_OUT_RESERVE|IO_IO_IN_DELAY_MAX|IO_IO_OUT1_DELAY_MAX|IO_IO_OUT2_DELAY_MAX|IO_SHIFT_DQS_EN_WHEN_SHIFT_DQS|AFI_RATE_RATIO|AFI_CLK_FREQ|CALIB_LFIFO_OFFSET|CALIB_VFIFO_OFFSET|ENABLE_SUPER_QUICK_CALIBRATION|MAX_LATENCY_COUNT_WIDTH|READ_VALID_FIFO_SIZE|REG_FILE_INIT_SEQ_SIGNATURE|TINIT_CNTR0_VAL|TINIT_CNTR1_VAL|TINIT_CNTR2_VAL|TRESET_CNTR0_VAL|TRESET_CNTR1_VAL|TRESET_CNTR2_VAL|CONFIG_HPS_SDR_CTRLCFG_EXTRATIME1_CFG_EXTRA_CTL_CLK_RD_TO_WR|CONFIG_HPS_SDR_CTRLCFG_EXTRATIME1_CFG_EXTRA_CTL_CLK_RD_TO_WR_BC|CONFIG_HPS_SDR_CTRLCFG_EXTRATIME1_CFG_EXTRA_CTL_CLK_RD_TO_WR_DIFF_CHIP)\s+' SDRAM_CONFIG_H_FILENAME = "sdram_config.h" sdramHTemplate = "" seqAutoTemplate = "" seqDefinesTemplate = "" seqAutoAcTemplate = "" seqAutoInstTemplate = "" seqAutoTemplateList = [] seqDefinesTemplateList = [] seqAutoAcTemplateList = [] seqAutoInstTemplateList = [] def __init__(self, inputDir, outputDir, emifFileName='emif.xml', hpsFileName='hps.xml'): """ EMIFGrokker initialization """ self.inputDir = inputDir self.outputDir = outputDir sdramDir = self.outputDir if not os.path.isdir(sdramDir): os.makedirs(sdramDir) self.emifFileName = inputDir + os.sep + emifFileName self.hpsFileName = inputDir + os.sep + hpsFileName self.emifDom = xml.dom.minidom.parse(self.emifFileName) self.hpsDom = xml.dom.minidom.parse(self.hpsFileName) self.sequencerDefinesStream = None self.seqAutoFileName = inputDir + os.sep + "sequencer_auto.h" self.seqDefinesFileName = inputDir + os.sep + "sequencer_defines.h" self.seqAutoACFileName = inputDir + os.sep + "sequencer_auto_ac_init.c" self.seqAutoInstFileName = inputDir + os.sep + "sequencer_auto_inst_init.c" self.createFilesFromEMIF() def openSeqFiles(self): """ files to retrieve values to written to sdram_config.h """ self.seq_auto_fd = open(self.seqAutoFileName, "r") self.seq_defines_fd = open(self.seqDefinesFileName, "r") self.seq_auto_ac_fd = open(self.seqAutoACFileName, "r") self.seq_auto_inst_fd = open(self.seqAutoInstFileName, "r") def closeSeqFiles(self): """ close files """ self.seq_auto_fd.close() self.seq_defines_fd.close() self.seq_auto_ac_fd.close() self.seq_auto_inst_fd.close() def processSeqAuto(self): """ process sequencer files to retrieve variable. Regex match is from qts-filter.sh """ # replace underscore & bracket in sequencer_auto.h define for line in self.seq_auto_fd.readlines(): if re.match(".*__RW_MGR_", line) and not re.match(".*ac_", line) and not re.match(".*CONTENT_", line): line = re.sub("__RW_MGR", "RW_MGR", line) if re.match(self.SDRAM_MATCH, line): self.seqAutoTemplateList.append(re.sub(r' (\w+)(\s+)(\d+)', r' \1\t\3', line)) self.seqAutoTemplateList.sort() self.seqAutoTemplate = ''.join([item for item in self.seqAutoTemplateList]) # replace underscore & bracket in sequencer_defines.h define for line in self.seq_defines_fd.readlines(): if re.match("^#define (\w+_)", line): line = re.sub("__", "", line) if re.match(self.SDRAM_MATCH, line): self.seqDefinesTemplateList.append(re.sub(r' (\w+)(\s+)(\d+)', r' \1\t\3', line)) self.seqDefinesTemplateList.sort() self.seqDefinesTemplate = ''.join([item for item in self.seqDefinesTemplateList]) arrayMatchStart = 0 # replace const variable declaration in sequencer_auto_ac_init.c for line in self.seq_auto_ac_fd.readlines(): if re.match("^const.*\[", line) or arrayMatchStart: if arrayMatchStart == 0: line = line.strip() + " " arrayMatchStart = 1 if re.match("};", line): arrayMatchStart = 0 self.seqAutoAcTemplateList.append("};") continue line = re.sub("alt_u32", "u32", line) self.seqAutoAcTemplateList.append(re.sub("\[.*\]", "[]", line)) self.seqAutoAcTemplate = ''.join([item for item in self.seqAutoAcTemplateList]) arrayMatchStart = 0 # replace const variable declaration in sequencer_auto_inst_init.c for line in self.seq_auto_inst_fd.readlines(): if re.match("^const.*\[", line) or arrayMatchStart: if arrayMatchStart == 0: line = line.strip() + " " arrayMatchStart = 1 if re.match("};", line): arrayMatchStart = 0 self.seqAutoInstTemplateList.append("};") continue line = re.sub("alt_u32", "u32", line) self.seqAutoInstTemplateList.append(re.sub("\[.*\]", "[]", line)) self.seqAutoInstTemplate = ''.join([item for item in self.seqAutoInstTemplateList]) def handleSettingNode(self, settingNode): """ create define string from variable name and value """ if settingNode.hasAttribute('name') and settingNode.hasAttribute('value'): name = settingNode.getAttribute('name') value = settingNode.getAttribute('value') self.sequencerDefinesStream.write("#define " + name + ' ' + '(' + value + ')' + '\n') def updateTemplate(self, name, value): """ update sdram template """ pattern = "${" + name + "}" self.sdramHTemplate = self.sdramHTemplate.replace(pattern, value) def handleEMIFControllerNode(self, node): """ retrieve values from emif.xml for controller node """ derivedNoDmPins = 0 derivedCtrlWidth = 0 derivedEccEn = 0 derivedEccCorrEn = 0 self.mem_if_rd_to_wr_turnaround_oct = 0 node = xmlgrok.firstElementChild(node) while node != None: name = node.getAttribute('name') value = node.getAttribute('value') if value == "true": value = "1" elif value == "false": value = "0" self.updateTemplate(name, value) if name == "MEM_IF_DM_PINS_EN": if value == "1": derivedNoDmPins = 0 else: derivedNoDmPins = 1 if name == "MEM_DQ_WIDTH": if value == "8": derivedCtrlWidth = 0 derivedEccEn = 0 derivedEccCorrEn = 0 elif value == "16": derivedCtrlWidth = 1 derivedEccEn = 0 derivedEccCorrEn = 0 elif value == "24": derivedCtrlWidth = 1 derivedEccEn = 1 derivedEccCorrEn = 1 elif value == "32": derivedCtrlWidth = 2 derivedEccEn = 0 derivedEccCorrEn = 0 elif value == "40": derivedCtrlWidth = 2 derivedEccEn = 1 derivedEccCorrEn = 1 if name == "MEM_IF_RD_TO_WR_TURNAROUND_OCT": self.mem_if_rd_to_wr_turnaround_oct = int(value) node = xmlgrok.nextElementSibling(node) self.updateTemplate("DERIVED_NODMPINS", str(derivedNoDmPins)) self.updateTemplate("DERIVED_CTRLWIDTH", str(derivedCtrlWidth)) self.updateTemplate("DERIVED_ECCEN", str(derivedEccEn)) self.updateTemplate("DERIVED_ECCCORREN", str(derivedEccCorrEn)) def handleEMIFPllNode(self, node): """ retrieve values for pll node """ node = xmlgrok.firstElementChild(node) while node != None: name = node.getAttribute('name') value = node.getAttribute('value') self.updateTemplate(name, value) node = xmlgrok.nextElementSibling(node) def handleEMIFSequencerNode(self, node): """ retrieve values for sequencer node """ derivedMemtype = 0 derivedSelfrfshexit = 0 self.afi_rate_ratio = 0 node = xmlgrok.firstElementChild(node) while node != None: name = node.getAttribute('name') value = node.getAttribute('value') self.updateTemplate(name, value) if value.isdigit(): intValue = int(value) else: intValue = 0 if name == "DDR2" and intValue != 0: derivedMemtype = 1 derivedSelfrfshexit = 200 elif name == "DDR3" and intValue != 0: derivedMemtype = 2 derivedSelfrfshexit = 512 elif name == "LPDDR1" and intValue != 0: derivedMemtype = 3 derivedSelfrfshexit = 200 elif name == "LPDDR2" and intValue != 0: derivedMemtype = 4 derivedSelfrfshexit = 200 elif name == "AFI_RATE_RATIO" and intValue != 0: self.afi_rate_ratio = intValue node = xmlgrok.nextElementSibling(node) self.updateTemplate("DERIVED_MEMTYPE", str(derivedMemtype)) self.updateTemplate("DERIVED_SELFRFSHEXIT", str(derivedSelfrfshexit)) def handleHpsFpgaInterfaces(self, node): """ retrieve values for fpga interface """ node = xmlgrok.firstElementChild(node) while node != None: name = node.getAttribute('name') value = node.getAttribute('value') self.updateTemplate(name, value) node = xmlgrok.nextElementSibling(node) def createFilesFromEMIF(self): """ create sdram_config.h with the template and value read from xml. Different sequencer files are written to individual section, with comment at the start. """ self.sdramHTemplate ="""\ #define CONFIG_HPS_SDR_CTRLCFG_CPORTRDWR_CPORTRDWR 0x5A56A #define CONFIG_HPS_SDR_CTRLCFG_CPORTRMAP_CPORTRMAP 0xB00088 #define CONFIG_HPS_SDR_CTRLCFG_CPORTWIDTH_CPORTWIDTH 0x44555 #define CONFIG_HPS_SDR_CTRLCFG_CPORTWMAP_CPORTWMAP 0x2C011000 #define CONFIG_HPS_SDR_CTRLCFG_CTRLCFG_ADDRORDER ${ADDR_ORDER} #define CONFIG_HPS_SDR_CTRLCFG_CTRLCFG_DQSTRKEN ${USE_HPS_DQS_TRACKING} #define CONFIG_HPS_SDR_CTRLCFG_CTRLCFG_ECCCORREN ${DERIVED_ECCCORREN} #define CONFIG_HPS_SDR_CTRLCFG_CTRLCFG_ECCEN ${DERIVED_ECCEN} #define CONFIG_HPS_SDR_CTRLCFG_CTRLCFG_MEMBL ${MEM_BURST_LENGTH} #define CONFIG_HPS_SDR_CTRLCFG_CTRLCFG_MEMTYPE ${DERIVED_MEMTYPE} #define CONFIG_HPS_SDR_CTRLCFG_CTRLCFG_NODMPINS ${DERIVED_NODMPINS} #define CONFIG_HPS_SDR_CTRLCFG_CTRLCFG_REORDEREN 1 #define CONFIG_HPS_SDR_CTRLCFG_CTRLCFG_STARVELIMIT 10 #define CONFIG_HPS_SDR_CTRLCFG_CTRLWIDTH_CTRLWIDTH ${DERIVED_CTRLWIDTH} #define CONFIG_HPS_SDR_CTRLCFG_DRAMADDRW_BANKBITS ${MEM_IF_BANKADDR_WIDTH} #define CONFIG_HPS_SDR_CTRLCFG_DRAMADDRW_COLBITS ${MEM_IF_COL_ADDR_WIDTH} #define CONFIG_HPS_SDR_CTRLCFG_DRAMADDRW_CSBITS ${DEVICE_DEPTH} #define CONFIG_HPS_SDR_CTRLCFG_DRAMADDRW_ROWBITS ${MEM_IF_ROW_ADDR_WIDTH} #define CONFIG_HPS_SDR_CTRLCFG_DRAMDEVWIDTH_DEVWIDTH 8 #define CONFIG_HPS_SDR_CTRLCFG_DRAMIFWIDTH_IFWIDTH ${MEM_DQ_WIDTH} #define CONFIG_HPS_SDR_CTRLCFG_DRAMINTR_INTREN 0 #define CONFIG_HPS_SDR_CTRLCFG_DRAMODT_READ ${CFG_READ_ODT_CHIP} #define CONFIG_HPS_SDR_CTRLCFG_DRAMODT_WRITE ${CFG_WRITE_ODT_CHIP} #define CONFIG_HPS_SDR_CTRLCFG_DRAMTIMING1_AL 0 #define CONFIG_HPS_SDR_CTRLCFG_DRAMTIMING1_TCL ${MEM_TCL} #define CONFIG_HPS_SDR_CTRLCFG_DRAMTIMING1_TCWL ${MEM_WTCL_INT} #define CONFIG_HPS_SDR_CTRLCFG_DRAMTIMING1_TFAW ${MEM_TFAW} #define CONFIG_HPS_SDR_CTRLCFG_DRAMTIMING1_TRFC ${MEM_TRFC} #define CONFIG_HPS_SDR_CTRLCFG_DRAMTIMING1_TRRD ${MEM_TRRD} #define CONFIG_HPS_SDR_CTRLCFG_DRAMTIMING2_IF_TRCD ${MEM_TRCD} #define CONFIG_HPS_SDR_CTRLCFG_DRAMTIMING2_IF_TREFI ${MEM_TREFI} #define CONFIG_HPS_SDR_CTRLCFG_DRAMTIMING2_IF_TRP ${MEM_TRP} #define CONFIG_HPS_SDR_CTRLCFG_DRAMTIMING2_IF_TWR ${MEM_TWR} #define CONFIG_HPS_SDR_CTRLCFG_DRAMTIMING2_IF_TWTR ${MEM_TWTR} #define CONFIG_HPS_SDR_CTRLCFG_DRAMTIMING3_TCCD 4 #define CONFIG_HPS_SDR_CTRLCFG_DRAMTIMING3_TMRD ${MEM_TMRD_CK} #define CONFIG_HPS_SDR_CTRLCFG_DRAMTIMING3_TRAS ${MEM_TRAS} #define CONFIG_HPS_SDR_CTRLCFG_DRAMTIMING3_TRC ${MEM_TRC} #define CONFIG_HPS_SDR_CTRLCFG_DRAMTIMING3_TRTP ${MEM_TRTP} #define CONFIG_HPS_SDR_CTRLCFG_DRAMTIMING4_PWRDOWNEXIT 3 #define CONFIG_HPS_SDR_CTRLCFG_DRAMTIMING4_SELFRFSHEXIT ${DERIVED_SELFRFSHEXIT} #define CONFIG_HPS_SDR_CTRLCFG_EXTRATIME1_CFG_EXTRA_CTL_CLK_RD_TO_WR ${DERIVED_CLK_RD_TO_WR} #define CONFIG_HPS_SDR_CTRLCFG_EXTRATIME1_CFG_EXTRA_CTL_CLK_RD_TO_WR_BC ${DERIVED_CLK_RD_TO_WR} #define CONFIG_HPS_SDR_CTRLCFG_EXTRATIME1_CFG_EXTRA_CTL_CLK_RD_TO_WR_DIFF_CHIP ${DERIVED_CLK_RD_TO_WR} #define CONFIG_HPS_SDR_CTRLCFG_FIFOCFG_INCSYNC 0 #define CONFIG_HPS_SDR_CTRLCFG_FIFOCFG_SYNCMODE 0 #define CONFIG_HPS_SDR_CTRLCFG_FPGAPORTRST ${F2SDRAM_RESET_PORT_USED} #define CONFIG_HPS_SDR_CTRLCFG_LOWPWREQ_SELFRFSHMASK 3 #define CONFIG_HPS_SDR_CTRLCFG_LOWPWRTIMING_AUTOPDCYCLES 0 #define CONFIG_HPS_SDR_CTRLCFG_LOWPWRTIMING_CLKDISABLECYCLES 8 #define CONFIG_HPS_SDR_CTRLCFG_MPPACING_0_THRESHOLD1_31_0 0x20820820 #define CONFIG_HPS_SDR_CTRLCFG_MPPACING_1_THRESHOLD1_59_32 0x8208208 #define CONFIG_HPS_SDR_CTRLCFG_MPPACING_1_THRESHOLD2_3_0 0 #define CONFIG_HPS_SDR_CTRLCFG_MPPACING_2_THRESHOLD2_35_4 0x41041041 #define CONFIG_HPS_SDR_CTRLCFG_MPPACING_3_THRESHOLD2_59_36 0x410410 #define CONFIG_HPS_SDR_CTRLCFG_MPPRIORITY_USERPRIORITY 0x0 #define CONFIG_HPS_SDR_CTRLCFG_MPTHRESHOLDRST_0_THRESHOLDRSTCYCLES_31_0 0x01010101 #define CONFIG_HPS_SDR_CTRLCFG_MPTHRESHOLDRST_1_THRESHOLDRSTCYCLES_63_32 0x01010101 #define CONFIG_HPS_SDR_CTRLCFG_MPTHRESHOLDRST_2_THRESHOLDRSTCYCLES_79_64 0x0101 #define CONFIG_HPS_SDR_CTRLCFG_MPWIEIGHT_0_STATICWEIGHT_31_0 0x21084210 #define CONFIG_HPS_SDR_CTRLCFG_MPWIEIGHT_1_STATICWEIGHT_49_32 0x10441 #define CONFIG_HPS_SDR_CTRLCFG_MPWIEIGHT_1_SUMOFWEIGHT_13_0 0x78 #define CONFIG_HPS_SDR_CTRLCFG_MPWIEIGHT_2_SUMOFWEIGHT_45_14 0x0 #define CONFIG_HPS_SDR_CTRLCFG_MPWIEIGHT_3_SUMOFWEIGHT_63_46 0x0 #define CONFIG_HPS_SDR_CTRLCFG_PHYCTRL_PHYCTRL_0 0x200 #define CONFIG_HPS_SDR_CTRLCFG_PORTCFG_AUTOPCHEN 0 #define CONFIG_HPS_SDR_CTRLCFG_RFIFOCMAP_RFIFOCMAP 0x760210 #define CONFIG_HPS_SDR_CTRLCFG_STATICCFG_MEMBL 2 #define CONFIG_HPS_SDR_CTRLCFG_STATICCFG_USEECCASDATA 0 #define CONFIG_HPS_SDR_CTRLCFG_WFIFOCMAP_WFIFOCMAP 0x980543 """ # Get a list of all nodes with the emif element name emifNodeList = self.emifDom.getElementsByTagName('emif') if len(emifNodeList) > 1: print ("*** WARNING:" + "Multiple emif Elements found in %s!" % self.emifFileName) # For each of the emif element nodes, go through the child list # Note that currently there is only one emif Element # but this code will handle more than one emif node # In the future, multiple emif nodes may need additional code # to combine settings from the multiple emif Elements for emifNode in emifNodeList: # Currently, there are only 3 children of the emif Element: # sequencer, controller, and pll # but this is left open-ended for future additions to the # specification for the emif.xml childNode = xmlgrok.firstElementChild(emifNode) while childNode != None: if childNode.nodeName == 'controller': self.handleEMIFControllerNode(childNode) elif childNode.nodeName == 'sequencer': self.handleEMIFSequencerNode(childNode) elif childNode.nodeName == 'pll': self.handleEMIFPllNode(childNode) childNode = xmlgrok.nextElementSibling(childNode) data_rate_ratio = 2 dwidth_ratio = self.afi_rate_ratio * data_rate_ratio if dwidth_ratio == 0: derivedClkRdToWr = 0 else: derivedClkRdToWr = (self.mem_if_rd_to_wr_turnaround_oct / (dwidth_ratio / 2)) if (self.mem_if_rd_to_wr_turnaround_oct % (dwidth_ratio / 2)) > 0: derivedClkRdToWr += 1 self.updateTemplate("DERIVED_CLK_RD_TO_WR", str(int(derivedClkRdToWr))) # MPFE information are stored in hps.xml despite we generate # them into sdram_config, so let's load hps.xml hpsNodeList = self.hpsDom.getElementsByTagName('hps') for hpsNode in hpsNodeList: childNode = xmlgrok.firstElementChild(hpsNode) while childNode != None: # MPFE info is part of fpga_interfaces if childNode.nodeName == 'fpga_interfaces': self.handleHpsFpgaInterfaces(childNode) childNode = xmlgrok.nextElementSibling(childNode) self.sequencerDefinesStream = streamer.Streamer(self.outputDir + os.sep + EMIFGrokker.SDRAM_CONFIG_H_FILENAME, 'w') self.sequencerDefinesStream.open() self.sequencerDefinesStream.writeLicenseHeader() self.sequencerDefinesStream.write(EMIFGrokker.SDRAM_FILE_HEADER) ret = self.sequencerDefinesStream.writeSentinelStart(EMIFGrokker.SDRAM_SENTINEL) if ret == -1: print("Empty header written. Exiting.") self.sequencerDefinesStream.write("/* SDRAM configuration */\n") self.sequencerDefinesStream.write(self.sdramHTemplate) self.openSeqFiles() self.processSeqAuto() self.sequencerDefinesStream.write("\n") self.sequencerDefinesStream.write("/* Sequencer auto configuration */\n") self.sequencerDefinesStream.write(self.seqAutoTemplate) self.sequencerDefinesStream.write("\n") self.sequencerDefinesStream.write("/* Sequencer defines configuration */\n") self.sequencerDefinesStream.write(self.seqDefinesTemplate) self.sequencerDefinesStream.write("\n") self.sequencerDefinesStream.write("/* Sequencer ac_rom_init configuration */\n") self.sequencerDefinesStream.write(self.seqAutoAcTemplate) self.sequencerDefinesStream.write("\n\n") self.sequencerDefinesStream.write("/* Sequencer inst_rom_init configuration */\n") self.sequencerDefinesStream.write(self.seqAutoInstTemplate) self.sequencerDefinesStream.write("\n") ret = self.sequencerDefinesStream.writeSentinelEnd(EMIFGrokker.SDRAM_SENTINEL) if ret == -1: print("Empty header written. Exiting.") self.sequencerDefinesStream.close() self.closeSeqFiles()