From c44932f81da4edfa68e78dd2a99a1344ae5009cc Mon Sep 17 00:00:00 2001 From: Tamas Vami Date: Thu, 20 Nov 2025 20:14:18 -0800 Subject: [PATCH 1/3] Make ECON readout batched --- include/pflib/ECON.h | 1 + src/pflib/ECON.cxx | 95 ++++++++++++++++++++++++++++++++++---------- 2 files changed, 76 insertions(+), 20 deletions(-) diff --git a/include/pflib/ECON.h b/include/pflib/ECON.h index 84e47fd61..740e9e52b 100644 --- a/include/pflib/ECON.h +++ b/include/pflib/ECON.h @@ -45,6 +45,7 @@ class ECON { const std::string& file_path); uint64_t readParameter(const std::string& page, const std::string& param, bool print_values = false); + std::map readRegisterRange(int start_addr, int end_addr); void dumpSettings(const std::string& filename, bool should_decompile); diff --git a/src/pflib/ECON.cxx b/src/pflib/ECON.cxx index c8f301b93..3a06d4059 100644 --- a/src/pflib/ECON.cxx +++ b/src/pflib/ECON.cxx @@ -15,6 +15,7 @@ ECON::ECON(I2C& i2c, uint8_t econ_base_addr, const std::string& type_version) econ_base_{econ_base_addr}, compiler_{Compiler::get(type_version)}, type_{type_version} { + i2c_.set_bus_speed(1400); econ_reg_nbytes_lut_ = compiler_.build_register_byte_lut(); pflib_log(debug) << "ECON base addr " << packing::hex(econ_base_); @@ -240,37 +241,80 @@ std::map> ECON::getRegisters( const int page_id = 0; // always page 0 std::map all_regs; + // Batch contiguous addresses + const int MAX_READ_GAP = 8; + const int MAX_BATCH_SIZE = 256; if (selected.empty()) { - // if no specific registers are requested, read all registers - // printf("[DEBUG] Selected map is empty — reading all registers.\n"); + // Build sorted list of all register addresses we need to read + std::vector addresses; for (const auto& [reg_addr, nbytes] : econ_reg_nbytes_lut_) { - std::vector values = getValues(reg_addr, nbytes); - for (int i = 0; i < values.size(); ++i) { - // printf("Read [0x%04x] = 0x%02x\n", reg_addr + i, values[i]); - all_regs[reg_addr + i] = values[i]; + for (int i = 0; i < nbytes; i++) { + addresses.push_back(reg_addr + i); } } + // sort the addresses + std::sort(addresses.begin(), addresses.end()); + // remove duplicates if any + addresses.erase(std::unique(addresses.begin(), addresses.end()), addresses.end()); + + for (size_t i = 0; i < addresses.size(); ) { + int start_addr = addresses[i]; + int end_addr = addresses[i]; + size_t j = i + 1; + + // Extend batch while addresses are close together + while (j < addresses.size() && + addresses[j] - end_addr <= MAX_READ_GAP && + addresses[j] - start_addr < MAX_BATCH_SIZE) { + end_addr = addresses[j]; + j++; + } + + // Read the batch + auto batch_result = readRegisterRange(start_addr, end_addr); + for (const auto& [addr, val] : batch_result) { + chip_reg[page_id][addr] = val; + } + // advance to next batch + i = j; + } } else { - // only read the registers in selected[0] + // Similar logic for selected registers const auto& reg_map = selected.at(page_id); - for (const auto& [reg_addr, nbytes] : econ_reg_nbytes_lut_) { - if (reg_map.find(reg_addr) != reg_map.end()) { - std::vector values = getValues(reg_addr, nbytes); - for (int i = 0; i < (int)values.size(); ++i) { - // printf("Read [0x%04x] = 0x%02x\n", reg_addr + i, values[i]); - all_regs[reg_addr + i] = values[i]; + std::vector addresses; + for (const auto& [addr, _] : reg_map) { + addresses.push_back(addr); + } + // sort the addresses + std::sort(addresses.begin(), addresses.end()); + + // Batch read the selected addresses + for (size_t i = 0; i < addresses.size(); ) { + int start_addr = addresses[i]; + int end_addr = addresses[i]; + size_t j = i + 1; + + while (j < addresses.size() && + addresses[j] - end_addr <= MAX_READ_GAP && + addresses[j] - start_addr < MAX_BATCH_SIZE) { + end_addr = addresses[j]; + j++; + } + + auto batch_result = readRegisterRange(start_addr, end_addr); + for (const auto& [addr, val] : batch_result) { + if (reg_map.find(addr) != reg_map.end()) { + chip_reg[page_id][addr] = val; } } - } - } - - for (const auto& [reg, val] : all_regs) { - chip_reg[page_id][reg] = val; - } + // advance to next batch + i = j; + } // end loop on batches + } // end else selected not empty return chip_reg; -} +} // end of ECON::getRegisters std::map> ECON::applyParameters( const std::map>& parameters) { @@ -369,6 +413,17 @@ uint64_t ECON::readParameter(const std::string& page, const std::string& param, return values[page][param]; // return the actual register value } +std::map ECON::readRegisterRange(int start_addr, int end_addr) { + int total_bytes = end_addr - start_addr + 1; + std::vector values = getValues(start_addr, total_bytes); + + std::map result; + for (int i = 0; i < total_bytes; i++) { + result[start_addr + i] = values[i]; + } + return result; +} + void ECON::dumpSettings(const std::string& filename, bool should_decompile) { if (filename.empty()) { PFEXCEPTION_RAISE("Filename", From 6df85f00f4a1a327156048ebb952bd351e3ff7ca Mon Sep 17 00:00:00 2001 From: Tamas Vami Date: Thu, 20 Nov 2025 21:13:32 -0800 Subject: [PATCH 2/3] format --- src/pflib/ECON.cxx | 31 +++++++++++++++---------------- 1 file changed, 15 insertions(+), 16 deletions(-) diff --git a/src/pflib/ECON.cxx b/src/pflib/ECON.cxx index 3a06d4059..9f3abd49a 100644 --- a/src/pflib/ECON.cxx +++ b/src/pflib/ECON.cxx @@ -256,16 +256,16 @@ std::map> ECON::getRegisters( // sort the addresses std::sort(addresses.begin(), addresses.end()); // remove duplicates if any - addresses.erase(std::unique(addresses.begin(), addresses.end()), addresses.end()); - - for (size_t i = 0; i < addresses.size(); ) { + addresses.erase(std::unique(addresses.begin(), addresses.end()), + addresses.end()); + + for (size_t i = 0; i < addresses.size();) { int start_addr = addresses[i]; int end_addr = addresses[i]; size_t j = i + 1; - + // Extend batch while addresses are close together - while (j < addresses.size() && - addresses[j] - end_addr <= MAX_READ_GAP && + while (j < addresses.size() && addresses[j] - end_addr <= MAX_READ_GAP && addresses[j] - start_addr < MAX_BATCH_SIZE) { end_addr = addresses[j]; j++; @@ -288,20 +288,19 @@ std::map> ECON::getRegisters( } // sort the addresses std::sort(addresses.begin(), addresses.end()); - + // Batch read the selected addresses - for (size_t i = 0; i < addresses.size(); ) { + for (size_t i = 0; i < addresses.size();) { int start_addr = addresses[i]; int end_addr = addresses[i]; size_t j = i + 1; - - while (j < addresses.size() && - addresses[j] - end_addr <= MAX_READ_GAP && + + while (j < addresses.size() && addresses[j] - end_addr <= MAX_READ_GAP && addresses[j] - start_addr < MAX_BATCH_SIZE) { end_addr = addresses[j]; j++; } - + auto batch_result = readRegisterRange(start_addr, end_addr); for (const auto& [addr, val] : batch_result) { if (reg_map.find(addr) != reg_map.end()) { @@ -310,11 +309,11 @@ std::map> ECON::getRegisters( } // advance to next batch i = j; - } // end loop on batches - } // end else selected not empty + } // end loop on batches + } // end else selected not empty return chip_reg; -} // end of ECON::getRegisters +} // end of ECON::getRegisters std::map> ECON::applyParameters( const std::map>& parameters) { @@ -416,7 +415,7 @@ uint64_t ECON::readParameter(const std::string& page, const std::string& param, std::map ECON::readRegisterRange(int start_addr, int end_addr) { int total_bytes = end_addr - start_addr + 1; std::vector values = getValues(start_addr, total_bytes); - + std::map result; for (int i = 0; i < total_bytes; i++) { result[start_addr + i] = values[i]; From fce53f90ae1af648e12e44e5cec47755ed3b5113 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Fri, 21 Nov 2025 05:14:42 +0000 Subject: [PATCH 3/3] Apply clang-format --style=Google --- src/pflib/bittware/bittware_axilite.cxx | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/src/pflib/bittware/bittware_axilite.cxx b/src/pflib/bittware/bittware_axilite.cxx index d3d64b32a..d6a8e33f3 100644 --- a/src/pflib/bittware/bittware_axilite.cxx +++ b/src/pflib/bittware/bittware_axilite.cxx @@ -21,7 +21,8 @@ AxiLite::AxiLite(const uint32_t base_address, const char* dev, : dev_{dev}, base_{base_address | 0x00c00000}, mask_{mask_space & 0xFFFFFFFCu}, - antimask_{0xFFFFFFFFu ^ mask_}, waswrite_{true} { + antimask_{0xFFFFFFFFu ^ mask_}, + waswrite_{true} { auto ptr = handle_map.find(dev); if (ptr != handle_map.end()) handle_ = ptr->second; @@ -49,9 +50,10 @@ uint32_t AxiLite::read(uint32_t addr) { "Address 0x%0x is invalid", addr)); } uint32_t val; - if (waswrite_) { // seem to need this double read, would be good to fix at firmware level... - dmaReadRegister(handle_, base_ | addr, &val); - waswrite_=false; + if (waswrite_) { // seem to need this double read, would be good to fix at + // firmware level... + dmaReadRegister(handle_, base_ | addr, &val); + waswrite_ = false; } dmaReadRegister(handle_, base_ | addr, &val); return val; @@ -63,7 +65,7 @@ void AxiLite::write(uint32_t addr, uint32_t val) { "Address 0x%0x is invalid", addr)); } dmaWriteRegister(handle_, base_ | addr, val); - waswrite_=true; + waswrite_ = true; } static int first_bit_set(uint32_t mask) {