resultado incorrecto de la operación en la aritmética de desplazamiento a la derecha en verilog

1

Si simplemente escribo el siguiente código:

module TOP;

wire [31:0] a = 32'b11111111_11111111_11000000_00000000;
wire [31:0] b = 32'b00000000_00000000_00010000_00011111;

wire [4:0] shamt;
assign shamt = b[4:0];

wire signed [31:0] signed_a;
assign signed_a = a;

wire [31:0] output;
assign output = signed_a >>> b;

Esto da un resultado correcto que es 11111111_11111111_11111111_11111111

Sin embargo, si uso código que usa el módulo, siempre genera un resultado incorrecto:

module TOP;

reg [31:0] a = 32'b11111111_11111111_11000000_00000000;
reg [31:0] b = 32'b00000000_00000000_00010000_00011111;

wire [31:0] out;

ALU alu(
    .A(a),
    .B(b),
    .C(out)
);

initial
begin
    #10 $display("out: %b\n", out);
    #10 $display("outout: %b\n", alu.outout);
    #10 $display("C: %b\n", alu.C);
end

endmodule

module ALU (
    input [31:0] A,
    input [31:0] B,
    output [31:0] C
);

wire signed [31:0] outout;

wire [31:0] signed_a;
assign signed_a = A;

wire [4:0] shamt;
assign shamt = B[4:0];

assign outout = signed_a >>> shamt;

assign C = outout;

endmodule

En el código anterior, todos los resultados de $ display muestran un valor incorrecto que es

00000000_00000000_00000000_00000001.

¿Por qué no genera un valor correcto como el primer código?

    
pregunta sungjun cho

2 respuestas

0

Debe definir signed_a como firmado en el módulo ALU:

wire [31:0] signed_a;

debería ser

wire signed [31:0] signed_a;
    
respondido por el alex.forencich
1

Su problema se reduce a simples errores tipográficos.

En tu segundo código tienes lugares donde usas singed_a , y otros donde usas signed_a . Si verifica las advertencias de su compilador, en realidad le dirá esto.

Básicamente, su código ignora la entrada A porque lo está asignando a una variable inexistente.

En segundo lugar, su segundo código utiliza un cambio de bit ( >> ), no un cambio aritmético ( >>> ), por lo que no realizará la extensión de signo (ver más abajo).

El resultado que tu segundo módulo calcula es exactamente el resultado correcto para el hardware que has descrito.

>> es el operador de desplazamiento de bits, que realiza el llenado a cero. No importa si el número está firmado o sin firmar, cambiará en ceros a los MSB.

El operador >>> por otro lado es un cambio aritmético. Este realizará una extensión de signo, cambiando el MSB del número original a los MSB.

    
respondido por el Tom Carpenter

Lea otras preguntas en las etiquetas