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

Subversion Repositories ht_tunnel

[/] [ht_tunnel/] [tags/] [START/] [rtl/] [systemc/] [errorhandler_l2/] [errorhandler_l2.cpp] - Blame information for rev 19

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 acastong
//ht_errorHandler.cpp
2
 
3
/* ***** BEGIN LICENSE BLOCK *****
4
 * Version: MPL 1.1
5
 *
6
 * The contents of this file are subject to the Mozilla Public License Version
7
 * 1.1 (the "License"); you may not use this file except in compliance with
8
 * the License. You may obtain a copy of the License at
9
 * http://www.mozilla.org/MPL/
10
 *
11
 * Software distributed under the License is distributed on an "AS IS" basis,
12
 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
13
 * for the specific language governing rights and limitations under the
14
 * License.
15
 *
16
 * The Original Code is HyperTransport Tunnel IP Core.
17
 *
18
 * The Initial Developer of the Original Code is
19
 * Ecole Polytechnique de Montreal.
20
 * Portions created by the Initial Developer are Copyright (C) 2005
21
 * the Initial Developer. All Rights Reserved.
22
 *
23
 * Contributor(s):
24
 *   Martin Corriveau
25
 *   Ami Castonguay <acastong@grm.polymtl.ca>
26
 *
27
 * Alternatively, the contents of this file may be used under the terms
28
 * of the Polytechnique HyperTransport Tunnel IP Core Source Code License
29
 * (the  "PHTICSCL License", see the file PHTICSCL.txt), in which case the
30
 * provisions of PHTICSCL License are applicable instead of those
31
 * above. If you wish to allow use of your version of this file only
32
 * under the terms of the PHTICSCL License and not to allow others to use
33
 * your version of this file under the MPL, indicate your decision by
34
 * deleting the provisions above and replace them with the notice and
35
 * other provisions required by the PHTICSCL License. If you do not delete
36
 * the provisions above, a recipient may use your version of this file
37
 * under either the MPL or the PHTICSCL License."
38
 *
39
 * ***** END LICENSE BLOCK ***** */
40
 
41
#include "errorhandler_l2.h"
42
 
43
errorhandler_l2::errorhandler_l2( sc_module_name name) :sc_module(name)
44
{
45
        //This is combinatory to it's sensitive to all the variables read by the process
46
        SC_METHOD(stateMachine);
47
        sensitive << csr_end_of_chain << csr_initcomplete << csr_drop_uninit_link << csr_unit_id <<
48
                ro_available_fwd << ro_packet_fwd <<
49
                fc_ack_eh << inputRegister << eh_cmd_data_fc << eh_available_fc << dataLeftToSendm1 << state;
50
 
51
        //This represents registers, so it's only sensitive to clk and reset
52
        SC_METHOD(clockAndReset);
53
        sensitive_neg << resetx;
54
        sensitive_pos << clk;
55
 
56
}
57
 
58
 
59
void errorhandler_l2::clockAndReset(){
60
 
61
        if(resetx.read() == false){
62
                //We have no data to send
63
                dataLeftToSendm1 = 0;
64
                //Go back to idle state
65
                state = IdleState;
66
 
67
                eh_cmd_data_fc = 0;
68
                eh_available_fc = false;
69
 
70
                syn_ControlPacketComplete defaultPkt;
71
                initialize_syn_ControlPacketComplete(defaultPkt);
72
                inputRegister = defaultPkt;
73
        }
74
        else{
75
                eh_available_fc = next_outputReq;
76
                dataLeftToSendm1 = next_dataLeftToSendm1;
77
                state = next_state;
78
                eh_cmd_data_fc = next_outputData;
79
                inputRegister = next_inputRegister;
80
        }
81
}
82
 
