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

Subversion Repositories ht_tunnel

[/] [ht_tunnel/] [tags/] [START/] [bench/] [flow_control_l2/] [history_buffer_l3_tb/] [history_buffer_l3_tb.cpp] - Blame information for rev 21

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 acastong
//history_buffer_l3_tb.cpp
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
#include "history_buffer_l3_tb.h"
40
#include "../../../rtl/systemc/flow_control_l2/history_buffer_l3.h"
41
#include <cstdlib>
42
#include <sstream>
43
 
44
using namespace std;
45
 
46
history_buffer_l3_tb::history_buffer_l3_tb(sc_module_name name) : sc_module(name){
47
        SC_THREAD(simulate_memory);
48
        sensitive_pos(clk);
49
 
50
        SC_THREAD(stimulus);
51
        sensitive_pos(clk);
52
 
53
        srand(8955);
54
        write_ack_number = 0;
55
        read_ack_number = 0;
56
        current_history_size = 0;
57
        internal_write_pos = 0;
58
}
59
 
60
void history_buffer_l3_tb::simulate_memory(){
61
        while(true){
62
                wait();
63
                if(history_memory_read_address.read() >= HISTORY_MEMORY_SIZE){
64
                        cout << "Error, read address outside valid range" << endl;
65
                        break;
66
                }
67
                history_memory_output = (sc_uint<32>)history_memory[history_memory_read_address.read()];
68
 
69
                if(history_memory_write.read()){
70
                        if(history_memory_write_address.read() >= HISTORY_MEMORY_SIZE){
71
                                cout << "Error, write address outside valid range" << endl;
72
                                break;
73
                        }
74
                        history_memory[history_memory_write_address.read()] =
75
                                (unsigned)(sc_uint<32>)history_memory_write_data.read();
76
                }
77
        }
78
}
79
 
80
/*
81
        sc_in <sc_bv<32> > history_packet;
82
        sc_in <bool > history_playback_done;
83
        sc_in <bool > room_available_in_history;
84
        sc_in <bool > history_playback_ready;
85
 
86
        sc_out <bool > consume_history;
87
        sc_out <bool > begin_history_playback;
88
        sc_out <bool > add_to_history;
89
        sc_out <bool > new_history_entry;
90
        sc_out <sc_uint<5> > new_history_entry_size_m1;
91
        sc_out<sc_bv<32> > fc_dword_lk;
92
        sc_out<bool>    nop_received;
93
        sc_out<sc_uint<8> >     ack_value;
94
 
95
        sc_out<bool>    resetx;
96
*/
97
 
98
void history_buffer_l3_tb::stimulus(){
99
        consume_history = false;
100
        begin_history_playback = false;
101
        add_to_history = false;
102
        new_history_entry = false;
103
        new_history_entry_size_m1 = 0;
104
        fc_dword_lk = 0;
105
        nop_received = false;
106
        write_ack_number = 0;
107
        read_ack_number = 0;
108
 
109
 
110
        ///////////////////////////////////
111
        // Test two short retry sequences
112
        ///////////////////////////////////
113
        resetx = false;
114
 
115
        for(int n = 0; n < 3; n++) wait();
116
        resetx = true;
117
 
118
        try{
119
                send_random_packets(4);
120
                ack_packets(2);
121
                send_random_packets(2);
122
                ack_packets(1);
123
                send_random_packets(2);
124
                ack_packets(3);
125
 
126
                playback_history();
127
 
128
                ack_packets(1);
129
                send_random_packets(4);
130
                ack_packets(3);
131
 
132
                ack_packets(1);
133
 
134
                while(internal_write_pos > 18){
135
                        send_random_packets(1);
136
                }
137
 
138
                playback_history();
139
 
140
                ///////////////////////////////////
141
                // Test room_available_in_history
142
                ///////////////////////////////////
143
 
144
                while((HISTORY_MEMORY_SIZE - current_history_size) > 18){
145
                        if(!room_available_in_history.read()){
146
                                cout << "HISTORY_MEMORY_SIZE: " << HISTORY_MEMORY_SIZE << endl;
147
                                cout << "current_history_size: " << current_history_size << endl;
148
                                throw SimulationException(
149
                                "room_available_in_history is false when it should be true");
150
                        }
151
                        send_random_packets(1);
152
 
153
                }
154
                if(room_available_in_history.read())
155
                        throw SimulationException(
156
                        "room_available_in_history is true when it should be false");
157
 
158
                cout << "SIMULATION COMPLETE" << endl;
159
        }
160
        catch(SimulationException se){
161
                cout << se.data << endl;
162
        }
163
}
164
 
