diff options
| author | yct000 <yahyacantugrul@gmail.com> | 2023-06-05 15:09:13 +0200 |
|---|---|---|
| committer | yct000 <yahyacantugrul@gmail.com> | 2023-06-05 15:09:13 +0200 |
| commit | 23c13329255364dc1730d7ea220c1497c055e9dc (patch) | |
| tree | b26f239d9c30d6d3b5e4aa79ffe86e922e4dea84 /sources/apps/case_studies/cs1_interleaving_pattern/tools.h | |
| parent | 59ec1e91bedd156ae37f3a835782088c74346f76 (diff) | |
| download | dram-bender-23c13329255364dc1730d7ea220c1497c055e9dc.tar.gz | |
Add case study#1's sources
Diffstat (limited to 'sources/apps/case_studies/cs1_interleaving_pattern/tools.h')
| -rw-r--r-- | sources/apps/case_studies/cs1_interleaving_pattern/tools.h | 213 |
1 files changed, 213 insertions, 0 deletions
diff --git a/sources/apps/case_studies/cs1_interleaving_pattern/tools.h b/sources/apps/case_studies/cs1_interleaving_pattern/tools.h new file mode 100644 index 0000000..2c00865 --- /dev/null +++ b/sources/apps/case_studies/cs1_interleaving_pattern/tools.h @@ -0,0 +1,213 @@ +#pragma once +#define TOOLS_H + +#include "instruction.h" +#include "prog.h" + +#include <cstdint> +#include <vector> +#include <exception> +#include <cassert> +#include <algorithm> +#include <chrono> +#include <iostream> + +Inst all_nops() +{ + return __pack_mininsts(SMC_NOP(), SMC_NOP(), SMC_NOP(), SMC_NOP()); +} + +void sleep_delay (Program& program, uint64_t sleep_time) { + while(sleep_time > UINT32_MAX){ + program.add_inst(SMC_SLEEP(UINT32_MAX)); + sleep_time -= UINT32_MAX; + } + switch(sleep_time){ + case 0: + break; + case 1: + program.add_inst(all_nops()); + break; + case 2: + program.add_inst(all_nops()); + program.add_inst(all_nops()); + break; + default: + program.add_inst(SMC_SLEEP(sleep_time)); + break; + } +} + +int add_op_with_delay (Program& prog, Mininst ins, int before_cycles, int after_cycles) { + + int remaining = before_cycles < 0 ? 0 : before_cycles; + + while(remaining >= 4) { + prog.add_inst(all_nops()); + remaining -= 4; + } + + switch(remaining) { + case 0: + prog.add_inst(__pack_mininsts(ins, SMC_NOP(), SMC_NOP(), SMC_NOP())); + remaining = after_cycles - 3; + break; + case 1: + prog.add_inst(__pack_mininsts(SMC_NOP(), ins, SMC_NOP(), SMC_NOP())); + remaining = after_cycles - 2; + break; + case 2: + prog.add_inst(__pack_mininsts(SMC_NOP(), SMC_NOP(), ins, SMC_NOP())); + remaining = after_cycles - 1; + break; + case 3: + prog.add_inst(__pack_mininsts(SMC_NOP(), SMC_NOP(), SMC_NOP(), ins)); + remaining = after_cycles; + break; + + default: + assert(false && "This line should not be reached. Possible bug in the program."); + } + + while (remaining >= 4) { + prog.add_inst(all_nops()); + remaining -= 4; + } + + return remaining; +} + +int add_op_with_delay (Program& prog, Inst ins, int before_cycles, int after_cycles) { + + int remaining = before_cycles; + + while(remaining > 0) { + prog.add_inst(all_nops()); + remaining -= 4; + } + + prog.add_inst(ins); + remaining = after_cycles; + + while (remaining >= 4) { + prog.add_inst(all_nops()); + remaining -= 4; + } + + return remaining; +} + + + +typedef uint32_t SMC_REG; + +struct OutOfSoftMCRegsException : public std::exception { + const char * what () const throw () { + return "No more SoftMC registers to allocate."; + } +}; + +static uint32_t label_counter = 0; +std::string createSMCLabel(const std::string& name) { + return name + std::to_string(label_counter++); +} + +class SoftMCRegAllocator { + + public: + SoftMCRegAllocator(uint32_t num_regs, const std::vector<uint32_t>& reserved_regs) { + free_regs.reserve(num_regs); + + for(uint32_t i = 0; i < num_regs; i++) { + if(std::find(reserved_regs.begin(), reserved_regs.end(), i) == reserved_regs.end()) + free_regs.emplace_back(i); + } + } + + SMC_REG allocate_SMC_REG() { + if(free_regs.size() == 0) + throw OutOfSoftMCRegsException(); + + SMC_REG ret_reg = *(free_regs.begin()); + free_regs.erase(free_regs.begin()); + return ret_reg; + } + + void free_SMC_REG(const SMC_REG r) { + // make sure r is not in the free list + auto it = std::find(free_regs.begin(), free_regs.end(), r); + assert(it == free_regs.end()); + + free_regs.push_back(r); + } + + uint num_free_regs() const { + return free_regs.size(); + } + + private: + std::vector<uint32_t> free_regs; +}; + + +typedef uint PhysicalRowID; +typedef uint LogicalRowID; + +typedef enum LogPhysRowIDScheme { + SEQUENTIAL, + SAMSUNG, + MAX +} LogPhysRowIDScheme; + +LogPhysRowIDScheme logical_physical_conversion_scheme = LogPhysRowIDScheme::SEQUENTIAL; + +PhysicalRowID to_physical_row_id(uint logical_row_id) { + + switch(logical_physical_conversion_scheme) { + case LogPhysRowIDScheme::SEQUENTIAL: { + return logical_row_id; + break; + } + case LogPhysRowIDScheme::SAMSUNG: { + if(logical_row_id & 0x8) { + PhysicalRowID phys_row_id = logical_row_id & 0xFFFFFFF9; + phys_row_id |= (~logical_row_id & 0x00000006); // set bit pos 3 and 2 + + return phys_row_id; + } else { + return logical_row_id; + } + break; + } + default: { + std::cout << "ERROR: unimplemented logical to physical row id conversion scheme!" << std::endl; + exit(1); + } + } +} + +LogicalRowID to_logical_row_id(uint physical_row_id) { + switch(logical_physical_conversion_scheme) { + case LogPhysRowIDScheme::SEQUENTIAL: { + return physical_row_id; + break; + } + case LogPhysRowIDScheme::SAMSUNG: { + if(physical_row_id & 0x8) { + PhysicalRowID log_row_id = physical_row_id & 0xFFFFFFF9; + log_row_id |= (~physical_row_id & 0x00000006); // set bit pos 3 and 2 + + return log_row_id; + } else { + return physical_row_id; + } + break; + } + default: { + std::cout << "ERROR: unimplemented physical to logical row id conversion scheme!" << std::endl; + exit(1); + } + } + + return 0; +} |
