📄 ecc_mem.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.// -------------------------------------------------------------////// ECC-protected memory model extension for RAL//// This example assumes 32 bits of user data and 4 bits of ECC code// stored in a memory with 36-bit addressable words.//`include "vmm_ral.sv"//// Compute ECC code//class ecc_32_4; virtual function bit [3:0] compute(bit [31:0] data); compute = {^data[31:24], ^data[23:16], ^data[15: 8], ^data[ 7: 0]}; endfunction: computeendclass: ecc_32_4 //// Memory callback extension implementing ECC error injection.// Errors can be injected when a memory location is written// (i.e. the ECC error will be reported every time the location// is read back) or it can be injected when a memory location is// read (i.e. the ECC error may or may not be reported when the// same location is subsequently read).//// This error injection model supports only single-bit errors, in// either the data or ECC code itself.//// By default, errors are not injected. Errors can be injected at// a specified rate by setting the 'error_rate' value to non-zero.// A value of 'hFF indicates 100% error rate.//// This callback class works in tandem with the backdoor access// class to allow direct access to the ECC code via the the backdoor.// See ecc_mem0_bkdr class below.//class ecc_mem0_cb extends vmm_ral_mem_callbacks; bit [7:0] error_rate = 0; rand bit error_on_write; rand bit error_on_read; rand bit [6:0] error_on_bit; static local ecc_32_4 ecc = new; local bit [35:0] ecc_rdat; constraint valid { error_on_bit < 36; } constraint write_error_rate { error_on_write dist {0 :/ (255 - error_rate), 1 :/ error_rate}; } constraint read_error_rate { error_on_read dist {0 :/ (255 - error_rate), 1 :/ error_rate}; } virtual task post_write(vmm_ral_mem mem, bit [63:0] offset, bit [63:0] wdat, vmm_ral::path_e path, string domain, ref vmm_rw::status_e status); bit [35:0] ecc_wdat; // No point in injecting random ECC error on write if // writing via backdoor WITH an ECC error if (path == vmm_ral::BACKDOOR && wdat[35:32] != 4'b0000) begin this.error_on_write = 1; return; end ecc_wdat = {this.ecc.compute(wdat), wdat[31:0]}; this.randomize(); if (this.error_on_write) begin ecc_wdat ^= 1'b1 << error_on_bit; end tb_top.dut.mem0[offset] = ecc_wdat; endtask: post_write virtual task pre_read(vmm_ral_mem mem, ref bit [63:0] offset, ref vmm_ral::path_e path, ref string domain); // No point in injecting ECC error on read if // reading via backdoor... if (path == vmm_ral::BACKDOOR) begin this.error_on_read = 0; return; end this.randomize(); if (this.error_on_read) begin ecc_rdat = tb_top.dut.mem0[offset]; tb_top.dut.mem0[offset] = ecc_rdat ^ (1'b1 << error_on_bit); end endtask: pre_read virtual task post_read(input vmm_ral_mem mem, input bit [63:0] offset, ref bit [63:0] rdat, input vmm_ral::path_e path, input string domain, ref vmm_rw::status_e status); // Remove the ECC error at the end of the read if (this.error_on_read) begin tb_top.dut.mem0[offset] = ecc_rdat; end endtask: post_readendclass: ecc_mem0_cb//// Backdoor accesses can include ECC information because// the data value is always transfered as 64 bits.// If the ECC-protected memory has addressable locations// that are less than 64 bits, the additional bits can be used// to carry the ECC information. In this example, the 32 bit// data values are concatenated with a 4-bit ECC code yielding// 36 bit transfers.//// The ECC information is represented using a validity// indicator, not the ECC value. If the bit is cleared, the// corresponding ECC bit is valid. If the bit is set, the// corresponding ECC bit is invalid or will be corrupted.//// Note that backdoor accesses are subjected to the memory// callbacks (see ecc_mem0_cb class above) before they are// physically executed in this backdoor access class.//class ecc_mem0_backdoor extends vmm_ral_mem_backdoor; static local ecc_32_4 ecc = new; virtual task write(output vmm_rw::status_e status, input bit [63:0] offset, input bit [63:0] data, input int data_id, input int scenario_id, input int stream_id); // Corrupt ECC bit if it is set in the data to write data[35:32] = this.ecc.compute(data[31:0]) ^ data[35:32]; tb_top.dut.mem0[offset] = data; status = vmm_rw::IS_OK; endtask: write virtual task read(output vmm_rw::status_e status, input bit [63:0] offset, output bit [63:0] data, input int data_id, input int scenario_id, input int stream_id); // Report invalid ECC bits data = tb_top.dut.mem0[offset]; data[35:32] = this.ecc.compute(data[31:0]) ^ data[35:32]; status = vmm_rw::IS_OK; endtask: readendclass: ecc_mem0_backdoor//// Fake DUT to enable error-free compilation//module dut(); reg [35:0] mem0[1023];endmodulemodule tb_top();dut dut();endmodule
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -