initial commit
This commit is contained in:
commit
0dc2657e88
|
@ -0,0 +1,9 @@
|
||||||
|
**/bin
|
||||||
|
**/obj-pin
|
||||||
|
**/obj-comm
|
||||||
|
/.classpath
|
||||||
|
/.cproject
|
||||||
|
/.project
|
||||||
|
/.settings
|
||||||
|
**/hs_err*
|
||||||
|
**/*.swp
|
|
@ -0,0 +1,202 @@
|
||||||
|
|
||||||
|
Apache License
|
||||||
|
Version 2.0, January 2004
|
||||||
|
http://www.apache.org/licenses/
|
||||||
|
|
||||||
|
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||||
|
|
||||||
|
1. Definitions.
|
||||||
|
|
||||||
|
"License" shall mean the terms and conditions for use, reproduction,
|
||||||
|
and distribution as defined by Sections 1 through 9 of this document.
|
||||||
|
|
||||||
|
"Licensor" shall mean the copyright owner or entity authorized by
|
||||||
|
the copyright owner that is granting the License.
|
||||||
|
|
||||||
|
"Legal Entity" shall mean the union of the acting entity and all
|
||||||
|
other entities that control, are controlled by, or are under common
|
||||||
|
control with that entity. For the purposes of this definition,
|
||||||
|
"control" means (i) the power, direct or indirect, to cause the
|
||||||
|
direction or management of such entity, whether by contract or
|
||||||
|
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||||
|
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||||
|
|
||||||
|
"You" (or "Your") shall mean an individual or Legal Entity
|
||||||
|
exercising permissions granted by this License.
|
||||||
|
|
||||||
|
"Source" form shall mean the preferred form for making modifications,
|
||||||
|
including but not limited to software source code, documentation
|
||||||
|
source, and configuration files.
|
||||||
|
|
||||||
|
"Object" form shall mean any form resulting from mechanical
|
||||||
|
transformation or translation of a Source form, including but
|
||||||
|
not limited to compiled object code, generated documentation,
|
||||||
|
and conversions to other media types.
|
||||||
|
|
||||||
|
"Work" shall mean the work of authorship, whether in Source or
|
||||||
|
Object form, made available under the License, as indicated by a
|
||||||
|
copyright notice that is included in or attached to the work
|
||||||
|
(an example is provided in the Appendix below).
|
||||||
|
|
||||||
|
"Derivative Works" shall mean any work, whether in Source or Object
|
||||||
|
form, that is based on (or derived from) the Work and for which the
|
||||||
|
editorial revisions, annotations, elaborations, or other modifications
|
||||||
|
represent, as a whole, an original work of authorship. For the purposes
|
||||||
|
of this License, Derivative Works shall not include works that remain
|
||||||
|
separable from, or merely link (or bind by name) to the interfaces of,
|
||||||
|
the Work and Derivative Works thereof.
|
||||||
|
|
||||||
|
"Contribution" shall mean any work of authorship, including
|
||||||
|
the original version of the Work and any modifications or additions
|
||||||
|
to that Work or Derivative Works thereof, that is intentionally
|
||||||
|
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||||
|
or by an individual or Legal Entity authorized to submit on behalf of
|
||||||
|
the copyright owner. For the purposes of this definition, "submitted"
|
||||||
|
means any form of electronic, verbal, or written communication sent
|
||||||
|
to the Licensor or its representatives, including but not limited to
|
||||||
|
communication on electronic mailing lists, source code control systems,
|
||||||
|
and issue tracking systems that are managed by, or on behalf of, the
|
||||||
|
Licensor for the purpose of discussing and improving the Work, but
|
||||||
|
excluding communication that is conspicuously marked or otherwise
|
||||||
|
designated in writing by the copyright owner as "Not a Contribution."
|
||||||
|
|
||||||
|
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||||
|
on behalf of whom a Contribution has been received by Licensor and
|
||||||
|
subsequently incorporated within the Work.
|
||||||
|
|
||||||
|
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||||
|
this License, each Contributor hereby grants to You a perpetual,
|
||||||
|
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||||
|
copyright license to reproduce, prepare Derivative Works of,
|
||||||
|
publicly display, publicly perform, sublicense, and distribute the
|
||||||
|
Work and such Derivative Works in Source or Object form.
|
||||||
|
|
||||||
|
3. Grant of Patent License. Subject to the terms and conditions of
|
||||||
|
this License, each Contributor hereby grants to You a perpetual,
|
||||||
|
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||||
|
(except as stated in this section) patent license to make, have made,
|
||||||
|
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||||
|
where such license applies only to those patent claims licensable
|
||||||
|
by such Contributor that are necessarily infringed by their
|
||||||
|
Contribution(s) alone or by combination of their Contribution(s)
|
||||||
|
with the Work to which such Contribution(s) was submitted. If You
|
||||||
|
institute patent litigation against any entity (including a
|
||||||
|
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||||
|
or a Contribution incorporated within the Work constitutes direct
|
||||||
|
or contributory patent infringement, then any patent licenses
|
||||||
|
granted to You under this License for that Work shall terminate
|
||||||
|
as of the date such litigation is filed.
|
||||||
|
|
||||||
|
4. Redistribution. You may reproduce and distribute copies of the
|
||||||
|
Work or Derivative Works thereof in any medium, with or without
|
||||||
|
modifications, and in Source or Object form, provided that You
|
||||||
|
meet the following conditions:
|
||||||
|
|
||||||
|
(a) You must give any other recipients of the Work or
|
||||||
|
Derivative Works a copy of this License; and
|
||||||
|
|
||||||
|
(b) You must cause any modified files to carry prominent notices
|
||||||
|
stating that You changed the files; and
|
||||||
|
|
||||||
|
(c) You must retain, in the Source form of any Derivative Works
|
||||||
|
that You distribute, all copyright, patent, trademark, and
|
||||||
|
attribution notices from the Source form of the Work,
|
||||||
|
excluding those notices that do not pertain to any part of
|
||||||
|
the Derivative Works; and
|
||||||
|
|
||||||
|
(d) If the Work includes a "NOTICE" text file as part of its
|
||||||
|
distribution, then any Derivative Works that You distribute must
|
||||||
|
include a readable copy of the attribution notices contained
|
||||||
|
within such NOTICE file, excluding those notices that do not
|
||||||
|
pertain to any part of the Derivative Works, in at least one
|
||||||
|
of the following places: within a NOTICE text file distributed
|
||||||
|
as part of the Derivative Works; within the Source form or
|
||||||
|
documentation, if provided along with the Derivative Works; or,
|
||||||
|
within a display generated by the Derivative Works, if and
|
||||||
|
wherever such third-party notices normally appear. The contents
|
||||||
|
of the NOTICE file are for informational purposes only and
|
||||||
|
do not modify the License. You may add Your own attribution
|
||||||
|
notices within Derivative Works that You distribute, alongside
|
||||||
|
or as an addendum to the NOTICE text from the Work, provided
|
||||||
|
that such additional attribution notices cannot be construed
|
||||||
|
as modifying the License.
|
||||||
|
|
||||||
|
You may add Your own copyright statement to Your modifications and
|
||||||
|
may provide additional or different license terms and conditions
|
||||||
|
for use, reproduction, or distribution of Your modifications, or
|
||||||
|
for any such Derivative Works as a whole, provided Your use,
|
||||||
|
reproduction, and distribution of the Work otherwise complies with
|
||||||
|
the conditions stated in this License.
|
||||||
|
|
||||||
|
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||||
|
any Contribution intentionally submitted for inclusion in the Work
|
||||||
|
by You to the Licensor shall be under the terms and conditions of
|
||||||
|
this License, without any additional terms or conditions.
|
||||||
|
Notwithstanding the above, nothing herein shall supersede or modify
|
||||||
|
the terms of any separate license agreement you may have executed
|
||||||
|
with Licensor regarding such Contributions.
|
||||||
|
|
||||||
|
6. Trademarks. This License does not grant permission to use the trade
|
||||||
|
names, trademarks, service marks, or product names of the Licensor,
|
||||||
|
except as required for reasonable and customary use in describing the
|
||||||
|
origin of the Work and reproducing the content of the NOTICE file.
|
||||||
|
|
||||||
|
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||||
|
agreed to in writing, Licensor provides the Work (and each
|
||||||
|
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||||
|
implied, including, without limitation, any warranties or conditions
|
||||||
|
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||||
|
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||||
|
appropriateness of using or redistributing the Work and assume any
|
||||||
|
risks associated with Your exercise of permissions under this License.
|
||||||
|
|
||||||
|
8. Limitation of Liability. In no event and under no legal theory,
|
||||||
|
whether in tort (including negligence), contract, or otherwise,
|
||||||
|
unless required by applicable law (such as deliberate and grossly
|
||||||
|
negligent acts) or agreed to in writing, shall any Contributor be
|
||||||
|
liable to You for damages, including any direct, indirect, special,
|
||||||
|
incidental, or consequential damages of any character arising as a
|
||||||
|
result of this License or out of the use or inability to use the
|
||||||
|
Work (including but not limited to damages for loss of goodwill,
|
||||||
|
work stoppage, computer failure or malfunction, or any and all
|
||||||
|
other commercial damages or losses), even if such Contributor
|
||||||
|
has been advised of the possibility of such damages.
|
||||||
|
|
||||||
|
9. Accepting Warranty or Additional Liability. While redistributing
|
||||||
|
the Work or Derivative Works thereof, You may choose to offer,
|
||||||
|
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||||
|
or other liability obligations and/or rights consistent with this
|
||||||
|
License. However, in accepting such obligations, You may act only
|
||||||
|
on Your own behalf and on Your sole responsibility, not on behalf
|
||||||
|
of any other Contributor, and only if You agree to indemnify,
|
||||||
|
defend, and hold each Contributor harmless for any liability
|
||||||
|
incurred by, or claims asserted against, such Contributor by reason
|
||||||
|
of your accepting any such warranty or additional liability.
|
||||||
|
|
||||||
|
END OF TERMS AND CONDITIONS
|
||||||
|
|
||||||
|
APPENDIX: How to apply the Apache License to your work.
|
||||||
|
|
||||||
|
To apply the Apache License to your work, attach the following
|
||||||
|
boilerplate notice, with the fields enclosed by brackets "[]"
|
||||||
|
replaced with your own identifying information. (Don't include
|
||||||
|
the brackets!) The text should be enclosed in the appropriate
|
||||||
|
comment syntax for the file format. We also recommend that a
|
||||||
|
file or class name and description of purpose be included on the
|
||||||
|
same "printed page" as the copyright notice for easier
|
||||||
|
identification within third-party archives.
|
||||||
|
|
||||||
|
Copyright [yyyy] [name of copyright owner]
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
|
@ -0,0 +1,32 @@
|
||||||
|
3. 2. 1. The maintainers is a copy of the way that the Linux kernel maintainers works.
|
||||||
|
|
||||||
|
|
||||||
|
Example copy from SESC (Would be different for Tejas. Changes would be updated soon.)
|
||||||
|
-------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
Please follow the following steps before sending a path/update:
|
||||||
|
|
||||||
|
1-Checkout the latest SESC version and synchronize your patch with it.
|
||||||
|
|
||||||
|
2-Try to verify that your patch/update works.
|
||||||
|
|
||||||
|
3-If a patch involves more than one maintainer send it to both of them
|
||||||
|
simulatenously.
|
||||||
|
|
||||||
|
4-Follow the coding guideline of the documentation.
|
||||||
|
|
||||||
|
D: Description
|
||||||
|
F: Files Maintained (Use regular expression to do a match)
|
||||||
|
P: Person
|
||||||
|
M: Mail patches to
|
||||||
|
W: Web-page
|
||||||
|
S: Status, one of the following:
|
||||||
|
|
||||||
|
Supported: Someone is actually paid to look after this.
|
||||||
|
Maintained: Someone actually looks after it.
|
||||||
|
Odd Fixes: It has a maintainer but they don't have time to do
|
||||||
|
much other than throw the odd patch in. See below..
|
||||||
|
Orphan: No current maintainer [but maybe you could take the
|
||||||
|
role as you write your new code].
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,30 @@
|
||||||
|
/*****************************************************************************
|
||||||
|
Tejas Simulator
|
||||||
|
------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
Copyright [2010] [Indian Institute of Technology, Delhi]
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
Contributors: <name>
|
||||||
|
|
||||||
|
------------------------ NOTICE for Apache Common Pool ------------------------
|
||||||
|
|
||||||
|
Apache Commons Pool
|
||||||
|
Copyright 2001-2012 The Apache Software Foundation
|
||||||
|
|
||||||
|
This product includes software developed by
|
||||||
|
The Apache Software Foundation (http://www.apache.org/).
|
||||||
|
|
||||||
|
*****************************************************************************/
|
||||||
|
|
|
@ -0,0 +1,103 @@
|
||||||
|
Operating System Verified on:
|
||||||
|
1. Ubuntu 14.04
|
||||||
|
2. Ubuntu 16.04
|
||||||
|
3. Ubuntu 18.04
|
||||||
|
|
||||||
|
|
||||||
|
HOW TO setup Tejas
|
||||||
|
-----------------------
|
||||||
|
Building
|
||||||
|
---------
|
||||||
|
how to setup the simulator for the first time.
|
||||||
|
|
||||||
|
Pre-requisite:
|
||||||
|
1. Download Intel PIN. Tested for version 3.7 Kit: 97619
|
||||||
|
https://software.intel.com/en-us/articles/pin-a-binary-instrumentation-tool-downloads
|
||||||
|
|
||||||
|
2. Java version: openjdk8
|
||||||
|
3. make
|
||||||
|
4. ant
|
||||||
|
5. g++
|
||||||
|
|
||||||
|
Commands to build:
|
||||||
|
--------------
|
||||||
|
|
||||||
|
Make changes to (set absolute path as per your machine) :
|
||||||
|
|
||||||
|
src/simulator/config/config.xml
|
||||||
|
src/emulator/pin/makefile_linux_mac
|
||||||
|
|
||||||
|
Run:
|
||||||
|
ant make-jar
|
||||||
|
|
||||||
|
If everything goes well, this will create a jars folder with tejas.jar in it.
|
||||||
|
|
||||||
|
Testing
|
||||||
|
----------
|
||||||
|
cd scripts
|
||||||
|
./test.sh
|
||||||
|
|
||||||
|
|
||||||
|
# Examples of configure parameters:
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
modifying and testing the simulator
|
||||||
|
-----------------------------------
|
||||||
|
|
||||||
|
testing
|
||||||
|
-------
|
||||||
|
|
||||||
|
committing
|
||||||
|
---------
|
||||||
|
|
||||||
|
ChangeLog
|
||||||
|
---------
|
||||||
|
|
||||||
|
|
||||||
|
Tejas directory structure
|
||||||
|
------------------------------
|
||||||
|
|
||||||
|
doc - contains explanation of the functionality and working of
|
||||||
|
source code with suitable examples
|
||||||
|
LICENSE - Contains the terms and conditions for use, reproduction and distribution
|
||||||
|
MAINTAINERS - who is responsible for what description
|
||||||
|
NOTICE - copyright notice
|
||||||
|
README - Contains instructions to build and provides overview of Tejas
|
||||||
|
src - all real code for Tejas is in this directory (description below)
|
||||||
|
TODO - if you have some time available and you want to have some fun,
|
||||||
|
check this file and help improve Tejas
|
||||||
|
|
||||||
|
|
||||||
|
src directory structure
|
||||||
|
-----------------------
|
||||||
|
|
||||||
|
configure - configuration script
|
||||||
|
emulator - source files of the emulator (Implemented in C++)
|
||||||
|
simulator - source files of the simulator (Implemented in Java)
|
||||||
|
|
||||||
|
/src/simulator/ :
|
||||||
|
generic - functionalities used across packages
|
||||||
|
for example : event queue is used by memory-system and pipeline
|
||||||
|
misc - miscellaneous functions
|
||||||
|
memory - cache simulator
|
||||||
|
pipeline - pipeline simulation
|
||||||
|
config - used to set various configuration parameters such as underlying architecture,
|
||||||
|
number of cores, and branch-predictor
|
||||||
|
power - power modelling of the system using performance counters
|
||||||
|
net - simulate the on-chip network to estimate the delay due to bus-contention
|
||||||
|
emulatorinterface - interface to the emulator
|
||||||
|
|
||||||
|
|
||||||
|
/src/simulator/emulatorinterface :
|
||||||
|
translator - translates the assembly-format of the executable to abstract instruction
|
||||||
|
translator/x86 - x86 translator
|
||||||
|
translator/mips - mips translator
|
||||||
|
translator/arm - arm translator
|
||||||
|
communication - used to take the value from the emulator
|
||||||
|
communication/shm - shared memory
|
||||||
|
communication/pipe - pipe
|
||||||
|
communication/network - network
|
||||||
|
communication/socket - sockets
|
||||||
|
instruction - abstract format of the instruction
|
|
@ -0,0 +1,8 @@
|
||||||
|
Version 0.1:
|
||||||
|
+ NUCA (To be done by Mayur)
|
||||||
|
+ Some Testing (Rajshekar)
|
||||||
|
+ Reuse thread ids (Eldhose and Harsh)
|
||||||
|
+ Pipeline Bugs (Eldhose and Mayur)
|
||||||
|
|
||||||
|
Version 0.2:
|
||||||
|
+ Qemu Packet and Pin Packet (Prathmesh and Nitin)
|
|
@ -0,0 +1,12 @@
|
||||||
|
1)
|
||||||
|
_______________________________________________________________________________
|
||||||
|
|
||||||
|
2)
|
||||||
|
_______________________________________________________________________________
|
||||||
|
|
||||||
|
3)
|
||||||
|
_______________________________________________________________________________
|
||||||
|
|
||||||
|
4)
|
||||||
|
_______________________________________________________________________________
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
ADD
|
|
@ -0,0 +1 @@
|
||||||
|
add
|
|
@ -0,0 +1 @@
|
||||||
|
ADD
|
|
@ -0,0 +1,81 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
|
|
||||||
|
<project basedir="." default="build" name="Tejas">
|
||||||
|
<!-- change these as required -->
|
||||||
|
<property name="jar-dir" value="jars"/> <!-- directory where the jars are generated -->
|
||||||
|
<property name="jar-name" value="tejas"/> <!-- name of the jar -->
|
||||||
|
<property name="main-class" value="main.Main"/> <!-- path to the main class -->
|
||||||
|
<!-- ________________________ -->
|
||||||
|
|
||||||
|
<property environment="env"/>
|
||||||
|
<property name="debuglevel" value="source,lines,vars"/>
|
||||||
|
<property name="target" value="1.6"/>
|
||||||
|
<property name="source" value="1.6"/>
|
||||||
|
<path id="Tejas.classpath">
|
||||||
|
<pathelement location="bin"/>
|
||||||
|
</path>
|
||||||
|
<target name="init">
|
||||||
|
<mkdir dir="bin"/>
|
||||||
|
<copy includeemptydirs="false" todir="bin">
|
||||||
|
<fileset dir="src">
|
||||||
|
<exclude name="**/*.launch"/>
|
||||||
|
<exclude name="**/*.java"/>
|
||||||
|
<exclude name="simulator/"/>
|
||||||
|
<exclude name="emulator/pin/"/>
|
||||||
|
</fileset>
|
||||||
|
</copy>
|
||||||
|
<copy includeemptydirs="false" todir="bin">
|
||||||
|
<fileset dir="src/simulator">
|
||||||
|
<exclude name="**/*.launch"/>
|
||||||
|
<exclude name="**/*.java"/>
|
||||||
|
</fileset>
|
||||||
|
</copy>
|
||||||
|
<copy includeemptydirs="false" todir="bin">
|
||||||
|
<fileset dir="src/emulator/pin">
|
||||||
|
<exclude name="**/*.launch"/>
|
||||||
|
<exclude name="**/*.java"/>
|
||||||
|
</fileset>
|
||||||
|
</copy>
|
||||||
|
</target>
|
||||||
|
<target name="clean" depends="clean-pin">
|
||||||
|
<delete dir="bin"/>
|
||||||
|
<delete dir="jars"/>
|
||||||
|
</target>
|
||||||
|
<target depends="clean" name="cleanall"/>
|
||||||
|
<target depends="build-subprojects,build-project,build-pin" name="build"/>
|
||||||
|
<target name="build-subprojects"/>
|
||||||
|
<target depends="init" name="build-project">
|
||||||
|
<echo message="${ant.project.name}: ${ant.file}"/>
|
||||||
|
<javac debug="true" debuglevel="${debuglevel}" destdir="bin" source="${source}" target="${target}">
|
||||||
|
<src path="src"/>
|
||||||
|
<exclude name="simulator/"/>
|
||||||
|
<exclude name="emulator/pin/"/>
|
||||||
|
<classpath refid="Tejas.classpath"/>
|
||||||
|
</javac>
|
||||||
|
<javac debug="true" debuglevel="${debuglevel}" destdir="bin" source="${source}" target="${target}">
|
||||||
|
<src path="src/simulator"/>
|
||||||
|
<classpath refid="Tejas.classpath"/>
|
||||||
|
</javac>
|
||||||
|
<javac debug="true" debuglevel="${debuglevel}" destdir="bin" source="${source}" target="${target}">
|
||||||
|
<src path="src/emulator/pin"/>
|
||||||
|
<classpath refid="Tejas.classpath"/>
|
||||||
|
</javac>
|
||||||
|
</target>
|
||||||
|
<target name="clean-pin">
|
||||||
|
<exec dir="src/emulator/pin" executable="make">
|
||||||
|
<arg value="clean"/>
|
||||||
|
</exec>
|
||||||
|
</target>
|
||||||
|
<target name="build-pin">
|
||||||
|
<exec dir="src/emulator/pin" executable="make">
|
||||||
|
</exec>
|
||||||
|
</target>
|
||||||
|
<target name="make-jar" depends="build">
|
||||||
|
<mkdir dir="${jar-dir}"/>
|
||||||
|
<jar destfile="${jar-dir}/${jar-name}.jar" basedir="bin">
|
||||||
|
<manifest>
|
||||||
|
<attribute name="Main-Class" value="${main-class}"/>
|
||||||
|
</manifest>
|
||||||
|
</jar>
|
||||||
|
</target>
|
||||||
|
</project>
|
|
@ -0,0 +1,98 @@
|
||||||
|
|
||||||
|
|
||||||
|
from sys import platform
|
||||||
|
import subprocess
|
||||||
|
import xml.etree.ElementTree as ET
|
||||||
|
import os, sys
|
||||||
|
import shutil
|
||||||
|
|
||||||
|
# TEJAS_HOME = "/home/sandeep/Desktop/Work/PhD/Tejas"
|
||||||
|
# PIN_HOME = "/home/sandeep/Desktop/Test/pin-3.7-97619-g0d0c92f4f-gcc-linux/"
|
||||||
|
|
||||||
|
print (("\n\nStep 1 : Reading Config files"))
|
||||||
|
fname = 'bin/config/config.xml'
|
||||||
|
tree = ET.parse(fname)
|
||||||
|
root = tree.getroot()
|
||||||
|
emulator = root.find('Emulator')
|
||||||
|
TEJAS_HOME=emulator.find('Tejashome').text
|
||||||
|
PIN_HOME=emulator.find('PinTool').text
|
||||||
|
|
||||||
|
|
||||||
|
#PIN
|
||||||
|
print (("\n\nStep 2 : setting up Pin"))
|
||||||
|
print ("Building Pin")
|
||||||
|
subprocess.call(['./tejaspin.sh', TEJAS_HOME, PIN_HOME])
|
||||||
|
print ("Building PIN done")
|
||||||
|
|
||||||
|
#configuring
|
||||||
|
print ('\n\nStep 3 : Configuring')
|
||||||
|
|
||||||
|
jniInclude=""
|
||||||
|
fname=""
|
||||||
|
|
||||||
|
jniInclude = "-I/usr/lib/jvm/java-8-openjdk-amd64/include/linux -I/usr/lib/jvm/java-8-openjdk-amd64/include "
|
||||||
|
fname = 'src/emulator/pin/makefile_linux_mac'
|
||||||
|
|
||||||
|
print ('setting PINPATH in ' + fname + " to " + PIN_HOME)
|
||||||
|
f = open(fname, 'r')
|
||||||
|
lines = f.readlines()
|
||||||
|
i = 0
|
||||||
|
for line in lines:
|
||||||
|
if "PIN_KIT ?=" in line:
|
||||||
|
lines[i] = "PIN_KIT ?=" + PIN_HOME + "\n"
|
||||||
|
if "JNINCLUDE =" in line:
|
||||||
|
lines[i] = "JNINCLUDE =" + jniInclude + "\n"
|
||||||
|
i = i + 1
|
||||||
|
f.close()
|
||||||
|
f = open(fname, 'w')
|
||||||
|
for line in lines:
|
||||||
|
f.write(line)
|
||||||
|
f.close()
|
||||||
|
|
||||||
|
#update config.xml
|
||||||
|
fname = 'src/simulator/config/config.xml'
|
||||||
|
tree = ET.parse(fname)
|
||||||
|
root = tree.getroot()
|
||||||
|
emulator = root.find('Emulator')
|
||||||
|
print ('setting PinTool in ' + fname + ' to ' + PIN_HOME)
|
||||||
|
emulator.find('PinTool').text = PIN_HOME
|
||||||
|
print ('setting PinInstrumentor in ' + fname + ' to ' + TEJAS_HOME + '/src/emulator/pin/obj-pin/causalityTool.so')
|
||||||
|
emulator.find('PinInstrumentor').text = TEJAS_HOME + "/src/emulator/pin/obj-pin/causalityTool.so"
|
||||||
|
print ('setting ShmLibDirectory in ' + fname + ' to ' + TEJAS_HOME + '/src/emulator/pin/obj-comm')
|
||||||
|
emulator.find('ShmLibDirectory').text = TEJAS_HOME + "/src/emulator/pin/obj-comm"
|
||||||
|
print ('setting KillEmulatorScript in ' + fname + ' to ' + TEJAS_HOME + '/src/simulator/main/killAllDescendents.sh')
|
||||||
|
emulator.find('KillEmulatorScript').text = TEJAS_HOME + "/src/simulator/main/killAllDescendents.sh"
|
||||||
|
|
||||||
|
system = root.find('System')
|
||||||
|
noc = system.find('NOC')
|
||||||
|
print ('setting NocConfigFile in ' + fname + ' to ' + TEJAS_HOME + '/src/simulator/config/NocConfig.txt')
|
||||||
|
noc.find('NocConfigFile').text = TEJAS_HOME + '/src/simulator/config/NocConfig.txt'
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
if sys.version_info < (2, 7):
|
||||||
|
tree.write(fname, encoding="UTF-8")
|
||||||
|
else:
|
||||||
|
tree.write(fname, encoding="UTF-8", xml_declaration=True)
|
||||||
|
|
||||||
|
print ("configure successful")
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#building
|
||||||
|
print ('\n\nStep 4 : Building Jar File')
|
||||||
|
print ("jniInclude is " + jniInclude)
|
||||||
|
status = subprocess.call('ant make-jar',shell=True)
|
||||||
|
if status != 0 or os.path.exists(TEJAS_HOME + "/src/emulator/pin/obj-pin/causalityTool.so") == False or os.path.exists(TEJAS_HOME + "/src/emulator/pin/obj-comm/libshmlib.so") == False:
|
||||||
|
print ("error building : " + str(os.WEXITSTATUS(status)))
|
||||||
|
# print (output)
|
||||||
|
sys.exit(1)
|
||||||
|
else:
|
||||||
|
print ("build successful")
|
||||||
|
|
||||||
|
|
||||||
|
print ("------------- Tejas installed successfuly ----------------\n" )
|
||||||
|
print ("Tejas jar has been created here : " + TEJAS_HOME + "/jars/tejas.jar")
|
||||||
|
print ("Configuration file is kept here : " + TEJAS_HOME + "/src/simulator/config/config.xml")
|
||||||
|
print ("Use this command to run tejas : java -jar <tejas.jar> <config-file> <output-file> <input-program and arguments>")
|
|
@ -0,0 +1,202 @@
|
||||||
|
|
||||||
|
Apache License
|
||||||
|
Version 2.0, January 2004
|
||||||
|
http://www.apache.org/licenses/
|
||||||
|
|
||||||
|
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||||
|
|
||||||
|
1. Definitions.
|
||||||
|
|
||||||
|
"License" shall mean the terms and conditions for use, reproduction,
|
||||||
|
and distribution as defined by Sections 1 through 9 of this document.
|
||||||
|
|
||||||
|
"Licensor" shall mean the copyright owner or entity authorized by
|
||||||
|
the copyright owner that is granting the License.
|
||||||
|
|
||||||
|
"Legal Entity" shall mean the union of the acting entity and all
|
||||||
|
other entities that control, are controlled by, or are under common
|
||||||
|
control with that entity. For the purposes of this definition,
|
||||||
|
"control" means (i) the power, direct or indirect, to cause the
|
||||||
|
direction or management of such entity, whether by contract or
|
||||||
|
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||||
|
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||||
|
|
||||||
|
"You" (or "Your") shall mean an individual or Legal Entity
|
||||||
|
exercising permissions granted by this License.
|
||||||
|
|
||||||
|
"Source" form shall mean the preferred form for making modifications,
|
||||||
|
including but not limited to software source code, documentation
|
||||||
|
source, and configuration files.
|
||||||
|
|
||||||
|
"Object" form shall mean any form resulting from mechanical
|
||||||
|
transformation or translation of a Source form, including but
|
||||||
|
not limited to compiled object code, generated documentation,
|
||||||
|
and conversions to other media types.
|
||||||
|
|
||||||
|
"Work" shall mean the work of authorship, whether in Source or
|
||||||
|
Object form, made available under the License, as indicated by a
|
||||||
|
copyright notice that is included in or attached to the work
|
||||||
|
(an example is provided in the Appendix below).
|
||||||
|
|
||||||
|
"Derivative Works" shall mean any work, whether in Source or Object
|
||||||
|
form, that is based on (or derived from) the Work and for which the
|
||||||
|
editorial revisions, annotations, elaborations, or other modifications
|
||||||
|
represent, as a whole, an original work of authorship. For the purposes
|
||||||
|
of this License, Derivative Works shall not include works that remain
|
||||||
|
separable from, or merely link (or bind by name) to the interfaces of,
|
||||||
|
the Work and Derivative Works thereof.
|
||||||
|
|
||||||
|
"Contribution" shall mean any work of authorship, including
|
||||||
|
the original version of the Work and any modifications or additions
|
||||||
|
to that Work or Derivative Works thereof, that is intentionally
|
||||||
|
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||||
|
or by an individual or Legal Entity authorized to submit on behalf of
|
||||||
|
the copyright owner. For the purposes of this definition, "submitted"
|
||||||
|
means any form of electronic, verbal, or written communication sent
|
||||||
|
to the Licensor or its representatives, including but not limited to
|
||||||
|
communication on electronic mailing lists, source code control systems,
|
||||||
|
and issue tracking systems that are managed by, or on behalf of, the
|
||||||
|
Licensor for the purpose of discussing and improving the Work, but
|
||||||
|
excluding communication that is conspicuously marked or otherwise
|
||||||
|
designated in writing by the copyright owner as "Not a Contribution."
|
||||||
|
|
||||||
|
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||||
|
on behalf of whom a Contribution has been received by Licensor and
|
||||||
|
subsequently incorporated within the Work.
|
||||||
|
|
||||||
|
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||||
|
this License, each Contributor hereby grants to You a perpetual,
|
||||||
|
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||||
|
copyright license to reproduce, prepare Derivative Works of,
|
||||||
|
publicly display, publicly perform, sublicense, and distribute the
|
||||||
|
Work and such Derivative Works in Source or Object form.
|
||||||
|
|
||||||
|
3. Grant of Patent License. Subject to the terms and conditions of
|
||||||
|
this License, each Contributor hereby grants to You a perpetual,
|
||||||
|
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||||
|
(except as stated in this section) patent license to make, have made,
|
||||||
|
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||||
|
where such license applies only to those patent claims licensable
|
||||||
|
by such Contributor that are necessarily infringed by their
|
||||||
|
Contribution(s) alone or by combination of their Contribution(s)
|
||||||
|
with the Work to which such Contribution(s) was submitted. If You
|
||||||
|
institute patent litigation against any entity (including a
|
||||||
|
cross-claim or counter claim in a lawsuit) alleging that the Work
|
||||||
|
or a Contribution incorporated within the Work constitutes direct
|
||||||
|
or contributory patent infringement, then any patent licenses
|
||||||
|
granted to You under this License for that Work shall terminate
|
||||||
|
as of the date such litigation is filed.
|
||||||
|
|
||||||
|
4. Redistribution. You may reproduce and distribute copies of the
|
||||||
|
Work or Derivative Works thereof in any medium, with or without
|
||||||
|
modifications, and in Source or Object form, provided that You
|
||||||
|
meet the following conditions:
|
||||||
|
|
||||||
|
(a) You must give any other recipients of the Work or
|
||||||
|
Derivative Works a copy of this License; and
|
||||||
|
|
||||||
|
(b) You must cause any modified files to carry prominent notices
|
||||||
|
stating that You changed the files; and
|
||||||
|
|
||||||
|
(c) You must retain, in the Source form of any Derivative Works
|
||||||
|
that You distribute, all copyright, patent, trademark, and
|
||||||
|
attribution notices from the Source form of the Work,
|
||||||
|
excluding those notices that do not pertain to any part of
|
||||||
|
the Derivative Works; and
|
||||||
|
|
||||||
|
(d) If the Work includes a "NOTICE" text file as part of its
|
||||||
|
distribution, then any Derivative Works that You distribute must
|
||||||
|
include a readable copy of the attribution notices contained
|
||||||
|
within such NOTICE file, excluding those notices that do not
|
||||||
|
pertain to any part of the Derivative Works, in at least one
|
||||||
|
of the following places: within a NOTICE text file distributed
|
||||||
|
as part of the Derivative Works; within the Source form or
|
||||||
|
documentation, if provided along with the Derivative Works; or,
|
||||||
|
within a display generated by the Derivative Works, if and
|
||||||
|
wherever such third-party notices normally appear. The contents
|
||||||
|
of the NOTICE file are for informational purposes only and
|
||||||
|
do not modify the License. You may add Your own attribution
|
||||||
|
notices within Derivative Works that You distribute, alongside
|
||||||
|
or as an addendum to the NOTICE text from the Work, provided
|
||||||
|
that such additional attribution notices cannot be construed
|
||||||
|
as modifying the License.
|
||||||
|
|
||||||
|
You may add Your own copyright statement to Your modifications and
|
||||||
|
may provide additional or different license terms and conditions
|
||||||
|
for use, reproduction, or distribution of Your modifications, or
|
||||||
|
for any such Derivative Works as a whole, provided Your use,
|
||||||
|
reproduction, and distribution of the Work otherwise complies with
|
||||||
|
the conditions stated in this License.
|
||||||
|
|
||||||
|
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||||
|
any Contribution intentionally submitted for inclusion in the Work
|
||||||
|
by You to the Licensor shall be under the terms and conditions of
|
||||||
|
this License, without any additional terms or conditions.
|
||||||
|
Notwithstanding the above, nothing herein shall supersede or modify
|
||||||
|
the terms of any separate license agreement you may have executed
|
||||||
|
with Licensor regarding such Contributions.
|
||||||
|
|
||||||
|
6. Trademarks. This License does not grant permission to use the trade
|
||||||
|
names, trademarks, service marks, or product names of the Licensor,
|
||||||
|
except as required for reasonable and customary use in describing the
|
||||||
|
origin of the Work and reproducing the content of the NOTICE file.
|
||||||
|
|
||||||
|
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||||
|
agreed to in writing, Licensor provides the Work (and each
|
||||||
|
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||||
|
implied, including, without limitation, any warranties or conditions
|
||||||
|
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||||
|
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||||
|
appropriateness of using or redistributing the Work and assume any
|
||||||
|
risks associated with Your exercise of permissions under this License.
|
||||||
|
|
||||||
|
8. Limitation of Liability. In no event and under no legal theory,
|
||||||
|
whether in tort (including negligence), contract, or otherwise,
|
||||||
|
unless required by applicable law (such as deliberate and grossly
|
||||||
|
negligent acts) or agreed to in writing, shall any Contributor be
|
||||||
|
liable to You for damages, including any direct, indirect, special,
|
||||||
|
incidental, or consequential damages of any character arising as a
|
||||||
|
result of this License or out of the use or inability to use the
|
||||||
|
Work (including but not limited to damages for loss of goodwill,
|
||||||
|
work stoppage, computer failure or malfunction, or any and all
|
||||||
|
other commercial damages or losses), even if such Contributor
|
||||||
|
has been advised of the possibility of such damages.
|
||||||
|
|
||||||
|
9. Accepting Warranty or Additional Liability. While redistributing
|
||||||
|
the Work or Derivative Works thereof, You may choose to offer,
|
||||||
|
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||||
|
or other liability obligations and/or rights consistent with this
|
||||||
|
License. However, in accepting such obligations, You may act only
|
||||||
|
on Your own behalf and on Your sole responsibility, not on behalf
|
||||||
|
of any other Contributor, and only if You agree to indemnify,
|
||||||
|
defend, and hold each Contributor harmless for any liability
|
||||||
|
incurred by, or claims asserted against, such Contributor by reason
|
||||||
|
of your accepting any such warranty or additional liability.
|
||||||
|
|
||||||
|
END OF TERMS AND CONDITIONS
|
||||||
|
|
||||||
|
APPENDIX: How to apply the Apache License to your work.
|
||||||
|
|
||||||
|
To apply the Apache License to your work, attach the following
|
||||||
|
boilerplate notice, with the fields enclosed by brackets "[]"
|
||||||
|
replaced with your own identifying information. (Don't include
|
||||||
|
the brackets!) The text should be enclosed in the appropriate
|
||||||
|
comment syntax for the file format. We also recommend that a
|
||||||
|
file or class name and description of purpose be included on the
|
||||||
|
same "printed page" as the copyright notice for easier
|
||||||
|
identification within third-party archives.
|
||||||
|
|
||||||
|
Copyright [yyyy] [name of copyright owner]
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
|
@ -0,0 +1,4 @@
|
||||||
|
wget https://software.intel.com/sites/landingpage/pintool/downloads/pin-3.7-97619-g0d0c92f4f-gcc-linux.tar.gz
|
||||||
|
tar -xzvf pin-3.7-97619-g0d0c92f4f-gcc-linux.tar.gz
|
||||||
|
cd pin-3.7-97619-g0d0c92f4f-gcc-linux
|
||||||
|
pwd
|
|
@ -0,0 +1,311 @@
|
||||||
|
|
||||||
|
from sys import platform
|
||||||
|
import commands
|
||||||
|
import xml.etree.ElementTree as ET
|
||||||
|
import os, sys
|
||||||
|
import shutil
|
||||||
|
|
||||||
|
if platform == "win32":
|
||||||
|
from subprocess import check_output,call
|
||||||
|
pwd = os.getcwd(); ###change
|
||||||
|
#elif platform == "linux" or platform == "linux2":
|
||||||
|
else:
|
||||||
|
pwd = commands.getoutput('pwd')
|
||||||
|
#print "\npwd is " + pwd
|
||||||
|
if os.path.exists(pwd + "/Tejas-Simulator") == False:
|
||||||
|
os.mkdir(pwd + "/Tejas-Simulator")
|
||||||
|
os.chdir(pwd + "/Tejas-Simulator")
|
||||||
|
pwd = pwd + "/Tejas-Simulator"
|
||||||
|
|
||||||
|
#print dependencies
|
||||||
|
print "\nInstallation Dependencies :"
|
||||||
|
print "\t1) Mercurial"
|
||||||
|
print "\t2) Java (tested for 1.6 and 1.7)"
|
||||||
|
print "\t3) ant"
|
||||||
|
print "\t4) Intel Pin tar-ball"
|
||||||
|
|
||||||
|
installation_option=raw_input("\n\nPress enter to continue. ")
|
||||||
|
|
||||||
|
# Install from tar-ball or repository
|
||||||
|
print "\n\nStep 1 : cloning Tejas source"
|
||||||
|
print "\n\nTejas Installation Option : "
|
||||||
|
print "\t1) to install Tejas from the tar-ball in installation kit"
|
||||||
|
print "\t2) to install Tejas from the repository (Latest version)"
|
||||||
|
installation_option=raw_input("\n\nenter option : ")
|
||||||
|
|
||||||
|
if installation_option=="1":
|
||||||
|
tejas_tar_ball=raw_input("\n\nenter path of tejas tar-ball : ")
|
||||||
|
|
||||||
|
if platform == "win32":
|
||||||
|
cmd="tar -xvf "+tejas_tar_ball+" --force-local"
|
||||||
|
status = call(cmd,shell=True)
|
||||||
|
#else platform == "linux" or platform == "linux2":
|
||||||
|
else:
|
||||||
|
status = os.system("tar -xvf " + tejas_tar_ball)
|
||||||
|
if status!=0:
|
||||||
|
print "error in extracting tejas : " + + str(os.WEXITSTATUS(status))
|
||||||
|
print '\n'
|
||||||
|
sys.exit(1)
|
||||||
|
else:
|
||||||
|
print "extracted tejas successfully"
|
||||||
|
|
||||||
|
elif installation_option=="2":
|
||||||
|
if platform == "linux" or platform == "linux2":
|
||||||
|
print "\n\n\tEnter guest as username and guest1 as password on prompt"
|
||||||
|
|
||||||
|
#clone tejas
|
||||||
|
url = "http://www.cse.iitd.ac.in/srishtihg/hg/distrib/Tejas"
|
||||||
|
if os.path.exists(pwd + '/Tejas'):
|
||||||
|
print "Tejas source already cloned"
|
||||||
|
else:
|
||||||
|
print 'getting source please wait'
|
||||||
|
status = os.system("hg clone " + url)
|
||||||
|
#status, output = commands.getstatusoutput("hg clone " + url)
|
||||||
|
if status != 0:
|
||||||
|
print "error cloning : " + str(os.WEXITSTATUS(status))
|
||||||
|
#print output
|
||||||
|
print '\n'
|
||||||
|
sys.exit(1)
|
||||||
|
else:
|
||||||
|
print "cloning successful"
|
||||||
|
|
||||||
|
else:
|
||||||
|
print "Invalid option for installation : " + installation_option
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
|
||||||
|
#PIN
|
||||||
|
print "\n\nStep 2 : setting up Pin"
|
||||||
|
pin_path = ""
|
||||||
|
|
||||||
|
#download PIN
|
||||||
|
if platform == "win32":
|
||||||
|
#download PIN
|
||||||
|
print "Download version 71313-msvc11-windows from Intel's website : http://software.intel.com/en-us/articles/pintool-downloads"
|
||||||
|
print "Please read the license before downloading : http://software.intel.com/sites/landingpage/pintool/extlicense.txt"
|
||||||
|
print "NOTE : This installation script requires Pin in the form of zip file"
|
||||||
|
|
||||||
|
pin_tar_path = raw_input("\n\nenter absolute path of the Pin zip: ")
|
||||||
|
if os.path.exists(pin_tar_path) == False:
|
||||||
|
print "Pin not provided.. Exiting."
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
#extract PIN
|
||||||
|
print "extracting PIN"
|
||||||
|
if os.path.exists(pwd + "/PIN"):
|
||||||
|
shutil.rmtree(pwd + "/PIN")
|
||||||
|
os.mkdir(pwd + "/PIN")
|
||||||
|
os.chdir(pwd + "/PIN")
|
||||||
|
status = call("jar xf " + pin_tar_path,shell=True)
|
||||||
|
if status != 0:
|
||||||
|
print "error extracting Pin"
|
||||||
|
print output
|
||||||
|
sys.exit(1)
|
||||||
|
filenames = os.listdir(pwd + "/PIN")
|
||||||
|
pin_path = pwd + "/PIN/" + filenames[0]
|
||||||
|
os.chdir(pwd)
|
||||||
|
|
||||||
|
else:
|
||||||
|
#if platform == "linux" or platform == "linux2":
|
||||||
|
#download PIN
|
||||||
|
print "Download version 62732 from Intel's website : http://software.intel.com/en-us/articles/pintool-downloads"
|
||||||
|
print "Please read the license before downloading : http://software.intel.com/sites/landingpage/pintool/extlicense.txt"
|
||||||
|
print "NOTE : This installation script requires Pin in the form of a tar-ball"
|
||||||
|
|
||||||
|
pin_tar_path = raw_input("\n\nenter absolute path of the Pin tar-ball (only tar.gz format) : ")
|
||||||
|
if os.path.exists(pin_tar_path) == False:
|
||||||
|
print "Pin not provided.. Exiting."
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
|
||||||
|
#extract PIN
|
||||||
|
print "extracting PIN"
|
||||||
|
if os.path.exists(pwd + "/PIN"):
|
||||||
|
shutil.rmtree(pwd + "/PIN")
|
||||||
|
os.mkdir(pwd + "/PIN")
|
||||||
|
os.chdir(pwd + "/PIN")
|
||||||
|
status, output = commands.getstatusoutput("tar -xvf " + pin_tar_path)
|
||||||
|
if status != 0:
|
||||||
|
print "error extracting Pin : " + str(os.WEXITSTATUS(status))
|
||||||
|
print output
|
||||||
|
sys.exit(1)
|
||||||
|
filenames = os.listdir(pwd + "/PIN")
|
||||||
|
pin_path = pwd + "/PIN/" + filenames[0]
|
||||||
|
os.chdir(pwd)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#configuring
|
||||||
|
print '\n\nStep 3 : Configuring'
|
||||||
|
|
||||||
|
jniInclude=""
|
||||||
|
fname=""
|
||||||
|
if platform == "win32":
|
||||||
|
jniInclude = "-I\"" + os.getenv('JAVA_HOME') + "\\include\" " + "-I\"" + os.getenv('JAVA_HOME') + "\\include\\win32\""
|
||||||
|
fname = 'Tejas/src/emulator/pin/makefile_windows'
|
||||||
|
else:
|
||||||
|
if platform == "darwin":
|
||||||
|
jniInclude = "-I/System/Library/Frameworks/JavaVM.framework/Versions/Current/Headers"
|
||||||
|
else:
|
||||||
|
jniInclude = "-I/usr/lib/jvm/java-6-openjdk-amd64/include -I/usr/lib/jvm/java-7-openjdk-amd64/include -I/usr/lib/jvm/java-8-openjdk-amd64/include -I/usr/lib/jvm/java-9-openjdk-amd64/include -I/usr/lib/jvm/java-6-openjdk-i386/include -I/usr/lib/jvm/java-7-openjdk-i386/include -I/usr/lib/jvm/java-8-openjdk-i386/include -I/usr/lib/jvm/java-9-openjdk-i386/include "
|
||||||
|
fname = 'Tejas/src/emulator/pin/makefile_linux_mac'
|
||||||
|
|
||||||
|
print 'setting PINPATH in ' + fname + " to " + pin_path
|
||||||
|
f = open(fname, 'r')
|
||||||
|
lines = f.readlines()
|
||||||
|
i = 0
|
||||||
|
for line in lines:
|
||||||
|
if "PIN_KIT ?=" in line:
|
||||||
|
lines[i] = "PIN_KIT ?=" + pin_path + "\n"
|
||||||
|
if "JNINCLUDE =" in line:
|
||||||
|
lines[i] = "JNINCLUDE =" + jniInclude + "\n"
|
||||||
|
i = i + 1
|
||||||
|
f.close()
|
||||||
|
f = open(fname, 'w')
|
||||||
|
for line in lines:
|
||||||
|
f.write(line)
|
||||||
|
f.close()
|
||||||
|
|
||||||
|
#update config.xml
|
||||||
|
fname = 'Tejas/src/simulator/config/config.xml'
|
||||||
|
tree = ET.parse(fname)
|
||||||
|
root = tree.getroot()
|
||||||
|
emulator = root.find('Emulator')
|
||||||
|
if platform == "win32":
|
||||||
|
print 'setting PinTool in ' + fname + ' to ' + pin_path
|
||||||
|
emulator.find('PinTool').text = pin_path
|
||||||
|
print 'setting PinInstrumentor in ' + fname + ' to ' + pwd + '\Tejas\src\emulator\pin\obj-pin\causalityTool.dll'
|
||||||
|
emulator.find('PinInstrumentor').text = pwd + "\Tejas\src\emulator\pin\obj-pin\causalityTool.dll"
|
||||||
|
print 'setting ShmLibDirectory in ' + fname + ' to ' + pwd + '\Tejas\src\emulator\pin\obj-comm'
|
||||||
|
emulator.find('ShmLibDirectory').text = pwd + "\Tejas\src\emulator\pin\obj-comm"
|
||||||
|
print 'setting KillEmulatorScript in ' + fname + ' to ' + pwd + '\Tejas\src\simulator\main\killAllDescendents.bat'
|
||||||
|
emulator.find('KillEmulatorScript').text = pwd + "\Tejas\src\simulator\main\killAllDescendents.bat"
|
||||||
|
else:
|
||||||
|
#if platform == "linux" or platform == "linux2":
|
||||||
|
print 'setting PinTool in ' + fname + ' to ' + pin_path
|
||||||
|
emulator.find('PinTool').text = pin_path
|
||||||
|
print 'setting PinInstrumentor in ' + fname + ' to ' + pwd + '/Tejas/src/emulator/pin/obj-pin/causalityTool.so'
|
||||||
|
emulator.find('PinInstrumentor').text = pwd + "/Tejas/src/emulator/pin/obj-pin/causalityTool.so"
|
||||||
|
print 'setting ShmLibDirectory in ' + fname + ' to ' + pwd + '/Tejas/src/emulator/pin/obj-comm'
|
||||||
|
emulator.find('ShmLibDirectory').text = pwd + "/Tejas/src/emulator/pin/obj-comm"
|
||||||
|
print 'setting KillEmulatorScript in ' + fname + ' to ' + pwd + '/Tejas/src/simulator/main/killAllDescendents.sh'
|
||||||
|
emulator.find('KillEmulatorScript').text = pwd + "/Tejas/src/simulator/main/killAllDescendents.sh"
|
||||||
|
|
||||||
|
system = root.find('System')
|
||||||
|
noc = system.find('NOC')
|
||||||
|
print 'setting NocConfigFile in ' + fname + ' to ' + pwd + '/Tejas/src/simulator/config/NocConfig.txt'
|
||||||
|
noc.find('NocConfigFile').text = pwd + '/Tejas/src/simulator/config/NocConfig.txt'
|
||||||
|
|
||||||
|
|
||||||
|
#Change NOC config path
|
||||||
|
#l2=root.find('L2')
|
||||||
|
#print 'setting NocConfigFile in ' + fname + ' to ' + pwd + '/Tejas/src/simulator/config/NocConfig.txt'
|
||||||
|
#l2.find('NocConfigFile').text = pwd + "/Tejas/src/simulator/config/NocConfig.txt"
|
||||||
|
|
||||||
|
if sys.version_info < (2, 7):
|
||||||
|
tree.write(fname, encoding="UTF-8")
|
||||||
|
else:
|
||||||
|
tree.write(fname, encoding="UTF-8", xml_declaration=True)
|
||||||
|
|
||||||
|
print "configure successful"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#building
|
||||||
|
print '\n\nStep 4 : Building'
|
||||||
|
os.chdir('Tejas')
|
||||||
|
if platform == "win32":
|
||||||
|
pwd = os.getcwd();
|
||||||
|
print "pwd is " + pwd
|
||||||
|
status = call("ant make-jar",shell=True)
|
||||||
|
if status != 0 or os.path.exists(pwd + "/src/emulator/pin/obj-pin/causalityTool.dll") == False or os.path.exists(pwd + "/src/emulator/pin/obj-comm/libshmlib.dll") == False:
|
||||||
|
print "error building : "
|
||||||
|
sys.exit(1)
|
||||||
|
else:
|
||||||
|
print "build successful"
|
||||||
|
else:
|
||||||
|
#if platform == "linux" or platform == "linux2":
|
||||||
|
pwd = commands.getoutput('pwd')
|
||||||
|
print "pwd is " + pwd
|
||||||
|
status, output = commands.getstatusoutput("ant make-jar")
|
||||||
|
if status != 0 or os.path.exists(pwd + "/src/emulator/pin/obj-pin/causalityTool.so") == False or os.path.exists(pwd + "/src/emulator/pin/obj-comm/libshmlib.so") == False:
|
||||||
|
print "error building : " + str(os.WEXITSTATUS(status))
|
||||||
|
print output
|
||||||
|
sys.exit(1)
|
||||||
|
else:
|
||||||
|
print "build successful"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#test-run : hello world
|
||||||
|
if platform == "win32":
|
||||||
|
print '\n\nStep 5 : Test Run - Hello World'
|
||||||
|
os.chdir('..')
|
||||||
|
pwd=os.getcwd();
|
||||||
|
|
||||||
|
if os.path.exists(pwd + '/outputs')==False:
|
||||||
|
os.mkdir('outputs')
|
||||||
|
if os.path.exists(pwd + '/tests')==False:
|
||||||
|
os.mkdir('tests')
|
||||||
|
if os.path.exists(pwd + '/tests/hello_world.cpp')==False:
|
||||||
|
f = open(pwd + '/tests/hello_world.cpp', 'w')
|
||||||
|
f.write("#include<iostream>\nint main() {\nstd::cout<<\"hello world\"<<std::endl;\nreturn (0);\n}\n")
|
||||||
|
f.close()
|
||||||
|
|
||||||
|
cmd = "cl " + pwd + "/tests/hello_world.cpp "
|
||||||
|
os.chdir("tests");
|
||||||
|
print cmd
|
||||||
|
status = call(cmd,shell=True)
|
||||||
|
if status != 0 or os.path.exists(pwd + "/tests/hello_world.exe") == False:
|
||||||
|
print "error compiling test file "
|
||||||
|
sys.exit(1)
|
||||||
|
os.chdir('..')
|
||||||
|
cmd = "java -jar Tejas/jars/tejas.jar Tejas/src/simulator/config/config.xml outputs/hello_world.output tests/hello_world.exe"
|
||||||
|
print cmd
|
||||||
|
status = os.system(cmd)
|
||||||
|
|
||||||
|
|
||||||
|
if status != 0 or os.path.exists(pwd + "/outputs/hello_world.output") == False:
|
||||||
|
print "error running test "
|
||||||
|
sys.exit(1)
|
||||||
|
else:
|
||||||
|
#if platform == "linux" or platform == "linux2":
|
||||||
|
print '\n\nStep 5 : Test Run - Hello World'
|
||||||
|
os.chdir('..')
|
||||||
|
pwd=commands.getoutput('pwd')
|
||||||
|
|
||||||
|
if os.path.exists(pwd + '/outputs')==False:
|
||||||
|
os.mkdir('outputs')
|
||||||
|
if os.path.exists(pwd + '/tests')==False:
|
||||||
|
os.mkdir('tests')
|
||||||
|
if os.path.exists(pwd + '/tests/hello_world.cpp')==False:
|
||||||
|
f = open(pwd + '/tests/hello_world.cpp', 'w')
|
||||||
|
f.write("#include<iostream>\nint main() {\nstd::cout<<\"hello world\"<<std::endl;\nreturn (0);\n}\n")
|
||||||
|
f.close()
|
||||||
|
|
||||||
|
cmd = "g++ " + pwd + "/tests/hello_world.cpp -o " + pwd + "/tests/hello_world.o"
|
||||||
|
print cmd
|
||||||
|
status, output = commands.getstatusoutput(cmd)
|
||||||
|
if status != 0 or os.path.exists(pwd + "/tests/hello_world.o") == False:
|
||||||
|
print "error compiling test file : " + str(os.WEXITSTATUS(status))
|
||||||
|
print output
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
cmd = "java -jar " + pwd + "/Tejas/jars/tejas.jar " + pwd + "/Tejas/src/simulator/config/config.xml " + pwd + "/outputs/hello_world.output " + pwd + "/tests/hello_world.o"
|
||||||
|
print cmd
|
||||||
|
status = os.system(cmd)
|
||||||
|
|
||||||
|
|
||||||
|
if status != 0 or os.path.exists(pwd + "/outputs/hello_world.output") == False:
|
||||||
|
print "error running test : " + str(os.WEXITSTATUS(status))
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
|
||||||
|
print "Helloworld test completed \n\n\n"
|
||||||
|
print "------------- Tejas installed successfuly ----------------\n"
|
||||||
|
print "Tejas jar has been created here : " + pwd + "/Tejas/jars/tejas.jar"
|
||||||
|
print "Configuration file is kept here : " + pwd + "/Tejas/src/simulator/config/config.xml"
|
||||||
|
print "Use this command to run tejas : java -jar <tejas.jar> <config-file> <output-file> <input-program and arguments>"
|
|
@ -0,0 +1,82 @@
|
||||||
|
#Parallel Benchmark Suite. Contains parsec, splash, parboil, custom-benchmarks
|
||||||
|
|
||||||
|
if [ "$#" -ne 4 ]; then
|
||||||
|
echo "Illegal parameters"
|
||||||
|
echo "Usage bash parallel_bm.sh jarfile configfile statsdir outputsdir"
|
||||||
|
exit
|
||||||
|
fi
|
||||||
|
|
||||||
|
jarfile=$1
|
||||||
|
configfile=$2
|
||||||
|
statsdir=$3
|
||||||
|
outputsdir=$4
|
||||||
|
|
||||||
|
parsecdir="/mnt/srishtistr0/home/eldhose/PARSEC/parsec-2.1-core"
|
||||||
|
splash2dir="/local_scratch/mayur/jitter-code/splash2"
|
||||||
|
parboildir="/mnt/srishtistr0/home/eldhose/parboil"
|
||||||
|
custombmdir=
|
||||||
|
|
||||||
|
echo "Please don't use forward slash at the end of directory path"
|
||||||
|
|
||||||
|
echo "processing fmm"
|
||||||
|
java -Xmx1g -jar $jarfile $configfile $statsdir/fmm $splash2dir/codes/apps/fmm/FMM > $outputsdir/fmm 2>&1
|
||||||
|
|
||||||
|
echo "processing fft"
|
||||||
|
java -Xmx1g -jar $jarfile $configfile $statsdir/fft $splash2dir/codes/kernels/fft/FFT -p32 -m24 > $outputsdir/fft 2>&1
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
echo "processing lu_contiguous"
|
||||||
|
java -Xmx1g -jar $jarfile $configfile $statsdir/lu_contiguous $splash2dir/codes/kernels/lu/contiguous_blocks/LU -n4096 -p32 -b8 > $outputsdir/lu_contiguous 2>&1
|
||||||
|
|
||||||
|
|
||||||
|
echo "processing radiosity"
|
||||||
|
java -Xmx1g -jar $jarfile $configfile $statsdir/radiosity $splash2dir/codes/apps/radiosity/RADIOSITY -p 32 -batch -largeroom > $outputsdir/radiosity 2>&1
|
||||||
|
|
||||||
|
|
||||||
|
echo "processing blackscholes"
|
||||||
|
java -Xmx1g -jar $jarfile $configfile $statsdir/blackscholes $parsecdir/pkgs/apps/blackscholes/inst/amd64-linux.gcc-hooks/bin/blackscholes 32 $parsecdir/pkgs/apps/blackscholes/run/in_64K.txt /mnt/srishtistr0/home/eldhose/parsec-2.1-core/pkgs/apps/blackscholes/run/prices.txt > $outputsdir/blackscholes 2>&1
|
||||||
|
|
||||||
|
|
||||||
|
echo "processing fluidanimate"
|
||||||
|
java -Xmx1g -jar $jarfile $configfile $statsdir/fluid $parsecdir/pkgs/apps/fluidanimate/inst/amd64-linux.gcc-hooks/bin/fluidanimate 32 5 $parsecdir/pkgs/apps/fluidanimate/run/in_300K.fluid $parsecdir/pkgs/apps/fluidanimate/run/out.fluid > $outputsdir/fluidanimate 2>&1
|
||||||
|
|
||||||
|
|
||||||
|
echo "processing swaptions"
|
||||||
|
java -Xmx1g -jar $jarfile $configfile $statsdir/swaptions $parsecdir/pkgs/apps/swaptions/inst/amd64-linux.gcc-hooks/bin/swaptions -ns 64 -sm 20000 -nt 32 > $outputsdir/swaptions 2>&1
|
||||||
|
|
||||||
|
|
||||||
|
echo "processing streamcluster"
|
||||||
|
java -Xmx1g -jar $jarfile $configfile $statsdir/stream $parsecdir/pkgs/kernels/streamcluster/inst/amd64-linux.gcc-hooks/bin/streamcluster 10 20 128 16384 16384 1000 none $parsecdir/pkgs/kernels/streamcluster/run/output.txt 32 > $outputsdir/streamcluster 2>&1
|
||||||
|
|
||||||
|
|
||||||
|
echo "processing bodytrack"
|
||||||
|
#java -Xmx1g -jar $jarfile $configfile $statsdir/bodytrack $parsecdir/pkgs/apps/bodytrack/inst/amd64-linux.gcc-hooks/bin/bodytrack $parsecdir/pkgs/apps/bodytrack/run/sequenceB_4 4 4 4000 5 0 32 > $outputsdir/bodytrack 2>&1
|
||||||
|
|
||||||
|
|
||||||
|
echo "processing freqmine"
|
||||||
|
#java -Xmx1g -jar $jarfile $configfile $statsdir/freqmine $parsecdir/pkgs/apps/freqmine/inst/amd64-linux.gcc-hooks/bin/freqmine $parsecdir/pkgs/apps/freqmine/run/kosarak_250k.dat 790freqmine > $outputsdir/freqmine 2>&1
|
||||||
|
|
||||||
|
|
||||||
|
echo "processing vips"
|
||||||
|
#java -Xmx1g -jar $jarfile $configfile $statsdir/vips $parsecdir/pkgs/apps/vips/inst/amd64-linux.gcc-hooks/bin/vips im_benchmark $parsecdir/pkgs/apps/vips/run/bigben_2662x5500.v $parsecdir/pkgs/apps/vips/run/output.v > $outputsdir/vips 2>&1
|
||||||
|
|
||||||
|
|
||||||
|
echo "processing histo"
|
||||||
|
java -Xmx1g -jar $jarfile $configfile $statsdir/histo $parboildir/benchmarks/histo/build/omp_base_default/histo -i $parboildir/datasets/histo/default/input/img.bin -o $parboildir/benchmarks/histo/run/default/ref.bmp -- 20 4 > $outputsdir/histo 2>&1
|
||||||
|
|
||||||
|
|
||||||
|
echo "processing stencil"
|
||||||
|
java -Xmx1g -jar $jarfile $configfile $statsdir/stencil $parboildir/benchmarks/stencil/build/omp_base_default/stencil -i $parboildir/datasets/stencil/small/input/128x128x32.bin -o $parboildir/benchmarks/stencil/run/small/128x128x32.out -- 128 128 32 100 > $outputsdir/stencil 2>&1
|
||||||
|
|
||||||
|
|
||||||
|
echo "processing radix"
|
||||||
|
#java -Xmx1g -jar $jarfile $configfile $statsdir/radix $splash2dir/codes/kernels/radix/RADIX -p32 -n7666996 -r4 -m524288 > $outputsdir/radix 2>&1
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#echo "processing "
|
||||||
|
#java -Xmx1g -jar $jarfile > $outputsdir/ 2>&1
|
||||||
|
|
||||||
|
|
||||||
|
echo "OVER!!!"
|
|
@ -0,0 +1,78 @@
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
echo "Script for running Tejas dram benchmarks!"
|
||||||
|
|
||||||
|
#read arguments
|
||||||
|
|
||||||
|
if [ "$1" == "" ]; then
|
||||||
|
echo "Usage: run_tejasdram -r rank -b bank -policy Open/Close -bench benchmark"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
while [ "$1" != "" ]; do
|
||||||
|
case $1 in
|
||||||
|
-c | --chan ) shift
|
||||||
|
chan=$1
|
||||||
|
;;
|
||||||
|
-r | --rank ) shift
|
||||||
|
rank=$1
|
||||||
|
;;
|
||||||
|
-b | --bank ) shift
|
||||||
|
bank=$1
|
||||||
|
;;
|
||||||
|
-policy ) shift
|
||||||
|
rowbuff=$1
|
||||||
|
;;
|
||||||
|
-bench ) shift
|
||||||
|
bench=$1
|
||||||
|
;;
|
||||||
|
* ) echo "Usage: script -r rank -b bank -policy Open/Close -bench benchmark"
|
||||||
|
exit 1
|
||||||
|
esac
|
||||||
|
shift
|
||||||
|
done
|
||||||
|
|
||||||
|
|
||||||
|
#rank=1
|
||||||
|
#bank=8
|
||||||
|
#rowbuff="Open"
|
||||||
|
#bench="429.mcf"
|
||||||
|
bench_name=`echo $bench | sed 's/.*\.//g' `
|
||||||
|
echo "Running bench : "$bench"_50M/$bench_name"
|
||||||
|
|
||||||
|
sed -i "s/<rowBufferPolicy>.*Page<\/rowBufferPolicy>/<rowBufferPolicy>"$rowbuff"Page<\/rowBufferPolicy>/g" ../src/simulator/config/config.xml
|
||||||
|
sed -i "s/<numChans>[0-9]*<\/numChans>/<numChans>"$chan"<\/numChans>/g" ../src/simulator/config/config.xml
|
||||||
|
sed -i "s/<numRanks>[0-9]*<\/numRanks>/<numRanks>"$rank"<\/numRanks>/g" ../src/simulator/config/config.xml
|
||||||
|
sed -i "s/<numBanks>[0-9]*<\/numBanks>/<numBanks>"$bank"<\/numBanks>/g" ../src/simulator/config/config.xml
|
||||||
|
|
||||||
|
#sed -i "s/\/mnt\/srishtistr0\/home\/harveen\/benchmarks\/dram_traces\/k6_.*.trc/\/mnt\/srishtistr0\/home\/harveen\/benchmarks\/dram_traces\/k6_"$bench"_"$rank"R_"$bank"B_"$rowbuff".trc/g" /mnt/srishtistr0/home/harveen/Tejas-RAM-try/Tejas-dram/../src/simulator/main/Main.java
|
||||||
|
|
||||||
|
#sed -i "s/\/mnt\/srishtistr0\/home\/harveen\/benchmarks\/timing\/.*.timing/\/mnt\/srishtistr0\/home\/harveen\/benchmarks\/timing\/"$bench"_"$rank"R_"$bank"B_"$rowbuff".timing/g" /mnt/srishtistr0/home/harveen/Tejas-RAM-try/Tejas-dram/../src/simulator/main/Main.java
|
||||||
|
|
||||||
|
#echo "Compiling!!"
|
||||||
|
|
||||||
|
#ant make-jar
|
||||||
|
|
||||||
|
echo -n "Running Tejas dram"
|
||||||
|
|
||||||
|
java -jar ../jars/tejas.jar ../src/simulator/config/config.xml /home/hk/Harveen/Work/DRAMSim/benchmarks/outputs/kips/tejas_dram/"$bench"_"$rank"R_"$bank"B_"$rowbuff".output /home/hk/Harveen/Work/DRAMSim/benchmarks/cpu2006/"$bench"_50M/"$bench_name"
|
||||||
|
|
||||||
|
#calculate average
|
||||||
|
|
||||||
|
#awk '{sum += ($2 - $1) ;n++} END {print sum/n,n}' /mnt/srishtistr0/home/harveen/benchmarks/timing/"$bench"_"$rank"R_"$bank"B_"$rowbuff".timing
|
||||||
|
|
||||||
|
#average_time=`awk '{sum += ($2 - $1) ;n++} END {print sum/n}' /mnt/srishtistr0/home/harveen/benchmarks/timing/"$bench"_"$rank"R_"$bank"B_"$rowbuff".timing`
|
||||||
|
|
||||||
|
#echo "Average is $average_time"
|
||||||
|
#rounded=`printf '%.*f' 0 $average_time`
|
||||||
|
#echo "Rounded to $rounded"
|
||||||
|
#latency=`expr $rounded + 20`;
|
||||||
|
|
||||||
|
#sed -i "s/<MainMemoryLatency>[0-9]*<\/MainMemoryLatency>/<MainMemoryLatency>"$latency"<\/MainMemoryLatency>/g" ~/Harveen/Work/DRAMSim/repo/Tejas-Simulator/Tejas/../src/simulator/config/config.xml
|
||||||
|
|
||||||
|
#cd /mnt/srishtistr0/home/harveen/repo/Tejas-Simulator/Tejas
|
||||||
|
|
||||||
|
echo "Running Tejas Sim"
|
||||||
|
|
||||||
|
java -jar /home/hk/Harveen/Work/DRAMSim/repo/Tejas-Simulator/Tejas/jars/tejas.jar /home/hk/Harveen/Work/DRAMSim/repo/Tejas-Simulator/Tejas/src/simulator/config/config.xml /home/hk/Harveen/Work/DRAMSim/benchmarks/outputs/kips/tejas_sim/"$bench"_"$rank"R_"$bank"B_"$rowbuff".output /home/hk/Harveen/Work/DRAMSim/benchmarks/cpu2006/"$bench"_50M/"$bench_name"
|
||||||
|
|
|
@ -0,0 +1,311 @@
|
||||||
|
|
||||||
|
from sys import platform
|
||||||
|
import commands
|
||||||
|
import xml.etree.ElementTree as ET
|
||||||
|
import os, sys
|
||||||
|
import shutil
|
||||||
|
|
||||||
|
if platform == "win32":
|
||||||
|
from subprocess import check_output,call
|
||||||
|
pwd = os.getcwd(); ###change
|
||||||
|
#elif platform == "linux" or platform == "linux2":
|
||||||
|
else:
|
||||||
|
pwd = commands.getoutput('pwd')
|
||||||
|
#print "\npwd is " + pwd
|
||||||
|
if os.path.exists(pwd + "/Tejas-Simulator") == False:
|
||||||
|
os.mkdir(pwd + "/Tejas-Simulator")
|
||||||
|
os.chdir(pwd + "/Tejas-Simulator")
|
||||||
|
pwd = pwd + "/Tejas-Simulator"
|
||||||
|
|
||||||
|
#print dependencies
|
||||||
|
print "\nInstallation Dependencies :"
|
||||||
|
print "\t1) Mercurial"
|
||||||
|
print "\t2) Java (tested for 1.6 and 1.7)"
|
||||||
|
print "\t3) ant"
|
||||||
|
print "\t4) Intel Pin tar-ball"
|
||||||
|
|
||||||
|
installation_option=raw_input("\n\nPress enter to continue. ")
|
||||||
|
|
||||||
|
# Install from tar-ball or repository
|
||||||
|
print "\n\nStep 1 : cloning Tejas source"
|
||||||
|
print "\n\nTejas Installation Option : "
|
||||||
|
print "\t1) to install Tejas from the tar-ball in installation kit"
|
||||||
|
print "\t2) to install Tejas from the repository (Latest version)"
|
||||||
|
installation_option=raw_input("\n\nenter option : ")
|
||||||
|
|
||||||
|
if installation_option=="1":
|
||||||
|
tejas_tar_ball=raw_input("\n\nenter path of tejas tar-ball : ")
|
||||||
|
|
||||||
|
if platform == "win32":
|
||||||
|
cmd="tar -xvf "+tejas_tar_ball+" --force-local"
|
||||||
|
status = call(cmd,shell=True)
|
||||||
|
#else platform == "linux" or platform == "linux2":
|
||||||
|
else:
|
||||||
|
status = os.system("tar -xvf " + tejas_tar_ball)
|
||||||
|
if status!=0:
|
||||||
|
print "error in extracting tejas : " + + str(os.WEXITSTATUS(status))
|
||||||
|
print '\n'
|
||||||
|
sys.exit(1)
|
||||||
|
else:
|
||||||
|
print "extracted tejas successfully"
|
||||||
|
|
||||||
|
elif installation_option=="2":
|
||||||
|
if platform == "linux" or platform == "linux2":
|
||||||
|
print "\n\n\tEnter guest as username and guest1 as password on prompt"
|
||||||
|
|
||||||
|
#clone tejas
|
||||||
|
url = "http://www.cse.iitd.ac.in/srishtihg/hg/distrib/Tejas"
|
||||||
|
if os.path.exists(pwd + '/Tejas'):
|
||||||
|
print "Tejas source already cloned"
|
||||||
|
else:
|
||||||
|
print 'getting source please wait'
|
||||||
|
status = os.system("hg clone " + url)
|
||||||
|
#status, output = commands.getstatusoutput("hg clone " + url)
|
||||||
|
if status != 0:
|
||||||
|
print "error cloning : " + str(os.WEXITSTATUS(status))
|
||||||
|
#print output
|
||||||
|
print '\n'
|
||||||
|
sys.exit(1)
|
||||||
|
else:
|
||||||
|
print "cloning successful"
|
||||||
|
|
||||||
|
else:
|
||||||
|
print "Invalid option for installation : " + installation_option
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
|
||||||
|
#PIN
|
||||||
|
print "\n\nStep 2 : setting up Pin"
|
||||||
|
pin_path = ""
|
||||||
|
|
||||||
|
#download PIN
|
||||||
|
if platform == "win32":
|
||||||
|
#download PIN
|
||||||
|
print "Download version 71313-msvc11-windows from Intel's website : http://software.intel.com/en-us/articles/pintool-downloads"
|
||||||
|
print "Please read the license before downloading : http://software.intel.com/sites/landingpage/pintool/extlicense.txt"
|
||||||
|
print "NOTE : This installation script requires Pin in the form of zip file"
|
||||||
|
|
||||||
|
pin_tar_path = raw_input("\n\nenter absolute path of the Pin zip: ")
|
||||||
|
if os.path.exists(pin_tar_path) == False:
|
||||||
|
print "Pin not provided.. Exiting."
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
#extract PIN
|
||||||
|
print "extracting PIN"
|
||||||
|
if os.path.exists(pwd + "/PIN"):
|
||||||
|
shutil.rmtree(pwd + "/PIN")
|
||||||
|
os.mkdir(pwd + "/PIN")
|
||||||
|
os.chdir(pwd + "/PIN")
|
||||||
|
status = call("jar xf " + pin_tar_path,shell=True)
|
||||||
|
if status != 0:
|
||||||
|
print "error extracting Pin"
|
||||||
|
print output
|
||||||
|
sys.exit(1)
|
||||||
|
filenames = os.listdir(pwd + "/PIN")
|
||||||
|
pin_path = pwd + "/PIN/" + filenames[0]
|
||||||
|
os.chdir(pwd)
|
||||||
|
|
||||||
|
else:
|
||||||
|
#if platform == "linux" or platform == "linux2":
|
||||||
|
#download PIN
|
||||||
|
print "Download version 62732 from Intel's website : http://software.intel.com/en-us/articles/pintool-downloads"
|
||||||
|
print "Please read the license before downloading : http://software.intel.com/sites/landingpage/pintool/extlicense.txt"
|
||||||
|
print "NOTE : This installation script requires Pin in the form of a tar-ball"
|
||||||
|
|
||||||
|
pin_tar_path = raw_input("\n\nenter absolute path of the Pin tar-ball (only tar.gz format) : ")
|
||||||
|
if os.path.exists(pin_tar_path) == False:
|
||||||
|
print "Pin not provided.. Exiting."
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
|
||||||
|
#extract PIN
|
||||||
|
print "extracting PIN"
|
||||||
|
if os.path.exists(pwd + "/PIN"):
|
||||||
|
shutil.rmtree(pwd + "/PIN")
|
||||||
|
os.mkdir(pwd + "/PIN")
|
||||||
|
os.chdir(pwd + "/PIN")
|
||||||
|
status, output = commands.getstatusoutput("tar -xvf " + pin_tar_path)
|
||||||
|
if status != 0:
|
||||||
|
print "error extracting Pin : " + str(os.WEXITSTATUS(status))
|
||||||
|
print output
|
||||||
|
sys.exit(1)
|
||||||
|
filenames = os.listdir(pwd + "/PIN")
|
||||||
|
pin_path = pwd + "/PIN/" + filenames[0]
|
||||||
|
os.chdir(pwd)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#configuring
|
||||||
|
print '\n\nStep 3 : Configuring'
|
||||||
|
|
||||||
|
jniInclude=""
|
||||||
|
fname=""
|
||||||
|
if platform == "win32":
|
||||||
|
jniInclude = "-I\"" + os.getenv('JAVA_HOME') + "\\include\" " + "-I\"" + os.getenv('JAVA_HOME') + "\\include\\win32\""
|
||||||
|
fname = 'Tejas/src/emulator/pin/makefile_windows'
|
||||||
|
else:
|
||||||
|
if platform == "darwin":
|
||||||
|
jniInclude = "-I/System/Library/Frameworks/JavaVM.framework/Versions/Current/Headers"
|
||||||
|
else:
|
||||||
|
jniInclude = "-I/usr/lib/jvm/java-6-openjdk-amd64/include -I/usr/lib/jvm/java-7-openjdk-amd64/include -I/usr/lib/jvm/java-8-openjdk-amd64/include -I/usr/lib/jvm/java-9-openjdk-amd64/include -I/usr/lib/jvm/java-6-openjdk-i386/include -I/usr/lib/jvm/java-7-openjdk-i386/include -I/usr/lib/jvm/java-8-openjdk-i386/include -I/usr/lib/jvm/java-9-openjdk-i386/include "
|
||||||
|
fname = 'Tejas/src/emulator/pin/makefile_linux_mac'
|
||||||
|
|
||||||
|
print 'setting PINPATH in ' + fname + " to " + pin_path
|
||||||
|
f = open(fname, 'r')
|
||||||
|
lines = f.readlines()
|
||||||
|
i = 0
|
||||||
|
for line in lines:
|
||||||
|
if "PIN_KIT ?=" in line:
|
||||||
|
lines[i] = "PIN_KIT ?=" + pin_path + "\n"
|
||||||
|
if "JNINCLUDE =" in line:
|
||||||
|
lines[i] = "JNINCLUDE =" + jniInclude + "\n"
|
||||||
|
i = i + 1
|
||||||
|
f.close()
|
||||||
|
f = open(fname, 'w')
|
||||||
|
for line in lines:
|
||||||
|
f.write(line)
|
||||||
|
f.close()
|
||||||
|
|
||||||
|
#update config.xml
|
||||||
|
fname = 'Tejas/src/simulator/config/config.xml'
|
||||||
|
tree = ET.parse(fname)
|
||||||
|
root = tree.getroot()
|
||||||
|
emulator = root.find('Emulator')
|
||||||
|
if platform == "win32":
|
||||||
|
print 'setting PinTool in ' + fname + ' to ' + pin_path
|
||||||
|
emulator.find('PinTool').text = pin_path
|
||||||
|
print 'setting PinInstrumentor in ' + fname + ' to ' + pwd + '\Tejas\src\emulator\pin\obj-pin\causalityTool.dll'
|
||||||
|
emulator.find('PinInstrumentor').text = pwd + "\Tejas\src\emulator\pin\obj-pin\causalityTool.dll"
|
||||||
|
print 'setting ShmLibDirectory in ' + fname + ' to ' + pwd + '\Tejas\src\emulator\pin\obj-comm'
|
||||||
|
emulator.find('ShmLibDirectory').text = pwd + "\Tejas\src\emulator\pin\obj-comm"
|
||||||
|
print 'setting KillEmulatorScript in ' + fname + ' to ' + pwd + '\Tejas\src\simulator\main\killAllDescendents.bat'
|
||||||
|
emulator.find('KillEmulatorScript').text = pwd + "\Tejas\src\simulator\main\killAllDescendents.bat"
|
||||||
|
else:
|
||||||
|
#if platform == "linux" or platform == "linux2":
|
||||||
|
print 'setting PinTool in ' + fname + ' to ' + pin_path
|
||||||
|
emulator.find('PinTool').text = pin_path
|
||||||
|
print 'setting PinInstrumentor in ' + fname + ' to ' + pwd + '/Tejas/src/emulator/pin/obj-pin/causalityTool.so'
|
||||||
|
emulator.find('PinInstrumentor').text = pwd + "/Tejas/src/emulator/pin/obj-pin/causalityTool.so"
|
||||||
|
print 'setting ShmLibDirectory in ' + fname + ' to ' + pwd + '/Tejas/src/emulator/pin/obj-comm'
|
||||||
|
emulator.find('ShmLibDirectory').text = pwd + "/Tejas/src/emulator/pin/obj-comm"
|
||||||
|
print 'setting KillEmulatorScript in ' + fname + ' to ' + pwd + '/Tejas/src/simulator/main/killAllDescendents.sh'
|
||||||
|
emulator.find('KillEmulatorScript').text = pwd + "/Tejas/src/simulator/main/killAllDescendents.sh"
|
||||||
|
|
||||||
|
system = root.find('System')
|
||||||
|
noc = system.find('NOC')
|
||||||
|
print 'setting NocConfigFile in ' + fname + ' to ' + pwd + '/Tejas/src/simulator/config/NocConfig.txt'
|
||||||
|
noc.find('NocConfigFile').text = pwd + '/Tejas/src/simulator/config/NocConfig.txt'
|
||||||
|
|
||||||
|
|
||||||
|
#Change NOC config path
|
||||||
|
#l2=root.find('L2')
|
||||||
|
#print 'setting NocConfigFile in ' + fname + ' to ' + pwd + '/Tejas/src/simulator/config/NocConfig.txt'
|
||||||
|
#l2.find('NocConfigFile').text = pwd + "/Tejas/src/simulator/config/NocConfig.txt"
|
||||||
|
|
||||||
|
if sys.version_info < (2, 7):
|
||||||
|
tree.write(fname, encoding="UTF-8")
|
||||||
|
else:
|
||||||
|
tree.write(fname, encoding="UTF-8", xml_declaration=True)
|
||||||
|
|
||||||
|
print "configure successful"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#building
|
||||||
|
print '\n\nStep 4 : Building'
|
||||||
|
os.chdir('Tejas')
|
||||||
|
if platform == "win32":
|
||||||
|
pwd = os.getcwd();
|
||||||
|
print "pwd is " + pwd
|
||||||
|
status = call("ant make-jar",shell=True)
|
||||||
|
if status != 0 or os.path.exists(pwd + "/src/emulator/pin/obj-pin/causalityTool.dll") == False or os.path.exists(pwd + "/src/emulator/pin/obj-comm/libshmlib.dll") == False:
|
||||||
|
print "error building : "
|
||||||
|
sys.exit(1)
|
||||||
|
else:
|
||||||
|
print "build successful"
|
||||||
|
else:
|
||||||
|
#if platform == "linux" or platform == "linux2":
|
||||||
|
pwd = commands.getoutput('pwd')
|
||||||
|
print "pwd is " + pwd
|
||||||
|
status, output = commands.getstatusoutput("ant make-jar")
|
||||||
|
if status != 0 or os.path.exists(pwd + "/src/emulator/pin/obj-pin/causalityTool.so") == False or os.path.exists(pwd + "/src/emulator/pin/obj-comm/libshmlib.so") == False:
|
||||||
|
print "error building : " + str(os.WEXITSTATUS(status))
|
||||||
|
print output
|
||||||
|
sys.exit(1)
|
||||||
|
else:
|
||||||
|
print "build successful"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#test-run : hello world
|
||||||
|
if platform == "win32":
|
||||||
|
print '\n\nStep 5 : Test Run - Hello World'
|
||||||
|
os.chdir('..')
|
||||||
|
pwd=os.getcwd();
|
||||||
|
|
||||||
|
if os.path.exists(pwd + '/outputs')==False:
|
||||||
|
os.mkdir('outputs')
|
||||||
|
if os.path.exists(pwd + '/tests')==False:
|
||||||
|
os.mkdir('tests')
|
||||||
|
if os.path.exists(pwd + '/tests/hello_world.cpp')==False:
|
||||||
|
f = open(pwd + '/tests/hello_world.cpp', 'w')
|
||||||
|
f.write("#include<iostream>\nint main() {\nstd::cout<<\"hello world\"<<std::endl;\nreturn (0);\n}\n")
|
||||||
|
f.close()
|
||||||
|
|
||||||
|
cmd = "cl " + pwd + "/tests/hello_world.cpp "
|
||||||
|
os.chdir("tests");
|
||||||
|
print cmd
|
||||||
|
status = call(cmd,shell=True)
|
||||||
|
if status != 0 or os.path.exists(pwd + "/tests/hello_world.exe") == False:
|
||||||
|
print "error compiling test file "
|
||||||
|
sys.exit(1)
|
||||||
|
os.chdir('..')
|
||||||
|
cmd = "java -jar Tejas/jars/tejas.jar Tejas/src/simulator/config/config.xml outputs/hello_world.output tests/hello_world.exe"
|
||||||
|
print cmd
|
||||||
|
status = os.system(cmd)
|
||||||
|
|
||||||
|
|
||||||
|
if status != 0 or os.path.exists(pwd + "/outputs/hello_world.output") == False:
|
||||||
|
print "error running test "
|
||||||
|
sys.exit(1)
|
||||||
|
else:
|
||||||
|
#if platform == "linux" or platform == "linux2":
|
||||||
|
print '\n\nStep 5 : Test Run - Hello World'
|
||||||
|
os.chdir('..')
|
||||||
|
pwd=commands.getoutput('pwd')
|
||||||
|
|
||||||
|
if os.path.exists(pwd + '/outputs')==False:
|
||||||
|
os.mkdir('outputs')
|
||||||
|
if os.path.exists(pwd + '/tests')==False:
|
||||||
|
os.mkdir('tests')
|
||||||
|
if os.path.exists(pwd + '/tests/hello_world.cpp')==False:
|
||||||
|
f = open(pwd + '/tests/hello_world.cpp', 'w')
|
||||||
|
f.write("#include<iostream>\nint main() {\nstd::cout<<\"hello world\"<<std::endl;\nreturn (0);\n}\n")
|
||||||
|
f.close()
|
||||||
|
|
||||||
|
cmd = "g++ " + pwd + "/tests/hello_world.cpp -o " + pwd + "/tests/hello_world.o"
|
||||||
|
print cmd
|
||||||
|
status, output = commands.getstatusoutput(cmd)
|
||||||
|
if status != 0 or os.path.exists(pwd + "/tests/hello_world.o") == False:
|
||||||
|
print "error compiling test file : " + str(os.WEXITSTATUS(status))
|
||||||
|
print output
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
cmd = "java -jar " + pwd + "/Tejas/jars/tejas.jar " + pwd + "/Tejas/src/simulator/config/config.xml " + pwd + "/outputs/hello_world.output " + pwd + "/tests/hello_world.o"
|
||||||
|
print cmd
|
||||||
|
status = os.system(cmd)
|
||||||
|
|
||||||
|
|
||||||
|
if status != 0 or os.path.exists(pwd + "/outputs/hello_world.output") == False:
|
||||||
|
print "error running test : " + str(os.WEXITSTATUS(status))
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
|
||||||
|
print "Helloworld test completed \n\n\n"
|
||||||
|
print "------------- Tejas installed successfuly ----------------\n"
|
||||||
|
print "Tejas jar has been created here : " + pwd + "/Tejas/jars/tejas.jar"
|
||||||
|
print "Configuration file is kept here : " + pwd + "/Tejas/src/simulator/config/config.xml"
|
||||||
|
print "Use this command to run tejas : java -jar <tejas.jar> <config-file> <output-file> <input-program and arguments>"
|
|
@ -0,0 +1,46 @@
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
if [ "$#" -ne 6 ]; then
|
||||||
|
echo "Illegal parameters"
|
||||||
|
echo "Usage bash spec2006.sh script_status_file jarfile configfile statsdir outputsdir scriptdir"
|
||||||
|
exit
|
||||||
|
fi
|
||||||
|
|
||||||
|
rm $1
|
||||||
|
jarfile=$2
|
||||||
|
configfile=$3
|
||||||
|
statsdir=$4
|
||||||
|
outputsdir=$5
|
||||||
|
scriptdir=$6
|
||||||
|
|
||||||
|
echo "Please don't use forward slash at the end of directory path"
|
||||||
|
|
||||||
|
#bash "$scriptdir"spec2006_single.sh "perlbench" $jarfile $configfile $statsdir $outputsdir >> $1 2>&1
|
||||||
|
bash "$scriptdir"spec2006_single.sh "bzip2" $jarfile $configfile $statsdir $outputsdir >> $1 2>&1
|
||||||
|
bash "$scriptdir"spec2006_single.sh "gcc" $jarfile $configfile $statsdir $outputsdir >> $1 2>&1
|
||||||
|
bash "$scriptdir"spec2006_single.sh "bwaves" $jarfile $configfile $statsdir $outputsdir >> $1 2>&1
|
||||||
|
bash "$scriptdir"spec2006_single.sh "gamess" $jarfile $configfile $statsdir $outputsdir >> $1 2>&1
|
||||||
|
bash "$scriptdir"spec2006_single.sh "mcf" $jarfile $configfile $statsdir $outputsdir >> $1 2>&1
|
||||||
|
bash "$scriptdir"spec2006_single.sh "milc" $jarfile $configfile $statsdir $outputsdir >> $1 2>&1
|
||||||
|
bash "$scriptdir"spec2006_single.sh "zeusmp" $jarfile $configfile $statsdir $outputsdir >> $1 2>&1
|
||||||
|
bash "$scriptdir"spec2006_single.sh "gromacs" $jarfile $configfile $statsdir $outputsdir >> $1 2>&1
|
||||||
|
bash "$scriptdir"spec2006_single.sh "cactusADM" $jarfile $configfile $statsdir $outputsdir >> $1 2>&1
|
||||||
|
bash "$scriptdir"spec2006_single.sh "leslie3d" $jarfile $configfile $statsdir $outputsdir >> $1 2>&1
|
||||||
|
bash "$scriptdir"spec2006_single.sh "namd" $jarfile $configfile $statsdir $outputsdir >> $1 2>&1
|
||||||
|
bash "$scriptdir"spec2006_single.sh "gobmk" $jarfile $configfile $statsdir $outputsdir >> $1 2>&1
|
||||||
|
#bash "$scriptdir"spec2006_single.sh "dealII" $jarfile $configfile $statsdir $outputsdir >> $1 2>&1
|
||||||
|
bash "$scriptdir"spec2006_single.sh "soplex" $jarfile $configfile $statsdir $outputsdir >> $1 2>&1
|
||||||
|
bash "$scriptdir"spec2006_single.sh "povray" $jarfile $configfile $statsdir $outputsdir >> $1 2>&1
|
||||||
|
bash "$scriptdir"spec2006_single.sh "calculix" $jarfile $configfile $statsdir $outputsdir >> $1 2>&1
|
||||||
|
bash "$scriptdir"spec2006_single.sh "hmmer" $jarfile $configfile $statsdir $outputsdir >> $1 2>&1
|
||||||
|
bash "$scriptdir"spec2006_single.sh "sjeng" $jarfile $configfile $statsdir $outputsdir >> $1 2>&1
|
||||||
|
bash "$scriptdir"spec2006_single.sh "GemsFDTD" $jarfile $configfile $statsdir $outputsdir >> $1 2>&1
|
||||||
|
bash "$scriptdir"spec2006_single.sh "libquantum" $jarfile $configfile $statsdir $outputsdir >> $1 2>&1
|
||||||
|
bash "$scriptdir"spec2006_single.sh "h264ref" $jarfile $configfile $statsdir $outputsdir >> $1 2>&1
|
||||||
|
bash "$scriptdir"spec2006_single.sh "tonto" $jarfile $configfile $statsdir $outputsdir >> $1 2>&1
|
||||||
|
bash "$scriptdir"spec2006_single.sh "lbm" $jarfile $configfile $statsdir $outputsdir >> $1 2>&1
|
||||||
|
bash "$scriptdir"spec2006_single.sh "omnetpp" $jarfile $configfile $statsdir $outputsdir >> $1 2>&1
|
||||||
|
bash "$scriptdir"spec2006_single.sh "astar" $jarfile $configfile $statsdir $outputsdir >> $1 2>&1
|
||||||
|
bash "$scriptdir"spec2006_single.sh "wrf" $jarfile $configfile $statsdir $outputsdir >> $1 2>&1
|
||||||
|
bash "$scriptdir"spec2006_single.sh "sphinx3" $jarfile $configfile $statsdir $outputsdir >> $1 2>&1
|
||||||
|
bash "$scriptdir"spec2006_single.sh "xalancbmk" $jarfile $configfile $statsdir $outputsdir >> $1 2>&1
|
|
@ -0,0 +1,295 @@
|
||||||
|
#!/bin/bash
|
||||||
|
#usage bash spec2006_tejasBase_runBenchmark.sh <benchmark>
|
||||||
|
#export LD_LIBRARY_PATH="/mnt/srishtistr0/scratch/rajshekar/tejas/lib/"
|
||||||
|
|
||||||
|
if [ "$#" -ne 5 ]; then
|
||||||
|
echo "Illegal parameters"
|
||||||
|
echo "Usage bash spec2006.sh benchmark jarfile configfile statsdir outputsdir"
|
||||||
|
exit
|
||||||
|
fi
|
||||||
|
|
||||||
|
#jarfile="/mnt/srishtistr0/home/prathmesh/workspace/Tejas/jars/tejas.jar"
|
||||||
|
jarfile=$2
|
||||||
|
|
||||||
|
#configfile="/mnt/srishtistr0/home/prathmesh/workspace/Tejas/src/simulator/config/config.xml"
|
||||||
|
configfile=$3
|
||||||
|
|
||||||
|
#outputfiledir="/mnt/srishtistr0/home/prathmesh/scripts/stats"$2
|
||||||
|
outputfiledir=$4
|
||||||
|
outputfile=""
|
||||||
|
|
||||||
|
#stdoutfiledir="/mnt/srishtistr0/home/prathmesh/scripts/outputs"$2
|
||||||
|
stdoutfiledir=$5
|
||||||
|
stdoutfile=""
|
||||||
|
|
||||||
|
specpath="/mnt/srishtistr0/scratch/rajshekar/benchmarks/cpu2006/benchspec/CPU2006"
|
||||||
|
|
||||||
|
if [ $1 = perlbench ]
|
||||||
|
then
|
||||||
|
executable="$specpath/400.perlbench/run/run_base_test_amd64-m64-gcc43-nn.0000/perlbench_base.amd64-m64-gcc43-nn -I. -I./lib $specpath/400.perlbench/run/run_base_test_amd64-m64-gcc43-nn.0000/test.pl"
|
||||||
|
outputfile=$outputfiledir/"perlbench"
|
||||||
|
stdoutfile=$stdoutfiledir/"perlbench"
|
||||||
|
else
|
||||||
|
if [ $1 = "bzip2" ]
|
||||||
|
then
|
||||||
|
executable="$specpath/401.bzip2/run/run_base_test_amd64-m64-gcc43-nn.0000/bzip2_base.amd64-m64-gcc43-nn $specpath/401.bzip2/run/run_base_test_amd64-m64-gcc43-nn.0000/input.program 5"
|
||||||
|
#executable="$specpath/401.bzip2/run/run_base_ref_amd64-m64-gcc43-nn.0001/bzip2_base.amd64-m64-gcc43-nn $specpath/401.bzip2/run/run_base_ref_amd64-m64-gcc43-nn.0001/input.source 280"
|
||||||
|
outputfile=$outputfiledir/"bzip2"
|
||||||
|
stdoutfile=$stdoutfiledir/"bzip2"
|
||||||
|
else
|
||||||
|
if [ $1 = "gcc" ]
|
||||||
|
then
|
||||||
|
executable="$specpath/403.gcc/run/run_base_test_amd64-m64-gcc43-nn.0000/gcc_base.amd64-m64-gcc43-nn $specpath/403.gcc/run/run_base_test_amd64-m64-gcc43-nn.0000/cccp.i -o $specpath/403.gcc/run/run_base_test_amd64-m64-gcc43-nn.0000/cccp.s"
|
||||||
|
#executable="$specpath/403.gcc/run/run_base_ref_amd64-m64-gcc43-nn.0001/gcc_base.amd64-m64-gcc43-nn $specpath/403.gcc/run/run_base_ref_amd64-m64-gcc43-nn.0001/166.i -o $specpath/403.gcc/run/run_base_ref_amd64-m64-gcc43-nn.0001/166.s"
|
||||||
|
outputfile=$outputfiledir/"gcc"
|
||||||
|
stdoutfile=$stdoutfiledir/"gcc"
|
||||||
|
else
|
||||||
|
if [ $1 = "bwaves" ]
|
||||||
|
then
|
||||||
|
executable="$specpath/410.bwaves/run/run_base_test_amd64-m64-gcc43-nn.0000/bwaves_base.amd64-m64-gcc43-nn"
|
||||||
|
#executable="$specpath/410.bwaves/run/run_base_ref_amd64-m64-gcc43-nn.0000/bwaves_base.amd64-m64-gcc43-nn"
|
||||||
|
outputfile=$outputfiledir/"bwaves"
|
||||||
|
stdoutfile=$stdoutfiledir/"bwaves"
|
||||||
|
else
|
||||||
|
if [ $1 = "gamess" ]
|
||||||
|
then
|
||||||
|
executable="$specpath/416.gamess/run/run_base_test_amd64-m64-gcc43-nn.0000/gamess_base.amd64-m64-gcc43-nn"
|
||||||
|
#executable="$specpath/416.gamess/run/run_base_ref_amd64-m64-gcc43-nn.0000/gamess_base.amd64-m64-gcc43-nn"
|
||||||
|
outputfile=$outputfiledir/"gamess"
|
||||||
|
stdoutfile=$stdoutfiledir/"gamess"
|
||||||
|
else
|
||||||
|
if [ $1 = mcf ]
|
||||||
|
then
|
||||||
|
executable="$specpath/429.mcf/run/run_base_test_amd64-m64-gcc43-nn.0000/mcf_base.amd64-m64-gcc43-nn $specpath/429.mcf/run/run_base_test_amd64-m64-gcc43-nn.0000/inp.in"
|
||||||
|
#executable="$specpath/429.mcf/run/run_base_ref_amd64-m64-gcc43-nn.0000/mcf_base.amd64-m64-gcc43-nn $specpath/429.mcf/run/run_base_ref_amd64-m64-gcc43-nn.0000/inp.in"
|
||||||
|
outputfile=$outputfiledir/"mcf"
|
||||||
|
stdoutfile=$stdoutfiledir/"mcf"
|
||||||
|
else
|
||||||
|
if [ $1 = "milc" ]
|
||||||
|
then
|
||||||
|
executable="$specpath/433.milc/run/run_base_test_amd64-m64-gcc43-nn.0000/milc_base.amd64-m64-gcc43-nn"
|
||||||
|
#executable="$specpath/433.milc/run/run_base_ref_amd64-m64-gcc43-nn.0000/milc_base.amd64-m64-gcc43-nn"
|
||||||
|
outputfile=$outputfiledir/"milc"
|
||||||
|
stdoutfile=$stdoutfiledir/"milc"
|
||||||
|
else
|
||||||
|
if [ $1 = "zeusmp" ]
|
||||||
|
then
|
||||||
|
cd "$specpath/434.zeusmp/run/run_base_test_amd64-m64-gcc43-nn.0000"
|
||||||
|
executable="$specpath/434.zeusmp/run/run_base_test_amd64-m64-gcc43-nn.0000/zeusmp_base.amd64-m64-gcc43-nn"
|
||||||
|
#cd "$specpath/434.zeusmp/run/run_base_ref_amd64-m64-gcc43-nn.0000"
|
||||||
|
#executable="$specpath/434.zeusmp/run/run_base_ref_amd64-m64-gcc43-nn.0000/zeusmp_base.amd64-m64-gcc43-nn"
|
||||||
|
outputfile=$outputfiledir/"zeusmp"
|
||||||
|
stdoutfile=$stdoutfiledir/"zeusmp"
|
||||||
|
else
|
||||||
|
if [ $1 = gromacs ]
|
||||||
|
then
|
||||||
|
executable="$specpath/435.gromacs/run/run_base_test_amd64-m64-gcc43-nn.0000/gromacs_base.amd64-m64-gcc43-nn -silent -deffnm $specpath/435.gromacs/run/run_base_test_amd64-m64-gcc43-nn.0000/gromacs -nice 0"
|
||||||
|
#executable="$specpath/435.gromacs/run/run_base_ref_amd64-m64-gcc43-nn.0000/gromacs_base.amd64-m64-gcc43-nn -silent -deffnm $specpath/435.gromacs/run/run_base_ref_amd64-m64-gcc43-nn.0000/gromacs -nice 0"
|
||||||
|
outputfile=$outputfiledir/"gromacs"
|
||||||
|
stdoutfile=$stdoutfiledir/"gromacs"
|
||||||
|
else
|
||||||
|
if [ $1 = cactusADM ]
|
||||||
|
then
|
||||||
|
executable="$specpath/436.cactusADM/run/run_base_test_amd64-m64-gcc43-nn.0000/cactusADM_base.amd64-m64-gcc43-nn $specpath/436.cactusADM/run/run_base_test_amd64-m64-gcc43-nn.0000/benchADM.par"
|
||||||
|
#executable="$specpath/436.cactusADM/run/run_base_ref_amd64-m64-gcc43-nn.0000/cactusADM_base.amd64-m64-gcc43-nn $specpath/436.cactusADM/run/run_base_ref_amd64-m64-gcc43-nn.0000/benchADM.par"
|
||||||
|
outputfile=$outputfiledir/"cactusADM"
|
||||||
|
stdoutfile=$stdoutfiledir/"cactusADM"
|
||||||
|
else
|
||||||
|
if [ $1 = "leslie3d" ]
|
||||||
|
then
|
||||||
|
executable="$specpath/437.leslie3d/run/run_base_test_amd64-m64-gcc43-nn.0000/leslie3d_base.amd64-m64-gcc43-nn"
|
||||||
|
#executable="$specpath/437.leslie3d/run/run_base_ref_amd64-m64-gcc43-nn.0000/leslie3d_base.amd64-m64-gcc43-nn"
|
||||||
|
outputfile=$outputfiledir/"leslie3d"
|
||||||
|
stdoutfile=$stdoutfiledir/"leslie3d"
|
||||||
|
else
|
||||||
|
if [ $1 = namd ]
|
||||||
|
then
|
||||||
|
executable="$specpath/444.namd/run/run_base_test_amd64-m64-gcc43-nn.0000/namd_base.amd64-m64-gcc43-nn --input $specpath/444.namd/run/run_base_test_amd64-m64-gcc43-nn.0000/namd.input --iterations 1 --output $specpath/444.namd/run/run_base_test_amd64-m64-gcc43-nn.0000/namd.out"
|
||||||
|
#executable="$specpath/444.namd/run/run_base_ref_amd64-m64-gcc43-nn.0000/namd_base.amd64-m64-gcc43-nn --input $specpath/444.namd/run/run_base_ref_amd64-m64-gcc43-nn.0000/namd.input --iterations 38 --output $specpath/444.namd/run/run_base_ref_amd64-m64-gcc43-nn.0000/namd.out"
|
||||||
|
outputfile=$outputfiledir/"namd"
|
||||||
|
stdoutfile=$stdoutfiledir/"namd"
|
||||||
|
else
|
||||||
|
if [ $1 = "gobmk" ]
|
||||||
|
then
|
||||||
|
executable="$specpath/445.gobmk/run/run_base_test_amd64-m64-gcc43-nn.0000/gobmk_base.amd64-m64-gcc43-nn --quiet --mode gtp"
|
||||||
|
#executable="$specpath/445.gobmk/run/run_base_ref_amd64-m64-gcc43-nn.0001/gobmk_base.amd64-m64-gcc43-nn --quiet --mode gtp"
|
||||||
|
outputfile=$outputfiledir/"gobmk"
|
||||||
|
stdoutfile=$stdoutfiledir/"gobmk"
|
||||||
|
else
|
||||||
|
if [ $1 = dealII ]
|
||||||
|
then
|
||||||
|
executable="$specpath/447.dealII/run/run_base_test_amd64-m64-gcc43-nn.0000/dealII_base.amd64-m64-gcc43-nn 8"
|
||||||
|
#does not build
|
||||||
|
outputfile=$outputfiledir/"dealII"
|
||||||
|
stdoutfile=$stdoutfiledir/"dealII"
|
||||||
|
else
|
||||||
|
if [ $1 = "soplex" ]
|
||||||
|
then
|
||||||
|
executable="$specpath/450.soplex/run/run_base_test_amd64-m64-gcc43-nn.0000/soplex_base.amd64-m64-gcc43-nn -m10000 $specpath/450.soplex/run/run_base_test_amd64-m64-gcc43-nn.0000/test.mps"
|
||||||
|
#executable="$specpath/450.soplex/run/run_base_ref_amd64-m64-gcc43-nn.0000/soplex_base.amd64-m64-gcc43-nn -s1 -e -m45000 $specpath/450.soplex/run/run_base_ref_amd64-m64-gcc43-nn.0000/pds-50.mps"
|
||||||
|
outputfile=$outputfiledir/"soplex"
|
||||||
|
stdoutfile=$stdoutfiledir/"soplex"
|
||||||
|
else
|
||||||
|
if [ $1 = povray ]
|
||||||
|
then
|
||||||
|
executable="$specpath/453.povray/run/run_base_test_amd64-m64-gcc43-nn.0000/povray_base.amd64-m64-gcc43-nn $specpath/453.povray/run/run_base_test_amd64-m64-gcc43-nn.0000/SPEC-benchmark-test.ini"
|
||||||
|
#executable="$specpath/453.povray/run/run_base_ref_amd64-m64-gcc43-nn.0000/povray_base.amd64-m64-gcc43-nn $specpath/453.povray/run/run_base_ref_amd64-m64-gcc43-nn.0000/SPEC-benchmark-ref.ini"
|
||||||
|
outputfile=$outputfiledir/"povray"
|
||||||
|
stdoutfile=$stdoutfiledir/"povray"
|
||||||
|
else
|
||||||
|
if [ $1 = calculix ]
|
||||||
|
then
|
||||||
|
executable="$specpath/454.calculix/run/run_base_test_amd64-m64-gcc43-nn.0000/calculix_base.amd64-m64-gcc43-nn -i $specpath/454.calculix/run/run_base_test_amd64-m64-gcc43-nn.0000/beampic"
|
||||||
|
#executable="$specpath/454.calculix/run/run_base_ref_amd64-m64-gcc43-nn.0000/calculix_base.amd64-m64-gcc43-nn -i $specpath/454.calculix/run/run_base_ref_amd64-m64-gcc43-nn.0000/hyperviscoplastic"
|
||||||
|
outputfile=$outputfiledir/"calculix"
|
||||||
|
stdoutfile=$stdoutfiledir/"calculix"
|
||||||
|
else
|
||||||
|
if [ $1 = hmmer ]
|
||||||
|
then
|
||||||
|
executable="$specpath/456.hmmer/run/run_base_test_amd64-m64-gcc43-nn.0000/hmmer_base.amd64-m64-gcc43-nn --fixed 0 --mean 325 --num 45000 --sd 200 --seed 0 $specpath/456.hmmer/run/run_base_test_amd64-m64-gcc43-nn.0000/bombesin.hmm"
|
||||||
|
#executable="$specpath/456.hmmer/run/run_base_ref_amd64-m64-gcc43-nn.0001/hmmer_base.amd64-m64-gcc43-nn $specpath/456.hmmer/run/run_base_ref_amd64-m64-gcc43-nn.0001/nph3.hmm $specpath/456.hmmer/run/run_base_ref_amd64-m64-gcc43-nn.0001/swiss41"
|
||||||
|
outputfile=$outputfiledir/"hmmer"
|
||||||
|
stdoutfile=$stdoutfiledir/"hmmer"
|
||||||
|
else
|
||||||
|
if [ $1 = sjeng ]
|
||||||
|
then
|
||||||
|
executable="$specpath/458.sjeng/run/run_base_test_amd64-m64-gcc43-nn.0000/sjeng_base.amd64-m64-gcc43-nn $specpath/458.sjeng/run/run_base_test_amd64-m64-gcc43-nn.0000/test.txt"
|
||||||
|
#executable="$specpath/458.sjeng/run/run_base_ref_amd64-m64-gcc43-nn.0001/sjeng_base.amd64-m64-gcc43-nn $specpath/458.sjeng/run/run_base_ref_amd64-m64-gcc43-nn.0001/ref.txt"
|
||||||
|
outputfile=$outputfiledir/"sjeng"
|
||||||
|
stdoutfile=$stdoutfiledir/"sjeng"
|
||||||
|
else
|
||||||
|
if [ $1 = "GemsFDTD" ]
|
||||||
|
then
|
||||||
|
cd "$specpath/459.GemsFDTD/run/run_base_test_amd64-m64-gcc43-nn.0000/"
|
||||||
|
executable="$specpath/459.GemsFDTD/run/run_base_test_amd64-m64-gcc43-nn.0000/GemsFDTD_base.amd64-m64-gcc43-nn"
|
||||||
|
#cd "$specpath/459.GemsFDTD/run/run_base_ref_amd64-m64-gcc43-nn.0000/"
|
||||||
|
#executable="$specpath/459.GemsFDTD/run/run_base_ref_amd64-m64-gcc43-nn.0000/GemsFDTD_base.amd64-m64-gcc43-nn"
|
||||||
|
outputfile=$outputfiledir/"GemsFDTD"
|
||||||
|
stdoutfile=$stdoutfiledir/"GemsFDTD"
|
||||||
|
else
|
||||||
|
if [ $1 = libquantum ]
|
||||||
|
then
|
||||||
|
executable="$specpath/462.libquantum/run/run_base_test_amd64-m64-gcc43-nn.0000/libquantum_base.amd64-m64-gcc43-nn 33 5"
|
||||||
|
#executable="$specpath/462.libquantum/run/run_base_ref_amd64-m64-gcc43-nn.0001/libquantum_base.amd64-m64-gcc43-nn 1397 8"
|
||||||
|
outputfile=$outputfiledir/"libquantum"
|
||||||
|
stdoutfile=$stdoutfiledir/"libquantum"
|
||||||
|
else
|
||||||
|
if [ $1 = "h264ref" ]
|
||||||
|
then
|
||||||
|
cd "$specpath/464.h264ref/run/run_base_test_amd64-m64-gcc43-nn.0000/"
|
||||||
|
executable="$specpath/464.h264ref/run/run_base_test_amd64-m64-gcc43-nn.0000/h264ref_base.amd64-m64-gcc43-nn -d foreman_test_encoder_baseline.cfg"
|
||||||
|
#cd "$specpath/464.h264ref/run/run_base_ref_amd64-m64-gcc43-nn.0001/"
|
||||||
|
#executable="$specpath/464.h264ref/run/run_base_ref_amd64-m64-gcc43-nn.0001/h264ref_base.amd64-m64-gcc43-nn -d foreman_ref_encoder_baseline.cfg"
|
||||||
|
#or
|
||||||
|
#executable="$specpath/464.h264ref/run/run_base_ref_amd64-m64-gcc43-nn.0001/h264ref_base.amd64-m64-gcc43-nn -d $specpath/464.h264ref/run/run_base_ref_amd64-m64-gcc43-nn.0001/foreman_ref_encoder_baseline.cfg"
|
||||||
|
outputfile=$outputfiledir/"h264ref"
|
||||||
|
stdoutfile=$stdoutfiledir/"h264ref"
|
||||||
|
else
|
||||||
|
if [ $1 = "tonto" ]
|
||||||
|
then
|
||||||
|
cd "$specpath/465.tonto/run/run_base_test_amd64-m64-gcc43-nn.0000/"
|
||||||
|
executable="$specpath/465.tonto/run/run_base_test_amd64-m64-gcc43-nn.0000/tonto_base.amd64-m64-gcc43-nn"
|
||||||
|
#cd "$specpath/465.tonto/run/run_base_ref_amd64-m64-gcc43-nn.0000/"
|
||||||
|
#executable="$specpath/465.tonto/run/run_base_ref_amd64-m64-gcc43-nn.0000/tonto_base.amd64-m64-gcc43-nn"
|
||||||
|
outputfile=$outputfiledir/"tonto"
|
||||||
|
stdoutfile=$stdoutfiledir/"tonto"
|
||||||
|
else
|
||||||
|
if [ $1 = lbm ]
|
||||||
|
then
|
||||||
|
executable="$specpath/470.lbm/run/run_base_test_amd64-m64-gcc43-nn.0000/lbm_base.amd64-m64-gcc43-nn 20 reference.dat 0 1 $specpath/470.lbm/run/run_base_test_amd64-m64-gcc43-nn.0000/100_100_130_cf_a.of"
|
||||||
|
#executable="$specpath/470.lbm/run/run_base_ref_amd64-m64-gcc43-nn.0000/lbm_base.amd64-m64-gcc43-nn 3000 reference.dat 0 0 $specpath/470.lbm/run/run_base_ref_amd64-m64-gcc43-nn.0000/100_100_130_ldc.of"
|
||||||
|
outputfile=$outputfiledir/"lbm"
|
||||||
|
stdoutfile=$stdoutfiledir/"lbm"
|
||||||
|
else
|
||||||
|
if [ $1 = "omnetpp" ]
|
||||||
|
then
|
||||||
|
cd "$specpath/471.omnetpp/run/run_base_test_amd64-m64-gcc43-nn.0000/"
|
||||||
|
executable="$specpath/471.omnetpp/run/run_base_test_amd64-m64-gcc43-nn.0000/omnetpp_base.amd64-m64-gcc43-nn omnetpp.ini"
|
||||||
|
#executable="$specpath/471.omnetpp/run/run_base_ref_amd64-m64-gcc43-nn.0001/omnetpp_base.amd64-m64-gcc43-nn $specpath/471.omnetpp/run/run_base_ref_amd64-m64-gcc43-nn.0001/omnetpp.ini"
|
||||||
|
outputfile=$outputfiledir/"omnetpp"
|
||||||
|
stdoutfile=$stdoutfiledir/"omnetpp"
|
||||||
|
else
|
||||||
|
if [ $1 = "astar" ]
|
||||||
|
then
|
||||||
|
cd "$specpath/473.astar/run/run_base_test_amd64-m64-gcc43-nn.0000/"
|
||||||
|
executable="$specpath/473.astar/run/run_base_test_amd64-m64-gcc43-nn.0000/astar_base.amd64-m64-gcc43-nn lake.cfg"
|
||||||
|
#cd "$specpath/473.astar/run/run_base_ref_amd64-m64-gcc43-nn.0001/"
|
||||||
|
#executable="$specpath/473.astar/run/run_base_ref_amd64-m64-gcc43-nn.0001/astar_base.amd64-m64-gcc43-nn BigLakes2048.cfg"
|
||||||
|
#or
|
||||||
|
#executable="$specpath/473.astar/run/run_base_ref_amd64-m64-gcc43-nn.0001/astar_base.amd64-m64-gcc43-nn $specpath/473.astar/run/run_base_ref_amd64-m64-gcc43-nn.0001/BigLakes2048.cfg"
|
||||||
|
outputfile=$outputfiledir/"astar"
|
||||||
|
stdoutfile=$stdoutfiledir/"astar"
|
||||||
|
else
|
||||||
|
if [ $1 = "wrf" ]
|
||||||
|
then
|
||||||
|
cd "$specpath/481.wrf/run/run_base_test_amd64-m64-gcc43-nn.0000/"
|
||||||
|
executable="$specpath/481.wrf/run/run_base_test_amd64-m64-gcc43-nn.0000/wrf_base.amd64-m64-gcc43-nn"
|
||||||
|
#cd "$specpath/481.wrf/run/run_base_ref_amd64-m64-gcc43-nn.0000/"
|
||||||
|
#executable="$specpath/481.wrf/run/run_base_ref_amd64-m64-gcc43-nn.0000/wrf_base.amd64-m64-gcc43-nn"
|
||||||
|
outputfile=$outputfiledir/"wrf"
|
||||||
|
stdoutfile=$stdoutfiledir/"wrf"
|
||||||
|
else
|
||||||
|
if [ $1 = "sphinx3" ]
|
||||||
|
then
|
||||||
|
cd "$specpath/482.sphinx3/run/run_base_test_amd64-m64-gcc43-nn.0000/"
|
||||||
|
executable="$specpath/482.sphinx3/run/run_base_test_amd64-m64-gcc43-nn.0000/sphinx_livepretend_base.amd64-m64-gcc43-nn ctlfile $specpath/482.sphinx3/run/run_base_test_amd64-m64-gcc43-nn.0000 args.an4"
|
||||||
|
#cd "$specpath/482.sphinx3/run/run_base_ref_amd64-m64-gcc43-nn.0000/"
|
||||||
|
#executable="$specpath/482.sphinx3/run/run_base_ref_amd64-m64-gcc43-nn.0000/sphinx_livepretend_base.amd64-m64-gcc43-nn ctlfile $specpath/482.sphinx3/run/run_base_ref_amd64-m64-gcc43-nn.0000/ args.an4"
|
||||||
|
outputfile=$outputfiledir/"sphinx3"
|
||||||
|
stdoutfile=$stdoutfiledir/"sphinx3"
|
||||||
|
else
|
||||||
|
if [ $1 = xalancbmk ]
|
||||||
|
then
|
||||||
|
executable="$specpath/483.xalancbmk/run/run_base_test_amd64-m64-gcc43-nn.0000/Xalan_base.amd64-m64-gcc43-nn -v $specpath/483.xalancbmk/run/run_base_test_amd64-m64-gcc43-nn.0000/test.xml $specpath/483.xalancbmk/run/run_base_test_amd64-m64-gcc43-nn.0000/xalanc.xsl"
|
||||||
|
#executable="$specpath/483.xalancbmk/run/run_base_ref_amd64-m64-gcc43-nn.0001/Xalan_base.amd64-m64-gcc43-nn -v $specpath/483.xalancbmk/run/run_base_ref_amd64-m64-gcc43-nn.0001/t5.xml $specpath/483.xalancbmk/run/run_base_ref_amd64-m64-gcc43-nn.0001/xalanc.xsl"
|
||||||
|
outputfile=$outputfiledir/"xalancbmk"
|
||||||
|
stdoutfile=$stdoutfiledir/"xalancbmk"
|
||||||
|
else
|
||||||
|
if [ $1 = "998.specrand" ]
|
||||||
|
#do not call
|
||||||
|
then
|
||||||
|
executable=""
|
||||||
|
outputfile=""
|
||||||
|
else
|
||||||
|
if [ $1 = "999.specrand" ]
|
||||||
|
#do not call
|
||||||
|
then
|
||||||
|
executable=""
|
||||||
|
outputfile=""
|
||||||
|
else
|
||||||
|
echo "invalid argument "$1
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
echo "starting : "$outputfile
|
||||||
|
java -Xmx1024m -jar $jarfile $configfile $outputfile $executable > $stdoutfile
|
||||||
|
echo "finished : "$outputfile
|
|
@ -0,0 +1,23 @@
|
||||||
|
#This is the hardcoded script to build pin
|
||||||
|
# THIS IS NOT USED. Makefile handles the building of pin
|
||||||
|
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
# This is used to build the PIN tools
|
||||||
|
|
||||||
|
echo "Compiling PIN tools $1"
|
||||||
|
TEJAS_HOME="../../.."
|
||||||
|
PIN_HOME=$2
|
||||||
|
|
||||||
|
cd src/emulator/pin
|
||||||
|
|
||||||
|
|
||||||
|
g++ -Wall -Werror -Wno-unknown-pragmas -D__PIN__=1 -DPIN_CRT=1 -fno-stack-protector -fno-exceptions -funwind-tables -fasynchronous-unwind-tables -fno-rtti -DTARGET_IA32E -DHOST_IA32E -fPIC -DTARGET_LINUX -fabi-version=2 -I$PIN_HOME/source/include/pin -I$PIN_HOME/source/include/pin/gen -isystem $PIN_HOME/extras/stlport/include -isystem $PIN_HOME/extras/libstdc++/include -isystem $PIN_HOME/extras/crt/include -isystem $PIN_HOME/extras/crt/include/arch-x86_64 -isystem $PIN_HOME/extras/crt/include/kernel/uapi -isystem $PIN_HOME/extras/crt/include/kernel/uapi/asm-x86 -I$PIN_HOMEextras/components/include -I$PIN_HOME/extras/components/include -I$PIN_HOME//extras/xed-intel64/include/xed -I$PIN_HOME/source/tools/InstLib -O3 -fomit-frame-pointer -fno-strict-aliasing -c -I$TEJAS_HOME/src/simulator/emulatorinterface/communication -I$TEJAS_HOME/src/simulator/emulatorinterface/communication/shm -I$TEJAS_HOME/src/simulator/emulatorinterface/communication/filePacket causalityTool.cpp ../../simulator/emulatorinterface/communication/shm/shmem.cc
|
||||||
|
|
||||||
|
mkdir obj-pin
|
||||||
|
mv causalityTool.o shmem.o obj-pin/
|
||||||
|
|
||||||
|
g++ -shared -Wl,--hash-style=sysv $PIN_HOME/intel64/runtime/pincrt/crtbeginS.o -Wl,-Bsymbolic -Wl,--version-script=$PIN_HOME/source/include/pin/pintool.ver -fabi-version=2 -o obj-pin/causalityTool.so obj-pin/causalityTool.o obj-pin/shmem.o -L$PIN_HOME/intel64/runtime/pincrt -L$PIN_HOME/intel64/lib -L$PIN_HOME/intel64/lib-ext -L$PIN_HOME/extras/xed-intel64/lib -lpin -lxed $PIN_HOME/intel64/runtime/pincrt/crtendS.o -lpin3dwarf -ldl-dynamic -nostdlib -lstlport-dynamic -lm-dynamic -lc-dynamic -lunwind-dynamic
|
||||||
|
|
||||||
|
cd $TEJAS_HOME
|
||||||
|
|
|
@ -0,0 +1,4 @@
|
||||||
|
rm tests/run.out
|
||||||
|
g++ tests/hello_world.cpp -o tests/hello_world.o
|
||||||
|
java -jar ../jars/tejas.jar ../bin/config/config.xml tests/run.out tests/hello_world.o
|
||||||
|
cat tests/run.out
|
|
@ -0,0 +1,8 @@
|
||||||
|
#include<iostream>
|
||||||
|
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
|
int main(){
|
||||||
|
cout<<"This is working "<<endl;
|
||||||
|
return 0;
|
||||||
|
}
|
|
@ -0,0 +1,256 @@
|
||||||
|
#include <iostream>
|
||||||
|
#include <fstream>
|
||||||
|
#include "pin.H"
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <sys/shm.h>
|
||||||
|
#include <cstdlib>
|
||||||
|
#include <cstring>
|
||||||
|
#include <sched.h>
|
||||||
|
#include <sys/time.h>
|
||||||
|
#include <sys/resource.h>
|
||||||
|
|
||||||
|
|
||||||
|
#include "IPCBase.h"
|
||||||
|
#include "shmem.h"
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef _LP64
|
||||||
|
#define MASK 0xffffffffffffffff
|
||||||
|
#else
|
||||||
|
#define MASK 0x00000000ffffffff
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Defining command line arguments
|
||||||
|
KNOB<UINT64> KnobMap(KNOB_MODE_WRITEONCE, "pintool",
|
||||||
|
"map", "1", "Maps");
|
||||||
|
KNOB<UINT64> KnobIgnore(KNOB_MODE_WRITEONCE, "pintool",
|
||||||
|
"numIgn", "0", "Ignore these many profilable instructions");
|
||||||
|
KNOB<UINT64> KnobId(KNOB_MODE_WRITEONCE, "pintool",
|
||||||
|
"id", "1", "shm id to generate key");
|
||||||
|
|
||||||
|
PIN_LOCK lock;
|
||||||
|
INT32 numThreads = 0;
|
||||||
|
UINT64 checkSum = 0;
|
||||||
|
|
||||||
|
static UINT64 numIns = 0;
|
||||||
|
UINT64 numInsToIgnore = 0;
|
||||||
|
BOOL ignoreActive = false;
|
||||||
|
|
||||||
|
IPC::IPCBase *tst;
|
||||||
|
|
||||||
|
VOID ThreadStart(THREADID threadid, CONTEXT *ctxt, INT32 flags, VOID *v)
|
||||||
|
{
|
||||||
|
GetLock(&lock, threadid+1);
|
||||||
|
numThreads++;
|
||||||
|
printf("threads till now %d\n",numThreads);
|
||||||
|
fflush(stdout);
|
||||||
|
ReleaseLock(&lock);
|
||||||
|
ASSERT(numThreads <= MaxNumThreads, "Maximum number of threads exceeded\n");
|
||||||
|
|
||||||
|
tst->onThread_start(threadid);
|
||||||
|
}
|
||||||
|
|
||||||
|
VOID ThreadFini(THREADID tid,const CONTEXT *ctxt, INT32 flags, VOID *v)
|
||||||
|
{
|
||||||
|
while (tst->onThread_finish(tid)==-1) {
|
||||||
|
PIN_Yield();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Pass a memory read record
|
||||||
|
VOID RecordMemRead(THREADID tid,VOID * ip, VOID * addr)
|
||||||
|
{
|
||||||
|
if (ignoreActive) return;
|
||||||
|
checkSum+=2;
|
||||||
|
uint64_t nip = MASK & (uint64_t)ip;
|
||||||
|
uint64_t naddr = MASK & (uint64_t)addr;
|
||||||
|
while (tst->analysisFn(tid,nip,2,naddr)== -1) {
|
||||||
|
PIN_Yield();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Pass a memory write record
|
||||||
|
VOID RecordMemWrite(THREADID tid,VOID * ip, VOID * addr)
|
||||||
|
{
|
||||||
|
if (ignoreActive) return;
|
||||||
|
checkSum+=3;
|
||||||
|
uint64_t nip = MASK & (uint64_t)ip;
|
||||||
|
uint64_t naddr = MASK & (uint64_t)addr;
|
||||||
|
while(tst->analysisFn(tid,nip,3,naddr)== -1) {
|
||||||
|
PIN_Yield();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
VOID BrnFun(THREADID tid,ADDRINT tadr,BOOL taken,VOID *ip)
|
||||||
|
{
|
||||||
|
if (ignoreActive) return;
|
||||||
|
uint64_t nip = MASK & (uint64_t)ip;
|
||||||
|
uint64_t ntadr = MASK & (uint64_t)tadr;
|
||||||
|
if (taken) {
|
||||||
|
checkSum+=4;
|
||||||
|
while (tst->analysisFn(tid,nip,4,ntadr)==-1) {
|
||||||
|
PIN_Yield();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
checkSum+=5;
|
||||||
|
while (tst->analysisFn(tid,nip,5,ntadr)==-1) {
|
||||||
|
PIN_Yield();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
VOID RegValRead(THREADID tid,VOID * ip,REG* _reg)
|
||||||
|
{
|
||||||
|
if (ignoreActive) return;
|
||||||
|
checkSum+=6;
|
||||||
|
uint64_t nip = MASK & (uint64_t)ip;
|
||||||
|
uint64_t _nreg = MASK & (uint64_t)_reg;
|
||||||
|
while (tst->analysisFn(tid,nip,6,_nreg)== -1) {
|
||||||
|
PIN_Yield();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
VOID RegValWrite(THREADID tid,VOID * ip,REG* _reg)
|
||||||
|
{
|
||||||
|
if (ignoreActive) return;
|
||||||
|
checkSum+=7;
|
||||||
|
uint64_t nip = MASK & (uint64_t)ip;
|
||||||
|
uint64_t _nreg = MASK & (uint64_t)_reg;
|
||||||
|
while (tst->analysisFn(tid,nip,7,_nreg)== -1) {
|
||||||
|
PIN_Yield();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
VOID CountIns()
|
||||||
|
{
|
||||||
|
if (!ignoreActive) return;
|
||||||
|
numIns++;
|
||||||
|
if (numIns>numInsToIgnore) ignoreActive = false; //activate Now
|
||||||
|
}
|
||||||
|
|
||||||
|
// Pin calls this function every time a new instruction is encountered
|
||||||
|
VOID Instruction(INS ins, VOID *v)
|
||||||
|
{
|
||||||
|
UINT32 memOperands = INS_MemoryOperandCount(ins);
|
||||||
|
if (ignoreActive)
|
||||||
|
INS_InsertCall(ins, IPOINT_BEFORE, (AFUNPTR)CountIns, IARG_END);
|
||||||
|
/*
|
||||||
|
UINT32 maxWregs = INS_MaxNumWRegs(ins);
|
||||||
|
UINT32 maxRregs = INS_MaxNumRRegs(ins);
|
||||||
|
|
||||||
|
for(UINT32 i=0; i< maxWregs; i++) {
|
||||||
|
REG x = REG_FullRegName(INS_RegW(ins, i));
|
||||||
|
if (REG_is_gr(x) || x == REG_EFLAGS)
|
||||||
|
INS_InsertCall(ins, IPOINT_BEFORE, (AFUNPTR)RegValWrite,IARG_THREAD_ID, IARG_INST_PTR, IARG_REG_VALUE,x,IARG_END);
|
||||||
|
}
|
||||||
|
for(UINT32 i=0; i< maxRregs; i++) {
|
||||||
|
REG x = REG_FullRegName(INS_RegR(ins, i));
|
||||||
|
if (REG_is_gr(x) || x == REG_EFLAGS)
|
||||||
|
INS_InsertCall(ins, IPOINT_BEFORE, (AFUNPTR)RegValRead,IARG_THREAD_ID, IARG_INST_PTR, IARG_REG_VALUE,x,IARG_END);
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
if (INS_IsBranchOrCall(ins))//INS_IsIndirectBranchOrCall(ins))
|
||||||
|
{
|
||||||
|
INS_InsertCall(ins, IPOINT_BEFORE, (AFUNPTR)BrnFun, IARG_THREAD_ID, IARG_BRANCH_TARGET_ADDR, IARG_BRANCH_TAKEN, IARG_INST_PTR, IARG_END);
|
||||||
|
}
|
||||||
|
/* if (INS_HasFallThrough(ins))//INS_IsIndirectBranchOrCall(ins))
|
||||||
|
{
|
||||||
|
INS_InsertCall(ins, IPOINT_AFTER, (AFUNPTR)BrnFun, IARG_BRANCH_TARGET_ADDR, IARG_BRANCH_TAKEN, IARG_INST_PTR, IARG_END);
|
||||||
|
} */
|
||||||
|
// Iterate over each memory operand of the instruction.
|
||||||
|
for (UINT32 memOp = 0; memOp < memOperands; memOp++)
|
||||||
|
{
|
||||||
|
if (INS_MemoryOperandIsRead(ins, memOp))
|
||||||
|
{
|
||||||
|
INS_InsertPredicatedCall(
|
||||||
|
ins, IPOINT_BEFORE, (AFUNPTR)RecordMemRead,
|
||||||
|
IARG_THREAD_ID,
|
||||||
|
IARG_INST_PTR,
|
||||||
|
IARG_MEMORYOP_EA, memOp,
|
||||||
|
IARG_END);
|
||||||
|
}
|
||||||
|
// Note that in some architectures a single memory operand can be
|
||||||
|
// both read and written (for instance incl (%eax) on IA-32)
|
||||||
|
// In that case we instrument it once for read and once for write.
|
||||||
|
if (INS_MemoryOperandIsWritten(ins, memOp))
|
||||||
|
{
|
||||||
|
INS_InsertPredicatedCall(
|
||||||
|
ins, IPOINT_BEFORE, (AFUNPTR)RecordMemWrite,
|
||||||
|
IARG_THREAD_ID,
|
||||||
|
IARG_INST_PTR,
|
||||||
|
IARG_MEMORYOP_EA, memOp,
|
||||||
|
IARG_END);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// This function is called when the application exits
|
||||||
|
VOID Fini(INT32 code, VOID *v)
|
||||||
|
{
|
||||||
|
//printf("checkSum is %lld\n",checkSum);
|
||||||
|
tst->unload();
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ===================================================================== */
|
||||||
|
/* Print Help Message */
|
||||||
|
/* ===================================================================== */
|
||||||
|
|
||||||
|
INT32 Usage()
|
||||||
|
{
|
||||||
|
cerr << "This tool instruments the benchmarks" << endl;
|
||||||
|
cerr << endl << KNOB_BASE::StringKnobSummary() << endl;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ===================================================================== */
|
||||||
|
/* Main */
|
||||||
|
/* ===================================================================== */
|
||||||
|
|
||||||
|
// argc, argv are the entire command line, including pin -t <toolname> -- ...
|
||||||
|
int main(int argc, char * argv[])
|
||||||
|
{
|
||||||
|
|
||||||
|
// Initialize pin
|
||||||
|
if (PIN_Init(argc, argv)) return Usage();
|
||||||
|
|
||||||
|
// Knobs get initialized only after initlializing PIN
|
||||||
|
numInsToIgnore = KnobIgnore;
|
||||||
|
if (numInsToIgnore>0) ignoreActive = true;
|
||||||
|
// printf("Ignoring %lld profilable instructions \n", numInsToIgnore);
|
||||||
|
// fflush(stdout);
|
||||||
|
|
||||||
|
UINT64 mask = KnobMap;
|
||||||
|
// printf("mask for pin %lld\n", mask);
|
||||||
|
// fflush(stdout);
|
||||||
|
if (sched_setaffinity(0, sizeof(mask), (cpu_set_t *)&mask) <0) {
|
||||||
|
perror("sched_setaffinity");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//tst = new IPC::Shm ();
|
||||||
|
UINT64 id = KnobId;
|
||||||
|
//printf("id received = %lld", id);
|
||||||
|
tst = new IPC::Shm (id);
|
||||||
|
PIN_AddThreadStartFunction(ThreadStart, 0);
|
||||||
|
|
||||||
|
// Register Instruction to be called to instrument instructions
|
||||||
|
INS_AddInstrumentFunction(Instruction, 0);
|
||||||
|
|
||||||
|
PIN_AddThreadFiniFunction(ThreadFini, 0);
|
||||||
|
|
||||||
|
// Register Fini to be called when the application exits
|
||||||
|
PIN_AddFiniFunction(Fini, 0);
|
||||||
|
|
||||||
|
// Start the program, never returns
|
||||||
|
PIN_StartProgram();
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
Binary file not shown.
|
@ -0,0 +1,49 @@
|
||||||
|
#include <jni.h>
|
||||||
|
int test()
|
||||||
|
{
|
||||||
|
JavaVMOption options[1];
|
||||||
|
JNIEnv *env;
|
||||||
|
JavaVM *jvm;
|
||||||
|
JavaVMInitArgs vm_args;
|
||||||
|
|
||||||
|
jclass cls;
|
||||||
|
jmethodID mid;
|
||||||
|
jint square;
|
||||||
|
long status;
|
||||||
|
//boolean not;
|
||||||
|
|
||||||
|
options[0].optionString = "-Djava.class.path=.";
|
||||||
|
memset(&vm_args, 0, sizeof(vm_args));
|
||||||
|
vm_args.version = JNI_VERSION_1_6;
|
||||||
|
vm_args.nOptions = 1;
|
||||||
|
vm_args.options = options;
|
||||||
|
vm_args.ignoreUnrecognized=false;
|
||||||
|
status = JNI_CreateJavaVM(&jvm, (void**)&env, &vm_args);
|
||||||
|
static const char* const ECOClassName = "intMethod";
|
||||||
|
static const char* const ECOClassName2 = "Sample2";
|
||||||
|
if (status)
|
||||||
|
{
|
||||||
|
cls = env->FindClass(ECOClassName2);
|
||||||
|
if(cls !=0)
|
||||||
|
{
|
||||||
|
mid = env->GetStaticMethodID(cls, ECOClassName, "(I)I");
|
||||||
|
if(mid !=0)
|
||||||
|
{
|
||||||
|
square = env->CallStaticIntMethod(cls, mid, 5);
|
||||||
|
printf("Result of intMethod: %d\n", square);
|
||||||
|
}
|
||||||
|
|
||||||
|
// mid = env->GetStaticMethodID(cls, "booleanMethod", "(Z)Z");
|
||||||
|
// if(mid !=0)
|
||||||
|
// {
|
||||||
|
// not = env->CallStaticBooleanMethod(cls, mid, 1);
|
||||||
|
// printf("Result of booleanMethod: %d\n", not);
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
|
||||||
|
jvm->DestroyJavaVM();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return -1;
|
||||||
|
}
|
|
@ -0,0 +1,10 @@
|
||||||
|
class Sample2
|
||||||
|
{
|
||||||
|
public static int intMethod(int n) {
|
||||||
|
return n*n;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean booleanMethod(boolean bool) {
|
||||||
|
return !bool;
|
||||||
|
}
|
||||||
|
}
|
Binary file not shown.
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,35 @@
|
||||||
|
// Do not change these encodings, change Encoding.java too, if needed.
|
||||||
|
|
||||||
|
#define THREADCOMPLETE -1
|
||||||
|
#define SUBSETSIMCOMPLETE -2
|
||||||
|
|
||||||
|
#define MEMREAD 2
|
||||||
|
#define MEMWRITE 3
|
||||||
|
#define TAKEN 4
|
||||||
|
#define NOTTAKEN 5
|
||||||
|
#define REGREAD 6
|
||||||
|
#define REGWRITE 7
|
||||||
|
#define TIMER 8
|
||||||
|
|
||||||
|
// these are for function entry, For function exit x+1 will be used
|
||||||
|
#define BCAST 10
|
||||||
|
#define SIGNAL 12
|
||||||
|
#define LOCK 14
|
||||||
|
#define UNLOCK 16
|
||||||
|
#define JOIN 18
|
||||||
|
#define CONDWAIT 20
|
||||||
|
#define BARRIERWAIT 22
|
||||||
|
#define BARRIERINIT 26
|
||||||
|
#define ASSEMBLY 27
|
||||||
|
#define INSTRUCTION 28
|
||||||
|
#define FUNC_START 29
|
||||||
|
#define INTERRUPT 30
|
||||||
|
#define PROCESS_SWITCH 31
|
||||||
|
#define DOM_SWITCH 32
|
||||||
|
#define CPL_SWITCH 34
|
||||||
|
|
||||||
|
#define PARENT_SPAWN 35
|
||||||
|
#define CHILD_START 36
|
||||||
|
|
||||||
|
|
||||||
|
const char* findType(int type);
|
|
@ -0,0 +1,6 @@
|
||||||
|
|
||||||
|
ifeq ($(OS),Windows_NT)
|
||||||
|
include makefile_windows
|
||||||
|
else
|
||||||
|
include makefile_linux_mac
|
||||||
|
endif
|
|
@ -0,0 +1,719 @@
|
||||||
|
##############################################################
|
||||||
|
#
|
||||||
|
# Here are some things you might want to configure
|
||||||
|
#
|
||||||
|
##############################################################
|
||||||
|
|
||||||
|
# These definitions are generated by the kit builder from PIN
|
||||||
|
# when we run configure for PIN. please cross check it.
|
||||||
|
KIT=1
|
||||||
|
TARGET_OS=l
|
||||||
|
|
||||||
|
# if your tool is not in the kit directory
|
||||||
|
# then set this to the pin-2.0-X-Y directory
|
||||||
|
PIN_KIT ?= /home/kushagra/Desktop/pin-62732
|
||||||
|
PIN_HOME ?= $(PIN_KIT)/source/tools
|
||||||
|
|
||||||
|
# Select static or dynamic linking for tool
|
||||||
|
# only applies to unix
|
||||||
|
#PIN_DYNAMIC = -static
|
||||||
|
PIN_DYNAMIC = -ldl
|
||||||
|
|
||||||
|
##############################################################
|
||||||
|
#
|
||||||
|
# Typical users will not need to change the stuff below here
|
||||||
|
#
|
||||||
|
##############################################################
|
||||||
|
|
||||||
|
##############################################################
|
||||||
|
# Set things for all architectures and all OS
|
||||||
|
##############################################################
|
||||||
|
ifeq ($(DEBUG),1)
|
||||||
|
OPT =
|
||||||
|
DBG = -g
|
||||||
|
else
|
||||||
|
DBG =
|
||||||
|
OPT = -O3 -fomit-frame-pointer
|
||||||
|
endif
|
||||||
|
|
||||||
|
# IDB supports only Dwarf-2, GDB test should use the default
|
||||||
|
DBG_INFO_ALWAYS_IDB = -gdwarf-2 -O0
|
||||||
|
DBG_INFO_ALWAYS = -g -O0
|
||||||
|
|
||||||
|
PIN_LD = $(CXX)
|
||||||
|
PIN_CXXFLAGS = -DBIGARRAY_MULTIPLIER=1 -DUSING_XED $(DBG)
|
||||||
|
PIN_CXXFLAGS += -fno-strict-aliasing -I$(PIN_HOME)/Include -I$(PIN_HOME)/InstLib
|
||||||
|
PIN_LPATHS = -L$(PIN_HOME)/Lib/ -L$(PIN_HOME)/ExtLib/
|
||||||
|
PIN_BASE_LIBS :=
|
||||||
|
PIN_LDFLAGS = $(DBG)
|
||||||
|
NO_LOGO =
|
||||||
|
SSE2 = -msse2
|
||||||
|
ifdef ICC
|
||||||
|
ICC_NO_SSE = -mia32
|
||||||
|
endif
|
||||||
|
ENABLE_VS = 0
|
||||||
|
PROBE = 1
|
||||||
|
AS_FLAGS =
|
||||||
|
ASLD_FLAGS =
|
||||||
|
COMPARE_EXT = compare
|
||||||
|
|
||||||
|
ifeq ($(CCOV),1)
|
||||||
|
# code coverage is on
|
||||||
|
ifeq ($(findstring "cc/10.",$(ICCDIR)),)
|
||||||
|
# icc version >= 11
|
||||||
|
PIN_LDFLAGS += -prof-gen=srcpos
|
||||||
|
else
|
||||||
|
# icc version 10
|
||||||
|
PIN_LDFLAGS += -prof-genx
|
||||||
|
endif
|
||||||
|
ifneq ($(CCOVDIR),)
|
||||||
|
PIN_LDFLAGS += -prof-dir $(CCOVDIR)
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
|
||||||
|
ifeq ($(ENABLE_VS),1)
|
||||||
|
VIRT_SEG_FLAG = -xyzzy -241runtime 0 -xyzzy -virtual_segments 1
|
||||||
|
else
|
||||||
|
VIRT_SEG_FLAG =
|
||||||
|
endif
|
||||||
|
|
||||||
|
ifndef HOST_ARCH
|
||||||
|
# default to building for the host you are on. You can override this on the cmd line.
|
||||||
|
HST=$(shell uname -m)
|
||||||
|
ifeq (${HST},x86_64)
|
||||||
|
HOST_ARCH=ia32e
|
||||||
|
endif
|
||||||
|
ifeq (${HST},amd64)
|
||||||
|
HOST_ARCH=ia32e
|
||||||
|
endif
|
||||||
|
ifeq (${HST},i686)
|
||||||
|
HOST_ARCH=ia32
|
||||||
|
endif
|
||||||
|
ifeq (${HST},x86)
|
||||||
|
HOST_ARCH=ia32
|
||||||
|
endif
|
||||||
|
ifeq (${HST},i386)
|
||||||
|
HOST_ARCH=ia32
|
||||||
|
endif
|
||||||
|
ifeq (${HST},ia64)
|
||||||
|
HOST_ARCH=ipf
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
|
||||||
|
ifndef HOST_ARCH
|
||||||
|
$(error could not detect building host. please define HOST_ARCH on the command line)
|
||||||
|
endif
|
||||||
|
|
||||||
|
ifndef TARGET
|
||||||
|
TARGET=${HOST_ARCH}
|
||||||
|
endif
|
||||||
|
|
||||||
|
#define TARGET_LONG
|
||||||
|
ifeq (${TARGET},ia32e)
|
||||||
|
TARGET_LONG=intel64
|
||||||
|
endif
|
||||||
|
ifeq (${TARGET},ia32)
|
||||||
|
TARGET_LONG=ia32
|
||||||
|
endif
|
||||||
|
ifeq (${TARGET},ipf)
|
||||||
|
TARGET_LONG=ia64
|
||||||
|
endif
|
||||||
|
ifndef TARGET_LONG
|
||||||
|
$(error unknown TARGET, could not define TARGET_LONG)
|
||||||
|
endif
|
||||||
|
|
||||||
|
##############################################################
|
||||||
|
# Set the kit versus source tree stuff
|
||||||
|
##############################################################
|
||||||
|
ifndef KIT
|
||||||
|
KIT = 0
|
||||||
|
endif
|
||||||
|
ifndef OVERRIDE_DEFAULT_COMPILER
|
||||||
|
OVERRIDE_DEFAULT_COMPILER = 0
|
||||||
|
endif
|
||||||
|
|
||||||
|
OS=$(shell uname -s)
|
||||||
|
ifeq ($(findstring CYGWIN,$(OS)),CYGWIN)
|
||||||
|
BUILD_OS = w
|
||||||
|
TARGET_OS = w
|
||||||
|
TARGET_OS_LONG = windows
|
||||||
|
else
|
||||||
|
ifeq ($(OS),Darwin)
|
||||||
|
BUILD_OS = m
|
||||||
|
TARGET_OS = m
|
||||||
|
TARGET_OS_LONG = mac
|
||||||
|
else
|
||||||
|
ifeq ($(OS),FreeBSD)
|
||||||
|
BUILD_OS = b
|
||||||
|
TARGET_OS = b
|
||||||
|
TARGET_OS_LONG = bsd
|
||||||
|
else
|
||||||
|
BUILD_OS = l
|
||||||
|
TARGET_OS = l
|
||||||
|
TARGET_OS_LONG = linux
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
|
||||||
|
# Attach-Detach tests are not supported on all OSes
|
||||||
|
# ATTACH feature is not supported on 2.4 because there is no /proc/pid/task
|
||||||
|
# on this system that gives the list of threads
|
||||||
|
|
||||||
|
# Linux kernel 2.6.18-1.2798.fc6 has a bug in ptrace_detach which don't reset single-step flag
|
||||||
|
|
||||||
|
OSREL=$(shell uname -r)
|
||||||
|
NO_ATTACH_TESTS_OS = 2.4
|
||||||
|
|
||||||
|
ATTACH_SUPPORTED = yes
|
||||||
|
DETACH_SUPPORTED = yes
|
||||||
|
|
||||||
|
ifeq ($(findstring $(NO_ATTACH_TESTS_OS),$(OSREL)),$(NO_ATTACH_TESTS_OS))
|
||||||
|
ATTACH_SUPPORTED = no
|
||||||
|
endif
|
||||||
|
|
||||||
|
|
||||||
|
PIN = $(PIN_NOFLAGS) $(PIN_TEST_FLAGS)
|
||||||
|
PIN_TEST_FLAGS = -slow_asserts $(VIRT_SEG_FLAG) $(PIN_FLAGS) $(PIN_USERFLAGS)
|
||||||
|
|
||||||
|
ifeq (${KIT},0)
|
||||||
|
|
||||||
|
#
|
||||||
|
# Building out of a source tree
|
||||||
|
#
|
||||||
|
|
||||||
|
ifeq (${TARGET},ia32e)
|
||||||
|
TARGET_EXT = ia32_intel64
|
||||||
|
else
|
||||||
|
TARGET_EXT = $(TARGET_LONG)
|
||||||
|
endif
|
||||||
|
|
||||||
|
# If you are building out of a source tree and not a kit
|
||||||
|
# point this to the charm directory
|
||||||
|
PIN_ROOT ?= ../..
|
||||||
|
|
||||||
|
# XED put its files in a directory according to the compiler, use ICCPIN=1 to indicate
|
||||||
|
# that pin was built by ICC
|
||||||
|
ifneq ($(ICCPIN),)
|
||||||
|
XEDKIT = $(PIN_ROOT)/build/Source/xed/xed-icc-pin-$(TARGET_OS_LONG)-$(TARGET_LONG)/xed2-kit
|
||||||
|
else
|
||||||
|
XEDKIT = $(PIN_ROOT)/build/Source/xed/xed-gcc-pin-$(TARGET_OS_LONG)-$(TARGET_LONG)/xed2-kit
|
||||||
|
endif
|
||||||
|
|
||||||
|
APP_CXXFLAGS += -I$(PIN_ROOT)/Source/fund/00-export-include -I$(PIN_ROOT)/Source/util/00-export-include
|
||||||
|
APP_CXXFLAGS2 += -I$(PIN_ROOT)/Source/fund/00-export-include -I$(PIN_ROOT)/Source/util/00-export-include
|
||||||
|
|
||||||
|
PIN_CXXFLAGS += -I$(XEDKIT)/include \
|
||||||
|
-I$(PIN_ROOT)/Source/fund/00-export-include -I$(PIN_ROOT)/Source/util/00-export-include \
|
||||||
|
-I$(PIN_ROOT)/build/Source/pin/pin-W-X-Y-$(TARGET_EXT)-$(TARGET_OS_LONG)/source/include/gen \
|
||||||
|
-I$(PIN_ROOT)/build/Source/pin/pin-W-X-Y-$(TARGET_EXT)-$(TARGET_OS_LONG)/source/include \
|
||||||
|
-I$(PIN_ROOT)/build/Source/pin/pin-W-X-Y-$(TARGET_EXT)-$(TARGET_OS_LONG)/source/include/pin/gen \
|
||||||
|
-I$(PIN_ROOT)/build/Source/pin/pin-W-X-Y-$(TARGET_EXT)-$(TARGET_OS_LONG)/source/include/pin
|
||||||
|
|
||||||
|
# When cross-building an ia32 tool on an ia32e host, the Pin headers could be in either of two possible places.
|
||||||
|
# If only the ia32 Pin kit was built, the headers are in the location specified above. However, if the combined
|
||||||
|
# Pin kit was built, they are in the location specified below.
|
||||||
|
ifeq (${TARGET}-${HOST_ARCH},ia32-ia32e)
|
||||||
|
PIN_CXXFLAGS += -I$(PIN_ROOT)/build/Source/pin/pin-W-X-Y-ia32_intel64-$(TARGET_OS_LONG)/source/include/gen \
|
||||||
|
-I$(PIN_ROOT)/build/Source/pin/pin-W-X-Y-ia32_intel64-$(TARGET_OS_LONG)/source/include \
|
||||||
|
-I$(PIN_ROOT)/build/Source/pin/pin-W-X-Y-ia32_intel64-$(TARGET_OS_LONG)/source/include/pin/gen \
|
||||||
|
-I$(PIN_ROOT)/build/Source/pin/pin-W-X-Y-ia32_intel64-$(TARGET_OS_LONG)/source/include/pin
|
||||||
|
endif
|
||||||
|
|
||||||
|
TARGET_SPEC = ${TARGET}_${TARGET_OS}${TARGET_OFORMAT}
|
||||||
|
PIN_LPATHS += -L$(PIN_ROOT)/build/Source/pin/pin-${TARGET_OS_LONG}-${TARGET_LONG} \
|
||||||
|
-L$(PIN_ROOT)/External/Libdwarf/Lib_${TARGET_SPEC} \
|
||||||
|
-L$(PIN_ROOT)/External/Libelf/Lib_${TARGET_SPEC} \
|
||||||
|
-L$(XEDKIT)/lib
|
||||||
|
PIN_LIBNAMES = $(PIN_ROOT)/build/Source/pin/pin-${TARGET_OS_LONG}-${TARGET_LONG}/libpin.a
|
||||||
|
|
||||||
|
PINDB = $(PIN_ROOT)/build/Source/pindb/export-${TARGET_OS_LONG}-${TARGET_LONG}/pindb
|
||||||
|
PINDB_LIBPATH =
|
||||||
|
PINDB_WITH_LIBPATH = $(PINDB)
|
||||||
|
|
||||||
|
ifeq (${TARGET_OS_LONG}-${TARGET_LONG},linux-ia32)
|
||||||
|
PIN_EXE = $(PIN_ROOT)/Source/pin/pin-runner-linux-ia32.sh
|
||||||
|
else
|
||||||
|
ifeq (${TARGET_OS_LONG}-${TARGET_LONG},linux-intel64)
|
||||||
|
PIN_EXE = $(PIN_ROOT)/Source/pin/pin-runner-linux-intel64.sh
|
||||||
|
else
|
||||||
|
PIN_EXE = $(PIN_ROOT)/build/Source/pin/pin-${TARGET_OS_LONG}-${TARGET_LONG}/pin
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
PIN_NOFLAGS = $(PIN_EXE)
|
||||||
|
|
||||||
|
TAIPIN = $(PIN_ROOT)/build/Source/idbpin/export-$(TARGET_OS_LONG)-$(TARGET_LONG)/libtaipin.so
|
||||||
|
IDBKIT =$(PIN_ROOT)/External/idb/idb-$(TARGET_OS_LONG)-$(TARGET_LONG).tar.gz
|
||||||
|
|
||||||
|
OVERRIDE_DEFAULT_COMPILER = 1
|
||||||
|
|
||||||
|
VSCRIPT_DIR = $(PIN_HOME)/Include/
|
||||||
|
else
|
||||||
|
|
||||||
|
#
|
||||||
|
# Building out of a kit
|
||||||
|
#
|
||||||
|
PIN_KIT ?= ../../..
|
||||||
|
|
||||||
|
ifeq (${TARGET_OS},l)
|
||||||
|
TARGET_OS_LONG=linux
|
||||||
|
endif
|
||||||
|
ifeq (${TARGET_OS},m)
|
||||||
|
TARGET_OS_LONG=mac
|
||||||
|
endif
|
||||||
|
ifeq (${TARGET_OS},w)
|
||||||
|
TARGET_OS_LONG=windows
|
||||||
|
endif
|
||||||
|
ifeq (${TARGET_OS},b)
|
||||||
|
TARGET_OS_LONG=bsd
|
||||||
|
endif
|
||||||
|
|
||||||
|
PIN_EXE = $(PIN_KIT)/$(TARGET_LONG)/bin/pinbin
|
||||||
|
PIN_NOFLAGS = $(PIN_KIT)/pin
|
||||||
|
PINDB = $(PIN_KIT)/$(TARGET_LONG)/bin/pindb
|
||||||
|
PINDB_LIBPATH = $(PIN_KIT)/$(TARGET_LONG)/runtime
|
||||||
|
PINDB_WITH_LIBPATH = LD_LIBRARY_PATH=$(PINDB_LIBPATH):$$LD_LIBRARY_PATH $(PINDB)
|
||||||
|
TAIPIN = $(PIN_KIT)/$(TARGET_LONG)/bin/libtaipin.so
|
||||||
|
|
||||||
|
XEDKIT = $(PIN_KIT)/extras/xed2-$(TARGET_LONG)
|
||||||
|
PIN_LPATHS += -L$(XEDKIT)/lib -L$(PIN_KIT)/$(TARGET_LONG)/lib -L$(PIN_KIT)/$(TARGET_LONG)/lib-ext
|
||||||
|
PIN_CXXFLAGS += -I$(XEDKIT)/include -I$(PIN_KIT)/extras/components/include \
|
||||||
|
-I$(PIN_KIT)/source/include -I$(PIN_KIT)/source/include/gen \
|
||||||
|
-I$(PIN_KIT)/source/include/pin -I$(PIN_KIT)/source/include/pin/gen
|
||||||
|
VSCRIPT_DIR = $(PIN_KIT)/source/include/pin
|
||||||
|
|
||||||
|
APP_CXXFLAGS += -I$(PIN_KIT)/extras/components/include
|
||||||
|
APP_CXXFLAGS2 += -I$(PIN_KIT)/extras/components/include
|
||||||
|
|
||||||
|
endif
|
||||||
|
|
||||||
|
ifndef ICC
|
||||||
|
ifdef ICCVER
|
||||||
|
$(error ignoring ICCVER since ICC is not defined)
|
||||||
|
endif
|
||||||
|
ICCVER =
|
||||||
|
ICC =
|
||||||
|
else
|
||||||
|
ICC = 1
|
||||||
|
ifndef ICCVER
|
||||||
|
ICCVER = 11
|
||||||
|
endif
|
||||||
|
|
||||||
|
#Define ICCDIR according to ICCVER
|
||||||
|
ifeq ($(ICCVER), 10)
|
||||||
|
endif
|
||||||
|
ifeq ($(ICCVER), 11)
|
||||||
|
ICCDIR_32E = /usr/intel/pkgs/icc/11.1.046e/bin/intel64
|
||||||
|
ICCDIR_32 = /usr/intel/pkgs/icc/11.1.046/bin/ia32
|
||||||
|
endif
|
||||||
|
|
||||||
|
ifndef ICCDIR_32
|
||||||
|
$(error ICCDIR_32 is not defined, define ICCDIR_32 on the command line or define valid ICCVER)
|
||||||
|
endif
|
||||||
|
ifeq (${TARGET},ia32e)
|
||||||
|
ifndef ICCDIR_32E
|
||||||
|
$(error ICCDIR_32E is not defined, define ICCDIR_32E on the command line or define valid ICCVER)
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
|
||||||
|
|
||||||
|
ifeq ($(ICC),1)
|
||||||
|
ifeq ($(GCCVER),)
|
||||||
|
GCCVER = 4.3.1
|
||||||
|
endif
|
||||||
|
ifeq (${TARGET},ia32e)
|
||||||
|
ICCDIR = $(ICCDIR_32E)
|
||||||
|
else
|
||||||
|
ICCDIR = $(ICCDIR_32)
|
||||||
|
endif
|
||||||
|
CXX = $(ICCDIR)/icpc
|
||||||
|
CC = $(ICCDIR)/icc
|
||||||
|
COMPARE_EXT = compareICC
|
||||||
|
|
||||||
|
# When compiling with ICC, we need to add reference to GCC version.
|
||||||
|
ICC_FLAGS = -gcc-version=430 -i_static -Wl,-rpath=/usr/intel/pkgs/gcc/$(GCCVER)/lib
|
||||||
|
ICC_FLAGS += -Qlocation,gld,/usr/intel/pkgs/gcc/$(GCCVER)/bin
|
||||||
|
ICC_FLAGS += -gcc-name=/usr/intel/pkgs/gcc/$(GCCVER)/bin/gcc
|
||||||
|
ICC_FLAGS += -gxx-name=/usr/intel/pkgs/gcc/$(GCCVER)/bin/g++
|
||||||
|
|
||||||
|
# Enable ICC optimizations
|
||||||
|
# ICC splits the called function into 2 different funcs - the actual func that using nonconventional
|
||||||
|
# calling standard (args passed in regs), and a func which handle standard calling convention (pass
|
||||||
|
# args to regs). Pin is trying to change the last func. To avoid this we disable inter-procedural
|
||||||
|
# optimizations. Maybe in ICC 12 we could use -opt-args-in-reg=none
|
||||||
|
ICC_FLAGS += -O2 -fno-inline -no-ip
|
||||||
|
OPT =
|
||||||
|
|
||||||
|
# Add ICC flags to all compilation and linkage flags
|
||||||
|
APP_CXXLINK_FLAGS += $(ICC_FLAGS)
|
||||||
|
APP_CXXFLAGS += $(ICC_FLAGS) -fno-inline
|
||||||
|
PIN_LDFLAGS += $(ICC_FLAGS)
|
||||||
|
PIN_CXXFLAGS += $(ICC_FLAGS)
|
||||||
|
|
||||||
|
# Disable warnings
|
||||||
|
PIN_CXXFLAGS += -wd1418 -wd1419 -wd981 -wd383 -wd869 -wd593 -wd266 -wd279 -wd444 -wd168 -wd810 -wd810 -wd181
|
||||||
|
PIN_CXXFLAGS += -wd1195 -wd168 -wd193
|
||||||
|
endif
|
||||||
|
|
||||||
|
# No effect on GNU linkers, relevant to MS tools
|
||||||
|
APP_CXXLINK_FLAGS_NORANDOM = $(APP_CXXLINK_FLAGS)
|
||||||
|
|
||||||
|
ifeq ($(OVERRIDE_DEFAULT_COMPILER),1)
|
||||||
|
# We override CXX only if it is the default one from Make.
|
||||||
|
# Environment overrides of CXX take precidence.
|
||||||
|
|
||||||
|
ifeq ($(TARGET),ipf)
|
||||||
|
ifeq ($(origin CXX), default)
|
||||||
|
CXX = /usr/intel/pkgs/gcc/3.4/bin/g++
|
||||||
|
endif
|
||||||
|
ifeq ($(origin CC), default)
|
||||||
|
CC = /usr/intel/pkgs/gcc/3.4/bin/gcc
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
|
||||||
|
ifeq ($(TARGET),ia32)
|
||||||
|
ifeq ($(TARGET_OS),l)
|
||||||
|
ifeq ($(origin CC), default)
|
||||||
|
CC = /usr/intel/pkgs/gcc/4.3.1/bin/gcc
|
||||||
|
endif
|
||||||
|
ifeq ($(origin CXX), default)
|
||||||
|
CXX = /usr/intel/pkgs/gcc/4.3.1/bin/g++
|
||||||
|
endif
|
||||||
|
else
|
||||||
|
ifeq ($(TARGET_OS),b)
|
||||||
|
ifeq ($(origin CC), default)
|
||||||
|
CC = /usr/local/bin/gcc43
|
||||||
|
endif
|
||||||
|
ifeq ($(origin CXX), default)
|
||||||
|
CXX = /usr/local/bin/g++43
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
|
||||||
|
ifeq ($(TARGET),ia32e)
|
||||||
|
ifeq ($(TARGET_OS),l)
|
||||||
|
ifeq ($(origin CXX), default)
|
||||||
|
CXX = /usr/intel/pkgs/gcc/4.3.1/bin/g++
|
||||||
|
endif
|
||||||
|
ifeq ($(origin CC), default)
|
||||||
|
CC = /usr/intel/pkgs/gcc/4.3.1/bin/gcc
|
||||||
|
endif
|
||||||
|
else
|
||||||
|
ifeq ($(TARGET_OS),b)
|
||||||
|
ifeq ($(origin CC), default)
|
||||||
|
CC = /usr/local/bin/gcc43
|
||||||
|
endif
|
||||||
|
ifeq ($(origin CXX), default)
|
||||||
|
CXX = /usr/local/bin/g++43
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
|
||||||
|
# Pin-probe runtime doesn't support the new GNU_HASH style
|
||||||
|
# First check if the linker used to build the tools support the flag --hash-style.
|
||||||
|
# In this case set the hash-style to be the old (SYSV) style
|
||||||
|
HELPOUT=$(shell $(CC) -v --help 2>&1)
|
||||||
|
ifneq ($(findstring --hash-style,$(HELPOUT)),)
|
||||||
|
PIN_LDFLAGS += -Wl,--hash-style=sysv
|
||||||
|
endif
|
||||||
|
|
||||||
|
# GLIBC version 2.4 implements the function __stack_chk_fail used by new GCC
|
||||||
|
# versions when stack-protector is on. Therefore, disable this option (if supported)
|
||||||
|
ifneq ($(findstring stack-protector,$(HELPOUT)),)
|
||||||
|
PIN_CXXFLAGS += -fno-stack-protector
|
||||||
|
endif
|
||||||
|
|
||||||
|
|
||||||
|
##############################################################
|
||||||
|
# Set the architecture specific stuff
|
||||||
|
##############################################################
|
||||||
|
|
||||||
|
ifeq ($(TARGET),ia32)
|
||||||
|
|
||||||
|
PIN_CXXFLAGS += -DTARGET_IA32 -DHOST_IA32
|
||||||
|
APP_CXXFLAGS += -DTARGET_IA32 -DFUND_TC_HOSTCPU=FUND_CPU_IA32 -DFUND_TC_TARGETCPU=FUND_CPU_IA32
|
||||||
|
APP_CXXFLAGS2 += -DTARGET_IA32 -DFUND_TC_HOSTCPU=FUND_CPU_IA32 -DFUND_TC_TARGETCPU=FUND_CPU_IA32
|
||||||
|
PIN_BASE_LIBS += -lxed
|
||||||
|
PIN_BASE_LIBS_SA += -lxed
|
||||||
|
#TOOLADDR=--section-start,.interp=0x70008400
|
||||||
|
# The 400 in the address leaves room for the program headers
|
||||||
|
|
||||||
|
ifeq ($(TARGET_OS),m)
|
||||||
|
### TOOLADDR setting for Mac
|
||||||
|
# old value that works with MacOS 10.4.1: 0x50048000
|
||||||
|
# old value that works for SPEC but not gui program: 0x16048000
|
||||||
|
TOOLADDR = -Wl,-seg1addr -Wl,0x84048000
|
||||||
|
PIN_PTHREAD_LIBS = -lpinpthread
|
||||||
|
### FIXMAC: __pthread_mutex_init is not yet redefined
|
||||||
|
#PIN_PTHREAD_LIBS_FLAGS = -Wl,-u,__pthread_mutex_init
|
||||||
|
else
|
||||||
|
### TOOLADDR setting for Linux and Windows
|
||||||
|
TOOLADDR = -Wl,--section-start,.interp=0x06048400
|
||||||
|
PIN_PTHREAD_LIBS = -lpinpthread
|
||||||
|
PIN_PTHREAD_LIBS_FLAGS = -Wl,-u,__pthread_mutex_init
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
|
||||||
|
ifeq ($(TARGET),ia32)
|
||||||
|
ifeq (${HOST_ARCH},ia32e)
|
||||||
|
### IA32 on Intel64 compiler flags
|
||||||
|
PIN_CXXFLAGS += -m32
|
||||||
|
PIN_LDFLAGS += -m32
|
||||||
|
ASLD_FLAGS = -m elf_i386
|
||||||
|
AS_FLAGS = --32
|
||||||
|
TESTAPP = ../Tests/$(OBJDIR)cp-pin
|
||||||
|
APP_CXXFLAGS += -m32
|
||||||
|
APP_CXXFLAGS2 += -m32
|
||||||
|
CC += -m32
|
||||||
|
CXX += -m32
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
|
||||||
|
ifeq ($(TARGET),ia32e)
|
||||||
|
PIN_CXXFLAGS += -DTARGET_IA32E -DHOST_IA32E
|
||||||
|
APP_CXXFLAGS += -DTARGET_IA32E -DFUND_TC_HOSTCPU=FUND_CPU_INTEL64 -DFUND_TC_TARGETCPU=FUND_CPU_INTEL64
|
||||||
|
APP_CXXFLAGS2 += -DTARGET_IA32E -DFUND_TC_HOSTCPU=FUND_CPU_INTEL64 -DFUND_TC_TARGETCPU=FUND_CPU_INTEL64
|
||||||
|
PIN_BASE_LIBS += -lxed
|
||||||
|
PIN_BASE_LIBS_SA += -lxed
|
||||||
|
ifeq ($(TARGET_OS),b)
|
||||||
|
# FreeBSD
|
||||||
|
TOOLADDR = -Wl,--section-start,.interp=0x60000190
|
||||||
|
endif
|
||||||
|
|
||||||
|
ifeq ($(TARGET_OS), m)
|
||||||
|
### TOOLADDR setting for Mac
|
||||||
|
# old value that works with MacOS 10.4.1: 0x50048000
|
||||||
|
# old value that works for SPEC but not gui program: 0x16048000
|
||||||
|
#TOOLADDR = -Wl,-seg1addr -Wl,0x50048000
|
||||||
|
PIN_PTHREAD_LIBS = -lpinpthread
|
||||||
|
### FIXMAC: __pthread_mutex_init is not yet redefined
|
||||||
|
#PIN_PTHREAD_LIBS_FLAGS = -Wl,-u,__pthread_mutex_init
|
||||||
|
else
|
||||||
|
# Linux
|
||||||
|
PIN_PTHREAD_LIBS = -lpinpthread
|
||||||
|
PIN_PTHREAD_LIBS_FLAGS = -Wl,-u,__pthread_mutex_init
|
||||||
|
TOOLADDR = -Wl,--section-start,.interp=0x20048000
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
|
||||||
|
ifeq ($(TARGET),ipf)
|
||||||
|
PIN_CXXFLAGS += -DTARGET_IPF -DHOST_IPF
|
||||||
|
APP_CXXFLAGS += -DTARGET_IPF -DFUND_TC_HOSTCPU=FUND_CPU_IA64 -DFUND_TC_TARGETCPU=FUND_CPU_IA64
|
||||||
|
APP_CXXFLAGS2 += -DTARGET_IPF -DFUND_TC_HOSTCPU=FUND_CPU_IA64 -DFUND_TC_TARGETCPU=FUND_CPU_IA64
|
||||||
|
TOOLADDR = -Wl,--section-start,.interp=0x00000c0000000400,--section-start,.init_array=0x00000e0000000400,-defsym,__init_array_start=0x00000e0000000400,-defsym,__preinit_array_start=__init_array_start,-defsym,__preinit_array_end=__preinit_array_start
|
||||||
|
PIN_PTHREAD_LIBS = -lpinpthread
|
||||||
|
PIN_PTHREAD_LIBS_FLAGS = -Wl,-u,__pthread_mutex_init
|
||||||
|
endif
|
||||||
|
|
||||||
|
##############################################################
|
||||||
|
# Set the OS specific variables
|
||||||
|
# Some of this refers to architecture dependent variables
|
||||||
|
# so this must second
|
||||||
|
##############################################################
|
||||||
|
|
||||||
|
# Select tools to be shared objects on Linux
|
||||||
|
# Use ?= to allow the user to override it in the command line
|
||||||
|
ifeq ($(TARGET_OS),l)
|
||||||
|
SOTOOL ?= 1
|
||||||
|
endif
|
||||||
|
ifeq ($(TARGET_OS),b)
|
||||||
|
SOTOOL ?= 1
|
||||||
|
endif
|
||||||
|
|
||||||
|
ifeq ($(TARGET_OS),w)
|
||||||
|
### Windows
|
||||||
|
|
||||||
|
PIN_CXXFLAGS += -DTARGET_WINDOWS -mno-cygwin
|
||||||
|
|
||||||
|
#FIXME: make this conditional based on the compiler
|
||||||
|
PIN_BASE_LIBS += -lpinvm -lntdll
|
||||||
|
PIN_LDFLAGS += -Wl,--export-all-symbols
|
||||||
|
PIN_LDFLAGS += -shared -Wl,-wrap,atexit,-wrap,_onexit,-e,_Ptrace_DllMainCRTStartup@12 -mno-cygwin
|
||||||
|
PIN_LDFLAGS += -Wl,--image-base -Wl,0x55000000
|
||||||
|
PINTOOL_SUFFIX = .dll
|
||||||
|
ifndef TESTAPP
|
||||||
|
TESTAPP = $(PIN_HOME)/Tests/cp-pin.exe
|
||||||
|
endif
|
||||||
|
APP_CXXFLAGS += -DTARGET_WINDOWS -mno-cygwin -DFUND_TC_HOSTOS=FUND_OS_WINDOWS -DFUND_TC_TARGETOS=FUND_OS_WINDOWS
|
||||||
|
PIN_CMP = cmp
|
||||||
|
PIN_DIFF = diff -w
|
||||||
|
APP_CXXFLAGS2 += -mno-cygwin
|
||||||
|
EXEEXT = .exe
|
||||||
|
OBJEXT = obj
|
||||||
|
else
|
||||||
|
### Linux or Mac or FreeBSD
|
||||||
|
ifeq ($(TARGET_OS),m)
|
||||||
|
PIN_CMP = ../mac-cmp
|
||||||
|
else
|
||||||
|
PIN_CMP = cmp
|
||||||
|
endif
|
||||||
|
PIN_DIFF = ${PIN_CMP}
|
||||||
|
ifeq ($(TARGET_OS),b)
|
||||||
|
# on FreeBSD we currently support only libthr as libpthread uses KSE
|
||||||
|
APP_PTHREAD=-lthr
|
||||||
|
else
|
||||||
|
APP_PTHREAD=-lpthread
|
||||||
|
endif
|
||||||
|
ifndef TESTAPP
|
||||||
|
TESTAPP = /bin/cp
|
||||||
|
endif
|
||||||
|
|
||||||
|
ifeq ($(SOTOOL),1)
|
||||||
|
### Linux or FreeBSD (tool is shared object)
|
||||||
|
|
||||||
|
# on intel64 and ipf shared-objects must be compiled with -fPIC
|
||||||
|
ifneq ($(TARGET),ia32)
|
||||||
|
PIN_CXXFLAGS += -fPIC
|
||||||
|
endif
|
||||||
|
|
||||||
|
ifeq ($(TARGET_OS),l)
|
||||||
|
PIN_CXXFLAGS += -DTARGET_LINUX
|
||||||
|
APP_CXXFLAGS += -DTARGET_LINUX -DFUND_TC_HOSTOS=FUND_OS_LINUX -DFUND_TC_TARGETOS=FUND_OS_LINUX
|
||||||
|
PIN_BASE_LIBS += -ldwarf -lelf ${PIN_DYNAMIC}
|
||||||
|
PIN_BASE_LIBS_SA += -Wl,-Bstatic -ldwarf -lelf -Wl,-Bdynamic ${PIN_DYNAMIC}
|
||||||
|
PIN_SOFLAGS = -shared -Wl,-Bsymbolic -Wl,--version-script=$(VSCRIPT_DIR)/pintool.ver
|
||||||
|
else
|
||||||
|
PIN_CXXFLAGS += -DTARGET_BSD
|
||||||
|
APP_CXXFLAGS += -DTARGET_BSD -DFUND_TC_HOSTOS=FUND_OS_BSD -DFUND_TC_TARGETOS=FUND_OS_BSD
|
||||||
|
PIN_BASE_LIBS += -ldwarf -lelf
|
||||||
|
PIN_BASE_LIBS_SA += -ldwarf -lelf
|
||||||
|
PIN_SOFLAGS = -shared -Wl,-Bsymbolic -Wl,--version-script=$(VSCRIPT_DIR)/pintool.ver
|
||||||
|
endif
|
||||||
|
|
||||||
|
# shared object tool don't need TOOLADDR
|
||||||
|
TOOLADDR =
|
||||||
|
PINTOOL_SUFFIX=.so
|
||||||
|
SATOOL_SUFFIX=
|
||||||
|
EXEEXT=
|
||||||
|
OBJEXT=o
|
||||||
|
PIN_SALDFLAGS := $(PIN_LDFLAGS)
|
||||||
|
PIN_LDFLAGS += $(PIN_SOFLAGS)
|
||||||
|
else
|
||||||
|
### Linux or Mac or FreeBSD (tool is executable)
|
||||||
|
|
||||||
|
ifeq ($(TARGET_OS),l)
|
||||||
|
### Linux
|
||||||
|
PIN_BASE_LIBS += -ldwarf -lelf ${PIN_DYNAMIC}
|
||||||
|
PIN_BASE_LIBS_SA += -Wl,-Bstatic -ldwarf -lelf -Wl,-Bdynamic ${PIN_DYNAMIC}
|
||||||
|
PIN_CXXFLAGS += -DTARGET_LINUX
|
||||||
|
PIN_LDFLAGS += -Wl,-u,malloc
|
||||||
|
APP_CXXFLAGS += -DTARGET_LINUX -DFUND_TC_HOSTOS=FUND_OS_LINUX -DFUND_TC_TARGETOS=FUND_OS_LINUX
|
||||||
|
else
|
||||||
|
ifeq ($(TARGET_OS),b)
|
||||||
|
### FreeBSD
|
||||||
|
PIN_BASE_LIBS += -ldwarf -lelf
|
||||||
|
PIN_BASE_LIBS_SA += -ldwarf -lelf
|
||||||
|
PIN_CXXFLAGS += -DTARGET_BSD
|
||||||
|
PIN_LDFLAGS += -Wl,-u,malloc
|
||||||
|
APP_CXXFLAGS += -DTARGET_BSD -DFUND_TC_HOSTOS=FUND_OS_BSD -DFUND_TC_TARGETOS=FUND_OS_BSD
|
||||||
|
else
|
||||||
|
ifeq ($(TARGET_OS),m)
|
||||||
|
### Mac
|
||||||
|
# This enables the thread safe libc by pulling in pthread.o from libpinpthread.a
|
||||||
|
# Otherwise, you will get the non threadsafe version from libc
|
||||||
|
# It also pulls in malloc_st.o by using malloc
|
||||||
|
|
||||||
|
PIN_BASE_LIBS += $(PIN_PTHREAD_LIBS) ${PIN_DYNAMIC}
|
||||||
|
PIN_LDFLAGS += $(PIN_PTHREAD_LIBS_FLAGS)
|
||||||
|
|
||||||
|
# The -lpinpthreads library refers to symbols in -lpin / -lsapin, so
|
||||||
|
# add them a second time on the link line.
|
||||||
|
PIN_BASE_LIBS_MAC = -lpin
|
||||||
|
PIN_BASE_LIBS_MAC_SA = -lsapin
|
||||||
|
|
||||||
|
# Suppress linker warnings
|
||||||
|
#PIN_LPATHS += -L$(PIN_KIT)/extras/components/lib/$(TARGET_LONG)/ -L$(PIN_KIT)/extras/xed2-$(TARGET_LONG)/lib/ -L$(PIN_KIT)/$(TARGET_LONG)/lib/ -L$(PIN_KIT)/$(TARGET_LONG)/lib-ext/
|
||||||
|
PIN_LDFLAGS += -stdlib=libstdc++ -shared -w -exported_symbols_list $(PIN_KIT)/source/include/pin/pintool.exp
|
||||||
|
PIN_CXXFLAGS += -DTARGET_MAC -stdlib=libstdc++ -I$(PIN_KIT)/extras/xed-$(TARGET_LONG)/include
|
||||||
|
APP_CXXFLAGS += -DTARGET_MAC -DFUND_TC_HOSTOS=FUND_OS_MAC -DFUND_TC_TARGETOS=FUND_OS_MAC
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
|
||||||
|
PIN_SALDFLAGS := $(PIN_LDFLAGS) # static analysis tools don't need TOOLADDR
|
||||||
|
PIN_LDFLAGS += ${TOOLADDR}
|
||||||
|
#####PINTOOL_SUFFIX =
|
||||||
|
PINTOOL_SUFFIX=.so
|
||||||
|
SATOOL_SUFFIX =
|
||||||
|
EXEEXT =
|
||||||
|
OBJEXT = o
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
|
||||||
|
ifeq ($(PIN_PIE),1)
|
||||||
|
ifneq ($(SOTOOL),1)
|
||||||
|
PIN_CXXFLAGS += -fPIE
|
||||||
|
PIN_LDFLAGS += -pie -Wl,-Bsymbolic
|
||||||
|
TOOLADDR =
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
|
||||||
|
SAPIN_LIBS = -lsapin $(PIN_BASE_LIBS_SA) $(PIN_BASE_LIBS_MAC_SA)
|
||||||
|
PIN_LIBS = -lpin $(PIN_BASE_LIBS) $(PIN_BASE_LIBS_MAC)
|
||||||
|
|
||||||
|
##############################################################
|
||||||
|
# Some final variables
|
||||||
|
##############################################################
|
||||||
|
|
||||||
|
# put the lpaths before all the libs
|
||||||
|
PIN_LDFLAGS += ${PIN_LPATHS}
|
||||||
|
PIN_CXXFLAGS_NOOPT := $(PIN_CXXFLAGS)
|
||||||
|
PIN_CXXFLAGS += $(OPT)
|
||||||
|
NO_OPTIMIZE = -O0
|
||||||
|
COPT = -c
|
||||||
|
OUTOPT = -o
|
||||||
|
OUTEXE = -o
|
||||||
|
LINK_OUT = -o
|
||||||
|
|
||||||
|
MYOBJDIR = obj-comm/
|
||||||
|
OBJDIR = obj-pin/
|
||||||
|
PYTHON = python
|
||||||
|
|
||||||
|
##############################################################
|
||||||
|
# Rules to make testing easier
|
||||||
|
# This testing only checks that the application ran correctly.
|
||||||
|
# It does no checking of the results of the tool.
|
||||||
|
# If you make the tool self checking and exit with a non zero exit code,
|
||||||
|
# then it will detect the error
|
||||||
|
# Before the test, we make a .tested and a .failed file. If
|
||||||
|
# the test succeeds, we remove the .failed file.
|
||||||
|
# find . -name '*.tested'
|
||||||
|
# and
|
||||||
|
# find . -name '*.failed'
|
||||||
|
# will summarize what you tested and what failed
|
||||||
|
##############################################################
|
||||||
|
%.test: $(OBJDIR)
|
||||||
|
|
||||||
|
%$(PINTOOL_SUFFIX).test : $(OBJDIR)%$(PINTOOL_SUFFIX) %.tested %.failed
|
||||||
|
touch $<.makefile.copy; rm $<.makefile.copy
|
||||||
|
$(PIN) -t $< -- $(TESTAPP) makefile $<.makefile.copy
|
||||||
|
$(PIN_CMP) makefile $<.makefile.copy
|
||||||
|
rm $<.makefile.copy; rm $(@:$(PINTOOL_SUFFIX).test=.failed)
|
||||||
|
|
||||||
|
# Some subdirectories do not want the $(PINTOOL_SUFFIX) in their test name.
|
||||||
|
%.test : $(OBJDIR)%$(PINTOOL_SUFFIX) %.tested %.failed
|
||||||
|
touch $<.makefile.copy; rm $<.makefile.copy
|
||||||
|
$(PIN) -t $< -- $(TESTAPP) makefile $<.makefile.copy
|
||||||
|
$(PIN_CMP) makefile $<.makefile.copy
|
||||||
|
rm $<.makefile.copy; rm $(@:.test=.failed)
|
||||||
|
|
||||||
|
|
||||||
|
%.tested :
|
||||||
|
touch $@
|
||||||
|
|
||||||
|
%.failed :
|
||||||
|
touch $@
|
||||||
|
|
||||||
|
# otherwise these are deleted if the tool build fails
|
||||||
|
.PRECIOUS : %.tested %.failed
|
||||||
|
|
||||||
|
all:
|
||||||
|
|
||||||
|
.PHONY: dir mydir
|
||||||
|
dir:
|
||||||
|
mkdir -p $(OBJDIR)
|
||||||
|
mydir:
|
||||||
|
mkdir -p $(MYOBJDIR)
|
|
@ -0,0 +1,73 @@
|
||||||
|
PIN_KIT ?=/home/rajshekar/softwares/pin-97554/
|
||||||
|
CXX=$(shell make PIN_ROOT=$(PIN_KIT) VAR=CXX -f pin_makefile print_var)
|
||||||
|
LINKER=$(shell make PIN_ROOT=$(PIN_KIT) VAR=LINKER -f pin_makefile print_var)
|
||||||
|
TOOL_CXXFLAGS=$(shell make PIN_ROOT=$(PIN_KIT) VAR=TOOL_CXXFLAGS -f pin_makefile print_var)
|
||||||
|
TOOL_LDFLAGS=$(shell make PIN_ROOT=$(PIN_KIT) VAR=TOOL_LDFLAGS -f pin_makefile print_var)
|
||||||
|
TOOL_LPATHS=$(shell make PIN_ROOT=$(PIN_KIT) VAR=TOOL_LPATHS -f pin_makefile print_var)
|
||||||
|
TOOL_LIBS=$(shell make PIN_ROOT=$(PIN_KIT) VAR=TOOL_LIBS -f pin_makefile print_var)
|
||||||
|
APP_CXXFLAGS=$(shell make PIN_ROOT=$(PIN_KIT) VAR=APP_CXXFLAGS -f pin_makefile print_var)
|
||||||
|
APP_LDFLAGS=$(shell make PIN_ROOT=$(PIN_KIT) VAR=APP_LDFLAGS -f pin_makefile print_var)
|
||||||
|
APP_LPATHS=$(shell make PIN_ROOT=$(PIN_KIT) VAR=APP_LPATHS -f pin_makefile print_var)
|
||||||
|
APP_LIBS=$(shell make PIN_ROOT=$(PIN_KIT) VAR=APP_LIBS -f pin_makefile print_var)
|
||||||
|
|
||||||
|
TOPDIR = $(shell pwd)/../../simulator/
|
||||||
|
COMMDIR = $(TOPDIR)emulatorinterface/communication
|
||||||
|
COMM_INCLUDE = -I$(COMMDIR) -I$(COMMDIR)/shm -I$(COMMDIR)/filePacket
|
||||||
|
TOPBINDIR = $(shell pwd)/../../../bin/
|
||||||
|
JNIBINDIR=obj-comm
|
||||||
|
BINDIR=obj-pin
|
||||||
|
|
||||||
|
dummy=$(shell mkdir $(JNIBINDIR))
|
||||||
|
dummy=$(shell mkdir $(BINDIR))
|
||||||
|
|
||||||
|
LIB_EXTENSION=
|
||||||
|
OBJ_EXTENSION=
|
||||||
|
FLAGS_FOR_ZLIB=
|
||||||
|
POSITION_INDEPENDENCE=
|
||||||
|
ifeq ($(OS),Windows_NT)
|
||||||
|
LIB_EXTENSION=dll
|
||||||
|
OBJ_EXTENSION=obj
|
||||||
|
FLAGS_FOR_ZLIB=
|
||||||
|
POSITION_INDEPENDENCE=
|
||||||
|
else
|
||||||
|
LIB_EXTENSION=so
|
||||||
|
OBJ_EXTENSION=o
|
||||||
|
FLAGS_FOR_ZLIB=
|
||||||
|
POSITION_INDEPENDENCE=-fPIC
|
||||||
|
endif
|
||||||
|
|
||||||
|
JNICOMMAND=
|
||||||
|
ifeq ($(OS),Windows_NT)
|
||||||
|
JNICOMMAND=cl.exe /O2 $(JNINCLUDE) -LD $(COMMDIR)/shm/JNIShm.c -Fe$(JNIBINDIR)/libshmlib.$(LIB_EXTENSION)
|
||||||
|
else
|
||||||
|
JNICOMMAND=$(CC) -I$(JNIBINDIR) $(JNILinkingFlags) $(COMMDIR)/shm/JNIShm.c $(JNINCLUDE) -o $(JNIBINDIR)/libshmlib.$(LIB_EXTENSION)
|
||||||
|
endif
|
||||||
|
|
||||||
|
all: $(BINDIR)/causalityTool.$(LIB_EXTENSION) $(JNIBINDIR)/libshmlib.$(LIB_EXTENSION)
|
||||||
|
|
||||||
|
$(BINDIR)/causalityTool.$(LIB_EXTENSION): $(BINDIR)/causalityTool.$(OBJ_EXTENSION) $(BINDIR)/shmem.$(OBJ_EXTENSION)
|
||||||
|
$(LINKER) $(TOOL_LDFLAGS) -o $(BINDIR)/causalityTool.$(LIB_EXTENSION) $(BINDIR)/causalityTool.$(OBJ_EXTENSION) $(BINDIR)/shmem.$(OBJ_EXTENSION) $(FLAGS_FOR_ZLIB) $(TOOL_LPATHS) $(TOOL_LIBS)
|
||||||
|
|
||||||
|
$(BINDIR)/causalityTool.$(OBJ_EXTENSION): causalityTool.cpp $(COMMDIR)/IPCBase.h $(COMMDIR)/shm/shmem.h $(COMMDIR)/filePacket/filePacket.h $(COMMDIR)/shm/shmem.cc
|
||||||
|
$(CXX) $(TOOL_CXXFLAGS) $(COMM_INCLUDE) -c causalityTool.cpp ../../simulator/emulatorinterface/communication/shm/shmem.cc
|
||||||
|
mv causalityTool.$(OBJ_EXTENSION) $(BINDIR)/causalityTool.$(OBJ_EXTENSION)
|
||||||
|
mv shmem.$(OBJ_EXTENSION) $(BINDIR)/shmem.$(OBJ_EXTENSION)
|
||||||
|
|
||||||
|
$(BINDIR)/shmem.$(OBJ_EXTENSION): $(COMMDIR)/IPCBase.h $(COMMDIR)/shm/shmem.h $(COMMDIR)/shm/shmem.cc
|
||||||
|
$(CXX) $(POSITION_INDEPENDENCE) $(APP_CXXFLAGS) -c ../../simulator/emulatorinterface/communication/shm/shmem.cc -o $(BINDIR)/shmem.$(OBJ_EXTENSION)
|
||||||
|
|
||||||
|
|
||||||
|
################################ JNI stuff comes here ############################################
|
||||||
|
JNIPACKAGE = emulatorinterface.communication.shm.SharedMem
|
||||||
|
JNINCLUDE =-I/usr/lib/jvm/java-8-openjdk-amd64/include/linux -I/usr/lib/jvm/java-8-openjdk-amd64/include
|
||||||
|
JNILinkingFlags = -shared -Wall $(POSITION_INDEPENDENCE)
|
||||||
|
JAVAH = javah -jni
|
||||||
|
|
||||||
|
$(JNIBINDIR)/libshmlib.$(LIB_EXTENSION): $(JNIBINDIR)/SharedMem.h $(COMMDIR)/shm/JNIShm.c $(COMMDIR)/common.h
|
||||||
|
$(shell $(JNICOMMAND))
|
||||||
|
|
||||||
|
$(JNIBINDIR)/SharedMem.h: $(TOPBINDIR)/emulatorinterface/communication/shm/SharedMem.class
|
||||||
|
$(JAVAH) -classpath $(TOPBINDIR) -o $(JNIBINDIR)/SharedMem.h $(JNIPACKAGE)
|
||||||
|
|
||||||
|
clean:
|
||||||
|
rm -rf $(BINDIR)/* $(JNIBINDIR)/*
|
|
@ -0,0 +1,25 @@
|
||||||
|
##############################################################
|
||||||
|
#
|
||||||
|
# DO NOT EDIT THIS FILE!
|
||||||
|
#
|
||||||
|
##############################################################
|
||||||
|
|
||||||
|
# If the tool is built out of the kit, PIN_ROOT must be specified in the make invocation and point to the kit root.
|
||||||
|
ifdef PIN_ROOT
|
||||||
|
CONFIG_ROOT := $(PIN_ROOT)/source/tools/Config
|
||||||
|
else
|
||||||
|
CONFIG_ROOT := ../Config
|
||||||
|
endif
|
||||||
|
include $(CONFIG_ROOT)/makefile.config
|
||||||
|
#include makefile.rules
|
||||||
|
include $(TOOLS_ROOT)/Config/makefile.default.rules
|
||||||
|
|
||||||
|
print_var:
|
||||||
|
@echo $($(VAR))
|
||||||
|
|
||||||
|
|
||||||
|
##############################################################
|
||||||
|
#
|
||||||
|
# DO NOT EDIT THIS FILE!
|
||||||
|
#
|
||||||
|
##############################################################
|
|
@ -0,0 +1,278 @@
|
||||||
|
#include <iostream>
|
||||||
|
#include <fstream>
|
||||||
|
#include "pin.H"
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <sys/shm.h>
|
||||||
|
#include <cstdlib>
|
||||||
|
#include <cstring>
|
||||||
|
#include <sched.h>
|
||||||
|
#include <sys/time.h>
|
||||||
|
#include <sys/resource.h>
|
||||||
|
#include <time.h>
|
||||||
|
#include <sys/timeb.h>
|
||||||
|
|
||||||
|
#include "IPCBase.h"
|
||||||
|
#include "shmem.h"
|
||||||
|
|
||||||
|
#include "encoding.h"
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef _LP64
|
||||||
|
#define MASK 0xffffffffffffffff
|
||||||
|
#else
|
||||||
|
#define MASK 0x00000000ffffffff
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Defining command line arguments
|
||||||
|
KNOB<UINT64> KnobLong(KNOB_MODE_WRITEONCE, "pintool",
|
||||||
|
"map", "1", "Maps");
|
||||||
|
|
||||||
|
PIN_LOCK lock;
|
||||||
|
INT32 numThreads = 0;
|
||||||
|
UINT64 checkSum = 0;
|
||||||
|
IPC::IPCBase *tst;
|
||||||
|
|
||||||
|
|
||||||
|
// needs -lrt (real-time lib)
|
||||||
|
// 1970-01-01 epoch UTC time, 1 nanosecond resolution
|
||||||
|
uint64_t ClockGetTime()
|
||||||
|
{
|
||||||
|
timespec ts;
|
||||||
|
clock_gettime(CLOCK_REALTIME, &ts);
|
||||||
|
return (uint64_t)ts.tv_sec * 1000000000LL + (uint64_t)ts.tv_nsec;
|
||||||
|
}
|
||||||
|
|
||||||
|
#define cmp(a) (rtn_name->find(a) != string::npos)
|
||||||
|
|
||||||
|
|
||||||
|
VOID ThreadStart(THREADID threadid, CONTEXT *ctxt, INT32 flags, VOID *v)
|
||||||
|
{
|
||||||
|
GetLock(&lock, threadid+1);
|
||||||
|
numThreads++;
|
||||||
|
printf("threads till now %d\n",numThreads);
|
||||||
|
fflush(stdout);
|
||||||
|
ReleaseLock(&lock);
|
||||||
|
ASSERT(numThreads <= MaxNumThreads, "Maximum number of threads exceeded\n");
|
||||||
|
|
||||||
|
/*tst->onThread_start(threadid);*/
|
||||||
|
}
|
||||||
|
|
||||||
|
VOID ThreadFini(THREADID tid,const CONTEXT *ctxt, INT32 flags, VOID *v)
|
||||||
|
{
|
||||||
|
/* while (tst->onThread_finish(tid)==-1) {
|
||||||
|
PIN_Yield();
|
||||||
|
}*/
|
||||||
|
}
|
||||||
|
|
||||||
|
//Pass a memory read record
|
||||||
|
VOID RecordMemRead(THREADID tid,VOID * ip, VOID * addr)
|
||||||
|
{
|
||||||
|
checkSum+=MEMREAD;
|
||||||
|
/* uint64_t nip = MASK & (uint64_t)ip;
|
||||||
|
uint64_t naddr = MASK & (uint64_t)addr;
|
||||||
|
while (tst->analysisFn(tid,nip,MEMREAD,naddr)== -1) {
|
||||||
|
PIN_Yield();
|
||||||
|
}*/
|
||||||
|
}
|
||||||
|
|
||||||
|
// Pass a memory write record
|
||||||
|
VOID RecordMemWrite(THREADID tid,VOID * ip, VOID * addr)
|
||||||
|
{
|
||||||
|
checkSum+=MEMWRITE;
|
||||||
|
/* uint64_t nip = MASK & (uint64_t)ip;
|
||||||
|
uint64_t naddr = MASK & (uint64_t)addr;
|
||||||
|
while(tst->analysisFn(tid,nip,MEMWRITE,naddr)== -1) {
|
||||||
|
PIN_Yield();
|
||||||
|
}*/
|
||||||
|
}
|
||||||
|
|
||||||
|
VOID BrnFun(THREADID tid,ADDRINT tadr,BOOL taken,VOID *ip)
|
||||||
|
{
|
||||||
|
checkSum = taken ? TAKEN : NOTTAKEN;
|
||||||
|
/* uint64_t nip = MASK & (uint64_t)ip;
|
||||||
|
uint64_t ntadr = MASK & (uint64_t)tadr;
|
||||||
|
if (taken) {
|
||||||
|
while (tst->analysisFn(tid,nip,TAKEN,ntadr)==-1) {
|
||||||
|
PIN_Yield();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
while (tst->analysisFn(tid,nip,NOTTAKEN,ntadr)==-1) {
|
||||||
|
PIN_Yield();
|
||||||
|
}
|
||||||
|
}*/
|
||||||
|
}
|
||||||
|
|
||||||
|
//VOID FunEntry(ADDRINT first_arg, const string * name, THREADID threadid)
|
||||||
|
VOID FunEntry(ADDRINT first_arg, UINT32 encode, THREADID threadid)
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
GetLock(&lock, threadid+1);
|
||||||
|
printf("%d enters in %d with first arg %p --%llu \n",threadid,encode,(void *)first_arg,ClockGetTime());
|
||||||
|
//TraceFile << threadid <<" enter "<< *name << "(" << first_arg << ")" << endl;
|
||||||
|
ReleaseLock(&lock);
|
||||||
|
|
||||||
|
|
||||||
|
checkSum+=encode;
|
||||||
|
|
||||||
|
/*uint64_t uarg = MASK & (uint64_t)first_arg;
|
||||||
|
while (tst->analysisFn(threadid,ClockGetTime(),encode,uarg)== -1) {
|
||||||
|
PIN_Yield();
|
||||||
|
}*/
|
||||||
|
}
|
||||||
|
|
||||||
|
VOID FunExit(ADDRINT *ret, UINT32 encode, THREADID threadid)
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
GetLock(&lock, threadid+1);
|
||||||
|
printf("%d exits from %d with return value %p --%llu\n",threadid,encode,(void *)ret,ClockGetTime());
|
||||||
|
//TraceFile << threadid <<" exit "<< *name << " returns " << ret << endl;
|
||||||
|
ReleaseLock(&lock);
|
||||||
|
|
||||||
|
|
||||||
|
checkSum+=encode;
|
||||||
|
/* uint64_t uret = MASK & (uint64_t)ret;
|
||||||
|
while (tst->analysisFn(threadid,ClockGetTime(),encode,uret)== -1) {
|
||||||
|
PIN_Yield();
|
||||||
|
}*/
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Pin calls this function every time a new instruction is encountered
|
||||||
|
VOID Instruction(INS ins, VOID *v)
|
||||||
|
{
|
||||||
|
UINT32 memOperands = INS_MemoryOperandCount(ins);
|
||||||
|
|
||||||
|
if (INS_IsBranchOrCall(ins))//INS_IsIndirectBranchOrCall(ins))
|
||||||
|
{
|
||||||
|
INS_InsertCall(ins, IPOINT_BEFORE, (AFUNPTR)BrnFun, IARG_THREAD_ID, IARG_BRANCH_TARGET_ADDR, IARG_BRANCH_TAKEN, IARG_INST_PTR, IARG_END);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Iterate over each memory operand of the instruction.
|
||||||
|
for (UINT32 memOp = 0; memOp < memOperands; memOp++)
|
||||||
|
{
|
||||||
|
if (INS_MemoryOperandIsRead(ins, memOp))
|
||||||
|
{
|
||||||
|
INS_InsertPredicatedCall(
|
||||||
|
ins, IPOINT_BEFORE, (AFUNPTR)RecordMemRead,
|
||||||
|
IARG_THREAD_ID,
|
||||||
|
IARG_INST_PTR,
|
||||||
|
IARG_MEMORYOP_EA, memOp,
|
||||||
|
IARG_END);
|
||||||
|
}
|
||||||
|
// Note that in some architectures a single memory operand can be
|
||||||
|
// both read and written (for instance incl (%eax) on IA-32)
|
||||||
|
// In that case we instrument it once for read and once for write.
|
||||||
|
if (INS_MemoryOperandIsWritten(ins, memOp))
|
||||||
|
{
|
||||||
|
INS_InsertPredicatedCall(
|
||||||
|
ins, IPOINT_BEFORE, (AFUNPTR)RecordMemWrite,
|
||||||
|
IARG_THREAD_ID,
|
||||||
|
IARG_INST_PTR,
|
||||||
|
IARG_MEMORYOP_EA, memOp,
|
||||||
|
IARG_END);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//if (RTN_Valid(rtn) && RtnMatchesName(RTN_Name(rtn), name))
|
||||||
|
|
||||||
|
// This is a routine level instrumentation
|
||||||
|
VOID FlagRtn(RTN rtn, VOID* v)
|
||||||
|
{
|
||||||
|
RTN_Open(rtn);
|
||||||
|
const string* rtn_name = new string(RTN_Name(rtn));
|
||||||
|
INT32 encode;
|
||||||
|
|
||||||
|
if (cmp("pthread_cond_broadcast")) encode = BCAST;
|
||||||
|
else if (cmp("pthread_cond_signal")) encode = SIGNAL;
|
||||||
|
else if (cmp("pthread_mutex_lock")) encode = LOCK;
|
||||||
|
else if (cmp("pthread_mutex_unlock_")) encode = UNLOCK; //pthread_mutex_unlock is just a wrapper
|
||||||
|
else if (cmp("pthread_join")) encode = JOIN;
|
||||||
|
else if (cmp("pthread_cond_wait")) encode = CONDWAIT;
|
||||||
|
else if (cmp("pthread_barrier_wait")) encode = BARRIERWAIT;
|
||||||
|
else encode = -1;
|
||||||
|
|
||||||
|
if (encode != -1 && RTN_Valid(rtn)) {
|
||||||
|
RTN_InsertCall(rtn, IPOINT_BEFORE, (AFUNPTR)FunEntry,
|
||||||
|
IARG_FUNCARG_ENTRYPOINT_VALUE,0,
|
||||||
|
IARG_UINT32,encode,
|
||||||
|
IARG_THREAD_ID,
|
||||||
|
IARG_END);
|
||||||
|
|
||||||
|
RTN_InsertCall(rtn, IPOINT_AFTER, (AFUNPTR)FunExit,
|
||||||
|
IARG_FUNCRET_EXITPOINT_VALUE,
|
||||||
|
IARG_UINT32,encode+1,
|
||||||
|
IARG_THREAD_ID,
|
||||||
|
IARG_END);
|
||||||
|
|
||||||
|
}
|
||||||
|
RTN_Close(rtn);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// This function is called when the application exits
|
||||||
|
VOID Fini(INT32 code, VOID *v)
|
||||||
|
{
|
||||||
|
printf("checkSum is %lld\n",checkSum);
|
||||||
|
tst->unload();
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ===================================================================== */
|
||||||
|
/* Print Help Message */
|
||||||
|
/* ===================================================================== */
|
||||||
|
|
||||||
|
INT32 Usage()
|
||||||
|
{
|
||||||
|
cerr << "This tool instruments the benchmarks" << endl;
|
||||||
|
cerr << endl << KNOB_BASE::StringKnobSummary() << endl;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ===================================================================== */
|
||||||
|
/* Main */
|
||||||
|
/* ===================================================================== */
|
||||||
|
|
||||||
|
// argc, argv are the entire command line, including pin -t <toolname> -- ...
|
||||||
|
int main(int argc, char * argv[])
|
||||||
|
{
|
||||||
|
|
||||||
|
UINT64 mask = KnobLong;
|
||||||
|
printf("mask for pin %lld\n", mask);
|
||||||
|
fflush(stdout);
|
||||||
|
if (sched_setaffinity(0, sizeof(mask), (cpu_set_t *)&mask) <0) {
|
||||||
|
perror("sched_setaffinity");
|
||||||
|
}
|
||||||
|
|
||||||
|
PIN_InitSymbols();
|
||||||
|
// Initialize pin
|
||||||
|
if (PIN_Init(argc, argv)) return Usage();
|
||||||
|
|
||||||
|
tst = new IPC::Shm ();
|
||||||
|
|
||||||
|
PIN_AddThreadStartFunction(ThreadStart, 0);
|
||||||
|
|
||||||
|
// Register Instruction to be called to instrument instructions
|
||||||
|
INS_AddInstrumentFunction(Instruction, 0);
|
||||||
|
|
||||||
|
// Register ThreadFini to be called when a thread exits
|
||||||
|
PIN_AddThreadFiniFunction(ThreadFini, 0);
|
||||||
|
|
||||||
|
// Register FlagRtn whenever you get a routine
|
||||||
|
RTN_AddInstrumentFunction(FlagRtn, 0);
|
||||||
|
|
||||||
|
// Register Fini to be called when the application exits
|
||||||
|
PIN_AddFiniFunction(Fini, 0);
|
||||||
|
|
||||||
|
// Start the program, never returns
|
||||||
|
PIN_StartProgram();
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
|
@ -0,0 +1,374 @@
|
||||||
|
#include <iostream>
|
||||||
|
#include <fstream>
|
||||||
|
#include "pin.H"
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <sys/shm.h>
|
||||||
|
#include <cstdlib>
|
||||||
|
#include <cstring>
|
||||||
|
#include <sched.h>
|
||||||
|
#include <sys/time.h>
|
||||||
|
#include <sys/resource.h>
|
||||||
|
#include <time.h>
|
||||||
|
#include <sys/timeb.h>
|
||||||
|
|
||||||
|
#include "IPCBase.h"
|
||||||
|
#include "shmem.h"
|
||||||
|
|
||||||
|
#include "encoding.h"
|
||||||
|
|
||||||
|
#ifdef _LP64
|
||||||
|
#define MASK 0xffffffffffffffff
|
||||||
|
#else
|
||||||
|
#define MASK 0x00000000ffffffff
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Defining command line arguments
|
||||||
|
KNOB<UINT64> KnobLong(KNOB_MODE_WRITEONCE, "pintool", "map", "1", "Maps");
|
||||||
|
|
||||||
|
PIN_LOCK lock;
|
||||||
|
INT32 numThreads = 0;
|
||||||
|
UINT64 checkSum = 0;
|
||||||
|
//IPC::IPCBase *tst;
|
||||||
|
bool pumpingStatus[MaxNumThreads];
|
||||||
|
ADDRINT curSynchVar[MaxNumThreads];
|
||||||
|
|
||||||
|
#define PacketEpoch 50
|
||||||
|
uint32_t countPacket[MaxNumThreads];
|
||||||
|
|
||||||
|
// needs -lrt (real-time lib)
|
||||||
|
// 1970-01-01 epoch UTC time, 1 nanosecond resolution
|
||||||
|
uint64_t ClockGetTime() {
|
||||||
|
timespec ts;
|
||||||
|
clock_gettime(CLOCK_REALTIME, &ts);
|
||||||
|
return (uint64_t) ts.tv_sec * 1000000000LL + (uint64_t) ts.tv_nsec;
|
||||||
|
}
|
||||||
|
|
||||||
|
// this compulsory is true if it is entering some function
|
||||||
|
// so that even if halts we have a timer packet here.
|
||||||
|
void sendTimerPacket(int tid, bool compulsory) {
|
||||||
|
if ((countPacket[tid]++ % PacketEpoch)==0 || compulsory){
|
||||||
|
GetLock(&lock, tid + 1);
|
||||||
|
checkSum +=TIMER;
|
||||||
|
ReleaseLock(&lock);
|
||||||
|
|
||||||
|
countPacket[tid]=0;
|
||||||
|
/*uint64_t time = ClockGetTime();
|
||||||
|
while (tst->analysisFn(tid, time, TIMER, 0) == -1) {
|
||||||
|
PIN_Yield();
|
||||||
|
}*/
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#define cmp(a) (rtn_name->find(a) != string::npos)
|
||||||
|
|
||||||
|
/*
|
||||||
|
bool isActive(int tid) {
|
||||||
|
return pumpingStatus[tid];
|
||||||
|
}
|
||||||
|
void reActivate(int tid) {
|
||||||
|
pumpingStatus[tid] = true;
|
||||||
|
curSynchVar[tid] = 0;
|
||||||
|
}
|
||||||
|
void deActivate(int tid, ADDRINT addr) {
|
||||||
|
curSynchVar[tid] = addr;
|
||||||
|
pumpingStatus[tid] = false;
|
||||||
|
}
|
||||||
|
bool hasEntered(int tid, ADDRINT addr) {
|
||||||
|
return (curSynchVar[tid] == addr);
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
VOID ThreadStart(THREADID threadid, CONTEXT *ctxt, INT32 flags, VOID *v) {
|
||||||
|
GetLock(&lock, threadid + 1);
|
||||||
|
numThreads++;
|
||||||
|
printf("threads till now %d\n", numThreads);
|
||||||
|
fflush(stdout);
|
||||||
|
ReleaseLock(&lock);
|
||||||
|
ASSERT(numThreads <= MaxNumThreads, "Maximum number of threads exceeded\n");
|
||||||
|
|
||||||
|
pumpingStatus[numThreads - 1] = true;
|
||||||
|
/*tst->onThread_start(threadid);*/
|
||||||
|
}
|
||||||
|
|
||||||
|
VOID ThreadFini(THREADID tid, const CONTEXT *ctxt, INT32 flags, VOID *v) {
|
||||||
|
/*while (tst->onThread_finish(tid) == -1) {
|
||||||
|
PIN_Yield();
|
||||||
|
}*/
|
||||||
|
}
|
||||||
|
|
||||||
|
//Pass a memory read record
|
||||||
|
VOID RecordMemRead(THREADID tid, VOID * ip, VOID * addr) {
|
||||||
|
/*
|
||||||
|
if (!isActive(tid))
|
||||||
|
return;
|
||||||
|
*/
|
||||||
|
|
||||||
|
sendTimerPacket(tid,false);
|
||||||
|
|
||||||
|
GetLock(&lock, tid + 1);
|
||||||
|
checkSum +=MEMREAD;
|
||||||
|
ReleaseLock(&lock);
|
||||||
|
|
||||||
|
/*uint64_t nip = MASK & (uint64_t) ip;
|
||||||
|
uint64_t naddr = MASK & (uint64_t) addr;
|
||||||
|
while (tst->analysisFn(tid, nip, MEMREAD, naddr) == -1) {
|
||||||
|
PIN_Yield();
|
||||||
|
}
|
||||||
|
*/}
|
||||||
|
|
||||||
|
// Pass a memory write record
|
||||||
|
VOID RecordMemWrite(THREADID tid, VOID * ip, VOID * addr) {
|
||||||
|
/*
|
||||||
|
if (!isActive(tid))
|
||||||
|
return;
|
||||||
|
*/
|
||||||
|
|
||||||
|
sendTimerPacket(tid,false);
|
||||||
|
|
||||||
|
GetLock(&lock, tid + 1);
|
||||||
|
checkSum +=MEMWRITE;
|
||||||
|
ReleaseLock(&lock);
|
||||||
|
|
||||||
|
/*
|
||||||
|
uint64_t nip = MASK & (uint64_t) ip;
|
||||||
|
uint64_t naddr = MASK & (uint64_t) addr;
|
||||||
|
while (tst->analysisFn(tid, nip, MEMWRITE, naddr) == -1) {
|
||||||
|
PIN_Yield();
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
|
||||||
|
VOID BrnFun(THREADID tid, ADDRINT tadr, BOOL taken, VOID *ip) {
|
||||||
|
/*
|
||||||
|
if (!isActive(tid))
|
||||||
|
return;
|
||||||
|
*/
|
||||||
|
|
||||||
|
sendTimerPacket(tid,false);
|
||||||
|
|
||||||
|
/*
|
||||||
|
uint64_t nip = MASK & (uint64_t) ip;
|
||||||
|
uint64_t ntadr = MASK & (uint64_t) tadr;
|
||||||
|
if (taken) {
|
||||||
|
GetLock(&lock, tid + 1);
|
||||||
|
checkSum +=TAKEN;
|
||||||
|
ReleaseLock(&lock);
|
||||||
|
|
||||||
|
while (tst->analysisFn(tid, nip, TAKEN, ntadr) == -1) {
|
||||||
|
PIN_Yield();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
GetLock(&lock, tid + 1);
|
||||||
|
checkSum +=NOTTAKEN;
|
||||||
|
ReleaseLock(&lock);
|
||||||
|
while (tst->analysisFn(tid, nip, NOTTAKEN, ntadr) == -1) {
|
||||||
|
PIN_Yield();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
|
||||||
|
//VOID FunEntry(ADDRINT first_arg, const string * name, THREADID threadid)
|
||||||
|
VOID FunEntry(ADDRINT first_arg, UINT32 encode, THREADID tid) {
|
||||||
|
uint64_t time = ClockGetTime();
|
||||||
|
/*
|
||||||
|
if (!isActive(tid)) {
|
||||||
|
// printf("tid %d could not register %d entry as not active\n", tid,
|
||||||
|
// encode);
|
||||||
|
// fflush(stdout);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
// deActivate(tid, first_arg);
|
||||||
|
|
||||||
|
sendTimerPacket(tid,true);
|
||||||
|
if (true){//(encode == LOCK || encode == UNLOCK) {
|
||||||
|
const char *temp = findType(encode);
|
||||||
|
|
||||||
|
GetLock(&lock, tid + 1);
|
||||||
|
printf("%d %s with first arg %p --%llu \n", tid, temp,
|
||||||
|
(void *) first_arg, time);
|
||||||
|
fflush(stdout);
|
||||||
|
ReleaseLock(&lock);
|
||||||
|
}
|
||||||
|
|
||||||
|
GetLock(&lock, tid + 1);
|
||||||
|
checkSum +=encode;
|
||||||
|
ReleaseLock(&lock);
|
||||||
|
|
||||||
|
/*
|
||||||
|
uint64_t uarg = MASK & (uint64_t) first_arg;
|
||||||
|
while (tst->analysisFn(tid, time, encode, uarg) == -1) {
|
||||||
|
PIN_Yield();
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
|
||||||
|
VOID FunExit(ADDRINT first_arg, UINT32 encode, THREADID tid) {
|
||||||
|
// uint64_t time = ClockGetTime();
|
||||||
|
/*
|
||||||
|
if (!isActive(tid) && !hasEntered(tid,first_arg)) {
|
||||||
|
// printf("tid %d could not register %d exit as not active\n", tid,
|
||||||
|
// encode);
|
||||||
|
// fflush(stdout);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
// reActivate(tid);
|
||||||
|
|
||||||
|
sendTimerPacket(tid,false);
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
if (true){//(encode == LOCK+1) {
|
||||||
|
char* temp = findType(encode);
|
||||||
|
GetLock(&lock, tid + 1);
|
||||||
|
printf("%d %s with first arg %p --%llu\n", tid, temp,
|
||||||
|
(void *) first_arg, time);
|
||||||
|
//TraceFile << threadid <<" exit "<< *name << " returns " << ret << endl;
|
||||||
|
ReleaseLock(&lock);
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
GetLock(&lock, tid + 1);
|
||||||
|
checkSum +=encode;
|
||||||
|
ReleaseLock(&lock);
|
||||||
|
|
||||||
|
/*
|
||||||
|
uint64_t uarg = MASK & (uint64_t) first_arg;
|
||||||
|
while (tst->analysisFn(tid, time, encode, uarg) == -1) {
|
||||||
|
PIN_Yield();
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// Pin calls this function every time a new instruction is encountered
|
||||||
|
VOID Instruction(INS ins, VOID *v) {
|
||||||
|
UINT32 memOperands = INS_MemoryOperandCount(ins);
|
||||||
|
|
||||||
|
if (INS_IsBranchOrCall(ins))//INS_IsIndirectBranchOrCall(ins))
|
||||||
|
{
|
||||||
|
INS_InsertCall(ins, IPOINT_BEFORE, (AFUNPTR) BrnFun, IARG_THREAD_ID,
|
||||||
|
IARG_BRANCH_TARGET_ADDR, IARG_BRANCH_TAKEN, IARG_INST_PTR,
|
||||||
|
IARG_END);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Iterate over each memory operand of the instruction.
|
||||||
|
for (UINT32 memOp = 0; memOp < memOperands; memOp++) {
|
||||||
|
if (INS_MemoryOperandIsRead(ins, memOp)) {
|
||||||
|
INS_InsertPredicatedCall(ins, IPOINT_BEFORE,
|
||||||
|
(AFUNPTR) RecordMemRead, IARG_THREAD_ID, IARG_INST_PTR,
|
||||||
|
IARG_MEMORYOP_EA, memOp, IARG_END);
|
||||||
|
}
|
||||||
|
// Note that in some architectures a single memory operand can be
|
||||||
|
// both read and written (for instance incl (%eax) on IA-32)
|
||||||
|
// In that case we instrument it once for read and once for write.
|
||||||
|
if (INS_MemoryOperandIsWritten(ins, memOp)) {
|
||||||
|
INS_InsertPredicatedCall(ins, IPOINT_BEFORE,
|
||||||
|
(AFUNPTR) RecordMemWrite, IARG_THREAD_ID, IARG_INST_PTR,
|
||||||
|
IARG_MEMORYOP_EA, memOp, IARG_END);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//if (RTN_Valid(rtn) && RtnMatchesName(RTN_Name(rtn), name))
|
||||||
|
|
||||||
|
// This is a routine level instrumentation
|
||||||
|
VOID FlagRtn(RTN rtn, VOID* v) {
|
||||||
|
RTN_Open(rtn);
|
||||||
|
const string* rtn_name = new string(RTN_Name(rtn));
|
||||||
|
INT32 encode;
|
||||||
|
|
||||||
|
if (cmp("pthread_cond_broadcast"))
|
||||||
|
encode = BCAST;
|
||||||
|
else if (cmp("pthread_cond_signal"))
|
||||||
|
encode = SIGNAL;
|
||||||
|
else if (cmp("pthread_mutex_lock"))
|
||||||
|
encode = LOCK;
|
||||||
|
else if (cmp("pthread_mutex_unlock_"))
|
||||||
|
encode = UNLOCK; //pthread_mutex_unlock is just a wrapper
|
||||||
|
else if (cmp("pthread_join"))
|
||||||
|
encode = JOIN;
|
||||||
|
else if (cmp("pthread_cond_wait"))
|
||||||
|
encode = CONDWAIT;
|
||||||
|
else if (cmp("pthread_barrier_wait"))
|
||||||
|
encode = BARRIERWAIT;
|
||||||
|
else
|
||||||
|
encode = -1;
|
||||||
|
|
||||||
|
if (encode != -1 && RTN_Valid(rtn)) {
|
||||||
|
RTN_InsertCall(rtn, IPOINT_BEFORE, (AFUNPTR) FunEntry,
|
||||||
|
IARG_FUNCARG_ENTRYPOINT_VALUE, 0, IARG_UINT32, encode,
|
||||||
|
IARG_THREAD_ID, IARG_END);
|
||||||
|
|
||||||
|
RTN_InsertCall(rtn, IPOINT_AFTER, (AFUNPTR) FunExit,
|
||||||
|
IARG_FUNCARG_ENTRYPOINT_VALUE, 0, IARG_UINT32, encode + 1,
|
||||||
|
IARG_THREAD_ID, IARG_END);
|
||||||
|
|
||||||
|
}
|
||||||
|
RTN_Close(rtn);
|
||||||
|
}
|
||||||
|
|
||||||
|
// This function is called when the application exits
|
||||||
|
VOID Fini(INT32 code, VOID *v) {
|
||||||
|
printf("checkSum is %lld\n", checkSum);
|
||||||
|
/* tst->unload();*/
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ===================================================================== */
|
||||||
|
/* Print Help Message */
|
||||||
|
/* ===================================================================== */
|
||||||
|
|
||||||
|
INT32 Usage() {
|
||||||
|
cerr << "This tool instruments the benchmarks" << endl;
|
||||||
|
cerr << endl << KNOB_BASE::StringKnobSummary() << endl;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ===================================================================== */
|
||||||
|
/* Main */
|
||||||
|
/* ===================================================================== */
|
||||||
|
|
||||||
|
// argc, argv are the entire command line, including pin -t <toolname> -- ...
|
||||||
|
int main(int argc, char * argv[]) {
|
||||||
|
|
||||||
|
UINT64 mask = KnobLong;
|
||||||
|
printf("mask for pin %lld\n", mask);
|
||||||
|
fflush(stdout);
|
||||||
|
if (sched_setaffinity(0, sizeof(mask), (cpu_set_t *) &mask) < 0) {
|
||||||
|
perror("sched_setaffinity");
|
||||||
|
}
|
||||||
|
|
||||||
|
PIN_InitSymbols();
|
||||||
|
// Initialize pin
|
||||||
|
if (PIN_Init(argc, argv))
|
||||||
|
return Usage();
|
||||||
|
|
||||||
|
/* tst = new IPC::Shm();*/
|
||||||
|
|
||||||
|
PIN_AddThreadStartFunction(ThreadStart, 0);
|
||||||
|
|
||||||
|
// Register Instruction to be called to instrument instructions
|
||||||
|
INS_AddInstrumentFunction(Instruction, 0);
|
||||||
|
|
||||||
|
// Register ThreadFini to be called when a thread exits
|
||||||
|
PIN_AddThreadFiniFunction(ThreadFini, 0);
|
||||||
|
|
||||||
|
// Register FlagRtn whenever you get a routine
|
||||||
|
RTN_AddInstrumentFunction(FlagRtn, 0);
|
||||||
|
|
||||||
|
// Register Fini to be called when the application exits
|
||||||
|
PIN_AddFiniFunction(Fini, 0);
|
||||||
|
|
||||||
|
// Start the program, never returns
|
||||||
|
PIN_StartProgram();
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
|
@ -0,0 +1,12 @@
|
||||||
|
package config;
|
||||||
|
|
||||||
|
public class BranchPredictorConfig {
|
||||||
|
public int PCBits;
|
||||||
|
public int BHRsize;
|
||||||
|
public int saturating_bits;
|
||||||
|
public BP predictorMode;
|
||||||
|
|
||||||
|
public static enum BP {
|
||||||
|
NoPredictor, PerfectPredictor, AlwaysTaken, AlwaysNotTaken, Tournament, Bimodal, GShare, GAg, GAp, PAg, PAp,TAGE
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,16 @@
|
||||||
|
package config;
|
||||||
|
|
||||||
|
public class BusConfig {
|
||||||
|
int latency;
|
||||||
|
|
||||||
|
public BusConfig() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getLatency() {
|
||||||
|
return latency;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setLatency(int latency) {
|
||||||
|
this.latency = latency;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,220 @@
|
||||||
|
/*****************************************************************************
|
||||||
|
Tejas Simulator
|
||||||
|
------------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
Copyright [2010] [Indian Institute of Technology, Delhi]
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
------------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
Contributors: Moksh Upadhyay
|
||||||
|
*****************************************************************************/
|
||||||
|
package config;
|
||||||
|
|
||||||
|
import memorysystem.nuca.NucaCache.Mapping;
|
||||||
|
import memorysystem.nuca.NucaCache.NucaType;
|
||||||
|
import generic.PortType;
|
||||||
|
|
||||||
|
public class CacheConfig
|
||||||
|
{
|
||||||
|
public long operatingFreq;
|
||||||
|
public long stepSize;
|
||||||
|
|
||||||
|
public WritePolicy writePolicy;
|
||||||
|
public String nextLevel;
|
||||||
|
public int blockSize;
|
||||||
|
public int assoc;
|
||||||
|
public int size;
|
||||||
|
public int numEntries;
|
||||||
|
public int readLatency;
|
||||||
|
public int writeLatency;
|
||||||
|
|
||||||
|
public PortType portType;
|
||||||
|
public int readPorts;
|
||||||
|
public int writePorts;
|
||||||
|
public int readWritePorts;
|
||||||
|
public int portReadOccupancy;
|
||||||
|
public int portWriteOccupancy;
|
||||||
|
|
||||||
|
public int numberOfBuses;
|
||||||
|
public int busOccupancy;
|
||||||
|
public int mshrSize;
|
||||||
|
public NucaType nucaType;
|
||||||
|
public Mapping mapping;
|
||||||
|
|
||||||
|
public boolean collectWorkingSetData = false;
|
||||||
|
public long workingSetChunkSize = -1;
|
||||||
|
|
||||||
|
public CacheEnergyConfig power;
|
||||||
|
|
||||||
|
public String cacheName;
|
||||||
|
public int numComponents;
|
||||||
|
public boolean firstLevel = false;
|
||||||
|
public CacheDataType cacheDataType = null;
|
||||||
|
public String nextLevelId;
|
||||||
|
|
||||||
|
public String coherenceName;
|
||||||
|
|
||||||
|
public boolean isDirectory = false;
|
||||||
|
|
||||||
|
public static enum WritePolicy{
|
||||||
|
WRITE_BACK, WRITE_THROUGH
|
||||||
|
}
|
||||||
|
|
||||||
|
public static enum PrefetcherType{
|
||||||
|
None, Power4
|
||||||
|
}
|
||||||
|
|
||||||
|
public PrefetcherType prefetcherType;
|
||||||
|
|
||||||
|
public int AMAT;
|
||||||
|
|
||||||
|
//Getters and setters
|
||||||
|
|
||||||
|
public WritePolicy getWritePolicy() {
|
||||||
|
return writePolicy;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getNextLevel() {
|
||||||
|
return nextLevel;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getBlockSize() {
|
||||||
|
return blockSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getAssoc() {
|
||||||
|
return assoc;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getSize() {
|
||||||
|
return size;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getReadLatency() {
|
||||||
|
return readLatency;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setReadLatency(int readLatency) {
|
||||||
|
this.readLatency = readLatency;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getWriteLatency() {
|
||||||
|
return writeLatency;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setWriteLatency(int writeLatency) {
|
||||||
|
this.writeLatency = writeLatency;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getReadPorts() {
|
||||||
|
return readPorts;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setReadPorts(int readPorts) {
|
||||||
|
this.readPorts = readPorts;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getWritePorts() {
|
||||||
|
return writePorts;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setWritePorts(int writePorts) {
|
||||||
|
this.writePorts = writePorts;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getReadWritePorts() {
|
||||||
|
return readWritePorts;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setReadWritePorts(int readWritePorts) {
|
||||||
|
this.readWritePorts = readWritePorts;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getPortReadOccupancy() {
|
||||||
|
return portReadOccupancy;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPortReadOccupancy(int portReadOccupancy) {
|
||||||
|
this.portReadOccupancy = portReadOccupancy;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getPortWriteOccupancy() {
|
||||||
|
return portWriteOccupancy;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPortWriteOccupancy(int portWriteOccupancy) {
|
||||||
|
this.portWriteOccupancy = portWriteOccupancy;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void setWritePolicy(WritePolicy writePolicy) {
|
||||||
|
this.writePolicy = writePolicy;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void setNextLevel(String nextLevel) {
|
||||||
|
this.nextLevel = nextLevel;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void setBlockSize(int blockSize) {
|
||||||
|
this.blockSize = blockSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void setAssoc(int assoc) {
|
||||||
|
this.assoc = assoc;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void setSize(int size) {
|
||||||
|
this.size = size;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getNumberOfBuses() {
|
||||||
|
return numberOfBuses;
|
||||||
|
}
|
||||||
|
public int getBankSize()
|
||||||
|
{
|
||||||
|
return size/(SystemConfig.nocConfig.numberOfColumns * SystemConfig.nocConfig.numberOfRows);
|
||||||
|
}
|
||||||
|
public NucaType getNucaType() {
|
||||||
|
return nucaType;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setNucaType(NucaType nucaType) {
|
||||||
|
this.nucaType = nucaType;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getBusOccupancy() {
|
||||||
|
return busOccupancy;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setBusOccupancy(int busOccupancy) {
|
||||||
|
this.busOccupancy = busOccupancy;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getAMAT() {
|
||||||
|
return AMAT;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setAMAT(int aMAT) {
|
||||||
|
AMAT = aMAT;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// public boolean isFirstLevel() {
|
||||||
|
// return isFirstLevel;
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// public void setFirstLevel(boolean isFirstLevel) {
|
||||||
|
// this.isFirstLevel = isFirstLevel;
|
||||||
|
// }
|
||||||
|
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,7 @@
|
||||||
|
package config;
|
||||||
|
|
||||||
|
public enum CacheDataType {
|
||||||
|
Instruction,
|
||||||
|
Data,
|
||||||
|
Unified
|
||||||
|
}
|
|
@ -0,0 +1,7 @@
|
||||||
|
package config;
|
||||||
|
|
||||||
|
public class CacheEnergyConfig {
|
||||||
|
public double leakageEnergy;
|
||||||
|
public double readDynamicEnergy;
|
||||||
|
public double writeDynamicEnergy;
|
||||||
|
}
|
|
@ -0,0 +1,7 @@
|
||||||
|
package config;
|
||||||
|
|
||||||
|
public enum CommunicationType {
|
||||||
|
sharedMemory,
|
||||||
|
network,
|
||||||
|
file
|
||||||
|
}
|
|
@ -0,0 +1,154 @@
|
||||||
|
/*****************************************************************************
|
||||||
|
Tejas Simulator
|
||||||
|
------------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
Copyright [2010] [Indian Institute of Technology, Delhi]
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
------------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
Contributors: Moksh Upadhyay
|
||||||
|
*****************************************************************************/
|
||||||
|
package config;
|
||||||
|
|
||||||
|
import java.util.Vector;
|
||||||
|
import generic.PortType;
|
||||||
|
|
||||||
|
public class CoreConfig
|
||||||
|
{
|
||||||
|
public long frequency;
|
||||||
|
public long stepSize;
|
||||||
|
|
||||||
|
public int LSQNumLoadEntries;
|
||||||
|
public int LSQNumStoreEntries;
|
||||||
|
public int LSQLatency;
|
||||||
|
public PortType LSQPortType;
|
||||||
|
public int LSQAccessPorts;
|
||||||
|
public int LSQPortOccupancy;
|
||||||
|
|
||||||
|
public PipelineType pipelineType;
|
||||||
|
|
||||||
|
public int ITLBSize;
|
||||||
|
public int ITLBLatency;
|
||||||
|
public int ITLBMissPenalty;
|
||||||
|
public PortType ITLBPortType;
|
||||||
|
public int ITLBAccessPorts;
|
||||||
|
public int ITLBPortOccupancy;
|
||||||
|
|
||||||
|
public int DTLBSize;
|
||||||
|
public int DTLBLatency;
|
||||||
|
public int DTLBMissPenalty;
|
||||||
|
public PortType DTLBPortType;
|
||||||
|
public int DTLBAccessPorts;
|
||||||
|
public int DTLBPortOccupancy;
|
||||||
|
|
||||||
|
public int STLBSize;
|
||||||
|
public int STLBLatency;
|
||||||
|
public int STLBMissPenalty;
|
||||||
|
public PortType STLBPortType;
|
||||||
|
public int STLBAccessPorts;
|
||||||
|
public int STLBPortOccupancy;
|
||||||
|
|
||||||
|
public int DecodeWidth;
|
||||||
|
public int IssueWidth;
|
||||||
|
public int RetireWidth;
|
||||||
|
public int ROBSize;
|
||||||
|
public int IWSize;
|
||||||
|
public int IntRegFileSize;
|
||||||
|
public int FloatRegFileSize;
|
||||||
|
public int IntArchRegNum;
|
||||||
|
public int FloatArchRegNum;
|
||||||
|
|
||||||
|
public int BranchMispredPenalty;
|
||||||
|
|
||||||
|
public int ExecutionCoreNumPorts;
|
||||||
|
|
||||||
|
public int IntALUNum;
|
||||||
|
public int IntMulNum;
|
||||||
|
public int IntDivNum;
|
||||||
|
public int FloatALUNum;
|
||||||
|
public int FloatMulNum;
|
||||||
|
public int FloatDivNum;
|
||||||
|
public int JumpNum;
|
||||||
|
public int MemoryNum;
|
||||||
|
|
||||||
|
public int IntALULatency;
|
||||||
|
public int IntMulLatency;
|
||||||
|
public int IntDivLatency;
|
||||||
|
public int FloatALULatency;
|
||||||
|
public int FloatMulLatency;
|
||||||
|
public int FloatDivLatency;
|
||||||
|
public int JumpLatency;
|
||||||
|
public int MemoryLatency;
|
||||||
|
|
||||||
|
public int IntALUReciprocalOfThroughput;
|
||||||
|
public int IntMulReciprocalOfThroughput;
|
||||||
|
public int IntDivReciprocalOfThroughput;
|
||||||
|
public int FloatALUReciprocalOfThroughput;
|
||||||
|
public int FloatMulReciprocalOfThroughput;
|
||||||
|
public int FloatDivReciprocalOfThroughput;
|
||||||
|
public int JumpReciprocalOfThroughput;
|
||||||
|
public int MemoryReciprocalOfThroughput;
|
||||||
|
|
||||||
|
public int[] IntALUPortNumbers;
|
||||||
|
public int[] IntMulPortNumbers;
|
||||||
|
public int[] IntDivPortNumbers;
|
||||||
|
public int[] FloatALUPortNumbers;
|
||||||
|
public int[] FloatMulPortNumbers;
|
||||||
|
public int[] FloatDivPortNumbers;
|
||||||
|
public int[] JumpPortNumbers;
|
||||||
|
public int[] MemoryPortNumbers;
|
||||||
|
|
||||||
|
public Vector<CacheConfig> coreCacheList = new Vector<CacheConfig>();
|
||||||
|
|
||||||
|
public BranchPredictorConfig branchPredictor;
|
||||||
|
|
||||||
|
public boolean TreeBarrier;
|
||||||
|
|
||||||
|
public int barrierLatency;
|
||||||
|
public int barrierUnit;
|
||||||
|
|
||||||
|
public EnergyConfig bPredPower;
|
||||||
|
public EnergyConfig decodePower;
|
||||||
|
public EnergyConfig intRATPower;
|
||||||
|
public EnergyConfig floatRATPower;
|
||||||
|
public EnergyConfig intFreeListPower;
|
||||||
|
public EnergyConfig floatFreeListPower;
|
||||||
|
public EnergyConfig lsqPower;
|
||||||
|
public EnergyConfig intRegFilePower;
|
||||||
|
public EnergyConfig floatRegFilePower;
|
||||||
|
public EnergyConfig iwPower;
|
||||||
|
public EnergyConfig robPower;
|
||||||
|
public EnergyConfig intALUPower;
|
||||||
|
public EnergyConfig floatALUPower;
|
||||||
|
public EnergyConfig complexALUPower;
|
||||||
|
public EnergyConfig resultsBroadcastBusPower;
|
||||||
|
public EnergyConfig iTLBPower;
|
||||||
|
public EnergyConfig dTLBPower;
|
||||||
|
public EnergyConfig sTLBPower;
|
||||||
|
|
||||||
|
public int getICacheLatency() {
|
||||||
|
int latency = 0;
|
||||||
|
|
||||||
|
for(CacheConfig config : coreCacheList) {
|
||||||
|
if(config.firstLevel) {
|
||||||
|
if(config.cacheDataType==CacheDataType.Instruction ||
|
||||||
|
config.cacheDataType==CacheDataType.Unified) {
|
||||||
|
return config.readLatency;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
misc.Error.showErrorAndExit("Could not locate instruction cache config !!");
|
||||||
|
return latency;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,5 @@
|
||||||
|
package config;
|
||||||
|
|
||||||
|
public class DirectoryConfig extends CacheConfig {
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,18 @@
|
||||||
|
package config;
|
||||||
|
|
||||||
|
public class EmulatorConfig {
|
||||||
|
|
||||||
|
public static CommunicationType communicationType;
|
||||||
|
public static EmulatorType emulatorType;
|
||||||
|
|
||||||
|
public static int maxThreadsForTraceCollection = 1024;
|
||||||
|
public static boolean storeExecutionTraceInAFile;
|
||||||
|
public static String basenameForTraceFiles;
|
||||||
|
|
||||||
|
public static String PinTool = null;
|
||||||
|
public static String PinInstrumentor = null;
|
||||||
|
public static String QemuTool = null;
|
||||||
|
public static String ShmLibDirectory;
|
||||||
|
public static String GetBenchmarkPIDScript;
|
||||||
|
public static String KillEmulatorScript;
|
||||||
|
}
|
|
@ -0,0 +1,7 @@
|
||||||
|
package config;
|
||||||
|
|
||||||
|
public enum EmulatorType {
|
||||||
|
pin,
|
||||||
|
qemu,
|
||||||
|
none
|
||||||
|
}
|
|
@ -0,0 +1,48 @@
|
||||||
|
package config;
|
||||||
|
|
||||||
|
import generic.GlobalClock;
|
||||||
|
import generic.Statistics;
|
||||||
|
|
||||||
|
import java.io.FileWriter;
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
public class EnergyConfig {
|
||||||
|
public double leakageEnergy;
|
||||||
|
public double dynamicEnergy;
|
||||||
|
public long numAccesses = 0;
|
||||||
|
|
||||||
|
public EnergyConfig(double leakagePower, double dynamicPower) {
|
||||||
|
this.leakageEnergy = leakagePower;
|
||||||
|
this.dynamicEnergy = dynamicPower;
|
||||||
|
}
|
||||||
|
|
||||||
|
public EnergyConfig(EnergyConfig power, long numAccesses) {
|
||||||
|
this.leakageEnergy = power.leakageEnergy * (GlobalClock.getCurrentTime());
|
||||||
|
this.dynamicEnergy = power.dynamicEnergy*numAccesses;
|
||||||
|
this.numAccesses = numAccesses;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String toString()
|
||||||
|
{
|
||||||
|
return " " + leakageEnergy
|
||||||
|
+ "\t" + dynamicEnergy
|
||||||
|
+ "\t" + (leakageEnergy + dynamicEnergy);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void add(EnergyConfig a, EnergyConfig b)
|
||||||
|
{
|
||||||
|
leakageEnergy = a.leakageEnergy + b.leakageEnergy;
|
||||||
|
dynamicEnergy = a.dynamicEnergy + b.dynamicEnergy;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void add(EnergyConfig a)
|
||||||
|
{
|
||||||
|
leakageEnergy += a.leakageEnergy;
|
||||||
|
dynamicEnergy += a.dynamicEnergy;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void printEnergyStats(FileWriter outputFileWriter, String componentName) throws IOException {
|
||||||
|
outputFileWriter.write(componentName + "\t" + Statistics.formatDouble(leakageEnergy) + "\t" + Statistics.formatDouble(dynamicEnergy)
|
||||||
|
+ "\t" + Statistics.formatDouble((leakageEnergy + dynamicEnergy)) + "\t" + numAccesses + "\n");
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,190 @@
|
||||||
|
package config;
|
||||||
|
|
||||||
|
import generic.EventQueue;
|
||||||
|
import generic.GlobalClock;
|
||||||
|
|
||||||
|
public class FrequencyConfig {
|
||||||
|
|
||||||
|
static long HCF;
|
||||||
|
|
||||||
|
public static void setupStepSizes()
|
||||||
|
{
|
||||||
|
findLCM();
|
||||||
|
|
||||||
|
long lowestFrequency = Long.MAX_VALUE;
|
||||||
|
for(int i = 0; i < SystemConfig.core.length; i++)
|
||||||
|
{
|
||||||
|
if((LCM / SystemConfig.core[i].frequency) < lowestFrequency)
|
||||||
|
{
|
||||||
|
lowestFrequency = (LCM / SystemConfig.core[i].frequency);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for(int i = 0; i < SystemConfig.sharedCacheConfigs.size(); i++)
|
||||||
|
{
|
||||||
|
if((LCM / SystemConfig.sharedCacheConfigs.get(i).operatingFreq) < lowestFrequency)
|
||||||
|
{
|
||||||
|
lowestFrequency = (LCM / SystemConfig.sharedCacheConfigs.get(i).operatingFreq);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if((LCM / SystemConfig.nocConfig.operatingFreq) < lowestFrequency)
|
||||||
|
{
|
||||||
|
lowestFrequency = (LCM / SystemConfig.nocConfig.operatingFreq);
|
||||||
|
}
|
||||||
|
if((LCM / SystemConfig.mainMemoryFrequency) < lowestFrequency)
|
||||||
|
{
|
||||||
|
lowestFrequency = (LCM / SystemConfig.mainMemoryFrequency);
|
||||||
|
}
|
||||||
|
|
||||||
|
int div = 1;
|
||||||
|
while(lowestFrequency/div >= 1)
|
||||||
|
{
|
||||||
|
if(lowestFrequency % div != 0)
|
||||||
|
{
|
||||||
|
div++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean factor = true;
|
||||||
|
for(int i = 0; i < SystemConfig.core.length; i++)
|
||||||
|
{
|
||||||
|
if((LCM / SystemConfig.core[i].frequency) % (lowestFrequency/div) != 0)
|
||||||
|
{
|
||||||
|
factor = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for(int i = 0; i < SystemConfig.sharedCacheConfigs.size(); i++)
|
||||||
|
{
|
||||||
|
if((LCM / SystemConfig.sharedCacheConfigs.get(i).operatingFreq) % (lowestFrequency/div) != 0)
|
||||||
|
{
|
||||||
|
factor = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if((LCM / SystemConfig.nocConfig.operatingFreq) % (lowestFrequency/div) != 0)
|
||||||
|
{
|
||||||
|
factor = false;
|
||||||
|
}
|
||||||
|
if((LCM / SystemConfig.mainMemoryFrequency) % (lowestFrequency/div) != 0)
|
||||||
|
{
|
||||||
|
factor = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(factor == true)
|
||||||
|
{
|
||||||
|
HCF = lowestFrequency / div;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
div++;
|
||||||
|
}
|
||||||
|
|
||||||
|
for(int i = 0; i < SystemConfig.core.length; i++)
|
||||||
|
{
|
||||||
|
SystemConfig.core[i].stepSize = (LCM / SystemConfig.core[i].frequency) / HCF;
|
||||||
|
for(int j = 0; j < SystemConfig.core[i].coreCacheList.size(); j++)
|
||||||
|
{
|
||||||
|
SystemConfig.core[i].coreCacheList.get(j).operatingFreq = SystemConfig.core[i].frequency;
|
||||||
|
SystemConfig.core[i].coreCacheList.get(j).stepSize = SystemConfig.core[i].stepSize;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for(int i = 0; i < SystemConfig.sharedCacheConfigs.size(); i++)
|
||||||
|
{
|
||||||
|
SystemConfig.sharedCacheConfigs.get(i).stepSize = (LCM / SystemConfig.sharedCacheConfigs.get(i).operatingFreq) / HCF;
|
||||||
|
}
|
||||||
|
SystemConfig.nocConfig.stepSize = (LCM / SystemConfig.nocConfig.operatingFreq) / HCF;
|
||||||
|
SystemConfig.mainMemoryStepSize = (LCM / SystemConfig.mainMemoryFrequency) / HCF;
|
||||||
|
|
||||||
|
GlobalClock.effectiveGlobalClockFrequency = SystemConfig.core[0].frequency * SystemConfig.core[0].stepSize;
|
||||||
|
setEventQueueSize();
|
||||||
|
}
|
||||||
|
|
||||||
|
static long LCM = 1;
|
||||||
|
static void findLCM()
|
||||||
|
{
|
||||||
|
long maxFrequency = Long.MIN_VALUE;
|
||||||
|
for(int i = 0; i < SystemConfig.core.length; i++)
|
||||||
|
{
|
||||||
|
if(SystemConfig.core[i].frequency > maxFrequency)
|
||||||
|
{
|
||||||
|
maxFrequency = SystemConfig.core[i].frequency;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for(int i = 0; i < SystemConfig.sharedCacheConfigs.size(); i++)
|
||||||
|
{
|
||||||
|
if(SystemConfig.sharedCacheConfigs.get(i).operatingFreq > maxFrequency)
|
||||||
|
{
|
||||||
|
maxFrequency = SystemConfig.sharedCacheConfigs.get(i).operatingFreq;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(SystemConfig.nocConfig.operatingFreq > maxFrequency)
|
||||||
|
{
|
||||||
|
maxFrequency = SystemConfig.nocConfig.operatingFreq;
|
||||||
|
}
|
||||||
|
if(SystemConfig.mainMemoryFrequency > maxFrequency)
|
||||||
|
{
|
||||||
|
maxFrequency = SystemConfig.mainMemoryFrequency;
|
||||||
|
}
|
||||||
|
|
||||||
|
int m = 1;
|
||||||
|
while(true)
|
||||||
|
{
|
||||||
|
boolean factor = true;
|
||||||
|
for(int i = 0; i < SystemConfig.core.length; i++)
|
||||||
|
{
|
||||||
|
if((maxFrequency * m) % SystemConfig.core[i].frequency != 0)
|
||||||
|
{
|
||||||
|
factor = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for(int i = 0; i < SystemConfig.sharedCacheConfigs.size(); i++)
|
||||||
|
{
|
||||||
|
if((maxFrequency * m) % SystemConfig.sharedCacheConfigs.get(i).operatingFreq != 0)
|
||||||
|
{
|
||||||
|
factor = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if((maxFrequency * m) % SystemConfig.nocConfig.operatingFreq != 0)
|
||||||
|
{
|
||||||
|
factor = false;
|
||||||
|
}
|
||||||
|
if((maxFrequency * m) % SystemConfig.mainMemoryFrequency != 0)
|
||||||
|
{
|
||||||
|
factor = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(factor == true)
|
||||||
|
{
|
||||||
|
LCM = (maxFrequency * m);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
m++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void setEventQueueSize()
|
||||||
|
{
|
||||||
|
long highestLatencyOfAnyElement = Long.MIN_VALUE;
|
||||||
|
for(int i = 0; i < SystemConfig.sharedCacheConfigs.size(); i++)
|
||||||
|
{
|
||||||
|
if(((SystemConfig.sharedCacheConfigs.get(i).writeLatency + SystemConfig.sharedCacheConfigs.get(i).portWriteOccupancy) * SystemConfig.sharedCacheConfigs.get(i).stepSize) > highestLatencyOfAnyElement)
|
||||||
|
{
|
||||||
|
highestLatencyOfAnyElement = ((SystemConfig.sharedCacheConfigs.get(i).writeLatency + SystemConfig.sharedCacheConfigs.get(i).portWriteOccupancy) * SystemConfig.sharedCacheConfigs.get(i).stepSize);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(((SystemConfig.nocConfig.latency + SystemConfig.nocConfig.latencyBetweenNOCElements + SystemConfig.nocConfig.portOccupancy) * SystemConfig.nocConfig.stepSize) > highestLatencyOfAnyElement)
|
||||||
|
{
|
||||||
|
highestLatencyOfAnyElement = ((SystemConfig.nocConfig.latency + SystemConfig.nocConfig.latencyBetweenNOCElements + SystemConfig.nocConfig.portOccupancy) * SystemConfig.nocConfig.stepSize);
|
||||||
|
}
|
||||||
|
if(((SystemConfig.mainMemoryLatency + SystemConfig.mainMemoryPortOccupancy) * SystemConfig.mainMemoryStepSize) > highestLatencyOfAnyElement)
|
||||||
|
{
|
||||||
|
highestLatencyOfAnyElement = ((SystemConfig.mainMemoryLatency + SystemConfig.mainMemoryPortOccupancy) * SystemConfig.mainMemoryStepSize);
|
||||||
|
}
|
||||||
|
|
||||||
|
EventQueue.queueSize = (int)(highestLatencyOfAnyElement * 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,163 @@
|
||||||
|
package config;
|
||||||
|
|
||||||
|
import generic.PortType;
|
||||||
|
|
||||||
|
public class MainMemoryConfig {
|
||||||
|
|
||||||
|
public static enum RowBufferPolicy {
|
||||||
|
OpenPage,
|
||||||
|
ClosePage
|
||||||
|
}
|
||||||
|
|
||||||
|
public static enum QueuingStructure
|
||||||
|
{
|
||||||
|
PerRank,
|
||||||
|
PerRankPerBank
|
||||||
|
};
|
||||||
|
|
||||||
|
public static enum SchedulingPolicy
|
||||||
|
{
|
||||||
|
RankThenBankRoundRobin,
|
||||||
|
BankThenRankRoundRobin
|
||||||
|
};
|
||||||
|
|
||||||
|
public static RowBufferPolicy rowBufferPolicy;
|
||||||
|
public static SchedulingPolicy schedulingPolicy; //TODO: hard-coded for now
|
||||||
|
public static QueuingStructure queuingStructure;
|
||||||
|
|
||||||
|
//system config
|
||||||
|
//changed by harveenk for testing RAM clk
|
||||||
|
//below params acc to DDR3_micron_32M_8B_x4_sg125.ic int numRankPorts;
|
||||||
|
public int numRankPorts;
|
||||||
|
public PortType rankPortType; //TODO: check this
|
||||||
|
public int rankOccupancy;
|
||||||
|
public int rankLatency;
|
||||||
|
public int rankOperatingFrequency; //TODO: currently synchronous with MC
|
||||||
|
|
||||||
|
public double cpu_ram_ratio;
|
||||||
|
|
||||||
|
//system config
|
||||||
|
public int numChans;
|
||||||
|
public int numRanks; //**************************** //TODO Hard coded for now!! Need to calculate this
|
||||||
|
public int numBanks;
|
||||||
|
public int numRows;
|
||||||
|
public int numCols;
|
||||||
|
public int TRANSQUEUE_DEPTH;
|
||||||
|
//public int CMD_QUEUE_DEPTH = 32;
|
||||||
|
public static int TOTAL_ROW_ACCESSES;
|
||||||
|
|
||||||
|
//all timing parameters //TODO: are these to be specified here?
|
||||||
|
|
||||||
|
public int tCCD;
|
||||||
|
public int BL; //this is the number of bursts, not scaled to cpu clock
|
||||||
|
public int tBL;
|
||||||
|
public int tCL;
|
||||||
|
public int tAL;
|
||||||
|
public int tRP;
|
||||||
|
public int tCMD;
|
||||||
|
public int tRC;
|
||||||
|
public int tRCD;
|
||||||
|
public int tRAS;
|
||||||
|
public int tRFC;
|
||||||
|
public int tRTRS;
|
||||||
|
public int tRRD;
|
||||||
|
public int tFAW;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public int tRL;
|
||||||
|
public int tWL;
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
|
||||||
|
public int tCCD = 4;
|
||||||
|
public int tBL = 8;
|
||||||
|
public int tCL = 10;
|
||||||
|
public int tAL = 0;
|
||||||
|
public int tRP = 10;
|
||||||
|
public int tCMD = 1;
|
||||||
|
public int tRC = 34;
|
||||||
|
public int tRCD = 10;
|
||||||
|
public int tRAS = 24;
|
||||||
|
public int tRFC = 107;
|
||||||
|
public int tRTRS = 1;
|
||||||
|
public int tRRD = 4;
|
||||||
|
public int tFAW = 20;
|
||||||
|
|
||||||
|
public int tRL = (tCL+tAL);
|
||||||
|
public int tWL = (tRL-1);
|
||||||
|
|
||||||
|
//for refresh
|
||||||
|
public double tCK=1.5;
|
||||||
|
|
||||||
|
public int tRTP = 5;
|
||||||
|
public int tWTR = 5;
|
||||||
|
public int tWR = 10;
|
||||||
|
*/
|
||||||
|
|
||||||
|
//public int tRL = (tCL+tAL);
|
||||||
|
// public int tWL = (tRL-1);
|
||||||
|
|
||||||
|
//for refresh
|
||||||
|
public double tCK;
|
||||||
|
public int RefreshPeriod;
|
||||||
|
|
||||||
|
public int tRTP;
|
||||||
|
public int tWTR;
|
||||||
|
public int tWR;
|
||||||
|
|
||||||
|
public int ReadToPreDelay;
|
||||||
|
public int WriteToPreDelay;
|
||||||
|
public int ReadToWriteDelay;
|
||||||
|
public int ReadAutopreDelay;
|
||||||
|
public int WriteAutopreDelay;
|
||||||
|
public int WriteToReadDelayB; //interbank
|
||||||
|
public int WriteToReadDelayR; //interrank
|
||||||
|
|
||||||
|
//yet to implement
|
||||||
|
//public int tCKE = 4;
|
||||||
|
//public int tXP = 4;
|
||||||
|
|
||||||
|
|
||||||
|
//bus parameters
|
||||||
|
public int DATA_BUS_BITS; //width of the data bus in bits
|
||||||
|
public int TRANSACTION_SIZE;
|
||||||
|
public int DATA_BUS_BYTES;
|
||||||
|
|
||||||
|
//debug variables
|
||||||
|
public boolean DEBUG_BUS = false;
|
||||||
|
public boolean DEBUG_BANKSTATE = false;
|
||||||
|
public boolean DEBUG_CMDQ = false;
|
||||||
|
|
||||||
|
public RowBufferPolicy getRowBufferPolicy()
|
||||||
|
{
|
||||||
|
return rowBufferPolicy;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getRankNumPorts()
|
||||||
|
{
|
||||||
|
return numRankPorts;
|
||||||
|
}
|
||||||
|
|
||||||
|
public PortType getRankPortType()
|
||||||
|
{
|
||||||
|
return rankPortType;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getRankOccupancy()
|
||||||
|
{
|
||||||
|
return rankOccupancy;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getRankLatency()
|
||||||
|
{
|
||||||
|
return rankLatency;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getRankOperatingFrequency()
|
||||||
|
{
|
||||||
|
return rankOperatingFrequency;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,90 @@
|
||||||
|
/*****************************************************************************
|
||||||
|
Tejas Simulator
|
||||||
|
------------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
Copyright [2010] [Indian Institute of Technology, Delhi]
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
------------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
Contributors: Eldhose Peter
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
package config;
|
||||||
|
|
||||||
|
import generic.PortType;
|
||||||
|
import net.RoutingAlgo;
|
||||||
|
import net.NOC.CONNECTIONTYPE;
|
||||||
|
import net.NOC.TOPOLOGY;
|
||||||
|
import net.RoutingAlgo.ARBITER;
|
||||||
|
import net.RoutingAlgo.SELSCHEME;
|
||||||
|
|
||||||
|
public class NocConfig
|
||||||
|
{
|
||||||
|
public long operatingFreq;
|
||||||
|
public long stepSize;
|
||||||
|
public TOPOLOGY topology;
|
||||||
|
public int latency;
|
||||||
|
public PortType portType;
|
||||||
|
public int accessPorts;
|
||||||
|
public int portOccupancy;
|
||||||
|
public int numberOfBuffers;
|
||||||
|
public RoutingAlgo.ALGO rAlgo;
|
||||||
|
public int latencyBetweenNOCElements;
|
||||||
|
public SELSCHEME selScheme;
|
||||||
|
public ARBITER arbiterType;
|
||||||
|
public int technologyPoint;
|
||||||
|
public CONNECTIONTYPE ConnType;
|
||||||
|
public int numberOfColumns;
|
||||||
|
public int numberOfRows;
|
||||||
|
public String NocTopologyFile;
|
||||||
|
|
||||||
|
public int getLatency() {
|
||||||
|
return latency;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getAccessPorts() {
|
||||||
|
return accessPorts;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getPortOccupancy() {
|
||||||
|
return portOccupancy;
|
||||||
|
}
|
||||||
|
public void setLatency(int latency) {
|
||||||
|
this.latency = latency;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setAccessPorts(int accessPorts) {
|
||||||
|
this.accessPorts = accessPorts;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPortOccupancy(int portOccupancy) {
|
||||||
|
this.portOccupancy = portOccupancy;
|
||||||
|
}
|
||||||
|
public void setTopology(TOPOLOGY topology)
|
||||||
|
{
|
||||||
|
this.topology = topology;
|
||||||
|
}
|
||||||
|
|
||||||
|
public TOPOLOGY getTopology()
|
||||||
|
{
|
||||||
|
return this.topology;
|
||||||
|
}
|
||||||
|
public int getNumberOfBankRows(){
|
||||||
|
return this.numberOfRows;
|
||||||
|
}
|
||||||
|
public int getNumberOfBankColumns(){
|
||||||
|
return this.numberOfColumns;
|
||||||
|
}
|
||||||
|
|
||||||
|
public EnergyConfig power;
|
||||||
|
}
|
|
@ -0,0 +1,11 @@
|
||||||
|
10 10
|
||||||
|
M - D1 - - - - - - -
|
||||||
|
C L2 C L2 C L2 C L2 - -
|
||||||
|
L2 C L2 C L2 C L2 C - -
|
||||||
|
C L2 C L2 C L2 C L2 - -
|
||||||
|
L2 C L2 C L2 C L2 C - -
|
||||||
|
C L2 C L2 C L2 C L2 - -
|
||||||
|
L2 C L2 C L2 C L2 C - -
|
||||||
|
C L2 C L2 C L2 C L2 - -
|
||||||
|
L2 C L2 C L2 C L2 C - -
|
||||||
|
- - - - - - - - - -
|
|
@ -0,0 +1,5 @@
|
||||||
|
package config;
|
||||||
|
|
||||||
|
public enum PipelineType {
|
||||||
|
inOrder,outOfOrder,statistical
|
||||||
|
}
|
|
@ -0,0 +1,56 @@
|
||||||
|
/*****************************************************************************
|
||||||
|
Tejas Simulator
|
||||||
|
------------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
Copyright [2010] [Indian Institute of Technology, Delhi]
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
------------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
Contributors: Moksh Upadhyay, Abhishek Sagar
|
||||||
|
*****************************************************************************/
|
||||||
|
package config;
|
||||||
|
|
||||||
|
import memorysystem.nuca.NucaCache.NucaType;
|
||||||
|
|
||||||
|
public class SimulationConfig
|
||||||
|
{
|
||||||
|
public static int NumTempIntReg; //Number of temporary Integer registers
|
||||||
|
public static boolean IndexAddrModeEnable; //Indexed addressing mode Enabled or disabled
|
||||||
|
public static long MapEmuCores; //Emulator cores to run on
|
||||||
|
public static long MapJavaCores; //Java simulator cores to run on
|
||||||
|
public static long NumInsToIgnore; // Number of "Profilable" instructions to ignore from start
|
||||||
|
public static String outputFileName;
|
||||||
|
public static boolean debugMode;
|
||||||
|
|
||||||
|
public static boolean detachMemSysInsn;
|
||||||
|
public static boolean detachMemSysData;
|
||||||
|
|
||||||
|
public static boolean subsetSimulation;
|
||||||
|
public static long subsetSimSize;
|
||||||
|
public static boolean pinpointsSimulation;
|
||||||
|
public static String pinpointsFile;
|
||||||
|
public static boolean markerFunctionsSimulation;
|
||||||
|
public static String startMarker;
|
||||||
|
public static String endMarker;
|
||||||
|
public static long numInsForTrace;
|
||||||
|
public static long numCyclesForTrace;
|
||||||
|
public static NucaType nucaType;
|
||||||
|
public static boolean powerStats;
|
||||||
|
public static boolean broadcast;
|
||||||
|
|
||||||
|
public static boolean collectInsnWorkingSetInfo;
|
||||||
|
public static long insnWorkingSetChunkSize;
|
||||||
|
|
||||||
|
public static boolean collectDataWorkingSetInfo;
|
||||||
|
public static long dataWorkingSetChunkSize;
|
||||||
|
}
|
|
@ -0,0 +1,65 @@
|
||||||
|
/*****************************************************************************
|
||||||
|
Tejas Simulator
|
||||||
|
------------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
Copyright [2010] [Indian Institute of Technology, Delhi]
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
------------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
Contributors: Moksh Upadhyay
|
||||||
|
*****************************************************************************/
|
||||||
|
package config;
|
||||||
|
|
||||||
|
import java.util.Hashtable;
|
||||||
|
import java.util.Vector;
|
||||||
|
|
||||||
|
import generic.PortType;
|
||||||
|
|
||||||
|
public class SystemConfig
|
||||||
|
{
|
||||||
|
public static enum Interconnect {
|
||||||
|
Bus, Noc
|
||||||
|
}
|
||||||
|
|
||||||
|
public static int NoOfCores;
|
||||||
|
|
||||||
|
public static int maxNumJavaThreads;
|
||||||
|
public static int numEmuThreadsPerJavaThread;
|
||||||
|
|
||||||
|
public static CoreConfig[] core;
|
||||||
|
public static Vector<CacheConfig> sharedCacheConfigs=new Vector<CacheConfig>();
|
||||||
|
|
||||||
|
//added later kush
|
||||||
|
public static boolean memControllerToUse;
|
||||||
|
|
||||||
|
public static int mainMemoryLatency;
|
||||||
|
public static long mainMemoryFrequency;
|
||||||
|
public static long mainMemoryStepSize;
|
||||||
|
public static PortType mainMemPortType;
|
||||||
|
public static int mainMemoryAccessPorts;
|
||||||
|
public static int mainMemoryPortOccupancy;
|
||||||
|
public static int cacheBusLatency;
|
||||||
|
public static String coherenceEnforcingCache;
|
||||||
|
public static BusConfig busConfig;
|
||||||
|
public static NocConfig nocConfig;
|
||||||
|
public static EnergyConfig busEnergy;
|
||||||
|
|
||||||
|
public static Interconnect interconnect;
|
||||||
|
public static EnergyConfig mainMemoryControllerPower;
|
||||||
|
public static EnergyConfig globalClockPower;
|
||||||
|
|
||||||
|
//FIXME
|
||||||
|
//TODO
|
||||||
|
//have to do it here since the object is not being created in xml parser yet
|
||||||
|
public static MainMemoryConfig mainMemoryConfig;
|
||||||
|
}
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,720 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no" ?><!--/*****************************************************************************
|
||||||
|
Tejas Simulator
|
||||||
|
*************************************************************************************
|
||||||
|
|
||||||
|
Copyright 2010 Indian Institute of Technology, Delhi
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
|
||||||
|
******************************************************************************
|
||||||
|
Contributors: Moksh Upadhyay, Abhishek Sagar, Prathmesh Kallurkar
|
||||||
|
*****************************************************************************
|
||||||
|
|
||||||
|
based on Intel® Core™ i7-7820X X-series Processor
|
||||||
|
TDP = 112W
|
||||||
|
52.5 mm x 45 mm
|
||||||
|
/-->
|
||||||
|
<Configuration>
|
||||||
|
<Emulator>
|
||||||
|
<!--Emulator type and communication type define what is the input for instruction data to Tejas-->
|
||||||
|
<!--Currently we support following (emulator,communication) combinations : -->
|
||||||
|
<!--(pin, sharedMemory), (qemu, sharedMemory), (qemu, network), (none, file)-->
|
||||||
|
<!--(pin,file) combination can be used to collect execution trace of an application in a compressed file-->
|
||||||
|
<EmulatorType>none</EmulatorType> <!--pin,qemu-->
|
||||||
|
|
||||||
|
<!--NOTE only file interface supports the execution of multiple benchmarks inside tejas-->
|
||||||
|
<!--if you are reading the packets from a file, the emulator must be set to none-->
|
||||||
|
<!--multiple benchmarks are specified using arguments to the simulator-->
|
||||||
|
<CommunicationType>file</CommunicationType> <!--file,sharedMemory,network-->
|
||||||
|
|
||||||
|
<!--We can use tejas as an interface to create a compressed (gzip) trace file using the emulator-->
|
||||||
|
<!--Set this option to true if you want to create a trace file of the benchmark execution-->
|
||||||
|
<!--In this mode, Tejas will be used only as an interface to the emulator. NO simulation will be performed-->
|
||||||
|
<!--Right now, this option is valid ONLY for emulator type pin and communication type file-->
|
||||||
|
<StoreExecutionTraceInAFile>false</StoreExecutionTraceInAFile>
|
||||||
|
|
||||||
|
<!-- If store packets in a file option is set to true, this parameter indicates the basename for the trace files -->
|
||||||
|
<!--One trace file is maintained for each store. The name of trace file for core n is basename_n.gz-->
|
||||||
|
<!--We do not allow overwriting of trace files. So if a tracefile with same name is pre-existing, kindly rename it-->
|
||||||
|
<BasenameForTraceFiles>/home/prathmesh/tejasupdate/Tejas-dram/test/helloworld_trace</BasenameForTraceFiles>
|
||||||
|
|
||||||
|
<PinTool>/home/rajshekar/softwares/pin-97554/</PinTool>
|
||||||
|
<PinInstrumentor>/home/rajshekar/projects/nvms/workspace/Tejas/src/emulator/pin/obj-pin/causalityTool.so</PinInstrumentor>
|
||||||
|
<QemuTool>TODO/home/prathmesh/workspace/qemu/x86_64-linux-user/qemu-x86_64 /home/prathmesh/tmp/testQemu.o</QemuTool>
|
||||||
|
<ShmLibDirectory>/home/rajshekar/projects/nvms/workspace/Tejas/src/emulator/pin/obj-comm</ShmLibDirectory>
|
||||||
|
<KillEmulatorScript>/home/rajshekar/projects/nvms/workspace/Tejas/src/simulator/main/killAllDescendents.sh</KillEmulatorScript>
|
||||||
|
</Emulator>
|
||||||
|
|
||||||
|
<!--Simulation Parameters-->
|
||||||
|
<Simulation>
|
||||||
|
<CollectInsnWorkingSet>false</CollectInsnWorkingSet>
|
||||||
|
<InsnWorkingSetChunkSize>3000000</InsnWorkingSetChunkSize> <!--Chunk size of instructions over which working set must be noted-->
|
||||||
|
|
||||||
|
<CollectDataWorkingSet>false</CollectDataWorkingSet>
|
||||||
|
<DataWorkingSetChunkSize>3000000</DataWorkingSetChunkSize> <!--Chunk size of instructions over which working set must be noted-->
|
||||||
|
|
||||||
|
<NumTempIntReg>16</NumTempIntReg> <!--Number of temporary Integer registers-->
|
||||||
|
<IndexAddrModeEnable>0</IndexAddrModeEnable> <!--Indexed addressing mode Enabled or disabled (Write 1 for YES, 0 for NO)-->
|
||||||
|
<EmuCores>0</EmuCores> <!--The cores on which emulator will run(supports ',' and '-' for ranges)-->
|
||||||
|
<JavaCores>1</JavaCores> <!--The cores on which simulator will run(supports ',' and '-' for ranges)-->
|
||||||
|
<DebugMode>false</DebugMode> <!--True if debug related printing is desired-->
|
||||||
|
<DetachMemSysData>false</DetachMemSysData>
|
||||||
|
<DetachMemSysInsn>false</DetachMemSysInsn>
|
||||||
|
<PrintPowerStats>true</PrintPowerStats>
|
||||||
|
<Broadcast>false</Broadcast>
|
||||||
|
<pinpointsSim>true</pinpointsSim>
|
||||||
|
<pinpointsFile>/home/rajshekar/benchmarks/cpu2006/PinPoints/perlbench.ref.t.sorted</pinpointsFile>
|
||||||
|
<NumInsToIgnore>0</NumInsToIgnore> <!--Ignores these many profilable instructions from the start of the program-->
|
||||||
|
<subsetSim>true</subsetSim>
|
||||||
|
<subsetSimSize>1000000000</subsetSimSize>
|
||||||
|
<markerFunctions>false</markerFunctions>
|
||||||
|
<startSimMarker>XXX_startInstrumentation</startSimMarker>
|
||||||
|
<endSimMarker>XXX_endInstrumentation</endSimMarker>
|
||||||
|
<NumCores>8</NumCores>
|
||||||
|
</Simulation>
|
||||||
|
|
||||||
|
<!--System Parameters-->
|
||||||
|
<System>
|
||||||
|
<MainMemory>
|
||||||
|
<MemControllerToUse>SIMPLE</MemControllerToUse> <!-- Set the value as DRAM to enable DRAM else use SIMPLE to disable DRAM -->
|
||||||
|
<MainMemoryLatency>100</MainMemoryLatency> <!--The latency of main memory (in clock cycles)-->
|
||||||
|
<MainMemoryFrequency>2100</MainMemoryFrequency> <!--Operating frequency of the main memory (in MHz)-->
|
||||||
|
<MainMemoryPortType>FCFS</MainMemoryPortType> <!--Type of access ports in the Main Memory (UL : Unlimited; FCFS : First Come First Serve; PR : Priority port)-->
|
||||||
|
<MainMemoryAccessPorts>1</MainMemoryAccessPorts> <!--Number of access ports in the Main Memory-->
|
||||||
|
<MainMemoryPortOccupancy>1</MainMemoryPortOccupancy> <!--The occupancy of the Main Memory ports (in clock cycles)-->
|
||||||
|
<LeakageEnergy>0.0073</LeakageEnergy>
|
||||||
|
<DynamicEnergy>0.0544</DynamicEnergy>
|
||||||
|
</MainMemory>
|
||||||
|
|
||||||
|
<CacheBusLatency>1</CacheBusLatency> <!--Latency of the RING used for broadcasting messages for cache coherence-->
|
||||||
|
|
||||||
|
<GlobalClock>
|
||||||
|
<LeakageEnergy>0.3456</LeakageEnergy>
|
||||||
|
<DynamicEnergy>0.2886</DynamicEnergy>
|
||||||
|
</GlobalClock>
|
||||||
|
|
||||||
|
<!--Core Parameters-->
|
||||||
|
<Core>
|
||||||
|
<CoreNumber>0-7</CoreNumber>
|
||||||
|
<CoreFrequency>4200</CoreFrequency> <!--Operating frequency of the core (in MHz)-->
|
||||||
|
<PipelineType>outOfOrder</PipelineType> <!--inOrder,outOfOrder(set issue width for multi-issue in-order)-->
|
||||||
|
|
||||||
|
<BranchPredictor>
|
||||||
|
<Predictor_Mode>TAGE</Predictor_Mode> <!-- Legal Values are NoPredictor, PerfectPredictor, AlwaysTaken, AlwaysNotTaken, Tournament, Bimodal, GAg, GAp, GShare, PAg, PAp, TAGE -->
|
||||||
|
<PCBits>8</PCBits>
|
||||||
|
<BHRsize>16</BHRsize>
|
||||||
|
<BranchMispredPenalty>17</BranchMispredPenalty> <!--Branch misprediction penalty--><!-- https://www.7-cpu.com/cpu/Skylake.html -->
|
||||||
|
<SaturatingBits>2</SaturatingBits>
|
||||||
|
<LeakageEnergy>0.0178</LeakageEnergy>
|
||||||
|
<DynamicEnergy>0.0962</DynamicEnergy>
|
||||||
|
</BranchPredictor>
|
||||||
|
|
||||||
|
<LSQ>
|
||||||
|
<NumLoadEntries>72</NumLoadEntries>
|
||||||
|
<NumStoreEntries>56</NumStoreEntries> <!--Maximum number of entries in the LSQ--><!--72 load entries, 56 store entries in skylake-->
|
||||||
|
<LSQLatency>0</LSQLatency> <!--In clock cycles-->
|
||||||
|
<LSQPortType>UL</LSQPortType> <!--Type of access ports in the LSQ (UL : Unlimited; FCFS : First Come First Serve; PR : Priority port)-->
|
||||||
|
<LSQAccessPorts>-1</LSQAccessPorts> <!--Number of access ports in the LSQ-->
|
||||||
|
<LSQPortOccupancy>-1</LSQPortOccupancy> <!--The occupancy of the LSQ ports (in clock cycles)-->
|
||||||
|
<LeakageEnergy>0.0318</LeakageEnergy>
|
||||||
|
<DynamicEnergy>0.1725</DynamicEnergy>
|
||||||
|
</LSQ>
|
||||||
|
|
||||||
|
<ITLB>
|
||||||
|
<Size>128</Size> <!--Maximum number of entries in the ITLB-->
|
||||||
|
<Latency>1</Latency> <!--In clock cycles-->
|
||||||
|
<MissPenalty>10</MissPenalty> <!--In clock cycles-->
|
||||||
|
<PortType>UL</PortType> <!--Type of access ports in the ITLB (UL : Unlimited; FCFS : First Come First Serve; PR : Priority port)-->
|
||||||
|
<AccessPorts>-1</AccessPorts> <!--Number of access ports in the ITLB-->
|
||||||
|
<PortOccupancy>-1</PortOccupancy> <!--The occupancy of the ITLB ports (in clock cycles)-->
|
||||||
|
<LeakageEnergy>0.00546275</LeakageEnergy>
|
||||||
|
<DynamicEnergy>0.06792852941</DynamicEnergy>
|
||||||
|
</ITLB>
|
||||||
|
|
||||||
|
<DTLB>
|
||||||
|
<Size>64</Size> <!--Maximum number of entries in the DTLB-->
|
||||||
|
<Latency>1</Latency> <!--In clock cycles-->
|
||||||
|
<MissPenalty>10</MissPenalty> <!--In clock cycles-->
|
||||||
|
<PortType>UL</PortType> <!--Type of access ports in the ITLB (UL : Unlimited; FCFS : First Come First Serve; PR : Priority port)-->
|
||||||
|
<AccessPorts>-1</AccessPorts> <!--Number of access ports in the ITLB-->
|
||||||
|
<PortOccupancy>-1</PortOccupancy> <!--The occupancy of the ITLB ports (in clock cycles)-->
|
||||||
|
<LeakageEnergy>0.00546275</LeakageEnergy>
|
||||||
|
<DynamicEnergy>0.06792852941</DynamicEnergy>
|
||||||
|
</DTLB>
|
||||||
|
|
||||||
|
<Decode> <!--Instruction decode-->
|
||||||
|
<Width>6</Width>
|
||||||
|
<LeakageEnergy>0.0598</LeakageEnergy>
|
||||||
|
<DynamicEnergy>0.0347</DynamicEnergy>
|
||||||
|
</Decode>
|
||||||
|
|
||||||
|
<Rename>
|
||||||
|
<RAT>
|
||||||
|
<Integer>
|
||||||
|
<LeakageEnergy>0.0045</LeakageEnergy>
|
||||||
|
<DynamicEnergy>0.0150</DynamicEnergy>
|
||||||
|
</Integer>
|
||||||
|
<Float>
|
||||||
|
<LeakageEnergy>0.0017</LeakageEnergy>
|
||||||
|
<DynamicEnergy>0.0130</DynamicEnergy>
|
||||||
|
</Float>
|
||||||
|
</RAT>
|
||||||
|
<FreeList>
|
||||||
|
<Integer>
|
||||||
|
<LeakageEnergy>0.0016</LeakageEnergy>
|
||||||
|
<DynamicEnergy>0.0085</DynamicEnergy>
|
||||||
|
</Integer>
|
||||||
|
<Float>
|
||||||
|
<LeakageEnergy>0.0030</LeakageEnergy>
|
||||||
|
<DynamicEnergy>0.0045</DynamicEnergy>
|
||||||
|
</Float>
|
||||||
|
</FreeList>
|
||||||
|
</Rename>
|
||||||
|
|
||||||
|
<InstructionWindow>
|
||||||
|
<IssueWidth>8</IssueWidth> <!--Instruction issue width-->
|
||||||
|
<IWSize>97</IWSize> <!--Maximum number of entries in the Instruction Window-->
|
||||||
|
<LeakageEnergy>0.0046</LeakageEnergy>
|
||||||
|
<DynamicEnergy>0.0142</DynamicEnergy>
|
||||||
|
</InstructionWindow>
|
||||||
|
|
||||||
|
<ROB>
|
||||||
|
<RetireWidth>4</RetireWidth> <!--Instruction retire width-->
|
||||||
|
<ROBSize>224</ROBSize> <!--Maximum number of entries in the ROB-->
|
||||||
|
<LeakageEnergy>0.0058</LeakageEnergy>
|
||||||
|
<DynamicEnergy>0.0304</DynamicEnergy>
|
||||||
|
</ROB>
|
||||||
|
|
||||||
|
<RegisterFile>
|
||||||
|
<Integer>
|
||||||
|
<IntRegFileSize>180</IntRegFileSize> <!--Maximum number of entries in the Integer register file-->
|
||||||
|
<IntArchRegNum>32</IntArchRegNum> <!--Number of Integer architectural registers-->
|
||||||
|
<LeakageEnergy>0.0108</LeakageEnergy>
|
||||||
|
<DynamicEnergy>0.0572</DynamicEnergy>
|
||||||
|
</Integer>
|
||||||
|
|
||||||
|
<Float>
|
||||||
|
<FloatRegFileSize>144</FloatRegFileSize> <!--Maximum number of entries in the Floating point register file-->
|
||||||
|
<FloatArchRegNum>32</FloatArchRegNum> <!--Number of Floating point architectural registers-->
|
||||||
|
<LeakageEnergy>0.0075</LeakageEnergy>
|
||||||
|
<DynamicEnergy>0.0207</DynamicEnergy>
|
||||||
|
</Float>
|
||||||
|
|
||||||
|
</RegisterFile>
|
||||||
|
|
||||||
|
<ExecutionCoreNumPorts>8</ExecutionCoreNumPorts>
|
||||||
|
|
||||||
|
<IntALU>
|
||||||
|
<Num>4</Num> <!--Number of Integer ALUs-->
|
||||||
|
<Latency>1</Latency> <!--Latency of Integer ALUs-->
|
||||||
|
<ReciprocalOfThroughput>1</ReciprocalOfThroughput>
|
||||||
|
<!--PortNumber>0</PortNumber-->
|
||||||
|
<PortNumber>0</PortNumber>
|
||||||
|
<PortNumber>1</PortNumber>
|
||||||
|
<PortNumber>5</PortNumber>
|
||||||
|
<PortNumber>6</PortNumber>
|
||||||
|
<LeakageEnergy>0.0542</LeakageEnergy>
|
||||||
|
<DynamicEnergy>0.3257</DynamicEnergy>
|
||||||
|
</IntALU>
|
||||||
|
|
||||||
|
<IntMul>
|
||||||
|
<Num>1</Num>
|
||||||
|
<Latency>3</Latency>
|
||||||
|
<ReciprocalOfThroughput>1</ReciprocalOfThroughput>
|
||||||
|
<PortNumber>1</PortNumber>
|
||||||
|
<LeakageEnergy>0.0271</LeakageEnergy>
|
||||||
|
<DynamicEnergy>0.6514</DynamicEnergy>
|
||||||
|
</IntMul>
|
||||||
|
|
||||||
|
<IntDiv>
|
||||||
|
<Num>1</Num>
|
||||||
|
<Latency>21</Latency>
|
||||||
|
<ReciprocalOfThroughput>12</ReciprocalOfThroughput>
|
||||||
|
<PortNumber>0</PortNumber>
|
||||||
|
<LeakageEnergy>0.0271</LeakageEnergy>
|
||||||
|
<DynamicEnergy>0.6514</DynamicEnergy>
|
||||||
|
</IntDiv>
|
||||||
|
|
||||||
|
<FloatALU>
|
||||||
|
<Num>1</Num>
|
||||||
|
<Latency>3</Latency>
|
||||||
|
<ReciprocalOfThroughput>1</ReciprocalOfThroughput>
|
||||||
|
<PortNumber>1</PortNumber>
|
||||||
|
<LeakageEnergy>0.0654</LeakageEnergy>
|
||||||
|
<DynamicEnergy>0.5366</DynamicEnergy>
|
||||||
|
</FloatALU>
|
||||||
|
|
||||||
|
<FloatMul>
|
||||||
|
<Num>1</Num>
|
||||||
|
<Latency>5</Latency>
|
||||||
|
<ReciprocalOfThroughput>1</ReciprocalOfThroughput>
|
||||||
|
<PortNumber>0</PortNumber>
|
||||||
|
<LeakageEnergy>0.0271</LeakageEnergy>
|
||||||
|
<DynamicEnergy>0.6514</DynamicEnergy>
|
||||||
|
</FloatMul>
|
||||||
|
|
||||||
|
<FloatDiv>
|
||||||
|
<Num>1</Num>
|
||||||
|
<Latency>24</Latency>
|
||||||
|
<ReciprocalOfThroughput>12</ReciprocalOfThroughput>
|
||||||
|
<PortNumber>0</PortNumber>
|
||||||
|
<LeakageEnergy>0.0271</LeakageEnergy>
|
||||||
|
<DynamicEnergy>0.6514</DynamicEnergy>
|
||||||
|
</FloatDiv>
|
||||||
|
|
||||||
|
<Jump>
|
||||||
|
<Num>2</Num>
|
||||||
|
<Latency>1</Latency>
|
||||||
|
<ReciprocalOfThroughput>1</ReciprocalOfThroughput>
|
||||||
|
<PortNumber>0</PortNumber>
|
||||||
|
<PortNumber>6</PortNumber>
|
||||||
|
<LeakageEnergy>0.0271</LeakageEnergy>
|
||||||
|
<DynamicEnergy>0.6514</DynamicEnergy>
|
||||||
|
</Jump>
|
||||||
|
|
||||||
|
<Memory>
|
||||||
|
<Num>4</Num>
|
||||||
|
<Latency>1</Latency>
|
||||||
|
<ReciprocalOfThroughput>1</ReciprocalOfThroughput>
|
||||||
|
<PortNumber>2</PortNumber>
|
||||||
|
<PortNumber>3</PortNumber>
|
||||||
|
<PortNumber>4</PortNumber>
|
||||||
|
<PortNumber>7</PortNumber>
|
||||||
|
<LeakageEnergy>0.0271</LeakageEnergy>
|
||||||
|
<DynamicEnergy>0.6514</DynamicEnergy>
|
||||||
|
</Memory>
|
||||||
|
|
||||||
|
<ResultsBroadcastBus>
|
||||||
|
<LeakageEnergy>0.0239</LeakageEnergy>
|
||||||
|
<DynamicEnergy>0.5948</DynamicEnergy>
|
||||||
|
</ResultsBroadcastBus>
|
||||||
|
|
||||||
|
<TreeBarrier>false</TreeBarrier> <!--Only for particular purposes. Otherwise keep it as false-->
|
||||||
|
<BarrierLatency>2</BarrierLatency>
|
||||||
|
<BarrierUnit>Distributed</BarrierUnit> <!--Central and distributed-->
|
||||||
|
|
||||||
|
<!--Specify all the private caches of a core here-->
|
||||||
|
|
||||||
|
<!--The caches which connect directly to the core must be specified as firstLevel caches-->
|
||||||
|
<!--In case you want to use an unified first level cache, set the cache type to unified in the cache property field-->
|
||||||
|
|
||||||
|
<!--Each cache has has a unique (name,id) pair. The (name,id) pair is used to create connections between caches-->
|
||||||
|
|
||||||
|
<!--For private caches, the id of the cache is the core-number. -->
|
||||||
|
<!--For a shared cache which may be split up, the ids are assigned from 0,1, to (numComponents-1)-->
|
||||||
|
|
||||||
|
<!--nextLevelId field is a mathematical formula which evaluates the id of the next level cache-->
|
||||||
|
<!--The id of the current cache can be specified by a special symbol $i-->
|
||||||
|
<!--It must be used if we want to generate a topology where there are multiple caches in the next level of memory hierarchy-->
|
||||||
|
|
||||||
|
<!--Example icache scenario where there are 4 cores, and 2 cores share same L2 cache-->
|
||||||
|
<!--Cache name="iCache" nextLevel="L2" nextLevelId="$i/2" firstLevel="true" type="ICache_32K_4"/-->
|
||||||
|
<!--Cache name="L2" numComponents="2" nextLevel="L3" type="L2Cache_256K_8"/-->
|
||||||
|
<!--Here core0,core1 will use L2[0] and core2,core3 will use L2[1]-->
|
||||||
|
|
||||||
|
<Cache name="I1" nextLevel="L2" firstLevel="true" type="ICache_32K_8"/>
|
||||||
|
<Cache name="L1" nextLevel="L2" firstLevel="true" type="L1Cache_32K_8"/>
|
||||||
|
<Cache name="L2" nextLevel="L3" type="L2Cache_256K_4"/>
|
||||||
|
</Core>
|
||||||
|
|
||||||
|
<SharedCaches>
|
||||||
|
<Cache name="L3" type="L3Cache_8M_16"/><!--Intel® Core™ i9-7960X X-series Processor actually has 11M L3. Reducing to 8 to keep it a power of 2 (required by Tejas)-->
|
||||||
|
<Cache name="D1" type="Directory1"/>
|
||||||
|
</SharedCaches>
|
||||||
|
|
||||||
|
<Interconnect>BUS</Interconnect>
|
||||||
|
|
||||||
|
<NOC>
|
||||||
|
<NocConfigFile>/home/rajshekar/projects/nvms/configurations/config_1052_8core_skylake_NocConfig.txt</NocConfigFile>
|
||||||
|
<NocSelScheme>STATIC</NocSelScheme>
|
||||||
|
<NocNumberOfBuffers>4</NocNumberOfBuffers>
|
||||||
|
<NocPortType>FCFS</NocPortType>
|
||||||
|
<NocAccessPorts>4</NocAccessPorts>
|
||||||
|
<NocPortOccupancy>1</NocPortOccupancy>
|
||||||
|
<NocLatency>1</NocLatency>
|
||||||
|
<NocOperatingFreq>2000</NocOperatingFreq>
|
||||||
|
<NocTopology>TORUS</NocTopology> <!--NOCTopology-->
|
||||||
|
<NocRoutingAlgorithm>SIMPLE</NocRoutingAlgorithm>
|
||||||
|
<NocLatencyBetweenNOCElements>4</NocLatencyBetweenNOCElements>
|
||||||
|
<NocRouterArbiter>RR_ARBITER</NocRouterArbiter>
|
||||||
|
<TechPoint>90</TechPoint>
|
||||||
|
<NocConnection>ELECTRICAL</NocConnection>
|
||||||
|
|
||||||
|
|
||||||
|
<LeakageEnergy>0.1877</LeakageEnergy>
|
||||||
|
<DynamicEnergy>2.1164</DynamicEnergy>
|
||||||
|
</NOC>
|
||||||
|
|
||||||
|
<BUS>
|
||||||
|
<Latency>30</Latency>
|
||||||
|
<LeakageEnergy>0.1877</LeakageEnergy>
|
||||||
|
<DynamicEnergy>2.1164</DynamicEnergy>
|
||||||
|
</BUS>
|
||||||
|
<MainMemoryController> <!-- These values are used when controller specified above is DRAM (not SIMPLE) -->
|
||||||
|
<rowBufferPolicy>OpenPage</rowBufferPolicy> <!-- OpenPage or ClosePage -->
|
||||||
|
<schedulingPolicy>RankThenBankRoundRobin</schedulingPolicy> <!-- RankThenBankRoundRobin or BankThenRankRoundRobin-->
|
||||||
|
<queuingStructure>PerRank</queuingStructure> <!-- PerRank or PerRankPerBank -->
|
||||||
|
<numRankPorts>1</numRankPorts>
|
||||||
|
<rankPortType>FCFS</rankPortType> <!--Type of access ports in the MainMemoryController (UL : Unlimited; FCFS : First Come First Serve; PR : Priority port)-->
|
||||||
|
<rankOccupancy>1</rankOccupancy>
|
||||||
|
<rankLatency>100</rankLatency>
|
||||||
|
<rankOperatingFrequency>3600</rankOperatingFrequency>
|
||||||
|
<numChans>2</numChans> <!-- Number of physical channels = number of memory controllers -->
|
||||||
|
<numRanks>2</numRanks> <!-- Number of Ranks per memory controller-->
|
||||||
|
<numBanks>8</numBanks> <!-- Number of Banks per Rank -->
|
||||||
|
<numRows>16384</numRows> <!-- Number of Rows per Bank -->
|
||||||
|
<numCols>2048</numCols> <!-- Number of Columns per Bank -->
|
||||||
|
<TRANSQUEUE_DEPTH>32</TRANSQUEUE_DEPTH> <!-- Depth of transaction queue. Note: currently this is not used -->
|
||||||
|
<TOTAL_ROW_ACCESSES>4</TOTAL_ROW_ACCESSES> <!-- For Open Page policy: Number of continuous row accesses after which the row would be closed. This is to prevent starvation to other rows. -->
|
||||||
|
|
||||||
|
<!-- Timing parameters follow below -->
|
||||||
|
<!-- Currently set according to DDR3 Micron 32M 8B x4 speed grade: 125 -->
|
||||||
|
<!-- Timing parameters for other devices can be found in DRAMSim2 repository in GitHub. Check folder "ini" for device specific timing parameters. Or same can be obtained from Datasheets for Micron DDR parts -->
|
||||||
|
|
||||||
|
<tCCD>4</tCCD> <!-- Column-to-Column Delay: internal burst (prefetch) length. DDR: 1, DDR2: 2, DDR2: 4-->
|
||||||
|
<tBL>8</tBL> <!-- Data burst duration i.e. number of bytes returned for each request (burst). Specified in beats not cycles. DDR3: 8 beats -->
|
||||||
|
<tCL>11</tCL> <!-- Column Access Strobe latency. Cycles between column access command and start of data return by the DRAM device -->
|
||||||
|
<tAL>0</tAL> <!-- Latency added to column accesses. Used for posted CAS commands. -->
|
||||||
|
<tRP>11</tRP> <!-- Row Precharge. Time that it takes for the array to precharge (in cycles) -->
|
||||||
|
<tCMD>1</tCMD> <!-- Command transport duration. The num of cycles a command occupies on the command bus from controller to DRAM device (Ranks) -->
|
||||||
|
<tRC>39</tRC> <!-- Row Cycle. Cycles between accesses to different rows in a bank. tRC = tRAS + tRP -->
|
||||||
|
<tRCD>11</tRCD> <!-- Row to Column command delay. Cycles between row access and date readt at sense amplifiers -->
|
||||||
|
<tRAS>28</tRAS> <!-- Row Access Strobe. Cycles between row access command and data restoration in the DRAM array. DRAM bank cannot be precharged until at least tRAS cycles after previous bank activation -->
|
||||||
|
<tRFC>88</tRFC> <!-- Refresh Cycle time. Cycles it takes to refresh the array. -->
|
||||||
|
<tRTRS>1</tRTRS> <!-- Rank to Rank switching time. Cycles required to switch from 1 rank to another rank -->
|
||||||
|
<tRRD>5</tRRD> <!-- Row activation to Row activation delay. Minimum cycles between two row activation commands to the same DRAM device. Limits peak current profile. -->
|
||||||
|
<tFAW>24</tFAW> <!-- Four (row) bank Activation Window. A rolling time-frame in which a maximum of four-bank activation can be engaged. Limits peak current profile. -->
|
||||||
|
<tRTP>6</tRTP> <!-- Rank to Precharge. Cycles between a read and a precharge command. -->
|
||||||
|
<tWTR>6</tWTR> <!-- Write to Read delay time.The minimum time interval -->
|
||||||
|
<tWR>12</tWR> <!-- Write Recovery Time. The minimum cycles between end of a write data burst and the start of a precharge command. Allows sense amplifiers to restore data to cells. -->
|
||||||
|
<tCK>1.25</tCK> <!-- Clock cycle period in ns -->
|
||||||
|
<RefreshPeriod>7800</RefreshPeriod> <!-- Time (in ns) after which a Refresh is issued -->
|
||||||
|
<DATA_BUS_BITS>64</DATA_BUS_BITS> <!-- Width of DATA bus in bits. 64 bits according to JEDEC standard -->
|
||||||
|
</MainMemoryController>
|
||||||
|
|
||||||
|
</System>
|
||||||
|
|
||||||
|
<!--Give all the library elements here-->
|
||||||
|
<Library>
|
||||||
|
<UnifiedCache_32K_8>
|
||||||
|
<Frequency>4200</Frequency> <!-- private caches take frequency of containing core -->
|
||||||
|
<WriteMode>WB</WriteMode> <!--Write-back (WB) or write-through (WT)-->
|
||||||
|
<BlockSize>64</BlockSize> <!--In bytes-->
|
||||||
|
<Associativity>8</Associativity>
|
||||||
|
<Size>32768</Size> <!--In Bytes-->
|
||||||
|
<ReadLatency>3</ReadLatency> <!--In clock cycles-->
|
||||||
|
<WriteLatency>3</WriteLatency> <!--In clock cycles-->
|
||||||
|
<PortType>UL</PortType> <!--Type of access ports in the Cache (UL : Unlimited; FCFS : First Come First Serve; PR : Priority port)-->
|
||||||
|
<ReadPorts>0</ReadPorts>
|
||||||
|
<WritePorts>0</WritePorts>
|
||||||
|
<ReadWritePorts>1</ReadWritePorts>
|
||||||
|
<PortReadOccupancy>1</PortReadOccupancy>
|
||||||
|
<PortWriteOccupancy>1</PortWriteOccupancy>
|
||||||
|
<Coherence>None</Coherence> <!--Coherence of upper level (N : None, S : Snoopy, D : Directory)-->
|
||||||
|
<Prefetcher>None</Prefetcher>
|
||||||
|
<NumBuses>1</NumBuses> <!--Coherence of upper level (N : None, S : Snoopy, D : Directory)-->
|
||||||
|
<MSHRSize>16</MSHRSize>
|
||||||
|
<BusOccupancy>0</BusOccupancy>
|
||||||
|
<Nuca>NONE</Nuca> <!--NUCA type (S_NUCA, D_NUCA, NONE)-->
|
||||||
|
<ONuca>NONE</ONuca> <!--ONUCA type (BCAST, TSI, NONE)-->
|
||||||
|
<NucaMapping>S</NucaMapping> <!--Valid for NUCA; S: Set-Associative A: Address-Mapped -->
|
||||||
|
<LeakageEnergy>0.1092</LeakageEnergy>
|
||||||
|
<ReadDynamicEnergy>0.33964264705</ReadDynamicEnergy>
|
||||||
|
<WriteDynamicEnergy>0.33964264705</WriteDynamicEnergy>
|
||||||
|
<CacheType>Unified</CacheType> <!--Instruction,Data,Unified-->
|
||||||
|
</UnifiedCache_32K_8>
|
||||||
|
|
||||||
|
<ICache_32K_8>
|
||||||
|
<Frequency>4200</Frequency> <!-- private caches take frequency of containing core -->
|
||||||
|
<WriteMode>WB</WriteMode> <!--Write-back (WB) or write-through (WT)-->
|
||||||
|
<BlockSize>64</BlockSize> <!--In bytes-->
|
||||||
|
<Associativity>8</Associativity>
|
||||||
|
<Size>32768</Size> <!--In Bytes-->
|
||||||
|
<ReadLatency>4</ReadLatency> <!--In clock cycles-->
|
||||||
|
<WriteLatency>4</WriteLatency> <!--In clock cycles-->
|
||||||
|
<PortType>FCFS</PortType> <!--Type of access ports in the Cache (UL : Unlimited; FCFS : First Come First Serve; PR : Priority port)-->
|
||||||
|
<ReadPorts>0</ReadPorts>
|
||||||
|
<WritePorts>0</WritePorts>
|
||||||
|
<ReadWritePorts>4</ReadWritePorts>
|
||||||
|
<PortReadOccupancy>1</PortReadOccupancy>
|
||||||
|
<PortWriteOccupancy>1</PortWriteOccupancy>
|
||||||
|
<Coherence>None</Coherence> <!--Coherence of upper level (N : None, S : Snoopy, D : Directory)-->
|
||||||
|
<Prefetcher>None</Prefetcher>
|
||||||
|
<NumBuses>1</NumBuses> <!--Coherence of upper level (N : None, S : Snoopy, D : Directory)-->
|
||||||
|
<MSHRSize>16</MSHRSize>
|
||||||
|
<BusOccupancy>0</BusOccupancy>
|
||||||
|
<Nuca>NONE</Nuca> <!--NUCA type (S_NUCA, D_NUCA, NONE)-->
|
||||||
|
<ONuca>NONE</ONuca> <!--ONUCA type (BCAST, TSI, NONE)-->
|
||||||
|
<NucaMapping>S</NucaMapping> <!--Valid for NUCA; S: Set-Associative A: Address-Mapped -->
|
||||||
|
<LeakageEnergy>0.1092</LeakageEnergy>
|
||||||
|
<ReadDynamicEnergy>0.33964264705</ReadDynamicEnergy>
|
||||||
|
<WriteDynamicEnergy>0.33964264705</WriteDynamicEnergy>
|
||||||
|
<CacheType>Instruction</CacheType> <!--I : Instruction, D : Data, U : Unified-->
|
||||||
|
</ICache_32K_8>
|
||||||
|
|
||||||
|
<L1Cache_32K_8>
|
||||||
|
<Frequency>4200</Frequency> <!-- private caches take frequency of containing core -->
|
||||||
|
<WriteMode>WT</WriteMode> <!--Write-back (WB) or write-through (WT)-->
|
||||||
|
<BlockSize>64</BlockSize> <!--In bytes-->
|
||||||
|
<Associativity>8</Associativity>
|
||||||
|
<Size>32768</Size> <!--In Bytes-->
|
||||||
|
<ReadLatency>4</ReadLatency> <!--In clock cycles-->
|
||||||
|
<WriteLatency>4</WriteLatency> <!--In clock cycles-->
|
||||||
|
<PortType>UL</PortType> <!--Type of access ports in the Cache (UL : Unlimited; FCFS : First Come First Serve; PR : Priority port)-->
|
||||||
|
<ReadPorts>0</ReadPorts>
|
||||||
|
<WritePorts>0</WritePorts>
|
||||||
|
<ReadWritePorts>2</ReadWritePorts>
|
||||||
|
<PortReadOccupancy>1</PortReadOccupancy>
|
||||||
|
<PortWriteOccupancy>1</PortWriteOccupancy>
|
||||||
|
<Coherence>None</Coherence> <!--Coherence of upper level (N : None, S : Snoopy, D : Directory)-->
|
||||||
|
<Prefetcher>None</Prefetcher>
|
||||||
|
<NumBuses>1</NumBuses> <!--Coherence of upper level (N : None, S : Snoopy, D : Directory)-->
|
||||||
|
<MSHRSize>16</MSHRSize>
|
||||||
|
<BusOccupancy>0</BusOccupancy>
|
||||||
|
<Nuca>NONE</Nuca> <!--NUCA type (S_NUCA, D_NUCA, NONE)-->
|
||||||
|
<ONuca>NONE</ONuca> <!--ONUCA type (BCAST, TSI, NONE)-->
|
||||||
|
<NucaMapping>S</NucaMapping> <!--Valid for NUCA; S: Set-Associative A: Address-Mapped -->
|
||||||
|
<LeakageEnergy>0.1092</LeakageEnergy>
|
||||||
|
<ReadDynamicEnergy>0.33964264705</ReadDynamicEnergy>
|
||||||
|
<WriteDynamicEnergy>0.33964264705</WriteDynamicEnergy>
|
||||||
|
<CacheType>Data</CacheType> <!--I : Instruction, D : Data, U : Unified-->
|
||||||
|
</L1Cache_32K_8>
|
||||||
|
|
||||||
|
<L2Cache_256K_8>
|
||||||
|
<WriteMode>WB</WriteMode> <!--Write-back (WB) or write-through (WT)-->
|
||||||
|
<BlockSize>64</BlockSize> <!--In bytes-->
|
||||||
|
<Associativity>8</Associativity>
|
||||||
|
<Size>262144</Size> <!--In Bytes-->
|
||||||
|
<ReadLatency>12</ReadLatency> <!--In clock cycles-->
|
||||||
|
<WriteLatency>12</WriteLatency> <!--In clock cycles-->
|
||||||
|
<PortType>FCFS</PortType> <!--Type of access ports in the Cache (UL : Unlimited; FCFS : First Come First Serve; PR : Priority port)-->
|
||||||
|
<ReadPorts>0</ReadPorts>
|
||||||
|
<WritePorts>0</WritePorts>
|
||||||
|
<ReadWritePorts>1</ReadWritePorts>
|
||||||
|
<PortReadOccupancy>1</PortReadOccupancy>
|
||||||
|
<PortWriteOccupancy>1</PortWriteOccupancy>
|
||||||
|
<Coherence>None</Coherence> <!--Coherence of upper level (N : None, S : Snoopy, D : Directory)-->
|
||||||
|
<Prefetcher>None</Prefetcher>
|
||||||
|
<NumBuses>1</NumBuses> <!--Coherence of upper level (N : None, S : Snoopy, D : Directory)-->
|
||||||
|
<MSHRSize>256</MSHRSize>
|
||||||
|
<BusOccupancy>0</BusOccupancy>
|
||||||
|
<Nuca>NONE</Nuca> <!--NUCA type (S_NUCA, D_NUCA, NONE)-->
|
||||||
|
<ONuca>NONE</ONuca> <!--ONUCA type (BCAST, TSI)-->
|
||||||
|
<NucaMapping>S</NucaMapping> <!--Valid for NUCA; S: Set-Associative A: Address-Mapped -->
|
||||||
|
<LeakageEnergy>0.1592</LeakageEnergy>
|
||||||
|
<ReadDynamicEnergy>0.43964264705</ReadDynamicEnergy>
|
||||||
|
<WriteDynamicEnergy>0.43964264705</WriteDynamicEnergy>
|
||||||
|
<CacheType>Unified</CacheType> <!--I : Instruction, D : Data, U : Unified-->
|
||||||
|
</L2Cache_256K_8>
|
||||||
|
|
||||||
|
<L2Cache_256K_4>
|
||||||
|
<Frequency>4200</Frequency> <!-- private caches take frequency of containing core -->
|
||||||
|
<WriteMode>WB</WriteMode> <!--Write-back (WB) or write-through (WT)-->
|
||||||
|
<BlockSize>64</BlockSize> <!--In bytes-->
|
||||||
|
<Associativity>4</Associativity>
|
||||||
|
<Size>262144</Size> <!--In Bytes-->
|
||||||
|
<ReadLatency>12</ReadLatency> <!--In clock cycles-->
|
||||||
|
<WriteLatency>12</WriteLatency> <!--In clock cycles-->
|
||||||
|
<PortType>FCFS</PortType> <!--Type of access ports in the Cache (UL : Unlimited; FCFS : First Come First Serve; PR : Priority port)-->
|
||||||
|
<ReadPorts>0</ReadPorts>
|
||||||
|
<WritePorts>0</WritePorts>
|
||||||
|
<ReadWritePorts>1</ReadWritePorts>
|
||||||
|
<PortReadOccupancy>1</PortReadOccupancy>
|
||||||
|
<PortWriteOccupancy>1</PortWriteOccupancy>
|
||||||
|
<Coherence>D1</Coherence> <!--Coherence of upper level (N : None, S : Snoopy, D : Directory)-->
|
||||||
|
<Prefetcher>Power4</Prefetcher>
|
||||||
|
<NumBuses>1</NumBuses> <!--Coherence of upper level (N : None, S : Snoopy, D : Directory)-->
|
||||||
|
<MSHRSize>256</MSHRSize>
|
||||||
|
<BusOccupancy>0</BusOccupancy>
|
||||||
|
<Nuca>NONE</Nuca> <!--NUCA type (S_NUCA, D_NUCA, NONE)-->
|
||||||
|
<ONuca>NONE</ONuca> <!--ONUCA type (BCAST, TSI)-->
|
||||||
|
<NucaMapping>S</NucaMapping> <!--Valid for NUCA; S: Set-Associative A: Address-Mapped -->
|
||||||
|
<LeakageEnergy>0.1592</LeakageEnergy>
|
||||||
|
<ReadDynamicEnergy>0.43964264705</ReadDynamicEnergy>
|
||||||
|
<WriteDynamicEnergy>0.43964264705</WriteDynamicEnergy>
|
||||||
|
<CacheType>Unified</CacheType> <!--I : Instruction, D : Data, U : Unified-->
|
||||||
|
</L2Cache_256K_4>
|
||||||
|
|
||||||
|
<L3Cache_1M_8>
|
||||||
|
<Frequency>2000</Frequency>
|
||||||
|
<WriteMode>WB</WriteMode> <!--Write-back (WB) or write-through (WT)-->
|
||||||
|
<BlockSize>64</BlockSize> <!--In bytes-->
|
||||||
|
<Associativity>8</Associativity>
|
||||||
|
<Size>1048576</Size> <!--In Bytes-->
|
||||||
|
<ReadLatency>60</ReadLatency> <!--In clock cycles-->
|
||||||
|
<WriteLatency>60</WriteLatency> <!--In clock cycles-->
|
||||||
|
<PortType>UL</PortType> <!--Type of access ports in the Cache (UL : Unlimited; FCFS : First Come First Serve; PR : Priority port)-->
|
||||||
|
<ReadPorts>0</ReadPorts>
|
||||||
|
<WritePorts>0</WritePorts>
|
||||||
|
<ReadWritePorts>1</ReadWritePorts>
|
||||||
|
<PortReadOccupancy>1</PortReadOccupancy>
|
||||||
|
<PortWriteOccupancy>1</PortWriteOccupancy>
|
||||||
|
<Coherence>None</Coherence> <!--Coherence of upper level (N : None, S : Snoopy, D : Directory)-->
|
||||||
|
<Prefetcher>None</Prefetcher>
|
||||||
|
<NumBuses>1</NumBuses> <!--Coherence of upper level (N : None, S : Snoopy, D : Directory)-->
|
||||||
|
<MSHRSize>8</MSHRSize>
|
||||||
|
<BusOccupancy>0</BusOccupancy>
|
||||||
|
<Nuca>NONE</Nuca> <!--NUCA type (S_NUCA, D_NUCA, NONE)-->
|
||||||
|
<ONuca>NONE</ONuca> <!--ONUCA type (BCAST, TSI, NONE)-->
|
||||||
|
<NucaMapping>S</NucaMapping> <!--Valid for NUCA; S: Set-Associative A: Address-Mapped -->
|
||||||
|
<LeakageEnergy>0.1892</LeakageEnergy>
|
||||||
|
<ReadDynamicEnergy>0.60964264705</ReadDynamicEnergy>
|
||||||
|
<WriteDynamicEnergy>0.60964264705</WriteDynamicEnergy>
|
||||||
|
<CacheType>Unified</CacheType> <!--I : Instruction, D : Data, U : Unified-->
|
||||||
|
</L3Cache_1M_8>
|
||||||
|
|
||||||
|
<L3Cache_8M_16>
|
||||||
|
<Frequency>2000</Frequency>
|
||||||
|
<WriteMode>WB</WriteMode> <!--Write-back (WB) or write-through (WT)-->
|
||||||
|
<BlockSize>64</BlockSize> <!--In bytes-->
|
||||||
|
<Associativity>16</Associativity>
|
||||||
|
<Size>8388608</Size> <!--In Bytes-->
|
||||||
|
<ReadLatency>60</ReadLatency> <!--In clock cycles-->
|
||||||
|
<WriteLatency>60</WriteLatency> <!--In clock cycles-->
|
||||||
|
<PortType>UL</PortType> <!--Type of access ports in the Cache (UL : Unlimited; FCFS : First Come First Serve; PR : Priority port)-->
|
||||||
|
<ReadPorts>0</ReadPorts>
|
||||||
|
<WritePorts>0</WritePorts>
|
||||||
|
<ReadWritePorts>1</ReadWritePorts>
|
||||||
|
<PortReadOccupancy>5</PortReadOccupancy>
|
||||||
|
<PortWriteOccupancy>5</PortWriteOccupancy>
|
||||||
|
<Coherence>None</Coherence> <!--Coherence of upper level (N : None, S : Snoopy, D : Directory)-->
|
||||||
|
<Prefetcher>Power4</Prefetcher>
|
||||||
|
<NumBuses>1</NumBuses> <!--Coherence of upper level (N : None, S : Snoopy, D : Directory)-->
|
||||||
|
<MSHRSize>8</MSHRSize>
|
||||||
|
<BusOccupancy>0</BusOccupancy>
|
||||||
|
<Nuca>NONE</Nuca> <!--NUCA type (S_NUCA, D_NUCA, NONE)-->
|
||||||
|
<ONuca>NONE</ONuca> <!--ONUCA type (BCAST, TSI, NONE)-->
|
||||||
|
<NucaMapping>S</NucaMapping> <!--Valid for NUCA; S: Set-Associative A: Address-Mapped -->
|
||||||
|
<LeakageEnergy>0.1892</LeakageEnergy>
|
||||||
|
<ReadDynamicEnergy>0.60964264705</ReadDynamicEnergy>
|
||||||
|
<WriteDynamicEnergy>0.60964264705</WriteDynamicEnergy>
|
||||||
|
<CacheType>Unified</CacheType> <!--I : Instruction, D : Data, U : Unified-->
|
||||||
|
</L3Cache_8M_16>
|
||||||
|
|
||||||
|
<L3Cache_12M_16>
|
||||||
|
<Frequency>2000</Frequency>
|
||||||
|
<WriteMode>WB</WriteMode> <!--Write-back (WB) or write-through (WT)-->
|
||||||
|
<BlockSize>64</BlockSize> <!--In bytes-->
|
||||||
|
<Associativity>16</Associativity>
|
||||||
|
<Size>12582912</Size> <!--In Bytes-->
|
||||||
|
<ReadLatency>60</ReadLatency> <!--In clock cycles-->
|
||||||
|
<WriteLatency>60</WriteLatency> <!--In clock cycles-->
|
||||||
|
<PortType>UL</PortType> <!--Type of access ports in the Cache (UL : Unlimited; FCFS : First Come First Serve; PR : Priority port)-->
|
||||||
|
<ReadPorts>0</ReadPorts>
|
||||||
|
<WritePorts>0</WritePorts>
|
||||||
|
<ReadWritePorts>1</ReadWritePorts>
|
||||||
|
<PortReadOccupancy>1</PortReadOccupancy>
|
||||||
|
<PortWriteOccupancy>1</PortWriteOccupancy>
|
||||||
|
<Coherence>None</Coherence> <!--Coherence of upper level (N : None, S : Snoopy, D : Directory)-->
|
||||||
|
<Prefetcher>None</Prefetcher>
|
||||||
|
<NumBuses>1</NumBuses> <!--Coherence of upper level (N : None, S : Snoopy, D : Directory)-->
|
||||||
|
<MSHRSize>8</MSHRSize>
|
||||||
|
<BusOccupancy>0</BusOccupancy>
|
||||||
|
<Nuca>NONE</Nuca> <!--NUCA type (S_NUCA, D_NUCA, NONE)-->
|
||||||
|
<ONuca>NONE</ONuca> <!--ONUCA type (BCAST, TSI, NONE)-->
|
||||||
|
<NucaMapping>S</NucaMapping> <!--Valid for NUCA; S: Set-Associative A: Address-Mapped -->
|
||||||
|
<LeakageEnergy>0.1892</LeakageEnergy>
|
||||||
|
<ReadDynamicEnergy>0.60964264705</ReadDynamicEnergy>
|
||||||
|
<WriteDynamicEnergy>0.60964264705</WriteDynamicEnergy>
|
||||||
|
<CacheType>Unified</CacheType> <!--I : Instruction, D : Data, U : Unified-->
|
||||||
|
</L3Cache_12M_16>
|
||||||
|
|
||||||
|
<L3Cache_22M_16>
|
||||||
|
<Frequency>2000</Frequency>
|
||||||
|
<WriteMode>WB</WriteMode> <!--Write-back (WB) or write-through (WT)-->
|
||||||
|
<BlockSize>64</BlockSize> <!--In bytes-->
|
||||||
|
<Associativity>16</Associativity>
|
||||||
|
<Size>23068672</Size> <!--In Bytes-->
|
||||||
|
<ReadLatency>44</ReadLatency> <!--In clock cycles-->
|
||||||
|
<WriteLatency>44</WriteLatency> <!--In clock cycles-->
|
||||||
|
<PortType>UL</PortType> <!--Type of access ports in the Cache (UL : Unlimited; FCFS : First Come First Serve; PR : Priority port)-->
|
||||||
|
<ReadPorts>0</ReadPorts>
|
||||||
|
<WritePorts>0</WritePorts>
|
||||||
|
<ReadWritePorts>1</ReadWritePorts>
|
||||||
|
<PortReadOccupancy>1</PortReadOccupancy>
|
||||||
|
<PortWriteOccupancy>1</PortWriteOccupancy>
|
||||||
|
<Coherence>None</Coherence> <!--Coherence of upper level (N : None, S : Snoopy, D : Directory)-->
|
||||||
|
<Prefetcher>None</Prefetcher>
|
||||||
|
<NumBuses>1</NumBuses> <!--Coherence of upper level (N : None, S : Snoopy, D : Directory)-->
|
||||||
|
<MSHRSize>8</MSHRSize>
|
||||||
|
<BusOccupancy>0</BusOccupancy>
|
||||||
|
<Nuca>NONE</Nuca> <!--NUCA type (S_NUCA, D_NUCA, NONE)-->
|
||||||
|
<ONuca>NONE</ONuca> <!--ONUCA type (BCAST, TSI, NONE)-->
|
||||||
|
<NucaMapping>S</NucaMapping> <!--Valid for NUCA; S: Set-Associative A: Address-Mapped -->
|
||||||
|
<LeakageEnergy>0.1892</LeakageEnergy>
|
||||||
|
<ReadDynamicEnergy>0.60964264705</ReadDynamicEnergy>
|
||||||
|
<WriteDynamicEnergy>0.60964264705</WriteDynamicEnergy>
|
||||||
|
<CacheType>Unified</CacheType> <!--I : Instruction, D : Data, U : Unified-->
|
||||||
|
</L3Cache_22M_16>
|
||||||
|
|
||||||
|
<L3Cache_16M_16>
|
||||||
|
<Frequency>2000</Frequency>
|
||||||
|
<WriteMode>WB</WriteMode> <!--Write-back (WB) or write-through (WT)-->
|
||||||
|
<BlockSize>64</BlockSize> <!--In bytes-->
|
||||||
|
<Associativity>16</Associativity>
|
||||||
|
<Size>16777216</Size> <!--In Bytes-->
|
||||||
|
<ReadLatency>44</ReadLatency> <!--In clock cycles-->
|
||||||
|
<WriteLatency>44</WriteLatency> <!--In clock cycles-->
|
||||||
|
<PortType>UL</PortType> <!--Type of access ports in the Cache (UL : Unlimited; FCFS : First Come First Serve; PR : Priority port)-->
|
||||||
|
<ReadPorts>0</ReadPorts>
|
||||||
|
<WritePorts>0</WritePorts>
|
||||||
|
<ReadWritePorts>1</ReadWritePorts>
|
||||||
|
<PortReadOccupancy>5</PortReadOccupancy>
|
||||||
|
<PortWriteOccupancy>5</PortWriteOccupancy>
|
||||||
|
<Coherence>None</Coherence> <!--Coherence of upper level (N : None, S : Snoopy, D : Directory)-->
|
||||||
|
<Prefetcher>None</Prefetcher>
|
||||||
|
<NumBuses>1</NumBuses> <!--Coherence of upper level (N : None, S : Snoopy, D : Directory)-->
|
||||||
|
<MSHRSize>8</MSHRSize>
|
||||||
|
<BusOccupancy>0</BusOccupancy>
|
||||||
|
<Nuca>NONE</Nuca> <!--NUCA type (S_NUCA, D_NUCA, NONE)-->
|
||||||
|
<ONuca>NONE</ONuca> <!--ONUCA type (BCAST, TSI, NONE)-->
|
||||||
|
<NucaMapping>S</NucaMapping> <!--Valid for NUCA; S: Set-Associative A: Address-Mapped -->
|
||||||
|
<LeakageEnergy>0.1892</LeakageEnergy>
|
||||||
|
<ReadDynamicEnergy>0.60964264705</ReadDynamicEnergy>
|
||||||
|
<WriteDynamicEnergy>0.60964264705</WriteDynamicEnergy>
|
||||||
|
<CacheType>Unified</CacheType> <!--I : Instruction, D : Data, U : Unified-->
|
||||||
|
</L3Cache_16M_16>
|
||||||
|
|
||||||
|
<Directory1>
|
||||||
|
<Frequency>2000</Frequency>
|
||||||
|
<WriteMode>WB</WriteMode> <!--Write-back (WB) or write-through (WT)-->
|
||||||
|
<LastLevel>N</LastLevel> <!--Whether this is the last level in the hierarchy or not (Y for yes, N for no)-->
|
||||||
|
<BlockSize>64</BlockSize> <!--In bytes (this should be same as the block size of the Caches between those you want coherence)-->
|
||||||
|
<Associativity>64</Associativity>
|
||||||
|
<NumEntries>65536</NumEntries>
|
||||||
|
<ReadLatency>5</ReadLatency> <!--In clock cycles-->
|
||||||
|
<WriteLatency>5</WriteLatency> <!--In clock cycles-->
|
||||||
|
<PortType>FCFS</PortType> <!--Type of access ports in the Cache (UL : Unlimited; FCFS : First Come First Serve; PR : Priority port)-->
|
||||||
|
<ReadPorts>0</ReadPorts>
|
||||||
|
<WritePorts>0</WritePorts>
|
||||||
|
<ReadWritePorts>2</ReadWritePorts>
|
||||||
|
<PortReadOccupancy>1</PortReadOccupancy>
|
||||||
|
<PortWriteOccupancy>1</PortWriteOccupancy>
|
||||||
|
<Coherence>N</Coherence> <!--Coherence of upper level (N : None, S : Snoopy, D : Directory)-->
|
||||||
|
<Prefetcher>None</Prefetcher>
|
||||||
|
<NumBuses>1</NumBuses> <!--Coherence of upper level (N : None, S : Snoopy, D : Directory)-->
|
||||||
|
<MSHRSize>16</MSHRSize>
|
||||||
|
<BusOccupancy>0</BusOccupancy>
|
||||||
|
<Nuca>NONE</Nuca> <!--NUCA type (S_NUCA, D_NUCA, NONE)-->
|
||||||
|
<ONuca>NONE</ONuca> <!--ONUCA type (BCAST, TSI, NONE)-->
|
||||||
|
<NucaMapping>S</NucaMapping> <!--Valid for NUCA; S: Set-Associative A: Address-Mapped -->
|
||||||
|
<CacheType>Unified</CacheType>
|
||||||
|
<LeakageEnergy>.1092</LeakageEnergy>
|
||||||
|
<ReadDynamicEnergy>.3396</ReadDynamicEnergy>
|
||||||
|
<WriteDynamicEnergy>.3396</WriteDynamicEnergy>
|
||||||
|
<IsDirectory>true</IsDirectory>
|
||||||
|
<CacheType>Unified</CacheType> <!--I : Instruction, D : Data, U : Unified-->
|
||||||
|
</Directory1>
|
||||||
|
|
||||||
|
</Library>
|
||||||
|
|
||||||
|
</Configuration>
|
|
@ -0,0 +1,5 @@
|
||||||
|
package dram;
|
||||||
|
|
||||||
|
public class Bank {
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,54 @@
|
||||||
|
package dram;
|
||||||
|
|
||||||
|
import dram.MainMemoryBusPacket.BusPacketType;
|
||||||
|
import generic.RequestType;
|
||||||
|
|
||||||
|
|
||||||
|
public class BankState {
|
||||||
|
|
||||||
|
public enum CurrentBankState
|
||||||
|
{
|
||||||
|
IDLE,
|
||||||
|
ROW_ACTIVE,
|
||||||
|
PRECHARGING,
|
||||||
|
REFRESHING,
|
||||||
|
POWER_DOWN
|
||||||
|
}
|
||||||
|
|
||||||
|
CurrentBankState currentBankState;
|
||||||
|
int openRowAddress;
|
||||||
|
long nextRead;
|
||||||
|
long nextWrite;
|
||||||
|
long nextActivate;
|
||||||
|
long nextPrecharge;
|
||||||
|
long nextPowerUp;
|
||||||
|
|
||||||
|
BusPacketType lastCommand;
|
||||||
|
|
||||||
|
BankState()
|
||||||
|
{
|
||||||
|
//System.out.println("HI!! Constructing Bank States");
|
||||||
|
currentBankState = CurrentBankState.IDLE;
|
||||||
|
openRowAddress = 0;
|
||||||
|
nextRead = 0;
|
||||||
|
nextWrite = 0;
|
||||||
|
nextActivate = 0;
|
||||||
|
nextPrecharge = 0;
|
||||||
|
nextPowerUp = 0;
|
||||||
|
lastCommand = BusPacketType.READ;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void printState()
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
System.out.println("current Bank State: "+ currentBankState +" "+ openRowAddress +" "
|
||||||
|
+ nextRead +" "+
|
||||||
|
nextWrite +" "+
|
||||||
|
nextActivate +" "+
|
||||||
|
nextPrecharge +" "+
|
||||||
|
nextPowerUp +" "+
|
||||||
|
lastCommand);
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,5 @@
|
||||||
|
package dram;
|
||||||
|
|
||||||
|
public class BusPacketQueue1D {
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,5 @@
|
||||||
|
package dram;
|
||||||
|
|
||||||
|
public class BusPacketQueue2D {
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,773 @@
|
||||||
|
package dram;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
|
||||||
|
//import com.sun.xml.internal.bind.v2.runtime.unmarshaller.XsiNilLoader.Array;
|
||||||
|
|
||||||
|
import config.MainMemoryConfig;
|
||||||
|
import config.MainMemoryConfig.QueuingStructure;
|
||||||
|
import config.MainMemoryConfig.RowBufferPolicy;
|
||||||
|
import config.MainMemoryConfig.SchedulingPolicy;
|
||||||
|
import dram.BankState.CurrentBankState;
|
||||||
|
import dram.MainMemoryBusPacket.BusPacketType;
|
||||||
|
import generic.GlobalClock;
|
||||||
|
import main.Main;
|
||||||
|
import misc.Error;
|
||||||
|
import net.Bus;
|
||||||
|
|
||||||
|
public class CommandQueue {
|
||||||
|
|
||||||
|
ArrayList<MainMemoryBusPacket> BusPacketQueue1D;
|
||||||
|
ArrayList<ArrayList<MainMemoryBusPacket>> perRankQueue;
|
||||||
|
ArrayList<ArrayList<ArrayList<MainMemoryBusPacket>>> queues;
|
||||||
|
//QueuingStructure queuingStructure; //in mainmemconfig
|
||||||
|
int numBankQueues;
|
||||||
|
int CMD_QUEUE_DEPTH;
|
||||||
|
|
||||||
|
BankState[][] bankStates;
|
||||||
|
int rowAccessCounters[][];
|
||||||
|
|
||||||
|
MainMemoryConfig mainMemoryConfig;
|
||||||
|
int nextRank;
|
||||||
|
int nextBank;
|
||||||
|
int nextRankPRE;
|
||||||
|
int nextBankPRE;
|
||||||
|
int refreshRank;
|
||||||
|
boolean refreshWaiting;
|
||||||
|
boolean sendAct;
|
||||||
|
ArrayList<ArrayList<Integer>> tFAWCountdown;
|
||||||
|
|
||||||
|
public CommandQueue(MainMemoryConfig mainMemoryConfig,BankState bankStates[][])
|
||||||
|
{
|
||||||
|
sendAct=true;
|
||||||
|
nextBank=0;
|
||||||
|
nextRank=0;
|
||||||
|
refreshWaiting=false;
|
||||||
|
refreshRank=0;
|
||||||
|
nextBankPRE=0;
|
||||||
|
nextRankPRE=0;
|
||||||
|
|
||||||
|
|
||||||
|
this.mainMemoryConfig=mainMemoryConfig;
|
||||||
|
rowAccessCounters=new int[mainMemoryConfig.numRanks][mainMemoryConfig.numBanks];
|
||||||
|
tFAWCountdown=new ArrayList<ArrayList<Integer>>(mainMemoryConfig.numRanks);
|
||||||
|
|
||||||
|
for (int i=0;i<mainMemoryConfig.numRanks;i++)
|
||||||
|
{
|
||||||
|
//init the empty vectors here so we don't seg fault later
|
||||||
|
tFAWCountdown.add(new ArrayList<Integer>());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
this.bankStates=bankStates;
|
||||||
|
|
||||||
|
|
||||||
|
if (mainMemoryConfig.queuingStructure==QueuingStructure.PerRank)
|
||||||
|
{
|
||||||
|
numBankQueues = 1;
|
||||||
|
}
|
||||||
|
else if (mainMemoryConfig.queuingStructure==QueuingStructure.PerRankPerBank)
|
||||||
|
{
|
||||||
|
numBankQueues = mainMemoryConfig.numBanks;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Error.showErrorAndExit("== Error - Unknown queuing structure");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//BusPacketQueue1D = new ArrayList<MainMemoryBusPacket>();
|
||||||
|
this.CMD_QUEUE_DEPTH = 1024;
|
||||||
|
|
||||||
|
//perRankQueue = new ArrayList<ArrayList<MainMemoryBusPacket>>();
|
||||||
|
queues = new ArrayList<ArrayList<ArrayList<MainMemoryBusPacket>>>();
|
||||||
|
for (int rank=0; rank<mainMemoryConfig.numRanks; rank++)
|
||||||
|
{
|
||||||
|
//this loop will run only once for per-rank and NUM_BANKS times for per-rank-per-bank
|
||||||
|
perRankQueue = new ArrayList<ArrayList<MainMemoryBusPacket>>();
|
||||||
|
|
||||||
|
for (int bank=0; bank<numBankQueues; bank++)
|
||||||
|
{
|
||||||
|
BusPacketQueue1D = new ArrayList<MainMemoryBusPacket>();
|
||||||
|
|
||||||
|
//actualQueue = BusPacket1D();
|
||||||
|
//System.out.println(BusPacketQueue1D);
|
||||||
|
perRankQueue.add(BusPacketQueue1D);
|
||||||
|
|
||||||
|
}
|
||||||
|
queues.add(perRankQueue);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public void enqueue(MainMemoryBusPacket busPacket)
|
||||||
|
{
|
||||||
|
|
||||||
|
int rank = busPacket.rank;
|
||||||
|
int bank = busPacket.bank;
|
||||||
|
if (mainMemoryConfig.queuingStructure==QueuingStructure.PerRank)
|
||||||
|
{
|
||||||
|
queues.get(rank).get(0).add(busPacket);
|
||||||
|
//if(mainMemoryConfig.DEBUG_CMDQ)
|
||||||
|
// Test.outputLog.print("Enqueued to command queue for rank "+ rank + "\n");
|
||||||
|
if (queues.get(rank).get(0).size()>CMD_QUEUE_DEPTH)
|
||||||
|
{
|
||||||
|
Error.showErrorAndExit("== Error - Enqueued more than allowed in command queue");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (mainMemoryConfig.queuingStructure==QueuingStructure.PerRankPerBank)
|
||||||
|
{
|
||||||
|
queues.get(rank).get(bank).add(busPacket);
|
||||||
|
if (queues.get(rank).get(bank).size()>CMD_QUEUE_DEPTH)
|
||||||
|
{
|
||||||
|
Error.showErrorAndExit("== Error - Enqueued more than allowed in command queue");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Error.showErrorAndExit("== Error - Unknown queuing structure");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//checks if busPacket is allowed to be issued
|
||||||
|
boolean isIssuable(MainMemoryBusPacket busPacket,long currentClockCycle )
|
||||||
|
{
|
||||||
|
// long currentClockCycle=GlobalClock.getCurrentTime();
|
||||||
|
|
||||||
|
switch (busPacket.busPacketType)
|
||||||
|
{
|
||||||
|
case REFRESH:
|
||||||
|
|
||||||
|
break;
|
||||||
|
case ACTIVATE:
|
||||||
|
if ((bankStates[busPacket.rank][busPacket.bank].currentBankState == CurrentBankState.IDLE ||
|
||||||
|
bankStates[busPacket.rank][busPacket.bank].currentBankState == CurrentBankState.REFRESHING) &&
|
||||||
|
currentClockCycle >= bankStates[busPacket.rank][busPacket.bank].nextActivate &&
|
||||||
|
tFAWCountdown.get(busPacket.rank).size() < 4)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
//busPacket.printPacketToFile();
|
||||||
|
//Main.debugPrinter.print("\n");
|
||||||
|
|
||||||
|
/*if(mainMemoryConfig.DEBUG_CMDQ)
|
||||||
|
{
|
||||||
|
if(currentClockCycle < 0 && busPacket.bank == 3)
|
||||||
|
{
|
||||||
|
Main.outputLog.print("Cannot issue Activate because \n");
|
||||||
|
Main.outputLog.print(String.valueOf(bankStates[busPacket.rank][busPacket.bank].currentBankState == CurrentBankState.IDLE) + " ");
|
||||||
|
Main.outputLog.print(String.valueOf(bankStates[busPacket.rank][busPacket.bank].currentBankState == CurrentBankState.REFRESHING) + " ");
|
||||||
|
Main.outputLog.print(String.valueOf(currentClockCycle >= bankStates[busPacket.rank][busPacket.bank].nextActivate) + " ");
|
||||||
|
Main.outputLog.print(String.valueOf(tFAWCountdown.get(busPacket.rank).size() < 4) + " \n");
|
||||||
|
Main.outputLog.print(bankStates[0][3].currentBankState.toString());
|
||||||
|
|
||||||
|
}
|
||||||
|
}*/
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
//break;
|
||||||
|
case WRITE:
|
||||||
|
case WRITE_P:
|
||||||
|
if (bankStates[busPacket.rank][busPacket.bank].currentBankState == CurrentBankState.ROW_ACTIVE &&
|
||||||
|
currentClockCycle >= bankStates[busPacket.rank][busPacket.bank].nextWrite &&
|
||||||
|
busPacket.row == bankStates[busPacket.rank][busPacket.bank].openRowAddress &&
|
||||||
|
rowAccessCounters[busPacket.rank][busPacket.bank] < MainMemoryConfig.TOTAL_ROW_ACCESSES)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
|
||||||
|
//Main.debugPrinter.print("Cannot issue packet of type: \n");
|
||||||
|
//busPacket.printPacketToFile();
|
||||||
|
//Main.debugPrinter.print("\n");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
//break;
|
||||||
|
case READ_P:
|
||||||
|
case READ:
|
||||||
|
if (bankStates[busPacket.rank][busPacket.bank].currentBankState == CurrentBankState.ROW_ACTIVE &&
|
||||||
|
currentClockCycle >= bankStates[busPacket.rank][busPacket.bank].nextRead &&
|
||||||
|
busPacket.row == bankStates[busPacket.rank][busPacket.bank].openRowAddress &&
|
||||||
|
rowAccessCounters[busPacket.rank][busPacket.bank] < MainMemoryConfig.TOTAL_ROW_ACCESSES)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
|
||||||
|
//Main.debugPrinter.print("Cannot issue packet of type: \n");
|
||||||
|
//busPacket.printPacketToFile();
|
||||||
|
//Main.debugPrinter.print("\n");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
//break;
|
||||||
|
case PRECHARGE:
|
||||||
|
if (bankStates[busPacket.rank][busPacket.bank].currentBankState == CurrentBankState.ROW_ACTIVE &&
|
||||||
|
currentClockCycle >= bankStates[busPacket.rank][busPacket.bank].nextPrecharge)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
|
||||||
|
//Main.debugPrinter.print("Cannot issue packet of type: \n");
|
||||||
|
//busPacket.printPacketToFile();
|
||||||
|
//Main.debugPrinter.print("\n");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
//break;
|
||||||
|
default:
|
||||||
|
Error.showErrorAndExit("== Error - Trying to issue a crazy bus packet type : ");
|
||||||
|
busPacket.printPacket();
|
||||||
|
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//Removes the next item from the command queue based on the system's
|
||||||
|
//command scheduling policy
|
||||||
|
public MainMemoryBusPacket pop(long currentClockCycle)
|
||||||
|
{
|
||||||
|
MainMemoryBusPacket busPacket=null;
|
||||||
|
//this can be done here because pop() is called every clock cycle by the parent MemoryController
|
||||||
|
// figures out the sliding window requirement for tFAW
|
||||||
|
//
|
||||||
|
//deal with tFAW book-keeping
|
||||||
|
// each rank has it's own counter since the restriction is on a device level
|
||||||
|
for (int i=0;i<mainMemoryConfig.numRanks;i++)
|
||||||
|
{
|
||||||
|
//decrement all the counters we have going
|
||||||
|
for (int j=0;j<tFAWCountdown.get(i).size();j++)
|
||||||
|
{
|
||||||
|
tFAWCountdown.get(i).set(j,tFAWCountdown.get(i).get(j)-1);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
//the head will always be the smallest counter, so check if it has reached 0
|
||||||
|
if (tFAWCountdown.get(i).size()>0 && tFAWCountdown.get(i).get(0)==0)
|
||||||
|
|
||||||
|
{
|
||||||
|
//tFAWCountdown[i].erase(tFAWCountdown[i].begin());
|
||||||
|
//Main.debugPrinter.print("\nFinally removed\n");
|
||||||
|
//Main.debugPrinter.print(i+" :rank\n");
|
||||||
|
//Main.debugPrinter.print("size: "+tFAWCountdown.get(i).size());
|
||||||
|
tFAWCountdown.get(i).remove(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Now we need to find a packet to issue. When the code picks a packet, it will set
|
||||||
|
busPacket = [some eligible packet]
|
||||||
|
|
||||||
|
First the code looks if any refreshes need to go
|
||||||
|
Then it looks for data packets
|
||||||
|
Otherwise, it starts looking for rows to close (in open page)
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (mainMemoryConfig.rowBufferPolicy==RowBufferPolicy.ClosePage)
|
||||||
|
{
|
||||||
|
boolean sendingREF = false;
|
||||||
|
//if the memory controller set the flags signaling that we need to issue a refresh
|
||||||
|
if (refreshWaiting)
|
||||||
|
{
|
||||||
|
boolean foundActiveOrTooEarly = false;
|
||||||
|
//look for an open bank
|
||||||
|
for (int b=0;b<mainMemoryConfig.numBanks;b++)
|
||||||
|
{
|
||||||
|
ArrayList<MainMemoryBusPacket> queue = getCommandQueue(refreshRank,b);
|
||||||
|
//checks to make sure that all banks are idle
|
||||||
|
if (bankStates[refreshRank][b].currentBankState == CurrentBankState.ROW_ACTIVE)
|
||||||
|
{
|
||||||
|
foundActiveOrTooEarly = true;
|
||||||
|
//if the bank is open, make sure there is nothing else
|
||||||
|
// going there before we close it
|
||||||
|
for (int j=0;j<queue.size();j++)
|
||||||
|
{
|
||||||
|
MainMemoryBusPacket packet = queue.get(j);
|
||||||
|
if (packet.row == bankStates[refreshRank][b].openRowAddress &&
|
||||||
|
packet.bank == b)
|
||||||
|
{
|
||||||
|
if (packet.busPacketType != BusPacketType.ACTIVATE && isIssuable(packet,currentClockCycle))
|
||||||
|
{
|
||||||
|
busPacket = packet;
|
||||||
|
queue.remove(j);
|
||||||
|
sendingREF = true;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
// NOTE: checks nextActivate time for each bank to make sure tRP is being
|
||||||
|
// satisfied. the next ACT and next REF can be issued at the same
|
||||||
|
// point in the future, so just use nextActivate field instead of
|
||||||
|
// creating a nextRefresh field
|
||||||
|
else if (bankStates[refreshRank][b].nextActivate > currentClockCycle)
|
||||||
|
{
|
||||||
|
foundActiveOrTooEarly = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//if there are no open banks and timing has been met, send out the refresh
|
||||||
|
// reset flags and rank pointer
|
||||||
|
if (!foundActiveOrTooEarly && bankStates[refreshRank][0].currentBankState != CurrentBankState.POWER_DOWN)
|
||||||
|
{
|
||||||
|
busPacket = new MainMemoryBusPacket(1, 1, 0, refreshRank,0 ,BusPacketType.REFRESH);
|
||||||
|
refreshRank = -1;
|
||||||
|
refreshWaiting = false;
|
||||||
|
sendingREF = true;
|
||||||
|
}
|
||||||
|
} // refreshWaiting
|
||||||
|
|
||||||
|
|
||||||
|
//if we're not sending a REF, proceed as normal
|
||||||
|
if (!sendingREF)
|
||||||
|
{
|
||||||
|
boolean foundIssuable = false;
|
||||||
|
int startingRank = nextRank;
|
||||||
|
int startingBank = nextBank;
|
||||||
|
do
|
||||||
|
{
|
||||||
|
ArrayList<MainMemoryBusPacket> queue = getCommandQueue(nextRank, nextBank);
|
||||||
|
//make sure there is something in this queue first
|
||||||
|
// also make sure a rank isn't waiting for a refresh
|
||||||
|
// if a rank is waiting for a refresh, don't issue anything to it until the
|
||||||
|
// refresh logic above has sent one out (ie, letting banks close)
|
||||||
|
if (!(queue.size()==0) && !((nextRank == refreshRank) && refreshWaiting))
|
||||||
|
{
|
||||||
|
if (mainMemoryConfig.queuingStructure == QueuingStructure.PerRank)
|
||||||
|
{
|
||||||
|
|
||||||
|
//search from beginning to find first issuable bus packet
|
||||||
|
for (int i=0;i<queue.size();i++)
|
||||||
|
{
|
||||||
|
if (isIssuable(queue.get(i),currentClockCycle))
|
||||||
|
{
|
||||||
|
//check to make sure we aren't removing a read/write that is paired with an activate
|
||||||
|
if (i>0 && queue.get(i-1).busPacketType==BusPacketType.ACTIVATE &&
|
||||||
|
queue.get(i-1).physicalAddress == queue.get(i).physicalAddress)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
busPacket = queue.get(i);
|
||||||
|
queue.remove(i);
|
||||||
|
foundIssuable = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (isIssuable(queue.get(0),currentClockCycle))
|
||||||
|
{
|
||||||
|
|
||||||
|
//no need to search because if the front can't be sent,
|
||||||
|
// then no chance something behind it can go instead
|
||||||
|
busPacket = queue.get(0);
|
||||||
|
queue.remove(0);
|
||||||
|
foundIssuable = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//if we found something, break out of do-while
|
||||||
|
if (foundIssuable) break;
|
||||||
|
|
||||||
|
//rank round robin
|
||||||
|
if (mainMemoryConfig.queuingStructure == QueuingStructure.PerRank)
|
||||||
|
{
|
||||||
|
nextRank = (nextRank + 1) % mainMemoryConfig.numRanks;
|
||||||
|
if (startingRank == nextRank)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
int temp[]=nextRankAndBank(nextRank, nextBank);
|
||||||
|
nextRank = temp[0];
|
||||||
|
nextBank = temp[1];
|
||||||
|
|
||||||
|
if (startingRank == nextRank && startingBank == nextBank)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
while (true);
|
||||||
|
|
||||||
|
//if we couldn't find anything to send, return false
|
||||||
|
if (!foundIssuable){
|
||||||
|
//Test.debugPrinter.print("Not foundIssuable !!!\n");
|
||||||
|
|
||||||
|
return null;}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (mainMemoryConfig.rowBufferPolicy==RowBufferPolicy.OpenPage)
|
||||||
|
{
|
||||||
|
boolean sendingREForPRE = false;
|
||||||
|
if (refreshWaiting)
|
||||||
|
{
|
||||||
|
boolean sendREF = true;
|
||||||
|
//make sure all banks idle and timing met for a REF
|
||||||
|
for (int b=0;b<mainMemoryConfig.numBanks;b++)
|
||||||
|
{
|
||||||
|
//if a bank is active we can't send a REF yet
|
||||||
|
if (bankStates[refreshRank][b].currentBankState == CurrentBankState.ROW_ACTIVE)
|
||||||
|
{
|
||||||
|
sendREF = false;
|
||||||
|
boolean closeRow = true;
|
||||||
|
//search for commands going to an open row
|
||||||
|
ArrayList<MainMemoryBusPacket> refreshQueue = getCommandQueue(refreshRank,b);
|
||||||
|
|
||||||
|
for (int j=0;j<refreshQueue.size();j++)
|
||||||
|
{
|
||||||
|
MainMemoryBusPacket packet = refreshQueue.get(j);
|
||||||
|
//if a command in the queue is going to the same row . . .
|
||||||
|
if (bankStates[refreshRank][b].openRowAddress == packet.row &&
|
||||||
|
b == packet.bank)
|
||||||
|
{
|
||||||
|
// . . . and is not an activate . . .
|
||||||
|
if (packet.busPacketType != BusPacketType.ACTIVATE)
|
||||||
|
{
|
||||||
|
closeRow = false;
|
||||||
|
// . . . and can be issued . . .
|
||||||
|
if (isIssuable(packet,currentClockCycle))
|
||||||
|
{
|
||||||
|
//send it out
|
||||||
|
busPacket = packet;
|
||||||
|
refreshQueue.remove(j);
|
||||||
|
sendingREForPRE = true;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else //command is an activate
|
||||||
|
{
|
||||||
|
//if we've encountered another act, no other command will be of interest
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//if the bank is open and we are allowed to close it, then send a PRE
|
||||||
|
if (closeRow && currentClockCycle >= bankStates[refreshRank][b].nextPrecharge)
|
||||||
|
{
|
||||||
|
rowAccessCounters[refreshRank][b]=0;
|
||||||
|
busPacket = new MainMemoryBusPacket( 0, 0, b, refreshRank, 0, BusPacketType.PRECHARGE);
|
||||||
|
sendingREForPRE = true;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
// NOTE: the next ACT and next REF can be issued at the same
|
||||||
|
// point in the future, so just use nextActivate field instead of
|
||||||
|
// creating a nextRefresh field
|
||||||
|
else if (bankStates[refreshRank][b].nextActivate > currentClockCycle) //and this bank doesn't have an open row
|
||||||
|
{
|
||||||
|
sendREF = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//if there are no open banks and timing has been met, send out the refresh
|
||||||
|
// reset flags and rank pointer
|
||||||
|
if (sendREF && bankStates[refreshRank][0].currentBankState != CurrentBankState.POWER_DOWN)
|
||||||
|
{
|
||||||
|
busPacket = new MainMemoryBusPacket(0, 0, 0, refreshRank, 0, BusPacketType.REFRESH);
|
||||||
|
refreshRank = -1;
|
||||||
|
refreshWaiting = false;
|
||||||
|
sendingREForPRE = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!sendingREForPRE)
|
||||||
|
{
|
||||||
|
int startingRank = nextRank;
|
||||||
|
int startingBank = nextBank;
|
||||||
|
boolean foundIssuable = false;
|
||||||
|
do // round robin over queues
|
||||||
|
{
|
||||||
|
ArrayList<MainMemoryBusPacket> queue = getCommandQueue(nextRank,nextBank);
|
||||||
|
//make sure there is something there first
|
||||||
|
if (!(queue.size()==0) && !((nextRank == refreshRank) && refreshWaiting))
|
||||||
|
{
|
||||||
|
//search from the beginning to find first issuable bus packet
|
||||||
|
for (int i=0;i<queue.size();i++)
|
||||||
|
{
|
||||||
|
MainMemoryBusPacket packet = queue.get(i);
|
||||||
|
if (isIssuable(packet,currentClockCycle))
|
||||||
|
{
|
||||||
|
//check for dependencies
|
||||||
|
boolean dependencyFound = false;
|
||||||
|
for (int j=0;j<i;j++)
|
||||||
|
{
|
||||||
|
MainMemoryBusPacket prevPacket = queue.get(j);
|
||||||
|
if (prevPacket.busPacketType != BusPacketType.ACTIVATE &&
|
||||||
|
prevPacket.bank == packet.bank &&
|
||||||
|
prevPacket.row == packet.row)
|
||||||
|
{
|
||||||
|
dependencyFound = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (dependencyFound) continue;
|
||||||
|
|
||||||
|
busPacket = packet;
|
||||||
|
|
||||||
|
//if the bus packet before is an activate, that is the act that was
|
||||||
|
// paired with the column access we are removing, so we have to remove
|
||||||
|
// that activate as well (check i>0 because if i==0 then theres nothing before it)
|
||||||
|
if (i>0 && queue.get(i-1).busPacketType == BusPacketType.ACTIVATE)
|
||||||
|
{
|
||||||
|
rowAccessCounters[(busPacket).rank][(busPacket).bank]++;
|
||||||
|
|
||||||
|
//Test.outputLog.print("incrementing row access counter for bank " + busPacket.bank + " value is "
|
||||||
|
// + rowAccessCounters[(busPacket).rank][(busPacket).bank] +"\n");
|
||||||
|
|
||||||
|
// i is being returned, but i-1 is being thrown away, so must delete it here
|
||||||
|
|
||||||
|
//changed by kushagra
|
||||||
|
queue.set(i-1,null);
|
||||||
|
|
||||||
|
// remove both i-1 (the activate) and i (we've saved the pointer in *busPacket)
|
||||||
|
|
||||||
|
//queue.remove(i-1); //added by kushagra
|
||||||
|
queue.remove(i);
|
||||||
|
queue.remove(i-1);
|
||||||
|
}
|
||||||
|
else // there's no activate before this packet
|
||||||
|
{
|
||||||
|
//or just remove the one bus packet
|
||||||
|
queue.remove(i);
|
||||||
|
}
|
||||||
|
|
||||||
|
foundIssuable = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//if we found something, break out of do-while
|
||||||
|
if (foundIssuable) break;
|
||||||
|
|
||||||
|
//rank round robin
|
||||||
|
if (mainMemoryConfig.queuingStructure == QueuingStructure.PerRank)
|
||||||
|
{
|
||||||
|
nextRank = (nextRank + 1) % mainMemoryConfig.numRanks;
|
||||||
|
if (startingRank == nextRank)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
int temp[] = nextRankAndBank(nextRank, nextBank);
|
||||||
|
nextRank = temp[0];
|
||||||
|
nextBank = temp[1];
|
||||||
|
temp = null;
|
||||||
|
if (startingRank == nextRank && startingBank == nextBank)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
while (true);
|
||||||
|
|
||||||
|
//if nothing was issuable, see if we can issue a PRE to an open bank
|
||||||
|
// that has no other commands waiting
|
||||||
|
if (!foundIssuable)
|
||||||
|
{
|
||||||
|
|
||||||
|
//Test.outputLog.print("Searching for banks to close\n");
|
||||||
|
|
||||||
|
//search for banks to close
|
||||||
|
boolean sendingPRE = false;
|
||||||
|
startingRank = nextRankPRE;
|
||||||
|
startingBank = nextBankPRE;
|
||||||
|
|
||||||
|
do // round robin over all ranks and banks
|
||||||
|
{
|
||||||
|
ArrayList<MainMemoryBusPacket> queue = getCommandQueue(nextRankPRE, nextBankPRE);
|
||||||
|
boolean found = false;
|
||||||
|
//check if bank is open
|
||||||
|
if (bankStates[nextRankPRE][nextBankPRE].currentBankState == CurrentBankState.ROW_ACTIVE)
|
||||||
|
{
|
||||||
|
for (int i=0;i<queue.size();i++)
|
||||||
|
{
|
||||||
|
//if there is something going to that bank and row, then we don't want to send a PRE
|
||||||
|
if (queue.get(i).bank == nextBankPRE &&
|
||||||
|
queue.get(i).row == bankStates[nextRankPRE][nextBankPRE].openRowAddress)
|
||||||
|
{
|
||||||
|
found = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//if nothing found going to that bank and row or too many accesses have happened, close it
|
||||||
|
if (!found || rowAccessCounters[nextRankPRE][nextBankPRE]==MainMemoryConfig.TOTAL_ROW_ACCESSES)
|
||||||
|
{
|
||||||
|
//Test.outputLog.print("Trying to issue precharge\n");
|
||||||
|
|
||||||
|
if (currentClockCycle >= bankStates[nextRankPRE][nextBankPRE].nextPrecharge)
|
||||||
|
{
|
||||||
|
//System.out.println("issuing precharge to open bank " + nextBankPRE + " next precharge " +
|
||||||
|
// bankStates[nextRankPRE][nextBankPRE].nextPrecharge + " at time " + currentClockCycle);
|
||||||
|
//Test.outputLog.print("issuing precharge to bank " + nextBankPRE);
|
||||||
|
sendingPRE = true;
|
||||||
|
rowAccessCounters[nextRankPRE][nextBankPRE] = 0;
|
||||||
|
busPacket = new MainMemoryBusPacket(0, 0, nextBankPRE, nextRankPRE, 0,BusPacketType.PRECHARGE );
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
int temp[] = nextRankAndBank(nextRankPRE, nextBankPRE);
|
||||||
|
nextRankPRE = temp[0];
|
||||||
|
nextBankPRE = temp[1];
|
||||||
|
temp = null;
|
||||||
|
}
|
||||||
|
while (!(startingRank == nextRankPRE && startingBank == nextBankPRE));
|
||||||
|
|
||||||
|
//if no PREs could be sent, just return false
|
||||||
|
if (!sendingPRE) return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//sendAct is flag used for posted-cas
|
||||||
|
// posted-cas is enabled when AL>0
|
||||||
|
// when sendAct is true, when don't want to increment our indexes
|
||||||
|
// so we send the column access that is paid with this act
|
||||||
|
if (mainMemoryConfig.tAL>0 && sendAct)
|
||||||
|
{
|
||||||
|
sendAct = false;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
sendAct = true;
|
||||||
|
int a[]=nextRankAndBank(nextRank, nextBank);
|
||||||
|
nextRank=a[0];
|
||||||
|
nextBank=a[1];
|
||||||
|
}
|
||||||
|
|
||||||
|
//if its an activate, add a tfaw counter
|
||||||
|
if (busPacket.busPacketType==BusPacketType.ACTIVATE)
|
||||||
|
{
|
||||||
|
tFAWCountdown.get((busPacket).rank).add(mainMemoryConfig.tFAW);
|
||||||
|
//Main.debugPrinter.print("\nInsert into FAW Rank: "+(busPacket).rank+"\n");
|
||||||
|
//Main.debugPrinter.print("size of rank FAW: "+tFAWCountdown.get(busPacket.rank).size()+"\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
return busPacket;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int[] nextRankAndBank(int rank, int bank)
|
||||||
|
{
|
||||||
|
if (mainMemoryConfig.schedulingPolicy == SchedulingPolicy.RankThenBankRoundRobin)
|
||||||
|
{
|
||||||
|
rank++;
|
||||||
|
if (rank == mainMemoryConfig.numRanks)
|
||||||
|
{
|
||||||
|
rank = 0;
|
||||||
|
bank++;
|
||||||
|
if (bank == mainMemoryConfig.numBanks)
|
||||||
|
{
|
||||||
|
bank = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
int a[]={rank,bank};
|
||||||
|
return a;
|
||||||
|
}
|
||||||
|
//bank-then-rank round robin
|
||||||
|
else if (mainMemoryConfig.schedulingPolicy == SchedulingPolicy.BankThenRankRoundRobin)
|
||||||
|
{
|
||||||
|
bank++;
|
||||||
|
if (bank == mainMemoryConfig.numBanks)
|
||||||
|
{
|
||||||
|
bank = 0;
|
||||||
|
rank++;
|
||||||
|
if (rank == mainMemoryConfig.numRanks)
|
||||||
|
{
|
||||||
|
rank = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
int a[]={rank,bank};
|
||||||
|
return a;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Error.showErrorAndExit("== Error - Unknown scheduling policy");
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
ArrayList<MainMemoryBusPacket> getCommandQueue(int rank, int bank)
|
||||||
|
{
|
||||||
|
if (mainMemoryConfig.queuingStructure == QueuingStructure.PerRankPerBank)
|
||||||
|
{
|
||||||
|
return queues.get(rank).get(bank);
|
||||||
|
}
|
||||||
|
else if (mainMemoryConfig.queuingStructure == QueuingStructure.PerRank)
|
||||||
|
{
|
||||||
|
return queues.get(rank).get(0);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Error.showErrorAndExit("Unknown queue structure");
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void needRefresh(int rank)
|
||||||
|
{
|
||||||
|
refreshWaiting = true;
|
||||||
|
refreshRank = rank;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean canPop()
|
||||||
|
{
|
||||||
|
return(BusPacketQueue1D.size()>0);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public boolean hasRoomFor(int num, int rank, int bank)
|
||||||
|
{
|
||||||
|
return (CMD_QUEUE_DEPTH - getCommandQueue(rank, bank).size() >= num);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
//this function for TEST
|
||||||
|
public void printTest()
|
||||||
|
{
|
||||||
|
if (mainMemoryConfig.queuingStructure== QueuingStructure.PerRank)
|
||||||
|
{
|
||||||
|
Main.outputLog.print("\n== Printing Per Rank Queue at Clock Cycle "+ GlobalClock.getCurrentTime() +"\n" );
|
||||||
|
for (int i=0;i< mainMemoryConfig.numRanks;i++)
|
||||||
|
{
|
||||||
|
Main.outputLog.print(" = Rank " + i + " size : " + queues.get(i).get(0).size() + "\n");
|
||||||
|
for (int j=0;j < queues.get(i).get(0).size();j++)
|
||||||
|
{
|
||||||
|
Main.outputLog.print(" "+ j + "]");
|
||||||
|
queues.get(i).get(0).get(j).printTest();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,48 @@
|
||||||
|
package dram;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.FileWriter;
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
public class DebugPrinter {
|
||||||
|
|
||||||
|
public FileWriter logFileWriter;
|
||||||
|
|
||||||
|
public DebugPrinter(String filename) {
|
||||||
|
|
||||||
|
try {
|
||||||
|
|
||||||
|
File logfile = new File(filename);
|
||||||
|
logFileWriter = new FileWriter(logfile);
|
||||||
|
}
|
||||||
|
catch (IOException e)
|
||||||
|
{
|
||||||
|
//System.out.println("Harveenk: unable to create log file");
|
||||||
|
//System.out.println("Exception: " + e);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public void close()
|
||||||
|
{
|
||||||
|
try{
|
||||||
|
logFileWriter.close();
|
||||||
|
}
|
||||||
|
catch(IOException e)
|
||||||
|
{
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public void print(String s)
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
logFileWriter.write(s);
|
||||||
|
}
|
||||||
|
catch (IOException e)
|
||||||
|
{
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,5 @@
|
||||||
|
package dram;
|
||||||
|
|
||||||
|
public class Dram {
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,168 @@
|
||||||
|
package dram;
|
||||||
|
|
||||||
|
import main.Main;
|
||||||
|
import generic.Event;
|
||||||
|
import generic.RequestType;
|
||||||
|
|
||||||
|
import misc.Error;
|
||||||
|
|
||||||
|
//use to encapsulate payload
|
||||||
|
//corresponds to BusPacket
|
||||||
|
|
||||||
|
public class MainMemoryBusPacket implements Cloneable{
|
||||||
|
|
||||||
|
public static enum BusPacketType {
|
||||||
|
READ,
|
||||||
|
READ_P,
|
||||||
|
WRITE,
|
||||||
|
WRITE_P,
|
||||||
|
ACTIVATE,
|
||||||
|
PRECHARGE,
|
||||||
|
REFRESH,
|
||||||
|
DATA,
|
||||||
|
NULL
|
||||||
|
}
|
||||||
|
//replaced by request type, in case of events
|
||||||
|
//but still need for command queue
|
||||||
|
|
||||||
|
public int row;
|
||||||
|
public int column;
|
||||||
|
public int bank;
|
||||||
|
public int rank;
|
||||||
|
public long physicalAddress;
|
||||||
|
public BusPacketType busPacketType;
|
||||||
|
|
||||||
|
//for TEST
|
||||||
|
private static long numpackets = 0;
|
||||||
|
public long testid;
|
||||||
|
public long timeCreated;
|
||||||
|
|
||||||
|
public MainMemoryBusPacket (int row,
|
||||||
|
int column,
|
||||||
|
int bank,
|
||||||
|
int rank,
|
||||||
|
long physicalAddress,
|
||||||
|
BusPacketType busPacketType){
|
||||||
|
this.row = row;
|
||||||
|
this.column = column;
|
||||||
|
this.bank = bank;
|
||||||
|
this.rank = rank;
|
||||||
|
this.physicalAddress = physicalAddress;
|
||||||
|
this.busPacketType = busPacketType;
|
||||||
|
|
||||||
|
//for TEST
|
||||||
|
numpackets++;
|
||||||
|
this.testid = numpackets;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public MainMemoryBusPacket()
|
||||||
|
{
|
||||||
|
this.row = -1;
|
||||||
|
this.column = -1;
|
||||||
|
this.bank = -1;
|
||||||
|
this.rank = -1;
|
||||||
|
this.physicalAddress = -1;
|
||||||
|
this.busPacketType = BusPacketType.NULL; //"invalid" type to avoid spurious reads
|
||||||
|
|
||||||
|
//for TEST
|
||||||
|
numpackets++;
|
||||||
|
this.testid = numpackets;
|
||||||
|
this.timeCreated = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
//these entities are set on address mapping
|
||||||
|
|
||||||
|
public MainMemoryBusPacket Clone(){
|
||||||
|
try {
|
||||||
|
return (MainMemoryBusPacket) (super.clone());
|
||||||
|
} catch (CloneNotSupportedException e) {
|
||||||
|
misc.Error.showErrorAndExit("Error in cloning event object");
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setBusPacketType(BusPacketType busPacketType)
|
||||||
|
{
|
||||||
|
this.busPacketType = busPacketType;
|
||||||
|
}
|
||||||
|
|
||||||
|
public BusPacketType getBusPacketType()
|
||||||
|
{
|
||||||
|
return this.busPacketType;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void printPacket()
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
System.out.println("Bus packet type: "+ busPacketType +" Row: "+ row +" Col: "
|
||||||
|
+ column +" Bank: "+
|
||||||
|
bank +" Rank: "+
|
||||||
|
rank +" Phys Address: "+
|
||||||
|
physicalAddress + " Id : " + testid + " timeCreated: " + timeCreated );
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
|
||||||
|
public void printPacketToFile()
|
||||||
|
{
|
||||||
|
|
||||||
|
/*Main.debugPrinter.print("Bus packet type: "+ busPacketType +" "+ row +" "
|
||||||
|
+ column +" "+
|
||||||
|
bank +" "+
|
||||||
|
rank +" "+
|
||||||
|
physicalAddress + "\n");
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*Test.debugPrinter.print("Bus packet type: "+ busPacketType + " Row: "+ row +" Col: "
|
||||||
|
+ column +" Bank: "+
|
||||||
|
bank +" Rank: "+
|
||||||
|
rank +" Phys Address: "+
|
||||||
|
String.format("%08X",physicalAddress) + " Id : " + testid + " timeCreated: " + timeCreated + "\n");
|
||||||
|
*/
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
//this function for TEST
|
||||||
|
public void printTest()
|
||||||
|
{
|
||||||
|
if(this == null)
|
||||||
|
return;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
switch (busPacketType)
|
||||||
|
{
|
||||||
|
case READ:
|
||||||
|
Main.outputLog.print("BP [READ] pa[0x"+ String.format("%07X", ((physicalAddress>>6)<<6)).toLowerCase() + "] r["+rank+"] b["+bank+"] row["+row+"] col["+column+"]\n");
|
||||||
|
break;
|
||||||
|
case READ_P:
|
||||||
|
Main.outputLog.print("BP [READ_P] pa[0x"+String.format("%07X", ((physicalAddress>>6)<<6)).toLowerCase()+"] r["+rank+"] b["+bank+"] row["+row+"] col["+column+"]\n");
|
||||||
|
break;
|
||||||
|
case WRITE:
|
||||||
|
Main.outputLog.print("BP [WRITE] pa[0x"+String.format("%07X", ((physicalAddress>>6)<<6)).toLowerCase()+"] r["+rank+"] b["+bank+"] row["+row+"] col["+column+"]\n");
|
||||||
|
break;
|
||||||
|
case WRITE_P:
|
||||||
|
Main.outputLog.print("BP [WRITE_P] pa[0x"+String.format("%07X", ((physicalAddress>>6)<<6)).toLowerCase()+"] r["+rank+"] b["+bank+"] row["+row+"] col["+column+"]\n");
|
||||||
|
break;
|
||||||
|
case ACTIVATE:
|
||||||
|
Main.outputLog.print("BP [ACT] pa[0x"+String.format("%07X", ((physicalAddress>>6)<<6)).toLowerCase()+"] r["+rank+"] b["+bank+"] row["+row+"] col["+column+"]\n");
|
||||||
|
break;
|
||||||
|
case PRECHARGE:
|
||||||
|
Main.outputLog.print("BP [PRE] pa[0x"+String.format("%07X", ((physicalAddress>>6)<<6)).toLowerCase()+"] r["+rank+"] b["+bank+"] row["+row+"] col["+column+"]\n");
|
||||||
|
break;
|
||||||
|
case REFRESH:
|
||||||
|
Main.outputLog.print("BP [REF] pa[0x"+String.format("%07X", ((physicalAddress>>6)<<6)).toLowerCase()+"] r["+rank+"] b["+bank+"] row["+row+"] col["+column+"]\n");
|
||||||
|
break;
|
||||||
|
case DATA:
|
||||||
|
Main.outputLog.print("BP [DATA] pa[0x"+String.format("%07X", ((physicalAddress>>6)<<6)).toLowerCase()+"] r["+rank+"] b["+bank+"] row["+row+"] col["+column+"] data["+0+"]=");
|
||||||
|
//printData();
|
||||||
|
|
||||||
|
Main.outputLog.print("NO DATA\n");
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
Error.showErrorAndExit("Trying to print unknown kind of bus packet");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,776 @@
|
||||||
|
package dram;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import config.MainMemoryConfig;
|
||||||
|
import config.MainMemoryConfig.QueuingStructure;
|
||||||
|
import config.MainMemoryConfig.RowBufferPolicy;
|
||||||
|
import config.MainMemoryConfig.SchedulingPolicy;
|
||||||
|
import config.SystemConfig;
|
||||||
|
import dram.BankState.CurrentBankState;
|
||||||
|
import dram.MainMemoryBusPacket.BusPacketType;
|
||||||
|
import generic.Core;
|
||||||
|
import generic.Event;
|
||||||
|
import generic.EventQueue;
|
||||||
|
import generic.GlobalClock;
|
||||||
|
import generic.RequestType;
|
||||||
|
import main.ArchitecturalComponent;
|
||||||
|
import main.Main;
|
||||||
|
import memorysystem.AddressCarryingEvent;
|
||||||
|
import memorysystem.Cache;
|
||||||
|
import memorysystem.MainMemoryController;
|
||||||
|
import misc.Error;
|
||||||
|
|
||||||
|
public class MainMemoryDRAMController extends MainMemoryController{
|
||||||
|
|
||||||
|
private int numTransactions;
|
||||||
|
|
||||||
|
//how many CPU clock cycles to next RAM cycle
|
||||||
|
//int nextTick = 0;
|
||||||
|
|
||||||
|
int channel; //channel number for this mem controller
|
||||||
|
long busFreeTime = 0L; //for keeping track of when the bus is free
|
||||||
|
|
||||||
|
MainMemoryConfig mainMemoryConfig;
|
||||||
|
|
||||||
|
//TODO: need a way to store the actual requesting element
|
||||||
|
//dirty workaround for now
|
||||||
|
|
||||||
|
Cache parentCache;
|
||||||
|
int refreshRank;
|
||||||
|
|
||||||
|
//for statistics
|
||||||
|
long totalTime = 0;
|
||||||
|
long totalTransactions = 0;
|
||||||
|
long totalReadTransactions[][];
|
||||||
|
long totalWriteTransactions[][];
|
||||||
|
|
||||||
|
ArrayList<MainMemoryBusPacket> pendingTransQueue;
|
||||||
|
//MainMemoryBusPacket pendingTransQueue[]; //to keep track of packets that could not be added to command queue
|
||||||
|
BankState bankStates[][];
|
||||||
|
CommandQueue commandQueue;
|
||||||
|
Rank ranks[];
|
||||||
|
int refreshCount[];
|
||||||
|
|
||||||
|
public MainMemoryDRAMController(MainMemoryConfig mainMemoryConfig) {
|
||||||
|
super();
|
||||||
|
|
||||||
|
//added later by kush
|
||||||
|
if(SystemConfig.memControllerToUse==false){
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.mainMemoryConfig = mainMemoryConfig;
|
||||||
|
|
||||||
|
numTransactions = 0;
|
||||||
|
refreshRank=0;
|
||||||
|
ranks = new Rank[mainMemoryConfig.numRanks];
|
||||||
|
bankStates = new BankState[mainMemoryConfig.numRanks][mainMemoryConfig.numBanks];
|
||||||
|
totalReadTransactions = new long[mainMemoryConfig.numRanks][mainMemoryConfig.numBanks];
|
||||||
|
totalWriteTransactions = new long[mainMemoryConfig.numRanks][mainMemoryConfig.numBanks];
|
||||||
|
|
||||||
|
for(int i=0; i < mainMemoryConfig.numRanks;i++)
|
||||||
|
{
|
||||||
|
for(int j=0; j < mainMemoryConfig.numBanks; j++)
|
||||||
|
{
|
||||||
|
bankStates[i][j] = new BankState();
|
||||||
|
}
|
||||||
|
ranks[i] = new Rank(mainMemoryConfig,i,this);
|
||||||
|
}
|
||||||
|
|
||||||
|
pendingTransQueue=new ArrayList<MainMemoryBusPacket>();
|
||||||
|
|
||||||
|
commandQueue = new CommandQueue(mainMemoryConfig,bankStates);
|
||||||
|
|
||||||
|
refreshCount=new int[mainMemoryConfig.numRanks];
|
||||||
|
|
||||||
|
for(int i=0;i<mainMemoryConfig.numRanks;i++){
|
||||||
|
refreshCount[i]=(int)((mainMemoryConfig.RefreshPeriod/mainMemoryConfig.tCK)/mainMemoryConfig.numRanks)*(i+1);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void handleEvent(EventQueue eventQ, Event e)
|
||||||
|
{
|
||||||
|
|
||||||
|
//added later by kush
|
||||||
|
if(SystemConfig.memControllerToUse==false){
|
||||||
|
super.handleEvent(eventQ,e);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
long currentTime = GlobalClock.getCurrentTime();
|
||||||
|
|
||||||
|
//System.out.println("Hi!! handling a dram event of type " + e.getRequestType());
|
||||||
|
//Main.debugPrinter.print("\nHi!! handling a dram event of type " + e.getRequestType()+ "\n");
|
||||||
|
|
||||||
|
|
||||||
|
//check if state update event
|
||||||
|
|
||||||
|
if(e.getRequestType() == RequestType.Mem_Cntrlr_State_Update) {
|
||||||
|
|
||||||
|
StateUpdateEvent event = (StateUpdateEvent) e;
|
||||||
|
|
||||||
|
int rank = event.getRank();
|
||||||
|
int bank = event.getBank();
|
||||||
|
long eventTime = event.getEventTime(); //IMP: the reference for timing should be the time previous event was generated
|
||||||
|
//and not the current clock cycle as these 2 may differ sometimes!
|
||||||
|
BankState bankState = bankStates[rank][bank];
|
||||||
|
|
||||||
|
//FSM for commands with implicit state change
|
||||||
|
switch(bankState.lastCommand) {
|
||||||
|
|
||||||
|
case WRITE_P:
|
||||||
|
case READ_P:
|
||||||
|
bankState.currentBankState = CurrentBankState.PRECHARGING;
|
||||||
|
bankState.lastCommand = BusPacketType.PRECHARGE;
|
||||||
|
//create new FSM event and add to original queue
|
||||||
|
StateUpdateEvent FSMevent = new StateUpdateEvent(eventQ, (eventTime+mainMemoryConfig.tRP-1), e.getRequestingElement(),
|
||||||
|
e.getProcessingElement(), RequestType.Mem_Cntrlr_State_Update, rank, bank);
|
||||||
|
eventQ.addEvent(FSMevent);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case REFRESH:
|
||||||
|
//if last command was refresh, all banks were refreshed in that rank. set all as idle
|
||||||
|
for(int i=0; i < mainMemoryConfig.numBanks; i++)
|
||||||
|
{
|
||||||
|
bankStates[rank][i].currentBankState = CurrentBankState.IDLE;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case PRECHARGE:
|
||||||
|
bankState.currentBankState = CurrentBankState.IDLE;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
else if(e.getRequestType() == RequestType.Cache_Read || e.getRequestType() == RequestType.Cache_Write) {
|
||||||
|
|
||||||
|
//got a read or write event -> perform address mapping and add it to command queue
|
||||||
|
|
||||||
|
//TODO: workaround
|
||||||
|
this.parentCache = (Cache) e.getRequestingElement();
|
||||||
|
|
||||||
|
|
||||||
|
AddressCarryingEvent event = (AddressCarryingEvent) e;
|
||||||
|
|
||||||
|
//maintain number of transactions waiting to be serviced
|
||||||
|
numTransactions++;
|
||||||
|
|
||||||
|
|
||||||
|
MainMemoryBusPacket b = AddressMapping(event.getAddress());
|
||||||
|
b.setBusPacketType(requestTypeToBusPacketType(event.getRequestType()));
|
||||||
|
|
||||||
|
//for TIMING
|
||||||
|
//create k6 style trace file
|
||||||
|
b.timeCreated = GlobalClock.getCurrentTime();
|
||||||
|
//if(event.getRequestType() == RequestType.Cache_Read)
|
||||||
|
// Main.traceFile.print( String.format("0x%08X", b.physicalAddress) + " P_MEM_RD " + b.timeCreated + "\n");
|
||||||
|
//else
|
||||||
|
// Main.traceFile.print( String.format("0x%08X", b.physicalAddress) + " P_MEM_WR " + b.timeCreated + "\n");
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//System.out.println("Of bus packet type:");
|
||||||
|
//b.printPacket();
|
||||||
|
|
||||||
|
//add it to the list of pending transactions, we will enqueue to command queue from this list
|
||||||
|
pendingTransQueue.add(b);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
//finally send the data to cpu
|
||||||
|
|
||||||
|
else if (e.getRequestType() == RequestType.Rank_Response)
|
||||||
|
{
|
||||||
|
|
||||||
|
//System.out.println("Received rank response! Sending event");
|
||||||
|
//System.out.println("Time : " + GlobalClock.getCurrentTime() );
|
||||||
|
|
||||||
|
|
||||||
|
//For TIMING
|
||||||
|
//Main.timingLog.print(Long.toString(((RamBusAddressCarryingEvent) e).getBusPacket().timeCreated));
|
||||||
|
//Main.timingLog.print(" " + GlobalClock.getCurrentTime() + "\n");
|
||||||
|
|
||||||
|
MainMemoryBusPacket b = ((RamBusAddressCarryingEvent) e).getBusPacket();
|
||||||
|
totalTransactions++;
|
||||||
|
totalReadTransactions[b.rank][b.bank]++;
|
||||||
|
totalTime += ( GlobalClock.getCurrentTime() - b.timeCreated);
|
||||||
|
|
||||||
|
AddressCarryingEvent event = new AddressCarryingEvent(eventQ, 0,
|
||||||
|
this, this.parentCache, RequestType.Mem_Response,
|
||||||
|
((AddressCarryingEvent)e).getAddress());
|
||||||
|
//TODO: how to make processing element as cache????
|
||||||
|
//dirty workaround right now
|
||||||
|
|
||||||
|
getComInterface().sendMessage(event);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public void enqueueToCommandQ()
|
||||||
|
{
|
||||||
|
|
||||||
|
MainMemoryBusPacket b;
|
||||||
|
for(int i=0; i < pendingTransQueue.size(); i++)
|
||||||
|
{
|
||||||
|
b = pendingTransQueue.get(i);
|
||||||
|
if(commandQueue.hasRoomFor(2,b.rank, b.bank))
|
||||||
|
{
|
||||||
|
numTransactions--; //the transaction is no longer waiting in the controller
|
||||||
|
//pendingTransQueue.remove(0);
|
||||||
|
//create new ACTIVATE bus packet with the address we just decoded
|
||||||
|
MainMemoryBusPacket ACTcommand = b.Clone(); //check cloning is ok
|
||||||
|
ACTcommand.setBusPacketType(BusPacketType.ACTIVATE);
|
||||||
|
|
||||||
|
//create read or write command and enqueue it
|
||||||
|
MainMemoryBusPacket RWcommand = b.Clone();
|
||||||
|
//RWcommand.setBusPacketType(requestTypeToBusPacketType(event.getRequestType()));
|
||||||
|
|
||||||
|
//System.out.println("Enqueuing commands for address " + event.getAddress());
|
||||||
|
//System.out.println("ACTcommand busPacketType "+ACTcommand.busPacketType);
|
||||||
|
//System.out.println("RWcommand busPacketType "+RWcommand.busPacketType);
|
||||||
|
|
||||||
|
commandQueue.enqueue(ACTcommand);
|
||||||
|
commandQueue.enqueue(RWcommand);
|
||||||
|
|
||||||
|
//Main.debugPrinter.print("Enqueued ACT command bus packet to queue as follows:");
|
||||||
|
ACTcommand.printPacketToFile();
|
||||||
|
//Main.debugPrinter.print("Enqueued RW command bus packet to queue as follows:");
|
||||||
|
RWcommand.printPacketToFile();
|
||||||
|
|
||||||
|
//if enqueued, remove the pending packet
|
||||||
|
pendingTransQueue.remove(0);
|
||||||
|
|
||||||
|
break; //just enqueue the first one !! not all pending, break when first is enqueued
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public void oneCycleOperation(){
|
||||||
|
long currentTime = GlobalClock.getCurrentTime();
|
||||||
|
Core core0 = ArchitecturalComponent.getCores()[0]; //using core 0 queue similar to as in cache
|
||||||
|
|
||||||
|
if (refreshCount[refreshRank]==0)
|
||||||
|
{
|
||||||
|
commandQueue.needRefresh(refreshRank);
|
||||||
|
ranks[refreshRank].refreshWaiting = true;
|
||||||
|
refreshCount[refreshRank] = (int)(mainMemoryConfig.RefreshPeriod/mainMemoryConfig.tCK);
|
||||||
|
refreshRank++;
|
||||||
|
if (refreshRank == mainMemoryConfig.numRanks)
|
||||||
|
{
|
||||||
|
refreshRank = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
MainMemoryBusPacket b = null;
|
||||||
|
b = commandQueue.pop(currentTime);
|
||||||
|
//if(commandQueue.canPop())
|
||||||
|
|
||||||
|
|
||||||
|
if(b!=null)
|
||||||
|
{
|
||||||
|
|
||||||
|
int rank = b.rank;
|
||||||
|
int bank = b.bank;
|
||||||
|
|
||||||
|
if (b.busPacketType == BusPacketType.WRITE || b.busPacketType == BusPacketType.WRITE_P)
|
||||||
|
{
|
||||||
|
//if write, schedule the data packet
|
||||||
|
|
||||||
|
MainMemoryBusPacket dataPacketToSend = b.Clone();
|
||||||
|
dataPacketToSend.setBusPacketType(BusPacketType.DATA);
|
||||||
|
|
||||||
|
//Main.debugPrinter.print("\n\n Received a write, scheduling event for data packet for address " + dataPacketToSend.physicalAddress + "\n\n");
|
||||||
|
|
||||||
|
RamBusAddressCarryingEvent event = new RamBusAddressCarryingEvent( core0.getEventQueue() , (currentTime + mainMemoryConfig.tWL), this,
|
||||||
|
ranks[rank], RequestType.Main_Mem_Access, dataPacketToSend.physicalAddress, dataPacketToSend);
|
||||||
|
event.getEventQ().addEvent(event);
|
||||||
|
totalWriteTransactions[rank][bank]++;
|
||||||
|
}
|
||||||
|
|
||||||
|
//update state according to the popped bus packet
|
||||||
|
|
||||||
|
switch(b.busPacketType)
|
||||||
|
{
|
||||||
|
case READ_P:
|
||||||
|
case READ:
|
||||||
|
if(b.busPacketType == BusPacketType.READ_P)
|
||||||
|
{
|
||||||
|
bankStates[rank][bank].nextActivate = Math.max(currentTime + mainMemoryConfig.ReadAutopreDelay,
|
||||||
|
bankStates[rank][bank].nextActivate);
|
||||||
|
bankStates[rank][bank].lastCommand = BusPacketType.READ_P;
|
||||||
|
|
||||||
|
//create and send event state update event
|
||||||
|
//sending to core 0 event queue currently
|
||||||
|
//keeping requesting and processing element same
|
||||||
|
StateUpdateEvent StUpdtEvent = new StateUpdateEvent(core0.getEventQueue(), (currentTime+mainMemoryConfig.ReadToPreDelay), this,
|
||||||
|
this, RequestType.Mem_Cntrlr_State_Update, rank, bank);
|
||||||
|
StUpdtEvent.getEventQ().addEvent(StUpdtEvent);
|
||||||
|
|
||||||
|
}
|
||||||
|
else if (b.busPacketType == BusPacketType.READ)
|
||||||
|
{
|
||||||
|
bankStates[rank][bank].nextPrecharge = Math.max(currentTime + mainMemoryConfig.ReadToPreDelay,
|
||||||
|
bankStates[rank][bank].nextPrecharge);
|
||||||
|
bankStates[rank][bank].lastCommand = BusPacketType.READ;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i=0;i< mainMemoryConfig.numRanks;i++)
|
||||||
|
{
|
||||||
|
for (int j=0;j<mainMemoryConfig.numBanks;j++)
|
||||||
|
{
|
||||||
|
if (i!= rank)
|
||||||
|
{
|
||||||
|
|
||||||
|
if (bankStates[i][j].currentBankState == CurrentBankState.ROW_ACTIVE)
|
||||||
|
{
|
||||||
|
bankStates[i][j].nextRead = Math.max(currentTime + mainMemoryConfig.tBL/2 + mainMemoryConfig.tRTRS, bankStates[i][j].nextRead);
|
||||||
|
bankStates[i][j].nextWrite = Math.max(currentTime + mainMemoryConfig.ReadToWriteDelay,
|
||||||
|
bankStates[i][j].nextWrite);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
bankStates[i][j].nextRead = Math.max(currentTime + Math.max(mainMemoryConfig.tCCD, mainMemoryConfig.tBL/2),
|
||||||
|
bankStates[i][j].nextRead);
|
||||||
|
bankStates[i][j].nextWrite = Math.max(currentTime + mainMemoryConfig.ReadToWriteDelay,
|
||||||
|
bankStates[i][j].nextWrite);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (b.busPacketType == BusPacketType.READ_P)
|
||||||
|
{
|
||||||
|
//set read and write to nextActivate so the state table will prevent a read or write
|
||||||
|
// being issued (in cq.isIssuable())before the bank state has been changed because of the
|
||||||
|
// auto-precharge associated with this command
|
||||||
|
bankStates[rank][bank].nextRead = bankStates[rank][bank].nextActivate;
|
||||||
|
bankStates[rank][bank].nextWrite = bankStates[rank][bank].nextActivate;
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
case WRITE_P:
|
||||||
|
case WRITE:
|
||||||
|
if (b.busPacketType == BusPacketType.WRITE_P)
|
||||||
|
{
|
||||||
|
bankStates[rank][bank].nextActivate = Math.max(currentTime + mainMemoryConfig.WriteAutopreDelay,
|
||||||
|
bankStates[rank][bank].nextActivate);
|
||||||
|
bankStates[rank][bank].lastCommand = BusPacketType.WRITE_P;
|
||||||
|
|
||||||
|
//create and send event state update event
|
||||||
|
//sending to core 0 event queue currently
|
||||||
|
//keeping requesting and processing element same
|
||||||
|
StateUpdateEvent StUpdtEvent = new StateUpdateEvent(core0.getEventQueue(), (currentTime+mainMemoryConfig.WriteToPreDelay), this,
|
||||||
|
this, RequestType.Mem_Cntrlr_State_Update, rank, bank);
|
||||||
|
StUpdtEvent.getEventQ().addEvent(StUpdtEvent);
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
else if (b.busPacketType == BusPacketType.WRITE)
|
||||||
|
{
|
||||||
|
bankStates[rank][bank].nextPrecharge = Math.max(currentTime + mainMemoryConfig.WriteToPreDelay,
|
||||||
|
bankStates[rank][bank].nextPrecharge);
|
||||||
|
bankStates[rank][bank].lastCommand = BusPacketType.WRITE;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
for (int i=0;i< mainMemoryConfig.numRanks;i++)
|
||||||
|
{
|
||||||
|
for (int j=0;j<mainMemoryConfig.numBanks;j++)
|
||||||
|
{
|
||||||
|
if (i!=rank)
|
||||||
|
{
|
||||||
|
if (bankStates[i][j].currentBankState == CurrentBankState.ROW_ACTIVE)
|
||||||
|
{
|
||||||
|
bankStates[i][j].nextWrite = Math.max(currentTime + mainMemoryConfig.tBL/2 + mainMemoryConfig.tRTRS, bankStates[i][j].nextWrite);
|
||||||
|
bankStates[i][j].nextRead = Math.max(currentTime + mainMemoryConfig.WriteToReadDelayR,
|
||||||
|
bankStates[i][j].nextRead);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
bankStates[i][j].nextWrite = Math.max(currentTime + Math.max(mainMemoryConfig.tBL/2, mainMemoryConfig.tCCD), bankStates[i][j].nextWrite);
|
||||||
|
bankStates[i][j].nextRead = Math.max(currentTime + mainMemoryConfig.WriteToReadDelayB,
|
||||||
|
bankStates[i][j].nextRead);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//set read and write to nextActivate so the state table will prevent a read or write
|
||||||
|
// being issued (in cq.isIssuable())before the bank state has been changed because of the
|
||||||
|
// auto-precharge associated with this command
|
||||||
|
if (b.busPacketType == BusPacketType.WRITE_P)
|
||||||
|
{
|
||||||
|
bankStates[rank][bank].nextRead = bankStates[rank][bank].nextActivate;
|
||||||
|
bankStates[rank][bank].nextWrite = bankStates[rank][bank].nextActivate;
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ACTIVATE:
|
||||||
|
|
||||||
|
bankStates[rank][bank].currentBankState = CurrentBankState.ROW_ACTIVE;
|
||||||
|
bankStates[rank][bank].lastCommand = BusPacketType.ACTIVATE;
|
||||||
|
bankStates[rank][bank].openRowAddress = b.row;
|
||||||
|
bankStates[rank][bank].nextActivate = Math.max(currentTime + mainMemoryConfig.tRC, bankStates[rank][bank].nextActivate);
|
||||||
|
bankStates[rank][bank].nextPrecharge = Math.max(currentTime + mainMemoryConfig.tRAS, bankStates[rank][bank].nextPrecharge);
|
||||||
|
|
||||||
|
//if we are using posted-CAS, the next column access can be sooner than normal operation
|
||||||
|
|
||||||
|
bankStates[rank][bank].nextRead = Math.max(currentTime + (mainMemoryConfig.tRCD-mainMemoryConfig.tAL), bankStates[rank][bank].nextRead);
|
||||||
|
bankStates[rank][bank].nextWrite = Math.max(currentTime + (mainMemoryConfig.tRCD-mainMemoryConfig.tAL), bankStates[rank][bank].nextWrite);
|
||||||
|
|
||||||
|
for (int i=0;i<mainMemoryConfig.numBanks;i++)
|
||||||
|
{
|
||||||
|
if (i!=bank)
|
||||||
|
{
|
||||||
|
bankStates[rank][i].nextActivate = Math.max(currentTime + mainMemoryConfig.tRRD, bankStates[rank][i].nextActivate);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
case PRECHARGE:
|
||||||
|
{
|
||||||
|
bankStates[rank][bank].currentBankState = CurrentBankState.PRECHARGING;
|
||||||
|
bankStates[rank][bank].lastCommand = BusPacketType.PRECHARGE;
|
||||||
|
bankStates[rank][bank].nextActivate = Math.max(currentTime + mainMemoryConfig.tRP, bankStates[rank][bank].nextActivate);
|
||||||
|
|
||||||
|
//create and send event state update event
|
||||||
|
//sending to core 0 event queue currently
|
||||||
|
//keeping requesting and processing element same
|
||||||
|
StateUpdateEvent StUpdtEvent = new StateUpdateEvent(core0.getEventQueue(), (currentTime+mainMemoryConfig.tRP - 1), this,
|
||||||
|
this, RequestType.Mem_Cntrlr_State_Update, rank, bank);
|
||||||
|
StUpdtEvent.getEventQ().addEvent(StUpdtEvent);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case REFRESH:
|
||||||
|
{
|
||||||
|
for (int i=0; i< mainMemoryConfig.numBanks ;i++)
|
||||||
|
{
|
||||||
|
bankStates[rank][i].nextActivate = currentTime + mainMemoryConfig.tRFC;
|
||||||
|
bankStates[rank][i].currentBankState = CurrentBankState.REFRESHING;
|
||||||
|
bankStates[rank][i].lastCommand = BusPacketType.REFRESH;
|
||||||
|
}
|
||||||
|
|
||||||
|
//create and send event state update event
|
||||||
|
//sending to core 0 event queue currently
|
||||||
|
//keeping requesting and processing element same
|
||||||
|
|
||||||
|
//Sending only 1 event, need to refresh all banks in the rank for this - do this in handle event
|
||||||
|
StateUpdateEvent StUpdtEvent = new StateUpdateEvent(core0.getEventQueue(), (currentTime+mainMemoryConfig.tRFC - 1), this,
|
||||||
|
this, RequestType.Mem_Cntrlr_State_Update, rank, bank);
|
||||||
|
StUpdtEvent.getEventQ().addEvent(StUpdtEvent);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
Error.showErrorAndExit("== Error - Popped a command we shouldn't have of type : " + b.busPacketType);
|
||||||
|
}
|
||||||
|
|
||||||
|
//after state update
|
||||||
|
//schedule command packet as event to rank
|
||||||
|
RamBusAddressCarryingEvent event = new RamBusAddressCarryingEvent( core0.getEventQueue() , (currentTime + mainMemoryConfig.tCMD), this,
|
||||||
|
ranks[rank], RequestType.Main_Mem_Access, b.physicalAddress, b);
|
||||||
|
|
||||||
|
event.getEventQ().addEvent(event);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
else{
|
||||||
|
//Main.debugPrinter.print("Nothing to pop at this time\n");
|
||||||
|
//nothing to do this cycle as nothing popped
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
for (int i=0;i<mainMemoryConfig.numRanks;i++)
|
||||||
|
{
|
||||||
|
refreshCount[i]--;
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
//getter and setter for number of CPU cycles to next RAM clock posedge
|
||||||
|
/*public int getNextTick()
|
||||||
|
{
|
||||||
|
return nextTick;
|
||||||
|
}*/
|
||||||
|
|
||||||
|
|
||||||
|
/*public void setNextTick(int nextTick)
|
||||||
|
{
|
||||||
|
this.nextTick = nextTick;
|
||||||
|
}*/
|
||||||
|
|
||||||
|
|
||||||
|
public double getAverageLatency()
|
||||||
|
{
|
||||||
|
if(totalTransactions > 0)
|
||||||
|
return totalTime/totalTransactions;
|
||||||
|
else
|
||||||
|
return -1.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public long[][] getTotalReadTransactions()
|
||||||
|
{
|
||||||
|
return totalReadTransactions;
|
||||||
|
}
|
||||||
|
|
||||||
|
public long[][] getTotalWriteTransactions()
|
||||||
|
{
|
||||||
|
return totalWriteTransactions;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean WillAcceptTransaction()
|
||||||
|
{
|
||||||
|
//return (this.numTransactions < mainMemoryConfig.TRANSQUEUE_DEPTH);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public MainMemoryBusPacket AddressMapping(long physicalAddress)
|
||||||
|
{
|
||||||
|
long address = physicalAddress; //this will be returned
|
||||||
|
|
||||||
|
//always remember - physical Address is the Byte address!
|
||||||
|
|
||||||
|
long tempA, tempB;
|
||||||
|
int decodedRank, decodedBank, decodedRow, decodedCol, decodedChan;
|
||||||
|
|
||||||
|
int transactionMask = mainMemoryConfig.TRANSACTION_SIZE - 1; //this is the mask in binary. for eg: 0x3f for 64 bytes
|
||||||
|
|
||||||
|
int channelBits = log2(mainMemoryConfig.numChans);
|
||||||
|
int rankBits = log2(mainMemoryConfig.numRanks);
|
||||||
|
int bankBits = log2(mainMemoryConfig.numBanks);
|
||||||
|
int rowBits = log2(mainMemoryConfig.numRows);
|
||||||
|
int colBits = log2(mainMemoryConfig.numCols);
|
||||||
|
int colEffectiveBits;
|
||||||
|
|
||||||
|
int DataBusBytesOffest = log2(mainMemoryConfig.DATA_BUS_BYTES); //for 64 bit bus -> 8 bytes -> lower 3 bits of address irrelevant
|
||||||
|
|
||||||
|
int ColBytesOffset = log2(mainMemoryConfig.BL);
|
||||||
|
//these are the bits we need to throw away because of "bursts". The column address is incremented internally on bursts
|
||||||
|
//So for a burst length of 4, 8 bytes of data are transferred on each burst
|
||||||
|
//Each consecutive 8 byte chunk comes for the "next" column
|
||||||
|
//So we traverse 4 columns in 1 request. Thus the lower log2(4) bits become irrelevant for us. Throw them away
|
||||||
|
//Finally we get 8 bytes * 4 = 32 bytes of data for a 64 bit data bus and BL = 4.
|
||||||
|
//This is equal to a cache line
|
||||||
|
|
||||||
|
//For clarity
|
||||||
|
//Throw away bits to account for data bus size in bytes
|
||||||
|
//and for burst length
|
||||||
|
physicalAddress >>>= (DataBusBytesOffest + ColBytesOffset); //using >>> for unsigned right shift
|
||||||
|
//System.out.println("Shifted address by " + (DataBusBytesOffest + ColBytesOffset) + " bits");
|
||||||
|
|
||||||
|
|
||||||
|
//By the same logic, need to remove the burst-related column bits from the column bit width to be decoded
|
||||||
|
colEffectiveBits = colBits - ColBytesOffset;
|
||||||
|
|
||||||
|
|
||||||
|
if(mainMemoryConfig.rowBufferPolicy == RowBufferPolicy.OpenPage)
|
||||||
|
{
|
||||||
|
//baseline open page scheme
|
||||||
|
//row:rank:bank:col:chan
|
||||||
|
|
||||||
|
tempA = physicalAddress;
|
||||||
|
physicalAddress = physicalAddress >>> channelBits; //always unsigned shifting
|
||||||
|
tempB = physicalAddress << channelBits;
|
||||||
|
//System.out.println("Shifted address by " + rankBits + " bits");
|
||||||
|
decodedChan = (int) (tempA ^ tempB);
|
||||||
|
//System.out.println("decoded rank: " + Integer.toBinaryString(decodedRank));
|
||||||
|
|
||||||
|
tempA = physicalAddress;
|
||||||
|
physicalAddress = physicalAddress >>> colEffectiveBits;
|
||||||
|
tempB = physicalAddress << colEffectiveBits;
|
||||||
|
//System.out.println("Shifted address by " + bankBits + " bits");
|
||||||
|
decodedCol = (int) (tempA ^ tempB);
|
||||||
|
//System.out.println("decoded bank: " + Integer.toBinaryString(decodedBank));
|
||||||
|
|
||||||
|
tempA = physicalAddress;
|
||||||
|
physicalAddress = physicalAddress >>> bankBits;
|
||||||
|
tempB = physicalAddress << bankBits;
|
||||||
|
//System.out.println("Shifted address by " + colEffectiveBits + " bits");
|
||||||
|
decodedBank = (int) (tempA ^ tempB);
|
||||||
|
//System.out.println("decoded col: " + Integer.toBinaryString(decodedCol));
|
||||||
|
|
||||||
|
tempA = physicalAddress;
|
||||||
|
physicalAddress = physicalAddress >>> rankBits;
|
||||||
|
tempB = physicalAddress << rankBits;
|
||||||
|
decodedRank = (int) (tempA ^ tempB);
|
||||||
|
|
||||||
|
tempA = physicalAddress;
|
||||||
|
physicalAddress = physicalAddress >>> rowBits;
|
||||||
|
tempB = physicalAddress << rowBits;
|
||||||
|
decodedRow = (int) (tempA ^ tempB);
|
||||||
|
}
|
||||||
|
|
||||||
|
else if(mainMemoryConfig.rowBufferPolicy == RowBufferPolicy.ClosePage)
|
||||||
|
{
|
||||||
|
//baseline close page scheme
|
||||||
|
//row:col:rank:bank:chan
|
||||||
|
|
||||||
|
tempA = physicalAddress;
|
||||||
|
physicalAddress = physicalAddress >>> channelBits; //always unsigned shifting
|
||||||
|
tempB = physicalAddress << channelBits;
|
||||||
|
//System.out.println("Shifted address by " + rankBits + " bits");
|
||||||
|
decodedChan = (int) (tempA ^ tempB);
|
||||||
|
//System.out.println("decoded rank: " + Integer.toBinaryString(decodedRank));
|
||||||
|
|
||||||
|
tempA = physicalAddress;
|
||||||
|
physicalAddress = physicalAddress >>> bankBits;
|
||||||
|
tempB = physicalAddress << bankBits;
|
||||||
|
//System.out.println("Shifted address by " + bankBits + " bits");
|
||||||
|
decodedBank = (int) (tempA ^ tempB);
|
||||||
|
//System.out.println("decoded bank: " + Integer.toBinaryString(decodedBank));
|
||||||
|
|
||||||
|
tempA = physicalAddress;
|
||||||
|
physicalAddress = physicalAddress >>> rankBits;
|
||||||
|
tempB = physicalAddress << rankBits;
|
||||||
|
//System.out.println("Shifted address by " + colEffectiveBits + " bits");
|
||||||
|
decodedRank = (int) (tempA ^ tempB);
|
||||||
|
//System.out.println("decoded col: " + Integer.toBinaryString(decodedCol));
|
||||||
|
|
||||||
|
tempA = physicalAddress;
|
||||||
|
physicalAddress = physicalAddress >>> colEffectiveBits;
|
||||||
|
tempB = physicalAddress << colEffectiveBits;
|
||||||
|
decodedCol = (int) (tempA ^ tempB);
|
||||||
|
|
||||||
|
tempA = physicalAddress;
|
||||||
|
physicalAddress = physicalAddress >>> rowBits;
|
||||||
|
tempB = physicalAddress << rowBits;
|
||||||
|
decodedRow = (int) (tempA ^ tempB);
|
||||||
|
}
|
||||||
|
|
||||||
|
else //invalid case
|
||||||
|
{
|
||||||
|
decodedRow = -1;
|
||||||
|
decodedCol = -1;
|
||||||
|
decodedBank = -1;
|
||||||
|
decodedRank = -1;
|
||||||
|
decodedChan = -1;
|
||||||
|
Error.showErrorAndExit("Invalid Row Buffer Policy!");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//if num ranks = 1, decoded rank will always be "0"
|
||||||
|
|
||||||
|
|
||||||
|
MainMemoryBusPacket b = new MainMemoryBusPacket(decodedRow, decodedCol, decodedBank, decodedRank, address, null);
|
||||||
|
return b;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static int log2(int a)
|
||||||
|
{
|
||||||
|
return (int) (Math.log(a)/Math.log(2));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public BusPacketType requestTypeToBusPacketType(RequestType requestType)
|
||||||
|
{
|
||||||
|
switch(requestType)
|
||||||
|
{
|
||||||
|
case Cache_Read:
|
||||||
|
if(mainMemoryConfig.getRowBufferPolicy()==RowBufferPolicy.ClosePage)
|
||||||
|
{
|
||||||
|
return BusPacketType.READ_P;
|
||||||
|
}
|
||||||
|
else if(mainMemoryConfig.getRowBufferPolicy()==RowBufferPolicy.OpenPage)
|
||||||
|
{
|
||||||
|
return BusPacketType.READ;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Error.showErrorAndExit("Unkown row buffer policy");
|
||||||
|
return null; //needed to avoid compile error
|
||||||
|
}
|
||||||
|
//break; //not required because "unreachable" code
|
||||||
|
case Cache_Write:
|
||||||
|
if(mainMemoryConfig.getRowBufferPolicy()==RowBufferPolicy.ClosePage)
|
||||||
|
{
|
||||||
|
return BusPacketType.WRITE_P;
|
||||||
|
}
|
||||||
|
else if(mainMemoryConfig.getRowBufferPolicy()==RowBufferPolicy.OpenPage)
|
||||||
|
{
|
||||||
|
return BusPacketType.WRITE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Error.showErrorAndExit("Unkown row buffer policy");
|
||||||
|
return null; //needed to avoid compile error
|
||||||
|
}
|
||||||
|
//break;
|
||||||
|
default:
|
||||||
|
Error.showErrorAndExit("Request type "+ requestType + "does not have a corresponding bus packet type");
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setChannelNumber(int n)
|
||||||
|
{
|
||||||
|
this.channel = n;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public int getChannelNumber()
|
||||||
|
{
|
||||||
|
return this.channel;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setBusFreeTime(long t)
|
||||||
|
{
|
||||||
|
this.busFreeTime = t;
|
||||||
|
}
|
||||||
|
|
||||||
|
public long getBusFreeTime()
|
||||||
|
{
|
||||||
|
return this.busFreeTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*public void printBankStateTest()
|
||||||
|
{
|
||||||
|
Main.outputLog.print("== Printing bank states (According to MC) at Clock Cycle " + GlobalClock.getCurrentTime() + "\n");
|
||||||
|
for (int i=0; i < mainMemoryConfig.numRanks; i++)
|
||||||
|
{
|
||||||
|
for (int j=0; j < mainMemoryConfig.numBanks; j++)
|
||||||
|
{
|
||||||
|
if (bankStates[i][j].currentBankState == CurrentBankState.ROW_ACTIVE)
|
||||||
|
{
|
||||||
|
Main.outputLog.print("[" + bankStates[i][j].openRowAddress + "] ");
|
||||||
|
}
|
||||||
|
else if (bankStates[i][j].currentBankState == CurrentBankState.IDLE)
|
||||||
|
{
|
||||||
|
Main.outputLog.print("[idle] ");
|
||||||
|
}
|
||||||
|
else if (bankStates[i][j].currentBankState == CurrentBankState.PRECHARGING)
|
||||||
|
{
|
||||||
|
Main.outputLog.print("[pre] ");
|
||||||
|
}
|
||||||
|
else if (bankStates[i][j].currentBankState == CurrentBankState.REFRESHING)
|
||||||
|
{
|
||||||
|
Main.outputLog.print("[ref] ");
|
||||||
|
}
|
||||||
|
else if (bankStates[i][j].currentBankState == CurrentBankState.POWER_DOWN)
|
||||||
|
{
|
||||||
|
Main.outputLog.print("[lowp] ");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Main.outputLog.print("\n");
|
||||||
|
}
|
||||||
|
}*/
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,786 @@
|
||||||
|
package dram;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
|
||||||
|
import config.SystemConfig;
|
||||||
|
import config.MainMemoryConfig;
|
||||||
|
import config.MainMemoryConfig.QueuingStructure;
|
||||||
|
import config.MainMemoryConfig.RowBufferPolicy;
|
||||||
|
import config.MainMemoryConfig.SchedulingPolicy;
|
||||||
|
import dram.BankState.CurrentBankState;
|
||||||
|
import dram.MainMemoryBusPacket.BusPacketType;
|
||||||
|
import generic.Core;
|
||||||
|
import generic.Event;
|
||||||
|
import generic.EventQueue;
|
||||||
|
import generic.GlobalClock;
|
||||||
|
import generic.RequestType;
|
||||||
|
import main.ArchitecturalComponent;
|
||||||
|
import main.Main;
|
||||||
|
import memorysystem.AddressCarryingEvent;
|
||||||
|
import memorysystem.Cache;
|
||||||
|
import memorysystem.MainMemoryController;
|
||||||
|
import misc.Error;
|
||||||
|
|
||||||
|
public class MainMemoryDRAMControllerTest extends MainMemoryController{
|
||||||
|
|
||||||
|
private int numTransactions;
|
||||||
|
|
||||||
|
|
||||||
|
MainMemoryConfig mainMemoryConfig;
|
||||||
|
|
||||||
|
//TODO: need a way to store the actual requesting element
|
||||||
|
//dirty workaround for now
|
||||||
|
|
||||||
|
Cache parentCache;
|
||||||
|
int refreshRank;
|
||||||
|
Test parentTest;
|
||||||
|
|
||||||
|
ArrayList<MainMemoryBusPacket> pendingTransQueue;
|
||||||
|
//MainMemoryBusPacket pendingTransQueue[]; //to keep track of packets that could not be added to command queue
|
||||||
|
BankState bankStates[][];
|
||||||
|
CommandQueue commandQueue;
|
||||||
|
Rank ranks[];
|
||||||
|
int refreshCount[];
|
||||||
|
|
||||||
|
public MainMemoryDRAMControllerTest(MainMemoryConfig mainMemoryConfig, Test parentTest) {
|
||||||
|
super();
|
||||||
|
|
||||||
|
this.parentTest = parentTest;
|
||||||
|
this.mainMemoryConfig = mainMemoryConfig;
|
||||||
|
|
||||||
|
numTransactions = 0;
|
||||||
|
refreshRank=0;
|
||||||
|
ranks = new Rank[mainMemoryConfig.numRanks];
|
||||||
|
bankStates = new BankState[mainMemoryConfig.numRanks][mainMemoryConfig.numBanks];
|
||||||
|
|
||||||
|
//TODO is there a more elegant way :P
|
||||||
|
for(int i=0; i < mainMemoryConfig.numRanks;i++)
|
||||||
|
{
|
||||||
|
for(int j=0; j < mainMemoryConfig.numBanks; j++)
|
||||||
|
{
|
||||||
|
bankStates[i][j] = new BankState();
|
||||||
|
}
|
||||||
|
ranks[i] = new Rank(mainMemoryConfig,i,this);
|
||||||
|
}
|
||||||
|
|
||||||
|
pendingTransQueue=new ArrayList<MainMemoryBusPacket>();
|
||||||
|
|
||||||
|
commandQueue = new CommandQueue(mainMemoryConfig,bankStates);
|
||||||
|
|
||||||
|
//TODO: allocate and initialize arrays
|
||||||
|
refreshCount=new int[mainMemoryConfig.numRanks];
|
||||||
|
|
||||||
|
for(int i=0;i<mainMemoryConfig.numRanks;i++){
|
||||||
|
refreshCount[i]=(int)((mainMemoryConfig.RefreshPeriod/mainMemoryConfig.tCK)/mainMemoryConfig.numRanks)*(i+1);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void handleEvent(EventQueue eventQ, Event e)
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
long currentTime = GlobalClock.getCurrentTime();
|
||||||
|
|
||||||
|
//System.out.println("Hi!! handling a dram event of type " + e.getRequestType());
|
||||||
|
Test.debugPrinter.print("\nHi!! handling a dram event of type " + e.getRequestType()+ "\n");
|
||||||
|
|
||||||
|
|
||||||
|
//check if state update event
|
||||||
|
|
||||||
|
if(e.getRequestType() == RequestType.Mem_Cntrlr_State_Update) {
|
||||||
|
|
||||||
|
StateUpdateEvent event = (StateUpdateEvent) e;
|
||||||
|
|
||||||
|
int rank = event.getRank();
|
||||||
|
int bank = event.getBank();
|
||||||
|
long eventTime = event.getEventTime(); //IMP: the reference for timing should be the time previous event was generated
|
||||||
|
//and not the current clock cycle as these 2 may differ sometimes!
|
||||||
|
BankState bankState = bankStates[rank][bank];
|
||||||
|
|
||||||
|
Test.debugPrinter.print("\nHi!! Updating state for bank " + bank + " with last command " + bankState.lastCommand
|
||||||
|
+ " and current Bank State " + bankState.currentBankState +"\n\n");
|
||||||
|
|
||||||
|
//FSM for commands with implicit state change
|
||||||
|
switch(bankState.lastCommand) {
|
||||||
|
|
||||||
|
case WRITE_P:
|
||||||
|
case READ_P:
|
||||||
|
bankState.currentBankState = CurrentBankState.PRECHARGING;
|
||||||
|
bankState.lastCommand = BusPacketType.PRECHARGE;
|
||||||
|
//create new FSM event and add to original queue
|
||||||
|
StateUpdateEvent FSMevent = new StateUpdateEvent(eventQ, (eventTime+mainMemoryConfig.tRP-1), e.getRequestingElement(),
|
||||||
|
e.getProcessingElement(), RequestType.Mem_Cntrlr_State_Update, rank, bank);
|
||||||
|
eventQ.addEvent(FSMevent);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case REFRESH:
|
||||||
|
//if last command was refresh, all banks were refreshed in that rank. set all as idle
|
||||||
|
for(int i=0; i < mainMemoryConfig.numBanks; i++)
|
||||||
|
{
|
||||||
|
bankStates[rank][i].currentBankState = CurrentBankState.IDLE;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case PRECHARGE:
|
||||||
|
bankState.currentBankState = CurrentBankState.IDLE;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
else if(e.getRequestType() == RequestType.Cache_Read || e.getRequestType() == RequestType.Cache_Write) {
|
||||||
|
|
||||||
|
//got a read or write event -> perform address mapping and add it to command queue
|
||||||
|
|
||||||
|
if(true)
|
||||||
|
{
|
||||||
|
|
||||||
|
//System.out.println("Hi handling a Cache Read!!");
|
||||||
|
|
||||||
|
|
||||||
|
//TODO: very dirty workaround
|
||||||
|
this.parentCache = (Cache) e.getRequestingElement();
|
||||||
|
|
||||||
|
|
||||||
|
AddressCarryingEvent event = (AddressCarryingEvent) e;
|
||||||
|
|
||||||
|
//maintain number of transactions waiting to be serviced
|
||||||
|
numTransactions++;
|
||||||
|
|
||||||
|
|
||||||
|
MainMemoryBusPacket b = AddressMapping(event.getAddress());
|
||||||
|
b.setBusPacketType(requestTypeToBusPacketType(event.getRequestType()));
|
||||||
|
|
||||||
|
//for TIMING
|
||||||
|
b.timeCreated = GlobalClock.getCurrentTime();
|
||||||
|
|
||||||
|
//pendingTransQueue.add(x);
|
||||||
|
|
||||||
|
//MainMemoryBusPacket b=pendingTransQueue.get(0);
|
||||||
|
|
||||||
|
|
||||||
|
Test.debugPrinter.print("Of bus packet type:");
|
||||||
|
b.printPacketToFile();
|
||||||
|
|
||||||
|
|
||||||
|
if(commandQueue.hasRoomFor(2,b.rank, b.bank))
|
||||||
|
{
|
||||||
|
numTransactions--; //the transaction is no longer waiting in the controller
|
||||||
|
//pendingTransQueue.remove(0);
|
||||||
|
//create new ACTIVATE bus packet with the address we just decoded
|
||||||
|
MainMemoryBusPacket ACTcommand = b.Clone(); //check cloning is ok
|
||||||
|
ACTcommand.setBusPacketType(BusPacketType.ACTIVATE);
|
||||||
|
|
||||||
|
//create read or write command and enqueue it
|
||||||
|
MainMemoryBusPacket RWcommand = b.Clone();
|
||||||
|
//RWcommand.setBusPacketType(requestTypeToBusPacketType(event.getRequestType()));
|
||||||
|
|
||||||
|
//System.out.println("Enqueuing commands for address " + event.getAddress());
|
||||||
|
//System.out.println("ACTcommand busPacketType "+ACTcommand.busPacketType);
|
||||||
|
//System.out.println("RWcommand busPacketType "+RWcommand.busPacketType);
|
||||||
|
|
||||||
|
commandQueue.enqueue(ACTcommand);
|
||||||
|
commandQueue.enqueue(RWcommand);
|
||||||
|
|
||||||
|
Test.debugPrinter.print("Enqueued ACT command bus packet to queue as follows:");
|
||||||
|
ACTcommand.printPacketToFile();
|
||||||
|
Test.debugPrinter.print("Enqueued RW command bus packet to queue as follows:");
|
||||||
|
RWcommand.printPacketToFile();
|
||||||
|
|
||||||
|
//TODO: do we need to keep transactions yet to receive data in a pending queue?
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
//TODO: add power calculations. here?
|
||||||
|
|
||||||
|
else
|
||||||
|
{
|
||||||
|
//TODO: need to postpone this event, but by how much time??
|
||||||
|
Test.debugPrinter.print("No room in command queue!! For rank " + b.rank +"\n");
|
||||||
|
Test.debugPrinter.print("Adding to pending queue!");
|
||||||
|
pendingTransQueue.add(b);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
else {
|
||||||
|
//TODO: see how to handle this
|
||||||
|
//actually there is no need to handle this if the transq size is not limited
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
//finally send the data to cpu
|
||||||
|
|
||||||
|
else if (e.getRequestType() == RequestType.Rank_Response)
|
||||||
|
{
|
||||||
|
|
||||||
|
//System.out.println("Received rank response! Sending event");
|
||||||
|
|
||||||
|
//for TEST
|
||||||
|
if(mainMemoryConfig.DEBUG_BUS)
|
||||||
|
{
|
||||||
|
Test.outputLog.print(" -- MC Receiving From Data Bus on Clock Cycle "+ GlobalClock.getCurrentTime() +" : ");
|
||||||
|
//((RamBusAddressCarryingEvent) e).getBusPacket().printTest();
|
||||||
|
}
|
||||||
|
|
||||||
|
//for TEST
|
||||||
|
if (mainMemoryConfig.DEBUG_BUS)
|
||||||
|
{
|
||||||
|
Test.outputLog.print(" -- MC Issuing to CPU bus at Clock Cycle " + GlobalClock.getCurrentTime() +" : ");
|
||||||
|
Test.outputLog.print("T [Data] [0x"+ String.format("%07X",((AddressCarryingEvent)e).getAddress()).toLowerCase() + "] [0]\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
//for TIMING TEST
|
||||||
|
|
||||||
|
/*Test.timingLog.print("Id: " + ((RamBusAddressCarryingEvent) e).getBusPacket().testid);
|
||||||
|
Test.timingLog.print(" Address : " + String.format("%08X",((RamBusAddressCarryingEvent) e).getBusPacket().physicalAddress));
|
||||||
|
Test.timingLog.print(" Created at : " + ((RamBusAddressCarryingEvent) e).getBusPacket().timeCreated);
|
||||||
|
Test.timingLog.print(" Completed at : " + GlobalClock.getCurrentTime() + "\n");
|
||||||
|
*/
|
||||||
|
|
||||||
|
Test.timingLog.print(Long.toString(((RamBusAddressCarryingEvent) e).getBusPacket().timeCreated));
|
||||||
|
Test.timingLog.print(" " + GlobalClock.getCurrentTime() + "\n");
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
AddressCarryingEvent event = new AddressCarryingEvent(eventQ, 0,
|
||||||
|
this, this.parentCache, RequestType.Mem_Response,
|
||||||
|
((AddressCarryingEvent)e).getAddress());
|
||||||
|
//IMP
|
||||||
|
//TODO: how to make processing element as cache????
|
||||||
|
//very dirty workaround right now
|
||||||
|
|
||||||
|
//understand what this does
|
||||||
|
//getComInterface().sendMessage(event);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//TODO: what to do for a write?
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public void oneCycleOperation(){
|
||||||
|
Test.debugPrinter.print("\nhi! In one cycle operation for time " + GlobalClock.getCurrentTime() + "\n");
|
||||||
|
//MainMemoryBusPacket b = commandQueue.pop();
|
||||||
|
long currentTime = GlobalClock.getCurrentTime();
|
||||||
|
//Core parentTest = ArchitecturalComponent.getCores()[0]; //using core 0 queue similar to as in cache
|
||||||
|
|
||||||
|
if (refreshCount[refreshRank]==0)
|
||||||
|
{
|
||||||
|
commandQueue.needRefresh(refreshRank);
|
||||||
|
ranks[refreshRank].refreshWaiting = true;
|
||||||
|
refreshCount[refreshRank] = (int)(mainMemoryConfig.RefreshPeriod/mainMemoryConfig.tCK);
|
||||||
|
refreshRank++;
|
||||||
|
if (refreshRank == mainMemoryConfig.numRanks)
|
||||||
|
{
|
||||||
|
refreshRank = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//TODO:need to implement power portion of refresh
|
||||||
|
MainMemoryBusPacket b = null;
|
||||||
|
b = commandQueue.pop(currentTime);
|
||||||
|
//if(commandQueue.canPop())
|
||||||
|
|
||||||
|
|
||||||
|
if(b!=null)
|
||||||
|
{
|
||||||
|
|
||||||
|
//TODO: is there a more elegant way to do this?
|
||||||
|
//MainMemoryBusPacket b = commandQueue.pop(currentTime);
|
||||||
|
|
||||||
|
|
||||||
|
Test.debugPrinter.print("\n\nHi!! Popped a bus packet from queue successfully! Packet is \n");
|
||||||
|
b.printPacketToFile();
|
||||||
|
Test.debugPrinter.print("\n\n");
|
||||||
|
|
||||||
|
|
||||||
|
//added by harveenk
|
||||||
|
//Popped a memory packet so let's add pending packets if we have space for 2 and if it is the correct queue
|
||||||
|
//First check if we have any pending packets
|
||||||
|
if(pendingTransQueue.size()>0 && commandQueue.hasRoomFor(2, b.rank, b.bank))
|
||||||
|
{
|
||||||
|
|
||||||
|
int foundPacketIndex = -1;
|
||||||
|
MainMemoryBusPacket pendingPacket = null;
|
||||||
|
|
||||||
|
//find the first packet from the pending list that belongs to this particular queue
|
||||||
|
for(int i = 0; i < pendingTransQueue.size(); i++)
|
||||||
|
{
|
||||||
|
pendingPacket = pendingTransQueue.get(i);
|
||||||
|
if(pendingPacket.rank == b.rank &&
|
||||||
|
!( mainMemoryConfig.queuingStructure == QueuingStructure.PerRankPerBank && pendingPacket.bank != b.bank))
|
||||||
|
{
|
||||||
|
foundPacketIndex = i;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*if(mainMemoryConfig.DEBUG_CMDQ && currentTime >= 34193)
|
||||||
|
{
|
||||||
|
Test.outputLog.print("Trying to enqueue pending packet\n");
|
||||||
|
pendingPacket.printTest();
|
||||||
|
Test.outputLog.print("\n");
|
||||||
|
}*/
|
||||||
|
|
||||||
|
if(foundPacketIndex != -1) //found a packet for this queue, so add!
|
||||||
|
{
|
||||||
|
numTransactions--; //the transaction is no longer waiting in the controller
|
||||||
|
pendingTransQueue.remove(foundPacketIndex);
|
||||||
|
//create new ACTIVATE bus packet with the address we just decoded
|
||||||
|
MainMemoryBusPacket ACTcommand = pendingPacket.Clone(); //check cloning is ok
|
||||||
|
ACTcommand.setBusPacketType(BusPacketType.ACTIVATE);
|
||||||
|
|
||||||
|
//create read or write command and enqueue it
|
||||||
|
MainMemoryBusPacket RWcommand = pendingPacket.Clone();
|
||||||
|
//RWcommand.setBusPacketType(requestTypeToBusPacketType(event.getRequestType()));
|
||||||
|
|
||||||
|
Test.debugPrinter.print("\nGot room in queue! Adding a pending bus packet!!\n\n");
|
||||||
|
|
||||||
|
//System.out.println("Enqueuing commands for address " + pendingPacket.physicalAddress);
|
||||||
|
//System.out.println("ACTcommand busPacketType "+ACTcommand.busPacketType);
|
||||||
|
//System.out.println("RWcommand busPacketType "+RWcommand.busPacketType);
|
||||||
|
|
||||||
|
commandQueue.enqueue(ACTcommand);
|
||||||
|
commandQueue.enqueue(RWcommand);
|
||||||
|
|
||||||
|
Test.debugPrinter.print("Enqueued ACT command bus packet to queue as follows:");
|
||||||
|
ACTcommand.printPacketToFile();
|
||||||
|
Test.debugPrinter.print("Enqueued RW command bus packet to queue as follows:");
|
||||||
|
RWcommand.printPacketToFile();
|
||||||
|
|
||||||
|
//TODO: do we need to keep transactions yet to receive data in a pending queue?
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
int rank = b.rank;
|
||||||
|
int bank = b.bank;
|
||||||
|
|
||||||
|
if (b.busPacketType == BusPacketType.WRITE || b.busPacketType == BusPacketType.WRITE_P)
|
||||||
|
{
|
||||||
|
//if write, schedule the data packet
|
||||||
|
|
||||||
|
MainMemoryBusPacket dataPacketToSend = b.Clone();
|
||||||
|
dataPacketToSend.setBusPacketType(BusPacketType.DATA);
|
||||||
|
|
||||||
|
Test.debugPrinter.print("\n\n Received a write, scheduling event for data packet for address " + dataPacketToSend.physicalAddress + "\n\n");
|
||||||
|
|
||||||
|
RamBusAddressCarryingEvent event = new RamBusAddressCarryingEvent( parentTest.getEventQueue() , (currentTime + mainMemoryConfig.tWL), this,
|
||||||
|
ranks[rank], RequestType.Main_Mem_Access, dataPacketToSend.physicalAddress, dataPacketToSend);
|
||||||
|
event.getEventQ().addEvent(event);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
//update state according to the popped bus packet
|
||||||
|
|
||||||
|
switch(b.busPacketType)
|
||||||
|
{
|
||||||
|
case READ_P:
|
||||||
|
case READ:
|
||||||
|
if(b.busPacketType == BusPacketType.READ_P)
|
||||||
|
{
|
||||||
|
bankStates[rank][bank].nextActivate = Math.max(currentTime + mainMemoryConfig.ReadAutopreDelay,
|
||||||
|
bankStates[rank][bank].nextActivate);
|
||||||
|
bankStates[rank][bank].lastCommand = BusPacketType.READ_P;
|
||||||
|
|
||||||
|
|
||||||
|
//create and send event state update event
|
||||||
|
//sending to core 0 event queue currently
|
||||||
|
//keeping requesting and processing element same
|
||||||
|
StateUpdateEvent StUpdtEvent = new StateUpdateEvent(parentTest.getEventQueue(), (currentTime+mainMemoryConfig.ReadToPreDelay), this,
|
||||||
|
this, RequestType.Mem_Cntrlr_State_Update, rank, bank);
|
||||||
|
StUpdtEvent.getEventQ().addEvent(StUpdtEvent);
|
||||||
|
|
||||||
|
}
|
||||||
|
else if (b.busPacketType == BusPacketType.READ)
|
||||||
|
{
|
||||||
|
bankStates[rank][bank].nextPrecharge = Math.max(currentTime + mainMemoryConfig.ReadToPreDelay,
|
||||||
|
bankStates[rank][bank].nextPrecharge);
|
||||||
|
bankStates[rank][bank].lastCommand = BusPacketType.READ;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i=0;i< mainMemoryConfig.numRanks;i++)
|
||||||
|
{
|
||||||
|
for (int j=0;j<mainMemoryConfig.numBanks;j++)
|
||||||
|
{
|
||||||
|
if (i!= rank)
|
||||||
|
{
|
||||||
|
|
||||||
|
if (bankStates[i][j].currentBankState == CurrentBankState.ROW_ACTIVE)
|
||||||
|
{
|
||||||
|
bankStates[i][j].nextRead = Math.max(currentTime + mainMemoryConfig.tBL/2 + mainMemoryConfig.tRTRS, bankStates[i][j].nextRead);
|
||||||
|
bankStates[i][j].nextWrite = Math.max(currentTime + mainMemoryConfig.ReadToWriteDelay,
|
||||||
|
bankStates[i][j].nextWrite);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
bankStates[i][j].nextRead = Math.max(currentTime + Math.max(mainMemoryConfig.tCCD, mainMemoryConfig.tBL/2),
|
||||||
|
bankStates[i][j].nextRead);
|
||||||
|
bankStates[i][j].nextWrite = Math.max(currentTime + mainMemoryConfig.ReadToWriteDelay,
|
||||||
|
bankStates[i][j].nextWrite);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (b.busPacketType == BusPacketType.READ_P)
|
||||||
|
{
|
||||||
|
//set read and write to nextActivate so the state table will prevent a read or write
|
||||||
|
// being issued (in cq.isIssuable())before the bank state has been changed because of the
|
||||||
|
// auto-precharge associated with this command
|
||||||
|
bankStates[rank][bank].nextRead = bankStates[rank][bank].nextActivate;
|
||||||
|
bankStates[rank][bank].nextWrite = bankStates[rank][bank].nextActivate;
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
case WRITE_P:
|
||||||
|
case WRITE:
|
||||||
|
if (b.busPacketType == BusPacketType.WRITE_P)
|
||||||
|
{
|
||||||
|
bankStates[rank][bank].nextActivate = Math.max(currentTime + mainMemoryConfig.WriteAutopreDelay,
|
||||||
|
bankStates[rank][bank].nextActivate);
|
||||||
|
bankStates[rank][bank].lastCommand = BusPacketType.WRITE_P;
|
||||||
|
|
||||||
|
//create and send event state update event
|
||||||
|
//sending to core 0 event queue currently
|
||||||
|
//keeping requesting and processing element same
|
||||||
|
StateUpdateEvent StUpdtEvent = new StateUpdateEvent(parentTest.getEventQueue(), (currentTime+mainMemoryConfig.WriteToPreDelay), this,
|
||||||
|
this, RequestType.Mem_Cntrlr_State_Update, rank, bank);
|
||||||
|
StUpdtEvent.getEventQ().addEvent(StUpdtEvent);
|
||||||
|
Test.debugPrinter.print("\nAdded State update event to trigger at "+ (currentTime+mainMemoryConfig.WriteToPreDelay) + " for WRITE_P for bus packet ");
|
||||||
|
b.printPacketToFile();
|
||||||
|
|
||||||
|
}
|
||||||
|
else if (b.busPacketType == BusPacketType.WRITE)
|
||||||
|
{
|
||||||
|
bankStates[rank][bank].nextPrecharge = Math.max(currentTime + mainMemoryConfig.WriteToPreDelay,
|
||||||
|
bankStates[rank][bank].nextPrecharge);
|
||||||
|
bankStates[rank][bank].lastCommand = BusPacketType.WRITE;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
for (int i=0;i< mainMemoryConfig.numRanks;i++)
|
||||||
|
{
|
||||||
|
for (int j=0;j<mainMemoryConfig.numBanks;j++)
|
||||||
|
{
|
||||||
|
if (i!=rank)
|
||||||
|
{
|
||||||
|
if (bankStates[i][j].currentBankState == CurrentBankState.ROW_ACTIVE)
|
||||||
|
{
|
||||||
|
bankStates[i][j].nextWrite = Math.max(currentTime + mainMemoryConfig.tBL/2 + mainMemoryConfig.tRTRS, bankStates[i][j].nextWrite);
|
||||||
|
bankStates[i][j].nextRead = Math.max(currentTime + mainMemoryConfig.WriteToReadDelayR,
|
||||||
|
bankStates[i][j].nextRead);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
bankStates[i][j].nextWrite = Math.max(currentTime + Math.max(mainMemoryConfig.tBL/2, mainMemoryConfig.tCCD), bankStates[i][j].nextWrite);
|
||||||
|
bankStates[i][j].nextRead = Math.max(currentTime + mainMemoryConfig.WriteToReadDelayB,
|
||||||
|
bankStates[i][j].nextRead);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//set read and write to nextActivate so the state table will prevent a read or write
|
||||||
|
// being issued (in cq.isIssuable())before the bank state has been changed because of the
|
||||||
|
// auto-precharge associated with this command
|
||||||
|
if (b.busPacketType == BusPacketType.WRITE_P)
|
||||||
|
{
|
||||||
|
bankStates[rank][bank].nextRead = bankStates[rank][bank].nextActivate;
|
||||||
|
bankStates[rank][bank].nextWrite = bankStates[rank][bank].nextActivate;
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ACTIVATE:
|
||||||
|
|
||||||
|
bankStates[rank][bank].currentBankState = CurrentBankState.ROW_ACTIVE;
|
||||||
|
bankStates[rank][bank].lastCommand = BusPacketType.ACTIVATE;
|
||||||
|
bankStates[rank][bank].openRowAddress = b.row;
|
||||||
|
bankStates[rank][bank].nextActivate = Math.max(currentTime + mainMemoryConfig.tRC, bankStates[rank][bank].nextActivate);
|
||||||
|
bankStates[rank][bank].nextPrecharge = Math.max(currentTime + mainMemoryConfig.tRAS, bankStates[rank][bank].nextPrecharge);
|
||||||
|
|
||||||
|
//if we are using posted-CAS, the next column access can be sooner than normal operation
|
||||||
|
|
||||||
|
bankStates[rank][bank].nextRead = Math.max(currentTime + (mainMemoryConfig.tRCD-mainMemoryConfig.tAL), bankStates[rank][bank].nextRead);
|
||||||
|
bankStates[rank][bank].nextWrite = Math.max(currentTime + (mainMemoryConfig.tRCD-mainMemoryConfig.tAL), bankStates[rank][bank].nextWrite);
|
||||||
|
|
||||||
|
for (int i=0;i<mainMemoryConfig.numBanks;i++)
|
||||||
|
{
|
||||||
|
if (i!=bank)
|
||||||
|
{
|
||||||
|
bankStates[rank][i].nextActivate = Math.max(currentTime + mainMemoryConfig.tRRD, bankStates[rank][i].nextActivate);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
case PRECHARGE:
|
||||||
|
{
|
||||||
|
bankStates[rank][bank].currentBankState = CurrentBankState.PRECHARGING;
|
||||||
|
bankStates[rank][bank].lastCommand = BusPacketType.PRECHARGE;
|
||||||
|
bankStates[rank][bank].nextActivate = Math.max(currentTime + mainMemoryConfig.tRP, bankStates[rank][bank].nextActivate);
|
||||||
|
|
||||||
|
//create and send event state update event
|
||||||
|
//sending to core 0 event queue currently
|
||||||
|
//keeping requesting and processing element same
|
||||||
|
StateUpdateEvent StUpdtEvent = new StateUpdateEvent(parentTest.getEventQueue(), (currentTime+mainMemoryConfig.tRP - 1), this,
|
||||||
|
this, RequestType.Mem_Cntrlr_State_Update, rank, bank);
|
||||||
|
StUpdtEvent.getEventQ().addEvent(StUpdtEvent);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case REFRESH:
|
||||||
|
{
|
||||||
|
for (int i=0; i< mainMemoryConfig.numBanks ;i++)
|
||||||
|
{
|
||||||
|
bankStates[rank][i].nextActivate = currentTime + mainMemoryConfig.tRFC;
|
||||||
|
bankStates[rank][i].currentBankState = CurrentBankState.REFRESHING;
|
||||||
|
bankStates[rank][i].lastCommand = BusPacketType.REFRESH;
|
||||||
|
}
|
||||||
|
|
||||||
|
//create and send event state update event
|
||||||
|
//sending to core 0 event queue currently
|
||||||
|
//keeping requesting and processing element same
|
||||||
|
|
||||||
|
//Sending only 1 event, need to refresh all banks in the rank for this - do this in handle event
|
||||||
|
StateUpdateEvent StUpdtEvent = new StateUpdateEvent(parentTest.getEventQueue(), (currentTime+mainMemoryConfig.tRFC - 1), this,
|
||||||
|
this, RequestType.Mem_Cntrlr_State_Update, rank, bank);
|
||||||
|
StUpdtEvent.getEventQ().addEvent(StUpdtEvent);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
Error.showErrorAndExit("== Error - Popped a command we shouldn't have of type : " + b.busPacketType);
|
||||||
|
}
|
||||||
|
|
||||||
|
//IMP!!!
|
||||||
|
//TODO: check for collision on bus
|
||||||
|
|
||||||
|
//after state update
|
||||||
|
//schedule command packet as event to rank
|
||||||
|
RamBusAddressCarryingEvent event = new RamBusAddressCarryingEvent( parentTest.getEventQueue() , (currentTime + mainMemoryConfig.tCMD), this,
|
||||||
|
ranks[rank], RequestType.Main_Mem_Access, b.physicalAddress, b);
|
||||||
|
|
||||||
|
//TODO why is sendEvent not working?
|
||||||
|
//sendEvent(event); //using send event
|
||||||
|
|
||||||
|
event.getEventQ().addEvent(event);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//for TEST
|
||||||
|
if(mainMemoryConfig.DEBUG_BUS)
|
||||||
|
{
|
||||||
|
Test.outputLog.print(" -- MC Issuing On Command Bus at Clock Cycle "+ GlobalClock.getCurrentTime() +" : ");
|
||||||
|
//b.printTest();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
else{
|
||||||
|
Test.debugPrinter.print("Nothing to pop at this time\n");
|
||||||
|
//nothing to do this cycle as nothing popped
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// if(mainMemoryConfig.DEBUG_CMDQ){
|
||||||
|
// commandQueue.printTest();
|
||||||
|
// }
|
||||||
|
|
||||||
|
for (int i=0;i<mainMemoryConfig.numRanks;i++)
|
||||||
|
{
|
||||||
|
refreshCount[i]--;
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public boolean WillAcceptTransaction()
|
||||||
|
{
|
||||||
|
return (this.numTransactions < mainMemoryConfig.TRANSQUEUE_DEPTH);
|
||||||
|
}
|
||||||
|
|
||||||
|
public MainMemoryBusPacket AddressMapping(long physicalAddress)
|
||||||
|
{
|
||||||
|
//TODO: implement other schemes
|
||||||
|
|
||||||
|
|
||||||
|
long address = physicalAddress; //this will be returned
|
||||||
|
|
||||||
|
//always remember - physical Address is the Byte address!
|
||||||
|
|
||||||
|
long tempA, tempB;
|
||||||
|
int decodedRank, decodedBank, decodedRow, decodedCol, decodedChan;
|
||||||
|
|
||||||
|
int transactionMask = mainMemoryConfig.TRANSACTION_SIZE - 1; //this is the mask in binary. for eg: 0x3f for 64 bytes
|
||||||
|
|
||||||
|
int channelBits = log2(mainMemoryConfig.numChans);
|
||||||
|
int rankBits = log2(mainMemoryConfig.numRanks);
|
||||||
|
int bankBits = log2(mainMemoryConfig.numBanks);
|
||||||
|
int rowBits = log2(mainMemoryConfig.numRows);
|
||||||
|
int colBits = log2(mainMemoryConfig.numCols);
|
||||||
|
int colEffectiveBits;
|
||||||
|
|
||||||
|
int DataBusBytesOffest = log2(mainMemoryConfig.DATA_BUS_BYTES); //for 64 bit bus -> 8 bytes -> lower 3 bits of address irrelevant
|
||||||
|
|
||||||
|
int ColBytesOffset = log2(mainMemoryConfig.tBL);
|
||||||
|
//these are the bits we need to throw away because of "bursts". The column address is incremented internally on bursts
|
||||||
|
//So for a burst length of 4, 8 bytes of data are transferred on each burst
|
||||||
|
//Each consecutive 8 byte chunk comes for the "next" column
|
||||||
|
//So we traverse 4 columns in 1 request. Thus the lower log2(4) bits become irrelevant for us. Throw them away
|
||||||
|
//Finally we get 8 bytes * 4 = 32 bytes of data for a 64 bit data bus and BL = 4.
|
||||||
|
//This is equal to a cache line
|
||||||
|
|
||||||
|
//For clarity
|
||||||
|
//Throw away bits to account for data bus size in bytes
|
||||||
|
//and for burst length
|
||||||
|
physicalAddress >>>= (DataBusBytesOffest + ColBytesOffset); //using >>> for unsigned right shift
|
||||||
|
//System.out.println("Shifted address by " + (DataBusBytesOffest + ColBytesOffset) + " bits");
|
||||||
|
|
||||||
|
|
||||||
|
//By the same logic, need to remove the burst-related column bits from the column bit width to be decoded
|
||||||
|
colEffectiveBits = colBits - ColBytesOffset;
|
||||||
|
|
||||||
|
|
||||||
|
//implementing 1 scheme --- "scheme 2"
|
||||||
|
//chan:row:col:bank:rank
|
||||||
|
|
||||||
|
tempA = physicalAddress;
|
||||||
|
physicalAddress = physicalAddress >>> rankBits; //always unsigned shifting
|
||||||
|
tempB = physicalAddress << rankBits;
|
||||||
|
//System.out.println("Shifted address by " + rankBits + " bits");
|
||||||
|
decodedRank = (int) (tempA ^ tempB);
|
||||||
|
//System.out.println("decoded rank: " + Integer.toBinaryString(decodedRank));
|
||||||
|
|
||||||
|
tempA = physicalAddress;
|
||||||
|
physicalAddress = physicalAddress >>> bankBits;
|
||||||
|
tempB = physicalAddress << bankBits;
|
||||||
|
//System.out.println("Shifted address by " + bankBits + " bits");
|
||||||
|
decodedBank = (int) (tempA ^ tempB);
|
||||||
|
//System.out.println("decoded bank: " + Integer.toBinaryString(decodedBank));
|
||||||
|
|
||||||
|
tempA = physicalAddress;
|
||||||
|
physicalAddress = physicalAddress >>> colEffectiveBits;
|
||||||
|
tempB = physicalAddress << colEffectiveBits;
|
||||||
|
//System.out.println("Shifted address by " + colEffectiveBits + " bits");
|
||||||
|
decodedCol = (int) (tempA ^ tempB);
|
||||||
|
//System.out.println("decoded col: " + Integer.toBinaryString(decodedCol));
|
||||||
|
|
||||||
|
tempA = physicalAddress;
|
||||||
|
physicalAddress = physicalAddress >>> rowBits;
|
||||||
|
tempB = physicalAddress << rowBits;
|
||||||
|
decodedRow = (int) (tempA ^ tempB);
|
||||||
|
|
||||||
|
tempA = physicalAddress;
|
||||||
|
physicalAddress = physicalAddress >>> channelBits;
|
||||||
|
tempB = physicalAddress << channelBits;
|
||||||
|
decodedChan = (int) (tempA ^ tempB);
|
||||||
|
|
||||||
|
//TODO: channel not being taken into acount right now!!
|
||||||
|
|
||||||
|
//if num ranks = 1, decoded rank will always be "0"
|
||||||
|
|
||||||
|
MainMemoryBusPacket b = new MainMemoryBusPacket(decodedRow, decodedCol, decodedBank, decodedRank, address, null);
|
||||||
|
return b;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static int log2(int a)
|
||||||
|
{
|
||||||
|
return (int) (Math.log(a)/Math.log(2));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public BusPacketType requestTypeToBusPacketType(RequestType requestType)
|
||||||
|
{
|
||||||
|
switch(requestType)
|
||||||
|
{
|
||||||
|
case Cache_Read:
|
||||||
|
if(mainMemoryConfig.getRowBufferPolicy()==RowBufferPolicy.ClosePage)
|
||||||
|
{
|
||||||
|
return BusPacketType.READ_P;
|
||||||
|
}
|
||||||
|
else if(mainMemoryConfig.getRowBufferPolicy()==RowBufferPolicy.OpenPage)
|
||||||
|
{
|
||||||
|
return BusPacketType.READ;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Error.showErrorAndExit("Unkown row buffer policy");
|
||||||
|
return null; //needed to avoid compile error
|
||||||
|
}
|
||||||
|
//break; //not required because "unreachable" code
|
||||||
|
case Cache_Write:
|
||||||
|
if(mainMemoryConfig.getRowBufferPolicy()==RowBufferPolicy.ClosePage)
|
||||||
|
{
|
||||||
|
return BusPacketType.WRITE_P;
|
||||||
|
}
|
||||||
|
else if(mainMemoryConfig.getRowBufferPolicy()==RowBufferPolicy.OpenPage)
|
||||||
|
{
|
||||||
|
return BusPacketType.WRITE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Error.showErrorAndExit("Unkown row buffer policy");
|
||||||
|
return null; //needed to avoid compile error
|
||||||
|
}
|
||||||
|
//break;
|
||||||
|
default:
|
||||||
|
Error.showErrorAndExit("Request type "+ requestType + "does not have a corresponding bus packet type");
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void printBankStateTest()
|
||||||
|
{
|
||||||
|
Test.outputLog.print("== Printing bank states (According to MC) at Clock Cycle " + GlobalClock.getCurrentTime() + "\n");
|
||||||
|
for (int i=0; i < mainMemoryConfig.numRanks; i++)
|
||||||
|
{
|
||||||
|
for (int j=0; j < mainMemoryConfig.numBanks; j++)
|
||||||
|
{
|
||||||
|
if (bankStates[i][j].currentBankState == CurrentBankState.ROW_ACTIVE)
|
||||||
|
{
|
||||||
|
Test.outputLog.print("[" + bankStates[i][j].openRowAddress + "] ");
|
||||||
|
}
|
||||||
|
else if (bankStates[i][j].currentBankState == CurrentBankState.IDLE)
|
||||||
|
{
|
||||||
|
Test.outputLog.print("[idle] ");
|
||||||
|
}
|
||||||
|
else if (bankStates[i][j].currentBankState == CurrentBankState.PRECHARGING)
|
||||||
|
{
|
||||||
|
Test.outputLog.print("[pre] ");
|
||||||
|
}
|
||||||
|
else if (bankStates[i][j].currentBankState == CurrentBankState.REFRESHING)
|
||||||
|
{
|
||||||
|
Test.outputLog.print("[ref] ");
|
||||||
|
}
|
||||||
|
else if (bankStates[i][j].currentBankState == CurrentBankState.POWER_DOWN)
|
||||||
|
{
|
||||||
|
Test.outputLog.print("[lowp] ");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Test.outputLog.print("\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,50 @@
|
||||||
|
package dram;
|
||||||
|
|
||||||
|
import dram.MainMemoryBusPacket.BusPacketType;
|
||||||
|
import generic.EventQueue;
|
||||||
|
import generic.RequestType;
|
||||||
|
import generic.SimulationElement;
|
||||||
|
import main.Main;
|
||||||
|
import memorysystem.AddressCarryingEvent;
|
||||||
|
|
||||||
|
|
||||||
|
public class RamBusAddressCarryingEvent extends AddressCarryingEvent {
|
||||||
|
|
||||||
|
//public BusPacket busPacket; //encapsulate in request type
|
||||||
|
private MainMemoryBusPacket busPacket;
|
||||||
|
|
||||||
|
public RamBusAddressCarryingEvent(EventQueue eventQ, long eventTime,
|
||||||
|
SimulationElement requestingElement,
|
||||||
|
SimulationElement processingElement,
|
||||||
|
RequestType requestType, long address, MainMemoryBusPacket busPacket){
|
||||||
|
super(eventQ, eventTime, requestingElement, processingElement,
|
||||||
|
requestType, address);
|
||||||
|
this.setBusPacket(busPacket);
|
||||||
|
}
|
||||||
|
|
||||||
|
public RamBusAddressCarryingEvent(MainMemoryBusPacket busPacket)
|
||||||
|
{
|
||||||
|
super();
|
||||||
|
this.requestType = RequestType.Main_Mem_Access;
|
||||||
|
this.setBusPacket(busPacket);
|
||||||
|
}
|
||||||
|
|
||||||
|
public MainMemoryBusPacket getBusPacket() {
|
||||||
|
return busPacket;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setBusPacket(MainMemoryBusPacket busPacket) {
|
||||||
|
this.busPacket = busPacket;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void dump()
|
||||||
|
{
|
||||||
|
//System.out.println("CoreId: " + coreId + " RequestType : " + requestType + " RequestingElement : " + requestingElement + " ProcessingElement : " + processingElement + " EventTime : " + eventTime + " Address : " + address + " BusPacketType : " + busPacket.busPacketType + "\n" );
|
||||||
|
|
||||||
|
//write to debug file
|
||||||
|
|
||||||
|
//Main.debugPrinter.print("CoreId: " + coreId + " RequestType : " + requestType + " RequestingElement : " + requestingElement + " ProcessingElement : " + processingElement + " EventTime : " + eventTime + " Address : " + address + " BusPacketType : " + busPacket.busPacketType + "\n" );
|
||||||
|
//Test.debugPrinter.print("CoreId: " + coreId + " RequestType : " + requestType + " RequestingElement : " + requestingElement + " ProcessingElement : " + processingElement + " EventTime : " + eventTime + " Address : " + address + " BusPacketType : " + busPacket.busPacketType + "\n" );
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,319 @@
|
||||||
|
package dram;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
|
||||||
|
import config.MainMemoryConfig;
|
||||||
|
import dram.BankState.CurrentBankState;
|
||||||
|
import dram.MainMemoryBusPacket.BusPacketType;
|
||||||
|
import generic.Event;
|
||||||
|
import generic.EventQueue;
|
||||||
|
import generic.GlobalClock;
|
||||||
|
import generic.RequestType;
|
||||||
|
import generic.SimulationElement;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
|
||||||
|
import main.Main;
|
||||||
|
import misc.Error;
|
||||||
|
import config.MainMemoryConfig;
|
||||||
|
import dram.BankState.CurrentBankState;
|
||||||
|
|
||||||
|
public class Rank extends SimulationElement{
|
||||||
|
|
||||||
|
int id;
|
||||||
|
int incomingWriteBank;
|
||||||
|
int incomingWriteRow;
|
||||||
|
int incomingWriteColumn;
|
||||||
|
boolean isPowerDown;
|
||||||
|
|
||||||
|
|
||||||
|
MainMemoryBusPacket outgoingDataPacket;
|
||||||
|
//this can't be static as we can have multiple mem controllers having separate ram arrays
|
||||||
|
//static long busFreeTime ;
|
||||||
|
boolean refreshWaiting;
|
||||||
|
|
||||||
|
BankState bankStates[];
|
||||||
|
|
||||||
|
MainMemoryConfig mainMemoryConfig;
|
||||||
|
|
||||||
|
//parent memory controller
|
||||||
|
MainMemoryDRAMController parentMemContrlr;
|
||||||
|
|
||||||
|
Rank(MainMemoryConfig mainMemoryParameters, int id, MainMemoryDRAMController parentMemContrlr){
|
||||||
|
super(mainMemoryParameters.getRankPortType(), mainMemoryParameters.getRankNumPorts(), mainMemoryParameters.getRankOccupancy(), mainMemoryParameters.getRankLatency(), mainMemoryParameters.getRankOperatingFrequency());
|
||||||
|
//System.out.println("Constructing a rank!");
|
||||||
|
refreshWaiting=false;
|
||||||
|
bankStates = new BankState[mainMemoryParameters.numBanks];
|
||||||
|
|
||||||
|
for(int i=0; i < mainMemoryParameters.numBanks; i++)
|
||||||
|
{
|
||||||
|
bankStates[i] = new BankState();
|
||||||
|
}
|
||||||
|
|
||||||
|
this.mainMemoryConfig = mainMemoryParameters;
|
||||||
|
this.id = id;
|
||||||
|
this.parentMemContrlr = parentMemContrlr;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
int getId(){
|
||||||
|
return this.id;
|
||||||
|
}
|
||||||
|
|
||||||
|
void setId(int id){
|
||||||
|
this.id = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public void handleEvent(EventQueue eventQ, Event e) //basically a transaction of the receive from bus function
|
||||||
|
{
|
||||||
|
RamBusAddressCarryingEvent event = (RamBusAddressCarryingEvent) e;
|
||||||
|
//cast event to ram address carrying event
|
||||||
|
MainMemoryBusPacket b=event.getBusPacket().Clone();
|
||||||
|
//BusPacketType busPacketType = b.getBusPacketType();
|
||||||
|
//long addr = event.getAddress();
|
||||||
|
//RequestType requestType = event.getRequestType();
|
||||||
|
long currentTime = GlobalClock.getCurrentTime(); //Assumption: time will never change while handling an event
|
||||||
|
|
||||||
|
//System.out.println("Handling rank event scheduled for time " + event.getEventTime());
|
||||||
|
//b.printPacket();
|
||||||
|
//bankStates[b.bank].printState();
|
||||||
|
//System.out.println("Time:" + currentTime);
|
||||||
|
|
||||||
|
//Main.debugPrinter.print("\n\nHandling rank event.....\n");
|
||||||
|
//Main.debugPrinter.print("Received packet..\n");
|
||||||
|
//b.printPacketToFile();
|
||||||
|
//Main.debugPrinter.print("\n");
|
||||||
|
|
||||||
|
|
||||||
|
//for TEST
|
||||||
|
/*if(mainMemoryConfig.DEBUG_BUS)
|
||||||
|
{
|
||||||
|
if(e.getRequestType() != RequestType.Column_Read_Complete) //it's not an actual bus receive in this case
|
||||||
|
{
|
||||||
|
Test.outputLog.print(" -- R" + this.id + " Receiving On Bus at Clock Cycle "+ GlobalClock.getCurrentTime() +" : ");
|
||||||
|
b.printTest();
|
||||||
|
}
|
||||||
|
}*/
|
||||||
|
|
||||||
|
switch(b.busPacketType){
|
||||||
|
|
||||||
|
case READ:
|
||||||
|
//make sure read is allowed
|
||||||
|
if (bankStates[b.bank].currentBankState != CurrentBankState.ROW_ACTIVE || currentTime < bankStates[b.bank].nextRead || b.row != bankStates[b.bank].openRowAddress)
|
||||||
|
{
|
||||||
|
Error.showErrorAndExit("Received a read which is not allowed");
|
||||||
|
}
|
||||||
|
|
||||||
|
//update state table
|
||||||
|
bankStates[b.bank].nextPrecharge = Math.max(bankStates[b.bank].nextPrecharge, currentTime + mainMemoryConfig.ReadToPreDelay);
|
||||||
|
|
||||||
|
|
||||||
|
for (BankState bs : bankStates)
|
||||||
|
{
|
||||||
|
bs.nextRead = Math.max(bs.nextRead, currentTime + Math.max(mainMemoryConfig.tCCD, mainMemoryConfig.tBL/2));
|
||||||
|
bs.nextWrite=Math.max(bs.nextWrite,currentTime + mainMemoryConfig.ReadToWriteDelay);
|
||||||
|
}
|
||||||
|
|
||||||
|
b.setBusPacketType(BusPacketType.DATA);
|
||||||
|
event.addEventTime(mainMemoryConfig.tRL);
|
||||||
|
event.setRequestType(RequestType.Column_Read_Complete);
|
||||||
|
event.setBusPacket(b);
|
||||||
|
//don't use sendEvent as it routes through the "port" will add latency
|
||||||
|
event.incrementSerializationID();
|
||||||
|
event.getEventQ().addEvent(event);
|
||||||
|
//don't update processing and requesting elements as we want the event to come back to rank
|
||||||
|
break;
|
||||||
|
|
||||||
|
case READ_P:
|
||||||
|
if (bankStates[b.bank].currentBankState != CurrentBankState.ROW_ACTIVE ||
|
||||||
|
currentTime < bankStates[b.bank].nextRead ||
|
||||||
|
b.row != bankStates[b.bank].openRowAddress)
|
||||||
|
{
|
||||||
|
Error.showErrorAndExit("Received a read which is not allowed");
|
||||||
|
}
|
||||||
|
|
||||||
|
bankStates[b.bank].currentBankState = CurrentBankState.IDLE;
|
||||||
|
bankStates[b.bank].nextActivate = Math.max(bankStates[b.bank].nextActivate, currentTime + mainMemoryConfig.ReadAutopreDelay);
|
||||||
|
|
||||||
|
for (BankState bs : bankStates)
|
||||||
|
{
|
||||||
|
bs.nextRead = Math.max(bs.nextRead, currentTime + Math.max(mainMemoryConfig.tCCD, mainMemoryConfig.tBL/2));
|
||||||
|
bs.nextWrite = Math.max(bs.nextWrite, currentTime + mainMemoryConfig.ReadToWriteDelay);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
b.setBusPacketType(BusPacketType.DATA);
|
||||||
|
event.addEventTime(mainMemoryConfig.tRL);
|
||||||
|
event.setRequestType(RequestType.Column_Read_Complete);
|
||||||
|
|
||||||
|
event.setBusPacket(b);
|
||||||
|
//Main.debugPrinter.print("time to get data event: "+event.getEventTime());
|
||||||
|
|
||||||
|
event.incrementSerializationID();
|
||||||
|
event.getEventQ().addEvent(event);
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
|
||||||
|
case WRITE:
|
||||||
|
|
||||||
|
if (bankStates[b.bank].currentBankState != CurrentBankState.ROW_ACTIVE ||
|
||||||
|
currentTime < bankStates[b.bank].nextWrite ||
|
||||||
|
b.row != bankStates[b.bank].openRowAddress)
|
||||||
|
{
|
||||||
|
Error.showErrorAndExit("== Error - Rank " +id + " received a WRITE when not allowed");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
//update state table
|
||||||
|
bankStates[b.bank].nextPrecharge = Math.max(bankStates[b.bank].nextPrecharge, currentTime + mainMemoryConfig.WriteToPreDelay);
|
||||||
|
for (BankState bs:bankStates)
|
||||||
|
{
|
||||||
|
bs.nextRead = Math.max(bs.nextRead, currentTime + mainMemoryConfig.WriteToReadDelayB);
|
||||||
|
bs.nextWrite = Math.max(bs.nextWrite, currentTime + Math.max(mainMemoryConfig.tBL/2, mainMemoryConfig.tCCD));
|
||||||
|
}
|
||||||
|
|
||||||
|
//take note of where data is going when it arrives
|
||||||
|
incomingWriteBank = b.bank;
|
||||||
|
incomingWriteRow = b.row;
|
||||||
|
incomingWriteColumn = b.column;
|
||||||
|
b=null;
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
case WRITE_P:
|
||||||
|
|
||||||
|
if (bankStates[b.bank].currentBankState != CurrentBankState.ROW_ACTIVE ||
|
||||||
|
currentTime < bankStates[b.bank].nextWrite ||
|
||||||
|
b.row != bankStates[b.bank].openRowAddress)
|
||||||
|
{
|
||||||
|
Error.showErrorAndExit("== Error - Rank " + id + " received a WRITE_P when not allowed");
|
||||||
|
|
||||||
|
}
|
||||||
|
//update state table
|
||||||
|
bankStates[b.bank].currentBankState = CurrentBankState.IDLE;
|
||||||
|
bankStates[b.bank].nextActivate = Math.max(bankStates[b.bank].nextActivate, currentTime + mainMemoryConfig.WriteAutopreDelay);
|
||||||
|
for (BankState bs : bankStates)
|
||||||
|
{
|
||||||
|
bs.nextWrite = Math.max(bs.nextWrite, currentTime + Math.max(mainMemoryConfig.tCCD, mainMemoryConfig.tBL/2));
|
||||||
|
bs.nextRead = Math.max(bs.nextRead, currentTime + mainMemoryConfig.WriteToReadDelayB);
|
||||||
|
}
|
||||||
|
|
||||||
|
//take note of where data is going when it arrives
|
||||||
|
incomingWriteBank = b.bank;
|
||||||
|
incomingWriteRow = b.row;
|
||||||
|
incomingWriteColumn = b.column;
|
||||||
|
b=null;
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ACTIVATE:
|
||||||
|
//make sure activate is allowed
|
||||||
|
|
||||||
|
if (bankStates[b.bank].currentBankState != CurrentBankState.IDLE ||
|
||||||
|
currentTime < bankStates[b.bank].nextActivate)
|
||||||
|
{
|
||||||
|
Error.showErrorAndExit("== Error - Rank " + id + " received an ACT when not allowed");
|
||||||
|
}
|
||||||
|
|
||||||
|
bankStates[b.bank].currentBankState = CurrentBankState.ROW_ACTIVE;
|
||||||
|
bankStates[b.bank].nextActivate = currentTime + mainMemoryConfig.tRC;
|
||||||
|
bankStates[b.bank].openRowAddress = b.row;
|
||||||
|
|
||||||
|
//if AL is greater than one, then posted-cas is enabled - handle accordingly
|
||||||
|
if (mainMemoryConfig.tAL>0)
|
||||||
|
{
|
||||||
|
bankStates[b.bank].nextWrite = currentTime + (mainMemoryConfig.tRCD-mainMemoryConfig.tAL);
|
||||||
|
bankStates[b.bank].nextRead = currentTime + (mainMemoryConfig.tRCD-mainMemoryConfig.tAL);}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
bankStates[b.bank].nextWrite = currentTime + (mainMemoryConfig.tRCD-mainMemoryConfig.tAL);
|
||||||
|
bankStates[b.bank].nextRead = currentTime + (mainMemoryConfig.tRCD-mainMemoryConfig.tAL);
|
||||||
|
}
|
||||||
|
|
||||||
|
bankStates[b.bank].nextPrecharge = currentTime + mainMemoryConfig.tRAS;
|
||||||
|
for (int i=0;i<mainMemoryConfig.numBanks;i++)
|
||||||
|
{
|
||||||
|
if (i != b.bank)
|
||||||
|
{
|
||||||
|
bankStates[i].nextActivate = Math.max(bankStates[i].nextActivate, currentTime + mainMemoryConfig.tRRD);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
b=null;
|
||||||
|
|
||||||
|
break;
|
||||||
|
case PRECHARGE:
|
||||||
|
//make sure precharge is allowed
|
||||||
|
if (bankStates[b.bank].currentBankState != CurrentBankState.ROW_ACTIVE ||
|
||||||
|
currentTime < bankStates[b.bank].nextPrecharge)
|
||||||
|
{
|
||||||
|
//System.out.println("time of next precharge: " + bankStates[b.bank].nextPrecharge);
|
||||||
|
Error.showErrorAndExit("== Error - Rank " + id + " received a PRE when not allowed");
|
||||||
|
}
|
||||||
|
|
||||||
|
bankStates[b.bank].currentBankState = CurrentBankState.IDLE;
|
||||||
|
bankStates[b.bank].nextActivate = Math.max(bankStates[b.bank].nextActivate, currentTime + mainMemoryConfig.tRP);
|
||||||
|
b=null;
|
||||||
|
|
||||||
|
break;
|
||||||
|
case REFRESH:
|
||||||
|
refreshWaiting = false;
|
||||||
|
for (int i=0;i<mainMemoryConfig.numBanks;i++)
|
||||||
|
{
|
||||||
|
if (bankStates[i].currentBankState != CurrentBankState.IDLE){
|
||||||
|
Error.showErrorAndExit("== Error - Rank " + id + " received a REF when not allowed");
|
||||||
|
|
||||||
|
}
|
||||||
|
bankStates[i].nextActivate = currentTime + mainMemoryConfig.tRFC;
|
||||||
|
}
|
||||||
|
b=null;
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
case DATA:
|
||||||
|
|
||||||
|
if(event.getRequestType()==RequestType.Column_Read_Complete){
|
||||||
|
|
||||||
|
long busFreeTime = parentMemContrlr.getBusFreeTime();
|
||||||
|
if(currentTime >= busFreeTime){
|
||||||
|
parentMemContrlr.setBusFreeTime(currentTime+mainMemoryConfig.tBL/2);
|
||||||
|
event.addEventTime(mainMemoryConfig.tBL/2);
|
||||||
|
|
||||||
|
//change the requesting and the processing elements
|
||||||
|
event.setRequestType(RequestType.Rank_Response);
|
||||||
|
// event.setRequestingElement(event.getProcessingElement());
|
||||||
|
event.setProcessingElement(event.getRequestingElement());
|
||||||
|
event.incrementSerializationID();
|
||||||
|
event.getEventQ().addEvent(event);
|
||||||
|
|
||||||
|
//for TEST
|
||||||
|
/*if(mainMemoryConfig.DEBUG_BUS)
|
||||||
|
{
|
||||||
|
Test.outputLog.print(" -- R" + this.id + " Issuing On Data Bus at Clock Cycle " + GlobalClock.getCurrentTime() + " : ");
|
||||||
|
event.getBusPacket().printTest();
|
||||||
|
Test.outputLog.print("\n");
|
||||||
|
}*/
|
||||||
|
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
//simply moving the event forward in the event queue
|
||||||
|
event.addEventTime(busFreeTime-currentTime);
|
||||||
|
event.incrementSerializationID();
|
||||||
|
event.getEventQ().addEvent(event);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
else{
|
||||||
|
//it is a write
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
Error.showErrorAndExit("Invalid bus packet type received by rank");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,58 @@
|
||||||
|
package dram;
|
||||||
|
|
||||||
|
import main.Main;
|
||||||
|
import generic.EventQueue;
|
||||||
|
import generic.RequestType;
|
||||||
|
import generic.SimulationElement;
|
||||||
|
import generic.Event;
|
||||||
|
|
||||||
|
public class StateUpdateEvent extends Event {
|
||||||
|
|
||||||
|
private int rank;
|
||||||
|
private int bank;
|
||||||
|
|
||||||
|
public StateUpdateEvent(EventQueue eventQ, long eventTime,
|
||||||
|
SimulationElement requestingElement,
|
||||||
|
SimulationElement processingElement,
|
||||||
|
RequestType requestType, int rank, int bank) {
|
||||||
|
super(eventQ, eventTime, requestingElement, processingElement,
|
||||||
|
requestType, -1);
|
||||||
|
this.setRank(rank);
|
||||||
|
this.setBank(bank);
|
||||||
|
}
|
||||||
|
|
||||||
|
public StateUpdateEvent updateEvent(EventQueue eventQ, long eventTime,
|
||||||
|
SimulationElement requestingElement,
|
||||||
|
SimulationElement processingElement,
|
||||||
|
RequestType requestType, int rank, int bank) {
|
||||||
|
this.setRank(rank);
|
||||||
|
this.setBank(bank);
|
||||||
|
return (StateUpdateEvent)this.update(eventQ, eventTime, requestingElement, processingElement, requestType);
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getRank() {
|
||||||
|
return rank;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setRank(int rank) {
|
||||||
|
this.rank = rank;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getBank() {
|
||||||
|
return bank;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setBank(int bank) {
|
||||||
|
this.bank = bank;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public void dump()
|
||||||
|
{
|
||||||
|
//write to debug file
|
||||||
|
|
||||||
|
//Main.debugPrinter.print("CoreId: " + coreId + " RequestType : " + requestType + " RequestingElement : " + requestingElement + " ProcessingElement : " + processingElement + " EventTime : " + eventTime + " Rank : " + rank + " Bank : " + bank + "\n" );
|
||||||
|
//Test.debugPrinter.print("CoreId: " + coreId + " RequestType : " + requestType + " RequestingElement : " + requestingElement + " ProcessingElement : " + processingElement + " EventTime : " + eventTime + " Rank : " + rank + " Bank : " + bank + "\n" );
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,212 @@
|
||||||
|
package dram;
|
||||||
|
|
||||||
|
import generic.EventQueue;
|
||||||
|
import generic.GlobalClock;
|
||||||
|
import generic.RequestType;
|
||||||
|
|
||||||
|
import java.io.BufferedReader;
|
||||||
|
import java.io.FileNotFoundException;
|
||||||
|
import java.io.FileReader;
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
import memorysystem.Cache;
|
||||||
|
import memorysystem.AddressCarryingEvent;
|
||||||
|
import config.MainMemoryConfig;
|
||||||
|
import config.SystemConfig;
|
||||||
|
import config.XMLParser;
|
||||||
|
import misc.Error;
|
||||||
|
|
||||||
|
public class Test {
|
||||||
|
|
||||||
|
FileReader traceInput;
|
||||||
|
BufferedReader bufRead;
|
||||||
|
String readLine = null;
|
||||||
|
public static long numClockCycles = 75200; //number of clock cycles to run
|
||||||
|
long lastTime = 0;
|
||||||
|
long lastLineNumber = 0;
|
||||||
|
|
||||||
|
EventQueue eventQ;
|
||||||
|
MainMemoryConfig mainMemoryConfig;
|
||||||
|
MainMemoryDRAMControllerTest mainMemoryDRAMControllerTest;
|
||||||
|
Cache dummyParentCache = null;
|
||||||
|
AddressCarryingEvent pendingEvent;
|
||||||
|
|
||||||
|
public static DebugPrinter debugPrinter;
|
||||||
|
public static DebugPrinter outputLog;
|
||||||
|
public static DebugPrinter timingLog;
|
||||||
|
|
||||||
|
public Test() throws FileNotFoundException
|
||||||
|
{
|
||||||
|
|
||||||
|
this.mainMemoryConfig = SystemConfig.mainMemoryConfig;
|
||||||
|
mainMemoryDRAMControllerTest = new MainMemoryDRAMControllerTest(mainMemoryConfig, this);
|
||||||
|
eventQ = new EventQueue();
|
||||||
|
|
||||||
|
traceInput = new FileReader("/home/hk/Harveen/Work/DRAMSim/repo/Tejas-dram-sim/Tejas-dram/src/simulator/dram/k6_aoe_02_short.trc.uniq");
|
||||||
|
bufRead = new BufferedReader(traceInput);
|
||||||
|
|
||||||
|
GlobalClock.setCurrentTime(0);
|
||||||
|
GlobalClock.setStepSize(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void main(String[] args) throws IOException{
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
//Rank r1 = new Rank();
|
||||||
|
|
||||||
|
//System.out.println("Hi!Creating a Test");
|
||||||
|
|
||||||
|
XMLParser.parse("/home/hk/Harveen/Work/DRAMSim/repo/Tejas-dram-sim/Tejas-dram/src/simulator/config/config.xml");
|
||||||
|
|
||||||
|
//open debug file
|
||||||
|
debugPrinter = new DebugPrinter("event_log");
|
||||||
|
|
||||||
|
//outputLog = new DebugPrinter("output_log_BUS");
|
||||||
|
//outputLog = new DebugPrinter("output_log_BANKSTATE");
|
||||||
|
outputLog = new DebugPrinter("output_log_CMDQ");
|
||||||
|
|
||||||
|
timingLog = new DebugPrinter("timing_log");
|
||||||
|
|
||||||
|
|
||||||
|
Test test = new Test();
|
||||||
|
|
||||||
|
for(int i = 0; i < Test.numClockCycles; i++)
|
||||||
|
{
|
||||||
|
if(GlobalClock.getCurrentTime() == test.lastTime)
|
||||||
|
{
|
||||||
|
//System.out.println("Gonna add new events!! At time " + GlobalClock.getCurrentTime());
|
||||||
|
//if(!test.parseAndAddEvents()) //whenever going to run out of events, add new (upto 1024 clk cycles ahead)
|
||||||
|
//break;
|
||||||
|
|
||||||
|
test.parseAndAddEvents();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
test.mainMemoryDRAMControllerTest.oneCycleOperation(); //reverse the order because that is so in C code
|
||||||
|
|
||||||
|
test.eventQ.processEvents(); //process then one cycle as in the real Main
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//need to add code for refresh events
|
||||||
|
|
||||||
|
//print debug for each cycle
|
||||||
|
if(test.mainMemoryConfig.DEBUG_CMDQ && GlobalClock.getCurrentTime() >= 70758)
|
||||||
|
// test.mainMemoryDRAMControllerTest.commandQueue.printTest();
|
||||||
|
if(test.mainMemoryConfig.DEBUG_BANKSTATE)
|
||||||
|
test.mainMemoryDRAMControllerTest.printBankStateTest();
|
||||||
|
|
||||||
|
|
||||||
|
GlobalClock.incrementClock();
|
||||||
|
//System.out.println("Running for time " + GlobalClock.getCurrentTime());
|
||||||
|
//System.out.println("Last time was: " + test.lastTime);
|
||||||
|
}
|
||||||
|
//Note: Technically this code is not correct as it issues multiple requests for addresses that would be covered in a single burst
|
||||||
|
//and hence it is meaningless to service those addresses again and again. Ideally it should go to a cache
|
||||||
|
//But this is how DRAMSim2 does it, so for verification purposes, let us stick to this
|
||||||
|
//System.out.println("Simulation Complete!!");
|
||||||
|
debugPrinter.close();
|
||||||
|
outputLog.close();
|
||||||
|
timingLog.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean parseAndAddEvents() throws IOException
|
||||||
|
{
|
||||||
|
String currentLine;
|
||||||
|
long currentLineNumber = this.lastLineNumber;
|
||||||
|
long addEventsUptoTime = GlobalClock.getCurrentTime() + 1024;
|
||||||
|
|
||||||
|
long currentLineTime = 0;
|
||||||
|
long address;
|
||||||
|
|
||||||
|
//System.out.println("Adding events upto time " + addEventsUptoTime);
|
||||||
|
|
||||||
|
//then start processing further lines
|
||||||
|
while(true)
|
||||||
|
{
|
||||||
|
if((currentLine = bufRead.readLine()) != null)
|
||||||
|
{
|
||||||
|
|
||||||
|
//Format : Address Command ClockCycle
|
||||||
|
|
||||||
|
String[] parsedStrings = currentLine.split(" ");
|
||||||
|
currentLineTime = Long.parseLong(parsedStrings[2]);
|
||||||
|
|
||||||
|
RequestType reqType = null;
|
||||||
|
if(parsedStrings[1].equals("P_MEM_WR") || parsedStrings[1].equals("BOFF"))
|
||||||
|
{
|
||||||
|
reqType = RequestType.Cache_Write;
|
||||||
|
}
|
||||||
|
else if (parsedStrings[1].equals("P_FETCH") ||
|
||||||
|
parsedStrings[1].equals("P_MEM_RD") ||
|
||||||
|
parsedStrings[1].equals("P_LOCK_RD") ||
|
||||||
|
parsedStrings[1].equals("P_LOCK_WR")
|
||||||
|
)
|
||||||
|
{
|
||||||
|
reqType = RequestType.Cache_Read;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
Error.showErrorAndExit("== Unkown Command : " + parsedStrings[1]);
|
||||||
|
|
||||||
|
address = Long.parseLong(parsedStrings[0].substring(2),16);
|
||||||
|
|
||||||
|
|
||||||
|
//throw away lower size bits to account for burst size
|
||||||
|
address >>>= 6;
|
||||||
|
address <<= 6;
|
||||||
|
|
||||||
|
|
||||||
|
if(currentLineTime < addEventsUptoTime)
|
||||||
|
{
|
||||||
|
|
||||||
|
//check if any pending events from before
|
||||||
|
if(pendingEvent != null)
|
||||||
|
{
|
||||||
|
//System.out.println("Added pending event");
|
||||||
|
pendingEvent.print();
|
||||||
|
this.eventQ.addEvent(pendingEvent);
|
||||||
|
pendingEvent = null;
|
||||||
|
|
||||||
|
}
|
||||||
|
//create and add event to queue
|
||||||
|
AddressCarryingEvent e = new AddressCarryingEvent(this.eventQ, currentLineTime, dummyParentCache, this.mainMemoryDRAMControllerTest, reqType, address);
|
||||||
|
this.eventQ.addEvent(e);
|
||||||
|
|
||||||
|
//System.out.println(address + " " + parsedStrings[1] + " " + parsedStrings[2]);
|
||||||
|
|
||||||
|
this.lastTime = currentLineTime;
|
||||||
|
this.lastLineNumber = currentLineNumber;
|
||||||
|
currentLineNumber++;
|
||||||
|
|
||||||
|
//System.out.println("Setting last time to " + this.lastTime);
|
||||||
|
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
//System.out.println("Pending event to add");
|
||||||
|
//System.out.println(address + " " + parsedStrings[1] + " " + parsedStrings[2]);
|
||||||
|
pendingEvent = new AddressCarryingEvent(this.eventQ, currentLineTime, dummyParentCache, this.mainMemoryDRAMControllerTest, reqType, address);
|
||||||
|
|
||||||
|
this.lastTime = currentLineTime; //run next when it's time to add the pending event!
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
//System.out.println("Reached end of file!");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
//while(currentLineTime < addEventsUptoTime );
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public EventQueue getEventQueue()
|
||||||
|
{
|
||||||
|
return this.eventQ;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,18 @@
|
||||||
|
0x018ADB20 P_MEM_WR 0
|
||||||
|
0x01A5DB58 P_FETCH 5
|
||||||
|
0x0196CF98 P_FETCH 31
|
||||||
|
0x014957D8 P_FETCH 51
|
||||||
|
0x0196CFB8 P_FETCH 85
|
||||||
|
0x01BFF258 P_FETCH 110
|
||||||
|
0x06332178 P_FETCH 130
|
||||||
|
0x01495818 P_FETCH 174
|
||||||
|
0x01EE0E90 P_MEM_RD 190
|
||||||
|
0x063321F8 P_FETCH 211
|
||||||
|
0x01495798 P_FETCH 231
|
||||||
|
0x063321D8 P_FETCH 261
|
||||||
|
0x01BFF438 P_FETCH 301
|
||||||
|
0x01410A98 P_FETCH 564
|
||||||
|
0x01410A90 P_FETCH 565
|
||||||
|
0x01410A88 P_FETCH 566
|
||||||
|
0x07EA7B2C P_LOCK_RD 645
|
||||||
|
0x01410AD8 P_FETCH 1827
|
|
@ -0,0 +1,193 @@
|
||||||
|
/*****************************************************************************
|
||||||
|
BhartiSim Simulator
|
||||||
|
------------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
Copyright [2010] [Indian Institute of Technology, Delhi]
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
------------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
Contributors: Prathmesh Kallurkar, Abhishek Sagar
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
package emulatorinterface;
|
||||||
|
|
||||||
|
import java.nio.ByteBuffer;
|
||||||
|
|
||||||
|
import config.CommunicationType;
|
||||||
|
import config.EmulatorConfig;
|
||||||
|
import config.EmulatorType;
|
||||||
|
import emulatorinterface.communication.Encoding;
|
||||||
|
import emulatorinterface.communication.Packet;
|
||||||
|
import emulatorinterface.translator.x86.objparser.ObjParser;
|
||||||
|
|
||||||
|
public class DynamicInstructionBuffer implements Encoding
|
||||||
|
{
|
||||||
|
private long memRead[];
|
||||||
|
int memReadSize, memReadCount;
|
||||||
|
|
||||||
|
private long memWrite[];
|
||||||
|
int memWriteSize, memWriteCount;
|
||||||
|
|
||||||
|
private boolean branchInformationRead;
|
||||||
|
private boolean branchTaken;
|
||||||
|
private long branchAddress;
|
||||||
|
|
||||||
|
private long ip;
|
||||||
|
|
||||||
|
public DynamicInstructionBuffer()
|
||||||
|
{
|
||||||
|
memRead = new long[64];
|
||||||
|
memWrite = new long[64];
|
||||||
|
}
|
||||||
|
|
||||||
|
// read the packets from the arrayList and place them in suitable queues
|
||||||
|
public void configurePackets(EmulatorPacketList arrayListPacket)
|
||||||
|
{
|
||||||
|
branchInformationRead = false;
|
||||||
|
memReadCount = 0; memReadSize = 0;
|
||||||
|
memWriteCount = 0; memWriteSize = 0;
|
||||||
|
|
||||||
|
branchAddress = -1;
|
||||||
|
|
||||||
|
ip = arrayListPacket.get(0).ip;
|
||||||
|
|
||||||
|
int numAssemblyPackets = 0;
|
||||||
|
|
||||||
|
for (int i = 0; i < arrayListPacket.size(); i++)
|
||||||
|
{
|
||||||
|
Packet p = arrayListPacket.get(i);
|
||||||
|
assert (ip == p.ip) : "all instruction pointers not matching";
|
||||||
|
|
||||||
|
// System.out.println(i + " : " + p);
|
||||||
|
|
||||||
|
switch ((int)p.value)
|
||||||
|
{
|
||||||
|
case (-1):
|
||||||
|
break;
|
||||||
|
|
||||||
|
case (0):
|
||||||
|
misc.Error.showErrorAndExit("error in configuring packet : " + p );
|
||||||
|
break;
|
||||||
|
|
||||||
|
case (1):
|
||||||
|
misc.Error.showErrorAndExit("error in configuring packet : " + p);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case (MEMREAD):
|
||||||
|
memRead[memReadSize++] = p.tgt;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case (MEMWRITE):
|
||||||
|
memWrite[memWriteSize++] = p.tgt;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case (TAKEN):
|
||||||
|
branchTaken = true;
|
||||||
|
branchAddress = p.tgt;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case (NOTTAKEN):
|
||||||
|
branchTaken = false;
|
||||||
|
branchAddress = p.tgt;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case (ASSEMBLY):
|
||||||
|
numAssemblyPackets++;
|
||||||
|
|
||||||
|
default:
|
||||||
|
// System.out.println("error in configuring packets"+p.value);
|
||||||
|
// misc.Error.showErrorAndExit("error in configuring packets"+p.value);
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(EmulatorConfig.communicationType==CommunicationType.file) {
|
||||||
|
assert(numAssemblyPackets==1) : "Invalid number of assembly packets : " + numAssemblyPackets;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean getBranchTaken(long instructionPointer)
|
||||||
|
{
|
||||||
|
branchInformationRead = true;
|
||||||
|
return branchTaken;
|
||||||
|
}
|
||||||
|
|
||||||
|
public long getBranchAddress(long instructionPointer)
|
||||||
|
{
|
||||||
|
branchInformationRead = true;
|
||||||
|
return branchAddress;
|
||||||
|
}
|
||||||
|
|
||||||
|
public long getSingleLoadAddress(long instructionPointer)
|
||||||
|
{
|
||||||
|
long ret = -1;
|
||||||
|
|
||||||
|
if(memReadCount<memReadSize) {
|
||||||
|
ret = memRead[memReadCount++];
|
||||||
|
} else {
|
||||||
|
// System.err.println("expected load address : " +
|
||||||
|
// "ip = " + Long.toHexString(ip).toLowerCase()+
|
||||||
|
// "\tinstructionP = " + Long.toHexString(instructionPointer).toLowerCase() + " !!");
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public long getSingleStoreAddress(long instructionPointer)
|
||||||
|
{
|
||||||
|
long ret = -1;
|
||||||
|
|
||||||
|
if(memWriteCount<memWriteSize) {
|
||||||
|
ret = memWrite[memWriteCount++];
|
||||||
|
} else {
|
||||||
|
// System.err.println("expected store address : " +
|
||||||
|
// "ip = " + Long.toHexString(ip).toLowerCase()+
|
||||||
|
// "\tinstructionP = " + Long.toHexString(instructionPointer).toLowerCase() + " !!");
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void printBuffer()
|
||||||
|
{
|
||||||
|
//TODO
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getMemReadCount()
|
||||||
|
{
|
||||||
|
return memReadCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getMemWriteCount()
|
||||||
|
{
|
||||||
|
return memWriteCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getMemReadSize() {
|
||||||
|
return memReadSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getMemWriteSize() {
|
||||||
|
return memWriteSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean missedInformation() {
|
||||||
|
return (memReadCount<memReadSize || memWriteCount<memWriteSize || isBranchInformationReadNeeded());
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isBranchInformationReadNeeded() {
|
||||||
|
boolean readAuthenticBranch = branchInformationRead==false && branchAddress!=-1;
|
||||||
|
return readAuthenticBranch;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,51 @@
|
||||||
|
package emulatorinterface;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
|
||||||
|
import emulatorinterface.communication.Packet;
|
||||||
|
|
||||||
|
public class EmulatorPacketList {
|
||||||
|
|
||||||
|
ArrayList<Packet> packetList;
|
||||||
|
int size = 0;
|
||||||
|
final int listSize = 5; // load + store + branch + assembly + control-flow(thread)
|
||||||
|
|
||||||
|
public EmulatorPacketList() {
|
||||||
|
super();
|
||||||
|
this.packetList = new ArrayList<Packet>();
|
||||||
|
|
||||||
|
for(int i=0; i<listSize; i++) {
|
||||||
|
packetList.add(new Packet());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void add(Packet p) {
|
||||||
|
if(size==packetList.size()) {
|
||||||
|
// System.out.println("IP = " + p.ip + " Type = " +p.value);
|
||||||
|
// misc.Error.showErrorAndExit("packetList : trying to push more packets for fuse function" +
|
||||||
|
// "current size = " + size);
|
||||||
|
//System.out.println("packetList : trying to push more packets for fuse function" +
|
||||||
|
// "current size = " + size);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this.packetList.get(size).set(p);
|
||||||
|
size++;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void clear() {
|
||||||
|
size = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Packet get(int index) {
|
||||||
|
if(index>size) {
|
||||||
|
misc.Error.showErrorAndExit("trying to access element outside packetList size" +
|
||||||
|
"size = " + size + "\tindex = " + index);
|
||||||
|
}
|
||||||
|
|
||||||
|
return packetList.get(index);
|
||||||
|
}
|
||||||
|
|
||||||
|
public int size() {
|
||||||
|
return size;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,28 @@
|
||||||
|
package emulatorinterface;
|
||||||
|
|
||||||
|
import generic.GenericCircularQueue;
|
||||||
|
import generic.Instruction;
|
||||||
|
|
||||||
|
public class EmulatorThreadState {
|
||||||
|
|
||||||
|
boolean finished;
|
||||||
|
public boolean started = false;
|
||||||
|
boolean halted = false;
|
||||||
|
boolean isFirstPacket = true;
|
||||||
|
boolean fetchStatus = false; //true when #{packets} fetched by T_java (for T_app) > threshold else false
|
||||||
|
//int readerLocation;
|
||||||
|
long totalRead;
|
||||||
|
|
||||||
|
// We are assuming that one assembly instruction can have atmost 50 micro-operations.
|
||||||
|
// Its an over-estimation.
|
||||||
|
GenericCircularQueue<Instruction> outstandingMicroOps = new GenericCircularQueue<Instruction>(Instruction.class, 50);
|
||||||
|
|
||||||
|
// Packet pold = new Packet();
|
||||||
|
EmulatorPacketList packetList = new EmulatorPacketList();
|
||||||
|
|
||||||
|
public void checkStarted() {
|
||||||
|
if (this.isFirstPacket) {
|
||||||
|
this.started = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,243 @@
|
||||||
|
package emulatorinterface;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Hashtable;
|
||||||
|
import java.util.Iterator;
|
||||||
|
import java.util.LinkedList;
|
||||||
|
|
||||||
|
import memorysystem.AddressCarryingEvent;
|
||||||
|
|
||||||
|
|
||||||
|
import emulatorinterface.communication.Encoding;
|
||||||
|
import emulatorinterface.communication.IpcBase;
|
||||||
|
import emulatorinterface.communication.Packet;
|
||||||
|
import generic.Barrier;
|
||||||
|
import generic.BarrierTable;
|
||||||
|
import generic.CoreBcastBus;
|
||||||
|
import generic.RequestType;
|
||||||
|
|
||||||
|
class ResumeSleep {
|
||||||
|
ArrayList<Integer> resume=new ArrayList<Integer>();
|
||||||
|
ArrayList<Integer> sleep=new ArrayList<Integer>();
|
||||||
|
|
||||||
|
long barrierAddress;
|
||||||
|
|
||||||
|
void addSleeper(int t){
|
||||||
|
this.sleep.add(t);
|
||||||
|
}
|
||||||
|
|
||||||
|
void addResumer(int t){
|
||||||
|
this.resume.add(t);
|
||||||
|
}
|
||||||
|
|
||||||
|
int getNumResumers() {
|
||||||
|
return this.resume.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
int getNumSleepers() {
|
||||||
|
return this.sleep.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void merge(ResumeSleep other) {
|
||||||
|
for (int res : other.resume) {
|
||||||
|
this.addResumer(res);
|
||||||
|
}
|
||||||
|
for (int slp : other.sleep) {
|
||||||
|
this.addSleeper(slp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public void setBarrierAddress(long add){
|
||||||
|
this.barrierAddress = add;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public final class GlobalTable implements Encoding {
|
||||||
|
|
||||||
|
private Hashtable<Long, SynchPrimitive> synchTable;
|
||||||
|
private Hashtable<Integer, ThreadState> stateTable;
|
||||||
|
private IpcBase ipcType;
|
||||||
|
public GlobalTable(IpcBase ipcType) {
|
||||||
|
this.ipcType = ipcType;
|
||||||
|
this.synchTable = new Hashtable<Long, SynchPrimitive>();
|
||||||
|
this.stateTable = new Hashtable<Integer, ThreadState>();
|
||||||
|
// this.coreBcastBus = coreBcastBus;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Hashtable<Long, SynchPrimitive> getSynchTable() {
|
||||||
|
return synchTable;
|
||||||
|
}
|
||||||
|
public Hashtable<Integer, ThreadState> getStateTable() {
|
||||||
|
return stateTable;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setStateTable(Hashtable<Integer, ThreadState> stateTable) {
|
||||||
|
this.stateTable = stateTable;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// returns -2 if no thread needs to be slept/resumed.
|
||||||
|
// returns -1 if 'this' thread needs to sleep
|
||||||
|
// o/w returns otherThreadsId which will now resume
|
||||||
|
@SuppressWarnings("unused")
|
||||||
|
public ResumeSleep update(long addressSynchItem, int thread, long time,
|
||||||
|
long value) {
|
||||||
|
|
||||||
|
|
||||||
|
SynchPrimitive s;
|
||||||
|
if (synchTable.containsKey(addressSynchItem))
|
||||||
|
s = (SynchPrimitive)synchTable.get(addressSynchItem);
|
||||||
|
else {
|
||||||
|
s = new SynchPrimitive(
|
||||||
|
addressSynchItem, thread, time, value, ipcType);
|
||||||
|
synchTable.put(addressSynchItem, s);
|
||||||
|
}
|
||||||
|
|
||||||
|
ResumeSleep ret = new ResumeSleep();
|
||||||
|
switch ((int)value) {
|
||||||
|
case (BCAST):
|
||||||
|
// ret = s.broadcastEnter(thread,time,value);
|
||||||
|
break;
|
||||||
|
case (SIGNAL):
|
||||||
|
// ret = s.sigEnter(thread, time, value);
|
||||||
|
break;
|
||||||
|
case (LOCK):
|
||||||
|
// ret = s.lockEnter(thread, time, value);
|
||||||
|
break;
|
||||||
|
case (UNLOCK):
|
||||||
|
// ret = s.unlockEnter(thread, time, value);
|
||||||
|
break;
|
||||||
|
case (JOIN):
|
||||||
|
//TODO
|
||||||
|
break;
|
||||||
|
case (CONDWAIT):
|
||||||
|
// ret = s.waitEnter(thread, time, value);
|
||||||
|
break;
|
||||||
|
case (BARRIERWAIT):
|
||||||
|
Barrier bar = BarrierTable.barrierList.get(addressSynchItem);
|
||||||
|
if(bar != null){ //to track the condition that the barrier is already opened
|
||||||
|
|
||||||
|
while(bar.blockedThreadSize() == bar.getNumThreads()){ //to track re initialization of barrier
|
||||||
|
bar = BarrierTable.barrierList.get(++addressSynchItem);
|
||||||
|
if(bar == null){
|
||||||
|
addressSynchItem = BarrierTable.barrierCopy(--addressSynchItem);
|
||||||
|
bar = BarrierTable.barrierList.get(addressSynchItem);
|
||||||
|
System.out.println(thread + " bar was null");
|
||||||
|
//return ret;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
while(bar.containsThread(thread)){ //to block the same thread entering barrier twice
|
||||||
|
int i = bar.getNumThreads();
|
||||||
|
//addressSynchItem = BarrierTable.barrierCopy(addressSynchItem);
|
||||||
|
System.out.println("already contains " + thread);
|
||||||
|
bar = BarrierTable.barrierList.get(++addressSynchItem);
|
||||||
|
if(bar == null){
|
||||||
|
bar = new Barrier(addressSynchItem, i);
|
||||||
|
BarrierTable.barrierList.put(addressSynchItem, bar);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(bar==null){
|
||||||
|
System.err.println("barrier not yet initialized");
|
||||||
|
System.exit(0);
|
||||||
|
}
|
||||||
|
// System.out.println(" thread " + thread + " waiting on " +bar.getBarrierAddress() +" " + addressSynchItem);
|
||||||
|
// System.out.println(BarrierTable.barrierList.get(addressSynchItem).getBlockedThreads());
|
||||||
|
bar.addThread(thread);
|
||||||
|
// System.out.println(BarrierTable.barrierList.get(addressSynchItem).getBlockedThreads());
|
||||||
|
ret.setBarrierAddress((long)addressSynchItem);
|
||||||
|
ret.addSleeper(thread);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case (BCAST + 1):
|
||||||
|
// TODO
|
||||||
|
break;
|
||||||
|
case (SIGNAL + 1):
|
||||||
|
// ignore
|
||||||
|
break;
|
||||||
|
case (LOCK + 1):
|
||||||
|
// ret = s.lockExit(thread, time, value);
|
||||||
|
break;
|
||||||
|
case (UNLOCK + 1):
|
||||||
|
// ignore
|
||||||
|
break;
|
||||||
|
case (JOIN + 1):
|
||||||
|
break;
|
||||||
|
case (CONDWAIT + 1):
|
||||||
|
// ret = s.waitExit(thread, time, value);
|
||||||
|
break;
|
||||||
|
case (BARRIERWAIT + 1):
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// ResumeSleep resumePipelineTimer(int tidToResume) {
|
||||||
|
// ResumeSleep ret = new ResumeSleep();
|
||||||
|
// int numResumes=IpcBase.glTable.getStateTable().get(tidToResume).countTimedSleep;
|
||||||
|
// IpcBase.glTable.getStateTable().get(tidToResume).countTimedSleep=0;
|
||||||
|
// for (int i=0; i<numResumes; i++) {
|
||||||
|
// //System.out.println("Resuming by timer"+tidToResume);
|
||||||
|
// //this.pipelineInterfaces[tidToResume].resumePipeline();
|
||||||
|
// ret.addResumer(tidToResume);
|
||||||
|
// }
|
||||||
|
// if (ret==null) misc.Error.shutDown("resumePipelineTimer returned null");
|
||||||
|
// return ret;
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// ResumeSleep tryResumeOnWaitingPipelines(int signaller, long time) {
|
||||||
|
// ResumeSleep ret = new ResumeSleep();
|
||||||
|
// Hashtable<Integer, ThreadState> stateTable = IpcBase.glTable.getStateTable();
|
||||||
|
// Hashtable<Long, SynchPrimitive> synchTable = IpcBase.glTable.getSynchTable();
|
||||||
|
// ThreadState signallingThread = stateTable.get(signaller);
|
||||||
|
// signallingThread.lastTimerseen = time;
|
||||||
|
//
|
||||||
|
// for (PerAddressInfoNew pai : signallingThread.addressMap.values()) {
|
||||||
|
// for (Iterator<Integer> iter = pai.probableInteractors.iterator(); iter.hasNext();) {
|
||||||
|
// int waiter = (Integer)iter.next();
|
||||||
|
// ThreadState waiterThread = stateTable.get(waiter);
|
||||||
|
// if (waiterThread.isOntimedWaitAt(pai.address)) {
|
||||||
|
// //TODO if multiple RunnableThreads then this should be synchronised
|
||||||
|
// if (time>=waiterThread.timeSlept(pai.address)) {
|
||||||
|
// //Remove dependencies from both sides.
|
||||||
|
// iter.remove();
|
||||||
|
// waiterThread.removeDep(signaller);
|
||||||
|
// if (!waiterThread.isOntimedWait()) {
|
||||||
|
// //TODOthis means waiter got released from a timedWait by a timer and not by synchPrimitive.
|
||||||
|
// //this means that in the synchTable somewhere there is a stale entry of their lockEnter/Exit
|
||||||
|
// // or unlockEnter. which needs to removed.
|
||||||
|
// // flushSynchTable();
|
||||||
|
// /* System.out.println(waiter+" pipeline is resuming by timedWait from"+signaller
|
||||||
|
// +" num of Times"+stateTable.get(waiter).countTimedSleep);
|
||||||
|
// */
|
||||||
|
// ret = resumePipelineTimer(waiter);
|
||||||
|
// PerAddressInfoNew p = waiterThread.addressMap.get(pai.address);
|
||||||
|
// if (p!=null) {
|
||||||
|
// if (p.on_broadcast) {
|
||||||
|
// ret.merge(synchTable.get(pai.address).broadcastResume(p.broadcastTime,waiter));
|
||||||
|
// p.on_broadcast = false;
|
||||||
|
// p.broadcastTime = Long.MAX_VALUE;
|
||||||
|
// }
|
||||||
|
// else if (p.on_barrier) {
|
||||||
|
// ret.merge(synchTable.get(pai.address).barrierResume());
|
||||||
|
// p.on_barrier = false;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// else {
|
||||||
|
// // this means that the thread was not timedWait anymore as it got served by the synchronization
|
||||||
|
// // it was waiting for.
|
||||||
|
// iter.remove();
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// return ret;
|
||||||
|
// }
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,42 @@
|
||||||
|
package emulatorinterface;
|
||||||
|
|
||||||
|
import java.util.LinkedList;
|
||||||
|
|
||||||
|
public class PerAddressInfoNew {
|
||||||
|
|
||||||
|
LinkedList<Integer> probableInteractors;
|
||||||
|
long timeSinceSlept;
|
||||||
|
long address;
|
||||||
|
boolean timedWait=false;
|
||||||
|
boolean on_broadcast = false;
|
||||||
|
long broadcastTime = Long.MAX_VALUE;
|
||||||
|
boolean on_barrier = false;
|
||||||
|
|
||||||
|
public PerAddressInfoNew(LinkedList<Integer> tentativeInteractors,
|
||||||
|
long timeSinceSlept,long address,boolean timedWait) {
|
||||||
|
super();
|
||||||
|
this.probableInteractors = tentativeInteractors;
|
||||||
|
this.timeSinceSlept = timeSinceSlept;
|
||||||
|
this.address = address;
|
||||||
|
this.timedWait = timedWait;
|
||||||
|
}
|
||||||
|
|
||||||
|
public LinkedList<Integer> getTentativeInteractors() {
|
||||||
|
return probableInteractors;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTentativeInteractors(LinkedList<Integer> tentativeInteractors) {
|
||||||
|
this.probableInteractors = tentativeInteractors;
|
||||||
|
}
|
||||||
|
|
||||||
|
public long getTime() {
|
||||||
|
return timeSinceSlept;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTime(long time) {
|
||||||
|
this.timeSinceSlept = time;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,765 @@
|
||||||
|
/*
|
||||||
|
* This represents a reader thread in the simulator which keeps on reading from EMUTHREADS.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package emulatorinterface;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.lang.reflect.Array;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.TreeMap;
|
||||||
|
import java.util.Vector;
|
||||||
|
|
||||||
|
import main.ArchitecturalComponent;
|
||||||
|
import main.Main;
|
||||||
|
import memorysystem.Cache;
|
||||||
|
import memorysystem.MemorySystem;
|
||||||
|
import pipeline.PipelineInterface;
|
||||||
|
import config.CommunicationType;
|
||||||
|
import config.EmulatorConfig;
|
||||||
|
import config.EmulatorType;
|
||||||
|
import config.MainMemoryConfig;
|
||||||
|
import config.SystemConfig;
|
||||||
|
import emulatorinterface.ThreadBlockState.blockState;
|
||||||
|
import emulatorinterface.communication.Encoding;
|
||||||
|
import emulatorinterface.communication.IpcBase;
|
||||||
|
import emulatorinterface.communication.Packet;
|
||||||
|
import emulatorinterface.communication.filePacket.FileWrite;
|
||||||
|
import emulatorinterface.communication.shm.SharedMem;
|
||||||
|
import emulatorinterface.translator.InvalidInstructionException;
|
||||||
|
import emulatorinterface.translator.x86.objparser.ObjParser;
|
||||||
|
import generic.BarrierTable;
|
||||||
|
import generic.CircularPacketQueue;
|
||||||
|
import generic.Core;
|
||||||
|
import generic.GenericCircularQueue;
|
||||||
|
import generic.GlobalClock;
|
||||||
|
import generic.Instruction;
|
||||||
|
import generic.Statistics;
|
||||||
|
|
||||||
|
/* MaxNumThreads threads are created from this class. Each thread
|
||||||
|
* continuously keeps reading from the shared memory segment according
|
||||||
|
* to its index(taken care in the jni C file).
|
||||||
|
*/
|
||||||
|
public class RunnableThread implements Encoding, Runnable {
|
||||||
|
|
||||||
|
public static final int INSTRUCTION_THRESHOLD = 2000;
|
||||||
|
|
||||||
|
boolean oNotProcess = false;
|
||||||
|
|
||||||
|
int javaTid;
|
||||||
|
long sum = 0; // checksum
|
||||||
|
int EMUTHREADS;
|
||||||
|
int currentEMUTHREADS = 0; //total number of livethreads
|
||||||
|
int maxCoreAssign = 0; //the maximum core id assigned
|
||||||
|
|
||||||
|
static EmulatorThreadState[] emulatorThreadState;// = new EmulatorThreadState[EMUTHREADS];
|
||||||
|
static ThreadBlockState[] threadBlockState;//=new ThreadBlockState[EMUTHREADS];
|
||||||
|
GenericCircularQueue<Instruction>[] inputToPipeline;
|
||||||
|
FileWrite obj=new FileWrite(1,EmulatorConfig.basenameForTraceFiles);
|
||||||
|
// static long ignoredInstructions = 0;
|
||||||
|
|
||||||
|
// QQQ re-arrange packets for use by translate instruction.
|
||||||
|
// DynamicInstructionBuffer[] dynamicInstructionBuffer;
|
||||||
|
|
||||||
|
static long[] noOfMicroOps;
|
||||||
|
//long[] numInstructions;
|
||||||
|
//FIXME PipelineInterface should be in IpcBase and not here as pipelines from other RunnableThreads
|
||||||
|
// will need to interact.
|
||||||
|
PipelineInterface[] pipelineInterfaces;
|
||||||
|
long prevTotalInstructions, currentTotalInstructions;
|
||||||
|
long[] prevCycles;
|
||||||
|
|
||||||
|
public IpcBase ipcBase;
|
||||||
|
|
||||||
|
private static int liveJavaThreads;
|
||||||
|
|
||||||
|
static boolean printIPTrace = false;
|
||||||
|
static long numShmWrites[];
|
||||||
|
|
||||||
|
//aded by harveenk kushagra
|
||||||
|
//to synch RAM and core clock
|
||||||
|
long counter1=0;
|
||||||
|
long counter2=0;
|
||||||
|
|
||||||
|
//changed by kush, only declare here, initialize later
|
||||||
|
long RAMclock;
|
||||||
|
long CoreClock;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This keeps on reading from the appropriate index in the shared memory
|
||||||
|
* till it gets a -1 after which it stops. NOTE this depends on each thread
|
||||||
|
* calling threadFini() which might not be the case. This function will
|
||||||
|
* break if the threads which started do not call threadfini in the PIN (in
|
||||||
|
* case of unclean termination). Although the problem is easily fixable.
|
||||||
|
*/
|
||||||
|
public void run() {
|
||||||
|
|
||||||
|
// create pool for emulator packets
|
||||||
|
ArrayList<CircularPacketQueue> fromEmulatorAll = new ArrayList<CircularPacketQueue>(EMUTHREADS);
|
||||||
|
for(int i=0; i<EMUTHREADS; i++) {
|
||||||
|
CircularPacketQueue fromEmulator = new CircularPacketQueue(SharedMem.COUNT);
|
||||||
|
fromEmulatorAll.add(fromEmulator);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(printIPTrace==true) {
|
||||||
|
numShmWrites = new long
|
||||||
|
[SystemConfig.maxNumJavaThreads*SystemConfig.numEmuThreadsPerJavaThread];
|
||||||
|
}
|
||||||
|
|
||||||
|
Packet pnew = new Packet();
|
||||||
|
|
||||||
|
boolean allover = false;
|
||||||
|
//boolean emulatorStarted = false;
|
||||||
|
|
||||||
|
// start gets reinitialized when the program actually starts
|
||||||
|
//Main.setStartTime(System.currentTimeMillis());
|
||||||
|
EmulatorThreadState threadParam;
|
||||||
|
// keep on looping till there is something to read. iterates on the
|
||||||
|
// emulator threads from which it has to read.
|
||||||
|
// tid is java thread id
|
||||||
|
// tidEmu is the local notion of pin threads for the current java thread
|
||||||
|
// tidApp is the actual tid of a pin thread
|
||||||
|
|
||||||
|
while (true) {
|
||||||
|
|
||||||
|
|
||||||
|
for (int tidEmulator = 0; tidEmulator < EMUTHREADS ; tidEmulator++) {
|
||||||
|
|
||||||
|
CircularPacketQueue fromEmulator = fromEmulatorAll.get(tidEmulator);
|
||||||
|
|
||||||
|
threadParam = emulatorThreadState[tidEmulator];
|
||||||
|
|
||||||
|
// Thread is halted on a barrier or a sleep
|
||||||
|
if (threadParam.halted /*|| thread.finished*/) {
|
||||||
|
continue; //one bug need to be fixed to remove this comment
|
||||||
|
}
|
||||||
|
|
||||||
|
int tidApplication = javaTid * EMUTHREADS + tidEmulator;
|
||||||
|
int numReads = 0;
|
||||||
|
long v = 0;
|
||||||
|
|
||||||
|
// add outstanding micro-operations to input to pipeline
|
||||||
|
if (threadParam.outstandingMicroOps.isEmpty() == false) {
|
||||||
|
if(threadParam.outstandingMicroOps.size()<inputToPipeline[tidEmulator].spaceLeft()) {
|
||||||
|
while(threadParam.outstandingMicroOps.isEmpty() == false) {
|
||||||
|
inputToPipeline[tidEmulator].enqueue(threadParam.outstandingMicroOps.pollFirst());
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// there is no space in pipelineBuffer. So don't fetch any more instructions
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// get the number of packets to read. 'continue' and read from
|
||||||
|
// some other thread if there is nothing.
|
||||||
|
numReads = ipcBase.fetchManyPackets(tidApplication, fromEmulator);
|
||||||
|
//System.out.println("numReads = " + numReads);
|
||||||
|
if (fromEmulator.size() == 0) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
// update the number of read packets
|
||||||
|
threadParam.totalRead += numReads;
|
||||||
|
|
||||||
|
// If java thread itself is terminated then break out from this
|
||||||
|
// for loop. also update the variable all-over so that I can
|
||||||
|
// break from the outer while loop also.
|
||||||
|
if (ipcBase.javaThreadTermination[javaTid] == true) {
|
||||||
|
allover = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// need to do this only the first time
|
||||||
|
if (ipcBase.javaThreadStarted[javaTid]==false) {
|
||||||
|
//emulatorStarted = true;
|
||||||
|
//Main.setStartTime(System.currentTimeMillis());
|
||||||
|
ipcBase.javaThreadStarted[javaTid] = true;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
threadParam.checkStarted();
|
||||||
|
|
||||||
|
// Process all the packets read from the communication channel
|
||||||
|
while(fromEmulator.isEmpty() == false) {
|
||||||
|
pnew = fromEmulator.dequeue();
|
||||||
|
|
||||||
|
if(EmulatorConfig.emulatorType==EmulatorType.pin && EmulatorConfig.communicationType==CommunicationType.sharedMemory && EmulatorConfig.storeExecutionTraceInAFile==true) {
|
||||||
|
try {
|
||||||
|
try {
|
||||||
|
obj.analysisFn(javaTid, pnew.ip, pnew.value, pnew.tgt,null);
|
||||||
|
} catch (InvalidInstructionException e) {
|
||||||
|
// TODO Auto-generated catch block
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
} catch (IOException e) {
|
||||||
|
// TODO Auto-generated catch block
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
else {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
v = pnew.value;
|
||||||
|
|
||||||
|
if(printIPTrace==true) {
|
||||||
|
System.out.println("pinTrace["+tidApplication+"] " +
|
||||||
|
(++numShmWrites[tidApplication]) + " : " + pnew.ip);
|
||||||
|
}
|
||||||
|
|
||||||
|
// if we read -1, this means this emulator thread finished.
|
||||||
|
if (v == Encoding.THREADCOMPLETE) {
|
||||||
|
System.out.println("runnableshm : last packetList received for application-thread " +
|
||||||
|
tidApplication + " numCISC=" + pnew.ip);
|
||||||
|
//Statistics.setNumPINCISCInsn(pnew.ip, 0, tidEmulator);
|
||||||
|
threadParam.isFirstPacket = true; //preparing the thread for next packetList in same pipeline
|
||||||
|
signalFinish(tidApplication);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(v == Encoding.SUBSETSIMCOMPLETE)
|
||||||
|
{
|
||||||
|
System.out.println("within SUBSETSIMCOMPLETE ");
|
||||||
|
ipcBase.javaThreadTermination[javaTid] = true;
|
||||||
|
liveJavaThreads--;
|
||||||
|
allover = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
boolean ret = processPacket(threadParam, pnew, tidEmulator);
|
||||||
|
if(ret==false) {
|
||||||
|
// There is not enough space in pipeline buffer.
|
||||||
|
// So don't process any more packets.
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(printIPTrace==true) {
|
||||||
|
System.out.flush();
|
||||||
|
}
|
||||||
|
|
||||||
|
// perform error check.
|
||||||
|
ipcBase.errorCheck(tidApplication, threadParam.totalRead);
|
||||||
|
|
||||||
|
|
||||||
|
if (ipcBase.javaThreadTermination[javaTid] == true) { //check if java thread is finished
|
||||||
|
allover = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
//System.out.println("here");
|
||||||
|
if(liveJavaThreads==1)
|
||||||
|
{//System.out.println("size :"+inputToPipeline[tidEmulator].size());
|
||||||
|
if(inputToPipeline[tidEmulator].size()<=0)
|
||||||
|
{
|
||||||
|
//System.out.println("******************************continued*******************");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if(liveJavaThreads>1)
|
||||||
|
{//System.out.println("live threads :"+liveJavaThreads);
|
||||||
|
if(inputToPipeline[tidEmulator].size()<=0 || liveJavaThreads>1 && statusOfOtherThreads()) {
|
||||||
|
//System.out.println("******************************continued2*******************");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
runPipelines();
|
||||||
|
// System.out.println("after execution n= "+n+" Thread finished ? "+threadParams[1].finished);
|
||||||
|
|
||||||
|
// this runnable thread can be stopped in two ways. Either the
|
||||||
|
// emulator threads from which it was supposed to read never
|
||||||
|
// started(none of them) so it has to be signalled by the main
|
||||||
|
// thread. When this happens 'all over' becomes 'true' and it
|
||||||
|
// breaks out from the loop. The second situation is that all the
|
||||||
|
// emulator threads which started have now finished, so probably
|
||||||
|
// this thread should now terminate.
|
||||||
|
// The second condition handles this situation.
|
||||||
|
// NOTE this ugly state management cannot be avoided unless we use
|
||||||
|
// some kind of a signalling mechanism between the emulator and
|
||||||
|
// simulator(TODO).
|
||||||
|
// Although this should handle most of the cases.
|
||||||
|
if (allover || (ipcBase.javaThreadStarted[javaTid]==true && emuThreadsFinished())) {
|
||||||
|
ipcBase.javaThreadTermination[javaTid] = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
finishAllPipelines();
|
||||||
|
|
||||||
|
if(unHandledCount!=null) {
|
||||||
|
sorted_map.putAll(unHandledCount);
|
||||||
|
System.out.println(sorted_map);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// void errorCheck(int tidApp, int emuid, int queue_size,
|
||||||
|
// long numReads, long v) {
|
||||||
|
//
|
||||||
|
// // some error checking
|
||||||
|
// // threadParams[emuid].totalRead += numReads;
|
||||||
|
// long totalRead = threadParams[emuid].totalRead;
|
||||||
|
// long totalProduced = ipcBase.totalProduced(tidApp);
|
||||||
|
//
|
||||||
|
// if (totalRead > totalProduced) {
|
||||||
|
// System.out.println("numReads=" + numReads + " > totalProduced="
|
||||||
|
// + totalProduced + " !!");
|
||||||
|
//
|
||||||
|
// System.out.println("queue_size=" + queue_size);
|
||||||
|
// System.exit(1);
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// if (queue_size < 0) {
|
||||||
|
// System.out.println("queue less than 0");
|
||||||
|
// System.exit(1);
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
|
||||||
|
private boolean statusOfOtherThreads() {
|
||||||
|
// returns true if any other live threads have empty inputtopipeline
|
||||||
|
for(int i=0;i<EMUTHREADS;i++)
|
||||||
|
{
|
||||||
|
if(emulatorThreadState[i].started && threadBlockState[i].getState()==blockState.LIVE)
|
||||||
|
{
|
||||||
|
//System.out.println("in loop, size "+i+":"+inputToPipeline[i].size());
|
||||||
|
if(inputToPipeline[i].size()<=0)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// initialise a reader thread with the correct thread id and the buffer to
|
||||||
|
// write the results in.
|
||||||
|
public RunnableThread(String threadName, int javaTid, IpcBase ipcBase, Core[] cores) {
|
||||||
|
|
||||||
|
this.ipcBase = ipcBase;
|
||||||
|
|
||||||
|
this.EMUTHREADS = SystemConfig.numEmuThreadsPerJavaThread;
|
||||||
|
emulatorThreadState = new EmulatorThreadState[EMUTHREADS];
|
||||||
|
threadBlockState = new ThreadBlockState[EMUTHREADS];
|
||||||
|
|
||||||
|
// dynamicInstructionBuffer = new DynamicInstructionBuffer[EMUTHREADS];
|
||||||
|
inputToPipeline = (GenericCircularQueue<Instruction> [])
|
||||||
|
Array.newInstance(GenericCircularQueue.class, EMUTHREADS);
|
||||||
|
|
||||||
|
noOfMicroOps = new long[EMUTHREADS];
|
||||||
|
//numInstructions = new long[EMUTHREADS];
|
||||||
|
pipelineInterfaces = new PipelineInterface[EMUTHREADS];
|
||||||
|
for(int i = 0; i < EMUTHREADS; i++)
|
||||||
|
{
|
||||||
|
int id = javaTid*EMUTHREADS+i;
|
||||||
|
IpcBase.glTable.getStateTable().put(id, new ThreadState(id));
|
||||||
|
emulatorThreadState[i] = new EmulatorThreadState();
|
||||||
|
threadBlockState[i]=new ThreadBlockState();
|
||||||
|
|
||||||
|
//TODO pipelineinterfaces & inputToPipeline should also be in the IpcBase
|
||||||
|
pipelineInterfaces[i] = cores[i].getPipelineInterface();
|
||||||
|
inputToPipeline[i] = new GenericCircularQueue<Instruction>(
|
||||||
|
Instruction.class, INSTRUCTION_THRESHOLD);
|
||||||
|
|
||||||
|
// dynamicInstructionBuffer[i] = new DynamicInstructionBuffer();
|
||||||
|
|
||||||
|
GenericCircularQueue<Instruction>[] toBeSet =
|
||||||
|
(GenericCircularQueue<Instruction>[])
|
||||||
|
Array.newInstance(GenericCircularQueue.class, 1);
|
||||||
|
toBeSet[0] = inputToPipeline[i];
|
||||||
|
pipelineInterfaces[i].setInputToPipeline(toBeSet);
|
||||||
|
}
|
||||||
|
|
||||||
|
this.javaTid = javaTid;
|
||||||
|
System.out.println("-- starting java thread"+this.javaTid);
|
||||||
|
prevTotalInstructions=-1;
|
||||||
|
currentTotalInstructions=0;
|
||||||
|
// threadCoreMaping = new Hashtable<Integer, Integer>();
|
||||||
|
prevCycles=new long[EMUTHREADS];
|
||||||
|
|
||||||
|
|
||||||
|
//added by harveenk kushagra
|
||||||
|
CoreClock = cores[0].getFrequency() * 1000000;
|
||||||
|
|
||||||
|
//added later by kush
|
||||||
|
if(SystemConfig.memControllerToUse==true)
|
||||||
|
RAMclock = (long) (1 / (SystemConfig.mainMemoryConfig.tCK) * 1000000000);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void runPipelines() {
|
||||||
|
int minN = Integer.MAX_VALUE;
|
||||||
|
boolean RAMcyclerun = false;
|
||||||
|
|
||||||
|
|
||||||
|
for (int tidEmu = 0; tidEmu < maxCoreAssign; tidEmu++) {
|
||||||
|
EmulatorThreadState th = emulatorThreadState[tidEmu];
|
||||||
|
if ( th.halted && !(this.inputToPipeline[tidEmu].size() > INSTRUCTION_THRESHOLD)) {
|
||||||
|
th.halted = false;
|
||||||
|
}
|
||||||
|
int n = (int)(inputToPipeline[tidEmu].size() / pipelineInterfaces[tidEmu].getCore().getDecodeWidth()
|
||||||
|
* pipelineInterfaces[tidEmu].getCoreStepSize());
|
||||||
|
if (n < minN && n != 0)
|
||||||
|
minN = n;
|
||||||
|
}
|
||||||
|
minN = (minN == Integer.MAX_VALUE) ? 0 : minN;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
for (int i1 = 0; i1 < minN; i1++) {
|
||||||
|
|
||||||
|
/* Note: DRAM simulation
|
||||||
|
Order of execution must be maintained for cycle accurate simulation.
|
||||||
|
Order is:
|
||||||
|
MainMemoryController.oneCycleOperation()
|
||||||
|
processEvents() [called from within oneCycleOperation of pipelines]
|
||||||
|
MainMemoryController.enqueueToCommandQ();
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
//added later by kush
|
||||||
|
//run one cycle operation only when DRAM simulation enabled
|
||||||
|
if(SystemConfig.memControllerToUse==true){
|
||||||
|
counter1 += RAMclock;
|
||||||
|
|
||||||
|
|
||||||
|
//added by harveenk
|
||||||
|
if (counter2 < counter1)
|
||||||
|
{
|
||||||
|
|
||||||
|
counter2 += CoreClock;
|
||||||
|
for(int k=0;k<SystemConfig.mainMemoryConfig.numChans;k++){
|
||||||
|
ArchitecturalComponent.getMainMemoryDRAMController(null,k).oneCycleOperation();
|
||||||
|
}
|
||||||
|
//important - one cycle operation for dram must occur before events are processed
|
||||||
|
|
||||||
|
RAMcyclerun = true;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
for (int tidEmu = 0; tidEmu < maxCoreAssign; tidEmu++) {
|
||||||
|
pipelineInterfaces[tidEmu].oneCycleOperation();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//added later by kush
|
||||||
|
if(SystemConfig.memControllerToUse==true){
|
||||||
|
if(counter1 == counter2)
|
||||||
|
{
|
||||||
|
counter1 = 0;
|
||||||
|
counter2 = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if(RAMcyclerun == true)
|
||||||
|
{
|
||||||
|
|
||||||
|
//add the packets pending at this cycle to the queue
|
||||||
|
|
||||||
|
for(int k=0;k<SystemConfig.mainMemoryConfig.numChans;k++){
|
||||||
|
ArchitecturalComponent.getMainMemoryDRAMController(null,k).enqueueToCommandQ();
|
||||||
|
//print debug if RAM was run this cycle
|
||||||
|
|
||||||
|
//if(SystemConfig.mainMemoryConfig.DEBUG_BANKSTATE)
|
||||||
|
//ArchitecturalComponent.getMainMemoryDRAMController(null,k).printBankStateTest();
|
||||||
|
//if(SystemConfig.mainMemoryConfig.DEBUG_CMDQ)
|
||||||
|
//ArchitecturalComponent.getMainMemoryDRAMController(null,k).commandQueue.printTest();
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
RAMcyclerun = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
GlobalClock.incrementClock();
|
||||||
|
|
||||||
|
|
||||||
|
if(GlobalClock.getCurrentTime()%1000==0) {
|
||||||
|
// Every 1000 cycles, iterate over all the caches, and note the MSHR sizes
|
||||||
|
for(Cache c : ArchitecturalComponent.getCacheList()) {
|
||||||
|
c.noteMSHRStats();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(prevTotalInstructions == -1) {
|
||||||
|
prevTotalInstructions=0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void finishAllPipelines() {
|
||||||
|
|
||||||
|
//added by harveenk
|
||||||
|
boolean RAMcyclerun = false;
|
||||||
|
|
||||||
|
//finishAllPipelines is called when all communication channels (shared memory segments or files) have been read completely
|
||||||
|
//compiles statistics and winds up simulation
|
||||||
|
//NOTE: there are some UNSIMULATED instructions in the inputToPipeline structures and in the pipelines themselves.
|
||||||
|
// these are small in number (around 1200 per core at max) and should not affect the final statistics
|
||||||
|
|
||||||
|
for (int i=0; i<maxCoreAssign; i++) {
|
||||||
|
pipelineInterfaces[i].setExecutionComplete(true);
|
||||||
|
pipelineInterfaces[i].setPerCoreMemorySystemStatistics();
|
||||||
|
pipelineInterfaces[i].setTimingStatistics();
|
||||||
|
}
|
||||||
|
|
||||||
|
long dataRead = 0;
|
||||||
|
for (int i = 0; i < EMUTHREADS; i++) {
|
||||||
|
dataRead += emulatorThreadState[i].totalRead;
|
||||||
|
}
|
||||||
|
|
||||||
|
Statistics.setDataRead(dataRead, javaTid);
|
||||||
|
Statistics.setNoOfMicroOps(noOfMicroOps, javaTid);
|
||||||
|
|
||||||
|
IpcBase.free.release();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// returns true if all the emulator threads from which I was reading have
|
||||||
|
// finished
|
||||||
|
protected boolean emuThreadsFinished() {
|
||||||
|
boolean ret = true;
|
||||||
|
for (int i = 0; i < maxCoreAssign; i++) {
|
||||||
|
EmulatorThreadState thread = emulatorThreadState[i];
|
||||||
|
if (thread.started == true
|
||||||
|
&& thread.finished == false) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
* process each packetList
|
||||||
|
* parameters - Thread information, packetList, thread id
|
||||||
|
* Call fuseInstruction on a outstanding micro-ops list instead of pipeline buffer
|
||||||
|
* If we are not able to add packets from outstanding micro-ops list to pipeline buffer, then
|
||||||
|
* return false (there is no space in pipeline buffer).
|
||||||
|
*/
|
||||||
|
static int numProcessPackets = 0;
|
||||||
|
protected boolean processPacket(EmulatorThreadState thread, Packet pnew, int tidEmu) {
|
||||||
|
|
||||||
|
// System.out.println("&processPacket " + (++numProcessPackets) + " : " + pnew.ip);
|
||||||
|
|
||||||
|
boolean isSpaceInPipelineBuffer = true;
|
||||||
|
|
||||||
|
int tidApp = javaTid * EMUTHREADS + tidEmu;
|
||||||
|
|
||||||
|
sum += pnew.value;
|
||||||
|
|
||||||
|
if (pnew.value == TIMER) {//leaving timer packetList now
|
||||||
|
//resumeSleep(IpcBase.glTable.tryResumeOnWaitingPipelines(tidApp, pnew.ip));
|
||||||
|
return isSpaceInPipelineBuffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pnew.value>SYNCHSTART && pnew.value<SYNCHEND) { //for barrier enter and barrier exit
|
||||||
|
ResumeSleep ret = IpcBase.glTable.update(pnew.tgt, tidApp, pnew.ip, pnew.value);
|
||||||
|
if(ret!=null){
|
||||||
|
resumeSleep(ret);
|
||||||
|
}
|
||||||
|
checkForBlockingPacket(pnew.value,tidApp);
|
||||||
|
if(threadBlockState[tidApp].getState()==blockState.BLOCK)
|
||||||
|
{
|
||||||
|
checkForUnBlockingPacket(pnew.value,tidApp);
|
||||||
|
|
||||||
|
}
|
||||||
|
return isSpaceInPipelineBuffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(pnew.value == BARRIERINIT) //for barrier initialization
|
||||||
|
{
|
||||||
|
|
||||||
|
// System.out.println("Packet is " + pnew.toString());
|
||||||
|
BarrierTable.barrierListAdd(pnew);
|
||||||
|
return isSpaceInPipelineBuffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (thread.isFirstPacket)
|
||||||
|
{
|
||||||
|
this.pipelineInterfaces[tidApp].getCore().currentThreads++; //current number of threads in this pipeline
|
||||||
|
System.out.println("num of threads on core " + tidApp + " = " + this.pipelineInterfaces[tidApp].getCore().currentThreads);
|
||||||
|
this.pipelineInterfaces[tidApp].getCore().getExecEngine().setExecutionComplete(false);
|
||||||
|
this.pipelineInterfaces[tidApp].getCore().getExecEngine().setExecutionBegun(true);
|
||||||
|
currentEMUTHREADS ++;
|
||||||
|
if(tidApp>=maxCoreAssign)
|
||||||
|
maxCoreAssign = tidApp+1;
|
||||||
|
|
||||||
|
//thread.pold.set(pnew);
|
||||||
|
thread.packetList.add(pnew);
|
||||||
|
liveJavaThreads++;
|
||||||
|
threadBlockState[tidApp].gotLive();
|
||||||
|
thread.isFirstPacket=false;
|
||||||
|
return isSpaceInPipelineBuffer;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pnew.value!=INSTRUCTION && !(pnew.value>6 && pnew.value<26) && pnew.value!=Encoding.ASSEMBLY ) {
|
||||||
|
// just append the packet to outstanding packetList for current instruction pointer
|
||||||
|
thread.packetList.add(pnew);
|
||||||
|
|
||||||
|
} else {
|
||||||
|
//(numInstructions[tidEmu])++;
|
||||||
|
//this.dynamicInstructionBuffer[tidEmu].configurePackets(thread.packets);
|
||||||
|
|
||||||
|
int oldLength = inputToPipeline[tidEmu].size();
|
||||||
|
|
||||||
|
long numHandledInsn = 0;
|
||||||
|
int numMicroOpsBefore = thread.outstandingMicroOps.size();
|
||||||
|
|
||||||
|
ObjParser.fuseInstruction(tidApp, thread.packetList.get(0).ip,
|
||||||
|
thread.packetList, thread.outstandingMicroOps);
|
||||||
|
|
||||||
|
// Increment number of CISC instructions
|
||||||
|
Statistics.setNumCISCInsn(Statistics.getNumCISCInsn(javaTid, tidEmu) + 1, javaTid, tidEmu);
|
||||||
|
|
||||||
|
int numMicroOpsAfter = thread.outstandingMicroOps.size();
|
||||||
|
if(numMicroOpsAfter>numMicroOpsBefore) {
|
||||||
|
numHandledInsn = 1;
|
||||||
|
} else {
|
||||||
|
numHandledInsn = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// For one CISC instruction, we generate x micro-operations.
|
||||||
|
// We set the CISC ip of the first micro-op to the original CISC ip.
|
||||||
|
// IP of all the remaining micro-ops is set to -1(Invalid).
|
||||||
|
// This ensures that we do not artificially increase the hit-rate of instruction cache.
|
||||||
|
for(int i=numMicroOpsBefore; i<numMicroOpsAfter; i++) {
|
||||||
|
if(i==numMicroOpsBefore) {
|
||||||
|
thread.outstandingMicroOps.peek(i).setCISCProgramCounter(thread.packetList.get(0).ip);
|
||||||
|
} else {
|
||||||
|
thread.outstandingMicroOps.peek(i).setCISCProgramCounter(-1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// If I am running multiple benchmarks, the addresses of all the benchmarks must
|
||||||
|
// be tagged with benchmark ID. The tagging happens only if :
|
||||||
|
// (a) there are multiple benchmarks (b) the benchmark id for this thread is not zero
|
||||||
|
if(Main.benchmarkThreadMapping.getNumBenchmarks()>1 && tidApp>0 && Main.benchmarkThreadMapping.getBenchmarkIDForThread(tidApp)!=0) {
|
||||||
|
for(int i=numMicroOpsBefore; i<numMicroOpsAfter; i++) {
|
||||||
|
thread.outstandingMicroOps.peek(i).changeAddressesForBenchmark(Main.benchmarkThreadMapping.getBenchmarkIDForThread(tidApp));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
if(numHandledInsn==0 && printUnHandledInsn) {
|
||||||
|
calculateCulpritCISCInsns(thread.packetList.get(0).ip);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Either add all outstanding micro-ops or none.
|
||||||
|
if(thread.outstandingMicroOps.size()<this.inputToPipeline[tidEmu].spaceLeft()) {
|
||||||
|
// add outstanding micro-operations to input to pipeline
|
||||||
|
while(thread.outstandingMicroOps.isEmpty() == false) {
|
||||||
|
this.inputToPipeline[tidEmu].enqueue(thread.outstandingMicroOps.dequeue());
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
isSpaceInPipelineBuffer = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
Statistics.setNumHandledCISCInsn(
|
||||||
|
Statistics.getNumHandledCISCInsn(javaTid, tidEmu) + numHandledInsn,
|
||||||
|
javaTid, tidEmu);
|
||||||
|
|
||||||
|
int newLength = inputToPipeline[tidEmu].size();
|
||||||
|
noOfMicroOps[tidEmu] += newLength - oldLength;
|
||||||
|
|
||||||
|
if (!thread.halted && this.inputToPipeline[tidEmu].size() > INSTRUCTION_THRESHOLD) {
|
||||||
|
thread.halted = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
thread.packetList.clear();
|
||||||
|
thread.packetList.add(pnew);
|
||||||
|
}
|
||||||
|
|
||||||
|
return isSpaceInPipelineBuffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void checkForBlockingPacket(long value,int TidApp) {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
int val=(int)value;
|
||||||
|
switch(val)
|
||||||
|
{
|
||||||
|
case LOCK:
|
||||||
|
case JOIN:
|
||||||
|
case CONDWAIT:
|
||||||
|
case BARRIERWAIT:threadBlockState[TidApp].gotBlockingPacket(val);
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void checkForUnBlockingPacket(long value,int TidApp) {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
int val=(int)value;
|
||||||
|
switch(val)
|
||||||
|
{
|
||||||
|
case LOCK+1:
|
||||||
|
case JOIN+1:
|
||||||
|
case CONDWAIT+1:
|
||||||
|
case BARRIERWAIT+1:threadBlockState[TidApp].gotUnBlockingPacket();
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
boolean printUnHandledInsn = false;
|
||||||
|
private HashMap<Long, Long> unHandledCount;
|
||||||
|
UnhandledInsnCountComparator bvc;
|
||||||
|
TreeMap <Long,Long> sorted_map;
|
||||||
|
private void calculateCulpritCISCInsns(long ip) {
|
||||||
|
|
||||||
|
if(printUnHandledInsn==false) {
|
||||||
|
misc.Error.showErrorAndExit("printUnHandledInsn function should not be called. Its flag is not set !!");
|
||||||
|
}
|
||||||
|
|
||||||
|
if(unHandledCount==null) {
|
||||||
|
unHandledCount = new HashMap<Long,Long>();
|
||||||
|
bvc = new UnhandledInsnCountComparator(unHandledCount);
|
||||||
|
sorted_map = new TreeMap<Long,Long>(bvc);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(unHandledCount.get(ip)==null) {
|
||||||
|
unHandledCount.put(ip, 1l);
|
||||||
|
} else {
|
||||||
|
unHandledCount.put(ip,unHandledCount.get(ip)+1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
protected boolean poolExhausted(int tidEmulator) {
|
||||||
|
return false; //we have a growable pool now
|
||||||
|
//return (CustomObjectPool.getInstructionPool().getNumPoolAllowed() < 2000);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void resumeSleep(ResumeSleep update) {
|
||||||
|
for (int i=0; i<update.getNumSleepers(); i++) {
|
||||||
|
Instruction ins = Instruction.getSyncInstruction();
|
||||||
|
ins.setCISCProgramCounter(update.barrierAddress);
|
||||||
|
System.out.println( "Enqueued a barrier packet into "+ update.sleep.get(i) + " with add " + update.barrierAddress);
|
||||||
|
this.inputToPipeline[update.sleep.get(i)].enqueue(ins);
|
||||||
|
setThreadState(update.sleep.get(i), true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
protected void signalFinish(int tidApp) {
|
||||||
|
//finished pipline
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
// System.out.println("signalfinish thread " + tidApp + " mapping " + threadCoreMaping.get(tidApp));
|
||||||
|
this.inputToPipeline[tidApp].enqueue(Instruction.getInvalidInstruction());
|
||||||
|
IpcBase.glTable.getStateTable().get((Integer)tidApp).lastTimerseen = Long.MAX_VALUE;//(long)-1>>>1;
|
||||||
|
// System.out.println(tidApp+" pin thread got -1");
|
||||||
|
|
||||||
|
// FIXME threadParams should be on tidApp. Currently it is on tidEmu
|
||||||
|
emulatorThreadState[tidApp].finished = true;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void setThreadState(int tid,boolean cond)
|
||||||
|
{
|
||||||
|
// System.out.println("set thread state halted" + tid + " to " + cond);
|
||||||
|
emulatorThreadState[tid].halted = cond;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,419 @@
|
||||||
|
package emulatorinterface;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Hashtable;
|
||||||
|
import java.util.LinkedList;
|
||||||
|
|
||||||
|
//import org.apache.log4j.Logger;
|
||||||
|
|
||||||
|
|
||||||
|
import emulatorinterface.communication.Encoding;
|
||||||
|
import emulatorinterface.communication.IpcBase;
|
||||||
|
|
||||||
|
public class SynchPrimitive implements Encoding {
|
||||||
|
|
||||||
|
// private static final Logger logger = Logger.getLogger(SynchPrimitive.class);
|
||||||
|
private static final boolean debugMode = true;
|
||||||
|
LinkedList<SynchType> entries;
|
||||||
|
long address;
|
||||||
|
|
||||||
|
public SynchPrimitive(long addressSynchItem, int thread, long time,
|
||||||
|
long value, IpcBase ipcType) {
|
||||||
|
this.address = addressSynchItem;
|
||||||
|
this.entries = new LinkedList<SynchType>();
|
||||||
|
entries.add(new SynchType(thread, time, value));
|
||||||
|
}
|
||||||
|
|
||||||
|
private int putOnTimedWait(int thread, long time, long value) {
|
||||||
|
Hashtable<Integer, ThreadState> stateTable = IpcBase.glTable
|
||||||
|
.getStateTable();
|
||||||
|
ThreadState ts = stateTable.get(thread);
|
||||||
|
LinkedList<Integer> others = new LinkedList<Integer>();
|
||||||
|
// add dependencies bothways
|
||||||
|
for (ThreadState otherThreads : stateTable.values()) {
|
||||||
|
if (otherThreads.lastTimerseen < time && otherThreads.threadIndex!=thread) {
|
||||||
|
otherThreads.addDep(address, time, thread);
|
||||||
|
others.add(otherThreads.threadIndex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (others.size()!=0) {
|
||||||
|
if(debugMode)
|
||||||
|
System.out.println(this.address+" "+thread+" `"+value+"`, going on a timedWait on "+others.size()+" threads");
|
||||||
|
stateTable.get((Integer)thread).countTimedSleep++;
|
||||||
|
ts.addressMap.put(address, new PerAddressInfoNew(others, time, address,true));
|
||||||
|
entries.add(new SynchType(thread, time, value));
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if(debugMode)
|
||||||
|
System.out.println(this.address+" "+thread+" `"+value+"`, no TimedWait ");
|
||||||
|
ts.addressMap.remove(address);
|
||||||
|
}
|
||||||
|
return others.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
ResumeSleep sigEnter(int thread, long time, long value) {
|
||||||
|
boolean done = false;
|
||||||
|
//int interactingThread = -1;
|
||||||
|
ResumeSleep ret = new ResumeSleep();
|
||||||
|
SynchType toBeRemoved1 = null, toBeRemoved2 = null;
|
||||||
|
for (SynchType entry : entries) {
|
||||||
|
// if a wait enter before
|
||||||
|
if (entry.encoding == CONDWAIT && entry.time < time && entry.thread != thread) {
|
||||||
|
for (SynchType exit : entries) {
|
||||||
|
// if a wait exit after
|
||||||
|
if (exit.encoding == CONDWAIT + 1 && exit.time > time
|
||||||
|
&& exit.thread == entry.thread) {
|
||||||
|
if(debugMode)
|
||||||
|
System.out.println(this.address+" "+thread+" sigenter, got waitenter & exit from "+exit.thread);
|
||||||
|
if (done)
|
||||||
|
misc.Error.shutDown("Duplicate entry in sigEnter");
|
||||||
|
//interactingThread = exit.thread;
|
||||||
|
ret.addResumer(exit.thread);
|
||||||
|
done = true;
|
||||||
|
toBeRemoved1 = entry;
|
||||||
|
toBeRemoved2 = exit;
|
||||||
|
Hashtable<Integer, ThreadState> stateTable = IpcBase.glTable.getStateTable();
|
||||||
|
stateTable.get(exit.thread).addressMap.remove(address);
|
||||||
|
stateTable.get(thread).addressMap.remove(address);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (done)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!done) {
|
||||||
|
int otherThreads = putOnTimedWait(thread, time, value);
|
||||||
|
if (otherThreads==0) {
|
||||||
|
System.out.println("SynchPrimitive: Spurious signal received");
|
||||||
|
//interactingThread = -2; // means nobody sleeps/resumes
|
||||||
|
}
|
||||||
|
else ret.addSleeper(thread);
|
||||||
|
} else {
|
||||||
|
entries.remove(toBeRemoved1);
|
||||||
|
entries.remove(toBeRemoved2);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* if (interactingThread==-1) ret.addSleeper(thread);
|
||||||
|
else if (interactingThread==-2) {}
|
||||||
|
else {
|
||||||
|
ret.addResumer(interactingThread);
|
||||||
|
}
|
||||||
|
*/ return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
ResumeSleep waitEnter(int thread, long time, long value) {
|
||||||
|
//System.out.println(this.address+" "+" waitEnter");
|
||||||
|
entries.add(new SynchType(thread, time, value));
|
||||||
|
ResumeSleep ret = new ResumeSleep();
|
||||||
|
ret.addSleeper(thread);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
ResumeSleep waitExit(int thread, long time, long value) {
|
||||||
|
boolean done = false;
|
||||||
|
//int interactingThread = -1;
|
||||||
|
ResumeSleep ret = new ResumeSleep();
|
||||||
|
SynchType toBeRemoved1 = null, toBeRemoved2 = null;
|
||||||
|
for (SynchType entry : entries) {
|
||||||
|
// if this thread entered
|
||||||
|
if (entry.encoding == CONDWAIT && entry.time < time
|
||||||
|
&& entry.thread == thread) {
|
||||||
|
for (SynchType sig : entries) {
|
||||||
|
// if a signal by some other thread found
|
||||||
|
if (sig.encoding == SIGNAL && sig.time < time
|
||||||
|
&& sig.time > entry.time && sig.thread!=thread) {
|
||||||
|
if (done)
|
||||||
|
misc.Error.shutDown("Duplicate entry in wEx");
|
||||||
|
if(debugMode)
|
||||||
|
System.out.println(this.address+" "+thread+" waitexit, got signal dep on "+sig.thread);
|
||||||
|
//interactingThread = sig.thread;
|
||||||
|
ret.addResumer(sig.thread);
|
||||||
|
ret.addResumer(thread);
|
||||||
|
|
||||||
|
done = true;
|
||||||
|
toBeRemoved1 = entry;
|
||||||
|
toBeRemoved2 = sig;
|
||||||
|
|
||||||
|
Hashtable<Integer, ThreadState> stateTable = IpcBase.glTable
|
||||||
|
.getStateTable();
|
||||||
|
stateTable.get(sig.thread).addressMap
|
||||||
|
.remove(address);
|
||||||
|
stateTable.get(thread).addressMap.remove(address);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (done)
|
||||||
|
break;
|
||||||
|
//if (entry.encoding == BCAST && entry.time < time)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!done) {
|
||||||
|
// XXX the only difference between lock/unlock and wait/signal is here.
|
||||||
|
// as we are not going for a timedWait but original wait.
|
||||||
|
entries.add(new SynchType(thread, time, value));
|
||||||
|
//interactingThread = -2;
|
||||||
|
} else {
|
||||||
|
entries.remove(toBeRemoved1);
|
||||||
|
if (toBeRemoved2!=null) entries.remove(toBeRemoved2);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*if (interactingThread==-1) ret.addSleeper(thread);
|
||||||
|
else if (interactingThread==-2) {}
|
||||||
|
else {
|
||||||
|
ret.addResumer(interactingThread);
|
||||||
|
ret.addResumer(thread);
|
||||||
|
}*/
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
ResumeSleep unlockEnter(int thread, long time, long value) {
|
||||||
|
boolean done = false;
|
||||||
|
ResumeSleep ret = new ResumeSleep();
|
||||||
|
// int interactingThread = -1;
|
||||||
|
SynchType toBeRemoved1 = null, toBeRemoved2 = null;
|
||||||
|
for (SynchType entry : entries) {
|
||||||
|
// if a lock enter before
|
||||||
|
if (entry.encoding == LOCK && entry.time < time && entry.thread!=thread) {
|
||||||
|
for (SynchType exit : entries) {
|
||||||
|
// if a lock exit after
|
||||||
|
if (exit.encoding == LOCK + 1 && exit.time > time
|
||||||
|
&& exit.thread == entry.thread) {
|
||||||
|
if(debugMode)
|
||||||
|
System.out.println(this.address+" "+thread+" unlockenter, got lockenter and lockexit from "+exit.thread);
|
||||||
|
if (done)
|
||||||
|
misc.Error.shutDown("Duplicate entry in unlockEnter");
|
||||||
|
//XXXinteractingThread = exit.thread;
|
||||||
|
ret.addResumer(exit.thread);
|
||||||
|
done = true;
|
||||||
|
toBeRemoved1 = entry;
|
||||||
|
toBeRemoved2 = exit;
|
||||||
|
|
||||||
|
Hashtable<Integer, ThreadState> stateTable = IpcBase.glTable
|
||||||
|
.getStateTable();
|
||||||
|
stateTable.get(exit.thread).addressMap
|
||||||
|
.remove(address);
|
||||||
|
stateTable.get(thread).addressMap.remove(address);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (done)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!done) {
|
||||||
|
//May never get a corresponding lockenter lockexit
|
||||||
|
//so do a timed wait.
|
||||||
|
int otherThreads = putOnTimedWait(thread, time, value);
|
||||||
|
//XXX if (otherThreads==0) interactingThread = -2;// means nobody sleeps/resumes
|
||||||
|
if (otherThreads!=0) ret.addSleeper(thread);
|
||||||
|
|
||||||
|
} else {
|
||||||
|
entries.remove(toBeRemoved1);
|
||||||
|
entries.remove(toBeRemoved2);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*XXX if (interactingThread==-1) ret.addSleeper(thread);
|
||||||
|
else if (interactingThread==-2) {}
|
||||||
|
else {
|
||||||
|
ret.addResumer(interactingThread);
|
||||||
|
}*/
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
ResumeSleep lockEnter(int thread, long time, long value) {
|
||||||
|
if(debugMode) System.out.println(this.address+" "+thread+" lockenter");
|
||||||
|
entries.add(new SynchType(thread, time, value));
|
||||||
|
ResumeSleep ret = new ResumeSleep();
|
||||||
|
ret.addSleeper(thread);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
ResumeSleep lockExit(int thread, long time, long value) {
|
||||||
|
boolean done = false;
|
||||||
|
//int interactingThread = -1;
|
||||||
|
ResumeSleep ret = new ResumeSleep();
|
||||||
|
SynchType toBeRemoved1 = null, toBeRemoved2 = null;
|
||||||
|
for (SynchType entry : entries) {
|
||||||
|
// if this thread entered
|
||||||
|
if (entry.encoding == LOCK && entry.time < time
|
||||||
|
&& entry.thread == thread) {
|
||||||
|
for (SynchType unlock : entries) {
|
||||||
|
// if an unlock by some other thread found
|
||||||
|
if (unlock.encoding == UNLOCK && unlock.time < time
|
||||||
|
&& unlock.time > entry.time && unlock.thread!=thread) {
|
||||||
|
if(debugMode)
|
||||||
|
System.out.println(this.address+" "+thread+" lockexit, got unlock dep on "+unlock.thread);
|
||||||
|
//XXXinteractingThread = unlock.thread;
|
||||||
|
ret.addResumer(unlock.thread);
|
||||||
|
ret.addResumer(thread);
|
||||||
|
done = true;
|
||||||
|
toBeRemoved1 = entry;
|
||||||
|
toBeRemoved2 = unlock;
|
||||||
|
|
||||||
|
Hashtable<Integer, ThreadState> stateTable = IpcBase.glTable
|
||||||
|
.getStateTable();
|
||||||
|
stateTable.get(unlock.thread).addressMap
|
||||||
|
.remove(address);
|
||||||
|
stateTable.get(thread).addressMap.remove(address);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (done)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!done) {
|
||||||
|
// lock enter and lock exit seen but no unlock enter. so
|
||||||
|
// wait till others pass its time
|
||||||
|
int otherThreads = putOnTimedWait(thread, time, value);
|
||||||
|
if (otherThreads==0) ret.addResumer(thread);
|
||||||
|
|
||||||
|
/*if (otherThreads == 0) interactingThread = thread;
|
||||||
|
else interactingThread = -2;*/
|
||||||
|
} else {
|
||||||
|
entries.remove(toBeRemoved1);
|
||||||
|
if(toBeRemoved2!=null) entries.remove(toBeRemoved2);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* if (interactingThread==-1) ret.addSleeper(thread);
|
||||||
|
else if (interactingThread==-2) {}
|
||||||
|
else if (interactingThread==thread){
|
||||||
|
ret.addResumer(thread);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
ret.addResumer(interactingThread);
|
||||||
|
ret.addResumer(thread);
|
||||||
|
}*/
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
//check if "waitenter before" and "waitexit after/or not available"
|
||||||
|
ResumeSleep broadcastResume(long broadcastTime, int thread) {
|
||||||
|
ResumeSleep ret = new ResumeSleep();
|
||||||
|
ArrayList<SynchType> toBeRemoved = new ArrayList<SynchType>();
|
||||||
|
for (SynchType entry : entries) {
|
||||||
|
if (entry.encoding == BCAST && entry.thread==thread) {
|
||||||
|
ret.addResumer(entry.thread);
|
||||||
|
toBeRemoved.add(entry);
|
||||||
|
}
|
||||||
|
boolean exitPresent = false;
|
||||||
|
if (entry.encoding == CONDWAIT && entry.time<broadcastTime && entry.thread!=thread) {
|
||||||
|
for (SynchType exit : entries) {
|
||||||
|
if (exit.encoding == CONDWAIT+1 && exit.time>broadcastTime && exit.thread==entry.thread) {
|
||||||
|
// resume these thread
|
||||||
|
ret.addResumer(exit.thread);
|
||||||
|
toBeRemoved.add(entry);
|
||||||
|
}
|
||||||
|
if (exit.encoding == CONDWAIT+1 && exit.time>entry.time) {
|
||||||
|
exitPresent = true;
|
||||||
|
// this means it is a stale entry
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!exitPresent) {
|
||||||
|
//no exit, ONLY enter, resume these as well
|
||||||
|
ret.addResumer(entry.thread);
|
||||||
|
toBeRemoved.add(entry);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for(SynchType rem : toBeRemoved) {
|
||||||
|
entries.remove(rem);
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
ResumeSleep broadcastEnter(int thread, long time, long value) {
|
||||||
|
if(debugMode)
|
||||||
|
System.out.println(this.address+" "+thread+" broadcastenter");
|
||||||
|
ResumeSleep ret = new ResumeSleep();
|
||||||
|
Hashtable<Integer, ThreadState> stateTable = IpcBase.glTable.getStateTable();
|
||||||
|
if (putOnTimedWait(thread, time, value)==0) {
|
||||||
|
//return all threads which were waiting to resume
|
||||||
|
ArrayList<SynchType> toBeRemoved = new ArrayList<SynchType>();
|
||||||
|
for (SynchType entry : entries ) {
|
||||||
|
if (entry.encoding == CONDWAIT && entry.time < time && entry.thread != thread) {
|
||||||
|
for (SynchType exit : entries) {
|
||||||
|
if (exit.encoding == CONDWAIT+1 && exit.time > time && exit.thread==entry.thread) {
|
||||||
|
ret.addResumer(exit.thread);
|
||||||
|
stateTable.get(exit.thread).addressMap.remove(address);
|
||||||
|
toBeRemoved.add(entry);
|
||||||
|
toBeRemoved.add(exit);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
stateTable.get(thread).addressMap.remove(address);
|
||||||
|
for (SynchType t : toBeRemoved) {
|
||||||
|
entries.remove(t);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
PerAddressInfoNew p = stateTable.get(thread).addressMap.get(address);
|
||||||
|
p.on_broadcast = true;
|
||||||
|
p.broadcastTime = time;
|
||||||
|
// Not all threads have passed in time.
|
||||||
|
entries.add(new SynchType(thread, time, value));
|
||||||
|
ret.addSleeper(thread);
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ResumeSleep barrierEnter(int thread, long time, long value) {
|
||||||
|
if(debugMode)
|
||||||
|
System.out.println(this.address+" "+thread+" barrierenter");
|
||||||
|
entries.add(new SynchType(thread, time, value));
|
||||||
|
ResumeSleep ret = new ResumeSleep();
|
||||||
|
ret.addSleeper(thread);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ResumeSleep barrierExit(int thread, long time, long value) {
|
||||||
|
if(debugMode)
|
||||||
|
System.out.println(this.address+" "+thread+" barrierexit");
|
||||||
|
Hashtable<Integer, ThreadState> stateTable = IpcBase.glTable.getStateTable();
|
||||||
|
ResumeSleep ret = new ResumeSleep();
|
||||||
|
if (putOnTimedWait(thread, time, value)==0) {
|
||||||
|
ArrayList<SynchType> toBeRemoved = new ArrayList<SynchType>();
|
||||||
|
for (SynchType entry : entries ) {
|
||||||
|
if (entry.encoding==BARRIERWAIT) {
|
||||||
|
ret.addResumer(entry.thread);
|
||||||
|
stateTable.get(entry.thread).addressMap.remove(address);
|
||||||
|
toBeRemoved.add(entry);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
stateTable.get(thread).addressMap.remove(address);
|
||||||
|
for (SynchType t : toBeRemoved) {
|
||||||
|
entries.remove(t);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
PerAddressInfoNew p = stateTable.get(thread).addressMap.get(address);
|
||||||
|
p.on_barrier = true;
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ResumeSleep barrierResume() {
|
||||||
|
ResumeSleep ret = new ResumeSleep();
|
||||||
|
ArrayList<SynchType> toBeRemoved = new ArrayList<SynchType>();
|
||||||
|
for (SynchType entry : entries) {
|
||||||
|
if (entry.encoding == BARRIERWAIT) {
|
||||||
|
ret.addResumer(entry.thread);
|
||||||
|
toBeRemoved.add(entry);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for(SynchType t : toBeRemoved) {
|
||||||
|
entries.remove(t);
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,15 @@
|
||||||
|
package emulatorinterface;
|
||||||
|
|
||||||
|
public class SynchType {
|
||||||
|
|
||||||
|
public SynchType(int thread, long time, long value) {
|
||||||
|
super();
|
||||||
|
this.thread = thread;
|
||||||
|
this.time = time;
|
||||||
|
this.encoding = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
int thread;
|
||||||
|
long time;
|
||||||
|
long encoding; // same as in Encoding.java
|
||||||
|
}
|
|
@ -0,0 +1,54 @@
|
||||||
|
package emulatorinterface;
|
||||||
|
|
||||||
|
public class ThreadBlockState {
|
||||||
|
public enum blockState{LIVE, BLOCK, INACTIVE};
|
||||||
|
blockState BlockState;
|
||||||
|
int encode;
|
||||||
|
public ThreadBlockState() {
|
||||||
|
// TODO Auto-generated constructor stub
|
||||||
|
this.BlockState=blockState.INACTIVE;
|
||||||
|
encode=-1;
|
||||||
|
}
|
||||||
|
blockState getState()
|
||||||
|
{
|
||||||
|
return BlockState;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param encode
|
||||||
|
* LOCK 14,15
|
||||||
|
* JOIN 18,19
|
||||||
|
* CONDWAIT 20,21
|
||||||
|
* BARRIERWAIT 22,23
|
||||||
|
*/
|
||||||
|
public void gotBlockingPacket(int encode)
|
||||||
|
{
|
||||||
|
switch(BlockState)
|
||||||
|
{
|
||||||
|
case LIVE: this.encode=encode; BlockState=blockState.BLOCK;break;
|
||||||
|
case BLOCK: this.encode=encode;break;
|
||||||
|
case INACTIVE: this.encode=encode; BlockState=blockState.BLOCK;break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Thread started receiving packets after blockage
|
||||||
|
*/
|
||||||
|
public void gotUnBlockingPacket()
|
||||||
|
{
|
||||||
|
switch(BlockState)
|
||||||
|
{
|
||||||
|
case LIVE: break;
|
||||||
|
case BLOCK: this.encode=-1;BlockState=blockState.LIVE;break;
|
||||||
|
case INACTIVE: this.encode=-1;BlockState=blockState.LIVE;break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void gotLive()
|
||||||
|
{
|
||||||
|
if(BlockState==blockState.INACTIVE)
|
||||||
|
{
|
||||||
|
BlockState=blockState.LIVE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,100 @@
|
||||||
|
package emulatorinterface;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Iterator;
|
||||||
|
import java.util.LinkedList;
|
||||||
|
|
||||||
|
class PerAddressInfo {
|
||||||
|
|
||||||
|
LinkedList<Integer> probableInteractors;
|
||||||
|
long timeSinceSlept;
|
||||||
|
long address;
|
||||||
|
boolean timedWait=false;
|
||||||
|
|
||||||
|
|
||||||
|
public PerAddressInfo(LinkedList<Integer> tentativeInteractors,
|
||||||
|
long time,long address,boolean timedWait) {
|
||||||
|
super();
|
||||||
|
this.probableInteractors = tentativeInteractors;
|
||||||
|
this.timeSinceSlept = time;
|
||||||
|
this.address = address;
|
||||||
|
this.timedWait = timedWait;
|
||||||
|
}
|
||||||
|
|
||||||
|
public LinkedList<Integer> getTentativeInteractors() {
|
||||||
|
return probableInteractors;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTentativeInteractors(LinkedList<Integer> tentativeInteractors) {
|
||||||
|
this.probableInteractors = tentativeInteractors;
|
||||||
|
}
|
||||||
|
|
||||||
|
public long getTime() {
|
||||||
|
return timeSinceSlept;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTime(long time) {
|
||||||
|
this.timeSinceSlept = time;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public class ThreadState {
|
||||||
|
int threadIndex;
|
||||||
|
int countTimedSleep=0;
|
||||||
|
long lastTimerseen=(long)-1>>>1;
|
||||||
|
//boolean timedWait=false;
|
||||||
|
HashMap <Long,PerAddressInfoNew> addressMap = new HashMap<Long,PerAddressInfoNew>();
|
||||||
|
|
||||||
|
public ThreadState(int tid){
|
||||||
|
this.threadIndex = tid;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void removeDep(long address) {
|
||||||
|
addressMap.remove((Long)address);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void removeDep(int tidApp) {
|
||||||
|
//for (PerAddressInfo pai : addressMap.values()) {
|
||||||
|
for (Iterator<PerAddressInfoNew> iter = addressMap.values().iterator(); iter.hasNext();) {
|
||||||
|
PerAddressInfoNew pai = (PerAddressInfoNew) iter.next();
|
||||||
|
pai.probableInteractors.remove((Integer)tidApp);
|
||||||
|
if (pai.probableInteractors.size()==0) {
|
||||||
|
iter.remove();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addDep(long address, long time, int thread) {
|
||||||
|
PerAddressInfoNew opai;
|
||||||
|
if ((opai = this.addressMap.get(address)) != null) {
|
||||||
|
opai.probableInteractors.add(thread);
|
||||||
|
//opai.timeSinceSlept = time;
|
||||||
|
} else {
|
||||||
|
LinkedList<Integer> th = new LinkedList<Integer>();
|
||||||
|
th.add(thread);
|
||||||
|
this.addressMap.put(address,
|
||||||
|
new PerAddressInfoNew(th, -1, address, false));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
public long timeSlept(long address) {
|
||||||
|
return addressMap.get(address).timeSinceSlept;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isOntimedWait() {
|
||||||
|
boolean ret = false;
|
||||||
|
for (PerAddressInfoNew pai : addressMap.values()) {
|
||||||
|
ret = ret || pai.timedWait;
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isOntimedWaitAt(long address) {
|
||||||
|
if (addressMap.get(address) == null) return false;
|
||||||
|
else return addressMap.get(address).timedWait;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,26 @@
|
||||||
|
package emulatorinterface;
|
||||||
|
|
||||||
|
import java.util.Comparator;
|
||||||
|
import java.util.HashMap;
|
||||||
|
|
||||||
|
public class UnhandledInsnCountComparator implements Comparator<Long> {
|
||||||
|
|
||||||
|
public UnhandledInsnCountComparator(HashMap<Long, Long> hashMap) {
|
||||||
|
super();
|
||||||
|
this.hashMap = hashMap;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
HashMap<Long,Long> hashMap;
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int compare(Long arg0, Long arg1) {
|
||||||
|
if (hashMap.get(arg0) >= hashMap.get(arg1)) {
|
||||||
|
return -1;
|
||||||
|
} else {
|
||||||
|
return 1;
|
||||||
|
} // returning 0 would merge keys
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,128 @@
|
||||||
|
package emulatorinterface.communication;
|
||||||
|
|
||||||
|
public class CustomAsmCharPool {
|
||||||
|
byte pool[][][];
|
||||||
|
int head[];
|
||||||
|
int tail[];
|
||||||
|
final int bufferSize = 2*1024;
|
||||||
|
|
||||||
|
public CustomAsmCharPool(int maxApplicationThreads)
|
||||||
|
{
|
||||||
|
pool = new byte[maxApplicationThreads][bufferSize][64];
|
||||||
|
head = new int[maxApplicationThreads];
|
||||||
|
tail = new int[maxApplicationThreads];
|
||||||
|
for(int tidApp=0; tidApp<maxApplicationThreads; tidApp++) {
|
||||||
|
head[tidApp] = tail[tidApp] = -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void enqueue(int tidApp, byte inputBytes[], int offset)
|
||||||
|
{
|
||||||
|
// System.out.println("enqueue : " + new String(inputBytes, offset, 64));
|
||||||
|
|
||||||
|
if(isFull(tidApp)) {
|
||||||
|
misc.Error.showErrorAndExit("unable to handle new asm bytes");
|
||||||
|
}
|
||||||
|
|
||||||
|
tail[tidApp] = (tail[tidApp]+1)%bufferSize;
|
||||||
|
//pool[tidApp][tail[tidApp]] = newBytes
|
||||||
|
for(int i=0; i<64; i++) {
|
||||||
|
if( (offset+i) < inputBytes.length) {
|
||||||
|
pool[tidApp][tail[tidApp]][i] = inputBytes[offset+i];
|
||||||
|
} else {//asm packets for filePacket interface may have less than 64 characters
|
||||||
|
pool[tidApp][tail[tidApp]][i] = (byte)0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(head[tidApp]==-1) {
|
||||||
|
head[tidApp] = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public byte[] dequeue(int tidApp)
|
||||||
|
{
|
||||||
|
if(isEmpty(tidApp)) {
|
||||||
|
misc.Error.showErrorAndExit("pool underflow !!");
|
||||||
|
}
|
||||||
|
|
||||||
|
byte[] toBeReturned = pool[tidApp][head[tidApp]];
|
||||||
|
|
||||||
|
if(head[tidApp] == tail[tidApp]) {
|
||||||
|
head[tidApp] = -1;
|
||||||
|
tail[tidApp] = -1;
|
||||||
|
} else {
|
||||||
|
head[tidApp] = (head[tidApp] + 1)%bufferSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
// System.out.println("dequeue : " + new String(toBeReturned, 0, 64));
|
||||||
|
return toBeReturned;
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean isEmpty(int tidApp) {
|
||||||
|
if(head[tidApp]==-1) {
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public int size(int tidApp)
|
||||||
|
{
|
||||||
|
if(head[tidApp] == -1)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if(head[tidApp] <= tail[tidApp])
|
||||||
|
{
|
||||||
|
return (tail[tidApp] - head[tidApp] + 1);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return (bufferSize - head[tidApp] + tail[tidApp] + 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void clear(int tidApp) {
|
||||||
|
head[tidApp]=tail[tidApp]=-1;
|
||||||
|
}
|
||||||
|
|
||||||
|
//position refers to logical position in queue - NOT array index
|
||||||
|
public byte[] peek(int tidApp, int position)
|
||||||
|
{
|
||||||
|
if(size(tidApp) <= position)
|
||||||
|
{
|
||||||
|
misc.Error.showErrorAndExit("pool underflow");
|
||||||
|
}
|
||||||
|
|
||||||
|
int peekIndex = (head[tidApp] + position)%bufferSize;
|
||||||
|
return pool[tidApp][peekIndex];
|
||||||
|
}
|
||||||
|
|
||||||
|
public byte[] front(int tidApp)
|
||||||
|
{
|
||||||
|
return peek(tidApp, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isFull(int tidApp)
|
||||||
|
{
|
||||||
|
if((tail[tidApp] + 1)%bufferSize == head[tidApp])
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public int currentPosition(int tidApp) {
|
||||||
|
if(isEmpty(tidApp)) {
|
||||||
|
return 0;
|
||||||
|
} else if (head[tidApp]<=tail[tidApp]) {
|
||||||
|
return (tail[tidApp]-head[tidApp]+1);
|
||||||
|
} else {
|
||||||
|
return (bufferSize-(head[tidApp]-tail[tidApp]-1));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,45 @@
|
||||||
|
package emulatorinterface.communication;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// change encoding.h if any change here.
|
||||||
|
public interface Encoding {
|
||||||
|
|
||||||
|
static final int THREADCOMPLETE = -1;
|
||||||
|
static final int SUBSETSIMCOMPLETE = -2;
|
||||||
|
|
||||||
|
static final int MEMREAD = 2;
|
||||||
|
static final int MEMWRITE = 3;
|
||||||
|
static final int TAKEN = 4;
|
||||||
|
static final int NOTTAKEN = 5;
|
||||||
|
static final int REGREAD = 6;
|
||||||
|
static final int REGWRITE = 7;
|
||||||
|
|
||||||
|
static final int TIMER = 8;
|
||||||
|
|
||||||
|
// synchronization values should be between SYNCHSTART AND SYNCHEND
|
||||||
|
// The values are for corresponding "enter". For "exit" the value is
|
||||||
|
// 1+enter value. i.e. for example LOCK enter is 14 and LOCK exit is 15
|
||||||
|
static final int SYNCHSTART = 9;
|
||||||
|
static final int BCAST = 10;
|
||||||
|
static final int SIGNAL = 12;
|
||||||
|
static final int LOCK = 14;
|
||||||
|
static final int UNLOCK = 16;
|
||||||
|
static final int JOIN = 18;
|
||||||
|
static final int CONDWAIT = 20;
|
||||||
|
static final int BARRIERWAIT = 22;
|
||||||
|
static final int SYNCHEND = 24;
|
||||||
|
static final int BARRIERINIT = 26;
|
||||||
|
|
||||||
|
// An instruction can have two assembly
|
||||||
|
static final int ASSEMBLY = 27;
|
||||||
|
static final int INSTRUCTION = 28;
|
||||||
|
|
||||||
|
static final int INTERRUPT = 30;
|
||||||
|
static final int PROCESS_SWITCH = 31;
|
||||||
|
static final int DOM_SWITCH = 32;
|
||||||
|
static final int CPL_SWITCH = 34;
|
||||||
|
static final int PARENT_SPAWN = 35;
|
||||||
|
static final int CHILD_START = 36;
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,61 @@
|
||||||
|
/*
|
||||||
|
* Here is the base class for the IPC mechanisms. Any new IPC mechanism should implement the
|
||||||
|
* declared virtual functions. Also any variable common or independent of IPC mechanism should
|
||||||
|
* be declared here
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef H_include_IPC
|
||||||
|
#define H_include_IPC
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <iostream>
|
||||||
|
#include "common.h"
|
||||||
|
|
||||||
|
// This must be equal to the MAXNUMTHREADS*EMUTHREADS in IPCBase.java file. This is
|
||||||
|
// important so that we attach to the same sized memory segment
|
||||||
|
//#define MaxNumThreads (64)
|
||||||
|
#define MaxThreads (10000)
|
||||||
|
|
||||||
|
namespace IPC
|
||||||
|
{
|
||||||
|
|
||||||
|
class IPCBase
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
int MaxNumActiveThreads;
|
||||||
|
void (*lock)(int);
|
||||||
|
void (*unlock)(int);
|
||||||
|
|
||||||
|
// Initialise buffers or other stuffs related to IPC mechanisms
|
||||||
|
IPCBase(int maxNumActiveThreads, void (*lock)(int), void (*unlock)(int)){MaxNumActiveThreads = maxNumActiveThreads; this->lock=lock; this->unlock=unlock;}
|
||||||
|
|
||||||
|
// Fill the packet struct when doing analysis and send to Java process. This is the
|
||||||
|
// most important function
|
||||||
|
virtual int analysisFn (int tid,uint64_t ip, uint64_t value, uint64_t tgt)=0;
|
||||||
|
|
||||||
|
// Fill the packet struct when doing analysis and send to Java process. This is the
|
||||||
|
// most important function
|
||||||
|
virtual int analysisFnAssembly (int tid,uint64_t ip, uint64_t value, char *asmString)=0;
|
||||||
|
|
||||||
|
// Things to be done when a thread is started in PIN/ application
|
||||||
|
virtual void onThread_start (int tid)=0;
|
||||||
|
|
||||||
|
// Things to be done when a thread is finished in PIN/ application
|
||||||
|
virtual int onThread_finish (int tid, long numCISC)=0;
|
||||||
|
|
||||||
|
// Things to be done when subset simulation is finished in PIN/ application
|
||||||
|
virtual int onSubset_finish (int tid, long numCISC)=0;
|
||||||
|
|
||||||
|
virtual bool isSubsetsimCompleted(void)=0;
|
||||||
|
virtual bool setSubsetsimComplete(bool val)=0;
|
||||||
|
|
||||||
|
// Deallocate any memory, delete any buffers, shared memory, semaphores
|
||||||
|
virtual bool unload ()=0;
|
||||||
|
|
||||||
|
virtual ~IPCBase() {}
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
|
@ -0,0 +1,129 @@
|
||||||
|
/*
|
||||||
|
* This file declares some parameters which is common to all IPC mechanisms. Every IPC mechanism
|
||||||
|
* inherits this class and implements the functions declared. Since Java has runtime binding
|
||||||
|
* so the corresponding methods will be called.
|
||||||
|
*
|
||||||
|
* MAXNUMTHREADS - The maximum number of java threads running
|
||||||
|
* EMUTHREADS - The number of emulator threads 1 java thread is reading from
|
||||||
|
* COUNT - this many number of packets is allocated in the shared memory for each
|
||||||
|
* application/emulator thread
|
||||||
|
* */
|
||||||
|
|
||||||
|
package emulatorinterface.communication;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.concurrent.Semaphore;
|
||||||
|
|
||||||
|
import config.SystemConfig;
|
||||||
|
|
||||||
|
import emulatorinterface.GlobalTable;
|
||||||
|
import emulatorinterface.RunnableThread;
|
||||||
|
import generic.CircularPacketQueue;
|
||||||
|
import generic.GenericCircularQueue;
|
||||||
|
|
||||||
|
public abstract class IpcBase {
|
||||||
|
|
||||||
|
// Must ensure that MAXNUMTHREADS*EMUTHREADS == MaxNumThreads on the PIN side
|
||||||
|
// Do not move it to config file unless you can satisfy the first constraint
|
||||||
|
//public static final int MaxNumJavaThreads = 1;
|
||||||
|
//public static final int EmuThreadsPerJavaThread = 64;
|
||||||
|
// public static int memMapping[] = new int[EmuThreadsPerJavaThread];
|
||||||
|
|
||||||
|
// state management for reader threads
|
||||||
|
public boolean[] javaThreadTermination;
|
||||||
|
public boolean[] javaThreadStarted;
|
||||||
|
|
||||||
|
// number of instructions read by each of the threads
|
||||||
|
// public long[] numInstructions = new long[MaxNumJavaThreads];
|
||||||
|
|
||||||
|
// to maintain synchronization between main thread and the reader threads
|
||||||
|
public static final Semaphore free = new Semaphore(0, true);
|
||||||
|
|
||||||
|
// public static InstructionTable insTable;
|
||||||
|
public static GlobalTable glTable;
|
||||||
|
|
||||||
|
// Initialise structures and objects
|
||||||
|
public IpcBase () {
|
||||||
|
|
||||||
|
javaThreadTermination = new boolean[SystemConfig.maxNumJavaThreads];
|
||||||
|
javaThreadStarted = new boolean[SystemConfig.maxNumJavaThreads];
|
||||||
|
|
||||||
|
for (int i=0; i<SystemConfig.maxNumJavaThreads; i++) {
|
||||||
|
javaThreadTermination[i]=false;
|
||||||
|
javaThreadStarted[i]=false;
|
||||||
|
//TODO not all cores are assigned to each thread
|
||||||
|
//when the mechanism to tie threads to cores is in place
|
||||||
|
//this has to be changed
|
||||||
|
}
|
||||||
|
|
||||||
|
glTable = new GlobalTable(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
public abstract void initIpc();
|
||||||
|
|
||||||
|
/*** start, finish, isEmpty, fetchPacket, isTerminated ****/
|
||||||
|
public RunnableThread[] getRunnableThreads(){
|
||||||
|
System.out.println("Implement getRunnableThreads() in the IPC mechanism");
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// returns the numberOfPackets which are currently there in the stream for tidApp
|
||||||
|
//the runnable thread does not require the numPackets in stream
|
||||||
|
//public abstract int numPackets(int tidApp);
|
||||||
|
|
||||||
|
// fetch one packet for tidApp from index.
|
||||||
|
// fetchPacket creates a Packet structure which will strain the garbage collector.
|
||||||
|
// Hence, this method is no longer supported.
|
||||||
|
//public abstract Packet fetchOnePacket(int tidApp, int index);
|
||||||
|
|
||||||
|
//public abstract int fetchManyPackets(int tidApp, int readerLocation, int numReads,ArrayList<Packet> fromPIN);
|
||||||
|
public abstract int fetchManyPackets(int tidApp, CircularPacketQueue fromEmulator);
|
||||||
|
|
||||||
|
//public abstract long update(int tidApp, int numReads);
|
||||||
|
// The main thread waits for the finish of reader threads and returns total number of
|
||||||
|
// instructions read
|
||||||
|
|
||||||
|
// return the total packets produced by PIN till now
|
||||||
|
//public abstract long totalProduced(int tidApp);
|
||||||
|
|
||||||
|
public abstract void errorCheck(int tidApp, long totalReads);
|
||||||
|
|
||||||
|
public void waitForJavaThreads() {
|
||||||
|
|
||||||
|
try {
|
||||||
|
// this takes care if no thread started yet.
|
||||||
|
free.acquire();
|
||||||
|
|
||||||
|
int j=0;
|
||||||
|
// if any thread has started and not finished then wait.
|
||||||
|
for (int i=0; i<SystemConfig.maxNumJavaThreads; i++) {
|
||||||
|
if (javaThreadStarted[i] && !javaThreadTermination[i]) {
|
||||||
|
free.acquire();
|
||||||
|
j++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//inform threads which have not started about finish
|
||||||
|
for (int i=0; i<SystemConfig.maxNumJavaThreads; i++) {
|
||||||
|
if (javaThreadStarted[i]==false) {
|
||||||
|
javaThreadTermination[i]=true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (; j<SystemConfig.maxNumJavaThreads-1; j++) {
|
||||||
|
free.acquire();
|
||||||
|
}
|
||||||
|
} catch (InterruptedException ioe) {
|
||||||
|
misc.Error.showErrorAndExit("Wait for java threads interrupted !!");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Free buffers, free memory , deallocate any stuff.
|
||||||
|
public void finish() {
|
||||||
|
System.out.println("Implement finish in the IPC mechanism");
|
||||||
|
}
|
||||||
|
|
||||||
|
public static int getEmuThreadsPerJavaThread() {
|
||||||
|
return SystemConfig.numEmuThreadsPerJavaThread;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,55 @@
|
||||||
|
package emulatorinterface.communication;
|
||||||
|
|
||||||
|
// This is very hardbound to the jni C file. in the shmread function.Update JNIShm.c if any changes
|
||||||
|
// are made here
|
||||||
|
public class Packet
|
||||||
|
{
|
||||||
|
// If info packetList then ip represents instruction pointer and tgt represents the target addr/mem
|
||||||
|
// address. Else if synchronization packetList then ip represents time and tgt represents lock
|
||||||
|
// address. Else if timer packetList then ip represents time and tgt represents nothing.
|
||||||
|
|
||||||
|
// For a qemu packetList containing assembly of instruction, tgt indicates the size of the assembly string
|
||||||
|
public long ip;
|
||||||
|
public long value;
|
||||||
|
public long tgt;
|
||||||
|
|
||||||
|
public Packet ()
|
||||||
|
{
|
||||||
|
ip = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Packet(long ip, long value, long tgt)
|
||||||
|
{
|
||||||
|
this.ip = ip;
|
||||||
|
this.value = value;
|
||||||
|
this.tgt = tgt;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "Packet [ip=" + Long.toHexString(ip).toLowerCase() + ", tgt=" + tgt + ", value=" + value + "]";
|
||||||
|
}
|
||||||
|
|
||||||
|
public void set(long ip, long value, long tgt) {
|
||||||
|
this.ip = ip;
|
||||||
|
this.value = value;
|
||||||
|
this.tgt = tgt;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void set(Packet p) {
|
||||||
|
this.ip = p.ip;
|
||||||
|
this.tgt = p.tgt;
|
||||||
|
this.value = p.value;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
public Long getTgt()
|
||||||
|
{
|
||||||
|
return tgt;
|
||||||
|
}
|
||||||
|
public Long getIp()
|
||||||
|
{
|
||||||
|
return ip;
|
||||||
|
}*/
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,51 @@
|
||||||
|
/* Threads need to eat up the streams generated by the Emulator which
|
||||||
|
* is being run through process.runtime. Just prints whatever it reads.
|
||||||
|
* NOTE currently inputstream for pintool(and outputstream for java)
|
||||||
|
* has not been constructed as we never needed it.
|
||||||
|
* TODO should ideally implement a StreamWriter as well which can be used to pass
|
||||||
|
* arguments to the executable or the PIN tool.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package emulatorinterface.communication;
|
||||||
|
|
||||||
|
import java.io.*;
|
||||||
|
|
||||||
|
public class StreamGobbler implements Runnable {
|
||||||
|
|
||||||
|
String name; //Threads name (stdin or stderr)
|
||||||
|
InputStream is;
|
||||||
|
Thread thread;
|
||||||
|
|
||||||
|
public StreamGobbler (String name, InputStream is) {
|
||||||
|
this.name = name;
|
||||||
|
this.is = is;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void start () {
|
||||||
|
thread = new Thread (this);
|
||||||
|
thread.start ();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void run () {
|
||||||
|
try {
|
||||||
|
InputStreamReader isr = new InputStreamReader (is);
|
||||||
|
BufferedReader br = new BufferedReader (isr);
|
||||||
|
|
||||||
|
while (true) {
|
||||||
|
String s = br.readLine ();
|
||||||
|
if (s == null) break;
|
||||||
|
System.out.println("[" + name + "] " + s);
|
||||||
|
}
|
||||||
|
|
||||||
|
is.close ();
|
||||||
|
|
||||||
|
} catch (Exception ex) {
|
||||||
|
System.out.println("Problem reading stream " + name + "... :" + ex);
|
||||||
|
ex.printStackTrace ();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void join() throws InterruptedException{
|
||||||
|
thread.join();
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,39 @@
|
||||||
|
/*
|
||||||
|
*This file is included in the PIN tool and the C file of the javareader
|
||||||
|
*It defines some common parameters/structures which are common to simulator and emulator.
|
||||||
|
*/
|
||||||
|
#ifndef H_include_common
|
||||||
|
#define H_include_common
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#define ftokpath ("/tmp")
|
||||||
|
#define ftok_id (6)
|
||||||
|
|
||||||
|
//NOTE We have not included the parameters size and maxnumthreads here as they are
|
||||||
|
//needed by the java file too. So, to change these values update IPCBase.h
|
||||||
|
|
||||||
|
//for size of the shared memory segment we specify COUNT of packets.
|
||||||
|
//the shared memory segment size allocated is (COUNT+5)*sizeof(packet)*MaxNumThread
|
||||||
|
//COUNT- queue_size
|
||||||
|
//COUNT+1 - flag[0] of peterson lock
|
||||||
|
//COUNT+2 - flag[1] of peterson lock
|
||||||
|
//COUNT+3 - turn of peterson lock
|
||||||
|
//COUNT+4 - per thread number of packets produced
|
||||||
|
|
||||||
|
// the structure of the packet to be transferred via IPC
|
||||||
|
// its important to use uint64_t for ip so that different sizes on different
|
||||||
|
// platforms do not affect.
|
||||||
|
typedef struct{
|
||||||
|
uint64_t ip; /* address of instruction */
|
||||||
|
uint64_t volatile value; /* defines the encoding scheme,details in DynamicInstructionBuffer.java */
|
||||||
|
uint64_t tgt; /* value according to encoding scheme */
|
||||||
|
}packet;
|
||||||
|
|
||||||
|
union semun_pin {
|
||||||
|
int val; /* value for SETVAL */
|
||||||
|
struct semid_ds *buf; /* buffer for IPC_STAT, IPC_SET */
|
||||||
|
unsigned short int *array; /* array for GETALL, SETALL */
|
||||||
|
struct seminfo *__buf; /* buffer for IPC_INFO */
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
|
@ -0,0 +1,40 @@
|
||||||
|
/*
|
||||||
|
*This file is included in the PIN tool and the C file of the javareader
|
||||||
|
*It defines some common parameters/structures which are common to simulator and emulator.
|
||||||
|
*/
|
||||||
|
#ifndef H_include_common
|
||||||
|
#define H_include_common
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#define ftokpath ("/tmp")
|
||||||
|
#define ftok_id (6)
|
||||||
|
|
||||||
|
//NOTE We have not included the parameters size and maxnumthreads here as they are
|
||||||
|
//needed by the java file too. So, to change these values update IPCBase.h
|
||||||
|
|
||||||
|
//for size of the shared memory segment we specify COUNT of packets.
|
||||||
|
//the shared memory segment size allocated is (COUNT+5)*sizeof(packet)*MaxNumThread
|
||||||
|
//COUNT- queue_size
|
||||||
|
//COUNT+1 - flag[0] of peterson lock
|
||||||
|
//COUNT+2 - flag[1] of peterson lock
|
||||||
|
//COUNT+3 - turn of peterson lock
|
||||||
|
//COUNT+4 - per thread number of packets produced
|
||||||
|
|
||||||
|
// the structure of the packet to be transferred via IPC
|
||||||
|
// its important to use uint64_t for ip so that different sizes on different
|
||||||
|
// platforms do not affect.
|
||||||
|
typedef struct{
|
||||||
|
uint64_t ip; /* address of instruction */
|
||||||
|
uint64_t volatile value; /* defines the encoding scheme,details in DynamicInstructionBuffer.java */
|
||||||
|
uint64_t tgt; /* value according to encoding scheme */
|
||||||
|
}packet;
|
||||||
|
|
||||||
|
|
||||||
|
//union semun_pin {
|
||||||
|
// int val; /* value for SETVAL */
|
||||||
|
// struct semid_ds *buf; /* buffer for IPC_STAT, IPC_SET */
|
||||||
|
// unsigned short int *array; /* array for GETALL, SETALL */
|
||||||
|
// struct seminfo *__buf; /* buffer for IPC_INFO */
|
||||||
|
//};
|
||||||
|
|
||||||
|
#endif
|
|
@ -0,0 +1,224 @@
|
||||||
|
package emulatorinterface.communication.filePacket;
|
||||||
|
|
||||||
|
import java.io.BufferedReader;
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.FileInputStream;
|
||||||
|
import java.io.FileNotFoundException;
|
||||||
|
import java.io.FileReader;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStreamReader;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.StringTokenizer;
|
||||||
|
import java.util.zip.GZIPInputStream;
|
||||||
|
|
||||||
|
import main.CustomObjectPool;
|
||||||
|
import misc.Util;
|
||||||
|
|
||||||
|
import config.EmulatorConfig;
|
||||||
|
import config.EmulatorType;
|
||||||
|
import config.SimulationConfig;
|
||||||
|
import config.SystemConfig;
|
||||||
|
import emulatorinterface.communication.Encoding;
|
||||||
|
import emulatorinterface.communication.IpcBase;
|
||||||
|
import emulatorinterface.communication.Packet;
|
||||||
|
import generic.CircularPacketQueue;
|
||||||
|
|
||||||
|
//This communication type reads from a file containing instructions in the format "ip value tgt"
|
||||||
|
//where value is the type of the instruction and tgt is either assembly string(for assembly instruction)
|
||||||
|
//or a value for other instructions
|
||||||
|
public class FilePacket extends IpcBase implements Encoding {
|
||||||
|
|
||||||
|
BufferedReader inputBufferedReader[];
|
||||||
|
int maxApplicationThreads = -1;
|
||||||
|
long totalFetchedAssemblyPackets = 0;
|
||||||
|
ArrayList<Integer> pinpointWeights;
|
||||||
|
int cur_slice = 0;
|
||||||
|
String []basenameForBenchmarks;
|
||||||
|
|
||||||
|
public FilePacket(String []basenameForBenchmarks) {
|
||||||
|
this.maxApplicationThreads = SystemConfig.maxNumJavaThreads*SystemConfig.numEmuThreadsPerJavaThread;
|
||||||
|
this.basenameForBenchmarks = basenameForBenchmarks;
|
||||||
|
|
||||||
|
inputBufferedReader = new BufferedReader[maxApplicationThreads];
|
||||||
|
|
||||||
|
pinpointWeights = new ArrayList<Integer>();
|
||||||
|
if(SimulationConfig.pinpointsSimulation == true)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
BufferedReader pinpointsFile = new BufferedReader(new FileReader(SimulationConfig.pinpointsFile));
|
||||||
|
String line;
|
||||||
|
while((line = pinpointsFile.readLine()) != null)
|
||||||
|
{
|
||||||
|
pinpointWeights.add(Math.round(Float.parseFloat(line.split(" ")[1]) * 100));
|
||||||
|
}
|
||||||
|
pinpointsFile.close();
|
||||||
|
}
|
||||||
|
catch(Exception e)
|
||||||
|
{
|
||||||
|
misc.Error.showErrorAndExit(e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int numTotalThreads = 0;
|
||||||
|
for (int benchmark=0; benchmark<basenameForBenchmarks.length; benchmark++) {
|
||||||
|
for (int tid=0; ;tid++) {
|
||||||
|
String inputFileName;
|
||||||
|
if(SimulationConfig.pinpointsSimulation == false)
|
||||||
|
{
|
||||||
|
inputFileName = basenameForBenchmarks[benchmark] + "_" + tid + ".gz";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
inputFileName = basenameForBenchmarks[benchmark] + "_0_0.gz";
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
inputBufferedReader[numTotalThreads] = new BufferedReader(
|
||||||
|
new InputStreamReader(
|
||||||
|
new GZIPInputStream(
|
||||||
|
new FileInputStream(inputFileName))));
|
||||||
|
numTotalThreads++;
|
||||||
|
|
||||||
|
if(SimulationConfig.pinpointsSimulation == true)
|
||||||
|
{
|
||||||
|
//pinpoints is for single threaded applications only
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
if(tid==0) {
|
||||||
|
// not able to find first file is surely an error.
|
||||||
|
misc.Error.showErrorAndExit("Error in reading input packet file " + inputFileName);
|
||||||
|
} else {
|
||||||
|
System.out.println("Number of threads for benchmark " + basenameForBenchmarks[benchmark] + " : " + tid);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void initIpc() {
|
||||||
|
// this does nothing
|
||||||
|
}
|
||||||
|
|
||||||
|
public int fetchManyPackets(int tidApp, CircularPacketQueue fromEmulator) {
|
||||||
|
|
||||||
|
if(tidApp>=maxApplicationThreads) {
|
||||||
|
misc.Error.showErrorAndExit("FilePacket cannot handle tid = " + tidApp);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(inputBufferedReader[tidApp]==null) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int maxSize = fromEmulator.spaceLeft();
|
||||||
|
|
||||||
|
for(int i=0; i<maxSize; i++) {
|
||||||
|
|
||||||
|
try {
|
||||||
|
//Subset Simulation
|
||||||
|
if(SimulationConfig.subsetSimulation && totalFetchedAssemblyPackets >= (SimulationConfig.subsetSimSize + SimulationConfig.NumInsToIgnore)) {
|
||||||
|
fromEmulator.enqueue(totalFetchedAssemblyPackets-SimulationConfig.NumInsToIgnore, -2, -1);
|
||||||
|
return (i+1);
|
||||||
|
}
|
||||||
|
|
||||||
|
String inputLine = inputBufferedReader[tidApp].readLine();
|
||||||
|
|
||||||
|
if(inputLine != null) {
|
||||||
|
|
||||||
|
long ip = -1, value = -1, tgt = -1;
|
||||||
|
StringTokenizer stringTokenizer = new StringTokenizer(inputLine);
|
||||||
|
|
||||||
|
ip = Util.parseLong(stringTokenizer.nextToken());
|
||||||
|
value = Long.parseLong(stringTokenizer.nextToken());
|
||||||
|
|
||||||
|
if(value!=ASSEMBLY) {
|
||||||
|
tgt = Util.parseLong(stringTokenizer.nextToken());
|
||||||
|
} else {
|
||||||
|
totalFetchedAssemblyPackets += 1;
|
||||||
|
|
||||||
|
if(totalFetchedAssemblyPackets%1000000==0) {
|
||||||
|
System.out.println("Number of assembly instructions till now : " + totalFetchedAssemblyPackets);
|
||||||
|
}
|
||||||
|
|
||||||
|
tgt = -1;
|
||||||
|
CustomObjectPool.getCustomAsmCharPool().enqueue(tidApp, stringTokenizer.nextToken("\n").getBytes(), 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
//ignore these many instructions: NumInsToIgnore
|
||||||
|
if(totalFetchedAssemblyPackets < SimulationConfig.NumInsToIgnore) {
|
||||||
|
if(value == ASSEMBLY) {
|
||||||
|
CustomObjectPool.getCustomAsmCharPool().dequeue(tidApp);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
// totalFetchedAssemblyPackets just became equal to NumInsToIgnore, so
|
||||||
|
// we start setting fromEmulator packets
|
||||||
|
} else if(totalFetchedAssemblyPackets == SimulationConfig.NumInsToIgnore && value==ASSEMBLY) {
|
||||||
|
i=0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(SimulationConfig.pinpointsSimulation == false)
|
||||||
|
{
|
||||||
|
fromEmulator.enqueue(ip, value, tgt);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if(value != Encoding.SUBSETSIMCOMPLETE)
|
||||||
|
{
|
||||||
|
fromEmulator.enqueue(ip, value, tgt);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
inputBufferedReader[tidApp].close();
|
||||||
|
pinpointWeights.set(cur_slice, pinpointWeights.get(cur_slice)-1);
|
||||||
|
while(cur_slice < pinpointWeights.size() && pinpointWeights.get(cur_slice) <= 0)
|
||||||
|
{
|
||||||
|
cur_slice++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(cur_slice >= pinpointWeights.size())
|
||||||
|
{
|
||||||
|
fromEmulator.enqueue(ip, value, tgt);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
inputBufferedReader[tidApp] = new BufferedReader(
|
||||||
|
new InputStreamReader(
|
||||||
|
new GZIPInputStream(
|
||||||
|
new FileInputStream(basenameForBenchmarks[tidApp] + "_" + cur_slice + "_0.gz"))));
|
||||||
|
System.out.println("opening file: " + basenameForBenchmarks[tidApp] + "_" + cur_slice + "_0.gz");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return (i);
|
||||||
|
}
|
||||||
|
} catch (IOException e) {
|
||||||
|
// We are expecting an end of file exception at the end of the trace.
|
||||||
|
// Lets return the number of elements read till now.
|
||||||
|
// Hopefully some thread will contain a subset simulation complete packet
|
||||||
|
//System.out.println("Thread " + tidApp + " 's trace file has completed");
|
||||||
|
return i;
|
||||||
|
// misc.Error.showErrorAndExit("error in reading from file for tid = " + tidApp + "\n" + e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return maxSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void errorCheck(int tidApp, long totalReads) {
|
||||||
|
// we do not do any error checking for filePacket interface
|
||||||
|
}
|
||||||
|
|
||||||
|
public void finish() {
|
||||||
|
for(int i=0; i<maxApplicationThreads; i++) {
|
||||||
|
try {
|
||||||
|
if(inputBufferedReader[i] != null) {
|
||||||
|
inputBufferedReader[i].close();
|
||||||
|
}
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,121 @@
|
||||||
|
package emulatorinterface.communication.filePacket;
|
||||||
|
import java.io.BufferedReader;
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.FileOutputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.Hashtable;
|
||||||
|
import java.util.zip.GZIPInputStream;
|
||||||
|
import java.util.zip.GZIPOutputStream;
|
||||||
|
import java.util.zip.ZipEntry;
|
||||||
|
import java.util.zip.ZipOutputStream;
|
||||||
|
import main.Main;
|
||||||
|
import misc.Numbers;
|
||||||
|
import emulatorinterface.translator.x86.objparser.*;
|
||||||
|
import emulatorinterface.translator.x86.operand.OperandTranslator;
|
||||||
|
import emulatorinterface.translator.x86.registers.TempRegisterNum;
|
||||||
|
import generic.InstructionList;
|
||||||
|
import generic.Operand;
|
||||||
|
import emulatorinterface.translator.InvalidInstructionException;
|
||||||
|
|
||||||
|
|
||||||
|
public class FileWrite {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param args
|
||||||
|
* @throws IOException
|
||||||
|
*/
|
||||||
|
/*public static void main(String[] args) throws IOException {*/
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
String basefilename;
|
||||||
|
int maxnumofactivethreads;
|
||||||
|
BufferedReader input;
|
||||||
|
Hashtable<Long, StringBuilder> hashtable;
|
||||||
|
String line;
|
||||||
|
long instructionPointer;
|
||||||
|
String operation = null;
|
||||||
|
String operand1 = null, operand2 = null, operand3 = null;
|
||||||
|
|
||||||
|
StringBuilder sb = new StringBuilder();
|
||||||
|
|
||||||
|
public FileWrite(int maxNumActiveThreads, String baseFileName){
|
||||||
|
basefilename=new String(baseFileName);
|
||||||
|
maxnumofactivethreads=maxNumActiveThreads;
|
||||||
|
//System.out.println(basefilename+"***********************");
|
||||||
|
|
||||||
|
String exec=Main.getEmulatorFile();
|
||||||
|
input = ObjParser.readObjDumpOutput(exec);
|
||||||
|
hashtable=new Hashtable<Long, StringBuilder>();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
while ((line = ObjParser.readNextLineOfObjDump(input)) != null)
|
||||||
|
{
|
||||||
|
if (!(ObjParser.isContainingObjDumpAssemblyCode(line))) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
String assemblyCodeTokens[] = ObjParser.tokenizeObjDumpAssemblyCode(line);
|
||||||
|
|
||||||
|
// read the assembly code tokens
|
||||||
|
instructionPointer = Numbers.hexToLong(assemblyCodeTokens[0]);
|
||||||
|
|
||||||
|
//instructionPrefix = assemblyCodeTokens[1];
|
||||||
|
operation = assemblyCodeTokens[2];
|
||||||
|
operand1 = assemblyCodeTokens[3];
|
||||||
|
operand2 = assemblyCodeTokens[4];
|
||||||
|
operand3 = assemblyCodeTokens[5];
|
||||||
|
StringBuilder asm=new StringBuilder();
|
||||||
|
|
||||||
|
if(operand1!=null&& operand1.contains("<")) {
|
||||||
|
String[] temp=operand1.split(" ");
|
||||||
|
operand1=temp[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
if(operand1==null)
|
||||||
|
asm.append(operation);
|
||||||
|
else if(operand2==null)
|
||||||
|
{ asm.append(operation+" "+operand1);
|
||||||
|
|
||||||
|
}else if(operand3==null)
|
||||||
|
asm.append(operation+" "+operand1+","+operand2);
|
||||||
|
else {
|
||||||
|
asm.append(operation+" "+operand1+","+operand2+","+operand3);
|
||||||
|
}
|
||||||
|
|
||||||
|
hashtable.put(instructionPointer, asm);
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void printToFileIpValAddr(int tid,Long ip,Long val, Long addr, StringBuilder asmstring) throws IOException{
|
||||||
|
if(val!=27)
|
||||||
|
sb.append(ip+" "+ val+" "+ addr+"\n");
|
||||||
|
else
|
||||||
|
sb.append(ip+" "+ val+" "+ asmstring+"\n");
|
||||||
|
File f = new File(basefilename+"_"+tid+".gz");
|
||||||
|
GZIPOutputStream out = new GZIPOutputStream(new FileOutputStream(f));
|
||||||
|
|
||||||
|
byte[] data = sb.toString().getBytes();
|
||||||
|
out.write(data, 0, data.length);
|
||||||
|
|
||||||
|
|
||||||
|
out.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void analysisFn (int tid,Long ip, Long val, Long addr, StringBuilder asmstring) throws IOException, InvalidInstructionException
|
||||||
|
{ if(val==8) {
|
||||||
|
//timer instructions
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if(val!=28) {
|
||||||
|
printToFileIpValAddr(tid, ip, val, addr,asmstring);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if(hashtable.containsKey(ip))
|
||||||
|
|
||||||
|
printToFileIpValAddr(tid, ip, 27L, addr,hashtable.get(ip));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,204 @@
|
||||||
|
#include "filePacket.h"
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#ifdef _WIN32
|
||||||
|
#include <Windows.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#else
|
||||||
|
#include <sys/ipc.h>
|
||||||
|
#include <sys/sem.h>
|
||||||
|
#include <sys/shm.h>
|
||||||
|
#include <sys/msg.h>
|
||||||
|
#include <sys/syscall.h>
|
||||||
|
#include <pthread.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#endif
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <errno.h>
|
||||||
|
|
||||||
|
namespace IPC
|
||||||
|
{
|
||||||
|
|
||||||
|
char *basefileNamePublic;
|
||||||
|
|
||||||
|
FilePacket::FilePacket(int maxNumActiveThreads, const char *baseFileName, void (*lock)(int), void (*unlock)(int)) : IPCBase(maxNumActiveThreads, lock, unlock)
|
||||||
|
{
|
||||||
|
basefileNamePublic = new char[1000];
|
||||||
|
strcpy(basefileNamePublic, baseFileName);
|
||||||
|
|
||||||
|
this->maxNumActiveThreads = maxNumActiveThreads;
|
||||||
|
isSubsetsimComplete = false;
|
||||||
|
|
||||||
|
// If there is an existing file which can be overlapped due to the execution of pintool,
|
||||||
|
// flag an error and exit
|
||||||
|
for(int tid=0; tid<maxNumActiveThreads; tid++) {
|
||||||
|
char fileName[1000];
|
||||||
|
sprintf(fileName, "%s_%d.gz", baseFileName, tid);
|
||||||
|
FILE *f = fopen(fileName, "r");
|
||||||
|
if(f!=NULL) {
|
||||||
|
printf("Cannot overwrite an existing trace file : %s\n", fileName);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
getFiles();
|
||||||
|
|
||||||
|
// Initialize the files array
|
||||||
|
for(int tid=0; tid<maxNumActiveThreads; tid++) {
|
||||||
|
files[tid] = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
FilePacket::getFiles(){
|
||||||
|
|
||||||
|
#ifndef _WIN32
|
||||||
|
files = new gzFile[maxNumActiveThreads];
|
||||||
|
#else
|
||||||
|
files = new FILE*[maxNumActiveThreads];
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
FilePacket::printToFileIpValAddr(int tid,uint64_t ip, uint64_t val, uint64_t addr){
|
||||||
|
#ifndef _WIN32
|
||||||
|
gzprintf(files[tid], "%ld %ld %ld\n", ip, val, addr);
|
||||||
|
#else
|
||||||
|
fprintf(files[tid],"%ld %ld %ld\n", ip, val, addr);
|
||||||
|
fflush(files[tid]);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
FilePacket::printToFileIpValAsmString(int tid,uint64_t ip, uint64_t val, char *asmString){
|
||||||
|
#ifndef _WIN32
|
||||||
|
gzprintf(files[tid], "%ld %ld %s\n", ip, val, asmString);
|
||||||
|
#else
|
||||||
|
fprintf(files[tid], "%ld %ld %s\n", ip, val, asmString);
|
||||||
|
fflush(files[tid]);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
FilePacket::createPacketFileForThread(int tid)
|
||||||
|
{
|
||||||
|
#ifndef _WIN32
|
||||||
|
if(files[tid]==NULL) {
|
||||||
|
char fileName[1000];
|
||||||
|
sprintf(fileName, "%s_%d.gz", basefileNamePublic, tid);
|
||||||
|
|
||||||
|
FILE *fd = fopen(fileName, "w");
|
||||||
|
if(fd==NULL) {
|
||||||
|
perror("error in creating file !! ");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
files[tid] = gzdopen(fileno(fd), "w6");
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
if(files[tid]==NULL) {
|
||||||
|
char fileName[1000];
|
||||||
|
sprintf(fileName, "%s_%d", basefileNamePublic, tid);
|
||||||
|
|
||||||
|
files[tid] = fopen(fileName, "w");
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* If local queue is full, write to the shared memory and then write to localQueue.
|
||||||
|
* else just write at localQueue at the appropriate index i.e. at 'in'
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
FilePacket::analysisFn (int tid,uint64_t ip, uint64_t val, uint64_t addr)
|
||||||
|
{
|
||||||
|
(*lock)(tid);
|
||||||
|
createPacketFileForThread(tid);
|
||||||
|
if(val==INSTRUCTION) {
|
||||||
|
printf("Error in writing INSTRUCTION packet to trace file !!");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
printToFileIpValAddr(tid, ip, val, addr);
|
||||||
|
(*unlock)(tid);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int
|
||||||
|
FilePacket::analysisFnAssembly (int tid,uint64_t ip, uint64_t val, char *asmString)
|
||||||
|
{
|
||||||
|
(*lock)(tid);
|
||||||
|
createPacketFileForThread(tid);
|
||||||
|
|
||||||
|
printToFileIpValAsmString(tid, ip, val, asmString);
|
||||||
|
(*unlock)(tid);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
FilePacket::onThread_start (int tid)
|
||||||
|
{
|
||||||
|
fflush(stdout);
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
FilePacket::onThread_finish (int tid, long numCISC)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int FilePacket::onSubset_finish (int tid, long numCISC)
|
||||||
|
{
|
||||||
|
while(analysisFn(tid, 0, SUBSETSIMCOMPLETE, numCISC)==-1) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
FilePacket::closeAllFiles() {
|
||||||
|
printf("close all files \n"); fflush(stdout);
|
||||||
|
printf("Number of active threads...%d\n",MaxNumActiveThreads);
|
||||||
|
fflush(stdout);
|
||||||
|
for(int i=0; i<MaxNumActiveThreads; i++) {
|
||||||
|
#ifndef _WIN32
|
||||||
|
gzclose(files[i]);
|
||||||
|
#else
|
||||||
|
fclose(files[i]);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
FilePacket::unload()
|
||||||
|
{
|
||||||
|
if(files==NULL) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
closeAllFiles();
|
||||||
|
delete files;
|
||||||
|
}
|
||||||
|
|
||||||
|
FilePacket::~FilePacket ()
|
||||||
|
{
|
||||||
|
if(files==NULL) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
unload();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
FilePacket::setSubsetsimComplete(bool val)
|
||||||
|
{
|
||||||
|
isSubsetsimComplete = val;
|
||||||
|
return isSubsetsimComplete;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
FilePacket::isSubsetsimCompleted()
|
||||||
|
{
|
||||||
|
return isSubsetsimComplete;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
} // namespace IPC
|
|
@ -0,0 +1,57 @@
|
||||||
|
#ifndef H_include_filePacket
|
||||||
|
#define H_include_filePacket
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include "../IPCBase.h"
|
||||||
|
#include "../../../../emulator/pin/encoding.h"
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
|
#include <conio.h>
|
||||||
|
#else
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <zlib.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
namespace IPC
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
class FilePacket : public IPCBase
|
||||||
|
{
|
||||||
|
|
||||||
|
protected:
|
||||||
|
|
||||||
|
int maxNumActiveThreads;
|
||||||
|
|
||||||
|
// Once subset sim complete boolean variable is set, we should not write to shared memory any further.
|
||||||
|
volatile bool isSubsetsimComplete;
|
||||||
|
#ifndef _WIN32
|
||||||
|
gzFile *files;
|
||||||
|
#else
|
||||||
|
FILE **files;
|
||||||
|
#endif
|
||||||
|
void createPacketFileForThread(int tid);
|
||||||
|
void closeAllFiles();
|
||||||
|
void getFiles();
|
||||||
|
void printToFileIpValAsmString(int tid,uint64_t ip, uint64_t val, char *asmString);
|
||||||
|
void printToFileIpValAddr(int tid,uint64_t ip, uint64_t val, uint64_t addr);
|
||||||
|
public:
|
||||||
|
|
||||||
|
FilePacket(int maxNumThreads, const char *baseFileName, void (*lock)(int), void (*unlock)(int));
|
||||||
|
bool isSubsetsimCompleted(void);
|
||||||
|
bool setSubsetsimComplete(bool val);
|
||||||
|
|
||||||
|
int analysisFn (int tid,uint64_t ip, uint64_t value, uint64_t tgt);
|
||||||
|
int analysisFnAssembly (int tid,uint64_t ip, uint64_t value, char *asmString);
|
||||||
|
|
||||||
|
void onThread_start (int tid);
|
||||||
|
int onThread_finish (int tid, long numCISC);
|
||||||
|
int onSubset_finish (int tid, long numCISC);
|
||||||
|
|
||||||
|
bool unload ();
|
||||||
|
~FilePacket ();
|
||||||
|
};
|
||||||
|
}
|
||||||
|
#endif
|
|
@ -0,0 +1,199 @@
|
||||||
|
package emulatorinterface.communication.mmap;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.FileNotFoundException;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.RandomAccessFile;
|
||||||
|
import java.nio.IntBuffer;
|
||||||
|
import java.nio.MappedByteBuffer;
|
||||||
|
import java.nio.channels.FileChannel;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
|
||||||
|
import config.SimulationConfig;
|
||||||
|
import config.SystemConfig;
|
||||||
|
|
||||||
|
import emulatorinterface.communication.*;
|
||||||
|
import generic.CircularPacketQueue;
|
||||||
|
|
||||||
|
|
||||||
|
/*XXX
|
||||||
|
* Caution, this code has not been tested.
|
||||||
|
* */
|
||||||
|
|
||||||
|
public class MemMap extends IpcBase
|
||||||
|
{
|
||||||
|
// Must ensure that this is same as in mmap.h
|
||||||
|
public static final int COUNT = 1000;
|
||||||
|
static final String FILEPATH = "pfile";
|
||||||
|
|
||||||
|
File aFile;
|
||||||
|
RandomAccessFile ioFile;
|
||||||
|
FileChannel ioChannel;
|
||||||
|
|
||||||
|
private IntBuffer ibuf;
|
||||||
|
|
||||||
|
private IntBuffer lockBuf;
|
||||||
|
MappedByteBuffer buf;
|
||||||
|
MappedByteBuffer lBuf;
|
||||||
|
|
||||||
|
public MemMap(){
|
||||||
|
super();
|
||||||
|
aFile = new File (FILEPATH);
|
||||||
|
try {
|
||||||
|
ioFile = new RandomAccessFile (aFile, "rw");
|
||||||
|
ioChannel = ioFile.getChannel ();
|
||||||
|
} catch (FileNotFoundException e) {
|
||||||
|
// TODO Auto-generated catch block
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public Process startPIN(String cmd) throws Exception{
|
||||||
|
Runtime rt = Runtime.getRuntime();
|
||||||
|
try {
|
||||||
|
Process p = rt.exec(cmd);
|
||||||
|
StreamGobbler s1 = new StreamGobbler ("stdin", p.getInputStream ());
|
||||||
|
StreamGobbler s2 = new StreamGobbler ("stderr", p.getErrorStream ());
|
||||||
|
s1.start ();
|
||||||
|
s2.start ();
|
||||||
|
return p;
|
||||||
|
} catch (Exception e) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public void waitForJavaThreads() {
|
||||||
|
try {
|
||||||
|
// this takes care if no thread started yet.
|
||||||
|
free.acquire();
|
||||||
|
|
||||||
|
// if any thread has started and not finished then wait.
|
||||||
|
for (int i=0; i<SystemConfig.maxNumJavaThreads; i++) {
|
||||||
|
if (javaThreadStarted[i] && !javaThreadTermination[i]) {
|
||||||
|
free.acquire();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//inform threads which have not started about finish
|
||||||
|
for (int i=0; i<SystemConfig.maxNumJavaThreads; i++) {
|
||||||
|
if (javaThreadStarted[i]==false) javaThreadTermination[i]=true;
|
||||||
|
//totalInstructions += numInstructions[i];
|
||||||
|
}
|
||||||
|
} catch (InterruptedException ioe) {
|
||||||
|
misc.Error.showErrorAndExit("Wait for java threads interrupted !!");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void finish(){
|
||||||
|
try {
|
||||||
|
ioFile.close ();
|
||||||
|
} catch (IOException e) {
|
||||||
|
// TODO Auto-generated catch block
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public Packet fetchOnePacket(int tidApp, int index) {
|
||||||
|
//TODO
|
||||||
|
//this should return a packet (ibuf.get( (index) %COUNT ) );
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void initIpc() {
|
||||||
|
if (SimulationConfig.debugMode)
|
||||||
|
System.out.println("-- Mmap initialising");
|
||||||
|
try {
|
||||||
|
buf = ioChannel.map (FileChannel.MapMode.READ_WRITE, 0L,
|
||||||
|
(long) ((COUNT) * 4)).load ();
|
||||||
|
|
||||||
|
lBuf = ioChannel.map (FileChannel.MapMode.READ_WRITE, (long) ((COUNT) * 4),
|
||||||
|
(long) (20) ).load ();
|
||||||
|
ioChannel.close ();
|
||||||
|
|
||||||
|
//FIXME TODO
|
||||||
|
// these should be as packet buffer not int buffers
|
||||||
|
ibuf = buf.asIntBuffer ();
|
||||||
|
lockBuf = lBuf.asIntBuffer ();
|
||||||
|
} catch (IOException e) {
|
||||||
|
// TODO Auto-generated catch block
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
String name;
|
||||||
|
for (int i=0; i<SystemConfig.maxNumJavaThreads; i++){
|
||||||
|
name = "thread"+Integer.toString(i);
|
||||||
|
javaThreadTermination[i]=false;
|
||||||
|
javaThreadStarted[i]=false;
|
||||||
|
//TODO not all cores are assigned to each thread
|
||||||
|
//when the mechanism to tie threads to cores is in place
|
||||||
|
//this has to be changed
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public int numPackets(int tidApp) {
|
||||||
|
get_lock(lockBuf, 0, lBuf);
|
||||||
|
int queue_size = lockBuf.get(0);
|
||||||
|
release_lock(lockBuf, 0, lBuf);
|
||||||
|
return queue_size;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void release_lock(IntBuffer lockBuf2, int i, MappedByteBuffer lBuf2) {
|
||||||
|
ibuf.put(COUNT + 2, 0);
|
||||||
|
buf.force();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private void get_lock(IntBuffer lockBuf2, int i, MappedByteBuffer lBuf2) {
|
||||||
|
|
||||||
|
ibuf.put(COUNT + 2, 1); // flag[1] = 1
|
||||||
|
buf.force();
|
||||||
|
ibuf.put(COUNT + 3, 0); // turn = 0
|
||||||
|
buf.force();
|
||||||
|
while( (ibuf.get(COUNT+1) == 1) && (ibuf.get(COUNT + 3) == 0 )) {}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public long totalProduced(int tidApp) {
|
||||||
|
return lockBuf.get(0 + 4);
|
||||||
|
}
|
||||||
|
|
||||||
|
public long update(int tidApp, int numReads) {
|
||||||
|
int queue_size;
|
||||||
|
get_lock(lockBuf, 0, lBuf);
|
||||||
|
queue_size = lockBuf.get(0);
|
||||||
|
queue_size -= numReads;
|
||||||
|
lockBuf.put(0, queue_size);
|
||||||
|
release_lock(lockBuf, 0,lBuf);
|
||||||
|
return queue_size;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int fetchManyPackets(int tidApp, int index, int numPackets,
|
||||||
|
ArrayList<Packet> fromPIN) {
|
||||||
|
return 0;
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public ArrayList<Packet> fetchManyPackets(int tidApp, int readerLocation,
|
||||||
|
int numReads) {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void errorCheck(int tidApp, long totalReads) {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int fetchManyPackets(int tidApp, CircularPacketQueue fromEmulator) {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,228 @@
|
||||||
|
#include "mmap.h"
|
||||||
|
#include <sys/mman.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
|
||||||
|
namespace IPC
|
||||||
|
{
|
||||||
|
/*Mmap();
|
||||||
|
int analysisFn (int tid,uint64_t ip, int value, uint64_t tgt);
|
||||||
|
void onThread_start (int tid);
|
||||||
|
int onThread_finish (int tid);
|
||||||
|
bool unload ();
|
||||||
|
~Mmap();*/
|
||||||
|
|
||||||
|
#define FILESIZE ( (COUNT+5) * sizeof(packet))
|
||||||
|
|
||||||
|
void
|
||||||
|
Mmap::get_lock(packet *map) {
|
||||||
|
map[COUNT+1].value = 1; // flag[0] = 1
|
||||||
|
msync(map+COUNT*4, 5 * 4, MS_SYNC);
|
||||||
|
map[COUNT+3].value = 1; // turn = 1
|
||||||
|
msync(map+COUNT*4, 5 * 4, MS_SYNC);
|
||||||
|
while((map[COUNT+2].value == 1) && (map[COUNT+3].value == 1)) {}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
Mmap::release_lock(packet *map) {
|
||||||
|
map[COUNT + 1].value = 0;
|
||||||
|
msync(map+COUNT*4, 5 * 4, MS_SYNC);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Mmap::Mmap (int maxNumActiveThreads, void (*lock)(int), void (*unlock)(int)) : IPCBase(maxNumActiveThreads, lock, unlock)
|
||||||
|
{
|
||||||
|
//FILEPATH is shared through common.h
|
||||||
|
fd = open (FILEPATH, O_RDWR | O_CREAT | O_TRUNC, (mode_t) 0600);
|
||||||
|
if (fd == -1)
|
||||||
|
{
|
||||||
|
perror ("Error opening file for writing");
|
||||||
|
exit (EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
|
int result = write (fd, "", 1);
|
||||||
|
if (result != 1)
|
||||||
|
{
|
||||||
|
close (fd);
|
||||||
|
perror ("Error writing last byte of the file");
|
||||||
|
exit (EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Now the file is ready to be mmapped.
|
||||||
|
*/
|
||||||
|
tldata[0].map = (packet *) mmap (0, FILESIZE, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
|
||||||
|
if (tldata[0].map == (packet *)MAP_FAILED)
|
||||||
|
{
|
||||||
|
close (fd);
|
||||||
|
perror ("Error mmappp ing the file");
|
||||||
|
exit (EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// initialise book-keeping variables for each of the threads
|
||||||
|
THREAD_DATA *myData;
|
||||||
|
for (int t=0; t<MaxThreads; t++) {
|
||||||
|
myData = &tldata[t];
|
||||||
|
myData->tlqsize = 0;
|
||||||
|
myData->in = 0;
|
||||||
|
myData->out = 0;
|
||||||
|
myData->sum = 0;
|
||||||
|
// myData->tlq = new packet[locQ];
|
||||||
|
myData->map = tldata[0].map+(COUNT+5)*t; // point to the correct index in file
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* If local queue is full, write to the shared memory and then write to localQueue.
|
||||||
|
* else just write at localQueue at the appropriate index i.e. at 'in'
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
Mmap::analysisFn (int tid,uint64_t ip, int val, uint64_t addr)
|
||||||
|
{
|
||||||
|
THREAD_DATA *myData = &tldata[tid];
|
||||||
|
|
||||||
|
// if my local queue is full, I should write to the shared memory and return if cannot return
|
||||||
|
// write immediately, so that PIN can yield this thread.
|
||||||
|
if (myData->tlqsize == locQ) {
|
||||||
|
if (Mmap::filewrite(tid,0)==-1) return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// log the packet in my local queue
|
||||||
|
packet *myQueue = myData->tlq;
|
||||||
|
uint32_t *in = &(myData->in);
|
||||||
|
packet *sendPacket = &(myQueue[*in]);
|
||||||
|
|
||||||
|
sendPacket->ip = (uint64_t)ip;
|
||||||
|
sendPacket->value = val;
|
||||||
|
sendPacket->tgt = (uint64_t)addr;
|
||||||
|
|
||||||
|
*in = (*in + 1) % locQ;
|
||||||
|
myData->tlqsize++;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
Mmap::onThread_start (int tid)
|
||||||
|
{
|
||||||
|
THREAD_DATA *myData = &tldata[tid];
|
||||||
|
packet *map = myData->map;
|
||||||
|
|
||||||
|
map[COUNT].value = 0; // queue size pointer
|
||||||
|
map[COUNT + 1].value = 0; // flag[0] = 0
|
||||||
|
map[COUNT + 2].value = 0; // flag[1] = 0
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
Mmap::onThread_finish (int tid)
|
||||||
|
{
|
||||||
|
THREAD_DATA *myData = &tldata[tid];
|
||||||
|
|
||||||
|
// keep writing till we empty our local queue
|
||||||
|
while (myData->tlqsize !=0) {
|
||||||
|
if (Mmap::filewrite(tid,0)==-1) return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// last write to our shared memory. This time write a -1 in the 'value' field of the packet
|
||||||
|
return Mmap::filewrite(tid,1);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
endian_swap (packet& x)
|
||||||
|
{
|
||||||
|
/*(x>>56) |
|
||||||
|
((x<<40) & 0x00FF000000000000LLU) |
|
||||||
|
((x<<24) & 0x0000FF0000000000LLU) |
|
||||||
|
((x<<8) & 0x000000FF00000000LLU) |
|
||||||
|
((x>>8) & 0x00000000FF000000) |
|
||||||
|
((x>>24) & 0x0000000000FF0000) |
|
||||||
|
((x>>40) & 0x000000000000FF00) |
|
||||||
|
(x<<56);
|
||||||
|
*/
|
||||||
|
/*x = (x >> 24) |
|
||||||
|
((x << 8) & 0x00FF0000) | ((x >> 8) & 0x0000FF00) | (x << 24);
|
||||||
|
*/
|
||||||
|
|
||||||
|
//Swap endinaness accordingly
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
Mmap::filewrite (int tid, int last)
|
||||||
|
{
|
||||||
|
int queue_size;
|
||||||
|
int numWrite;
|
||||||
|
|
||||||
|
THREAD_DATA *myData = &tldata[tid];
|
||||||
|
packet* map = myData->map;
|
||||||
|
|
||||||
|
get_lock(map);
|
||||||
|
queue_size = map[COUNT].value;
|
||||||
|
release_lock(map);
|
||||||
|
numWrite = COUNT - queue_size;
|
||||||
|
|
||||||
|
// if numWrite is 0 this means cant write now. So should yield.
|
||||||
|
if (numWrite==0) return -1;
|
||||||
|
|
||||||
|
// if last packet then write -1 else write the actual packets
|
||||||
|
if (last ==0) {
|
||||||
|
|
||||||
|
// write 'numWrite' or 'local_queue_size' packets, whichever is less
|
||||||
|
numWrite = numWrite<myData->tlqsize ? numWrite:myData->tlqsize;
|
||||||
|
|
||||||
|
for (int i=0; i< numWrite; i++) {
|
||||||
|
|
||||||
|
// for checksum
|
||||||
|
myData->sum+=myData->tlq[(myData->out+i)%locQ].value;
|
||||||
|
|
||||||
|
// copy from local buffer to file with appropriate swappings.
|
||||||
|
endian_swap((myData->tlq[(myData->out+i)%locQ]));
|
||||||
|
memcpy(&(map[(myData->prod_ptr+i)%COUNT]),
|
||||||
|
&(myData->tlq[(myData->out+i)%locQ]),
|
||||||
|
sizeof(packet));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
numWrite = 1;
|
||||||
|
map[myData->prod_ptr % COUNT].value = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// some bookkeeping of the threads state.
|
||||||
|
myData->out = (myData->out + numWrite)%locQ;
|
||||||
|
myData->tlqsize=myData->tlqsize-numWrite;
|
||||||
|
myData->prod_ptr = (myData->prod_ptr + numWrite) % COUNT;
|
||||||
|
|
||||||
|
// update queue_size
|
||||||
|
get_lock(map);
|
||||||
|
queue_size = map[COUNT].value;
|
||||||
|
queue_size += numWrite;
|
||||||
|
|
||||||
|
myData->tot_prod += numWrite;
|
||||||
|
|
||||||
|
map[COUNT].value = queue_size;
|
||||||
|
map[COUNT+4].value = myData->tot_prod;
|
||||||
|
release_lock(map);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool
|
||||||
|
Mmap::unload() {
|
||||||
|
if (munmap (tldata[0].map, FILESIZE) == -1)
|
||||||
|
{
|
||||||
|
perror ("Error un-mmapping the file");
|
||||||
|
/* Decide here whether to close(fd) and exit() or not. Depends... */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Mmap::~Mmap ()
|
||||||
|
{
|
||||||
|
for (int t=0; t<MaxThreads; t++) {
|
||||||
|
delete tldata[t].tlq;
|
||||||
|
}
|
||||||
|
close (fd);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
} // namespace IPC
|
|
@ -0,0 +1,54 @@
|
||||||
|
#ifndef H_include_mmap
|
||||||
|
#define H_include_mmap
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
|
||||||
|
#include "../IPCBase.h"
|
||||||
|
|
||||||
|
// Must ensure that this is same as in Memmap.java
|
||||||
|
#define COUNT (1000)
|
||||||
|
#define locQ (50)
|
||||||
|
#define FILEPATH "pfile"
|
||||||
|
|
||||||
|
namespace IPC
|
||||||
|
{
|
||||||
|
|
||||||
|
class Mmap:public IPCBase
|
||||||
|
{
|
||||||
|
protected:
|
||||||
|
int fd;
|
||||||
|
// For keeping a record of various thread related variables
|
||||||
|
#define PADSIZE 28 //64-36, assuming it is on 32bit machine(as addresses are 32bit)
|
||||||
|
struct THREAD_DATA
|
||||||
|
{
|
||||||
|
uint32_t tlqsize; /* address of instruction */
|
||||||
|
uint32_t in; /* in pointer in the local queue */
|
||||||
|
uint32_t out; /* out pointer in the local queue */
|
||||||
|
packet *map; /* thread's mmap index pointer */
|
||||||
|
packet *tlq; /* XXX local queue, write in shmem when this fils */
|
||||||
|
uint32_t prod_ptr; /* producer pointer in the shared mem */
|
||||||
|
uint32_t tot_prod; /* total packets produced */
|
||||||
|
uint64_t sum; /* checksum */
|
||||||
|
uint8_t _pad[PADSIZE]; /* to handle false sharing */
|
||||||
|
};
|
||||||
|
|
||||||
|
public:
|
||||||
|
THREAD_DATA tldata[MaxThreads];
|
||||||
|
Mmap(int maxNumActiveThreads, void (*lock)(int), void (*unlock)(int));
|
||||||
|
int analysisFn (int tid,uint64_t ip, int value, uint64_t tgt);
|
||||||
|
void onThread_start (int tid);
|
||||||
|
int onThread_finish (int tid);
|
||||||
|
int filewrite(int tid, int last);
|
||||||
|
void get_lock(packet *map);
|
||||||
|
void release_lock(packet *map);
|
||||||
|
bool unload ();
|
||||||
|
~Mmap();
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue