10 u32 get_data_word(
const std::vector<u64>& data,
u32 address,
u32 width)
13 u32 row = start_pos >> 6;
14 u32 start_bit = start_pos & 0x3F;
16 if (row >=
data.size() || 64 % width != 0 || width > 32)
18 log_error(
"hal_simulator",
"cannot read data word of width {} at address {0:x}.", width, address);
23 return (
u32)((
data.at(row) >> start_bit) & ((1 << width) - 1));
26 void set_data_word(std::vector<u64>& data,
u32 in_data,
u32 address,
u32 width)
29 u32 row = start_pos >> 6;
30 u32 start_bit = start_pos & 0x3F;
32 if (row >=
data.size() || 64 % width != 0 || width > 32)
34 log_error(
"hal_simulator",
"cannot write data word {0:x} of width {} to address {0:x}.", in_data, width, address);
39 u64 mask = ~((((
u64)1 << width) - 1) << start_bit);
40 data.at(row) = (
data.at(row) & mask) ^ ((
u64)in_data << start_bit);
44 NetlistSimulator::SimulationGateRAM::SimulationGateRAM(
const Gate* gate) : SimulationGateSequential(gate)
46 const GateType* gate_type = gate->get_type();
47 const RAMComponent* ram_component = gate_type->get_component_as<RAMComponent>([](
const GateTypeComponent* c) {
return RAMComponent::is_class_of(c); });
48 assert(ram_component !=
nullptr);
50 m_bit_size = ram_component->get_bit_size();
52 for (
const GateTypeComponent* component : ram_component->get_components([](
const GateTypeComponent* c) { return RAMPortComponent::is_class_of(c); }))
54 const RAMPortComponent* port_component = component->convert_to<RAMPortComponent>();
57 simulation_port.clock_func = port_component->get_clock_function();
58 simulation_port.enable_func = port_component->get_enable_function();
59 simulation_port.is_write = port_component->is_write_port();
61 for (GatePin* pin : gate_type->get_pin_group_by_name(port_component->get_data_group())->get_pins())
63 simulation_port.data_pins.push_back(pin);
66 for (GatePin* pin : gate_type->get_pin_group_by_name(port_component->get_address_group())->get_pins())
68 simulation_port.address_pins.push_back(pin);
72 for (
const std::string& var : simulation_port.clock_func.get_variable_names())
74 if (
const GatePin* pin = gate_type->get_pin_by_name(var); pin !=
nullptr && pin->get_type() == PinType::clock)
76 simulation_port.clock_net = gate->get_fan_in_net(pin);
80 assert(simulation_port.clock_net !=
nullptr);
82 m_ports.push_back(simulation_port);
88 GateType* gate_type = m_gate->get_type();
90 const RAMComponent* ram_component = gate_type->get_component_as<RAMComponent>([](
const GateTypeComponent* c) {
return RAMComponent::is_class_of(c); });
91 if (ram_component ==
nullptr)
93 log_error(
"hal_simulator",
"cannot find RAM properties for RAM gate '{}' with ID {} of type '{}'.", m_gate->get_name(), m_gate->get_id(), gate_type->get_name());
99 const std::vector<std::string>& init_ids = ram_component->get_init_identifiers();
101 if (init_ids.empty())
103 log_error(
"hal_simulator",
"no initialization identifiers for RAM gate '{}' with ID {} of type '{}'.", m_gate->get_name(), m_gate->get_id(), gate_type->get_name());
107 for (
const std::string&
identifier : init_ids)
109 auto param_res = m_gate->get_parameter_value(
identifier);
110 if (param_res.is_error())
113 "could not read initialization parameter '{}' for RAM gate '{}' with ID {}: {}",
117 param_res.get_error().get());
120 const std::string& pv = param_res.get();
121 const std::string&
data = (pv.size() >= 2 && pv[0] ==
'0' && pv[1] ==
'x') ? pv.substr(2) : pv;
124 if (data_len == 0 || data_len % 16 != 0)
126 log_error(
"hal_simulator",
"initialization data for '{}' in RAM gate '{}' must be a multiple of 64 bits.",
identifier, m_gate->get_name());
130 for (
u32 i = 0; i < data_len; i += 16)
132 m_data.push_back(strtoull(
data.substr(data_len - i - 16, 16).c_str(),
nullptr, 16));
136 if (ram_component->get_bit_size() != m_data.size() * 64)
138 log_error(
"hal_simulator",
"initialization data does not fit memory size for RAM gate '{}' with ID {} of type '{}'.", m_gate->get_name(), m_gate->get_id(), gate_type->get_name());
149 case BooleanFunction::Value::ONE:
150 init_val = 0xFFFFFFFFFFFFFFFF;
152 case BooleanFunction::Value::ZERO:
155 case BooleanFunction::Value::X:
156 case BooleanFunction::Value::Z:
157 log_error(
"hal_simulator",
"RAM gate '{}' with ID {} of type {} cannot be initialized with value '{}'.", m_gate->get_name(), m_gate->get_id(), gate_type->get_name(), BooleanFunction::to_string(value));
161 assert(ram_component->get_bit_size() % 64 == 0);
162 u32 num_words = ram_component->get_bit_size() / 64;
164 for (
u32 i = 0; i < num_words; i++)
166 m_data.push_back(init_val);
171 for (
const Port& port : m_ports)
175 u32 data_size = port.data_pins.size();
176 for (
u32 j = 0; j < data_size; j++)
178 const Net* out_net = m_gate->get_fan_out_net(port.data_pins.at(j));
179 new_events[out_net] = BooleanFunction::Value::ZERO;
185 bool NetlistSimulator::SimulationGateRAM::simulate(
const Simulation& simulation,
const WaveEvent& event, std::map<std::pair<const Net*, u64>, BooleanFunction::Value>& new_events)
191 for (
size_t i = 0; i < m_ports.size(); i++)
193 Port& port = m_ports.at(i);
194 if (event.affected_net == port.clock_net && port.clock_func.evaluate(m_input_values).get() == BooleanFunction::ONE)
196 if (port.enable_func.evaluate(m_input_values).get() == BooleanFunction::Value::ONE)
200 m_clocked_write_ports.push_back(i);
204 m_clocked_read_ports.push_back(i);
210 if (!m_clocked_read_ports.empty() || !m_clocked_write_ports.empty())
219 void NetlistSimulator::SimulationGateRAM::clock(
const u64 current_time, std::map<std::pair<const Net*, u64>, BooleanFunction::Value>& new_events)
224 std::unordered_map<std::string, BooleanFunction> functions = m_gate->get_boolean_functions();
226 for (
size_t index : m_clocked_read_ports)
228 Port port = m_ports.at(
index);
230 std::vector<BooleanFunction::Value> address_values;
231 for (
const GatePin* pin : port.address_pins)
233 address_values.push_back(m_input_values.at(pin->get_name()));
237 u32 data_size = port.data_pins.size();
240 u32 read_data = get_data_word(m_data, address, data_size);
243 assert(data_values.size() == data_size);
246 for (
u32 i = 0; i < data_size; i++)
248 const Net* out_net = m_gate->get_fan_out_net(port.data_pins.at(i));
249 new_events[std::make_pair(out_net, current_time + delay)] = data_values.at(i);
253 for (
size_t index : m_clocked_write_ports)
255 Port port = m_ports.at(
index);
257 u32 data_size = port.data_pins.size();
262 for (
u32 i = 0; i < data_size; i++)
264 const GatePin* pin = port.data_pins.at(i);
267 if (
auto func_it = functions.find(pin->get_name()); func_it != functions.end() && func_it->second.evaluate(m_input_values).get() != BooleanFunction::Value::ONE)
272 data_values[i] = m_input_values.at(pin->get_name());
275 set_data_word(m_data, write_data, address, data_size);
278 m_clocked_read_ports.clear();
279 m_clocked_write_ports.clear();
#define log_error(channel,...)
u32 get_int_bus_value(const std::unordered_map< std::string, BooleanFunction::Value > &signal_values, const std::vector< GatePin * > &ordered_pins)
std::vector< BooleanFunction::Value > int_to_values(u32 integer, u32 len)
u32 values_to_int(const std::vector< BooleanFunction::Value > &values)