2012-09-13 23 views
9

Por ejemplo, decir que tengo un reg [7:0] myReg que asignarle el valor -8'D69¿Cómo se comporta Verilog con números negativos?

Sé tiendas Verilog que como complemento a 2 por lo que debe ser almacenada como

10111011 

La pregunta que tengo ahora es si fueron a realizar una operación en él, digamos myReg/2

¿Lo evaluaría a -34? ¿O tomaría 10111011 y lo convertiría en 187 y luego realizaría la división, devolviendo 93?

+1

También debe declarar los números firmados como tales. 'reg signed [7: 0] my_reg' – Morgan

+0

Puede usar >>> 1 para realizar un signo de división extendida por 2. (si se declara como un tipo firmado). – Morgan

Respuesta

10

Debe recordar que -8d69 es solo un patrón de bits. reg es un tipo que contiene patrones de bits. Es el tipo de variable que instruye / para realizar aritmética con o sin signo.

Si esto es para la síntesis, teniendo en cuenta que desea probar y evitar los divisores, realmente quiere intentar y evitar los divisores firmados. Es probable que la síntesis más pequeño con >>> 1

reg [7:0] a; 
reg signed [7:0] b; 
reg [7:0] c; 
reg signed [7:0] d; 

initial begin 
    a = -8'd69 ; 
    b = -8'd69 ; 
    c = -8'd69 ; 
    d = -8'd69 ; 
    #10ns; 
    a = a/2  ; 
    b = b/2  ; 
    #10ns; 
    $display("a  : %8b, %d", a, a); 
    $display("b  : %8b, %d", b, b); 
    $display("c >>>1 : %8b, %d", c>>>1, c>>>1); 
    $display("d >>>1 : %8b, %d", d>>>1, d>>>1); 
end 

Da:

a  : 01011101, 93 
b  : 11011110, -34 
c >>>1 : 01011101, 93 
d >>>1 : 11011101, -35 

>> x desplaza a la derecha por lugares x, x >>> x desplaza a la derecha lugares pero de signo extiende para este tipo firmados.

NB: el /2 también se está redondeando en mis ejemplos, >>> redondeará hacia abajo/truncará.

5

Por ejemplo, decir que tengo un reg [7: 0] myReg que asignarle el valor -8'D69

En realidad, esto no es un número con signo sino una expresión que consiste en una negación unitaria aplicada a una constante positiva. Si la expresión fuera -8'd130, el resultado se desbordaría. Las constantes firmadas se declaran como 8'sd69 o simplemente 69.

La pregunta que tengo ahora es si tuviera que realizar una operación en ella, dicen myReg/2

myReg no está firmado por lo que el resultado de la expresión también será sin signo *. Si necesita que se firme el resultado que , todos los operandos deben estar firmados. Hay un par de maneras de lograr esto:

//Declare the reg as signed and divide by a signed value 
reg signed [7:0] myReg; 
assign result = myReg/2; 

//Use system functions 
assign result = $signed(myReg)/2; 

* Las reglas completas con respecto a la evaluación de expresiones son mucho más complejo, pero básicamente el resultado de cualquier expresión no está firmado, a menos que se firman todos los operandos.

reg signed [7:0] a; 
reg [7:0] b; 

initial 
begin 
result = a;   //Signed 
result = a * a;  //Signed 
result = a * 10;  //Signed 
result = $unsigned(a); //Unsigned 
result = a[0];   //Unsigned 
result = a[7:0];  //Unsigned 
result = {a,a};  //Unsigned 
result = 10{a};  //Unsigned 
result = a + b;  //Unsigned 
result = a * b;  //Unsigned 
end 
1

voy a añadir que 1. Tipos de datos de bits y reg están sin firmar, por defecto. 2. Los tipos de datos int, integer, longint, shortint y byte están firmados, por defecto. 3. Todos estos tipos de datos pueden tomar un calificador firmado o sin firmar para cambiar el valor predeterminado.

Entonces, al asignar -8'D69 a myReg se realiza una conversión implícita a 187. Entonces, myReg/2 = 187/2 = 93, sin firmar. Es importante comprender cuándo y cómo SystemVerilog realiza conversiones de tipo implícitas en expresiones y asignaciones.

Cuestiones relacionadas