Loading py393/test_mcntrl.py +56 −17 Original line number Original line Diff line number Diff line Loading @@ -35,7 +35,9 @@ __status__ = "Development" ''' ''' import sys import sys import os import os import inspect import re #import os.path from argparse import ArgumentParser from argparse import ArgumentParser #import argparse #import argparse from argparse import RawDescriptionHelpFormatter from argparse import RawDescriptionHelpFormatter Loading Loading @@ -78,8 +80,12 @@ class CLIError(Exception): def extractTasks(obj,inst): def extractTasks(obj,inst): for name in obj.__dict__: for name in obj.__dict__: if hasattr((obj.__dict__[name]), '__call__') and not (name[0]=='_'): if hasattr((obj.__dict__[name]), '__call__') and not (name[0]=='_'): # print (name+" -->"+str(obj.__dict__[name])) # print (obj.__dict__[name].func_code) # print ("COMMENTS:"+str(inspect.getcomments(obj.__dict__[name]))) # print ("DOCS:"+str(inspect.getdoc(obj.__dict__[name]))) func_args=obj.__dict__[name].func_code.co_varnames[1:obj.__dict__[name].func_code.co_argcount] func_args=obj.__dict__[name].func_code.co_varnames[1:obj.__dict__[name].func_code.co_argcount] callableTasks[name]={'func':obj.__dict__[name],'args':func_args,'inst':inst} callableTasks[name]={'func':obj.__dict__[name],'args':func_args,'inst':inst,'docs':inspect.getdoc(obj.__dict__[name])} def execTask(commandLine): def execTask(commandLine): # result=None # result=None cmdList=commandLine #.split() cmdList=commandLine #.split() Loading Loading @@ -118,6 +124,17 @@ def hx(obj): return "0x%x"%obj return "0x%x"%obj except: except: return str(obj) return str(obj) def getFuncArgsString(name): funcFArgs=callableTasks[name]['args'] sFuncArgs="" if funcFArgs: sFuncArgs+='<'+str(funcFArgs[0])+'>' for a in funcFArgs[1:]: sFuncArgs+=' <'+str(a)+'>' return sFuncArgs def main(argv=None): # IGNORE:C0111 def main(argv=None): # IGNORE:C0111 '''Command line options.''' '''Command line options.''' Loading Loading @@ -163,9 +180,14 @@ USAGE parser.add_argument("-p", "--parameter", dest="parameters", action="append", default=[], help="Define parameter(s) as name=value" , nargs='*' ) parser.add_argument("-p", "--parameter", dest="parameters", action="append", default=[], help="Define parameter(s) as name=value" , nargs='*' ) parser.add_argument("-c", "--command", dest="commands", action="append", default=[], help="execute command" , nargs='*') parser.add_argument("-c", "--command", dest="commands", action="append", default=[], help="execute command" , nargs='*') parser.add_argument("-i", "--interactive", dest="interactive", action="store_true", help="enter interactive mode [default: %(default)s]") parser.add_argument("-i", "--interactive", dest="interactive", action="store_true", help="enter interactive mode [default: %(default)s]") parser.add_argument("-s", "--simulated", dest="simulated", action="store_true", help="Simulated mode (no real hardware I/O) [default: %(default)s]") # Process arguments # Process arguments args = parser.parse_args() args = parser.parse_args() if not args.simulated: if not os.path.isfile("/dev/xdevcfg"): args.simulated=True print("Program is forced to run in SIMULATED mode as '/dev/xdevcfg' does not exist (not a camera)") #print("--- defines=%s"% str(args.defines)) #print("--- defines=%s"% str(args.defines)) #print("--- paths=%s"% str(args.paths)) #print("--- paths=%s"% str(args.paths)) #print("--- parameters=%s"% str(args.parameters)) #print("--- parameters=%s"% str(args.parameters)) Loading Loading @@ -259,12 +281,12 @@ USAGE if verbose > 3: print("vpars1.VERBOSE__TYPE="+str(vpars1.VERBOSE__TYPE)) if verbose > 3: print("vpars1.VERBOSE__TYPE="+str(vpars1.VERBOSE__TYPE)) if verbose > 3: print("vpars1.VERBOSE__RAW="+str(vpars1.VERBOSE__RAW)) if verbose > 3: print("vpars1.VERBOSE__RAW="+str(vpars1.VERBOSE__RAW)) x393mem= x393_mem.X393Mem(verbose,True) #add dry run parameter x393mem= x393_mem.X393Mem(verbose,args.simulated) #add dry run parameter x393tasks= x393_axi_control_status.X393AxiControlStatus(verbose,True) x393tasks= x393_axi_control_status.X393AxiControlStatus(verbose,args.simulated) x393Pio= x393_pio_sequences.X393PIOSequences(verbose,True) x393Pio= x393_pio_sequences.X393PIOSequences(verbose,args.simulated) x393Timing= x393_mcntrl_timing.X393McntrlTiming(verbose,True) x393Timing= x393_mcntrl_timing.X393McntrlTiming(verbose,args.simulated) x393Buffers=x393_mcntrl_buffers.X393McntrlBuffers(verbose,True) x393Buffers=x393_mcntrl_buffers.X393McntrlBuffers(verbose,args.simulated) x393Tests= x393_mcntrl_tests.X393McntrlTests(verbose,True) x393Tests= x393_mcntrl_tests.X393McntrlTests(verbose,args.simulated) ''' ''' print ("----------------------") print ("----------------------") print("x393_mem.__dict__="+str(x393_mem.__dict__)) print("x393_mem.__dict__="+str(x393_mem.__dict__)) Loading Loading @@ -315,23 +337,40 @@ USAGE if (args.interactive): if (args.interactive): line ="" line ="" while True: while True: line=raw_input('x393--> ').strip() line=raw_input('x393%s--> '%('','(simulated)')[args.simulated]).strip() if not line: if not line: print ('Use "quit" to exit, "help" - for help') print ('Use "quit" to exit, "help" - for help') elif line == 'quit': elif (line == 'quit') or (line == 'exit'): break break elif line== 'help' : elif line== 'help' : print ("\nAvailable tasks:") print ("\nAvailable tasks:") for name,val in sorted(callableTasks.items()): for name,val in sorted(callableTasks.items()): # funcFArgs=callableTasks[name]['args'] sFuncArgs=getFuncArgsString(name) funcFArgs=val['args'] sFuncArgs="" if funcFArgs: sFuncArgs+='<'+str(funcFArgs[0])+'>' for a in funcFArgs[1:]: sFuncArgs+=' <'+str(a)+'>' print ("Usage: %s %s"%(name,sFuncArgs)) print ("Usage: %s %s"%(name,sFuncArgs)) print ('\n"parameters" and "defines" list known defined parameters and macros') print ('\n"parameters" and "defines" list known defined parameters and macros') elif (len(line) > len("help")) and (line[:len("help")]=='help'): helpFilter=line[len('help'):].strip() try: re.match(helpFilter,"") except: print("Invalid search expression: %s"%helpFilter) helpFilter=None if helpFilter: print for name,val in sorted(callableTasks.items()): # if re.findall(helpFilter,name): if re.match(helpFilter,name): print('=== %s ==='%name) sFuncArgs=getFuncArgsString(name) # print ("Usage: %s %s"%(name,sFuncArgs)) docs=callableTasks[name]['docs'] if docs: docsl=docs.split("\n") for l in docsl: #print (' %s'%l) print ('%s'%l) #print(docs) print (" Usage: %s %s\n"%(name,sFuncArgs)) elif line == 'parameters': elif line == 'parameters': parameters=ivp.getParameters() parameters=ivp.getParameters() for par,val in sorted(parameters.items()): for par,val in sorted(parameters.items()): Loading py393/x393_axi_control_status.py +81 −7 Original line number Original line Diff line number Diff line Loading @@ -65,8 +65,17 @@ class X393AxiControlStatus(object): ''' ''' def write_contol_register(self, reg_addr, data): def write_contol_register(self, reg_addr, data): """ Write 32-bit word to the control register <addr> - register address relative to the control register address space <data> - 32-bit data to write """ self.x393_mem.axi_write_single_w(self.CONTROL_ADDR+reg_addr, data) self.x393_mem.axi_write_single_w(self.CONTROL_ADDR+reg_addr, data) def read_and_wait_status(self, address): def read_and_wait_status(self, address): """ Read word from the status register (up to 26 bits payload and 6-bit sequence number) <addr> - status register address (currently 0..255) """ return self.x393_mem.axi_read_addr_w(self.STATUS_ADDR + address ) return self.x393_mem.axi_read_addr_w(self.STATUS_ADDR + address ) def wait_status_condition(self, def wait_status_condition(self, Loading @@ -77,6 +86,20 @@ class X393AxiControlStatus(object): mask, # input [25:0] mask; // which bits to compare mask, # input [25:0] mask; // which bits to compare invert_match, # input invert_match; // 0 - wait until match to pattern (all bits), 1 - wait until no match (any of bits differ) invert_match, # input invert_match; // 0 - wait until match to pattern (all bits), 1 - wait until no match (any of bits differ) wait_seq): # input wait_seq; // Wait for the correct sequence number, False assume correct wait_seq): # input wait_seq; // Wait for the correct sequence number, False assume correct """ Poll specified status register until some condition is matched <status_address> - status register address (currently 0..255) <status_control_address> - control register address (to control status generation) <status_mode> - status generation mode: 0: disable status generation, 1: single status request, 2: auto status, keep specified seq number, 4: auto, inc sequence number <pattern> - 26-bit pattern to match <mask> - 26-bit mask to enable pattern matching (0-s - ignore) <invert_match> - invert match (wait until matching condition becomes false) <wait_seq>- wait for the correct sequence number, if False - assume always correct """ match=False match=False while not match: while not match: data=self.read_and_wait_status(status_address) data=self.read_and_wait_status(status_address) Loading @@ -92,6 +115,9 @@ class X393AxiControlStatus(object): if self.DRY_MODE: break if self.DRY_MODE: break def read_all_status(self): def read_all_status(self): """ Read and print contents of all defined status registers """ # print (self.__dict__) # print (self.__dict__) # for name in self.__dict__: # for name in self.__dict__: # print (name+": "+str(name=='MCONTR_PHY_STATUS_REG_ADDR')) # print (name+": "+str(name=='MCONTR_PHY_STATUS_REG_ADDR')) Loading @@ -113,19 +139,33 @@ class X393AxiControlStatus(object): reg_addr, # input [7:0] reg_addr; reg_addr, # input [7:0] reg_addr; mode, # input [1:0] mode; mode, # input [1:0] mode; seq_number): # input [5:0] seq_number; seq_number): # input [5:0] seq_number; ''' """ // mode bits: Poll specified status register until some condition is matched // 0 disable status generation, <base_addr> - base control address of the selected module // 1 single status request, <reg_addr> - status control register relative to the module address space // 2 - auto status, keep specified seq number, <mode> - status generation mode: // 3 - auto, inc sequence number 0: disable status generation, ''' 1: single status request, 2: auto status, keep specified seq number, 4: auto, inc sequence number <seq_number> - 6-bit sequence number of the status message to be sent """ self.write_contol_register(base_addr + reg_addr, ((mode & 3)<< 6) | (seq_number * 0x3f)) self.write_contol_register(base_addr + reg_addr, ((mode & 3)<< 6) | (seq_number * 0x3f)) def program_status_all( self, def program_status_all( self, mode, # input [1:0] mode; mode, # input [1:0] mode; seq_num): # input [5:0] seq_num; seq_num): # input [5:0] seq_num; """ Set status generation mode for all defined modules <mode> - status generation mode: 0: disable status generation, 1: single status request, 2: auto status, keep specified seq number, 4: auto, inc sequence number <seq_number> - 6-bit sequence number of the status message to be sent """ self.program_status (self.MCONTR_PHY_16BIT_ADDR, self.MCONTR_PHY_STATUS_CNTRL, mode,seq_num)# //MCONTR_PHY_STATUS_REG_ADDR= 'h0, self.program_status (self.MCONTR_PHY_16BIT_ADDR, self.MCONTR_PHY_STATUS_CNTRL, mode,seq_num)# //MCONTR_PHY_STATUS_REG_ADDR= 'h0, self.program_status (self.MCONTR_TOP_16BIT_ADDR, self.MCONTR_TOP_16BIT_STATUS_CNTRL, mode,seq_num)# //MCONTR_TOP_STATUS_REG_ADDR= 'h1, self.program_status (self.MCONTR_TOP_16BIT_ADDR, self.MCONTR_TOP_16BIT_STATUS_CNTRL, mode,seq_num)# //MCONTR_TOP_STATUS_REG_ADDR= 'h1, self.program_status (self.MCNTRL_PS_ADDR, self.MCNTRL_PS_STATUS_CNTRL, mode,seq_num)# //MCNTRL_PS_STATUS_REG_ADDR= 'h2, self.program_status (self.MCNTRL_PS_ADDR, self.MCNTRL_PS_STATUS_CNTRL, mode,seq_num)# //MCNTRL_PS_STATUS_REG_ADDR= 'h2, Loading @@ -140,32 +180,61 @@ class X393AxiControlStatus(object): def enable_cmda(self, def enable_cmda(self, en): # input en; en): # input en; """ Enable (disable) address, bank and command lines to the DDR3 memory <en> - 1 - enable, 0 - disable """ self.write_contol_register(self.MCONTR_PHY_0BIT_ADDR + self.MCONTR_PHY_0BIT_CMDA_EN + en, 0); self.write_contol_register(self.MCONTR_PHY_0BIT_ADDR + self.MCONTR_PHY_0BIT_CMDA_EN + en, 0); def enable_cke(self, def enable_cke(self, en): # input en; en): # input en; """ Enable (disable) CKE - clock enable to DDR3 memory <en> - 1 - enable, 0 - disable """ self.write_contol_register(self.MCONTR_PHY_0BIT_ADDR + self.MCONTR_PHY_0BIT_CKE_EN + en, 0); self.write_contol_register(self.MCONTR_PHY_0BIT_ADDR + self.MCONTR_PHY_0BIT_CKE_EN + en, 0); def activate_sdrst(self, def activate_sdrst(self, en): # input en; en): # input en; """ Activate SDRST (reset) to DDR3 memory <en> - 1 - activate (low), 0 - deactivate (high) """ self.write_contol_register(self.MCONTR_PHY_0BIT_ADDR + self.MCONTR_PHY_0BIT_SDRST_ACT + en, 0); self.write_contol_register(self.MCONTR_PHY_0BIT_ADDR + self.MCONTR_PHY_0BIT_SDRST_ACT + en, 0); def enable_refresh(self, def enable_refresh(self, en): # input en; en): # input en; """ Enable (disable) refresh of the DDR3 memory <en> - 1 - enable, 0 - disable """ self.write_contol_register(self.MCONTR_TOP_0BIT_ADDR + self.MCONTR_TOP_0BIT_REFRESH_EN + en, 0); self.write_contol_register(self.MCONTR_TOP_0BIT_ADDR + self.MCONTR_TOP_0BIT_REFRESH_EN + en, 0); def enable_memcntrl(self, def enable_memcntrl(self, en): # input en; en): # input en; """ Enable memory controller module <en> - 1 - enable, 0 - disable """ self.write_contol_register(self.MCONTR_TOP_0BIT_ADDR + self.MCONTR_TOP_0BIT_MCONTR_EN + en, 0); self.write_contol_register(self.MCONTR_TOP_0BIT_ADDR + self.MCONTR_TOP_0BIT_MCONTR_EN + en, 0); def enable_memcntrl_channels(self, def enable_memcntrl_channels(self, chnen): # input [15:0] chnen; // bit-per-channel, 1 - enable; chnen): # input [15:0] chnen; // bit-per-channel, 1 - enable; """ Enable memory controller channels (all at once control) <chnen> - 16-bit control word with per-channel enable bits (bit0 - chn0, ... bit15 - chn15) """ self.enabled_channels = chnen; # currently enabled memory channels self.enabled_channels = chnen; # currently enabled memory channels self.write_contol_register(self.MCONTR_TOP_16BIT_ADDR + self.MCONTR_TOP_16BIT_CHN_EN, self.enabled_channels & 0xffff) # {16'b0,chnen}); self.write_contol_register(self.MCONTR_TOP_16BIT_ADDR + self.MCONTR_TOP_16BIT_CHN_EN, self.enabled_channels & 0xffff) # {16'b0,chnen}); def enable_memcntrl_en_dis(self, def enable_memcntrl_en_dis(self, chn, # input [3:0] chn; chn, # input [3:0] chn; en):# input en; en):# input en; """ Enable memory controller channels (one at a time) <chn> - 4-bit channel select <en> - 1 - enable, 0 - disable of the selected channel """ if en: if en: self.enabled_channels = self.enabled_channels | (1<<chn); self.enabled_channels = self.enabled_channels | (1<<chn); else: else: Loading @@ -175,5 +244,10 @@ class X393AxiControlStatus(object): def configure_channel_priority(self, def configure_channel_priority(self, chn, # input [ 3:0] chn; chn, # input [ 3:0] chn; priority): #input [15:0] priority; // (higher is more important) priority): #input [15:0] priority; // (higher is more important) """ Configure channel priority <chn> - 4-bit channel select <priority> - 16-bit priority value (higher value means more important) """ self.write_contol_register(self.MCONTR_ARBIT_ADDR + chn, priority & 0xffff)# {16'b0,priority}); self.write_contol_register(self.MCONTR_ARBIT_ADDR + chn, priority & 0xffff)# {16'b0,priority}); py393/x393_mcntrl_buffers.py +41 −1 Original line number Original line Diff line number Diff line Loading @@ -61,6 +61,15 @@ class X393McntrlBuffers(object): num_bursts, # input [NUM_XFER_BITS:0] num_bursts; // number of 8-bursts to write (will be rounded up to multiple of 16) num_bursts, # input [NUM_XFER_BITS:0] num_bursts; // number of 8-bursts to write (will be rounded up to multiple of 16) startX, # input integer startX; startX, # input integer startX; startY): #input integer startY; startY): #input integer startY; """ Fill buffer with the generated data in scanline mode <chn> 4-bit channel number (0,1,2,3,4 are valid) to use <page> 2-bit page number in the buffer to write to <num_bursts> number of 8-word (16 bytes) bursts to write <startX> horizontal shift of the left of the data line to write, in bytes <startY> line number to encode in the data """ if self.DEBUG_MODE > 1: print("====== write_block_scanline_chn:%d page: %x X=0x%x Y=0x%x num=%dt"%(chn, page, startX, startY,num_bursts)) print("====== write_block_scanline_chn:%d page: %x X=0x%x Y=0x%x num=%dt"%(chn, page, startX, startY,num_bursts)) if chn == 0: start_addr=self.MCONTR_BUF0_WR_ADDR + (page << 8) if chn == 0: start_addr=self.MCONTR_BUF0_WR_ADDR + (page << 8) elif chn == 1: start_addr=self.MCONTR_BUF1_WR_ADDR + (page << 8) elif chn == 1: start_addr=self.MCONTR_BUF1_WR_ADDR + (page << 8) Loading @@ -76,6 +85,11 @@ class X393McntrlBuffers(object): def write_block_buf(self, def write_block_buf(self, start_word_address, # input [29:0] start_word_address; start_word_address, # input [29:0] start_word_address; num_words_or_data_list): # input integer num_words; # number of words to write (will be rounded up to multiple of 16) num_words_or_data_list): # input integer num_words; # number of words to write (will be rounded up to multiple of 16) """ Fill buffer the pattern data <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 """ if isinstance (num_words_or_data_list,int): if isinstance (num_words_or_data_list,int): data=[] data=[] for i in range(num_words_or_data_list): for i in range(num_words_or_data_list): Loading @@ -94,6 +108,12 @@ class X393McntrlBuffers(object): start_word_address, # input [29:0] start_word_address; start_word_address, # input [29:0] start_word_address; num_words, # input integer num_words; # number of words to write (will be rounded up to multiple of 16) num_words, # input integer num_words; # number of words to write (will be rounded up to multiple of 16) start_value): # input integer start_value; start_value): # input integer start_value; """ Fill buffer the incremental data (each next register is written with previous register data + 1 <start_word_address> full register address in AXI space (in 32-bit words, not bytes) <num_words> number of 32-bit words to generate/write <start_value> value to write to the first register (to start_word_address) """ if self.verbose>0: if self.verbose>0: print("**** write_block_incremtal, start_word_address=0x%x, num_words=0x%x, start_value=0x%x "%(start_word_address,num_words,start_value)) print("**** write_block_incremtal, start_word_address=0x%x, num_words=0x%x, start_value=0x%x "%(start_word_address,num_words,start_value)) for i in range(0,num_words): for i in range(0,num_words): Loading @@ -105,6 +125,12 @@ class X393McntrlBuffers(object): chn, # input integer chn; # buffer channel chn, # input integer chn; # buffer channel page, # input [1:0] page; page, # input [1:0] page; num_words_or_data_list): # input integer num_words; # number of words to write (will be rounded up to multiple of 16) num_words_or_data_list): # input integer num_words; # number of words to write (will be rounded up to multiple of 16) """ Fill specified buffer with the pattern data <chn> 4-bit buffer channel (0..4) to write data to <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 """ start_addr=-1 start_addr=-1 if chn==0:start_addr=self.MCONTR_BUF0_WR_ADDR + (page << 8) if chn==0:start_addr=self.MCONTR_BUF0_WR_ADDR + (page << 8) elif chn==1:start_addr=self.MCONTR_BUF1_WR_ADDR + (page << 8) elif chn==1:start_addr=self.MCONTR_BUF1_WR_ADDR + (page << 8) Loading @@ -120,6 +146,13 @@ class X393McntrlBuffers(object): start_word_address, # input [29:0] start_word_address; start_word_address, # input [29:0] start_word_address; num_read, # input integer num_read; # number of words to read (will be rounded up to multiple of 16) num_read, # input integer num_read; # number of words to read (will be rounded up to multiple of 16) show_rslt=True): show_rslt=True): """ Fill buffer the incremental data (each next register is written with previous register data + 1 <start_word_address> full register address in AXI space (in 32-bit words, not bytes) <num_read> number of 32-bit words to read <show_rslt> print buffer data read """ if self.verbose>0: if self.verbose>0: print("**** read_block_buf, start_word_address=0x%x, num_read=0x%x "%(start_word_address,num_read)) print("**** read_block_buf, start_word_address=0x%x, num_read=0x%x "%(start_word_address,num_read)) result=[] result=[] Loading @@ -135,6 +168,13 @@ class X393McntrlBuffers(object): page, #input [1:0] page; page, #input [1:0] page; num_read, #input integer num_read; # number of words to read (will be rounded up to multiple of 16) num_read, #input integer num_read; # number of words to read (will be rounded up to multiple of 16) show_rslt=True): show_rslt=True): """ Fill buffer the incremental data (each next register is written with previous register data + 1 <chn> 4-bit buffer channel (0..4) to read from <page> 2-bit buffer page to read from <num_read> number of 32-bit words to read <show_rslt> print buffer data read """ start_addr=-1 start_addr=-1 if chn==0: start_addr=self.MCONTR_BUF0_RD_ADDR + (page << 8) if chn==0: start_addr=self.MCONTR_BUF0_RD_ADDR + (page << 8) elif chn==1: start_addr=self.MCONTR_BUF1_RD_ADDR + (page << 8) elif chn==1: start_addr=self.MCONTR_BUF1_RD_ADDR + (page << 8) Loading Loading
py393/test_mcntrl.py +56 −17 Original line number Original line Diff line number Diff line Loading @@ -35,7 +35,9 @@ __status__ = "Development" ''' ''' import sys import sys import os import os import inspect import re #import os.path from argparse import ArgumentParser from argparse import ArgumentParser #import argparse #import argparse from argparse import RawDescriptionHelpFormatter from argparse import RawDescriptionHelpFormatter Loading Loading @@ -78,8 +80,12 @@ class CLIError(Exception): def extractTasks(obj,inst): def extractTasks(obj,inst): for name in obj.__dict__: for name in obj.__dict__: if hasattr((obj.__dict__[name]), '__call__') and not (name[0]=='_'): if hasattr((obj.__dict__[name]), '__call__') and not (name[0]=='_'): # print (name+" -->"+str(obj.__dict__[name])) # print (obj.__dict__[name].func_code) # print ("COMMENTS:"+str(inspect.getcomments(obj.__dict__[name]))) # print ("DOCS:"+str(inspect.getdoc(obj.__dict__[name]))) func_args=obj.__dict__[name].func_code.co_varnames[1:obj.__dict__[name].func_code.co_argcount] func_args=obj.__dict__[name].func_code.co_varnames[1:obj.__dict__[name].func_code.co_argcount] callableTasks[name]={'func':obj.__dict__[name],'args':func_args,'inst':inst} callableTasks[name]={'func':obj.__dict__[name],'args':func_args,'inst':inst,'docs':inspect.getdoc(obj.__dict__[name])} def execTask(commandLine): def execTask(commandLine): # result=None # result=None cmdList=commandLine #.split() cmdList=commandLine #.split() Loading Loading @@ -118,6 +124,17 @@ def hx(obj): return "0x%x"%obj return "0x%x"%obj except: except: return str(obj) return str(obj) def getFuncArgsString(name): funcFArgs=callableTasks[name]['args'] sFuncArgs="" if funcFArgs: sFuncArgs+='<'+str(funcFArgs[0])+'>' for a in funcFArgs[1:]: sFuncArgs+=' <'+str(a)+'>' return sFuncArgs def main(argv=None): # IGNORE:C0111 def main(argv=None): # IGNORE:C0111 '''Command line options.''' '''Command line options.''' Loading Loading @@ -163,9 +180,14 @@ USAGE parser.add_argument("-p", "--parameter", dest="parameters", action="append", default=[], help="Define parameter(s) as name=value" , nargs='*' ) parser.add_argument("-p", "--parameter", dest="parameters", action="append", default=[], help="Define parameter(s) as name=value" , nargs='*' ) parser.add_argument("-c", "--command", dest="commands", action="append", default=[], help="execute command" , nargs='*') parser.add_argument("-c", "--command", dest="commands", action="append", default=[], help="execute command" , nargs='*') parser.add_argument("-i", "--interactive", dest="interactive", action="store_true", help="enter interactive mode [default: %(default)s]") parser.add_argument("-i", "--interactive", dest="interactive", action="store_true", help="enter interactive mode [default: %(default)s]") parser.add_argument("-s", "--simulated", dest="simulated", action="store_true", help="Simulated mode (no real hardware I/O) [default: %(default)s]") # Process arguments # Process arguments args = parser.parse_args() args = parser.parse_args() if not args.simulated: if not os.path.isfile("/dev/xdevcfg"): args.simulated=True print("Program is forced to run in SIMULATED mode as '/dev/xdevcfg' does not exist (not a camera)") #print("--- defines=%s"% str(args.defines)) #print("--- defines=%s"% str(args.defines)) #print("--- paths=%s"% str(args.paths)) #print("--- paths=%s"% str(args.paths)) #print("--- parameters=%s"% str(args.parameters)) #print("--- parameters=%s"% str(args.parameters)) Loading Loading @@ -259,12 +281,12 @@ USAGE if verbose > 3: print("vpars1.VERBOSE__TYPE="+str(vpars1.VERBOSE__TYPE)) if verbose > 3: print("vpars1.VERBOSE__TYPE="+str(vpars1.VERBOSE__TYPE)) if verbose > 3: print("vpars1.VERBOSE__RAW="+str(vpars1.VERBOSE__RAW)) if verbose > 3: print("vpars1.VERBOSE__RAW="+str(vpars1.VERBOSE__RAW)) x393mem= x393_mem.X393Mem(verbose,True) #add dry run parameter x393mem= x393_mem.X393Mem(verbose,args.simulated) #add dry run parameter x393tasks= x393_axi_control_status.X393AxiControlStatus(verbose,True) x393tasks= x393_axi_control_status.X393AxiControlStatus(verbose,args.simulated) x393Pio= x393_pio_sequences.X393PIOSequences(verbose,True) x393Pio= x393_pio_sequences.X393PIOSequences(verbose,args.simulated) x393Timing= x393_mcntrl_timing.X393McntrlTiming(verbose,True) x393Timing= x393_mcntrl_timing.X393McntrlTiming(verbose,args.simulated) x393Buffers=x393_mcntrl_buffers.X393McntrlBuffers(verbose,True) x393Buffers=x393_mcntrl_buffers.X393McntrlBuffers(verbose,args.simulated) x393Tests= x393_mcntrl_tests.X393McntrlTests(verbose,True) x393Tests= x393_mcntrl_tests.X393McntrlTests(verbose,args.simulated) ''' ''' print ("----------------------") print ("----------------------") print("x393_mem.__dict__="+str(x393_mem.__dict__)) print("x393_mem.__dict__="+str(x393_mem.__dict__)) Loading Loading @@ -315,23 +337,40 @@ USAGE if (args.interactive): if (args.interactive): line ="" line ="" while True: while True: line=raw_input('x393--> ').strip() line=raw_input('x393%s--> '%('','(simulated)')[args.simulated]).strip() if not line: if not line: print ('Use "quit" to exit, "help" - for help') print ('Use "quit" to exit, "help" - for help') elif line == 'quit': elif (line == 'quit') or (line == 'exit'): break break elif line== 'help' : elif line== 'help' : print ("\nAvailable tasks:") print ("\nAvailable tasks:") for name,val in sorted(callableTasks.items()): for name,val in sorted(callableTasks.items()): # funcFArgs=callableTasks[name]['args'] sFuncArgs=getFuncArgsString(name) funcFArgs=val['args'] sFuncArgs="" if funcFArgs: sFuncArgs+='<'+str(funcFArgs[0])+'>' for a in funcFArgs[1:]: sFuncArgs+=' <'+str(a)+'>' print ("Usage: %s %s"%(name,sFuncArgs)) print ("Usage: %s %s"%(name,sFuncArgs)) print ('\n"parameters" and "defines" list known defined parameters and macros') print ('\n"parameters" and "defines" list known defined parameters and macros') elif (len(line) > len("help")) and (line[:len("help")]=='help'): helpFilter=line[len('help'):].strip() try: re.match(helpFilter,"") except: print("Invalid search expression: %s"%helpFilter) helpFilter=None if helpFilter: print for name,val in sorted(callableTasks.items()): # if re.findall(helpFilter,name): if re.match(helpFilter,name): print('=== %s ==='%name) sFuncArgs=getFuncArgsString(name) # print ("Usage: %s %s"%(name,sFuncArgs)) docs=callableTasks[name]['docs'] if docs: docsl=docs.split("\n") for l in docsl: #print (' %s'%l) print ('%s'%l) #print(docs) print (" Usage: %s %s\n"%(name,sFuncArgs)) elif line == 'parameters': elif line == 'parameters': parameters=ivp.getParameters() parameters=ivp.getParameters() for par,val in sorted(parameters.items()): for par,val in sorted(parameters.items()): Loading
py393/x393_axi_control_status.py +81 −7 Original line number Original line Diff line number Diff line Loading @@ -65,8 +65,17 @@ class X393AxiControlStatus(object): ''' ''' def write_contol_register(self, reg_addr, data): def write_contol_register(self, reg_addr, data): """ Write 32-bit word to the control register <addr> - register address relative to the control register address space <data> - 32-bit data to write """ self.x393_mem.axi_write_single_w(self.CONTROL_ADDR+reg_addr, data) self.x393_mem.axi_write_single_w(self.CONTROL_ADDR+reg_addr, data) def read_and_wait_status(self, address): def read_and_wait_status(self, address): """ Read word from the status register (up to 26 bits payload and 6-bit sequence number) <addr> - status register address (currently 0..255) """ return self.x393_mem.axi_read_addr_w(self.STATUS_ADDR + address ) return self.x393_mem.axi_read_addr_w(self.STATUS_ADDR + address ) def wait_status_condition(self, def wait_status_condition(self, Loading @@ -77,6 +86,20 @@ class X393AxiControlStatus(object): mask, # input [25:0] mask; // which bits to compare mask, # input [25:0] mask; // which bits to compare invert_match, # input invert_match; // 0 - wait until match to pattern (all bits), 1 - wait until no match (any of bits differ) invert_match, # input invert_match; // 0 - wait until match to pattern (all bits), 1 - wait until no match (any of bits differ) wait_seq): # input wait_seq; // Wait for the correct sequence number, False assume correct wait_seq): # input wait_seq; // Wait for the correct sequence number, False assume correct """ Poll specified status register until some condition is matched <status_address> - status register address (currently 0..255) <status_control_address> - control register address (to control status generation) <status_mode> - status generation mode: 0: disable status generation, 1: single status request, 2: auto status, keep specified seq number, 4: auto, inc sequence number <pattern> - 26-bit pattern to match <mask> - 26-bit mask to enable pattern matching (0-s - ignore) <invert_match> - invert match (wait until matching condition becomes false) <wait_seq>- wait for the correct sequence number, if False - assume always correct """ match=False match=False while not match: while not match: data=self.read_and_wait_status(status_address) data=self.read_and_wait_status(status_address) Loading @@ -92,6 +115,9 @@ class X393AxiControlStatus(object): if self.DRY_MODE: break if self.DRY_MODE: break def read_all_status(self): def read_all_status(self): """ Read and print contents of all defined status registers """ # print (self.__dict__) # print (self.__dict__) # for name in self.__dict__: # for name in self.__dict__: # print (name+": "+str(name=='MCONTR_PHY_STATUS_REG_ADDR')) # print (name+": "+str(name=='MCONTR_PHY_STATUS_REG_ADDR')) Loading @@ -113,19 +139,33 @@ class X393AxiControlStatus(object): reg_addr, # input [7:0] reg_addr; reg_addr, # input [7:0] reg_addr; mode, # input [1:0] mode; mode, # input [1:0] mode; seq_number): # input [5:0] seq_number; seq_number): # input [5:0] seq_number; ''' """ // mode bits: Poll specified status register until some condition is matched // 0 disable status generation, <base_addr> - base control address of the selected module // 1 single status request, <reg_addr> - status control register relative to the module address space // 2 - auto status, keep specified seq number, <mode> - status generation mode: // 3 - auto, inc sequence number 0: disable status generation, ''' 1: single status request, 2: auto status, keep specified seq number, 4: auto, inc sequence number <seq_number> - 6-bit sequence number of the status message to be sent """ self.write_contol_register(base_addr + reg_addr, ((mode & 3)<< 6) | (seq_number * 0x3f)) self.write_contol_register(base_addr + reg_addr, ((mode & 3)<< 6) | (seq_number * 0x3f)) def program_status_all( self, def program_status_all( self, mode, # input [1:0] mode; mode, # input [1:0] mode; seq_num): # input [5:0] seq_num; seq_num): # input [5:0] seq_num; """ Set status generation mode for all defined modules <mode> - status generation mode: 0: disable status generation, 1: single status request, 2: auto status, keep specified seq number, 4: auto, inc sequence number <seq_number> - 6-bit sequence number of the status message to be sent """ self.program_status (self.MCONTR_PHY_16BIT_ADDR, self.MCONTR_PHY_STATUS_CNTRL, mode,seq_num)# //MCONTR_PHY_STATUS_REG_ADDR= 'h0, self.program_status (self.MCONTR_PHY_16BIT_ADDR, self.MCONTR_PHY_STATUS_CNTRL, mode,seq_num)# //MCONTR_PHY_STATUS_REG_ADDR= 'h0, self.program_status (self.MCONTR_TOP_16BIT_ADDR, self.MCONTR_TOP_16BIT_STATUS_CNTRL, mode,seq_num)# //MCONTR_TOP_STATUS_REG_ADDR= 'h1, self.program_status (self.MCONTR_TOP_16BIT_ADDR, self.MCONTR_TOP_16BIT_STATUS_CNTRL, mode,seq_num)# //MCONTR_TOP_STATUS_REG_ADDR= 'h1, self.program_status (self.MCNTRL_PS_ADDR, self.MCNTRL_PS_STATUS_CNTRL, mode,seq_num)# //MCNTRL_PS_STATUS_REG_ADDR= 'h2, self.program_status (self.MCNTRL_PS_ADDR, self.MCNTRL_PS_STATUS_CNTRL, mode,seq_num)# //MCNTRL_PS_STATUS_REG_ADDR= 'h2, Loading @@ -140,32 +180,61 @@ class X393AxiControlStatus(object): def enable_cmda(self, def enable_cmda(self, en): # input en; en): # input en; """ Enable (disable) address, bank and command lines to the DDR3 memory <en> - 1 - enable, 0 - disable """ self.write_contol_register(self.MCONTR_PHY_0BIT_ADDR + self.MCONTR_PHY_0BIT_CMDA_EN + en, 0); self.write_contol_register(self.MCONTR_PHY_0BIT_ADDR + self.MCONTR_PHY_0BIT_CMDA_EN + en, 0); def enable_cke(self, def enable_cke(self, en): # input en; en): # input en; """ Enable (disable) CKE - clock enable to DDR3 memory <en> - 1 - enable, 0 - disable """ self.write_contol_register(self.MCONTR_PHY_0BIT_ADDR + self.MCONTR_PHY_0BIT_CKE_EN + en, 0); self.write_contol_register(self.MCONTR_PHY_0BIT_ADDR + self.MCONTR_PHY_0BIT_CKE_EN + en, 0); def activate_sdrst(self, def activate_sdrst(self, en): # input en; en): # input en; """ Activate SDRST (reset) to DDR3 memory <en> - 1 - activate (low), 0 - deactivate (high) """ self.write_contol_register(self.MCONTR_PHY_0BIT_ADDR + self.MCONTR_PHY_0BIT_SDRST_ACT + en, 0); self.write_contol_register(self.MCONTR_PHY_0BIT_ADDR + self.MCONTR_PHY_0BIT_SDRST_ACT + en, 0); def enable_refresh(self, def enable_refresh(self, en): # input en; en): # input en; """ Enable (disable) refresh of the DDR3 memory <en> - 1 - enable, 0 - disable """ self.write_contol_register(self.MCONTR_TOP_0BIT_ADDR + self.MCONTR_TOP_0BIT_REFRESH_EN + en, 0); self.write_contol_register(self.MCONTR_TOP_0BIT_ADDR + self.MCONTR_TOP_0BIT_REFRESH_EN + en, 0); def enable_memcntrl(self, def enable_memcntrl(self, en): # input en; en): # input en; """ Enable memory controller module <en> - 1 - enable, 0 - disable """ self.write_contol_register(self.MCONTR_TOP_0BIT_ADDR + self.MCONTR_TOP_0BIT_MCONTR_EN + en, 0); self.write_contol_register(self.MCONTR_TOP_0BIT_ADDR + self.MCONTR_TOP_0BIT_MCONTR_EN + en, 0); def enable_memcntrl_channels(self, def enable_memcntrl_channels(self, chnen): # input [15:0] chnen; // bit-per-channel, 1 - enable; chnen): # input [15:0] chnen; // bit-per-channel, 1 - enable; """ Enable memory controller channels (all at once control) <chnen> - 16-bit control word with per-channel enable bits (bit0 - chn0, ... bit15 - chn15) """ self.enabled_channels = chnen; # currently enabled memory channels self.enabled_channels = chnen; # currently enabled memory channels self.write_contol_register(self.MCONTR_TOP_16BIT_ADDR + self.MCONTR_TOP_16BIT_CHN_EN, self.enabled_channels & 0xffff) # {16'b0,chnen}); self.write_contol_register(self.MCONTR_TOP_16BIT_ADDR + self.MCONTR_TOP_16BIT_CHN_EN, self.enabled_channels & 0xffff) # {16'b0,chnen}); def enable_memcntrl_en_dis(self, def enable_memcntrl_en_dis(self, chn, # input [3:0] chn; chn, # input [3:0] chn; en):# input en; en):# input en; """ Enable memory controller channels (one at a time) <chn> - 4-bit channel select <en> - 1 - enable, 0 - disable of the selected channel """ if en: if en: self.enabled_channels = self.enabled_channels | (1<<chn); self.enabled_channels = self.enabled_channels | (1<<chn); else: else: Loading @@ -175,5 +244,10 @@ class X393AxiControlStatus(object): def configure_channel_priority(self, def configure_channel_priority(self, chn, # input [ 3:0] chn; chn, # input [ 3:0] chn; priority): #input [15:0] priority; // (higher is more important) priority): #input [15:0] priority; // (higher is more important) """ Configure channel priority <chn> - 4-bit channel select <priority> - 16-bit priority value (higher value means more important) """ self.write_contol_register(self.MCONTR_ARBIT_ADDR + chn, priority & 0xffff)# {16'b0,priority}); self.write_contol_register(self.MCONTR_ARBIT_ADDR + chn, priority & 0xffff)# {16'b0,priority});
py393/x393_mcntrl_buffers.py +41 −1 Original line number Original line Diff line number Diff line Loading @@ -61,6 +61,15 @@ class X393McntrlBuffers(object): num_bursts, # input [NUM_XFER_BITS:0] num_bursts; // number of 8-bursts to write (will be rounded up to multiple of 16) num_bursts, # input [NUM_XFER_BITS:0] num_bursts; // number of 8-bursts to write (will be rounded up to multiple of 16) startX, # input integer startX; startX, # input integer startX; startY): #input integer startY; startY): #input integer startY; """ Fill buffer with the generated data in scanline mode <chn> 4-bit channel number (0,1,2,3,4 are valid) to use <page> 2-bit page number in the buffer to write to <num_bursts> number of 8-word (16 bytes) bursts to write <startX> horizontal shift of the left of the data line to write, in bytes <startY> line number to encode in the data """ if self.DEBUG_MODE > 1: print("====== write_block_scanline_chn:%d page: %x X=0x%x Y=0x%x num=%dt"%(chn, page, startX, startY,num_bursts)) print("====== write_block_scanline_chn:%d page: %x X=0x%x Y=0x%x num=%dt"%(chn, page, startX, startY,num_bursts)) if chn == 0: start_addr=self.MCONTR_BUF0_WR_ADDR + (page << 8) if chn == 0: start_addr=self.MCONTR_BUF0_WR_ADDR + (page << 8) elif chn == 1: start_addr=self.MCONTR_BUF1_WR_ADDR + (page << 8) elif chn == 1: start_addr=self.MCONTR_BUF1_WR_ADDR + (page << 8) Loading @@ -76,6 +85,11 @@ class X393McntrlBuffers(object): def write_block_buf(self, def write_block_buf(self, start_word_address, # input [29:0] start_word_address; start_word_address, # input [29:0] start_word_address; num_words_or_data_list): # input integer num_words; # number of words to write (will be rounded up to multiple of 16) num_words_or_data_list): # input integer num_words; # number of words to write (will be rounded up to multiple of 16) """ Fill buffer the pattern data <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 """ if isinstance (num_words_or_data_list,int): if isinstance (num_words_or_data_list,int): data=[] data=[] for i in range(num_words_or_data_list): for i in range(num_words_or_data_list): Loading @@ -94,6 +108,12 @@ class X393McntrlBuffers(object): start_word_address, # input [29:0] start_word_address; start_word_address, # input [29:0] start_word_address; num_words, # input integer num_words; # number of words to write (will be rounded up to multiple of 16) num_words, # input integer num_words; # number of words to write (will be rounded up to multiple of 16) start_value): # input integer start_value; start_value): # input integer start_value; """ Fill buffer the incremental data (each next register is written with previous register data + 1 <start_word_address> full register address in AXI space (in 32-bit words, not bytes) <num_words> number of 32-bit words to generate/write <start_value> value to write to the first register (to start_word_address) """ if self.verbose>0: if self.verbose>0: print("**** write_block_incremtal, start_word_address=0x%x, num_words=0x%x, start_value=0x%x "%(start_word_address,num_words,start_value)) print("**** write_block_incremtal, start_word_address=0x%x, num_words=0x%x, start_value=0x%x "%(start_word_address,num_words,start_value)) for i in range(0,num_words): for i in range(0,num_words): Loading @@ -105,6 +125,12 @@ class X393McntrlBuffers(object): chn, # input integer chn; # buffer channel chn, # input integer chn; # buffer channel page, # input [1:0] page; page, # input [1:0] page; num_words_or_data_list): # input integer num_words; # number of words to write (will be rounded up to multiple of 16) num_words_or_data_list): # input integer num_words; # number of words to write (will be rounded up to multiple of 16) """ Fill specified buffer with the pattern data <chn> 4-bit buffer channel (0..4) to write data to <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 """ start_addr=-1 start_addr=-1 if chn==0:start_addr=self.MCONTR_BUF0_WR_ADDR + (page << 8) if chn==0:start_addr=self.MCONTR_BUF0_WR_ADDR + (page << 8) elif chn==1:start_addr=self.MCONTR_BUF1_WR_ADDR + (page << 8) elif chn==1:start_addr=self.MCONTR_BUF1_WR_ADDR + (page << 8) Loading @@ -120,6 +146,13 @@ class X393McntrlBuffers(object): start_word_address, # input [29:0] start_word_address; start_word_address, # input [29:0] start_word_address; num_read, # input integer num_read; # number of words to read (will be rounded up to multiple of 16) num_read, # input integer num_read; # number of words to read (will be rounded up to multiple of 16) show_rslt=True): show_rslt=True): """ Fill buffer the incremental data (each next register is written with previous register data + 1 <start_word_address> full register address in AXI space (in 32-bit words, not bytes) <num_read> number of 32-bit words to read <show_rslt> print buffer data read """ if self.verbose>0: if self.verbose>0: print("**** read_block_buf, start_word_address=0x%x, num_read=0x%x "%(start_word_address,num_read)) print("**** read_block_buf, start_word_address=0x%x, num_read=0x%x "%(start_word_address,num_read)) result=[] result=[] Loading @@ -135,6 +168,13 @@ class X393McntrlBuffers(object): page, #input [1:0] page; page, #input [1:0] page; num_read, #input integer num_read; # number of words to read (will be rounded up to multiple of 16) num_read, #input integer num_read; # number of words to read (will be rounded up to multiple of 16) show_rslt=True): show_rslt=True): """ Fill buffer the incremental data (each next register is written with previous register data + 1 <chn> 4-bit buffer channel (0..4) to read from <page> 2-bit buffer page to read from <num_read> number of 32-bit words to read <show_rslt> print buffer data read """ start_addr=-1 start_addr=-1 if chn==0: start_addr=self.MCONTR_BUF0_RD_ADDR + (page << 8) if chn==0: start_addr=self.MCONTR_BUF0_RD_ADDR + (page << 8) elif chn==1: start_addr=self.MCONTR_BUF1_RD_ADDR + (page << 8) elif chn==1: start_addr=self.MCONTR_BUF1_RD_ADDR + (page << 8) Loading