Verilog mudando o tamanho do lado direito

Jan 14 2021

Eu tenho um módulo básico como se segue para demonstrar algo.

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

O que eu espero é que E seja 1, porque;

U é 101

T é 011

e U + ~T + 001é,

   101
   100
   001
+______
= 1010 

Então, C tem 010 parte e E tem 1. Este é o comportamento esperado, no entanto, eu tenho C igual, mas E como 0. Acho que verilog está aumentando o tamanho das variáveis ​​RHS para 4 bits porque o lado esquerdo tem 4 bits ( 1 + 3). No entanto, para T, ele acrescenta 0 à esquerda antes de complementar T, então T torna-se 0011 e seu complemento passa a ser 1100, em vez de 0100, versão de 4 bits do complemento T.

E isso leva a,

   0101
   1100
   0001
+______
= 10010 

O que faz com que E seja 0 conforme visto.

Não entendo por que isso acontece e não consegui encontrar uma maneira de fazer a complementação acontecer antes de adicionar um zero à esquerda.

Se eu fizer o seguinte, funcionará bem e E terá 1:

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

Isso confirma que minha suspeita está certa. Então, eu tenho essa solução, sim. No entanto, não estou muito satisfeito com isso, acho que deveria haver uma maneira de evitar esse comportamento.

Qualquer ajuda seria apreciada.

Respostas

3 dave_59 Jan 14 2021 at 05:55

Quando você tem operandos de mistura de larguras diferentes, Verilog tem regras para dimensionar cada operando para a largura do maior operando com base no contexto da expressão. Você observou corretamente que o LHS tem 4 bits, os operandos no RHS são estendidos para 4 bits. Isso acontece antes de aplicar a operação.

Você pode corrigir isso aproveitando o fato de que operandos de uma concatenação são contextos autodeterminados:

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

Agora, a largura de ~Té determinada exclusivamente pela largura de T.