bit_bash.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 bit_bash;
00031 
00032 vmm_log log = new("Bit Bash", "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 
00040    ral_model = env.ral.get_model();
00041    if (ral_model == null) begin
00042       `vmm_fatal(log, "No RAL abstraction model was specified");
00043    end
00044 
00045    env.reset_dut();
00046    ral_model.reset();
00047 
00048    // Iterate over all registers, trying to modify read-only bits
00049    // and making sure read-write bits can be set and cleared
00050    ral_model.get_registers(regs);
00051    foreach (regs[i]) begin
00052       vmm_ral_field fields[];
00053       vmm_ral::access_e mode[`VMM_RAL_DATA_WIDTH];
00054       string domains[];
00055       bit [`VMM_RAL_DATA_WIDTH-1:0] wo_mask;
00056       bit [`VMM_RAL_DATA_WIDTH-1:0] reset_val;
00057       int n_bits;
00058 
00059       n_bits = regs[i].get_n_bytes() * 8;
00060 
00061       // Let's see what kind of bits we have...
00062       regs[i].get_fields(fields);
00063 
00064       // Registers may be accessible from multiple physical interfaces (domains)
00065       regs[i].get_domains(domains);
00066 
00067       // Bash the bits in the register via each domain
00068       foreach (domains[j]) begin
00069          vmm_rw::status_e status;
00070          bit [`VMM_RAL_DATA_WIDTH-1:0] val, exp, v, other;
00071          int next_lsb;
00072 
00073          next_lsb = 0;
00074          wo_mask = '1;
00075          foreach (fields[k]) begin
00076             int lsb, w;
00077 
00078             lsb = fields[k].get_lsb_pos_in_register();
00079             w   = fields[k].get_n_bits();
00080 
00081             // Any unused bits on the right side of the LSB?
00082             while (next_lsb < lsb) begin
00083                mode[next_lsb++] = vmm_ral::RO;
00084             end
00085 
00086             repeat (w) begin
00087                mode[next_lsb] = fields[k].get_access(domains[j]);
00088                if (mode[next_lsb] == vmm_ral::WO) wo_mask[next_lsb] = 1'b0;
00089                next_lsb++;
00090             end
00091          end
00092          // Any unused bits on the left side of the MSB?
00093          while (next_lsb < 64) begin
00094             mode[next_lsb++] = vmm_ral::RO;
00095          end
00096 
00097          `vmm_note(log, $psprintf("Verifying bits in register %s in domain \"%s\"...",
00098                                   regs[i].get_fullname(), domains[j]));
00099 
00100          // The mirror still contains initial value
00101          reset_val = regs[i].get();
00102 
00103          // But the mirrored value of any WO bits will read back
00104          // as all zeroes via the frontdoor...
00105          reset_val &= wo_mask;
00106 
00107          regs[i].read(status, val, vmm_ral::BFM, domains[j]);
00108          if (status != vmm_rw::IS_OK) begin
00109             `vmm_error(log, $psprintf("Status was %s when reading register \"%s\" through domain \"%s\".",
00110                                       status, regs[i].get_fullname(), domains[j]));
00111          end
00112 
00113          if (val !== reset_val) begin
00114             `vmm_error(log, $psprintf("Initial value of register \"%s\" ('h%h) not %s ('h%h)",
00115                                       regs[i].get_fullname(), val,
00116                                       (j == 0) ? "reset value" : "as expected",
00117                                       reset_val));
00118          end
00119 
00120          // Bash the kth bit
00121          other = 0;
00122          for (int k = 0; k < n_bits; k++) begin
00123 
00124             // Cannot test unpredictable bit behavior
00125             if (mode[k] >= vmm_ral::DC) begin
00126                other[k] = 1;
00127                continue;
00128             end
00129 
00130             bash_kth_bit(regs[i], k, mode[k], domains[j], wo_mask);
00131          end
00132 
00133          // Write the complement of the reset value
00134          // Except in the "OTHER" and "USERx" bits
00135          val = reset_val ^ ~other;
00136          
00137          regs[i].write(status, val, vmm_ral::BFM, domains[j]);
00138          if (status != vmm_rw::IS_OK) begin
00139             `vmm_error(log, $psprintf("Status was %s when writing to register \"%s\" through domain \"%s\".",
00140                                       status, regs[i].get_fullname(), domains[j]));
00141          end
00142    
00143          exp = regs[i].get() & wo_mask;
00144          regs[i].read(status, v, vmm_ral::BFM, domains[j]);
00145          if (status != vmm_rw::IS_OK) begin
00146             `vmm_error(log, $psprintf("Status was %s when reading register \"%s\" through domain \"%s\".",
00147                                       status, regs[i].get_fullname(), domains[j]));
00148          end
00149    
00150          if (v !== exp) begin
00151             `vmm_error(log, $psprintf("Writing 'h%h to register \"%s\" with initial value 'h%h yielded 'h%h instead of 'h%h",
00152                                       val, regs[i].get_fullname(), reset_val, v, exp));
00153          end
00154       end
00155    end
00156 
00157    // Apply reset then verify all reset values
00158    env.hw_reset();
00159    ral_model.reset();
00160 
00161    foreach (regs[i]) begin
00162       string domains[];
00163 
00164       // Registers may be accessible from multiple physical interfaces (domains)
00165       regs[i].get_domains(domains);
00166 
00167       // Verify the reset value in each domain
00168       foreach (domains[j]) begin
00169          vmm_rw::status_e status;
00170          bit [`VMM_RAL_DATA_WIDTH-1:0] v;
00171       
00172          `vmm_note(log, $psprintf("Verifying reset value of register %s in domain \"%s\"...",
00173                                   regs[i].get_fullname(), domains[j]));
00174 
00175          regs[i].mirror(status, vmm_ral::VERB, vmm_ral::BFM, domains[j]);
00176          if (status != vmm_rw::IS_OK) begin
00177             `vmm_error(log, $psprintf("Status was %s when reading reset value of register \"%s\" through domain \"%s\".",
00178                                       status, regs[i].get_fullname(), domains[j]));
00179          end
00180       end
00181    end
00182    
00183    env.log.report();
00184 end
00185 
00186 
00187 task bash_kth_bit(input vmm_ral_reg       regs,
00188                   input int               k,
00189                   input vmm_ral::access_e mode,
00190                   input string            domain,
00191                   input bit [`VMM_RAL_DATA_WIDTH-1:0]        wo_mask);
00192    vmm_rw::status_e status;
00193    bit [`VMM_RAL_DATA_WIDTH-1:0] val, exp, v;
00194    bit bit_val;
00195 
00196    `vmm_note(log, $psprintf("...Bashing %s bit #%0d", mode.name(), k));
00197 
00198    repeat (2) begin
00199       val = regs.get();
00200       v   = val;
00201       exp = val;
00202       val[k] = ~val[k];
00203       bit_val = val[k];
00204 
00205       regs.write(status, val, vmm_ral::BFM, domain);
00206       if (status != vmm_rw::IS_OK) begin
00207          `vmm_error(log, $psprintf("Status was %s when writing to register \"%s\" through domain \"%s\".",
00208                                    status, regs.get_fullname(), domain));
00209       end
00210 
00211       exp = regs.get() & wo_mask;
00212       regs.read(status, val, vmm_ral::BFM, domain);
00213       if (status != vmm_rw::IS_OK) begin
00214          `vmm_error(log, $psprintf("Status was %s when reading register \"%s\" through domain \"%s\".",
00215                                    status, regs.get_fullname(), domain));
00216       end
00217    
00218       if (val !== exp) begin
00219          `vmm_error(log, $psprintf("Writing a %b in bit #%0d of register \"%s\" with initial value 'h%h yielded 'h%h instead of 'h%h",
00220                                    bit_val, k, regs.get_fullname(), v, val, exp));
00221       end
00222    end
00223 
00224    // If this is a write-once bit, apply reset and make sure it
00225    // can be written again.
00226    if (mode == vmm_ral::W1) begin
00227       env.hw_reset();
00228       regs.reset();
00229       val = regs.get();
00230       val[k] = ~val[k];
00231       regs.write(status, val, vmm_ral::BFM, domain);
00232       if (status != vmm_rw::IS_OK) begin
00233          `vmm_error(log, $psprintf("Status was %s when writing to register \"%s\" through domain \"%s\".",
00234                                    status, regs.get_fullname(), domain));
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          `vmm_error(log, $psprintf("Status was %s when reading register \"%s\" through domain \"%s\".",
00241                                    status, regs.get_fullname(), domain));
00242       end
00243    
00244       if (val !== exp) begin
00245          `vmm_error(log, $psprintf("Writing a %b in W1 bit #%0d of register \"%s\" after reset yielded 'h%h instead of 'h%h",
00246                                    bit_val, k, regs.get_fullname(), val, exp));
00247       end
00248    end
00249 endtask: bash_kth_bit
00250 
00251 endprogram: bit_bash
00252 

Intelligent Design Verification
Intelligent Design Verification
Project: VMM, Revision: 1.0.1
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:32:18 2008
Find a documentation bug? Report bugs to: bugs.intelligentdv.com Project: DoxygenFilterSV