├── .gitignore ├── LICENSE ├── README.md ├── README_es ├── config.ini ├── lib ├── colors.h ├── copy.c ├── copy.h ├── handle_options.h ├── isa.h ├── utils.h └── xml │ ├── license.txt │ ├── rapidxml.hpp │ ├── rapidxml_iterators.hpp │ ├── rapidxml_print.hpp │ └── rapidxml_utils.hpp ├── makefile ├── parser.l ├── parser.y ├── stats.txt └── template.xml /.gitignore: -------------------------------------------------------------------------------- 1 | *~ 2 | *.out 3 | *.html 4 | *.tab.* 5 | *.yy.* 6 | *#* 7 | *.ini 8 | !config.ini 9 | *.txt 10 | !stats.txt 11 | mcpat 12 | gem5ToMcPAT 13 | out.xml 14 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2016 Marcos Horro 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # gem5McPATparse v0.1 2 | An attempt to adapt [gem5](http://gem5.org/Main_Page) output to [McPAT](http://www.hpl.hp.com/research/mcpat/) input. This version is implemented in Bison, Flex and C/C++. It also uses the library [RapidXML](http://rapidxml.sourceforge.net/) for C++. Based on Fernando Endo's notes *[1]*, this parser extracts the parameters and statistics from the output of gem5, 'config.ini' and 'stats.txt', and fills the equivalent fields in a XML based on 'template.xml'. 3 | 4 | ## Compilation 5 | To compile this version: 6 | 7 | make 8 | 9 | ## Running the parser 10 | To run the parser and generate 'output.xml': 11 | 12 | make run 13 | 14 | It is also possible to run as (all these options are mandatory): 15 | 16 | ./gem5McPATparse -x -c -s -o 17 | ./gem5McPATparse --xmltempalte --config --stats --output 18 | 19 | In order to get help from the program: 20 | 21 | ./gem5McPATparse -h 22 | 23 | ## Software needed 24 | It has been tested in a Linux distribution with `gcc version 5.2.1`, `bison version 3.0.2`, `flex 2.5.39` and `make 4.0` 25 | 26 | The template has been adapted for the [last version](https://code.google.com/archive/p/mcpat/downloads) of [McPAT 1.0]. The gem5 version tested is from [03/2015](https://github.com/gem5/gem5/commit/8909843a76c723cb9d8a0b1394eeeba4d7abadb1), but it should work for a more recent version. 27 | 28 | # TODO list 29 | 30 | What can be done or improved: 31 | 32 | * Parse `system.mc` params and statistics 33 | * Check why dcache `block_size` must be 32 in order to work 34 | * Code clarity 35 | * Portability [?] 36 | 37 | # Bugs 38 | 39 | This tool is currently in development, so if you find a bug, you can open an issue. If you do not agree with the translation of a parameter or value, please do the same in order to discuss it! 40 | 41 | # Limitations 42 | This first version is focused on the compatibility of the output of memory system and core in gem5 with the input of McPAT. Thus, other components such as PCIe will be ignored by the moment. 43 | 44 | * Most of translations only work for X86 Architectures. It is needed to find the synonyms for the rest of ISAs 45 | 46 | # References 47 | *[1]*: [Fernando Akira Endo. Génération dynamique de code pour l’optimisation énergétique. Architectures Matérielles [cs.AR]. Université Grenoble Alpes, 2015. Français. . (Appendix A)](https://tel.archives-ouvertes.fr/tel-01285964/document) 48 | -------------------------------------------------------------------------------- /README_es: -------------------------------------------------------------------------------- 1 | gem5ToMcPAT v0.1 2 | ================ 3 | 4 | Esta herramienta nace con la intención de acoplar la salida de gem5 5 | a la herramienta McPAT. El funcionamiento de este parser se basa en 6 | la entrada de dos ficheros salida de gem5, de la configuración y las 7 | estadísticas de la ejecución, y una template en XML modelo del input 8 | de McPAT. Así éste generará un fichero a partir de los anteriores 9 | válido como input del modelador de energías McPAT. 10 | 11 | Una ejecución típica sería la siguiente: 12 | 13 | ./gem5ToMcPAT -x template.xml -c config.ini -s stats.txt -o out.xml 14 | 15 | Los nombres que se han utilizado hablan por sí mismos y no creo que 16 | merezcan mayor explicación. 17 | 18 | Gestión de errores: 19 | =================== 20 | El parseador no parará el parsing de los ficheros si se encuentra 21 | algún error. Esta continuidad hasta EOF se debe a que se prefiere 22 | encontrar todos los errores posibles hasta final de fichero. Con 23 | todo, en caso de encontrarse algún error, el parser no generará 24 | ningún fichero de salida, pues probablemente fuese erróneo. En su 25 | lugar mostrará por pantalla una salida con todos los errores encon- 26 | trados en ambos ficheros de configuración. Si la template no fuese 27 | válida, el parseador también pararía la ejecución, es por ello que 28 | por defecto se da esta template al usuario. 29 | 30 | Warnings: 31 | ========= 32 | Dado que gem5 es un framework muy complejo y tiene diferentes modos 33 | de funcionamiento, sus salidas pueden ser más o menos detalladas. 34 | Así es posible que algunas ejecuciones, las salidas carezcan de al- 35 | gún parámetro. Por defecto, el parser inicializa todos los parámetros 36 | que considera necesarios a cero, en caso de que su valor siga siendo 37 | cero a la horar de escribirlo en la salida. 38 | 39 | OTROS: 40 | ====== 41 | Como se puede ver, en todas las cabeceras de los fuente se encutra la 42 | licencia de código libre. Dado que este parser está pensado para 43 | la comunidad de gem5, he decidido subirlo a un repositorio abierto [1]. 44 | El feedback ha sido en general bueno [2]. 45 | 46 | [1] https://github.com/markoshorro/gem5McPATparse 47 | [2] https://www.mail-archive.com/gem5-users@gem5.org/msg12867.html (ver el thread) 48 | -------------------------------------------------------------------------------- /config.ini: -------------------------------------------------------------------------------- 1 | [root] 2 | type=Root 3 | children=system 4 | eventq_index=0 5 | full_system=false 6 | sim_quantum=0 7 | time_sync_enable=false 8 | time_sync_period=100000000000 9 | time_sync_spin_threshold=100000000 10 | 11 | [system] 12 | type=System 13 | children=clk_domain cpu cpu_clk_domain cpu_voltage_domain dvfs_handler l2 mem_ctrls membus tol2bus voltage_domain 14 | boot_osflags=a 15 | cache_line_size=64 16 | clk_domain=system.clk_domain 17 | eventq_index=0 18 | init_param=0 19 | kernel= 20 | kernel_addr_check=true 21 | load_addr_mask=1099511627775 22 | load_offset=0 23 | mem_mode=timing 24 | mem_ranges=0:4294967295 25 | memories=system.mem_ctrls 26 | mmap_using_noreserve=false 27 | num_work_ids=16 28 | readfile= 29 | symbolfile= 30 | work_begin_ckpt_count=0 31 | work_begin_cpu_id_exit=-1 32 | work_begin_exit_count=0 33 | work_cpus_ckpt_count=0 34 | work_end_ckpt_count=0 35 | work_end_exit_count=0 36 | work_item_id=-1 37 | system_port=system.membus.slave[0] 38 | 39 | [system.clk_domain] 40 | type=SrcClockDomain 41 | clock=1000 42 | domain_id=-1 43 | eventq_index=0 44 | init_perf_level=0 45 | voltage_domain=system.voltage_domain 46 | 47 | [system.cpu] 48 | type=DerivO3CPU 49 | children=apic_clk_domain branchPred dcache dtb dtb_walker_cache fuPool icache interrupts isa itb itb_walker_cache tracer workload 50 | LFSTSize=1024 51 | LQEntries=32 52 | LSQCheckLoads=true 53 | LSQDepCheckShift=4 54 | SQEntries=32 55 | SSITSize=1024 56 | activity=0 57 | backComSize=5 58 | branchPred=system.cpu.branchPred 59 | cachePorts=200 60 | checker=Null 61 | clk_domain=system.cpu_clk_domain 62 | commitToDecodeDelay=1 63 | commitToFetchDelay=1 64 | commitToIEWDelay=1 65 | commitToRenameDelay=1 66 | commitWidth=8 67 | cpu_id=0 68 | decodeToFetchDelay=1 69 | decodeToRenameDelay=1 70 | decodeWidth=8 71 | dispatchWidth=8 72 | do_checkpoint_insts=true 73 | do_quiesce=true 74 | do_statistics_insts=true 75 | dtb=system.cpu.dtb 76 | eventq_index=0 77 | fetchBufferSize=64 78 | fetchQueueSize=32 79 | fetchToDecodeDelay=1 80 | fetchTrapLatency=1 81 | fetchWidth=8 82 | forwardComSize=5 83 | fuPool=system.cpu.fuPool 84 | function_trace=false 85 | function_trace_start=0 86 | iewToCommitDelay=1 87 | iewToDecodeDelay=1 88 | iewToFetchDelay=1 89 | iewToRenameDelay=1 90 | interrupts=system.cpu.interrupts 91 | isa=system.cpu.isa 92 | issueToExecuteDelay=1 93 | issueWidth=8 94 | itb=system.cpu.itb 95 | max_insts_all_threads=0 96 | max_insts_any_thread=0 97 | max_loads_all_threads=0 98 | max_loads_any_thread=0 99 | needsTSO=true 100 | numIQEntries=64 101 | numPhysCCRegs=1280 102 | numPhysFloatRegs=256 103 | numPhysIntRegs=256 104 | numROBEntries=192 105 | numRobs=1 106 | numThreads=1 107 | profile=0 108 | progress_interval=0 109 | renameToDecodeDelay=1 110 | renameToFetchDelay=1 111 | renameToIEWDelay=2 112 | renameToROBDelay=1 113 | renameWidth=8 114 | simpoint_start_insts= 115 | smtCommitPolicy=RoundRobin 116 | smtFetchPolicy=SingleThread 117 | smtIQPolicy=Partitioned 118 | smtIQThreshold=100 119 | smtLSQPolicy=Partitioned 120 | smtLSQThreshold=100 121 | smtNumFetchingThreads=1 122 | smtROBPolicy=Partitioned 123 | smtROBThreshold=100 124 | socket_id=0 125 | squashWidth=8 126 | store_set_clear_period=250000 127 | switched_out=false 128 | system=system 129 | tracer=system.cpu.tracer 130 | trapLatency=13 131 | wbWidth=8 132 | workload=system.cpu.workload 133 | dcache_port=system.cpu.dcache.cpu_side 134 | icache_port=system.cpu.icache.cpu_side 135 | 136 | [system.cpu.apic_clk_domain] 137 | type=DerivedClockDomain 138 | clk_divider=16 139 | clk_domain=system.cpu_clk_domain 140 | eventq_index=0 141 | 142 | [system.cpu.branchPred] 143 | type=BranchPredictor 144 | BTBEntries=4096 145 | BTBTagSize=16 146 | RASSize=16 147 | choiceCtrBits=2 148 | choicePredictorSize=8192 149 | eventq_index=0 150 | globalCtrBits=2 151 | globalPredictorSize=8192 152 | instShiftAmt=2 153 | localCtrBits=2 154 | localHistoryTableSize=2048 155 | localPredictorSize=2048 156 | numThreads=1 157 | predType=tournament 158 | 159 | [system.cpu.dcache] 160 | type=BaseCache 161 | children=tags 162 | addr_ranges=0:18446744073709551615 163 | assoc=4 164 | clk_domain=system.cpu_clk_domain 165 | demand_mshr_reserve=1 166 | eventq_index=0 167 | forward_snoops=true 168 | hit_latency=2 169 | is_top_level=true 170 | max_miss_count=0 171 | mshrs=4 172 | prefetch_on_access=false 173 | prefetcher=Null 174 | response_latency=2 175 | sequential_access=false 176 | size=32768 177 | system=system 178 | tags=system.cpu.dcache.tags 179 | tgts_per_mshr=20 180 | two_queue=false 181 | write_buffers=8 182 | cpu_side=system.cpu.dcache_port 183 | mem_side=system.tol2bus.slave[1] 184 | 185 | [system.cpu.dcache.tags] 186 | type=LRU 187 | assoc=4 188 | block_size=64 189 | clk_domain=system.cpu_clk_domain 190 | eventq_index=0 191 | hit_latency=2 192 | sequential_access=false 193 | size=32768 194 | 195 | [system.cpu.dtb] 196 | type=X86TLB 197 | children=walker 198 | eventq_index=0 199 | size=64 200 | walker=system.cpu.dtb.walker 201 | 202 | [system.cpu.dtb.walker] 203 | type=X86PagetableWalker 204 | clk_domain=system.cpu_clk_domain 205 | eventq_index=0 206 | num_squash_per_cycle=4 207 | system=system 208 | port=system.cpu.dtb_walker_cache.cpu_side 209 | 210 | [system.cpu.dtb_walker_cache] 211 | type=BaseCache 212 | children=tags 213 | addr_ranges=0:18446744073709551615 214 | assoc=2 215 | clk_domain=system.cpu_clk_domain 216 | demand_mshr_reserve=1 217 | eventq_index=0 218 | forward_snoops=true 219 | hit_latency=2 220 | is_top_level=true 221 | max_miss_count=0 222 | mshrs=10 223 | prefetch_on_access=false 224 | prefetcher=Null 225 | response_latency=2 226 | sequential_access=false 227 | size=1024 228 | system=system 229 | tags=system.cpu.dtb_walker_cache.tags 230 | tgts_per_mshr=12 231 | two_queue=false 232 | write_buffers=8 233 | cpu_side=system.cpu.dtb.walker.port 234 | mem_side=system.tol2bus.slave[3] 235 | 236 | [system.cpu.dtb_walker_cache.tags] 237 | type=LRU 238 | assoc=2 239 | block_size=64 240 | clk_domain=system.cpu_clk_domain 241 | eventq_index=0 242 | hit_latency=2 243 | sequential_access=false 244 | size=1024 245 | 246 | [system.cpu.fuPool] 247 | type=FUPool 248 | children=FUList0 FUList1 FUList2 FUList3 FUList4 FUList5 FUList6 FUList7 FUList8 249 | FUList=system.cpu.fuPool.FUList0 system.cpu.fuPool.FUList1 system.cpu.fuPool.FUList2 system.cpu.fuPool.FUList3 system.cpu.fuPool.FUList4 system.cpu.fuPool.FUList5 system.cpu.fuPool.FUList6 system.cpu.fuPool.FUList7 system.cpu.fuPool.FUList8 250 | eventq_index=0 251 | 252 | [system.cpu.fuPool.FUList0] 253 | type=FUDesc 254 | children=opList 255 | count=6 256 | eventq_index=0 257 | opList=system.cpu.fuPool.FUList0.opList 258 | 259 | [system.cpu.fuPool.FUList0.opList] 260 | type=OpDesc 261 | eventq_index=0 262 | issueLat=1 263 | opClass=IntAlu 264 | opLat=1 265 | 266 | [system.cpu.fuPool.FUList1] 267 | type=FUDesc 268 | children=opList0 opList1 269 | count=2 270 | eventq_index=0 271 | opList=system.cpu.fuPool.FUList1.opList0 system.cpu.fuPool.FUList1.opList1 272 | 273 | [system.cpu.fuPool.FUList1.opList0] 274 | type=OpDesc 275 | eventq_index=0 276 | issueLat=1 277 | opClass=IntMult 278 | opLat=3 279 | 280 | [system.cpu.fuPool.FUList1.opList1] 281 | type=OpDesc 282 | eventq_index=0 283 | issueLat=19 284 | opClass=IntDiv 285 | opLat=20 286 | 287 | [system.cpu.fuPool.FUList2] 288 | type=FUDesc 289 | children=opList0 opList1 opList2 290 | count=4 291 | eventq_index=0 292 | opList=system.cpu.fuPool.FUList2.opList0 system.cpu.fuPool.FUList2.opList1 system.cpu.fuPool.FUList2.opList2 293 | 294 | [system.cpu.fuPool.FUList2.opList0] 295 | type=OpDesc 296 | eventq_index=0 297 | issueLat=1 298 | opClass=FloatAdd 299 | opLat=2 300 | 301 | [system.cpu.fuPool.FUList2.opList1] 302 | type=OpDesc 303 | eventq_index=0 304 | issueLat=1 305 | opClass=FloatCmp 306 | opLat=2 307 | 308 | [system.cpu.fuPool.FUList2.opList2] 309 | type=OpDesc 310 | eventq_index=0 311 | issueLat=1 312 | opClass=FloatCvt 313 | opLat=2 314 | 315 | [system.cpu.fuPool.FUList3] 316 | type=FUDesc 317 | children=opList0 opList1 opList2 318 | count=2 319 | eventq_index=0 320 | opList=system.cpu.fuPool.FUList3.opList0 system.cpu.fuPool.FUList3.opList1 system.cpu.fuPool.FUList3.opList2 321 | 322 | [system.cpu.fuPool.FUList3.opList0] 323 | type=OpDesc 324 | eventq_index=0 325 | issueLat=1 326 | opClass=FloatMult 327 | opLat=4 328 | 329 | [system.cpu.fuPool.FUList3.opList1] 330 | type=OpDesc 331 | eventq_index=0 332 | issueLat=12 333 | opClass=FloatDiv 334 | opLat=12 335 | 336 | [system.cpu.fuPool.FUList3.opList2] 337 | type=OpDesc 338 | eventq_index=0 339 | issueLat=24 340 | opClass=FloatSqrt 341 | opLat=24 342 | 343 | [system.cpu.fuPool.FUList4] 344 | type=FUDesc 345 | children=opList 346 | count=0 347 | eventq_index=0 348 | opList=system.cpu.fuPool.FUList4.opList 349 | 350 | [system.cpu.fuPool.FUList4.opList] 351 | type=OpDesc 352 | eventq_index=0 353 | issueLat=1 354 | opClass=MemRead 355 | opLat=1 356 | 357 | [system.cpu.fuPool.FUList5] 358 | type=FUDesc 359 | children=opList00 opList01 opList02 opList03 opList04 opList05 opList06 opList07 opList08 opList09 opList10 opList11 opList12 opList13 opList14 opList15 opList16 opList17 opList18 opList19 360 | count=4 361 | eventq_index=0 362 | opList=system.cpu.fuPool.FUList5.opList00 system.cpu.fuPool.FUList5.opList01 system.cpu.fuPool.FUList5.opList02 system.cpu.fuPool.FUList5.opList03 system.cpu.fuPool.FUList5.opList04 system.cpu.fuPool.FUList5.opList05 system.cpu.fuPool.FUList5.opList06 system.cpu.fuPool.FUList5.opList07 system.cpu.fuPool.FUList5.opList08 system.cpu.fuPool.FUList5.opList09 system.cpu.fuPool.FUList5.opList10 system.cpu.fuPool.FUList5.opList11 system.cpu.fuPool.FUList5.opList12 system.cpu.fuPool.FUList5.opList13 system.cpu.fuPool.FUList5.opList14 system.cpu.fuPool.FUList5.opList15 system.cpu.fuPool.FUList5.opList16 system.cpu.fuPool.FUList5.opList17 system.cpu.fuPool.FUList5.opList18 system.cpu.fuPool.FUList5.opList19 363 | 364 | [system.cpu.fuPool.FUList5.opList00] 365 | type=OpDesc 366 | eventq_index=0 367 | issueLat=1 368 | opClass=SimdAdd 369 | opLat=1 370 | 371 | [system.cpu.fuPool.FUList5.opList01] 372 | type=OpDesc 373 | eventq_index=0 374 | issueLat=1 375 | opClass=SimdAddAcc 376 | opLat=1 377 | 378 | [system.cpu.fuPool.FUList5.opList02] 379 | type=OpDesc 380 | eventq_index=0 381 | issueLat=1 382 | opClass=SimdAlu 383 | opLat=1 384 | 385 | [system.cpu.fuPool.FUList5.opList03] 386 | type=OpDesc 387 | eventq_index=0 388 | issueLat=1 389 | opClass=SimdCmp 390 | opLat=1 391 | 392 | [system.cpu.fuPool.FUList5.opList04] 393 | type=OpDesc 394 | eventq_index=0 395 | issueLat=1 396 | opClass=SimdCvt 397 | opLat=1 398 | 399 | [system.cpu.fuPool.FUList5.opList05] 400 | type=OpDesc 401 | eventq_index=0 402 | issueLat=1 403 | opClass=SimdMisc 404 | opLat=1 405 | 406 | [system.cpu.fuPool.FUList5.opList06] 407 | type=OpDesc 408 | eventq_index=0 409 | issueLat=1 410 | opClass=SimdMult 411 | opLat=1 412 | 413 | [system.cpu.fuPool.FUList5.opList07] 414 | type=OpDesc 415 | eventq_index=0 416 | issueLat=1 417 | opClass=SimdMultAcc 418 | opLat=1 419 | 420 | [system.cpu.fuPool.FUList5.opList08] 421 | type=OpDesc 422 | eventq_index=0 423 | issueLat=1 424 | opClass=SimdShift 425 | opLat=1 426 | 427 | [system.cpu.fuPool.FUList5.opList09] 428 | type=OpDesc 429 | eventq_index=0 430 | issueLat=1 431 | opClass=SimdShiftAcc 432 | opLat=1 433 | 434 | [system.cpu.fuPool.FUList5.opList10] 435 | type=OpDesc 436 | eventq_index=0 437 | issueLat=1 438 | opClass=SimdSqrt 439 | opLat=1 440 | 441 | [system.cpu.fuPool.FUList5.opList11] 442 | type=OpDesc 443 | eventq_index=0 444 | issueLat=1 445 | opClass=SimdFloatAdd 446 | opLat=1 447 | 448 | [system.cpu.fuPool.FUList5.opList12] 449 | type=OpDesc 450 | eventq_index=0 451 | issueLat=1 452 | opClass=SimdFloatAlu 453 | opLat=1 454 | 455 | [system.cpu.fuPool.FUList5.opList13] 456 | type=OpDesc 457 | eventq_index=0 458 | issueLat=1 459 | opClass=SimdFloatCmp 460 | opLat=1 461 | 462 | [system.cpu.fuPool.FUList5.opList14] 463 | type=OpDesc 464 | eventq_index=0 465 | issueLat=1 466 | opClass=SimdFloatCvt 467 | opLat=1 468 | 469 | [system.cpu.fuPool.FUList5.opList15] 470 | type=OpDesc 471 | eventq_index=0 472 | issueLat=1 473 | opClass=SimdFloatDiv 474 | opLat=1 475 | 476 | [system.cpu.fuPool.FUList5.opList16] 477 | type=OpDesc 478 | eventq_index=0 479 | issueLat=1 480 | opClass=SimdFloatMisc 481 | opLat=1 482 | 483 | [system.cpu.fuPool.FUList5.opList17] 484 | type=OpDesc 485 | eventq_index=0 486 | issueLat=1 487 | opClass=SimdFloatMult 488 | opLat=1 489 | 490 | [system.cpu.fuPool.FUList5.opList18] 491 | type=OpDesc 492 | eventq_index=0 493 | issueLat=1 494 | opClass=SimdFloatMultAcc 495 | opLat=1 496 | 497 | [system.cpu.fuPool.FUList5.opList19] 498 | type=OpDesc 499 | eventq_index=0 500 | issueLat=1 501 | opClass=SimdFloatSqrt 502 | opLat=1 503 | 504 | [system.cpu.fuPool.FUList6] 505 | type=FUDesc 506 | children=opList 507 | count=0 508 | eventq_index=0 509 | opList=system.cpu.fuPool.FUList6.opList 510 | 511 | [system.cpu.fuPool.FUList6.opList] 512 | type=OpDesc 513 | eventq_index=0 514 | issueLat=1 515 | opClass=MemWrite 516 | opLat=1 517 | 518 | [system.cpu.fuPool.FUList7] 519 | type=FUDesc 520 | children=opList0 opList1 521 | count=4 522 | eventq_index=0 523 | opList=system.cpu.fuPool.FUList7.opList0 system.cpu.fuPool.FUList7.opList1 524 | 525 | [system.cpu.fuPool.FUList7.opList0] 526 | type=OpDesc 527 | eventq_index=0 528 | issueLat=1 529 | opClass=MemRead 530 | opLat=1 531 | 532 | [system.cpu.fuPool.FUList7.opList1] 533 | type=OpDesc 534 | eventq_index=0 535 | issueLat=1 536 | opClass=MemWrite 537 | opLat=1 538 | 539 | [system.cpu.fuPool.FUList8] 540 | type=FUDesc 541 | children=opList 542 | count=1 543 | eventq_index=0 544 | opList=system.cpu.fuPool.FUList8.opList 545 | 546 | [system.cpu.fuPool.FUList8.opList] 547 | type=OpDesc 548 | eventq_index=0 549 | issueLat=3 550 | opClass=IprAccess 551 | opLat=3 552 | 553 | [system.cpu.icache] 554 | type=BaseCache 555 | children=tags 556 | addr_ranges=0:18446744073709551615 557 | assoc=8 558 | clk_domain=system.cpu_clk_domain 559 | demand_mshr_reserve=1 560 | eventq_index=0 561 | forward_snoops=true 562 | hit_latency=2 563 | is_top_level=true 564 | max_miss_count=0 565 | mshrs=4 566 | prefetch_on_access=false 567 | prefetcher=Null 568 | response_latency=2 569 | sequential_access=false 570 | size=32768 571 | system=system 572 | tags=system.cpu.icache.tags 573 | tgts_per_mshr=20 574 | two_queue=false 575 | write_buffers=8 576 | cpu_side=system.cpu.icache_port 577 | mem_side=system.tol2bus.slave[0] 578 | 579 | [system.cpu.icache.tags] 580 | type=LRU 581 | assoc=8 582 | block_size=64 583 | clk_domain=system.cpu_clk_domain 584 | eventq_index=0 585 | hit_latency=2 586 | sequential_access=false 587 | size=32768 588 | 589 | [system.cpu.interrupts] 590 | type=X86LocalApic 591 | clk_domain=system.cpu.apic_clk_domain 592 | eventq_index=0 593 | int_latency=1000 594 | pio_addr=2305843009213693952 595 | pio_latency=100000 596 | system=system 597 | int_master=system.membus.slave[2] 598 | int_slave=system.membus.master[1] 599 | pio=system.membus.master[0] 600 | 601 | [system.cpu.isa] 602 | type=X86ISA 603 | eventq_index=0 604 | 605 | [system.cpu.itb] 606 | type=X86TLB 607 | children=walker 608 | eventq_index=0 609 | size=64 610 | walker=system.cpu.itb.walker 611 | 612 | [system.cpu.itb.walker] 613 | type=X86PagetableWalker 614 | clk_domain=system.cpu_clk_domain 615 | eventq_index=0 616 | num_squash_per_cycle=4 617 | system=system 618 | port=system.cpu.itb_walker_cache.cpu_side 619 | 620 | [system.cpu.itb_walker_cache] 621 | type=BaseCache 622 | children=tags 623 | addr_ranges=0:18446744073709551615 624 | assoc=2 625 | clk_domain=system.cpu_clk_domain 626 | demand_mshr_reserve=1 627 | eventq_index=0 628 | forward_snoops=true 629 | hit_latency=2 630 | is_top_level=true 631 | max_miss_count=0 632 | mshrs=10 633 | prefetch_on_access=false 634 | prefetcher=Null 635 | response_latency=2 636 | sequential_access=false 637 | size=1024 638 | system=system 639 | tags=system.cpu.itb_walker_cache.tags 640 | tgts_per_mshr=12 641 | two_queue=false 642 | write_buffers=8 643 | cpu_side=system.cpu.itb.walker.port 644 | mem_side=system.tol2bus.slave[2] 645 | 646 | [system.cpu.itb_walker_cache.tags] 647 | type=LRU 648 | assoc=2 649 | block_size=64 650 | clk_domain=system.cpu_clk_domain 651 | eventq_index=0 652 | hit_latency=2 653 | sequential_access=false 654 | size=1024 655 | 656 | [system.cpu.tracer] 657 | type=ExeTracer 658 | eventq_index=0 659 | 660 | [system.cpu.workload] 661 | type=LiveProcess 662 | cmd=tests/test-progs/hello/bin/x86/linux/hello 663 | cwd=/home/markoshorro/gem5 664 | drivers= 665 | egid=100 666 | env= 667 | errout=cerr 668 | euid=100 669 | eventq_index=0 670 | executable=tests/test-progs/hello/bin/x86/linux/hello 671 | gid=100 672 | input=cin 673 | kvmInSE=false 674 | max_stack_size=67108864 675 | output=cout 676 | pid=100 677 | ppid=99 678 | simpoint=0 679 | system=system 680 | uid=100 681 | useArchPT=false 682 | 683 | [system.cpu_clk_domain] 684 | type=SrcClockDomain 685 | clock=500 686 | domain_id=-1 687 | eventq_index=0 688 | init_perf_level=0 689 | voltage_domain=system.cpu_voltage_domain 690 | 691 | [system.cpu_voltage_domain] 692 | type=VoltageDomain 693 | eventq_index=0 694 | voltage=1.000000 695 | 696 | [system.dvfs_handler] 697 | type=DVFSHandler 698 | domains= 699 | enable=false 700 | eventq_index=0 701 | sys_clk_domain=system.clk_domain 702 | transition_latency=100000000 703 | 704 | [system.l2] 705 | type=BaseCache 706 | children=tags 707 | addr_ranges=0:18446744073709551615 708 | assoc=8 709 | clk_domain=system.cpu_clk_domain 710 | demand_mshr_reserve=1 711 | eventq_index=0 712 | forward_snoops=true 713 | hit_latency=20 714 | is_top_level=false 715 | max_miss_count=0 716 | mshrs=20 717 | prefetch_on_access=false 718 | prefetcher=Null 719 | response_latency=20 720 | sequential_access=false 721 | size=262144 722 | system=system 723 | tags=system.l2.tags 724 | tgts_per_mshr=12 725 | two_queue=false 726 | write_buffers=8 727 | cpu_side=system.tol2bus.master[0] 728 | mem_side=system.membus.slave[1] 729 | 730 | [system.l2.tags] 731 | type=LRU 732 | assoc=8 733 | block_size=64 734 | clk_domain=system.cpu_clk_domain 735 | eventq_index=0 736 | hit_latency=20 737 | sequential_access=false 738 | size=262144 739 | 740 | [system.mem_ctrls] 741 | type=DRAMCtrl 742 | IDD0=0.075000 743 | IDD02=0.000000 744 | IDD2N=0.050000 745 | IDD2N2=0.000000 746 | IDD2P0=0.000000 747 | IDD2P02=0.000000 748 | IDD2P1=0.000000 749 | IDD2P12=0.000000 750 | IDD3N=0.057000 751 | IDD3N2=0.000000 752 | IDD3P0=0.000000 753 | IDD3P02=0.000000 754 | IDD3P1=0.000000 755 | IDD3P12=0.000000 756 | IDD4R=0.187000 757 | IDD4R2=0.000000 758 | IDD4W=0.165000 759 | IDD4W2=0.000000 760 | IDD5=0.220000 761 | IDD52=0.000000 762 | IDD6=0.000000 763 | IDD62=0.000000 764 | VDD=1.500000 765 | VDD2=0.000000 766 | activation_limit=4 767 | addr_mapping=RoRaBaCoCh 768 | bank_groups_per_rank=0 769 | banks_per_rank=8 770 | burst_length=8 771 | channels=1 772 | clk_domain=system.clk_domain 773 | conf_table_reported=true 774 | device_bus_width=8 775 | device_rowbuffer_size=1024 776 | device_size=536870912 777 | devices_per_rank=8 778 | dll=true 779 | eventq_index=0 780 | in_addr_map=true 781 | max_accesses_per_row=16 782 | mem_sched_policy=frfcfs 783 | min_writes_per_switch=16 784 | null=false 785 | page_policy=open_adaptive 786 | range=0:4294967295 787 | ranks_per_channel=2 788 | read_buffer_size=32 789 | static_backend_latency=10000 790 | static_frontend_latency=10000 791 | tBURST=5000 792 | tCCD_L=0 793 | tCK=1250 794 | tCL=13750 795 | tCS=2500 796 | tRAS=35000 797 | tRCD=13750 798 | tREFI=7800000 799 | tRFC=260000 800 | tRP=13750 801 | tRRD=6000 802 | tRRD_L=0 803 | tRTP=7500 804 | tRTW=2500 805 | tWR=15000 806 | tWTR=7500 807 | tXAW=30000 808 | tXP=0 809 | tXPDLL=0 810 | tXS=0 811 | tXSDLL=0 812 | write_buffer_size=64 813 | write_high_thresh_perc=85 814 | write_low_thresh_perc=50 815 | port=system.membus.master[2] 816 | 817 | [system.membus] 818 | type=CoherentXBar 819 | clk_domain=system.clk_domain 820 | eventq_index=0 821 | forward_latency=4 822 | frontend_latency=3 823 | response_latency=2 824 | snoop_filter=Null 825 | snoop_response_latency=4 826 | system=system 827 | use_default_range=false 828 | width=16 829 | master=system.cpu.interrupts.pio system.cpu.interrupts.int_slave system.mem_ctrls.port 830 | slave=system.system_port system.l2.mem_side system.cpu.interrupts.int_master 831 | 832 | [system.tol2bus] 833 | type=CoherentXBar 834 | clk_domain=system.cpu_clk_domain 835 | eventq_index=0 836 | forward_latency=0 837 | frontend_latency=1 838 | response_latency=1 839 | snoop_filter=Null 840 | snoop_response_latency=1 841 | system=system 842 | use_default_range=false 843 | width=32 844 | master=system.l2.cpu_side 845 | slave=system.cpu.icache.mem_side system.cpu.dcache.mem_side system.cpu.itb_walker_cache.mem_side system.cpu.dtb_walker_cache.mem_side 846 | 847 | [system.voltage_domain] 848 | type=VoltageDomain 849 | eventq_index=0 850 | voltage=1.000000 851 | 852 | -------------------------------------------------------------------------------- /lib/colors.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2016 Marcos Horro 3 | * All rights reserved. MIT Licence 4 | * 5 | * Redistribution and use in source and binary forms, with or without 6 | * modification, are permitted provided that the following conditions are 7 | * met: redistributions of source code must retain the above copyright 8 | * notice, this list of conditions and the following disclaimer; 9 | * redistributions in binary form must reproduce the above copyright 10 | * notice, this list of conditions and the following disclaimer in the 11 | * documentation and/or other materials provided with the distribution; 12 | * neither the name of the copyright holders nor the names of its 13 | * contributors may be used to endorse or promote products derived from 14 | * this software without specific prior written permission. 15 | * 16 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 17 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 18 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 19 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 20 | * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 21 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 22 | * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 26 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 | * 28 | * Authors: Marcos Horro Varela 29 | * 30 | */ 31 | 32 | #include 33 | 34 | // more details http://ascii-table.com/ansi-escape-sequences.php 35 | 36 | #define RES "\x1B[0m" 37 | #define BLD "\x1B[1m" 38 | #define RED "\x1B[31m" 39 | #define GRN "\x1B[32m" 40 | #define YEL "\x1B[33m" 41 | #define BLU "\x1B[34m" 42 | #define MAG "\x1B[35m" 43 | #define CYN "\x1B[36m" 44 | #define WHT "\x1B[37m" 45 | -------------------------------------------------------------------------------- /lib/copy.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2016 Marcos Horro 3 | * All rights reserved. MIT Licence 4 | * 5 | * Redistribution and use in source and binary forms, with or without 6 | * modification, are permitted provided that the following conditions are 7 | * met: redistributions of source code must retain the above copyright 8 | * notice, this list of conditions and the following disclaimer; 9 | * redistributions in binary form must reproduce the above copyright 10 | * notice, this list of conditions and the following disclaimer in the 11 | * documentation and/or other materials provided with the distribution; 12 | * neither the name of the copyright holders nor the names of its 13 | * contributors may be used to endorse or promote products derived from 14 | * this software without specific prior written permission. 15 | * 16 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 17 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 18 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 19 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 20 | * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 21 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 22 | * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 26 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 | * 28 | * Authors: Marcos Horro Varela 29 | * 30 | */ 31 | #include 32 | #include 33 | #include 34 | 35 | void copy(char const *source, char const *dest) 36 | { 37 | int childExitStatus; 38 | pid_t pid; 39 | int status; 40 | char const *error_msg = "Error copying template! Quitting...\n"; 41 | if (!source || !dest) { 42 | /* handle as you wish */ 43 | } 44 | 45 | pid = fork(); 46 | 47 | if (pid == 0) { /* child */ 48 | execl("/bin/cp", "/bin/cp", source, dest, (char *)0); 49 | } 50 | else if (pid < 0) { 51 | /* error - couldn't start process */ 52 | printf("%s", error_msg); 53 | exit(-1); 54 | } 55 | else { 56 | /* parent - wait for child - this has all error handling, you 57 | * could just call wait() as long as you are only expecting to 58 | * have one child process at a time. 59 | */ 60 | pid_t ws = waitpid( pid, &childExitStatus, WNOHANG); 61 | if (ws == -1) 62 | { /* error */ 63 | printf("%s", error_msg); 64 | exit(-1); 65 | } 66 | 67 | if( WIFEXITED(childExitStatus)) /* exit code in childExitStatus */ 68 | { 69 | status = WEXITSTATUS(childExitStatus); /* zero is normal exit */ 70 | } 71 | else if (WIFSIGNALED(childExitStatus)) /* killed */ 72 | { 73 | } 74 | else if (WIFSTOPPED(childExitStatus)) /* stopped */ 75 | { 76 | } 77 | } 78 | } 79 | -------------------------------------------------------------------------------- /lib/copy.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2016 Marcos Horro 3 | * All rights reserved. MIT Licence 4 | * 5 | * Redistribution and use in source and binary forms, with or without 6 | * modification, are permitted provided that the following conditions are 7 | * met: redistributions of source code must retain the above copyright 8 | * notice, this list of conditions and the following disclaimer; 9 | * redistributions in binary form must reproduce the above copyright 10 | * notice, this list of conditions and the following disclaimer in the 11 | * documentation and/or other materials provided with the distribution; 12 | * neither the name of the copyright holders nor the names of its 13 | * contributors may be used to endorse or promote products derived from 14 | * this software without specific prior written permission. 15 | * 16 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 17 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 18 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 19 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 20 | * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 21 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 22 | * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 26 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 | * 28 | * Authors: Marcos Horro Varela 29 | * 30 | */ 31 | // taken from https://stackoverflow.com/questions/2180079/how-can-i-copy-a-file-on-unix-using-c 32 | #include "copy.c" 33 | 34 | void copy(char const *source, char const *dest); 35 | -------------------------------------------------------------------------------- /lib/handle_options.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2016 Marcos Horro 3 | * All rights reserved. MIT Licence 4 | * 5 | * Redistribution and use in source and binary forms, with or without 6 | * modification, are permitted provided that the following conditions are 7 | * met: redistributions of source code must retain the above copyright 8 | * notice, this list of conditions and the following disclaimer; 9 | * redistributions in binary form must reproduce the above copyright 10 | * notice, this list of conditions and the following disclaimer in the 11 | * documentation and/or other materials provided with the distribution; 12 | * neither the name of the copyright holders nor the names of its 13 | * contributors may be used to endorse or promote products derived from 14 | * this software without specific prior written permission. 15 | * 16 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 17 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 18 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 19 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 20 | * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 21 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 22 | * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 26 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 | * 28 | * Authors: Marcos Horro Varela 29 | * Juan Quintela 30 | */ 31 | static struct option long_options[] = { 32 | { .name = "xmltemplate", 33 | .has_arg = required_argument, 34 | .flag = NULL, 35 | .val = 0}, 36 | { .name = "config", 37 | .has_arg = required_argument, 38 | .flag = NULL, 39 | .val = 0}, 40 | { .name = "stats", 41 | .has_arg = required_argument, 42 | .flag = NULL, 43 | .val = 0}, 44 | { .name = "output", 45 | .has_arg = required_argument, 46 | .flag = NULL, 47 | .val = 0}, 48 | {0, 0, 0, 0} 49 | }; 50 | 51 | void usage(int i) 52 | { 53 | printf( 54 | "Usage: gem5ToMcPAT [OPTIONS]\n" 55 | "Launch parser gem5ToMcPAT\n" 56 | "Options:\n" 57 | " -x , --xmltemplate=: XML template\n" 58 | " -c , --config=: config.ini file (not JSON!)\n" 59 | " -s , --stats=: statistics file\n" 60 | " -o , --output=: XML output\n" 61 | " -h, --help: displays this message\n\n"); 62 | exit(i); 63 | } 64 | 65 | static int check_file(char *arg, FILE **f) 66 | { 67 | *f = fopen(arg, "r"); 68 | 69 | return (*f!=NULL); 70 | } 71 | 72 | static void handle_long_options(struct option option, char *arg) 73 | { 74 | if (!strcmp(option.name, "help")) 75 | usage(0); 76 | 77 | if (!strcmp(option.name, "config")) { 78 | if (!check_file(arg, &config_fptr)) { 79 | printf("'%s': invalid file\n", arg); 80 | fclose(config_fptr); 81 | usage(-3); 82 | } 83 | } 84 | 85 | if (!strcmp(option.name, "stats")) { 86 | if (!check_file(arg, &stats_fptr)) { 87 | printf("'%s': invalid file\n", arg); 88 | fclose(stats_fptr); 89 | usage(-3); 90 | } 91 | } 92 | 93 | if (!strcmp(option.name, "xmltemplate")) { 94 | strcpy(xml_file, arg); 95 | } 96 | 97 | if (!strcmp(option.name, "output")) { 98 | strcpy(out_file, arg); 99 | } 100 | } 101 | 102 | int handle_options(int argc, char **argv) 103 | { 104 | while (1) { 105 | int c; 106 | int flags = 0; 107 | int option_index = 0; 108 | 109 | c = getopt_long (argc, argv, "x:c:s:o:", 110 | long_options, &option_index); 111 | if (c == -1) 112 | break; 113 | 114 | switch (c) { 115 | case 0: 116 | handle_long_options(long_options[option_index], 117 | optarg); 118 | break; 119 | 120 | case 'c': 121 | if (!check_file(optarg, &config_fptr)) { 122 | printf("'%s': invalid file\n", optarg); 123 | fclose(config_fptr); 124 | usage(-3); 125 | } 126 | break; 127 | 128 | case 's': 129 | if (!check_file(optarg, &stats_fptr)) { 130 | printf("'%s': invalid file\n", optarg); 131 | fclose(stats_fptr); 132 | usage(-3); 133 | } 134 | break; 135 | case 'x': strcpy(xml_file, optarg); break; 136 | case 'o': strcpy(out_file, optarg); break; 137 | case '?': 138 | case 'h': 139 | usage(0); 140 | break; 141 | 142 | default: 143 | printf ("?? getopt returned character code 0%o ??\n", c); 144 | usage(-1); 145 | } 146 | } 147 | 148 | if (stats_fptr==NULL) { 149 | if (!check_file(stats_file, &stats_fptr)) { 150 | printf("'%s': invalid file\n", stats_file); 151 | fclose(stats_fptr); 152 | usage(-3); 153 | } 154 | } 155 | 156 | if (config_fptr==NULL) { 157 | if (!check_file(conf_file, &config_fptr)) { 158 | printf("'%s': invalid file\n", conf_file); 159 | fclose(config_fptr); 160 | usage(-3); 161 | } 162 | } 163 | 164 | return 0; 165 | } 166 | -------------------------------------------------------------------------------- /lib/isa.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2016 Marcos Horro 3 | * All rights reserved. MIT Licence 4 | * 5 | * Redistribution and use in source and binary forms, with or without 6 | * modification, are permitted provided that the following conditions are 7 | * met: redistributions of source code must retain the above copyright 8 | * notice, this list of conditions and the following disclaimer; 9 | * redistributions in binary form must reproduce the above copyright 10 | * notice, this list of conditions and the following disclaimer in the 11 | * documentation and/or other materials provided with the distribution; 12 | * neither the name of the copyright holders nor the names of its 13 | * contributors may be used to endorse or promote products derived from 14 | * this software without specific prior written permission. 15 | * 16 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 17 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 18 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 19 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 20 | * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 21 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 22 | * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 26 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 | * 28 | * Authors: Marcos Horro Varela 29 | * 30 | */ 31 | #ifndef ISA 32 | # define ISA 33 | 34 | /* Default to X86. */ 35 | # if !defined(ISA_X86) && !defined(ISA_ARM) && !defined(ISA_GENERIC) 36 | # define ISA_X86 37 | # endif 38 | 39 | /* Define the possible dataset sizes. */ 40 | # ifdef ISA_X86 41 | # define INT_EXE 2 42 | # define FP_EXE 8 43 | # endif 44 | 45 | # ifdef ISA_ARM 46 | # define INT_EXE 3 47 | # define FP_EXE 7 48 | # endif 49 | 50 | # ifdef ISA_GENERIC 51 | # define INT_EXE 3 52 | # define FP_EXE 6 53 | # endif 54 | 55 | #endif /* !ISA */ 56 | -------------------------------------------------------------------------------- /lib/utils.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2016 Marcos Horro 3 | * All rights reserved. MIT Licence 4 | * 5 | * Redistribution and use in source and binary forms, with or without 6 | * modification, are permitted provided that the following conditions are 7 | * met: redistributions of source code must retain the above copyright 8 | * notice, this list of conditions and the following disclaimer; 9 | * redistributions in binary form must reproduce the above copyright 10 | * notice, this list of conditions and the following disclaimer in the 11 | * documentation and/or other materials provided with the distribution; 12 | * neither the name of the copyright holders nor the names of its 13 | * contributors may be used to endorse or promote products derived from 14 | * this software without specific prior written permission. 15 | * 16 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 17 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 18 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 19 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 20 | * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 21 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 22 | * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 26 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 | * 28 | * Authors: Marcos Horro Varela 29 | * 30 | */ 31 | 32 | #include 33 | #include 34 | #include 35 | #include 36 | #include 37 | #include 38 | #include 39 | #include 40 | #include 41 | #include 42 | #include 43 | #include "colors.h" 44 | #include "isa.h" 45 | #include "copy.h" 46 | #include "xml/rapidxml.hpp" 47 | #include "xml/rapidxml_print.hpp" 48 | 49 | using namespace rapidxml; 50 | using namespace std; 51 | 52 | #ifndef VERSION 53 | #define VERSION "0.1" 54 | #endif 55 | 56 | #ifndef MAX 57 | #define MAX(X,Y) X>Y ? X : Y 58 | #endif 59 | 60 | #define MAX_NUM 1000 61 | #define MAX_LINE 1000 62 | 63 | struct t_mcpat_params { 64 | /* for x86 architectures */ 65 | int isa_x86 = 0; 66 | /* core parameters */ 67 | int clock_rate; 68 | int fetch_width = 4; 69 | int decode_width = 4; 70 | int issue_width = 4; 71 | int peak_issue_width = 6; 72 | int commit_width = 4; 73 | int instruction_buffer_size = 32; 74 | int instruction_window_size = 64; 75 | int fp_instruction_window_size = 64; 76 | int ROB_size = 128; 77 | int phy_Regs_IRF_size = 256; 78 | int phy_Regs_FRF_size = 256; 79 | int store_buffer_size = 96; 80 | int load_buffer_size = 48; 81 | int RAS_size = 64; 82 | /* to calculate base */ 83 | int nbase = 0; 84 | int base_stages = 0; 85 | int nmax_base = 0; 86 | int max_base = 0; 87 | int pipeline_depth[2] = {INT_EXE, FP_EXE}; 88 | /* branch predictor */ 89 | int load_predictor[3] = {0}; 90 | int global_predictor[2]; 91 | int predictor_chooser[2]; 92 | /* branch predictor buffer */ 93 | int BTB_config; 94 | /* cache parameters: TLB and caches */ 95 | int number_entries_dtlb; 96 | int number_entries_itlb; 97 | /* cache l1 */ 98 | int dcache_config[7]; 99 | int icache_config[7]; 100 | int dcache_buffer_sizes[4]; 101 | int icache_buffer_sizes[4]; 102 | 103 | int dhit_lat; 104 | int dresp_lat; 105 | int ihit_lat; 106 | int iresp_lat; 107 | 108 | /* cache l2 */ 109 | int l2_avail = 0; 110 | int L2_config[7]; 111 | int L2_buffer_sizes[4]; 112 | 113 | int l2hit_lat; 114 | int l2resp_lat; 115 | 116 | /* cache l3 */ 117 | int l3_avail = 0; 118 | int L3_config[7]; 119 | int L3_buffer_sizes[4]; 120 | 121 | int l3hit_lat; 122 | int l3resp_lat; 123 | 124 | /* ALUs latencies (default values) */ 125 | int lat_IntDiv = 20; 126 | int lat_IntMult = 3; 127 | 128 | /* main memory */ 129 | int memory_channels_per_mc = 1; 130 | int number_ranks = 2; 131 | int number_mcs = 1; // todo 132 | int block_size = 64; 133 | }; 134 | 135 | struct t_mcpat_stats { 136 | /* core statistics */ 137 | int total_instructions = 0; 138 | int branch_instructions = 0; 139 | int branch_mispredictions = 0; 140 | int load_instructions = 0; 141 | int store_instructions = 0; 142 | int committed_int_instructions = 0; 143 | int committed_fp_instructions = 0; 144 | double pipeline_duty_cycle = 0.0; 145 | int total_cycles = 0; 146 | int idle_cycles = 0; 147 | int ROB_reads = 0; 148 | int ROB_writes = 0; 149 | int rename_reads = 0; 150 | int rename_writes = 0; 151 | int fp_rename_reads = 0; 152 | int fp_rename_writes = 0; 153 | int inst_window_reads = 0; 154 | int inst_window_writes = 0; 155 | int inst_window_wakeup_accesses = 0; 156 | 157 | int fp_inst_window_reads = 0; 158 | int fp_inst_window_writes = 0; 159 | int fp_inst_window_wakeup_accesses = 0; 160 | int int_regfile_reads = 0; 161 | int int_regfile_writes = 0; 162 | int float_regfile_reads = 0; 163 | int float_regfile_writes = 0; 164 | int function_calls = 0; 165 | /* formulas */ 166 | int ialu_accesses = 0; 167 | int fpu_accesses = 0; 168 | int mul_accesses = 0; 169 | /* btb stats */ 170 | int btb_read_accesses = 0; 171 | int btb_write_accesses = 0; 172 | /* tlb L1 */ 173 | int dtlb_total_accesses = 0; 174 | int dtlb_total_misses = 0; 175 | int itlb_total_accesses = 0; 176 | int itlb_total_misses = 0; 177 | 178 | /* aux: default values */ 179 | int IntDiv = 0; 180 | int IntMult = 0; 181 | int overall_access[4] = {0}; 182 | int overall_misses[4] = {0}; 183 | int WriteReq_access[4] = {0}; 184 | int WriteReq_hits[2] = {0}; // i1/d1 185 | int WriteReq_misses[4] = {0}; 186 | int Writeback_accesses[4] = {0}; 187 | int Writeback_misses = 0; // l2 188 | int Writeback_misses_l3 = 0; // l3 189 | 190 | /* main memory */ 191 | int memory_reads = 0; 192 | int memory_writes = 0; 193 | }; 194 | 195 | struct t_error { 196 | int n_stat = 0; 197 | int stat_l[MAX_NUM] = {0}; 198 | char *stat[MAX_NUM]; 199 | 200 | int n_config = 0; 201 | int config_l[MAX_NUM] = {0}; 202 | char *config[MAX_NUM]; 203 | }; 204 | 205 | FILE *config_fptr = NULL; 206 | FILE *stats_fptr = NULL; 207 | char xml_file[80] = "template.xml"; 208 | char out_file[80] = "out.xml"; 209 | char conf_file[80] = "config.ini"; 210 | char stats_file[80] = "stats.txt"; 211 | 212 | // function headers 213 | void usage(int i); 214 | int handle_options(int argc, char **argv); 215 | char *make_tuple(int n, int v[]); 216 | void init_param(t_mcpat_params *p); 217 | 218 | // simple function to create a tuple with n values 219 | // like [value1],[value2],...,[valuen] 220 | char *make_tuple(int n, ...) 221 | { 222 | int i; 223 | char *aux = (char *) malloc(sizeof(char)*80); 224 | char str1[50], str2[50]; 225 | 226 | va_list ap; 227 | va_start(ap, n); 228 | int v = va_arg(ap, int); 229 | snprintf(str1, 50, "%d", v); 230 | for (i=0; i < n-1; i++) { 231 | strcat(str1, ","); 232 | v = va_arg(ap, int); 233 | snprintf(str2, 50, "%d", v); 234 | strcat(str1, str2); 235 | } 236 | strcpy(aux, str1); 237 | 238 | return aux; 239 | } 240 | 241 | // due to C++11 it is needed to initialize like this 242 | // the initialization is needed in case the execution 243 | // does not provide the minimum params for McPAT 244 | void init_param(t_mcpat_params *p) 245 | { 246 | /* CORE PARAMS */ 247 | p->fetch_width = 4; 248 | p->decode_width = 4; 249 | p->issue_width = 4; 250 | p->peak_issue_width = 6; 251 | p->commit_width = 4; 252 | p->instruction_buffer_size = 32; 253 | p->instruction_window_size = 64; 254 | p->fp_instruction_window_size = 64; 255 | p->ROB_size = 128; 256 | p->phy_Regs_IRF_size = 256; 257 | p->phy_Regs_FRF_size = 256; 258 | p->store_buffer_size = 96; 259 | p->load_buffer_size = 48; 260 | p->RAS_size = 64; 261 | /* BTB */ 262 | p->BTB_config = 4096; 263 | /* PBT */ 264 | p->load_predictor[0] = 10; 265 | p->load_predictor[1] = 3; 266 | p->load_predictor[2] = 1024; 267 | p->global_predictor[0] = 4096; 268 | p->global_predictor[1] = 2; 269 | p->predictor_chooser[0] = 4096; 270 | p->predictor_chooser[1] = 2; 271 | } 272 | -------------------------------------------------------------------------------- /lib/xml/license.txt: -------------------------------------------------------------------------------- 1 | Use of this software is granted under one of the following two licenses, 2 | to be chosen freely by the user. 3 | 4 | 1. Boost Software License - Version 1.0 - August 17th, 2003 5 | =============================================================================== 6 | 7 | Copyright (c) 2006, 2007 Marcin Kalicinski 8 | 9 | Permission is hereby granted, free of charge, to any person or organization 10 | obtaining a copy of the software and accompanying documentation covered by 11 | this license (the "Software") to use, reproduce, display, distribute, 12 | execute, and transmit the Software, and to prepare derivative works of the 13 | Software, and to permit third-parties to whom the Software is furnished to 14 | do so, all subject to the following: 15 | 16 | The copyright notices in the Software and this entire statement, including 17 | the above license grant, this restriction and the following disclaimer, 18 | must be included in all copies of the Software, in whole or in part, and 19 | all derivative works of the Software, unless such copies or derivative 20 | works are solely in the form of machine-executable object code generated by 21 | a source language processor. 22 | 23 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 24 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 25 | FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT 26 | SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE 27 | FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, 28 | ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 29 | DEALINGS IN THE SOFTWARE. 30 | 31 | 2. The MIT License 32 | =============================================================================== 33 | 34 | Copyright (c) 2006, 2007 Marcin Kalicinski 35 | 36 | Permission is hereby granted, free of charge, to any person obtaining a copy 37 | of this software and associated documentation files (the "Software"), to deal 38 | in the Software without restriction, including without limitation the rights 39 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies 40 | of the Software, and to permit persons to whom the Software is furnished to do so, 41 | subject to the following conditions: 42 | 43 | The above copyright notice and this permission notice shall be included in all 44 | copies or substantial portions of the Software. 45 | 46 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 47 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 48 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 49 | THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 50 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 51 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 52 | IN THE SOFTWARE. 53 | -------------------------------------------------------------------------------- /lib/xml/rapidxml_iterators.hpp: -------------------------------------------------------------------------------- 1 | #ifndef RAPIDXML_ITERATORS_HPP_INCLUDED 2 | #define RAPIDXML_ITERATORS_HPP_INCLUDED 3 | 4 | // Copyright (C) 2006, 2009 Marcin Kalicinski 5 | // Version 1.13 6 | // Revision $DateTime: 2009/05/13 01:46:17 $ 7 | //! \file rapidxml_iterators.hpp This file contains rapidxml iterators 8 | 9 | #include "rapidxml.hpp" 10 | 11 | namespace rapidxml 12 | { 13 | 14 | //! Iterator of child nodes of xml_node 15 | template 16 | class node_iterator 17 | { 18 | 19 | public: 20 | 21 | typedef typename xml_node value_type; 22 | typedef typename xml_node &reference; 23 | typedef typename xml_node *pointer; 24 | typedef std::ptrdiff_t difference_type; 25 | typedef std::bidirectional_iterator_tag iterator_category; 26 | 27 | node_iterator() 28 | : m_node(0) 29 | { 30 | } 31 | 32 | node_iterator(xml_node *node) 33 | : m_node(node->first_node()) 34 | { 35 | } 36 | 37 | reference operator *() const 38 | { 39 | assert(m_node); 40 | return *m_node; 41 | } 42 | 43 | pointer operator->() const 44 | { 45 | assert(m_node); 46 | return m_node; 47 | } 48 | 49 | node_iterator& operator++() 50 | { 51 | assert(m_node); 52 | m_node = m_node->next_sibling(); 53 | return *this; 54 | } 55 | 56 | node_iterator operator++(int) 57 | { 58 | node_iterator tmp = *this; 59 | ++this; 60 | return tmp; 61 | } 62 | 63 | node_iterator& operator--() 64 | { 65 | assert(m_node && m_node->previous_sibling()); 66 | m_node = m_node->previous_sibling(); 67 | return *this; 68 | } 69 | 70 | node_iterator operator--(int) 71 | { 72 | node_iterator tmp = *this; 73 | ++this; 74 | return tmp; 75 | } 76 | 77 | bool operator ==(const node_iterator &rhs) 78 | { 79 | return m_node == rhs.m_node; 80 | } 81 | 82 | bool operator !=(const node_iterator &rhs) 83 | { 84 | return m_node != rhs.m_node; 85 | } 86 | 87 | private: 88 | 89 | xml_node *m_node; 90 | 91 | }; 92 | 93 | //! Iterator of child attributes of xml_node 94 | template 95 | class attribute_iterator 96 | { 97 | 98 | public: 99 | 100 | typedef typename xml_attribute value_type; 101 | typedef typename xml_attribute &reference; 102 | typedef typename xml_attribute *pointer; 103 | typedef std::ptrdiff_t difference_type; 104 | typedef std::bidirectional_iterator_tag iterator_category; 105 | 106 | attribute_iterator() 107 | : m_attribute(0) 108 | { 109 | } 110 | 111 | attribute_iterator(xml_node *node) 112 | : m_attribute(node->first_attribute()) 113 | { 114 | } 115 | 116 | reference operator *() const 117 | { 118 | assert(m_attribute); 119 | return *m_attribute; 120 | } 121 | 122 | pointer operator->() const 123 | { 124 | assert(m_attribute); 125 | return m_attribute; 126 | } 127 | 128 | attribute_iterator& operator++() 129 | { 130 | assert(m_attribute); 131 | m_attribute = m_attribute->next_attribute(); 132 | return *this; 133 | } 134 | 135 | attribute_iterator operator++(int) 136 | { 137 | attribute_iterator tmp = *this; 138 | ++this; 139 | return tmp; 140 | } 141 | 142 | attribute_iterator& operator--() 143 | { 144 | assert(m_attribute && m_attribute->previous_attribute()); 145 | m_attribute = m_attribute->previous_attribute(); 146 | return *this; 147 | } 148 | 149 | attribute_iterator operator--(int) 150 | { 151 | attribute_iterator tmp = *this; 152 | ++this; 153 | return tmp; 154 | } 155 | 156 | bool operator ==(const attribute_iterator &rhs) 157 | { 158 | return m_attribute == rhs.m_attribute; 159 | } 160 | 161 | bool operator !=(const attribute_iterator &rhs) 162 | { 163 | return m_attribute != rhs.m_attribute; 164 | } 165 | 166 | private: 167 | 168 | xml_attribute *m_attribute; 169 | 170 | }; 171 | 172 | } 173 | 174 | #endif 175 | -------------------------------------------------------------------------------- /lib/xml/rapidxml_print.hpp: -------------------------------------------------------------------------------- 1 | #ifndef RAPIDXML_PRINT_HPP_INCLUDED 2 | #define RAPIDXML_PRINT_HPP_INCLUDED 3 | 4 | // Copyright (C) 2006, 2009 Marcin Kalicinski 5 | // Version 1.13 6 | // Revision $DateTime: 2009/05/13 01:46:17 $ 7 | //! \file rapidxml_print.hpp This file contains rapidxml printer implementation 8 | 9 | #include "rapidxml.hpp" 10 | 11 | // Only include streams if not disabled 12 | #ifndef RAPIDXML_NO_STREAMS 13 | #include 14 | #include 15 | #endif 16 | 17 | namespace rapidxml 18 | { 19 | 20 | /////////////////////////////////////////////////////////////////////// 21 | // Printing flags 22 | 23 | const int print_no_indenting = 0x1; //!< Printer flag instructing the printer to suppress indenting of XML. See print() function. 24 | 25 | /////////////////////////////////////////////////////////////////////// 26 | // Internal 27 | 28 | //! \cond internal 29 | namespace internal 30 | { 31 | 32 | /////////////////////////////////////////////////////////////////////////// 33 | // Internal character operations 34 | 35 | // Copy characters from given range to given output iterator 36 | template 37 | inline OutIt copy_chars(const Ch *begin, const Ch *end, OutIt out) 38 | { 39 | while (begin != end) 40 | *out++ = *begin++; 41 | return out; 42 | } 43 | 44 | // Copy characters from given range to given output iterator and expand 45 | // characters into references (< > ' " &) 46 | template 47 | inline OutIt copy_and_expand_chars(const Ch *begin, const Ch *end, Ch noexpand, OutIt out) 48 | { 49 | while (begin != end) 50 | { 51 | if (*begin == noexpand) 52 | { 53 | *out++ = *begin; // No expansion, copy character 54 | } 55 | else 56 | { 57 | switch (*begin) 58 | { 59 | case Ch('<'): 60 | *out++ = Ch('&'); *out++ = Ch('l'); *out++ = Ch('t'); *out++ = Ch(';'); 61 | break; 62 | case Ch('>'): 63 | *out++ = Ch('&'); *out++ = Ch('g'); *out++ = Ch('t'); *out++ = Ch(';'); 64 | break; 65 | case Ch('\''): 66 | *out++ = Ch('&'); *out++ = Ch('a'); *out++ = Ch('p'); *out++ = Ch('o'); *out++ = Ch('s'); *out++ = Ch(';'); 67 | break; 68 | case Ch('"'): 69 | *out++ = Ch('&'); *out++ = Ch('q'); *out++ = Ch('u'); *out++ = Ch('o'); *out++ = Ch('t'); *out++ = Ch(';'); 70 | break; 71 | case Ch('&'): 72 | *out++ = Ch('&'); *out++ = Ch('a'); *out++ = Ch('m'); *out++ = Ch('p'); *out++ = Ch(';'); 73 | break; 74 | default: 75 | *out++ = *begin; // No expansion, copy character 76 | } 77 | } 78 | ++begin; // Step to next character 79 | } 80 | return out; 81 | } 82 | 83 | // Fill given output iterator with repetitions of the same character 84 | template 85 | inline OutIt fill_chars(OutIt out, int n, Ch ch) 86 | { 87 | for (int i = 0; i < n; ++i) 88 | *out++ = ch; 89 | return out; 90 | } 91 | 92 | // Find character 93 | template 94 | inline bool find_char(const Ch *begin, const Ch *end) 95 | { 96 | while (begin != end) 97 | if (*begin++ == ch) 98 | return true; 99 | return false; 100 | } 101 | 102 | /////////////////////////////////////////////////////////////////////////// 103 | // Internal printing operations 104 | 105 | template 106 | inline OutIt print_children(OutIt out, const xml_node *node, int flags, int indent); 107 | 108 | template 109 | inline OutIt print_attributes(OutIt out, const xml_node *node, int flags); 110 | 111 | template 112 | inline OutIt print_data_node(OutIt out, const xml_node *node, int flags, int indent); 113 | 114 | template 115 | inline OutIt print_cdata_node(OutIt out, const xml_node *node, int flags, int indent); 116 | 117 | template 118 | inline OutIt print_element_node(OutIt out, const xml_node *node, int flags, int indent); 119 | 120 | template 121 | inline OutIt print_declaration_node(OutIt out, const xml_node *node, int flags, int indent); 122 | 123 | template 124 | inline OutIt print_comment_node(OutIt out, const xml_node *node, int flags, int indent); 125 | 126 | template 127 | inline OutIt print_doctype_node(OutIt out, const xml_node *node, int flags, int indent); 128 | 129 | template 130 | inline OutIt print_pi_node(OutIt out, const xml_node *node, int flags, int indent); 131 | 132 | // Print node 133 | template 134 | inline OutIt print_node(OutIt out, const xml_node *node, int flags, int indent) 135 | { 136 | // Print proper node type 137 | switch (node->type()) 138 | { 139 | 140 | // Document 141 | case node_document: 142 | out = print_children(out, node, flags, indent); 143 | break; 144 | 145 | // Element 146 | case node_element: 147 | out = print_element_node(out, node, flags, indent); 148 | break; 149 | 150 | // Data 151 | case node_data: 152 | out = print_data_node(out, node, flags, indent); 153 | break; 154 | 155 | // CDATA 156 | case node_cdata: 157 | out = print_cdata_node(out, node, flags, indent); 158 | break; 159 | 160 | // Declaration 161 | case node_declaration: 162 | out = print_declaration_node(out, node, flags, indent); 163 | break; 164 | 165 | // Comment 166 | case node_comment: 167 | out = print_comment_node(out, node, flags, indent); 168 | break; 169 | 170 | // Doctype 171 | case node_doctype: 172 | out = print_doctype_node(out, node, flags, indent); 173 | break; 174 | 175 | // Pi 176 | case node_pi: 177 | out = print_pi_node(out, node, flags, indent); 178 | break; 179 | 180 | // Unknown 181 | default: 182 | assert(0); 183 | break; 184 | } 185 | 186 | // If indenting not disabled, add line break after node 187 | if (!(flags & print_no_indenting)) 188 | *out = Ch('\n'), ++out; 189 | 190 | // Return modified iterator 191 | return out; 192 | } 193 | 194 | // Print children of the node 195 | template 196 | inline OutIt print_children(OutIt out, const xml_node *node, int flags, int indent) 197 | { 198 | for (xml_node *child = node->first_node(); child; child = child->next_sibling()) 199 | out = print_node(out, child, flags, indent); 200 | return out; 201 | } 202 | 203 | // Print attributes of the node 204 | template 205 | inline OutIt print_attributes(OutIt out, const xml_node *node, int flags) 206 | { 207 | for (xml_attribute *attribute = node->first_attribute(); attribute; attribute = attribute->next_attribute()) 208 | { 209 | if (attribute->name() && attribute->value()) 210 | { 211 | // Print attribute name 212 | *out = Ch(' '), ++out; 213 | out = copy_chars(attribute->name(), attribute->name() + attribute->name_size(), out); 214 | *out = Ch('='), ++out; 215 | // Print attribute value using appropriate quote type 216 | if (find_char(attribute->value(), attribute->value() + attribute->value_size())) 217 | { 218 | *out = Ch('\''), ++out; 219 | out = copy_and_expand_chars(attribute->value(), attribute->value() + attribute->value_size(), Ch('"'), out); 220 | *out = Ch('\''), ++out; 221 | } 222 | else 223 | { 224 | *out = Ch('"'), ++out; 225 | out = copy_and_expand_chars(attribute->value(), attribute->value() + attribute->value_size(), Ch('\''), out); 226 | *out = Ch('"'), ++out; 227 | } 228 | } 229 | } 230 | return out; 231 | } 232 | 233 | // Print data node 234 | template 235 | inline OutIt print_data_node(OutIt out, const xml_node *node, int flags, int indent) 236 | { 237 | assert(node->type() == node_data); 238 | if (!(flags & print_no_indenting)) 239 | out = fill_chars(out, indent, Ch('\t')); 240 | out = copy_and_expand_chars(node->value(), node->value() + node->value_size(), Ch(0), out); 241 | return out; 242 | } 243 | 244 | // Print data node 245 | template 246 | inline OutIt print_cdata_node(OutIt out, const xml_node *node, int flags, int indent) 247 | { 248 | assert(node->type() == node_cdata); 249 | if (!(flags & print_no_indenting)) 250 | out = fill_chars(out, indent, Ch('\t')); 251 | *out = Ch('<'); ++out; 252 | *out = Ch('!'); ++out; 253 | *out = Ch('['); ++out; 254 | *out = Ch('C'); ++out; 255 | *out = Ch('D'); ++out; 256 | *out = Ch('A'); ++out; 257 | *out = Ch('T'); ++out; 258 | *out = Ch('A'); ++out; 259 | *out = Ch('['); ++out; 260 | out = copy_chars(node->value(), node->value() + node->value_size(), out); 261 | *out = Ch(']'); ++out; 262 | *out = Ch(']'); ++out; 263 | *out = Ch('>'); ++out; 264 | return out; 265 | } 266 | 267 | // Print element node 268 | template 269 | inline OutIt print_element_node(OutIt out, const xml_node *node, int flags, int indent) 270 | { 271 | assert(node->type() == node_element); 272 | 273 | // Print element name and attributes, if any 274 | if (!(flags & print_no_indenting)) 275 | out = fill_chars(out, indent, Ch('\t')); 276 | *out = Ch('<'), ++out; 277 | out = copy_chars(node->name(), node->name() + node->name_size(), out); 278 | out = print_attributes(out, node, flags); 279 | 280 | // If node is childless 281 | if (node->value_size() == 0 && !node->first_node()) 282 | { 283 | // Print childless node tag ending 284 | *out = Ch('/'), ++out; 285 | *out = Ch('>'), ++out; 286 | } 287 | else 288 | { 289 | // Print normal node tag ending 290 | *out = Ch('>'), ++out; 291 | 292 | // Test if node contains a single data node only (and no other nodes) 293 | xml_node *child = node->first_node(); 294 | if (!child) 295 | { 296 | // If node has no children, only print its value without indenting 297 | out = copy_and_expand_chars(node->value(), node->value() + node->value_size(), Ch(0), out); 298 | } 299 | else if (child->next_sibling() == 0 && child->type() == node_data) 300 | { 301 | // If node has a sole data child, only print its value without indenting 302 | out = copy_and_expand_chars(child->value(), child->value() + child->value_size(), Ch(0), out); 303 | } 304 | else 305 | { 306 | // Print all children with full indenting 307 | if (!(flags & print_no_indenting)) 308 | *out = Ch('\n'), ++out; 309 | out = print_children(out, node, flags, indent + 1); 310 | if (!(flags & print_no_indenting)) 311 | out = fill_chars(out, indent, Ch('\t')); 312 | } 313 | 314 | // Print node end 315 | *out = Ch('<'), ++out; 316 | *out = Ch('/'), ++out; 317 | out = copy_chars(node->name(), node->name() + node->name_size(), out); 318 | *out = Ch('>'), ++out; 319 | } 320 | return out; 321 | } 322 | 323 | // Print declaration node 324 | template 325 | inline OutIt print_declaration_node(OutIt out, const xml_node *node, int flags, int indent) 326 | { 327 | // Print declaration start 328 | if (!(flags & print_no_indenting)) 329 | out = fill_chars(out, indent, Ch('\t')); 330 | *out = Ch('<'), ++out; 331 | *out = Ch('?'), ++out; 332 | *out = Ch('x'), ++out; 333 | *out = Ch('m'), ++out; 334 | *out = Ch('l'), ++out; 335 | 336 | // Print attributes 337 | out = print_attributes(out, node, flags); 338 | 339 | // Print declaration end 340 | *out = Ch('?'), ++out; 341 | *out = Ch('>'), ++out; 342 | 343 | return out; 344 | } 345 | 346 | // Print comment node 347 | template 348 | inline OutIt print_comment_node(OutIt out, const xml_node *node, int flags, int indent) 349 | { 350 | assert(node->type() == node_comment); 351 | if (!(flags & print_no_indenting)) 352 | out = fill_chars(out, indent, Ch('\t')); 353 | *out = Ch('<'), ++out; 354 | *out = Ch('!'), ++out; 355 | *out = Ch('-'), ++out; 356 | *out = Ch('-'), ++out; 357 | out = copy_chars(node->value(), node->value() + node->value_size(), out); 358 | *out = Ch('-'), ++out; 359 | *out = Ch('-'), ++out; 360 | *out = Ch('>'), ++out; 361 | return out; 362 | } 363 | 364 | // Print doctype node 365 | template 366 | inline OutIt print_doctype_node(OutIt out, const xml_node *node, int flags, int indent) 367 | { 368 | assert(node->type() == node_doctype); 369 | if (!(flags & print_no_indenting)) 370 | out = fill_chars(out, indent, Ch('\t')); 371 | *out = Ch('<'), ++out; 372 | *out = Ch('!'), ++out; 373 | *out = Ch('D'), ++out; 374 | *out = Ch('O'), ++out; 375 | *out = Ch('C'), ++out; 376 | *out = Ch('T'), ++out; 377 | *out = Ch('Y'), ++out; 378 | *out = Ch('P'), ++out; 379 | *out = Ch('E'), ++out; 380 | *out = Ch(' '), ++out; 381 | out = copy_chars(node->value(), node->value() + node->value_size(), out); 382 | *out = Ch('>'), ++out; 383 | return out; 384 | } 385 | 386 | // Print pi node 387 | template 388 | inline OutIt print_pi_node(OutIt out, const xml_node *node, int flags, int indent) 389 | { 390 | assert(node->type() == node_pi); 391 | if (!(flags & print_no_indenting)) 392 | out = fill_chars(out, indent, Ch('\t')); 393 | *out = Ch('<'), ++out; 394 | *out = Ch('?'), ++out; 395 | out = copy_chars(node->name(), node->name() + node->name_size(), out); 396 | *out = Ch(' '), ++out; 397 | out = copy_chars(node->value(), node->value() + node->value_size(), out); 398 | *out = Ch('?'), ++out; 399 | *out = Ch('>'), ++out; 400 | return out; 401 | } 402 | 403 | } 404 | //! \endcond 405 | 406 | /////////////////////////////////////////////////////////////////////////// 407 | // Printing 408 | 409 | //! Prints XML to given output iterator. 410 | //! \param out Output iterator to print to. 411 | //! \param node Node to be printed. Pass xml_document to print entire document. 412 | //! \param flags Flags controlling how XML is printed. 413 | //! \return Output iterator pointing to position immediately after last character of printed text. 414 | template 415 | inline OutIt print(OutIt out, const xml_node &node, int flags = 0) 416 | { 417 | return internal::print_node(out, &node, flags, 0); 418 | } 419 | 420 | #ifndef RAPIDXML_NO_STREAMS 421 | 422 | //! Prints XML to given output stream. 423 | //! \param out Output stream to print to. 424 | //! \param node Node to be printed. Pass xml_document to print entire document. 425 | //! \param flags Flags controlling how XML is printed. 426 | //! \return Output stream. 427 | template 428 | inline std::basic_ostream &print(std::basic_ostream &out, const xml_node &node, int flags = 0) 429 | { 430 | print(std::ostream_iterator(out), node, flags); 431 | return out; 432 | } 433 | 434 | //! Prints formatted XML to given output stream. Uses default printing flags. Use print() function to customize printing process. 435 | //! \param out Output stream to print to. 436 | //! \param node Node to be printed. 437 | //! \return Output stream. 438 | template 439 | inline std::basic_ostream &operator <<(std::basic_ostream &out, const xml_node &node) 440 | { 441 | return print(out, node); 442 | } 443 | 444 | #endif 445 | 446 | } 447 | 448 | #endif 449 | -------------------------------------------------------------------------------- /lib/xml/rapidxml_utils.hpp: -------------------------------------------------------------------------------- 1 | #ifndef RAPIDXML_UTILS_HPP_INCLUDED 2 | #define RAPIDXML_UTILS_HPP_INCLUDED 3 | 4 | // Copyright (C) 2006, 2009 Marcin Kalicinski 5 | // Version 1.13 6 | // Revision $DateTime: 2009/05/13 01:46:17 $ 7 | //! \file rapidxml_utils.hpp This file contains high-level rapidxml utilities that can be useful 8 | //! in certain simple scenarios. They should probably not be used if maximizing performance is the main objective. 9 | 10 | #include "rapidxml.hpp" 11 | #include 12 | #include 13 | #include 14 | #include 15 | 16 | namespace rapidxml 17 | { 18 | 19 | //! Represents data loaded from a file 20 | template 21 | class file 22 | { 23 | 24 | public: 25 | 26 | //! Loads file into the memory. Data will be automatically destroyed by the destructor. 27 | //! \param filename Filename to load. 28 | file(const char *filename) 29 | { 30 | using namespace std; 31 | 32 | // Open stream 33 | basic_ifstream stream(filename, ios::binary); 34 | if (!stream) 35 | throw runtime_error(string("cannot open file ") + filename); 36 | stream.unsetf(ios::skipws); 37 | 38 | // Determine stream size 39 | stream.seekg(0, ios::end); 40 | size_t size = stream.tellg(); 41 | stream.seekg(0); 42 | 43 | // Load data and add terminating 0 44 | m_data.resize(size + 1); 45 | stream.read(&m_data.front(), static_cast(size)); 46 | m_data[size] = 0; 47 | } 48 | 49 | //! Loads file into the memory. Data will be automatically destroyed by the destructor 50 | //! \param stream Stream to load from 51 | file(std::basic_istream &stream) 52 | { 53 | using namespace std; 54 | 55 | // Load data and add terminating 0 56 | stream.unsetf(ios::skipws); 57 | m_data.assign(istreambuf_iterator(stream), istreambuf_iterator()); 58 | if (stream.fail() || stream.bad()) 59 | throw runtime_error("error reading stream"); 60 | m_data.push_back(0); 61 | } 62 | 63 | //! Gets file data. 64 | //! \return Pointer to data of file. 65 | Ch *data() 66 | { 67 | return &m_data.front(); 68 | } 69 | 70 | //! Gets file data. 71 | //! \return Pointer to data of file. 72 | const Ch *data() const 73 | { 74 | return &m_data.front(); 75 | } 76 | 77 | //! Gets file data size. 78 | //! \return Size of file data, in characters. 79 | std::size_t size() const 80 | { 81 | return m_data.size(); 82 | } 83 | 84 | private: 85 | 86 | std::vector m_data; // File data 87 | 88 | }; 89 | 90 | //! Counts children of node. Time complexity is O(n). 91 | //! \return Number of children of node 92 | template 93 | inline std::size_t count_children(xml_node *node) 94 | { 95 | xml_node *child = node->first_node(); 96 | std::size_t count = 0; 97 | while (child) 98 | { 99 | ++count; 100 | child = child->next_sibling(); 101 | } 102 | return count; 103 | } 104 | 105 | //! Counts attributes of node. Time complexity is O(n). 106 | //! \return Number of attributes of node 107 | template 108 | inline std::size_t count_attributes(xml_node *node) 109 | { 110 | xml_attribute *attr = node->first_attribute(); 111 | std::size_t count = 0; 112 | while (attr) 113 | { 114 | ++count; 115 | attr = attr->next_attribute(); 116 | } 117 | return count; 118 | } 119 | 120 | } 121 | 122 | #endif 123 | -------------------------------------------------------------------------------- /makefile: -------------------------------------------------------------------------------- 1 | # This makefile allows to compile and run the parser 2 | 3 | COMP=g++ 4 | XMLTEMPLATE=template.xml 5 | OUTPUT=out.xml 6 | CONF=config.ini 7 | STATS=stats.txt 8 | BIN=gem5McPATparse 9 | FLAGS=-lfl -ly -std=c++11 10 | PARS=parser 11 | .PHONY: compile run clean 12 | 13 | compile: parser.l parser.y 14 | flex $(PARS).l 15 | bison -o $(PARS).tab.c $(PARS).y -yd 16 | $(COMP) -o $(BIN) lex.yy.c $(PARS).tab.c $(FLAGS) 17 | 18 | run: 19 | ./$(BIN) -x $(XMLTEMPLATE) -c $(CONF) -s $(STATS) -o $(OUTPUT) 20 | 21 | clean: 22 | -rm *.yy.c *.tab.c *.out *.tab.h stack.hh $(OUTPUT) $(BIN) 23 | -------------------------------------------------------------------------------- /parser.l: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2016 Marcos Horro 3 | * All rights reserved. MIT Licence 4 | * 5 | * Redistribution and use in source and binary forms, with or without 6 | * modification, are permitted provided that the following conditions are 7 | * met: redistributions of source code must retain the above copyright 8 | * notice, this list of conditions and the following disclaimer; 9 | * redistributions in binary form must reproduce the above copyright 10 | * notice, this list of conditions and the following disclaimer in the 11 | * documentation and/or other materials provided with the distribution; 12 | * neither the name of the copyright holders nor the names of its 13 | * contributors may be used to endorse or promote products derived from 14 | * this software without specific prior written permission. 15 | * 16 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 17 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 18 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 19 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 20 | * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 21 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 22 | * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 26 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 | * 28 | * Authors: Marcos Horro Varela 29 | * 30 | */ 31 | %option yylineno noyywrap nodefault stack 32 | %{ 33 | #include "parser.tab.h" 34 | 35 | /* THIS WAY IS POSSIBLE TO RETURN TO PREVIOUS STATE */ 36 | int PREV_STATE = -1; 37 | 38 | %} 39 | %x CLK 40 | %x ISA 41 | 42 | %x LATENCY 43 | 44 | %x DTLB 45 | %x ITLB 46 | 47 | %x DL1 48 | %x DL1TAGS 49 | %x IL1 50 | %x IL1TAGS 51 | 52 | %x L2 53 | %x L2TAGS 54 | 55 | %x L3 56 | %x L3TAGS 57 | 58 | %x MMEM 59 | 60 | %x DELIM 61 | %x VALUE 62 | 63 | digit [0-9] 64 | double {digit}+"."{digit}+ 65 | letter [a-zA-Z] 66 | alphanum [a-zA-Z0-9] 67 | str {letter}+ 68 | ws [ ] 69 | eq "=" 70 | ignore [a-zA-Z0-9\-\/\[\]\.\_\:\#\(\)\+\,\%\'\;]+ 71 | fetchWidth "fetchWidth" 72 | decodeWidth "decodeWidth" 73 | issueWidth "issueWidth" 74 | commitWidth "commitWidth" 75 | fetchBufferSize "fetchBufferSize" 76 | numIQEntries "numIQEntries" 77 | numROBEntries "numROBEntries" 78 | numPhysIntRegs "numPhysIntRegs" 79 | numPhysFloatRegs "numPhysFloatRegs" 80 | SQEntries "SQEntries" 81 | LQEntries "LQEntries" 82 | RASSize "RASSize" 83 | f2DecodeDelay "fetchToDecodeDelay" 84 | d2RenameDelay "decodeToRenameDelay" 85 | r2IEWDelay "renameToIEWDelay" 86 | i2CommitDelay "iewToCommitDelay" 87 | c2DecodeDelay "commitToDecodeDelay" 88 | c2FetchDelay "commitToFetchDelay" 89 | c2IEWDelay "commitToIEWDelay" 90 | c2RenameDelay "commitToRenameDelay" 91 | lHistBits "localHistoryBits" 92 | lCtrBits "localCtrBits" 93 | lPredictorSize "localPredictorSize" 94 | gPredictorSize "globalPredictorSize" 95 | gCtrBits "globalCtrBits" 96 | cPredictorSize "choicePredictorSize" 97 | cCtrBits "choiceCtrBits" 98 | BTBEntries "BTBEntries" 99 | CPU "system.cpu." 100 | SYS "system." 101 | SL2 "system.l2." 102 | SL3 "system.l3." 103 | DTB "system.cpu.dtb_walker_cache.tags." 104 | ITB "system.cpu.itb_walker_cache.tags." 105 | D1 "system.cpu.dcache." 106 | I1 "system.cpu.icache." 107 | %% 108 | 109 | /* CLOCK */ 110 | "[system.clk_domain]" { 111 | BEGIN(CLK); 112 | } 113 | 114 | "clock" { 115 | BEGIN(VALUE); 116 | return SYSCLK; 117 | } 118 | 119 | /* MEM MODE */ 120 | "mem_mode" { 121 | BEGIN(VALUE); 122 | return M_MODE; 123 | } 124 | 125 | /* ISA type. QUITE MESSY... */ 126 | 127 | "[system.cpu.isa]\n" { 128 | BEGIN(ISA); 129 | } 130 | 131 | "type=" { 132 | return ISA_T; 133 | } 134 | 135 | {alphanum}+ { 136 | /* it is not a real string but it is easier 137 | then to compare a string */ 138 | yylval.t_str = yytext; 139 | BEGIN(INITIAL); 140 | return STR; 141 | } 142 | 143 | /* core parameters */ 144 | /* FETCHWIDTH */ 145 | {fetchWidth} { 146 | BEGIN(VALUE); 147 | return FETCHW; 148 | } 149 | 150 | /* DECODEWIDTH */ 151 | {decodeWidth} { 152 | BEGIN(VALUE); 153 | return DECODEW; 154 | } 155 | 156 | /* ISSUEWIDTH */ 157 | {issueWidth} { 158 | BEGIN(VALUE); 159 | return ISSUEW; 160 | } 161 | 162 | /* COMMITWIDTH */ 163 | {commitWidth} { 164 | BEGIN(VALUE); 165 | return COMMITW; 166 | } 167 | 168 | /* fetchBufferSize */ 169 | {fetchBufferSize} { 170 | BEGIN(VALUE); 171 | return BUFFERS; 172 | } 173 | 174 | /* numIQEntries */ 175 | {numIQEntries} { 176 | BEGIN(VALUE); 177 | return NIQENTRIES; 178 | } 179 | 180 | /* numROBEntries */ 181 | {numROBEntries} { 182 | BEGIN(VALUE); 183 | return NROBENTRIES; 184 | } 185 | 186 | /* numPhysIntRegs */ 187 | {numPhysIntRegs} { 188 | BEGIN(VALUE); 189 | return NINTREGS; 190 | } 191 | 192 | /* numPhysFloatRegs */ 193 | {numPhysFloatRegs} { 194 | BEGIN(VALUE); 195 | return NFREGS; 196 | } 197 | 198 | /* SQEntries */ 199 | {SQEntries} { 200 | BEGIN(VALUE); 201 | return SQENTRIES; 202 | } 203 | /* LQEntries */ 204 | {LQEntries} { 205 | BEGIN(VALUE); 206 | return LQENTRIES; 207 | } 208 | /* RASSize */ 209 | {RASSize} { 210 | BEGIN(VALUE); 211 | return RASSIZE; 212 | } 213 | 214 | /* BRANCH PREDICTOR */ 215 | {lHistBits} { 216 | BEGIN(VALUE); 217 | return LHISTB; 218 | } 219 | 220 | {lCtrBits} { 221 | BEGIN(VALUE); 222 | return LCTRB; 223 | } 224 | 225 | {lPredictorSize} { 226 | BEGIN(VALUE); 227 | return LPREDSIZE; 228 | } 229 | 230 | {gPredictorSize} { 231 | BEGIN(VALUE); 232 | return GPREDSIZE; 233 | } 234 | 235 | {gCtrBits} { 236 | BEGIN(VALUE); 237 | return GCTRB; 238 | } 239 | 240 | {cPredictorSize} { 241 | BEGIN(VALUE); 242 | return CPREDSIZE; 243 | } 244 | 245 | {cCtrBits} { 246 | BEGIN(VALUE); 247 | return CCTRB; 248 | } 249 | 250 | /* BRANCH PREDICTOR BUFFER */ 251 | 252 | {BTBEntries} { 253 | BEGIN(VALUE); 254 | return BTBE; 255 | } 256 | 257 | /* CACHE PARAMETERS */ 258 | /* tlb */ 259 | 260 | "[system.cpu.dtb]" { 261 | BEGIN(DTLB); 262 | } 263 | 264 | "[system.cpu.itb]" { 265 | BEGIN(ITLB); 266 | } 267 | 268 | "size" { 269 | BEGIN(VALUE); 270 | return TLBD; 271 | } 272 | 273 | "size" { 274 | BEGIN(VALUE); 275 | return TLBI; 276 | } 277 | 278 | /* DATA CACHE L1 */ 279 | "[system.cpu.dcache]" { 280 | BEGIN(DL1); 281 | } 282 | 283 | "size" { 284 | PREV_STATE = DL1; 285 | BEGIN(VALUE); 286 | return DL1SIZE; 287 | } 288 | 289 | "assoc" { 290 | PREV_STATE = DL1; 291 | BEGIN(VALUE); 292 | return DL1ASSOC; 293 | } 294 | 295 | "mshrs" { 296 | PREV_STATE = DL1; 297 | BEGIN(VALUE); 298 | return D1MSHRS; 299 | } 300 | 301 | "hit_latency" { 302 | PREV_STATE = DL1; 303 | BEGIN(VALUE); 304 | return HLDL1; 305 | } 306 | 307 | "response_latency" { 308 | PREV_STATE = DL1; 309 | BEGIN(VALUE); 310 | return RLDL1; 311 | } 312 | 313 | "write_buffers" { 314 | BEGIN(VALUE); 315 | return WBDL1; 316 | } 317 | 318 | "[system.cpu.dcache.tags]" { 319 | BEGIN(DL1TAGS); 320 | } 321 | 322 | "block_size" { 323 | BEGIN(VALUE); 324 | return DL1BSIZE; 325 | } 326 | 327 | /* INST CACHE L1 */ 328 | "[system.cpu.icache]" { 329 | BEGIN(IL1); 330 | } 331 | 332 | "size" { 333 | BEGIN(VALUE); 334 | return IL1SIZE; 335 | } 336 | 337 | "assoc" { 338 | PREV_STATE = IL1; 339 | BEGIN(VALUE); 340 | return IL1ASSOC; 341 | } 342 | 343 | "mshrs" { 344 | PREV_STATE = IL1; 345 | BEGIN(VALUE); 346 | return I1MSHRS; 347 | } 348 | 349 | "hit_latency" { 350 | PREV_STATE = IL1; 351 | BEGIN(VALUE); 352 | return HLIL1; 353 | } 354 | 355 | "response_latency" { 356 | PREV_STATE = IL1; 357 | BEGIN(VALUE); 358 | return RLIL1; 359 | } 360 | 361 | "[system.cpu.icache.tags]" { 362 | BEGIN(IL1TAGS); 363 | } 364 | 365 | "block_size" { 366 | BEGIN(VALUE); 367 | return IL1BSIZE; 368 | } 369 | 370 | /* CACHE L2 */ 371 | 372 | "[system.l2]" { 373 | BEGIN(L2); 374 | } 375 | 376 | "size" { 377 | PREV_STATE = L2; 378 | BEGIN(VALUE); 379 | return L2SIZE; 380 | } 381 | 382 | "assoc" { 383 | PREV_STATE = L2; 384 | BEGIN(VALUE); 385 | return L2ASSOC; 386 | } 387 | 388 | "mshrs" { 389 | PREV_STATE = L2; 390 | BEGIN(VALUE); 391 | return L2MSHRS; 392 | } 393 | 394 | "hit_latency" { 395 | PREV_STATE = L2; 396 | BEGIN(VALUE); 397 | return HLL2; 398 | } 399 | 400 | "response_latency" { 401 | PREV_STATE = L2; 402 | BEGIN(VALUE); 403 | return RLL2; 404 | } 405 | 406 | "write_buffers" { 407 | BEGIN(VALUE); 408 | return WBL2; 409 | } 410 | 411 | "[system.l2.tags]" { 412 | BEGIN(L2TAGS); 413 | } 414 | 415 | "block_size" { 416 | BEGIN(VALUE); 417 | return L2BSIZE; 418 | } 419 | 420 | /* CACHE L3 */ 421 | 422 | "[system.l3]" { 423 | BEGIN(L3); 424 | } 425 | 426 | "size" { 427 | PREV_STATE = L3; 428 | BEGIN(VALUE); 429 | return L3SIZE; 430 | } 431 | 432 | "assoc" { 433 | PREV_STATE = L3; 434 | BEGIN(VALUE); 435 | return L3ASSOC; 436 | } 437 | 438 | "mshrs" { 439 | PREV_STATE = L3; 440 | BEGIN(VALUE); 441 | return L3MSHRS; 442 | } 443 | 444 | "hit_latency" { 445 | PREV_STATE = L3; 446 | BEGIN(VALUE); 447 | return HLL3; 448 | } 449 | 450 | "response_latency" { 451 | PREV_STATE = L3; 452 | BEGIN(VALUE); 453 | return RLL3; 454 | } 455 | 456 | "write_buffers" { 457 | BEGIN(VALUE); 458 | return WBL3; 459 | } 460 | 461 | "[system.l3.tags]" { 462 | BEGIN(L3TAGS); 463 | } 464 | 465 | "block_size" { 466 | BEGIN(VALUE); 467 | return L3BSIZE; 468 | } 469 | 470 | /* CALCULATING BASE PARAMETERS (SEE APPENDIX A) */ 471 | 472 | {f2DecodeDelay} { 473 | BEGIN(VALUE); 474 | return BASE; 475 | } 476 | 477 | {d2RenameDelay} { 478 | BEGIN(VALUE); 479 | return BASE; 480 | } 481 | 482 | {r2IEWDelay} { 483 | BEGIN(VALUE); 484 | return BASE; 485 | } 486 | 487 | {i2CommitDelay} { 488 | BEGIN(VALUE); 489 | return BASE; 490 | } 491 | 492 | {c2DecodeDelay} { 493 | BEGIN(VALUE); 494 | return MAXBASE; 495 | } 496 | 497 | {c2FetchDelay} { 498 | BEGIN(VALUE); 499 | return MAXBASE; 500 | } 501 | 502 | {c2IEWDelay} { 503 | BEGIN(VALUE); 504 | return MAXBASE; 505 | } 506 | 507 | {c2RenameDelay} { 508 | BEGIN(VALUE); 509 | return MAXBASE; 510 | } 511 | 512 | /* MAIN MEMORY PARAMS */ 513 | "[system.mem_ctrls]" { 514 | BEGIN(MMEM); 515 | } 516 | 517 | "channels" { 518 | PREV_STATE = MMEM; 519 | BEGIN(VALUE); 520 | return MM_CHNLS; 521 | } 522 | 523 | "ranks_per_channel" { 524 | PREV_STATE = MMEM; 525 | BEGIN(VALUE); 526 | return MM_RANKS; 527 | } 528 | 529 | "write_buffer_size" { 530 | BEGIN(VALUE); 531 | return MM_BSIZE; 532 | } 533 | 534 | 535 | /* ====== STATISTICS ====== */ 536 | 537 | {CPU}"decode.DecodedInsts" { 538 | BEGIN(DELIM); 539 | return DECODINSTS; 540 | } 541 | 542 | {CPU}"branchPred.condPredicted" { 543 | BEGIN(DELIM); 544 | return BRANCHPRED; 545 | } 546 | 547 | {CPU}"branchPred.condIncorrect" { 548 | BEGIN(DELIM); 549 | return BRANCHERR; 550 | } 551 | 552 | {CPU}"iew.iewExecLoadInsts"|{CPU}"num_load_insts" { 553 | BEGIN(DELIM); 554 | return IEWLOAD; 555 | } 556 | 557 | {CPU}"iew.exec_refs"|{CPU}"num_store_insts" { 558 | BEGIN(DELIM); 559 | return IEWSTORE; 560 | } 561 | 562 | {CPU}"commit.int_insts" { 563 | BEGIN(DELIM); 564 | return CINT; 565 | } 566 | 567 | {CPU}"commit.fp_insts" { 568 | BEGIN(DELIM); 569 | return CFP; 570 | } 571 | 572 | {CPU}"ipc_total" { 573 | BEGIN(DELIM); 574 | return IPC; 575 | } 576 | 577 | {CPU}"numCycles" { 578 | BEGIN(DELIM); 579 | return NCYCLES; 580 | } 581 | 582 | {CPU}"idleCycles"|{CPU}"num_idle_cycles" { 583 | BEGIN(DELIM); 584 | return ICYCLES; 585 | } 586 | 587 | {CPU}"rob.rob_reads" { 588 | BEGIN(DELIM); 589 | return ROBREADS; 590 | } 591 | 592 | {CPU}"rob.rob_writes" { 593 | BEGIN(DELIM); 594 | return ROBWRITES; 595 | } 596 | 597 | {CPU}"rename.int_rename_lookups" { 598 | BEGIN(DELIM); 599 | return RE_INT_LKUP; 600 | } 601 | 602 | {CPU}"rename.int_rename_operands" { 603 | BEGIN(DELIM); 604 | return RE_INT_OP; 605 | } 606 | 607 | {CPU}"rename.fp_rename_lookups" { 608 | BEGIN(DELIM); 609 | return RE_FP_LKUP; 610 | } 611 | 612 | {CPU}"rename.fp_rename_operands" { 613 | BEGIN(DELIM); 614 | return RE_FP_OP; 615 | } 616 | 617 | {CPU}"iq.int_inst_queue_reads" { 618 | BEGIN(DELIM); 619 | return IQ_INT_R; 620 | } 621 | 622 | {CPU}"iq.int_inst_queue_writes" { 623 | BEGIN(DELIM); 624 | return IQ_INT_W; 625 | } 626 | 627 | {CPU}"iq.int_inst_queue_wakeup_accesses" { 628 | BEGIN(DELIM); 629 | return IQ_INT_WA; 630 | } 631 | 632 | {CPU}"iq.fp_inst_queue_reads" { 633 | BEGIN(DELIM); 634 | return IQ_FP_QR; 635 | } 636 | 637 | {CPU}"iq.fp_inst_queue_writes" { 638 | BEGIN(DELIM); 639 | return IQ_FP_QW; 640 | } 641 | 642 | {CPU}"iq.fp_inst_queue_wakeup_accesses" { 643 | BEGIN(DELIM); 644 | return IQ_FP_QWA; 645 | } 646 | 647 | {CPU}"int_regfile_reads" { 648 | BEGIN(DELIM); 649 | return INT_RG_R; 650 | } 651 | 652 | {CPU}"int_regfile_writes" { 653 | BEGIN(DELIM); 654 | return INT_RG_W; 655 | } 656 | 657 | {CPU}"fp_regfile_reads" { 658 | BEGIN(DELIM); 659 | return FP_RG_R; 660 | } 661 | 662 | {CPU}"fp_regfile_writes" { 663 | BEGIN(DELIM); 664 | return FP_RG_W; 665 | } 666 | 667 | {CPU}"commit.function_calls" { 668 | BEGIN(DELIM); 669 | return COMCALLS; 670 | } 671 | 672 | {CPU}"iq.FU_type_0::IntDiv" { 673 | BEGIN(DELIM); 674 | return INTDIV; 675 | } 676 | 677 | {CPU}"iq.FU_type_0::IntMult" { 678 | BEGIN(DELIM); 679 | return INTMULT; 680 | } 681 | 682 | {CPU}"iq.int_alu_accesses" { 683 | BEGIN(DELIM); 684 | return INT_ALU_ACC; 685 | } 686 | 687 | {CPU}"iq.fp_alu_accesses" { 688 | BEGIN(DELIM); 689 | return FP_ALU_ACC; 690 | } 691 | 692 | "opClass=IntMult" { 693 | BEGIN(LATENCY); 694 | return MULTALU_LAT; 695 | } 696 | 697 | "opClass=IntDiv" { 698 | BEGIN(LATENCY); 699 | return DIVALU_LAT; 700 | } 701 | 702 | "opLat" { 703 | BEGIN(VALUE); 704 | } 705 | 706 | /* BTB */ 707 | {CPU}"branchPred.BTBLookups" { 708 | BEGIN(DELIM); 709 | return BTBLKUP; 710 | } 711 | 712 | {CPU}"branchPred.BTBUpdates" { 713 | BEGIN(DELIM); 714 | return BTBUP; 715 | } 716 | 717 | /* TLBs */ 718 | {DTB}"replacements" { 719 | BEGIN(DELIM); 720 | return DTB_MISS; 721 | } 722 | 723 | {DTB}"data_accesses" { 724 | BEGIN(DELIM); 725 | return DTB_ACC; 726 | } 727 | 728 | {ITB}"replacements" { 729 | BEGIN(DELIM); 730 | return ITB_MISS; 731 | } 732 | 733 | {ITB}"data_accesses" { 734 | BEGIN(DELIM); 735 | return ITB_ACC; 736 | } 737 | 738 | /* L1 CACHES */ 739 | {D1}"overall_accesses::total" { 740 | BEGIN(DELIM); 741 | return D1_ACC; 742 | } 743 | 744 | {D1}"overall_misses::total" { 745 | BEGIN(DELIM); 746 | return D1_MISS; 747 | } 748 | 749 | {D1}"WriteReq_accesses::total" { 750 | BEGIN(DELIM); 751 | return D1_WRACC; 752 | } 753 | 754 | {D1}"writebacks::total" { 755 | BEGIN(DELIM); 756 | return D1_WRBACK; 757 | } 758 | 759 | {D1}"WriteReq_misses::total" { 760 | BEGIN(DELIM); 761 | return D1_WRMISS; 762 | } 763 | 764 | {D1}"WriteReq_hits::total" { 765 | BEGIN(DELIM); 766 | return D1_WRHITS; 767 | } 768 | 769 | /* ICACHE */ 770 | {I1}"overall_accesses::total" { 771 | BEGIN(DELIM); 772 | return I1_ACC; 773 | } 774 | 775 | {I1}"overall_misses::total" { 776 | BEGIN(DELIM); 777 | return I1_MISS; 778 | } 779 | 780 | {I1}"WriteReq_accesses::total" { 781 | BEGIN(DELIM); 782 | return I1_WRACC; 783 | } 784 | 785 | {I1}"writebacks::total" { 786 | BEGIN(DELIM); 787 | return I1_WRBACK; 788 | } 789 | 790 | {I1}"WriteReq_misses::total" { 791 | BEGIN(DELIM); 792 | return I1_WRMISS; 793 | } 794 | 795 | {I1}"WriteReq_hits::total" { 796 | BEGIN(DELIM); 797 | return I1_WRHITS; 798 | } 799 | 800 | /* L2 CACHE */ 801 | {SL2}"overall_accesses::total" { 802 | BEGIN(DELIM); 803 | return L2_ACC; 804 | } 805 | 806 | {SL2}"overall_misses::total" { 807 | BEGIN(DELIM); 808 | return L2_MISS; 809 | } 810 | 811 | {SL2}"WriteReq_accesses::total" { 812 | BEGIN(DELIM); 813 | return L2_WRACC; 814 | } 815 | 816 | {SL2}"WriteReq_misses::total" { 817 | BEGIN(DELIM); 818 | return L2_WRMISS; 819 | } 820 | 821 | {SL2}"Writeback_accesses::total" { 822 | BEGIN(DELIM); 823 | return L2_WRBACK; 824 | } 825 | 826 | {SL2}"Writeback_misses::total" { 827 | BEGIN(DELIM); 828 | return L2_WRBMISS; 829 | } 830 | 831 | /* L3 CACHE */ 832 | {SL3}"overall_accesses::total" { 833 | BEGIN(DELIM); 834 | return L3_ACC; 835 | } 836 | 837 | {SL3}"overall_misses::total" { 838 | BEGIN(DELIM); 839 | return L3_MISS; 840 | } 841 | 842 | {SL3}"WriteReq_accesses::total" { 843 | BEGIN(DELIM); 844 | return L3_WRACC; 845 | } 846 | 847 | {SL3}"WriteReq_misses::total" { 848 | BEGIN(DELIM); 849 | return L3_WRMISS; 850 | } 851 | 852 | {SL3}"Writeback_accesses::total" { 853 | BEGIN(DELIM); 854 | return L3_WRBACK; 855 | } 856 | 857 | {SL3}"Writeback_misses::total" { 858 | BEGIN(DELIM); 859 | return L3_WRBMISS; 860 | } 861 | 862 | /* MAIN MEMORY */ 863 | {SYS}"mem_ctrls.num_reads::total" { 864 | BEGIN(DELIM); 865 | return MM_NREADS; 866 | } 867 | 868 | {SYS}"mem_ctrls.num_writes::total" { 869 | BEGIN(DELIM); 870 | return MM_NWRITES; 871 | } 872 | 873 | 874 | /* OBTAINING VALUES DESIRED */ 875 | 876 | {eq} { 877 | return EQ; 878 | } 879 | 880 | {ws}+ { 881 | BEGIN(VALUE); 882 | return WS; 883 | } 884 | 885 | {letter}+ { 886 | yylval.t_str = strdup(yytext); 887 | if (PREV_STATE!=-1) { 888 | BEGIN(PREV_STATE); 889 | PREV_STATE = -1; 890 | } else { 891 | BEGIN(INITIAL); 892 | } 893 | return STR; 894 | } 895 | 896 | {digit}+ { 897 | yylval.t_int = atoi(yytext); 898 | if (PREV_STATE!=-1) { 899 | BEGIN(PREV_STATE); 900 | PREV_STATE = -1; 901 | } else { 902 | BEGIN(INITIAL); 903 | } 904 | return NUM; 905 | } 906 | 907 | {double} { 908 | yylval.t_double = atof(yytext); 909 | if (PREV_STATE!=-1) { 910 | BEGIN(PREV_STATE); 911 | PREV_STATE = -1; 912 | } else { 913 | BEGIN(INITIAL); 914 | } 915 | return FLOAT; 916 | } 917 | 918 | /* WHEN NOTHING ELSE MATCHES */ 919 | {ignore}|{eq}|{ws}|"\n"|. { 920 | if (PREV_STATE!=-1) { 921 | BEGIN(PREV_STATE); 922 | PREV_STATE = -1; 923 | } else { 924 | BEGIN(INITIAL); 925 | } 926 | return BADTKN; 927 | } 928 | 929 | <*>{ignore}|{eq}|{ws}|"\n"|. { /* DO NOTHING */ } 930 | %% 931 | 932 | /** Some comments: 933 | * PREV_STATE allows to return to the previous state. It is used when 934 | * a tag like [something] contains more than one parameter to catch 935 | **/ 936 | -------------------------------------------------------------------------------- /parser.y: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2016 Marcos Horro 3 | * All rights reserved. MIT Licence 4 | * 5 | * Redistribution and use in source and binary forms, with or without 6 | * modification, are permitted provided that the following conditions are 7 | * met: redistributions of source code must retain the above copyright 8 | * notice, this list of conditions and the following disclaimer; 9 | * redistributions in binary form must reproduce the above copyright 10 | * notice, this list of conditions and the following disclaimer in the 11 | * documentation and/or other materials provided with the distribution; 12 | * neither the name of the copyright holders nor the names of its 13 | * contributors may be used to endorse or promote products derived from 14 | * this software without specific prior written permission. 15 | * 16 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 17 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 18 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 19 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 20 | * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 21 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 22 | * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 26 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 | * 28 | * Authors: Marcos Horro Varela 29 | * 30 | */ 31 | %error-verbose 32 | %{ 33 | #include "lib/utils.h" 34 | #include "lib/handle_options.h" 35 | 36 | int ERROR = 0; 37 | int DETAILED = 0; 38 | 39 | extern FILE *yyin; 40 | extern int yylineno; 41 | xml_document<> doc; 42 | 43 | struct t_mcpat_params *mcpat_param; 44 | struct t_mcpat_stats *mcpat_stats; 45 | struct t_error *error_list; 46 | 47 | int yylex(void); 48 | void yyerror(const char *s, ...); 49 | void yyrestart(FILE *yyin); 50 | %} 51 | %union { 52 | int t_int; 53 | double t_double; 54 | char * t_str; 55 | } 56 | /* TOKENS PARAMS */ 57 | %token EQ WS NL BADTKN 58 | %token ISA_T SYSCLK M_MODE 59 | %token FETCHW DECODEW ISSUEW COMMITW BASE MAXBASE BUFFERS 60 | %token NIQENTRIES NROBENTRIES NINTREGS NFREGS SQENTRIES LQENTRIES RASSIZE 61 | %token LHISTB LCTRB LPREDSIZE GPREDSIZE GCTRB CPREDSIZE CCTRB 62 | %token BTBE 63 | %token TLBD TLBI 64 | %token IL1SIZE IL1ASSOC I1MSHRS HLIL1 RLIL1 IL1BSIZE 65 | %token DL1SIZE DL1ASSOC D1MSHRS HLDL1 RLDL1 WBDL1 DL1BSIZE 66 | %token L2SIZE L2ASSOC L2MSHRS HLL2 RLL2 WBL2 L2BSIZE 67 | %token L3SIZE L3ASSOC L3MSHRS HLL3 RLL3 WBL3 L3BSIZE 68 | %token MULTALU_LAT DIVALU_LAT 69 | /* TOKENS STATS */ 70 | %token DECODINSTS BRANCHPRED BRANCHERR IEWLOAD IEWSTORE CINT CFP IPC NCYCLES 71 | %token ICYCLES ROBREADS ROBWRITES RE_INT_LKUP RE_INT_OP RE_FP_LKUP RE_FP_OP 72 | %token IQ_INT_R IQ_INT_W IQ_INT_WA IQ_FP_QR IQ_FP_QW IQ_FP_QWA INT_RG_R INT_RG_W 73 | %token FP_RG_R FP_RG_W COMCALLS INTDIV INTMULT INT_ALU_ACC FP_ALU_ACC 74 | %token BTBLKUP BTBUP 75 | %token DTB_MISS DTB_ACC ITB_MISS ITB_ACC 76 | %token D1_ACC D1_MISS D1_WRACC D1_WRBACK D1_WRMISS D1_WRHITS 77 | %token I1_ACC I1_MISS I1_WRACC I1_WRBACK I1_WRMISS I1_WRHITS 78 | %token L2_ACC L2_MISS L2_WRACC L2_WRMISS L2_WRBACK L2_WRBMISS 79 | %token L3_ACC L3_MISS L3_WRACC L3_WRMISS L3_WRBACK L3_WRBMISS 80 | %token MM_CHNLS MM_RANKS MM_BSIZE MM_NREADS MM_NWRITES 81 | %token NUM 82 | %token FLOAT 83 | %token STR 84 | // tokens types etc 85 | %start S 86 | %% 87 | // rules 88 | S : line { /* finish */ } 89 | ; 90 | 91 | /* left recursion better than right recursion: due to stack reasons */ 92 | line : /* empty */ 93 | | line config 94 | | line stats 95 | | line error { /* do nothing */ } 96 | ; 97 | 98 | config: 99 | ISA_T STR { mcpat_param->isa_x86 = !strcmp("X86ISA", $2); } 100 | | M_MODE EQ STR { DETAILED = (!strcmp("timing", $3));} 101 | | SYSCLK EQ NUM { mcpat_param->clock_rate = $3; } 102 | | FETCHW EQ NUM { mcpat_param->fetch_width = $3; } 103 | | DECODEW EQ NUM { 104 | mcpat_param->decode_width = $3; 105 | mcpat_param->issue_width = $3; } 106 | | ISSUEW EQ NUM { mcpat_param->peak_issue_width = $3; } 107 | | COMMITW EQ NUM { mcpat_param->commit_width = $3; } 108 | | BASE EQ NUM { mcpat_param->base_stages += $3; mcpat_param->nbase++; } 109 | | MAXBASE EQ NUM { 110 | mcpat_param->max_base = MAX(mcpat_param->max_base, $3); 111 | mcpat_param->nmax_base++; } 112 | | BUFFERS EQ NUM { mcpat_param->instruction_buffer_size = $3; } 113 | | NIQENTRIES EQ NUM { 114 | if ($3 % 2==0){ 115 | mcpat_param->instruction_window_size = $3/2; 116 | mcpat_param->fp_instruction_window_size = $3/2; 117 | } else { yyerror("numIQEntries must be odd\n"); } } 118 | | NROBENTRIES EQ NUM { mcpat_param->ROB_size = $3; } 119 | | NINTREGS EQ NUM { mcpat_param->phy_Regs_IRF_size = $3; } 120 | | NFREGS EQ NUM { mcpat_param->phy_Regs_FRF_size = $3; } 121 | | SQENTRIES EQ NUM { mcpat_param->store_buffer_size = $3; } 122 | | LQENTRIES EQ NUM { mcpat_param->load_buffer_size = $3; } 123 | | RASSIZE EQ NUM { mcpat_param->RAS_size = $3; } 124 | | LHISTB EQ NUM { mcpat_param->load_predictor[0] = $3; } 125 | | LCTRB EQ NUM { mcpat_param->load_predictor[1] = $3; } 126 | | LPREDSIZE EQ NUM { 127 | mcpat_param->load_predictor[2] = $3; 128 | if (mcpat_param->load_predictor[0]==0) { 129 | mcpat_param->load_predictor[0] = (int) floor(log2((double) $3)); 130 | } } 131 | | GPREDSIZE EQ NUM { mcpat_param->global_predictor[0] = $3; } 132 | | GCTRB EQ NUM { mcpat_param->global_predictor[1] = $3; } 133 | | CPREDSIZE EQ NUM { mcpat_param->predictor_chooser[0] = $3; } 134 | | CCTRB EQ NUM { mcpat_param->predictor_chooser[1] = $3; } 135 | | BTBE EQ NUM { mcpat_param->BTB_config = $3; } 136 | | TLBD EQ NUM { mcpat_param->number_entries_dtlb = $3; } 137 | | TLBI EQ NUM { mcpat_param->number_entries_itlb = $3; } 138 | | DL1SIZE EQ NUM { mcpat_param->dcache_config[0] = $3; } 139 | | DL1BSIZE EQ NUM { mcpat_param->dcache_config[1] = $3; } 140 | | DL1ASSOC EQ NUM { 141 | mcpat_param->dcache_config[2] = $3; 142 | mcpat_param->dcache_config[3] = 1; 143 | mcpat_param->dcache_config[5] = 32; 144 | mcpat_param->dcache_config[6] = 1;} 145 | | D1MSHRS EQ NUM { 146 | mcpat_param->dcache_buffer_sizes[0] = $3; 147 | mcpat_param->dcache_buffer_sizes[1] = $3; 148 | mcpat_param->dcache_buffer_sizes[2] = $3; } 149 | | WBDL1 EQ NUM { mcpat_param->icache_buffer_sizes[3] = $3; } 150 | | HLDL1 EQ NUM { mcpat_param->dhit_lat = $3; } 151 | | RLDL1 EQ NUM { mcpat_param->dresp_lat = $3; } 152 | | IL1SIZE EQ NUM { mcpat_param->icache_config[0] = $3; } 153 | | IL1BSIZE EQ NUM { mcpat_param->icache_config[1] = $3; } 154 | | IL1ASSOC EQ NUM { 155 | mcpat_param->icache_config[2] = $3; 156 | mcpat_param->icache_config[3] = 1; 157 | mcpat_param->icache_config[5] = 32; 158 | mcpat_param->icache_config[6] = 1;} 159 | | I1MSHRS EQ NUM { 160 | mcpat_param->icache_buffer_sizes[0] = $3; 161 | mcpat_param->icache_buffer_sizes[1] = $3; 162 | mcpat_param->icache_buffer_sizes[2] = $3; 163 | mcpat_param->icache_buffer_sizes[3] = 0;} 164 | | HLIL1 EQ NUM { mcpat_param->ihit_lat = $3; } 165 | | RLIL1 EQ NUM { mcpat_param->iresp_lat = $3; } 166 | | L2SIZE EQ NUM { mcpat_param->L2_config[0] = $3; } 167 | | L2BSIZE EQ NUM { mcpat_param->L2_config[1] = $3; mcpat_param->l2_avail = 1; } 168 | | L2ASSOC EQ NUM { 169 | mcpat_param->L2_config[2] = $3; 170 | mcpat_param->L2_config[3] = 1; 171 | mcpat_param->L2_config[5] = 32; 172 | mcpat_param->L2_config[6] = 1;} 173 | | L2MSHRS EQ NUM { 174 | mcpat_param->L2_buffer_sizes[0] = $3; 175 | mcpat_param->L2_buffer_sizes[1] = $3; 176 | mcpat_param->L2_buffer_sizes[2] = $3; } 177 | | WBL2 EQ NUM { mcpat_param->L2_buffer_sizes[3] = $3; } 178 | | HLL2 EQ NUM { mcpat_param->l2hit_lat = $3; } 179 | | RLL2 EQ NUM { mcpat_param->l2resp_lat = $3; } 180 | | L3SIZE EQ NUM { mcpat_param->L3_config[0] = $3; mcpat_param->l3_avail = 1; } 181 | | L3BSIZE EQ NUM { mcpat_param->L3_config[1] = $3; } 182 | | L3ASSOC EQ NUM { 183 | mcpat_param->L3_config[2] = $3; 184 | mcpat_param->L3_config[3] = 1; 185 | mcpat_param->L3_config[5] = 32; 186 | mcpat_param->L3_config[6] = 1;} 187 | | L3MSHRS EQ NUM { 188 | mcpat_param->L3_buffer_sizes[0] = $3; 189 | mcpat_param->L3_buffer_sizes[1] = $3; 190 | mcpat_param->L3_buffer_sizes[2] = $3; } 191 | | WBL3 EQ NUM { mcpat_param->L3_buffer_sizes[3] = $3; } 192 | | HLL3 EQ NUM { mcpat_param->l3hit_lat = $3; } 193 | | RLL3 EQ NUM { mcpat_param->l3resp_lat = $3; } 194 | | MULTALU_LAT EQ NUM { mcpat_param->lat_IntMult = $3; } 195 | | DIVALU_LAT EQ NUM { mcpat_param->lat_IntDiv = $3; } 196 | | MM_CHNLS EQ NUM { mcpat_param->memory_channels_per_mc = $3; } 197 | | MM_RANKS EQ NUM { mcpat_param->number_ranks = $3; } 198 | | MM_BSIZE EQ NUM { mcpat_param->block_size = $3; } 199 | 200 | 201 | stats: DECODINSTS WS NUM { mcpat_stats->total_instructions = $3; } 202 | | BRANCHPRED WS NUM { mcpat_stats->branch_instructions = $3; } 203 | | BRANCHERR WS NUM { mcpat_stats->branch_mispredictions = $3; } 204 | | IEWLOAD WS NUM { mcpat_stats->load_instructions = $3; } 205 | | IEWSTORE WS NUM { mcpat_stats->store_instructions = $3; } 206 | | CINT WS NUM { mcpat_stats->committed_int_instructions = $3; } 207 | | CFP WS NUM { mcpat_stats->committed_fp_instructions = $3; } 208 | | IPC WS FLOAT { mcpat_stats->pipeline_duty_cycle = $3; } 209 | | NCYCLES WS NUM { mcpat_stats->total_cycles = $3; } 210 | | ICYCLES WS NUM { mcpat_stats->idle_cycles = $3; } 211 | | ICYCLES WS FLOAT { mcpat_stats->idle_cycles = $3; } /*conversion*/ 212 | | ROBREADS WS NUM { mcpat_stats->ROB_reads = $3; } 213 | | ROBWRITES WS NUM { mcpat_stats->ROB_writes = $3; } 214 | | RE_INT_LKUP WS NUM { mcpat_stats->rename_reads = $3; } 215 | | RE_INT_OP WS NUM { mcpat_stats->rename_writes = $3; } 216 | | RE_FP_LKUP WS NUM { mcpat_stats->fp_rename_reads = $3; } 217 | | RE_FP_OP WS NUM { mcpat_stats->fp_rename_writes = $3; } 218 | | IQ_INT_R WS NUM { mcpat_stats->inst_window_reads = $3; } 219 | | IQ_INT_W WS NUM { mcpat_stats->inst_window_writes = $3; } 220 | | IQ_INT_WA WS NUM { mcpat_stats->inst_window_wakeup_accesses = $3; } 221 | | IQ_FP_QR WS NUM { mcpat_stats->fp_inst_window_reads = $3; } 222 | | IQ_FP_QW WS NUM { mcpat_stats->fp_inst_window_writes = $3; } 223 | | IQ_FP_QWA WS NUM { mcpat_stats->fp_inst_window_wakeup_accesses = $3; } 224 | | INT_RG_R WS NUM { mcpat_stats->int_regfile_reads = $3; } 225 | | INT_RG_W WS NUM { mcpat_stats->int_regfile_writes = $3; } 226 | | FP_RG_R WS NUM { mcpat_stats->float_regfile_reads = $3; } 227 | | FP_RG_W WS NUM { mcpat_stats->float_regfile_writes = $3; } 228 | | COMCALLS WS NUM { mcpat_stats->function_calls = $3; } 229 | | INTDIV WS NUM { mcpat_stats->IntDiv = $3; } 230 | | INTMULT WS NUM { mcpat_stats->IntMult = $3; } 231 | | INT_ALU_ACC WS NUM { mcpat_stats->ialu_accesses = $3; } 232 | | FP_ALU_ACC WS NUM { mcpat_stats->fpu_accesses = $3;} 233 | | BTBLKUP WS NUM { mcpat_stats->btb_read_accesses = $3; } 234 | | BTBUP WS NUM { mcpat_stats->btb_write_accesses = $3; } 235 | | DTB_MISS WS NUM { mcpat_stats->dtlb_total_misses = $3; } 236 | | DTB_ACC WS NUM { mcpat_stats->dtlb_total_accesses = $3; } 237 | | ITB_MISS WS NUM { mcpat_stats->itlb_total_misses = $3; } 238 | | ITB_ACC WS NUM { mcpat_stats->itlb_total_accesses = $3; } 239 | | D1_ACC WS NUM { mcpat_stats->overall_access[0] = $3; } 240 | | D1_MISS WS NUM { mcpat_stats->overall_misses[0] = $3; } 241 | | D1_WRACC WS NUM { mcpat_stats->WriteReq_access[0] = $3; } 242 | | D1_WRMISS WS NUM { mcpat_stats->WriteReq_misses[0] = $3; } 243 | | D1_WRHITS WS NUM { mcpat_stats->WriteReq_hits[0] = $3; } 244 | | D1_WRBACK WS NUM { mcpat_stats->Writeback_accesses[0] = $3; } 245 | | I1_ACC WS NUM { mcpat_stats->overall_access[1] = $3; } 246 | | I1_MISS WS NUM { mcpat_stats->overall_misses[1] = $3; } 247 | | I1_WRACC WS NUM { mcpat_stats->WriteReq_access[1] = $3; } 248 | | I1_WRMISS WS NUM { mcpat_stats->WriteReq_misses[1] = $3; } 249 | | I1_WRHITS WS NUM { mcpat_stats->WriteReq_hits[1] = $3; } 250 | | I1_WRBACK WS NUM { mcpat_stats->Writeback_accesses[1] = $3; } 251 | | L2_ACC WS NUM { mcpat_stats->overall_access[2] = $3; } 252 | | L2_MISS WS NUM { mcpat_stats->overall_misses[2] = $3; } 253 | | L2_WRACC WS NUM { mcpat_stats->WriteReq_access[2] = $3; } 254 | | L2_WRMISS WS NUM { mcpat_stats->WriteReq_misses[2] = $3; } 255 | | L2_WRBACK WS NUM { mcpat_stats->Writeback_accesses[2] = $3; } 256 | | L2_WRBMISS WS NUM { mcpat_stats->Writeback_misses = $3; } 257 | | L3_ACC WS NUM { mcpat_stats->overall_access[3] = $3; } 258 | | L3_MISS WS NUM { mcpat_stats->overall_misses[3] = $3; } 259 | | L3_WRACC WS NUM { mcpat_stats->WriteReq_access[3] = $3; } 260 | | L3_WRMISS WS NUM { mcpat_stats->WriteReq_misses[3] = $3; } 261 | | L3_WRBACK WS NUM { mcpat_stats->Writeback_accesses[3] = $3; } 262 | | L3_WRBMISS WS NUM { mcpat_stats->Writeback_misses_l3 = $3; } 263 | | MM_NREADS WS NUM { mcpat_stats->memory_reads = $3; } 264 | | MM_NWRITES WS NUM { mcpat_stats->memory_writes = $3; } 265 | ; 266 | 267 | %% 268 | 269 | /* trying to be kind with memory */ 270 | void free_structs() 271 | { 272 | int i; 273 | free(mcpat_param); 274 | free(mcpat_stats); 275 | for (i=0; i < MAX_NUM; i++) { 276 | free(error_list->stat[i]); 277 | } 278 | for (i=0; i < MAX_NUM; i++) { 279 | free(error_list->config[i]); 280 | } 281 | // removing everything from memory pool! 282 | doc.clear(); 283 | } 284 | 285 | 286 | /* finds a concrete tag given the name of the tag (type) the value of 287 | the attribute name and then sets its value to value */ 288 | void findAndSetValue(xml_node<> *parent, char const *type, char const *name_value, char *value) 289 | { 290 | int found = 0; 291 | for (xml_node<> *node = parent->first_node(type); node; node = node->next_sibling()) { 292 | if (!strcmp(node->first_attribute("name")->value(), name_value)) { 293 | if (!node->first_attribute("value")) { 294 | // is this good? 295 | cout << "Error: bad structure XML in " << name_value << endl; 296 | cout << "Quitting..." << endl; 297 | free_structs(); 298 | exit(-1); 299 | } 300 | // checked before if this attribute exists 301 | node->remove_attribute(node->first_attribute("value")); 302 | // creating again this attribute and allocating string value 303 | char *value_name = doc.allocate_string(value); 304 | xml_attribute<> *attr = doc.allocate_attribute("value", value_name); 305 | node->append_attribute(attr); 306 | // found! 307 | found = 1; 308 | } 309 | } 310 | 311 | if (!found) { 312 | // we could make a set of warnings in order to tell the user 313 | // that a requested param/stat has not been set 314 | cout << type << ": " << name_value << " not found!" << endl; 315 | } 316 | } 317 | 318 | void findAndSetIntValue(xml_node<> *parent, char const *type, char const *name_value, int value) 319 | { 320 | char str[80]; 321 | snprintf(str, 80, "%d", value); 322 | if (value <= 0) { 323 | cout << BLD YEL "Warning: " << type <<" " << parent->first_attribute("id")->value() 324 | <<" '" << name_value << "' may have not been set!" RES << endl; 325 | } 326 | findAndSetValue(parent, type, name_value, str); 327 | 328 | } 329 | 330 | void findAndSetFloatValue(xml_node<> *parent, char const *type, char const *name_value, double value) 331 | { 332 | char str[80]; 333 | snprintf(str, 80, "%f", value); 334 | if (value <= 0.0) { 335 | cout << BLD YEL "Warning: " << type <<" " << parent->first_attribute("id")->value() 336 | <<" '" << name_value << "' may have not been set!" RES << endl; 337 | } 338 | findAndSetValue(parent, type, name_value, str); 339 | } 340 | 341 | void checkNode(xml_node<> *node, char const *id, char const *value) 342 | { 343 | char const *error_msg = "Error in template structure! Quitting\n"; 344 | 345 | // no lazy comparison possible 346 | if (node==0) { 347 | cout << "Node does not exist!" << endl; 348 | cout << error_msg << endl; 349 | free_structs(); 350 | unlink(out_file); 351 | exit(0); 352 | } 353 | 354 | // if node is not null, i.e. exists 355 | if ((strcmp(node->first_attribute("id")->value(), id))&& 356 | (strcmp(node->first_attribute("name")->value(), value))) { 357 | cout << "Component " << id << " missing" << endl; 358 | cout << "Found: " << node->first_attribute("id")->value() << " " 359 | << node->first_attribute("name")->value() << endl; 360 | cout << error_msg << endl; 361 | unlink(out_file); 362 | free_structs(); 363 | exit(0); 364 | } 365 | } 366 | 367 | /* xmlParser fills with the correct values the templates and prints in 368 | out.xml */ 369 | void xmlParser() throw() 370 | { 371 | cout << "Parsing template..." << endl; 372 | // Read the xml file into a vector 373 | ifstream theTemplate (out_file); 374 | vector buffer((istreambuf_iterator(theTemplate)), istreambuf_iterator()); 375 | buffer.push_back('\0'); 376 | // Parse the buffer using the xml file parsing library into doc 377 | doc.parse<0>(&buffer[0]); 378 | 379 | // Find our root node 380 | xml_node<> *root_node = doc.first_node("component"); 381 | checkNode(root_node, "root", "root"); 382 | 383 | // system node 384 | xml_node<> *sys_node = root_node->first_node("component"); 385 | checkNode(sys_node, "system", "system"); 386 | 387 | /* SYSTEM PARAMS AND STATS */ 388 | findAndSetIntValue(sys_node, "param", "number_of_L2Directories", mcpat_param->l2_avail); 389 | findAndSetIntValue(sys_node, "param", "Private_L2", mcpat_param->l2_avail); 390 | findAndSetIntValue(sys_node, "param", "number_of_L2s", mcpat_param->l2_avail); 391 | findAndSetIntValue(sys_node, "param", "number_of_L3s", mcpat_param->l3_avail); 392 | findAndSetIntValue(sys_node, "param", "homogeneous_L3s", mcpat_param->l3_avail); 393 | if (mcpat_param->l3_avail) { 394 | findAndSetIntValue(sys_node, "param", "number_cache_levels", 3); 395 | } 396 | findAndSetIntValue(sys_node, "param", "target_core_clockrate", mcpat_param->clock_rate); 397 | findAndSetIntValue(sys_node, "stat", "total_cycles", mcpat_stats->total_cycles); 398 | findAndSetIntValue(sys_node, "stat", "idle_cycles", mcpat_stats->idle_cycles); 399 | findAndSetIntValue(sys_node, "stat", "busy_cycles", mcpat_stats->total_cycles - mcpat_stats->idle_cycles); 400 | 401 | /* CORE PARAMS AND STATS */ 402 | xml_node<> *core_node = sys_node->first_node("component"); 403 | checkNode(core_node, "system.core0", "core0"); 404 | findAndSetIntValue(core_node, "param", "clock_rate", mcpat_param->clock_rate); 405 | findAndSetIntValue(core_node, "param", "x86", mcpat_param->isa_x86); 406 | findAndSetIntValue(core_node, "param", "fetch_width", mcpat_param->fetch_width); 407 | findAndSetIntValue(core_node, "param", "decode_width", mcpat_param->decode_width); 408 | findAndSetIntValue(core_node, "param", "issue_width", mcpat_param->issue_width); 409 | findAndSetIntValue(core_node, "param", "peak_issue_width", mcpat_param->peak_issue_width); 410 | findAndSetIntValue(core_node, "param", "commit_width", mcpat_param->commit_width); 411 | if ((mcpat_param->nbase!=4)||(mcpat_param->nmax_base!=4)) 412 | cout << BLD YEL "Warning: some parameters missing to set properly 'pipeline_depth'!" RES << endl; 413 | findAndSetValue(core_node, "param", "pipeline_depth", make_tuple(2, (INT_EXE + 414 | mcpat_param->base_stages + 415 | mcpat_param->max_base), 416 | (FP_EXE + 417 | mcpat_param->base_stages + 418 | mcpat_param->max_base))); 419 | findAndSetIntValue(core_node, "param", "instruction_buffer_size", mcpat_param->instruction_buffer_size); 420 | findAndSetIntValue(core_node, "param", "instruction_window_size", mcpat_param->instruction_window_size); 421 | findAndSetIntValue(core_node, "param", "fp_instruction_window_size", mcpat_param->fp_instruction_window_size); 422 | findAndSetIntValue(core_node, "param", "ROB_size", mcpat_param->ROB_size); 423 | findAndSetIntValue(core_node, "param", "phy_Regs_IRF_size", mcpat_param->phy_Regs_IRF_size); 424 | findAndSetIntValue(core_node, "param", "phy_Regs_FRF_size", mcpat_param->phy_Regs_FRF_size); 425 | findAndSetIntValue(core_node, "param", "store_buffer_size", mcpat_param->store_buffer_size); 426 | findAndSetIntValue(core_node, "param", "load_buffer_size", mcpat_param->load_buffer_size); 427 | findAndSetIntValue(core_node, "param", "RAS_size", mcpat_param->RAS_size); 428 | 429 | findAndSetIntValue(core_node, "stat", "total_instructions", mcpat_stats->total_instructions); 430 | findAndSetIntValue(core_node, "stat", "branch_instructions", mcpat_stats->branch_instructions); 431 | findAndSetIntValue(core_node, "stat", "branch_mispredictions", mcpat_stats->branch_mispredictions); 432 | findAndSetIntValue(core_node, "stat", "load_instructions", mcpat_stats->load_instructions); 433 | findAndSetIntValue(core_node, "stat", "store_instructions", mcpat_stats->store_instructions - mcpat_stats->load_instructions); 434 | findAndSetIntValue(core_node, "stat", "committed_int_instructions", mcpat_stats->committed_int_instructions); 435 | findAndSetIntValue(core_node, "stat", "committed_fp_instructions", mcpat_stats->committed_fp_instructions); 436 | findAndSetFloatValue(core_node, "stat", "pipeline_duty_cycle", mcpat_stats->pipeline_duty_cycle); 437 | findAndSetIntValue(core_node, "stat", "total_cycles", mcpat_stats->total_cycles); 438 | findAndSetIntValue(core_node, "stat", "idle_cycles", mcpat_stats->idle_cycles); 439 | findAndSetIntValue(core_node, "stat", "busy_cycles", mcpat_stats->total_cycles - mcpat_stats->idle_cycles); 440 | findAndSetIntValue(core_node, "stat", "ROB_reads", mcpat_stats->ROB_reads); 441 | findAndSetIntValue(core_node, "stat", "ROB_writes", mcpat_stats->ROB_writes); 442 | findAndSetIntValue(core_node, "stat", "rename_reads", mcpat_stats->rename_reads); 443 | findAndSetIntValue(core_node, "stat", "rename_writes", mcpat_stats->rename_writes); 444 | findAndSetIntValue(core_node, "stat", "fp_rename_reads", mcpat_stats->fp_rename_reads); 445 | findAndSetIntValue(core_node, "stat", "fp_rename_writes", mcpat_stats->fp_rename_writes); 446 | findAndSetIntValue(core_node, "stat", "inst_window_reads", mcpat_stats->inst_window_reads); 447 | findAndSetIntValue(core_node, "stat", "inst_window_writes", mcpat_stats->inst_window_writes); 448 | findAndSetIntValue(core_node, "stat", "inst_window_wakeup_accesses", mcpat_stats->inst_window_wakeup_accesses); 449 | findAndSetIntValue(core_node, "stat", "fp_inst_window_reads", mcpat_stats->fp_inst_window_reads); 450 | findAndSetIntValue(core_node, "stat", "fp_inst_window_writes", mcpat_stats->fp_inst_window_writes); 451 | findAndSetIntValue(core_node, "stat", "fp_inst_window_wakeup_accesses", mcpat_stats->fp_inst_window_wakeup_accesses); 452 | findAndSetIntValue(core_node, "stat", "int_regfile_reads", mcpat_stats->int_regfile_reads); 453 | findAndSetIntValue(core_node, "stat", "int_regfile_writes", mcpat_stats->int_regfile_writes); 454 | findAndSetIntValue(core_node, "stat", "float_regfile_reads", mcpat_stats->float_regfile_reads); 455 | findAndSetIntValue(core_node, "stat", "function_calls", mcpat_stats->function_calls); 456 | mcpat_stats->mul_accesses = mcpat_stats->IntDiv*mcpat_param->lat_IntDiv + 457 | mcpat_stats->IntMult*mcpat_param->lat_IntMult; 458 | mcpat_stats->ialu_accesses -= mcpat_stats->mul_accesses; 459 | findAndSetIntValue(core_node, "stat", "ialu_accesses", mcpat_stats->ialu_accesses); 460 | findAndSetIntValue(core_node, "stat", "fpu_accesses", mcpat_stats->fpu_accesses); 461 | findAndSetIntValue(core_node, "stat", "mul_accesses", mcpat_stats->mul_accesses); 462 | // this is not the same as the Appendix says, but in some 463 | // templates the same values are used 464 | findAndSetIntValue(core_node, "stat", "cdb_alu_accesses", mcpat_stats->ialu_accesses); 465 | findAndSetIntValue(core_node, "stat", "cdb_mul_accesses", mcpat_stats->mul_accesses); 466 | findAndSetIntValue(core_node, "stat", "cdb_fpu_accesses", mcpat_stats->fpu_accesses); 467 | 468 | /* BRANCH PREDICTOR */ 469 | xml_node<> *bp_node = core_node->first_node("component"); 470 | checkNode(bp_node, "system.core0.predictor", "PBT"); 471 | findAndSetValue(bp_node, "param", "load_predictor", 472 | make_tuple(3, mcpat_param->load_predictor[0], mcpat_param->load_predictor[1], 473 | mcpat_param->load_predictor[2])); 474 | findAndSetValue(bp_node, "param", "global_predictor", 475 | make_tuple(2, mcpat_param->global_predictor[0], mcpat_param->global_predictor[1])); 476 | findAndSetValue(bp_node, "param", "predictor_chooser", 477 | make_tuple(2, mcpat_param->predictor_chooser[0], mcpat_param->predictor_chooser[1])); 478 | 479 | /* ITLB */ 480 | xml_node<> *itlb_node = bp_node->next_sibling(); 481 | checkNode(itlb_node, "system.core0.itlb", "itlb"); 482 | findAndSetIntValue(itlb_node, "param", "number_entries", mcpat_param->number_entries_itlb); 483 | findAndSetIntValue(itlb_node, "stat", "total_accesses", mcpat_stats->itlb_total_accesses); 484 | findAndSetIntValue(itlb_node, "stat", "total_misses", mcpat_stats->itlb_total_misses); 485 | 486 | /* ICACHE */ 487 | xml_node<> *icache_node = itlb_node->next_sibling(); 488 | checkNode(icache_node, "system.core0.icache", "icache"); 489 | findAndSetValue(icache_node, "param", "icache_config", make_tuple(8,mcpat_param->icache_config[0], 490 | 32, /* temporal */ 491 | mcpat_param->icache_config[2], 492 | 1,mcpat_param->ihit_lat+mcpat_param->iresp_lat, 493 | mcpat_param->ihit_lat+mcpat_param->iresp_lat, 32, 0)); 494 | findAndSetValue(icache_node, "param", "buffer_sizes", make_tuple(4,mcpat_param->icache_buffer_sizes[0], 495 | mcpat_param->icache_buffer_sizes[1], 496 | mcpat_param->icache_buffer_sizes[2],0)); 497 | findAndSetIntValue(icache_node, "stat", "read_accesses", mcpat_stats->overall_access[0]-mcpat_stats->WriteReq_access[0]); 498 | findAndSetIntValue(icache_node, "stat", "read_misses", mcpat_stats->overall_misses[0]-mcpat_stats->WriteReq_misses[0]); 499 | 500 | /* DTLB */ 501 | xml_node<> *dtlb_node = icache_node->next_sibling(); 502 | checkNode(dtlb_node, "system.core0.dtlb", "dtlb"); 503 | findAndSetIntValue(dtlb_node, "param", "number_entries", mcpat_param->number_entries_dtlb); 504 | findAndSetIntValue(dtlb_node, "stat", "total_accesses", mcpat_stats->dtlb_total_accesses); 505 | findAndSetIntValue(dtlb_node, "stat", "total_misses", mcpat_stats->dtlb_total_misses); 506 | 507 | /* DCACHE */ 508 | xml_node<> *dcache_node = dtlb_node->next_sibling(); 509 | checkNode(dcache_node, "system.core0.dcache", "dcache"); 510 | findAndSetValue(dcache_node, "param", "dcache_config", make_tuple(8,mcpat_param->dcache_config[0], 511 | 32, /* temporal */ 512 | mcpat_param->dcache_config[2], 513 | 1,mcpat_param->dhit_lat+mcpat_param->dresp_lat, 514 | mcpat_param->dhit_lat+mcpat_param->dresp_lat, 32, 1)); 515 | findAndSetValue(dcache_node, "param", "buffer_sizes", make_tuple(4,mcpat_param->dcache_buffer_sizes[0], 516 | mcpat_param->dcache_buffer_sizes[1], 517 | mcpat_param->dcache_buffer_sizes[2], 518 | mcpat_param->dcache_buffer_sizes[3])); 519 | findAndSetIntValue(dcache_node, "stat", "read_accesses", mcpat_stats->overall_access[1]-mcpat_stats->WriteReq_access[1]); 520 | findAndSetIntValue(dcache_node, "stat", "write_accesses", mcpat_stats->WriteReq_access[1]-mcpat_stats->Writeback_accesses[1]); 521 | findAndSetIntValue(dcache_node, "stat", "read_misses", mcpat_stats->overall_misses[1]-mcpat_stats->WriteReq_misses[1]); 522 | findAndSetIntValue(dcache_node, "stat", "write_misses", mcpat_stats->WriteReq_access[1]-mcpat_stats->WriteReq_hits[1]); 523 | 524 | /* BTB: param tag in the middle that is why double next_sibling() */ 525 | xml_node<> *btb_node = dcache_node->next_sibling()->next_sibling(); 526 | checkNode(btb_node, "system.core0.BTB", "BTB"); 527 | findAndSetValue(btb_node, "param", "BTB_config", make_tuple(6,mcpat_param->BTB_config,4,2,2,1,1)); 528 | findAndSetIntValue(btb_node, "stat", "read_accesses", mcpat_stats->btb_read_accesses); 529 | findAndSetIntValue(btb_node, "stat", "write_accesses", mcpat_stats->btb_write_accesses); 530 | 531 | /* L10 DIR */ 532 | xml_node<> *l1dir_node = core_node->next_sibling(); 533 | checkNode(l1dir_node, "system.L1Directory0", "L1Directory0"); 534 | findAndSetIntValue(l1dir_node, "param", "clockrate", mcpat_param->clock_rate); 535 | 536 | /* L20 DIR */ 537 | xml_node<> *l2dir_node = l1dir_node->next_sibling(); 538 | checkNode(l2dir_node, "system.L2Directory0", "L2Directory0"); 539 | findAndSetIntValue(l2dir_node, "param", "clockrate", mcpat_param->clock_rate); 540 | 541 | /* L20 CACHE */ 542 | xml_node<> *l2_node = l2dir_node->next_sibling(); 543 | checkNode(l2_node, "system.L20", "L20"); 544 | findAndSetValue(l2_node, "param", "L2_config", make_tuple(8,mcpat_param->L2_config[0], 545 | mcpat_param->L2_config[1], 546 | mcpat_param->L2_config[2], 547 | 1,mcpat_param->l2hit_lat + mcpat_param->l2resp_lat, 548 | mcpat_param->l2hit_lat + mcpat_param->l2resp_lat, 32, 1)); 549 | findAndSetValue(l2_node, "param", "buffer_sizes", make_tuple(4,mcpat_param->L2_buffer_sizes[0], 550 | mcpat_param->L2_buffer_sizes[1], 551 | mcpat_param->L2_buffer_sizes[2], 552 | mcpat_param->L2_buffer_sizes[3])); 553 | findAndSetIntValue(l2_node, "param", "clockrate", mcpat_param->clock_rate); 554 | findAndSetIntValue(l2_node, "stat", "read_accesses", mcpat_stats->overall_access[2]-mcpat_stats->WriteReq_access[2]); 555 | findAndSetIntValue(l2_node, "stat", "write_accesses", mcpat_stats->overall_access[2] + 556 | mcpat_stats->Writeback_accesses[2] + mcpat_stats->WriteReq_access[2]); 557 | findAndSetIntValue(l2_node, "stat", "read_misses", mcpat_stats->overall_misses[2]-mcpat_stats->WriteReq_misses[2]); 558 | findAndSetIntValue(l2_node, "stat", "write_misses", mcpat_stats->overall_misses[2]-mcpat_stats->Writeback_misses + 559 | mcpat_stats->WriteReq_misses[2]); 560 | 561 | /* L30 CACHE */ 562 | xml_node<> *l3_node = l2_node->next_sibling(); 563 | checkNode(l3_node, "system.L30", "L30"); 564 | findAndSetValue(l3_node, "param", "L3_config", make_tuple(8,mcpat_param->L3_config[0], 565 | mcpat_param->L3_config[1], 566 | mcpat_param->L3_config[2], 567 | 1,mcpat_param->l3hit_lat + mcpat_param->l3resp_lat, 568 | mcpat_param->l3hit_lat + mcpat_param->l3resp_lat, 32, 1)); 569 | findAndSetValue(l3_node, "param", "buffer_sizes", make_tuple(4,mcpat_param->L3_buffer_sizes[0], 570 | mcpat_param->L3_buffer_sizes[1], 571 | mcpat_param->L3_buffer_sizes[2], 572 | mcpat_param->L3_buffer_sizes[3])); 573 | findAndSetIntValue(l3_node, "param", "clockrate", mcpat_param->clock_rate); 574 | findAndSetIntValue(l3_node, "stat", "read_accesses", mcpat_stats->overall_access[3]-mcpat_stats->WriteReq_access[3]); 575 | findAndSetIntValue(l3_node, "stat", "write_accesses", mcpat_stats->overall_access[3] + 576 | mcpat_stats->Writeback_accesses[3] + mcpat_stats->WriteReq_access[3]); 577 | findAndSetIntValue(l3_node, "stat", "read_misses", mcpat_stats->overall_misses[3]-mcpat_stats->WriteReq_misses[3]); 578 | findAndSetIntValue(l3_node, "stat", "write_misses", mcpat_stats->overall_misses[3]-mcpat_stats->Writeback_misses_l3 + 579 | mcpat_stats->WriteReq_misses[3]); 580 | 581 | /* TODO: NoC */ 582 | xml_node<> *noc_node = l3_node->next_sibling(); 583 | checkNode(noc_node, "system.NoC0", "noc0"); 584 | 585 | /* Main memory */ 586 | xml_node<> *mc_node = noc_node->next_sibling(); 587 | checkNode(mc_node, "system.mc", "mc"); 588 | findAndSetIntValue(mc_node, "param", "mc_clock", mcpat_param->clock_rate); 589 | findAndSetIntValue(mc_node, "param", "block_size", mcpat_param->block_size); 590 | findAndSetIntValue(mc_node, "param", "memory_channels_per_mc", mcpat_param->memory_channels_per_mc); 591 | findAndSetIntValue(mc_node, "param", "number_ranks", mcpat_param->number_ranks); 592 | 593 | findAndSetIntValue(mc_node, "stat", "memory_accesses", mcpat_stats->memory_reads + mcpat_stats->memory_writes); 594 | findAndSetIntValue(mc_node, "stat", "memory_reads", mcpat_stats->memory_reads); 595 | findAndSetIntValue(mc_node, "stat", "memory_writes", mcpat_stats->memory_writes); 596 | 597 | // finishing message 598 | cout << BLD "finish filling!" RES << endl; 599 | std::ofstream output; 600 | output.open(out_file); 601 | output << doc; 602 | } 603 | 604 | /* initializing */ 605 | void init_structs() 606 | { 607 | int i; 608 | mcpat_param = (struct t_mcpat_params *) malloc(sizeof(struct t_mcpat_params)); 609 | mcpat_stats = (struct t_mcpat_stats *) malloc(sizeof(struct t_mcpat_stats)); 610 | 611 | error_list = (struct t_error *) malloc(sizeof(struct t_error)); 612 | for (i=0; i < MAX_NUM; i++) { 613 | error_list->stat[i] = (char *) malloc(MAX_LINE*sizeof(char)); 614 | error_list->config[i] = (char *) malloc(MAX_LINE*sizeof(char)); 615 | } 616 | 617 | init_param(mcpat_param); 618 | } 619 | 620 | /* when 'error' is found in the parser */ 621 | void yyerror(const char *s, ...) 622 | { 623 | // activating error flag 624 | ERROR = 1; 625 | // showing user that there has been an error and then recording it 626 | printf("%d: error: %s\n", yylineno, s); 627 | if (yyin == config_fptr) { 628 | error_list->config[error_list->n_config] = strdup(s); 629 | error_list->config_l[error_list->n_config++] = yylineno; 630 | } else if (yyin == stats_fptr) { 631 | error_list->stat[error_list->n_stat] = strdup(s); 632 | error_list->stat_l[error_list->n_stat++] = yylineno; 633 | } 634 | } 635 | 636 | /* display recorded errors */ 637 | void display_errors() 638 | { 639 | int i; 640 | 641 | if ((error_list->n_config == 0)&& 642 | (error_list->n_stat == 0)) { 643 | printf(GRN "Parsing was successful!\n" RES); 644 | return; 645 | } 646 | 647 | printf(RED "Errors in config.ini: %d\n" RES, error_list->n_config); 648 | for(i=0; i < error_list->n_config; i++) { 649 | printf("%d: %s\n", error_list->config_l[i], error_list->config[i]); 650 | } 651 | 652 | printf(RED "Errors in stats: %d\n" RES, error_list->n_stat); 653 | for(i=0; i < error_list->n_stat; i++) { 654 | printf("%d: %s\n", error_list->stat_l[i], error_list->stat[i]); 655 | } 656 | } 657 | 658 | ///////////////////////////////// 659 | // main function 660 | int main(int argc, char *argv[]) 661 | { 662 | printf(BLD "gem5ToMcPAT v%s 2016\n" RES, VERSION); 663 | 664 | // check options 665 | int result = handle_options(argc, argv); 666 | 667 | if (result != 0) 668 | exit(result); 669 | 670 | if (argc - optind != 0) { 671 | printf ("Extra arguments\n\n"); 672 | while (optind < argc) 673 | printf ("'%s' ", argv[optind++]); 674 | printf ("\n"); 675 | usage(-2); 676 | } 677 | 678 | // copying file 679 | copy(xml_file, out_file); 680 | sleep(1); 681 | 682 | // initializing all the structures needed 683 | init_structs(); 684 | 685 | // parse config.ini 686 | yyin = config_fptr; 687 | yyparse(); 688 | printf("[config.ini]: finished parsing!\n"); 689 | fclose(yyin); 690 | 691 | // to clean yyin 692 | yyrestart(yyin); 693 | yyin = stats_fptr; 694 | yylineno = 0; 695 | yyparse(); 696 | printf("[stats.txt]: finished parsing!\n"); 697 | fclose(yyin); 698 | 699 | // in case the simulation is not detailed 700 | if (!DETAILED) 701 | printf(BLD YEL "Warning: simulation has not been done in detailed memory mode\n" 702 | "Thus there is a lack of stats and some values will be set to zero\n" RES); 703 | 704 | // fill template.xml if zero errors parsing 705 | // otherwise it makes no sense 706 | if (!ERROR) xmlParser(); 707 | else unlink(out_file); 708 | 709 | display_errors(); 710 | 711 | // free everything 712 | free_structs(); 713 | 714 | // quiting! 715 | exit(0); 716 | } 717 | -------------------------------------------------------------------------------- /template.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 37 | 38 | 39 | 40 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 58 | 59 | 60 | 61 | 62 | 64 | 65 | 66 | 68 | 69 | 70 | 71 | 72 | 73 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 101 | 102 | 103 | 104 | 105 | 110 | 111 | 113 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 140 | 141 | 142 | 143 | 144 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | 173 | 174 | 175 | 176 | 177 | 178 | 179 | 182 | 189 | 191 | 192 | 193 | 194 | 195 | 196 | 197 | 198 | 199 | 200 | 201 | 202 | 203 | 204 | 205 | 206 | 207 | 208 | 209 | 210 | 211 | 212 | 213 | 215 | 216 | 217 | 219 | 220 | 221 | 222 | 223 | 224 | 225 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | 234 | 235 | 236 | 237 | 238 | 239 | 240 | 241 | 242 | 243 | 244 | 245 | 246 | 247 | 248 | 249 | 250 | 251 | 252 | 253 | 254 | 255 | 256 | 257 | 258 | 259 | 260 | 261 | 262 | 263 | 264 | 265 | 266 | 269 | 270 | 271 | 272 | 273 | 274 | 275 | 276 | 277 | 278 | 279 | 280 | 281 | 282 | 283 | 284 | 285 | 286 | 287 | 290 | 291 | 292 | 293 | 294 | 295 | 296 | 297 | 298 | 299 | 300 | 301 | 302 | 303 | 304 | 305 | 306 | 307 | 308 | 309 | 310 | 311 | 312 | 313 | 314 | 315 | 316 | 317 | 318 | 319 | 320 | 321 | 322 | 323 | 324 | 325 | 326 | 327 | 328 | 329 | 330 | 331 | 332 | 333 | 334 | 335 | 336 | 337 | 338 | 339 | 340 | 341 | 342 | 343 | 344 | 345 | 346 | 347 | 348 | 349 | 350 | 351 | 353 | 354 | 355 | 356 | 357 | 358 | 359 | 360 | 361 | 362 | 363 | 364 | 365 | 366 | 367 | 368 | 369 | 370 | 371 | 372 | 375 | 376 | 377 | 378 | 379 | 380 | 381 | 382 | 383 | 384 | 385 | 386 | 387 | 388 | 389 | 390 | 391 | 392 | 393 | --------------------------------------------------------------------------------