blob: 0ad55ec9d5a0bd2947856f238d9ac80befb6699d [file] [log] [blame]
// Copyright 2025 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include "hw_sim/hw_primitives.h"
Clock::Observer::Observer(Clock* clock)
: clock_(clock) {
clock_->AddObserver(this);
}
Clock::Observer::~Observer() {
clock_->RemoveObserver(this);
}
void Clock::Step() {
context_->timeInc(1);
(*clock_) = 1;
Eval();
for (auto& observer : observers_) {
observer->OnRisingEdge();
Eval();
}
context_->timeInc(1);
(*clock_) = 0;
Eval();
for (auto& observer : observers_) {
observer->OnFallingEdge();
Eval();
}
}
void Clock::Eval() {
eval_function_();
}
void Clock::AddObserver(Observer* observer) {
observers_.push_back(observer);
}
void Clock::RemoveObserver(Observer* observer) {
auto it = std::find(observers_.begin(), observers_.end(), observer);
if (it != observers_.end()) {
observers_.erase(it);
}
}
// static
AxiAddr AxiAddr::FromIdAddrSize(int id, uint32_t addr, uint32_t byte_length) {
uint32_t start_addr = addr;
uint32_t end_addr = addr + byte_length - 1;
uint32_t start_line = start_addr / 16;
uint32_t end_line = end_addr / 16;
uint32_t beats = (end_line - start_line) + 1;
uint32_t size = std::ceil(std::log2(byte_length));
size = std::min(size, 4u);
AxiAddr axi_addr;
axi_addr.addr_bits_addr = addr;
axi_addr.addr_bits_prot = 0;
axi_addr.addr_bits_id = id;
axi_addr.addr_bits_len = beats - 1;
axi_addr.addr_bits_size = size;
axi_addr.addr_bits_burst = 1; // INCR
axi_addr.addr_bits_lock = 0;
axi_addr.addr_bits_cache = 0;
axi_addr.addr_bits_qos = 0;
axi_addr.addr_bits_region = 0;
return axi_addr;
}