_data = tr.data_packet[wr_num];
93 wr_num++;
94 end
95 else begin
96 wr_en = 0;
97 wr_data = tr.data_packet[wr_num];
98 end
99 #(CYC*1);
100 end
101 wr_en = 0;
102 endtask
103
104 task Transcation::rd_oper;
105 uint32 rd_num;
106 $display("Read: %d",dp.len_r);
107 @(posedge clk);
108 #1;
109 #(dp.interval*CYC);
110 while(rd_num < dp.len_r)begin
111 if(~rd_empty)begin
112 rd_en = 1;
113 rd_num++;
114 end
115 else
116 rd_en = 0;
117 #(CYC*1);
118 end
119 rd_en = 0;
120 endtask
121
122 task Transcation::wr_rd_operation;
123 tr.data_packet = new[dp.len_w];
124 $display("len_w = %d, len_r = %d, inverval = %d",dp.len_w,dp.len_r,dp.interval);
125 foreach(tr.data_packet[i])begin
126 tr.data_packet[i] = i+1;
127 //$display(tr.data_packet[i]);
128 end
129 fork
130 wri_oper;
131 rd_oper;
132 join
133 endtask
134
135 function void Transcation::ref_gen(ref uint32 q_ref_data[$]);
136 integer j;
137 foreach(q_len[i])begin
138 for(j=0;j<q_len[i];j++)begin
139 q_ref_data = {q_ref_data,j+1};
140 end
141 end
142 endfunction
143
144 class Scoreboard;
145 uint32 total_num,error_num = 0;
146
147 function compare(ref uint32 q_data[$],ref uint32 q_ref[$]);
148 uint32 comp_num;
149 uint32 i;
150 uint32 data_len,ref_len;
151 status_e status;
152 data_len = $size(q_data);
153 ref_len = $size(q_ref);
154 $display("The lengths of q_data and q_ref are %d,%d",$size(q_data),$size(q_ref));
155 if(data_len >= ref_len)
156 comp_num = ref_len;
157 else
158 comp_num = data_len;
159 total_num = comp_num;
160 for(i=0;i<comp_num;i++)begin
161 if(q_data[i] != q_ref[i])begin
162 error_num++;
163 $display("The %dth data is different between the two!",i);
164 status = false;
165 return status;
166 end
167 end
168 status = true;
169 return status;
170 endfunction
171 endclass
172
173 //Descriptor dp;
174 Transcation tr;
175 Scoreboard sb;
176
177 //main
178 initial begin
179 //int status;
180 status_e status;
181 wr_en = 0;
182 rd_en = 0;
183 wr_data = 0;
184 #1;
185 #(2*CYC);
186 repeat(2)begin
187 tr = new();
188 tr.wr_rd_operation;
189 #(50*CYC);
190 end
191 #20;
192 tr.ref_gen(tr.q_ref_data);
193
194 //soreboard
195 sb = new();
196 status = sb.compare(tr.q_rd_data,tr.q_ref_data);
197 if(status == true)
198 $display("Simulation success!");
199 else
200 $display("Simulation filure!");
201 $stop;
202 end
203
204 //save readed data
205 initial begin
206 forever begin
207 @(posedge clk);
208 `ifdef FW
209 if(rd_en)
210 `else
211 if(rd_en_t)
212 `endif
213 tr.q_rd_data = {tr.q_rd_data,rd_data};
214 end
215 end
216
217 always@(posedge clk)begin
218 rd_en_t <= rd_en;
219 end
220
221 fifo_sync
222 #(.D_W(D_W),
223 .LOG_2_DEPTH(8),//256
224 .MODE(MODE)
225 )uut
226 (
227 .clk (clk),
228 .rst_n (rst_n),
229 .wr_en (wr_en),
230 .wr_data (wr_data),
231 .rd_en (rd_en),
232 .rd_data (rd_data),
233 .wr_full (wr_full),
234 .rd_empty (rd_empty)
235 );
236
237 endmodule:testbench
testbench.sv
四、VCS+Verdi工具使用
不得不说大多EDA工具确实没有IT行业的开发工具友好,用起来着实费了一番功夫。VCS这一仿真工具有自己的GUI debug tool,但功能不够强大。这里我们使用Verdi来debug。在上一节的SV代码中有一段fsdb的代码是专门产生Verdi波形文件的。因SV本身并没有这两个 |