
inalhdl.spinalhdl-sim_2.13.1.11.0.source-code.SharedMemIface.cpp Maven / Gradle / Ivy
#include"SharedMemIface.hpp"
#include
#include
#include
#include
#include
#include
SharedMemIface::SharedMemIface(const string& shmem_name_, size_t shmem_size_) :
closed(false), shmem_name(shmem_name_), shmem_size(shmem_size_), ret_code(0),
data_buffer(), error_string() {
shared_memory_object::remove(shmem_name.c_str());
segment = managed_shared_memory(create_only, shmem_name.c_str(), shmem_size);
const ShmemAllocator alloc_inst(segment.get_segment_manager());
shared_struct = segment.construct("SharedStruct")(alloc_inst);
shared_struct->proc_status.store(ProcStatus::init);
}
string SharedMemIface::print_signals(){
this->check_ready();
std::string ret;
shared_struct->proc_status.store(ProcStatus::print_signals);
this->check_ready();
ret = (const char*)shared_struct->data.data();
return ret;
}
int64_t SharedMemIface::get_signal_handle(const string& handle_name){
this->check_ready();
shared_struct->data.resize(handle_name.size());
std::copy(handle_name.begin(), handle_name.end(), shared_struct->data.begin());
shared_struct->data.push_back(0);
shared_struct->proc_status.store(ProcStatus::get_signal_handle);
this->check_ready();
return shared_struct->handle;
}
void SharedMemIface::read_raw(int64_t handle, std::vector& data_, bool is_mem){
this->check_ready();
shared_struct->handle.store(handle);
if(is_mem) {
shared_struct->index.store(this->index);
shared_struct->proc_status.store(ProcStatus::read_mem);
} else {
shared_struct->proc_status.store(ProcStatus::read);
}
this->check_ready();
data_.resize(shared_struct->data.size());
std::copy(shared_struct->data.begin(), shared_struct->data.end(), data_.begin());
}
void SharedMemIface::read(int64_t handle, std::vector& data_){
read_raw(handle, data_, false);
}
void SharedMemIface::read_mem(int64_t handle, std::vector& data_, int64_t index_){
this->index = index_;
read_raw(handle, data_, true);
}
std::vector SharedMemIface::read(int64_t handle){
this->read(handle, data_buffer);
return this->data_buffer;
}
std::vector SharedMemIface::read_mem(int64_t handle, int64_t index_){
this->read_mem(handle, data_buffer, index_);
return this->data_buffer;
}
int64_t SharedMemIface::read64_raw(int64_t handle, bool is_mem){
int64_t ret = 0;
this->read_raw(handle, this->data_buffer, is_mem);
size_t copy_size = std::min((size_t)8, this->data_buffer.size());
size_t start_orig = this->data_buffer.size()-1;
for(uint8_t i = 0; i < copy_size; i++) {
((int8_t*) &ret)[i] = this->data_buffer[start_orig - i];
}
return ret;
}
int64_t SharedMemIface::read64(int64_t handle){
return read64_raw(handle, false);
}
int64_t SharedMemIface::read64_mem(int64_t handle, int64_t index_){
this->index = index_;
return read64_raw(handle, true);
}
int32_t SharedMemIface::read32_raw(int64_t handle, bool is_mem){
int32_t ret = 0;
this->read_raw(handle, this->data_buffer, is_mem);
size_t copy_size = std::min((size_t)4, this->data_buffer.size());
size_t start_orig = this->data_buffer.size()-1;
for(uint8_t i = 0; i < copy_size; i++) {
((int8_t*) &ret)[i] = this->data_buffer[start_orig - i];
}
return ret;
}
int32_t SharedMemIface::read32(int64_t handle){
return read32_raw(handle, false);
}
int32_t SharedMemIface::read32_mem(int64_t handle, int64_t index_){
this->index = index_;
return read32_raw(handle, true);
}
void SharedMemIface::write_raw(int64_t handle, const std::vector& data_, bool is_mem){
this->check_ready();
shared_struct->handle.store(handle);
shared_struct->data.resize(data_.size());
std::copy(data_.begin(), data_.end(), shared_struct->data.begin());
if(is_mem) {
shared_struct->index.store(this->index);
shared_struct->proc_status.store(ProcStatus::write_mem);
} else {
shared_struct->proc_status.store(ProcStatus::write);
}
}
void SharedMemIface::write(int64_t handle, const std::vector& data_){
write_raw(handle, data_, false);
}
void SharedMemIface::write_mem(int64_t handle, const std::vector& data_, int64_t index_){
this->index = index_;
write_raw(handle, data_, true);
}
void SharedMemIface::write64_raw(int64_t handle, int64_t data_, bool is_mem){
this->data_buffer.resize(8);
for(uint8_t i = 0; i < 8; i++) this->data_buffer[7-i] = (data_ >> 8*i) & 0xFF;
write_raw(handle, this->data_buffer, is_mem);
}
void SharedMemIface::write64(int64_t handle, int64_t data_){
write64_raw(handle, data_, false);
}
void SharedMemIface::write64_mem(int64_t handle, int64_t data_, int64_t index_){
this->index = index_;
write64_raw(handle, data_, true);
}
void SharedMemIface::write32_raw(int64_t handle, int32_t data_, bool is_mem){
this->data_buffer.resize(4);
for(uint8_t i = 0; i < 4; i++) this->data_buffer[3-i] = (data_ >> 8*i) & 0xFF;
write_raw(handle, this->data_buffer, is_mem);
}
void SharedMemIface::write32(int64_t handle, int32_t data_){
write32_raw(handle, data_, false);
}
void SharedMemIface::write32_mem(int64_t handle, int32_t data_, int64_t index_){
this->index = index_;
write32_raw(handle, data_, true);
}
int32_t SharedMemIface::get_time_precision() {
this->check_ready();
return shared_struct->time_precision;
}
void SharedMemIface::sleep(int64_t sleep_cycles){
this->check_ready();
shared_struct->sleep_cycles.store(sleep_cycles);
shared_struct->proc_status.store(ProcStatus::sleep);
}
void SharedMemIface::eval(){
this->sleep(0);
}
void SharedMemIface::set_seed(int64_t seed){
this->check_ready();
shared_struct->seed.store(seed);
shared_struct->proc_status.store(ProcStatus::set_seed);
this->check_ready();
}
void SharedMemIface::randomize(int64_t seed){
this->check_ready();
shared_struct->seed.store(seed);
shared_struct->proc_status.store(ProcStatus::randomize);
this->check_ready();
}
void SharedMemIface::close(){
this->check_ready();
shared_struct->proc_status.store(ProcStatus::close);
this->closed = true;
segment.destroy("SharedStruct");
shared_memory_object::remove(shmem_name.c_str());
}
SharedMemIface::~SharedMemIface(){}
void SharedMemIface::check_ready(){
if(this->closed) throw VpiException("Attempt to access an already closed simulation");
ProcStatus status = shared_struct->proc_status.load();
#ifndef NO_SPINLOCK_YIELD_OPTIMIZATION
for(uint32_t spin_count = 0; status != ProcStatus::ready; ++spin_count) {
#else
while(status != ProcStatus::ready) {
#endif
if (status == ProcStatus::error) {
this->closed = true;
error_string = (const char*) shared_struct->data.data();
segment.destroy("SharedStruct");
shared_memory_object::remove(shmem_name.c_str());
throw VpiException(error_string.c_str());
}
if (status == ProcStatus::closed) {
this->closed = true;
segment.destroy("SharedStruct");
shared_memory_object::remove(shmem_name.c_str());
throw VpiException("Unexpected closed simulation");
}
int64_t retcode = this->ret_code.load(std::memory_order_relaxed);
if(retcode) {
this->closed = true;
error_string = "Simulation crashed with return status ";
error_string += to_string(retcode);
segment.destroy("SharedStruct");
shared_memory_object::remove(shmem_name.c_str());
throw VpiException(error_string.c_str());
}
#ifndef NO_SPINLOCK_YIELD_OPTIMIZATION
if (spin_count < SPINLOCK_MAX_ACQUIRE_SPINS) {
_spin_pause();
} else {
std::this_thread::yield();
spin_count = 0;
}
#endif
status = shared_struct->proc_status.load();
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy