diff options
| author | Ataberk <olgunataberk@gmail.com> | 2022-09-25 17:22:03 +0200 |
|---|---|---|
| committer | Ataberk <olgunataberk@gmail.com> | 2022-09-25 17:22:03 +0200 |
| commit | dc0b3db1b4f1895a07e5fe280ee3790e87f97b9f (patch) | |
| tree | b47203aa281bdd959def4451c84d310cd9cf2e12 /sources/apps/QUAC-TRNG/src | |
| download | dram-bender-dc0b3db1b4f1895a07e5fe280ee3790e87f97b9f.tar.gz | |
Initial commit
Diffstat (limited to 'sources/apps/QUAC-TRNG/src')
| -rw-r--r-- | sources/apps/QUAC-TRNG/src/observe.cpp | 726 | ||||
| -rw-r--r-- | sources/apps/QUAC-TRNG/src/slow_entropy.cpp | 204 | ||||
| -rw-r--r-- | sources/apps/QUAC-TRNG/src/slow_sha.cpp | 233 | ||||
| -rw-r--r-- | sources/apps/QUAC-TRNG/src/util.cpp | 670 | ||||
| -rw-r--r-- | sources/apps/QUAC-TRNG/src/util.h | 55 |
5 files changed, 1888 insertions, 0 deletions
diff --git a/sources/apps/QUAC-TRNG/src/observe.cpp b/sources/apps/QUAC-TRNG/src/observe.cpp new file mode 100644 index 0000000..275c516 --- /dev/null +++ b/sources/apps/QUAC-TRNG/src/observe.cpp @@ -0,0 +1,726 @@ +#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 <algorithm> +#include <iterator> +#include <iomanip> + +#define NEWFILTER + +using namespace std; + +#define NO_BANKS 2 +#define NO_ROWS 32*1024 + +// 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 PATTERN_REG 12 +#define INV_PATTERN_REG 13 +#define TEMP_PATTERN_REG 14 + +#define BAR 3 +#define CAR 4 +#define RARBASE 5 +#define RAR1 6 +#define RAR2 9 + +#define ONE_REG 10 +#define ZERO_REG 11 + +#define ITER_REG 7 +#define CTR_REG 8 + +#define INIT_LOOP 15 + +Program genRowCopy(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; +} + +/** + * 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; +} + + +/** + * This function will generate a block of instructions that will + * write to a range of rows. It assumes the bank will be precharged. + */ + +Program genCopyRange(int row_reg, int no_rows, int bank_reg, bool stripes) +{ + Program ret; + ret.add_inst(SMC_LI(no_rows, INIT_LOOP)); + ret.add_inst(SMC_ADD(INIT_LOOP, row_reg, INIT_LOOP)); // write until this row + + ret.add_inst(SMC_LI(0, ONE_REG)); + ret.add_inst(SMC_LI(1, ZERO_REG)); + + ret.add_label("genWriteRange:LOOP_BEGIN"); + ret.add_inst(SMC_SLEEP(4)); + + ret.add_below(genRowCopy(4,4,ONE_REG,row_reg,bank_reg)); + ret.add_inst(SMC_SLEEP(6)); + ret.add_inst(SMC_PRE(bank_reg, 0, 0), SMC_NOP(), SMC_NOP(), SMC_NOP()); + ret.add_inst(SMC_ADDI(row_reg, 1, row_reg)); + + ret.add_inst(SMC_SLEEP(6)); + ret.add_below(genRowCopy(4,4,ZERO_REG,row_reg,bank_reg)); + ret.add_inst(SMC_SLEEP(6)); + ret.add_inst(SMC_PRE(bank_reg, 0, 0), SMC_NOP(), SMC_NOP(), SMC_NOP()); + ret.add_inst(SMC_ADDI(row_reg, 1, row_reg)); + + ret.add_inst(SMC_SLEEP(6)); + + ret.add_below(genRowCopy(4,4,ONE_REG,row_reg,bank_reg)); + ret.add_inst(SMC_SLEEP(6)); + ret.add_inst(SMC_PRE(bank_reg, 0, 0), SMC_NOP(), SMC_NOP(), SMC_NOP()); + ret.add_inst(SMC_ADDI(row_reg, 1, row_reg)); + ret.add_inst(SMC_SLEEP(6)); + + ret.add_below(genRowCopy(4,4,ZERO_REG,row_reg,bank_reg)); + ret.add_inst(SMC_SLEEP(6)); + ret.add_inst(SMC_PRE(bank_reg, 0, 0), SMC_NOP(), SMC_NOP(), SMC_NOP()); + ret.add_inst(SMC_ADDI(row_reg, 1, row_reg)); + ret.add_inst(SMC_SLEEP(6)); + + ret.add_inst(SMC_SUBI(row_reg, no_rows, row_reg)); + return ret; +} + +/** + * This function will generate a block of instructions that will + * write to a range of rows. It assumes the bank will be precharged. + */ +Program genWriteRange1000(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)); // write until this row + + ret.add_label("genWriteRange:LOOP_BEGIN"); + ret.add_inst(SMC_LI(0, CAR)); + + ret.add_inst(SMC_ACT(bank_reg, 0, row_reg, 1), SMC_NOP(), SMC_NOP(), SMC_NOP()); + ret.add_inst(SMC_SLEEP(4)); + + for(int i = 0 ; i < 32 ; i++) + { + ret.add_inst(SMC_WRITE(bank_reg, 0, CAR, 1, 0, 0), SMC_NOP(), SMC_NOP(), SMC_NOP()); + ret.add_inst(SMC_NOP(), SMC_WRITE(bank_reg, 0, CAR, 1, 0, 0), SMC_NOP(), SMC_NOP()); + ret.add_inst(SMC_NOP(), SMC_NOP(), SMC_WRITE(bank_reg, 0, CAR, 1, 0, 0), SMC_NOP()); + ret.add_inst(SMC_NOP(), SMC_NOP(), SMC_NOP(), SMC_WRITE(bank_reg, 0, CAR, 1, 0, 0)); + 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, 1), SMC_NOP(), SMC_NOP(), SMC_NOP()); + + ret.add_inst(SMC_MV(PATTERN_REG, TEMP_PATTERN_REG)); + ret.add_inst(SMC_MV(INV_PATTERN_REG, PATTERN_REG)); + ret.add_inst(SMC_MV(TEMP_PATTERN_REG, INV_PATTERN_REG)); + for(int i = 0 ; i < 16 ; i++) + ret.add_inst(SMC_LDWD(PATTERN_REG,i)); + + ret.add_inst(SMC_ACT(bank_reg, 0, row_reg, 1), SMC_NOP(), SMC_NOP(), SMC_NOP()); + ret.add_inst(SMC_SLEEP(4)); + + for(int i = 0 ; i < 32 ; i++) + { + ret.add_inst(SMC_WRITE(bank_reg, 0, CAR, 1, 0, 0), SMC_NOP(), SMC_NOP(), SMC_NOP()); + ret.add_inst(SMC_NOP(), SMC_WRITE(bank_reg, 0, CAR, 1, 0, 0), SMC_NOP(), SMC_NOP()); + ret.add_inst(SMC_NOP(), SMC_NOP(), SMC_WRITE(bank_reg, 0, CAR, 1, 0, 0), SMC_NOP()); + ret.add_inst(SMC_NOP(), SMC_NOP(), SMC_NOP(), SMC_WRITE(bank_reg, 0, CAR, 1, 0, 0)); + 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, 1), SMC_NOP(), SMC_NOP(), SMC_NOP()); + ret.add_inst(SMC_SLEEP(4)); + + ret.add_inst(SMC_ACT(bank_reg, 0, row_reg, 1), SMC_NOP(), SMC_NOP(), SMC_NOP()); + ret.add_inst(SMC_SLEEP(4)); + + for(int i = 0 ; i < 32 ; i++) + { + ret.add_inst(SMC_WRITE(bank_reg, 0, CAR, 1, 0, 0), SMC_NOP(), SMC_NOP(), SMC_NOP()); + ret.add_inst(SMC_NOP(), SMC_WRITE(bank_reg, 0, CAR, 1, 0, 0), SMC_NOP(), SMC_NOP()); + ret.add_inst(SMC_NOP(), SMC_NOP(), SMC_WRITE(bank_reg, 0, CAR, 1, 0, 0), SMC_NOP()); + ret.add_inst(SMC_NOP(), SMC_NOP(), SMC_NOP(), SMC_WRITE(bank_reg, 0, CAR, 1, 0, 0)); + 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, 1), SMC_NOP(), SMC_NOP(), SMC_NOP()); + ret.add_inst(SMC_SLEEP(4)); + + ret.add_inst(SMC_ACT(bank_reg, 0, row_reg, 1), SMC_NOP(), SMC_NOP(), SMC_NOP()); + ret.add_inst(SMC_SLEEP(4)); + + for(int i = 0 ; i < 32 ; i++) + { + ret.add_inst(SMC_WRITE(bank_reg, 0, CAR, 1, 0, 0), SMC_NOP(), SMC_NOP(), SMC_NOP()); + ret.add_inst(SMC_NOP(), SMC_WRITE(bank_reg, 0, CAR, 1, 0, 0), SMC_NOP(), SMC_NOP()); + ret.add_inst(SMC_NOP(), SMC_NOP(), SMC_WRITE(bank_reg, 0, CAR, 1, 0, 0), SMC_NOP()); + ret.add_inst(SMC_NOP(), SMC_NOP(), SMC_NOP(), SMC_WRITE(bank_reg, 0, CAR, 1, 0, 0)); + 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, 1), SMC_NOP(), SMC_NOP(), SMC_NOP()); + ret.add_inst(SMC_SLEEP(4)); + + ret.add_inst(SMC_MV(PATTERN_REG, TEMP_PATTERN_REG)); + ret.add_inst(SMC_MV(INV_PATTERN_REG, PATTERN_REG)); + ret.add_inst(SMC_MV(TEMP_PATTERN_REG, INV_PATTERN_REG)); + for(int i = 0 ; i < 16 ; i++) + ret.add_inst(SMC_LDWD(PATTERN_REG,i)); + + ret.add_inst(SMC_SUBI(row_reg, no_rows, row_reg)); + return ret; +} + +/** + * This function will generate a block of instructions that will + * write to a range of rows. It assumes the bank will be precharged. + */ + +Program genWriteRange(int row_reg, int no_rows, int bank_reg, bool stripes) +{ + Program ret; + ret.add_inst(SMC_LI(no_rows, INIT_LOOP)); + ret.add_inst(SMC_ADD(INIT_LOOP, row_reg, INIT_LOOP)); // write until this row + + ret.add_label("genWriteRange:LOOP_BEGIN"); + ret.add_inst(SMC_LI(0, CAR)); + ret.add_inst(SMC_ACT(bank_reg, 0, row_reg, 1), SMC_NOP(), SMC_NOP(), SMC_NOP()); + ret.add_inst(SMC_SLEEP(4)); + for(int i = 0 ; i < 64 ; i++) + { + ret.add_inst(SMC_WRITE(bank_reg, 0, CAR, 1, 0, 0), SMC_NOP(), SMC_NOP(), SMC_NOP()); + ret.add_inst(SMC_NOP(), SMC_NOP(), SMC_WRITE(bank_reg, 0, CAR, 1, 0, 0), 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()); + if(stripes) + { + ret.add_inst(SMC_MV(PATTERN_REG, TEMP_PATTERN_REG)); + ret.add_inst(SMC_MV(INV_PATTERN_REG, PATTERN_REG)); + ret.add_inst(SMC_MV(TEMP_PATTERN_REG, INV_PATTERN_REG)); + for(int i = 0 ; i < 16 ; i++) + ret.add_inst(SMC_LDWD(PATTERN_REG,i)); + } + ret.add_branch(ret.BR_TYPE::BL, row_reg, INIT_LOOP, "genWriteRange:LOOP_BEGIN"); + ret.add_inst(SMC_SUBI(row_reg, no_rows, row_reg)); + 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)); // TODO: fix this + ret.add_inst(SMC_ACT(bank_reg, 0, row_reg, 1), SMC_NOP(), SMC_NOP(), SMC_NOP()); + ret.add_inst(SMC_SLEEP(4)); + for(int i = 0 ; i < 64 ; 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_READ(bank_reg, 0, CAR, 1, 0, 0), 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; +} +/** + * @return an instruction formed by NOPs + */ +Inst all_nops() +{ + return __pack_mininsts(SMC_NOP(), SMC_NOP(), SMC_NOP(), SMC_NOP()); +} + +Program gen_test_prog(int bank, int r1, int r2,int iters) +{ + Program program; + + program.add_inst(SMC_LI(8, CASR)); // Load 8 into CASR since each READ reads 8 columns + program.add_inst(SMC_LI(1, BASR)); // Load 1 into BASR + program.add_inst(SMC_LI(1, RASR)); // Load 1 into RASR + + program.add_inst(SMC_LI(0xffffffff, PATTERN_REG)); + program.add_inst(SMC_LI(0x00000000, INV_PATTERN_REG)); + for(int i = 0 ; i < 16 ; i++) + program.add_inst(SMC_LDWD(PATTERN_REG,i)); + + program.add_inst(SMC_LI(bank, BAR)); + program.add_inst(SMC_LI(r1-(r1%4), RARBASE)); + + program.add_inst(SMC_LI(iters, ITER_REG)); + program.add_inst(SMC_LI(0, CTR_REG)); + + program.add_label("WRITE_BEGIN"); + program.add_inst(SMC_PRE(BAR, 0, 0), SMC_NOP(), SMC_NOP(), SMC_NOP()); + program.add_inst(SMC_SLEEP(3)); + program.add_below(genWriteRange(RARBASE, 4, BAR, true)); + //program.add_below(genWriteRange1000(RARBASE, 4, BAR)); + //program.add_below(genCopyRange(RARBASE, 4, BAR, true)); + program.add_inst(SMC_LI(r1, RAR1)); + program.add_inst(SMC_LI(r2, RAR2)); + + program.add_below(genActPreActSequence(1, 1, RAR1, RAR2, BAR)); + + program.add_inst(SMC_SLEEP(6)); + program.add_inst(SMC_PRE(BAR, 0, 0), SMC_NOP(), SMC_NOP(), SMC_NOP()); + + program.add_below(genReadRange(RARBASE, 1, BAR)); + program.add_inst(SMC_ADDI(CTR_REG, 1, CTR_REG)); + + program.add_branch(program.BR_TYPE::BL, CTR_REG, ITER_REG, "WRITE_BEGIN"); + program.add_inst(SMC_END()); + + return program; +} + +bool nonoverlapping_pattern(std::vector<uint8_t> bv) +{ + unsigned wsize = bv.size()/8; + uint8_t buf[wsize]; + for(int j = 0 ; j < wsize ; j++) + { + uint8_t intermediate = 0; + for(int k = 0 ; k < 8 ; k++) + intermediate = (intermediate << 1) | bv[j*8 + k]; + buf[j] = intermediate; + } + + int bin[8] = {0}; + for (int i = 0 ; i < (1024*128*8 - 3) ; i += 3) + { + if (i % 8 < 6) + bin[(buf[i/8] >> (i%8)) & 0x7]++; + else + { + int next_bits = 3 - (8-(i%8)); + int next_mask = next_bits == 2 ? 0x3 : 0x1; + int this_mask = next_bits == 2 ? 0x1 : 0x3; + uint8_t next_pattern = (buf[(i/8)+1]) & next_mask; + uint8_t this_pattern = (buf[i/8] >> (i%8)) & this_mask; + bin[(next_pattern << (3-next_bits)) | this_pattern]++; + } + } + + bool pass = true; + for (int i = 0 ; i < 8 ; i++) + { + cout << i << ": " << bin[i] << endl; + if (bin[i] < 30000 || bin[i] > 55000) + pass = false; + } + return pass; +} + +vector<int> pre_filter(SoftMCPlatform& platform, int bank, int row) +{ + vector<int> cells_to_track; + + const int NO_CELLS = 64 * 1024; + const int pre_pre_filter_iterations = 128*1024; + const int threshold_size = 4096; + + Program prog = gen_test_prog(bank, row, row+3, pre_pre_filter_iterations); + platform.execute(prog); + uint8_t buf1[8*1024]; + uint8_t buf2[8*1024]; + + vector<vector<uint8_t>> vnc_bitstreams; + + for (int i = 0 ; i < NO_CELLS ; i++) + vnc_bitstreams.push_back(vector<uint8_t>()); + + // Von neumann corrector first + for (int i = 0 ; i < pre_pre_filter_iterations/2 ; i++) + { + platform.receiveData((char*)buf1, 8*1024); + platform.receiveData((char*)buf2, 8*1024); + + for (int b = 0 ; b < NO_CELLS ; b++) + { + if(vnc_bitstreams[b].size() == threshold_size) + continue; + + int b1 = (buf1[b/8] >> b%8) & 0x1; + int b2 = (buf2[b/8] >> b%8) & 0x1; + + if (~b1 & b2) + vnc_bitstreams[b].push_back(1); + else if (b1 & ~b2) + vnc_bitstreams[b].push_back(0); + } + } + + int cnt = 0; + for (int b = 0 ; b < NO_CELLS ; b++) + { + if (vnc_bitstreams[b].size() == threshold_size) + cnt++; + } + + cout << cnt << " cells have passed initial filtering." << endl; + + // counter bins for each bitline + int bin[NO_CELLS][8]; + for (int i = 0 ; i < NO_CELLS ; i++) + { + for (int j = 0 ; j < 8 ; j++) + bin[i][j] = 0; + } + + int freq[NO_CELLS] = {0}; + + for (int b = 0 ; b < NO_CELLS ; b++) + { + if (vnc_bitstreams[b].size() < threshold_size - 1) + continue; + for (int i = 0 ; i < (threshold_size - 1)/3 ; i++) + { + int b1 = vnc_bitstreams[b][i] & 0x1; + int b2 = vnc_bitstreams[b][i+1] & 0x1; + int b3 = vnc_bitstreams[b][i+2] & 0x1; + + if (b1) + freq[b]++; + if (b2) + freq[b]++; + if (b3) + freq[b]++; + + bin[b][(b3 << 2) | (b2 << 1) | b1]++; + } + } + + bool passed_frequency[NO_CELLS] = {false}; + + int upper_freq = threshold_size/2 + threshold_size/2/100; + int lower_freq = threshold_size/2 - threshold_size/2/100; + for (int i = 0 ; i < NO_CELLS ; i++) + { + if (vnc_bitstreams[i].size() < threshold_size - 1) + continue; + if (freq[i] < upper_freq && freq[i] > lower_freq) + passed_frequency[i] = true; + } + + cnt = 0; + for (int b = 0 ; b < NO_CELLS ; b++) + { + if (passed_frequency[b]) + cnt++; + } + + cout << cnt << " cells have passed frequency filtering." << endl; + + //cout << "Cell: " << i << endl; + int lower_limit = ((threshold_size - 1) / 3 / 8) - (((threshold_size - 1) / 3 / 8) / 10); + int upper_limit = ((threshold_size - 1) / 3 / 8) + (((threshold_size - 1) / 3 / 8) / 10); + cout << "UL: " << upper_limit << " LL: " << lower_limit << endl; + bool passed[NO_CELLS]; + + for (int b = 0 ; b < NO_CELLS ; b++) + passed[b] = true; + + for (int i = 0 ; i < NO_CELLS ; i++) + { + if (!passed_frequency[i]) + { + passed[i] = false; + continue; + } + for (int j = 0 ; j < 8 ; j++) + { + //cout << "Bin" << j << ": " << bin[i][j] << endl; + if (bin[i][j] < lower_limit || bin[i][j] > upper_limit) + { + //cout << "Cell " << i << " Bin" << j << ": " << bin[i][j] << endl; + passed[i] = false; + break; + } + } + if (passed[i]) + cout << i << " " << "PASSed" << endl; + } + + for (int i = 0 ; i < NO_CELLS ; i++) + { + if (passed[i]) + cells_to_track.push_back(i); + } + + return cells_to_track; +} + +int main(int argc, char *argv[]) +{ + SoftMCPlatform platform; + int err; + + // buffer allocated for reading data from the board + uint8_t buf[8*1024]; + uint8_t prev_read[8*1024]; + + // Initialize the platform, opens file descriptors for the board PCI-E interface. + if((err = platform.init()) != SOFTMC_SUCCESS){ + cerr << "Could not initialize SoftMC Platform: " << err << endl; + } + // reset the board to hopefully restore the board's state + platform.reset_fpga(); + platform.set_aref(true); + + ifstream lfFile; + string trackFn = string(argv[1]) + "/" + "lastrow.txt"; + lfFile.open(trackFn); + + int x=0; + lfFile >> x; + + lfFile.close(); + + for(int bank = 1 ; bank < NO_BANKS ; bank++) + { + for(int r1 = x ; r1 < NO_ROWS ; r1 += 4) + { + bool satisfied = false; + #ifdef NEWFILTER + vector<int> cell_pos = pre_filter(platform, bank, r1); + #else + // Enrollment phase: + // Look at switching activity of each cell in a row + Program prog = gen_test_prog(bank, r1, r1+3, 32*1024); + platform.execute(prog); + int n_switches[64*1024]; // how many times each cell have switched + fill(n_switches, n_switches + 64*1024, 0); + platform.receiveData((char*)prev_read, 8*1024); + for(int k = 0; k < 32*1024-1 ; k++) + { + platform.receiveData((char*)buf, 8*1024); // read one segment each iteration + for(int i = 0 ; i < 8 * 1024 ; i++) + { + uint8_t diff = prev_read[i] ^ buf[i]; + for(int j = 0 ; j < 8 ; j++) + n_switches[i*8 + j] += (diff >> j) & 0x1; + } + copy(begin(buf), end(buf), begin(prev_read)); + } + vector<int> cell_pos; // Switching cell positions + float total_bps = 0; + for(int i = 0 ; i < 8*8*1024 ; i++) + { + // In total it takes 132ms to execute all the DRAM commands + // We compute bps based on switching + total_bps += (1000/132.f) * n_switches[i]; + if(n_switches[i] > 1000) + cell_pos.push_back(i); + } + + cout << "Finished enrollment for bank " << bank << + " row " << r1 << "... " << cell_pos.size() << " cells passed... Predicted bps " + << fixed << setw(11) << setprecision(6) << total_bps << endl; + #endif + + cout << "Finished enrollment for bank " << bank << + " row " << r1 << "... " << cell_pos.size() << " cells passed..." << endl; + + if(cell_pos.size() == 0) + continue; + + for (int i = 0 ; i < cell_pos.size() ; i++) + cout << cell_pos[i] << " "; + cout << endl; + + // Begin filtered acquisition phase + vector<vector<uint8_t>> stream_per_cell; + for(int i = 0 ; i < cell_pos.size() ; i++) + { + stream_per_cell.push_back(vector<uint8_t>()); + } + + int prev_bpc_i = 0; + int prev_cell_flips[cell_pos.size()]{0}; + + int loop_count = 0; + int loop_limit = 15; + bool bcf = false; // has the best cell exceeded the threshold + + while(!satisfied) + { + if(loop_count == loop_limit) + { + cout << "Exiting because we have iterated enough times" << endl; + break; + } + int iterations = 1024*1024; + Program prog = gen_test_prog(bank, r1, r1+3, iterations); + platform.execute(prog); + + for(int k = 0; k < iterations/2 ; k++) + { + platform.receiveData((char*)prev_read, 8*1024); // read one segment each iteration + platform.receiveData((char*)buf, 8*1024); // read one segment each iteration + //VON NEUMANN CORRECTOR BELOW + for(int i = 0 ; i < cell_pos.size() ; i++) + { + uint8_t b1 = (prev_read[cell_pos[i]/8] >> (cell_pos[i]%8)) & 0x1; + uint8_t b2 = (buf[cell_pos[i]/8] >> (cell_pos[i]%8)) & 0x1; + uint8_t b3 = b1 ^ b2; + if(!b3) continue; + if(b2) stream_per_cell[i].push_back(1); + else stream_per_cell[i].push_back(0); + } + } + + int bpc_flips = 0; // best performing cell flip count + int bpc_i = 0; // best performing cell index + for(int i = 0 ; i < cell_pos.size() ; i++) + { + if(stream_per_cell[i].size() > bpc_flips) + { + bpc_flips = stream_per_cell[i].size(); + bpc_i = i; + } + } + + /* + cout << "Dumping # of switches per cell..." << endl; + for(int i = 0 ; i < cell_pos.size() ; i++) + { + cout << "Cell#" << cell_pos[i] << " Got:" << stream_per_cell[i].size() - prev_cell_flips[i] + << "Exp:" << 32*n_switches[cell_pos[i]] << endl; + } + */ + + if(!bcf) + { + if(prev_bpc_i == bpc_i) + { + int remaining_bits = 1024*1024 - bpc_flips; + int count_diff = bpc_flips - prev_cell_flips[bpc_i]; + if(remaining_bits/count_diff + 1 > 16) + { + cout << "Exiting because it will take too long" << endl; + break; + } + if(remaining_bits < 0){ + cout << "Finished one cell, will keep iterating for 5 iterations" << endl; + bcf = true; + loop_limit = loop_count + 5; + } + else{ + cout << "It will take " << remaining_bits/count_diff + 1 << " more iterations to finish" << endl; + cout << "Based on the best cell's performance which has flipped " << bpc_flips << " times so far" << endl; + } + }else + { + cout << "Cannot approximate test time because the best performing cell changed" << endl; + cout << "Was " << cell_pos[prev_bpc_i] << " Now " << cell_pos[bpc_i] << endl; + } + } + cout << "Cells about to finish: " << endl; + for(int i = 0 ; i < cell_pos.size() ; i++){ + if(stream_per_cell[i].size() > 768*1024) + cout << cell_pos[i] << ":" << stream_per_cell[i].size() << " "; + + prev_cell_flips[i] = stream_per_cell[i].size(); + } + cout << endl; + prev_bpc_i = bpc_i; + loop_count ++; + } + + cout << "Writing bitstreams..." << endl; + int filtered_streams = 0; + for(int i = 0 ; i < cell_pos.size() ; i++){ + if(stream_per_cell[i].size() >= 1024*1024){ //&& nonoverlapping_pattern(stream_per_cell[i])){ + ofstream dump_file; + filtered_streams++; + string fn = string(argv[1]) + "/" + to_string(bank) + "_" + to_string(r1) + + "_" + to_string(r1+3) + "_" + to_string(cell_pos[i]); + dump_file.open(fn, ofstream::binary); + unsigned wsize = stream_per_cell[i].size()/8; + uint8_t wbuf[wsize]; + for(int j = 0 ; j < wsize ; j++) + { + uint8_t intermediate = 0; + for(int k = 0 ; k < 8 ; k++) + intermediate = (intermediate << 1) | stream_per_cell[i][j*8 + k]; + wbuf[j] = intermediate; + } + dump_file.write((char*)wbuf, wsize); + dump_file.close(); + } + } + //cout << "Filtered streams: " << filtered_streams << endl; + cout << "Finished processing b:" << bank << " r1:" << r1 << " r2:" << r1+3 << endl; + ofstream lfFile; + string trackFn = string(argv[1]) + "/" + "lastrow.txt"; + lfFile.open(trackFn); + lfFile << r1; + lfFile.close(); + } + } +} diff --git a/sources/apps/QUAC-TRNG/src/slow_entropy.cpp b/sources/apps/QUAC-TRNG/src/slow_entropy.cpp new file mode 100644 index 0000000..a18cf6e --- /dev/null +++ b/sources/apps/QUAC-TRNG/src/slow_entropy.cpp @@ -0,0 +1,204 @@ +#include "instruction.h" +#include "prog.h" +#include "platform.h" +#include "util.h" +#include <fstream> +#include <iostream> +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> +#include <cstring> +#include <list> +#include <math.h> +#include <algorithm> +#include <iterator> +#include <iomanip> + +using namespace std; + +Program gen_test_prog(int bank, int r1, int r2, int iters, int read_cols, int placement) +{ + Program program; + + program.add_inst(SMC_LI(8, CASR)); // Load 8 into CASR since each READ reads 8 columns + program.add_inst(SMC_LI(1, RASR)); // Load 1 into RASR + + program.add_inst(SMC_LI(bank, BAR)); + program.add_inst(SMC_LI(r1, RARBASE)); + + program.add_inst(SMC_LI(iters, ITER_REG)); + program.add_inst(SMC_LI(0, CTR_REG)); + + program.add_inst(SMC_PRE(BAR,0,1),SMC_NOP(),SMC_NOP(),SMC_NOP()); + program.add_inst(SMC_SLEEP(5)); + + program.add_inst(SMC_LI(r1, RAR1)); + program.add_inst(SMC_LI(r2, RAR2)); + + program.add_label("WRITE_BEGIN"); + //program.add_below(genWriteRange(RARBASE, 4, BAR, true)); + switch(placement) + { + // Invert 0-1 start pattern before here when we set the + // WIDEREG + case 1000: + program.add_below(genWriteRange1000(RARBASE, 4, BAR)); + break; + case 1001: + program.add_below(genWriteRange1001(RARBASE, 4, BAR)); + break; + case 1010: + program.add_below(genWriteRange1010(RARBASE, 4, BAR)); + break; + case 1011: + program.add_below(genWriteRange1011(RARBASE, 4, BAR)); + break; + case 1100: + program.add_below(genWriteRange1100(RARBASE, 4, BAR)); + break; + case 1101: + program.add_below(genWriteRange1101(RARBASE, 4, BAR)); + break; + case 1110: + program.add_below(genWriteRange1110(RARBASE, 4, BAR)); + break; + case 1111: + program.add_below(genWriteRange1111(RARBASE, 4, BAR)); + break; + default: + printf("Unexpected placement encoding\n"); + exit(0); + } + + program.add_below(genActPreActSequence(1, 1, RAR1, RAR2, BAR)); + program.add_inst(SMC_SLEEP(4)); + program.add_inst(SMC_PRE(BAR, 0, 1), SMC_NOP(), SMC_NOP(), SMC_NOP()); + program.add_inst(SMC_SLEEP(4)); + program.add_below(genReadRange(RARBASE, 1, BAR, read_cols)); + + program.add_inst(SMC_ADDI(CTR_REG, 1, CTR_REG)); + program.add_branch(program.BR_TYPE::BL, CTR_REG, ITER_REG, "WRITE_BEGIN"); + program.add_inst(SMC_END()); + + return program; +} + +int main(int argc, char *argv[]) +{ + bool DUMP_RAW = false; + + SoftMCPlatform platform; + int err; + + // buffer allocated for reading data from the board + uint8_t buf[4*READ_CL*64]; + + // Initialize the platform, opens file descriptors for the board PCI-E interface. + if((err = platform.init()) != SOFTMC_SUCCESS){ + cerr << "Could not initialize SoftMC Platform: " << err << endl; + } + // reset the board to hopefully restore the board's state + platform.reset_fpga(); + platform.set_aref(true); + + int bank = 1; + + int row_stride = atoi(argv[3]); + + string placement = argv[2]; + bool invert = false; + + int iters = atoi(argv[4]); + + ofstream ent_file; + string fn = string(argv[1]) + "/" + to_string(bank) + "_" + to_string(iters) + "_" + to_string(READ_CL) + "_" + to_string(NO_ROWS) + "_" + placement + ".txt"; + cout << "Saving to file " << fn << endl; + ent_file.open(fn); + + char new_placement[10]; + if (placement[0] == '0') + { + for (std::string::size_type i = 0 ; i < placement.size() ; i++) + if(placement[i] == '0') + new_placement[i] = '1'; + else if(placement[i] == '1') + new_placement[i] = '0'; + else + new_placement[i] = placement[i]; + placement = string(new_placement); + invert = true; + } + + Program program; + program.add_inst(SMC_LI(invert ? 0x0 : 0xffffffff, PATTERN_REG)); + program.add_inst(SMC_LI(invert ? 0xffffffff : 0x0, INV_PATTERN_REG)); + for(int i = 0 ; i < 16 ; i++) + program.add_inst(SMC_LDWD(PATTERN_REG,i)); + program.add_inst(SMC_END()); + platform.execute(program); + + unsigned char *byte_buf[READ_CL*64]; + for(int i = 0 ; i < READ_CL*64 ; i++) + byte_buf[i] = new unsigned char[iters]; + + // Frequency of 1s and 0s generated by each bitline + int alphabet[READ_CL*64*8][2]; + + ent_file << NO_ROWS/row_stride << " " << READ_CL << endl; + + for(int r1 = 0 ; r1 < NO_ROWS ; r1+=row_stride) + { + ent_file << r1 << " "; + Program prog = gen_test_prog(bank, r1, r1+3, iters, READ_CL, std::stoi(placement)); + platform.execute(prog); + + for(int i = 0 ; i < iters ; i++) + { + platform.receiveData((char*)buf, READ_CL*64); // read one segment each iteration + for(int j = 0 ; j < READ_CL*64 ; j++) + byte_buf[j][i] = buf[j]; + } + + for(int i = 0 ; i < READ_CL*64*8 ; i++) + for(int j = 0 ; j < 2 ; j++) + alphabet[i][j] = 0; + + for(int j = 0 ; j < READ_CL*64*8 ; j++) + { + for(int i = 0 ; i < iters ; i++) + alphabet[j][(byte_buf[j/8][i]>>(j%8))&0x1] += 1; + + float approxent = 0; + for(int i = 0 ; i < 2 ; i++) + { + int freq = alphabet[j][i]; + float p = ((float) freq) / ((float) iters); + approxent -= freq == 0 ? 0 : p * log2(p); + } + + ent_file << approxent << " "; + + /* + if(approxent > 0.995) + { + unsigned char bits[iters/8]{0}; + for(int i = 0 ; i < iters ; i++) + bits[i/8] |= ((byte_buf[j/8][i] >> (j%8)) & 0x1) << (7-(i%8)); + ofstream dump_file; + string fn = string(argv[2]) + "/" + to_string(r1) + "_" + to_string(j) + ".bin"; + dump_file.open(fn, ofstream::binary); + dump_file.write((char*)(bits), iters/8); + dump_file.close(); + } + */ + } + + ent_file << endl; + + printf("\rrow %d", r1); + fflush(stdout); + } + for(int i = 0 ; i < READ_CL*64 ; i++) + delete byte_buf[i]; + ent_file.close(); +} diff --git a/sources/apps/QUAC-TRNG/src/slow_sha.cpp b/sources/apps/QUAC-TRNG/src/slow_sha.cpp new file mode 100644 index 0000000..69bf72f --- /dev/null +++ b/sources/apps/QUAC-TRNG/src/slow_sha.cpp @@ -0,0 +1,233 @@ +#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 <algorithm> +#include <iterator> +#include <iomanip> +#include <openssl/sha.h> +#include "util.h" + +using namespace std; + +// each iter generates 320 bytes of RN +// #define ITERS_SHA 450000 +#define READ_CL 128 + +// 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 PATTERN_REG 12 +#define INV_PATTERN_REG 13 +#define TEMP_PATTERN_REG 14 + +#define BAR 3 +#define CAR 4 +#define RARBASE 5 +#define RAR1 6 +#define RAR2 9 + +#define COPY_REG1 10 +#define COPY_REG2 11 + +#define ITER_REG 7 +#define CTR_REG 8 + +#define INIT_LOOP 15 + +Program gen_test_prog(int bank, int r1, int r2, int iters, int placement) +{ + Program program; + + program.add_inst(SMC_LI(8, CASR)); // Load 8 into CASR since each READ reads 8 columns + program.add_inst(SMC_LI(1, BASR)); // Load 1 into BASR + program.add_inst(SMC_LI(1, RASR)); // Load 1 into RASR + + program.add_inst(SMC_LI(bank, BAR)); + program.add_inst(SMC_LI(r1-(r1%4), RARBASE)); + + program.add_inst(SMC_LI(iters, ITER_REG)); + program.add_inst(SMC_LI(0, CTR_REG)); + + program.add_label("WRITE_BEGIN"); + program.add_inst(SMC_PRE(BAR, 0, 0), SMC_NOP(), SMC_NOP(), SMC_NOP()); + program.add_inst(SMC_SLEEP(3)); + switch(placement) + { + // Invert 0-1 start pattern before here when we set the + // WIDEREG + case 1000: + program.add_below(genWriteRange1000(RARBASE, 4, BAR)); + break; + case 1001: + program.add_below(genWriteRange1001(RARBASE, 4, BAR)); + break; + case 1010: + program.add_below(genWriteRange1010(RARBASE, 4, BAR)); + break; + case 1011: + program.add_below(genWriteRange1011(RARBASE, 4, BAR)); + break; + case 1100: + program.add_below(genWriteRange1100(RARBASE, 4, BAR)); + break; + case 1101: + program.add_below(genWriteRange1101(RARBASE, 4, BAR)); + break; + case 1110: + program.add_below(genWriteRange1110(RARBASE, 4, BAR)); + break; + case 1111: + program.add_below(genWriteRange1111(RARBASE, 4, BAR)); + break; + default: + printf("Unexpected placement encoding\n"); + exit(0); + } + + //program.add_below(genCopyRange(RARBASE, 4, BAR, true)); + program.add_inst(SMC_LI(r1, RAR1)); + program.add_inst(SMC_LI(r2, RAR2)); + + program.add_below(genActPreActSequence(1, 1, RAR1, RAR2, BAR)); + + program.add_inst(SMC_SLEEP(6)); + program.add_inst(SMC_PRE(BAR, 0, 0), SMC_NOP(), SMC_NOP(), SMC_NOP()); + + program.add_below(genReadRange(RARBASE, 1, BAR, 128)); + program.add_inst(SMC_ADDI(CTR_REG, 1, CTR_REG)); + + program.add_branch(program.BR_TYPE::BL, CTR_REG, ITER_REG, "WRITE_BEGIN"); + program.add_inst(SMC_END()); + + return program; +} + +int main(int argc, char *argv[]) +{ + SoftMCPlatform platform; + int err; + + // buffer allocated for reading data from the board + unsigned char buf[4*READ_CL*64]; + + // Initialize the platform, opens file descriptors for the board PCI-E interface. + if((err = platform.init()) != SOFTMC_SUCCESS){ + cerr << "Could not initialize SoftMC Platform: " << err << endl; + } + // reset the board to hopefully restore the board's state + platform.reset_fpga(); + platform.set_aref(true); + // Read selected segments from file + // first line: <number of segments> + // each line: <bank> <segment_start> <placement> + ifstream sf; + string sf_name = string(argv[2]); + sf.open(sf_name); + + int n_segments; sf >> n_segments; + std::vector<std::string> placements; + std::vector<int> banks, segments; + std::vector<float> ents; + for(int i = 0 ; i < n_segments ; i++) + { + int read; + sf >> read; banks.push_back(read); + sf >> read; segments.push_back(read); + float ent; + sf >> ent; ents.push_back(ent); + std::string rd; + sf >> rd; placements.push_back(rd); + } + + for(int i = 0 ; i < n_segments ; i++) + { + int bank = banks[i]; + int r1 = segments[i]; + float ent = ents[i]; + + if (ent < 1) + continue; + + std::string placement = placements[i]; + + bool invert = false; + // placement_magic + char new_placement[10]; + if (placement[0] == '0') + { + for (std::string::size_type i = 0 ; i < placement.size() ; i++) + if(placement[i] == '0') + new_placement[i] = '1'; + else if(placement[i] == '1') + new_placement[i] = '0'; + else + new_placement[i] = placement[i]; + placement = string(new_placement); + invert = true; + } + + Program program; + program.add_inst(SMC_LI(invert ? 0x0 : 0xffffffff, PATTERN_REG)); + program.add_inst(SMC_LI(invert ? 0xffffffff : 0x0, INV_PATTERN_REG)); + for(int i = 0 ; i < 16 ; i++) + program.add_inst(SMC_LDWD(PATTERN_REG,i)); + program.add_inst(SMC_END()); + platform.execute(program); + + unsigned char *bitstream; + + unsigned int sha_input_ent = 256; + unsigned int sha_input_blocks = ent/sha_input_ent + 1; + unsigned int row_partition_size = 8192/sha_input_blocks; + // UNTODO //TODO: from now on this is going to be 16Mbits + unsigned int test_iters = (1024*1024*1024)/(8*sha_input_blocks*32); + + + bitstream = new unsigned char[test_iters*32*sha_input_blocks]; + + cout << "Running for " << test_iters << " iterations." << endl; + cout << "Total bits of entropy: " << ent << " -> " << sha_input_blocks << " sha input blocks for the row" << endl; + + Program prog = gen_test_prog(bank, r1, r1+3, test_iters, std::stoi(placement)); + platform.execute(prog); + + for(int i = 0 ; i < test_iters ; i++) + { + platform.receiveData((char*)buf, 8192); // read one segment each iteration + // https://stackoverflow.com/q/13784434 + for(int j = 0 ; j < sha_input_blocks ; j++) + { + unsigned char hash[SHA256_DIGEST_LENGTH]; + SHA256_CTX sha256; + SHA256_Init(&sha256); + SHA256_Update(&sha256, (char*)(buf+row_partition_size*j), row_partition_size); + SHA256_Final(hash, &sha256); + for(int k = 0 ; k < SHA256_DIGEST_LENGTH ; k++) + { + bitstream[i*sha_input_blocks*SHA256_DIGEST_LENGTH + j*SHA256_DIGEST_LENGTH + k] = hash[k]; + } + } + } + ofstream dump_file; + string fn = string(argv[1]) + "/" + placements[i] + "_" + to_string(r1) + ".bin"; + dump_file.open(fn, ofstream::binary); + dump_file.write((char*)(bitstream), test_iters*32*sha_input_blocks); + dump_file.close(); + printf("\rrow %d", r1); + fflush(stdout); + delete bitstream; + } + +} diff --git a/sources/apps/QUAC-TRNG/src/util.cpp b/sources/apps/QUAC-TRNG/src/util.cpp new file mode 100644 index 0000000..41e4d50 --- /dev/null +++ b/sources/apps/QUAC-TRNG/src/util.cpp @@ -0,0 +1,670 @@ +#include "util.h" + +/** + * 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, int read_cols) +{ + 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, 1), SMC_NOP(), SMC_NOP(), SMC_NOP()); + ret.add_inst(SMC_SLEEP(4)); + + for(int i = 0 ; i < read_cols/4 ; 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_READ(bank_reg, 0, CAR, 1, 0, 0), SMC_NOP(), SMC_NOP()); + ret.add_inst(SMC_NOP(), SMC_NOP(), SMC_READ(bank_reg, 0, CAR, 1, 0, 0), SMC_NOP()); + ret.add_inst(SMC_NOP(), SMC_NOP(), SMC_NOP(), SMC_READ(bank_reg, 0, CAR, 1, 0, 0)); + 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, 1), SMC_NOP(), SMC_NOP(), SMC_NOP()); + ret.add_branch(ret.BR_TYPE::BL, row_reg, INIT_LOOP, "genReadRange:LOOP_BEGIN"); + ret.add_inst(SMC_SUBI(row_reg, no_rows, row_reg)); + return ret; +} + + + + +/** + * This function will generate a block of instructions that will + * write to a range of rows. It assumes the bank will be precharged. + */ +Program genWriteRange1000(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)); // write until this row + + ret.add_label("genWriteRange:LOOP_BEGIN"); + ret.add_inst(SMC_LI(0, CAR)); + + ret.add_inst(SMC_ACT(bank_reg, 0, row_reg, 1), SMC_NOP(), SMC_NOP(), SMC_NOP()); + ret.add_inst(SMC_SLEEP(4)); + + for(int i = 0 ; i < 32 ; i++) + { + ret.add_inst(SMC_WRITE(bank_reg, 0, CAR, 1, 0, 0), SMC_NOP(), SMC_NOP(), SMC_NOP()); + ret.add_inst(SMC_NOP(), SMC_WRITE(bank_reg, 0, CAR, 1, 0, 0), SMC_NOP(), SMC_NOP()); + ret.add_inst(SMC_NOP(), SMC_NOP(), SMC_WRITE(bank_reg, 0, CAR, 1, 0, 0), SMC_NOP()); + ret.add_inst(SMC_NOP(), SMC_NOP(), SMC_NOP(), SMC_WRITE(bank_reg, 0, CAR, 1, 0, 0)); + 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, 1), SMC_NOP(), SMC_NOP(), SMC_NOP()); + + ret.add_inst(SMC_MV(PATTERN_REG, TEMP_PATTERN_REG)); + ret.add_inst(SMC_MV(INV_PATTERN_REG, PATTERN_REG)); + ret.add_inst(SMC_MV(TEMP_PATTERN_REG, INV_PATTERN_REG)); + for(int i = 0 ; i < 16 ; i++) + ret.add_inst(SMC_LDWD(PATTERN_REG,i)); + + ret.add_inst(SMC_ACT(bank_reg, 0, row_reg, 1), SMC_NOP(), SMC_NOP(), SMC_NOP()); + ret.add_inst(SMC_SLEEP(4)); + + for(int i = 0 ; i < 32 ; i++) + { + ret.add_inst(SMC_WRITE(bank_reg, 0, CAR, 1, 0, 0), SMC_NOP(), SMC_NOP(), SMC_NOP()); + ret.add_inst(SMC_NOP(), SMC_WRITE(bank_reg, 0, CAR, 1, 0, 0), SMC_NOP(), SMC_NOP()); + ret.add_inst(SMC_NOP(), SMC_NOP(), SMC_WRITE(bank_reg, 0, CAR, 1, 0, 0), SMC_NOP()); + ret.add_inst(SMC_NOP(), SMC_NOP(), SMC_NOP(), SMC_WRITE(bank_reg, 0, CAR, 1, 0, 0)); + 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, 1), SMC_NOP(), SMC_NOP(), SMC_NOP()); + ret.add_inst(SMC_SLEEP(4)); + + ret.add_inst(SMC_ACT(bank_reg, 0, row_reg, 1), SMC_NOP(), SMC_NOP(), SMC_NOP()); + ret.add_inst(SMC_SLEEP(4)); + + for(int i = 0 ; i < 32 ; i++) + { + ret.add_inst(SMC_WRITE(bank_reg, 0, CAR, 1, 0, 0), SMC_NOP(), SMC_NOP(), SMC_NOP()); + ret.add_inst(SMC_NOP(), SMC_WRITE(bank_reg, 0, CAR, 1, 0, 0), SMC_NOP(), SMC_NOP()); + ret.add_inst(SMC_NOP(), SMC_NOP(), SMC_WRITE(bank_reg, 0, CAR, 1, 0, 0), SMC_NOP()); + ret.add_inst(SMC_NOP(), SMC_NOP(), SMC_NOP(), SMC_WRITE(bank_reg, 0, CAR, 1, 0, 0)); + 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, 1), SMC_NOP(), SMC_NOP(), SMC_NOP()); + ret.add_inst(SMC_SLEEP(4)); + + ret.add_inst(SMC_ACT(bank_reg, 0, row_reg, 1), SMC_NOP(), SMC_NOP(), SMC_NOP()); + ret.add_inst(SMC_SLEEP(4)); + + for(int i = 0 ; i < 32 ; i++) + { + ret.add_inst(SMC_WRITE(bank_reg, 0, CAR, 1, 0, 0), SMC_NOP(), SMC_NOP(), SMC_NOP()); + ret.add_inst(SMC_NOP(), SMC_WRITE(bank_reg, 0, CAR, 1, 0, 0), SMC_NOP(), SMC_NOP()); + ret.add_inst(SMC_NOP(), SMC_NOP(), SMC_WRITE(bank_reg, 0, CAR, 1, 0, 0), SMC_NOP()); + ret.add_inst(SMC_NOP(), SMC_NOP(), SMC_NOP(), SMC_WRITE(bank_reg, 0, CAR, 1, 0, 0)); + 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, 1), SMC_NOP(), SMC_NOP(), SMC_NOP()); + ret.add_inst(SMC_SLEEP(4)); + + ret.add_inst(SMC_MV(PATTERN_REG, TEMP_PATTERN_REG)); + ret.add_inst(SMC_MV(INV_PATTERN_REG, PATTERN_REG)); + ret.add_inst(SMC_MV(TEMP_PATTERN_REG, INV_PATTERN_REG)); + for(int i = 0 ; i < 16 ; i++) + ret.add_inst(SMC_LDWD(PATTERN_REG,i)); + + ret.add_inst(SMC_SUBI(row_reg, no_rows, row_reg)); + return ret; +} + +/** + * This function will generate a block of instructions that will + * write to a range of rows. It assumes the bank will be precharged. + */ +Program genWriteRange1001(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)); // write until this row + + ret.add_label("genWriteRange:LOOP_BEGIN"); + ret.add_inst(SMC_LI(0, CAR)); + + ret.add_inst(SMC_ACT(bank_reg, 0, row_reg, 1), SMC_NOP(), SMC_NOP(), SMC_NOP()); + ret.add_inst(SMC_SLEEP(4)); + + for(int i = 0 ; i < 32 ; i++) + { + ret.add_inst(SMC_WRITE(bank_reg, 0, CAR, 1, 0, 0), SMC_NOP(), SMC_NOP(), SMC_NOP()); + ret.add_inst(SMC_NOP(), SMC_WRITE(bank_reg, 0, CAR, 1, 0, 0), SMC_NOP(), SMC_NOP()); + ret.add_inst(SMC_NOP(), SMC_NOP(), SMC_WRITE(bank_reg, 0, CAR, 1, 0, 0), SMC_NOP()); + ret.add_inst(SMC_NOP(), SMC_NOP(), SMC_NOP(), SMC_WRITE(bank_reg, 0, CAR, 1, 0, 0)); + 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, 1), SMC_NOP(), SMC_NOP(), SMC_NOP()); + + ret.add_inst(SMC_MV(PATTERN_REG, TEMP_PATTERN_REG)); + ret.add_inst(SMC_MV(INV_PATTERN_REG, PATTERN_REG)); + ret.add_inst(SMC_MV(TEMP_PATTERN_REG, INV_PATTERN_REG)); + for(int i = 0 ; i < 16 ; i++) + ret.add_inst(SMC_LDWD(PATTERN_REG,i)); + + ret.add_inst(SMC_ACT(bank_reg, 0, row_reg, 1), SMC_NOP(), SMC_NOP(), SMC_NOP()); + ret.add_inst(SMC_SLEEP(4)); + + for(int i = 0 ; i < 32 ; i++) + { + ret.add_inst(SMC_WRITE(bank_reg, 0, CAR, 1, 0, 0), SMC_NOP(), SMC_NOP(), SMC_NOP()); + ret.add_inst(SMC_NOP(), SMC_WRITE(bank_reg, 0, CAR, 1, 0, 0), SMC_NOP(), SMC_NOP()); + ret.add_inst(SMC_NOP(), SMC_NOP(), SMC_WRITE(bank_reg, 0, CAR, 1, 0, 0), SMC_NOP()); + ret.add_inst(SMC_NOP(), SMC_NOP(), SMC_NOP(), SMC_WRITE(bank_reg, 0, CAR, 1, 0, 0)); + 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, 1), SMC_NOP(), SMC_NOP(), SMC_NOP()); + ret.add_inst(SMC_SLEEP(4)); + + ret.add_inst(SMC_ACT(bank_reg, 0, row_reg, 1), SMC_NOP(), SMC_NOP(), SMC_NOP()); + ret.add_inst(SMC_SLEEP(4)); + + for(int i = 0 ; i < 32 ; i++) + { + ret.add_inst(SMC_WRITE(bank_reg, 0, CAR, 1, 0, 0), SMC_NOP(), SMC_NOP(), SMC_NOP()); + ret.add_inst(SMC_NOP(), SMC_WRITE(bank_reg, 0, CAR, 1, 0, 0), SMC_NOP(), SMC_NOP()); + ret.add_inst(SMC_NOP(), SMC_NOP(), SMC_WRITE(bank_reg, 0, CAR, 1, 0, 0), SMC_NOP()); + ret.add_inst(SMC_NOP(), SMC_NOP(), SMC_NOP(), SMC_WRITE(bank_reg, 0, CAR, 1, 0, 0)); + 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, 1), SMC_NOP(), SMC_NOP(), SMC_NOP()); + ret.add_inst(SMC_SLEEP(4)); + + ret.add_inst(SMC_MV(PATTERN_REG, TEMP_PATTERN_REG)); + ret.add_inst(SMC_MV(INV_PATTERN_REG, PATTERN_REG)); + ret.add_inst(SMC_MV(TEMP_PATTERN_REG, INV_PATTERN_REG)); + for(int i = 0 ; i < 16 ; i++) + ret.add_inst(SMC_LDWD(PATTERN_REG,i)); + + ret.add_inst(SMC_ACT(bank_reg, 0, row_reg, 1), SMC_NOP(), SMC_NOP(), SMC_NOP()); + ret.add_inst(SMC_SLEEP(4)); + + for(int i = 0 ; i < 32 ; i++) + { + ret.add_inst(SMC_WRITE(bank_reg, 0, CAR, 1, 0, 0), SMC_NOP(), SMC_NOP(), SMC_NOP()); + ret.add_inst(SMC_NOP(), SMC_WRITE(bank_reg, 0, CAR, 1, 0, 0), SMC_NOP(), SMC_NOP()); + ret.add_inst(SMC_NOP(), SMC_NOP(), SMC_WRITE(bank_reg, 0, CAR, 1, 0, 0), SMC_NOP()); + ret.add_inst(SMC_NOP(), SMC_NOP(), SMC_NOP(), SMC_WRITE(bank_reg, 0, CAR, 1, 0, 0)); + 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, 1), SMC_NOP(), SMC_NOP(), SMC_NOP()); + ret.add_inst(SMC_SLEEP(4)); + + ret.add_inst(SMC_SUBI(row_reg, no_rows, row_reg)); + return ret; +} + +/** + * This function will generate a block of instructions that will + * write to a range of rows. It assumes the bank will be precharged. + */ +Program genWriteRange1010(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)); // write until this row + + ret.add_label("genWriteRange:LOOP_BEGIN"); + ret.add_inst(SMC_LI(0, CAR)); + + ret.add_inst(SMC_ACT(bank_reg, 0, row_reg, 1), SMC_NOP(), SMC_NOP(), SMC_NOP()); + ret.add_inst(SMC_SLEEP(4)); + + for(int i = 0 ; i < 32 ; i++) + { + ret.add_inst(SMC_WRITE(bank_reg, 0, CAR, 1, 0, 0), SMC_NOP(), SMC_NOP(), SMC_NOP()); + ret.add_inst(SMC_NOP(), SMC_WRITE(bank_reg, 0, CAR, 1, 0, 0), SMC_NOP(), SMC_NOP()); + ret.add_inst(SMC_NOP(), SMC_NOP(), SMC_WRITE(bank_reg, 0, CAR, 1, 0, 0), SMC_NOP()); + ret.add_inst(SMC_NOP(), SMC_NOP(), SMC_NOP(), SMC_WRITE(bank_reg, 0, CAR, 1, 0, 0)); + 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, 1), SMC_NOP(), SMC_NOP(), SMC_NOP()); + + ret.add_inst(SMC_MV(PATTERN_REG, TEMP_PATTERN_REG)); + ret.add_inst(SMC_MV(INV_PATTERN_REG, PATTERN_REG)); + ret.add_inst(SMC_MV(TEMP_PATTERN_REG, INV_PATTERN_REG)); + for(int i = 0 ; i < 16 ; i++) + ret.add_inst(SMC_LDWD(PATTERN_REG,i)); + + ret.add_branch(ret.BR_TYPE::BL, row_reg, INIT_LOOP, "genWriteRange:LOOP_BEGIN"); + ret.add_inst(SMC_SUBI(row_reg, no_rows, row_reg)); + return ret; +} + +/** + * This function will generate a block of instructions that will + * write to a range of rows. It assumes the bank will be precharged. + */ +Program genWriteRange1011(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)); // write until this row + + ret.add_label("genWriteRange:LOOP_BEGIN"); + ret.add_inst(SMC_LI(0, CAR)); + + ret.add_inst(SMC_ACT(bank_reg, 0, row_reg, 1), SMC_NOP(), SMC_NOP(), SMC_NOP()); + ret.add_inst(SMC_SLEEP(4)); + + for(int i = 0 ; i < 32 ; i++) + { + ret.add_inst(SMC_WRITE(bank_reg, 0, CAR, 1, 0, 0), SMC_NOP(), SMC_NOP(), SMC_NOP()); + ret.add_inst(SMC_NOP(), SMC_WRITE(bank_reg, 0, CAR, 1, 0, 0), SMC_NOP(), SMC_NOP()); + ret.add_inst(SMC_NOP(), SMC_NOP(), SMC_WRITE(bank_reg, 0, CAR, 1, 0, 0), SMC_NOP()); + ret.add_inst(SMC_NOP(), SMC_NOP(), SMC_NOP(), SMC_WRITE(bank_reg, 0, CAR, 1, 0, 0)); + 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, 1), SMC_NOP(), SMC_NOP(), SMC_NOP()); + + ret.add_inst(SMC_MV(PATTERN_REG, TEMP_PATTERN_REG)); + ret.add_inst(SMC_MV(INV_PATTERN_REG, PATTERN_REG)); + ret.add_inst(SMC_MV(TEMP_PATTERN_REG, INV_PATTERN_REG)); + for(int i = 0 ; i < 16 ; i++) + ret.add_inst(SMC_LDWD(PATTERN_REG,i)); + + ret.add_inst(SMC_ACT(bank_reg, 0, row_reg, 1), SMC_NOP(), SMC_NOP(), SMC_NOP()); + ret.add_inst(SMC_SLEEP(4)); + + for(int i = 0 ; i < 32 ; i++) + { + ret.add_inst(SMC_WRITE(bank_reg, 0, CAR, 1, 0, 0), SMC_NOP(), SMC_NOP(), SMC_NOP()); + ret.add_inst(SMC_NOP(), SMC_WRITE(bank_reg, 0, CAR, 1, 0, 0), SMC_NOP(), SMC_NOP()); + ret.add_inst(SMC_NOP(), SMC_NOP(), SMC_WRITE(bank_reg, 0, CAR, 1, 0, 0), SMC_NOP()); + ret.add_inst(SMC_NOP(), SMC_NOP(), SMC_NOP(), SMC_WRITE(bank_reg, 0, CAR, 1, 0, 0)); + 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, 1), SMC_NOP(), SMC_NOP(), SMC_NOP()); + ret.add_inst(SMC_SLEEP(4)); + + ret.add_inst(SMC_MV(PATTERN_REG, TEMP_PATTERN_REG)); + ret.add_inst(SMC_MV(INV_PATTERN_REG, PATTERN_REG)); + ret.add_inst(SMC_MV(TEMP_PATTERN_REG, INV_PATTERN_REG)); + for(int i = 0 ; i < 16 ; i++) + ret.add_inst(SMC_LDWD(PATTERN_REG,i)); + + ret.add_inst(SMC_ACT(bank_reg, 0, row_reg, 1), SMC_NOP(), SMC_NOP(), SMC_NOP()); + ret.add_inst(SMC_SLEEP(4)); + + for(int i = 0 ; i < 32 ; i++) + { + ret.add_inst(SMC_WRITE(bank_reg, 0, CAR, 1, 0, 0), SMC_NOP(), SMC_NOP(), SMC_NOP()); + ret.add_inst(SMC_NOP(), SMC_WRITE(bank_reg, 0, CAR, 1, 0, 0), SMC_NOP(), SMC_NOP()); + ret.add_inst(SMC_NOP(), SMC_NOP(), SMC_WRITE(bank_reg, 0, CAR, 1, 0, 0), SMC_NOP()); + ret.add_inst(SMC_NOP(), SMC_NOP(), SMC_NOP(), SMC_WRITE(bank_reg, 0, CAR, 1, 0, 0)); + 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, 1), SMC_NOP(), SMC_NOP(), SMC_NOP()); + ret.add_inst(SMC_SLEEP(4)); + + + ret.add_inst(SMC_ACT(bank_reg, 0, row_reg, 1), SMC_NOP(), SMC_NOP(), SMC_NOP()); + ret.add_inst(SMC_SLEEP(4)); + + for(int i = 0 ; i < 32 ; i++) + { + ret.add_inst(SMC_WRITE(bank_reg, 0, CAR, 1, 0, 0), SMC_NOP(), SMC_NOP(), SMC_NOP()); + ret.add_inst(SMC_NOP(), SMC_WRITE(bank_reg, 0, CAR, 1, 0, 0), SMC_NOP(), SMC_NOP()); + ret.add_inst(SMC_NOP(), SMC_NOP(), SMC_WRITE(bank_reg, 0, CAR, 1, 0, 0), SMC_NOP()); + ret.add_inst(SMC_NOP(), SMC_NOP(), SMC_NOP(), SMC_WRITE(bank_reg, 0, CAR, 1, 0, 0)); + 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, 1), SMC_NOP(), SMC_NOP(), SMC_NOP()); + ret.add_inst(SMC_SLEEP(4)); + + ret.add_inst(SMC_SUBI(row_reg, no_rows, row_reg)); + return ret; +} + +/** + * This function will generate a block of instructions that will + * write to a range of rows. It assumes the bank will be precharged. + */ +Program genWriteRange1100(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)); // write until this row + + ret.add_label("genWriteRange:LOOP_BEGIN"); + ret.add_inst(SMC_LI(0, CAR)); + + ret.add_inst(SMC_ACT(bank_reg, 0, row_reg, 1), SMC_NOP(), SMC_NOP(), SMC_NOP()); + ret.add_inst(SMC_SLEEP(4)); + + for(int i = 0 ; i < 32 ; i++) + { + ret.add_inst(SMC_WRITE(bank_reg, 0, CAR, 1, 0, 0), SMC_NOP(), SMC_NOP(), SMC_NOP()); + ret.add_inst(SMC_NOP(), SMC_WRITE(bank_reg, 0, CAR, 1, 0, 0), SMC_NOP(), SMC_NOP()); + ret.add_inst(SMC_NOP(), SMC_NOP(), SMC_WRITE(bank_reg, 0, CAR, 1, 0, 0), SMC_NOP()); + ret.add_inst(SMC_NOP(), SMC_NOP(), SMC_NOP(), SMC_WRITE(bank_reg, 0, CAR, 1, 0, 0)); + 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, 1), SMC_NOP(), SMC_NOP(), SMC_NOP()); + + ret.add_inst(SMC_SLEEP(4)); + + + ret.add_inst(SMC_ACT(bank_reg, 0, row_reg, 1), SMC_NOP(), SMC_NOP(), SMC_NOP()); + ret.add_inst(SMC_SLEEP(4)); + + for(int i = 0 ; i < 32 ; i++) + { + ret.add_inst(SMC_WRITE(bank_reg, 0, CAR, 1, 0, 0), SMC_NOP(), SMC_NOP(), SMC_NOP()); + ret.add_inst(SMC_NOP(), SMC_WRITE(bank_reg, 0, CAR, 1, 0, 0), SMC_NOP(), SMC_NOP()); + ret.add_inst(SMC_NOP(), SMC_NOP(), SMC_WRITE(bank_reg, 0, CAR, 1, 0, 0), SMC_NOP()); + ret.add_inst(SMC_NOP(), SMC_NOP(), SMC_NOP(), SMC_WRITE(bank_reg, 0, CAR, 1, 0, 0)); + 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, 1), SMC_NOP(), SMC_NOP(), SMC_NOP()); + ret.add_inst(SMC_SLEEP(4)); + + ret.add_inst(SMC_MV(PATTERN_REG, TEMP_PATTERN_REG)); + ret.add_inst(SMC_MV(INV_PATTERN_REG, PATTERN_REG)); + ret.add_inst(SMC_MV(TEMP_PATTERN_REG, INV_PATTERN_REG)); + for(int i = 0 ; i < 16 ; i++) + ret.add_inst(SMC_LDWD(PATTERN_REG,i)); + + ret.add_inst(SMC_ACT(bank_reg, 0, row_reg, 1), SMC_NOP(), SMC_NOP(), SMC_NOP()); + ret.add_inst(SMC_SLEEP(4)); + + for(int i = 0 ; i < 32 ; i++) + { + ret.add_inst(SMC_WRITE(bank_reg, 0, CAR, 1, 0, 0), SMC_NOP(), SMC_NOP(), SMC_NOP()); + ret.add_inst(SMC_NOP(), SMC_WRITE(bank_reg, 0, CAR, 1, 0, 0), SMC_NOP(), SMC_NOP()); + ret.add_inst(SMC_NOP(), SMC_NOP(), SMC_WRITE(bank_reg, 0, CAR, 1, 0, 0), SMC_NOP()); + ret.add_inst(SMC_NOP(), SMC_NOP(), SMC_NOP(), SMC_WRITE(bank_reg, 0, CAR, 1, 0, 0)); + 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, 1), SMC_NOP(), SMC_NOP(), SMC_NOP()); + ret.add_inst(SMC_SLEEP(4)); + + ret.add_inst(SMC_ACT(bank_reg, 0, row_reg, 1), SMC_NOP(), SMC_NOP(), SMC_NOP()); + ret.add_inst(SMC_SLEEP(4)); + + for(int i = 0 ; i < 32 ; i++) + { + ret.add_inst(SMC_WRITE(bank_reg, 0, CAR, 1, 0, 0), SMC_NOP(), SMC_NOP(), SMC_NOP()); + ret.add_inst(SMC_NOP(), SMC_WRITE(bank_reg, 0, CAR, 1, 0, 0), SMC_NOP(), SMC_NOP()); + ret.add_inst(SMC_NOP(), SMC_NOP(), SMC_WRITE(bank_reg, 0, CAR, 1, 0, 0), SMC_NOP()); + ret.add_inst(SMC_NOP(), SMC_NOP(), SMC_NOP(), SMC_WRITE(bank_reg, 0, CAR, 1, 0, 0)); + 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, 1), SMC_NOP(), SMC_NOP(), SMC_NOP()); + ret.add_inst(SMC_SLEEP(4)); + + ret.add_inst(SMC_MV(PATTERN_REG, TEMP_PATTERN_REG)); + ret.add_inst(SMC_MV(INV_PATTERN_REG, PATTERN_REG)); + ret.add_inst(SMC_MV(TEMP_PATTERN_REG, INV_PATTERN_REG)); + for(int i = 0 ; i < 16 ; i++) + ret.add_inst(SMC_LDWD(PATTERN_REG,i)); + + ret.add_inst(SMC_SUBI(row_reg, no_rows, row_reg)); + return ret; +} + +/** + * This function will generate a block of instructions that will + * write to a range of rows. It assumes the bank will be precharged. + */ +Program genWriteRange1101(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)); // write until this row + + ret.add_label("genWriteRange:LOOP_BEGIN"); + ret.add_inst(SMC_LI(0, CAR)); + + ret.add_inst(SMC_ACT(bank_reg, 0, row_reg, 1), SMC_NOP(), SMC_NOP(), SMC_NOP()); + ret.add_inst(SMC_SLEEP(4)); + + for(int i = 0 ; i < 32 ; i++) + { + ret.add_inst(SMC_WRITE(bank_reg, 0, CAR, 1, 0, 0), SMC_NOP(), SMC_NOP(), SMC_NOP()); + ret.add_inst(SMC_NOP(), SMC_WRITE(bank_reg, 0, CAR, 1, 0, 0), SMC_NOP(), SMC_NOP()); + ret.add_inst(SMC_NOP(), SMC_NOP(), SMC_WRITE(bank_reg, 0, CAR, 1, 0, 0), SMC_NOP()); + ret.add_inst(SMC_NOP(), SMC_NOP(), SMC_NOP(), SMC_WRITE(bank_reg, 0, CAR, 1, 0, 0)); + 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, 1), SMC_NOP(), SMC_NOP(), SMC_NOP()); + + ret.add_inst(SMC_SLEEP(4)); + + + ret.add_inst(SMC_ACT(bank_reg, 0, row_reg, 1), SMC_NOP(), SMC_NOP(), SMC_NOP()); + ret.add_inst(SMC_SLEEP(4)); + + for(int i = 0 ; i < 32 ; i++) + { + ret.add_inst(SMC_WRITE(bank_reg, 0, CAR, 1, 0, 0), SMC_NOP(), SMC_NOP(), SMC_NOP()); + ret.add_inst(SMC_NOP(), SMC_WRITE(bank_reg, 0, CAR, 1, 0, 0), SMC_NOP(), SMC_NOP()); + ret.add_inst(SMC_NOP(), SMC_NOP(), SMC_WRITE(bank_reg, 0, CAR, 1, 0, 0), SMC_NOP()); + ret.add_inst(SMC_NOP(), SMC_NOP(), SMC_NOP(), SMC_WRITE(bank_reg, 0, CAR, 1, 0, 0)); + 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, 1), SMC_NOP(), SMC_NOP(), SMC_NOP()); + ret.add_inst(SMC_SLEEP(4)); + + ret.add_inst(SMC_MV(PATTERN_REG, TEMP_PATTERN_REG)); + ret.add_inst(SMC_MV(INV_PATTERN_REG, PATTERN_REG)); + ret.add_inst(SMC_MV(TEMP_PATTERN_REG, INV_PATTERN_REG)); + for(int i = 0 ; i < 16 ; i++) + ret.add_inst(SMC_LDWD(PATTERN_REG,i)); + + ret.add_inst(SMC_ACT(bank_reg, 0, row_reg, 1), SMC_NOP(), SMC_NOP(), SMC_NOP()); + ret.add_inst(SMC_SLEEP(4)); + + for(int i = 0 ; i < 32 ; i++) + { + ret.add_inst(SMC_WRITE(bank_reg, 0, CAR, 1, 0, 0), SMC_NOP(), SMC_NOP(), SMC_NOP()); + ret.add_inst(SMC_NOP(), SMC_WRITE(bank_reg, 0, CAR, 1, 0, 0), SMC_NOP(), SMC_NOP()); + ret.add_inst(SMC_NOP(), SMC_NOP(), SMC_WRITE(bank_reg, 0, CAR, 1, 0, 0), SMC_NOP()); + ret.add_inst(SMC_NOP(), SMC_NOP(), SMC_NOP(), SMC_WRITE(bank_reg, 0, CAR, 1, 0, 0)); + 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, 1), SMC_NOP(), SMC_NOP(), SMC_NOP()); + ret.add_inst(SMC_SLEEP(4)); + + ret.add_inst(SMC_MV(PATTERN_REG, TEMP_PATTERN_REG)); + ret.add_inst(SMC_MV(INV_PATTERN_REG, PATTERN_REG)); + ret.add_inst(SMC_MV(TEMP_PATTERN_REG, INV_PATTERN_REG)); + for(int i = 0 ; i < 16 ; i++) + ret.add_inst(SMC_LDWD(PATTERN_REG,i)); + + ret.add_inst(SMC_ACT(bank_reg, 0, row_reg, 1), SMC_NOP(), SMC_NOP(), SMC_NOP()); + ret.add_inst(SMC_SLEEP(4)); + + for(int i = 0 ; i < 32 ; i++) + { + ret.add_inst(SMC_WRITE(bank_reg, 0, CAR, 1, 0, 0), SMC_NOP(), SMC_NOP(), SMC_NOP()); + ret.add_inst(SMC_NOP(), SMC_WRITE(bank_reg, 0, CAR, 1, 0, 0), SMC_NOP(), SMC_NOP()); + ret.add_inst(SMC_NOP(), SMC_NOP(), SMC_WRITE(bank_reg, 0, CAR, 1, 0, 0), SMC_NOP()); + ret.add_inst(SMC_NOP(), SMC_NOP(), SMC_NOP(), SMC_WRITE(bank_reg, 0, CAR, 1, 0, 0)); + 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, 1), SMC_NOP(), SMC_NOP(), SMC_NOP()); + ret.add_inst(SMC_SLEEP(4)); + + + + ret.add_inst(SMC_SUBI(row_reg, no_rows, row_reg)); + return ret; +} + +/** + * This function will generate a block of instructions that will + * write to a range of rows. It assumes the bank will be precharged. + */ +Program genWriteRange1110(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)); // write until this row + + ret.add_label("genWriteRange:LOOP_BEGIN"); + ret.add_inst(SMC_LI(0, CAR)); + + ret.add_inst(SMC_ACT(bank_reg, 0, row_reg, 1), SMC_NOP(), SMC_NOP(), SMC_NOP()); + ret.add_inst(SMC_SLEEP(4)); + + for(int i = 0 ; i < 32 ; i++) + { + ret.add_inst(SMC_WRITE(bank_reg, 0, CAR, 1, 0, 0), SMC_NOP(), SMC_NOP(), SMC_NOP()); + ret.add_inst(SMC_NOP(), SMC_WRITE(bank_reg, 0, CAR, 1, 0, 0), SMC_NOP(), SMC_NOP()); + ret.add_inst(SMC_NOP(), SMC_NOP(), SMC_WRITE(bank_reg, 0, CAR, 1, 0, 0), SMC_NOP()); + ret.add_inst(SMC_NOP(), SMC_NOP(), SMC_NOP(), SMC_WRITE(bank_reg, 0, CAR, 1, 0, 0)); + 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, 1), SMC_NOP(), SMC_NOP(), SMC_NOP()); + + ret.add_inst(SMC_SLEEP(4)); + ret.add_inst(SMC_ACT(bank_reg, 0, row_reg, 1), SMC_NOP(), SMC_NOP(), SMC_NOP()); + ret.add_inst(SMC_SLEEP(4)); + + for(int i = 0 ; i < 32 ; i++) + { + ret.add_inst(SMC_WRITE(bank_reg, 0, CAR, 1, 0, 0), SMC_NOP(), SMC_NOP(), SMC_NOP()); + ret.add_inst(SMC_NOP(), SMC_WRITE(bank_reg, 0, CAR, 1, 0, 0), SMC_NOP(), SMC_NOP()); + ret.add_inst(SMC_NOP(), SMC_NOP(), SMC_WRITE(bank_reg, 0, CAR, 1, 0, 0), SMC_NOP()); + ret.add_inst(SMC_NOP(), SMC_NOP(), SMC_NOP(), SMC_WRITE(bank_reg, 0, CAR, 1, 0, 0)); + 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, 1), SMC_NOP(), SMC_NOP(), SMC_NOP()); + ret.add_inst(SMC_SLEEP(4)); + + ret.add_inst(SMC_ACT(bank_reg, 0, row_reg, 1), SMC_NOP(), SMC_NOP(), SMC_NOP()); + ret.add_inst(SMC_SLEEP(4)); + + for(int i = 0 ; i < 32 ; i++) + { + ret.add_inst(SMC_WRITE(bank_reg, 0, CAR, 1, 0, 0), SMC_NOP(), SMC_NOP(), SMC_NOP()); + ret.add_inst(SMC_NOP(), SMC_WRITE(bank_reg, 0, CAR, 1, 0, 0), SMC_NOP(), SMC_NOP()); + ret.add_inst(SMC_NOP(), SMC_NOP(), SMC_WRITE(bank_reg, 0, CAR, 1, 0, 0), SMC_NOP()); + ret.add_inst(SMC_NOP(), SMC_NOP(), SMC_NOP(), SMC_WRITE(bank_reg, 0, CAR, 1, 0, 0)); + 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, 1), SMC_NOP(), SMC_NOP(), SMC_NOP()); + ret.add_inst(SMC_SLEEP(4)); + + ret.add_inst(SMC_MV(PATTERN_REG, TEMP_PATTERN_REG)); + ret.add_inst(SMC_MV(INV_PATTERN_REG, PATTERN_REG)); + ret.add_inst(SMC_MV(TEMP_PATTERN_REG, INV_PATTERN_REG)); + for(int i = 0 ; i < 16 ; i++) + ret.add_inst(SMC_LDWD(PATTERN_REG,i)); + + ret.add_inst(SMC_ACT(bank_reg, 0, row_reg, 1), SMC_NOP(), SMC_NOP(), SMC_NOP()); + ret.add_inst(SMC_SLEEP(4)); + + for(int i = 0 ; i < 32 ; i++) + { + ret.add_inst(SMC_WRITE(bank_reg, 0, CAR, 1, 0, 0), SMC_NOP(), SMC_NOP(), SMC_NOP()); + ret.add_inst(SMC_NOP(), SMC_WRITE(bank_reg, 0, CAR, 1, 0, 0), SMC_NOP(), SMC_NOP()); + ret.add_inst(SMC_NOP(), SMC_NOP(), SMC_WRITE(bank_reg, 0, CAR, 1, 0, 0), SMC_NOP()); + ret.add_inst(SMC_NOP(), SMC_NOP(), SMC_NOP(), SMC_WRITE(bank_reg, 0, CAR, 1, 0, 0)); + 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, 1), SMC_NOP(), SMC_NOP(), SMC_NOP()); + ret.add_inst(SMC_SLEEP(4)); + + ret.add_inst(SMC_MV(PATTERN_REG, TEMP_PATTERN_REG)); + ret.add_inst(SMC_MV(INV_PATTERN_REG, PATTERN_REG)); + ret.add_inst(SMC_MV(TEMP_PATTERN_REG, INV_PATTERN_REG)); + for(int i = 0 ; i < 16 ; i++) + ret.add_inst(SMC_LDWD(PATTERN_REG,i)); + + ret.add_inst(SMC_SUBI(row_reg, no_rows, row_reg)); + return ret; +} + +/** + * This function will generate a block of instructions that will + * write to a range of rows. It assumes the bank will be precharged. + */ +Program genWriteRange1111(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)); // write until this row + + ret.add_label("genWriteRange:LOOP_BEGIN"); + ret.add_inst(SMC_LI(0, CAR)); + + ret.add_inst(SMC_ACT(bank_reg, 0, row_reg, 1), SMC_NOP(), SMC_NOP(), SMC_NOP()); + ret.add_inst(SMC_SLEEP(4)); + + for(int i = 0 ; i < 32 ; i++) + { + ret.add_inst(SMC_WRITE(bank_reg, 0, CAR, 1, 0, 0), SMC_NOP(), SMC_NOP(), SMC_NOP()); + ret.add_inst(SMC_NOP(), SMC_WRITE(bank_reg, 0, CAR, 1, 0, 0), SMC_NOP(), SMC_NOP()); + ret.add_inst(SMC_NOP(), SMC_NOP(), SMC_WRITE(bank_reg, 0, CAR, 1, 0, 0), SMC_NOP()); + ret.add_inst(SMC_NOP(), SMC_NOP(), SMC_NOP(), SMC_WRITE(bank_reg, 0, CAR, 1, 0, 0)); + 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, 1), SMC_NOP(), SMC_NOP(), SMC_NOP()); + + ret.add_branch(ret.BR_TYPE::BL, row_reg, INIT_LOOP, "genWriteRange:LOOP_BEGIN"); + ret.add_inst(SMC_SUBI(row_reg, no_rows, row_reg)); + return ret; +} + +/** + * @return an instruction formed by NOPs + */ +Inst all_nops() +{ + return __pack_mininsts(SMC_NOP(), SMC_NOP(), SMC_NOP(), SMC_NOP()); +} diff --git a/sources/apps/QUAC-TRNG/src/util.h b/sources/apps/QUAC-TRNG/src/util.h new file mode 100644 index 0000000..1f07e0e --- /dev/null +++ b/sources/apps/QUAC-TRNG/src/util.h @@ -0,0 +1,55 @@ +#ifndef UTIL_HH +#define UTIL_HH + +#include "prog.h" + +#define ITERS_DUMP 1024*1024 +#define READ_CL_DUMP 8 + +#define ITERS 10000 //1024*1024 // 256*8 +#define READ_CL 128 + +#define NO_BANKS 1 +#define NO_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 PATTERN_REG 12 +#define INV_PATTERN_REG 13 +#define TEMP_PATTERN_REG 14 + +#define BAR 3 +#define CAR 4 +#define RARBASE 5 +#define RAR1 6 +#define RAR2 9 + +#define COPY_REG1 10 +#define COPY_REG2 11 + +#define ITER_REG 7 +#define CTR_REG 8 + +#define INIT_LOOP 15 + +Program genActPreActSequence(int t1, int t2, int row1_reg, int row2_reg, int bank_reg); +Program genReadRange(int row_reg, int no_rows, int bank_reg, int read_cols); +Program genWriteRange1000(int row_reg, int no_rows, int bank_reg); +Program genWriteRange1111(int row_reg, int no_rows, int bank_reg); +Program genWriteRange1001(int row_reg, int no_rows, int bank_reg); +Program genWriteRange1010(int row_reg, int no_rows, int bank_reg); +Program genWriteRange1011(int row_reg, int no_rows, int bank_reg); +Program genWriteRange1100(int row_reg, int no_rows, int bank_reg); +Program genWriteRange1101(int row_reg, int no_rows, int bank_reg); +Program genWriteRange1110(int row_reg, int no_rows, int bank_reg); +Inst all_nops(); + + + +#endif |