83
bool errorhandler_l2::checkEOCError() const
84
{
85
        /**
86
                End of chain can happen for two reasons :
87
                   - csr_end_of_chain is asserted, either because we truly are
88
                     the last element of the chain or because it is set by
89
                         software
90
                   - The link is not initialized yet and csr_drop_uninit_link is
91
                     set.
92
        */
93
        if( csr_end_of_chain.read() == true ||
94
                ( csr_initcomplete.read() == false &&
95
                  csr_drop_uninit_link.read() == true ) )
96
        {
97
                return true;
98
        }
99
        return false;
100
}
101
 
102
 
103
 
104
#ifdef SYSTEMC_SIM
105
/// Trace external function
106
void
107
sc_trace(       sc_trace_file *tf, const errorhandler_l2& v,
108
                        const sc_string& NAME )
109
{
110
        sc_trace(tf,v.clk, NAME + ".clk");
111
        sc_trace(tf,v.ro_packet_fwd, NAME + ".ro_packet_fwd");
112
        sc_trace(tf,v.ro_available_fwd, NAME + ".ro_available_fwd");
113
        sc_trace(tf,v.eh_ack_ro, NAME + ".eh_ack_ro");
114
        sc_trace(tf,v.fc_ack_eh, NAME + ".fc_ack_eh");
115
        sc_trace(tf,v.eh_cmd_data_fc, NAME + ".eh_cmd_data_fc");
116
        sc_trace(tf,v.eh_available_fc, NAME + ".eh_available_fc");
117
        sc_trace(tf,v.eh_address_db, NAME + ".eh_address_db");
118
        sc_trace(tf,v.eh_erase_db, NAME + ".eh_erase_db");
119
        sc_trace(tf,v.eh_vctype_db, NAME + ".eh_vctype_db");
120
        sc_trace(tf,v.csr_end_of_chain, NAME + ".csr_end_of_chain");
121
        sc_trace(tf,v.csr_initcomplete, NAME + ".csr_initcomplete");
122
        sc_trace(tf,v.csr_drop_uninit_link, NAME + ".csr_drop_uninit_link");
123
        sc_trace(tf,v.resetx, NAME + ".resetx");
124
        sc_trace(tf,v.dataLeftToSendm1, NAME + ".dataLeftToSendm1");
125
 
126
}
127
#endif
128
 
