initial commit

This commit is contained in:
Rajshekar K K 2020-07-04 12:04:37 +05:30
commit 0dc2657e88
324 changed files with 738090 additions and 0 deletions

9
.gitignore vendored Normal file
View File

@ -0,0 +1,9 @@
**/bin
**/obj-pin
**/obj-comm
/.classpath
/.cproject
/.project
/.settings
**/hs_err*
**/*.swp

0
CHANGELOG Executable file
View File

202
LICENSE Executable file
View File

@ -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.

32
MAINTAINERS Executable file
View File

@ -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].

30
NOTICE Executable file
View File

@ -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/).
*****************************************************************************/

103
README Executable file
View File

@ -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

8
ROADMAP Executable file
View File

@ -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)

12
TODO Executable file
View File

@ -0,0 +1,12 @@
1)
_______________________________________________________________________________
2)
_______________________________________________________________________________
3)
_______________________________________________________________________________
4)
_______________________________________________________________________________

1
VERSION Executable file
View File

@ -0,0 +1 @@
0.2

1
benchmarks/parsec Executable file
View File

@ -0,0 +1 @@
ADD

1
benchmarks/speccpu2006 Executable file
View File

@ -0,0 +1 @@
add

1
benchmarks/splash Executable file
View File

@ -0,0 +1 @@
ADD

81
build.xml Executable file
View File

@ -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>

98
install.py Normal file
View File

@ -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>")

View File

@ -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.

4
scripts/get_pin_latest.sh Executable file
View File

@ -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

311
scripts/install.py Normal file
View File

@ -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>"

82
scripts/parallel_bm.sh Executable file
View File

@ -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!!!"

78
scripts/run_tejasdram Executable file
View File

@ -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"

311
scripts/sc Normal file
View File

@ -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>"

46
scripts/spec2006.sh Executable file
View File

@ -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

295
scripts/spec2006_single.sh Executable file
View File

@ -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

23
scripts/tejaspin.sh Executable file
View File

@ -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

4
scripts/test.sh Executable file
View File

@ -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

View File

@ -0,0 +1,8 @@
#include<iostream>
using namespace std;
int main(){
cout<<"This is working "<<endl;
return 0;
}

View File

@ -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.

View File

@ -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;
}

View File

@ -0,0 +1,10 @@
class Sample2
{
public static int intMethod(int n) {
return n*n;
}
public static boolean booleanMethod(boolean bool) {
return !bool;
}
}

BIN
src/emulator/pin/a.out Executable file

Binary file not shown.

1017
src/emulator/pin/causalityTool.cpp Executable file

File diff suppressed because it is too large Load Diff

35
src/emulator/pin/encoding.h Executable file
View File

@ -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);

6
src/emulator/pin/makefile Executable file
View File

@ -0,0 +1,6 @@
ifeq ($(OS),Windows_NT)
include makefile_windows
else
include makefile_linux_mac
endif

View File

@ -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)

View File

@ -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)/*

25
src/emulator/pin/pin_makefile Executable file
View File

@ -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!
#
##############################################################

View 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;
}

374
src/emulator/pin/printingTool.cpp Executable file
View File

@ -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;
}

View File

@ -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
}
}

View File

@ -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;
}
}

View File

@ -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;
// }
}

View File

@ -0,0 +1,7 @@
package config;
public enum CacheDataType {
Instruction,
Data,
Unified
}

View File

@ -0,0 +1,7 @@
package config;
public class CacheEnergyConfig {
public double leakageEnergy;
public double readDynamicEnergy;
public double writeDynamicEnergy;
}

View File

@ -0,0 +1,7 @@
package config;
public enum CommunicationType {
sharedMemory,
network,
file
}

View 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;
}
}

View File

@ -0,0 +1,5 @@
package config;
public class DirectoryConfig extends CacheConfig {
}

View File

@ -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;
}

View File

@ -0,0 +1,7 @@
package config;
public enum EmulatorType {
pin,
qemu,
none
}

View File

@ -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");
}
}

View File

@ -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);
}
}

View File

@ -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;
}
}

View File

@ -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;
}

View File

@ -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 - -
- - - - - - - - - -

View File

@ -0,0 +1,5 @@
package config;
public enum PipelineType {
inOrder,outOfOrder,statistical
}

View File

@ -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;
}

View File

@ -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

720
src/simulator/config/config.xml Executable file
View File

@ -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>

View File

@ -0,0 +1,5 @@
package dram;
public class Bank {
}

View File

@ -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);
*/
}
}

View File

@ -0,0 +1,5 @@
package dram;
public class BusPacketQueue1D {
}

View File

@ -0,0 +1,5 @@
package dram;
public class BusPacketQueue2D {
}

View File

@ -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();
}
}
}
}
}

View File

@ -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();
}
}
}

View File

@ -0,0 +1,5 @@
package dram;
public class Dram {
}

View File

@ -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");
}
}
}
}

View File

@ -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");
}
}*/
}

View File

@ -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");
}
}
}

View File

@ -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" );
}
}

View File

@ -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");
}
}
}

View File

@ -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" );
}
}

View File

@ -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

View File

@ -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

View File

@ -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;
}
}

View File

@ -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;
}
}

View File

@ -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;
}
}
}

View File

@ -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;
// }
}

View File

@ -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;
}
}

View File

@ -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;
}
}

View File

@ -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;
}
}

View File

@ -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
}

View File

@ -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;
}
}
}

View File

@ -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;
}
}

View File

@ -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
}
}

View File

@ -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));
}
}
}

View File

@ -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;
}

View File

@ -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

View File

@ -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;
}
}

View File

@ -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;
}*/
}

View File

@ -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();
}
}

View File

@ -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

View File

@ -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

View File

@ -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();
}
}
}
}

View File

@ -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));
}
}
}
}

View File

@ -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

View File

@ -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

View File

@ -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;
}
}

View File

@ -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

View File

@ -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