diff --git a/.gitignore b/.gitignore index 02d40fb3..c7425d6f 100644 --- a/.gitignore +++ b/.gitignore @@ -21,3 +21,4 @@ DRAMSys/analyzer/scripts/__pycache__/ *.autosave *__pycache__* DRAMSys/gem5/boot_linux/linux-aarch32-ael.img +DRAMSys/docs/doxygen diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index ba3576c0..700ec923 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -1,3 +1,4 @@ +# vim: set ts=4 sw=4 expandtab: image: gcc variables: @@ -5,12 +6,10 @@ variables: stages: - build + - dramsys-gem5-build - WIDEIO - DDR3 - -cache: - paths: - - build/ + - Coverage build: stage: build @@ -22,7 +21,36 @@ build: - cd build - qmake ../DRAMSys/DRAMSys.pro - make -j4 - + - find . -name "*.o" -type f -delete + - rm -rf ${CI_PROJECT_DIR}/coverage + - mkdir -p ${CI_PROJECT_DIR}/coverage + + cache: + key: build + paths: + - build/ + policy: push + + artifacts: + paths: + - coverage/ + +coverage: + stage: Coverage + coverage: '/Total:\|(\d+\.?\d+\%)/' + script: + # delete all empty files since they produce errors + - find coverage -size 0 -type f -delete + - ls coverage/ -lah + - lcov `find coverage -type f -exec echo "-a {}" \;` -o coverage/final.out + - lcov --list coverage/final.out + + artifacts: + paths: + - coverage/final.out + + include: - '/DRAMSys/tests/DDR3/ci.yml' - '/DRAMSys/tests/WIDEIO/ci.yml' + #- '/DRAMSys/tests/dramsys-gem5/ci.yml' # Should be activated again when a new gitlab runner with right dependencies is used diff --git a/.gitmodules b/.gitmodules index 82647b71..458b70e3 100644 --- a/.gitmodules +++ b/.gitmodules @@ -5,3 +5,6 @@ path = DRAMSys/library/src/common/third_party/DRAMPower url = https://github.com/tukl-msd/DRAMPower.git branch = master +[submodule "DRAMSys/unitTests/googletest"] + path = DRAMSys/unitTests/googletest + url = https://github.com/google/googletest.git diff --git a/DRAMSys/DRAMSys.pro b/DRAMSys/DRAMSys.pro index 3653e3bf..d4a5e29e 100644 --- a/DRAMSys/DRAMSys.pro +++ b/DRAMSys/DRAMSys.pro @@ -11,11 +11,26 @@ $$eval(thermalsim) { message(Thermal Simulation Feature Disabled) } +dramsys_disable_coverage_check = $$(DRAMSYS_DISABLE_COVERAGE_CHECK) +isEmpty(dramsys_disable_coverage_check) { + message(Coverage check ENABLED) +} else { + message(Coverage check DISABLED) +} + +systemc_home = $$(SYSTEMC_HOME) +isEmpty(systemc_home) { + systemc_home = /opt/systemc +} +message(SystemC home is $${systemc_home}) + SUBDIRS += library +SUBDIRS += unitTests SUBDIRS += simulator SUBDIRS += traceAnalyzer library.subdir = library +unitTests.subdir = unitTests simulator.subdir = simulator traceAnalyzer.subdir = traceAnalyzer diff --git a/DRAMSys/docs/doxyCfg.cfg b/DRAMSys/docs/doxyCfg.cfg new file mode 100644 index 00000000..ea4940db --- /dev/null +++ b/DRAMSys/docs/doxyCfg.cfg @@ -0,0 +1,1228 @@ +# Doxyfile 1.4.4 + +# This file describes the settings to be used by the documentation system +# doxygen (www.doxygen.org) for a project +# +# All text after a hash (#) is considered a comment and will be ignored +# The format is: +# TAG = value [value, ...] +# For lists items can also be appended using: +# TAG += value [value, ...] +# Values that contain spaces should be placed between quotes (" ") + +#--------------------------------------------------------------------------- +# Project related configuration options +#--------------------------------------------------------------------------- + +# The PROJECT_NAME tag is a single word (or a sequence of words surrounded +# by quotes) that should identify the project. + +PROJECT_NAME = DRAMSys + +# The PROJECT_NUMBER tag can be used to enter a project or revision number. +# This could be handy for archiving the generated documentation or +# if some version control system is used. + +PROJECT_NUMBER = + +# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) +# base path where the generated documentation will be put. +# If a relative path is entered, it will be relative to the location +# where doxygen was started. If left blank the current directory will be used. + +OUTPUT_DIRECTORY = doxygen + +# If the CREATE_SUBDIRS tag is set to YES, then doxygen will create +# 4096 sub-directories (in 2 levels) under the output directory of each output +# format and will distribute the generated files over these directories. +# Enabling this option can be useful when feeding doxygen a huge amount of +# source files, where putting all generated files in the same directory would +# otherwise cause performance problems for the file system. + +CREATE_SUBDIRS = NO + +# The OUTPUT_LANGUAGE tag is used to specify the language in which all +# documentation generated by doxygen is written. Doxygen will use this +# information to generate all constant output in the proper language. +# The default language is English, other supported languages are: +# Brazilian, Catalan, Chinese, Chinese-Traditional, Croatian, Czech, Danish, +# Dutch, Finnish, French, German, Greek, Hungarian, Italian, Japanese, +# Japanese-en (Japanese with English messages), Korean, Korean-en, Norwegian, +# Polish, Portuguese, Romanian, Russian, Serbian, Slovak, Slovene, Spanish, +# Swedish, and Ukrainian. + +OUTPUT_LANGUAGE = English + +# This tag can be used to specify the encoding used in the generated output. +# The encoding is not always determined by the language that is chosen, +# but also whether or not the output is meant for Windows or non-Windows users. +# In case there is a difference, setting the USE_WINDOWS_ENCODING tag to YES +# forces the Windows encoding (this is the default for the Windows binary), +# whereas setting the tag to NO uses a Unix-style encoding (the default for +# all platforms other than Windows). + +USE_WINDOWS_ENCODING = NO + +# If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will +# include brief member descriptions after the members that are listed in +# the file and class documentation (similar to JavaDoc). +# Set to NO to disable this. + +BRIEF_MEMBER_DESC = YES + +# If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend +# the brief description of a member or function before the detailed description. +# Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the +# brief descriptions will be completely suppressed. + +REPEAT_BRIEF = YES + +# This tag implements a quasi-intelligent brief description abbreviator +# that is used to form the text in various listings. Each string +# in this list, if found as the leading text of the brief description, will be +# stripped from the text and the result after processing the whole list, is +# used as the annotated text. Otherwise, the brief description is used as-is. +# If left blank, the following values are used ("$name" is automatically +# replaced with the name of the entity): "The $name class" "The $name widget" +# "The $name file" "is" "provides" "specifies" "contains" +# "represents" "a" "an" "the" + +ABBREVIATE_BRIEF = + +# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then +# Doxygen will generate a detailed section even if there is only a brief +# description. + +ALWAYS_DETAILED_SEC = NO + +# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all +# inherited members of a class in the documentation of that class as if those +# members were ordinary class members. Constructors, destructors and assignment +# operators of the base classes will not be shown. + +INLINE_INHERITED_MEMB = NO + +# If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full +# path before files name in the file list and in the header files. If set +# to NO the shortest path that makes the file name unique will be used. + +FULL_PATH_NAMES = YES + +# If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag +# can be used to strip a user-defined part of the path. Stripping is +# only done if one of the specified strings matches the left-hand part of +# the path. The tag can be used to show relative paths in the file list. +# If left blank the directory from which doxygen is run is used as the +# path to strip. + +STRIP_FROM_PATH = + +# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of +# the path mentioned in the documentation of a class, which tells +# the reader which header file to include in order to use a class. +# If left blank only the name of the header file containing the class +# definition is used. Otherwise one should specify the include paths that +# are normally passed to the compiler using the -I flag. + +STRIP_FROM_INC_PATH = + +# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter +# (but less readable) file names. This can be useful is your file systems +# doesn't support long names like on DOS, Mac, or CD-ROM. + +SHORT_NAMES = NO + +# If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen +# will interpret the first line (until the first dot) of a JavaDoc-style +# comment as the brief description. If set to NO, the JavaDoc +# comments will behave just like the Qt-style comments (thus requiring an +# explicit @brief command for a brief description. + +JAVADOC_AUTOBRIEF = YES + +# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen +# treat a multi-line C++ special comment block (i.e. a block of //! or /// +# comments) as a brief description. This used to be the default behaviour. +# The new default is to treat a multi-line C++ comment block as a detailed +# description. Set this tag to YES if you prefer the old behaviour instead. + +MULTILINE_CPP_IS_BRIEF = NO + +# If the DETAILS_AT_TOP tag is set to YES then Doxygen +# will output the detailed description near the top, like JavaDoc. +# If set to NO, the detailed description appears after the member +# documentation. + +DETAILS_AT_TOP = NO + +# If the INHERIT_DOCS tag is set to YES (the default) then an undocumented +# member inherits the documentation from any documented member that it +# re-implements. + +INHERIT_DOCS = YES + +# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC +# tag is set to YES, then doxygen will reuse the documentation of the first +# member in the group (if any) for the other members of the group. By default +# all members of a group must be documented explicitly. + +DISTRIBUTE_GROUP_DOC = NO + +# If the SEPARATE_MEMBER_PAGES tag is set to YES, then doxygen will produce +# a new page for each member. If set to NO, the documentation of a member will +# be part of the file/class/namespace that contains it. + +SEPARATE_MEMBER_PAGES = NO + +# The TAB_SIZE tag can be used to set the number of spaces in a tab. +# Doxygen uses this value to replace tabs by spaces in code fragments. + +TAB_SIZE = 4 + +# This tag can be used to specify a number of aliases that acts +# as commands in the documentation. An alias has the form "name=value". +# For example adding "sideeffect=\par Side Effects:\n" will allow you to +# put the command \sideeffect (or @sideeffect) in the documentation, which +# will result in a user-defined paragraph with heading "Side Effects:". +# You can put \n's in the value part of an alias to insert newlines. + +ALIASES = + +# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C +# sources only. Doxygen will then generate output that is more tailored for C. +# For instance, some of the names that are used will be different. The list +# of all members will be omitted, etc. + +OPTIMIZE_OUTPUT_FOR_C = NO + +# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java sources +# only. Doxygen will then generate output that is more tailored for Java. +# For instance, namespaces will be presented as packages, qualified scopes +# will look different, etc. + +OPTIMIZE_OUTPUT_JAVA = NO + +# Set the SUBGROUPING tag to YES (the default) to allow class member groups of +# the same type (for instance a group of public functions) to be put as a +# subgroup of that type (e.g. under the Public Functions section). Set it to +# NO to prevent subgrouping. Alternatively, this can be done per class using +# the \nosubgrouping command. + +SUBGROUPING = YES + +#--------------------------------------------------------------------------- +# Build related configuration options +#--------------------------------------------------------------------------- + +# If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in +# documentation are documented, even if no documentation was available. +# Private class members and static file members will be hidden unless +# the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES + +EXTRACT_ALL = YES + +# If the EXTRACT_PRIVATE tag is set to YES all private members of a class +# will be included in the documentation. + +EXTRACT_PRIVATE = YES + +# If the EXTRACT_STATIC tag is set to YES all static members of a file +# will be included in the documentation. + +EXTRACT_STATIC = YES + +# If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs) +# defined locally in source files will be included in the documentation. +# If set to NO only classes defined in header files are included. + +EXTRACT_LOCAL_CLASSES = YES + +# This flag is only useful for Objective-C code. When set to YES local +# methods, which are defined in the implementation section but not in +# the interface are included in the documentation. +# If set to NO (the default) only methods in the interface are included. + +EXTRACT_LOCAL_METHODS = NO + +# If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all +# undocumented members of documented classes, files or namespaces. +# If set to NO (the default) these members will be included in the +# various overviews, but no documentation section is generated. +# This option has no effect if EXTRACT_ALL is enabled. + +HIDE_UNDOC_MEMBERS = NO + +# If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all +# undocumented classes that are normally visible in the class hierarchy. +# If set to NO (the default) these classes will be included in the various +# overviews. This option has no effect if EXTRACT_ALL is enabled. + +HIDE_UNDOC_CLASSES = NO + +# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all +# friend (class|struct|union) declarations. +# If set to NO (the default) these declarations will be included in the +# documentation. + +HIDE_FRIEND_COMPOUNDS = NO + +# If the HIDE_IN_BODY_DOCS tag is set to YES, Doxygen will hide any +# documentation blocks found inside the body of a function. +# If set to NO (the default) these blocks will be appended to the +# function's detailed documentation block. + +HIDE_IN_BODY_DOCS = NO + +# The INTERNAL_DOCS tag determines if documentation +# that is typed after a \internal command is included. If the tag is set +# to NO (the default) then the documentation will be excluded. +# Set it to YES to include the internal documentation. + +INTERNAL_DOCS = NO + +# If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate +# file names in lower-case letters. If set to YES upper-case letters are also +# allowed. This is useful if you have classes or files whose names only differ +# in case and if your file system supports case sensitive file names. Windows +# and Mac users are advised to set this option to NO. + +CASE_SENSE_NAMES = YES + +# If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen +# will show members with their full class and namespace scopes in the +# documentation. If set to YES the scope will be hidden. + +HIDE_SCOPE_NAMES = NO + +# If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen +# will put a list of the files that are included by a file in the documentation +# of that file. + +SHOW_INCLUDE_FILES = YES + +# If the INLINE_INFO tag is set to YES (the default) then a tag [inline] +# is inserted in the documentation for inline members. + +INLINE_INFO = YES + +# If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen +# will sort the (detailed) documentation of file and class members +# alphabetically by member name. If set to NO the members will appear in +# declaration order. + +SORT_MEMBER_DOCS = YES + +# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the +# brief documentation of file, namespace and class members alphabetically +# by member name. If set to NO (the default) the members will appear in +# declaration order. + +SORT_BRIEF_DOCS = NO + +# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be +# sorted by fully-qualified names, including namespaces. If set to +# NO (the default), the class list will be sorted only by class name, +# not including the namespace part. +# Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES. +# Note: This option applies only to the class list, not to the +# alphabetical list. + +SORT_BY_SCOPE_NAME = NO + +# The GENERATE_TODOLIST tag can be used to enable (YES) or +# disable (NO) the todo list. This list is created by putting \todo +# commands in the documentation. + +GENERATE_TODOLIST = YES + +# The GENERATE_TESTLIST tag can be used to enable (YES) or +# disable (NO) the test list. This list is created by putting \test +# commands in the documentation. + +GENERATE_TESTLIST = YES + +# The GENERATE_BUGLIST tag can be used to enable (YES) or +# disable (NO) the bug list. This list is created by putting \bug +# commands in the documentation. + +GENERATE_BUGLIST = YES + +# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or +# disable (NO) the deprecated list. This list is created by putting +# \deprecated commands in the documentation. + +GENERATE_DEPRECATEDLIST= YES + +# The ENABLED_SECTIONS tag can be used to enable conditional +# documentation sections, marked by \if sectionname ... \endif. + +ENABLED_SECTIONS = + +# The MAX_INITIALIZER_LINES tag determines the maximum number of lines +# the initial value of a variable or define consists of for it to appear in +# the documentation. If the initializer consists of more lines than specified +# here it will be hidden. Use a value of 0 to hide initializers completely. +# The appearance of the initializer of individual variables and defines in the +# documentation can be controlled using \showinitializer or \hideinitializer +# command in the documentation regardless of this setting. + +MAX_INITIALIZER_LINES = 30 + +# Set the SHOW_USED_FILES tag to NO to disable the list of files generated +# at the bottom of the documentation of classes and structs. If set to YES the +# list will mention the files that were used to generate the documentation. + +SHOW_USED_FILES = YES + +# If the sources in your project are distributed over multiple directories +# then setting the SHOW_DIRECTORIES tag to YES will show the directory hierarchy +# in the documentation. The default is YES. + +SHOW_DIRECTORIES = YES + +# The FILE_VERSION_FILTER tag can be used to specify a program or script that +# doxygen should invoke to get the current version for each file (typically from the +# version control system). Doxygen will invoke the program by executing (via +# popen()) the command , where is the value of +# the FILE_VERSION_FILTER tag, and is the name of an input file +# provided by doxygen. Whatever the progam writes to standard output +# is used as the file version. See the manual for examples. + +FILE_VERSION_FILTER = + +#--------------------------------------------------------------------------- +# configuration options related to warning and progress messages +#--------------------------------------------------------------------------- + +# The QUIET tag can be used to turn on/off the messages that are generated +# by doxygen. Possible values are YES and NO. If left blank NO is used. + +QUIET = NO + +# The WARNINGS tag can be used to turn on/off the warning messages that are +# generated by doxygen. Possible values are YES and NO. If left blank +# NO is used. + +WARNINGS = YES + +# If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings +# for undocumented members. If EXTRACT_ALL is set to YES then this flag will +# automatically be disabled. + +WARN_IF_UNDOCUMENTED = YES + +# If WARN_IF_DOC_ERROR is set to YES, doxygen will generate warnings for +# potential errors in the documentation, such as not documenting some +# parameters in a documented function, or documenting parameters that +# don't exist or using markup commands wrongly. + +WARN_IF_DOC_ERROR = YES + +# This WARN_NO_PARAMDOC option can be abled to get warnings for +# functions that are documented, but have no documentation for their parameters +# or return value. If set to NO (the default) doxygen will only warn about +# wrong or incomplete parameter documentation, but not about the absence of +# documentation. + +WARN_NO_PARAMDOC = NO + +# The WARN_FORMAT tag determines the format of the warning messages that +# doxygen can produce. The string should contain the $file, $line, and $text +# tags, which will be replaced by the file and line number from which the +# warning originated and the warning text. Optionally the format may contain +# $version, which will be replaced by the version of the file (if it could +# be obtained via FILE_VERSION_FILTER) + +WARN_FORMAT = "$file:$line: $text" + +# The WARN_LOGFILE tag can be used to specify a file to which warning +# and error messages should be written. If left blank the output is written +# to stderr. + +WARN_LOGFILE = + +#--------------------------------------------------------------------------- +# configuration options related to the input files +#--------------------------------------------------------------------------- + +# The INPUT tag can be used to specify the files and/or directories that contain +# documented source files. You may enter file names like "myfile.cpp" or +# directories like "/usr/src/myproject". Separate the files or directories +# with spaces. + +INPUT = ../ + +# If the value of the INPUT tag contains directories, you can use the +# FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp +# and *.h) to filter out the source-files in the directories. If left +# blank the following patterns are tested: +# *.c *.cc *.cxx *.cpp *.c++ *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh *.hxx +# *.hpp *.h++ *.idl *.odl *.cs *.php *.php3 *.inc *.m *.mm + +FILE_PATTERNS = + +# The RECURSIVE tag can be used to turn specify whether or not subdirectories +# should be searched for input files as well. Possible values are YES and NO. +# If left blank NO is used. + +RECURSIVE = YES + +# The EXCLUDE tag can be used to specify files and/or directories that should +# excluded from the INPUT source files. This way you can easily exclude a +# subdirectory from a directory tree whose root is specified with the INPUT tag. + +EXCLUDE = + +# The EXCLUDE_SYMLINKS tag can be used select whether or not files or +# directories that are symbolic links (a Unix filesystem feature) are excluded +# from the input. + +EXCLUDE_SYMLINKS = NO + +# If the value of the INPUT tag contains directories, you can use the +# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude +# certain files from those directories. Note that the wildcards are matched +# against the file with absolute path, so to exclude all test directories +# for example use the pattern */test/* + +EXCLUDE_PATTERNS = + +# The EXAMPLE_PATH tag can be used to specify one or more files or +# directories that contain example code fragments that are included (see +# the \include command). + +EXAMPLE_PATH = + +# If the value of the EXAMPLE_PATH tag contains directories, you can use the +# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp +# and *.h) to filter out the source-files in the directories. If left +# blank all files are included. + +EXAMPLE_PATTERNS = + +# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be +# searched for input files to be used with the \include or \dontinclude +# commands irrespective of the value of the RECURSIVE tag. +# Possible values are YES and NO. If left blank NO is used. + +EXAMPLE_RECURSIVE = NO + +# The IMAGE_PATH tag can be used to specify one or more files or +# directories that contain image that are included in the documentation (see +# the \image command). + +IMAGE_PATH = + +# The INPUT_FILTER tag can be used to specify a program that doxygen should +# invoke to filter for each input file. Doxygen will invoke the filter program +# by executing (via popen()) the command , where +# is the value of the INPUT_FILTER tag, and is the name of an +# input file. Doxygen will then use the output that the filter program writes +# to standard output. If FILTER_PATTERNS is specified, this tag will be +# ignored. + +INPUT_FILTER = + +# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern +# basis. Doxygen will compare the file name with each pattern and apply the +# filter if there is a match. The filters are a list of the form: +# pattern=filter (like *.cpp=my_cpp_filter). See INPUT_FILTER for further +# info on how filters are used. If FILTER_PATTERNS is empty, INPUT_FILTER +# is applied to all files. + +FILTER_PATTERNS = + +# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using +# INPUT_FILTER) will be used to filter the input files when producing source +# files to browse (i.e. when SOURCE_BROWSER is set to YES). + +FILTER_SOURCE_FILES = NO + +#--------------------------------------------------------------------------- +# configuration options related to source browsing +#--------------------------------------------------------------------------- + +# If the SOURCE_BROWSER tag is set to YES then a list of source files will +# be generated. Documented entities will be cross-referenced with these sources. +# Note: To get rid of all source code in the generated output, make sure also +# VERBATIM_HEADERS is set to NO. + +SOURCE_BROWSER = NO + +# Setting the INLINE_SOURCES tag to YES will include the body +# of functions and classes directly in the documentation. + +INLINE_SOURCES = NO + +# Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct +# doxygen to hide any special comment blocks from generated source code +# fragments. Normal C and C++ comments will always remain visible. + +STRIP_CODE_COMMENTS = YES + +# If the REFERENCED_BY_RELATION tag is set to YES (the default) +# then for each documented function all documented +# functions referencing it will be listed. + +REFERENCED_BY_RELATION = YES + +# If the REFERENCES_RELATION tag is set to YES (the default) +# then for each documented function all documented entities +# called/used by that function will be listed. + +REFERENCES_RELATION = YES + +# If the USE_HTAGS tag is set to YES then the references to source code +# will point to the HTML generated by the htags(1) tool instead of doxygen +# built-in source browser. The htags tool is part of GNU's global source +# tagging system (see http://www.gnu.org/software/global/global.html). You +# will need version 4.8.6 or higher. + +USE_HTAGS = NO + +# If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen +# will generate a verbatim copy of the header file for each class for +# which an include is specified. Set to NO to disable this. + +VERBATIM_HEADERS = YES + +#--------------------------------------------------------------------------- +# configuration options related to the alphabetical class index +#--------------------------------------------------------------------------- + +# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index +# of all compounds will be generated. Enable this if the project +# contains a lot of classes, structs, unions or interfaces. + +ALPHABETICAL_INDEX = YES + +# If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then +# the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns +# in which this list will be split (can be a number in the range [1..20]) + +COLS_IN_ALPHA_INDEX = 5 + +# In case all classes in a project start with a common prefix, all +# classes will be put under the same header in the alphabetical index. +# The IGNORE_PREFIX tag can be used to specify one or more prefixes that +# should be ignored while generating the index headers. + +IGNORE_PREFIX = + +#--------------------------------------------------------------------------- +# configuration options related to the HTML output +#--------------------------------------------------------------------------- + +# If the GENERATE_HTML tag is set to YES (the default) Doxygen will +# generate HTML output. + +GENERATE_HTML = YES + +# The HTML_OUTPUT tag is used to specify where the HTML docs will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `html' will be used as the default path. + +HTML_OUTPUT = html + +# The HTML_FILE_EXTENSION tag can be used to specify the file extension for +# each generated HTML page (for example: .htm,.php,.asp). If it is left blank +# doxygen will generate files with .html extension. + +HTML_FILE_EXTENSION = .html + +# The HTML_HEADER tag can be used to specify a personal HTML header for +# each generated HTML page. If it is left blank doxygen will generate a +# standard header. + +HTML_HEADER = + +# The HTML_FOOTER tag can be used to specify a personal HTML footer for +# each generated HTML page. If it is left blank doxygen will generate a +# standard footer. + +HTML_FOOTER = + +# The HTML_STYLESHEET tag can be used to specify a user-defined cascading +# style sheet that is used by each HTML page. It can be used to +# fine-tune the look of the HTML output. If the tag is left blank doxygen +# will generate a default style sheet. Note that doxygen will try to copy +# the style sheet file to the HTML output directory, so don't put your own +# stylesheet in the HTML output directory as well, or it will be erased! + +HTML_STYLESHEET = + +# If the HTML_ALIGN_MEMBERS tag is set to YES, the members of classes, +# files or namespaces will be aligned in HTML using tables. If set to +# NO a bullet list will be used. + +HTML_ALIGN_MEMBERS = YES + +# If the GENERATE_HTMLHELP tag is set to YES, additional index files +# will be generated that can be used as input for tools like the +# Microsoft HTML help workshop to generate a compressed HTML help file (.chm) +# of the generated HTML documentation. + +GENERATE_HTMLHELP = NO + +# If the GENERATE_HTMLHELP tag is set to YES, the CHM_FILE tag can +# be used to specify the file name of the resulting .chm file. You +# can add a path in front of the file if the result should not be +# written to the html output directory. + +CHM_FILE = + +# If the GENERATE_HTMLHELP tag is set to YES, the HHC_LOCATION tag can +# be used to specify the location (absolute path including file name) of +# the HTML help compiler (hhc.exe). If non-empty doxygen will try to run +# the HTML help compiler on the generated index.hhp. + +HHC_LOCATION = + +# If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag +# controls if a separate .chi index file is generated (YES) or that +# it should be included in the master .chm file (NO). + +GENERATE_CHI = NO + +# If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag +# controls whether a binary table of contents is generated (YES) or a +# normal table of contents (NO) in the .chm file. + +BINARY_TOC = NO + +# The TOC_EXPAND flag can be set to YES to add extra items for group members +# to the contents of the HTML help documentation and to the tree view. + +TOC_EXPAND = NO + +# The DISABLE_INDEX tag can be used to turn on/off the condensed index at +# top of each HTML page. The value NO (the default) enables the index and +# the value YES disables it. + +DISABLE_INDEX = NO + +# This tag can be used to set the number of enum values (range [1..20]) +# that doxygen will group on one line in the generated HTML documentation. + +ENUM_VALUES_PER_LINE = 4 + +# If the GENERATE_TREEVIEW tag is set to YES, a side panel will be +# generated containing a tree-like index structure (just like the one that +# is generated for HTML Help). For this to work a browser that supports +# JavaScript, DHTML, CSS and frames is required (for instance Mozilla 1.0+, +# Netscape 6.0+, Internet explorer 5.0+, or Konqueror). Windows users are +# probably better off using the HTML help feature. + +GENERATE_TREEVIEW = NO + +# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be +# used to set the initial width (in pixels) of the frame in which the tree +# is shown. + +TREEVIEW_WIDTH = 250 + +#--------------------------------------------------------------------------- +# configuration options related to the LaTeX output +#--------------------------------------------------------------------------- + +# If the GENERATE_LATEX tag is set to YES (the default) Doxygen will +# generate Latex output. + +GENERATE_LATEX = NO + +# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `latex' will be used as the default path. + +LATEX_OUTPUT = latex + +# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be +# invoked. If left blank `latex' will be used as the default command name. + +LATEX_CMD_NAME = latex + +# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to +# generate index for LaTeX. If left blank `makeindex' will be used as the +# default command name. + +MAKEINDEX_CMD_NAME = makeindex + +# If the COMPACT_LATEX tag is set to YES Doxygen generates more compact +# LaTeX documents. This may be useful for small projects and may help to +# save some trees in general. + +COMPACT_LATEX = NO + +# The PAPER_TYPE tag can be used to set the paper type that is used +# by the printer. Possible values are: a4, a4wide, letter, legal and +# executive. If left blank a4wide will be used. + +PAPER_TYPE = a4wide + +# The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX +# packages that should be included in the LaTeX output. + +EXTRA_PACKAGES = + +# The LATEX_HEADER tag can be used to specify a personal LaTeX header for +# the generated latex document. The header should contain everything until +# the first chapter. If it is left blank doxygen will generate a +# standard header. Notice: only use this tag if you know what you are doing! + +LATEX_HEADER = + +# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated +# is prepared for conversion to pdf (using ps2pdf). The pdf file will +# contain links (just like the HTML output) instead of page references +# This makes the output suitable for online browsing using a pdf viewer. + +PDF_HYPERLINKS = NO + +# If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of +# plain latex in the generated Makefile. Set this option to YES to get a +# higher quality PDF documentation. + +USE_PDFLATEX = NO + +# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode. +# command to the generated LaTeX files. This will instruct LaTeX to keep +# running if errors occur, instead of asking the user for help. +# This option is also used when generating formulas in HTML. + +LATEX_BATCHMODE = NO + +# If LATEX_HIDE_INDICES is set to YES then doxygen will not +# include the index chapters (such as File Index, Compound Index, etc.) +# in the output. + +LATEX_HIDE_INDICES = NO + +#--------------------------------------------------------------------------- +# configuration options related to the RTF output +#--------------------------------------------------------------------------- + +# If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output +# The RTF output is optimized for Word 97 and may not look very pretty with +# other RTF readers or editors. + +GENERATE_RTF = NO + +# The RTF_OUTPUT tag is used to specify where the RTF docs will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `rtf' will be used as the default path. + +RTF_OUTPUT = rtf + +# If the COMPACT_RTF tag is set to YES Doxygen generates more compact +# RTF documents. This may be useful for small projects and may help to +# save some trees in general. + +COMPACT_RTF = NO + +# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated +# will contain hyperlink fields. The RTF file will +# contain links (just like the HTML output) instead of page references. +# This makes the output suitable for online browsing using WORD or other +# programs which support those fields. +# Note: wordpad (write) and others do not support links. + +RTF_HYPERLINKS = NO + +# Load stylesheet definitions from file. Syntax is similar to doxygen's +# config file, i.e. a series of assignments. You only have to provide +# replacements, missing definitions are set to their default value. + +RTF_STYLESHEET_FILE = + +# Set optional variables used in the generation of an rtf document. +# Syntax is similar to doxygen's config file. + +RTF_EXTENSIONS_FILE = + +#--------------------------------------------------------------------------- +# configuration options related to the man page output +#--------------------------------------------------------------------------- + +# If the GENERATE_MAN tag is set to YES (the default) Doxygen will +# generate man pages + +GENERATE_MAN = NO + +# The MAN_OUTPUT tag is used to specify where the man pages will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `man' will be used as the default path. + +MAN_OUTPUT = man + +# The MAN_EXTENSION tag determines the extension that is added to +# the generated man pages (default is the subroutine's section .3) + +MAN_EXTENSION = .3 + +# If the MAN_LINKS tag is set to YES and Doxygen generates man output, +# then it will generate one additional man file for each entity +# documented in the real man page(s). These additional files +# only source the real man page, but without them the man command +# would be unable to find the correct page. The default is NO. + +MAN_LINKS = NO + +#--------------------------------------------------------------------------- +# configuration options related to the XML output +#--------------------------------------------------------------------------- + +# If the GENERATE_XML tag is set to YES Doxygen will +# generate an XML file that captures the structure of +# the code including all documentation. + +GENERATE_XML = NO + +# The XML_OUTPUT tag is used to specify where the XML pages will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `xml' will be used as the default path. + +XML_OUTPUT = xml + +# The XML_SCHEMA tag can be used to specify an XML schema, +# which can be used by a validating XML parser to check the +# syntax of the XML files. + +XML_SCHEMA = + +# The XML_DTD tag can be used to specify an XML DTD, +# which can be used by a validating XML parser to check the +# syntax of the XML files. + +XML_DTD = + +# If the XML_PROGRAMLISTING tag is set to YES Doxygen will +# dump the program listings (including syntax highlighting +# and cross-referencing information) to the XML output. Note that +# enabling this will significantly increase the size of the XML output. + +XML_PROGRAMLISTING = YES + +#--------------------------------------------------------------------------- +# configuration options for the AutoGen Definitions output +#--------------------------------------------------------------------------- + +# If the GENERATE_AUTOGEN_DEF tag is set to YES Doxygen will +# generate an AutoGen Definitions (see autogen.sf.net) file +# that captures the structure of the code including all +# documentation. Note that this feature is still experimental +# and incomplete at the moment. + +GENERATE_AUTOGEN_DEF = NO + +#--------------------------------------------------------------------------- +# configuration options related to the Perl module output +#--------------------------------------------------------------------------- + +# If the GENERATE_PERLMOD tag is set to YES Doxygen will +# generate a Perl module file that captures the structure of +# the code including all documentation. Note that this +# feature is still experimental and incomplete at the +# moment. + +GENERATE_PERLMOD = NO + +# If the PERLMOD_LATEX tag is set to YES Doxygen will generate +# the necessary Makefile rules, Perl scripts and LaTeX code to be able +# to generate PDF and DVI output from the Perl module output. + +PERLMOD_LATEX = NO + +# If the PERLMOD_PRETTY tag is set to YES the Perl module output will be +# nicely formatted so it can be parsed by a human reader. This is useful +# if you want to understand what is going on. On the other hand, if this +# tag is set to NO the size of the Perl module output will be much smaller +# and Perl will parse it just the same. + +PERLMOD_PRETTY = YES + +# The names of the make variables in the generated doxyrules.make file +# are prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX. +# This is useful so different doxyrules.make files included by the same +# Makefile don't overwrite each other's variables. + +PERLMOD_MAKEVAR_PREFIX = + +#--------------------------------------------------------------------------- +# Configuration options related to the preprocessor +#--------------------------------------------------------------------------- + +# If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will +# evaluate all C-preprocessor directives found in the sources and include +# files. + +ENABLE_PREPROCESSING = YES + +# If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro +# names in the source code. If set to NO (the default) only conditional +# compilation will be performed. Macro expansion can be done in a controlled +# way by setting EXPAND_ONLY_PREDEF to YES. + +MACRO_EXPANSION = NO + +# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES +# then the macro expansion is limited to the macros specified with the +# PREDEFINED and EXPAND_AS_PREDEFINED tags. + +EXPAND_ONLY_PREDEF = NO + +# If the SEARCH_INCLUDES tag is set to YES (the default) the includes files +# in the INCLUDE_PATH (see below) will be search if a #include is found. + +SEARCH_INCLUDES = YES + +# The INCLUDE_PATH tag can be used to specify one or more directories that +# contain include files that are not input files but should be processed by +# the preprocessor. + +INCLUDE_PATH = + +# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard +# patterns (like *.h and *.hpp) to filter out the header-files in the +# directories. If left blank, the patterns specified with FILE_PATTERNS will +# be used. + +INCLUDE_FILE_PATTERNS = + +# The PREDEFINED tag can be used to specify one or more macro names that +# are defined before the preprocessor is started (similar to the -D option of +# gcc). The argument of the tag is a list of macros of the form: name +# or name=definition (no spaces). If the definition and the = are +# omitted =1 is assumed. To prevent a macro definition from being +# undefined via #undef or recursively expanded use the := operator +# instead of the = operator. + +PREDEFINED = + +# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then +# this tag can be used to specify a list of macro names that should be expanded. +# The macro definition that is found in the sources will be used. +# Use the PREDEFINED tag if you want to use a different macro definition. + +EXPAND_AS_DEFINED = + +# If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then +# doxygen's preprocessor will remove all function-like macros that are alone +# on a line, have an all uppercase name, and do not end with a semicolon. Such +# function macros are typically used for boiler-plate code, and will confuse +# the parser if not removed. + +SKIP_FUNCTION_MACROS = YES + +#--------------------------------------------------------------------------- +# Configuration::additions related to external references +#--------------------------------------------------------------------------- + +# The TAGFILES option can be used to specify one or more tagfiles. +# Optionally an initial location of the external documentation +# can be added for each tagfile. The format of a tag file without +# this location is as follows: +# TAGFILES = file1 file2 ... +# Adding location for the tag files is done as follows: +# TAGFILES = file1=loc1 "file2 = loc2" ... +# where "loc1" and "loc2" can be relative or absolute paths or +# URLs. If a location is present for each tag, the installdox tool +# does not have to be run to correct the links. +# Note that each tag file must have a unique name +# (where the name does NOT include the path) +# If a tag file is not located in the directory in which doxygen +# is run, you must also specify the path to the tagfile here. + +TAGFILES = + +# When a file name is specified after GENERATE_TAGFILE, doxygen will create +# a tag file that is based on the input files it reads. + +GENERATE_TAGFILE = + +# If the ALLEXTERNALS tag is set to YES all external classes will be listed +# in the class index. If set to NO only the inherited external classes +# will be listed. + +ALLEXTERNALS = NO + +# If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed +# in the modules index. If set to NO, only the current project's groups will +# be listed. + +EXTERNAL_GROUPS = YES + +# The PERL_PATH should be the absolute path and name of the perl script +# interpreter (i.e. the result of `which perl'). + +PERL_PATH = /usr/bin/perl + +#--------------------------------------------------------------------------- +# Configuration options related to the dot tool +#--------------------------------------------------------------------------- + +# If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will +# generate a inheritance diagram (in HTML, RTF and LaTeX) for classes with base +# or super classes. Setting the tag to NO turns the diagrams off. Note that +# this option is superseded by the HAVE_DOT option below. This is only a +# fallback. It is recommended to install and use dot, since it yields more +# powerful graphs. + +CLASS_DIAGRAMS = YES + +# If set to YES, the inheritance and collaboration graphs will hide +# inheritance and usage relations if the target is undocumented +# or is not a class. + +HIDE_UNDOC_RELATIONS = YES + +# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is +# available from the path. This tool is part of Graphviz, a graph visualization +# toolkit from AT&T and Lucent Bell Labs. The other options in this section +# have no effect if this option is set to NO (the default) + +HAVE_DOT = NO + +# If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen +# will generate a graph for each documented class showing the direct and +# indirect inheritance relations. Setting this tag to YES will force the +# the CLASS_DIAGRAMS tag to NO. + +CLASS_GRAPH = YES + +# If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen +# will generate a graph for each documented class showing the direct and +# indirect implementation dependencies (inheritance, containment, and +# class references variables) of the class with other documented classes. + +COLLABORATION_GRAPH = YES + +# If the GROUP_GRAPHS and HAVE_DOT tags are set to YES then doxygen +# will generate a graph for groups, showing the direct groups dependencies + +GROUP_GRAPHS = YES + +# If the UML_LOOK tag is set to YES doxygen will generate inheritance and +# collaboration diagrams in a style similar to the OMG's Unified Modeling +# Language. + +UML_LOOK = NO + +# If set to YES, the inheritance and collaboration graphs will show the +# relations between templates and their instances. + +TEMPLATE_RELATIONS = NO + +# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT +# tags are set to YES then doxygen will generate a graph for each documented +# file showing the direct and indirect include dependencies of the file with +# other documented files. + +INCLUDE_GRAPH = YES + +# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and +# HAVE_DOT tags are set to YES then doxygen will generate a graph for each +# documented header file showing the documented files that directly or +# indirectly include this file. + +INCLUDED_BY_GRAPH = YES + +# If the CALL_GRAPH and HAVE_DOT tags are set to YES then doxygen will +# generate a call dependency graph for every global function or class method. +# Note that enabling this option will significantly increase the time of a run. +# So in most cases it will be better to enable call graphs for selected +# functions only using the \callgraph command. + +CALL_GRAPH = NO + +# If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen +# will graphical hierarchy of all classes instead of a textual one. + +GRAPHICAL_HIERARCHY = YES + +# If the DIRECTORY_GRAPH, SHOW_DIRECTORIES and HAVE_DOT tags are set to YES +# then doxygen will show the dependencies a directory has on other directories +# in a graphical way. The dependency relations are determined by the #include +# relations between the files in the directories. + +DIRECTORY_GRAPH = YES + +# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images +# generated by dot. Possible values are png, jpg, or gif +# If left blank png will be used. + +DOT_IMAGE_FORMAT = png + +# The tag DOT_PATH can be used to specify the path where the dot tool can be +# found. If left blank, it is assumed the dot tool can be found in the path. + +DOT_PATH = + +# The DOTFILE_DIRS tag can be used to specify one or more directories that +# contain dot files that are included in the documentation (see the +# \dotfile command). + +DOTFILE_DIRS = + +# The MAX_DOT_GRAPH_WIDTH tag can be used to set the maximum allowed width +# (in pixels) of the graphs generated by dot. If a graph becomes larger than +# this value, doxygen will try to truncate the graph, so that it fits within +# the specified constraint. Beware that most browsers cannot cope with very +# large images. + +MAX_DOT_GRAPH_WIDTH = 1024 + +# The MAX_DOT_GRAPH_HEIGHT tag can be used to set the maximum allows height +# (in pixels) of the graphs generated by dot. If a graph becomes larger than +# this value, doxygen will try to truncate the graph, so that it fits within +# the specified constraint. Beware that most browsers cannot cope with very +# large images. + +MAX_DOT_GRAPH_HEIGHT = 1024 + +# The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the +# graphs generated by dot. A depth value of 3 means that only nodes reachable +# from the root by following a path via at most 3 edges will be shown. Nodes +# that lay further from the root node will be omitted. Note that setting this +# option to 1 or 2 may greatly reduce the computation time needed for large +# code bases. Also note that a graph may be further truncated if the graph's +# image dimensions are not sufficient to fit the graph (see MAX_DOT_GRAPH_WIDTH +# and MAX_DOT_GRAPH_HEIGHT). If 0 is used for the depth value (the default), +# the graph is not depth-constrained. + +MAX_DOT_GRAPH_DEPTH = 0 + +# Set the DOT_TRANSPARENT tag to YES to generate images with a transparent +# background. This is disabled by default, which results in a white background. +# Warning: Depending on the platform used, enabling this option may lead to +# badly anti-aliased labels on the edges of a graph (i.e. they become hard to +# read). + +DOT_TRANSPARENT = NO + +# Set the DOT_MULTI_TARGETS tag to YES allow dot to generate multiple output +# files in one run (i.e. multiple -o and -T options on the command line). This +# makes dot run faster, but since only newer versions of dot (>1.8.10) +# support this, this feature is disabled by default. + +DOT_MULTI_TARGETS = NO + +# If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will +# generate a legend page explaining the meaning of the various boxes and +# arrows in the dot generated graphs. + +GENERATE_LEGEND = YES + +# If the DOT_CLEANUP tag is set to YES (the default) Doxygen will +# remove the intermediate dot files that are used to generate +# the various graphs. + +DOT_CLEANUP = YES + +#--------------------------------------------------------------------------- +# Configuration::additions related to the search engine +#--------------------------------------------------------------------------- + +# The SEARCHENGINE tag specifies whether or not a search engine should be +# used. If set to NO the values of all tags below this one will be ignored. + +SEARCHENGINE = NO diff --git a/DRAMSys/gem5/gem5.pro b/DRAMSys/gem5/gem5.pro index e7ba799b..031a3e86 100644 --- a/DRAMSys/gem5/gem5.pro +++ b/DRAMSys/gem5/gem5.pro @@ -33,13 +33,30 @@ DEFINES += TIXML_USE_STL DEFINES += SC_INCLUDE_DYNAMIC_PROCESSES DEFINES += DRAMSYS_GEM5 +dramsys_disable_coverage_check = $$(DRAMSYS_DISABLE_COVERAGE_CHECK) +isEmpty(dramsys_disable_coverage_check) { + coverage_check = true + message(Coverage check ENABLED) +} else { + coverage_check = false + message(Coverage check DISABLED) +} + unix:!macx { - QMAKE_CXXFLAGS += -std=c++11 -O0 -g + QMAKE_CXXFLAGS += -std=c++11 -O0 -g + $$eval(coverage_check) { + QMAKE_CXXFLAGS += -fprofile-arcs -ftest-coverage -fPIC -O0 + QMAKE_LFLAGS += -lgcov --coverage + } } macx: { - CONFIG += c++11 - QMAKE_CXXFLAGS += -std=c++0x -stdlib=libc++ -O0 -g + CONFIG += c++11 + QMAKE_CXXFLAGS += -std=c++0x -stdlib=libc++ -O0 -g + $$eval(coverage_check) { + QMAKE_CXXFLAGS += --coverage + QMAKE_LFLAGS += --coverage + } } INCLUDEPATH += ../library/src/simulation/ @@ -75,23 +92,76 @@ SOURCES += $${gem5_root}/util/tlm/src/sim_control.cc SOURCES += main.cpp DISTFILES += ../DRAMSys.astylerc -DISTFILES += configs/singleElasticTraceReplay.ini + +DISTFILES += etrace_single/config.ini +DISTFILES += etrace_single_L2/HPCG-47MB/config.ini +DISTFILES += etrace_single_L2/Pathfinder/config.ini +DISTFILES += etrace_single_L2/hpcc-linpack/config.ini +DISTFILES += etrace_single_L2/hpcc-fft/config.ini +DISTFILES += etrace_single_L2/config.ini +DISTFILES += etrace_single_L2/hpcc-dgemm/config.ini +DISTFILES += etrace_single_L2/hpcc-gups/config.ini DISTFILES += configs/singleElasticTraceReplayWithL2.ini -DISTFILES += configs/dualElasticTraceReplay.ini DISTFILES += configs/nvdimmp.ini DISTFILES += configs/hello.ini +DISTFILES += configs/dualElasticTraceReplay.ini +DISTFILES += configs/singleElasticTraceReplay.ini DISTFILES += configs/boot_linux.ini +DISTFILES += gem5_fs/stream/config.ini +DISTFILES += gem5_fs/stream/stream_1_cores.rcS +DISTFILES += gem5_fs/parsec/simmedium/fluidanimate/fluidanimate_simmedium_2.rcS +DISTFILES += gem5_fs/parsec/simmedium/fluidanimate/config.ini +DISTFILES += gem5_fs/parsec/simmedium/ferret/config.ini +DISTFILES += gem5_fs/parsec/simmedium/ferret/ferret_simmedium_2.rcS +DISTFILES += gem5_fs/parsec/simmedium/blackscholes/blackscholes_simmedium_2.rcS +DISTFILES += gem5_fs/parsec/simmedium/blackscholes/config.ini +DISTFILES += gem5_fs/parsec/simlarge/streamcluster/config.ini +DISTFILES += gem5_fs/parsec/simlarge/streamcluster/streamcluster_simlarge_2.rcS +DISTFILES += gem5_fs/parsec/simsmall/fluidanimate/fluidanimate_simsmall_2.rcS +DISTFILES += gem5_fs/parsec/simsmall/fluidanimate/config.ini +DISTFILES += gem5_fs/parsec/simsmall/bodytrack/bodytrack_simsmall_2.rcS +DISTFILES += gem5_fs/parsec/simsmall/bodytrack/config.ini +DISTFILES += gem5_fs/parsec/simsmall/ferret/config.ini +DISTFILES += gem5_fs/parsec/simsmall/ferret/ferret_simsmall_2.rcS +DISTFILES += gem5_fs/parsec/simsmall/blackscholes/config.ini +DISTFILES += gem5_fs/parsec/simsmall/blackscholes/blackscholes_simsmall_2.rcS +DISTFILES += gem5_fs/parsec/simdev/fluidanimate/config.ini +DISTFILES += gem5_fs/parsec/simdev/fluidanimate/fluidanimate_simdev_2.rcS +DISTFILES += gem5_fs/parsec/simdev/blackscholes/blackscholes_simdev_2.rcS +DISTFILES += gem5_fs/parsec/simdev/blackscholes/config.ini DISTFILES += examples/tlm_elastic_slave.py DISTFILES += examples/tlm_elastic_slave_mc_direct.py DISTFILES += examples/tlm_elastic_slave_with_l2.py +DISTFILES += gem5_se/almabench/config.ini +DISTFILES += gem5_se/fldry/config.ini +DISTFILES += gem5_se/Queens/config.ini +DISTFILES += gem5_se/chomp/config.ini +DISTFILES += gem5_se/l1_cache/Queens/config.ini +DISTFILES += gem5_se/l1_cache/chomp/config.ini +DISTFILES += gem5_se/l1_cache/Puzzle/config.ini +DISTFILES += gem5_se/l1_cache/RealMM/config.ini +DISTFILES += gem5_se/l1_cache/Perm/config.ini +DISTFILES += gem5_se/l1_cache/Treesort/config.ini +DISTFILES += gem5_se/l1_cache/Bubblesort/config.ini +DISTFILES += gem5_se/l1_cache/misr/config.ini +DISTFILES += gem5_se/l1_cache/exptree/config.ini +DISTFILES += gem5_se/l1_cache/Quicksort/config.ini +DISTFILES += gem5_se/l1_cache/IntMM/config.ini +DISTFILES += gem5_se/l1_cache/Oscar/config.ini +DISTFILES += gem5_se/l1_cache/FloatMM/config.ini +DISTFILES += gem5_se/l1_cache/Towers/config.ini +DISTFILES += gem5_se/run.sh +DISTFILES += gem5_se/Puzzle/config.ini +DISTFILES += gem5_se/RealMM/config.ini +DISTFILES += gem5_se/Perm/config.ini +DISTFILES += gem5_se/Treesort/config.ini DISTFILES += gem5_se/Bubblesort/config.ini +DISTFILES += gem5_se/misr/config.ini +DISTFILES += gem5_se/lpbench/config.ini +DISTFILES += gem5_se/8_cores/config.ini +DISTFILES += gem5_se/exptree/config.ini +DISTFILES += gem5_se/Quicksort/config.ini DISTFILES += gem5_se/IntMM/config.ini DISTFILES += gem5_se/Oscar/config.ini -DISTFILES += gem5_se/Perm/config.ini -DISTFILES += gem5_se/Puzzle/config.ini -DISTFILES += gem5_se/Queens/config.ini -DISTFILES += gem5_se/Quicksort/config.ini -DISTFILES += gem5_se/RealMM/config.ini +DISTFILES += gem5_se/FloatMM/config.ini DISTFILES += gem5_se/Towers/config.ini -DISTFILES += gem5_se/Treesort/config.ini -DISTFILES += gem5_se/run.sh diff --git a/DRAMSys/gem5/gem5_se/hello-x86/config.dot b/DRAMSys/gem5/gem5_se/hello-x86/config.dot new file mode 100644 index 00000000..8b3a6ae1 --- /dev/null +++ b/DRAMSys/gem5/gem5_se/hello-x86/config.dot @@ -0,0 +1,275 @@ +digraph G { +ranksep="1.3"; +subgraph cluster_root { +color="#000000"; +fillcolor="#bab6ae"; +fontcolor="#000000"; +fontname=Arial; +fontsize=14; +label="root \n: Root"; +shape=Mrecord; +style="rounded, filled"; +tooltip="eventq_index=0 full_system=false sim_quantum=0 time_sync_enable=false time_sync_period=100000000000 time_sync_spin_threshold=100000000"; +subgraph cluster_system { +color="#000000"; +fillcolor="#e4e7eb"; +fontcolor="#000000"; +fontname=Arial; +fontsize=14; +label="system \n: System"; +shape=Mrecord; +style="rounded, filled"; +tooltip="boot_osflags=a cache_line_size=64 clk_domain=system.clk_domain default_p_state=UNDEFINED eventq_index=0 exit_on_work_items=false init_param=0 kernel= kernel_addr_check=false kernel_extras= kvm_vm=Null load_addr_mask=18446744073709551615 load_offset=0 mem_mode=timing mem_ranges=0:536870911:0:0:0:0 memories=system.physmem mmap_using_noreserve=false multi_thread=false num_work_ids=16 p_state_clk_gate_bins=20 p_state_clk_gate_max=1000000000000 p_state_clk_gate_min=1000 power_model= readfile= symbolfile= thermal_components= thermal_model=Null work_begin_ckpt_count=0 work_begin_cpu_id_exit=-1 work_begin_exit_count=0 work_cpus_ckpt_count=0 work_end_ckpt_count=0 work_end_exit_count=0 work_item_id=-1"; +system_system_port [color="#000000", fillcolor="#b6b8bc", fontcolor="#000000", fontname=Arial, fontsize=14, label=system_port, shape=Mrecord, style="rounded, filled"]; +subgraph cluster_system_membus { +color="#000000"; +fillcolor="#6f798c"; +fontcolor="#000000"; +fontname=Arial; +fontsize=14; +label="membus \n: SystemXBar"; +shape=Mrecord; +style="rounded, filled"; +tooltip="clk_domain=system.clk_domain default_p_state=UNDEFINED eventq_index=0 forward_latency=4 frontend_latency=3 p_state_clk_gate_bins=20 p_state_clk_gate_max=1000000000000 p_state_clk_gate_min=1000 point_of_coherency=true point_of_unification=true power_model= response_latency=2 snoop_filter=system.membus.snoop_filter snoop_response_latency=4 system=system use_default_range=false width=16"; +system_membus_master [color="#000000", fillcolor="#586070", fontcolor="#000000", fontname=Arial, fontsize=14, label=master, shape=Mrecord, style="rounded, filled"]; +system_membus_slave [color="#000000", fillcolor="#586070", fontcolor="#000000", fontname=Arial, fontsize=14, label=slave, shape=Mrecord, style="rounded, filled"]; +subgraph cluster_system_membus_snoop_filter { +color="#000000"; +fillcolor="#bab6ae"; +fontcolor="#000000"; +fontname=Arial; +fontsize=14; +label="snoop_filter \n: SnoopFilter"; +shape=Mrecord; +style="rounded, filled"; +tooltip="eventq_index=0 lookup_latency=1 max_capacity=8388608 system=system"; +} + +} + +subgraph cluster_system_external_memory { +color="#000000"; +fillcolor="#bab6ae"; +fontcolor="#000000"; +fontname=Arial; +fontsize=14; +label="external_memory \n: ExternalSlave"; +shape=Mrecord; +style="rounded, filled"; +tooltip="addr_ranges=0:536870911:0:0:0:0 clk_domain=system.clk_domain default_p_state=UNDEFINED eventq_index=0 p_state_clk_gate_bins=20 p_state_clk_gate_max=1000000000000 p_state_clk_gate_min=1000 port_data=transactor port_type=tlm_slave power_model="; +system_external_memory_port [color="#000000", fillcolor="#94918b", fontcolor="#000000", fontname=Arial, fontsize=14, label=port, shape=Mrecord, style="rounded, filled"]; +} + +subgraph cluster_system_voltage_domain { +color="#000000"; +fillcolor="#bab6ae"; +fontcolor="#000000"; +fontname=Arial; +fontsize=14; +label="voltage_domain \n: VoltageDomain"; +shape=Mrecord; +style="rounded, filled"; +tooltip="eventq_index=0 voltage=1.0"; +} + +subgraph cluster_system_physmem { +color="#000000"; +fillcolor="#5e5958"; +fontcolor="#000000"; +fontname=Arial; +fontsize=14; +label="physmem \n: SimpleMemory"; +shape=Mrecord; +style="rounded, filled"; +tooltip="bandwidth=73.000000 clk_domain=system.clk_domain conf_table_reported=true default_p_state=UNDEFINED eventq_index=0 in_addr_map=true kvm_map=true latency=30000 latency_var=0 null=false p_state_clk_gate_bins=20 p_state_clk_gate_max=1000000000000 p_state_clk_gate_min=1000 power_model= range=0:134217727:0:0:0:0"; +} + +subgraph cluster_system_clk_domain { +color="#000000"; +fillcolor="#bab6ae"; +fontcolor="#000000"; +fontname=Arial; +fontsize=14; +label="clk_domain \n: SrcClockDomain"; +shape=Mrecord; +style="rounded, filled"; +tooltip="clock=1000 domain_id=-1 eventq_index=0 init_perf_level=0 voltage_domain=system.voltage_domain"; +} + +subgraph cluster_system_cpu_voltage_domain { +color="#000000"; +fillcolor="#bab6ae"; +fontcolor="#000000"; +fontname=Arial; +fontsize=14; +label="cpu_voltage_domain \n: VoltageDomain"; +shape=Mrecord; +style="rounded, filled"; +tooltip="eventq_index=0 voltage=1.0"; +} + +subgraph cluster_system_dvfs_handler { +color="#000000"; +fillcolor="#bab6ae"; +fontcolor="#000000"; +fontname=Arial; +fontsize=14; +label="dvfs_handler \n: DVFSHandler"; +shape=Mrecord; +style="rounded, filled"; +tooltip="domains= enable=false eventq_index=0 sys_clk_domain=system.clk_domain transition_latency=100000000"; +} + +subgraph cluster_system_cpu_clk_domain { +color="#000000"; +fillcolor="#bab6ae"; +fontcolor="#000000"; +fontname=Arial; +fontsize=14; +label="cpu_clk_domain \n: SrcClockDomain"; +shape=Mrecord; +style="rounded, filled"; +tooltip="clock=500 domain_id=-1 eventq_index=0 init_perf_level=0 voltage_domain=system.cpu_voltage_domain"; +} + +subgraph cluster_system_cpu { +color="#000000"; +fillcolor="#bbc6d9"; +fontcolor="#000000"; +fontname=Arial; +fontsize=14; +label="cpu \n: TimingSimpleCPU"; +shape=Mrecord; +style="rounded, filled"; +tooltip="branchPred=Null checker=Null clk_domain=system.cpu_clk_domain cpu_id=0 default_p_state=UNDEFINED do_checkpoint_insts=true do_quiesce=true do_statistics_insts=true dtb=system.cpu.dtb eventq_index=0 function_trace=false function_trace_start=0 interrupts=system.cpu.interrupts isa=system.cpu.isa itb=system.cpu.itb max_insts_all_threads=0 max_insts_any_thread=0 max_loads_all_threads=0 max_loads_any_thread=0 numThreads=1 p_state_clk_gate_bins=20 p_state_clk_gate_max=1000000000000 p_state_clk_gate_min=1000 power_gating_on_idle=false power_model= profile=0 progress_interval=0 pwr_gating_latency=300 simpoint_start_insts= socket_id=0 switched_out=false syscallRetryLatency=10000 system=system tracer=system.cpu.tracer wait_for_remote_gdb=false workload=system.cpu.workload"; +system_cpu_icache_port [color="#000000", fillcolor="#959ead", fontcolor="#000000", fontname=Arial, fontsize=14, label=icache_port, shape=Mrecord, style="rounded, filled"]; +system_cpu_dcache_port [color="#000000", fillcolor="#959ead", fontcolor="#000000", fontname=Arial, fontsize=14, label=dcache_port, shape=Mrecord, style="rounded, filled"]; +subgraph cluster_system_cpu_workload { +color="#000000"; +fillcolor="#bab6ae"; +fontcolor="#000000"; +fontname=Arial; +fontsize=14; +label="workload \n: Process"; +shape=Mrecord; +style="rounded, filled"; +tooltip="cmd=tests/test-progs/hello/bin/x86/linux/hello cwd=/media/disk2/gem5_tnt/gem5 drivers= egid=100 env= errout=cerr euid=100 eventq_index=0 executable=tests/test-progs/hello/bin/x86/linux/hello gid=100 input=cin kvmInSE=false maxStackSize=67108864 output=cout pgid=100 pid=100 ppid=0 simpoint=0 system=system uid=100 useArchPT=false"; +} + +subgraph cluster_system_cpu_apic_clk_domain { +color="#000000"; +fillcolor="#bab6ae"; +fontcolor="#000000"; +fontname=Arial; +fontsize=14; +label="apic_clk_domain \n: DerivedClockDomain"; +shape=Mrecord; +style="rounded, filled"; +tooltip="clk_divider=16 clk_domain=system.cpu_clk_domain eventq_index=0"; +} + +subgraph cluster_system_cpu_dtb { +color="#000000"; +fillcolor="#bab6ae"; +fontcolor="#000000"; +fontname=Arial; +fontsize=14; +label="dtb \n: X86TLB"; +shape=Mrecord; +style="rounded, filled"; +tooltip="eventq_index=0 size=64 walker=system.cpu.dtb.walker"; +subgraph cluster_system_cpu_dtb_walker { +color="#000000"; +fillcolor="#9f9c95"; +fontcolor="#000000"; +fontname=Arial; +fontsize=14; +label="walker \n: X86PagetableWalker"; +shape=Mrecord; +style="rounded, filled"; +tooltip="clk_domain=system.cpu_clk_domain default_p_state=UNDEFINED eventq_index=0 num_squash_per_cycle=4 p_state_clk_gate_bins=20 p_state_clk_gate_max=1000000000000 p_state_clk_gate_min=1000 power_model= system=system"; +system_cpu_dtb_walker_port [color="#000000", fillcolor="#7f7c77", fontcolor="#000000", fontname=Arial, fontsize=14, label=port, shape=Mrecord, style="rounded, filled"]; +} + +} + +subgraph cluster_system_cpu_interrupts { +color="#000000"; +fillcolor="#c7a793"; +fontcolor="#000000"; +fontname=Arial; +fontsize=14; +label="interrupts \n: X86LocalApic"; +shape=Mrecord; +style="rounded, filled"; +tooltip="clk_domain=system.cpu.apic_clk_domain default_p_state=UNDEFINED eventq_index=0 int_latency=1000 p_state_clk_gate_bins=20 p_state_clk_gate_max=1000000000000 p_state_clk_gate_min=1000 pio_addr=2305843009213693952 pio_latency=100000 power_model= system=system"; +system_cpu_interrupts_int_slave [color="#000000", fillcolor="#9f8575", fontcolor="#000000", fontname=Arial, fontsize=14, label=int_slave, shape=Mrecord, style="rounded, filled"]; +system_cpu_interrupts_int_master [color="#000000", fillcolor="#9f8575", fontcolor="#000000", fontname=Arial, fontsize=14, label=int_master, shape=Mrecord, style="rounded, filled"]; +system_cpu_interrupts_pio [color="#000000", fillcolor="#9f8575", fontcolor="#000000", fontname=Arial, fontsize=14, label=pio, shape=Mrecord, style="rounded, filled"]; +} + +subgraph cluster_system_cpu_itb { +color="#000000"; +fillcolor="#bab6ae"; +fontcolor="#000000"; +fontname=Arial; +fontsize=14; +label="itb \n: X86TLB"; +shape=Mrecord; +style="rounded, filled"; +tooltip="eventq_index=0 size=64 walker=system.cpu.itb.walker"; +subgraph cluster_system_cpu_itb_walker { +color="#000000"; +fillcolor="#9f9c95"; +fontcolor="#000000"; +fontname=Arial; +fontsize=14; +label="walker \n: X86PagetableWalker"; +shape=Mrecord; +style="rounded, filled"; +tooltip="clk_domain=system.cpu_clk_domain default_p_state=UNDEFINED eventq_index=0 num_squash_per_cycle=4 p_state_clk_gate_bins=20 p_state_clk_gate_max=1000000000000 p_state_clk_gate_min=1000 power_model= system=system"; +system_cpu_itb_walker_port [color="#000000", fillcolor="#7f7c77", fontcolor="#000000", fontname=Arial, fontsize=14, label=port, shape=Mrecord, style="rounded, filled"]; +} + +} + +subgraph cluster_system_cpu_isa { +color="#000000"; +fillcolor="#bab6ae"; +fontcolor="#000000"; +fontname=Arial; +fontsize=14; +label="isa \n: X86ISA"; +shape=Mrecord; +style="rounded, filled"; +tooltip="eventq_index=0"; +} + +subgraph cluster_system_cpu_tracer { +color="#000000"; +fillcolor="#bab6ae"; +fontcolor="#000000"; +fontname=Arial; +fontsize=14; +label="tracer \n: ExeTracer"; +shape=Mrecord; +style="rounded, filled"; +tooltip="eventq_index=0"; +} + +} + +} + +} + +system_system_port -> system_membus_slave; +system_membus_master -> system_cpu_interrupts_pio; +system_membus_master -> system_cpu_interrupts_int_slave; +system_membus_master -> system_external_memory_port; +system_cpu_icache_port -> system_membus_slave; +system_cpu_dcache_port -> system_membus_slave; +system_cpu_dtb_walker_port -> system_membus_slave; +system_cpu_interrupts_int_master -> system_membus_slave; +system_cpu_itb_walker_port -> system_membus_slave; +} diff --git a/DRAMSys/gem5/gem5_se/hello-x86/config.dot.pdf b/DRAMSys/gem5/gem5_se/hello-x86/config.dot.pdf new file mode 100644 index 00000000..e1f465e9 Binary files /dev/null and b/DRAMSys/gem5/gem5_se/hello-x86/config.dot.pdf differ diff --git a/DRAMSys/gem5/gem5_se/hello-x86/config.dot.svg b/DRAMSys/gem5/gem5_se/hello-x86/config.dot.svg new file mode 100644 index 00000000..d2c806f2 --- /dev/null +++ b/DRAMSys/gem5/gem5_se/hello-x86/config.dot.svg @@ -0,0 +1,193 @@ + + + + + + +G + +cluster_root + + +root +: Root + + + +cluster_system + + +system +: System + + + +cluster_system_membus + + +membus +: SystemXBar + + + +cluster_system_external_memory + + +external_memory +: ExternalSlave + + + +cluster_system_cpu + + +cpu +: TimingSimpleCPU + + + +cluster_system_cpu_dtb + + +dtb +: X86TLB + + + +cluster_system_cpu_dtb_walker + + +walker +: X86PagetableWalker + + + +cluster_system_cpu_interrupts + + +interrupts +: X86LocalApic + + + +cluster_system_cpu_itb + + +itb +: X86TLB + + + +cluster_system_cpu_itb_walker + + +walker +: X86PagetableWalker + + + + +system_system_port + +system_port + + +system_membus_slave + +slave + + +system_system_port->system_membus_slave + + + + +system_membus_master + +master + + +system_external_memory_port + +port + + +system_membus_master->system_external_memory_port + + + + +system_cpu_interrupts_int_slave + +int_slave + + +system_membus_master->system_cpu_interrupts_int_slave + + + + +system_cpu_interrupts_pio + +pio + + +system_membus_master->system_cpu_interrupts_pio + + + + +system_cpu_icache_port + +icache_port + + +system_cpu_icache_port->system_membus_slave + + + + +system_cpu_dcache_port + +dcache_port + + +system_cpu_dcache_port->system_membus_slave + + + + +system_cpu_dtb_walker_port + +port + + +system_cpu_dtb_walker_port->system_membus_slave + + + + +system_cpu_interrupts_int_master + +int_master + + +system_cpu_interrupts_int_master->system_membus_slave + + + + +system_cpu_itb_walker_port + +port + + +system_cpu_itb_walker_port->system_membus_slave + + + + + diff --git a/DRAMSys/gem5/gem5_se/hello-x86/config.ini b/DRAMSys/gem5/gem5_se/hello-x86/config.ini new file mode 100644 index 00000000..52972f4b --- /dev/null +++ b/DRAMSys/gem5/gem5_se/hello-x86/config.ini @@ -0,0 +1,282 @@ +[root] +type=Root +children=system +eventq_index=0 +full_system=false +sim_quantum=0 +time_sync_enable=false +time_sync_period=100000000000 +time_sync_spin_threshold=100000000 + +[system] +type=System +children=clk_domain cpu cpu_clk_domain cpu_voltage_domain dvfs_handler external_memory membus physmem voltage_domain +boot_osflags=a +cache_line_size=64 +clk_domain=system.clk_domain +default_p_state=UNDEFINED +eventq_index=0 +exit_on_work_items=false +init_param=0 +kernel= +kernel_addr_check=false +kernel_extras= +kvm_vm=Null +load_addr_mask=18446744073709551615 +load_offset=0 +mem_mode=timing +mem_ranges=0:536870911:0:0:0:0 +memories=system.physmem +mmap_using_noreserve=false +multi_thread=false +num_work_ids=16 +p_state_clk_gate_bins=20 +p_state_clk_gate_max=1000000000000 +p_state_clk_gate_min=1000 +power_model= +readfile= +symbolfile= +thermal_components= +thermal_model=Null +work_begin_ckpt_count=0 +work_begin_cpu_id_exit=-1 +work_begin_exit_count=0 +work_cpus_ckpt_count=0 +work_end_ckpt_count=0 +work_end_exit_count=0 +work_item_id=-1 +system_port=system.membus.slave[0] + +[system.clk_domain] +type=SrcClockDomain +clock=1000 +domain_id=-1 +eventq_index=0 +init_perf_level=0 +voltage_domain=system.voltage_domain + +[system.cpu] +type=TimingSimpleCPU +children=apic_clk_domain dtb interrupts isa itb tracer workload +branchPred=Null +checker=Null +clk_domain=system.cpu_clk_domain +cpu_id=0 +default_p_state=UNDEFINED +do_checkpoint_insts=true +do_quiesce=true +do_statistics_insts=true +dtb=system.cpu.dtb +eventq_index=0 +function_trace=false +function_trace_start=0 +interrupts=system.cpu.interrupts +isa=system.cpu.isa +itb=system.cpu.itb +max_insts_all_threads=0 +max_insts_any_thread=0 +max_loads_all_threads=0 +max_loads_any_thread=0 +numThreads=1 +p_state_clk_gate_bins=20 +p_state_clk_gate_max=1000000000000 +p_state_clk_gate_min=1000 +power_gating_on_idle=false +power_model= +profile=0 +progress_interval=0 +pwr_gating_latency=300 +simpoint_start_insts= +socket_id=0 +switched_out=false +syscallRetryLatency=10000 +system=system +tracer=system.cpu.tracer +wait_for_remote_gdb=false +workload=system.cpu.workload +dcache_port=system.membus.slave[2] +icache_port=system.membus.slave[1] + +[system.cpu.apic_clk_domain] +type=DerivedClockDomain +clk_divider=16 +clk_domain=system.cpu_clk_domain +eventq_index=0 + +[system.cpu.dtb] +type=X86TLB +children=walker +eventq_index=0 +size=64 +walker=system.cpu.dtb.walker + +[system.cpu.dtb.walker] +type=X86PagetableWalker +clk_domain=system.cpu_clk_domain +default_p_state=UNDEFINED +eventq_index=0 +num_squash_per_cycle=4 +p_state_clk_gate_bins=20 +p_state_clk_gate_max=1000000000000 +p_state_clk_gate_min=1000 +power_model= +system=system +port=system.membus.slave[4] + +[system.cpu.interrupts] +type=X86LocalApic +clk_domain=system.cpu.apic_clk_domain +default_p_state=UNDEFINED +eventq_index=0 +int_latency=1000 +p_state_clk_gate_bins=20 +p_state_clk_gate_max=1000000000000 +p_state_clk_gate_min=1000 +pio_addr=2305843009213693952 +pio_latency=100000 +power_model= +system=system +int_master=system.membus.slave[5] +int_slave=system.membus.master[1] +pio=system.membus.master[0] + +[system.cpu.isa] +type=X86ISA +eventq_index=0 + +[system.cpu.itb] +type=X86TLB +children=walker +eventq_index=0 +size=64 +walker=system.cpu.itb.walker + +[system.cpu.itb.walker] +type=X86PagetableWalker +clk_domain=system.cpu_clk_domain +default_p_state=UNDEFINED +eventq_index=0 +num_squash_per_cycle=4 +p_state_clk_gate_bins=20 +p_state_clk_gate_max=1000000000000 +p_state_clk_gate_min=1000 +power_model= +system=system +port=system.membus.slave[3] + +[system.cpu.tracer] +type=ExeTracer +eventq_index=0 + +[system.cpu.workload] +type=Process +cmd=../../DRAMSys/gem5/gem5_se/hello-x86/hello +cwd= +drivers= +egid=100 +env= +errout=cerr +euid=100 +eventq_index=0 +executable=../../DRAMSys/gem5/gem5_se/hello-x86/hello +gid=100 +input=cin +kvmInSE=false +maxStackSize=67108864 +output=cout +pgid=100 +pid=100 +ppid=0 +simpoint=0 +system=system +uid=100 +useArchPT=false + +[system.cpu_clk_domain] +type=SrcClockDomain +clock=500 +domain_id=-1 +eventq_index=0 +init_perf_level=0 +voltage_domain=system.cpu_voltage_domain + +[system.cpu_voltage_domain] +type=VoltageDomain +eventq_index=0 +voltage=1.0 + +[system.dvfs_handler] +type=DVFSHandler +domains= +enable=false +eventq_index=0 +sys_clk_domain=system.clk_domain +transition_latency=100000000 + +[system.external_memory] +type=ExternalSlave +addr_ranges=0:536870911:0:0:0:0 +clk_domain=system.clk_domain +default_p_state=UNDEFINED +eventq_index=0 +p_state_clk_gate_bins=20 +p_state_clk_gate_max=1000000000000 +p_state_clk_gate_min=1000 +port_data=transactor +port_type=tlm_slave +power_model= +port=system.membus.master[2] + +[system.membus] +type=CoherentXBar +children=snoop_filter +clk_domain=system.clk_domain +default_p_state=UNDEFINED +eventq_index=0 +forward_latency=4 +frontend_latency=3 +p_state_clk_gate_bins=20 +p_state_clk_gate_max=1000000000000 +p_state_clk_gate_min=1000 +point_of_coherency=true +point_of_unification=true +power_model= +response_latency=2 +snoop_filter=system.membus.snoop_filter +snoop_response_latency=4 +system=system +use_default_range=false +width=16 +master=system.cpu.interrupts.pio system.cpu.interrupts.int_slave system.external_memory.port +slave=system.system_port system.cpu.icache_port system.cpu.dcache_port system.cpu.itb.walker.port system.cpu.dtb.walker.port system.cpu.interrupts.int_master + +[system.membus.snoop_filter] +type=SnoopFilter +eventq_index=0 +lookup_latency=1 +max_capacity=8388608 +system=system + +[system.physmem] +type=SimpleMemory +bandwidth=73.000000 +clk_domain=system.clk_domain +conf_table_reported=true +default_p_state=UNDEFINED +eventq_index=0 +in_addr_map=true +kvm_map=true +latency=30000 +latency_var=0 +null=false +p_state_clk_gate_bins=20 +p_state_clk_gate_max=1000000000000 +p_state_clk_gate_min=1000 +power_model= +range=0:134217727:0:0:0:0 + +[system.voltage_domain] +type=VoltageDomain +eventq_index=0 +voltage=1.0 + diff --git a/DRAMSys/gem5/gem5_se/hello-x86/config.json b/DRAMSys/gem5/gem5_se/hello-x86/config.json new file mode 100644 index 00000000..8b3e80bc --- /dev/null +++ b/DRAMSys/gem5/gem5_se/hello-x86/config.json @@ -0,0 +1,397 @@ +{ + "name": null, + "sim_quantum": 0, + "system": { + "kernel": "", + "mmap_using_noreserve": false, + "kernel_addr_check": false, + "membus": { + "point_of_coherency": true, + "system": "system", + "response_latency": 2, + "cxx_class": "CoherentXBar", + "forward_latency": 4, + "clk_domain": "system.clk_domain", + "point_of_unification": true, + "width": 16, + "eventq_index": 0, + "default_p_state": "UNDEFINED", + "p_state_clk_gate_max": 1000000000000, + "master": { + "peer": [ + "system.cpu.interrupts.pio", + "system.cpu.interrupts.int_slave", + "system.external_memory.port" + ], + "role": "MASTER" + }, + "type": "CoherentXBar", + "frontend_latency": 3, + "slave": { + "peer": [ + "system.system_port", + "system.cpu.icache_port", + "system.cpu.dcache_port", + "system.cpu.itb.walker.port", + "system.cpu.dtb.walker.port", + "system.cpu.interrupts.int_master" + ], + "role": "SLAVE" + }, + "p_state_clk_gate_min": 1000, + "snoop_filter": { + "name": "snoop_filter", + "system": "system", + "max_capacity": 8388608, + "eventq_index": 0, + "cxx_class": "SnoopFilter", + "path": "system.membus.snoop_filter", + "type": "SnoopFilter", + "lookup_latency": 1 + }, + "power_model": [], + "path": "system.membus", + "snoop_response_latency": 4, + "name": "membus", + "p_state_clk_gate_bins": 20, + "use_default_range": false + }, + "symbolfile": "", + "kvm_vm": null, + "readfile": "", + "thermal_model": null, + "cxx_class": "System", + "work_begin_cpu_id_exit": -1, + "load_offset": 0, + "work_begin_exit_count": 0, + "p_state_clk_gate_min": 1000, + "memories": [ + "system.physmem" + ], + "work_begin_ckpt_count": 0, + "clk_domain": { + "name": "clk_domain", + "clock": [ + 1000 + ], + "init_perf_level": 0, + "voltage_domain": "system.voltage_domain", + "eventq_index": 0, + "cxx_class": "SrcClockDomain", + "path": "system.clk_domain", + "type": "SrcClockDomain", + "domain_id": -1 + }, + "mem_ranges": [ + "0:536870911:0:0:0:0" + ], + "eventq_index": 0, + "default_p_state": "UNDEFINED", + "p_state_clk_gate_max": 1000000000000, + "dvfs_handler": { + "enable": false, + "name": "dvfs_handler", + "sys_clk_domain": "system.clk_domain", + "transition_latency": 100000000, + "eventq_index": 0, + "cxx_class": "DVFSHandler", + "domains": [], + "path": "system.dvfs_handler", + "type": "DVFSHandler" + }, + "work_end_exit_count": 0, + "type": "System", + "voltage_domain": { + "name": "voltage_domain", + "eventq_index": 0, + "voltage": [ + 1.0 + ], + "cxx_class": "VoltageDomain", + "path": "system.voltage_domain", + "type": "VoltageDomain" + }, + "cache_line_size": 64, + "external_memory": { + "name": "external_memory", + "p_state_clk_gate_min": 1000, + "p_state_clk_gate_bins": 20, + "default_p_state": "UNDEFINED", + "clk_domain": "system.clk_domain", + "power_model": [], + "addr_ranges": [ + "0:536870911:0:0:0:0" + ], + "eventq_index": 0, + "port_type": "tlm_slave", + "cxx_class": "ExternalSlave", + "p_state_clk_gate_max": 1000000000000, + "path": "system.external_memory", + "type": "ExternalSlave", + "port": { + "peer": "system.membus.master[2]", + "role": "SLAVE" + }, + "port_data": "transactor" + }, + "boot_osflags": "a", + "system_port": { + "peer": "system.membus.slave[0]", + "role": "MASTER" + }, + "physmem": { + "range": "0:134217727:0:0:0:0", + "latency": 30000, + "name": "physmem", + "p_state_clk_gate_min": 1000, + "eventq_index": 0, + "p_state_clk_gate_bins": 20, + "default_p_state": "UNDEFINED", + "kvm_map": true, + "clk_domain": "system.clk_domain", + "power_model": [], + "latency_var": 0, + "bandwidth": "73.000000", + "conf_table_reported": true, + "cxx_class": "SimpleMemory", + "p_state_clk_gate_max": 1000000000000, + "path": "system.physmem", + "null": false, + "type": "SimpleMemory", + "in_addr_map": true + }, + "power_model": [], + "work_cpus_ckpt_count": 0, + "thermal_components": [], + "path": "system", + "cpu_clk_domain": { + "name": "cpu_clk_domain", + "clock": [ + 500 + ], + "init_perf_level": 0, + "voltage_domain": "system.cpu_voltage_domain", + "eventq_index": 0, + "cxx_class": "SrcClockDomain", + "path": "system.cpu_clk_domain", + "type": "SrcClockDomain", + "domain_id": -1 + }, + "work_end_ckpt_count": 0, + "mem_mode": "timing", + "name": "system", + "init_param": 0, + "p_state_clk_gate_bins": 20, + "kernel_extras": [], + "load_addr_mask": 18446744073709551615, + "cpu": [ + { + "do_statistics_insts": true, + "numThreads": 1, + "itb": { + "name": "itb", + "eventq_index": 0, + "cxx_class": "X86ISA::TLB", + "walker": { + "name": "walker", + "p_state_clk_gate_min": 1000, + "p_state_clk_gate_bins": 20, + "cxx_class": "X86ISA::Walker", + "clk_domain": "system.cpu_clk_domain", + "power_model": [], + "system": "system", + "eventq_index": 0, + "default_p_state": "UNDEFINED", + "p_state_clk_gate_max": 1000000000000, + "path": "system.cpu.itb.walker", + "type": "X86PagetableWalker", + "port": { + "peer": "system.membus.slave[3]", + "role": "MASTER" + }, + "num_squash_per_cycle": 4 + }, + "path": "system.cpu.itb", + "type": "X86TLB", + "size": 64 + }, + "power_gating_on_idle": false, + "function_trace": false, + "do_checkpoint_insts": true, + "cxx_class": "TimingSimpleCPU", + "max_loads_all_threads": 0, + "system": "system", + "apic_clk_domain": { + "name": "apic_clk_domain", + "clk_domain": "system.cpu_clk_domain", + "eventq_index": 0, + "cxx_class": "DerivedClockDomain", + "path": "system.cpu.apic_clk_domain", + "type": "DerivedClockDomain", + "clk_divider": 16 + }, + "clk_domain": "system.cpu_clk_domain", + "function_trace_start": 0, + "cpu_id": 0, + "checker": null, + "eventq_index": 0, + "default_p_state": "UNDEFINED", + "p_state_clk_gate_max": 1000000000000, + "do_quiesce": true, + "type": "TimingSimpleCPU", + "profile": 0, + "icache_port": { + "peer": "system.membus.slave[1]", + "role": "MASTER" + }, + "p_state_clk_gate_bins": 20, + "p_state_clk_gate_min": 1000, + "syscallRetryLatency": 10000, + "interrupts": [ + { + "int_master": { + "peer": "system.membus.slave[5]", + "role": "MASTER" + }, + "name": "interrupts", + "p_state_clk_gate_min": 1000, + "pio": { + "peer": "system.membus.master[0]", + "role": "SLAVE" + }, + "int_slave": { + "peer": "system.membus.master[1]", + "role": "SLAVE" + }, + "p_state_clk_gate_bins": 20, + "cxx_class": "X86ISA::Interrupts", + "pio_latency": 100000, + "clk_domain": "system.cpu.apic_clk_domain", + "power_model": [], + "system": "system", + "int_latency": 1000, + "eventq_index": 0, + "default_p_state": "UNDEFINED", + "p_state_clk_gate_max": 1000000000000, + "path": "system.cpu.interrupts", + "pio_addr": 2305843009213693952, + "type": "X86LocalApic" + } + ], + "dcache_port": { + "peer": "system.membus.slave[2]", + "role": "MASTER" + }, + "socket_id": 0, + "power_model": [], + "max_insts_all_threads": 0, + "path": "system.cpu", + "pwr_gating_latency": 300, + "max_loads_any_thread": 0, + "switched_out": false, + "workload": [ + { + "uid": 100, + "pid": 100, + "kvmInSE": false, + "cxx_class": "Process", + "executable": "tests/test-progs/hello/bin/x86/linux/hello", + "drivers": [], + "system": "system", + "gid": 100, + "eventq_index": 0, + "env": [], + "maxStackSize": 67108864, + "ppid": 0, + "type": "Process", + "cwd": "/media/disk2/gem5_tnt/gem5", + "pgid": 100, + "simpoint": 0, + "euid": 100, + "input": "cin", + "path": "system.cpu.workload", + "name": "workload", + "cmd": [ + "tests/test-progs/hello/bin/x86/linux/hello" + ], + "errout": "cerr", + "useArchPT": false, + "egid": 100, + "output": "cout" + } + ], + "name": "cpu", + "wait_for_remote_gdb": false, + "dtb": { + "name": "dtb", + "eventq_index": 0, + "cxx_class": "X86ISA::TLB", + "walker": { + "name": "walker", + "p_state_clk_gate_min": 1000, + "p_state_clk_gate_bins": 20, + "cxx_class": "X86ISA::Walker", + "clk_domain": "system.cpu_clk_domain", + "power_model": [], + "system": "system", + "eventq_index": 0, + "default_p_state": "UNDEFINED", + "p_state_clk_gate_max": 1000000000000, + "path": "system.cpu.dtb.walker", + "type": "X86PagetableWalker", + "port": { + "peer": "system.membus.slave[4]", + "role": "MASTER" + }, + "num_squash_per_cycle": 4 + }, + "path": "system.cpu.dtb", + "type": "X86TLB", + "size": 64 + }, + "simpoint_start_insts": [], + "max_insts_any_thread": 0, + "progress_interval": 0, + "branchPred": null, + "isa": [ + { + "eventq_index": 0, + "path": "system.cpu.isa", + "type": "X86ISA", + "name": "isa", + "cxx_class": "X86ISA::ISA" + } + ], + "tracer": { + "eventq_index": 0, + "path": "system.cpu.tracer", + "type": "ExeTracer", + "name": "tracer", + "cxx_class": "Trace::ExeTracer" + } + } + ], + "multi_thread": false, + "cpu_voltage_domain": { + "name": "cpu_voltage_domain", + "eventq_index": 0, + "voltage": [ + 1.0 + ], + "cxx_class": "VoltageDomain", + "path": "system.cpu_voltage_domain", + "type": "VoltageDomain" + }, + "num_work_ids": 16, + "work_item_id": -1, + "exit_on_work_items": false + }, + "time_sync_period": 100000000000, + "eventq_index": 0, + "time_sync_spin_threshold": 100000000, + "cxx_class": "Root", + "path": "root", + "time_sync_enable": false, + "type": "Root", + "full_system": false +} \ No newline at end of file diff --git a/DRAMSys/gem5/gem5_se/hello-x86/hello b/DRAMSys/gem5/gem5_se/hello-x86/hello new file mode 100755 index 00000000..a3ec8dcd Binary files /dev/null and b/DRAMSys/gem5/gem5_se/hello-x86/hello differ diff --git a/DRAMSys/gem5/gem5_se/run.sh b/DRAMSys/gem5/gem5_se/run.sh index 363340e0..0e642cf2 100755 --- a/DRAMSys/gem5/gem5_se/run.sh +++ b/DRAMSys/gem5/gem5_se/run.sh @@ -97,7 +97,9 @@ for s in $simfiles; do cp $sf $simulation logfile=${sfn}_${bin}.log # LD_PRELOAD=/usr/lib/libtcmalloc.so ./${elf} ${simulation} ../../DRAMSys/gem5/gem5_se/${bin}/config.ini 1 > ${logfile} 2>&1 & - ./${elf} ${simulation} ../../DRAMSys/gem5/gem5_se/${bin}/config.ini 1 > ${logfile} 2>&1 & + date >> ${logfile} + time ./${elf} ${simulation} ../../DRAMSys/gem5/gem5_se/${bin}/config.ini 1 >> ${logfile} 2>&1 + date >> ${logfile} done done diff --git a/DRAMSys/library/library.pro b/DRAMSys/library/library.pro index 4364debd..ea30b870 100644 --- a/DRAMSys/library/library.pro +++ b/DRAMSys/library/library.pro @@ -56,32 +56,44 @@ INCLUDEPATH += src/common/third_party/json/include DEFINES += TIXML_USE_STL DEFINES += SC_INCLUDE_DYNAMIC_PROCESSES +dramsys_disable_coverage_check = $$(DRAMSYS_DISABLE_COVERAGE_CHECK) +isEmpty(dramsys_disable_coverage_check) { + coverage_check = true + message(Coverage check ENABLED) +} else { + coverage_check = false + message(Coverage check DISABLED) +} + unix:!macx { - QMAKE_CXXFLAGS += -std=c++11 -O0 -g + QMAKE_CXXFLAGS += -std=c++11 -O0 -g + $$eval(coverage_check) { + QMAKE_CXXFLAGS += -fprofile-arcs -ftest-coverage -fPIC -O0 + QMAKE_LFLAGS += -lgcov --coverage + } } macx: { CONFIG += c++11 QMAKE_CXXFLAGS += -std=c++0x -stdlib=libc++ -O0 -g QMAKE_MACOSX_DEPLOYMENT_TARGET=10.14 + $$eval(coverage_check) { + QMAKE_CXXFLAGS += --coverage + QMAKE_LFLAGS += --coverage + } } QMAKE_CXXFLAGS += -isystem $${systemc_home}/include SOURCES += \ src/common/third_party/tinyxml2/tinyxml2.cpp \ - src/common/xmlAddressdecoder.cpp \ - src/common/Utils.cpp \ src/common/TlmRecorder.cpp \ - src/common/dramExtension.cpp \ src/common/DebugManager.cpp \ src/controller/core/configuration/Configuration.cpp \ src/controller/core/powerdown/PowerDownManagerTimeout.cpp \ src/controller/core/powerdown/PowerDownManagerBankwise.cpp \ src/controller/core/powerdown/PowerDownManager.cpp \ - src/controller/scheduler/ThreadLoad.cpp \ - src/controller/scheduler/PARBS.cpp \ - src/controller/scheduler/Fr_Fcfs.cpp \ + src/controller/scheduler/FrFcfs.cpp \ src/controller/scheduler/Fifo.cpp \ src/controller/scheduler/SMS.cpp \ src/controller/core/refresh/RefreshManagerBankwise.cpp \ @@ -97,12 +109,10 @@ SOURCES += \ src/controller/core/scheduling/checker/PreBChecker.cpp \ src/controller/core/scheduling/checker/ActBChecker.cpp \ src/controller/core/scheduling/ScheduledCommand.cpp \ - src/controller/core/TimingCalculation.cpp \ src/controller/core/Slots.cpp \ src/controller/core/ControllerCore.cpp \ src/simulation/MemoryManager.cpp \ src/simulation/TemperatureController.cpp \ - src/controller/scheduler/readwritegrouper.cpp \ src/controller/core/configuration/ConfigurationLoader.cpp \ src/controller/core/powerdown/NoPowerDown.cpp \ src/controller/Command.cpp \ @@ -122,29 +132,35 @@ SOURCES += \ src/error/ECC/Word.cpp \ src/error/eccbaseclass.cpp \ src/error/ecchamming.cpp \ - src/controller/scheduler/Fr_Fcfs_read_priority.cpp \ - src/controller/scheduler/Fr_Fcfs_grouper.cpp \ + src/controller/scheduler/FrFcfsRp.cpp \ + src/controller/scheduler/FrFcfsGrp.cpp \ + src/controller/scheduler/Grp.cpp \ src/controller/RecordableController.cpp \ src/common/AddressDecoder.cpp \ - src/controller/scheduler/grp.cpp \ - src/common/congenAddressDecoder.cpp + src/simulation/Dram.cpp \ + src/simulation/RecordableDram.cpp \ + src/simulation/Arbiter.cpp \ + src/common/CongenAddressDecoder.cpp \ + src/common/XmlAddressDecoder.cpp \ + src/controller/core/timingCalculations.cpp \ + src/common/dramExtensions.cpp \ + src/common/utils.cpp \ + src/simulation/DramDDR3.cpp \ + src/simulation/DramDDR4.cpp \ + src/simulation/DramRecordable.cpp \ + src/simulation/DramWideIO.cpp HEADERS += \ src/common/third_party/tinyxml2/tinyxml2.h \ - src/common/xmlAddressdecoder.h \ - src/common/Utils.h \ src/common/TlmRecorder.h \ src/common/tlm2_base_protocol_checker.h \ src/common/protocol.h \ - src/common/dramExtension.h \ src/common/DebugManager.h \ src/controller/core/configuration/Configuration.h \ src/controller/core/powerdown/PowerDownManagerTimeout.h \ src/controller/core/powerdown/PowerDownManagerBankwise.h \ src/controller/core/powerdown/PowerDownManager.h \ - src/controller/scheduler/ThreadLoad.h \ - src/controller/scheduler/PARBS.h \ - src/controller/scheduler/Fr_Fcfs.h \ + src/controller/scheduler/FrFcfs.h \ src/controller/scheduler/Fifo.h \ src/controller/scheduler/SMS.h \ src/controller/Controller.h \ @@ -162,9 +178,7 @@ HEADERS += \ src/controller/core/scheduling/checker/ActivateChecker.h \ src/controller/core/scheduling/checker/PreBChecker.h \ src/controller/core/scheduling/checker/ActBChecker.h \ - src/controller/core/scheduling/Trigger.h \ src/controller/core/scheduling/ScheduledCommand.h \ - src/controller/core/TimingCalculation.h \ src/controller/core/Slots.h \ src/controller/core/ControllerCore.h \ src/simulation/TracePlayer.h \ @@ -172,10 +186,8 @@ HEADERS += \ src/simulation/Dram.h \ src/simulation/Arbiter.h \ src/common/libDRAMPower.h \ - src/controller/scheduler/readwritegrouper.h \ src/simulation/ReorderBuffer.h \ src/controller/core/configuration/MemSpec.h \ - src/controller/core/configuration/thermalSimConfig.h \ src/simulation/StlPlayer.h \ src/simulation/TracePlayerListener.h \ src/simulation/TraceGenerator.h \ @@ -200,15 +212,24 @@ HEADERS += \ src/error/ECC/Word.h \ src/error/eccbaseclass.h \ src/error/ecchamming.h \ - src/controller/scheduler/Fr_Fcfs_read_priority.h \ - src/controller/scheduler/Fr_Fcfs_grouper.h \ + src/controller/scheduler/FrFcfsRp.h \ + src/controller/scheduler/FrFcfsGrp.h \ + src/controller/scheduler/Grp.h \ src/simulation/IArbiter.h \ src/simulation/SimpleArbiter.h \ src/controller/RecordableController.h \ src/simulation/RecordableDram.h \ src/common/AddressDecoder.h \ - src/controller/scheduler/grp.h \ - src/common/congenAddressDecoder.h + src/common/CongenAddressDecoder.h \ + src/common/XmlAddressDecoder.h \ + src/controller/core/timingCalculations.h \ + src/common/dramExtensions.h \ + src/common/utils.h \ + src/controller/core/configuration/TemperatureSimConfig.h \ + src/simulation/DramDDR3.h \ + src/simulation/DramDDR4.h \ + src/simulation/DramRecordable.h \ + src/simulation/DramWideIO.h #src/common/third_party/json/include/nlohmann/json.hpp \ thermalsim = $$(THERMALSIM) diff --git a/DRAMSys/library/resources/configs/amconfigs/rgram-rbc.xml b/DRAMSys/library/resources/configs/amconfigs/rgram-rbc.xml new file mode 100644 index 00000000..689aad68 --- /dev/null +++ b/DRAMSys/library/resources/configs/amconfigs/rgram-rbc.xml @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/DRAMSys/library/resources/configs/mcconfigs/fifo.xml b/DRAMSys/library/resources/configs/mcconfigs/fifo.xml index 73231bba..d01b9248 100644 --- a/DRAMSys/library/resources/configs/mcconfigs/fifo.xml +++ b/DRAMSys/library/resources/configs/mcconfigs/fifo.xml @@ -1,7 +1,7 @@ - + diff --git a/DRAMSys/library/resources/configs/mcconfigs/fifoStrict.xml b/DRAMSys/library/resources/configs/mcconfigs/fifoStrict.xml index dee4f5d4..ed869b57 100644 --- a/DRAMSys/library/resources/configs/mcconfigs/fifoStrict.xml +++ b/DRAMSys/library/resources/configs/mcconfigs/fifoStrict.xml @@ -1,7 +1,7 @@ - + diff --git a/DRAMSys/library/resources/configs/mcconfigs/fifo_ecc.xml b/DRAMSys/library/resources/configs/mcconfigs/fifo_ecc.xml index 73231bba..d01b9248 100644 --- a/DRAMSys/library/resources/configs/mcconfigs/fifo_ecc.xml +++ b/DRAMSys/library/resources/configs/mcconfigs/fifo_ecc.xml @@ -1,7 +1,7 @@ - + diff --git a/DRAMSys/library/resources/configs/mcconfigs/fr_fcfs.xml b/DRAMSys/library/resources/configs/mcconfigs/fr_fcfs.xml index e5a6579e..20db08cd 100644 --- a/DRAMSys/library/resources/configs/mcconfigs/fr_fcfs.xml +++ b/DRAMSys/library/resources/configs/mcconfigs/fr_fcfs.xml @@ -1,7 +1,7 @@ - + diff --git a/DRAMSys/library/resources/configs/mcconfigs/fr_fcfs_grp.xml b/DRAMSys/library/resources/configs/mcconfigs/fr_fcfs_grp.xml index 75570d40..dad77bf6 100644 --- a/DRAMSys/library/resources/configs/mcconfigs/fr_fcfs_grp.xml +++ b/DRAMSys/library/resources/configs/mcconfigs/fr_fcfs_grp.xml @@ -1,7 +1,7 @@ - + diff --git a/DRAMSys/library/resources/configs/mcconfigs/fr_fcfs_rp.xml b/DRAMSys/library/resources/configs/mcconfigs/fr_fcfs_rp.xml index 5a9f1c0c..3f636ba0 100644 --- a/DRAMSys/library/resources/configs/mcconfigs/fr_fcfs_rp.xml +++ b/DRAMSys/library/resources/configs/mcconfigs/fr_fcfs_rp.xml @@ -1,7 +1,7 @@ - + diff --git a/DRAMSys/library/resources/configs/mcconfigs/grp.xml b/DRAMSys/library/resources/configs/mcconfigs/grp.xml index a62969fb..753cca46 100644 --- a/DRAMSys/library/resources/configs/mcconfigs/grp.xml +++ b/DRAMSys/library/resources/configs/mcconfigs/grp.xml @@ -1,7 +1,7 @@ - + diff --git a/DRAMSys/library/resources/configs/mcconfigs/rgrmccfg.xml b/DRAMSys/library/resources/configs/mcconfigs/rgrmccfg.xml index bb8b64ae..b17e59ce 100644 --- a/DRAMSys/library/resources/configs/mcconfigs/rgrmccfg.xml +++ b/DRAMSys/library/resources/configs/mcconfigs/rgrmccfg.xml @@ -1,7 +1,7 @@ - + diff --git a/DRAMSys/library/resources/configs/simulator/rgrsimcfg-gem5-fs.xml b/DRAMSys/library/resources/configs/simulator/rgrsimcfg-gem5-fs.xml new file mode 100644 index 00000000..47c6a016 --- /dev/null +++ b/DRAMSys/library/resources/configs/simulator/rgrsimcfg-gem5-fs.xml @@ -0,0 +1,19 @@ + + + + + + + + + + + + + + + + + + + diff --git a/DRAMSys/library/resources/resources.pri b/DRAMSys/library/resources/resources.pri index 36bf4859..ddd5d42b 100644 --- a/DRAMSys/library/resources/resources.pri +++ b/DRAMSys/library/resources/resources.pri @@ -77,16 +77,41 @@ DISTFILES += resources/scripts/analyse_trace.pl DISTFILES += resources/scripts/video_rendering/temperatur.job.pl DISTFILES += resources/scripts/video_rendering/temperatur.pl DISTFILES += resources/scripts/video_rendering/Makefile -DISTFILES += resources/scripts/DRAMSylva/LICENSE -DISTFILES += resources/scripts/DRAMSylva/README -DISTFILES += resources/scripts/DRAMSylva/DRAMSylva.patch +DISTFILES += resources/scripts/DRAMSylva/collect.sh +DISTFILES += resources/scripts/DRAMSylva/common.in +DISTFILES += resources/scripts/DRAMSylva/DRAMSylva.jobscript DISTFILES += resources/scripts/DRAMSylva/DRAMSylva.sh DISTFILES += resources/scripts/DRAMSylva/DRAMSylvaCSVPlot.py DISTFILES += resources/scripts/DRAMSylva/DRAMSyrup.py -DISTFILES += resources/scripts/DRAMSylva/configs.json +DISTFILES += resources/scripts/DRAMSylva/gem5ilva.jobscript +DISTFILES += resources/scripts/DRAMSylva/gem5ilva.sh +DISTFILES += resources/scripts/DRAMSylva/gem5ilva_fs.jobscript +DISTFILES += resources/scripts/DRAMSylva/gem5ilva_fs.sh +DISTFILES += resources/scripts/DRAMSylva/LICENSE +DISTFILES += resources/scripts/DRAMSylva/README +DISTFILES += resources/scripts/DRAMSylva/configs_json/configs.json +DISTFILES += resources/scripts/DRAMSylva/configs_json/configsbrc.json +DISTFILES += resources/scripts/DRAMSylva/configs_json/configsbrc1x.json +DISTFILES += resources/scripts/DRAMSylva/configs_json/configsbrc1x_gem5.json +DISTFILES += resources/scripts/DRAMSylva/configs_json/configsbrc2x.json +DISTFILES += resources/scripts/DRAMSylva/configs_json/configsbrc2x_gem5.json +DISTFILES += resources/scripts/DRAMSylva/configs_json/configsbrc4x.json +DISTFILES += resources/scripts/DRAMSylva/configs_json/configsbrc4x_gem5.json +DISTFILES += resources/scripts/DRAMSylva/configs_json/configsrbc.json +DISTFILES += resources/scripts/DRAMSylva/configs_json/configsrbc1x.json +DISTFILES += resources/scripts/DRAMSylva/configs_json/configsrbc1x_gem5.json +DISTFILES += resources/scripts/DRAMSylva/configs_json/configsrbc1x_gem5_fs.json +DISTFILES += resources/scripts/DRAMSylva/configs_json/configsrbc1x_gem5_fs_nodb.json +DISTFILES += resources/scripts/DRAMSylva/configs_json/configsrbc2x.json +DISTFILES += resources/scripts/DRAMSylva/configs_json/configsrbc2x_gem5.json +DISTFILES += resources/scripts/DRAMSylva/configs_json/configsrbc4x.json +DISTFILES += resources/scripts/DRAMSylva/configs_json/configsrbc4x_gem5.json +DISTFILES += resources/scripts/DRAMSylva/configs_json/ref.json +DISTFILES += resources/scripts/DRAMSylva/configs_json/ref_bw.json DISTFILES += resources/scripts/trace_gen.py DISTFILES += resources/scripts/traceGenerationForNNTraining.pl + # Trace Files DISTFILES += resources/traces/chstone-aes_32.stl DISTFILES += resources/traces/test2.stl diff --git a/DRAMSys/library/resources/simulations/rgrsim-gem5-fs.xml b/DRAMSys/library/resources/simulations/rgrsim-gem5-fs.xml new file mode 100644 index 00000000..a6e1ad3c --- /dev/null +++ b/DRAMSys/library/resources/simulations/rgrsim-gem5-fs.xml @@ -0,0 +1,20 @@ + + + + + + + + + + + + + + + + diff --git a/DRAMSys/library/src/common/AddressDecoder.cpp b/DRAMSys/library/src/common/AddressDecoder.cpp index f5eb23ce..b0a3b98f 100644 --- a/DRAMSys/library/src/common/AddressDecoder.cpp +++ b/DRAMSys/library/src/common/AddressDecoder.cpp @@ -34,8 +34,8 @@ */ #include "AddressDecoder.h" -#include "xmlAddressdecoder.h" -#include "congenAddressDecoder.h" +#include "XmlAddressDecoder.h" +#include "CongenAddressDecoder.h" AddressDecoder *AddressDecoder::m_pInstance = nullptr; @@ -50,7 +50,7 @@ void AddressDecoder::createInstance(Type t) assert(m_pInstance == nullptr); switch (t) { case Type::XML: - m_pInstance = new xmlAddressDecoder; + m_pInstance = new XmlAddressDecoder; break; case Type::CONGEN: m_pInstance = new CongenAddressDecoder; diff --git a/DRAMSys/library/src/common/congenAddressDecoder.cpp b/DRAMSys/library/src/common/CongenAddressDecoder.cpp similarity index 99% rename from DRAMSys/library/src/common/congenAddressDecoder.cpp rename to DRAMSys/library/src/common/CongenAddressDecoder.cpp index 5a366741..ea11dcbc 100644 --- a/DRAMSys/library/src/common/congenAddressDecoder.cpp +++ b/DRAMSys/library/src/common/CongenAddressDecoder.cpp @@ -33,8 +33,8 @@ * Johannes Feldmann */ -#include "congenAddressDecoder.h" -#include "Utils.h" +#include "CongenAddressDecoder.h" +#include "utils.h" #include diff --git a/DRAMSys/library/src/common/congenAddressDecoder.h b/DRAMSys/library/src/common/CongenAddressDecoder.h similarity index 98% rename from DRAMSys/library/src/common/congenAddressDecoder.h rename to DRAMSys/library/src/common/CongenAddressDecoder.h index e2d210a5..51778ecf 100644 --- a/DRAMSys/library/src/common/congenAddressDecoder.h +++ b/DRAMSys/library/src/common/CongenAddressDecoder.h @@ -47,8 +47,7 @@ using std::vector; using std::pair; using std::map; -class CongenAddressDecoder - : private AddressDecoder +class CongenAddressDecoder : private AddressDecoder { // Friendship needed so that the AddressDecoder can access the // constructor of this class to create the object in CreateInstance. diff --git a/DRAMSys/library/src/common/DebugManager.h b/DRAMSys/library/src/common/DebugManager.h index be40527b..dd35b796 100644 --- a/DRAMSys/library/src/common/DebugManager.h +++ b/DRAMSys/library/src/common/DebugManager.h @@ -34,13 +34,13 @@ * Matthias Jung */ -#ifndef DEBUGMANAGER_H_ -#define DEBUGMANAGER_H_ +#ifndef DEBUGMANAGER_H +#define DEBUGMANAGER_H #include #include #include -#include "Utils.h" +#include "utils.h" class DebugManager { @@ -63,4 +63,4 @@ private: ofstream debugFile; }; -#endif /* DEBUGMANAGER_H_ */ +#endif // DEBUGMANAGER_H diff --git a/DRAMSys/library/src/common/TlmRecorder.cpp b/DRAMSys/library/src/common/TlmRecorder.cpp index b0d21f33..c4b626fb 100644 --- a/DRAMSys/library/src/common/TlmRecorder.cpp +++ b/DRAMSys/library/src/common/TlmRecorder.cpp @@ -41,8 +41,8 @@ #include "TlmRecorder.h" #include "protocol.h" -#include "dramExtension.h" -#include "xmlAddressdecoder.h" +#include "dramExtensions.h" +#include "XmlAddressDecoder.h" #include "../controller/core/configuration/Configuration.h" #include "../controller/Controller.h" @@ -325,9 +325,9 @@ void TlmRecorder::insertGeneralInfo() sqlite3_bind_int64(insertGeneralInfoStatement, 2, simulationTimeCoveredByRecording.value()); sqlite3_bind_int(insertGeneralInfoStatement, 3, - Configuration::getInstance().memSpec.NumberOfBanks); + Configuration::getInstance().memSpec->NumberOfBanks); sqlite3_bind_int(insertGeneralInfoStatement, 4, - Configuration::getInstance().memSpec.clk.value()); + Configuration::getInstance().memSpec->clk.value()); sqlite3_bind_text(insertGeneralInfoStatement, 5, "PS", 2, NULL); sqlite3_bind_text(insertGeneralInfoStatement, 6, mcconfig.c_str(), mcconfig.length(), NULL); @@ -339,7 +339,7 @@ void TlmRecorder::insertGeneralInfo() sqlite3_bind_int64(insertGeneralInfoStatement, 9, 0); else sqlite3_bind_int64(insertGeneralInfoStatement, 9, - (Configuration::getInstance().memSpec.clk * + (Configuration::getInstance().memSpec->clk * Configuration::getInstance().WindowSize).value()); if (Configuration::getInstance().ControllerCoreRefEnablePostpone || Configuration::getInstance().ControllerCoreRefEnablePullIn) { diff --git a/DRAMSys/library/src/common/TlmRecorder.h b/DRAMSys/library/src/common/TlmRecorder.h index 8abcb2ac..683988a9 100644 --- a/DRAMSys/library/src/common/TlmRecorder.h +++ b/DRAMSys/library/src/common/TlmRecorder.h @@ -36,8 +36,8 @@ * Eder F. Zulian */ -#ifndef TLMPHASERECORDER_H -#define TLMPHASERECORDER_H +#ifndef TLMRECORDER_H +#define TLMRECORDER_H #include #include @@ -49,9 +49,9 @@ #include #include #include -#include "xmlAddressdecoder.h" +#include "XmlAddressDecoder.h" #include "DebugManager.h" -#include "Utils.h" +#include "utils.h" using namespace std; @@ -151,5 +151,5 @@ private: insertDebugMessageString, updateDataStrobeString, insertPowerString; }; -#endif +#endif // TLMRECORDER_H diff --git a/DRAMSys/library/src/common/xmlAddressdecoder.cpp b/DRAMSys/library/src/common/XmlAddressDecoder.cpp similarity index 89% rename from DRAMSys/library/src/common/xmlAddressdecoder.cpp rename to DRAMSys/library/src/common/XmlAddressDecoder.cpp index 11f4549c..dfbb4dd8 100644 --- a/DRAMSys/library/src/common/xmlAddressdecoder.cpp +++ b/DRAMSys/library/src/common/XmlAddressDecoder.cpp @@ -35,21 +35,21 @@ * Matthias Jung */ -#include "xmlAddressdecoder.h" +#include "XmlAddressDecoder.h" #include -#include "Utils.h" +#include "utils.h" #include "bitset" #include "../controller/core/configuration/Configuration.h" using namespace std; using namespace tinyxml2; -xmlAddressDecoder::xmlAddressDecoder() +XmlAddressDecoder::XmlAddressDecoder() { addressmapping = NULL; } -void xmlAddressDecoder::setConfiguration(std::string addressConfigURI) +void XmlAddressDecoder::setConfiguration(std::string addressConfigURI) { tinyxml2::XMLDocument doc; loadXML(addressConfigURI, doc); @@ -76,7 +76,7 @@ void xmlAddressDecoder::setConfiguration(std::string addressConfigURI) } -DecodedAddress xmlAddressDecoder::decodeAddress(sc_dt::uint64 addr) +DecodedAddress XmlAddressDecoder::decodeAddress(sc_dt::uint64 addr) { DecodedAddress result; result.channel = (addr & masks["channel"]) >> shifts["channel"]; @@ -84,15 +84,15 @@ DecodedAddress xmlAddressDecoder::decodeAddress(sc_dt::uint64 addr) //result.bankgroup = (addr & masks["bankgroup"]) >> shifts["bankgroup"]; result.bank = (addr & masks["bank"]) >> shifts["bank"]; result.bankgroup = result.bank % - Configuration::getInstance().memSpec.NumberOfBankGroups; - result.rank = result.bank % Configuration::getInstance().memSpec.NumberOfRanks; + Configuration::getInstance().memSpec->NumberOfBankGroups; + result.rank = result.bank % Configuration::getInstance().memSpec->NumberOfRanks; result.row = (addr & masks["row"]) >> shifts["row"]; result.column = (addr & masks["column"]) >> shifts["column"]; result.bytes = (addr & masks["bytes"]) >> shifts["bytes"]; return result; } -sc_dt::uint64 xmlAddressDecoder::encodeAddress(DecodedAddress n) +sc_dt::uint64 XmlAddressDecoder::encodeAddress(DecodedAddress n) { return n.channel << shifts["channel"] | n.rank << shifts["rank"] | @@ -103,7 +103,7 @@ sc_dt::uint64 xmlAddressDecoder::encodeAddress(DecodedAddress n) n.bytes << shifts["bytes"]; } -bool xmlAddressDecoder::testConfigFile(std::string url) +bool XmlAddressDecoder::testConfigFile(std::string url) { // Simple test if the root node has the correct name. // This is suitable for now, but can be extended in future. @@ -115,7 +115,7 @@ bool xmlAddressDecoder::testConfigFile(std::string url) return (strcmp(addressMap->Name(), "addressmapping") == 0); } -void xmlAddressDecoder::print() +void XmlAddressDecoder::print() { cout << headline << endl; cout << "Address Mapping:" << endl << endl; diff --git a/DRAMSys/library/src/common/xmlAddressdecoder.h b/DRAMSys/library/src/common/XmlAddressDecoder.h similarity index 92% rename from DRAMSys/library/src/common/xmlAddressdecoder.h rename to DRAMSys/library/src/common/XmlAddressDecoder.h index de1e574c..dfd65072 100644 --- a/DRAMSys/library/src/common/xmlAddressdecoder.h +++ b/DRAMSys/library/src/common/XmlAddressDecoder.h @@ -35,17 +35,16 @@ * Matthias Jung */ -#ifndef _XMLADDRESSDECODER_H -#define _XMLADDRESSDECODER_H +#ifndef XMLADDRESSDECODER_H +#define XMLADDRESSDECODER_H #include -#include "Utils.h" +#include "utils.h" #include "third_party/tinyxml2/tinyxml2.h" #include "AddressDecoder.h" -class xmlAddressDecoder - : private AddressDecoder +class XmlAddressDecoder : private AddressDecoder { // Friendship needed so that the AddressDecoder can access the // constructor of this class to create the object in CreateInstance. @@ -58,7 +57,7 @@ private: tinyxml2::XMLElement *addressmapping; public: - xmlAddressDecoder(); + XmlAddressDecoder(); virtual DecodedAddress decodeAddress(sc_dt::uint64 addr); virtual sc_dt::uint64 encodeAddress(DecodedAddress n); @@ -71,4 +70,4 @@ public: virtual void print(); }; -#endif +#endif // XMLADDRESSDECODER_H diff --git a/DRAMSys/library/src/common/dramExtension.cpp b/DRAMSys/library/src/common/dramExtensions.cpp similarity index 98% rename from DRAMSys/library/src/common/dramExtension.cpp rename to DRAMSys/library/src/common/dramExtensions.cpp index bfb7b7c4..ed1d0b0d 100644 --- a/DRAMSys/library/src/common/dramExtension.cpp +++ b/DRAMSys/library/src/common/dramExtensions.cpp @@ -35,10 +35,10 @@ * Matthias Jung */ -#include "dramExtension.h" +#include "dramExtensions.h" #include "../controller/core/configuration/Configuration.h" #include "map" -#include "Utils.h" +#include "utils.h" using namespace tlm; @@ -281,7 +281,7 @@ bool operator !=(const Row &lhs, const Row &rhs) const Row Row::operator ++() { - id = (id + 1) % Configuration::getInstance().memSpec.NumberOfRows; + id = (id + 1) % Configuration::getInstance().memSpec->NumberOfRows; return *this; } diff --git a/DRAMSys/library/src/common/dramExtension.h b/DRAMSys/library/src/common/dramExtensions.h similarity index 91% rename from DRAMSys/library/src/common/dramExtension.h rename to DRAMSys/library/src/common/dramExtensions.h index 19176cc5..3a4b1a51 100644 --- a/DRAMSys/library/src/common/dramExtension.h +++ b/DRAMSys/library/src/common/dramExtensions.h @@ -34,26 +34,23 @@ * Matthias Jung */ -#ifndef DRAMEXTENSION_H_ -#define DRAMEXTENSION_H_ +#ifndef DRAMEXTENSIONS_H +#define DRAMEXTENSIONS_H #include #include #include - class Thread { public: - explicit Thread(unsigned int id) : - id(id) - { - } + explicit Thread(unsigned int id) : id(id) {} unsigned int ID() const { return id; } + private: unsigned int id; }; @@ -61,14 +58,13 @@ private: class Channel { public: - explicit Channel(unsigned int id) : - id(id) - { - } + explicit Channel(unsigned int id) : id(id) {} + unsigned int ID() const { return id; } + private: unsigned int id; }; @@ -76,14 +72,13 @@ private: class BankGroup { public: - explicit BankGroup(unsigned int id) : - id(id) - { - } + explicit BankGroup(unsigned int id) : id(id) {} + unsigned int ID() const { return id; } + private: unsigned int id; }; @@ -91,10 +86,8 @@ private: class Bank { public: - Bank(unsigned int id) : - id(id) - { - } + Bank(unsigned int id) : id(id) {} + unsigned int ID() const { return id; @@ -110,7 +103,6 @@ public: return std::to_string(id); } - private: unsigned int id; }; @@ -120,14 +112,9 @@ class Row public: static const Row NO_ROW; - Row() : - id(0), isNoRow(true) - { - } - explicit Row(unsigned int id) : - id(id), isNoRow(false) - { - } + Row() : id(0), isNoRow(true) {} + + explicit Row(unsigned int id) : id(id), isNoRow(false) {} unsigned int ID() const { @@ -135,6 +122,7 @@ public: } const Row operator++(); + private: unsigned int id; bool isNoRow; @@ -145,21 +133,19 @@ private: class Column { public: - explicit Column(unsigned int id) : - id(id) - { - } + explicit Column(unsigned int id) : id(id) {} unsigned int ID() const { return id; } + private: unsigned int id; }; -class DramExtension: public tlm::tlm_extension +class DramExtension : public tlm::tlm_extension { public: DramExtension(); @@ -251,4 +237,4 @@ bool operator!=(const Row &lhs, const Row &rhs); bool operator==(const Column &lhs, const Column &rhs); bool operator!=(const Column &lhs, const Column &rhs); -#endif /* DRAMEXTENSION_H_ */ +#endif // DRAMEXTENSIONS_H diff --git a/DRAMSys/library/src/common/protocol.h b/DRAMSys/library/src/common/protocol.h index 00b03c36..06af9c30 100644 --- a/DRAMSys/library/src/common/protocol.h +++ b/DRAMSys/library/src/common/protocol.h @@ -35,8 +35,8 @@ * Matthias Jung */ -#ifndef EXTENDED_PHASE_DRAM -#define EXTENDED_PHASE_DRAM +#ifndef PROTOCOL_H +#define PROTOCOL_H // DRAM Control Phases DECLARE_EXTENDED_PHASE(BEGIN_PREB); @@ -100,5 +100,5 @@ DECLARE_EXTENDED_PHASE(REF_TRIGGER); DECLARE_EXTENDED_PHASE(PDN_TRIGGER); -#endif +#endif // PROTOCOL_H diff --git a/DRAMSys/library/src/common/third_party/DRAMPower b/DRAMSys/library/src/common/third_party/DRAMPower index fa0627c4..746d56ea 160000 --- a/DRAMSys/library/src/common/third_party/DRAMPower +++ b/DRAMSys/library/src/common/third_party/DRAMPower @@ -1 +1 @@ -Subproject commit fa0627c4e6c5b35a040e416592061fb7e672daaf +Subproject commit 746d56ea53c5227428fff3e13716a68f259ad243 diff --git a/DRAMSys/library/src/common/Utils.cpp b/DRAMSys/library/src/common/utils.cpp similarity index 99% rename from DRAMSys/library/src/common/Utils.cpp rename to DRAMSys/library/src/common/utils.cpp index 6634201b..69c6f899 100644 --- a/DRAMSys/library/src/common/Utils.cpp +++ b/DRAMSys/library/src/common/utils.cpp @@ -35,11 +35,11 @@ * Matthias Jung */ -#include "Utils.h" +#include "utils.h" #include #include #include -#include "dramExtension.h" +#include "dramExtensions.h" #include "../controller/Controller.h" using namespace std; diff --git a/DRAMSys/library/src/common/Utils.h b/DRAMSys/library/src/common/utils.h similarity index 97% rename from DRAMSys/library/src/common/Utils.h rename to DRAMSys/library/src/common/utils.h index ac7a71a1..79bf1c5b 100644 --- a/DRAMSys/library/src/common/Utils.h +++ b/DRAMSys/library/src/common/utils.h @@ -35,8 +35,8 @@ * Eder F. Zulian */ -#ifndef UTILS_COMMON_UTILS_H_ -#define UTILS_COMMON_UTILS_H_ +#ifndef UTILS_H +#define UTILS_H #include #include @@ -44,7 +44,7 @@ #include #include #include -#include "dramExtension.h" +#include "dramExtensions.h" #include "third_party/tinyxml2/tinyxml2.h" #define DEF_SINGLETON( NAME ) \ @@ -148,5 +148,5 @@ double queryDoubleParameter(tinyxml2::XMLElement *node, std::string name); void setUpDummy(tlm::tlm_generic_payload &payload, Bank &bank); -#endif /* UTILS_COMMON_H_ */ +#endif // UTILS_H diff --git a/DRAMSys/library/src/controller/Command.h b/DRAMSys/library/src/controller/Command.h index da66fef4..e8aa28e7 100644 --- a/DRAMSys/library/src/controller/Command.h +++ b/DRAMSys/library/src/controller/Command.h @@ -33,13 +33,12 @@ * Janik Schlemminger * Matthias Jung */ -#ifndef COMMAND_H_ -#define COMMAND_H_ +#ifndef COMMAND_H +#define COMMAND_H #include #include - enum class Command { NOP, PreB, @@ -64,4 +63,4 @@ std::string commandToString(Command command); const std::vector &getAllCommands(); bool commandIsIn(Command command, std::vector commands); -#endif /* COMMAND_H_ */ +#endif // COMMAND_H diff --git a/DRAMSys/library/src/controller/Controller.cpp b/DRAMSys/library/src/controller/Controller.cpp index b322b1cc..1fac6814 100644 --- a/DRAMSys/library/src/controller/Controller.cpp +++ b/DRAMSys/library/src/controller/Controller.cpp @@ -39,22 +39,82 @@ #include "Controller.h" #include +Controller::Controller(sc_module_name /*name*/) : + frontendPEQ(this, &Controller::frontendPEQCallback), + dramPEQ(this, &Controller::dramPEQCallback), + controllerCorePEQ(this, &Controller::controllerCorePEQCallback), + debugManager(DebugManager::getInstance()) +{ + controllerCore = new ControllerCore("core", *this, numberOfPayloadsInSystem); + buildScheduler(); + iSocket.register_nb_transport_bw(this, &Controller::nb_transport_bw); + tSocket.register_nb_transport_fw(this, &Controller::nb_transport_fw); + tSocket.register_transport_dbg(this, &Controller::transport_dbg); +} + +Controller::~Controller() +{ + // Bandwidth: + sc_time activeTime = numberOfTransactionsServed + * Configuration::getInstance().memSpec->BurstLength + / Configuration::getInstance().memSpec->DataRate + * Configuration::getInstance().memSpec->clk; + + sc_time idleTime = getIdleTime(); + sc_time endTime = getEndTime(); + sc_time startTime = getStartTime(); + + double bandwidth = (activeTime / (endTime - startTime) * 100); + double bandwidth_IDLE = ((activeTime) / (endTime - startTime - idleTime) * 100); + + double maxBandwidth = ( + // clk in Mhz e.g. 800 [MHz]: + (1000000 / Configuration::getInstance().memSpec->clk.to_double()) + // DataRate e.g. 2 + * Configuration::getInstance().memSpec->DataRate + // BusWidth e.g. 8 or 64 + * Configuration::getInstance().memSpec->bitWidth + // Number of devices on a DIMM e.g. 8 + * Configuration::getInstance().NumberOfDevicesOnDIMM ) / ( 1024 ); + + cout << name() << string(" Total Time: ") + << (endTime - startTime).to_string() + << endl; + cout << name() << string(" AVG BW: ") + << std::fixed << std::setprecision(2) + << ((bandwidth / 100)*maxBandwidth) + << " Gibit/s (" << bandwidth << " %)" + << endl; + cout << name() << string(" AVG BW/IDLE: ") + << std::fixed << std::setprecision(2) + << ((bandwidth_IDLE / 100)*maxBandwidth) + << " Gibit/s (" << (bandwidth_IDLE) << " %)" + << endl; + cout << name() << string(" MAX BW: ") + << std::fixed << std::setprecision(2) + << maxBandwidth << " Gibit/s" + << endl; + + delete controllerCore; + delete scheduler; +} + void Controller::buildScheduler() { string selectedScheduler = Configuration::getInstance().Scheduler; - if (selectedScheduler == "FIFO") { + if (selectedScheduler == "Fifo") { scheduler = new Fifo(*controllerCore); - } else if (selectedScheduler == "FIFO_STRICT") { + } else if (selectedScheduler == "FifoStrict") { scheduler = new FifoStrict(*this, *controllerCore); - } else if (selectedScheduler == "FR_FCFS") { - scheduler = new FR_FCFS(*controllerCore); - } else if (selectedScheduler == "FR_FCFS_RP") { - scheduler = new FR_FCFS_RP(*controllerCore); - } else if (selectedScheduler == "FR_FCFS_GRP") { - scheduler = new FR_FCFS_GRP(*controllerCore, this); - } else if (selectedScheduler == "GRP") { - scheduler = new GRP(*controllerCore, this); + } else if (selectedScheduler == "FrFcfs") { + scheduler = new FrFcfs(*controllerCore); + } else if (selectedScheduler == "FrFcfsRp") { + scheduler = new FrFcfsRp(*controllerCore); + } else if (selectedScheduler == "FrFcfsGrp") { + scheduler = new FrFcfsGrp(*controllerCore, this); + } else if (selectedScheduler == "Grp") { + scheduler = new Grp(*controllerCore, this); } else if (selectedScheduler == "SMS") { scheduler = new SMS("SMS", *controllerCore, Configuration::getInstance().SJFProbability); @@ -80,7 +140,8 @@ void Controller::send(const ScheduledCommand &command, tlm_phase phase; - switch (command.getCommand()) { + switch (command.getCommand()) + { //TODO: refactor tlm recorder case Command::Read: phase = BEGIN_RD; @@ -95,9 +156,9 @@ void Controller::send(const ScheduledCommand &command, phase = BEGIN_WRA; break; case Command::AutoRefresh: - if (!Configuration::getInstance().BankwiseLogic) { + if (!Configuration::getInstance().BankwiseLogic) phase = BEGIN_REFA; - } else + else phase = BEGIN_REFB; break; case Command::Activate: @@ -116,39 +177,39 @@ void Controller::send(const ScheduledCommand &command, phase = BEGIN_PRE_ALL; break; case Command::PDNA: - if (!Configuration::getInstance().BankwiseLogic) { + if (!Configuration::getInstance().BankwiseLogic) phase = BEGIN_PDNA; - } else + else phase = BEGIN_PDNAB; break; case Command::PDNAX: - if (!Configuration::getInstance().BankwiseLogic) { + if (!Configuration::getInstance().BankwiseLogic) phase = END_PDNA; - } else + else phase = END_PDNAB; break; case Command::PDNP: - if (!Configuration::getInstance().BankwiseLogic) { + if (!Configuration::getInstance().BankwiseLogic) phase = BEGIN_PDNP; - } else + else phase = BEGIN_PDNPB; break; case Command::PDNPX: - if (!Configuration::getInstance().BankwiseLogic) { + if (!Configuration::getInstance().BankwiseLogic) phase = END_PDNP; - } else + else phase = END_PDNPB; break; case Command::SREF: - if (!Configuration::getInstance().BankwiseLogic) { + if (!Configuration::getInstance().BankwiseLogic) phase = BEGIN_SREF; - } else + else phase = BEGIN_SREFB; break; case Command::SREFX: - if (!Configuration::getInstance().BankwiseLogic) { + if (!Configuration::getInstance().BankwiseLogic) phase = END_SREF; - } else + else phase = END_SREFB; break; default: @@ -187,18 +248,23 @@ void Controller::send(Trigger trigger, sc_time time, void Controller::controllerCorePEQCallback(tlm_generic_payload &payload, const tlm_phase &phase) { - if (phase == REF_TRIGGER) { + if (phase == REF_TRIGGER) + { controllerCore->triggerRefresh(payload); - } else if (phase == PDN_TRIGGER) { + } + else if (phase == PDN_TRIGGER) + { controllerCore->powerDownManager->sleep(DramExtension::getExtension( payload).getBank(), sc_time_stamp()); - } else { + } + else + { Bank bank = DramExtension::getBank(payload); sendToDram(payload, phase, SC_ZERO_TIME); - if (phase == BEGIN_RD || phase == BEGIN_WR) { + if (phase == BEGIN_RD || phase == BEGIN_WR) scheduleNextFromScheduler(DramExtension::getBank(payload)); - } else if (phase == BEGIN_REFB) + else if (phase == BEGIN_REFB) printDebugMessage("Entering REFB on bank " + to_string(bank.ID())); else if (phase == BEGIN_REFA) printDebugMessage("Entering REFA"); @@ -229,18 +295,20 @@ tlm_sync_enum Controller::nb_transport_fw(tlm_generic_payload &payload, { sc_time notDelay = fwDelay; - if (phase == BEGIN_REQ) { - notDelay += Configuration::getInstance().memSpec.clk; + if (phase == BEGIN_REQ) + { + notDelay += Configuration::getInstance().memSpec->clk; - //Bandwidth IDLE - if ((getTotalNumberOfPayloadsInSystem() == 0) && idleState) { + // Bandwidth IDLE + if ((getTotalNumberOfPayloadsInSystem() == 0) && idleState) endBandwidthIdleCollector(); - } - } else if (phase == END_RESP) { - // Badnwith IDLE - if (getTotalNumberOfPayloadsInSystem() == 1) { + } + else if (phase == END_RESP) + { + // Bandwidth IDLE + // TODO: getTotalNumberOfPayloadsInSystem() == 1 && !idleState ?? + if (getTotalNumberOfPayloadsInSystem() == 1) startBandwidthIdleCollector(); - } } printDebugMessage("[fw] " + phaseNameToString(phase) + " notification in " + @@ -258,27 +326,37 @@ unsigned int Controller::transport_dbg(tlm::tlm_generic_payload &trans) void Controller::frontendPEQCallback(tlm_generic_payload &payload, const tlm_phase &phase) { - if (phase == BEGIN_REQ) { - printDebugMessage(string("Payload in system: ") + to_string( - getTotalNumberOfPayloadsInSystem())); + if (phase == BEGIN_REQ) + { + printDebugMessage(string("Payloads in system: ") + + to_string(getTotalNumberOfPayloadsInSystem())); payload.acquire(); payloadEntersSystem(payload); + if (getTotalNumberOfPayloadsInSystem() > - controllerCore->config.MaxNrOfTransactions) { + controllerCore->config.MaxNrOfTransactions) + { printDebugMessage("##Backpressure: Max number of transactions in system reached"); backpressure = &payload; - return; } - payload.set_response_status(tlm::TLM_OK_RESPONSE); - sendToFrontend(payload, END_REQ, SC_ZERO_TIME); + else + { + payload.set_response_status(tlm::TLM_OK_RESPONSE); + sendToFrontend(payload, END_REQ, SC_ZERO_TIME); - scheduler->storeRequest(&payload); - scheduleNextFromScheduler(DramExtension::getExtension(payload).getBank()); - } else if (phase == PendingRequest) { + scheduler->storeRequest(&payload); + scheduleNextFromScheduler(DramExtension::getExtension(payload).getBank()); + } + } + else if (phase == PendingRequest) + { // Schedule a pending request. scheduleNextFromScheduler(DramExtension::getExtension(payload).getBank()); - } else if (phase == END_RESP) { - if (backpressure != NULL) { + } + else if (phase == END_RESP) + { + if (backpressure != NULL) + { printDebugMessage("##Backpressure released"); backpressure->set_response_status(tlm::TLM_OK_RESPONSE); sendToFrontend(*backpressure, END_REQ, SC_ZERO_TIME); @@ -289,8 +367,14 @@ void Controller::frontendPEQCallback(tlm_generic_payload &payload, } payloadLeavesSystem(payload); + responseQueue.pop(); payload.release(); - } else { + + if(!responseQueue.empty()) + sendToFrontend(*(responseQueue.front()), BEGIN_RESP, SC_ZERO_TIME); + } + else + { SC_REPORT_FATAL(0, "Front-end PEQ in controller wrapper was triggered with unknown phase"); } @@ -299,15 +383,16 @@ void Controller::frontendPEQCallback(tlm_generic_payload &payload, void Controller::payloadEntersSystem(tlm_generic_payload &payload) { Bank bank = DramExtension::getExtension(payload).getBank(); + numberOfPayloadsInSystem[bank]++; printDebugMessage( "Payload enters system on bank " + to_string(bank.ID()) + ". Total number of payloads in Controller: " + to_string(getTotalNumberOfPayloadsInSystem())); - numberOfPayloadsInSystem[bank]++; // Set Start Time for Simulation - if (startTimeSet == false) { + if (!startTimeSet) + { printDebugMessage("Simulation Timer Start"); - startTime = sc_time_stamp() - Configuration::getInstance().memSpec.clk; + startTime = sc_time_stamp() - Configuration::getInstance().memSpec->clk; startTimeSet = true; } } @@ -326,51 +411,66 @@ void Controller::payloadLeavesSystem(tlm_generic_payload &payload) unsigned int Controller::getTotalNumberOfPayloadsInSystem() { unsigned int sum = 0; - for (Bank bank : controllerCore->getBanks()) { + for (Bank bank : controllerCore->getBanks()) sum += numberOfPayloadsInSystem[bank]; - } return sum; } void Controller::scheduleNextFromScheduler(Bank bank) { - if (controllerCore->bankIsBusy(bank)) { + if (controllerCore->bankIsBusy(bank)) return; - } + // TODO: rescheduled always true? bool rescheduled = true; pair nextRequest = scheduler->getNextRequest(bank); - if (nextRequest.second != NULL) { + if (nextRequest.second != NULL) + { schedule(nextRequest.first, *nextRequest.second); - } else { + } + else + { gp *pendingRequest = scheduler->getPendingRequest(bank); - if (pendingRequest != NULL) { + // TODO: if path (pendingRequest != NULL) is only used by SMS scheduler + if (pendingRequest != NULL) + { rescheduled = true; frontendPEQ.notify(*(pendingRequest), PendingRequest, - Configuration::getInstance().memSpec.clk); + Configuration::getInstance().memSpec->clk); } } + // TODO: only used with FifoStrict scheduler queue blocked; - while (!blockedRequests.empty()) { + while (!blockedRequests.empty()) + { bank = blockedRequests.front(); blockedRequests.pop(); pair nextRequest = scheduler->getNextRequest(bank); - if (nextRequest.second != NULL) { + if (nextRequest.second != NULL) + { schedule(nextRequest.first, *nextRequest.second); - } else { + } + else + { gp *pendingRequest = scheduler->getPendingRequest(bank); - if (pendingRequest != NULL) { + if (pendingRequest != NULL) + { //Pending request - if (!rescheduled) { + if (!rescheduled) + { + // TODO: never reached, rescheduled is always true rescheduled = true; frontendPEQ.notify(*(pendingRequest), PendingRequest, - Configuration::getInstance().memSpec.clk); - } else + Configuration::getInstance().memSpec->clk); + } + else + { blocked.push(bank); + } } } } @@ -381,7 +481,8 @@ void Controller::schedule(Command command, gp &payload) { controllerCore->powerDownManager->wakeUp(DramExtension::getBank(payload), sc_time_stamp()); - if (controllerCore->scheduleRequest(command, payload)) { + if (controllerCore->scheduleRequest(command, payload)) + { printDebugMessage("\t-> Next payload was scheduled by core [" + commandToString( command) + "] (unblocked)"); } @@ -411,41 +512,59 @@ void Controller::dramPEQCallback(tlm_generic_payload &payload, printDebugMessage("Received " + phaseNameToString(phase) + " on bank " + to_string(bank.ID()) + " from DRAM"); - if (phase == END_RD || phase == END_WR) { - sendToFrontend(payload, BEGIN_RESP, SC_ZERO_TIME); - } else if (phase == END_RDA || phase == END_WRA) { - sendToFrontend(payload, BEGIN_RESP, SC_ZERO_TIME); + if (phase == END_RD || phase == END_WR) + { + if(responseQueue.empty()) + sendToFrontend(payload, BEGIN_RESP, SC_ZERO_TIME); + + responseQueue.push(&payload); + } + else if (phase == END_RDA || phase == END_WRA) + { + if(responseQueue.empty()) + sendToFrontend(payload, BEGIN_RESP, SC_ZERO_TIME); + + responseQueue.push(&payload); scheduleNextFromScheduler(bank); - } else if (phase == END_REFA) { + } + else if (phase == END_REFA) + { printDebugMessage("Finished auto refresh on all banks "); bool sleepy = true; - for (Bank bank : controllerCore->getBanks()) { - if (numberOfPayloadsInSystem[bank] != 0) { + for (Bank bank : controllerCore->getBanks()) + { + if (numberOfPayloadsInSystem[bank] != 0) + { sleepy = false; scheduleNextFromScheduler(bank); } } - - if (sleepy == true) { + if (sleepy == true) controllerCore->powerDownManager->sleep(0, sc_time_stamp()); - } - } else if (phase == END_REFB) { + } + else if (phase == END_REFB) + { printDebugMessage("Finished auto refresh on bank " + to_string(bank.ID())); - if (numberOfPayloadsInSystem[bank] == 0) { + if (numberOfPayloadsInSystem[bank] == 0) controllerCore->powerDownManager->sleep(bank, sc_time_stamp()); - } else { + else scheduleNextFromScheduler(bank); - } - scheduleNextFromScheduler(bank); - } else if (containsPhase(phase, {END_PREB, END_PRE, END_ACTB, END_ACT})) { + scheduleNextFromScheduler(bank); } - else if (phase == END_PRE_ALL) { + else if (containsPhase(phase, {END_PREB, END_PRE, END_ACTB, END_ACT})) + { + scheduleNextFromScheduler(bank); + } + else if (phase == END_PRE_ALL) + { // No need to trigger anything for a END_PRE_ALL. It is followed by a AUTO_REFRESH anyway (in our current // scheduler implementation) - } else { + } + else + { string str = string("DRAM PEQ in controller wrapper was triggered with unsupported phase ") + phaseNameToString(phase); @@ -458,6 +577,8 @@ void Controller::sendToDram(tlm_generic_payload &payload, { tlm_phase TPhase = phase; sc_time TDelay = delay; + if (phase == BEGIN_WR || phase == BEGIN_RD || phase == BEGIN_WRA || phase == BEGIN_RDA) + numberOfTransactionsServed++; iSocket->nb_transport_fw(payload, TPhase, TDelay); } @@ -505,7 +626,7 @@ void Controller::endBandwidthIdleCollector() { printDebugMessage("IDLE End"); idleTime += sc_time_stamp() - idleStart + - Configuration::getInstance().memSpec.clk; + Configuration::getInstance().memSpec->clk; idleState = false; } diff --git a/DRAMSys/library/src/controller/Controller.h b/DRAMSys/library/src/controller/Controller.h index efaae49e..282a9224 100644 --- a/DRAMSys/library/src/controller/Controller.h +++ b/DRAMSys/library/src/controller/Controller.h @@ -35,8 +35,8 @@ * Eder F. Zulian */ -#ifndef CONTROLLERWRAPPER_H_ -#define CONTROLLERWRAPPER_H_ +#ifndef CONTROLLER_H +#define CONTROLLER_H #include #include @@ -49,11 +49,11 @@ #include #include -#include "../common/dramExtension.h" +#include "../common/dramExtensions.h" #include "../common/DebugManager.h" #include "../common/protocol.h" #include "../common/TlmRecorder.h" -#include "../common/Utils.h" +#include "../common/utils.h" #include "core/configuration/Configuration.h" #include "core/configuration/MemSpec.h" #include "Command.h" @@ -62,14 +62,13 @@ #include "IController.h" #include "core/powerdown/IPowerDownManager.h" #include "core/scheduling/ScheduledCommand.h" -#include "core/scheduling/Trigger.h" -#include "core/TimingCalculation.h" +#include "core/timingCalculations.h" #include "scheduler/Fifo.h" -#include "scheduler/grp.h" +#include "scheduler/Grp.h" #include "scheduler/FifoStrict.h" -#include "scheduler/Fr_Fcfs.h" -#include "scheduler/Fr_Fcfs_read_priority.h" -#include "scheduler/Fr_Fcfs_grouper.h" +#include "scheduler/FrFcfs.h" +#include "scheduler/FrFcfsRp.h" +#include "scheduler/FrFcfsGrp.h" #include "scheduler/SMS.h" #include "scheduler/IScheduler.h" @@ -78,27 +77,12 @@ using namespace tlm; DECLARE_EXTENDED_PHASE(PendingRequest); -class Controller: public sc_module, public IController +class Controller : public sc_module, public IController { public: - Controller(sc_module_name /*name*/) : - frontendPEQ(this, &Controller::frontendPEQCallback), dramPEQ(this, - &Controller::dramPEQCallback), controllerCorePEQ(this, - &Controller::controllerCorePEQCallback), - debugManager(DebugManager::getInstance()) - { - controllerCore = new ControllerCore("core", *this, numberOfPayloadsInSystem); - buildScheduler(); - iSocket.register_nb_transport_bw(this, &Controller::nb_transport_bw); - tSocket.register_nb_transport_fw(this, &Controller::nb_transport_fw); - tSocket.register_transport_dbg(this, &Controller::transport_dbg); - } + Controller(sc_module_name); - virtual ~Controller() - { - delete controllerCore; - delete scheduler; - } + virtual ~Controller(); void terminateSimulation(); @@ -112,8 +96,9 @@ public: virtual void send(Trigger trigger, sc_time time, tlm_generic_payload &payload) override; - tlm_utils::simple_initiator_socket iSocket; tlm_utils::simple_target_socket tSocket; + tlm_utils::simple_initiator_socket iSocket; + unsigned int getTotalNumberOfPayloadsInSystem(); void scheduleNextFromScheduler(Bank bank) override; @@ -155,8 +140,9 @@ protected: //Scheduler* scheduler; IScheduler *scheduler; std::map numberOfPayloadsInSystem; - std::vector refreshCollisionRequets; + std::vector refreshCollisionRequets; tlm::tlm_generic_payload *backpressure = NULL; + std::queue responseQueue; tlm_utils::peq_with_cb_and_phase frontendPEQ; tlm_utils::peq_with_cb_and_phase dramPEQ; @@ -170,7 +156,8 @@ protected: sc_time idleTime; sc_time endTime; sc_time startTime; - int startTimeSet = false; + bool startTimeSet = false; + unsigned long long int numberOfTransactionsServed = 0; void startBandwidthIdleCollector(); void endBandwidthIdleCollector(); @@ -180,5 +167,5 @@ protected: static const unsigned int controllerThreadId = INT_MAX; }; -#endif /* CONTROLLERWRAPPER_H_ */ +#endif // CONTROLLER_H diff --git a/DRAMSys/library/src/controller/ControllerState.cpp b/DRAMSys/library/src/controller/ControllerState.cpp index efff0548..c7318363 100644 --- a/DRAMSys/library/src/controller/ControllerState.cpp +++ b/DRAMSys/library/src/controller/ControllerState.cpp @@ -37,7 +37,7 @@ #include "ControllerState.h" #include -#include "core/TimingCalculation.h" +#include "core/timingCalculations.h" using namespace std; @@ -51,7 +51,7 @@ const ScheduledCommand ControllerState::getLastCommand(Command command) { ScheduledCommand max; - for (unsigned int i = 0; i < config->memSpec.NumberOfBanks; ++i) { + for (unsigned int i = 0; i < config->memSpec->NumberOfBanks; ++i) { ScheduledCommand current = getLastCommand(command, Bank(i)); if (current.getStart() > max.getStart()) max = current; @@ -65,7 +65,7 @@ const ScheduledCommand ControllerState::getLastScheduledCommand() ScheduledCommand lastCommand; for (Command cmd : getAllCommands()) { - for (Bank bank : Configuration::getInstance().memSpec.getBanks()) { + for (Bank bank : Configuration::getInstance().memSpec->getBanks()) { ScheduledCommand ¤t = lastScheduledByCommandAndBank[cmd][bank]; if (current.getStart() > lastCommand.getStart()) lastCommand = current; @@ -154,17 +154,17 @@ void ControllerState::cleanUp(sc_time time) vector tmp; for (ScheduledCommand &command : lastDataStrobeCommands) { if (command.getEnd() >= time - || getDistance(command.getEnd(), time) <= config->memSpec.tDataStrobeHistory()) + || getDistance(command.getEnd(), time) <= config->memSpec->tDataStrobeHistory()) tmp.push_back(command); } lastDataStrobeCommands = tmp; - if (time >= config->memSpec.tActHistory()) + if (time >= config->memSpec->tActHistory()) lastActivates.erase(lastActivates.begin(), - lastActivates.lower_bound(time - config->memSpec.tActHistory())); + lastActivates.lower_bound(time - config->memSpec->tActHistory())); - if (time >= config->memSpec.tActBHistory()) + if (time >= config->memSpec->tActBHistory()) lastActivatesB.erase(lastActivatesB.begin(), - lastActivatesB.lower_bound(time - config->memSpec.tActBHistory())); + lastActivatesB.lower_bound(time - config->memSpec->tActBHistory())); } void ControllerState::printDebugMessage(std::string message) diff --git a/DRAMSys/library/src/controller/ControllerState.h b/DRAMSys/library/src/controller/ControllerState.h index fff61882..a5d9d609 100644 --- a/DRAMSys/library/src/controller/ControllerState.h +++ b/DRAMSys/library/src/controller/ControllerState.h @@ -34,8 +34,8 @@ * Matthias Jung */ -#ifndef CONTROLLER_STATE_H_ -#define CONTROLLER_STATE_H_ +#ifndef CONTROLLERSTATE_H +#define CONTROLLERSTATE_H #include #include "RowBufferStates.h" @@ -49,7 +49,7 @@ class ControllerState { public: ControllerState(std::string ownerName, - Configuration *config) : bus(config->memSpec.clk), ownerName(ownerName), + Configuration *config) : bus(config->memSpec->clk), ownerName(ownerName), config(config) { rowBufferStates = new RowBufferState(ownerName); @@ -84,5 +84,5 @@ private: void printDebugMessage(std::string message); }; -#endif /* CONTROLLER_STATE_H_ */ +#endif // CONTROLLERSTATE_H diff --git a/DRAMSys/library/src/controller/IController.h b/DRAMSys/library/src/controller/IController.h index ded2de7b..b61fc0d7 100644 --- a/DRAMSys/library/src/controller/IController.h +++ b/DRAMSys/library/src/controller/IController.h @@ -41,9 +41,9 @@ #include #include #include "core/scheduling/ScheduledCommand.h" -#include "core/scheduling/Trigger.h" -#include "../common/dramExtension.h" +#include "../common/dramExtensions.h" +enum Trigger {REFTrigger, PDNTrigger}; // Utiliy class to pass around the Controller class to the controller Core and various schedulers, without having to propagate the template defintions // throughout all classes diff --git a/DRAMSys/library/src/controller/RowBufferStates.cpp b/DRAMSys/library/src/controller/RowBufferStates.cpp index 2948203a..4db36b8a 100644 --- a/DRAMSys/library/src/controller/RowBufferStates.cpp +++ b/DRAMSys/library/src/controller/RowBufferStates.cpp @@ -37,7 +37,7 @@ #include "RowBufferStates.h" #include "core/ControllerCore.h" #include "../common/DebugManager.h" -#include "../common/Utils.h" +#include "../common/utils.h" using namespace std; @@ -76,7 +76,7 @@ void RowBufferState::closeRowBuffer(Bank bank) bool RowBufferState::allRowBuffersAreClosed() const { - for (unsigned int i = 0; i < Configuration::getInstance().memSpec.NumberOfBanks; + for (unsigned int i = 0; i < Configuration::getInstance().memSpec->NumberOfBanks; ++i) { if (rowBufferIsOpen(Bank(i))) return false; @@ -86,7 +86,7 @@ bool RowBufferState::allRowBuffersAreClosed() const void RowBufferState::closeAllRowBuffers() { - for (unsigned int i = 0; i < Configuration::getInstance().memSpec.NumberOfBanks; + for (unsigned int i = 0; i < Configuration::getInstance().memSpec->NumberOfBanks; ++i) { rowsInRowBuffers[Bank(i)] = Row::NO_ROW; } diff --git a/DRAMSys/library/src/controller/RowBufferStates.h b/DRAMSys/library/src/controller/RowBufferStates.h index 63de434e..f2670dec 100644 --- a/DRAMSys/library/src/controller/RowBufferStates.h +++ b/DRAMSys/library/src/controller/RowBufferStates.h @@ -34,11 +34,11 @@ * Matthias Jung */ -#ifndef ROWBUFFERSTATES_H_ -#define ROWBUFFERSTATES_H_ +#ifndef ROWBUFFERSTATES_H +#define ROWBUFFERSTATES_H #include -#include "../common/dramExtension.h" +#include "../common/dramExtensions.h" class RowBufferState { @@ -60,5 +60,5 @@ private: void printDebugMessage(std::string message); }; -#endif /* BANKSTATES_H_ */ +#endif // ROWBUFFERSTATES_H diff --git a/DRAMSys/library/src/controller/core/ControllerCore.cpp b/DRAMSys/library/src/controller/core/ControllerCore.cpp index 63069368..5c43afcc 100644 --- a/DRAMSys/library/src/controller/core/ControllerCore.cpp +++ b/DRAMSys/library/src/controller/core/ControllerCore.cpp @@ -49,9 +49,9 @@ #include "refresh/RefreshManagerBankwise.h" #include "refresh/RefreshManager.h" #include "refresh/RGR.h" -#include "../../common/dramExtension.h" -#include "../../common/Utils.h" -#include "TimingCalculation.h" +#include "../../common/dramExtensions.h" +#include "../../common/utils.h" +#include "timingCalculations.h" #include "powerdown/PowerDownManager.h" #include "powerdown/PowerDownManagerTimeout.h" @@ -87,13 +87,16 @@ ControllerCore::ControllerCore(sc_module_name /*name*/, if (config.RowGranularRef) { refreshManager = new RGR("RGR", *this); - assert(config.getTrasb() <= config.memSpec.tRAS); - assert(config.getTrasb() >= config.memSpec.tRCD); - assert(config.getTrrdb_L() <= config.memSpec.tRRD_L); - assert(config.getTrrdb_S() <= config.memSpec.tRRD_S); - assert(config.getTrpb() <= config.memSpec.tRP); - assert(config.getTrcb() <= config.memSpec.tRC); - assert(config.getTfawb() <= config.memSpec.tNAW); + // TODO: How to use asserts with new memspec? + /* + assert(config.getTrasb() <= config.memSpec->tRAS); + assert(config.getTrasb() >= config.memSpec->tRCD); + assert(config.getTrrdb_L() <= config.memSpec->tRRD_L); + assert(config.getTrrdb_S() <= config.memSpec->tRRD_S); + assert(config.getTrpb() <= config.memSpec->tRP); + assert(config.getTrcb() <= config.memSpec->tRC); + assert(config.getTfawb() <= config.memSpec->tNAW); + */ } else { if (config.BankwiseLogic) { refreshManager = new RefreshManagerBankwise("refManagerBw", *this); @@ -138,27 +141,27 @@ ControllerCore::~ControllerCore() void ControllerCore::triggerRefresh(tlm::tlm_generic_payload &payload) { /* Refresh can be disabled for tests purpose */ - if (config.ControllerCoreRefDisable == false) { + if (config.ControllerCoreRefDisable == false) + { sc_time time = sc_time_stamp(); Bank bank = DramExtension::getExtension(payload).getBank(); state->cleanUp(time); if (!refreshManager->isInvalidated(payload, time) - && !powerDownManager->isInSelfRefresh(bank)) { + && !powerDownManager->isInSelfRefresh(bank)) + { printDebugMessage("Triggering refresh on bank " + to_string(bank.ID())); powerDownManager->wakeUpForRefresh(bank, time); //expects PDNA and PDNP to exit without delay bool pdnpToSrefTransition = false; - if (config.PowerDownMode == EPowerDownMode::Staggered) { - pdnpToSrefTransition = state->getLastCommand(Command::PDNPX, - bank).getStart() >= time; - } - if (pdnpToSrefTransition) { + if (config.PowerDownMode == EPowerDownMode::Staggered) + pdnpToSrefTransition = (state->getLastCommand(Command::PDNPX, + bank).getStart() >= time); + if (pdnpToSrefTransition) powerDownManager->sleep(bank, time); - } else { + else refreshManager->scheduleRefresh(payload, time); - } } } } @@ -169,13 +172,17 @@ bool ControllerCore::scheduleRequest(Command command, sc_time start = clkAlign(sc_time_stamp()); state->cleanUp(start); ScheduledCommand scheduledCommand = schedule(command, start, payload); - if (config.ControllerCoreRefDisable == true) { + if (config.ControllerCoreRefDisable) + { state->change(scheduledCommand); controller.send(scheduledCommand, payload); return true; - } else { + } + else + { if (!((command == Command::Precharge || command == Command::Activate) - && refreshManager->hasCollision(scheduledCommand))) { + && refreshManager->hasCollision(scheduledCommand))) + { state->change(scheduledCommand); controller.send(scheduledCommand, payload); return true; @@ -189,17 +196,17 @@ ScheduledCommand ControllerCore::schedule(Command command, sc_time start, { ControllerCore::printDebugMessage("Scheduling command " + commandToString( command) + " on " + DramExtension::getBank(payload).toString()); - ICommandChecker &checker = getCommandChecker(command); sc_time executionTime = getExecutionTime(command, payload); ScheduledCommand scheduledCommand(command, start, executionTime, DramExtension::getExtension(payload)); - checker.delayToSatisfyConstraints(scheduledCommand); + getCommandChecker(command).delayToSatisfyConstraints(scheduledCommand); return scheduledCommand; } bool ControllerCore::hasPendingRequests() { - for (Bank bank : getBanks()) { + for (Bank bank : getBanks()) + { if (numberOfPayloads[bank] != 0) return true; } @@ -217,22 +224,31 @@ bool ControllerCore::bankIsBusy(Bank bank) ScheduledCommand lastScheduledCommand = state->getLastScheduledCommand(bank); if (lastScheduledCommand.isNoCommand()) + { return false; - else if (lastScheduledCommand.commandIsIn( { Command::Write, Command::Read })) { + } + else if (lastScheduledCommand.commandIsIn({Command::Write, Command::Read})) + { // Read and writes can overlap, so the bank should not be busy during a rd/wr return (time < lastScheduledCommand.getStart()); } - else if (lastScheduledCommand.commandIsIn( { Command::WriteA, Command::ReadA, Command::PreB, Command::Precharge, Command::PrechargeAll, Command::ActB, Command::Activate })) { + else if (lastScheduledCommand.commandIsIn({Command::WriteA, Command::ReadA, Command::PreB, + Command::Precharge, Command::PrechargeAll, + Command::ActB, Command::Activate})) + { return (time < lastScheduledCommand.getEnd()); } - else if (lastScheduledCommand.getCommand() == Command::AutoRefresh) { + else if (lastScheduledCommand.getCommand() == Command::AutoRefresh) + { return (time < lastScheduledCommand.getEnd()); - } else if (lastScheduledCommand.commandIsIn( { Command::SREFX, Command::PDNPX, Command::PDNAX, Command::SREF, Command::PDNP, - Command::PDNA - })) { + } + else if (lastScheduledCommand.commandIsIn({Command::SREFX, Command::PDNPX, Command::PDNAX, + Command::SREF, Command::PDNP, Command::PDNA})) + { return false; } - else { + else + { SC_REPORT_FATAL("Core", "Last command unkown"); return false; } @@ -243,7 +259,7 @@ const std::vector &ControllerCore::getBanks() static std::vector banks; if (banks.size() == 0) { - for (unsigned int i = 0; i < config.memSpec.NumberOfBanks; i++) { + for (unsigned int i = 0; i < config.memSpec->NumberOfBanks; i++) { banks.push_back(Bank(i)); } } diff --git a/DRAMSys/library/src/controller/core/ControllerCore.h b/DRAMSys/library/src/controller/core/ControllerCore.h index 7b00f1ea..f0b7dc99 100644 --- a/DRAMSys/library/src/controller/core/ControllerCore.h +++ b/DRAMSys/library/src/controller/core/ControllerCore.h @@ -34,8 +34,8 @@ * Matthias Jung */ -#ifndef CONTROLLER_H_ -#define CONTROLLER_H_ +#ifndef CONTROLLERCORE_H +#define CONTROLLERCORE_H #include #include @@ -88,5 +88,5 @@ private: void printDebugMessage(string message); }; -#endif /* CONTROLLER_H_ */ +#endif // CONTROLLERCORE_H diff --git a/DRAMSys/library/src/controller/core/Slots.cpp b/DRAMSys/library/src/controller/core/Slots.cpp index 20126eab..d74ce9e9 100644 --- a/DRAMSys/library/src/controller/core/Slots.cpp +++ b/DRAMSys/library/src/controller/core/Slots.cpp @@ -35,7 +35,7 @@ */ #include "Slots.h" -#include "TimingCalculation.h" +#include "timingCalculations.h" Slots::Slots(sc_time clk) : diff --git a/DRAMSys/library/src/controller/core/Slots.h b/DRAMSys/library/src/controller/core/Slots.h index 5a821a4b..61663568 100644 --- a/DRAMSys/library/src/controller/core/Slots.h +++ b/DRAMSys/library/src/controller/core/Slots.h @@ -34,13 +34,13 @@ * Matthias Jung */ -#ifndef SLOTS_H_ -#define SLOTS_H_ +#ifndef SLOTS_H +#define SLOTS_H + #include #include #include "scheduling/ScheduledCommand.h" - class Slots { public: @@ -60,4 +60,4 @@ private: }; -#endif /* SLOTS_H_ */ +#endif // SLOTS_H diff --git a/DRAMSys/library/src/controller/core/configuration/Configuration.cpp b/DRAMSys/library/src/controller/core/configuration/Configuration.cpp index 50f5d563..eb0918f3 100644 --- a/DRAMSys/library/src/controller/core/configuration/Configuration.cpp +++ b/DRAMSys/library/src/controller/core/configuration/Configuration.cpp @@ -40,7 +40,7 @@ #include "Configuration.h" #include "ConfigurationLoader.h" -#include "../../../common/xmlAddressdecoder.h" +#include "../../../common/XmlAddressDecoder.h" using namespace std; @@ -349,10 +349,10 @@ void Configuration::setParameters(std::map std::uint64_t Configuration::getSimMemSizeInBytes() { // 1. Get number of banks, rows, columns and data width in bits for one die (or chip) - std::uint64_t banks = memSpec.NumberOfBanks; - std::uint64_t rows = memSpec.NumberOfRows; - std::uint64_t columns = memSpec.NumberOfColumns; - std::uint64_t bitWidth = memSpec.bitWidth; + std::uint64_t banks = memSpec->NumberOfBanks; + std::uint64_t rows = memSpec->NumberOfRows; + std::uint64_t columns = memSpec->NumberOfColumns; + std::uint64_t bitWidth = memSpec->bitWidth; // 2. Calculate size of one DRAM chip in bits std::uint64_t chipBitSize = banks * rows * columns * bitWidth; // 3. Calculate size of one DRAM chip in bytes @@ -381,7 +381,7 @@ std::uint64_t Configuration::getSimMemSizeInBytes() // The bus width is given in bits, e.g., 64-bit data bus, 128-bit data bus, etc. unsigned int Configuration::getDataBusWidth() { - unsigned int dataBusWidth = memSpec.bitWidth * NumberOfDevicesOnDIMM; + unsigned int dataBusWidth = memSpec->bitWidth * NumberOfDevicesOnDIMM; assert(dataBusWidth > 0); return dataBusWidth; } @@ -390,7 +390,7 @@ unsigned int Configuration::getDataBusWidth() unsigned int Configuration::getBytesPerBurst() { // First multiply to get the number of bits in a burst, then divide by 8 to get the value in bytes. The order is important. Think on a single x4 device. - unsigned int bytesPerBurst = (memSpec.BurstLength * getDataBusWidth()) / 8; + unsigned int bytesPerBurst = (memSpec->BurstLength * getDataBusWidth()) / 8; assert(bytesPerBurst > 0); if (NumberOfDevicesOnDIMM > 1) { @@ -399,7 +399,7 @@ unsigned int Configuration::getBytesPerBurst() // or burst element has N bytes. N = 2^(# bits for byte offset)). unsigned int burstElementSizeInBytes = AddressDecoder::getInstance().amount["bytes"]; - assert(bytesPerBurst == (burstElementSizeInBytes * memSpec.BurstLength)); + assert(bytesPerBurst == (burstElementSizeInBytes * memSpec->BurstLength)); } return bytesPerBurst; @@ -407,27 +407,27 @@ unsigned int Configuration::getBytesPerBurst() sc_time Configuration::getTrasb() { - return trasbclk * memSpec.clk; + return trasbclk * memSpec->clk; } sc_time Configuration::getTrrdb_L() { - return trrdblclk * memSpec.clk; + return trrdblclk * memSpec->clk; } sc_time Configuration::getTrrdb_S() { - return trrdbsclk * memSpec.clk; + return trrdbsclk * memSpec->clk; } sc_time Configuration::getTrpb() { - return trpbclk * memSpec.clk; + return trpbclk * memSpec->clk; } sc_time Configuration::getTrcb() { - return trcbclk * memSpec.clk; + return trcbclk * memSpec->clk; } sc_time Configuration::getTfawb() { - return tfawbclk * memSpec.clk; + return tfawbclk * memSpec->clk; } bool Configuration::getRGRBank(unsigned int w) { diff --git a/DRAMSys/library/src/controller/core/configuration/Configuration.h b/DRAMSys/library/src/controller/core/configuration/Configuration.h index c20e35f7..51d4079e 100644 --- a/DRAMSys/library/src/controller/core/configuration/Configuration.h +++ b/DRAMSys/library/src/controller/core/configuration/Configuration.h @@ -36,15 +36,15 @@ * Felipe S. Prado */ -#ifndef CONFIGURATION_H_ -#define CONFIGURATION_H_ +#ifndef CONFIGURATION_H +#define CONFIGURATION_H #include #include #include #include "MemSpec.h" -#include "thermalSimConfig.h" -#include "../../../common/Utils.h" +#include "TemperatureSimConfig.h" +#include "../../../common/utils.h" #include "../../../error/eccbaseclass.h" @@ -54,7 +54,8 @@ enum class EPowerDownMode {NoPowerDown, Staggered, TimeoutPDN, TimeoutSREF}; enum class ECCControllerMode {Disabled, Hamming}; -struct Configuration { +struct Configuration +{ static std::string memspecUri; static std::string mcconfigUri; std::string pathToResources; @@ -71,7 +72,7 @@ struct Configuration { unsigned int Capsize = 5; sc_time getPowerDownTimeout() { - return powerDownTimeoutInClk * memSpec.clk; + return powerDownTimeoutInClk * memSpec->clk; } EPowerDownMode PowerDownMode = EPowerDownMode::Staggered; bool ReadWriteGrouping = false; @@ -138,7 +139,7 @@ struct Configuration { unsigned long long int AddressOffset = 0; // MemSpec (from DRAM-Power XML) - MemSpec memSpec; + MemSpec *memSpec; void setParameter(std::string name, std::string value); void setParameters(std::map parameterMap); @@ -163,5 +164,5 @@ private: unsigned int powerDownTimeoutInClk = 3; }; -#endif /* CONFIGURATION_H_ */ +#endif // CONFIGURATION_H diff --git a/DRAMSys/library/src/controller/core/configuration/ConfigurationLoader.cpp b/DRAMSys/library/src/controller/core/configuration/ConfigurationLoader.cpp index 31f478b7..a4d3f94f 100644 --- a/DRAMSys/library/src/controller/core/configuration/ConfigurationLoader.cpp +++ b/DRAMSys/library/src/controller/core/configuration/ConfigurationLoader.cpp @@ -32,11 +32,12 @@ * Authors: * Janik Schlemminger * Matthias Jung + * Lukas Steiner */ #include "ConfigurationLoader.h" #include "MemSpec.h" -#include "../TimingCalculation.h" +#include "../timingCalculations.h" using namespace tinyxml2; using namespace std; @@ -101,34 +102,6 @@ void ConfigurationLoader::loadConfigFromUri(Configuration &config, loadConfig(config, e); } -void ConfigurationLoader::loadMemSpec(Configuration &config, string memspecUri) -{ - tinyxml2::XMLDocument doc; - config.memspecUri = memspecUri; - loadXML(memspecUri, doc); - XMLElement *memspec = doc.FirstChildElement("memspec"); - loadMemSpec(config, memspec); -} - -void ConfigurationLoader::loadMemSpec(Configuration &config, - XMLElement *memspec) -{ - config.memSpec.MemoryId = queryStringParameter(memspec, "memoryId"); - config.memSpec.MemoryType = queryStringParameter(memspec, "memoryType"); - - if (config.memSpec.MemoryType == "DDR4") { - loadDDR4(config, memspec); - } else if (config.memSpec.MemoryType == "DDR3") { - loadDDR3(config, memspec); - } else if (config.memSpec.MemoryType == "LPDDR4") { - loadLPDDR4(config, memspec); - } else if (config.memSpec.MemoryType == "WIDEIO_SDR") { - loadWideIO(config, memspec); - } else { - reportFatal("ConfigurationLoader", "Unsupported DRAM type"); - } -} - void ConfigurationLoader::loadMCConfig(Configuration &config, string mcconfigUri) { @@ -155,236 +128,278 @@ void ConfigurationLoader::loadMCConfig(Configuration &config, } +void ConfigurationLoader::loadMemSpec(Configuration &config, string memspecUri) +{ + tinyxml2::XMLDocument doc; + config.memspecUri = memspecUri; + loadXML(memspecUri, doc); + XMLElement *memspec = doc.FirstChildElement("memspec"); + loadMemSpec(config, memspec); +} + +void ConfigurationLoader::loadMemSpec(Configuration &config, + XMLElement *memspec) +{ + string memoryType = queryStringParameter(memspec, "memoryType"); + + if (memoryType == "DDR4") { + Configuration::getInstance().memSpec = + new MemSpecDDR4; + loadDDR4(config, memspec); + } else if (memoryType == "DDR3") { + Configuration::getInstance().memSpec = + new MemSpecDDR3; + loadDDR3(config, memspec); + } else if (memoryType == "LPDDR4") { + Configuration::getInstance().memSpec = + new MemSpecLPDDR4; + loadLPDDR4(config, memspec); + } else if (memoryType == "WIDEIO_SDR") { + Configuration::getInstance().memSpec = + new MemSpecWideIO; + loadWideIO(config, memspec); + } else { + reportFatal("ConfigurationLoader", "Unsupported DRAM type"); + } + + loadCommons(config, memspec); +} + +void ConfigurationLoader::loadCommons(Configuration &config, XMLElement *memspec) +{ + config.memSpec->MemoryId = queryStringParameter(memspec, "memoryId"); + config.memSpec->MemoryType = queryStringParameter(memspec, "memoryType"); +} + void ConfigurationLoader::loadDDR3(Configuration &config, XMLElement *memspec) { //MemArchitecture XMLElement *architecture = memspec->FirstChildElement("memarchitecturespec"); - config.memSpec.NumberOfBanks = queryUIntParameter(architecture, "nbrOfBanks"); - config.memSpec.NumberOfBankGroups = 1; - config.memSpec.NumberOfRanks = queryUIntParameter(architecture, "nbrOfRanks"); - config.memSpec.BurstLength = queryUIntParameter(architecture, "burstLength"); - config.memSpec.nActivate = 4; - config.memSpec.DataRate = queryUIntParameter(architecture, "dataRate"); - config.memSpec.NumberOfRows = queryUIntParameter(architecture, "nbrOfRows"); - config.memSpec.NumberOfColumns = queryUIntParameter(architecture, + config.memSpec->NumberOfBanks = queryUIntParameter(architecture, "nbrOfBanks"); + config.memSpec->NumberOfBankGroups = 1; + config.memSpec->NumberOfRanks = queryUIntParameter(architecture, "nbrOfRanks"); + config.memSpec->BurstLength = queryUIntParameter(architecture, "burstLength"); + config.memSpec->nActivate = 4; + config.memSpec->DataRate = queryUIntParameter(architecture, "dataRate"); + config.memSpec->NumberOfRows = queryUIntParameter(architecture, "nbrOfRows"); + config.memSpec->NumberOfColumns = queryUIntParameter(architecture, "nbrOfColumns"); - config.memSpec.bitWidth = queryUIntParameter(architecture, "width"); - config.memSpec.DLL = true; - config.memSpec.termination = true; + config.memSpec->bitWidth = queryUIntParameter(architecture, "width"); + config.memSpec->DLL = true; + config.memSpec->termination = true; //MemTimings XMLElement *timings = memspec->FirstChildElement("memtimingspec"); - config.memSpec.clkMHz = queryDoubleParameter(timings, "clkMhz"); - config.memSpec.clk = FrequencyToClk(config.memSpec.clkMHz); - sc_time clk = config.memSpec.clk; - config.memSpec.tRP = clk * queryUIntParameter(timings, "RP"); - config.memSpec.tRAS = clk * queryUIntParameter(timings, "RAS"); - config.memSpec.tRC = clk * queryUIntParameter(timings, "RC"); - config.memSpec.tRTP = clk * queryUIntParameter(timings, "RTP"); - config.memSpec.tRRD_S = clk * queryUIntParameter(timings, "RRD"); - config.memSpec.tRRD_L = clk * queryUIntParameter(timings, "RRD"); - config.memSpec.tCCD_S = clk * queryUIntParameter(timings, "CCD"); - config.memSpec.tCCD_L = clk * queryUIntParameter(timings, "CCD"); - config.memSpec.tRCD = clk * queryUIntParameter(timings, "RCD"); - config.memSpec.tNAW = clk * queryUIntParameter(timings, "FAW"); - config.memSpec.tRL = clk * queryUIntParameter(timings, "RL"); - config.memSpec.tWL = clk * queryUIntParameter(timings, "WL"); - config.memSpec.tWR = clk * queryUIntParameter(timings, "WR"); - config.memSpec.tWTR_S = clk * queryUIntParameter(timings, "WTR"); - config.memSpec.tWTR_L = clk * queryUIntParameter(timings, "WTR"); - config.memSpec.tCKESR = clk * queryUIntParameter(timings, "CKESR"); - config.memSpec.tCKE = clk * queryUIntParameter(timings, "CKE"); - config.memSpec.tXP = clk * queryUIntParameter(timings, "XP"); - config.memSpec.tXPDLL = clk * queryUIntParameter(timings, "XPDLL"); - config.memSpec.tXSR = clk * queryUIntParameter(timings, "XS"); - config.memSpec.tXSRDLL = clk * queryUIntParameter(timings, "XSDLL"); - config.memSpec.tAL = clk * queryUIntParameter(timings, "AL"); - config.memSpec.tRFC = clk * queryUIntParameter(timings, "RFC"); - config.memSpec.tREFI = clk * queryUIntParameter(timings, "REFI"); - config.memSpec.tDQSCK = clk * queryUIntParameter(timings, "DQSCK"); + config.memSpec->clkMHz = queryDoubleParameter(timings, "clkMhz"); + config.memSpec->clk = FrequencyToClk(config.memSpec->clkMHz); + sc_time clk = config.memSpec->clk; + config.memSpec->tRP = clk * queryUIntParameter(timings, "RP"); + config.memSpec->tRAS = clk * queryUIntParameter(timings, "RAS"); + config.memSpec->tRC = clk * queryUIntParameter(timings, "RC"); + config.memSpec->tRTP = clk * queryUIntParameter(timings, "RTP"); + config.memSpec->tRRD_S = clk * queryUIntParameter(timings, "RRD"); + config.memSpec->tRRD_L = clk * queryUIntParameter(timings, "RRD"); + config.memSpec->tCCD_S = clk * queryUIntParameter(timings, "CCD"); + config.memSpec->tCCD_L = clk * queryUIntParameter(timings, "CCD"); + config.memSpec->tRCD = clk * queryUIntParameter(timings, "RCD"); + config.memSpec->tNAW = clk * queryUIntParameter(timings, "FAW"); + config.memSpec->tRL = clk * queryUIntParameter(timings, "RL"); + config.memSpec->tWL = clk * queryUIntParameter(timings, "WL"); + config.memSpec->tWR = clk * queryUIntParameter(timings, "WR"); + config.memSpec->tWTR_S = clk * queryUIntParameter(timings, "WTR"); + config.memSpec->tWTR_L = clk * queryUIntParameter(timings, "WTR"); + config.memSpec->tCKESR = clk * queryUIntParameter(timings, "CKESR"); + config.memSpec->tCKE = clk * queryUIntParameter(timings, "CKE"); + config.memSpec->tXP = clk * queryUIntParameter(timings, "XP"); + config.memSpec->tXPDLL = clk * queryUIntParameter(timings, "XPDLL"); + config.memSpec->tXSR = clk * queryUIntParameter(timings, "XS"); + config.memSpec->tXSRDLL = clk * queryUIntParameter(timings, "XSDLL"); + config.memSpec->tAL = clk * queryUIntParameter(timings, "AL"); + config.memSpec->tRFC = clk * queryUIntParameter(timings, "RFC"); + config.memSpec->tREFI = clk * queryUIntParameter(timings, "REFI"); + config.memSpec->tDQSCK = clk * queryUIntParameter(timings, "DQSCK"); - config.memSpec.refreshTimings.clear(); - for (unsigned int i = 0; i < config.memSpec.NumberOfBanks; ++i) { - config.memSpec.refreshTimings[Bank(i)] = RefreshTiming(config.memSpec.tRFC, - config.memSpec.tREFI); + config.memSpec->refreshTimings.clear(); + for (unsigned int i = 0; i < config.memSpec->NumberOfBanks; ++i) { + config.memSpec->refreshTimings[Bank(i)] = RefreshTiming(config.memSpec->tRFC, + config.memSpec->tREFI); } // Currents and Volatages: TODO Check if this is correct. XMLElement *powers = memspec->FirstChildElement("mempowerspec"); - config.memSpec.iDD0 = queryDoubleParameter(powers, "idd0"); - config.memSpec.iDD02 = 0; - config.memSpec.iDD2P0 = queryDoubleParameter(powers, "idd2p0"); - config.memSpec.iDD2P1 = queryDoubleParameter(powers, "idd2p1"); - config.memSpec.iDD2N = queryDoubleParameter(powers, "idd2n"); - config.memSpec.iDD3P0 = queryDoubleParameter(powers, "idd3p0"); - config.memSpec.iDD3P1 = queryDoubleParameter(powers, "idd3p1"); - config.memSpec.iDD3N = queryDoubleParameter(powers, "idd3n"); - config.memSpec.iDD4R = queryDoubleParameter(powers, "idd4r"); - config.memSpec.iDD4W = queryDoubleParameter(powers, "idd4w"); - config.memSpec.iDD5 = queryDoubleParameter(powers, "idd5"); - config.memSpec.iDD6 = queryDoubleParameter(powers, "idd6"); - config.memSpec.iDD62 = 0; - config.memSpec.vDD = queryDoubleParameter(powers, "vdd"); - config.memSpec.vDD2 = 0; + config.memSpec->iDD0 = queryDoubleParameter(powers, "idd0"); + config.memSpec->iDD02 = 0; + config.memSpec->iDD2P0 = queryDoubleParameter(powers, "idd2p0"); + config.memSpec->iDD2P1 = queryDoubleParameter(powers, "idd2p1"); + config.memSpec->iDD2N = queryDoubleParameter(powers, "idd2n"); + config.memSpec->iDD3P0 = queryDoubleParameter(powers, "idd3p0"); + config.memSpec->iDD3P1 = queryDoubleParameter(powers, "idd3p1"); + config.memSpec->iDD3N = queryDoubleParameter(powers, "idd3n"); + config.memSpec->iDD4R = queryDoubleParameter(powers, "idd4r"); + config.memSpec->iDD4W = queryDoubleParameter(powers, "idd4w"); + config.memSpec->iDD5 = queryDoubleParameter(powers, "idd5"); + config.memSpec->iDD6 = queryDoubleParameter(powers, "idd6"); + config.memSpec->iDD62 = 0; + config.memSpec->vDD = queryDoubleParameter(powers, "vdd"); + config.memSpec->vDD2 = 0; } - void ConfigurationLoader::loadDDR4(Configuration &config, XMLElement *memspec) { //MemArchitecture XMLElement *architecture = memspec->FirstChildElement("memarchitecturespec"); - config.memSpec.NumberOfBanks = queryUIntParameter(architecture, "nbrOfBanks"); - config.memSpec.NumberOfBankGroups = queryUIntParameter(architecture, + config.memSpec->NumberOfBanks = queryUIntParameter(architecture, "nbrOfBanks"); + config.memSpec->NumberOfBankGroups = queryUIntParameter(architecture, "nbrOfBankGroups"); - config.memSpec.NumberOfRanks = queryUIntParameter(architecture, "nbrOfRanks"); - config.memSpec.BurstLength = queryUIntParameter(architecture, "burstLength"); - config.memSpec.nActivate = 4; - config.memSpec.DataRate = queryUIntParameter(architecture, "dataRate"); - config.memSpec.NumberOfRows = queryUIntParameter(architecture, "nbrOfRows"); - config.memSpec.NumberOfColumns = queryUIntParameter(architecture, + config.memSpec->NumberOfRanks = queryUIntParameter(architecture, "nbrOfRanks"); + config.memSpec->BurstLength = queryUIntParameter(architecture, "burstLength"); + config.memSpec->nActivate = 4; + config.memSpec->DataRate = queryUIntParameter(architecture, "dataRate"); + config.memSpec->NumberOfRows = queryUIntParameter(architecture, "nbrOfRows"); + config.memSpec->NumberOfColumns = queryUIntParameter(architecture, "nbrOfColumns"); - config.memSpec.bitWidth = queryUIntParameter(architecture, "width"); - config.memSpec.DLL = true; - config.memSpec.termination = true; + config.memSpec->bitWidth = queryUIntParameter(architecture, "width"); + config.memSpec->DLL = true; + config.memSpec->termination = true; //MemTimings XMLElement *timings = memspec->FirstChildElement("memtimingspec"); - config.memSpec.clkMHz = queryDoubleParameter(timings, "clkMhz"); - config.memSpec.clk = FrequencyToClk(config.memSpec.clkMHz); - sc_time clk = config.memSpec.clk; - config.memSpec.tRP = clk * queryUIntParameter(timings, "RP"); - config.memSpec.tRAS = clk * queryUIntParameter(timings, "RAS"); - config.memSpec.tRC = clk * queryUIntParameter(timings, "RC"); - config.memSpec.tRTP = clk * queryUIntParameter(timings, "RTP"); - config.memSpec.tRRD_S = clk * queryUIntParameter(timings, "RRD_S"); - config.memSpec.tRRD_L = clk * queryUIntParameter(timings, "RRD_L"); - config.memSpec.tCCD_S = clk * queryUIntParameter(timings, "CCD_S"); - config.memSpec.tCCD_L = clk * queryUIntParameter(timings, "CCD_L"); - config.memSpec.tRCD = clk * queryUIntParameter(timings, "RCD"); - config.memSpec.tNAW = clk * queryUIntParameter(timings, "FAW"); - config.memSpec.tRL = clk * queryUIntParameter(timings, "RL"); - config.memSpec.tWL = clk * queryUIntParameter(timings, "WL"); - config.memSpec.tWR = clk * queryUIntParameter(timings, "WR"); - config.memSpec.tWTR_S = clk * queryUIntParameter(timings, "WTR_S"); - config.memSpec.tWTR_L = clk * queryUIntParameter(timings, "WTR_L"); - config.memSpec.tCKESR = clk * queryUIntParameter(timings, "CKESR"); - config.memSpec.tCKE = clk * queryUIntParameter(timings, "CKE"); - config.memSpec.tXP = clk * queryUIntParameter(timings, "XP"); - config.memSpec.tXPDLL = clk * queryUIntParameter(timings, "XPDLL"); - config.memSpec.tXSR = clk * queryUIntParameter(timings, "XS"); - config.memSpec.tXSRDLL = clk * queryUIntParameter(timings, "XSDLL"); - config.memSpec.tAL = clk * queryUIntParameter(timings, "AL"); - config.memSpec.tRFC = clk * queryUIntParameter(timings, "RFC"); - config.memSpec.tRFC2 = clk * queryUIntParameter(timings, "RFC2"); - config.memSpec.tRFC4 = clk * queryUIntParameter(timings, "RFC4"); - config.memSpec.tREFI = clk * queryUIntParameter(timings, "REFI"); - config.memSpec.tDQSCK = clk * queryUIntParameter(timings, "DQSCK"); + config.memSpec->clkMHz = queryDoubleParameter(timings, "clkMhz"); + config.memSpec->clk = FrequencyToClk(config.memSpec->clkMHz); + sc_time clk = config.memSpec->clk; + config.memSpec->tRP = clk * queryUIntParameter(timings, "RP"); + config.memSpec->tRAS = clk * queryUIntParameter(timings, "RAS"); + config.memSpec->tRC = clk * queryUIntParameter(timings, "RC"); + config.memSpec->tRTP = clk * queryUIntParameter(timings, "RTP"); + config.memSpec->tRRD_S = clk * queryUIntParameter(timings, "RRD_S"); + config.memSpec->tRRD_L = clk * queryUIntParameter(timings, "RRD_L"); + config.memSpec->tCCD_S = clk * queryUIntParameter(timings, "CCD_S"); + config.memSpec->tCCD_L = clk * queryUIntParameter(timings, "CCD_L"); + config.memSpec->tRCD = clk * queryUIntParameter(timings, "RCD"); + config.memSpec->tNAW = clk * queryUIntParameter(timings, "FAW"); + config.memSpec->tRL = clk * queryUIntParameter(timings, "RL"); + config.memSpec->tWL = clk * queryUIntParameter(timings, "WL"); + config.memSpec->tWR = clk * queryUIntParameter(timings, "WR"); + config.memSpec->tWTR_S = clk * queryUIntParameter(timings, "WTR_S"); + config.memSpec->tWTR_L = clk * queryUIntParameter(timings, "WTR_L"); + config.memSpec->tCKESR = clk * queryUIntParameter(timings, "CKESR"); + config.memSpec->tCKE = clk * queryUIntParameter(timings, "CKE"); + config.memSpec->tXP = clk * queryUIntParameter(timings, "XP"); + config.memSpec->tXPDLL = clk * queryUIntParameter(timings, "XPDLL"); + config.memSpec->tXSR = clk * queryUIntParameter(timings, "XS"); + config.memSpec->tXSRDLL = clk * queryUIntParameter(timings, "XSDLL"); + config.memSpec->tAL = clk * queryUIntParameter(timings, "AL"); + config.memSpec->tRFC = clk * queryUIntParameter(timings, "RFC"); + config.memSpec->tRFC2 = clk * queryUIntParameter(timings, "RFC2"); + config.memSpec->tRFC4 = clk * queryUIntParameter(timings, "RFC4"); + config.memSpec->tREFI = clk * queryUIntParameter(timings, "REFI"); + config.memSpec->tDQSCK = clk * queryUIntParameter(timings, "DQSCK"); - config.memSpec.refreshTimings.clear(); - for (unsigned int i = 0; i < config.memSpec.NumberOfBanks; ++i) { - config.memSpec.refreshTimings[Bank(i)] = RefreshTiming(config.memSpec.tRFC, - config.memSpec.tRFC2, - config.memSpec.tRFC4, - config.memSpec.tREFI); + config.memSpec->refreshTimings.clear(); + for (unsigned int i = 0; i < config.memSpec->NumberOfBanks; ++i) { + config.memSpec->refreshTimings[Bank(i)] = RefreshTiming(config.memSpec->tRFC, + config.memSpec->tRFC2, + config.memSpec->tRFC4, + config.memSpec->tREFI); } // Currents and Volatages: XMLElement *powers = memspec->FirstChildElement("mempowerspec"); - config.memSpec.iDD0 = queryDoubleParameter(powers, "idd0"); - config.memSpec.iDD02 = queryDoubleParameter(powers, "idd02"); - config.memSpec.iDD2P0 = queryDoubleParameter(powers, "idd2p0"); - config.memSpec.iDD2P1 = queryDoubleParameter(powers, "idd2p1"); - config.memSpec.iDD2N = queryDoubleParameter(powers, "idd2n"); - config.memSpec.iDD3P0 = queryDoubleParameter(powers, "idd3p0"); - config.memSpec.iDD3P1 = queryDoubleParameter(powers, "idd3p1"); - config.memSpec.iDD3N = queryDoubleParameter(powers, "idd3n"); - config.memSpec.iDD4R = queryDoubleParameter(powers, "idd4r"); - config.memSpec.iDD4W = queryDoubleParameter(powers, "idd4w"); - config.memSpec.iDD5 = queryDoubleParameter(powers, "idd5"); - config.memSpec.iDD6 = queryDoubleParameter(powers, "idd6"); - config.memSpec.iDD62 = queryDoubleParameter(powers, "idd62"); - config.memSpec.vDD = queryDoubleParameter(powers, "vdd"); - config.memSpec.vDD2 = queryDoubleParameter(powers, "vdd2"); + config.memSpec->iDD0 = queryDoubleParameter(powers, "idd0"); + config.memSpec->iDD02 = queryDoubleParameter(powers, "idd02"); + config.memSpec->iDD2P0 = queryDoubleParameter(powers, "idd2p0"); + config.memSpec->iDD2P1 = queryDoubleParameter(powers, "idd2p1"); + config.memSpec->iDD2N = queryDoubleParameter(powers, "idd2n"); + config.memSpec->iDD3P0 = queryDoubleParameter(powers, "idd3p0"); + config.memSpec->iDD3P1 = queryDoubleParameter(powers, "idd3p1"); + config.memSpec->iDD3N = queryDoubleParameter(powers, "idd3n"); + config.memSpec->iDD4R = queryDoubleParameter(powers, "idd4r"); + config.memSpec->iDD4W = queryDoubleParameter(powers, "idd4w"); + config.memSpec->iDD5 = queryDoubleParameter(powers, "idd5"); + config.memSpec->iDD6 = queryDoubleParameter(powers, "idd6"); + config.memSpec->iDD62 = queryDoubleParameter(powers, "idd62"); + config.memSpec->vDD = queryDoubleParameter(powers, "vdd"); + config.memSpec->vDD2 = queryDoubleParameter(powers, "vdd2"); } -// TODO: fix this for LPDDR4 +// TODO: change timings for LPDDR4 void ConfigurationLoader::loadLPDDR4(Configuration &config, XMLElement *memspec) { //MemArchitecture: XMLElement *architecture = memspec->FirstChildElement("memarchitecturespec"); - config.memSpec.NumberOfBanks = queryUIntParameter(architecture, "nbrOfBanks"); - config.memSpec.NumberOfBankGroups = 1; - config.memSpec.NumberOfRanks = queryUIntParameter(architecture, "nbrOfRanks"); - config.memSpec.BurstLength = queryUIntParameter(architecture, "burstLength"); - config.memSpec.nActivate = 4; - config.memSpec.DataRate = queryUIntParameter(architecture, "dataRate"); - config.memSpec.NumberOfRows = queryUIntParameter(architecture, "nbrOfRows"); - config.memSpec.NumberOfColumns = queryUIntParameter(architecture, + config.memSpec->NumberOfBanks = queryUIntParameter(architecture, "nbrOfBanks"); + config.memSpec->NumberOfBankGroups = 1; + config.memSpec->NumberOfRanks = queryUIntParameter(architecture, "nbrOfRanks"); + config.memSpec->BurstLength = queryUIntParameter(architecture, "burstLength"); + config.memSpec->nActivate = 4; + config.memSpec->DataRate = queryUIntParameter(architecture, "dataRate"); + config.memSpec->NumberOfRows = queryUIntParameter(architecture, "nbrOfRows"); + config.memSpec->NumberOfColumns = queryUIntParameter(architecture, "nbrOfColumns"); - config.memSpec.bitWidth = queryUIntParameter(architecture, "width"); - config.memSpec.DLL = false; // TODO: Correct? - config.memSpec.termination = true; // TODO: Correct? + config.memSpec->bitWidth = queryUIntParameter(architecture, "width"); + config.memSpec->DLL = false; // TODO: Correct? + config.memSpec->termination = true; // TODO: Correct? //MemTimings XMLElement *timings = memspec->FirstChildElement("memtimingspec"); - config.memSpec.clkMHz = queryDoubleParameter(timings, "clkMhz"); - config.memSpec.clk = FrequencyToClk(config.memSpec.clkMHz); - sc_time clk = config.memSpec.clk; - config.memSpec.tRP = clk * queryUIntParameter(timings, "RPPB"); - config.memSpec.tRPAB = clk * queryUIntParameter(timings, "RPAB"); - config.memSpec.tRAS = clk * queryUIntParameter(timings, "RAS"); - config.memSpec.tRC = clk * queryUIntParameter(timings, "RC"); - config.memSpec.tRTP = clk * queryUIntParameter(timings, "RTP"); - config.memSpec.tRRD_S = clk * queryUIntParameter(timings, "RRD"); - config.memSpec.tRRD_L = clk * queryUIntParameter(timings, "RRD"); - config.memSpec.tCCD_S = clk * queryUIntParameter(timings, "CCD"); - config.memSpec.tCCD_L = clk * queryUIntParameter(timings, "CCD"); - config.memSpec.tRCD = clk * queryUIntParameter(timings, "RCD"); - config.memSpec.tNAW = clk * queryUIntParameter(timings, "FAW"); - config.memSpec.tRL = clk * queryUIntParameter(timings, "RL"); - config.memSpec.tWL = clk * queryUIntParameter(timings, "WL"); - config.memSpec.tWR = clk * queryUIntParameter(timings, "WR"); - config.memSpec.tWTR_S = clk * queryUIntParameter(timings, "WTR"); - config.memSpec.tWTR_L = clk * queryUIntParameter(timings, "WTR"); - config.memSpec.tCKESR = clk * queryUIntParameter(timings, "CKESR"); - config.memSpec.tCKE = clk * queryUIntParameter(timings, "CKE"); - config.memSpec.tXP = clk * queryUIntParameter(timings, "XP"); - config.memSpec.tXPDLL = clk * queryUIntParameter(timings, "XP"); - config.memSpec.tXSR = clk * queryUIntParameter(timings, "XS"); - config.memSpec.tXSRDLL = clk * queryUIntParameter(timings, "XS"); - config.memSpec.tAL = clk * queryUIntParameter(timings, "AL"); - config.memSpec.tRFC = clk * queryUIntParameter(timings, "RFCAB"); - // TODO: config.memSpec.tRFCPB = clk * queryUIntParameter(timings, "RFCPB"); - config.memSpec.tREFI = clk * queryUIntParameter(timings, "REFIAB"); - // TODO: config.memSpec.tREFIPB = clk * queryUIntParameter(timings, "RFCPB"); - config.memSpec.tDQSCK = clk * queryUIntParameter(timings, "DQSCK"); + config.memSpec->clkMHz = queryDoubleParameter(timings, "clkMhz"); + config.memSpec->clk = FrequencyToClk(config.memSpec->clkMHz); + sc_time clk = config.memSpec->clk; + config.memSpec->tRP = clk * queryUIntParameter(timings, "RPPB"); + config.memSpec->tRPAB = clk * queryUIntParameter(timings, "RPAB"); + config.memSpec->tRAS = clk * queryUIntParameter(timings, "RAS"); + config.memSpec->tRC = clk * queryUIntParameter(timings, "RC"); + config.memSpec->tRTP = clk * queryUIntParameter(timings, "RTP"); + config.memSpec->tRRD_S = clk * queryUIntParameter(timings, "RRD"); + config.memSpec->tRRD_L = clk * queryUIntParameter(timings, "RRD"); + config.memSpec->tCCD_S = clk * queryUIntParameter(timings, "CCD"); + config.memSpec->tCCD_L = clk * queryUIntParameter(timings, "CCD"); + config.memSpec->tRCD = clk * queryUIntParameter(timings, "RCD"); + config.memSpec->tNAW = clk * queryUIntParameter(timings, "FAW"); + config.memSpec->tRL = clk * queryUIntParameter(timings, "RL"); + config.memSpec->tWL = clk * queryUIntParameter(timings, "WL"); + config.memSpec->tWR = clk * queryUIntParameter(timings, "WR"); + config.memSpec->tWTR_S = clk * queryUIntParameter(timings, "WTR"); + config.memSpec->tWTR_L = clk * queryUIntParameter(timings, "WTR"); + config.memSpec->tCKESR = clk * queryUIntParameter(timings, "CKESR"); + config.memSpec->tCKE = clk * queryUIntParameter(timings, "CKE"); + config.memSpec->tXP = clk * queryUIntParameter(timings, "XP"); + config.memSpec->tXPDLL = clk * queryUIntParameter(timings, "XP"); + config.memSpec->tXSR = clk * queryUIntParameter(timings, "XS"); + config.memSpec->tXSRDLL = clk * queryUIntParameter(timings, "XS"); + config.memSpec->tAL = clk * queryUIntParameter(timings, "AL"); + config.memSpec->tRFC = clk * queryUIntParameter(timings, "RFCAB"); + // TODO: config.memSpec->tRFCPB = clk * queryUIntParameter(timings, "RFCPB"); + config.memSpec->tREFI = clk * queryUIntParameter(timings, "REFIAB"); + // TODO: config.memSpec->tREFIPB = clk * queryUIntParameter(timings, "RFCPB"); + config.memSpec->tDQSCK = clk * queryUIntParameter(timings, "DQSCK"); - config.memSpec.refreshTimings.clear(); - for (unsigned int i = 0; i < config.memSpec.NumberOfBanks; ++i) { - config.memSpec.refreshTimings[Bank(i)] = RefreshTiming(config.memSpec.tRFC, - config.memSpec.tREFI); + config.memSpec->refreshTimings.clear(); + for (unsigned int i = 0; i < config.memSpec->NumberOfBanks; ++i) { + config.memSpec->refreshTimings[Bank(i)] = RefreshTiming(config.memSpec->tRFC, + config.memSpec->tREFI); } // Currents and Volatages: XMLElement *powers = memspec->FirstChildElement("mempowerspec"); - config.memSpec.iDD0 = queryDoubleParameter(powers, "idd0"); - config.memSpec.iDD02 = queryDoubleParameter(powers, "idd02"); - config.memSpec.iDD2P0 = queryDoubleParameter(powers, "idd2p"); - config.memSpec.iDD2P1 = queryDoubleParameter(powers, "idd2p2"); - config.memSpec.iDD2N = queryDoubleParameter(powers, "idd2n"); - config.memSpec.iDD3P0 = queryDoubleParameter(powers, "idd3p"); - config.memSpec.iDD3P1 = queryDoubleParameter(powers, "idd3p2"); - config.memSpec.iDD3N = queryDoubleParameter(powers, "idd3n"); - config.memSpec.iDD4R = queryDoubleParameter(powers, "idd4r"); - config.memSpec.iDD4W = queryDoubleParameter(powers, "idd4w"); - config.memSpec.iDD5 = queryDoubleParameter(powers, "idd5"); - config.memSpec.iDD6 = queryDoubleParameter(powers, "idd6"); - config.memSpec.iDD62 = queryDoubleParameter(powers, "idd62"); - config.memSpec.vDD = queryDoubleParameter(powers, "vdd"); - config.memSpec.vDD2 = queryDoubleParameter(powers, "vdd2"); + config.memSpec->iDD0 = queryDoubleParameter(powers, "idd0"); + config.memSpec->iDD02 = queryDoubleParameter(powers, "idd02"); + config.memSpec->iDD2P0 = queryDoubleParameter(powers, "idd2p"); + config.memSpec->iDD2P1 = queryDoubleParameter(powers, "idd2p2"); + config.memSpec->iDD2N = queryDoubleParameter(powers, "idd2n"); + config.memSpec->iDD3P0 = queryDoubleParameter(powers, "idd3p"); + config.memSpec->iDD3P1 = queryDoubleParameter(powers, "idd3p2"); + config.memSpec->iDD3N = queryDoubleParameter(powers, "idd3n"); + config.memSpec->iDD4R = queryDoubleParameter(powers, "idd4r"); + config.memSpec->iDD4W = queryDoubleParameter(powers, "idd4w"); + config.memSpec->iDD5 = queryDoubleParameter(powers, "idd5"); + config.memSpec->iDD6 = queryDoubleParameter(powers, "idd6"); + config.memSpec->iDD62 = queryDoubleParameter(powers, "idd62"); + config.memSpec->vDD = queryDoubleParameter(powers, "vdd"); + config.memSpec->vDD2 = queryDoubleParameter(powers, "vdd2"); } void ConfigurationLoader::loadWideIO(Configuration &config, XMLElement *memspec) @@ -392,79 +407,79 @@ void ConfigurationLoader::loadWideIO(Configuration &config, XMLElement *memspec) //MemSpecification XMLElement *architecture = memspec->FirstChildElement("memarchitecturespec"); - config.memSpec.NumberOfBanks = queryUIntParameter(architecture, "nbrOfBanks"); - config.memSpec.NumberOfBankGroups = 1; - config.memSpec.NumberOfRanks = 1; - config.memSpec.BurstLength = queryUIntParameter(architecture, "burstLength"); - config.memSpec.nActivate = 2; - config.memSpec.DataRate = queryUIntParameter(architecture, "dataRate"); - config.memSpec.NumberOfRows = queryUIntParameter(architecture, "nbrOfRows"); - config.memSpec.NumberOfColumns = queryUIntParameter(architecture, + config.memSpec->NumberOfBanks = queryUIntParameter(architecture, "nbrOfBanks"); + config.memSpec->NumberOfBankGroups = 1; + config.memSpec->NumberOfRanks = 1; + config.memSpec->BurstLength = queryUIntParameter(architecture, "burstLength"); + config.memSpec->nActivate = 2; + config.memSpec->DataRate = queryUIntParameter(architecture, "dataRate"); + config.memSpec->NumberOfRows = queryUIntParameter(architecture, "nbrOfRows"); + config.memSpec->NumberOfColumns = queryUIntParameter(architecture, "nbrOfColumns"); - config.memSpec.bitWidth = queryUIntParameter(architecture, "width"); - config.memSpec.DLL = false; - config.memSpec.termination = false; + config.memSpec->bitWidth = queryUIntParameter(architecture, "width"); + config.memSpec->DLL = false; + config.memSpec->termination = false; //MemTimings XMLElement *timings = memspec->FirstChildElement("memtimingspec"); - config.memSpec.clkMHz = queryDoubleParameter(timings, "clkMhz"); - config.memSpec.clk = FrequencyToClk(config.memSpec.clkMHz); - sc_time clk = config.memSpec.clk; - config.memSpec.tRP = clk * queryUIntParameter(timings, "RP"); - config.memSpec.tRAS = clk * queryUIntParameter(timings, "RAS"); - config.memSpec.tRC = clk * queryUIntParameter(timings, "RC"); - config.memSpec.tRRD_S = clk * queryUIntParameter(timings, "RRD"); - config.memSpec.tRRD_L = config.memSpec.tRRD_S; - config.memSpec.tCCD_S = clk * queryUIntParameter(timings, "CCD"); - config.memSpec.tCCD_L = config.memSpec.tCCD_S; - config.memSpec.tRCD = clk * queryUIntParameter(timings, "RCD"); - config.memSpec.tNAW = clk * queryUIntParameter(timings, "TAW"); - config.memSpec.tRL = clk * queryUIntParameter(timings, "RL"); - config.memSpec.tWL = clk * queryUIntParameter(timings, "WL"); - config.memSpec.tWR = clk * queryUIntParameter(timings, "WR"); - config.memSpec.tWTR_S = clk * queryUIntParameter(timings, "WTR"); - config.memSpec.tWTR_L = config.memSpec.tWTR_S; - config.memSpec.tRTP = clk * queryUIntParameter(timings, "RTP"); - config.memSpec.tCKESR = clk * queryUIntParameter(timings, "CKESR"); - config.memSpec.tCKE = clk * queryUIntParameter(timings, "CKE"); - config.memSpec.tXP = clk * queryUIntParameter(timings, "XP"); - config.memSpec.tXPDLL = config.memSpec.tXP; - config.memSpec.tXSR = clk * queryUIntParameter(timings, "XS"); - config.memSpec.tXSRDLL = config.memSpec.tXSR; - config.memSpec.tAL = clk * queryUIntParameter(timings, "AL"); - config.memSpec.tRFC = clk * queryUIntParameter(timings, "RFC"); - config.memSpec.tREFI = clk * queryUIntParameter(timings, "REFI"); + config.memSpec->clkMHz = queryDoubleParameter(timings, "clkMhz"); + config.memSpec->clk = FrequencyToClk(config.memSpec->clkMHz); + sc_time clk = config.memSpec->clk; + config.memSpec->tRP = clk * queryUIntParameter(timings, "RP"); + config.memSpec->tRAS = clk * queryUIntParameter(timings, "RAS"); + config.memSpec->tRC = clk * queryUIntParameter(timings, "RC"); + config.memSpec->tRRD_S = clk * queryUIntParameter(timings, "RRD"); + config.memSpec->tRRD_L = config.memSpec->tRRD_S; + config.memSpec->tCCD_S = clk * queryUIntParameter(timings, "CCD"); + config.memSpec->tCCD_L = config.memSpec->tCCD_S; + config.memSpec->tRCD = clk * queryUIntParameter(timings, "RCD"); + config.memSpec->tNAW = clk * queryUIntParameter(timings, "TAW"); + config.memSpec->tRL = clk * queryUIntParameter(timings, "RL"); + config.memSpec->tWL = clk * queryUIntParameter(timings, "WL"); + config.memSpec->tWR = clk * queryUIntParameter(timings, "WR"); + config.memSpec->tWTR_S = clk * queryUIntParameter(timings, "WTR"); + config.memSpec->tWTR_L = config.memSpec->tWTR_S; + config.memSpec->tRTP = clk * queryUIntParameter(timings, "RTP"); + config.memSpec->tCKESR = clk * queryUIntParameter(timings, "CKESR"); + config.memSpec->tCKE = clk * queryUIntParameter(timings, "CKE"); + config.memSpec->tXP = clk * queryUIntParameter(timings, "XP"); + config.memSpec->tXPDLL = config.memSpec->tXP; + config.memSpec->tXSR = clk * queryUIntParameter(timings, "XS"); + config.memSpec->tXSRDLL = config.memSpec->tXSR; + config.memSpec->tAL = clk * queryUIntParameter(timings, "AL"); + config.memSpec->tRFC = clk * queryUIntParameter(timings, "RFC"); + config.memSpec->tREFI = clk * queryUIntParameter(timings, "REFI"); - config.memSpec.refreshTimings.clear(); - for (unsigned int i = 0; i < config.memSpec.NumberOfBanks; ++i) { - config.memSpec.refreshTimings[Bank(i)] = RefreshTiming(config.memSpec.tRFC, - config.memSpec.tREFI); + config.memSpec->refreshTimings.clear(); + for (unsigned int i = 0; i < config.memSpec->NumberOfBanks; ++i) { + config.memSpec->refreshTimings[Bank(i)] = RefreshTiming(config.memSpec->tRFC, + config.memSpec->tREFI); } // Currents and Volatages: XMLElement *powers = memspec->FirstChildElement("mempowerspec"); - config.memSpec.iDD0 = queryDoubleParameter(powers, "idd0"); - config.memSpec.iDD02 = queryDoubleParameter(powers, "idd02"); - config.memSpec.iDD2P0 = queryDoubleParameter(powers, "idd2p0"); - config.memSpec.iDD2P02 = queryDoubleParameter(powers, "idd2p02"); - config.memSpec.iDD2P1 = queryDoubleParameter(powers, "idd2p1"); - config.memSpec.iDD2P12 = queryDoubleParameter(powers, "idd2p12"); - config.memSpec.iDD2N = queryDoubleParameter(powers, "idd2n"); - config.memSpec.iDD2N2 = queryDoubleParameter(powers, "idd2n2"); - config.memSpec.iDD3P0 = queryDoubleParameter(powers, "idd3p0"); - config.memSpec.iDD3P02 = queryDoubleParameter(powers, "idd3p02"); - config.memSpec.iDD3P1 = queryDoubleParameter(powers, "idd3p1"); - config.memSpec.iDD3P12 = queryDoubleParameter(powers, "idd3p12"); - config.memSpec.iDD3N = queryDoubleParameter(powers, "idd3n"); - config.memSpec.iDD3N2 = queryDoubleParameter(powers, "idd3n2"); - config.memSpec.iDD4R = queryDoubleParameter(powers, "idd4r"); - config.memSpec.iDD4R2 = queryDoubleParameter(powers, "idd4r2"); - config.memSpec.iDD4W = queryDoubleParameter(powers, "idd4w"); - config.memSpec.iDD4W2 = queryDoubleParameter(powers, "idd4w2"); - config.memSpec.iDD5 = queryDoubleParameter(powers, "idd5"); - config.memSpec.iDD52 = queryDoubleParameter(powers, "idd52"); - config.memSpec.iDD6 = queryDoubleParameter(powers, "idd6"); - config.memSpec.iDD62 = queryDoubleParameter(powers, "idd62"); - config.memSpec.vDD = queryDoubleParameter(powers, "vdd"); - config.memSpec.vDD2 = queryDoubleParameter(powers, "vdd2"); + config.memSpec->iDD0 = queryDoubleParameter(powers, "idd0"); + config.memSpec->iDD02 = queryDoubleParameter(powers, "idd02"); + config.memSpec->iDD2P0 = queryDoubleParameter(powers, "idd2p0"); + config.memSpec->iDD2P02 = queryDoubleParameter(powers, "idd2p02"); + config.memSpec->iDD2P1 = queryDoubleParameter(powers, "idd2p1"); + config.memSpec->iDD2P12 = queryDoubleParameter(powers, "idd2p12"); + config.memSpec->iDD2N = queryDoubleParameter(powers, "idd2n"); + config.memSpec->iDD2N2 = queryDoubleParameter(powers, "idd2n2"); + config.memSpec->iDD3P0 = queryDoubleParameter(powers, "idd3p0"); + config.memSpec->iDD3P02 = queryDoubleParameter(powers, "idd3p02"); + config.memSpec->iDD3P1 = queryDoubleParameter(powers, "idd3p1"); + config.memSpec->iDD3P12 = queryDoubleParameter(powers, "idd3p12"); + config.memSpec->iDD3N = queryDoubleParameter(powers, "idd3n"); + config.memSpec->iDD3N2 = queryDoubleParameter(powers, "idd3n2"); + config.memSpec->iDD4R = queryDoubleParameter(powers, "idd4r"); + config.memSpec->iDD4R2 = queryDoubleParameter(powers, "idd4r2"); + config.memSpec->iDD4W = queryDoubleParameter(powers, "idd4w"); + config.memSpec->iDD4W2 = queryDoubleParameter(powers, "idd4w2"); + config.memSpec->iDD5 = queryDoubleParameter(powers, "idd5"); + config.memSpec->iDD52 = queryDoubleParameter(powers, "idd52"); + config.memSpec->iDD6 = queryDoubleParameter(powers, "idd6"); + config.memSpec->iDD62 = queryDoubleParameter(powers, "idd62"); + config.memSpec->vDD = queryDoubleParameter(powers, "vdd"); + config.memSpec->vDD2 = queryDoubleParameter(powers, "vdd2"); } diff --git a/DRAMSys/library/src/controller/core/configuration/ConfigurationLoader.h b/DRAMSys/library/src/controller/core/configuration/ConfigurationLoader.h index 8334cb4e..7a4e0410 100644 --- a/DRAMSys/library/src/controller/core/configuration/ConfigurationLoader.h +++ b/DRAMSys/library/src/controller/core/configuration/ConfigurationLoader.h @@ -32,14 +32,15 @@ * Authors: * Janik Schlemminger * Matthias Jung + * Lukas Steiner */ -#ifndef CONFIGURATIONLOADER_H_ -#define CONFIGURATIONLOADER_H_ +#ifndef CONFIGURATIONLOADER_H +#define CONFIGURATIONLOADER_H #include #include "../../../common/third_party/tinyxml2/tinyxml2.h" -#include "../../../common/Utils.h" +#include "../../../common/utils.h" #include "Configuration.h" class ConfigurationLoader @@ -65,8 +66,9 @@ private: static void loadConfig(Configuration &config, tinyxml2::XMLElement *configNode); static void loadConfigFromUri(Configuration &config, std::string uri, std::string first_element); - - //specific loader + // Loads common config of DRAMs + static void loadCommons(Configuration &config, tinyxml2::XMLElement *memspec); + // Load specific config static void loadDDR3(Configuration &config, tinyxml2::XMLElement *memspec); static void loadDDR4(Configuration &config, tinyxml2::XMLElement *memspec); static void loadLPDDR4(Configuration &config, tinyxml2::XMLElement *memspec); @@ -74,4 +76,4 @@ private: }; -#endif /* CONFIGURATIONLOADER_H_ */ +#endif // CONFIGURATIONLOADER_H diff --git a/DRAMSys/library/src/controller/core/configuration/MemSpec.h b/DRAMSys/library/src/controller/core/configuration/MemSpec.h index 434cb508..d13f2701 100644 --- a/DRAMSys/library/src/controller/core/configuration/MemSpec.h +++ b/DRAMSys/library/src/controller/core/configuration/MemSpec.h @@ -32,17 +32,18 @@ * Authors: * Janik Schlemminger * Matthias Jung + * Lukas Steiner */ -#ifndef MemSpec_H_ -#define MemSpec_H_ +#ifndef MEMSPEC_H +#define MEMSPEC_H #include #include -#include "../../../common/dramExtension.h" +#include "../../../common/dramExtensions.h" - -struct RefreshTiming { +struct RefreshTiming +{ RefreshTiming() {} RefreshTiming(sc_time tRFC, sc_time tREFI) : tRFC(tRFC), tRFC2(SC_ZERO_TIME), tRFC4(SC_ZERO_TIME), tREFI(tREFI) {} @@ -54,12 +55,8 @@ struct RefreshTiming { sc_time tREFI; }; -struct MemSpec { - MemSpec() - { - //default DDR4 - } - +struct MemSpec +{ const std::vector &getBanks() const { static std::vector banks; @@ -90,24 +87,31 @@ struct MemSpec { // Memspec Variables: double clkMHz; sc_time clk; - sc_time tRP; //precharge-time (pre -> act same bank) + sc_time tRP; //precharge-time (pre -> act same bank + sc_time tRTP; //Read to precharge + sc_time tRCD; //act -> read/write + sc_time tRL; //read latency (read command start to data strobe) + sc_time tWL; //write latency + sc_time tWR; //write recovery (write to precharge) + sc_time tCKESR; //min time in sref + sc_time tCKE; //min time in pdna or pdnp + + sc_time tRFC; //min ref->act delay 1X mode + sc_time tRFC2; //min ref->act delay 2X mode + sc_time tRFC4; //min ref->act delay 4X mode + sc_time tREFI; //auto refresh must be issued at an average periodic interval tREFI + + // TODO: move to specific memspecs sc_time tRPAB; //precharge-all time only for LPDDR4 sc_time tRAS; //active-time (act -> pre same bank) sc_time tRC; //RAS-cycle-time (min time bw 2 succesive ACT to same bank) sc_time tCCD_S; //max(bl, tCCD) is relevant for rd->rd sc_time tCCD_L; - sc_time tRTP; //Read to precharge sc_time tRRD_S; //min time bw 2 succesive ACT to different banks (different bank group) sc_time tRRD_L; //.. (same bank group) - sc_time tRCD; //act -> read/write sc_time tNAW; //n activate window - sc_time tRL; //read latency (read command start to data strobe) - sc_time tWL; //write latency - sc_time tWR; //write recovery (write to precharge) sc_time tWTR_S; //write to read (different bank group) sc_time tWTR_L; //.. (same bank group) - sc_time tCKESR; //min time in sref - sc_time tCKE; //min time in pdna or pdnp sc_time tXP; //min delay to row access command after pdnpx pdnax sc_time tXPDLL; //min delay to row access command after pdnpx pdnax for dll commands sc_time tXSR; //min delay to row access command after srefx @@ -115,11 +119,6 @@ struct MemSpec { sc_time tAL; //additive delay (delayed execution in dram) sc_time tDQSCK; - sc_time tRFC; //min ref->act delay 1X mode - sc_time tRFC2; //min ref->act delay 2X mode - sc_time tRFC4; //min ref->act delay 4X mode - sc_time tREFI; //auto refresh must be issued at an average periodic interval tREFI - // Currents and Voltages: double iDD0; double iDD02; @@ -165,5 +164,25 @@ struct MemSpec { } }; -#endif /* MemSpec_H_ */ +struct MemSpecDDR3 : public MemSpec +{ + +}; + +struct MemSpecDDR4 : public MemSpec +{ + +}; + +struct MemSpecWideIO : public MemSpec +{ + +}; + +struct MemSpecLPDDR4 : public MemSpec +{ + +}; + +#endif // MEMSPEC_H diff --git a/DRAMSys/library/src/controller/core/configuration/thermalSimConfig.h b/DRAMSys/library/src/controller/core/configuration/TemperatureSimConfig.h similarity index 96% rename from DRAMSys/library/src/controller/core/configuration/thermalSimConfig.h rename to DRAMSys/library/src/controller/core/configuration/TemperatureSimConfig.h index 6d202dbc..b9acd733 100644 --- a/DRAMSys/library/src/controller/core/configuration/thermalSimConfig.h +++ b/DRAMSys/library/src/controller/core/configuration/TemperatureSimConfig.h @@ -34,8 +34,8 @@ * Matthias Jung */ -#ifndef THERMALSIM_CONFIG_H -#define THERMALSIM_CONFIG_H +#ifndef TEMPERATURESIMCONFIG_H +#define TEMPERATURESIMCONFIG_H #include #include @@ -43,10 +43,10 @@ #include "../../../common/DebugManager.h" #include "../../../common/third_party/tinyxml2/tinyxml2.h" -#include "../../../common/Utils.h" - -struct TemperatureSimConfig { +#include "../../../common/utils.h" +struct TemperatureSimConfig +{ // Temperature Scale std::string TemperatureScale; std::string pathToResources; @@ -132,5 +132,5 @@ struct TemperatureSimConfig { } }; -#endif /* THERMALSIM_CONFIG_H */ +#endif // TEMPERATURESIMCONFIG_H diff --git a/DRAMSys/library/src/controller/core/powerdown/IPowerDownManager.h b/DRAMSys/library/src/controller/core/powerdown/IPowerDownManager.h index 1de77427..9ff8bd39 100644 --- a/DRAMSys/library/src/controller/core/powerdown/IPowerDownManager.h +++ b/DRAMSys/library/src/controller/core/powerdown/IPowerDownManager.h @@ -34,11 +34,11 @@ * Matthias Jung */ -#ifndef IPOWERDOWNMANAGER_H_ -#define IPOWERDOWNMANAGER_H_ +#ifndef IPOWERDOWNMANAGER_H +#define IPOWERDOWNMANAGER_H #include -#include "../../../common/dramExtension.h" +#include "../../../common/dramExtensions.h" #include "../../Command.h" @@ -126,4 +126,4 @@ inline std::string powerDownStateToString(PowerDownState powerDownState) } -#endif /* IPOWERDOWNMANAGER_H_ */ +#endif // IPOWERDOWNMANAGER_H diff --git a/DRAMSys/library/src/controller/core/powerdown/NoPowerDown.h b/DRAMSys/library/src/controller/core/powerdown/NoPowerDown.h index 13b9db16..19a53403 100644 --- a/DRAMSys/library/src/controller/core/powerdown/NoPowerDown.h +++ b/DRAMSys/library/src/controller/core/powerdown/NoPowerDown.h @@ -40,12 +40,12 @@ #include "PowerDownManager.h" #include -#include "../../../common/dramExtension.h" +#include "../../../common/dramExtensions.h" #include "../scheduling/ScheduledCommand.h" -class NoPowerDown: public IPowerDownManager +class NoPowerDown : public IPowerDownManager { public: NoPowerDown() {} diff --git a/DRAMSys/library/src/controller/core/powerdown/PowerDownManager.cpp b/DRAMSys/library/src/controller/core/powerdown/PowerDownManager.cpp index 93cab1a6..d5281e05 100644 --- a/DRAMSys/library/src/controller/core/powerdown/PowerDownManager.cpp +++ b/DRAMSys/library/src/controller/core/powerdown/PowerDownManager.cpp @@ -39,10 +39,10 @@ #include #include "PowerDownManager.h" #include "../ControllerCore.h" -#include "../TimingCalculation.h" +#include "../timingCalculations.h" #include "../../../common/DebugManager.h" #include -#include "../../../common/Utils.h" +#include "../../../common/utils.h" using namespace tlm; using namespace std; diff --git a/DRAMSys/library/src/controller/core/powerdown/PowerDownManager.h b/DRAMSys/library/src/controller/core/powerdown/PowerDownManager.h index a8a77e20..ee90629e 100644 --- a/DRAMSys/library/src/controller/core/powerdown/PowerDownManager.h +++ b/DRAMSys/library/src/controller/core/powerdown/PowerDownManager.h @@ -34,8 +34,8 @@ * Matthias Jung */ -#ifndef POWERDOWNMANAGER_H_ -#define POWERDOWNMANAGER_H_ +#ifndef POWERDOWNMANAGER_H +#define POWERDOWNMANAGER_H #include "PowerDownManagerBankwise.h" @@ -68,4 +68,4 @@ protected: }; -#endif /* POWERDOWNMANAGER_H_ */ +#endif // POWERDOWNMANAGER_H diff --git a/DRAMSys/library/src/controller/core/powerdown/PowerDownManagerBankwise.cpp b/DRAMSys/library/src/controller/core/powerdown/PowerDownManagerBankwise.cpp index 57490c88..a73d7674 100644 --- a/DRAMSys/library/src/controller/core/powerdown/PowerDownManagerBankwise.cpp +++ b/DRAMSys/library/src/controller/core/powerdown/PowerDownManagerBankwise.cpp @@ -36,9 +36,9 @@ #include "PowerDownManager.h" #include "../ControllerCore.h" -#include "../../../common/Utils.h" +#include "../../../common/utils.h" #include "../../../common/DebugManager.h" -#include "../TimingCalculation.h" +#include "../timingCalculations.h" using namespace tlm; diff --git a/DRAMSys/library/src/controller/core/powerdown/PowerDownManagerBankwise.h b/DRAMSys/library/src/controller/core/powerdown/PowerDownManagerBankwise.h index 5f532b00..69382538 100644 --- a/DRAMSys/library/src/controller/core/powerdown/PowerDownManagerBankwise.h +++ b/DRAMSys/library/src/controller/core/powerdown/PowerDownManagerBankwise.h @@ -34,15 +34,15 @@ * Matthias Jung */ -#ifndef POWERDOWNMANAGERBANKWISE_H_ -#define POWERDOWNMANAGERBANKWISE_H_ +#ifndef POWERDOWNMANAGERBANKWISE_H +#define POWERDOWNMANAGERBANKWISE_H #include #include #include #include #include "../../Command.h" -#include "../../../common/dramExtension.h" +#include "../../../common/dramExtensions.h" #include "../scheduling/ScheduledCommand.h" #include "IPowerDownManager.h" @@ -82,5 +82,5 @@ protected: void printDebugMessage(std::string message); }; -#endif /* POWERDOWNMANAGERBANKWISE_H_ */ +#endif // POWERDOWNMANAGERBANKWISE_H diff --git a/DRAMSys/library/src/controller/core/powerdown/PowerDownManagerTimeout.cpp b/DRAMSys/library/src/controller/core/powerdown/PowerDownManagerTimeout.cpp index c694d13f..997e9c37 100644 --- a/DRAMSys/library/src/controller/core/powerdown/PowerDownManagerTimeout.cpp +++ b/DRAMSys/library/src/controller/core/powerdown/PowerDownManagerTimeout.cpp @@ -38,9 +38,9 @@ #include "PowerDownManagerTimeout.h" #include "../ControllerCore.h" -#include "../../../common/Utils.h" +#include "../../../common/utils.h" #include "../../../common/DebugManager.h" -#include "../TimingCalculation.h" +#include "../timingCalculations.h" using namespace tlm; diff --git a/DRAMSys/library/src/controller/core/powerdown/PowerDownManagerTimeout.h b/DRAMSys/library/src/controller/core/powerdown/PowerDownManagerTimeout.h index 538df00c..d56675f5 100644 --- a/DRAMSys/library/src/controller/core/powerdown/PowerDownManagerTimeout.h +++ b/DRAMSys/library/src/controller/core/powerdown/PowerDownManagerTimeout.h @@ -36,12 +36,12 @@ * Felipe S. Prado */ -#ifndef POWERDOWNMANAGERTIMEOUT_H_ -#define POWERDOWNMANAGERTIMEOUT_H_ +#ifndef POWERDOWNMANAGERTIMEOUT_H +#define POWERDOWNMANAGERTIMEOUT_H #include "PowerDownManager.h" #include -#include "../../../common/dramExtension.h" +#include "../../../common/dramExtensions.h" #include "../scheduling/ScheduledCommand.h" #include @@ -60,4 +60,4 @@ public: -#endif /* POWERDOWNMANAGERTIMEOUT_H_ */ +#endif // POWERDOWNMANAGERTIMEOUT_H diff --git a/DRAMSys/library/src/controller/core/powerdown/PowerDownManagerTimeoutBankwise.cpp b/DRAMSys/library/src/controller/core/powerdown/PowerDownManagerTimeoutBankwise.cpp index 56a8b9b3..cd743e02 100644 --- a/DRAMSys/library/src/controller/core/powerdown/PowerDownManagerTimeoutBankwise.cpp +++ b/DRAMSys/library/src/controller/core/powerdown/PowerDownManagerTimeoutBankwise.cpp @@ -38,9 +38,9 @@ #include "PowerDownManagerTimeoutBankwise.h" #include "../ControllerCore.h" -#include "../../../common/Utils.h" +#include "../../../common/utils.h" #include "../../../common/DebugManager.h" -#include "../TimingCalculation.h" +#include "../timingCalculations.h" using namespace tlm; diff --git a/DRAMSys/library/src/controller/core/powerdown/PowerDownManagerTimeoutBankwise.h b/DRAMSys/library/src/controller/core/powerdown/PowerDownManagerTimeoutBankwise.h index 3c1fb76b..e4a43bed 100644 --- a/DRAMSys/library/src/controller/core/powerdown/PowerDownManagerTimeoutBankwise.h +++ b/DRAMSys/library/src/controller/core/powerdown/PowerDownManagerTimeoutBankwise.h @@ -36,12 +36,12 @@ * Felipe S. Prado */ -#ifndef POWERDOWNMANAGERTIMEOUTBANKWISE_H_ -#define POWERDOWNMANAGERTIMEOUTBANKWISE_H_ +#ifndef POWERDOWNMANAGERTIMEOUTBANKWISE_H +#define POWERDOWNMANAGERTIMEOUTBANKWISE_H #include "PowerDownManager.h" #include -#include "../../../common/dramExtension.h" +#include "../../../common/dramExtensions.h" #include "../scheduling/ScheduledCommand.h" #include @@ -60,4 +60,4 @@ public: -#endif /* POWERDOWNMANAGERTIMEOUTBANKWISE_H_ */ +#endif // POWERDOWNMANAGERTIMEOUTBANKWISE_H diff --git a/DRAMSys/library/src/controller/core/refresh/IRefreshManager.h b/DRAMSys/library/src/controller/core/refresh/IRefreshManager.h index 1668ef61..9b2f581b 100644 --- a/DRAMSys/library/src/controller/core/refresh/IRefreshManager.h +++ b/DRAMSys/library/src/controller/core/refresh/IRefreshManager.h @@ -35,8 +35,8 @@ * Matthias Jung */ -#ifndef IREFRESHMANAGER_H_ -#define IREFRESHMANAGER_H_ +#ifndef IREFRESHMANAGER_H +#define IREFRESHMANAGER_H #include #include "../scheduling/ScheduledCommand.h" @@ -62,5 +62,5 @@ public: virtual bool isInvalidated(tlm::tlm_generic_payload &payload, sc_time time) = 0; }; -#endif /* IREFRESHMANAGER_H_ */ +#endif // IREFRESHMANAGER_H diff --git a/DRAMSys/library/src/controller/core/refresh/RGR.cpp b/DRAMSys/library/src/controller/core/refresh/RGR.cpp index 37b552e4..f5cea5d0 100644 --- a/DRAMSys/library/src/controller/core/refresh/RGR.cpp +++ b/DRAMSys/library/src/controller/core/refresh/RGR.cpp @@ -36,8 +36,8 @@ #include "RGR.h" #include "../ControllerCore.h" -#include "../TimingCalculation.h" -#include "../../../common/Utils.h" +#include "../timingCalculations.h" +#include "../../../common/utils.h" #define TRUE 1 #define FALSE !(TRUE) @@ -46,19 +46,19 @@ using namespace std; RGR::RGR(sc_module_name, ControllerCore &ctrlcore) : ccore(ctrlcore), - timing(ctrlcore.config.memSpec.refreshTimings[ccore.getBanks()[0]]) + timing(ctrlcore.config.memSpec->refreshTimings[ccore.getBanks()[0]]) { fmb = ccore.config.ControllerCoreRefForceMaxPostponeBurst; bwl = ccore.config.BankwiseLogic; ri = ccore.config.getRowInc(); - auto nr = ccore.config.memSpec.NumberOfRows; + auto nr = ccore.config.memSpec->NumberOfRows; auto nar = ccore.config.getNumAR(); auto m = ccore.config.getRefMode(); rpr = (nr / m) / nar; assert(rpr > 0); tREFIx = timing.tREFI / m; trp = ccore.config.getTrpb(); - trcd = ccore.config.memSpec.tRCD; + trcd = ccore.config.memSpec->tRCD; postponeEnabled = ccore.config.ControllerCoreRefEnablePostpone; pullInEnabled = ccore.config.ControllerCoreRefEnablePullIn; maxpostpone = ccore.config.ControllerCoreRefMaxPostponed * m; @@ -73,7 +73,7 @@ RGR::RGR(sc_module_name, ControllerCore &ctrlcore) : ccore(ctrlcore), } #if INITIAL_DISPLACEMENT == TRUE if (bwl) { - auto nbs = ccore.config.memSpec.NumberOfBanks; + auto nbs = ccore.config.memSpec->NumberOfBanks; for (Bank b : ccore.getBanks()) { nextPlannedRefreshs[b] = b.ID() * tREFIx / nbs; } diff --git a/DRAMSys/library/src/controller/core/refresh/RGR.h b/DRAMSys/library/src/controller/core/refresh/RGR.h index 96ad8cdb..bfe8e444 100644 --- a/DRAMSys/library/src/controller/core/refresh/RGR.h +++ b/DRAMSys/library/src/controller/core/refresh/RGR.h @@ -32,12 +32,15 @@ * Author: Éder F. Zulian */ -#ifndef RGR_MANAGER_H_ -#define RGR_MANAGER_H_ -#include "../../../common/dramExtension.h" +#ifndef RGR_H +#define RGR_H + +#include "../../../common/dramExtensions.h" #include "../configuration/MemSpec.h" #include "IRefreshManager.h" + class ControllerCore; + class RGR : public IRefreshManager, public sc_module { public: @@ -73,5 +76,6 @@ private: void planNextRefresh(Bank b, sc_time t, bool align); void printDebugMessage(std::string message); }; -#endif /* RGR_MANAGER_H_ */ + +#endif // RGR_H diff --git a/DRAMSys/library/src/controller/core/refresh/RefreshManager.cpp b/DRAMSys/library/src/controller/core/refresh/RefreshManager.cpp index b07ed332..b088ca97 100644 --- a/DRAMSys/library/src/controller/core/refresh/RefreshManager.cpp +++ b/DRAMSys/library/src/controller/core/refresh/RefreshManager.cpp @@ -39,14 +39,14 @@ #include "RefreshManager.h" #include "../ControllerCore.h" -#include "../TimingCalculation.h" -#include "../../../common/Utils.h" +#include "../timingCalculations.h" +#include "../../../common/utils.h" using namespace tlm; RefreshManager::RefreshManager(sc_module_name, ControllerCore &controller) : controllerCore(controller), - timing(controller.config.memSpec.refreshTimings[Bank(0)]) + timing(controller.config.memSpec->refreshTimings[Bank(0)]) { auto m = controllerCore.config.getRefMode(); tREFIx = timing.tREFI / m; @@ -159,7 +159,7 @@ void RefreshManager::scheduleRefresh(tlm::tlm_generic_payload &payload, pre = doRefresh(payload, time); nrt = tRFCx; if (pre) - nrt += controllerCore.config.memSpec.tRP; + nrt += controllerCore.config.memSpec->tRP; nextRefTiming = nrt; nextState = ST_PULLIN; } else { @@ -175,7 +175,7 @@ void RefreshManager::scheduleRefresh(tlm::tlm_generic_payload &payload, pre = doRefresh(payload, time); nrt = tRFCx; if (pre) - nrt += controllerCore.config.memSpec.tRP; + nrt += controllerCore.config.memSpec->tRP; nextRefTiming = nrt; nextState = ST_PULLIN; } else { @@ -220,7 +220,7 @@ void RefreshManager::scheduleRefresh(tlm::tlm_generic_payload &payload, } else { nrt = tRFCx; if (pre) - nrt += controllerCore.config.memSpec.tRP; + nrt += controllerCore.config.memSpec->tRP; nextRefTiming = nrt; nextState = ST_BURST; } diff --git a/DRAMSys/library/src/controller/core/refresh/RefreshManager.h b/DRAMSys/library/src/controller/core/refresh/RefreshManager.h index c5fb5905..c89fa12b 100644 --- a/DRAMSys/library/src/controller/core/refresh/RefreshManager.h +++ b/DRAMSys/library/src/controller/core/refresh/RefreshManager.h @@ -35,8 +35,8 @@ * Éder F. Zulian */ -#ifndef REFRESHMANAGER_H_ -#define REFRESHMANAGER_H_ +#ifndef REFRESHMANAGER_H +#define REFRESHMANAGER_H #include "IRefreshManager.h" #include "../configuration/MemSpec.h" @@ -78,5 +78,5 @@ private: void printDebugMessage(std::string message); }; -#endif /* REFRESHMANAGER_H_ */ +#endif // REFRESHMANAGER_H diff --git a/DRAMSys/library/src/controller/core/refresh/RefreshManagerBankwise.cpp b/DRAMSys/library/src/controller/core/refresh/RefreshManagerBankwise.cpp index 533b7859..c53f779b 100644 --- a/DRAMSys/library/src/controller/core/refresh/RefreshManagerBankwise.cpp +++ b/DRAMSys/library/src/controller/core/refresh/RefreshManagerBankwise.cpp @@ -37,14 +37,14 @@ #include "RefreshManagerBankwise.h" #include "../ControllerCore.h" -#include "../TimingCalculation.h" -#include "../../../common/Utils.h" +#include "../timingCalculations.h" +#include "../../../common/utils.h" using namespace std; RefreshManagerBankwise::RefreshManagerBankwise(sc_module_name, ControllerCore &controller) : controllerCore(controller), - timing(controller.config.memSpec.refreshTimings[Bank(0)]) + timing(controller.config.memSpec->refreshTimings[Bank(0)]) { auto m = controllerCore.config.getRefMode(); tREFIx = timing.tREFI / m; @@ -146,7 +146,7 @@ void RefreshManagerBankwise::scheduleRefresh(tlm::tlm_generic_payload &payload, pre = doRefresh(payload, time); nrt = tRFCx; if (pre) - nrt += controllerCore.config.memSpec.tRP; + nrt += controllerCore.config.memSpec->tRP; nextRefTiming = nrt; nextState[bank] = ST_PULLIN; } else { @@ -162,7 +162,7 @@ void RefreshManagerBankwise::scheduleRefresh(tlm::tlm_generic_payload &payload, pre = doRefresh(payload, time); nrt = tRFCx; if (pre) - nrt += controllerCore.config.memSpec.tRP; + nrt += controllerCore.config.memSpec->tRP; nextRefTiming = nrt; nextState[bank] = ST_PULLIN; } else { @@ -208,7 +208,7 @@ void RefreshManagerBankwise::scheduleRefresh(tlm::tlm_generic_payload &payload, } else { nrt = tRFCx; if (pre) - nrt += controllerCore.config.memSpec.tRP; + nrt += controllerCore.config.memSpec->tRP; nextRefTiming = nrt; nextState[bank] = ST_BURST; } diff --git a/DRAMSys/library/src/controller/core/refresh/RefreshManagerBankwise.h b/DRAMSys/library/src/controller/core/refresh/RefreshManagerBankwise.h index 6b8558a1..a4728f4e 100644 --- a/DRAMSys/library/src/controller/core/refresh/RefreshManagerBankwise.h +++ b/DRAMSys/library/src/controller/core/refresh/RefreshManagerBankwise.h @@ -35,8 +35,8 @@ * Éder F. Zulian */ -#ifndef BANKWISEREFRESHMANAGER_H_ -#define BANKWISEREFRESHMANAGER_H_ +#ifndef REFRESHMANAGERBANKWISE_H +#define REFRESHMANAGERBANKWISE_H //#include "../../../common/dramExtension.h" #include "IRefreshManager.h" @@ -79,5 +79,5 @@ private: void printDebugMessage(std::string message); }; -#endif /* BANKWISEREFRESHMANAGER_H_ */ +#endif // REFRESHMANAGERBANKWISE_H diff --git a/DRAMSys/library/src/controller/core/scheduling/ScheduledCommand.cpp b/DRAMSys/library/src/controller/core/scheduling/ScheduledCommand.cpp index 3b367eda..4207b9ff 100644 --- a/DRAMSys/library/src/controller/core/scheduling/ScheduledCommand.cpp +++ b/DRAMSys/library/src/controller/core/scheduling/ScheduledCommand.cpp @@ -35,8 +35,8 @@ */ #include "ScheduledCommand.h" -#include "../TimingCalculation.h" -#include "../../../common/Utils.h" +#include "../timingCalculations.h" +#include "../../../common/utils.h" #include "../configuration/Configuration.h" bool ScheduledCommand::isNoCommand() const @@ -127,13 +127,13 @@ TimeInterval ScheduledCommand::getIntervalOnDataStrobe() const || getCommand() == Command::Write || getCommand() == Command::WriteA); - MemSpec &timings = Configuration::getInstance().memSpec; + MemSpec *timings = Configuration::getInstance().memSpec; if (getCommand() == Command::Read || getCommand() == Command::ReadA) { - return TimeInterval(getStart() + timings.tRL, - getStart() + timings.tRL + getReadAccessTime()); + return TimeInterval(getStart() + timings->tRL, + getStart() + timings->tRL + getReadAccessTime()); } else { - return TimeInterval(getStart() + timings.tWL - timings.clk / 2, - getStart() + timings.tWL + getWriteAccessTime() - timings.clk / 2); + return TimeInterval(getStart() + timings->tWL - timings->clk / 2, + getStart() + timings->tWL + getWriteAccessTime() - timings->clk / 2); } } diff --git a/DRAMSys/library/src/controller/core/scheduling/ScheduledCommand.h b/DRAMSys/library/src/controller/core/scheduling/ScheduledCommand.h index c2a5a2fc..bc4721b7 100644 --- a/DRAMSys/library/src/controller/core/scheduling/ScheduledCommand.h +++ b/DRAMSys/library/src/controller/core/scheduling/ScheduledCommand.h @@ -34,14 +34,14 @@ * Matthias Jung */ -#ifndef SCHEDULEDCOMMAND_H_ -#define SCHEDULEDCOMMAND_H_ +#ifndef SCHEDULEDCOMMAND_H +#define SCHEDULEDCOMMAND_H #include #include #include "../../Command.h" -#include "../../../common/dramExtension.h" -#include "../../../common/Utils.h" +#include "../../../common/dramExtensions.h" +#include "../../../common/utils.h" class ScheduledCommand { @@ -98,5 +98,5 @@ private: DramExtension extension; }; -#endif /* SCHEDULEDCOMMAND_H_ */ +#endif // SCHEDULEDCOMMAND_H diff --git a/DRAMSys/library/src/controller/core/scheduling/checker/ActBChecker.cpp b/DRAMSys/library/src/controller/core/scheduling/checker/ActBChecker.cpp index fff23cde..16557602 100644 --- a/DRAMSys/library/src/controller/core/scheduling/checker/ActBChecker.cpp +++ b/DRAMSys/library/src/controller/core/scheduling/checker/ActBChecker.cpp @@ -36,10 +36,10 @@ #include #include #include "ActBChecker.h" -#include "../../TimingCalculation.h" +#include "../../timingCalculations.h" #include "../../../../common/DebugManager.h" #include "../../../Command.h" -#include "../../../../common/Utils.h" +#include "../../../../common/utils.h" using namespace std; @@ -53,27 +53,27 @@ void ActBChecker::delayToSatisfyConstraints(ScheduledCommand &cmd) const Configuration::getInstance().getTrpb()); } else if (lcb.getCommand() == Command::Precharge || lcb.getCommand() == Command::PrechargeAll) { - cmd.establishMinDistanceFromStart(lcb.getStart(), config.memSpec.tRP); + cmd.establishMinDistanceFromStart(lcb.getStart(), config.memSpec->tRP); } else if (lcb.getCommand() == Command::ReadA) { cmd.establishMinDistanceFromStart(lcb.getStart(), - config.memSpec.tRTP + config.memSpec.tRP); + config.memSpec->tRTP + config.memSpec->tRP); } else if (lcb.getCommand() == Command::WriteA) { cmd.establishMinDistanceFromStart(lcb.getStart(), - config.memSpec.tWL + getWriteAccessTime() + config.memSpec.tWR + - config.memSpec.tRP); + config.memSpec->tWL + getWriteAccessTime() + config.memSpec->tWR + + config.memSpec->tRP); } else if (lcb.getCommand() == Command::AutoRefresh) { auto m = Configuration::getInstance().getRefMode(); if (m == 4) - cmd.establishMinDistanceFromStart(lcb.getStart(), config.memSpec.tRFC4); + cmd.establishMinDistanceFromStart(lcb.getStart(), config.memSpec->tRFC4); else if (m == 2) - cmd.establishMinDistanceFromStart(lcb.getStart(), config.memSpec.tRFC2); + cmd.establishMinDistanceFromStart(lcb.getStart(), config.memSpec->tRFC2); else - cmd.establishMinDistanceFromStart(lcb.getStart(), config.memSpec.tRFC); + cmd.establishMinDistanceFromStart(lcb.getStart(), config.memSpec->tRFC); } else if (lcb.getCommand() == Command::PDNPX || lcb.getCommand() == Command::PDNAX) { - cmd.establishMinDistanceFromStart(lcb.getStart(), config.memSpec.tXP); + cmd.establishMinDistanceFromStart(lcb.getStart(), config.memSpec->tXP); } else if (lcb.getCommand() == Command::SREFX) { - cmd.establishMinDistanceFromStart(lcb.getStart(), config.memSpec.tXSR); + cmd.establishMinDistanceFromStart(lcb.getStart(), config.memSpec->tXSR); } else { reportFatal("ActB Checker", "ActB can not follow " + commandToString(lcb.getCommand())); @@ -81,13 +81,13 @@ void ActBChecker::delayToSatisfyConstraints(ScheduledCommand &cmd) const } ScheduledCommand lc; if ((lc = state.getLastCommand(Command::PrechargeAll)).isValidCommand()) { - cmd.establishMinDistanceFromStart(lc.getStart(), config.memSpec.tRP); + cmd.establishMinDistanceFromStart(lc.getStart(), config.memSpec->tRP); } delay_to_satisfy_activateToActivate_sameBank(cmd); while (!(state.bus.isFree(cmd.getStart()) && satsfies_activateToActivate_differentBank(cmd) && satisfies_nActivateWindow(cmd))) { - cmd.delayStart(config.memSpec.clk); + cmd.delayStart(config.memSpec->clk); } } @@ -97,7 +97,7 @@ void ActBChecker::delay_to_satisfy_activateToActivate_sameBank( ScheduledCommand lastActOnBank = state.getLastCommand(Command::Activate, cmd.getBank()); if (lastActOnBank.isValidCommand()) { - cmd.establishMinDistanceFromStart(lastActOnBank.getStart(), config.memSpec.tRC); + cmd.establishMinDistanceFromStart(lastActOnBank.getStart(), config.memSpec->tRC); } ScheduledCommand lastActBOnBank = state.getLastCommand(Command::ActB, cmd.getBank()); @@ -121,7 +121,7 @@ bool ActBChecker::satsfies_activateToActivate_differentBank( } for (auto act : state.lastActivates) { sc_time t = act.first, tRRD = (cmd.getBankGroup() == act.second.getBankGroup() ? - config.memSpec.tRRD_L : config.memSpec.tRRD_S); + config.memSpec->tRRD_L : config.memSpec->tRRD_S); if ((t < cmd.getStart() && cmd.getStart() - t < tRRD) || (cmd.getStart() <= t && t - cmd.getStart() < tRRD)) { return false; @@ -132,11 +132,11 @@ bool ActBChecker::satsfies_activateToActivate_differentBank( bool ActBChecker::satisfies_nActivateWindow(ScheduledCommand &cmd) const { - if (state.lastActivatesB.size() >= config.memSpec.nActivate) { + if (state.lastActivatesB.size() >= config.memSpec->nActivate) { maplastActivates = state.lastActivatesB; lastActivates.emplace(cmd.getStart(), cmd); auto upper = lastActivates.begin(); - advance(upper, config.memSpec.nActivate); + advance(upper, config.memSpec->nActivate); auto lower = lastActivates.begin(); while (upper != lastActivates.end()) { if (upper->first - lower->first < Configuration::getInstance().getTfawb()) { diff --git a/DRAMSys/library/src/controller/core/scheduling/checker/ActBChecker.h b/DRAMSys/library/src/controller/core/scheduling/checker/ActBChecker.h index 023db94f..f1a04859 100644 --- a/DRAMSys/library/src/controller/core/scheduling/checker/ActBChecker.h +++ b/DRAMSys/library/src/controller/core/scheduling/checker/ActBChecker.h @@ -31,13 +31,16 @@ * * Author: Éder F. Zulian */ -#ifndef ACTB_CHECKER_H_ -#define ACTB_CHECKER_H_ + +#ifndef ACTBCHECKER_H +#define ACTBCHECKER_H + #include #include "ICommandChecker.h" #include "../../configuration/Configuration.h" #include "../../../ControllerState.h" -class ActBChecker: public ICommandChecker + +class ActBChecker : public ICommandChecker { public: ActBChecker(const Configuration &config, @@ -53,4 +56,5 @@ private: bool satsfies_activateToActivate_differentBank(ScheduledCommand &command) const; bool satisfies_nActivateWindow(ScheduledCommand &command) const; }; -#endif /* ACTB_CHECKER_H_ */ + +#endif // ACTBCHECKER_H diff --git a/DRAMSys/library/src/controller/core/scheduling/checker/ActivateChecker.cpp b/DRAMSys/library/src/controller/core/scheduling/checker/ActivateChecker.cpp index 86a6b0a1..f2bb8033 100644 --- a/DRAMSys/library/src/controller/core/scheduling/checker/ActivateChecker.cpp +++ b/DRAMSys/library/src/controller/core/scheduling/checker/ActivateChecker.cpp @@ -38,10 +38,10 @@ #include #include #include "ActivateChecker.h" -#include "../../TimingCalculation.h" +#include "../../timingCalculations.h" #include "../../../../common/DebugManager.h" #include "../../../Command.h" -#include "../../../../common/Utils.h" +#include "../../../../common/utils.h" using namespace std; @@ -56,38 +56,32 @@ void ActivateChecker::delayToSatisfyConstraints(ScheduledCommand &command) const || lastCommandOnBank.getCommand() == Command::Precharge || lastCommandOnBank.getCommand() == Command::PrechargeAll) { command.establishMinDistanceFromStart(lastCommandOnBank.getStart(), - config.memSpec.tRP); + config.memSpec->tRP); } else if (lastCommandOnBank.getCommand() == Command::ReadA) { command.establishMinDistanceFromStart(lastCommandOnBank.getStart(), - config.memSpec.tRTP + config.memSpec.tRP); + config.memSpec->tRTP + config.memSpec->tRP); } else if (lastCommandOnBank.getCommand() == Command::WriteA) { command.establishMinDistanceFromStart(lastCommandOnBank.getStart(), - config.memSpec.tRP); - } else if (lastCommandOnBank.getCommand() == Command::ReadA) { - command.establishMinDistanceFromStart(lastCommandOnBank.getStart(), - config.memSpec.tRTP + config.memSpec.tRP); - } else if (lastCommandOnBank.getCommand() == Command::WriteA) { - command.establishMinDistanceFromStart(lastCommandOnBank.getStart(), - config.memSpec.tWL + getWriteAccessTime() + config.memSpec.tWR + - config.memSpec.tRP); + config.memSpec->tWL + getWriteAccessTime() + config.memSpec->tWR + + config.memSpec->tRP); } else if (lastCommandOnBank.getCommand() == Command::AutoRefresh) { auto m = Configuration::getInstance().getRefMode(); if (m == 4) command.establishMinDistanceFromStart(lastCommandOnBank.getStart(), - config.memSpec.tRFC4); + config.memSpec->tRFC4); else if (m == 2) command.establishMinDistanceFromStart(lastCommandOnBank.getStart(), - config.memSpec.tRFC2); + config.memSpec->tRFC2); else command.establishMinDistanceFromStart(lastCommandOnBank.getStart(), - config.memSpec.tRFC); + config.memSpec->tRFC); } else if (lastCommandOnBank.getCommand() == Command::PDNPX || lastCommandOnBank.getCommand() == Command::PDNAX) { command.establishMinDistanceFromStart(lastCommandOnBank.getStart(), - config.memSpec.tXP); + config.memSpec->tXP); } else if (lastCommandOnBank.getCommand() == Command::SREFX) { command.establishMinDistanceFromStart(lastCommandOnBank.getStart(), - config.memSpec.tXSR); + config.memSpec->tXSR); } else reportFatal("Activate Checker", "Activate can not follow " + commandToString(lastCommandOnBank.getCommand())); @@ -98,7 +92,7 @@ void ActivateChecker::delayToSatisfyConstraints(ScheduledCommand &command) const while (!(state.bus.isFree(command.getStart()) && satsfies_activateToActivate_differentBank(command) && satisfies_nActivateWindow(command))) { - command.delayStart(config.memSpec.clk); + command.delayStart(config.memSpec->clk); } } @@ -110,14 +104,14 @@ void ActivateChecker::delay_to_satisfy_activateToActivate_sameBank( command.getBank()); if (lastActivateOnBank.isValidCommand()) { command.establishMinDistanceFromStart(lastActivateOnBank.getStart(), - config.memSpec.tRC); + config.memSpec->tRC); } ScheduledCommand lastActBOnBank = state.getLastCommand(Command::ActB, command.getBank()); if (lastActBOnBank.isValidCommand()) { command.establishMinDistanceFromStart(lastActivateOnBank.getStart(), - config.memSpec.tRC); + config.memSpec->tRC); } } @@ -127,7 +121,7 @@ bool ActivateChecker::satsfies_activateToActivate_differentBank( for (auto act : state.lastActivates) { sc_time time = act.first; sc_time tRRD = (command.getBankGroup() == act.second.getBankGroup()) ? - config.memSpec.tRRD_L : config.memSpec.tRRD_S; + config.memSpec->tRRD_L : config.memSpec->tRRD_S; if ((time < command.getStart() && command.getStart() - time < tRRD) || (command.getStart() <= time && time - command.getStart() < tRRD)) @@ -143,15 +137,15 @@ bool ActivateChecker::satisfies_nActivateWindow(ScheduledCommand &command) const * command in a copied set (not necessarily the last in time), * and check if the n-act constraint holds for the whole set. */ - if (state.lastActivates.size() >= config.memSpec.nActivate) { + if (state.lastActivates.size() >= config.memSpec->nActivate) { map lastActivates = state.lastActivates; lastActivates.emplace(command.getStart(), command); auto upper = lastActivates.begin(); - advance(upper, config.memSpec.nActivate); + advance(upper, config.memSpec->nActivate); auto lower = lastActivates.begin(); while (upper != lastActivates.end()) { - if (upper->first - lower->first < config.memSpec.tNAW) + if (upper->first - lower->first < config.memSpec->tNAW) return false; ++upper; ++lower; diff --git a/DRAMSys/library/src/controller/core/scheduling/checker/ActivateChecker.h b/DRAMSys/library/src/controller/core/scheduling/checker/ActivateChecker.h index ed62f98d..1312505d 100644 --- a/DRAMSys/library/src/controller/core/scheduling/checker/ActivateChecker.h +++ b/DRAMSys/library/src/controller/core/scheduling/checker/ActivateChecker.h @@ -34,8 +34,8 @@ * Matthias Jung */ -#ifndef ACTIVATESCHEDULER_H_ -#define ACTIVATESCHEDULER_H_ +#ifndef ACTIVATECHECKER_H +#define ACTIVATECHECKER_H #include #include "ICommandChecker.h" @@ -61,4 +61,4 @@ private: bool satisfies_nActivateWindow(ScheduledCommand &command) const; }; -#endif /* ACTIVATESCHEDULER_H_ */ +#endif // ACTIVATECHECKER_H diff --git a/DRAMSys/library/src/controller/core/scheduling/checker/ICommandChecker.h b/DRAMSys/library/src/controller/core/scheduling/checker/ICommandChecker.h index 833077cb..3f38f93b 100644 --- a/DRAMSys/library/src/controller/core/scheduling/checker/ICommandChecker.h +++ b/DRAMSys/library/src/controller/core/scheduling/checker/ICommandChecker.h @@ -34,8 +34,8 @@ * Matthias Jung */ -#ifndef ICOMMANDSCHEDULER_H_ -#define ICOMMANDSCHEDULER_H_ +#ifndef ICOMMANDCHECKER_H +#define ICOMMANDCHECKER_H #include #include "../ScheduledCommand.h" @@ -50,4 +50,4 @@ public: -#endif /* ICOMMANDSCHEDULER_H_ */ +#endif // ICOMMANDCHECKER_H diff --git a/DRAMSys/library/src/controller/core/scheduling/checker/PowerDownChecker.cpp b/DRAMSys/library/src/controller/core/scheduling/checker/PowerDownChecker.cpp index 6e066b61..723c74ec 100644 --- a/DRAMSys/library/src/controller/core/scheduling/checker/PowerDownChecker.cpp +++ b/DRAMSys/library/src/controller/core/scheduling/checker/PowerDownChecker.cpp @@ -36,7 +36,7 @@ */ #include "PowerDownChecker.h" -#include "../../TimingCalculation.h" +#include "../../timingCalculations.h" sc_time PowerDownChecker::getTimeConstraintToEnterPowerDown(Command lastCmd, Command pdnCmd) const @@ -47,26 +47,26 @@ sc_time PowerDownChecker::getTimeConstraintToEnterPowerDown(Command lastCmd, sc_time constraint; if (lastCmd == Command::Read || lastCmd == Command::ReadA) { - constraint = config.memSpec.tRL + getReadAccessTime() + config.memSpec.clk; + constraint = config.memSpec->tRL + getReadAccessTime() + config.memSpec->clk; } else if (lastCmd == Command::Write) { - constraint = config.memSpec.tWL + getWriteAccessTime() + config.memSpec.tWR; + constraint = config.memSpec->tWL + getWriteAccessTime() + config.memSpec->tWR; } else if (lastCmd == Command::WriteA) { - constraint = config.memSpec.tWL + getWriteAccessTime() + config.memSpec.tWR + - config.memSpec.clk; + constraint = config.memSpec->tWL + getWriteAccessTime() + config.memSpec->tWR + + config.memSpec->clk; } else if (lastCmd == Command::AutoRefresh) { auto m = Configuration::getInstance().getRefMode(); if (m == 4) - constraint = config.memSpec.tRFC4; + constraint = config.memSpec->tRFC4; else if (m == 2) - constraint = config.memSpec.tRFC2; + constraint = config.memSpec->tRFC2; else - constraint = config.memSpec.tRFC; + constraint = config.memSpec->tRFC; } else if (lastCmd == Command::PDNPX || lastCmd == Command::PDNAX) { - constraint = config.memSpec.tXP; + constraint = config.memSpec->tXP; } else if (lastCmd == Command::SREFX) { - constraint = config.memSpec.tXSR; + constraint = config.memSpec->tXSR; } else if (lastCmd == Command::Precharge || lastCmd == Command::PrechargeAll) { - constraint = config.memSpec.tRP; + constraint = config.memSpec->tRP; } else { reportFatal("Powerdown checker", commandToString(pdnCmd) + " can not follow " + commandToString(lastCmd)); @@ -93,33 +93,41 @@ const // PDNP - Precharge Power Down // SREF - Self Refresh - // Get the last scheduled command on this bank - ScheduledCommand lastSchedCmdOnBank = state.getLastScheduledCommand(bank); + // Get the last scheduled command + ScheduledCommand lastSchedCmd; + if(Configuration::getInstance().BankwiseLogic) + { + lastSchedCmd = state.getLastScheduledCommand(bank); + } + else + { + lastSchedCmd = state.getLastScheduledCommand(); + } - if (lastSchedCmdOnBank.isValidCommand()) { - // Get the start time for the last scheduled command on this bank - sc_time lastSchedCmdOnBankStart = lastSchedCmdOnBank.getStart(); - // Get the last command on this bank itself - Command lastCmdBank = lastSchedCmdOnBank.getCommand(); + if (lastSchedCmd.isValidCommand()) { + // Get the start time for the last scheduled command + sc_time lastSchedCmdStart = lastSchedCmd.getStart(); + // Get the last command + Command lastCmd = lastSchedCmd.getCommand(); - timeConstraint = getTimeConstraintToEnterPowerDown(lastCmdBank, pdnCmd); + timeConstraint = getTimeConstraintToEnterPowerDown(lastCmd, pdnCmd); - command.establishMinDistanceFromStart(lastSchedCmdOnBankStart, timeConstraint); + command.establishMinDistanceFromStart(lastSchedCmdStart, timeConstraint); } } else if (pdnCmd == Command::PDNAX) { // Leaving Active Power Down - timeConstraint = config.memSpec.tCKE; + timeConstraint = config.memSpec->tCKE; command.establishMinDistanceFromStart(state.getLastCommand(Command::PDNA, bank).getStart(), timeConstraint); } else if (pdnCmd == Command::PDNPX) { // Leaving Precharge Power Down - timeConstraint = config.memSpec.tCKE; + timeConstraint = config.memSpec->tCKE; command.establishMinDistanceFromStart(state.getLastCommand(Command::PDNP, bank).getStart(), timeConstraint); } else if (pdnCmd == Command::SREFX) { // Leaving Self Refresh - timeConstraint = config.memSpec.tCKESR; + timeConstraint = config.memSpec->tCKESR; command.establishMinDistanceFromStart(state.getLastCommand(Command::SREF, bank).getStart(), timeConstraint); } diff --git a/DRAMSys/library/src/controller/core/scheduling/checker/PowerDownChecker.h b/DRAMSys/library/src/controller/core/scheduling/checker/PowerDownChecker.h index df7a2a9a..a1b5f53d 100644 --- a/DRAMSys/library/src/controller/core/scheduling/checker/PowerDownChecker.h +++ b/DRAMSys/library/src/controller/core/scheduling/checker/PowerDownChecker.h @@ -34,8 +34,8 @@ * Matthias Jung */ -#ifndef POWERDOWNCHECKER_H_ -#define POWERDOWNCHECKER_H_ +#ifndef POWERDOWNCHECKER_H +#define POWERDOWNCHECKER_H #include @@ -60,5 +60,5 @@ private: Command pdnCmd) const; }; -#endif /* POWERDOWNCHECKER_H_ */ +#endif // POWERDOWNCHECKER_H diff --git a/DRAMSys/library/src/controller/core/scheduling/checker/PreBChecker.cpp b/DRAMSys/library/src/controller/core/scheduling/checker/PreBChecker.cpp index a8376a28..44e23882 100644 --- a/DRAMSys/library/src/controller/core/scheduling/checker/PreBChecker.cpp +++ b/DRAMSys/library/src/controller/core/scheduling/checker/PreBChecker.cpp @@ -33,8 +33,8 @@ */ #include "PreBChecker.h" -#include "../../TimingCalculation.h" -void PreBChecker::delayToSatisfyConstraints(ScheduledCommand &cmd)const +#include "../../timingCalculations.h" +void PreBChecker::delayToSatisfyConstraints(ScheduledCommand &cmd) const { sc_assert(cmd.getCommand() == Command::PreB); ScheduledCommand lastCmd = state.getLastScheduledCommand(cmd.getBank()); @@ -43,21 +43,21 @@ void PreBChecker::delayToSatisfyConstraints(ScheduledCommand &cmd)const cmd.establishMinDistanceFromStart(lastCmd.getStart(), Configuration::getInstance().getTrpb()); } else if (lastCmd.getCommand() == Command::Precharge) { - cmd.establishMinDistanceFromStart(lastCmd.getStart(), config.memSpec.tRP); + cmd.establishMinDistanceFromStart(lastCmd.getStart(), config.memSpec->tRP); } else if (lastCmd.getCommand() == Command::PrechargeAll) { - cmd.establishMinDistanceFromStart(lastCmd.getStart(), config.memSpec.tRP); + cmd.establishMinDistanceFromStart(lastCmd.getStart(), config.memSpec->tRP); } else if (lastCmd.getCommand() == Command::ActB) { cmd.establishMinDistanceFromStart(lastCmd.getStart(), - config.memSpec.tRCD); // XXX: trcd is less than the NEW! trasb! ok! + config.memSpec->tRCD); // XXX: trcd is less than the NEW! trasb! ok! } else if (lastCmd.getCommand() == Command::Activate) { - cmd.establishMinDistanceFromStart(lastCmd.getStart(), config.memSpec.tRCD); + cmd.establishMinDistanceFromStart(lastCmd.getStart(), config.memSpec->tRCD); } else if (lastCmd.getCommand() == Command::Read) { - cmd.establishMinDistanceFromStart(lastCmd.getStart(), config.memSpec.tRTP); + cmd.establishMinDistanceFromStart(lastCmd.getStart(), config.memSpec->tRTP); } else if (lastCmd.getCommand() == Command::Write) { cmd.establishMinDistanceFromStart(lastCmd.getStart(), - config.memSpec.tWL + getWriteAccessTime() + config.memSpec.tWR); + config.memSpec->tWL + getWriteAccessTime() + config.memSpec->tWR); } else if (lastCmd.getCommand() == Command::PDNAX) { - cmd.establishMinDistanceFromStart(lastCmd.getStart(), config.memSpec.tXP); + cmd.establishMinDistanceFromStart(lastCmd.getStart(), config.memSpec->tXP); } else { reportFatal("PreB Checker", "PreB can not follow " + commandToString(lastCmd.getCommand())); @@ -65,11 +65,11 @@ void PreBChecker::delayToSatisfyConstraints(ScheduledCommand &cmd)const } ScheduledCommand lc; if ((lc = state.getLastCommand(Command::PrechargeAll)).isValidCommand()) { - cmd.establishMinDistanceFromStart(lc.getStart(), config.memSpec.tRP); + cmd.establishMinDistanceFromStart(lc.getStart(), config.memSpec->tRP); } if ((lc = state.getLastCommand(Command::Activate, cmd.getBank())).isValidCommand()) { - cmd.establishMinDistanceFromStart(lc.getStart(), config.memSpec.tRAS); + cmd.establishMinDistanceFromStart(lc.getStart(), config.memSpec->tRAS); } if ((lc = state.getLastCommand(Command::ActB, cmd.getBank())).isValidCommand()) { diff --git a/DRAMSys/library/src/controller/core/scheduling/checker/PreBChecker.h b/DRAMSys/library/src/controller/core/scheduling/checker/PreBChecker.h index f37241d9..980901a3 100644 --- a/DRAMSys/library/src/controller/core/scheduling/checker/PreBChecker.h +++ b/DRAMSys/library/src/controller/core/scheduling/checker/PreBChecker.h @@ -31,11 +31,14 @@ * * Author: Éder F. Zulian */ -#ifndef PREB_CHECKER_H_ -#define PREB_CHECKER_H_ + +#ifndef PREBCHECKER_H +#define PREBCHECKER_H + #include "ICommandChecker.h" #include "../../configuration/Configuration.h" #include "../../../ControllerState.h" + class PreBChecker: public ICommandChecker { public: @@ -48,4 +51,5 @@ private: const Configuration &config; ControllerState &state; }; -#endif /* PREB_CHECKER_H_ */ + +#endif // PREBCHECKER_H diff --git a/DRAMSys/library/src/controller/core/scheduling/checker/PrechargeAllChecker.cpp b/DRAMSys/library/src/controller/core/scheduling/checker/PrechargeAllChecker.cpp index 31b5732e..f6ee06d9 100644 --- a/DRAMSys/library/src/controller/core/scheduling/checker/PrechargeAllChecker.cpp +++ b/DRAMSys/library/src/controller/core/scheduling/checker/PrechargeAllChecker.cpp @@ -36,7 +36,7 @@ */ #include "PrechargeAllChecker.h" -#include "../../TimingCalculation.h" +#include "../../timingCalculations.h" void PrechargeAllChecker::delayToSatisfyConstraints(ScheduledCommand &command) @@ -45,48 +45,48 @@ const sc_assert(command.getCommand() == Command::PrechargeAll); // Consider all banks for the constraints, since precharge all command is supposed to happen at the same time on all banks - for (unsigned int bank = 0; bank < config.memSpec.NumberOfBanks; ++bank) { + for (unsigned int bank = 0; bank < config.memSpec->NumberOfBanks; ++bank) { ScheduledCommand lastCommand = state.getLastScheduledCommand(Bank(bank)); if (lastCommand.isValidCommand()) { if (lastCommand.getCommand() == Command::Precharge || lastCommand.getCommand() == Command::PreB) { command.establishMinDistanceFromStart(lastCommand.getStart(), - config.memSpec.tRP); + config.memSpec->tRP); } else if (lastCommand.getCommand() == Command::Activate || lastCommand.getCommand() == Command::ActB) { command.establishMinDistanceFromStart(lastCommand.getStart(), - config.memSpec.tRCD); + config.memSpec->tRCD); } else if (lastCommand.getCommand() == Command::Read) { command.establishMinDistanceFromStart(lastCommand.getStart(), - config.memSpec.tRTP); + config.memSpec->tRTP); } else if (lastCommand.getCommand() == Command::ReadA) { command.establishMinDistanceFromStart(lastCommand.getStart(), - config.memSpec.tRTP + config.memSpec.tRP); + config.memSpec->tRTP + config.memSpec->tRP); } else if (lastCommand.getCommand() == Command::Write) { command.establishMinDistanceFromStart(lastCommand.getStart(), - config.memSpec.tWL + getWriteAccessTime() + config.memSpec.tWR); + config.memSpec->tWL + getWriteAccessTime() + config.memSpec->tWR); } else if (lastCommand.getCommand() == Command::WriteA) { command.establishMinDistanceFromStart(lastCommand.getStart(), - config.memSpec.tWL + getWriteAccessTime() + config.memSpec.tWR + - config.memSpec.tRP); + config.memSpec->tWL + getWriteAccessTime() + config.memSpec->tWR + + config.memSpec->tRP); } else if (lastCommand.getCommand() == Command::AutoRefresh) { auto m = Configuration::getInstance().getRefMode(); if (m == 4) command.establishMinDistanceFromStart(lastCommand.getStart(), - config.memSpec.tRFC4); + config.memSpec->tRFC4); else if (m == 2) command.establishMinDistanceFromStart(lastCommand.getStart(), - config.memSpec.tRFC2); + config.memSpec->tRFC2); else command.establishMinDistanceFromStart(lastCommand.getStart(), - config.memSpec.tRFC); + config.memSpec->tRFC); } else if (lastCommand.getCommand() == Command::PDNAX || lastCommand.getCommand() == Command::PDNPX) { command.establishMinDistanceFromStart(lastCommand.getStart(), - config.memSpec.tXP); + config.memSpec->tXP); } else if (lastCommand.getCommand() == Command::SREFX) { command.establishMinDistanceFromStart(lastCommand.getStart(), - config.memSpec.tXSR); + config.memSpec->tXSR); } else reportFatal("Precharge All Checker", "Precharge All can not follow " + commandToString(lastCommand.getCommand())); @@ -97,7 +97,7 @@ const command.getBank()); if (lastActivate.isValidCommand()) { command.establishMinDistanceFromStart(lastActivate.getStart(), - config.memSpec.tRAS); + config.memSpec->tRAS); } state.bus.moveCommandToNextFreeSlot(command); diff --git a/DRAMSys/library/src/controller/core/scheduling/checker/PrechargeAllChecker.h b/DRAMSys/library/src/controller/core/scheduling/checker/PrechargeAllChecker.h index 62e8a0f2..41133b4b 100644 --- a/DRAMSys/library/src/controller/core/scheduling/checker/PrechargeAllChecker.h +++ b/DRAMSys/library/src/controller/core/scheduling/checker/PrechargeAllChecker.h @@ -34,14 +34,13 @@ * Matthias Jung */ -#ifndef PRECHARGEALLCHECKER_H_ -#define PRECHARGEALLCHECKER_H_ +#ifndef PRECHARGEALLCHECKER_H +#define PRECHARGEALLCHECKER_H #include "ICommandChecker.h" #include "../../configuration/Configuration.h" #include "../../../ControllerState.h" - class PrechargeAllChecker: public ICommandChecker { public: @@ -62,4 +61,4 @@ private: }; -#endif /* PRECHARGEALLCHECKER_H_ */ +#endif // PRECHARGEALLCHECKER_H diff --git a/DRAMSys/library/src/controller/core/scheduling/checker/PrechargeChecker.cpp b/DRAMSys/library/src/controller/core/scheduling/checker/PrechargeChecker.cpp index c51fb2b1..75a8ebdc 100644 --- a/DRAMSys/library/src/controller/core/scheduling/checker/PrechargeChecker.cpp +++ b/DRAMSys/library/src/controller/core/scheduling/checker/PrechargeChecker.cpp @@ -35,7 +35,7 @@ */ #include "PrechargeChecker.h" -#include "../../TimingCalculation.h" +#include "../../timingCalculations.h" void PrechargeChecker::delayToSatisfyConstraints(ScheduledCommand &command) @@ -52,23 +52,23 @@ const if (lastCommand.getCommand() == Command::Precharge || lastCommand.getCommand() == Command::PreB) { command.establishMinDistanceFromStart(lastCommand.getStart(), - config.memSpec.tRP); + config.memSpec->tRP); } else if (lastCommand.getCommand() == Command::Activate || lastCommand.getCommand() == Command::ActB) { command.establishMinDistanceFromStart(lastCommand.getStart(), - config.memSpec.tRCD); + config.memSpec->tRCD); } else if (lastCommand.getCommand() == Command::Read) { command.establishMinDistanceFromStart(lastCommand.getStart(), - config.memSpec.tRTP); + config.memSpec->tRTP); } else if (lastCommand.getCommand() == Command::Write) { command.establishMinDistanceFromStart(lastCommand.getStart(), - config.memSpec.tWL + getWriteAccessTime() + config.memSpec.tWR); + config.memSpec->tWL + getWriteAccessTime() + config.memSpec->tWR); } else if (lastCommand.getCommand() == Command::PDNAX) { command.establishMinDistanceFromStart(lastCommand.getStart(), - config.memSpec.tXP); + config.memSpec->tXP); } else reportFatal("Precharge Checker", "Precharge can not follow " + commandToString(lastCommand.getCommand())); @@ -78,7 +78,7 @@ const command.getBank()); if (lastActivate.isValidCommand()) { command.establishMinDistanceFromStart(lastActivate.getStart(), - config.memSpec.tRAS); + config.memSpec->tRAS); } state.bus.moveCommandToNextFreeSlot(command); diff --git a/DRAMSys/library/src/controller/core/scheduling/checker/PrechargeChecker.h b/DRAMSys/library/src/controller/core/scheduling/checker/PrechargeChecker.h index 4977dd55..05b94dc1 100644 --- a/DRAMSys/library/src/controller/core/scheduling/checker/PrechargeChecker.h +++ b/DRAMSys/library/src/controller/core/scheduling/checker/PrechargeChecker.h @@ -34,14 +34,13 @@ * Matthias Jung */ -#ifndef PRECHARGECHECKER_H_ -#define PRECHARGECHECKER_H_ +#ifndef PRECHARGECHECKER_H +#define PRECHARGECHECKER_H #include "ICommandChecker.h" #include "../../configuration/Configuration.h" #include "../../../ControllerState.h" - class PrechargeChecker: public ICommandChecker { public: @@ -57,4 +56,4 @@ private: }; -#endif /* PRECHARGECHECKER_H_ */ +#endif // PRECHARGECHECKER_ diff --git a/DRAMSys/library/src/controller/core/scheduling/checker/ReadChecker.cpp b/DRAMSys/library/src/controller/core/scheduling/checker/ReadChecker.cpp index b5917e42..06a121a6 100644 --- a/DRAMSys/library/src/controller/core/scheduling/checker/ReadChecker.cpp +++ b/DRAMSys/library/src/controller/core/scheduling/checker/ReadChecker.cpp @@ -35,8 +35,8 @@ */ #include "ReadChecker.h" -#include "../../TimingCalculation.h" -#include "../../../../common/Utils.h" +#include "../../timingCalculations.h" +#include "../../../../common/utils.h" #include "WriteChecker.h" using namespace std; @@ -52,7 +52,7 @@ void ReadChecker::delayToSatisfyConstraints(ScheduledCommand &command) const if (lastCommand.getCommand() == Command::Activate || lastCommand.getCommand() == Command::ActB) { command.establishMinDistanceFromStart(lastCommand.getStart(), - config.memSpec.tRCD); + config.memSpec->tRCD); } else if (lastCommand.getCommand() == Command::Read) { command.establishMinDistanceFromStart(lastCommand.getStart(), ReadChecker::readToRead(lastCommand, command)); @@ -62,14 +62,14 @@ void ReadChecker::delayToSatisfyConstraints(ScheduledCommand &command) const } else if (lastCommand.getCommand() == Command::PDNPX || lastCommand.getCommand() == Command::PDNAX) { command.establishMinDistanceFromStart(lastCommand.getStart(), - config.memSpec.tXP); + config.memSpec->tXP); } else reportFatal("Read Checker", "Read can not follow " + commandToString(lastCommand.getCommand())); } while (!state.bus.isFree(command.getStart()) || collidesOnDataStrobe(command)) { - command.delayStart(config.memSpec.clk); + command.delayStart(config.memSpec->clk); } } @@ -112,7 +112,7 @@ void ReadChecker::delayToSatisfyDLL(ScheduledCommand &read) const read.getBank()); if (lastSREFX.isValidCommand()) read.establishMinDistanceFromStart(lastSREFX.getStart(), - config.memSpec.tXSRDLL); + config.memSpec->tXSRDLL); } sc_time ReadChecker::readToRead(ScheduledCommand &firstRead, @@ -123,9 +123,9 @@ sc_time ReadChecker::readToRead(ScheduledCommand &firstRead, sc_assert(secondRead.getCommand() == Command::Read || secondRead.getCommand() == Command::ReadA); - MemSpec &config = Configuration::getInstance().memSpec; + MemSpec *config = Configuration::getInstance().memSpec; sc_time tCCD = (firstRead.getBankGroup() == secondRead.getBankGroup()) ? - config.tCCD_L : config.tCCD_S; + config->tCCD_L : config->tCCD_S; return max(tCCD, getReadAccessTime()); } @@ -137,9 +137,9 @@ sc_time ReadChecker::writeToRead(ScheduledCommand &write, sc_assert(write.getCommand() == Command::Write || write.getCommand() == Command::WriteA); - MemSpec &config = Configuration::getInstance().memSpec; - sc_time tWTR = (write.getBankGroup() == read.getBankGroup()) ? config.tWTR_L : - config.tWTR_S; - return config.tWL + getWriteAccessTime() + tWTR; + MemSpec *config = Configuration::getInstance().memSpec; + sc_time tWTR = (write.getBankGroup() == read.getBankGroup()) ? config->tWTR_L : + config->tWTR_S; + return config->tWL + getWriteAccessTime() + tWTR; } diff --git a/DRAMSys/library/src/controller/core/scheduling/checker/ReadChecker.h b/DRAMSys/library/src/controller/core/scheduling/checker/ReadChecker.h index 1fd31f2b..d9c9cce8 100644 --- a/DRAMSys/library/src/controller/core/scheduling/checker/ReadChecker.h +++ b/DRAMSys/library/src/controller/core/scheduling/checker/ReadChecker.h @@ -34,8 +34,8 @@ * Matthias Jung */ -#ifndef READCHECKER_H_ -#define READCHECKER_H_ +#ifndef READCHECKER_H +#define READCHECKER_H #include "ICommandChecker.h" #include "../../configuration/Configuration.h" @@ -65,5 +65,5 @@ private: ScheduledCommand &strobeCommand) const; }; -#endif /* READCHECKER_H_ */ +#endif // READCHECKER_H diff --git a/DRAMSys/library/src/controller/core/scheduling/checker/RefreshChecker.cpp b/DRAMSys/library/src/controller/core/scheduling/checker/RefreshChecker.cpp index f7d110f0..eea8f763 100644 --- a/DRAMSys/library/src/controller/core/scheduling/checker/RefreshChecker.cpp +++ b/DRAMSys/library/src/controller/core/scheduling/checker/RefreshChecker.cpp @@ -36,7 +36,7 @@ */ #include "RefreshChecker.h" -#include "../../TimingCalculation.h" +#include "../../timingCalculations.h" void RefreshChecker::delayToSatisfyConstraints(ScheduledCommand &command) const { @@ -50,53 +50,53 @@ void RefreshChecker::delayToSatisfyConstraints(ScheduledCommand &command) const if (lastCommandOnBank.getCommand() == Command::Precharge || lastCommandOnBank.getCommand() == Command::PrechargeAll) { command.establishMinDistanceFromStart(lastCommandOnBank.getStart(), - config.memSpec.tRP); + config.memSpec->tRP); } else if (lastCommandOnBank.getCommand() == Command::ReadA) { command.establishMinDistanceFromStart(lastCommandOnBank.getStart(), - config.memSpec.tRTP + config.memSpec.tRP); + config.memSpec->tRTP + config.memSpec->tRP); } else if (lastCommandOnBank.getCommand() == Command::WriteA) { command.establishMinDistanceFromStart(lastCommandOnBank.getStart(), - config.memSpec.tWL + getWriteAccessTime() + config.memSpec.tWR + - config.memSpec.tRP); + config.memSpec->tWL + getWriteAccessTime() + config.memSpec->tWR + + config.memSpec->tRP); } else if (lastCommandOnBank.getCommand() == Command::PDNPX || lastCommandOnBank.getCommand() == Command::PDNAX) { command.establishMinDistanceFromStart(lastCommandOnBank.getStart(), - config.memSpec.tXP); + config.memSpec->tXP); } else if (lastCommandOnBank.getCommand() == Command::SREFX) { command.establishMinDistanceFromStart(lastCommandOnBank.getStart(), - config.memSpec.tXSR); + config.memSpec->tXSR); } else if (lastCommandOnBank.getCommand() == Command::AutoRefresh) { } else reportFatal("Refresh Checker", "Refresh can not follow " + commandToString(lastCommandOnBank.getCommand())); } } else { - for (unsigned int bank = 0; bank < config.memSpec.NumberOfBanks; ++bank) { + for (unsigned int bank = 0; bank < config.memSpec->NumberOfBanks; ++bank) { ScheduledCommand lastCommand = state.getLastScheduledCommand(Bank(bank)); if (lastCommand.isValidCommand()) { if (lastCommand.getCommand() == Command::Precharge || lastCommand.getCommand() == Command::PrechargeAll || lastCommand.getCommand() == Command::PreB) { command.establishMinDistanceFromStart(lastCommand.getStart(), - config.memSpec.tRP); + config.memSpec->tRP); } else if (lastCommand.getCommand() == Command::Activate || lastCommand.getCommand() == Command::ActB) { command.establishMinDistanceFromStart(lastCommand.getStart(), - config.memSpec.tRCD); + config.memSpec->tRCD); } else if (lastCommand.getCommand() == Command::ReadA) { command.establishMinDistanceFromStart(lastCommand.getStart(), - config.memSpec.tRTP + config.memSpec.tRP); + config.memSpec->tRTP + config.memSpec->tRP); } else if (lastCommand.getCommand() == Command::WriteA) { command.establishMinDistanceFromStart(lastCommand.getStart(), - config.memSpec.tWL + getWriteAccessTime() + config.memSpec.tWR + - config.memSpec.tRP); + config.memSpec->tWL + getWriteAccessTime() + config.memSpec->tWR + + config.memSpec->tRP); } else if (lastCommand.getCommand() == Command::PDNAX || lastCommand.getCommand() == Command::PDNPX) { command.establishMinDistanceFromStart(lastCommand.getStart(), - config.memSpec.tXP); + config.memSpec->tXP); } else if (lastCommand.getCommand() == Command::SREFX) { command.establishMinDistanceFromStart(lastCommand.getStart(), - config.memSpec.tXSR); + config.memSpec->tXSR); } else if (lastCommand.getCommand() == Command::AutoRefresh) { } else reportFatal("Refresh Checker", diff --git a/DRAMSys/library/src/controller/core/scheduling/checker/RefreshChecker.h b/DRAMSys/library/src/controller/core/scheduling/checker/RefreshChecker.h index 1dd8655d..ae7a4c9e 100644 --- a/DRAMSys/library/src/controller/core/scheduling/checker/RefreshChecker.h +++ b/DRAMSys/library/src/controller/core/scheduling/checker/RefreshChecker.h @@ -34,16 +34,15 @@ * Matthias Jung */ -#ifndef REFRESHCHECKER_H_ -#define REFRESHCHECKER_H_ +#ifndef REFRESHCHECKER_H +#define REFRESHCHECKER_H #include "ICommandChecker.h" #include "../../../ControllerState.h" #include "../../configuration/Configuration.h" #include - -class RefreshChecker: public ICommandChecker +class RefreshChecker : public ICommandChecker { public: RefreshChecker(const Configuration &config, ControllerState &state) : @@ -64,4 +63,4 @@ private: }; -#endif /* REFRESHCHECKER_H_ */ +#endif // REFRESHCHECKER_H diff --git a/DRAMSys/library/src/controller/core/scheduling/checker/WriteChecker.cpp b/DRAMSys/library/src/controller/core/scheduling/checker/WriteChecker.cpp index 226d24aa..38eafdaa 100644 --- a/DRAMSys/library/src/controller/core/scheduling/checker/WriteChecker.cpp +++ b/DRAMSys/library/src/controller/core/scheduling/checker/WriteChecker.cpp @@ -35,8 +35,8 @@ */ #include "WriteChecker.h" -#include "../../TimingCalculation.h" -#include "../../../../common/Utils.h" +#include "../../timingCalculations.h" +#include "../../../../common/utils.h" #include "ReadChecker.h" using namespace std; @@ -52,7 +52,7 @@ void WriteChecker::delayToSatisfyConstraints(ScheduledCommand &command) const if (lastCommand.getCommand() == Command::Activate || lastCommand.getCommand() == Command::ActB) { command.establishMinDistanceFromStart(lastCommand.getStart(), - config.memSpec.tRCD); + config.memSpec->tRCD); } else if (lastCommand.getCommand() == Command::Read) { command.establishMinDistanceFromStart(lastCommand.getStart(), WriteChecker::readToWrite(lastCommand, command)); @@ -62,14 +62,14 @@ void WriteChecker::delayToSatisfyConstraints(ScheduledCommand &command) const } else if (lastCommand.getCommand() == Command::PDNPX || lastCommand.getCommand() == Command::PDNAX) { command.establishMinDistanceFromStart(lastCommand.getStart(), - config.memSpec.tXP); + config.memSpec->tXP); } else reportFatal("Write Checker", "Write can not follow " + commandToString(lastCommand.getCommand())); } while (!state.bus.isFree(command.getStart()) || collidesOnDataStrobe(command)) { - command.delayStart(config.memSpec.clk); + command.delayStart(config.memSpec->clk); } } @@ -114,9 +114,9 @@ sc_time WriteChecker::writeToWrite(ScheduledCommand &firstWrite, sc_assert(secondWrite.getCommand() == Command::Write || secondWrite.getCommand() == Command::WriteA); - MemSpec &config = Configuration::getInstance().memSpec; + MemSpec *config = Configuration::getInstance().memSpec; sc_time tCCD = (firstWrite.getBankGroup() == secondWrite.getBankGroup()) ? - config.tCCD_L : config.tCCD_S; + config->tCCD_L : config->tCCD_S; return max(tCCD, getWriteAccessTime()); } @@ -128,7 +128,7 @@ sc_time WriteChecker::readToWrite(ScheduledCommand &read __attribute__(( sc_assert(write.getCommand() == Command::Write || write.getCommand() == Command::WriteA); - MemSpec &config = Configuration::getInstance().memSpec; - return config.tRL + getReadAccessTime() - config.tWL + config.clk * 2; + MemSpec *config = Configuration::getInstance().memSpec; + return config->tRL + getReadAccessTime() - config->tWL + config->clk * 2; } diff --git a/DRAMSys/library/src/controller/core/scheduling/checker/WriteChecker.h b/DRAMSys/library/src/controller/core/scheduling/checker/WriteChecker.h index 5b8c46f8..4bddeb69 100644 --- a/DRAMSys/library/src/controller/core/scheduling/checker/WriteChecker.h +++ b/DRAMSys/library/src/controller/core/scheduling/checker/WriteChecker.h @@ -34,15 +34,14 @@ * Matthias Jung */ -#ifndef WRITECHECKER_H_ -#define WRITECHECKER_H_ +#ifndef WRITECHECKER_H +#define WRITECHECKER_H #include "ICommandChecker.h" #include "../../configuration/Configuration.h" #include "../../../ControllerState.h" - -class WriteChecker: public ICommandChecker +class WriteChecker : public ICommandChecker { public: WriteChecker(const Configuration &config, @@ -64,4 +63,4 @@ private: }; -#endif /* WRITECHECKER_H_ */ +#endif // WRITECHECKER_H diff --git a/DRAMSys/library/src/controller/core/TimingCalculation.cpp b/DRAMSys/library/src/controller/core/timingCalculations.cpp similarity index 78% rename from DRAMSys/library/src/controller/core/TimingCalculation.cpp rename to DRAMSys/library/src/controller/core/timingCalculations.cpp index 224fd7b1..077e5d22 100644 --- a/DRAMSys/library/src/controller/core/TimingCalculation.cpp +++ b/DRAMSys/library/src/controller/core/timingCalculations.cpp @@ -34,12 +34,12 @@ * Matthias Jung */ -#include "TimingCalculation.h" +#include "timingCalculations.h" #include "configuration/MemSpec.h" #include "ControllerCore.h" #include "../../common/DebugManager.h" #include "configuration/Configuration.h" -#include "../../common/Utils.h" +#include "../../common/utils.h" @@ -59,7 +59,7 @@ const sc_time FrequencyToClk(double frequencyMhz) const sc_time clkAlign(sc_time time, Alignment alignment) { - sc_time clk = Configuration::getInstance().memSpec.clk; + sc_time clk = Configuration::getInstance().memSpec->clk; if (alignment == UP) return ceil(time / clk) * clk; else @@ -69,39 +69,39 @@ const sc_time clkAlign(sc_time time, Alignment alignment) // Returns the execution time for commands that have a fixed execution time sc_time getExecutionTime(Command command, tlm::tlm_generic_payload &payload) { - MemSpec &config = Configuration::getInstance().memSpec; + MemSpec *config = Configuration::getInstance().memSpec; if (command == Command::PreB) { return Configuration::getInstance().getTrpb(); } else if (command == Command::Precharge || command == Command::PrechargeAll) { - return config.tRP; + return config->tRP; } else if (command == Command::ActB) { - return config.tRCD; + return config->tRCD; } else if (command == Command::Activate) { - return config.tRCD; + return config->tRCD; } else if (command == Command::Read) { - return config.tRL + getReadAccessTime(); + return config->tRL + getReadAccessTime(); } else if (command == Command::ReadA) { - return config.tRTP + config.tRP; + return config->tRTP + config->tRP; } else if (command == Command::Write) { - return config.tWL + getWriteAccessTime(); + return config->tWL + getWriteAccessTime(); } else if (command == Command::WriteA) { - return config.tWL + getWriteAccessTime() + config.tWR + config.tRP; + return config->tWL + getWriteAccessTime() + config->tWR + config->tRP; } else if (command == Command::PrechargeAll) { - return config.tRP; + return config->tRP; } else if (command == Command::AutoRefresh) { if (Configuration::getInstance().getRefMode() == 4) - return getElementFromMap(config.refreshTimings, + return getElementFromMap(config->refreshTimings, DramExtension::getExtension(payload).getBank()).tRFC4; else if (Configuration::getInstance().getRefMode() == 2) - return getElementFromMap(config.refreshTimings, + return getElementFromMap(config->refreshTimings, DramExtension::getExtension(payload).getBank()).tRFC2; else - return getElementFromMap(config.refreshTimings, + return getElementFromMap(config->refreshTimings, DramExtension::getExtension(payload).getBank()).tRFC; } else if (command == Command::PDNAX || command == Command::PDNPX || command == Command::SREFX) { - return config.clk; + return config->clk; } else { SC_REPORT_FATAL("getExecutionTime", "command not known or command doesn't have a fixed execution time"); @@ -112,11 +112,11 @@ sc_time getExecutionTime(Command command, tlm::tlm_generic_payload &payload) // Returns the minimum execution time for commands that have a variable execution time sc_time getMinExecutionTimeForPowerDownCmd(Command command) { - MemSpec &config = Configuration::getInstance().memSpec; + MemSpec *config = Configuration::getInstance().memSpec; if (command == Command::PDNA || command == Command::PDNP) { - return config.tCKE; + return config->tCKE; } else if (command == Command::SREF) { - return config.tCKESR; + return config->tCKESR; } else { SC_REPORT_FATAL("getMinimalExecutionTime", "command is not know or command has a fixed execution time"); @@ -133,19 +133,19 @@ bool isClkAligned(sc_time time, sc_time clk) sc_time getReadAccessTime() { Configuration &config = Configuration::getInstance(); - return (config.memSpec.BurstLength / config.memSpec.DataRate) * - config.memSpec.clk; + return (config.memSpec->BurstLength / config.memSpec->DataRate) * + config.memSpec->clk; } sc_time getWriteAccessTime() { Configuration &config = Configuration::getInstance(); - if (config.memSpec.DataRate == 1) { - return config.memSpec.clk * (config.memSpec.BurstLength); + if (config.memSpec->DataRate == 1) { + return config.memSpec->clk * (config.memSpec->BurstLength); } else { - return config.memSpec.clk * (config.memSpec.BurstLength / - config.memSpec.DataRate); + return config.memSpec->clk * (config.memSpec->BurstLength / + config.memSpec->DataRate); } } diff --git a/DRAMSys/library/src/controller/core/TimingCalculation.h b/DRAMSys/library/src/controller/core/timingCalculations.h similarity index 94% rename from DRAMSys/library/src/controller/core/TimingCalculation.h rename to DRAMSys/library/src/controller/core/timingCalculations.h index 03fa1918..e9f80d4e 100644 --- a/DRAMSys/library/src/controller/core/TimingCalculation.h +++ b/DRAMSys/library/src/controller/core/timingCalculations.h @@ -34,15 +34,14 @@ * Matthias Jung */ -#ifndef UTILS_H_ -#define UTILS_H_ +#ifndef TIMINGCALCULATIONS_H +#define TIMINGCALCULATIONS_H #include #include -#include "../../common/dramExtension.h" +#include "../../common/dramExtensions.h" #include "../Command.h" - sc_time getMinExecutionTimeForPowerDownCmd(Command command); sc_time getExecutionTime(Command command, tlm::tlm_generic_payload &payload); @@ -56,4 +55,4 @@ const sc_time clkAlign(sc_time time, Alignment alignment = UP); bool isClkAligned(sc_time time, sc_time clk); const sc_time FrequencyToClk(double frequencyMhz); -#endif /* UTILS_H_ */ +#endif // TIMINGCALCULATIONS_H diff --git a/DRAMSys/library/src/controller/scheduler/Fifo.cpp b/DRAMSys/library/src/controller/scheduler/Fifo.cpp index 6eb46aa8..cc2ddb11 100644 --- a/DRAMSys/library/src/controller/scheduler/Fifo.cpp +++ b/DRAMSys/library/src/controller/scheduler/Fifo.cpp @@ -36,27 +36,30 @@ #include "Fifo.h" -using namespace std; - void Fifo::storeRequest(gp *payload) { - buffer[DramExtension::getExtension(payload).getBank()].emplace_back(payload); + Bank bank = DramExtension::getExtension(payload).getBank(); + buffer[bank].emplace_back(payload); } -pair Fifo::getNextRequest(Bank bank) +std::pair Fifo::getNextRequest(Bank bank) { - if (!buffer[bank].empty()) { + if (!buffer[bank].empty()) + { gp *payload = buffer[bank].front(); - Command command = IScheduler::getNextCommand(*payload); + Command command = IScheduler::getNextCommand(payload); if (command == Command::Read || command == Command::ReadA - || command == Command::Write || command == Command::WriteA) { + || command == Command::Write || command == Command::WriteA) + { buffer[bank].pop_front(); } - return pair(command, payload); + return std::pair(command, payload); + } + else + { + return std::pair(Command::NOP, NULL); } - - return pair(Command::NOP, NULL); } gp *Fifo::getPendingRequest(Bank /*bank*/) diff --git a/DRAMSys/library/src/controller/scheduler/Fifo.h b/DRAMSys/library/src/controller/scheduler/Fifo.h index 912570d2..83f14124 100644 --- a/DRAMSys/library/src/controller/scheduler/Fifo.h +++ b/DRAMSys/library/src/controller/scheduler/Fifo.h @@ -34,15 +34,16 @@ * Matthias Jung */ -#ifndef FIFO_H_ -#define FIFO_H_ +#ifndef FIFO_H +#define FIFO_H + +#include +#include +#include #include "../core/ControllerCore.h" #include "../Command.h" #include "IScheduler.h" -#include -#include -#include class Fifo : public IScheduler { @@ -51,12 +52,12 @@ public: virtual ~Fifo() {} void storeRequest(gp *payload) override; - std::pair getNextRequest( - Bank bank) override; + std::pair + getNextRequest(Bank bank) override; virtual gp *getPendingRequest(Bank bank) override; private: std::map> buffer; }; -#endif /* FIFO_H_ */ +#endif // FIFO_H diff --git a/DRAMSys/library/src/controller/scheduler/FifoStrict.cpp b/DRAMSys/library/src/controller/scheduler/FifoStrict.cpp index 9b3f8ec3..4b890433 100644 --- a/DRAMSys/library/src/controller/scheduler/FifoStrict.cpp +++ b/DRAMSys/library/src/controller/scheduler/FifoStrict.cpp @@ -61,21 +61,21 @@ std::pair FifoStrict::getNextRequest( // enqueued request until the appropriate sequence of commands is // sent to the DRAM. // - // Every time getNextRequest() it is called it calls + // Every time getNextRequest() is called it calls // getNextCommand() that returns the suitable command to be sent // to the DRAM. // // getNextCommand() returns the proper command based on the // internal status of the DRAM. // - // In the worst case getNextCommand() need to be called three + // In the worst case getNextCommand() needs to be called three // times for a given element in the requests queue: first for // precharge, second for activate and finally for read or write // (accordingly the nature of the request). In contrast, for the // case of an already open row (due to a previous request) the // command itself could be directly issued. // - Command command = IScheduler::getNextCommand(*payload); + Command command = IScheduler::getNextCommand(payload); if (commandIsIn(command, {Command::Read, Command::Write, Command::ReadA, Command::WriteA})) { buffer.pop_front(); @@ -84,7 +84,7 @@ std::pair FifoStrict::getNextRequest( if (!buffer.empty()) { tlm::tlm_generic_payload *p = buffer.front().second; - Command cmd = IScheduler::getNextCommand(*p); + Command cmd = IScheduler::getNextCommand(p); if (commandIsIn(cmd, {Command::Read, Command::Write, Command::ReadA, Command::WriteA})) { Bank b = DramExtension::getBank(p); controller.blockedRequests.push(b); @@ -92,7 +92,7 @@ std::pair FifoStrict::getNextRequest( } } - return pair(command, payload); + return std::pair(command, payload); } else { // The next request in the FIFO is NOT for the bank passed as parameter. @@ -110,24 +110,24 @@ std::pair FifoStrict::getNextRequest( // Reads and writes will not be issued since this // scheduler executes all read and writes in a strict // order. - Command command = getNextCommand(*payload); + Command command = getNextCommand(payload); if (commandIsIn(command, {Command::Read, Command::Write, Command::ReadA, Command::WriteA})) { // Reads and writes must be executed in order. Then if // the next command for this request is read or write // NOP will be returned and no operation will be // performed. - return pair(Command::NOP, NULL); + return std::pair(Command::NOP, NULL); } else { // Commands other than read and write are issued normally. - return pair(command, payload); + return std::pair(command, payload); } } } } } - return pair(Command::NOP, NULL); + return std::pair(Command::NOP, NULL); } gp *FifoStrict::getPendingRequest(Bank /*bank*/) diff --git a/DRAMSys/library/src/controller/scheduler/FifoStrict.h b/DRAMSys/library/src/controller/scheduler/FifoStrict.h index acd22086..5404cb8c 100644 --- a/DRAMSys/library/src/controller/scheduler/FifoStrict.h +++ b/DRAMSys/library/src/controller/scheduler/FifoStrict.h @@ -40,7 +40,7 @@ #define FIFOSTRICT_H #include -#include +//#include #include #include "../core/ControllerCore.h" @@ -51,19 +51,19 @@ class FifoStrict : public IScheduler { public: IController &controller; - FifoStrict(IController &controller, - ControllerCore &controllerCore) : IScheduler(controllerCore), - controller(controller) {} + FifoStrict(IController &controller, ControllerCore &controllerCore) + : IScheduler(controllerCore), controller(controller) {} + virtual ~FifoStrict() {} void storeRequest(gp *payload) override; - std::pair getNextRequest( - Bank bank) override; + std::pair + getNextRequest(Bank bank) override; virtual gp *getPendingRequest(Bank bank) override; private: std::deque> buffer; }; -#endif /* FIFOSTRICT_H */ +#endif // FIFOSTRICT_H diff --git a/DRAMSys/library/src/controller/scheduler/Fr_Fcfs.cpp b/DRAMSys/library/src/controller/scheduler/FrFcfs.cpp similarity index 73% rename from DRAMSys/library/src/controller/scheduler/Fr_Fcfs.cpp rename to DRAMSys/library/src/controller/scheduler/FrFcfs.cpp index 05a4e745..c0d742af 100644 --- a/DRAMSys/library/src/controller/scheduler/Fr_Fcfs.cpp +++ b/DRAMSys/library/src/controller/scheduler/FrFcfs.cpp @@ -35,17 +35,17 @@ * Matthias Jung */ -#include "Fr_Fcfs.h" -#include "../../common/dramExtension.h" +#include "FrFcfs.h" +#include "../../common/dramExtensions.h" #include "../core/configuration/Configuration.h" #include using namespace std; -// The FR_FCFS is descibed in a 2000 paper from Rixner et al.: +// The FrFcfs (First Ready First Come First Served) is descibed in a 2000 paper from Rixner et al.: // Memory Access Scheduling // -// The FR_FCFS scheduler features for each bank in the DRAM a specific +// The FrFcfs scheduler features for each bank in the DRAM a specific // scheduling buffer for example: // // Bank0: OOOOOOOO @@ -58,7 +58,7 @@ using namespace std; // Bank6: OOOOO0XX // Bank7: XXXXXXXX -void FR_FCFS::storeRequest(gp *payload) +void FrFcfs::storeRequest(gp *payload) { // FIXME: Question: what if the buffer is full? IMHO the schedule function // should provide a true or false when the placement into the buffer worked @@ -67,26 +67,26 @@ void FR_FCFS::storeRequest(gp *payload) .emplace_back(payload); } -std::pair FR_FCFS::getNextRequest(Bank bank) +std::pair FrFcfs::getNextRequest(Bank bank) { // If the bank is empty like Bank0 in the example we do nothing - if (buffer[bank].empty()) { - return pair(Command::NOP, NULL); - } + if (buffer[bank].empty()) + return std::pair(Command::NOP, NULL); - // In FR_FCFS row hits have always the highest priority, therefore we search + // In FrFcfs row hits have always the highest priority, therefore we search // for row hits. If we find a row hit, we remove the transaction from the // queue and send it to the DRAM. - deque::iterator it = FindRowHit(bank); - if (it != buffer[bank].end()) { + std::deque::iterator it = findRowHit(bank); + if (it != buffer[bank].end()) + { gp *payload = *it; buffer[bank].erase(it); - return pair(getReadWriteCommand(*payload), payload); + return std::pair(getReadWriteCommand(payload), payload); } - // If there is no row hit, the FR_FCFS takes always the oldest transaction + // If there is no row hit, the FrFcfs takes always the oldest transaction // in the buffer, i.e. the transaction in the front. - return pair(getNextCommand(buffer[bank].front()), + return std::pair(getNextCommand(buffer[bank].front()), buffer[bank].front()); } @@ -97,27 +97,26 @@ std::pair FR_FCFS::getNextRequest(Bank bank) // deque container. The past-the-end element is the theoretical element that // would follow the last element in the deque container. It does not point to // any element, and thus shall not be dereferenced. -deque::iterator FR_FCFS::FindRowHit(Bank bank) +std::deque::iterator FrFcfs::findRowHit(Bank bank) { - deque &queue = buffer[bank]; + std::deque &queue = buffer[bank]; + Row activeRow = controllerCore.getRowBufferStates().getRowInRowBuffer(bank); if (!controllerCore.getRowBufferStates().rowBufferIsOpen(bank)) return queue.end(); // Traverse the scheduling queue of the specific bank: - for (auto it = queue.begin(); it != queue.end(); it++) { - gp *payload = *it; + for (auto it = queue.begin(); it != queue.end(); it++) + { //Found row-hit and return the according iterator - if (DramExtension::getRow(payload) - == controllerCore.getRowBufferStates().getRowInRowBuffer(bank)) { + if (DramExtension::getRow(*it) == activeRow) return it; - } } return queue.end(); } -gp *FR_FCFS::getPendingRequest(Bank /*bank*/) +gp *FrFcfs::getPendingRequest(Bank /*bank*/) { return NULL; } diff --git a/DRAMSys/library/src/controller/scheduler/Fr_Fcfs.h b/DRAMSys/library/src/controller/scheduler/FrFcfs.h similarity index 85% rename from DRAMSys/library/src/controller/scheduler/Fr_Fcfs.h rename to DRAMSys/library/src/controller/scheduler/FrFcfs.h index 983c664a..b3fa643b 100644 --- a/DRAMSys/library/src/controller/scheduler/Fr_Fcfs.h +++ b/DRAMSys/library/src/controller/scheduler/FrFcfs.h @@ -35,8 +35,8 @@ * Matthias Jung */ -#ifndef FR_FCFS_H_ -#define FR_FCFS_H_ +#ifndef FRFCFS_H +#define FRFCFS_H #include "IScheduler.h" #include "../core/ControllerCore.h" @@ -44,25 +44,23 @@ #include #include - -class FR_FCFS : public IScheduler +class FrFcfs : public IScheduler { public: - FR_FCFS(ControllerCore &controllerCore) : IScheduler(controllerCore) {} - virtual ~FR_FCFS() {} + FrFcfs(ControllerCore &controllerCore) : IScheduler(controllerCore) {} + virtual ~FrFcfs() {} void storeRequest(gp *payload) override; - std::pair getNextRequest( - Bank bank) override; + std::pair + getNextRequest(Bank bank) override; virtual gp *getPendingRequest(Bank bank) override; protected: std::map> buffer; - std::deque::iterator FindRowHit(Bank bank); + std::deque::iterator findRowHit(Bank bank); private: }; - -#endif +#endif // FRFCFS_H diff --git a/DRAMSys/library/src/controller/scheduler/Fr_Fcfs_grouper.cpp b/DRAMSys/library/src/controller/scheduler/FrFcfsGrp.cpp similarity index 90% rename from DRAMSys/library/src/controller/scheduler/Fr_Fcfs_grouper.cpp rename to DRAMSys/library/src/controller/scheduler/FrFcfsGrp.cpp index 40a8258e..3b41fd43 100644 --- a/DRAMSys/library/src/controller/scheduler/Fr_Fcfs_grouper.cpp +++ b/DRAMSys/library/src/controller/scheduler/FrFcfsGrp.cpp @@ -33,14 +33,15 @@ * Matthias Jung */ -#include "Fr_Fcfs_grouper.h" +#include "FrFcfsGrp.h" -// The FR_FCFS_Read_Priority works exactly like the FR_FCFS_RP. -// However writes are grouped! For detailed documentation look into the FR_FCFS. +// The FrFcfsGrp (First Ready First Come First Served Grouper) works exactly +// like the FrFcfsRp (First Ready First Come First Served Read Priority). +// However writes are grouped! For detailed documentation look into the FrFcfs. // TODO: what is missed is a check if the buffers are full. This will only work // if we have buffers with a fixed size (Prado's future patch). -std::pair FR_FCFS_GRP::getNextRequest(Bank bank) +std::pair FrFcfsGrp::getNextRequest(Bank bank) { // If the bank is empty we do nothing: if (buffer[bank].empty()) { @@ -74,7 +75,7 @@ std::pair FR_FCFS_GRP::getNextRequest(Bank bank) if (hazardDetection(bank, it) == false) { buffer[bank].erase(it); printDebugMessage("Read Hit found"); - return pair(getReadWriteCommand(*read), + return pair(getReadWriteCommand(read), read); } else { // If there was a hazard, switch the mode and try again: @@ -112,7 +113,7 @@ std::pair FR_FCFS_GRP::getNextRequest(Bank bank) .getRowInRowBuffer(bank)) { buffer[bank].erase(it); printDebugMessage("Write Hit found"); - return pair(getReadWriteCommand(*write), + return pair(getReadWriteCommand(write), write); } } @@ -131,7 +132,7 @@ std::pair FR_FCFS_GRP::getNextRequest(Bank bank) // If nothing was found we check the other banks before we switch the mode: pair other(Command::NOP, NULL); - unsigned int B = Configuration::getInstance().memSpec.NumberOfBanks; + unsigned int B = Configuration::getInstance().memSpec->NumberOfBanks; for (unsigned int i = 1; i < B; i++) { Bank nextBank((bank.ID() + i) % B); @@ -144,12 +145,12 @@ std::pair FR_FCFS_GRP::getNextRequest(Bank bank) readMode = !readMode; return getNextRequest(bank); - reportFatal("FR_FCFS_GRP", "Never should go here ..."); + reportFatal("FrFcfsGrp", "Never should go here ..."); } // There is a hazard if a read is found which will be scheduled before a write // to the same column and the same row of the same bank: -bool FR_FCFS_GRP::hazardDetection(Bank bank, std::deque::iterator ext) +bool FrFcfsGrp::hazardDetection(Bank bank, std::deque::iterator ext) { gp *read = *ext; @@ -170,11 +171,11 @@ bool FR_FCFS_GRP::hazardDetection(Bank bank, std::deque::iterator ext) } // Estimate the number of writes/reads in all bank buffers: -unsigned int FR_FCFS_GRP::getNumberOfRequest(tlm::tlm_command cmd) +unsigned int FrFcfsGrp::getNumberOfRequest(tlm::tlm_command cmd) { unsigned int numberOfRequests = 0; for (unsigned int i = 0; - i < Configuration::getInstance().memSpec.NumberOfBanks; + i < Configuration::getInstance().memSpec->NumberOfBanks; i++) { for (auto it = buffer[i].begin(); it != buffer[i].end(); it++) { gp *trans = *it; @@ -187,7 +188,7 @@ unsigned int FR_FCFS_GRP::getNumberOfRequest(tlm::tlm_command cmd) return numberOfRequests; } -void FR_FCFS_GRP::printDebugMessage(std::string message) +void FrFcfsGrp::printDebugMessage(std::string message) { - DebugManager::getInstance().printDebugMessage("FR_FCFS_GRP", message); + DebugManager::getInstance().printDebugMessage("FrFcfsGrp", message); } diff --git a/DRAMSys/library/src/controller/scheduler/Fr_Fcfs_grouper.h b/DRAMSys/library/src/controller/scheduler/FrFcfsGrp.h similarity index 87% rename from DRAMSys/library/src/controller/scheduler/Fr_Fcfs_grouper.h rename to DRAMSys/library/src/controller/scheduler/FrFcfsGrp.h index 6ae8ff08..ffcf0b5a 100644 --- a/DRAMSys/library/src/controller/scheduler/Fr_Fcfs_grouper.h +++ b/DRAMSys/library/src/controller/scheduler/FrFcfsGrp.h @@ -33,29 +33,24 @@ * Matthias Jung */ -#ifndef FR_FCFS_GROUPER_H -#define FR_FCFS_GROUPER_H +#ifndef FRFCFSGRP_H +#define FRFCFSGRP_H -#include "Fr_Fcfs.h" +#include "FrFcfs.h" #include "../Controller.h" class Controller; -class FR_FCFS_GRP : public FR_FCFS +class FrFcfsGrp : public FrFcfs { public: - FR_FCFS_GRP(ControllerCore &controllerCore, Controller *c) : - FR_FCFS(controllerCore), - ctrl(c), - readMode(true) - { - } + FrFcfsGrp(ControllerCore &controllerCore, Controller *c) + : FrFcfs(controllerCore), ctrl(c), readMode(true) {} std::pair getNextRequest(Bank bank) override; private: - Controller *ctrl; bool hazardDetection(Bank bank, std::deque::iterator ext); unsigned int getNumberOfRequest(tlm::tlm_command cmd); @@ -63,4 +58,4 @@ private: bool readMode; }; -#endif // FR_FCFS_GROUPER_H +#endif // FRFCFSGRP_H diff --git a/DRAMSys/library/src/controller/scheduler/Fr_Fcfs_read_priority.cpp b/DRAMSys/library/src/controller/scheduler/FrFcfsRp.cpp similarity index 88% rename from DRAMSys/library/src/controller/scheduler/Fr_Fcfs_read_priority.cpp rename to DRAMSys/library/src/controller/scheduler/FrFcfsRp.cpp index 57c2f60f..250510c0 100644 --- a/DRAMSys/library/src/controller/scheduler/Fr_Fcfs_read_priority.cpp +++ b/DRAMSys/library/src/controller/scheduler/FrFcfsRp.cpp @@ -33,12 +33,13 @@ * Matthias Jung */ -#include "Fr_Fcfs_read_priority.h" +#include "FrFcfsRp.h" -// The FR_FCFS_Read_Priority works exactly like the FR_FCFS but reads are -// prioratized over writes. For detailed documentation look into the FR_FCFS. +// The FrFcfsRp (First Ready First Come First Served Read Priority) works +// exactly like the FrFcfs but reads are prioratized over writes. +// For detailed documentation look into the FrFcfs. -std::pair FR_FCFS_RP::getNextRequest(Bank bank) +std::pair FrFcfsRp::getNextRequest(Bank bank) { // If the bank is empty like Bank0 in the example we do nothing: if (buffer[bank].empty()) { @@ -62,7 +63,7 @@ std::pair FR_FCFS_RP::getNextRequest(Bank bank) if (hazardDetection(bank, it) == false) { buffer[bank].erase(it); printDebugMessage("Read Hit found"); - return pair(getReadWriteCommand(*read), read); + return pair(getReadWriteCommand(read), read); } } } @@ -78,7 +79,7 @@ std::pair FR_FCFS_RP::getNextRequest(Bank bank) == controllerCore.getRowBufferStates().getRowInRowBuffer(bank)) { buffer[bank].erase(it); printDebugMessage("Write Hit found"); - return pair(getReadWriteCommand(*write), write); + return pair(getReadWriteCommand(write), write); } } } @@ -107,13 +108,13 @@ std::pair FR_FCFS_RP::getNextRequest(Bank bank) } } - reportFatal("FR_FCFS_RP", "Never should go here ..."); + reportFatal("FrFcfsRp", "Never should go here ..."); return pair(Command::NOP, NULL); } // There is a hazard if a read is found which will be scheduled before a write // to the same column and the same row of the same bank: -bool FR_FCFS_RP::hazardDetection(Bank bank, std::deque::iterator ext) +bool FrFcfsRp::hazardDetection(Bank bank, std::deque::iterator ext) { gp *read = *ext; @@ -133,7 +134,7 @@ bool FR_FCFS_RP::hazardDetection(Bank bank, std::deque::iterator ext) return false; } -void FR_FCFS_RP::printDebugMessage(std::string message) +void FrFcfsRp::printDebugMessage(std::string message) { - DebugManager::getInstance().printDebugMessage("FR_FCFS_RP", message); + DebugManager::getInstance().printDebugMessage("FrFcfsRp", message); } diff --git a/DRAMSys/library/src/controller/scheduler/Fr_Fcfs_read_priority.h b/DRAMSys/library/src/controller/scheduler/FrFcfsRp.h similarity index 89% rename from DRAMSys/library/src/controller/scheduler/Fr_Fcfs_read_priority.h rename to DRAMSys/library/src/controller/scheduler/FrFcfsRp.h index fac0af85..c1c10ca4 100644 --- a/DRAMSys/library/src/controller/scheduler/Fr_Fcfs_read_priority.h +++ b/DRAMSys/library/src/controller/scheduler/FrFcfsRp.h @@ -33,23 +33,21 @@ * Matthias Jung */ -#ifndef FR_FCFS_READ_PRIORITY_H -#define FR_FCFS_READ_PRIORITY_H +#ifndef FRFCFSRP_H +#define FRFCFSRP_H -#include "Fr_Fcfs.h" +#include "FrFcfs.h" -class FR_FCFS_RP : public FR_FCFS +class FrFcfsRp : public FrFcfs { public: - FR_FCFS_RP(ControllerCore &controllerCore) : FR_FCFS(controllerCore) {} - + FrFcfsRp(ControllerCore &controllerCore) : FrFcfs(controllerCore) {} std::pair getNextRequest(Bank bank) override; private: - bool hazardDetection(Bank bank, std::deque::iterator ext); void printDebugMessage(std::string message); }; -#endif // FR_FCFS_READ_PRIORITY_H +#endif // FRFCFSRP_H diff --git a/DRAMSys/library/src/controller/scheduler/grp.cpp b/DRAMSys/library/src/controller/scheduler/Grp.cpp similarity index 90% rename from DRAMSys/library/src/controller/scheduler/grp.cpp rename to DRAMSys/library/src/controller/scheduler/Grp.cpp index 652405aa..cf4dffe2 100644 --- a/DRAMSys/library/src/controller/scheduler/grp.cpp +++ b/DRAMSys/library/src/controller/scheduler/Grp.cpp @@ -33,14 +33,14 @@ * Matthias Jung */ -#include "grp.h" +#include "Grp.h" -// GRP just reorders w.r.t. read write grouping, however is not aware of the -// row buffer. For a row buffer aware grouper refer to FR_FCFS_GRP. +// Grp (Grouper) just reorders w.r.t. read write grouping, however is not aware of the +// row buffer. For a row buffer aware grouper refer to FrFcfsGrp. // TODO: what is missed is a check if the buffers are full. This will only work // if we have buffers with a fixed size (Prado's future patch). -std::pair GRP::getNextRequest(Bank bank) +std::pair Grp::getNextRequest(Bank bank) { // If the bank is empty we do nothing: if (buffer[bank].empty()) { @@ -74,7 +74,7 @@ std::pair GRP::getNextRequest(Bank bank) if (hazardDetection(bank, it) == false) { buffer[bank].erase(it); printDebugMessage("Read Hit found"); - return pair(getReadWriteCommand(*read), + return pair(getReadWriteCommand(read), read); } else { // If there was a hazard, switch the mode and try again: @@ -106,7 +106,7 @@ std::pair GRP::getNextRequest(Bank bank) .getRowInRowBuffer(bank)) { buffer[bank].erase(it); printDebugMessage("Write Hit found"); - return pair(getReadWriteCommand(*write), + return pair(getReadWriteCommand(write), write); } else { printDebugMessage("Write miss found"); @@ -118,7 +118,7 @@ std::pair GRP::getNextRequest(Bank bank) // If nothing was found we check the other banks before we switch the mode: pair other(Command::NOP, NULL); - unsigned int B = Configuration::getInstance().memSpec.NumberOfBanks; + unsigned int B = Configuration::getInstance().memSpec->NumberOfBanks; for (unsigned int i = 1; i < B; i++) { Bank nextBank((bank.ID() + i) % B); @@ -131,12 +131,12 @@ std::pair GRP::getNextRequest(Bank bank) readMode = !readMode; return getNextRequest(bank); - reportFatal("GRP", "Never should go here ..."); + reportFatal("Grp", "Never should go here ..."); } // There is a hazard if a read is found which will be scheduled before a write // to the same column and the same row of the same bank: -bool GRP::hazardDetection(Bank bank, std::deque::iterator ext) +bool Grp::hazardDetection(Bank bank, std::deque::iterator ext) { gp *read = *ext; @@ -157,11 +157,11 @@ bool GRP::hazardDetection(Bank bank, std::deque::iterator ext) } // Estimate the number of writes/reads in all bank buffers: -unsigned int GRP::getNumberOfRequest(tlm::tlm_command cmd) +unsigned int Grp::getNumberOfRequest(tlm::tlm_command cmd) { unsigned int numberOfRequests = 0; for (unsigned int i = 0; - i < Configuration::getInstance().memSpec.NumberOfBanks; + i < Configuration::getInstance().memSpec->NumberOfBanks; i++) { for (auto it = buffer[i].begin(); it != buffer[i].end(); it++) { gp *trans = *it; @@ -174,7 +174,7 @@ unsigned int GRP::getNumberOfRequest(tlm::tlm_command cmd) return numberOfRequests; } -void GRP::printDebugMessage(std::string message) +void Grp::printDebugMessage(std::string message) { - DebugManager::getInstance().printDebugMessage("FR_FCFS_GRP", message); + DebugManager::getInstance().printDebugMessage("FrFcfsGrp", message); } diff --git a/DRAMSys/library/src/controller/scheduler/grp.h b/DRAMSys/library/src/controller/scheduler/Grp.h similarity index 89% rename from DRAMSys/library/src/controller/scheduler/grp.h rename to DRAMSys/library/src/controller/scheduler/Grp.h index 2ffc46e0..13ccea71 100644 --- a/DRAMSys/library/src/controller/scheduler/grp.h +++ b/DRAMSys/library/src/controller/scheduler/Grp.h @@ -33,29 +33,24 @@ * Matthias Jung */ -#ifndef GROUPER_H -#define GROUPER_H +#ifndef GRP_H +#define GRP_H -#include "Fr_Fcfs.h" +#include "FrFcfs.h" #include "../Controller.h" class Controller; -class GRP : public FR_FCFS +class Grp : public FrFcfs { public: - GRP(ControllerCore &controllerCore, Controller *c) : - FR_FCFS(controllerCore), - ctrl(c), - readMode(true) - { - } + Grp(ControllerCore &controllerCore, Controller *c) + : FrFcfs(controllerCore), ctrl(c), readMode(true) {} std::pair getNextRequest(Bank bank) override; private: - Controller *ctrl; bool hazardDetection(Bank bank, std::deque::iterator ext); unsigned int getNumberOfRequest(tlm::tlm_command cmd); @@ -63,4 +58,4 @@ private: bool readMode; }; -#endif // GROUPER_H +#endif // GRP_H diff --git a/DRAMSys/library/src/controller/scheduler/IScheduler.cpp b/DRAMSys/library/src/controller/scheduler/IScheduler.cpp index 09d53b47..2a9b6eff 100644 --- a/DRAMSys/library/src/controller/scheduler/IScheduler.cpp +++ b/DRAMSys/library/src/controller/scheduler/IScheduler.cpp @@ -50,13 +50,18 @@ void IScheduler::printDebugMessage(std::string message) Command IScheduler::getNextCommand(gp &payload) { Bank bank = DramExtension::getBank(payload); - if (!controllerCore.getRowBufferStates().rowBufferIsOpen(bank)) { + if (!controllerCore.getRowBufferStates().rowBufferIsOpen(bank)) + { return Command::Activate; - } else if (controllerCore.getRowBufferStates().rowBufferIsOpen(bank) && + } + else if (controllerCore.getRowBufferStates().rowBufferIsOpen(bank) && controllerCore.getRowBufferStates().getRowInRowBuffer(bank) != - DramExtension::getRow(payload)) { + DramExtension::getRow(payload)) + { return Command::Precharge; - } else { + } + else + { return getReadWriteCommand(payload); } } @@ -68,13 +73,15 @@ Command IScheduler::getNextCommand(gp *payload) Command IScheduler::getReadWriteCommand(gp &payload) { - - if (payload.get_command() == tlm::TLM_READ_COMMAND) { + if (payload.get_command() == tlm::TLM_READ_COMMAND) + { if (Configuration::getInstance().OpenPagePolicy) return Command::Read; else return Command::ReadA; - } else { + } + else + { if (Configuration::getInstance().OpenPagePolicy) return Command::Write; else @@ -86,3 +93,4 @@ Command IScheduler::getReadWriteCommand(gp *payload) { return getReadWriteCommand(*payload); } + diff --git a/DRAMSys/library/src/controller/scheduler/IScheduler.h b/DRAMSys/library/src/controller/scheduler/IScheduler.h index 0b0cf0f5..b40f29ec 100644 --- a/DRAMSys/library/src/controller/scheduler/IScheduler.h +++ b/DRAMSys/library/src/controller/scheduler/IScheduler.h @@ -38,9 +38,8 @@ #ifndef ISCHEDULER_H #define ISCHEDULER_H - #include -#include "../../common/dramExtension.h" +#include "../../common/dramExtensions.h" #include "../Command.h" #include "../core/ControllerCore.h" diff --git a/DRAMSys/library/src/controller/scheduler/PARBS.cpp b/DRAMSys/library/src/controller/scheduler/PARBS.cpp deleted file mode 100644 index fcc65896..00000000 --- a/DRAMSys/library/src/controller/scheduler/PARBS.cpp +++ /dev/null @@ -1,149 +0,0 @@ -/* - * Copyright (c) 2015, University of Kaiserslautern - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * 3. Neither the name of the copyright holder nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED - * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER - * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * Authors: - * Janik Schlemminger - * Robert Gernhardt - * Matthias Jung - */ - - -//// * PARBS.cpp -//// * -//// * Created on: Apr 9, 2014 -//// * Author: robert -//// */ - -//#include "PARBS.h" -//#include "../core/configuration/Configuration.h" -//#include "../../common/dramExtension.h" -//#include "map" -//#include "ThreadLoad.h" -//#include - -//namespace scheduler { - -//using namespace std; - -//PAR_BS::PAR_BS(ControllerCore& controllerCore, bool useExternalBankstates, unsigned int capsize) : -// controllerCore(controllerCore), useExternalBankstates(useExternalBankstates), capsize(capsize) -//{ -// if (useExternalBankstates) -// { -// batch = new FR_FCFS(controllerCore, true, false); -// buffer = new FR_FCFS(controllerCore, true, false); -// } -// else -// { -// batch = new FR_FCFS(controllerCore, true, false); -// buffer = new FR_FCFS(controllerCore, true, false); -// } -//} - -//PAR_BS::~PAR_BS() -//{ - -//} - -//bool PAR_BS::hasPayloads() -//{ -// return batch->hasPayloads() || buffer->hasPayloads(); -//} - -//void PAR_BS::schedule(gp* payload) -//{ -// printDebugMessage("hello!"); -// buffer->schedule(payload); -//} - -//gp* PAR_BS::getNextPayload() -//{ -// if (!batch->hasPayloads()) -// { -// stringstream s; -// s << "In batch: " << batch->getNumberOfQueuedPayloads() << "\t" << "in buffer: " << buffer->getNumberOfQueuedPayloads() << endl; -// formBatch(); -// s<< "Formed new batch" << endl; -// s << "In batch: " << batch->getNumberOfQueuedPayloads() << "\t" << "in buffer: " << buffer->getNumberOfQueuedPayloads() << endl; -// printDebugMessage(s.str()); -// sc_assert(batch->hasPayloads()); -// } - -// gp* result = batch->getNextPayload(); -// if(result == NULL) -// result = buffer->getNextPayload(); -// return result; -//} - -//void PAR_BS::removePayload(gp* payload) -//{ -// buffer->removePayload(payload); -// batch->removePayload(payload); - -// if (!useExternalBankstates) -// { -// DramExtension& extension = DramExtension::getExtension(payload); -// internalBankstates.openRowInRowBuffer(extension.getBank(), extension.getRow()); -// } - -//} - -//void PAR_BS::formBatch() -//{ -// map loads; - -// for (Bank bank : controllerCore.getBanks()) -// { -// for (unsigned int i = 0; i < capsize; i++) -// { -// gp* payload = buffer->popOldest(bank); -// if(payload == NULL) -// break; -// loads[DramExtension::getExtension(payload).getThread()].addTransaction(payload); -// } -// } - -// vector sortedLoads; -// for (auto& threadLoadPair : loads) -// { -// sortedLoads.push_back(&threadLoadPair.second); -// } - -// sort(sortedLoads.begin(), sortedLoads.end(), LoadPointerComparer()); - -// for (auto& load : sortedLoads) -// { -// batch->schedule(load->getTransactions()); -// } - -//} - -//} diff --git a/DRAMSys/library/src/controller/scheduler/PARBS.h b/DRAMSys/library/src/controller/scheduler/PARBS.h deleted file mode 100644 index 59e3f1e1..00000000 --- a/DRAMSys/library/src/controller/scheduler/PARBS.h +++ /dev/null @@ -1,77 +0,0 @@ -/* - * Copyright (c) 2015, University of Kaiserslautern - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * 3. Neither the name of the copyright holder nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED - * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER - * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * Authors: - * Janik Schlemminger - * Robert Gernhardt - * Matthias Jung - */ - - -//// * PARBS.h -//// * -//// * Created on: Apr 9, 2014 -//// * Author: robert -//// * - -//#ifndef PARBS_H_ -//#define PARBS_H_ -//#include "Scheduler.h" -//#include "../core/ControllerCore.h" -//#include "Fr_Fcfs.h" - -//namespace scheduler { - -//class PAR_BS : public Scheduler -//{ -//public: -// PAR_BS(ControllerCore& controllerCore, bool useExternalBankstates, unsigned int capsize); -// virtual ~PAR_BS(); - -// virtual bool hasPayloads() override; -// virtual void schedule(gp* payload) override; -// virtual gp* getNextPayload() override; -// virtual void removePayload(gp* payload) override; - -//private: -// void formBatch(); - -// ControllerCore& controllerCore; -// bool useExternalBankstates; -// RowBufferState internalBankstates; -// FR_FCFS *batch; -// FR_FCFS *buffer; -// unsigned int capsize; -//}; - -//} /* scheduler core */ - -//#endif diff --git a/DRAMSys/library/src/controller/scheduler/SMS.cpp b/DRAMSys/library/src/controller/scheduler/SMS.cpp index 0f407775..f01267d7 100644 --- a/DRAMSys/library/src/controller/scheduler/SMS.cpp +++ b/DRAMSys/library/src/controller/scheduler/SMS.cpp @@ -30,7 +30,7 @@ std::pair SMS::getNextRequest(Bank bank) return pair(Command::NOP, NULL); } else { gp *payload = bankBuffers[bank].front(); - Command command = IScheduler::getNextCommand(*payload); + Command command = IScheduler::getNextCommand(payload); if (command == Command::Read || command == Command::ReadA || command == Command::Write || command == Command::WriteA) { @@ -46,7 +46,7 @@ std::pair SMS::getNextRequest(Bank bank) void SMS::batchScheduler() { - sc_time memClk = Configuration::getInstance().memSpec.clk; + sc_time memClk = Configuration::getInstance().memSpec->clk; std::default_random_engine generator; std::bernoulli_distribution distribution((double) SJFprobability / 100.0); diff --git a/DRAMSys/library/src/controller/scheduler/SMS.h b/DRAMSys/library/src/controller/scheduler/SMS.h index d60c033a..4019836b 100644 --- a/DRAMSys/library/src/controller/scheduler/SMS.h +++ b/DRAMSys/library/src/controller/scheduler/SMS.h @@ -7,7 +7,7 @@ #include "IScheduler.h" #include "../core/ControllerCore.h" #include "../core/configuration/Configuration.h" -#include "../../common/dramExtension.h" +#include "../../common/dramExtensions.h" #include "../../common/DebugManager.h" #define LOW_SYSTEM_LOAD 16 diff --git a/DRAMSys/library/src/controller/scheduler/ThreadLoad.cpp b/DRAMSys/library/src/controller/scheduler/ThreadLoad.cpp deleted file mode 100644 index 1938c1d3..00000000 --- a/DRAMSys/library/src/controller/scheduler/ThreadLoad.cpp +++ /dev/null @@ -1,108 +0,0 @@ -/* - * Copyright (c) 2015, University of Kaiserslautern - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * 3. Neither the name of the copyright holder nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED - * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER - * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * Authors: - * Janik Schlemminger - * Robert Gernhardt - * Matthias Jung - */ - - -// * ThreadLoad.cpp -// * -// * Created on: Apr 9, 2014 -// * Author: robert -// */ - -//#include "ThreadLoad.h" - -//namespace scheduler { - -//using namespace std; - -//ThreadLoad::ThreadLoad() -//{ -// // TODO Auto-generated constructor stub - -//} - -//ThreadLoad::~ThreadLoad() -//{ -// // TODO Auto-generated destructor stub -//} - -//unsigned int ThreadLoad::getMaxBankLoad() const -//{ -// unsigned int maxLoad = 0; -// for (auto& bankVectorPair : load) -// { -// if (bankVectorPair.second.size() > maxLoad) -// maxLoad = bankVectorPair.second.size(); -// } -// return maxLoad; -//} - -//unsigned int ThreadLoad::getTotalLoad() const -//{ -// unsigned int totalLoad = 0; -// for (auto& bankVectorPair : load) -// { -// totalLoad += bankVectorPair.second.size(); -// } -// return totalLoad; -//} - -//void ThreadLoad::addTransaction(gp* payload) -//{ -// load[DramExtension::getExtension(payload).getBank()].push_back(payload); -//} - -//bool operator<(const ThreadLoad& lhs, const ThreadLoad& rhs) -//{ -// if (lhs.getMaxBankLoad() < rhs.getMaxBankLoad()) -// return true; -// else if (lhs.getMaxBankLoad() == rhs.getMaxBankLoad()) -// return lhs.getTotalLoad() < rhs.getTotalLoad(); -// else -// return false; -//} - -//vector ThreadLoad::getTransactions() -//{ -// vector result; -// for (auto& bankVectorPair : load) -// { -// result.insert(result.end(), bankVectorPair.second.begin(), bankVectorPair.second.end()); -// } -// return result; -//} - -//} /* namespace scheduler diff --git a/DRAMSys/library/src/controller/scheduler/ThreadLoad.h b/DRAMSys/library/src/controller/scheduler/ThreadLoad.h deleted file mode 100644 index f4152a05..00000000 --- a/DRAMSys/library/src/controller/scheduler/ThreadLoad.h +++ /dev/null @@ -1,81 +0,0 @@ -/* - * Copyright (c) 2015, University of Kaiserslautern - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * 3. Neither the name of the copyright holder nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED - * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER - * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * Authors: - * Janik Schlemminger - * Robert Gernhardt - * Matthias Jung - */ - - -//// * ThreadLoad.h -//// * -//// * Created on: Apr 9, 2014 -//// * Author: robert -//// */ - -//#ifndef THREADLOAD_H_ -//#define THREADLOAD_H_ -//#include -//#include -//#include "../../common/dramExtension.h" - -//namespace scheduler { - -//typedef tlm::tlm_generic_payload gp; - -//class ThreadLoad -//{ -//public: -// ThreadLoad();d -// virtual ~ThreadLoad(); - -// unsigned int getMaxBankLoad() const; -// unsigned int getTotalLoad() const; - -// void addTransaction(gp* payload); -// std::vector getTransactions(); - -//private: -// std::map> load; -//}; - -//bool operator< (const ThreadLoad &lhs, const ThreadLoad &rhs); - -//struct LoadPointerComparer { -// bool operator()(const ThreadLoad* l, const ThreadLoad* r) { -// return *l < *r; -// } -//}; - -//} /* namespace scheduler */ - -//#endif /* THREADLOAD_H_ diff --git a/DRAMSys/library/src/controller/scheduler/readwritegrouper.cpp b/DRAMSys/library/src/controller/scheduler/readwritegrouper.cpp deleted file mode 100644 index e290fddd..00000000 --- a/DRAMSys/library/src/controller/scheduler/readwritegrouper.cpp +++ /dev/null @@ -1,191 +0,0 @@ -/* - * Copyright (c) 2015, University of Kaiserslautern - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * 3. Neither the name of the copyright holder nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED - * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER - * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * Authors: - * Janik Schlemminger - * Robert Gernhardt - * Matthias Jung - */ - -//#include "readwritegrouper.h" -//#include "../../common/DebugManager.h" - -//namespace scheduler{ - -//using namespace tlm; -//using namespace std; - -//ReadWriteGrouper::ReadWriteGrouper(ControllerCore& controllerCore): controllerCore(controllerCore) -//{ -// batches.push_back(shared_ptr(new FR_FCFS(controllerCore,true,false))); -// batches.push_back(shared_ptr(new FR_FCFS(controllerCore,true,false))); -//} - -//ReadWriteGrouper::~ReadWriteGrouper() -//{ - -//} - -//void ReadWriteGrouper::schedule(gp *payload) -//{ -// tlm_command command = payload->get_command(); - -// if(batches.size() > 2) -// { -// if(command == TLM_READ_COMMAND) -// { -// //printDebugMessage("Scheduling read"); - -// if(schedulingReadCausesHazardWithQueuedWrite(payload)) -// { -// printDebugMessage("Scheduling read causes hazard with queued write"); -// batches.push_back(shared_ptr(new FR_FCFS(controllerCore,true,false))); -// batches.push_back(shared_ptr(new FR_FCFS(controllerCore,true,false))); -// } - -// getLatestReadBatch().schedule(payload); -// } -// else if(command == TLM_WRITE_COMMAND) -// { -// //printDebugMessage("Scheduling write"); -// getLatestWriteBatch().schedule(payload); -// } -// } -// else if(batches.size() == 2) -// { -// if(command == TLM_READ_COMMAND) -// { -// //printDebugMessage("Scheduling read"); - -// if(getLatestReadBatch().hasPayloads() && schedulingReadCausesHazardWithQueuedWrite(payload)) -// { -// printDebugMessage("Scheduling read causes hazard with queued write"); -// batches.push_back(shared_ptr(new FR_FCFS(controllerCore,true,false))); -// batches.push_back(shared_ptr(new FR_FCFS(controllerCore,true,false))); -// } -// else if(!getLatestReadBatch().hasPayloads() && getLatestWriteBatch().hasPayloads()) -// { -// printDebugMessage("Scheduling read, but there are writes to be processed first"); -// batches.erase(batches.begin()); -// batches.push_back(shared_ptr(new FR_FCFS(controllerCore,true,false))); -// batches.push_back(shared_ptr(new FR_FCFS(controllerCore,true,false))); -// } -// getLatestReadBatch().schedule(payload); - -// } -// else if(command == TLM_WRITE_COMMAND) -// { -// //printDebugMessage("Scheduling write"); -// getLatestWriteBatch().schedule(payload); -// } -// } -// else -// { -// sc_assert(false); -// } -//} - -//gp *ReadWriteGrouper::getNextPayload() -//{ -// if(batches.size() > 2) -// { -// return batches.front()->getNextPayload(); -// } -// else if(batches.size() == 2) -// { -// if(getLatestReadBatch().hasPayloads()) -// return getLatestReadBatch().getNextPayload(); -// else if(getLatestWriteBatch().hasPayloads()) -// return getLatestWriteBatch().getNextPayload(); -// else -// return NULL; -// } -// else -// { -// sc_assert(false); -// return NULL; -// } -//} - - -//void ReadWriteGrouper::removePayload(gp *payload) -//{ -// if(batches.size() > 2) -// { -// batches.front()->removePayload(payload); -// if(!batches.front()->hasPayloads()) -// batches.erase(batches.begin()); -// } -// else if(batches.size() == 2) -// { -// if(payload->is_read()) -// getLatestReadBatch().removePayload(payload); -// else -// getLatestWriteBatch().removePayload(payload); -// } -// else -// { -// sc_assert(false); -// } -//} - - -//bool ReadWriteGrouper::hasPayloads() -//{ -// if(batches.size() > 2) -// return true; -// else if(batches.size() == 2) -// return (getLatestReadBatch().hasPayloads() || getLatestWriteBatch().hasPayloads()); -// else -// { -// sc_assert(false); -// return NULL; -// } -//} - - -//bool ReadWriteGrouper::schedulingReadCausesHazardWithQueuedWrite(gp *payload) -//{ -// sc_assert(payload->is_read()); -// return getLatestWriteBatch().containsPayloadTragetingSameAddress(payload); -//} - -//FR_FCFS &ReadWriteGrouper::getLatestWriteBatch() -//{ -// return *batches[batches.size()-1]; -//} - -//FR_FCFS &ReadWriteGrouper::getLatestReadBatch() -//{ -// return *batches[batches.size()-2]; -//} - -//} diff --git a/DRAMSys/library/src/controller/scheduler/readwritegrouper.h b/DRAMSys/library/src/controller/scheduler/readwritegrouper.h deleted file mode 100644 index 760b17fc..00000000 --- a/DRAMSys/library/src/controller/scheduler/readwritegrouper.h +++ /dev/null @@ -1,78 +0,0 @@ -/* - * Copyright (c) 2015, University of Kaiserslautern - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * 3. Neither the name of the copyright holder nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED - * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER - * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * Authors: - * Janik Schlemminger - * Robert Gernhardt - * Matthias Jung - */ - -//#ifndef READWRITEGROUPER_H -//#define READWRITEGROUPER_H -//#include "Scheduler.h" -//#include "Fr_Fcfs.h" -//#include "../core/ControllerCore.h" -//#include -//#include - - -//namespace scheduler{ - -//class ReadWriteGrouper : public Scheduler -//{ -//public: -// ReadWriteGrouper(ControllerCore& controllerCore); -// ~ReadWriteGrouper(); -// virtual void schedule(gp* payload) override; -// virtual bool hasPayloads() override; -// virtual gp* getNextPayload() override; -// virtual void removePayload(gp* payload) override; - -//private: -// // contains batches of requests -// // last element always contains writes -// // next-to-last element always contains reads -// // there are always at least two batches -// // if there are more than two batches, batches[0] is never empty and -// // getNextPayload and removePayload are forwarded to batches[0] -// std::vector> batches; -// ControllerCore& controllerCore; - -// bool schedulingReadCausesHazardWithQueuedWrite(gp* payload); -// FR_FCFS& getLatestWriteBatch(); -// FR_FCFS& getLatestReadBatch(); - -//}; - - -//} - -//#endif // READWRITEGROUPER_H diff --git a/DRAMSys/library/src/error/eccbaseclass.h b/DRAMSys/library/src/error/eccbaseclass.h index 544eb420..720be2d7 100644 --- a/DRAMSys/library/src/error/eccbaseclass.h +++ b/DRAMSys/library/src/error/eccbaseclass.h @@ -8,7 +8,7 @@ #include "ECC/ECC.h" -#include "../common/xmlAddressdecoder.h" +#include "../common/XmlAddressDecoder.h" #include "../common/DebugManager.h" using namespace std; diff --git a/DRAMSys/library/src/error/errormodel.cpp b/DRAMSys/library/src/error/errormodel.cpp index eb70a964..861df60a 100644 --- a/DRAMSys/library/src/error/errormodel.cpp +++ b/DRAMSys/library/src/error/errormodel.cpp @@ -46,15 +46,15 @@ void errorModel::init() powerAnalysis = Configuration::getInstance().PowerAnalysis; thermalSim = Configuration::getInstance().ThermalSimulation; // Get Configuration parameters: - burstLenght = Configuration::getInstance().memSpec.BurstLength; - numberOfColumns = Configuration::getInstance().memSpec.NumberOfColumns; + burstLenght = Configuration::getInstance().memSpec->BurstLength; + numberOfColumns = Configuration::getInstance().memSpec->NumberOfColumns; bytesPerColumn = AddressDecoder::getInstance().amount["bytes"]; // Adjust number of bytes per column dynamically to the selected ecc controller bytesPerColumn = Configuration::getInstance().adjustNumBytesAfterECC( bytesPerColumn); - numberOfRows = Configuration::getInstance().memSpec.NumberOfRows; + numberOfRows = Configuration::getInstance().memSpec->NumberOfRows; numberOfBitErrorEvents = 0; @@ -253,7 +253,7 @@ void errorModel::markBitFlips() { double temp = getTemperature(); for (unsigned int row = 0; - row < Configuration::getInstance().memSpec.NumberOfRows; row++) { + row < Configuration::getInstance().memSpec->NumberOfRows; row++) { // If the row has never been accessed ignore it and go to the next one if (lastRowAccess[row] != SC_ZERO_TIME) { // Get the time interval between now and the last acivate/refresh @@ -498,7 +498,7 @@ double errorModel::getTemperature() // TODO // check if this is best way to request information to DRAMPower. unsigned long long clk_cycles = sc_time_stamp().value() / - Configuration::getInstance().memSpec.clk.value(); + Configuration::getInstance().memSpec->clk.value(); DRAMPower->calcWindowEnergy(clk_cycles); float average_power = (float)DRAMPower->getPower().average_power; temperature = TemperatureController::getInstance().getTemperature( diff --git a/DRAMSys/library/src/error/errormodel.h b/DRAMSys/library/src/error/errormodel.h index c1f21c6e..e562401c 100644 --- a/DRAMSys/library/src/error/errormodel.h +++ b/DRAMSys/library/src/error/errormodel.h @@ -40,7 +40,7 @@ #include #include #include "../controller/core/configuration/Configuration.h" -#include "../common/xmlAddressdecoder.h" +#include "../common/XmlAddressDecoder.h" #include "../common/third_party/DRAMPower/src/libdrampower/LibDRAMPower.h" class errorModel : public sc_module diff --git a/DRAMSys/library/src/simulation/Arbiter.cpp b/DRAMSys/library/src/simulation/Arbiter.cpp new file mode 100644 index 00000000..c68927f8 --- /dev/null +++ b/DRAMSys/library/src/simulation/Arbiter.cpp @@ -0,0 +1,251 @@ +/* + * Copyright (c) 2015, University of Kaiserslautern + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER + * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Authors: + * Robert Gernhardt + * Matthias Jung + * Eder F. Zulian + */ + +#include "Arbiter.h" + +using namespace std; +using namespace tlm; + +Arbiter::Arbiter(sc_module_name /*name*/) : payloadEventQueue(this, &Arbiter::peqCallback) +{ + // The arbiter communicates with one or more memory unity through one or more sockets (one or more memory channels). + // Each of the arbiter's initiator sockets is bound to a memory controller's target socket. + // Anytime an transaction comes from a memory unity to the arbiter the "bw" callback is called. + iSocket.register_nb_transport_bw(this, &Arbiter::nb_transport_bw); + + for (size_t i = 0; i < Configuration::getInstance().NumberOfMemChannels; ++i) + { + channelIsFree.push_back(true); + pendingRequests.push_back(queue()); + } + + // One or more devices can accesss all the memory units through the arbiter. + // Devices' initiator sockets are bound to arbiter's target sockets. + // As soon the arbiter receives a request in any of its target sockets it should treat and forward it to the proper memory channel. + tSocket.register_nb_transport_fw(this, &Arbiter::nb_transport_fw); + + tSocket.register_transport_dbg(this, &Arbiter::transport_dbg); +} + +// Initiated by initiator side +// This function is called when an arbiter's target socket receives a transaction from a device +tlm_sync_enum Arbiter::nb_transport_fw(int id, tlm_generic_payload &payload, + tlm_phase &phase, sc_time &fwDelay) +{ + sc_time notDelay = clkAlign(sc_time_stamp() + fwDelay) - + (sc_time_stamp() + fwDelay); + if (phase == BEGIN_REQ) + { + // adjust address offset: + payload.set_address(payload.get_address() - + Configuration::getInstance().AddressOffset); + + // In the begin request phase the socket ID is appended to the payload. + // It will extracted from the payload and used later. + appendDramExtension(id, payload); + payload.acquire(); + } + else if (phase == END_RESP) + { + notDelay += Configuration::getInstance().memSpec->clk; + payload.release(); + } + + printDebugMessage("[fw] " + phaseNameToString(phase) + " notification in " + + notDelay.to_string()); + payloadEventQueue.notify(payload, phase, notDelay); + return TLM_ACCEPTED; +} + +// Initiated by dram side +// This function is called when an arbiter's initiator socket receives a transaction from a memory controller +tlm_sync_enum Arbiter::nb_transport_bw(int channelId, tlm_generic_payload &payload, + tlm_phase &phase, sc_time &bwDelay) +{ + // Check channel ID + if ((unsigned int)channelId != DramExtension::getExtension(payload).getChannel().ID()) + SC_REPORT_FATAL("Arbiter", "Payload extension was corrupted"); + + printDebugMessage("[bw] " + phaseNameToString(phase) + " notification in " + + bwDelay.to_string()); + payloadEventQueue.notify(payload, phase, bwDelay); + return TLM_ACCEPTED; +} + +unsigned int Arbiter::transport_dbg(int /*id*/, tlm::tlm_generic_payload &trans) +{ + // adjust address offset: + trans.set_address(trans.get_address() - + Configuration::getInstance().AddressOffset); + + DecodedAddress decodedAddress = AddressDecoder::getInstance().decodeAddress( + trans.get_address()); + return iSocket[decodedAddress.channel]->transport_dbg(trans); +} + +void Arbiter::peqCallback(tlm_generic_payload &payload, const tlm_phase &phase) +{ + unsigned int initiatorSocket = DramExtension::getExtension( + payload).getThread().ID(); + unsigned int channelId = DramExtension::getExtension(payload).getChannel().ID(); + + // Check the valid range of initiatorSocket ID and channel Id + // TODO: initiatorSocket ID not checked + assert(channelId < Configuration::getInstance().NumberOfMemChannels); + + // Phases initiated by the intiator side from arbiter's point of view (devices performing memory requests to the arbiter) + if (phase == BEGIN_REQ) + { + if (channelIsFree[channelId]) { + // This channel was available. Forward the new transaction to the memory controller. + channelIsFree[channelId] = false; + sendToChannel(channelId, payload, phase, SC_ZERO_TIME); + } else { + // This channel is busy. Enqueue the new transaction which phase is BEGIN_REQ. + pendingRequests[channelId].push(&payload); + } + } + // Phases initiated by the target side from arbiter's point of view (memory side) + else if (phase == END_REQ) { + channelIsFree[channelId] = true; + + // The arbiter receives a transaction which phase is END_REQ from memory controller and forwards it to the requester device. + sendToInitiator(initiatorSocket, payload, phase, SC_ZERO_TIME); + + // This channel is now free! Dispatch a new transaction (phase is BEGIN_REQ) from the queue, if any. Send it to the memory controller. + if (!pendingRequests[channelId].empty()) { + tlm_generic_payload *payloadToSend = pendingRequests[channelId].front(); + pendingRequests[channelId].pop(); + // Send ONE of the enqueued new transactions (phase is BEGIN_REQ) through this channel. + sendToChannel(channelId, *payloadToSend, BEGIN_REQ, SC_ZERO_TIME); + // Mark the channel as busy again. + channelIsFree[channelId] = false; + } + } + else if (phase == BEGIN_RESP) + { + // The arbiter receives a transaction in BEGIN_RESP phase + // (that came from the memory side) and forwards it to the requester + // device + if (receivedResponses[initiatorSocket].empty()) { + sendToInitiator(initiatorSocket, payload, phase, SC_ZERO_TIME); + } + // Enqueue the transaction in BEGIN_RESP phase until the initiator + // device acknowledge it (phase changes to END_RESP). + receivedResponses[initiatorSocket].push(&payload); + } + else if (phase == END_RESP) + { + // Send the END_RESP message to the memory + sendToChannel(channelId, payload, phase, SC_ZERO_TIME); + // Drop one element of the queue of BEGIN_RESP from memory to this device + receivedResponses[initiatorSocket].pop(); + + // Check if there are queued transactoins with phase BEGIN_RESP from memory to this device + if (!receivedResponses[initiatorSocket].empty()) { + // The queue is not empty. + tlm_generic_payload *payloadToSend = receivedResponses[initiatorSocket].front(); + // Send ONE extra BEGIN_RESP to the device + sendToInitiator(initiatorSocket, *payloadToSend, BEGIN_RESP, SC_ZERO_TIME); + } + } + else + SC_REPORT_FATAL(0, + "Payload event queue in arbiter was triggered with unknown phase"); +} + +void Arbiter::sendToChannel(unsigned int channelId, tlm_generic_payload &payload, + const tlm_phase &phase, const sc_time &delay) +{ + tlm_phase TPhase = phase; + sc_time TDelay = delay; + iSocket[channelId]->nb_transport_fw(payload, TPhase, TDelay); +} + +void Arbiter::sendToInitiator(unsigned int id, tlm_generic_payload &payload, + const tlm_phase &phase, const sc_time &delay) +{ + tlm_phase TPhase = phase; + sc_time TDelay = delay; + tSocket[id]->nb_transport_bw(payload, TPhase, TDelay); +} + +void Arbiter::appendDramExtension(int socketId, tlm_generic_payload &payload) +{ + // Append Generation Extension + GenerationExtension *genExtension = new GenerationExtension(sc_time_stamp()); + payload.set_auto_extension(genExtension); + + unsigned int burstlength = payload.get_streaming_width(); + DecodedAddress decodedAddress = AddressDecoder::getInstance().decodeAddress(payload.get_address()); + // Check the valid range of decodedAddress + if (addressIsValid(decodedAddress)) { + DramExtension *extension = new DramExtension(Thread(socketId), + Channel(decodedAddress.channel), Bank(decodedAddress.bank), + BankGroup(decodedAddress.bankgroup), Row(decodedAddress.row), + Column(decodedAddress.column), burstlength); + payload.set_auto_extension(extension); + } else { + SC_REPORT_FATAL("Arbiter", "Decoded Address is not inside the valid range"); + } +} + +bool Arbiter::addressIsValid(DecodedAddress &decodedAddress) +{ + if (decodedAddress.channel >= AddressDecoder::getInstance().amount["channel"]) { + return false; + } + if (decodedAddress.bank >= AddressDecoder::getInstance().amount["bank"]) { + return false; + } + if (decodedAddress.bankgroup > + AddressDecoder::getInstance().amount["bankgroup"]) { + return false; + } + if (decodedAddress.column >= AddressDecoder::getInstance().amount["column"]) { + return false; + } + if (decodedAddress.row >= AddressDecoder::getInstance().amount["row"]) { + return false; + } + return true; +} + +void Arbiter::printDebugMessage(std::string message) +{ + DebugManager::getInstance().printDebugMessage(this->name(), message); +} diff --git a/DRAMSys/library/src/simulation/Arbiter.h b/DRAMSys/library/src/simulation/Arbiter.h index 7f60913d..672862c8 100644 --- a/DRAMSys/library/src/simulation/Arbiter.h +++ b/DRAMSys/library/src/simulation/Arbiter.h @@ -35,8 +35,8 @@ * Eder F. Zulian */ -#ifndef ARBITER_H_ -#define ARBITER_H_ +#ifndef ARBITER_H +#define ARBITER_H #include #include @@ -46,249 +46,60 @@ #include #include #include -#include "../common/xmlAddressdecoder.h" -#include "../common/dramExtension.h" -#include "../controller/core/TimingCalculation.h" +#include "../common/XmlAddressDecoder.h" +#include "../common/dramExtensions.h" +#include "../controller/core/timingCalculations.h" #include "../controller/core/configuration/ConfigurationLoader.h" using namespace std; using namespace tlm; -struct Arbiter: public sc_module { +class Arbiter : public sc_module +{ public: tlm_utils::multi_passthrough_initiator_socket iSocket; tlm_utils::multi_passthrough_target_socket tSocket; - SC_CTOR(Arbiter) : payloadEventQueue(this, &Arbiter::peqCallback) - { - // The arbiter communicates with one or more memory unity through one or more sockets (one or more memory channels). - // Each of the arbiter's initiator sockets is bound to a memory controller's target socket. - // Anytime an transaction comes from a memory unity to the arbiter the "bw" callback is called. - iSocket.register_nb_transport_bw(this, &Arbiter::nb_transport_bw); - - for (size_t i = 0; i < Configuration::getInstance().NumberOfMemChannels; ++i) { - channelIsFree.push_back(true); - pendingRequests.push_back(queue()); - } - - // One or more devices can accesss all the memory units through the arbiter. - // Devices' initiator sockets are bound to arbiter's target sockets. - // As soon the arbiter receives a request in any of its target sockets it should treat and forward it to the proper memory channel. - tSocket.register_nb_transport_fw(this, &Arbiter::nb_transport_fw); - - tSocket.register_transport_dbg(this, &Arbiter::transport_dbg); - } + Arbiter(sc_module_name); + SC_HAS_PROCESS(Arbiter); private: tlm_utils::peq_with_cb_and_phase payloadEventQueue; vector channelIsFree; - //used to account for the request_accept_delay in the dram controllers + // used to account for the request_accept_delay in the dram controllers // This is a queue of new transactions. The phase of a new request is BEGIN_REQ. vector> pendingRequests; - //used to account for the response_accept_delay in the initiators (traceplayer,core etc.) + // used to account for the response_accept_delay in the initiators (traceplayer, core etc.) // This is a queue of responses comming from the memory side. The phase of these transactions is BEGIN_RESP. std::map> receivedResponses; - //used to map the transaction from devices to the arbiter's target socket ID. - std::map routeMap; - - // Initiated by dram side - // This function is called when an arbiter's initiator socket receives a transaction from a memory controller - tlm_sync_enum nb_transport_bw(int channelId, tlm_generic_payload &payload, - tlm_phase &phase, sc_time &bwDelay) - { - // Check channel ID - if ((unsigned int)channelId != DramExtension::getExtension( - payload).getChannel().ID()) { - SC_REPORT_FATAL("Arbiter", "Payload extension was corrupted"); - } - - printDebugMessage("[bw] " + phaseNameToString(phase) + " notification in " + - bwDelay.to_string()); - payloadEventQueue.notify(payload, phase, bwDelay); - return TLM_ACCEPTED; - } - // Initiated by initiator side // This function is called when an arbiter's target socket receives a transaction from a device tlm_sync_enum nb_transport_fw(int id, tlm_generic_payload &payload, - tlm_phase &phase, sc_time &fwDelay) - { - sc_time notDelay = clkAlign(sc_time_stamp() + fwDelay) - - (sc_time_stamp() + fwDelay); - if (phase == BEGIN_REQ) { - // adjust address offset: - payload.set_address(payload.get_address() - - Configuration::getInstance().AddressOffset); + tlm_phase &phase, sc_time &fwDelay); - // Map the payload with socket id. - routeMap[&payload] = id; + // Initiated by dram side + // This function is called when an arbiter's initiator socket receives a transaction from a memory controller + tlm_sync_enum nb_transport_bw(int channelId, tlm_generic_payload &payload, + tlm_phase &phase, sc_time &bwDelay); - // In the begin request phase the socket ID is appended to the payload. - // It will extracted from the payload and used later. - appendDramExtension(id, payload); - payload.acquire(); - } else if (phase == END_RESP) { - notDelay += Configuration::getInstance().memSpec.clk; - // Erase before the payload is released. - routeMap.erase(&payload); - payload.release(); - } + virtual unsigned int transport_dbg(int /*id*/, tlm::tlm_generic_payload &trans); - printDebugMessage("[fw] " + phaseNameToString(phase) + " notification in " + - notDelay.to_string()); - payloadEventQueue.notify(payload, phase, notDelay); - return TLM_ACCEPTED; - } - - virtual unsigned int transport_dbg(int /*id*/, tlm::tlm_generic_payload &trans) - { - // adjust address offset: - trans.set_address(trans.get_address() - - Configuration::getInstance().AddressOffset); - - DecodedAddress decodedAddress = AddressDecoder::getInstance().decodeAddress( - trans.get_address()); - return iSocket[decodedAddress.channel]->transport_dbg(trans); - } - - void peqCallback(tlm_generic_payload &payload, const tlm_phase &phase) - { - unsigned int initiatorSocket = DramExtension::getExtension( - payload).getThread().ID(); - unsigned int channelId = DramExtension::getExtension(payload).getChannel().ID(); - - // Check the valid range of initiatorSocket ID and channel Id - assert(channelId < Configuration::getInstance().NumberOfMemChannels); - - // Phases initiated by the intiator side from arbiter's point of view (devices performing memory requests to the arbiter) - if (phase == BEGIN_REQ) { - if (channelIsFree[channelId]) { - // This channel was available. Forward the new transaction to the memory controller. - channelIsFree[channelId] = false; - sendToChannel(channelId, payload, phase, SC_ZERO_TIME); - } else { - // This channel is busy. Enqueue the new transaction which phase is BEGIN_REQ. - pendingRequests[channelId].push(&payload); - } - } else if (phase == END_RESP) { - // Send the END_RESP message to the memory - sendToChannel(channelId, payload, phase, SC_ZERO_TIME); - // Drop one element of the queue of BEGIN_RESP from memory to this device - receivedResponses[initiatorSocket].pop(); - - // Check if there are queued transactoins with phase BEGIN_RESP from memory to this device - if (!receivedResponses[initiatorSocket].empty()) { - // The queue is not empty. - tlm_generic_payload *payloadToSend = receivedResponses[initiatorSocket].front(); - // Send ONE extra BEGIN_RESP to the device - sendToInitiator(initiatorSocket, *payloadToSend, BEGIN_RESP, SC_ZERO_TIME); - } - } - - // Phases initiated by the target side from arbiter's point of view (memory side) - else if (phase == END_REQ) { - channelIsFree[channelId] = true; - // Validate the initiatorSocket ID - if ((int)initiatorSocket != routeMap[&payload]) { - SC_REPORT_FATAL("Arbiter", "Payload extension was corrupted"); - } - // The arbiter receives a transaction which phase is END_REQ from memory controller and forwards it to the requester device. - sendToInitiator(initiatorSocket, payload, phase, SC_ZERO_TIME); - - // This channel is now free! Dispatch a new transaction (phase is BEGIN_REQ) from the queue, if any. Send it to the memory controller. - if (!pendingRequests[channelId].empty()) { - tlm_generic_payload *payloadToSend = pendingRequests[channelId].front(); - pendingRequests[channelId].pop(); - // Send ONE of the enqueued new transactions (phase is BEGIN_REQ) through this channel. - sendToChannel(channelId, *payloadToSend, BEGIN_REQ, SC_ZERO_TIME); - // Mark the channel as busy again. - channelIsFree[channelId] = false; - } - } else if (phase == BEGIN_RESP) { - // Validate the initiatorSocket ID - if ((int)initiatorSocket != routeMap[&payload]) { - SC_REPORT_FATAL("Arbiter", "Payload extension was corrupted"); - } - // The arbiter receives a transaction in BEGIN_RESP phase - // (that came from the memory side) and forwards it to the requester - // device - if (receivedResponses[initiatorSocket].empty()) { - sendToInitiator(initiatorSocket, payload, phase, SC_ZERO_TIME); - } - // Enqueue the transaction in BEGIN_RESP phase until the initiator - // device acknowledge it (phase changes to END_RESP). - receivedResponses[initiatorSocket].push(&payload); - } else { - SC_REPORT_FATAL(0, - "Payload event queue in arbiter was triggered with unknown phase"); - } - } + void peqCallback(tlm_generic_payload &payload, const tlm_phase &phase); void sendToChannel(unsigned int channelId, tlm_generic_payload &payload, - const tlm_phase &phase, const sc_time &delay) - { - tlm_phase TPhase = phase; - sc_time TDelay = delay; - iSocket[channelId]->nb_transport_fw(payload, TPhase, TDelay); - } + const tlm_phase &phase, const sc_time &delay); void sendToInitiator(unsigned int id, tlm_generic_payload &payload, - const tlm_phase &phase, const sc_time &delay) - { - tlm_phase TPhase = phase; - sc_time TDelay = delay; - tSocket[id]->nb_transport_bw(payload, TPhase, TDelay); - } + const tlm_phase &phase, const sc_time &delay); - void appendDramExtension(int socketId, tlm_generic_payload &payload) - { - // Append Generation Extension - GenerationExtension *genExtension = new GenerationExtension(sc_time_stamp()); - payload.set_auto_extension(genExtension); + void appendDramExtension(int socketId, tlm_generic_payload &payload); - unsigned int burstlength = payload.get_streaming_width(); - DecodedAddress decodedAddress = AddressDecoder::getInstance().decodeAddress( - payload.get_address()); - // Check the valid range of decodedAddress - if (addressIsValid(decodedAddress)) { - DramExtension *extension = new DramExtension(Thread(socketId), - Channel(decodedAddress.channel), Bank(decodedAddress.bank), - BankGroup(decodedAddress.bankgroup), Row(decodedAddress.row), - Column(decodedAddress.column), burstlength); - payload.set_auto_extension(extension); - } else { - SC_REPORT_FATAL("Arbiter", "Decoded Address are not inside the valid range"); - } - } + bool addressIsValid(DecodedAddress &decodedAddress); - bool addressIsValid(DecodedAddress &decodedAddress) - { - if (decodedAddress.channel >= AddressDecoder::getInstance().amount["channel"]) { - return false; - } - if (decodedAddress.bank >= AddressDecoder::getInstance().amount["bank"]) { - return false; - } - if (decodedAddress.bankgroup > - AddressDecoder::getInstance().amount["bankgroup"]) { - return false; - } - if (decodedAddress.column >= AddressDecoder::getInstance().amount["column"]) { - return false; - } - if (decodedAddress.row >= AddressDecoder::getInstance().amount["row"]) { - return false; - } - return true; - } - - void printDebugMessage(std::string message) - { - DebugManager::getInstance().printDebugMessage(this->name(), message); - } + void printDebugMessage(std::string message); }; -#endif /* ARBITER_H_ */ +#endif // ARBITER_H diff --git a/DRAMSys/library/src/simulation/DRAMSys.cpp b/DRAMSys/library/src/simulation/DRAMSys.cpp index 161bb210..8ee7792f 100644 --- a/DRAMSys/library/src/simulation/DRAMSys.cpp +++ b/DRAMSys/library/src/simulation/DRAMSys.cpp @@ -46,14 +46,18 @@ #include "Setup.h" #include "../common/TlmRecorder.h" #include "../common/DebugManager.h" -#include "../common/xmlAddressdecoder.h" -#include "../common/congenAddressDecoder.h" +#include "../common/XmlAddressDecoder.h" +#include "../common/CongenAddressDecoder.h" #include "../controller/core/ControllerCore.h" #include "../controller/core/configuration/ConfigurationLoader.h" -#include "../common/Utils.h" +#include "../common/utils.h" #include "../simulation/TemperatureController.h" #include "../controller/Controller.h" #include "../error/ecchamming.h" +#include "DramRecordable.h" +#include "DramDDR3.h" +#include "DramDDR4.h" +#include "DramWideIO.h" using namespace std; @@ -86,7 +90,7 @@ DRAMSys::DRAMSys(sc_module_name __attribute__((unused)) name, // ConfigurationLoader because some information from the xmlAddressDecoder // is needed to assure the coherence of the configuration. - if (xmlAddressDecoder::testConfigFile(pathToResources + "configs/amconfigs/" + + if (XmlAddressDecoder::testConfigFile(pathToResources + "configs/amconfigs/" + amconfig)) { AddressDecoder::createInstance(AddressDecoder::Type::XML); AddressDecoder::getInstance().setConfiguration(pathToResources @@ -175,7 +179,7 @@ void DRAMSys::logo() void DRAMSys::setupDebugManager(const string &traceName) { auto &dbg = DebugManager::getInstance(); - dbg.writeToConsole = true; + dbg.writeToConsole = false; dbg.writeToFile = true; if (dbg.writeToFile) dbg.openDebugFile(traceName + ".txt"); @@ -242,6 +246,7 @@ void DRAMSys::instantiateModules(const string &traceName, arbiter = new Arbiter("arbiter"); // Create DRAM + std::string memoryType = Configuration::getInstance().memSpec->MemoryType; for (size_t i = 0; i < Configuration::getInstance().NumberOfMemChannels; i++) { @@ -256,11 +261,32 @@ void DRAMSys::instantiateModules(const string &traceName, str = "dram" + std::to_string(i); Dram *dram; - if (recordingEnabled) - dram = new RecordableDram(str.c_str(), tlmRecorders[i]); + + if (memoryType == "DDR3") + { + if (recordingEnabled) + dram = new DramRecordable(str.c_str(), tlmRecorders[i]); + else + dram = new DramDDR3(str.c_str()); + } + else if (memoryType == "DDR4") + { + if (recordingEnabled) + dram = new DramRecordable(str.c_str(), tlmRecorders[i]); + else + dram = new DramDDR4(str.c_str()); + } + else if (memoryType == "WIDEIO_SDR") + { + if (recordingEnabled) + dram = new DramRecordable(str.c_str(), tlmRecorders[i]); + else + dram = new DramWideIO(str.c_str()); + } else - dram = new Dram(str.c_str()); - dram->setDramController(controllers[i]); + { + SC_REPORT_FATAL("DRAMSys", "Unsupported DRAM type"); + } drams.push_back(dram); if (Configuration::getInstance().CheckTLM2Protocol) { @@ -317,6 +343,10 @@ DRAMSys::~DRAMSys() delete rec; } + for (auto tlmChecker : playersTlmCheckers) { + delete tlmChecker; + } + for (auto tlmChecker : controllersTlmCheckers) { delete tlmChecker; } diff --git a/DRAMSys/library/src/simulation/DRAMSys.h b/DRAMSys/library/src/simulation/DRAMSys.h index 25bf4bad..288820e8 100644 --- a/DRAMSys/library/src/simulation/DRAMSys.h +++ b/DRAMSys/library/src/simulation/DRAMSys.h @@ -36,8 +36,8 @@ * Felipe S. Prado */ -#ifndef DRAMSYS_H_ -#define DRAMSYS_H_ +#ifndef DRAMSYS_H +#define DRAMSYS_H #include #include @@ -53,11 +53,14 @@ #include "../common/tlm2_base_protocol_checker.h" #include "../error/eccbaseclass.h" -class DRAMSys: public sc_module +class DRAMSys : public sc_module { public: tlm_utils::multi_passthrough_target_socket tSocket; + std::vector*> + playersTlmCheckers; + sc_event terminateSimulation; SC_HAS_PROCESS(DRAMSys); @@ -105,4 +108,4 @@ private: void setupDebugManager(const string &traceName); }; -#endif /* SIMULATIONMANAGER_H_ */ +#endif // DRAMSYS_H diff --git a/DRAMSys/library/src/simulation/Dram.cpp b/DRAMSys/library/src/simulation/Dram.cpp new file mode 100644 index 00000000..cc391efc --- /dev/null +++ b/DRAMSys/library/src/simulation/Dram.cpp @@ -0,0 +1,420 @@ +/* + * Copyright (c) 2015, University of Kaiserslautern + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER + * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Authors: + * Robert Gernhardt + * Matthias Jung + * Peter Ehses + * Eder F. Zulian + * Felipe S. Prado + */ + +#include "Dram.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "../common/DebugManager.h" +#include "../common/dramExtensions.h" +#include "../controller/Controller.h" +#include "../controller/core/timingCalculations.h" +#include "../controller/core/configuration/Configuration.h" +#include "../common/protocol.h" +#include "../common/utils.h" +#include "../common/third_party/DRAMPower/src/libdrampower/LibDRAMPower.h" + +using namespace std; +using namespace tlm; +using namespace Data; + +Dram::Dram(sc_module_name) : tSocket("socket") +{ + // Adjust number of bytes per burst dynamically to the selected ecc controller + bytesPerBurst = Configuration::getInstance() + .adjustNumBytesAfterECC(bytesPerBurst); + + tSocket.register_nb_transport_fw(this, &Dram::nb_transport_fw); + tSocket.register_transport_dbg(this, &Dram::transport_dbg); + + // Parameters for DRAMPower + sc_time clk = Configuration::getInstance().memSpec->clk; + + MemArchitectureSpec memArchSpec; + memArchSpec.burstLength = + Configuration::getInstance().memSpec->BurstLength; + memArchSpec.dataRate = Configuration::getInstance().memSpec->DataRate; + memArchSpec.nbrOfRows = + Configuration::getInstance().memSpec->NumberOfRows; + memArchSpec.nbrOfBanks = + Configuration::getInstance().memSpec->NumberOfBanks; + memArchSpec.nbrOfColumns = + Configuration::getInstance().memSpec->NumberOfColumns; + memArchSpec.nbrOfRanks = + Configuration::getInstance().memSpec->NumberOfRanks; + memArchSpec.width = Configuration::getInstance().memSpec->bitWidth; + memArchSpec.nbrOfBankGroups = + Configuration::getInstance().memSpec->NumberOfBankGroups; + memArchSpec.twoVoltageDomains = (Configuration::getInstance().memSpec->vDD2 == 0 + ? false : true); + memArchSpec.dll = Configuration::getInstance().memSpec->DLL; + + MemTimingSpec memTimingSpec; + memTimingSpec.FAWB = Configuration::getInstance().tfawbclk; + memTimingSpec.RASB = Configuration::getInstance().trasbclk; + memTimingSpec.RCB = Configuration::getInstance().trcbclk; + memTimingSpec.RPB = Configuration::getInstance().trpbclk; + memTimingSpec.RRDB = Configuration::getInstance().trrdblclk; + memTimingSpec.RRDB_L = Configuration::getInstance().trrdblclk; + memTimingSpec.RRDB_S = Configuration::getInstance().trrdblclk; + memTimingSpec.AL = Configuration::getInstance().memSpec->tAL / clk; + memTimingSpec.CCD = Configuration::getInstance().memSpec->tCCD_S / clk; + memTimingSpec.CCD_L = Configuration::getInstance().memSpec->tCCD_L / clk; + memTimingSpec.CCD_S = Configuration::getInstance().memSpec->tCCD_S / clk; + memTimingSpec.CKE = Configuration::getInstance().memSpec->tCKE / clk; + memTimingSpec.CKESR = Configuration::getInstance().memSpec->tCKESR / clk; + memTimingSpec.clkMhz = Configuration::getInstance().memSpec->clkMHz; + // See also MemTimingSpec.cc in DRAMPower + memTimingSpec.clkPeriod = 1000.0 / Configuration::getInstance().memSpec->clkMHz; + memTimingSpec.DQSCK = Configuration::getInstance().memSpec->tDQSCK / clk; + memTimingSpec.FAW = Configuration::getInstance().memSpec->tNAW / clk; + memTimingSpec.RAS = Configuration::getInstance().memSpec->tRAS / clk; + memTimingSpec.RC = Configuration::getInstance().memSpec->tRC / clk; + memTimingSpec.RCD = Configuration::getInstance().memSpec->tRCD / clk; + memTimingSpec.REFI = Configuration::getInstance().memSpec->tREFI / clk; + auto m = Configuration::getInstance().getRefMode(); + if (m == 4) + memTimingSpec.RFC = Configuration::getInstance().memSpec->tRFC4 / clk; + else if (m == 2) + memTimingSpec.RFC = Configuration::getInstance().memSpec->tRFC2 / clk; + else + memTimingSpec.RFC = Configuration::getInstance().memSpec->tRFC / clk; + memTimingSpec.RL = Configuration::getInstance().memSpec->tRL / clk; + memTimingSpec.RP = Configuration::getInstance().memSpec->tRP / clk; + memTimingSpec.RRD = Configuration::getInstance().memSpec->tRRD_S / clk; + memTimingSpec.RRD_L = Configuration::getInstance().memSpec->tRRD_L / clk; + memTimingSpec.RRD_S = Configuration::getInstance().memSpec->tRRD_S / clk; + memTimingSpec.RTP = Configuration::getInstance().memSpec->tRTP / clk; + memTimingSpec.TAW = Configuration::getInstance().memSpec->tNAW / clk; + memTimingSpec.WL = Configuration::getInstance().memSpec->tWL / clk; + memTimingSpec.WR = Configuration::getInstance().memSpec->tWR / clk; + memTimingSpec.WTR = Configuration::getInstance().memSpec->tWTR_S / clk; + memTimingSpec.WTR_L = Configuration::getInstance().memSpec->tWTR_L / clk; + memTimingSpec.WTR_S = Configuration::getInstance().memSpec->tWTR_S / clk; + memTimingSpec.XP = Configuration::getInstance().memSpec->tXP / clk; + memTimingSpec.XPDLL = Configuration::getInstance().memSpec->tXPDLL / clk; + memTimingSpec.XS = Configuration::getInstance().memSpec->tXSR / clk; + memTimingSpec.XSDLL = Configuration::getInstance().memSpec->tXSRDLL / clk; + + MemPowerSpec memPowerSpec; + memPowerSpec.idd0 = Configuration::getInstance().memSpec->iDD0; + memPowerSpec.idd02 = Configuration::getInstance().memSpec->iDD02; + memPowerSpec.idd2p0 = Configuration::getInstance().memSpec->iDD2P0; + memPowerSpec.idd2p02 = Configuration::getInstance().memSpec->iDD2P02; + memPowerSpec.idd2p1 = Configuration::getInstance().memSpec->iDD2P1; + memPowerSpec.idd2p12 = Configuration::getInstance().memSpec->iDD2P12; + memPowerSpec.idd2n = Configuration::getInstance().memSpec->iDD2N; + memPowerSpec.idd2n2 = Configuration::getInstance().memSpec->iDD2N2; + memPowerSpec.idd3p0 = Configuration::getInstance().memSpec->iDD3P0; + memPowerSpec.idd3p02 = Configuration::getInstance().memSpec->iDD3P02; + memPowerSpec.idd3p1 = Configuration::getInstance().memSpec->iDD3P1; + memPowerSpec.idd3p12 = Configuration::getInstance().memSpec->iDD3P12; + memPowerSpec.idd3n = Configuration::getInstance().memSpec->iDD3N; + memPowerSpec.idd3n2 = Configuration::getInstance().memSpec->iDD3N2; + memPowerSpec.idd4r = Configuration::getInstance().memSpec->iDD4R; + memPowerSpec.idd4r2 = Configuration::getInstance().memSpec->iDD4R2; + memPowerSpec.idd4w = Configuration::getInstance().memSpec->iDD4W; + memPowerSpec.idd4w2 = Configuration::getInstance().memSpec->iDD4W2; + memPowerSpec.idd5 = Configuration::getInstance().memSpec->iDD5; + memPowerSpec.idd52 = Configuration::getInstance().memSpec->iDD52; + memPowerSpec.idd6 = Configuration::getInstance().memSpec->iDD6; + memPowerSpec.idd62 = Configuration::getInstance().memSpec->iDD62; + memPowerSpec.vdd = Configuration::getInstance().memSpec->vDD; + memPowerSpec.vdd2 = Configuration::getInstance().memSpec->vDD2; + + MemorySpecification memSpec; + memSpec.id = Configuration::getInstance().memSpec->MemoryId; + memSpec.memoryType = Configuration::getInstance().memSpec->MemoryType; + memSpec.memTimingSpec = memTimingSpec; + memSpec.memPowerSpec = memPowerSpec; + memSpec.memArchSpec = memArchSpec; + + DRAMPower = new libDRAMPower(memSpec, 0); +} + +Dram::~Dram() +{ + if (!Configuration::getInstance().DatabaseRecording) + DRAMPower->calcEnergy(); + + // Print the final total energy and the average power for + // the simulation: + cout << name() << string(" Total Energy: ") + << fixed << std::setprecision( 2 ) + << DRAMPower->getEnergy().total_energy + * Configuration::getInstance().NumberOfDevicesOnDIMM + << string(" pJ") + << endl; + + cout << name() << string(" Average Power: ") + << fixed << std::setprecision( 2 ) + << DRAMPower->getPower().average_power + * Configuration::getInstance().NumberOfDevicesOnDIMM + << string(" mW") << endl; + + if (Configuration::getInstance().UseMalloc) + free(memory); +} + +tlm_sync_enum Dram::nb_transport_fw(tlm_generic_payload &payload, + tlm_phase &phase, sc_time &delay) +{ + unsigned int bank = DramExtension::getExtension(payload).getBank().ID(); + + // This is only needed for power simulation: + unsigned long long cycle = sc_time_stamp().value() / + Configuration::getInstance().memSpec->clk.value(); + + if (phase == BEGIN_PREB) + { + DRAMPower->doCommand(MemCommand::PREB, bank, cycle); + sendToController(payload, END_PREB, delay + getExecutionTime(Command::PreB, + payload)); + } + else if (phase == BEGIN_PRE) + { + DRAMPower->doCommand(MemCommand::PRE, bank, cycle); + sendToController(payload, END_PRE, delay + getExecutionTime(Command::Precharge, + payload)); + } + else if (phase == BEGIN_PRE_ALL) + { + DRAMPower->doCommand(MemCommand::PREA, bank, cycle); + sendToController(payload, END_PRE_ALL, + delay + getExecutionTime(Command::PrechargeAll, payload)); + } + else if (phase == BEGIN_ACTB) + { + DRAMPower->doCommand(MemCommand::ACTB, bank, cycle); + sendToController(payload, END_ACTB, delay + getExecutionTime(Command::ActB, + payload)); + } + else if (phase == BEGIN_ACT) + { + DRAMPower->doCommand(MemCommand::ACT, bank, cycle); + sendToController(payload, END_ACT, delay + getExecutionTime(Command::Activate, + payload)); + } + else if (phase == BEGIN_WR) + { + DRAMPower->doCommand(MemCommand::WR, bank, cycle); + // save data: + if (StoreMode == StorageMode::Store) // Use Storage + { + unsigned char *phyAddr = memory + payload.get_address(); + memcpy(phyAddr, payload.get_data_ptr(), payload.get_data_length()); + } + sendToController(payload, END_WR, delay + getExecutionTime(Command::Write, + payload)); + } + else if (phase == BEGIN_RD) + { + DRAMPower->doCommand(MemCommand::RD, bank, cycle); + // load data: + if (StoreMode == StorageMode::Store) // use StorageMode + { + unsigned char *phyAddr = memory + payload.get_address(); + memcpy(payload.get_data_ptr(), phyAddr, payload.get_data_length()); + } + sendToController(payload, END_RD, delay + getExecutionTime(Command::Read, + payload)); + } + else if (phase == BEGIN_WRA) + { + DRAMPower->doCommand(MemCommand::WRA, bank, cycle); + // save data: + if (StoreMode == StorageMode::Store) // Use Storage + { + unsigned char *phyAddr = memory + payload.get_address(); + memcpy(phyAddr, payload.get_data_ptr(), payload.get_data_length()); + } + sendToController(payload, END_WRA, delay + getExecutionTime(Command::WriteA, + payload)); + } + else if (phase == BEGIN_RDA) + { + DRAMPower->doCommand(MemCommand::RDA, bank, cycle); + // Load data: + if (StoreMode == StorageMode::Store) // use StorageMode + { + unsigned char *phyAddr = memory + payload.get_address(); + memcpy(payload.get_data_ptr(), phyAddr, payload.get_data_length()); + } + sendToController(payload, END_RDA, delay + getExecutionTime(Command::ReadA, + payload)); + } + else if (phase == BEGIN_REFA) + { + DRAMPower->doCommand(MemCommand::REF, bank, cycle); + sendToController(payload, END_REFA, + delay + getExecutionTime(Command::AutoRefresh, payload)); + } + else if (phase == BEGIN_REFB) + { + DRAMPower->doCommand(MemCommand::REFB, bank, cycle); + sendToController(payload, END_REFB, + delay + getExecutionTime(Command::AutoRefresh, payload)); + } + // Powerdown phases have to be started and ended by the controller, because they do not have a fixed length + else if (phase == BEGIN_PDNA) + { + DRAMPower->doCommand(MemCommand::PDN_S_ACT, bank, cycle); + } + else if (phase == END_PDNA) + { + DRAMPower->doCommand(MemCommand::PUP_ACT, bank, cycle); + } + else if (phase == BEGIN_PDNAB) + { + SC_REPORT_FATAL("DRAM", "Power calculation for bankwise logic not supported"); + } + else if (phase == END_PDNAB) + { + SC_REPORT_FATAL("DRAM", "Power calculation for bankwise logic not supported"); + } + else if (phase == BEGIN_PDNP) + { + DRAMPower->doCommand(MemCommand::PDN_S_PRE, bank, cycle); + } + else if (phase == END_PDNP) + { + DRAMPower->doCommand(MemCommand::PUP_PRE, bank, cycle); + } + else if (phase == BEGIN_PDNPB) + { + SC_REPORT_FATAL("DRAM", "Power calculation for bankwise logic not supported"); + } + else if (phase == END_PDNPB) + { + SC_REPORT_FATAL("DRAM", "Power calculation for bankwise logic not supported"); + } + else if (phase == BEGIN_SREF) + { + DRAMPower->doCommand(MemCommand::SREN, bank, cycle); + } + else if (phase == END_SREF) + { + DRAMPower->doCommand(MemCommand::SREX, bank, cycle); + } + else if (phase == BEGIN_SREFB) + { + SC_REPORT_FATAL("DRAM", "Power calculation for bankwise logic not supported"); + } + else if (phase == END_SREFB) + { + SC_REPORT_FATAL("DRAM", "Power calculation for bankwise logic not supported"); + } + else + { + SC_REPORT_FATAL("DRAM", "DRAM PEQ was called with unknown phase"); + } + + return TLM_ACCEPTED; +} + +unsigned int Dram::transport_dbg(tlm_generic_payload &trans) +{ + printDebugMessage("transport_dgb"); + + // TODO: This part is not tested yet, neither with traceplayers nor with GEM5 coupling + if (StoreMode == StorageMode::NoStorage) + { + SC_REPORT_FATAL("DRAM", + "Debug Transport is used in combination with NoStorage"); + } + else + { + tlm_command cmd = trans.get_command(); + //sc_dt::uint64 adr = trans.get_address(); // TODO: - offset; + unsigned char *ptr = trans.get_data_ptr(); + unsigned int len = trans.get_data_length(); + //unsigned int bank = DramExtension::getExtension(trans).getBank().ID(); + + //cout << "cmd " << (cmd ? "write" : "read") << " adr " << hex << adr << " len " << len << endl; + + if (cmd == TLM_READ_COMMAND) + { + if (StoreMode == StorageMode::Store) + { // Use Storage + unsigned char *phyAddr = memory + trans.get_address(); + memcpy(ptr, phyAddr, trans.get_data_length()); + } + else + { + //ememory[bank]->load(trans); + SC_REPORT_FATAL("DRAM", "Debug transport not supported with error model yet."); + } + } + else if (cmd == TLM_WRITE_COMMAND) + { + if (StoreMode == StorageMode::Store) + { // Use Storage + unsigned char *phyAddr = memory + trans.get_address(); + memcpy(phyAddr, ptr, trans.get_data_length()); + } + else + { + //ememory[bank]->store(trans); + SC_REPORT_FATAL("DRAM", "Debug transport not supported with error model yet."); + } + } + return len; + } + return 0; +} + +void Dram::sendToController(tlm_generic_payload &payload, const tlm_phase &phase, + const sc_time &delay) +{ + tlm_phase TPhase = phase; + sc_time TDelay = delay; + tSocket->nb_transport_bw(payload, TPhase, TDelay); +} + +void Dram::printDebugMessage(string message) +{ + DebugManager::getInstance().printDebugMessage(name(), message); +} diff --git a/DRAMSys/library/src/simulation/Dram.h b/DRAMSys/library/src/simulation/Dram.h index 7c383498..372df02c 100644 --- a/DRAMSys/library/src/simulation/Dram.h +++ b/DRAMSys/library/src/simulation/Dram.h @@ -37,551 +37,53 @@ * Felipe S. Prado */ -#ifndef DRAM_H_ -#define DRAM_H_ +#ifndef DRAM_H +#define DRAM_H -#include #include #include -#include #include -#include -#include -#include -#include -#include -#include "../common/DebugManager.h" -#include "../common/dramExtension.h" #include "../controller/Controller.h" -#include "../controller/core/TimingCalculation.h" #include "../controller/core/configuration/Configuration.h" -#include "../common/protocol.h" -#include "../common/Utils.h" #include "../common/third_party/DRAMPower/src/libdrampower/LibDRAMPower.h" -#include "../error/errormodel.h" using namespace std; using namespace tlm; using namespace Data; -struct Dram : sc_module { +class Dram : public sc_module +{ +private: unsigned int bytesPerBurst = Configuration::getInstance().getBytesPerBurst(); - // TLM Related: - tlm_utils::simple_target_socket tSocket; - // Power Model related bool powerAnalysis = Configuration::getInstance().PowerAnalysis; - libDRAMPower *DRAMPower; - - // Bandwidth realted: - unsigned long long int numberOfTransactionsServed; - sc_time firstAccess; - sc_time lastAccess; - - // Error Model related: - StorageMode StoreMode = Configuration::getInstance().StoreMode; - std::vector ememory; +protected: // Data Storage: + StorageMode StoreMode = Configuration::getInstance().StoreMode; unsigned char *memory; - Controller *dramController; + libDRAMPower *DRAMPower; - SC_CTOR(Dram) : tSocket("socket") - { - // Adjust number of bytes per burst dynamically to the selected ecc controller - bytesPerBurst = Configuration::getInstance().adjustNumBytesAfterECC( - bytesPerBurst); - dramController = NULL; + virtual tlm_sync_enum nb_transport_fw(tlm_generic_payload &payload, + tlm_phase &phase, sc_time &delay); - std::uint64_t memorySize = Configuration::getInstance().getSimMemSizeInBytes(); - if (Configuration::getInstance().UseMalloc) { - memory = (unsigned char *)malloc(memorySize); - if (!memory) { - SC_REPORT_FATAL(this->name(), "Memory allocation failed"); - } - } else { - // allocate and model storage of one DRAM channel using memory map - memory = (unsigned char *)mmap(NULL, memorySize, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANON | MAP_NORESERVE, -1, 0); - } - - tSocket.register_nb_transport_fw(this, &Dram::nb_transport_fw); - tSocket.register_transport_dbg(this, &Dram::transport_dbg); - - if (powerAnalysis == true) { - sc_time clk = Configuration::getInstance().memSpec.clk; - - MemArchitectureSpec memArchSpec; - memArchSpec.burstLength = - Configuration::getInstance().memSpec.BurstLength; - memArchSpec.dataRate = Configuration::getInstance().memSpec.DataRate; - memArchSpec.nbrOfRows = - Configuration::getInstance().memSpec.NumberOfRows; - memArchSpec.nbrOfBanks = - Configuration::getInstance().memSpec.NumberOfBanks; - memArchSpec.nbrOfColumns = - Configuration::getInstance().memSpec.NumberOfColumns; - memArchSpec.nbrOfRanks = - Configuration::getInstance().memSpec.NumberOfRanks; - memArchSpec.width = Configuration::getInstance().memSpec.bitWidth; - memArchSpec.nbrOfBankGroups = - Configuration::getInstance().memSpec.NumberOfBankGroups; - memArchSpec.twoVoltageDomains = (Configuration::getInstance().memSpec.vDD2 == 0 - ? false : true); - memArchSpec.dll = Configuration::getInstance().memSpec.DLL; - - MemTimingSpec memTimingSpec; - memTimingSpec.FAWB = Configuration::getInstance().tfawbclk; - memTimingSpec.RASB = Configuration::getInstance().trasbclk; - memTimingSpec.RCB = Configuration::getInstance().trcbclk; - memTimingSpec.RPB = Configuration::getInstance().trpbclk; - memTimingSpec.RRDB = Configuration::getInstance().trrdblclk; - memTimingSpec.RRDB_L = Configuration::getInstance().trrdblclk; - memTimingSpec.RRDB_S = Configuration::getInstance().trrdblclk; - memTimingSpec.AL = Configuration::getInstance().memSpec.tAL / clk; - memTimingSpec.CCD = Configuration::getInstance().memSpec.tCCD_S / clk; - memTimingSpec.CCD_L = Configuration::getInstance().memSpec.tCCD_L / clk; - memTimingSpec.CCD_S = Configuration::getInstance().memSpec.tCCD_S / clk; - memTimingSpec.CKE = Configuration::getInstance().memSpec.tCKE / clk; - memTimingSpec.CKESR = Configuration::getInstance().memSpec.tCKESR / clk; - memTimingSpec.clkMhz = Configuration::getInstance().memSpec.clkMHz; - // See also MemTimingSpec.cc in DRAMPower - memTimingSpec.clkPeriod = 1000.0 / Configuration::getInstance().memSpec.clkMHz; - memTimingSpec.DQSCK = Configuration::getInstance().memSpec.tDQSCK / clk; - memTimingSpec.FAW = Configuration::getInstance().memSpec.tNAW / clk; - memTimingSpec.RAS = Configuration::getInstance().memSpec.tRAS / clk; - memTimingSpec.RC = Configuration::getInstance().memSpec.tRC / clk; - memTimingSpec.RCD = Configuration::getInstance().memSpec.tRCD / clk; - memTimingSpec.REFI = Configuration::getInstance().memSpec.tREFI / clk; - auto m = Configuration::getInstance().getRefMode(); - if (m == 4) - memTimingSpec.RFC = Configuration::getInstance().memSpec.tRFC4 / clk; - else if (m == 2) - memTimingSpec.RFC = Configuration::getInstance().memSpec.tRFC2 / clk; - else - memTimingSpec.RFC = Configuration::getInstance().memSpec.tRFC / clk; - memTimingSpec.RL = Configuration::getInstance().memSpec.tRL / clk; - memTimingSpec.RP = Configuration::getInstance().memSpec.tRP / clk; - memTimingSpec.RRD = Configuration::getInstance().memSpec.tRRD_S / clk; - memTimingSpec.RRD_L = Configuration::getInstance().memSpec.tRRD_L / clk; - memTimingSpec.RRD_S = Configuration::getInstance().memSpec.tRRD_S / clk; - memTimingSpec.RTP = Configuration::getInstance().memSpec.tRTP / clk; - memTimingSpec.TAW = Configuration::getInstance().memSpec.tNAW / clk; - memTimingSpec.WL = Configuration::getInstance().memSpec.tWL / clk; - memTimingSpec.WR = Configuration::getInstance().memSpec.tWR / clk; - memTimingSpec.WTR = Configuration::getInstance().memSpec.tWTR_S / clk; - memTimingSpec.WTR_L = Configuration::getInstance().memSpec.tWTR_L / clk; - memTimingSpec.WTR_S = Configuration::getInstance().memSpec.tWTR_S / clk; - memTimingSpec.XP = Configuration::getInstance().memSpec.tXP / clk; - memTimingSpec.XPDLL = Configuration::getInstance().memSpec.tXPDLL / clk; - memTimingSpec.XS = Configuration::getInstance().memSpec.tXSR / clk; - memTimingSpec.XSDLL = Configuration::getInstance().memSpec.tXSRDLL / clk; - - MemPowerSpec memPowerSpec; - memPowerSpec.idd0 = Configuration::getInstance().memSpec.iDD0; - memPowerSpec.idd02 = Configuration::getInstance().memSpec.iDD02; - memPowerSpec.idd2p0 = Configuration::getInstance().memSpec.iDD2P0; - memPowerSpec.idd2p02 = Configuration::getInstance().memSpec.iDD2P02; - memPowerSpec.idd2p1 = Configuration::getInstance().memSpec.iDD2P1; - memPowerSpec.idd2p12 = Configuration::getInstance().memSpec.iDD2P12; - memPowerSpec.idd2n = Configuration::getInstance().memSpec.iDD2N; - memPowerSpec.idd2n2 = Configuration::getInstance().memSpec.iDD2N2; - memPowerSpec.idd3p0 = Configuration::getInstance().memSpec.iDD3P0; - memPowerSpec.idd3p02 = Configuration::getInstance().memSpec.iDD3P02; - memPowerSpec.idd3p1 = Configuration::getInstance().memSpec.iDD3P1; - memPowerSpec.idd3p12 = Configuration::getInstance().memSpec.iDD3P12; - memPowerSpec.idd3n = Configuration::getInstance().memSpec.iDD3N; - memPowerSpec.idd3n2 = Configuration::getInstance().memSpec.iDD3N2; - memPowerSpec.idd4r = Configuration::getInstance().memSpec.iDD4R; - memPowerSpec.idd4r2 = Configuration::getInstance().memSpec.iDD4R2; - memPowerSpec.idd4w = Configuration::getInstance().memSpec.iDD4W; - memPowerSpec.idd4w2 = Configuration::getInstance().memSpec.iDD4W2; - memPowerSpec.idd5 = Configuration::getInstance().memSpec.iDD5; - memPowerSpec.idd52 = Configuration::getInstance().memSpec.iDD52; - memPowerSpec.idd6 = Configuration::getInstance().memSpec.iDD6; - memPowerSpec.idd62 = Configuration::getInstance().memSpec.iDD62; - memPowerSpec.vdd = Configuration::getInstance().memSpec.vDD; - memPowerSpec.vdd2 = Configuration::getInstance().memSpec.vDD2; - - MemorySpecification memSpec; - memSpec.id = Configuration::getInstance().memSpec.MemoryId; - memSpec.memoryType = Configuration::getInstance().memSpec.MemoryType; - memSpec.memTimingSpec = memTimingSpec; - memSpec.memPowerSpec = memPowerSpec; - memSpec.memArchSpec = memArchSpec; - - DRAMPower = new libDRAMPower( memSpec, 0 ); - } - - // Bandwidth Calculation: - numberOfTransactionsServed = 0; - firstAccess = SC_ZERO_TIME; - lastAccess = SC_ZERO_TIME; - - // For each bank in a channel a error Model is created: - if (StoreMode == StorageMode::ErrorModel) { - for (unsigned i = 0; i < Configuration::getInstance().memSpec.NumberOfBanks; - i++) { - errorModel *em; - std::string errorModelStr = "errorModel_bank" + std::to_string(i); - if (powerAnalysis == true) { - em = new errorModel(errorModelStr.c_str(), DRAMPower); - } else { - em = new errorModel(errorModelStr.c_str()); - } - ememory.push_back(em); - } - } - } - - virtual void end_of_simulation() - { - } - - ~Dram() - { - if (powerAnalysis == true) { - if (!Configuration::getInstance().DatabaseRecording) - DRAMPower->calcEnergy(); - - // Print the final total energy and the average power for - // the simulation: - cout << name() << string(" Total Energy: ") - << fixed << std::setprecision( 2 ) - << DRAMPower->getEnergy().total_energy - * Configuration::getInstance().NumberOfDevicesOnDIMM - << string(" pJ") - << endl; - - cout << name() << string(" Average Power: ") - << fixed << std::setprecision( 2 ) - << DRAMPower->getPower().average_power - * Configuration::getInstance().NumberOfDevicesOnDIMM - << string(" mW") << endl; - } - - // Bandwidth: - - sc_time activeTime = numberOfTransactionsServed - * Configuration::getInstance().memSpec.BurstLength - / Configuration::getInstance().memSpec.DataRate - * Configuration::getInstance().memSpec.clk; - - sc_time idleTime = dramController->getIdleTime(); - sc_time endTime = dramController->getEndTime(); - sc_time startTime = dramController->getStartTime(); - - double bandwidth = (activeTime / (endTime - startTime) * 100); - double bandwidth_IDLE = ((activeTime) / (endTime - startTime - idleTime) * 100); - - double maxBandwidth = ( - // clk in Mhz e.g. 800 [MHz]: - (1000000 / Configuration::getInstance().memSpec.clk.to_double()) - // DataRate e.g. 2 - * Configuration::getInstance().memSpec.DataRate - // BusWidth e.g. 8 or 64 - * Configuration::getInstance().memSpec.bitWidth - // Number of devices on a DIMM e.g. 8 - * Configuration::getInstance().NumberOfDevicesOnDIMM ) / ( 1024 ); - - cout << name() << string(" Total Time: ") - << (endTime - startTime).to_string() - << endl; - cout << name() << string(" AVG BW: ") - << std::fixed << std::setprecision(2) - << ((bandwidth / 100)*maxBandwidth) - << " Gibit/s (" << bandwidth << " %)" - << endl; - cout << name() << string(" AVG BW/IDLE: ") - << std::fixed << std::setprecision(2) - << ((bandwidth_IDLE / 100)*maxBandwidth) - << " Gibit/s (" << (bandwidth_IDLE) << " %)" - << endl; - cout << name() << string(" MAX BW: ") - << std::fixed << std::setprecision(2) - << maxBandwidth << " Gibit/s" - << endl; - // Clean up: - for (auto e : ememory) { - delete e; - } - - if (Configuration::getInstance().UseMalloc) { - free(memory); - } - } - - virtual tlm::tlm_sync_enum nb_transport_fw(tlm::tlm_generic_payload &payload, - tlm::tlm_phase &phase, sc_time &delay) - { - if (numberOfTransactionsServed == 0) { - firstAccess = sc_time_stamp(); - } else { - lastAccess = sc_time_stamp(); - } - - unsigned int bank = DramExtension::getExtension(payload).getBank().ID(); - - // This is only needed for power simulation: - unsigned long long cycle = 0; - if (powerAnalysis == true) { - cycle = sc_time_stamp().value() / - Configuration::getInstance().memSpec.clk.value(); - } - if (phase == BEGIN_PREB) { - if (powerAnalysis == true) { - DRAMPower->doCommand(MemCommand::PREB, bank, cycle); - } - sendToController(payload, END_PREB, delay + getExecutionTime(Command::PreB, - payload)); - } else if (phase == BEGIN_PRE) { - if (powerAnalysis == true) { - DRAMPower->doCommand(MemCommand::PRE, bank, cycle); - } - sendToController(payload, END_PRE, delay + getExecutionTime(Command::Precharge, - payload)); - } else if (phase == BEGIN_PRE_ALL) { - if (powerAnalysis == true) { - DRAMPower->doCommand(MemCommand::PREA, bank, cycle); - } - sendToController(payload, END_PRE_ALL, - delay + getExecutionTime(Command::PrechargeAll, payload)); - } else if (phase == BEGIN_ACTB) { - if (powerAnalysis == true) { - DRAMPower->doCommand(MemCommand::ACTB, bank, cycle); - } - sendToController(payload, END_ACTB, delay + getExecutionTime(Command::ActB, - payload)); - unsigned int row = DramExtension::getExtension(payload).getRow().ID(); - if (StoreMode == StorageMode::ErrorModel) { - ememory[bank]->activate(row); - } - } else if (phase == BEGIN_ACT) { - if (powerAnalysis == true) { - DRAMPower->doCommand(MemCommand::ACT, bank, cycle); - } - sendToController(payload, END_ACT, delay + getExecutionTime(Command::Activate, - payload)); - unsigned int row = DramExtension::getExtension(payload).getRow().ID(); - - if (StoreMode == StorageMode::ErrorModel) { - ememory[bank]->activate(row); - } - } else if (phase == BEGIN_WR) { -#if !defined (DRAMSYS_PCT) && !defined (DRAMSYS_GEM5) - assert(payload.get_data_length() == bytesPerBurst); -#endif - - if (powerAnalysis == true) { - DRAMPower->doCommand(MemCommand::WR, bank, cycle); - } - numberOfTransactionsServed++; - - //save data: - if (StoreMode == StorageMode::NoStorage) { - // Don't store data - } else if (StoreMode == StorageMode::Store) { // Use Storage - unsigned char *phyAddr = memory + payload.get_address(); - memcpy(phyAddr, payload.get_data_ptr(), payload.get_data_length()); - } else { // == 2 Use Storage with Error Model - ememory[bank]->store(payload); - } - sendToController(payload, END_WR, delay + getExecutionTime(Command::Write, - payload)); - } else if (phase == BEGIN_RD) { -#if !defined (DRAMSYS_PCT) && !defined (DRAMSYS_GEM5) - assert(payload.get_data_length() == bytesPerBurst); -#endif - - numberOfTransactionsServed++; - if (powerAnalysis == true) { - DRAMPower->doCommand(MemCommand::RD, bank, cycle); - } - - // Load data: - if (StoreMode == StorageMode::Store) { //use StorageMode - unsigned char *phyAddr = memory + payload.get_address(); - memcpy(payload.get_data_ptr(), phyAddr, payload.get_data_length()); - } else if (StoreMode == - StorageMode::ErrorModel) { // use StorageMode with errormodel - ememory[bank]->load(payload); - } - - sendToController(payload, END_RD, delay + getExecutionTime(Command::Read, - payload)); - } else if (phase == BEGIN_WRA) { - numberOfTransactionsServed++; - if (powerAnalysis == true) { - DRAMPower->doCommand(MemCommand::WRA, bank, cycle); - } - - //save data: - if (StoreMode == StorageMode::NoStorage) { - // Don't store data - } else if (StoreMode == StorageMode::Store) { // Use Storage - unsigned char *phyAddr = memory + payload.get_address(); - memcpy(phyAddr, payload.get_data_ptr(), payload.get_data_length()); - } else { // == 2 Use Storage with Error Model - ememory[bank]->store(payload); - } - sendToController(payload, END_WRA, delay + getExecutionTime(Command::WriteA, - payload)); - } else if (phase == BEGIN_RDA) { - numberOfTransactionsServed++; - if (powerAnalysis == true) { - DRAMPower->doCommand(MemCommand::RDA, bank, cycle); - } - - // Load data: - if (StoreMode == StorageMode::Store) { //use StorageMode - unsigned char *phyAddr = memory + payload.get_address(); - memcpy(payload.get_data_ptr(), phyAddr, payload.get_data_length()); - } else if (StoreMode == - StorageMode::ErrorModel) { // use StorageMode with errormodel - ememory[bank]->load(payload); - } - - sendToController(payload, END_RDA, delay + getExecutionTime(Command::ReadA, - payload)); - } else if (phase == BEGIN_REFA) { - if (powerAnalysis == true) { - DRAMPower->doCommand(MemCommand::REF, bank, cycle); - } - sendToController(payload, END_REFA, - delay + getExecutionTime(Command::AutoRefresh, payload)); - unsigned int row = DramExtension::getExtension(payload).getRow().ID(); - - if (StoreMode == StorageMode::ErrorModel) { - ememory[bank]->refresh(row); - } - } - - else if (phase == BEGIN_REFB) { - if (powerAnalysis == true) { - DRAMPower->doCommand(MemCommand::REFB, bank, cycle); - } - sendToController(payload, END_REFB, - delay + getExecutionTime(Command::AutoRefresh, payload)); - } - - //Powerdown phases have to be started and ended by the controller, because they do not have a fixed length - else if (phase == BEGIN_PDNA) { - if (powerAnalysis == true) { - DRAMPower->doCommand(MemCommand::PDN_S_ACT, bank, cycle); - } - } else if (phase == END_PDNA) { - if (powerAnalysis == true) { - DRAMPower->doCommand(MemCommand::PUP_ACT, bank, cycle); - } - } else if (phase == BEGIN_PDNAB) { - if (powerAnalysis == true) { - SC_REPORT_FATAL("DRAM", "Power calculation for bankwise logic not supported"); - } - } else if (phase == END_PDNAB) { - if (powerAnalysis == true) { - SC_REPORT_FATAL("DRAM", "Power calculation for bankwise logic not supported"); - } - } else if (phase == BEGIN_PDNP) { - if (powerAnalysis == true) { - DRAMPower->doCommand(MemCommand::PDN_S_PRE, bank, cycle); - } - } else if (phase == END_PDNP) { - if (powerAnalysis == true) { - DRAMPower->doCommand(MemCommand::PUP_PRE, bank, cycle); - } - } else if (phase == BEGIN_PDNPB) { - if (powerAnalysis == true) { - SC_REPORT_FATAL("DRAM", "Power calculation for bankwise logic not supported"); - } - } else if (phase == END_PDNPB) { - if (powerAnalysis == true) { - SC_REPORT_FATAL("DRAM", "Power calculation for bankwise logic not supported"); - } - } else if (phase == BEGIN_SREF) { - if (powerAnalysis == true) { - DRAMPower->doCommand(MemCommand::SREN, bank, cycle); - } - } else if (phase == END_SREF) { - if (powerAnalysis == true) { - DRAMPower->doCommand(MemCommand::SREX, bank, cycle); - } - } else if (phase == BEGIN_SREFB) { - if (powerAnalysis == true) { - SC_REPORT_FATAL("DRAM", "Power calculation for bankwise logic not supported"); - } - } else if (phase == END_SREFB) { - if (powerAnalysis == true) { - SC_REPORT_FATAL("DRAM", "Power calculation for bankwise logic not supported"); - } - } else { - if (powerAnalysis == true) { - SC_REPORT_FATAL("DRAM", "DRAM PEQ was called with unknown phase"); - } - } - - return tlm::TLM_ACCEPTED; - } - - virtual unsigned int transport_dbg(tlm::tlm_generic_payload &trans) - { - printDebugMessage("transport_dgb"); - - // TODO: This part is not tested yet, neither with traceplayers neither with GEM5 coupling - if (StoreMode == StorageMode::NoStorage) { - SC_REPORT_FATAL("DRAM", - "Debug Transport is used in combination with NoStorage"); - } else { - tlm::tlm_command cmd = trans.get_command(); - //sc_dt::uint64 adr = trans.get_address(); // TODO: - offset; - unsigned char *ptr = trans.get_data_ptr(); - unsigned int len = trans.get_data_length(); - //unsigned int bank = DramExtension::getExtension(trans).getBank().ID(); - - //cout << "cmd " << (cmd ? "write" : "read") << " adr " << hex << adr << " len " << len << endl; - - if ( cmd == tlm::TLM_READ_COMMAND ) { - if (StoreMode == StorageMode::Store) { // Use Storage - unsigned char *phyAddr = memory + trans.get_address(); - memcpy(ptr, phyAddr, trans.get_data_length()); - } else { - //ememory[bank]->load(trans); - SC_REPORT_FATAL("DRAM", "Debug transport not supported with error model yet."); - } - } else if ( cmd == tlm::TLM_WRITE_COMMAND ) { - - if (StoreMode == StorageMode::Store) { // Use Storage - unsigned char *phyAddr = memory + trans.get_address(); - memcpy(phyAddr, ptr, trans.get_data_length()); - } else { - //ememory[bank]->store(trans); - SC_REPORT_FATAL("DRAM", "Debug transport not supported with error model yet."); - } - - } - return len; - } - return 0; - } + virtual unsigned int transport_dbg(tlm_generic_payload &trans); void sendToController(tlm_generic_payload &payload, const tlm_phase &phase, - const sc_time &delay) - { - tlm_phase TPhase = phase; - sc_time TDelay = delay; - tSocket->nb_transport_bw(payload, TPhase, TDelay); - } + const sc_time &delay); - void printDebugMessage(string message) - { - DebugManager::getInstance().printDebugMessage(name(), message); - } + void printDebugMessage(string message); - void setDramController(Controller *contr) - { - dramController = contr; - } +public: + tlm_utils::simple_target_socket tSocket; + + Dram(sc_module_name); + SC_HAS_PROCESS(Dram); + + virtual ~Dram(); }; -#endif /* DRAM_H_ */ +#endif // DRAM_H diff --git a/DRAMSys/library/src/simulation/DramDDR3.cpp b/DRAMSys/library/src/simulation/DramDDR3.cpp new file mode 100644 index 00000000..ebe78c90 --- /dev/null +++ b/DRAMSys/library/src/simulation/DramDDR3.cpp @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2019, University of Kaiserslautern + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER + * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Authors: + * Lukas Steiner + */ + +#include "DramDDR3.h" + +#include "Dram.h" +#include "../controller/core/configuration/Configuration.h" + +DramDDR3::DramDDR3(sc_module_name name) : Dram(name) +{ + if (StoreMode == StorageMode::ErrorModel) + SC_REPORT_FATAL("DramDDR3", "Error Model for DDR3 not supported"); +} diff --git a/DRAMSys/library/src/controller/core/scheduling/Trigger.h b/DRAMSys/library/src/simulation/DramDDR3.h similarity index 84% rename from DRAMSys/library/src/controller/core/scheduling/Trigger.h rename to DRAMSys/library/src/simulation/DramDDR3.h index b0026be8..0886d25a 100644 --- a/DRAMSys/library/src/controller/core/scheduling/Trigger.h +++ b/DRAMSys/library/src/simulation/DramDDR3.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, University of Kaiserslautern + * Copyright (c) 2019, University of Kaiserslautern * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -30,15 +30,21 @@ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * Authors: - * Janik Schlemminger - * Matthias Jung + * Lukas Steiner */ -#ifndef TRIGGER_H_ -#define TRIGGER_H_ +#ifndef DRAMDDR3_H +#define DRAMDDR3_H +#include "Dram.h" +#include +#include -enum Trigger {REFTrigger, PDNTrigger}; +class DramDDR3 : public Dram +{ +public: + DramDDR3(sc_module_name); + SC_HAS_PROCESS(DramDDR3); +}; - -#endif /* TRIGGER_H_ */ +#endif // DRAMDDR3_H diff --git a/DRAMSys/library/src/simulation/DramDDR4.cpp b/DRAMSys/library/src/simulation/DramDDR4.cpp new file mode 100644 index 00000000..8feeb259 --- /dev/null +++ b/DRAMSys/library/src/simulation/DramDDR4.cpp @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2019, University of Kaiserslautern + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER + * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Authors: + * Lukas Steiner + */ + +#include "DramDDR4.h" + +#include "Dram.h" +#include "../controller/core/configuration/Configuration.h" + +DramDDR4::DramDDR4(sc_module_name name) : Dram(name) +{ + if (StoreMode == StorageMode::ErrorModel) + SC_REPORT_FATAL("DramDDR4", "Error Model for DDR4 not supported"); +} diff --git a/DRAMSys/library/src/simulation/DramDDR4.h b/DRAMSys/library/src/simulation/DramDDR4.h new file mode 100644 index 00000000..5cf92424 --- /dev/null +++ b/DRAMSys/library/src/simulation/DramDDR4.h @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2019, University of Kaiserslautern + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER + * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Authors: + * Lukas Steiner + */ + +#ifndef DRAMDDR4_H +#define DRAMDDR4_H + +#include "Dram.h" +#include +#include + +class DramDDR4 : public Dram +{ +public: + DramDDR4(sc_module_name); + SC_HAS_PROCESS(DramDDR4); +}; + +#endif // DRAMDDR4_H diff --git a/DRAMSys/library/src/simulation/DramRecordable.cpp b/DRAMSys/library/src/simulation/DramRecordable.cpp new file mode 100644 index 00000000..cc24e5a2 --- /dev/null +++ b/DRAMSys/library/src/simulation/DramRecordable.cpp @@ -0,0 +1,143 @@ +/* + * Copyright (c) 2019, University of Kaiserslautern + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER + * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Authors: + * Lukas Steiner + */ + +#include "DramRecordable.h" +#include +#include +#include "../common/TlmRecorder.h" +#include "DramDDR3.h" +#include "DramDDR4.h" +#include "DramWideIO.h" +#include "../common/utils.h" + +using namespace tlm; + +template +DramRecordable::DramRecordable(sc_module_name name, TlmRecorder *tlmRecorder) + : BaseDram(name), tlmRecorder(tlmRecorder) +{ + // Create a thread that is triggered every $powerWindowSize + // to generate a Power over Time plot in the Trace analyzer: + SC_THREAD(powerWindow); +} + +template +DramRecordable::~DramRecordable() +{ + BaseDram::DRAMPower->calcEnergy(); + recordPower(); + tlmRecorder->closeConnection(); +} + +template +tlm_sync_enum DramRecordable::nb_transport_fw(tlm_generic_payload &payload, + tlm_phase &phase, sc_time &delay) +{ + // Recording time used by the traceAnalyzer + sc_time recTime = sc_time_stamp() + delay; + + // These are terminating phases recorded by the DRAM. The execution + // time of the related command must be taken into consideration. + if (phase == END_PDNA || phase == END_PDNAB) + recTime += getExecutionTime(Command::PDNAX, payload); + else if (phase == END_PDNP || phase == END_PDNPB) + recTime += getExecutionTime(Command::PDNPX, payload); + else if (phase == END_SREF || phase == END_SREFB) + recTime += getExecutionTime(Command::SREFX, payload); + + unsigned int thr = DramExtension::getExtension(payload).getThread().ID(); + unsigned int ch = DramExtension::getExtension(payload).getChannel().ID(); + unsigned int bg = DramExtension::getExtension(payload).getBankGroup().ID(); + unsigned int bank = DramExtension::getExtension(payload).getBank().ID(); + unsigned int row = DramExtension::getExtension(payload).getRow().ID(); + unsigned int col = DramExtension::getExtension(payload).getColumn().ID(); + + // TODO: printDebugMessage not inherited + this->printDebugMessage("Recording " + phaseNameToString(phase) + " thread " + + to_string(thr) + " channel " + to_string(ch) + " bank group " + to_string( + bg) + " bank " + to_string(bank) + " row " + to_string(row) + " column " + + to_string(col) + " at " + recTime.to_string()); + + tlmRecorder->recordPhase(payload, phase, recTime); + + return BaseDram::nb_transport_fw(payload, phase, delay); +} + +// This Thread is only triggered when Power Simulation is enabled. +// It estimates the current average power which will be stored in the trace database for visualization purposes. +template +void DramRecordable::powerWindow() +{ + unsigned long long clkCycles = 0; + + do { + // At the very beginning (zero clock cycles) the energy is 0, so we wait first + wait(powerWindowSize); + + clkCycles = sc_time_stamp().value() / + Configuration::getInstance().memSpec->clk.value(); + + this->DRAMPower->calcWindowEnergy(clkCycles); + + // During operation the energy should never be zero since the device is always consuming + assert(!isEqual(this->DRAMPower->getEnergy().window_energy, 0.0)); + + // Store the time (in seconds) and the current average power (in mW) into the database + recordPower(); + + // Here considering that DRAMPower provides the energy in pJ and the power in mW + this->printDebugMessage(string("\tWindow Energy: \t") + to_string( + this->DRAMPower->getEnergy().window_energy * + Configuration::getInstance().NumberOfDevicesOnDIMM) + string("\t[pJ]")); + this->printDebugMessage(string("\tWindow Average Power: \t") + to_string( + this->DRAMPower->getPower().window_average_power * + Configuration::getInstance().NumberOfDevicesOnDIMM) + string("\t[mW]")); + + } while (true); +} + +template +void DramRecordable::recordPower() +{ + tlmRecorder->recordPower(sc_time_stamp().to_seconds(), + this->DRAMPower->getPower().window_average_power + * Configuration::getInstance().NumberOfDevicesOnDIMM); +} + + +template class DramRecordable; +template class DramRecordable; +template class DramRecordable; + diff --git a/DRAMSys/library/src/simulation/DramRecordable.h b/DRAMSys/library/src/simulation/DramRecordable.h new file mode 100644 index 00000000..59d6873a --- /dev/null +++ b/DRAMSys/library/src/simulation/DramRecordable.h @@ -0,0 +1,81 @@ +/* + * Copyright (c) 2019, University of Kaiserslautern + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER + * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Authors: + * Lukas Steiner + */ + +#ifndef DRAMRECORDABLE_H +#define DRAMRECORDABLE_H + +#include +#include +#include "DramDDR3.h" +#include "DramDDR4.h" +#include "RecordableDram.h" +#include "../common/TlmRecorder.h" + +using namespace tlm; + +template +class DramRecordable : public BaseDram +{ +public: + DramRecordable(sc_module_name name, TlmRecorder *tlmRecorder); + SC_HAS_PROCESS(DramRecordable); + + virtual ~DramRecordable(); + +protected: + virtual tlm_sync_enum nb_transport_fw(tlm_generic_payload &payload, + tlm_phase &phase, sc_time &delay); + +private: + TlmRecorder *tlmRecorder; + sc_time powerWindowSize = Configuration::getInstance().memSpec->clk * + Configuration::getInstance().WindowSize; + + // When working with floats, we have to decide ourselves what is an + // acceptable definition for "equal". Here the number is compared with a + // suitable error margin (0.00001). + bool isEqual(double a, double b, const double epsilon = 1e-05) + { + return std::fabs(a - b) < epsilon; + } + + // This Thread is only triggered when Power Simulation is enabled. + // It estimates the current average power which will be stored in the trace database for visualization purposes. + void powerWindow(); + + void recordPower(); +}; + +#endif // DRAMRECORDABLE_H diff --git a/DRAMSys/library/src/simulation/DramWideIO.cpp b/DRAMSys/library/src/simulation/DramWideIO.cpp new file mode 100644 index 00000000..3f69ca7a --- /dev/null +++ b/DRAMSys/library/src/simulation/DramWideIO.cpp @@ -0,0 +1,253 @@ +/* + * Copyright (c) 2019, University of Kaiserslautern + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER + * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Authors: + * Lukas Steiner + */ + +#include "DramWideIO.h" + +#include +#include +#include "Dram.h" +#include "../controller/core/configuration/Configuration.h" +#include "../error/errormodel.h" + +using namespace tlm; + +DramWideIO::DramWideIO(sc_module_name name) : Dram(name) +{ + // For each bank in a channel a error Model is created: + if (StoreMode == StorageMode::ErrorModel) + { + if (Configuration::getInstance().UseMalloc) + free(memory); + + for (unsigned i = 0; i < Configuration::getInstance().memSpec->NumberOfBanks; + i++) + { + errorModel *em; + std::string errorModelStr = "errorModel_bank" + std::to_string(i); + em = new errorModel(errorModelStr.c_str(), DRAMPower); + ememory.push_back(em); + } + } +} + +DramWideIO::~DramWideIO() +{ + // Clean up: + for (auto e : ememory) + delete e; +} + +tlm_sync_enum DramWideIO::nb_transport_fw(tlm_generic_payload &payload, + tlm_phase &phase, sc_time &delay) +{ + unsigned int bank = DramExtension::getExtension(payload).getBank().ID(); + + // This is only needed for power simulation: + unsigned long long cycle = sc_time_stamp().value() / + Configuration::getInstance().memSpec->clk.value(); + + if (phase == BEGIN_PREB) + { + DRAMPower->doCommand(MemCommand::PREB, bank, cycle); + sendToController(payload, END_PREB, delay + getExecutionTime(Command::PreB, + payload)); + } + else if (phase == BEGIN_PRE) + { + DRAMPower->doCommand(MemCommand::PRE, bank, cycle); + sendToController(payload, END_PRE, delay + getExecutionTime(Command::Precharge, + payload)); + } + else if (phase == BEGIN_PRE_ALL) + { + DRAMPower->doCommand(MemCommand::PREA, bank, cycle); + sendToController(payload, END_PRE_ALL, + delay + getExecutionTime(Command::PrechargeAll, payload)); + } + else if (phase == BEGIN_ACTB) + { + DRAMPower->doCommand(MemCommand::ACTB, bank, cycle); + sendToController(payload, END_ACTB, delay + getExecutionTime(Command::ActB, + payload)); + unsigned int row = DramExtension::getExtension(payload).getRow().ID(); + if (StoreMode == StorageMode::ErrorModel) + ememory[bank]->activate(row); + } + else if (phase == BEGIN_ACT) + { + DRAMPower->doCommand(MemCommand::ACT, bank, cycle); + sendToController(payload, END_ACT, delay + getExecutionTime(Command::Activate, + payload)); + unsigned int row = DramExtension::getExtension(payload).getRow().ID(); + + if (StoreMode == StorageMode::ErrorModel) + ememory[bank]->activate(row); + } + else if (phase == BEGIN_WR) + { + DRAMPower->doCommand(MemCommand::WR, bank, cycle); + // save data: + if (StoreMode == StorageMode::Store) // Use Storage + { + unsigned char *phyAddr = memory + payload.get_address(); + memcpy(phyAddr, payload.get_data_ptr(), payload.get_data_length()); + } + else if (StoreMode == StorageMode::ErrorModel) // Use Storage with Error Model + { + ememory[bank]->store(payload); + } + sendToController(payload, END_WR, delay + getExecutionTime(Command::Write, + payload)); + } + else if (phase == BEGIN_RD) + { + DRAMPower->doCommand(MemCommand::RD, bank, cycle); + // load data: + if (StoreMode == StorageMode::Store) // use StorageMode + { + unsigned char *phyAddr = memory + payload.get_address(); + memcpy(payload.get_data_ptr(), phyAddr, payload.get_data_length()); + } + else if (StoreMode == StorageMode::ErrorModel) // use StorageMode with errormodel + { + ememory[bank]->load(payload); + } + sendToController(payload, END_RD, delay + getExecutionTime(Command::Read, + payload)); + } + else if (phase == BEGIN_WRA) + { + DRAMPower->doCommand(MemCommand::WRA, bank, cycle); + // save data: + if (StoreMode == StorageMode::Store) // Use Storage + { + unsigned char *phyAddr = memory + payload.get_address(); + memcpy(phyAddr, payload.get_data_ptr(), payload.get_data_length()); + } + else if (StoreMode == StorageMode::ErrorModel) // Use Storage with Error Model + { + ememory[bank]->store(payload); + } + sendToController(payload, END_WRA, delay + getExecutionTime(Command::WriteA, + payload)); + } + else if (phase == BEGIN_RDA) + { + DRAMPower->doCommand(MemCommand::RDA, bank, cycle); + // Load data: + if (StoreMode == StorageMode::Store) // use StorageMode + { + unsigned char *phyAddr = memory + payload.get_address(); + memcpy(payload.get_data_ptr(), phyAddr, payload.get_data_length()); + } + else if (StoreMode == StorageMode::ErrorModel) // use StorageMode with errormodel + { + ememory[bank]->load(payload); + } + sendToController(payload, END_RDA, delay + getExecutionTime(Command::ReadA, + payload)); + } + else if (phase == BEGIN_REFA) + { + DRAMPower->doCommand(MemCommand::REF, bank, cycle); + sendToController(payload, END_REFA, + delay + getExecutionTime(Command::AutoRefresh, payload)); + unsigned int row = DramExtension::getExtension(payload).getRow().ID(); + + if (StoreMode == StorageMode::ErrorModel) + ememory[bank]->refresh(row); + } + else if (phase == BEGIN_REFB) + { + DRAMPower->doCommand(MemCommand::REFB, bank, cycle); + sendToController(payload, END_REFB, + delay + getExecutionTime(Command::AutoRefresh, payload)); + } + // Powerdown phases have to be started and ended by the controller, because they do not have a fixed length + else if (phase == BEGIN_PDNA) + { + DRAMPower->doCommand(MemCommand::PDN_S_ACT, bank, cycle); + } + else if (phase == END_PDNA) + { + DRAMPower->doCommand(MemCommand::PUP_ACT, bank, cycle); + } + else if (phase == BEGIN_PDNAB) + { + SC_REPORT_FATAL("DRAM", "Power calculation for bankwise logic not supported"); + } + else if (phase == END_PDNAB) + { + SC_REPORT_FATAL("DRAM", "Power calculation for bankwise logic not supported"); + } + else if (phase == BEGIN_PDNP) + { + DRAMPower->doCommand(MemCommand::PDN_S_PRE, bank, cycle); + } + else if (phase == END_PDNP) + { + DRAMPower->doCommand(MemCommand::PUP_PRE, bank, cycle); + } + else if (phase == BEGIN_PDNPB) + { + SC_REPORT_FATAL("DRAM", "Power calculation for bankwise logic not supported"); + } + else if (phase == END_PDNPB) + { + SC_REPORT_FATAL("DRAM", "Power calculation for bankwise logic not supported"); + } + else if (phase == BEGIN_SREF) + { + DRAMPower->doCommand(MemCommand::SREN, bank, cycle); + } + else if (phase == END_SREF) + { + DRAMPower->doCommand(MemCommand::SREX, bank, cycle); + } + else if (phase == BEGIN_SREFB) + { + SC_REPORT_FATAL("DRAM", "Power calculation for bankwise logic not supported"); + } + else if (phase == END_SREFB) + { + SC_REPORT_FATAL("DRAM", "Power calculation for bankwise logic not supported"); + } + else + { + SC_REPORT_FATAL("DRAM", "DRAM PEQ was called with unknown phase"); + } + + return TLM_ACCEPTED; +} diff --git a/DRAMSys/library/src/simulation/DramWideIO.h b/DRAMSys/library/src/simulation/DramWideIO.h new file mode 100644 index 00000000..56e0b39a --- /dev/null +++ b/DRAMSys/library/src/simulation/DramWideIO.h @@ -0,0 +1,62 @@ +/* + * Copyright (c) 2019, University of Kaiserslautern + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER + * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Authors: + * Lukas Steiner + */ + +#ifndef DRAMWIDEIO_H +#define DRAMWIDEIO_H + +#include +#include +#include "Dram.h" +#include "../error/errormodel.h" + +using namespace tlm; + +class DramWideIO : public Dram +{ +public: + DramWideIO(sc_module_name); + SC_HAS_PROCESS(DramWideIO); + + virtual ~DramWideIO(); + +protected: + virtual tlm_sync_enum nb_transport_fw(tlm_generic_payload &payload, + tlm_phase &phase, sc_time &delay); + +private: + std::vector ememory; +}; + +#endif // DRAMWIDEIO_H diff --git a/DRAMSys/library/src/simulation/ExampleInitiator.h b/DRAMSys/library/src/simulation/ExampleInitiator.h index f8b60b9e..7b227709 100644 --- a/DRAMSys/library/src/simulation/ExampleInitiator.h +++ b/DRAMSys/library/src/simulation/ExampleInitiator.h @@ -1,16 +1,17 @@ -#ifndef EXAMPLEINITIATOR -#define EXAMPLEINITIATOR +#ifndef EXAMPLEINITIATOR_H +#define EXAMPLEINITIATOR_H #include #include #include "MemoryManager.h" -#include "../common/dramExtension.h" +#include "../common/dramExtensions.h" #include "TracePlayer.h" using namespace std; -struct ExampleInitiator: sc_module { +struct ExampleInitiator : sc_module +{ // TLM-2 socket, defaults to 32-bits wide, base protocol tlm_utils::simple_initiator_socket socket; @@ -202,4 +203,4 @@ struct ExampleInitiator: sc_module { tlm_utils::peq_with_cb_and_phase m_peq; }; -#endif // EXAMPLEINITIATOR +#endif // EXAMPLEINITIATOR_H diff --git a/DRAMSys/library/src/simulation/IArbiter.h b/DRAMSys/library/src/simulation/IArbiter.h index 3c3460cc..872fd929 100644 --- a/DRAMSys/library/src/simulation/IArbiter.h +++ b/DRAMSys/library/src/simulation/IArbiter.h @@ -34,8 +34,8 @@ * Matthias Jung */ -#ifndef IARBITER_H_ -#define IARBITER_H_ +#ifndef IARBITER_H +#define IARBITER_H #include #include @@ -49,7 +49,8 @@ using namespace std; using namespace tlm; -struct IArbiter: public sc_module { +struct IArbiter : public sc_module +{ public: tlm_utils::multi_passthrough_target_socket tSocket; tlm_utils::multi_passthrough_initiator_socket iSocket; @@ -101,7 +102,7 @@ protected: payload.set_auto_extension(genExtension); unsigned int burstlength = payload.get_streaming_width(); - DecodedAddress decodedAddress = xmlAddressDecoder::getInstance().decodeAddress( + DecodedAddress decodedAddress = XmlAddressDecoder::getInstance().decodeAddress( payload.get_address()); // Check the valid range of decodedAddress if (addressIsValid(decodedAddress)) { @@ -118,25 +119,25 @@ protected: bool addressIsValid(DecodedAddress &decodedAddress) { if (decodedAddress.channel >= - xmlAddressDecoder::getInstance().amount["channel"]) { + XmlAddressDecoder::getInstance().amount["channel"]) { return false; } - if (decodedAddress.bank >= xmlAddressDecoder::getInstance().amount["bank"]) { + if (decodedAddress.bank >= XmlAddressDecoder::getInstance().amount["bank"]) { return false; } if (decodedAddress.bankgroup > - xmlAddressDecoder::getInstance().amount["bankgroup"]) { + XmlAddressDecoder::getInstance().amount["bankgroup"]) { return false; } if (decodedAddress.column >= - xmlAddressDecoder::getInstance().amount["column"]) { + XmlAddressDecoder::getInstance().amount["column"]) { return false; } - if (decodedAddress.row >= xmlAddressDecoder::getInstance().amount["row"]) { + if (decodedAddress.row >= XmlAddressDecoder::getInstance().amount["row"]) { return false; } return true; } }; -#endif /* IARBITER_H_ */ +#endif // IARBITER_H diff --git a/DRAMSys/library/src/simulation/MemoryManager.h b/DRAMSys/library/src/simulation/MemoryManager.h index 8b431ca5..83baa275 100644 --- a/DRAMSys/library/src/simulation/MemoryManager.h +++ b/DRAMSys/library/src/simulation/MemoryManager.h @@ -34,8 +34,8 @@ * Matthias Jung */ -#ifndef MEMORYMANAGER_H_ -#define MEMORYMANAGER_H_ +#ifndef MEMORYMANAGER_H +#define MEMORYMANAGER_H #include #include @@ -55,4 +55,4 @@ private: std::vector freePayloads; }; -#endif /* MEMORYMANAGER_H_ */ +#endif // MEMORYMANAGER_H diff --git a/DRAMSys/library/src/simulation/RecordableDram.cpp b/DRAMSys/library/src/simulation/RecordableDram.cpp new file mode 100644 index 00000000..699f0a74 --- /dev/null +++ b/DRAMSys/library/src/simulation/RecordableDram.cpp @@ -0,0 +1,135 @@ +/* + * Copyright (c) 2018, University of Kaiserslautern + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER + * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Authors: + * Felipe S. Prado + * Matthias Jung + */ + +#include "RecordableDram.h" + +using namespace tlm; + +RecordableDram::RecordableDram(sc_module_name name, TlmRecorder *tlmRecorder) + : Dram(name), tlmRecorder(tlmRecorder) +{ + // Create a thread that is triggered every $powerWindowSize + // to generate a Power over Time plot in the Trace analyzer: + if (Configuration::getInstance().PowerAnalysis + && Configuration::getInstance().EnableWindowing) + SC_THREAD(powerWindow); +} + +RecordableDram::~RecordableDram() +{ + if (Configuration::getInstance().PowerAnalysis) + { + // Obtain the residual energy which was not covered by + // previous windows + DRAMPower->calcEnergy(); + recordPower(); + } + tlmRecorder->closeConnection(); +} + + +tlm_sync_enum RecordableDram::nb_transport_fw(tlm_generic_payload &payload, + tlm_phase &phase, sc_time &delay) +{ + // Recording time used by the traceAnalyzer + sc_time recTime = sc_time_stamp() + delay; + + // These are terminating phases recorded by the DRAM. The execution + // time of the related command must be taken into consideration. + if (phase == END_PDNA || phase == END_PDNAB) { + recTime += getExecutionTime(Command::PDNAX, payload); + } else if (phase == END_PDNP || phase == END_PDNPB) { + recTime += getExecutionTime(Command::PDNPX, payload); + } else if (phase == END_SREF || phase == END_SREFB) { + recTime += getExecutionTime(Command::SREFX, payload); + } + + unsigned int thr = DramExtension::getExtension(payload).getThread().ID(); + unsigned int ch = DramExtension::getExtension(payload).getChannel().ID(); + unsigned int bg = DramExtension::getExtension(payload).getBankGroup().ID(); + unsigned int bank = DramExtension::getExtension(payload).getBank().ID(); + unsigned int row = DramExtension::getExtension(payload).getRow().ID(); + unsigned int col = DramExtension::getExtension(payload).getColumn().ID(); + + printDebugMessage("Recording " + phaseNameToString(phase) + " thread " + + to_string(thr) + " channel " + to_string(ch) + " bank group " + to_string( + bg) + " bank " + to_string(bank) + " row " + to_string(row) + " column " + + to_string(col) + " at " + recTime.to_string()); + + tlmRecorder->recordPhase(payload, phase, recTime); + + return Dram::nb_transport_fw(payload, phase, delay); +} + +// This Thread is only triggered when Power Simulation is enabled. +// It estimates the current average power which will be stored in the trace database for visualization purposes. +void RecordableDram::powerWindow() +{ + unsigned long long clkCycles = 0; + + do { + // At the very beginning (zero clock cycles) the energy is 0, so we wait first + wait(powerWindowSize); + + clkCycles = sc_time_stamp().value() / + Configuration::getInstance().memSpec->clk.value(); + + DRAMPower->calcWindowEnergy(clkCycles); + + // During operation the energy should never be zero since the device is always consuming + assert(!isEqual(DRAMPower->getEnergy().window_energy, 0.0)); + + // Store the time (in seconds) and the current average power (in mW) into the database + recordPower(); + + // Here considering that DRAMPower provides the energy in pJ and the power in mW + printDebugMessage(string("\tWindow Energy: \t") + to_string( + DRAMPower->getEnergy().window_energy * + Configuration::getInstance().NumberOfDevicesOnDIMM) + string("\t[pJ]")); + printDebugMessage(string("\tWindow Average Power: \t") + to_string( + DRAMPower->getPower().window_average_power * + Configuration::getInstance().NumberOfDevicesOnDIMM) + string("\t[mW]")); + + } while (true); +} + +void RecordableDram::recordPower() +{ + tlmRecorder->recordPower(sc_time_stamp().to_seconds(), + DRAMPower->getPower().window_average_power + * Configuration::getInstance().NumberOfDevicesOnDIMM); +} + diff --git a/DRAMSys/library/src/simulation/RecordableDram.h b/DRAMSys/library/src/simulation/RecordableDram.h index 00a2d073..0434177a 100644 --- a/DRAMSys/library/src/simulation/RecordableDram.h +++ b/DRAMSys/library/src/simulation/RecordableDram.h @@ -34,119 +34,45 @@ * Matthias Jung */ -#ifndef RECORDABLEDRAM_H_ -#define RECORDABLEDRAM_H_ +#ifndef RECORDABLEDRAM_H +#define RECORDABLEDRAM_H #include "Dram.h" #include "../common/TlmRecorder.h" -struct RecordableDram : public Dram { +using namespace tlm; + +class RecordableDram : public Dram +{ +public: + RecordableDram(sc_module_name, TlmRecorder *tlmRecorder); SC_HAS_PROCESS(RecordableDram); - RecordableDram(sc_module_name name, TlmRecorder *tlmRecorder): - Dram(name), tlmRecorder(tlmRecorder) - { - // Create a thread that is triggered every $powerWindowSize - // to generate a Power over Time plot in the Trace analyzer: - if (Configuration::getInstance().PowerAnalysis - && Configuration::getInstance().EnableWindowing) - SC_THREAD(powerWindow); - } - ~RecordableDram() - { - if (Configuration::getInstance().PowerAnalysis) { - // Obtain the residual energy which was not covered by - // previous windows - DRAMPower->calcEnergy(); - recordPower(); - } - tlmRecorder->closeConnection(); - } + ~RecordableDram(); +protected: + virtual tlm_sync_enum nb_transport_fw(tlm_generic_payload &payload, + tlm_phase &phase, sc_time &delay); + +private: TlmRecorder *tlmRecorder; - sc_time powerWindowSize = Configuration::getInstance().memSpec.clk * + sc_time powerWindowSize = Configuration::getInstance().memSpec->clk * Configuration::getInstance().WindowSize; - virtual tlm::tlm_sync_enum nb_transport_fw(tlm::tlm_generic_payload &payload, - tlm::tlm_phase &phase, sc_time &delay) - { - // Recording time used by the traceAnalyzer - sc_time recTime = sc_time_stamp() + delay; - - // These are terminating phases recorded by the DRAM. The execution - // time of the related command must be taken into consideration. - if (phase == END_PDNA || phase == END_PDNAB) { - recTime += getExecutionTime(Command::PDNAX, payload); - } else if (phase == END_PDNP || phase == END_PDNPB) { - recTime += getExecutionTime(Command::PDNPX, payload); - } else if (phase == END_SREF || phase == END_SREFB) { - recTime += getExecutionTime(Command::SREFX, payload); - } - - unsigned int thr = DramExtension::getExtension(payload).getThread().ID(); - unsigned int ch = DramExtension::getExtension(payload).getChannel().ID(); - unsigned int bg = DramExtension::getExtension(payload).getBankGroup().ID(); - unsigned int bank = DramExtension::getExtension(payload).getBank().ID(); - unsigned int row = DramExtension::getExtension(payload).getRow().ID(); - unsigned int col = DramExtension::getExtension(payload).getColumn().ID(); - - printDebugMessage("Recording " + phaseNameToString(phase) + " thread " + - to_string(thr) + " channel " + to_string(ch) + " bank group " + to_string( - bg) + " bank " + to_string(bank) + " row " + to_string(row) + " column " + - to_string(col) + " at " + recTime.to_string()); - - tlmRecorder->recordPhase(payload, phase, recTime); - - return Dram::nb_transport_fw(payload, phase, delay); - } - // When working with floats, we have to decide ourselves what is an // acceptable definition for "equal". Here the number is compared with a // suitable error margin (0.00001). - bool is_equal(double a, double b, const double epsilon = 1e-05) + bool isEqual(double a, double b, const double epsilon = 1e-05) { return std::fabs(a - b) < epsilon; } // This Thread is only triggered when Power Simulation is enabled. // It estimates the current average power which will be stored in the trace database for visualization purposes. - void powerWindow() - { - unsigned long long clk_cycles = 0; + void powerWindow(); - do { - // At the very beginning (zero clock cycles) the energy is 0, so we wait first - wait(powerWindowSize); - - clk_cycles = sc_time_stamp().value() / - Configuration::getInstance().memSpec.clk.value(); - - DRAMPower->calcWindowEnergy(clk_cycles); - - // During operation the energy should never be zero since the device is always consuming - assert(!is_equal(DRAMPower->getEnergy().window_energy, 0.0)); - - // Store the time (in seconds) and the current average power (in mW) into the database - recordPower(); - - // Here considering that DRAMPower provides the energy in pJ and the power in mW - printDebugMessage(string("\tWindow Energy: \t") + to_string( - DRAMPower->getEnergy().window_energy * - Configuration::getInstance().NumberOfDevicesOnDIMM) + string("\t[pJ]")); - printDebugMessage(string("\tWindow Average Power: \t") + to_string( - DRAMPower->getPower().window_average_power * - Configuration::getInstance().NumberOfDevicesOnDIMM) + string("\t[mW]")); - - } while (true); - } - - void recordPower() - { - tlmRecorder->recordPower(sc_time_stamp().to_seconds(), - DRAMPower->getPower().window_average_power - * Configuration::getInstance().NumberOfDevicesOnDIMM); - } + void recordPower(); }; -#endif /* RECORDABLEDRAM_H_ */ +#endif // RECORDABLEDRAM_H diff --git a/DRAMSys/library/src/simulation/Setup.h b/DRAMSys/library/src/simulation/Setup.h index a8398686..34d064e1 100644 --- a/DRAMSys/library/src/simulation/Setup.h +++ b/DRAMSys/library/src/simulation/Setup.h @@ -39,7 +39,7 @@ #include #include -#include "../common/Utils.h" +#include "../common/utils.h" #include "TracePlayer.h" #include "StlPlayer.h" diff --git a/DRAMSys/library/src/simulation/SimpleArbiter.h b/DRAMSys/library/src/simulation/SimpleArbiter.h index ec1994ae..5434576b 100644 --- a/DRAMSys/library/src/simulation/SimpleArbiter.h +++ b/DRAMSys/library/src/simulation/SimpleArbiter.h @@ -38,9 +38,9 @@ #define SIMPLEARBITER_H #include "IArbiter.h" -#include "../common/xmlAddressdecoder.h" -#include "../common/dramExtension.h" -#include "../controller/core/TimingCalculation.h" +#include "../common/XmlAddressDecoder.h" +#include "../common/dramExtensions.h" +#include "../controller/core/timingCalculations.h" using namespace std; using namespace tlm; diff --git a/DRAMSys/library/src/simulation/StlPlayer.h b/DRAMSys/library/src/simulation/StlPlayer.h index 8e36b54b..cace8884 100644 --- a/DRAMSys/library/src/simulation/StlPlayer.h +++ b/DRAMSys/library/src/simulation/StlPlayer.h @@ -40,13 +40,14 @@ #ifndef STLPLAYER_H #define STLPLAYER_H -#include "../common/xmlAddressdecoder.h" +#include "../common/XmlAddressDecoder.h" #include "TracePlayer.h" using namespace std; using namespace tlm; -template class StlPlayer: public TracePlayer +template +class StlPlayer : public TracePlayer { public: StlPlayer(sc_module_name /*name*/, @@ -60,7 +61,7 @@ public: SC_REPORT_FATAL(0, (string("Could not open trace ") + pathToTrace).c_str()); this->playerClk = playerClk; - this->burstlength = Configuration::getInstance().memSpec.BurstLength; + this->burstlength = Configuration::getInstance().memSpec->BurstLength; this->dataLength = Configuration::getInstance().getBytesPerBurst(); this->lineCnt = 0; } @@ -86,7 +87,6 @@ public: } else { numberOfTransactions++; } - // Allocate a generic payload for this request. gp *payload = this->allocatePayload(); @@ -170,16 +170,17 @@ public: payload->set_data_ptr(data); payload->set_command(cmd); - if (relative == false) { + if (relative == false) + { // Send the transaction directly or schedule it to be sent in the future. if (sendingTime <= sc_time_stamp()) this->payloadEventQueue.notify(*payload, BEGIN_REQ, SC_ZERO_TIME); else this->payloadEventQueue.notify(*payload, BEGIN_REQ, sendingTime - sc_time_stamp()); - } else { - payloadEventQueue.notify(*payload, BEGIN_REQ, sendingTime); } + else + payloadEventQueue.notify(*payload, BEGIN_REQ, sendingTime); } private: @@ -188,7 +189,7 @@ private: unsigned int burstlength; unsigned int dataLength; - sc_time playerClk; // May be different from from the memory clock! + sc_time playerClk; // May be different from the memory clock! }; #endif // STLPLAYER_H diff --git a/DRAMSys/library/src/simulation/TemperatureController.h b/DRAMSys/library/src/simulation/TemperatureController.h index d26dc2d7..8d91d56a 100644 --- a/DRAMSys/library/src/simulation/TemperatureController.h +++ b/DRAMSys/library/src/simulation/TemperatureController.h @@ -34,8 +34,8 @@ * Matthias Jung */ -#ifndef TEMPERATURE_CONTROLLER_H_ -#define TEMPERATURE_CONTROLLER_H_ +#ifndef TEMPERATURECONTROLLER_H +#define TEMPERATURECONTROLLER_H #include #include @@ -43,7 +43,7 @@ #include #include "../common/DebugManager.h" -#include "../common/Utils.h" +#include "../common/utils.h" #include "../controller/core/configuration/Configuration.h" #ifdef THERMALSIM @@ -152,5 +152,5 @@ private: void printDebugMessage(std::string message); }; -#endif /* TEMPERATURE_CONTROLLER_H_ */ +#endif // TEMPERATURECONTROLLER_H diff --git a/DRAMSys/library/src/simulation/TraceGenerator.h b/DRAMSys/library/src/simulation/TraceGenerator.h index 04d9cc49..c6e5cd12 100644 --- a/DRAMSys/library/src/simulation/TraceGenerator.h +++ b/DRAMSys/library/src/simulation/TraceGenerator.h @@ -38,23 +38,23 @@ #ifndef TRACEGENERATOR_H #define TRACEGENERATOR_H - #include "TracePlayer.h" using namespace std; using namespace tlm; -struct TraceGenerator: public TracePlayer { +struct TraceGenerator : public TracePlayer +{ public: TraceGenerator(sc_module_name /*name*/, unsigned int clkMhz, TracePlayerListener *listener) : TracePlayer(listener), transCounter(0) { if (clkMhz == 0) - clk = Configuration::getInstance().memSpec.clk; + clk = Configuration::getInstance().memSpec->clk; else clk = FrequencyToClk(clkMhz); - this->burstlenght = Configuration::getInstance().memSpec.BurstLength; + this->burstlenght = Configuration::getInstance().memSpec->BurstLength; } virtual void nextPayload() override @@ -86,5 +86,5 @@ private: unsigned int transCounter; }; -#endif +#endif // TRACEGENERATOR_H diff --git a/DRAMSys/library/src/simulation/TracePlayer.cpp b/DRAMSys/library/src/simulation/TracePlayer.cpp index e46840b3..793dd904 100644 --- a/DRAMSys/library/src/simulation/TracePlayer.cpp +++ b/DRAMSys/library/src/simulation/TracePlayer.cpp @@ -80,7 +80,6 @@ tlm_sync_enum TracePlayer::nb_transport_bw(tlm_generic_payload &payload, void TracePlayer::peqCallback(tlm_generic_payload &payload, const tlm_phase &phase) { - if (phase == BEGIN_REQ) { payload.acquire(); sendToTarget(payload, phase, SC_ZERO_TIME); @@ -99,7 +98,8 @@ void TracePlayer::peqCallback(tlm_generic_payload &payload, transactionsReceived++; // If all answers were received: - if (finished == true && numberOfTransactions == transactionsReceived) { + if (finished == true && numberOfTransactions == transactionsReceived) + { this->terminate(); } } else if (phase == END_RESP) { @@ -108,6 +108,13 @@ void TracePlayer::peqCallback(tlm_generic_payload &payload, } } +void TracePlayer::sendToTarget(tlm_generic_payload &payload, const tlm_phase &phase, const sc_time &delay) +{ + tlm_phase TPhase = phase; + sc_time TDelay = delay; + iSocket->nb_transport_fw(payload, TPhase, TDelay); +} + void TracePlayer::setNumberOfTransactions(unsigned int n) { numberOfTransactions = n; diff --git a/DRAMSys/library/src/simulation/TracePlayer.h b/DRAMSys/library/src/simulation/TracePlayer.h index d03f5ead..fbc2e004 100644 --- a/DRAMSys/library/src/simulation/TracePlayer.h +++ b/DRAMSys/library/src/simulation/TracePlayer.h @@ -36,8 +36,8 @@ * Felipe S. Prado */ -#ifndef TRACEPLAYER_H_ -#define TRACEPLAYER_H_ +#ifndef TRACEPLAYER_H +#define TRACEPLAYER_H #include #include @@ -49,14 +49,15 @@ #include "MemoryManager.h" #include "../controller/core/configuration/Configuration.h" #include "../common/DebugManager.h" -#include "../common/xmlAddressdecoder.h" -#include "../controller/core/TimingCalculation.h" +#include "../common/XmlAddressDecoder.h" +#include "../controller/core/timingCalculations.h" #include "TracePlayerListener.h" using namespace std; using namespace tlm; -struct TracePlayer: public sc_module { +struct TracePlayer : public sc_module +{ public: tlm_utils::simple_initiator_socket iSocket; TracePlayer(TracePlayerListener *listener); @@ -77,12 +78,7 @@ private: sc_time &bwDelay); void peqCallback(tlm_generic_payload &payload, const tlm_phase &phase); void sendToTarget(tlm_generic_payload &payload, const tlm_phase &phase, - const sc_time &delay) - { - tlm_phase TPhase = phase; - sc_time TDelay = delay; - iSocket->nb_transport_fw(payload, TPhase, TDelay); - } + const sc_time &delay); MemoryManager memoryManager; unsigned int transactionsSent; unsigned int transactionsReceived; @@ -90,4 +86,4 @@ private: bool finished; }; -#endif /* TRACEPLAYER_H_ */ +#endif // TRACEPLAYER_H diff --git a/DRAMSys/library/src/simulation/TraceSetup.cpp b/DRAMSys/library/src/simulation/TraceSetup.cpp index c64eac3d..79a241d6 100644 --- a/DRAMSys/library/src/simulation/TraceSetup.cpp +++ b/DRAMSys/library/src/simulation/TraceSetup.cpp @@ -56,9 +56,10 @@ traceSetup::traceSetup(std::string uri, simulation->FirstChildElement("tracesetup"); for (tinyxml2::XMLElement *device = - tracesetup->FirstChildElement("device"); - device != NULL; - device = device->NextSiblingElement("device")) { + tracesetup->FirstChildElement("device"); + device != NULL; + device = device->NextSiblingElement("device")) + { sc_time playerClk; unsigned int frequency = device->IntAttribute("clkMhz"); @@ -83,12 +84,12 @@ traceSetup::traceSetup(std::string uri, std::string moduleName = name; // replace all '.' to '_' - std::replace( moduleName.begin(), moduleName.end(), '.', '_'); + std::replace(moduleName.begin(), moduleName.end(), '.', '_'); TracePlayer *player; - if (strcmp(ext.c_str(), "stl") == 0) { + if (ext == "stl") { player = new StlPlayer(moduleName.c_str(), stlFile, playerClk, this); - } else if (strcmp(ext.c_str(), "rstl") == 0) { + } else if (ext == "rstl") { player = new StlPlayer(moduleName.c_str(), stlFile, playerClk, this); } else { std::string error = "Unsupported file extension in " + name; diff --git a/DRAMSys/library/src/simulation/TraceSetup.h b/DRAMSys/library/src/simulation/TraceSetup.h index 901b6756..49f91049 100644 --- a/DRAMSys/library/src/simulation/TraceSetup.h +++ b/DRAMSys/library/src/simulation/TraceSetup.h @@ -39,7 +39,7 @@ #include #include -#include "../common/Utils.h" +#include "../common/utils.h" #include "TracePlayer.h" #include "StlPlayer.h" diff --git a/DRAMSys/simulator/main.cpp b/DRAMSys/simulator/main.cpp index d2716f80..956f373e 100644 --- a/DRAMSys/simulator/main.cpp +++ b/DRAMSys/simulator/main.cpp @@ -93,8 +93,20 @@ int sc_main(int argc, char **argv) traceSetup *ts = new traceSetup(SimulationXML, resources, &players); // Bind STL Players with DRAMSys: - for (auto &p : players) { - p->iSocket.bind(dramSys->tSocket); + for (size_t i = 0; i < players.size(); i++) { + if(Configuration::getInstance().CheckTLM2Protocol) + { + string str = "TLMCheckerPlayer" + std::to_string(i); + tlm_utils::tlm2_base_protocol_checker<> *playerTlmChecker = + new tlm_utils::tlm2_base_protocol_checker<>(str.c_str()); + dramSys->playersTlmCheckers.push_back(playerTlmChecker); + players[i]->iSocket.bind(dramSys->playersTlmCheckers[i]->target_socket); + dramSys->playersTlmCheckers[i]->initiator_socket.bind(dramSys->tSocket); + } + else + { + players[i]->iSocket.bind(dramSys->tSocket); + } } // Store the starting of the simulation in wallclock time: diff --git a/DRAMSys/simulator/simulator.pro b/DRAMSys/simulator/simulator.pro index adf11c06..a0b27493 100644 --- a/DRAMSys/simulator/simulator.pro +++ b/DRAMSys/simulator/simulator.pro @@ -18,6 +18,15 @@ isEmpty(systemc_target_arch) { message(SystemC target architecture is $${systemc_target_arch}) +dramsys_disable_coverage_check = $$(DRAMSYS_DISABLE_COVERAGE_CHECK) +isEmpty(dramsys_disable_coverage_check) { + coverage_check = true + message(Coverage check ENABLED) +} else { + coverage_check = false + message(Coverage check DISABLED) +} + unix:!macx { message(Building on a GNU/Linux) QMAKE_RPATHDIR += $${systemc_home}/lib-$${systemc_target_arch} @@ -28,13 +37,21 @@ DEFINES += TIXML_USE_STL DEFINES += SC_INCLUDE_DYNAMIC_PROCESSES unix:!macx { - QMAKE_CXXFLAGS += -std=c++11 -O0 -g + QMAKE_CXXFLAGS += -std=c++11 -O0 -g + $$eval(coverage_check) { + QMAKE_CXXFLAGS += -fprofile-arcs -ftest-coverage -fPIC -O0 + QMAKE_LFLAGS += -lgcov --coverage + } } macx: { CONFIG += c++11 QMAKE_CXXFLAGS += -std=c++0x -stdlib=libc++ -O0 -g QMAKE_MACOSX_DEPLOYMENT_TARGET=10.14 + $$eval(coverage_check) { + QMAKE_CXXFLAGS += --coverage + QMAKE_LFLAGS += --coverage + } } INCLUDEPATH += ../library/src/simulation/ diff --git a/DRAMSys/tests/DDR3/ci.yml b/DRAMSys/tests/DDR3/ci.yml index 06cdadfa..a5afa603 100644 --- a/DRAMSys/tests/DDR3/ci.yml +++ b/DRAMSys/tests/DDR3/ci.yml @@ -2,6 +2,8 @@ example_ddr3: stage: DDR3 script: + - export GCOV_PREFIX=$(pwd) + - export GCOV_PREFIX_STRIP=$(pwd | awk -F"/" '{print NF-1}') - cd build/simulator - ./DRAMSys ../../DRAMSys/tests/DDR3/simulations/ddr3-example.xml ../../DRAMSys/tests/DDR3/ - ls -lah @@ -10,15 +12,27 @@ example_ddr3: - perl -e 'if(`sqldiff ../../DRAMSys/tests/DDR3/expected/ddr3-example_ddr3_ch0.tdb ddr3-example_ddr3_ch0.tdb` eq "") {exit(0)} else {exit(-1)}' - cd ../traceAnalyzer - python3 ../../DRAMSys/traceAnalyzer/scripts/tests.py ../simulator/ddr3-example_ddr3_ch0.tdb | if ! grep "failed"; then exit 0; else exit 1; fi + # Run Code Coverage + - lcov -q -c --rc geninfo_adjust_src_path=$GCOV_PREFIX -d ${CI_PROJECT_DIR}/build/ -o ${CI_PROJECT_DIR}/coverage/${CI_JOB_NAME}.out + + cache: + key: build + paths: + - build/ + policy: pull + artifacts: paths: - build/simulator/ddr3-example_ddr3_ch0.tdb + - coverage/${CI_JOB_NAME}.out expire_in: 2 days # Testing Reordering with FR_FCFS Scheduling Algorithm: fr_fcfs: stage: DDR3 script: + - export GCOV_PREFIX=$(pwd) + - export GCOV_PREFIX_STRIP=$(pwd | awk -F"/" '{print NF-1}') - cd build/simulator - ./DRAMSys ../../DRAMSys/tests/DDR3/simulations/ddr3-fr_fcfs.xml ../../DRAMSys/tests/DDR3/ - ls -lah @@ -27,18 +41,43 @@ fr_fcfs: - perl -e 'if(`sqldiff ../../DRAMSys/tests/DDR3/expected/ddr3-fr_fcfs_ddr3_ch0.tdb ddr3-fr_fcfs_ddr3_ch0.tdb` eq "") {exit(0)} else {exit(-1)}' - cd ../traceAnalyzer - python3 ../../DRAMSys/traceAnalyzer/scripts/tests.py ../simulator/ddr3-fr_fcfs_ddr3_ch0.tdb | if ! grep "failed"; then exit 0; else exit 1; fi + # Run Code Coverage + - lcov -q -c --rc geninfo_adjust_src_path=$GCOV_PREFIX -d ${CI_PROJECT_DIR}/build/ -o ${CI_PROJECT_DIR}/coverage/${CI_JOB_NAME}.out + + cache: + key: build + paths: + - build/ + policy: pull allow_failure: true # TODO should be removed after first tests artifacts: paths: - build/simulator/ddr3-fr_fcfs_ddr3_ch0.tdb + - coverage/${CI_JOB_NAME}.out expire_in: 2 days -# Testing with TLM Protocol Cchecker +# Testing with TLM Protocol Checker protocol_checker: stage: DDR3 script: + - export GCOV_PREFIX=$(pwd) + - export GCOV_PREFIX_STRIP=$(pwd | awk -F"/" '{print NF-1}') - cd build/simulator - - ./DRAMSys ../../DRAMSys/tests/DDR3/simulations/ddr3-protocol_checker.xml ../../DRAMSys/tests/DDR3/ + - ./DRAMSys ../../DRAMSys/tests/DDR3/simulations/ddr3-protocol_checker.xml ../../DRAMSys/tests/DDR3/ > output.txt - echo "TODO" + - ls -lah + # Run Code Coverage + - lcov -q -c --rc geninfo_adjust_src_path=$GCOV_PREFIX -d ${CI_PROJECT_DIR}/build/ -o ${CI_PROJECT_DIR}/coverage/${CI_JOB_NAME}.out + + cache: + key: build + paths: + - build/ + policy: pull + + artifacts: + paths: + - coverage/${CI_JOB_NAME}.out + expire_in: 2 days diff --git a/DRAMSys/tests/DDR3/configs/mcconfigs/fifoStrict.xml b/DRAMSys/tests/DDR3/configs/mcconfigs/fifoStrict.xml index dee4f5d4..ed869b57 100644 --- a/DRAMSys/tests/DDR3/configs/mcconfigs/fifoStrict.xml +++ b/DRAMSys/tests/DDR3/configs/mcconfigs/fifoStrict.xml @@ -1,7 +1,7 @@ - + diff --git a/DRAMSys/tests/DDR3/configs/mcconfigs/fr_fcfs.xml b/DRAMSys/tests/DDR3/configs/mcconfigs/fr_fcfs.xml index e5a6579e..20db08cd 100644 --- a/DRAMSys/tests/DDR3/configs/mcconfigs/fr_fcfs.xml +++ b/DRAMSys/tests/DDR3/configs/mcconfigs/fr_fcfs.xml @@ -1,7 +1,7 @@ - + diff --git a/DRAMSys/tests/TLM_compliance/fifoStrict.xml b/DRAMSys/tests/TLM_compliance/fifoStrict.xml index d5814755..440f465a 100644 --- a/DRAMSys/tests/TLM_compliance/fifoStrict.xml +++ b/DRAMSys/tests/TLM_compliance/fifoStrict.xml @@ -2,7 +2,7 @@ - + diff --git a/DRAMSys/tests/WIDEIO/ci.yml b/DRAMSys/tests/WIDEIO/ci.yml index 76ca5555..e04215e0 100644 --- a/DRAMSys/tests/WIDEIO/ci.yml +++ b/DRAMSys/tests/WIDEIO/ci.yml @@ -1,10 +1,13 @@ +# vim: set ts=4 sw=4 expandtab: example_wideio: stage: WIDEIO script: + - export GCOV_PREFIX=$(pwd) + - export GCOV_PREFIX_STRIP=$(pwd | awk -F"/" '{print NF-1}') # Generate specific traces for WIDEIO: - cd DRAMSys/tests/WIDEIO/traces/ - perl generator.pl - - cd ../../../../ + - cd - # Run DRAMSys - cd build/simulator - ./DRAMSys ../../DRAMSys/tests/WIDEIO/simulations/wideio-example.xml ../../DRAMSys/tests/WIDEIO/ @@ -15,7 +18,15 @@ example_wideio: - python3 ../../DRAMSys/traceAnalyzer/scripts/tests.py ../simulator/wideio-example_wideio_ch1.tdb | if ! grep "failed"; then exit 0; else exit 1; fi - python3 ../../DRAMSys/traceAnalyzer/scripts/tests.py ../simulator/wideio-example_wideio_ch2.tdb | if ! grep "failed"; then exit 0; else exit 1; fi - python3 ../../DRAMSys/traceAnalyzer/scripts/tests.py ../simulator/wideio-example_wideio_ch3.tdb | if ! grep "failed"; then exit 0; else exit 1; fi + # Run Code Coverage + - lcov -q -c --rc geninfo_adjust_src_path=$GCOV_PREFIX -d ${CI_PROJECT_DIR}/build/ -o ${CI_PROJECT_DIR}/coverage/${CI_JOB_NAME}.out + cache: + key: build + paths: + - build/ + policy: pull + allow_failure: true # TODO: should be removed once the problems are fixed! artifacts: @@ -24,5 +35,6 @@ example_wideio: - build/simulator/wideio-example_wideio_ch1.tdb - build/simulator/wideio-example_wideio_ch2.tdb - build/simulator/wideio-example_wideio_ch3.tdb + - coverage/${CI_JOB_NAME}.out expire_in: 2 days diff --git a/DRAMSys/tests/WIDEIO/configs/mcconfigs/fifoStrict.xml b/DRAMSys/tests/WIDEIO/configs/mcconfigs/fifoStrict.xml index dee4f5d4..ed869b57 100644 --- a/DRAMSys/tests/WIDEIO/configs/mcconfigs/fifoStrict.xml +++ b/DRAMSys/tests/WIDEIO/configs/mcconfigs/fifoStrict.xml @@ -1,7 +1,7 @@ - + diff --git a/DRAMSys/tests/dramsys-gem5/ci.yml b/DRAMSys/tests/dramsys-gem5/ci.yml new file mode 100644 index 00000000..3e7e16f4 --- /dev/null +++ b/DRAMSys/tests/dramsys-gem5/ci.yml @@ -0,0 +1,35 @@ +# vim: set ts=4 sw=4 expandtab: +dramsys-gem5-build: + stage: dramsys-gem5-build + script: + - git submodule sync + - git submodule update --init --recursive + - cd DRAMSys/tests/dramsys-gem5 + - git clone https://github.com/tukl-msd/gem5.TnT.git + - cd gem5.TnT + - ./get_essential_repos.sh + - ./build_gem5.sh + - export GEM5=${HOME}/gem5_tnt/gem5 + - export LD_LIBRARY_PATH=${LD_LIBRARY_PATH}:${GEM5}/build/ARM + - cd ../../../.. + - rm -rf build-dramsys-gem5 + - mkdir -p build-dramsys-gem5 + - cd build-dramsys-gem5 + - qmake ../DRAMSys/DRAMSys.pro + - make -j$(cat /proc/cpuinfo | grep processor | wc -l) > build.log 2>&1 + cache: + key: build + paths: + - build-dramsys-gem5/ + - DRAMSys/tests/dramsys-gem5/gem5.TnT + policy: push + + # TODO: "allow_failure" should be removed as soon the server has + # dependencies properly installed + allow_failure: true + + artifacts: + paths: + - build-dramsys-gem5/build.log + expire_in: 2 days + diff --git a/DRAMSys/tests/error/fr_fcfs.xml b/DRAMSys/tests/error/fr_fcfs.xml index c2861799..9066796c 100644 --- a/DRAMSys/tests/error/fr_fcfs.xml +++ b/DRAMSys/tests/error/fr_fcfs.xml @@ -2,7 +2,7 @@ - + diff --git a/DRAMSys/tests/simple/fifoStrict.xml b/DRAMSys/tests/simple/fifoStrict.xml index 43744c7d..247c4de3 100644 --- a/DRAMSys/tests/simple/fifoStrict.xml +++ b/DRAMSys/tests/simple/fifoStrict.xml @@ -2,7 +2,7 @@ - + diff --git a/DRAMSys/tests/timing_compliance/fifoStrict.xml b/DRAMSys/tests/timing_compliance/fifoStrict.xml index 2c84267e..fc213074 100644 --- a/DRAMSys/tests/timing_compliance/fifoStrict.xml +++ b/DRAMSys/tests/timing_compliance/fifoStrict.xml @@ -2,7 +2,7 @@ - + diff --git a/DRAMSys/traceAnalyzer/scripts/tests.py b/DRAMSys/traceAnalyzer/scripts/tests.py index 27cb71a5..2d3becd9 100755 --- a/DRAMSys/traceAnalyzer/scripts/tests.py +++ b/DRAMSys/traceAnalyzer/scripts/tests.py @@ -269,9 +269,9 @@ def phase_transitions_are_valid(connection): validTransitions['PDNAB'] = set(['PRE', 'RD', 'RDA', 'WR', 'WRA', 'REFB']) validTransitions['PDNPB'] = set(['ACT', 'REFB', 'SREFB']) - validTransitions['SREFB'] = set(['ACT']) + validTransitions['SREFB'] = set(['ACT', 'REFB']) else: - validTransitions['PRE'] = set(['ACT', 'PRE_ALL']) + validTransitions['PRE'] = set(['ACT', 'PRE_ALL', 'REFA']) validTransitions['PRE_ALL'] = set(['REFA', 'SREF']) validTransitions['ACT'] = set(['RD', 'RDA', 'WR', 'WRA', 'PRE_ALL']) @@ -512,11 +512,12 @@ def max_number_ref_burst(connection): return TestSuceeded() +@test @test def max_time_without_ref(connection): - """Checks that the maximum time allowed between REFA commands""" + """Checks that the maximum time allowed between REFA/SREF commands is not exceeded""" cursor = connection.cursor() - query = """SELECT PhaseBegin, PhaseEnd FROM phases WHERE PhaseName = 'REFA' """ + query = """SELECT PhaseBegin, PhaseEnd FROM phases WHERE PhaseName = 'REFA' OR PhaseName = 'SREF' """ prevrow = [0] * 2 flexibleRef = getFlexibleRef(connection) maxRefBurst = getMaxRefBurst(connection) @@ -529,6 +530,10 @@ def max_time_without_ref(connection): else: maxTimeWithoutRef = dramconfig.tREFI + dramconfig.tRP + tolerance = 0.05 + + maxTimeWithoutRef = maxTimeWithoutRef + dramconfig.tREFI*tolerance + for row in result: timeBetweenRefs = row[0] - prevrow[1] if (timeBetweenRefs > maxTimeWithoutRef): @@ -708,10 +713,10 @@ def strict_transaction_order(connection): transactions += str(currentRow[0]) + "," if (transactions != ""): - if (dramconfig.scheduler == "FIFO_STRICT"): + if (dramconfig.scheduler == "FifoStrict"): return TestFailed("Transactions {0} is/are not in Order ".format(transactions)) else: - return TestResult(True, "Transactions are not in Order, however this is okay since no FIFO_STRICT was choosen") + return TestResult(True, "Transactions are not in Order, however this is okay since no FifoStrict was choosen") return TestSuceeded() # ----------- powerdown checks --------------------------------------- diff --git a/DRAMSys/unitTests/Testfile.h b/DRAMSys/unitTests/Testfile.h new file mode 100644 index 00000000..50726e5c --- /dev/null +++ b/DRAMSys/unitTests/Testfile.h @@ -0,0 +1,7 @@ +#include +#include "../library/src/controller/Command.h" + +TEST(testsuite, test) +{ + EXPECT_EQ(commandToString(Command::Activate), "ACT"); +} diff --git a/DRAMSys/unitTests/googleTest.pri b/DRAMSys/unitTests/googleTest.pri new file mode 100644 index 00000000..122881e3 --- /dev/null +++ b/DRAMSys/unitTests/googleTest.pri @@ -0,0 +1,23 @@ +GOOGLETEST_DIR = googletest + +!isEmpty(GOOGLETEST_DIR): { + GTEST_SRCDIR = $$GOOGLETEST_DIR/googletest + GMOCK_SRCDIR = $$GOOGLETEST_DIR/googlemock +} + +requires(exists($$GTEST_SRCDIR):exists($$GMOCK_SRCDIR)) + +!exists($$GOOGLETEST_DIR):message("No googletest src dir found - set GOOGLETEST_DIR to enable.") + +DEFINES += \ + GTEST_LANG_CXX11 + +INCLUDEPATH *= \ + $$GTEST_SRCDIR \ + $$GTEST_SRCDIR/include \ + $$GMOCK_SRCDIR \ + $$GMOCK_SRCDIR/include + +SOURCES += \ + $$GTEST_SRCDIR/src/gtest-all.cc \ + $$GMOCK_SRCDIR/src/gmock-all.cc diff --git a/DRAMSys/unitTests/googletest b/DRAMSys/unitTests/googletest new file mode 160000 index 00000000..b77e5c76 --- /dev/null +++ b/DRAMSys/unitTests/googletest @@ -0,0 +1 @@ +Subproject commit b77e5c76252bac322bb82c5b444f050bd0d92451 diff --git a/DRAMSys/unitTests/main.cpp b/DRAMSys/unitTests/main.cpp new file mode 100644 index 00000000..e76b5f95 --- /dev/null +++ b/DRAMSys/unitTests/main.cpp @@ -0,0 +1,9 @@ +#include +#include +#include "Testfile.h" + +int sc_main(int argc, char **argv) +{ + testing::InitGoogleTest(&argc, argv); + return RUN_ALL_TESTS(); +} diff --git a/DRAMSys/unitTests/unitTests.pro b/DRAMSys/unitTests/unitTests.pro new file mode 100644 index 00000000..375411e7 --- /dev/null +++ b/DRAMSys/unitTests/unitTests.pro @@ -0,0 +1,77 @@ +TARGET = unitTestsDRAMSys + +TEMPLATE = app +CONFIG += console +CONFIG -= app_bundle +CONFIG -= qt + +systemc_home = $$(SYSTEMC_HOME) +isEmpty(systemc_home) { + systemc_home = /opt/systemc +} +message(SystemC home is $${systemc_home}) + +systemc_target_arch = $$(SYSTEMC_TARGET_ARCH) +isEmpty(systemc_target_arch) { + systemc_target_arch = linux64 +} + +message(SystemC target architecture is $${systemc_target_arch}) + +dramsys_disable_coverage_check = $$(DRAMSYS_DISABLE_COVERAGE_CHECK) +isEmpty(dramsys_disable_coverage_check) { + coverage_check = true + message(Coverage check ENABLED) +} else { + coverage_check = false + message(Coverage check DISABLED) +} + +unix:!macx { + message(Building on a GNU/Linux) + QMAKE_RPATHDIR += $${systemc_home}/lib-$${systemc_target_arch} + message(Linker options QMAKE_RPATHDIR is $${QMAKE_RPATHDIR}) +} + +DEFINES += TIXML_USE_STL +DEFINES += SC_INCLUDE_DYNAMIC_PROCESSES + +unix:!macx { + QMAKE_CXXFLAGS += -std=c++11 -O0 -g + $$eval(coverage_check) { + QMAKE_CXXFLAGS += -fprofile-arcs -ftest-coverage -fPIC -O0 + QMAKE_LFLAGS += -lgcov --coverage + } +} + +macx: { + CONFIG += c++11 + QMAKE_CXXFLAGS += -std=c++0x -stdlib=libc++ -O0 -g + $$eval(coverage_check) { + QMAKE_CXXFLAGS += --coverage + QMAKE_LFLAGS += --coverage + } +} + +QMAKE_CXXFLAGS += -pthread + +INCLUDEPATH += ../library/src/simulation/ +INCLUDEPATH += $${systemc_home}/include + +LIBS += -L$${systemc_home}/lib-$${systemc_target_arch} -lsystemc -lpthread + +SOURCEHOME = ../library/src/ + +SOURCES += \ + main.cpp \ + $${SOURCEHOME}/controller/Command.cpp + + +HEADERS += \ + Testfile.h \ + $${SOURCEHOME}/controller/Command.h + +DISTFILES += ../DRAMSys.astylerc + +include(googleTest.pri) +DISTFILES += googleTest.pri diff --git a/README.md b/README.md index 22db70c4..42b094de 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,7 @@ framework that consists of models reflecting the DRAM functionality, power consumption, temperature behaviour and retention time errors. Pipeline Status: [![pipeline status](https://git.eit.uni-kl.de/ems/astdm/dram.sys/badges/master/pipeline.svg)](https://git.eit.uni-kl.de/ems/astdm/dram.sys/commits/master) - +[![Coverage report](https://git.eit.uni-kl.de/ems/astdm/dram.sys/badges/master/coverage.svg?job=coverage)](https://git.eit.uni-kl.de/ems/astdm/dram.sys/commits/master) ## Basic Setup Open a terminal window, go to your home directory, create a directory for your @@ -28,10 +28,9 @@ $ git config --global color.ui auto ``` Now clone the repository into a local folder on your computer. -Replace the occurrences of the word **user** with your own user name. ```bash -$ git clone --recursive https://user@git.eit.uni-kl.de:ems/astdm/dram.sys.git +$ git clone --recursive https://git.eit.uni-kl.de/ems/astdm/dram.sys.git ``` The *--recursive* flag tells git to initialize all submodules within the @@ -43,7 +42,7 @@ Now you can implement, test, commit and push features into a **branch**. When you consider your work stable enough to be merged into the master branch it is time to open a **merge request** using the web interface. -Your changes will be reviewed and finally integrated to the master branch. +Your changes will be reviewed and finally integrated into the master branch. After cloning go to the project directory. @@ -53,26 +52,34 @@ $ cd dram.sys ### Dependencies -Make sure you have properly installed in your system the required libraries -and programs. +Make sure you have properly installed all the required libraries and +tools in your system. - **General dependencies** -You can use [utils/install_deb.sh](./utils/install_deb.sh) in order to install dependencies. First -read and understand the script then execute it. Type your password if -required. +You may want to have a look on the convenience scripts that are located in the +[utils](./utils) folder. ```bash -$ bash install_deb.sh +$ cd utils +$ ls ``` -- **SystemC 2.3.1 and TLM 2.0** - -You can use [utils/getsysc.sh](./utils/getsysc.sh) to download and install SystemC 2.3.1 -and TLM 2.0. First read and understand the script then execute it. +You can use [utils/install_deb.sh](./utils/install_deb.sh) in order to install +dependencies. First read and understand the script, then execute it. Type your +password if required. ```bash -$ bash getsysc.sh +$ ./install_deb.sh +``` + +- **SystemC 2.3.1a and TLM-2.0** + +You can use [utils/getsysc.sh](./utils/getsysc.sh) to download and install SystemC 2.3.1a +and TLM-2.0. First read and understand the script then execute it. + +```bash +$ ./getsysc.sh ``` Alternatively, the sources can be downloaded from @@ -85,16 +92,39 @@ You can use [utils/getqwt.sh](./utils/getqwt.sh) in order to install qwt-6.1. Fi and understand the script then execute it. ```bash -$ bash getqwt.sh +$ ./getqwt.sh $ cd ~/qwt-6.1 -$ sudo make install +``` + +After that add environment variables to your ~/.bashrc. Open the file with a +text editor (e.g., nano, gedit, kate, notepad++, subl, atom, ultraedit, emacs, +vim, etc.). + +```bash +$ nano ~/.bashrc +``` + + +```bash +export LIBQWT_HOME=${HOME}/qwt-6.1/lib +export LIBQWT_HEADERS=${HOME}/qwt-6.1/src +export LD_LIBRARY_PATH=${LD_LIBRARY_PATH:+${LD_LIBRARY_PATH}:}${LIBQWT_HOME} +``` + +Remember to verify that the library was created and the header files are +located in the paths you specify. You can use the **ls** command to accomplish +that. + +```bash +$ ls ${HOME}/qwt-6.1/lib +$ ls ${HOME}/qwt-6.1/src ``` Further information about Qwt can be found [here](http://qwt.sourceforge.net/). To grant flexibility to the user the paths where to find some essential libraries and headers can be specified with environment variables. Make sure -you have the environment variables below in your ~/.bashrc file. +you have the environment variables below defined in your ~/.bashrc file. **Note that some of the variables are automatically generated by the scripts. If you install the libraries in custom paths in your system you have to adapt the @@ -104,17 +134,17 @@ environment variables accordingly**. # SystemC home and target architecture export SYSTEMC_HOME=$HOME/systemc-2.3.1a export SYSTEMC_TARGET_ARCH=linux64 +export LD_LIBRARY_PATH=${LD_LIBRARY_PATH}:${SYSTEMC_HOME}/lib-$SYSTEMC_TARGET_ARCH # DRAMSys libraries and headers export LIBPYTHON_VERSION="3.5m" export PYTHON_HOME=/usr/lib/python3.5 export PYTHON_HEADERS=/usr/include/python3.5m -export LIBQWT_HOME=/usr/local/qwt-6.1.4-svn/lib -export LIBQWT_HEADERS=/usr/local/qwt-6.1.4-svn/include +export LIBQWT_HOME=${HOME}/qwt-6.1/lib +export LIBQWT_HEADERS=${HOME}/qwt-6.1/src +export LD_LIBRARY_PATH=${LD_LIBRARY_PATH:+${LD_LIBRARY_PATH}:}${LIBQWT_HOME} -export LD_LIBRARY_PATH=${LD_LIBRARY_PATH:+${LD_LIBRARY_PATH}:}$LIBQWT_HOME -export LD_LIBRARY_PATH=${LD_LIBRARY_PATH}:${SYSTEMC_HOME}/lib-$SYSTEMC_TARGET_ARCH ``` ### Coding Style @@ -477,8 +507,8 @@ Below, the sub-configurations are listed and explained. - *NumberOfDevicesOnDIMM* (unsigned int) - Number of devices on dual inline memory module - *CheckTLM2Protocol* (boolean) - - "1": enables the TLM 2.0 Protocol Checking - - "0": disables the TLM 2.0 Protocol Checking + - "1": enables the TLM-2.0 Protocol Checking + - "0": disables the TLM-2.0 Protocol Checking - *ECCControllerMode* (string) - "Disabled": No ECC Controller is used - "Hamming": Enables an ECC Controller with classic SECDED implementation using Hamming Code @@ -676,7 +706,7 @@ Below, the sub-configurations are listed and explained. - + @@ -734,9 +764,13 @@ Below, the sub-configurations are listed and explained. - *MaxNrOfTransactions* (unsigned int) - Maximum number of transactions. - *Scheduler* (string) - - "FIFO": first in, first out - - "FIFO_STRICT": out-of-order treatment of queue elements not allowed - - "FR_FCFS": first-come, first-served + - "Fifo": first in, first out + - "FifoStrict": out-of-order treatment of queue elements not allowed + - "FrFcfs": first ready first-come-first-served + - "FrFcfsRp": first ready first-come-first-served read priority + - "FrFcfsGrp": first ready first-come-first-served grouper + - "Grp": grouper + - "SMS": will be removed - *Capsize* (unsigned int) - Capacitor cell size. - *PowerDownMode* (enum EPowerDownMode) @@ -944,7 +978,7 @@ A description of the content each directory follows. ### Log Collector Script Users can profit of running multiple simulations automatically with -[DRAMSylva](DRAMSys/library/resources/scripts/DRAMSylva/DRAMSylva.sh). +[DRAMSylva.sh]. Every time you run the script you get a new folder with the name containing the execution time: dram.sys\_YYYY\_MM\_DD-HH.MM.SS. @@ -1044,8 +1078,9 @@ If some traces in trace_list are compressed in a tar.gz and require decompression before execution the option **tgz_traces** can be set to **yes**. The tarball is specified by the variable **tgz_file** and it is expected to be available (already commited and pushed to be available after -cloning) in the [trace folder](DRAMSys/library/resources/traces). DRAMSylva -will uncompress the tarball extracting the traces before using them. +cloning) in the [trace folder](DRAMSys/library/resources/traces). +[DRAMSylva.sh] will uncompress the tarball extracting the traces before using +them. ```bash tgz_traces="yes" @@ -1056,16 +1091,15 @@ Set the variable **use_json_cfg** to **yes** in order to override sim_files with new simulation files generated from a JSON description. Otherwise the simulation files are the ones specified by sim_files. Files are expected to be available (already commited and pushed to be available after cloning) in -[configs_json](DRAMSys/library/resources/scripts/DRAMSylva/configs_json). +[configs_json]. ```bash use_json_cfg="yes" ``` All the essential simuation files are auto generated accordingly to each of -the JSON descriptions provided in **json_cfg_list**. -Several examples of JSON configuration files are provided in -[configs_json](DRAMSys/library/resources/scripts/DRAMSylva/configs_json). +the JSON descriptions provided in **json_cfg_list**. Several examples of JSON +configuration files are provided in [configs_json]. + Insert the desired simulation data in one or multiple JSON files following any of the examples provided, e.g., @@ -1073,7 +1107,7 @@ Several examples of JSON configuration files are provided in Multiple arrays are allowed and encouraged. Each array corresponds to a full simulation setup. -+ Add your JSON files to **json_cfg_list** in DRAMSylva.sh. ++ Add your JSON files to **json_cfg_list** in [DRAMSylva.sh]. ```bash json_cfg_list=" @@ -1084,11 +1118,11 @@ ref_bw.json + Commit and push your changes. -+ Run **DRAMSylva** as previously described. All generated files will be ++ Run **[DRAMSylva.sh]** as previously described. All generated files will be inside the output folder, so it will be possible to keep a perfect track of all simulations. -For more information check the documentation in [DRAMSylva](DRAMSys/library/resources/scripts/DRAMSylva). +For more information check the documentation inside [DRAMSylva folder]. ### Trace Generator Script @@ -1233,10 +1267,11 @@ $ cd SuperLU_4.3/ $ cp MAKE_INC/make.linux make.inc ``` -Make sure the SuperLUroot variable in ./make.inc is properly set (in my case $(HOME)/repos/). +Make sure the SuperLUroot variable in ./make.inc is properly set. For example, +if you downloaded it to your home folder set as follows. ```bash -SuperLUroot = $(HOME)/repos/SuperLU_4.3 +SuperLUroot = $(HOME)/SuperLU_4.3 ``` Compile the library: @@ -1263,10 +1298,10 @@ $ cd 3d-ice-2.2.6 ``` Open the file makefile.def and set some variables. Set the correct path to the -SuperLU library you just compiled (in my case $(HOME)/repos/): +SuperLU library you just compiled. ```bash -SLU_MAIN = $(HOME)/repos/SuperLU_$(SLU_VERSION) +SLU_MAIN = $(HOME)/SuperLU_$(SLU_VERSION) ``` Set the YACC variable to bison-2.4.1: @@ -1275,14 +1310,14 @@ Set the YACC variable to bison-2.4.1: YACC = bison-2.4.1 ``` -Set the systemC architecture and main folder variables: +Set the following variables with proper values. ```bash -SYSTEMC_ARCH = [linux,linux64] -SYSTEMC_MAIN = $(HOME)/repos/systemc-$(SYSTEMC_VERSION) +SYSTEMC_ARCH = linux64 +SYSTEMC_MAIN = $(HOME)/systemc-2.3.1a ``` -Compile 3D-ICE with SystemC/TLM2.0 support: +Compile 3D-ICE with SystemC TLM-2.0 support: ```bash $ make clean @@ -1379,7 +1414,7 @@ Enable the error model in fr_fcfs.xml. - + @@ -1416,7 +1451,7 @@ $ ./DRAMSys > output ## DRAMSys with gem5 Install gem5 by following the instructions on the [gem5 wiki](http://gem5.org/Documentation#Getting_Started). -Optionally, use the scripts from [gem5.TnT](https://github.com/tukl-msd/gem5.TnT) to install gem5, build it, get some benchmark programs and learn more about gem5. +Optionally, use the scripts from [gem5.TnT] to install gem5, build it, get some benchmark programs and learn more about gem5. In order to understand the SystemC coupling with gem5 it is recommended to read the documentation in the gem5 repository *util/tlm/README* and [12]. @@ -1445,13 +1480,18 @@ path to gem5, for example in the *QtCreator under Projects > Build GEM5=/path/to/gem5/ ``` +Example: + +``` +GEM5=$HOME/gem5_tnt/gem5 +``` + Optionally, export environment variables in your **~/.bashrc** file or equivalent and open a new terminal: ```bash -# In this example gem5 is located at $HOME/gem5 (that is your home folder). -# Modify the variable to use the correct location. -export GEM5=$HOME/gem5 +# In this example gem5 is located at $HOME/gem5_tnt/gem5. +export GEM5=$HOME/gem5_tnt/gem5 # Add the folder containing libgem5_opt.so to the list where libraries should # be searched for. @@ -1535,17 +1575,21 @@ Execute a hello world application: A **Hello world!** message should be printed to the standard output. -Execute a bubble sort application: +Execute applications: + +```bash +./DRAMSys_gem5 ../../DRAMSys/library/resources/simulations/ddr3-gem5-se.xml ../../DRAMSys/gem5/gem5_se/Oscar/config.ini 1 +``` ```bash ./DRAMSys_gem5 ../../DRAMSys/library/resources/simulations/ddr3-gem5-se.xml ../../DRAMSys/gem5/gem5_se/Bubblesort/config.ini 1 ``` -Wait some minutes for the bubble sort application to finish. +Wait some minutes for the application to finish. The hello application binary was copied from gem5 repository. -The bubble sort application was obtained with [gem5.TnT](https://github.com/tukl-msd/gem5.TnT). +Other applications were obtained with [gem5.TnT]. Command template for generating **.ini** configuration files follows: @@ -1578,6 +1622,145 @@ A convenience script to execute several applications automatically [**run.sh**](DRAMSys/gem5/gem5_se/run.sh) is provided . Take a look and learn from it. +### [PARSEC] FS Mode + +Full system simulation files for ARM available in [DRAMSys/gem5/gem5_fs/parsec_arm_minor_2c_8GB](DRAMSys/gem5/gem5_fs/parsec_arm_minor_2c_8GB). + +Choose the benchmark in [parsec_arm_minor_2c_8GB.rcS](DRAMSys/gem5/gem5_fs/parsec_arm_minor_2c_8GB/parsec_arm_minor_2c_8GB.rcS). + +Edit the paths in [config.ini](DRAMSys/gem5/gem5_fs/parsec_arm_minor_2c_8GB/config.ini). + +All files required to build DRAMSys_gem5 and execute the simulation (gem5 +library, benchmarks, disk image, etc.) can be obtained with [gem5.TnT]. + +Start a simulation. Example: + +```bash +dram.sys/build/gem5$ ./DRAMSys_gem5 ../../DRAMSys/library/resources/simulations/rgrsim-gem5-fs.xml ../../DRAMSys/gem5/gem5_fs/parsec_arm_minor_2c_8GB/config.ini 1 +``` + +Optionally, open another terminal or tab and connect to gem5. + +```bash +$ telnet localhost 3456 +``` + +Note: the port may vary, gem5 prints it during initialization. Example: + +``` +system.terminal: Listening for connections on port 3456 +``` + +### [PARSEC] SE Mode + + +Binaries and gem5 SE configuration files for ARM available in [DRAMSys/gem5/gem5_se/parsec-arm](DRAMSys/gem5/gem5_se/parsec-arm). + +Use [gem5.TnT] to download parsec. Example: + +Go to your **gem5.TnT** folder. Then go to **arch/arm** folder. Execute the +script *build-parsec-serial.sh*. + +```bash +gem5.TnT/arch/arm$ ./build-parsec-serial.sh +``` + +Extract inputs files. Example: + +```bash +cd $HOME/gem5_tnt/benchmarks/parsec-3.0/pkgs/kernels/canneal/inputs +tar -xf input_simdev.tar +tar -xf input_test.tar +tar -xf input_simmedium.tar +tar -xf input_simsmall.tar +tar -xf input_native.tar +tar -xf input_simlarge.tar + +cd $HOME/gem5_tnt/benchmarks/parsec-3.0/pkgs/apps/fluidanimate/inputs +tar -xf input_simdev.tar +tar -xf input_test.tar +tar -xf input_native.tar +tar -xf input_simlarge.tar +tar -xf input_simmedium.tar +tar -xf input_simsmall.tar + +cd $HOME/gem5_tnt/benchmarks/parsec-3.0/pkgs/apps/blackscholes/inputs +tar -xf input_simdev.tar +tar -xf input_test.tar +tar -xf input_native.tar +tar -xf input_simlarge.tar +tar -xf input_simmedium.tar +tar -xf input_simsmall.tar +``` + +Open [DRAMSys/gem5/gem5_se/parsec-arm/config.ini](DRAMSys/gem5/gem5_se/parsec-arm/config.ini) + +Edit **cmd=**. + +Edit **executable=**. + +Examples (**Replace USER. Use the correct path in your computer.**): + +``` +-- canneal -- + +cmd=../../DRAMSys/gem5/gem5_se/parsec-arm/canneal/canneal 1 5 100 /home/USER/gem5_tnt/benchmarks/parsec-3.0/pkgs/kernels/canneal/inputs/10.nets 1 +cmd=../../DRAMSys/gem5/gem5_se/parsec-arm/canneal/canneal 1 100 300 /home/USER/gem5_tnt/benchmarks/parsec-3.0/pkgs/kernels/canneal/inputs/100.nets 2 +cmd=../../DRAMSys/gem5/gem5_se/parsec-arm/canneal/canneal 1 10000 2000 /home/USER/gem5_tnt/benchmarks/parsec-3.0/pkgs/kernels/canneal/inputs/100000.nets 32 +cmd=../../DRAMSys/gem5/gem5_se/parsec-arm/canneal/canneal 1 15000 2000 /home/USER/gem5_tnt/benchmarks/parsec-3.0/pkgs/kernels/canneal/inputs/200000.nets 64 +cmd=../../DRAMSys/gem5/gem5_se/parsec-arm/canneal/canneal 1 15000 2000 /home/USER/gem5_tnt/benchmarks/parsec-3.0/pkgs/kernels/canneal/inputs/400000.nets 128 + +executable=../../DRAMSys/gem5/gem5_se/parsec-arm/canneal/canneal + +-- streamcluster -- + +cmd=../../DRAMSys/gem5/gem5_se/parsec-arm/streamcluster/streamcluster 2 5 1 10 10 5 none output.txt 1 +cmd=../../DRAMSys/gem5/gem5_se/parsec-arm/streamcluster/streamcluster 3 10 3 16 16 10 none output.txt 1 +cmd=../../DRAMSys/gem5/gem5_se/parsec-arm/streamcluster/streamcluster 10 20 32 4096 4096 1000 none output.txt 1 +cmd=../../DRAMSys/gem5/gem5_se/parsec-arm/streamcluster/streamcluster 10 20 64 8192 8192 1000 none output.txt 1 +cmd=../../DRAMSys/gem5/gem5_se/parsec-arm/streamcluster/streamcluster 10 20 128 16384 16384 1000 none output.txt 1 +cmd=../../DRAMSys/gem5/gem5_se/parsec-arm/streamcluster/streamcluster 10 20 128 1000000 200000 5000 none output.txt 1 + +executable=../../DRAMSys/gem5/gem5_se/parsec-arm/streamcluster/streamcluster + +-- swaptions -- + +cmd=../../DRAMSys/gem5/gem5_se/parsec-arm/swaptions/swaptions -ns 1 -sm 5 -nt 1 +cmd=../../DRAMSys/gem5/gem5_se/parsec-arm/swaptions/swaptions -ns 3 -sm 50 -nt 1 +cmd=../../DRAMSys/gem5/gem5_se/parsec-arm/swaptions/swaptions -ns 16 -sm 5000 -nt 1 +cmd=../../DRAMSys/gem5/gem5_se/parsec-arm/swaptions/swaptions -ns 32 -sm 10000 -nt 1 +cmd=../../DRAMSys/gem5/gem5_se/parsec-arm/swaptions/swaptions -ns 64 -sm 20000 -nt 1 + +executable=../../DRAMSys/gem5/gem5_se/parsec-arm/swaptions/swaptions + +-- fluidanimate -- + +cmd=../../DRAMSys/gem5/gem5_se/parsec-arm/fluidanimate/fluidanimate 1 1 /home/USER/gem5_tnt/benchmarks/parsec-3.0/pkgs/apps/fluidanimate/inputs/in_5K.fluid out.fluid +cmd=../../DRAMSys/gem5/gem5_se/parsec-arm/fluidanimate/fluidanimate 1 3 /home/USER/gem5_tnt/benchmarks/parsec-3.0/pkgs/apps/fluidanimate/inputs/in_15K.fluid out.fluid +cmd=../../DRAMSys/gem5/gem5_se/parsec-arm/fluidanimate/fluidanimate 1 5 /home/USER/gem5_tnt/benchmarks/parsec-3.0/pkgs/apps/fluidanimate/inputs/in_35K.fluid out.fluid +cmd=../../DRAMSys/gem5/gem5_se/parsec-arm/fluidanimate/fluidanimate 1 5 /home/USER/gem5_tnt/benchmarks/parsec-3.0/pkgs/apps/fluidanimate/inputs/in_100K.fluid out.fluid +cmd=../../DRAMSys/gem5/gem5_se/parsec-arm/fluidanimate/fluidanimate 1 5 /home/USER/gem5_tnt/benchmarks/parsec-3.0/pkgs/apps/fluidanimate/inputs/in_300K.fluid out.fluid + +executable=../../DRAMSys/gem5/gem5_se/parsec-arm/fluidanimate/fluidanimate + +-- blackscholes -- + +cmd=../../DRAMSys/gem5/gem5_se/parsec-arm/blackscholes/blackscholes 1 /home/USER/gem5_tnt/benchmarks/parsec-3.0/pkgs/apps/blackscholes/inputs/in_4.txt prices.txt +cmd=../../DRAMSys/gem5/gem5_se/parsec-arm/blackscholes/blackscholes 1 /home/USER/gem5_tnt/benchmarks/parsec-3.0/pkgs/apps/blackscholes/inputs/in_16.txt prices.txt +cmd=../../DRAMSys/gem5/gem5_se/parsec-arm/blackscholes/blackscholes 1 /home/USER/gem5_tnt/benchmarks/parsec-3.0/pkgs/apps/blackscholes/inputs/in_4K.txt prices.txt +cmd=../../DRAMSys/gem5/gem5_se/parsec-arm/blackscholes/blackscholes 1 /home/USER/gem5_tnt/benchmarks/parsec-3.0/pkgs/apps/blackscholes/inputs/in_16K.txt prices.txt +cmd=../../DRAMSys/gem5/gem5_se/parsec-arm/blackscholes/blackscholes 1 /home/USER/gem5_tnt/benchmarks/parsec-3.0/pkgs/apps/blackscholes/inputs/in_64K.txt prices.txt + +executable=../../DRAMSys/gem5/gem5_se/parsec-arm/blackscholes/blackscholes + +``` + +Start a simulation. Example: + +```bash +dram.sys/build/gem5$ ./DRAMSys_gem5 ../../DRAMSys/library/resources/simulations/rgrsim-gem5-se.xml ../../DRAMSys/gem5/gem5_se/parsec-arm/config.ini 1 +``` + ### Boot Linux with gem5 and DRAMSys The procedure is very similar to the traffic generator example above. @@ -1702,10 +1885,350 @@ An overview of the architcture being simulated is presented below: For more spophisticated setups, even with l2 caches the proper ini file should be created. If you need help please contact Matthias Jung. -### DRAMSys + GEM5 Log Collector Script +### DRAMSys + GEM5 Log Collector Scripts -Users can profit of running multiple simulations automatically with -[gem5ilva](DRAMSys/library/resources/scripts/DRAMSylva/gem5ilva.sh). +Users can profit of running multiple **DRAMSys + gem5** simulations +automatically with [gem5ilva.sh] for **gem5 syscall emulation (SE) mode** and +[gem5ilva_fs.sh] for **gem5 full system (FS) mode**. + +Normally you will have to push your changes before running the scripts. This +approach makes it easier to track back what exactly was tested by the scripts. + +The scripts provide variables that tell **git** where to get the source +code from (repository URL), user name to be used (your git account), +**branch** to checkout (your working branch), etc. They are: + +```bash +# Git info. +git_user="$USER" +git_branch="master" +git_url="git.eit.uni-kl.de:ems/astdm/dram.sys.git" +git_url_https="git.eit.uni-kl.de/ems/astdm/dram.sys.git" +``` + +The default values of the variables presented above assume that your git +account uses the same name as your user name in your PC. If that is not the +case, replace the value of the **git_user** variable with your git account +name. Similarly, replace the value of the variable **git_branch** with your +working branch name. There (in your working branch) you can push your changes +and/or new files before executing the scripts. + +Open the script in QtCreator or another text editor of your choice and set the +variables with values that fit your needs. + +Nevertheless, for some cases, you may want to have gem5 essential files out of +the main repository (usually because they are too big to be added to the +repository). + +For those cases uncomment and properly set the variable +**external_inifile_path** in [gem5ilva_fs.sh]. + +This allows you to use a gem5 **config.ini** file external to the repository. +Note, however, that in this case it is up to you to keep track of your +simulation setup. + +**Hint:** +[gem5.TnT] provides convenience scripts +to create gem5 disk images with benchmarking programs embedded. + +### Notes for [Elwetritsch] Users + +Firstly, take a look at [High Performance Computing at the TU Kaiserslautern](https://elwe.rhrk.uni-kl.de/). + +After that, please give yourself a change to learn a bit about [Batch Usage at +RHRK TU Kaiserslautern](https://elwe.rhrk.uni-kl.de/elwetritsch/batch.shtml). +This will probably save you some time later on. + +When using DRAMSys + gem5 on the [Elwetritsch] gem5 can be installed with +convenience scripts provided by [gem5.TnT]. + +[gem5.TnT] also provides convenience scripts +to create gem5 disk images with benchmarking programs embedded. The creation +of disk images for gem5 requires superuser privilege. A solution is to copy +(e.g., using scp or mounting a folder, etc.) the locally created disk images +to [Elwetritsch]. Since there is no compilation involved, copying disk images +created in one machine to another machine should not incur in incompatibility +problems. + +On [gem5.TnT] repository open a [gem5.TnT] config file. + +```bash +$ vim common/defaults.in +``` + +Note the variable **ROOTDIR**. Its default value is *ROOTDIR=$HOME/gem5_tnt*. +That means that [gem5.TnT] will download to *$HOME/gem5_tnt*. + +Currently the space one can use in its Elwetrich *$HOME* folder is limited to +a few tens of GiB. Nevertheless, a directory **/scratch/$USER** is provided +with less space restrictions. + +One can create a symlink pointing to **/scratch/$USER/gem5_tnt**. + +```bash +$ cd $SCRATCH +$ mkdir gem5_tnt +$ cd +$ ln -s /scratch/$USER/gem5_tnt +``` + +On [gem5.TnT] repository use the commands below to get files and build gem5: + +```bash +$ ./get_essential_fs.sh +$ ./get_benchmarks.sh +$ ./get_extra_fs.sh +$ ./build_gem5.sh +``` + +To get DRAMSys installed follow the traditional setup instructions described +in this document. + +For building DRAMSys one can profit from using [DRAMSylva.sh] which loads the +modules that are necessary for building DRAMSys on [Elwetritsch]. + +Regarding dependencies for building DRAMSys and DRAMSys + gem5, the scripts +provided inside the [DRAMSylva folder], when running on [Elwetritsch], will +load the required modules automatically. + +As usual, one may export environment variables from his/her **~/.bashrc** file +on Elwetritch. Some segments extracted from a functional ~/.bashrc file are +presented below to be used as reference. Note that you may have to adapt it, +for example, changing paths to point to the place you installed some of the +libraries. + +```bash +# User specific aliases and functions +# SystemC home +export SYSTEMC_HOME=$HOME/systemc-2.3.1a +# SystemC target architecture +export SYSTEMC_TARGET_ARCH=linux64 + +# Qwt lib +export LIBQWT_HOME=$HOME/qwt-6.1/lib +export LIBQWT_HEADERS=$HOME/qwt-6.1/src +export LD_LIBRARY_PATH=${LD_LIBRARY_PATH:+${LD_LIBRARY_PATH}:}$LIBQWT_HOME + +# Python lib +export LIBPYTHON_VERSION="3.6m" +export PYTHON_HOME=/usr/lib64 +export PYTHON_HEADERS=/usr/include/python3.6m + +# Gem5 + DRAMsys +export GEM5=$HOME/gem5_tnt/gem5 + +# Gem5 SystemC TLM-2.0 coupling (see also: $HOME/gem5_tnt/gem5/util/tlm/README) +export LD_LIBRARY_PATH=${LD_LIBRARY_PATH}:${GEM5}/build/ARM +export LD_LIBRARY_PATH=${LD_LIBRARY_PATH}:${SYSTEMC_HOME}/lib-$SYSTEMC_TARGET_ARCH +export PKG_CONFIG_PATH=${PKG_CONFIG_PATH}:${SYSTEMC_HOME}/lib-$SYSTEMC_TARGET_ARCH/pkgconfig + +# M5_PATH for gem5 +export M5_PATH=$HOME/gem5_tnt/full_system/arm/aarch-system-20180409 + +# Do not close my terminal when inactive after a timeout +unset TMOUT +``` + +[SLURM](https://slurm.schedmd.com/overview.html) **job scripts** are available +inside the [DRAMSylva folder]. They can be used directly without changes or as +examples on how to start jobs using nodes of the [Elwetritsch] cluster. Of +course, one can create his/her own job scripts. + + +### Coverage Check + +Coverage check is enabled by default and can be disabled with an environment +variable. + +```bash +export DRAMSYS_DISABLE_COVERAGE_CHECK=1 +``` + +### DRAMSys + GEM5 x86 + +Make sure you have built **gem5/build/X86/libgem5_opt.so**. If you build with +[gem5.TnT] you can check if the library exists as follows. + +```bash +$ ls $HOME/gem5_tnt/gem5/build/X86/libgem5_opt.so +``` + +Change your ~/.bashrc. + +```bash +# In this example gem5 is located at $HOME/gem5_tnt/gem5. +export GEM5=$HOME/gem5_tnt/gem5 + +# Add the folder containing libgem5_opt.so to the list where libraries should +# be searched for. +#export LD_LIBRARY_PATH=${LD_LIBRARY_PATH}:${GEM5}/build/ARM +export LD_LIBRARY_PATH=${LD_LIBRARY_PATH}:${GEM5}/build/X86 +``` + +After that close QtCreator and all terminals. + +Open a new terminal. + +Change the architecture in [DRAMSys/gem5/gem5.pro](DRAMSys/gem5/gem5.pro). + +``` +gem5_arch = 'X86' +``` + +Delete the file **DRAMSys/DRAMSys.pro.user** from the repository. + +```bash +$ rm DRAMSys/DRAMSys.pro.user +``` + +Open a new QtCreator. + +Build DRAMSys as usual. + +After building, go the the folder where *DRAMSys_gem5* is located. + +Test with a hello world application for X86. + +```bash +./DRAMSys_gem5 ../../DRAMSys/library/resources/simulations/ddr3-gem5-se.xml ../../DRAMSys/gem5/gem5_se/hello-x86/config.ini 1 +``` + +A **Hello world!** message should be printed to the standard output. + +### [MiBench] + +Applications for x86 and configuration files available in [DRAMSys/gem5/gem5_se/MiBench](DRAMSys/gem5/gem5_se/MiBench). + +Examples: + +**Automotive Applications** + +**Basicmath** +```bash +./DRAMSys_gem5 ../../DRAMSys/library/resources/simulations/ddr3-gem5-se.xml ../../DRAMSys/gem5/gem5_se/MiBench/automotive/basicmath/small/config.ini 1 +./DRAMSys_gem5 ../../DRAMSys/library/resources/simulations/ddr3-gem5-se.xml ../../DRAMSys/gem5/gem5_se/MiBench/automotive/basicmath/large/config.ini 1 +``` + +**Bitcount** +```bash +./DRAMSys_gem5 ../../DRAMSys/library/resources/simulations/ddr3-gem5-se.xml ../../DRAMSys/gem5/gem5_se/MiBench/automotive/bitcount/small/config.ini 1 +./DRAMSys_gem5 ../../DRAMSys/library/resources/simulations/ddr3-gem5-se.xml ../../DRAMSys/gem5/gem5_se/MiBench/automotive/bitcount/large/config.ini 1 +``` + +**Qsort** +```bash +./DRAMSys_gem5 ../../DRAMSys/library/resources/simulations/ddr3-gem5-se.xml ../../DRAMSys/gem5/gem5_se/MiBench/automotive/qsort/small/config.ini 1 +./DRAMSys_gem5 ../../DRAMSys/library/resources/simulations/ddr3-gem5-se.xml ../../DRAMSys/gem5/gem5_se/MiBench/automotive/qsort/large/config.ini 1 +``` + +**Susan** +```bash +./DRAMSys_gem5 ../../DRAMSys/library/resources/simulations/ddr3-gem5-se.xml ../../DRAMSys/gem5/gem5_se/MiBench/automotive/susan/small/corners/config.ini 1 +./DRAMSys_gem5 ../../DRAMSys/library/resources/simulations/ddr3-gem5-se.xml ../../DRAMSys/gem5/gem5_se/MiBench/automotive/susan/large/corners/config.ini 1 + +./DRAMSys_gem5 ../../DRAMSys/library/resources/simulations/ddr3-gem5-se.xml ../../DRAMSys/gem5/gem5_se/MiBench/automotive/susan/small/edges/config.ini 1 +./DRAMSys_gem5 ../../DRAMSys/library/resources/simulations/ddr3-gem5-se.xml ../../DRAMSys/gem5/gem5_se/MiBench/automotive/susan/large/edges/config.ini 1 + +./DRAMSys_gem5 ../../DRAMSys/library/resources/simulations/ddr3-gem5-se.xml ../../DRAMSys/gem5/gem5_se/MiBench/automotive/susan/small/smoothing/config.ini 1 +./DRAMSys_gem5 ../../DRAMSys/library/resources/simulations/ddr3-gem5-se.xml ../../DRAMSys/gem5/gem5_se/MiBench/automotive/susan/large/smoothing/config.ini 1 +``` + +**Network Applications** + +**Dijkstra** +```bash +./DRAMSys_gem5 ../../DRAMSys/library/resources/simulations/ddr3-gem5-se.xml ../../DRAMSys/gem5/gem5_se/MiBench/network/dijkstra/small/config.ini 1 +./DRAMSys_gem5 ../../DRAMSys/library/resources/simulations/ddr3-gem5-se.xml ../../DRAMSys/gem5/gem5_se/MiBench/network/dijkstra/large/config.ini 1 +``` + +**Patricia** +```bash +./DRAMSys_gem5 ../../DRAMSys/library/resources/simulations/ddr3-gem5-se.xml ../../DRAMSys/gem5/gem5_se/MiBench/network/patricia/small/config.ini 1 +./DRAMSys_gem5 ../../DRAMSys/library/resources/simulations/ddr3-gem5-se.xml ../../DRAMSys/gem5/gem5_se/MiBench/network/patricia/large/config.ini 1 +``` + +**Security Applications** + +**Blowfish Encode** +```bash +./DRAMSys_gem5 ../../DRAMSys/library/resources/simulations/ddr3-gem5-se.xml ../../DRAMSys/gem5/gem5_se/MiBench/security/blowfish/encode/small/config.ini 1 +./DRAMSys_gem5 ../../DRAMSys/library/resources/simulations/ddr3-gem5-se.xml ../../DRAMSys/gem5/gem5_se/MiBench/security/blowfish/encode/large/config.ini 1 +``` + +**Blowfish Decode** +```bash +./DRAMSys_gem5 ../../DRAMSys/library/resources/simulations/ddr3-gem5-se.xml ../../DRAMSys/gem5/gem5_se/MiBench/security/blowfish/decode/small/config.ini 1 +./DRAMSys_gem5 ../../DRAMSys/library/resources/simulations/ddr3-gem5-se.xml ../../DRAMSys/gem5/gem5_se/MiBench/security/blowfish/decode/large/config.ini 1 +``` + +**SHA** +```bash +./DRAMSys_gem5 ../../DRAMSys/library/resources/simulations/ddr3-gem5-se.xml ../../DRAMSys/gem5/gem5_se/MiBench/security/sha/small/config.ini 1 +./DRAMSys_gem5 ../../DRAMSys/library/resources/simulations/ddr3-gem5-se.xml ../../DRAMSys/gem5/gem5_se/MiBench/security/sha/large/config.ini 1 +``` + +**Telecom Applications** + +**CRC32** +```bash +./DRAMSys_gem5 ../../DRAMSys/library/resources/simulations/ddr3-gem5-se.xml ../../DRAMSys/gem5/gem5_se/MiBench/telecomm/crc32/small/config.ini 1 +./DRAMSys_gem5 ../../DRAMSys/library/resources/simulations/ddr3-gem5-se.xml ../../DRAMSys/gem5/gem5_se/MiBench/telecomm/crc32/large/config.ini 1 +``` + +**FFT** +```bash +./DRAMSys_gem5 ../../DRAMSys/library/resources/simulations/ddr3-gem5-se.xml ../../DRAMSys/gem5/gem5_se/MiBench/telecomm/fft/small/config.ini 1 +./DRAMSys_gem5 ../../DRAMSys/library/resources/simulations/ddr3-gem5-se.xml ../../DRAMSys/gem5/gem5_se/MiBench/telecomm/fft/large/config.ini 1 +``` + +**FFT-INV** +```bash +./DRAMSys_gem5 ../../DRAMSys/library/resources/simulations/ddr3-gem5-se.xml ../../DRAMSys/gem5/gem5_se/MiBench/telecomm/fft-inv/small/config.ini 1 +./DRAMSys_gem5 ../../DRAMSys/library/resources/simulations/ddr3-gem5-se.xml ../../DRAMSys/gem5/gem5_se/MiBench/telecomm/fft-inv/large/config.ini 1 +``` + +**GSM Encode** +```bash +./DRAMSys_gem5 ../../DRAMSys/library/resources/simulations/ddr3-gem5-se.xml ../../DRAMSys/gem5/gem5_se/MiBench/telecomm/gsm/encode/small/config.ini 1 +./DRAMSys_gem5 ../../DRAMSys/library/resources/simulations/ddr3-gem5-se.xml ../../DRAMSys/gem5/gem5_se/MiBench/telecomm/gsm/encode/large/config.ini 1 +``` + +**GSM Decode** +```bash +./DRAMSys_gem5 ../../DRAMSys/library/resources/simulations/ddr3-gem5-se.xml ../../DRAMSys/gem5/gem5_se/MiBench/telecomm/gsm/decode/small/config.ini 1 +./DRAMSys_gem5 ../../DRAMSys/library/resources/simulations/ddr3-gem5-se.xml ../../DRAMSys/gem5/gem5_se/MiBench/telecomm/gsm/decode/large/config.ini 1 +``` + +Check the folder [DRAMSys/gem5/gem5_se/MiBench](DRAMSys/gem5/gem5_se/MiBench) for all applications and configuration files. + +### More AARCH64 Apps + +Full system simulation files for ARM available in [DRAMSys/gem5/gem5_fs/arm64](DRAMSys/gem5/gem5_fs/arm64). + +You can edit [arm64.rcS](DRAMSys/gem5/gem5_fs/arm64/arm64.rcS) to start an application and call *m5 exit* when it finishes. + +Edit the paths in [config.ini](DRAMSys/gem5/gem5_fs/arm64/config.ini). + +All files required to build DRAMSys_gem5 and execute the simulation (gem5 +library, benchmarks, disk image, etc.) can be obtained with [gem5.TnT]. + +Start a simulation. Example: + +```bash +dram.sys/build/gem5$ ./DRAMSys_gem5 ../../DRAMSys/library/resources/simulations/rgrsim-gem5-fs.xml ../../DRAMSys/gem5/gem5_fs/arm64/config.ini 1 +``` + +Optionally, open another terminal or tab and connect to gem5. + +```bash +$ telnet localhost 3456 +``` + +Note: the port may vary, gem5 prints it during initialization. Example: + +``` +system.terminal: Listening for connections on port 3456 +``` ## References @@ -1756,3 +2279,13 @@ Conference on Embedded Computer Systems Architectures Modeling and Simulation Portable Radhika Jagtap, Stephan Diestelhorst, Andreas Hansson, Matthias Jung and Norbert Wehn, IEEE International Conference on Embedded Computer Systems Architectures Modeling and Simulation (SAMOS), 2016, Samos Island, Greece. + +[gem5.TnT]: https://github.com/tukl-msd/gem5.TnT +[gem5ilva.sh]: DRAMSys/library/resources/scripts/DRAMSylva/gem5ilva.sh +[gem5ilva_fs.sh]: DRAMSys/library/resources/scripts/DRAMSylva/gem5ilva_fs.sh +[Elwetritsch]: https://elwe.rhrk.uni-kl.de/ +[DRAMSylva.sh]: DRAMSys/library/resources/scripts/DRAMSylva/DRAMSylva.sh +[DRAMSylva folder]: DRAMSys/library/resources/scripts/DRAMSylva +[configs_json]: DRAMSys/library/resources/scripts/DRAMSylva/configs_json +[MiBench]: http://vhosts.eecs.umich.edu/mibench/ +[PARSEC]: http://parsec.cs.princeton.edu/ diff --git a/coding-style.md b/coding-style.md index 7647bd95..80291bc1 100644 --- a/coding-style.md +++ b/coding-style.md @@ -148,7 +148,7 @@ There is a plugin for VIM. More information can be found in ## Applying the Coding Style The script [make_pretty.sh](./utils/make_pretty.sh) applies the coding style -to the project excluding thrid party code. +to the project excluding third party code. ## References diff --git a/utils/getqwt.sh b/utils/getqwt.sh index d197a1da..b3f43208 100755 --- a/utils/getqwt.sh +++ b/utils/getqwt.sh @@ -35,11 +35,11 @@ dest=$HOME/qwt-6.1 svn checkout svn://svn.code.sf.net/p/qwt/code/branches/qwt-6.1 $dest cd $dest -qmake qwt.pro svn up -r 2481 +if [[ $(hostname -s) =~ ^head[0-9]+$ ]] || [[ $(hostname -s) =~ ^node[0-9]+$ ]]; then + # Elwetritsch cluster - heads or nodes + module load qt/5.5 +fi +qmake qwt.pro make - -# Add env. variables to ~/.bashrc -echo "export LIBQWT_HOME=/usr/local/qwt-6.1.4-svn/lib" >> ~/.bashrc -echo "export LIBQWT_HEADERS=/usr/local/qwt-6.1.4-svn/include" >> ~/.bashrc -echo "Now go to $dest and execute \"sudo make install\"." +echo "Done." diff --git a/utils/install_deb.sh b/utils/install_deb.sh index 1b4f42d9..31afe9e7 100755 --- a/utils/install_deb.sh +++ b/utils/install_deb.sh @@ -32,17 +32,18 @@ # # Author: Éder F. Zulian +distro=$(cat /etc/os-release | grep "^ID=" | sed 's/.*=//' | awk '{print tolower($0)}') # Check distro. This script supports Debian/Ubuntu -distro=`lsb_release -is` -if [ "$distro" != "Debian" ] && [ "$distro" != "Ubuntu" ]; then +if [ "$distro" != "debian" ] && [ "$distro" != "ubuntu" ]; then echo -e "Error unsupported distribution (${distro}). This script supports Debian/Ubuntu." 1>&2 - exit 1 + exit 1 fi # Ensure the newest versions of all packages currently installed sudo apt-get update sudo apt-get upgrade -# Required dependencies +# Required dependencies and useful tools deplist=" +g++ libc6 libstdc++6 gitk @@ -70,6 +71,16 @@ libqt5svg5-dev libqt5sql5 libqt5widgets5 libqt5core5a +lsb-core +gedit +sublime-text +vim-gtk +kate +wget +gtkwave +openssh-server +nautilus +telnet " for d in $deplist; do sudo apt-get -y install $d