165
void history_buffer_l3_tb::playback_history(){
166
 
167
        //Begin playback
168
        begin_history_playback = true;
169
        wait();
170
 
171
        //Wait for the history to be ready for playback
172
        int max_time = 32;
173
        while(!history_playback_ready.read()){
174
                if(max_time-- == 0){
175
                        throw SimulationException("Error, playback did not get ready");
176
                }
177
                wait();
178
        }
179
        begin_history_playback = false;
180
 
181
        //Read and check packets in history
182
        RetryEntry entry;
183
        for(std::deque<RetryEntry>::iterator i = simulated_history.begin();
184
                i != simulated_history.end();i++)
185
        {
186
                entry = *i;
187
                int pos = 0;
188
                while(pos != entry.size){
189
                        if(history_playback_done.read()){
190
                                throw SimulationException(
191
                                        "ERROR: History playback done signal asserted before really done");
192
                        }
193
                        if(consume_history.read()){
194
                                if(history_packet.read() != sc_uint<32>(entry.dwords[pos])){
195
                                        ostringstream o;
196
                                        o << "Error, invalid dword received: "
197
                                                << history_packet.read().to_string(SC_HEX)
198
                                                << " expected: " << sc_uint<32>(entry.dwords[pos]).to_string(SC_HEX);
199
                                        throw SimulationException(o.str());
200
                                }
201
                                pos++;
202
                        }
203
                        consume_history = ((rand() % 10) < 8) && (pos != entry.size);
204
                        wait();
205
                }
206
        }
207
 
208
        //Verify the playback done signal
209
        int max_count = 2;
210
        while(history_playback_done.read()){
211
                if(--max_count == 0){
212
                        throw SimulationException(
213
                                "ERROR: History playback done signal not asserted when actually done");
214
                }
215
                wait();
216
        }
217
 
218
 
219
}
220
 
221
void history_buffer_l3_tb::ack_packets(int number){
222
        read_ack_number = (read_ack_number + number) % 256;
223
        ack_value = read_ack_number;
224
        nop_received = true;
225
        wait();
226
        nop_received = false;
227
        for(int n = 0; n < number; n++){
228
                current_history_size -= simulated_history.front().size + 1;
229
                simulated_history.pop_front();
230
        }
231
}
232
 
233
 
234
void history_buffer_l3_tb::send_random_packets(int number){
235
        RetryEntry entry;
236
        for(int n = 0; n < number; n++){
237
                generateRandomEntry(&entry);
238
                simulated_history.push_back(entry);
239
                new_history_entry = true;
240
                new_history_entry_size_m1 = entry.size - 1;
241
                wait();
242
                new_history_entry = false;
243
 
244
                int dwords_sent = 0;
245
                while(dwords_sent < entry.size){
246
                        bool send = rand() % 10 < 8;
247
                        add_to_history = send;
248
                        if(send) fc_dword_lk = entry.dwords[dwords_sent++];
249
                        wait();
250
                }
251
                add_to_history = false;
252
                current_history_size += entry.size + 1;
253
                internal_write_pos = (internal_write_pos + entry.size + 1) % 128;
254
        }
255
}
256
 
257
 
258
/*
259
struct RetryEntry{
260
        int size;
261
        int identification;
262
        int     dwords[18];
263
}
264
 
265
*/
266
void history_buffer_l3_tb::generateRandomEntry(RetryEntry * e){
267
        e->size = (rand() % 18) + 1;
268
        e->identification = ++write_ack_number;
269
        for(int i = 0; i < e->size; i++){
270
                //Rand can have a MAX_VALUE as low as 32K on some compilers
271
                e->dwords[i] = rand() & 0xFFF |
272
                        ((rand() & 0xFFF) << 12) |
273
                        ((rand() & 0xFF) << 24);
274
        }
275
 
276
        //Clear the last to facilitate detecting errors
277
        for(int i = e->size; i < 18; i++){
278
                e->dwords[i] = 0;
279
        }
280
 
281
}

powered by: WebSVN 2.1.0

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