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 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 Version: 1.5.6 Sat Oct 18 11:32:18 2008 |