tableMapping
List of all pip packages imported
1""" 2List of all pip packages imported 3""" 4 5import difflib 6import itertools 7import json 8import logging 9import os 10import re 11import sys 12 13import jellyfish 14import numpy as np 15import pandas as pd 16import yaml 17from tabulate import tabulate 18 19# =========================================================================================== 20# ======================================= Begin Class ======================================= 21# =========================================================================================== 22 23 24class TableMapping: 25 """ 26 Generates a golden model for a particular SRAM memory table map config 27 using a respective TCAM memory table map and configs. 28 """ 29 30 # * ----------------------------------------------------------------- Variables 31 def __init__(self): 32 """ 33 Constructor: Initializes all the class variables 34 35 **Public Variables:** 36 :param str prjWorkDir: current project working dir 37 :param str sramTableDir: abs path of SRAM table map folder 38 :param str tcamTableConfigsFilePath: abs path of TCAM table map config file 39 :param str tcamTableConfigsFileName: TCAM table map config file name 40 :param str tcamTableXlsxFilePath: abs path of TCAM table map XLSX file 41 :param str tcamTableXlsxFileName: TCAM table map XLSX file name 42 :param str sramTableXlsxFilePath: abs path of generated SRAM table map XLSX file 43 :param str sramTableXlsxFileName: SRAM table map XLSX file name 44 :param str sramTableHtmlFilePath: abs path of generated SRAM table map HTML file 45 :param str sramTableHtmlFileName: SRAM table map HTML file name 46 :param str sramTableJsonFilePath: abs path of generated SRAM table map JSON file 47 :param str sramTableJsonFileName: SRAM table map JSON file name 48 :param str sramTableTxtFilePath: abs path of generated SRAM table map TXT file 49 :param str sramTableTxtFileName: SRAM table map TXT file name 50 51 **Protected Variables:** 52 :param dict _tcamTableConfigs: TCAM table map configs 53 :param DataFrame _tcamTable: TCAM table map 54 :param DataFrame _sramTable: SRAM table map 55 :param DataFrame _tcamQSAddrTable: TCAM table map query addr sub str 56 :param DataFrame _sramQSAddrTable: SRAM table map query addr sub str 57 58 **Private Variables:** 59 :param int __tcamQueryStrLen: `queryStrLen` of a particular TCAM table config 60 :param int __tcamSubStrLen: `subStrLen` of a particular TCAM table config 61 :param int __tcamTotalSubStr: `totalSubStr` of a particular TCAM table config 62 :param int __tcamPotMatchAddr: `potMatchAddr` of a particular TCAM table config 63 :param int __sramTableRows: SRAM table map row count 64 :param int __sramTableCols: SRAM table map col count 65 :param list __tcamRows: TCAM table map row count vector 66 :param list __tcamCols: TCAM table map col count vector 67 :param list __tcamColVec: TCAM table map sub string address col count vector 68 :param list __sramRows: SRAM table map row count vector 69 :param list __sramRowVec: SRAM table map sub string address row count vector 70 :param list __sramCols: SRAM table map col count vector 71 """ 72 # * ------------------- public vars 73 self.prjWorkDir = "" 74 self.sramTableDir = "" 75 self.tcamTableConfigsFilePath = "" 76 self.tcamTableConfigsFileName = "" 77 self.tcamTableXlsxFilePath = "" 78 self.tcamTableXlsxFileName = "" 79 self.sramTableXlsxFilePath = "" 80 self.sramTableXlsxFileName = "" 81 self.sramTableHtmlFilePath = "" 82 self.sramTableHtmlFileName = "" 83 self.sramTableJsonFilePath = "" 84 self.sramTableJsonFileName = "" 85 self.sramTableTxtFilePath = "" 86 self.sramTableTxtFileName = "" 87 # * ------------------- protected vars 88 self._tcamTableConfigs = {} 89 self._tcamTable = pd.DataFrame 90 self._sramTable = pd.DataFrame 91 self._tcamQSAddrTable = pd.DataFrame 92 self._sramQSAddrTable = pd.DataFrame 93 # * ------------------- private vars 94 self.__tcamQueryStrLen = 0 95 self.__tcamSubStrLen = 0 96 self.__tcamTotalSubStr = 0 97 self.__tcamPotMatchAddr = 0 98 self.__sramTableRows = 0 99 self.__sramTableCols = 0 100 self.__tcamRows = [] 101 self.__tcamCols = [] 102 self.__tcamColVec = [] 103 self.__sramRows = [] 104 self.__sramRowVec = [] 105 self.__sramCols = [] 106 # * logging config 107 logging.basicConfig( 108 level=logging.DEBUG, 109 filename="./logs/tableMapping.log", 110 format="%(asctime)s | %(filename)s | %(funcName)s | %(levelname)s | %(lineno)d | %(message)s", 111 ) 112 113 # * ----------------------------------------------------------------- Functions 114 def getPrjDir(self, verbose): 115 """ 116 Obtain the absolute path of the current working directory. 117 118 :param int verbose: print information in verbose mode. 119 :return str: absolute path of the current project working directory. 120 """ 121 self.prjWorkDir = os.getcwd() 122 logging.info("Project working dir: %s", self.prjWorkDir) 123 printVerbose(verbose, f"Project working dir: {self.prjWorkDir}") 124 return self.prjWorkDir 125 126 def getYAMLFilePath(self, verbose): 127 """ 128 Obtain the absolute path of file tcamTables.yaml. 129 130 :param int verbose: print information in verbose mode. 131 :return str: absolute path of the current project working directory. 132 """ 133 # * get tcamTables config file path 134 tempPath = os.path.join(self.prjWorkDir, "compiler/configs/tcamTables.yaml") 135 if os.path.isfile(tempPath) is True: 136 self.tcamTableConfigsFilePath = tempPath 137 self.tcamTableConfigsFileName = os.path.basename(tempPath) 138 logging.info('"FOUND": TCAM table config file path: %s', self.tcamTableConfigsFilePath) 139 printVerbose(verbose, f'"FOUND": TCAM table config file path: {self.tcamTableConfigsFilePath}') 140 return self.tcamTableConfigsFilePath 141 logging.error('"NOT FOUND": TCAM table config file path: %s', self.tcamTableConfigsFilePath) 142 sys.exit(f'"NOT FOUND": TCAM table config file path: {self.tcamTableConfigsFilePath}') 143 144 def readYAML(self, filePath, verbose): 145 """ 146 Read a particular YAML config file 147 148 :param str filePath: absolute path of file tcamTables.yaml. 149 :param int verbose: print information in verbose mode. 150 :return dict: dictionary containing all the TCAM table configs. 151 """ 152 with open(filePath, encoding="utf-8") as file: 153 self._tcamTableConfigs = yaml.full_load(file) 154 # print(json.dumps(self._tcamTableConfigs,indent=4)) 155 # print(yaml.dump(self._tcamTableConfigs,sort_keys=False,default_flow_style=False)) 156 logging.info("Read TCAM table config file: %s", self.tcamTableConfigsFilePath) 157 printVerbose(verbose, f"Read TCAM table config file: {self.tcamTableConfigsFilePath}") 158 return self._tcamTableConfigs 159 160 def printYAML(self, debug): 161 """ 162 Print all present configs of a YAML file either in JSON or YAML style. 163 164 :param int debug: print information in debug mode. 165 """ 166 printDebug(debug, "Printing TCAM table configs") 167 print(json.dumps(self._tcamTableConfigs, indent=4)) 168 # print(yaml.dump(self._tcamTableConfigs,sort_keys=False,default_flow_style=False)) 169 logging.info("Printed TCAM table configs") 170 171 def getTCAMConfig(self, tcamConfig): 172 """ 173 Check if a particular tcamTable config exists in file tcamTables.yaml. If found store the config params in vars. 174 - **__tcamQueryStrLen:** saves `queryStrLen` 175 - **__tcamSubStrLen:** saves `subStrLen` 176 - **__tcamTotalSubStr:** saves `totalSubStr` 177 - **__tcamPotMatchAddr:** saves `potMatchAddr` 178 179 :param str tcamConfig: TCAM table config name e.g. tcamTableX 180 :return dict: dictionary containing the respective table map config. 181 """ 182 # * look for specific tcam config in compiler/configs/tcamTables.yaml 183 if tcamConfig in self._tcamTableConfigs.keys(): 184 tempConfig = self._tcamTableConfigs[tcamConfig] 185 # * save tcam config vars 186 self.__tcamQueryStrLen = tempConfig["queryStrLen"] 187 self.__tcamSubStrLen = tempConfig["subStrLen"] 188 self.__tcamTotalSubStr = tempConfig["totalSubStr"] 189 self.__tcamPotMatchAddr = tempConfig["potMatchAddr"] 190 # * print specific tcam config 191 # print(type(tempConfig)) 192 logging.info('"FOUND" Required TCAM Config [%s]', tcamConfig) 193 print('"FOUND" Required TCAM Config [%s]', tcamConfig) 194 logging.info("TCAM Config Data [%s] = %s", tcamConfig, tempConfig) 195 return tempConfig 196 logging.error('"NOT FOUND": TCAM Config [%s]', tcamConfig) 197 sys.exit(f'"NOT FOUND": Required TCAM table config [{tcamConfig}]') 198 199 def getTCAMTableFilePath(self, tcamConfig, verbose): 200 """ 201 Obtain the absolute path of file **tcamTableX.xlsx** which represents the TCAM memory table map. 202 203 :param str tcamConfig: TCAM table config name e.g. tcamTableX 204 :param int verbose: print information in verbose mode. 205 :return str: absolute path of the TCAM table mapping file. 206 """ 207 # * find the specific tcam table map in compiler/lib/ 208 tempPath = os.path.join(self.prjWorkDir, "compiler/lib/" + tcamConfig + ".xlsx") 209 if os.path.isfile(tempPath) is True: 210 self.tcamTableXlsxFilePath = tempPath 211 self.tcamTableXlsxFileName = os.path.basename(tempPath) 212 logging.info('"FOUND" TCAM table map XLSX file path: %s', self.tcamTableXlsxFilePath) 213 printVerbose(verbose, f'"FOUND" TCAM table map XLSX file path: {self.tcamTableXlsxFilePath}') 214 return self.tcamTableXlsxFilePath 215 logging.error('"NOT FOUND": TCAM table map XLSX file path: %s', self.tcamTableXlsxFilePath) 216 sys.exit(f'"NOT FOUND": TCAM table map XLSX file path {self.tcamTableXlsxFilePath}') 217 218 def printDF(self, dataFrame, heading): 219 """ 220 Display the contents of a particular data frame. 221 222 :param DataFrame dataFrame: particular data frame object. 223 :param str heading: Title above data frame. 224 """ 225 print("\n") 226 print("Printing dataframe: %s", heading) 227 print(tabulate(dataFrame, headers="keys", showindex=True, disable_numparse=True, tablefmt="github"), "\n") 228 logging.info("Printing dataframe: %s", str(heading)) 229 230 def getTcamTableMap(self): 231 """ 232 Getter function for the TCAM table map 233 234 :return DataFrame: TCAM table map dataframe object 235 """ 236 return self._tcamTable 237 238 def getSramTableMap(self): 239 """ 240 Getter function for the SRAM table map 241 242 :return DataFrame: SRAM table map dataframe object 243 """ 244 return self._sramTable 245 246 def readTCAMTable(self, verbose): 247 """ 248 Read the contents of a **tcamTableX.xlsx** TCAM memory table map as a data frame. 249 250 :param int verbose: print information in verbose mode. 251 :return int: list containing dimensions of TCAM table memory map. 252 """ 253 # * store tcam table in dataframe 254 self._tcamTable = pd.read_excel(self.tcamTableXlsxFilePath, skiprows=2, index_col=None, engine="openpyxl") 255 # * get num of rows and col from tcam table 256 tcamTableRows = self._tcamTable.shape[0] 257 tcamTableCols = self._tcamTable.shape[1] 258 # * compare row/col of tcam table with respective yaml config 259 if tcamTableRows == self.__tcamPotMatchAddr and tcamTableCols - 1 == self.__tcamQueryStrLen: 260 logging.info('"MATCH FOUND": TCAM table map rows == TCAM table YAML config potMatchAddr') 261 printVerbose(verbose, '"MATCH FOUND": TCAM table map rows == TCAM table YAML config potMatchAddr') 262 logging.info('"MATCH FOUND": TCAM table map cols == TCAM table YAML config queryStrLen') 263 printVerbose(verbose, '"MATCH FOUND": TCAM table map cols == TCAM table YAML config queryStrLen') 264 return [tcamTableRows, tcamTableCols] 265 logging.error('"MATCH NOT FOUND": TCAM table map rows != TCAM table YAML config potMatchAddr') 266 logging.error('"MATCH NOT FOUND": TCAM table map cols != TCAM table YAML config queryStrLen') 267 sys.exit('"MATCH NOT FOUND": MISMATCH in TCAM table map and YAML config rows/cols') 268 269 def getSRAMTableDim(self, verbose): 270 """ 271 Generate the dimensions of the SRAM table map data frame using TCAM table map configs. 272 273 :param int verbose: print information in verbose mode. 274 :return int: list containing dimensions of SRAM table memory map. 275 """ 276 self.__sramTableRows = self.__tcamTotalSubStr * pow(2, self.__tcamSubStrLen) 277 self.__sramTableCols = self.__tcamPotMatchAddr 278 logging.info("SRAM table rows [{%4d}] cols [{%4d}]", self.__sramTableRows, self.__sramTableCols) 279 printVerbose(verbose, f"SRAM table rows [{self.__sramTableRows}] cols [{self.__sramTableCols}]") 280 return [self.__sramTableRows, self.__sramTableCols] 281 282 def genSRAMTable(self, verbose): 283 """ 284 Create an empty SRAM table map data frame containing respective row addresses and column headings. 285 286 :param int verbose: print information in verbose mode. 287 """ 288 # * create temp vars 289 sramTableAddrList = [] 290 sramColHeadings = [] 291 # * create row address 292 for i in range(self.__tcamTotalSubStr): 293 for j in range(2**self.__tcamSubStrLen): 294 padding = "0" + str(self.__tcamSubStrLen) + "b" 295 # sramTableAddrList.append(format(j, '#012b')) # with 0b prefix 296 sramTableAddrList.append(format(j, padding)) # without 0b prefix 297 logging.info("Created [{%4d}] SRAM addresses from search query [{%4d}]", j + 1, i) 298 printVerbose(verbose, f"Created [{j+1}] SRAM addresses from search query [{i}]") 299 # * create col headings 300 for k in reversed(range(self.__tcamPotMatchAddr)): 301 heading = "D" + str(k) 302 sramColHeadings.append(heading) 303 logging.info("Created column heading %s", heading) 304 # * gen empty m*n sram table 305 self._sramTable = pd.DataFrame(index=np.arange(self.__sramTableRows), columns=np.arange(self.__sramTableCols)) 306 # * rename column headings 307 self._sramTable.columns = sramColHeadings 308 # * insert addr col at position 0 309 self._sramTable.insert(0, "Addresses", sramTableAddrList, allow_duplicates=True) 310 logging.info("Created empty [%d x %d] SRAM table", self._sramTable.shape[0], self._sramTable.shape[1]) 311 printVerbose(verbose, f"Created empty [{self._sramTable.shape[0]} x {self._sramTable.shape[1]}] SRAM table") 312 313 def createSRAMTableDir(self, verbose): 314 """ 315 Create a directory to store SRAM table maps in various formats. 316 317 :param int verbose: print information in verbose mode. 318 :return str: absolute path of the SRAM table map directory. 319 """ 320 # * create sramTables dir if it doesn't exist 321 self.sramTableDir = os.path.join(self.prjWorkDir, "sramTables") 322 if os.path.exists(self.sramTableDir) is False: 323 os.makedirs("sramTables") 324 logging.info("Created sramTables dir: %s", self.sramTableDir) 325 printVerbose(verbose, f"Created sramTables dir: {self.sramTableDir}") 326 return self.sramTableDir 327 328 def splitRowsAndCols(self, debug): 329 """ 330 Create TCAM and SRAM table map row and column vectors based on TCAM table config parameters. 331 332 :param int debug: print information in debug mode. 333 :return list: list containing TCAM and SRAM row and column vectors. 334 """ 335 # * store tcam and sram table in temp vars 336 tcamDF = self._tcamTable 337 sramDF = self._sramTable 338 logging.info("TCAM table (r*c): %s", tuple(tcamDF.shape)) 339 logging.info("SRAM table (r*c): %s", tuple(sramDF.shape)) 340 # * create tcamRows vector 341 self.__tcamRows = np.arange(0, self.__tcamPotMatchAddr, 1).tolist() 342 logging.info("TCAM table row vector: %s", list(self.__tcamRows)) 343 printDebug(debug, f"TCAM table row vector: {*self.__tcamRows,}") 344 # * create tcamCols vector 345 self.__tcamCols = np.arange(1, self.__tcamQueryStrLen + 1, 1).tolist() 346 logging.info("TCAM table col vector: %s", list(self.__tcamCols)) 347 printDebug(debug, f"TCAM table col vector: {*self.__tcamCols,}") 348 # * create tcamColVec vector and split in equal pieces 349 self.__tcamColVec = np.array_split(self.__tcamCols, self.__tcamTotalSubStr) 350 for i in range(len(self.__tcamColVec)): 351 self.__tcamColVec[i] = self.__tcamColVec[i].tolist() 352 logging.info("TCAM table col split vector [%d]: %s", i, list(self.__tcamColVec[i])) 353 printDebug(debug, f"TCAM table col split vector [{i}]: {self.__tcamColVec[i]}") 354 # * create sramRows vector 355 self.__sramRows = np.arange(0, self.__tcamTotalSubStr * 2**self.__tcamSubStrLen, 1).tolist() 356 logging.info("SRAM table row vector: %s", list(self.__sramRows)) 357 printDebug(debug, f"SRAM table row vector: {self.__sramRows}") 358 # * create sramRowVec vector and split in equal pieces 359 self.__sramRowVec = np.array_split(self.__sramRows, self.__tcamTotalSubStr) 360 for i in range(len(self.__sramRowVec)): 361 self.__sramRowVec[i] = self.__sramRowVec[i].tolist() 362 logging.info("SRAM table row split vector [%d]: %s", i, list(self.__sramRowVec[i])) 363 printDebug(debug, f"SRAM table row split vector [{i}]: {self.__sramRowVec[i]}") 364 # * create sramCols vector 365 self.__sramCols = np.arange(0, self.__tcamPotMatchAddr + 1, 1).tolist() 366 logging.info("SRAM table col vector: %s", list(self.__sramCols)) 367 printDebug(debug, f"SRAM table col vector: {self.__sramCols}") 368 return [self.__tcamRows, self.__tcamColVec, self.__sramRowVec, self.__sramCols] 369 370 def isolateTCAMSearchQueries(self, verbose, debug): 371 """ 372 Create a data frame containing all the sub strings in original format from all the TCAM table search queries. 373 374 :param int verbose: print information in verbose mode. 375 :param int debug: print information in debug mode. 376 """ 377 tcamDF = self._tcamTable 378 count1 = 0 379 self._tcamQSAddrTable = pd.DataFrame(columns=["TCAM Query Str Addr", "PMA", "QS col"]) 380 381 # * ----- add all original search queries in dataframe 382 # * iterate through tcam table rows 383 for row in range(len(tcamDF)): 384 # * iterate through tcam table cols 385 for col in range(len(self.__tcamColVec)): 386 # * search and concat search query string address in tcam table 387 tempAddr = [str(c) for c in list(tcamDF.iloc[row, self.__tcamColVec[col]])] 388 tempAddr = "".join(tempAddr) 389 # * append row in sqSubStrAddrDf data frame 390 tempRow = [tempAddr, row, col] 391 self._tcamQSAddrTable.loc[count1] = tempRow 392 count1 += 1 393 logging.info("TCAM Search Queries Table | Addr: %s | TCAM Row: %5d | Sub String Col: %5d |", tempAddr, row, col) 394 printDebug(debug, f"TCAM Search Queries Table | Addr: {tempAddr} | TCAM Row: {row} | Sub String Col: {col} |") 395 if verbose: 396 self.printDF(self._tcamQSAddrTable, "Original TCAM Search Query Address Table") 397 398 def generateSRAMSubStr(self, verbose, debug): 399 """ 400 Generate all possible combinations of all sub strings from the original TCAM table search queries. 401 402 :param int verbose: print information in verbose mode. 403 :param int debug: print information in debug mode. 404 """ 405 count2 = 0 406 self._sramQSAddrTable = pd.DataFrame(columns=["SRAM Query Str Addr", "PMA", "QS col"]) 407 408 # * ----- find all possible alternatives for X based addr 409 # * create array of N bit bin addresses 410 queryStrBinAddrList = np.arange(2**self.__tcamSubStrLen).tolist() 411 padding = "0" + str(self.__tcamSubStrLen) + "b" 412 for item in queryStrBinAddrList: 413 dec2Bin = format(item, padding) 414 queryStrBinAddrList = queryStrBinAddrList[:item] + [dec2Bin] + queryStrBinAddrList[item + 1 :] 415 logging.info("N bit bin addr list: %s", list(queryStrBinAddrList)) 416 logging.info("N bit bin addr list len: %d", len(queryStrBinAddrList)) 417 if verbose or debug: 418 print("N bit bin addr list: %s", list(queryStrBinAddrList)) 419 print("N bit bin addr list len: %d", len(queryStrBinAddrList)) 420 421 # * get origSQ addr 422 tempQSAddrList = self._tcamQSAddrTable["TCAM Query Str Addr"].to_list() 423 tempQSPmaList = self._tcamQSAddrTable["PMA"].to_list() 424 tempQSColList = self._tcamQSAddrTable["QS col"].to_list() 425 426 printDebug(debug, f"Search Query addr list: {tempQSAddrList}") 427 printDebug(debug, f"Search Query addr list len: {len(tempQSAddrList)}\n") 428 # * map the 'bX in search queries to 0 and 1 429 for (oldAddr, pma, qscol) in zip(tempQSAddrList, tempQSPmaList, tempQSColList): 430 # * if 'bX in search query then find all possible alternatives and add in table 431 if "x" in oldAddr: 432 for newAddr in queryStrBinAddrList: 433 matching = jellyfish.damerau_levenshtein_distance(oldAddr, newAddr) 434 if matching == len(re.findall("x", oldAddr)): 435 printVerbose( 436 verbose, 437 f"count = {count2} | orig Search Query = {oldAddr} | " f"new Search Query = {newAddr} | matching ratio = {matching} |", 438 ) 439 logging.info( 440 "count = %d | orig Search Query = %s | new Search Query = %s | matching ratio = %f |", count2, oldAddr, newAddr, matching 441 ) 442 self._sramQSAddrTable.loc[count2] = [newAddr, pma, qscol] 443 count2 += 1 444 # * else simply add search query in table as is 445 else: 446 printVerbose(verbose, f"count = {count2} | orig Search Query = {oldAddr} | new Search Query = {oldAddr} | matching ratio = {0} |") 447 logging.info("count = %d | orig Search Query = %s | new Search Query = %s | matching ratio = %f |", count2, oldAddr, oldAddr, 0) 448 self._sramQSAddrTable.loc[count2] = [oldAddr, pma, qscol] 449 count2 += 1 450 451 if verbose: 452 self.printDF(self._sramQSAddrTable, "Original SRAM Search Query Address Table") 453 454 def mapTCAMtoSRAM(self, verbose, debug): 455 """ 456 Map all possible combinations of TCAM table map sub strings to SRAM table map sub strings. 457 458 :param int verbose: print information in verbose mode. 459 :param int debug: print information in debug mode. 460 """ 461 sramDF = self._sramTable 462 sramAddrList = self._sramQSAddrTable["SRAM Query Str Addr"].to_list() 463 tcamRowList = self._sramQSAddrTable["PMA"].to_list() 464 sramColList = self._sramQSAddrTable["QS col"].to_list() 465 466 if len(tcamRowList) == len(sramColList): 467 for (queryStr, pma, qsCol) in itertools.zip_longest(sramAddrList, tcamRowList, sramColList): 468 # * create sram table subsections based on query str 469 tempSRAMTable = sramDF.iloc[self.__sramRowVec[qsCol], self.__sramCols] 470 logging.info("Search Query mapping portion: %d", qsCol) 471 printDebug(debug, f"Search Query mapping portion: {qsCol}") 472 # print(tabulate(tempSRAMTable,headers='keys',tablefmt='github'),'\n') 473 # * find specific mapping cell in sram table 474 rowIndex = tempSRAMTable.index[tempSRAMTable["Addresses"] == queryStr].to_list()[0] 475 colIndex = len(self.__sramCols) - pma - 1 476 # print('sram rowIndex: ',rowIndex,type(rowIndex)) 477 # print('sram colIndex: ',colIndex,type(colIndex)) 478 # * find specific entry 479 oldSramTableEntry = sramDF.iloc[rowIndex, colIndex] 480 # print(sramDF.iloc[rowIndex,colIndex]) 481 # * replace specific entry 482 sramDF.iat[rowIndex, colIndex] = 1 483 # * print before and after 484 if verbose or debug: 485 logging.info("SRAM table cell [%d, %d] | Value = %s -> %s", rowIndex, colIndex, oldSramTableEntry, sramDF.iat[rowIndex, colIndex]) 486 printDebug(debug, f"SRAM table cell [{rowIndex}, {colIndex}] | Value = {oldSramTableEntry} -> {sramDF.iat[rowIndex,colIndex]}") 487 # * add zeros in empty cells 488 sramDF = sramDF.fillna(0) 489 self._sramTable = sramDF 490 else: 491 logging.error('"MATCH NOT FOUND": TCAM table rows != SRAM table cols config potMatchAddr') 492 sys.exit('"MATCH NOT FOUND": MISMATCH in TCAM table map and YAML config rows/cols') 493 494 def writeSRAMtoXlsx(self): 495 """ 496 Generates an SRAM table map in XLSX format. 497 498 :return str: absolute path of the SRAM table map `.xlsx` file. 499 """ 500 # * create sram table file path and name 501 self.sramTableXlsxFileName = os.path.basename(self.tcamTableXlsxFileName.replace("tcam", "sram")) 502 self.sramTableXlsxFilePath = os.path.join(self.sramTableDir, self.sramTableXlsxFileName) 503 # * create excel file in dir sramTables 504 # writer = pd.ExcelWriter(self.sramTableXlsxFilePath,engine='xlsxwriter') 505 # writer.save() 506 # * apply formatting to dataframe 507 self._sramTable.style.applymap(highlightCell).to_excel( 508 excel_writer=self.sramTableXlsxFilePath, sheet_name=self.sramTableXlsxFileName, na_rep="", header=True, index=True, engine="openpyxl" 509 ) 510 logging.info("Created SRAM table XLSX file: %s", self.sramTableXlsxFilePath) 511 print("Created SRAM table XLSX file: %s", self.sramTableXlsxFilePath) 512 return self.sramTableXlsxFilePath 513 514 def writeSRAMtoHtml(self): 515 """ 516 Generates an SRAM table map in HTML format. 517 518 :return str: absolute path of the SRAM table map `.html` file. 519 """ 520 # * create sram table file path and name 521 self.sramTableHtmlFileName = os.path.basename(self.tcamTableXlsxFileName.replace("tcam", "sram").replace(".xlsx", ".html")) 522 self.sramTableHtmlFilePath = os.path.join(self.sramTableDir, self.sramTableHtmlFileName) 523 # * create html file in dir sramTables 524 self._sramTable.to_html(self.sramTableHtmlFilePath, index=True, header=True, justify="center", classes="table table-stripped") 525 logging.info("Created SRAM table HTML file: %s", self.sramTableHtmlFilePath) 526 print("Created SRAM table HTML file: %s", self.sramTableHtmlFilePath) 527 return self.sramTableHtmlFilePath 528 529 def writeSRAMtoJson(self): 530 """ 531 Generates an SRAM table map in JSON format. 532 533 :return str: absolute path of the SRAM table map `.json` file. 534 """ 535 # * create sram table file path and name 536 self.sramTableJsonFileName = os.path.basename(self.tcamTableXlsxFileName.replace("tcam", "sram").replace(".xlsx", ".json")) 537 self.sramTableJsonFilePath = os.path.join(self.sramTableDir, self.sramTableJsonFileName) 538 # * create json file in dir sramTables 539 self._sramTable.to_json(self.sramTableJsonFilePath, orient="index", indent=4) 540 logging.info("Created SRAM table JSON file: %s", self.sramTableJsonFilePath) 541 print("Created SRAM table JSON file: %s", self.sramTableJsonFilePath) 542 return self.sramTableJsonFilePath 543 544 def writeSRAMtoTxt(self): 545 """ 546 Generates an SRAM table map in TXT format. 547 548 :return str: absolute path of the SRAM table map `.txt` file. 549 """ 550 # * create sram table file path and name 551 self.sramTableTxtFileName = os.path.basename(self.tcamTableXlsxFileName.replace("tcam", "sram").replace(".xlsx", ".txt")) 552 self.sramTableTxtFilePath = os.path.join(self.sramTableDir, self.sramTableTxtFileName) 553 # * create txt file in dir sramTables 554 myTable = tabulate(self._sramTable, headers="keys", showindex=True, disable_numparse=True, tablefmt="github") 555 with open(self.sramTableTxtFilePath, "w", encoding="utf-8") as file: 556 file.write(myTable) 557 logging.info("Created SRAM table Txt file: %s", self.sramTableTxtFilePath) 558 print("Created SRAM table Txt file: %s", self.sramTableTxtFilePath) 559 return self.sramTableTxtFilePath 560 561 562# =========================================================================================== 563# ======================================== End Class ======================================== 564# =========================================================================================== 565 566 567def printVerbose(verbose, msg): 568 """ 569 Prints a string if verbose flag is active. 570 571 :param int verbose: print information in verbose mode. 572 :param str msg: Message to be printed in verbose mode. 573 """ 574 if verbose: 575 print(str(msg)) 576 577 578def printDebug(debug, msg): 579 """ 580 Prints a string if debug flag is active. 581 582 :param int debug: print information in debug mode. 583 :param str msg: Message to be printed in debug mode. 584 """ 585 if debug: 586 print(str(msg)) 587 588 589def highlightCell(val): 590 """ 591 Colors SRAM table map cells in XLSX file depending upon their value. 592 593 :param int val: numerical value of a particular cell. 594 :return str: cell background color code as a hex RBG value. 595 """ 596 if val == 1: 597 color = "#E5961A" 598 elif val == 0: 599 color = "#E4EA15" 600 else: 601 color = "#D8C05A" 602 return f"background-color: {color}"
25class TableMapping: 26 """ 27 Generates a golden model for a particular SRAM memory table map config 28 using a respective TCAM memory table map and configs. 29 """ 30 31 # * ----------------------------------------------------------------- Variables 32 def __init__(self): 33 """ 34 Constructor: Initializes all the class variables 35 36 **Public Variables:** 37 :param str prjWorkDir: current project working dir 38 :param str sramTableDir: abs path of SRAM table map folder 39 :param str tcamTableConfigsFilePath: abs path of TCAM table map config file 40 :param str tcamTableConfigsFileName: TCAM table map config file name 41 :param str tcamTableXlsxFilePath: abs path of TCAM table map XLSX file 42 :param str tcamTableXlsxFileName: TCAM table map XLSX file name 43 :param str sramTableXlsxFilePath: abs path of generated SRAM table map XLSX file 44 :param str sramTableXlsxFileName: SRAM table map XLSX file name 45 :param str sramTableHtmlFilePath: abs path of generated SRAM table map HTML file 46 :param str sramTableHtmlFileName: SRAM table map HTML file name 47 :param str sramTableJsonFilePath: abs path of generated SRAM table map JSON file 48 :param str sramTableJsonFileName: SRAM table map JSON file name 49 :param str sramTableTxtFilePath: abs path of generated SRAM table map TXT file 50 :param str sramTableTxtFileName: SRAM table map TXT file name 51 52 **Protected Variables:** 53 :param dict _tcamTableConfigs: TCAM table map configs 54 :param DataFrame _tcamTable: TCAM table map 55 :param DataFrame _sramTable: SRAM table map 56 :param DataFrame _tcamQSAddrTable: TCAM table map query addr sub str 57 :param DataFrame _sramQSAddrTable: SRAM table map query addr sub str 58 59 **Private Variables:** 60 :param int __tcamQueryStrLen: `queryStrLen` of a particular TCAM table config 61 :param int __tcamSubStrLen: `subStrLen` of a particular TCAM table config 62 :param int __tcamTotalSubStr: `totalSubStr` of a particular TCAM table config 63 :param int __tcamPotMatchAddr: `potMatchAddr` of a particular TCAM table config 64 :param int __sramTableRows: SRAM table map row count 65 :param int __sramTableCols: SRAM table map col count 66 :param list __tcamRows: TCAM table map row count vector 67 :param list __tcamCols: TCAM table map col count vector 68 :param list __tcamColVec: TCAM table map sub string address col count vector 69 :param list __sramRows: SRAM table map row count vector 70 :param list __sramRowVec: SRAM table map sub string address row count vector 71 :param list __sramCols: SRAM table map col count vector 72 """ 73 # * ------------------- public vars 74 self.prjWorkDir = "" 75 self.sramTableDir = "" 76 self.tcamTableConfigsFilePath = "" 77 self.tcamTableConfigsFileName = "" 78 self.tcamTableXlsxFilePath = "" 79 self.tcamTableXlsxFileName = "" 80 self.sramTableXlsxFilePath = "" 81 self.sramTableXlsxFileName = "" 82 self.sramTableHtmlFilePath = "" 83 self.sramTableHtmlFileName = "" 84 self.sramTableJsonFilePath = "" 85 self.sramTableJsonFileName = "" 86 self.sramTableTxtFilePath = "" 87 self.sramTableTxtFileName = "" 88 # * ------------------- protected vars 89 self._tcamTableConfigs = {} 90 self._tcamTable = pd.DataFrame 91 self._sramTable = pd.DataFrame 92 self._tcamQSAddrTable = pd.DataFrame 93 self._sramQSAddrTable = pd.DataFrame 94 # * ------------------- private vars 95 self.__tcamQueryStrLen = 0 96 self.__tcamSubStrLen = 0 97 self.__tcamTotalSubStr = 0 98 self.__tcamPotMatchAddr = 0 99 self.__sramTableRows = 0 100 self.__sramTableCols = 0 101 self.__tcamRows = [] 102 self.__tcamCols = [] 103 self.__tcamColVec = [] 104 self.__sramRows = [] 105 self.__sramRowVec = [] 106 self.__sramCols = [] 107 # * logging config 108 logging.basicConfig( 109 level=logging.DEBUG, 110 filename="./logs/tableMapping.log", 111 format="%(asctime)s | %(filename)s | %(funcName)s | %(levelname)s | %(lineno)d | %(message)s", 112 ) 113 114 # * ----------------------------------------------------------------- Functions 115 def getPrjDir(self, verbose): 116 """ 117 Obtain the absolute path of the current working directory. 118 119 :param int verbose: print information in verbose mode. 120 :return str: absolute path of the current project working directory. 121 """ 122 self.prjWorkDir = os.getcwd() 123 logging.info("Project working dir: %s", self.prjWorkDir) 124 printVerbose(verbose, f"Project working dir: {self.prjWorkDir}") 125 return self.prjWorkDir 126 127 def getYAMLFilePath(self, verbose): 128 """ 129 Obtain the absolute path of file tcamTables.yaml. 130 131 :param int verbose: print information in verbose mode. 132 :return str: absolute path of the current project working directory. 133 """ 134 # * get tcamTables config file path 135 tempPath = os.path.join(self.prjWorkDir, "compiler/configs/tcamTables.yaml") 136 if os.path.isfile(tempPath) is True: 137 self.tcamTableConfigsFilePath = tempPath 138 self.tcamTableConfigsFileName = os.path.basename(tempPath) 139 logging.info('"FOUND": TCAM table config file path: %s', self.tcamTableConfigsFilePath) 140 printVerbose(verbose, f'"FOUND": TCAM table config file path: {self.tcamTableConfigsFilePath}') 141 return self.tcamTableConfigsFilePath 142 logging.error('"NOT FOUND": TCAM table config file path: %s', self.tcamTableConfigsFilePath) 143 sys.exit(f'"NOT FOUND": TCAM table config file path: {self.tcamTableConfigsFilePath}') 144 145 def readYAML(self, filePath, verbose): 146 """ 147 Read a particular YAML config file 148 149 :param str filePath: absolute path of file tcamTables.yaml. 150 :param int verbose: print information in verbose mode. 151 :return dict: dictionary containing all the TCAM table configs. 152 """ 153 with open(filePath, encoding="utf-8") as file: 154 self._tcamTableConfigs = yaml.full_load(file) 155 # print(json.dumps(self._tcamTableConfigs,indent=4)) 156 # print(yaml.dump(self._tcamTableConfigs,sort_keys=False,default_flow_style=False)) 157 logging.info("Read TCAM table config file: %s", self.tcamTableConfigsFilePath) 158 printVerbose(verbose, f"Read TCAM table config file: {self.tcamTableConfigsFilePath}") 159 return self._tcamTableConfigs 160 161 def printYAML(self, debug): 162 """ 163 Print all present configs of a YAML file either in JSON or YAML style. 164 165 :param int debug: print information in debug mode. 166 """ 167 printDebug(debug, "Printing TCAM table configs") 168 print(json.dumps(self._tcamTableConfigs, indent=4)) 169 # print(yaml.dump(self._tcamTableConfigs,sort_keys=False,default_flow_style=False)) 170 logging.info("Printed TCAM table configs") 171 172 def getTCAMConfig(self, tcamConfig): 173 """ 174 Check if a particular tcamTable config exists in file tcamTables.yaml. If found store the config params in vars. 175 - **__tcamQueryStrLen:** saves `queryStrLen` 176 - **__tcamSubStrLen:** saves `subStrLen` 177 - **__tcamTotalSubStr:** saves `totalSubStr` 178 - **__tcamPotMatchAddr:** saves `potMatchAddr` 179 180 :param str tcamConfig: TCAM table config name e.g. tcamTableX 181 :return dict: dictionary containing the respective table map config. 182 """ 183 # * look for specific tcam config in compiler/configs/tcamTables.yaml 184 if tcamConfig in self._tcamTableConfigs.keys(): 185 tempConfig = self._tcamTableConfigs[tcamConfig] 186 # * save tcam config vars 187 self.__tcamQueryStrLen = tempConfig["queryStrLen"] 188 self.__tcamSubStrLen = tempConfig["subStrLen"] 189 self.__tcamTotalSubStr = tempConfig["totalSubStr"] 190 self.__tcamPotMatchAddr = tempConfig["potMatchAddr"] 191 # * print specific tcam config 192 # print(type(tempConfig)) 193 logging.info('"FOUND" Required TCAM Config [%s]', tcamConfig) 194 print('"FOUND" Required TCAM Config [%s]', tcamConfig) 195 logging.info("TCAM Config Data [%s] = %s", tcamConfig, tempConfig) 196 return tempConfig 197 logging.error('"NOT FOUND": TCAM Config [%s]', tcamConfig) 198 sys.exit(f'"NOT FOUND": Required TCAM table config [{tcamConfig}]') 199 200 def getTCAMTableFilePath(self, tcamConfig, verbose): 201 """ 202 Obtain the absolute path of file **tcamTableX.xlsx** which represents the TCAM memory table map. 203 204 :param str tcamConfig: TCAM table config name e.g. tcamTableX 205 :param int verbose: print information in verbose mode. 206 :return str: absolute path of the TCAM table mapping file. 207 """ 208 # * find the specific tcam table map in compiler/lib/ 209 tempPath = os.path.join(self.prjWorkDir, "compiler/lib/" + tcamConfig + ".xlsx") 210 if os.path.isfile(tempPath) is True: 211 self.tcamTableXlsxFilePath = tempPath 212 self.tcamTableXlsxFileName = os.path.basename(tempPath) 213 logging.info('"FOUND" TCAM table map XLSX file path: %s', self.tcamTableXlsxFilePath) 214 printVerbose(verbose, f'"FOUND" TCAM table map XLSX file path: {self.tcamTableXlsxFilePath}') 215 return self.tcamTableXlsxFilePath 216 logging.error('"NOT FOUND": TCAM table map XLSX file path: %s', self.tcamTableXlsxFilePath) 217 sys.exit(f'"NOT FOUND": TCAM table map XLSX file path {self.tcamTableXlsxFilePath}') 218 219 def printDF(self, dataFrame, heading): 220 """ 221 Display the contents of a particular data frame. 222 223 :param DataFrame dataFrame: particular data frame object. 224 :param str heading: Title above data frame. 225 """ 226 print("\n") 227 print("Printing dataframe: %s", heading) 228 print(tabulate(dataFrame, headers="keys", showindex=True, disable_numparse=True, tablefmt="github"), "\n") 229 logging.info("Printing dataframe: %s", str(heading)) 230 231 def getTcamTableMap(self): 232 """ 233 Getter function for the TCAM table map 234 235 :return DataFrame: TCAM table map dataframe object 236 """ 237 return self._tcamTable 238 239 def getSramTableMap(self): 240 """ 241 Getter function for the SRAM table map 242 243 :return DataFrame: SRAM table map dataframe object 244 """ 245 return self._sramTable 246 247 def readTCAMTable(self, verbose): 248 """ 249 Read the contents of a **tcamTableX.xlsx** TCAM memory table map as a data frame. 250 251 :param int verbose: print information in verbose mode. 252 :return int: list containing dimensions of TCAM table memory map. 253 """ 254 # * store tcam table in dataframe 255 self._tcamTable = pd.read_excel(self.tcamTableXlsxFilePath, skiprows=2, index_col=None, engine="openpyxl") 256 # * get num of rows and col from tcam table 257 tcamTableRows = self._tcamTable.shape[0] 258 tcamTableCols = self._tcamTable.shape[1] 259 # * compare row/col of tcam table with respective yaml config 260 if tcamTableRows == self.__tcamPotMatchAddr and tcamTableCols - 1 == self.__tcamQueryStrLen: 261 logging.info('"MATCH FOUND": TCAM table map rows == TCAM table YAML config potMatchAddr') 262 printVerbose(verbose, '"MATCH FOUND": TCAM table map rows == TCAM table YAML config potMatchAddr') 263 logging.info('"MATCH FOUND": TCAM table map cols == TCAM table YAML config queryStrLen') 264 printVerbose(verbose, '"MATCH FOUND": TCAM table map cols == TCAM table YAML config queryStrLen') 265 return [tcamTableRows, tcamTableCols] 266 logging.error('"MATCH NOT FOUND": TCAM table map rows != TCAM table YAML config potMatchAddr') 267 logging.error('"MATCH NOT FOUND": TCAM table map cols != TCAM table YAML config queryStrLen') 268 sys.exit('"MATCH NOT FOUND": MISMATCH in TCAM table map and YAML config rows/cols') 269 270 def getSRAMTableDim(self, verbose): 271 """ 272 Generate the dimensions of the SRAM table map data frame using TCAM table map configs. 273 274 :param int verbose: print information in verbose mode. 275 :return int: list containing dimensions of SRAM table memory map. 276 """ 277 self.__sramTableRows = self.__tcamTotalSubStr * pow(2, self.__tcamSubStrLen) 278 self.__sramTableCols = self.__tcamPotMatchAddr 279 logging.info("SRAM table rows [{%4d}] cols [{%4d}]", self.__sramTableRows, self.__sramTableCols) 280 printVerbose(verbose, f"SRAM table rows [{self.__sramTableRows}] cols [{self.__sramTableCols}]") 281 return [self.__sramTableRows, self.__sramTableCols] 282 283 def genSRAMTable(self, verbose): 284 """ 285 Create an empty SRAM table map data frame containing respective row addresses and column headings. 286 287 :param int verbose: print information in verbose mode. 288 """ 289 # * create temp vars 290 sramTableAddrList = [] 291 sramColHeadings = [] 292 # * create row address 293 for i in range(self.__tcamTotalSubStr): 294 for j in range(2**self.__tcamSubStrLen): 295 padding = "0" + str(self.__tcamSubStrLen) + "b" 296 # sramTableAddrList.append(format(j, '#012b')) # with 0b prefix 297 sramTableAddrList.append(format(j, padding)) # without 0b prefix 298 logging.info("Created [{%4d}] SRAM addresses from search query [{%4d}]", j + 1, i) 299 printVerbose(verbose, f"Created [{j+1}] SRAM addresses from search query [{i}]") 300 # * create col headings 301 for k in reversed(range(self.__tcamPotMatchAddr)): 302 heading = "D" + str(k) 303 sramColHeadings.append(heading) 304 logging.info("Created column heading %s", heading) 305 # * gen empty m*n sram table 306 self._sramTable = pd.DataFrame(index=np.arange(self.__sramTableRows), columns=np.arange(self.__sramTableCols)) 307 # * rename column headings 308 self._sramTable.columns = sramColHeadings 309 # * insert addr col at position 0 310 self._sramTable.insert(0, "Addresses", sramTableAddrList, allow_duplicates=True) 311 logging.info("Created empty [%d x %d] SRAM table", self._sramTable.shape[0], self._sramTable.shape[1]) 312 printVerbose(verbose, f"Created empty [{self._sramTable.shape[0]} x {self._sramTable.shape[1]}] SRAM table") 313 314 def createSRAMTableDir(self, verbose): 315 """ 316 Create a directory to store SRAM table maps in various formats. 317 318 :param int verbose: print information in verbose mode. 319 :return str: absolute path of the SRAM table map directory. 320 """ 321 # * create sramTables dir if it doesn't exist 322 self.sramTableDir = os.path.join(self.prjWorkDir, "sramTables") 323 if os.path.exists(self.sramTableDir) is False: 324 os.makedirs("sramTables") 325 logging.info("Created sramTables dir: %s", self.sramTableDir) 326 printVerbose(verbose, f"Created sramTables dir: {self.sramTableDir}") 327 return self.sramTableDir 328 329 def splitRowsAndCols(self, debug): 330 """ 331 Create TCAM and SRAM table map row and column vectors based on TCAM table config parameters. 332 333 :param int debug: print information in debug mode. 334 :return list: list containing TCAM and SRAM row and column vectors. 335 """ 336 # * store tcam and sram table in temp vars 337 tcamDF = self._tcamTable 338 sramDF = self._sramTable 339 logging.info("TCAM table (r*c): %s", tuple(tcamDF.shape)) 340 logging.info("SRAM table (r*c): %s", tuple(sramDF.shape)) 341 # * create tcamRows vector 342 self.__tcamRows = np.arange(0, self.__tcamPotMatchAddr, 1).tolist() 343 logging.info("TCAM table row vector: %s", list(self.__tcamRows)) 344 printDebug(debug, f"TCAM table row vector: {*self.__tcamRows,}") 345 # * create tcamCols vector 346 self.__tcamCols = np.arange(1, self.__tcamQueryStrLen + 1, 1).tolist() 347 logging.info("TCAM table col vector: %s", list(self.__tcamCols)) 348 printDebug(debug, f"TCAM table col vector: {*self.__tcamCols,}") 349 # * create tcamColVec vector and split in equal pieces 350 self.__tcamColVec = np.array_split(self.__tcamCols, self.__tcamTotalSubStr) 351 for i in range(len(self.__tcamColVec)): 352 self.__tcamColVec[i] = self.__tcamColVec[i].tolist() 353 logging.info("TCAM table col split vector [%d]: %s", i, list(self.__tcamColVec[i])) 354 printDebug(debug, f"TCAM table col split vector [{i}]: {self.__tcamColVec[i]}") 355 # * create sramRows vector 356 self.__sramRows = np.arange(0, self.__tcamTotalSubStr * 2**self.__tcamSubStrLen, 1).tolist() 357 logging.info("SRAM table row vector: %s", list(self.__sramRows)) 358 printDebug(debug, f"SRAM table row vector: {self.__sramRows}") 359 # * create sramRowVec vector and split in equal pieces 360 self.__sramRowVec = np.array_split(self.__sramRows, self.__tcamTotalSubStr) 361 for i in range(len(self.__sramRowVec)): 362 self.__sramRowVec[i] = self.__sramRowVec[i].tolist() 363 logging.info("SRAM table row split vector [%d]: %s", i, list(self.__sramRowVec[i])) 364 printDebug(debug, f"SRAM table row split vector [{i}]: {self.__sramRowVec[i]}") 365 # * create sramCols vector 366 self.__sramCols = np.arange(0, self.__tcamPotMatchAddr + 1, 1).tolist() 367 logging.info("SRAM table col vector: %s", list(self.__sramCols)) 368 printDebug(debug, f"SRAM table col vector: {self.__sramCols}") 369 return [self.__tcamRows, self.__tcamColVec, self.__sramRowVec, self.__sramCols] 370 371 def isolateTCAMSearchQueries(self, verbose, debug): 372 """ 373 Create a data frame containing all the sub strings in original format from all the TCAM table search queries. 374 375 :param int verbose: print information in verbose mode. 376 :param int debug: print information in debug mode. 377 """ 378 tcamDF = self._tcamTable 379 count1 = 0 380 self._tcamQSAddrTable = pd.DataFrame(columns=["TCAM Query Str Addr", "PMA", "QS col"]) 381 382 # * ----- add all original search queries in dataframe 383 # * iterate through tcam table rows 384 for row in range(len(tcamDF)): 385 # * iterate through tcam table cols 386 for col in range(len(self.__tcamColVec)): 387 # * search and concat search query string address in tcam table 388 tempAddr = [str(c) for c in list(tcamDF.iloc[row, self.__tcamColVec[col]])] 389 tempAddr = "".join(tempAddr) 390 # * append row in sqSubStrAddrDf data frame 391 tempRow = [tempAddr, row, col] 392 self._tcamQSAddrTable.loc[count1] = tempRow 393 count1 += 1 394 logging.info("TCAM Search Queries Table | Addr: %s | TCAM Row: %5d | Sub String Col: %5d |", tempAddr, row, col) 395 printDebug(debug, f"TCAM Search Queries Table | Addr: {tempAddr} | TCAM Row: {row} | Sub String Col: {col} |") 396 if verbose: 397 self.printDF(self._tcamQSAddrTable, "Original TCAM Search Query Address Table") 398 399 def generateSRAMSubStr(self, verbose, debug): 400 """ 401 Generate all possible combinations of all sub strings from the original TCAM table search queries. 402 403 :param int verbose: print information in verbose mode. 404 :param int debug: print information in debug mode. 405 """ 406 count2 = 0 407 self._sramQSAddrTable = pd.DataFrame(columns=["SRAM Query Str Addr", "PMA", "QS col"]) 408 409 # * ----- find all possible alternatives for X based addr 410 # * create array of N bit bin addresses 411 queryStrBinAddrList = np.arange(2**self.__tcamSubStrLen).tolist() 412 padding = "0" + str(self.__tcamSubStrLen) + "b" 413 for item in queryStrBinAddrList: 414 dec2Bin = format(item, padding) 415 queryStrBinAddrList = queryStrBinAddrList[:item] + [dec2Bin] + queryStrBinAddrList[item + 1 :] 416 logging.info("N bit bin addr list: %s", list(queryStrBinAddrList)) 417 logging.info("N bit bin addr list len: %d", len(queryStrBinAddrList)) 418 if verbose or debug: 419 print("N bit bin addr list: %s", list(queryStrBinAddrList)) 420 print("N bit bin addr list len: %d", len(queryStrBinAddrList)) 421 422 # * get origSQ addr 423 tempQSAddrList = self._tcamQSAddrTable["TCAM Query Str Addr"].to_list() 424 tempQSPmaList = self._tcamQSAddrTable["PMA"].to_list() 425 tempQSColList = self._tcamQSAddrTable["QS col"].to_list() 426 427 printDebug(debug, f"Search Query addr list: {tempQSAddrList}") 428 printDebug(debug, f"Search Query addr list len: {len(tempQSAddrList)}\n") 429 # * map the 'bX in search queries to 0 and 1 430 for (oldAddr, pma, qscol) in zip(tempQSAddrList, tempQSPmaList, tempQSColList): 431 # * if 'bX in search query then find all possible alternatives and add in table 432 if "x" in oldAddr: 433 for newAddr in queryStrBinAddrList: 434 matching = jellyfish.damerau_levenshtein_distance(oldAddr, newAddr) 435 if matching == len(re.findall("x", oldAddr)): 436 printVerbose( 437 verbose, 438 f"count = {count2} | orig Search Query = {oldAddr} | " f"new Search Query = {newAddr} | matching ratio = {matching} |", 439 ) 440 logging.info( 441 "count = %d | orig Search Query = %s | new Search Query = %s | matching ratio = %f |", count2, oldAddr, newAddr, matching 442 ) 443 self._sramQSAddrTable.loc[count2] = [newAddr, pma, qscol] 444 count2 += 1 445 # * else simply add search query in table as is 446 else: 447 printVerbose(verbose, f"count = {count2} | orig Search Query = {oldAddr} | new Search Query = {oldAddr} | matching ratio = {0} |") 448 logging.info("count = %d | orig Search Query = %s | new Search Query = %s | matching ratio = %f |", count2, oldAddr, oldAddr, 0) 449 self._sramQSAddrTable.loc[count2] = [oldAddr, pma, qscol] 450 count2 += 1 451 452 if verbose: 453 self.printDF(self._sramQSAddrTable, "Original SRAM Search Query Address Table") 454 455 def mapTCAMtoSRAM(self, verbose, debug): 456 """ 457 Map all possible combinations of TCAM table map sub strings to SRAM table map sub strings. 458 459 :param int verbose: print information in verbose mode. 460 :param int debug: print information in debug mode. 461 """ 462 sramDF = self._sramTable 463 sramAddrList = self._sramQSAddrTable["SRAM Query Str Addr"].to_list() 464 tcamRowList = self._sramQSAddrTable["PMA"].to_list() 465 sramColList = self._sramQSAddrTable["QS col"].to_list() 466 467 if len(tcamRowList) == len(sramColList): 468 for (queryStr, pma, qsCol) in itertools.zip_longest(sramAddrList, tcamRowList, sramColList): 469 # * create sram table subsections based on query str 470 tempSRAMTable = sramDF.iloc[self.__sramRowVec[qsCol], self.__sramCols] 471 logging.info("Search Query mapping portion: %d", qsCol) 472 printDebug(debug, f"Search Query mapping portion: {qsCol}") 473 # print(tabulate(tempSRAMTable,headers='keys',tablefmt='github'),'\n') 474 # * find specific mapping cell in sram table 475 rowIndex = tempSRAMTable.index[tempSRAMTable["Addresses"] == queryStr].to_list()[0] 476 colIndex = len(self.__sramCols) - pma - 1 477 # print('sram rowIndex: ',rowIndex,type(rowIndex)) 478 # print('sram colIndex: ',colIndex,type(colIndex)) 479 # * find specific entry 480 oldSramTableEntry = sramDF.iloc[rowIndex, colIndex] 481 # print(sramDF.iloc[rowIndex,colIndex]) 482 # * replace specific entry 483 sramDF.iat[rowIndex, colIndex] = 1 484 # * print before and after 485 if verbose or debug: 486 logging.info("SRAM table cell [%d, %d] | Value = %s -> %s", rowIndex, colIndex, oldSramTableEntry, sramDF.iat[rowIndex, colIndex]) 487 printDebug(debug, f"SRAM table cell [{rowIndex}, {colIndex}] | Value = {oldSramTableEntry} -> {sramDF.iat[rowIndex,colIndex]}") 488 # * add zeros in empty cells 489 sramDF = sramDF.fillna(0) 490 self._sramTable = sramDF 491 else: 492 logging.error('"MATCH NOT FOUND": TCAM table rows != SRAM table cols config potMatchAddr') 493 sys.exit('"MATCH NOT FOUND": MISMATCH in TCAM table map and YAML config rows/cols') 494 495 def writeSRAMtoXlsx(self): 496 """ 497 Generates an SRAM table map in XLSX format. 498 499 :return str: absolute path of the SRAM table map `.xlsx` file. 500 """ 501 # * create sram table file path and name 502 self.sramTableXlsxFileName = os.path.basename(self.tcamTableXlsxFileName.replace("tcam", "sram")) 503 self.sramTableXlsxFilePath = os.path.join(self.sramTableDir, self.sramTableXlsxFileName) 504 # * create excel file in dir sramTables 505 # writer = pd.ExcelWriter(self.sramTableXlsxFilePath,engine='xlsxwriter') 506 # writer.save() 507 # * apply formatting to dataframe 508 self._sramTable.style.applymap(highlightCell).to_excel( 509 excel_writer=self.sramTableXlsxFilePath, sheet_name=self.sramTableXlsxFileName, na_rep="", header=True, index=True, engine="openpyxl" 510 ) 511 logging.info("Created SRAM table XLSX file: %s", self.sramTableXlsxFilePath) 512 print("Created SRAM table XLSX file: %s", self.sramTableXlsxFilePath) 513 return self.sramTableXlsxFilePath 514 515 def writeSRAMtoHtml(self): 516 """ 517 Generates an SRAM table map in HTML format. 518 519 :return str: absolute path of the SRAM table map `.html` file. 520 """ 521 # * create sram table file path and name 522 self.sramTableHtmlFileName = os.path.basename(self.tcamTableXlsxFileName.replace("tcam", "sram").replace(".xlsx", ".html")) 523 self.sramTableHtmlFilePath = os.path.join(self.sramTableDir, self.sramTableHtmlFileName) 524 # * create html file in dir sramTables 525 self._sramTable.to_html(self.sramTableHtmlFilePath, index=True, header=True, justify="center", classes="table table-stripped") 526 logging.info("Created SRAM table HTML file: %s", self.sramTableHtmlFilePath) 527 print("Created SRAM table HTML file: %s", self.sramTableHtmlFilePath) 528 return self.sramTableHtmlFilePath 529 530 def writeSRAMtoJson(self): 531 """ 532 Generates an SRAM table map in JSON format. 533 534 :return str: absolute path of the SRAM table map `.json` file. 535 """ 536 # * create sram table file path and name 537 self.sramTableJsonFileName = os.path.basename(self.tcamTableXlsxFileName.replace("tcam", "sram").replace(".xlsx", ".json")) 538 self.sramTableJsonFilePath = os.path.join(self.sramTableDir, self.sramTableJsonFileName) 539 # * create json file in dir sramTables 540 self._sramTable.to_json(self.sramTableJsonFilePath, orient="index", indent=4) 541 logging.info("Created SRAM table JSON file: %s", self.sramTableJsonFilePath) 542 print("Created SRAM table JSON file: %s", self.sramTableJsonFilePath) 543 return self.sramTableJsonFilePath 544 545 def writeSRAMtoTxt(self): 546 """ 547 Generates an SRAM table map in TXT format. 548 549 :return str: absolute path of the SRAM table map `.txt` file. 550 """ 551 # * create sram table file path and name 552 self.sramTableTxtFileName = os.path.basename(self.tcamTableXlsxFileName.replace("tcam", "sram").replace(".xlsx", ".txt")) 553 self.sramTableTxtFilePath = os.path.join(self.sramTableDir, self.sramTableTxtFileName) 554 # * create txt file in dir sramTables 555 myTable = tabulate(self._sramTable, headers="keys", showindex=True, disable_numparse=True, tablefmt="github") 556 with open(self.sramTableTxtFilePath, "w", encoding="utf-8") as file: 557 file.write(myTable) 558 logging.info("Created SRAM table Txt file: %s", self.sramTableTxtFilePath) 559 print("Created SRAM table Txt file: %s", self.sramTableTxtFilePath) 560 return self.sramTableTxtFilePath
Generates a golden model for a particular SRAM memory table map config using a respective TCAM memory table map and configs.
32 def __init__(self): 33 """ 34 Constructor: Initializes all the class variables 35 36 **Public Variables:** 37 :param str prjWorkDir: current project working dir 38 :param str sramTableDir: abs path of SRAM table map folder 39 :param str tcamTableConfigsFilePath: abs path of TCAM table map config file 40 :param str tcamTableConfigsFileName: TCAM table map config file name 41 :param str tcamTableXlsxFilePath: abs path of TCAM table map XLSX file 42 :param str tcamTableXlsxFileName: TCAM table map XLSX file name 43 :param str sramTableXlsxFilePath: abs path of generated SRAM table map XLSX file 44 :param str sramTableXlsxFileName: SRAM table map XLSX file name 45 :param str sramTableHtmlFilePath: abs path of generated SRAM table map HTML file 46 :param str sramTableHtmlFileName: SRAM table map HTML file name 47 :param str sramTableJsonFilePath: abs path of generated SRAM table map JSON file 48 :param str sramTableJsonFileName: SRAM table map JSON file name 49 :param str sramTableTxtFilePath: abs path of generated SRAM table map TXT file 50 :param str sramTableTxtFileName: SRAM table map TXT file name 51 52 **Protected Variables:** 53 :param dict _tcamTableConfigs: TCAM table map configs 54 :param DataFrame _tcamTable: TCAM table map 55 :param DataFrame _sramTable: SRAM table map 56 :param DataFrame _tcamQSAddrTable: TCAM table map query addr sub str 57 :param DataFrame _sramQSAddrTable: SRAM table map query addr sub str 58 59 **Private Variables:** 60 :param int __tcamQueryStrLen: `queryStrLen` of a particular TCAM table config 61 :param int __tcamSubStrLen: `subStrLen` of a particular TCAM table config 62 :param int __tcamTotalSubStr: `totalSubStr` of a particular TCAM table config 63 :param int __tcamPotMatchAddr: `potMatchAddr` of a particular TCAM table config 64 :param int __sramTableRows: SRAM table map row count 65 :param int __sramTableCols: SRAM table map col count 66 :param list __tcamRows: TCAM table map row count vector 67 :param list __tcamCols: TCAM table map col count vector 68 :param list __tcamColVec: TCAM table map sub string address col count vector 69 :param list __sramRows: SRAM table map row count vector 70 :param list __sramRowVec: SRAM table map sub string address row count vector 71 :param list __sramCols: SRAM table map col count vector 72 """ 73 # * ------------------- public vars 74 self.prjWorkDir = "" 75 self.sramTableDir = "" 76 self.tcamTableConfigsFilePath = "" 77 self.tcamTableConfigsFileName = "" 78 self.tcamTableXlsxFilePath = "" 79 self.tcamTableXlsxFileName = "" 80 self.sramTableXlsxFilePath = "" 81 self.sramTableXlsxFileName = "" 82 self.sramTableHtmlFilePath = "" 83 self.sramTableHtmlFileName = "" 84 self.sramTableJsonFilePath = "" 85 self.sramTableJsonFileName = "" 86 self.sramTableTxtFilePath = "" 87 self.sramTableTxtFileName = "" 88 # * ------------------- protected vars 89 self._tcamTableConfigs = {} 90 self._tcamTable = pd.DataFrame 91 self._sramTable = pd.DataFrame 92 self._tcamQSAddrTable = pd.DataFrame 93 self._sramQSAddrTable = pd.DataFrame 94 # * ------------------- private vars 95 self.__tcamQueryStrLen = 0 96 self.__tcamSubStrLen = 0 97 self.__tcamTotalSubStr = 0 98 self.__tcamPotMatchAddr = 0 99 self.__sramTableRows = 0 100 self.__sramTableCols = 0 101 self.__tcamRows = [] 102 self.__tcamCols = [] 103 self.__tcamColVec = [] 104 self.__sramRows = [] 105 self.__sramRowVec = [] 106 self.__sramCols = [] 107 # * logging config 108 logging.basicConfig( 109 level=logging.DEBUG, 110 filename="./logs/tableMapping.log", 111 format="%(asctime)s | %(filename)s | %(funcName)s | %(levelname)s | %(lineno)d | %(message)s", 112 )
Constructor: Initializes all the class variables
Public Variables:
Parameters
- str prjWorkDir: current project working dir
- str sramTableDir: abs path of SRAM table map folder
- str tcamTableConfigsFilePath: abs path of TCAM table map config file
- str tcamTableConfigsFileName: TCAM table map config file name
- str tcamTableXlsxFilePath: abs path of TCAM table map XLSX file
- str tcamTableXlsxFileName: TCAM table map XLSX file name
- str sramTableXlsxFilePath: abs path of generated SRAM table map XLSX file
- str sramTableXlsxFileName: SRAM table map XLSX file name
- str sramTableHtmlFilePath: abs path of generated SRAM table map HTML file
- str sramTableHtmlFileName: SRAM table map HTML file name
- str sramTableJsonFilePath: abs path of generated SRAM table map JSON file
- str sramTableJsonFileName: SRAM table map JSON file name
- str sramTableTxtFilePath: abs path of generated SRAM table map TXT file
- str sramTableTxtFileName: SRAM table map TXT file name
Protected Variables:
- dict _tcamTableConfigs: TCAM table map configs
- DataFrame _tcamTable: TCAM table map
- DataFrame _sramTable: SRAM table map
- DataFrame _tcamQSAddrTable: TCAM table map query addr sub str
- DataFrame _sramQSAddrTable: SRAM table map query addr sub str
Private Variables:
- int __tcamQueryStrLen:
queryStrLen
of a particular TCAM table config - int __tcamSubStrLen:
subStrLen
of a particular TCAM table config - int __tcamTotalSubStr:
totalSubStr
of a particular TCAM table config - int __tcamPotMatchAddr:
potMatchAddr
of a particular TCAM table config - int __sramTableRows: SRAM table map row count
- int __sramTableCols: SRAM table map col count
- list __tcamRows: TCAM table map row count vector
- list __tcamCols: TCAM table map col count vector
- list __tcamColVec: TCAM table map sub string address col count vector
- list __sramRows: SRAM table map row count vector
- list __sramRowVec: SRAM table map sub string address row count vector
- list __sramCols: SRAM table map col count vector
115 def getPrjDir(self, verbose): 116 """ 117 Obtain the absolute path of the current working directory. 118 119 :param int verbose: print information in verbose mode. 120 :return str: absolute path of the current project working directory. 121 """ 122 self.prjWorkDir = os.getcwd() 123 logging.info("Project working dir: %s", self.prjWorkDir) 124 printVerbose(verbose, f"Project working dir: {self.prjWorkDir}") 125 return self.prjWorkDir
Obtain the absolute path of the current working directory.
Parameters
- int verbose: print information in verbose mode.
Returns
absolute path of the current project working directory.
127 def getYAMLFilePath(self, verbose): 128 """ 129 Obtain the absolute path of file tcamTables.yaml. 130 131 :param int verbose: print information in verbose mode. 132 :return str: absolute path of the current project working directory. 133 """ 134 # * get tcamTables config file path 135 tempPath = os.path.join(self.prjWorkDir, "compiler/configs/tcamTables.yaml") 136 if os.path.isfile(tempPath) is True: 137 self.tcamTableConfigsFilePath = tempPath 138 self.tcamTableConfigsFileName = os.path.basename(tempPath) 139 logging.info('"FOUND": TCAM table config file path: %s', self.tcamTableConfigsFilePath) 140 printVerbose(verbose, f'"FOUND": TCAM table config file path: {self.tcamTableConfigsFilePath}') 141 return self.tcamTableConfigsFilePath 142 logging.error('"NOT FOUND": TCAM table config file path: %s', self.tcamTableConfigsFilePath) 143 sys.exit(f'"NOT FOUND": TCAM table config file path: {self.tcamTableConfigsFilePath}')
Obtain the absolute path of file tcamTables.yaml.
Parameters
- int verbose: print information in verbose mode.
Returns
absolute path of the current project working directory.
145 def readYAML(self, filePath, verbose): 146 """ 147 Read a particular YAML config file 148 149 :param str filePath: absolute path of file tcamTables.yaml. 150 :param int verbose: print information in verbose mode. 151 :return dict: dictionary containing all the TCAM table configs. 152 """ 153 with open(filePath, encoding="utf-8") as file: 154 self._tcamTableConfigs = yaml.full_load(file) 155 # print(json.dumps(self._tcamTableConfigs,indent=4)) 156 # print(yaml.dump(self._tcamTableConfigs,sort_keys=False,default_flow_style=False)) 157 logging.info("Read TCAM table config file: %s", self.tcamTableConfigsFilePath) 158 printVerbose(verbose, f"Read TCAM table config file: {self.tcamTableConfigsFilePath}") 159 return self._tcamTableConfigs
Read a particular YAML config file
Parameters
- str filePath: absolute path of file tcamTables.yaml.
- int verbose: print information in verbose mode.
Returns
dictionary containing all the TCAM table configs.
161 def printYAML(self, debug): 162 """ 163 Print all present configs of a YAML file either in JSON or YAML style. 164 165 :param int debug: print information in debug mode. 166 """ 167 printDebug(debug, "Printing TCAM table configs") 168 print(json.dumps(self._tcamTableConfigs, indent=4)) 169 # print(yaml.dump(self._tcamTableConfigs,sort_keys=False,default_flow_style=False)) 170 logging.info("Printed TCAM table configs")
Print all present configs of a YAML file either in JSON or YAML style.
Parameters
- int debug: print information in debug mode.
172 def getTCAMConfig(self, tcamConfig): 173 """ 174 Check if a particular tcamTable config exists in file tcamTables.yaml. If found store the config params in vars. 175 - **__tcamQueryStrLen:** saves `queryStrLen` 176 - **__tcamSubStrLen:** saves `subStrLen` 177 - **__tcamTotalSubStr:** saves `totalSubStr` 178 - **__tcamPotMatchAddr:** saves `potMatchAddr` 179 180 :param str tcamConfig: TCAM table config name e.g. tcamTableX 181 :return dict: dictionary containing the respective table map config. 182 """ 183 # * look for specific tcam config in compiler/configs/tcamTables.yaml 184 if tcamConfig in self._tcamTableConfigs.keys(): 185 tempConfig = self._tcamTableConfigs[tcamConfig] 186 # * save tcam config vars 187 self.__tcamQueryStrLen = tempConfig["queryStrLen"] 188 self.__tcamSubStrLen = tempConfig["subStrLen"] 189 self.__tcamTotalSubStr = tempConfig["totalSubStr"] 190 self.__tcamPotMatchAddr = tempConfig["potMatchAddr"] 191 # * print specific tcam config 192 # print(type(tempConfig)) 193 logging.info('"FOUND" Required TCAM Config [%s]', tcamConfig) 194 print('"FOUND" Required TCAM Config [%s]', tcamConfig) 195 logging.info("TCAM Config Data [%s] = %s", tcamConfig, tempConfig) 196 return tempConfig 197 logging.error('"NOT FOUND": TCAM Config [%s]', tcamConfig) 198 sys.exit(f'"NOT FOUND": Required TCAM table config [{tcamConfig}]')
Check if a particular tcamTable config exists in file tcamTables.yaml. If found store the config params in vars.
- __tcamQueryStrLen: saves
queryStrLen
- __tcamSubStrLen: saves
subStrLen
- __tcamTotalSubStr: saves
totalSubStr
- __tcamPotMatchAddr: saves
potMatchAddr
Parameters
- str tcamConfig: TCAM table config name e.g. tcamTableX
Returns
dictionary containing the respective table map config.
200 def getTCAMTableFilePath(self, tcamConfig, verbose): 201 """ 202 Obtain the absolute path of file **tcamTableX.xlsx** which represents the TCAM memory table map. 203 204 :param str tcamConfig: TCAM table config name e.g. tcamTableX 205 :param int verbose: print information in verbose mode. 206 :return str: absolute path of the TCAM table mapping file. 207 """ 208 # * find the specific tcam table map in compiler/lib/ 209 tempPath = os.path.join(self.prjWorkDir, "compiler/lib/" + tcamConfig + ".xlsx") 210 if os.path.isfile(tempPath) is True: 211 self.tcamTableXlsxFilePath = tempPath 212 self.tcamTableXlsxFileName = os.path.basename(tempPath) 213 logging.info('"FOUND" TCAM table map XLSX file path: %s', self.tcamTableXlsxFilePath) 214 printVerbose(verbose, f'"FOUND" TCAM table map XLSX file path: {self.tcamTableXlsxFilePath}') 215 return self.tcamTableXlsxFilePath 216 logging.error('"NOT FOUND": TCAM table map XLSX file path: %s', self.tcamTableXlsxFilePath) 217 sys.exit(f'"NOT FOUND": TCAM table map XLSX file path {self.tcamTableXlsxFilePath}')
Obtain the absolute path of file tcamTableX.xlsx which represents the TCAM memory table map.
Parameters
- str tcamConfig: TCAM table config name e.g. tcamTableX
- int verbose: print information in verbose mode.
Returns
absolute path of the TCAM table mapping file.
219 def printDF(self, dataFrame, heading): 220 """ 221 Display the contents of a particular data frame. 222 223 :param DataFrame dataFrame: particular data frame object. 224 :param str heading: Title above data frame. 225 """ 226 print("\n") 227 print("Printing dataframe: %s", heading) 228 print(tabulate(dataFrame, headers="keys", showindex=True, disable_numparse=True, tablefmt="github"), "\n") 229 logging.info("Printing dataframe: %s", str(heading))
Display the contents of a particular data frame.
Parameters
- DataFrame dataFrame: particular data frame object.
- str heading: Title above data frame.
231 def getTcamTableMap(self): 232 """ 233 Getter function for the TCAM table map 234 235 :return DataFrame: TCAM table map dataframe object 236 """ 237 return self._tcamTable
Getter function for the TCAM table map
Returns
TCAM table map dataframe object
239 def getSramTableMap(self): 240 """ 241 Getter function for the SRAM table map 242 243 :return DataFrame: SRAM table map dataframe object 244 """ 245 return self._sramTable
Getter function for the SRAM table map
Returns
SRAM table map dataframe object
247 def readTCAMTable(self, verbose): 248 """ 249 Read the contents of a **tcamTableX.xlsx** TCAM memory table map as a data frame. 250 251 :param int verbose: print information in verbose mode. 252 :return int: list containing dimensions of TCAM table memory map. 253 """ 254 # * store tcam table in dataframe 255 self._tcamTable = pd.read_excel(self.tcamTableXlsxFilePath, skiprows=2, index_col=None, engine="openpyxl") 256 # * get num of rows and col from tcam table 257 tcamTableRows = self._tcamTable.shape[0] 258 tcamTableCols = self._tcamTable.shape[1] 259 # * compare row/col of tcam table with respective yaml config 260 if tcamTableRows == self.__tcamPotMatchAddr and tcamTableCols - 1 == self.__tcamQueryStrLen: 261 logging.info('"MATCH FOUND": TCAM table map rows == TCAM table YAML config potMatchAddr') 262 printVerbose(verbose, '"MATCH FOUND": TCAM table map rows == TCAM table YAML config potMatchAddr') 263 logging.info('"MATCH FOUND": TCAM table map cols == TCAM table YAML config queryStrLen') 264 printVerbose(verbose, '"MATCH FOUND": TCAM table map cols == TCAM table YAML config queryStrLen') 265 return [tcamTableRows, tcamTableCols] 266 logging.error('"MATCH NOT FOUND": TCAM table map rows != TCAM table YAML config potMatchAddr') 267 logging.error('"MATCH NOT FOUND": TCAM table map cols != TCAM table YAML config queryStrLen') 268 sys.exit('"MATCH NOT FOUND": MISMATCH in TCAM table map and YAML config rows/cols')
Read the contents of a tcamTableX.xlsx TCAM memory table map as a data frame.
Parameters
- int verbose: print information in verbose mode.
Returns
list containing dimensions of TCAM table memory map.
270 def getSRAMTableDim(self, verbose): 271 """ 272 Generate the dimensions of the SRAM table map data frame using TCAM table map configs. 273 274 :param int verbose: print information in verbose mode. 275 :return int: list containing dimensions of SRAM table memory map. 276 """ 277 self.__sramTableRows = self.__tcamTotalSubStr * pow(2, self.__tcamSubStrLen) 278 self.__sramTableCols = self.__tcamPotMatchAddr 279 logging.info("SRAM table rows [{%4d}] cols [{%4d}]", self.__sramTableRows, self.__sramTableCols) 280 printVerbose(verbose, f"SRAM table rows [{self.__sramTableRows}] cols [{self.__sramTableCols}]") 281 return [self.__sramTableRows, self.__sramTableCols]
Generate the dimensions of the SRAM table map data frame using TCAM table map configs.
Parameters
- int verbose: print information in verbose mode.
Returns
list containing dimensions of SRAM table memory map.
283 def genSRAMTable(self, verbose): 284 """ 285 Create an empty SRAM table map data frame containing respective row addresses and column headings. 286 287 :param int verbose: print information in verbose mode. 288 """ 289 # * create temp vars 290 sramTableAddrList = [] 291 sramColHeadings = [] 292 # * create row address 293 for i in range(self.__tcamTotalSubStr): 294 for j in range(2**self.__tcamSubStrLen): 295 padding = "0" + str(self.__tcamSubStrLen) + "b" 296 # sramTableAddrList.append(format(j, '#012b')) # with 0b prefix 297 sramTableAddrList.append(format(j, padding)) # without 0b prefix 298 logging.info("Created [{%4d}] SRAM addresses from search query [{%4d}]", j + 1, i) 299 printVerbose(verbose, f"Created [{j+1}] SRAM addresses from search query [{i}]") 300 # * create col headings 301 for k in reversed(range(self.__tcamPotMatchAddr)): 302 heading = "D" + str(k) 303 sramColHeadings.append(heading) 304 logging.info("Created column heading %s", heading) 305 # * gen empty m*n sram table 306 self._sramTable = pd.DataFrame(index=np.arange(self.__sramTableRows), columns=np.arange(self.__sramTableCols)) 307 # * rename column headings 308 self._sramTable.columns = sramColHeadings 309 # * insert addr col at position 0 310 self._sramTable.insert(0, "Addresses", sramTableAddrList, allow_duplicates=True) 311 logging.info("Created empty [%d x %d] SRAM table", self._sramTable.shape[0], self._sramTable.shape[1]) 312 printVerbose(verbose, f"Created empty [{self._sramTable.shape[0]} x {self._sramTable.shape[1]}] SRAM table")
Create an empty SRAM table map data frame containing respective row addresses and column headings.
Parameters
- int verbose: print information in verbose mode.
314 def createSRAMTableDir(self, verbose): 315 """ 316 Create a directory to store SRAM table maps in various formats. 317 318 :param int verbose: print information in verbose mode. 319 :return str: absolute path of the SRAM table map directory. 320 """ 321 # * create sramTables dir if it doesn't exist 322 self.sramTableDir = os.path.join(self.prjWorkDir, "sramTables") 323 if os.path.exists(self.sramTableDir) is False: 324 os.makedirs("sramTables") 325 logging.info("Created sramTables dir: %s", self.sramTableDir) 326 printVerbose(verbose, f"Created sramTables dir: {self.sramTableDir}") 327 return self.sramTableDir
Create a directory to store SRAM table maps in various formats.
Parameters
- int verbose: print information in verbose mode.
Returns
absolute path of the SRAM table map directory.
329 def splitRowsAndCols(self, debug): 330 """ 331 Create TCAM and SRAM table map row and column vectors based on TCAM table config parameters. 332 333 :param int debug: print information in debug mode. 334 :return list: list containing TCAM and SRAM row and column vectors. 335 """ 336 # * store tcam and sram table in temp vars 337 tcamDF = self._tcamTable 338 sramDF = self._sramTable 339 logging.info("TCAM table (r*c): %s", tuple(tcamDF.shape)) 340 logging.info("SRAM table (r*c): %s", tuple(sramDF.shape)) 341 # * create tcamRows vector 342 self.__tcamRows = np.arange(0, self.__tcamPotMatchAddr, 1).tolist() 343 logging.info("TCAM table row vector: %s", list(self.__tcamRows)) 344 printDebug(debug, f"TCAM table row vector: {*self.__tcamRows,}") 345 # * create tcamCols vector 346 self.__tcamCols = np.arange(1, self.__tcamQueryStrLen + 1, 1).tolist() 347 logging.info("TCAM table col vector: %s", list(self.__tcamCols)) 348 printDebug(debug, f"TCAM table col vector: {*self.__tcamCols,}") 349 # * create tcamColVec vector and split in equal pieces 350 self.__tcamColVec = np.array_split(self.__tcamCols, self.__tcamTotalSubStr) 351 for i in range(len(self.__tcamColVec)): 352 self.__tcamColVec[i] = self.__tcamColVec[i].tolist() 353 logging.info("TCAM table col split vector [%d]: %s", i, list(self.__tcamColVec[i])) 354 printDebug(debug, f"TCAM table col split vector [{i}]: {self.__tcamColVec[i]}") 355 # * create sramRows vector 356 self.__sramRows = np.arange(0, self.__tcamTotalSubStr * 2**self.__tcamSubStrLen, 1).tolist() 357 logging.info("SRAM table row vector: %s", list(self.__sramRows)) 358 printDebug(debug, f"SRAM table row vector: {self.__sramRows}") 359 # * create sramRowVec vector and split in equal pieces 360 self.__sramRowVec = np.array_split(self.__sramRows, self.__tcamTotalSubStr) 361 for i in range(len(self.__sramRowVec)): 362 self.__sramRowVec[i] = self.__sramRowVec[i].tolist() 363 logging.info("SRAM table row split vector [%d]: %s", i, list(self.__sramRowVec[i])) 364 printDebug(debug, f"SRAM table row split vector [{i}]: {self.__sramRowVec[i]}") 365 # * create sramCols vector 366 self.__sramCols = np.arange(0, self.__tcamPotMatchAddr + 1, 1).tolist() 367 logging.info("SRAM table col vector: %s", list(self.__sramCols)) 368 printDebug(debug, f"SRAM table col vector: {self.__sramCols}") 369 return [self.__tcamRows, self.__tcamColVec, self.__sramRowVec, self.__sramCols]
Create TCAM and SRAM table map row and column vectors based on TCAM table config parameters.
Parameters
- int debug: print information in debug mode.
Returns
list containing TCAM and SRAM row and column vectors.
371 def isolateTCAMSearchQueries(self, verbose, debug): 372 """ 373 Create a data frame containing all the sub strings in original format from all the TCAM table search queries. 374 375 :param int verbose: print information in verbose mode. 376 :param int debug: print information in debug mode. 377 """ 378 tcamDF = self._tcamTable 379 count1 = 0 380 self._tcamQSAddrTable = pd.DataFrame(columns=["TCAM Query Str Addr", "PMA", "QS col"]) 381 382 # * ----- add all original search queries in dataframe 383 # * iterate through tcam table rows 384 for row in range(len(tcamDF)): 385 # * iterate through tcam table cols 386 for col in range(len(self.__tcamColVec)): 387 # * search and concat search query string address in tcam table 388 tempAddr = [str(c) for c in list(tcamDF.iloc[row, self.__tcamColVec[col]])] 389 tempAddr = "".join(tempAddr) 390 # * append row in sqSubStrAddrDf data frame 391 tempRow = [tempAddr, row, col] 392 self._tcamQSAddrTable.loc[count1] = tempRow 393 count1 += 1 394 logging.info("TCAM Search Queries Table | Addr: %s | TCAM Row: %5d | Sub String Col: %5d |", tempAddr, row, col) 395 printDebug(debug, f"TCAM Search Queries Table | Addr: {tempAddr} | TCAM Row: {row} | Sub String Col: {col} |") 396 if verbose: 397 self.printDF(self._tcamQSAddrTable, "Original TCAM Search Query Address Table")
Create a data frame containing all the sub strings in original format from all the TCAM table search queries.
Parameters
- int verbose: print information in verbose mode.
- int debug: print information in debug mode.
399 def generateSRAMSubStr(self, verbose, debug): 400 """ 401 Generate all possible combinations of all sub strings from the original TCAM table search queries. 402 403 :param int verbose: print information in verbose mode. 404 :param int debug: print information in debug mode. 405 """ 406 count2 = 0 407 self._sramQSAddrTable = pd.DataFrame(columns=["SRAM Query Str Addr", "PMA", "QS col"]) 408 409 # * ----- find all possible alternatives for X based addr 410 # * create array of N bit bin addresses 411 queryStrBinAddrList = np.arange(2**self.__tcamSubStrLen).tolist() 412 padding = "0" + str(self.__tcamSubStrLen) + "b" 413 for item in queryStrBinAddrList: 414 dec2Bin = format(item, padding) 415 queryStrBinAddrList = queryStrBinAddrList[:item] + [dec2Bin] + queryStrBinAddrList[item + 1 :] 416 logging.info("N bit bin addr list: %s", list(queryStrBinAddrList)) 417 logging.info("N bit bin addr list len: %d", len(queryStrBinAddrList)) 418 if verbose or debug: 419 print("N bit bin addr list: %s", list(queryStrBinAddrList)) 420 print("N bit bin addr list len: %d", len(queryStrBinAddrList)) 421 422 # * get origSQ addr 423 tempQSAddrList = self._tcamQSAddrTable["TCAM Query Str Addr"].to_list() 424 tempQSPmaList = self._tcamQSAddrTable["PMA"].to_list() 425 tempQSColList = self._tcamQSAddrTable["QS col"].to_list() 426 427 printDebug(debug, f"Search Query addr list: {tempQSAddrList}") 428 printDebug(debug, f"Search Query addr list len: {len(tempQSAddrList)}\n") 429 # * map the 'bX in search queries to 0 and 1 430 for (oldAddr, pma, qscol) in zip(tempQSAddrList, tempQSPmaList, tempQSColList): 431 # * if 'bX in search query then find all possible alternatives and add in table 432 if "x" in oldAddr: 433 for newAddr in queryStrBinAddrList: 434 matching = jellyfish.damerau_levenshtein_distance(oldAddr, newAddr) 435 if matching == len(re.findall("x", oldAddr)): 436 printVerbose( 437 verbose, 438 f"count = {count2} | orig Search Query = {oldAddr} | " f"new Search Query = {newAddr} | matching ratio = {matching} |", 439 ) 440 logging.info( 441 "count = %d | orig Search Query = %s | new Search Query = %s | matching ratio = %f |", count2, oldAddr, newAddr, matching 442 ) 443 self._sramQSAddrTable.loc[count2] = [newAddr, pma, qscol] 444 count2 += 1 445 # * else simply add search query in table as is 446 else: 447 printVerbose(verbose, f"count = {count2} | orig Search Query = {oldAddr} | new Search Query = {oldAddr} | matching ratio = {0} |") 448 logging.info("count = %d | orig Search Query = %s | new Search Query = %s | matching ratio = %f |", count2, oldAddr, oldAddr, 0) 449 self._sramQSAddrTable.loc[count2] = [oldAddr, pma, qscol] 450 count2 += 1 451 452 if verbose: 453 self.printDF(self._sramQSAddrTable, "Original SRAM Search Query Address Table")
Generate all possible combinations of all sub strings from the original TCAM table search queries.
Parameters
- int verbose: print information in verbose mode.
- int debug: print information in debug mode.
455 def mapTCAMtoSRAM(self, verbose, debug): 456 """ 457 Map all possible combinations of TCAM table map sub strings to SRAM table map sub strings. 458 459 :param int verbose: print information in verbose mode. 460 :param int debug: print information in debug mode. 461 """ 462 sramDF = self._sramTable 463 sramAddrList = self._sramQSAddrTable["SRAM Query Str Addr"].to_list() 464 tcamRowList = self._sramQSAddrTable["PMA"].to_list() 465 sramColList = self._sramQSAddrTable["QS col"].to_list() 466 467 if len(tcamRowList) == len(sramColList): 468 for (queryStr, pma, qsCol) in itertools.zip_longest(sramAddrList, tcamRowList, sramColList): 469 # * create sram table subsections based on query str 470 tempSRAMTable = sramDF.iloc[self.__sramRowVec[qsCol], self.__sramCols] 471 logging.info("Search Query mapping portion: %d", qsCol) 472 printDebug(debug, f"Search Query mapping portion: {qsCol}") 473 # print(tabulate(tempSRAMTable,headers='keys',tablefmt='github'),'\n') 474 # * find specific mapping cell in sram table 475 rowIndex = tempSRAMTable.index[tempSRAMTable["Addresses"] == queryStr].to_list()[0] 476 colIndex = len(self.__sramCols) - pma - 1 477 # print('sram rowIndex: ',rowIndex,type(rowIndex)) 478 # print('sram colIndex: ',colIndex,type(colIndex)) 479 # * find specific entry 480 oldSramTableEntry = sramDF.iloc[rowIndex, colIndex] 481 # print(sramDF.iloc[rowIndex,colIndex]) 482 # * replace specific entry 483 sramDF.iat[rowIndex, colIndex] = 1 484 # * print before and after 485 if verbose or debug: 486 logging.info("SRAM table cell [%d, %d] | Value = %s -> %s", rowIndex, colIndex, oldSramTableEntry, sramDF.iat[rowIndex, colIndex]) 487 printDebug(debug, f"SRAM table cell [{rowIndex}, {colIndex}] | Value = {oldSramTableEntry} -> {sramDF.iat[rowIndex,colIndex]}") 488 # * add zeros in empty cells 489 sramDF = sramDF.fillna(0) 490 self._sramTable = sramDF 491 else: 492 logging.error('"MATCH NOT FOUND": TCAM table rows != SRAM table cols config potMatchAddr') 493 sys.exit('"MATCH NOT FOUND": MISMATCH in TCAM table map and YAML config rows/cols')
Map all possible combinations of TCAM table map sub strings to SRAM table map sub strings.
Parameters
- int verbose: print information in verbose mode.
- int debug: print information in debug mode.
495 def writeSRAMtoXlsx(self): 496 """ 497 Generates an SRAM table map in XLSX format. 498 499 :return str: absolute path of the SRAM table map `.xlsx` file. 500 """ 501 # * create sram table file path and name 502 self.sramTableXlsxFileName = os.path.basename(self.tcamTableXlsxFileName.replace("tcam", "sram")) 503 self.sramTableXlsxFilePath = os.path.join(self.sramTableDir, self.sramTableXlsxFileName) 504 # * create excel file in dir sramTables 505 # writer = pd.ExcelWriter(self.sramTableXlsxFilePath,engine='xlsxwriter') 506 # writer.save() 507 # * apply formatting to dataframe 508 self._sramTable.style.applymap(highlightCell).to_excel( 509 excel_writer=self.sramTableXlsxFilePath, sheet_name=self.sramTableXlsxFileName, na_rep="", header=True, index=True, engine="openpyxl" 510 ) 511 logging.info("Created SRAM table XLSX file: %s", self.sramTableXlsxFilePath) 512 print("Created SRAM table XLSX file: %s", self.sramTableXlsxFilePath) 513 return self.sramTableXlsxFilePath
Generates an SRAM table map in XLSX format.
Returns
absolute path of the SRAM table map
.xlsx
file.
515 def writeSRAMtoHtml(self): 516 """ 517 Generates an SRAM table map in HTML format. 518 519 :return str: absolute path of the SRAM table map `.html` file. 520 """ 521 # * create sram table file path and name 522 self.sramTableHtmlFileName = os.path.basename(self.tcamTableXlsxFileName.replace("tcam", "sram").replace(".xlsx", ".html")) 523 self.sramTableHtmlFilePath = os.path.join(self.sramTableDir, self.sramTableHtmlFileName) 524 # * create html file in dir sramTables 525 self._sramTable.to_html(self.sramTableHtmlFilePath, index=True, header=True, justify="center", classes="table table-stripped") 526 logging.info("Created SRAM table HTML file: %s", self.sramTableHtmlFilePath) 527 print("Created SRAM table HTML file: %s", self.sramTableHtmlFilePath) 528 return self.sramTableHtmlFilePath
Generates an SRAM table map in HTML format.
Returns
absolute path of the SRAM table map
.html
file.
530 def writeSRAMtoJson(self): 531 """ 532 Generates an SRAM table map in JSON format. 533 534 :return str: absolute path of the SRAM table map `.json` file. 535 """ 536 # * create sram table file path and name 537 self.sramTableJsonFileName = os.path.basename(self.tcamTableXlsxFileName.replace("tcam", "sram").replace(".xlsx", ".json")) 538 self.sramTableJsonFilePath = os.path.join(self.sramTableDir, self.sramTableJsonFileName) 539 # * create json file in dir sramTables 540 self._sramTable.to_json(self.sramTableJsonFilePath, orient="index", indent=4) 541 logging.info("Created SRAM table JSON file: %s", self.sramTableJsonFilePath) 542 print("Created SRAM table JSON file: %s", self.sramTableJsonFilePath) 543 return self.sramTableJsonFilePath
Generates an SRAM table map in JSON format.
Returns
absolute path of the SRAM table map
.json
file.
545 def writeSRAMtoTxt(self): 546 """ 547 Generates an SRAM table map in TXT format. 548 549 :return str: absolute path of the SRAM table map `.txt` file. 550 """ 551 # * create sram table file path and name 552 self.sramTableTxtFileName = os.path.basename(self.tcamTableXlsxFileName.replace("tcam", "sram").replace(".xlsx", ".txt")) 553 self.sramTableTxtFilePath = os.path.join(self.sramTableDir, self.sramTableTxtFileName) 554 # * create txt file in dir sramTables 555 myTable = tabulate(self._sramTable, headers="keys", showindex=True, disable_numparse=True, tablefmt="github") 556 with open(self.sramTableTxtFilePath, "w", encoding="utf-8") as file: 557 file.write(myTable) 558 logging.info("Created SRAM table Txt file: %s", self.sramTableTxtFilePath) 559 print("Created SRAM table Txt file: %s", self.sramTableTxtFilePath) 560 return self.sramTableTxtFilePath
Generates an SRAM table map in TXT format.
Returns
absolute path of the SRAM table map
.txt
file.
568def printVerbose(verbose, msg): 569 """ 570 Prints a string if verbose flag is active. 571 572 :param int verbose: print information in verbose mode. 573 :param str msg: Message to be printed in verbose mode. 574 """ 575 if verbose: 576 print(str(msg))
Prints a string if verbose flag is active.
Parameters
- int verbose: print information in verbose mode.
- str msg: Message to be printed in verbose mode.
579def printDebug(debug, msg): 580 """ 581 Prints a string if debug flag is active. 582 583 :param int debug: print information in debug mode. 584 :param str msg: Message to be printed in debug mode. 585 """ 586 if debug: 587 print(str(msg))
Prints a string if debug flag is active.
Parameters
- int debug: print information in debug mode.
- str msg: Message to be printed in debug mode.
590def highlightCell(val): 591 """ 592 Colors SRAM table map cells in XLSX file depending upon their value. 593 594 :param int val: numerical value of a particular cell. 595 :return str: cell background color code as a hex RBG value. 596 """ 597 if val == 1: 598 color = "#E5961A" 599 elif val == 0: 600 color = "#E4EA15" 601 else: 602 color = "#D8C05A" 603 return f"background-color: {color}"
Colors SRAM table map cells in XLSX file depending upon their value.
Parameters
- int val: numerical value of a particular cell.
Returns
cell background color code as a hex RBG value.