В чем разница между Verilog! и ~?
Итак, это закончилось тем, что ошибка, которая удерживала меня в течение нескольких дней, была частью кода, который должен был быть оценен как False, оценивая True. Мой исходный код выглядел примерно так:
if(~x && ~y) begin
//do stuff
end
то есть. Если x НЕ ОДИН, а y НЕ ОДИН, тогда делайте что-нибудь. Пройдя через отладчик, я понял, что хотя x равно 1, выражение в if-statement все еще приводило к TRUE, и последующий код выполнялся.
Однако, когда я сменил оператор на:
if(x == 0 && y == 0) begin
//do stuff
end
а также попытался:
if(!x && !y) begin
//do stuff
end
код внутри оператора if не был оценен, что было ожидаемым поведением. Я понимаю, что ~ - поразрядное отрицание и! логическое отрицание, но не должно (~ x & ~ y) и (! x & &! y) оценивать одно и то же? Я боюсь, что кодовая база слишком велика, поэтому я не могу вставить ее здесь, но это было единственное изменение, которое я сделал, чтобы заставить код работать так, как я предполагал. Спасибо.
В ответ на один из комментариев ниже я создал тестовый пример для проверки этого поведения:
`timescale 10ns/1ns
модуль test_negation();
integer x, y;
initial begin
x = 1; y = 0;
if(~x && ~y) begin
$display("%s", "First case executed");
end
if(!x && !y) begin
$display("%s", "Second case executed");
end
if(x == 0 && y == 0) begin
$display("%s", "Third case executed");
end
end endmodule
И как ни странно, "первый случай выполнен" печатается, чтобы подтвердить первоначальное поведение, которое я наблюдал.
Ответы
Ответ 1
Символ !
представляет логическое или логическое отрицание. Для любого значения x
, отличного от нуля, !x
оценивается как ноль или ложь, а когда x
равно нулю, !x
оценивается как один или истинный.
Символ ~
представляет побитовое отрицание. Каждый бит в значении переключается, поэтому для 16-разрядного x == 0xA5A5
, ~x
будет оцениваться до 0x5A5A
.
Условие if()
ожидает выражения, которое вычисляется как true или false, где любое ненулевое (положительное или отрицательное) значение true, а ноль - false.
&&
является логическим И. Он принимает два выражения, оценивая один или истинный, если и только если оба выражения истинны. Опять же, "истина" здесь означает ненулевой, положительный или отрицательный.
Учитывая все это, мы можем видеть, что единственное время ~x
и !x
оценивается с тем же значением, когда x == -1
или, если x
без знака, когда x == MAX_UNSIGNED
.
Ответ 2
Я вижу. Переменная "x" в приведенном выше коде была целым числом Verilog (integer x;
). Однако целочисленная переменная представлена Verilog как 32-разрядное целое число. Поэтому, хотя x был "1", как я заметил, ~ x не приведет к "0", а в "11111111111111111111111111111110"! И поэтому неудивительно, что первый случай был выполнен. Моя вина. Спасибо за все ответы.
Ответ 3
~
- бит-мудрый оператор и возвращает инвертирование аргумента.
!
является логическим оператором и возвращает один бит.
Пример:
reg [7:0] bit_wise, logic_op;
initial begin
bit_wise = ~8'hA1; // bit_wise == 8'h6E
logic_op = !8'hA1; // logic_op == 8'b00
$display("bit_wise:%h logic_op:%h", bit_wise, logic_op); // bit_wise:5e logic_op:00
end
В вашем примере:
if(~x && ~y) begin
//do stuff
end
Фактически это то же самое, что:
if(x!='1 && y!='1) begin // '1 means the with of x all 1s and the with of y all 1s
//do stuff
end
Как правило, лучшим стилем кодирования является использование логических операторов внутри операторов if. Используйте только битовые операторы с манипуляциями с присваиванием данных.