Verilog меняет размер правой части

Jan 14 2021

У меня есть базовый модуль, чтобы кое-что продемонстрировать.

module tb();

reg [2:0] U;
reg [2:0] T;
reg [2:0] C;
reg E;

initial begin

    U = 5;
    T = 3;
    {E, C} = U + ~T + 1'b1;
    #1000;

end

endmodule

Я ожидаю, что E будет 1, потому что;

U является 101

T является 011

и U + ~T + 001есть,

   101
   100
   001
+______
= 1010 

Итак, C получает часть 010, а E получает 1. Это ожидаемое поведение, однако я получаю C то же самое, но E как 0. Я думаю, verilog увеличивает размеры переменных RHS до 4 бит, потому что левая часть составляет 4 бита ( 1 + 3). Однако для T он добавляет начальный 0 перед дополнением T, поэтому T становится 0011, а его дополнение оказывается равным 1100 вместо 0100, 4-битная версия дополнения T.

И это приводит к

   0101
   1100
   0001
+______
= 10010 

Это приводит к тому, что E равняется 0, как видно.

Я не понимаю, почему это так, и не мог найти способ сделать дополнение до добавления ведущего нуля.

Если вместо этого я сделаю следующее, все будет нормально, и E получит 1:

    U = 5;
    T = 3;
    T = ~T;
    {E, C} = U + T + 1'b1;

Это подтверждает, что мои подозрения верны. Итак, у меня есть такое решение, да. Однако я не очень доволен этим, я думаю, что должен быть способ предотвратить такое поведение.

Любая помощь будет оценена по достоинству.

Ответы

3 dave_59 Jan 14 2021 at 05:55

Когда у вас есть операнды, состоящие из смеси разной ширины, Verilog имеет правила для определения размера каждого операнда по ширине самого большого операнда на основе контекста выражения. Вы правильно заметили, что LHS - это 4 бита, операнды на RHS расширяются до 4 бит. Это происходит перед применением операции.

Вы можете исправить это, воспользовавшись тем фактом, что операнды конкатенации являются самоопределяемыми контекстами:

{E, C} = U + {~T} + 1'b1;

Теперь ширина ~Tопределяется исключительно шириной T.