Come troncare la larghezza di un bit di espressione in Verilog?


11

Considera un'espressione come:

assign x = func(A) ^ func(B);

dove l'uscita della funzione è larga 32 bit e x è un filo di 16 bit. Voglio assegnare solo i 16 bit più bassi dello xor risultante.

So che il codice sopra lo fa già, ma genera anche un avviso. L'approccio "ovvio" non funziona:

assign x = (func(A) ^ func(B))[15:0]; // error: '[' is unexpected

Risposte:


8

Puoi usare un'altra variabile, sebbene non sia particolarmente elegante.

wire[31:0] y;

assign y = func(A) ^ func(B);
assign x = y[15:0];

Un approccio migliore sarebbe usare una funzione.

function [15:0] trunc_32_to_16(input [31:0] val32);
  trunc_32_to_16 = val32[15:0];
endfunction

assign x = trunc_32_to_16(func(A) ^ func(B));

Speravo che ci sarebbe stato qualcosa di più bello di così ... Oh beh, creerò solo un gran numero di funzioni di troncamento.
user23106,

5

Nel tuo esempio, stai troncando implicitamente i bit.

Rendere esplicito il troncamento può spesso rimuovere gli avvisi in simulazione / filaccia / sintesi.

Un modo per farlo in linea consiste nell'utilizzare un operatore del cast, ad esempio:

typedef logic [15:0] HALF_WORD;
assign x = HALF_WORD'((func(A) ^ func(B));

Questo approccio può avere senso se dal contesto è ovvio che tutti i bit che vengono rilasciati sono 0.

Se alcuni bit potrebbero essere diversi da zero, suggerirei di utilizzare ancora una rete intermedia come suggerito da @dwikle in una risposta precedente , poiché rende più chiaro che stai effettivamente gettando via i bit. Eccolo di nuovo per riferimento.

wire[31:0] y;

assign y = func(A) ^ func(B);
assign x = y[15:0];

1
Penso che funzionerebbe solo in SystemVerilog. Interessante comunque.
Tom Carpenter,

@TomCarpenter, vuoi limitarti al sottoinsieme di Verilog disponibile in IEEE Std 1364-2005, piuttosto che utilizzare il set completo di verilog sintetizzabili disponibili in una delle più recenti revisioni unificate IEEE Std 1800? Potresti voler dire Verilog-2005 o qualcosa da chiarire, dal momento che lo standard Verilog è stato inserito nello standard SystemVerilog unificato nel 2009.
Mattgately

3

Penso che questo potrebbe aiutare a mantenere il conto alla rovescia.

wire [15:0] not_used ;

assign {not_used, x} = (func(A) ^ func(B));

Non sono sicuro se ciò sia valido con assegnazioni però.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.