x393_axi_control_status.py 20.9 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 162
        'refresh_en':         self.get_refresh_en(quiet),
        'sequences_set':      self.get_sequences_set(quiet)
        }
        
163
    def write_control_register(self, reg_addr, data):
164 165
        """
        Write 32-bit word to the control register
166 167
        @param addr - register address relative to the control register address space
        @param data - 32-bit data to write
168
        """
169
        self.x393_mem.axi_write_single_w(vrlg.CONTROL_ADDR+reg_addr, data)
170

171
    def read_control_register(self, reg_addr=None, quiet=1):
172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192
        """
        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

    
193 194 195 196 197 198 199
    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):
200
            num_busy+=(self.x393_mem.axi_read_addr_w(vrlg.STATUS_ADDR + 0)>>8) & 1
201 202 203
        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
204
    def read_status(self, address): # was read_and_wait_status
205 206 207 208
        """
        Read word from the status register (up to 26 bits payload and 6-bit sequence number)
        <addr> - status register address (currently 0..255)
        """
209
        return self.x393_mem.axi_read_addr_w(vrlg.STATUS_ADDR + address )
210 211 212 213 214 215 216
    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
217 218
                              wait_seq,               # input        wait_seq; // Wait for the correct sequence number, False assume correct
                              timeout=10.0):          # maximal timeout (0 - no timeout)
219 220
        """
        Poll specified status register until some condition is matched
221 222 223 224 225 226 227 228 229 230 231 232 233
        @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
234
        """
235
        match=False
Andrey Filippov's avatar
Andrey Filippov committed
236 237 238
        endTime=None
        if timeout>0:
            endTime=time()+timeout
239
        while not match:
Andrey Filippov's avatar
Andrey Filippov committed
240
            data=self.read_status(status_address)
241
            if wait_seq:
242
                seq_num = ((data >> vrlg.STATUS_SEQ_SHFT) ^ 0x20) & 0x30
243
                self.write_control_register(status_control_address, ((status_mode & 3) <<6) | (seq_num & 0x3f))
Andrey Filippov's avatar
Andrey Filippov committed
244
                data=self.read_status(status_address)
245
                while (((data >> vrlg.STATUS_SEQ_SHFT) ^ seq_num) & 0x30) !=0:
Andrey Filippov's avatar
Andrey Filippov committed
246
                    data=self.read_status(status_address)
247
                    if self.DRY_MODE: break
Andrey Filippov's avatar
Andrey Filippov committed
248 249 250 251 252
                    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
253 254 255
            match = (((data ^ pattern) & mask & 0x3ffffff)==0)
            if invert_match:
                match = not match
256
            if self.DRY_MODE: break
Andrey Filippov's avatar
Andrey Filippov committed
257 258 259 260 261 262
            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
263 264

    def read_all_status(self):
265 266 267
        """
        Read and print contents of all defined status registers
        """
268 269 270 271
#        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'])
272 273 274 275 276 277 278
        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)))
279
#        print ("MCNTRL_TEST01_STATUS_REG_CHN1_ADDR:  %s"%(hx(self.read_status(vrlg.MCNTRL_TEST01_STATUS_REG_CHN1_ADDR),8)))
280 281 282
        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)))
283
        print ("MEMBRIDGE_STATUS_REG:                %s"%(hx(self.read_status(vrlg.MEMBRIDGE_STATUS_REG),8)))
284 285 286 287 288 289 290 291
        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 ()
                 
292 293 294 295 296
    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;
297
        """
298
        Program status control for specified module/register
299 300 301 302 303 304 305 306 307
        <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
        """
308
        self.write_control_register(base_addr + reg_addr, ((mode & 3)<< 6) | (seq_number * 0x3f))
309 310 311 312 313


    def program_status_all( self,
                            mode,     # input [1:0] mode;
                            seq_num): # input [5:0] seq_num;
314 315
        """
        Set status generation mode for all defined modules
316
        @param mode -       status generation mode:
317 318 319 320
                                  0: disable status generation,
                                  1: single status request,
                                  2: auto status, keep specified seq number,
                                  4: auto, inc sequence number 
321
        @param seq_number - 6-bit sequence number of the status message to be sent
