shared_access.sv

Go to the documentation of this file.
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
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
Doxygen Version: 1.5.6
Sat Oct 18 11:38:21 2008
Find a documentation bug? Report bugs to: bugs.intelligentdv.com Project: DoxygenFilterSV