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.
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: class vmm_ral_tests;
00024:
00025: extern static task hw_reset(vmm_ral_block blk,
00026: string domain,
00027: vmm_log log);
00028:
00029: extern static task bit_bash(vmm_ral_block blk,
00030: string domain,
00031: vmm_log log);
00032:
00033: extern static task mem_walk(vmm_ral_block blk,
00034: string domain,
00035: vmm_log log);
00036:
00037: extern static task reg_access(vmm_ral_block blk,
00038: vmm_log log);
00039:
00040: extern static task mem_access(vmm_ral_block blk,
00041: vmm_log log);
00042:
00043: extern static task shared_access(vmm_ral_block blk,
00044: vmm_log log);
00045:
00046:
00047: extern local static task bash_kth_bit(vmm_log log,
00048: vmm_ral_reg regs,
00049: int k,
00050: vmm_ral::access_e mode,
00051: string domain,
00052: bit [64-1:0] wo_mask);
00053: endclass: vmm_ral_tests
00054:
00055:
00056: task vmm_ral_tests::hw_reset(vmm_ral_block blk,
00057: string domain,
00058: vmm_log log);
00059: vmm_ral_reg regs[];
00060:
00061: // Iterate over all registers, checking the reset values
00062: blk.get_registers(regs, domain);
00063: foreach (regs[i]) begin
00064: string domains[];
00065:
00066: // Registers with some attributes are not to be tested
00067: if (regs[i].get_attribute("NO_RAL_TESTS") != "" ||
00068: regs[i].get_attribute("NO_HW_RESET_TEST") != "") continue;
00069:
00070: // Registers may be accessible from multiple physical interfaces (domains)
00071: regs[i].get_domains(domains);
00072:
00073: // Verify the initial (reset) value in each domain
00074: foreach (domains[j]) begin
00075: vmm_rw::status_e status;
00076: bit [64-1:0] v;
00077:
00078:
: do
: /* synopsys translate_off */
: if (log.start_msg(vmm_log::NOTE_TYP, , "", -1)) begin
: void'(log.text($psprintf("Verifying reset value of register %s in domain \"%s\"...",
: regs[i].get_fullname(), domains[j])));
: log.end_msg();
: end
: /* synopsys translate_on */
: while (0);
00080:
00081: regs[i].mirror(status, vmm_ral::VERB, vmm_ral::BFM, domains[j]);
00082: if (status != vmm_rw::IS_OK) begin
00083:
: do
: /* synopsys translate_off */
: if (log.start_msg(vmm_log::FAILURE_TYP, vmm_log::ERROR_SEV, "", -1)) begin
: void'(log.text($psprintf("Status was %s when reading reset value of register \"%s\" through domain \"%s\".",
: status.name(), regs[i].get_fullname(), domains[j])));
: log.end_msg();
: end
: /* synopsys translate_on */
: while (0);
00085: end
00086: end
00087: end
00088: endtask: hw_reset
00089:
00090:
00091:
00092: task vmm_ral_tests::bit_bash(vmm_ral_block blk,
00093: string domain,
00094: vmm_log log);
00095: vmm_ral_reg regs[];
00096:
00097: // Iterate over all registers, trying to modify read-only bits
00098: // and making sure read-write bits can be set and cleared
00099: blk.get_registers(regs, domain);
00100: foreach (regs[i]) begin
00101: vmm_ral_field fields[];
00102: vmm_ral::access_e mode[64];
00103: string domains[];
00104: bit [64-1:0] wo_mask;
00105: bit [64-1:0] reset_val;
00106: int n_bits;
00107:
00108: // Registers with some attributes are not to be tested
00109: if (regs[i].get_attribute("NO_RAL_TESTS") != "" ||
00110: regs[i].get_attribute("NO_BIT_BASH_TEST") != "") continue;
00111:
00112: n_bits = regs[i].get_n_bytes() * 8;
00113:
00114: // Let's see what kind of bits we have...
00115: regs[i].get_fields(fields);
00116:
00117: // Registers may be accessible from multiple physical interfaces (domains)
00118: regs[i].get_domains(domains);
00119:
00120: // Bash the bits in the register via each domain
00121: foreach (domains[j]) begin
00122: vmm_rw::status_e status;
00123: bit [64-1:0] val, exp, v, other;
00124: int next_lsb;
00125:
00126: next_lsb = 0;
00127: wo_mask = '1;
00128: foreach (fields[k]) begin
00129: int lsb, w;
00130:
00131: lsb = fields[k].get_lsb_pos_in_register();
00132: w = fields[k].get_n_bits();
00133:
00134: // Any unused bits on the right side of the LSB?
00135: while (next_lsb < lsb) begin
00136: mode[next_lsb++] = vmm_ral::RO;
00137: end
00138:
00139: repeat (w) begin
00140: mode[next_lsb] = fields[k].get_access(domains[j]);
00141: if (mode[next_lsb] == vmm_ral::WO) wo_mask[next_lsb] = 1'b0;
00142: next_lsb++;
00143: end
00144: end
00145: // Any unused bits on the left side of the MSB?
00146: while (next_lsb < 64) begin
00147: mode[next_lsb++] = vmm_ral::RO;
00148: end
00149:
00150:
: do
: /* synopsys translate_off */
: if (log.start_msg(vmm_log::NOTE_TYP, , "", -1)) begin
: void'(log.text($psprintf("Verifying bits in register %s in domain \"%s\"...",
: regs[i].get_fullname(), domains[j])));
: log.end_msg();
: end
: /* synopsys translate_on */
: while (0);
00152:
00153: // The mirror still contains initial value
00154: reset_val = regs[i].get();
00155:
00156: // But the mirrored value of any WO bits will read back
00157: // as all zeroes via the frontdoor...
00158: reset_val &= wo_mask;
00159:
00160: regs[i].read(status, val, vmm_ral::BFM, domains[j]);
00161: if (status != vmm_rw::IS_OK) begin
00162:
: do
: /* synopsys translate_off */
: if (log.start_msg(vmm_log::FAILURE_TYP, vmm_log::ERROR_SEV, "", -1)) begin
: void'(log.text($psprintf("Status was %s when reading register \"%s\" through domain \"%s\".",
: status, regs[i].get_fullname(), domains[j])));
: log.end_msg();
: end
: /* synopsys translate_on */
: while (0);
00164: end
00165:
00166: if (val !== reset_val) begin
00167:
: do
: /* synopsys translate_off */
: if (log.start_msg(vmm_log::FAILURE_TYP, vmm_log::ERROR_SEV, "", -1)) begin
: void'(log.text($psprintf("Initial value of register \"%s\" 'h%h not %s 'h%h",
: regs[i].get_fullname(), val,
: (j == 0) ? "reset value" : "as expected",
: reset_val)));
: log.end_msg();
: end
: /* synopsys translate_on */
: while (0);
00171: end
00172:
00173: // Bash the kth bit
00174: other = 0;
00175: for (int k = 0; k < n_bits; k++) begin
00176:
00177: // Cannot test unpredictable bit behavior
00178: if (mode[k] >= vmm_ral::DC) begin
00179: other[k] = 1;
00180: continue;
00181: end
00182:
00183: bash_kth_bit(log, regs[i], k, mode[k], domains[j], wo_mask);
00184: end
00185:
00186: // Write the complement of the reset value
00187: // Except in the "OTHER" and "USERx" bits
00188: val = reset_val ^ ~other;
00189:
00190: regs[i].write(status, val, vmm_ral::BFM, domains[j]);
00191: if (status != vmm_rw::IS_OK) begin
00192:
: do
: /* synopsys translate_off */
: if (log.start_msg(vmm_log::FAILURE_TYP, vmm_log::ERROR_SEV, "", -1)) begin
: void'(log.text($psprintf("Status was %s when writing to register \"%s\" through domain \"%s\".",
: status, regs[i].get_fullname(), domains[j])));
: log.end_msg();
: end
: /* synopsys translate_on */
: while (0);
00194: end
00195:
00196: exp = regs[i].get() & wo_mask;
00197: regs[i].read(status, v, vmm_ral::BFM, domains[j]);
00198: if (status != vmm_rw::IS_OK) begin
00199:
: do
: /* synopsys translate_off */
: if (log.start_msg(vmm_log::FAILURE_TYP, vmm_log::ERROR_SEV, "", -1)) begin
: void'(log.text($psprintf("Status was %s when reading register \"%s\" through domain \"%s\".",
: status, regs[i].get_fullname(), domains[j])));
: log.end_msg();
: end
: /* synopsys translate_on */
: while (0);
00201: end
00202:
00203: if (v !== exp) begin
00204:
: do
: /* synopsys translate_off */
: if (log.start_msg(vmm_log::FAILURE_TYP, vmm_log::ERROR_SEV, "", -1)) begin
: void'(log.text($psprintf("Writing 'h%h to register \"%s\" with initial value 'h%h yielded 'h%h instead of 'h%h",
: val, regs[i].get_fullname(), reset_val, v, exp)));
: log.end_msg();
: end
: /* synopsys translate_on */
: while (0);
00206: end
00207: end
00208: end
00209: endtask: bit_bash
00210:
00211:
00212: task vmm_ral_tests::bash_kth_bit(vmm_log log,
00213: vmm_ral_reg regs,
00214: int k,
00215: vmm_ral::access_e mode,
00216: string domain,
00217: bit [64-1:0] wo_mask);
00218: vmm_rw::status_e status;
00219: bit [64-1:0] val, exp, v;
00220: bit bit_val;
00221:
00222:
: do
: /* synopsys translate_off */
: if (log.start_msg(vmm_log::NOTE_TYP, , "", -1)) begin
: void'(log.text($psprintf("...Bashing %s bit #%0d", mode.name(), k)));
: log.end_msg();
: end
: /* synopsys translate_on */
: while (0);
00223:
00224: repeat (2) begin
00225: val = regs.get();
00226: v = val;
00227: exp = val;
00228: val[k] = ~val[k];
00229: bit_val = val[k];
00230:
00231: regs.write(status, val, vmm_ral::BFM, domain);
00232: if (status != vmm_rw::IS_OK) begin
00233:
: do
: /* synopsys translate_off */
: if (log.start_msg(vmm_log::FAILURE_TYP, vmm_log::ERROR_SEV, "", -1)) begin
: void'(log.text($psprintf("Status was %s when writing to register \"%s\" through domain \"%s\".",
: status, regs.get_fullname(), domain)));
: log.end_msg();
: end
: /* synopsys translate_on */
: while (0);
00235: end
00236:
00237: exp = regs.get() & wo_mask;
00238: regs.read(status, val, vmm_ral::BFM, domain);
00239: if (status != vmm_rw::IS_OK) begin
00240:
: do
: /* synopsys translate_off */
: if (log.start_msg(vmm_log::FAILURE_TYP, vmm_log::ERROR_SEV, "", -1)) begin
: void'(log.text($psprintf("Status was %s when reading register \"%s\" through domain \"%s\".",
: status, regs.get_fullname(), domain)));
: log.end_msg();
: end
: /* synopsys translate_on */
: while (0);
00242: end
00243:
00244: if (val !== exp) begin
00245:
: do
: /* synopsys translate_off */
: if (log.start_msg(vmm_log::FAILURE_TYP, vmm_log::ERROR_SEV, "", -1)) begin
: void'(log.text($psprintf("Writing a %b in bit #%0d of register \"%s\" with initial value 'h%h yielded 'h%h instead of 'h%h",
: bit_val, k, regs.get_fullname(), v, val, exp)));
: log.end_msg();
: end
: /* synopsys translate_on */
: while (0);
00247: end
00248: end
00249: endtask: bash_kth_bit
00250:
00251:
00252: task vmm_ral_tests::mem_walk(vmm_ral_block blk,
00253: string domain,
00254: vmm_log log);
00255: vmm_ral_mem mems[];
00256:
00257: // Walk over all RW memories
00258: blk.get_memories(mems, domain);
00259: foreach (mems[i]) begin
00260: vmm_ral::access_e mode;
00261: string domains[];
00262: int n_bits;
00263:
00264: // Memories with some attributes are not to be tested
00265: if (mems[i].get_attribute("NO_RAL_TESTS") != "" ||
00266: mems[i].get_attribute("NO_MEM_WALK_TEST") != "") continue;
00267:
00268: n_bits = mems[i].get_n_bits();
00269:
00270: // Memories may be accessible from multiple physical interfaces (domains)
00271: mems[i].get_domains(domains);
00272:
00273: // Walk the memory via each domain
00274: foreach (domains[j]) begin
00275: vmm_rw::status_e status;
00276: bit [64-1:0] val, exp, v;
00277:
00278: // Only deal with RW memories
00279: if (mems[i].get_access(domains[j]) != vmm_ral::RW) continue;
00280:
00281:
: do
: /* synopsys translate_off */
: if (log.start_msg(vmm_log::NOTE_TYP, , "", -1)) begin
: void'(log.text($psprintf("Walking memory %s in domain \"%s\"...",
: mems[i].get_fullname(), domains[j])));
: log.end_msg();
: end
: /* synopsys translate_on */
: while (0);
00283:
00284: // The walking process is, for address k:
00285: // - Write ~k
00286: // - Read k-1 and expect ~(k-1) if k > 0
00287: // - Write k-1 at k-1
00288: // - Read k and expect ~k if k == last address
00289: for (int k = 0; k < mems[i].get_size(); k++) begin
00290: mems[i].write(status, k, ~k, vmm_ral::BFM, domains[j]);
00291: if (status != vmm_rw::IS_OK) begin
00292:
: do
: /* synopsys translate_off */
: if (log.start_msg(vmm_log::FAILURE_TYP, vmm_log::ERROR_SEV, "", -1)) begin
: void'(log.text($psprintf("Status was %s when writing \"%s[%0d]\" through domain \"%s\".",
: status.name(), mems[i].get_fullname(), k, domains[j])));
: log.end_msg();
: end
: /* synopsys translate_on */
: while (0);
00294: end
00295:
00296: if (k > 0) begin
00297: mems[i].read(status, k-1, val, vmm_ral::BFM, domains[j]);
00298: if (status != vmm_rw::IS_OK) begin
00299:
: do
: /* synopsys translate_off */
: if (log.start_msg(vmm_log::FAILURE_TYP, vmm_log::ERROR_SEV, "", -1)) begin
: void'(log.text($psprintf("Status was %s when reading \"%s[%0d]\" through domain \"%s\".",
: status.name(), mems[i].get_fullname(), k, domains[j])));
: log.end_msg();
: end
: /* synopsys translate_on */
: while (0);
00301: end
00302: else begin
00303: exp = ~(k-1) & ((1'b1<<n_bits)-1);
00304: if (val !== exp) begin
00305:
: do
: /* synopsys translate_off */
: if (log.start_msg(vmm_log::FAILURE_TYP, vmm_log::ERROR_SEV, "", -1)) begin
: void'(log.text($psprintf("\"%s[%0d-1]\" read back as 'h%h instead of 'h%h.",
: mems[i].get_fullname(), k, val, exp)));
: log.end_msg();
: end
: /* synopsys translate_on */
: while (0);
00307:
00308: end
00309: end
00310:
00311: mems[i].write(status, k-1, k-1, vmm_ral::BFM, domains[j]);
00312: if (status != vmm_rw::IS_OK) begin
00313:
: do
: /* synopsys translate_off */
: if (log.start_msg(vmm_log::FAILURE_TYP, vmm_log::ERROR_SEV, "", -1)) begin
: void'(log.text($psprintf("Status was %s when writing \"%s[%0d-1]\" through domain \"%s\".",
: status.name(), mems[i].get_fullname(), k, domains[j])));
: log.end_msg();
: end
: /* synopsys translate_on */
: while (0);
00315: end
00316: end
00317:
00318: if (k == mems[i].get_size() - 1) begin
00319: mems[i].read(status, k, val, vmm_ral::BFM, domains[j]);
00320: if (status != vmm_rw::IS_OK) begin
00321:
: do
: /* synopsys translate_off */
: if (log.start_msg(vmm_log::FAILURE_TYP, vmm_log::ERROR_SEV, "", -1)) begin
: void'(log.text($psprintf("Status was %s when reading \"%s[%0d]\" through domain \"%s\".",
: status.name(), mems[i].get_fullname(), k, domains[j])));
: log.end_msg();
: end
: /* synopsys translate_on */
: while (0);
00323: end
00324: else begin
00325: exp = ~(k) & ((1'b1<<n_bits)-1);
00326: if (val !== exp) begin
00327:
: do
: /* synopsys translate_off */
: if (log.start_msg(vmm_log::FAILURE_TYP, vmm_log::ERROR_SEV, "", -1)) begin
: void'(log.text($psprintf("\"%s[%0d]\" read back as 'h%h instead of 'h%h.",
: mems[i].get_fullname(), k, val, exp)));
: log.end_msg();
: end
: /* synopsys translate_on */
: while (0);
00329:
00330: end
00331: end
00332: end
00333: end
00334: end
00335: end
00336: endtask: mem_walk
00337:
00338:
00339: task vmm_ral_tests::reg_access(vmm_ral_block blk,
00340: vmm_log log);
00341: vmm_ral_reg regs[];
00342: bit skip_reg = 0;
00343:
00344: // Iterate over all registers, checking accesses
00345: blk.get_registers(regs);
00346: foreach (regs[i]) begin
00347: string domains[];
00348:
00349: // Registers with some attributes are not to be tested
00350: if (regs[i].get_attribute("NO_RAL_TESTS") != "" ||
00351: regs[i].get_attribute("NO_REG_ACCESS_TEST") != "") continue;
00352:
00353: // Can only deal with registers with backdoor access
00354: if (regs[i].get_backdoor() == null) begin
00355:
: do
: /* synopsys translate_off */
: if (log.start_msg(vmm_log::FAILURE_TYP, vmm_log::WARNING_SEV, "", -1)) begin
: void'(log.text($psprintf("Register \"%s\" does not have a backdoor mechanism available",
: regs[i].get_fullname())));
: log.end_msg();
: end
: /* synopsys translate_on */
: while(0);
00357: continue;
00358: end
00359:
00360: // Registers may be accessible from multiple physical interfaces (domains)
00361: regs[i].get_domains(domains);
00362:
00363: // Cannot test access if register contains RO or OTHER fields
00364: begin
00365: vmm_ral_field fields[];
00366: regs[i].get_fields(fields);
00367: foreach (fields[j]) begin
00368: foreach (domains[k]) begin
00369: if (fields[j].get_access(domains[k]) == vmm_ral::RO) begin
00370:
: do
: /* synopsys translate_off */
: if (log.start_msg(vmm_log::FAILURE_TYP, vmm_log::WARNING_SEV, "", -1)) begin
: void'(log.text($psprintf("Register \"%s\" has RO bits",
: regs[i].get_fullname())));
: log.end_msg();
: end
: /* synopsys translate_on */
: while(0);
00372: skip_reg = 1; break;
00373: end
00374: if (fields[j].get_access(domains[k]) >= vmm_ral::OTHER) begin
00375:
: do
: /* synopsys translate_off */
: if (log.start_msg(vmm_log::FAILURE_TYP, vmm_log::WARNING_SEV, "", -1)) begin
: void'(log.text($psprintf("Register \"%s\" has OTHER or USER bits",
: regs[i].get_fullname())));
: log.end_msg();
: end
: /* synopsys translate_on */
: while(0);
00377: skip_reg = 1; break;
00378: end
00379: end
00380: if (skip_reg == 1) break;
00381: end
00382: if (skip_reg == 1) begin
00383: skip_reg = 0;
00384: continue;
00385: end
00386: end
00387:
00388: // Access each register:
00389: // - Write complement of reset value via front door
00390: // - Read value via backdoor and compare against mirror
00391: // - Write reset value via backdoor
00392: // - Read via front door and compare against mirror
00393: foreach (domains[j]) begin
00394: vmm_rw::status_e status;
00395: bit [64-1:0] v, exp;
00396:
00397:
: do
: /* synopsys translate_off */
: if (log.start_msg(vmm_log::NOTE_TYP, , "", -1)) begin
: void'(log.text($psprintf("Verifying access of register %s in domain \"%s\"...",
: regs[i].get_fullname(), domains[j])));
: log.end_msg();
: end
: /* synopsys translate_on */
: while (0);
00399:
00400: v = regs[i].get();
00401:
00402: regs[i].write(status, ~v, vmm_ral::BFM, domains[j]);
00403: if (status != vmm_rw::IS_OK) begin
00404:
: do
: /* synopsys translate_off */
: if (log.start_msg(vmm_log::FAILURE_TYP, vmm_log::ERROR_SEV, "", -1)) begin
: void'(log.text($psprintf("Status was %s when writing \"%s\" through domain \"%s\".",
: status.name(), regs[i].get_fullname(), domains[j])));
: log.end_msg();
: end
: /* synopsys translate_on */
: while (0);
00406: end
00407:
00408: regs[i].mirror(status, vmm_ral::VERB, vmm_ral::BACKDOOR);
00409: if (status != vmm_rw::IS_OK) begin
00410:
: do
: /* synopsys translate_off */
: if (log.start_msg(vmm_log::FAILURE_TYP, vmm_log::ERROR_SEV, "", -1)) begin
: void'(log.text($psprintf("Status was %s when reading reset value of register \"%s\" through backdoor.",
: status.name(), regs[i].get_fullname())));
: log.end_msg();
: end
: /* synopsys translate_on */
: while (0);
00412: end
00413:
00414: regs[i].write(status, v, vmm_ral::BACKDOOR, domains[j]);
00415: if (status != vmm_rw::IS_OK) begin
00416:
: do
: /* synopsys translate_off */
: if (log.start_msg(vmm_log::FAILURE_TYP, vmm_log::ERROR_SEV, "", -1)) begin
: void'(log.text($psprintf("Status was %s when writing \"%s\" through backdoor.",
: status.name(), regs[i].get_fullname())));
: log.end_msg();
: end
: /* synopsys translate_on */
: while (0);
00418: end
00419:
00420: regs[i].mirror(status, vmm_ral::VERB, vmm_ral::BFM, domains[j]);
00421: if (status != vmm_rw::IS_OK) begin
00422:
: do
: /* synopsys translate_off */
: if (log.start_msg(vmm_log::FAILURE_TYP, vmm_log::ERROR_SEV, "", -1)) begin
: void'(log.text($psprintf("Status was %s when reading reset value of register \"%s\" through domain \"%s\".",
: status.name(), regs[i].get_fullname(), domains[j])));
: log.end_msg();
: end
: /* synopsys translate_on */
: while (0);
00424: end
00425: end
00426: end
00427: endtask: reg_access
00428:
00429:
00430: task vmm_ral_tests::mem_access(vmm_ral_block blk,
00431: vmm_log log);
00432: vmm_ral_mem mems[];
00433:
00434: // Access each location in all memories
00435: blk.get_memories(mems);
00436: foreach (mems[i]) begin
00437: vmm_ral::access_e mode;
00438: string domains[];
00439: int n_bits;
00440:
00441: // Memories with some attributes are not to be tested
00442: if (mems[i].get_attribute("NO_RAL_TESTS") != "" ||
00443: mems[i].get_attribute("NO_MEM_ACCESS_TEST") != "") continue;
00444:
00445: // Can only deal with memories with backdoor access
00446: if (mems[i].get_backdoor() == null) begin
00447:
: do
: /* synopsys translate_off */
: if (log.start_msg(vmm_log::FAILURE_TYP, vmm_log::WARNING_SEV, "", -1)) begin
: void'(log.text($psprintf("Memory \"%s\" does not have a backdoor mechanism available",
: mems[i].get_fullname())));
: log.end_msg();
: end
: /* synopsys translate_on */
: while(0);
00449: continue;
00450: end
00451:
00452: n_bits = mems[i].get_n_bits();
00453:
00454: // Memories may be accessible from multiple physical interfaces (domains)
00455: mems[i].get_domains(domains);
00456:
00457: // Walk the memory via each domain
00458: foreach (domains[j]) begin
00459: vmm_rw::status_e status;
00460: bit [64-1:0] val, exp, v;
00461:
00462:
: do
: /* synopsys translate_off */
: if (log.start_msg(vmm_log::NOTE_TYP, , "", -1)) begin
: void'(log.text($psprintf("Accessing memory %s in domain \"%s\"...\n",
: mems[i].get_fullname(), domains[j])));
: log.end_msg();
: end
: /* synopsys translate_on */
: while (0);
00464:
00465: mode = mems[i].get_access(domains[j]);
00466:
00467: // The access process is, for address k:
00468: // - Write random value via front door
00469: // - Read via backdoor and expect same random value if RW
00470: // - Write complement of random value via back door
00471: // - Read via front door and expect inverted random value
00472: for (int k = 0; k < mems[i].get_size(); k++) begin
00473: val = $random & ((1'b1<<n_bits)-1);
00474: if (mode == vmm_ral::RO) begin
00475: mems[i].peek(status, k, exp);
00476: if (status != vmm_rw::IS_OK) begin
00477:
: do
: /* synopsys translate_off */
: if (log.start_msg(vmm_log::FAILURE_TYP, vmm_log::ERROR_SEV, "", -1)) begin
: void'(log.text($psprintf("Status was %s when reading \"%s[%0d]\" through backdoor.",
: status.name(), mems[i].get_fullname(), k)));
: log.end_msg();
: end
: /* synopsys translate_on */
: while (0);
00479: end
00480: end
00481: else exp = val;
00482:
00483: mems[i].write(status, k, val, vmm_ral::BFM, domains[j]);
00484: if (status != vmm_rw::IS_OK) begin
00485:
: do
: /* synopsys translate_off */
: if (log.start_msg(vmm_log::FAILURE_TYP, vmm_log::ERROR_SEV, "", -1)) begin
: void'(log.text($psprintf("Status was %s when writing \"%s[%0d]\" through domain \"%s\".",
: status.name(), mems[i].get_fullname(), k, domains[j])));
: log.end_msg();
: end
: /* synopsys translate_on */
: while (0);
00487: end
00488:
00489: val = 'x;
00490: mems[i].peek(status, k, val);
00491: if (status != vmm_rw::IS_OK) begin
00492:
: do
: /* synopsys translate_off */
: if (log.start_msg(vmm_log::FAILURE_TYP, vmm_log::ERROR_SEV, "", -1)) begin
: void'(log.text($psprintf("Status was %s when reading \"%s[%0d]\" through backdoor.",
: status.name(), mems[i].get_fullname(), k)));
: log.end_msg();
: end
: /* synopsys translate_on */
: while (0);
00494: end
00495: else begin
00496: if (val !== exp) begin
00497:
: do
: /* synopsys translate_off */
: if (log.start_msg(vmm_log::FAILURE_TYP, vmm_log::ERROR_SEV, "", -1)) begin
: void'(log.text($psprintf("Backdoor \"%s[%0d]\" read back as 'h%h instead of 'h%h.",
: mems[i].get_fullname(), k, val, exp)));
: log.end_msg();
: end
: /* synopsys translate_on */
: while (0);
00499: end
00500: end
00501:
00502: exp = ~exp & ((1'b1<<n_bits)-1);
00503: mems[i].poke(status, k, exp);
00504: if (status != vmm_rw::IS_OK) begin
00505:
: do
: /* synopsys translate_off */
: if (log.start_msg(vmm_log::FAILURE_TYP, vmm_log::ERROR_SEV, "", -1)) begin
: void'(log.text($psprintf("Status was %s when writing \"%s[%0d-1]\" through backdoor.",
: status.name(), mems[i].get_fullname(), k)));
: log.end_msg();
: end
: /* synopsys translate_on */
: while (0);
00507: end
00508:
00509: mems[i].read(status, k, val, vmm_ral::BFM, domains[j]);
00510: if (status != vmm_rw::IS_OK) begin
00511:
: do
: /* synopsys translate_off */
: if (log.start_msg(vmm_log::FAILURE_TYP, vmm_log::ERROR_SEV, "", -1)) begin
: void'(log.text($psprintf("Status was %s when reading \"%s[%0d]\" through domain \"%s\".",
: status.name(), mems[i].get_fullname(), k, domains[j])));
: log.end_msg();
: end
: /* synopsys translate_on */
: while (0);
00513: end
00514: else begin
00515: if (mode == vmm_ral::WO) begin
00516: if (val !== '0) begin
00517:
: do
: /* synopsys translate_off */
: if (log.start_msg(vmm_log::FAILURE_TYP, vmm_log::ERROR_SEV, "", -1)) begin
: void'(log.text($psprintf("Front door \"%s[%0d]\" read back as 'h%h instead of 'h%h.",
: mems[i].get_fullname(), k, val, 0)));
: log.end_msg();
: end
: /* synopsys translate_on */
: while (0);
00519: end
00520: end
00521: else begin
00522: if (val !== exp) begin
00523:
: do
: /* synopsys translate_off */
: if (log.start_msg(vmm_log::FAILURE_TYP, vmm_log::ERROR_SEV, "", -1)) begin
: void'(log.text($psprintf("Front door \"%s[%0d]\" read back as 'h%h instead of 'h%h.",
: mems[i].get_fullname(), k, val, exp)));
: log.end_msg();
: end
: /* synopsys translate_on */
: while (0);
00525: end
00526: end
00527: end
00528: end
00529: end
00530: end
00531: endtask: mem_access
00532:
00533:
00534: task vmm_ral_tests::shared_access(vmm_ral_block blk,
00535: vmm_log log);
00536: vmm_ral_reg regs[];
00537: vmm_ral_mem mems[];
00538:
00539: // Iterate over all registers, looking for shared registers
00540: blk.get_registers(regs);
00541: foreach (regs[i]) begin
00542: string domains[];
00543: vmm_ral_field fields[];
00544: bit [64-1:0] other_mask;
00545: bit [64-1:0] wo_mask[];
00546:
00547: // Registers with some attributes are not to be tested
00548: if (regs[i].get_attribute("NO_RAL_TESTS") != "" ||
00549: regs[i].get_attribute("NO_SHARED_ACCESS_TEST") != "") continue;
00550:
00551: // Only look at shared registers
00552: if (regs[i].get_n_domains() < 2) continue;
00553: regs[i].get_domains(domains);
00554:
00555: // Let's see what kind of bits we have...
00556: regs[i].get_fields(fields);
00557:
00558: // Identify unpredictable bits and the ones we shouldn't change
00559: other_mask = 0;
00560: foreach (fields[k]) begin
00561: int lsb, w;
00562:
00563: lsb = fields[k].get_lsb_pos_in_register();
00564: w = fields[k].get_n_bits();
00565:
00566: if (fields[k].get_access(domains[0]) >= vmm_ral::OTHER) begin
00567: repeat (w) begin
00568: other_mask[lsb++] = 1'b1;
00569: end
00570: end
00571: end
00572:
00573: // WO bits will always readback as 0's but the mirror
00574: // with return what is supposed to have been written
00575: // so we cannot use the mirror-check function
00576: wo_mask = new [domains.size()];
00577: foreach (domains[j]) begin
00578: bit [64-1:0] wo;
00579: wo = 0;
00580: foreach (fields[k]) begin
00581: int lsb, w;
00582:
00583: lsb = fields[k].get_lsb_pos_in_register();
00584: w = fields[k].get_n_bits();
00585:
00586: if (fields[k].get_access(domains[j]) == vmm_ral::WO) begin
00587: repeat (w) begin
00588: wo[lsb++] = 1'b1;
00589: end
00590: end
00591: end
00592: wo_mask[j] = wo;
00593: end
00594:
00595: // Try to write through each domain
00596: foreach (domains[j]) begin
00597: vmm_rw::status_e status;
00598: bit [64-1:0] prev, v;
00599:
00600: // The mirror should contain the initial value
00601: prev = regs[i].get();
00602:
00603: // Write a random value, except in those "don't touch" fields
00604: v = ({$random, $random} & ~other_mask) | (prev & other_mask);
00605:
00606:
: do
: /* synopsys translate_off */
: if (log.start_msg(vmm_log::NOTE_TYP, , "", -1)) begin
: void'(log.text($psprintf("Writing register %s via domain \"%s\"...",
: regs[i].get_fullname(), domains[j])));
: log.end_msg();
: end
: /* synopsys translate_on */
: while (0);
00608:
00609:
: do
: /* synopsys translate_off */
: if (log.start_msg(vmm_log::DEBUG_TYP, vmm_log::DEBUG_SEV, "", -1)) begin
: void'(log.text($psprintf("Writing 'h%h over 'h%h", v, prev)));
: log.end_msg();
: end
: /* synopsys translate_on */
: while (0);
00610:
00611: regs[i].write(status, v, vmm_ral::BFM, domains[j]);
00612: if (status != vmm_rw::IS_OK) begin
00613:
: do
: /* synopsys translate_off */
: if (log.start_msg(vmm_log::FAILURE_TYP, vmm_log::ERROR_SEV, "", -1)) begin
: void'(log.text($psprintf("Status was %s when writing register \"%s\" through domain \"%s\".",
: status.name(), regs[i].get_fullname(), domains[j])));
: log.end_msg();
: end
: /* synopsys translate_on */
: while (0);
00615: end
00616:
00617: foreach (domains[k]) begin
00618: bit [64-1:0] actual, exp;
00619:
00620:
: do
: /* synopsys translate_off */
: if (log.start_msg(vmm_log::NOTE_TYP, , "", -1)) begin
: void'(log.text($psprintf("Reading register %s via domain \"%s\"...",
: regs[i].get_fullname(), domains[k])));
: log.end_msg();
: end
: /* synopsys translate_on */
: while (0);
00622:
00623: // Was it what we expected?
00624: exp = regs[i].get() & ~wo_mask[k];
00625:
00626: regs[i].read(status, actual, vmm_ral::BFM, domains[k]);
00627: if (status != vmm_rw::IS_OK) begin
00628:
: do
: /* synopsys translate_off */
: if (log.start_msg(vmm_log::FAILURE_TYP, vmm_log::ERROR_SEV, "", -1)) begin
: void'(log.text($psprintf("Status was %s when reading register \"%s\" through domain \"%s\".",
: status.name(), regs[i].get_fullname(), domains[k])));
: log.end_msg();
: end
: /* synopsys translate_on */
: while (0);
00630: end
00631:
00632:
: do
: /* synopsys translate_off */
: if (log.start_msg(vmm_log::DEBUG_TYP, vmm_log::DEBUG_SEV, "", -1)) begin
: void'(log.text($psprintf("Read 'h%h, expecting 'h%h",
: actual, exp)));
: log.end_msg();
: end
: /* synopsys translate_on */
: while (0);
00634:
00635: if (actual !== exp) begin
00636:
: do
: /* synopsys translate_off */
: if (log.start_msg(vmm_log::FAILURE_TYP, vmm_log::ERROR_SEV, "", -1)) begin
: void'(log.text($psprintf("Register \"%s\" through domain \"%s\" is 'h%h instead of 'h%h after writing 'h%h via domain \"%s\" over 'h%h.",
: regs[i].get_fullname(), domains[k],
: actual, exp, v, domains[j], prev)));
: log.end_msg();
: end
: /* synopsys translate_on */
: while (0);
00639: end
00640: end
00641: end
00642: end
00643:
00644: // Iterate over all memories, looking for shared ones
00645: blk.get_memories(mems);
00646: foreach (mems[i]) begin
00647: string domains[];
00648: int read_from = -1;
00649:
00650: // Memories with some attributes are not to be tested
00651: if (mems[i].get_attribute("NO_RAL_TESTS") != "" ||
00652: mems[i].get_attribute("NO_SHARED_ACCESS_TEST") != "") continue;
00653:
00654: // Only look at shared memories
00655: if (mems[i].get_n_domains() < 2) continue;
00656: mems[i].get_domains(domains);
00657:
00658: // We need at least a backdoor or a domain that can read
00659: // the shared memory
00660: if (mems[i].get_backdoor() == null) begin
00661: foreach (domains[j]) begin
00662: vmm_ral::access_e right;
00663: right = mems[i].get_access(domains[j]);
00664: if (right == vmm_ral::RW ||
00665: right == vmm_ral::RO) begin
00666: read_from = j;
00667: break;
00668: end
00669: end
00670: if (read_from < 0) begin
00671:
: do
: /* synopsys translate_off */
: if (mems[i].log.start_msg(vmm_log::FAILURE_TYP, vmm_log::WARNING_SEV, "", -1)) begin
: void'(mems[i].log.text("Memory cannot be read from any domains or backdoor. Shared access not verified."));
: mems[i].log.end_msg();
: end
: /* synopsys translate_on */
: while(0);
00672: continue;
00673: end
00674: end
00675:
00676: // Try to write through each domain
00677: foreach (domains[j]) begin
00678:
00679:
: do
: /* synopsys translate_off */
: if (log.start_msg(vmm_log::NOTE_TYP, , "", -1)) begin
: void'(log.text($psprintf("Writing shared memory \"%s\" via domain \"%s\".",
: mems[i].get_fullname(), domains[j])));
: log.end_msg();
: end
: /* synopsys translate_on */
: while (0);
00681:
00682: // All addresses
00683: for (int offset = 0; offset < mems[i].get_size(); offset++) begin
00684: vmm_rw::status_e status;
00685: bit [64-1:0] prev, v;
00686:
00687: // Read the initial value
00688: if (mems[i].get_backdoor() != null) begin
00689: mems[i].peek(status, offset, prev);
00690: if (status != vmm_rw::IS_OK) begin
00691:
: do
: /* synopsys translate_off */
: if (log.start_msg(vmm_log::FAILURE_TYP, vmm_log::ERROR_SEV, "", -1)) begin
: void'(log.text($psprintf("Status was %s when reading initial value of \"%s\"[%0d] through backdoor.",
: status.name(), mems[i].get_fullname(), offset)));
: log.end_msg();
: end
: /* synopsys translate_on */
: while (0);
00693: end
00694: end
00695: else begin
00696: mems[i].read(status, offset, prev, vmm_ral::BFM, domains[read_from]);
00697: if (status != vmm_rw::IS_OK) begin
00698:
: do
: /* synopsys translate_off */
: if (log.start_msg(vmm_log::FAILURE_TYP, vmm_log::ERROR_SEV, "", -1)) begin
: void'(log.text($psprintf("Status was %s when reading initial value of \"%s\"[%0d] through domain \"%s\".",
: status.name(), mems[i].get_fullname(),
: offset, domains[read_from])));
: log.end_msg();
: end
: /* synopsys translate_on */
: while (0);
00701: end
00702: end
00703:
00704:
00705: // Write a random value,
00706: v = {$random, $random};
00707:
00708: mems[i].write(status, offset, v, vmm_ral::BFM, domains[j]);
00709: if (status != vmm_rw::IS_OK) begin
00710:
: do
: /* synopsys translate_off */
: if (log.start_msg(vmm_log::FAILURE_TYP, vmm_log::ERROR_SEV, "", -1)) begin
: void'(log.text($psprintf("Status was %s when writing \"%s\"[%0d] through domain \"%s\".",
: status.name(), mems[i].get_fullname(), offset, domains[j])));
: log.end_msg();
: end
: /* synopsys translate_on */
: while (0);
00712: end
00713:
00714: // Read back from all other domains
00715: foreach (domains[k]) begin
00716: bit [64-1:0] actual, exp;
00717:
00718: mems[i].read(status, offset, actual, vmm_ral::BFM, domains[k]);
00719: if (status != vmm_rw::IS_OK) begin
00720:
: do
: /* synopsys translate_off */
: if (log.start_msg(vmm_log::FAILURE_TYP, vmm_log::ERROR_SEV, "", -1)) begin
: void'(log.text($psprintf("Status was %s when reading %s[%0d] through domain \"%s\".",
: status.name(), mems[i].get_fullname(), offset, domains[k])));
: log.end_msg();
: end
: /* synopsys translate_on */
: while (0);
00722: end
00723:
00724: // Was it what we expected?
00725: exp = v;
00726: if (mems[i].get_access(domains[j]) == vmm_ral::RO) begin
00727: exp = prev;
00728: end
00729: if (mems[i].get_access(domains[k]) == vmm_ral::WO) begin
00730: exp = 0;
00731: end
00732: // Trim to number of bits
00733: exp &= (1 << mems[i].get_n_bits()) - 1;
00734: if (actual !== exp) begin
00735:
: do
: /* synopsys translate_off */
: if (log.start_msg(vmm_log::FAILURE_TYP, vmm_log::ERROR_SEV, "", -1)) begin
: void'(log.text($psprintf("%s[%0d] through domain \"%s\" is 'h%h instead of 'h%h after writing 'h%h via domain \"%s\" over 'h%h.",
: mems[i].get_fullname(), offset, domains[k],
: actual, exp, v, domains[j], prev)));
: log.end_msg();
: end
: /* synopsys translate_on */
: while (0);
00738: end
00739: end
00740: end
00741: end
00742: end
00743: endtask: shared_access