Verilog - путаница между || и + оператор

В булевой алгебре сложение терминов соответствует вентилю ИЛИ, а умножение соответствует вентилю И.

Предположим, мне нужен вентилятор термостата, который работает следующим образом:

Вентилятор должен включаться при включении обогревателя или кондиционера. В качестве альтернативы, если пользователь запрашивает включение вентилятора (включив вход fan_on), вентилятор должен включиться, даже если обогреватель или кондиционер выключены.

Основываясь на этих требованиях, я сформулировал логическое утверждение в коде Verilog следующим образом:

assign blower_fan = fan_on + heater + aircon;

Однако при моделировании это дает неверное решение. Однако это работает:

assign blower_fan = fan_on || (heater + aircon);

так же как и

assign blower_fan = fan_on || (heater || aircon);

Мой вопрос:

Что я неправильно понимаю в операторе +? Кроме того, я запутался между двумя последними решениями, которые ДЕЙСТВИТЕЛЬНО работают - почему оба они работают, и является ли последнее, где я использую только логический оператор ИЛИ более правильным (или предпочтительным) способом делать то, что я хочу сделать?

Редактировать № 1: вот весь модуль, где я объявил входы и выходы

module top_module (
    input too_cold,
    input too_hot,
    input mode,
    input fan_on,
    output heater,
    output aircon,
    output fan
); 

    assign heater = (mode&&too_cold);
    assign aircon = (!mode&&too_hot);
    assign fan = (fan_on) || (heater || aircon);

endmodule

person cloudy_eclispse    schedule 07.06.2017    source источник
comment
В задаче можно с уверенностью предположить, что и a, и h не будут равны 1 одновременно. Вот почему это не было тестовым случаем. Но второй комментарий ginginsha был очень полезен, так как объяснял, почему эта попытка оказалась правильной, хотя и ошибочной. Моя ошибка заключалась в том, что я перепутал логическую арифметику с оператором «+», который в Verilog используется как арифметический оператор! Ну ой.   -  person cloudy_eclispse    schedule 07.06.2017


Ответы (2)


Логическое выражение для ИЛИ и И равно || и && соответственно.

Символ + на самом деле является арифметическим выражением

a = 2'b01 // 1
b = 2'b01 // 1
a + b = 2'b10 // 1 + 1 = 2
a || b = 2'b01 // 1 OR 1 = 1

Источник: https://www.utdallas.edu/~akshay.sridharan/index_files/Page5212.htm

РЕДАКТИРОВАТЬ:

Два следующих утверждения логически эквивалентны

assign fan = (fan_on) || (heater || aircon);
assign fan = fan_on || heater || aircon;

Проблема с

assign blower_fan = fan_on + heater + aircon;

заключается в том, что если два входа имеют высокий уровень (например, обогреватель = 1, кондиционер = 1, fan_on = 0), то blower_fan (который считается равным 1 биту) переполняется и, следовательно, будет равен 0 (1'b1 + 1'b1 = 1'b0).

person ginginsha    schedule 07.06.2017
comment
Гм, в источнике, который вы мне дали, говорится, что || и && являются логическими операторами, что мне и нужно, верно? Вместо побитовых операторов? - person cloudy_eclispse; 07.06.2017
comment
Верно, извините за это. Логическое ИЛИ оценивается как истинное, если ни один из операндов не равен 0. Проблема может заключаться в том, что в случае assign blower_fan = fan_on + обогреватель + кондиционер; происходит переполнение для blower_fan. - person ginginsha; 07.06.2017
comment
Это имеет смысл! И помогает мне понять, почему второй оказался правильным тестовым решением, хотя логика неверна. Спасибо :) - person cloudy_eclispse; 07.06.2017

Оператор Verilog + не является оператором ИЛИ, это оператор сложения. В Verilog есть два оператора ИЛИ:

|   bitwise OR 
||  logical OR

Для векторов побитовая операция обрабатывает отдельные биты векторных операндов отдельно. Напротив, с логическими операторами скаляр или вектор считаются ИСТИННЫМИ, если они содержат хотя бы одну единицу, и ЛОЖНЫМИ, когда каждый бит равен 0. Xs и Z считаются неизвестными (ни TRUE, ни ЛОЖЬ).

Вы также можете использовать оператор | в качестве оператора сокращения.

Например:

Expression           Result    Comment
=========================================
   1'b0 |  1'b0      1'b0      bitwise OR
   1'b0 |  1'b1      1'b1      bitwise OR
   1'b1 |  1'b0      1'b1      bitwise OR
   1'b1 |  1'b1      1'b1      bitwise OR

4'b0101 |  4'b1100   4'b1101   bitwise OR

4'b0000 || 4'b0000   1'b0      logical OR
4'b0000 || 4'b1100   1'b1      logical OR
4'b0101 || 4'b0000   1'b1      logical OR
4'b0101 || 4'b1100   1'b1      logical OR

| 4'b0000            1'b0      reduction
| 4'b0101            1'b1      reduction
| 4'b1111            1'b1      reduction

Если вы используете оператор + вместо оператора | и присваиваете однобитовое значение, вы эффективно используете исключающее ИЛИ вместо ИЛИ. Сравните эти таблицы истинности:

            OR     XOR    +
A    B      F      F      F   
==============================
1'b0 1'b0   1'b0   1'b0   1'b0
1'b0 1'b1   1'b1   1'b1   1'b1
1'b1 1'b0   1'b1   1'b1   1'b1
1'b1 1'b1   1'b1   1'b0   1'b0

Это выражение:

assign blower_fan = fan_on || (heater + aircon);

потерпит неудачу, когда fan_on будет 1'b0, а heater и aircon будут 1'b1, тогда как этот не будет:

assign blower_fan = fan_on | heater | aircon;
person Matthew Taylor    schedule 07.06.2017