diff options
| -rw-r--r-- | sources/apps/case_studies/cs3_bitwise/Makefile | 33 | ||||
| -rw-r--r-- | sources/apps/case_studies/cs3_bitwise/README.md | 23 | ||||
| -rw-r--r-- | sources/apps/case_studies/cs3_bitwise/run_tests.sh | 12 | ||||
| -rw-r--r-- | sources/apps/case_studies/cs3_bitwise/test.cpp | 309 |
4 files changed, 377 insertions, 0 deletions
diff --git a/sources/apps/case_studies/cs3_bitwise/Makefile b/sources/apps/case_studies/cs3_bitwise/Makefile new file mode 100644 index 0000000..168e445 --- /dev/null +++ b/sources/apps/case_studies/cs3_bitwise/Makefile @@ -0,0 +1,33 @@ +program_NAME := TEST +program_CXX_SRCS := test.cpp $(wildcard ../../api/*.c) $(wildcard ../../api/*.cpp) +program_CXX_OBJS := ${program_CXX_SRCS:.cpp=.o} +program_CXX_OBJS := ${program_CXX_OBJS:.c=.o} +program_OBJS := $(program_CXX_OBJS) +program_INCLUDE_DIRS := ../../api ../../../boost-lib +program_LIBRARY_DIRS := +program_LIBRARIES := +CPPFLAGS += -g -std=c++11 -pthread -O3 + +CPPFLAGS += $(foreach includedir,$(program_INCLUDE_DIRS),-I$(includedir)) +LDFLAGS += $(foreach librarydir,$(program_LIBRARY_DIRS),-L$(librarydir)) +LDFLAGS += $(foreach library,$(program_LIBRARIES),-l$(library)) + +CC=g++ + +.PHONY: all clean distclean + +all: $(program_NAME) + +$(program_NAME): $(program_OBJS) + $(CC) $(CPPFLAGS) $(program_OBJS) -o $(program_NAME) $(LDFLAGS) + +clean: + @- $(RM) $(program_NAME) + @- $(RM) $(program_OBJS) + +parser: + $(MAKE) -C ../../api/lexyacc + cp ../../api/lexyacc/smc_parser . + +distclean: clean + diff --git a/sources/apps/case_studies/cs3_bitwise/README.md b/sources/apps/case_studies/cs3_bitwise/README.md new file mode 100644 index 0000000..1db9c54 --- /dev/null +++ b/sources/apps/case_studies/cs3_bitwise/README.md @@ -0,0 +1,23 @@ +## Case Study #3: In-DRAM Bitwise Operations + +### Instructions + +1. run `make` to compile the DRAM Bender program +2. execute `run_tests.sh` to generate data under `results` directory + +### Data format + +`run_tests.sh` creates one result file for each iteration of an AND and an OR experiment. For example, `AND-log1.csv` contains the results for the first iteration of an AND experiment. + +A line in this file corresponds to a tested DRAM segment and contains the following comma separated information (taken from test.cpp, line 299): + +``` +row: The address of the first row in the tested segment +op_type: "AND" or "OR" +dp1: Value stored in the first operand +dp2: Value stored in the second operand +t1: Distance between the first ACT and the first PRE command +t2: Distance between the first PRE and the second ACT command +platext: Placement of the operands (see lines 244-264 in test.cpp) +errors: Number of bit errors in the output +```
\ No newline at end of file diff --git a/sources/apps/case_studies/cs3_bitwise/run_tests.sh b/sources/apps/case_studies/cs3_bitwise/run_tests.sh new file mode 100644 index 0000000..21c8fb5 --- /dev/null +++ b/sources/apps/case_studies/cs3_bitwise/run_tests.sh @@ -0,0 +1,12 @@ +#!/bin/bash +mkdir -p results + +for i in {1..10} +do + sudo ./TEST 1 "results/AND-log$i.csv" > /dev/null +done + +for i in {1..10} +do + sudo ./TEST 0 "results/OR-log$i.csv" > /dev/null +done diff --git a/sources/apps/case_studies/cs3_bitwise/test.cpp b/sources/apps/case_studies/cs3_bitwise/test.cpp new file mode 100644 index 0000000..2b71f66 --- /dev/null +++ b/sources/apps/case_studies/cs3_bitwise/test.cpp @@ -0,0 +1,309 @@ +#include "instruction.h" +#include "prog.h" +#include "platform.h" +#include <fstream> +#include <iostream> +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> +#include <cstring> +#include <list> +#include <bitset> + +using namespace std; + +#define buffer_size 8192*8 + +#define NUM_BANKS 1 //16 +#define NUM_ROWS (1024*32) + +// Stride register ids are fixed and should not be changed +// CASR should always be reg 0 +#define CASR 0 +// BASR should always be reg 1 +#define BASR 1 +// RASR should always be reg 2 +#define RASR 2 + +#define CONSTANT 8 +#define OP1 12 +#define OP2 13 + +#define BAR 3 +#define CAR 4 +#define RAR 5 +#define SRC 6 +#define DST 7 + +#define INIT_LOOP 9 + +#define TEMP1 10 +#define NUM_ROWS_REG 11 + + +/** + * @return an instruction formed by NOPs + */ +Inst all_nops() +{ + return __pack_mininsts(SMC_NOP(), SMC_NOP(), SMC_NOP(), SMC_NOP()); +} + +SoftMCPlatform platform; + +/** + * To send an ACT -> SLEEP t1 -> PRE -> SLEEP t2 -> ACT sequence + * This seq. will use BAR RAR1 and RAR2 registers + */ +Program genActPreActSequence(int t1, int t2, int row1_reg, int row2_reg, int bank_reg) +{ + Program ret; + // t1 -> ACT to PRE, t2 -> PRE to 2nd ACT + int sz = 3 + t1 + t2; + sz = (4-(sz%4)) + sz; + Mininst buff[sz]; + for(int i = 0 ; i < sz ; i++) + buff[i] = SMC_NOP(); + + // Overwrite with the actual sequence + buff[0] = SMC_ACT(bank_reg, 0, row1_reg, 0); + buff[1+t1] = SMC_PRE(bank_reg, 0, 0); + buff[2+t1+t2] = SMC_ACT(bank_reg, 0, row2_reg, 0); + + for(int i = 0 ; i < sz ; i+=4) + ret.add_inst(buff[i], buff[i+1], buff[i+2], buff[i+3]); + + return ret; +} + +Program genReadRange(int row_reg, int no_rows, int bank_reg) +{ + Program ret; + ret.add_inst(SMC_LI(no_rows, INIT_LOOP)); + ret.add_inst(SMC_ADD(INIT_LOOP, row_reg, INIT_LOOP)); // read until this row + ret.add_label("genReadRange:LOOP_BEGIN"); + ret.add_inst(SMC_LI(0, CAR)); + ret.add_inst(SMC_ACT(bank_reg, 0, row_reg, no_rows>1), SMC_NOP(), SMC_NOP(), SMC_NOP()); + ret.add_inst(SMC_SLEEP(4)); + for(int i = 0 ; i < 128 ; i++) + { + ret.add_inst(SMC_READ(bank_reg, 0, CAR, 1, 0, 0), SMC_NOP(), SMC_NOP(), SMC_NOP()); + ret.add_inst(SMC_NOP(), SMC_NOP(), SMC_NOP(), SMC_NOP()); + } + ret.add_inst(SMC_SLEEP(4)); + ret.add_inst(SMC_PRE(bank_reg, 0, 0), SMC_NOP(), SMC_NOP(), SMC_NOP()); + ret.add_branch(ret.BR_TYPE::BL, row_reg, INIT_LOOP, "genReadRange:LOOP_BEGIN"); + /* + ret.add_inst(SMC_SLEEP(5)); + ret.dump_registers(); + ret.add_inst(SMC_END()); + */ + ret.add_inst(SMC_SUBI(row_reg, no_rows, row_reg)); + return ret; +} + +Program writeRowSlow(unsigned int _BAR, unsigned int _RAR, unsigned int _CAR, unsigned int _PATTERN_REG, unsigned int _TEMP1, string label) +{ + Program prog; + + for (int i = 0 ; i < 16 ; i++) + prog.add_inst(SMC_LDWD(_PATTERN_REG, i)); + + prog.add_inst(SMC_LI(1024, TEMP1)); + + prog.add_inst(SMC_LI(0, _CAR)); + prog.add_inst(SMC_ACT(_BAR, 0, _RAR, 0), SMC_NOP(), SMC_NOP(), SMC_NOP()); + prog.add_inst(SMC_NOP(), SMC_NOP(), SMC_NOP(), SMC_NOP()); + prog.add_inst(SMC_NOP(), SMC_NOP(), SMC_NOP(), SMC_NOP()); + prog.add_label("WRS:BEGIN" + label); + prog.add_inst(SMC_WRITE(_BAR, 0, _CAR, 1, 0, 0), SMC_NOP(), SMC_NOP(), SMC_NOP()); + prog.add_branch(prog.BR_TYPE::BL, _CAR, TEMP1, "WRS:BEGIN" + label); + prog.add_inst(SMC_PRE(_BAR, 0, 0), SMC_NOP(), SMC_NOP(), SMC_NOP()); + prog.add_inst(SMC_SLEEP(3)); + + return prog; +} + +Program AMBITTest(bool andOp, unsigned int op1, unsigned int op2, unsigned int t1, unsigned int t2, int op1Placement, int op2Placement, int constantPlacement) +{ + Program prog; + + prog.add_inst(SMC_LI(8, CASR)); + prog.add_inst(SMC_LI(0, BASR)); + prog.add_inst(SMC_LI(1, RASR)); + prog.add_inst(SMC_LI(1, BAR)); + prog.add_inst(SMC_LI(0, RAR)); + prog.add_inst(SMC_LI(NUM_ROWS, NUM_ROWS_REG)); + prog.add_label("SEGMENT_BEGIN"); + for(int i = 0 ; i < 4 ; i++) + { + if(i == op1Placement) + { + prog.add_inst(SMC_LI(op1, OP1)); + prog.add_below(writeRowSlow(BAR, RAR, CAR, OP1, TEMP1, "one")); + } + else if (i == op2Placement) + { + prog.add_inst(SMC_LI(op2, OP2)); + prog.add_below(writeRowSlow(BAR, RAR, CAR, OP2, TEMP1, "two")); + } + else if (i == constantPlacement) + { + prog.add_inst(SMC_LI(andOp ? 0x00000000 : 0xffffffff, CONSTANT)); + prog.add_below(writeRowSlow(BAR, RAR, CAR, CONSTANT, TEMP1, "three")); + } + else + { + prog.add_inst(SMC_LI(0x00000000, CONSTANT)); + prog.add_below(writeRowSlow(BAR, RAR, CAR, CONSTANT, TEMP1, "four")); + } + prog.add_inst(SMC_ADDI(RAR, 1, RAR)); + } + + prog.add_inst(SMC_SUBI(RAR, 3, SRC)); + prog.add_inst(SMC_SUBI(RAR, 2, DST)); + prog.add_below(genActPreActSequence(t1, t2, SRC, DST, BAR)); + + prog.add_inst(SMC_NOP(), SMC_NOP(), SMC_NOP(), SMC_NOP()); + prog.add_inst(SMC_NOP(), SMC_NOP(), SMC_NOP(), SMC_NOP()); + prog.add_inst(SMC_NOP(), SMC_NOP(), SMC_NOP(), SMC_NOP()); + prog.add_inst(SMC_NOP(), SMC_NOP(), SMC_NOP(), SMC_NOP()); + prog.add_inst(SMC_NOP(), SMC_NOP(), SMC_NOP(), SMC_NOP()); + prog.add_inst(SMC_PRE(BAR, 0, 0), SMC_NOP(), SMC_NOP(), SMC_NOP()); + + //prog.dump_registers(); + + prog.add_below(genReadRange(SRC, 3, BAR)); + prog.add_branch(prog.BR_TYPE::BL, RAR, NUM_ROWS_REG, "SEGMENT_BEGIN"); + prog.add_inst(SMC_END()); + + return prog; +} + +int main(int argc, char * argv[]) +{ + if(platform.init() != SOFTMC_SUCCESS){ + cerr << "Could not initialize SoftMC Platform" << endl; + } + + platform.reset_fpga(); + + if (argc != 3) + { + cout << "Give me two arguments" << endl; + exit(0); + } + bool andOp = false; + + if (atoi(argv[1])) + andOp = true; + else + andOp = false; + + srand(time(NULL)); + + ofstream fileOutput; + fileOutput.open(argv[2]); + fileOutput << "row,operation,op1,op2,t1,t2,op1-placement,op2-placement,constant-placement,bit-flips" << endl; + + for(int i_data = 0 ; i_data < 4 ; i_data++) + { + unsigned int dp1; + unsigned int dp2; + + if (i_data == 0) + { + dp1 = 0x00000000; + dp2 = 0x00000000; + } + else if (i_data == 1) + { + dp1 = 0x00000000; + dp2 = 0xffffffff; + } + else if (i_data == 2) + { + dp1 = 0xffffffff; + dp2 = 0x00000000; + } + else if (i_data == 3) + { + dp1 = 0xffffffff; + dp2 = 0xffffffff; + } + + unsigned int expected = andOp ? (dp1 & dp2) : (dp1 | dp2); + + for (int t1 = 0 ; t1 < 10 ; t1++) + { + for (int t2 = 0 ; t2 < 10 ; t2++) + { + for (int pla = 0 ; pla < 3 ; pla++) + { + string platext; + if (pla == 0) + { + cout << "Begin with " << (andOp ? "AND" : "OR") << " T1:" << t1 << " T2:" << t2 << " OP1:" << 0 << " OP2:" << 1 << " C:" << 2 << endl; + Program prog = AMBITTest(andOp, dp1, dp2, t1, t2, 0, 1, 2); + platext = "0,1,2"; + platform.execute(prog); + } + else if (pla == 1) + { + cout << "Begin with T1:" << t1 << " T2:" << t2 << " OP1:" << 0 << " OP2:" << 2 << " C:" << 1 << endl; + Program prog = AMBITTest(andOp, dp1, dp2, t1, t2, 0, 2, 1); + platext = "0,2,1"; + platform.execute(prog); + } + else if (pla == 2) + { + cout << "Begin with T1:" << t1 << " T2:" << t2 << " OP1:" << 1 << " OP2:" << 2 << " C:" << 0 << endl; + Program prog = AMBITTest(andOp, dp1, dp2, t1, t2, 1, 2, 0); + platext = "1,2,0"; + platform.execute(prog); + } + + //platform.readRegisterDump(); + //exit(0); + + for (int row = 0 ; row < NUM_ROWS ; row += 4) + { + uint8_t rd_rows[3][8192]; + + for(int i = 0 ; i < 3 ; i++) // Read three rows each main iteration + platform.receiveData((void*)rd_rows[i], 8192); + + uint32_t* readData1 = ((uint32_t*) rd_rows[0]); + uint32_t* readData2 = ((uint32_t*) rd_rows[1]); + uint32_t* readData3 = ((uint32_t*) rd_rows[2]); + unsigned long long errors = 0; + bool noTRA = false; + for(int i = 0 ; i < 8192/4 ; i++) + { + unsigned int differences; + if (readData1[i] == readData2[i] && readData2[i] == readData3[i]) + differences = __builtin_popcount(readData1[i]^expected); + else{ // if !TRA, assume errors + noTRA = true; + break; + } + errors += differences; + } + if(noTRA) + { + fileOutput << row << "," << (andOp ? "AND" : "OR") << "," << dp1 << "," << dp2 << "," << t1 << "," << t2 << "," << platext << "," << -1 << endl; + cout << "Row:" << row << " No TRA " << endl; + } + else + { + fileOutput << row << "," << (andOp ? "AND" : "OR") << "," << dp1 << "," << dp2 << "," << t1 << "," << t2 << "," << platext << "," << errors << endl; + cout << "Row:" << row << " Errors:" << errors << endl; + } + } + } + } + } + } + fileOutput.close(); + printf("\nTest Finished\n"); +} |
