URL
https://opencores.org/ocsvn/qaz_libs/qaz_libs/trunk
Subversion Repositories qaz_libs
[/] [qaz_libs/] [trunk/] [axi4_lib/] [sim/] [src/] [legacy/] [axi4_models/] [axi4_memory_pkg.sv] - Rev 45
Compare with Previous | Blame | View Log
////////////////////////////////////////////////////////////////////////// //////// Copyright (C) 2015 Authors and OPENCORES.ORG //////// //////// This source file may be used and distributed without //////// restriction provided that this copyright statement is not //////// removed from the file and that any derivative work contains //////// the original copyright notice and the associated disclaimer. //////// //////// This source file is free software; you can redistribute it //////// and/or modify it under the terms of the GNU Lesser General //////// Public License as published by the Free Software Foundation; //////// either version 2.1 of the License, or (at your option) any //////// later version. //////// //////// This source is distributed in the hope that it will be //////// useful, but WITHOUT ANY WARRANTY; without even the implied //////// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR //////// PURPOSE. See the GNU Lesser General Public License for more //////// details. //////// //////// You should have received a copy of the GNU Lesser General //////// Public License along with this source; if not, download it //////// from http://www.opencores.org/lgpl.shtml //////// //////////////////////////////////////////////////////////////////////////package axi4_memory_pkg;// --------------------------------------------------------------------//import axi4_models_pkg::*;import bfm_pkg::*;import logger_pkg::*;// --------------------------------------------------------------------//class memory_tr_class #(A, N, I, type WORD_T = byte)extends transaction_class #(memory_tr_class #(A, N, I));rand int addr;rand int size;rand byte data[];constraint default_addr{addr[$clog2(N*8)-1:0] == 0;}constraint default_size{size dist {N := 40, [N*2:N*15] := 40, [N*16:N*255] := 20};}//--------------------------------------------------------------------//function void init(int addr, int size);this.data = new[size];this.addr = addr;this.size = size;endfunction: init//--------------------------------------------------------------------//function void random(int addr, int size);this.data = new[size];assert(this.randomize() with{this.addr == addr; // why not working?this.size == size;});this.addr = addr;this.size = size;endfunction: random// --------------------------------------------------------------------//task constant(int addr, int size, byte value[]);init(addr, size);this.data = new[size];for(int i = 0; i < size; i += value.size)foreach(value[k])data[i + k] = value[k];endtask: constant// --------------------------------------------------------------------//task automatic counting(int addr, int count);byte word[];int word_size = $bits(WORD_T) / 8; // word size in bytesinit(addr, count * word_size);for(WORD_T i = 0; i < count; i++)beginword = {<< byte{i}};foreach(word[k])data[addr + (i * word_size) + k] = word[k];endendtask: counting// --------------------------------------------------------------------//function void copy(TR_T from);init(from.addr, from.size);this.data = new[from.size];foreach(from.data[i])this.data[i] = from.data[i];endfunction: copy//--------------------------------------------------------------------function new;a_word_t_mod_n: assert($bits(WORD_T) % 8 == 0) else $fatal;endfunction: new// --------------------------------------------------------------------//endclass: memory_tr_class// --------------------------------------------------------------------//class axi4_memory_class #(A, N, I, type WORD_T = byte)extends axi4_slave_model_class #(.A(A), .N(N), .I(I));logger_class log;byte memory [*];// --------------------------------------------------------------------//function void clear_all;memory.delete;endfunction: clear_all// --------------------------------------------------------------------//function void compare(memory_tr_class #(A, N, I, WORD_T) tr_h);foreach(tr_h.data[i])if(memory.exists(tr_h.addr + i))beginif(memory[tr_h.addr + i] != tr_h.data[i])log.error($sformatf("%m | 1 memory[0x%8.h] = 0x%2.h | 0x%2.h", tr_h.addr + i, memory[tr_h.addr + i], tr_h.data[i]));endelselog.error($sformatf("%m | 2 memory[0x%8.h] = 0x%2.h | 0x%2.h", tr_h.addr + i, 'bx, tr_h.data[i]));endfunction: compare// --------------------------------------------------------------------//task display_memory(int offset, int count);for(int i = 0; i < count; i++)if(memory.exists(offset + i))$display("^^^ %16.t | %m | memory[0x%8.x] = 0x%2.x", $time, offset + i, memory[offset + i]);else$display("^^^ %16.t | %m | memory[0x%8.x] = 0x%2.x", $time, offset + i, 8'hxx);endtask: display_memory// --------------------------------------------------------------------//task constant_fill(int offset, int count, int value);for(int i = 0; i < count; i++)memory[offset + i] = value;endtask: constant_fill// --------------------------------------------------------------------//task counting_fill(int offset, int count);for(int i = 0; i < count; i++)memory[offset + i] = i;endtask: counting_fill// --------------------------------------------------------------------//task dump_words(int offset, ref byte data[]);foreach(data[i])if(memory.exists(offset + i))data[i] = memory[offset + i];elsedata[i] = 'bx;endtask: dump_words// --------------------------------------------------------------------//function reg [7:0] dump(int offset);if(memory.exists(offset))return(memory[offset]);elsereturn('bx);endfunction: dump// --------------------------------------------------------------------//task load_words(int offset, byte data[]);foreach(data[i])memory[offset + i] = data[i];endtask: load_words// --------------------------------------------------------------------//task load(int offset, reg [7:0] data);memory[offset] = data;endtask: load// --------------------------------------------------------------------//task run_read_interface;int result;logic [9:0] delay = 0;int memory_addr;forever@(axi4_s.cb_s)beginresult = ar_q_h.q.try_peek(ar_if_h);if(result != 0)beginlog.debug($sformatf("araddr = 0x%h", ar_if_h.araddr));log.debug($sformatf("arlen = 0x%h", ar_if_h.arlen));delay = $urandom_range(9, 0);if(delay > 6)repeat($urandom_range(50, 1))@(axi4_s.cb_s);for(int i = 0; i < ar_if_h.arlen + 1; i++)beginmemory_addr = ar_if_h.araddr + (i * (2 ** ar_if_h.arsize));for(int i = 0; i < ar_if_h.N; i++)beginif(memory.exists(memory_addr))r_if_h.rdata[i*8 +: 8] = memory[memory_addr];elser_if_h.rdata[i*8 +: 8] = 8'hxx;memory_addr++;endlog.debug($sformatf("rdata = 0x%h", r_if_h.rdata));if(i == ar_if_h.arlen)beginar_q_h.q.get(ar_if_h);r_if_h.rlast = 1;endelser_if_h.rlast = 0;r_if_h.rid = 0;r_if_h.rresp = 0;r_q_h.q.put(r_if_h);r_if_h = new(axi4_s);@(axi4_s.cb_s);endr_if_h.rlast = 0;endendendtask: run_read_interface// --------------------------------------------------------------------//task run_write_interface;int result;logic [9:0] delay = 0;int memory_addr;forever@(axi4_s.cb_s)beginresult = aw_q_h.q.try_peek(aw_if_h);if(result != 0)beginmemory_addr = aw_if_h.awaddr;log.debug($sformatf("awaddr = 0x%h", aw_if_h.awaddr));delay = $urandom_range(9, 0);if(delay > 6)repeat($urandom_range(8, 1))@(axi4_s.cb_s);for(int i = 0; i < aw_if_h.awlen + 1; i++)beginw_q_h.q.get(w_if_h);log.debug($sformatf("wdata = 0x%h", w_if_h.wdata));for(int k = 0; k < aw_if_h.N; k++)beginmemory[memory_addr] = w_if_h.wdata[k*8 +: 8];memory_addr++;endif(i == aw_if_h.awlen)beginb_if_h.bresp = 0;b_if_h.bid = aw_if_h.awid;b_q_h.q.put(b_if_h);b_if_h = new(axi4_s);aw_q_h.q.get(aw_if_h);end@(axi4_s.cb_s);endendendendtask: run_write_interface// --------------------------------------------------------------------//task run_model;wait(axi4_s.cb_s.aresetn);axi4_s.zero_cycle_delay();aw_q_h.run_q();w_q_h.run_q();b_q_h.run_q();ar_q_h.run_q();r_q_h.run_q();forkrun_write_interface();join_noneforkrun_read_interface();join_noneendtask: run_model//--------------------------------------------------------------------function new(virtual axi4_if #(.A(A), .N(N), .I(I)) axi4_s);super.new(axi4_s);a_word_t_mod_n: assert($bits(WORD_T) % 8 == 0) else $fatal;this.aw_q_h = new(axi4_s, 2);this.w_q_h = new(axi4_s, 16);this.b_q_h = new(axi4_s, 2);this.ar_q_h = new(axi4_s, 2);this.r_q_h = new(axi4_s, 16);this.log = new();endfunction: new// --------------------------------------------------------------------//endclass: axi4_memory_class// --------------------------------------------------------------------//endpackage: axi4_memory_pkg
