cloudFPGA (cF) API  1.0
The documentation of the source code of cloudFPGA (cF)
toecam.cpp
Go to the documentation of this file.
1 /*
2  * Copyright 2016 -- 2021 IBM Corporation
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 
34 #include "toecam.hpp"
35 
36 using namespace hls;
37 
38 
42 #ifndef __SYNTHESIS__
43  extern bool gTraceEvent;
44 #endif
45 
46 #define THIS_NAME "TOECAM"
47 
48 #define TRACE_OFF 0x0000
49 #define TRACE_CAM 1 << 1
50 #define TRACE_ALL 0xFFFF
51 
52 #define DEBUG_LEVEL (TRACE_OFF)
53 
54 
55 //-- C/RTL LATENCY AND INITIAL INTERVAL
56 //-- Use numbers >= to those of the 'Co-simulation Report'
57 #define MAX_CAM_LATENCY 0
58 
59 
62  #define CAM_ARRAY_SIZE 2
63  static KeyValuePair CamArray0;
64  static KeyValuePair CamArray1;
65  static KeyValuePair CamArray2;
66  static KeyValuePair CamArray3;
67  static KeyValuePair CamArray4;
68  static KeyValuePair CamArray5;
69  static KeyValuePair CamArray6;
70  static KeyValuePair CamArray7;
71 
72 
80 bool camLookup(FourTuple key, RtlSessId &value)
81 {
82  #pragma HLS pipeline II=1 enable_flush
83  if ((CamArray0.key == key) && (CamArray0.valid == true)) {
84  value = CamArray0.value;
85  return true;
86  }
87  else if ((CamArray1.key == key) && (CamArray1.valid == true)) {
88  value = CamArray1.value;
89  return true;
90  }
91  else if ((CamArray2.key == key) && (CamArray2.valid == true)) {
92  value = CamArray2.value;
93  return true;
94  }
95  else if ((CamArray3.key == key) && (CamArray3.valid == true)) {
96  value = CamArray3.value;
97  return true;
98  }
99  else if ((CamArray4.key == key) && (CamArray4.valid == true)) {
100  value = CamArray4.value;
101  return true;
102  }
103  else if ((CamArray5.key == key) && (CamArray5.valid == true)) {
104  value = CamArray5.value;
105  return true;
106  }
107  else if ((CamArray6.key == key) && (CamArray6.valid == true)) {
108  value = CamArray6.value;
109  return true;
110  }
111  else if ((CamArray7.key == key) && (CamArray7.valid == true)) {
112  value = CamArray7.value;
113  return true;
114  }
115  else
116  return false;
117 }
118 
119 
127 {
128  #pragma HLS pipeline II=1 enable_flush
129 
130  if (CamArray0.valid == false) {
131  CamArray0 = kVP;
132  return true;
133  }
134  else if (CamArray1.valid == false) {
135  CamArray1 = kVP;
136  return true;
137  }
138  else if (CamArray2.valid == false) {
139  CamArray2 = kVP;
140  return true;
141  }
142  else if (CamArray3.valid == false) {
143  CamArray3 = kVP;
144  return true;
145  }
146  else if (CamArray4.valid == false) {
147  CamArray4 = kVP;
148  return true;
149  }
150  else if (CamArray5.valid == false) {
151  CamArray5 = kVP;
152  return true;
153  }
154  else if (CamArray6.valid == false) {
155  CamArray6 = kVP;
156  return true;
157  }
158  else if (CamArray7.valid == false) {
159  CamArray7 = kVP;
160  return true;
161  }
162  else {
163  return false;
164  }
165 }
166 
167 
175 {
176  #pragma HLS pipeline II=1 enable_flush
177 
178  if ((CamArray0.key == key) && (CamArray0.valid == true)) {
179  CamArray0.valid = false;
180  return true;
181  }
182  else if ((CamArray1.key == key) && (CamArray1.valid == true)) {
183  CamArray1.valid = false;
184  return true;
185  }
186  else if ((CamArray2.key == key) && (CamArray2.valid == true)) {
187  CamArray2.valid = false;
188  return true;
189  }
190  else if ((CamArray3.key == key) && (CamArray3.valid == true)) {
191  CamArray3.valid = false;
192  return true;
193  }
194  else if ((CamArray4.key == key) && (CamArray4.valid == true)) {
195  CamArray4.valid = false;
196  return true;
197  }
198  else if ((CamArray5.key == key) && (CamArray5.valid == true)) {
199  CamArray5.valid = false;
200  return true;
201  }
202  else if ((CamArray6.key == key) && (CamArray6.valid == true)) {
203  CamArray6.valid = false;
204  return true;
205  }
206  else if ((CamArray7.key == key) && (CamArray7.valid == true)) {
207  CamArray7.valid = false;
208  return true;
209  }
210  else
211  return false;
212 }
213 
214 
233 void toecam(
234  //------------------------------------------------------
235  //-- MMIO Interfaces
236  //------------------------------------------------------
237  ap_uint<1> *poMMIO_CamReady,
238  //------------------------------------------------------
239  //-- CAM / This / Session Lookup & Update Interfaces
240  //------------------------------------------------------
241  stream<CamSessionLookupRequest> &siTOE_SssLkpReq,
242  stream<CamSessionLookupReply> &soTOE_SssLkpRep,
243  stream<CamSessionUpdateRequest> &siTOE_SssUpdReq,
244  stream<CamSessionUpdateReply> &soTOE_SssUpdRep)
245 {
246  //-- DIRECTIVES FOR THE INTERFACES -----------------------------------------
247  #pragma HLS INTERFACE ap_ctrl_none port=return
248  #pragma HLS INLINE
249  #pragma HLS PIPELINE II=1 enable_flush
250 
251  const char *myName = concat3(THIS_NAME, "/", "CAM");
252 
253  //-- STATIC ARRAYS ---------------------------------------------------------
254  #pragma HLS RESET variable=CamArray0
255  #pragma HLS RESET variable=CamArray1
256  #pragma HLS RESET variable=CamArray2
257  #pragma HLS RESET variable=CamArray3
258  #pragma HLS RESET variable=CamArray4
259  #pragma HLS RESET variable=CamArray5
260  #pragma HLS RESET variable=CamArray6
261  #pragma HLS RESET variable=CamArray7
262 
263  //-- STATIC CONTROL VARIABLES (with RESET) ---------------------------------
264  static enum FsmStates { CAM_WAIT_4_REQ=0, CAM_LOOKUP_REP, CAM_UPDATE_REP } \
265  cam_fsmState=CAM_WAIT_4_REQ;
266  #pragma HLS RESET variable=cam_fsmState
267  static int cam_startupDelay = 100;
268  #pragma HLS RESET variable=cam_startupDelay
269 
270  //-- STATIC DATAFLOW VARIABLES --------------------------------------------
271  static CamSessionLookupRequest cam_request;
272  static CamSessionUpdateRequest cam_update;
273  static int cam_idleCnt = 0;
274 
275  //-----------------------------------------------------
276  //-- EMULATE STARTUP OF CAM
277  //-----------------------------------------------------
278  if (cam_startupDelay) {
279  *poMMIO_CamReady = 0;
280  cam_startupDelay--;
281  return;
282  }
283  else {
284  *poMMIO_CamReady = 1;
285  }
286 
287  //-----------------------------------------------------
288  //-- CONTENT ADDRESSABLE MEMORY PROCESS
289  //-----------------------------------------------------
290  switch (cam_fsmState) {
291  case CAM_WAIT_4_REQ:
292  if (!siTOE_SssLkpReq.empty()) {
293  siTOE_SssLkpReq.read(cam_request);
294  cam_idleCnt = MAX_CAM_LATENCY;
295  cam_fsmState = CAM_LOOKUP_REP;
296  }
297  else if (!siTOE_SssUpdReq.empty()) {
298  siTOE_SssUpdReq.read(cam_update);
299  cam_idleCnt = MAX_CAM_LATENCY;
300  cam_fsmState = CAM_UPDATE_REP;
301  }
302  break;
303  case CAM_LOOKUP_REP:
304  //-- Wait some cycles to match the co-simulation --
305  if (cam_idleCnt > 0) {
306  cam_idleCnt--;
307  }
308  else {
309  RtlSessId rtlValue;
310  bool hit = camLookup(cam_request.key, rtlValue);
311  if (hit)
312  soTOE_SssLkpRep.write(CamSessionLookupReply(true, rtlValue, cam_request.source));
313  else
314  soTOE_SssLkpRep.write(CamSessionLookupReply(false, cam_request.source));
315  if (DEBUG_LEVEL & TRACE_CAM) {
316  printInfo(myName, "Received a session lookup request from %d for socket pair: \n",
317  cam_request.source.to_int());
318  LE_SocketPair leSocketPair(LE_SockAddr(cam_request.key.theirIp, cam_request.key.theirPort),
319  LE_SockAddr(cam_request.key.myIp, cam_request.key.myPort));
320  printSockPair(myName, leSocketPair);
321  }
322  cam_fsmState = CAM_WAIT_4_REQ;
323  }
324  break;
325  case CAM_UPDATE_REP:
326  //-- Wait some cycles to match the co-simulation --
327  if (cam_idleCnt > 0) {
328  cam_idleCnt--;
329  }
330  else {
331  // [TODO - What if element does not exist]
332  if (cam_update.op == INSERT) {
333  //Is there a check if it already exists?
334  camInsert(KeyValuePair(cam_update.key, cam_update.value, true));
335  soTOE_SssUpdRep.write(CamSessionUpdateReply(cam_update.value, INSERT, cam_update.source));
336  }
337  else { // DELETE
338  camDelete(cam_update.key);
339  soTOE_SssUpdRep.write(CamSessionUpdateReply(cam_update.value, DELETE, cam_update.source));
340  }
341  if (DEBUG_LEVEL & TRACE_CAM) {
342  printInfo(myName, "Received a session cam_update request (%d) from %d for socket pair: \n",
343  cam_update.op, cam_update.source.to_int());
344  LE_SocketPair leSocketPair(LE_SockAddr(cam_request.key.theirIp, cam_request.key.theirPort),
345  LE_SockAddr(cam_request.key.myIp, cam_request.key.myPort));
346  printSockPair(myName, leSocketPair);
347  }
348  cam_fsmState = CAM_WAIT_4_REQ;
349  }
350  break;
351 
352  } // End-of: switch()
353 
354 }
355 
356 
366 #if HLS_VERSION == 2017
367  void toecam_top(
368  //------------------------------------------------------
369  //-- MMIO Interfaces
370  //------------------------------------------------------
371  ap_uint<1> *poMMIO_CamReady,
372  //------------------------------------------------------
373  //-- CAM / This / Session Lookup & Update Interfaces
374  //------------------------------------------------------
375  stream<CamSessionLookupRequest> &siTOE_SssLkpReq,
376  stream<CamSessionLookupReply> &soTOE_SssLkpRep,
377  stream<CamSessionUpdateRequest> &siTOE_SssUpdReq,
378  stream<CamSessionUpdateReply> &soTOE_SssUpdRep)
379 {
380  //-- DIRECTIVES FOR THE INTERFACES -----------------------------------------
381  #pragma HLS INTERFACE ap_ctrl_none port=return
382 
383 
384 
385 
386 
388  #pragma HLS INTERFACE ap_none register port=poMMIO_CamReady name=poMMIO_CamReady
389 
390  #pragma HLS resource core=AXI4Stream variable=siTOE_SssLkpReq metadata="-bus_bundle siTOE_SssLkpReq"
391  #pragma HLS DATA_PACK variable=siTOE_SssLkpReq
392  #pragma HLS resource core=AXI4Stream variable=soTOE_SssLkpRep metadata="-bus_bundle soTOE_SssLkpRep"
393  #pragma HLS DATA_PACK variable=soTOE_SssLkpRep
394  #pragma HLS resource core=AXI4Stream variable=siTOE_SssUpdReq metadata="-bus_bundle siTOE_SssUpdReq"
395  #pragma HLS DATA_PACK variable=siTOE_SssUpdReq
396  #pragma HLS resource core=AXI4Stream variable=soTOE_SssUpdRep metadata="-bus_bundle soTOE_SssUpdRep"
397  #pragma HLS DATA_PACK variable=soTOE_SssUpdRep
398 
399  //-- DIRECTIVES FOR THIS PROCESS -------------------------------------------
400  #pragma HLS DATAFLOW
401 
402  //-- MAIN IPTX PROCESS -----------------------------------------------------
403  toecam(
404  //-- MMIO Interfaces
405  poMMIO_CamReady,
406  //-- CAM / This / Session Lookup & Update Interfaces
407  siTOE_SssLkpReq,
408  soTOE_SssLkpRep,
409  siTOE_SssUpdReq,
410  soTOE_SssUpdRep);
411 
412 }
413 #else
415  //------------------------------------------------------
416  //-- MMIO Interfaces
417  //------------------------------------------------------
418  ap_uint<1> *poMMIO_CamReady,
419  //------------------------------------------------------
420  //-- CAM / This / Session Lookup & Update Interfaces
421  //------------------------------------------------------
422  stream<CamSessionLookupRequest> &siTOE_SssLkpReq,
423  stream<CamSessionLookupReply> &soTOE_SssLkpRep,
424  stream<CamSessionUpdateRequest> &siTOE_SssUpdReq,
425  stream<CamSessionUpdateReply> &soTOE_SssUpdRep)
426 {
427  //-- DIRECTIVES FOR THE INTERFACES -----------------------------------------
428  #pragma HLS INTERFACE ap_ctrl_none port=return
429 
430  #pragma HLS INTERFACE ap_none register port=poMMIO_CamReady name=poMMIO_CamReady
431 
432  #pragma HLS INTERFACE axis off port=siTOE_SssLkpReq
433  #pragma HLS DATA_PACK variable=siTOE_SssLkpReq
434  #pragma HLS INTERFACE axis register both port=soTOE_SssLkpRep
435  #pragma HLS DATA_PACK variable=soTOE_SssLkpRep
436  #pragma HLS INTERFACE axis off port=siTOE_SssUpdReq
437  #pragma HLS DATA_PACK variable=siTOE_SssUpdReq
438  #pragma HLS INTERFACE axis register both port=soTOE_SssUpdRep
439  #pragma HLS DATA_PACK variable=soTOE_SssUpdRep
440 
441  //-- DIRECTIVES FOR THIS PROCESS -------------------------------------------
442  #pragma HLS DATAFLOW disable_start_propagation
443 
444  //-- MAIN IPTX PROCESS -----------------------------------------------------
445  toecam(
446  //-- MMIO Interfaces
447  poMMIO_CamReady,
448  //-- CAM / This / Session Lookup & Update Interfaces
449  siTOE_SssLkpReq,
450  soTOE_SssLkpRep,
451  siTOE_SssUpdReq,
452  soTOE_SssUpdRep);
453 
454 }
455 #endif // HLS_VERSION
456 
LE_TcpPort theirPort
Definition: nts_types.hpp:398
LE_Ip4Addr theirIp
Definition: nts_types.hpp:396
LE_TcpPort myPort
Definition: nts_types.hpp:397
LE_Ip4Addr myIp
Definition: nts_types.hpp:395
#define TRACE_CAM
Definition: toecam.cpp:49
bool camLookup(FourTuple key, RtlSessId &value)
Search the CAM array for a key.
Definition: toecam.cpp:80
bool camDelete(FourTuple key)
Remove a key-value pair from the CAM array.
Definition: toecam.cpp:174
bool gTraceEvent
Definition: tb_nal.cpp:151
#define MAX_CAM_LATENCY
Definition: toecam.cpp:57
#define THIS_NAME
Definition: toecam.cpp:46
bool camInsert(KeyValuePair kVP)
Insert a new key-value pair in the CAM array.
Definition: toecam.cpp:126
#define DEBUG_LEVEL
Definition: toecam.cpp:52
void toecam(ap_uint< 1 > *poMMIO_CamReady, stream< CamSessionLookupRequest > &siTOE_SssLkpReq, stream< CamSessionLookupReply > &soTOE_SssLkpRep, stream< CamSessionUpdateRequest > &siTOE_SssUpdReq, stream< CamSessionUpdateReply > &soTOE_SssUpdRep)
Main process of the Content-Addressable Memory (TOECAM).
Definition: toecam.cpp:233
void toecam_top(ap_uint< 1 > *poMMIO_CamReady, stream< CamSessionLookupRequest > &siTOE_SssLkpReq, stream< CamSessionLookupReply > &soTOE_SssLkpRep, stream< CamSessionUpdateRequest > &siTOE_SssUpdReq, stream< CamSessionUpdateReply > &soTOE_SssUpdRep)
Top of Content-Addressable Memory (TOECAM).
Definition: toecam.cpp:414
#define printInfo(callerName, format,...)
A macro to print an information message.
Definition: nts_utils.hpp:169
#define concat3(firstCharConst, secondCharConst, thirdCharConst)
Definition: nts_utils.hpp:161
ap_uint< 14 > RtlSessId
Definition: nts_types.hpp:378
void printSockPair(const char *callerName, SocketPair sockPair)
Print a socket pair association.
Definition: nts_utils.cpp:114
@ DELETE
Definition: nts_types.hpp:382
@ INSERT
Definition: nts_types.hpp:382
bool valid
Definition: cam16.hpp:46
: Content-Addressable Memory (CAM) for TCP Offload Engine (TOE)