aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAtaberk <olguantaberk@gmail.com>2023-06-03 17:02:07 +0200
committerAtaberk <olguantaberk@gmail.com>2023-06-03 17:02:07 +0200
commit59ec1e91bedd156ae37f3a835782088c74346f76 (patch)
tree3fad0fc6c221bd98a6ab933c46628bf3cbef2317
parente2e1571680b037b85f01cbca7b89fad81a80b45c (diff)
downloaddram-bender-59ec1e91bedd156ae37f3a835782088c74346f76.tar.gz
Add case study#3's sources
-rw-r--r--sources/apps/case_studies/cs3_bitwise/Makefile33
-rw-r--r--sources/apps/case_studies/cs3_bitwise/README.md23
-rw-r--r--sources/apps/case_studies/cs3_bitwise/run_tests.sh12
-rw-r--r--sources/apps/case_studies/cs3_bitwise/test.cpp309
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");
+}