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 `include "ral_env.svh" 00024 00025 `ifndef RAL_TB_ENV 00026 `define RAL_TB_ENV tb_env 00027 `endif 00028 00029 00030 program shared_access; 00031 00032 vmm_log log = new("Shared Access", "Test"); 00033 `RAL_TB_ENV env = new; 00034 00035 initial 00036 begin 00037 vmm_ral_block_or_sys ral_model; 00038 vmm_ral_reg regs[]; 00039 vmm_ral_mem mems[]; 00040 00041 ral_model = env.ral.get_model(); 00042 if (ral_model == null) begin 00043 `vmm_fatal(log, "No RAL abstraction model was specified"); 00044 end 00045 00046 env.reset_dut(); 00047 ral_model.reset(); 00048 00049 //log.set_verbosity(vmm_log::DEBUG_SEV); 00050 //env.ral.log.set_verbosity(vmm_log::TRACE_SEV); 00051 00052 // Iterate over all registers, looking for shared registers 00053 ral_model.get_registers(regs); 00054 foreach (regs[i]) begin 00055 string domains[]; 00056 vmm_ral_field fields[]; 00057 bit [`VMM_RAL_DATA_WIDTH-1:0] other_mask; 00058 bit [`VMM_RAL_DATA_WIDTH-1:0] wo_mask[]; 00059 00060 // Only look at shared registers 00061 if (regs[i].get_n_domains() < 2) continue; 00062 regs[i].get_domains(domains); 00063 00064 // Let's see what kind of bits we have... 00065 regs[i].get_fields(fields); 00066 00067 // Identify unpredictable bits and the ones we shouldn't change 00068 other_mask = 0; 00069 foreach (fields[k]) begin 00070 int lsb, w; 00071 00072 lsb = fields[k].get_lsb_pos_in_register(); 00073 w = fields[k].get_n_bits(); 00074 00075 if (fields[k].get_access(domains[0]) >= vmm_ral::OTHER) begin 00076 repeat (w) begin 00077 other_mask[lsb++] = 1'b1; 00078 end 00079 end 00080 end 00081 00082 // WO bits will always readback as 0's but the mirror 00083 // with return what is supposed to have been written 00084 // so we cannot use the mirror-check function 00085 wo_mask = new [domains.size()]; 00086 foreach (domains[j]) begin 00087 bit [`VMM_RAL_DATA_WIDTH-1:0] wo; 00088 wo = 0; 00089 foreach (fields[k]) begin 00090 int lsb, w; 00091 00092 lsb = fields[k].get_lsb_pos_in_register(); 00093 w = fields[k].get_n_bits(); 00094 00095 if (fields[k].get_access(domains[j]) == vmm_ral::WO) begin 00096 repeat (w) begin 00097 wo[lsb++] = 1'b1; 00098 end 00099 end 00100 end 00101 wo_mask[j] = wo; 00102 end 00103 00104 // Try to write through each domain 00105 foreach (domains[j]) begin 00106 vmm_rw::status_e status; 00107 bit [`VMM_RAL_DATA_WIDTH-1:0] prev, v; 00108 00109 // The mirror should contain the initial value 00110 prev = regs[i].get(); 00111 00112 // Write a random value, except in those "don't touch" fields 00113 v = ({$random, $random} & ~other_mask) | (prev & other_mask); 00114 00115 `vmm_note(log, $psprintf("Writing register %s via domain \"%s\"...", 00116 regs[i].get_fullname(), domains[j])); 00117 00118 `vmm_debug(log, $psprintf("Writing 'h%h over 'h%h", v, prev)); 00119 00120 regs[i].write(status, v, vmm_ral::BFM, domains[j]); 00121 if (status != vmm_rw::IS_OK) begin 00122 `vmm_error(log, $psprintf("Status was %s when writing register \"%s\" through domain \"%s\".", 00123 status.name(), regs[i].get_fullname(), domains[j])); 00124 end 00125 00126 foreach (domains[k]) begin 00127 bit [`VMM_RAL_DATA_WIDTH-1:0] actual, exp; 00128 00129 `vmm_note(log, $psprintf("Reading register %s via domain \"%s\"...", 00130 regs[i].get_fullname(), domains[k])); 00131 00132 // Was it what we expected? 00133 exp = regs[i].get() & ~wo_mask[k]; 00134 00135 regs[i].read(status, actual, vmm_ral::BFM, domains[k]); 00136 if (status != vmm_rw::IS_OK) begin 00137 `vmm_error(log, $psprintf("Status was %s when reading register \"%s\" through domain \"%s\".", 00138 status.name(), regs[i].get_fullname(), domains[k])); 00139 end 00140 00141 `vmm_debug(log, $psprintf("Read 'h%h, expecting 'h%h", 00142 actual, exp)); 00143 00144 if (actual !== exp) begin 00145 `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.", 00146 regs[i].get_fullname(), domains[k], 00147 actual, exp, v, domains[j], prev)); 00148 end 00149 end 00150 end 00151 end 00152 00153 // Iterate over all memories, looking for shared ones 00154 ral_model.get_memories(mems); 00155 foreach (mems[i]) begin 00156 string domains[]; 00157 int read_from = -1; 00158 00159 // Only look at shared memories 00160 if (mems[i].get_n_domains() < 2) continue; 00161 mems[i].get_domains(domains); 00162 00163 // We need at least a backdoor or a domain that can read 00164 // the shared memory 00165 if (mems[i].get_backdoor() == null) begin 00166 foreach (domains[j]) begin 00167 vmm_ral::access_e right; 00168 right = mems[i].get_access(domains[j]); 00169 if (right == vmm_ral::RW || 00170 right == vmm_ral::RO) begin 00171 read_from = j; 00172 break; 00173 end 00174 end 00175 if (read_from < 0) begin 00176 `vmm_warning(mems[i].log, "Memory cannot be read from any domains or backdoor. Shared access not verified."); 00177 continue; 00178 end 00179 end 00180 00181 // Try to write through each domain 00182 foreach (domains[j]) begin 00183 00184 `vmm_note(log, $psprintf("Writing shared memory \"%s\" via domain \"%s\".", 00185 mems[i].get_fullname(), domains[j])); 00186 00187 // All addresses 00188 for (int offset = 0; offset < mems[i].get_size(); offset++) begin 00189 vmm_rw::status_e status; 00190 bit [`VMM_RAL_DATA_WIDTH-1:0] prev, v; 00191 00192 // Read the initial value 00193 if (mems[i].get_backdoor() != null) begin 00194 mems[i].peek(status, offset, prev); 00195 if (status != vmm_rw::IS_OK) begin 00196 `vmm_error(log, $psprintf("Status was %s when reading initial value of \"%s\"[%0d] through backdoor.", 00197 status.name(), mems[i].get_fullname(), offset)); 00198 end 00199 end 00200 else begin 00201 mems[i].read(status, offset, prev, vmm_ral::BFM, domains[read_from]); 00202 if (status != vmm_rw::IS_OK) begin 00203 `vmm_error(log, $psprintf("Status was %s when reading initial value of \"%s\"[%0d] through domain \"%s\".", 00204 status.name(), mems[i].get_fullname(), 00205 offset, domains[read_from])); 00206 end 00207 end 00208 00209 00210 // Write a random value, 00211 v = {$random, $random}; 00212 00213 mems[i].write(status, offset, v, vmm_ral::BFM, domains[j]); 00214 if (status != vmm_rw::IS_OK) begin 00215 `vmm_error(log, $psprintf("Status was %s when writing \"%s\"[%0d] through domain \"%s\".", 00216 status.name(), mems[i].get_fullname(), offset, domains[j])); 00217 end 00218 00219 // Read back from all other domains 00220 foreach (domains[k]) begin 00221 bit [`VMM_RAL_DATA_WIDTH-1:0] actual, exp; 00222 00223 mems[i].read(status, offset, actual, vmm_ral::BFM, domains[k]); 00224 if (status != vmm_rw::IS_OK) begin 00225 `vmm_error(log, $psprintf("Status was %s when reading %s[%0d] through domain \"%s\".", 00226 status.name(), mems[i].get_fullname(), offset, domains[k])); 00227 end 00228 00229 // Was it what we expected? 00230 exp = v; 00231 if (mems[i].get_access(domains[j]) == vmm_ral::RO) begin 00232 exp = prev; 00233 end 00234 if (mems[i].get_access(domains[k]) == vmm_ral::WO) begin 00235 exp = 0; 00236 end 00237 // Trim to number of bits 00238 exp &= (1 << mems[i].get_n_bits()) - 1; 00239 if (actual !== exp) begin 00240 `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.", 00241 mems[i].get_fullname(), offset, domains[k], 00242 actual, exp, v, domains[j], prev)); 00243 end 00244 end 00245 end 00246 end 00247 end 00248 00249 env.log.report(); 00250 end 00251 endprogram: shared_access 00252
![]() Intelligent Design Verification Project: VMM, Revision: 1.0.0 |
Copyright (c) 2008 Intelligent Design Verification. Permission is granted to copy, distribute and/or modify this document under the terms of the GNU Free Documentation License, Version 1.2 or any later version published by the Free Software Foundation; with no Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts. A copy of the license is included here: http://www.intelligentdv.com/licenses/fdl.txt |
![]() Doxygen Version: 1.5.6 Sat Oct 18 11:38:21 2008 |