Commit 63ff2819 authored by Andrey Filippov's avatar Andrey Filippov

working on Python code for hardware testing

parent 4c3995d6
...@@ -9,3 +9,4 @@ x393.prj ...@@ -9,3 +9,4 @@ x393.prj
*DEBUG_VDT* *DEBUG_VDT*
*.kate-swp *.kate-swp
*.old *.old
*.pyc
\ No newline at end of file
...@@ -35,7 +35,7 @@ ...@@ -35,7 +35,7 @@
input buf_rst; // connect to external buffer (but only if not paused) input buf_rst; // connect to external buffer (but only if not paused)
begin begin
func_encode_skip= func_encode_cmd ( func_encode_skip= func_encode_cmd (
{{14-CMD_DONE_BIT{1'b0}}, done, skip[CMD_PAUSE_BITS-1:0]}, // 15-bit row/column adderss {{14-CMD_DONE_BIT{1'b0}}, done, skip[CMD_PAUSE_BITS-1:0]}, // 15-bit row/column address
bank[2:0], // bank (here OK to be any) bank[2:0], // bank (here OK to be any)
3'b0, // RAS/CAS/WE, positive logic 3'b0, // RAS/CAS/WE, positive logic
odt_en, // enable ODT odt_en, // enable ODT
......
...@@ -21,7 +21,7 @@ ...@@ -21,7 +21,7 @@
// Low-level tasks // Low-level tasks
// alternative way to check for empty read queue (without a separate counter) // alternative way to check for empty read queue (without a separate counter)
task write_contol_register; task write_contol_register;
input [29:0] reg_addr; input [29:0] reg_addr;
// input integer reg_addr; // input integer reg_addr;
input [31:0] data; input [31:0] data;
......
eclipse.preferences.version=1 eclipse.preferences.version=1
encoding/import_verilog_parameters.py=utf-8 encoding/import_verilog_parameters.py=utf-8
encoding/test1.py=utf-8 encoding/test1.py=utf-8
encoding/test2.py=utf-8
...@@ -30,6 +30,18 @@ __status__ = "Development" ...@@ -30,6 +30,18 @@ __status__ = "Development"
import re import re
import os import os
import string import string
class VerilogParameters(object): #this is Borg
__shared_state = {}
def __init__(self, parameters=None):
self.__dict__ = self.__shared_state
if (parameters):
adict={}
for parName in parameters:
adict[parName]= parameters[parName][0]
adict[parName+"__TYPE"]=parameters[parName][1]
adict[parName+"__RAW"]= parameters[parName][2]
self.__dict__.update(adict)
class ImportVerilogParameters(object): class ImportVerilogParameters(object):
''' '''
classdocs classdocs
...@@ -38,6 +50,7 @@ class ImportVerilogParameters(object): ...@@ -38,6 +50,7 @@ class ImportVerilogParameters(object):
parameters={} parameters={}
conditions=[True] conditions=[True]
rootPath=None rootPath=None
verbose=1
''' '''
parameters - dictionalry of already known parameters, defines - defined macros parameters - dictionalry of already known parameters, defines - defined macros
''' '''
...@@ -47,6 +60,7 @@ class ImportVerilogParameters(object): ...@@ -47,6 +60,7 @@ class ImportVerilogParameters(object):
''' '''
if parameters: if parameters:
self.parameters=parameters.copy() self.parameters=parameters.copy()
self.parseRawParameters()
if defines: if defines:
self.defines=defines.copy() self.defines=defines.copy()
if rootPath: if rootPath:
...@@ -249,7 +263,8 @@ class ImportVerilogParameters(object): ...@@ -249,7 +263,8 @@ class ImportVerilogParameters(object):
Adds parsed parameters to the dictionary Adds parsed parameters to the dictionary
''' '''
def readParameterPortList(self,path,portMode=True): def readParameterPortList(self,path,portMode=True):
print ("readParameterPortList:Processing %s"%(path)) if (self.verbose>2):
print ("readParameterPortList:Processing %s"%(path))
with open (path, "r") as myfile: #with will close file when done with open (path, "r") as myfile: #with will close file when done
text=myfile.read() text=myfile.read()
# remove /* */ comments # remove /* */ comments
...@@ -339,13 +354,14 @@ class ImportVerilogParameters(object): ...@@ -339,13 +354,14 @@ class ImportVerilogParameters(object):
for line in preprocessedLines: for line in preprocessedLines:
if line[-1] == ";": if line[-1] == ";":
portMode=False portMode=False
print ("portMode is "+str(portMode)) if (self.verbose>2):
print ("portMode is "+str(portMode))
try: try:
if portMode and (preprocessedLines[0][0]==","): if portMode and (preprocessedLines[0][0]==","):
preprocessedLines.insert(0,preprocessedLines.pop(0)[1:]) preprocessedLines.insert(0,preprocessedLines.pop(0)[1:])
except: except:
pass if (self.verbose>2):
print("No preprocessed lines left") print("No preprocessed lines left")
while preprocessedLines: while preprocessedLines:
# print("A: len(preprocessedLines)=%d, first is %s"%(len(preprocessedLines),preprocessedLines[0])) # print("A: len(preprocessedLines)=%d, first is %s"%(len(preprocessedLines),preprocessedLines[0]))
line= preprocessedLines.pop(0) line= preprocessedLines.pop(0)
...@@ -480,18 +496,30 @@ class ImportVerilogParameters(object): ...@@ -480,18 +496,30 @@ class ImportVerilogParameters(object):
# process expression here, for now - just use expression string # process expression here, for now - just use expression string
ev= self.parseExpression(expLine) ev= self.parseExpression(expLine)
if ev is None: if ev is None:
self.parameters[parName]= (expLine,parType) self.parameters[parName]= (expLine,parType,expLine)
else: else:
if not parType: if not parType:
parType=ev[1] parType=ev[1]
# self.parameters[parName]= (ev[0],parType) # self.parameters[parName]= (ev[0],parType)
self.parameters[parName]= (ev[0],parType+" raw="+expLine) self.parameters[parName]= (ev[0],parType,expLine)
# if portMode: # while True: # if portMode: # while True:
if portMode or (termChar == ";"): # while True: if portMode or (termChar == ";"): # while True:
break; break;
# print ("======= Parameters =======") # print ("======= Parameters =======")
# for par in self.parameters: # for par in self.parameters:
# print (par+": "+self.parameters[par]) # print (par+": "+self.parameters[par])
def parseRawParameters(self):
for parName in self.parameters:
valTyp= self.parameters[parName]
if (not valTyp[1]) or (valTyp[1]=="RAW"):
ev= self.parseExpression(valTyp[0])
# print ("valTyp="+str(valTyp))
# print ("ev="+str(ev))
if ev:
self.parameters[parName]= (ev[0],ev[1],valTyp[0])
if parName == "VERBOSE":
self.verbose=ev[0]
''' '''
get parameter dictionary get parameter dictionary
''' '''
......
...@@ -38,6 +38,7 @@ from argparse import ArgumentParser ...@@ -38,6 +38,7 @@ from argparse import ArgumentParser
from argparse import RawDescriptionHelpFormatter from argparse import RawDescriptionHelpFormatter
from import_verilog_parameters import ImportVerilogParameters from import_verilog_parameters import ImportVerilogParameters
from import_verilog_parameters import VerilogParameters
__all__ = [] __all__ = []
__version__ = 0.1 __version__ = 0.1
__date__ = '2015-03-01' __date__ = '2015-03-01'
...@@ -89,41 +90,36 @@ def main(argv=None): # IGNORE:C0111 ...@@ -89,41 +90,36 @@ def main(argv=None): # IGNORE:C0111
USAGE USAGE
''' % (program_shortdesc, __author__,str(__date__)) ''' % (program_shortdesc, __author__,str(__date__))
preDefines={}
# parser = argparse.ArgumentParser() preParameters={}
# parser = ArgumentParser()
'''
parser = ArgumentParser(description=program_license, formatter_class=RawDescriptionHelpFormatter)
parser.add_argument("-v", "--verbose", dest="verbose", action="count", help="set verbosity level [default: %(default)s]")
parser.add_argument('-V', '--version', action='version', version=program_version_message)
parser.add_argument(dest="paths", help="Verilog include files with parameter definitions [default: %(default)s]", metavar="path", nargs='+')
args = parser.parse_args()
#print argv
print args
print ("***1.25")
return
'''
ivp= ImportVerilogParameters (None,None)
try: try:
# Setup argument parser # Setup argument parser
parser = ArgumentParser(description=program_license, formatter_class=RawDescriptionHelpFormatter) parser = ArgumentParser(description=program_license, formatter_class=RawDescriptionHelpFormatter)
parser.add_argument("-v", "--verbose", dest="verbose", action="count", help="set verbosity level [default: %(default)s]") parser.add_argument("-v", "--verbose", dest="verbose", action="count", help="set verbosity level [default: %(default)s]")
parser.add_argument('-V', '--version', action='version', version=program_version_message) parser.add_argument('-V', '--version', action='version', version=program_version_message)
parser.add_argument(dest="paths", help="Verilog include files with parameter definitions [default: %(default)s]", metavar="path", nargs='+') parser.add_argument( dest="paths", help="Verilog include files with parameter definitions [default: %(default)s]", metavar="path", nargs='*')
parser.add_argument("-d", "--define", dest="defines", action="append", help="Define macro(s)" )
parser.add_argument("-p", "--parameter", dest="parameters", action="append", help="Define parameter(s) as name=value" )
# Process arguments # Process arguments
args = parser.parse_args() args = parser.parse_args()
paths = args.paths paths = args.paths
verbose = args.verbose verbose = args.verbose
if args.defines:
for predef in args.defines:
kv=predef.split("=")
if len(kv)<2:
kv.append("")
preDefines[kv[0].strip("`")]=kv[1]
if verbose > 0: if verbose > 0:
print("Verbose mode on") # print("Verbose mode on "+hex(verbose))
# if inpat and expat and inpat == expat: args.parameters.append('VERBOSE=%d'%verbose) # add as verilog parameter
# raise CLIError("include and exclude pattern are equal! Nothing will be processed.") if args.parameters:
for prePars in args.parameters:
# for path in paths: kv=prePars.split("=")
# ### do something with inpath ### if len(kv)>1:
# ivp.readParameterPortList(path) preParameters[kv[0]]=(kv[1],"RAW",kv[1]) # todo - need to go through the parser
# return 0
except KeyboardInterrupt: except KeyboardInterrupt:
### handle keyboard interrupt ### ### handle keyboard interrupt ###
return 0 return 0
...@@ -134,23 +130,34 @@ USAGE ...@@ -134,23 +130,34 @@ USAGE
sys.stderr.write(program_name + ": " + repr(e) + "\n") sys.stderr.write(program_name + ": " + repr(e) + "\n")
sys.stderr.write(indent + " for help use --help") sys.stderr.write(indent + " for help use --help")
return 2 return 2
# Take out from the try/except for debugging # Take out from the try/except for debugging
ivp= ImportVerilogParameters(preParameters,preDefines)
for path in paths: for path in paths:
### do something with inpath ### ### do something with inpath ###
ivp.readParameterPortList(path) ivp.readParameterPortList(path)
defines= ivp.getDefines()
print ("======= Extracted defines =======")
for macro in defines:
print ("`"+macro+": "+defines[macro])
parameters=ivp.getParameters() parameters=ivp.getParameters()
print ("======= Parameters =======") vpars=VerilogParameters(parameters)
for par in parameters: if verbose > 3:
try: defines= ivp.getDefines()
print (par+" = "+hex(parameters[par][0])+" (type = "+parameters[par][1]+")") print ("======= Extracted defines =======")
except: for macro in defines:
print (par+" = "+str(parameters[par][0])+" (type = "+parameters[par][1]+")") print ("`"+macro+": "+defines[macro])
print ("======= Parameters =======")
for par in parameters:
try:
print (par+" = "+hex(parameters[par][0])+" (type = "+parameters[par][1]+" raw = "+parameters[par][2]+")")
except:
print (par+" = "+str(parameters[par][0])+" (type = "+parameters[par][1]+" raw = "+parameters[par][2]+")")
print("vpars.VERBOSE="+str(vpars.VERBOSE))
print("vpars.VERBOSE__TYPE="+str(vpars.VERBOSE__TYPE))
print("vpars.VERBOSE__RAW="+str(vpars.VERBOSE__RAW))
print (VerilogParameters.__dict__)
vpars1=VerilogParameters()
print("vpars1.VERBOSE="+str(vpars1.VERBOSE))
print("vpars1.VERBOSE__TYPE="+str(vpars1.VERBOSE__TYPE))
print("vpars1.VERBOSE__RAW="+str(vpars1.VERBOSE__RAW))
return 0 return 0
...@@ -158,7 +165,6 @@ if __name__ == "__main__": ...@@ -158,7 +165,6 @@ if __name__ == "__main__":
if DEBUG: if DEBUG:
# sys.argv.append("-h") # sys.argv.append("-h")
sys.argv.append("-v") sys.argv.append("-v")
# sys.argv.append("-r")
if TESTRUN: if TESTRUN:
import doctest import doctest
doctest.testmod() doctest.testmod()
......
'''
# Copyright (C) 2015, Elphel.inc.
# Memory read/write functions
# 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 <http://www.gnu.org/licenses/>.
@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"
from __future__ import print_function
#import sys
#import x393_mem
from import_verilog_parameters import VerilogParameters
from x393_mem import X393Mem
#MCNTRL_TEST01_CHN4_STATUS_CNTRL=0
class X393AxiControlStatus(object):
DRY_MODE= False # True
DEBUG_MODE=1
# vpars=None
x393_mem=None
target_phase=0 # TODO: set!
def __init__(self, debug_mode=1,dry_mode=False):
self.DEBUG_MODE=debug_mode
self.DRY_MODE=dry_mode
# self.vpars=VerilogParameters()
self.x393_mem=X393Mem(debug_mode,dry_mode)
self.__dict__.update(VerilogParameters.__dict__) # Add verilog parameters to the class namespace
'''
Maybe import parameters into the module, not class namespace to use directly, w/o self. ?
# __dict__.update(VerilogParameters.__dict__) # Add verilog parameters to the class namespace
'''
def write_contol_register(self, reg_addr, data):
self.x393_mem.axi_write_single_w(self.CONTROL_ADDR+reg_addr, data)
def read_and_wait_status(self, address):
return self.x393_mem.axi_read_addr_w(self.STATUS_ADDR + address )
def wait_status_condition(self,
status_address, # input [STATUS_DEPTH-1:0] status_address;
status_control_address, # input [29:0] status_control_address;
status_mode, # input [1:0] status_mode;
pattern, # input [25:0] pattern; // bits as in read registers
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)
wait_seq): # input wait_seq; // Wait for the correct sequence number, False assume correct
match=False
while not match:
data=self.read_and_wait_status(status_address)
if wait_seq:
seq_num = ((data >> self.STATUS_SEQ_SHFT) ^ 0x20) & 0x30
data=self.read_and_wait_status(status_address)
while (((data >> self.STATUS_SEQ_SHFT) ^ seq_num) & 0x30) !=0:
data=self.read_and_wait_status(status_address)
match = (((data ^ pattern) & mask & 0x3ffffff)==0)
if invert_match:
match = not match
def wait_phase_shifter_ready(self):
data=self.read_and_wait_status(self.MCONTR_PHY_STATUS_REG_ADDR)
while (((data & self.STATUS_PSHIFTER_RDY_MASK) == 0) or (((data ^ self.target_phase) & 0xff) != 0)):
data=self.read_and_wait_status(self.MCONTR_PHY_STATUS_REG_ADDR)
def read_all_status(self):
print ("MCONTR_PHY_STATUS_REG_ADDR: 0x%x"%(self.read_and_wait_status(self.MCONTR_PHY_STATUS_REG_ADDR)))
print ("MCONTR_TOP_STATUS_REG_ADDR: 0x%x"%(self.read_and_wait_status(self.MCONTR_TOP_STATUS_REG_ADDR)))
print ("MCNTRL_PS_STATUS_REG_ADDR: 0x%x"%(self.read_and_wait_status(self.MCNTRL_PS_STATUS_REG_ADDR)))
print ("MCNTRL_SCANLINE_STATUS_REG_CHN1_ADDR:0x%x"%(self.read_and_wait_status(self.MCNTRL_SCANLINE_STATUS_REG_CHN1_ADDR)))
print ("MCNTRL_SCANLINE_STATUS_REG_CHN3_ADDR:0x%x"%(self.read_and_wait_status(self.MCNTRL_SCANLINE_STATUS_REG_CHN3_ADDR)))
print ("MCNTRL_TILED_STATUS_REG_CHN2_ADDR: 0x%x"%(self.read_and_wait_status(self.MCNTRL_TILED_STATUS_REG_CHN2_ADDR)))
print ("MCNTRL_TILED_STATUS_REG_CHN4_ADDR: 0x%x"%(self.read_and_wait_status(self.MCNTRL_TILED_STATUS_REG_CHN4_ADDR)))
print ("MCNTRL_TEST01_STATUS_REG_CHN1_ADDR: 0x%x"%(self.read_and_wait_status(self.MCNTRL_TEST01_STATUS_REG_CHN1_ADDR)))
print ("MCNTRL_TEST01_STATUS_REG_CHN2_ADDR: 0x%x"%(self.read_and_wait_status(self.MCNTRL_TEST01_STATUS_REG_CHN2_ADDR)))
print ("MCNTRL_TEST01_STATUS_REG_CHN3_ADDR: 0x%x"%(self.read_and_wait_status(self.MCNTRL_TEST01_STATUS_REG_CHN3_ADDR)))
print ("MCNTRL_TEST01_STATUS_REG_CHN4_ADDR: 0x%x"%(self.read_and_wait_status(self.MCNTRL_TEST01_STATUS_REG_CHN4_ADDR)))
def program_status(self,
base_addr, # input [29:0] base_addr;
reg_addr, # input [7:0] reg_addr;
mode, # input [1:0] mode;
seq_number): # input [5:0] seq_number;
'''
// mode bits:
// 0 disable status generation,
// 1 single status request,
// 2 - auto status, keep specified seq number,
// 3 - auto, inc sequence number
'''
self.write_contol_register(base_addr + reg_addr, ((mode & 3)<< 6) | (seq_number * 0x3f))
def program_status_all( self,
mode, # input [1:0] mode;
seq_num): # input [5:0] seq_num;
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.MCNTRL_PS_ADDR, self.MCNTRL_PS_STATUS_CNTRL, mode,seq_num)# //MCNTRL_PS_STATUS_REG_ADDR= 'h2,
self.program_status (self.MCNTRL_SCANLINE_CHN1_ADDR, self.MCNTRL_SCANLINE_STATUS_CNTRL, mode,seq_num)#; //MCNTRL_SCANLINE_STATUS_REG_CHN2_ADDR='h4,
self.program_status (self.MCNTRL_SCANLINE_CHN3_ADDR, self.MCNTRL_SCANLINE_STATUS_CNTRL, mode,seq_num)# //MCNTRL_SCANLINE_STATUS_REG_CHN3_ADDR='h5,
self.program_status (self.MCNTRL_TILED_CHN2_ADDR, self.MCNTRL_TILED_STATUS_CNTRL, mode,seq_num)# //MCNTRL_TILED_STATUS_REG_CHN4_ADDR= 'h6,
self.program_status (self.MCNTRL_TILED_CHN4_ADDR, self.MCNTRL_TILED_STATUS_CNTRL, mode,seq_num)#; //MCNTRL_TILED_STATUS_REG_CHN4_ADDR= 'h6,
self.program_status (self.MCNTRL_TEST01_ADDR, self.MCNTRL_TEST01_CHN1_STATUS_CNTRL,mode,seq_num)#; //MCNTRL_TEST01_STATUS_REG_CHN2_ADDR= 'h3c,
self.program_status (self.MCNTRL_TEST01_ADDR, self.MCNTRL_TEST01_CHN2_STATUS_CNTRL,mode,seq_num)#; //MCNTRL_TEST01_STATUS_REG_CHN2_ADDR= 'h3c,
self.program_status (self.MCNTRL_TEST01_ADDR, self.MCNTRL_TEST01_CHN3_STATUS_CNTRL,mode,seq_num)#; //MCNTRL_TEST01_STATUS_REG_CHN3_ADDR= 'h3d,
self.program_status (self.MCNTRL_TEST01_ADDR, self.MCNTRL_TEST01_CHN4_STATUS_CNTRL,mode,seq_num)#; //MCNTRL_TEST01_STATUS_REG_CHN4_ADDR= 'h3e,
'''
x393_tasks_ps_pio
'''
def schedule_ps_pio(self, #; // shedule software-control memory operation (may need to check FIFO status first)
seq_addr, # input [9:0] seq_addr; // sequence start address
page, # input [1:0] page; // buffer page number
urgent, # input urgent; // high priority request (only for competion wityh other channels, wiil not pass in this FIFO)
chn, # input chn; // channel buffer to use: 0 - memory read, 1 - memory write
wait_complete): # input wait_complete; // Do not request a newe transaction from the scheduler until previous memory transaction is finished
self.write_contol_register(self.MCNTRL_PS_ADDR + self.MCNTRL_PS_CMD,
# {17'b0,
((0,1)[wait_complete]<<14) |
((0,1)[chn]<<13) |
((0,1)[urgent]<<12) |
((page & 3) << 10) |
(seq_addr & 0x3ff))
def wait_ps_pio_ready(self, #; // wait PS PIO module can accept comamnds (fifo half empty)
mode, # input [1:0] mode;
sync_seq): # input sync_seq; // synchronize sequences
self.wait_status_condition (
self.MCNTRL_PS_STATUS_REG_ADDR,
self.MCNTRL_PS_ADDR + self.MCNTRL_PS_STATUS_CNTRL,
mode & 3,
0,
2 << self.STATUS_2LSB_SHFT,
0,
sync_seq)
def wait_ps_pio_done(self, # // wait PS PIO module has no pending/running memory transaction
mode, # input [1:0] mode;
sync_seq): # input sync_seq; // synchronize sequences
self.wait_status_condition (
self.MCNTRL_PS_STATUS_REG_ADDR,
self.MCNTRL_PS_ADDR + self.MCNTRL_PS_STATUS_CNTRL,
mode & 3,
0,
3 << self.STATUS_2LSB_SHFT,
0,
sync_seq)
'''
x393_mcontr_encode_cmd
'''
def func_encode_cmd(self, # function [31:0]
addr, # input [14:0] addr; // 15-bit row/column adderss
bank, # input [2:0] bank; // bank (here OK to be any)
rcw, # input [2:0] rcw; // RAS/CAS/WE, positive logic
odt_en, # input odt_en; // enable ODT
cke, # input cke; // disable CKE
sel, # input sel; // first/second half-cycle, other will be nop (cke+odt applicable to both)
dq_en, # input dq_en; // enable (not tristate) DQ lines (internal timing sequencer for 0->1 and 1->0)
dqs_en, # input dqs_en; // enable (not tristate) DQS lines (internal timing sequencer for 0->1 and 1->0)
dqs_toggle,# input dqs_toggle; // enable toggle DQS according to the pattern
dci, # input dci; // DCI disable, both DQ and DQS lines (internal logic and timing sequencer for 0->1 and 1->0)
buf_wr, # input buf_wr; // connect to external buffer (but only if not paused)
buf_rd, # input buf_rd; // connect to external buffer (but only if not paused)
nop, # input nop; // add NOP after the current command, keep other data
buf_rst): # input buf_rst; // connect to external buffer (but only if not paused)
return (
((addr & 0x7fff) << 17) | # addr[14:0], // 15-bit row/column adderss
((bank & 0x7) << 14) | # bank [2:0], // bank
((rcw & 0x7) << 11) | # rcw[2:0], // RAS/CAS/WE
((0,1)[odt_en] << 10) | # odt_en, // enable ODT
((0,1)[cke] << 9) | # cke, // may be optimized (removed from here)?
((0,1)[sel] << 8) | # sel, // first/second half-cycle, other will be nop (cke+odt applicable to both)
((0,1)[dq_en] << 7) | # dq_en, // enable (not tristate) DQ lines (internal timing sequencer for 0->1 and 1->0)
((0,1)[dqs_en] << 6) | # dqs_en, // enable (not tristate) DQS lines (internal timing sequencer for 0->1 and 1->0)
((0,1)[dqs_toggle]<< 5) | # dqs_toggle, // enable toggle DQS according to the pattern
((0,1)[dci] << 4) | # dci, // DCI disable, both DQ and DQS lines (internal logic and timing sequencer for 0->1 and 1->0)
((0,1)[buf_wr] << 3) | # buf_wr, // phy_buf_wr, // connect to external buffer (but only if not paused)
((0,1)[buf_rd] << 2) | # buf_rd, // phy_buf_rd, // connect to external buffer (but only if not paused)
((0,1)[nop] << 1) | # nop, // add NOP after the current command, keep other data
((0,1)[buf_rst] << 0) # buf_rst // Reset buffer address/ increase buffer page
)
def func_encode_skip(self, # function [31:0]
skip, # input [CMD_PAUSE_BITS-1:0] skip; // number of extra cycles to skip (and keep all the other outputs)
done, # input done; // end of sequence
bank, # input [2:0] bank; // bank (here OK to be any)
odt_en, # input odt_en; // enable ODT
cke, # input cke; // disable CKE
sel, # input sel; // first/second half-cycle, other will be nop (cke+odt applicable to both)
dq_en, # input dq_en; // enable (not tristate) DQ lines (internal timing sequencer for 0->1 and 1->0)
dqs_en, # input dqs_en; // enable (not tristate) DQS lines (internal timing sequencer for 0->1 and 1->0)
dqs_toggle, # input dqs_toggle; // enable toggle DQS according to the pattern
dci, # input dci; // DCI disable, both DQ and DQS lines (internal logic and timing sequencer for 0->1 and 1->0)
buf_wr, # input buf_wr; // connect to external buffer (but only if not paused)
buf_rd, # input buf_rd; // connect to external buffer (but only if not paused)
buf_rst): #input buf_rst; // connect to external buffer (but only if not paused)
return self.func_encode_cmd (
((0,1)[done] << self.CMD_PAUSE_BITS) | # {{14-CMD_DONE_BIT{1'b0}}, done,
(skip & ((1 << self.CMD_PAUSE_BITS)-1)), # skip[CMD_PAUSE_BITS-1:0]}, // 15-bit row/column address
bank & 7, # bank[2:0], // bank (here OK to be any)
0, # 3'b0, // RAS/CAS/WE, positive logic
odt_en, #// enable ODT
cke, #// disable CKE
sel, #// first/second half-cycle, other will be nop (cke+odt applicable to both)
dq_en, #// enable (not tristate) DQ lines (internal timing sequencer for 0->1 and 1->0)
dqs_en, #// enable (not tristate) DQS lines (internal timing sequencer for 0->1 and 1->0)
dqs_toggle, #// enable toggle DQS according to the pattern
dci, #// DCI disable, both DQ and DQS lines (internal logic and timing sequencer for 0->1 and 1->0)
buf_wr, #// connect to external buffer (but only if not paused)
buf_rd, #// connect to external buffer (but only if not paused)
0, # 1'b0, // nop
buf_rst) #
'''
x393_tasks_pio_sequences
'''
'''
vpars1=VerilogParameters()
print("vpars1.VERBOSE="+str(vpars1.VERBOSE))
print("vpars1.VERBOSE__TYPE="+str(vpars1.VERBOSE__TYPE))
print("vpars1.VERBOSE__RAW="+str(vpars1.VERBOSE__RAW))
'''
\ No newline at end of file
'''
# Copyright (C) 2015, Elphel.inc.
# Memory read/write functions
# 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 <http://www.gnu.org/licenses/>.
@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"
from __future__ import print_function
import mmap
#import sys
import struct
class X393Mem(object):
'''
classdocs
'''
DRY_MODE= False # True
PAGE_SIZE=4096
DEBUG_MODE=1
ENDIAN="<" # little, ">" for big
AXI_SLAVE0_BASE=0x40000000
def __init__(self, debug_mode=1,dry_mode=False):
self.DEBUG_MODE=debug_mode
self.DRY_MODE=dry_mode
def write_mem (self,addr, data):
if self.DRY_MODE:
print ("write_mem(0x%x,0x%x)"%(addr,data))
return
with open("/dev/mem", "r+b") as f:
page_addr=addr & (~(self.PAGE_SIZE-1))
page_offs=addr-page_addr
if (page_addr>=0x80000000):
page_addr-= (1<<32)
mm = mmap.mmap(f.fileno(), self.PAGE_SIZE, offset=page_addr)
packedData=struct.pack(self.ENDIAN+"L",data)
d=struct.unpack(self.ENDIAN+"L",packedData)[0]
mm[page_offs:page_offs+4]=packedData
if self.DEBUG_MODE > 2:
print ("0x%08x <== 0x%08x (%d)"%(addr,d,d))
mm.close()
'''
if MONITOR_EMIO and VEBOSE:
gpio0=read_mem (0xe000a068)
gpio1=read_mem (0xe000a06c)
print("GPIO: %04x %04x %04x %04x"%(gpio1>>16, gpio1 & 0xffff, gpio0>>16, gpio0 & 0xffff))
if ((gpio0 & 0xc) != 0xc) or ((gpio0 & 0xff00) != 0):
print("******** AXI STUCK ************")
exit (0)
'''
def read_mem (self,addr):
if self.DRY_MODE:
print ("read_mem(0x%x)"%(addr))
return
with open("/dev/mem", "r+b") as f:
page_addr=addr & (~(self.PAGE_SIZE-1))
page_offs=addr-page_addr
if (page_addr>=0x80000000):
page_addr-= (1<<32)
mm = mmap.mmap(f.fileno(), self.PAGE_SIZE, offset=page_addr)
data=struct.unpack(self.ENDIAN+"L",mm[page_offs:page_offs+4])
d=data[0]
if self.DEBUG_MODE > 2:
print ("0x%08x ==> 0x%08x (%d)"%(addr,d,d))
return d
# mm.close() #probably not needed with "with"
'''
Read/write slave AXI using byte addresses relative to the AXI memory reagion
'''
def axi_write_single(self,addr,data):
self.write_mem(self.AXI_SLAVE0_BASE+addr,data)
def axi_read_addr(self,addr):
return self.read_mem(self.AXI_SLAVE0_BASE+addr)
'''
Read/write slave AXI using 32-bit word addresses (same as in Verilog code)
'''
def axi_write_single_w(self,addr,data):
self.axi_write_single(addr<<2,data)
def axi_read_addr_w(self,addr):
return self.axi_read_addr(addr<<2)
\ No newline at end of file
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