Commit f7c03985 authored by Andrey Filippov's avatar Andrey Filippov

more verilog tasks converted to python

parent 8de61d31
...@@ -19,7 +19,7 @@ ...@@ -19,7 +19,7 @@
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/> . * along with this program. If not, see <http://www.gnu.org/licenses/> .
*******************************************************************************/ *******************************************************************************/
task schedule_ps_pio; // shedule software-control memory operation (may need to check FIFO status first) task schedule_ps_pio; // schedule software-control memory operation (may need to check FIFO status first)
input [9:0] seq_addr; // sequence start address input [9:0] seq_addr; // sequence start address
input [1:0] page; // buffer page number input [1:0] page; // buffer page number
input urgent; // high priority request (only for competion wityh other channels, wiil not pass in this FIFO) input urgent; // high priority request (only for competion wityh other channels, wiil not pass in this FIFO)
......
...@@ -386,10 +386,10 @@ class ImportVerilogParameters(object): ...@@ -386,10 +386,10 @@ class ImportVerilogParameters(object):
print ("ERROR: failed to evaluate expression in '%s' (starting from '%s'"%(line,line[start:])) print ("ERROR: failed to evaluate expression in '%s' (starting from '%s'"%(line,line[start:]))
return None return None
endPos=skipWS(exp[2]) endPos=skipWS(exp[2])
if endPosp >= len(line): if endPos >= len(line):
print ("ERROR: EOL reached when closing ')' was expected in '%s'"%line) print ("ERROR: EOL reached when closing ')' was expected in '%s'"%line)
return None return None
if line[ep] != ")": if line[endPos] != ")":
print ("ERROR: Found '%s'when closing ')' was expected in '%s'"%(line[endPos],line)) print ("ERROR: Found '%s'when closing ')' was expected in '%s'"%(line[endPos],line))
return None return None
endPos=skipWS(endPos+1) endPos=skipWS(endPos+1)
......
...@@ -46,6 +46,8 @@ import x393_mem ...@@ -46,6 +46,8 @@ import x393_mem
import x393_axi_control_status import x393_axi_control_status
import x393_pio_sequences import x393_pio_sequences
import x393_mcntrl_timing import x393_mcntrl_timing
import x393_mcntrl_buffers
import x393_mcntrl_tests
__all__ = [] __all__ = []
__version__ = 0.1 __version__ = 0.1
__date__ = '2015-03-01' __date__ = '2015-03-01'
...@@ -230,6 +232,8 @@ USAGE ...@@ -230,6 +232,8 @@ USAGE
x393tasks= x393_axi_control_status.X393AxiControlStatus(verbose,True) x393tasks= x393_axi_control_status.X393AxiControlStatus(verbose,True)
x393Pio= x393_pio_sequences.X393PIOSequences(verbose,True) x393Pio= x393_pio_sequences.X393PIOSequences(verbose,True)
x393Timing= x393_mcntrl_timing.X393McntrlTiming(verbose,True) x393Timing= x393_mcntrl_timing.X393McntrlTiming(verbose,True)
x393Buffers=x393_mcntrl_buffers.X393McntrlBuffers(verbose,True)
x393Tests= x393_mcntrl_tests.X393McntrlTests(verbose,True)
''' '''
print ("----------------------") print ("----------------------")
print("x393_mem.__dict__="+str(x393_mem.__dict__)) print("x393_mem.__dict__="+str(x393_mem.__dict__))
...@@ -248,7 +252,10 @@ USAGE ...@@ -248,7 +252,10 @@ USAGE
extractTasks(x393_axi_control_status.X393AxiControlStatus,x393tasks) extractTasks(x393_axi_control_status.X393AxiControlStatus,x393tasks)
extractTasks(x393_pio_sequences.X393PIOSequences,x393Pio) extractTasks(x393_pio_sequences.X393PIOSequences,x393Pio)
extractTasks(x393_mcntrl_timing.X393McntrlTiming,x393Timing) extractTasks(x393_mcntrl_timing.X393McntrlTiming,x393Timing)
extractTasks(x393_mcntrl_buffers.X393McntrlBuffers,x393Buffers)
extractTasks(x393_mcntrl_tests.X393McntrlTests,x393Tests)
#
if verbose > 3: if verbose > 3:
funcName="read_mem" funcName="read_mem"
funcArgs=[0x377,123] funcArgs=[0x377,123]
......
...@@ -40,7 +40,8 @@ class X393AxiControlStatus(object): ...@@ -40,7 +40,8 @@ class X393AxiControlStatus(object):
DEBUG_MODE=1 DEBUG_MODE=1
# vpars=None # vpars=None
x393_mem=None x393_mem=None
target_phase=0 # TODO: set! enabled_channels=0 # currently enable channels
# verbose=1
def __init__(self, debug_mode=1,dry_mode=True): def __init__(self, debug_mode=1,dry_mode=True):
self.DEBUG_MODE=debug_mode self.DEBUG_MODE=debug_mode
self.DRY_MODE=dry_mode self.DRY_MODE=dry_mode
...@@ -52,7 +53,10 @@ class X393AxiControlStatus(object): ...@@ -52,7 +53,10 @@ class X393AxiControlStatus(object):
# print (VerilogParameters.__dict__) # print (VerilogParameters.__dict__)
# self.__dict__.update(VerilogParameters.__dict__) # Add verilog parameters to the class namespace # self.__dict__.update(VerilogParameters.__dict__) # Add verilog parameters to the class namespace
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
# try:
# verbose=self.verbose
# except:
# pass
# print ("+++++++++++++++ self.__dict__ ++++++++++++++++++++++++++") # print ("+++++++++++++++ self.__dict__ ++++++++++++++++++++++++++")
# print (self.__dict__) # print (self.__dict__)
''' '''
...@@ -86,11 +90,6 @@ class X393AxiControlStatus(object): ...@@ -86,11 +90,6 @@ class X393AxiControlStatus(object):
if invert_match: if invert_match:
match = not match match = not match
if self.DRY_MODE: break if self.DRY_MODE: break
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)
if self.DRY_MODE: break
def read_all_status(self): def read_all_status(self):
# print (self.__dict__) # print (self.__dict__)
...@@ -138,6 +137,43 @@ class X393AxiControlStatus(object): ...@@ -138,6 +137,43 @@ class X393AxiControlStatus(object):
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_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_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, 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 enable_cmda(self,
''' en): # input en;
self.write_contol_register(self.MCONTR_PHY_0BIT_ADDR + self.MCONTR_PHY_0BIT_CMDA_EN + en, 0);
def enable_cke(self,
en): # input en;
self.write_contol_register(self.MCONTR_PHY_0BIT_ADDR + self.MCONTR_PHY_0BIT_CKE_EN + en, 0);
def activate_sdrst(self,
en): # input en;
self.write_contol_register(self.MCONTR_PHY_0BIT_ADDR + self.MCONTR_PHY_0BIT_SDRST_ACT + en, 0);
def enable_refresh(self,
en): # input en;
self.write_contol_register(self.MCONTR_TOP_0BIT_ADDR + self.MCONTR_TOP_0BIT_REFRESH_EN + en, 0);
def enable_memcntrl(self,
en): # input en;
self.write_contol_register(self.MCONTR_TOP_0BIT_ADDR + self.MCONTR_TOP_0BIT_MCONTR_EN + en, 0);
def enable_memcntrl_channels(self,
chnen): # input [15:0] chnen; // bit-per-channel, 1 - enable;
self.enabled_channels = chnen; # currently enabled memory channels
self.write_contol_register(self.MCONTR_TOP_16BIT_ADDR + self.MCONTR_TOP_16BIT_CHN_EN, self.enabled_channels & 0xffff) # {16'b0,chnen});
def enable_memcntrl_en_dis(self,
chn, # input [3:0] chn;
en):# input en;
if en:
self.enabled_channels = self.enabled_channels | (1<<chn);
else:
self.enabled_channels = self.enabled_channels & ~(1<<chn);
self.write_contol_register(self.MCONTR_TOP_16BIT_ADDR + self. MCONTR_TOP_16BIT_CHN_EN, self.enabled_channels & 0xffff) # {16'b0,ENABLED_CHANNELS});
def configure_channel_priority(self,
chn, # input [ 3:0] chn;
priority): #input [15:0] priority; // (higher is more important)
self.write_contol_register(self.MCONTR_ARBIT_ADDR + chn, priority & 0xffff)# {16'b0,priority});
from __future__ import print_function
'''
# Copyright (C) 2015, Elphel.inc.
# Methods that mimic Verilog tasks used for simulation
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <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"
#import sys
#import x393_mem
#x393_pio_sequences
from import_verilog_parameters import VerilogParameters
from x393_mem import X393Mem
from x393_axi_control_status import X393AxiControlStatus
#from verilog_utils import * # concat, bits
#from verilog_utils import hx, concat, bits, getParWidth
#from verilog_utils import concat, getParWidth
#from x393_axi_control_status import concat, bits
class X393McntrlBuffers(object):
DRY_MODE= True # True
DEBUG_MODE=1
# vpars=None
x393_mem=None
x393_axi_tasks=None #x393X393AxiControlStatus
verbose=1
def __init__(self, debug_mode=1,dry_mode=True):
self.DEBUG_MODE=debug_mode
self.DRY_MODE=dry_mode
self.x393_mem=X393Mem(debug_mode,dry_mode)
self.x393_axi_tasks=X393AxiControlStatus(debug_mode,dry_mode)
self.__dict__.update(VerilogParameters.__dict__["_VerilogParameters__shared_state"]) # Add verilog parameters to the class namespace
try:
self.verbose=self.VERBOSE
except:
pass
def write_block_scanline_chn(self, #
chn, # input [3:0] chn; // buffer channel
page, # input [1:0] page;
num_bursts, # input [NUM_XFER_BITS:0] num_bursts; // number of 8-bursts to write (will be rounded up to multiple of 16)
startX, # input integer startX;
startY): #input integer startY;
print("====== write_block_scanline_chn:%d page: %x X=0x%x Y=0x%x num=%dt"%(chn, page, startX, startY,num_bursts))
if chn == 0: start_addr=self.MCONTR_BUF0_WR_ADDR + (page << 8)
elif chn == 1: start_addr=self.MCONTR_BUF1_WR_ADDR + (page << 8)
elif chn == 2: start_addr=self.MCONTR_BUF2_WR_ADDR + (page << 8)
elif chn == 3: start_addr=self.MCONTR_BUF3_WR_ADDR + (page << 8)
elif chn == 4: start_addr=self.MCONTR_BUF4_WR_ADDR + (page << 8)
else:
print("**** ERROR: Invalid channel for write_block_scanline_chn = %d"% chn)
start_addr = self.MCONTR_BUF0_WR_ADDR+ (page << 8);
num_words=num_bursts << 2;
self.write_block_incremtal (start_addr, num_words, (startX<<2) + (startY<<16));# 1 of startX is 8x16 bit, 16 bytes or 4 32-bit words
def write_block_buf(self,
start_word_address, # input [29:0] start_word_address;
num_words_or_data_list): # input integer num_words; # number of words to write (will be rounded up to multiple of 16)
if isinstance (num_words_or_data_list,int):
data=[]
for i in range(num_words_or_data_list):
data.append(i | (((i + 7) & 0xff) << 8) | (((i + 23) & 0xff) << 16) | (((i + 31) & 0xff) << 24))
else:
data=num_words_or_data_list
if self.verbose>0:
print("**** write_block_buf, start_word_address=0x%x, num+words=0x%x"%(start_word_address,len(data)))
for i,d in enumerate(data):
d= i | (((i + 7) & 0xff) << 8) | (((i + 23) & 0xff) << 16) | (((i + 31) & 0xff) << 24)
if self.verbose>2:
print(" write_block_buf 0x%x:0x%x"%(start_word_address+i,d))
self.x393_mem.axi_write_single_w(start_word_address+i, d)
def write_block_incremtal(self,
start_word_address, # input [29:0] start_word_address;
num_words, # input integer num_words; # number of words to write (will be rounded up to multiple of 16)
start_value): # input integer start_value;
if self.verbose>0:
print("**** write_block_incremtal, start_word_address=0x%x, num_words=0x%x, start_value=0x%x "%(start_word_address,num_words,start_value))
for i in range(0,num_words):
if self.verbose>2:
print(" write_block_buf 0x%x:0x%x"%(start_word_address+i,start_value+i))
self.x393_mem.axi_write_single_w(start_word_address+i, start_value+i)
def write_block_buf_chn(self, #
chn, # input integer chn; # buffer channel
page, # input [1:0] page;
num_words_or_data_list): # input integer num_words; # number of words to write (will be rounded up to multiple of 16)
start_addr=-1
if chn==0:start_addr=self.MCONTR_BUF0_WR_ADDR + (page << 8)
elif chn==1:start_addr=self.MCONTR_BUF1_WR_ADDR + (page << 8)
elif chn==2:start_addr=self.MCONTR_BUF2_WR_ADDR + (page << 8)
elif chn==3:start_addr=self.MCONTR_BUF3_WR_ADDR + (page << 8)
elif chn==4:start_addr=self.MCONTR_BUF4_WR_ADDR + (page << 8)
else:
print("**** ERROR: Invalid channel for write buffer = %d"% chn)
start_addr = self.MCONTR_BUF0_WR_ADDR+ (page << 8)
self.write_block_buf (start_addr, num_words_or_data_list)
def read_block_buf(self,
start_word_address, # input [29:0] start_word_address;
num_read, # input integer num_read; # number of words to read (will be rounded up to multiple of 16)
show_rslt=True):
if self.verbose>0:
print("**** read_block_buf, start_word_address=0x%x, num_read=0x%x "%(start_word_address,num_read))
result=[]
for i in range(num_read): #for (i = 0; i < num_read; i = i + 16) begin
d=self.x393_mem.axi_read_addr_w(start_word_address+i)
if (self.verbose>2) or show_rslt:
print(" read_block_buf 0x%x:0x%x"%(start_word_address+i,d))
result.append(d)
return result
def read_block_buf_chn(self, # S uppressThisWarning VEditor : may be unused
chn, # input [3:0] chn; # buffer channel
page, #input [1:0] page;
num_read, #input integer num_read; # number of words to read (will be rounded up to multiple of 16)
show_rslt=True):
start_addr=-1
if chn==0: start_addr=self.MCONTR_BUF0_RD_ADDR + (page << 8)
elif chn==1: start_addr=self.MCONTR_BUF1_RD_ADDR + (page << 8)
elif chn==2: start_addr=self.MCONTR_BUF2_RD_ADDR + (page << 8)
elif chn==3: start_addr=self.MCONTR_BUF3_RD_ADDR + (page << 8)
elif chn==4: start_addr=self.MCONTR_BUF4_RD_ADDR + (page << 8)
else:
print("**** ERROR: Invalid channel for read buffer = %d"%chn)
start_addr = self.MCONTR_BUF0_RD_ADDR+ (page << 8)
result=self.read_block_buf (start_addr, num_read, show_rslt)
return result
from __future__ import print_function
'''
# Copyright (C) 2015, Elphel.inc.
# Methods that mimic Verilog tasks used for simulation
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <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"
#import sys
#import x393_mem
#x393_pio_sequences
from import_verilog_parameters import VerilogParameters
from x393_mem import X393Mem
from x393_axi_control_status import X393AxiControlStatus
from x393_pio_sequences import X393PIOSequences
from x393_mcntrl_timing import X393McntrlTiming
from x393_mcntrl_buffers import X393McntrlBuffers
#from verilog_utils import * # concat, bits
#from verilog_utils import hx, concat, bits, getParWidth
from verilog_utils import concat #, getParWidth
#from x393_axi_control_status import concat, bits
class X393McntrlTests(object):
DRY_MODE= True # True
DEBUG_MODE=1
x393_mem=None
x393_axi_tasks=None #x393X393AxiControlStatus
x393_pio_sequences=None
x393_mcntrl_timing=None
x393_mcntrl_buffers=None
verbose=1
def __init__(self, debug_mode=1,dry_mode=True):
self.DEBUG_MODE= debug_mode
self.DRY_MODE= dry_mode
self.x393_mem= X393Mem(debug_mode,dry_mode)
self.x393_axi_tasks= X393AxiControlStatus(debug_mode,dry_mode)
self.x393_pio_sequences= X393PIOSequences(debug_mode,True)
self.x393_mcntrl_timing= X393McntrlTiming(debug_mode,True)
self.x393_mcntrl_buffers= X393McntrlBuffers(debug_mode,True)
self.__dict__.update(VerilogParameters.__dict__["_VerilogParameters__shared_state"]) # Add verilog parameters to the class namespace
try:
self.verbose=self.VERBOSE
except:
pass
def func_encode_mode_tiled(self, # function [6:0]
byte32, # input byte32; # 32-byte columns (0 - 16-byte columns)
keep_open, # input keep_open; # for 8 or less rows - do not close page between accesses
extra_pages, # input [1:0] extra_pages; # number of extra pages that need to stay (not to be overwritten) in the buffer
# can be used for overlapping tile read access
write_mem, # input write_mem; # write to memory mode (0 - read from memory)
enable, # input enable; # enable requests from this channel ( 0 will let current to finish, but not raise want/need)
chn_reset): # input chn_reset; # immediately reset all the internal circuitry
return concat (# func_encode_mode_tiled={
((0,1)[byte32], 1), # byte32,
((0,1)[keep_open],1), # keep_open,
(extra_pages, 2), # extra_pages,
((0,1)[write_mem],1), # write_mem,
((0,1)[enable], 1), #enable,
((1,0)[chn_reset],1)) # ~chn_reset};
def func_encode_mode_scanline(self, # function [4:0]
extra_pages, # input [1:0] extra_pages; # number of extra pages that need to stay (not to be overwritten) in the buffer
# can be used for overlapping tile read access
write_mem, # input write_mem; # write to memory mode (0 - read from memory)
enable, # input enable; # enable requests from this channel ( 0 will let current to finish, but not raise want/need)
chn_reset): # input chn_reset; # immediately reset all the internal circuitry
return concat (# func_encode_mode_tiled={
(extra_pages, 2), # extra_pages,
((0,1)[write_mem],1), # write_mem,
((0,1)[enable], 1), #enable,
((1,0)[chn_reset],1)) # ~chn_reset};
def set_all_sequences(self):
if self.verbose>0: print("SET MRS")
self.x393_pio_sequences.set_mrs(1) # reset DLL
if self.verbose>0: print("SET REFRESH")
self.x393_pio_sequences.set_refresh(
50, # input [ 9:0] t_rfc; # =50 for tCK=2.5ns
16) #input [ 7:0] t_refi; # 48/97 for normal, 8 - for simulation
if self.verbose>0: print("SET WRITE LEVELING")
self.x393_pio_sequences.set_write_lev(16) # write leveling, 16 times (full buffer - 128)
if self.verbose>0: print("SET READ PATTERNt")
self.x393_pio_sequences.set_read_pattern(8) # 8x2*64 bits, 32x32 bits to read
if self.verbose>0: print("SET WRITE BLOCK")
self.x393_pio_sequences.set_write_block(
5, # 3'h5, # bank
0x1234, # 15'h1234, # row address
0x100 # 10'h100 # column address
)
if self.verbose>0: print("SET READ BLOCK");
self.x393_pio_sequences.set_read_block (
5, # 3'h5, # bank
0x1234, # 15'h1234, # row address
0x100 # 10'h100 # column address
)
def test_write_levelling(self,
wait_complete, # Wait for operation to complete
wlev_dqs_dly= 0x80,
norm_dqs_odly=0x78):
# Set special values for DQS idelay for write leveling
self.x393_pio_sequences.wait_ps_pio_done(self.DEFAULT_STATUS_MODE,1); # not no interrupt running cycle - delays are changed immediately
self.x393_mcntrl_timing.axi_set_dqs_idelay_wlv()
# Set write buffer (from DDR3) WE signal delay for write leveling mode
self.x393_mcntrl_timing.axi_set_wbuf_delay(self.WBUF_DLY_WLV)
# TODO: Set configurable delay time instead of #80
self.x393_mcntrl_timing.axi_set_dqs_odelay(wlev_dqs_dly) # 'h80); # 'h80 - inverted, 'h60 - not - 'h80 will cause warnings during simulation
self.x393_pio_sequences.schedule_ps_pio (# schedule software-control memory operation (may need to check FIFO status first)
self.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 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) # `PS_PIO_WAIT_COMPLETE );# wait_complete; # Do not request a newe transaction from the scheduler until previous memory transaction is finished
self.x393_pio_sequences.wait_ps_pio_done(self.DEFAULT_STATUS_MODE,1); # wait previous memory transaction finished before changing delays (effective immediately)
self.x393_mcntrl_buffers.read_block_buf_chn (0, 0, 32, 1, 1); # chn=0, page=0, number of 32-bit words=32, wait_done
self.x393_mcntrl_timing.axi_set_dqs_odelay(self.DLY_DQS_ODELAY)
self.x393_pio_sequences.schedule_ps_pio ( # schedule software-control memory operation (may need to check FIFO status first)
self.WRITELEV_OFFSET, # input [9:0] seq_addr; # sequence start address
1, # 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) # `PS_PIO_WAIT_COMPLETE );# wait_complete; # Do not request a newe transaction from the scheduler until previous memory transaction is finished
self.x393_pio_sequences.wait_ps_pio_done(self.DEFAULT_STATUS_MODE,1); # wait previous memory transaction finished before changing delays (effective immediately)
rslt=self.x393_mcntrl_buffers.read_block_buf_chn (0, 1, 32, 1, 1 ); # chn=0, page=1, number of 32-bit words=32, wait_done
self.x393_mcntrl_timing.axi_set_dqs_idelay_nominal()
self.x393_mcntrl_timing.axi_set_dqs_odelay(norm_dqs_odly) # 'h78);
self.x393_mcntrl_timing.axi_set_wbuf_delay(self.WBUF_DLY_DFLT); #DFLT_WBUF_DELAY
return rslt
def test_read_pattern(self,
wait_complete): # Wait for operation to complete
self.x393_pio_sequences.schedule_ps_pio ( # schedule software-control memory operation (may need to check FIFO status first)
self.READ_PATTERN_OFFSET, # input [9:0] seq_addr; # sequence start address
2, # 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) # `PS_PIO_WAIT_COMPLETE ) # wait_complete; # Do not request a newe transaction from the scheduler until previous memory transaction is finished
self.x393_pio_sequences.wait_ps_pio_done(self.DEFAULT_STATUS_MODE,1) # wait previous memory transaction finished before changing delays (effective immediately)
return self.x393_mcntrl_buffers.read_block_buf_chn (0, 2, 32, 1, 1 ) # chn=0, page=2, number of 32-bit words=32, wait_done
def test_write_block(self,
wait_complete): # Wait for operation to complete
# write_block_buf_chn; # fill block memory - already set in set_up task
self.x393_pio_sequences.schedule_ps_pio ( # schedule software-control memory operation (may need to check FIFO status first)
self.WRITE_BLOCK_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)
1, # 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
# temporary - for debugging:
# self.x393_pio_sequences.wait_ps_pio_done(self.DEFAULT_STATUS_MODE,1) # wait previous memory transaction finished before changing delays (effective immediately)
def test_read_block(self,
wait_complete): # Wait for operation to complete
self.x393_pio_sequences.schedule_ps_pio ( # schedule software-control memory operation (may need to check FIFO status first)
self.READ_BLOCK_OFFSET, # input [9:0] seq_addr; # sequence start address
3, # 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
self.x393_pio_sequences.schedule_ps_pio ( # schedule software-control memory operation (may need to check FIFO status first)
self.READ_BLOCK_OFFSET, # input [9:0] seq_addr; # sequence start address
2, # 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
self.x393_pio_sequences.schedule_ps_pio ( # schedule software-control memory operation (may need to check FIFO status first)
self.READ_BLOCK_OFFSET, # input [9:0] seq_addr; # sequence start address
1, # 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
self.x393_pio_sequences.wait_ps_pio_done(self.DEFAULT_STATUS_MODE,1); # wait previous memory transaction finished before changing delays (effective immediately)
return self.x393_mcntrl_buffers.read_block_buf_chn (0, 3, 256, 1, 1 ) # chn=0, page=3, number of 32-bit words=256, wait_done
def test_scanline_write(self, #
channel, # input [3:0] channel;
extra_pages, # input [1:0] extra_pages;
wait_done, # input wait_done;
window_width, # input [15:0] window_width;
window_height, # input [15:0] window_height;
window_left, # input [15:0] window_left;
window_top): # input [15:0] window_top;
# integer startx,starty; # temporary - because of the vdt bug with integer ports
# pages_per_row= (window_width>>NUM_XFER_BITS)+((window_width[NUM_XFER_BITS-1:0]==0)?0:1);
pages_per_row= (window_width>>self.NUM_XFER_BITS)+(0,1)[(window_width & ((1<<self.NUM_XFER_BITS))-1)==0] # (window_width>>NUM_XFER_BITS)+((window_width[NUM_XFER_BITS-1:0]==0)?0:1);
print("====== test_scanline_write: channel=%d, extra_pages=%d, wait_done=%d"%
(channel, extra_pages, wait_done))
if channel == 1:
start_addr= self.MCNTRL_SCANLINE_CHN1_ADDR
status_address= self.MCNTRL_TEST01_STATUS_REG_CHN1_ADDR
status_control_address= self.MCNTRL_TEST01_ADDR + self.MCNTRL_TEST01_CHN1_STATUS_CNTRL
test_mode_address= self.MCNTRL_TEST01_ADDR + self.MCNTRL_TEST01_CHN1_MODE
elif channel == 3:
start_addr= self.MCNTRL_SCANLINE_CHN3_ADDR
status_address= self.MCNTRL_TEST01_STATUS_REG_CHN3_ADDR
status_control_address= self.MCNTRL_TEST01_ADDR + self.MCNTRL_TEST01_CHN3_STATUS_CNTRL
test_mode_address= self.MCNTRL_TEST01_ADDR + self.MCNTRL_TEST01_CHN3_MODE
else:
print("**** ERROR: Invalid channel, only 1 and 3 are valid")
start_addr= self.MCNTRL_SCANLINE_CHN1_ADDR
status_address= self.MCNTRL_TEST01_STATUS_REG_CHN1_ADDR
status_control_address= self.MCNTRL_TEST01_ADDR + self.MCNTRL_TEST01_CHN1_STATUS_CNTRL
test_mode_address= self.MCNTRL_TEST01_ADDR + self.MCNTRL_TEST01_CHN1_MODE
mode= self.func_encode_mode_scanline(
extra_pages,
1, # write_mem,
1, # enable
0) # chn_reset
self.x393_axi_tasks.write_contol_register(start_addr + self.MCNTRL_SCANLINE_STARTADDR, self.FRAME_START_ADDRESS); # RA=80, CA=0, BA=0 22-bit frame start address (3 CA LSBs==0. BA==0)
self.x393_axi_tasks.write_contol_register(start_addr + self.MCNTRL_SCANLINE_FRAME_FULL_WIDTH, self.FRAME_FULL_WIDTH);
self.x393_axi_tasks.write_contol_register(start_addr + self.MCNTRL_SCANLINE_WINDOW_WH, {window_height,window_width}); #WINDOW_WIDTH + (WINDOW_HEIGHT<<16));
self.x393_axi_tasks.write_contol_register(start_addr + self.MCNTRL_SCANLINE_WINDOW_X0Y0, {window_top,window_left}); #WINDOW_X0+ (WINDOW_Y0<<16));
self.x393_axi_tasks.write_contol_register(start_addr + self.MCNTRL_SCANLINE_WINDOW_STARTXY, self.SCANLINE_STARTX+(self.SCANLINE_STARTY<<16));
self.x393_axi_tasks.write_contol_register(start_addr + self.MCNTRL_SCANLINE_MODE, mode);
self.x393_axi_tasks.configure_channel_priority(channel,0); # lowest priority channel 3
# enable_memcntrl_channels(16'h000b); # channels 0,1,3 are enabled
self.x393_axi_tasks.enable_memcntrl_en_dis(channel,1);
self.x393_axi_tasks.write_contol_register(test_mode_address, self.TEST01_START_FRAME);
for ii in range(0,self.TEST_INITIAL_BURST): # for (ii=0;ii<TEST_INITIAL_BURST;ii=ii+1) begin
# VDT bugs: 1:does not propagate undefined width through ?:, 2: - does not allow to connect it to task integer input, 3: shows integer input width as 1
if pages_per_row > 1:
if (ii % pages_per_row) < (pages_per_row-1):
xfer_size= 1 << self.NUM_XFER_BITS
else:
xfer_size= window_width % (1<<self.NUM_XFER_BITS)
else:
xfer_size= window_width & 0xffff
print("########### test_scanline_write block %d: channel=%d"%(ii, channel));
startx=window_left + ((ii % pages_per_row) << self.NUM_XFER_BITS)
starty=window_top + (ii / pages_per_row);
self.x393_mcntrl_buffers.write_block_scanline_chn(
channel,
(ii & 3),
xfer_size,
startx, #window_left + ((ii % pages_per_row)<<NUM_XFER_BITS), # SCANLINE_CUR_X,
starty) # window_top + (ii / pages_per_row)); # SCANLINE_CUR_Y);\
for ii in range(window_height * pages_per_row): # for (ii=0;ii< (window_height * pages_per_row) ;ii = ii+1) begin # here assuming 1 page per line
if (ii >= self.TEST_INITIAL_BURST): # begin # wait page ready and fill page after first 4 are filled
self.x393_axi_tasks.wait_status_condition (
status_address, # MCNTRL_TEST01_STATUS_REG_CHN3_ADDR,
status_control_address, # MCNTRL_TEST01_ADDR + MCNTRL_TEST01_CHN3_STATUS_CNTRL,
self.DEFAULT_STATUS_MODE,
(ii-self.TEST_INITIAL_BURST)<<16, # 4-bit page number
0xf << 16, #'hf << 16, # mask for the 4-bit page number
1, # not equal to
(0,1)[ii == self.TEST_INITIAL_BURST]) # synchronize sequence number - only first time, next just wait fro auto update
if pages_per_row > 1:
if (ii % pages_per_row) < (pages_per_row-1):
xfer_size= 1 << self.NUM_XFER_BITS
else:
xfer_size= window_width % (1<<self.NUM_XFER_BITS)
else:
xfer_size= window_width & 0xffff
print("########### test_scanline_write block %d: channel=%d"%(ii, channel));
startx=window_left + ((ii % pages_per_row) << self.NUM_XFER_BITS);
starty=window_top + (ii / pages_per_row);
self.x393_mcntrl_buffers.write_block_scanline_chn(
channel,
(ii & 3),
xfer_size,
startx, # window_left + ((ii % pages_per_row)<<NUM_XFER_BITS), # SCANLINE_CUR_X,
starty) # window_top + (ii / pages_per_row)); # SCANLINE_CUR_Y);
self.x393_axi_tasks.write_contol_register(test_mode_address, self.TEST01_NEXT_PAGE)
if wait_done:
self.x393_axi_tasks.wait_status_condition ( # may also be read directly from the same bit of mctrl_linear_rw (address=5) status
status_address, # MCNTRL_TEST01_STATUS_REG_CHN3_ADDR,
status_control_address, # MCNTRL_TEST01_ADDR + MCNTRL_TEST01_CHN3_STATUS_CNTRL,
self.DEFAULT_STATUS_MODE,
2 << self.STATUS_2LSB_SHFT, # bit 24 - busy, bit 25 - frame done
2 << self.STATUS_2LSB_SHFT, # mask for the 4-bit page number
0, # equal to
0); # no need to synchronize sequence number
# enable_memcntrl_en_dis(channel,0); # disable channel
def test_scanline_read(self, # SuppressThisWarning VEditor - may be unused
channel, # input [3:0] channel;
extra_pages, # input [1:0] extra_pages;
show_data, # input extra_pages;
window_width, # input [15:0] window_width;
window_height, # input [15:0] window_height;
window_left, # input [15:0] window_left;
window_top): # input [15:0] window_top;
result=[] # will be a 2-d array
# pages_per_row= (window_width>>NUM_XFER_BITS)+((window_width[NUM_XFER_BITS-1:0]==0)?0:1);
pages_per_row= (window_width>>self.NUM_XFER_BITS)+(0,1)[(window_width & ((1<<self.NUM_XFER_BITS))-1)==0] # (window_width>>NUM_XFER_BITS)+((window_width[NUM_XFER_BITS-1:0]==0)?0:1);
print("====== test_scanline_read: channel=%d, extra_pages=%d, show_data=%d"%
(channel, extra_pages, show_data))
if channel == 1:
start_addr= self.MCNTRL_SCANLINE_CHN1_ADDR
status_address= self.MCNTRL_TEST01_STATUS_REG_CHN1_ADDR
status_control_address= self.MCNTRL_TEST01_ADDR + self.MCNTRL_TEST01_CHN1_STATUS_CNTRL
test_mode_address= self.MCNTRL_TEST01_ADDR + self.MCNTRL_TEST01_CHN1_MODE
elif channel == 3:
start_addr= self.MCNTRL_SCANLINE_CHN3_ADDR
status_address= self.MCNTRL_TEST01_STATUS_REG_CHN3_ADDR
status_control_address= self.MCNTRL_TEST01_ADDR + self.MCNTRL_TEST01_CHN3_STATUS_CNTRL
test_mode_address= self.MCNTRL_TEST01_ADDR + self.MCNTRL_TEST01_CHN3_MODE
else:
print("**** ERROR: Invalid channel, only 1 and 3 are valid")
start_addr= self.MCNTRL_SCANLINE_CHN1_ADDR
status_address= self.MCNTRL_TEST01_STATUS_REG_CHN1_ADDR
status_control_address= self.MCNTRL_TEST01_ADDR + self.MCNTRL_TEST01_CHN1_STATUS_CNTRL
test_mode_address= self.MCNTRL_TEST01_ADDR + self.MCNTRL_TEST01_CHN1_MODE
mode= self.func_encode_mode_scanline(
extra_pages,
0, # write_mem,
1, # enable
0) # chn_reset
# program to the
self.x393_axi_tasks.write_contol_register(start_addr + self.MCNTRL_SCANLINE_STARTADDR, self.FRAME_START_ADDRESS); # RA=80, CA=0, BA=0 22-bit frame start address (3 CA LSBs==0. BA==0)
self.x393_axi_tasks.write_contol_register(start_addr + self.MCNTRL_SCANLINE_FRAME_FULL_WIDTH, self.FRAME_FULL_WIDTH);
self.x393_axi_tasks.write_contol_register(start_addr + self.MCNTRL_SCANLINE_WINDOW_WH, {window_height,window_width}); #WINDOW_WIDTH + (WINDOW_HEIGHT<<16));
self.x393_axi_tasks.write_contol_register(start_addr + self.MCNTRL_SCANLINE_WINDOW_X0Y0, {window_top,window_left}); #WINDOW_X0+ (WINDOW_Y0<<16));
self.x393_axi_tasks.write_contol_register(start_addr + self.MCNTRL_SCANLINE_WINDOW_STARTXY, self.SCANLINE_STARTX+(self.SCANLINE_STARTY<<16));
self.x393_axi_tasks.write_contol_register(start_addr + self.MCNTRL_SCANLINE_MODE, mode);# set mode register: {extra_pages[1:0],enable,!reset}
self.x393_axi_tasks.configure_channel_priority(channel,0); # lowest priority channel 3
self.x393_axi_tasks.enable_memcntrl_en_dis(channel,1);
self.x393_axi_tasks.write_contol_register(test_mode_address, self.TEST01_START_FRAME);
for ii in range(window_height * pages_per_row): # for (ii=0;ii<(window_height * pages_per_row);ii = ii+1) begin
if pages_per_row > 1:
if (ii % pages_per_row) < (pages_per_row-1):
xfer_size= 1 << self.NUM_XFER_BITS
else:
xfer_size= window_width % (1<<self.NUM_XFER_BITS)
else:
xfer_size= window_width & 0xffff
self.x393_axi_tasks.wait_status_condition (
status_address, #MCNTRL_TEST01_STATUS_REG_CHN2_ADDR,
status_control_address, # MCNTRL_TEST01_ADDR + MCNTRL_TEST01_CHN2_STATUS_CNTRL,
self.DEFAULT_STATUS_MODE,
(ii) << 16, # -TEST_INITIAL_BURST)<<16, # 4-bit page number
0xf << 16, #'hf << 16, # mask for the 4-bit page number
1, # not equal to
(0,1)[ii == 0]) # synchronize sequence number - only first time, next just wait fro auto update
# read block (if needed), for now just sikip
if (show_data):
print("########### test_scanline_read block %d: channel=%d"%(ii, channel));
result.append(self.x393_mcntrl_buffers.read_block_buf_chn (
channel,
(ii & 3),
xfer_size <<2,
1, # chn=0, page=3, number of 32-bit words=256, wait_done
show_data))
self.x393_axi_tasks.write_contol_register(test_mode_address, self.TEST01_NEXT_PAGE)
return result
def test_tiled_write(self, #
channel, # input [3:0] channel;
byte32, # input byte32;
keep_open, # input keep_open;
extra_pages, # input [1:0] extra_pages;
wait_done, # input wait_done;
window_width, # input [15:0] window_width;
window_height, # input [15:0] window_height;
window_left, # input [15:0] window_left;
window_top, # input [15:0] window_top;
tile_width, # input [ 7:0] tile_width;
tile_height, # input [ 7:0] tile_height;
tile_vstep): # input [ 7:0] tile_vstep;
# tiles_per_row= (window_width/tile_width)+ ((window_width % tile_width==0)?0:1);
tiles_per_row= (window_width/tile_width)+ (0,1)[(window_width % tile_width)==0]
tile_rows_per_window= ((window_height-1)/tile_vstep) + 1
tile_size= tile_width*tile_height;
channel= (0,1)[channel]
keep_open= (0,1)[keep_open]
wait_done= (0,1)[wait_done]
print("====== test_tiled_write: channel=%d, byte32=%d, keep_open=%d, extra_pages=%d, wait_done=%d"%
(channel, byte32, keep_open, extra_pages, wait_done))
if channel == 2:
start_addr= self.MCNTRL_TILED_CHN2_ADDR
status_address= self.MCNTRL_TEST01_STATUS_REG_CHN2_ADDR
status_control_address= self.MCNTRL_TEST01_ADDR + self.MCNTRL_TEST01_CHN2_STATUS_CNTRL
test_mode_address= self.MCNTRL_TEST01_ADDR + self.MCNTRL_TEST01_CHN2_MODE
elif channel == 4:
start_addr= self.MCNTRL_TILED_CHN4_ADDR;
status_address= self.MCNTRL_TEST01_STATUS_REG_CHN4_ADDR;
status_control_address= self.MCNTRL_TEST01_ADDR + self.MCNTRL_TEST01_CHN4_STATUS_CNTRL;
test_mode_address= self.MCNTRL_TEST01_ADDR + self.MCNTRL_TEST01_CHN4_MODE;
else:
print("**** ERROR: Invalid channel, only 2 and 4 are valid");
start_addr= self.MCNTRL_TILED_CHN2_ADDR;
status_address= self.MCNTRL_TEST01_STATUS_REG_CHN2_ADDR;
status_control_address= self.MCNTRL_TEST01_ADDR + self.MCNTRL_TEST01_CHN2_STATUS_CNTRL;
test_mode_address= self.MCNTRL_TEST01_ADDR + self.MCNTRL_TEST01_CHN2_MODE;
mode= self.func_encode_mode_tiled(
byte32,
keep_open,
extra_pages,
1, # write_mem,
1, # enable
0) # chn_reset
self.x393_axi_tasks.write_contol_register(start_addr + self.MCNTRL_TILED_STARTADDR,
self.FRAME_START_ADDRESS) # RA=80, CA=0, BA=0 22-bit frame start address (3 CA LSBs==0. BA==0)
self.x393_axi_tasks.write_contol_register(start_addr + self.MCNTRL_TILED_FRAME_FULL_WIDTH,
self.FRAME_FULL_WIDTH)
self.x393_axi_tasks.write_contol_register(start_addr + self.MCNTRL_TILED_WINDOW_WH,
concat((window_height,16),
(window_width, 16))) # {window_height,window_width});
self.x393_axi_tasks.write_contol_register(start_addr + self.MCNTRL_TILED_WINDOW_X0Y0,
concat((window_top, 16),
(window_left, 16))) # {window_top,window_left});
self.x393_axi_tasks.write_contol_register(start_addr + self.MCNTRL_TILED_WINDOW_STARTXY,
concat((self.TILED_STARTY, 16),
(self.TILED_STARTX, 16))) # TILED_STARTX+(TILED_STARTY<<16));
self.x393_axi_tasks.write_contol_register(start_addr + self.MCNTRL_TILED_TILE_WHS,
concat((tile_vstep, 8),
(tile_height, 8),
(tile_width, 8))) # {8'b0,tile_vstep,tile_height,tile_width});#tile_width+(tile_height<<8)+(tile_vstep<<16));
self.x393_axi_tasks.write_contol_register(start_addr + self.MCNTRL_TILED_MODE, mode);# set mode register: {extra_pages[1:0],enable,!reset}
self.x393_axi_tasks.configure_channel_priority(channel,0) # lowest priority channel 3
self.x393_axi_tasks.enable_memcntrl_en_dis(channel,1);
self.x393_axi_tasks.write_contol_register(test_mode_address, self.TEST01_START_FRAME);
for ii in range(self.TEST_INITIAL_BURST): # for (ii=0;ii<TEST_INITIAL_BURST;ii=ii+1) begin
print("########### test_tiled_write block %d: channel=%d"%( ii, channel))
startx = window_left + ((ii % tiles_per_row) * tile_width)
starty = window_top + (ii / tile_rows_per_window) # SCANLINE_CUR_Y);
self.x393_mcntrl_buffers.write_block_scanline_chn( # TODO: Make a different tile buffer data, matching the order
channel, # channel
(ii & 3),
tile_size,
startx, #window_left + ((ii % tiles_per_row) * tile_width),
starty); #window_top + (ii / tile_rows_per_window)); # SCANLINE_CUR_Y);\
for ii in range(tiles_per_row * tile_rows_per_window): # for (ii=0;ii<(tiles_per_row * tile_rows_per_window);ii = ii+1) begin
if ii >= self.TEST_INITIAL_BURST: # ) begin # wait page ready and fill page after first 4 are filled
self.x393_axi_tasks.wait_status_condition (
status_address, # MCNTRL_TEST01_STATUS_REG_CHN5_ADDR,
status_control_address, # MCNTRL_TEST01_ADDR + MCNTRL_TEST01_CHN5_STATUS_CNTRL,
self.DEFAULT_STATUS_MODE,
(ii-self.TEST_INITIAL_BURST)<<16, # 4-bit page number
0xf << 16, # 'hf << 16, # mask for the 4-bit page number
1, # not equal to
(0,1)[ii == self.TEST_INITIAL_BURST]); # synchronize sequence number - only first time, next just wait fro auto update
print("########### test_tiled_write block %d: channel=%d"%(ii, channel))
startx = window_left + ((ii % tiles_per_row) * tile_width);
starty = window_top + (ii / tile_rows_per_window);
self.x393_mcntrl_buffers.write_block_scanline_chn( # TODO: Make a different tile buffer data, matching the order
channel, # channel
(ii & 3),
tile_size,
startx, # window_left + ((ii % tiles_per_row) * tile_width),
starty) # window_top + (ii / tile_rows_per_window)); # SCANLINE_CUR_Y);\
self.x393_axi_tasks.write_contol_register(test_mode_address, self.TEST01_NEXT_PAGE);
if wait_done:
self.x393_axi_tasks.wait_status_condition( # may also be read directly from the same bit of mctrl_linear_rw (address=5) status
status_address, # MCNTRL_TEST01_STATUS_REG_CHN3_ADDR,
status_control_address, # MCNTRL_TEST01_ADDR + MCNTRL_TEST01_CHN3_STATUS_CNTRL,
self.DEFAULT_STATUS_MODE,
2 << self.STATUS_2LSB_SHFT, # bit 24 - busy, bit 25 - frame done
2 << self.STATUS_2LSB_SHFT, # mask for the 4-bit page number
0, # equal to
0) # no need to synchronize sequence number
# enable_memcntrl_en_dis(channel,0); # disable channel
def test_tiled_read(self, #\
channel, # input [3:0] channel;
byte32, # input byte32;
keep_open, # input keep_open;
extra_pages, # input [1:0] extra_pages;
show_data, # input show_data;
window_width, # input [15:0] window_width;
window_height, # input [15:0] window_height;
window_left, # input [15:0] window_left;
window_top, # input [15:0] window_top;
tile_width, # input [ 7:0] tile_width;
tile_height, # input [ 7:0] tile_height;
tile_vstep): # input [ 7:0] tile_vstep;
result=[] # will be a 2-d array
# tiles_per_row= (window_width/tile_width)+ ((window_width % tile_width==0)?0:1);
tiles_per_row= (window_width/tile_width)+ (0,1)[(window_width % tile_width)==0]
tile_rows_per_window= ((window_height-1)/tile_vstep) + 1
tile_size= tile_width*tile_height;
channel= (0,1)[channel]
keep_open= (0,1)[keep_open]
show_data= (0,1)[show_data]
print("====== test_tiled_read: channel=%d, byte32=%d, keep_open=%d, extra_pages=%d, show_data=%d"%
(channel, byte32, keep_open, extra_pages, show_data))
if channel == 2:
start_addr= self.MCNTRL_TILED_CHN2_ADDR;
status_address= self.MCNTRL_TEST01_STATUS_REG_CHN2_ADDR;
status_control_address= self.MCNTRL_TEST01_ADDR + self.MCNTRL_TEST01_CHN2_STATUS_CNTRL;
test_mode_address= self.MCNTRL_TEST01_ADDR + self.MCNTRL_TEST01_CHN2_MODE;
elif channel == 4:
start_addr= self.MCNTRL_TILED_CHN4_ADDR;
status_address= self.MCNTRL_TEST01_STATUS_REG_CHN4_ADDR;
status_control_address= self.MCNTRL_TEST01_ADDR + self.MCNTRL_TEST01_CHN4_STATUS_CNTRL;
test_mode_address= self.MCNTRL_TEST01_ADDR + self.MCNTRL_TEST01_CHN4_MODE;
else:
print("**** ERROR: Invalid channel, only 2 and 4 are valid");
start_addr= self.MCNTRL_TILED_CHN2_ADDR;
status_address= self.MCNTRL_TEST01_STATUS_REG_CHN2_ADDR;
status_control_address= self.MCNTRL_TEST01_ADDR + self.MCNTRL_TEST01_CHN2_STATUS_CNTRL;
test_mode_address= self.MCNTRL_TEST01_ADDR + self.MCNTRL_TEST01_CHN2_MODE;
mode= self.func_encode_mode_tiled(
byte32,
keep_open,
extra_pages,
0, # write_mem,
1, # enable
0) # chn_reset
self.x393_axi_tasks.write_contol_register(start_addr + self.MCNTRL_TILED_STARTADDR,
self.FRAME_START_ADDRESS) # RA=80, CA=0, BA=0 22-bit frame start address (3 CA LSBs==0. BA==0)
self.x393_axi_tasks.write_contol_register(start_addr + self.MCNTRL_TILED_FRAME_FULL_WIDTH,
self.FRAME_FULL_WIDTH)
self.x393_axi_tasks.write_contol_register(start_addr + self.MCNTRL_TILED_WINDOW_WH,
concat((window_height,16),
(window_width, 16))) # {window_height,window_width});
self.x393_axi_tasks.write_contol_register(start_addr + self.MCNTRL_TILED_WINDOW_X0Y0,
concat((window_top, 16),
(window_left, 16))) # {window_top,window_left});
self.x393_axi_tasks.write_contol_register(start_addr + self.MCNTRL_TILED_WINDOW_STARTXY,
concat((self.TILED_STARTY, 16),
(self.TILED_STARTX, 16))) # TILED_STARTX+(TILED_STARTY<<16));
self.x393_axi_tasks.write_contol_register(start_addr + self.MCNTRL_TILED_TILE_WHS,
concat((tile_vstep, 8),
(tile_height, 8),
(tile_width, 8))) # {8'b0,tile_vstep,tile_height,tile_width});#tile_width+(tile_height<<8)+(tile_vstep<<16));
self.x393_axi_tasks.write_contol_register(start_addr + self.MCNTRL_TILED_MODE, mode);# set mode register: {extra_pages[1:0],enable,!reset}
self.x393_axi_tasks.configure_channel_priority(channel,0) # lowest priority channel 3
self.x393_axi_tasks.enable_memcntrl_en_dis(channel,1);
self.x393_axi_tasks.write_contol_register(test_mode_address, self.TEST01_START_FRAME);
for ii in range(tiles_per_row * tile_rows_per_window): # (ii=0;ii<(tiles_per_row * tile_rows_per_window);ii = ii+1) begin
self.x393_axi_tasks.wait_status_condition (
status_address, # MCNTRL_TEST01_STATUS_REG_CHN4_ADDR,
status_control_address, # MCNTRL_TEST01_ADDR + MCNTRL_TEST01_CHN4_STATUS_CNTRL,
self.DEFAULT_STATUS_MODE,
ii << 16, # -TEST_INITIAL_BURST)<<16, # 4-bit page number
0xf<< 16, #'hf << 16, # mask for the 4-bit page number
1, # not equal to
(0,1)[ii == 0]) # synchronize sequence number - only first time, next just wait fro auto update
if (show_data):
print("########### test_tiled_read block %d: channel=%d"%(ii, channel))
result.append(self.x393_mcntrl_buffers.read_block_buf_chn (channel,
(ii & 3),
tile_size <<2,
1, # chn=0, page=3, number of 32-bit words=256, wait_done
show_data))
self.x393_axi_tasks.write_contol_register(test_mode_address, self.TEST01_NEXT_PAGE);
# enable_memcntrl_en_dis(channel,0); # disable channel
return result
...@@ -45,7 +45,6 @@ class X393McntrlTiming(object): ...@@ -45,7 +45,6 @@ class X393McntrlTiming(object):
x393_mem=None x393_mem=None
x393_axi_tasks=None #x393X393AxiControlStatus x393_axi_tasks=None #x393X393AxiControlStatus
target_phase=0 # TODO: set! target_phase=0 # TODO: set!
target_phase=0
def __init__(self, debug_mode=1,dry_mode=True): def __init__(self, debug_mode=1,dry_mode=True):
self.DEBUG_MODE=debug_mode self.DEBUG_MODE=debug_mode
self.DRY_MODE=dry_mode self.DRY_MODE=dry_mode
...@@ -152,6 +151,12 @@ class X393McntrlTiming(object): ...@@ -152,6 +151,12 @@ class X393McntrlTiming(object):
self.x393_axi_tasks.write_contol_register(self.DLY_SET,0) self.x393_axi_tasks.write_contol_register(self.DLY_SET,0)
self.target_phase = phase self.target_phase = phase
def wait_phase_shifter_ready(self):
data=self.x393_axi_tasks.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.x393_axi_tasks.read_and_wait_status(self.MCONTR_PHY_STATUS_REG_ADDR)
if self.DRY_MODE: break
def axi_set_wbuf_delay(self, def axi_set_wbuf_delay(self,
delay): # input [3:0] delay; delay): # input [3:0] delay;
print("SET WBUF DELAY=0x%x"%delay) print("SET WBUF DELAY=0x%x"%delay)
......
...@@ -105,3 +105,77 @@ class X393Mem(object): ...@@ -105,3 +105,77 @@ class X393Mem(object):
def axi_read_addr_w(self,addr): def axi_read_addr_w(self,addr):
return self.axi_read_addr(addr<<2) return self.axi_read_addr(addr<<2)
'''
task axi_write_addr_data;
input [11:0] id;
input [31:0] addr;
input [31:0] data;
input [ 3:0] len;
input [ 1:0] burst;
input data_en; // if 0 - do not send data, only address
input [ 3:0] wstrb;
input last;
reg data_sent;
// wire data_sent_d;
// assign #(.1) data_sent_d= data_sent;
begin
wait (!CLK && AW_READY);
AWID_IN_r <= id;
AWADDR_IN_r <= addr;
AWLEN_IN_r <= len;
AWSIZE_IN_r <= 3'b010;
AWBURST_IN_r <= burst;
AW_SET_CMD_r <= 1'b1;
if (data_en && W_READY) begin
WID_IN_r <= id;
WDATA_IN_r <= data;
WSTRB_IN_r <= wstrb;
WLAST_IN_r <= last;
W_SET_CMD_r <= 1'b1;
data_sent <= 1'b1;
end else begin
data_sent <= 1'b0;
end
DEBUG1 <=1'b1;
wait (CLK);
DEBUG1 <=1'b0;
AWID_IN_r <= 'hz;
AWADDR_IN_r <= 'hz;
AWLEN_IN_r <= 'hz;
AWSIZE_IN_r <= 'hz;
AWBURST_IN_r <= 'hz;
AW_SET_CMD_r <= 1'b0;
DEBUG2 <=1'b1;
if (data_sent) begin
WID_IN_r <= 'hz;
WDATA_IN_r <= 'hz;
WSTRB_IN_r <= 'hz;
WLAST_IN_r <= 'hz;
W_SET_CMD_r <= 1'b0;
end
// Now sent data if it was not sent simultaneously with the address
if (data_en && !data_sent) begin
DEBUG3 <=1'b1;
wait (!CLK && W_READY);
DEBUG3 <=1'b0;
WID_IN_r <= id;
WDATA_IN_r <= data;
WSTRB_IN_r <= wstrb;
WLAST_IN_r <= last;
W_SET_CMD_r <= 1'b1;
wait (CLK);
DEBUG3 <=1'bx;
WID_IN_r <= 'hz;
WDATA_IN_r <= 'hz;
WSTRB_IN_r <= 'hz;
WLAST_IN_r <= 'hz;
W_SET_CMD_r <= 1'b0;
end
DEBUG2 <=1'b0;
#0.1;
data_sent <= 1'b0;
#0.1;
end
endtask
'''
\ No newline at end of file
...@@ -64,7 +64,7 @@ class X393PIOSequences(object): ...@@ -64,7 +64,7 @@ class X393PIOSequences(object):
# __dict__.update(VerilogParameters.__dict__) # Add verilog parameters to the class namespace # __dict__.update(VerilogParameters.__dict__) # Add verilog parameters to the class namespace
''' '''
def schedule_ps_pio(self, #; // shedule software-control memory operation (may need to check FIFO status first) def schedule_ps_pio(self, #; // schedule software-control memory operation (may need to check FIFO status first)
seq_addr, # input [9:0] seq_addr; // sequence start address seq_addr, # input [9:0] seq_addr; // sequence start address
page, # input [1:0] page; // buffer page number 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) urgent, # input urgent; // high priority request (only for competion wityh other channels, wiil not pass in this FIFO)
...@@ -81,7 +81,7 @@ class X393PIOSequences(object): ...@@ -81,7 +81,7 @@ class X393PIOSequences(object):
def wait_ps_pio_ready(self, #; // wait PS PIO module can accept comamnds (fifo half empty) def wait_ps_pio_ready(self, #; // wait PS PIO module can accept comamnds (fifo half empty)
mode, # input [1:0] mode; mode, # input [1:0] mode;
sync_seq): # input sync_seq; // synchronize sequences sync_seq): # input sync_seq; // synchronize sequences
self.wait_status_condition ( self.x393_axi_tasks.wait_status_condition (
self.MCNTRL_PS_STATUS_REG_ADDR, self.MCNTRL_PS_STATUS_REG_ADDR,
self.MCNTRL_PS_ADDR + self.MCNTRL_PS_STATUS_CNTRL, self.MCNTRL_PS_ADDR + self.MCNTRL_PS_STATUS_CNTRL,
mode & 3, mode & 3,
...@@ -93,7 +93,7 @@ class X393PIOSequences(object): ...@@ -93,7 +93,7 @@ class X393PIOSequences(object):
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
self.wait_status_condition ( self.x393_axi_tasks.wait_status_condition (
self.MCNTRL_PS_STATUS_REG_ADDR, self.MCNTRL_PS_STATUS_REG_ADDR,
self.MCNTRL_PS_ADDR + self.MCNTRL_PS_STATUS_CNTRL, self.MCNTRL_PS_ADDR + self.MCNTRL_PS_STATUS_CNTRL,
mode & 3, mode & 3,
......
...@@ -306,7 +306,7 @@ always #(CLKIN_PERIOD/2) CLK = ~CLK; ...@@ -306,7 +306,7 @@ always #(CLKIN_PERIOD/2) CLK = ~CLK;
// set MR registers in DDR3 memory, run DCI calibration (long) // set MR registers in DDR3 memory, run DCI calibration (long)
wait_ps_pio_ready(DEFAULT_STATUS_MODE, 1); // wait FIFO not half full wait_ps_pio_ready(DEFAULT_STATUS_MODE, 1); // wait FIFO not half full
schedule_ps_pio ( // shedule software-control memory operation (may need to check FIFO status first) 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 INITIALIZE_OFFSET, // input [9:0] seq_addr; // sequence start address
0, // input [1:0] page; // buffer page number 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 urgent; // high priority request (only for competion with other channels, wiil not pass in this FIFO)
...@@ -1097,7 +1097,7 @@ task test_write_levelling; // SuppressThisWarning VEditor - may be unused ...@@ -1097,7 +1097,7 @@ task test_write_levelling; // SuppressThisWarning VEditor - may be unused
// Set write buffer (from DDR3) WE signal delay for write leveling mode // Set write buffer (from DDR3) WE signal delay for write leveling mode
axi_set_wbuf_delay(WBUF_DLY_WLV); axi_set_wbuf_delay(WBUF_DLY_WLV);
axi_set_dqs_odelay('h80); // 'h80 - inverted, 'h60 - not - 'h80 will cause warnings during simulation axi_set_dqs_odelay('h80); // 'h80 - inverted, 'h60 - not - 'h80 will cause warnings during simulation
schedule_ps_pio ( // shedule software-control memory operation (may need to check FIFO status first) schedule_ps_pio ( // schedule software-control memory operation (may need to check FIFO status first)
WRITELEV_OFFSET, // input [9:0] seq_addr; // sequence start address WRITELEV_OFFSET, // input [9:0] seq_addr; // sequence start address
0, // input [1:0] page; // buffer page number 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 urgent; // high priority request (only for competion with other channels, wiil not pass in this FIFO)
...@@ -1108,7 +1108,7 @@ task test_write_levelling; // SuppressThisWarning VEditor - may be unused ...@@ -1108,7 +1108,7 @@ task test_write_levelling; // SuppressThisWarning VEditor - may be unused
read_block_buf_chn (0, 0, 32, 1 ); // chn=0, page=0, number of 32-bit words=32, wait_done read_block_buf_chn (0, 0, 32, 1 ); // chn=0, page=0, number of 32-bit words=32, wait_done
// @ (negedge rstb); // @ (negedge rstb);
axi_set_dqs_odelay(DLY_DQS_ODELAY); axi_set_dqs_odelay(DLY_DQS_ODELAY);
schedule_ps_pio ( // shedule software-control memory operation (may need to check FIFO status first) schedule_ps_pio ( // schedule software-control memory operation (may need to check FIFO status first)
WRITELEV_OFFSET, // input [9:0] seq_addr; // sequence start address WRITELEV_OFFSET, // input [9:0] seq_addr; // sequence start address
1, // input [1:0] page; // buffer page number 1, // 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 urgent; // high priority request (only for competion with other channels, wiil not pass in this FIFO)
...@@ -1128,7 +1128,7 @@ endtask ...@@ -1128,7 +1128,7 @@ endtask
task test_read_pattern; // SuppressThisWarning VEditor - may be unused task test_read_pattern; // SuppressThisWarning VEditor - may be unused
begin begin
schedule_ps_pio ( // shedule software-control memory operation (may need to check FIFO status first) schedule_ps_pio ( // schedule software-control memory operation (may need to check FIFO status first)
READ_PATTERN_OFFSET, // input [9:0] seq_addr; // sequence start address READ_PATTERN_OFFSET, // input [9:0] seq_addr; // sequence start address
2, // input [1:0] page; // buffer page number 2, // 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 urgent; // high priority request (only for competion with other channels, wiil not pass in this FIFO)
...@@ -1142,7 +1142,7 @@ endtask ...@@ -1142,7 +1142,7 @@ endtask
task test_write_block; // SuppressThisWarning VEditor - may be unused task test_write_block; // SuppressThisWarning VEditor - may be unused
begin begin
// write_block_buf_chn; // fill block memory - already set in set_up task // write_block_buf_chn; // fill block memory - already set in set_up task
schedule_ps_pio ( // shedule software-control memory operation (may need to check FIFO status first) schedule_ps_pio ( // schedule software-control memory operation (may need to check FIFO status first)
WRITE_BLOCK_OFFSET, // input [9:0] seq_addr; // sequence start address WRITE_BLOCK_OFFSET, // input [9:0] seq_addr; // sequence start address
0, // input [1:0] page; // buffer page number 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 urgent; // high priority request (only for competion with other channels, wiil not pass in this FIFO)
...@@ -1155,19 +1155,19 @@ endtask ...@@ -1155,19 +1155,19 @@ endtask
task test_read_block; // SuppressThisWarning VEditor - may be unused task test_read_block; // SuppressThisWarning VEditor - may be unused
begin begin
schedule_ps_pio ( // shedule software-control memory operation (may need to check FIFO status first) schedule_ps_pio ( // schedule software-control memory operation (may need to check FIFO status first)
READ_BLOCK_OFFSET, // input [9:0] seq_addr; // sequence start address READ_BLOCK_OFFSET, // input [9:0] seq_addr; // sequence start address
3, // input [1:0] page; // buffer page number 3, // 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 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 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 `PS_PIO_WAIT_COMPLETE );// wait_complete; // Do not request a newe transaction from the scheduler until previous memory transaction is finished
schedule_ps_pio ( // shedule software-control memory operation (may need to check FIFO status first) schedule_ps_pio ( // schedule software-control memory operation (may need to check FIFO status first)
READ_BLOCK_OFFSET, // input [9:0] seq_addr; // sequence start address READ_BLOCK_OFFSET, // input [9:0] seq_addr; // sequence start address
2, // input [1:0] page; // buffer page number 2, // 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 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 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 `PS_PIO_WAIT_COMPLETE );// wait_complete; // Do not request a newe transaction from the scheduler until previous memory transaction is finished
schedule_ps_pio ( // shedule software-control memory operation (may need to check FIFO status first) schedule_ps_pio ( // schedule software-control memory operation (may need to check FIFO status first)
READ_BLOCK_OFFSET, // input [9:0] seq_addr; // sequence start address READ_BLOCK_OFFSET, // input [9:0] seq_addr; // sequence start address
1, // input [1:0] page; // buffer page number 1, // 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 urgent; // high priority request (only for competion with other channels, wiil not pass in this FIFO)
......
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