from __future__ import print_function ''' # Copyright (C) 2015, Elphel.inc. # Methods that mimic Verilog tasks used for simulation # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . @author: Andrey Filippov @copyright: 2015 Elphel, Inc. @license: GPLv3.0+ @contact: andrey@elphel.coml @deffield updated: Updated ''' __author__ = "Andrey Filippov" __copyright__ = "Copyright 2015, Elphel, Inc." __license__ = "GPL" __version__ = "3.0+" __maintainer__ = "Andrey Filippov" __email__ = "andrey@elphel.com" __status__ = "Development" #import sys #import x393_mem #x393_pio_sequences #from import_verilog_parameters import VerilogParameters from x393_mem import X393Mem #from x393_axi_control_status import X393AxiControlStatus import x393_axi_control_status from verilog_utils import convert_w32_to_mem16 #,convert_mem16_to_w32 import vrlg class X393McntrlBuffers(object): DRY_MODE= True # True DEBUG_MODE=1 # vpars=None x393_mem=None x393_axi_tasks=None #x393X393AxiControlStatus verbose=1 def __init__(self, debug_mode=1,dry_mode=True): self.DEBUG_MODE=debug_mode self.DRY_MODE=dry_mode self.x393_mem=X393Mem(debug_mode,dry_mode) # self.x393_axi_tasks=X393AxiControlStatus(debug_mode,dry_mode) self.x393_axi_tasks=x393_axi_control_status.X393AxiControlStatus(debug_mode,dry_mode) # self.__dict__.update(VerilogParameters.__dict__["_VerilogParameters__shared_state"]) # Add verilog parameters to the class namespace try: self.verbose=vrlg.VERBOSE except: pass def write_block_scanline_chn(self, # chn, # input [3:0] chn; // buffer channel page, # input [1:0] page; 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; startY): #input integer startY; """ Fill buffer with the generated data in scanline mode 4-bit channel number (0,1,2,3,4 are valid) to use 2-bit page number in the buffer to write to number of 8-word (16 bytes) bursts to write horizontal shift of the left of the data line to write, in bytes 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)) if chn == 0: start_addr=vrlg.MCONTR_BUF0_WR_ADDR + (page << 8) # elif chn == 1: start_addr=vrlg.MCONTR_BUF1_WR_ADDR + (page << 8) elif chn == 2: start_addr=vrlg.MCONTR_BUF2_WR_ADDR + (page << 8) elif chn == 3: start_addr=vrlg.MCONTR_BUF3_WR_ADDR + (page << 8) elif chn == 4: start_addr=vrlg.MCONTR_BUF4_WR_ADDR + (page << 8) else: print("**** ERROR: Invalid channel for write_block_scanline_chn = %d"% chn) start_addr = vrlg.MCONTR_BUF0_WR_ADDR+ (page << 8); num_words=num_bursts << 2; self.write_block_incremtal (start_addr, num_words, (startX<<2) + (startY<<16));# 1 of startX is 8x16 bit, 16 bytes or 4 32-bit words def write_block_buf(self, 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) """ Fill buffer the pattern data full register address in AXI space (in 32-bit words, not bytes) 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,long)): data=[] for i in range(num_words_or_data_list): 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) 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) def write_block_incremtal(self, 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) start_value, # input integer start_value; quiet=1): """ Fill buffer the incremental data (each next register is written with previous register data + 1 @param start_word_address full register address in AXI space (in 32-bit words, not bytes) @param num_words number of 32-bit words to generate/write @start_value value to write to the first register (to start_word_address) """ if quiet < 2: 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): if quiet < 1: print(" write_block_buf 0x%x:0x%x"%(start_word_address+i,start_value+i)) self.x393_mem.axi_write_single_w(start_word_address+i, start_value+i) def write_block_buf_chn(self, # chn, # input integer chn; # buffer channel 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) quiet = 1): """ Fill specified buffer with the pattern data @param chn 4-bit buffer channel (0..4) to write data to @param page 2-bit buffer page to write to @param num_words_or_data_list> number of 32-bit words to generate/write or a list with integer data @param quiet reduce output """ if quiet < 2: 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=vrlg.MCONTR_BUF0_WR_ADDR + (page << 8) # elif chn==1:start_addr=vrlg.MCONTR_BUF1_WR_ADDR + (page << 8) elif chn==2:start_addr=vrlg.MCONTR_BUF2_WR_ADDR + (page << 8) elif chn==3:start_addr=vrlg.MCONTR_BUF3_WR_ADDR + (page << 8) elif chn==4:start_addr=vrlg.MCONTR_BUF4_WR_ADDR + (page << 8) else: print("**** ERROR: Invalid channel for write buffer = %d"% chn) start_addr = vrlg.MCONTR_BUF0_WR_ADDR+ (page << 8) self.write_block_buf (start_addr, num_words_or_data_list) def read_block_buf(self, 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) show_rslt=True): """ Fill buffer the incremental data (each next register is written with previous register data + 1 @param start_word_address full register address in AXI space (in 32-bit words, not bytes) @param num_read number of 32-bit words to read @param show_rslt print buffer data read 1 - column, 16 - as 16-bit (memory words), 32 - as 32-bit (data words) """ if (self.verbose>1) or (show_rslt==1): 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 d=self.x393_mem.axi_read_addr_w(start_word_address+i) if (self.verbose>2) or (show_rslt==1): print(" read_block_buf 0x%x:0x%x"%(start_word_address+i,d)) result.append(d) if show_rslt==16: rslt16=convert_w32_to_mem16(result) sum_read16=0 for d in rslt16: sum_read16+=d print("read16 (0x%x):"%(sum_read16),end="") for i in range(len(rslt16)): if (i & 0x1f) == 0: print("\n%03x:"%i,end=" ") print("%04x"%rslt16[i],end=" ") print("\n") elif show_rslt==32: sum_rd_buf=0 for d in result: sum_rd_buf+=d print("read buffer: (0x%x):"%(sum_rd_buf),end="") for i in range(len(result)): if (i & 0xf) == 0: print("\n%03x:"%i,end=" ") print("%08x"%result[i],end=" ") print("\n") return result def read_block_buf_chn(self, # S uppressThisWarning VEditor : may be unused chn, # input [3:0] chn; # buffer channel page, #input [1:0] page; num_read, #input integer num_read; # number of words to read (will be rounded up to multiple of 16) show_rslt=True): """ Fill buffer the incremental data (each next register is written with previous register data + 1 @param chn 4-bit buffer channel (0..4) to read from @param page 2-bit buffer page to read from @param num_read number of 32-bit words to read @param show_rslt print buffer data read 1 - column, 16 - as 16-bit (memory words), 32 - as 32-bit (data words) """ start_addr=-1 if chn==0: start_addr=vrlg.MCONTR_BUF0_RD_ADDR + (page << 8) elif chn==2: start_addr=vrlg.MCONTR_BUF2_RD_ADDR + (page << 8) elif chn==3: start_addr=vrlg.MCONTR_BUF3_RD_ADDR + (page << 8) elif chn==4: start_addr=vrlg.MCONTR_BUF4_RD_ADDR + (page << 8) else: print("**** ERROR: Invalid channel for read buffer = %d"%chn) start_addr = vrlg.MCONTR_BUF0_RD_ADDR+ (page << 8) result=self.read_block_buf (start_addr, num_read, show_rslt) return result