x393_axi_control_status.py 23.2 KB
Newer Older
1
from __future__ import print_function
2 3
'''
# Copyright (C) 2015, Elphel.inc.
4
# Methods that mimic Verilog tasks used for simulation  
5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
# 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
33
#from import_verilog_parameters import VerilogParameters
34
from x393_mem import X393Mem
35
from verilog_utils import hx
Andrey Filippov's avatar
Andrey Filippov committed
36
from time import time
37
import vrlg
38

39
#enabled_channels=0 # currently enable channels
40 41 42 43 44
cke_en=0
cmda_en=0
sdrst_on=1
mcntrl_en=0
refresh_en=0
45
#channel_priority=[None]*16
46
sequences_set=0
47
class X393AxiControlStatus(object):
48
    DRY_MODE= True # True
49 50 51
    DEBUG_MODE=1
#    vpars=None
    x393_mem=None
52
    FPGA_RST_CTRL=0xf8000240
53
    verbose=1
54
    def __init__(self, debug_mode=1,dry_mode=True):
55 56 57
        self.DEBUG_MODE=debug_mode
        self.DRY_MODE=dry_mode
        self.x393_mem=X393Mem(debug_mode,dry_mode)
58 59 60 61 62
        try:
            self.verbose=vrlg.VERBOSE
        except:
            pass
        
63
#        self.__dict__.update(VerilogParameters.__dict__["_VerilogParameters__shared_state"]) # Add verilog parameters to the class namespace
64 65 66 67
        '''
        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
        '''
68 69 70
        
        # Use 'import pickle' (exists in the camera) to save/restore state
    def init_state(self):
71 72
#        global  enabled_channels, cke_en, cmda_en, sdrst_on, mcntrl_en, channel_priority, refresh_en, sequences_set
        global  cke_en, cmda_en, sdrst_on, mcntrl_en, refresh_en, sequences_set
73 74 75
        """
        reset state (as after bitstream load)
        """
76
#        enabled_channels=0 # currently enable channels
77 78 79 80
        cke_en=0
        cmda_en=0
        sdrst_on=1
        mcntrl_en=0
81
#        channel_priority=[None]*16
82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125
        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):
126
#        global  enabled_channels
127
        enabled_channels = self.read_control_register(vrlg.MCONTR_TOP_16BIT_ADDR + vrlg.MCONTR_TOP_16BIT_CHN_EN)        
128 129 130 131 132
        if quiet<2 :
            print ("ENABLED_CHANNELS =  0x%x"%enabled_channels)
        return enabled_channels

    def get_channel_priorities(self,quiet=1):
133 134
#        global channel_priority
        channel_priority = []
135 136
        if quiet<2 :
            print ("CHANNEL PRIORITIES:",end=" ")
137
            for chn in range (16):
138
                v = self.read_control_register(vrlg.MCONTR_ARBIT_ADDR + chn)
139 140 141
                print ("%d"%v,end=" ")
                channel_priority.append(v)
            """                
142 143 144 145 146
            for v in channel_priority:
                if v is None:
                    print (" - ",end=" ")
                else:
                    print ("%d"%v,end=" ")
147
            """        
148 149 150 151 152 153 154 155 156
            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),
157 158
        'enabled_channels':   self.get_enabled_channels(quiet),   # updated
        'channel_priorities': self.get_channel_priorities(quiet), # updated
159 160 161
        'refresh_en':         self.get_refresh_en(quiet),
        'sequences_set':      self.get_sequences_set(quiet)
        }
Andrey Filippov's avatar
Andrey Filippov committed
162 163 164 165
    def hwmon(self):
        """
        Read current temperature and supply voltages
        """
166 167
#        HWMON_PATH = "/sys/devices/amba.0/f8007100.ps7-xadc/"
        HWMON_PATH = '/sys/devices/soc0/amba@0/f8007100.ps7-xadc/iio:device0/'
Andrey Filippov's avatar
Andrey Filippov committed
168 169 170 171
        FILE = "file"
        ITEM = "item"
        UNITS = "units"
        SCALE = "scale"
172 173 174 175 176 177 178 179 180 181
        HWMON_ITEMS= [{FILE:"in_temp0",             ITEM:"Temperature", UNITS:"C", SCALE: 0.001},
                      {FILE:"in_voltage0_vccint",   ITEM:"VCCint",      UNITS:"V", SCALE: 0.001},
                      {FILE:"in_voltage1_vccaux",   ITEM:"VCCaux",      UNITS:"V", SCALE: 0.001},
                      {FILE:"in_voltage2_vccbram",  ITEM:"VCCbram",     UNITS:"V", SCALE: 0.001},
                      {FILE:"in_voltage3_vccpint",  ITEM:"VCCPint",     UNITS:"V", SCALE: 0.001},
                      {FILE:"in_voltage4_vccpaux",  ITEM:"VCCPaux",     UNITS:"V", SCALE: 0.001},
                      {FILE:"in_voltage5_vccoddr",  ITEM:"VCCOddr",     UNITS:"V", SCALE: 0.001},
                      {FILE:"in_voltage6_vrefp",    ITEM:"VREFp",       UNITS:"V", SCALE: 0.001},
                      {FILE:"in_voltage7_vrefn",    ITEM:"VREFn",       UNITS:"V", SCALE: 0.001},
                      ]
Andrey Filippov's avatar
Andrey Filippov committed
182
        print("hwmon:")
183 184 185
        if self.DRY_MODE:
            print ("Not defined for simulation mode")
            return
Andrey Filippov's avatar
Andrey Filippov committed
186
        for par in HWMON_ITEMS:
187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203
#            with open(HWMON_PATH + par[FILE]) as f:
#                d=int(f.read())
            with open(HWMON_PATH + par[FILE]+"_raw") as f:
                raw=float(f.read().strip())
            with open(HWMON_PATH + par[FILE]+"_scale") as f:
                scale=float(f.read().strip())
            try:    
                with open(HWMON_PATH + par[FILE]+"_offset") as f:
                    offset=float(f.read().strip())
            except:
                offset = 0
            #(guess)
#            if (raw>2047) and (par[UNITS] == 'V'):
            if (raw > 4000):
                raw -= 4096    
            d= (raw + offset)*scale        

Andrey Filippov's avatar
Andrey Filippov committed
204 205 206 207 208 209 210 211
            num_digits=0
            s = par[SCALE]
            while s < 1:
                s *= 10
                num_digits += 1
            w = 2+num_digits + (0,1)[num_digits > 0]    
            frmt = "%%12s = %%%d.%df %%s"%(w,num_digits)    
            print(frmt%(par[ITEM],(d*par[SCALE]),par[UNITS]))
212
            
213
    def write_control_register(self, reg_addr, data):
214 215
        """
        Write 32-bit word to the control register
216 217
        @param addr - register address relative to the control register address space
        @param data - 32-bit data to write
218
        """
219
        self.x393_mem.axi_write_single_w(vrlg.CONTROL_ADDR+reg_addr, data)
220

221
    def read_control_register(self, reg_addr=None, quiet=1):
222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242
        """
        Read 32-bit word from the control register (written by the software or the command sequencer)
        @param  addr - register address relative to the control register address space
        @param quiet - reduce output
        @return control register value
        """
        if reg_addr is None:
            rslt=[self.x393_mem.axi_read_addr_w(vrlg.CONTROL_RBACK_ADDR+reg_addr) for reg_addr in range(1024)]
            if quiet < 2:
                for reg_addr in range(1024):
                    if (reg_addr & 0x0f) == 0:
                        print("\n0x%03x:"%(reg_addr),end=" ")
                    print("%08x"%(rslt[reg_addr]),end=" ")
                print()    
            return rslt
        rslt=self.x393_mem.axi_read_addr_w(vrlg.CONTROL_RBACK_ADDR+reg_addr)
        if quiet < 1:
            print("control register 0x%x(0x%x) --> 0x%x"%(reg_addr,vrlg.CONTROL_RBACK_ADDR+reg_addr,rslt))
        return rslt

    
243 244 245 246 247 248 249
    def test_read_status(self, rpt): # was read_and_wait_status
        """
        Read word from the status register 0 and calculate part of the run busy
        <rpt> - number of times to repeat
        """
        num_busy=0
        for _ in range(rpt):
250
            num_busy+=(self.x393_mem.axi_read_addr_w(vrlg.STATUS_ADDR + 0)>>8) & 1
251 252 253
        ratio=(1.0* num_busy)/rpt
        print (("num_busy=%d, rpt=%d, ratio=%f"%(num_busy,rpt,100*ratio))+"%")
        return ratio
Andrey Filippov's avatar
Andrey Filippov committed
254
    def read_status(self, address): # was read_and_wait_status
255 256 257 258
        """
        Read word from the status register (up to 26 bits payload and 6-bit sequence number)
        <addr> - status register address (currently 0..255)
        """
259
        return self.x393_mem.axi_read_addr_w(vrlg.STATUS_ADDR + address )
260 261 262 263 264 265 266
    def wait_status_condition(self,
                              status_address,         # input [STATUS_DEPTH-1:0] status_address;
                              status_control_address, # input [29:0] status_control_address;
                              status_mode,            # input  [1:0] status_mode;
                              pattern,                # input [25:0] pattern;        // bits as in read registers
                              mask,                   # input [25:0] mask;           // which bits to compare
                              invert_match,           # input        invert_match;   // 0 - wait until match to pattern (all bits), 1 - wait until no match (any of bits differ)
Andrey Filippov's avatar
Andrey Filippov committed
267 268
                              wait_seq,               # input        wait_seq; // Wait for the correct sequence number, False assume correct
                              timeout=10.0):          # maximal timeout (0 - no timeout)
269 270
        """
        Poll specified status register until some condition is matched
271 272 273 274 275 276 277 278 279 280 281 282 283
        @param status_address   status register address (currently 0..255)
        @param status_control_address> - control register address (to control status generation)
        @param status_mode status generation mode:
                             0: disable status generation,
                             1: single status request,
                             2: auto status, keep specified seq number,
                             4: auto, inc sequence number 
        @param pattern       26-bit pattern to match
        @param mask          26-bit mask to enable pattern matching (0-s - ignore)
        @param invert_match  invert match (wait until matching condition becomes false)
        @param wait_seq      wait for the correct sequence number, if False - assume always correct
        @param timeout       maximal time to wait for condition
        @return 1 if success, 0 - if timeout
284
        """
285
        match=False
Andrey Filippov's avatar
Andrey Filippov committed
286 287 288
        endTime=None
        if timeout>0:
            endTime=time()+timeout
289
        while not match:
Andrey Filippov's avatar
Andrey Filippov committed
290
            data=self.read_status(status_address)
291
            if wait_seq:
292
                seq_num = ((data >> vrlg.STATUS_SEQ_SHFT) ^ 0x20) & 0x30
293
                self.write_control_register(status_control_address, ((status_mode & 3) <<6) | (seq_num & 0x3f))
Andrey Filippov's avatar
Andrey Filippov committed
294
                data=self.read_status(status_address)
295
                while (((data >> vrlg.STATUS_SEQ_SHFT) ^ seq_num) & 0x30) !=0:
Andrey Filippov's avatar
Andrey Filippov committed
296
                    data=self.read_status(status_address)
297
                    if self.DRY_MODE: break
Andrey Filippov's avatar
Andrey Filippov committed
298 299 300 301 302
                    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
303 304 305
            match = (((data ^ pattern) & mask & 0x3ffffff)==0)
            if invert_match:
                match = not match
306
            if self.DRY_MODE: break
Andrey Filippov's avatar
Andrey Filippov committed
307 308 309 310 311 312
            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
313 314

    def read_all_status(self):
315 316 317
        """
        Read and print contents of all defined status registers
        """
318 319 320 321
#        print (self.__dict__)
#        for name in self.__dict__:
#            print (name+": "+str(name=='MCONTR_PHY_STATUS_REG_ADDR'))
#        print (self.__dict__['MCONTR_PHY_STATUS_REG_ADDR'])
322 323 324 325 326 327 328
        print ("MCONTR_PHY_STATUS_REG_ADDR:          %s"%(hx(self.read_status(vrlg.MCONTR_PHY_STATUS_REG_ADDR),8)))
        print ("MCONTR_TOP_STATUS_REG_ADDR:          %s"%(hx(self.read_status(vrlg.MCONTR_TOP_STATUS_REG_ADDR),8)))
        print ("MCNTRL_PS_STATUS_REG_ADDR:           %s"%(hx(self.read_status(vrlg.MCNTRL_PS_STATUS_REG_ADDR) ,8)))
        print ("MCNTRL_SCANLINE_STATUS_REG_CHN1_ADDR:%s"%(hx(self.read_status(vrlg.MCNTRL_SCANLINE_STATUS_REG_CHN1_ADDR),8)))
        print ("MCNTRL_SCANLINE_STATUS_REG_CHN3_ADDR:%s"%(hx(self.read_status(vrlg.MCNTRL_SCANLINE_STATUS_REG_CHN3_ADDR),8)))
        print ("MCNTRL_TILED_STATUS_REG_CHN2_ADDR:   %s"%(hx(self.read_status(vrlg.MCNTRL_TILED_STATUS_REG_CHN2_ADDR),8)))
        print ("MCNTRL_TILED_STATUS_REG_CHN4_ADDR:   %s"%(hx(self.read_status(vrlg.MCNTRL_TILED_STATUS_REG_CHN4_ADDR),8)))
329
#        print ("MCNTRL_TEST01_STATUS_REG_CHN1_ADDR:  %s"%(hx(self.read_status(vrlg.MCNTRL_TEST01_STATUS_REG_CHN1_ADDR),8)))
330 331 332
        print ("MCNTRL_TEST01_STATUS_REG_CHN2_ADDR:  %s"%(hx(self.read_status(vrlg.MCNTRL_TEST01_STATUS_REG_CHN2_ADDR),8)))
        print ("MCNTRL_TEST01_STATUS_REG_CHN3_ADDR:  %s"%(hx(self.read_status(vrlg.MCNTRL_TEST01_STATUS_REG_CHN3_ADDR),8)))
        print ("MCNTRL_TEST01_STATUS_REG_CHN4_ADDR:  %s"%(hx(self.read_status(vrlg.MCNTRL_TEST01_STATUS_REG_CHN4_ADDR),8)))
333
        print ("MEMBRIDGE_STATUS_REG:                %s"%(hx(self.read_status(vrlg.MEMBRIDGE_STATUS_REG),8)))
334 335 336 337 338 339 340 341
        items_per_line = 8
        for i in range (256):
            if not i % items_per_line:
                print ("\n0x%02x: "%(i), end = "") 
            d=hx(self.read_status(i),8)
            print ("%s "%(d), end = "")
        print ()
                 
342 343 344 345 346
    def program_status(self,
                       base_addr,   # input [29:0] base_addr;
                       reg_addr,    # input  [7:0] reg_addr;
                       mode,        # input  [1:0] mode;
                       seq_number): # input  [5:0] seq_number;
347
        """
348
        Program status control for specified module/register
349 350 351 352 353 354 355 356 357
        <base_addr> -  base control address of the selected module
        <reg_addr> -   status control register relative to the module address space
        <mode> -       status generation mode:
                                  0: disable status generation,
                                  1: single status request,
                                  2: auto status, keep specified seq number,
                                  4: auto, inc sequence number 
        <seq_number> - 6-bit sequence number of the status message to be sent
        """
358
        self.write_control_register(base_addr + reg_addr, ((mode & 3)<< 6) | (seq_number * 0x3f))
359 360 361 362 363


    def program_status_all( self,
                            mode,     # input [1:0] mode;
                            seq_num): # input [5:0] seq_num;
364 365
        """
        Set status generation mode for all defined modules
366
        @param mode -       status generation mode:
367 368 369 370
                                  0: disable status generation,
                                  1: single status request,
                                  2: auto status, keep specified seq number,
                                  4: auto, inc sequence number 
371
        @param seq_number - 6-bit sequence number of the status message to be sent
372 373
        """

374 375 376 377 378 379 380
        self.program_status (vrlg.MCONTR_PHY_16BIT_ADDR,     vrlg.MCONTR_PHY_STATUS_CNTRL,        mode,seq_num)# //MCONTR_PHY_STATUS_REG_ADDR=          'h0,
        self.program_status (vrlg.MCONTR_TOP_16BIT_ADDR,     vrlg.MCONTR_TOP_16BIT_STATUS_CNTRL,  mode,seq_num)# //MCONTR_TOP_STATUS_REG_ADDR=          'h1,
        self.program_status (vrlg.MCNTRL_PS_ADDR,            vrlg.MCNTRL_PS_STATUS_CNTRL,         mode,seq_num)# //MCNTRL_PS_STATUS_REG_ADDR=           'h2,
        self.program_status (vrlg.MCNTRL_SCANLINE_CHN1_ADDR, vrlg.MCNTRL_SCANLINE_STATUS_CNTRL,   mode,seq_num)#; //MCNTRL_SCANLINE_STATUS_REG_CHN2_ADDR='h4,
        self.program_status (vrlg.MCNTRL_SCANLINE_CHN3_ADDR, vrlg.MCNTRL_SCANLINE_STATUS_CNTRL,   mode,seq_num)# //MCNTRL_SCANLINE_STATUS_REG_CHN3_ADDR='h5,
        self.program_status (vrlg.MCNTRL_TILED_CHN2_ADDR,    vrlg.MCNTRL_TILED_STATUS_CNTRL,      mode,seq_num)# //MCNTRL_TILED_STATUS_REG_CHN4_ADDR=   'h6,
        self.program_status (vrlg.MCNTRL_TILED_CHN4_ADDR,    vrlg.MCNTRL_TILED_STATUS_CNTRL,      mode,seq_num)#; //MCNTRL_TILED_STATUS_REG_CHN4_ADDR=   'h6,
381
#        self.program_status (vrlg.MCNTRL_TEST01_ADDR,        vrlg.MCNTRL_TEST01_CHN1_STATUS_CNTRL,mode,seq_num)#; //MCNTRL_TEST01_STATUS_REG_CHN2_ADDR=  'h3c,
382 383 384
        self.program_status (vrlg.MCNTRL_TEST01_ADDR,        vrlg.MCNTRL_TEST01_CHN2_STATUS_CNTRL,mode,seq_num)#; //MCNTRL_TEST01_STATUS_REG_CHN2_ADDR=  'h3c,
        self.program_status (vrlg.MCNTRL_TEST01_ADDR,        vrlg.MCNTRL_TEST01_CHN3_STATUS_CNTRL,mode,seq_num)#; //MCNTRL_TEST01_STATUS_REG_CHN3_ADDR=  'h3d,
        self.program_status (vrlg.MCNTRL_TEST01_ADDR,        vrlg.MCNTRL_TEST01_CHN4_STATUS_CNTRL,mode,seq_num)#; //MCNTRL_TEST01_STATUS_REG_CHN4_ADDR=  'h3e,
385
        self.program_status (vrlg.MEMBRIDGE_ADDR,            vrlg.MEMBRIDGE_STATUS_CNTRL,         mode,seq_num)#; //MCNTRL_TEST01_STATUS_REG_CHN4_ADDR=  'h3e,
386

387 388
    def enable_cmda(self,
                    en): # input en;
389 390 391 392
        """
        Enable (disable) address, bank and command lines to the DDR3 memory
        <en> - 1 - enable, 0 - disable
        """
393 394 395 396
        global cmda_en
        en=(0,1)[en]
        if self.verbose>0:
            print ("ENABLE CMDA %s"%str(en))
397
        self.write_control_register(vrlg.MCONTR_PHY_0BIT_ADDR +  vrlg.MCONTR_PHY_0BIT_CMDA_EN + en, 0);
398
        cmda_en=en
399 400 401
            
    def enable_cke(self,
                    en): # input en;
402 403 404 405
        """
        Enable (disable) CKE - clock enable to DDR3 memory 
        <en> - 1 - enable, 0 - disable
        """
406 407 408 409
        global  cke_en
        en=(0,1)[en]
        if self.verbose>0:
            print ("ENABLE CKE %s"%str(en))
410
        self.write_control_register(vrlg.MCONTR_PHY_0BIT_ADDR +  vrlg.MCONTR_PHY_0BIT_CKE_EN + en, 0);
411
        cke_en=en
412 413 414

    def activate_sdrst(self,
                    en): # input en;
415 416 417 418
        """
        Activate SDRST (reset) to DDR3 memory 
        <en> - 1 - activate (low), 0 - deactivate (high)
        """
419 420 421 422
        global sdrst_on
        en=(0,1)[en]
        if self.verbose>0:
            print ("ACTIVATE SDRST %s"%str(en))
423
        self.write_control_register(vrlg.MCONTR_PHY_0BIT_ADDR +  vrlg.MCONTR_PHY_0BIT_SDRST_ACT + en, 0);
424
        sdrst_on=en
425 426

    def enable_refresh(self,
427
                       en): # input en;
428 429 430 431
        """
        Enable (disable) refresh of the DDR3 memory 
        <en> - 1 - enable, 0 - disable
        """
432 433 434 435
        global  refresh_en
        en=(0,1)[en]
        if self.verbose>0:
            print ("ENABLE REFRESH %s"%str(en))
436
        self.write_control_register(vrlg.MCONTR_TOP_0BIT_ADDR +  vrlg.MCONTR_TOP_0BIT_REFRESH_EN + en, 0);
437
        refresh_en=en
438 439
        
    def enable_memcntrl(self,
440
                        en): # input en;
441 442 443 444
        """
        Enable memory controller module 
        <en> - 1 - enable, 0 - disable
        """
445 446
        global  mcntrl_en
        en=(0,1)[en]
447
        if self.verbose > 0:
448
            print ("ENABLE MEMCTRL %s"%str(en))
449
        self.write_control_register(vrlg.MCONTR_TOP_0BIT_ADDR +  vrlg.MCONTR_TOP_0BIT_MCONTR_EN + en, 0);
450
        mcntrl_en=en
451 452
    def enable_memcntrl_channels(self,
                                 chnen): # input [15:0] chnen; // bit-per-channel, 1 - enable;
453 454 455 456
        """
        Enable memory controller channels (all at once control) 
        <chnen> - 16-bit control word with per-channel enable bits (bit0 - chn0, ... bit15 - chn15)
        """
457
#        global  enabled_channels
458
        enabled_channels = chnen # currently enabled memory channels
459
        self.write_control_register(vrlg.MCONTR_TOP_16BIT_ADDR +  vrlg.MCONTR_TOP_16BIT_CHN_EN, enabled_channels & 0xffff) # {16'b0,chnen});
460
        if self.verbose > 0:
461
            print ("ENABLED MEMCTRL CHANNELS 0x%x (word), chnen=0x%x"%(enabled_channels,chnen))
462 463 464 465

    def enable_memcntrl_en_dis(self,
                               chn, # input [3:0] chn;
                               en):# input       en;
466 467 468 469 470
        """
        Enable memory controller channels (one at a time) 
        <chn> - 4-bit channel select
        <en> -  1 - enable, 0 - disable of the selected channel
        """
471 472
#        global  enabled_channels
# Adding readback register
473
        enabled_channels = self.read_control_register(vrlg.MCONTR_TOP_16BIT_ADDR + vrlg.MCONTR_TOP_16BIT_CHN_EN)        
474
        if en:
475
            enabled_channels |=  1<<chn;
476
        else:
477
            enabled_channels &= ~(1<<chn);
478
        self.write_control_register(vrlg.MCONTR_TOP_16BIT_ADDR + vrlg.MCONTR_TOP_16BIT_CHN_EN, enabled_channels & 0xffff) #  {16'b0,ENABLED_CHANNELS});
479
        if self.verbose > 0:
480
            print ("ENABLED MEMCTRL CHANNELS 0x%x (en/dis)"%enabled_channels)
481 482 483

    def configure_channel_priority(self,
                                   chn, # input [ 3:0] chn;
484
                                   priority=0): #input [15:0] priority; // (higher is more important)
485 486 487 488 489
        """
        Configure channel priority  
        <chn> -      4-bit channel select
        <priority> - 16-bit priority value (higher value means more important)
        """
490
#        global channel_priority
491
        self.write_control_register(vrlg.MCONTR_ARBIT_ADDR + chn, priority  & 0xffff)# {16'b0,priority});
492
        if self.verbose > 0:
493
            print ("SET CHANNEL %d priority=0x%x"%(chn,priority))
494
#        channel_priority[chn]=priority
495