8 NetlistSimulator::SimulationGateFF::SimulationGateFF(
const Gate* gate) : SimulationGateSequential(gate)
10 const GateType* gate_type = gate->get_type();
11 const FFComponent* ff_component = gate_type->get_component_as<FFComponent>([](
const GateTypeComponent* c) {
return FFComponent::is_class_of(c); });
12 assert(ff_component !=
nullptr);
13 m_clock_func = ff_component->get_clock_function();
14 m_next_state_func = ff_component->get_next_state_function();
15 m_preset_func = ff_component->get_async_set_function();
16 m_clear_func = ff_component->get_async_reset_function();
17 for (
const GatePin* pin : gate_type->get_pins())
19 switch (pin->get_type())
22 if (
const Net*
net = gate->get_fan_out_net(pin);
net !=
nullptr)
24 m_state_output_nets.push_back(gate->get_fan_out_net(pin));
27 case PinType::neg_state:
28 if (
const Net*
net = gate->get_fan_out_net(pin);
net !=
nullptr)
30 m_state_inverted_output_nets.push_back(gate->get_fan_out_net(pin));
34 m_clock_nets.push_back(gate->get_fan_in_net(pin));
41 auto behavior = ff_component->get_async_set_reset_behavior();
42 m_sr_behavior_out = behavior.first;
43 m_sr_behavior_out_inverted = behavior.second;
48 GateType* gate_type = m_gate->get_type();
55 const InitComponent* init_component = gate_type->get_component_as<InitComponent>([](
const GateTypeComponent* c) {
return InitComponent::is_class_of(c); });
56 if (init_component ==
nullptr)
58 log_error(
"hal_simulator",
"cannot find initialization data for flip-flop '{}' with ID {} of type '{}'.", m_gate->get_name(), m_gate->get_id(), gate_type->get_name());
61 const std::string& init_str = std::get<1>(m_gate->get_data(init_component->get_init_category(), init_component->get_init_identifiers().front()));
63 if (!init_str.empty())
66 value = BooleanFunction::Value::X;
69 value = BooleanFunction::Value::ONE;
71 else if (init_str ==
"0")
73 value = BooleanFunction::Value::ZERO;
77 log_error(
"hal_simulator",
"init value of flip-flop '{}' with ID {} of type '{}' is neither '1' or '0'.", m_gate->get_name(), m_gate->get_id(), gate_type->get_name());
85 for (Endpoint* ep : m_gate->get_fan_out_endpoints())
87 if (ep->get_pin()->get_type() == PinType::state)
89 new_events[ep->get_net()] = value;
91 else if (ep->get_pin()->get_type() == PinType::neg_state)
93 new_events[ep->get_net()] = inv_value;
98 bool NetlistSimulator::SimulationGateFF::simulate(
const Simulation& simulation,
const WaveEvent& event, std::map<std::pair<const Net*, u64>, BooleanFunction::Value>& new_events)
103 auto async_set = m_preset_func.evaluate(m_input_values).get();
104 auto async_reset = m_clear_func.evaluate(m_input_values).get();
107 if (async_set == BooleanFunction::ONE || async_reset == BooleanFunction::ONE)
109 BooleanFunction::Value result = BooleanFunction::Value::X;
110 BooleanFunction::Value inv_result = BooleanFunction::Value::X;
112 if (async_set == BooleanFunction::ONE && async_reset == BooleanFunction::ONE)
115 BooleanFunction::Value old_output = BooleanFunction::Value::X;
116 if (!m_state_output_nets.empty())
118 const Net* out_net = m_state_output_nets[0];
119 if (
auto it = simulation.m_events.find(out_net); it != simulation.m_events.end())
121 old_output = it->second.back().new_value;
124 BooleanFunction::Value old_output_inv = BooleanFunction::Value::X;
125 if (!m_state_inverted_output_nets.empty())
127 auto out_net = m_state_inverted_output_nets[0];
128 if (
auto it = simulation.m_events.find(out_net); it != simulation.m_events.end())
130 old_output_inv = it->second.back().new_value;
136 else if (async_set == BooleanFunction::ONE)
139 result = BooleanFunction::Value::ONE;
142 else if (async_reset == BooleanFunction::ONE)
145 result = BooleanFunction::Value::ZERO;
150 for (
auto out_net : m_state_output_nets)
152 new_events[std::make_pair(out_net, event.time + delay)] = result;
154 for (
auto out_net : m_state_inverted_output_nets)
156 new_events[std::make_pair(out_net, event.time + delay)] = inv_result;
161 else if (std::find(m_clock_nets.begin(), m_clock_nets.end(), event.affected_net) != m_clock_nets.end())
164 return (m_clock_func.evaluate(m_input_values).get() != BooleanFunction::ONE);
170 void NetlistSimulator::SimulationGateFF::clock(
const u64 current_time, std::map<std::pair<const Net*, u64>, BooleanFunction::Value>& new_events)
176 BooleanFunction::Value result = m_next_state_func.evaluate(m_input_values).get();
180 for (
const Net* out_net : m_state_output_nets)
182 new_events[std::make_pair(out_net, current_time + delay)] = result;
184 for (
const Net* out_net : m_state_inverted_output_nets)
186 new_events[std::make_pair(out_net, current_time + delay)] = inv_result;
#define log_error(channel,...)
BooleanFunction::Value toggle(BooleanFunction::Value v)
BooleanFunction::Value process_clear_preset_behavior(AsyncSetResetBehavior behavior, BooleanFunction::Value previous_output)