diff --git a/benches/addressdecoder.cpp b/benches/addressdecoder.cpp index 7b93dbed..9e129b1b 100644 --- a/benches/addressdecoder.cpp +++ b/benches/addressdecoder.cpp @@ -59,7 +59,8 @@ static void decode(benchmark::State& state) for (auto _ : state) { - auto decodedAddress = decoder.decodeAddress(distribution(engine)); + auto randomAddress = distribution(engine); + auto decodedAddress = decoder.decodeAddress(randomAddress); benchmark::DoNotOptimize(decodedAddress); } } diff --git a/src/configuration/DRAMSys/config/AddressMapping.h b/src/configuration/DRAMSys/config/AddressMapping.h index d3127201..0c4806ed 100644 --- a/src/configuration/DRAMSys/config/AddressMapping.h +++ b/src/configuration/DRAMSys/config/AddressMapping.h @@ -43,28 +43,21 @@ namespace DRAMSys::Config { -struct XorPair -{ - unsigned int FIRST; - unsigned int SECOND; -}; - -NLOHMANN_JSONIFY_ALL_THINGS(XorPair, FIRST, SECOND) - struct AddressMapping { static constexpr std::string_view KEY = "addressmapping"; static constexpr std::string_view SUB_DIR = "addressmapping"; - std::optional> BYTE_BIT; - std::optional> COLUMN_BIT; - std::optional> ROW_BIT; - std::optional> BANK_BIT; - std::optional> BANKGROUP_BIT; - std::optional> RANK_BIT; - std::optional> PSEUDOCHANNEL_BIT; - std::optional> CHANNEL_BIT; - std::optional> XOR; + using BitEntry = std::variant>; + + std::optional> BYTE_BIT; + std::optional> COLUMN_BIT; + std::optional> ROW_BIT; + std::optional> BANK_BIT; + std::optional> BANKGROUP_BIT; + std::optional> RANK_BIT; + std::optional> PSEUDOCHANNEL_BIT; + std::optional> CHANNEL_BIT; }; NLOHMANN_JSONIFY_ALL_THINGS(AddressMapping, @@ -75,8 +68,7 @@ NLOHMANN_JSONIFY_ALL_THINGS(AddressMapping, BANKGROUP_BIT, RANK_BIT, PSEUDOCHANNEL_BIT, - CHANNEL_BIT, - XOR) + CHANNEL_BIT) } // namespace DRAMSys::Config diff --git a/src/libdramsys/DRAMSys/simulation/AddressDecoder.cpp b/src/libdramsys/DRAMSys/simulation/AddressDecoder.cpp index ac99a572..62aa2c61 100644 --- a/src/libdramsys/DRAMSys/simulation/AddressDecoder.cpp +++ b/src/libdramsys/DRAMSys/simulation/AddressDecoder.cpp @@ -47,56 +47,71 @@ namespace DRAMSys { +static void addMapping(std::vector const& mappingVector, + std::vector& bitVector, + std::vector>& xorVector) +{ + for (const auto& bitEntry : mappingVector) + { + std::visit( + [&bitVector, &xorVector](auto&& arg) + { + using T = std::decay_t; + if constexpr (std::is_same_v) + { + bitVector.push_back(arg); + } + else if constexpr (std::is_same_v>) + { + bitVector.push_back(arg.at(0)); + xorVector.push_back(arg); + } + }, + bitEntry); + } +} + AddressDecoder::AddressDecoder(const DRAMSys::Config::AddressMapping& addressMapping) { if (const auto& channelBits = addressMapping.CHANNEL_BIT) { - std::copy(channelBits->begin(), channelBits->end(), std::back_inserter(vChannelBits)); + addMapping(*channelBits, vChannelBits, vXor); } if (const auto& rankBits = addressMapping.RANK_BIT) { - std::copy(rankBits->begin(), rankBits->end(), std::back_inserter(vRankBits)); + addMapping(*rankBits, vRankBits, vXor); } // HBM pseudo channels are internally modelled as ranks if (const auto& pseudoChannelBits = addressMapping.PSEUDOCHANNEL_BIT) { - std::copy( - pseudoChannelBits->begin(), pseudoChannelBits->end(), std::back_inserter(vRankBits)); + addMapping(*pseudoChannelBits, vRankBits, vXor); } if (const auto& bankGroupBits = addressMapping.BANKGROUP_BIT) { - std::copy(bankGroupBits->begin(), bankGroupBits->end(), std::back_inserter(vBankGroupBits)); + addMapping(*bankGroupBits, vBankGroupBits, vXor); } if (const auto& byteBits = addressMapping.BYTE_BIT) { - std::copy(byteBits->begin(), byteBits->end(), std::back_inserter(vByteBits)); - } - - if (const auto& xorBits = addressMapping.XOR) - { - for (const auto& xorBit : *xorBits) - { - vXor.emplace_back(xorBit.FIRST, xorBit.SECOND); - } + addMapping(*byteBits, vByteBits, vXor); } if (const auto& bankBits = addressMapping.BANK_BIT) { - std::copy(bankBits->begin(), bankBits->end(), std::back_inserter(vBankBits)); + addMapping(*bankBits, vBankBits, vXor); } if (const auto& rowBits = addressMapping.ROW_BIT) { - std::copy(rowBits->begin(), rowBits->end(), std::back_inserter(vRowBits)); + addMapping(*rowBits, vRowBits, vXor); } if (const auto& columnBits = addressMapping.COLUMN_BIT) { - std::copy(columnBits->begin(), columnBits->end(), std::back_inserter(vColumnBits)); + addMapping(*columnBits, vColumnBits, vXor); } unsigned channels = std::lround(std::pow(2.0, vChannelBits.size())); @@ -188,12 +203,16 @@ DecodedAddress AddressDecoder::decodeAddress(uint64_t encAddr) const // For each used xor: // Get the first bit and second bit. Apply a bitwise xor operator and save it back to the // first bit. + auto tempAddr = encAddr; for (const auto& it : vXor) { - uint64_t xoredBit = - (((encAddr >> it.first) & UINT64_C(1)) ^ ((encAddr >> it.second) & UINT64_C(1))); - encAddr &= ~(UINT64_C(1) << it.first); - encAddr |= xoredBit << it.first; + uint64_t xoredBit = std::accumulate(it.cbegin(), + it.cend(), + 0, + [tempAddr](uint64_t acc, unsigned xorBit) + { return acc ^= (tempAddr >> xorBit) & UINT64_C(1); }); + encAddr &= ~(UINT64_C(1) << it[0]); + encAddr |= xoredBit << it[0]; } DecodedAddress decAddr; @@ -238,12 +257,16 @@ unsigned AddressDecoder::decodeChannel(uint64_t encAddr) const // For each used xor: // Get the first bit and second bit. Apply a bitwise xor operator and save it back to the // first bit. + auto tempAddr = encAddr; for (const auto& it : vXor) { - uint64_t xoredBit = - (((encAddr >> it.first) & UINT64_C(1)) ^ ((encAddr >> it.second) & UINT64_C(1))); - encAddr &= ~(UINT64_C(1) << it.first); - encAddr |= xoredBit << it.first; + uint64_t xoredBit = std::accumulate(it.cbegin(), + it.cend(), + 0, + [tempAddr](uint64_t acc, unsigned xorBit) + { return acc ^= (tempAddr >> xorBit) & UINT64_C(1); }); + encAddr &= ~(UINT64_C(1) << it[0]); + encAddr |= xoredBit << it[0]; } unsigned channel = 0; @@ -298,10 +321,13 @@ void AddressDecoder::print() const { uint64_t addressBits = (UINT64_C(1) << vChannelBits[static_cast::size_type>(it)]); - for (auto it2 : vXor) + for (auto xorMapping : vXor) { - if (it2.first == vChannelBits[static_cast::size_type>(it)]) - addressBits |= (UINT64_C(1) << it2.second); + if (xorMapping.at(0) == vChannelBits[static_cast::size_type>(it)]) + { + for (auto it = xorMapping.cbegin() + 1; it != xorMapping.cend(); it++) + addressBits |= (UINT64_C(1) << *it); + } } std::cout << " Ch " << std::setw(2) << it << ": " << std::bitset<64>(addressBits) << std::endl; @@ -311,10 +337,13 @@ void AddressDecoder::print() const { uint64_t addressBits = (UINT64_C(1) << vRankBits[static_cast::size_type>(it)]); - for (auto it2 : vXor) + for (auto xorMapping : vXor) { - if (it2.first == vRankBits[static_cast::size_type>(it)]) - addressBits |= (UINT64_C(1) << it2.second); + if (xorMapping.at(0) == vRankBits[static_cast::size_type>(it)]) + { + for (auto it = xorMapping.cbegin() + 1; it != xorMapping.cend(); it++) + addressBits |= (UINT64_C(1) << *it); + } } std::cout << " Ra " << std::setw(2) << it << ": " << std::bitset<64>(addressBits) << std::endl; @@ -324,10 +353,14 @@ void AddressDecoder::print() const { uint64_t addressBits = (UINT64_C(1) << vBankGroupBits[static_cast::size_type>(it)]); - for (auto it2 : vXor) + for (auto xorMapping : vXor) { - if (it2.first == vBankGroupBits[static_cast::size_type>(it)]) - addressBits |= (UINT64_C(1) << it2.second); + if (xorMapping.at(0) == + vBankGroupBits[static_cast::size_type>(it)]) + { + for (auto it = xorMapping.cbegin() + 1; it != xorMapping.cend(); it++) + addressBits |= (UINT64_C(1) << *it); + } } std::cout << " Bg " << std::setw(2) << it << ": " << std::bitset<64>(addressBits) << std::endl; @@ -337,10 +370,13 @@ void AddressDecoder::print() const { uint64_t addressBits = (UINT64_C(1) << vBankBits[static_cast::size_type>(it)]); - for (auto it2 : vXor) + for (auto xorMapping : vXor) { - if (it2.first == vBankBits[static_cast::size_type>(it)]) - addressBits |= (UINT64_C(1) << it2.second); + if (xorMapping.at(0) == vBankBits[static_cast::size_type>(it)]) + { + for (auto it = xorMapping.cbegin() + 1; it != xorMapping.cend(); it++) + addressBits |= (UINT64_C(1) << *it); + } } std::cout << " Ba " << std::setw(2) << it << ": " << std::bitset<64>(addressBits) << std::endl; @@ -350,10 +386,13 @@ void AddressDecoder::print() const { uint64_t addressBits = (UINT64_C(1) << vRowBits[static_cast::size_type>(it)]); - for (auto it2 : vXor) + for (auto xorMapping : vXor) { - if (it2.first == vRowBits[static_cast::size_type>(it)]) - addressBits |= (UINT64_C(1) << it2.second); + if (xorMapping.at(0) == vRowBits[static_cast::size_type>(it)]) + { + for (auto it = xorMapping.cbegin() + 1; it != xorMapping.cend(); it++) + addressBits |= (UINT64_C(1) << *it); + } } std::cout << " Ro " << std::setw(2) << it << ": " << std::bitset<64>(addressBits) << std::endl; @@ -363,10 +402,13 @@ void AddressDecoder::print() const { uint64_t addressBits = (UINT64_C(1) << vColumnBits[static_cast::size_type>(it)]); - for (auto it2 : vXor) + for (auto xorMapping : vXor) { - if (it2.first == vColumnBits[static_cast::size_type>(it)]) - addressBits |= (UINT64_C(1) << it2.second); + if (xorMapping.at(0) == vColumnBits[static_cast::size_type>(it)]) + { + for (auto it = xorMapping.cbegin() + 1; it != xorMapping.cend(); it++) + addressBits |= (UINT64_C(1) << *it); + } } std::cout << " Co " << std::setw(2) << it << ": " << std::bitset<64>(addressBits) << std::endl; @@ -376,10 +418,13 @@ void AddressDecoder::print() const { uint64_t addressBits = (UINT64_C(1) << vByteBits[static_cast::size_type>(it)]); - for (auto it2 : vXor) + for (auto xorMapping : vXor) { - if (it2.first == vByteBits[static_cast::size_type>(it)]) - addressBits |= (UINT64_C(1) << it2.second); + if (xorMapping.at(0) == vByteBits[static_cast::size_type>(it)]) + { + for (auto it = xorMapping.cbegin() + 1; it != xorMapping.cend(); it++) + addressBits |= (UINT64_C(1) << *it); + } } std::cout << " By " << std::setw(2) << it << ": " << std::bitset<64>(addressBits) << std::endl; diff --git a/src/libdramsys/DRAMSys/simulation/AddressDecoder.h b/src/libdramsys/DRAMSys/simulation/AddressDecoder.h index 64f28140..053940da 100644 --- a/src/libdramsys/DRAMSys/simulation/AddressDecoder.h +++ b/src/libdramsys/DRAMSys/simulation/AddressDecoder.h @@ -99,7 +99,7 @@ private: // This container stores for each used xor gate a pair of address bits, the first bit is // overwritten with the result - std::vector> vXor; + std::vector> vXor; std::vector vChannelBits; std::vector vRankBits; std::vector vBankGroupBits; diff --git a/tests/tests_configuration/test_configuration.cpp b/tests/tests_configuration/test_configuration.cpp index 5620704a..7b0bb8b6 100644 --- a/tests/tests_configuration/test_configuration.cpp +++ b/tests/tests_configuration/test_configuration.cpp @@ -62,15 +62,19 @@ protected: static DRAMSys::Config::TrafficGeneratorStateMachine createTraceGeneratorMultipleStates(); static DRAMSys::Config::RowHammer createTraceHammer(); + static std::vector + addressMapBitVector(std::vector bits) + { + return {bits.begin(), bits.end()}; + }; + DRAMSys::Config::AddressMapping addressMapping{ - {{0, 1}}, - {{2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12}}, - {{16}}, - {{13, 14, 15}}, - {{17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32}}, - {{33}}, - std::nullopt, - std::nullopt, + addressMapBitVector({0, 1}), + addressMapBitVector({2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12}), + addressMapBitVector({16}), + addressMapBitVector({13, 14, 15}), + addressMapBitVector({17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32}), + addressMapBitVector({33}), std::nullopt}; DRAMSys::Config::McConfig mcConfig{PagePolicyType::Open, diff --git a/tests/tests_regression/DDR3/ddr3-example.json b/tests/tests_regression/DDR3/ddr3-example.json index 2f4f6f56..5e0fc2b9 100644 --- a/tests/tests_regression/DDR3/ddr3-example.json +++ b/tests/tests_regression/DDR3/ddr3-example.json @@ -1,14 +1,8 @@ { "simulation": { "addressmapping": { - "XOR": [ - { - "FIRST": 13, - "SECOND": 16 - } - ], "BANK_BIT": [ - 13, + [13, 16], 14, 15 ],