322 323
        """

324 325 326 327 328 329 330
        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,
331
#        self.program_status (vrlg.MCNTRL_TEST01_ADDR,        vrlg.MCNTRL_TEST01_CHN1_STATUS_CNTRL,mode,seq_num)#; //MCNTRL_TEST01_STATUS_REG_CHN2_ADDR=  'h3c,
332 333 334
        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,
335
        self.program_status (vrlg.MEMBRIDGE_ADDR,            vrlg.MEMBRIDGE_STATUS_CNTRL,         mode,seq_num)#; //MCNTRL_TEST01_STATUS_REG_CHN4_ADDR=  'h3e,
336

337 338
    def enable_cmda(self,
                    en): # input en;
339 340 341 342
        """
        Enable (disable) address, bank and command lines to the DDR3 memory
        <en> - 1 - enable, 0 - disable
        """
343 344 345 346
        global cmda_en
        en=(0,1)[en]
        if self.verbose>0:
            print ("ENABLE CMDA %s"%str(en))
347
        self.write_control_register(vrlg.MCONTR_PHY_0BIT_ADDR +  vrlg.MCONTR_PHY_0BIT_CMDA_EN + en, 0);
348
        cmda_en=en
349 350 351
            
    def enable_cke(self,
                    en): # input en;
352 353 354 355
        """
        Enable (disable) CKE - clock enable to DDR3 memory 
        <en> - 1 - enable, 0 - disable
        """
356 357 358 359
        global  cke_en
        en=(0,1)[en]
        if self.verbose>0:
            print ("ENABLE CKE %s"%str(en))
360
        self.write_control_register(vrlg.MCONTR_PHY_0BIT_ADDR +  vrlg.MCONTR_PHY_0BIT_CKE_EN + en, 0);
361
        cke_en=en
362 363 364

    def activate_sdrst(self,
                    en): # input en;
365 366 367 368
        """
        Activate SDRST (reset) to DDR3 memory 
        <en> - 1 - activate (low), 0 - deactivate (high)
        """
369 370 371 372
        global sdrst_on
        en=(0,1)[en]
        if self.verbose>0:
            print ("ACTIVATE SDRST %s"%str(en))
373
        self.write_control_register(vrlg.MCONTR_PHY_0BIT_ADDR +  vrlg.MCONTR_PHY_0BIT_SDRST_ACT + en, 0);
374
        sdrst_on=en
375 376

    def enable_refresh(self,
377
                       en): # input en;
378 379 380 381
        """
        Enable (disable) refresh of the DDR3 memory 
        <en> - 1 - enable, 0 - disable
        """
382 383 384 385
        global  refresh_en
        en=(0,1)[en]
        if self.verbose>0:
            print ("ENABLE REFRESH %s"%str(en))
386
        self.write_control_register(vrlg.MCONTR_TOP_0BIT_ADDR +  vrlg.MCONTR_TOP_0BIT_REFRESH_EN + en, 0);
387
        refresh_en=en
388 389
        
    def enable_memcntrl(self,
390
                        en): # input en;
391 392 393 394
        """
        Enable memory controller module 
        <en> - 1 - enable, 0 - disable
        """
395 396
        global  mcntrl_en
        en=(0,1)[en]
397
        if self.verbose > 0:
398
            print ("ENABLE MEMCTRL %s"%str(en))
399
        self.write_control_register(vrlg.MCONTR_TOP_0BIT_ADDR +  vrlg.MCONTR_TOP_0BIT_MCONTR_EN + en, 0);
400
        mcntrl_en=en
401 402
    def enable_memcntrl_channels(self,
                                 chnen): # input [15:0] chnen; // bit-per-channel, 1 - enable;
403 404 405 406
        """
        Enable memory controller channels (all at once control) 
        <chnen> - 16-bit control word with per-channel enable bits (bit0 - chn0, ... bit15 - chn15)
        """
407
#        global  enabled_channels
408
        enabled_channels = chnen # currently enabled memory channels
409
        self.write_control_register(vrlg.MCONTR_TOP_16BIT_ADDR +  vrlg.MCONTR_TOP_16BIT_CHN_EN, enabled_channels & 0xffff) # {16'b0,chnen});
410
        if self.verbose > 0:
411
            print ("ENABLED MEMCTRL CHANNELS 0x%x (word), chnen=0x%x"%(enabled_channels,chnen))
412 413 414 415

    def enable_memcntrl_en_dis(self,
                               chn, # input [3:0] chn;
                               en):# input       en;
416 417 418 419 420
        """
        Enable memory controller channels (one at a time) 
        <chn> - 4-bit channel select
        <en> -  1 - enable, 0 - disable of the selected channel
        """
421 422
#        global  enabled_channels
# Adding readback register
423
        enabled_channels = self.read_control_register(vrlg.MCONTR_TOP_16BIT_ADDR + vrlg.MCONTR_TOP_16BIT_CHN_EN)        
424
        if en:
425
            enabled_channels |=  1<<chn;
426
        else:
427
            enabled_channels &= ~(1<<chn);
428
        self.write_control_register(vrlg.MCONTR_TOP_16BIT_ADDR + vrlg.MCONTR_TOP_16BIT_CHN_EN, enabled_channels & 0xffff) #  {16'b0,ENABLED_CHANNELS});
429
        if self.verbose > 0:
430
            print ("ENABLED MEMCTRL CHANNELS 0x%x (en/dis)"%enabled_channels)
431 432 433

    def configure_channel_priority(self,
                                   chn, # input [ 3:0] chn;
434
                                   priority=0): #input [15:0] priority; // (higher is more important)
435 436 437 438 439
        """
        Configure channel priority  
        <chn> -      4-bit channel select
        <priority> - 16-bit priority value (higher value means more important)
        """
440
#        global channel_priority
441
        self.write_control_register(vrlg.MCONTR_ARBIT_ADDR + chn, priority  & 0xffff)# {16'b0,priority});
442
        if self.verbose > 0:
443
            print ("SET CHANNEL %d priority=0x%x"%(chn,priority))
444
#        channel_priority[chn]=priority
445