AXI muckbucket
axi_seq.svh
Go to the documentation of this file.
1 //
3 // Copyright (C) 2017, Matt Dew @ Dew Technologies, LLC
4 //
5 // This program is free software (logic verification): you can redistribute it
6 // and/or modify it under the terms of the GNU Lesser General Public License (LGPL)
7 // as published by the Free Software Foundation, either version 3 of the License,
8 // or (at your option) any later version.
9 //
10 // This program is distributed in the hope that it will be useful, but WITHOUT
11 // ANY WARRANTY; without even the implied warranty of MERCHANTIBILITY or
12 // FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
13 // for more details.
14 //
15 // License: LGPL, v3, as defined and found on www.gnu.org,
16 // http://www.gnu.org/licenses/lgpl.html
17 //
18 //
19 // Author's intent: If you use this AXI verification code and find or fix bugs
20 // or make improvements, then share those fixes or improvements.
21 // If you use this in a bigger project, I don't care about,
22 // or want, any changes or code outside this block.
23 // Example: If you use this in an SoC simulation/testbench
24 // I don't want, or care about, your SoC or other blocks.
25 // I just care about the enhancements to these AXI files.
26 // That's why I have choosen the LGPL instead of the GPL.
28 
33 class axi_seq : public uvm_sequence <axi_seq_item> { public:
34 
36 
37 // const int axi_readback = 1;
38  const int clearmemory = 0;
39  const int window_size = 0x1_0000;
40  int xfers_to_send = 1;
41 
42  bit valid [];
43 
44  bit <2:0> max_burst_size;
45 
46  int xfers_done=0;
47 
49 
50  new (string name="axi_seq");
51  task body();
52 
53  void set_transaction_count(int count);
54  bit compare_items (ref axi_seq_item write_item, ref axi_seq_item read_item);
55 
56 };
57 
62  axi_seq::new (string name="axi_seq") {
63 
64  int dwidth;
65  super.new(name);
66 
67 
68  // Getting width is done here in the constructor because
69  // it is used in randomize(), which is done before body() is called
70 
71  uvm_info(this.get_type_name(),
72  "Looking for AXI_DATA_WIDTH in uvm_config_db",
73  UVM_MEDIUM)
74 
75  if (!uvm_config_db <int> ::get(null, "", "AXI_DATA_WIDTH", dwidth)) {
76  uvm_fatal(this.get_type_name(),
77  "Unable to fetch AXI_DATA_WIDTH from config db.")
78  }
79 
80  max_burst_size=$clog2(dwidth/8);
81 
82 }
83 
84 
93 
94  uvm_info(this.get_type_name(),
95  $sformatf("set_transaction_count(%0d)",count),
96  UVM_INFO)
97 
98 
99  xfers_to_send = count;
100 }
101 
103 }
104 
105 
115  bit axi_seq::compare_items (ref axi_seq_item write_item, ref axi_seq_item read_item) {
116 
117  bit <2:0> max_burst_size;
118  int yy;
119  bit <7:0> localbuffer [];
120  bit <7:0> read_data;
121  bit <7:0> expected_data;
122  int idatacntr;
123  int miscompare_cntr;
124  string write_item_s;
125  string read_item_s;
126  string expected_data_s;
127  string msg_s;
128  string localbuffer_s;
129  int rollover_cnt;
130 
131  bit <7:0> expected_data_array [];
132 
133 
134  if (write_item.burst_type==e_FIXED) {
135 
136  idatacntr=2**write_item.burst_size;
137 
138  // compare every nth byte with the same offset byte in last beat.
139  // should look like only the last beat got sent repeatedly
140  // construct the expected array,, then compare against actual.
141  // if miscompare, print original, readback and (calculated) expected.
142 
143  miscompare_cntr=0;
144  expected_data_array=new[read_item.data.size()];
145 
146  // brute force, not elegant at all.
147  // write to local buffer, then compare that buffer (repeated) with the axi readback
148 
149 
150  yy=0;
151  localbuffer=new[2**write_item.burst_size];
152  for (int y=0;y <localbuffer.size();y++) {
153  localbuffer[y]=0x0;
154  }
155  for (int y=0;y <write_item.len;y++) {
156  localbuffer[yy++]=write_item.data[y];
157  if (yy >= 2**write_item.burst_size) {
158  yy=0;
159  }
160  }
161 
162  yy=0;
163  for (int y=0; y <expected_data_array.size(); y++) {
164  expected_data_array[y]=localbuffer[yy++];
165  if (yy >= localbuffer.size()) {
166  yy=0;
167  }
168  }
169 
170  for (int y=0;y <read_item.data.size();y++) {
171  expected_data = expected_data_array[y];
172  read_data = read_item.data[y];
173  if (expected_data!=read_data) {
174  miscompare_cntr++;
175  }
176  }
177 
178  assert (miscompare_cntr==0) else {
179  write_item_s="";
180  read_item_s="";
181  expected_data_s="";
182  localbuffer_s="";
183 
184  for (int z=0;z <write_item.data.size();z++) {
185  $sformat(write_item_s, "%s 0x%2x", write_item_s, write_item.data[z]);
186  }
187 
188  for (int z=0;z <read_item.data.size();z++) {
189  $sformat(read_item_s, "%s 0x%2x", read_item_s, read_item.data[z]);
190  }
191 
192  for (int z=0;z <expected_data_array.size();z++) {
193  $sformat(expected_data_s, "%s 0x%2x", expected_data_s, expected_data_array[z]);
194  }
195 
196  for (int z=0;z <localbuffer.size();z++) {
197  $sformat(localbuffer_s, "%s 0x%2x", localbuffer_s, localbuffer[z]);
198  }
199 
200 
201  uvm_error("AXI READBACK e_FIXED miscompare",
202  $sformatf("%0d miscompares between expected and actual data items. \nExpected: %s \n Actual: %s; \nWritten: %s \nLocalbuffer: %s", miscompare_cntr, expected_data_s, read_item_s, write_item_s, localbuffer_s ));
203  }
204 
206 
207  } else if (write_item.burst_type==e_INCR || write_item.burst_type==e_WRAP) {
208  for (int z=0;z <write_item.len;z++) {
209  read_data=read_item.data[z];
210  expected_data=write_item.data[z];
211  assert(expected_data==read_data) else {
212  miscompare_cntr++;
213  uvm_error("AXI READBACK e_INCR miscompare",
214  $sformatf("expected: 0x%0x actual:0x%0x",
215  expected_data,
216  read_data))
217  }
218  }
219  } else {
220  miscompare_cntr++;
221  uvm_error(this.get_type_name(),
222  $sformatf("Unsupported burst type %0d", write_item.burst_type))
223 
224  }
225 
226 return (miscompare_cntr == 0);
227 }
void set_transaction_count(int count)
How many transactions?
Definition: axi_seq.svh:92
int xfers_to_send
Definition: axi_seq.svh:40
int xfers_done
Definition: axi_seq.svh:46
Extremely simple memory model with just write() and read() methods.
Definition: memory.svh:32
bit< 2:0 > max_burst_size
Definition: axi_seq.svh:44
const int window_size
Definition: axi_seq.svh:39
memory m_memory
Definition: axi_seq.svh:48
task body()
Definition: axi_seq.svh:102
bit valid[]
Definition: axi_seq.svh:42
new(string name="axi_seq")
Constructor.
Definition: axi_seq.svh:62
uvm_object_utils(axi_seq) const int clearmemory=0
Writes to memory over AXI, backdoor readback, then AXI readback.
Definition: axi_seq.svh:33
bit compare_items(ref axi_seq_item write_item, ref axi_seq_item read_item)
Compares the write-item with the corresponding read_item.
Definition: axi_seq.svh:115
contains all data and functions related to axi and usage