Commit 8df14818 authored by Andrey Filippov's avatar Andrey Filippov

more hardware tests

parent 49288bf2
...@@ -33,13 +33,13 @@ task wait_status_condition; ...@@ -33,13 +33,13 @@ task wait_status_condition;
begin begin
WAITING_STATUS = 1; WAITING_STATUS = 1;
for (match=0; !match; match = invert_match ^ (((registered_rdata ^ {6'h0,pattern}) & {6'h0,mask})==0)) begin for (match=0; !match; match = invert_match ^ (((registered_rdata ^ {6'h0,pattern}) & {6'h0,mask})==0)) begin
read_and_wait_status(status_address); read_status(status_address);
if (wait_seq) begin if (wait_seq) begin
seq_num = (registered_rdata[STATUS_SEQ_SHFT+:6] ^ 6'h20)&'h30; seq_num = (registered_rdata[STATUS_SEQ_SHFT+:6] ^ 6'h20)&'h30;
write_contol_register(status_control_address, {24'b0,status_mode,seq_num}); write_contol_register(status_control_address, {24'b0,status_mode,seq_num});
read_and_wait_status(status_address); read_status(status_address);
while (((registered_rdata[STATUS_SEQ_SHFT+:6] ^ seq_num) & 6'h30)!=0) begin // match just 2 MSBs while (((registered_rdata[STATUS_SEQ_SHFT+:6] ^ seq_num) & 6'h30)!=0) begin // match just 2 MSBs
read_and_wait_status(status_address); read_status(status_address);
end end
end end
end end
...@@ -58,7 +58,7 @@ task wait_status_condition_auto; // assumes status is already updating ...@@ -58,7 +58,7 @@ task wait_status_condition_auto; // assumes status is already updating
begin begin
WAITING_STATUS = 1; WAITING_STATUS = 1;
for (match=0; !match; match = invert_match ^ (((registered_rdata ^ {6'h0,pattern}) & {6'h0,mask})==0)) begin for (match=0; !match; match = invert_match ^ (((registered_rdata ^ {6'h0,pattern}) & {6'h0,mask})==0)) begin
read_and_wait_status(status_address); read_status(status_address);
end end
WAITING_STATUS = 0; WAITING_STATUS = 0;
end end
...@@ -68,9 +68,9 @@ endtask ...@@ -68,9 +68,9 @@ endtask
task wait_phase_shifter_ready; task wait_phase_shifter_ready;
begin begin
WAITING_STATUS = 1; WAITING_STATUS = 1;
read_and_wait_status(MCONTR_PHY_STATUS_REG_ADDR); read_status(MCONTR_PHY_STATUS_REG_ADDR);
while (((registered_rdata & STATUS_PSHIFTER_RDY_MASK) == 0) || (((registered_rdata ^ {24'h0,target_phase}) & 'hff) != 0)) begin while (((registered_rdata & STATUS_PSHIFTER_RDY_MASK) == 0) || (((registered_rdata ^ {24'h0,target_phase}) & 'hff) != 0)) begin
read_and_wait_status(MCONTR_PHY_STATUS_REG_ADDR); // exits after negedge CLK read_status(MCONTR_PHY_STATUS_REG_ADDR); // exits after negedge CLK
end end
WAITING_STATUS = 0; WAITING_STATUS = 0;
end end
...@@ -78,21 +78,21 @@ endtask ...@@ -78,21 +78,21 @@ endtask
task read_all_status; task read_all_status;
begin begin
read_and_wait_status (MCONTR_PHY_STATUS_REG_ADDR); read_status (MCONTR_PHY_STATUS_REG_ADDR);
read_and_wait_status (MCONTR_TOP_STATUS_REG_ADDR); read_status (MCONTR_TOP_STATUS_REG_ADDR);
read_and_wait_status (MCNTRL_PS_STATUS_REG_ADDR); read_status (MCNTRL_PS_STATUS_REG_ADDR);
read_and_wait_status (MCNTRL_SCANLINE_STATUS_REG_CHN1_ADDR); read_status (MCNTRL_SCANLINE_STATUS_REG_CHN1_ADDR);
read_and_wait_status (MCNTRL_SCANLINE_STATUS_REG_CHN3_ADDR); read_status (MCNTRL_SCANLINE_STATUS_REG_CHN3_ADDR);
read_and_wait_status (MCNTRL_TILED_STATUS_REG_CHN2_ADDR); read_status (MCNTRL_TILED_STATUS_REG_CHN2_ADDR);
read_and_wait_status (MCNTRL_TILED_STATUS_REG_CHN4_ADDR); read_status (MCNTRL_TILED_STATUS_REG_CHN4_ADDR);
read_and_wait_status (MCNTRL_TEST01_STATUS_REG_CHN1_ADDR); read_status (MCNTRL_TEST01_STATUS_REG_CHN1_ADDR);
read_and_wait_status (MCNTRL_TEST01_STATUS_REG_CHN2_ADDR); read_status (MCNTRL_TEST01_STATUS_REG_CHN2_ADDR);
read_and_wait_status (MCNTRL_TEST01_STATUS_REG_CHN3_ADDR); read_status (MCNTRL_TEST01_STATUS_REG_CHN3_ADDR);
read_and_wait_status (MCNTRL_TEST01_STATUS_REG_CHN4_ADDR); read_status (MCNTRL_TEST01_STATUS_REG_CHN4_ADDR);
end end
endtask endtask
task read_and_wait_status; task read_status;
input [STATUS_DEPTH-1:0] address; input [STATUS_DEPTH-1:0] address;
begin begin
read_and_wait_w(STATUS_ADDR + address ); // Will set: registered_rdata <= rdata; read_and_wait_w(STATUS_ADDR + address ); // Will set: registered_rdata <= rdata;
......
...@@ -377,7 +377,13 @@ USAGE ...@@ -377,7 +377,13 @@ USAGE
print print
for name,val in sorted(callableTasks.items()): for name,val in sorted(callableTasks.items()):
if re.match(helpFilter,name): if re.match(helpFilter,name):
#enable_memcntrl enable_memcntr .__class__.__name__
print('=== %s ==='%name) print('=== %s ==='%name)
print('defined in %s.%s, %s: %d)'%(str(callableTasks[name]['inst'].__class__.__module__),
callableTasks[name]['inst'].__class__.__name__,
callableTasks[name]['func'].func_code.co_filename,
callableTasks[name]['func'].func_code.co_firstlineno
))
sFuncArgs=getFuncArgsString(name) sFuncArgs=getFuncArgsString(name)
docs=callableTasks[name]['docs'] docs=callableTasks[name]['docs']
if docs: if docs:
......
...@@ -40,12 +40,16 @@ def hx(obj): ...@@ -40,12 +40,16 @@ def hx(obj):
Simulate Verilog concatenation. Input list tuple of items, each being a pair of (value, width) Simulate Verilog concatenation. Input list tuple of items, each being a pair of (value, width)
''' '''
def concat(items): def concat(items):
# print(items)
val=0 val=0
width=0 width=0
for vw in reversed(items): for vw in reversed(items):
v=vw[0] v=vw[0]
if vw[1]==1: if vw[1]==1: # So True/False will also work, not just 0/1
v=(0,1)[v] # So True/False will also work, not juet o/1 if v:
v=1
else:
v=0
val |= (v & ((1 << vw[1])-1))<<width val |= (v & ((1 << vw[1])-1))<<width
width += vw[1] width += vw[1]
return (val,width) return (val,width)
......
...@@ -34,7 +34,7 @@ from import_verilog_parameters import VerilogParameters ...@@ -34,7 +34,7 @@ from import_verilog_parameters import VerilogParameters
from x393_mem import X393Mem from x393_mem import X393Mem
#from verilog_utils import hx,concat, bits #from verilog_utils import hx,concat, bits
from verilog_utils import hx from verilog_utils import hx
from time import time
class X393AxiControlStatus(object): class X393AxiControlStatus(object):
DRY_MODE= True # True DRY_MODE= True # True
DEBUG_MODE=1 DEBUG_MODE=1
...@@ -72,13 +72,12 @@ class X393AxiControlStatus(object): ...@@ -72,13 +72,12 @@ class X393AxiControlStatus(object):
<data> - 32-bit data to write <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_status(self, address): # was read_and_wait_status
""" """
Read word from the status register (up to 26 bits payload and 6-bit sequence number) Read word from the status register (up to 26 bits payload and 6-bit sequence number)
<addr> - status register address (currently 0..255) <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,
status_address, # input [STATUS_DEPTH-1:0] status_address; status_address, # input [STATUS_DEPTH-1:0] status_address;
status_control_address, # input [29:0] status_control_address; status_control_address, # input [29:0] status_control_address;
...@@ -86,7 +85,8 @@ class X393AxiControlStatus(object): ...@@ -86,7 +85,8 @@ class X393AxiControlStatus(object):
pattern, # input [25:0] pattern; // bits as in read registers pattern, # input [25:0] pattern; // bits as in read registers
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
timeout=10.0): # maximal timeout (0 - no timeout)
""" """
Poll specified status register until some condition is matched Poll specified status register until some condition is matched
<status_address> - status register address (currently 0..255) <status_address> - status register address (currently 0..255)
...@@ -100,20 +100,37 @@ class X393AxiControlStatus(object): ...@@ -100,20 +100,37 @@ class X393AxiControlStatus(object):
<mask> - 26-bit mask to enable pattern matching (0-s - ignore) <mask> - 26-bit mask to enable pattern matching (0-s - ignore)
<invert_match> - invert match (wait until matching condition becomes false) <invert_match> - invert match (wait until matching condition becomes false)
<wait_seq>- wait for the correct sequence number, if False - assume always correct <wait_seq>- wait for the correct sequence number, if False - assume always correct
<timeout> maximal time to wait for condition
Return 1 if success, 0 - if timeout
""" """
match=False match=False
endTime=None
if timeout>0:
endTime=time()+timeout
while not match: while not match:
data=self.read_and_wait_status(status_address) data=self.read_status(status_address)
if wait_seq: if wait_seq:
seq_num = ((data >> self.STATUS_SEQ_SHFT) ^ 0x20) & 0x30 seq_num = ((data >> self.STATUS_SEQ_SHFT) ^ 0x20) & 0x30
data=self.read_and_wait_status(status_address) self.write_contol_register(status_control_address, ((status_mode & 3) <<6) | (seq_num & 0x3f))
data=self.read_status(status_address)
while (((data >> self.STATUS_SEQ_SHFT) ^ seq_num) & 0x30) !=0: while (((data >> self.STATUS_SEQ_SHFT) ^ seq_num) & 0x30) !=0:
data=self.read_and_wait_status(status_address) data=self.read_status(status_address)
if self.DRY_MODE: break if self.DRY_MODE: break
if timeout and (time()>endTime):
print("TIMEOUT in wait_status_condition(status_address=0x%x,status_control_address=0x%x,pattern=0x%x,mask=0x%x,timeout=%f)"%
(status_address,status_control_address,pattern,mask,timeout))
print ("last read status data is 0x%x, written seq number is 0x%x"%(data,seq_num))
return 0
match = (((data ^ pattern) & mask & 0x3ffffff)==0) match = (((data ^ pattern) & mask & 0x3ffffff)==0)
if invert_match: if invert_match:
match = not match match = not match
if self.DRY_MODE: break if self.DRY_MODE: break
if timeout and (time()>endTime):
print("TIMEOUT1 in wait_status_condition(status_address=0x%x,status_control_address=0x%x,pattern=0x%x,mask=0x%x,timeout=%f)"%
(status_address,status_control_address,pattern,mask,timeout))
print ("last read status data is 0x%x"%(data))
return 0
return 1
def read_all_status(self): def read_all_status(self):
""" """
...@@ -123,17 +140,17 @@ class X393AxiControlStatus(object): ...@@ -123,17 +140,17 @@ class X393AxiControlStatus(object):
# 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'))
# print (self.__dict__['MCONTR_PHY_STATUS_REG_ADDR']) # print (self.__dict__['MCONTR_PHY_STATUS_REG_ADDR'])
print ("MCONTR_PHY_STATUS_REG_ADDR: %s"%(hx(self.read_and_wait_status(self.MCONTR_PHY_STATUS_REG_ADDR)))) print ("MCONTR_PHY_STATUS_REG_ADDR: %s"%(hx(self.read_status(self.MCONTR_PHY_STATUS_REG_ADDR))))
print ("MCONTR_TOP_STATUS_REG_ADDR: %s"%(hx(self.read_and_wait_status(self.MCONTR_TOP_STATUS_REG_ADDR)))) print ("MCONTR_TOP_STATUS_REG_ADDR: %s"%(hx(self.read_status(self.MCONTR_TOP_STATUS_REG_ADDR))))
print ("MCNTRL_PS_STATUS_REG_ADDR: %s"%(hx(self.read_and_wait_status(self.MCNTRL_PS_STATUS_REG_ADDR)))) print ("MCNTRL_PS_STATUS_REG_ADDR: %s"%(hx(self.read_status(self.MCNTRL_PS_STATUS_REG_ADDR))))
print ("MCNTRL_SCANLINE_STATUS_REG_CHN1_ADDR:%s"%(hx(self.read_and_wait_status(self.MCNTRL_SCANLINE_STATUS_REG_CHN1_ADDR)))) print ("MCNTRL_SCANLINE_STATUS_REG_CHN1_ADDR:%s"%(hx(self.read_status(self.MCNTRL_SCANLINE_STATUS_REG_CHN1_ADDR))))
print ("MCNTRL_SCANLINE_STATUS_REG_CHN3_ADDR:%s"%(hx(self.read_and_wait_status(self.MCNTRL_SCANLINE_STATUS_REG_CHN3_ADDR)))) print ("MCNTRL_SCANLINE_STATUS_REG_CHN3_ADDR:%s"%(hx(self.read_status(self.MCNTRL_SCANLINE_STATUS_REG_CHN3_ADDR))))
print ("MCNTRL_TILED_STATUS_REG_CHN2_ADDR: %s"%(hx(self.read_and_wait_status(self.MCNTRL_TILED_STATUS_REG_CHN2_ADDR)))) print ("MCNTRL_TILED_STATUS_REG_CHN2_ADDR: %s"%(hx(self.read_status(self.MCNTRL_TILED_STATUS_REG_CHN2_ADDR))))
print ("MCNTRL_TILED_STATUS_REG_CHN4_ADDR: %s"%(hx(self.read_and_wait_status(self.MCNTRL_TILED_STATUS_REG_CHN4_ADDR)))) print ("MCNTRL_TILED_STATUS_REG_CHN4_ADDR: %s"%(hx(self.read_status(self.MCNTRL_TILED_STATUS_REG_CHN4_ADDR))))
print ("MCNTRL_TEST01_STATUS_REG_CHN1_ADDR: %s"%(hx(self.read_and_wait_status(self.MCNTRL_TEST01_STATUS_REG_CHN1_ADDR)))) print ("MCNTRL_TEST01_STATUS_REG_CHN1_ADDR: %s"%(hx(self.read_status(self.MCNTRL_TEST01_STATUS_REG_CHN1_ADDR))))
print ("MCNTRL_TEST01_STATUS_REG_CHN2_ADDR: %s"%(hx(self.read_and_wait_status(self.MCNTRL_TEST01_STATUS_REG_CHN2_ADDR)))) print ("MCNTRL_TEST01_STATUS_REG_CHN2_ADDR: %s"%(hx(self.read_status(self.MCNTRL_TEST01_STATUS_REG_CHN2_ADDR))))
print ("MCNTRL_TEST01_STATUS_REG_CHN3_ADDR: %s"%(hx(self.read_and_wait_status(self.MCNTRL_TEST01_STATUS_REG_CHN3_ADDR)))) print ("MCNTRL_TEST01_STATUS_REG_CHN3_ADDR: %s"%(hx(self.read_status(self.MCNTRL_TEST01_STATUS_REG_CHN3_ADDR))))
print ("MCNTRL_TEST01_STATUS_REG_CHN4_ADDR: %s"%(hx(self.read_and_wait_status(self.MCNTRL_TEST01_STATUS_REG_CHN4_ADDR)))) print ("MCNTRL_TEST01_STATUS_REG_CHN4_ADDR: %s"%(hx(self.read_status(self.MCNTRL_TEST01_STATUS_REG_CHN4_ADDR))))
def program_status(self, def program_status(self,
base_addr, # input [29:0] base_addr; base_addr, # input [29:0] base_addr;
......
...@@ -116,22 +116,31 @@ class X393McntrlTests(object): ...@@ -116,22 +116,31 @@ class X393McntrlTests(object):
set_per_pin_delays=0): set_per_pin_delays=0):
""" """
Initial setup of the memory controller, including: Initial setup of the memory controller, including:
disable (and reset) memory controller
enable memory controller
setup status generation in all modules
tristate patterns tristate patterns
DQS/DQM patterns DQS/DQM patterns
all sequences all sequences
channel 0 buffer data channel 0 buffer data
I/O delays I/O delays
clock phase clock phase
status generation write buffer latency
<set_per_pin_delays> - 1 - set individual (per-pin) I/O delays, 0 - use common for the whole class <set_per_pin_delays> - 1 - set individual (per-pin) I/O delays, 0 - use common for the whole class
Returns 1 if phase was set, 0 if it failed
""" """
#reset memory controller
self.x393_axi_tasks.enable_memcntrl(0)
#enable memory controller
self.x393_axi_tasks.enable_memcntrl(1)
#program status for all used modules to refresh at any bit change
self.x393_axi_tasks.program_status_all(3, 0)
# set dq /dqs tristate on/off patterns # set dq /dqs tristate on/off patterns
self.x393_mcntrl_timing.axi_set_tristate_patterns() self.x393_mcntrl_timing.axi_set_tristate_patterns()
# set patterns for DM (always 0) and DQS - always the same (may try different for write lev.) # set patterns for DM (always 0) and DQS - always the same (may try different for write lev.)
self.x393_mcntrl_timing.axi_set_dqs_dqm_patterns() self.x393_mcntrl_timing.axi_set_dqs_dqm_patterns()
# prepare all sequences # prepare all sequences
self.set_all_sequences; self.set_all_sequences()
# prepare write buffer # prepare write buffer
self.x393_mcntrl_buffers.write_block_buf_chn(0,0,256); # fill block memory (channel, page, number) self.x393_mcntrl_buffers.write_block_buf_chn(0,0,256); # fill block memory (channel, page, number)
# set all delays # set all delays
...@@ -149,11 +158,14 @@ class X393McntrlTests(object): ...@@ -149,11 +158,14 @@ class X393McntrlTests(object):
# set clock phase relative to DDR clk # set clock phase relative to DDR clk
# print("Debugging: sleeping for 1 second") # print("Debugging: sleeping for 1 second")
# sleep(1) # sleep(1)
self.x393_mcntrl_timing.axi_set_phase(self.DLY_PHASE); phaseOK=self.x393_mcntrl_timing.axi_set_phase(self.DLY_PHASE,wait_phase_en=True); # wait for phase set
# self.x393_axi_tasks.read_all_status() if not phaseOK:
print("Failed to set clock phase")
#program status for all used modules to refresh at any bit change return 0
self.x393_axi_tasks.program_status_all(3, 0) # read and print status (optional)
self.x393_mcntrl_timing.axi_set_wbuf_delay(self.WBUF_DLY_DFLT)
self.x393_axi_tasks.read_all_status()
return 1
def set_all_sequences(self): def set_all_sequences(self):
""" """
...@@ -182,7 +194,51 @@ class X393McntrlTests(object): ...@@ -182,7 +194,51 @@ class X393McntrlTests(object):
0x1234, # 15'h1234, # row address 0x1234, # 15'h1234, # row address
0x100 # 10'h100 # column address 0x100 # 10'h100 # column address
) )
def init_ddr3(self):
"""
Enable address/command pins, remove SDRST, enable CKE,
Setup PS PIO
Set DDR3 MR0..MR3 registers
"""
"""
// enable output for address/commands to DDR chip
enable_cmda(1);
repeat (16) @(posedge CLK) ;
// remove reset from DDR chip
activate_sdrst(0); // was enabled at system reset
#5000; // actually 500 usec required
repeat (16) @(posedge CLK) ;
enable_cke(1);
repeat (16) @(posedge CLK) ;
// enable_memcntrl(1); // enable memory controller
enable_memcntrl_channels(16'h0003); // only channel 0 and 1 are enabled
configure_channel_priority(0,0); // lowest priority channel 0
configure_channel_priority(1,0); // lowest priority channel 1
enable_reset_ps_pio(1,0); // enable, no reset
// set MR registers in DDR3 memory, run DCI calibration (long)
wait_ps_pio_ready(DEFAULT_STATUS_MODE, 1); // wait FIFO not half full
schedule_ps_pio ( // schedule software-control memory operation (may need to check FIFO status first)
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
`PS_PIO_WAIT_COMPLETE );// wait_complete; // Do not request a newe transaction from the scheduler until previous memory transaction is finished
`ifdef WAIT_MRS
wait_ps_pio_done(DEFAULT_STATUS_MODE, 1);
`else
repeat (32) @(posedge CLK) ; // what delay is needed to be sure? Add to PS_PIO?
// first refreshes will be fast (accummulated while waiting)
`endif
enable_refresh(1);
axi_set_dqs_odelay('h78); //??? dafaults - wrong?
"""
def test_write_levelling(self, def test_write_levelling(self,
wait_complete, # Wait for operation to complete wait_complete, # Wait for operation to complete
wlev_dqs_dly= 0x80, wlev_dqs_dly= 0x80,
......
...@@ -51,6 +51,51 @@ class X393McntrlTiming(object): ...@@ -51,6 +51,51 @@ class X393McntrlTiming(object):
self.x393_mem=X393Mem(debug_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.__dict__.update(VerilogParameters.__dict__["_VerilogParameters__shared_state"]) # Add verilog parameters to the class namespace self.__dict__.update(VerilogParameters.__dict__["_VerilogParameters__shared_state"]) # Add verilog parameters to the class namespace
def axi_set_phase(self,
phase, # input [PHASE_WIDTH-1:0] phase;
wait_phase_en=True,
wait_seq=False):
"""
Set clock phase
<phase> 8-bit clock phase value
<wait_phase_en> compare phase shift to programmed (will not work if the program was restarted)
<wait_seq> read and re-send status request to make sure status reflects new data (just for testing, too fast for Python)
Returns 1 if success, 0 if timeout (or no wait was performed)
"""
if self.DEBUG_MODE > 1:
print("SET CLOCK PHASE=0x%x"%phase)
self.x393_axi_tasks.write_contol_register(self.LD_DLY_PHASE, phase & ((1<<self.PHASE_WIDTH)-1)) # {{(32-PHASE_WIDTH){1'b0}},phase}); // control regiter address
self.x393_axi_tasks.write_contol_register(self.DLY_SET,0)
self.target_phase = phase
if wait_phase_en:
return self.wait_phase(True, wait_seq)
return 0
def wait_phase(self,
check_phase_value=True,
wait_seq=False):
"""
Wait for the phase shifter
<check_phase_value> compare phase shift to programmed (will not work if the program was restarted)
<wait_seq> read and re-send status request to make sure status reflects new data (just for testing, too fast for Python)
Returns 1 if success, 0 if timeout
"""
patt = 0x3000000 | self.target_phase
mask = 0x3000100
if check_phase_value:
mask |= 0xff
return self.x393_axi_tasks.wait_status_condition(
self.MCONTR_PHY_STATUS_REG_ADDR, # status_address,
self.MCONTR_PHY_16BIT_ADDR + self.MCONTR_PHY_STATUS_CNTRL, # status_control_address,
3, # status_mode,
patt, # pattern,
mask, # mask
0, # invert_match
wait_seq, # wait_seq;
1.0) # maximal timeout (0 - no timeout)
def get_target_phase(self): def get_target_phase(self):
""" """
Returns previously set clock phase value Returns previously set clock phase value
...@@ -210,25 +255,13 @@ class X393McntrlTiming(object): ...@@ -210,25 +255,13 @@ class X393McntrlTiming(object):
for i in range(0,number): # (i=0;i<number;i=i+1) begin for i in range(0,number): # (i=0;i<number;i=i+1) begin
self.x393_axi_tasks.write_contol_register(reg_addr + i, delay) # {24'b0,delay}); // control register address self.x393_axi_tasks.write_contol_register(reg_addr + i, delay) # {24'b0,delay}); // control register address
def axi_set_phase(self,
phase): # input [PHASE_WIDTH-1:0] phase;
"""
Set clock phase
<phase> 8-bit clock phase value
"""
if self.DEBUG_MODE > 1:
print("SET CLOCK PHASE=0x%x"%phase)
self.x393_axi_tasks.write_contol_register(self.LD_DLY_PHASE, phase & ((1<<self.PHASE_WIDTH)-1)) # {{(32-PHASE_WIDTH){1'b0}},phase}); // control regiter address
self.x393_axi_tasks.write_contol_register(self.DLY_SET,0)
self.target_phase = phase
def wait_phase_shifter_ready(self): def wait_phase_shifter_ready(self):
""" """
Wait until clock phase shifter is ready Wait until clock phase shifter is ready
""" """
data=self.x393_axi_tasks.read_and_wait_status(self.MCONTR_PHY_STATUS_REG_ADDR) data=self.x393_axi_tasks.read_status(self.MCONTR_PHY_STATUS_REG_ADDR)
while (((data & self.STATUS_PSHIFTER_RDY_MASK) == 0) or (((data ^ self.target_phase) & 0xff) != 0)): while (((data & self.STATUS_PSHIFTER_RDY_MASK) == 0) or (((data ^ self.target_phase) & 0xff) != 0)):
data=self.x393_axi_tasks.read_and_wait_status(self.MCONTR_PHY_STATUS_REG_ADDR) data=self.x393_axi_tasks.read_status(self.MCONTR_PHY_STATUS_REG_ADDR)
if self.DRY_MODE: break if self.DRY_MODE: break
def axi_set_wbuf_delay(self, def axi_set_wbuf_delay(self,
......
...@@ -105,9 +105,10 @@ class X393PIOSequences(object): ...@@ -105,9 +105,10 @@ class X393PIOSequences(object):
0, 0,
sync_seq) sync_seq)
def wait_ps_pio_done(self, # // wait PS PIO module has no pending/running memory transaction def wait_ps_pio_done(self, # // wait PS PIO module has no pending/running memory transaction
mode, # input [1:0] mode; mode, # input [1:0] mode;
sync_seq): # input sync_seq; // synchronize sequences sync_seq, # input sync_seq; // synchronize sequences
timeout=2.0): # maximal timeout in seconds
""" """
Wait PS PIO module has no pending/running memory transaction Wait PS PIO module has no pending/running memory transaction
<mode> status mode (0..3) - see 'help program_status' <mode> status mode (0..3) - see 'help program_status'
...@@ -120,7 +121,8 @@ class X393PIOSequences(object): ...@@ -120,7 +121,8 @@ class X393PIOSequences(object):
0, 0,
3 << self.STATUS_2LSB_SHFT, 3 << self.STATUS_2LSB_SHFT,
0, 0,
sync_seq) sync_seq,
timeout)
''' '''
x393_mcontr_encode_cmd x393_mcontr_encode_cmd
''' '''
...@@ -355,7 +357,7 @@ class X393PIOSequences(object): ...@@ -355,7 +357,7 @@ class X393PIOSequences(object):
(al,2), # al[1:0], # MR1.4_3 (al,2), # al[1:0], # MR1.4_3
(rtt,1), # rtt[0], # MR1.2 (rtt,1), # rtt[0], # MR1.2
(ods,1), # ods[0], # MR1.1 (ods,1), # ods[0], # MR1.1
(dll)))[0] #dll}; # MR1.0 (dll,1)))[0] #dll}; # MR1.0
def func_ddr3_mr2(self, # ; function [ADDRESS_NUMBER+2:0] def func_ddr3_mr2(self, # ; function [ADDRESS_NUMBER+2:0]
rtt_wr, # input [1:0] rtt_wr; # Dynamic ODT : rtt_wr, # input [1:0] rtt_wr; # Dynamic ODT :
...@@ -414,10 +416,10 @@ class X393PIOSequences(object): ...@@ -414,10 +416,10 @@ class X393PIOSequences(object):
1x, 2'bx1 - reserved 1x, 2'bx1 - reserved
""" """
return concat(( return concat((
(3,3), # 3'h3, (3,3), # 3'h3,
(0,self.ADDRESS_NUMBER), # {ADDRESS_NUMBER-3{1'b0}}, (0,self.ADDRESS_NUMBER-3), # {ADDRESS_NUMBER-3{1'b0}},
(mpr, 1), # mpr, # MR3.2 (mpr, 1), # mpr, # MR3.2
(mpr_rf,2)))[0] # mpr_rf[1:0]}; # MR3.1_0 (mpr_rf,2)))[0] # mpr_rf[1:0]}; # MR3.1_0
''' '''
x393_tasks_pio_sequences x393_tasks_pio_sequences
...@@ -617,7 +619,7 @@ class X393PIOSequences(object): ...@@ -617,7 +619,7 @@ class X393PIOSequences(object):
self.x393_mem.axi_write_single_w(cmd_addr, data) self.x393_mem.axi_write_single_w(cmd_addr, data)
cmd_addr += 1 cmd_addr += 1
# skip done bank ODT CKE SEL DQEN DQSEN DQSTGL DCI B_WR B_RD B_RST # skip done bank ODT CKE SEL DQEN DQSEN DQSTGL DCI B_WR B_RD B_RST
data.self.func_encode_skip( 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)# tMOD data=self.func_encode_skip( 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)# tMOD
self.x393_mem.axi_write_single_w(cmd_addr, data) self.x393_mem.axi_write_single_w(cmd_addr, data)
cmd_addr += 1 cmd_addr += 1
# first read # first read
...@@ -820,10 +822,10 @@ class X393PIOSequences(object): ...@@ -820,10 +822,10 @@ class X393PIOSequences(object):
0) # 2'h0); # [1:0] mpr_rf; # MPR read function: 2'b00: predefined pattern 0101... 0) # 2'h0); # [1:0] mpr_rf; # MPR read function: 2'b00: predefined pattern 0101...
cmd_addr = self.MCONTR_CMD_WR_ADDR + self.INITIALIZE_OFFSET; cmd_addr = self.MCONTR_CMD_WR_ADDR + self.INITIALIZE_OFFSET;
if self.DEBUG_MODE > 1: if self.DEBUG_MODE > 1:
print("mr0=0x%x", mr0); print("mr0=0x%05x"%mr0);
print("mr1=0x%x", mr1); print("mr1=0x%05x"%mr1);
print("mr2=0x%x", mr2); print("mr2=0x%05x"%mr2);
print("mr3=0x%x", mr3); print("mr3=0x%05x"%mr3);
# addr bank RCW ODT CKE SEL DQEN DQSEN DQSTGL DCI B_WR B_RD NOP, B_RST # addr bank RCW ODT CKE SEL DQEN DQSEN DQSTGL DCI B_WR B_RD NOP, B_RST
data=self.func_encode_cmd(bits(mr2,(14,0)), bits(mr2,(17,15)), 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0) data=self.func_encode_cmd(bits(mr2,(14,0)), bits(mr2,(17,15)), 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)
self.x393_mem.axi_write_single_w(cmd_addr, data) self.x393_mem.axi_write_single_w(cmd_addr, data)
......
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