1 |
2 |
acastong |
//flow_control_l2_tb.h
|
2 |
|
|
/* ***** BEGIN LICENSE BLOCK *****
|
3 |
|
|
* Version: MPL 1.1
|
4 |
|
|
*
|
5 |
|
|
* The contents of this file are subject to the Mozilla Public License Version
|
6 |
|
|
* 1.1 (the "License"); you may not use this file except in compliance with
|
7 |
|
|
* the License. You may obtain a copy of the License at
|
8 |
|
|
* http://www.mozilla.org/MPL/
|
9 |
|
|
*
|
10 |
|
|
* Software distributed under the License is distributed on an "AS IS" basis,
|
11 |
|
|
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
12 |
|
|
* for the specific language governing rights and limitations under the
|
13 |
|
|
* License.
|
14 |
|
|
*
|
15 |
|
|
* The Original Code is HyperTransport Tunnel IP Core.
|
16 |
|
|
*
|
17 |
|
|
* The Initial Developer of the Original Code is
|
18 |
|
|
* Ecole Polytechnique de Montreal.
|
19 |
|
|
* Portions created by the Initial Developer are Copyright (C) 2005
|
20 |
|
|
* the Initial Developer. All Rights Reserved.
|
21 |
|
|
*
|
22 |
|
|
* Contributor(s):
|
23 |
|
|
* Ami Castonguay <acastong@grm.polymtl.ca>
|
24 |
|
|
*
|
25 |
|
|
* Alternatively, the contents of this file may be used under the terms
|
26 |
|
|
* of the Polytechnique HyperTransport Tunnel IP Core Source Code License
|
27 |
|
|
* (the "PHTICSCL License", see the file PHTICSCL.txt), in which case the
|
28 |
|
|
* provisions of PHTICSCL License are applicable instead of those
|
29 |
|
|
* above. If you wish to allow use of your version of this file only
|
30 |
|
|
* under the terms of the PHTICSCL License and not to allow others to use
|
31 |
|
|
* your version of this file under the MPL, indicate your decision by
|
32 |
|
|
* deleting the provisions above and replace them with the notice and
|
33 |
|
|
* other provisions required by the PHTICSCL License. If you do not delete
|
34 |
|
|
* the provisions above, a recipient may use your version of this file
|
35 |
|
|
* under either the MPL or the PHTICSCL License."
|
36 |
|
|
*
|
37 |
|
|
* ***** END LICENSE BLOCK ***** */
|
38 |
|
|
|
39 |
|
|
#ifndef FLOW_CONTROL_L2_TB_H
|
40 |
|
|
#define FLOW_CONTROL_L2_TB_H
|
41 |
|
|
|
42 |
|
|
#include "../../../rtl/systemc/core_synth/synth_datatypes.h"
|
43 |
|
|
#include "../../../rtl/systemc/core_synth/constants.h"
|
44 |
|
|
#include <deque>
|
45 |
|
|
#include <string>
|
46 |
|
|
|
47 |
|
|
#define NOP_COUNTER_DELAY 20
|
48 |
|
|
|
49 |
|
|
///Testbench for the complete flow_control_l2 module
|
50 |
|
|
/** The flow_control_l2 module is BIG, so testing it is a HUGE job.
|
51 |
|
|
This testbench covers a couple of simple cases but in no way
|
52 |
|
|
covers all the functionality.
|
53 |
|
|
*/
|
54 |
|
|
class flow_control_l2_tb : public sc_module
|
55 |
|
|
{
|
56 |
|
|
public:
|
57 |
|
|
///Delay before nop frees buffers
|
58 |
|
|
/**
|
59 |
|
|
The testbench simulates the flow control credits, so when packets are received,
|
60 |
|
|
flow control credits are eventually freed and sent to the flow control module.
|
61 |
|
|
This is number of cycles of delay there is between the time packets are received
|
62 |
|
|
and the moment credit are freed
|
63 |
|
|
*/
|
64 |
|
|
static const int nop_counter_delay;
|
65 |
|
|
|
66 |
|
|
///Maximum number of data buffers there are in the simulated next node
|
67 |
|
|
static const unsigned next_node_databuffers_maximum[3];
|
68 |
|
|
|
69 |
|
|
///Maximum number of command buffers there are in the simulated next node
|
70 |
|
|
static const unsigned next_node_buffers_maximum[3];
|
71 |
|
|
|
72 |
|
|
|
73 |
|
|
///A structure that represents a packet of data
|
74 |
|
|
struct PacketData{
|
75 |
|
|
int size;///< Size (number of dwords), from 1 to 16
|
76 |
|
|
int dwords[16];///< actual data
|
77 |
|
|
sc_bv<64> associated_control_pkt;///< The command packet associated with this data
|
78 |
|
|
};
|
79 |
|
|
|
80 |
|
|
///A structure to identify an entry in the data buffers
|
81 |
|
|
struct DataBufferEntry{
|
82 |
|
|
sc_uint<BUFFERS_ADDRESS_WIDTH> address;///<Unique address of the entry
|
83 |
|
|
VirtualChannel vc;///<Virtual channel of the entry
|
84 |
|
|
int size;///< Size (number of dwords), from 1 to 16
|
85 |
|
|
int dwords[16];///< actual data
|
86 |
|
|
};
|
87 |
|
|
|
88 |
|
|
///From what source is the flow control currently sending a packet
|
89 |
|
|
enum FlowControlStatus{
|
90 |
|
|
FC_SENDING_CSR,
|
91 |
|
|
FC_SENDING_EH,
|
92 |
|
|
FC_SENDING_FWD,
|
93 |
|
|
FC_SENDING_UI,
|
94 |
|
|
FC_NONE
|
95 |
|
|
};
|
96 |
|
|
|
97 |
|
|
///An output value of the flow control module, contains 32 bits dword and CTL values
|
98 |
|
|
struct OutputDword{
|
99 |
|
|
sc_bv<32> dword;
|
100 |
|
|
bool lctl;
|
101 |
|
|
bool hctl;
|
102 |
|
|
};
|
103 |
|
|
|
104 |
|
|
///Flow control informatino contained in a nop packet
|
105 |
|
|
struct NopInfo{
|
106 |
|
|
sc_bv<12> nop_information;
|
107 |
|
|
sc_uint<8> nop_ack_value;
|
108 |
|
|
bool nop_received;
|
109 |
|
|
};
|
110 |
|
|
|
111 |
|
|
///Structure representing a history entry
|
112 |
|
|
struct HistoryEntry{
|
113 |
|
|
sc_bv<64> pkt;///<The command packet
|
114 |
|
|
sc_uint<8> nop_ack_value;///<Ack value of the entry (part of HT spec!)
|
115 |
|
|
unsigned data_size;///<Number of dwords of data
|
116 |
|
|
unsigned data[16];///<The actual data
|
117 |
|
|
unsigned crc;///Per packet CRC of the entry
|
118 |
|
|
};
|
119 |
|
|
|
120 |
|
|
///Exception that can be thrown
|
121 |
|
|
struct TestbenchError{
|
122 |
|
|
std::string message;
|
123 |
|
|
};
|
124 |
|
|
|
125 |
|
|
/// The Clock
|
126 |
|
|
sc_in<bool> clk;
|
127 |
|
|
/// Reset signal
|
128 |
|
|
sc_out<bool> resetx;
|
129 |
|
|
///LDTSTOP# signal
|
130 |
|
|
sc_out<bool> ldtstopx;
|
131 |
|
|
|
132 |
|
|
// USER_FIFO
|
133 |
|
|
///The packet the user interface wants to send
|
134 |
|
|
sc_out <sc_bv<64> > ui_packet_fc;
|
135 |
|
|
///If it there is a packet available to be sent
|
136 |
|
|
sc_out <bool> ui_available_fc;
|
137 |
|
|
///The VC's that can accept packets currently
|
138 |
|
|
sc_in <sc_bv<3> > fc_user_fifo_ge2_ui;
|
139 |
|
|
|
140 |
|
|
///The VC in which the flow control wants to read data from the UI data buffer
|
141 |
|
|
sc_in <VirtualChannel> fc_data_vc_ui;
|
142 |
|
|
///The data from the UI buffers
|
143 |
|
|
sc_out <sc_bv<32> > ui_data_fc;
|
144 |
|
|
///To consume the data from the UI buffers
|
145 |
|
|
sc_in <bool> fc_consume_data_ui;
|
146 |
|
|
|
147 |
|
|
// Forward -- FC
|
148 |
|
|
//If there is a packet to be sent from the reordering from the other side
|
149 |
|
|
sc_out <bool> ro_available_fwd;
|
150 |
|
|
///The packet to send
|
151 |
|
|
sc_out <syn_ControlPacketComplete > ro_packet_fwd;
|
152 |
|
|
///The VirtualChannel of the packet to send
|
153 |
|
|
sc_out <VirtualChannel > ro_packet_vc_fwd;
|
154 |
|
|
///To acknoledge that the packet has been consumed
|
155 |
|
|
sc_in <bool> fwd_ack_ro;
|
156 |
|
|
|
157 |
|
|
//LINK
|
158 |
|
|
///The dword to send to the other link
|
159 |
|
|
sc_in <sc_bv<32> > fc_dword_lk;
|
160 |
|
|
///The LCTL control signal to send along with the data
|
161 |
|
|
sc_in <bool> fc_lctl_lk;
|
162 |
|
|
///The HCTL control signal to send along with the data
|
163 |
|
|
sc_in <bool> fc_hctl_lk;
|
164 |
|
|
///The link consumes the data we are sending
|
165 |
|
|
sc_out <bool> lk_consume_fc;
|
166 |
|
|
#ifdef RETRY_MODE_ENABLED
|
167 |
|
|
///Force the link to disconnect
|
168 |
|
|
sc_in <bool> fc_disconnect_lk;
|
169 |
|
|
///This signal is active when the RX side of the link is connected
|
170 |
|
|
sc_out <bool> lk_rx_connected;
|
171 |
|
|
///If the link wants to initiate a retry disconnect
|
172 |
|
|
sc_out <bool> lk_initiate_retry_disconnect;
|
173 |
|
|
///If we are in the mode retry
|
174 |
|
|
sc_out <bool> csr_retry;
|
175 |
|
|
//Command decoder
|
176 |
|
|
/**Turns on when a disconnect sequence is initiated
|
177 |
|
|
All buffer counts are zeroed and we must replay all packets
|
178 |
|
|
that have not been acked*/
|
179 |
|
|
sc_out <bool> cd_initiate_retry_disconnect;
|
180 |
|
|
#endif
|
181 |
|
|
|
182 |
|
|
//DATA BUFFER
|
183 |
|
|
///The address where to read the data
|
184 |
|
|
sc_in <sc_uint<BUFFERS_ADDRESS_WIDTH> > fwd_address_db;
|
185 |
|
|
///The VC in which to read the data
|
186 |
|
|
sc_in <VirtualChannel> fwd_vctype_db;
|
187 |
|
|
///To read (consume) the data at the address specified
|
188 |
|
|
sc_in <bool> fwd_read_db;
|
189 |
|
|
///The data received from the data buffer
|
190 |
|
|
sc_out <sc_bv<32> > db_data_fwd;
|
191 |
|
|
|
192 |
|
|
|
193 |
|
|
///Buffer count information from RO and DB for sending nop's
|
194 |
|
|
///The buffers the ro can notify as being free to the HT node we are connected to
|
195 |
|
|
sc_out <sc_bv<6> > ro_buffer_cnt_fc;
|
196 |
|
|
///The buffers the ro can notify as being free to the HT node we are connected to
|
197 |
|
|
sc_out <sc_bv<6> > db_buffer_cnt_fc;
|
198 |
|
|
|
199 |
|
|
//Connexion Error handler FLOW control
|
200 |
|
|
///Acknoledge that the dword has been read
|
201 |
|
|
sc_in <bool> fc_ack_eh;
|
202 |
|
|
///The dword to send (command packet or data payload)
|
203 |
|
|
sc_out <sc_bv<32> > eh_cmd_data_fc;
|
204 |
|
|
///If there is a dword to send
|
205 |
|
|
sc_out <bool> eh_available_fc;
|
206 |
|
|
|
207 |
|
|
//Connexion CSR -- FLOW control
|
208 |
|
|
///Acknoledge that the dword has been read
|
209 |
|
|
sc_in <bool> fc_ack_csr;
|
210 |
|
|
///If there is a dword to send
|
211 |
|
|
sc_out <bool> csr_available_fc;
|
212 |
|
|
///The dword to send (command packet or data payload)
|
213 |
|
|
sc_out <sc_bv<32> > csr_dword_fc;
|
214 |
|
|
|
215 |
|
|
///If we are to turn the transmitter off
|
216 |
|
|
sc_out <bool> csr_transmitteroff;
|
217 |
|
|
|
218 |
|
|
///This bit forces a single stomp to be sent
|
219 |
|
|
sc_out<bool> csr_force_single_stomp_fc;
|
220 |
|
|
///This bit forces a single CRC error to be sent
|
221 |
|
|
sc_out<bool> csr_force_single_error_fc;
|
222 |
|
|
///Once a stomp is sent, we clear the signal to send the stomp
|
223 |
|
|
sc_in<bool> fc_clear_single_error_csr;
|
224 |
|
|
///Once a CRC error is sent, we clear the signal to send the error
|
225 |
|
|
sc_in<bool> fc_clear_single_stomp_csr;
|
226 |
|
|
|
227 |
|
|
|
228 |
|
|
|
229 |
|
|
//Connexion pour les NOP request
|
230 |
|
|
///Databuffer requests that a nop be sent.
|
231 |
|
|
sc_out <bool> db_nop_req_fc;
|
232 |
|
|
///Reordering requests that a nop be sent.
|
233 |
|
|
sc_out <bool> ro_nop_req_fc;
|
234 |
|
|
///A nop was just sent
|
235 |
|
|
sc_in <bool> fc_nop_sent;
|
236 |
|
|
|
237 |
|
|
// NOP info packet
|
238 |
|
|
///The buffer information received in a nop
|
239 |
|
|
sc_out<sc_bv<12> > cd_nopinfo_fc;
|
240 |
|
|
///If a nop was just received
|
241 |
|
|
sc_out<bool> cd_nop_received_fc;
|
242 |
|
|
|
243 |
|
|
///Let the reordering know which buffers are free in the next node
|
244 |
|
|
sc_in <sc_bv<6> > fwd_next_node_buffer_status_ro;
|
245 |
|
|
|
246 |
|
|
#ifdef RETRY_MODE_ENABLED
|
247 |
|
|
///The packet that is acked in the nop (for retry mode)
|
248 |
|
|
/**
|
249 |
|
|
When we receive this ack value, we can erase the packet associated with
|
250 |
|
|
that number (and all the previous ones) from our buffers.
|
251 |
|
|
*/
|
252 |
|
|
sc_out<sc_uint<8> > cd_nop_ack_value_fc;
|
253 |
|
|
|
254 |
|
|
///CD maitains a count of valid packet received, that count is then sent in nops
|
255 |
|
|
sc_out<sc_uint<8> > cd_rx_next_pkt_to_ack_fc;
|
256 |
|
|
|
257 |
|
|
//////////////////////////////////////////
|
258 |
|
|
// Memory interface - synchronous
|
259 |
|
|
/////////////////////////////////////////
|
260 |
|
|
sc_in<bool> history_memory_write;
|
261 |
|
|
sc_in<sc_uint<LOG2_HISTORY_MEMORY_SIZE> > history_memory_write_address;
|
262 |
|
|
sc_in<sc_bv<32> > history_memory_write_data;
|
263 |
|
|
sc_in<sc_uint<LOG2_HISTORY_MEMORY_SIZE> > history_memory_read_address;
|
264 |
|
|
sc_out<sc_bv<32> > history_memory_output;
|
265 |
|
|
|
266 |
|
|
///Actual content of the simulated memory
|
267 |
|
|
unsigned history_memory[HISTORY_MEMORY_SIZE];
|
268 |
|
|
#endif
|
269 |
|
|
|
270 |
|
|
///This containes packets sent to the user fifo
|
271 |
|
|
/** The TB does not strictly test that the user fifo extracts the correct
|
272 |
|
|
packet (the user_fifo testbench is there for that), but it does keep
|
273 |
|
|
track of all packet sent and extracted from the user_fifo to make sure
|
274 |
|
|
they are valid
|
275 |
|
|
*/
|
276 |
|
|
std::deque<sc_bv<64> > user_packets;
|
277 |
|
|
///Data associated with the user packets
|
278 |
|
|
/**This will be used to generate inputs to the flow_control when it wants
|
279 |
|
|
to access the data associated with the packets read from the user_fifo*/
|
280 |
|
|
std::deque<PacketData> user_data[3];
|
281 |
|
|
///VC of the data being read by the flow_control
|
282 |
|
|
VirtualChannel current_user_data_vc;
|
283 |
|
|
///VC of the data currently being received by the UI
|
284 |
|
|
/** UI takes a cycle to update it's output, so this variable keeps track of
|
285 |
|
|
what is currently on the ouput (what was requested last cycle)
|
286 |
|
|
*/
|
287 |
|
|
VirtualChannel current_user_data_vc_output;
|
288 |
|
|
///Packet that are expected to be outputed
|
289 |
|
|
/**Most packet are read from various sources, so once they are read, we
|
290 |
|
|
can expect what it is going to be outputed. This does not cover all
|
291 |
|
|
packets though : for example user packets are internal to the
|
292 |
|
|
flow_control_2 module so there is no way to predict that it will
|
293 |
|
|
be output, at least with black box testing.*/
|
294 |
|
|
std::deque<OutputDword> expected_output;
|
295 |
|
|
|
296 |
|
|
///History structure of the design
|
297 |
|
|
std::deque<HistoryEntry> history;
|
298 |
|
|
|
299 |
|
|
///Status of the design : what it is currently sending
|
300 |
|
|
FlowControlStatus fc_status;
|
301 |
|
|
|
302 |
|
|
///Data of the databuffer entry
|
303 |
|
|
/**
|
304 |
|
|
A real databuffer is not simulated. When a packet is sent from the
|
305 |
|
|
command buffers, the address is noted and stored and checking when
|
306 |
|
|
the flow control module tries to check the data. This variable
|
307 |
|
|
stores the data of the entry
|
308 |
|
|
*/
|
309 |
|
|
DataBufferEntry databuffer_data;
|
310 |
|
|
///Virtual channel of the databuffer entry currently being output
|
311 |
|
|
/** Databuffer has a latency of 1 cycle before data is correct on the output.
|
312 |
|
|
This variable store information about what is currently being output (what
|
313 |
|
|
was requested last cycle)*/
|
314 |
|
|
VirtualChannel databuffer_output_vc;
|
315 |
|
|
///Address of the databuffer entry currently being output
|
316 |
|
|
/** Databuffer has a latency of 1 cycle before data is correct on the output.
|
317 |
|
|
This variable store information about what is currently being output (what
|
318 |
|
|
was requested last cycle)*/
|
319 |
|
|
unsigned databuffer_output_addr;
|
320 |
|
|
|
321 |
|
|
///SystemC Macro
|
322 |
|
|
SC_HAS_PROCESS(flow_control_l2_tb);
|
323 |
|
|
|
324 |
|
|
///Module constructor
|
325 |
|
|
flow_control_l2_tb(sc_module_name name);
|
326 |
|
|
|
327 |
|
|
///Controls percentage of change of generating packet from different sources
|
328 |
|
|
/**
|
329 |
|
|
Will vary throughout different stages of the testbench
|
330 |
|
|
*/
|
331 |
|
|
//@{
|
332 |
|
|
int percent_chance_from_eh;
|
333 |
|
|
int percent_chance_from_csr;
|
334 |
|
|
int percent_chance_from_fwd;
|
335 |
|
|
int percent_chance_from_ui;
|
336 |
|
|
//@{
|
337 |
|
|
|
338 |
|
|
///Number of dwords of data left to send (or sent) from the different sources
|
339 |
|
|
//@{
|
340 |
|
|
unsigned data_left_eh;
|
341 |
|
|
unsigned data_left_csr;
|
342 |
|
|
unsigned data_sent_ui;
|
343 |
|
|
unsigned data_sent_db;
|
344 |
|
|
//@{
|
345 |
|
|
|
346 |
|
|
///Controls percentage of change of requesting nop packet to be sent
|
347 |
|
|
/**
|
348 |
|
|
Will vary throughout different stages of the testbench
|
349 |
|
|
*/
|
350 |
|
|
//@{
|
351 |
|
|
int percent_chance_nop_req_db;
|
352 |
|
|
int percent_chance_nop_req_ro;
|
353 |
|
|
//@{
|
354 |
|
|
|
355 |
|
|
///Controls percentage of change of requesting nop packet to received
|
356 |
|
|
/**
|
357 |
|
|
Will vary throughout different stages of the testbench
|
358 |
|
|
*/
|
359 |
|
|
int percent_chance_nop_received;
|
360 |
|
|
|
361 |
|
|
///Per packet CRC calcualted for packets with no data associated
|
362 |
|
|
unsigned crc1;
|
363 |
|
|
///Per packet CRC calcualted for packets with data associated
|
364 |
|
|
unsigned crc2;
|
365 |
|
|
|
366 |
|
|
//This is the number of buffers that are free (command and data)
|
367 |
|
|
unsigned next_node_buffers_free[3];
|
368 |
|
|
unsigned next_node_databuffers_free[3];
|
369 |
|
|
|
370 |
|
|
//This is the number of buffers that have been advertised as being free through
|
371 |
|
|
//nops as seen by the next node (does not take into account the nop delay)
|
372 |
|
|
unsigned next_node_buffers_advertised[3];
|
373 |
|
|
unsigned next_node_databuffers_advertised[3];
|
374 |
|
|
|
375 |
|
|
//This is the number of buffers that have been advertised as being free through
|
376 |
|
|
//nops as seen by the current node (takes into account the nop delay)
|
377 |
|
|
unsigned buffers_available[3];
|
378 |
|
|
unsigned databuffers_available[3];
|
379 |
|
|
|
380 |
|
|
/** verify_output() MUST run after produce_inputs,
|
381 |
|
|
so when produce_inputs is done, do a notification
|
382 |
|
|
*/
|
383 |
|
|
sc_event input_produced;
|
384 |
|
|
|
385 |
|
|
///Nop delay is done simply be shifting data inside an array
|
386 |
|
|
NopInfo nop_delay[NOP_COUNTER_DELAY];
|
387 |
|
|
|
388 |
|
|
///<Variable used to track the construction of the history structure
|
389 |
|
|
/** The history structure is build from reading the output of the
|
390 |
|
|
flow_control module. All these variables are used to build up
|
391 |
|
|
the current_history_entry which is then stored in the history\
|
392 |
|
|
structure
|
393 |
|
|
*/
|
394 |
|
|
HistoryEntry current_history_entry;
|
395 |
|
|
bool history_second_dword_next;
|
396 |
|
|
bool history_crc_next;
|
397 |
|
|
int history_data_count;
|
398 |
|
|
bool history_ignore_nop_crc;
|
399 |
|
|
int history_ack_value;
|
400 |
|
|
|
401 |
|
|
///The count of packet received (for the retry mode)
|
402 |
|
|
sc_uint<8> next_node_ack_value_pending;
|
403 |
|
|
sc_uint<8> next_node_ack_value;
|
404 |
|
|
|
405 |
|
|
///If the dword of the flow control should be ignored when calculating the ack valeu
|
406 |
|
|
/** For the history structure, every entry has an ack value. This value is updated
|
407 |
|
|
by observing the control packets sent from flow_control output. When the first
|
408 |
|
|
dword of a quad word packet is sent, ignore_next_dword_for_ack is set so that the
|
409 |
|
|
second dword is simply ignored.
|
410 |
|
|
*/
|
411 |
|
|
bool ignore_next_dword_for_ack;
|
412 |
|
|
|
413 |
|
|
///If we are in a retry sequence (set by start retry sequence)
|
414 |
|
|
bool retry_sequence;
|
415 |
|
|
///The simulated history structure
|
416 |
|
|
std::deque<HistoryEntry> retry_playback_history;
|
417 |
|
|
///Next dword will be second dword of command packet
|
418 |
|
|
bool retry_second_dword_next;
|
419 |
|
|
///CRC of entry is next
|
420 |
|
|
bool retry_crc_next;
|
421 |
|
|
///Nop can be inserted in stream, after a nop, we expect a Nop CRC
|
422 |
|
|
/**Nop crc will be contained in expected dword structure*/
|
423 |
|
|
bool retry_expect_nop_crc;
|
424 |
|
|
///The amount of data that has been received for an entry
|
425 |
|
|
int retry_data_count;
|
426 |
|
|
///Set after a command packet, if it has data associated to it (in retry sequence)
|
427 |
|
|
/**Cleared when all data is received*/
|
428 |
|
|
bool retry_receive_data;
|
429 |
|
|
|
430 |
|
|
///Link is disconnected for retry reasons
|
431 |
|
|
/** When the flow_control says to the link to disconnect, it takes some cycles
|
432 |
|
|
before the output is correct again (the link would take some cycles to
|
433 |
|
|
correctly reconnect. So when a retry sequence is started, retry_disconnect is
|
434 |
|
|
set until fc_disconnect_lk is false so that the flow_control output is ignored.
|
435 |
|
|
*/
|
436 |
|
|
bool retry_disconnect;
|
437 |
|
|
|
438 |
|
|
///Becomes true when an error is detected
|
439 |
|
|
bool error;
|
440 |
|
|
|
441 |
|
|
///Simulates the history memory as if it was a real memory
|
442 |
|
|
void simulate_memory();
|
443 |
|
|
|
444 |
|
|
///Set some variables that control global behavious of Testbench over time
|
445 |
|
|
/** It set the percentage of chance of all the */
|
446 |
|
|
void control_testbench();
|
447 |
|
|
///Produces random packets for all inputs of the flow_control
|
448 |
|
|
void produce_inputs();
|
449 |
|
|
///Verifies that the output of the design is correct
|
450 |
|
|
void verify_output();
|
451 |
|
|
///Generate a random response packet
|
452 |
|
|
/**
|
453 |
|
|
@param pkt The generated packet returned by address
|
454 |
|
|
@param data_size The generated packet data size returned by address
|
455 |
|
|
*/
|
456 |
|
|
void generate_random_response(sc_bv<32> &pkt, unsigned &data_size);
|
457 |
|
|
///Generate a random posted packet
|
458 |
|
|
/**
|
459 |
|
|
@param pkt The generated packet returned by address
|
460 |
|
|
@param data_size The generated packet data size returned by address
|
461 |
|
|
*/
|
462 |
|
|
void generate_random_posted(sc_bv<64> &pkt, unsigned &data_size);
|
463 |
|
|
///Generate a random non posted packet
|
464 |
|
|
/**
|
465 |
|
|
@param pkt The generated packet returned by address
|
466 |
|
|
@param data_size The generated packet data size returned by address
|
467 |
|
|
*/
|
468 |
|
|
void generate_random_nposted(sc_bv<64> &pkt, unsigned &data_size);
|
469 |
|
|
|
470 |
|
|
///Generate a random packet of any Virtual Channel
|
471 |
|
|
/**
|
472 |
|
|
@param pkt The generated packet returned by address
|
473 |
|
|
@param data_size The generated packet data size returned by address
|
474 |
|
|
*/
|
475 |
|
|
VirtualChannel generate_random_packet(sc_bv<64> &pkt, unsigned &data_size);
|
476 |
|
|
|
477 |
|
|
///Generate a random 32-bit vecgtor
|
478 |
|
|
/**
|
479 |
|
|
@param vector The random vector returned by address
|
480 |
|
|
*/
|
481 |
|
|
void getRandomVector(sc_bv<32> &vector);
|
482 |
|
|
|
483 |
|
|
///Generate a random 64-bit vecgtor
|
484 |
|
|
/**
|
485 |
|
|
@param vector The random vector returned by address
|
486 |
|
|
*/
|
487 |
|
|
void getRandomVector(sc_bv<64> &vector);
|
488 |
|
|
|
489 |
|
|
///Add data packet to the list of packet sent to FC from UI
|
490 |
|
|
/**
|
491 |
|
|
@param datalength The number of dwords of data
|
492 |
|
|
@param ui_vc The virtual channel of the packet
|
493 |
|
|
@param associated_control_packet The command packet associated to the data packet
|
494 |
|
|
*/
|
495 |
|
|
void add_ui_data_packet(unsigned datalength,
|
496 |
|
|
VirtualChannel ui_vc,
|
497 |
|
|
sc_bv<64> &associated_control_packet);
|
498 |
|
|
|
499 |
|
|
///Sets the databuffer_data variable
|
500 |
|
|
/**
|
501 |
|
|
@param datalength The number of dwords of data
|
502 |
|
|
@param ui_vc The virtual channel of the packet
|
503 |
|
|
@param associated_control_packet The command packet associated to the data packet
|
504 |
|
|
*/
|
505 |
|
|
void update_databuffer_entry(unsigned datalength,
|
506 |
|
|
VirtualChannel ui_vc,
|
507 |
|
|
sc_uint<4> &data_address);
|
508 |
|
|
|
509 |
|
|
///Update CRC1
|
510 |
|
|
/**
|
511 |
|
|
@param dword Dword to use to calculate the new value of CRC1
|
512 |
|
|
@param dword LCTL value to use to calculate the new value of CRC1
|
513 |
|
|
@param dword HCTL value to use to calculate the new value of CRC1
|
514 |
|
|
*/
|
515 |
|
|
void calculate_crc1(sc_bv<32> dword,bool lctl, bool hctl);
|
516 |
|
|
|
517 |
|
|
///Update CRC2
|
518 |
|
|
/**
|
519 |
|
|
@param dword Dword to use to calculate the new value of CRC2
|
520 |
|
|
@param dword LCTL value to use to calculate the new value of CRC2
|
521 |
|
|
@param dword HCTL value to use to calculate the new value of CRC2
|
522 |
|
|
*/
|
523 |
|
|
void calculate_crc2(sc_bv<32> dword,bool lctl, bool hctl);
|
524 |
|
|
|
525 |
|
|
///Updates a CRC with 34 bits of data
|
526 |
|
|
/**
|
527 |
|
|
@param crc The CRC to update (by address)
|
528 |
|
|
@param data The 34 bits to calculate the CRC on
|
529 |
|
|
*/
|
530 |
|
|
void calculate_crc(unsigned &crc,sc_bv<34> &data);
|
531 |
|
|
|
532 |
|
|
///Clears all next node buffer status
|
533 |
|
|
/** This clears all information about the number of free buffers and
|
534 |
|
|
the number of advertised buffers
|
535 |
|
|
*/
|
536 |
|
|
void clear_next_node_information();
|
537 |
|
|
|
538 |
|
|
///Adds the CRC of a data packet to the list of expected dwords
|
539 |
|
|
/**@param data The data packet with it's associated command packet
|
540 |
|
|
*/
|
541 |
|
|
void add_expected_crc_for_packet(PacketData &data);
|
542 |
|
|
|
543 |
|
|
///Takes care of everything necessary to verify when a retry sequence is start
|
544 |
|
|
/** Should be called when a disconnect nop is received in retry mode : it will
|
545 |
|
|
take care of expecting the CRC that will follow the NOP*/
|
546 |
|
|
void start_retry_sequence();
|
547 |
|
|
|
548 |
|
|
///Checks correctness of what is sent in retry sequence
|
549 |
|
|
/** Called by verify_output when in the retry sequence */
|
550 |
|
|
void manage_retry_sequence();
|
551 |
|
|
///Manages the history of packet sent
|
552 |
|
|
/** From the output of the flow_control , a history of packet sent is build so
|
553 |
|
|
that when a retry sequence occurs, what is resent by the flow control can
|
554 |
|
|
be compared to what is stored in that history*/
|
555 |
|
|
void manage_history();
|
556 |
|
|
|
557 |
|
|
///Frees random number of buffers in the next node
|
558 |
|
|
/** Flow control sends packets to the next node, which would fill buffers in a
|
559 |
|
|
real system. These real packets would eventually be read and the buffers
|
560 |
|
|
freed. So this method randomly frees buffers*/
|
561 |
|
|
void free_buffers();
|
562 |
|
|
///Updates the buffers count and ack number on the other side when packets are received
|
563 |
|
|
void manage_ack_buffer_count();
|
564 |
|
|
///Generates nops from the next node (acks history and frees buffers)
|
565 |
|
|
void send_next_node_nops();
|
566 |
|
|
|
567 |
|
|
};
|
568 |
|
|
|
569 |
|
|
///Function to allow to output the status to an outputstream
|
570 |
|
|
ostream &operator<<(ostream &out,const flow_control_l2_tb::FlowControlStatus fc_status);
|
571 |
|
|
|
572 |
|
|
#endif
|
573 |
|
|
|