32 class memory :
public uvm_component {
public:
33 uvm_component_utils(
memory)
39 new(
string name=
"memory", uvm_component parent=null);
40 virtual void write(input bit <ADDR_WIDTH-1:0> addr, input bit <7:0> data);
41 virtual bit <7:0>
read (input bit <ADDR_WIDTH-1:0> addr);
43 input bit <ADDR_WIDTH-1:0> lower_addr,
44 input bit <ADDR_WIDTH-1:0> upper_addr);
51 memory::new(
string name=
"memory", uvm_component parent=null) {
52 super.
new(name, parent);
58 automatic
void memory::write(input bit <ADDR_WIDTH-1:0> addr, input bit <7:0> data) {
59 uvm_info(this.get_type_name(), $sformatf(
"write mem(0x%0x)=0x%0x", addr, data), UVM_HIGH)
67 automatic bit <7:0>
memory::read(input bit <ADDR_WIDTH-1:0> addr) {
68 if (mem.exists(addr)) {
69 uvm_info(this.get_type_name(), $sformatf(
"read mem(0x%0x)=0x%0x", addr, mem[addr]), UVM_HIGH)
73 uvm_info(this.get_type_name(),
74 $sformatf(
"read unwritten memory address [0x%0x]", addr),
87 input bit <ADDR_WIDTH-1:0> lower_addr,
88 input bit <ADDR_WIDTH-1:0> upper_addr) {
91 const int postcheck = 1;
92 const int precheck = 1;
117 string expected_data_s;
118 string actual_data_s;
120 string localbuffer_s;
123 bit <7:0> expected_data_array [];
124 bit <7:0> actual_data_array [];
126 bit <2:0> max_burst_size;
128 bit <7:0> localbuffer [];
130 bit <7:0> expected_data;
133 assert (item != null);
136 uvm_fatal(this.get_type_name(),
"Item is null")
143 uvm_info(
"...",
"Now reading back from memory to verify", UVM_LOW)
146 if (item.burst_type ==
e_WRAP) {
150 .burst_size(item.burst_size),
151 .burst_length(item.len)) + 1;
153 dtsize = (2**item.burst_size) * max_beat_cnt;
155 Lower_Wrap_Boundary = (int(item.addr/dtsize) * dtsize);
156 Upper_Wrap_Boundary = Lower_Wrap_Boundary + dtsize;
158 pre_check_start_addr = lower_addr;
159 pre_check_stop_addr = Lower_Wrap_Boundary;
161 check_start_addr = Lower_Wrap_Boundary;
162 check_stop_addr = Upper_Wrap_Boundary;
164 post_check_start_addr = Upper_Wrap_Boundary;
165 post_check_stop_addr = upper_addr;
168 pre_check_start_addr = lower_addr;
169 pre_check_stop_addr = item.addr;
171 check_start_addr = item.addr;
172 check_stop_addr = item.addr+item.len;
174 post_check_start_addr = item.addr+item.len;
175 post_check_stop_addr = upper_addr;
179 $sformat(msg_s,
"%s Item: %s", msg_s, item.convert2string());
180 $sformat(msg_s,
"%s pre_check_start_addr: 0x%0x", msg_s, pre_check_start_addr);
181 $sformat(msg_s,
"%s pre_check_stop_addr: 0x%0x", msg_s, pre_check_stop_addr);
182 $sformat(msg_s,
"%s check_start_addr: 0x%0x", msg_s, check_start_addr);
183 $sformat(msg_s,
"%s check_stop_addr: 0x%0x", msg_s, check_stop_addr);
184 $sformat(msg_s,
"%s post_check_start_addr: 0x%0x", msg_s, post_check_start_addr);
185 $sformat(msg_s,
"%s post_check_stop_addr: 0x%0x", msg_s, post_check_stop_addr);
186 $sformat(msg_s,
"%s Lower_Wrap_Boundary: 0x%0x", msg_s, Lower_Wrap_Boundary);
187 $sformat(msg_s,
"%s Upper_Wrap_Boundary: 0x%0x", msg_s, Upper_Wrap_Boundary);
190 uvm_info(
"CHECK MEMORY",
201 for (
int i=pre_check_start_addr;i <pre_check_stop_addr;i++) {
203 assert(expected_data==read_data)
else {
205 uvm_error(
"MEMORY PRE-CHECK miscompare",
206 $sformatf(
"Address: 0x%0x expected: 0x%0x actual:0x%0x",
215 if (item.burst_type ==
e_FIXED) {
217 expected_data_array =
new[2**item.burst_size];
218 actual_data_array =
new[2**item.burst_size];
219 localbuffer =
new[2**item.burst_size];
226 for (
int y=0;y <localbuffer.size();y++) {
229 for (
int y=0;y <item.len;y++) {
230 localbuffer[yy++]=item.data[y];
231 if (yy >= 2**item.burst_size) {
237 for (
int y=0; y <expected_data_array.size(); y++) {
238 expected_data_array[y]=localbuffer[yy++];
239 if (yy >= localbuffer.size()) {
255 for (
int y=0;y <localbuffer.size();y++) {
256 expected_data = expected_data_array[y];
257 read_data =
read(item.addr+y);
258 actual_data_array[y] = read_data;
259 if (expected_data!=read_data) {
264 assert (miscompare_cntr==0)
else {
271 for (
int z=0;z <item.data.size();z++) {
272 $sformat(write_item_s,
"%s 0x%2x", write_item_s, item.data[z]);
276 for (
int z=0;z <expected_data_array.size();z++) {
277 $sformat(expected_data_s,
"%s 0x%2x", expected_data_s, expected_data_array[z]);
280 for (
int z=0;z <actual_data_array.size();z++) {
281 $sformat(actual_data_s,
"%s 0x%2x", actual_data_s, actual_data_array[z]);
284 for (
int z=0;z <localbuffer.size();z++) {
285 $sformat(localbuffer_s,
"%s 0x%2x", localbuffer_s, localbuffer[z]);
289 $sformat(msg_s,
"%s %0d miscompares between expected and actual data items.", msg_s, miscompare_cntr );
290 $sformat(msg_s,
"%s \nExpected: %s", msg_s, expected_data_s);
291 $sformat(msg_s,
"%s \nActual: %s", msg_s, actual_data_s);
292 $sformat(msg_s,
"%s \nWritten: %s", msg_s, write_item_s);
293 $sformat(msg_s,
"%s \nLocalbuffer: %s", msg_s, localbuffer_s);
295 uvm_error(
"READBACK e_FIXED miscompare", msg_s);
301 }
else if (item.burst_type ==
e_INCR) {
302 for (
int z=0;z <item.len;z++) {
303 expected_data=item.data[z];
304 read_data=
read(item.addr+z);
306 assert(expected_data==read_data)
else {
308 uvm_error(
"e_INCR miscompare",
309 $sformatf(
"addr:0x%0x expected: 0x%0x actual:0x%0x",
315 }
else if (item.burst_type ==
e_WRAP) {
317 if (item.addr + item.len < Upper_Wrap_Boundary) {
319 for (
int z=Lower_Wrap_Boundary;z <item.addr;z++) {
321 assert(expected_data==read_data)
else {
323 uvm_fatal(
"e_WRAP miscompare",
324 $sformatf(
"expected: 0x%0x actual:0x%0x",
330 for (
int z=0;z <item.len;z++) {
331 expected_data=item.data[z];
332 read_data=
read(item.addr+z);
333 assert(expected_data==read_data)
else {
335 uvm_fatal(
"e_WRAP miscompare",
336 $sformatf(
"expected: 0x%0x actual:0x%0x",
343 for (
int z=item.addr+item.len;z <Upper_Wrap_Boundary;z++) {
345 assert(expected_data==read_data)
else {
347 uvm_fatal(
"e_WRAP miscompare",
348 $sformatf(
"expected: 0x%0x actual:0x%0x",
358 for (
int i=item.addr; i <Upper_Wrap_Boundary; i++) {
359 expected_data=item.data[i-item.addr];
361 assert(expected_data==read_data)
else {
363 uvm_error(
"e_WRAP miscompare",
364 $sformatf(
"expected: 0x%0x actual:0x%0x",
372 rollover_cnt=item.len-((item.addr+item.len)-Upper_Wrap_Boundary);
373 for (
int i=rollover_cnt;i <item.len;i++) {
374 expected_data=item.data[i];
375 read_data=
read(Lower_Wrap_Boundary+(i-rollover_cnt));
376 assert(expected_data==read_data)
else {
379 for (
int j=Lower_Wrap_Boundary;j <Upper_Wrap_Boundary;j++) {
380 $sformat(msg_s,
"%s 0x%2x", msg_s,
read(j));
382 uvm_fatal(
"e_WRAP miscompare",
383 $sformatf(
"Wrap Window contents: [0x%0x - 0x%0x]: %s expected: 0x%0x actual:[0x%0x]=0x%0x (rollover_cnt: 0x%0x)",
385 Upper_Wrap_Boundary-1,
388 Lower_Wrap_Boundary+(i-rollover_cnt),
403 uvm_fatal(this.get_type_name(), $sformatf(
"Invalid burst_type: %0d", item.burst_type))
410 for (
int i=post_check_start_addr;i <post_check_stop_addr;i++) {
412 assert(expected_data==read_data)
else {
414 uvm_error(
"MEMORY POST-CHECK miscompare",
415 $sformatf(
"expected: 0x%0x actual:0x%0x",
423 return (miscompare_cntr == 0);
bit< C_AXI_LEN_WIDTH-1:0 > calculate_axlen(input bit< C_AXI_ADDR_WIDTH-1:0 > addr, input bit< 2:0 > burst_size, input shortint burst_length)
calculate awlen or arlen
Extremely simple memory model with just write() and read() methods.
bit seq_item_check(ref axi_seq_item item, input bit< ADDR_WIDTH-1:0 > lower_addr, input bit< ADDR_WIDTH-1:0 > upper_addr)
Compares an axi_seq_item's data and burst_type against expected matching memory contents.
virtual void write(input bit< ADDR_WIDTH-1:0 > addr, input bit< 7:0 > data)
Writes into memory.
virtual bit< 7:0 > read(input bit< ADDR_WIDTH-1:0 > addr)
Reads from memory.
uvm_component_utils(memory) bit<7 new(string name="memory", uvm_component parent=null)
Constructor.
contains all data and functions related to axi and usage