C ++ Моделирование цифровой логики, реализация дружественных бинарных операторов

Я работаю над экспериментом по моделированию цифровой логики. (Логические ворота.)

У меня есть абстрактный базовый класс component из которого класс andgate наследует. Класс port также наследует от component, Учебный класс port имеет члена; PORTSTATE state,

PORTSTATE является классом enum, со значениями, включающими HIGH, LOW, HIGH_IMPEDANCE, UNDEFINEDи т. д. (Это просто справочная информация.)

Симуляция работает путем изменения состояния входного порта на некоторый логический вентиль. Ворота связаны (используя указатели) с классом Net который в свою очередь имеет указатели на всю подключенную логику в этой сети. Это позволяет изменять все ворота ниже по потоку от одного, который изменил свое состояние, как требуется. Рассмотрим состояние логического элемента, изменяющегося из-за изменения на входе, при использовании сети, к которой подключен его выход, любые шлюзы, расположенные дальше по последовательности, могут быть соответствующим образом обновлены.

Мой вопрос о том, как этот процесс должен быть выполнен с использованием дружественных функций и бинарных операторов, таких как operator&,

Рассмотрим вентиль And с 1 выходным портом и 2 входными портами. Порты являются членами класса, представляющего ворота, и к ним прикреплена некоторая информация, такая как их направление, а также их состояние.

Вызывается функция для вычисления выхода гейта из входов. Эта функция является функцией-членом класса gate. Например, у шлюза And есть версия этой функции.

Изначально я реализовал функцию следующим образом.

void Update()
{
this->output_port.SetState(this->input_port_a & this->input_port_b);
}

Важность в том, что operator& вызывается с аргументами 2 входных вентилей; input_port_a а также input_port_b в качестве аргументов.

В классе порта я тогда реализовал этот оператор.

friend const port& operator&(const port& left, const port& right)
{
if((left.state == PORTSTATE::HIGH) && (right.state == PORTSTATE::HIGH))
{
return PORTSTATE::HIGH;
}
else if( // These are the 3 options for definitive low
((left.portstate == PORTSTATE::LOW) && (right.portstate == PORTSTATE::HIGH))
|| ((left.portstate == PORTSTATE::LOW) && (right.portstate == PORTSTATE::LOW))
|| ((left.portstate == PORTSTATE::HIGH) && (right.portstate == PORTSTATE::LOW))
)
{
return PORTSTATE::LOW;
}
else
{
return PORTSTATE::UNDEFINED; // Anything else is not defined
}
}

Но у меня есть серьезные проблемы с этим. Вы не можете «И» 2 порта вместе. Порт — это абстрактное понятие, метод отслеживания того, какой ток течет (или, что то же самое, какое напряжение подается) на какие входы или выходы. Более физическая интерпретация состоит в том, что порт представляет собой короткий отрезок провода, через который проходит некоторый ток. Ток либо «ВЫСОКИЙ», либо «НИЗКИЙ», но, конечно, нет способа «И» соединить эти 2 объекта. Я думаю, что большинство инженеров и физиков, вероятно, смотрят на этот кусок кода в ужасе из-за этого.

Таким образом, «очевидное» решение состоит в том, чтобы разместить operator& внутри ворот А как дружественная функция.

Однако те, кто не спит, поймут, что это тоже плохая * идея, потому что тогда было бы возможно только & 2 экземпляра И ворот вместе, и это, конечно, не имеет смысла, и при этом он не вычисляет правильный результат! (Может ли это даже вычислить разумный результат? Маловероятно.)

*(совершенно неправильно)

Рассматривать;

andgate and_gate_1, and_gate_2;
// Setup the inputs, outputs, connections, networks
// When stepping through the simulation, we end up with something like this:
and_gate_1.Update();

// Which calls a function like this:
const andgate& operator&(const andgate& left, const andgate& right)
{
// How would you even implement this? It makes no sense...
}

Так что да, это проблема, и я не могу придумать решение. Хотя в некотором смысле это концептуально, идея использовать первый подход и иметь возможность «И» соединить два кусочка проволоки кажется серьезной ошибкой.

Единственное, о чем я могу думать, это обойтись без операторов и программировать все вручную внутри шлюзов And. Update() функция … Но этот тип избегает хороших вещей в C ++, которые заключаются в том, что вы можете писать операторы для таких вещей.

Обратите внимание, что если бы не было такой вещи, как PORTSTATE и если в замен bool не было бы проблемы, так как 2 типа логики могут быть просто &‘вместе Однако это изменит Update() что-то вроде этого, что тоже не очень приятно. (Обратите внимание, что членский доступ открыт

void Update()
{

return (input_a.state) & (input)b.state); // input_* is of type port, state is a bool
}

Возможно, лучше защитить данные: (но, может быть, «выглядит» хуже из-за вызова функции?)

void Update()
{

return (input_a.state()) & (input)b.state()); // input_* is of type port
// state() is a member function returning a bool
}

Это также вводит проблему только двух существующих состояний. Нет ничего, что могло бы обрабатывать неопределенные состояния или состояния с высоким импедансом и т. Д.

Так что я застрял и вне идей.

0

Решение

Перегрузить operator& для двоих PORTSTATE, Устраняя проблему с UNDEFINED это заставит вашу последнюю форму работать.

PORTSTATE operator&(const PORTSTATE& a, const PORTSTATE& b)
{
...
}

void Update()
{
return input_a.state() & input_b.state(); // input_* is of type port
// state() is a member function returning a bool
}

Для меня это самый правильный путь, потому что операция AND работает только с состояниями.

Вызов функции-члена не сбивает с толку и широко используется. Во-первых, это делает явным то, что порт имеет состояние, в котором вы находитесь (и это более логично). Во-вторых, это защищает state поле от внешней модификации.

1

Другие решения


По вопросам рекламы [email protected]