VMM - (expanded) RAL/vmm_ral_field.sv

Expanded versions of source files are the output of the preprocessor. Lines subject to conditional compilation are not shown and all compiler pragmas have been stripped. Macros have been completely expanded.

RAL/vmm_ral_field.sv unexpanded source

00001: // 
00002: // -------------------------------------------------------------
00003: //    Copyright 2004-2008 Synopsys, Inc.
00004: //    All Rights Reserved Worldwide
00005: // 
00006: //    Licensed under the Apache License, Version 2.0 (the
00007: //    "License"); you may not use this file except in
00008: //    compliance with the License.  You may obtain a copy of
00009: //    the License at
00010: // 
00011: //        http://www.apache.org/licenses/LICENSE-2.0
00012: // 
00013: //    Unless required by applicable law or agreed to in
00014: //    writing, software distributed under the License is
00015: //    distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
00016: //    CONDITIONS OF ANY KIND, either express or implied.  See
00017: //    the License for the specific language governing
00018: //    permissions and limitations under the License.
00019: // -------------------------------------------------------------
00020: // 
00021: 
00022: 
00023: typedef class vmm_ral_field;
00024: class vmm_ral_field_callbacks extends vmm_ral_callbacks;
00025: 
00026:    virtual task pre_write(vmm_ral_field                     field,
00027:                           ref bit [64-1:0] wdat,
00028:                           ref vmm_ral::path_e               path,
00029:                           ref string                        domain);
00030:    endtask: pre_write
00031: 
00032:    virtual task post_write(vmm_ral_field                 field,
00033:                            bit [64-1:0] wdat,
00034:                            vmm_ral::path_e               path,
00035:                            string                        domain,
00036:                            ref vmm_rw::status_e          status);
00037:    endtask: post_write
00038: 
00039:    virtual task pre_read(vmm_ral_field         field,
00040:                          ref vmm_ral::path_e   path,
00041:                          ref string            domain);
00042:    endtask: pre_read
00043: 
00044:    virtual task post_read(vmm_ral_field                     field,
00045:                           ref bit [64-1:0] rdat,
00046:                           vmm_ral::path_e                   path,
00047:                           string                            domain,
00048:                           ref vmm_rw::status_e              status);
00049:    endtask: post_read
00050: endclass: vmm_ral_field_callbacks
00051: 
00052: 
00053: class vmm_ral_field;
00054:    static vmm_log log = new("RAL", "field");
00055: 
00056:    local string name;
00057:    local vmm_ral::access_e access;
00058:    local vmm_ral_reg parent;
00059:    local int unsigned lsb;
00060:    local int unsigned size;
00061:    local bit [64-1:0] mirrored; // What we think is in the HW
00062:    local bit [64-1:0] desired;  // Mirrored after set()
00063:    rand  bit [64-1:0] value;    // Mirrored after randomize()
00064:    local bit [64-1:0] reset_value;
00065:    local logic [64-1:0] soft_reset_value;
00066:    local bit written;
00067: 
00068:    vmm_ral_field_callbacks XcbsX[$];
00069: 
00070:    local bit no_cover;
00071:    local bit cover_on;
00072: 
00073:    constraint vmm_ral_field_valid {
00074:       if (64 > size) {
00075:          value < (`VMM_RAL_DATA_WIDTH'h1 << size);
00076:       }
00077:    }
00078: 
00079:    extern function new(vmm_ral_reg                   parent,
00080:                        string                        name,
00081:                        int unsigned                  size,
00082:                        vmm_ral::access_e             access,
00083:                        bit [64-1:0] reset,
00084:                        logic [64-1:0] soft_reset,
00085:                        int unsigned                  lsb_pos,
00086:                        bit                           is_rand = 0,
00087:                        bit                           cover_on = 1);
00088: 
00089:    extern virtual function string get_name();
00090:    extern virtual function string get_fullname();
00091:    extern virtual function vmm_ral_reg get_register();
00092:    extern virtual function int unsigned get_lsb_pos_in_register();
00093:    extern virtual function int unsigned get_n_bits();
00094:    extern virtual function vmm_ral::access_e get_access(string domain = "");
00095:    extern virtual function vmm_ral::access_e set_access(vmm_ral::access_e mode);
00096: 
00097:    extern virtual function void display(string prefix = "");
00098:    extern virtual function string psdisplay(string prefix = "");
00099: 
00100:    extern virtual function bit set_cover(bit is_on);
00101:    extern virtual function bit is_cover_on();
00102: 
00103:    /*local*/ extern virtual function bit [64-1:0] XpredictX(bit [64-1:0] cur_val,
00104:                                                                              bit [64-1:0] wr_val,
00105:                                                                              string                        domain);
00106: 
00107:    /*local*/ extern virtual function void XforceX(bit [64-1:0] value,
00108:                                                   vmm_ral::path_e               path,
00109:                                                   string                        domain);
00110:    /*local*/ extern virtual function void XwroteX(bit [64-1:0] value,
00111:                                                   vmm_ral::path_e               path,
00112:                                                   string                        domain);
00113:    /*local*/ extern virtual function bit[64-1:0] XupdX();
00114: 
00115:    extern virtual function void set(bit[64-1:0] value);
00116:    extern virtual function bit predict(bit [64-1:0] value);
00117:    extern virtual function bit[64-1:0] get();
00118:    extern virtual function void reset(vmm_ral::reset_e kind = vmm_ral::HARD);
00119:    extern virtual function logic [64-1:0]
00120:                     set_reset(logic [64-1:0] value,
00121:                               vmm_ral::reset_e                kind = vmm_ral::HARD);
00122:    extern virtual function bit needs_update();
00123: 
00124:    extern virtual task write(output vmm_rw::status_e              status,
00125:                              input  bit [64-1:0] value,
00126:                              input  vmm_ral::path_e               path = vmm_ral::DEFAULT,
00127:                              input  string                        domain = "",
00128:                              input  int                           data_id = -1,
00129:                              input  int                           scenario_id =- 1,
00130:                              input  int                           stream_id = -1);
00131:    extern virtual task read(output vmm_rw::status_e             status,
00132:                             output bit[64-1:0] value,
00133:                             input  vmm_ral::path_e              path = vmm_ral::DEFAULT,
00134:                             input  string                       domain = "",
00135:                             input  int                          data_id = -1,
00136:                             input  int                          scenario_id = -1,
00137:                             input  int                          stream_id = -1);
00138:                
00139:    extern virtual task poke(output vmm_rw::status_e              status,
00140:                             input  bit [64-1:0] value,
00141:                             input  int                           data_id = -1,
00142:                             input  int                           scenario_id =- 1,
00143:                             input  int                           stream_id = -1);
00144:    extern virtual task peek(output vmm_rw::status_e             status,
00145:                             output bit[64-1:0] value,
00146:                             input  int                          data_id = -1,
00147:                             input  int                          scenario_id = -1,
00148:                             input  int                          stream_id = -1);
00149:                
00150:    extern virtual task mirror(output vmm_rw::status_e status,
00151:                               input  vmm_ral::check_e check = vmm_ral::QUIET,
00152:                               input  vmm_ral::path_e  path = vmm_ral::DEFAULT,
00153:                               input  string           domain = "");
00154: 
00155:    extern function void prepend_callback(vmm_ral_field_callbacks cb);
00156:    extern function void append_callback(vmm_ral_field_callbacks cb);
00157:    extern function void unregister_callback(vmm_ral_field_callbacks cb);
00158: 
00159:    extern function void pre_randomize();
00160:    extern function void post_randomize();
00161: endclass: vmm_ral_field
00162: 
00163: 
00164: function vmm_ral_field::new(vmm_ral_reg                   parent,
00165:                             string                        name,
00166:                             int unsigned                  size,
00167:                             vmm_ral::access_e             access,
00168:                             bit [64-1:0] reset,
00169:                             logic [64-1:0] soft_reset,
00170:                             int unsigned                  lsb_pos,
00171:                             bit                           is_rand,
00172:                             bit                           cover_on);
00173:    this.parent = parent;
00174:    this.name   = name;
00175: 
00176:    if (size == 0) begin
00177:       
     : do 
     :    if (this.log.start_msg(vmm_log::FAILURE_TYP, vmm_log::ERROR_SEV)) begin 
     :       void'(this.log.text($psprintf("Field \"%s\" cannot have 0 bits", name))); 
     :       this.log.end_msg(); 
     :    end 
     : while (0);
00178:       size = 1;
00179:    end
00180:    if (size > 64) begin
00182: 
     : do 
     :    if (this.log.start_msg(vmm_log::FAILURE_TYP, vmm_log::ERROR_SEV)) begin 
     :       void'(this.log.text($psprintf("Field \"%s\" cannot have more than %0d bits",
     :                                      name, 64))); 
     :       this.log.end_msg(); 
     :    end 
     : while (0);
00183:       size = 64;
00184:    end
00185:    this.size   = size;
00186: 
00187:    this.access = access;
00188:    this.reset_value = reset;
00189:    this.soft_reset_value = soft_reset;
00190:    this.lsb    = lsb_pos;
00191:    this.parent.register_field(this);
00192:    if (!is_rand) this.value.rand_mode(0);
00193: 
00194:    this.written = 0;
00195: 
00196:    this.cover_on = cover_on;
00197:    this.no_cover = !cover_on;
00198: endfunction: new
00199: 
00200: 
00201: function string vmm_ral_field::get_name();
00202:    get_name = this.name;
00203: endfunction: get_name
00204: 
00205: 
00206: function string vmm_ral_field::get_fullname();
00207:    get_fullname = {this.parent.get_fullname(), ".", this.name};
00208: endfunction: get_fullname
00209: 
00210: 
00211: function vmm_ral_reg vmm_ral_field::get_register();
00212:    get_register = this.parent;
00213: endfunction: get_register
00214: 
00215: 
00216: function int unsigned vmm_ral_field::get_lsb_pos_in_register();
00217:    get_lsb_pos_in_register = this.lsb;
00218: endfunction: get_lsb_pos_in_register
00219: 
00220: 
00221: function int unsigned vmm_ral_field::get_n_bits();
00222:    get_n_bits = this.size;
00223: endfunction: get_n_bits
00224: 
00225: 
00226: function vmm_ral::access_e vmm_ral_field::get_access(string domain);
00227:    get_access = this.access;
00228:    if (parent.get_n_domains() == 1 || domain == "BaCkDoOr") return get_access;
00229: 
00230:    // Is the register restricted in this domain?
00231:    case (this.parent.get_rights(domain))
00232:      vmm_ral::RW:
00233:        // No restrictions
00234:        return get_access;
00235: 
00236:      vmm_ral::RO:
00237:        case (get_access)
00238:          vmm_ral::RW,
00239:          vmm_ral::RO,
00240:          vmm_ral::W1,
00241:          vmm_ral::W1C: get_access = vmm_ral::RO;
00242: 
00243:          vmm_ral::RU,
00244:          vmm_ral::A0,
00245:          vmm_ral::A1: get_access = vmm_ral::RU;
00246: 
00247:          vmm_ral::WO: begin
00250: 
     : do 
     :    if (this.log.start_msg(vmm_log::FAILURE_TYP, vmm_log::ERROR_SEV)) begin 
     :       void'(this.log.text($psprintf("WO field \"%s\" restricted to RO in domain \"%s\"",
     :                                  this.get_name(), domain))); 
     :       this.log.end_msg(); 
     :    end 
     : while (0);
00251:          end
00252: 
00253:          // No change for the other modes (OTHER, USERx)
00254:        endcase
00255: 
00256:      vmm_ral::WO:
00257:        case (get_access)
00258:          vmm_ral::RW,
00259:          vmm_ral::WO: get_access = vmm_ral::WO;
00260: 
00261:          vmm_ral::RO,
00262:          vmm_ral::RU,
00263:          vmm_ral::W1C,
00264:          vmm_ral::A0,
00265:          vmm_ral::A1: begin
00268: 
     : do 
     :    if (this.log.start_msg(vmm_log::FAILURE_TYP, vmm_log::ERROR_SEV)) begin 
     :       void'(this.log.text($psprintf("%s field \"%s\" restricted to WO in domain \"%s\"",
     :                                  get_access.name(), this.get_name(), domain))); 
     :       this.log.end_msg(); 
     :    end 
     : while (0);
00269:          end
00270: 
00271:          // No change for the other modes (W1, OTHER, USERx)
00272:        endcase
00273: 
00274:      default:
00277: 
     : do 
     :    if (this.log.start_msg(vmm_log::FAILURE_TYP, vmm_log::ERROR_SEV)) begin 
     :       void'(this.log.text($psprintf("Shared register \"%s\" containing field \"%s\" is not shared in domain \"%s\"",
     :                             this.parent.get_name(), this.get_name(), domain))); 
     :       this.log.end_msg(); 
     :    end 
     : while (0);
00278:    endcase
00279: endfunction: get_access
00280: 
00281: 
00282: function vmm_ral::access_e vmm_ral_field::set_access(vmm_ral::access_e mode);
00283:    set_access = this.access;
00284:    this.access = mode;
00285: endfunction: set_access
00286: 
00287: 
00288: function void vmm_ral_field::display(string prefix);
00289:    $write("%s\n", this.psdisplay(prefix));
00290: endfunction: display
00291: 
00292: 
00293: function string vmm_ral_field::psdisplay(string prefix);
00294:    string fmt;
00295:    $sformat(fmt, "%0d'h%%%0dh", this.get_n_bits(),
00296:             (this.get_n_bits()-1)/4 + 1);
00297:    $sformat(psdisplay, {"%s%s[%0d-%0d] = ",fmt,"%s"}, prefix,
00298:             this.get_name(),
00299:             this.get_lsb_pos_in_register() + this.get_n_bits() - 1,
00300:             this.get_lsb_pos_in_register(), this.desired,
00301:             (this.desired != this.mirrored) ? $psprintf({" (Mirror: ",fmt,")"}, this.mirrored) : "");
00302: endfunction: psdisplay
00303: 
00304: 
00305: function bit vmm_ral_field::set_cover(bit is_on);
00306:    set_cover = this.cover_on;
00307: 
00308:    if (this.no_cover && is_on) begin
00309:       
     : do 
     :    if (this.log.start_msg(vmm_log::FAILURE_TYP, vmm_log::WARNING_SEV)) begin 
     :       void'(this.log.text($psprintf("Cannot turn cover ON if constructed with coverage disabled in field \"%s\"", this.get_name()))); 
     :       this.log.end_msg(); 
     :    end 
     : while(0);
00310:       return set_cover;
00311:    end
00312: 
00313:    this.cover_on = is_on;
00314: endfunction: set_cover
00315: 
00316: 
00317: function bit vmm_ral_field::is_cover_on();
00318:    is_cover_on = this.cover_on;
00319: endfunction: is_cover_on
00320: 
00321: 
00322: function bit [64-1:0] vmm_ral_field::XpredictX(bit [64-1:0] cur_val,
00323:                                                                 bit [64-1:0] wr_val,
00324:                                                                 string                        domain);
00325: 
00326:    case (this.get_access(domain))
00327:      vmm_ral::RW:    return wr_val;
00328:      vmm_ral::RO:    return cur_val;
00329:      vmm_ral::WO:    return wr_val;
00330:      vmm_ral::W1:    return (this.written) ? cur_val : wr_val;
00331:      vmm_ral::RU:    return cur_val;
00332:      vmm_ral::RC:    return cur_val;
00333:      vmm_ral::W1C:   return cur_val & (~wr_val);
00334:      vmm_ral::A0:    return cur_val | wr_val;
00335:      vmm_ral::A1:    return cur_val & wr_val;
00336:      vmm_ral::DC:    return wr_val;
00337:      vmm_ral::OTHER,
00338:      vmm_ral::USER0,
00339:      vmm_ral::USER1,
00340:      vmm_ral::USER2,
00341:      vmm_ral::USER3: return wr_val;
00342:    endcase
00343: 
00344:    
     : do 
     :    if (log.start_msg(vmm_log::FAILURE_TYP, vmm_log::FATAL_SEV)) begin 
     :       void'(log.text("vmm_ral_field::XpredictX(): Internal error")); 
     :       log.end_msg(); 
     :    end 
     : while (0);
00345:    return 0;
00346: endfunction: XpredictX
00347: 
00348: 
00349: function void vmm_ral_field::XforceX(bit[64-1:0] value,
00350:                                      vmm_ral::path_e              path,
00351:                                      string                       domain);
00352:    value &= ('b1 << this.size)-1;
00353: 
00354:    // If the value was obtained via a front-door access
00355:    // then a RC field will have been cleared
00356:    if (path == vmm_ral::BFM && this.get_access(domain) == vmm_ral::RC) begin
00357:       value = 0;
00358:    end
00359: 
00360:    // If the value of a WO field was obtained via a front-door access
00361:    // it will always read back as 0 and the value of the field
00362:    // cannot be inferred from it
00363:    if (path == vmm_ral::BFM && this.get_access(domain) == vmm_ral::WO) return;
00364: 
00365:    this.mirrored = value;
00366:    this.desired = value;
00367:    this.value   = value;
00368: endfunction: XforceX
00369: 
00370: 
00371: function void vmm_ral_field::XwroteX(bit[64-1:0] value,
00372:                                      vmm_ral::path_e              path,
00373:                                      string                       domain);
00374:    if (value >> this.size) begin
00376: 
     : do 
     :    if (this.log.start_msg(vmm_log::FAILURE_TYP, vmm_log::WARNING_SEV)) begin 
     :       void'(this.log.text($psprintf("Specified value (0x%h) greater than field \"%s\" size (%0d bits)",
     :                                        value, this.get_name(), this.size))); 
     :       this.log.end_msg(); 
     :    end 
     : while(0);
00377:       value &= ('b1 << this.size)-1;
00378:    end
00379: 
00380:    if (path == vmm_ral::BFM) begin
00381:       this.mirrored = this.XpredictX(this.mirrored, value, domain);
00382:    end
00383:    else this.mirrored = value;
00384: 
00385:    this.desired = this.mirrored;
00386:    this.value   = this.mirrored;
00387: 
00388:    this.written = 1;
00389: endfunction: XwroteX
00390: 
00391: 
00392: function bit [64-1:0] vmm_ral_field::XupdX();
00393:    // Figure out which value must be written to get the desired value
00394:    // given what we think is the current value in the hardware
00395:    XupdX = 0;
00396: 
00397:    case (this.access)
00398:       vmm_ral::RW:    XupdX = this.desired;
00399:       vmm_ral::RO:    XupdX = this.desired;
00400:       vmm_ral::WO:    XupdX = this.desired;
00401:       vmm_ral::W1:    XupdX = this.desired;
00402:       vmm_ral::RU:    XupdX = this.desired;
00403:       vmm_ral::RC:    XupdX = this.desired;
00404:       vmm_ral::W1C:   XupdX = ~this.desired;
00405:       vmm_ral::A0:    XupdX = this.desired;
00406:       vmm_ral::A1:    XupdX = this.desired;
00407:       vmm_ral::DC,
00408:       vmm_ral::OTHER,
00409:       vmm_ral::USER0,
00410:       vmm_ral::USER1,
00411:       vmm_ral::USER2,
00412:       vmm_ral::USER3: XupdX = this.desired;
00413:    endcase
00414: endfunction: XupdX
00415: 
00416: 
00417: function void vmm_ral_field::set(bit[64-1:0] value);
00418:    if (value >> this.size) begin
00420: 
     : do 
     :    if (this.log.start_msg(vmm_log::FAILURE_TYP, vmm_log::WARNING_SEV)) begin 
     :       void'(this.log.text($psprintf("Specified value (0x%h) greater than field \"%s\" size (%0d bits)",
     :                                        value, this.get_name(), this.size))); 
     :       this.log.end_msg(); 
     :    end 
     : while(0);
00421:       value &= ('b1 << this.size)-1;
00422:    end
00423: 
00424:    case (this.access)
00425:       vmm_ral::RW:    this.desired = value;
00426:       vmm_ral::RO:    this.desired = this.desired;
00427:       vmm_ral::WO:    this.desired = value;
00428:       vmm_ral::W1:    this.desired = (this.written) ? this.desired : value;
00429:       vmm_ral::RU:    this.desired = this.desired;
00430:       vmm_ral::RC:    this.desired = this.desired;
00431:       vmm_ral::W1C:   this.desired &= (~value);
00432:       vmm_ral::A0:    this.desired |= value;
00433:       vmm_ral::A1:    this.desired &= value;
00434:       vmm_ral::DC,
00435:       vmm_ral::OTHER,
00436:       vmm_ral::USER0,
00437:       vmm_ral::USER1,
00438:       vmm_ral::USER2,
00439:       vmm_ral::USER3: this.desired = value;
00440:    endcase
00441:    this.value = this.desired;
00442: endfunction: set
00443: 
00444:  
00445: function bit vmm_ral_field::predict(bit[64-1:0] value);
00446:    if (this.parent.Xis_busyX) begin
00449: 
     : do 
     :    if (this.log.start_msg(vmm_log::FAILURE_TYP, vmm_log::WARNING_SEV)) begin 
     :       void'(this.log.text($psprintf("Trying to predict value of field \"%s\" while register \"%s\" is being accessed",
     :                                        this.get_name(),
     :                                        this.parent.get_fullname()))); 
     :       this.log.end_msg(); 
     :    end 
     : while(0);
00450:       return 0;
00451:    end
00452:    
00453:    value &= ('b1 << this.size)-1;
00454:    this.mirrored = value;
00455:    this.desired = value;
00456:    this.value   = value;
00457: 
00458:    return 1;
00459: endfunction: predict
00460: 
00461: 
00462: function bit[64-1:0] vmm_ral_field::get();
00463:    get = this.desired;
00464: endfunction: get
00465: 
00466: 
00467: function void vmm_ral_field::reset(vmm_ral::reset_e kind);
00468:    case (kind)
00469:      vmm_ral::HARD: begin
00470:         this.mirrored = reset_value;
00471:         this.desired  = reset_value;
00472:         this.written  = 0;
00473:      end
00474:      vmm_ral::SOFT: begin
00475:         if (soft_reset_value !== 'x) begin
00476:            this.mirrored = soft_reset_value;
00477:            this.desired  = soft_reset_value;
00478:         end
00479:      end
00480:    endcase
00481:    this.value = this.desired;
00482: endfunction: reset
00483: 
00484: 
00485: function logic [64-1:0]
00486:    vmm_ral_field::set_reset(logic [64-1:0] value,
00487:                             vmm_ral::reset_e kind);
00488:    case (kind)
00489:      vmm_ral::HARD: begin
00490:         set_reset = this.reset_value;
00491:         this.reset_value = value;
00492:      end
00493:      vmm_ral::SOFT: begin
00494:         set_reset = this.soft_reset_value;
00495:         this.soft_reset_value = value;
00496:      end
00497:    endcase
00498: endfunction: set_reset
00499: 
00500: 
00501: function bit vmm_ral_field::needs_update();
00502:    needs_update = (this.mirrored != this.desired);
00503: endfunction: needs_update
00504: 
00505: 
00506: task vmm_ral_field::write(output vmm_rw::status_e              status,
00507:                           input  bit [64-1:0] value,
00508:                           input  vmm_ral::path_e               path,
00509:                           input  string                        domain,
00510:                           input  int                           data_id,
00511:                           input  int                           scenario_id,
00512:                           input  int                           stream_id);
00513:    bit [64-1:0] tmp;
00514:    vmm_ral_field fields[];
00515: 
00516:    this.parent.XatomicX(1);
00517: 
00518:    if (value >> this.size) begin
00519:       
     : do 
     :    if (log.start_msg(vmm_log::FAILURE_TYP, vmm_log::WARNING_SEV)) begin 
     :       void'(log.text($psprintf("vmm_ral_field::write(): Value greater than field \"%s\" size", this.get_name()))); 
     :       log.end_msg(); 
     :    end 
     : while(0);
00520:       value &= value & ((1<<this.size)-1);
00521:    end
00522: 
00523:    tmp = 0;
00524:    // What values are written for the other fields???
00525:    this.parent.get_fields(fields);
00526:    foreach (fields[i]) begin
00527:       if (fields[i] == this) begin
00528:          tmp |= value << this.lsb;
00529:          continue;
00530:       end
00531: 
00532:       // It depends on what kind of bits they are made of...
00533:       case (fields[i].get_access(domain))
00534:         // These...
00535:         vmm_ral::RW,
00536:         vmm_ral::RO,
00537:         vmm_ral::WO,
00538:         vmm_ral::W1,
00539:         vmm_ral::RU,
00540:         vmm_ral::DC,
00541:         vmm_ral::OTHER,
00542:         vmm_ral::USER0,
00543:         vmm_ral::USER1,
00544:         vmm_ral::USER2,
00545:         vmm_ral::USER3:
00546:           // Use their mirrored value
00547:           tmp |= fields[i].get() << fields[i].get_lsb_pos_in_register();
00548: 
00549:         // These...
00550:         vmm_ral::RC,
00551:         vmm_ral::W1C,
00552:         vmm_ral::A0:
00553:           // Use all 0's
00554:           tmp |= 0;
00555: 
00556:         // These...
00557:         vmm_ral::A1:
00558:           // Use all 1's
00559:           tmp |= ((1<<fields[i].get_n_bits())-1) << fields[i].get_lsb_pos_in_register();
00560: 
00561:         default:
00562:           
     : do 
     :    if (log.start_msg(vmm_log::FAILURE_TYP, vmm_log::FATAL_SEV)) begin 
     :       void'(log.text("Internal error: write() does not handle field access mode")); 
     :       log.end_msg(); 
     :    end 
     : while (0);
00563:       endcase
00564:    end
00565: 
00566:    this.parent.XwriteX(status, tmp, path, domain, data_id, scenario_id, stream_id);
00567: 
00568:    this.parent.XatomicX(0);
00569: endtask: write
00570: 
00571: 
00572: task vmm_ral_field::read(output vmm_rw::status_e             status,
00573:                          output bit[64-1:0] value,
00574:                          input  vmm_ral::path_e              path,
00575:                          input  string                       domain,
00576:                          input  int                          data_id,
00577:                          input  int                          scenario_id,
00578:                          input  int                          stream_id);
00579:    bit[64-1:0] reg_value;
00580: 
00581:    this.parent.read(status, reg_value, path, domain, data_id, scenario_id, stream_id);
00582:    value = (reg_value >> lsb) & ((1<<size))-1;
00583: endtask: read
00584:                
00585: 
00586: task vmm_ral_field::poke(output vmm_rw::status_e              status,
00587:                          input  bit [64-1:0] value,
00588:                          input  int                           data_id,
00589:                          input  int                           scenario_id,
00590:                          input  int                           stream_id);
00591:    bit [64-1:0] tmp;
00592: 
00593:    this.parent.XatomicX(1);
00594: 
00595:    if (value >> this.size) begin
00596:       
     : do 
     :    if (log.start_msg(vmm_log::FAILURE_TYP, vmm_log::WARNING_SEV)) begin 
     :       void'(log.text($psprintf("vmm_ral_field::poke(): Value greater than field \"%s\" size", this.get_name()))); 
     :       log.end_msg(); 
     :    end 
     : while(0);
00597:       value &= value & ((1<<this.size)-1);
00598:    end
00599: 
00600:    tmp = 0;
00601:    // What is the current values of the other fields???
00602:    this.parent.peek(status, tmp, data_id, scenario_id, stream_id);
00603:    if (status != vmm_rw::IS_OK) begin
00604:       
     : do 
     :    if (log.start_msg(vmm_log::FAILURE_TYP, vmm_log::ERROR_SEV)) begin 
     :       void'(log.text($psprintf("vmm_ral_field::poke(): Peeking register \"%s\" returned status %s", this.parent.get_fullname(), status.name()))); 
     :       log.end_msg(); 
     :    end 
     : while (0);
00605:       return;
00606:    end
00607: 
00608:    // Force the value for this field then poke the resulting value
00609:    tmp &= ~(((1<<this.size)-1) << this.lsb);
00610:    tmp |= value << this.lsb;
00611:    this.parent.poke(status, tmp, data_id, scenario_id, stream_id);
00612: 
00613:    this.parent.XatomicX(0);
00614: endtask: poke
00615: 
00616: 
00617: task vmm_ral_field::peek(output vmm_rw::status_e             status,
00618:                          output bit[64-1:0] value,
00619:                          input  int                          data_id,
00620:                          input  int                          scenario_id,
00621:                          input  int                          stream_id);
00622:    bit[64-1:0] reg_value;
00623: 
00624:    this.parent.peek(status, reg_value, data_id, scenario_id, stream_id);
00625:    value = (reg_value >> lsb) & ((1<<size))-1;
00626: endtask: peek
00627:                
00628: 
00629: task vmm_ral_field::mirror(output vmm_rw::status_e status,
00630:                            input  vmm_ral::check_e check,
00631:                            input  vmm_ral::path_e  path,
00632:                            string                  domain);
00633:    this.parent.mirror(status, check, path, domain);
00634: endtask: mirror
00635: 
00636: 
00637: function void vmm_ral_field::prepend_callback(vmm_ral_field_callbacks cb);
00638:    foreach (this.XcbsX[i]) begin
00639:       if (this.XcbsX[i] == cb) begin
00640:          
     : do 
     :    if (this.log.start_msg(vmm_log::FAILURE_TYP, vmm_log::WARNING_SEV)) begin 
     :       void'(this.log.text($psprintf("Callback has already been registered with field \"%s\"", this.get_name()))); 
     :       this.log.end_msg(); 
     :    end 
     : while(0);
00641:          return;
00642:       end
00643:    end
00644:    
00645:    // Prepend new callback
00646:    this.XcbsX.push_front(cb);
00647: endfunction: prepend_callback
00648: 
00649: 
00650: function void vmm_ral_field::append_callback(vmm_ral_field_callbacks cb);
00651:    foreach (this.XcbsX[i]) begin
00652:       if (this.XcbsX[i] == cb) begin
00653:          
     : do 
     :    if (this.log.start_msg(vmm_log::FAILURE_TYP, vmm_log::WARNING_SEV)) begin 
     :       void'(this.log.text($psprintf("Callback has already been registered with field \"%s\"", this.get_name()))); 
     :       this.log.end_msg(); 
     :    end 
     : while(0);
00654:          return;
00655:       end
00656:    end
00657:    
00658:    // Append new callback
00659:    this.XcbsX.push_back(cb);
00660: endfunction: append_callback
00661: 
00662: 
00663: function void vmm_ral_field::unregister_callback(vmm_ral_field_callbacks cb);
00664:    foreach (this.XcbsX[i]) begin
00665:       if (this.XcbsX[i] == cb) begin
00666:          int j = i;
00667:          // Unregister it
00668:          this.XcbsX.delete(j);
00669:          return;
00670:       end
00671:    end
00672: 
00673:    
     : do 
     :    if (this.log.start_msg(vmm_log::FAILURE_TYP, vmm_log::WARNING_SEV)) begin 
     :       void'(this.log.text($psprintf("Callback was not registered with field \"%s\"", this.get_name()))); 
     :       this.log.end_msg(); 
     :    end 
     : while(0);
00674: endfunction: unregister_callback
00675: 
00676: 
00677: function void vmm_ral_field::pre_randomize();
00678:    // Update the only publicly known property with the current
00679:    // desired value so it can be used as a state variable should
00680:    // the rand_mode of the field be turned off.
00681:    this.value = this.desired;
00682: endfunction: pre_randomize
00683: 
00684: 
00685: function void vmm_ral_field::post_randomize();
00686:    this.desired = this.value;
00687: endfunction: post_randomize