Commit e4dae58e authored by Andrey Filippov's avatar Andrey Filippov

debugging command/address timing adjustment

parent 1902d5ce
-v
-d TARGET_MODE=1
-f ../system_defines.vh
-f ../includes/x393_parameters.vh ../includes/x393_cur_params_target.vh ../includes/x393_localparams.vh
......
......@@ -61,7 +61,7 @@ __version__ = 0.1
__date__ = '2015-03-01'
__updated__ = '2015-03-01'
DEBUG = 1
DEBUG = 0 # 1
TESTRUN = 0
PROFILE = 0
QUIET=1 # more try/excepts
......@@ -209,7 +209,7 @@ USAGE
args = parser.parse_args()
if not args.exceptions:
args.exceptions=0
QUIET = (1,0)[args.exceptions]
# print ("args.exception=%d, QUIET=%d"%(args.exceptions,QUIET))
......@@ -223,6 +223,14 @@ USAGE
#print("--- commands=%s"% str(args.commands))
# paths = args.paths
verbose = args.verbose
if not verbose:
verbose=0
print("args=%s"%(str(args)))
print("sys.argv=%s"%(str(sys.argv)))
print("DEBUG=%s"%(str(DEBUG)))
print ("verbose=%d"%verbose)
paths=[]
if (args.paths):
for group in args.paths:
......@@ -247,7 +255,7 @@ USAGE
preDefines[kv[0].strip("`")]=kv[1]
#print("+++ defines=%s"% str(preDefines))
if verbose > 0:
if verbose > -1: # always
# print("Verbose mode on "+hex(verbose))
args.parameters.append(['VERBOSE=%d'%verbose]) # add as verilog parameter
......
......@@ -44,15 +44,11 @@ def set_name_field(vname,
<fieldIndex> byte field index (0 - lowest byte, 1 - bits[15:8], etc)
<value> value to set the specified byte to
"""
# v=vrlg.__dict__[vname]
v=globals()[vname]
# print ("old value for %s is %s"%(vname,str(vrlg.__dict__[vname])))
mask = 0xff << (8*fieldIndex)
val = value << (8*fieldIndex)
v = ((v ^ val) & mask) ^ v
# vrlg.__dict__[vname]=v
globals()[vname]=v
# print ("new value for %s is %s (0x%x)"%(vname,str(vrlg.__dict__[vname]),vrlg.__dict__[vname]))
def get_name_field(vname,
fieldIndex):
......@@ -62,6 +58,11 @@ def get_name_field(vname,
<fieldIndex> byte field index (0 - lowest byte, 1 - bits[15:8], etc)
Return specified byte
"""
# print ("value for %s is %s"%(vname,str(globals()[vname])))
# print ("dflt for %s is %s"%(vname,str(DEFAULTS[vname])))
# print ("value[%d] for %s is 0x%x"%(fieldIndex,vname,globals()[vname]))
# print ("dflt[%d] for %s is 0x%x"%(fieldIndex,vname,DEFAULTS[vname]))
return ( globals()[vname] >> (8*fieldIndex)) & 0xff
def get_default_field(vname,
......@@ -74,8 +75,11 @@ def get_default_field(vname,
Return specified byte
"""
global DEFAULTS
# print ("value for %s is %s"%(vname,str(globals()[vname])))
# print ("dflt for %s is %s"%(vname,str(DEFAULTS[vname])))
# print ("value[%d] for %s is 0x%x"%(fieldIndex,vname,globals()[vname]))
# print ("dflt[%d] for %s is 0x%x"%(fieldIndex,vname,DEFAULTS[vname]))
# return (vrlg.DEFAULTS[vname] >> (8*fieldIndex)) & 0xff
return (DEFAULTS[vname] >> (8*fieldIndex)) & 0xff
def get_default(vname):
......
......@@ -36,24 +36,122 @@ from x393_mem import X393Mem
from verilog_utils import hx
from time import time
import vrlg
enabled_channels=0 # currently enable channels
cke_en=0
cmda_en=0
sdrst_on=1
mcntrl_en=0
refresh_en=0
channel_priority=[None]*16
sequences_set=0
class X393AxiControlStatus(object):
DRY_MODE= True # True
DEBUG_MODE=1
# vpars=None
x393_mem=None
enabled_channels=0 # currently enable channels
FPGA_RST_CTRL=0xf8000240
# verbose=1
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)
try:
self.verbose=vrlg.VERBOSE
except:
pass
# self.__dict__.update(VerilogParameters.__dict__["_VerilogParameters__shared_state"]) # 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
'''
# Use 'import pickle' (exists in the camera) to save/restore state
def init_state(self):
global enabled_channels, cke_en, cmda_en, sdrst_on, mcntrl_en, channel_priority, refresh_en, sequences_set
"""
reset state (as after bitstream load)
"""
enabled_channels=0 # currently enable channels
cke_en=0
cmda_en=0
sdrst_on=1
mcntrl_en=0
channel_priority=[None]*16
refresh_en=0
sequences_set=0
if self.verbose>0:
print ("*** System state reset ****")
# TODO: Add state save/restore in tmpfs file (like /var/state/...) (/var/state does not exist initially)
def get_sequences_set(self,quiet=1):
global sequences_set
if quiet<2 :
print ("SEQUENCES SET = %d"%sequences_set)
return sequences_set
def set_sequences_set(self,val,quiet=1):
global sequences_set
val= (0,1)[val]
sequences_set=val
if quiet<2 :
print ("SEQUENCES SET = %d"%sequences_set)
def get_cke_en(self,quiet=1):
global cke_en
if quiet<2 :
print ("CKE EN = %d"%cke_en)
return cke_en
def get_cmda_en(self,quiet=1):
global cmda_en
if quiet<2 :
print ("CMDA EN = %d"%cmda_en)
return cmda_en
def get_sdrst_on(self,quiet=1):
global sdrst_on
if quiet<2 :
print ("SDRST ON = %d"%sdrst_on)
return sdrst_on
def get_mcntrl_en(self,quiet=1):
global mcntrl_en
if quiet<2 :
print ("MCNTRL ON = %d"%mcntrl_en)
return mcntrl_en
def get_refresh_en(self,quiet=1):
global refresh_en
if quiet<2 :
print ("REFRESH EN = %d"%refresh_en)
return refresh_en
def get_enabled_channels(self,quiet=1):
global enabled_channels
if quiet<2 :
print ("ENABLED_CHANNELS = 0x%x"%enabled_channels)
return enabled_channels
def get_channel_priorities(self,quiet=1):
global channel_priority
if quiet<2 :
print ("CHANNEL PRIORITIES:",end=" ")
for v in channel_priority:
if v is None:
print (" - ",end=" ")
else:
print ("%d"%v,end=" ")
print()
return channel_priority
def get_state(self,quiet=1):
return {
'cke_en': self.get_cke_en(quiet),
'cmda_en': self.get_cmda_en(quiet),
'sdrst_on': self.get_sdrst_on(quiet),
'mcntrl_en': self.get_mcntrl_en(quiet),
'enabled_channels': self.get_enabled_channels(quiet),
'channel_priorities': self.get_channel_priorities(quiet),
'refresh_en': self.get_refresh_en(quiet),
'sequences_set': self.get_sequences_set(quiet)
}
def write_contol_register(self, reg_addr, data):
"""
Write 32-bit word to the control register
......@@ -202,7 +300,12 @@ class X393AxiControlStatus(object):
Enable (disable) address, bank and command lines to the DDR3 memory
<en> - 1 - enable, 0 - disable
"""
global cmda_en
en=(0,1)[en]
if self.verbose>0:
print ("ENABLE CMDA %s"%str(en))
self.write_contol_register(vrlg.MCONTR_PHY_0BIT_ADDR + vrlg.MCONTR_PHY_0BIT_CMDA_EN + en, 0);
cmda_en=en
def enable_cke(self,
en): # input en;
......@@ -210,7 +313,12 @@ class X393AxiControlStatus(object):
Enable (disable) CKE - clock enable to DDR3 memory
<en> - 1 - enable, 0 - disable
"""
global cke_en
en=(0,1)[en]
if self.verbose>0:
print ("ENABLE CKE %s"%str(en))
self.write_contol_register(vrlg.MCONTR_PHY_0BIT_ADDR + vrlg.MCONTR_PHY_0BIT_CKE_EN + en, 0);
cke_en=en
def activate_sdrst(self,
en): # input en;
......@@ -218,32 +326,49 @@ class X393AxiControlStatus(object):
Activate SDRST (reset) to DDR3 memory
<en> - 1 - activate (low), 0 - deactivate (high)
"""
global sdrst_on
en=(0,1)[en]
if self.verbose>0:
print ("ACTIVATE SDRST %s"%str(en))
self.write_contol_register(vrlg.MCONTR_PHY_0BIT_ADDR + vrlg.MCONTR_PHY_0BIT_SDRST_ACT + en, 0);
sdrst_on=en
def enable_refresh(self,
en): # input en;
en): # input en;
"""
Enable (disable) refresh of the DDR3 memory
<en> - 1 - enable, 0 - disable
"""
global refresh_en
en=(0,1)[en]
if self.verbose>0:
print ("ENABLE REFRESH %s"%str(en))
self.write_contol_register(vrlg.MCONTR_TOP_0BIT_ADDR + vrlg.MCONTR_TOP_0BIT_REFRESH_EN + en, 0);
refresh_en=en
def enable_memcntrl(self,
en): # input en;
en): # input en;
"""
Enable memory controller module
<en> - 1 - enable, 0 - disable
"""
global mcntrl_en
en=(0,1)[en]
if self.verbose>0:
print ("ENABLE MEMCTRL %s"%str(en))
self.write_contol_register(vrlg.MCONTR_TOP_0BIT_ADDR + vrlg.MCONTR_TOP_0BIT_MCONTR_EN + en, 0);
mcntrl_en=en
def enable_memcntrl_channels(self,
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.write_contol_register(vrlg.MCONTR_TOP_16BIT_ADDR + vrlg.MCONTR_TOP_16BIT_CHN_EN, self.enabled_channels & 0xffff) # {16'b0,chnen});
global enabled_channels
enabled_channels = chnen # currently enabled memory channels
self.write_contol_register(vrlg.MCONTR_TOP_16BIT_ADDR + vrlg.MCONTR_TOP_16BIT_CHN_EN, enabled_channels & 0xffff) # {16'b0,chnen});
if self.verbose>0:
print ("ENABLED MEMCTRL CHANNELS 0x%x (word)"%enabled_channels)
def enable_memcntrl_en_dis(self,
chn, # input [3:0] chn;
......@@ -253,19 +378,26 @@ class X393AxiControlStatus(object):
<chn> - 4-bit channel select
<en> - 1 - enable, 0 - disable of the selected channel
"""
global enabled_channels
if en:
self.enabled_channels = self.enabled_channels | (1<<chn);
enabled_channels |= 1<<chn;
else:
self.enabled_channels = self.enabled_channels & ~(1<<chn);
self.write_contol_register(vrlg.MCONTR_TOP_16BIT_ADDR + self. MCONTR_TOP_16BIT_CHN_EN, self.enabled_channels & 0xffff) # {16'b0,ENABLED_CHANNELS});
enabled_channels &= ~(1<<chn);
self.write_contol_register(vrlg.MCONTR_TOP_16BIT_ADDR + self. MCONTR_TOP_16BIT_CHN_EN, enabled_channels & 0xffff) # {16'b0,ENABLED_CHANNELS});
if self.verbose>0:
print ("ENABLED MEMCTRL CHANNELS 0x%x (en/dis)"%enabled_channels)
def configure_channel_priority(self,
chn, # input [ 3:0] chn;
priority): #input [15:0] priority; // (higher is more important)
priority=0): #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)
"""
global channel_priority
self.write_contol_register(vrlg.MCONTR_ARBIT_ADDR + chn, priority & 0xffff)# {16'b0,priority});
if self.verbose>0:
print ("SET CHANNEL %d priority=0x%x"%(chn,priority))
channel_priority[chn]=priority
This diff is collapsed.
......@@ -33,7 +33,8 @@ __status__ = "Development"
#x393_pio_sequences
#from import_verilog_parameters import VerilogParameters
from x393_mem import X393Mem
from x393_axi_control_status import X393AxiControlStatus
#from x393_axi_control_status import X393AxiControlStatus
import x393_axi_control_status
#from verilog_utils import * # concat, bits
#from verilog_utils import hx, concat, bits, getParWidth
#from verilog_utils import concat, getParWidth
......@@ -50,10 +51,11 @@ class X393McntrlBuffers(object):
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=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=self.VERBOSE
self.verbose=vrlg.VERBOSE
except:
pass
def write_block_scanline_chn(self, #
......
This diff is collapsed.
This diff is collapsed.
......@@ -33,12 +33,15 @@ __status__ = "Development"
#x393_pio_sequences
#from import_verilog_parameters import VerilogParameters
from x393_mem import X393Mem
from x393_axi_control_status import X393AxiControlStatus
#from x393_axi_control_status import X393AxiControlStatus
import x393_axi_control_status
from x393_mcntrl_buffers import X393McntrlBuffers
#from verilog_utils import * # concat, bits
from verilog_utils import concat, bits
#from x393_axi_control_status import concat, bits
import vrlg # global parameters
from time import sleep
class X393PIOSequences(object):
DRY_MODE= True # True
DEBUG_MODE=1
......@@ -50,7 +53,8 @@ class X393PIOSequences(object):
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=X393AxiControlStatus(debug_mode,dry_mode)
self.x393_axi_tasks=x393_axi_control_status.X393AxiControlStatus(debug_mode,dry_mode)
self.x393_mcntrl_buffers= X393McntrlBuffers(debug_mode,dry_mode)
# self.__dict__.update(VerilogParameters.__dict__["_VerilogParameters__shared_state"]) # Add verilog parameters to the class namespace
'''
......@@ -949,3 +953,79 @@ class X393PIOSequences(object):
wait_complete) # `PS_PIO_WAIT_COMPLETE )# wait_complete; # Do not request a newer transaction from the scheduler until previous memory transaction is finished
# temporary - for debugging:
# self.wait_ps_pio_done(vrlg.DEFAULT_STATUS_MODE,1) # wait previous memory transaction finished before changing delays (effective immediately)
def write_levelling(self,
wait_complete=1, # Wait for operation to complete
quiet=1):
"""
Read data in write levelling mode
<wait_complete> wait write levelling operation to complete (0 - may initiate multiple PS PIO operations)
<quiet> reduce output
returns a pair of ratios for getting "1" for 2 lanes and problem marker (should be 0)
"""
numBufWords=32 # twice nrep in set_write_lev
self.wait_ps_pio_done(vrlg.DEFAULT_STATUS_MODE,1); # not no interrupt running cycle - delays are changed immediately
self.schedule_ps_pio (# schedule software-control memory operation (may need to check FIFO status first)
vrlg.WRITELEV_OFFSET, # input [9:0] seq_addr; # sequence start address
0, # input [1:0] page; # buffer page number
0, # input urgent; # high priority request (only for competition with other channels, will not pass in this FIFO)
0, # input chn; # channel buffer to use: 0 - memory read, 1 - memory write
wait_complete) # `PS_PIO_WAIT_COMPLETE );# wait_complete; # Do not request a newe transaction from the scheduler until previous memory transaction is finished
self.wait_ps_pio_done(vrlg.DEFAULT_STATUS_MODE,1); # wait previous memory transaction finished before changing delays (effective immediately)
buf=self.x393_mcntrl_buffers.read_block_buf_chn (0, 0, numBufWords, (0,1)[quiet<1]) # chn=0, page=0, number of 32-bit words=32, show_rslt
#calculate 1-s ratio for both lanes
rslt=[0.0,0.0,0.0] # last word - number of "problem" bytes that have non-ones in bits [7:1]
for i in range(0,numBufWords):
rslt[i & 1] += ((buf[i] & 1) +
((buf[i] >> 8) & 1) +
((buf[i] >> 16) & 1) +
((buf[i] >> 24) & 1))
rslt[2] += ((0,1)[(buf[i] & 0xfe) != 0]+
(0,1)[(buf[i] & 0xfe00) != 0]+
(0,1)[(buf[i] & 0xfe0000) != 0]+
(0,1)[(buf[i] & 0xfe000000) != 0])
for i in range(2):
rslt[i]/=2*numBufWords
rslt[2]/=4*numBufWords
if quiet <1:
print ("WLEV lanes ratios: %f %f, non 0x00/0x01 bytes: %f"%(rslt[0],rslt[1],rslt[2]))
return rslt
def restart_ddr3(self,
wait_complete=True,
quiet=1):
"""
Activate SDRST, enable address/command pins, remove SDRST, enable CKE,
Setup PS PIO
Set DDR3 MR0..MR3 registers
<wait_complete> Do not request a new transaction from the scheduler until previous memory transaction is finished
<quiet> reduce output
"""
# enable output for address/commands to DDR chip
self.x393_axi_tasks.enable_cmda(1)
self.x393_axi_tasks.activate_sdrst(1) # reset DDR3
sleep(0.1)
# remove reset from DDR3 chip
self.x393_axi_tasks.activate_sdrst(0) # was enabled at system reset
sleep(0.1) # actually 500 usec required
self.x393_axi_tasks.enable_cke(1);
self.x393_axi_tasks.enable_memcntrl_channels(0x3) # only channel 0 and 1 are enabled
self.x393_axi_tasks.configure_channel_priority(0,0) # lowest priority channel 0
self.x393_axi_tasks.configure_channel_priority(1,0) # lowest priority channel 1
self.enable_reset_ps_pio(1,0) # enable, no reset
# set MR registers in DDR3 memory, run DCI calibration (long)
self.wait_ps_pio_ready(vrlg.DEFAULT_STATUS_MODE, 1, 2.0); # wait FIFO not half full, sync sequences, timeout 2 sec
self.schedule_ps_pio ( # schedule software-control memory operation (may need to check FIFO status first)
vrlg.INITIALIZE_OFFSET, # input [9:0] seq_addr; # sequence start address
0, # input [1:0] page; # buffer page number
0, # input urgent; # high priority request (only for competion with other channels, wiil not pass in this FIFO)
0, # input chn; # channel buffer to use: 0 - memory read, 1 - memory write
wait_complete ); # wait_complete; # Do not request a newe transaction from the scheduler until previous memory transaction is finished
# Wait PS PIO sequence DOEN
self.wait_ps_pio_done(vrlg.DEFAULT_STATUS_MODE, 1 , 2.0); # wait FIFO not half full, sync sequences, timeout 2 sec
......@@ -37,6 +37,7 @@ from x393_mem import X393Mem
#from subprocess import call
from time import sleep
import vrlg # global parameters
import x393_axi_control_status
DEFAULT_BITFILE="/usr/local/verilog/x393.bit"
FPGA_RST_CTRL= 0xf8000240
......@@ -50,6 +51,7 @@ class X393Utils(object):
x393_mem=None
enabled_channels=0 # currently enable channels
saveFileName=None
x393_axi_tasks=None
# verbose=1
def __init__(self, debug_mode=1,dry_mode=True,saveFileName=None):
self.DEBUG_MODE=debug_mode
......@@ -57,6 +59,8 @@ class X393Utils(object):
if saveFileName:
self.saveFileName=saveFileName.strip()
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
def reset_get(self):
"""
......@@ -117,6 +121,7 @@ class X393Utils(object):
self.x393_mem.write_mem(FPGA0_THR_CTRL,0)
print ("Reset OFF")
self.reset(0xa)
self.x393_axi_tasks.init_state()
def exp_gpio (self,
mode="in",
......
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