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
*DEBUG_VDT*
*.kate-swp
*.old
*.pyc
\ No newline at end of file
......@@ -35,7 +35,7 @@
input buf_rst; // connect to external buffer (but only if not paused)
begin
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)
3'b0, // RAS/CAS/WE, positive logic
odt_en, // enable ODT
......
eclipse.preferences.version=1
encoding/import_verilog_parameters.py=utf-8
encoding/test1.py=utf-8
encoding/test2.py=utf-8
......@@ -30,6 +30,18 @@ __status__ = "Development"
import re
import os
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):
'''
classdocs
......@@ -38,6 +50,7 @@ class ImportVerilogParameters(object):
parameters={}
conditions=[True]
rootPath=None
verbose=1
'''
parameters - dictionalry of already known parameters, defines - defined macros
'''
......@@ -47,6 +60,7 @@ class ImportVerilogParameters(object):
'''
if parameters:
self.parameters=parameters.copy()
self.parseRawParameters()
if defines:
self.defines=defines.copy()
if rootPath:
......@@ -249,6 +263,7 @@ class ImportVerilogParameters(object):
Adds parsed parameters to the dictionary
'''
def readParameterPortList(self,path,portMode=True):
if (self.verbose>2):
print ("readParameterPortList:Processing %s"%(path))
with open (path, "r") as myfile: #with will close file when done
text=myfile.read()
......@@ -339,12 +354,13 @@ class ImportVerilogParameters(object):
for line in preprocessedLines:
if line[-1] == ";":
portMode=False
if (self.verbose>2):
print ("portMode is "+str(portMode))
try:
if portMode and (preprocessedLines[0][0]==","):
preprocessedLines.insert(0,preprocessedLines.pop(0)[1:])
except:
pass
if (self.verbose>2):
print("No preprocessed lines left")
while preprocessedLines:
# print("A: len(preprocessedLines)=%d, first is %s"%(len(preprocessedLines),preprocessedLines[0]))
......@@ -480,18 +496,30 @@ class ImportVerilogParameters(object):
# process expression here, for now - just use expression string
ev= self.parseExpression(expLine)
if ev is None:
self.parameters[parName]= (expLine,parType)
self.parameters[parName]= (expLine,parType,expLine)
else:
if not parType:
parType=ev[1]
# 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 or (termChar == ";"): # while True:
break;
# print ("======= Parameters =======")
# for par in self.parameters:
# 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
'''
......
......@@ -38,6 +38,7 @@ from argparse import ArgumentParser
from argparse import RawDescriptionHelpFormatter
from import_verilog_parameters import ImportVerilogParameters
from import_verilog_parameters import VerilogParameters
__all__ = []
__version__ = 0.1
__date__ = '2015-03-01'
......@@ -89,41 +90,36 @@ def main(argv=None): # IGNORE:C0111
USAGE
''' % (program_shortdesc, __author__,str(__date__))
# parser = argparse.ArgumentParser()
# 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)
preDefines={}
preParameters={}
try:
# Setup argument parser
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='+')
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
args = parser.parse_args()
paths = args.paths
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:
print("Verbose mode on")
# if inpat and expat and inpat == expat:
# raise CLIError("include and exclude pattern are equal! Nothing will be processed.")
# for path in paths:
# ### do something with inpath ###
# ivp.readParameterPortList(path)
# return 0
# print("Verbose mode on "+hex(verbose))
args.parameters.append('VERBOSE=%d'%verbose) # add as verilog parameter
if args.parameters:
for prePars in args.parameters:
kv=prePars.split("=")
if len(kv)>1:
preParameters[kv[0]]=(kv[1],"RAW",kv[1]) # todo - need to go through the parser
except KeyboardInterrupt:
### handle keyboard interrupt ###
return 0
......@@ -135,22 +131,33 @@ USAGE
sys.stderr.write(indent + " for help use --help")
return 2
# Take out from the try/except for debugging
ivp= ImportVerilogParameters(preParameters,preDefines)
for path in paths:
### do something with inpath ###
ivp.readParameterPortList(path)
parameters=ivp.getParameters()
vpars=VerilogParameters(parameters)
if verbose > 3:
defines= ivp.getDefines()
print ("======= Extracted defines =======")
for macro in defines:
print ("`"+macro+": "+defines[macro])
parameters=ivp.getParameters()
print ("======= Parameters =======")
for par in parameters:
try:
print (par+" = "+hex(parameters[par][0])+" (type = "+parameters[par][1]+")")
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]+")")
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
......@@ -158,7 +165,6 @@ if __name__ == "__main__":
if DEBUG:
# sys.argv.append("-h")
sys.argv.append("-v")
# sys.argv.append("-r")
if TESTRUN:
import doctest
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