From 94f465bd9b6e44b47317a3925e9f93c0513728dd Mon Sep 17 00:00:00 2001 From: John Leidel Date: Mon, 12 Feb 2018 14:39:16 -0600 Subject: [PATCH 1/4] adding dynamic cmc template --- cmc/dynamic_template/LICENSE | 10 ++ cmc/dynamic_template/Makefile | 37 +++++ cmc/dynamic_template/README | 8 + cmc/dynamic_template/cmc.c | 269 ++++++++++++++++++++++++++++++++++ include/hmc_sim_types.h | 2 +- 5 files changed, 325 insertions(+), 1 deletion(-) create mode 100644 cmc/dynamic_template/LICENSE create mode 100644 cmc/dynamic_template/Makefile create mode 100644 cmc/dynamic_template/README create mode 100644 cmc/dynamic_template/cmc.c diff --git a/cmc/dynamic_template/LICENSE b/cmc/dynamic_template/LICENSE new file mode 100644 index 0000000..db016a1 --- /dev/null +++ b/cmc/dynamic_template/LICENSE @@ -0,0 +1,10 @@ +Copyright (c) 2015, Texas Tech University +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. + +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. diff --git a/cmc/dynamic_template/Makefile b/cmc/dynamic_template/Makefile new file mode 100644 index 0000000..232a17e --- /dev/null +++ b/cmc/dynamic_template/Makefile @@ -0,0 +1,37 @@ +#!/bin/sh +# +# HMC-SIM 2.0 DYNAMIC CMC TEMPLATE MAKEFILE +# +#------------------------------------ + +include ../Makefile.inc + +#-- CHANGE THE NAME OF YOUR LIBRARY HERE +LIBNAME := dynamic_cmctemplate +#--------------------------------------- + +SRCDIR := . +BUILDDIR := build +TARGET := lib$(LIBNAME).so + +CFLAGS := $(CFLAGS) -fPIC + +SRCEXT = c +SOURCES := $(shell find $(SRCDIR) -type f -name *.$(SRCEXT)) +OBJECTS := $(patsubst $(SRCDIR)/%,$(BUILDDIR)/%,$(SOURCES:.$(SRCEXT)=.o)) +DEPS := $(OBJECTS:.o=.deps) + +$(TARGET): $(OBJECTS) + @echo " Linking... $(TARGET)"; $(CC) -shared -o $(TARGET) $(OBJECTS) +$(BUILDDIR)/%.o: $(SRCDIR)/%.$(SRCEXT) + @mkdir -p $(BUILDDIR) + @echo " CC $<"; $(CC) $(CFLAGS) -MD -MF $(@:.o=.deps) -c -o $@ $< +clean: + @echo " Cleaning..."; $(RM) -r $(BUILDDIR) $(TARGET) +install: $(TARGET) + @echo " Installing $(TARGET)"; install $(TARGET) $(PREFIX)/cmc/ +-include $(DEPS) + +.PHONY: clean install + +#--EOF diff --git a/cmc/dynamic_template/README b/cmc/dynamic_template/README new file mode 100644 index 0000000..fa8c200 --- /dev/null +++ b/cmc/dynamic_template/README @@ -0,0 +1,8 @@ +------------------------------------------------- +HMC-Sim 2.0 DYNAMIC CMC Template + +Use this sample CMC template to implement +your own CMC operations. Be sure to +read the documentation found at www.gc64.org +------------------------------------------------- +EOF diff --git a/cmc/dynamic_template/cmc.c b/cmc/dynamic_template/cmc.c new file mode 100644 index 0000000..71fe364 --- /dev/null +++ b/cmc/dynamic_template/cmc.c @@ -0,0 +1,269 @@ +/* + * _CMC_C_ + * + * Implements a dynamic CMC operation + * + */ + +#include +#include +#include +#include "hmc_sim.h" + +/* ----------------------------------------------------- GLOBALS */ +/* These globals define the CMC operation parameters, the request + enum and the command code. Modify these values for your + respective CMC operation. If more than one CMC library is used + in a simulation, these values MUST be unique across disparate + libraries. +*/ + + +/* __op_name : Contains a string representative for the trace logs */ +static char *__op_name = "DYNAMIC_TEMPLATE_OP"; + +/* __rqst : Contains the respective command enum that the simulated + : application uses to initiate a request for this command. + : See hmc_rqst_t enums from hmc_sim_types.h + : MUST BE UNIQUE ACROSS CMC LIBS +*/ +static hmc_rqst_t __rqst = CMC04; + +/* __cmd : Contains the respective command code for this CMC operation. + : This MUST match the __rqst field. For example, if we have + : CMC32 as the __rqst, then the __cmd is (uint32_t)(32). +*/ +static uint32_t __cmd = 1; + +/* __rqst_len : Contains the respective command request packet len in flits + : Permissible values are 1->17. This must include the header + : and tail flits. Commands with just an address have 1 flit. + : Commands with data will include at least two flits. + : It is up to the implementor to decode the data flits +*/ +static uint32_t __rqst_len = 1; + +/* __rsp_len : Contains the respective command response packet len in flits + : Permissible values are 0->17. This must include the header + : and tail flits. If __rsp_len is 0, then the operation + : is assumed to be posted. +*/ +static uint32_t __rsp_len = 2; + +/* __rsp_cmd : Contains the respective response command. See hmc_response_t + : enum in hmc_sim_types.h. All normal commands are permissible. + : If RSP_CMC is selected, you must also set __rsp_cmd_code +*/ +static hmc_response_t __rsp_cmd = RD_RS; + + +/* __rsp_cmd_code : Contains the command code for RSP_CMC command + : responses. The code must be <= 127 decimal. + : Unused response commands are 64->127 +*/ +static uint8_t __rsp_cmd_code = 0x00; + +/* __transient_power : Contains the transient power of the respective + : CMC operation. If this field is unknown, + : the CMC infrastructure will assume a value of 0. +*/ +static float __transient_power = 0.5; + +/* __row_ops : Contains the number of row operations for the respective + : CMC operation. If this field is unknown, the CMC + : infrastructure will assume a value of 1. +*/ +static uint32_t __row_ops = 2; + +/* __dynamic_rsp_len : Contains the instantaneous dynamic response len + : for the packet currently being processed in flits +*/ +uint32_t __dynamic_rsp_len = 0; + +/* __dynamic_rqst_len : Contains the instantaneous dynamic request len + : for the packet currently being processed in flits +*/ +uint32_t __dynamic_rqst_len = 0; + +/* __dynamic_cmc : Determines if dynamic request and response packets + : are enabled; 0=no; 1=yes +*/ +static int __dynamic_cmc = 1; + +/* ----------------------------------------------------- HMCSIM_EXECUTE_CMC */ +/* + * Performs the actual CMC operation. All your custom logic belongs in this + * function. + * + * *hmc is a void pointer to the core hmc structure. Note that this must + * be cast to (struct hmcsim_t *) + * dev is the respective device where the op is occurring + * quad is the respective quad where the op is occurring + * vault is the respective vault where the op is occurring + * bank is the respective bank where the op is occurring + * addr is the base address of the incoming request + * length is the length of the incoming request + * head is the packet head + * tail is the packet tail + * *rqst_payload is the incoming request payload formatted as the maximum + * possible packet (256 bytes of data). Its up to this function to + * pull the required bits from this payload. + * *rsp_payload is the outgoing response data payload formatted as the + * maximum possible packet (256 bytes of data). Its up to this function + * to write the required number of output bits in the response payload. + * Note that the calling infrastructure will only utilize the number of + * bytes as defined by the rsp_len of this CMC operation + * + */ +extern int hmcsim_execute_cmc( void *hmc, + uint32_t dev, + uint32_t quad, + uint32_t vault, + uint32_t bank, + uint64_t addr, + uint32_t length, + uint64_t head, + uint64_t tail, + uint64_t *rqst_payload, + uint64_t *rsp_payload ){ + + /* relevant function pointers */ + struct hmcsim_t *l_hmc = (struct hmcsim_t *)(hmc); + int (*readmem)(struct hmcsim_t *, + uint64_t, + uint64_t *, + uint32_t ) = NULL; + int (*writemem)(struct hmcsim_t *, + uint64_t, + uint64_t *, + uint32_t ) = NULL; + int (*read_cmcreg)(struct hmcsim_t *, + uint32_t, + uint64_t, + uint64_t *) = NULL; + int (*write_cmcreg)(struct hmcsim_t *, + uint32_t, + uint64_t, + uint64_t ) = NULL; + + /* init the function pointers */ + readmem = l_hmc->readmem; + writemem = l_hmc->writemem; + read_cmcreg = l_hmc->read_cmcreg; + write_cmcreg = l_hmc->write_cmcreg; + + /* + * !!! perform your operation !!! + * + */ + + return 0; +} + +/* ----------------------------------------------------- HMCSIM_REGISTER_CMC */ +/* + * Registers the target CMC library instance with the core simulation. This + * function is loaded via dlopen and called from the HMC-Sim library when + * the sim makes a call to hmcsim_load_cmc(). Most users will not need + * to change this function. + * + * *rqst is a pointer to a valid hmc_rqst_t that defines which CMC operation + * command enum that this library will utilize. See the hmc_rqst_t + * enums labeled CMCnn in ~/include/hmc_sim_types.h. + * + * *cmd is the respective command code that matches the *rqst command enum. + * For example, if *rqst returns CMC32, then the *cmd is "32". + * + * *rsp_len is the respective command's response packet length. + * This must fit within the standard HMC response packet sizes + * + * *rsp_cmd is the respective command's response command type. See + * the values defined in the hmc_response_t enum in ~/include/hmc_sim_types.h + * + * *rsp_cmd_code is the respective command's response command code in raw form. + * + */ +extern int hmcsim_register_cmc( hmc_rqst_t *rqst, + uint32_t *cmd, + uint32_t *rqst_len, + uint32_t *rsp_len, + hmc_response_t *rsp_cmd, + uint8_t *rsp_cmd_code){ + *rqst = __rqst; + *cmd = __cmd; + *rqst_len = __rqst_len; + *rsp_len = __rsp_len; + *rsp_cmd = __rsp_cmd; + *rsp_cmd_code = __rsp_cmd_code; + + return 0; +} + +/* ----------------------------------------------------- HMCSIM_CMC_DYNAMIC */ +/* + * Returns whether or not this packet contains dynamic request or response + * values. 0=no; 1=yes + * + */ +int hmcsim_cmc_dynamic(){ + return __dynamic_cmc; +} + +/* ----------------------------------------------------- HMCSIM_CMC_RSP_LEN */ +/* + * Returns the value of the dynamic packet response. + * If dynamic packets are not enabled, this function returns + * the value of __rsp_len + * + */ +uint32_t hmcsim_cmc_dynamic_rsp_len(){ + if( __dynamic_cmc == 1 ){ + return __dynamic_rsp_len; + }else{ + return __rsp_len; + } +} + +/* ----------------------------------------------------- HMCSIM_CMC_RQST_LEN */ +/* + * Returns the value of the dynamic packet request. + * If dynamic packets are not enabled, this function returns + * the value of __rqst_len + * + */ +uint32_t hmcsim_cmc_dynamic_rqst_len(){ + if( __dynamic_cmc ){ + return __dynamic_rqst_len; + }else{ + return __rqst_len; + } +} + +/* ----------------------------------------------------- HMCSIM_CMC_STR */ +/* + * Returns the name of the CMC operation for use in tracing + * Most users will not need to change this function + * + * *out is the output string that is written to + * + */ +extern void hmcsim_cmc_str( char *out ){ + sprintf( out, "%s", __op_name ); +} + + +/* ----------------------------------------------------- HMCSIM_CMC_POWER */ +/* + * Returns the amount of transient power and the number of row operations + * for this respective operation. If these values are not known, then + * the CMC infrastructure assumes a transient power of 0 and 1 row op. + * Users can modify these values based upon the runtime of the operation. + * This function is not called until AFTER the processing is complete + * + */ +extern void hmcsim_cmc_power( uint32_t *row_ops, float *tpower ){ + *row_ops = __row_ops; + *tpower = __transient_power; +} + +/* EOF */ diff --git a/include/hmc_sim_types.h b/include/hmc_sim_types.h index d43ab0d..d700dfd 100644 --- a/include/hmc_sim_types.h +++ b/include/hmc_sim_types.h @@ -451,7 +451,7 @@ struct hmcsim_t{ uint64_t idx, uint64_t *data); - int (*write_cmcreg)(struct hmcsim_t hmc, + int (*write_cmcreg)(struct hmcsim_t *hmc, uint32_t dev, uint64_t idx, uint64_t data); From 3dc1b7709b2cfe89d9a88d41fb5ab502de221cb7 Mon Sep 17 00:00:00 2001 From: John Leidel Date: Mon, 12 Feb 2018 14:50:03 -0600 Subject: [PATCH 2/4] adding support to CMC library loader for dynamic cmc functions --- cmc/dynamic_template/cmc.c | 4 ++-- include/hmc_sim_types.h | 3 +++ src/hmc_cmc.c | 20 ++++++++++++++++++++ 3 files changed, 25 insertions(+), 2 deletions(-) diff --git a/cmc/dynamic_template/cmc.c b/cmc/dynamic_template/cmc.c index 71fe364..166567c 100644 --- a/cmc/dynamic_template/cmc.c +++ b/cmc/dynamic_template/cmc.c @@ -88,7 +88,7 @@ uint32_t __dynamic_rqst_len = 0; /* __dynamic_cmc : Determines if dynamic request and response packets : are enabled; 0=no; 1=yes */ -static int __dynamic_cmc = 1; +static uint32_t __dynamic_cmc = 1; /* ----------------------------------------------------- HMCSIM_EXECUTE_CMC */ /* @@ -205,7 +205,7 @@ extern int hmcsim_register_cmc( hmc_rqst_t *rqst, * values. 0=no; 1=yes * */ -int hmcsim_cmc_dynamic(){ +uint32_t hmcsim_cmc_dynamic(){ return __dynamic_cmc; } diff --git a/include/hmc_sim_types.h b/include/hmc_sim_types.h index d700dfd..2fa29ff 100644 --- a/include/hmc_sim_types.h +++ b/include/hmc_sim_types.h @@ -326,6 +326,7 @@ struct hmc_cmc_t{ int track_power; /*! HMC-SIM: HMC_CMC_T: DOES THIS CMC OP TRACK POWER? */ uint32_t active; /*! HMC-SIM: HMC_CMC_T: SIGNALS THAT THE COMMAND IS ACTIVE */ + uint32_t dynamic; /*! HMC-SIM: HMC_CMC_T: SIGNALS THAT THE COMMAND IS DYNAMIC */ void *handle; /*! HMC-SIM: HMC_CMC_T: DLSYM HANDLE */ /* -- fptrs */ @@ -350,6 +351,8 @@ struct hmc_cmc_t{ void (*cmc_str)(char *); void (*cmc_power)(uint32_t *, /* row_ops */ float *); /* transient power */ + uint32_t (*cmc_dyn_rsp)(); /* dynamic response length */ + uint32_t (*cmc_dyn_rqst)(); /* dynamic request length */ }; struct hmc_internal_stat_t{ diff --git a/src/hmc_cmc.c b/src/hmc_cmc.c index 737c62c..59830b7 100644 --- a/src/hmc_cmc.c +++ b/src/hmc_cmc.c @@ -215,6 +215,10 @@ static int hmcsim_register_functions( struct hmcsim_t *hmc, char *cmc_lib ){ uint64_t *) = NULL; void (*cmc_str)(char *) = NULL; void (*cmc_power)(uint32_t *,float *) = NULL; + uint32_t (*cmc_dyn_rsp)() = NULL; + uint32_t (*cmc_dyn_rqst)() = NULL; + uint32_t (*cmc_dyn)() = NULL; + uint32_t dynamic = 0; /* ---- */ /* attempt to load the library */ @@ -280,6 +284,18 @@ static int hmcsim_register_functions( struct hmcsim_t *hmc, char *cmc_lib ){ /* -- hmcsim_cmc_power */ cmc_power = (void (*)(uint32_t *,float *))dlsym(handle,"hmcsim_cmc_power"); + /* hmcsim_cmc_dynamic */ + cmc_dyn = (uint32_t (*)())dlsym(handle,"hmcsim_cmc_dynamic"); + if( cmc_dyn != NULL ){ + dynamic = (*cmc_dyn)(); + } + if( dynamic ){ + /* load the remainder of the dynamic rqst/rsp functions */ + cmc_dyn_rsp = (uint32_t (*)())dlsym(handle,"hmcsim_cmc_dynamic_rsp_len"); + cmc_dyn_rqst = (uint32_t (*)())dlsym(handle,"hmcsim_cmc_dynamic_rqst_len"); + } + + /* done loading functions */ idx = hmcsim_cmc_rawtoidx( cmd ); @@ -314,6 +330,10 @@ static int hmcsim_register_functions( struct hmcsim_t *hmc, char *cmc_lib ){ hmc->cmcs[idx].cmc_execute = cmc_execute; hmc->cmcs[idx].cmc_str = cmc_str; + hmc->cmcs[idx].dynamic = dynamic; + hmc->cmcs[idx].cmc_dyn_rsp = cmc_dyn_rsp; + hmc->cmcs[idx].cmc_dyn_rqst = cmc_dyn_rqst; + return 0; } From 93e4aba98d019ea6550a97a37c48c32d897eafd6 Mon Sep 17 00:00:00 2001 From: John Leidel Date: Mon, 12 Feb 2018 15:38:39 -0600 Subject: [PATCH 3/4] adding functionality to query dynamic request and response packet length from the remainder of the CMC infrastrcuture --- cmc/dynamic_template/cmc.c | 4 ++++ src/hmc_cmc.c | 16 +++++++++++++++- 2 files changed, 19 insertions(+), 1 deletion(-) diff --git a/cmc/dynamic_template/cmc.c b/cmc/dynamic_template/cmc.c index 166567c..b3c4ec8 100644 --- a/cmc/dynamic_template/cmc.c +++ b/cmc/dynamic_template/cmc.c @@ -196,6 +196,10 @@ extern int hmcsim_register_cmc( hmc_rqst_t *rqst, *rsp_cmd = __rsp_cmd; *rsp_cmd_code = __rsp_cmd_code; + /* initialize the dynamic packet lengths */ + __dynamic_rsp_len = __rsp_len; + __dynamic_rqst_len = __rqst_len; + return 0; } diff --git a/src/hmc_cmc.c b/src/hmc_cmc.c index 59830b7..7124677 100644 --- a/src/hmc_cmc.c +++ b/src/hmc_cmc.c @@ -344,6 +344,7 @@ extern int hmcsim_query_cmc( struct hmcsim_t *hmc, uint8_t *cmd ){ /* vars */ uint32_t idx = HMC_MAX_CMC; + uint32_t (*cmc_dyn_rqst)() = NULL; /* ---- */ idx = hmcsim_cmc_cmdtoidx( type ); @@ -366,6 +367,13 @@ extern int hmcsim_query_cmc( struct hmcsim_t *hmc, *flits = hmc->cmcs[idx].rqst_len; *cmd = hmc->cmcs[idx].cmd; + /* check for a dynamic command */ + if( hmc->cmcs[idx].dynamic == 1){ + // this cmc command has a dynamic request or response length + cmc_dyn_rqst = hmc->cmcs[idx].cmc_dyn_rqst; + *flits = (*cmc_dyn_rqst)(); + } + return 0; } @@ -405,6 +413,7 @@ extern int hmcsim_process_cmc( struct hmcsim_t *hmc, uint64_t *) = NULL; void (*cmc_str)(char *); void (*cmc_power)(uint32_t *,float *) = NULL; + uint32_t (*cmc_dyn_rsp)() = NULL; /* ---- */ /* resolve the index of the cmc in the lookup table */ @@ -450,7 +459,12 @@ extern int hmcsim_process_cmc( struct hmcsim_t *hmc, #endif /* register all the response data */ - *rsp_len = hmc->cmcs[idx].rsp_len; + if( hmc->cmcs[idx].dynamic == 1 ){ + cmc_dyn_rsp = hmc->cmcs[idx].cmc_dyn_rsp; + *rsp_len = (*cmc_dyn_rsp)(); + }else{ + *rsp_len = hmc->cmcs[idx].rsp_len; + } *rsp_cmd = hmc->cmcs[idx].rsp_cmd; if( *rsp_len > 0 ){ From 2d868e60a2208c562e5994fdb5c4b7c6550a4c65 Mon Sep 17 00:00:00 2001 From: John Leidel Date: Tue, 13 Feb 2018 08:21:48 -0600 Subject: [PATCH 4/4] adding dyn cmc test for dynamic cmc operations and fixing several bugs in the dynamic_cmc template source --- cmc/dynamic_template/cmc.c | 2 +- src/hmc_cmc.c | 4 +- test/Makefile | 2 +- test/dyn_cmc/Makefile | 22 ++ test/dyn_cmc/README | 4 + test/dyn_cmc/scripts/runall.sh | 4 + test/dyn_cmc/scripts/smalltest_4GB.sh | 23 +++ test/dyn_cmc/scripts/smalltest_8GB.sh | 22 ++ test/dyn_cmc/src/.execute_test.c.swp | Bin 0 -> 20480 bytes test/dyn_cmc/src/dyn_cmc.c | 279 ++++++++++++++++++++++++++ test/dyn_cmc/src/execute_test.c | 210 +++++++++++++++++++ test/dyn_cmc/src/shiftamt.c | 132 ++++++++++++ 12 files changed, 700 insertions(+), 4 deletions(-) create mode 100644 test/dyn_cmc/Makefile create mode 100644 test/dyn_cmc/README create mode 100755 test/dyn_cmc/scripts/runall.sh create mode 100755 test/dyn_cmc/scripts/smalltest_4GB.sh create mode 100755 test/dyn_cmc/scripts/smalltest_8GB.sh create mode 100644 test/dyn_cmc/src/.execute_test.c.swp create mode 100644 test/dyn_cmc/src/dyn_cmc.c create mode 100644 test/dyn_cmc/src/execute_test.c create mode 100644 test/dyn_cmc/src/shiftamt.c diff --git a/cmc/dynamic_template/cmc.c b/cmc/dynamic_template/cmc.c index b3c4ec8..a49ecc3 100644 --- a/cmc/dynamic_template/cmc.c +++ b/cmc/dynamic_template/cmc.c @@ -33,7 +33,7 @@ static hmc_rqst_t __rqst = CMC04; : This MUST match the __rqst field. For example, if we have : CMC32 as the __rqst, then the __cmd is (uint32_t)(32). */ -static uint32_t __cmd = 1; +static uint32_t __cmd = 4; /* __rqst_len : Contains the respective command request packet len in flits : Permissible values are 1->17. This must include the header diff --git a/src/hmc_cmc.c b/src/hmc_cmc.c index 7124677..9891d45 100644 --- a/src/hmc_cmc.c +++ b/src/hmc_cmc.c @@ -300,8 +300,8 @@ static int hmcsim_register_functions( struct hmcsim_t *hmc, char *cmc_lib ){ idx = hmcsim_cmc_rawtoidx( cmd ); #ifdef HMC_DEBUG - printf( "HMCSIM_REGISTER_FUNCTIONS: Setting CMC command at IDX=%d to ACTIVE\n", - idx ); + printf( "HMCSIM_REGISTER_FUNCTIONS: Setting CMC command (%d) at IDX=%d to ACTIVE\n", + cmd,idx ); #endif if( hmc->cmcs[idx].active == 1 ){ diff --git a/test/Makefile b/test/Makefile index 8b675cb..fb86378 100644 --- a/test/Makefile +++ b/test/Makefile @@ -5,7 +5,7 @@ # Drives building all the hmcsim tests -SUBDIRS := simple simple_cmc hmc_physrand decode_physrand stream stream_power mutex mutex_linear sst_init fe_linear fe_tree load_fe gups stream_power_config stream_power_tecplot simple_api +SUBDIRS := simple simple_cmc hmc_physrand decode_physrand stream stream_power mutex mutex_linear sst_init fe_linear fe_tree load_fe gups stream_power_config stream_power_tecplot simple_api dyn_cmc CLEANDIRS := $(addsuffix .clean, $(SUBDIRS)) diff --git a/test/dyn_cmc/Makefile b/test/dyn_cmc/Makefile new file mode 100644 index 0000000..f6e2a1e --- /dev/null +++ b/test/dyn_cmc/Makefile @@ -0,0 +1,22 @@ +#!/bin/sh +# +# HMCSIM TEST APPLICATIONS +# +# TEST: DYN_CMC +# --------------------------------------- + +include ../Makefile.inc + +SRC=./src + +all: dyn_cmc +$(SRC)/shiftamt.o: $(SRC)/shiftamt.c + $(CC) $(CFLAGS) -c -o $@ $< +$(SRC)/execute_test.o: $(SRC)/execute_test.c + $(CC) $(CFLAGS) -c -o $@ $< +$(SRC)/dyn_cmc.o: $(SRC)/dyn_cmc.c + $(CC) $(CFLAGS) -c -o $@ $< +dyn_cmc: $(SRC)/dyn_cmc.o $(SRC)/shiftamt.o $(SRC)/execute_test.o + $(CC) $(CFLAGS) -o $@ $(SRC)/dyn_cmc.o $(SRC)/shiftamt.o $(SRC)/execute_test.o $(LDFLAGS) $(LDLIBS) +clean: + rm -Rf ./dyn_cmc ./src/*.o diff --git a/test/dyn_cmc/README b/test/dyn_cmc/README new file mode 100644 index 0000000..f4183a4 --- /dev/null +++ b/test/dyn_cmc/README @@ -0,0 +1,4 @@ +DYN_CMC HMCSIM-2.0 EXAMPLE +----------------------------- +tests the simple initialization +and use of a dynamic cmc library diff --git a/test/dyn_cmc/scripts/runall.sh b/test/dyn_cmc/scripts/runall.sh new file mode 100755 index 0000000..ec454c4 --- /dev/null +++ b/test/dyn_cmc/scripts/runall.sh @@ -0,0 +1,4 @@ +#!/bin/bash + +./smalltest_4GB.sh +./smalltest_8GB.sh diff --git a/test/dyn_cmc/scripts/smalltest_4GB.sh b/test/dyn_cmc/scripts/smalltest_4GB.sh new file mode 100755 index 0000000..0108235 --- /dev/null +++ b/test/dyn_cmc/scripts/smalltest_4GB.sh @@ -0,0 +1,23 @@ +#!/bin/bash + +ulimit -s unlimited + +MUTEX=../dyn_cmc +RUNDIR=`pwd` + +BANKS=16 +CAPACITY=4 +LINKS=4 +BSIZE=64 +QDEPTH=64 +XDEPTH=128 +VAULTS=32 +DRAMS=20 +LIBSRC=../../../cmc/ + + +echo "Executing $MUTEX -L $LIBSRC -b $BANKS -c $CAPACITY -d $DRAMS -l $LINKS -m $BSIZE -n 1 -q $QDEPTH -v $VAULTS -x $XDEPTH" + + +$MUTEX -L $LIBSRC -b $BANKS -c $CAPACITY -d $DRAMS -l $LINKS -m $BSIZE -n 1 -q $QDEPTH -v $VAULTS -x $XDEPTH + diff --git a/test/dyn_cmc/scripts/smalltest_8GB.sh b/test/dyn_cmc/scripts/smalltest_8GB.sh new file mode 100755 index 0000000..5611cfd --- /dev/null +++ b/test/dyn_cmc/scripts/smalltest_8GB.sh @@ -0,0 +1,22 @@ +#!/bin/bash + +ulimit -s unlimited + +MUTEX=../dyn_cmc +RUNDIR=`pwd` + +BANKS=16 +CAPACITY=8 +LINKS=8 +BSIZE=64 +QDEPTH=64 +XDEPTH=128 +VAULTS=64 +DRAMS=20 +LIBSRC=../../../cmc/ + + +echo "Executing $MUTEX -L $LIBSRC -b $BANKS -c $CAPACITY -d $DRAMS -l $LINKS -m $BSIZE -n 1 -q $QDEPTH -v $VAULTS -x $XDEPTH" + + +$MUTEX -L $LIBSRC -b $BANKS -c $CAPACITY -d $DRAMS -l $LINKS -m $BSIZE -n 1 -q $QDEPTH -v $VAULTS -x $XDEPTH diff --git a/test/dyn_cmc/src/.execute_test.c.swp b/test/dyn_cmc/src/.execute_test.c.swp new file mode 100644 index 0000000000000000000000000000000000000000..56f3e58b49a10e26710f213ad5635ed0c3a43ec8 GIT binary patch literal 20480 zcmeI3Yit}>6~_mXkfx<60;zncpf|4KuGf!UCutfbwaaEbPBvNZI{V10gke21_D((f z$jq!`*MvZ!AT^O%B&b3wl`oZA35hptBPt=Gs;Wc_q7_0=UY`mm2vn#!pmP zrlvRal;vzwu4yV0 zr2=kP1izqyka_sen{KD)2v0pk^q_MQrw8rwu&b{|Ed3 zf8L@fe*kZS7r+(pEch1qCU_D&3_S30a1cFtJ_kIYfgIQe?gY1j&EU`5 za3A0m@I&x5@MUlbTm%n;hky<~22O$@um$|-2H1nIfG5D?paYJ84}q&&73Ed%3U~~B z2|Nmx!2)Q5V_+H#f+QFKTftlJQIubRAArlC4ODO&cx{WKJPkZ>7~BT7fL|i;^AxxQ z+MoiGU^93JV}{1ftKb>%Bxr&f_#n6iYzKcwaOo=e8F&bM7Q_xFj<#bpz1aloD_65w zwOnTVS*~zI%~sS2HgT$unaX9giaIr&&s0<`JC$YAne0)u0;5WiO{m9nS@omMJ~nVb z@e52PncLBI({))gCDQboYqIoy@yk7Dd3rs;9MfY1%Zf-nFV2jGEmBLRVhQb;%v3UY zoToDR$zo{=4HIpcEET6%<#0*OOt75>nlZ$zZcEOawrehj#Zq-+%>Uv=bIqoapdUl5 zKhdt~^QL!S`piH#Gh^Kbp-H|)qHUYa!%gv+haoW(M^XwD|{xk?$j^St38z&%k}W6U}0dYUhZ zhLkz4o}e~`hEy%@m@$@)R@=RuHU8=+<-;P@Fo-7gQ+-29H0hduM~A`&v)ER1euJi% zJn20{R5|9zs;O0+?#`EMHqgJ|)#f%>Wz8_04VtC{yVyM8-vDS?CT~U%6nB>OHtDD_9kV?j? zin_vFC6~$PPQ&R`N|~(64rdAzd9_sT)-7C$=hSplqtRwMT&AcqLA|Sv!&C6ARHjD0 zwU9j(b3d!hkn@v1`#0Q9!6%M8EoOq~&b&rgU( zdNG~u*zo@1D$inQx}yj7`(SQpj<+JgbR5^Kd2uVlYA(c6T=Q%^Vb*EK6P%R^_-s=n zXSBl1Yie*8LE`9M-mFN9-%j5(lNH8;=9q4~)pYUsCvL%8YMViJE&}cN7hZ zQ#5$u?>mDAEw7)IymTlxJqLMPcx|yVN&fgHINODq!&ha?$~GLKW^Ub@^=b{Q#!&eB zN0_JCX=q;EK`ri(VlH|nyalNf{c<=Fl;wI(NB2Ts#ggQ86h7lHRg=P@tE{4yD+;D1 ze=g9Z?BNIs!D6*s;SUe;WWtX{JewFs7A=o_sYy3lUNN!0S~bF=i>wViNW$*1B300= zw{*79vW)n{Dzr}eEn@?0IU>zzwNw-X{koNjl(AA6j0n1YoY2-p(7OW(zDhHl{`BJL zGWB02u+>fF+?az)6X<<-I=EI#@A;0~*)+a1GX zedM_CE&E8lPYDz6!N7ytAE}Q=(lAQNr@8S|*E4KuW>uQiqNHwr&}hZ@DC7J6UBxB9Lr1D{@Wi{$V+W+sszH%q_p0xiD-rv84ef%5X5zq!TPy$)- z7wp$x2QPvb!1us6z!$+hsDfSK9qh&b27U#e0~f&wa69-N_TkTi&jZ?<-wEEve)}bG z8Qc#JfNkIn?5V#B>YxPD;0Ev}+WcGa8n^KcoUu0jYpgKq?>=kP1KnEECn@q`%6GtmLua#CkOd9Z)cVFW+^$gP@obeM+=79W z0*>8s*8U5ni?B%#IVh&mgE;~&Jy;_e(}OiaH9c4dahx8qIDU|)ha4M^ATy}%M~8YT z9{Z~v%!9#>NR?$@Pd?gQZa81$bx%BxnAwJ@w+z#ddHZoNKT4`ZM<-^rZx@@bPp*fOyOixpB<3ycS#Oe1m30Ja8CC z77^WWH@()YMtb#xmw>r^wG;{UqBg^vt#xcKc(KS|GY*diKN +#include +#include +#include +#include "hmc_sim.h" + +/* ----------------------------------------------------- FUNCTION PROTOTYPES */ +extern int getshiftamount( uint32_t num_links, + uint32_t capacity, + uint32_t bsize, + uint32_t *shiftamt ); +extern int execute_test( struct hmcsim_t *hmc, + uint32_t num_threads, + uint32_t shiftamt ); + +/* ----------------------------------------------------- LOAD_CMC_LIBS */ +/* + * LOAD_CMC_LIBS + * + */ +static int load_cmc_libs( struct hmcsim_t *hmc, char *libsrc ){ + /* vars */ + int srclen = strlen( libsrc ) + 1; + char *lib = NULL; + char *mlib = "/dynamic_template/libdynamic_cmctemplate.so"; + /* ---- */ + + lib = malloc( sizeof( char ) * (strlen(mlib)+srclen) ); + if( lib == NULL ){ + printf( "ERROR : COULD NOT ALLOCATE MEMORY FOR LIB: %s\n", mlib ); + return -1; + } + + sprintf( lib, "%s%s%s", libsrc, "/", mlib ); + + + printf( "LOADING CMC LIBRARY: %s\n", mlib ); + if( hmcsim_load_cmc( hmc, lib ) != 0 ){ + printf( "ERROR : COULD NOT LOAD CMC LIBRARY : %s\n", mlib ); + return -1; + }else{ + printf( "LOADED CMC LIBRARY: %s\n", mlib ); + } + + free( lib ); + lib = NULL; + + fflush( stdout ); + + return 0; +} + +/* ----------------------------------------------------- MAIN */ +/* + * MAIN + * + */ +extern int main( int argc, char **argv ){ + /* vars */ + int ret = 0; + uint32_t i = 0; + uint32_t num_devs = 0; + uint32_t num_links = 0; + uint32_t num_vaults = 0; + uint32_t queue_depth = 0; + uint32_t num_banks = 0; + uint32_t num_drams = 0; + uint32_t capacity = 0; + uint32_t xbar_depth = 0; + uint32_t num_threads = 1; + uint32_t bsize = 128; + uint32_t shiftamt = 0; + char *libsrc = NULL; + struct hmcsim_t hmc; + /* ---- */ + + while(( ret = getopt( argc, argv, "b:c:d:hl:m:n:q:v:x:N:T:L:" )) != -1 ) + { + switch( ret ) + { + case 'b': + num_banks = (uint32_t)(atoi(optarg)); + break; + case 'c': + capacity = (uint32_t)(atoi(optarg)); + break; + case 'd': + num_drams = (uint32_t)(atoi(optarg)); + break; + case 'h': + printf( "%s%s%s\n", "usage : ", argv[0], " -bcdhlnqvx" ); + printf( " -b \n" ); + printf( " -c \n" ); + printf( " -d \n" ); + printf( " -l \n" ); + printf( " -m \n" ); + printf( " -n \n" ); + printf( " -q \n" ); + printf( " -v \n" ); + printf( " -x \n" ); + printf( " -h ...print help\n" ); + return 0; + break; + case 'l': + num_links = (uint32_t)(atoi(optarg)); + break; + case 'm': + bsize = (uint32_t)(atoi(optarg)); + break; + case 'n': + num_devs = (uint32_t)(atoi(optarg)); + break; + case 'q': + queue_depth = (uint32_t)(atoi(optarg)); + break; + case 'v': + num_vaults = (uint32_t)(atoi(optarg)); + break; + case 'x': + xbar_depth = (uint32_t)(atoi(optarg)); + break; + case 'L': + if( libsrc != NULL ){ + printf( "error : libsrc already set\n" ); + return -1; + } + libsrc = malloc( sizeof( char ) * (strlen( optarg )+1) ); + sprintf( libsrc, "%s", optarg ); + break; + case '?': + default: + printf( "%s%s%s\n", "Unknown option: see ", argv[0], + " -bcdhlmnqsvxNTL" ); + return -1; + break; + } + } + + + + /* + * get the shift amount based upon + * the max block size, device size and link count + * + */ + if( getshiftamount( num_links, capacity, bsize, &shiftamt ) != 0 ){ + printf( "FAILED TO RETRIEVE SHIFT AMOUNT\n" ); + hmcsim_free( &hmc ); + free( libsrc ); + libsrc = NULL; + } + + + /* + * init the library + * + */ + + ret = hmcsim_init(&hmc, + num_devs, + num_links, + num_vaults, + queue_depth, + num_banks, + num_drams, + capacity, + xbar_depth ); + if( ret != 0 ){ + printf( "FAILED TO INIT HMCSIM\n" ); + return -1; + }else{ + printf( "SUCCESS : INITIALIZED HMCSIM\n" ); + } + + /* + * setup the device topology + * + */ + if( num_devs > 1 ){ + /* + * MULTIPLE DEVICES + * + */ + }else{ + /* + * SINGLE DEVICE + * + */ + + for( i=0; i +#include +#include +#include +#include "hmc_sim.h" + + +/* ------------------------------------------------- RQST_PACKET_LENGTH */ +uint32_t rqst_packet_length( uint64_t header ){ + uint32_t var = 0x00; + + var = (uint32_t)((header&0x1F)>>7); + return var; +} + +/* ------------------------------------------------- ZERO_PACKET */ +/* + * ZERO_PACKET + * + */ +static void zero_packet( uint64_t *packet ) { +uint64_t i = 0x00ll; + + /* + * zero the packet + * + */ + for( i=0; i 1 ){ + // lay out packet + packet[0] = head; + for(i=0; i<((plen-1)*2); i++ ){ + packet[i+1] = payload[i]; + } + packet[(plen*2)-1] = tail; + }else{ + packet[0] = head; + packet[1] = tail; + } + ret = hmcsim_send( hmc, &(packet[0]) ); + }else{ + printf( "ERROR : FATAL : MALFORMED PACKET FROM THREAD %d\n", i ); + } + + switch( ret ){ + case 0: + /* success */ + printf( "SUCCESS : INJECTED DYNAMIC_TEMPLATE_CMC PACKET INTO DEVICE\n" ); + break; + case HMC_STALL: + printf( "FAILED : HMC DEVICE WAS STALLED ON FIRST CLOCK CYCLE\n" ); + goto complete_failure; + break; + case -1: + default: + printf( "FAILED : INITIAL DYNAMIC_TEMPLATE_CMC PACKET SEND FAILURE\n" ); + goto complete_failure; + break; + } + + }else{ + // check for response + for( i=0; inum_links; i++ ){ + ret = HMC_OK; + while( ret != HMC_STALL ){ + ret = hmcsim_recv( hmc, cub, i, &(packet[0]) ); + + if( ret == 0 ){ + /* decode the response */ + hmcsim_decode_memresponse( hmc, + &(packet[0]), + &d_response_head, + &d_response_tail, + &d_type, + &d_length, + &d_tag, + &d_rtn_tag, + &d_src_link, + &d_rrp, + &d_frp, + &d_seq, + &d_dinv, + &d_errstat, + &d_rtc, + &d_crc ); + printf( "RECEIVED PACKET WITH %d FLITS\n", d_length ); + done = 1; + }/* -- good response */ + }/* -- get all the responses */ + }/* -- end response loop */ + } + cycles++; + hmcsim_clock( hmc ); + } + + printf( "COMPLETED TEST IN %" PRIu64 " CYCLES\n", cycles ); + +complete_failure: + fclose( ofile ); + ofile = NULL; + + return 0; +} + + +/* EOF */ diff --git a/test/dyn_cmc/src/shiftamt.c b/test/dyn_cmc/src/shiftamt.c new file mode 100644 index 0000000..dce56f3 --- /dev/null +++ b/test/dyn_cmc/src/shiftamt.c @@ -0,0 +1,132 @@ +/* + * _SHIFTAMT_C_ + * + * HMCSIM GUPS TEST + * + * FUNCTIONS TO GET THE APPROPRIATE ADDRESS SHIFT AMOUNT + * + */ + + +#include +#include +#include + +/* --------------------------------------------- GETSHIFTAMOUNT */ +/* + * GETSHIFTAMOUNT + * + */ +extern int getshiftamount( uint32_t num_links, + uint32_t capacity, + uint32_t bsize, + uint32_t *shiftamt ) +{ + + if( num_links == 4 ){ + /* + * 4 link devices + * + */ + if( capacity == 2 ){ + /* + * 2GB capacity + * + */ + switch( bsize ) + { + case 32 : + *shiftamt = 5; + break; + case 64 : + *shiftamt = 6; + break; + case 128: + *shiftamt = 7; + break; + default: + return -1; + break; + } + }else if( capacity == 4 ){ + /* + * 4GB capacity + * + */ + switch( bsize ) + { + case 32 : + *shiftamt = 5; + break; + case 64 : + *shiftamt = 6; + break; + case 128: + *shiftamt = 7; + break; + default: + return -1; + break; + } + }else{ + return -1; + } + + }else if( num_links == 8 ){ + /* + * 8 link devices + * + */ + if( capacity == 4 ){ + /* + * 4GB capacity + * + */ + switch( bsize ) + { + case 32 : + *shiftamt = 5; + break; + case 64 : + *shiftamt = 6; + break; + case 128: + *shiftamt = 7; + break; + default: + return -1; + break; + } + }else if( capacity == 8 ){ + /* + * 8GB capacity + * + */ + switch( bsize ) + { + case 32 : + *shiftamt = 5; + break; + case 64 : + *shiftamt = 6; + break; + case 128: + *shiftamt = 7; + break; + default: + return -1; + break; + } + }else{ + return -1; + } + }else{ + return -1; + } + + + return 0; +} + +/* EOF */ +