129
void errorhandler_l2::stateMachine(){
130
 
131
        ///////////////////////////////////////////////
132
        // Default outputs
133
        ///////////////////////////////////////////////
134
        eh_ack_ro = false;
135
        next_dataLeftToSendm1 = 0;
136
        //All 1's because response packets for end of chain errors must only contain 1's
137
        next_outputData = "11111111111111111111111111111111";
138
        next_outputReq = false;
139
        next_state = IdleState;
140
        next_inputRegister = ro_packet_fwd.read();
141
        eh_address_db.write( 0 );
142
        eh_vctype_db.write( VC_NONE );
143
        eh_erase_db = false;
144
        //No need for this, reading the packet at the input is a signal that we
145
        //received a eoc packet, so no need for an extra signal.
146
        //eh_received_eoc_error_csr = false;
147
 
148
        //General variables that can be used in multiple states
149
        sc_bv<64> input_register_pkt = inputRegister.read().packet;
150
        PacketCommand input_register_cmd = getPacketCommand(input_register_pkt.range(5,0));
151
        VirtualChannel input_register_vc = getVirtualChannel(input_register_pkt,input_register_cmd);
152
        bool dataAssociated = hasDataAssociated(input_register_cmd);
153
 
154
        switch(state){
155
 
156
        ///////////////////////////////////////////////
157
        // IDLE STATE
158
        ///////////////////////////////////////////////
159
        case IdleState :
160
                /**If there is a packet and it is a an end of chain error
161
                   The same packets "signal" goes to both the flow control and
162
                   the error handler.  What dicates who consumes that packet
163
                   is if we are currently in a end of chain states
164
                */
165
                if((checkEOCError() || ro_packet_fwd.read().error64BitExtension)
166
                                && ro_available_fwd == true){
167
                        next_state = AnalyzePacketStateOutputFree;
168
                        eh_ack_ro = true;
169
                }
170
                break;
171
 
172
 
173
        ///////////////////////////////////////////////
174
        // AnalyzePacketStateOutputLoaded STATE
175
        ///////////////////////////////////////////////
176
        /** This state means that we have a new packet to analyze in the
177
                input buffer but that there is also data in the output buffer
178
                waiting to be sent
179
        */
180
        case AnalyzePacketStateOutputLoaded :
181
                next_outputReq = true;
182
                next_outputData = eh_cmd_data_fc.read();
183
                next_state = AnalyzePacketStateOutputLoaded;
184
 
185
                //This state does roughly he same thing as the next state, but can only
186
                //update the output buffers if the FC acks what in the output buffer
187
                //If there is no ack, we stop right here and wait for the ack.
188
                if(fc_ack_eh.read() == false) break;
189
 
190
        /** This state means that we have a new packet to analyze in the
191
                input buffer and that we can output data to the flow control
192
                immediately.
193
        */
194
        ///////////////////////////////////////////////
195
        // AnalyzePacketStateOutputFree STATE
196
        ///////////////////////////////////////////////
197
        case AnalyzePacketStateOutputFree :
198
 
199
                //When we reveice non posted packets, we generate a response with
200
                //the MASTER_ABORT bit on
201
                if(input_register_vc == VC_NON_POSTED ){
202
 
203
                        // Construct Response Packet and activate the sending process
204
                        bool passPW = getPassPW(input_register_pkt);
205
                        sc_uint<5> dataLengthm1 = getDataLengthm1(input_register_pkt);
206
                        //sc_uint<5> dataLength = dataLengthm1 + 1;
207
                        sc_bv<5> reqUID = getUnitID(input_register_pkt);
208
                        sc_bv<5> srcTag = request_getSrcTag(input_register_pkt);
209
 
210
                        switch( input_register_cmd ){
211
 
212
                        case READ:
213
                        case ATOMIC:
214
                                {
215
                                        /**
216
                                                In the case we received READ or ATOMIC request, we must
217
                                                reply with a response that has the right amount of data
218
                                                requested.
219
                                        */
220
                                        sc_bv<32> readResponse = generateReadResponse( csr_unit_id.read(),
221
                                                srcTag,
222
                                                reqUID.range(1,0),
223
                                                dataLengthm1,
224
                                                false,
225
                                                RE_MASTER_ABORT,
226
                                                passPW,
227
                                                false);
228
 
229
                                        next_outputData = readResponse;
230
                                        next_outputReq = true;
231
                                        next_dataLeftToSendm1 = dataLengthm1;
232
                                        next_state = SendingDataStateInputFree;
233
                                }
234
                                break;
235
                        //case WRITE:
236
                        default:
237
                                {
238
                                        /**
239
                                                In the case of a WRITE, we simply respond with a
240
                                                TargetDone
241
                                        */
242
                                        next_outputData = generateTargetDone( csr_unit_id.read(),
243
                                                srcTag,
244
                                                reqUID.range(1,0),
245
                                                false,
246
                                                RE_MASTER_ABORT,
247
                                                passPW,
248
                                                false);
249
                                        next_outputReq = true;
250
                                        next_state = InputFreeOutputLoaded;
251
                                }
252
                                break;
253
 
254
                        }
255
                }
256
                //In the case of POSTED and RESPONSE vc's, we can't response
257
                //We simply flag a bit in the CSR saying that we received an error.
258
                else if(input_register_cmd != BROADCAST){
259
                        //eh_received_eoc_error_csr = true;
260
                }
261
 
262
                /** If the received packet contained data, we drop it */
263
                if(dataAssociated){
264
                        eh_address_db.write( inputRegister.read().data_address );
265
                        eh_vctype_db.write( input_register_vc);
266
                        eh_erase_db = true;
267
                }
268
 
269
                break;
270
 
271
 
272
        ///////////////////////////////////////////////
273
        // SendingDataStateInputFree STATE
274
        ///////////////////////////////////////////////
275
        case SendingDataStateInputFree :
276
                next_outputReq = true;
277
 
278
                next_dataLeftToSendm1 = dataLeftToSendm1;
279
                next_state = SendingDataStateInputFree;
280
 
281
                //If there is a new packet at the input
282
                if((checkEOCError() || ro_packet_fwd.read().error64BitExtension)
283
                                && ro_available_fwd == true){
284
                        //If we only have one more data to send and the current data
285
                        //is being read, load the last data and analyze the new packet
286
                        if(dataLeftToSendm1.read() == 0 && fc_ack_eh.read() == true) {
287
                                next_state = AnalyzePacketStateOutputLoaded;
288
                        }
289
                        //If we only have one more data to send and the current data
290
                        //is not being read, we stay
291
                        else if(dataLeftToSendm1.read() == 0){
292
                                next_state = SendingDataStateInputLoaded;
293
                                next_outputData = eh_cmd_data_fc.read();
294
                        }
295
                        else {
296
                                next_state = SendingDataStateInputLoaded;
297
                                if(fc_ack_eh.read() == true){
298
                                        next_dataLeftToSendm1 = dataLeftToSendm1.read() - 1;
299
                                }
300
                                else{
301
                                        next_outputData = eh_cmd_data_fc.read();
302
                                }
303
                        }
304
                        eh_ack_ro = true;
305
                }
306
                else if(fc_ack_eh.read() == true){
307
                        if(dataLeftToSendm1.read() == 0){
308
                                next_state = InputFreeOutputLoaded;
309
                        }
310
                        else{
311
                                next_dataLeftToSendm1 = dataLeftToSendm1.read() - 1;
312
                        }
313
                }
314
                else{
315
                        next_outputData = eh_cmd_data_fc.read();
316
                }
317
 
318
                break;
319
 
320
        ///////////////////////////////////////////////
321
        // SendingDataStateInputLoaded STATE
322
        ///////////////////////////////////////////////
323
        case SendingDataStateInputLoaded :
324
                next_outputReq = true;
325
                next_dataLeftToSendm1 = dataLeftToSendm1;
326
                next_state = SendingDataStateInputLoaded;
327
                next_inputRegister = inputRegister;
328
 
329
                if(fc_ack_eh.read() == true){
330
                        if(dataLeftToSendm1.read() == 0) next_state = AnalyzePacketStateOutputLoaded;
331
                        else next_dataLeftToSendm1 = dataLeftToSendm1.read() - 1;
332
                }
333
                else{
334
                        next_outputData = eh_cmd_data_fc.read();
335
                }
336
                break;
337
 
338
        ///////////////////////////////////////////////
339
        // InputFreeOutputLoaded STATE
340
        ///////////////////////////////////////////////
341
        case InputFreeOutputLoaded :
342
                next_outputData = eh_cmd_data_fc.read();
343
                next_outputReq = true;
344
 
345
                if((checkEOCError() || ro_packet_fwd.read().error64BitExtension)
346
                                && ro_available_fwd == true){
347
                        if(fc_ack_eh.read() == true){
348
                                next_state = AnalyzePacketStateOutputFree;
349
                                next_outputReq = false;
350
                        }
351
                        else{
352
                                next_state = AnalyzePacketStateOutputLoaded;
353
                                next_outputData = eh_cmd_data_fc.read();
354
                        }
355
                }
356
                else if(fc_ack_eh.read() == true){
357
                        next_state = IdleState;
358
                        next_outputReq = false;
359
                }
360
                else{
361
                        next_state = InputFreeOutputLoaded;
362
                        next_outputData = eh_cmd_data_fc.read();
363
                }
364
                break;
365
 
366
        }
367
}
368
 
369
#ifndef SYSTEMC_SIM
370
#include "../core_synth/synth_control_packet.cpp"
371
#endif
372
 
373
 

powered by: WebSVN 2.1.0

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