2012-09-13 22 views
9

Per esempio, dire che ho un reg [7:0] myReg assegno che il valore -8'D69Come si comporta Verilog con numeri negativi?

So negozi Verilog esso come complemento a 2 e quindi dovrebbe essere archiviato come

10111011 

La domanda che ho adesso è se io dovevano eseguire un'operazione su di essa, ad esempio myReg/2

Valuterebbe a -34? O prenderebbe 10111011 e lo trasformerebbe in 187 quindi eseguirà la divisione, restituendo 93?

+1

È inoltre necessario dichiarare i numeri firmati come tali. 'reg signed [7: 0] my_reg' – Morgan

+0

Puoi usare >>> 1 per eseguire una divisione estesa di segno per 2. (se è dichiarata come un tipo firmato). – Morgan

risposta

10

È necessario ricordare che lo -8d69 è solo un motivo. reg è un tipo che contiene schemi di bit. È il tipo di variabile che indica a / di eseguire operazioni aritmetiche con segno o senza segno.

Se questo è per sintesi, in mente che si desidera provare ed evitare i divisori, si vuole davvero cercare di evitare i divisori firmati. Sarà probabilmente sintesi più piccola 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 

Dà:

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

>> x turni diritto di posti x, >>> x Turni posti x giusto, ma il segno si estende per i tipi di firma.

NB: lo /2 è anch'esso arrotondato nei miei esempi, >>> verrà arrotondato per eccesso/troncato.

5

Ad esempio, dire che ho un reg [7: 0] myReg assegno così il valore -8'D69

Questo in realtà non è un numero con segno ma invece un'espressione formata una negazione unaria applicata a una costante positiva. Se l'espressione era -8'd130, il risultato sarebbe l'overflow. Le costanti firmate sono dichiarate come 8'sd69 o solo 69.

La domanda che ho ora è se dovessi eseguire un'operazione su di esso, dire myReg/2

myReg è senza segno così il risultato dell'espressione sarà anche senza segno *. Se è necessario firmare il risultato rispetto a , è necessario firmare tutti gli operandi. Ci sono un paio di modi per raggiungere questo obiettivo:

//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; 

* Il regolamento completo in materia di valutazione di espressione sono molto più complessi ma fondamentalmente il risultato di ogni espressione non è firmato, a meno che tutti gli operandi sono firmati.

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

io aggiungo che 1. tipi di dati bit e reg sono senza segno, per impostazione predefinita. 2. I tipi di dati int, integer, longint, shortint e byte sono firmati, per impostazione predefinita. 3. Tutti questi tipi di dati possono richiedere un qualificatore firmato o non firmato per modificare il valore predefinito.

Quindi, l'assegnazione di -8'D69 a myReg esegue una conversione implicita a 187. Then myReg/2 = 187/2 = 93, senza segno. È importante capire quando e come SystemVerilog esegue conversioni di tipo implicito in espressioni e assegnazioni.

Problemi correlati