⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 shared_access.sv

📁 VMM 文档加源码, synopsys公司很好的验证资料
💻 SV
字号:
// // -------------------------------------------------------------//    Copyright 2004-2008 Synopsys, Inc.//    All Rights Reserved Worldwide// //    Licensed under the Apache License, Version 2.0 (the//    "License"); you may not use this file except in//    compliance with the License.  You may obtain a copy of//    the License at// //        http://www.apache.org/licenses/LICENSE-2.0// //    Unless required by applicable law or agreed to in//    writing, software distributed under the License is//    distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR//    CONDITIONS OF ANY KIND, either express or implied.  See//    the License for the specific language governing//    permissions and limitations under the License.// -------------------------------------------------------------// `include "ral_env.svh"`ifndef RAL_TB_ENV`define RAL_TB_ENV tb_env`endifprogram shared_access;vmm_log log = new("Shared Access", "Test");`RAL_TB_ENV env = new;initialbegin   vmm_ral_block_or_sys ral_model;   vmm_ral_reg regs[];   vmm_ral_mem mems[];   ral_model = env.ral.get_model();   if (ral_model == null) begin      `vmm_fatal(log, "No RAL abstraction model was specified");   end   env.reset_dut();   ral_model.reset();   //log.set_verbosity(vmm_log::DEBUG_SEV);   //env.ral.log.set_verbosity(vmm_log::TRACE_SEV);   // Iterate over all registers, looking for shared registers   ral_model.get_registers(regs);   foreach (regs[i]) begin      string domains[];      vmm_ral_field fields[];      bit [`VMM_RAL_DATA_WIDTH-1:0] other_mask;      bit [`VMM_RAL_DATA_WIDTH-1:0] wo_mask[];      // Only look at shared registers      if (regs[i].get_n_domains() < 2) continue;      regs[i].get_domains(domains);      // Let's see what kind of bits we have...      regs[i].get_fields(fields);      // Identify unpredictable bits and the ones we shouldn't change      other_mask = 0;      foreach (fields[k]) begin         int lsb, w;         lsb = fields[k].get_lsb_pos_in_register();         w   = fields[k].get_n_bits();         if (fields[k].get_access(domains[0]) >= vmm_ral::OTHER) begin            repeat (w) begin               other_mask[lsb++] = 1'b1;            end         end      end      // WO bits will always readback as 0's but the mirror      // with return what is supposed to have been written      // so we cannot use the mirror-check function      wo_mask = new [domains.size()];      foreach (domains[j]) begin         bit [`VMM_RAL_DATA_WIDTH-1:0] wo;         wo = 0;         foreach (fields[k]) begin            int lsb, w;            lsb = fields[k].get_lsb_pos_in_register();            w   = fields[k].get_n_bits();            if (fields[k].get_access(domains[j]) == vmm_ral::WO) begin               repeat (w) begin                  wo[lsb++] = 1'b1;               end            end         end         wo_mask[j] = wo;      end      // Try to write through each domain      foreach (domains[j]) begin         vmm_rw::status_e status;         bit [`VMM_RAL_DATA_WIDTH-1:0] prev, v;         // The mirror should contain the initial value         prev = regs[i].get();         // Write a random value, except in those "don't touch" fields         v = ({$random, $random} & ~other_mask) | (prev & other_mask);         `vmm_note(log, $psprintf("Writing register %s via domain \"%s\"...",                                  regs[i].get_fullname(), domains[j]));         `vmm_debug(log, $psprintf("Writing 'h%h over 'h%h", v, prev));         regs[i].write(status, v, vmm_ral::BFM, domains[j]);         if (status != vmm_rw::IS_OK) begin            `vmm_error(log, $psprintf("Status was %s when writing register \"%s\" through domain \"%s\".",                                      status.name(), regs[i].get_fullname(), domains[j]));         end         foreach (domains[k]) begin            bit [`VMM_RAL_DATA_WIDTH-1:0] actual, exp;            `vmm_note(log, $psprintf("Reading register %s via domain \"%s\"...",                                     regs[i].get_fullname(), domains[k]));            // Was it what we expected?            exp = regs[i].get() & ~wo_mask[k];            regs[i].read(status, actual, vmm_ral::BFM, domains[k]);            if (status != vmm_rw::IS_OK) begin               `vmm_error(log, $psprintf("Status was %s when reading register \"%s\" through domain \"%s\".",                                         status.name(), regs[i].get_fullname(), domains[k]));            end            `vmm_debug(log, $psprintf("Read 'h%h, expecting 'h%h",                                      actual, exp));            if (actual !== exp) begin               `vmm_error(log, $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));            end         end      end   end      // Iterate over all memories, looking for shared ones   ral_model.get_memories(mems);   foreach (mems[i]) begin      string domains[];      int read_from = -1;      // Only look at shared memories      if (mems[i].get_n_domains() < 2) continue;      mems[i].get_domains(domains);      // We need at least a backdoor or a domain that can read      // the shared memory      if (mems[i].get_backdoor() == null) begin         foreach (domains[j]) begin            vmm_ral::access_e right;            right = mems[i].get_access(domains[j]);            if (right == vmm_ral::RW ||                right == vmm_ral::RO) begin               read_from = j;               break;            end         end         if (read_from < 0) begin            `vmm_warning(mems[i].log, "Memory cannot be read from any domains or backdoor. Shared access not verified.");            continue;         end      end      // Try to write through each domain      foreach (domains[j]) begin         `vmm_note(log, $psprintf("Writing shared memory \"%s\" via domain \"%s\".",                                  mems[i].get_fullname(), domains[j]));         // All addresses         for (int offset = 0; offset < mems[i].get_size(); offset++) begin            vmm_rw::status_e status;            bit [`VMM_RAL_DATA_WIDTH-1:0] prev, v;                        // Read the initial value            if (mems[i].get_backdoor() != null) begin               mems[i].peek(status, offset, prev);               if (status != vmm_rw::IS_OK) begin                  `vmm_error(log, $psprintf("Status was %s when reading initial value of \"%s\"[%0d] through backdoor.",                                            status.name(), mems[i].get_fullname(), offset));               end            end            else begin               mems[i].read(status, offset, prev, vmm_ral::BFM, domains[read_from]);               if (status != vmm_rw::IS_OK) begin                  `vmm_error(log, $psprintf("Status was %s when reading initial value of \"%s\"[%0d] through domain \"%s\".",                                            status.name(), mems[i].get_fullname(),                                            offset, domains[read_from]));               end            end                                    // Write a random value,            v = {$random, $random};                        mems[i].write(status, offset, v, vmm_ral::BFM, domains[j]);            if (status != vmm_rw::IS_OK) begin               `vmm_error(log, $psprintf("Status was %s when writing \"%s\"[%0d] through domain \"%s\".",                                         status.name(), mems[i].get_fullname(), offset, domains[j]));            end                        // Read back from all other domains            foreach (domains[k]) begin               bit [`VMM_RAL_DATA_WIDTH-1:0] actual, exp;               mems[i].read(status, offset, actual, vmm_ral::BFM, domains[k]);               if (status != vmm_rw::IS_OK) begin                  `vmm_error(log, $psprintf("Status was %s when reading %s[%0d] through domain \"%s\".",                                         status.name(), mems[i].get_fullname(), offset, domains[k]));               end               // Was it what we expected?               exp = v;               if (mems[i].get_access(domains[j]) == vmm_ral::RO) begin                  exp = prev;               end               if (mems[i].get_access(domains[k]) == vmm_ral::WO) begin                  exp = 0;               end               // Trim to number of bits               exp &= (1 << mems[i].get_n_bits()) - 1;               if (actual !== exp) begin                  `vmm_error(log, $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));               end            end         end      end   end      env.log.report();endendprogram: shared_access

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -