1 |
2 |
acastong |
//flow_control_l2.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 |
|
|
* Jean-Francois Belanger
|
24 |
|
|
* Ami Castonguay <acastong@grm.polymtl.ca>
|
25 |
|
|
*
|
26 |
|
|
* Alternatively, the contents of this file may be used under the terms
|
27 |
|
|
* of the Polytechnique HyperTransport Tunnel IP Core Source Code License
|
28 |
|
|
* (the "PHTICSCL License", see the file PHTICSCL.txt), in which case the
|
29 |
|
|
* provisions of PHTICSCL License are applicable instead of those
|
30 |
|
|
* above. If you wish to allow use of your version of this file only
|
31 |
|
|
* under the terms of the PHTICSCL License and not to allow others to use
|
32 |
|
|
* your version of this file under the MPL, indicate your decision by
|
33 |
|
|
* deleting the provisions above and replace them with the notice and
|
34 |
|
|
* other provisions required by the PHTICSCL License. If you do not delete
|
35 |
|
|
* the provisions above, a recipient may use your version of this file
|
36 |
|
|
* under either the MPL or the PHTICSCL License."
|
37 |
|
|
*
|
38 |
|
|
* ***** END LICENSE BLOCK ***** */
|
39 |
|
|
|
40 |
|
|
#ifndef FLOW_CONTROL_L2_H
|
41 |
|
|
#define FLOW_CONTROL_L2_H
|
42 |
|
|
|
43 |
|
|
#include "../core_synth/synth_datatypes.h"
|
44 |
|
|
#include "../core_synth/constants.h"
|
45 |
|
|
|
46 |
|
|
//Forward declaration
|
47 |
|
|
class flow_control_l3;
|
48 |
|
|
class nop_framer_l3;
|
49 |
|
|
class multiplexer_l3;
|
50 |
|
|
class rx_farend_cnt_l3;
|
51 |
|
|
class user_fifo_l3;
|
52 |
|
|
class fairness_l3;
|
53 |
|
|
|
54 |
|
|
#ifdef RETRY_MODE_ENABLED
|
55 |
|
|
class history_buffer_l3;
|
56 |
|
|
class fc_packet_crc_l3;
|
57 |
|
|
#endif
|
58 |
|
|
|
59 |
|
|
/// Top module of the flow control
|
60 |
|
|
/**
|
61 |
|
|
The flow control is the module that frames the packets to be sent out.
|
62 |
|
|
In the HyperTransport tunnel, there are multiple sources of outgoing
|
63 |
|
|
packets. The flow control decides which packet must be sent.
|
64 |
|
|
|
65 |
|
|
It keeps track of the buffers available in the next HT node. It is
|
66 |
|
|
also responsible for sending nop flow control packets when the databuffer
|
67 |
|
|
or reordering requests it. It will also send nops when there si nothing else
|
68 |
|
|
to send.
|
69 |
|
|
|
70 |
|
|
The module is also called the forward module, because it is responsible for
|
71 |
|
|
sending packets that arrived from the other side of the tunnel but that
|
72 |
|
|
wasn't for this node.
|
73 |
|
|
|
74 |
|
|
In retry mode, the flow control keeps a history buffer of all the packets
|
75 |
|
|
sent until they are acked, so they can be replayed if there is a transmission
|
76 |
|
|
error. It also add the CRC to every packet.
|
77 |
|
|
|
78 |
|
|
Dwords are sent to the link, when the link is not busy.
|
79 |
|
|
|
80 |
|
|
When the user interface requests that a packet that has data associated be sent,
|
81 |
|
|
there is an two input buffers for every VC, one for packets with data and one for
|
82 |
|
|
packets without data. The command packet is sent directly to the flow control,
|
83 |
|
|
so the input buffers for the user are actually located in the flow control so
|
84 |
|
|
that it can decide from which VC it is best to send. The data payload of the
|
85 |
|
|
packet with data is kept in the user interface, so the flow control must request
|
86 |
|
|
that data when sending a packet with data associated.
|
87 |
|
|
*/
|
88 |
|
|
class flow_control_l2 : public sc_module
|
89 |
|
|
{
|
90 |
|
|
public:
|
91 |
|
|
//***********************************
|
92 |
|
|
// Ports definition
|
93 |
|
|
//***********************************
|
94 |
|
|
|
95 |
|
|
/// The Clock
|
96 |
|
|
sc_in<bool> clk;
|
97 |
|
|
/// Reset signal
|
98 |
|
|
sc_in<bool> resetx;
|
99 |
|
|
///LDTSTOP# signal
|
100 |
|
|
sc_in<bool> ldtstopx;
|
101 |
|
|
|
102 |
|
|
// USER_FIFO
|
103 |
|
|
///The packet the user interface wants to send
|
104 |
|
|
sc_in <sc_bv<64> > ui_packet_fc;
|
105 |
|
|
///If it there is a packet available to be sent
|
106 |
|
|
sc_in <bool> ui_available_fc;
|
107 |
|
|
///The VC's that can accept packets currently
|
108 |
|
|
sc_out <sc_bv<3> > fc_user_fifo_ge2_ui;
|
109 |
|
|
|
110 |
|
|
///The VC in which the flow control wants to read data from the UI data buffer
|
111 |
|
|
sc_out <VirtualChannel> fc_data_vc_ui;
|
112 |
|
|
///The data from the UI buffers
|
113 |
|
|
sc_in <sc_bv<32> > ui_data_fc;
|
114 |
|
|
///To consume the data from the UI buffers
|
115 |
|
|
sc_out <bool> fc_consume_data_ui;
|
116 |
|
|
|
117 |
|
|
// Forward -- FC
|
118 |
|
|
///If there is a packet to be sent from the reordering from the other side
|
119 |
|
|
sc_in <bool> ro_available_fwd;
|
120 |
|
|
///The packet to sent
|
121 |
|
|
sc_in <syn_ControlPacketComplete > ro_packet_fwd;
|
122 |
|
|
sc_in<VirtualChannel> ro_packet_vc_fwd;
|
123 |
|
|
///To acknoledge that the packet has been consumed
|
124 |
|
|
sc_out <bool> fwd_ack_ro;
|
125 |
|
|
|
126 |
|
|
//LINK
|
127 |
|
|
///The dword to send to the other link
|
128 |
|
|
sc_out <sc_bv<32> > fc_dword_lk;
|
129 |
|
|
///The LCTL control signal to send along with the data
|
130 |
|
|
sc_out <bool> fc_lctl_lk;
|
131 |
|
|
///The HCTL control signal to send along with the data
|
132 |
|
|
sc_out <bool> fc_hctl_lk;
|
133 |
|
|
///The link consumes the data we are sending
|
134 |
|
|
sc_in <bool> lk_consume_fc;
|
135 |
|
|
#ifdef RETRY_MODE_ENABLED
|
136 |
|
|
///Force the link to disconnect
|
137 |
|
|
/**Disconnect will occur after the current dword is done sending*/
|
138 |
|
|
sc_out <bool> fc_disconnect_lk;
|
139 |
|
|
///This signal is active when the RX side of the link is connected
|
140 |
|
|
sc_in <bool> lk_rx_connected;
|
141 |
|
|
///If the link wants to initiate a retry disconnect
|
142 |
|
|
sc_in <bool> lk_initiate_retry_disconnect;
|
143 |
|
|
///If we are in the mode retry
|
144 |
|
|
sc_in <bool> csr_retry;
|
145 |
|
|
//Command decoder
|
146 |
|
|
/**Turns on when a disconnect sequence is initiated
|
147 |
|
|
All buffer counts are zeroed and we must replay all packets
|
148 |
|
|
that have not been acked*/
|
149 |
|
|
sc_in <bool> cd_initiate_retry_disconnect;
|
150 |
|
|
#endif
|
151 |
|
|
|
152 |
|
|
//DATA BUFFER
|
153 |
|
|
///The address where to read the data
|
154 |
|
|
sc_out <sc_uint<BUFFERS_ADDRESS_WIDTH> > fwd_address_db;
|
155 |
|
|
///The VC in which to read the data
|
156 |
|
|
sc_out <VirtualChannel> fwd_vctype_db;
|
157 |
|
|
///To read (consume) the data at the address specified
|
158 |
|
|
sc_out <bool> fwd_read_db;
|
159 |
|
|
///To erase the data packet
|
160 |
|
|
sc_out <bool> fwd_erase_db;
|
161 |
|
|
///The data received from the data buffer
|
162 |
|
|
sc_in <sc_bv<32> > db_data_fwd;
|
163 |
|
|
|
164 |
|
|
|
165 |
|
|
///Buffer count information from RO and DB for sending nop's
|
166 |
|
|
///The buffers the ro can notify as being free to the HT node we are connected to
|
167 |
|
|
//Bits 1..0 : PC, Bits 3..2 : RC. Bits 5..4 : NPC
|
168 |
|
|
sc_in <sc_bv<6> > ro_buffer_cnt_fc;
|
169 |
|
|
///The buffers the ro can notify as being free to the HT node we are connected to
|
170 |
|
|
//Bits 1..0 : PC, Bits 3..2 : RC. Bits 5..4 : NPC
|
171 |
|
|
sc_in <sc_bv<6> > db_buffer_cnt_fc;
|
172 |
|
|
|
173 |
|
|
//Connexion Error handler FLOW control
|
174 |
|
|
///Acknoledge that the dword has been read
|
175 |
|
|
sc_out <bool> fc_ack_eh;
|
176 |
|
|
///The dword to send (command packet or data payload)
|
177 |
|
|
sc_in <sc_bv<32> > eh_cmd_data_fc;
|
178 |
|
|
///If there is a dword to send
|
179 |
|
|
sc_in <bool> eh_available_fc;
|
180 |
|
|
|
181 |
|
|
//Connexion CSR -- FLOW control
|
182 |
|
|
///Acknoledge that the dword has been read
|
183 |
|
|
sc_out <bool> fc_ack_csr;
|
184 |
|
|
///If there is a dword to send
|
185 |
|
|
sc_in <bool> csr_available_fc;
|
186 |
|
|
///The dword to send (command packet or data payload)
|
187 |
|
|
sc_in <sc_bv<32> > csr_dword_fc;
|
188 |
|
|
|
189 |
|
|
///If we are to turn the transmitter off
|
190 |
|
|
///Now ignored since reset is necessary to reactivate link. transmitter off is taken care
|
191 |
|
|
//of in the link only
|
192 |
|
|
//sc_in <bool> csr_transmitteroff;
|
193 |
|
|
|
194 |
|
|
#ifdef RETRY_MODE_ENABLED
|
195 |
|
|
///This bit forces a single stomp to be sent
|
196 |
|
|
sc_in<bool> csr_force_single_stomp_fc;
|
197 |
|
|
///This bit forces a single CRC error to be sent
|
198 |
|
|
sc_in<bool> csr_force_single_error_fc;
|
199 |
|
|
///Once a CRC error is sent, we clear the signal to send the error
|
200 |
|
|
sc_out<bool> fc_clear_single_error_csr;
|
201 |
|
|
///Once a stomp is sent, we clear the signal to send the stomp
|
202 |
|
|
sc_out<bool> fc_clear_single_stomp_csr;
|
203 |
|
|
#endif
|
204 |
|
|
|
205 |
|
|
|
206 |
|
|
//Connexion pour les NOP request
|
207 |
|
|
///Databuffer requests that a nop be sent.
|
208 |
|
|
sc_in <bool> db_nop_req_fc;
|
209 |
|
|
///Reordering requests that a nop be sent.
|
210 |
|
|
sc_in <bool> ro_nop_req_fc;
|
211 |
|
|
///A nop was just sent
|
212 |
|
|
sc_out <bool> fc_nop_sent;
|
213 |
|
|
|
214 |
|
|
// NOP info packet
|
215 |
|
|
///The buffer information received in a nop
|
216 |
|
|
sc_in<sc_bv<12> > cd_nopinfo_fc;
|
217 |
|
|
///If a nop was just received
|
218 |
|
|
sc_in<bool> cd_nop_received_fc;
|
219 |
|
|
|
220 |
|
|
///Let the reordering know which buffers are free in the next node
|
221 |
|
|
sc_out <sc_bv<6> > fwd_next_node_buffer_status_ro;
|
222 |
|
|
|
223 |
|
|
#ifdef RETRY_MODE_ENABLED
|
224 |
|
|
///The packet that is acked in the nop (for retry mode)
|
225 |
|
|
/**
|
226 |
|
|
When we receive this ack value, we can erase the packet associated with
|
227 |
|
|
that number (and all the previous ones) from our buffers.
|
228 |
|
|
*/
|
229 |
|
|
sc_in<sc_uint<8> > cd_nop_ack_value_fc;
|
230 |
|
|
|
231 |
|
|
///CD maitains a count of valid packet received, that count is then sent in nops
|
232 |
|
|
sc_in<sc_uint<8> > cd_rx_next_pkt_to_ack_fc;
|
233 |
|
|
|
234 |
|
|
//////////////////////////////////////////
|
235 |
|
|
// Memory interface - synchronous
|
236 |
|
|
/////////////////////////////////////////
|
237 |
|
|
sc_out<bool> history_memory_write;///<Write to history memory
|
238 |
|
|
sc_out<sc_uint<LOG2_HISTORY_MEMORY_SIZE> > history_memory_write_address;///<Address where to write in history memory
|
239 |
|
|
sc_out<sc_bv<32> > history_memory_write_data;///<Data to write to history memory
|
240 |
|
|
sc_out<sc_uint<LOG2_HISTORY_MEMORY_SIZE> > history_memory_read_address;///<Address where to read in history memory
|
241 |
|
|
sc_in<sc_bv<32> > history_memory_output;///<Data read in history memory
|
242 |
|
|
|
243 |
|
|
|
244 |
|
|
///To clear the farent count (like for when we initiate a retry sequence)
|
245 |
|
|
sc_signal <bool> clear_farend_count;
|
246 |
|
|
|
247 |
|
|
//Connection to History buffers
|
248 |
|
|
///The packet from the history buffer
|
249 |
|
|
sc_signal <sc_bv<32> > history_packet;
|
250 |
|
|
///Signal from history buffers to tell that the playback is done
|
251 |
|
|
sc_signal <bool > history_playback_done;
|
252 |
|
|
///Activate to make the history play back it's history
|
253 |
|
|
sc_signal <bool > begin_history_playback;
|
254 |
|
|
///Activate to interrupt the history playback
|
255 |
|
|
sc_signal <bool > stop_history_playback;
|
256 |
|
|
///When the history is ready to begin a playback sequence
|
257 |
|
|
sc_signal <bool > history_playback_ready;
|
258 |
|
|
///To consume the dword from the history
|
259 |
|
|
sc_signal <bool > consume_history;
|
260 |
|
|
|
261 |
|
|
///Signal from the history buffer to say how much room is available in the buffers
|
262 |
|
|
sc_signal <bool > room_available_in_history;
|
263 |
|
|
|
264 |
|
|
///To tell the history buffers to add to it's history the buffer being outputed to the link
|
265 |
|
|
sc_signal <bool > add_to_history;
|
266 |
|
|
///Prepare a new entry in the history buffers
|
267 |
|
|
sc_signal <bool > new_history_entry;
|
268 |
|
|
///The size of the entry to prepare
|
269 |
|
|
sc_signal <sc_uint<5> > new_history_entry_size_m1;
|
270 |
|
|
|
271 |
|
|
|
272 |
|
|
//Connection to CRC unit
|
273 |
|
|
///To calculate the CRC from the current output
|
274 |
|
|
sc_signal<bool> calculate_crc;
|
275 |
|
|
///Reset the value of the CRC
|
276 |
|
|
sc_signal<bool> clear_crc;
|
277 |
|
|
///To calculate the CRC from the current output in and store in the alternate nop CRC register
|
278 |
|
|
sc_signal<bool> calculate_nop_crc;
|
279 |
|
|
///Reset the value of the alternate nop CRC register
|
280 |
|
|
sc_signal<bool> clear_nop_crc;
|
281 |
|
|
///The CRC register value
|
282 |
|
|
sc_signal<sc_uint<32> > crc_output;
|
283 |
|
|
///The nop CRC register value
|
284 |
|
|
sc_signal<sc_uint<32> > nop_crc_output;
|
285 |
|
|
|
286 |
|
|
|
287 |
|
|
#endif
|
288 |
|
|
|
289 |
|
|
|
290 |
|
|
///Controls the output mux which selects what is sent to the TX link
|
291 |
|
|
sc_signal <sc_uint<4> > fc_ctr_mux;
|
292 |
|
|
|
293 |
|
|
|
294 |
|
|
|
295 |
|
|
//------------------------------------------
|
296 |
|
|
// Instanciation
|
297 |
|
|
//------------------------------------------
|
298 |
|
|
flow_control_l3* the_flow_control; ///>("the_flow_control");
|
299 |
|
|
nop_framer_l3* the_nop_framer; ///>("the_nop_framer");
|
300 |
|
|
multiplexer_l3* the_multiplexer; ///>("the_multiplexer");
|
301 |
|
|
rx_farend_cnt_l3* the_rx_farend_cnt; ///>("the_rx_farend_cnt");
|
302 |
|
|
user_fifo_l3* the_user_fifo; ///>("the_user_fifo");
|
303 |
|
|
fairness_l3* the_fairness; ///>("the_fairness");
|
304 |
|
|
#ifdef RETRY_MODE_ENABLED
|
305 |
|
|
history_buffer_l3* the_history_buffer;///>("the_history_buffer");
|
306 |
|
|
fc_packet_crc_l3* the_fc_packet_crc;///>("the_fc_packet_crc");
|
307 |
|
|
#endif
|
308 |
|
|
|
309 |
|
|
//***********************************
|
310 |
|
|
// Intern Signals
|
311 |
|
|
//***********************************
|
312 |
|
|
|
313 |
|
|
//FIFO --FC
|
314 |
|
|
///packet coming from the user fifo
|
315 |
|
|
sc_signal <sc_bv<64> > fifo_user_packet;
|
316 |
|
|
///if there is packet available from the user fifo
|
317 |
|
|
sc_signal<bool> fifo_user_available;
|
318 |
|
|
///consume the data from the user fifo
|
319 |
|
|
sc_signal <bool> consume_user_fifo; //acknowledge
|
320 |
|
|
///flow control (l3) is currently reading output, do not change it!
|
321 |
|
|
sc_signal <bool> hold_user_fifo;
|
322 |
|
|
|
323 |
|
|
/** @name Fifo registered modules
|
324 |
|
|
These signals are not necessary, but they are registered in fifo
|
325 |
|
|
module to accelerate the combinatorial path of the next module.
|
326 |
|
|
*/
|
327 |
|
|
//@{
|
328 |
|
|
///Virtual channel of the ::fifo_user_packet
|
329 |
|
|
sc_signal<VirtualChannel> fifo_user_packet_vc;
|
330 |
|
|
///If ::fifo_user_packet is a double word packet (as opposed to a quad word, word = 16 bits)
|
331 |
|
|
sc_signal<bool> fifo_user_packet_dword;
|
332 |
|
|
///If ::fifo_user_packet has any data associated
|
333 |
|
|
sc_signal<bool> fifo_user_packet_data_asociated;
|
334 |
|
|
#ifdef RETRY_MODE_ENABLED
|
335 |
|
|
///
|
336 |
|
|
sc_signal<PacketCommand > fifo_user_packet_command;
|
337 |
|
|
#endif
|
338 |
|
|
///Size of ::fifo_user_packet data in dwords minus 1
|
339 |
|
|
sc_signal<sc_uint<4> > fifo_user_packet_data_count_m1;
|
340 |
|
|
///If ::fifo_user_packet has the chain bit on (also checks if it's a posted packet)
|
341 |
|
|
sc_signal<bool> fifo_user_packet_isChain;
|
342 |
|
|
//@}
|
343 |
|
|
|
344 |
|
|
///Dword coming from the nop generator
|
345 |
|
|
sc_signal <sc_bv<32> > ht_nop_pkt;
|
346 |
|
|
|
347 |
|
|
//Fairness Algorithm
|
348 |
|
|
|
349 |
|
|
///If the local side has priority
|
350 |
|
|
sc_signal<bool> local_priority;
|
351 |
|
|
|
352 |
|
|
///If a local packet is issued (can be sent or reserved to send when buffers available)
|
353 |
|
|
sc_signal<bool> local_packet_issued;
|
354 |
|
|
|
355 |
|
|
|
356 |
|
|
|
357 |
|
|
//NOP
|
358 |
|
|
///A nop is the next packet that must be sent after the current on has been sent
|
359 |
|
|
sc_signal <bool> nop_next_to_send;
|
360 |
|
|
///Disconnect nops must be generated
|
361 |
|
|
sc_signal <bool> generate_disconnect_nop;
|
362 |
|
|
///If the RO and DB have buffers to notify as being free to the next node
|
363 |
|
|
sc_signal <bool> has_nop_buffers_to_send;
|
364 |
|
|
|
365 |
|
|
///To select the CRC as output to the link
|
366 |
|
|
sc_signal <bool> select_crc_output;
|
367 |
|
|
///To select the nop CRC as output to the link
|
368 |
|
|
sc_signal <bool> select_nop_crc_output;
|
369 |
|
|
|
370 |
|
|
/// indicate the packet type that is sent.
|
371 |
|
|
//one hot encoding, meaning of bits :
|
372 |
|
|
//0 - response data
|
373 |
|
|
//1 - response command
|
374 |
|
|
//2 - non-posted data
|
375 |
|
|
//3 - non-posted command
|
376 |
|
|
//4 - posted data
|
377 |
|
|
//5 - posted command
|
378 |
|
|
sc_signal <sc_bv<6> > current_sent_type;
|
379 |
|
|
|
380 |
|
|
///The output of the registered MUX (selection of data source before per-packet CRC)
|
381 |
|
|
sc_signal <sc_bv<32> > mux_registered_output;
|
382 |
|
|
|
383 |
|
|
///SystemC macro
|
384 |
|
|
SC_HAS_PROCESS(flow_control_l2);
|
385 |
|
|
|
386 |
|
|
///constructor, instanciates sub-modules and links them
|
387 |
|
|
flow_control_l2(sc_module_name name);
|
388 |
|
|
|
389 |
|
|
#ifdef RETRY_MODE_ENABLED
|
390 |
|
|
///Takes care of sending the clear_single error and clear single stomp to the CSR
|
391 |
|
|
void send_clear_single_error_and_stomp();
|
392 |
|
|
#endif
|
393 |
|
|
|
394 |
|
|
#ifdef SYSTEMC_SIM
|
395 |
|
|
///class destructor in simulation, to free the instanciated sub-modules
|
396 |
|
|
virtual ~flow_control_l2();
|
397 |
|
|
#endif
|
398 |
|
|
};
|
399 |
|
|
|
400 |
|
|
|
401 |
|
|
#endif
|