OpenCores
URL https://opencores.org/ocsvn/ht_tunnel/ht_tunnel/trunk

Subversion Repositories ht_tunnel

[/] [ht_tunnel/] [tags/] [START/] [bench/] [flow_control_l2/] [flow_control_l2_tb/] [flow_control_l2_tb.h] - Blame information for rev 19

Details | Compare with Previous | View Log

Line No. Rev Author Line
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
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.