a simple virtual machine for the guestos
License
abhaykadam/vm
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Folders and files
Name | Name | Last commit message | Last commit date | |
---|---|---|---|---|
Repository files navigation
=============================================================================== Coding Guidelines =============================================================================== * Indenting: Tabs should be used for indenting. It is recommended to configure your editor with a tab size of 8 spaces for a coherent layout with other developers of Multi2Sim. * Line wrapping: Lines should have an approximate maximum length of 80 characters, including initial tabs (and assuming a tab counts as 8 characters). Code should continue on the next line with an additional tab otherwise. Example: int long_function_with_many_arguments(int argument_1, char *arg2, int arg3) { /* Function body */ } * Comments: Comments should not use the double slash '//' notation. They should use instead the '/* */' notation. Multiple-line comments should use a '*' character at the beginning of each new line, respecting the 80-character limit of the lines. /* This is an example of a comment that spans multiple lines. When the * second line starts, an asterisk is used. */ * Code blocks: Brackets in code blocks should not share a line with other code, both for opening and closing brackets. The opening parenthesis should have no space on the left for a function declaration, but it should have it for 'if', 'while', and 'for' blocks. Examples: void function(int arg1, char *arg2) { } if (cond) { /* Block 1 */ } else { /* Block 2 */ } while (1) { } for (i = 0; i < 10; i++) only_one_line_example(); * Enumerations: Enumeration types should be named 'enum <xxx>_t', without using 'typedef' declarations. For example: enum my_enum_t { err_list_ok = 0, err_list_bounds, err_list_not_fount }; * Memory allocation: Dynamic memory allocation should be followed by a check that there was enough virtual memory available. This affects malloc, calloc, strdup, and strndup functions. Failing to allocate memory should cause a standard fatal error, as follows: void *buf; char *s; buf = malloc(100); if (!buf) fatal("%s: out of memory", __FUNCTION__); s = strdup("hello"); if (!s) fatal("%s: out of memory", __FUNCTION__); * Structure declaration: Structure types should be named 'struct <XXX>_t', without using 'typedef' declarations. For example: struct my_struct_t { int field1; char *field2; }; If a structure is used with dynamic allocation simulating a C++ object, there should be two functions 'xxx_create' and 'xxx_free' with the following structure: struct my_struct_t *my_struct_create(void) { struct my_struct_t *my_struct; /* Create object */ my_struct = calloc(1, sizeof(struct my_struct_t)); if (!my_struct) fatal("%s: out of memory", __FUNCTION__); /* Initialize */ my_struct->field1 = ... my_struct->field2 = ... /* Return */ return my_struct; } void my_struct_free(struct my_struct_t *my_struct) { [ ... free fields ... ] free(my_struct); } * Forward declarations: Forward declarations should be avoided. A source file ".c" in a library should have two sections (if used) declaring private and public functions. Private functions should be declared in the order they are used to avoid forward declarations. Public functions should be included in the ".h" file associated with the ".c" source (or common for the entire library). For example: /* * Private Functions */ static void func1() { ... } [ 2 line breaks ] static void func2() { ... } [ 4 line breaks ] /* * Public Functions */ void public_func1() { ... } * Variables declaration Variables should be declared only at the beginning of code blocks (can be primary or secondary code blocks). Variables declared for a code block should be classified in categories, such as type, or location of the code where they will be used. Several variables sharing the same type should be listed in different lines. For example: static void mem_config_read_networks(struct config_t *config) { struct net_t *net; int i; char buf[MAX_STRING_SIZE]; char *section; /* Create networks */ for (section = config_section_first(config); section; section = config_section_next(config)) { char *net_name; /* Network section */ if (strncasecmp(section, "Network ", 8)) continue; net_name = section + 8; /* Create network */ net = net_create(net_name); mem_debug("\t%s\n", net_name); list_add(mem_system->net_list, net); } * Spaces: Conditions and expressions in parenthesis should be have a space on the left of the opening parenthesis. Arguments in a function and function calls should not have a space on the left of the opening parenthesis. if (condition) while (condition) for (...) void my_func_declaration(...); my_func_call(); No spaces are used after an opening parenthesis or before a closing parenthesis. One space used after commas. if (a < b) void my_func_decl(int a, int b); Spaces should be used on both sides of operators, such as assignments or arithmetic: var1 = var2; for (x = 0; x < 10; x++) a += 2; var1 = a < 3 ? 10 : 20; result = (a + 3) / 5; Type casts should be followed by a space: printf("%lld\n", (long long) value); =============================================================================== Steps to Release a New Version Release (Administrator): =============================================================================== * svn commit all previous changes * Run 'svn update' + 'svn2cl.sh' * Update AM_INIT_AUTOMAKE in 'configure.ac' * Remake all to update 'Makefiles' ~/multi2sim/trunk$ make clean ~/multi2sim/trunk$ make * Add line in Changelog: "Version X.Y.Z released" * Copy 'trunk' directory into 'tags'. For example: ~/multi2sim$ svn cp trunk tags/multi2sim-X.Y.Z * svn commit * In trunk directory, create tar ball. ~/multi2sim/trunk$ make distcheck * Copy tar ball to Multi2Sim server: scp multi2sim-X.Y.Z.tar.gz $(M2S-SERVER):public_html/files/ * Update Multi2Sim web site. * Log in. * Click toolbox -> Special Pages -> Uncategorized templates * Update 'Latest Version' and 'Latest Version Date' * Send email to multi2sim@multi2sim.org =============================================================================== Command to update Copyright in all files: =============================================================================== sources=$(find | grep \\.c$) sed -i "s,^ \* Copyright.*$, * Copyright (C) 2011 Rafael Ubal (ubal@ece.neu.edu)," $sources =============================================================================== Notes about the memory system =============================================================================== When a memory address is accessed in an SRAM bank, the access time is calculated based on the following time components: * T_precharge: time to store the contents of the row buffer into its corresponding memory location. * T_row_buf_access: base access time to the row buffer. * T_activate: time to load a memory location into the row buffer. There are three possibilities to compute the access time T_access, one for each of the following scenarios: 1) Row-closed. The row buffer is empty, and the new row needs to be activated before being accessed. T_access = T_activate + T_row_buf_access. 2) Row-hit. The row buffer contains the requested address. T_access = T_row_buf_access. 3) Row-conflict. The row buffer contains a different address. T_access = T_precharge + T_activate + T_row_buf_access. =============================================================================== Help message for memory system configuration =============================================================================== Option '--mem-config <file>' is used to configure the memory system. The configuration file is a plain-text file in the IniFile format. The memory system is formed of a set of cache modules, main memory modules, and interconnects. Interconnects can be defined in two different configuration files. The first way is using option '--net-config <file>' (use option '--help-net-config' for more information). Any network defined in the network configuration file can be referenced from the memory configuration file. These networks will be referred hereafter as external networks. The second option to define a network straight in the memory system configuration. This alternative is provided for convenience and brevity. By using sections [Network <name>], networks with a default topology are created, which include a single switch, and one bidirectional link from the switch to every end node present in the network. The following sections and variables can be used in the memory system configuration file: Section [General] defines global parameters affecting the entire memory system. PageSize = <size> (Default = 4096) Memory page size. Virtual addresses are translated into new physical addresses in ascending order at the granularity of the page size. Section [Module <name>] defines a generic memory module. This section is used to declare both caches and main memory modules accessible from CPU cores or GPU compute units. Type = {Cache|MainMemory} (Required) Type of the memory module. From the simulation point of view, the difference between a cache and a main memory module is that the former contains only a subset of the data located at the memory locations it serves. Geometry = <geo> Cache geometry, defined in a separate section of type [Geometry <geo>]. This variable is required for cache modules. LowNetwork = <net> Network connecting the module with other lower-level modules, i.e., modules closer to main memory. This variable is mandatory for caches, and should not appear for main memory modules. Value <net> can refer to an internal network defined in a [Network <net>] section, or to an external network defined in the network configuration file. LowNetworkNode = <node> If 'LowNetwork' points to an external network, node in the network that the module is mapped to. For internal networks, this variable should be omitted. HighNetwork = <net> Network connecting the module with other higher-level modules, i.e., modules closer to CPU cores or GPU compute units. For highest level modules accessible by CPU/GPU, this variable should be omitted. HighNetworkNode = <node> If 'HighNetwork' points to an external network, node that the module is mapped to. LowModules = <mod1> [<mod2> ...] List of lower-level modules. For a cache module, this variable is rquired. If there is only one lower-level module, it serves the entire address space for the current module. If there are several lower-level modules, each served a disjoint subset of the address space. This variable should be omitted for main memory modules. BlockSize = <size> Block size in bytes. This variable is required for a main memory module. It should be omitted for a cache module (in this case, the block size is specified in the corresponding cache geometry section). Latency = <cycles> Memory access latency. This variable is required for a main memory module, and should be omitted for a cache module (the access latency is specified in the corresponding cache geometry section in this case). AddressRange = { BOUNDS <low> <high> | ADDR DIV <div> MOD <mod> EQ <eq> } Physical address range served by the module. If not specified, the entire address space is served by the module. There are two possible formats for the value of 'Range': With the first format, the user can specify the lowest and highest byte included in the address range. The value in <low> must be a multiple of the module block size, and the value in <high> must be a multiple of the block size minus 1. With the second format, the address space can be split between different modules in an interleaved manner. If dividing an address by <div> and modulo <mod> makes it equal to <eq>, it is served by this module. The value of <div> must be a multiple of the block size. When a module serves only a subset of the address space, the user must make sure that the rest of the modules at the same level serve the remaining address space. Section [CacheGeometry <geo>] defines a geometry for a cache. Caches using this geometry are instantiated [Module <name>] sections. Sets = <num_sets> (Required) Number of sets in the cache. Assoc = <num_ways> (Required) Cache associativity. The total number of blocks contained in the cache is given by the product Sets * Assoc. BlockSize = <size> (Required) Size of a cache block in bytes. The total size of the cache is given by the product Sets * Assoc * BlockSize. Latency = <cycles> (Required) Hit latency for a cache in number of cycles. Policy = {LRU|FIFO|Random} (Default = LRU) Block replacement policy. MSHR = <size> (Default = 16) Miss status holding register (MSHR) size in number of entries. This value determines the maximum number of accesses that can be in flight for the cache, including the time since the access request is received, until a potential miss is resolved. Ports = <num> (Default = 2) Number of ports. The number of ports in a cache limits the number of concurrent hits. If an access is a miss, it remains in the MSHR while it is resolved, but releases the cache port. Section [Network <net>] defines an internal default interconnect, formed of a single switch connecting all modules pointing to the network. For every module in the network, a bidirectional link is created automatically between the module and the switch, together with the suitable input/output buffers in the switch and the module. DefaultInputBufferSize = <size> Size of input buffers for end nodes (memory modules) and switch. DefaultOutputBufferSize = <size> Size of output buffers for end nodes and switch. DefaultBandwidth = <bandwidth> Bandwidth for links and switch crossbar in number of bytes per cycle. Section [Entry <name>] creates an entry into the memory system. An entry is a connection between a CPU core/thread or a GPU compute unit with a module in the memory system. Type = {CPU | GPU} Type of processing node that this entry refers to. Core = <core> CPU core identifier. This is a value between 0 and the number of cores minus 1, as defined in the CPU configuration file. This variable should be omitted for GPU entries. Thread = <thread> CPU thread identifier. Value between 0 and the number of threads per core minus 1. Omitted for GPU entries. ComputeUnit = <id> GPU compute unit identifier. Value between 0 and the number of compute units minus 1, as defined in the GPU configuration file. This variable should be omitted for CPU entries. DataModule = <mod> Module in the memory system that will serve as an entry to a CPU core/thread when reading/writing program data. The value in <mod> corresponds to a module defined in a section [Module <mod>]. Omitted for GPU entries. InstModule = <mod> Module serving as an entry to a CPU core/thread when fetching program instructions. Omitted for GPU entries. Module = <mod> Module serving as an entry to a GPU compute unit when reading/writing program data in the global memory scope. Omitted for CPU entries. =============================================================================== Help message in IPC report file =============================================================================== The IPC (instructions-per-cycle) report file shows performance value for a context at specific intervals. If a context spawns child contexts, only IPC statistics for the parent context are shown. The following fields are shown in each record: <cycle> Current simulation cycle. The increment between this value and the value shown in the next record is the interval specified in the context configuration file. <inst> Number of non-speculative instructions executed in the current interval. <ipc-glob> Global IPC observed so far. This value is equal to the number of executed non-speculative instructions divided by the current cycle. <ipc-int> IPC observed in the current interval. This value is equal to the number of instructions executed in the current interval divided by the number of cycles of the interval.
About
a simple virtual machine for the guestos
Resources
License
Stars
Watchers
Forks
Releases
No releases published
Packages 0
No packages published