Verilog cambiando el tamaño del lado derecho

Jan 14 2021

Tengo un módulo básico como sigue para demostrar 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

Lo que espero es que E sea 1, porque;

U es 101

T es 011

y U + ~T + 001es,

   101
   100
   001
+______
= 1010 

Entonces, C obtiene 010 parte y E obtiene 1. Este es el comportamiento esperado, sin embargo, obtengo C igual pero E como 0. Creo que verilog está aumentando el tamaño de las variables RHS a 4 bits porque el lado izquierdo es de 4 bits ( 1 + 3). Sin embargo, para T, agrega 0 inicial antes de complementar T, por lo que T se convierte en 0011 y su complemento resulta ser 1100, en lugar de 0100, versión de 4 bits del complemento T.

Y esto lleva a

   0101
   1100
   0001
+______
= 10010 

Lo que hace que E sea 0 como se ve.

No entiendo por qué es así, y no pude encontrar una manera de hacer que ocurra la complementación antes de agregar un cero a la izquierda.

Si hago lo siguiente en su lugar, funciona bien y E obtiene 1:

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

Esto confirma que mi sospecha es correcta. Entonces, tengo esa solución, sí. Sin embargo, no estoy realmente satisfecho con eso, creo que debería haber una forma de prevenir ese comportamiento.

Cualquier ayuda sería apreciada.

Respuestas

3 dave_59 Jan 14 2021 at 05:55

Cuando tiene operandos de mezcla de diferentes anchos, Verilog tiene reglas para dimensionar cada operando al ancho del operando más grande según el contexto de la expresión. Observó correctamente que el LHS es de 4 bits, los operandos en el RHS se extienden a 4 bits. Esto sucede antes de aplicar la operación.

Puede solucionar este problema aprovechando el hecho de que los operandos de una concatenación son contextos autodeterminados:

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

Ahora el ancho de ~Testá determinado únicamente por el ancho de T.